G4BooleanSolid.cc

Go to the documentation of this file.
00001 //
00002 // ********************************************************************
00003 // * License and Disclaimer                                           *
00004 // *                                                                  *
00005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
00006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
00007 // * conditions of the Geant4 Software License,  included in the file *
00008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
00009 // * include a list of copyright holders.                             *
00010 // *                                                                  *
00011 // * Neither the authors of this software system, nor their employing *
00012 // * institutes,nor the agencies providing financial support for this *
00013 // * work  make  any representation or  warranty, express or implied, *
00014 // * regarding  this  software system or assume any liability for its *
00015 // * use.  Please see the license in the file  LICENSE  and URL above *
00016 // * for the full disclaimer and the limitation of liability.         *
00017 // *                                                                  *
00018 // * This  code  implementation is the result of  the  scientific and *
00019 // * technical work of the GEANT4 collaboration.                      *
00020 // * By using,  copying,  modifying or  distributing the software (or *
00021 // * any work based  on the software)  you  agree  to acknowledge its *
00022 // * use  in  resulting  scientific  publications,  and indicate your *
00023 // * acceptance of all terms of the Geant4 Software license.          *
00024 // ********************************************************************
00025 //
00026 //
00027 // $Id$
00028 //
00029 // Implementation for the abstract base class for solids created by boolean 
00030 // operations between other solids
00031 //
00032 // History:
00033 //
00034 // 10.09.98 V.Grichine, created
00035 //
00036 // --------------------------------------------------------------------
00037 
00038 #include "G4BooleanSolid.hh"
00039 #include "G4VSolid.hh"
00040 #include "G4Polyhedron.hh"
00041 #include "HepPolyhedronProcessor.h"
00042 #include "Randomize.hh"
00043 
00045 //
00046 // Constructor
00047 
00048 G4BooleanSolid::G4BooleanSolid( const G4String& pName,
00049                                 G4VSolid* pSolidA ,
00050                                 G4VSolid* pSolidB   ) :
00051   G4VSolid(pName), fAreaRatio(0.), fStatistics(1000000), fCubVolEpsilon(0.001),
00052   fAreaAccuracy(-1.), fCubicVolume(0.), fSurfaceArea(0.),
00053   fpPolyhedron(0), createdDisplacedSolid(false)
00054 {
00055   fPtrSolidA = pSolidA ;
00056   fPtrSolidB = pSolidB ;
00057 }
00058 
00060 //
00061 // Constructor
00062 
00063 G4BooleanSolid::G4BooleanSolid( const G4String& pName,
00064                                       G4VSolid* pSolidA ,
00065                                       G4VSolid* pSolidB ,
00066                                       G4RotationMatrix* rotMatrix,
00067                                 const G4ThreeVector& transVector    ) :
00068   G4VSolid(pName), fAreaRatio(0.), fStatistics(1000000), fCubVolEpsilon(0.001),
00069   fAreaAccuracy(-1.), fCubicVolume(0.), fSurfaceArea(0.),
00070   fpPolyhedron(0), createdDisplacedSolid(true)
00071 {
00072   fPtrSolidA = pSolidA ;
00073   fPtrSolidB = new G4DisplacedSolid("placedB",pSolidB,rotMatrix,transVector) ;
00074 }
00075 
00077 //
00078 // Constructor
00079 
00080 G4BooleanSolid::G4BooleanSolid( const G4String& pName,
00081                                       G4VSolid* pSolidA ,
00082                                       G4VSolid* pSolidB ,
00083                                 const G4Transform3D& transform    ) :
00084   G4VSolid(pName), fAreaRatio(0.), fStatistics(1000000), fCubVolEpsilon(0.001),
00085   fAreaAccuracy(-1.), fCubicVolume(0.), fSurfaceArea(0.),
00086   fpPolyhedron(0), createdDisplacedSolid(true)
00087 {
00088   fPtrSolidA = pSolidA ;
00089   fPtrSolidB = new G4DisplacedSolid("placedB",pSolidB,transform) ;
00090 }
00091 
00093 //
00094 // Fake default constructor - sets only member data and allocates memory
00095 //                            for usage restricted to object persistency.
00096 
00097 G4BooleanSolid::G4BooleanSolid( __void__& a )
00098   : G4VSolid(a), fPtrSolidA(0), fPtrSolidB(0), fAreaRatio(0.),
00099     fStatistics(1000000), fCubVolEpsilon(0.001), 
00100     fAreaAccuracy(-1.), fCubicVolume(0.), fSurfaceArea(0.),
00101     fpPolyhedron(0), createdDisplacedSolid(false)
00102 {
00103 }
00104 
00106 //
00107 // Destructor deletes transformation contents of the created displaced solid
00108 
00109 G4BooleanSolid::~G4BooleanSolid() 
00110 {
00111   if(createdDisplacedSolid)
00112   {
00113     ((G4DisplacedSolid*)fPtrSolidB)->CleanTransformations();
00114   }
00115   delete fpPolyhedron;
00116 }
00117 
00119 //
00120 // Copy constructor
00121 
00122 G4BooleanSolid::G4BooleanSolid(const G4BooleanSolid& rhs)
00123   : G4VSolid (rhs), fPtrSolidA(rhs.fPtrSolidA), fPtrSolidB(rhs.fPtrSolidB),
00124     fAreaRatio(rhs.fAreaRatio),
00125     fStatistics(rhs.fStatistics), fCubVolEpsilon(rhs.fCubVolEpsilon),
00126     fAreaAccuracy(rhs.fAreaAccuracy), fCubicVolume(rhs.fCubicVolume),
00127     fSurfaceArea(rhs.fSurfaceArea), fpPolyhedron(0),
00128     createdDisplacedSolid(rhs.createdDisplacedSolid)
00129 {
00130 }
00131 
00133 //
00134 // Assignment operator
00135 
00136 G4BooleanSolid& G4BooleanSolid::operator = (const G4BooleanSolid& rhs) 
00137 {
00138   // Check assignment to self
00139   //
00140   if (this == &rhs)  { return *this; }
00141 
00142   // Copy base class data
00143   //
00144   G4VSolid::operator=(rhs);
00145 
00146   // Copy data
00147   //
00148   fPtrSolidA= rhs.fPtrSolidA; fPtrSolidB= rhs.fPtrSolidB;
00149   fAreaRatio= rhs.fAreaRatio;
00150   fStatistics= rhs.fStatistics; fCubVolEpsilon= rhs.fCubVolEpsilon;
00151   fAreaAccuracy= rhs.fAreaAccuracy; fCubicVolume= rhs.fCubicVolume;
00152   fSurfaceArea= rhs.fSurfaceArea; fpPolyhedron= 0;
00153   createdDisplacedSolid= rhs.createdDisplacedSolid;
00154 
00155   return *this;
00156 }  
00157 
00159 //
00160 // If Solid is made up from a Boolean operation of two solids,
00161 //   return the corresponding solid (for no=0 and 1)
00162 // If the solid is not a "Boolean", return 0
00163 
00164 const G4VSolid* G4BooleanSolid::GetConstituentSolid(G4int no) const
00165 {
00166   const G4VSolid*  subSolid=0;
00167   if( no == 0 )  
00168     subSolid = fPtrSolidA;
00169   else if( no == 1 ) 
00170     subSolid = fPtrSolidB;
00171   else
00172   {
00173     DumpInfo();
00174     G4Exception("G4BooleanSolid::GetConstituentSolid()",
00175                 "GeomSolids0002", FatalException, "Invalid solid index.");
00176   }
00177 
00178   return subSolid;
00179 }
00180 
00182 //
00183 // If Solid is made up from a Boolean operation of two solids,
00184 //   return the corresponding solid (for no=0 and 1)
00185 // If the solid is not a "Boolean", return 0
00186 
00187 G4VSolid* G4BooleanSolid::GetConstituentSolid(G4int no)
00188 {
00189   G4VSolid*  subSolid=0;
00190   if( no == 0 )  
00191     subSolid = fPtrSolidA;
00192   else if( no == 1 ) 
00193     subSolid = fPtrSolidB;
00194   else
00195   {
00196     DumpInfo();
00197     G4Exception("G4BooleanSolid::GetConstituentSolid()",
00198                 "GeomSolids0002", FatalException, "Invalid solid index.");
00199   }
00200 
00201   return subSolid;
00202 }
00203 
00205 //
00206 // Returns entity type
00207 
00208 G4GeometryType G4BooleanSolid::GetEntityType() const 
00209 {
00210   return G4String("G4BooleanSolid");
00211 }
00212 
00214 //
00215 // Stream object contents to an output stream
00216 
00217 std::ostream& G4BooleanSolid::StreamInfo(std::ostream& os) const
00218 {
00219   os << "-----------------------------------------------------------\n"
00220      << "    *** Dump for Boolean solid - " << GetName() << " ***\n"
00221      << "    ===================================================\n"
00222      << " Solid type: " << GetEntityType() << "\n"
00223      << " Parameters of constituent solids: \n"
00224      << "===========================================================\n";
00225   fPtrSolidA->StreamInfo(os);
00226   fPtrSolidB->StreamInfo(os);
00227   os << "===========================================================\n";
00228 
00229   return os;
00230 }
00231 
00233 //
00234 // Returns a point (G4ThreeVector) randomly and uniformly selected
00235 // on the solid surface
00236 //
00237 
00238 G4ThreeVector G4BooleanSolid::GetPointOnSurface() const
00239 {
00240   G4double rand;
00241   G4ThreeVector p;
00242 
00243   do
00244   {
00245     rand = G4UniformRand();
00246 
00247     if (rand < GetAreaRatio()) { p = fPtrSolidA->GetPointOnSurface(); }
00248     else                       { p = fPtrSolidB->GetPointOnSurface(); }
00249   } while (Inside(p) != kSurface);
00250 
00251   return p;
00252 }
00253 
00255 //
00256 // Returns polyhedron for visualization
00257 
00258 G4Polyhedron* G4BooleanSolid::GetPolyhedron () const
00259 {
00260   if (!fpPolyhedron ||
00261       fpPolyhedron->GetNumberOfRotationStepsAtTimeOfCreation() !=
00262       fpPolyhedron->GetNumberOfRotationSteps())
00263     {
00264       delete fpPolyhedron;
00265       fpPolyhedron = CreatePolyhedron();
00266     }
00267   return fpPolyhedron;
00268 }
00269 
00271 //
00272 // Stacks polyhedra for processing. Returns top polyhedron.
00273 
00274 G4Polyhedron*
00275 G4BooleanSolid::StackPolyhedron(HepPolyhedronProcessor& processor,
00276                                 const G4VSolid* solid) const
00277 {
00278   HepPolyhedronProcessor::Operation operation;
00279   const G4String& type = solid->GetEntityType();
00280   if (type == "G4UnionSolid")
00281     { operation = HepPolyhedronProcessor::UNION; }
00282   else if (type == "G4IntersectionSolid")
00283     { operation = HepPolyhedronProcessor::INTERSECTION; }
00284   else if (type == "G4SubtractionSolid")
00285     { operation = HepPolyhedronProcessor::SUBTRACTION; }
00286   else
00287   {
00288     std::ostringstream message;
00289     message << "Solid - " << solid->GetName()
00290             << " - Unrecognised composite solid" << G4endl
00291             << " Returning NULL !";
00292     G4Exception("StackPolyhedron()", "GeomSolids1001", JustWarning, message);
00293     return 0;
00294   }
00295 
00296   G4Polyhedron* top = 0;
00297   const G4VSolid* solidA = solid->GetConstituentSolid(0);
00298   const G4VSolid* solidB = solid->GetConstituentSolid(1);
00299 
00300   if (solidA->GetConstituentSolid(0))
00301   {
00302     top = StackPolyhedron(processor, solidA);
00303   }
00304   else
00305   {
00306     top = solidA->GetPolyhedron();
00307   }
00308   G4Polyhedron* operand = solidB->GetPolyhedron();
00309   processor.push_back (operation, *operand);
00310 
00311   return top;
00312 }

Generated on Mon May 27 17:47:46 2013 for Geant4 by  doxygen 1.4.7