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 G4DisplacedSolid class fo 27 // operations between other solids 28 // 29 // 28.10.98 V.Grichine: created 30 // 28.02.18 E.Tcherniaev: improved contruction 31 // ------------------------------------------- 32 33 #include "G4DisplacedSolid.hh" 34 35 #include "G4VoxelLimits.hh" 36 37 #include "G4VPVParameterisation.hh" 38 39 #include "G4VGraphicsScene.hh" 40 #include "G4Polyhedron.hh" 41 42 ////////////////////////////////////////////// 43 // 44 // Constructor for transformation like rotatio 45 // in new frame. It is similar to 1st constrac 46 47 G4DisplacedSolid::G4DisplacedSolid( const G4St 48 G4VS 49 G4Ro 50 const G4Th 51 : G4VSolid(pName) 52 { 53 if (pSolid->GetEntityType() == "G4DisplacedS 54 { 55 fPtrSolid = ((G4DisplacedSolid*)pSolid)->G 56 G4AffineTransform t1 = ((G4DisplacedSolid* 57 G4AffineTransform t2 = G4AffineTransform(r 58 fDirectTransform = new G4AffineTransform(t 59 } 60 else 61 { 62 fPtrSolid = pSolid; 63 fDirectTransform = new G4AffineTransform(r 64 } 65 fPtrTransform = new G4AffineTransform(fDirec 66 } 67 68 ////////////////////////////////////////////// 69 // 70 // Constructor 71 72 G4DisplacedSolid::G4DisplacedSolid( const G4St 73 G4VS 74 const G4Tr 75 : G4VSolid(pName) 76 { 77 if (pSolid->GetEntityType() == "G4DisplacedS 78 { 79 fPtrSolid = ((G4DisplacedSolid*)pSolid)->G 80 G4AffineTransform t1 = ((G4DisplacedSolid* 81 G4AffineTransform t2 = G4AffineTransform(t 82 t 83 fDirectTransform = new G4AffineTransform(t 84 } 85 else 86 { 87 fPtrSolid = pSolid; 88 fDirectTransform = new G4AffineTransform(t 89 t 90 } 91 fPtrTransform = new G4AffineTransform(fDirec 92 } 93 94 ////////////////////////////////////////////// 95 // 96 // Constructor for use with creation of Transi 97 // from Persistent object 98 99 G4DisplacedSolid::G4DisplacedSolid( const G4St 100 G4VS 101 const G4Af 102 : G4VSolid(pName) 103 { 104 if (pSolid->GetEntityType() == "G4DisplacedS 105 { 106 fPtrSolid = ((G4DisplacedSolid*)pSolid)->G 107 G4AffineTransform t1 = ((G4DisplacedSolid* 108 auto t2 = G4AffineTransform(directTransfo 109 fDirectTransform = new G4AffineTransform(t 110 } 111 else 112 { 113 fPtrSolid = pSolid; 114 fDirectTransform = new G4AffineTransform(d 115 } 116 fPtrTransform = new G4AffineTransform(fDirec 117 } 118 119 ////////////////////////////////////////////// 120 // 121 // Fake default constructor - sets only member 122 // for usage restri 123 124 G4DisplacedSolid::G4DisplacedSolid( __void__& 125 : G4VSolid(a) 126 { 127 } 128 129 ////////////////////////////////////////////// 130 // 131 // Destructor 132 133 G4DisplacedSolid::~G4DisplacedSolid() 134 { 135 CleanTransformations(); 136 delete fpPolyhedron; fpPolyhedron = nullptr; 137 } 138 139 ////////////////////////////////////////////// 140 // 141 // Copy constructor 142 143 G4DisplacedSolid::G4DisplacedSolid(const G4Dis 144 : G4VSolid (rhs), fPtrSolid(rhs.fPtrSolid) 145 { 146 fPtrTransform = new G4AffineTransform(*(rhs. 147 fDirectTransform = new G4AffineTransform(*(r 148 } 149 150 ////////////////////////////////////////////// 151 // 152 // Assignment operator 153 154 G4DisplacedSolid& G4DisplacedSolid::operator = 155 { 156 // Check assignment to self 157 // 158 if (this == &rhs) { return *this; } 159 160 // Copy base class data 161 // 162 G4VSolid::operator=(rhs); 163 164 // Copy data 165 // 166 fPtrSolid = rhs.fPtrSolid; 167 delete fPtrTransform; delete fDirectTransfor 168 fPtrTransform = new G4AffineTransform(*(rhs. 169 fDirectTransform = new G4AffineTransform(*(r 170 fRebuildPolyhedron = false; 171 delete fpPolyhedron; fpPolyhedron = nullptr; 172 173 return *this; 174 } 175 176 void G4DisplacedSolid::CleanTransformations() 177 { 178 if(fPtrTransform != nullptr) 179 { 180 delete fPtrTransform; fPtrTransform = null 181 delete fDirectTransform; fDirectTransform 182 } 183 } 184 185 const G4DisplacedSolid* G4DisplacedSolid::GetD 186 { 187 return this; 188 } 189 190 G4DisplacedSolid* G4DisplacedSolid::GetDisplac 191 { 192 return this; 193 } 194 195 G4VSolid* G4DisplacedSolid::GetConstituentMove 196 { 197 return fPtrSolid; 198 } 199 200 ////////////////////////////////////////////// 201 202 G4AffineTransform G4DisplacedSolid::GetTransf 203 { 204 G4AffineTransform aTransform = *fPtrTransfor 205 return aTransform; 206 } 207 208 void G4DisplacedSolid::SetTransform(G4AffineTr 209 { 210 fPtrTransform = &transform ; 211 fRebuildPolyhedron = true; 212 } 213 214 ////////////////////////////////////////////// 215 216 G4AffineTransform G4DisplacedSolid::GetDirect 217 { 218 G4AffineTransform aTransform= *fDirectTransf 219 return aTransform; 220 } 221 222 void G4DisplacedSolid::SetDirectTransform(G4Af 223 { 224 fDirectTransform = &transform ; 225 fRebuildPolyhedron = true; 226 } 227 228 ////////////////////////////////////////////// 229 230 G4RotationMatrix G4DisplacedSolid::GetFrameRot 231 { 232 G4RotationMatrix InvRotation = fDirectTransf 233 return InvRotation; 234 } 235 236 void G4DisplacedSolid::SetFrameRotation(const 237 { 238 fDirectTransform->SetNetRotation(matrix); 239 fRebuildPolyhedron = true; 240 } 241 242 ////////////////////////////////////////////// 243 244 G4ThreeVector G4DisplacedSolid::GetFrameTrans 245 { 246 return fPtrTransform->NetTranslation(); 247 } 248 249 void G4DisplacedSolid::SetFrameTranslation(con 250 { 251 fPtrTransform->SetNetTranslation(vector); 252 fRebuildPolyhedron = true; 253 } 254 255 ////////////////////////////////////////////// 256 257 G4RotationMatrix G4DisplacedSolid::GetObjectRo 258 { 259 G4RotationMatrix Rotation = fPtrTransform->N 260 return Rotation; 261 } 262 263 void G4DisplacedSolid::SetObjectRotation(const 264 { 265 fPtrTransform->SetNetRotation(matrix); 266 fRebuildPolyhedron = true; 267 } 268 269 ////////////////////////////////////////////// 270 271 G4ThreeVector G4DisplacedSolid::GetObjectTran 272 { 273 return fDirectTransform->NetTranslation(); 274 } 275 276 void G4DisplacedSolid::SetObjectTranslation(co 277 { 278 fDirectTransform->SetNetTranslation(vector); 279 fRebuildPolyhedron = true; 280 } 281 282 ////////////////////////////////////////////// 283 // 284 // Get bounding box 285 286 void G4DisplacedSolid::BoundingLimits(G4ThreeV 287 G4ThreeV 288 { 289 if (!fDirectTransform->IsRotated()) 290 { 291 // Special case of pure translation 292 // 293 fPtrSolid->BoundingLimits(pMin,pMax); 294 G4ThreeVector offset = fDirectTransform->N 295 pMin += offset; 296 pMax += offset; 297 } 298 else 299 { 300 // General case, use CalculateExtent() to 301 // 302 G4VoxelLimits unLimit; 303 G4double xmin,xmax,ymin,ymax,zmin,zmax; 304 fPtrSolid->CalculateExtent(kXAxis,unLimit, 305 fPtrSolid->CalculateExtent(kYAxis,unLimit, 306 fPtrSolid->CalculateExtent(kZAxis,unLimit, 307 pMin.set(xmin,ymin,zmin); 308 pMax.set(xmax,ymax,zmax); 309 } 310 311 // Check correctness of the bounding box 312 // 313 if (pMin.x() >= pMax.x() || pMin.y() >= pMax 314 { 315 std::ostringstream message; 316 message << "Bad bounding box (min >= max) 317 << GetName() << " !" 318 << "\npMin = " << pMin 319 << "\npMax = " << pMax; 320 G4Exception("G4DisplacedSolid::BoundingLim 321 JustWarning, message); 322 DumpInfo(); 323 } 324 } 325 326 ////////////////////////////////////////////// 327 // 328 // Calculate extent under transform and specif 329 330 G4bool 331 G4DisplacedSolid::CalculateExtent( const EAxis 332 const G4Vox 333 const G4Aff 334 G4dou 335 G4dou 336 { 337 G4AffineTransform sumTransform ; 338 sumTransform.Product(*fDirectTransform,pTran 339 return fPtrSolid->CalculateExtent(pAxis,pVox 340 } 341 342 ////////////////////////////////////////////// 343 // 344 // SurfaceNormal 345 346 EInside G4DisplacedSolid::Inside(const G4Three 347 { 348 G4ThreeVector newPoint = fPtrTransform->Tran 349 return fPtrSolid->Inside(newPoint) ; 350 } 351 352 ////////////////////////////////////////////// 353 // 354 // 355 356 G4ThreeVector 357 G4DisplacedSolid::SurfaceNormal( const G4Three 358 { 359 G4ThreeVector newPoint = fPtrTransform->Tran 360 G4ThreeVector normal = fPtrSolid->SurfaceNor 361 return fDirectTransform->TransformAxis(norma 362 } 363 364 ////////////////////////////////////////////// 365 // 366 // The same algorithm as in DistanceToIn(p) 367 368 G4double 369 G4DisplacedSolid::DistanceToIn( const G4ThreeV 370 const G4ThreeV 371 { 372 G4ThreeVector newPoint = fPtrTransform->Tran 373 G4ThreeVector newDirection = fPtrTransform-> 374 return fPtrSolid->DistanceToIn(newPoint,newD 375 } 376 377 ////////////////////////////////////////////// 378 // 379 // Approximate nearest distance from the point 380 // two solids 381 382 G4double 383 G4DisplacedSolid::DistanceToIn( const G4ThreeV 384 { 385 G4ThreeVector newPoint = fPtrTransform->Tran 386 return fPtrSolid->DistanceToIn(newPoint) ; 387 } 388 389 ////////////////////////////////////////////// 390 // 391 // The same algorithm as DistanceToOut(p) 392 393 G4double 394 G4DisplacedSolid::DistanceToOut( const G4Three 395 const G4Three 396 const G4bool 397 G4bool 398 G4Three 399 { 400 G4ThreeVector solNorm ; 401 G4ThreeVector newPoint = fPtrTransform->Tran 402 G4ThreeVector newDirection = fPtrTransform-> 403 G4double dist = fPtrSolid->DistanceToOut(new 404 cal 405 if(calcNorm) 406 { 407 *n = fDirectTransform->TransformAxis(solNo 408 } 409 return dist ; 410 } 411 412 ////////////////////////////////////////////// 413 // 414 // Inverted algorithm of DistanceToIn(p) 415 416 G4double 417 G4DisplacedSolid::DistanceToOut( const G4Three 418 { 419 G4ThreeVector newPoint = fPtrTransform->Tran 420 return fPtrSolid->DistanceToOut(newPoint) ; 421 } 422 423 ////////////////////////////////////////////// 424 // 425 // ComputeDimensions 426 427 void 428 G4DisplacedSolid::ComputeDimensions( G4V 429 const G4i 430 const G4V 431 { 432 DumpInfo(); 433 G4Exception("G4DisplacedSolid::ComputeDimens 434 "GeomSolids0001", FatalException 435 "Method not applicable in this c 436 } 437 438 ////////////////////////////////////////////// 439 // 440 // Return volume 441 442 G4double G4DisplacedSolid::GetCubicVolume() 443 { 444 return fPtrSolid->GetCubicVolume(); 445 } 446 447 ////////////////////////////////////////////// 448 // 449 // Return surface area 450 451 G4double G4DisplacedSolid::GetSurfaceArea() 452 { 453 return fPtrSolid->GetSurfaceArea(); 454 } 455 456 ////////////////////////////////////////////// 457 // 458 // Returns a point (G4ThreeVector) randomly an 459 // on the solid surface 460 // 461 462 G4ThreeVector G4DisplacedSolid::GetPointOnSurf 463 { 464 G4ThreeVector p = fPtrSolid->GetPointOnSurfa 465 return fDirectTransform->TransformPoint(p); 466 } 467 468 ////////////////////////////////////////////// 469 // 470 // Return the number of constituents used for 471 472 G4int G4DisplacedSolid::GetNumOfConstituents() 473 { 474 return fPtrSolid->GetNumOfConstituents(); 475 } 476 477 ////////////////////////////////////////////// 478 // 479 // Return true if the solid has only planar fa 480 481 G4bool G4DisplacedSolid::IsFaceted() const 482 { 483 return fPtrSolid->IsFaceted(); 484 } 485 486 ////////////////////////////////////////////// 487 // 488 // Return object type name 489 490 G4GeometryType G4DisplacedSolid::GetEntityType 491 { 492 return {"G4DisplacedSolid"}; 493 } 494 495 ////////////////////////////////////////////// 496 // 497 // Make a clone of the object 498 // 499 G4VSolid* G4DisplacedSolid::Clone() const 500 { 501 return new G4DisplacedSolid(*this); 502 } 503 504 ////////////////////////////////////////////// 505 // 506 // Stream object contents to an output stream 507 508 std::ostream& G4DisplacedSolid::StreamInfo(std 509 { 510 os << "------------------------------------- 511 << " *** Dump for Displaced solid - " 512 << " ================================= 513 << " Solid type: " << GetEntityType() << 514 << " Parameters of constituent solid: \n" 515 << "===================================== 516 fPtrSolid->StreamInfo(os); 517 os << "===================================== 518 << " Transformations: \n" 519 << " Direct transformation - translati 520 << " " << fDirectTransform->Net 521 << " - rotation 522 << " "; 523 fDirectTransform->NetRotation().print(os); 524 os << "\n" 525 << "===================================== 526 527 return os; 528 } 529 530 ////////////////////////////////////////////// 531 // 532 // DescribeYourselfTo 533 534 void 535 G4DisplacedSolid::DescribeYourselfTo ( G4VGrap 536 { 537 scene.AddSolid (*this); 538 } 539 540 ////////////////////////////////////////////// 541 // 542 // CreatePolyhedron 543 544 G4Polyhedron* 545 G4DisplacedSolid::CreatePolyhedron () const 546 { 547 G4Polyhedron* polyhedron = fPtrSolid->Create 548 if (polyhedron != nullptr) 549 { 550 polyhedron 551 ->Transform(G4Transform3D(GetObjectRotatio 552 } 553 else 554 { 555 DumpInfo(); 556 G4Exception("G4DisplacedSolid::CreatePolyh 557 "GeomSolids2002", JustWarning, 558 "No G4Polyhedron for displaced 559 } 560 return polyhedron; 561 } 562 563 ////////////////////////////////////////////// 564 // 565 // GetPolyhedron 566 567 G4Polyhedron* G4DisplacedSolid::GetPolyhedron 568 { 569 if (fpPolyhedron == nullptr || 570 fRebuildPolyhedron || 571 fpPolyhedron->GetNumberOfRotationStepsAt 572 fpPolyhedron->GetNumberOfRotationSteps() 573 { 574 fpPolyhedron = CreatePolyhedron(); 575 fRebuildPolyhedron = false; 576 } 577 return fpPolyhedron; 578 } 579