36 std::unordered_map<std::string, G4Volume*>* g4s) {
39 log->info(2,
className(),
"G4NativeSystemFactory::buildSolid for ", g4name);
51 thisG4Volume->setSolidPlacement(*rot,
getPosition(s));
56 if (thisG4Volume->getSolid() !=
nullptr)
return thisG4Volume->getSolid();
62 auto volume_copy =
gsystem +
"/" + *copyOf;
64 if (thisG4Volume->getSolid() !=
nullptr)
return thisG4Volume->getSolid();
75 bool absoluteCoordinates =
false;
76 if (!solidOperations.empty() && solidOperations[0] ==
"@") {
77 absoluteCoordinates =
true;
78 solidOperations.erase(solidOperations.begin());
81 if (solidOperations.size() == 3) {
82 auto resolveOperandName = [s, g4s](
const std::string& operand) -> std::string {
87 auto leftName = resolveOperandName(solidOperations[0]);
88 auto rightName = resolveOperandName(solidOperations[2]);
91 if (left ==
nullptr || right ==
nullptr)
return nullptr;
95 G4Transform3D transform;
96 if (absoluteCoordinates) {
102 G4RotationMatrix rot1 = leftWrapper->getSolidRotation();
103 G4RotationMatrix rot2 = rightWrapper->getSolidRotation();
104 G4ThreeVector pos1 = leftWrapper->getSolidTranslation();
105 G4ThreeVector pos2 = rightWrapper->getSolidTranslation();
107 G4RotationMatrix invRot1 = rot1.inverse();
108 G4RotationMatrix invNetRotation = (rot2 * invRot1).invert();
109 G4ThreeVector netTranslation = pos2 - pos1;
110 netTranslation *= rot1;
111 transform = G4Transform3D(invNetRotation, netTranslation);
117 G4RotationMatrix rotate = rightWrapper->getSolidRotation();
118 G4ThreeVector translate = rightWrapper->getSolidTranslation();
119 G4RotationMatrix invRot = rotate.invert();
120 G4Transform3D transf1(invRot, G4ThreeVector(0, 0, 0));
121 G4Transform3D transf2(G4RotationMatrix(), translate);
122 transform = transf2 * transf1;
125 if (solidOperations[1] ==
"+") {
126 thisG4Volume->setSolid(
new G4UnionSolid(g4name, left, right, transform),
log);
128 else if (solidOperations[1] ==
"-") {
129 thisG4Volume->setSolid(
new G4SubtractionSolid(g4name, left, right, transform),
log);
131 else if (solidOperations[1] ==
"*") {
132 thisG4Volume->setSolid(
new G4IntersectionSolid(g4name, left, right, transform),
log);
136 "The boolean constructor of <", g4name,
"> uses unsupported operator <",
137 solidOperations[1],
">. Use +, -, or *.");
139 return thisG4Volume->getSolid();
142 "The boolean constructor of <", g4name,
"> must be: left operator right.");
149 std::string type = s->
getType();
151 if (type ==
"G4Box") {
152 thisG4Volume->setSolid(
new G4Box(g4name,
157 return thisG4Volume->getSolid();
159 else if (type ==
"G4Tubs") {
160 thisG4Volume->setSolid(
new G4Tubs(g4name,
167 return thisG4Volume->getSolid();
169 else if (type ==
"G4Sphere") {
170 thisG4Volume->setSolid(
new G4Sphere(g4name,
178 return thisG4Volume->getSolid();
180 else if (type ==
"G4Torus") {
181 thisG4Volume->setSolid(
new G4Torus(g4name,
188 return thisG4Volume->getSolid();
190 else if (type ==
"G4CutTubs") {
191 thisG4Volume->setSolid(
new G4CutTubs(g4name,
197 G4ThreeVector(pars[5], pars[6], pars[7]),
198 G4ThreeVector(pars[8], pars[9], pars[10])
200 return thisG4Volume->getSolid();
202 else if (type ==
"G4Cons") {
203 thisG4Volume->setSolid(
new G4Cons(g4name,
212 return thisG4Volume->getSolid();
214 else if (type ==
"G4Para") {
215 thisG4Volume->setSolid(
new G4Para(g4name,
226 return thisG4Volume->getSolid();
228 else if (type ==
"G4Trd") {
229 thisG4Volume->setSolid(
new G4Trd(g4name,
236 return thisG4Volume->getSolid();
238 else if (type ==
"G4Trap") {
240 if (pars.size() == 4) {
241 thisG4Volume->setSolid(
new G4Trap(g4name,
248 else if (pars.size() == 11) {
249 thisG4Volume->setSolid(
new G4Trap(g4name,
264 else if (pars.size() == 24) {
266 pt[0] = G4ThreeVector(pars[0], pars[1], pars[2]);
267 pt[1] = G4ThreeVector(pars[3], pars[4], pars[5]);
268 pt[2] = G4ThreeVector(pars[6], pars[7], pars[8]);
269 pt[3] = G4ThreeVector(pars[9], pars[10], pars[11]);
270 pt[4] = G4ThreeVector(pars[12], pars[13], pars[14]);
271 pt[5] = G4ThreeVector(pars[15], pars[16], pars[17]);
272 pt[6] = G4ThreeVector(pars[18], pars[19], pars[20]);
273 pt[7] = G4ThreeVector(pars[21], pars[22], pars[23]);
275 thisG4Volume->setSolid(
new G4Trap(g4name, pt),
log);
279 "The constructor of <", g4name,
"> must have 4, 11 or 24 parameters",
280 " see https://geant4-userdoc.web.cern.ch/UsersGuides/ForApplicationDeveloper/html/Detector/Geometry/geomSolids.html");
282 return thisG4Volume->getSolid();
284 else if (type ==
"G4Polycone") {
285 double phistart = pars[0];
286 double phitotal = pars[1];
287 int zplanes =
static_cast<int>(pars[2]);
290 auto zPlane = std::make_unique<double[]>(zplanes);
291 auto rInner = std::make_unique<double[]>(zplanes);
292 auto rOuter = std::make_unique<double[]>(zplanes);
294 for (
int zpl = 0; zpl < zplanes; ++zpl) {
295 zPlane[zpl] = pars[3 + 0 * zplanes + zpl];
296 rInner[zpl] = pars[3 + 1 * zplanes + zpl];
297 rOuter[zpl] = pars[3 + 2 * zplanes + zpl];
300 thisG4Volume->setSolid(
new G4Polycone(g4name,
308 return thisG4Volume->getSolid();
310 else if (type ==
"G4Polyhedra") {
313 double phistart = pars[0];
314 double phitotal = pars[1];
315 int numSides =
static_cast<int>(pars[2]);
316 int zplanes =
static_cast<int>(pars[3]);
318 if (numSides < 1 ||
static_cast<int>(pars.size()) != 4 + 3 * zplanes) {
320 "The constructor of <", g4name,
"> must have numSides >= 1 and ",
321 4 + 3 * zplanes,
" parameters (4 + 3 x numZPlanes), we got ", pars.size());
325 auto zPlane = std::make_unique<double[]>(zplanes);
326 auto rInner = std::make_unique<double[]>(zplanes);
327 auto rOuter = std::make_unique<double[]>(zplanes);
329 for (
int zpl = 0; zpl < zplanes; ++zpl) {
330 rInner[zpl] = pars[4 + 0 * zplanes + zpl];
331 rOuter[zpl] = pars[4 + 1 * zplanes + zpl];
332 zPlane[zpl] = pars[4 + 2 * zplanes + zpl];
335 thisG4Volume->setSolid(
new G4Polyhedra(g4name,
344 return thisG4Volume->getSolid();
346 else if (type ==
"G4Paraboloid") {
347 thisG4Volume->setSolid(
new G4Paraboloid(g4name,
352 return thisG4Volume->getSolid();
354 else if (type ==
"G4EllipticalTube") {
355 thisG4Volume->setSolid(
new G4EllipticalTube(g4name,
360 return thisG4Volume->getSolid();
362 else if (type ==
"G4Ellipsoid") {
363 thisG4Volume->setSolid(
new G4Ellipsoid(g4name,
370 return thisG4Volume->getSolid();
374 "The constructor of <", g4name,
"> uses an unknown solid type <", type,
375 ">. See Geant4 manual for supported primitives.");