G4BREPSolid Class Reference

#include <G4BREPSolid.hh>

Inheritance diagram for G4BREPSolid:

G4VSolid G4BREPSolidBox G4BREPSolidCone G4BREPSolidCylinder G4BREPSolidPCone G4BREPSolidPolyhedra G4BREPSolidSphere G4BREPSolidTorus

Public Member Functions

 G4BREPSolid (const G4String &name)
 G4BREPSolid (const G4String &, G4Surface **, G4int)
virtual ~G4BREPSolid ()
virtual void Initialize ()
G4bool CalculateExtent (const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pMin, G4double &pMax) const
virtual EInside Inside (register const G4ThreeVector &Pt) const
virtual G4ThreeVector SurfaceNormal (const G4ThreeVector &) const
virtual G4double DistanceToIn (const G4ThreeVector &) const
virtual G4double DistanceToIn (register const G4ThreeVector &Pt, register const G4ThreeVector &V) const
virtual G4double DistanceToOut (const G4ThreeVector &) const
virtual G4double DistanceToOut (register const G4ThreeVector &Pt, register const G4ThreeVector &V, const G4bool calcNorm=false, G4bool *validNorm=0, G4ThreeVector *n=0) const
G4Point3D Scope () const
virtual G4String GetEntityType () const
virtual G4VSolidClone () const
virtual std::ostream & StreamInfo (std::ostream &os) const
void DescribeYourselfTo (G4VGraphicsScene &scene) const
G4PolyhedronCreatePolyhedron () const
G4NURBSCreateNURBS () const
virtual G4PolyhedronGetPolyhedron () const
G4int Intersect (register const G4Ray &) const
G4SurfaceGetSurface (G4int) const
void Active (G4int) const
G4int Active () const
G4double GetShortestDistance () const
G4int GetId () const
void SetId (G4int)
const G4StringGetName () const
void SetName (const G4String &name)
G4int GetNumberOfFaces () const
G4int GetNumberOfSolids () const
const G4Axis2Placement3DGetPlace () const
const G4BoundingBox3DGetBBox () const
G4int GetCubVolStatistics () const
G4double GetCubVolEpsilon () const
void SetCubVolStatistics (G4int st)
void SetCubVolEpsilon (G4double ep)
G4int GetAreaStatistics () const
G4double GetAreaAccuracy () const
void SetAreaStatistics (G4int st)
void SetAreaAccuracy (G4double ep)
G4double GetCubicVolume ()
G4double GetSurfaceArea ()
G4double IntersectionDistance () const
void IntersectionDistance (G4double) const
virtual void Reset () const
 G4BREPSolid (__void__ &)
 G4BREPSolid (const G4BREPSolid &rhs)
G4BREPSolidoperator= (const G4BREPSolid &rhs)

Protected Member Functions

G4ThreeVectorListCreateRotatedVertices (const G4AffineTransform &) const
G4bool IsConvex ()
virtual void CalcBBoxes ()
void CheckSurfaceNormals ()
void RemoveHiddenFaces (register const G4Ray &G4Rayref, G4int) const
void TestSurfaceBBoxes (register const G4Ray &) const
G4int StartInside () const
void StartInside (G4int si) const
void QuickSort (register G4Surface **SrfVec, register G4int left, register G4int right) const

Protected Attributes

G4int Box
G4int Convex
G4int AxisBox
G4int PlaneSolid
G4Axis2Placement3Dplace
G4BoundingBox3Dbbox
G4double intersectionDistance
G4int active
G4int startInside
G4int nb_of_surfaces
G4Point3D intersection_point
G4Surface ** SurfaceVec
G4double RealDist
G4String solidname
G4int Id

Static Protected Attributes

static G4int NumberOfSolids = 0
static G4Ray Track
static G4double ShortestDistance = kInfinity

Detailed Description

Definition at line 50 of file G4BREPSolid.hh.


Constructor & Destructor Documentation

G4BREPSolid::G4BREPSolid ( const G4String name  ) 

Definition at line 52 of file G4BREPSolid.cc.

References G4cout, and G4endl.

Referenced by Clone().

00053  : G4VSolid(name),
00054    Box(0), Convex(0), AxisBox(0), PlaneSolid(0), place(0), bbox(0),
00055    intersectionDistance(kInfinity), active(1), startInside(0),
00056    nb_of_surfaces(0), SurfaceVec(0), RealDist(0.), solidname(name), Id(0),
00057    fStatistics(1000000), fCubVolEpsilon(0.001), fAreaAccuracy(-1.),
00058    fCubicVolume(0.), fSurfaceArea(0.), fpPolyhedron(0)
00059 {
00060   static G4bool warn=true;
00061   if (warn)
00062   {
00063     G4cout
00064          << "--------------------------------------------------------" << G4endl
00065          << "WARNING: BREPS classes are being dismissed.  They will |" << G4endl
00066          << "         be removed starting  from next  Geant4  major |" << G4endl
00067          << "         release.  Please, consider switching to adopt |" << G4endl
00068          << "         correspondent CSG or specific primitives.     |" << G4endl
00069          << "--------------------------------------------------------"
00070          << G4endl;
00071     warn = false;
00072   }
00073 }

G4BREPSolid::G4BREPSolid ( const G4String ,
G4Surface **  ,
G4int   
)

Definition at line 75 of file G4BREPSolid.cc.

References G4cout, G4endl, and Initialize().

00078  : G4VSolid(name),
00079    Box(0), Convex(0), AxisBox(0), PlaneSolid(0), place(0), bbox(0),
00080    intersectionDistance(kInfinity), active(1), startInside(0),
00081    nb_of_surfaces(numberOfSrfs), SurfaceVec(srfVec), RealDist(0.),
00082    solidname(name), Id(0),
00083    fStatistics(1000000), fCubVolEpsilon(0.001), fAreaAccuracy(-1.),
00084    fCubicVolume(0.), fSurfaceArea(0.), fpPolyhedron(0)
00085 {
00086   static G4bool warn=true;
00087   if (warn)
00088   {
00089     G4cout
00090          << "--------------------------------------------------------" << G4endl
00091          << "WARNING: BREPS classes are being dismissed.  They will |" << G4endl
00092          << "         be removed starting  from next  Geant4  major |" << G4endl
00093          << "         release.  Please, consider switching to adopt |" << G4endl
00094          << "         correspondent CSG or specific primitives.     |" << G4endl
00095          << "--------------------------------------------------------"
00096          << G4endl;
00097     warn = false;
00098   }
00099   Initialize();
00100 }

G4BREPSolid::~G4BREPSolid (  )  [virtual]

Definition at line 112 of file G4BREPSolid.cc.

References bbox, nb_of_surfaces, place, and SurfaceVec.

00113 {
00114   delete place;
00115   delete bbox;
00116   
00117   for(G4int a=0;a<nb_of_surfaces;++a)
00118     { delete SurfaceVec[a]; }
00119   
00120   delete [] SurfaceVec;
00121   delete fpPolyhedron;
00122 }

G4BREPSolid::G4BREPSolid ( __void__ &   ) 

Definition at line 102 of file G4BREPSolid.cc.

00103   : G4VSolid(a),
00104    Box(0), Convex(0), AxisBox(0), PlaneSolid(0), place(0), bbox(0),
00105    intersectionDistance(kInfinity), active(1), startInside(0),
00106    nb_of_surfaces(0), SurfaceVec(0), RealDist(0.), solidname(""), Id(0),
00107    fStatistics(1000000), fCubVolEpsilon(0.001), fAreaAccuracy(-1.),
00108    fCubicVolume(0.), fSurfaceArea(0.), fpPolyhedron(0)
00109 {
00110 }

G4BREPSolid::G4BREPSolid ( const G4BREPSolid rhs  ) 

Definition at line 124 of file G4BREPSolid.cc.

References Initialize().

00125   : G4VSolid(rhs), Box(rhs.Box), Convex(rhs.Convex), AxisBox(rhs.AxisBox),
00126     PlaneSolid(rhs.PlaneSolid), place(0), bbox(0),
00127     intersectionDistance(rhs.intersectionDistance), active(rhs.active),
00128     startInside(rhs.startInside), nb_of_surfaces(rhs.nb_of_surfaces),
00129     intersection_point(rhs.intersection_point), SurfaceVec(0),
00130     RealDist(rhs.RealDist), solidname(rhs.solidname), Id(rhs.Id),
00131     fStatistics(rhs.fStatistics), fCubVolEpsilon(rhs.fCubVolEpsilon),
00132     fAreaAccuracy(rhs.fAreaAccuracy), fCubicVolume(rhs.fCubicVolume),
00133     fSurfaceArea(rhs.fSurfaceArea), fpPolyhedron(0)
00134 {
00135   Initialize();
00136 }


Member Function Documentation

G4int G4BREPSolid::Active (  )  const [inline]

Definition at line 57 of file G4BREPSolid.icc.

References active.

Referenced by G4BREPSolidPolyhedra::Reset(), G4BREPSolidPCone::Reset(), and TestSurfaceBBoxes().

00058 {
00059   return active;
00060 }

void G4BREPSolid::Active ( G4int   )  const [inline]

Definition at line 52 of file G4BREPSolid.icc.

00053 {
00054   ((G4BREPSolid*)this)->active=x;
00055 }

