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 // Implementation of G4UTessellatedSolid wrapp 27 // 28 // 11.01.18 G.Cosmo, CERN 29 // ------------------------------------------- 30 31 #include "G4TessellatedSolid.hh" 32 #include "G4UTessellatedSolid.hh" 33 34 #if ( defined(G4GEOM_USE_USOLIDS) || defined(G 35 36 #include "G4TriangularFacet.hh" 37 #include "G4QuadrangularFacet.hh" 38 39 #include "G4GeomTools.hh" 40 #include "G4AffineTransform.hh" 41 #include "G4BoundingEnvelope.hh" 42 43 ////////////////////////////////////////////// 44 // 45 // Constructors 46 // 47 G4UTessellatedSolid::G4UTessellatedSolid() 48 : Base_t("") 49 { 50 } 51 52 G4UTessellatedSolid::G4UTessellatedSolid(const 53 : Base_t(name) 54 { 55 } 56 57 ////////////////////////////////////////////// 58 // 59 // Fake default constructor - sets only member 60 // for usage restri 61 // 62 G4UTessellatedSolid::G4UTessellatedSolid(__voi 63 : Base_t(a) 64 { 65 } 66 67 ////////////////////////////////////////////// 68 // 69 // Destructor 70 // 71 G4UTessellatedSolid::~G4UTessellatedSolid() 72 { 73 std::size_t size = fFacets.size(); 74 for (std::size_t i = 0; i < size; ++i) { de 75 fFacets.clear(); 76 } 77 78 ////////////////////////////////////////////// 79 // 80 // Copy constructor 81 // 82 G4UTessellatedSolid::G4UTessellatedSolid(const 83 : Base_t(source) 84 { 85 } 86 87 ////////////////////////////////////////////// 88 // 89 // Assignment operator 90 // 91 G4UTessellatedSolid& 92 G4UTessellatedSolid::operator=(const G4UTessel 93 { 94 if (this == &source) return *this; 95 96 Base_t::operator=( source ); 97 98 return *this; 99 } 100 101 ////////////////////////////////////////////// 102 // 103 // Accessors 104 105 G4bool G4UTessellatedSolid::AddFacet(G4VFacet* 106 { 107 // Add a facet to the structure, checking va 108 // 109 if (GetSolidClosed()) 110 { 111 G4Exception("G4UTessellatedSolid::AddFacet 112 JustWarning, "Attempt to add f 113 return false; 114 } 115 if (!aFacet->IsDefined()) 116 { 117 G4Exception("G4UTessellatedSolid::AddFacet 118 JustWarning, "Attempt to add f 119 aFacet->StreamInfo(G4cout); 120 return false; 121 } 122 if (aFacet->GetNumberOfVertices() == 3) 123 { 124 auto a3Facet = dynamic_cast<G4TriangularFa 125 return Base_t::AddTriangularFacet(U3Vector 126 127 128 U3Vector 129 130 131 U3Vector 132 133 134 true); 135 } 136 else if (aFacet->GetNumberOfVertices() == 4) 137 { 138 auto a4Facet = dynamic_cast<G4Quadrangular 139 return Base_t::AddQuadrilateralFacet(U3Vec 140 141 142 U3Vec 143 144 145 U3Vec 146 147 148 U3Vec 149 150 151 true) 152 } 153 else 154 { 155 G4Exception("G4UTessellatedSolid::AddFacet 156 JustWarning, "Attempt to add f 157 aFacet->StreamInfo(G4cout); 158 return false; 159 } 160 } 161 162 G4VFacet* G4UTessellatedSolid::GetFacet(G4int 163 { 164 return fFacets[i]; 165 } 166 167 G4int G4UTessellatedSolid::GetNumberOfFacets() 168 { 169 return GetNFacets(); 170 } 171 172 void G4UTessellatedSolid::SetSolidClosed(const 173 { 174 if (t && !Base_t::IsClosed()) 175 { 176 Base_t::Close(); 177 std::size_t nVertices = fTessellated.fVert 178 std::size_t nFacets = fTessellated.fFace 179 for (std::size_t j = 0; j < nVertices; ++j 180 { 181 U3Vector vt = fTessellated.fVertices[j]; 182 fVertexList.emplace_back(vt.x(), vt.y(), 183 } 184 for (std::size_t i = 0; i < nFacets; ++i) 185 { 186 vecgeom::TriangleFacet<G4double>* afacet 187 std::vector<G4ThreeVector> v; 188 for (const auto & vertex : afacet->fVert 189 { 190 v.emplace_back(vertex.x(), 191 vertex.y(), 192 vertex.z()); 193 } 194 G4VFacet* facet = new G4TriangularFacet( 195 196 facet->SetVertices(&fVertexList); 197 for (G4int k=0; k<3; ++k) 198 { 199 facet->SetVertexIndex(k, afacet->fIndi 200 } 201 fFacets.push_back(facet); 202 } 203 } 204 } 205 206 G4bool G4UTessellatedSolid::GetSolidClosed() c 207 { 208 return Base_t::IsClosed(); 209 } 210 211 void G4UTessellatedSolid::SetMaxVoxels(G4int) 212 { 213 // Not yet implemented ! 214 } 215 216 G4double G4UTessellatedSolid::GetMinXExtent() 217 { 218 U3Vector aMin, aMax; 219 Base_t::Extent(aMin, aMax); 220 return aMin.x(); 221 } 222 G4double G4UTessellatedSolid::GetMaxXExtent() 223 { 224 U3Vector aMin, aMax; 225 Base_t::Extent(aMin, aMax); 226 return aMax.x(); 227 } 228 G4double G4UTessellatedSolid::GetMinYExtent() 229 { 230 U3Vector aMin, aMax; 231 Base_t::Extent(aMin, aMax); 232 return aMin.y(); 233 } 234 G4double G4UTessellatedSolid::GetMaxYExtent() 235 { 236 U3Vector aMin, aMax; 237 Base_t::Extent(aMin, aMax); 238 return aMax.y(); 239 } 240 G4double G4UTessellatedSolid::GetMinZExtent() 241 { 242 U3Vector aMin, aMax; 243 Base_t::Extent(aMin, aMax); 244 return aMin.z(); 245 } 246 G4double G4UTessellatedSolid::GetMaxZExtent() 247 { 248 U3Vector aMin, aMax; 249 Base_t::Extent(aMin, aMax); 250 return aMax.z(); 251 } 252 253 G4int G4UTessellatedSolid::AllocatedMemoryWith 254 { 255 G4int base = sizeof(*this); 256 base += fVertexList.capacity() * sizeof(G4Th 257 258 std::size_t limit = fFacets.size(); 259 for (std::size_t i = 0; i < limit; ++i) 260 { 261 G4VFacet &facet = *fFacets[i]; 262 base += facet.AllocatedMemory(); 263 } 264 return base; 265 } 266 G4int G4UTessellatedSolid::AllocatedMemory() 267 { 268 return AllocatedMemoryWithoutVoxels(); 269 } 270 void G4UTessellatedSolid::DisplayAllocatedMemo 271 { 272 G4int without = AllocatedMemoryWithoutVoxels 273 // G4int with = AllocatedMemory(); 274 // G4double ratio = (G4double) with / witho 275 // G4cout << "G4TessellatedSolid - Allocate 276 // << without << "; with " << with < 277 G4cout << "G4TessellatedSolid - Allocated me 278 << without << G4endl; 279 } 280 281 282 ////////////////////////////////////////////// 283 // 284 // Get bounding box 285 286 void G4UTessellatedSolid::BoundingLimits(G4Thr 287 G4Thr 288 { 289 U3Vector aMin, aMax; 290 Base_t::Extent(aMin, aMax); 291 pMin = G4ThreeVector(aMin.x(), aMin.y(), aMi 292 pMax = G4ThreeVector(aMax.x(), aMax.y(), aMa 293 294 // Check correctness of the bounding box 295 // 296 if (pMin.x() >= pMax.x() || pMin.y() >= pMax 297 { 298 std::ostringstream message; 299 message << "Bad bounding box (min >= max) 300 << GetName() << " !" 301 << "\npMin = " << pMin 302 << "\npMax = " << pMax; 303 G4Exception("G4UTessellatedSolid::Bounding 304 "GeomMgt0001", JustWarning, me 305 StreamInfo(G4cout); 306 } 307 } 308 309 310 ////////////////////////////////////////////// 311 // 312 // Calculate extent under transform and specif 313 314 G4bool 315 G4UTessellatedSolid::CalculateExtent(const EAx 316 const G4V 317 const G4A 318 G4d 319 { 320 G4ThreeVector bmin, bmax; 321 322 // Check bounding box (bbox) 323 // 324 BoundingLimits(bmin,bmax); 325 G4BoundingEnvelope bbox(bmin,bmax); 326 327 // Use simple bounding-box to help in the ca 328 // 329 return bbox.CalculateExtent(pAxis,pVoxelLimi 330 331 #if 0 332 // Precise extent computation (disabled by d 333 // 334 G4double kCarToleranceHalf = 0.5*kCarToleran 335 if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVox 336 { 337 return (pMin < pMax) ? true : false; 338 } 339 340 // The extent is calculated as cumulative ex 341 // formed by facets and the center of the bo 342 // 343 G4double eminlim = pVoxelLimit.GetMinExtent( 344 G4double emaxlim = pVoxelLimit.GetMaxExtent( 345 346 G4ThreeVectorList base; 347 G4ThreeVectorList apex(1); 348 std::vector<const G4ThreeVectorList *> pyram 349 pyramid[0] = &base; 350 pyramid[1] = &apex; 351 apex[0] = (bmin+bmax)*0.5; 352 353 // main loop along facets 354 pMin = kInfinity; 355 pMax = -kInfinity; 356 for (G4int i=0; i<GetNumberOfFacets(); ++i) 357 { 358 G4VFacet* facet = GetFacet(i); 359 if (std::abs((facet->GetSurfaceNormal()).d 360 < kCarToleranceHalf) continue; 361 362 base.resize(3); 363 for (G4int k=0; k<3; ++k) { base[k] = face 364 G4double emin,emax; 365 G4BoundingEnvelope benv(pyramid); 366 if (!benv.CalculateExtent(pAxis,pVoxelLimi 367 if (emin < pMin) pMin = emin; 368 if (emax > pMax) pMax = emax; 369 if (eminlim > pMin && emaxlim < pMax) brea 370 } 371 return (pMin < pMax); 372 #endif 373 } 374 375 376 ////////////////////////////////////////////// 377 // 378 // CreatePolyhedron() 379 // 380 G4Polyhedron* G4UTessellatedSolid::CreatePolyh 381 { 382 auto nVertices = (G4int)fVertexList.size(); 383 auto nFacets = (G4int)fFacets.size(); 384 auto polyhedron = new G4Polyhedron(nVertices 385 for (auto i = 0; i < nVertices; ++i) 386 { 387 polyhedron->SetVertex(i+1, fVertexList[i]) 388 } 389 390 for (auto i = 0; i < nFacets; ++i) 391 { 392 G4int v[3]; // Only facets with 3 vertice 393 G4VFacet* facet = GetFacet(i); 394 for (auto j = 0; j < 3; ++j) // Retrieve i 395 { 396 v[j] = facet->GetVertexIndex(j) + 1; 397 } 398 polyhedron->SetFacet(i+1, v[0], v[1], v[2] 399 } 400 polyhedron->SetReferences(); 401 402 return polyhedron; 403 } 404 405 #endif // G4GEOM_USE_USOLIDS 406