PLaSK library
Loading...
Searching...
No Matches
translation_container.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 */
15
16#include <cstdlib> //abs
17
18#define PLASK_TRANSLATIONCONTAINER2D_NAME ("container" PLASK_GEOMETRY_TYPE_NAME_SUFFIX_2D)
19#define PLASK_TRANSLATIONCONTAINER3D_NAME ("container" PLASK_GEOMETRY_TYPE_NAME_SUFFIX_3D)
20
21namespace plask {
22
23template <int dim>
25
26template <int dim>
30
31template <int dim>
33 invalidateCache();
34 return this->_addUnsafe(newTranslation(el, aligner), aligner);
35}
36
37template <int dim>
39 return this->addUnsafe(el, align::fromVector(translation));
40}
41
42template <int dim>
43PathHints::Hint TranslationContainer<dim>::insertUnsafe(const std::size_t pos, shared_ptr<typename TranslationContainer<dim>::ChildType> el, ChildAligner aligner) {
44 invalidateCache();
45 return this->_insertUnsafe(pos, newTranslation(el, aligner), aligner);
46}
47
48template <int dim>
49PathHints::Hint TranslationContainer<dim>::insertUnsafe(const std::size_t pos, shared_ptr<typename TranslationContainer<dim>::ChildType> el, const typename TranslationContainer<dim>::DVec& translation) {
50 return this->insertUnsafe(pos, el, align::fromVector(translation));
51}
52
53/*template <>
54void TranslationContainer<2>::writeXMLChildAttr(XMLWriter::Element &dest_xml_child_tag, std::size_t child_index, const AxisNames &axes) const {
55 shared_ptr<Translation<2>> child_tran = children[child_index];
56 if (child_tran->translation.tran() != 0.0) dest_xml_child_tag.attr(axes.getNameForTran(), child_tran->translation.tran());
57 if (child_tran->translation.vert() != 0.0) dest_xml_child_tag.attr(axes.getNameForVert(), child_tran->translation.vert());
58}
59
60template <>
61void TranslationContainer<3>::writeXMLChildAttr(XMLWriter::Element &dest_xml_child_tag, std::size_t child_index, const AxisNames &axes) const {
62 shared_ptr<Translation<3>> child_tran = children[child_index];
63 if (child_tran->translation.lon() != 0.0) dest_xml_child_tag.attr(axes.getNameForTran(), child_tran->translation.lon());
64 if (child_tran->translation.tran() != 0.0) dest_xml_child_tag.attr(axes.getNameForTran(), child_tran->translation.tran());
65 if (child_tran->translation.vert() != 0.0) dest_xml_child_tag.attr(axes.getNameForVert(), child_tran->translation.vert());
66}*/
67
68template <int dim>
70 delete cache.load();
71 cache = nullptr;
72}
73
74template <int dim>
76 if (!cache.load())
77 cache = buildSpatialIndex<dim>(children).release();
78 return cache;
79}
80
81template <int dim>
83 if (cache.load()) return cache;
84 boost::lock_guard<boost::mutex> lock(const_cast<boost::mutex&>(cache_mutex));
85 //this also will check if cache is non-null egain, someone could build cache when we waited for enter to critical section:
86 return const_cast<TranslationContainer<dim>*>(this)->ensureHasCache();
87}
88
89template <int dim>
92 for (std::size_t child_no = 0; child_no < children.size(); ++child_no)
93 result->addUnsafe(children[child_no]->getChild(), children[child_no]->translation);
94 return result;
95}
96
97template <int dim>
99 auto found = copied.find(this);
100 if (found != copied.end()) return found->second;
102 for (std::size_t child_no = 0; child_no < children.size(); ++child_no)
103 if (children[child_no]->getChild())
104 result->addUnsafe(static_pointer_cast<ChildType>(children[child_no]->getChild()->deepCopy(copied)), children[child_no]->translation);
105 return result;
106 copied[this] = result;
107 return result;
108}
109
110
111template <int dim>
113 std::vector<std::pair<shared_ptr<ChildType>, Vec<3, double>>>& children_after_change, Vec<3, double>* /*recomended_translation*/) const {
115 for (std::size_t child_no = 0; child_no < children.size(); ++child_no)
117 result->addUnsafe(children_after_change[child_no].first, children[child_no]->translation + vec<dim, double>(children_after_change[child_no].second));
118 return result;
119}
120
121template <int dim>
123 shared_ptr<TranslationT> trans_geom = plask::make_shared<TranslationT>(el);
124 aligner.align(*trans_geom);
125 return trans_geom;
126}
127
128// ---- containers readers: ----
129
130template <int dim>
134 const bool reverse = reader.source.enumAttribute<bool>("order")
135 .value("normal", false)
136 .value("reverse", true)
137 .get(false);
138 auto default_aligner = align::fromXML(reader.source, reader.getAxisNames(), align::fromVector(Primitive<dim>::ZERO_VEC));
139 if (reverse) {
140 read_children(reader,
141 [&]() -> PathHints::Hint {
142 auto aligner = align::fromXML(reader.source, reader.getAxisNames(), default_aligner);
143 return result->insert(0, reader.readExactlyOneChild<typename TranslationContainer<dim>::ChildType>(), aligner);
144 },
145 [&]() {
146 result->insert(0, reader.readObject<typename TranslationContainer<dim>::ChildType>(), default_aligner);
147 }
148 );
149 } else {
150 read_children(reader,
151 [&]() -> PathHints::Hint {
152 auto aligner = align::fromXML(reader.source, reader.getAxisNames(), default_aligner);
154 },
155 [&]() {
156 result->add(reader.readObject<typename TranslationContainer<dim>::ChildType>(), default_aligner);
157 }
158 );
159 }
160 return result;
161}
162
163static GeometryReader::RegisterObjectReader container2D_reader(PLASK_TRANSLATIONCONTAINER2D_NAME, read_TranslationContainer<2>);
164static GeometryReader::RegisterObjectReader container3D_reader(PLASK_TRANSLATIONCONTAINER3D_NAME, read_TranslationContainer<3>);
165static GeometryReader::RegisterObjectReader align_container2D_reader("align2d", read_TranslationContainer<2>);
166static GeometryReader::RegisterObjectReader align_container3D_reader("align3d", read_TranslationContainer<3>);
167
170
171} // namespace plask