void G4BREPSolid::CalcBBoxes (  )  [protected, virtual]

Definition at line 1140 of file G4BREPSolid.cc.

References active, bbox, G4Surface::CalcBBox(), G4Exception(), G4Surface::GetBBox(), G4BoundingBox3D::GetBoxMax(), G4BoundingBox3D::GetBoxMin(), JustWarning, PINFINITY(), and SurfaceVec.

Referenced by G4BREPSolidPolyhedra::Initialize(), G4BREPSolidPCone::Initialize(), G4BREPSolidCone::Initialize(), and Initialize().

01141 {
01142   // First initialization. Calculates the bounding boxes
01143   // for the surfaces and for the solid.
01144 
01145   G4Surface* srf;
01146   G4Point3D min, max;
01147   
01148   if(active)
01149   {
01150     min =  PINFINITY;
01151     max = -PINFINITY;
01152     
01153     for(G4int a = 0;a < nb_of_surfaces;a++)
01154     {
01155       // Get first in List
01156       //
01157       srf = SurfaceVec[a];
01158 /*
01159       G4int convex=1; 
01160       G4int concavepoint=-1;
01161 
01162       if (srf->MyType() == 1) 
01163       {
01164         concavepoint = srf->IsConvex();
01165         convex = srf->GetConvex();
01166       }
01167 
01168       // Make bbox for face
01169       //
01170       if(convex && Concavepoint==-1)
01171 */
01172       {
01173         srf->CalcBBox();
01174         G4Point3D box_min = srf->GetBBox()->GetBoxMin();
01175         G4Point3D box_max = srf->GetBBox()->GetBoxMax();
01176 
01177         // Find max and min of face bboxes to make solids bbox.
01178 
01179         // replace by Extend
01180         // max < box_max
01181         //
01182         if(max.x() < box_max.x()) max.setX(box_max.x()); 
01183         if(max.y() < box_max.y()) max.setY(box_max.y()); 
01184         if(max.z() < box_max.z()) max.setZ(box_max.z()); 
01185 
01186         // min > box_min
01187         //
01188         if(min.x() > box_min.x()) min.setX(box_min.x()); 
01189         if(min.y() > box_min.y()) min.setY(box_min.y()); 
01190         if(min.z() > box_min.z()) min.setZ(box_min.z());
01191       }
01192     }
01193     bbox =  new G4BoundingBox3D(min, max);
01194     return;
01195   }
01196   G4Exception("G4BREPSolid::CalcBBoxes()", "GeomSolids1002",
01197               JustWarning, "No bbox calculated for solid.");
01198 }

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

Implements G4VSolid.

Definition at line 596 of file G4BREPSolid.cc.

References bbox, G4VSolid::ClipBetweenSections(), G4VSolid::ClipCrossSection(), CreateRotatedVertices(), G4BoundingBox3D::GetBoxMax(), G4BoundingBox3D::GetBoxMin(), G4VoxelLimits::GetMaxExtent(), G4VoxelLimits::GetMaxXExtent(), G4VoxelLimits::GetMaxYExtent(), G4VoxelLimits::GetMaxZExtent(), G4VoxelLimits::GetMinExtent(), G4VoxelLimits::GetMinXExtent(), G4VoxelLimits::GetMinYExtent(), G4VoxelLimits::GetMinZExtent(), Inside(), G4AffineTransform::Inverse(), G4AffineTransform::IsRotated(), G4VoxelLimits::IsXLimited(), G4VoxelLimits::IsYLimited(), G4VoxelLimits::IsZLimited(), G4VSolid::kCarTolerance, kOutside, kXAxis, kYAxis, kZAxis, G4AffineTransform::NetTranslation(), and G4AffineTransform::TransformPoint().

00600 {
00601   G4Point3D Min = bbox->GetBoxMin();
00602   G4Point3D Max = bbox->GetBoxMax();
00603 
00604   if (!pTransform.IsRotated())
00605     {
00606       // Special case handling for unrotated boxes
00607       // Compute x/y/z mins and maxs respecting limits, with early returns
00608       // if outside limits. Then switch() on pAxis
00609       //
00610       G4double xoffset,xMin,xMax;
00611       G4double yoffset,yMin,yMax;
00612       G4double zoffset,zMin,zMax;
00613 
00614       xoffset=pTransform.NetTranslation().x();
00615       xMin=xoffset+Min.x();
00616       xMax=xoffset+Max.x();
00617       if (pVoxelLimit.IsXLimited())
00618       {
00619         if (xMin>pVoxelLimit.GetMaxXExtent()
00620             ||xMax<pVoxelLimit.GetMinXExtent())
00621         {
00622           return false;
00623         }
00624         else
00625         {
00626           if (xMin<pVoxelLimit.GetMinXExtent())
00627           {
00628             xMin=pVoxelLimit.GetMinXExtent();
00629           }
00630           if (xMax>pVoxelLimit.GetMaxXExtent())
00631           {
00632             xMax=pVoxelLimit.GetMaxXExtent();
00633           }
00634         }
00635       }
00636 
00637       yoffset=pTransform.NetTranslation().y();
00638       yMin=yoffset+Min.y();
00639       yMax=yoffset+Max.y();
00640       if (pVoxelLimit.IsYLimited())
00641       {
00642         if (yMin>pVoxelLimit.GetMaxYExtent()
00643             ||yMax<pVoxelLimit.GetMinYExtent())
00644         {
00645           return false;
00646         }
00647         else
00648         {
00649           if (yMin<pVoxelLimit.GetMinYExtent())
00650           {
00651             yMin=pVoxelLimit.GetMinYExtent();
00652           }
00653           if (yMax>pVoxelLimit.GetMaxYExtent())
00654           {
00655             yMax=pVoxelLimit.GetMaxYExtent();
00656           }
00657         }
00658       }
00659 
00660       zoffset=pTransform.NetTranslation().z();
00661       zMin=zoffset+Min.z();
00662       zMax=zoffset+Max.z();
00663       if (pVoxelLimit.IsZLimited())
00664       {
00665         if (zMin>pVoxelLimit.GetMaxZExtent()
00666             ||zMax<pVoxelLimit.GetMinZExtent())
00667         {
00668           return false;
00669         }
00670         else
00671         {
00672           if (zMin<pVoxelLimit.GetMinZExtent())
00673           {
00674             zMin=pVoxelLimit.GetMinZExtent();
00675           }
00676           if (zMax>pVoxelLimit.GetMaxZExtent())
00677           {
00678             zMax=pVoxelLimit.GetMaxZExtent();
00679           }
00680         }
00681       }
00682 
00683       switch (pAxis)
00684       {
00685         case kXAxis:
00686           pMin=xMin;
00687           pMax=xMax;
00688           break;
00689         case kYAxis:
00690           pMin=yMin;
00691           pMax=yMax;
00692           break;
00693         case kZAxis:
00694           pMin=zMin;
00695           pMax=zMax;
00696           break;
00697         default:
00698           break;
00699       }
00700       pMin-=kCarTolerance;
00701       pMax+=kCarTolerance;
00702 
00703       return true;
00704     }
00705   else
00706     {
00707       // General rotated case - create and clip mesh to boundaries
00708 
00709       G4bool existsAfterClip=false;
00710       G4ThreeVectorList *vertices;
00711 
00712       pMin=+kInfinity;
00713       pMax=-kInfinity;
00714 
00715       // Calculate rotated vertex coordinates
00716       //
00717       vertices=CreateRotatedVertices(pTransform);
00718       ClipCrossSection(vertices,0,pVoxelLimit,pAxis,pMin,pMax);
00719       ClipCrossSection(vertices,4,pVoxelLimit,pAxis,pMin,pMax);
00720       ClipBetweenSections(vertices,0,pVoxelLimit,pAxis,pMin,pMax);
00721 
00722       if ( (pMin!=kInfinity) || (pMax!=-kInfinity) )
00723       {
00724         existsAfterClip=true;
00725     
00726         // Add 2*tolerance to avoid precision troubles
00727         //
00728         pMin-=kCarTolerance;
00729         pMax+=kCarTolerance;
00730       }
00731       else
00732       {
00733         // Check for case where completely enveloping clipping volume.
00734         // If point inside then we are confident that the solid completely
00735         // envelopes the clipping volume. Hence set min/max extents according
00736         // to clipping volume extents along the specified axis.
00737         //
00738         G4ThreeVector clipCentre(
00739                 (pVoxelLimit.GetMinXExtent()+pVoxelLimit.GetMaxXExtent())*0.5,
00740                 (pVoxelLimit.GetMinYExtent()+pVoxelLimit.GetMaxYExtent())*0.5,
00741                 (pVoxelLimit.GetMinZExtent()+pVoxelLimit.GetMaxZExtent())*0.5);
00742 
00743         if (Inside(pTransform.Inverse().TransformPoint(clipCentre))!=kOutside)
00744         {
00745           existsAfterClip=true;
00746           pMin=pVoxelLimit.GetMinExtent(pAxis);
00747           pMax=pVoxelLimit.GetMaxExtent(pAxis);
00748         }
00749       }
00750       delete vertices;
00751       return existsAfterClip;
00752     }
00753 }

void G4BREPSolid::CheckSurfaceNormals (  )  [protected]

Definition at line 213 of file G4BREPSolid.cc.

