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
23
namespace
plask
{
24
25
GeometryObject::CompositeChanger::CompositeChanger
(
const
Changer
*
changer
) {
26
changers
.push_back(
changer
);
27
}
28
29
GeometryObject::CompositeChanger
&
GeometryObject::CompositeChanger::operator()
(
const
Changer
*
changer
) {
30
changers.push_back(
changer
);
31
return
*
this
;
32
}
33
34
GeometryObject::CompositeChanger::~CompositeChanger
() {
35
for
(
auto
c: changers)
delete
c;
36
}
37
38
bool
GeometryObject::CompositeChanger::apply
(
shared_ptr<GeometryObject>
&
to_change
,
Vec<3, double>
* translation)
const
{
39
for
(
auto
c: changers)
if
(c->apply(
to_change
, translation))
return
true
;
40
return
false
;
41
}
42
43
bool
GeometryObject::ReplaceChanger::apply
(
shared_ptr<GeometryObject>
&
to_change
,
Vec<3, double>
* translation)
const
{
44
if
(
to_change
!= from)
return
false
;
45
to_change
= to;
46
if
(translation) *translation = this->translation;
47
return
true
;
48
}
49
50
GeometryObject::ToBlockChanger::ToBlockChanger
(
shared_ptr<const GeometryObject>
toChange
,
51
const
SolidOrGradientMaterial
& material,
52
bool
draft) {
53
from =
toChange
;
54
to =
changeToBlock
(material, from, translation, draft);
55
}
56
57
bool
GeometryObject::DeleteChanger::apply
(
shared_ptr<GeometryObject>
&
to_change
,
Vec<3, double>
*
/*translation*/
)
const
{
58
if
(
to_change
!= toDel)
return
false
;
59
to_change
=
shared_ptr<GeometryObject>
();
60
return
true
;
61
}
62
63
void
GeometryObject::WriteXMLCallback::prerareToAutonaming
(
const
GeometryObject
&
subtree_root
) {
64
subtree_root
.forEachRealObjectInSubtree([&](
const
GeometryObject
&
e
) {
return
++this->counts[&
e
] == 1; });
65
}
66
67
std::string
GeometryObject::WriteXMLCallback::getName
(
const
GeometryObject
&,
AxisNames
&)
const
{
68
return
std::string();
69
}
70
71
std::vector<std::string>
GeometryObject::WriteXMLCallback::getPathNames
(
const
GeometryObject
&,
const
GeometryObject
&, std::size_t)
const
{
72
return
std::vector<std::string>();
73
}
74
75
XMLWriter::Element
GeometryObject::WriteXMLCallback::makeTag
(
XMLElement
&
parent_tag
,
const
GeometryObject
&
object
,
AxisNames
&
axesNames
) {
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
}
82
XMLWriter::Element
tag
(
parent_tag
,
object
.
getTypeName
());
83
AxisNames
newAxesNames
=
axesNames
;
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
107
XMLElement
GeometryObject::WriteXMLCallback::makeChildTag
(
XMLElement
&
container_tag
,
const
GeometryObject
&
/*container*/
, std::size_t
/*index_of_child_in_parent*/
)
const
{
108
XMLElement
tag
(
container_tag
,
"item"
);
109
//TODO get paths
110
return
tag
;
111
}
112
113
GeometryObject::~GeometryObject
() {
114
fireChanged
(
Event::EVENT_DELETE
);
115
}
116
117
void
GeometryObject::writeXML
(
XMLWriter::Element
&
parent_xml_object
,
WriteXMLCallback
&
write_cb
,
AxisNames
axes)
const
{
118
XMLWriter::Element
tag
=
write_cb
.makeTag(
parent_xml_object
, *
this
, axes);
119
if
(
WriteXMLCallback::isRef
(
tag
))
return
;
120
writeXMLAttr
(
tag
, axes);
121
writeXMLChildren
(
tag
,
write_cb
, axes);
122
}
123
124
template
<
int
DIMS>
125
shared_ptr< GeometryObjectD<DIMS>
>
GeometryObject::asD
() {
126
if
(
getDimensionsCount
() != DIMS ||
isGeometry
())
return
shared_ptr< GeometryObjectD<DIMS>
>();
127
return
static_pointer_cast< GeometryObjectD<DIMS>
>(
shared_from_this
());
128
}
129
130
template
<
int
DIMS>
131
shared_ptr< const GeometryObjectD<DIMS>
>
GeometryObject::asD
()
const
{
132
if
(
getDimensionsCount
() != DIMS ||
isGeometry
())
return
shared_ptr< const GeometryObjectD<DIMS>
>();
133
return
static_pointer_cast< const GeometryObjectD<DIMS>
>(
shared_from_this
());
134
}
135
136
template
shared_ptr< GeometryObjectD<2>
> GeometryObject::asD<2>();
137
template
shared_ptr< GeometryObjectD<3>
> GeometryObject::asD<3>();
138
template
shared_ptr< const GeometryObjectD<2>
> GeometryObject::asD<2>()
const
;
139
template
shared_ptr< const GeometryObjectD<3>
> GeometryObject::asD<3>()
const
;
140
141
shared_ptr<Geometry>
GeometryObject::asGeometry
() {
142
return
isGeometry
() ?
static_pointer_cast<Geometry>
(
shared_from_this
()) :
shared_ptr<Geometry>
();
143
}
144
145
shared_ptr<const Geometry>
GeometryObject::asGeometry
()
const
{
146
return
isGeometry
() ?
static_pointer_cast<const Geometry>
(
shared_from_this
()) :
shared_ptr<const Geometry>
();
147
}
148
149
bool
GeometryObject::hasInSubtree
(
const
GeometryObject
&el)
const
{
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
158
bool
GeometryObject::Subtree::hasBranches
()
const
{
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
167
Path
GeometryObject::Subtree::toLinearPath
()
const
{
168
std::vector< shared_ptr<const GeometryObject> >
result
;
169
if
(empty())
return
result
;
170
const
GeometryObject::Subtree
*
path_nodes
=
this
;
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
180
Path
GeometryObject::Subtree::getLastPath
()
const
{
181
std::vector< shared_ptr<const GeometryObject> >
result
;
182
if
(empty())
return
result
;
183
const
GeometryObject::Subtree
*
path_nodes
=
this
;
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
192
void
GeometryObject::ensureCanHasAsParent
(
const
GeometryObject
&
potential_parent
)
const
{
193
if
(
hasInSubtree
(
potential_parent
))
194
throw
CyclicReferenceException
();
195
}
196
197
void
GeometryObject::writeXMLAttr
(
XMLWriter::Element
&
/*dest_xml_object*/
,
const
AxisNames
&
/*axes*/
)
const
{
198
// do nothing
199
}
200
201
void
GeometryObject::writeXMLChildren
(
XMLWriter::Element
&
dest_xml_object
,
GeometryObject::WriteXMLCallback
&
write_cb
,
const
AxisNames
&axes)
const
{
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
207
std::size_t
GeometryObject::getRealChildrenCount
()
const
{
208
return
getChildrenCount
();
209
}
210
211
shared_ptr<GeometryObject>
GeometryObject::getRealChildNo
(std::size_t
child_no
)
const
{
212
return
getChildNo
(
child_no
);
213
}
214
215
void
GeometryObject::removeAtUnsafe
(std::size_t) {
216
throw
NotImplemented
(
"removeAtUnsafe(std::size_t)"
);
217
}
218
219
void
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
227
template
<
int
dims>
228
shared_ptr<const GeometryObject>
GeometryObjectD<dims>::getMatchingAt
(
const
DVec
& point,
const
Predicate
& predicate,
const
plask::PathHints
* path)
const
{
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))
238
return
shared_ptr<const GeometryObject>
();
239
}
240
nodes = &(nodes->
children
.front());
241
}
242
return
shared_ptr<const GeometryObject>
();
243
}
244
245
template
<
int
dims>
246
std::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
252
template
struct
PLASK_API
GeometryObjectD<2>
;
253
template
struct
PLASK_API
GeometryObjectD<3>
;
254
255
}
// namespace plask
plask
geometry
object.cpp
Generated by
1.9.8