11 #include <geometry/modules/fbxWriter/FBXWriterModule.h>
12 #include <geometry/GeometryManager.h>
14 #include "G4PhysicalVolumeStore.hh"
15 #include "G4LogicalVolumeStore.hh"
16 #include "G4SolidStore.hh"
17 #include "G4VPhysicalVolume.hh"
18 #include "G4LogicalVolume.hh"
19 #include "G4VSolid.hh"
20 #include "G4DisplacedSolid.hh"
21 #include "G4Material.hh"
22 #include "G4VisAttributes.hh"
23 #include "G4ThreeVector.hh"
24 #include "G4RotationMatrix.hh"
25 #include "G4Transform3D.hh"
26 #include "G4VPVParameterisation.hh"
28 #include <G4Polyhedron.hh>
39 setDescription(
"Write the detector geometry in a (semi-)hierarchical FBX format.");
59 B2ERROR(
"No geometry found: add the Geometry module to the path before the FBXWriter module.");
63 G4PhysicalVolumeStore* pvStore = G4PhysicalVolumeStore::GetInstance();
64 G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance();
65 G4SolidStore* solidStore = G4SolidStore::GetInstance();
68 m_PVName =
new std::vector<std::string>(pvStore->size(),
"");
69 m_LVName =
new std::vector<std::string>(lvStore->size(),
"");
70 m_SolidName =
new std::vector<std::string>(solidStore->size(),
"");
71 for (G4VPhysicalVolume* physVol : *pvStore) {
72 int pvIndex = std::find(pvStore->begin(), pvStore->end(), physVol) - pvStore->begin();
73 if ((*
m_PVName)[pvIndex].length() == 0) {
75 G4LogicalVolume* logVol = physVol->GetLogicalVolume();
76 int lvIndex = std::find(lvStore->begin(), lvStore->end(), logVol) - lvStore->begin();
77 if ((*
m_LVName)[lvIndex].length() == 0) {
79 G4VSolid* solid = logVol->GetSolid();
80 int solidIndex = std::find(solidStore->begin(), solidStore->end(), solid) - solidStore->begin();
90 m_PVCount =
new std::vector<unsigned int>(pvStore->size(), 0);
91 m_LVCount =
new std::vector<unsigned int>(lvStore->size(), 0);
92 m_SolidCount =
new std::vector<unsigned int>(solidStore->size(), 0);
93 m_PVReplicas =
new std::vector<unsigned int>(pvStore->size(), 0);
94 m_LVReplicas =
new std::vector<unsigned int>(lvStore->size(), 0);
96 m_LVUnique =
new std::vector<bool>(lvStore->size(),
true);
98 unsigned int geometryCount = 0;
99 unsigned int materialCount = 0;
100 unsigned int modelCount = 0;
101 for (
unsigned int pvIndex = 0; pvIndex < pvStore->size(); ++pvIndex) {
102 if ((*
m_PVName)[pvIndex].length() > 0) {
103 modelCount += (*m_PVCount)[pvIndex] + (*m_PVReplicas)[pvIndex];
106 for (
unsigned int lvIndex = 0; lvIndex < lvStore->size(); ++lvIndex) {
107 if ((*
m_LVName)[lvIndex].length() > 0) {
109 modelCount += (*m_LVCount)[lvIndex] + (*m_LVReplicas)[lvIndex];
114 for (
unsigned int solidIndex = 0; solidIndex < solidStore->size(); ++solidIndex) {
116 geometryCount += (*m_SolidCount)[solidIndex] + (*m_SolidReplicas)[solidIndex] + 1;
126 m_PVID =
new std::vector<unsigned long long>(pvStore->size(), 0x0000010000000000LL);
127 m_LVID =
new std::vector<unsigned long long>(lvStore->size(), 0x000000C000000000LL);
128 m_SolidID =
new std::vector<unsigned long long>(solidStore->size(), 0x0000008000000000LL);
129 m_MatID =
new std::vector<unsigned long long>(lvStore->size(), 0x0000004000000000LL);
130 m_Visible =
new std::vector<bool>(lvStore->size(),
false);
131 m_File <<
"Objects: {" << std::endl;
132 for (
unsigned int solidIndex = 0; solidIndex < solidStore->size(); ++solidIndex) {
133 (*m_SolidID)[solidIndex] += 0x0000000001000000LL * solidIndex;
135 for (
unsigned int solidCount = 0; solidCount <= (*m_SolidCount)[solidIndex]; ++solidCount) {
140 for (
unsigned int lvIndex = 0; lvIndex < lvStore->size(); ++lvIndex) {
141 (*m_MatID)[lvIndex] += 0x0000000001000000LL * lvIndex;
142 (*m_LVID)[lvIndex] += 0x0000000001000000LL * lvIndex;
143 if ((*
m_LVName)[lvIndex].length() > 0) {
147 for (
unsigned int pvIndex = 0; pvIndex < pvStore->size(); ++pvIndex) {
148 (*m_PVID)[pvIndex] += 0x0000000001000000LL * pvIndex;
154 m_File <<
"}" << std::endl << std::endl;
160 m_File <<
"Connections: {" << std::endl;
162 int pvIndex = std::find(pvStore->begin(), pvStore->end(), topVol) - pvStore->begin();
163 m_File <<
"\t; Physical volume Model::" << (*m_PVName)[pvIndex] <<
" to Model::RootNode" << std::endl <<
164 "\tC: \"OO\"," << (*m_PVID)[pvIndex] <<
",0" << std::endl << std::endl <<
165 "}" << std::endl << std::endl;
167 m_File <<
"Takes: {" << std::endl <<
168 "\tCurrent: \"\"" << std::endl <<
190 G4PhysicalVolumeStore* pvStore = G4PhysicalVolumeStore::GetInstance();
191 G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance();
192 G4SolidStore* solidStore = G4SolidStore::GetInstance();
194 G4String name = originalName;
195 if (name.length() == 0) { name =
"anonymous"; }
197 for (
char c :
" .,:;?'\"*+-=|^!/@#$\\%{}[]()<>") std::replace(name.begin(), name.end(), c,
'_');
199 for (
int j = (
int)index - 1; j >= 0; --j) {
200 if ((*names)[j].length() == 0)
continue;
204 match = (*pvStore)[j]->GetName().compare((*pvStore)[index]->GetName());
break;
206 match = (*lvStore)[j]->GetName().compare((*lvStore)[index]->GetName());
break;
208 match = (*solidStore)[j]->GetName().compare((*solidStore)[index]->GetName());
break;
211 if (name.length() == (*names)[j].length()) {
212 (*names)[j].append(
"_1");
214 int n = std::stoi((*names)[j].substr(name.length() + 1),
nullptr);
216 name.append(std::to_string(n + 1));
220 (*names)[index] = name;
225 if ((solid->GetEntityType() ==
"G4IntersectionSolid") ||
226 (solid->GetEntityType() ==
"G4UnionSolid") ||
227 (solid->GetEntityType() ==
"G4SubtractionSolid") ||
228 (solid->GetEntityType() ==
"G4BooleanSolid")) {
230 auto* g4polyhedron =
new G4Polyhedron(*polyhedron);
241 G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance();
242 G4LogicalVolume* logVol = (*lvStore)[lvIndex];
243 unsigned long long matID = (*m_MatID)[lvIndex];
244 G4Color color(0.0, 1.0, 0.0, 0.5);
245 if ((matName.compare(0, 23,
"eclBarrelCrystalLogical") == 0) ||
246 (matName.compare(0, 20,
"eclFwdCrystalLogical") == 0) ||
247 (matName.compare(0, 20,
"eclBwdCrystalLogical") == 0) ||
248 (matName.compare(0, 24,
"eclBarrelCrystalPhysical") == 0) ||
249 (matName.compare(0, 21,
"eclFwdCrystalPhysical") == 0) ||
250 (matName.compare(0, 21,
"eclBwdCrystalPhysical") == 0)) {
251 color = G4Color(1.0, 0.25, 0.0, 0.7);
254 G4String materialName = logVol->GetMaterial()->GetName();
256 if (materialName ==
"Vacuum") visible =
false;
257 if (materialName ==
"G4_AIR") visible =
false;
258 if (materialName ==
"CDCGas") visible =
false;
259 if (materialName ==
"ColdAir") visible =
false;
260 if (materialName ==
"STR-DryAir") visible =
false;
261 if (materialName ==
"TOPAir") visible =
false;
262 if (materialName ==
"TOPVacuum") visible =
false;
263 const G4VisAttributes* visAttr = logVol->GetVisAttributes();
265 color =
const_cast<G4Color&
>(logVol->GetVisAttributes()->GetColor());
266 if (!(visAttr->IsVisible())) visible =
false;
270 if (logVol->GetSensitiveDetector() !=
nullptr) visible =
"";
271 (*m_Visible)[lvIndex] = visible;
272 m_File <<
"\t; Color for LogVol " << logVol->GetName() << std::endl <<
273 "\tMaterial: " << matID <<
", \"Material::" << matName << R
"(", "" {)" << std::endl <<
274 "\t\tVersion: 102" << std::endl <<
275 "\t\tProperties70: {" << std::endl <<
276 "\t\t\tP: \"ShadingModel\", \"KString\", \"\", \"\", \"phong\"" << std::endl <<
277 "\t\t\tP: \"DiffuseColor\", \"RGBColor\", \"Color\", \"A\"," <<
278 color.GetRed() <<
"," << color.GetGreen() <<
"," << color.GetBlue() << std::endl <<
279 "\t\t\tP: \"TransparentColor\", \"RGBColor\", \"Color\", \"A\",1,1,1" << std::endl <<
280 "\t\t\tP: \"TransparencyFactor\", \"double\", \"Number\", \"\"," << (visible ? 1.0 - color.GetAlpha() : 1) << std::endl <<
281 "\t\t}" << std::endl <<
287 m_File <<
"\t; LogVol " << logVol->GetName() <<
" with solid " << logVol->GetSolid()->GetName() << std::endl <<
288 "\tModel: " << lvID <<
", \"Model::lv_" << lvName << R
"(", "Null" {)" << std::endl <<
289 "\t\tVersion: 232" << std::endl <<
290 "\t\tProperties70: {" << std::endl <<
291 "\t\t}" << std::endl <<
292 "\t\tShading: T" << std::endl <<
293 "\t\tCulling: \"CullingOff\"" << std::endl <<
300 G4LogicalVolume* logVol = physVol->GetLogicalVolume();
301 for (
int daughter = 0; daughter < logVol->GetNoDaughters(); ++daughter) {
302 G4VPhysicalVolume* physVolDaughter = logVol->GetDaughter(daughter);
303 for (
int j = 0; j < physVolDaughter->GetMultiplicity(); ++j) {
309 G4PhysicalVolumeStore* pvStore = G4PhysicalVolumeStore::GetInstance();
310 G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance();
311 int pvIndex = std::find(pvStore->begin(), pvStore->end(), physVol) - pvStore->begin();
312 unsigned long long pvID = (*m_PVID)[pvIndex];
313 unsigned int pvCount = (*m_PVCount)[pvIndex];
314 std::string pvName = (*m_PVName)[pvIndex];
315 int lvIndex = std::find(lvStore->begin(), lvStore->end(), logVol) - lvStore->begin();
316 unsigned long long lvID = (*m_LVID)[lvIndex];
317 unsigned int lvCount = (*m_LVCount)[lvIndex];
318 std::string lvName = (*m_LVName)[lvIndex];
320 if (physVol->IsReplicated()) {
321 G4VSolid* solid = logVol->GetSolid();
322 G4SolidStore* solidStore = G4SolidStore::GetInstance();
323 int solidIndex = std::find(solidStore->begin(), solidStore->end(), solid) - solidStore->begin();
324 unsigned long long solidID = (*m_SolidID)[solidIndex];
330 physVol->GetReplicationData(axis, nReplicas, width, offset, consuming);
331 physVol->SetCopyNo(replica);
332 G4VPVParameterisation* physParameterisation = physVol->GetParameterisation();
333 if (physParameterisation) {
334 G4VSolid* solidReplica = physParameterisation->ComputeSolid(replica, physVol);
335 physParameterisation->ComputeTransformation(replica, physVol);
336 solidReplica->ComputeDimensions(physParameterisation, replica, physVol);
337 if (!(*solidReplica == *solid)) {
338 std::string solidName = (*m_SolidName)[solidIndex];
339 solidName.append(
"_R");
340 solidName.append(std::to_string(replica));
344 if ((replica == 0) && (lvCount == 0)) {
353 pvName.append(std::to_string(replica));
356 G4RotationMatrix* originalRotation = physVol->GetRotation();
357 G4ThreeVector translation;
358 G4RotationMatrix rotation;
362 translation.setX(width * (replica - 0.5 * (nReplicas - 1)));
363 physVol->SetTranslation(translation);
366 translation.setY(width * (replica - 0.5 * (nReplicas - 1)));
367 physVol->SetTranslation(translation);
370 translation.setZ(width * (replica - 0.5 * (nReplicas - 1)));
371 physVol->SetTranslation(translation);
374 if (solid->GetEntityType() ==
"G4Tubs") {
375 double originalRMin = ((G4Tubs*)solid)->GetInnerRadius();
376 double originalRMax = ((G4Tubs*)solid)->GetOuterRadius();
377 ((G4Tubs*)solid)->SetInnerRadius(offset + width * replica);
378 ((G4Tubs*)solid)->SetOuterRadius(offset + width * (replica + 1));
379 std::string solidName = (*m_SolidName)[solidIndex];
380 solidName.append(
"_R");
381 solidName.append(std::to_string(replica));
383 ((G4Tubs*)solid)->SetInnerRadius(originalRMin);
384 ((G4Tubs*)solid)->SetOuterRadius(originalRMax);
385 }
else if (replica == 0) {
386 B2WARNING(
"Built-in volumes replicated along radius for " << solid->GetEntityType() <<
387 " (solid " << solid->GetName() <<
") are not visualisable.");
391 physVol->SetRotation(&(rotation.rotateZ(-(offset + (replica + 0.5) * width))));
394 if (
m_UsePrototypes && !((axis == kRho) && (solid->GetEntityType() ==
"G4Tubs"))) {
395 if ((replica == 0) && (lvCount == 0)) {
404 pvName.append(std::to_string(replica));
406 if (axis == kPhi) physVol->SetRotation(originalRotation);
418 (*m_LVCount)[lvIndex]++;
419 (*m_PVCount)[pvIndex]++;
426 G4LogicalVolume* logVol = physVol->GetLogicalVolume();
427 for (
int daughter = 0; daughter < logVol->GetNoDaughters(); ++daughter) {
428 G4VPhysicalVolume* physVolDaughter = logVol->GetDaughter(daughter);
429 for (
int j = 0; j < physVolDaughter->GetMultiplicity(); ++j) {
435 G4PhysicalVolumeStore* pvStore = G4PhysicalVolumeStore::GetInstance();
436 G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance();
437 G4SolidStore* solidStore = G4SolidStore::GetInstance();
438 G4VSolid* solid = logVol->GetSolid();
439 int pvIndex = std::find(pvStore->begin(), pvStore->end(), physVol) - pvStore->begin();
440 int lvIndex = std::find(lvStore->begin(), lvStore->end(), logVol) - lvStore->begin();
441 int solidIndex = std::find(solidStore->begin(), solidStore->end(), solid) - solidStore->begin();
442 if (physVol->IsReplicated()) {
448 physVol->GetReplicationData(axis, nReplicas, width, offset, consuming);
449 G4VPVParameterisation* physParameterisation = physVol->GetParameterisation();
450 if (physParameterisation) {
451 G4VSolid* solidReplica = physParameterisation->ComputeSolid(0, physVol);
452 physParameterisation->ComputeTransformation(0, physVol);
453 solidReplica->ComputeDimensions(physParameterisation, 0, physVol);
454 if (!(*solidReplica == *solid))(*m_SolidReplicas)[solidIndex]++;
456 if ((*
m_LVReplicas)[lvIndex] > 0)(*m_LVUnique)[lvIndex] =
false;
457 (*m_LVReplicas)[lvIndex] = 1;
459 (*m_LVReplicas)[lvIndex]++;
461 (*m_PVReplicas)[pvIndex]++;
463 if ((axis == kRho) && (solid->GetEntityType() ==
"G4Tubs"))(*m_SolidReplicas)[solidIndex]++;
464 if (
m_UsePrototypes && !((axis == kRho) && (solid->GetEntityType() ==
"G4Tubs"))) {
465 (*m_LVReplicas)[lvIndex] = 1;
467 (*m_LVReplicas)[lvIndex]++;
469 (*m_PVReplicas)[pvIndex]++;
472 if ((*
m_LVCount)[lvIndex] > 0)(*m_LVUnique)[lvIndex] =
false;
474 (*m_PVCount)[pvIndex] = 1;
475 (*m_LVCount)[lvIndex] = 1;
477 (*m_PVCount)[pvIndex]++;
478 (*m_LVCount)[lvIndex]++;
487 G4PhysicalVolumeStore* pvStore = G4PhysicalVolumeStore::GetInstance();
488 G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance();
489 G4SolidStore* solidStore = G4SolidStore::GetInstance();
490 G4LogicalVolume* logVol = physVol->GetLogicalVolume();
491 int pvIndex = std::find(pvStore->begin(), pvStore->end(), physVol) - pvStore->begin();
492 unsigned long long pvID = (*m_PVID)[pvIndex];
493 unsigned int pvCount = (*m_PVCount)[pvIndex];
494 std::string pvName = (*m_PVName)[pvIndex];
495 int lvIndex = std::find(lvStore->begin(), lvStore->end(), logVol) - lvStore->begin();
496 unsigned long long lvID = (*m_LVID)[lvIndex];
497 unsigned int lvCount = (*m_LVCount)[lvIndex];
498 std::string lvName = (*m_LVName)[lvIndex];
499 for (
int daughter = 0; daughter < logVol->GetNoDaughters(); ++daughter) {
500 G4VPhysicalVolume* physVolDaughter = logVol->GetDaughter(daughter);
501 int pvIndexDaughter = std::find(pvStore->begin(), pvStore->end(), physVolDaughter) - pvStore->begin();
502 unsigned long long pvIDDaughter = (*m_PVID)[pvIndexDaughter];
503 unsigned int pvCountDaughter = (*m_PVCount)[pvIndexDaughter];
504 for (
int j = 0; j < physVolDaughter->GetMultiplicity(); ++j) {
506 if ((replica == 0) && (j == 0) && (lvCount == 0) && (pvCountDaughter == 0)) {
516 pvID + 0x00010000 * replica + pvCount);
524 G4VSolid* solid = logVol->GetSolid();
525 int solidIndex = std::find(solidStore->begin(), solidStore->end(), solid) - solidStore->begin();
526 unsigned long long solidID = (*m_SolidID)[solidIndex];
527 unsigned long long matID = (*m_MatID)[lvIndex];
528 std::string solidName = (*m_SolidName)[solidIndex];
529 if (physVol->IsReplicated()) {
531 pvName.append(std::to_string(replica));
537 physVol->GetReplicationData(axis, nReplicas, width, offset, consuming);
538 physVol->SetCopyNo(replica);
539 G4VPVParameterisation* physParameterisation = physVol->GetParameterisation();
540 if (physParameterisation) {
541 G4VSolid* solidReplica = physParameterisation->ComputeSolid(replica, physVol);
542 physParameterisation->ComputeTransformation(replica, physVol);
543 solidReplica->ComputeDimensions(physParameterisation, replica, physVol);
544 if (!(*solidReplica == *solid)) {
545 solidName.append(
"_R");
546 solidName.append(std::to_string(replica));
547 solidID += 0x00010000 * replica;
550 if ((replica == 0) && (lvCount == 0)) {
559 lvName.append(std::to_string(replica));
561 writeSolidToPV(pvName, solidName, (*
m_Visible)[lvIndex], matID, pvID + 0x00010000 * replica + pvCount, solidID);
563 writeSolidToLV(lvName, solidName, (*
m_Visible)[lvIndex], matID, lvID + 0x00010000 * replica + lvCount, solidID);
567 writeLVToPV(pvName, lvName, pvID + 0x00010000 * replica + pvCount, lvID + 0x00010000 * replica + lvCount);
570 if ((axis == kRho) && (solid->GetEntityType() ==
"G4Tubs")) {
571 solidName.append(
"_R");
572 solidName.append(std::to_string(replica));
573 solidID += 0x00010000 * replica;
575 if (
m_UsePrototypes && !((axis == kRho) && (solid->GetEntityType() ==
"G4Tubs"))) {
576 if ((replica == 0) && (lvCount == 0)) {
585 lvName.append(std::to_string(replica));
587 writeSolidToPV(pvName, solidName, (*
m_Visible)[lvIndex], matID, pvID + 0x00010000 * replica + pvCount, solidID);
589 writeSolidToLV(lvName, solidName, (*
m_Visible)[lvIndex], matID, lvID + 0x00010000 * replica + lvCount, solidID);
593 writeLVToPV(pvName, lvName, pvID + 0x00010000 * replica + pvCount, lvID + 0x00010000 * replica + lvCount);
613 (*m_LVCount)[lvIndex]++;
614 (*m_PVCount)[pvIndex]++;
620 std::time_t t = std::time(
nullptr);
621 struct tm* now = std::localtime(&t);
622 m_File <<
"; FBX 7.3.0 project file" << std::endl <<
623 "; Copyright (C) 1997-2010 Autodesk Inc. and/or its licensors." << std::endl <<
624 "; All rights reserved." << std::endl << std::endl <<
625 "FBXHeaderExtension: {" << std::endl <<
626 "\tFBXHeaderVersion: 1003" << std::endl <<
627 "\tFBXVersion: 7300" << std::endl <<
628 "\tCreationTime: \"" << std::put_time(now,
"%F %T") <<
":000\"" << std::endl <<
639 "\tCreator: \"FBX SDK/FBX Plugins version 2013.3\"" << std::endl <<
640 "\tSceneInfo: \"SceneInfo::GlobalInfo\", \"UserData\" {" << std::endl <<
641 "\t\tType: \"UserData\"" << std::endl <<
642 "\t\tVersion: 100" << std::endl <<
643 "\t\tMetaData: {" << std::endl <<
644 "\t\t\tVersion: 100" << std::endl <<
645 "\t\t\tTitle: \"Belle II Detector\"" << std::endl <<
646 "\t\t\tSubject: \"Detector Geometry Model\"" << std::endl <<
647 "\t\t\tAuthor: \"Belle II Collaboration\"" << std::endl <<
648 "\t\t\tKeywords: \"\"" << std::endl <<
649 "\t\t\tRevision: \"\"" << std::endl <<
650 "\t\t\tComment: \"\"" << std::endl <<
651 "\t\t}" << std::endl <<
652 "\t}" << std::endl <<
653 "}" << std::endl << std::endl;
655 m_File <<
"GlobalSettings: {" << std::endl <<
656 "\tVersion: 1000" << std::endl <<
657 "\tProperties70: {" << std::endl <<
658 "\t\tP: \"UpAxis\", \"int\", \"Integer\", \"\",1" << std::endl <<
659 "\t\tP: \"UpAxisSign\", \"int\", \"Integer\", \"\",1" << std::endl <<
660 "\t\tP: \"FrontAxis\", \"int\", \"Integer\", \"\",2" << std::endl <<
661 "\t\tP: \"FrontAxisSign\", \"int\", \"Integer\", \"\",1" << std::endl <<
662 "\t\tP: \"CoordAxis\", \"int\", \"Integer\", \"\",0" << std::endl <<
663 "\t\tP: \"CoordAxisSign\", \"int\", \"Integer\", \"\",1" << std::endl <<
664 "\t\tP: \"OriginalUpAxis\", \"int\", \"Integer\", \"\",1" << std::endl <<
665 "\t\tP: \"OriginalUpAxisSign\", \"int\", \"Integer\", \"\",1" << std::endl <<
666 "\t\tP: \"UnitScaleFactor\", \"double\", \"Number\", \"\",1" << std::endl <<
667 "\t\tP: \"OriginalUnitScaleFactor\", \"double\", \"Number\", \"\",1" << std::endl <<
668 "\t\tP: \"AmbientColor\", \"ColorRGB\", \"Color\", \"\",1,1,1" << std::endl <<
669 "\t\tP: \"DefaultCamera\", \"KString\", \"\", \"\", \"Producer Perspective\"" << std::endl <<
670 "\t\tP: \"TimeMode\", \"enum\", \"\", \"\",0" << std::endl <<
671 "\t\tP: \"TimeSpanStart\", \"KTime\", \"Time\", \"\",0" << std::endl <<
672 "\t\tP: \"TimeSpanStop\", \"KTime\", \"Time\", \"\",10" << std::endl <<
673 "\t\tP: \"CustomFrameRate\", \"double\", \"Number\", \"\",-1" << std::endl <<
674 "\t}" << std::endl <<
675 "}" << std::endl << std::endl;
677 m_File <<
"Documents: {" << std::endl <<
678 "\tCount: 1" << std::endl <<
679 "\tDocument: 4000000000, \"\", \"Scene\" {" << std::endl <<
680 "\t\tProperties70: {" << std::endl <<
681 "\t\t\tP: \"SourceObject\", \"object\", \"\", \"\"" << std::endl <<
682 "\t\t\tP: \"ActiveAnimStackName\", \"KString\", \"\", \"\", \"\"" << std::endl <<
683 "\t\t}" << std::endl <<
684 "\t\tRootNode: 0" << std::endl <<
685 "\t}" << std::endl <<
686 "}" << std::endl << std::endl;
688 m_File <<
"References: {" << std::endl <<
689 "}" << std::endl << std::endl;
691 m_File <<
"Definitions: {" << std::endl <<
692 "\tVersion: 100" << std::endl <<
693 "\tCount: 4" << std::endl <<
694 "\tObjectType: \"GlobalSettings\" {" << std::endl <<
695 "\t\tCount: 1" << std::endl <<
697 m_File <<
"\tObjectType: \"Model\" {" << std::endl <<
698 "\t\tCount: " << modelCount << std::endl <<
699 "\t\tPropertyTemplate: \"FbxNode\" {" << std::endl <<
700 "\t\t\tProperties70: {" << std::endl <<
701 "\t\t\t\tP: \"QuaternionInterpolate\", \"enum\", \"\", \"\",0" << std::endl <<
702 "\t\t\t\tP: \"RotationOffset\", \"Vector3D\", \"Vector\", \"\",0,0,0" << std::endl <<
703 "\t\t\t\tP: \"RotationPivot\", \"Vector3D\", \"Vector\", \"\",0,0,0" << std::endl <<
704 "\t\t\t\tP: \"ScalingOffset\", \"Vector3D\", \"Vector\", \"\",0,0,0" << std::endl <<
705 "\t\t\t\tP: \"ScalingPivot\", \"Vector3D\", \"Vector\", \"\",0,0,0" << std::endl <<
706 "\t\t\t\tP: \"TranslationActive\", \"bool\", \"\", \"\",0" << std::endl <<
707 "\t\t\t\tP: \"TranslationMin\", \"Vector3D\", \"Vector\", \"\",0,0,0" << std::endl <<
708 "\t\t\t\tP: \"TranslationMax\", \"Vector3D\", \"Vector\", \"\",0,0,0" << std::endl <<
709 "\t\t\t\tP: \"TranslationMinX\", \"bool\", \"\", \"\",0" << std::endl <<
710 "\t\t\t\tP: \"TranslationMinY\", \"bool\", \"\", \"\",0" << std::endl <<
711 "\t\t\t\tP: \"TranslationMinZ\", \"bool\", \"\", \"\",0" << std::endl <<
712 "\t\t\t\tP: \"TranslationMaxX\", \"bool\", \"\", \"\",0" << std::endl <<
713 "\t\t\t\tP: \"TranslationMaxY\", \"bool\", \"\", \"\",0" << std::endl <<
714 "\t\t\t\tP: \"TranslationMaxZ\", \"bool\", \"\", \"\",0" << std::endl <<
715 "\t\t\t\tP: \"RotationOrder\", \"enum\", \"\", \"\",0" << std::endl <<
716 "\t\t\t\tP: \"RotationSpaceForLimitOnly\", \"bool\", \"\", \"\",0" << std::endl <<
717 "\t\t\t\tP: \"RotationStiffnessX\", \"double\", \"Number\", \"\",0" << std::endl <<
718 "\t\t\t\tP: \"RotationStiffnessY\", \"double\", \"Number\", \"\",0" << std::endl <<
719 "\t\t\t\tP: \"RotationStiffnessZ\", \"double\", \"Number\", \"\",0" << std::endl <<
720 "\t\t\t\tP: \"AxisLen\", \"double\", \"Number\", \"\",10" << std::endl <<
721 "\t\t\t\tP: \"PreRotation\", \"Vector3D\", \"Vector\", \"\",0,0,0" << std::endl <<
722 "\t\t\t\tP: \"PostRotation\", \"Vector3D\", \"Vector\", \"\",0,0,0" << std::endl <<
723 "\t\t\t\tP: \"RotationActive\", \"bool\", \"\", \"\",0" << std::endl <<
724 "\t\t\t\tP: \"RotationMin\", \"Vector3D\", \"Vector\", \"\",0,0,0" << std::endl <<
725 "\t\t\t\tP: \"RotationMax\", \"Vector3D\", \"Vector\", \"\",0,0,0" << std::endl <<
726 "\t\t\t\tP: \"RotationMinX\", \"bool\", \"\", \"\",0" << std::endl <<
727 "\t\t\t\tP: \"RotationMinY\", \"bool\", \"\", \"\",0" << std::endl <<
728 "\t\t\t\tP: \"RotationMinZ\", \"bool\", \"\", \"\",0" << std::endl <<
729 "\t\t\t\tP: \"RotationMaxX\", \"bool\", \"\", \"\",0" << std::endl <<
730 "\t\t\t\tP: \"RotationMaxY\", \"bool\", \"\", \"\",0" << std::endl <<
731 "\t\t\t\tP: \"RotationMaxZ\", \"bool\", \"\", \"\",0" << std::endl <<
732 "\t\t\t\tP: \"InheritType\", \"enum\", \"\", \"\",0" << std::endl <<
733 "\t\t\t\tP: \"ScalingActive\", \"bool\", \"\", \"\",0" << std::endl <<
734 "\t\t\t\tP: \"ScalingMin\", \"Vector3D\", \"Vector\", \"\",0,0,0" << std::endl <<
735 "\t\t\t\tP: \"ScalingMax\", \"Vector3D\", \"Vector\", \"\",0,0,0" << std::endl <<
736 "\t\t\t\tP: \"ScalingMinX\", \"bool\", \"\", \"\",0" << std::endl <<
737 "\t\t\t\tP: \"ScalingMinY\", \"bool\", \"\", \"\",0" << std::endl <<
738 "\t\t\t\tP: \"ScalingMinZ\", \"bool\", \"\", \"\",0" << std::endl <<
739 "\t\t\t\tP: \"ScalingMaxX\", \"bool\", \"\", \"\",0" << std::endl <<
740 "\t\t\t\tP: \"ScalingMaxY\", \"bool\", \"\", \"\",0" << std::endl <<
741 "\t\t\t\tP: \"ScalingMaxZ\", \"bool\", \"\", \"\",0" << std::endl <<
742 "\t\t\t\tP: \"GeometricTranslation\", \"Vector3D\", \"Vector\", \"\",0,0,0" << std::endl <<
743 "\t\t\t\tP: \"GeometricRotation\", \"Vector3D\", \"Vector\", \"\",0,0,0" << std::endl <<
744 "\t\t\t\tP: \"GeometricScaling\", \"Vector3D\", \"Vector\", \"\",1,1,1" << std::endl <<
745 "\t\t\t\tP: \"MinDampRangeX\", \"double\", \"Number\", \"\",0" << std::endl <<
746 "\t\t\t\tP: \"MinDampRangeY\", \"double\", \"Number\", \"\",0" << std::endl <<
747 "\t\t\t\tP: \"MinDampRangeZ\", \"double\", \"Number\", \"\",0" << std::endl <<
748 "\t\t\t\tP: \"MaxDampRangeX\", \"double\", \"Number\", \"\",0" << std::endl <<
749 "\t\t\t\tP: \"MaxDampRangeY\", \"double\", \"Number\", \"\",0" << std::endl <<
750 "\t\t\t\tP: \"MaxDampRangeZ\", \"double\", \"Number\", \"\",0" << std::endl <<
751 "\t\t\t\tP: \"MinDampStrengthX\", \"double\", \"Number\", \"\",0" << std::endl <<
752 "\t\t\t\tP: \"MinDampStrengthY\", \"double\", \"Number\", \"\",0" << std::endl <<
753 "\t\t\t\tP: \"MinDampStrengthZ\", \"double\", \"Number\", \"\",0" << std::endl <<
754 "\t\t\t\tP: \"MaxDampStrengthX\", \"double\", \"Number\", \"\",0" << std::endl <<
755 "\t\t\t\tP: \"MaxDampStrengthY\", \"double\", \"Number\", \"\",0" << std::endl <<
756 "\t\t\t\tP: \"MaxDampStrengthZ\", \"double\", \"Number\", \"\",0" << std::endl <<
757 "\t\t\t\tP: \"PreferedAngleX\", \"double\", \"Number\", \"\",0" << std::endl <<
758 "\t\t\t\tP: \"PreferedAngleY\", \"double\", \"Number\", \"\",0" << std::endl <<
759 "\t\t\t\tP: \"PreferedAngleZ\", \"double\", \"Number\", \"\",0" << std::endl <<
760 "\t\t\t\tP: \"LookAtProperty\", \"object\", \"\", \"\"" << std::endl <<
761 "\t\t\t\tP: \"UpVectorProperty\", \"object\", \"\", \"\"" << std::endl <<
762 "\t\t\t\tP: \"Show\", \"bool\", \"\", \"\",1" << std::endl <<
763 "\t\t\t\tP: \"NegativePercentShapeSupport\", \"bool\", \"\", \"\",1" << std::endl <<
764 "\t\t\t\tP: \"DefaultAttributeIndex\", \"int\", \"Integer\", \"\",0" << std::endl <<
765 "\t\t\t\tP: \"Freeze\", \"bool\", \"\", \"\",0" << std::endl <<
766 "\t\t\t\tP: \"LODBox\", \"bool\", \"\", \"\",0" << std::endl <<
767 "\t\t\t\tP: \"Lcl Translation\", \"Lcl Translation\", \"\", \"A\",0,0,0" << std::endl <<
768 "\t\t\t\tP: \"Lcl Rotation\", \"Lcl Rotation\", \"\", \"A\",0,0,0" << std::endl <<
769 "\t\t\t\tP: \"Lcl Scaling\", \"Lcl Scaling\", \"\", \"A\",1,1,1" << std::endl <<
770 "\t\t\t\tP: \"Visibility\", \"Visibility\", \"\", \"A\",1" << std::endl <<
771 "\t\t\t\tP: \"Visibility Inheritance\", \"Visibility Inheritance\", \"\", \"\",1" << std::endl <<
772 "\t\t\t}" << std::endl <<
773 "\t\t}" << std::endl <<
775 m_File <<
"\tObjectType: \"Material\" {" << std::endl <<
776 "\t\tCount: " << materialCount << std::endl <<
777 "\t\tPropertyTemplate: \"FbxSurfacePhong\" {" << std::endl <<
778 "\t\t\tProperties70: {" << std::endl <<
779 "\t\t\t\tP: \"ShadingModel\", \"KString\", \"\", \"\", \"Phong\"" << std::endl <<
780 "\t\t\t\tP: \"MultiLayer\", \"bool\", \"\", \"\",0" << std::endl <<
781 "\t\t\t\tP: \"EmissiveColor\", \"ColorRGB\", \"Color\", \"A\",0,0,0" << std::endl <<
782 "\t\t\t\tP: \"EmissiveFactor\", \"double\", \"Number\", \"A\",0" << std::endl <<
783 "\t\t\t\tP: \"AmbientColor\", \"ColorRGB\", \"Color\", \"A\",0,0,0" << std::endl <<
784 "\t\t\t\tP: \"AmbientFactor\", \"double\", \"Number\", \"A\",0" << std::endl <<
785 "\t\t\t\tP: \"DiffuseColor\", \"ColorRGB\", \"Color\", \"A\",0,0,0" << std::endl <<
786 "\t\t\t\tP: \"DiffuseFactor\", \"double\", \"Number\", \"A\",1" << std::endl <<
787 "\t\t\t\tP: \"Bump\", \"Vector3D\", \"Vector\", \"\",0,0,0" << std::endl <<
788 "\t\t\t\tP: \"NormalMap\", \"Vector3D\", \"Vector\", \"\",0,0,0" << std::endl <<
789 "\t\t\t\tP: \"BumpFactor\", \"double\", \"Number\", \"\",1" << std::endl <<
790 "\t\t\t\tP: \"TransparentColor\", \"ColorRGB\", \"Color\", \"A\",0,0,0" << std::endl <<
791 "\t\t\t\tP: \"TransparencyFactor\", \"double\", \"Number\", \"A\",0" << std::endl <<
792 "\t\t\t\tP: \"DisplacementColor\", \"ColorRGB\", \"Color\", \"\",0,0,0" << std::endl <<
793 "\t\t\t\tP: \"DisplacementFactor\", \"double\", \"Number\", \"\",1" << std::endl <<
794 "\t\t\t\tP: \"VectorDisplacementColor\", \"ColorRGB\", \"Color\", \"\",0,0,0" << std::endl <<
795 "\t\t\t\tP: \"VectorDisplacementFactor\", \"double\", \"Number\", \"\",1" << std::endl <<
796 "\t\t\t\tP: \"SpecularColor\", \"ColorRGB\", \"Color\", \"A\",0,0,0" << std::endl <<
797 "\t\t\t\tP: \"SpecularFactor\", \"double\", \"Number\", \"A\",0" << std::endl <<
798 "\t\t\t\tP: \"ShininessExponent\", \"double\", \"Number\", \"A\",20" << std::endl <<
799 "\t\t\t\tP: \"ReflectionColor\", \"ColorRGB\", \"Color\", \"A\",0,0,0" << std::endl <<
800 "\t\t\t\tP: \"ReflectionFactor\", \"double\", \"Number\", \"A\",0" << std::endl <<
801 "\t\t\t}" << std::endl <<
802 "\t\t}" << std::endl <<
830 m_File <<
"\tObjectType: \"Geometry\" {" << std::endl <<
831 "\t\tCount: " << geometryCount << std::endl <<
832 "\t\tPropertyTemplate: \"FbxMesh\" {" << std::endl <<
833 "\t\t\tProperties70: {" << std::endl <<
834 "\t\t\t\tP: \"Color\", \"ColorRGB\", \"Color\", \"\",1,1,1" << std::endl <<
835 "\t\t\t\tP: \"BBoxMin\", \"Vector3D\", \"Vector\", \"\",0,0,0" << std::endl <<
836 "\t\t\t\tP: \"BBoxMax\", \"Vector3D\", \"Vector\", \"\",0,0,0" << std::endl <<
837 "\t\t\t\tP: \"Primary Visibility\", \"bool\", \"\", \"\",1" << std::endl <<
838 "\t\t\t\tP: \"Casts Shadows\", \"bool\", \"\", \"\",0" << std::endl <<
839 "\t\t\t\tP: \"Receive Shadows\", \"bool\", \"\", \"\",0" << std::endl <<
840 "\t\t\t}" << std::endl <<
841 "\t\t}" << std::endl <<
842 "\t}" << std::endl <<
843 "}" << std::endl << std::endl;
848 unsigned long long solidID)
851 polyhedron->SetNumberOfRotationSteps(120);
852 m_File <<
"\t; Solid " << solid->GetName() <<
" of type " << solid->GetEntityType() << std::endl <<
853 "\tGeometry: " << solidID <<
", \"Geometry::" << name << R
"(", "Mesh" {)" << std::endl <<
854 "\t\tVertices: *" << polyhedron->GetNoVertices() * 3 <<
" {" << std::endl <<
"\t\t\ta: ";
855 std::streampos startOfLine =
m_File.tellp();
856 for (
int j = 1; j <= polyhedron->GetNoVertices(); ++j) {
857 m_File << (j == 1 ?
"" :
",") <<
858 polyhedron->GetVertex(j).x() <<
"," <<
859 polyhedron->GetVertex(j).y() <<
"," <<
860 polyhedron->GetVertex(j).z();
861 if (
m_File.tellp() - startOfLine > 100) {
862 startOfLine =
m_File.tellp();
863 m_File << std::endl <<
"\t\t\t\t";
866 m_File << std::endl <<
"\t\t}" << std::endl;
868 std::vector<int> vertices;
869 for (
int k = 1; k <= polyhedron->GetNoFacets(); ++k) {
870 G4bool notLastEdge =
true;
871 G4int ndx = -1, edgeFlag = 1;
873 notLastEdge = polyhedron->GetNextVertexIndex(ndx, edgeFlag);
875 vertices.push_back(ndx - 1);
877 vertices.push_back(-ndx);
879 }
while (notLastEdge);
881 m_File <<
"\t\tPolygonVertexIndex: *" << vertices.size() <<
" {" << std::endl <<
"\t\t\ta: ";
882 startOfLine =
m_File.tellp();
883 for (
unsigned int j = 0; j < vertices.size(); ++j) {
884 m_File << (j == 0 ?
"" :
",") << vertices[j];
885 if (
m_File.tellp() - startOfLine > 100) {
886 startOfLine =
m_File.tellp();
887 m_File << std::endl <<
"\t\t\t\t";
890 m_File << std::endl <<
"\t\t}" << std::endl;
892 m_File <<
"\t\tGeometryVersion: 124" << std::endl <<
893 "\t\tLayerElementNormal: 0 {" << std::endl <<
894 "\t\t\tVersion: 101" << std::endl <<
896 "\t\t\tMappingInformationType: \"ByPolygonVertex\"" << std::endl <<
897 "\t\t\tReferenceInformationType: \"Direct\"" << std::endl <<
898 "\t\t\tNormals: *" << vertices.size() * 3 <<
" {" << std::endl <<
"\t\t\t\ta: ";
899 startOfLine =
m_File.tellp();
901 for (
int k = 1; k <= polyhedron->GetNoFacets(); ++k) {
902 G4Normal3D normal = polyhedron->GetUnitNormal(k);
904 m_File << (j == 0 ?
"" :
",") << normal.x() <<
"," << normal.y() <<
"," << normal.z();
905 if (
m_File.tellp() - startOfLine > 100) {
906 startOfLine =
m_File.tellp();
907 m_File << std::endl <<
"\t\t\t\t";
909 }
while (vertices[j++] >= 0);
911 m_File << std::endl <<
"\t\t\t}" << std::endl <<
"\t\t}" << std::endl <<
912 "\t\tLayerElementMaterial: 0 {" << std::endl <<
913 "\t\t\tVersion: 101" << std::endl <<
915 "\t\t\tMappingInformationType: \"AllSame\"" << std::endl <<
916 "\t\t\tReferenceInformationType: \"IndexToDirect\"" << std::endl <<
917 "\t\t\tMaterials: *1 {" << std::endl <<
918 "\t\t\t\ta: 0" << std::endl <<
919 "\t\t\t}" << std::endl <<
920 "\t\t}" << std::endl <<
921 "\t\tLayer: 0 {" << std::endl <<
922 "\t\t\tVersion: 100" << std::endl <<
923 "\t\t\tLayerElement: {" << std::endl <<
924 "\t\t\t\tType: \"LayerElementNormal\"" << std::endl <<
925 "\t\t\t\tTypedIndex: 0" << std::endl <<
926 "\t\t\t}" << std::endl <<
927 "\t\t\tLayerElement: {" << std::endl <<
928 "\t\t\t\tType: \"LayerElementMaterial\"" << std::endl <<
929 "\t\t\t\tTypedIndex: 0" << std::endl <<
930 "\t\t\t}" << std::endl <<
931 "\t\t}" << std::endl <<
934 B2INFO(
"Polyhedron representation of solid " << name <<
" cannot be created");
940 G4RotationMatrix* rot = physVol->GetObjectRotation();
941 G4ThreeVector move = physVol->GetObjectTranslation();
943 double yaw = std::atan2(rot->yx(), rot->xx()) * 180.0 / M_PI;
944 if (fabs(yaw) < 1.0E-12) yaw = 0.0;
945 double pitch = -std::asin(rot->zx()) * 180.0 / M_PI;
946 if (fabs(pitch) < 1.0E-12) pitch = 0.0;
947 double roll = std::atan2(rot->zy(), rot->zz()) * 180.0 / M_PI;
948 if (fabs(roll) < 1.0E-12) roll = 0.0;
949 m_File <<
"\t; PhysVol " << physVol->GetName();
950 if (physVol->IsReplicated()) {
951 m_File <<
" (replicated: copy " << physVol->GetCopyNo() <<
")";
953 m_File <<
", placing LogVol " << physVol->GetLogicalVolume()->GetName() << std::endl <<
954 "\tModel: " << pvID <<
", \"Model::" << pvName << R
"(", "Null" {)" << std::endl <<
955 "\t\tVersion: 232" << std::endl <<
956 "\t\tProperties70: {" << std::endl <<
957 "\t\t\tP: \"Lcl Translation\", \"Lcl Translation\", \"\", \"A\"," <<
958 move.x() <<
"," << move.y() <<
"," << move.z() << std::endl <<
959 "\t\t\tP: \"Lcl Rotation\", \"Lcl Rotation\", \"\", \"A\"," <<
960 roll <<
"," << pitch <<
"," << yaw << std::endl <<
961 "\t\t}" << std::endl <<
962 "\t\tShading: T" << std::endl <<
963 "\t\tCulling: \"CullingOff\"" << std::endl <<
968 unsigned long long matID,
unsigned long long lvID,
unsigned long long solidID)
970 m_File <<
"\t; Solid Geometry::" << solidName <<
", LogVol Model::lv_" << lvName << std::endl <<
971 "\t" << (visible ?
"" :
"; ") <<
"C: \"OO\"," << solidID <<
"," << lvID << std::endl << std::endl <<
972 "\t; Color Material::" << lvName <<
", LogVol Model::lv_" << lvName << std::endl <<
973 "\t" << (visible ?
"" :
"; ") <<
"C: \"OO\"," << matID <<
"," << lvID << std::endl << std::endl;
977 unsigned long long matID,
unsigned long long pvID,
unsigned long long solidID)
979 m_File <<
"\t; Solid Geometry::" << solidName <<
", PhysVol Model::" << pvName << std::endl <<
980 "\t" << (visible ?
"" :
"; ") <<
"C: \"OO\"," << solidID <<
"," << pvID << std::endl << std::endl <<
981 "\t; Color Material::" << pvName <<
", PhysVol Model::" << pvName << std::endl <<
982 "\t" << (visible ?
"" :
"; ") <<
"C: \"OO\"," << matID <<
"," << pvID << std::endl << std::endl;
986 unsigned long long lvID)
988 m_File <<
"\t; LogVol Model::lv_" << lvName <<
", PhysVol Model::" << pvName << std::endl <<
989 "\tC: \"OO\"," << lvID <<
"," << pvID << std::endl << std::endl;
993 unsigned long long pvIDDaughter,
unsigned long long lvID)
995 m_File <<
"\t; PhysVol Model::" << pvNameDaughter <<
", parent LogVol Model::lv_" << lvName << std::endl <<
996 "\tC: \"OO\"," << pvIDDaughter <<
"," << lvID << std::endl << std::endl;
1000 unsigned long long pvIDDaughter,
unsigned long long pvID)
1002 m_File <<
"\t; PhysVol Model::" << pvNameDaughter <<
", parent PhysVol Model::" << pvName << std::endl <<
1003 "\tC: \"OO\"," << pvIDDaughter <<
"," << pvID << std::endl << std::endl;
1010 G4VSolid* solidA = solid->GetConstituentSolid(0);
1011 G4VSolid* solidB = solid->GetConstituentSolid(1);
1012 HepPolyhedron* polyhedronA =
nullptr;
1013 if ((solidA->GetEntityType() ==
"G4IntersectionSolid") ||
1014 (solidA->GetEntityType() ==
"G4UnionSolid") ||
1015 (solidA->GetEntityType() ==
"G4SubtractionSolid") ||
1016 (solidA->GetEntityType() ==
"G4BooleanSolid")) {
1019 polyhedronA =
new HepPolyhedron(*(solidA->GetPolyhedron()));
1021 HepPolyhedron* polyhedronB =
nullptr;
1022 G4VSolid* solidB2 = solidB;
1023 if (solidB->GetEntityType() ==
"G4DisplacedSolid") {
1024 solidB2 = ((G4DisplacedSolid*)solidB)->GetConstituentMovedSolid();
1026 if ((solidB2->GetEntityType() ==
"G4IntersectionSolid") ||
1027 (solidB2->GetEntityType() ==
"G4UnionSolid") ||
1028 (solidB2->GetEntityType() ==
"G4SubtractionSolid") ||
1029 (solidB2->GetEntityType() ==
"G4BooleanSolid")) {
1031 if (solidB != solidB2) {
1032 polyhedronB->Transform(G4Transform3D(
1033 ((G4DisplacedSolid*)solidB)->GetObjectRotation(),
1034 ((G4DisplacedSolid*)solidB)->GetObjectTranslation()));
1037 polyhedronB =
new HepPolyhedron(*(solidB->GetPolyhedron()));
1039 auto* result =
new HepPolyhedron();
1040 if (solid->GetEntityType() ==
"G4UnionSolid") {
1041 *result = polyhedronA->add(*polyhedronB);
1042 }
else if (solid->GetEntityType() ==
"G4SubtractionSolid") {
1043 *result = polyhedronA->subtract(*polyhedronB);
1044 }
else if (solid->GetEntityType() ==
"G4IntersectionSolid") {
1045 *result = polyhedronA->intersect(*polyhedronB);
1047 B2WARNING(
"getBooleanSolidPolyhedron(): Unrecognized boolean solid " << solid->GetName() <<
1048 " of type " << solid->GetEntityType());