References Convex, G4cout, G4Surface::GetNumberOfPoints(), G4Surface::GetPoint(), nb_of_surfaces, G4Surface::Norm(), PlaneSolid, and SurfaceVec.

Referenced by G4BREPSolidPolyhedra::Initialize(), G4BREPSolidPCone::Initialize(), G4BREPSolidCone::Initialize(), and Initialize().

00214 {
00215   if(!PlaneSolid)
00216     return; // All faces must be planar
00217  
00218   Convex=1;
00219  
00220   // Checks that the normals of the surfaces point outwards.
00221   // If not, turns the Normal to point out.
00222   
00223   // Loop through each face and check the G4Vector3D of the Normal
00224   //
00225   G4Surface* srf;
00226   G4Point3D V;
00227   
00228   G4int SrfNum = 0;
00229   G4double YValue=0;
00230   G4Point3D Pt;
00231   
00232   G4int a, b;
00233   for(a=0; a<nb_of_surfaces; a++)
00234   {
00235     // Find vertex point containing extreme y value
00236     //
00237     srf = SurfaceVec[a];
00238     G4int Points = srf->GetNumberOfPoints();
00239     
00240     for(b =0; b<Points; b++)
00241     {
00242       Pt = (G4Point3D)srf->GetPoint(b);    
00243       if(YValue < Pt.y())
00244       {
00245         YValue = Pt.y();
00246         SrfNum = a;   // Save srf number
00247       }
00248     }
00249   }
00250 
00251   // Move the selected face to the first in the List
00252   //
00253   srf = SurfaceVec[SrfNum];            
00254   
00255   // Start handling the surfaces in order and compare
00256   // the neighbouring ones and turn their normals if they
00257   // point inwards
00258   //
00259   G4Point3D Pt1;
00260   G4Point3D Pt2;
00261   G4Point3D Pt3;
00262   G4Point3D Pt4;
00263   
00264   G4Vector3D N1;
00265   G4Vector3D N2;    
00266   G4Vector3D N3;    
00267   G4Vector3D N4;    
00268 
00269   G4int* ConnectedList = new G4int[nb_of_surfaces];    
00270 
00271   for(a=0; a<nb_of_surfaces; a++)
00272     ConnectedList[a]=0;
00273   
00274   G4Surface* ConnectedSrf;
00275 
00276   for(a=0; a<nb_of_surfaces-1; a++)
00277   {
00278     if(ConnectedList[a] == 0) 
00279       break;
00280     else
00281       ConnectedList[a]=1;
00282     
00283     srf = SurfaceVec[a];
00284     G4int SrfPoints = srf->GetNumberOfPoints();
00285     N1 = (srf->Norm())->GetDir();
00286 
00287     for(b=a+1; b<nb_of_surfaces; b++)
00288     {
00289       if(ConnectedList[b] == 1) 
00290         break;
00291       else
00292         ConnectedList[b]=1;
00293      
00294       // Get next in List
00295       // 
00296       ConnectedSrf = SurfaceVec[b];    
00297 
00298       // Check if it is connected to srf by looping through the points.
00299       //
00300       G4int ConnSrfPoints = ConnectedSrf->GetNumberOfPoints();
00301 
00302       for(G4int c=0;c<SrfPoints;c++)
00303       {
00304         Pt1 = srf->GetPoint(c);
00305 
00306         for(G4int d=0;d<ConnSrfPoints;d++)
00307         {
00308           // Find common points
00309           //
00310           Pt2 = (ConnectedSrf)->GetPoint(d);
00311 
00312           if( Pt1 == Pt2 ) 
00313           {
00314             // Common point found. Compare normals.
00315             //
00316             N2 = ((ConnectedSrf)->Norm())->GetDir();
00317 
00318             // Check cross product.
00319             //
00320             G4Vector3D CP1 = G4Vector3D( N1.cross(N2) );
00321             G4double CrossProd1 = CP1.x()+CP1.y()+CP1.z();
00322 
00323             // Create the other normals
00324             //
00325             if(c==0) 
00326               Pt3 = srf->GetPoint(c+1);
00327             else
00328               Pt3 = srf->GetPoint(0);
00329 
00330             N3 = (Pt1-Pt3);
00331 
00332             if(d==0) 
00333               Pt4 = (ConnectedSrf)->GetPoint(d+1);
00334             else
00335               Pt4 = (ConnectedSrf)->GetPoint(0);
00336 
00337             N4 = (Pt1-Pt4);
00338 
00339             G4Vector3D CP2 = G4Vector3D( N3.cross(N4) );
00340             G4double CrossProd2 = CP2.x()+CP2.y()+CP2.z();
00341 
00342             G4cout << "\nCroosProd2: " << CrossProd2;
00343 
00344             if( (CrossProd1 < 0 && CrossProd2 < 0) ||
00345                 (CrossProd1 > 0 && CrossProd2 > 0)    )
00346             {
00347               // Turn Normal
00348               //
00349               (ConnectedSrf)->Norm()
00350                 ->SetDir(-1 * (ConnectedSrf)->Norm()->GetDir());
00351 
00352               // Take the CrossProd1 again as the other Normal was turned.
00353               //
00354               CP1 = N1.cross(N2);
00355               CrossProd1 = CP1.x()+CP1.y()+CP1.z();
00356             }
00357             if(CrossProd1 > 0) 
00358               Convex=0;
00359           }
00360         }
00361       }
00362     }
00363   }
00364   
00365   delete []ConnectedList;
00366 }

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

Reimplemented from G4VSolid.

Reimplemented in G4BREPSolidBox, G4BREPSolidCone, G4BREPSolidCylinder, G4BREPSolidPCone, G4BREPSolidPolyhedra, G4BREPSolidSphere, and G4BREPSolidTorus.

Definition at line 196 of file G4BREPSolid.cc.

References G4BREPSolid().

00197 {
00198   return new G4BREPSolid(*this);
00199 }

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

Reimplemented from G4VSolid.

Definition at line 1130 of file G4BREPSolid.cc.

References bbox, G4BoundingBox3D::GetBoxMax(), and G4BoundingBox3D::GetBoxMin().

01131 {
01132   // Approximate implementation, just a box ...
01133 
01134   G4Point3D Min = bbox->GetBoxMin();
01135   G4Point3D Max = bbox->GetBoxMax();  
01136 
01137   return new G4NURBSbox (Max.x(), Max.y(), Max.z());
01138 }

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

Reimplemented from G4VSolid.

Reimplemented in G4BREPSolidPCone, and G4BREPSolidPolyhedra.

Definition at line 1120 of file G4BREPSolid.cc.

References bbox, G4BoundingBox3D::GetBoxMax(), and G4BoundingBox3D::GetBoxMin().

Referenced by GetPolyhedron().

01121 {
01122   // Approximate implementation, just a box ...
01123 
01124   G4Point3D Min = bbox->GetBoxMin();
01125   G4Point3D Max = bbox->GetBoxMax();  
01126 
01127   return new G4PolyhedronBox (Max.x(), Max.y(), Max.z());
01128 }

G4ThreeVectorList * G4BREPSolid::CreateRotatedVertices ( const G4AffineTransform  )  const [protected]

Definition at line 756 of file G4BREPSolid.cc.

References bbox, FatalException, G4Exception(), G4BoundingBox3D::GetBoxMax(), G4BoundingBox3D::GetBoxMin(), and G4AffineTransform::TransformPoint().

Referenced by CalculateExtent().

00757 {
00758   G4Point3D Min = bbox->GetBoxMin();
00759   G4Point3D Max = bbox->GetBoxMax();
00760 
00761   G4ThreeVectorList *vertices;
00762   vertices=new G4ThreeVectorList();
00763     
00764   if (vertices)
00765   {
00766     vertices->reserve(8);
00767     G4ThreeVector vertex0(Min.x(),Min.y(),Min.z());
00768     G4ThreeVector vertex1(Max.x(),Min.y(),Min.z());
00769     G4ThreeVector vertex2(Max.x(),Max.y(),Min.z());
00770     G4ThreeVector vertex3(Min.x(),Max.y(),Min.z());
00771     G4ThreeVector vertex4(Min.x(),Min.y(),Max.z());
00772     G4ThreeVector vertex5(Max.x(),Min.y(),Max.z());
00773     G4ThreeVector vertex6(Max.x(),Max.y(),Max.z());
00774     G4ThreeVector vertex7(Min.x(),Max.y(),Max.z());
00775 
00776     vertices->push_back(pTransform.TransformPoint(vertex0));
00777     vertices->push_back(pTransform.TransformPoint(vertex1));
00778     vertices->push_back(pTransform.TransformPoint(vertex2));
00779     vertices->push_back(pTransform.TransformPoint(vertex3));
00780     vertices->push_back(pTransform.TransformPoint(vertex4));
00781     vertices->push_back(pTransform.TransformPoint(vertex5));
00782     vertices->push_back(pTransform.TransformPoint(vertex6));
00783     vertices->push_back(pTransform.TransformPoint(vertex7));
00784   }
00785   else
00786   {
00787     G4Exception("G4BREPSolid::CreateRotatedVertices()", "GeomSolids0003",
00788                 FatalException, "Out of memory - Cannot allocate vertices!");
00789   }
00790   return vertices;
00791 }

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

