PLaSK library
Loading...
Searching...
No Matches
object.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 <boost/algorithm/string/join.hpp>
15
16#include "object.hpp"
17#include "leaf.hpp"
18#include "transform.hpp"
19#include "space.hpp"
20#include "path.hpp"
21#include "reader.hpp"
22
23namespace plask {
24
28
33
35 for (auto c: changers) delete c;
36}
37
39 for (auto c: changers) if (c->apply(to_change, translation)) return true;
40 return false;
41}
42
44 if (to_change != from) return false;
45 to_change = to;
46 if (translation) *translation = this->translation;
47 return true;
48}
49
51 const SolidOrGradientMaterial& material,
52 bool draft) {
53 from = toChange;
54 to = changeToBlock(material, from, translation, draft);
55}
56
58 if (to_change != toDel) return false;
60 return true;
61}
62
64 subtree_root.forEachRealObjectInSubtree([&](const GeometryObject& e) { return ++this->counts[&e] == 1; });
65}
66
68 return std::string();
69}
70
71std::vector<std::string> GeometryObject::WriteXMLCallback::getPathNames(const GeometryObject&, const GeometryObject&, std::size_t) const {
72 return std::vector<std::string>();
73}
74
76 auto saved_name = names_of_saved.find(&object);
77 if (saved_name != names_of_saved.end()) {
78 XMLWriter::Element ref(parent_tag, "again");
79 ref.attr("ref", saved_name->second);
80 return ref;
81 }
84 std::string name = getName(object, newAxesNames);
85 if (name.empty()) { // check if auto-name should be constructed
86 auto c = counts.find(&object);
87 if (c != counts.end() && c->second > 1) { //only for non-unique objects
88 name += "#";
89 name += boost::lexical_cast<std::string>(nextAutoName);
90 ++nextAutoName;
91 }
92 }
93 if (!name.empty()) {
94 tag.attr("name", name);
95 names_of_saved[&object] = name;
96 }
97 if (!object.roles.empty()) {
98 tag.attr("role", boost::join(object.roles, ","));
99 }
100 if (axesNames != newAxesNames) {
101 axesNames = std::move(newAxesNames);
102 tag.attr("axes", axesNames.str());
103 }
104 return tag;
105}
106
107XMLElement GeometryObject::WriteXMLCallback::makeChildTag(XMLElement& container_tag, const GeometryObject& /*container*/, std::size_t /*index_of_child_in_parent*/) const {
109 //TODO get paths
110 return tag;
111}
112
116
123
124template<int DIMS>
129
130template<int DIMS>
135
136template shared_ptr< GeometryObjectD<2> > GeometryObject::asD<2>();
137template shared_ptr< GeometryObjectD<3> > GeometryObject::asD<3>();
138template shared_ptr< const GeometryObjectD<2> > GeometryObject::asD<2>() const;
139template shared_ptr< const GeometryObjectD<3> > GeometryObject::asD<3>() const;
140
144
148
150 if (&el == this) return true;
151 std::size_t c = getRealChildrenCount();
152 for (std::size_t i = 0; i < c; ++i)
153 if (getRealChildNo(i)->hasInSubtree(el))
154 return true;
155 return false;
156}
157
159 const std::vector<Subtree>* c = &children;
160 while (!c->empty()) {
161 if (c->size() > 1) return true;
162 c = &((*c)[0].children);
163 }
164 return false;
165}
166
168 std::vector< shared_ptr<const GeometryObject> > result;
169 if (empty()) return result;
171 while (true) {
172 if (path_nodes->children.size() > 1) throw NotUniqueObjectException("there is more than one path in the subtree.");
173 result.push_back(path_nodes->object);
174 if (path_nodes->children.empty()) break;
175 path_nodes = &(path_nodes->children[0]);
176 }
177 return result;
178}
179
181 std::vector< shared_ptr<const GeometryObject> > result;
182 if (empty()) return result;
184 while (true) {
185 result.push_back(path_nodes->object);
186 if (path_nodes->children.empty()) break;
187 path_nodes = &(path_nodes->children.back());
188 }
189 return result;
190}
191
196
197void GeometryObject::writeXMLAttr(XMLWriter::Element& /*dest_xml_object*/, const AxisNames& /*axes*/) const {
198 // do nothing
199}
200
202 const std::size_t child_count = getRealChildrenCount();
203 for (std::size_t i = 0; i < child_count; ++i)
204 getRealChildNo(i)->writeXML(dest_xml_object, write_cb, axes);
205}
206
208 return getChildrenCount();
209}
210
214
216 throw NotImplemented("removeAtUnsafe(std::size_t)");
217}
218
219void GeometryObject::forEachRealObjectInSubtree(std::function<bool (const GeometryObject &)> callback) const {
220 if (!callback(*this)) return;
221 std::size_t size = getRealChildrenCount();
222 for (std::size_t i = 0; i < size; ++i) getRealChildNo(i)->forEachRealObjectInSubtree(callback);
223}
224
225// --- GeometryObjectD ---
226
227template <int dims>
229 Subtree subtree = getPathsAt(point, false);
230 // Walk the subtree
231 const GeometryObject::Subtree* nodes = &subtree;
232 while (!nodes->empty()) {
233 if (predicate(*(nodes->object))) return nodes->object;
234 if (nodes->children.empty()) return shared_ptr<const GeometryObject>();
235 assert(nodes->children.size() == 1);
236 if (path && nodes->object->isContainer()) {
237 if (!path->includes(nodes->object, nodes->children.front().object))
239 }
240 nodes = &(nodes->children.front());
241 }
243}
244
245template <int dims>
246std::set<std::string> GeometryObjectD<dims>::getRolesAt(const DVec& point, const plask::PathHints* path) const {
247 std::set<std::string> result;
248 getMatchingAt(point, [&](const GeometryObject& o)->bool { result.insert(o.roles.begin(), o.roles.end()); return false; }, path);
249 return result;
250}
251
254
255} // namespace plask