36 std::unordered_map<std::string, G4Volume*>* g4s) {
39 log->info(2,
"%1G4NativeSystemFactory::buildSolid for %2",
className(), 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);
137 "The boolean constructor of <%1> uses unsupported operator <%2>. Use +, -, or *.", g4name,
140 return thisG4Volume->getSolid();
151 std::string type = s->
getType();
153 if (type ==
"G4Box") {
154 thisG4Volume->setSolid(
new G4Box(g4name,
159 return thisG4Volume->getSolid();
161 else if (type ==
"G4Tubs") {
162 thisG4Volume->setSolid(
new G4Tubs(g4name,
169 return thisG4Volume->getSolid();
171 else if (type ==
"G4Sphere") {
172 thisG4Volume->setSolid(
new G4Sphere(g4name,
180 return thisG4Volume->getSolid();
182 else if (type ==
"G4Torus") {
183 thisG4Volume->setSolid(
new G4Torus(g4name,
190 return thisG4Volume->getSolid();
192 else if (type ==
"G4CutTubs") {
193 thisG4Volume->setSolid(
new G4CutTubs(g4name,
199 G4ThreeVector(pars[5], pars[6], pars[7]),
200 G4ThreeVector(pars[8], pars[9], pars[10])
202 return thisG4Volume->getSolid();
204 else if (type ==
"G4Cons") {
205 thisG4Volume->setSolid(
new G4Cons(g4name,
214 return thisG4Volume->getSolid();
216 else if (type ==
"G4Para") {
217 thisG4Volume->setSolid(
new G4Para(g4name,
228 return thisG4Volume->getSolid();
230 else if (type ==
"G4Trd") {
231 thisG4Volume->setSolid(
new G4Trd(g4name,
238 return thisG4Volume->getSolid();
240 else if (type ==
"G4Trap") {
242 if (pars.size() == 4) {
243 thisG4Volume->setSolid(
new G4Trap(g4name,
250 else if (pars.size() == 11) {
251 thisG4Volume->setSolid(
new G4Trap(g4name,
266 else if (pars.size() == 24) {
268 pt[0] = G4ThreeVector(pars[0], pars[1], pars[2]);
269 pt[1] = G4ThreeVector(pars[3], pars[4], pars[5]);
270 pt[2] = G4ThreeVector(pars[6], pars[7], pars[8]);
271 pt[3] = G4ThreeVector(pars[9], pars[10], pars[11]);
272 pt[4] = G4ThreeVector(pars[12], pars[13], pars[14]);
273 pt[5] = G4ThreeVector(pars[15], pars[16], pars[17]);
274 pt[6] = G4ThreeVector(pars[18], pars[19], pars[20]);
275 pt[7] = G4ThreeVector(pars[21], pars[22], pars[23]);
277 thisG4Volume->setSolid(
new G4Trap(g4name, pt),
log);
282 "The constructor of <%1> must have 4, 11 or 24 parameters see "
283 "https://geant4-userdoc.web.cern.ch/UsersGuides/ForApplicationDeveloper/html/Detector/"
284 "Geometry/geomSolids.html", g4name);
286 return thisG4Volume->getSolid();
288 else if (type ==
"G4Polycone") {
289 double phistart = pars[0];
290 double phitotal = pars[1];
291 int zplanes =
static_cast<int>(pars[2]);
294 auto zPlane = std::make_unique<double[]>(zplanes);
295 auto rInner = std::make_unique<double[]>(zplanes);
296 auto rOuter = std::make_unique<double[]>(zplanes);
298 for (
int zpl = 0; zpl < zplanes; ++zpl) {
299 zPlane[zpl] = pars[3 + 0 * zplanes + zpl];
300 rInner[zpl] = pars[3 + 1 * zplanes + zpl];
301 rOuter[zpl] = pars[3 + 2 * zplanes + zpl];
304 thisG4Volume->setSolid(
new G4Polycone(g4name,
312 return thisG4Volume->getSolid();
314 else if (type ==
"G4Polyhedra") {
317 double phistart = pars[0];
318 double phitotal = pars[1];
319 int numSides =
static_cast<int>(pars[2]);
320 int zplanes =
static_cast<int>(pars[3]);
322 if (numSides < 1 ||
static_cast<int>(pars.size()) != 4 + 3 * zplanes) {
325 "The constructor of <%1> must have numSides >= 1 and %2 parameters (4 + 3 x numZPlanes), we "
326 "got %3", g4name, 4 + 3 * zplanes, pars.size());
330 auto zPlane = std::make_unique<double[]>(zplanes);
331 auto rInner = std::make_unique<double[]>(zplanes);
332 auto rOuter = std::make_unique<double[]>(zplanes);
334 for (
int zpl = 0; zpl < zplanes; ++zpl) {
335 rInner[zpl] = pars[4 + 0 * zplanes + zpl];
336 rOuter[zpl] = pars[4 + 1 * zplanes + zpl];
337 zPlane[zpl] = pars[4 + 2 * zplanes + zpl];
340 thisG4Volume->setSolid(
new G4Polyhedra(g4name,
349 return thisG4Volume->getSolid();
351 else if (type ==
"G4Paraboloid") {
352 thisG4Volume->setSolid(
new G4Paraboloid(g4name,
357 return thisG4Volume->getSolid();
359 else if (type ==
"G4EllipticalTube") {
360 thisG4Volume->setSolid(
new G4EllipticalTube(g4name,
365 return thisG4Volume->getSolid();
367 else if (type ==
"G4Ellipsoid") {
368 thisG4Volume->setSolid(
new G4Ellipsoid(g4name,
375 return thisG4Volume->getSolid();
380 "The constructor of <%1> uses an unknown solid type <%2>. See Geant4 manual for supported "
381 "primitives.", g4name, type);