Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/geometry/solids/specific/src/G4Polyhedra.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/specific/src/G4Polyhedra.cc (Version 11.3.0) and /geometry/solids/specific/src/G4Polyhedra.cc (Version 11.1.2)


  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 G4Polyhedra, a CSG polyhe     26 // Implementation of G4Polyhedra, a CSG polyhedra,
 27 // as an inherited class of G4VCSGfaceted.         27 // as an inherited class of G4VCSGfaceted.
 28 //                                                 28 //
 29 // Utility classes:                                29 // Utility classes:
 30 //    * G4EnclosingCylinder: decided a quick c     30 //    * G4EnclosingCylinder: decided a quick check of geometry would be a
 31 //      good idea (for CPU speed). If the quic     31 //      good idea (for CPU speed). If the quick check fails, the regular
 32 //      full-blown G4VCSGfaceted version is in     32 //      full-blown G4VCSGfaceted version is invoked.
 33 //    * G4ReduciblePolygon: Really meant as a      33 //    * G4ReduciblePolygon: Really meant as a check of input parameters,
 34 //      this utility class also "converts" the     34 //      this utility class also "converts" the GEANT3-like PGON/PCON
 35 //      arguments into the newer ones.             35 //      arguments into the newer ones.
 36 // Both these classes are implemented outside      36 // Both these classes are implemented outside this file because they are
 37 // shared with G4Polycone.                         37 // shared with G4Polycone.
 38 //                                                 38 //
 39 // Author: David C. Williams (davidw@scipp.ucs     39 // Author: David C. Williams (davidw@scipp.ucsc.edu)
 40 // -------------------------------------------     40 // --------------------------------------------------------------------
 41                                                    41 
 42 #include "G4Polyhedra.hh"                          42 #include "G4Polyhedra.hh"
 43                                                    43 
 44 #if !defined(G4GEOM_USE_UPOLYHEDRA)                44 #if !defined(G4GEOM_USE_UPOLYHEDRA)
 45                                                    45 
 46 #include "G4PolyhedraSide.hh"                      46 #include "G4PolyhedraSide.hh"
 47 #include "G4PolyPhiFace.hh"                        47 #include "G4PolyPhiFace.hh"
 48                                                    48 
 49 #include "G4GeomTools.hh"                          49 #include "G4GeomTools.hh"
 50 #include "G4VoxelLimits.hh"                        50 #include "G4VoxelLimits.hh"
 51 #include "G4AffineTransform.hh"                    51 #include "G4AffineTransform.hh"
 52 #include "G4BoundingEnvelope.hh"                   52 #include "G4BoundingEnvelope.hh"
 53                                                    53 
 54 #include "G4QuickRand.hh"                          54 #include "G4QuickRand.hh"
 55                                                    55 
 56 #include "G4EnclosingCylinder.hh"                  56 #include "G4EnclosingCylinder.hh"
 57 #include "G4ReduciblePolygon.hh"                   57 #include "G4ReduciblePolygon.hh"
 58 #include "G4VPVParameterisation.hh"                58 #include "G4VPVParameterisation.hh"
 59                                                    59 
 60 namespace                                          60 namespace
 61 {                                                  61 {
 62   G4Mutex surface_elementsMutex = G4MUTEX_INIT     62   G4Mutex surface_elementsMutex = G4MUTEX_INITIALIZER;
 63 }                                                  63 }
 64                                                    64 
 65 using namespace CLHEP;                             65 using namespace CLHEP;
 66                                                    66 
 67 // Constructor (GEANT3 style parameters)           67 // Constructor (GEANT3 style parameters)
 68 //                                                 68 //
 69 // GEANT3 PGON radii are specified in the dist     69 // GEANT3 PGON radii are specified in the distance to the norm of each face.
 70 //                                                 70 //
 71 G4Polyhedra::G4Polyhedra( const G4String& name     71 G4Polyhedra::G4Polyhedra( const G4String& name,
 72                                 G4double phiSt     72                                 G4double phiStart,
 73                                 G4double thePh     73                                 G4double thePhiTotal,
 74                                 G4int theNumSi     74                                 G4int theNumSide,
 75                                 G4int numZPlan     75                                 G4int numZPlanes,
 76                           const G4double zPlan     76                           const G4double zPlane[],
 77                           const G4double rInne     77                           const G4double rInner[],
 78                           const G4double rOute     78                           const G4double rOuter[]  )
 79   : G4VCSGfaceted( name )                          79   : G4VCSGfaceted( name )
 80 {                                                  80 {
 81   if (theNumSide <= 0)                             81   if (theNumSide <= 0)
 82   {                                                82   {
 83     std::ostringstream message;                    83     std::ostringstream message;
 84     message << "Solid must have at least one s     84     message << "Solid must have at least one side - " << GetName() << G4endl
 85             << "        No sides specified !";     85             << "        No sides specified !";
 86     G4Exception("G4Polyhedra::G4Polyhedra()",      86     G4Exception("G4Polyhedra::G4Polyhedra()", "GeomSolids0002",
 87                 FatalErrorInArgument, message)     87                 FatalErrorInArgument, message);
 88   }                                                88   }
 89                                                    89 
 90   //                                               90   //
 91   // Calculate conversion factor from G3 radiu     91   // Calculate conversion factor from G3 radius to G4 radius
 92   //                                               92   //
 93   G4double phiTotal = thePhiTotal;                 93   G4double phiTotal = thePhiTotal;
 94   if ( (phiTotal <=0) || (phiTotal >= twopi*(1     94   if ( (phiTotal <=0) || (phiTotal >= twopi*(1-DBL_EPSILON)) )
 95     { phiTotal = twopi; }                          95     { phiTotal = twopi; }
 96   G4double convertRad = std::cos(0.5*phiTotal/     96   G4double convertRad = std::cos(0.5*phiTotal/theNumSide);
 97                                                    97 
 98   //                                               98   //
 99   // Some historical stuff                         99   // Some historical stuff
100   //                                              100   //
101   original_parameters = new G4PolyhedraHistori    101   original_parameters = new G4PolyhedraHistorical;
102                                                   102 
103   original_parameters->numSide = theNumSide;      103   original_parameters->numSide = theNumSide;
104   original_parameters->Start_angle = phiStart;    104   original_parameters->Start_angle = phiStart;
105   original_parameters->Opening_angle = phiTota    105   original_parameters->Opening_angle = phiTotal;
106   original_parameters->Num_z_planes = numZPlan    106   original_parameters->Num_z_planes = numZPlanes;
107   original_parameters->Z_values = new G4double    107   original_parameters->Z_values = new G4double[numZPlanes];
108   original_parameters->Rmin = new G4double[num    108   original_parameters->Rmin = new G4double[numZPlanes];
109   original_parameters->Rmax = new G4double[num    109   original_parameters->Rmax = new G4double[numZPlanes];
110                                                   110 
111   for (G4int i=0; i<numZPlanes; ++i)              111   for (G4int i=0; i<numZPlanes; ++i)
112   {                                               112   {
113     if (( i < numZPlanes-1) && ( zPlane[i] ==     113     if (( i < numZPlanes-1) && ( zPlane[i] == zPlane[i+1] ))
114     {                                             114     {
115       if( (rInner[i]   > rOuter[i+1])             115       if( (rInner[i]   > rOuter[i+1])
116         ||(rInner[i+1] > rOuter[i])   )           116         ||(rInner[i+1] > rOuter[i])   )
117       {                                           117       {
118         DumpInfo();                               118         DumpInfo();
119         std::ostringstream message;               119         std::ostringstream message;
120         message << "Cannot create a Polyhedra     120         message << "Cannot create a Polyhedra with no contiguous segments."
121                 << G4endl                         121                 << G4endl
122                 << "        Segments are not c    122                 << "        Segments are not contiguous !" << G4endl
123                 << "        rMin[" << i << "]     123                 << "        rMin[" << i << "] = " << rInner[i]
124                 << " -- rMax[" << i+1 << "] =     124                 << " -- rMax[" << i+1 << "] = " << rOuter[i+1] << G4endl
125                 << "        rMin[" << i+1 << "    125                 << "        rMin[" << i+1 << "] = " << rInner[i+1]
126                 << " -- rMax[" << i << "] = "     126                 << " -- rMax[" << i << "] = " << rOuter[i];
127         G4Exception("G4Polyhedra::G4Polyhedra(    127         G4Exception("G4Polyhedra::G4Polyhedra()", "GeomSolids0002",
128                     FatalErrorInArgument, mess    128                     FatalErrorInArgument, message);
129       }                                           129       }
130     }                                             130     }
131     original_parameters->Z_values[i] = zPlane[    131     original_parameters->Z_values[i] = zPlane[i];
132     original_parameters->Rmin[i] = rInner[i]/c    132     original_parameters->Rmin[i] = rInner[i]/convertRad;
133     original_parameters->Rmax[i] = rOuter[i]/c    133     original_parameters->Rmax[i] = rOuter[i]/convertRad;
134   }                                               134   }
135                                                   135 
136                                                   136 
137   //                                              137   //
138   // Build RZ polygon using special PCON/PGON     138   // Build RZ polygon using special PCON/PGON GEANT3 constructor
139   //                                              139   //
140   auto rz = new G4ReduciblePolygon( rInner, rO << 140   G4ReduciblePolygon* rz =
                                                   >> 141     new G4ReduciblePolygon( rInner, rOuter, zPlane, numZPlanes );
141   rz->ScaleA( 1/convertRad );                     142   rz->ScaleA( 1/convertRad );
142                                                   143 
143   //                                              144   //
144   // Do the real work                             145   // Do the real work
145   //                                              146   //
146   Create( phiStart, phiTotal, theNumSide, rz )    147   Create( phiStart, phiTotal, theNumSide, rz );
147                                                   148 
148   delete rz;                                      149   delete rz;
149 }                                                 150 }
150                                                   151 
151 // Constructor (generic parameters)               152 // Constructor (generic parameters)
152 //                                                153 //
153 G4Polyhedra::G4Polyhedra( const G4String& name    154 G4Polyhedra::G4Polyhedra( const G4String& name,
154                                 G4double phiSt    155                                 G4double phiStart,
155                                 G4double phiTo    156                                 G4double phiTotal,
156                                 G4int    theNu    157                                 G4int    theNumSide,
157                                 G4int    numRZ    158                                 G4int    numRZ,
158                           const G4double r[],     159                           const G4double r[],
159                           const G4double z[]      160                           const G4double z[]   )
160   : G4VCSGfaceted( name ), genericPgon(true)      161   : G4VCSGfaceted( name ), genericPgon(true)
161 {                                                 162 {
162   if (theNumSide <= 0)                            163   if (theNumSide <= 0)
163   {                                               164   {
164     std::ostringstream message;                   165     std::ostringstream message;
165     message << "Solid must have at least one s    166     message << "Solid must have at least one side - " << GetName() << G4endl
166             << "        No sides specified !";    167             << "        No sides specified !";
167     G4Exception("G4Polyhedra::G4Polyhedra()",     168     G4Exception("G4Polyhedra::G4Polyhedra()", "GeomSolids0002",
168                 FatalErrorInArgument, message)    169                 FatalErrorInArgument, message);
169   }                                               170   }
170                                                   171 
171   auto rz = new G4ReduciblePolygon( r, z, numR << 172   G4ReduciblePolygon* rz = new G4ReduciblePolygon( r, z, numRZ );
172                                                   173 
173   Create( phiStart, phiTotal, theNumSide, rz )    174   Create( phiStart, phiTotal, theNumSide, rz );
174                                                   175 
175   // Set original_parameters struct for consis    176   // Set original_parameters struct for consistency
176   //                                              177   //
177   SetOriginalParameters(rz);                      178   SetOriginalParameters(rz);
178                                                   179 
179   delete rz;                                      180   delete rz;
180 }                                                 181 }
181                                                   182 
182 // Create                                         183 // Create
183 //                                                184 //
184 // Generic create routine, called by each cons    185 // Generic create routine, called by each constructor
185 // after conversion of arguments                  186 // after conversion of arguments
186 //                                                187 //
187 void G4Polyhedra::Create( G4double phiStart,      188 void G4Polyhedra::Create( G4double phiStart,
188                           G4double phiTotal,      189                           G4double phiTotal,
189                           G4int    theNumSide,    190                           G4int    theNumSide,
190                           G4ReduciblePolygon*     191                           G4ReduciblePolygon* rz  )
191 {                                                 192 {
192   //                                              193   //
193   // Perform checks of rz values                  194   // Perform checks of rz values
194   //                                              195   //
195   if (rz->Amin() < 0.0)                           196   if (rz->Amin() < 0.0)
196   {                                               197   {
197     std::ostringstream message;                   198     std::ostringstream message;
198     message << "Illegal input parameters - " <    199     message << "Illegal input parameters - " << GetName() << G4endl
199             << "        All R values must be >    200             << "        All R values must be >= 0 !";
200     G4Exception("G4Polyhedra::Create()", "Geom    201     G4Exception("G4Polyhedra::Create()", "GeomSolids0002",
201                 FatalErrorInArgument, message)    202                 FatalErrorInArgument, message);
202   }                                               203   }
203                                                   204 
204   G4double rzArea = rz->Area();                   205   G4double rzArea = rz->Area();
205   if (rzArea < -kCarTolerance)                    206   if (rzArea < -kCarTolerance)
206   {                                               207   {
207     rz->ReverseOrder();                           208     rz->ReverseOrder();
208   }                                               209   }
209   else if (rzArea < kCarTolerance)                210   else if (rzArea < kCarTolerance)
210   {                                               211   {
211     std::ostringstream message;                   212     std::ostringstream message;
212     message << "Illegal input parameters - " <    213     message << "Illegal input parameters - " << GetName() << G4endl
213             << "        R/Z cross section is z    214             << "        R/Z cross section is zero or near zero: " << rzArea;
214     G4Exception("G4Polyhedra::Create()", "Geom    215     G4Exception("G4Polyhedra::Create()", "GeomSolids0002",
215                 FatalErrorInArgument, message)    216                 FatalErrorInArgument, message);
216   }                                               217   }
217                                                   218 
218   if ( (!rz->RemoveDuplicateVertices( kCarTole    219   if ( (!rz->RemoveDuplicateVertices( kCarTolerance ))
219     || (!rz->RemoveRedundantVertices( kCarTole    220     || (!rz->RemoveRedundantVertices( kCarTolerance )) )
220   {                                               221   {
221     std::ostringstream message;                   222     std::ostringstream message;
222     message << "Illegal input parameters - " <    223     message << "Illegal input parameters - " << GetName() << G4endl
223             << "        Too few unique R/Z val    224             << "        Too few unique R/Z values !";
224     G4Exception("G4Polyhedra::Create()", "Geom    225     G4Exception("G4Polyhedra::Create()", "GeomSolids0002",
225                 FatalErrorInArgument, message)    226                 FatalErrorInArgument, message);
226   }                                               227   }
227                                                   228 
228   if (rz->CrossesItself( 1/kInfinity ))           229   if (rz->CrossesItself( 1/kInfinity ))
229   {                                               230   {
230     std::ostringstream message;                   231     std::ostringstream message;
231     message << "Illegal input parameters - " <    232     message << "Illegal input parameters - " << GetName() << G4endl
232             << "        R/Z segments cross !";    233             << "        R/Z segments cross !";
233     G4Exception("G4Polyhedra::Create()", "Geom    234     G4Exception("G4Polyhedra::Create()", "GeomSolids0002",
234                 FatalErrorInArgument, message)    235                 FatalErrorInArgument, message);
235   }                                               236   }
236                                                   237 
237   numCorner = rz->NumVertices();                  238   numCorner = rz->NumVertices();
238                                                   239 
239                                                   240 
240   startPhi = phiStart;                            241   startPhi = phiStart;
241   while( startPhi < 0 )    // Loop checking, 1    242   while( startPhi < 0 )    // Loop checking, 13.08.2015, G.Cosmo
242     startPhi += twopi;                            243     startPhi += twopi;
243   //                                              244   //
244   // Phi opening? Account for some possible ro    245   // Phi opening? Account for some possible roundoff, and interpret
245   // nonsense value as representing no phi ope    246   // nonsense value as representing no phi opening
246   //                                              247   //
247   if ( (phiTotal <= 0) || (phiTotal > twopi*(1    248   if ( (phiTotal <= 0) || (phiTotal > twopi*(1-DBL_EPSILON)) )
248   {                                               249   {
249     phiIsOpen = false;                            250     phiIsOpen = false;
250     endPhi = startPhi + twopi;                    251     endPhi = startPhi + twopi;
251   }                                               252   }
252   else                                            253   else
253   {                                               254   {
254     phiIsOpen = true;                             255     phiIsOpen = true;
255     endPhi = startPhi + phiTotal;                 256     endPhi = startPhi + phiTotal;
256   }                                               257   }
257                                                   258 
258   //                                              259   //
259   // Save number sides                            260   // Save number sides
260   //                                              261   //
261   numSide = theNumSide;                           262   numSide = theNumSide;
262                                                   263 
263   //                                              264   //
264   // Allocate corner array.                       265   // Allocate corner array.
265   //                                              266   //
266   corners = new G4PolyhedraSideRZ[numCorner];     267   corners = new G4PolyhedraSideRZ[numCorner];
267                                                   268 
268   //                                              269   //
269   // Copy corners                                 270   // Copy corners
270   //                                              271   //
271   G4ReduciblePolygonIterator iterRZ(rz);          272   G4ReduciblePolygonIterator iterRZ(rz);
272                                                   273 
273   G4PolyhedraSideRZ *next = corners;              274   G4PolyhedraSideRZ *next = corners;
274   iterRZ.Begin();                                 275   iterRZ.Begin();
275   do    // Loop checking, 13.08.2015, G.Cosmo     276   do    // Loop checking, 13.08.2015, G.Cosmo
276   {                                               277   {
277     next->r = iterRZ.GetA();                      278     next->r = iterRZ.GetA();
278     next->z = iterRZ.GetB();                      279     next->z = iterRZ.GetB();
279   } while( ++next, iterRZ.Next() );               280   } while( ++next, iterRZ.Next() );
280                                                   281 
281   //                                              282   //
282   // Allocate face pointer array                  283   // Allocate face pointer array
283   //                                              284   //
284   numFace = phiIsOpen ? numCorner+2 : numCorne    285   numFace = phiIsOpen ? numCorner+2 : numCorner;
285   faces = new G4VCSGface*[numFace];               286   faces = new G4VCSGface*[numFace];
286                                                   287 
287   //                                              288   //
288   // Construct side faces                         289   // Construct side faces
289   //                                              290   //
290   // To do so properly, we need to keep track     291   // To do so properly, we need to keep track of four successive RZ
291   // corners.                                     292   // corners.
292   //                                              293   //
293   // But! Don't construct a face if both point    294   // But! Don't construct a face if both points are at zero radius!
294   //                                              295   //
295   G4PolyhedraSideRZ* corner = corners,            296   G4PolyhedraSideRZ* corner = corners,
296                    * prev = corners + numCorne    297                    * prev = corners + numCorner-1,
297                    * nextNext;                    298                    * nextNext;
298   G4VCSGface** face = faces;                      299   G4VCSGface** face = faces;
299   do    // Loop checking, 13.08.2015, G.Cosmo     300   do    // Loop checking, 13.08.2015, G.Cosmo
300   {                                               301   {
301     next = corner+1;                              302     next = corner+1;
302     if (next >= corners+numCorner) next = corn    303     if (next >= corners+numCorner) next = corners;
303     nextNext = next+1;                            304     nextNext = next+1;
304     if (nextNext >= corners+numCorner) nextNex    305     if (nextNext >= corners+numCorner) nextNext = corners;
305                                                   306 
306     if (corner->r < 1/kInfinity && next->r < 1    307     if (corner->r < 1/kInfinity && next->r < 1/kInfinity) continue;
307 /*                                                308 /*
308     // We must decide here if we can dare decl    309     // We must decide here if we can dare declare one of our faces
309     // as having a "valid" normal (i.e. allBeh    310     // as having a "valid" normal (i.e. allBehind = true). This
310     // is never possible if the face faces "in    311     // is never possible if the face faces "inward" in r *unless*
311     // we have only one side                      312     // we have only one side
312     //                                            313     //
313     G4bool allBehind;                             314     G4bool allBehind;
314     if ((corner->z > next->z) && (numSide > 1)    315     if ((corner->z > next->z) && (numSide > 1))
315     {                                             316     {
316       allBehind = false;                          317       allBehind = false;
317     }                                             318     }
318     else                                          319     else
319     {                                             320     {
320       //                                          321       //
321       // Otherwise, it is only true if the lin    322       // Otherwise, it is only true if the line passing
322       // through the two points of the segment    323       // through the two points of the segment do not
323       // split the r/z cross section              324       // split the r/z cross section
324       //                                          325       //
325       allBehind = !rz->BisectedBy( corner->r,     326       allBehind = !rz->BisectedBy( corner->r, corner->z,
326                                    next->r, ne    327                                    next->r, next->z, kCarTolerance );
327     }                                             328     }
328 */                                                329 */
329     *face++ = new G4PolyhedraSide( prev, corne    330     *face++ = new G4PolyhedraSide( prev, corner, next, nextNext,
330                  numSide, startPhi, endPhi-sta    331                  numSide, startPhi, endPhi-startPhi, phiIsOpen );
331   } while( prev=corner, corner=next, corner >     332   } while( prev=corner, corner=next, corner > corners );
332                                                   333 
333   if (phiIsOpen)                                  334   if (phiIsOpen)
334   {                                               335   {
335     //                                            336     //
336     // Construct phi open edges                   337     // Construct phi open edges
337     //                                            338     //
338     *face++ = new G4PolyPhiFace( rz, startPhi,    339     *face++ = new G4PolyPhiFace( rz, startPhi, phiTotal/numSide, endPhi );
339     *face++ = new G4PolyPhiFace( rz, endPhi,      340     *face++ = new G4PolyPhiFace( rz, endPhi,   phiTotal/numSide, startPhi );
340   }                                               341   }
341                                                   342 
342   //                                              343   //
343   // We might have dropped a face or two: reca    344   // We might have dropped a face or two: recalculate numFace
344   //                                              345   //
345   numFace = (G4int)(face-faces);                  346   numFace = (G4int)(face-faces);
346                                                   347 
347   //                                              348   //
348   // Make enclosingCylinder                       349   // Make enclosingCylinder
349   //                                              350   //
350   enclosingCylinder =                             351   enclosingCylinder =
351     new G4EnclosingCylinder( rz, phiIsOpen, ph    352     new G4EnclosingCylinder( rz, phiIsOpen, phiStart, phiTotal );
352 }                                                 353 }
353                                                   354 
354 // Fake default constructor - sets only member    355 // Fake default constructor - sets only member data and allocates memory
355 //                            for usage restri    356 //                            for usage restricted to object persistency.
356 //                                                357 //
357 G4Polyhedra::G4Polyhedra( __void__& a )           358 G4Polyhedra::G4Polyhedra( __void__& a )
358   : G4VCSGfaceted(a), startPhi(0.), endPhi(0.)    359   : G4VCSGfaceted(a), startPhi(0.), endPhi(0.)
359 {                                                 360 {
360 }                                                 361 }
361                                                   362 
362 // Destructor                                     363 // Destructor
363 //                                                364 //
364 G4Polyhedra::~G4Polyhedra()                       365 G4Polyhedra::~G4Polyhedra()
365 {                                                 366 {
366   delete [] corners;                              367   delete [] corners;
367   delete original_parameters;                     368   delete original_parameters;
368   delete enclosingCylinder;                       369   delete enclosingCylinder;
369   delete fElements;                               370   delete fElements;
370   delete fpPolyhedron;                            371   delete fpPolyhedron;
371   corners = nullptr;                              372   corners = nullptr;
372   original_parameters = nullptr;                  373   original_parameters = nullptr;
373   enclosingCylinder = nullptr;                    374   enclosingCylinder = nullptr;
374   fElements = nullptr;                            375   fElements = nullptr;
375   fpPolyhedron = nullptr;                         376   fpPolyhedron = nullptr;
376 }                                                 377 }
377                                                   378 
378 // Copy constructor                               379 // Copy constructor
379 //                                                380 //
380 G4Polyhedra::G4Polyhedra( const G4Polyhedra& s    381 G4Polyhedra::G4Polyhedra( const G4Polyhedra& source )
381   : G4VCSGfaceted( source )                       382   : G4VCSGfaceted( source )
382 {                                                 383 {
383   CopyStuff( source );                            384   CopyStuff( source );
384 }                                                 385 }
385                                                   386 
386 // Assignment operator                            387 // Assignment operator
387 //                                                388 //
388 G4Polyhedra &G4Polyhedra::operator=( const G4P    389 G4Polyhedra &G4Polyhedra::operator=( const G4Polyhedra& source )
389 {                                                 390 {
390   if (this == &source) return *this;              391   if (this == &source) return *this;
391                                                   392 
392   G4VCSGfaceted::operator=( source );             393   G4VCSGfaceted::operator=( source );
393                                                   394 
394   delete [] corners;                              395   delete [] corners;
395   delete original_parameters;                     396   delete original_parameters;
396   delete enclosingCylinder;                       397   delete enclosingCylinder;
397                                                   398 
398   CopyStuff( source );                            399   CopyStuff( source );
399                                                   400 
400   return *this;                                   401   return *this;
401 }                                                 402 }
402                                                   403 
403 // CopyStuff                                      404 // CopyStuff
404 //                                                405 //
405 void G4Polyhedra::CopyStuff( const G4Polyhedra    406 void G4Polyhedra::CopyStuff( const G4Polyhedra& source )
406 {                                                 407 {
407   //                                              408   //
408   // Simple stuff                                 409   // Simple stuff
409   //                                              410   //
410   numSide    = source.numSide;                    411   numSide    = source.numSide;
411   startPhi   = source.startPhi;                   412   startPhi   = source.startPhi;
412   endPhi     = source.endPhi;                     413   endPhi     = source.endPhi;
413   phiIsOpen  = source.phiIsOpen;                  414   phiIsOpen  = source.phiIsOpen;
414   numCorner  = source.numCorner;                  415   numCorner  = source.numCorner;
415   genericPgon= source.genericPgon;                416   genericPgon= source.genericPgon;
416                                                   417 
417   //                                              418   //
418   // The corner array                             419   // The corner array
419   //                                              420   //
420   corners = new G4PolyhedraSideRZ[numCorner];     421   corners = new G4PolyhedraSideRZ[numCorner];
421                                                   422 
422   G4PolyhedraSideRZ* corn = corners,              423   G4PolyhedraSideRZ* corn = corners,
423                    * sourceCorn = source.corne    424                    * sourceCorn = source.corners;
424   do    // Loop checking, 13.08.2015, G.Cosmo     425   do    // Loop checking, 13.08.2015, G.Cosmo
425   {                                               426   {
426     *corn = *sourceCorn;                          427     *corn = *sourceCorn;
427   } while( ++sourceCorn, ++corn < corners+numC    428   } while( ++sourceCorn, ++corn < corners+numCorner );
428                                                   429 
429   //                                              430   //
430   // Original parameters                          431   // Original parameters
431   //                                              432   //
432   if (source.original_parameters != nullptr)   << 433   if (source.original_parameters)
433   {                                               434   {
434     original_parameters =                         435     original_parameters =
435       new G4PolyhedraHistorical( *source.origi    436       new G4PolyhedraHistorical( *source.original_parameters );
436   }                                               437   }
437                                                   438 
438   //                                              439   //
439   // Enclosing cylinder                           440   // Enclosing cylinder
440   //                                              441   //
441   enclosingCylinder = new G4EnclosingCylinder(    442   enclosingCylinder = new G4EnclosingCylinder( *source.enclosingCylinder );
442                                                   443 
443   //                                              444   //
444   // Surface elements                             445   // Surface elements
445   //                                              446   //
446   delete fElements;                               447   delete fElements;
447   fElements = nullptr;                            448   fElements = nullptr;
448                                                   449 
449   //                                              450   //
450   // Polyhedron                                   451   // Polyhedron
451   //                                              452   //
452   fRebuildPolyhedron = false;                     453   fRebuildPolyhedron = false;
453   delete fpPolyhedron;                            454   delete fpPolyhedron;
454   fpPolyhedron = nullptr;                         455   fpPolyhedron = nullptr;
455 }                                                 456 }
456                                                   457 
457 // Reset                                          458 // Reset
458 //                                                459 //
459 // Recalculates and reshapes the solid, given     460 // Recalculates and reshapes the solid, given pre-assigned scaled
460 // original_parameters.                           461 // original_parameters.
461 //                                                462 //
462 G4bool G4Polyhedra::Reset()                       463 G4bool G4Polyhedra::Reset()
463 {                                                 464 {
464   if (genericPgon)                                465   if (genericPgon)
465   {                                               466   {
466     std::ostringstream message;                   467     std::ostringstream message;
467     message << "Solid " << GetName() << " buil    468     message << "Solid " << GetName() << " built using generic construct."
468             << G4endl << "Not applicable to th    469             << G4endl << "Not applicable to the generic construct !";
469     G4Exception("G4Polyhedra::Reset()", "GeomS    470     G4Exception("G4Polyhedra::Reset()", "GeomSolids1001",
470                 JustWarning, message, "Paramet    471                 JustWarning, message, "Parameters NOT resetted.");
471     return true;                                  472     return true;
472   }                                               473   }
473                                                   474 
474   //                                              475   //
475   // Clear old setup                              476   // Clear old setup
476   //                                              477   //
477   G4VCSGfaceted::DeleteStuff();                   478   G4VCSGfaceted::DeleteStuff();
478   delete [] corners;                              479   delete [] corners;
479   delete enclosingCylinder;                       480   delete enclosingCylinder;
480   delete fElements;                               481   delete fElements;
481   corners = nullptr;                              482   corners = nullptr;
482   fElements = nullptr;                            483   fElements = nullptr;
483   enclosingCylinder = nullptr;                    484   enclosingCylinder = nullptr;
484                                                   485 
485   //                                              486   //
486   // Rebuild polyhedra                            487   // Rebuild polyhedra
487   //                                              488   //
488   auto rz = new G4ReduciblePolygon( original_p << 489   G4ReduciblePolygon* rz =
489                                     original_p << 490     new G4ReduciblePolygon( original_parameters->Rmin,
490                                     original_p << 491                             original_parameters->Rmax,
491                                     original_p << 492                             original_parameters->Z_values,
                                                   >> 493                             original_parameters->Num_z_planes );
492   Create( original_parameters->Start_angle,       494   Create( original_parameters->Start_angle,
493           original_parameters->Opening_angle,     495           original_parameters->Opening_angle,
494           original_parameters->numSide, rz );     496           original_parameters->numSide, rz );
495   delete rz;                                      497   delete rz;
496                                                   498 
497   return false;                                   499   return false;
498 }                                                 500 }
499                                                   501 
500 // Inside                                         502 // Inside
501 //                                                503 //
502 // This is an override of G4VCSGfaceted::Insid    504 // This is an override of G4VCSGfaceted::Inside, created in order
503 // to speed things up by first checking with G    505 // to speed things up by first checking with G4EnclosingCylinder.
504 //                                                506 //
505 EInside G4Polyhedra::Inside( const G4ThreeVect    507 EInside G4Polyhedra::Inside( const G4ThreeVector& p ) const
506 {                                                 508 {
507   //                                              509   //
508   // Quick test                                   510   // Quick test
509   //                                              511   //
510   if (enclosingCylinder->MustBeOutside(p)) ret    512   if (enclosingCylinder->MustBeOutside(p)) return kOutside;
511                                                   513 
512   //                                              514   //
513   // Long answer                                  515   // Long answer
514   //                                              516   //
515   return G4VCSGfaceted::Inside(p);                517   return G4VCSGfaceted::Inside(p);
516 }                                                 518 }
517                                                   519 
518 // DistanceToIn                                   520 // DistanceToIn
519 //                                                521 //
520 // This is an override of G4VCSGfaceted::Insid    522 // This is an override of G4VCSGfaceted::Inside, created in order
521 // to speed things up by first checking with G    523 // to speed things up by first checking with G4EnclosingCylinder.
522 //                                                524 //
523 G4double G4Polyhedra::DistanceToIn( const G4Th    525 G4double G4Polyhedra::DistanceToIn( const G4ThreeVector& p,
524                                     const G4Th    526                                     const G4ThreeVector& v ) const
525 {                                                 527 {
526   //                                              528   //
527   // Quick test                                   529   // Quick test
528   //                                              530   //
529   if (enclosingCylinder->ShouldMiss(p,v))         531   if (enclosingCylinder->ShouldMiss(p,v))
530     return kInfinity;                             532     return kInfinity;
531                                                   533 
532   //                                              534   //
533   // Long answer                                  535   // Long answer
534   //                                              536   //
535   return G4VCSGfaceted::DistanceToIn( p, v );     537   return G4VCSGfaceted::DistanceToIn( p, v );
536 }                                                 538 }
537                                                   539 
538 // DistanceToIn                                   540 // DistanceToIn
539 //                                                541 //
540 G4double G4Polyhedra::DistanceToIn( const G4Th    542 G4double G4Polyhedra::DistanceToIn( const G4ThreeVector& p ) const
541 {                                                 543 {
542   return G4VCSGfaceted::DistanceToIn(p);          544   return G4VCSGfaceted::DistanceToIn(p);
543 }                                                 545 }
544                                                   546 
545 // Get bounding box                               547 // Get bounding box
546 //                                                548 //
547 void G4Polyhedra::BoundingLimits(G4ThreeVector    549 void G4Polyhedra::BoundingLimits(G4ThreeVector& pMin,
548                                  G4ThreeVector    550                                  G4ThreeVector& pMax) const
549 {                                                 551 {
550   G4double rmin = kInfinity, rmax = -kInfinity    552   G4double rmin = kInfinity, rmax = -kInfinity;
551   G4double zmin = kInfinity, zmax = -kInfinity    553   G4double zmin = kInfinity, zmax = -kInfinity;
552   for (G4int i=0; i<GetNumRZCorner(); ++i)        554   for (G4int i=0; i<GetNumRZCorner(); ++i)
553   {                                               555   {
554     G4PolyhedraSideRZ corner = GetCorner(i);      556     G4PolyhedraSideRZ corner = GetCorner(i);
555     if (corner.r < rmin) rmin = corner.r;         557     if (corner.r < rmin) rmin = corner.r;
556     if (corner.r > rmax) rmax = corner.r;         558     if (corner.r > rmax) rmax = corner.r;
557     if (corner.z < zmin) zmin = corner.z;         559     if (corner.z < zmin) zmin = corner.z;
558     if (corner.z > zmax) zmax = corner.z;         560     if (corner.z > zmax) zmax = corner.z;
559   }                                               561   }
560                                                   562 
561   G4double sphi    = GetStartPhi();               563   G4double sphi    = GetStartPhi();
562   G4double ephi    = GetEndPhi();                 564   G4double ephi    = GetEndPhi();
563   G4double dphi    = IsOpen() ? ephi-sphi : tw    565   G4double dphi    = IsOpen() ? ephi-sphi : twopi;
564   G4int    ksteps  = GetNumSide();                566   G4int    ksteps  = GetNumSide();
565   G4double astep   = dphi/ksteps;                 567   G4double astep   = dphi/ksteps;
566   G4double sinStep = std::sin(astep);             568   G4double sinStep = std::sin(astep);
567   G4double cosStep = std::cos(astep);             569   G4double cosStep = std::cos(astep);
568                                                   570 
569   G4double sinCur = GetSinStartPhi();             571   G4double sinCur = GetSinStartPhi();
570   G4double cosCur = GetCosStartPhi();             572   G4double cosCur = GetCosStartPhi();
571   if (!IsOpen()) rmin = 0.;                       573   if (!IsOpen()) rmin = 0.;
572   G4double xmin = rmin*cosCur, xmax = xmin;       574   G4double xmin = rmin*cosCur, xmax = xmin;
573   G4double ymin = rmin*sinCur, ymax = ymin;       575   G4double ymin = rmin*sinCur, ymax = ymin;
574   for (G4int k=0; k<ksteps+1; ++k)                576   for (G4int k=0; k<ksteps+1; ++k)
575   {                                               577   {
576     G4double x = rmax*cosCur;                     578     G4double x = rmax*cosCur;
577     if (x < xmin) xmin = x;                       579     if (x < xmin) xmin = x;
578     if (x > xmax) xmax = x;                       580     if (x > xmax) xmax = x;
579     G4double y = rmax*sinCur;                     581     G4double y = rmax*sinCur;
580     if (y < ymin) ymin = y;                       582     if (y < ymin) ymin = y;
581     if (y > ymax) ymax = y;                       583     if (y > ymax) ymax = y;
582     if (rmin > 0)                                 584     if (rmin > 0)
583     {                                             585     {
584       G4double xx = rmin*cosCur;                  586       G4double xx = rmin*cosCur;
585       if (xx < xmin) xmin = xx;                   587       if (xx < xmin) xmin = xx;
586       if (xx > xmax) xmax = xx;                   588       if (xx > xmax) xmax = xx;
587       G4double yy = rmin*sinCur;                  589       G4double yy = rmin*sinCur;
588       if (yy < ymin) ymin = yy;                   590       if (yy < ymin) ymin = yy;
589       if (yy > ymax) ymax = yy;                   591       if (yy > ymax) ymax = yy;
590     }                                             592     }
591     G4double sinTmp = sinCur;                     593     G4double sinTmp = sinCur;
592     sinCur = sinCur*cosStep + cosCur*sinStep;     594     sinCur = sinCur*cosStep + cosCur*sinStep;
593     cosCur = cosCur*cosStep - sinTmp*sinStep;     595     cosCur = cosCur*cosStep - sinTmp*sinStep;
594   }                                               596   }
595   pMin.set(xmin,ymin,zmin);                       597   pMin.set(xmin,ymin,zmin);
596   pMax.set(xmax,ymax,zmax);                       598   pMax.set(xmax,ymax,zmax);
597                                                   599 
598   // Check correctness of the bounding box        600   // Check correctness of the bounding box
599   //                                              601   //
600   if (pMin.x() >= pMax.x() || pMin.y() >= pMax    602   if (pMin.x() >= pMax.x() || pMin.y() >= pMax.y() || pMin.z() >= pMax.z())
601   {                                               603   {
602     std::ostringstream message;                   604     std::ostringstream message;
603     message << "Bad bounding box (min >= max)     605     message << "Bad bounding box (min >= max) for solid: "
604             << GetName() << " !"                  606             << GetName() << " !"
605             << "\npMin = " << pMin                607             << "\npMin = " << pMin
606             << "\npMax = " << pMax;               608             << "\npMax = " << pMax;
607     G4Exception("G4Polyhedra::BoundingLimits()    609     G4Exception("G4Polyhedra::BoundingLimits()", "GeomMgt0001",
608                 JustWarning, message);            610                 JustWarning, message);
609     DumpInfo();                                   611     DumpInfo();
610   }                                               612   }
611 }                                                 613 }
612                                                   614 
613 // Calculate extent under transform and specif    615 // Calculate extent under transform and specified limit
614 //                                                616 //
615 G4bool G4Polyhedra::CalculateExtent(const EAxi    617 G4bool G4Polyhedra::CalculateExtent(const EAxis pAxis,
616                                     const G4Vo    618                                     const G4VoxelLimits& pVoxelLimit,
617                                     const G4Af    619                                     const G4AffineTransform& pTransform,
618                                     G4double&     620                                     G4double& pMin, G4double& pMax) const
619 {                                                 621 {
620   G4ThreeVector bmin, bmax;                       622   G4ThreeVector bmin, bmax;
621   G4bool exist;                                   623   G4bool exist;
622                                                   624 
623   // Check bounding box (bbox)                    625   // Check bounding box (bbox)
624   //                                              626   //
625   BoundingLimits(bmin,bmax);                      627   BoundingLimits(bmin,bmax);
626   G4BoundingEnvelope bbox(bmin,bmax);             628   G4BoundingEnvelope bbox(bmin,bmax);
627 #ifdef G4BBOX_EXTENT                              629 #ifdef G4BBOX_EXTENT
628   return bbox.CalculateExtent(pAxis,pVoxelLimi    630   return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
629 #endif                                            631 #endif
630   if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVox    632   if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVoxelLimit,pTransform,pMin,pMax))
631   {                                               633   {
632     return exist = pMin < pMax;                << 634     return exist = (pMin < pMax) ? true : false;
633   }                                               635   }
634                                                   636 
635   // To find the extent, RZ contour of the pol    637   // To find the extent, RZ contour of the polycone is subdivided
636   // in triangles. The extent is calculated as    638   // in triangles. The extent is calculated as cumulative extent of
637   // all sub-polycones formed by rotation of t    639   // all sub-polycones formed by rotation of triangles around Z
638   //                                              640   //
639   G4TwoVectorList contourRZ;                      641   G4TwoVectorList contourRZ;
640   G4TwoVectorList triangles;                      642   G4TwoVectorList triangles;
641   std::vector<G4int> iout;                        643   std::vector<G4int> iout;
642   G4double eminlim = pVoxelLimit.GetMinExtent(    644   G4double eminlim = pVoxelLimit.GetMinExtent(pAxis);
643   G4double emaxlim = pVoxelLimit.GetMaxExtent(    645   G4double emaxlim = pVoxelLimit.GetMaxExtent(pAxis);
644                                                   646 
645   // get RZ contour, ensure anticlockwise orde    647   // get RZ contour, ensure anticlockwise order of corners
646   for (G4int i=0; i<GetNumRZCorner(); ++i)        648   for (G4int i=0; i<GetNumRZCorner(); ++i)
647   {                                               649   {
648     G4PolyhedraSideRZ corner = GetCorner(i);      650     G4PolyhedraSideRZ corner = GetCorner(i);
649     contourRZ.emplace_back(corner.r,corner.z); << 651     contourRZ.push_back(G4TwoVector(corner.r,corner.z));
650   }                                               652   }
651   G4GeomTools::RemoveRedundantVertices(contour    653   G4GeomTools::RemoveRedundantVertices(contourRZ,iout,2*kCarTolerance);
652   G4double area = G4GeomTools::PolygonArea(con    654   G4double area = G4GeomTools::PolygonArea(contourRZ);
653   if (area < 0.) std::reverse(contourRZ.begin(    655   if (area < 0.) std::reverse(contourRZ.begin(),contourRZ.end());
654                                                   656 
655   // triangulate RZ countour                      657   // triangulate RZ countour
656   if (!G4GeomTools::TriangulatePolygon(contour    658   if (!G4GeomTools::TriangulatePolygon(contourRZ,triangles))
657   {                                               659   {
658     std::ostringstream message;                   660     std::ostringstream message;
659     message << "Triangulation of RZ contour ha    661     message << "Triangulation of RZ contour has failed for solid: "
660             << GetName() << " !"                  662             << GetName() << " !"
661             << "\nExtent has been calculated u    663             << "\nExtent has been calculated using boundary box";
662     G4Exception("G4Polyhedra::CalculateExtent(    664     G4Exception("G4Polyhedra::CalculateExtent()",
663                 "GeomMgt1002",JustWarning,mess    665                 "GeomMgt1002",JustWarning,message);
664     return bbox.CalculateExtent(pAxis,pVoxelLi    666     return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
665   }                                               667   }
666                                                   668 
667   // set trigonometric values                     669   // set trigonometric values
668   G4double sphi     = GetStartPhi();              670   G4double sphi     = GetStartPhi();
669   G4double ephi     = GetEndPhi();                671   G4double ephi     = GetEndPhi();
670   G4double dphi     = IsOpen() ? ephi-sphi : t    672   G4double dphi     = IsOpen() ? ephi-sphi : twopi;
671   G4int    ksteps   = GetNumSide();               673   G4int    ksteps   = GetNumSide();
672   G4double astep    = dphi/ksteps;                674   G4double astep    = dphi/ksteps;
673   G4double sinStep  = std::sin(astep);            675   G4double sinStep  = std::sin(astep);
674   G4double cosStep  = std::cos(astep);            676   G4double cosStep  = std::cos(astep);
675   G4double sinStart = GetSinStartPhi();           677   G4double sinStart = GetSinStartPhi();
676   G4double cosStart = GetCosStartPhi();           678   G4double cosStart = GetCosStartPhi();
677                                                   679 
678   // allocate vector lists                        680   // allocate vector lists
679   std::vector<const G4ThreeVectorList *> polyg    681   std::vector<const G4ThreeVectorList *> polygons;
680   polygons.resize(ksteps+1);                      682   polygons.resize(ksteps+1);
681   for (G4int k=0; k<ksteps+1; ++k)                683   for (G4int k=0; k<ksteps+1; ++k)
682   {                                               684   {
683     polygons[k] = new G4ThreeVectorList(3);       685     polygons[k] = new G4ThreeVectorList(3);
684   }                                               686   }
685                                                   687 
686   // main loop along triangles                    688   // main loop along triangles
687   pMin =  kInfinity;                              689   pMin =  kInfinity;
688   pMax = -kInfinity;                              690   pMax = -kInfinity;
689   G4int ntria = (G4int)triangles.size()/3;        691   G4int ntria = (G4int)triangles.size()/3;
690   for (G4int i=0; i<ntria; ++i)                   692   for (G4int i=0; i<ntria; ++i)
691   {                                               693   {
692     G4double sinCur = sinStart;                   694     G4double sinCur = sinStart;
693     G4double cosCur = cosStart;                   695     G4double cosCur = cosStart;
694     G4int i3 = i*3;                               696     G4int i3 = i*3;
695     for (G4int k=0; k<ksteps+1; ++k) // rotate    697     for (G4int k=0; k<ksteps+1; ++k) // rotate triangle
696     {                                             698     {
697       auto ptr = const_cast<G4ThreeVectorList* << 699       G4ThreeVectorList* ptr = const_cast<G4ThreeVectorList*>(polygons[k]);
698       auto iter = ptr->begin();                << 700       G4ThreeVectorList::iterator iter = ptr->begin();
699       iter->set(triangles[i3+0].x()*cosCur,       701       iter->set(triangles[i3+0].x()*cosCur,
700                 triangles[i3+0].x()*sinCur,       702                 triangles[i3+0].x()*sinCur,
701                 triangles[i3+0].y());             703                 triangles[i3+0].y());
702       iter++;                                     704       iter++;
703       iter->set(triangles[i3+1].x()*cosCur,       705       iter->set(triangles[i3+1].x()*cosCur,
704                 triangles[i3+1].x()*sinCur,       706                 triangles[i3+1].x()*sinCur,
705                 triangles[i3+1].y());             707                 triangles[i3+1].y());
706       iter++;                                     708       iter++;
707       iter->set(triangles[i3+2].x()*cosCur,       709       iter->set(triangles[i3+2].x()*cosCur,
708                 triangles[i3+2].x()*sinCur,       710                 triangles[i3+2].x()*sinCur,
709                 triangles[i3+2].y());             711                 triangles[i3+2].y());
710                                                   712 
711       G4double sinTmp = sinCur;                   713       G4double sinTmp = sinCur;
712       sinCur = sinCur*cosStep + cosCur*sinStep    714       sinCur = sinCur*cosStep + cosCur*sinStep;
713       cosCur = cosCur*cosStep - sinTmp*sinStep    715       cosCur = cosCur*cosStep - sinTmp*sinStep;
714     }                                             716     }
715                                                   717 
716     // set sub-envelope and adjust extent         718     // set sub-envelope and adjust extent
717     G4double emin,emax;                           719     G4double emin,emax;
718     G4BoundingEnvelope benv(polygons);            720     G4BoundingEnvelope benv(polygons);
719     if (!benv.CalculateExtent(pAxis,pVoxelLimi    721     if (!benv.CalculateExtent(pAxis,pVoxelLimit,pTransform,emin,emax)) continue;
720     if (emin < pMin) pMin = emin;                 722     if (emin < pMin) pMin = emin;
721     if (emax > pMax) pMax = emax;                 723     if (emax > pMax) pMax = emax;
722     if (eminlim > pMin && emaxlim < pMax) brea    724     if (eminlim > pMin && emaxlim < pMax) break; // max possible extent
723   }                                               725   }
724   // free memory                                  726   // free memory
725   for (G4int k=0; k<ksteps+1; ++k) { delete po << 727   for (G4int k=0; k<ksteps+1; ++k) { delete polygons[k]; polygons[k]=0;}
726   return (pMin < pMax);                           728   return (pMin < pMax);
727 }                                                 729 }
728                                                   730 
729 // ComputeDimensions                              731 // ComputeDimensions
730 //                                                732 //
731 void G4Polyhedra::ComputeDimensions(       G4V    733 void G4Polyhedra::ComputeDimensions(       G4VPVParameterisation* p,
732                                      const G4i    734                                      const G4int n,
733                                      const G4V    735                                      const G4VPhysicalVolume* pRep )
734 {                                                 736 {
735   p->ComputeDimensions(*this,n,pRep);             737   p->ComputeDimensions(*this,n,pRep);
736 }                                                 738 }
737                                                   739 
738 // GetEntityType                                  740 // GetEntityType
739 //                                                741 //
740 G4GeometryType G4Polyhedra::GetEntityType() co    742 G4GeometryType G4Polyhedra::GetEntityType() const
741 {                                                 743 {
742   return {"G4Polyhedra"};                      << 744   return G4String("G4Polyhedra");
743 }                                              << 
744                                                << 
745 // IsFaceted                                   << 
746 //                                             << 
747 G4bool G4Polyhedra::IsFaceted() const          << 
748 {                                              << 
749   return true;                                 << 
750 }                                                 745 }
751                                                   746 
752 // Make a clone of the object                     747 // Make a clone of the object
753 //                                                748 //
754 G4VSolid* G4Polyhedra::Clone() const              749 G4VSolid* G4Polyhedra::Clone() const
755 {                                                 750 {
756   return new G4Polyhedra(*this);                  751   return new G4Polyhedra(*this);
757 }                                                 752 }
758                                                   753 
759 // Stream object contents to an output stream     754 // Stream object contents to an output stream
760 //                                                755 //
761 std::ostream& G4Polyhedra::StreamInfo( std::os    756 std::ostream& G4Polyhedra::StreamInfo( std::ostream& os ) const
762 {                                                 757 {
763   G4long oldprc = os.precision(16);               758   G4long oldprc = os.precision(16);
764   os << "-------------------------------------    759   os << "-----------------------------------------------------------\n"
765      << "    *** Dump for solid - " << GetName    760      << "    *** Dump for solid - " << GetName() << " ***\n"
766      << "    =================================    761      << "    ===================================================\n"
767      << " Solid type: G4Polyhedra\n"              762      << " Solid type: G4Polyhedra\n"
768      << " Parameters: \n"                         763      << " Parameters: \n"
769      << "    starting phi angle : " << startPh    764      << "    starting phi angle : " << startPhi/degree << " degrees \n"
770      << "    ending phi angle   : " << endPhi/    765      << "    ending phi angle   : " << endPhi/degree << " degrees \n"
771      << "    number of sides    : " << numSide    766      << "    number of sides    : " << numSide << " \n";
772   G4int i=0;                                      767   G4int i=0;
773   if (!genericPgon)                               768   if (!genericPgon)
774   {                                               769   {
775     G4int numPlanes = original_parameters->Num    770     G4int numPlanes = original_parameters->Num_z_planes;
776     os << "    number of Z planes: " << numPla    771     os << "    number of Z planes: " << numPlanes << "\n"
777        << "              Z values: \n";           772        << "              Z values: \n";
778     for (i=0; i<numPlanes; ++i)                   773     for (i=0; i<numPlanes; ++i)
779     {                                             774     {
780       os << "              Z plane " << i << "    775       os << "              Z plane " << i << ": "
781          << original_parameters->Z_values[i] <    776          << original_parameters->Z_values[i] << "\n";
782     }                                             777     }
783     os << "              Tangent distances to     778     os << "              Tangent distances to inner surface (Rmin): \n";
784     for (i=0; i<numPlanes; ++i)                   779     for (i=0; i<numPlanes; ++i)
785     {                                             780     {
786       os << "              Z plane " << i << "    781       os << "              Z plane " << i << ": "
787          << original_parameters->Rmin[i] << "\    782          << original_parameters->Rmin[i] << "\n";
788     }                                             783     }
789     os << "              Tangent distances to     784     os << "              Tangent distances to outer surface (Rmax): \n";
790     for (i=0; i<numPlanes; ++i)                   785     for (i=0; i<numPlanes; ++i)
791     {                                             786     {
792       os << "              Z plane " << i << "    787       os << "              Z plane " << i << ": "
793          << original_parameters->Rmax[i] << "\    788          << original_parameters->Rmax[i] << "\n";
794     }                                             789     }
795   }                                               790   }
796   os << "    number of RZ points: " << numCorn    791   os << "    number of RZ points: " << numCorner << "\n"
797      << "              RZ values (corners): \n    792      << "              RZ values (corners): \n";
798      for (i=0; i<numCorner; ++i)                  793      for (i=0; i<numCorner; ++i)
799      {                                            794      {
800        os << "                         "          795        os << "                         "
801           << corners[i].r << ", " << corners[i    796           << corners[i].r << ", " << corners[i].z << "\n";
802      }                                            797      }
803   os << "-------------------------------------    798   os << "-----------------------------------------------------------\n";
804   os.precision(oldprc);                           799   os.precision(oldprc);
805                                                   800 
806   return os;                                      801   return os;
807 }                                                 802 }
808                                                   803 
809 //////////////////////////////////////////////    804 //////////////////////////////////////////////////////////////////////////
810 //                                                805 //
811 // Return volume                                  806 // Return volume
812                                                   807 
813 G4double G4Polyhedra::GetCubicVolume()            808 G4double G4Polyhedra::GetCubicVolume()
814 {                                                 809 {
815   if (fCubicVolume == 0.)                         810   if (fCubicVolume == 0.)
816   {                                               811   {
817     G4double total = 0.;                          812     G4double total = 0.;
818     G4int nrz = GetNumRZCorner();                 813     G4int nrz = GetNumRZCorner();
819     G4PolyhedraSideRZ a = GetCorner(nrz - 1);     814     G4PolyhedraSideRZ a = GetCorner(nrz - 1);
820     for (G4int i=0; i<nrz; ++i)                   815     for (G4int i=0; i<nrz; ++i)
821     {                                             816     {
822       G4PolyhedraSideRZ b = GetCorner(i);         817       G4PolyhedraSideRZ b = GetCorner(i);
823       total += (b.r*b.r + b.r*a.r + a.r*a.r)*(    818       total += (b.r*b.r + b.r*a.r + a.r*a.r)*(b.z - a.z);
824       a = b;                                      819       a = b;
825     }                                             820     }
826     fCubicVolume = std::abs(total)*               821     fCubicVolume = std::abs(total)*
827       std::sin((GetEndPhi() - GetStartPhi())/G    822       std::sin((GetEndPhi() - GetStartPhi())/GetNumSide())*GetNumSide()/6.;
828   }                                               823   }
829   return fCubicVolume;                            824   return fCubicVolume;
830 }                                                 825 }
831                                                   826 
832 //////////////////////////////////////////////    827 //////////////////////////////////////////////////////////////////////////
833 //                                                828 //
834 // Return surface area                            829 // Return surface area
835                                                   830 
836 G4double G4Polyhedra::GetSurfaceArea()            831 G4double G4Polyhedra::GetSurfaceArea()
837 {                                                 832 {
838   if (fSurfaceArea == 0.)                         833   if (fSurfaceArea == 0.)
839   {                                               834   {
840     G4double total = 0.;                          835     G4double total = 0.;
841     G4int nrz = GetNumRZCorner();                 836     G4int nrz = GetNumRZCorner();
842     if (IsOpen())                                 837     if (IsOpen())
843     {                                             838     {
844       G4PolyhedraSideRZ a = GetCorner(nrz - 1)    839       G4PolyhedraSideRZ a = GetCorner(nrz - 1);
845       for (G4int i=0; i<nrz; ++i)                 840       for (G4int i=0; i<nrz; ++i)
846       {                                           841       {
847         G4PolyhedraSideRZ b = GetCorner(i);       842         G4PolyhedraSideRZ b = GetCorner(i);
848         total += a.r*b.z - a.z*b.r;               843         total += a.r*b.z - a.z*b.r;
849         a = b;                                    844         a = b;
850       }                                           845       }
851       total = std::abs(total);                    846       total = std::abs(total);
852     }                                             847     }
853     G4double alp = (GetEndPhi() - GetStartPhi(    848     G4double alp = (GetEndPhi() - GetStartPhi())/GetNumSide();
854     G4double cosa = std::cos(alp);                849     G4double cosa = std::cos(alp);
855     G4double sina = std::sin(alp);                850     G4double sina = std::sin(alp);
856     G4PolyhedraSideRZ a = GetCorner(nrz - 1);     851     G4PolyhedraSideRZ a = GetCorner(nrz - 1);
857     for (G4int i=0; i<nrz; ++i)                   852     for (G4int i=0; i<nrz; ++i)
858     {                                             853     {
859       G4PolyhedraSideRZ b = GetCorner(i);         854       G4PolyhedraSideRZ b = GetCorner(i);
860       G4ThreeVector p1(a.r, 0, a.z);              855       G4ThreeVector p1(a.r, 0, a.z);
861       G4ThreeVector p2(a.r*cosa, a.r*sina, a.z    856       G4ThreeVector p2(a.r*cosa, a.r*sina, a.z);
862       G4ThreeVector p3(b.r*cosa, b.r*sina, b.z    857       G4ThreeVector p3(b.r*cosa, b.r*sina, b.z);
863       G4ThreeVector p4(b.r, 0, b.z);              858       G4ThreeVector p4(b.r, 0, b.z);
864       total += GetNumSide()*(G4GeomTools::Quad    859       total += GetNumSide()*(G4GeomTools::QuadAreaNormal(p1, p2, p3, p4)).mag();
865       a = b;                                      860       a = b;
866     }                                             861     }
867     fSurfaceArea = total;                         862     fSurfaceArea = total;
868   }                                               863   }
869   return fSurfaceArea;                            864   return fSurfaceArea;
870 }                                                 865 }
871                                                   866 
872 //////////////////////////////////////////////    867 //////////////////////////////////////////////////////////////////////////
873 //                                                868 //
874 // Set vector of surface elements, auxiliary m    869 // Set vector of surface elements, auxiliary method for sampling
875 // random points on surface                       870 // random points on surface
876                                                   871 
877 void G4Polyhedra::SetSurfaceElements() const      872 void G4Polyhedra::SetSurfaceElements() const
878 {                                                 873 {
879   fElements = new std::vector<G4Polyhedra::sur    874   fElements = new std::vector<G4Polyhedra::surface_element>;
880   G4double total = 0.;                            875   G4double total = 0.;
881   G4int nrz = GetNumRZCorner();                   876   G4int nrz = GetNumRZCorner();
882                                                   877 
883   // set lateral surface elements                 878   // set lateral surface elements
884   G4double dphi = (GetEndPhi() - GetStartPhi()    879   G4double dphi = (GetEndPhi() - GetStartPhi())/GetNumSide();
885   G4double cosa = std::cos(dphi);                 880   G4double cosa = std::cos(dphi);
886   G4double sina = std::sin(dphi);                 881   G4double sina = std::sin(dphi);
887   G4int ia = nrz - 1;                             882   G4int ia = nrz - 1;
888   for (G4int ib=0; ib<nrz; ++ib)                  883   for (G4int ib=0; ib<nrz; ++ib)
889   {                                               884   {
890     G4PolyhedraSideRZ a = GetCorner(ia);          885     G4PolyhedraSideRZ a = GetCorner(ia);
891     G4PolyhedraSideRZ b = GetCorner(ib);          886     G4PolyhedraSideRZ b = GetCorner(ib);
892     G4Polyhedra::surface_element selem;           887     G4Polyhedra::surface_element selem;
893     selem.i0 = ia;                                888     selem.i0 = ia;
894     selem.i1 = ib;                                889     selem.i1 = ib;
895     ia = ib;                                      890     ia = ib;
896     if (a.r == 0. && b.r == 0.) continue;         891     if (a.r == 0. && b.r == 0.) continue;
897     G4ThreeVector p1(a.r, 0, a.z);                892     G4ThreeVector p1(a.r, 0, a.z);
898     G4ThreeVector p2(a.r*cosa, a.r*sina, a.z);    893     G4ThreeVector p2(a.r*cosa, a.r*sina, a.z);
899     G4ThreeVector p3(b.r*cosa, b.r*sina, b.z);    894     G4ThreeVector p3(b.r*cosa, b.r*sina, b.z);
900     G4ThreeVector p4(b.r, 0, b.z);                895     G4ThreeVector p4(b.r, 0, b.z);
901     if (a.r > 0.)                                 896     if (a.r > 0.)
902     {                                             897     {
903       selem.i2 = -1;                              898       selem.i2 = -1;
904       total += GetNumSide()*(G4GeomTools::Tria    899       total += GetNumSide()*(G4GeomTools::TriangleAreaNormal(p1, p2, p3)).mag();
905       selem.area = total;                         900       selem.area = total;
906       fElements->push_back(selem);                901       fElements->push_back(selem);
907     }                                             902     }
908     if (b.r > 0.)                                 903     if (b.r > 0.)
909     {                                             904     {
910       selem.i2 = -2;                              905       selem.i2 = -2;
911       total += GetNumSide()*(G4GeomTools::Tria    906       total += GetNumSide()*(G4GeomTools::TriangleAreaNormal(p1, p3, p4)).mag();
912       selem.area = total;                         907       selem.area = total;
913       fElements->push_back(selem);                908       fElements->push_back(selem);
914     }                                             909     }
915   }                                               910   }
916                                                   911 
917   // set elements for phi cuts                    912   // set elements for phi cuts
918   if (IsOpen())                                   913   if (IsOpen())
919   {                                               914   {
920     G4TwoVectorList contourRZ;                    915     G4TwoVectorList contourRZ;
921     std::vector<G4int> triangles;                 916     std::vector<G4int> triangles;
922     for (G4int i=0; i<nrz; ++i)                   917     for (G4int i=0; i<nrz; ++i)
923     {                                             918     {
924       G4PolyhedraSideRZ corner = GetCorner(i);    919       G4PolyhedraSideRZ corner = GetCorner(i);
925       contourRZ.emplace_back(corner.r, corner. << 920       contourRZ.push_back(G4TwoVector(corner.r, corner.z));
926     }                                             921     }
927     G4GeomTools::TriangulatePolygon(contourRZ,    922     G4GeomTools::TriangulatePolygon(contourRZ, triangles);
928     auto ntria = (G4int)triangles.size();      << 923     G4int ntria = (G4int)triangles.size();
929     for (G4int i=0; i<ntria; i+=3)                924     for (G4int i=0; i<ntria; i+=3)
930     {                                             925     {
931       G4Polyhedra::surface_element selem;         926       G4Polyhedra::surface_element selem;
932       selem.i0 = triangles[i];                    927       selem.i0 = triangles[i];
933       selem.i1 = triangles[i+1];                  928       selem.i1 = triangles[i+1];
934       selem.i2 = triangles[i+2];                  929       selem.i2 = triangles[i+2];
935       G4PolyhedraSideRZ a = GetCorner(selem.i0    930       G4PolyhedraSideRZ a = GetCorner(selem.i0);
936       G4PolyhedraSideRZ b = GetCorner(selem.i1    931       G4PolyhedraSideRZ b = GetCorner(selem.i1);
937       G4PolyhedraSideRZ c = GetCorner(selem.i2    932       G4PolyhedraSideRZ c = GetCorner(selem.i2);
938       G4double stria =                            933       G4double stria =
939         std::abs(G4GeomTools::TriangleArea(a.r    934         std::abs(G4GeomTools::TriangleArea(a.r, a.z, b.r, b.z, c.r, c.z));
940       total += stria;                             935       total += stria;
941       selem.area = total;                         936       selem.area = total;
942       fElements->push_back(selem); // start ph    937       fElements->push_back(selem); // start phi
943       total += stria;                             938       total += stria;
944       selem.area = total;                         939       selem.area = total;
945       selem.i0 += nrz;                            940       selem.i0 += nrz;
946       fElements->push_back(selem); // end phi     941       fElements->push_back(selem); // end phi
947     }                                             942     }
948   }                                               943   }
949 }                                                 944 }
950                                                   945 
951 //////////////////////////////////////////////    946 //////////////////////////////////////////////////////////////////////////
952 //                                                947 //
953 // Generate random point on surface               948 // Generate random point on surface
954                                                   949 
955 G4ThreeVector G4Polyhedra::GetPointOnSurface()    950 G4ThreeVector G4Polyhedra::GetPointOnSurface() const
956 {                                                 951 {
957   // Set surface elements                         952   // Set surface elements
958   if (fElements == nullptr)                    << 953   if (!fElements)
959   {                                               954   {
960     G4AutoLock l(&surface_elementsMutex);         955     G4AutoLock l(&surface_elementsMutex);
961     SetSurfaceElements();                         956     SetSurfaceElements();
962     l.unlock();                                   957     l.unlock();
963   }                                               958   }
964                                                   959 
965   // Select surface element                       960   // Select surface element
966   G4Polyhedra::surface_element selem;             961   G4Polyhedra::surface_element selem;
967   selem = fElements->back();                      962   selem = fElements->back();
968   G4double select = selem.area*G4QuickRand();     963   G4double select = selem.area*G4QuickRand();
969   auto it = std::lower_bound(fElements->begin(    964   auto it = std::lower_bound(fElements->begin(), fElements->end(), select,
970                              [](const G4Polyhe    965                              [](const G4Polyhedra::surface_element& x, G4double val)
971                              -> G4bool { retur    966                              -> G4bool { return x.area < val; });
972                                                   967 
973   // Generate random point                        968   // Generate random point
974   G4double x = 0, y = 0, z = 0;                   969   G4double x = 0, y = 0, z = 0;
975   G4double u = G4QuickRand();                     970   G4double u = G4QuickRand();
976   G4double v = G4QuickRand();                     971   G4double v = G4QuickRand();
977   if (u + v > 1.) { u = 1. - u; v = 1. - v; }     972   if (u + v > 1.) { u = 1. - u; v = 1. - v; }
978   G4int i0 = (*it).i0;                            973   G4int i0 = (*it).i0;
979   G4int i1 = (*it).i1;                            974   G4int i1 = (*it).i1;
980   G4int i2 = (*it).i2;                            975   G4int i2 = (*it).i2;
981   if (i2 < 0) // lateral surface                  976   if (i2 < 0) // lateral surface
982   {                                               977   {
983     // sample point                               978     // sample point
984     G4int nside = GetNumSide();                   979     G4int nside = GetNumSide();
985     G4double dphi = (GetEndPhi() - GetStartPhi    980     G4double dphi = (GetEndPhi() - GetStartPhi())/nside;
986     G4double cosa = std::cos(dphi);               981     G4double cosa = std::cos(dphi);
987     G4double sina = std::sin(dphi);               982     G4double sina = std::sin(dphi);
988     G4PolyhedraSideRZ a = GetCorner(i0);          983     G4PolyhedraSideRZ a = GetCorner(i0);
989     G4PolyhedraSideRZ b = GetCorner(i1);          984     G4PolyhedraSideRZ b = GetCorner(i1);
990     G4ThreeVector p0(a.r, 0, a.z);                985     G4ThreeVector p0(a.r, 0, a.z);
991     G4ThreeVector p1(b.r, 0, b.z);                986     G4ThreeVector p1(b.r, 0, b.z);
992     G4ThreeVector p2(b.r*cosa, b.r*sina, b.z);    987     G4ThreeVector p2(b.r*cosa, b.r*sina, b.z);
993     if (i2 == -1) p1.set(a.r*cosa, a.r*sina, a    988     if (i2 == -1) p1.set(a.r*cosa, a.r*sina, a.z);
994     p0 += (p1 - p0)*u + (p2 - p0)*v;              989     p0 += (p1 - p0)*u + (p2 - p0)*v;
995     // find selected side and rotate point        990     // find selected side and rotate point
996     G4double scurr = (*it).area;                  991     G4double scurr = (*it).area;
997     G4double sprev = (it == fElements->begin()    992     G4double sprev = (it == fElements->begin()) ? 0. : (*(--it)).area;
998     G4int iside = nside*(select - sprev)/(scur    993     G4int iside = nside*(select - sprev)/(scurr - sprev);
999     if (iside == 0 && GetStartPhi() == 0.)        994     if (iside == 0 && GetStartPhi() == 0.)
1000     {                                            995     {
1001       x = p0.x();                                996       x = p0.x();
1002       y = p0.y();                                997       y = p0.y();
1003       z = p0.z();                                998       z = p0.z();
1004     }                                            999     }
1005     else                                         1000     else
1006     {                                            1001     {
1007       if (iside == nside) --iside; // iside m    1002       if (iside == nside) --iside; // iside must be less then nside
1008       G4double phi = iside*dphi + GetStartPhi    1003       G4double phi = iside*dphi + GetStartPhi();
1009       G4double cosphi = std::cos(phi);           1004       G4double cosphi = std::cos(phi);
1010       G4double sinphi = std::sin(phi);           1005       G4double sinphi = std::sin(phi);
1011       x = p0.x()*cosphi - p0.y()*sinphi;         1006       x = p0.x()*cosphi - p0.y()*sinphi;
1012       y = p0.x()*sinphi + p0.y()*cosphi;         1007       y = p0.x()*sinphi + p0.y()*cosphi;
1013       z = p0.z();                                1008       z = p0.z();
1014     }                                            1009     }
1015   }                                              1010   }
1016   else // phi cut                                1011   else // phi cut
1017   {                                              1012   {
1018     G4int nrz = GetNumRZCorner();                1013     G4int nrz = GetNumRZCorner();
1019     G4double phi = (i0 < nrz) ? GetStartPhi()    1014     G4double phi = (i0 < nrz) ? GetStartPhi() : GetEndPhi();
1020     if (i0 >= nrz) { i0 -= nrz; }                1015     if (i0 >= nrz) { i0 -= nrz; }
1021     G4PolyhedraSideRZ p0 = GetCorner(i0);        1016     G4PolyhedraSideRZ p0 = GetCorner(i0);
1022     G4PolyhedraSideRZ p1 = GetCorner(i1);        1017     G4PolyhedraSideRZ p1 = GetCorner(i1);
1023     G4PolyhedraSideRZ p2 = GetCorner(i2);        1018     G4PolyhedraSideRZ p2 = GetCorner(i2);
1024     G4double r = (p1.r - p0.r)*u + (p2.r - p0    1019     G4double r = (p1.r - p0.r)*u + (p2.r - p0.r)*v + p0.r;
1025     x = r*std::cos(phi);                         1020     x = r*std::cos(phi);
1026     y = r*std::sin(phi);                         1021     y = r*std::sin(phi);
1027     z = (p1.z - p0.z)*u + (p2.z - p0.z)*v + p    1022     z = (p1.z - p0.z)*u + (p2.z - p0.z)*v + p0.z;
1028   }                                              1023   }
1029   return {x, y, z};                           << 1024   return G4ThreeVector(x, y, z);
1030 }                                                1025 }
1031                                                  1026 
1032 /////////////////////////////////////////////    1027 //////////////////////////////////////////////////////////////////////////
1033 //                                               1028 //
1034 // CreatePolyhedron                              1029 // CreatePolyhedron
1035                                                  1030 
1036 G4Polyhedron* G4Polyhedra::CreatePolyhedron()    1031 G4Polyhedron* G4Polyhedra::CreatePolyhedron() const
1037 {                                                1032 {
1038   std::vector<G4TwoVector> rz(numCorner);        1033   std::vector<G4TwoVector> rz(numCorner);
1039   for (G4int i = 0; i < numCorner; ++i)          1034   for (G4int i = 0; i < numCorner; ++i)
1040     rz[i].set(corners[i].r, corners[i].z);       1035     rz[i].set(corners[i].r, corners[i].z);
1041   return new G4PolyhedronPgon(startPhi, endPh    1036   return new G4PolyhedronPgon(startPhi, endPhi - startPhi, numSide, rz);
1042 }                                                1037 }
1043                                                  1038 
1044 // SetOriginalParameters                         1039 // SetOriginalParameters
1045 //                                               1040 //
1046 void G4Polyhedra::SetOriginalParameters(G4Red    1041 void G4Polyhedra::SetOriginalParameters(G4ReduciblePolygon* rz)
1047 {                                                1042 {
1048   G4int numPlanes = numCorner;                   1043   G4int numPlanes = numCorner;
1049   G4bool isConvertible = true;                   1044   G4bool isConvertible = true;
1050   G4double Zmax=rz->Bmax();                      1045   G4double Zmax=rz->Bmax();
1051   rz->StartWithZMin();                           1046   rz->StartWithZMin();
1052                                                  1047 
1053   // Prepare vectors for storage                 1048   // Prepare vectors for storage
1054   //                                             1049   //
1055   std::vector<G4double> Z;                       1050   std::vector<G4double> Z;
1056   std::vector<G4double> Rmin;                    1051   std::vector<G4double> Rmin;
1057   std::vector<G4double> Rmax;                    1052   std::vector<G4double> Rmax;
1058                                                  1053 
1059   G4int countPlanes=1;                           1054   G4int countPlanes=1;
1060   G4int icurr=0;                                 1055   G4int icurr=0;
1061   G4int icurl=0;                                 1056   G4int icurl=0;
1062                                                  1057 
1063   // first plane Z=Z[0]                          1058   // first plane Z=Z[0]
1064   //                                             1059   //
1065   Z.push_back(corners[0].z);                     1060   Z.push_back(corners[0].z);
1066   G4double Zprev=Z[0];                           1061   G4double Zprev=Z[0];
1067   if (Zprev == corners[1].z)                     1062   if (Zprev == corners[1].z)
1068   {                                              1063   {
1069     Rmin.push_back(corners[0].r);                1064     Rmin.push_back(corners[0].r);
1070     Rmax.push_back (corners[1].r);icurr=1;       1065     Rmax.push_back (corners[1].r);icurr=1;
1071   }                                              1066   }
1072   else if (Zprev == corners[numPlanes-1].z)      1067   else if (Zprev == corners[numPlanes-1].z)
1073   {                                              1068   {
1074     Rmin.push_back(corners[numPlanes-1].r);      1069     Rmin.push_back(corners[numPlanes-1].r);
1075     Rmax.push_back (corners[0].r);               1070     Rmax.push_back (corners[0].r);
1076     icurl=numPlanes-1;                           1071     icurl=numPlanes-1;
1077   }                                              1072   }
1078   else                                           1073   else
1079   {                                              1074   {
1080     Rmin.push_back(corners[0].r);                1075     Rmin.push_back(corners[0].r);
1081     Rmax.push_back (corners[0].r);               1076     Rmax.push_back (corners[0].r);
1082   }                                              1077   }
1083                                                  1078 
1084   // next planes until last                      1079   // next planes until last
1085   //                                             1080   //
1086   G4int inextr=0, inextl=0;                      1081   G4int inextr=0, inextl=0;
1087   for (G4int i=0; i < numPlanes-2; ++i)          1082   for (G4int i=0; i < numPlanes-2; ++i)
1088   {                                              1083   {
1089     inextr=1+icurr;                              1084     inextr=1+icurr;
1090     inextl=(icurl <= 0)? numPlanes-1 : icurl-    1085     inextl=(icurl <= 0)? numPlanes-1 : icurl-1;
1091                                                  1086 
1092     if((corners[inextr].z >= Zmax) & (corners    1087     if((corners[inextr].z >= Zmax) & (corners[inextl].z >= Zmax))  { break; }
1093                                                  1088 
1094     G4double Zleft = corners[inextl].z;          1089     G4double Zleft = corners[inextl].z;
1095     G4double Zright = corners[inextr].z;         1090     G4double Zright = corners[inextr].z;
1096     if(Zright>Zleft)                             1091     if(Zright>Zleft)
1097     {                                            1092     {
1098       Z.push_back(Zleft);                        1093       Z.push_back(Zleft);
1099       countPlanes++;                             1094       countPlanes++;
1100       G4double difZr=corners[inextr].z - corn    1095       G4double difZr=corners[inextr].z - corners[icurr].z;
1101       G4double difZl=corners[inextl].z - corn    1096       G4double difZl=corners[inextl].z - corners[icurl].z;
1102                                                  1097 
1103       if(std::fabs(difZl) < kCarTolerance)       1098       if(std::fabs(difZl) < kCarTolerance)
1104       {                                          1099       {
1105         if(std::fabs(difZr) < kCarTolerance)     1100         if(std::fabs(difZr) < kCarTolerance)
1106         {                                        1101         {
1107           Rmin.push_back(corners[inextl].r);     1102           Rmin.push_back(corners[inextl].r);
1108           Rmax.push_back(corners[icurr].r);      1103           Rmax.push_back(corners[icurr].r);
1109         }                                        1104         }
1110         else                                     1105         else
1111         {                                        1106         {
1112           Rmin.push_back(corners[inextl].r);     1107           Rmin.push_back(corners[inextl].r);
1113           Rmax.push_back(corners[icurr].r + (    1108           Rmax.push_back(corners[icurr].r + (Zleft-corners[icurr].z)/difZr
1114                                 *(corners[ine    1109                                 *(corners[inextr].r - corners[icurr].r));
1115         }                                        1110         }
1116       }                                          1111       }
1117       else if (difZl >= kCarTolerance)           1112       else if (difZl >= kCarTolerance)
1118       {                                          1113       {
1119         if(std::fabs(difZr) < kCarTolerance)     1114         if(std::fabs(difZr) < kCarTolerance)
1120         {                                        1115         {
1121           Rmin.push_back(corners[icurl].r);      1116           Rmin.push_back(corners[icurl].r);
1122           Rmax.push_back(corners[icurr].r);      1117           Rmax.push_back(corners[icurr].r);
1123         }                                        1118         }
1124         else                                     1119         else
1125         {                                        1120         {
1126           Rmin.push_back(corners[icurl].r);      1121           Rmin.push_back(corners[icurl].r);
1127           Rmax.push_back(corners[icurr].r + (    1122           Rmax.push_back(corners[icurr].r + (Zleft-corners[icurr].z)/difZr
1128                                 *(corners[ine    1123                                 *(corners[inextr].r - corners[icurr].r));
1129         }                                        1124         }
1130       }                                          1125       }
1131       else                                       1126       else
1132       {                                          1127       {
1133         isConvertible=false; break;              1128         isConvertible=false; break;
1134       }                                          1129       }
1135       icurl=(icurl == 0)? numPlanes-1 : icurl    1130       icurl=(icurl == 0)? numPlanes-1 : icurl-1;
1136     }                                            1131     }
1137     else if(std::fabs(Zright-Zleft)<kCarToler    1132     else if(std::fabs(Zright-Zleft)<kCarTolerance)  // Zright=Zleft
1138     {                                            1133     {
1139       Z.push_back(Zleft);                        1134       Z.push_back(Zleft);
1140       ++countPlanes;                             1135       ++countPlanes;
1141       ++icurr;                                   1136       ++icurr;
1142                                                  1137 
1143       icurl=(icurl == 0)? numPlanes-1 : icurl    1138       icurl=(icurl == 0)? numPlanes-1 : icurl-1;
1144                                                  1139 
1145       Rmin.push_back(corners[inextl].r);         1140       Rmin.push_back(corners[inextl].r);
1146       Rmax.push_back (corners[inextr].r);        1141       Rmax.push_back (corners[inextr].r);
1147     }                                            1142     }
1148     else  // Zright<Zleft                        1143     else  // Zright<Zleft
1149     {                                            1144     {
1150       Z.push_back(Zright);                       1145       Z.push_back(Zright);
1151       ++countPlanes;                             1146       ++countPlanes;
1152                                                  1147 
1153       G4double difZr=corners[inextr].z - corn    1148       G4double difZr=corners[inextr].z - corners[icurr].z;
1154       G4double difZl=corners[inextl].z - corn    1149       G4double difZl=corners[inextl].z - corners[icurl].z;
1155       if(std::fabs(difZr) < kCarTolerance)       1150       if(std::fabs(difZr) < kCarTolerance)
1156       {                                          1151       {
1157         if(std::fabs(difZl) < kCarTolerance)     1152         if(std::fabs(difZl) < kCarTolerance)
1158         {                                        1153         {
1159           Rmax.push_back(corners[inextr].r);     1154           Rmax.push_back(corners[inextr].r);
1160           Rmin.push_back(corners[icurr].r);      1155           Rmin.push_back(corners[icurr].r);
1161         }                                        1156         }
1162         else                                     1157         else
1163         {                                        1158         {
1164           Rmin.push_back(corners[icurl].r + (    1159           Rmin.push_back(corners[icurl].r + (Zright-corners[icurl].z)/difZl
1165                                 * (corners[in    1160                                 * (corners[inextl].r - corners[icurl].r));
1166           Rmax.push_back(corners[inextr].r);     1161           Rmax.push_back(corners[inextr].r);
1167         }                                        1162         }
1168         ++icurr;                                 1163         ++icurr;
1169       }           // plate                       1164       }           // plate
1170       else if (difZr >= kCarTolerance)           1165       else if (difZr >= kCarTolerance)
1171       {                                          1166       {
1172         if(std::fabs(difZl) < kCarTolerance)     1167         if(std::fabs(difZl) < kCarTolerance)
1173         {                                        1168         {
1174           Rmax.push_back(corners[inextr].r);     1169           Rmax.push_back(corners[inextr].r);
1175           Rmin.push_back (corners[icurr].r);     1170           Rmin.push_back (corners[icurr].r);
1176         }                                        1171         }
1177         else                                     1172         else
1178         {                                        1173         {
1179           Rmax.push_back(corners[inextr].r);     1174           Rmax.push_back(corners[inextr].r);
1180           Rmin.push_back (corners[icurl].r+(Z    1175           Rmin.push_back (corners[icurl].r+(Zright-corners[icurl].z)/difZl
1181                                   * (corners[    1176                                   * (corners[inextl].r - corners[icurl].r));
1182         }                                        1177         }
1183         ++icurr;                                 1178         ++icurr;
1184       }                                          1179       }
1185       else                                       1180       else
1186       {                                          1181       {
1187         isConvertible=false; break;              1182         isConvertible=false; break;
1188       }                                          1183       }
1189     }                                            1184     }
1190   }   // end for loop                            1185   }   // end for loop
1191                                                  1186 
1192   // last plane Z=Zmax                           1187   // last plane Z=Zmax
1193   //                                             1188   //
1194   Z.push_back(Zmax);                             1189   Z.push_back(Zmax);
1195   ++countPlanes;                                 1190   ++countPlanes;
1196   inextr=1+icurr;                                1191   inextr=1+icurr;
1197   inextl=(icurl <= 0)? numPlanes-1 : icurl-1;    1192   inextl=(icurl <= 0)? numPlanes-1 : icurl-1;
1198                                                  1193 
1199   Rmax.push_back(corners[inextr].r);             1194   Rmax.push_back(corners[inextr].r);
1200   Rmin.push_back(corners[inextl].r);             1195   Rmin.push_back(corners[inextl].r);
1201                                                  1196 
1202   // Set original parameters Rmin,Rmax,Z         1197   // Set original parameters Rmin,Rmax,Z
1203   //                                             1198   //
1204   if(isConvertible)                              1199   if(isConvertible)
1205   {                                              1200   {
1206    original_parameters = new G4PolyhedraHisto    1201    original_parameters = new G4PolyhedraHistorical;
1207    original_parameters->numSide = numSide;       1202    original_parameters->numSide = numSide;
1208    original_parameters->Z_values = new G4doub    1203    original_parameters->Z_values = new G4double[countPlanes];
1209    original_parameters->Rmin = new G4double[c    1204    original_parameters->Rmin = new G4double[countPlanes];
1210    original_parameters->Rmax = new G4double[c    1205    original_parameters->Rmax = new G4double[countPlanes];
1211                                                  1206 
1212    for(G4int j=0; j < countPlanes; ++j)          1207    for(G4int j=0; j < countPlanes; ++j)
1213    {                                             1208    {
1214      original_parameters->Z_values[j] = Z[j];    1209      original_parameters->Z_values[j] = Z[j];
1215      original_parameters->Rmax[j] = Rmax[j];     1210      original_parameters->Rmax[j] = Rmax[j];
1216      original_parameters->Rmin[j] = Rmin[j];     1211      original_parameters->Rmin[j] = Rmin[j];
1217    }                                             1212    }
1218    original_parameters->Start_angle = startPh    1213    original_parameters->Start_angle = startPhi;
1219    original_parameters->Opening_angle = endPh    1214    original_parameters->Opening_angle = endPhi-startPhi;
1220    original_parameters->Num_z_planes = countP    1215    original_parameters->Num_z_planes = countPlanes;
1221                                                  1216 
1222   }                                              1217   }
1223   else  // Set parameters(r,z) with Rmin==0 a    1218   else  // Set parameters(r,z) with Rmin==0 as convention
1224   {                                              1219   {
1225 #ifdef G4SPECSDEBUG                              1220 #ifdef G4SPECSDEBUG
1226     std::ostringstream message;                  1221     std::ostringstream message;
1227     message << "Polyhedra " << GetName() << G    1222     message << "Polyhedra " << GetName() << G4endl
1228       << "cannot be converted to Polyhedra wi    1223       << "cannot be converted to Polyhedra with (Rmin,Rmaz,Z) parameters!";
1229     G4Exception("G4Polyhedra::SetOriginalPara    1224     G4Exception("G4Polyhedra::SetOriginalParameters()",
1230                 "GeomSolids0002", JustWarning    1225                 "GeomSolids0002", JustWarning, message);
1231 #endif                                           1226 #endif
1232     original_parameters = new G4PolyhedraHist    1227     original_parameters = new G4PolyhedraHistorical;
1233     original_parameters->numSide = numSide;      1228     original_parameters->numSide = numSide;
1234     original_parameters->Z_values = new G4dou    1229     original_parameters->Z_values = new G4double[numPlanes];
1235     original_parameters->Rmin = new G4double[    1230     original_parameters->Rmin = new G4double[numPlanes];
1236     original_parameters->Rmax = new G4double[    1231     original_parameters->Rmax = new G4double[numPlanes];
1237                                                  1232 
1238     for(G4int j=0; j < numPlanes; ++j)           1233     for(G4int j=0; j < numPlanes; ++j)
1239     {                                            1234     {
1240       original_parameters->Z_values[j] = corn    1235       original_parameters->Z_values[j] = corners[j].z;
1241       original_parameters->Rmax[j] = corners[    1236       original_parameters->Rmax[j] = corners[j].r;
1242       original_parameters->Rmin[j] = 0.0;        1237       original_parameters->Rmin[j] = 0.0;
1243     }                                            1238     }
1244     original_parameters->Start_angle = startP    1239     original_parameters->Start_angle = startPhi;
1245     original_parameters->Opening_angle = endP    1240     original_parameters->Opening_angle = endPhi-startPhi;
1246     original_parameters->Num_z_planes = numPl    1241     original_parameters->Num_z_planes = numPlanes;
1247   }                                              1242   }
1248 }                                                1243 }
1249                                                  1244 
1250 #endif                                           1245 #endif
1251                                                  1246