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 10.4.p2)


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