45 std::unordered_map<std::string, G4Volume*>* g4s) {
48 log->info(2,
"%1G4NativeSystemFactory::buildSolid for %2",
className(), g4name);
60 thisG4Volume->setSolidPlacement(*rot,
getPosition(s));
65 if (thisG4Volume->getSolid() !=
nullptr)
return thisG4Volume->getSolid();
71 auto volume_copy =
gsystem +
"/" + *copyOf;
73 if (thisG4Volume->getSolid() !=
nullptr)
return thisG4Volume->getSolid();
84 bool absoluteCoordinates =
false;
85 if (!solidOperations.empty() && solidOperations[0] ==
"@") {
86 absoluteCoordinates =
true;
87 solidOperations.erase(solidOperations.begin());
90 if (solidOperations.size() == 3) {
91 auto resolveOperandName = [s, g4s](
const std::string& operand) -> std::string {
96 auto leftName = resolveOperandName(solidOperations[0]);
97 auto rightName = resolveOperandName(solidOperations[2]);
100 if (left ==
nullptr || right ==
nullptr)
return nullptr;
104 G4Transform3D transform;
105 if (absoluteCoordinates) {
111 G4RotationMatrix rot1 = leftWrapper->getSolidRotation();
112 G4RotationMatrix rot2 = rightWrapper->getSolidRotation();
113 G4ThreeVector pos1 = leftWrapper->getSolidTranslation();
114 G4ThreeVector pos2 = rightWrapper->getSolidTranslation();
116 G4RotationMatrix invRot1 = rot1.inverse();
117 G4RotationMatrix invNetRotation = (rot2 * invRot1).invert();
118 G4ThreeVector netTranslation = pos2 - pos1;
119 netTranslation *= rot1;
120 transform = G4Transform3D(invNetRotation, netTranslation);
126 G4RotationMatrix rotate = rightWrapper->getSolidRotation();
127 G4ThreeVector translate = rightWrapper->getSolidTranslation();
128 G4RotationMatrix invRot = rotate.invert();
129 G4Transform3D transf1(invRot, G4ThreeVector(0, 0, 0));
130 G4Transform3D transf2(G4RotationMatrix(), translate);
131 transform = transf2 * transf1;
134 if (solidOperations[1] ==
"+") {
135 thisG4Volume->setSolid(
new G4UnionSolid(g4name, left, right, transform),
log);
137 else if (solidOperations[1] ==
"-") {
138 thisG4Volume->setSolid(
new G4SubtractionSolid(g4name, left, right, transform),
log);
140 else if (solidOperations[1] ==
"*") {
141 thisG4Volume->setSolid(
new G4IntersectionSolid(g4name, left, right, transform),
log);
146 "The boolean constructor of <%1> uses unsupported operator <%2>. Use +, -, or *.", g4name,
149 return thisG4Volume->getSolid();
160 std::string type = s->
getType();
162 if (type ==
"G4Box") {
163 thisG4Volume->setSolid(
new G4Box(g4name,
168 return thisG4Volume->getSolid();
170 else if (type ==
"G4Tubs") {
171 thisG4Volume->setSolid(
new G4Tubs(g4name,
178 return thisG4Volume->getSolid();
180 else if (type ==
"G4Sphere") {
181 thisG4Volume->setSolid(
new G4Sphere(g4name,
189 return thisG4Volume->getSolid();
191 else if (type ==
"G4Torus") {
192 thisG4Volume->setSolid(
new G4Torus(g4name,
199 return thisG4Volume->getSolid();
201 else if (type ==
"G4CutTubs") {
202 thisG4Volume->setSolid(
new G4CutTubs(g4name,
208 G4ThreeVector(pars[5], pars[6], pars[7]),
209 G4ThreeVector(pars[8], pars[9], pars[10])
211 return thisG4Volume->getSolid();
213 else if (type ==
"G4Cons") {
214 thisG4Volume->setSolid(
new G4Cons(g4name,
223 return thisG4Volume->getSolid();
225 else if (type ==
"G4Para") {
226 thisG4Volume->setSolid(
new G4Para(g4name,
237 return thisG4Volume->getSolid();
239 else if (type ==
"G4Trd") {
240 thisG4Volume->setSolid(
new G4Trd(g4name,
247 return thisG4Volume->getSolid();
249 else if (type ==
"G4Trap") {
251 if (pars.size() == 4) {
252 thisG4Volume->setSolid(
new G4Trap(g4name,
259 else if (pars.size() == 11) {
260 thisG4Volume->setSolid(
new G4Trap(g4name,
275 else if (pars.size() == 24) {
277 pt[0] = G4ThreeVector(pars[0], pars[1], pars[2]);
278 pt[1] = G4ThreeVector(pars[3], pars[4], pars[5]);
279 pt[2] = G4ThreeVector(pars[6], pars[7], pars[8]);
280 pt[3] = G4ThreeVector(pars[9], pars[10], pars[11]);
281 pt[4] = G4ThreeVector(pars[12], pars[13], pars[14]);
282 pt[5] = G4ThreeVector(pars[15], pars[16], pars[17]);
283 pt[6] = G4ThreeVector(pars[18], pars[19], pars[20]);
284 pt[7] = G4ThreeVector(pars[21], pars[22], pars[23]);
286 thisG4Volume->setSolid(
new G4Trap(g4name, pt),
log);
291 "The constructor of <%1> must have 4, 11 or 24 parameters see "
292 "https://geant4-userdoc.web.cern.ch/UsersGuides/ForApplicationDeveloper/html/Detector/"
293 "Geometry/geomSolids.html", g4name);
295 return thisG4Volume->getSolid();
297 else if (type ==
"G4Polycone") {
298 double phistart = pars[0];
299 double phitotal = pars[1];
300 int zplanes =
static_cast<int>(pars[2]);
303 auto zPlane = std::make_unique<double[]>(zplanes);
304 auto rInner = std::make_unique<double[]>(zplanes);
305 auto rOuter = std::make_unique<double[]>(zplanes);
307 for (
int zpl = 0; zpl < zplanes; ++zpl) {
308 zPlane[zpl] = pars[3 + 0 * zplanes + zpl];
309 rInner[zpl] = pars[3 + 1 * zplanes + zpl];
310 rOuter[zpl] = pars[3 + 2 * zplanes + zpl];
313 thisG4Volume->setSolid(
new G4Polycone(g4name,
321 return thisG4Volume->getSolid();
323 else if (type ==
"G4Polyhedra") {
326 double phistart = pars[0];
327 double phitotal = pars[1];
328 int numSides =
static_cast<int>(pars[2]);
329 int zplanes =
static_cast<int>(pars[3]);
331 if (numSides < 1 ||
static_cast<int>(pars.size()) != 4 + 3 * zplanes) {
334 "The constructor of <%1> must have numSides >= 1 and %2 parameters (4 + 3 x numZPlanes), we "
335 "got %3", g4name, 4 + 3 * zplanes, pars.size());
339 auto zPlane = std::make_unique<double[]>(zplanes);
340 auto rInner = std::make_unique<double[]>(zplanes);
341 auto rOuter = std::make_unique<double[]>(zplanes);
343 for (
int zpl = 0; zpl < zplanes; ++zpl) {
344 rInner[zpl] = pars[4 + 0 * zplanes + zpl];
345 rOuter[zpl] = pars[4 + 1 * zplanes + zpl];
346 zPlane[zpl] = pars[4 + 2 * zplanes + zpl];
349 thisG4Volume->setSolid(
new G4Polyhedra(g4name,
358 return thisG4Volume->getSolid();
360 else if (type ==
"G4Paraboloid") {
361 thisG4Volume->setSolid(
new G4Paraboloid(g4name,
366 return thisG4Volume->getSolid();
368 else if (type ==
"G4EllipticalTube") {
369 thisG4Volume->setSolid(
new G4EllipticalTube(g4name,
374 return thisG4Volume->getSolid();
376 else if (type ==
"G4Ellipsoid") {
377 thisG4Volume->setSolid(
new G4Ellipsoid(g4name,
384 return thisG4Volume->getSolid();
386 else if (type ==
"G4Orb") {
387 thisG4Volume->setSolid(
new G4Orb(g4name,
390 return thisG4Volume->getSolid();
392 else if (type ==
"G4GenericPolycone") {
393 double phistart = pars[0];
394 double phitotal = pars[1];
395 int numRZ =
static_cast<int>(pars[2]);
398 auto r = std::make_unique<double[]>(numRZ);
399 auto z = std::make_unique<double[]>(numRZ);
400 for (
int i = 0; i < numRZ; ++i) {
401 r[i] = pars[3 + 0 * numRZ + i];
402 z[i] = pars[3 + 1 * numRZ + i];
405 thisG4Volume->setSolid(
new G4GenericPolycone(g4name,
412 return thisG4Volume->getSolid();
414 else if (type ==
"G4EllipticalCone") {
415 thisG4Volume->setSolid(
new G4EllipticalCone(g4name,
421 return thisG4Volume->getSolid();
423 else if (type ==
"G4Hype") {
424 thisG4Volume->setSolid(
new G4Hype(g4name,
431 return thisG4Volume->getSolid();
433 else if (type ==
"G4Tet") {
435 thisG4Volume->setSolid(
new G4Tet(g4name,
436 G4ThreeVector(pars[0], pars[1], pars[2]),
437 G4ThreeVector(pars[3], pars[4], pars[5]),
438 G4ThreeVector(pars[6], pars[7], pars[8]),
439 G4ThreeVector(pars[9], pars[10], pars[11])
441 return thisG4Volume->getSolid();
443 else if (type ==
"G4TwistedBox") {
444 thisG4Volume->setSolid(
new G4TwistedBox(g4name,
450 return thisG4Volume->getSolid();
452 else if (type ==
"G4TwistedTrap") {
454 if (pars.size() == 5) {
455 thisG4Volume->setSolid(
new G4TwistedTrap(g4name,
463 else if (pars.size() == 11) {
464 thisG4Volume->setSolid(
new G4TwistedTrap(g4name,
481 "The constructor of <%1> must have 5 or 11 parameters.", g4name);
483 return thisG4Volume->getSolid();
485 else if (type ==
"G4TwistedTrd") {
486 thisG4Volume->setSolid(
new G4TwistedTrd(g4name,
494 return thisG4Volume->getSolid();
496 else if (type ==
"G4TwistedTubs") {
497 thisG4Volume->setSolid(
new G4TwistedTubs(g4name,
504 return thisG4Volume->getSolid();
509 "The constructor of <%1> uses an unknown solid type <%2>. See Geant4 manual for supported "
510 "primitives.", g4name, type);