PLaSK library
Loading...
Searching...
No Matches
container.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 "
container.hpp
"
15
16
namespace
plask
{
17
18
template
<
int
dim>
19
void
GeometryObjectContainer<dim>::writeXMLChildAttr
(
XMLWriter::Element
&, std::size_t,
const
AxisNames
&)
const
{
20
// do nothing
21
}
22
23
template
<
int
dim>
24
void
GeometryObjectContainer<dim>::writeXML
(
XMLWriter::Element
&
parent_xml_object
,
25
GeometryObject::WriteXMLCallback
&
write_cb
,
26
AxisNames
axes)
const
{
27
XMLWriter::Element
container_tag
=
write_cb
.makeTag(
parent_xml_object
, *
this
, axes);
28
if
(
GeometryObject::WriteXMLCallback::isRef
(
container_tag
))
return
;
29
this->writeXMLAttr(
container_tag
, axes);
30
for
(std::size_t i = 0; i < children.size(); ++i) {
31
XMLWriter::Element
child_tag
=
write_cb
.makeChildTag(
container_tag
, *
this
, i);
32
writeXMLChildAttr(
child_tag
, i, axes);
33
if
(
auto
child = children[i]->getChild())
34
if
(child) child->writeXML(
child_tag
,
write_cb
, axes);
35
}
36
}
37
38
template
<
int
dim>
void
GeometryObjectContainer<dim>::onChildChanged
(
const
GeometryObject::Event
&
evt
) {
39
this->fireChanged(
evt
.originalSource(),
evt
.flagsForParent());
40
}
41
42
template
<
int
dim>
void
GeometryObjectContainer<dim>::connectOnChildChanged
(
Translation<dim>
& child) {
43
child.
changedConnectMethod
(
this
, &
GeometryObjectContainer::onChildChanged
);
44
}
45
46
template
<
int
dim>
void
GeometryObjectContainer<dim>::disconnectOnChildChanged
(
Translation<dim>
& child) {
47
child.
changedDisconnectMethod
(
this
, &
GeometryObjectContainer::onChildChanged
);
48
}
49
50
template
<
int
dim>
51
bool
GeometryObjectContainer<dim>::contains
(
const
typename
GeometryObjectContainer<dim>::DVec
& p)
const
{
52
for
(
auto
child : children)
53
if
(child->contains(p))
return
true
;
54
return
false
;
55
}
56
57
template
<
int
dim>
typename
GeometryObjectContainer<dim>::Box
GeometryObjectContainer<dim>::getBoundingBox
()
const
{
58
if
(children.empty())
return
Box
(
Primitive<dim>::ZERO_VEC
,
Primitive<dim>::ZERO_VEC
);
59
Box
result
= children[0]->getBoundingBox();
60
for
(std::size_t i = 1; i < children.size(); ++i)
result
.makeInclude(children[i]->getBoundingBox());
61
return
result
;
62
}
63
64
template
<
int
dim>
shared_ptr<Material>
GeometryObjectContainer<dim>::getMaterial
(
const
DVec
& p)
const
{
65
for
(
auto
child_it
= children.rbegin();
child_it
!= children.rend(); ++
child_it
) {
66
shared_ptr<Material>
r = (*child_it)->getMaterial(p);
67
if
(r !=
nullptr
)
return
r;
68
}
69
return
shared_ptr<Material>
();
70
}
71
72
template
<
int
dim>
73
void
GeometryObjectContainer<dim>::getBoundingBoxesToVec
(
const
GeometryObject::Predicate
& predicate,
74
std::vector<Box>&
dest
,
75
const
PathHints
* path)
const
{
76
if
(predicate(*
this
)) {
77
dest
.push_back(this->getBoundingBox());
78
return
;
79
}
80
forEachChild([&](
const
Translation<dim>
& child) { child.
getBoundingBoxesToVec
(predicate,
dest
, path); }, path);
81
82
/*if (path) {
83
auto c = path->getTranslationChildren<dim>(*this);
84
if (!c.empty()) {
85
for (auto child: c) child->getBoundingBoxesToVec(predicate, dest, path);
86
return;
87
}
88
}
89
for (auto child: children) child->getBoundingBoxesToVec(predicate, dest, path);*/
90
}
91
92
template
<
int
dim>
93
void
GeometryObjectContainer<dim>::getObjectsToVec
(
const
GeometryObject::Predicate
& predicate,
94
std::vector<
shared_ptr<const GeometryObject>
>&
dest
,
95
const
PathHints
* path)
const
{
96
if
(predicate(*
this
)) {
97
dest
.push_back(this->
shared_from_this
());
98
return
;
99
}
100
forEachChild([&](
const
Translation<dim>
& child) { child.
getObjectsToVec
(predicate,
dest
, path); }, path);
101
102
/*if (path) {
103
auto c = path->getTranslationChildren<dim>(*this);
104
if (!c.empty()) {
105
for (auto child: c) child->getObjectsToVec(predicate, dest, path);
106
return;
107
}
108
}
109
for (auto child: children) child->getObjectsToVec(predicate, dest, path);*/
110
}
111
112
template
<
int
dim>
113
void
GeometryObjectContainer<dim>::getPositionsToVec
(
const
GeometryObject::Predicate
& predicate,
114
std::vector<DVec>&
dest
,
115
const
PathHints
* path)
const
{
116
if
(predicate(*
this
)) {
117
dest
.push_back(
Primitive<dim>::ZERO_VEC
);
118
return
;
119
}
120
forEachChild([&](
const
Translation<dim>
& child) { child.
getPositionsToVec
(predicate,
dest
, path); }, path);
121
122
/*if (path) {
123
auto c = path->getTranslationChildren<dim>(*this);
124
if (!c.empty()) {
125
for (auto child: c) child->getPositionsToVec(predicate, dest, path);
126
return;
127
}
128
}
129
for (auto child: children) child->getPositionsToVec(predicate, dest, path);*/
130
}
131
132
// template <int dim>
133
// void GeometryObjectContainer<dim>::extractToVec(const GeometryObject::Predicate &predicate, std::vector<
134
// shared_ptr<const GeometryObjectD<dim> > >& dest, const PathHints *path) const {
135
// if (predicate(*this)) {
136
// dest.push_back(static_pointer_cast< const GeometryObjectD<dim> >(this->shared_from_this()));
137
// return;
138
// }
139
// if (path) {
140
// auto c = path->getTranslationChildren<dim>(*this);
141
// if (!c.empty()) {
142
// for (auto child: c) child->extractToVec(predicate, dest, path);
143
// return;
144
// }
145
// }
146
// for (auto child: children) child->extractToVec(predicate, dest, path);
147
// }
148
149
template
<
int
dim>
bool
GeometryObjectContainer<dim>::hasInSubtree
(
const
GeometryObject
& el)
const
{
150
if
(&el ==
this
)
return
true
;
151
for
(
auto
child : children)
152
if
(child->hasInSubtree(el))
return
true
;
153
return
false
;
154
}
155
156
template
<
int
dim>
157
GeometryObject::Subtree
GeometryObjectContainer<dim>::getPathsTo
(
const
GeometryObject
& el,
158
const
PathHints
* path)
const
{
159
if
(
this
== &el)
return
this->
shared_from_this
();
160
if
(path) {
161
auto
hintChildren
= path->
getTranslationChildren
<dim>(*this);
162
if
(!
hintChildren
.empty())
return
findPathsFromChildTo(
hintChildren
.begin(),
hintChildren
.end(), el, path);
163
}
164
return
findPathsFromChildTo(children.begin(), children.end(), el, path);
165
}
166
167
template
<
int
dim>
168
GeometryObject::Subtree
GeometryObjectContainer<dim>::getPathsAt
(
const
typename
GeometryObjectContainer::DVec
& point,
169
bool
all
)
const
{
170
GeometryObject::Subtree
result
;
171
if
(
all
) {
172
for
(
auto
child = children.begin(); child != children.end(); ++child) {
173
GeometryObject::Subtree
child_path
= (*child)->getPathsAt(point,
true
);
174
if
(!
child_path
.empty())
result
.
children
.push_back(std::move(
child_path
));
175
}
176
}
else
{
177
for
(
auto
child = children.rbegin(); child != children.rend(); ++child) {
178
GeometryObject::Subtree
child_path
= (*child)->getPathsAt(point,
false
);
179
if
(!
child_path
.empty()) {
180
result
.
children
.push_back(std::move(
child_path
));
181
break
;
182
}
183
}
184
}
185
if
(!
result
.children.empty())
result
.object =
this
->shared_from_this();
186
return
result
;
187
}
188
189
template
<
int
dim> std::size_t
GeometryObjectContainer<dim>::getChildrenCount
()
const
{
return
children.size(); }
190
191
template
<
int
dim>
shared_ptr<GeometryObject>
GeometryObjectContainer<dim>::getChildNo
(std::size_t
child_no
)
const
{
192
this->ensureIsValidChildNr(
child_no
);
193
return
children[
child_no
];
194
}
195
196
template
<
int
dim>
197
198
std::size_t
GeometryObjectContainer<dim>::getChildIndex
(
const
shared_ptr<ChildType>& el,
const
PathHints
* path)
const
{
199
std::size_t index, i = 0;
200
bool
found
=
false
;
201
auto
self = this->
shared_from_this
();
202
for
(
auto
child_tran
: children) {
203
auto
child =
child_tran
->getChild();
204
if
(child && child == el && (path ==
nullptr
|| path->
includes
(self,
child_tran
))) {
205
if
(
found
)
throw
NotUniqueObjectException
();
206
found
=
true
;
207
index = i;
208
}
209
++i;
210
}
211
if
(!
found
)
throw
NoSuchGeometryObject
();
212
return
index;
213
}
214
215
template
<
int
dim>
216
shared_ptr<const GeometryObject>
GeometryObjectContainer<dim>::changedVersion
(
const
GeometryObject::Changer
&
changer
,
217
Vec<3, double>
* translation)
const
{
218
shared_ptr<GeometryObject>
result
(
const_pointer_cast<GeometryObject>
(this->
shared_from_this
()));
219
if
(changer.
apply
(
result
, translation) || children.empty())
return
result
;
220
221
bool
were_changes
=
false
;
// any child was changed?
222
std::vector<std::pair<shared_ptr<ChildType>,
Vec<3, double>
>>
children_after_change
;
223
for
(
const
shared_ptr<TranslationT>&
child_tran
: children) {
224
Vec<3, double>
trans_from_child
;
225
shared_ptr<GeometryObject>
old_child
=
child_tran
->getChild();
226
if
(!
old_child
)
continue
;
227
shared_ptr<GeometryObject>
new_child
=
228
const_pointer_cast<GeometryObject>
(
old_child
->changedVersion(
changer
, &
trans_from_child
));
229
if
(
new_child
!=
old_child
)
were_changes
=
true
;
230
children_after_change
.emplace_back(
dynamic_pointer_cast<ChildType>
(
new_child
),
trans_from_child
);
231
}
232
233
if
(translation) *translation =
vec
(0.0, 0.0, 0.0);
// we can't recommend anything special
234
if
(
were_changes
)
result
= this->changedVersionForChildren(
children_after_change
, translation);
235
result
->roles = this->roles;
236
237
return
result
;
238
}
239
240
template
<
int
dim>
241
bool
GeometryObjectContainer<dim>::removeIfTUnsafe
(
242
const
std::function<
bool
(
const
shared_ptr<TranslationT>& c)>& predicate) {
243
auto
dst = children.begin();
244
for
(
auto
i : children)
245
if
(predicate(i)) disconnectOnChildChanged(*i);
246
else
247
*dst++ = i;
248
if
(dst != children.end()) {
249
children.erase(dst, children.end());
250
return
true
;
251
}
else
252
return
false
;
253
}
254
255
template
<
int
dim>
256
bool
GeometryObjectContainer<dim>::removeIfT
(
const
std::function<
bool
(
const
shared_ptr<TranslationT>& c)>& predicate) {
257
if
(removeIfTUnsafe(predicate)) {
258
this->fireChildrenChanged();
259
return
true
;
260
}
else
261
return
false
;
262
}
263
264
template
<
int
dim>
void
GeometryObjectContainer<dim>::removeAtUnsafe
(std::size_t index) {
265
disconnectOnChildChanged(*children[index]);
266
children.erase(children.begin() + index);
267
}
268
269
template
<
int
dim>
270
void
GeometryObjectContainer<dim>::addPointsAlongToSet
(std::set<double>& points,
271
Primitive<3>::Direction
direction,
272
unsigned
max_steps,
273
double
min_step_size)
const
{
274
for
(
const
auto
& child : children) {
275
if
(child)
276
child->addPointsAlongToSet(points, direction, this->max_steps ? this->max_steps : max_steps,
277
this->min_step_size ? this->min_step_size : min_step_size);
278
}
279
}
280
281
template
<
int
dim>
282
void
GeometryObjectContainer<dim>::addLineSegmentsToSet
(std::set<
typename
GeometryObjectD<dim>::LineSegment
>& segments,
283
unsigned
max_steps,
284
double
min_step_size)
const
{
285
for
(
const
auto
& child : children) {
286
if
(child)
287
child->addLineSegmentsToSet(segments, this->max_steps ? this->max_steps : max_steps,
288
this->min_step_size ? this->min_step_size : min_step_size);
289
}
290
}
291
292
template
struct
PLASK_API
GeometryObjectContainer<2>
;
293
template
struct
PLASK_API
GeometryObjectContainer<3>
;
294
295
}
// namespace plask
plask
geometry
container.cpp
Generated by
1.9.8