PLaSK library

Loading...
Searching...
No Matches
object.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__GEOMETRY_OBJECT_H
15#define PLASK__GEOMETRY_OBJECT_H
16
24#include <functional>
25#include <set>
26#include <tuple>
27#include <vector>
28
29#include <boost/variant.hpp>
30#include <boost/algorithm/string.hpp>
31
32#include "../material/air.hpp"
33#include "../material/material.hpp"
34#include "../material/db.hpp"
35#include "../utils/iterators.hpp"
36#include "primitives.hpp"
37
38#include <boost/signals2.hpp>
39#include "../utils/event.hpp"
40
41#include "../axes.hpp"
42#include "../utils/warnings.hpp"
43#include "../utils/xml/writer.hpp"
44
45#define BOOST_BIND_GLOBAL_PLACEHOLDERS
46#include <boost/bind.hpp>
47
49#define PLASK_GEOMETRY_TYPE_NAME_SUFFIX_2D "2d"
50
52#define PLASK_GEOMETRY_TYPE_NAME_SUFFIX_3D "3d"
53
55#define PLASK_GEOMETRY_MAX_STEPS 10
56
58#define PLASK_GEOMETRY_MIN_STEP_SIZE 0.005
59
60 namespace plask {
61
62 class GeometryReader;
63
64 struct PathHints;
65 struct Path;
66
67 struct Geometry;
68 template <int dimensions> struct GeometryObjectD;
69 template <int dimensions> struct TranslationContainer;
70
74 typedef boost::variant<shared_ptr<Material>, shared_ptr<MaterialsDB::MixedCompositionFactory>> SolidOrGradientMaterial;
75
80 struct PLASK_API GeometryObject : public enable_shared_from_this<GeometryObject> {
82 enum Type {
83 TYPE_LEAF = 0,
84 TYPE_TRANSFORM = 1,
85 TYPE_SPACE_CHANGER = 2,
86 TYPE_CONTAINER = 3,
87 TYPE_GEOMETRY = 4,
88 TYPE_SEPARATOR = 5
89 };
90
99 class PLASK_API Event : public EventWithSourceAndFlags<GeometryObject, unsigned> {
100 const GeometryObject* _originalSource;
101
102 public:
103 using EventWithSourceAndFlags<GeometryObject, unsigned>::FlagsType;
104
106 enum Flags : FlagsType {
107 EVENT_DELETE = 1 << 0,
108 EVENT_RESIZE = 1 << 1,
109 EVENT_DELEGATED = 1 << 2,
110 EVENT_CHILDREN_INSERT = 1 << 3,
111 EVENT_CHILDREN_REMOVE = 1 << 4,
112 EVENT_CHILDREN_GENERIC = 1 << 5,
113 EVENT_EDGES =
114 1 << 6,
115 EVENT_STEPS = 1 << 7,
116 EVENT_USER_DEFINED = 1 << 8
118 };
119
126 FlagsType flagsForParent() const {
127 return flagsWithout(EVENT_DELETE | EVENT_CHILDREN_INSERT | EVENT_CHILDREN_REMOVE | EVENT_CHILDREN_GENERIC) |
128 EVENT_DELEGATED | (hasFlag(EVENT_DELETE) ? EVENT_RESIZE : 0u);
129 }
130
139 FlagsType flagsForParentWithChildrenWasChangedInformation() const {
140 FlagsType result = flagsForParent();
141 if (hasAnyFlag(EVENT_CHILDREN_INSERT | EVENT_CHILDREN_REMOVE | EVENT_CHILDREN_GENERIC))
142 result |= EVENT_CHILDREN_GENERIC;
143 return result;
144 }
145
151 bool hasFlag(Flags flag) const { return hasAnyFlag(flag); }
152
157 bool isDelete() const { return hasFlag(EVENT_DELETE); }
158
163 bool isResize() const { return hasFlag(EVENT_RESIZE); }
164
169 bool isDelgatedFromChild() const { return hasFlag(EVENT_DELEGATED); }
170
175 bool hasChangedChildrenList() const {
176 return hasAnyFlag(EVENT_CHILDREN_INSERT | EVENT_CHILDREN_REMOVE | EVENT_CHILDREN_GENERIC);
177 }
178
183 bool hasChangedEdges() const { return hasFlag(EVENT_EDGES); }
184
189 const GeometryObject* originalSource() const { return _originalSource; }
190
196 explicit Event(GeometryObject* source, FlagsType flags = 0)
197 : EventWithSourceAndFlags<GeometryObject, unsigned>(source, flags), _originalSource(source) {}
198
205 explicit Event(GeometryObject* source, const GeometryObject* originalSource, FlagsType flags)
206 : EventWithSourceAndFlags<GeometryObject, unsigned>(source, flags), _originalSource(originalSource) {}
207 };
208
214 struct PLASK_API ChildrenListChangedEvent : public Event {
215 using Event::FlagsType;
216
217 ChildrenListChangedEvent(GeometryObject* source,
218 FlagsType flags,
219 const std::size_t beginIndex,
220 const std::size_t endIndex)
221 : Event(source, flags), beginIndex(beginIndex), endIndex(endIndex) {}
222
224 const std::size_t beginIndex;
225
227 const std::size_t endIndex;
228 };
229
233 struct PLASK_API Subtree {
235 shared_ptr<const GeometryObject> object;
236
238 std::vector<Subtree> children;
239
244 Subtree(shared_ptr<const GeometryObject> object = shared_ptr<const GeometryObject>()) : object(object) {}
245
251 Subtree(shared_ptr<const GeometryObject> object, const std::vector<Subtree>& children)
252 : object(object), children(children) {}
253
259 Subtree(shared_ptr<const GeometryObject> object, std::vector<Subtree>&& children)
260 : object(object), children(std::forward<std::vector<Subtree>>(children)) {}
261
272 static Subtree extendIfNotEmpty(shared_ptr<const GeometryObject> root, Subtree&& children) {
273 return children.empty() ? Subtree() : Subtree(root, std::vector<Subtree>{std::forward<Subtree>(children)});
274 }
275
286 static Subtree extendIfNotEmpty(const GeometryObject* root, Subtree&& children) {
287 return children.empty()
288 ? Subtree()
289 : Subtree(root->shared_from_this(), std::vector<Subtree>{std::forward<Subtree>(children)});
290 }
291
297 bool hasBranches() const;
298
305 Path toLinearPath() const;
306
311 Path getLastPath() const;
312
317 bool empty() const { return !object; }
318 };
319
325 struct PLASK_API Changer {
327 virtual ~Changer() {}
328
338 virtual bool apply(shared_ptr<GeometryObject>& to_change, Vec<3, double>* translation = 0) const = 0;
339 };
340
348 struct PLASK_API CompositeChanger : public Changer {
349 std::vector<const Changer*> changers;
350
355 CompositeChanger(const Changer* changer);
356
362 CompositeChanger& operator()(const Changer* changer);
363
369 CompositeChanger& append(const Changer* changer) { return operator()(changer); }
370
374 CompositeChanger() {}
375
377 ~CompositeChanger();
378
379 bool apply(shared_ptr<GeometryObject>& to_change, Vec<3, double>* translation = 0) const override;
380 };
381
385 struct PLASK_API ReplaceChanger : public Changer {
386 shared_ptr<const GeometryObject> from;
387 shared_ptr<GeometryObject> to;
388
390 Vec<3, double> translation;
391
393 ReplaceChanger() {}
394
399 ReplaceChanger(shared_ptr<const GeometryObject> from, shared_ptr<GeometryObject> to, Vec<3, double> translation)
400 : from(from), to(to), translation(translation) {}
401
407 template <typename F>
408 ReplaceChanger(const shared_ptr<const GeometryObject>& from, F calc_replace)
409 : from(from), translation(0.0, 0.0, 0.0) {
410 this->to = calc_replace(this->from);
411 }
412
413 bool apply(shared_ptr<GeometryObject>& to_change, Vec<3, double>* translation = 0) const override;
414 };
415
420 struct PLASK_API ToBlockChanger : public ReplaceChanger {
421 ToBlockChanger(shared_ptr<const GeometryObject> toChange, const SolidOrGradientMaterial& material, bool draft = false);
422 };
423
424 struct PLASK_API DeleteChanger : public Changer {
425 shared_ptr<const GeometryObject> toDel;
426
427 DeleteChanger(shared_ptr<const GeometryObject> toDel) : toDel(toDel) {}
428
429 bool apply(shared_ptr<GeometryObject>& to_change, Vec<3, double>* translation = 0) const override;
430 };
431
433 typedef std::function<bool(const GeometryObject&)> Predicate;
434
436 static bool PredicateIsLeaf(const GeometryObject& el) { return el.isLeaf(); }
437
439 struct PLASK_API PredicateIsA {
440 const GeometryObject& objectToBeEqual;
441 PredicateIsA(const GeometryObject& objectToBeEqual) : objectToBeEqual(objectToBeEqual) {}
442 PredicateIsA(const shared_ptr<GeometryObject>& objectToBeEqual) : objectToBeEqual(*objectToBeEqual) {}
443 PredicateIsA(const shared_ptr<const GeometryObject>& objectToBeEqual) : objectToBeEqual(*objectToBeEqual) {}
444 bool operator()(const GeometryObject& el) const { return &el == &objectToBeEqual; }
445 };
446
448 struct PLASK_API PredicateHasRole {
449 std::string role_name;
450 PredicateHasRole(const std::string& role_name) : role_name(role_name) {
451 boost::algorithm::trim(this->role_name);
452 };
453 PredicateHasRole(std::string&& role_name) : role_name(std::move(role_name)) {
454 boost::algorithm::trim(this->role_name);
455 };
456 bool operator()(const GeometryObject& obj) const { return obj.roles.find(role_name) != obj.roles.end(); }
457 };
458
479 class PLASK_API WriteXMLCallback {
485 std::map<const GeometryObject*, std::string> names_of_saved;
486
487 std::map<const GeometryObject*, unsigned> counts;
488
489 unsigned nextAutoName;
490
491 public:
492 WriteXMLCallback() : nextAutoName(0) {}
493
500 void prerareToAutonaming(const GeometryObject& subtree_root);
501
509 virtual std::string getName(const GeometryObject& object, AxisNames& axesNames) const;
510
518 virtual std::vector<std::string> getPathNames(const GeometryObject& parent,
519 const GeometryObject& child,
520 std::size_t index_of_child_in_parent) const;
521
533 XMLWriter::Element makeTag(XMLElement& parent_tag, const GeometryObject& object, AxisNames& axesNames);
534
535 XMLElement makeChildTag(XMLElement& container_tag,
536 const GeometryObject& container,
537 std::size_t index_of_child_in_parent) const;
538
544 static bool isRef(const XMLElement& el) { return el.getName() == "again"; }
545 };
546
548 unsigned max_steps;
549
551 double min_step_size;
552
554 void setMaxSteps(unsigned value) {
555 max_steps = value;
556 fireChanged(GeometryObject::Event::EVENT_STEPS);
557 }
558
560 void setMinStepSize(double value) {
561 min_step_size = value;
562 fireChanged(GeometryObject::Event::EVENT_STEPS);
563 }
564
566 std::set<std::string> roles;
567
569 boost::signals2::signal<void(Event&)> changed;
570
579 template <typename ClassT, typename methodT>
580 boost::signals2::connection changedConnectMethod(ClassT* obj,
581 methodT method,
582 boost::signals2::connect_position at = boost::signals2::at_back) {
583 return changed.connect(boost::bind(method, obj, _1), at);
584 }
585
587 template <typename ClassT, typename methodT> void changedDisconnectMethod(ClassT* obj, methodT method) {
588 changed.disconnect(boost::bind(method, obj, _1));
589 }
590
591 /*
592 * Just call changed with given event data.
593 * Subroles can redefine this and do some extra actions.
594 * @param evt event data
595 */
596 /*virtual void callChanged(Event& evt) {
597 changed(evt);
598 }*/
599
604 template <typename EventT = Event, typename... Args>
605 void fireChanged(Args&&... event_constructor_params_without_source) {
606 EventT evt(this, std::forward<Args>(event_constructor_params_without_source)...);
607 changed(evt); // callChanged
608 }
609
614 GeometryObject(const GeometryObject& to_copy)
615 : enable_shared_from_this<GeometryObject>(to_copy),
616 max_steps(to_copy.max_steps),
617 min_step_size(to_copy.min_step_size) {}
618
623 GeometryObject& operator=(const GeometryObject& to_copy) {
624 enable_shared_from_this<GeometryObject>::operator=(to_copy);
625 max_steps = to_copy.max_steps;
626 min_step_size = to_copy.min_step_size;
627 return *this;
628 }
629
630 GeometryObject() : max_steps(0), min_step_size(0) {}
631
632 GeometryObject(unsigned max_steps, double min_step_size) : max_steps(max_steps), min_step_size(min_step_size) {}
633
637 virtual ~GeometryObject();
638
645 virtual std::string getTypeName() const = 0;
646
656 virtual void writeXML(XMLWriter::Element& parent_xml_object,
657 WriteXMLCallback& write_cb,
658 AxisNames parent_axes) const;
659
667 void writeXML(XMLWriter::Element& parent_xml_object, WriteXMLCallback& write_cb) const {
668 writeXML(parent_xml_object, write_cb, AxisNames::getAbsoluteNames());
669 }
670
677 void writeXML(XMLWriter::Element& parent_xml_object) const {
678 WriteXMLCallback write_cb;
679 writeXML(parent_xml_object, write_cb, AxisNames::getAbsoluteNames());
680 }
681
686 template <int DIMS> shared_ptr<GeometryObjectD<DIMS>> asD();
687
692 template <int DIMS> shared_ptr<const GeometryObjectD<DIMS>> asD() const;
693
698 shared_ptr<Geometry> asGeometry();
699
704 shared_ptr<const Geometry> asGeometry() const;
705
710 virtual Type getType() const = 0;
711
712 bool isLeaf() const { return getType() == TYPE_LEAF; }
713 bool isTransform() const { return getType() == TYPE_TRANSFORM || getType() == TYPE_SPACE_CHANGER; }
714 bool isSpaceChanger() const { return getType() == TYPE_SPACE_CHANGER; }
715 bool isContainer() const { return getType() == TYPE_CONTAINER; }
716 bool isGeometry() const { return getType() == TYPE_GEOMETRY; }
717
718 /*
719 * Get material only if it this object is solid (has assign exactly one material).
720 * @return material or nullptr if it is not solid
721 *
722 * Default implementation returns nullptr.
723 */
724 // virtual shared_ptr<Material> singleMaterial() const { return shared_ptr<Material>(); }
725
733 virtual void addPointsAlongToSet(std::set<double>& points,
734 Primitive<3>::Direction PLASK_UNUSED(direction),
735 unsigned PLASK_UNUSED(max_steps),
736 double PLASK_UNUSED(min_step_size)) const = 0;
737
745 std::set<double> getPointsAlong(Primitive<3>::Direction direction,
746 unsigned max_steps = PLASK_GEOMETRY_MAX_STEPS,
747 double min_step_size = PLASK_GEOMETRY_MIN_STEP_SIZE) const {
748 std::set<double> points;
749 addPointsAlongToSet(points, direction, max_steps, min_step_size);
750 return points;
751 }
752
758 bool hasRole(std::string role_name) const {
759 boost::algorithm::trim(role_name);
760 return roles.find(role_name) != roles.end();
761 }
762
767 void addRole(std::string role_name) {
768 boost::algorithm::trim(role_name);
769 roles.insert(role_name);
770 }
771
776 void removeRole(std::string role_name) {
777 boost::algorithm::trim(role_name);
778 roles.erase(role_name);
779 }
780
784 void clearRoles() { roles.clear(); }
785
790 virtual int getDimensionsCount() const = 0;
791
798 virtual void validate() const {}
799
805 // TODO ? predicate, path
806 virtual bool hasInSubtree(const GeometryObject& el) const;
807
808 bool hasInSubtree(const GeometryObject& el, const PathHints* pathHints) const {
809 return !getObjects(PredicateIsA(el), pathHints).empty();
810 }
811
812 bool hasInSubtree(shared_ptr<const GeometryObject> el, const PathHints* pathHints) const {
813 return hasInSubtree(*el, pathHints);
814 }
815
823 // TODO ? predicate
824 virtual Subtree getPathsTo(const GeometryObject& el, const PathHints* pathHints = 0) const = 0;
825
832 virtual void getObjectsToVec(const Predicate& predicate,
833 std::vector<shared_ptr<const GeometryObject>>& dest,
834 const PathHints* path = 0) const = 0;
835
842 void getObjectsToVec(const Predicate& predicate,
843 std::vector<shared_ptr<const GeometryObject>>& dest,
844 const PathHints& path) const {
845 getObjectsToVec(predicate, dest, &path);
846 }
847
854 std::vector<shared_ptr<const GeometryObject>> getObjects(const Predicate& predicate,
855 const PathHints* path = 0) const {
856 std::vector<shared_ptr<const GeometryObject>> result;
857 getObjectsToVec(predicate, result, path);
858 return result;
859 }
860
867 std::vector<shared_ptr<const GeometryObject>> getObjects(const Predicate& predicate, const PathHints& path) const {
868 return getObjects(predicate, &path);
869 }
870
876 void getLeafsToVec(std::vector<shared_ptr<const GeometryObject>>& dest, const PathHints* path = 0) const {
877 getObjectsToVec(&GeometryObject::PredicateIsLeaf, dest, path);
878 }
879
885 void getLeafsToVec(std::vector<shared_ptr<const GeometryObject>>& dest, const PathHints& path) const {
886 getLeafsToVec(dest, &path);
887 }
888
894 std::vector<shared_ptr<const GeometryObject>> getLeafs(const PathHints* path = 0) const {
895 std::vector<shared_ptr<const GeometryObject>> result;
896 getLeafsToVec(result, path);
897 return result;
898 }
899
905 std::vector<shared_ptr<const GeometryObject>> getLeafs(const PathHints& path) const { return getLeafs(&path); }
906
912 void getObjectsWithRoleToVec(const std::string& role, std::vector<shared_ptr<const GeometryObject>>& dest) const {
913 getObjectsToVec(PredicateHasRole(role), dest);
914 }
915
921 std::vector<shared_ptr<const GeometryObject>> getObjectsWithRole(const std::string& role) const {
922 return getObjects(PredicateHasRole(role));
923 }
924
929 virtual std::size_t getChildrenCount() const = 0;
930
936 virtual shared_ptr<GeometryObject> getChildNo(std::size_t child_no) const = 0;
937
944 virtual std::size_t getRealChildrenCount() const;
945
953 virtual shared_ptr<GeometryObject> getRealChildNo(std::size_t child_no) const;
954
964 virtual void removeAtUnsafe(std::size_t index);
965
972 void removeAt(std::size_t index) {
973 ensureIsValidChildNr(index, "removeAt", "index");
974 removeAtUnsafe(index);
975 fireChildrenRemoved(index, index + 1);
976 }
977
978 void removeRangeUnsafe(std::size_t index_begin, std::size_t index_end) {
979 while (index_begin < index_end) removeAtUnsafe(--index_end);
980 }
981
987 bool removeRange(std::size_t index_begin, std::size_t index_end) {
988 if (index_begin >= index_end) return false;
989 ensureIsValidChildNr(index_end - 1, "removeRange", "index_end-1");
990 removeRangeUnsafe(index_begin, index_end);
991 fireChildrenRemoved(index_begin, index_end);
992 return true;
993 }
994
1002 virtual void forEachRealObjectInSubtree(std::function<bool(const GeometryObject&)> callback) const;
1003
1004 private:
1005 struct ChildGetter { // used by begin(), end()
1006 shared_ptr<const GeometryObject> el;
1007 ChildGetter(const shared_ptr<const GeometryObject>& el) : el(el) {}
1008 shared_ptr<GeometryObject> operator()(std::size_t index) const { return el->getChildNo(index); }
1009 };
1010
1011 public:
1013 FunctorIndexedIterator<ChildGetter> begin() const {
1014 return FunctorIndexedIterator<ChildGetter>(ChildGetter(this->shared_from_this()), 0);
1015 }
1016
1018 FunctorIndexedIterator<ChildGetter> end() const {
1019 return FunctorIndexedIterator<ChildGetter>(ChildGetter(this->shared_from_this()), getChildrenCount());
1020 }
1021
1022 // virtual GeometryTransform getTransform()
1023
1030 virtual shared_ptr<const GeometryObject> changedVersion(const Changer& changer,
1031 Vec<3, double>* translation = 0) const = 0;
1032
1037 virtual shared_ptr<GeometryObject> shallowCopy() const = 0;
1038
1044 virtual shared_ptr<GeometryObject> deepCopy(
1045 std::map<const GeometryObject*, shared_ptr<GeometryObject>>& copied) const = 0;
1046
1051 shared_ptr<GeometryObject> deepCopy() {
1052 std::map<const GeometryObject*, shared_ptr<GeometryObject>> copied;
1053 return deepCopy(copied);
1054 }
1055
1056 bool canHasAsChild(const GeometryObject& potential_child) const { return !potential_child.hasInSubtree(*this); }
1057
1058 bool canHasAsParent(const GeometryObject& potential_parent) const { return !this->hasInSubtree(potential_parent); }
1059
1064 void ensureCanHasAsParent(const GeometryObject& potential_parent) const;
1065
1070 void ensureCanHaveAsChild(const GeometryObject& potential_child) const {
1071 potential_child.ensureCanHasAsParent(*this);
1072 }
1073
1074 protected:
1082 virtual void writeXMLAttr(XMLWriter::Element& dest_xml_object, const AxisNames& axes) const;
1083
1090 virtual void writeXMLChildren(XMLWriter::Element& dest_xml_object,
1091 WriteXMLCallback& write_cb,
1092 const AxisNames& axes) const;
1093
1101 void ensureIsValidChildNr(std::size_t child_no,
1102 const char* method_name = "getChildNo",
1103 const char* arg_name = "child_no") const {
1104 std::size_t children_count = getRealChildrenCount();
1105 if (child_no >= children_count)
1106 throw OutOfBoundsException(method_name, arg_name, child_no, 0, children_count - 1);
1107 }
1108
1116 void ensureIsValidInsertPosition(std::size_t child_no,
1117 const char* method_name = "insert",
1118 const char* arg_name = "pos") const {
1119 std::size_t children_count = getRealChildrenCount();
1120 if (child_no > children_count)
1121 throw OutOfBoundsException(method_name, arg_name, child_no, 0, children_count - 1);
1122 }
1123
1125 void fireChildrenChanged() {
1126 this->fireChanged(GeometryObject::Event::EVENT_RESIZE | GeometryObject::Event::EVENT_CHILDREN_GENERIC);
1127 }
1128
1129 void fireChildrenRemoved(std::size_t beginIndex, std::size_t endIndex) {
1130 this->fireChanged<ChildrenListChangedEvent>(
1131 GeometryObject::Event::EVENT_RESIZE | GeometryObject::Event::EVENT_CHILDREN_REMOVE, beginIndex, endIndex);
1132 }
1133
1134 void fireChildrenInserted(std::size_t beginIndex, std::size_t endIndex) {
1135 this->fireChanged<ChildrenListChangedEvent>(
1136 GeometryObject::Event::EVENT_RESIZE | GeometryObject::Event::EVENT_CHILDREN_INSERT, beginIndex, endIndex);
1137 }
1138};
1139
1140 template <int dim> struct Translation;
1141
1147 template <int dim> struct PLASK_API GeometryObjectD : public GeometryObject {
1148 static const int DIM = dim;
1149 typedef typename Primitive<dim>::Box Box;
1150 typedef typename Primitive<dim>::DVec DVec;
1151
1155 struct LineSegment {
1156 private:
1157 DVec _p[2];
1158
1159 public:
1160 LineSegment(const DVec& p0, const DVec& p1) {
1161 _p[0] = p0;
1162 _p[1] = p1;
1163 if (_p[1] < _p[0]) std::swap(_p[0], _p[1]);
1164 }
1165 const DVec& p0() const { return _p[0]; }
1166 const DVec& p1() const { return _p[1]; }
1167 const DVec& operator[](std::size_t i) const { return _p[i]; }
1168
1169 bool operator<(const LineSegment& c) const {
1170 return _p[0] < c._p[0] || (!(c._p[0] < _p[0]) && _p[1] < c._p[1]);
1171 }
1172 };
1173
1174 int getDimensionsCount() const override { return dim; }
1175
1176 using GeometryObject::getPathsTo;
1177
1184 virtual Subtree getPathsAt(const DVec& point, bool all = false) const = 0;
1185
1191 virtual bool contains(const DVec& point) const = 0;
1192
1193 /*
1194 * Check if this geometry object contains some point from given @a area.
1195 * @param area rectangular area
1196 * @return true only if this geometry contains some points from @a area
1197 */
1198 // TODO unused - to use and implement in subclasses (most have impl.) or to remove
1199 // virtual bool intersects(const Box& area) const = 0;
1200
1205 virtual Box getBoundingBox() const = 0;
1206
1207 virtual DVec getBoundingBoxSize() const { return getBoundingBox().size(); }
1208
1218 virtual Box getRealBoundingBox() const { return getBoundingBox(); }
1219
1225 virtual shared_ptr<Material> getMaterial(const DVec& p) const = 0;
1226
1232 shared_ptr<Material> getMaterialOrAir(const DVec& p) const {
1233 auto real_mat = getMaterial(p);
1234 return real_mat ? real_mat : plask::make_shared<materials::Air>();
1235 }
1236
1245 virtual void getBoundingBoxesToVec(const GeometryObject::Predicate& predicate,
1246 std::vector<Box>& dest,
1247 const PathHints* path = 0) const = 0;
1248
1256 void getBoundingBoxesToVec(const GeometryObject::Predicate& predicate,
1257 std::vector<Box>& dest,
1258 const PathHints& path) const {
1259 getBoundingBoxesToVec(predicate, dest, &path);
1260 }
1261
1268 std::vector<Box> getBoundingBoxes(const GeometryObject::Predicate& predicate, const PathHints* path = 0) const {
1269 std::vector<Box> result;
1270 getBoundingBoxesToVec(predicate, result, path);
1271 return result;
1272 }
1273
1280 std::vector<Box> getBoundingBoxes(const GeometryObject::Predicate& predicate, const PathHints& path) {
1281 return getBoundingBoxes(predicate, &path);
1282 }
1283
1290 void getLeafsBoundingBoxesToVec(std::vector<Box>& dest, const PathHints* path = 0) const {
1291 getBoundingBoxesToVec(&GeometryObject::PredicateIsLeaf, dest, path);
1292 }
1293
1300 void getLeafsBoundingBoxesToVec(std::vector<Box>& dest, const PathHints& path) const {
1301 getLeafsBoundingBoxesToVec(dest, &path);
1302 }
1303
1310 std::vector<Box> getLeafsBoundingBoxes(const PathHints* path = 0) const {
1311 std::vector<Box> result;
1312 getLeafsBoundingBoxesToVec(result, path);
1313 return result;
1314 }
1315
1322 std::vector<Box> getLeafsBoundingBoxes(const PathHints& path) const { return getLeafsBoundingBoxes(&path); }
1323
1330 void getObjectBoundingBoxesToVec(std::vector<Box>& dest,
1331 const GeometryObject& object,
1332 const PathHints* path = 0) const {
1333 getBoundingBoxesToVec(GeometryObject::PredicateIsA(object), dest, path);
1334 }
1335
1342 void getObjectBoundingBoxesToVec(std::vector<Box>& dest,
1343 const GeometryObject& object,
1344 const PathHints& path) const {
1345 getObjectBoundingBoxesToVec(dest, object, &path);
1346 }
1347
1354 std::vector<Box> getObjectBoundingBoxes(const GeometryObject& object, const PathHints* path = 0) const {
1355 std::vector<Box> result;
1356 getObjectBoundingBoxesToVec(result, object, path);
1357 return result;
1358 }
1359
1367 std::vector<Box> getObjectBoundingBoxes(const GeometryObject& object, const PathHints& path) const {
1368 return getObjectBoundingBoxes(object, &path);
1369 }
1370
1382 virtual void getPositionsToVec(const Predicate& predicate,
1383 std::vector<DVec>& dest,
1384 const PathHints* path = 0) const = 0;
1385
1396 void getPositionsToVec(const Predicate& predicate, std::vector<DVec>& dest, const PathHints& path) const {
1397 getPositionsToVec(predicate, dest, &path);
1398 }
1399
1411 std::vector<DVec> getPositions(const Predicate& predicate, const PathHints* path = 0) const {
1412 std::vector<DVec> result;
1413 getPositionsToVec(predicate, result, path);
1414 return result;
1415 }
1416
1427 std::vector<DVec> getPositions(const Predicate& predicate, const PathHints& path) const {
1428 return getPositions(predicate, &path);
1429 }
1430
1440 void getLeafsPositionsToVec(std::vector<DVec>& dest, const PathHints* path = 0) const {
1441 getPositionsToVec(&GeometryObject::PredicateIsLeaf, dest, path);
1442 }
1443
1453 void getLeafsPositionsToVec(std::vector<DVec>& dest, const PathHints& path) const {
1454 getLeafsPositionsToVec(dest, &path);
1455 }
1456
1466 std::vector<DVec> getLeafsPositions(const PathHints* path = 0) const {
1467 std::vector<DVec> result;
1468 getLeafsPositionsToVec(result, path);
1469 return result;
1470 }
1471
1481 std::vector<DVec> getLeafsPositions(const PathHints& path) const { return getLeafsPositions(&path); }
1482
1493 void getObjectPositionsToVec(std::vector<DVec>& dest,
1494 const GeometryObject& object,
1495 const PathHints* path = 0) const {
1496 getPositionsToVec(PredicateIsA(object), dest, path);
1497 }
1498
1509 void getObjectPositionsToVec(std::vector<DVec>& dest, const GeometryObject& object, const PathHints& path) const {
1510 getObjectPositionsToVec(dest, object, &path);
1511 }
1512
1522 std::vector<DVec> getObjectPositions(const GeometryObject& object, const PathHints* path = 0) const {
1523 return getPositions(PredicateIsA(object), path);
1524 }
1525
1535 std::vector<DVec> getObjectPositions(const GeometryObject& object, const PathHints& path) const {
1536 return getObjectPositions(object, &path);
1537 }
1538
1539 // /*
1540 // * Get objects from the subtree with root in this, which fulfill predecate. Returned objects
1541 // * are wrapped in transformations, which transform them to the root coordinates.
1542 // * @param predicate
1543 // * @param dest[out] place to append resulted objects
1544 // * @param path
1545 // */
1546 // virtual void extractToVec(const Predicate& predicate, std::vector< shared_ptr<const GeometryObjectD<dim> > >&
1547 // dest, const PathHints* path = 0) const = 0;
1548
1549 // /*
1550 // * Get objects from the subtree with root in this, which fulfill predecate. Returned objects
1551 // * are wrapped in transformations, which transform them to the root coordinates.
1552 // * @param predicate
1553 // * @param dest[out] place to append resulted objects
1554 // * @param path
1555 // */
1556 // void extractToVec(const Predicate& predicate, std::vector< shared_ptr<const GeometryObjectD<dim> > >& dest, const
1557 // PathHints& path) const {
1558 // extractToVec(predicate, dest, &path);
1559 // }
1560
1561 // /*
1562 // * Get objects from the subtree with root in this, which fulfill predecate. Returned objects
1563 // * are wrapped in transformations, which transform them to the root coordinates.
1564 // * @param predicate
1565 // * @param path
1566 // * @return resulted objects
1567 // */
1568 // std::vector< shared_ptr<const GeometryObjectD<dim> > > extract(const Predicate& predicate, const PathHints* path
1569 // = 0) const {
1570 // std::vector< shared_ptr<const GeometryObjectD<dim> > > dest;
1571 // extractToVec(predicate, dest, path);
1572 // return dest;
1573 // }
1574
1575 // /*
1576 // * Get objects from the subtree with root in this, which fulfill predecate. Returned objects
1577 // * are wrapped in transformations, which transform them to the root coordinates.
1578 // * @param predicate
1579 // * @param path
1580 // * @return resulted objects
1581 // */
1582 // std::vector<shared_ptr<const GeometryObjectD<dim>>> extract(const Predicate& predicate, const PathHints& path)
1583 // const {
1584 // return extract(predicate, &path);
1585 // }
1586
1587 // /*
1588 // * Get instances of the object withing subtree with root in this. Returned
1589 // * are wrapped in transformations, which transform them to the root coordinates.
1590 // * @param object object to extract
1591 // * @param path
1592 // * @return resulted objects
1593 // */
1594 // std::vector<shared_ptr<const GeometryObjectD<dim>>> extractObject(const GeometryObjectD<dim>& object, const
1595 // PathHints* path = 0) {
1596 // return extract(PredicateIsA(object), path);
1597 // }
1598
1599 // /*
1600 // * Get instances of the object withing subtree with root in this. Returned intances
1601 // * are wrapped in transformations, which transform them to the root coordinates.
1602 // * @param object object to extract
1603 // * @param path
1604 // * @return resulted objects
1605 // */
1606 // std::vector<shared_ptr<const GeometryObjectD<dim>>> extractObject(const GeometryObjectD<dim>& object, const
1607 // PathHints& path) {
1608 // return extractObject(object, &path);
1609 // }
1610
1611 // /*
1612 // * Get leafs withing subtree with root in this, wrapped in transformations, which transform them to the root
1613 // coordinates.
1614 // * @param path
1615 // * @return resulted objects
1616 // */
1617 // std::vector<shared_ptr<const GeometryObjectD<dim>>> extractLeafs(const PathHints* path = 0) {
1618 // return extract(&GeometryObject::PredicateIsLeaf, path);
1619 // }
1620
1621 // /*
1622 // * Get leafs withing subtree with root in this, wrapped in transformations, which transform them to the root
1623 // coordinates.
1624 // * @param path
1625 // * @return resulted objects
1626 // */
1627 // std::vector<shared_ptr<const GeometryObjectD<dim>>> extractLeafs(const PathHints& path) {
1628 // return extractLeafs(&path);
1629 // }
1630
1631 // //TODO
1632 // //shared_ptr<const TranslationContainer<dim>> extractIntoContainer(const Predicate& predicate, const PathHints*
1633 // path = 0) const;
1634 // //shared_ptr<const TranslationContainer<dim>> extractIntoContainer(const Predicate& predicate, const PathHints&
1635 // path) const;
1636
1637 // Path getMatchingPathToObjectAt(const DVec& point, const Predicate& predicate, const PathHints* path = 0) const;
1638
1646 shared_ptr<const GeometryObject> getMatchingAt(const DVec& point,
1647 const Predicate& predicate,
1648 const PathHints* path = 0) const;
1649
1657 inline shared_ptr<const GeometryObject> getMatchingAt(const DVec& point,
1658 const Predicate& predicate,
1659 const PathHints& path) const {
1660 return getMatchingAt(point, predicate, &path);
1661 }
1662
1670 inline bool objectIncludes(const GeometryObject& object, const PathHints* path, const DVec& point) const {
1671 return getMatchingAt(point, PredicateIsA(object), path) != nullptr;
1672 }
1673
1681 inline bool objectIncludes(const GeometryObject& object, const PathHints& path, const DVec& point) const {
1682 return objectIncludes(object, &path, point);
1683 }
1684
1691 inline bool objectIncludes(const GeometryObject& object, const DVec& point) const {
1692 return objectIncludes(object, nullptr, point);
1693 }
1694
1701 std::set<std::string> getRolesAt(const DVec& point, const plask::PathHints* path = 0) const;
1702
1709 std::set<std::string> getRolesAt(const DVec& point, const plask::PathHints& path) const {
1710 return getRolesAt(point, &path);
1711 }
1712
1722 shared_ptr<const GeometryObject> hasRoleAt(const std::string& role_name,
1723 const DVec& point,
1724 const plask::PathHints* path = 0) const {
1725 return getMatchingAt(point, GeometryObject::PredicateHasRole(role_name), path);
1726 }
1727
1737 shared_ptr<const GeometryObject> hasRoleAt(const std::string& role_name,
1738 const DVec& point,
1739 const plask::PathHints& path) const {
1740 return hasRoleAt(role_name, point, &path);
1741 }
1742
1749 virtual void addLineSegmentsToSet(std::set<LineSegment>& PLASK_UNUSED(segments),
1750 unsigned PLASK_UNUSED(max_steps),
1751 double PLASK_UNUSED(min_step_size)) const = 0;
1752
1759 std::set<LineSegment> getLineSegments(unsigned max_steps = PLASK_GEOMETRY_MAX_STEPS,
1760 double min_step_size = PLASK_GEOMETRY_MIN_STEP_SIZE) const {
1761 std::set<LineSegment> segments;
1762 addLineSegmentsToSet(segments, max_steps, min_step_size);
1763 return segments;
1764 }
1765};
1766
1767 PLASK_API_EXTERN_TEMPLATE_STRUCT(GeometryObjectD<2>)
1768 PLASK_API_EXTERN_TEMPLATE_STRUCT(GeometryObjectD<3>)
1769
1770} // namespace plask
1771
1772#endif // PLASK__GEOMETRY_OBJECT_H