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