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>
137std::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>
142std::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