Geant4 Cross Reference |
1 // 1 2 // ******************************************* 3 // * License and Disclaimer 4 // * 5 // * The Geant4 software is copyright of th 6 // * the Geant4 Collaboration. It is provided 7 // * conditions of the Geant4 Software License 8 // * LICENSE and available at http://cern.ch/ 9 // * include a list of copyright holders. 10 // * 11 // * Neither the authors of this software syst 12 // * institutes,nor the agencies providing fin 13 // * work make any representation or warran 14 // * regarding this software system or assum 15 // * use. Please see the license in the file 16 // * for the full disclaimer and the limitatio 17 // * 18 // * This code implementation is the result 19 // * technical work of the GEANT4 collaboratio 20 // * By using, copying, modifying or distri 21 // * any work based on the software) you ag 22 // * use in resulting scientific publicati 23 // * acceptance of all terms of the Geant4 Sof 24 // ******************************************* 25 // 26 // G4STRead implementation 27 // 28 // Author: Zoltan Torzsok, November 2007 29 // ------------------------------------------- 30 31 #include <fstream> 32 33 #include "G4STRead.hh" 34 35 #include "G4Material.hh" 36 #include "G4Box.hh" 37 #include "G4QuadrangularFacet.hh" 38 #include "G4TriangularFacet.hh" 39 #include "G4TessellatedSolid.hh" 40 #include "G4LogicalVolume.hh" 41 #include "G4PVPlacement.hh" 42 #include "G4AffineTransform.hh" 43 #include "G4VoxelLimits.hh" 44 45 // ------------------------------------------- 46 void G4STRead::TessellatedRead(const std::stri 47 { 48 if(tessellatedList.size() > 0) 49 { 50 tessellatedList.back()->SetSolidClosed(tru 51 // Finish the previous solid at first! 52 } 53 54 std::istringstream stream(line.substr(2)); 55 56 G4String name; 57 stream >> name; 58 59 G4TessellatedSolid* tessellated = new G4Tess 60 volumeMap[tessellated] = 61 new G4LogicalVolume(tessellated, solid_mat 62 tessellatedList.push_back(tessellated); 63 64 #ifdef G4VERBOSE 65 G4cout << "G4STRead: Reading solid: " << nam 66 #endif 67 } 68 69 // ------------------------------------------- 70 void G4STRead::FacetRead(const std::string& li 71 { 72 if(tessellatedList.size() == 0) 73 { 74 G4Exception("G4STRead::FacetRead()", "Read 75 "A solid must be defined befor 76 } 77 78 if(line[2] == '3') // Triangular facet 79 { 80 G4double x1, y1, z1; 81 G4double x2, y2, z2; 82 G4double x3, y3, z3; 83 84 std::istringstream stream(line.substr(4)); 85 stream >> x1 >> y1 >> z1 >> x2 >> y2 >> z2 86 tessellatedList.back()->AddFacet(new G4Tri 87 G4ThreeVector(x1, y1, z1), G4ThreeVector 88 G4ThreeVector(x3, y3, z3), ABSOLUTE)); 89 } 90 else if(line[2] == '4') // Quadrangular fac 91 { 92 G4double x1, y1, z1; 93 G4double x2, y2, z2; 94 G4double x3, y3, z3; 95 G4double x4, y4, z4; 96 97 std::istringstream stream(line.substr(4)); 98 stream >> x1 >> y1 >> z1 >> x2 >> y2 >> z2 99 z4; 100 tessellatedList.back()->AddFacet(new G4Qua 101 G4ThreeVector(x1, y1, z1), G4ThreeVector 102 G4ThreeVector(x3, y3, z3), G4ThreeVector 103 } 104 else 105 { 106 G4Exception("G4STRead::FacetRead()", "Read 107 "Number of vertices per facet 108 } 109 } 110 111 // ------------------------------------------- 112 void G4STRead::PhysvolRead(const std::string& 113 { 114 G4int level; 115 G4String name; 116 G4double r1, r2, r3; 117 G4double r4, r5, r6; 118 G4double r7, r8, r9; 119 G4double pX, pY, pZ; 120 G4double n1, n2, n3, n4, n5; 121 122 std::istringstream stream(line.substr(2)); 123 stream >> level >> name >> r1 >> r2 >> r3 >> 124 r7 >> r8 >> r9 >> n3 >> pX >> pY >> pZ >> 125 std::string::size_type idx = name.rfind("_") 126 if(idx != std::string::npos) 127 { 128 name.resize(idx); 129 } 130 else 131 { 132 G4Exception("G4STRead::PhysvolRead()", "Re 133 "Invalid input stream!"); 134 return; 135 } 136 137 G4cout << "G4STRead: Placing tessellated sol 138 139 G4TessellatedSolid* tessellated = nullptr; 140 141 for(std::size_t i = 0; i < tessellatedList.s 142 { // Find the volume for this physvol! 143 if(tessellatedList[i]->GetName() == G4Stri 144 { 145 tessellated = tessellatedList[i]; 146 break; 147 } 148 } 149 150 if(tessellated == nullptr) 151 { 152 G4String error_msg = "Referenced solid '" 153 G4Exception("G4STRead::PhysvolRead()", "Re 154 error_msg); 155 } 156 if(volumeMap.find(tessellated) == volumeMap. 157 { 158 G4String error_msg = "Referenced solid '" 159 "' is not associated 160 G4Exception("G4STRead::PhysvolRead()", "In 161 error_msg); 162 } 163 const G4RotationMatrix rot(G4ThreeVector(r1, 164 G4ThreeVector(r4, 165 G4ThreeVector(r7, 166 const G4ThreeVector pos(pX, pY, pZ); 167 168 new G4PVPlacement(G4Transform3D(rot.inverse( 169 name + "_PV", world_volume 170 // Note: INVERSE of rotation is needed!!! 171 172 G4double minx, miny, minz; 173 G4double maxx, maxy, maxz; 174 const G4VoxelLimits limits; 175 176 tessellated->CalculateExtent(kXAxis, limits, 177 minx, maxx); 178 tessellated->CalculateExtent(kYAxis, limits, 179 miny, maxy); 180 tessellated->CalculateExtent(kZAxis, limits, 181 minz, maxz); 182 183 if(world_extent.x() < std::fabs(minx)) 184 { 185 world_extent.setX(std::fabs(minx)); 186 } 187 if(world_extent.y() < std::fabs(miny)) 188 { 189 world_extent.setY(std::fabs(miny)); 190 } 191 if(world_extent.z() < std::fabs(minz)) 192 { 193 world_extent.setZ(std::fabs(minz)); 194 } 195 if(world_extent.x() < std::fabs(maxx)) 196 { 197 world_extent.setX(std::fabs(maxx)); 198 } 199 if(world_extent.y() < std::fabs(maxy)) 200 { 201 world_extent.setY(std::fabs(maxy)); 202 } 203 if(world_extent.z() < std::fabs(maxz)) 204 { 205 world_extent.setZ(std::fabs(maxz)); 206 } 207 } 208 209 // ------------------------------------------- 210 void G4STRead::ReadGeom(const G4String& name) 211 { 212 #ifdef G4VERBOSE 213 G4cout << "G4STRead: Reading '" << name << " 214 #endif 215 std::ifstream GeomFile(name); 216 217 if(!GeomFile) 218 { 219 G4String error_msg = "Cannot open file: " 220 G4Exception("G4STRead::ReadGeom()", "ReadE 221 } 222 223 tessellatedList.clear(); 224 volumeMap.clear(); 225 std::string line; 226 227 while(getline(GeomFile, line)) 228 { 229 if(line[0] == 'f') 230 { 231 TessellatedRead(line); 232 } 233 else if(line[0] == 'p') 234 { 235 FacetRead(line); 236 } 237 } 238 239 if(tessellatedList.size() > 0) // Finish th 240 { 241 tessellatedList.back()->SetSolidClosed(tru 242 } 243 244 G4cout << "G4STRead: Reading '" << name << " 245 } 246 247 // ------------------------------------------- 248 void G4STRead::ReadTree(const G4String& name) 249 { 250 #ifdef G4VERBOSE 251 G4cout << "G4STRead: Reading '" << name << " 252 #endif 253 std::ifstream TreeFile(name); 254 255 if(!TreeFile) 256 { 257 G4String error_msg = "Cannot open file: " 258 G4Exception("G4STRead::ReadTree()", "ReadE 259 } 260 261 std::string line; 262 263 while(getline(TreeFile, line)) 264 { 265 if(line[0] == 'g') 266 { 267 PhysvolRead(line); 268 } 269 } 270 271 G4cout << "G4STRead: Reading '" << name << " 272 } 273 274 // ------------------------------------------- 275 G4LogicalVolume* G4STRead::Read(const G4String 276 G4Material* me 277 G4Material* so 278 { 279 if(mediumMaterial == nullptr) 280 { 281 G4Exception("G4STRead::Read()", "InvalidSe 282 "Pointer to medium material is 283 } 284 if(solidMaterial == nullptr) 285 { 286 G4Exception("G4STRead::Read()", "InvalidSe 287 "Pointer to solid material is 288 } 289 290 solid_material = solidMaterial; 291 292 world_box = new G4Box("TessellatedWorldBox", 293 // We don't know the extent of the world yet 294 world_volume = new G4LogicalVolume(world_box 295 "Tessella 296 world_extent = G4ThreeVector(0, 0, 0); 297 298 ReadGeom(name + ".geom"); 299 ReadTree(name + ".tree"); 300 301 // Now setting the world extent ... 302 // 303 if(world_box->GetXHalfLength() > world_exten 304 { 305 world_box->SetXHalfLength(world_extent.x() 306 } 307 if(world_box->GetYHalfLength() > world_exten 308 { 309 world_box->SetYHalfLength(world_extent.y() 310 } 311 if(world_box->GetZHalfLength() > world_exten 312 { 313 world_box->SetZHalfLength(world_extent.z() 314 } 315 316 return world_volume; 317 } 318