DLG4::VolumeBuilders
A fluent interface for Geant4 geometry definition.
Loading...
Searching...
No Matches
StructureBuilderBase.hpp
Go to the documentation of this file.
1#ifndef DLG4_STRUCTUREBUILDER_HPP
2#define DLG4_STRUCTUREBUILDER_HPP
11#include "Linkable.hh"
15#include "VolumeBuilderCore.hh"
16#include <memory>
17
18
20#define BASE StructureBuilderBase<U>
21#define DERIVED typename BASE::DerivedPtr
22
23
24 // template <typename U>
25 // template <typename T>
26 // BASE::StructureBuilderBase(i_shared_ptr<T> other,
27 // std::enable_if_t<std::is_base_of_v<VolumeBuilder<T>, T>, int> =
28 // 0) : StructureBuilderBase(other, SET_LINK) {
29 // }
30
31 template <typename U>
32 //Note: placement_configs_.children seem shallow copied here, handled in Fork
33 BASE::StructureBuilderBase(const StructureBuilderBase &other) :
34 builder_configs_(other.builder_configs_),
35 boolean_configs_(other.boolean_configs_),
36 lv_configs_(other.lv_configs_),
37 placement_configs_(
38 other.placement_configs_) {
39 // avoid masked bugs from stale view:
40 builder_configs_->builder_view = nullptr;
41 builder_configs_->istructure_ptr = nullptr;
42 }
43
44
52 template <typename U>
53 template <typename T, typename std::enable_if_t<std::is_base_of_v<IStructureBuilder, T>, int>>
54 BASE::StructureBuilderBase(const SharedPtr<T> &other, SET_LINK_TYPE)
55 : builder_configs_(other->builder_configs_,SET_LINK),
56 boolean_configs_(other->boolean_configs_,SET_LINK),
57 lv_configs_(other->lv_configs_, SET_LINK),
58 placement_configs_(other->placement_configs_,SET_LINK),
59 final_solid_ptr_(other->final_solid_ptr_,SET_LINK),
60 solid_ptr_(other->solid_ptr_,SET_LINK),
61 logicvol_ptr_(other->logicvol_ptr_,SET_LINK),
62 placement_(other->placement_,SET_LINK) {
63 builder_configs_->istructure_ptr = IStructurePtr(other);
64 // provide a builder view on builders:
65 if (other->placement_configs_->is_builder) {
66 VolumeBuilder builder_view = other->ToVolumeBuilder();
67 //We're storing the view in the builder by writing to the builder through that same view!
68 builder_view->StoreBuilderView(builder_view);
69 }
70 }
71
72 template <typename U>
73 BASE::~StructureBuilderBase() {
74 // optionally release resources (default)
75 // ReSharper disable once CppIfCanBeReplacedByConstexprIf
76 if (!has_ownership_ && placement_configs_->is_builder) {
77 // This is SO wrong. This should be done at CREATION of members,
78 // not deletion of class.
79 // But it works for now and we're super restrictive on creation.
80 placement_.make_persistent();
81 }
82 }
83
84 template <typename U>
85 DERIVED BASE::MakePlacement() {
86 if (was_placed_) {
87 throw std::runtime_error("Cannot make placement - structure was already placed");
88 }
89 was_placed_ = true;
90 if (!placement_configs_->is_builder) {
91 // assembly
92 for (auto &child : placement_configs_->children) {
93 auto name = this->builder_configs_->builder_view->GetPlacementBaseName();
94 child->placement_configs_->parent_name = name;
95 //recurse until concrete, below:
96 child->MakePlacement();
97 }
98 } else {
99 // concrete builder. Break recursion and call builder placement.
100 this->builder_configs_->builder_view->MakePlacement();
101 }
102 return this->shared_from_this();
103 }
104
105 template <typename U>
106 DERIVED BASE::
107 PlaceAndFork() {
108 this->MakePlacement();
109 auto clone = this->ForkForPlacement(); // default/preset options
110 return clone;
111 }
112
113 template <typename U>
114 DERIVED BASE::
115 SetName(const G4String &name) {
116 this->builder_configs_->builder_view->SetName(name);
117 return this->shared_from_this();
118 }
119
120 template <typename U>
121 DERIVED BASE::SetMaterial(
122 G4Material *material) {
123 if (!placement_configs_->is_builder) {
124 // assembly
125 for (auto &child : placement_configs_->children) {
126 child->SetMaterial(material);
127 }
128 } else {
129 // concrete builder... operate with concrete view:
130 this->builder_configs_->builder_view->SetMaterial(material);
131 }
132 return this->shared_from_this();
133 }
134
135 template <typename U>
136 DERIVED BASE::SetColor(double r, double g,
137 double b, double alpha) {
138 if (!placement_configs_->is_builder) {
139 // assembly
140 for (auto &child : placement_configs_->children) {
141 child->SetColor(r, g, b, alpha);
142 }
143 } else {
144 // concrete builder... operate with concrete view:
145 this->builder_configs_->builder_view->SetColor(r, g, b, alpha);
146 }
147 return this->shared_from_this();
148 }
149
150 template <typename U>
151 DERIVED BASE::SetColor(
152 const G4Colour &color) {
153 if (!placement_configs_->is_builder) {
154 // assembly
155 for (auto &child : placement_configs_->children) {
156 child->SetColor(color);
157 }
158 } else {
159 // concrete builder... operate with concrete view:
160 this->builder_configs_->builder_view->SetColor(color);
161 }
162 return this->shared_from_this();
163 }
164
165 template <typename U>
166 DERIVED BASE::SetAlpha(G4double alpha) {
167 if (!placement_configs_->is_builder) {
168 // assembly
169 for (auto &child : placement_configs_->children) {
170 child->SetAlpha(alpha);
171 }
172 } else {
173 // concrete builder... operate with concrete view:
174 this->builder_configs_->builder_view->SetAlpha(alpha);
175 }
176 return this->shared_from_this();
177 }
178
179 template <typename U>
180 DERIVED BASE::ForceSolid(bool x) {
181 if (!placement_configs_->is_builder) {
182 // assembly
183 for (auto &child : placement_configs_->children) {
184 child->ForceSolid(x);
185 }
186 } else {
187 // concrete builder... operate with concrete view:
188 this->builder_configs_->builder_view->ForceSolid(x);
189 }
190 return this->shared_from_this();
191 }
192
193 template <typename U>
194 DERIVED BASE::
195 SetVisibility(bool is_visible) {
196 if (!placement_configs_->is_builder) {
197 // assembly
198 for (auto &child : placement_configs_->children) {
199 child->SetVisibility(is_visible);
200 }
201 } else {
202 // concrete builder... operate with concrete view:
203 this->builder_configs_->builder_view->SetVisibility(is_visible);
204 }
205 return this->shared_from_this();
206 }
207
208 template <typename U>
209 DERIVED BASE::SetPhysRotation(
210 const G4RotationMatrix &rot) {
211 // Transforms are kept hierarchical and essentially are combined when placed:
212 // This way order of setting different hierarchy levels doesn't matter.
213 // This removes some creative uses, but also a lot of confusion.
214 this->builder_configs_->builder_view->SetPhysRotation(rot);
215 return this->shared_from_this();
216 }
217
218 template <typename U>
219 DERIVED BASE::StackPhysRotation(
220 const G4RotationMatrix &stacked_rot) {
221 this->builder_configs_->builder_view->StackPhysRotation(stacked_rot);
222 auto retval = this->shared_from_this();
223 return retval;
224 }
225
226 template <typename U>
227 DERIVED BASE::SetPhysOffset(
228 const Unit3Vec &offset) {
229 this->builder_configs_->builder_view->SetPhysOffset(offset);
230 return this->shared_from_this();
231 }
232
233 template <typename U>
234 DERIVED BASE::StackPhysOffset(
235 const Unit3Vec &offset) {
236 this->builder_configs_->builder_view->StackPhysOffset(offset);
237 return this->shared_from_this();
238 }
239
240 template <typename U>
241 DERIVED BASE::SetPhysTransform(
242 const UnitlessG4Transform3D &new_transform) {
243 this->builder_configs_->builder_view->SetPhysTransform(new_transform);
244 return this->shared_from_this();
245 }
246
247 template <typename U>
248 DERIVED BASE::StackPhysTransform(
249 const UnitlessG4Transform3D &stacked_transform) {
250 this->builder_configs_->builder_view->StackPhysTransform(stacked_transform);
251 return this->shared_from_this();
252 }
253
254 template <typename U>
255 DERIVED BASE::OverridePlacementName(
256 const G4String &pName) {
257 this->builder_configs_->builder_view->OverridePlacementName(pName);
258 return this->shared_from_this();
259 }
260
261 template <typename U>
262 DERIVED BASE::SetCopyNo(G4int pCopyNo) {
263 //TODO FIX THIS
264 std::cout << "fixme" << std::endl;
265 return this->shared_from_this();
266 }
267
268 template <typename U>
269 DERIVED BASE::SetSurfaceCheck(
270 G4bool pSurfChk) {
271 if (!placement_configs_->is_builder) {
272 // assembly
273 for (auto &child : placement_configs_->children) {
274 child->SetSurfaceCheck(pSurfChk);
275 }
276 } else {
277 // concrete builder... operate with concrete view:
278 this->builder_configs_->builder_view->SetSurfaceCheck(pSurfChk);
279 }
280 return this->shared_from_this();
281 }
282
283 template <typename U>
284 DERIVED BASE::SetMother(
285 const VolumeBuilder &mother) {
286 if (!placement_configs_->is_builder) {
287 // assembly
288 for (auto &child : placement_configs_->children) {
289 child->SetMother(mother);
290 }
291 } else {
292 // concrete builder... operate with concrete view:
293 this->builder_configs_->builder_view->SetMother(mother);
294 }
295 return this->shared_from_this();
296 }
297
298 template <typename U>
299 DERIVED BASE::SetAutoPlacementNaming(
300 bool set) {
301 //FIXME check overriding of explicit_name_set
302 // naming is hierarchical. So just set ours.
303 this->builder_configs_->builder_view->SetAutoPlacementNaming(set);
304 return this->shared_from_this();
305 }
306
307 template <typename U>
308 DERIVED BASE::
309 SetAutoCopyNo(bool set) {
310 // Copy No is not hierarchical, so enable individual auto set.
311 if (!placement_configs_->is_builder) {
312 // assembly
313 for (auto &child : placement_configs_->children) {
314 child->SetAutoCopyNo(set);
315 }
316 } else {
317 // concrete builder... operate with concrete view:
318 this->builder_configs_->builder_view->SetAutoCopyNo(set);
319 }
320 return this->shared_from_this();
321 }
322
323
324 template <typename U>
325 DERIVED BASE::ForkForPlacement(
326 // TODO review what do with copy_no
327 std::optional<int> copy_no, const G4String &name_override) {
328 // Polymorphic clone through builder view method.
329 auto c1 = this->builder_configs_->builder_view->ForkForPlacement();
330 auto c2 = c1->builder_configs_->istructure_ptr;
331 auto copy = i_dynamic_pointer_cast<U>(c2);
332 if (!placement_configs_->is_builder) {
333 // assembly
334 copy->placement_configs_->children.clear();
335 for (auto &child : placement_configs_->children) {
336 auto builderview_clone = child->builder_configs_->builder_view->ForkForPlacement(
337 std::nullopt, "", true);
338 auto clone_istructure_view = builderview_clone->builder_configs_->istructure_ptr->
339 ToStructureView();
340 copy->placement_configs_->children.emplace_back(clone_istructure_view);
341 }
342 }
343 return DERIVED(copy);
344 }
345
346 template <typename U>
347 DERIVED BASE::ForkForLogicalVolume(const G4String &new_name) {
348 // Polymorphic clone through builder view method.
349 auto c1 = this->builder_configs_->builder_view->ForkForLogicalVolume(new_name);
350 auto c2 = c1->builder_configs_->istructure_ptr;
351 auto copy = i_dynamic_pointer_cast<U>(c2);
352 if (!placement_configs_->is_builder) {
353 // assembly
354 copy->placement_configs_->children.clear();
355 for (auto &child : placement_configs_->children) {
356 auto builderview_clone = child->builder_configs_->builder_view->ForkForLogicalVolume(
357 new_name);
358 auto clone_istructure_view = builderview_clone->builder_configs_->istructure_ptr->
359 ToStructureView();
360 copy->placement_configs_->children.emplace_back(clone_istructure_view);
361 }
362 }
363 return DERIVED(copy);
364 }
365
366 template <typename U>
367 DERIVED BASE::CopyPlacementConfigsFrom(
368 const VolumeBuilder &other) {
369 // we just copy THIS structure's configs.. no recursion.
370 this->builder_configs_->builder_view->CopyPlacementConfigsFrom(other);
371 return this->shared_from_this();
372 }
373
374 template <typename U>
375 DERIVED BASE::SetDefaultUnit(
376 G4double unit) {
377 // Transforms are all stored INTERNALLY with units... so we can safely
378 // set the interface unit on each hierachy.
379 this->builder_configs_->builder_view->SetDefaultUnit(unit);
380 return this->shared_from_this();
381 }
382
383
384 template <typename U>
385 G4double BASE::GetEffectiveDefaultUnit() const {
386 return this->builder_configs_->builder_view->GetEffectiveDefaultUnit();
387 }
388
389 template <typename U>
390 G4String BASE::GetBuilderName() const {
391 return this->builder_configs_->builder_view->GetBuilderName();
392 }
393
394 template <typename U>
395 BASE::StructureBuilderBase() {
396 lv_configs_->vis_att = G4VisAttributes(true);
397 placement_configs_->is_builder = false;
398 }
399
400
401 template <typename U>
402 void BASE::ValidateForPVBuild(std::string const &site) {
403 builder_configs_->builder_view->ValidateForPVBuild(site);
404 }
405
406 template <typename U>
407 void BASE::ValidatePlacementNotBuilt(
408 const std::string &operation) const {
409 builder_configs_->builder_view->ValidatePlacementNotBuilt(operation);
410 }
411
412 template <typename U>
413 StructureBuilder BASE::ToStructureView() const {
414 return builder_configs_->istructure_ptr->ToStructureView();
415 }
416
417 template <typename U>
418 VolumeBuilder BASE::ToVolumeBuilder() const {
419 // calls the BuilderView copy/convert ctor::
420 // presently the i_shared converter only works with l-value.
421 std::shared_ptr<U> builder_std_ptr =
422 std::const_pointer_cast<U>(this->shared_from_this());
423 auto x = DerivedPtr(builder_std_ptr);
424 return VolumeBuilder(x);
425 }
426
427
428 template <typename U>
429 SharedPtr<IStructureBuilder> BASE::clone_impl() const {
430 // consider moving this to Assembly derived class since nothing else uses the base implementation.
431 const U &derived_ref = static_cast<const U &>(*this); // downcast
432 auto retval = new U(derived_ref); // copy
433 auto shared_ptr = i_shared_ptr<U>(retval);
434 VolumeBuilder builder_view = shared_ptr->ToVolumeBuilder();
435 builder_view->SetName(this->GetBuilderName());
436 //We're storing the view in the builder by writing to the builder through that same view!
437 builder_view->StoreBuilderView(builder_view);
438
439 return shared_mutable_this(retval); // wrap and return.
440 }
441
442 template <typename U>
443 G4String BASE::GetLogicVolName() const {
444 return this->builder_configs_->builder_view->GetLogicVolName();
445 }
446
447#undef BASE
448#undef DERIVED
449}
450
451//reveiw explict name parameter, copy algorithm, name propogation...
452#endif
#define SET_LINK
Definition Linkable.hh:63
#define SET_LINK_TYPE
Definition Linkable.hh:62
#define DERIVED
A wrapper for std::shared_ptr that allows and facilitates many implicit(i) type conversions.
std::shared_ptr< T > shared_mutable_this(const std::enable_shared_from_this< T > *obj)
SharedPtr< VolumeBuilderCore > VolumeBuilder
SharedPtr< IStructureBuilder > IStructurePtr
True polymorphic class base view for all structures Mostly for internal use.
SharedPtr< StructureBuilderCore > StructureBuilder