PLaSK library

Loading...
Searching...
No Matches
transform.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 "transform.hpp"
15
16#include "../manager.hpp"
17#include "reader.hpp"
18
19#define PLASK_TRANSLATION2D_NAME ("translation" PLASK_GEOMETRY_TYPE_NAME_SUFFIX_2D)
20#define PLASK_TRANSLATION3D_NAME ("translation" PLASK_GEOMETRY_TYPE_NAME_SUFFIX_3D)
21
22 namespace plask {
23
24 template <int dim> const char* Translation<dim>::NAME = dim == 2 ? PLASK_TRANSLATION2D_NAME : PLASK_TRANSLATION3D_NAME;
25
26 template <int dim> std::string Translation<dim>::getTypeName() const { return NAME; }
27
28 template <int dim>
29 shared_ptr<Translation<dim>> Translation<dim>::compress(shared_ptr<GeometryObjectD<dim>> child_or_translation,
30 const typename Translation<dim>::DVec& translation) {
31 shared_ptr<Translation<dim>> as_translation = dynamic_pointer_cast<Translation<dim>>(child_or_translation);
32 if (as_translation) { // translations are compressed, we must create new object because we can't modify
33 // child_or_translation (which can include pointer to objects in original tree)
34 return plask::make_shared<Translation<dim>>(as_translation->getChild(),
35 as_translation->translation + translation);
36 } else {
37 return plask::make_shared<Translation<dim>>(child_or_translation, translation);
38 }
39}
40
41 template <int dim> shared_ptr<Material> Translation<dim>::getMaterial(const typename Translation<dim>::DVec& p) const {
42 return this->hasChild() ? this->_child->getMaterial(p - translation) : shared_ptr<Material>();
43}
44
45 template <int dim> bool Translation<dim>::contains(const typename Translation<dim>::DVec& p) const {
46 return this->hasChild() ? this->_child->contains(p - translation) : false;
47}
48
49 template <int dim>
50 GeometryObject::Subtree Translation<dim>::getPathsAt(const typename Translation::DVec& point, bool all) const {
51 if (!this->hasChild()) return GeometryObject::Subtree();
52 return GeometryObject::Subtree::extendIfNotEmpty(this, this->_child->getPathsAt(point - translation, all));
53}
54
55 template <int dim>
56 typename Translation<dim>::Box Translation<dim>::fromChildCoords(
57 const typename Translation<dim>::ChildType::Box& child_bbox) const {
58 return child_bbox.translated(this->translation);
59}
60
61 template <int dim>
62 void Translation<dim>::getPositionsToVec(const GeometryObject::Predicate& predicate,
63 std::vector<DVec>& dest,
64 const PathHints* path) const {
65 if (predicate(*this)) {
66 dest.push_back(Primitive<dim>::ZERO_VEC);
67 return;
68 }
69 if (!this->hasChild()) return;
70 const std::size_t old_size = dest.size();
71 this->_child->getPositionsToVec(predicate, dest, path);
72 for (std::size_t i = old_size; i < dest.size(); ++i) dest[i] += translation;
73}
74
75 template <int dim> shared_ptr<GeometryObject> Translation<dim>::shallowCopy() const { return copyShallow(); }
76
77 template <int dim>
78 shared_ptr<const GeometryObject> Translation<dim>::changedVersion(const GeometryObject::Changer& changer,
79 Vec<3, double>* translation) const {
80 shared_ptr<GeometryObject> result(const_pointer_cast<GeometryObject>(this->shared_from_this()));
81 if (changer.apply(result, translation) || !this->hasChild()) return result;
82 Vec<3, double> returned_translation(0.0, 0.0, 0.0);
83 shared_ptr<const GeometryObject> new_child = this->getChild()->changedVersion(changer, &returned_translation);
84 Vec<dim, double> translation_we_will_do = vec<dim, double>(returned_translation);
85 if (new_child == getChild() && translation_we_will_do == Primitive<dim>::ZERO_VEC) return result;
86 if (translation) // we will change translation (partially if dim==2) internally, so we recommend no extra
87 // translation
88 *translation = returned_translation -
89 vec<3, double>(translation_we_will_do); // still we can recommend translation in third direction
90 return shared_ptr<GeometryObject>(
91 new Translation<dim>(const_pointer_cast<ChildType>(dynamic_pointer_cast<const ChildType>(new_child)),
92 this->translation + translation_we_will_do));
93}
94
95 template <> void Translation<2>::writeXMLAttr(XMLWriter::Element& dest_xml_object, const AxisNames& axes) const {
96 BaseClass::writeXMLAttr(dest_xml_object, axes);
97 if (translation.tran() != 0.0) dest_xml_object.attr(axes.getNameForTran(), translation.tran());
98 if (translation.vert() != 0.0) dest_xml_object.attr(axes.getNameForVert(), translation.vert());
99}
100
101 template <> void Translation<3>::writeXMLAttr(XMLWriter::Element& dest_xml_object, const AxisNames& axes) const {
102 BaseClass::writeXMLAttr(dest_xml_object, axes);
103 if (translation.lon() != 0.0) dest_xml_object.attr(axes.getNameForLong(), translation.lon());
104 if (translation.tran() != 0.0) dest_xml_object.attr(axes.getNameForTran(), translation.tran());
105 if (translation.vert() != 0.0) dest_xml_object.attr(axes.getNameForVert(), translation.vert());
106}
107
108// template <int dim>
109// void Translation<dim>::extractToVec(const GeometryObject::Predicate &predicate, std::vector< shared_ptr<const
110// GeometryObjectD<dim> > >& dest, const PathHints *path) const {
111// if (predicate(*this)) {
112// dest.push_back(static_pointer_cast< const GeometryObjectD<dim> >(this->shared_from_this()));
113// return;
114// }
115// std::vector< shared_ptr<const GeometryObjectD<dim> > > child_res = getChild()->extract(predicate, path);
116// for (shared_ptr<const GeometryObjectD<dim>>& c: child_res)
117// dest.push_back(Translation<dim>::compress(const_pointer_cast<GeometryObjectD<dim>>(c), this->translation));
118// }
119
120 template <int dim>
121 void Translation<dim>::addPointsAlongToSet(std::set<double>& points,
122 Primitive<3>::Direction direction,
123 unsigned max_steps,
124 double min_step_size) const {
125 if (this->_child) {
126 double trans = translation[int(direction) - (3 - dim)];
127 std::set<double> child_points;
128 this->_child->addPointsAlongToSet(child_points, direction, this->max_steps ? this->max_steps : max_steps,
129 this->min_step_size ? this->min_step_size : min_step_size);
130 for (double p : child_points) points.insert(p + trans);
131 }
132}
133
134 template <int dim>
135 void Translation<dim>::addLineSegmentsToSet(std::set<typename GeometryObjectD<dim>::LineSegment>& segments,
136 unsigned max_steps,
137 double min_step_size) const {
138 if (this->_child) {
139 std::set<typename GeometryObjectD<dim>::LineSegment> child_segments;
140 this->_child->addLineSegmentsToSet(child_segments, this->max_steps ? this->max_steps : max_steps,
141 this->min_step_size ? this->min_step_size : min_step_size);
142 for (const auto& p : child_segments)
143 segments.insert(typename GeometryObjectD<dim>::LineSegment(p[0] + translation, p[1] + translation));
144 }
145}
146
147 template <typename TranslationType>
148 inline static void setupTranslation2D3D(GeometryReader& reader, TranslationType& translation) {
149 translation.translation.tran() = reader.source.getAttribute(reader.getAxisTranName(), 0.0);
150 translation.translation.vert() = reader.source.getAttribute(reader.getAxisVertName(), 0.0);
151 translation.setChild(reader.readExactlyOneChild<typename TranslationType::ChildType>());
152}
153
154 shared_ptr<GeometryObject> read_translation2D(GeometryReader& reader) {
155 GeometryReader::SetExpectedSuffix suffixSetter(reader, PLASK_GEOMETRY_TYPE_NAME_SUFFIX_2D);
156 shared_ptr<Translation<2>> translation(new Translation<2>());
157 setupTranslation2D3D(reader, *translation);
158 return translation;
159}
160
161 shared_ptr<GeometryObject> read_translation3D(GeometryReader& reader) {
162 GeometryReader::SetExpectedSuffix suffixSetter(reader, PLASK_GEOMETRY_TYPE_NAME_SUFFIX_3D);
163 shared_ptr<Translation<3>> translation(new Translation<3>());
164 translation->translation.lon() = reader.source.getAttribute(reader.getAxisLongName(), 0.0);
165 setupTranslation2D3D(reader, *translation);
166 return translation;
167}
168
169 static GeometryReader::RegisterObjectReader translation2D_reader(PLASK_TRANSLATION2D_NAME, read_translation2D);
170 static GeometryReader::RegisterObjectReader translation3D_reader(PLASK_TRANSLATION3D_NAME, read_translation3D);
171
172 template struct PLASK_API Translation<2>;
173 template struct PLASK_API Translation<3>;
174
175} // namespace plask