GDML Export Implementation ========================== Intend to borrow from here for Collada export, so need to know details of the exporter implementation. * http://www-geant4.kek.jp/Reference/9.6.p02/classG4GDMLWrite.html Inverted inheritance chain structure:: G4GDMLWrite < ... < G4GDMLWriteStructure Contary to expectations from the name `G4GDMLWriteStructure` is top dog inheriting from all the other `G4GDMLWrite*` classes including `G4GDMLWrite` at the base. Inheritance misused for categorisation. $DYB/NuWa-trunk/lhcb/Sim/GaussTools/src/Components/GiGaRunActionGDML.cpp:: 55 G4VPhysicalVolume* wpv = G4TransportationManager::GetTransportationManager()-> 56 GetNavigatorForTracking()->GetWorldVolume(); 57 58 G4String outFilePath("g4_00.gdml"); 59 G4GDMLParser parser ; 60 if(wpv) 61 { 62 std::cout << "GiGaRunActionGDML::BeginOfRunAction writing to " << m_outFilePath << std::endl ; 63 parser.Write(outFilePath, wpv); 64 } $DYB/external/build/LCG/geant4.9.2.p01/source/persistency/gdml/src/G4GDMLParser.cc:: 37 G4GDMLParser::G4GDMLParser() 38 : ucode(false) 39 { 40 reader = new G4GDMLReadStructure; 41 writer = new G4GDMLWriteStructure; 42 xercesc::XMLPlatformUtils::Initialize(); 43 } $DYB/external/build/LCG/geant4.9.2.p01/source/persistency/gdml/include/G4GDMLParser.icc:: 47 inline 48 void G4GDMLParser::Write(const G4String& filename, 49 const G4VPhysicalVolume* const pvol, 50 G4bool refs, 51 const G4String& schemaLocation) 52 { 53 const G4int depth = 0; 54 G4LogicalVolume* lvol = 0; 55 56 if (!pvol) 57 { 58 G4VPhysicalVolume* worldPV = GetWorldVolume(); 59 if (!worldPV) 60 { 61 G4Exception("G4DMLParser::Write()", "InvalidSetup", FatalException, 62 "Detector-Construction needs to be registered first!"); 63 } 64 lvol = worldPV->GetLogicalVolume(); 65 } 66 else 67 { 68 lvol = pvol->GetLogicalVolume(); 69 } 70 writer->Write(filename,lvol,schemaLocation,depth,refs); 71 } $DYB/external/build/LCG/geant4.9.2.p01/source/persistency/gdml/src/G4GDMLWrite.cc:: 107 G4Transform3D G4GDMLWrite::Write(const G4String& fname, 108 const G4LogicalVolume* const logvol, 109 const G4String& setSchemaLocation, 110 const G4int depth, 111 G4bool refs) 112 { /// /// xercesc XML writer/doc setup /// 161 DefineWrite(gdml); // open "define" element 162 MaterialsWrite(gdml); // open "materials" element and clear materialsList, isotopeList 163 SolidsWrite(gdml); // open "solids" element and clear solidsList 164 StructureWrite(gdml); // open "structure" element 165 SetupWrite(gdml,logvol); // open "setup" element and populate 166 167 G4Transform3D R = TraverseVolumeTree(logvol,depth); // the meat, kicking off the recursive traverse 168 /// /// xercesc XML writing /// 216 return R; 217 } $DYB/external/build/LCG/geant4.9.2.p01/source/persistency/gdml/src/G4GDMLWriteStructure.cc:: 189 G4Transform3D G4GDMLWriteStructure:: 190 TraverseVolumeTree(const G4LogicalVolume* const volumePtr, const G4int depth) 191 { 192 if (VolumeMap().find(volumePtr) != VolumeMap().end()) 193 { 194 return VolumeMap()[volumePtr]; // Volume is already processed 195 } 196 197 G4VSolid* solidPtr = volumePtr->GetSolid(); 198 G4Transform3D R,invR; /// /// reflected solid handling skipped /// 235 const G4String name 236 = GenerateName(volumePtr->GetName(),volumePtr); // lvName 237 const G4String materialref 238 = GenerateName(volumePtr->GetMaterial()->GetName(), 239 volumePtr->GetMaterial()); 240 const G4String solidref 241 = GenerateName(solidPtr->GetName(),solidPtr); ... ... prep the volumeElement using name/materialref/solidref but dont append to structure yet ... ... 2181 ... 2182 ... 2183 ... ... 232 if (reflected>0) { invR = R.inverse(); } 233 // Only compute the inverse when necessary! ... 252 const G4int daughterCount = volumePtr->GetNoDaughters(); 253 254 for (G4int i=0;iGetDaughter(i); 257 const G4String ModuleName = Modularize(physvol,depth); 258 259 G4Transform3D daughterR; 260 261 if (ModuleName.empty()) // Check if subtree requested to be 262 { // a separate module! 263 daughterR = TraverseVolumeTree(physvol->GetLogicalVolume(),depth+1); ... ... Q: hmm, how come not getting a deeper GDML structure then ? ... A: because no matter what depth of the recursion the resulting volumeElement with 0 or more child physvol ... are appended to the fixed structureElement gdml/structure/ ... 264 } 265 else 266 { 267 G4GDMLWriteStructure writer; 268 daughterR = writer.Write(ModuleName,physvol->GetLogicalVolume(), 269 SchemaLocation,depth+1); 270 } ... 272 if (const G4PVDivision* const divisionvol 273 = dynamic_cast(physvol)) // Is it division? 274 { /// /// divisional/replica/parameterized skipped /// 309 else // Is it a physvol? 310 { 311 G4RotationMatrix rot; 312 313 if (physvol->GetFrameRotation() != 0) 314 { 315 rot = *(physvol->GetFrameRotation()); 316 } 317 G4Transform3D P(rot,physvol->GetObjectTranslation()); // placement transform of daughter pv wrt mother 318 PhysvolWrite(volumeElement,physvol,invR*P*daughterR,ModuleName); ... ... R, invR are identity transforms when not dealing with reflections.. ? ... 319 } 320 } 321 322 structureElement->appendChild(volumeElement); 323 // Append the volume AFTER traversing the children so that 324 // the order of volumes will be correct! 325 326 VolumeMap()[volumePtr] = R; 327 328 G4GDMLWriteMaterials::AddMaterial(volumePtr->GetMaterial()); 329 // Add the involved materials and solids! 330 331 G4GDMLWriteSolids::AddSolid(solidPtr); 332 333 return R; 334 } :: 76 void G4GDMLWriteStructure::PhysvolWrite(xercesc::DOMElement* volumeElement, 77 const G4VPhysicalVolume* const physvol, 78 const G4Transform3D& T, 79 const G4String& ModuleName) 80 { 81 HepGeom::Scale3D scale; 82 HepGeom::Rotate3D rotate; 83 HepGeom::Translate3D translate; 84 85 T.getDecomposition(scale,rotate,translate); 86 87 const G4ThreeVector scl(scale(0,0),scale(1,1),scale(2,2)); 88 const G4ThreeVector rot = GetAngles(rotate.getRotation()); 89 const G4ThreeVector pos = T.getTranslation(); 90 91 const G4String name = GenerateName(physvol->GetName(),physvol); 92 93 xercesc::DOMElement* physvolElement = NewElement("physvol"); 94 physvolElement->setAttributeNode(NewAttribute("name",name)); 95 volumeElement->appendChild(physvolElement); 96 97 const G4String volumeref 98 = GenerateName(physvol->GetLogicalVolume()->GetName(), 99 physvol->GetLogicalVolume()); 100 101 if (ModuleName.empty()) 102 { 103 xercesc::DOMElement* volumerefElement = NewElement("volumeref"); 104 volumerefElement->setAttributeNode(NewAttribute("ref",volumeref)); 105 physvolElement->appendChild(volumerefElement); 106 } ... ... physvol are the children of the mother lv. ... volumeref/@ref point to the lv of the child physvol ... ... 2181 ... 2182 ... 2183 ... 2184 ... 2185 ... 2186 ... 2187 ... 2188 ... ... 107 else 108 { 109 xercesc::DOMElement* fileElement = NewElement("file"); 110 fileElement->setAttributeNode(NewAttribute("name",ModuleName)); 111 fileElement->setAttributeNode(NewAttribute("volname",volumeref)); 112 physvolElement->appendChild(fileElement); 113 } 114 115 if (std::fabs(pos.x()) > kLinearPrecision 116 || std::fabs(pos.y()) > kLinearPrecision 117 || std::fabs(pos.z()) > kLinearPrecision) 118 { 119 PositionWrite(physvolElement,name+"_pos",pos); 120 } 121 if (std::fabs(rot.x()) > kAngularPrecision 122 || std::fabs(rot.y()) > kAngularPrecision 123 || std::fabs(rot.z()) > kAngularPrecision) 124 { 125 RotationWrite(physvolElement,name+"_rot",rot); 126 } 127 if (std::fabs(scl.x()-1.0) > kRelativePrecision 128 || std::fabs(scl.y()-1.0) > kRelativePrecision 129 || std::fabs(scl.z()-1.0) > kRelativePrecision) 130 { 131 ScaleWrite(physvolElement,name+"_scl",scl); 132 } 133 } $LOCAL_BASE/env/geant4/geometry/gdml/g4_01.gdml:: ... ... structure only goes to two levels ? structure/volume/physvol/volumeref ... presumably depth heirarchy being repesented via the volumeref linking up multiple such relations ... ... Logical volumes with @name are pointed to by physvol/volumeref/@ref ... 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 .... 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 .... 30919 30920 30921 30922 30923 30924 30925 30926 30927 30928 30929 30930 30931 30932 30933 30934 30935 30936 30937 30938 30939 30940 $LOCAL_BASE/env/geant4/geometry/gdml/g4_01.gdml:: 1 2 3 4 5 6 7 8 9 10 11 12 13 14

15 16 17 18 .. 401 402 403 404 405 406 407 408 409 ... 2172 .... .... dealt with above .... 30940 30941 30942 30943 30944 30945 30946