PLaSK library

Loading...
Searching...
No Matches
filter.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__FILTER_H
15#define PLASK__FILTER_H
16
17#include "translation.hpp"
18#include "change_space_size.hpp"
19#include "change_space_size_cyl.hpp"
20
21 namespace plask {
22
23 struct FilterCommonBase: public Solver {
24 template <typename... Args>
25 FilterCommonBase(Args&&... args): Solver(std::forward<Args>(args)...) {}
26};
27
29 template <typename PropertyT, PropertyType propertyType, typename OutputSpaceType, typename VariadicTemplateTypesHolder>
30 struct FilterBaseImpl {
31 static_assert(propertyType == FIELD_PROPERTY || propertyType == MULTI_FIELD_PROPERTY,
32 "Filter can't be used with value properties (it can be used with field properties only)");
33};
34
35 template <typename PropertyT, typename OutputSpaceType, typename... ExtraArgs>
36 struct FilterBaseImpl< PropertyT, FIELD_PROPERTY, OutputSpaceType, VariadicTemplateTypesHolder<ExtraArgs...> >
37 : public FilterCommonBase
38{
39 // one outer source (input)
40 // vector of inner sources (inputs)
41 // one output (provider)
42
43 typedef typename PropertyAt<PropertyT, OutputSpaceType>::ValueType ValueType;
44 typedef DataSource<PropertyT, OutputSpaceType> DataSourceT;
45 typedef std::unique_ptr<DataSourceT> DataSourceTPtr;
46 typedef std::function<plask::optional<ValueType>(std::size_t)> DataSourceF;
47
48 struct FilterLazyDataImpl: public LazyDataImpl<ValueType> {
49
50 DataSourceF outerSourceData;
51
52 std::vector<DataSourceF> innerSourcesData;
53
54 /*const FilterBaseImpl< PropertyT, FIELD_PROPERTY, OutputSpaceType, VariadicTemplateTypesHolder<ExtraArgs...> >& filter;*/
55 shared_ptr<const MeshD<OutputSpaceType::DIM>> dst_mesh;
56 //std::tuple<ExtraArgs...> extra_args;
57 //InterpolationMethod method;
58
59 FilterLazyDataImpl(
60 const FilterBaseImpl< PropertyT, FIELD_PROPERTY, OutputSpaceType, VariadicTemplateTypesHolder<ExtraArgs...> >& filter,
61 const shared_ptr<const MeshD<OutputSpaceType::DIM>>& dst_mesh, ExtraArgs... extra_args, InterpolationMethod method
62 )
63 : innerSourcesData(filter.innerSources.size()), /*filter(filter),*/ dst_mesh(dst_mesh)/*, extra_args(extra_args...), method(method)*/ {
64 for (std::size_t source_index = 0; source_index < filter.innerSources.size(); ++source_index)
65 innerSourcesData[source_index] = filter.innerSources[source_index]->operator()(dst_mesh, std::forward<ExtraArgs>(extra_args)..., method);
66 outerSourceData = filter.outerSource->operator()(dst_mesh, std::forward<ExtraArgs>(extra_args)..., method);
67 }
68
69 ValueType at(std::size_t point_index) const override {
70 for (std::size_t source_index = 0; source_index < innerSourcesData.size(); ++source_index) {
71 //if (!innerSourcesData[source_index])
72 // innerSourcesData[source_index] = filter.innerSources[source_index]->operator()(dst_mesh, extra_args, method);
73 plask::optional<ValueType> v = innerSourcesData[source_index](point_index);
74 if (v) return *v;
75 }
76 //if (!outerSourceData) outerSourceData = filter.outerSource->operator()(dst_mesh, extra_args, method);
77 return *outerSourceData(point_index);
78 }
79
80 std::size_t size() const override { return dst_mesh->size(); }
81
82 };
83
84 protected:
85 std::vector<DataSourceTPtr> innerSources;
86
87 DataSourceTPtr outerSource;
88
90 shared_ptr<OutputSpaceType> geometry;
91
92 template <typename SourceType>
93 auto setOuterRecv(std::unique_ptr<SourceType>&& outerSource) -> decltype(outerSource->in)& {
94 decltype(outerSource->in)& res = outerSource->in;
95 // setOuter(std::move(outerSource)); //can't call fireChange before connecting provider to returned receiver
96 disconnect(this->outerSource);
97 this->outerSource = std::move(outerSource);
98 connect(*this->outerSource);
99 return res;
100 }
101
102 template <typename SourceType>
103 auto appendInnerRecv(std::unique_ptr<SourceType>&& innerSource) -> decltype(innerSource->in)& {
104 decltype(innerSource->in)& res = innerSource->in;
105 this->innerSources.push_back(std::move(innerSource));
106 connect(*this->innerSources.back());
107 return res;
108 }
109
110 public:
111
113 typename ProviderFor<PropertyT, OutputSpaceType>::Delegate out;
114
119 FilterBaseImpl(shared_ptr<OutputSpaceType> geometry): FilterCommonBase("Filter"), geometry(geometry),
120 out([&] (const shared_ptr<const MeshD<OutputSpaceType::DIM>>& dst_mesh, ExtraArgs&&... extra_args, InterpolationMethod method) -> LazyData<ValueType> {
121 return this->get(dst_mesh, std::forward<ExtraArgs>(extra_args)..., method);
122 })
123 {
124 setDefault(PropertyAt<PropertyT, OutputSpaceType>::getDefaultValue());
125 }
126
127 std::string getClassName() const override { return "Filter"; }
128
133 shared_ptr<OutputSpaceType> getGeometry() const { return geometry; }
134
142 LazyData<ValueType> get(const shared_ptr<const MeshD<OutputSpaceType::DIM>>& dst_mesh, ExtraArgs... extra_args, InterpolationMethod method) const {
143 return new FilterLazyDataImpl(*this, dst_mesh, std::forward<ExtraArgs>(extra_args)..., method);
144 /*if (innerSources.empty()) //special case, for fast getting data from outer source
145 return (*outerSource)(dst_mesh, std::forward<ExtraArgs>(extra_args)..., method);
146 DataVector<ValueT> result(dst_mesh.size());
147 NoLogging nolog;
148 bool silent = outerSource && typeid(*outerSource) != typeid(ConstDataSource<PropertyT, OutputSpaceType>);
149 for (std::size_t i = 0; i < result.size(); ++i) {
150 // iterate over inner sources, if inner sources don't provide data, use outer source:
151 plask::optional<ValueT> innerVal;
152 for (const DataSourceTPtr& innerSource: innerSources) {
153 innerVal = innerSource->get(dst_mesh[i], std::forward<ExtraArgs>(extra_args)..., method);
154 if (innerVal) { silent = true; break; }
155 }
156 result[i] = *(innerVal ? innerVal : outerSource->get(dst_mesh[i], std::forward<ExtraArgs>(extra_args)..., method));
157 if (silent) nolog.silence();
158 }
159 return result;*/
160 }
161
166 void setOuter(DataSourceTPtr&& outerSource) {
167 disconnect(this->outerSource);
168 this->outerSource = std::move(outerSource);
169 connect(*this->outerSource);
170 out.fireChanged();
171 }
172
177 void setDefault(const ValueType& value) {
178 disconnect(this->outerSource);
179 this->outerSource.reset(new ConstDataSource<PropertyT, OutputSpaceType>(value));
180 connect(*this->outerSource);
181 out.fireChanged();
182 }
183
188 void appendInner(DataSourceTPtr&& innerSource) {
189 this->innerSources.push_back(std::move(innerSource));
190 connect(*this->innerSources.back());
191 out.fireChanged();
192 }
193
200 virtual ReceiverFor<PropertyT, Geometry3D>& input(GeometryObjectD<3>& obj, const PathHints* path = nullptr) = 0;
201
202 ReceiverFor<PropertyT, Geometry3D>& input(shared_ptr<GeometryObjectD<3>> obj, const PathHints* path = nullptr) {
203 return input(*obj, path);
204 }
205
206 ReceiverFor<PropertyT, Geometry3D>& input(Geometry3D& inGeom, const PathHints* path = nullptr) {
207 return input(inGeom.getChild(), path);
208 }
209
210 ReceiverFor<PropertyT, Geometry3D>& input(shared_ptr<Geometry3D> inGeom, const PathHints* path = nullptr) {
211 return input(inGeom->getChild(), path);
212 }
213
214 virtual ReceiverFor<PropertyT, Geometry2DCartesian>& input(Geometry2DCartesian& obj, const PathHints* path = nullptr) = 0;
215
216 ReceiverFor<PropertyT, Geometry2DCartesian>& input(shared_ptr<Geometry2DCartesian> obj, const PathHints* path = nullptr) {
217 return input(*obj, path);
218 }
219
220 virtual ReceiverFor<PropertyT, Geometry2DCylindrical>& input(Geometry2DCylindrical& obj, const PathHints* path = nullptr) = 0;
221
222 ReceiverFor<PropertyT, Geometry2DCylindrical>& input(shared_ptr<Geometry2DCylindrical> obj, const PathHints* path = nullptr) {
223 return input(*obj, path);
224 }
225
226 private:
227
228 void onSourceChange(/*Provider&, bool isDestr*/) {
229 //if (!isDestr)
230 out.fireChanged();
231 }
232
233 void connect(DataSourceT& in) {
234 in.changed.connect(boost::bind(&FilterBaseImpl::onSourceChange, this/*, _1, _2*/));
235 }
236
237 void disconnect(DataSourceT& in) {
238 in.changed.disconnect(boost::bind(&FilterBaseImpl::onSourceChange, this/*, _1, _2*/));
239 }
240
241 void disconnect(DataSourceTPtr& in) {
242 if (in) disconnect(*in);
243 }
244};
245
246 template <typename PropertyT, typename OutputSpaceType, typename... ExtraArgs>
247 struct FilterBaseImpl< PropertyT, MULTI_FIELD_PROPERTY, OutputSpaceType, VariadicTemplateTypesHolder<ExtraArgs...> >
248 : public FilterCommonBase
249{
250 // one outer source (input)
251 // vector of inner sources (inputs)
252 // one output (provider)
253
254 typedef typename PropertyAt<PropertyT, OutputSpaceType>::ValueType ValueType;
255 typedef DataSource<PropertyT, OutputSpaceType> DataSourceT;
256 typedef std::unique_ptr<DataSourceT> DataSourceTPtr;
257 typedef std::function<plask::optional<ValueType>(std::size_t)> DataSourceF;
258 typedef typename PropertyT::EnumType EnumType;
259
260 struct FilterLazyDataImpl: public LazyDataImpl<ValueType> {
261
262 DataSourceF outerSourceData;
263
264 std::vector<DataSourceF> innerSourcesData;
265
266 /*const FilterBaseImpl< PropertyT, MULTI_FIELD_PROPERTY, OutputSpaceType, VariadicTemplateTypesHolder<ExtraArgs...> >& filter;*/
267 shared_ptr<const MeshD<OutputSpaceType::DIM>> dst_mesh;
268 //std::tuple<ExtraArgs...> extra_args;
269 //InterpolationMethod method;
270
271 EnumType num;
272
273 FilterLazyDataImpl(
274 const FilterBaseImpl< PropertyT, MULTI_FIELD_PROPERTY, OutputSpaceType, VariadicTemplateTypesHolder<ExtraArgs...> >& filter,
275 EnumType num, const shared_ptr<const MeshD<OutputSpaceType::DIM>>& dst_mesh, ExtraArgs... extra_args, InterpolationMethod method
276 )
277 : innerSourcesData(filter.innerSources.size()), /*filter(filter),*/ dst_mesh(dst_mesh)/*, extra_args(extra_args...), method(method)*/, num(num)
278 {
279 for (std::size_t source_index = 0; source_index < filter.innerSources.size(); ++source_index)
280 innerSourcesData[source_index] = filter.innerSources[source_index]->operator()(num, dst_mesh, std::forward<ExtraArgs>(extra_args)..., method);
281 outerSourceData = filter.outerSource->operator()(num, dst_mesh, std::forward<ExtraArgs>(extra_args)..., method);
282 }
283
284 ValueType at(std::size_t point_index) const override {
285 for (std::size_t source_index = 0; source_index < innerSourcesData.size(); ++source_index) {
286 //if (!innerSourcesData[source_index])
287 // innerSourcesData[source_index] = filter.innerSources[source_index]->operator()(dst_mesh, extra_args, method);
288 plask::optional<ValueType> v = innerSourcesData[source_index](point_index);
289 if (v) return *v;
290 }
291 //if (!outerSourceData) outerSourceData = filter.outerSource->operator()(dst_mesh, extra_args, method);
292 return *outerSourceData(point_index);
293 }
294
295 std::size_t size() const override { return dst_mesh->size(); }
296
297 };
298
299 protected:
300 std::vector<DataSourceTPtr> innerSources;
301
302 DataSourceTPtr outerSource;
303
305 shared_ptr<OutputSpaceType> geometry;
306
307 template <typename SourceType>
308 auto setOuterRecv(std::unique_ptr<SourceType>&& outerSource) -> decltype(outerSource->in)& {
309 decltype(outerSource->in)& res = outerSource->in;
310 // setOuter(std::move(outerSource)); //can't call fireChange before connecting provider to returned receiver
311 disconnect(this->outerSource);
312 this->outerSource = std::move(outerSource);
313 connect(*this->outerSource);
314 return res;
315 }
316
317 template <typename SourceType>
318 auto appendInnerRecv(std::unique_ptr<SourceType>&& innerSource) -> decltype(innerSource->in)& {
319 decltype(innerSource->in)& res = innerSource->in;
320 this->innerSources.push_back(std::move(innerSource));
321 connect(*this->innerSources.back());
322 return res;
323 }
324
325 public:
326
328 typename ProviderFor<PropertyT, OutputSpaceType>::Delegate out;
329
334 FilterBaseImpl(shared_ptr<OutputSpaceType> geometry): FilterCommonBase("Filter"), geometry(geometry),
335 out([&] (EnumType num, const shared_ptr<const MeshD<OutputSpaceType::DIM>>& dst_mesh, ExtraArgs&&... extra_args, InterpolationMethod method) -> LazyData<ValueType> {
336 return this->get(num, dst_mesh, std::forward<ExtraArgs>(extra_args)..., method);
337 },
338 [&] () -> size_t {
339 size_t size = this->outerSource->size();
340 for (const auto& inner: this->innerSources) {
341 if (inner->size() != size)
342 throw DataError("all providers in {} filter must have equal number of values", PropertyT::NAME);
343 }
344 return size;
345 })
346 {
347 setDefault(PropertyAt<PropertyT, OutputSpaceType>::getDefaultValue());
348 }
349
350 std::string getClassName() const override { return "Filter"; }
351
356 shared_ptr<OutputSpaceType> getGeometry() const { return geometry; }
357
365 LazyData<ValueType> get(EnumType num, const shared_ptr<const MeshD<OutputSpaceType::DIM>>& dst_mesh, ExtraArgs... extra_args, InterpolationMethod method) const {
366 return new FilterLazyDataImpl(*this, num, dst_mesh, std::forward<ExtraArgs>(extra_args)..., method);
367 /*if (innerSources.empty()) //special case, for fast getting data from outer source
368 return (*outerSource)(dst_mesh, std::forward<ExtraArgs>(extra_args)..., method);
369 DataVector<ValueT> result(dst_mesh.size());
370 NoLogging nolog;
371 bool silent = outerSource && typeid(*outerSource) != typeid(ConstDataSource<PropertyT, OutputSpaceType>);
372 for (std::size_t i = 0; i < result.size(); ++i) {
373 // iterate over inner sources, if inner sources don't provide data, use outer source:
374 plask::optional<ValueT> innerVal;
375 for (const DataSourceTPtr& innerSource: innerSources) {
376 innerVal = innerSource->get(dst_mesh[i], std::forward<ExtraArgs>(extra_args)..., method);
377 if (innerVal) { silent = true; break; }
378 }
379 result[i] = *(innerVal ? innerVal : outerSource->get(dst_mesh[i], std::forward<ExtraArgs>(extra_args)..., method));
380 if (silent) nolog.silence();
381 }
382 return result;*/
383 }
384
389 void setOuter(DataSourceTPtr&& outerSource) {
390 disconnect(this->outerSource);
391 this->outerSource = std::move(outerSource);
392 connect(*this->outerSource);
393 out.fireChanged();
394 }
395
400 void setDefault(const ValueType& value) {
401 disconnect(this->outerSource);
402 this->outerSource.reset(new ConstDataSource<PropertyT, OutputSpaceType>(value));
403 connect(*this->outerSource);
404 out.fireChanged();
405 }
406
411 void appendInner(DataSourceTPtr&& innerSource) {
412 this->innerSources.push_back(std::move(innerSource));
413 connect(*this->innerSources.back());
414 out.fireChanged();
415 }
416
423 virtual ReceiverFor<PropertyT, Geometry3D>& input(GeometryObjectD<3>& obj, const PathHints* path = nullptr) = 0;
424
425 ReceiverFor<PropertyT, Geometry3D>& input(shared_ptr<GeometryObjectD<3>> obj, const PathHints* path = nullptr) {
426 return input(*obj, path);
427 }
428
429 ReceiverFor<PropertyT, Geometry3D>& input(Geometry3D& inGeom, const PathHints* path = nullptr) {
430 return input(inGeom.getChild(), path);
431 }
432
433 ReceiverFor<PropertyT, Geometry3D>& input(shared_ptr<Geometry3D> inGeom, const PathHints* path = nullptr) {
434 return input(inGeom->getChild(), path);
435 }
436
437 virtual ReceiverFor<PropertyT, Geometry2DCartesian>& input(Geometry2DCartesian& obj, const PathHints* path = nullptr) = 0;
438
439 ReceiverFor<PropertyT, Geometry2DCartesian>& input(shared_ptr<Geometry2DCartesian> obj, const PathHints* path = nullptr) {
440 return input(*obj, path);
441 }
442
443 virtual ReceiverFor<PropertyT, Geometry2DCylindrical>& input(Geometry2DCylindrical& obj, const PathHints* path = nullptr) = 0;
444
445 ReceiverFor<PropertyT, Geometry2DCylindrical>& input(shared_ptr<Geometry2DCylindrical> obj, const PathHints* path = nullptr) {
446 return input(*obj, path);
447 }
448
449 private:
450
451 void onSourceChange(/*Provider&, bool isDestr*/) {
452 //if (!isDestr)
453 out.fireChanged();
454 }
455
456 void connect(DataSourceT& in) {
457 in.changed.connect(boost::bind(&FilterBaseImpl::onSourceChange, this/*, _1, _2*/));
458 }
459
460 void disconnect(DataSourceT& in) {
461 in.changed.disconnect(boost::bind(&FilterBaseImpl::onSourceChange, this/*, _1, _2*/));
462 }
463
464 void disconnect(DataSourceTPtr& in) {
465 if (in) disconnect(*in);
466 }
467};
468
474 template <typename PropertyT, typename OutputSpaceType>
475 using FilterBase = FilterBaseImpl<PropertyT, PropertyT::propertyType, OutputSpaceType, typename PropertyT::ExtraParams>;
476
477 template <typename PropertyT, typename OutputSpaceType>
478 struct FilterImpl {};
479
486 template <typename PropertyT>
487 struct FilterImpl<PropertyT, Geometry3D>: public FilterBase<PropertyT, Geometry3D> {
488
489 FilterImpl(shared_ptr<Geometry3D> geometry): FilterBase<PropertyT, Geometry3D>(geometry) {}
490
491 using FilterBase<PropertyT, Geometry3D>::setOuter;
492
493 using FilterBase<PropertyT, Geometry3D>::appendInner;
494
495 ReceiverFor<PropertyT, Geometry3D>& input(GeometryObjectD<3>& obj, const PathHints* path = nullptr) override {
496 if (obj.hasInSubtree(this->geometry->getChild(), path))
497 return setOuter(obj, path);
498 else
499 return appendInner(obj, path);
500 }
501
502 ReceiverFor<PropertyT, Geometry2DCartesian>& input(Geometry2DCartesian& innerObj, const PathHints* path = nullptr) override {
503 return appendInner(innerObj, path);
504 }
505
506 ReceiverFor<PropertyT, Geometry2DCylindrical>& input(Geometry2DCylindrical& innerObj, const PathHints* path = nullptr) override {
507 return appendInner(innerObj, path);
508 }
509
510 ReceiverFor<PropertyT, Geometry3D>& setOuter(GeometryObjectD<3>& outerObj, const PathHints* path = nullptr) {
511 std::unique_ptr< TranslatedOuterDataSource<PropertyT, Geometry3D> > source(new TranslatedOuterDataSource<PropertyT, Geometry3D>());
512 source->connect(outerObj, *this->geometry->getChild(), path);
513 return this->setOuterRecv(std::move(source));
514 }
515
516 ReceiverFor<PropertyT, Geometry3D>& setOuter(shared_ptr<GeometryObjectD<3>> outerObj, const PathHints* path = nullptr) {
517 return setOuter(*outerObj, path);
518 }
519
520 ReceiverFor<PropertyT, Geometry3D>& setOuter(Geometry3D& outerGeom, const PathHints* path = nullptr) {
521 return setOuter(outerGeom.getChild(), path);
522 }
523
524 ReceiverFor<PropertyT, Geometry3D>& setOuter(shared_ptr<Geometry3D> outerGeom, const PathHints* path = nullptr) {
525 return setOuter(outerGeom->getChild(), path);
526 }
527
528 ReceiverFor<PropertyT, Geometry3D>& appendInner(GeometryObjectD<3>& innerObj, const PathHints* path = nullptr) {
529 std::unique_ptr< TranslatedInnerDataSource<PropertyT, Geometry3D> > source(new TranslatedInnerDataSource<PropertyT, Geometry3D>());
530 source->connect(innerObj, *this->geometry, path);
531 return this->appendInnerRecv(std::move(source));
532 }
533
534 ReceiverFor<PropertyT, Geometry3D>& appendInner(shared_ptr<GeometryObjectD<3>> innerObj, const PathHints* path = nullptr) {
535 return appendInner(*innerObj, path);
536 }
537
538 ReceiverFor<PropertyT, Geometry2DCartesian>& appendInner2D(Extrusion& innerObj, const PathHints* path = nullptr) {
539 std::unique_ptr< DataFrom2Dto3DSource<PropertyT> > source(new DataFrom2Dto3DSource<PropertyT>());
540 source->connect(innerObj, *this->geometry, path);
541 return this->appendInnerRecv(std::move(source));
542 }
543
544 ReceiverFor<PropertyT, Geometry2DCartesian>& appendInner2D(shared_ptr<Extrusion> innerObj, const PathHints* path = nullptr) {
545 return appendInner2D(*innerObj, path);
546 }
547
548 ReceiverFor<PropertyT, Geometry2DCartesian>& appendInner(Geometry2DCartesian& innerObj, const PathHints* path = nullptr) {
549 return appendInner2D(innerObj.getExtrusion(), path);
550 }
551
552 ReceiverFor<PropertyT, Geometry2DCartesian>& appendInner(shared_ptr<Geometry2DCartesian> innerObj, const PathHints* path = nullptr) {
553 return appendInner2D(innerObj->getExtrusion(), path);
554 }
555
556 ReceiverFor<PropertyT, Geometry2DCylindrical>& appendInner2D(Revolution& innerObj, const PathHints* path = nullptr) {
557 std::unique_ptr< DataFromCyl2Dto3DSource<PropertyT> > source(new DataFromCyl2Dto3DSource<PropertyT>());
558 source->connect(innerObj, *this->geometry, path);
559 return this->appendInnerRecv(std::move(source));
560 }
561
562 ReceiverFor<PropertyT, Geometry2DCylindrical>& appendInner2D(shared_ptr<Revolution> innerObj, const PathHints* path = nullptr) {
563 return appendInner2D(*innerObj, path);
564 }
565
566 ReceiverFor<PropertyT, Geometry2DCylindrical>& appendInner(Geometry2DCylindrical& innerObj, const PathHints* path = nullptr) {
567 return appendInner2D(innerObj.getRevolution(), path);
568 }
569
570 ReceiverFor<PropertyT, Geometry2DCylindrical>& appendInner(shared_ptr<Geometry2DCylindrical> innerObj, const PathHints* path = nullptr) {
571 return appendInner2D(innerObj->getRevolution(), path);
572 }
573};
574
581 template <typename PropertyT>
582 struct FilterImpl<PropertyT, Geometry2DCartesian>: public FilterBase<PropertyT, Geometry2DCartesian> {
583
584 FilterImpl(shared_ptr<Geometry2DCartesian> geometry): FilterBase<PropertyT, Geometry2DCartesian>(geometry) {}
585
586 using FilterBase<PropertyT, Geometry2DCartesian>::setOuter;
587
588 using FilterBase<PropertyT, Geometry2DCartesian>::appendInner;
589
590 ReceiverFor<PropertyT, Geometry3D>& input(GeometryObjectD<3>& outerObj, const PathHints* path = nullptr) override {
591 return setOuter(outerObj, path);
592 }
593
594 ReceiverFor<PropertyT, Geometry2DCartesian>& input(Geometry2DCartesian& obj, const PathHints* path = nullptr) override {
595 return input(obj.getChild(), path);
596 }
597
598 ReceiverFor<PropertyT, Geometry2DCylindrical>& input(Geometry2DCylindrical&, const PathHints* = nullptr) override {
599 throw Exception("bad use of filter over Cartesian space. Cartesian geometry 2D can't contain cylindrical geometry and can't be included in cylindrical geometry.");
600 }
601
602 ReceiverFor<PropertyT, Geometry2DCartesian>& input(GeometryObjectD<2>& obj, const PathHints* path = nullptr) {
603 if (obj.hasInSubtree(this->geometry->getChild(), path))
604 return setOuter(obj, path);
605 else
606 return appendInner(obj, path);
607 }
608
609 ReceiverFor<PropertyT, Geometry2DCartesian>& input(shared_ptr<GeometryObjectD<2>> obj, const PathHints* path = nullptr) {
610 return input(*obj, path);
611 }
612
613 ReceiverFor<PropertyT, Geometry3D>& setOuter(GeometryObjectD<3>& outerObj, const PathHints* path = nullptr, std::size_t pointsCount = 10) {
614 std::unique_ptr< DataFrom3Dto2DSource<PropertyT> > source(new DataFrom3Dto2DSource<PropertyT>(pointsCount));
615 source->connect(outerObj, *this->geometry->getExtrusion(), path);
616 return this->setOuterRecv(std::move(source));
617 }
618
619 ReceiverFor<PropertyT, Geometry3D>& setOuter(shared_ptr<GeometryObjectD<3>> outerObj, const PathHints* path = nullptr, std::size_t pointsCount = 10) {
620 return setOuter(*outerObj, path, pointsCount);
621 }
622
623 ReceiverFor<PropertyT, Geometry2DCartesian>& setOuter(GeometryObjectD<2>& outerObj, const PathHints* path = nullptr) {
624 std::unique_ptr< TranslatedOuterDataSource<PropertyT, Geometry2DCartesian> > source(new TranslatedOuterDataSource<PropertyT, Geometry2DCartesian>());
625 source->connect(outerObj, *this->geometry->getChild(), path);
626 return this->setOuterRecv(std::move(source));
627 }
628
629 ReceiverFor<PropertyT, Geometry2DCartesian>& setOuter(shared_ptr<GeometryObjectD<2>> outerObj, const PathHints* path = nullptr) {
630 return setOuter(*outerObj, path);
631 }
632
633 ReceiverFor<PropertyT, Geometry2DCartesian>& setOuter(Geometry2DCartesian& outerGeom, const PathHints* path = nullptr) {
634 return setOuter(outerGeom.getChild(), path);
635 }
636
637 ReceiverFor<PropertyT, Geometry2DCartesian>& setOuter(shared_ptr<Geometry2DCartesian> outerGeom, const PathHints* path = nullptr) {
638 return setOuter(outerGeom->getChild(), path);
639 }
640
641 ReceiverFor<PropertyT, Geometry2DCartesian>& appendInner(GeometryObjectD<2>& innerObj, const PathHints* path = nullptr) {
642 std::unique_ptr< TranslatedInnerDataSource<PropertyT, Geometry2DCartesian> > source(new TranslatedInnerDataSource<PropertyT, Geometry2DCartesian>());
643 source->connect(innerObj, *this->geometry, path);
644 return this->appendInnerRecv(std::move(source));
645 }
646
647 ReceiverFor<PropertyT, Geometry2DCartesian>& appendInner(shared_ptr<GeometryObjectD<2>> innerObj, const PathHints* path = nullptr) {
648 return this->appendInner(*innerObj, path);
649 }
650
651 ReceiverFor<PropertyT, Geometry2DCartesian>& appendInner(Geometry2DCartesian& innerGeom, const PathHints* path = nullptr) {
652 return appendInner(innerGeom.getChild(), path);
653 }
654
655 ReceiverFor<PropertyT, Geometry2DCartesian>& appendInner(shared_ptr<Geometry2DCartesian> innerGeom, const PathHints* path = nullptr) {
656 return appendInner(innerGeom->getChild(), path);
657 }
658};
659
666 template <typename PropertyT>
667 struct FilterImpl<PropertyT, Geometry2DCylindrical>: public FilterBase<PropertyT, Geometry2DCylindrical> {
668
669 FilterImpl(shared_ptr<Geometry2DCylindrical> geometry): FilterBase<PropertyT, Geometry2DCylindrical>(geometry) {}
670
671 using FilterBase<PropertyT, Geometry2DCylindrical>::setOuter;
672
673 using FilterBase<PropertyT, Geometry2DCylindrical>::appendInner;
674
675 ReceiverFor<PropertyT, Geometry3D>& input(GeometryObjectD<3>& outerObj, const PathHints* path = nullptr) override {
676 return setOuter(outerObj, path);
677 }
678
679 ReceiverFor<PropertyT, Geometry2DCylindrical>& input(Geometry2DCylindrical& obj, const PathHints* path = nullptr) override {
680 return input(obj.getChild(), path);
681 }
682
683 ReceiverFor<PropertyT, Geometry2DCartesian>& input(Geometry2DCartesian&, const PathHints* = nullptr) override {
684 throw Exception("bad use of filter over cylindrical space. Cylindrical geometry can't contain Cartesian geometry 2D and can't be included in Cartesian geometry 2D.");
685 }
686
687 ReceiverFor<PropertyT, Geometry2DCylindrical>& input(GeometryObjectD<2>& obj, const PathHints* path = nullptr) {
688 if (obj.hasInSubtree(this->geometry->getChild(), path))
689 return setOuter(obj, path);
690 else
691 return appendInner(obj, path);
692 }
693
694 ReceiverFor<PropertyT, Geometry2DCylindrical>& input(shared_ptr<GeometryObjectD<2>> obj, const PathHints* path = nullptr) {
695 return input(*obj, path);
696 }
697
698 ReceiverFor<PropertyT, Geometry3D>& setOuter(GeometryObjectD<3>& outerObj, const PathHints* path = nullptr, std::size_t pointsCount = 10) {
699 std::unique_ptr< DataFrom3DtoCyl2DSource<PropertyT> > source(new DataFrom3DtoCyl2DSource<PropertyT>(pointsCount));
700 source->connect(outerObj, *this->geometry->getRevolution(), path);
701 return this->setOuterRecv(std::move(source));
702 }
703
704 ReceiverFor<PropertyT, Geometry3D>& setOuter(shared_ptr<GeometryObjectD<3>> outerObj, const PathHints* path = nullptr, std::size_t pointsCount = 10) {
705 return setOuter(*outerObj, path, pointsCount);
706 }
707
708 ReceiverFor<PropertyT, Geometry2DCylindrical>& setOuter(GeometryObjectD<2>& outerObj, const PathHints* path = nullptr) {
709 std::unique_ptr< TranslatedOuterDataSource<PropertyT, Geometry2DCylindrical> > source(new TranslatedOuterDataSource<PropertyT, Geometry2DCylindrical>());
710 if (source->inTranslation.rad_r() != 0.0)
711 throw Exception("bad use of a filter over cylindrical space. Connection of the data sources connected with the cylindrical geometries translated in rad_r direction are not allowed.");
712 source->connect(outerObj, *this->geometry->getChild(), path);
713 return this->setOuterRecv(std::move(source));
714 }
715
716 ReceiverFor<PropertyT, Geometry2DCylindrical>& setOuter(shared_ptr<GeometryObjectD<2>> outerObj, const PathHints* path = nullptr) {
717 return setOuter(*outerObj, path);
718 }
719
720 ReceiverFor<PropertyT, Geometry2DCylindrical>& setOuter(Geometry2DCylindrical& outerGeom, const PathHints* path = nullptr) {
721 return setOuter(outerGeom.getChild(), path);
722 }
723
724 ReceiverFor<PropertyT, Geometry2DCylindrical>& setOuter(shared_ptr<Geometry2DCylindrical> outerGeom, const PathHints* path = nullptr) {
725 return setOuter(outerGeom->getChild(), path);
726 }
727
728 ReceiverFor<PropertyT, Geometry2DCylindrical>& appendInner(GeometryObjectD<2>& innerObj, const PathHints* path = nullptr) {
729 std::unique_ptr< TranslatedInnerDataSource<PropertyT, Geometry2DCylindrical> > source(new TranslatedInnerDataSource<PropertyT, Geometry2DCylindrical>());
730 for (const auto& r: source->regions) {
731 if (r.inTranslation.rad_r() != 0.0)
732 throw Exception("bad use of a filter over cylindrical space. Connection of the data sources connected with the cylindrical geometries translated in rad_r direction are not allowed.");
733 }
734 source->connect(innerObj, *this->geometry, path);
735 return this->appendInnerRecv(std::move(source));
736 }
737
738 ReceiverFor<PropertyT, Geometry2DCylindrical>& appendInner(shared_ptr<GeometryObjectD<2>> innerObj, const PathHints* path = nullptr) {
739 return this->appendInner(*innerObj, path);
740 }
741
742 ReceiverFor<PropertyT, Geometry2DCylindrical>& appendInner(Geometry2DCylindrical& innerGeom, const PathHints* path = nullptr) {
743 return appendInner(innerGeom.getChild(), path);
744 }
745
746 ReceiverFor<PropertyT, Geometry2DCylindrical>& appendInner(shared_ptr<Geometry2DCylindrical> innerGeom, const PathHints* path = nullptr) {
747 return appendInner(innerGeom->getChild(), path);
748 }
749};
750
762 template <typename PropertyT, typename OutputSpaceType>
763 using Filter = FilterImpl<PropertyT, OutputSpaceType>;
764
765} // namespace plask
766
767#endif // PLASK__FILTER_H