00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
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
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
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
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
00095
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
00108
00109 G4BooleanSolid::~G4BooleanSolid()
00110 {
00111 if(createdDisplacedSolid)
00112 {
00113 ((G4DisplacedSolid*)fPtrSolidB)->CleanTransformations();
00114 }
00115 delete fpPolyhedron;
00116 }
00117
00119
00120
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
00135
00136 G4BooleanSolid& G4BooleanSolid::operator = (const G4BooleanSolid& rhs)
00137 {
00138
00139
00140 if (this == &rhs) { return *this; }
00141
00142
00143
00144 G4VSolid::operator=(rhs);
00145
00146
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
00161
00162
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
00184
00185
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
00207
00208 G4GeometryType G4BooleanSolid::GetEntityType() const
00209 {
00210 return G4String("G4BooleanSolid");
00211 }
00212
00214
00215
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
00235
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
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
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 }