9 #include <geometry/modules/vrmlWriter/VRMLWriterModule.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" 
   17 #include "G4VSolid.hh" 
   18 #include "G4VisAttributes.hh" 
   19 #include "G4VisExtent.hh" 
   20 #include "G4Material.hh" 
   21 #include "G4ThreeVector.hh" 
   22 #include "G4RotationMatrix.hh" 
   23 #include "G4Transform3D.hh" 
   24 #include "G4VPVParameterisation.hh" 
   27 #include <G4Polyhedron.hh> 
   28 #include <G4DisplacedSolid.hh> 
   39   setDescription(
"Write the detector geometry in a hierarchical VRML format.");
 
   56     B2ERROR(
"No geometry found: add the Geometry module to the path before the VRMLWriter module.");
 
   62   G4PhysicalVolumeStore* pvStore = G4PhysicalVolumeStore::GetInstance();
 
   63   G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance();
 
   64   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(), 
"");
 
   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();
 
   87   m_IsCylinder = 
new std::vector<bool>(solidStore->size(), 
false);
 
   88   for (
unsigned int solidIndex = 0; solidIndex < solidStore->size(); ++solidIndex) {
 
   90       if ((*solidStore)[solidIndex]->GetEntityType() == 
"G4Tubs") {
 
   91         auto* tube = (G4Tubs*)((*solidStore)[solidIndex]);
 
   92         (*m_IsCylinder)[solidIndex] = ((tube->GetInnerRadius() == 0.0) && (tube->GetDeltaPhiAngle() == 2.0 * M_PI));
 
  101   m_PVIndex = 
new std::vector<std::vector<int> >(lvStore->size(), std::vector<int>());
 
  102   m_LVWritten = 
new std::vector<bool>(lvStore->size(), 
false);
 
  103   m_PVWritten = 
new std::vector<bool>(pvStore->size(), 
false);
 
  107   int pvIndex = std::find(pvStore->begin(), pvStore->end(), topVol) - pvStore->begin();
 
  108   int lvIndex = std::find(lvStore->begin(), lvStore->end(), topVol->GetLogicalVolume()) - lvStore->begin();
 
  109   m_File << 
"# PhysicalVolume " << topVol->GetName() << std::endl <<
 
  110          "DEF " << (*m_PVName)[pvIndex] << 
" Transform {" << std::endl <<
 
  111          " children lv_" << (*m_LVName)[lvIndex] << 
"{}" << std::endl <<
 
  128   G4SolidStore* solidStore = G4SolidStore::GetInstance();
 
  129   G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance();
 
  130   G4PhysicalVolumeStore* pvStore = G4PhysicalVolumeStore::GetInstance();
 
  132   G4String name = originalName;
 
  133   if (name.length() == 0) { name = 
"anonymous"; }
 
  135   for (
char c : 
" .,:;?'\"*+-=|^!/@#$\\%{}[]()<>") std::replace(name.begin(), name.end(), c, 
'_');
 
  137   for (
int j = (
int)index - 1; j >= 0; --j) {
 
  138     if ((*names)[j].length() == 0) 
continue;
 
  142         match = (*pvStore)[j]->GetName().compare((*pvStore)[index]->GetName()); 
break;
 
  144         match = (*lvStore)[j]->GetName().compare((*lvStore)[index]->GetName()); 
break;
 
  146         match = (*solidStore)[j]->GetName().compare((*solidStore)[index]->GetName()); 
break;
 
  149       if (name.length() == (*names)[j].length()) {
 
  150         (*names)[j].append(
"_1");
 
  152       int n = std::stoi((*names)[j].substr(name.length() + 1), 
nullptr);
 
  154       name.append(std::to_string(n + 1));
 
  158   (*names)[index] = name;
 
  163   m_File << 
"# Solid " << solid->GetName() << 
" of type " << solid->GetEntityType() << std::endl;
 
  165     auto* tube = (G4Tubs*)solid;
 
  167     m_File << 
"PROTO solid_" << solidName << 
" [ ] {" << std::endl <<
 
  168            " Cylinder {" << std::endl << std::setprecision(10) <<
 
  169            "  radius " << tube->GetOuterRadius() << std::endl <<
 
  170            "  height " << tube->GetZHalfLength() * 2.0 << std::endl <<
 
  173   } 
else if (solid->GetEntityType() == 
"G4Box") {
 
  174     auto* box = (G4Box*)solid;
 
  175     m_File << 
"PROTO solid_" << solidName << 
" [ ] {" << std::endl <<
 
  176            " Box {" << std::endl << std::setprecision(10) <<
 
  177            "  size " << box->GetXHalfLength() * 2.0 << 
" " <<
 
  178            box->GetYHalfLength() * 2.0 << 
" " <<
 
  179            box->GetZHalfLength() * 2.0 << std::endl <<
 
  182   } 
else if ((solid->GetEntityType() == 
"G4IntersectionSolid") ||
 
  183              (solid->GetEntityType() == 
"G4UnionSolid") ||
 
  184              (solid->GetEntityType() == 
"G4SubtractionSolid") ||
 
  185              (solid->GetEntityType() == 
"G4BooleanSolid")) {
 
  187     auto* g4polyhedron = 
new G4Polyhedron(*polyhedron);
 
  199   G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance();
 
  200   int lvIndex = std::find(lvStore->begin(), lvStore->end(), logVol) - lvStore->begin();
 
  202   (*m_LVWritten)[lvIndex] = 
true;
 
  203   G4Color color(0.0, 1.0, 0.0, 0.5); 
 
  204   if ((lvName.compare(0, 23, 
"eclBarrelCrystalLogical") == 0) ||
 
  205       (lvName.compare(0, 20, 
"eclFwdCrystalLogical") == 0) ||
 
  206       (lvName.compare(0, 20, 
"eclBwdCrystalLogical") == 0)) {
 
  207     color = G4Color(1.0, 0.25, 0.0, 0.7); 
 
  209   std::string visible = 
"";
 
  210   G4String materialName = logVol->GetMaterial()->GetName();
 
  212   if (materialName == 
"Vacuum") visible = 
"#";
 
  213   if (materialName == 
"G4_AIR") visible = 
"#";
 
  214   if (materialName == 
"CDCGas") visible = 
"#";
 
  215   if (materialName == 
"ColdAir") visible = 
"#";
 
  216   if (materialName == 
"STR-DryAir") visible = 
"#";
 
  217   if (materialName == 
"TOPAir") visible = 
"#";
 
  218   if (materialName == 
"TOPVacuum") visible = 
"#";
 
  219   const G4VisAttributes* visAttr = logVol->GetVisAttributes();
 
  221     color = 
const_cast<G4Color&
>(logVol->GetVisAttributes()->GetColor());
 
  222     if (!(visAttr->IsVisible())) visible = 
"#";
 
  226   bool hasDaughters = (visible.length() == 0) || ((*
m_PVIndex)[lvIndex].size() > 0);
 
  227   if (logVol->GetSensitiveDetector() != 
nullptr) visible = 
"";
 
  228   m_File << 
"# LogicalVolume " << logVol->GetName() << 
" containing " << materialName << std::endl <<
 
  229          "PROTO lv_" << lvName << 
" [ ] {" << std::endl <<
 
  230          " Group {" << std::endl <<
 
  231          "  " << (hasDaughters ? 
"" : 
"#") << 
"children [" << std::endl;
 
  234     m_File << 
"   " << visible << 
"Transform {" << std::endl <<
 
  235            "   " << visible << 
" rotation 1 0 0 " << M_PI_2 << std::endl <<
 
  236            "   " << visible << 
" children [" << std::endl;
 
  239   m_File << 
"   " << visible << 
"Shape {" << std::endl <<
 
  240          "   " << visible << 
" appearance Appearance {" << std::endl <<
 
  241          "   " << visible << 
"  material Material {" << std::endl <<
 
  242          "   " << visible << 
"   diffuseColor " << color.GetRed() << 
" " <<
 
  243          color.GetGreen() << 
" " <<
 
  244          color.GetBlue() << std::endl <<
 
  245          "   " << visible << 
"   " << (color.GetAlpha() == 1.0 ? 
"#" : 
"") <<
 
  246          "transparency " << 1.0 - color.GetAlpha() << std::endl <<
 
  247          "   " << visible << 
"  }" << std::endl <<
 
  248          "   " << visible << 
" }" << std::endl <<
 
  249          "   " << visible << 
" geometry solid_" << solidName << 
"{}" << std::endl <<
 
  250          "   " << visible << 
"}" << std::endl;
 
  252     visible.resize(visible.length() - 2);
 
  253     m_File << 
"   " << visible << 
" ]" << std::endl <<
 
  254            "   " << visible << 
"}" << std::endl;
 
  256   G4PhysicalVolumeStore* pvStore = G4PhysicalVolumeStore::GetInstance();
 
  257   for (
int daughter : (*
m_PVIndex)[lvIndex]) {
 
  258     G4VPhysicalVolume* physVol = (*pvStore)[daughter];
 
  259     std::string pvNameDaughter = (*m_PVName)[daughter];
 
  260     int lvDaughter = std::find(lvStore->begin(), lvStore->end(), physVol->GetLogicalVolume()) - lvStore->begin();
 
  261     std::string lvNameDaughter = (*m_LVName)[lvDaughter];
 
  262     if (physVol->IsReplicated()) {
 
  263       G4VSolid* solid = logVol->GetSolid();
 
  269       physVol->GetReplicationData(axis, nReplicas, width, offset, consuming);
 
  270       G4VPVParameterisation* physParameterisation = physVol->GetParameterisation();
 
  271       if (physParameterisation) { 
 
  272         for (
int replica = 0; replica < nReplicas; ++replica) {
 
  273           std::string pvNameReplica = pvNameDaughter;
 
  274           std::string lvNameReplica = lvNameDaughter;
 
  275           pvNameReplica.append(
"_");
 
  276           pvNameReplica.append(std::to_string(replica));
 
  277           physVol->SetCopyNo(replica);
 
  278           physParameterisation->ComputeTransformation(replica, physVol);
 
  279           G4VSolid* solidReplica = physParameterisation->ComputeSolid(replica, physVol);
 
  280           if (solidReplica != solid) { 
 
  281             lvNameReplica.append(
"_");
 
  282             lvNameReplica.append(std::to_string(replica));
 
  287         G4ThreeVector originalTranslation = physVol->GetTranslation();
 
  288         G4RotationMatrix* originalRotation = physVol->GetRotation();
 
  289         for (
int replica = 0; replica < nReplicas; ++replica) {
 
  290           G4ThreeVector translation; 
 
  291           G4RotationMatrix rotation; 
 
  292           std::string pvNameReplica = pvNameDaughter;
 
  293           std::string lvNameReplica = lvNameDaughter;
 
  294           pvNameReplica.append(
"_");
 
  295           pvNameReplica.append(std::to_string(replica));
 
  296           physVol->SetCopyNo(replica);
 
  300               translation.setX(width * (replica - 0.5 * (nReplicas - 1)));
 
  301               physVol->SetTranslation(translation);
 
  304               translation.setY(width * (replica - 0.5 * (nReplicas - 1)));
 
  305               physVol->SetTranslation(translation);
 
  308               translation.setZ(width * (replica - 0.5 * (nReplicas - 1)));
 
  309               physVol->SetTranslation(translation);
 
  312               if (solid->GetEntityType() == 
"G4Tubs") {
 
  313                 lvNameReplica.append(
"_");
 
  314                 lvNameReplica.append(std::to_string(replica));
 
  316                 B2WARNING(
"Built-in volumes replicated along radius for " << solid->GetEntityType() <<
 
  317                           " (solid " << solid->GetName() << 
") are not visualisable.");
 
  321               physVol->SetRotation(&(rotation.rotateZ(-(offset + (replica + 0.5) * width))));
 
  327         physVol->SetTranslation(originalTranslation);
 
  328         physVol->SetRotation(originalRotation);
 
  333     (*m_PVWritten)[daughter] = 
true;
 
  335   G4VisExtent extent = logVol->GetSolid()->GetExtent();
 
  336   double xMin = extent.GetXmin();
 
  337   double xMax = extent.GetXmax();
 
  338   double yMin = extent.GetYmin();
 
  339   double yMax = extent.GetYmax();
 
  340   double zMin = extent.GetZmin();
 
  341   double zMax = extent.GetZmax();
 
  342   double xCenter = 0.5 * (xMin + xMax);
 
  343   double yCenter = 0.5 * (yMin + yMax);
 
  344   double zCenter = 0.5 * (zMin + zMax);
 
  345   bool atOrigin = (std::fabs(xCenter) + std::fabs(yCenter) + std::fabs(zCenter) > 1.0e-12);
 
  346   m_File << 
"  " << (hasDaughters ? 
"" : 
"#") << 
"]" << std::endl <<
 
  347          "  " << (atOrigin ? 
"" : 
"#") <<
 
  348          "bboxCenter " << xCenter << 
" " << yCenter << 
" " << zCenter << std::endl <<
 
  349          "  bboxSize " << xMax - xMin << 
" " <<
 
  350          (isCylinder ? zMax - zMin : yMax - yMin) << 
" " <<
 
  351          (isCylinder ? yMax - yMin : zMax - zMin) << std::endl <<
 
  353          "} # end of " << lvName << std::endl;
 
  358   G4LogicalVolume* logVol = physVol->GetLogicalVolume();
 
  359   G4VSolid* solid = logVol->GetSolid();
 
  360   G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance();
 
  361   int lvIndex = std::find(lvStore->begin(), lvStore->end(), logVol) - lvStore->begin();
 
  362   std::string lvName = (*m_LVName)[lvIndex];
 
  363   if (physVol->IsReplicated()) {
 
  364     G4SolidStore* solidStore = G4SolidStore::GetInstance();
 
  365     int solidIndex = std::find(solidStore->begin(), solidStore->end(), solid) - solidStore->begin();
 
  366     std::string solidName = (*m_SolidName)[solidIndex];
 
  372     physVol->GetReplicationData(axis, nReplicas, width, offset, consuming);
 
  373     G4VPVParameterisation* physParameterisation = physVol->GetParameterisation();
 
  374     if (physParameterisation) { 
 
  375       for (
int replica = 0; replica < nReplicas; ++replica) {
 
  376         std::string lvNameReplica = lvName;
 
  377         G4VSolid* solidReplica = physParameterisation->ComputeSolid(replica, physVol);
 
  378         if (solidReplica != solid) { 
 
  379           solidReplica->ComputeDimensions(physParameterisation, replica, physVol);
 
  380           std::string solidNameReplica = solidName;
 
  381           solidNameReplica.append(
"_");
 
  382           solidNameReplica.append(std::to_string(replica));
 
  383           lvNameReplica.append(
"_");
 
  384           lvNameReplica.append(std::to_string(replica));
 
  391       for (
int replica = 0; replica < nReplicas; ++replica) {
 
  393           if (solid->GetEntityType() == 
"G4Tubs") {
 
  394             double originalRMin = ((G4Tubs*)solid)->GetInnerRadius();
 
  395             double originalRMax = ((G4Tubs*)solid)->GetOuterRadius();
 
  396             ((G4Tubs*)solid)->SetInnerRadius(offset + width * replica);
 
  397             ((G4Tubs*)solid)->SetOuterRadius(offset + width * (replica + 1));
 
  398             std::string solidNameReplica = solidName;
 
  399             solidNameReplica.append(
"_");
 
  400             solidNameReplica.append(std::to_string(replica));
 
  401             std::string lvNameReplica = lvName;
 
  402             lvNameReplica.append(
"_");
 
  403             lvNameReplica.append(std::to_string(replica));
 
  405             ((G4Tubs*)solid)->SetInnerRadius(originalRMin);
 
  406             ((G4Tubs*)solid)->SetOuterRadius(originalRMax);
 
  410             B2WARNING(
"Built-in volumes replicated along radius for " << solid->GetEntityType() <<
 
  411                       " (solid " << solid->GetName() << 
") are not visualisable.");
 
  425   G4PhysicalVolumeStore* pvStore = G4PhysicalVolumeStore::GetInstance();
 
  426   G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance();
 
  427   G4SolidStore* solidStore = G4SolidStore::GetInstance();
 
  429   int pvIndex = std::find(pvStore->begin(), pvStore->end(), physVol) - pvStore->begin();
 
  433   G4LogicalVolume* logVol = physVol->GetLogicalVolume();
 
  434   int lvIndex = std::find(lvStore->begin(), lvStore->end(), logVol) - lvStore->begin();
 
  435   for (
size_t daughter = 0; daughter < logVol->GetNoDaughters(); ++daughter) {
 
  436     G4VPhysicalVolume* dPhysVol = logVol->GetDaughter(daughter);
 
  437     (*m_PVIndex)[lvIndex].push_back(std::find(pvStore->begin(), pvStore->end(), dPhysVol) - pvStore->begin());
 
  441   int solidIndex = std::find(solidStore->begin(), solidStore->end(), logVol->GetSolid()) - solidStore->begin();
 
  447   m_File << 
"#VRML V2.0 utf8" << std::endl << std::endl <<
 
  448          "WorldInfo {" << std::endl <<
 
  449          "  info [ \"(c) The Belle II Collaboration\" ]" << std::endl <<
 
  450          "  title \"The Belle II Detector\"" << std::endl <<
 
  452          "Viewpoint {" << std::endl <<
 
  453          " position 0 0 15000" << std::endl <<
 
  454          " description \"front\"" << std::endl <<
 
  456          "Viewpoint {" << std::endl <<
 
  457          " position 0 0 -15000" << std::endl <<
 
  458          " orientation 0 1 0 3.141593" << std::endl <<
 
  459          " description \"back\"" << std::endl <<
 
  461          "Viewpoint {" << std::endl <<
 
  462          " position 0 15000 0" << std::endl <<
 
  463          " orientation 1 0 0 -1.570796" << std::endl <<
 
  464          " description \"top\"" << std::endl <<
 
  466          "Viewpoint {" << std::endl <<
 
  467          " position 0 -15000 0" << std::endl <<
 
  468          " orientation 1 0 0 1.570796" << std::endl <<
 
  469          " description \"bottom\"" << std::endl <<
 
  471          "Viewpoint {" << std::endl <<
 
  472          " position 15000 0 0" << std::endl <<
 
  473          " orientation 0 1 0 1.570796" << std::endl <<
 
  474          " description \"right\"" << std::endl <<
 
  476          "Viewpoint {" << std::endl <<
 
  477          " position -15000 0 0" << std::endl <<
 
  478          " orientation 0 1 0 -1.570796" << std::endl <<
 
  479          " description \"left\"" << std::endl <<
 
  486     m_File << 
"PROTO solid_" << name << 
" [ ] {" << std::endl <<
 
  487            " IndexedFaceSet {" << std::endl <<
 
  488            "  coord Coordinate {" << std::endl <<
 
  489            "   point [" << std::endl;
 
  490     for (
int j = 1; j <= polyhedron->GetNoVertices(); ++j) {
 
  491       m_File << 
"    " << polyhedron->GetVertex(j).x() << 
" " <<
 
  492              polyhedron->GetVertex(j).y() << 
" " <<
 
  493              polyhedron->GetVertex(j).z() << std::endl;
 
  495     m_File << 
"   ]" << std::endl <<
 
  497            "  coordIndex [" << std::endl;
 
  498     for (
int j = 0; j < polyhedron->GetNoFacets(); ++j) {
 
  499       G4bool notLastEdge = 
true;
 
  500       G4int ndx = -1, edgeFlag = 1;
 
  503         notLastEdge = polyhedron->GetNextVertexIndex(ndx, edgeFlag);
 
  505       } 
while (notLastEdge);
 
  506       m_File << 
" -1" << std::endl;
 
  508     m_File << 
"  ]" << std::endl <<
 
  512     B2INFO(
"Polyhedron representation of solid " << name << 
" cannot be created");
 
  520     m_File << 
"   USE " << pvName << std::endl; 
 
  522     m_File << 
"   # PhysicalVolume " << physVol->GetName() << 
" copy " << physVol->GetCopyNo() << std::endl <<
 
  523            "   DEF " << pvName << 
" Transform {" << std::endl; 
 
  524     G4RotationMatrix* rot = physVol->GetObjectRotation();
 
  525     G4ThreeVector move = physVol->GetObjectTranslation();
 
  526     double yaw = std::atan2(rot->yx(), rot->xx());
 
  527     double pitch = -std::asin(rot->zx());
 
  528     double roll = std::atan2(rot->zy(), rot->zz());
 
  529     std::cout << physVol->GetName() << 
" translation: " << move.x() << 
"," << move.y() << 
"," << move.z() << std::endl;
 
  530     std::cout << physVol->GetName() << 
" rotation: " << yaw * 180.0 / M_PI << 
"," << pitch * 180.0 / M_PI << 
"," << roll * 180.0 / M_PI
 
  532     if (move.mag2() != 0.0) {
 
  533       m_File << 
"    translation " << std::setprecision(10) <<
 
  534              move.x() << 
" " << move.y() << 
" " << move.z() << std::endl;
 
  536     if (!(rot->isIdentity())) {
 
  537       double trace = std::max(-1.0, std::min(3.0, rot->xx() + rot->yy() + rot->zz()));
 
  538       double angle = std::acos(0.5 * (trace - 1.0));
 
  539       G4ThreeVector rotA(rot->zy() - rot->yz(), rot->xz() - rot->zx(), rot->yx() - rot->xy());
 
  540       if ((rotA.x() == 0.0) && (rotA.y() == 0.0) && (rotA.z() == 0.0)) {
 
  543         if (rot->xx() > 0.0) {
 
  544           rotA.setX((rot->yy() - 1.0) * (rot->zz() - 1.0) -  rot->yz()        *  rot->zy());
 
  545           rotA.setY(rot->yz()        *  rot->zx()        -  rot->yx()        * (rot->zz() - 1.0));
 
  546           rotA.setZ(rot->yx()        *  rot->zy()        -  rot->zx()        * (rot->yy() - 1.0));
 
  547         } 
else if (rot->yy() > 0.0) {
 
  548           rotA.setX(rot->xy()        * (rot->zz() - 1.0) -  rot->xz()        *  rot->zy());
 
  549           rotA.setY(rot->xz()        *  rot->zx()        - (rot->xx() - 1.0) * (rot->zz() - 1.0));
 
  550           rotA.setZ((rot->xx() - 1.0) *  rot->zy()        -  rot->xy()        *  rot->zx());
 
  552           rotA.setX(rot->xy()        *  rot->yz()        -  rot->xz()        * (rot->yy() - 1.0));
 
  553           rotA.setY(rot->xz()        *  rot->yx()        -  rot->yz()        * (rot->xx() - 1.0));
 
  554           rotA.setZ((rot->xx() - 1.0) * (rot->yy() - 1.0) -  rot->xy()        *  rot->yx());
 
  558       m_File << 
"    rotation " << std::setprecision(10) <<
 
  559              rotA.x() << 
" " << rotA.y() << 
" " << rotA.z() << 
" " << angle << std::endl;
 
  561     m_File << 
"    children lv_" << lvName << 
"{}" << std::endl <<
 
  570   G4VSolid* solidA = solid->GetConstituentSolid(0);
 
  571   G4VSolid* solidB = solid->GetConstituentSolid(1);
 
  572   HepPolyhedron* polyhedronA = 
nullptr;
 
  573   if ((solidA->GetEntityType() == 
"G4IntersectionSolid") ||
 
  574       (solidA->GetEntityType() == 
"G4UnionSolid") ||
 
  575       (solidA->GetEntityType() == 
"G4SubtractionSolid") ||
 
  576       (solidA->GetEntityType() == 
"G4BooleanSolid")) {
 
  579     polyhedronA = 
new HepPolyhedron(*(solidA->GetPolyhedron()));
 
  581   HepPolyhedron* polyhedronB = 
nullptr;
 
  582   G4VSolid* solidB2 = solidB;
 
  583   if (solidB->GetEntityType() == 
"G4DisplacedSolid") {
 
  584     solidB2 = ((G4DisplacedSolid*)solidB)->GetConstituentMovedSolid();
 
  586   if ((solidB2->GetEntityType() == 
"G4IntersectionSolid") ||
 
  587       (solidB2->GetEntityType() == 
"G4UnionSolid") ||
 
  588       (solidB2->GetEntityType() == 
"G4SubtractionSolid") ||
 
  589       (solidB2->GetEntityType() == 
"G4BooleanSolid")) {
 
  591     if (solidB != solidB2) { 
 
  592       polyhedronB->Transform(G4Transform3D(
 
  593                                ((G4DisplacedSolid*)solidB)->GetObjectRotation(),
 
  594                                ((G4DisplacedSolid*)solidB)->GetObjectTranslation()));
 
  597     polyhedronB = 
new HepPolyhedron(*(solidB->GetPolyhedron()));
 
  599   auto* result = 
new HepPolyhedron();
 
  600   if (solid->GetEntityType() == 
"G4UnionSolid") {
 
  601     *result = polyhedronA->add(*polyhedronB);
 
  602   } 
else if (solid->GetEntityType() == 
"G4SubtractionSolid") {
 
  603     *result = polyhedronA->subtract(*polyhedronB);
 
  604   } 
else if (solid->GetEntityType() == 
"G4IntersectionSolid") {
 
  605     *result = polyhedronA->intersect(*polyhedronB);
 
  607     B2WARNING(
"getBooleanSolidPolyhedron(): Unrecognized boolean solid " << solid->GetName() <<
 
  608               " of type " << solid->GetEntityType());
 
void setDescription(const std::string &description)
Sets the description of the module.
void describeSolid(G4VSolid *, const std::string &, bool)
Emit VRML for each solid.
VRMLWriterModule()
Constructor of the module.
void writePolyhedron(const G4Polyhedron *, const std::string &)
Emit VRML for the solid's polyhedron.
void initialize() override
Initialize at the start of a job.
void event() override
Called for each event: this runs the VRML writer only for the first event.
void writePhysicalVolume(const G4VPhysicalVolume *, const std::string &, const std::string &, bool)
Emit VRML for each daughter of a logical volume.
void descendAndDescribe(G4VPhysicalVolume *, const std::string &, int)
Emit VRML for a physical volume (recursive)
std::ofstream m_File
Output file.
void writePreamble(void)
Emit VRML for the start of the file.
bool m_First
Once-only flag to write VRML only on the first event.
std::vector< std::vector< int > > * m_PVIndex
Indices (in G4PhysicalVolumeStore) of the logical volume's physical-volume daughters.
void assignName(std::vector< std::string > *, unsigned int, const G4String &, int)
Create unique and legal name for each solid.
std::vector< bool > * m_IsCylinder
Flag to indicate that a solid can be rendered as a VMRL cylinder.
std::string m_Filename
User-specified output filename.
std::vector< bool > * m_PVWritten
Flag to indicate that the physical volume has already been written.
std::vector< std::string > * m_PVName
Modified (legal-character and unique) physical-volume name.
std::vector< std::string > * m_SolidName
Modified (legal-character and unique) solid name.
void describeLogicalVolume(G4LogicalVolume *, const std::string &, const std::string &, bool)
Emit VRML for each logical volume.
std::vector< bool > * m_LVWritten
Flag to indicate that the logical volume has already been written.
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 describePhysicalVolume(G4VPhysicalVolume *)
Access next physical volume in the tree (recursive)
static GeometryManager & getInstance()
Return a reference to the instance.
G4VPhysicalVolume * getTopVolume()
Return a pointer to the top volume.
REG_MODULE(B2BIIConvertBeamParams)
Register the module.
void addParam(const std::string &name, T ¶mVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Abstract base class for different kinds of events.