PLaSK library
Loading...
Searching...
No Matches
space.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 "
space.hpp
"
15
16
#include <memory>
17
#include <cassert>
18
19
namespace
plask
{
20
21
void
Geometry::setEdges
(
const
std::function<
plask::optional<std::string>
(
const
std::string& s)>&
borderValuesGetter
,
22
const
AxisNames
&
axesNames
,
23
const
MaterialsDB
&materialsDB,
24
bool
draft)
25
{
26
plask::optional<std::string>
v
,
v_lo
,
v_hi
;
27
try
{
28
v
=
borderValuesGetter
(
"edges"
);
29
if
(
v
)
setAllEdges
(*
edge::Strategy::fromStrUnique
(*
v
, materialsDB));
30
}
catch
(...) {
31
if
(!draft)
throw
;
32
}
33
try
{
34
v
=
borderValuesGetter
(
"planar"
);
35
if
(
v
)
setPlanarEdges
(*
edge::Strategy::fromStrUnique
(*
v
, materialsDB));
36
}
catch
(...) {
37
if
(!draft)
throw
;
38
}
39
for
(
int
dir_nr
= 0;
dir_nr
< 3; ++
dir_nr
) {
40
std::string
axis_name
=
axesNames
[
dir_nr
];
41
try
{
42
v
=
borderValuesGetter
(
axis_name
);
43
if
(
v
)
setEdges
(
Direction
(
dir_nr
), *
edge::Strategy::fromStrUnique
(*
v
, materialsDB));
44
}
catch
(...) {
45
if
(!draft)
throw
;
46
}
47
try
{
48
v_lo
=
borderValuesGetter
(
axis_name
+
"-lo"
);
49
if
((
v
=
borderValuesGetter
(
alternativeDirectionName
(
dir_nr
, 0)))) {
50
if
(
v_lo
)
throw
BadInput
(
"setEdges"
,
"edge specified by both '{0}-lo' and '{1}'"
,
axis_name
,
alternativeDirectionName
(
dir_nr
, 0));
51
else
v_lo
=
v
;
52
}
53
}
catch
(...) {
54
if
(!draft)
throw
;
55
v_lo
.reset();
56
}
57
try
{
58
v_hi
=
borderValuesGetter
(
axis_name
+
"-hi"
);
59
if
((
v
=
borderValuesGetter
(
alternativeDirectionName
(
dir_nr
, 1)))) {
60
if
(
v_hi
)
throw
BadInput
(
"setEdges"
,
"edge specified by both '{0}-hi' and '{1}'"
,
axis_name
,
alternativeDirectionName
(
dir_nr
, 1));
61
else
v_hi
=
v
;
62
}
63
}
catch
(...) {
64
if
(!draft)
throw
;
65
v_hi
.reset();
66
}
67
try
{
68
if
(
v_lo
&&
v_hi
) {
69
try
{
70
setEdges
(
Direction
(
dir_nr
), *
edge::Strategy::fromStrUnique
(*
v_lo
, materialsDB), *
edge::Strategy::fromStrUnique
(*
v_hi
, materialsDB));
71
v_lo
.reset();
72
v_hi
.reset();
73
}
catch
(...) {
74
if
(!draft)
throw
;
75
}
76
}
77
if
(
v_lo
) {
78
try
{
79
setEdge
(
Direction
(
dir_nr
),
false
, *
edge::Strategy::fromStrUnique
(*
v_lo
, materialsDB));
80
}
catch
(...) {
81
if
(!draft)
throw
;
82
}
83
}
84
if
(
v_hi
) {
85
try
{
86
setEdge
(
Direction
(
dir_nr
),
true
, *
edge::Strategy::fromStrUnique
(*
v_hi
, materialsDB));
87
}
catch
(...) {
88
if
(!draft)
throw
;
89
}
90
}
91
}
catch
(
DimensionError
&) {
92
if
(!draft)
throw
BadInput
(
"setEdges"
,
"axis '{0}' is not allowed for this space"
,
axis_name
);
93
}
catch
(...) {
94
if
(!draft)
throw
;
95
}
96
}
97
}
98
99
void
Geometry::storeEdgeInXML
(
XMLWriter::Element
&
dest_xml_object
,
Geometry::Direction
direction,
bool
higher
)
const
{
100
const
edge::Strategy
&
b
= this->
getEdge
(direction,
higher
);
101
if
(
b
.type() !=
edge::Strategy::DEFAULT
)
102
dest_xml_object
.attr(this->
alternativeDirectionName
(direction,
higher
),
b
.str());
103
}
104
105
template
<
int
dim>
106
void
GeometryD<dim>::onChildChanged
(
const
GeometryObject::Event
&
evt
) {
107
if
(
evt
.isResize()) cachedBoundingBox = getChild()->getBoundingBox();
108
//compiler should optimized out dim == 2 condition checking
109
fireChanged(
evt
.originalSource(), dim == 2 ?
evt
.flagsForParentWithChildrenWasChangedInformation() :
evt
.flagsForParent());
110
}
111
112
template
<
int
dim>
113
void
GeometryD<dim>::disconnectOnChildChanged
() {
114
connection_with_child.disconnect();
115
}
116
117
template
<
int
dim>
118
void
GeometryD<dim>::initNewChild
() {
119
disconnectOnChildChanged();
//disconnect old child, if any
120
auto
c3d
= getObject3D();
121
if
(
c3d
) {
122
if
(
c3d
) connection_with_child =
c3d
->changedConnectMethod(
this
, &
GeometryD<dim>::onChildChanged
);
123
auto
c = getChildUnsafe();
124
if
(c) cachedBoundingBox = c->getBoundingBox();
125
}
126
}
127
128
template
<
int
dim>
129
int
GeometryD<dim>::getDimensionsCount
()
const
{
return
DIM; }
130
131
template
<
int
dim>
132
shared_ptr<Material>
GeometryD<dim>::getMaterial
(
const
Vec<dim, double>
&p)
const
{
133
return
getMaterialOrDefault(p);
134
}
135
136
template
<
int
dim>
137
std::set<std::string>
GeometryD<dim>::getRolesAt
(
const
typename
GeometryD<dim>::CoordsType
&point,
const
PathHints
*path)
const
{
138
return
getChild()->getRolesAt(wrapEdges(point), path);
139
}
140
141
template
<
int
dim>
142
std::set<std::string>
GeometryD<dim>::getRolesAt
(
const
typename
GeometryD<dim>::CoordsType
&point,
const
PathHints &path)
const
{
143
return
getChild()->getRolesAt(wrapEdges(point), &path);
144
}
145
146
template
<>
147
void
GeometryD<2>::writeXMLAttr
(
XMLWriter::Element
&
dest_xml_object
,
const
AxisNames
&axes)
const
{
148
Geometry::writeXMLAttr
(
dest_xml_object
, axes);
149
dest_xml_object
.attr(
"axes"
, axes.str());
150
this->storeEdgeInXML(
dest_xml_object
, DIRECTION_TRAN,
false
);
151
this->storeEdgeInXML(
dest_xml_object
, DIRECTION_TRAN,
true
);
152
this->storeEdgeInXML(
dest_xml_object
, DIRECTION_VERT,
false
);
153
this->storeEdgeInXML(
dest_xml_object
, DIRECTION_VERT,
true
);
154
}
155
156
template
<>
157
void
GeometryD<3>::writeXMLAttr
(
XMLWriter::Element
&
dest_xml_object
,
const
AxisNames
&axes)
const
{
158
Geometry::writeXMLAttr
(
dest_xml_object
, axes);
159
dest_xml_object
.attr(
"axes"
, axes.str());
160
for
(
int
dir
= 0;
dir
< 3; ++
dir
) {
161
this->storeEdgeInXML(
dest_xml_object
,
plask::Geometry::Direction
(
dir
),
false
);
162
this->storeEdgeInXML(
dest_xml_object
,
plask::Geometry::Direction
(
dir
),
true
);
163
}
164
}
165
166
template
class
PLASK_API
GeometryD<2>
;
167
template
class
PLASK_API
GeometryD<3>
;
168
169
Geometry2DCartesian::Geometry2DCartesian
(
shared_ptr<Extrusion>
extrusion)
170
: extrusion(extrusion)
171
{
172
initNewChild
();
173
}
174
175
Geometry2DCartesian::Geometry2DCartesian
(shared_ptr<
GeometryObjectD<2>
>
childGeometry
,
double
length)
176
: extrusion(
plask
::make_shared<
Extrusion
>(
childGeometry
, length))
177
{
178
initNewChild
();
179
}
180
181
shared_ptr< GeometryObjectD<2>
>
Geometry2DCartesian::getChild
()
const
{
182
if
(!extrusion)
throw
NoChildException
();
183
auto
child = extrusion->getChild();
184
if
(!child)
throw
NoChildException
();
185
return
child;
186
}
187
188
shared_ptr< GeometryObjectD<2>
>
Geometry2DCartesian::getChildUnsafe
()
const
{
189
return
extrusion->getChild();
190
}
191
192
shared_ptr<Material>
Geometry2DCartesian::getMaterial
(
const
Vec<2, double>
&p)
const
{
193
Vec<2, double>
r = p;
194
shared_ptr<Material>
material;
195
196
bottomup.apply(
cachedBoundingBox
, r, material);
197
if
(material)
return
material;
198
199
leftright.apply(
cachedBoundingBox
, r, material);
200
if
(material)
return
material;
201
202
return
getMaterialOrDefault
(r);
203
}
204
205
GeometryD<2>::CoordsType
Geometry2DCartesian::wrapEdges
(
GeometryD<2>::CoordsType
p)
const
{
206
shared_ptr<Material>
ignored
;
207
bottomup.apply(
cachedBoundingBox
, p,
ignored
);
208
leftright.apply(
cachedBoundingBox
, p,
ignored
);
209
return
p;
210
}
211
212
void
Geometry2DCartesian::setExtrusion
(
shared_ptr<Extrusion>
extrusion) {
213
if
(this->extrusion == extrusion)
return
;
214
this->extrusion = extrusion;
215
this->
initNewChild
();
216
fireChildrenChanged
();
217
}
218
219
// Geometry2DCartesian* Geometry2DCartesian::getSubspace(const shared_ptr<GeometryObjectD<2>>& object, const PathHints* path, bool copyEdges) const {
220
// auto shifts = getChild()->getObjectPositions(object, path);
221
// // auto new_child = getChild()->getUniqueObjectInThisCoordinates(object, path);
222
// // if (!new_child) {
223
// // new_child = object->requireUniqueObjectInThisCoordinates(getChild(), path);
224
// // new_child->translation = - new_child->translation;
225
// // }
226
// // if (copyEdges) {
227
// // std::unique_ptr<Geometry2DCartesian> result(new Geometry2DCartesian(*this));
228
// // result->extrusion = plask::make_shared<Extrusion>(new_child, getExtrusion()->length);
229
// // return result.release();
230
// // } else
231
// // return new Geometry2DCartesian(new_child, getExtrusion()->length);
232
// }
233
234
void
Geometry2DCartesian::setEdges
(
Direction
direction,
const
edge::Strategy
&
border_lo
,
const
edge::Strategy
&
border_hi
) {
235
Primitive<3>::ensureIsValid2DDirection
(direction);
236
if
(direction ==
DIRECTION_TRAN
)
237
leftright.setStrategies(
border_lo
,
border_hi
);
238
else
239
bottomup.setStrategies(
border_lo
,
border_hi
);
240
fireChanged
(Event::EVENT_EDGES);
241
}
242
243
void
Geometry2DCartesian::setEdge
(
Direction
direction,
bool
higher
,
const
edge::Strategy
&
border_to_set
) {
244
Primitive<3>::ensureIsValid2DDirection
(direction);
245
if
(direction ==
DIRECTION_TRAN
)
246
leftright.set(
higher
,
border_to_set
);
247
else
248
bottomup.set(
higher
,
border_to_set
);
249
fireChanged
(Event::EVENT_EDGES);
250
}
251
252
const
edge::Strategy
&
Geometry2DCartesian::getEdge
(
Direction
direction,
bool
higher
)
const
{
253
Primitive<3>::ensureIsValid2DDirection
(direction);
254
return
(direction ==
DIRECTION_TRAN
) ? leftright.get(
higher
) : bottomup.get(
higher
);
255
}
256
257
shared_ptr<GeometryObject>
Geometry2DCartesian::shallowCopy
()
const
{
258
shared_ptr<Geometry2DCartesian>
result
=
make_shared<Geometry2DCartesian>
(
static_pointer_cast<Extrusion>
(this->extrusion->shallowCopy()));
259
result
->setEdges(
DIRECTION_TRAN
, leftright.getLo(), leftright.getHi());
260
result
->setEdges(
DIRECTION_VERT
, bottomup.getLo(), bottomup.getHi());
261
result
->frontMaterial = frontMaterial;
262
result
->backMaterial = backMaterial;
263
return
result
;
264
}
265
266
shared_ptr<GeometryObject>
Geometry2DCartesian::deepCopy
(std::map<
const
GeometryObject
*,
shared_ptr<GeometryObject>
>&
copied
)
const
{
267
auto
found
=
copied
.find(
this
);
268
if
(
found
!=
copied
.end())
return
found
->second;
269
shared_ptr<Geometry2DCartesian>
result
=
make_shared<Geometry2DCartesian>
(
static_pointer_cast<Extrusion>
(this->extrusion->deepCopy(
copied
)));
270
result
->setEdges(
DIRECTION_TRAN
, leftright.getLo(), leftright.getHi());
271
result
->setEdges(
DIRECTION_VERT
, bottomup.getLo(), bottomup.getHi());
272
result
->frontMaterial = frontMaterial;
273
result
->backMaterial = backMaterial;
274
copied
[
this
] =
result
;
275
return
result
;
276
}
277
278
void
Geometry2DCartesian::writeXML
(
XMLWriter::Element
&
parent_xml_object
,
WriteXMLCallback
&
write_cb
,
AxisNames
axes)
const
{
279
XMLWriter::Element
tag
=
write_cb
.makeTag(
parent_xml_object
, *
this
, axes);
280
if
(WriteXMLCallback::isRef(
tag
))
return
;
281
writeXMLAttr
(
tag
, axes);
282
if
(
auto
c =
getExtrusion
()) {
283
if
(
isinf
(c->getLength()) && c->hasChild()) {
284
c->getChild()->writeXML(
tag
,
write_cb
, axes);
285
}
else
{
286
c->writeXML(
tag
,
write_cb
, axes);
287
}
288
}
289
}
290
291
Geometry2DCylindrical::Geometry2DCylindrical
(
shared_ptr<Revolution>
revolution)
292
: revolution(revolution)
293
{
294
initNewChild
();
295
}
296
297
Geometry2DCylindrical::Geometry2DCylindrical
(shared_ptr<
GeometryObjectD<2>
>
childGeometry
)
298
: revolution(
plask
::make_shared<
Revolution
>(
childGeometry
))
299
{
300
initNewChild
();
301
}
302
303
shared_ptr< GeometryObjectD<2>
>
Geometry2DCylindrical::getChild
()
const
{
304
if
(!revolution)
throw
NoChildException
();
305
auto
child = revolution->getChild();
306
if
(!child)
throw
NoChildException
();
307
return
child;
308
}
309
310
shared_ptr<GeometryObjectD<2>
>
Geometry2DCylindrical::getChildUnsafe
()
const
{
311
return
revolution->getChild();
312
}
313
314
shared_ptr<Material>
Geometry2DCylindrical::getMaterial
(
const
Vec<2, double>
&p)
const
{
315
Vec<2, double>
r = p;
316
if
(r.c0 < 0) r.c0 = -r.c0;
// Structure is ALWAYS symmetric with respect to the axis
317
318
shared_ptr<Material>
material;
319
320
bottomup.apply(
cachedBoundingBox
, r, material);
321
if
(material)
return
material;
322
323
innerouter.apply(
cachedBoundingBox
, r, material);
324
if
(material)
return
material;
325
326
return
getMaterialOrDefault
(r);
327
}
328
329
GeometryD<2>::CoordsType
Geometry2DCylindrical::wrapEdges
(
GeometryD<2>::CoordsType
p)
const
{
330
shared_ptr<Material>
ignored
;
331
bottomup.apply(
cachedBoundingBox
, p,
ignored
);
332
innerouter.apply(
cachedBoundingBox
, p,
ignored
);
333
return
p;
334
}
335
336
void
Geometry2DCylindrical::setRevolution
(
shared_ptr<Revolution>
revolution) {
337
if
(this->revolution == revolution)
return
;
338
this->revolution = revolution;
339
this->
initNewChild
();
340
fireChildrenChanged
();
341
}
342
343
// Geometry2DCylindrical* Geometry2DCylindrical::getSubspace(const shared_ptr< GeometryObjectD<2> >& object, const PathHints* path, bool copyEdges) const {
344
// }
345
346
void
Geometry2DCylindrical::setEdges
(
Direction
direction,
const
edge::Strategy
&
border_to_set
) {
347
Primitive<3>::ensureIsValid2DDirection
(direction);
348
if
(direction ==
DIRECTION_TRAN
) {
349
try
{
350
innerouter.setBoth(
dynamic_cast<
const
edge::UniversalStrategy
&
>
(
border_to_set
));
351
}
catch
(std::bad_cast&) {
352
throw
BadInput
(
"setEdges"
,
"wrong edge type for inner or outer edge"
);
353
}
354
}
else
355
bottomup.setBoth(
border_to_set
);
356
fireChanged
(Event::EVENT_EDGES);
357
}
358
359
void
Geometry2DCylindrical::setEdges
(
Direction
direction,
const
edge::Strategy
&
border_lo
,
const
edge::Strategy
&
border_hi
) {
360
ensureBoundDirIsProper(direction
/*, false*/
);
361
//ensureBoundDirIsProper(direction, true);
362
if
(direction ==
DIRECTION_TRAN
) {
363
try
{
364
innerouter.setStrategies(
dynamic_cast<
const
edge::UniversalStrategy
&
>
(
border_lo
),
365
dynamic_cast<
const
edge::UniversalStrategy
&
>
(
border_hi
));
366
}
catch
(std::bad_cast&) {
367
throw
BadInput
(
"setEdges"
,
"wrong edge type for inner or outer edge"
);
368
}
369
}
else
370
bottomup.setStrategies(
border_lo
,
border_hi
);
//bottomup is only one valid proper bound for lo and hi
371
fireChanged
(Event::EVENT_EDGES);
372
}
373
374
void
Geometry2DCylindrical::setEdge
(
Direction
direction,
bool
higher
,
const
edge::Strategy
&
border_to_set
) {
375
ensureBoundDirIsProper(direction
/*, higher*/
);
376
if
(direction ==
DIRECTION_TRAN
) {
377
try
{
378
innerouter.set(
higher
,
dynamic_cast<
const
edge::UniversalStrategy
&
>
(
border_to_set
));
379
}
catch
(std::bad_cast&) {
380
throw
BadInput
(
"setEdge"
,
"wrong edge type for inner or outer edge"
);
381
}
382
}
else
383
bottomup.set(
higher
,
border_to_set
);
384
fireChanged
(Event::EVENT_EDGES);
385
}
386
387
const
edge::Strategy
&
Geometry2DCylindrical::getEdge
(
Direction
direction,
bool
higher
)
const
{
388
ensureBoundDirIsProper(direction
/*, higher*/
);
389
return
(direction ==
DIRECTION_TRAN
) ? innerouter.get(
higher
) : bottomup.get(
higher
);
390
}
391
392
shared_ptr<GeometryObject>
Geometry2DCylindrical::shallowCopy
()
const
{
393
shared_ptr<Geometry2DCylindrical>
result
=
make_shared<Geometry2DCylindrical>
(
static_pointer_cast<Revolution>
(
static_pointer_cast<Revolution>
(this->revolution->shallowCopy())));
394
result
->setEdges(
DIRECTION_TRAN
, innerouter.getLo(), innerouter.getHi());
395
result
->setEdges(
DIRECTION_VERT
, bottomup.getLo(), bottomup.getHi());
396
return
result
;
397
}
398
399
shared_ptr<GeometryObject>
Geometry2DCylindrical::deepCopy
(std::map<
const
GeometryObject
*,
shared_ptr<GeometryObject>
>&
copied
)
const
{
400
auto
found
=
copied
.find(
this
);
401
if
(
found
!=
copied
.end())
return
found
->second;
402
shared_ptr<Geometry2DCylindrical>
result
=
make_shared<Geometry2DCylindrical>
(
static_pointer_cast<Revolution>
(this->revolution->deepCopy(
copied
)));
403
result
->setEdges(
DIRECTION_TRAN
, innerouter.getLo(), innerouter.getHi());
404
result
->setEdges(
DIRECTION_VERT
, bottomup.getLo(), bottomup.getHi());
405
copied
[
this
] =
result
;
406
return
result
;
407
}
408
409
void
Geometry2DCylindrical::writeXML
(
XMLWriter::Element
&
parent_xml_object
,
WriteXMLCallback
&
write_cb
,
AxisNames
axes)
const
{
410
XMLWriter::Element
tag
=
write_cb
.makeTag(
parent_xml_object
, *
this
, axes);
411
if
(WriteXMLCallback::isRef(
tag
))
return
;
412
writeXMLAttr
(
tag
, axes);
413
if
(
auto
c =
getRevolution
()) c->writeXML(
tag
,
write_cb
, axes);
414
}
415
416
void
Geometry3D::setEdges
(
Direction
direction,
const
edge::Strategy
&
border_lo
,
const
edge::Strategy
&
border_hi
) {
417
switch
(direction) {
418
case
DIRECTION_LONG
: backfront.setStrategies(
border_lo
,
border_hi
);
break
;
419
case
DIRECTION_TRAN
: leftright.setStrategies(
border_lo
,
border_hi
);
break
;
420
case
DIRECTION_VERT
: bottomup.setStrategies(
border_lo
,
border_hi
);
break
;
421
}
422
fireChanged
(Event::EVENT_EDGES);
423
}
424
425
void
Geometry3D::setEdges
(
Direction
direction,
const
edge::Strategy
&
border_to_set
) {
426
switch
(direction) {
427
case
DIRECTION_LONG
: backfront.setBoth(
border_to_set
);
break
;
428
case
DIRECTION_TRAN
: leftright.setBoth(
border_to_set
);
break
;
429
case
DIRECTION_VERT
: bottomup.setBoth(
border_to_set
);
break
;
430
}
431
fireChanged
(Event::EVENT_EDGES);
432
}
433
434
void
Geometry3D::setEdge
(
Direction
direction,
bool
higher
,
const
edge::Strategy
&
border_to_set
) {
435
switch
(direction) {
436
case
DIRECTION_LONG
: backfront.set(
higher
,
border_to_set
);
break
;
437
case
DIRECTION_TRAN
: leftright.set(
higher
,
border_to_set
);
break
;
438
case
DIRECTION_VERT
: bottomup.set(
higher
,
border_to_set
);
break
;
439
}
440
fireChanged
(Event::EVENT_EDGES);
441
}
442
443
const
edge::Strategy
&
Geometry3D::getEdge
(
Direction
direction,
bool
higher
)
const
{
444
switch
(direction) {
445
case
DIRECTION_LONG
:
return
backfront.get(
higher
);
446
case
DIRECTION_TRAN
:
return
leftright.get(
higher
);
447
case
DIRECTION_VERT
:
return
bottomup.get(
higher
);
448
}
449
assert
(0);
450
#ifdef _MSC_VER
451
__assume
(0);
452
#endif
453
std::abort();
// to silent warning in gcc/clang release build
454
}
455
456
Geometry3D::Geometry3D
(shared_ptr<
GeometryObjectD<3>
> child)
457
: child(child) {
458
initNewChild
();
459
}
460
461
shared_ptr<GeometryObjectD<3>
>
Geometry3D::getChild
()
const
{
462
if
(!child)
throw
NoChildException
();
463
return
child;
464
}
465
466
shared_ptr< GeometryObjectD<3>
>
Geometry3D::getChildUnsafe
()
const
{
467
return
child;
468
}
469
470
shared_ptr<GeometryObjectD<3>
>
Geometry3D::getObject3D
()
const
{
471
return
child;
472
}
473
474
shared_ptr<Material>
Geometry3D::getMaterial
(
const
Vec<3, double>
&p)
const
{
475
Vec<3, double>
r = p;
476
shared_ptr<Material>
material;
477
478
bottomup.apply(
cachedBoundingBox
, r, material);
479
if
(material)
return
material;
480
481
leftright.apply(
cachedBoundingBox
, r, material);
482
if
(material)
return
material;
483
484
backfront.apply(
cachedBoundingBox
, r, material);
485
if
(material)
return
material;
486
487
return
getMaterialOrDefault
(r);
488
}
489
490
GeometryD<3>::CoordsType
Geometry3D::wrapEdges
(
GeometryD<3>::CoordsType
p)
const
{
491
shared_ptr<Material>
ignored
;
492
bottomup.apply(
cachedBoundingBox
, p,
ignored
);
493
leftright.apply(
cachedBoundingBox
, p,
ignored
);
494
backfront.apply(
cachedBoundingBox
, p,
ignored
);
495
return
p;
496
}
497
498
499
shared_ptr<GeometryObject>
Geometry3D::shallowCopy
()
const
{
500
shared_ptr<Geometry3D>
result
=
make_shared<Geometry3D>
(this->child);
501
result
->setEdges(
DIRECTION_LONG
, backfront.getLo(), backfront.getHi());
502
result
->setEdges(
DIRECTION_TRAN
, leftright.getLo(), leftright.getHi());
503
result
->setEdges(
DIRECTION_VERT
, bottomup.getLo(), bottomup.getHi());
504
return
result
;
505
}
506
507
shared_ptr<GeometryObject>
Geometry3D::deepCopy
(std::map<
const
GeometryObject
*,
shared_ptr<GeometryObject>
>&
copied
)
const
{
508
auto
found
=
copied
.find(
this
);
509
if
(
found
!=
copied
.end())
return
found
->second;
510
shared_ptr<Geometry3D>
result
=
make_shared<Geometry3D>
(static_pointer_cast<
GeometryObjectD<3>
>(this->child->deepCopy(
copied
)));
511
result
->setEdges(
DIRECTION_LONG
, backfront.getLo(), backfront.getHi());
512
result
->setEdges(
DIRECTION_TRAN
, leftright.getLo(), leftright.getHi());
513
result
->setEdges(
DIRECTION_VERT
, bottomup.getLo(), bottomup.getHi());
514
copied
[
this
] =
result
;
515
return
result
;
516
}
517
518
// Geometry3D* Geometry3D::getSubspace(const shared_ptr<GeometryObjectD<3>>& object, const PathHints* path, bool copyEdges) const {
519
// }
520
521
shared_ptr<const GeometryObject>
Geometry2DCartesian::changedVersion
(
const
Changer
&
changer
,
Vec<3, double>
* translation)
const
{
522
auto
child =
getChild
();
523
auto
newChild
=
dynamic_pointer_cast<GeometryObjectD<2>
>(
524
const_pointer_cast<GeometryObject>
(child->changedVersion(
changer
, translation)));
525
if
(child ==
newChild
)
526
return
shared_from_this
();
527
shared_ptr<Geometry2DCartesian>
result
=
make_shared<Geometry2DCartesian>
(
newChild
, extrusion->getLength());
528
result
->setEdges(
DIRECTION_TRAN
, leftright.getLo(), leftright.getHi());
529
result
->setEdges(
DIRECTION_VERT
, bottomup.getLo(), bottomup.getHi());
530
result
->frontMaterial = frontMaterial;
531
result
->backMaterial = backMaterial;
532
return
result
;
533
}
534
535
shared_ptr<const GeometryObject>
Geometry2DCylindrical::changedVersion
(
const
Changer
&
changer
,
Vec<3, double>
* translation)
const
{
536
auto
child =
getChild
();
537
auto
newChild
=
dynamic_pointer_cast<GeometryObjectD<2>
>(
538
const_pointer_cast<GeometryObject>
(child->changedVersion(
changer
, translation)));
539
if
(child ==
newChild
)
540
return
shared_from_this
();
541
shared_ptr<Geometry2DCylindrical>
result
=
make_shared<Geometry2DCylindrical>
(
newChild
);
542
result
->setEdges(
DIRECTION_TRAN
, innerouter.getLo(), innerouter.getHi());
543
result
->setEdges(
DIRECTION_VERT
, bottomup.getLo(), bottomup.getHi());
544
return
result
;
545
}
546
547
shared_ptr<const GeometryObject>
Geometry3D::changedVersion
(
const
Changer
&
changer
,
Vec<3, double>
* translation)
const
{
548
auto
child =
getChild
();
549
auto
newChild
=
dynamic_pointer_cast<GeometryObjectD<3>
>(
550
const_pointer_cast<GeometryObject>
(child->changedVersion(
changer
, translation)));
551
if
(child ==
newChild
)
552
return
shared_from_this
();
553
shared_ptr<Geometry3D>
result
=
make_shared<Geometry3D>
(
newChild
);
554
result
->setEdges(
DIRECTION_LONG
, backfront.getLo(), backfront.getHi());
555
result
->setEdges(
DIRECTION_TRAN
, leftright.getLo(), leftright.getHi());
556
result
->setEdges(
DIRECTION_VERT
, bottomup.getLo(), bottomup.getHi());
557
return
result
;
558
}
559
560
561
562
}
// namespace plask
plask
geometry
space.cpp
Generated by
1.9.8