G4SubtractionSolid Class Reference

#include <G4SubtractionSolid.hh>

Inheritance diagram for G4SubtractionSolid:

G4BooleanSolid G4VSolid

Public Member Functions

 G4SubtractionSolid (const G4String &pName, G4VSolid *pSolidA, G4VSolid *pSolidB)
 G4SubtractionSolid (const G4String &pName, G4VSolid *pSolidA, G4VSolid *pSolidB, G4RotationMatrix *rotMatrix, const G4ThreeVector &transVector)
 G4SubtractionSolid (const G4String &pName, G4VSolid *pSolidA, G4VSolid *pSolidB, const G4Transform3D &transform)
virtual ~G4SubtractionSolid ()
G4GeometryType GetEntityType () const
G4VSolidClone () const
 G4SubtractionSolid (__void__ &)
 G4SubtractionSolid (const G4SubtractionSolid &rhs)
G4SubtractionSolidoperator= (const G4SubtractionSolid &rhs)
G4bool CalculateExtent (const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pMin, G4double &pMax) const
EInside Inside (const G4ThreeVector &p) const
G4ThreeVector SurfaceNormal (const G4ThreeVector &p) const
G4double DistanceToIn (const G4ThreeVector &p, const G4ThreeVector &v) const
G4double DistanceToIn (const G4ThreeVector &p) const
G4double DistanceToOut (const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=false, G4bool *validNorm=0, G4ThreeVector *n=0) const
G4double DistanceToOut (const G4ThreeVector &p) const
void ComputeDimensions (G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
void DescribeYourselfTo (G4VGraphicsScene &scene) const
G4PolyhedronCreatePolyhedron () const
G4NURBSCreateNURBS () const

Detailed Description

Definition at line 53 of file G4SubtractionSolid.hh.


Constructor & Destructor Documentation

G4SubtractionSolid::G4SubtractionSolid ( const G4String pName,
G4VSolid pSolidA,
G4VSolid pSolidB 
)

Definition at line 62 of file G4SubtractionSolid.cc.

Referenced by Clone().

00065   : G4BooleanSolid(pName,pSolidA,pSolidB)
00066 {
00067 }

G4SubtractionSolid::G4SubtractionSolid ( const G4String pName,
G4VSolid pSolidA,
G4VSolid pSolidB,
G4RotationMatrix rotMatrix,
const G4ThreeVector transVector 
)

Definition at line 73 of file G4SubtractionSolid.cc.

00078   : G4BooleanSolid(pName,pSolidA,pSolidB,rotMatrix,transVector)
00079 {
00080 } 

G4SubtractionSolid::G4SubtractionSolid ( const G4String pName,
G4VSolid pSolidA,
G4VSolid pSolidB,
const G4Transform3D transform 
)

Definition at line 86 of file G4SubtractionSolid.cc.

00090   : G4BooleanSolid(pName,pSolidA,pSolidB,transform)
00091 {
00092 }

G4SubtractionSolid::~G4SubtractionSolid (  )  [virtual]

Definition at line 108 of file G4SubtractionSolid.cc.

00109 {
00110 }

G4SubtractionSolid::G4SubtractionSolid ( __void__ &   ) 

Definition at line 99 of file G4SubtractionSolid.cc.

00100   : G4BooleanSolid(a)
00101 {
00102 }

G4SubtractionSolid::G4SubtractionSolid ( const G4SubtractionSolid rhs  ) 

Definition at line 116 of file G4SubtractionSolid.cc.

00117   : G4BooleanSolid (rhs)
00118 {
00119 }


Member Function Documentation

G4bool G4SubtractionSolid::CalculateExtent ( const EAxis  pAxis,
const G4VoxelLimits pVoxelLimit,
const G4AffineTransform pTransform,
G4double pMin,
G4double pMax 
) const [virtual]

Implements G4VSolid.

Definition at line 144 of file G4SubtractionSolid.cc.

References G4VSolid::CalculateExtent(), and G4BooleanSolid::fPtrSolidA.

00149 {
00150   // Since we cannot be sure how much the second solid subtracts 
00151   // from the first,    we must use the first solid's extent!
00152 
00153   return fPtrSolidA->CalculateExtent( pAxis, pVoxelLimit, 
00154                                       pTransform, pMin, pMax );
00155 }

G4VSolid * G4SubtractionSolid::Clone (  )  const [virtual]

Reimplemented from G4VSolid.

Definition at line 520 of file G4SubtractionSolid.cc.

References G4SubtractionSolid().

00521 {
00522   return new G4SubtractionSolid(*this);
00523 }

void G4SubtractionSolid::ComputeDimensions ( G4VPVParameterisation p,
const G4int  n,
const G4VPhysicalVolume pRep 
) [virtual]

Reimplemented from G4VSolid.

Definition at line 530 of file G4SubtractionSolid.cc.

00533 {
00534 }

G4NURBS * G4SubtractionSolid::CreateNURBS (  )  const [virtual]

Reimplemented from G4VSolid.

Definition at line 567 of file G4SubtractionSolid.cc.

00568 {
00569   // Take into account boolean operation - see CreatePolyhedron.
00570   // return new G4NURBSbox (1.0, 1.0, 1.0);
00571   return 0;
00572 }

G4Polyhedron * G4SubtractionSolid::CreatePolyhedron (  )  const [virtual]

Reimplemented from G4VSolid.

Definition at line 551 of file G4SubtractionSolid.cc.

References processor, and G4BooleanSolid::StackPolyhedron().

00552 {
00553   HepPolyhedronProcessor processor;
00554   // Stack components and components of components recursively
00555   // See G4BooleanSolid::StackPolyhedron
00556   G4Polyhedron* top = StackPolyhedron(processor, this);
00557   G4Polyhedron* result = new G4Polyhedron(*top);
00558   if (processor.execute(*result)) { return result; }
00559   else { return 0; }
00560 }

void G4SubtractionSolid::DescribeYourselfTo ( G4VGraphicsScene scene  )  const [virtual]

Implements G4VSolid.

Definition at line 541 of file G4SubtractionSolid.cc.

References G4VGraphicsScene::AddSolid().

00542 {
00543   scene.AddSolid (*this);
00544 }

G4double G4SubtractionSolid::DistanceToIn ( const G4ThreeVector p  )  const [virtual]

Implements G4VSolid.

Definition at line 392 of file G4SubtractionSolid.cc.

References G4VSolid::DistanceToIn(), G4VSolid::DistanceToOut(), G4BooleanSolid::fPtrSolidA, G4BooleanSolid::fPtrSolidB, G4cerr, G4cout, G4endl, G4VSolid::Inside(), Inside(), kInside, and kOutside.

00393 {
00394   G4double dist=0.0;
00395 
00396 #ifdef G4BOOLDEBUG
00397   if( Inside(p) == kInside )
00398   {
00399     G4cout << "WARNING - Invalid call in "
00400            << "G4SubtractionSolid::DistanceToIn(p)" << G4endl
00401            << "  Point p is inside !" << G4endl;
00402     G4cout << "          p = " << p << G4endl;
00403     G4cerr << "WARNING - Invalid call in "
00404            << "G4SubtractionSolid::DistanceToIn(p)" << G4endl
00405            << "  Point p is inside !" << G4endl;
00406     G4cerr << "          p = " << p << G4endl;
00407   }
00408 #endif
00409 
00410   if( ( fPtrSolidA->Inside(p) != kOutside) &&   // case 1
00411       ( fPtrSolidB->Inside(p) != kOutside)    )
00412   {
00413       dist= fPtrSolidB->DistanceToOut(p)  ;
00414   }
00415   else
00416   {
00417       dist= fPtrSolidA->DistanceToIn(p) ; 
00418   }
00419   
00420   return dist; 
00421 }

G4double G4SubtractionSolid::DistanceToIn ( const G4ThreeVector p,
const G4ThreeVector v 
) const [virtual]

Implements G4VSolid.

Definition at line 256 of file G4SubtractionSolid.cc.

References G4VSolid::DistanceToIn(), G4VSolid::DistanceToOut(), G4VSolid::DumpInfo(), G4BooleanSolid::fPtrSolidA, G4BooleanSolid::fPtrSolidB, G4cerr, G4cout, G4endl, G4Exception(), G4VSolid::GetEntityType(), G4VSolid::GetName(), G4VSolid::Inside(), Inside(), JustWarning, kInside, and kOutside.

00258 {
00259   G4double dist = 0.0,disTmp = 0.0 ;
00260     
00261 #ifdef G4BOOLDEBUG
00262   if( Inside(p) == kInside )
00263   {
00264     G4cout << "WARNING - Invalid call in "
00265            << "G4SubtractionSolid::DistanceToIn(p,v)" << G4endl
00266            << "  Point p is inside !" << G4endl;
00267     G4cout << "          p = " << p << G4endl;
00268     G4cout << "          v = " << v << G4endl;
00269     G4cerr << "WARNING - Invalid call in "
00270            << "G4SubtractionSolid::DistanceToIn(p,v)" << G4endl
00271            << "  Point p is inside !" << G4endl;
00272     G4cerr << "          p = " << p << G4endl;
00273     G4cerr << "          v = " << v << G4endl;
00274   }
00275 #endif
00276 
00277     // if( // ( fPtrSolidA->Inside(p) != kOutside) &&  // case1:p in both A&B 
00278     if ( fPtrSolidB->Inside(p) != kOutside )   // start: out of B
00279     {
00280       dist = fPtrSolidB->DistanceToOut(p,v) ; // ,calcNorm,validNorm,n) ;
00281       
00282       if( fPtrSolidA->Inside(p+dist*v) != kInside )
00283       {
00284         G4int count1=0;
00285         do
00286         {
00287           disTmp = fPtrSolidA->DistanceToIn(p+dist*v,v) ;
00288 
00289           if(disTmp == kInfinity)
00290           {  
00291             return kInfinity ;
00292           }
00293           dist += disTmp ;
00294 
00295           if( Inside(p+dist*v) == kOutside )
00296           {
00297             disTmp = fPtrSolidB->DistanceToOut(p+dist*v,v) ; 
00298             dist += disTmp ;
00299             count1++;
00300             if( count1 > 1000 )  // Infinite loop detected
00301             {
00302               G4String nameB = fPtrSolidB->GetName();
00303               if(fPtrSolidB->GetEntityType()=="G4DisplacedSolid")
00304               {
00305                 nameB = (dynamic_cast<G4DisplacedSolid*>(fPtrSolidB))
00306                         ->GetConstituentMovedSolid()->GetName();
00307               }
00308               std::ostringstream message;
00309               message << "Illegal condition caused by solids: "
00310                       << fPtrSolidA->GetName() << " and " << nameB << G4endl;
00311               message.precision(16);
00312               message << "Looping detected in point " << p+dist*v
00313                       << ", from original point " << p
00314                       << " and direction " << v << G4endl
00315                       << "Computed candidate distance: " << dist << "*mm.";
00316               message.precision(6);
00317               DumpInfo();
00318               G4Exception("G4SubtractionSolid::DistanceToIn(p,v)",
00319                           "GeomSolids1001", JustWarning, message,
00320                           "Returning candidate distance.");
00321               return dist;
00322             }
00323           }    
00324         }
00325         while( Inside(p+dist*v) == kOutside ) ;
00326       }
00327     }
00328     else // p outside A, start in A
00329     {
00330       dist = fPtrSolidA->DistanceToIn(p,v) ;
00331 
00332       if( dist == kInfinity ) // past A, hence past A\B
00333       {
00334         return kInfinity ;
00335       }
00336       else
00337       {
00338         G4int count2=0;
00339         while( Inside(p+dist*v) == kOutside )  // pushing loop
00340         {
00341           disTmp = fPtrSolidB->DistanceToOut(p+dist*v,v) ;
00342           dist += disTmp ;
00343 
00344           if( Inside(p+dist*v) == kOutside )
00345           { 
00346             disTmp = fPtrSolidA->DistanceToIn(p+dist*v,v) ;
00347 
00348             if(disTmp == kInfinity) // past A, hence past A\B
00349             {  
00350               return kInfinity ;
00351             }                 
00352             dist += disTmp ;
00353             count2++;
00354             if( count2 > 1000 )  // Infinite loop detected
00355             {
00356               G4String nameB = fPtrSolidB->GetName();
00357               if(fPtrSolidB->GetEntityType()=="G4DisplacedSolid")
00358               {
00359                 nameB = (dynamic_cast<G4DisplacedSolid*>(fPtrSolidB))
00360                         ->GetConstituentMovedSolid()->GetName();
00361               }
00362               std::ostringstream message;
00363               message << "Illegal condition caused by solids: "
00364                       << fPtrSolidA->GetName() << " and " << nameB << G4endl;
00365               message.precision(16);
00366               message << "Looping detected in point " << p+dist*v
00367                       << ", from original point " << p
00368                       << " and direction " << v << G4endl
00369                       << "Computed candidate distance: " << dist << "*mm.";
00370               message.precision(6);
00371               DumpInfo();
00372               G4Exception("G4SubtractionSolid::DistanceToIn(p,v)",
00373                           "GeomSolids1001", JustWarning, message);
00374               return dist;         
00375 
00376             }
00377           }
00378         }
00379       }
00380     }
00381   
00382   return dist ;
00383 }

G4double G4SubtractionSolid::DistanceToOut ( const G4ThreeVector p  )  const [virtual]

Implements G4VSolid.

Definition at line 482 of file G4SubtractionSolid.cc.

References G4VSolid::DistanceToIn(), G4VSolid::DistanceToOut(), G4BooleanSolid::fPtrSolidA, G4BooleanSolid::fPtrSolidB, G4cerr, G4cout, G4endl, Inside(), and kOutside.

00483 {
00484   G4double dist=0.0;
00485 
00486   if( Inside(p) == kOutside )
00487   { 
00488 #ifdef G4BOOLDEBUG
00489     G4cout << "WARNING - Invalid call in "
00490            << "G4SubtractionSolid::DistanceToOut(p)" << G4endl
00491            << "  Point p is outside" << G4endl;
00492     G4cout << "          p = " << p << G4endl;
00493     G4cerr << "WARNING - Invalid call in "
00494            << "G4SubtractionSolid::DistanceToOut(p)" << G4endl
00495            << "  Point p is outside" << G4endl;
00496     G4cerr << "          p = " << p << G4endl;
00497 #endif
00498   }
00499   else
00500   {
00501      dist= std::min(fPtrSolidA->DistanceToOut(p),
00502                       fPtrSolidB->DistanceToIn(p) ) ; 
00503   }
00504   return dist; 
00505 }

G4double G4SubtractionSolid::DistanceToOut ( const G4ThreeVector p,
const G4ThreeVector v,
const G4bool  calcNorm = false,
G4bool validNorm = 0,
G4ThreeVector n = 0 
) const [virtual]

Implements G4VSolid.

Definition at line 428 of file G4SubtractionSolid.cc.

References G4VSolid::DistanceToIn(), G4VSolid::DistanceToOut(), G4BooleanSolid::fPtrSolidA, G4BooleanSolid::fPtrSolidB, G4cerr, G4cout, G4endl, Inside(), kOutside, and G4VSolid::SurfaceNormal().

00433 {
00434 #ifdef G4BOOLDEBUG
00435     if( Inside(p) == kOutside )
00436     {
00437       G4cout << "Position:"  << G4endl << G4endl;
00438       G4cout << "p.x() = "   << p.x()/mm << " mm" << G4endl;
00439       G4cout << "p.y() = "   << p.y()/mm << " mm" << G4endl;
00440       G4cout << "p.z() = "   << p.z()/mm << " mm" << G4endl << G4endl;
00441       G4cout << "Direction:" << G4endl << G4endl;
00442       G4cout << "v.x() = "   << v.x() << G4endl;
00443       G4cout << "v.y() = "   << v.y() << G4endl;
00444       G4cout << "v.z() = "   << v.z() << G4endl << G4endl;
00445       G4cout << "WARNING - Invalid call in "
00446              << "G4SubtractionSolid::DistanceToOut(p,v)" << G4endl
00447              << "  Point p is outside !" << G4endl;
00448       G4cout << "          p = " << p << G4endl;
00449       G4cout << "          v = " << v << G4endl;
00450       G4cerr << "WARNING - Invalid call in "
00451              << "G4SubtractionSolid::DistanceToOut(p,v)" << G4endl
00452              << "  Point p is outside !" << G4endl;
00453       G4cerr << "          p = " << p << G4endl;
00454       G4cerr << "          v = " << v << G4endl;
00455     }
00456 #endif
00457 
00458     G4double distout;
00459     G4double distA = fPtrSolidA->DistanceToOut(p,v,calcNorm,validNorm,n) ;
00460     G4double distB = fPtrSolidB->DistanceToIn(p,v) ;
00461     if(distB < distA)
00462     {
00463       if(calcNorm)
00464       {
00465         *n = -(fPtrSolidB->SurfaceNormal(p+distB*v)) ;
00466         *validNorm = false ;
00467       }
00468       distout= distB ;
00469     }
00470     else
00471     {
00472       distout= distA ; 
00473     } 
00474     return distout;
00475 }

G4GeometryType G4SubtractionSolid::GetEntityType (  )  const [virtual]

Reimplemented from G4BooleanSolid.

Definition at line 511 of file G4SubtractionSolid.cc.

00512 {
00513   return G4String("G4SubtractionSolid");
00514 }

EInside G4SubtractionSolid::Inside ( const G4ThreeVector p  )  const [virtual]

Implements G4VSolid.

Definition at line 161 of file G4SubtractionSolid.cc.

References G4BooleanSolid::fPtrSolidA, G4BooleanSolid::fPtrSolidB, G4GeometryTolerance::GetInstance(), G4GeometryTolerance::GetRadialTolerance(), G4VSolid::Inside(), kInside, kOutside, kSurface, and G4VSolid::SurfaceNormal().

Referenced by DistanceToIn(), DistanceToOut(), and SurfaceNormal().

00162 {
00163   EInside positionA = fPtrSolidA->Inside(p);
00164   if (positionA == kOutside) return kOutside;
00165 
00166   EInside positionB = fPtrSolidB->Inside(p);
00167   
00168   if(positionA == kInside && positionB == kOutside)
00169   {
00170     return kInside ;
00171   }
00172   else
00173   {
00174     if(( positionA == kInside && positionB == kSurface) ||
00175        ( positionB == kOutside && positionA == kSurface) ||
00176        ( positionA == kSurface && positionB == kSurface &&
00177          ( fPtrSolidA->SurfaceNormal(p) - 
00178            fPtrSolidB->SurfaceNormal(p) ).mag2() > 
00179             1000*G4GeometryTolerance::GetInstance()->GetRadialTolerance() ) )
00180     {
00181       return kSurface;
00182     }
00183     else
00184     {
00185       return kOutside;
00186     }
00187   }
00188 }

G4SubtractionSolid & G4SubtractionSolid::operator= ( const G4SubtractionSolid rhs  ) 

Definition at line 126 of file G4SubtractionSolid.cc.

References G4BooleanSolid::operator=().

00127 {
00128   // Check assignment to self
00129   //
00130   if (this == &rhs)  { return *this; }
00131 
00132   // Copy base class data
00133   //
00134   G4BooleanSolid::operator=(rhs);
00135 
00136   return *this;
00137 }  

G4ThreeVector G4SubtractionSolid::SurfaceNormal ( const G4ThreeVector p  )  const [virtual]

Implements G4VSolid.

Definition at line 195 of file G4SubtractionSolid.cc.

References G4VSolid::DistanceToIn(), G4VSolid::DistanceToOut(), G4BooleanSolid::fPtrSolidA, G4BooleanSolid::fPtrSolidB, G4cerr, G4cout, G4endl, G4VSolid::Inside(), Inside(), kInside, kOutside, kSurface, and G4VSolid::SurfaceNormal().

00196 {
00197   G4ThreeVector normal;
00198   if( Inside(p) == kOutside )
00199   {
00200 #ifdef G4BOOLDEBUG
00201     G4cout << "WARNING - Invalid call [1] in "
00202            << "G4SubtractionSolid::SurfaceNormal(p)" << G4endl
00203            << "  Point p is inside !" << G4endl;
00204     G4cout << "          p = " << p << G4endl;
00205     G4cerr << "WARNING - Invalid call [1] in "
00206            << "G4SubtractionSolid::SurfaceNormal(p)" << G4endl
00207            << "  Point p is inside !" << G4endl;
00208     G4cerr << "          p = " << p << G4endl;
00209 #endif
00210   }
00211   else
00212   { 
00213     if( fPtrSolidA->Inside(p) == kSurface && 
00214         fPtrSolidB->Inside(p) != kInside      ) 
00215     {
00216       normal = fPtrSolidA->SurfaceNormal(p) ;
00217     }
00218     else if( fPtrSolidA->Inside(p) == kInside && 
00219              fPtrSolidB->Inside(p) != kOutside    )
00220     {
00221       normal = -fPtrSolidB->SurfaceNormal(p) ;
00222     }
00223     else 
00224     {
00225       if ( fPtrSolidA->DistanceToOut(p) <= fPtrSolidB->DistanceToIn(p) )
00226       {
00227         normal = fPtrSolidA->SurfaceNormal(p) ;
00228       }
00229       else
00230       {
00231         normal = -fPtrSolidB->SurfaceNormal(p) ;
00232       }
00233 #ifdef G4BOOLDEBUG
00234       if(Inside(p) == kInside)
00235       {
00236         G4cout << "WARNING - Invalid call [2] in "
00237              << "G4SubtractionSolid::SurfaceNormal(p)" << G4endl
00238              << "  Point p is inside !" << G4endl;
00239         G4cout << "          p = " << p << G4endl;
00240         G4cerr << "WARNING - Invalid call [2] in "
00241              << "G4SubtractionSolid::SurfaceNormal(p)" << G4endl
00242              << "  Point p is inside !" << G4endl;
00243         G4cerr << "          p = " << p << G4endl;
00244       }
00245 #endif
00246     }
00247   }
00248   return normal;
00249 }


The documentation for this class was generated from the following files:
Generated on Mon May 27 17:53:28 2013 for Geant4 by  doxygen 1.4.7