Geant4 Cross Reference

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


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
 26 // Implementation of G4UPolyhedra wrapper clas     26 // Implementation of G4UPolyhedra wrapper class
 27 //                                                 27 //
 28 // 31.10.13 G.Cosmo, CERN                          28 // 31.10.13 G.Cosmo, CERN
 29 // -------------------------------------------     29 // --------------------------------------------------------------------
 30                                                    30 
 31 #include "G4Polyhedra.hh"                          31 #include "G4Polyhedra.hh"
 32 #include "G4UPolyhedra.hh"                         32 #include "G4UPolyhedra.hh"
 33                                                    33 
 34 #if ( defined(G4GEOM_USE_USOLIDS) || defined(G     34 #if ( defined(G4GEOM_USE_USOLIDS) || defined(G4GEOM_USE_PARTIAL_USOLIDS) )
 35                                                    35 
 36 #include "G4GeomTools.hh"                          36 #include "G4GeomTools.hh"
 37 #include "G4GeometryTolerance.hh"                  37 #include "G4GeometryTolerance.hh"
 38 #include "G4AffineTransform.hh"                    38 #include "G4AffineTransform.hh"
 39 #include "G4VPVParameterisation.hh"                39 #include "G4VPVParameterisation.hh"
 40 #include "G4BoundingEnvelope.hh"                   40 #include "G4BoundingEnvelope.hh"
 41                                                    41 
 42 using namespace CLHEP;                             42 using namespace CLHEP;
 43                                                    43 
 44 //////////////////////////////////////////////     44 ////////////////////////////////////////////////////////////////////////
 45 //                                                 45 //
 46 // Constructor (GEANT3 style parameters)           46 // Constructor (GEANT3 style parameters)
 47 //                                                 47 //
 48 // GEANT3 PGON radii are specified in the dist     48 // GEANT3 PGON radii are specified in the distance to the norm of each face.
 49 //                                             <<  49 //  
 50 G4UPolyhedra::G4UPolyhedra(const G4String& nam <<  50 G4UPolyhedra::G4UPolyhedra(const G4String& name, 
 51                                  G4double phiS     51                                  G4double phiStart,
 52                                  G4double phiT     52                                  G4double phiTotal,
 53                                  G4int numSide <<  53                                  G4int numSide,  
 54                                  G4int numZPla     54                                  G4int numZPlanes,
 55                            const G4double zPla     55                            const G4double zPlane[],
 56                            const G4double rInn     56                            const G4double rInner[],
 57                            const G4double rOut     57                            const G4double rOuter[]  )
 58   : Base_t(name, phiStart, phiTotal, numSide,      58   : Base_t(name, phiStart, phiTotal, numSide,
 59            numZPlanes, zPlane, rInner, rOuter)     59            numZPlanes, zPlane, rInner, rOuter)
 60 {                                                  60 {
 61   fGenericPgon = false;                            61   fGenericPgon = false;
 62   SetOriginalParameters();                         62   SetOriginalParameters();
 63   wrStart = phiStart;                              63   wrStart = phiStart;
 64   while (wrStart < 0)                              64   while (wrStart < 0)
 65   {                                                65   {
 66     wrStart += twopi;                              66     wrStart += twopi;
 67   }                                                67   }
 68   wrDelta = phiTotal;                              68   wrDelta = phiTotal;
 69   if (wrDelta <= 0. || wrDelta >= twopi*(1-DBL     69   if (wrDelta <= 0. || wrDelta >= twopi*(1-DBL_EPSILON))
 70   {                                                70   {
 71     wrDelta = twopi;                               71     wrDelta = twopi;
 72   }                                                72   }
 73   wrNumSide = numSide;                             73   wrNumSide = numSide;
 74   G4double convertRad = 1./std::cos(0.5*wrDelt     74   G4double convertRad = 1./std::cos(0.5*wrDelta/wrNumSide);
 75   rzcorners.resize(0);                             75   rzcorners.resize(0);
 76   for (G4int i=0; i<numZPlanes; ++i)               76   for (G4int i=0; i<numZPlanes; ++i)
 77   {                                                77   {
 78     G4double z = zPlane[i];                        78     G4double z = zPlane[i];
 79     G4double r = rOuter[i]*convertRad;             79     G4double r = rOuter[i]*convertRad;
 80     rzcorners.emplace_back(r,z);               <<  80     rzcorners.push_back(G4TwoVector(r,z));
 81   }                                                81   }
 82   for (G4int i=numZPlanes-1; i>=0; --i)            82   for (G4int i=numZPlanes-1; i>=0; --i)
 83   {                                                83   {
 84     G4double z = zPlane[i];                        84     G4double z = zPlane[i];
 85     G4double r = rInner[i]*convertRad;             85     G4double r = rInner[i]*convertRad;
 86     rzcorners.emplace_back(r,z);               <<  86     rzcorners.push_back(G4TwoVector(r,z));
 87   }                                                87   }
 88   std::vector<G4int> iout;                         88   std::vector<G4int> iout;
 89   G4GeomTools::RemoveRedundantVertices(rzcorne     89   G4GeomTools::RemoveRedundantVertices(rzcorners,iout,2*kCarTolerance);
 90 }                                                  90 }
 91                                                    91 
 92                                                    92 
 93 //////////////////////////////////////////////     93 ////////////////////////////////////////////////////////////////////////
 94 //                                                 94 //
 95 // Constructor (generic parameters)                95 // Constructor (generic parameters)
 96 //                                                 96 //
 97 G4UPolyhedra::G4UPolyhedra(const G4String& nam <<  97 G4UPolyhedra::G4UPolyhedra(const G4String& name, 
 98                                  G4double phiS     98                                  G4double phiStart,
 99                                  G4double phiT     99                                  G4double phiTotal,
100                                  G4int    numS << 100                                  G4int    numSide,  
101                                  G4int    numR    101                                  G4int    numRZ,
102                            const G4double r[],    102                            const G4double r[],
103                            const G4double z[]     103                            const G4double z[]   )
104   : Base_t(name, phiStart, phiTotal, numSide,     104   : Base_t(name, phiStart, phiTotal, numSide, numRZ, r, z)
105 {                                                 105 {
106   fGenericPgon = true;                            106   fGenericPgon = true;
107   SetOriginalParameters();                        107   SetOriginalParameters();
108   wrStart = phiStart;                             108   wrStart = phiStart;
109   while (wrStart < 0.)                            109   while (wrStart < 0.)
110   {                                               110   {
111     wrStart += twopi;                             111     wrStart += twopi;
112   }                                               112   }
113   wrDelta = phiTotal;                             113   wrDelta = phiTotal;
114   if (wrDelta <= 0. || wrDelta >= twopi*(1-DBL    114   if (wrDelta <= 0. || wrDelta >= twopi*(1-DBL_EPSILON))
115   {                                               115   {
116     wrDelta = twopi;                              116     wrDelta = twopi;
117   }                                               117   }
118   wrNumSide = numSide;                            118   wrNumSide = numSide;
119   rzcorners.resize(0);                            119   rzcorners.resize(0);
120   for (G4int i=0; i<numRZ; ++i)                   120   for (G4int i=0; i<numRZ; ++i)
121   {                                               121   {
122     rzcorners.emplace_back(r[i],z[i]);         << 122     rzcorners.push_back(G4TwoVector(r[i],z[i]));
123   }                                               123   }
124   std::vector<G4int> iout;                        124   std::vector<G4int> iout;
125   G4GeomTools::RemoveRedundantVertices(rzcorne    125   G4GeomTools::RemoveRedundantVertices(rzcorners,iout,2*kCarTolerance);
126 }                                                 126 }
127                                                   127 
128                                                   128 
129 //////////////////////////////////////////////    129 ////////////////////////////////////////////////////////////////////////
130 //                                                130 //
131 // Fake default constructor - sets only member    131 // Fake default constructor - sets only member data and allocates memory
132 //                            for usage restri    132 //                            for usage restricted to object persistency.
133 //                                                133 //
134 G4UPolyhedra::G4UPolyhedra( __void__& a )         134 G4UPolyhedra::G4UPolyhedra( __void__& a )
135   : Base_t(a)                                     135   : Base_t(a)
136 {                                                 136 {
137 }                                                 137 }
138                                                   138 
139                                                   139 
140 //////////////////////////////////////////////    140 ////////////////////////////////////////////////////////////////////////
141 //                                                141 //
142 // Destructor                                     142 // Destructor
143 //                                                143 //
144 G4UPolyhedra::~G4UPolyhedra() = default;       << 144 G4UPolyhedra::~G4UPolyhedra()
                                                   >> 145 {
                                                   >> 146 }
145                                                   147 
146                                                   148 
147 //////////////////////////////////////////////    149 ////////////////////////////////////////////////////////////////////////
148 //                                                150 //
149 // Copy constructor                               151 // Copy constructor
150 //                                                152 //
151 G4UPolyhedra::G4UPolyhedra( const G4UPolyhedra    153 G4UPolyhedra::G4UPolyhedra( const G4UPolyhedra& source )
152   : Base_t( source )                              154   : Base_t( source )
153 {                                                 155 {
154   fGenericPgon = source.fGenericPgon;             156   fGenericPgon = source.fGenericPgon;
155   fOriginalParameters = source.fOriginalParame    157   fOriginalParameters = source.fOriginalParameters;
156   wrStart   = source.wrStart;                     158   wrStart   = source.wrStart;
157   wrDelta   = source.wrDelta;                     159   wrDelta   = source.wrDelta;
158   wrNumSide = source.wrNumSide;                   160   wrNumSide = source.wrNumSide;
159   rzcorners = source.rzcorners;                   161   rzcorners = source.rzcorners;
160 }                                                 162 }
161                                                   163 
162                                                   164 
163 //////////////////////////////////////////////    165 ////////////////////////////////////////////////////////////////////////
164 //                                                166 //
165 // Assignment operator                            167 // Assignment operator
166 //                                                168 //
167 G4UPolyhedra& G4UPolyhedra::operator=( const G    169 G4UPolyhedra& G4UPolyhedra::operator=( const G4UPolyhedra& source )
168 {                                                 170 {
169   if (this == &source) return *this;              171   if (this == &source) return *this;
170                                                   172 
171   Base_t::operator=( source );                    173   Base_t::operator=( source );
172   fGenericPgon = source.fGenericPgon;             174   fGenericPgon = source.fGenericPgon;
173   fOriginalParameters = source.fOriginalParame    175   fOriginalParameters = source.fOriginalParameters;
174   wrStart   = source.wrStart;                     176   wrStart   = source.wrStart;
175   wrDelta   = source.wrDelta;                     177   wrDelta   = source.wrDelta;
176   wrNumSide = source.wrNumSide;                   178   wrNumSide = source.wrNumSide;
177   rzcorners = source.rzcorners;                   179   rzcorners = source.rzcorners;
178                                                   180 
179   return *this;                                   181   return *this;
180 }                                                 182 }
181                                                   183 
182                                                   184 
183 //////////////////////////////////////////////    185 ////////////////////////////////////////////////////////////////////////
184 //                                                186 //
185 // Accessors & modifiers                          187 // Accessors & modifiers
186 //                                                188 //
187 G4int G4UPolyhedra::GetNumSide() const            189 G4int G4UPolyhedra::GetNumSide() const
188 {                                                 190 {
189   return wrNumSide;                               191   return wrNumSide;
190 }                                                 192 }
191 G4double G4UPolyhedra::GetStartPhi() const        193 G4double G4UPolyhedra::GetStartPhi() const
192 {                                                 194 {
193   return wrStart;                                 195   return wrStart;
194 }                                                 196 }
195 G4double G4UPolyhedra::GetEndPhi() const          197 G4double G4UPolyhedra::GetEndPhi() const
196 {                                                 198 {
197   return (wrStart + wrDelta);                     199   return (wrStart + wrDelta);
198 }                                                 200 }
199 G4double G4UPolyhedra::GetSinStartPhi() const     201 G4double G4UPolyhedra::GetSinStartPhi() const
200 {                                                 202 {
201   G4double phi = GetStartPhi();                   203   G4double phi = GetStartPhi();
202   return std::sin(phi);                           204   return std::sin(phi);
203 }                                                 205 }
204 G4double G4UPolyhedra::GetCosStartPhi() const     206 G4double G4UPolyhedra::GetCosStartPhi() const
205 {                                                 207 {
206   G4double phi = GetStartPhi();                   208   G4double phi = GetStartPhi();
207   return std::cos(phi);                           209   return std::cos(phi);
208 }                                                 210 }
209 G4double G4UPolyhedra::GetSinEndPhi() const       211 G4double G4UPolyhedra::GetSinEndPhi() const
210 {                                                 212 {
211   G4double phi = GetEndPhi();                     213   G4double phi = GetEndPhi();
212   return std::sin(phi);                           214   return std::sin(phi);
213 }                                                 215 }
214 G4double G4UPolyhedra::GetCosEndPhi() const       216 G4double G4UPolyhedra::GetCosEndPhi() const
215 {                                                 217 {
216   G4double phi = GetEndPhi();                     218   G4double phi = GetEndPhi();
217   return std::cos(phi);                           219   return std::cos(phi);
218 }                                                 220 }
219 G4bool G4UPolyhedra::IsOpen() const               221 G4bool G4UPolyhedra::IsOpen() const
220 {                                                 222 {
221   return (wrDelta < twopi);                       223   return (wrDelta < twopi);
222 }                                                 224 }
223 G4bool G4UPolyhedra::IsGeneric() const            225 G4bool G4UPolyhedra::IsGeneric() const
224 {                                                 226 {
225   return fGenericPgon;                            227   return fGenericPgon;
226 }                                                 228 }
227 G4int G4UPolyhedra::GetNumRZCorner() const        229 G4int G4UPolyhedra::GetNumRZCorner() const
228 {                                                 230 {
229   return rzcorners.size();                        231   return rzcorners.size();
230 }                                                 232 }
231 G4PolyhedraSideRZ G4UPolyhedra::GetCorner(G4in    233 G4PolyhedraSideRZ G4UPolyhedra::GetCorner(G4int index) const
232 {                                                 234 {
233   G4TwoVector rz = rzcorners.at(index);           235   G4TwoVector rz = rzcorners.at(index);
234   G4PolyhedraSideRZ psiderz = { rz.x(), rz.y()    236   G4PolyhedraSideRZ psiderz = { rz.x(), rz.y() };
235                                                   237 
236   return psiderz;                                 238   return psiderz;
237 }                                                 239 }
238 G4PolyhedraHistorical* G4UPolyhedra::GetOrigin    240 G4PolyhedraHistorical* G4UPolyhedra::GetOriginalParameters() const
239 {                                                 241 {
240   return new G4PolyhedraHistorical(fOriginalPa    242   return new G4PolyhedraHistorical(fOriginalParameters);
241 }                                                 243 }
242 void G4UPolyhedra::SetOriginalParameters()        244 void G4UPolyhedra::SetOriginalParameters()
243 {                                                 245 {
244   G4double startPhi = GetPhiStart();              246   G4double startPhi = GetPhiStart();
245   G4double deltaPhi = GetPhiDelta();              247   G4double deltaPhi = GetPhiDelta();
246   G4int numPlanes   = GetZSegmentCount() + 1;     248   G4int numPlanes   = GetZSegmentCount() + 1;
247   G4int numSides    = GetSideCount();             249   G4int numSides    = GetSideCount();
248                                                   250 
249   fOriginalParameters.Start_angle   = startPhi    251   fOriginalParameters.Start_angle   = startPhi;
250   fOriginalParameters.Opening_angle = deltaPhi    252   fOriginalParameters.Opening_angle = deltaPhi;
251   fOriginalParameters.Num_z_planes  = numPlane    253   fOriginalParameters.Num_z_planes  = numPlanes;
252   fOriginalParameters.numSide       = numSides    254   fOriginalParameters.numSide       = numSides;
253                                                   255 
254   delete [] fOriginalParameters.Z_values;         256   delete [] fOriginalParameters.Z_values;
255   delete [] fOriginalParameters.Rmin;             257   delete [] fOriginalParameters.Rmin;
256   delete [] fOriginalParameters.Rmax;             258   delete [] fOriginalParameters.Rmax;
257   fOriginalParameters.Z_values = new G4double[    259   fOriginalParameters.Z_values = new G4double[numPlanes];
258   fOriginalParameters.Rmin = new G4double[numP    260   fOriginalParameters.Rmin = new G4double[numPlanes];
259   fOriginalParameters.Rmax = new G4double[numP    261   fOriginalParameters.Rmax = new G4double[numPlanes];
260                                                   262 
261   G4double convertRad = fGenericPgon              263   G4double convertRad = fGenericPgon
262                       ? 1.0 : std::cos(0.5*del    264                       ? 1.0 : std::cos(0.5*deltaPhi/numSides);
263   for (G4int i=0; i<numPlanes; ++i)               265   for (G4int i=0; i<numPlanes; ++i)
264   {                                               266   {
265     fOriginalParameters.Z_values[i] = GetZPlan    267     fOriginalParameters.Z_values[i] = GetZPlanes()[i];
266     fOriginalParameters.Rmax[i]     = GetRMax(    268     fOriginalParameters.Rmax[i]     = GetRMax()[i]/convertRad;
267     fOriginalParameters.Rmin[i]     = GetRMin(    269     fOriginalParameters.Rmin[i]     = GetRMin()[i]/convertRad;
268   }                                               270   }
269 }                                                 271 }
270 void G4UPolyhedra::SetOriginalParameters(G4Pol    272 void G4UPolyhedra::SetOriginalParameters(G4PolyhedraHistorical* pars)
271 {                                                 273 {
272   fOriginalParameters = *pars;                    274   fOriginalParameters = *pars;
273   fRebuildPolyhedron = true;                      275   fRebuildPolyhedron = true;
274   Reset();                                        276   Reset();
275 }                                                 277 }
276                                                   278 
277 G4bool G4UPolyhedra::Reset()                      279 G4bool G4UPolyhedra::Reset()
278 {                                                 280 {
279   if (fGenericPgon)                               281   if (fGenericPgon)
280   {                                               282   {
281     std::ostringstream message;                   283     std::ostringstream message;
282     message << "Solid " << GetName() << " buil    284     message << "Solid " << GetName() << " built using generic construct."
283             << G4endl << "Not applicable to th    285             << G4endl << "Not applicable to the generic construct !";
284     G4Exception("G4UPolyhedra::Reset()", "Geom    286     G4Exception("G4UPolyhedra::Reset()", "GeomSolids1001",
285                 JustWarning, message, "Paramet    287                 JustWarning, message, "Parameters NOT reset.");
286     return true;  // error code set               288     return true;  // error code set
287   }                                               289   }
288                                                   290 
289   //                                              291   //
290   // Rebuild polyhedra based on original param    292   // Rebuild polyhedra based on original parameters
291   //                                              293   //
292   wrStart = fOriginalParameters.Start_angle;      294   wrStart = fOriginalParameters.Start_angle;
293   while (wrStart < 0.)                            295   while (wrStart < 0.)
294   {                                               296   {
295     wrStart += twopi;                             297     wrStart += twopi;
296   }                                               298   }
297   wrDelta = fOriginalParameters.Opening_angle;    299   wrDelta = fOriginalParameters.Opening_angle;
298   if (wrDelta <= 0. || wrDelta >= twopi*(1-DBL    300   if (wrDelta <= 0. || wrDelta >= twopi*(1-DBL_EPSILON))
299   {                                               301   {
300     wrDelta = twopi;                              302     wrDelta = twopi;
301   }                                               303   }
302   wrNumSide = fOriginalParameters.numSide;        304   wrNumSide = fOriginalParameters.numSide;
303   rzcorners.resize(0);                            305   rzcorners.resize(0);
304   for (G4int i=0; i<fOriginalParameters.Num_z_    306   for (G4int i=0; i<fOriginalParameters.Num_z_planes; ++i)
305   {                                               307   {
306     G4double z = fOriginalParameters.Z_values[    308     G4double z = fOriginalParameters.Z_values[i];
307     G4double r = fOriginalParameters.Rmax[i];     309     G4double r = fOriginalParameters.Rmax[i];
308     rzcorners.emplace_back(r,z);               << 310     rzcorners.push_back(G4TwoVector(r,z));
309   }                                               311   }
310   for (G4int i=fOriginalParameters.Num_z_plane    312   for (G4int i=fOriginalParameters.Num_z_planes-1; i>=0; --i)
311   {                                               313   {
312     G4double z = fOriginalParameters.Z_values[    314     G4double z = fOriginalParameters.Z_values[i];
313     G4double r = fOriginalParameters.Rmin[i];     315     G4double r = fOriginalParameters.Rmin[i];
314     rzcorners.emplace_back(r,z);               << 316     rzcorners.push_back(G4TwoVector(r,z));
315   }                                               317   }
316   std::vector<G4int> iout;                        318   std::vector<G4int> iout;
317   G4GeomTools::RemoveRedundantVertices(rzcorne    319   G4GeomTools::RemoveRedundantVertices(rzcorners,iout,2*kCarTolerance);
318                                                   320 
319   return false;  // error code unset              321   return false;  // error code unset
320 }                                                 322 }
321                                                   323 
322                                                   324 
323 //////////////////////////////////////////////    325 ////////////////////////////////////////////////////////////////////////
324 //                                                326 //
325 // Dispatch to parameterisation for replicatio    327 // Dispatch to parameterisation for replication mechanism dimension
326 // computation & modification.                    328 // computation & modification.
327 //                                                329 //
328 void G4UPolyhedra::ComputeDimensions(G4VPVPara    330 void G4UPolyhedra::ComputeDimensions(G4VPVParameterisation* p,
329                                      const G4i    331                                      const G4int n,
330                                      const G4V    332                                      const G4VPhysicalVolume* pRep)
331 {                                                 333 {
332   p->ComputeDimensions(*(G4Polyhedra*)this,n,p    334   p->ComputeDimensions(*(G4Polyhedra*)this,n,pRep);
333 }                                                 335 }
334                                                   336 
335                                                   337 
336 //////////////////////////////////////////////    338 //////////////////////////////////////////////////////////////////////////
337 //                                                339 //
338 // Make a clone of the object                     340 // Make a clone of the object
339                                                   341 
340 G4VSolid* G4UPolyhedra::Clone() const             342 G4VSolid* G4UPolyhedra::Clone() const
341 {                                                 343 {
342   return new G4UPolyhedra(*this);                 344   return new G4UPolyhedra(*this);
343 }                                                 345 }
344                                                   346 
345                                                   347 
346 //////////////////////////////////////////////    348 //////////////////////////////////////////////////////////////////////////
347 //                                                349 //
348 // Get bounding box                               350 // Get bounding box
349                                                   351 
350 void G4UPolyhedra::BoundingLimits(G4ThreeVecto    352 void G4UPolyhedra::BoundingLimits(G4ThreeVector& pMin,
351                                   G4ThreeVecto    353                                   G4ThreeVector& pMax) const
352 {                                                 354 {
353   static G4bool checkBBox = true;                 355   static G4bool checkBBox = true;
354   static G4bool checkPhi  = true;                 356   static G4bool checkPhi  = true;
355                                                   357 
356   G4double rmin = kInfinity, rmax = -kInfinity    358   G4double rmin = kInfinity, rmax = -kInfinity;
357   G4double zmin = kInfinity, zmax = -kInfinity    359   G4double zmin = kInfinity, zmax = -kInfinity;
358   for (G4int i=0; i<GetNumRZCorner(); ++i)        360   for (G4int i=0; i<GetNumRZCorner(); ++i)
359   {                                               361   {
360     G4PolyhedraSideRZ corner = GetCorner(i);      362     G4PolyhedraSideRZ corner = GetCorner(i);
361     if (corner.r < rmin) rmin = corner.r;         363     if (corner.r < rmin) rmin = corner.r;
362     if (corner.r > rmax) rmax = corner.r;         364     if (corner.r > rmax) rmax = corner.r;
363     if (corner.z < zmin) zmin = corner.z;         365     if (corner.z < zmin) zmin = corner.z;
364     if (corner.z > zmax) zmax = corner.z;         366     if (corner.z > zmax) zmax = corner.z;
365   }                                               367   }
366                                                   368 
367   G4double sphi    = GetStartPhi();               369   G4double sphi    = GetStartPhi();
368   G4double ephi    = GetEndPhi();                 370   G4double ephi    = GetEndPhi();
369   G4double dphi    = IsOpen() ? ephi-sphi : tw    371   G4double dphi    = IsOpen() ? ephi-sphi : twopi;
370   G4int    ksteps  = GetNumSide();                372   G4int    ksteps  = GetNumSide();
371   G4double astep   = dphi/ksteps;                 373   G4double astep   = dphi/ksteps;
372   G4double sinStep = std::sin(astep);             374   G4double sinStep = std::sin(astep);
373   G4double cosStep = std::cos(astep);             375   G4double cosStep = std::cos(astep);
374                                                   376 
375   G4double sinCur = GetSinStartPhi();             377   G4double sinCur = GetSinStartPhi();
376   G4double cosCur = GetCosStartPhi();             378   G4double cosCur = GetCosStartPhi();
377   if (!IsOpen()) rmin = 0.;                       379   if (!IsOpen()) rmin = 0.;
378   G4double xmin = rmin*cosCur, xmax = xmin;       380   G4double xmin = rmin*cosCur, xmax = xmin;
379   G4double ymin = rmin*sinCur, ymax = ymin;       381   G4double ymin = rmin*sinCur, ymax = ymin;
380   for (G4int k=0; k<ksteps+1; ++k)                382   for (G4int k=0; k<ksteps+1; ++k)
381   {                                               383   {
382     G4double x = rmax*cosCur;                     384     G4double x = rmax*cosCur;
383     if (x < xmin) xmin = x;                       385     if (x < xmin) xmin = x;
384     if (x > xmax) xmax = x;                       386     if (x > xmax) xmax = x;
385     G4double y = rmax*sinCur;                     387     G4double y = rmax*sinCur;
386     if (y < ymin) ymin = y;                       388     if (y < ymin) ymin = y;
387     if (y > ymax) ymax = y;                       389     if (y > ymax) ymax = y;
388     if (rmin > 0.)                                390     if (rmin > 0.)
389     {                                             391     {
390       G4double xx = rmin*cosCur;                  392       G4double xx = rmin*cosCur;
391       if (xx < xmin) xmin = xx;                   393       if (xx < xmin) xmin = xx;
392       if (xx > xmax) xmax = xx;                   394       if (xx > xmax) xmax = xx;
393       G4double yy = rmin*sinCur;                  395       G4double yy = rmin*sinCur;
394       if (yy < ymin) ymin = yy;                   396       if (yy < ymin) ymin = yy;
395       if (yy > ymax) ymax = yy;                   397       if (yy > ymax) ymax = yy;
396     }                                             398     }
397     G4double sinTmp = sinCur;                     399     G4double sinTmp = sinCur;
398     sinCur = sinCur*cosStep + cosCur*sinStep;     400     sinCur = sinCur*cosStep + cosCur*sinStep;
399     cosCur = cosCur*cosStep - sinTmp*sinStep;     401     cosCur = cosCur*cosStep - sinTmp*sinStep;
400   }                                               402   }
401   pMin.set(xmin,ymin,zmin);                       403   pMin.set(xmin,ymin,zmin);
402   pMax.set(xmax,ymax,zmax);                       404   pMax.set(xmax,ymax,zmax);
403                                                   405 
404   // Check correctness of the bounding box        406   // Check correctness of the bounding box
405   //                                              407   //
406   if (pMin.x() >= pMax.x() || pMin.y() >= pMax    408   if (pMin.x() >= pMax.x() || pMin.y() >= pMax.y() || pMin.z() >= pMax.z())
407   {                                               409   {
408     std::ostringstream message;                   410     std::ostringstream message;
409     message << "Bad bounding box (min >= max)     411     message << "Bad bounding box (min >= max) for solid: "
410             << GetName() << " !"                  412             << GetName() << " !"
411             << "\npMin = " << pMin                413             << "\npMin = " << pMin
412             << "\npMax = " << pMax;               414             << "\npMax = " << pMax;
413     G4Exception("G4UPolyhedra::BoundingLimits(    415     G4Exception("G4UPolyhedra::BoundingLimits()", "GeomMgt0001",
414                 JustWarning, message);            416                 JustWarning, message);
415     StreamInfo(G4cout);                           417     StreamInfo(G4cout);
416   }                                               418   }
417                                                   419 
418   // Check consistency of bounding boxes          420   // Check consistency of bounding boxes
419   //                                              421   //
420   if (checkBBox)                                  422   if (checkBBox)
421   {                                               423   {
422     U3Vector vmin, vmax;                          424     U3Vector vmin, vmax;
423     Extent(vmin,vmax);                            425     Extent(vmin,vmax);
424     if (std::abs(pMin.x()-vmin.x()) > kCarTole    426     if (std::abs(pMin.x()-vmin.x()) > kCarTolerance ||
425         std::abs(pMin.y()-vmin.y()) > kCarTole    427         std::abs(pMin.y()-vmin.y()) > kCarTolerance ||
426         std::abs(pMin.z()-vmin.z()) > kCarTole    428         std::abs(pMin.z()-vmin.z()) > kCarTolerance ||
427         std::abs(pMax.x()-vmax.x()) > kCarTole    429         std::abs(pMax.x()-vmax.x()) > kCarTolerance ||
428         std::abs(pMax.y()-vmax.y()) > kCarTole    430         std::abs(pMax.y()-vmax.y()) > kCarTolerance ||
429         std::abs(pMax.z()-vmax.z()) > kCarTole    431         std::abs(pMax.z()-vmax.z()) > kCarTolerance)
430     {                                             432     {
431       std::ostringstream message;                 433       std::ostringstream message;
432       message << "Inconsistency in bounding bo    434       message << "Inconsistency in bounding boxes for solid: "
433               << GetName() << " !"                435               << GetName() << " !"
434               << "\nBBox min: wrapper = " << p    436               << "\nBBox min: wrapper = " << pMin << " solid = " << vmin
435               << "\nBBox max: wrapper = " << p    437               << "\nBBox max: wrapper = " << pMax << " solid = " << vmax;
436       G4Exception("G4UPolyhedra::BoundingLimit    438       G4Exception("G4UPolyhedra::BoundingLimits()", "GeomMgt0001",
437                   JustWarning, message);          439                   JustWarning, message);
438       checkBBox = false;                          440       checkBBox = false;
439     }                                             441     }
440   }                                               442   }
441                                                   443 
442   // Check consistency of angles                  444   // Check consistency of angles
443   //                                              445   //
444   if (checkPhi)                                   446   if (checkPhi)
445   {                                               447   {
446     if (GetStartPhi() != GetPhiStart()  ||     << 448     if (GetStartPhi() != GetPhiStart() ||
447         GetEndPhi()   != GetPhiEnd()    ||     << 449   GetEndPhi()   != GetPhiEnd()   ||
448         GetNumSide()  != GetSideCount() ||     << 450   GetNumSide()  != GetSideCount() ||
449         IsOpen()      != (Base_t::GetPhiDelta(    451         IsOpen()      != (Base_t::GetPhiDelta() < twopi))
450     {                                             452     {
451       std::ostringstream message;                 453       std::ostringstream message;
452       message << "Inconsistency in Phi angles     454       message << "Inconsistency in Phi angles or # of sides for solid: "
453               << GetName() << " !"                455               << GetName() << " !"
454               << "\nPhi start  : wrapper = " <    456               << "\nPhi start  : wrapper = " << GetStartPhi()
455               << " solid = " <<     GetPhiStar    457               << " solid = " <<     GetPhiStart()
456               << "\nPhi end    : wrapper = " <    458               << "\nPhi end    : wrapper = " << GetEndPhi()
457               << " solid = " <<     GetPhiEnd(    459               << " solid = " <<     GetPhiEnd()
458               << "\nPhi # sides: wrapper = " <    460               << "\nPhi # sides: wrapper = " << GetNumSide()
459               << " solid = " <<     GetSideCou    461               << " solid = " <<     GetSideCount()
460               << "\nPhi is open: wrapper = " <    462               << "\nPhi is open: wrapper = " << (IsOpen() ? "true" : "false")
461               << " solid = "                      463               << " solid = "
462               << ((Base_t::GetPhiDelta() < two    464               << ((Base_t::GetPhiDelta() < twopi) ? "true" : "false");
463       G4Exception("G4UPolyhedra::BoundingLimit    465       G4Exception("G4UPolyhedra::BoundingLimits()", "GeomMgt0001",
464                   JustWarning, message);          466                   JustWarning, message);
465       checkPhi = false;                           467       checkPhi = false;
466     }                                             468     }
467   }                                               469   }
468 }                                                 470 }
469                                                   471 
470 //////////////////////////////////////////////    472 //////////////////////////////////////////////////////////////////////////
471 //                                                473 //
472 // Calculate extent under transform and specif    474 // Calculate extent under transform and specified limit
473                                                   475 
474 G4bool                                            476 G4bool
475 G4UPolyhedra::CalculateExtent(const EAxis pAxi    477 G4UPolyhedra::CalculateExtent(const EAxis pAxis,
476                               const G4VoxelLim    478                               const G4VoxelLimits& pVoxelLimit,
477                               const G4AffineTr    479                               const G4AffineTransform& pTransform,
478                                     G4double&     480                                     G4double& pMin, G4double& pMax) const
479 {                                                 481 {
480   G4ThreeVector bmin, bmax;                       482   G4ThreeVector bmin, bmax;
481   G4bool exist;                                   483   G4bool exist;
482                                                   484 
483   // Check bounding box (bbox)                    485   // Check bounding box (bbox)
484   //                                              486   //
485   BoundingLimits(bmin,bmax);                      487   BoundingLimits(bmin,bmax);
486   G4BoundingEnvelope bbox(bmin,bmax);             488   G4BoundingEnvelope bbox(bmin,bmax);
487 #ifdef G4BBOX_EXTENT                              489 #ifdef G4BBOX_EXTENT
488   if (true) return bbox.CalculateExtent(pAxis,    490   if (true) return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
489 #endif                                            491 #endif
490   if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVox    492   if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVoxelLimit,pTransform,pMin,pMax))
491   {                                               493   {
492     return exist = pMin < pMax;                << 494     return exist = (pMin < pMax) ? true : false;
493   }                                               495   }
494                                                   496 
495   // To find the extent, RZ contour of the pol    497   // To find the extent, RZ contour of the polycone is subdivided
496   // in triangles. The extent is calculated as    498   // in triangles. The extent is calculated as cumulative extent of
497   // all sub-polycones formed by rotation of t    499   // all sub-polycones formed by rotation of triangles around Z
498   //                                              500   //
499   G4TwoVectorList contourRZ;                      501   G4TwoVectorList contourRZ;
500   G4TwoVectorList triangles;                      502   G4TwoVectorList triangles;
501   std::vector<G4int> iout;                        503   std::vector<G4int> iout;
502   G4double eminlim = pVoxelLimit.GetMinExtent(    504   G4double eminlim = pVoxelLimit.GetMinExtent(pAxis);
503   G4double emaxlim = pVoxelLimit.GetMaxExtent(    505   G4double emaxlim = pVoxelLimit.GetMaxExtent(pAxis);
504                                                   506 
505   // get RZ contour, ensure anticlockwise orde    507   // get RZ contour, ensure anticlockwise order of corners
506   for (G4int i=0; i<GetNumRZCorner(); ++i)        508   for (G4int i=0; i<GetNumRZCorner(); ++i)
507   {                                               509   {
508     G4PolyhedraSideRZ corner = GetCorner(i);      510     G4PolyhedraSideRZ corner = GetCorner(i);
509     contourRZ.emplace_back(corner.r,corner.z); << 511     contourRZ.push_back(G4TwoVector(corner.r,corner.z));
510   }                                               512   }
511   G4GeomTools::RemoveRedundantVertices(contour    513   G4GeomTools::RemoveRedundantVertices(contourRZ,iout,2*kCarTolerance);
512   G4double area = G4GeomTools::PolygonArea(con    514   G4double area = G4GeomTools::PolygonArea(contourRZ);
513   if (area < 0.) std::reverse(contourRZ.begin(    515   if (area < 0.) std::reverse(contourRZ.begin(),contourRZ.end());
514                                                   516 
515   // triangulate RZ countour                      517   // triangulate RZ countour
516   if (!G4GeomTools::TriangulatePolygon(contour    518   if (!G4GeomTools::TriangulatePolygon(contourRZ,triangles))
517   {                                               519   {
518     std::ostringstream message;                   520     std::ostringstream message;
519     message << "Triangulation of RZ contour ha    521     message << "Triangulation of RZ contour has failed for solid: "
520             << GetName() << " !"                  522             << GetName() << " !"
521             << "\nExtent has been calculated u    523             << "\nExtent has been calculated using boundary box";
522     G4Exception("G4UPolyhedra::CalculateExtent    524     G4Exception("G4UPolyhedra::CalculateExtent()",
523                 "GeomMgt1002",JustWarning,mess    525                 "GeomMgt1002",JustWarning,message);
524     return bbox.CalculateExtent(pAxis,pVoxelLi    526     return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
525   }                                               527   }
526                                                   528 
527   // set trigonometric values                     529   // set trigonometric values
528   G4double sphi     = GetStartPhi();              530   G4double sphi     = GetStartPhi();
529   G4double ephi     = GetEndPhi();                531   G4double ephi     = GetEndPhi();
530   G4double dphi     = IsOpen() ? ephi-sphi : t    532   G4double dphi     = IsOpen() ? ephi-sphi : twopi;
531   G4int    ksteps   = GetNumSide();               533   G4int    ksteps   = GetNumSide();
532   G4double astep    = dphi/ksteps;                534   G4double astep    = dphi/ksteps;
533   G4double sinStep  = std::sin(astep);            535   G4double sinStep  = std::sin(astep);
534   G4double cosStep  = std::cos(astep);            536   G4double cosStep  = std::cos(astep);
535   G4double sinStart = GetSinStartPhi();           537   G4double sinStart = GetSinStartPhi();
536   G4double cosStart = GetCosStartPhi();           538   G4double cosStart = GetCosStartPhi();
537                                                   539 
538   // allocate vector lists                        540   // allocate vector lists
539   std::vector<const G4ThreeVectorList *> polyg    541   std::vector<const G4ThreeVectorList *> polygons;
540   polygons.resize(ksteps+1);                      542   polygons.resize(ksteps+1);
541   for (G4int k=0; k<ksteps+1; ++k)                543   for (G4int k=0; k<ksteps+1; ++k)
542   {                                               544   {
543     polygons[k] = new G4ThreeVectorList(3);       545     polygons[k] = new G4ThreeVectorList(3);
544   }                                               546   }
545                                                   547 
546   // main loop along triangles                    548   // main loop along triangles
547   pMin =  kInfinity;                              549   pMin =  kInfinity;
548   pMax = -kInfinity;                              550   pMax = -kInfinity;
549   G4int ntria = triangles.size()/3;               551   G4int ntria = triangles.size()/3;
550   for (G4int i=0; i<ntria; ++i)                   552   for (G4int i=0; i<ntria; ++i)
551   {                                               553   {
552     G4double sinCur = sinStart;                   554     G4double sinCur = sinStart;
553     G4double cosCur = cosStart;                   555     G4double cosCur = cosStart;
554     G4int i3 = i*3;                               556     G4int i3 = i*3;
555     for (G4int k=0; k<ksteps+1; ++k) // rotate    557     for (G4int k=0; k<ksteps+1; ++k) // rotate triangle
556     {                                             558     {
557       auto ptr = const_cast<G4ThreeVectorList* << 559       G4ThreeVectorList* ptr = const_cast<G4ThreeVectorList*>(polygons[k]);
558       auto iter = ptr->begin();                << 560       G4ThreeVectorList::iterator iter = ptr->begin();
559       iter->set(triangles[i3+0].x()*cosCur,       561       iter->set(triangles[i3+0].x()*cosCur,
560                 triangles[i3+0].x()*sinCur,       562                 triangles[i3+0].x()*sinCur,
561                 triangles[i3+0].y());             563                 triangles[i3+0].y());
562       iter++;                                     564       iter++;
563       iter->set(triangles[i3+1].x()*cosCur,       565       iter->set(triangles[i3+1].x()*cosCur,
564                 triangles[i3+1].x()*sinCur,       566                 triangles[i3+1].x()*sinCur,
565                 triangles[i3+1].y());             567                 triangles[i3+1].y());
566       iter++;                                     568       iter++;
567       iter->set(triangles[i3+2].x()*cosCur,       569       iter->set(triangles[i3+2].x()*cosCur,
568                 triangles[i3+2].x()*sinCur,       570                 triangles[i3+2].x()*sinCur,
569                 triangles[i3+2].y());             571                 triangles[i3+2].y());
570                                                   572 
571       G4double sinTmp = sinCur;                   573       G4double sinTmp = sinCur;
572       sinCur = sinCur*cosStep + cosCur*sinStep    574       sinCur = sinCur*cosStep + cosCur*sinStep;
573       cosCur = cosCur*cosStep - sinTmp*sinStep    575       cosCur = cosCur*cosStep - sinTmp*sinStep;
574     }                                             576     }
575                                                   577 
576     // set sub-envelope and adjust extent         578     // set sub-envelope and adjust extent
577     G4double emin,emax;                           579     G4double emin,emax;
578     G4BoundingEnvelope benv(polygons);            580     G4BoundingEnvelope benv(polygons);
579     if (!benv.CalculateExtent(pAxis,pVoxelLimi    581     if (!benv.CalculateExtent(pAxis,pVoxelLimit,pTransform,emin,emax)) continue;
580     if (emin < pMin) pMin = emin;                 582     if (emin < pMin) pMin = emin;
581     if (emax > pMax) pMax = emax;                 583     if (emax > pMax) pMax = emax;
582     if (eminlim > pMin && emaxlim < pMax) brea    584     if (eminlim > pMin && emaxlim < pMax) break; // max possible extent
583   }                                               585   }
584   // free memory                                  586   // free memory
585   for (G4int k=0; k<ksteps+1; ++k) { delete po << 587   for (G4int k=0; k<ksteps+1; ++k) { delete polygons[k]; polygons[k]=0;}
586   return (pMin < pMax);                           588   return (pMin < pMax);
587 }                                                 589 }
588                                                   590 
589                                                   591 
590 //////////////////////////////////////////////    592 ////////////////////////////////////////////////////////////////////////
591 //                                                593 //
592 // CreatePolyhedron                               594 // CreatePolyhedron
593 //                                                595 //
594 G4Polyhedron* G4UPolyhedra::CreatePolyhedron()    596 G4Polyhedron* G4UPolyhedra::CreatePolyhedron() const
595 {                                                 597 {
596   return new G4PolyhedronPgon(wrStart, wrDelta << 598   if (!IsGeneric())
                                                   >> 599   {
                                                   >> 600     return new G4PolyhedronPgon( fOriginalParameters.Start_angle,
                                                   >> 601                                  fOriginalParameters.Opening_angle,
                                                   >> 602                                  fOriginalParameters.numSide,
                                                   >> 603                                  fOriginalParameters.Num_z_planes,
                                                   >> 604                                  fOriginalParameters.Z_values,
                                                   >> 605                                  fOriginalParameters.Rmin,
                                                   >> 606                                  fOriginalParameters.Rmax);
                                                   >> 607   }
                                                   >> 608   else
                                                   >> 609   {
                                                   >> 610     // The following code prepares for:
                                                   >> 611     // HepPolyhedron::createPolyhedron(int Nnodes, int Nfaces,
                                                   >> 612     //                                 const double xyz[][3],
                                                   >> 613     //                                 const int faces_vec[][4])
                                                   >> 614     // Here is an extract from the header file HepPolyhedron.h:
                                                   >> 615     /**
                                                   >> 616      * Creates user defined polyhedron.
                                                   >> 617      * This function allows the user to define arbitrary polyhedron.
                                                   >> 618      * The faces of the polyhedron should be either triangles or planar
                                                   >> 619      * quadrilateral. Nodes of a face are defined by indexes pointing to
                                                   >> 620      * the elements in the xyz array. Numeration of the elements in the
                                                   >> 621      * array starts from 1 (like in fortran). The indexes can be positive
                                                   >> 622      * or negative. Negative sign means that the corresponding edge is
                                                   >> 623      * invisible. The normal of the face should be directed to exterior
                                                   >> 624      * of the polyhedron. 
                                                   >> 625      * 
                                                   >> 626      * @param  Nnodes number of nodes
                                                   >> 627      * @param  Nfaces number of faces
                                                   >> 628      * @param  xyz    nodes
                                                   >> 629      * @param  faces_vec  faces (quadrilaterals or triangles)
                                                   >> 630      * @return status of the operation - is non-zero in case of problem
                                                   >> 631      */
                                                   >> 632     G4int nNodes;
                                                   >> 633     G4int nFaces;
                                                   >> 634     typedef G4double double3[3];
                                                   >> 635     double3* xyz;
                                                   >> 636     typedef G4int int4[4];
                                                   >> 637     int4* faces_vec;
                                                   >> 638     if (IsOpen())
                                                   >> 639     {
                                                   >> 640       // Triangulate open ends.  Simple ear-chopping algorithm...
                                                   >> 641       // I'm not sure how robust this algorithm is (J.Allison).
                                                   >> 642       //
                                                   >> 643       std::vector<G4bool> chopped(GetNumRZCorner(), false);
                                                   >> 644       std::vector<G4int*> triQuads;
                                                   >> 645       G4int remaining = GetNumRZCorner();
                                                   >> 646       G4int iStarter = 0;
                                                   >> 647       while (remaining >= 3)    // Loop checking, 13.08.2015, G.Cosmo
                                                   >> 648       {
                                                   >> 649         // Find unchopped corners...
                                                   >> 650         //
                                                   >> 651         G4int A = -1, B = -1, C = -1;
                                                   >> 652         G4int iStepper = iStarter;
                                                   >> 653         do    // Loop checking, 13.08.2015, G.Cosmo
                                                   >> 654         {
                                                   >> 655           if (A < 0)      { A = iStepper; }
                                                   >> 656           else if (B < 0) { B = iStepper; }
                                                   >> 657           else if (C < 0) { C = iStepper; }
                                                   >> 658           do    // Loop checking, 13.08.2015, G.Cosmo
                                                   >> 659           {
                                                   >> 660             if (++iStepper >= GetNumRZCorner()) iStepper = 0;
                                                   >> 661           }
                                                   >> 662           while (chopped[iStepper]);
                                                   >> 663         }
                                                   >> 664         while (C < 0 && iStepper != iStarter);
                                                   >> 665 
                                                   >> 666         // Check triangle at B is pointing outward (an "ear").
                                                   >> 667         // Sign of z cross product determines...
                                                   >> 668 
                                                   >> 669         G4double BAr = GetCorner(A).r - GetCorner(B).r;
                                                   >> 670         G4double BAz = GetCorner(A).z - GetCorner(B).z;
                                                   >> 671         G4double BCr = GetCorner(C).r - GetCorner(B).r;
                                                   >> 672         G4double BCz = GetCorner(C).z - GetCorner(B).z;
                                                   >> 673         if (BAr * BCz - BAz * BCr < kCarTolerance)
                                                   >> 674         {
                                                   >> 675           G4int* tq = new G4int[3];
                                                   >> 676           tq[0] = A + 1;
                                                   >> 677           tq[1] = B + 1;
                                                   >> 678           tq[2] = C + 1;
                                                   >> 679           triQuads.push_back(tq);
                                                   >> 680           chopped[B] = true;
                                                   >> 681           --remaining;
                                                   >> 682         }
                                                   >> 683         else
                                                   >> 684         {
                                                   >> 685           do    // Loop checking, 13.08.2015, G.Cosmo
                                                   >> 686           {
                                                   >> 687             if (++iStarter >= GetNumRZCorner()) { iStarter = 0; }
                                                   >> 688           }
                                                   >> 689           while (chopped[iStarter]);
                                                   >> 690         }
                                                   >> 691       }
                                                   >> 692 
                                                   >> 693       // Transfer to faces...
                                                   >> 694       G4int numSide=GetNumSide();
                                                   >> 695       nNodes = (numSide + 1) * GetNumRZCorner();
                                                   >> 696       nFaces = numSide * GetNumRZCorner() + 2 * triQuads.size();
                                                   >> 697       faces_vec = new int4[nFaces];
                                                   >> 698       G4int iface = 0;
                                                   >> 699       G4int addition = GetNumRZCorner() * numSide;
                                                   >> 700       G4int d = GetNumRZCorner() - 1;
                                                   >> 701       for (G4int iEnd = 0; iEnd < 2; ++iEnd)
                                                   >> 702       {
                                                   >> 703         for (size_t i = 0; i < triQuads.size(); ++i)
                                                   >> 704         {
                                                   >> 705           // Negative for soft/auxiliary/normally invisible edges...
                                                   >> 706           //
                                                   >> 707           G4int a, b, c;
                                                   >> 708           if (iEnd == 0)
                                                   >> 709           {
                                                   >> 710             a = triQuads[i][0];
                                                   >> 711             b = triQuads[i][1];
                                                   >> 712             c = triQuads[i][2];
                                                   >> 713           }
                                                   >> 714           else
                                                   >> 715           {
                                                   >> 716             a = triQuads[i][0] + addition;
                                                   >> 717             b = triQuads[i][2] + addition;
                                                   >> 718             c = triQuads[i][1] + addition;
                                                   >> 719           }
                                                   >> 720           G4int ab = std::abs(b - a);
                                                   >> 721           G4int bc = std::abs(c - b);
                                                   >> 722           G4int ca = std::abs(a - c);
                                                   >> 723           faces_vec[iface][0] = (ab == 1 || ab == d)? a: -a;
                                                   >> 724           faces_vec[iface][1] = (bc == 1 || bc == d)? b: -b;
                                                   >> 725           faces_vec[iface][2] = (ca == 1 || ca == d)? c: -c;
                                                   >> 726           faces_vec[iface][3] = 0;
                                                   >> 727           ++iface;
                                                   >> 728         }
                                                   >> 729       }
                                                   >> 730 
                                                   >> 731       // Continue with sides...
                                                   >> 732 
                                                   >> 733       xyz = new double3[nNodes];
                                                   >> 734       const G4double dPhi = (GetEndPhi() - GetStartPhi()) / numSide;
                                                   >> 735       G4double phi = GetStartPhi();
                                                   >> 736       G4int ixyz = 0;
                                                   >> 737       for (G4int iSide = 0; iSide < numSide; ++iSide)
                                                   >> 738       {
                                                   >> 739         for (G4int iCorner = 0; iCorner < GetNumRZCorner(); ++iCorner)
                                                   >> 740         {
                                                   >> 741           xyz[ixyz][0] = GetCorner(iCorner).r * std::cos(phi);
                                                   >> 742           xyz[ixyz][1] = GetCorner(iCorner).r * std::sin(phi);
                                                   >> 743           xyz[ixyz][2] = GetCorner(iCorner).z;
                                                   >> 744           if (iCorner < GetNumRZCorner() - 1)
                                                   >> 745           {
                                                   >> 746             faces_vec[iface][0] = ixyz + 1;
                                                   >> 747             faces_vec[iface][1] = ixyz + GetNumRZCorner() + 1;
                                                   >> 748             faces_vec[iface][2] = ixyz + GetNumRZCorner() + 2;
                                                   >> 749             faces_vec[iface][3] = ixyz + 2;
                                                   >> 750           }
                                                   >> 751           else
                                                   >> 752           {
                                                   >> 753             faces_vec[iface][0] = ixyz + 1;
                                                   >> 754             faces_vec[iface][1] = ixyz + GetNumRZCorner() + 1;
                                                   >> 755             faces_vec[iface][2] = ixyz + 2;
                                                   >> 756             faces_vec[iface][3] = ixyz - GetNumRZCorner() + 2;
                                                   >> 757           }
                                                   >> 758           ++iface;
                                                   >> 759           ++ixyz;
                                                   >> 760         }
                                                   >> 761         phi += dPhi;
                                                   >> 762       }
                                                   >> 763 
                                                   >> 764       // Last GetCorner...
                                                   >> 765 
                                                   >> 766       for (G4int iCorner = 0; iCorner < GetNumRZCorner(); ++iCorner)
                                                   >> 767       {
                                                   >> 768         xyz[ixyz][0] = GetCorner(iCorner).r * std::cos(phi);
                                                   >> 769         xyz[ixyz][1] = GetCorner(iCorner).r * std::sin(phi);
                                                   >> 770         xyz[ixyz][2] = GetCorner(iCorner).z;
                                                   >> 771         ++ixyz;
                                                   >> 772       }
                                                   >> 773     }
                                                   >> 774     else  // !phiIsOpen - i.e., a complete 360 degrees.
                                                   >> 775     {
                                                   >> 776       nNodes = GetNumSide() * GetNumRZCorner();
                                                   >> 777       nFaces = GetNumSide() * GetNumRZCorner();;
                                                   >> 778       xyz = new double3[nNodes];
                                                   >> 779       faces_vec = new int4[nFaces];
                                                   >> 780       // const G4double dPhi = (endPhi - startPhi) / numSide;
                                                   >> 781       const G4double dPhi = twopi / GetNumSide();
                                                   >> 782       // !phiIsOpen endPhi-startPhi = 360 degrees.
                                                   >> 783       G4double phi = GetStartPhi();
                                                   >> 784       G4int ixyz = 0, iface = 0;
                                                   >> 785       for (G4int iSide = 0; iSide < GetNumSide(); ++iSide)
                                                   >> 786       {
                                                   >> 787         for (G4int iCorner = 0; iCorner < GetNumRZCorner(); ++iCorner)
                                                   >> 788         {
                                                   >> 789           xyz[ixyz][0] = GetCorner(iCorner).r * std::cos(phi);
                                                   >> 790           xyz[ixyz][1] = GetCorner(iCorner).r * std::sin(phi);
                                                   >> 791           xyz[ixyz][2] = GetCorner(iCorner).z;
                                                   >> 792           if (iSide < GetNumSide() - 1)
                                                   >> 793           {
                                                   >> 794             if (iCorner < GetNumRZCorner() - 1)
                                                   >> 795             {
                                                   >> 796               faces_vec[iface][0] = ixyz + 1;
                                                   >> 797               faces_vec[iface][1] = ixyz + GetNumRZCorner() + 1;
                                                   >> 798               faces_vec[iface][2] = ixyz + GetNumRZCorner() + 2;
                                                   >> 799               faces_vec[iface][3] = ixyz + 2;
                                                   >> 800             }
                                                   >> 801             else
                                                   >> 802             {
                                                   >> 803               faces_vec[iface][0] = ixyz + 1;
                                                   >> 804               faces_vec[iface][1] = ixyz + GetNumRZCorner() + 1;
                                                   >> 805               faces_vec[iface][2] = ixyz + 2;
                                                   >> 806               faces_vec[iface][3] = ixyz - GetNumRZCorner() + 2;
                                                   >> 807             }
                                                   >> 808           }
                                                   >> 809           else   // Last side joins ends...
                                                   >> 810           {
                                                   >> 811             if (iCorner < GetNumRZCorner() - 1)
                                                   >> 812             {
                                                   >> 813               faces_vec[iface][0] = ixyz + 1;
                                                   >> 814               faces_vec[iface][1] = ixyz + GetNumRZCorner() - nFaces + 1;
                                                   >> 815               faces_vec[iface][2] = ixyz + GetNumRZCorner() - nFaces + 2;
                                                   >> 816               faces_vec[iface][3] = ixyz + 2;
                                                   >> 817             }
                                                   >> 818             else
                                                   >> 819             {
                                                   >> 820               faces_vec[iface][0] = ixyz + 1;
                                                   >> 821               faces_vec[iface][1] = ixyz - nFaces + GetNumRZCorner() + 1;
                                                   >> 822               faces_vec[iface][2] = ixyz - nFaces + 2;
                                                   >> 823               faces_vec[iface][3] = ixyz - GetNumRZCorner() + 2;
                                                   >> 824             }
                                                   >> 825           }
                                                   >> 826           ++ixyz;
                                                   >> 827           ++iface;
                                                   >> 828         }
                                                   >> 829         phi += dPhi;
                                                   >> 830       }
                                                   >> 831     }
                                                   >> 832     G4Polyhedron* polyhedron = new G4Polyhedron;
                                                   >> 833     G4int prob = polyhedron->createPolyhedron(nNodes, nFaces, xyz, faces_vec);
                                                   >> 834     delete [] faces_vec;
                                                   >> 835     delete [] xyz;
                                                   >> 836     if (prob)
                                                   >> 837     {
                                                   >> 838       std::ostringstream message;
                                                   >> 839       message << "Problem creating G4Polyhedron for: " << GetName();
                                                   >> 840       G4Exception("G4Polyhedra::CreatePolyhedron()", "GeomSolids1002",
                                                   >> 841                   JustWarning, message);
                                                   >> 842       delete polyhedron;
                                                   >> 843       return nullptr;
                                                   >> 844     }
                                                   >> 845     else
                                                   >> 846     {
                                                   >> 847       return polyhedron;
                                                   >> 848     }
                                                   >> 849   }
597 }                                                 850 }
598                                                   851 
599 #endif  // G4GEOM_USE_USOLIDS                     852 #endif  // G4GEOM_USE_USOLIDS
600                                                   853