PLaSK library

Loading...
Searching...
No Matches
intersection.cpp
Go to the documentation of this file.
1/*
2 * This file is part of PLaSK (https://plask.app) by Photonics Group at TUL
3 * Copyright (c) 2022 Lodz University of Technology
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 3.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14#include "intersection.hpp"
15
16#include "../manager.hpp"
17#include "reader.hpp"
18
19#define PLASK_INTERSECTION2D_NAME ("intersection" PLASK_GEOMETRY_TYPE_NAME_SUFFIX_2D)
20#define PLASK_INTERSECTION3D_NAME ("intersection" PLASK_GEOMETRY_TYPE_NAME_SUFFIX_3D)
21
22 namespace plask {
23
24 template <int dim>
25 const char* Intersection<dim>::NAME = dim == 2 ? PLASK_INTERSECTION2D_NAME : PLASK_INTERSECTION3D_NAME;
26
27 template <int dim>
28 shared_ptr<Material> Intersection<dim>::getMaterial(const typename Intersection<dim>::DVec& p) const {
29 return (this->hasChild() && this->inEnvelope(p)) ? this->_child->getMaterial(p) : shared_ptr<Material>();
30}
31
32 template <int dim> bool Intersection<dim>::contains(const typename Intersection<dim>::DVec& p) const {
33 return this->hasChild() && (inEnvelope(p)) && this->_child->contains(p);
34}
35
36 template <int dim>
37 GeometryObject::Subtree Intersection<dim>::getPathsAt(const typename Intersection<dim>::DVec& point, bool all) const {
38 if (this->hasChild() && inEnvelope(point))
39 return GeometryObject::Subtree::extendIfNotEmpty(this, this->_child->getPathsAt(point, all));
40 else
41 return GeometryObject::Subtree();
42}
43
44 template <int dim>
45 typename Intersection<dim>::Box Intersection<dim>::fromChildCoords(
46 const typename Intersection<dim>::ChildType::Box& child_bbox) const {
47 if (envelope) return envelope->getBoundingBox().intersection(child_bbox);
48 else
49 return child_bbox;
50}
51
52 template <int dim>
53 void Intersection<dim>::getBoundingBoxesToVec(const GeometryObject::Predicate& predicate,
54 std::vector<Box>& dest,
55 const PathHints* path) const {
56 if (predicate(*this)) {
57 dest.push_back(this->getBoundingBox());
58 return;
59 }
60 if (!this->hasChild()) return;
61 std::vector<Box> result = this->_child->getBoundingBoxes(predicate, path);
62 dest.reserve(dest.size() + result.size());
63 if (envelope) {
64 Box clipBox = envelope->getBoundingBox();
65 for (Box& r : result) {
66 r.makeIntersection(clipBox);
67 dest.push_back(r);
68 }
69 } else {
70 for (Box& r : result) dest.push_back(r);
71 }
72}
73
74 template <int dim>
75 void Intersection<dim>::getPositionsToVec(const GeometryObject::Predicate& predicate,
76 std::vector<DVec>& dest,
77 const PathHints* path) const {
78 this->_getNotChangedPositionsToVec(this, predicate, dest, path);
79}
80
81 template <int dim> shared_ptr<GeometryObject> Intersection<dim>::shallowCopy() const { return copyShallow(); }
82
83 template <int dim>
84 void Intersection<dim>::addPointsAlongToSet(std::set<double>& points,
85 Primitive<3>::Direction direction,
86 unsigned max_steps,
87 double min_step_size) const {
88 if (this->_child) {
89 if (!envelope) {
90 this->_child->addPointsAlongToSet(points, direction, this->max_steps ? this->max_steps : max_steps,
91 this->min_step_size ? this->min_step_size : min_step_size);
92 return;
93 }
94 std::set<double> child_points;
95 this->_child->addPointsAlongToSet(child_points, direction, this->max_steps ? this->max_steps : max_steps,
96 this->min_step_size ? this->min_step_size : min_step_size);
97 auto clipbox = envelope->getBoundingBox();
98 auto bbox = this->getBoundingBox();
99 points.insert(bbox.lower[int(direction) - (3 - dim)]);
100 for (double p : child_points) {
101 if (clipbox.lower[int(direction) - (3 - dim)] <= p && p <= clipbox.upper[int(direction) - (3 - dim)])
102 points.insert(p);
103 }
104 points.insert(bbox.upper[int(direction) - (3 - dim)]);
105 }
106}
107
108 template <int dim>
109 void Intersection<dim>::addLineSegmentsToSet(std::set<typename GeometryObjectD<dim>::LineSegment>& segments,
110 unsigned max_steps,
111 double min_step_size) const {
112 if (this->_child) {
113 if (!this->envelope) {
114 this->_child->addLineSegmentsToSet(segments, this->max_steps ? this->max_steps : max_steps,
115 this->min_step_size ? this->min_step_size : min_step_size);
116 return;
117 }
118 throw NotImplemented("getting line segments for objects interception");
119 // std::set<typename GeometryObjectD<dim>::LineSegment> child_segments;
120 // this->_child->addLineSegmentsToSet(child_segments, this->max_steps ? this->max_steps : max_steps,
121 // this->min_step_size ? this->min_step_size : min_step_size);
122 // for (const auto& s : child_segments) {
123 // if (envelope->contains(s.p0()) && envelope->contains(s.p1())) segments.insert(s);
124 // }
125 }
126}
127
128 template <int dim>
129 void Intersection<dim>::writeXMLChildren(XMLWriter::Element& dest_xml_object,
130 GeometryObject::WriteXMLCallback& write_cb,
131 const AxisNames& axes) const {
132 if (this->hasChild()) {
133 this->_child->writeXML(dest_xml_object, write_cb, axes);
134 if (envelope) envelope->writeXML(dest_xml_object, write_cb, axes);
135 }
136}
137
138 template <int dim> shared_ptr<GeometryObject> read_Intersection(GeometryReader& reader) {
139 GeometryReader::SetExpectedSuffix suffixSetter(
140 reader, dim == 2 ? PLASK_GEOMETRY_TYPE_NAME_SUFFIX_2D : PLASK_GEOMETRY_TYPE_NAME_SUFFIX_3D);
141 shared_ptr<Intersection<dim>> intersection = plask::make_shared<Intersection<dim>>();
142 if (reader.source.requireNext(reader.manager.draft ? (XMLReader::NODE_ELEMENT | XMLReader::NODE_ELEMENT_END)
143 : XMLReader::NODE_ELEMENT) == XMLReader::NODE_ELEMENT) {
144 intersection->setChild(reader.readObject<typename Intersection<dim>::ChildType>());
145 if (reader.source.requireTagOrEnd()) {
146 GeometryReader::RevertMaterialsAreRequired enableShapeOnlyMode(reader, false);
147 intersection->envelope = reader.readObject<typename Intersection<dim>::ChildType>();
148 reader.source.requireTagEnd();
149 }
150 } else {
151 reader.manager.pushError("Intersection object is empty", reader.source.getLineNr());
152 }
153 return intersection;
154}
155
156 static GeometryReader::RegisterObjectReader Intersection2D_reader(PLASK_INTERSECTION2D_NAME, read_Intersection<2>);
157 static GeometryReader::RegisterObjectReader Intersection3D_reader(PLASK_INTERSECTION3D_NAME, read_Intersection<3>);
158
159 template struct PLASK_API Intersection<2>;
160 template struct PLASK_API Intersection<3>;
161
162} // namespace plask