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 for G4ReflectedSolid class 27 // 28 // Author: Vladimir Grichine, 23.07.01 (Vladi 29 // ------------------------------------------- 30 31 #include "G4ReflectedSolid.hh" 32 33 #include <sstream> 34 35 #include "G4Point3D.hh" 36 #include "G4Vector3D.hh" 37 38 #include "G4AffineTransform.hh" 39 #include "G4Transform3D.hh" 40 #include "G4VoxelLimits.hh" 41 42 #include "G4VPVParameterisation.hh" 43 44 #include "G4VGraphicsScene.hh" 45 #include "G4Polyhedron.hh" 46 47 ////////////////////////////////////////////// 48 // 49 // Constructor using HepTransform3D, in fact H 50 51 G4ReflectedSolid::G4ReflectedSolid( const G4St 52 G4VS 53 const G4Tr 54 : G4VSolid(pName) 55 { 56 fPtrSolid = pSolid; 57 fDirectTransform3D = new G4Transform3D(trans 58 } 59 60 ////////////////////////////////////////////// 61 // 62 63 G4ReflectedSolid::~G4ReflectedSolid() 64 { 65 delete fDirectTransform3D; fDirectTransform3 66 delete fpPolyhedron; fpPolyhedron = nullptr; 67 } 68 69 ////////////////////////////////////////////// 70 // 71 72 G4ReflectedSolid::G4ReflectedSolid(const G4Ref 73 : G4VSolid(rhs), fPtrSolid(rhs.fPtrSolid) 74 { 75 fDirectTransform3D = new G4Transform3D(*rhs. 76 } 77 78 ////////////////////////////////////////////// 79 // 80 81 G4ReflectedSolid& G4ReflectedSolid::operator=( 82 { 83 // Check assignment to self 84 // 85 if (this == &rhs) { return *this; } 86 87 // Copy base class data 88 // 89 G4VSolid::operator=(rhs); 90 91 // Copy data 92 // 93 fPtrSolid = rhs.fPtrSolid; 94 delete fDirectTransform3D; 95 fDirectTransform3D = new G4Transform3D(*rhs. 96 fRebuildPolyhedron = false; 97 delete fpPolyhedron; fpPolyhedron = nullptr; 98 99 return *this; 100 } 101 102 ////////////////////////////////////////////// 103 // 104 105 G4GeometryType G4ReflectedSolid::GetEntityType 106 { 107 return {"G4ReflectedSolid"}; 108 } 109 110 const G4ReflectedSolid* G4ReflectedSolid::GetR 111 { 112 return this; 113 } 114 115 G4ReflectedSolid* G4ReflectedSolid::GetReflect 116 { 117 return this; 118 } 119 120 G4VSolid* G4ReflectedSolid::GetConstituentMove 121 { 122 return fPtrSolid; 123 } 124 125 ////////////////////////////////////////////// 126 // 127 128 G4Transform3D G4ReflectedSolid::GetTransform3 129 { 130 return fDirectTransform3D->inverse(); 131 } 132 133 G4Transform3D G4ReflectedSolid::GetDirectTran 134 { 135 G4Transform3D aTransform = *fDirectTransform 136 return aTransform; 137 } 138 139 void G4ReflectedSolid::SetDirectTransform3D(G4 140 { 141 fDirectTransform3D = &transform; 142 fRebuildPolyhedron = true; 143 } 144 145 ////////////////////////////////////////////// 146 // 147 // Get bounding box 148 149 void G4ReflectedSolid::BoundingLimits(G4ThreeV 150 G4ThreeV 151 { 152 fPtrSolid->BoundingLimits(pMin,pMax); 153 G4double xmin = pMin.x(), ymin = pMin.y(), z 154 G4double xmax = pMax.x(), ymax = pMax.y(), z 155 G4double xx = fDirectTransform3D->xx(); 156 G4double yy = fDirectTransform3D->yy(); 157 G4double zz = fDirectTransform3D->zz(); 158 159 if (std::abs(xx) == 1 && std::abs(yy) == 1 & 160 { 161 // Special case of reflection in axis and 162 // 163 if (xx == -1) { G4double tmp = -xmin; xmin 164 if (yy == -1) { G4double tmp = -ymin; ymin 165 if (zz == -1) { G4double tmp = -zmin; zmin 166 xmin += fDirectTransform3D->dx(); 167 xmax += fDirectTransform3D->dx(); 168 ymin += fDirectTransform3D->dy(); 169 ymax += fDirectTransform3D->dy(); 170 zmin += fDirectTransform3D->dz(); 171 zmax += fDirectTransform3D->dz(); 172 } 173 else 174 { 175 // Use additional reflection in Z to set u 176 // 177 G4Transform3D transform3D = G4ReflectZ3D() 178 G4AffineTransform transform(transform3D.ge 179 transform3D.ge 180 181 // Find bounding box 182 // 183 G4VoxelLimits unLimit; 184 fPtrSolid->CalculateExtent(kXAxis,unLimit, 185 fPtrSolid->CalculateExtent(kYAxis,unLimit, 186 fPtrSolid->CalculateExtent(kZAxis,unLimit, 187 } 188 189 pMin.set(xmin,ymin,-zmax); 190 pMax.set(xmax,ymax,-zmin); 191 192 // Check correctness of the bounding box 193 // 194 if (pMin.x() >= pMax.x() || pMin.y() >= pMax 195 { 196 std::ostringstream message; 197 message << "Bad bounding box (min >= max) 198 << GetName() << " !" 199 << "\npMin = " << pMin 200 << "\npMax = " << pMax; 201 G4Exception("G4ReflectedSolid::BoundingLim 202 JustWarning, message); 203 DumpInfo(); 204 } 205 } 206 207 ////////////////////////////////////////////// 208 // 209 // Calculate extent under transform and specif 210 211 G4bool 212 G4ReflectedSolid::CalculateExtent( const EAxis 213 const G4Vox 214 const G4Aff 215 G4dou 216 G4dou 217 { 218 // Separation of transformations. Calculatio 219 // in a reflection of the global space. In s 220 // reflected, but the solid is transformed j 221 // It allows one to use CalculateExtent() of 222 223 // Reflect voxel limits in Z 224 // 225 G4VoxelLimits limits; 226 limits.AddLimit(kXAxis, pVoxelLimits.GetMinX 227 pVoxelLimits.GetMaxX 228 limits.AddLimit(kYAxis, pVoxelLimits.GetMinY 229 pVoxelLimits.GetMaxY 230 limits.AddLimit(kZAxis,-pVoxelLimits.GetMaxZ 231 -pVoxelLimits.GetMinZ 232 233 // Set affine transformation 234 // 235 G4Transform3D transform3D = G4ReflectZ3D()*p 236 G4AffineTransform transform(transform3D.getR 237 transform3D.getT 238 239 // Find extent 240 // 241 if (!fPtrSolid->CalculateExtent(pAxis, limit 242 { 243 return false; 244 } 245 if (pAxis == kZAxis) 246 { 247 G4double tmp= -pMin; pMin= -pMax; pMax= tm 248 } 249 250 return true; 251 } 252 253 ////////////////////////////////////////////// 254 // 255 // 256 257 EInside G4ReflectedSolid::Inside(const G4Three 258 { 259 G4ThreeVector newPoint = (*fDirectTransform3 260 return fPtrSolid->Inside(newPoint); 261 } 262 263 ////////////////////////////////////////////// 264 // 265 // 266 267 G4ThreeVector 268 G4ReflectedSolid::SurfaceNormal( const G4Three 269 { 270 G4ThreeVector newPoint = (*fDirectTransform3 271 G4Vector3D normal = fPtrSolid->SurfaceNormal 272 return (*fDirectTransform3D)*normal; 273 } 274 275 ////////////////////////////////////////////// 276 // 277 // The same algorithm as in DistanceToIn(p) 278 279 G4double 280 G4ReflectedSolid::DistanceToIn( const G4ThreeV 281 const G4ThreeV 282 { 283 G4ThreeVector newPoint = (*fDirectTransf 284 G4ThreeVector newDirection = (*fDirectTransf 285 return fPtrSolid->DistanceToIn(newPoint,newD 286 } 287 288 ////////////////////////////////////////////// 289 // 290 // Approximate nearest distance from the point 291 // two solids 292 293 G4double 294 G4ReflectedSolid::DistanceToIn( const G4ThreeV 295 { 296 G4ThreeVector newPoint = (*fDirectTransform3 297 return fPtrSolid->DistanceToIn(newPoint); 298 } 299 300 ////////////////////////////////////////////// 301 // 302 // The same algorithm as DistanceToOut(p) 303 304 G4double 305 G4ReflectedSolid::DistanceToOut( const G4Three 306 const G4Three 307 const G4bool 308 G4bool* 309 G4Three 310 { 311 G4ThreeVector solNorm; 312 313 G4ThreeVector newPoint = (*fDirectTransf 314 G4ThreeVector newDirection = (*fDirectTransf 315 316 G4double dist = fPtrSolid->DistanceToOut(new 317 cal 318 if(calcNorm) 319 { 320 *n = (*fDirectTransform3D)*G4Vector3D(solN 321 } 322 return dist; 323 } 324 325 ////////////////////////////////////////////// 326 // 327 // Inverted algorithm of DistanceToIn(p) 328 329 G4double 330 G4ReflectedSolid::DistanceToOut( const G4Three 331 { 332 G4ThreeVector newPoint = (*fDirectTransform3 333 return fPtrSolid->DistanceToOut(newPoint); 334 } 335 336 ////////////////////////////////////////////// 337 // 338 // 339 340 void 341 G4ReflectedSolid::ComputeDimensions( G4V 342 const G4i 343 const G4V 344 { 345 DumpInfo(); 346 G4Exception("G4ReflectedSolid::ComputeDimens 347 "GeomMgt0001", FatalException, 348 "Method not applicable in this 349 } 350 351 ////////////////////////////////////////////// 352 // 353 // Return volume 354 355 G4double G4ReflectedSolid::GetCubicVolume() 356 { 357 return fPtrSolid->GetCubicVolume(); 358 } 359 360 ////////////////////////////////////////////// 361 // 362 // Return surface area 363 364 G4double G4ReflectedSolid::GetSurfaceArea() 365 { 366 return fPtrSolid->GetSurfaceArea(); 367 } 368 369 ////////////////////////////////////////////// 370 // 371 // Return a point (G4ThreeVector) randomly and 372 // on the solid surface 373 374 G4ThreeVector G4ReflectedSolid::GetPointOnSurf 375 { 376 G4ThreeVector p = fPtrSolid->GetPointOnSur 377 return (*fDirectTransform3D)*G4Point3D(p); 378 } 379 380 ////////////////////////////////////////////// 381 // 382 // Return the number of constituents used for 383 // of the solid 384 385 G4int G4ReflectedSolid::GetNumOfConstituents() 386 { 387 return fPtrSolid->GetNumOfConstituents(); 388 } 389 390 ////////////////////////////////////////////// 391 // 392 // Return true if the reflected solid has only 393 394 G4bool G4ReflectedSolid::IsFaceted() const 395 { 396 return fPtrSolid->IsFaceted(); 397 } 398 399 ////////////////////////////////////////////// 400 // 401 // Make a clone of this object 402 403 G4VSolid* G4ReflectedSolid::Clone() const 404 { 405 return new G4ReflectedSolid(*this); 406 } 407 408 ////////////////////////////////////////////// 409 // 410 // Stream object contents to an output stream 411 412 std::ostream& G4ReflectedSolid::StreamInfo(std 413 { 414 os << "------------------------------------- 415 << " *** Dump for Reflected solid - " 416 << " ================================= 417 << " Solid type: " << GetEntityType() << 418 << " Parameters of constituent solid: \n" 419 << "===================================== 420 fPtrSolid->StreamInfo(os); 421 os << "===================================== 422 << " Transformations: \n" 423 << " Direct transformation - translati 424 << " " << fDirectTransform3D->g 425 << " - rotation 426 << " "; 427 fDirectTransform3D->getRotation().print(os); 428 os << "\n" 429 << "===================================== 430 431 return os; 432 } 433 434 ////////////////////////////////////////////// 435 // 436 // 437 438 void 439 G4ReflectedSolid::DescribeYourselfTo ( G4VGrap 440 { 441 scene.AddSolid (*this); 442 } 443 444 ////////////////////////////////////////////// 445 // 446 // 447 448 G4Polyhedron* 449 G4ReflectedSolid::CreatePolyhedron () const 450 { 451 G4Polyhedron* polyhedron = fPtrSolid->Create 452 if (polyhedron != nullptr) 453 { 454 polyhedron->Transform(*fDirectTransform3D) 455 return polyhedron; 456 } 457 else 458 { 459 std::ostringstream message; 460 message << "Solid - " << GetName() 461 << " - original solid has no" << G 462 << "corresponding polyhedron. Retu 463 G4Exception("G4ReflectedSolid::CreatePolyh 464 "GeomMgt1001", JustWarning, me 465 return nullptr; 466 } 467 } 468 469 ////////////////////////////////////////////// 470 // 471 // 472 473 G4Polyhedron* 474 G4ReflectedSolid::GetPolyhedron () const 475 { 476 if ((fpPolyhedron == nullptr) || fRebuildPol 477 (fpPolyhedron->GetNumberOfRotationStepsA 478 fpPolyhedron->GetNumberOfRotationSteps( 479 { 480 fpPolyhedron = CreatePolyhedron(); 481 fRebuildPolyhedron = false; 482 } 483 return fpPolyhedron; 484 } 485