DLG4::VolumeBuilders
A fluent interface for Geant4 geometry definition.
Loading...
Searching...
No Matches
BoxBuilder.cc
Go to the documentation of this file.
1/*
2 * VolumeMaker.cc
3 *
4 * Created on: Jun 29, 2024
5 * Author: D. S. Leonard
6 */
7// Presently includes src for VolumeMaker and GeantMultiPlane classes
8// See header for documentation.
9
10#include "BoxBuilder.hh"
11#include <string>
12#include <VolumeBuilderTypes.hh>
13#include <G4Polycone.hh>
14#include <G4Polyhedra.hh>
15//#include "disableable_shared_from_this.hh"
16#include <G4Box.hh>
17
18#include "i_shared_ptr.hh"
19#include "StructureBuilder.hpp"
21
22class G4String;
23using namespace DLG4::Utilities;
24
25//Geant Box constructing methods //////////////////////////////////////////////////
26namespace DLG4::VolumeBuilders {
27 //Factories
28 // Factory methods for creating a BoxBuilder. These have been rewritten to
29 // delegate directly to the BoxBuilder's member methods.
30 // Yes, AI cranked out the duplication and delegation here after telling it exactly how to!
31
32 BoxBuilderPtr CreateBoxBuilder(const G4String &name) {
33 auto object = BoxBuilderPtr(new BoxBuilder(name));
34 return object;
35 }
36
37 BoxBuilderPtr CreateBoxBuilder(const G4String &name, const G4double unit) {
38 auto object = BoxBuilderPtr(new BoxBuilder(name));
39 object->SetDefaultUnit(unit);
40 return object;
41 }
42
43
44 BoxBuilderPtr CreateDeltasBoxBuilder(const G4double unit, const G4String &name,
45 const G4double edge_x,
46 const G4double x_delta,
47 const G4double edge_y, const G4double y_delta, const G4double edge_z,
48 const G4double z_delta) {
49 auto object = BoxBuilderPtr(new BoxBuilder(name));
50 object->SetXEdgeDelta(unit, edge_x, x_delta)
51 ->SetYEdgeDelta(unit, edge_y, y_delta)
52 ->SetZEdgeDelta(unit, edge_z, z_delta);
53 return object;
54 }
55
56 BoxBuilderPtr CreateDeltasBoxBuilder(const G4String &name, const G4double edge_x,
57 const G4double x_delta,
58 const G4double edge_y,
59 const G4double y_delta, const G4double edge_z, const G4double z_delta) {
60 auto object = BoxBuilderPtr(new BoxBuilder(name));
61 object->SetXEdgeDelta(edge_x, x_delta)
62 ->SetYEdgeDelta(edge_y, y_delta)
63 ->SetZEdgeDelta(edge_z, z_delta);
64 return object;
65 }
66
67 BoxBuilderPtr CreateZDeltaBoxBuilder(const G4double unit, const G4String &name,
68 const G4double x_full_size,
69 const G4double y_full_size,
70 const G4double edge_z, const G4double z_delta) {
71 if (x_full_size <= 0 || y_full_size <= 0) {
72 throw std::invalid_argument("Error in CreateZDeltaBoxBuilder(): for volume " + name
73 + ": Sizes provided without end offsets must be positive.\n");
74 }
75 auto object = BoxBuilderPtr(new BoxBuilder(name));
76 object->SetXSize(unit, x_full_size)
77 ->SetYSize(unit, y_full_size)
78 ->SetZEdgeDelta(unit, edge_z, z_delta);
79 return object;
80 }
81
82 BoxBuilderPtr CreateZDeltaBoxBuilder(const G4String &name, const G4double x_full_size,
83 const G4double y_full_size, const G4double edge_z,
84 const G4double z_delta) {
85 if (x_full_size <= 0 || y_full_size <= 0) {
86 throw std::invalid_argument("Error in CreateZDeltaBoxBuilder(): for volume " + name
87 + ": Sizes provided without end offsets must be positive.\n");
88 }
89 auto object = BoxBuilderPtr(new BoxBuilder(name));
90 object->SetXSize(x_full_size)
91 ->SetYSize(y_full_size)
92 ->SetZEdgeDelta(edge_z, z_delta);
93 return object;
94 }
95
96 BoxBuilderPtr CreateCenteredBoxBuilder(const G4double unit, const G4String &name,
97 const G4double x_full_size, const G4double y_full_size,
98 const G4double z_full_size) {
99 if (x_full_size <= 0 || y_full_size <= 0 || z_full_size <= 0) {
100 throw std::invalid_argument("Error in CreateCenteredBoxBuilder(): for volume " + name
101 + ": Sizes provided must be positive.\n");
102 }
103 auto object = BoxBuilderPtr(new BoxBuilder(name));
104 object->SetXSize(unit, x_full_size)
105 ->SetYSize(unit, y_full_size)
106 ->SetZSize(unit, z_full_size);
107 return object;
108 }
109
110 BoxBuilderPtr CreateCenteredBoxBuilder(const G4String &name, const G4double x_full_size,
111 const G4double y_full_size,
112 const G4double z_full_size) {
113 if (x_full_size <= 0 || y_full_size <= 0 || z_full_size <= 0) {
114 throw std::invalid_argument("Error in CreateCenteredBoxBuilder(): for volume " + name
115 + ": Sizes provided must be positive.\n");
116 }
117 auto object = BoxBuilderPtr(new BoxBuilder(name));
118 object->SetXSize(x_full_size)
119 ->SetYSize(y_full_size)
120 ->SetZSize(z_full_size);
121 return object;
122 }
123
124 BoxBuilderPtr CreateEdgesBoxBuilder(const G4String &name, const G4double x_edge1,
125 const G4double x_edge2, const G4double y_edge1,
126 const G4double y_edge2, const G4double z_edge1, const G4double z_edge2) {
127 auto object = BoxBuilderPtr(new BoxBuilder(name));
128 object->SetXEdges(x_edge1, x_edge2)
129 ->SetYEdges(y_edge1, y_edge2)
130 ->SetZEdges(z_edge1, z_edge2);
131 return object;
132 }
133
134 BoxBuilderPtr CreateEdgesBoxBuilder(const G4double unit, const G4String &name,
135 const G4double x_edge1, const G4double x_edge2,
136 const G4double y_edge1, const G4double y_edge2, const G4double z_edge1,
137 const G4double z_edge2) {
138 auto object = BoxBuilderPtr(new BoxBuilder(name));
139 object->SetXEdges(unit, x_edge1, x_edge2)
140 ->SetYEdges(unit, y_edge1, y_edge2)
141 ->SetZEdges(unit, z_edge1, z_edge2);
142 return object;
143 }
144
145 BoxBuilderPtr BoxBuilder::SetXSizeDimensioned(const G4double size) {
146 x_size_ = size;
147 return shared_from_this();
148 }
149
150 BoxBuilderPtr BoxBuilder::SetYSizeDimensioned(const G4double size) {
151 y_size_ = size;
152 return shared_from_this();
153 }
154
155 BoxBuilderPtr BoxBuilder::SetZSizeDimensioned(const G4double size) {
156 z_size_ = size;
157 return shared_from_this();
158 }
159
160 BoxBuilderPtr BoxBuilder::SetInternalOffsetDimensioned(const G4double x, const G4double y,
161 const G4double z) {
162 this->builder_configs_->internal_offset = G4ThreeVector(x, y, z);
163 PropagateTransform();
164 return shared_from_this();
165 }
166
167 // These methods use the builder's effective default unit.
168 BoxBuilderPtr BoxBuilder::SetXSize(const G4double x_size) {
169 return SetXSize(this->GetEffectiveDefaultUnit(), x_size);
170 }
171
172 BoxBuilderPtr BoxBuilder::SetYSize(const G4double y_size) {
173 return SetYSize(this->GetEffectiveDefaultUnit(), y_size);
174 }
175
176 BoxBuilderPtr BoxBuilder::SetZSize(const G4double z_size) {
177 return SetZSize(this->GetEffectiveDefaultUnit(), z_size);
178 }
179
180 BoxBuilderPtr BoxBuilder::SetXEdges(const G4double x_edge1, const G4double x_edge2) {
181 return SetXEdges(this->GetEffectiveDefaultUnit(), x_edge1, x_edge2);
182 }
183
184 BoxBuilderPtr BoxBuilder::SetYEdges(const G4double y_edge1, const G4double y_edge2) {
185 return SetYEdges(this->GetEffectiveDefaultUnit(), y_edge1, y_edge2);
186 }
187
188 BoxBuilderPtr BoxBuilder::SetZEdges(const G4double z_edge1, const G4double z_edge2) {
189 return SetZEdges(this->GetEffectiveDefaultUnit(), z_edge1, z_edge2);
190 }
191
192 BoxBuilderPtr BoxBuilder::SetXEdgeDelta(const G4double x_edge, const G4double x_delta) {
193 return SetXEdgeDelta(this->GetEffectiveDefaultUnit(), x_edge, x_delta);
194 }
195
196 BoxBuilderPtr BoxBuilder::SetYEdgeDelta(const G4double y_edge, const G4double y_delta) {
197 return SetYEdgeDelta(this->GetEffectiveDefaultUnit(), y_edge, y_delta);
198 }
199
200 BoxBuilderPtr BoxBuilder::SetZEdgeDelta(const G4double z_edge, const G4double z_delta) {
201 return SetZEdgeDelta(this->GetEffectiveDefaultUnit(), z_edge, z_delta);
202 }
203
204 BoxBuilderPtr BoxBuilder::SetInternalOffset(const G4double x, const G4double y,
205 const G4double z) {
206 return SetInternalOffset(this->GetEffectiveDefaultUnit(), x, y, z);
207 }
208
209 // These overloads handle the unit conversion and then delegate to the "Dimensioned" methods.
210 BoxBuilderPtr BoxBuilder::SetXSize(const G4double unit, const G4double x_size) {
211 return SetXSizeDimensioned(x_size * unit);
212 }
213
214 BoxBuilderPtr BoxBuilder::SetYSize(const G4double unit, const G4double y_size) {
215 return SetYSizeDimensioned(y_size * unit);
216 }
217
218 BoxBuilderPtr BoxBuilder::SetZSize(const G4double unit, const G4double z_size) {
219 return SetZSizeDimensioned(z_size * unit);
220 }
221
222 // These methods calculate the size and offset, apply the unit, and then delegate to the Dimensioned setters.
223 BoxBuilderPtr BoxBuilder::SetXEdges(const G4double unit, const G4double x_edge1,
224 const G4double x_edge2) {
225 G4double size = std::abs(x_edge2 - x_edge1);
226 G4double offset = (x_edge1 + x_edge2) / 2.0;
227 SetXSizeDimensioned(size * unit);
228 return SetInternalOffsetDimensioned(
229 offset * unit,
230 this->builder_configs_->internal_offset.y(),
231 this->builder_configs_->internal_offset.z()
232 );
233 }
234
235 BoxBuilderPtr BoxBuilder::SetYEdges(const G4double unit, const G4double y_edge1,
236 const G4double y_edge2) {
237 G4double size = std::abs(y_edge2 - y_edge1);
238 G4double offset = (y_edge1 + y_edge2) / 2.0;
239 SetYSizeDimensioned(size * unit);
240 return SetInternalOffsetDimensioned(
241 this->builder_configs_->internal_offset.x(),
242 offset * unit,
243 this->builder_configs_->internal_offset.z()
244 );
245 }
246
247 BoxBuilderPtr BoxBuilder::SetZEdges(const G4double unit, const G4double z_edge1,
248 const G4double z_edge2) {
249 G4double size = std::abs(z_edge2 - z_edge1);
250 G4double offset = (z_edge1 + z_edge2) / 2.0;
251 SetZSizeDimensioned(size * unit);
252 return SetInternalOffsetDimensioned(
253 this->builder_configs_->internal_offset.x(),
254 this->builder_configs_->internal_offset.y(),
255 offset * unit
256 );
257 }
258
259 // These methods calculate the size and offset from an edge and delta, apply the unit, and delegate.
260 BoxBuilderPtr BoxBuilder::SetXEdgeDelta(const G4double unit, const G4double x_edge,
261 const G4double x_delta) {
262 G4double size = std::abs(x_delta);
263 G4double offset = x_edge + x_delta / 2.0;
264 SetXSizeDimensioned(size * unit);
265 return SetInternalOffsetDimensioned(
266 offset * unit,
267 this->builder_configs_->internal_offset.y(),
268 this->builder_configs_->internal_offset.z()
269 );
270 }
271
272 BoxBuilderPtr BoxBuilder::SetYEdgeDelta(const G4double unit, const G4double y_edge,
273 const G4double y_delta) {
274 G4double size = std::abs(y_delta);
275 G4double offset = y_edge + y_delta / 2.0;
276 SetYSizeDimensioned(size * unit);
277 return SetInternalOffsetDimensioned(
278 this->builder_configs_->internal_offset.x(),
279 offset * unit,
280 this->builder_configs_->internal_offset.z()
281 );
282 }
283
284 BoxBuilderPtr BoxBuilder::SetZEdgeDelta(const G4double unit, const G4double z_edge,
285 const G4double z_delta) {
286 G4double size = std::abs(z_delta);
287 G4double offset = z_edge + z_delta / 2.0;
288 SetZSizeDimensioned(size * unit);
289 return SetInternalOffsetDimensioned(
290 this->builder_configs_->internal_offset.x(),
291 this->builder_configs_->internal_offset.y(),
292 offset * unit
293 );
294 }
295
296 BoxBuilderPtr BoxBuilder::SetInternalOffset(const G4double unit, const G4double x,
297 const G4double y, const G4double z) {
298 return SetInternalOffsetDimensioned(x * unit, y * unit, z * unit);
299 }
300
301 BoxBuilder::BoxBuilder(const G4String &name) {
302 this->builder_configs_->name = name;
303 }
304
305 //Private default copy ctor.
306 //This is used by clone methods of concrete classes
307 BoxBuilder::BoxBuilder(const BoxBuilder &other) : VolumeBuilder<BoxBuilder>(other),
308 // Call base class copy constructor
309 x_size_(other.x_size_),
310 y_size_(other.y_size_),
311 z_size_(other.z_size_) {
313 SetName(other.GetBuilderName());
314 builder_configs_->internal_offset = other.builder_configs_->internal_offset;
316 }
317
318 G4VSolid *BoxBuilder::SolidConstructor(const G4String &name) {
319 if (this->solid_ptr_.get() != nullptr) {
320 std::string error = "Error in BoxBuilder::SolidConstructor: A solid was already built\n"
321 "You can copy and rename the builder to reset it and build again.";
322 throw std::runtime_error(error);
323 }
324 G4cout << G4endl;
325 G4cout << "New BoxBuilder:" << GetBuilderName() // lie and use the final transformed name
326 << "x_size: " << x_size_ << " y_size: " << y_size_ << " z_size: " << z_size_ <<
327 G4endl;
328 G4cout << "Internal offset: " << this->builder_configs_->internal_offset << G4endl;
329 return new G4Box(name, x_size_ / 2.0, y_size_ / 2.0, z_size_ / 2.0);
330 }
331}
Builder class for simple Box solids.
BoxBuilderPtr SetXSize(G4double x_size)
G4VSolid * SolidConstructor(const G4String &name) override
The polymorphic Solid constructor.
BoxBuilderPtr SetZSize(G4double z_size)
BoxBuilderPtr SetInternalOffset(G4double x, G4double y, G4double z)
BoxBuilderPtr SetZEdgeDelta(G4double z_edge, G4double z_delta)
BoxBuilderPtr SetXEdgeDelta(G4double x_edge, G4double x_delta)
BoxBuilderPtr SetYEdgeDelta(G4double y_edge, G4double y_delta)
BoxBuilderPtr SetXEdges(G4double x_edge1, G4double x_edge2)
BoxBuilderPtr SetYEdges(G4double y_edge1, G4double y_edge2)
BoxBuilderPtr SetYSize(G4double y_size)
BoxBuilderPtr SetZEdges(G4double z_edge1, G4double z_edge2)
DerivedPtr SetName(const G4String &name)
SetName Sets name used for solid and derived product names.
A wrapper for std::shared_ptr that allows and facilitates many implicit(i) type conversions.
BoxBuilderPtr CreateCenteredBoxBuilder(const G4String &name, G4double x_full_size, G4double y_full_size, G4double z_full_size)
Create a Box solid.
BoxBuilderPtr CreateDeltasBoxBuilder(const G4String &name, G4double edge_x, G4double x_delta, G4double edge_y, G4double y_delta, G4double edge_z, G4double z_delta)
Create a Box solid.
Definition BoxBuilder.cc:56
BoxBuilderPtr CreateEdgesBoxBuilder(const G4String &name, G4double x_edge1, G4double x_edge2, G4double y_edge1, G4double y_edge2, G4double z_edge1, G4double z_edge2)
Create a Box solid from edge coordinates.
BoxBuilderPtr CreateBoxBuilder(const G4String &name)
Definition BoxBuilder.cc:32
BoxBuilderPtr CreateZDeltaBoxBuilder(const G4String &name, G4double x_full_size, G4double y_full_size, G4double edge_z, G4double z_delta)
Create a Box solid.
Definition BoxBuilder.cc:82
G4double GetEffectiveDefaultUnit() const
Get the builder default unit or global if not set.
SharedPtr< BoxBuilder > BoxBuilderPtr
Definition BoxBuilder.hh:28