Implements G4VSolid.

Definition at line 1115 of file G4BREPSolid.cc.

References G4VGraphicsScene::AddSolid().

01116 {
01117   scene.AddSolid (*this);
01118 }

G4double G4BREPSolid::DistanceToIn ( register const G4ThreeVector Pt,
register const G4ThreeVector V 
) const [virtual]

Reimplemented in G4BREPSolidCone, G4BREPSolidPCone, G4BREPSolidPolyhedra, and G4BREPSolidSphere.

Definition at line 930 of file G4BREPSolid.cc.

References Intersect(), G4VSolid::kCarTolerance, Reset(), ShortestDistance, G4Surface::SurfaceNormal(), SurfaceVec, and TestSurfaceBBoxes().

00932 {
00933   // Calculates the distance from a point outside the solid
00934   // to the solid's boundary along a specified direction vector.
00935   //
00936   // Note : Intersections with boundaries less than the tolerance must be
00937   //        ignored if the direction is away from the boundary.
00938   
00939   G4int a;
00940   
00941   // Set the surfaces to active again
00942   //
00943   Reset();
00944   
00945   const G4double sqrHalfTolerance = kCarTolerance*kCarTolerance*0.25;
00946   G4Vector3D Pttmp(Pt);
00947   G4Vector3D Vtmp(V);   
00948   G4Ray r(Pttmp, Vtmp);
00949 
00950   // Test if the bounding box of each surface is intersected
00951   // by the ray. If not, the surface become deactive.
00952   //
00953   TestSurfaceBBoxes(r);
00954   
00955   ShortestDistance = kInfinity;
00956   
00957   for(a=0; a< nb_of_surfaces; a++)
00958   {
00959     if( SurfaceVec[a]->IsActive() )
00960     {
00961       // Test if the ray intersects the surface
00962       //
00963       if( SurfaceVec[a]->Intersect(r) )
00964       {
00965         G4double surfDistance = SurfaceVec[a]->GetDistance();
00966 
00967         // If more than 1 surface is intersected, take the nearest one
00968         //
00969         if( surfDistance < ShortestDistance )
00970         {
00971           if( surfDistance > sqrHalfTolerance )
00972           {
00973             ShortestDistance = surfDistance;
00974           }
00975           else
00976           {
00977             // The point is within the boundary. It is ignored it if
00978             // the direction is away from the boundary
00979             //
00980             G4Vector3D Norm = SurfaceVec[a]->SurfaceNormal(Pttmp);
00981 
00982             if( (Norm * Vtmp) < 0 )
00983             {
00984               ShortestDistance = surfDistance;
00985             }
00986           }
00987         }
00988       }
00989     }
00990   }
00991   
00992   // Be careful !
00993   // SurfaceVec->Distance is in fact the squared distance
00994   //
00995   if(ShortestDistance != kInfinity)
00996     return std::sqrt(ShortestDistance);
00997   else
00998     return kInfinity;  // No intersection
00999 }

G4double G4BREPSolid::DistanceToIn ( const G4ThreeVector  )  const [virtual]

Implements G4VSolid.

Reimplemented in G4BREPSolidCone, G4BREPSolidPCone, G4BREPSolidPolyhedra, and G4BREPSolidSphere.

Definition at line 888 of file G4BREPSolid.cc.

References Reset(), and SurfaceVec.

00889 {
00890   // Calculates the shortest distance ("safety") from a point
00891   // outside the solid to any boundary of this solid.
00892   // Return 0 if the point is already inside.
00893 
00894   G4double *dists = new G4double[nb_of_surfaces];
00895   G4int a;
00896 
00897   // Set the surfaces to active again
00898   //
00899   Reset();
00900   
00901   // Compute the shortest distance of the point to each surface.
00902   // Be careful : it's a signed value
00903   //
00904   for(a=0; a< nb_of_surfaces; a++)  
00905     dists[a] = SurfaceVec[a]->HowNear(Pt);
00906      
00907   G4double Dist = kInfinity;
00908   
00909   // If dists[] is positive, the point is outside, so take the shortest of
00910   // the shortest positive distances dists[] can be equal to 0 : point on
00911   // a surface.
00912   // ( Problem with the G4FPlane : there is no inside and no outside...
00913   //   So, to test if the point is inside to return 0, utilize the Inside()
00914   //   function. But I don't know if it is really needed because dToIn is 
00915   //   called only if the point is outside )
00916   //
00917   for(a = 0; a < nb_of_surfaces; a++)
00918     if( std::fabs(Dist) > std::fabs(dists[a]) ) 
00919       //if( dists[a] >= 0)
00920         Dist = dists[a];
00921   
00922   delete[] dists;
00923 
00924   if(Dist == kInfinity)
00925     return 0;  // the point is inside the solid or on a surface
00926   else
00927     return std::fabs(Dist);
00928 }

G4double G4BREPSolid::DistanceToOut ( register const G4ThreeVector Pt,
register const G4ThreeVector V,
const G4bool  calcNorm = false,
G4bool validNorm = 0,
G4ThreeVector n = 0 
) const [virtual]

Reimplemented in G4BREPSolidCone, G4BREPSolidPCone, G4BREPSolidPolyhedra, and G4BREPSolidSphere.

Definition at line 1001 of file G4BREPSolid.cc.

References Intersect(), G4VSolid::kCarTolerance, Reset(), ShortestDistance, SurfaceVec, and TestSurfaceBBoxes().

01006 {
01007   // Calculates the distance from a point inside the solid to the solid's
01008   // boundary along a specified direction vector.
01009   // Returns 0 if the point is already outside.
01010   //
01011   // Note : If the shortest distance to a boundary is less than the tolerance,
01012   //        it is ignored. This allows for a point within a tolerant boundary
01013   //        to leave immediately.
01014 
01015   // Set the surfaces to active again
01016   //
01017   Reset();
01018 
01019   const G4double sqrHalfTolerance = kCarTolerance*kCarTolerance*0.25;
01020   G4Vector3D Ptv = P;
01021   G4int a;
01022 
01023   if(validNorm)
01024     *validNorm=false;
01025 
01026   G4Vector3D Pttmp(Ptv);
01027   G4Vector3D Vtmp(D);   
01028   
01029   G4Ray r(Pttmp, Vtmp);
01030 
01031   // Test if the bounding box of each surface is intersected
01032   // by the ray. If not, the surface become deactive.
01033   //
01034   TestSurfaceBBoxes(r);
01035   
01036   ShortestDistance = kInfinity;
01037  
01038   for(a=0; a< nb_of_surfaces; a++)
01039   {
01040     if(SurfaceVec[a]->IsActive())
01041     {
01042       // Test if the ray intersect the surface
01043       //
01044       if( (SurfaceVec[a]->Intersect(r)) )
01045       {
01046         // If more than 1 surface is intersected, take the nearest one
01047         //
01048         G4double surfDistance = SurfaceVec[a]->GetDistance();
01049         if( surfDistance < ShortestDistance )
01050         {
01051           if( surfDistance > sqrHalfTolerance )
01052           {
01053             ShortestDistance = surfDistance;
01054           }
01055           else
01056           {
01057             // The point is within the boundary: ignore it
01058           }
01059         }
01060       }
01061     }
01062   }
01063 
01064   // Be careful !
01065   // SurfaceVec->Distance is in fact the squared distance
01066   //
01067   if(ShortestDistance != kInfinity)
01068     return std::sqrt(ShortestDistance);
01069   else
01070     return 0.0;  // No intersection is found, the point is outside
01071 }

G4double G4BREPSolid::DistanceToOut ( const G4ThreeVector  )  const [virtual]

Implements G4VSolid.

Reimplemented in G4BREPSolidCone, G4BREPSolidPCone, G4BREPSolidPolyhedra, and G4BREPSolidSphere.

Definition at line 1073 of file G4BREPSolid.cc.

References Reset(), and SurfaceVec.

01074 {
01075   // Calculates the shortest distance ("safety") from a point
01076   // inside the solid to any boundary of this solid.
01077   // Returns 0 if the point is already outside.
01078 
01079   G4double *dists = new G4double[nb_of_surfaces];
01080   G4int a;
01081 
01082   // Set the surfaces to active again
01083   //
01084   Reset();
01085   
01086   // Compute the shortest distance of the point to each surfaces
01087   // Be careful : it's a signed value
01088   //
01089   for(a=0; a< nb_of_surfaces; a++)
01090     dists[a] = SurfaceVec[a]->HowNear(Pt);  
01091 
01092   G4double Dist = kInfinity;
01093   
01094   // If dists[] is negative, the point is inside so take the shortest of the
01095   // shortest negative distances dists[] can be equal to 0 : point on a
01096   // surface
01097   // ( Problem with the G4FPlane : there is no inside and no outside...
01098   //   So, to test if the point is outside to return 0, utilize the Inside()
01099   //   function. But I don`t know if it is really needed because dToOut is 
01100   //   called only if the point is inside )
01101   //
01102   for(a = 0; a < nb_of_surfaces; a++)
01103     if( std::fabs(Dist) > std::fabs(dists[a]) ) 
01104       //if( dists[a] <= 0)
01105         Dist = dists[a];
01106   
01107   delete[] dists;
01108 
01109   if(Dist == kInfinity)
01110     return 0;  // The point is ouside the solid or on a surface
01111   else
01112     return std::fabs(Dist);
01113 }

