PLaSK library

Loading...
Searching...
No Matches
space.hpp
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#ifndef PLASK__CALCULATION_SPACE_H
15#define PLASK__CALCULATION_SPACE_H
16
17#include "edge.hpp"
18#include "transform_space_cartesian.hpp"
19#include "transform_space_cylindric.hpp"
20
21#include "../axes.hpp"
22
23#include <boost/signals2.hpp>
24#include "../optional.hpp"
25#include "../utils/event.hpp"
26
27 namespace plask {
28
34 struct PLASK_API Geometry : public GeometryObject {
36 shared_ptr<Material> defaultMaterial;
37
39 AxisNames axisNames;
40
41 enum Direction {
42 DIRECTION_LONG = Primitive<3>::DIRECTION_LONG,
43 DIRECTION_TRAN = Primitive<3>::DIRECTION_TRAN,
44 DIRECTION_VERT = Primitive<3>::DIRECTION_VERT
45 };
46
52 Geometry(shared_ptr<Material> defaultMaterial = make_shared<materials::Air>())
53 : GeometryObject(PLASK_GEOMETRY_MAX_STEPS, PLASK_GEOMETRY_MIN_STEP_SIZE), defaultMaterial(defaultMaterial) {}
54
59 Geometry(const Geometry& to_copy) : GeometryObject(to_copy), defaultMaterial(to_copy.defaultMaterial) {}
60
65 Geometry& operator=(const Geometry& to_copy) {
66 GeometryObject::operator=(to_copy);
67 defaultMaterial = to_copy.defaultMaterial;
68 return *this;
69 }
70
72 virtual ~Geometry() { fireChanged(Event::EVENT_DELETE); }
73
81 virtual void setEdges(Direction direction, const edge::Strategy& border_lo, const edge::Strategy& border_hi) = 0;
82
89 virtual void setEdges(Direction direction, const edge::Strategy& border_to_set) {
90 setEdges(direction, border_to_set, border_to_set);
91 }
92
99 virtual void setPlanarEdges(const edge::Strategy& border_to_set) = 0;
100
105 void setAllEdges(const edge::Strategy& border_to_set) {
106 setPlanarEdges(border_to_set);
107 setEdges(DIRECTION_VERT, border_to_set);
108 }
109
116 virtual void setEdge(Direction direction, bool higher, const edge::Strategy& border_to_set) = 0;
117
118 // void setEdges(const std::function< std::unique_ptr<edge::Strategy> >(const std::string& s)>& borderValuesGetter,
119 // const AxisNames& axesNames);
120
129 void setEdges(const std::function<plask::optional<std::string>(const std::string& s)>& borderValuesGetter,
130 const AxisNames& axesNames,
131 const MaterialsDB& materialsDB = MaterialsDB::getDefault(),
132 bool draft = false);
133
140 virtual const edge::Strategy& getEdge(Direction direction, bool higher) const = 0;
141
147 virtual bool isSymmetric(Direction direction) const {
148 return getEdge(direction, false).type() == edge::Strategy::MIRROR ||
149 getEdge(direction, true).type() == edge::Strategy::MIRROR;
150 }
151
157 bool isPeriodic(Direction direction) const {
158 return getEdge(direction, false).type() == edge::Strategy::PERIODIC ||
159 getEdge(direction, true).type() == edge::Strategy::PERIODIC;
160 }
161
168 bool isExtended(Direction direction, bool higher) const { return getEdge(direction, higher).type() == edge::Strategy::EXTEND; }
169
170 Type getType() const override { return TYPE_GEOMETRY; }
171
176 virtual shared_ptr<GeometryObjectD<3>> getObject3D() const = 0;
177
178 protected:
183 template <typename EdgeType> static const EdgeType& castEdge(const edge::Strategy& strategy) {
184 return dynamic_cast<const EdgeType&>(strategy);
185 }
186
190 virtual const char* alternativeDirectionName(std::size_t ax, std::size_t orient) const {
191 const char* directions[3][2] = {{"back", "front"}, {"left", "right"}, {"bottom", "top"}};
192 return directions[ax][orient];
193 }
194
195 void storeEdgeInXML(XMLWriter::Element& dest_xml_object, Direction direction, bool higher) const;
196};
197
202 template <int dim> class PLASK_API GeometryD : public Geometry {
204 boost::signals2::connection connection_with_child;
205
206 public:
207 enum { DIM = dim };
208
209 typedef Vec<dim, double> CoordsType;
210
211 protected:
216 shared_ptr<Material> getMaterialOrDefault(const Vec<dim, double>& p) const {
217 auto real_mat = getChild()->getMaterial(p);
218 return real_mat ? real_mat : defaultMaterial;
219 }
220
222 typename Primitive<dim>::Box cachedBoundingBox;
223
228 void onChildChanged(const GeometryObject::Event& evt);
229
231 void disconnectOnChildChanged();
232
239 void initNewChild();
240
241 virtual ~GeometryD() { disconnectOnChildChanged(); }
242
243 public:
244 int getDimensionsCount() const override;
245
257 virtual shared_ptr<Material> getMaterial(const Vec<dim, double>& p) const;
258
265 virtual shared_ptr<GeometryObjectD<dim>> getChild() const = 0;
266
271 virtual shared_ptr<GeometryObjectD<dim>> getChildUnsafe() const = 0;
272
277 const typename Primitive<dim>::Box& getChildBoundingBox() const { return cachedBoundingBox; }
278
284 bool hasInSubtree(const GeometryObject& el) const override { return getChild()->hasInSubtree(el); }
285
286 bool hasInSubtree(shared_ptr<const GeometryObject> el, const PathHints* pathHints) const {
287 return getChild()->hasInSubtree(*el, pathHints);
288 }
289
297 Subtree getPathsTo(const GeometryObject& el, const PathHints* pathHints = 0) const override {
298 return getChild()->getPathsTo(el, pathHints);
299 }
300
308 void getObjectsToVec(const Predicate& predicate,
309 std::vector<shared_ptr<const GeometryObject>>& dest,
310 const PathHints* path = 0) const override {
311 return getChild()->getObjectsToVec(predicate, dest, path);
312 }
313
318 std::size_t getChildrenCount() const override { return getObject3D() ? 1 : 0; }
319
325 shared_ptr<GeometryObject> getChildNo(std::size_t child_no) const override {
326 // if (!hasChild() || child_no > 0) throw OutOfBoundsException("geometry::getChildNo", "child_no");
327 if (child_no >= getChildrenCount()) throw OutOfBoundsException("geometry::getChildNo", "child_no");
328 return getObject3D();
329 }
330
336 std::vector<shared_ptr<const GeometryObject>> getLeafs(const PathHints* path = nullptr) const {
337 return getChild()->getLeafs(path);
338 }
339
345 std::vector<shared_ptr<const GeometryObject>> getLeafs(const PathHints& path) const { return getChild()->getLeafs(path); }
346
356 std::vector<CoordsType> getLeafsPositions(const PathHints* path = nullptr) const { return getChild()->getLeafsPositions(path); }
357
367 std::vector<CoordsType> getLeafsPositions(const PathHints& path) const { return getChild()->getLeafsPositions(path); }
368
378 std::vector<CoordsType> getObjectPositions(const GeometryObject& object, const PathHints* path = nullptr) const {
379 return getChild()->getObjectPositions(object, path);
380 }
381
391 std::vector<CoordsType> getObjectPositions(const GeometryObject& object, const PathHints& path) const {
392 return getChild()->getObjectPositions(object, path);
393 }
394
404 std::vector<CoordsType> getObjectPositions(const shared_ptr<const GeometryObject>& object,
405 const PathHints* path = nullptr) const {
406 return getChild()->getObjectPositions(*object, path);
407 }
408
418 std::vector<CoordsType> getObjectPositions(const shared_ptr<const GeometryObject>& object, const PathHints& path) const {
419 return getChild()->getObjectPositions(*object, path);
420 }
421
428 std::vector<typename Primitive<DIM>::Box> getLeafsBoundingBoxes(const PathHints* path = nullptr) const {
429 return getChild()->getLeafsBoundingBoxes(path);
430 }
431
438 std::vector<typename Primitive<DIM>::Box> getLeafsBoundingBoxes(const PathHints& path) const {
439 return getChild()->getLeafsBoundingBoxes(path);
440 }
441
449 std::vector<typename Primitive<DIM>::Box> getObjectBoundingBoxes(const GeometryObject& object,
450 const PathHints* path = nullptr) const {
451 return getChild()->getObjectBoundingBoxes(object, path);
452 }
453
461 std::vector<typename Primitive<DIM>::Box> getObjectBoundingBoxes(const GeometryObject& object, const PathHints& path) const {
462 return getChild()->getObjectBoundingBoxes(object, path);
463 }
464
472 std::vector<typename Primitive<DIM>::Box> getObjectBoundingBoxes(const shared_ptr<const GeometryObject>& object,
473 const PathHints* path = nullptr) const {
474 return getChild()->getObjectBoundingBoxes(*object, path);
475 }
476
484 std::vector<typename Primitive<DIM>::Box> getObjectBoundingBoxes(const shared_ptr<const GeometryObject>& object,
485 const PathHints& path) const {
486 return getChild()->getObjectBoundingBoxes(*object, path);
487 }
488
494 std::vector<shared_ptr<const GeometryObject>> getObjectsWithRole(const std::string& role) const {
495 return getChild()->getObjectsWithRole(role);
496 }
497
504 GeometryObject::Subtree getPathsAt(const CoordsType& point, bool all = false) const {
505 return getChild()->getPathsAt(wrapEdges(point), all);
506 }
507
508 // std::vector<shared_ptr<const GeometryObjectD<DIMS>>> extract(const Predicate& predicate, const PathHints* path =
509 // 0) const {
510 // return getChild()->extract(predicate, path);
511 // }
512
513 // std::vector<shared_ptr<const GeometryObjectD<DIMS>>> extract(const Predicate& predicate, const PathHints& path)
514 // const {
515 // return getChild()->extract(predicate, path);
516 // }
517
518 // std::vector<shared_ptr<const GeometryObjectD<DIMS>>> extractObject(const shared_ptr<const GeometryObjectD<DIMS>>&
519 // object, const PathHints* path = 0) const {
520 // return getChild()->extractObject(*object, path);
521 // }
522
523 // std::vector<shared_ptr<const GeometryObjectD<DIMS>>> extractObject(const shared_ptr<const GeometryObjectD<DIMS>>&
524 // object, const PathHints& path) const {
525 // return getChild()->extractObject(*object, path);
526 // }
527
535 inline shared_ptr<const GeometryObject> getMatchingAt(const CoordsType& point,
536 const Predicate& predicate,
537 const PathHints* path = 0) {
538 return getChild()->getMatchingAt(wrapEdges(point), predicate, path);
539 }
540
548 inline shared_ptr<const GeometryObject> getMatchingAt(const CoordsType& point,
549 const Predicate& predicate,
550 const PathHints& path) {
551 return getChild()->getMatchingAt(wrapEdges(point), predicate, path);
552 }
553
561 inline bool objectIncludes(const GeometryObject& object, const PathHints* path, const CoordsType& point) const {
562 return getChild()->objectIncludes(object, path, wrapEdges(point));
563 }
564
572 inline bool objectIncludes(const GeometryObject& object, const PathHints& path, const CoordsType& point) const {
573 return getChild()->objectIncludes(object, path, wrapEdges(point));
574 }
575
582 inline bool objectIncludes(const GeometryObject& object, const CoordsType& point) const {
583 return getChild()->objectIncludes(object, wrapEdges(point));
584 }
585
595 inline shared_ptr<const GeometryObject> hasRoleAt(const std::string& role_name,
596 const CoordsType& point,
597 const plask::PathHints* path = 0) const {
598 return getChild()->hasRoleAt(role_name, wrapEdges(point), path);
599 }
600
610 shared_ptr<const GeometryObject> hasRoleAt(const std::string& role_name,
611 const CoordsType& point,
612 const plask::PathHints& path) const {
613 return getChild()->hasRoleAt(role_name, wrapEdges(point), path);
614 }
615
622 std::set<std::string> getRolesAt(const CoordsType& point, const plask::PathHints* path = 0) const;
623
630 std::set<std::string> getRolesAt(const CoordsType& point, const plask::PathHints& path) const;
631
632 void setPlanarEdges(const edge::Strategy& border_to_set) override;
633
634 // /*
635 // * Get the sub/super-space of this one (automatically detected)
636 // * \param object geometry object within the geometry tree of this subspace or with this space child as its
637 // sub-tree
638 // * \param path hints specifying particular instance of the geometry object
639 // * \param copyEdges indicates whether the new space should have the same edges as this one
640 // * \return new space
641 // */
642 // virtual GeometryD<DIMS>* getSubspace(const shared_ptr<GeometryObjectD<dim>>& object, const PathHints*
643 // path=nullptr, bool copyEdges=false) const = 0;
644
645 // /*
646 // * Get the sub/super-space of this one (automatically detected) with specified edges
647 // * \param object geometry object within the geometry tree of this subspace or with this space child as its
648 // sub-tree
649 // * \param path hints specifying particular instance of the geometry object
650 // * \param edges map of edge name to edge description
651 // * \param axesNames name of the axes for edges
652 // * \return new space
653 // */
654 // virtual GeometryD<DIMS>* getSubspace(const shared_ptr<GeometryObjectD<dim>>& object, const PathHints*
655 // path=nullptr,
656 // const std::map<std::string, std::string>& edges=null_borders,
657 // const AxisNames& axesNames=AxisNames("lon","tran","up")) const {
658 // GeometryD<dim>* subspace = getSubspace(object, path, false);
659 // subspace->setEdges( [&](const std::string& s) -> plask::optional<std::string> {
660 // auto b = edges.find(s);
661 // return (b != edges.end()) ? plask::optional<std::string>(b->second) : plask::optional<std::string>();
662 // }, axesNames);
663 // return subspace;
664 // }
665
668 virtual CoordsType wrapEdges(CoordsType p) const = 0;
669
670 void writeXMLAttr(XMLWriter::Element& dest_xml_object, const AxisNames& axes) const override;
671};
672
673 template <> inline void GeometryD<2>::setPlanarEdges(const edge::Strategy& border_to_set) {
674 setEdges(DIRECTION_TRAN, border_to_set);
675}
676
677 template <> inline void GeometryD<3>::setPlanarEdges(const edge::Strategy& border_to_set) {
678 setEdges(DIRECTION_LONG, border_to_set);
679 setEdges(DIRECTION_TRAN, border_to_set);
680}
681
682 template <> void GeometryD<2>::writeXMLAttr(XMLWriter::Element& dest_xml_object, const AxisNames& axes) const;
683 template <> void GeometryD<3>::writeXMLAttr(XMLWriter::Element& dest_xml_object, const AxisNames& axes) const;
684
685 PLASK_API_EXTERN_TEMPLATE_CLASS(GeometryD<2>)
686 PLASK_API_EXTERN_TEMPLATE_CLASS(GeometryD<3>)
687
688
692 class PLASK_API Geometry2DCartesian : public GeometryD<2> {
693 shared_ptr<Extrusion> extrusion;
694
695 edge::StrategyPairHolder<Primitive<2>::DIRECTION_TRAN> leftright;
696 edge::StrategyPairHolder<Primitive<2>::DIRECTION_VERT> bottomup;
697
698 shared_ptr<Material> frontMaterial;
699 shared_ptr<Material> backMaterial;
700
701 public:
702 static constexpr const char* NAME = "cartesian" PLASK_GEOMETRY_TYPE_NAME_SUFFIX_2D;
703
704 std::string getTypeName() const override { return NAME; }
705
710 void setLeftEdge(const edge::Strategy& newValue) {
711 leftright.setLo(newValue);
712 fireChanged(Event::EVENT_EDGES);
713 }
714
719 const edge::Strategy& getLeftEdge() { return leftright.getLo(); }
720
725 void setRightEdge(const edge::Strategy& newValue) {
726 leftright.setHi(newValue);
727 fireChanged(Event::EVENT_EDGES);
728 }
729
734 const edge::Strategy& getRightEdge() { return leftright.getHi(); }
735
740 void setBottomEdge(const edge::Strategy& newValue) {
741 bottomup.setLo(newValue);
742 fireChanged(Event::EVENT_EDGES);
743 }
744
749 const edge::Strategy& getBottomEdge() { return bottomup.getLo(); }
750
755 void setTopEdge(const edge::Strategy& newValue) {
756 bottomup.setHi(newValue);
757 fireChanged(Event::EVENT_EDGES);
758 }
759
764 const edge::Strategy& getTopEdge() { return bottomup.getHi(); }
765
772 void setEdges(Direction direction, const edge::Strategy& border_lo, const edge::Strategy& border_hi) override;
773
780 void setEdge(Direction direction, bool higher, const edge::Strategy& border_to_set) override;
781
782 const edge::Strategy& getEdge(Direction direction, bool higher) const override;
783
788 void setFrontMaterial(const shared_ptr<Material> material) {
789 frontMaterial = material;
790 fireChanged(Event::EVENT_EDGES);
791 }
792
794 shared_ptr<Material> getFrontMaterial() const { return frontMaterial ? frontMaterial : defaultMaterial; }
795
800 void setBackMaterial(const shared_ptr<Material> material) {
801 backMaterial = material;
802 fireChanged(Event::EVENT_EDGES);
803 }
804
806 shared_ptr<Material> getBackMaterial() const { return backMaterial ? backMaterial : defaultMaterial; }
807
812 explicit Geometry2DCartesian(shared_ptr<Extrusion> extrusion = shared_ptr<Extrusion>());
813
820 Geometry2DCartesian(shared_ptr<GeometryObjectD<2>> childGeometry, double length);
821
826 shared_ptr<GeometryObjectD<2>> getChild() const override;
827
828 shared_ptr<GeometryObjectD<2>> getChildUnsafe() const override;
829
830 void removeAtUnsafe(std::size_t) override { extrusion->setChildUnsafe(shared_ptr<GeometryObjectD<2>>()); }
831
832 shared_ptr<Material> getMaterial(const Vec<2, double>& p) const override;
833
838 shared_ptr<Extrusion> getExtrusion() const { return extrusion; }
839
844 shared_ptr<GeometryObjectD<3>> getObject3D() const override { return extrusion; }
845
850 void setExtrusion(shared_ptr<Extrusion> extrusion);
851
852 // virtual Geometry2DCartesian* getSubspace(const shared_ptr<GeometryObjectD<2>>& object, const PathHints* path
853 // = 0, bool copyEdges = false) const;
854
855 // virtual Geometry2DCartesian* getSubspace(const shared_ptr<GeometryObjectD<2>>& object, const PathHints*
856 // path=nullptr,
857 // const std::map<std::string, std::string>& edges=null_borders,
858 // const AxisNames& axesNames=AxisNames()) const {
859 // return (Geometry2DCartesian*)GeometryD<2>::getSubspace(object, path, edges, axesNames);
860 // }
861
862 CoordsType wrapEdges(CoordsType p) const override;
863
864 shared_ptr<GeometryObject> shallowCopy() const override;
865
866 shared_ptr<GeometryObject> deepCopy(std::map<const GeometryObject*, shared_ptr<GeometryObject>>& copied) const override;
867
873 void addPointsAlongToSet(std::set<double>& points, Primitive<3>::Direction direction, unsigned = 0, double = 0) const override {
874 shared_ptr<GeometryObjectD<2>> child;
875 try {
876 child = getChild();
877 } catch (const NoChildException&) {
878 return;
879 }
880 child->addPointsAlongToSet(points, direction, max_steps, min_step_size);
881 }
882
888 std::set<double> getPointsAlong(Primitive<3>::Direction direction) const {
889 std::set<double> points;
890 addPointsAlongToSet(points, direction);
891 return points;
892 }
893
898 void addLineSegmentsToSet(std::set<typename GeometryObjectD<2>::LineSegment>& segments) const {
899 shared_ptr<GeometryObjectD<2>> child;
900 try {
901 child = getChild();
902 } catch (const NoChildException&) {
903 return;
904 }
905 child->addLineSegmentsToSet(segments, max_steps, min_step_size);
906 }
907
912 std::set<typename GeometryObjectD<2>::LineSegment> getLineSegments() const {
913 std::set<typename GeometryObjectD<2>::LineSegment> segments;
914 addLineSegmentsToSet(segments);
915 return segments;
916 }
917
924 shared_ptr<const GeometryObject> changedVersion(const Changer& changer, Vec<3, double>* translation = 0) const override;
925
926 void writeXML(XMLWriter::Element& parent_xml_object, WriteXMLCallback& write_cb, AxisNames axes) const override;
927};
928
933 class PLASK_API Geometry2DCylindrical : public GeometryD<2> {
934 shared_ptr<Revolution> revolution;
935
936 edge::StrategyPairHolder<Primitive<2>::DIRECTION_TRAN, edge::UniversalStrategy> innerouter;
937 edge::StrategyPairHolder<Primitive<2>::DIRECTION_VERT> bottomup;
938
939 static void ensureBoundDirIsProper(Direction direction /*, bool hi*/) { Primitive<3>::ensureIsValid2DDirection(direction); }
940
941 public:
942 static constexpr const char* NAME = "cylindrical";
943
944 std::string getTypeName() const override { return NAME; }
945
950 void setInnerEdge(const edge::UniversalStrategy& newValue) {
951 innerouter.setLo(newValue);
952 fireChanged(Event::EVENT_EDGES);
953 }
954
959 const edge::UniversalStrategy& getInnerEdge() { return innerouter.getLo(); }
960
965 void setOuterEdge(const edge::UniversalStrategy& newValue) {
966 innerouter.setHi(newValue);
967 fireChanged(Event::EVENT_EDGES);
968 }
969
974 const edge::UniversalStrategy& getOuterEdge() { return innerouter.getHi(); }
975
980 void setBottomEdge(const edge::Strategy& newValue) {
981 bottomup.setLo(newValue);
982 fireChanged(Event::EVENT_EDGES);
983 }
984
989 const edge::Strategy& getBottomEdge() { return bottomup.getLo(); }
990
995 void setUpEdge(const edge::Strategy& newValue) {
996 bottomup.setHi(newValue);
997 fireChanged(Event::EVENT_EDGES);
998 }
999
1004 const edge::Strategy& getUpEdge() { return bottomup.getHi(); }
1005
1010 explicit Geometry2DCylindrical(shared_ptr<Revolution> revolution = shared_ptr<Revolution>());
1011
1018 explicit Geometry2DCylindrical(shared_ptr<GeometryObjectD<2>> childGeometry);
1019
1024 shared_ptr<GeometryObjectD<2>> getChild() const override;
1025
1026 shared_ptr<GeometryObjectD<2>> getChildUnsafe() const override;
1027
1028 void removeAtUnsafe(std::size_t) override { revolution->setChildUnsafe(shared_ptr<GeometryObjectD<2>>()); }
1029
1030 shared_ptr<Material> getMaterial(const Vec<2, double>& p) const override;
1031
1036 shared_ptr<Revolution> getRevolution() const { return revolution; }
1037
1042 shared_ptr<GeometryObjectD<3>> getObject3D() const override { return revolution; }
1043
1048 void setRevolution(shared_ptr<Revolution> revolution);
1049
1050 // virtual Geometry2DCylindrical* getSubspace(const shared_ptr<GeometryObjectD<2>>& object, const PathHints*
1051 // path = 0, bool copyEdges = false) const;
1052
1053 // virtual Geometry2DCylindrical* getSubspace(const shared_ptr<GeometryObjectD<2>>& object, const PathHints*
1054 // path=nullptr,
1055 // const std::map<std::string, std::string>& edges=null_borders,
1056 // const AxisNames& axesNames=AxisNames()) const {
1057 // return (Geometry2DCylindrical*)GeometryD<2>::getSubspace(object, path, edges, axesNames);
1058 // }
1059
1060 void setEdges(Direction direction, const edge::Strategy& border_lo, const edge::Strategy& border_hi) override;
1061
1062 void setEdges(Direction direction, const edge::Strategy& border_to_set) override;
1063
1064 void setEdge(Direction direction, bool higher, const edge::Strategy& border_to_set) override;
1065
1066 const edge::Strategy& getEdge(Direction direction, bool higher) const override;
1067
1068 bool isSymmetric(Direction direction) const override {
1069 if (direction == DIRECTION_TRAN) return true;
1070 return getEdge(direction, false).type() == edge::Strategy::MIRROR ||
1071 getEdge(direction, true).type() == edge::Strategy::MIRROR;
1072 }
1073
1074 CoordsType wrapEdges(CoordsType p) const override;
1075
1076 shared_ptr<GeometryObject> shallowCopy() const override;
1077
1078 shared_ptr<GeometryObject> deepCopy(std::map<const GeometryObject*, shared_ptr<GeometryObject>>& copied) const override;
1079
1085 void addPointsAlongToSet(std::set<double>& points, Primitive<3>::Direction direction, unsigned = 0, double = 0) const override {
1086 shared_ptr<GeometryObjectD<2>> child;
1087 try {
1088 child = getChild();
1089 } catch (const NoChildException&) {
1090 return;
1091 }
1092 child->addPointsAlongToSet(points, direction, max_steps, min_step_size);
1093 }
1094
1100 std::set<double> getPointsAlong(Primitive<3>::Direction direction) const {
1101 std::set<double> points;
1102 addPointsAlongToSet(points, direction);
1103 return points;
1104 }
1105
1110 void addLineSegmentsToSet(std::set<typename GeometryObjectD<2>::LineSegment>& segments) const {
1111 shared_ptr<GeometryObjectD<2>> child;
1112 try {
1113 child = getChild();
1114 } catch (const NoChildException&) {
1115 return;
1116 }
1117 child->addLineSegmentsToSet(segments, max_steps, min_step_size);
1118 }
1119
1124 std::set<typename GeometryObjectD<2>::LineSegment> getLineSegments() const {
1125 std::set<typename GeometryObjectD<2>::LineSegment> segments;
1126 addLineSegmentsToSet(segments);
1127 return segments;
1128 }
1129
1136 shared_ptr<const GeometryObject> changedVersion(const Changer& changer, Vec<3, double>* translation = 0) const override;
1137
1138 void writeXML(XMLWriter::Element& parent_xml_object, WriteXMLCallback& write_cb, AxisNames axes) const override;
1139
1140 protected:
1141 const char* alternativeDirectionName(std::size_t ax, std::size_t orient) const override {
1142 const char* directions[3][2] = {{"cw", "ccw"}, {"inner", "outer"}, {"bottom", "top"}};
1143 return directions[ax][orient];
1144 }
1145};
1146
1150 class PLASK_API Geometry3D : public GeometryD<3> {
1151 shared_ptr<GeometryObjectD<3>> child;
1152
1153 edge::StrategyPairHolder<Primitive<3>::DIRECTION_LONG> backfront;
1154 edge::StrategyPairHolder<Primitive<3>::DIRECTION_TRAN> leftright;
1155 edge::StrategyPairHolder<Primitive<3>::DIRECTION_VERT> bottomup;
1156
1157 public:
1158 static constexpr const char* NAME = "cartesian" PLASK_GEOMETRY_TYPE_NAME_SUFFIX_3D;
1159
1160 std::string getTypeName() const override { return NAME; }
1161
1166 void setLeftEdge(const edge::Strategy& newValue) {
1167 leftright.setLo(newValue);
1168 fireChanged(Event::EVENT_EDGES);
1169 }
1170
1175 const edge::Strategy& getLeftEdge() { return leftright.getLo(); }
1176
1181 void setRightEdge(const edge::Strategy& newValue) {
1182 leftright.setHi(newValue);
1183 fireChanged(Event::EVENT_EDGES);
1184 }
1185
1190 const edge::Strategy& getRightEdge() { return leftright.getHi(); }
1191
1196 void setBottomEdge(const edge::Strategy& newValue) {
1197 bottomup.setLo(newValue);
1198 fireChanged(Event::EVENT_EDGES);
1199 }
1200
1205 const edge::Strategy& getBottomEdge() { return bottomup.getLo(); }
1206
1211 void setTopEdge(const edge::Strategy& newValue) {
1212 bottomup.setHi(newValue);
1213 fireChanged(Event::EVENT_EDGES);
1214 }
1215
1220 const edge::Strategy& getTopEdge() { return bottomup.getHi(); }
1221
1228 void setEdges(Direction direction, const edge::Strategy& border_lo, const edge::Strategy& border_hi) override;
1229
1230 void setEdges(Direction direction, const edge::Strategy& border_to_set) override;
1231
1238 void setEdge(Direction direction, bool higher, const edge::Strategy& border_to_set) override;
1239
1240 const edge::Strategy& getEdge(Direction direction, bool higher) const override;
1241
1246 explicit Geometry3D(shared_ptr<GeometryObjectD<3>> child = shared_ptr<GeometryObjectD<3>>());
1247
1252 shared_ptr<GeometryObjectD<3>> getChild() const override;
1253
1254 shared_ptr<GeometryObjectD<3>> getChildUnsafe() const override;
1255
1261 void setChildUnsafe(shared_ptr<GeometryObjectD<3>> child) {
1262 if (child == this->child) return;
1263 this->child = child;
1264 this->initNewChild();
1265 }
1266
1271 void setChild(shared_ptr<GeometryObjectD<3>> child) {
1272 // this->ensureCanHaveAsChild(*child);
1273 setChildUnsafe(child);
1274 fireChildrenChanged();
1275 }
1276
1280 bool hasChild() const { return this->child != nullptr; }
1281
1282 void removeAtUnsafe(std::size_t) override { setChildUnsafe(shared_ptr<GeometryObjectD<3>>()); }
1283
1288 shared_ptr<GeometryObjectD<3>> getObject3D() const override;
1289
1290 shared_ptr<Material> getMaterial(const Vec<3, double>& p) const override;
1291
1292 CoordsType wrapEdges(CoordsType p) const override;
1293
1294 shared_ptr<GeometryObject> shallowCopy() const override;
1295
1296 shared_ptr<GeometryObject> deepCopy(std::map<const GeometryObject*, shared_ptr<GeometryObject>>& copied) const override;
1297
1303 void addPointsAlongToSet(std::set<double>& points, Primitive<3>::Direction direction, unsigned = 0, double = 0) const override {
1304 shared_ptr<GeometryObjectD<3>> child;
1305 try {
1306 child = getChild();
1307 } catch (const NoChildException&) {
1308 return;
1309 }
1310 child->addPointsAlongToSet(points, direction, max_steps, min_step_size);
1311 }
1312
1318 std::set<double> getPointsAlong(Primitive<3>::Direction direction) const {
1319 std::set<double> points;
1320 addPointsAlongToSet(points, direction);
1321 return points;
1322 }
1323
1328 void addLineSegmentsToSet(std::set<typename GeometryObjectD<3>::LineSegment>& segments) const {
1329 shared_ptr<GeometryObjectD<3>> child;
1330 try {
1331 child = getChild();
1332 } catch (const NoChildException&) {
1333 return;
1334 }
1335 child->addLineSegmentsToSet(segments, max_steps, min_step_size);
1336 }
1337
1342 std::set<typename GeometryObjectD<3>::LineSegment> getLineSegments() const {
1343 std::set<typename GeometryObjectD<3>::LineSegment> segments;
1344 addLineSegmentsToSet(segments);
1345 return segments;
1346 }
1347
1354 shared_ptr<const GeometryObject> changedVersion(const Changer& changer, Vec<3, double>* translation = 0) const override;
1355
1356 // virtual Geometry3D* getSubspace(const shared_ptr<GeometryObjectD<3>>& object, const PathHints* path=nullptr,
1357 // bool copyEdges=false) const;
1358};
1359
1360} // namespace plask
1361
1362#endif // PLASK__CALCULATION_SPACE_H