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 */
14#include "translation_container.hpp"
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
21 namespace plask {
22
23 template <int dim>
24 const char* TranslationContainer<dim>::NAME = dim == 2 ? PLASK_TRANSLATIONCONTAINER2D_NAME : PLASK_TRANSLATIONCONTAINER3D_NAME;
25
26 template <int dim>
27 TranslationContainer<dim>::~TranslationContainer() {
28 delete cache.load();
29}
30
31 template <int dim>
32 PathHints::Hint TranslationContainer<dim>::addUnsafe(shared_ptr<typename TranslationContainer<dim>::ChildType> el, ChildAligner aligner) {
33 invalidateCache();
34 return this->_addUnsafe(newTranslation(el, aligner), aligner);
35}
36
37 template <int dim>
38 PathHints::Hint TranslationContainer<dim>::addUnsafe(shared_ptr<typename TranslationContainer<dim>::ChildType> el, const typename TranslationContainer<dim>::DVec& translation) {
39 return this->addUnsafe(el, align::fromVector(translation));
40}
41
42 template <int dim>
43 PathHints::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
48 template <int dim>
49 PathHints::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 <>
54 void 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
60 template <>
61 void 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
68 template <int dim>
69 void TranslationContainer<dim>::invalidateCache() {
70 delete cache.load();
71 cache = nullptr;
72}
73
74 template <int dim>
75 SpatialIndexNode<dim>* TranslationContainer<dim>::ensureHasCache() {
76 if (!cache.load())
77 cache = buildSpatialIndex<dim>(children).release();
78 return cache;
79}
80
81 template <int dim>
82 SpatialIndexNode<dim>* TranslationContainer<dim>::ensureHasCache() const {
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
89 template <int dim>
90 shared_ptr<GeometryObject> TranslationContainer<dim>::shallowCopy() const {
91 shared_ptr<TranslationContainer<dim>> result = plask::make_shared<TranslationContainer<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
97 template <int dim>
98 shared_ptr<GeometryObject> TranslationContainer<dim>::deepCopy(std::map<const GeometryObject*, shared_ptr<GeometryObject>>& copied) const {
99 auto found = copied.find(this);
100 if (found != copied.end()) return found->second;
101 shared_ptr<TranslationContainer<dim>> result = plask::make_shared<TranslationContainer<dim>>();
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
111 template <int dim>
112 shared_ptr<GeometryObject> TranslationContainer<dim>::changedVersionForChildren(
113 std::vector<std::pair<shared_ptr<ChildType>, Vec<3, double>>>& children_after_change, Vec<3, double>* /*recomended_translation*/) const {
114 shared_ptr<TranslationContainer<dim>> result = plask::make_shared<TranslationContainer<dim>>();
115 for (std::size_t child_no = 0; child_no < children.size(); ++child_no)
116 if (children_after_change[child_no].first)
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
121 template <int dim>
122 shared_ptr<typename TranslationContainer<dim>::TranslationT> TranslationContainer<dim>::newTranslation(const shared_ptr<typename TranslationContainer<dim>::ChildType>& el, ChildAligner aligner) {
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
130 template <int dim>
131 shared_ptr<GeometryObject> read_TranslationContainer(GeometryReader& reader) {
132 shared_ptr< TranslationContainer<dim> > result(new TranslationContainer<dim>());
133 GeometryReader::SetExpectedSuffix suffixSetter(reader, dim == 2 ? PLASK_GEOMETRY_TYPE_NAME_SUFFIX_2D : PLASK_GEOMETRY_TYPE_NAME_SUFFIX_3D);
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);
153 return result->add(reader.readExactlyOneChild<typename TranslationContainer<dim>::ChildType>(), aligner);
154 },
155 [&]() {
156 result->add(reader.readObject<typename TranslationContainer<dim>::ChildType>(), default_aligner);
157 }
158 );
159 }
160 return result;
161}
162
163 static GeometryReader::RegisterObjectReader container2D_reader(PLASK_TRANSLATIONCONTAINER2D_NAME, read_TranslationContainer<2>);
164 static GeometryReader::RegisterObjectReader container3D_reader(PLASK_TRANSLATIONCONTAINER3D_NAME, read_TranslationContainer<3>);
165 static GeometryReader::RegisterObjectReader align_container2D_reader("align2d", read_TranslationContainer<2>);
166 static GeometryReader::RegisterObjectReader align_container3D_reader("align3d", read_TranslationContainer<3>);
167
168 template struct PLASK_API TranslationContainer<2>;
169 template struct PLASK_API TranslationContainer<3>;
170
171} // namespace plask