9#include <geometry/modules/fbxWriter/FBXWriterModule.h>
10#include <geometry/GeometryManager.h>
12#include "G4PhysicalVolumeStore.hh"
13#include "G4LogicalVolumeStore.hh"
14#include "G4SolidStore.hh"
15#include "G4VPhysicalVolume.hh"
16#include "G4LogicalVolume.hh"
18#include "G4DisplacedSolid.hh"
19#include "G4Material.hh"
20#include "G4VisAttributes.hh"
21#include "G4ThreeVector.hh"
22#include "G4RotationMatrix.hh"
23#include "G4Transform3D.hh"
24#include "G4VPVParameterisation.hh"
26#include <G4Polyhedron.hh>
37 setDescription(
"Write the detector geometry in a (semi-)hierarchical FBX format.");
57 B2ERROR(
"No geometry found: add the Geometry module to the path before the FBXWriter module.");
61 G4PhysicalVolumeStore* pvStore = G4PhysicalVolumeStore::GetInstance();
62 G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance();
63 G4SolidStore* solidStore = G4SolidStore::GetInstance();
66 m_PVName =
new std::vector<std::string>(pvStore->size(),
"");
67 m_LVName =
new std::vector<std::string>(lvStore->size(),
"");
68 m_SolidName =
new std::vector<std::string>(solidStore->size(),
"");
69 for (G4VPhysicalVolume* physVol : *pvStore) {
70 int pvIndex = std::find(pvStore->begin(), pvStore->end(), physVol) - pvStore->begin();
71 if ((*
m_PVName)[pvIndex].length() == 0) {
73 G4LogicalVolume* logVol = physVol->GetLogicalVolume();
74 int lvIndex = std::find(lvStore->begin(), lvStore->end(), logVol) - lvStore->begin();
75 if ((*
m_LVName)[lvIndex].length() == 0) {
77 G4VSolid* solid = logVol->GetSolid();
78 int solidIndex = std::find(solidStore->begin(), solidStore->end(), solid) - solidStore->begin();
88 m_PVCount =
new std::vector<unsigned int>(pvStore->size(), 0);
89 m_LVCount =
new std::vector<unsigned int>(lvStore->size(), 0);
90 m_SolidCount =
new std::vector<unsigned int>(solidStore->size(), 0);
91 m_PVReplicas =
new std::vector<unsigned int>(pvStore->size(), 0);
92 m_LVReplicas =
new std::vector<unsigned int>(lvStore->size(), 0);
94 m_LVUnique =
new std::vector<bool>(lvStore->size(),
true);
96 unsigned int geometryCount = 0;
97 unsigned int materialCount = 0;
98 unsigned int modelCount = 0;
99 for (
unsigned int pvIndex = 0; pvIndex < pvStore->size(); ++pvIndex) {
100 if ((*
m_PVName)[pvIndex].length() > 0) {
101 modelCount += (*m_PVCount)[pvIndex] + (*m_PVReplicas)[pvIndex];
104 for (
unsigned int lvIndex = 0; lvIndex < lvStore->size(); ++lvIndex) {
105 if ((*
m_LVName)[lvIndex].length() > 0) {
107 modelCount += (*m_LVCount)[lvIndex] + (*m_LVReplicas)[lvIndex];
112 for (
unsigned int solidIndex = 0; solidIndex < solidStore->size(); ++solidIndex) {
114 geometryCount += (*m_SolidCount)[solidIndex] + (*m_SolidReplicas)[solidIndex] + 1;
124 m_PVID =
new std::vector<unsigned long long>(pvStore->size(), 0x0000010000000000LL);
125 m_LVID =
new std::vector<unsigned long long>(lvStore->size(), 0x000000C000000000LL);
126 m_SolidID =
new std::vector<unsigned long long>(solidStore->size(), 0x0000008000000000LL);
127 m_MatID =
new std::vector<unsigned long long>(lvStore->size(), 0x0000004000000000LL);
128 m_Visible =
new std::vector<bool>(lvStore->size(),
false);
129 m_File <<
"Objects: {" << std::endl;
130 for (
unsigned int solidIndex = 0; solidIndex < solidStore->size(); ++solidIndex) {
131 (*m_SolidID)[solidIndex] += 0x0000000001000000LL * solidIndex;
133 for (
unsigned int solidCount = 0; solidCount <= (*m_SolidCount)[solidIndex]; ++solidCount) {
138 for (
unsigned int lvIndex = 0; lvIndex < lvStore->size(); ++lvIndex) {
139 (*m_MatID)[lvIndex] += 0x0000000001000000LL * lvIndex;
140 (*m_LVID)[lvIndex] += 0x0000000001000000LL * lvIndex;
141 if ((*
m_LVName)[lvIndex].length() > 0) {
145 for (
unsigned int pvIndex = 0; pvIndex < pvStore->size(); ++pvIndex) {
146 (*m_PVID)[pvIndex] += 0x0000000001000000LL * pvIndex;
152 m_File <<
"}" << std::endl << std::endl;
158 m_File <<
"Connections: {" << std::endl;
160 int pvIndex = std::find(pvStore->begin(), pvStore->end(), topVol) - pvStore->begin();
161 m_File <<
"\t; Physical volume Model::" << (*m_PVName)[pvIndex] <<
" to Model::RootNode" << std::endl <<
162 "\tC: \"OO\"," << (*m_PVID)[pvIndex] <<
",0" << std::endl << std::endl <<
163 "}" << std::endl << std::endl;
165 m_File <<
"Takes: {" << std::endl <<
166 "\tCurrent: \"\"" << std::endl <<
188 G4PhysicalVolumeStore* pvStore = G4PhysicalVolumeStore::GetInstance();
189 G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance();
190 G4SolidStore* solidStore = G4SolidStore::GetInstance();
192 G4String name = originalName;
193 if (name.length() == 0) { name =
"anonymous"; }
195 for (
char c :
" .,:;?'\"*+-=|^!/@#$\\%{}[]()<>") std::replace(name.begin(), name.end(), c,
'_');
197 for (
int j = (
int)index - 1; j >= 0; --j) {
198 if ((*names)[j].length() == 0)
continue;
202 match = (*pvStore)[j]->GetName().compare((*pvStore)[index]->GetName());
break;
204 match = (*lvStore)[j]->GetName().compare((*lvStore)[index]->GetName());
break;
206 match = (*solidStore)[j]->GetName().compare((*solidStore)[index]->GetName());
break;
209 if (name.length() == (*names)[j].length()) {
210 (*names)[j].append(
"_1");
212 int n = std::stoi((*names)[j].substr(name.length() + 1),
nullptr);
214 name.append(std::to_string(n + 1));
218 (*names)[index] = name;
223 if ((solid->GetEntityType() ==
"G4IntersectionSolid") ||
224 (solid->GetEntityType() ==
"G4UnionSolid") ||
225 (solid->GetEntityType() ==
"G4SubtractionSolid") ||
226 (solid->GetEntityType() ==
"G4BooleanSolid")) {
228 auto* g4polyhedron =
new G4Polyhedron(*polyhedron);
239 G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance();
240 G4LogicalVolume* logVol = (*lvStore)[lvIndex];
241 unsigned long long matID = (*m_MatID)[lvIndex];
242 G4Color color(0.0, 1.0, 0.0, 0.5);
243 if ((matName.compare(0, 23,
"eclBarrelCrystalLogical") == 0) ||
244 (matName.compare(0, 20,
"eclFwdCrystalLogical") == 0) ||
245 (matName.compare(0, 20,
"eclBwdCrystalLogical") == 0) ||
246 (matName.compare(0, 24,
"eclBarrelCrystalPhysical") == 0) ||
247 (matName.compare(0, 21,
"eclFwdCrystalPhysical") == 0) ||
248 (matName.compare(0, 21,
"eclBwdCrystalPhysical") == 0)) {
249 color = G4Color(1.0, 0.25, 0.0, 0.7);
252 G4String materialName = logVol->GetMaterial()->GetName();
254 if (materialName ==
"Vacuum") visible =
false;
255 if (materialName ==
"G4_AIR") visible =
false;
256 if (materialName ==
"CDCGas") visible =
false;
257 if (materialName ==
"ColdAir") visible =
false;
258 if (materialName ==
"STR-DryAir") visible =
false;
259 if (materialName ==
"TOPAir") visible =
false;
260 if (materialName ==
"TOPVacuum") visible =
false;
261 const G4VisAttributes* visAttr = logVol->GetVisAttributes();
263 color =
const_cast<G4Color&
>(logVol->GetVisAttributes()->GetColor());
264 if (!(visAttr->IsVisible())) visible =
false;
268 if (logVol->GetSensitiveDetector() !=
nullptr) visible =
"";
269 (*m_Visible)[lvIndex] = visible;
270 m_File <<
"\t; Color for LogVol " << logVol->GetName() << std::endl <<
271 "\tMaterial: " << matID <<
", \"Material::" << matName << R
"(", "" {)" << std::endl <<
272 "\t\tVersion: 102" << std::endl <<
273 "\t\tProperties70: {" << std::endl <<
274 "\t\t\tP: \"ShadingModel\", \"KString\", \"\", \"\", \"phong\"" << std::endl <<
275 "\t\t\tP: \"DiffuseColor\", \"RGBColor\", \"Color\", \"A\"," <<
276 color.GetRed() <<
"," << color.GetGreen() <<
"," << color.GetBlue() << std::endl <<
277 "\t\t\tP: \"TransparentColor\", \"RGBColor\", \"Color\", \"A\",1,1,1" << std::endl <<
278 "\t\t\tP: \"TransparencyFactor\", \"double\", \"Number\", \"\"," << (visible ? 1.0 - color.GetAlpha() : 1) << std::endl <<
279 "\t\t}" << std::endl <<
285 m_File <<
"\t; LogVol " << logVol->GetName() <<
" with solid " << logVol->GetSolid()->GetName() << std::endl <<
286 "\tModel: " << lvID <<
", \"Model::lv_" << lvName << R
"(", "Null" {)" << std::endl <<
287 "\t\tVersion: 232" << std::endl <<
288 "\t\tProperties70: {" << std::endl <<
289 "\t\t}" << std::endl <<
290 "\t\tShading: T" << std::endl <<
291 "\t\tCulling: \"CullingOff\"" << std::endl <<
298 G4LogicalVolume* logVol = physVol->GetLogicalVolume();
299 for (
size_t daughter = 0; daughter < logVol->GetNoDaughters(); ++daughter) {
300 G4VPhysicalVolume* physVolDaughter = logVol->GetDaughter(daughter);
301 for (
int j = 0; j < physVolDaughter->GetMultiplicity(); ++j) {
307 G4PhysicalVolumeStore* pvStore = G4PhysicalVolumeStore::GetInstance();
308 G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance();
309 int pvIndex = std::find(pvStore->begin(), pvStore->end(), physVol) - pvStore->begin();
310 unsigned long long pvID = (*m_PVID)[pvIndex];
311 unsigned int pvCount = (*m_PVCount)[pvIndex];
312 std::string pvName = (*m_PVName)[pvIndex];
313 int lvIndex = std::find(lvStore->begin(), lvStore->end(), logVol) - lvStore->begin();
314 unsigned long long lvID = (*m_LVID)[lvIndex];
315 unsigned int lvCount = (*m_LVCount)[lvIndex];
316 std::string lvName = (*m_LVName)[lvIndex];
318 if (physVol->IsReplicated()) {
319 G4VSolid* solid = logVol->GetSolid();
320 G4SolidStore* solidStore = G4SolidStore::GetInstance();
321 int solidIndex = std::find(solidStore->begin(), solidStore->end(), solid) - solidStore->begin();
322 unsigned long long solidID = (*m_SolidID)[solidIndex];
328 physVol->GetReplicationData(axis, nReplicas, width, offset, consuming);
329 physVol->SetCopyNo(replica);
330 G4VPVParameterisation* physParameterisation = physVol->GetParameterisation();
331 if (physParameterisation) {
332 G4VSolid* solidReplica = physParameterisation->ComputeSolid(replica, physVol);
333 physParameterisation->ComputeTransformation(replica, physVol);
334 solidReplica->ComputeDimensions(physParameterisation, replica, physVol);
335 if (!(*solidReplica == *solid)) {
336 std::string solidName = (*m_SolidName)[solidIndex];
337 solidName.append(
"_R");
338 solidName.append(std::to_string(replica));
342 if ((replica == 0) && (lvCount == 0)) {
351 pvName.append(std::to_string(replica));
354 G4RotationMatrix* originalRotation = physVol->GetRotation();
355 G4ThreeVector translation;
356 G4RotationMatrix rotation;
360 translation.setX(width * (replica - 0.5 * (nReplicas - 1)));
361 physVol->SetTranslation(translation);
364 translation.setY(width * (replica - 0.5 * (nReplicas - 1)));
365 physVol->SetTranslation(translation);
368 translation.setZ(width * (replica - 0.5 * (nReplicas - 1)));
369 physVol->SetTranslation(translation);
372 if (solid->GetEntityType() ==
"G4Tubs") {
373 double originalRMin = ((G4Tubs*)solid)->GetInnerRadius();
374 double originalRMax = ((G4Tubs*)solid)->GetOuterRadius();
375 ((G4Tubs*)solid)->SetInnerRadius(offset + width * replica);
376 ((G4Tubs*)solid)->SetOuterRadius(offset + width * (replica + 1));
377 std::string solidName = (*m_SolidName)[solidIndex];
378 solidName.append(
"_R");
379 solidName.append(std::to_string(replica));
381 ((G4Tubs*)solid)->SetInnerRadius(originalRMin);
382 ((G4Tubs*)solid)->SetOuterRadius(originalRMax);
383 }
else if (replica == 0) {
384 B2WARNING(
"Built-in volumes replicated along radius for " << solid->GetEntityType() <<
385 " (solid " << solid->GetName() <<
") are not visualisable.");
389 physVol->SetRotation(&(rotation.rotateZ(-(offset + (replica + 0.5) * width))));
392 if (
m_UsePrototypes && !((axis == kRho) && (solid->GetEntityType() ==
"G4Tubs"))) {
393 if ((replica == 0) && (lvCount == 0)) {
402 pvName.append(std::to_string(replica));
404 if (axis == kPhi) physVol->SetRotation(originalRotation);
416 (*m_LVCount)[lvIndex]++;
417 (*m_PVCount)[pvIndex]++;
424 G4LogicalVolume* logVol = physVol->GetLogicalVolume();
425 for (
size_t daughter = 0; daughter < logVol->GetNoDaughters(); ++daughter) {
426 G4VPhysicalVolume* physVolDaughter = logVol->GetDaughter(daughter);
427 for (
int j = 0; j < physVolDaughter->GetMultiplicity(); ++j) {
433 G4PhysicalVolumeStore* pvStore = G4PhysicalVolumeStore::GetInstance();
434 G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance();
435 G4SolidStore* solidStore = G4SolidStore::GetInstance();
436 G4VSolid* solid = logVol->GetSolid();
437 int pvIndex = std::find(pvStore->begin(), pvStore->end(), physVol) - pvStore->begin();
438 int lvIndex = std::find(lvStore->begin(), lvStore->end(), logVol) - lvStore->begin();
439 int solidIndex = std::find(solidStore->begin(), solidStore->end(), solid) - solidStore->begin();
440 if (physVol->IsReplicated()) {
446 physVol->GetReplicationData(axis, nReplicas, width, offset, consuming);
447 G4VPVParameterisation* physParameterisation = physVol->GetParameterisation();
448 if (physParameterisation) {
449 G4VSolid* solidReplica = physParameterisation->ComputeSolid(0, physVol);
450 physParameterisation->ComputeTransformation(0, physVol);
451 solidReplica->ComputeDimensions(physParameterisation, 0, physVol);
452 if (!(*solidReplica == *solid))(*m_SolidReplicas)[solidIndex]++;
454 if ((*
m_LVReplicas)[lvIndex] > 0)(*m_LVUnique)[lvIndex] =
false;
455 (*m_LVReplicas)[lvIndex] = 1;
457 (*m_LVReplicas)[lvIndex]++;
459 (*m_PVReplicas)[pvIndex]++;
461 if ((axis == kRho) && (solid->GetEntityType() ==
"G4Tubs"))(*m_SolidReplicas)[solidIndex]++;
462 if (
m_UsePrototypes && !((axis == kRho) && (solid->GetEntityType() ==
"G4Tubs"))) {
463 (*m_LVReplicas)[lvIndex] = 1;
465 (*m_LVReplicas)[lvIndex]++;
467 (*m_PVReplicas)[pvIndex]++;
470 if ((*
m_LVCount)[lvIndex] > 0)(*m_LVUnique)[lvIndex] =
false;
472 (*m_PVCount)[pvIndex] = 1;
473 (*m_LVCount)[lvIndex] = 1;
475 (*m_PVCount)[pvIndex]++;
476 (*m_LVCount)[lvIndex]++;
485 G4PhysicalVolumeStore* pvStore = G4PhysicalVolumeStore::GetInstance();
486 G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance();
487 G4SolidStore* solidStore = G4SolidStore::GetInstance();
488 G4LogicalVolume* logVol = physVol->GetLogicalVolume();
489 int pvIndex = std::find(pvStore->begin(), pvStore->end(), physVol) - pvStore->begin();
490 unsigned long long pvID = (*m_PVID)[pvIndex];
491 unsigned int pvCount = (*m_PVCount)[pvIndex];
492 std::string pvName = (*m_PVName)[pvIndex];
493 int lvIndex = std::find(lvStore->begin(), lvStore->end(), logVol) - lvStore->begin();
494 unsigned long long lvID = (*m_LVID)[lvIndex];
495 unsigned int lvCount = (*m_LVCount)[lvIndex];
496 std::string lvName = (*m_LVName)[lvIndex];
497 for (
size_t daughter = 0; daughter < logVol->GetNoDaughters(); ++daughter) {
498 G4VPhysicalVolume* physVolDaughter = logVol->GetDaughter(daughter);
499 int pvIndexDaughter = std::find(pvStore->begin(), pvStore->end(), physVolDaughter) - pvStore->begin();
500 unsigned long long pvIDDaughter = (*m_PVID)[pvIndexDaughter];
501 unsigned int pvCountDaughter = (*m_PVCount)[pvIndexDaughter];
502 for (
int j = 0; j < physVolDaughter->GetMultiplicity(); ++j) {
504 if ((replica == 0) && (j == 0) && (lvCount == 0) && (pvCountDaughter == 0)) {
514 pvID + 0x00010000 * replica + pvCount);
522 G4VSolid* solid = logVol->GetSolid();
523 int solidIndex = std::find(solidStore->begin(), solidStore->end(), solid) - solidStore->begin();
524 unsigned long long solidID = (*m_SolidID)[solidIndex];
525 unsigned long long matID = (*m_MatID)[lvIndex];
526 std::string solidName = (*m_SolidName)[solidIndex];
527 if (physVol->IsReplicated()) {
529 pvName.append(std::to_string(replica));
535 physVol->GetReplicationData(axis, nReplicas, width, offset, consuming);
536 physVol->SetCopyNo(replica);
537 G4VPVParameterisation* physParameterisation = physVol->GetParameterisation();
538 if (physParameterisation) {
539 G4VSolid* solidReplica = physParameterisation->ComputeSolid(replica, physVol);
540 physParameterisation->ComputeTransformation(replica, physVol);
541 solidReplica->ComputeDimensions(physParameterisation, replica, physVol);
542 if (!(*solidReplica == *solid)) {
543 solidName.append(
"_R");
544 solidName.append(std::to_string(replica));
545 solidID += 0x00010000 * replica;
548 if ((replica == 0) && (lvCount == 0)) {
557 lvName.append(std::to_string(replica));
559 writeSolidToPV(pvName, solidName, (*
m_Visible)[lvIndex], matID, pvID + 0x00010000 * replica + pvCount, solidID);
561 writeSolidToLV(lvName, solidName, (*
m_Visible)[lvIndex], matID, lvID + 0x00010000 * replica + lvCount, solidID);
565 writeLVToPV(pvName, lvName, pvID + 0x00010000 * replica + pvCount, lvID + 0x00010000 * replica + lvCount);
568 if ((axis == kRho) && (solid->GetEntityType() ==
"G4Tubs")) {
569 solidName.append(
"_R");
570 solidName.append(std::to_string(replica));
571 solidID += 0x00010000 * replica;
573 if (
m_UsePrototypes && !((axis == kRho) && (solid->GetEntityType() ==
"G4Tubs"))) {
574 if ((replica == 0) && (lvCount == 0)) {
583 lvName.append(std::to_string(replica));
585 writeSolidToPV(pvName, solidName, (*
m_Visible)[lvIndex], matID, pvID + 0x00010000 * replica + pvCount, solidID);
587 writeSolidToLV(lvName, solidName, (*
m_Visible)[lvIndex], matID, lvID + 0x00010000 * replica + lvCount, solidID);
591 writeLVToPV(pvName, lvName, pvID + 0x00010000 * replica + pvCount, lvID + 0x00010000 * replica + lvCount);
611 (*m_LVCount)[lvIndex]++;
612 (*m_PVCount)[pvIndex]++;
618 std::time_t t = std::time(
nullptr);
619 struct tm* now = std::localtime(&t);
620 m_File <<
"; FBX 7.3.0 project file" << std::endl <<
621 "; Copyright (C) 1997-2010 Autodesk Inc. and/or its licensors." << std::endl <<
622 "; All rights reserved." << std::endl << std::endl <<
623 "FBXHeaderExtension: {" << std::endl <<
624 "\tFBXHeaderVersion: 1003" << std::endl <<
625 "\tFBXVersion: 7300" << std::endl <<
626 "\tCreationTime: \"" << std::put_time(now,
"%F %T") <<
":000\"" << std::endl <<
637 "\tCreator: \"FBX SDK/FBX Plugins version 2013.3\"" << std::endl <<
638 "\tSceneInfo: \"SceneInfo::GlobalInfo\", \"UserData\" {" << std::endl <<
639 "\t\tType: \"UserData\"" << std::endl <<
640 "\t\tVersion: 100" << std::endl <<
641 "\t\tMetaData: {" << std::endl <<
642 "\t\t\tVersion: 100" << std::endl <<
643 "\t\t\tTitle: \"Belle II Detector\"" << std::endl <<
644 "\t\t\tSubject: \"Detector Geometry Model\"" << std::endl <<
645 "\t\t\tAuthor: \"Belle II Collaboration\"" << std::endl <<
646 "\t\t\tKeywords: \"\"" << std::endl <<
647 "\t\t\tRevision: \"\"" << std::endl <<
648 "\t\t\tComment: \"\"" << std::endl <<
649 "\t\t}" << std::endl <<
650 "\t}" << std::endl <<
651 "}" << std::endl << std::endl;
653 m_File <<
"GlobalSettings: {" << std::endl <<
654 "\tVersion: 1000" << std::endl <<
655 "\tProperties70: {" << std::endl <<
656 "\t\tP: \"UpAxis\", \"int\", \"Integer\", \"\",1" << std::endl <<
657 "\t\tP: \"UpAxisSign\", \"int\", \"Integer\", \"\",1" << std::endl <<
658 "\t\tP: \"FrontAxis\", \"int\", \"Integer\", \"\",2" << std::endl <<
659 "\t\tP: \"FrontAxisSign\", \"int\", \"Integer\", \"\",1" << std::endl <<
660 "\t\tP: \"CoordAxis\", \"int\", \"Integer\", \"\",0" << std::endl <<
661 "\t\tP: \"CoordAxisSign\", \"int\", \"Integer\", \"\",1" << std::endl <<
662 "\t\tP: \"OriginalUpAxis\", \"int\", \"Integer\", \"\",1" << std::endl <<
663 "\t\tP: \"OriginalUpAxisSign\", \"int\", \"Integer\", \"\",1" << std::endl <<
664 "\t\tP: \"UnitScaleFactor\", \"double\", \"Number\", \"\",1" << std::endl <<
665 "\t\tP: \"OriginalUnitScaleFactor\", \"double\", \"Number\", \"\",1" << std::endl <<
666 "\t\tP: \"AmbientColor\", \"ColorRGB\", \"Color\", \"\",1,1,1" << std::endl <<
667 "\t\tP: \"DefaultCamera\", \"KString\", \"\", \"\", \"Producer Perspective\"" << std::endl <<
668 "\t\tP: \"TimeMode\", \"enum\", \"\", \"\",0" << std::endl <<
669 "\t\tP: \"TimeSpanStart\", \"KTime\", \"Time\", \"\",0" << std::endl <<
670 "\t\tP: \"TimeSpanStop\", \"KTime\", \"Time\", \"\",10" << std::endl <<
671 "\t\tP: \"CustomFrameRate\", \"double\", \"Number\", \"\",-1" << std::endl <<
672 "\t}" << std::endl <<
673 "}" << std::endl << std::endl;
675 m_File <<
"Documents: {" << std::endl <<
676 "\tCount: 1" << std::endl <<
677 "\tDocument: 4000000000, \"\", \"Scene\" {" << std::endl <<
678 "\t\tProperties70: {" << std::endl <<
679 "\t\t\tP: \"SourceObject\", \"object\", \"\", \"\"" << std::endl <<
680 "\t\t\tP: \"ActiveAnimStackName\", \"KString\", \"\", \"\", \"\"" << std::endl <<
681 "\t\t}" << std::endl <<
682 "\t\tRootNode: 0" << std::endl <<
683 "\t}" << std::endl <<
684 "}" << std::endl << std::endl;
686 m_File <<
"References: {" << std::endl <<
687 "}" << std::endl << std::endl;
689 m_File <<
"Definitions: {" << std::endl <<
690 "\tVersion: 100" << std::endl <<
691 "\tCount: 4" << std::endl <<
692 "\tObjectType: \"GlobalSettings\" {" << std::endl <<
693 "\t\tCount: 1" << std::endl <<
695 m_File <<
"\tObjectType: \"Model\" {" << std::endl <<
696 "\t\tCount: " << modelCount << std::endl <<
697 "\t\tPropertyTemplate: \"FbxNode\" {" << std::endl <<
698 "\t\t\tProperties70: {" << std::endl <<
699 "\t\t\t\tP: \"QuaternionInterpolate\", \"enum\", \"\", \"\",0" << std::endl <<
700 "\t\t\t\tP: \"RotationOffset\", \"Vector3D\", \"Vector\", \"\",0,0,0" << std::endl <<
701 "\t\t\t\tP: \"RotationPivot\", \"Vector3D\", \"Vector\", \"\",0,0,0" << std::endl <<
702 "\t\t\t\tP: \"ScalingOffset\", \"Vector3D\", \"Vector\", \"\",0,0,0" << std::endl <<
703 "\t\t\t\tP: \"ScalingPivot\", \"Vector3D\", \"Vector\", \"\",0,0,0" << std::endl <<
704 "\t\t\t\tP: \"TranslationActive\", \"bool\", \"\", \"\",0" << std::endl <<
705 "\t\t\t\tP: \"TranslationMin\", \"Vector3D\", \"Vector\", \"\",0,0,0" << std::endl <<
706 "\t\t\t\tP: \"TranslationMax\", \"Vector3D\", \"Vector\", \"\",0,0,0" << std::endl <<
707 "\t\t\t\tP: \"TranslationMinX\", \"bool\", \"\", \"\",0" << std::endl <<
708 "\t\t\t\tP: \"TranslationMinY\", \"bool\", \"\", \"\",0" << std::endl <<
709 "\t\t\t\tP: \"TranslationMinZ\", \"bool\", \"\", \"\",0" << std::endl <<
710 "\t\t\t\tP: \"TranslationMaxX\", \"bool\", \"\", \"\",0" << std::endl <<
711 "\t\t\t\tP: \"TranslationMaxY\", \"bool\", \"\", \"\",0" << std::endl <<
712 "\t\t\t\tP: \"TranslationMaxZ\", \"bool\", \"\", \"\",0" << std::endl <<
713 "\t\t\t\tP: \"RotationOrder\", \"enum\", \"\", \"\",0" << std::endl <<
714 "\t\t\t\tP: \"RotationSpaceForLimitOnly\", \"bool\", \"\", \"\",0" << std::endl <<
715 "\t\t\t\tP: \"RotationStiffnessX\", \"double\", \"Number\", \"\",0" << std::endl <<
716 "\t\t\t\tP: \"RotationStiffnessY\", \"double\", \"Number\", \"\",0" << std::endl <<
717 "\t\t\t\tP: \"RotationStiffnessZ\", \"double\", \"Number\", \"\",0" << std::endl <<
718 "\t\t\t\tP: \"AxisLen\", \"double\", \"Number\", \"\",10" << std::endl <<
719 "\t\t\t\tP: \"PreRotation\", \"Vector3D\", \"Vector\", \"\",0,0,0" << std::endl <<
720 "\t\t\t\tP: \"PostRotation\", \"Vector3D\", \"Vector\", \"\",0,0,0" << std::endl <<
721 "\t\t\t\tP: \"RotationActive\", \"bool\", \"\", \"\",0" << std::endl <<
722 "\t\t\t\tP: \"RotationMin\", \"Vector3D\", \"Vector\", \"\",0,0,0" << std::endl <<
723 "\t\t\t\tP: \"RotationMax\", \"Vector3D\", \"Vector\", \"\",0,0,0" << std::endl <<
724 "\t\t\t\tP: \"RotationMinX\", \"bool\", \"\", \"\",0" << std::endl <<
725 "\t\t\t\tP: \"RotationMinY\", \"bool\", \"\", \"\",0" << std::endl <<
726 "\t\t\t\tP: \"RotationMinZ\", \"bool\", \"\", \"\",0" << std::endl <<
727 "\t\t\t\tP: \"RotationMaxX\", \"bool\", \"\", \"\",0" << std::endl <<
728 "\t\t\t\tP: \"RotationMaxY\", \"bool\", \"\", \"\",0" << std::endl <<
729 "\t\t\t\tP: \"RotationMaxZ\", \"bool\", \"\", \"\",0" << std::endl <<
730 "\t\t\t\tP: \"InheritType\", \"enum\", \"\", \"\",0" << std::endl <<
731 "\t\t\t\tP: \"ScalingActive\", \"bool\", \"\", \"\",0" << std::endl <<
732 "\t\t\t\tP: \"ScalingMin\", \"Vector3D\", \"Vector\", \"\",0,0,0" << std::endl <<
733 "\t\t\t\tP: \"ScalingMax\", \"Vector3D\", \"Vector\", \"\",0,0,0" << std::endl <<
734 "\t\t\t\tP: \"ScalingMinX\", \"bool\", \"\", \"\",0" << std::endl <<
735 "\t\t\t\tP: \"ScalingMinY\", \"bool\", \"\", \"\",0" << std::endl <<
736 "\t\t\t\tP: \"ScalingMinZ\", \"bool\", \"\", \"\",0" << std::endl <<
737 "\t\t\t\tP: \"ScalingMaxX\", \"bool\", \"\", \"\",0" << std::endl <<
738 "\t\t\t\tP: \"ScalingMaxY\", \"bool\", \"\", \"\",0" << std::endl <<
739 "\t\t\t\tP: \"ScalingMaxZ\", \"bool\", \"\", \"\",0" << std::endl <<
740 "\t\t\t\tP: \"GeometricTranslation\", \"Vector3D\", \"Vector\", \"\",0,0,0" << std::endl <<
741 "\t\t\t\tP: \"GeometricRotation\", \"Vector3D\", \"Vector\", \"\",0,0,0" << std::endl <<
742 "\t\t\t\tP: \"GeometricScaling\", \"Vector3D\", \"Vector\", \"\",1,1,1" << std::endl <<
743 "\t\t\t\tP: \"MinDampRangeX\", \"double\", \"Number\", \"\",0" << std::endl <<
744 "\t\t\t\tP: \"MinDampRangeY\", \"double\", \"Number\", \"\",0" << std::endl <<
745 "\t\t\t\tP: \"MinDampRangeZ\", \"double\", \"Number\", \"\",0" << std::endl <<
746 "\t\t\t\tP: \"MaxDampRangeX\", \"double\", \"Number\", \"\",0" << std::endl <<
747 "\t\t\t\tP: \"MaxDampRangeY\", \"double\", \"Number\", \"\",0" << std::endl <<
748 "\t\t\t\tP: \"MaxDampRangeZ\", \"double\", \"Number\", \"\",0" << std::endl <<
749 "\t\t\t\tP: \"MinDampStrengthX\", \"double\", \"Number\", \"\",0" << std::endl <<
750 "\t\t\t\tP: \"MinDampStrengthY\", \"double\", \"Number\", \"\",0" << std::endl <<
751 "\t\t\t\tP: \"MinDampStrengthZ\", \"double\", \"Number\", \"\",0" << std::endl <<
752 "\t\t\t\tP: \"MaxDampStrengthX\", \"double\", \"Number\", \"\",0" << std::endl <<
753 "\t\t\t\tP: \"MaxDampStrengthY\", \"double\", \"Number\", \"\",0" << std::endl <<
754 "\t\t\t\tP: \"MaxDampStrengthZ\", \"double\", \"Number\", \"\",0" << std::endl <<
755 "\t\t\t\tP: \"PreferedAngleX\", \"double\", \"Number\", \"\",0" << std::endl <<
756 "\t\t\t\tP: \"PreferedAngleY\", \"double\", \"Number\", \"\",0" << std::endl <<
757 "\t\t\t\tP: \"PreferedAngleZ\", \"double\", \"Number\", \"\",0" << std::endl <<
758 "\t\t\t\tP: \"LookAtProperty\", \"object\", \"\", \"\"" << std::endl <<
759 "\t\t\t\tP: \"UpVectorProperty\", \"object\", \"\", \"\"" << std::endl <<
760 "\t\t\t\tP: \"Show\", \"bool\", \"\", \"\",1" << std::endl <<
761 "\t\t\t\tP: \"NegativePercentShapeSupport\", \"bool\", \"\", \"\",1" << std::endl <<
762 "\t\t\t\tP: \"DefaultAttributeIndex\", \"int\", \"Integer\", \"\",0" << std::endl <<
763 "\t\t\t\tP: \"Freeze\", \"bool\", \"\", \"\",0" << std::endl <<
764 "\t\t\t\tP: \"LODBox\", \"bool\", \"\", \"\",0" << std::endl <<
765 "\t\t\t\tP: \"Lcl Translation\", \"Lcl Translation\", \"\", \"A\",0,0,0" << std::endl <<
766 "\t\t\t\tP: \"Lcl Rotation\", \"Lcl Rotation\", \"\", \"A\",0,0,0" << std::endl <<
767 "\t\t\t\tP: \"Lcl Scaling\", \"Lcl Scaling\", \"\", \"A\",1,1,1" << std::endl <<
768 "\t\t\t\tP: \"Visibility\", \"Visibility\", \"\", \"A\",1" << std::endl <<
769 "\t\t\t\tP: \"Visibility Inheritance\", \"Visibility Inheritance\", \"\", \"\",1" << std::endl <<
770 "\t\t\t}" << std::endl <<
771 "\t\t}" << std::endl <<
773 m_File <<
"\tObjectType: \"Material\" {" << std::endl <<
774 "\t\tCount: " << materialCount << std::endl <<
775 "\t\tPropertyTemplate: \"FbxSurfacePhong\" {" << std::endl <<
776 "\t\t\tProperties70: {" << std::endl <<
777 "\t\t\t\tP: \"ShadingModel\", \"KString\", \"\", \"\", \"Phong\"" << std::endl <<
778 "\t\t\t\tP: \"MultiLayer\", \"bool\", \"\", \"\",0" << std::endl <<
779 "\t\t\t\tP: \"EmissiveColor\", \"ColorRGB\", \"Color\", \"A\",0,0,0" << std::endl <<
780 "\t\t\t\tP: \"EmissiveFactor\", \"double\", \"Number\", \"A\",0" << std::endl <<
781 "\t\t\t\tP: \"AmbientColor\", \"ColorRGB\", \"Color\", \"A\",0,0,0" << std::endl <<
782 "\t\t\t\tP: \"AmbientFactor\", \"double\", \"Number\", \"A\",0" << std::endl <<
783 "\t\t\t\tP: \"DiffuseColor\", \"ColorRGB\", \"Color\", \"A\",0,0,0" << std::endl <<
784 "\t\t\t\tP: \"DiffuseFactor\", \"double\", \"Number\", \"A\",1" << std::endl <<
785 "\t\t\t\tP: \"Bump\", \"Vector3D\", \"Vector\", \"\",0,0,0" << std::endl <<
786 "\t\t\t\tP: \"NormalMap\", \"Vector3D\", \"Vector\", \"\",0,0,0" << std::endl <<
787 "\t\t\t\tP: \"BumpFactor\", \"double\", \"Number\", \"\",1" << std::endl <<
788 "\t\t\t\tP: \"TransparentColor\", \"ColorRGB\", \"Color\", \"A\",0,0,0" << std::endl <<
789 "\t\t\t\tP: \"TransparencyFactor\", \"double\", \"Number\", \"A\",0" << std::endl <<
790 "\t\t\t\tP: \"DisplacementColor\", \"ColorRGB\", \"Color\", \"\",0,0,0" << std::endl <<
791 "\t\t\t\tP: \"DisplacementFactor\", \"double\", \"Number\", \"\",1" << std::endl <<
792 "\t\t\t\tP: \"VectorDisplacementColor\", \"ColorRGB\", \"Color\", \"\",0,0,0" << std::endl <<
793 "\t\t\t\tP: \"VectorDisplacementFactor\", \"double\", \"Number\", \"\",1" << std::endl <<
794 "\t\t\t\tP: \"SpecularColor\", \"ColorRGB\", \"Color\", \"A\",0,0,0" << std::endl <<
795 "\t\t\t\tP: \"SpecularFactor\", \"double\", \"Number\", \"A\",0" << std::endl <<
796 "\t\t\t\tP: \"ShininessExponent\", \"double\", \"Number\", \"A\",20" << std::endl <<
797 "\t\t\t\tP: \"ReflectionColor\", \"ColorRGB\", \"Color\", \"A\",0,0,0" << std::endl <<
798 "\t\t\t\tP: \"ReflectionFactor\", \"double\", \"Number\", \"A\",0" << std::endl <<
799 "\t\t\t}" << std::endl <<
800 "\t\t}" << std::endl <<
828 m_File <<
"\tObjectType: \"Geometry\" {" << std::endl <<
829 "\t\tCount: " << geometryCount << std::endl <<
830 "\t\tPropertyTemplate: \"FbxMesh\" {" << std::endl <<
831 "\t\t\tProperties70: {" << std::endl <<
832 "\t\t\t\tP: \"Color\", \"ColorRGB\", \"Color\", \"\",1,1,1" << std::endl <<
833 "\t\t\t\tP: \"BBoxMin\", \"Vector3D\", \"Vector\", \"\",0,0,0" << std::endl <<
834 "\t\t\t\tP: \"BBoxMax\", \"Vector3D\", \"Vector\", \"\",0,0,0" << std::endl <<
835 "\t\t\t\tP: \"Primary Visibility\", \"bool\", \"\", \"\",1" << std::endl <<
836 "\t\t\t\tP: \"Casts Shadows\", \"bool\", \"\", \"\",0" << std::endl <<
837 "\t\t\t\tP: \"Receive Shadows\", \"bool\", \"\", \"\",0" << std::endl <<
838 "\t\t\t}" << std::endl <<
839 "\t\t}" << std::endl <<
840 "\t}" << std::endl <<
841 "}" << std::endl << std::endl;
846 unsigned long long solidID)
849 polyhedron->SetNumberOfRotationSteps(120);
850 m_File <<
"\t; Solid " << solid->GetName() <<
" of type " << solid->GetEntityType() << std::endl <<
851 "\tGeometry: " << solidID <<
", \"Geometry::" << name << R
"(", "Mesh" {)" << std::endl <<
852 "\t\tVertices: *" << polyhedron->GetNoVertices() * 3 <<
" {" << std::endl <<
"\t\t\ta: ";
853 std::streampos startOfLine =
m_File.tellp();
854 for (
int j = 1; j <= polyhedron->GetNoVertices(); ++j) {
855 m_File << (j == 1 ?
"" :
",") <<
856 polyhedron->GetVertex(j).x() <<
"," <<
857 polyhedron->GetVertex(j).y() <<
"," <<
858 polyhedron->GetVertex(j).z();
859 if (
m_File.tellp() - startOfLine > 100) {
860 startOfLine =
m_File.tellp();
861 m_File << std::endl <<
"\t\t\t\t";
864 m_File << std::endl <<
"\t\t}" << std::endl;
866 std::vector<int> vertices;
867 for (
int k = 1; k <= polyhedron->GetNoFacets(); ++k) {
868 G4bool notLastEdge =
true;
869 G4int ndx = -1, edgeFlag = 1;
871 notLastEdge = polyhedron->GetNextVertexIndex(ndx, edgeFlag);
873 vertices.push_back(ndx - 1);
875 vertices.push_back(-ndx);
877 }
while (notLastEdge);
879 m_File <<
"\t\tPolygonVertexIndex: *" << vertices.size() <<
" {" << std::endl <<
"\t\t\ta: ";
880 startOfLine =
m_File.tellp();
881 for (
unsigned int j = 0; j < vertices.size(); ++j) {
882 m_File << (j == 0 ?
"" :
",") << vertices[j];
883 if (
m_File.tellp() - startOfLine > 100) {
884 startOfLine =
m_File.tellp();
885 m_File << std::endl <<
"\t\t\t\t";
888 m_File << std::endl <<
"\t\t}" << std::endl;
890 m_File <<
"\t\tGeometryVersion: 124" << std::endl <<
891 "\t\tLayerElementNormal: 0 {" << std::endl <<
892 "\t\t\tVersion: 101" << std::endl <<
894 "\t\t\tMappingInformationType: \"ByPolygonVertex\"" << std::endl <<
895 "\t\t\tReferenceInformationType: \"Direct\"" << std::endl <<
896 "\t\t\tNormals: *" << vertices.size() * 3 <<
" {" << std::endl <<
"\t\t\t\ta: ";
897 startOfLine =
m_File.tellp();
899 for (
int k = 1; k <= polyhedron->GetNoFacets(); ++k) {
900 G4Normal3D normal = polyhedron->GetUnitNormal(k);
902 m_File << (j == 0 ?
"" :
",") << normal.x() <<
"," << normal.y() <<
"," << normal.z();
903 if (
m_File.tellp() - startOfLine > 100) {
904 startOfLine =
m_File.tellp();
905 m_File << std::endl <<
"\t\t\t\t";
907 }
while (vertices[j++] >= 0);
909 m_File << std::endl <<
"\t\t\t}" << std::endl <<
"\t\t}" << std::endl <<
910 "\t\tLayerElementMaterial: 0 {" << std::endl <<
911 "\t\t\tVersion: 101" << std::endl <<
913 "\t\t\tMappingInformationType: \"AllSame\"" << std::endl <<
914 "\t\t\tReferenceInformationType: \"IndexToDirect\"" << std::endl <<
915 "\t\t\tMaterials: *1 {" << std::endl <<
916 "\t\t\t\ta: 0" << std::endl <<
917 "\t\t\t}" << std::endl <<
918 "\t\t}" << std::endl <<
919 "\t\tLayer: 0 {" << std::endl <<
920 "\t\t\tVersion: 100" << std::endl <<
921 "\t\t\tLayerElement: {" << std::endl <<
922 "\t\t\t\tType: \"LayerElementNormal\"" << std::endl <<
923 "\t\t\t\tTypedIndex: 0" << std::endl <<
924 "\t\t\t}" << std::endl <<
925 "\t\t\tLayerElement: {" << std::endl <<
926 "\t\t\t\tType: \"LayerElementMaterial\"" << std::endl <<
927 "\t\t\t\tTypedIndex: 0" << std::endl <<
928 "\t\t\t}" << std::endl <<
929 "\t\t}" << std::endl <<
932 B2INFO(
"Polyhedron representation of solid " << name <<
" cannot be created");
938 G4RotationMatrix* rot = physVol->GetObjectRotation();
939 G4ThreeVector move = physVol->GetObjectTranslation();
941 double yaw = std::atan2(rot->yx(), rot->xx()) * 180.0 / M_PI;
942 if (fabs(yaw) < 1.0E-12) yaw = 0.0;
943 double pitch = -std::asin(rot->zx()) * 180.0 / M_PI;
944 if (fabs(pitch) < 1.0E-12) pitch = 0.0;
945 double roll = std::atan2(rot->zy(), rot->zz()) * 180.0 / M_PI;
946 if (fabs(roll) < 1.0E-12) roll = 0.0;
947 m_File <<
"\t; PhysVol " << physVol->GetName();
948 if (physVol->IsReplicated()) {
949 m_File <<
" (replicated: copy " << physVol->GetCopyNo() <<
")";
951 m_File <<
", placing LogVol " << physVol->GetLogicalVolume()->GetName() << std::endl <<
952 "\tModel: " << pvID <<
", \"Model::" << pvName << R
"(", "Null" {)" << std::endl <<
953 "\t\tVersion: 232" << std::endl <<
954 "\t\tProperties70: {" << std::endl <<
955 "\t\t\tP: \"Lcl Translation\", \"Lcl Translation\", \"\", \"A\"," <<
956 move.x() <<
"," << move.y() <<
"," << move.z() << std::endl <<
957 "\t\t\tP: \"Lcl Rotation\", \"Lcl Rotation\", \"\", \"A\"," <<
958 roll <<
"," << pitch <<
"," << yaw << std::endl <<
959 "\t\t}" << std::endl <<
960 "\t\tShading: T" << std::endl <<
961 "\t\tCulling: \"CullingOff\"" << std::endl <<
966 unsigned long long matID,
unsigned long long lvID,
unsigned long long solidID)
968 m_File <<
"\t; Solid Geometry::" << solidName <<
", LogVol Model::lv_" << lvName << std::endl <<
969 "\t" << (visible ?
"" :
"; ") <<
"C: \"OO\"," << solidID <<
"," << lvID << std::endl << std::endl <<
970 "\t; Color Material::" << lvName <<
", LogVol Model::lv_" << lvName << std::endl <<
971 "\t" << (visible ?
"" :
"; ") <<
"C: \"OO\"," << matID <<
"," << lvID << std::endl << std::endl;
975 unsigned long long matID,
unsigned long long pvID,
unsigned long long solidID)
977 m_File <<
"\t; Solid Geometry::" << solidName <<
", PhysVol Model::" << pvName << std::endl <<
978 "\t" << (visible ?
"" :
"; ") <<
"C: \"OO\"," << solidID <<
"," << pvID << std::endl << std::endl <<
979 "\t; Color Material::" << pvName <<
", PhysVol Model::" << pvName << std::endl <<
980 "\t" << (visible ?
"" :
"; ") <<
"C: \"OO\"," << matID <<
"," << pvID << std::endl << std::endl;
984 unsigned long long lvID)
986 m_File <<
"\t; LogVol Model::lv_" << lvName <<
", PhysVol Model::" << pvName << std::endl <<
987 "\tC: \"OO\"," << lvID <<
"," << pvID << std::endl << std::endl;
991 unsigned long long pvIDDaughter,
unsigned long long lvID)
993 m_File <<
"\t; PhysVol Model::" << pvNameDaughter <<
", parent LogVol Model::lv_" << lvName << std::endl <<
994 "\tC: \"OO\"," << pvIDDaughter <<
"," << lvID << std::endl << std::endl;
998 unsigned long long pvIDDaughter,
unsigned long long pvID)
1000 m_File <<
"\t; PhysVol Model::" << pvNameDaughter <<
", parent PhysVol Model::" << pvName << std::endl <<
1001 "\tC: \"OO\"," << pvIDDaughter <<
"," << pvID << std::endl << std::endl;
1008 G4VSolid* solidA = solid->GetConstituentSolid(0);
1009 G4VSolid* solidB = solid->GetConstituentSolid(1);
1010 HepPolyhedron* polyhedronA =
nullptr;
1011 if ((solidA->GetEntityType() ==
"G4IntersectionSolid") ||
1012 (solidA->GetEntityType() ==
"G4UnionSolid") ||
1013 (solidA->GetEntityType() ==
"G4SubtractionSolid") ||
1014 (solidA->GetEntityType() ==
"G4BooleanSolid")) {
1017 polyhedronA =
new HepPolyhedron(*(solidA->GetPolyhedron()));
1019 HepPolyhedron* polyhedronB =
nullptr;
1020 G4VSolid* solidB2 = solidB;
1021 if (solidB->GetEntityType() ==
"G4DisplacedSolid") {
1022 solidB2 = ((G4DisplacedSolid*)solidB)->GetConstituentMovedSolid();
1024 if ((solidB2->GetEntityType() ==
"G4IntersectionSolid") ||
1025 (solidB2->GetEntityType() ==
"G4UnionSolid") ||
1026 (solidB2->GetEntityType() ==
"G4SubtractionSolid") ||
1027 (solidB2->GetEntityType() ==
"G4BooleanSolid")) {
1029 if (solidB != solidB2) {
1030 polyhedronB->Transform(G4Transform3D(
1031 ((G4DisplacedSolid*)solidB)->GetObjectRotation(),
1032 ((G4DisplacedSolid*)solidB)->GetObjectTranslation()));
1035 polyhedronB =
new HepPolyhedron(*(solidB->GetPolyhedron()));
1037 auto* result =
new HepPolyhedron();
1038 if (solid->GetEntityType() ==
"G4UnionSolid") {
1039 *result = polyhedronA->add(*polyhedronB);
1040 }
else if (solid->GetEntityType() ==
"G4SubtractionSolid") {
1041 *result = polyhedronA->subtract(*polyhedronB);
1042 }
else if (solid->GetEntityType() ==
"G4IntersectionSolid") {
1043 *result = polyhedronA->intersect(*polyhedronB);
1045 B2WARNING(
"getBooleanSolidPolyhedron(): Unrecognized boolean solid " << solid->GetName() <<
1046 " of type " << solid->GetEntityType());
std::vector< unsigned int > * m_PVCount
Count of number of instances of each physical volume.
void writePVToParentLV(const std::string &, const std::string &, unsigned long long, unsigned long long)
Write FBX connection for each physical-volume daughter of a parent logical volume.
std::vector< unsigned long long > * m_LVID
Unique identifiers for logical volumes (Model nodes with links to Geometry and Material)
void writeLVToPV(const std::string &, const std::string &, unsigned long long, unsigned long long)
Write FBX connection for the (unique) logical volume of a physical volume.
void addConnections(G4VPhysicalVolume *, int)
Write FBX connections among all of the nodes in the tree (recursive)
FBXWriterModule()
Constructor of the module.
void initialize() override
Initialize at the start of a job.
std::vector< unsigned int > * m_LVReplicas
Count of number of replicas of each logical volume associated with a replicated physical volume.
void event() override
Called for each event: this runs the FBX writer only for the first event.
void addModels(G4VPhysicalVolume *, int)
Process one physical volume for FBX-node writing (recursive)
std::vector< unsigned int > * m_PVReplicas
Count of number of replicas of each replicated physical volume.
std::ofstream m_File
Output file.
void writeSolidToPV(const std::string &, const std::string &, bool, unsigned long long, unsigned long long, unsigned long long)
Write FBX connection for each physical volume's solid and color info (bypass singleton logical volume...
bool m_UsePrototypes
User-specified flag to select whether to write and re-use logical- and physical-volume prototypes onc...
std::vector< unsigned long long > * m_PVID
Unique identifiers for physical volumes (Model nodes with transformation information)
bool m_First
Once-only flag to write FBX only on the first event.
void writePreamble(int, int, int)
Write FBX at the start of the file.
std::vector< bool > * m_Visible
Flag to indicate that the logical volume is visible.
void writePVModelNode(G4VPhysicalVolume *, const std::string &, unsigned long long)
Write FBX definition for each physical volume.
std::vector< bool > * m_LVUnique
Flag to indicate that a logical volume is referenced at most once (eligible for bypass)
void assignName(std::vector< std::string > *, unsigned int, const G4String &, int)
Create unique and legal name for each solid, logical volume, physical volume.
std::vector< unsigned int > * m_SolidCount
Count of number of instances of each solid (typically 1)
void writeLVModelNode(G4LogicalVolume *, const std::string &, unsigned long long)
Write FBX definition for each logical volume.
void countEntities(G4VPhysicalVolume *)
Count the physical volumes, logical volumes, materials and solids (recursive)
std::string m_Filename
User-specified output filename.
std::vector< std::string > * m_PVName
Modified (legal-character and unique) physical-volume name.
std::vector< unsigned int > * m_SolidReplicas
Count of number of replicas of each solid (extras for replicas with modified solids)
std::vector< std::string > * m_SolidName
Modified (legal-character and unique) solid name.
std::vector< unsigned long long > * m_SolidID
Unique identifiers for solids (Geometry nodes)
std::vector< unsigned int > * m_LVCount
Count of number of instances of each logical volume.
std::vector< unsigned long long > * m_MatID
Unique identifiers for logical volumes' color information (Material nodes)
void writeMaterialNode(int, const std::string &)
Write FBX definition for each logical volume's color information.
void writePVToParentPV(const std::string &, const std::string &, unsigned long long, unsigned long long)
Write FBX connection for each physical-volume daughter of a parent physical volume (bypass singleton ...
HepPolyhedron * getBooleanSolidPolyhedron(G4VSolid *)
Create polyhedron for a boolean solid (recursive)
std::vector< std::string > * m_LVName
Modified (legal-character and unique) logical-volume name.
void writeGeometryNode(G4VSolid *, const std::string &, unsigned long long)
Write FBX definition for each solid's polyhedron.
void writePolyhedron(G4VSolid *, G4Polyhedron *, const std::string &, unsigned long long)
Write FBX definition for the solid's polyhedron.
void writeSolidToLV(const std::string &, const std::string &, bool, unsigned long long, unsigned long long, unsigned long long)
Write FBX connection for each logical volume's solid and color info.
void setDescription(const std::string &description)
Sets the description of the module.
G4VPhysicalVolume * getTopVolume()
Return a pointer to the top volume.
static GeometryManager & getInstance()
Return a reference to the instance.
void addParam(const std::string &name, T ¶mVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Abstract base class for different kinds of events.