PLaSK library
Loading...
Searching...
No Matches
transform.hpp
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
#ifndef PLASK__GEOMETRY_TRANSFORM_H
15
#define PLASK__GEOMETRY_TRANSFORM_H
16
17
#define BOOST_BIND_GLOBAL_PLACEHOLDERS
18
#include <boost/bind.hpp>
19
#include "
object.hpp
"
20
//#include <functional>
21
22
namespace
plask
{
23
32
template
<
int
dim,
typename
Child_Type = GeometryObjectD<dim>>
33
struct
GeometryObjectTransform
:
public
GeometryObjectD
<dim> {
34
typedef
typename
GeometryObjectD<dim>::DVec
DVec
;
35
typedef
typename
GeometryObjectD<dim>::Box
Box
;
36
typedef
Child_Type
ChildType
;
37
38
explicit
GeometryObjectTransform
(shared_ptr<ChildType> child =
nullptr
) :
_child
(child) {
connectOnChildChanged
(); }
39
40
explicit
GeometryObjectTransform
(
ChildType
& child)
41
:
_child
(static_pointer_cast<
ChildType
>(child.
shared_from_this
())) {
42
connectOnChildChanged
();
43
}
44
45
virtual
~GeometryObjectTransform
() {
disconnectOnChildChanged
(); }
46
47
GeometryObject::Type
getType
()
const override
{
return
GeometryObject::TYPE_TRANSFORM
; }
48
49
/*virtual void getLeafsToVec(std::vector< shared_ptr<const GeometryObject> >& dest) const {
50
getChild()->getLeafsToVec(dest);
51
}*/
52
53
void
getObjectsToVec
(
const
GeometryObject::Predicate
& predicate,
54
std::vector<
shared_ptr<const GeometryObject>
>&
dest
,
55
const
PathHints
* path = 0)
const override
{
56
if
(predicate(*
this
)) {
57
dest
.push_back(this->
shared_from_this
());
58
}
else
{
59
if
(
hasChild
())
_child
->getObjectsToVec(predicate,
dest
, path);
60
}
61
}
62
64
virtual
void
onChildChanged
(
const
GeometryObject::Event
&
evt
) {
65
this->
fireChanged
(evt.
originalSource
(),
evt
.flagsForParent());
66
}
67
69
void
connectOnChildChanged
() {
70
if
(
hasChild
())
71
_child
->changed.connect(boost::bind(&
GeometryObjectTransform<dim, Child_Type>::onChildChanged
,
this
,
_1
));
72
}
73
75
void
disconnectOnChildChanged
() {
76
if
(
hasChild
())
77
_child
->changed.disconnect(
78
boost::bind(&
GeometryObjectTransform<dim, Child_Type>::onChildChanged
,
this
,
_1
));
79
}
80
85
inline
shared_ptr<ChildType>
getChild
()
const
{
return
_child
; }
86
93
void
setChildUnsafe
(
const
shared_ptr<ChildType>& child) {
94
if
(child ==
_child
)
return
;
95
disconnectOnChildChanged
();
96
_child
= child;
97
connectOnChildChanged
();
98
}
99
106
void
setChild
(
const
shared_ptr<ChildType>& child) {
107
// if (!child) throw NoChildException();
108
if
(child ==
_child
)
return
;
109
if
(child) this->
ensureCanHaveAsChild
(*child);
110
setChildUnsafe
(child);
111
this->
fireChildrenChanged
();
112
}
113
117
bool
hasChild
()
const
{
return
_child
!=
nullptr
; }
118
122
void
validate
()
const override
{
123
if
(!
hasChild
())
throw
NoChildException
();
124
}
125
126
bool
hasInSubtree
(
const
GeometryObject
& el)
const override
{
127
return
&el ==
this
|| (
hasChild
() &&
_child
->hasInSubtree(el));
128
}
129
130
GeometryObject::Subtree
getPathsTo
(
const
GeometryObject
& el,
const
PathHints
* path = 0)
const override
{
131
if
(
this
== &el)
return
GeometryObject::Subtree
(this->
shared_from_this
());
132
if
(!
hasChild
())
GeometryObject::Subtree
();
133
GeometryObject::Subtree
e
=
_child
->getPathsTo(el, path);
134
if
(
e
.empty())
return
GeometryObject::Subtree
();
135
GeometryObject::Subtree
result
(this->
shared_from_this
());
136
result.
children
.push_back(std::move(
e
));
137
return
result
;
138
}
139
140
std::size_t
getChildrenCount
()
const override
{
return
hasChild
() ? 1 : 0; }
141
142
shared_ptr<GeometryObject>
getChildNo
(std::size_t
child_no
)
const override
{
143
if
(!
hasChild
() ||
child_no
> 0)
throw
OutOfBoundsException
(
"geometryObjectTransform::getChildNo"
,
"child_no"
);
144
return
_child
;
145
}
146
152
shared_ptr<GeometryObjectTransform<dim, Child_Type>
>
shallowCopyWithChild
(
153
const
shared_ptr<ChildType>& child)
const
{
154
shared_ptr<GeometryObjectTransform<dim, Child_Type>
>
result
=
155
static_pointer_cast<GeometryObjectTransform<dim, Child_Type>
>(this->
shallowCopy
());
156
result->setChild(child);
157
result
->roles = this->
roles
;
158
return
result
;
159
}
160
161
shared_ptr<GeometryObject>
deepCopy
(
162
std::map<
const
GeometryObject
*,
shared_ptr<GeometryObject>
>&
copied
)
const override
{
163
auto
found
=
copied
.find(
this
);
164
if
(
found
!=
copied
.end())
return
found
->second;
165
shared_ptr<GeometryObjectTransform<dim, Child_Type>
>
result
=
166
static_pointer_cast<GeometryObjectTransform<dim, Child_Type>
>(this->
shallowCopy
());
167
copied
[
this
] =
result
;
168
if
(
hasChild
()) result->setChild(
dynamic_pointer_cast<ChildType>
(
_child
->deepCopy(
copied
)));
169
return
result
;
170
}
171
172
shared_ptr<const GeometryObject>
changedVersion
(
const
GeometryObject::Changer
&
changer
,
173
Vec<3, double>
* translation = 0)
const override
{
174
shared_ptr<GeometryObject>
result
(
const_pointer_cast<GeometryObject>
(this->
shared_from_this
()));
175
if
(changer.
apply
(
result
, translation) || !
hasChild
())
return
result
;
176
shared_ptr<const GeometryObject>
new_child
=
_child
->changedVersion(
changer
, translation);
177
if
(!
new_child
)
return
shared_ptr<const GeometryObject>
();
// child was deleted, so we also should be
178
return
new_child
==
_child
?
result
179
:
shallowCopyWithChild
(
const_pointer_cast<ChildType>
(
180
dynamic_pointer_cast<const ChildType>
(
new_child
)));
181
}
182
183
void
removeAtUnsafe
(std::size_t)
override
{
_child
.reset(); }
184
190
virtual
Box
fromChildCoords
(
const
typename
ChildType::Box
&
child_bbox
)
const
= 0;
191
192
Box
getBoundingBox
()
const override
{
193
return
this->
hasChild
() ? this->
fromChildCoords
(this->
_child
->getBoundingBox())
194
:
Box
(
Primitive<dim>::ZERO_VEC
,
Primitive<dim>::ZERO_VEC
);
195
}
196
197
void
getBoundingBoxesToVec
(
const
GeometryObject::Predicate
& predicate,
198
std::vector<Box>&
dest
,
199
const
PathHints
* path)
const override
{
200
if
(predicate(*
this
)) {
201
dest
.push_back(this->
getBoundingBox
());
202
return
;
203
}
204
if
(!
hasChild
())
return
;
205
auto
child_boxes
= this->
_child
->getBoundingBoxes(predicate, path);
206
dest
.reserve(
dest
.size() +
child_boxes
.size());
207
for
(
auto
& r :
child_boxes
)
dest
.push_back(
this
->fromChildCoords(r));
208
}
209
215
inline
bool
childHasType
(
GeometryObject::Type
type)
const
{
return
hasChild
() && (
_child
->getType() == type); }
216
217
protected
:
218
shared_ptr<ChildType>
_child
;
219
224
template
<
typename
ThisType>
225
inline
static
void
_getNotChangedPositionsToVec
(
ThisType
_this
,
226
const
GeometryObject::Predicate
& predicate,
227
std::vector<DVec>&
dest
,
228
const
PathHints
* path) {
229
if
(predicate(*
_this
)) {
230
dest
.push_back(
Primitive<dim>::ZERO_VEC
);
231
return
;
232
}
233
if
(
_this
->hasChild())
_this
->_child->getPositionsToVec(predicate,
dest
, path);
234
}
235
};
236
244
template
<
int
this_dim
,
int
child_dim
= 5 -
this_dim
,
typename
ChildType =
GeometryObjectD<child_dim>
>
245
struct
GeometryObjectTransformSpace
:
public
GeometryObjectTransform
<this_dim, ChildType> {
246
typedef
typename
ChildType::Box
ChildBox
;
247
typedef
typename
ChildType::DVec
ChildVec
;
248
typedef
typename
GeometryObjectTransform<this_dim, ChildType>::DVec
DVec
;
249
using
GeometryObjectTransform
<
this_dim
,
ChildType
>
::getChild
;
250
251
explicit
GeometryObjectTransformSpace
(shared_ptr<ChildType> child = shared_ptr<ChildType>())
252
:
GeometryObjectTransform
<
this_dim
,
ChildType
>(child) {}
253
255
GeometryObject::Type
getType
()
const override
{
return
GeometryObject::TYPE_SPACE_CHANGER
; }
256
257
/*virtual std::vector< std::tuple<shared_ptr<const GeometryObject>, DVec> > getLeafsWithTranslations() const {
258
std::vector< shared_ptr<const GeometryObject> > v = getChild()->getLeafs();
259
std::vector< std::tuple<shared_ptr<const GeometryObject>, DVec> > result(v.size());
260
std::transform(v.begin(), v.end(), result.begin(), [](shared_ptr<const GeometryObject> e) {
261
return std::make_pair(e, Primitive<this_dim>::NAN_VEC);
262
});
263
return result;
264
}*/
265
};
266
271
template
<
int
dim>
struct
PLASK_API
Translation
:
public
GeometryObjectTransform
<dim> {
272
typedef
GeometryObjectTransform<dim>
BaseClass
;
273
274
static
const
char
*
NAME
;
275
276
std::string getTypeName()
const override
;
277
278
typedef
typename
BaseClass::ChildType
ChildType
;
279
281
typedef
typename
BaseClass::DVec
DVec
;
282
284
typedef
typename
BaseClass::Box
Box
;
285
286
using
BaseClass::getChild;
287
291
DVec
translation
;
292
293
// Translation(const Translation<dim>& translation) = default;
294
299
explicit
Translation
(shared_ptr<
GeometryObjectD<dim>
> child = shared_ptr<
GeometryObjectD<dim>
>(),
300
const
DVec
& translation =
Primitive<dim>::ZERO_VEC
)
301
:
BaseClass
(child), translation(translation) {}
302
303
explicit
Translation
(
GeometryObjectD<dim>
& child,
const
DVec
& translation =
Primitive<dim>::ZERO_VEC
)
304
:
BaseClass
(child), translation(translation) {}
305
315
static
shared_ptr<Translation<dim>
> compress(
316
shared_ptr<
GeometryObjectD<dim>
>
child_or_translation
= shared_ptr<
GeometryObjectD<dim>
>(),
317
const
DVec& translation =
Primitive<dim>::ZERO_VEC
);
318
319
shared_ptr<Material>
getMaterial(
const
DVec& p)
const override
;
320
321
bool
contains(
const
DVec& p)
const override
;
322
323
// TODO to use (impl. is good) or remove
324
/*virtual bool intersects(const Box& area) const {
325
return getChild()->intersects(area.translated(-translation));
326
}*/
327
328
using
GeometryObjectTransform
<dim>::getPathsTo;
329
330
GeometryObject::Subtree
getPathsAt(
const
DVec& point,
bool
all
=
false
)
const override
;
331
332
/*virtual void getLeafsInfoToVec(std::vector< std::tuple<shared_ptr<const GeometryObject>, Box, DVec> >& dest, const
333
PathHints* path = 0) const { const std::size_t old_size = dest.size(); getChild()->getLeafsInfoToVec(dest, path);
334
for (auto i = dest.begin() + old_size; i != dest.end(); ++i) {
335
std::get<1>(*i).translate(translation);
336
std::get<2>(*i) += translation;
337
}
338
}*/
339
340
Box fromChildCoords(
const
typename
ChildType::Box&
child_bbox
)
const override
;
341
342
/*virtual std::vector< std::tuple<shared_ptr<const GeometryObject>, DVec> > getLeafsWithTranslations() const {
343
std::vector< std::tuple<shared_ptr<const GeometryObject>, DVec> > result =
344
getChild()->getLeafsWithTranslations(); for (std::tuple<shared_ptr<const GeometryObject>, DVec>& r: result)
345
std::get<1>(r) += translation; return result;
346
}*/
347
348
virtual
void
getPositionsToVec(
const
GeometryObject::Predicate
& predicate,
349
std::vector<DVec>&
dest
,
350
const
PathHints
* path = 0)
const override
;
351
356
shared_ptr<Translation<dim>
>
copyShallow
()
const
{
357
return
shared_ptr<Translation<dim>
>(
new
Translation<dim>
(getChild(), translation));
358
}
359
360
shared_ptr<GeometryObject>
shallowCopy()
const override
;
361
362
virtual
shared_ptr<const GeometryObject>
changedVersion(
const
GeometryObject::Changer
&
changer
,
363
Vec<3, double>
* translation = 0)
const override
;
364
369
shared_ptr<Translation<dim>
>
copyShallow
(
const
DVec
&
new_translation
)
const
{
370
return
shared_ptr<Translation<dim>
>(
new
Translation<dim>
(getChild(),
new_translation
));
371
}
372
373
void
writeXMLAttr
(
XMLWriter::Element
&
dest_xml_object
,
const
AxisNames
& axes)
const override
;
374
375
// void extractToVec(const GeometryObject::Predicate &predicate, std::vector< shared_ptr<const GeometryObjectD<dim>
376
// > >& dest, const PathHints *path) const;
377
378
void
addPointsAlongToSet(std::set<double>& points,
379
Primitive<3>::Direction
direction,
380
unsigned
max_steps,
381
double
min_step_size)
const override
;
382
383
void
addLineSegmentsToSet(std::set<
typename
GeometryObjectD<dim>::LineSegment
>& segments,
384
unsigned
max_steps,
385
double
min_step_size)
const override
;
386
};
387
388
template
<>
void
Translation<2>::writeXMLAttr
(
XMLWriter::Element
&
dest_xml_object
,
const
AxisNames
& axes)
const
;
389
template
<>
void
Translation<3>::writeXMLAttr
(
XMLWriter::Element
&
dest_xml_object
,
const
AxisNames
& axes)
const
;
390
391
PLASK_API_EXTERN_TEMPLATE_STRUCT
(
Translation<2>
)
392
PLASK_API_EXTERN_TEMPLATE_STRUCT
(
Translation<3>
)
393
394
}
// namespace plask
395
396
#endif
// PLASK__GEOMETRY_TRANSFORM_H
plask
geometry
transform.hpp
Generated by
1.9.8