Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/geometry/solids/Boolean/src/G4BooleanSolid.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /geometry/solids/Boolean/src/G4BooleanSolid.cc (Version 11.3.0) and /geometry/solids/Boolean/src/G4BooleanSolid.cc (Version 11.2.1)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
 26 // Implementation of the base class for solids     26 // Implementation of the base class for solids created by Boolean 
 27 // operations between other solids                 27 // operations between other solids
 28 //                                                 28 //
 29 // 1998.09.10 V.Grichine - created                 29 // 1998.09.10 V.Grichine - created
 30 // -------------------------------------------     30 // --------------------------------------------------------------------
 31                                                    31 
 32 #include "G4BooleanSolid.hh"                       32 #include "G4BooleanSolid.hh"
 33 #include "G4VSolid.hh"                             33 #include "G4VSolid.hh"
 34 #include "G4DisplacedSolid.hh"                     34 #include "G4DisplacedSolid.hh"
 35 #include "G4ReflectedSolid.hh"                     35 #include "G4ReflectedSolid.hh"
 36 #include "G4ScaledSolid.hh"                        36 #include "G4ScaledSolid.hh"
 37 #include "G4Polyhedron.hh"                         37 #include "G4Polyhedron.hh"
 38 #include "HepPolyhedronProcessor.h"                38 #include "HepPolyhedronProcessor.h"
 39 #include "G4QuickRand.hh"                          39 #include "G4QuickRand.hh"
 40                                                    40 
 41 #include "G4AutoLock.hh"                           41 #include "G4AutoLock.hh"
 42                                                    42 
 43 namespace                                          43 namespace
 44 {                                                  44 {
 45   G4RecursiveMutex polyhedronMutex = G4MUTEX_I     45   G4RecursiveMutex polyhedronMutex = G4MUTEX_INITIALIZER;
 46 }                                                  46 }
 47                                                    47 
 48 G4VBooleanProcessor* G4BooleanSolid::fExternal     48 G4VBooleanProcessor* G4BooleanSolid::fExternalBoolProcessor = nullptr;
 49                                                    49 
 50 //////////////////////////////////////////////     50 //////////////////////////////////////////////////////////////////
 51 //                                                 51 //
 52 // Constructor                                     52 // Constructor
 53                                                    53 
 54 G4BooleanSolid::G4BooleanSolid( const G4String     54 G4BooleanSolid::G4BooleanSolid( const G4String& pName,
 55                                 G4VSolid* pSol     55                                 G4VSolid* pSolidA ,
 56                                 G4VSolid* pSol     56                                 G4VSolid* pSolidB )
 57   : G4VSolid(pName), fPtrSolidA(pSolidA), fPtr     57   : G4VSolid(pName), fPtrSolidA(pSolidA), fPtrSolidB(pSolidB)
 58 {                                                  58 {
 59 }                                                  59 }
 60                                                    60 
 61 //////////////////////////////////////////////     61 //////////////////////////////////////////////////////////////////
 62 //                                                 62 //
 63 // Constructor                                     63 // Constructor
 64                                                    64 
 65 G4BooleanSolid::G4BooleanSolid( const G4String     65 G4BooleanSolid::G4BooleanSolid( const G4String& pName,
 66                                       G4VSolid     66                                       G4VSolid* pSolidA ,
 67                                       G4VSolid     67                                       G4VSolid* pSolidB ,
 68                                       G4Rotati     68                                       G4RotationMatrix* rotMatrix,
 69                                 const G4ThreeV     69                                 const G4ThreeVector& transVector )
 70   : G4VSolid(pName), createdDisplacedSolid(tru     70   : G4VSolid(pName), createdDisplacedSolid(true)
 71 {                                                  71 {
 72   fPtrSolidA = pSolidA ;                           72   fPtrSolidA = pSolidA ;
 73   fPtrSolidB = new G4DisplacedSolid("placedB",     73   fPtrSolidB = new G4DisplacedSolid("placedB",pSolidB,rotMatrix,transVector) ;
 74 }                                                  74 }
 75                                                    75 
 76 //////////////////////////////////////////////     76 //////////////////////////////////////////////////////////////////
 77 //                                                 77 //
 78 // Constructor                                     78 // Constructor
 79                                                    79 
 80 G4BooleanSolid::G4BooleanSolid( const G4String     80 G4BooleanSolid::G4BooleanSolid( const G4String& pName,
 81                                       G4VSolid     81                                       G4VSolid* pSolidA ,
 82                                       G4VSolid     82                                       G4VSolid* pSolidB ,
 83                                 const G4Transf     83                                 const G4Transform3D& transform )
 84   : G4VSolid(pName), createdDisplacedSolid(tru     84   : G4VSolid(pName), createdDisplacedSolid(true)
 85 {                                                  85 {
 86   fPtrSolidA = pSolidA ;                           86   fPtrSolidA = pSolidA ;
 87   fPtrSolidB = new G4DisplacedSolid("placedB",     87   fPtrSolidB = new G4DisplacedSolid("placedB",pSolidB,transform) ;
 88 }                                                  88 }
 89                                                    89 
 90 //////////////////////////////////////////////     90 ///////////////////////////////////////////////////////////////
 91 //                                                 91 //
 92 // Fake default constructor - sets only member     92 // Fake default constructor - sets only member data and allocates memory
 93 //                            for usage restri     93 //                            for usage restricted to object persistency.
 94                                                    94 
 95 G4BooleanSolid::G4BooleanSolid( __void__& a )      95 G4BooleanSolid::G4BooleanSolid( __void__& a )
 96   : G4VSolid(a)                                    96   : G4VSolid(a)
 97 {                                                  97 {
 98 }                                                  98 }
 99                                                    99 
100 //////////////////////////////////////////////    100 ///////////////////////////////////////////////////////////////
101 //                                                101 //
102 // Destructor deletes transformation contents     102 // Destructor deletes transformation contents of the created displaced solid
103                                                   103 
104 G4BooleanSolid::~G4BooleanSolid()                 104 G4BooleanSolid::~G4BooleanSolid() 
105 {                                                 105 {
106   if(createdDisplacedSolid)                       106   if(createdDisplacedSolid)
107   {                                               107   {
108     ((G4DisplacedSolid*)fPtrSolidB)->CleanTran    108     ((G4DisplacedSolid*)fPtrSolidB)->CleanTransformations();
109   }                                               109   }
110   delete fpPolyhedron; fpPolyhedron = nullptr;    110   delete fpPolyhedron; fpPolyhedron = nullptr;
111 }                                                 111 }
112                                                   112 
113 //////////////////////////////////////////////    113 ///////////////////////////////////////////////////////////////
114 //                                                114 //
115 // Copy constructor                               115 // Copy constructor
116                                                   116 
117 G4BooleanSolid::G4BooleanSolid(const G4Boolean    117 G4BooleanSolid::G4BooleanSolid(const G4BooleanSolid& rhs)
118   : G4VSolid (rhs), fPtrSolidA(rhs.fPtrSolidA)    118   : G4VSolid (rhs), fPtrSolidA(rhs.fPtrSolidA), fPtrSolidB(rhs.fPtrSolidB),
119     fCubicVolume(rhs.fCubicVolume), fSurfaceAr    119     fCubicVolume(rhs.fCubicVolume), fSurfaceArea(rhs.fSurfaceArea),
120     fCubVolStatistics(rhs.fCubVolStatistics),     120     fCubVolStatistics(rhs.fCubVolStatistics),
121     fAreaStatistics(rhs.fAreaStatistics),         121     fAreaStatistics(rhs.fAreaStatistics),
122     fCubVolEpsilon(rhs.fCubVolEpsilon),           122     fCubVolEpsilon(rhs.fCubVolEpsilon),
123     fAreaAccuracy(rhs.fAreaAccuracy),             123     fAreaAccuracy(rhs.fAreaAccuracy),
124     createdDisplacedSolid(rhs.createdDisplaced    124     createdDisplacedSolid(rhs.createdDisplacedSolid)
125 {                                                 125 {
126   fPrimitives.resize(0); fPrimitivesSurfaceAre    126   fPrimitives.resize(0); fPrimitivesSurfaceArea = 0.;
127 }                                                 127 }
128                                                   128 
129 //////////////////////////////////////////////    129 ///////////////////////////////////////////////////////////////
130 //                                                130 //
131 // Assignment operator                            131 // Assignment operator
132                                                   132 
133 G4BooleanSolid& G4BooleanSolid::operator = (co    133 G4BooleanSolid& G4BooleanSolid::operator = (const G4BooleanSolid& rhs) 
134 {                                                 134 {
135   // Check assignment to self                     135   // Check assignment to self
136   //                                              136   //
137   if (this == &rhs)  { return *this; }            137   if (this == &rhs)  { return *this; }
138                                                   138 
139   // Copy base class data                         139   // Copy base class data
140   //                                              140   //
141   G4VSolid::operator=(rhs);                       141   G4VSolid::operator=(rhs);
142                                                   142 
143   // Copy data                                    143   // Copy data
144   //                                              144   //
145   fPtrSolidA= rhs.fPtrSolidA; fPtrSolidB= rhs.    145   fPtrSolidA= rhs.fPtrSolidA; fPtrSolidB= rhs.fPtrSolidB;
146   fCubicVolume= rhs.fCubicVolume; fSurfaceArea    146   fCubicVolume= rhs.fCubicVolume; fSurfaceArea= rhs.fSurfaceArea;
147   fCubVolStatistics = rhs.fCubVolStatistics; f    147   fCubVolStatistics = rhs.fCubVolStatistics; fCubVolEpsilon = rhs.fCubVolEpsilon;
148   fAreaStatistics = rhs.fAreaStatistics; fArea    148   fAreaStatistics = rhs.fAreaStatistics; fAreaAccuracy = rhs.fAreaAccuracy;
149   createdDisplacedSolid= rhs.createdDisplacedS    149   createdDisplacedSolid= rhs.createdDisplacedSolid;
150                                                   150 
151   fRebuildPolyhedron = false;                     151   fRebuildPolyhedron = false;
152   delete fpPolyhedron; fpPolyhedron = nullptr;    152   delete fpPolyhedron; fpPolyhedron = nullptr;
153   fPrimitives.resize(0); fPrimitivesSurfaceAre    153   fPrimitives.resize(0); fPrimitivesSurfaceArea = 0.;
154                                                   154 
155   return *this;                                   155   return *this;
156 }                                                 156 }  
157                                                   157 
158 //////////////////////////////////////////////    158 ///////////////////////////////////////////////////////////////
159 //                                                159 //
160 // If solid is made up from a Boolean operatio    160 // If solid is made up from a Boolean operation of two solids,
161 // return the corresponding solid (for no=0 an    161 // return the corresponding solid (for no=0 and 1)
162 // If the solid is not a "Boolean", return 0      162 // If the solid is not a "Boolean", return 0
163                                                   163 
164 const G4VSolid* G4BooleanSolid::GetConstituent    164 const G4VSolid* G4BooleanSolid::GetConstituentSolid(G4int no) const
165 {                                                 165 {
166   const G4VSolid* subSolid = nullptr;             166   const G4VSolid* subSolid = nullptr;
167   if( no == 0 )                                   167   if( no == 0 )  
168     subSolid = fPtrSolidA;                        168     subSolid = fPtrSolidA;
169   else if( no == 1 )                              169   else if( no == 1 ) 
170     subSolid = fPtrSolidB;                        170     subSolid = fPtrSolidB;
171   else                                            171   else
172   {                                               172   {
173     DumpInfo();                                   173     DumpInfo();
174     G4Exception("G4BooleanSolid::GetConstituen    174     G4Exception("G4BooleanSolid::GetConstituentSolid()",
175                 "GeomSolids0002", FatalExcepti    175                 "GeomSolids0002", FatalException, "Invalid solid index.");
176   }                                               176   }
177   return subSolid;                                177   return subSolid;
178 }                                                 178 }
179                                                   179 
180 //////////////////////////////////////////////    180 ///////////////////////////////////////////////////////////////
181 //                                                181 //
182 // If solid is made up from a Boolean operatio    182 // If solid is made up from a Boolean operation of two solids,
183 // return the corresponding solid (for no=0 an    183 // return the corresponding solid (for no=0 and 1)
184 // If the solid is not a "Boolean", return 0      184 // If the solid is not a "Boolean", return 0
185                                                   185 
186 G4VSolid* G4BooleanSolid::GetConstituentSolid(    186 G4VSolid* G4BooleanSolid::GetConstituentSolid(G4int no)
187 {                                                 187 {
188   G4VSolid* subSolid = nullptr;                   188   G4VSolid* subSolid = nullptr;
189   if( no == 0 )                                   189   if( no == 0 )  
190     subSolid = fPtrSolidA;                        190     subSolid = fPtrSolidA;
191   else if( no == 1 )                              191   else if( no == 1 ) 
192     subSolid = fPtrSolidB;                        192     subSolid = fPtrSolidB;
193   else                                            193   else
194   {                                               194   {
195     DumpInfo();                                   195     DumpInfo();
196     G4Exception("G4BooleanSolid::GetConstituen    196     G4Exception("G4BooleanSolid::GetConstituentSolid()",
197                 "GeomSolids0002", FatalExcepti    197                 "GeomSolids0002", FatalException, "Invalid solid index.");
198   }                                               198   }
199   return subSolid;                                199   return subSolid;
200 }                                                 200 }
201                                                   201 
202 //////////////////////////////////////////////    202 //////////////////////////////////////////////////////////////////////////
203 //                                                203 //
204 // Returns entity type                            204 // Returns entity type
205                                                   205 
206 G4GeometryType G4BooleanSolid::GetEntityType()    206 G4GeometryType G4BooleanSolid::GetEntityType() const 
207 {                                                 207 {
208   return {"G4BooleanSolid"};                      208   return {"G4BooleanSolid"};
209 }                                                 209 }
210                                                   210 
211 //////////////////////////////////////////////    211 //////////////////////////////////////////////////////////////////////////
212 //                                                212 //
213 // Set number of random points to be used for  << 
214                                                << 
215 void G4BooleanSolid::SetCubVolStatistics(G4int << 
216 {                                              << 
217   if (st != fCubVolStatistics) { fCubicVolume  << 
218   fCubVolStatistics = st;                      << 
219                                                << 
220   // Propagate st to all components of the 1st << 
221   if (fPtrSolidA->GetNumOfConstituents() > 1)  << 
222   {                                            << 
223     G4VSolid* ptr = fPtrSolidA;                << 
224     while(true)                                << 
225     {                                          << 
226       G4String type = ptr->GetEntityType();    << 
227       if (type == "G4DisplacedSolid")          << 
228       {                                        << 
229         ptr = ((G4DisplacedSolid*)ptr)->GetCon << 
230         continue;                              << 
231       }                                        << 
232       if (type == "G4ReflectedSolid")          << 
233       {                                        << 
234         ptr = ((G4ReflectedSolid*)ptr)->GetCon << 
235         continue;                              << 
236       }                                        << 
237       if (type == "G4ScaledSolid")             << 
238       {                                        << 
239         ptr = ((G4ScaledSolid*)ptr)->GetUnscal << 
240         continue;                              << 
241       }                                        << 
242       if (type != "G4MultiUnion") // G4MultiUn << 
243       {                                        << 
244   ((G4BooleanSolid*)ptr)->SetCubVolStatistics( << 
245       }                                        << 
246       break;                                   << 
247     }                                          << 
248   }                                            << 
249                                                << 
250   // Propagate st to all components of the 2nd << 
251   if (fPtrSolidB->GetNumOfConstituents() > 1)  << 
252   {                                            << 
253     G4VSolid* ptr = fPtrSolidB;                << 
254     while(true)                                << 
255     {                                          << 
256       G4String type = ptr->GetEntityType();    << 
257       if (type == "G4DisplacedSolid")          << 
258       {                                        << 
259         ptr = ((G4DisplacedSolid*)ptr)->GetCon << 
260         continue;                              << 
261       }                                        << 
262       if (type == "G4ReflectedSolid")          << 
263       {                                        << 
264         ptr = ((G4ReflectedSolid*)ptr)->GetCon << 
265         continue;                              << 
266       }                                        << 
267       if (type == "G4ScaledSolid")             << 
268       {                                        << 
269         ptr = ((G4ScaledSolid*)ptr)->GetUnscal << 
270         continue;                              << 
271       }                                        << 
272       if (type != "G4MultiUnion") // G4MultiUn << 
273       {                                        << 
274   ((G4BooleanSolid*)ptr)->SetCubVolStatistics( << 
275       }                                        << 
276       break;                                   << 
277     }                                          << 
278   }                                            << 
279 }                                              << 
280                                                << 
281 ////////////////////////////////////////////// << 
282 //                                             << 
283 // Set epsilon for computing cubic volume      << 
284                                                << 
285 void G4BooleanSolid::SetCubVolEpsilon(G4double << 
286 {                                              << 
287   if (ep != fCubVolEpsilon) { fCubicVolume = - << 
288   fCubVolEpsilon = ep;                         << 
289                                                << 
290   // Propagate ep to all components of the 1st << 
291   if (fPtrSolidA->GetNumOfConstituents() > 1)  << 
292   {                                            << 
293     G4VSolid* ptr = fPtrSolidA;                << 
294     while(true)                                << 
295     {                                          << 
296       G4String type = ptr->GetEntityType();    << 
297       if (type == "G4DisplacedSolid")          << 
298       {                                        << 
299         ptr = ((G4DisplacedSolid*)ptr)->GetCon << 
300         continue;                              << 
301       }                                        << 
302       if (type == "G4ReflectedSolid")          << 
303       {                                        << 
304         ptr = ((G4ReflectedSolid*)ptr)->GetCon << 
305         continue;                              << 
306       }                                        << 
307       if (type == "G4ScaledSolid")             << 
308       {                                        << 
309         ptr = ((G4ScaledSolid*)ptr)->GetUnscal << 
310         continue;                              << 
311       }                                        << 
312       if (type != "G4MultiUnion") // G4MultiUn << 
313       {                                        << 
314   ((G4BooleanSolid*)ptr)->SetCubVolEpsilon(ep) << 
315       }                                        << 
316       break;                                   << 
317     }                                          << 
318   }                                            << 
319                                                << 
320   // Propagate ep to all components of the 2nd << 
321   if (fPtrSolidB->GetNumOfConstituents() > 1)  << 
322   {                                            << 
323     G4VSolid* ptr = fPtrSolidB;                << 
324     while(true)                                << 
325     {                                          << 
326       G4String type = ptr->GetEntityType();    << 
327       if (type == "G4DisplacedSolid")          << 
328       {                                        << 
329         ptr = ((G4DisplacedSolid*)ptr)->GetCon << 
330         continue;                              << 
331       }                                        << 
332       if (type == "G4ReflectedSolid")          << 
333       {                                        << 
334         ptr = ((G4ReflectedSolid*)ptr)->GetCon << 
335         continue;                              << 
336       }                                        << 
337       if (type == "G4ScaledSolid")             << 
338       {                                        << 
339         ptr = ((G4ScaledSolid*)ptr)->GetUnscal << 
340         continue;                              << 
341       }                                        << 
342       if (type != "G4MultiUnion") // G4MultiUn << 
343       {                                        << 
344   ((G4BooleanSolid*)ptr)->SetCubVolEpsilon(ep) << 
345       }                                        << 
346       break;                                   << 
347     }                                          << 
348   }                                            << 
349 }                                              << 
350                                                << 
351 ////////////////////////////////////////////// << 
352 //                                             << 
353 // Stream object contents to an output stream     213 // Stream object contents to an output stream
354                                                   214 
355 std::ostream& G4BooleanSolid::StreamInfo(std::    215 std::ostream& G4BooleanSolid::StreamInfo(std::ostream& os) const
356 {                                                 216 {
357   os << "-------------------------------------    217   os << "-----------------------------------------------------------\n"
358      << "    *** Dump for Boolean solid - " <<    218      << "    *** Dump for Boolean solid - " << GetName() << " ***\n"
359      << "    =================================    219      << "    ===================================================\n"
360      << " Solid type: " << GetEntityType() <<     220      << " Solid type: " << GetEntityType() << "\n"
361      << " Parameters of constituent solids: \n    221      << " Parameters of constituent solids: \n"
362      << "=====================================    222      << "===========================================================\n";
363   fPtrSolidA->StreamInfo(os);                     223   fPtrSolidA->StreamInfo(os);
364   fPtrSolidB->StreamInfo(os);                     224   fPtrSolidB->StreamInfo(os);
365   os << "=====================================    225   os << "===========================================================\n";
366                                                   226 
367   return os;                                      227   return os;
368 }                                                 228 }
369                                                   229 
370 //////////////////////////////////////////////    230 //////////////////////////////////////////////////////////////////////////
371 //                                                231 //
372 // Creates list of constituent primitives of a    232 // Creates list of constituent primitives of and their placements
373                                                   233 
374 void G4BooleanSolid::GetListOfPrimitives(         234 void G4BooleanSolid::GetListOfPrimitives(
375        std::vector<std::pair<G4VSolid*,G4Trans    235        std::vector<std::pair<G4VSolid*,G4Transform3D>>& primitives,
376        const G4Transform3D& curPlacement) cons    236        const G4Transform3D& curPlacement) const
377 {                                                 237 {
378   G4Transform3D transform;                        238   G4Transform3D transform;
379   G4VSolid* solid;                                239   G4VSolid* solid;
380   G4String type;                                  240   G4String type;
381                                                   241 
382   // Repeat two times, first time for fPtrSoli    242   // Repeat two times, first time for fPtrSolidA and then for fPtrSolidB
383   //                                              243   //
384   for (auto i=0; i<2; ++i)                        244   for (auto i=0; i<2; ++i)
385   {                                               245   {
386     transform = curPlacement;                     246     transform = curPlacement;
387     solid     = (i == 0) ? fPtrSolidA : fPtrSo    247     solid     = (i == 0) ? fPtrSolidA : fPtrSolidB;
388     type      = solid->GetEntityType();           248     type      = solid->GetEntityType();
389                                                   249 
390     // While current solid is a trasformed sol    250     // While current solid is a trasformed solid just modify transform
391     //                                            251     //
392     while (type == "G4DisplacedSolid" ||          252     while (type == "G4DisplacedSolid" ||
393            type == "G4ReflectedSolid" ||          253            type == "G4ReflectedSolid" ||
394            type == "G4ScaledSolid")               254            type == "G4ScaledSolid")
395     {                                             255     {
396       if (type == "G4DisplacedSolid")             256       if (type == "G4DisplacedSolid")
397       {                                           257       {
398         transform = transform * G4Transform3D(    258         transform = transform * G4Transform3D(
399                     ((G4DisplacedSolid*)solid)    259                     ((G4DisplacedSolid*)solid)->GetObjectRotation(),
400                     ((G4DisplacedSolid*)solid)    260                     ((G4DisplacedSolid*)solid)->GetObjectTranslation());
401         solid     = ((G4DisplacedSolid*)solid)    261         solid     = ((G4DisplacedSolid*)solid)->GetConstituentMovedSolid();
402       }                                           262       }
403       else if (type == "G4ReflectedSolid")        263       else if (type == "G4ReflectedSolid")
404       {                                           264       {
405         transform= transform*((G4ReflectedSoli    265         transform= transform*((G4ReflectedSolid*)solid)->GetDirectTransform3D();
406         solid    = ((G4ReflectedSolid*)solid)-    266         solid    = ((G4ReflectedSolid*)solid)->GetConstituentMovedSolid();
407       }                                           267       }
408       else if (type == "G4ScaledSolid")           268       else if (type == "G4ScaledSolid")
409       {                                           269       {
410         transform = transform * ((G4ScaledSoli    270         transform = transform * ((G4ScaledSolid*)solid)->GetScaleTransform();
411         solid     = ((G4ScaledSolid*)solid)->G    271         solid     = ((G4ScaledSolid*)solid)->GetUnscaledSolid();
412       }                                           272       }
413       type  = solid->GetEntityType();             273       type  = solid->GetEntityType();
414     }                                             274     }
415                                                   275 
416     // If current solid is a Boolean solid the    276     // If current solid is a Boolean solid then continue recursion,
417     // otherwise add it to the list of primiti    277     // otherwise add it to the list of primitives
418     //                                            278     //
419     if (type == "G4UnionSolid"        ||          279     if (type == "G4UnionSolid"        ||
420         type == "G4SubtractionSolid"  ||          280         type == "G4SubtractionSolid"  ||
421         type == "G4IntersectionSolid" ||          281         type == "G4IntersectionSolid" ||
422         type == "G4BooleanSolid")                 282         type == "G4BooleanSolid")
423     {                                             283     {
424       ((G4BooleanSolid *)solid)->GetListOfPrim    284       ((G4BooleanSolid *)solid)->GetListOfPrimitives(primitives,transform);
425     }                                             285     }
426     else                                          286     else
427     {                                             287     {
428       primitives.emplace_back(solid,transform)    288       primitives.emplace_back(solid,transform);
429     }                                             289     }
430   }                                               290   }
431 }                                                 291 }
432                                                   292 
433 //////////////////////////////////////////////    293 //////////////////////////////////////////////////////////////////////////
434 //                                                294 //
435 // Returns a point (G4ThreeVector) randomly an    295 // Returns a point (G4ThreeVector) randomly and uniformly selected
436 // on the surface of the solid                    296 // on the surface of the solid
437                                                   297 
438 G4ThreeVector G4BooleanSolid::GetPointOnSurfac    298 G4ThreeVector G4BooleanSolid::GetPointOnSurface() const
439 {                                                 299 {
440   std::size_t nprims = fPrimitives.size();        300   std::size_t nprims = fPrimitives.size();
441   std::pair<G4VSolid *, G4Transform3D> prim;      301   std::pair<G4VSolid *, G4Transform3D> prim;
442                                                   302 
443   // Get list of primitives and find the total    303   // Get list of primitives and find the total area of their surfaces
444   //                                              304   //
445   if (nprims == 0)                                305   if (nprims == 0)
446   {                                               306   {
447     GetListOfPrimitives(fPrimitives, G4Transfo    307     GetListOfPrimitives(fPrimitives, G4Transform3D());
448     nprims = fPrimitives.size();                  308     nprims = fPrimitives.size();
449     fPrimitivesSurfaceArea = 0.;                  309     fPrimitivesSurfaceArea = 0.;
450     for (std::size_t i=0; i<nprims; ++i)          310     for (std::size_t i=0; i<nprims; ++i)
451     {                                             311     {
452       fPrimitivesSurfaceArea += fPrimitives[i]    312       fPrimitivesSurfaceArea += fPrimitives[i].first->GetSurfaceArea();
453     }                                             313     }
454   }                                               314   }
455                                                   315 
456   // Select random primitive, get random point    316   // Select random primitive, get random point on its surface and
457   // check that the point belongs to the surfa    317   // check that the point belongs to the surface of the solid
458   //                                              318   //
459   G4ThreeVector p;                                319   G4ThreeVector p;
460   for (std::size_t k=0; k<100000; ++k) // try     320   for (std::size_t k=0; k<100000; ++k) // try 100k times
461   {                                               321   {
462      G4double rand = fPrimitivesSurfaceArea *     322      G4double rand = fPrimitivesSurfaceArea * G4QuickRand();
463      G4double area = 0.;                          323      G4double area = 0.;
464      for (std::size_t i=0; i<nprims; ++i)         324      for (std::size_t i=0; i<nprims; ++i)
465      {                                            325      {
466        prim  = fPrimitives[i];                    326        prim  = fPrimitives[i];
467        area += prim.first->GetSurfaceArea();      327        area += prim.first->GetSurfaceArea();
468        if (rand < area) break;                    328        if (rand < area) break;
469      }                                            329      }
470      p = prim.first->GetPointOnSurface();         330      p = prim.first->GetPointOnSurface();
471      p = prim.second * G4Point3D(p);              331      p = prim.second * G4Point3D(p);
472      if (Inside(p) == kSurface) return p;         332      if (Inside(p) == kSurface) return p;
473   }                                               333   }
474   std::ostringstream message;                     334   std::ostringstream message;
475   message << "Solid - " << GetName() << "\n"      335   message << "Solid - " << GetName() << "\n"
476           << "All 100k attempts to generate a     336           << "All 100k attempts to generate a point on the surface have failed!\n"
477           << "The solid created may be an inva    337           << "The solid created may be an invalid Boolean construct!";
478   G4Exception("G4BooleanSolid::GetPointOnSurfa    338   G4Exception("G4BooleanSolid::GetPointOnSurface()",
479               "GeomSolids1001", JustWarning, m    339               "GeomSolids1001", JustWarning, message);
480   return p;                                       340   return p;
481 }                                              << 
482                                                << 
483 ////////////////////////////////////////////// << 
484 //                                             << 
485 // Return total number of constituents used fo << 
486                                                << 
487 G4int G4BooleanSolid::GetNumOfConstituents() c << 
488 {                                              << 
489   return (fPtrSolidA->GetNumOfConstituents() + << 
490 }                                              << 
491                                                << 
492 ////////////////////////////////////////////// << 
493 //                                             << 
494 // Return true if the resulting solid has only << 
495                                                << 
496 G4bool G4BooleanSolid::IsFaceted() const       << 
497 {                                              << 
498   return (fPtrSolidA->IsFaceted() && fPtrSolid << 
499 }                                                 341 }
500                                                   342 
501 //////////////////////////////////////////////    343 //////////////////////////////////////////////////////////////////////////
502 //                                                344 //
503 // Returns polyhedron for visualization           345 // Returns polyhedron for visualization
504                                                   346 
505 G4Polyhedron* G4BooleanSolid::GetPolyhedron ()    347 G4Polyhedron* G4BooleanSolid::GetPolyhedron () const
506 {                                                 348 {
507   if (fpPolyhedron == nullptr ||                  349   if (fpPolyhedron == nullptr ||
508       fRebuildPolyhedron ||                       350       fRebuildPolyhedron ||
509       fpPolyhedron->GetNumberOfRotationStepsAt    351       fpPolyhedron->GetNumberOfRotationStepsAtTimeOfCreation() !=
510       fpPolyhedron->GetNumberOfRotationSteps()    352       fpPolyhedron->GetNumberOfRotationSteps())
511     {                                             353     {
512       G4RecursiveAutoLock l(&polyhedronMutex);    354       G4RecursiveAutoLock l(&polyhedronMutex);
513       delete fpPolyhedron;                        355       delete fpPolyhedron;
514       fpPolyhedron = CreatePolyhedron();          356       fpPolyhedron = CreatePolyhedron();
515       fRebuildPolyhedron = false;                 357       fRebuildPolyhedron = false;
516       l.unlock();                                 358       l.unlock();
517     }                                             359     }
518   return fpPolyhedron;                            360   return fpPolyhedron;
519 }                                                 361 }
520                                                   362 
521 //////////////////////////////////////////////    363 //////////////////////////////////////////////////////////////////////////
522 //                                                364 //
523 // Stacks polyhedra for processing. Returns to    365 // Stacks polyhedra for processing. Returns top polyhedron.
524                                                   366 
525 G4Polyhedron*                                     367 G4Polyhedron*
526 G4BooleanSolid::StackPolyhedron(HepPolyhedronP    368 G4BooleanSolid::StackPolyhedron(HepPolyhedronProcessor& processor,
527                                 const G4VSolid    369                                 const G4VSolid* solid) const
528 {                                                 370 {
529   HepPolyhedronProcessor::Operation operation;    371   HepPolyhedronProcessor::Operation operation;
530   const G4String& type = solid->GetEntityType(    372   const G4String& type = solid->GetEntityType();
531   if (type == "G4UnionSolid")                     373   if (type == "G4UnionSolid")
532     { operation = HepPolyhedronProcessor::UNIO    374     { operation = HepPolyhedronProcessor::UNION; }
533   else if (type == "G4IntersectionSolid")         375   else if (type == "G4IntersectionSolid")
534     { operation = HepPolyhedronProcessor::INTE    376     { operation = HepPolyhedronProcessor::INTERSECTION; }
535   else if (type == "G4SubtractionSolid")          377   else if (type == "G4SubtractionSolid")
536     { operation = HepPolyhedronProcessor::SUBT    378     { operation = HepPolyhedronProcessor::SUBTRACTION; }
537   else                                            379   else
538   {                                               380   {
539     std::ostringstream message;                   381     std::ostringstream message;
540     message << "Solid - " << solid->GetName()     382     message << "Solid - " << solid->GetName()
541             << " - Unrecognised composite soli    383             << " - Unrecognised composite solid" << G4endl
542             << " Returning NULL !";               384             << " Returning NULL !";
543     G4Exception("StackPolyhedron()", "GeomSoli    385     G4Exception("StackPolyhedron()", "GeomSolids1001", JustWarning, message);
544     return nullptr;                               386     return nullptr;
545   }                                               387   }
546                                                   388 
547   G4Polyhedron* top = nullptr;                    389   G4Polyhedron* top = nullptr;
548   const G4VSolid* solidA = solid->GetConstitue    390   const G4VSolid* solidA = solid->GetConstituentSolid(0);
549   const G4VSolid* solidB = solid->GetConstitue    391   const G4VSolid* solidB = solid->GetConstituentSolid(1);
550                                                   392 
551   if (solidA->GetConstituentSolid(0) != nullpt    393   if (solidA->GetConstituentSolid(0) != nullptr)
552   {                                               394   {
553     top = StackPolyhedron(processor, solidA);     395     top = StackPolyhedron(processor, solidA);
554   }                                               396   }
555   else                                            397   else
556   {                                               398   {
557     top = solidA->GetPolyhedron();                399     top = solidA->GetPolyhedron();
558   }                                               400   }
559   G4Polyhedron* operand = solidB->GetPolyhedro    401   G4Polyhedron* operand = solidB->GetPolyhedron();
560   if (operand != nullptr)                         402   if (operand != nullptr)
561   {                                               403   {
562     processor.push_back (operation, *operand);    404     processor.push_back (operation, *operand);
563   }                                               405   }
564   else                                            406   else
565   {                                               407   {
566     std::ostringstream message;                   408     std::ostringstream message;
567     message << "Solid - " << solid->GetName()     409     message << "Solid - " << solid->GetName()
568             << " - No G4Polyhedron for Boolean    410             << " - No G4Polyhedron for Boolean component";
569     G4Exception("G4BooleanSolid::StackPolyhedr    411     G4Exception("G4BooleanSolid::StackPolyhedron()",
570                 "GeomSolids2001", JustWarning,    412                 "GeomSolids2001", JustWarning, message);
571   }                                               413   }
572                                                   414 
573   return top;                                     415   return top;
574 }                                                 416 }
575                                                   417 
576                                                   418 
577 //////////////////////////////////////////////    419 //////////////////////////////////////////////////////////////////////////
578 //                                                420 //
579 // Estimate Cubic Volume (capacity) and cache     421 // Estimate Cubic Volume (capacity) and cache it for reuse.
580                                                   422 
581 G4double G4BooleanSolid::GetCubicVolume()         423 G4double G4BooleanSolid::GetCubicVolume()
582 {                                                 424 {
583   if(fCubicVolume < 0.)                           425   if(fCubicVolume < 0.)
584   {                                               426   {
585     fCubicVolume = EstimateCubicVolume(fCubVol    427     fCubicVolume = EstimateCubicVolume(fCubVolStatistics, fCubVolEpsilon);
586   }                                               428   }
587   return fCubicVolume;                            429   return fCubicVolume;
588 }                                                 430 }
589                                                   431 
590 //////////////////////////////////////////////    432 //////////////////////////////////////////////////////////////////////////
591 //                                                433 //
592 // Set external Boolean processor.                434 // Set external Boolean processor.
593                                                   435 
594 void                                              436 void
595 G4BooleanSolid::SetExternalBooleanProcessor(G4    437 G4BooleanSolid::SetExternalBooleanProcessor(G4VBooleanProcessor* extProcessor)
596 {                                                 438 {
597   fExternalBoolProcessor = extProcessor;          439   fExternalBoolProcessor = extProcessor;
598 }                                                 440 }
599                                                   441 
600 //////////////////////////////////////////////    442 //////////////////////////////////////////////////////////////////////////
601 //                                                443 //
602 // Get external Boolean processor.                444 // Get external Boolean processor.
603                                                   445 
604 G4VBooleanProcessor* G4BooleanSolid::GetExtern    446 G4VBooleanProcessor* G4BooleanSolid::GetExternalBooleanProcessor()
605 {                                                 447 {
606   return fExternalBoolProcessor;                  448   return fExternalBoolProcessor;
607 }                                                 449 }
608                                                   450