G4double G4BREPSolid::GetAreaAccuracy (  )  const [inline]

Definition at line 171 of file G4BREPSolid.icc.

00172 {
00173   return fAreaAccuracy;
00174 }

G4int G4BREPSolid::GetAreaStatistics (  )  const [inline]

Definition at line 166 of file G4BREPSolid.icc.

00167 {
00168   return fStatistics;
00169 }

const G4BoundingBox3D * G4BREPSolid::GetBBox (  )  const [inline]

Definition at line 102 of file G4BREPSolid.icc.

References bbox.

Referenced by G4BREPSolidPolyhedra::Inside(), G4BREPSolidPCone::Inside(), and Inside().

00103 {
00104   return bbox;
00105 } 

G4double G4BREPSolid::GetCubicVolume (  )  [inline, virtual]

Reimplemented from G4VSolid.

Definition at line 188 of file G4BREPSolid.icc.

References G4VSolid::EstimateCubicVolume().

00189 {
00190   if(fCubicVolume != 0.) {;}
00191   else   { fCubicVolume = EstimateCubicVolume(fStatistics,fCubVolEpsilon); }
00192   return fCubicVolume;
00193 }

G4double G4BREPSolid::GetCubVolEpsilon (  )  const [inline]

Definition at line 149 of file G4BREPSolid.icc.

00150 {
00151   return fCubVolEpsilon;
00152 }

G4int G4BREPSolid::GetCubVolStatistics (  )  const [inline]

Definition at line 144 of file G4BREPSolid.icc.

00145 {
00146   return fStatistics;
00147 }

G4String G4BREPSolid::GetEntityType (  )  const [virtual]

Implements G4VSolid.

Definition at line 191 of file G4BREPSolid.cc.

Referenced by StreamInfo().

00192 {
00193   return "Closed_Shell";
00194 }

G4int G4BREPSolid::GetId (  )  const [inline]

Definition at line 67 of file G4BREPSolid.icc.

References Id.

00068 {
00069   return Id;
00070 }

const G4String & G4BREPSolid::GetName (  )  const [inline]

Reimplemented from G4VSolid.

Definition at line 77 of file G4BREPSolid.icc.

References solidname.

Referenced by StreamInfo().

00078 {
00079   return solidname;
00080 }

G4int G4BREPSolid::GetNumberOfFaces (  )  const [inline]

Definition at line 92 of file G4BREPSolid.icc.

References nb_of_surfaces.

00093 {
00094   return nb_of_surfaces;
00095 }

G4int G4BREPSolid::GetNumberOfSolids (  )  const [inline]

Definition at line 87 of file G4BREPSolid.icc.

References NumberOfSolids.

00088 {
00089   return NumberOfSolids;
00090 }

const G4Axis2Placement3D * G4BREPSolid::GetPlace (  )  const [inline]

Definition at line 97 of file G4BREPSolid.icc.

References place.

00098 {
00099   return place;
00100 }

G4Polyhedron * G4BREPSolid::GetPolyhedron (  )  const [virtual]

Reimplemented from G4VSolid.

Definition at line 1524 of file G4BREPSolid.cc.

References CreatePolyhedron(), and G4Polyhedron::GetNumberOfRotationStepsAtTimeOfCreation().

01525 {
01526   if (!fpPolyhedron ||
01527       fpPolyhedron->GetNumberOfRotationStepsAtTimeOfCreation() !=
01528       fpPolyhedron->GetNumberOfRotationSteps())
01529     {
01530       delete fpPolyhedron;
01531       fpPolyhedron = CreatePolyhedron();
01532     }
01533   return fpPolyhedron;
01534 }

G4double G4BREPSolid::GetShortestDistance (  )  const [inline]

Definition at line 62 of file G4BREPSolid.icc.

References ShortestDistance.

00063 {
00064   return ShortestDistance;
00065 }

G4Surface * G4BREPSolid::GetSurface ( G4int   )  const [inline]

Definition at line 47 of file G4BREPSolid.icc.

References SurfaceVec.

00048 {
00049   return SurfaceVec[nr];
00050 }

G4double G4BREPSolid::GetSurfaceArea (  )  [inline, virtual]

Reimplemented from G4VSolid.

Definition at line 195 of file G4BREPSolid.icc.

References G4VSolid::EstimateSurfaceArea().

00196 {
00197   if(fSurfaceArea != 0.) {;}
00198   else   { fSurfaceArea = EstimateSurfaceArea(fStatistics,fAreaAccuracy); }
00199   return fSurfaceArea;
00200 }

void G4BREPSolid::Initialize (  )  [virtual]

Reimplemented in G4BREPSolidCone, G4BREPSolidPCone, and G4BREPSolidPolyhedra.

Definition at line 171 of file G4BREPSolid.cc.

References active, AxisBox, Box, CalcBBoxes(), CheckSurfaceNormals(), IsConvex(), ShortestDistance, and SurfaceVec.

Referenced by G4BREPSolid(), and operator=().

00172 {
00173   if(active)
00174   {
00175     // Compute bounding box for solids and surfaces
00176     // Convert concave planes to convex
00177     //
00178     ShortestDistance= kInfinity;
00179     if (!SurfaceVec) { return; }
00180 
00181     IsBox();
00182     CheckSurfaceNormals();
00183     
00184     if(!Box || !AxisBox)
00185       IsConvex();
00186     
00187     CalcBBoxes();
00188   }
00189 }

EInside G4BREPSolid::Inside ( register const G4ThreeVector Pt  )  const [virtual]

Reimplemented in G4BREPSolidBox, G4BREPSolidCone, G4BREPSolidPCone, G4BREPSolidPolyhedra, and G4BREPSolidSphere.

Definition at line 793 of file G4BREPSolid.cc.

References GetBBox(), Intersect(), G4VSolid::kCarTolerance, kInside, kOutside, kSurface, Reset(), SurfaceVec, and TestSurfaceBBoxes().

Referenced by CalculateExtent().

00794 {
00795   // This function finds if the point Pt is inside, 
00796   // outside or on the surface of the solid
00797 
00798   const G4double sqrHalfTolerance = kCarTolerance*kCarTolerance*0.25;
00799 
00800   G4Vector3D v(1, 0, 0.01);
00801   G4Vector3D Pttmp(Pt);
00802   G4Vector3D Vtmp(v);
00803   G4Ray r(Pttmp, Vtmp);
00804   
00805   // Check if point is inside the PCone bounding box
00806   //
00807   if( !GetBBox()->Inside(Pttmp) )
00808     return kOutside;
00809 
00810   // Set the surfaces to active again
00811   //
00812   Reset();
00813   
00814   // Test if the bounding box of each surface is intersected
00815   // by the ray. If not, the surface become deactive.
00816   //
00817   TestSurfaceBBoxes(r);
00818   
00819   G4int hits=0, samehit=0;
00820 
00821   for(G4int a=0; a < nb_of_surfaces; a++)
00822   {
00823     if(SurfaceVec[a]->IsActive())
00824     {
00825       // Count the number of intersections. If this number is odd,
00826       // the start of the ray is inside the volume bounded by the surfaces,
00827       // so increment the number of intersection by 1 if the point is not
00828       // on the surface and if this intersection was not found before.
00829       //
00830       if( (SurfaceVec[a]->Intersect(r)) & 1 )
00831       {
00832         // Test if the point is on the surface
00833         //
00834         if(SurfaceVec[a]->GetDistance() < sqrHalfTolerance)
00835           return kSurface;
00836 
00837         // Test if this intersection was found before
00838         //
00839         for(G4int i=0; i<a; i++)
00840           if(SurfaceVec[a]->GetDistance() == SurfaceVec[i]->GetDistance())
00841           {
00842             samehit++;
00843             break;
00844           }
00845 
00846         // Count the number of surfaces intersected by the ray
00847         //
00848         if(!samehit)
00849           hits++;
00850       }
00851     }
00852   }
00853    
00854   // If the number of surfaces intersected is odd,
00855   // the point is inside the solid
00856   //
00857   if(hits&1)
00858     return kInside;
00859   else
00860     return kOutside;
00861 }

G4int G4BREPSolid::Intersect ( register const G4Ray  )  const

Definition at line 1300 of file G4BREPSolid.cc.

References bbox, G4Surface::Deactivate(), G4Surface::GetClosestHit(), G4Surface::GetDistance(), G4Surface::Intersect(), G4Surface::IsActive(), G4VSolid::kCarTolerance, G4Surface::MyType(), QuickSort(), G4BoundingBox3D::SetDistance(), G4Surface::SurfaceNormal(), and SurfaceVec.

Referenced by G4BREPSolidPolyhedra::DistanceToIn(), G4BREPSolidPCone::DistanceToIn(), G4BREPSolidCone::DistanceToIn(), DistanceToIn(), G4BREPSolidSphere::DistanceToOut(), G4BREPSolidPolyhedra::DistanceToOut(), G4BREPSolidPCone::DistanceToOut(), G4BREPSolidCone::DistanceToOut(), DistanceToOut(), and Inside().

