PLaSK library

Loading...
Searching...
No Matches
path.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 "path.hpp"
15
16#include <plask/config.hpp>
17
18#include "object.hpp"
19
20 namespace plask {
21
22 void PathHints::addHint(const Hint& hint) {
23 addHint(hint.first, hint.second);
24}
25
26 bool PathHints::includes(shared_ptr<const GeometryObject> container, shared_ptr<const GeometryObject> child_tran) const {
27 auto cont_set_it = hintFor.find(const_pointer_cast<GeometryObject>(container));
28 if (cont_set_it == hintFor.end()) return true; //no entry == no constraint == everything is included
29 return cont_set_it->second.find(const_pointer_cast<GeometryObject>(child_tran)) != cont_set_it->second.end();
30}
31
32 void PathHints::addHint(weak_ptr<GeometryObject> container, weak_ptr<GeometryObject> child) {
33 hintFor[container].insert(child);
34}
35
36 void PathHints::addAllHintsFromPath(const std::vector< shared_ptr<const GeometryObject> >& pathObjects) {
37 long possibleContainers_size = long(pathObjects.size()) - 1;
38 for (long i = 0; i < possibleContainers_size; ++i)
39 if (pathObjects[i]->isContainer())
40 addHint(const_pointer_cast<GeometryObject>(pathObjects[i]), const_pointer_cast<GeometryObject>(pathObjects[i+1]));
41}
42
43 void PathHints::addAllHintsFromPath(const Path& path) {
44 addAllHintsFromPath(path.objects);
45}
46
47 void PathHints::addAllHintsFromSubtree(const GeometryObject::Subtree &subtree) {
48 if (subtree.object->isContainer()) {
49 for (auto& c: subtree.children)
50 addHint(const_pointer_cast<GeometryObject>(subtree.object), const_pointer_cast<GeometryObject>(c.object));
51 }
52 for (auto& c: subtree.children)
53 addAllHintsFromPath(c);
54}
55
56std::set<shared_ptr<GeometryObject>> PathHints::getChildren(shared_ptr<const GeometryObject> container) {
57 std::set<shared_ptr<GeometryObject>> result;
58 auto e = hintFor.find(const_pointer_cast<GeometryObject>(container));
59 if (e == hintFor.end()) return result;
60 if (e->first.expired()) { // container was deleted, new container is under same address as was old one
61 hintFor.erase(e);
62 return result;
63 }
64 for (auto weak_child_iter = e->second.begin(); weak_child_iter != e->second.end(); ) {
65 shared_ptr<GeometryObject> child = weak_child_iter->lock();
66 if (!child) // child was deleted
67 e->second.erase(weak_child_iter++);
68 else {
69 result.insert(child);
70 ++weak_child_iter;
71 }
72 }
73 if (e->second.empty()) hintFor.erase(e); // we remove all constraints
74 return result;
75}
76
77std::set<shared_ptr<GeometryObject>> PathHints::getChildren(shared_ptr<const GeometryObject> container) const {
78 std::set<shared_ptr<GeometryObject>> result;
79 auto e = hintFor.find(const_pointer_cast<GeometryObject>(container));
80 if (e == hintFor.end() || e->first.expired()) return result;
81 for (auto child_weak: e->second) {
82 shared_ptr<GeometryObject> child = child_weak.lock();
83 if (child) result.insert(child);
84 }
85 return result;
86}
87
88 void PathHints::cleanDeleted() {
89 for(auto i = hintFor.begin(); i != hintFor.end(); )
90 if (i->first.expired())
91 hintFor.erase(i++);
92 else {
93 for (auto weak_child_iter = i->second.begin(); weak_child_iter != i->second.end(); ) {
94 if (weak_child_iter->expired())
95 i->second.erase(weak_child_iter);
96 else
97 ++weak_child_iter;
98 }
99 if (i->second.empty())
100 hintFor.erase(i++);
101 else
102 ++i;
103 }
104}
105
106//----------------- Path ------------------------------------------
107
108 bool Path::completeToFirst(const GeometryObject& newFirst, const PathHints* hints) {
109 GeometryObject::Subtree path = newFirst.getPathsTo(*objects.front(), hints);
110 if (path.empty()) return false;
111 push_front(path.toLinearPath().objects);
112 return true;
113}
114
115 bool Path::completeFromLast(const GeometryObject& newLast, const PathHints* hints) {
116 GeometryObject::Subtree path = objects.back()->getPathsTo(newLast, hints);
117 if (path.empty()) return false;
118 push_back(path.toLinearPath().objects);
119 return true;
120}
121
122 void Path::push_front(const std::vector< shared_ptr<const GeometryObject> >& toAdd) {
123 if (toAdd.empty()) return;
124 if (objects.empty()) {
125 objects = toAdd;
126 } else {
127 if (toAdd.back() == objects.front()) //last to add is already first on list?
128 objects.insert(objects.begin(), toAdd.begin(), toAdd.end()-1);
129 else
130 objects.insert(objects.begin(), toAdd.begin(), toAdd.end());
131 }
132}
133
134 void Path::push_back(const std::vector< shared_ptr<const GeometryObject> >& toAdd) {
135 if (toAdd.empty()) return;
136 if (objects.empty()) {
137 objects = toAdd;
138 } else {
139 if (toAdd.front() == objects.back()) //first to add is already as last on list?
140 objects.insert(objects.end(), toAdd.begin()+1, toAdd.end());
141 else
142 objects.insert(objects.end(), toAdd.begin(), toAdd.end());
143 }
144}
145
146 Path& Path::append(const std::vector< shared_ptr<const GeometryObject> >& path, const PathHints* hints) {
147 if (path.empty()) return *this;
148 if (objects.empty())
149 objects = path;
150 else {
151 if (completeToFirst(*path.back(), hints)) {
152 push_front(path);
153 } else
154 if (completeFromLast(*path.front(), hints)) {
155 push_back(path);
156 } else
157 throw Exception("cannot connect paths.");
158 }
159 return *this;
160}
161
162 Path& Path::append(const GeometryObject::Subtree& path, const PathHints* hints) {
163 return append(path.toLinearPath(), hints);
164}
165
166 Path& Path::append(const Path& path, const PathHints* hints) {
167 return append(path.objects, hints);
168}
169
170 Path& Path::append(const PathHints::Hint& hint, const PathHints* hints) {
171 return append(std::vector< shared_ptr<const GeometryObject> > { hint.first, hint.second }, hints);
172}
173
174 Path& Path::append(const GeometryObject& object, const PathHints* hints) {
175 return append( std::vector< shared_ptr<const GeometryObject> > { object.shared_from_this() }, hints);
176}
177
178 Path& Path::append(shared_ptr<const GeometryObject> object, const PathHints* hints) {
179 return append( std::vector< shared_ptr<const GeometryObject> > { object }, hints);
180}
181
182 PathHints Path::getPathHints() const {
183 PathHints result;
184 result.addAllHintsFromPath(*this);
185 return result;
186}
187
188} //namespace plask