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