01301 {
01302   // Gets the roughly calculated closest intersection point for
01303   // a b_spline & accurate point for others.
01304 
01305   const G4double sqrHalfTolerance = kCarTolerance*kCarTolerance*0.25;
01306 
01307   register G4Surface* srf;
01308   G4double HitDistance = -1;
01309   const G4Point3D& RayStart = rayref.GetStart();
01310   const G4Point3D& RayDir   = rayref.GetDir();
01311 
01312   G4int result=1;
01313    
01314   // Sort List of active surfaces according to
01315   // bbox distances to ray starting point
01316   //
01317   QuickSort(SurfaceVec, 0, nb_of_surfaces-1);
01318   G4int Number=0;
01319    
01320   // Start handling active surfaces in order
01321   //
01322   for(register G4int a=0;a<nb_of_surfaces;a++)
01323   {
01324     srf = SurfaceVec[a];
01325     
01326     if(srf->IsActive())
01327     {
01328       result = srf->Intersect(rayref);
01329       if(result)
01330       {
01331         // Get the evaluated point on the surface
01332         //
01333         const G4Point3D& closest_point = srf->GetClosestHit();
01334 
01335         // Test for DistanceToIn(pt, vec)
01336         // if d = 0 and vec.norm > 0, do not see the surface
01337         //
01338         if( !( (srf->GetDistance() < sqrHalfTolerance)  || 
01339              (RayDir.dot(srf->SurfaceNormal(closest_point)) > 0) ) )
01340         {
01341   
01342           if(srf->MyType()==1)
01343             HitDistance = srf->GetDistance();
01344           else
01345           {
01346             // Check if the evaluated point is in front of the 
01347             // bbox of the next surface.
01348             // 
01349             HitDistance = RayStart.distance2(closest_point);
01350           }
01351         }
01352       }   
01353       else  // No hit
01354       {
01355         srf->Deactivate();
01356       }
01357     }
01358     Number++;
01359   }
01360   
01361   if(HitDistance < 0)
01362     return 0;
01363   
01364   QuickSort(SurfaceVec, 0, nb_of_surfaces-1);
01365   
01366   if(!(SurfaceVec[0]->IsActive()))
01367     return 0;     
01368   
01369   ((G4BREPSolid*)this)->intersection_point = SurfaceVec[0]->GetClosestHit();
01370   bbox->SetDistance(HitDistance);
01371 
01372   return 1;
01373 }

void G4BREPSolid::IntersectionDistance ( G4double   )  const [inline]

Definition at line 42 of file G4BREPSolid.icc.

00043 {
00044   ((G4BREPSolid*)this)->intersectionDistance=d;
00045 }   

G4double G4BREPSolid::IntersectionDistance (  )  const [inline]

Definition at line 37 of file G4BREPSolid.icc.

References intersectionDistance.

00038 {
00039   return intersectionDistance;
00040 }

G4bool G4BREPSolid::IsConvex (  )  [protected]

Definition at line 460 of file G4BREPSolid.cc.

References Convex, G4Ray::GetDir(), G4Surface::GetNumberOfPoints(), G4Surface::GetPoint(), G4Surface::IsConvex(), G4Surface::Norm(), PlaneSolid, and SurfaceVec.

Referenced by G4BREPSolidPolyhedra::Initialize(), G4BREPSolidPCone::Initialize(), G4BREPSolidCone::Initialize(), and Initialize().

00461 {
00462   if (!PlaneSolid) { return 0; }    // All faces must be planar
00463 
00464   // This is not robust. There can be concave solids
00465   // where the concavity comes for example from three triangles.
00466 
00467   // Additional checking 20.8. For each face the connecting faces are
00468   // found and the cross product computed between the face and each
00469   // connecting face. If the result changes value at any point the
00470   // solid is concave.
00471   
00472   G4Surface* Srf=0;
00473   G4Surface* ConnectedSrf=0;
00474   G4int Result;
00475   Convex = 1;
00476   
00477   G4int a, b, c, d;
00478   for(a=0;a<nb_of_surfaces;a++)
00479   {
00480     Srf = SurfaceVec[a];
00481 
00482     // Primary test. Test wether any one of the faces
00483     // is concave -> solid is concave. This is not enough to
00484     // distinguish all the cases of concavity.
00485     //
00486     Result = Srf->IsConvex();
00487     
00488     if (Result != -1)
00489     {
00490       Convex = 0;
00491       return 0;
00492     }
00493   }
00494 
00495   Srf = SurfaceVec[0];        
00496 
00497   G4int ConnectingPoints=0;  
00498   G4Point3D  Pt1, Pt2;
00499   G4Vector3D N1, N2;    
00500 
00501   // L. Broglia
00502   // The number of connecting points can be 
00503   // (nb_of_surfaces-1) * nb_of_surfaces  (loop a & loop b)
00504   
00505   // G4int* ConnectedList = new G4int[nb_of_surfaces];
00506   const G4int maxCNum =  (nb_of_surfaces-1)*nb_of_surfaces; 
00507   G4int* ConnectedList = new G4int[maxCNum];  
00508 
00509   for(a=0; a<maxCNum; a++)
00510   {
00511     ConnectedList[a]=0;
00512   }
00513   
00514   G4int Connections=0;
00515 
00516   for(a=0; a<nb_of_surfaces-1; a++)
00517   {
00518     Srf = SurfaceVec[a];
00519     G4int SrfPoints = Srf->GetNumberOfPoints();
00520     Result=0;
00521     
00522     for(b=0; b<nb_of_surfaces; b++)
00523     {
00524       if (b==a) { continue; }
00525 
00526       // Get next in List
00527       //
00528       ConnectedSrf = SurfaceVec[b];
00529       
00530       // Check if it is connected to Srf by looping through the points.
00531       //
00532       G4int ConnSrfPoints = ConnectedSrf->GetNumberOfPoints();
00533       
00534       for(c=0; c<SrfPoints; c++)
00535       {
00536         const G4Point3D& Pts1 =Srf->GetPoint(c);
00537 
00538         for(d=0; d<ConnSrfPoints; d++)
00539         {
00540           // Find common points
00541           //
00542           const G4Point3D& Pts2 = ConnectedSrf->GetPoint(d);
00543           if (Pts1 == Pts2)  { ConnectingPoints++; }
00544         }
00545         if (ConnectingPoints > 0)  { break; }
00546       }
00547       
00548       if (ConnectingPoints > 0)
00549       {
00550         Connections++;
00551         ConnectedList[Connections]=b;
00552       }
00553       ConnectingPoints=0;
00554     }
00555   }
00556   
00557   // If connected, check for concavity.
00558   // Get surfaces from ConnectedList and compare their normals
00559   //
00560   for(c=0; c<Connections; c++)
00561   {
00562     G4int Left=0; 
00563     G4int Right =0;
00564     G4int tmp = ConnectedList[c];
00565     
00566     Srf = SurfaceVec[tmp];
00567     ConnectedSrf = SurfaceVec[tmp+1];
00568     
00569     // Get normals
00570     //
00571     N1 = Srf->Norm()->GetDir();
00572     N2 = ConnectedSrf->Norm()->GetDir();
00573 
00574     // Check cross product
00575     //
00576     G4Vector3D CP = G4Vector3D( N1.cross(N2) ); 
00577     G4double CrossProd = CP.x()+CP.y()+CP.z();
00578     if (CrossProd > 0)  { Left++;  }
00579     if (CrossProd < 0)  { Right++; }
00580     if (Left&&Right)
00581     {
00582       Convex = 0;
00583       delete [] ConnectedList;
00584       return 0;
00585     }
00586     Connections=0;
00587   } 
00588   
00589   Convex=1;
00590 
00591   delete [] ConnectedList;
00592 
00593   return 1;
00594 }

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

Definition at line 138 of file G4BREPSolid.cc.

References active, AxisBox, bbox, Box, Convex, fAreaAccuracy, fCubicVolume, fCubVolEpsilon, fStatistics, fSurfaceArea, Id, Initialize(), intersection_point, intersectionDistance, nb_of_surfaces, G4VSolid::operator=(), place, PlaneSolid, RealDist, solidname, startInside, and SurfaceVec.

Referenced by G4BREPSolidTorus::operator=(), G4BREPSolidSphere::operator=(), G4BREPSolidPolyhedra::operator=(), G4BREPSolidPCone::operator=(), G4BREPSolidCylinder::operator=(), G4BREPSolidCone::operator=(), and G4BREPSolidBox::operator=().

00139 {
00140    // Check assignment to self
00141    //
00142    if (this == &rhs)  { return *this; }
00143 
00144    // Copy base class data
00145    //
00146    G4VSolid::operator=(rhs);
00147 
00148    // Copy data
00149    //
00150    Box= rhs.Box; Convex= rhs.Convex; AxisBox= rhs.AxisBox;
00151    PlaneSolid= rhs.PlaneSolid;
00152    intersectionDistance= rhs.intersectionDistance; active= rhs.active;
00153    startInside= rhs.startInside; nb_of_surfaces= rhs.nb_of_surfaces;
00154    intersection_point= rhs.intersection_point;
00155    RealDist= rhs.RealDist; solidname= rhs.solidname; Id= rhs.Id;
00156    fStatistics= rhs.fStatistics; fCubVolEpsilon= rhs.fCubVolEpsilon;
00157    fAreaAccuracy= rhs.fAreaAccuracy; fCubicVolume= rhs.fCubicVolume;
00158    fSurfaceArea= rhs.fSurfaceArea;
00159 
00160    delete place; delete bbox; place= 0; bbox= 0;
00161    for(G4int a=0;a<nb_of_surfaces;++a)
00162      { delete SurfaceVec[a]; }
00163    delete [] SurfaceVec; SurfaceVec= 0;
00164    delete fpPolyhedron; fpPolyhedron= 0;
00165 
00166    Initialize();
00167 
00168    return *this;
00169 }  

void G4BREPSolid::QuickSort ( register G4Surface **  SrfVec,
register G4int  left,
register G4int  right 
) const [inline, protected]

Definition at line 117 of file G4BREPSolid.icc.

References G4Surface::GetDistance().

Referenced by Intersect().

00120 {
00121     register G4int i=left;
00122     register G4int j=right;
00123     register G4Surface* elem1;
00124     register G4Surface* elem2 = SrfVec[(left+right)/2];
00125     register G4double tmpdistance;
00126     do
00127     {
00128       tmpdistance = elem2->GetDistance();
00129       while ( SrfVec[i]->GetDistance() < tmpdistance  && i < right ) i++;
00130       while (tmpdistance < SrfVec[j]->GetDistance()  && j > left ) j--;
00131       if(i<=j)
00132       {
00133         elem1 = SrfVec[i];
00134         SrfVec[i] = SrfVec[j];
00135         SrfVec[j] = elem1;
00136         i++;j--;
00137       }
00138     } while (i<=j);
00139       
00140     if( left < j  ) QuickSort(SrfVec,left, j );
00141     if( i < right ) QuickSort(SrfVec,i, right);    
00142 }

void G4BREPSolid::RemoveHiddenFaces ( register const G4Ray G4Rayref,
G4int   
) const [protected]

Definition at line 1200 of file G4BREPSolid.cc.

References G4Surface::Deactivate(), G4Surface::MyType(), G4Surface::Norm(), and SurfaceVec.

01202 {
01203   // Deactivates the planar faces that are on the "back" side of a solid.
01204   // B-splines are not handled by this function. Also cases where the ray
01205   // starting point is Inside the bbox of the solid are ignored as we don't
01206   // know if the starting point is Inside the actual solid except for
01207   // axis-oriented box-like solids.
01208   
01209   register G4Surface* srf;
01210   register const G4Vector3D& RayDir = rayref.GetDir();
01211   register G4double Result;
01212   G4int a;
01213 
01214   // In all other cases the ray starting point is outside the solid
01215   //
01216   if(!In)
01217     for(a=0; a<nb_of_surfaces; a++)
01218     {
01219       // Deactivates the solids faces that are hidden
01220       //
01221       srf = SurfaceVec[a];
01222       if(srf->MyType()==1)
01223       {
01224         const G4Vector3D& Normal = (srf->Norm())->GetDir();
01225         Result = (RayDir * Normal);
01226 
01227         if( Result >= 0 )
01228           srf->Deactivate();
01229       }
01230     }
01231   else
01232     for(a=0; a<nb_of_surfaces; a++)
01233     {
01234       // Deactivates the AxisBox type solids faces whose normals 
01235       // point in the G4Vector3D opposite to the rays G4Vector3D
01236       // i.e. are behind the ray starting point as in this case the
01237       // ray starts from Inside the solid.
01238       //
01239       srf = SurfaceVec[a];
01240       if(srf->MyType()==1)
01241       {
01242         const G4Vector3D& Normal = (srf->Norm())->GetDir();
01243         Result = (RayDir * Normal);
01244 
01245         if( Result < 0 )
01246           srf->Deactivate();
01247       }
01248     }
01249 }

void G4BREPSolid::Reset (  )  const [virtual]

Reimplemented in G4BREPSolidPCone, and G4BREPSolidPolyhedra.

Definition at line 201 of file G4BREPSolid.cc.

References nb_of_surfaces, ShortestDistance, and SurfaceVec.

Referenced by G4BREPSolidCone::DistanceToIn(), DistanceToIn(), G4BREPSolidCone::DistanceToOut(), DistanceToOut(), and Inside().

00202 {
00203   ((G4BREPSolid*)this)->active=1;
00204   ((G4BREPSolid*)this)->intersectionDistance=kInfinity;
00205   ((G4BREPSolid*)this)->startInside=0; 
00206      
00207   for(register G4int a=0;a<nb_of_surfaces;a++)
00208     SurfaceVec[a]->Reset();
00209 
00210   ShortestDistance = kInfinity;
00211 }

G4Point3D G4BREPSolid::Scope (  )  const

Definition at line 1498 of file G4BREPSolid.cc.

References bbox, G4BoundingBox3D::GetBoxMax(), and G4BoundingBox3D::GetBoxMin().

01499 {
01500   G4Point3D scope;
01501   G4Point3D Max = bbox->GetBoxMax();
01502   G4Point3D Min = bbox->GetBoxMin();  
01503   
01504   scope.setX(std::fabs(Max.x()) - std::fabs(Min.x()));
01505   scope.setY(std::fabs(Max.y()) - std::fabs(Min.y()));
01506   scope.setZ(std::fabs(Max.z()) - std::fabs(Min.z()));
01507   
01508   return scope;
01509 }

void G4BREPSolid::SetAreaAccuracy ( G4double  ep  )  [inline]

Definition at line 182 of file G4BREPSolid.icc.

00183 {
00184   fSurfaceArea=0.;
00185   fAreaAccuracy=ep;
00186 }

void G4BREPSolid::SetAreaStatistics ( G4int  st  )  [inline]

Definition at line 176 of file G4BREPSolid.icc.

00177 {
00178   fSurfaceArea=0.;
00179   fStatistics=st;
00180 }

void G4BREPSolid::SetCubVolEpsilon ( G4double  ep  )  [inline]

Definition at line 160 of file G4BREPSolid.icc.

00161 {
00162   fCubicVolume=0.;
00163   fCubVolEpsilon=ep;
00164 }

void G4BREPSolid::SetCubVolStatistics ( G4int  st  )  [inline]

Definition at line 154 of file G4BREPSolid.icc.

00155 {
00156   fCubicVolume=0.;
00157   fStatistics=st;
00158 }

void G4BREPSolid::SetId ( G4int   )  [inline]

Definition at line 72 of file G4BREPSolid.icc.

References Id.

00073 {
00074   Id = n;
00075 }

void G4BREPSolid::SetName ( const G4String name  )  [inline]

Reimplemented from G4VSolid.

Definition at line 82 of file G4BREPSolid.icc.

References solidname.

00083 {
00084   solidname = name;
00085 }

void G4BREPSolid::StartInside ( G4int  si  )  const [inline, protected]

Definition at line 112 of file G4BREPSolid.icc.

00113 {
00114   ((G4BREPSolid*)this)->startInside=si;
00115 }  

G4int G4BREPSolid::StartInside (  )  const [inline, protected]

Definition at line 107 of file G4BREPSolid.icc.

References startInside.

Referenced by G4BREPSolidPolyhedra::Reset(), and G4BREPSolidPCone::Reset().

00108 {
00109   return startInside;
00110 }

std::ostream & G4BREPSolid::StreamInfo ( std::ostream &  os  )  const [virtual]

Implements G4VSolid.

Reimplemented in G4BREPSolidBox, G4BREPSolidCone, G4BREPSolidCylinder, G4BREPSolidPCone, G4BREPSolidPolyhedra, G4BREPSolidSphere, and G4BREPSolidTorus.

Definition at line 1511 of file G4BREPSolid.cc.

References GetEntityType(), GetName(), and NumberOfSolids.

Referenced by G4PlacedSolid::StreamInfo(), G4BREPSolidTorus::StreamInfo(), G4BREPSolidSphere::StreamInfo(), G4BREPSolidPolyhedra::StreamInfo(), G4BREPSolidPCone::StreamInfo(), G4BREPSolidCylinder::StreamInfo(), G4BREPSolidCone::StreamInfo(), and G4BREPSolidBox::StreamInfo().

01512 {
01513   os << "-----------------------------------------------------------\n"
01514      << "    *** Dump for solid - " << GetName() << " ***\n"
01515      << "    ===================================================\n"
01516      << " Solid type: " << GetEntityType() << "\n"
01517      << " Parameters: \n"
01518      << "   Number of solids: " << NumberOfSolids << "\n"
01519      << "-----------------------------------------------------------\n";
01520 
01521   return os;
01522 }

G4ThreeVector G4BREPSolid::SurfaceNormal ( const G4ThreeVector  )  const [virtual]

Implements G4VSolid.

Reimplemented in G4BREPSolidCone, G4BREPSolidPCone, G4BREPSolidPolyhedra, and G4BREPSolidSphere.

Definition at line 863 of file G4BREPSolid.cc.

References G4VSolid::kCarTolerance, G4Surface::SurfaceNormal(), and SurfaceVec.

00864 {  
00865   // This function calculates the normal of the surface at a point on the
00866   // surface. If the point is not on the surface the result is undefined.
00867   // Note : the sense of the normal depends on the sense of the surface.
00868 
00869   const G4double sqrHalfTolerance = kCarTolerance*kCarTolerance*0.25;
00870   G4int          iplane;
00871     
00872   // Find on which surface the point is
00873   //
00874   for(iplane = 0; iplane < nb_of_surfaces; iplane++)
00875   {
00876     if(SurfaceVec[iplane]->HowNear(Pt) < sqrHalfTolerance)
00877       // the point is on this surface
00878       break;
00879   }
00880   
00881   // Calculate the normal at this point
00882   //
00883   G4ThreeVector norm = SurfaceVec[iplane]->SurfaceNormal(Pt);
00884 
00885   return norm.unit();
00886 }

void G4BREPSolid::TestSurfaceBBoxes ( register const G4Ray  )  const [protected]

Definition at line 1251 of file G4BREPSolid.cc.

References Active(), bbox, G4Surface::Deactivate(), G4Surface::GetBBox(), G4BoundingBox3D::GetDistance(), G4Surface::Intersect(), G4Surface::IsActive(), G4Surface::MyType(), G4Surface::SetDistance(), SurfaceVec, and G4BoundingBox3D::Test().

Referenced by G4BREPSolidPolyhedra::DistanceToIn(), G4BREPSolidPCone::DistanceToIn(), DistanceToIn(), G4BREPSolidPolyhedra::DistanceToOut(), G4BREPSolidPCone::DistanceToOut(), DistanceToOut(), G4BREPSolidPolyhedra::Inside(), G4BREPSolidPCone::Inside(), and Inside().

01252 {
01253   register G4Surface* srf;
01254   G4int active_srfs = nb_of_surfaces;
01255   
01256   // Do the bbox tests to all surfaces in List
01257   // for planar faces the intersection is instead evaluated.
01258   //
01259   G4int intersection=0;
01260   
01261   for(G4int a=0;a<nb_of_surfaces;a++)
01262   {
01263     // Get first in List
01264     //
01265     srf = SurfaceVec[a];
01266     
01267     if(srf->IsActive())
01268     {
01269       // Get type
01270       //
01271       if(srf->MyType() != 1) // 1 == planar face
01272       {
01273         if(srf->GetBBox()->Test(rayref))
01274           srf->SetDistance(bbox->GetDistance());
01275         else
01276         {
01277           // Test failed. Flag as inactive.
01278           //
01279           srf->Deactivate();
01280           active_srfs--;
01281         }
01282       }
01283       else
01284       {
01285         // Type was convex planar face
01286         intersection = srf->Intersect(rayref);
01287 
01288         if(!intersection) 
01289           active_srfs--;
01290       }
01291     }
01292     else
01293       active_srfs--;
01294   }
01295   
01296   if(!active_srfs) Active(0);
01297 }


Field Documentation

G4int G4BREPSolid::active [protected]

Definition at line 227 of file G4BREPSolid.hh.

Referenced by Active(), CalcBBoxes(), G4BREPSolidBox::G4BREPSolidBox(), G4BREPSolidCone::G4BREPSolidCone(), G4BREPSolidCylinder::G4BREPSolidCylinder(), G4BREPSolidPCone::G4BREPSolidPCone(), G4BREPSolidPolyhedra::G4BREPSolidPolyhedra(), G4BREPSolidSphere::G4BREPSolidSphere(), G4BREPSolidTorus::G4BREPSolidTorus(), Initialize(), operator=(), and G4BREPSolidSphere::SphReset().

G4int G4BREPSolid::AxisBox [protected]

Definition at line 223 of file G4BREPSolid.hh.

Referenced by G4BREPSolidPolyhedra::Initialize(), G4BREPSolidPCone::Initialize(), G4BREPSolidCone::Initialize(), Initialize(), and operator=().

G4BoundingBox3D* G4BREPSolid::bbox [protected]

Definition at line 225 of file G4BREPSolid.hh.

Referenced by CalcBBoxes(), CalculateExtent(), CreateNURBS(), CreatePolyhedron(), CreateRotatedVertices(), GetBBox(), G4BREPSolidBox::Inside(), Intersect(), operator=(), Scope(), TestSurfaceBBoxes(), and ~G4BREPSolid().

G4int G4BREPSolid::Box [protected]

Definition at line 223 of file G4BREPSolid.hh.

Referenced by G4BREPSolidPolyhedra::Initialize(), G4BREPSolidPCone::Initialize(), G4BREPSolidCone::Initialize(), Initialize(), and operator=().

G4int G4BREPSolid::Convex [protected]

Definition at line 223 of file G4BREPSolid.hh.

Referenced by CheckSurfaceNormals(), IsConvex(), and operator=().

G4int G4BREPSolid::Id [protected]

Definition at line 234 of file G4BREPSolid.hh.

Referenced by GetId(), operator=(), and SetId().

G4Point3D G4BREPSolid::intersection_point [protected]

Definition at line 230 of file G4BREPSolid.hh.

Referenced by operator=().

G4double G4BREPSolid::intersectionDistance [protected]

Definition at line 226 of file G4BREPSolid.hh.

Referenced by IntersectionDistance(), and operator=().

G4int G4BREPSolid::nb_of_surfaces [protected]

Definition at line 229 of file G4BREPSolid.hh.

Referenced by CheckSurfaceNormals(), G4BREPSolidPolyhedra::DistanceToIn(), G4BREPSolidPCone::DistanceToIn(), G4BREPSolidPolyhedra::DistanceToOut(), G4BREPSolidPCone::DistanceToOut(), G4BREPSolidBox::G4BREPSolidBox(), G4BREPSolidCone::G4BREPSolidCone(), G4BREPSolidCylinder::G4BREPSolidCylinder(), GetNumberOfFaces(), G4BREPSolidPolyhedra::Inside(), G4BREPSolidPCone::Inside(), operator=(), G4BREPSolidPolyhedra::Reset(), G4BREPSolidPCone::Reset(), Reset(), G4BREPSolidPolyhedra::SurfaceNormal(), G4BREPSolidPCone::SurfaceNormal(), and ~G4BREPSolid().

G4int G4BREPSolid::NumberOfSolids = 0 [static, protected]

Definition at line 219 of file G4BREPSolid.hh.

Referenced by GetNumberOfSolids(), and StreamInfo().

G4Axis2Placement3D* G4BREPSolid::place [protected]

Definition at line 224 of file G4BREPSolid.hh.

Referenced by GetPlace(), operator=(), and ~G4BREPSolid().

G4int G4BREPSolid::PlaneSolid [protected]

Definition at line 223 of file G4BREPSolid.hh.

Referenced by CheckSurfaceNormals(), G4BREPSolidBox::G4BREPSolidBox(), IsConvex(), and operator=().

G4double G4BREPSolid::RealDist [protected]

Definition at line 232 of file G4BREPSolid.hh.

Referenced by operator=().

G4double G4BREPSolid::ShortestDistance = kInfinity [static, protected]

Definition at line 221 of file G4BREPSolid.hh.

Referenced by G4BREPSolidSphere::DistanceToIn(), G4BREPSolidPolyhedra::DistanceToIn(), G4BREPSolidPCone::DistanceToIn(), G4BREPSolidCone::DistanceToIn(), DistanceToIn(), G4BREPSolidSphere::DistanceToOut(), G4BREPSolidPolyhedra::DistanceToOut(), G4BREPSolidPCone::DistanceToOut(), G4BREPSolidCone::DistanceToOut(), DistanceToOut(), GetShortestDistance(), G4BREPSolidPolyhedra::Initialize(), G4BREPSolidPCone::Initialize(), G4BREPSolidCone::Initialize(), Initialize(), G4BREPSolidPolyhedra::Reset(), G4BREPSolidPCone::Reset(), and Reset().

G4String G4BREPSolid::solidname [protected]

Definition at line 233 of file G4BREPSolid.hh.

Referenced by GetName(), operator=(), and SetName().

G4int G4BREPSolid::startInside [protected]

Definition at line 228 of file G4BREPSolid.hh.

Referenced by operator=(), and StartInside().

G4Surface** G4BREPSolid::SurfaceVec [protected]

Definition at line 231 of file G4BREPSolid.hh.

Referenced by CalcBBoxes(), CheckSurfaceNormals(), G4BREPSolidSphere::DistanceToIn(), G4BREPSolidPolyhedra::DistanceToIn(), G4BREPSolidPCone::DistanceToIn(), G4BREPSolidCone::DistanceToIn(), DistanceToIn(), G4BREPSolidSphere::DistanceToOut(), G4BREPSolidPolyhedra::DistanceToOut(), G4BREPSolidPCone::DistanceToOut(), G4BREPSolidCone::DistanceToOut(), DistanceToOut(), GetSurface(), Initialize(), G4BREPSolidSphere::Inside(), G4BREPSolidPolyhedra::Inside(), G4BREPSolidPCone::Inside(), G4BREPSolidCone::Inside(), Inside(), Intersect(), IsConvex(), operator=(), RemoveHiddenFaces(), G4BREPSolidPolyhedra::Reset(), G4BREPSolidPCone::Reset(), Reset(), G4BREPSolidSphere::SurfaceNormal(), G4BREPSolidPolyhedra::SurfaceNormal(), G4BREPSolidPCone::SurfaceNormal(), G4BREPSolidCone::SurfaceNormal(), SurfaceNormal(), TestSurfaceBBoxes(), and ~G4BREPSolid().

G4Ray G4BREPSolid::Track [static, protected]

Definition at line 220 of file G4BREPSolid.hh.


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