Geant4 Cross Reference

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


  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  intell     18 // * This  code  implementation is the  intellectual property  of the *
 19 // * Vanderbilt University Free Electron Laser     19 // * Vanderbilt University Free Electron Laser Center                 *
 20 // * Vanderbilt University, Nashville, TN, USA     20 // * Vanderbilt University, Nashville, TN, USA                        *
 21 // * Development supported by:                     21 // * Development supported by:                                        *
 22 // * United States MFEL program  under grant F     22 // * United States MFEL program  under grant FA9550-04-1-0045         *
 23 // * and NASA under contract number NNG04CT05P     23 // * and NASA under contract number NNG04CT05P                        *
 24 // * Written by Marcus H. Mendenhall and Rober     24 // * Written by Marcus H. Mendenhall and Robert A. Weller.            *
 25 // *                                               25 // *                                                                  *
 26 // * Contributed to the Geant4 Core, January,      26 // * Contributed to the Geant4 Core, January, 2005.                   *
 27 // *                                               27 // *                                                                  *
 28 // *******************************************     28 // ********************************************************************
 29 //                                                 29 //
 30 // Implementation for G4Tet class                  30 // Implementation for G4Tet class
 31 //                                                 31 //
 32 // 03.09.2004 - Marcus Mendenhall, created         32 // 03.09.2004 - Marcus Mendenhall, created
 33 // 08.01.2020 - Evgueni Tcherniaev, complete r     33 // 08.01.2020 - Evgueni Tcherniaev, complete revision, speed up
 34 // -------------------------------------------     34 // --------------------------------------------------------------------
 35                                                    35 
 36 #include "G4Tet.hh"                                36 #include "G4Tet.hh"
 37                                                    37 
 38 #if !defined(G4GEOM_USE_UTET)                      38 #if !defined(G4GEOM_USE_UTET)
 39                                                    39 
 40 #include "G4VoxelLimits.hh"                        40 #include "G4VoxelLimits.hh"
 41 #include "G4AffineTransform.hh"                    41 #include "G4AffineTransform.hh"
 42 #include "G4BoundingEnvelope.hh"                   42 #include "G4BoundingEnvelope.hh"
 43                                                    43 
 44 #include "G4VPVParameterisation.hh"                44 #include "G4VPVParameterisation.hh"
 45                                                    45 
 46 #include "G4QuickRand.hh"                          46 #include "G4QuickRand.hh"
 47                                                    47 
 48 #include "G4VGraphicsScene.hh"                     48 #include "G4VGraphicsScene.hh"
 49 #include "G4Polyhedron.hh"                         49 #include "G4Polyhedron.hh"
 50 #include "G4VisExtent.hh"                          50 #include "G4VisExtent.hh"
 51                                                    51 
 52 #include "G4AutoLock.hh"                           52 #include "G4AutoLock.hh"
 53                                                    53 
 54 namespace                                          54 namespace
 55 {                                                  55 {
 56   G4Mutex polyhedronMutex = G4MUTEX_INITIALIZE     56   G4Mutex polyhedronMutex = G4MUTEX_INITIALIZER;
 57 }                                                  57 }
 58                                                    58 
 59 using namespace CLHEP;                             59 using namespace CLHEP;
 60                                                    60 
 61 //////////////////////////////////////////////     61 ////////////////////////////////////////////////////////////////////////
 62 //                                                 62 //
 63 // Constructor - create a tetrahedron              63 // Constructor - create a tetrahedron
 64 // A Tet has all of its geometrical informatio     64 // A Tet has all of its geometrical information precomputed
 65 //                                                 65 //
 66 G4Tet::G4Tet(const G4String& pName,                66 G4Tet::G4Tet(const G4String& pName,
 67              const G4ThreeVector& p0,              67              const G4ThreeVector& p0,
 68              const G4ThreeVector& p1,              68              const G4ThreeVector& p1,
 69              const G4ThreeVector& p2,              69              const G4ThreeVector& p2,
 70              const G4ThreeVector& p3, G4bool*      70              const G4ThreeVector& p3, G4bool* degeneracyFlag)
 71   : G4VSolid(pName)                                71   : G4VSolid(pName)
 72 {                                                  72 {
 73   // Check for degeneracy                          73   // Check for degeneracy
 74   G4bool degenerate = CheckDegeneracy(p0, p1,      74   G4bool degenerate = CheckDegeneracy(p0, p1, p2, p3);
 75   if (degeneracyFlag != nullptr)               <<  75   if (degeneracyFlag)
 76   {                                                76   {
 77     *degeneracyFlag = degenerate;                  77     *degeneracyFlag = degenerate;
 78   }                                                78   }
 79   else if (degenerate)                             79   else if (degenerate)
 80   {                                                80   {
 81     std::ostringstream message;                    81     std::ostringstream message;
 82     message << "Degenerate tetrahedron: " << G     82     message << "Degenerate tetrahedron: " << GetName() << " !\n"
 83             << "  anchor: " << p0 << "\n"          83             << "  anchor: " << p0 << "\n"
 84             << "  p1    : " << p1 << "\n"          84             << "  p1    : " << p1 << "\n"
 85             << "  p2    : " << p2 << "\n"          85             << "  p2    : " << p2 << "\n"
 86             << "  p3    : " << p3 << "\n"          86             << "  p3    : " << p3 << "\n"
 87             << "  volume: "                        87             << "  volume: "
 88             << std::abs((p1 - p0).cross(p2 - p     88             << std::abs((p1 - p0).cross(p2 - p0).dot(p3 - p0))/6.;
 89     G4Exception("G4Tet::G4Tet()", "GeomSolids0     89     G4Exception("G4Tet::G4Tet()", "GeomSolids0002", FatalException, message);
 90   }                                                90   }
 91                                                    91 
 92   // Define surface thickness                      92   // Define surface thickness
 93   halfTolerance = 0.5 * kCarTolerance;             93   halfTolerance = 0.5 * kCarTolerance;
 94                                                    94 
 95   // Set data members                              95   // Set data members
 96   Initialize(p0, p1, p2, p3);                      96   Initialize(p0, p1, p2, p3);
 97 }                                                  97 }
 98                                                    98 
 99 //////////////////////////////////////////////     99 ////////////////////////////////////////////////////////////////////////
100 //                                                100 //
101 // Fake default constructor - sets only member    101 // Fake default constructor - sets only member data and allocates memory
102 //                            for usage restri    102 //                            for usage restricted to object persistency.
103 //                                                103 //
104 G4Tet::G4Tet( __void__& a )                       104 G4Tet::G4Tet( __void__& a )
105   : G4VSolid(a)                                   105   : G4VSolid(a)
106 {                                                 106 {
107 }                                                 107 }
108                                                   108 
109 //////////////////////////////////////////////    109 ////////////////////////////////////////////////////////////////////////
110 //                                                110 //
111 // Destructor                                     111 // Destructor
112 //                                                112 //
113 G4Tet::~G4Tet()                                   113 G4Tet::~G4Tet()
114 {                                                 114 {
115   delete fpPolyhedron; fpPolyhedron = nullptr;    115   delete fpPolyhedron; fpPolyhedron = nullptr;
116 }                                                 116 }
117                                                   117 
118 //////////////////////////////////////////////    118 ////////////////////////////////////////////////////////////////////////
119 //                                                119 //
120 // Copy constructor                               120 // Copy constructor
121 //                                                121 //
122 G4Tet::G4Tet(const G4Tet& rhs)                    122 G4Tet::G4Tet(const G4Tet& rhs)
123   : G4VSolid(rhs)                                 123   : G4VSolid(rhs)
124 {                                                 124 {
125    halfTolerance = rhs.halfTolerance;             125    halfTolerance = rhs.halfTolerance;
126    fCubicVolume = rhs.fCubicVolume;               126    fCubicVolume = rhs.fCubicVolume;
127    fSurfaceArea = rhs.fSurfaceArea;               127    fSurfaceArea = rhs.fSurfaceArea;
128    for (G4int i = 0; i < 4; ++i) { fVertex[i]     128    for (G4int i = 0; i < 4; ++i) { fVertex[i] = rhs.fVertex[i]; }
129    for (G4int i = 0; i < 4; ++i) { fNormal[i]     129    for (G4int i = 0; i < 4; ++i) { fNormal[i] = rhs.fNormal[i]; }
130    for (G4int i = 0; i < 4; ++i) { fDist[i] =     130    for (G4int i = 0; i < 4; ++i) { fDist[i] = rhs.fDist[i]; }
131    for (G4int i = 0; i < 4; ++i) { fArea[i] =     131    for (G4int i = 0; i < 4; ++i) { fArea[i] = rhs.fArea[i]; }
132    fBmin = rhs.fBmin;                             132    fBmin = rhs.fBmin;
133    fBmax = rhs.fBmax;                             133    fBmax = rhs.fBmax;
134 }                                                 134 }
135                                                   135 
136 //////////////////////////////////////////////    136 ////////////////////////////////////////////////////////////////////////
137 //                                                137 //
138 // Assignment operator                            138 // Assignment operator
139 //                                                139 //
140 G4Tet& G4Tet::operator = (const G4Tet& rhs)       140 G4Tet& G4Tet::operator = (const G4Tet& rhs)
141 {                                                 141 {
142    // Check assignment to self                    142    // Check assignment to self
143    //                                             143    //
144    if (this == &rhs)  { return *this; }           144    if (this == &rhs)  { return *this; }
145                                                   145 
146    // Copy base class data                        146    // Copy base class data
147    //                                             147    //
148    G4VSolid::operator=(rhs);                      148    G4VSolid::operator=(rhs);
149                                                   149 
150    // Copy data                                   150    // Copy data
151    //                                             151    //
152    halfTolerance = rhs.halfTolerance;             152    halfTolerance = rhs.halfTolerance;
153    fCubicVolume = rhs.fCubicVolume;               153    fCubicVolume = rhs.fCubicVolume;
154    fSurfaceArea = rhs.fSurfaceArea;               154    fSurfaceArea = rhs.fSurfaceArea;
155    for (G4int i = 0; i < 4; ++i) { fVertex[i]     155    for (G4int i = 0; i < 4; ++i) { fVertex[i] = rhs.fVertex[i]; }
156    for (G4int i = 0; i < 4; ++i) { fNormal[i]     156    for (G4int i = 0; i < 4; ++i) { fNormal[i] = rhs.fNormal[i]; }
157    for (G4int i = 0; i < 4; ++i) { fDist[i] =     157    for (G4int i = 0; i < 4; ++i) { fDist[i] = rhs.fDist[i]; }
158    for (G4int i = 0; i < 4; ++i) { fArea[i] =     158    for (G4int i = 0; i < 4; ++i) { fArea[i] = rhs.fArea[i]; }
159    fBmin = rhs.fBmin;                             159    fBmin = rhs.fBmin;
160    fBmax = rhs.fBmax;                             160    fBmax = rhs.fBmax;
161    fRebuildPolyhedron = false;                    161    fRebuildPolyhedron = false;
162    delete fpPolyhedron; fpPolyhedron = nullptr    162    delete fpPolyhedron; fpPolyhedron = nullptr;
163                                                   163 
164    return *this;                                  164    return *this;
165 }                                                 165 }
166                                                   166 
167 //////////////////////////////////////////////    167 ////////////////////////////////////////////////////////////////////////
168 //                                                168 //
169 // Return true if tetrahedron is degenerate       169 // Return true if tetrahedron is degenerate
170 // Tetrahedron is concidered as degenerate in     170 // Tetrahedron is concidered as degenerate in case if its minimal
171 // height is less than degeneracy tolerance       171 // height is less than degeneracy tolerance
172 //                                                172 //
173 G4bool G4Tet::CheckDegeneracy(const G4ThreeVec    173 G4bool G4Tet::CheckDegeneracy(const G4ThreeVector& p0,
174                               const G4ThreeVec    174                               const G4ThreeVector& p1,
175                               const G4ThreeVec    175                               const G4ThreeVector& p2,
176                               const G4ThreeVec    176                               const G4ThreeVector& p3) const
177 {                                                 177 {
178   G4double hmin = 4. * kCarTolerance; // degen    178   G4double hmin = 4. * kCarTolerance; // degeneracy tolerance
179                                                   179 
180   // Calculate volume                             180   // Calculate volume
181   G4double vol = std::abs((p1 - p0).cross(p2 -    181   G4double vol = std::abs((p1 - p0).cross(p2 - p0).dot(p3 - p0));
182                                                   182 
183   // Calculate face areas squared                 183   // Calculate face areas squared
184   G4double ss[4];                                 184   G4double ss[4];
185   ss[0] = ((p1 - p0).cross(p2 - p0)).mag2();      185   ss[0] = ((p1 - p0).cross(p2 - p0)).mag2();
186   ss[1] = ((p2 - p0).cross(p3 - p0)).mag2();      186   ss[1] = ((p2 - p0).cross(p3 - p0)).mag2();
187   ss[2] = ((p3 - p0).cross(p1 - p0)).mag2();      187   ss[2] = ((p3 - p0).cross(p1 - p0)).mag2();
188   ss[3] = ((p2 - p1).cross(p3 - p1)).mag2();      188   ss[3] = ((p2 - p1).cross(p3 - p1)).mag2();
189                                                   189 
190   // Find face with max area                      190   // Find face with max area
191   G4int k = 0;                                    191   G4int k = 0;
192   for (G4int i = 1; i < 4; ++i) { if (ss[i] >     192   for (G4int i = 1; i < 4; ++i) { if (ss[i] > ss[k]) k = i; }
193                                                   193 
194   // Check: vol^2 / s^2 <= hmin^2                 194   // Check: vol^2 / s^2 <= hmin^2
195   return (vol*vol <= ss[k]*hmin*hmin);            195   return (vol*vol <= ss[k]*hmin*hmin);
196 }                                                 196 }
197                                                   197 
198 //////////////////////////////////////////////    198 ////////////////////////////////////////////////////////////////////////
199 //                                                199 //
200 // Set data members                               200 // Set data members
201 //                                                201 //
202 void G4Tet::Initialize(const G4ThreeVector& p0    202 void G4Tet::Initialize(const G4ThreeVector& p0,
203                        const G4ThreeVector& p1    203                        const G4ThreeVector& p1,
204                        const G4ThreeVector& p2    204                        const G4ThreeVector& p2,
205                        const G4ThreeVector& p3    205                        const G4ThreeVector& p3)
206 {                                                 206 {
207   // Set vertices                                 207   // Set vertices
208   fVertex[0] = p0;                                208   fVertex[0] = p0;
209   fVertex[1] = p1;                                209   fVertex[1] = p1;
210   fVertex[2] = p2;                                210   fVertex[2] = p2;
211   fVertex[3] = p3;                                211   fVertex[3] = p3;
212                                                   212 
213   G4ThreeVector norm[4];                          213   G4ThreeVector norm[4];
214   norm[0] = (p2 - p0).cross(p1 - p0);             214   norm[0] = (p2 - p0).cross(p1 - p0);
215   norm[1] = (p3 - p0).cross(p2 - p0);             215   norm[1] = (p3 - p0).cross(p2 - p0);
216   norm[2] = (p1 - p0).cross(p3 - p0);             216   norm[2] = (p1 - p0).cross(p3 - p0);
217   norm[3] = (p2 - p1).cross(p3 - p1);             217   norm[3] = (p2 - p1).cross(p3 - p1);
218   G4double volume = norm[0].dot(p3 - p0);         218   G4double volume = norm[0].dot(p3 - p0);
219   if (volume > 0.)                                219   if (volume > 0.)
220   {                                               220   {
221     for (auto & i : norm) { i = -i; }          << 221     for (G4int i = 0; i < 4; ++i) { norm[i] = -norm[i]; }
222   }                                               222   }
223                                                   223 
224   // Set normals to face planes                   224   // Set normals to face planes
225   for (G4int i = 0; i < 4; ++i) { fNormal[i] =    225   for (G4int i = 0; i < 4; ++i) { fNormal[i] = norm[i].unit(); }
226                                                   226 
227   // Set distances to planes                      227   // Set distances to planes
228   for (G4int i = 0; i < 3; ++i) { fDist[i] = f    228   for (G4int i = 0; i < 3; ++i) { fDist[i] = fNormal[i].dot(p0); }
229   fDist[3] = fNormal[3].dot(p1);                  229   fDist[3] = fNormal[3].dot(p1);
230                                                   230 
231   // Set face areas                               231   // Set face areas
232   for (G4int i = 0; i < 4; ++i) { fArea[i] = 0    232   for (G4int i = 0; i < 4; ++i) { fArea[i] = 0.5*norm[i].mag(); }
233                                                   233 
234   // Set bounding box                             234   // Set bounding box
235   for (G4int i = 0; i < 3; ++i)                   235   for (G4int i = 0; i < 3; ++i)
236   {                                               236   {
237     fBmin[i] = std::min(std::min(std::min(p0[i    237     fBmin[i] = std::min(std::min(std::min(p0[i], p1[i]), p2[i]), p3[i]);
238     fBmax[i] = std::max(std::max(std::max(p0[i    238     fBmax[i] = std::max(std::max(std::max(p0[i], p1[i]), p2[i]), p3[i]);
239   }                                               239   }
240                                                   240 
241   // Set volume and surface area                  241   // Set volume and surface area
242   fCubicVolume = std::abs(volume)/6.;             242   fCubicVolume = std::abs(volume)/6.;
243   fSurfaceArea = fArea[0] + fArea[1] + fArea[2    243   fSurfaceArea = fArea[0] + fArea[1] + fArea[2] + fArea[3];
244 }                                                 244 }
245                                                   245 
246 //////////////////////////////////////////////    246 ////////////////////////////////////////////////////////////////////////
247 //                                                247 //
248 // Set vertices                                   248 // Set vertices
249 //                                                249 //
250 void G4Tet::SetVertices(const G4ThreeVector& p    250 void G4Tet::SetVertices(const G4ThreeVector& p0,
251                         const G4ThreeVector& p    251                         const G4ThreeVector& p1,
252                         const G4ThreeVector& p    252                         const G4ThreeVector& p2,
253                         const G4ThreeVector& p    253                         const G4ThreeVector& p3, G4bool* degeneracyFlag)
254 {                                                 254 {
255   // Check for degeneracy                         255   // Check for degeneracy
256   G4bool degenerate = CheckDegeneracy(p0, p1,     256   G4bool degenerate = CheckDegeneracy(p0, p1, p2, p3);
257   if (degeneracyFlag != nullptr)               << 257   if (degeneracyFlag)
258   {                                               258   {
259     *degeneracyFlag = degenerate;                 259     *degeneracyFlag = degenerate;
260   }                                               260   }
261   else if (degenerate)                            261   else if (degenerate)
262   {                                               262   {
263     std::ostringstream message;                   263     std::ostringstream message;
264     message << "Degenerate tetrahedron is not     264     message << "Degenerate tetrahedron is not permitted: " << GetName() << " !\n"
265             << "  anchor: " << p0 << "\n"         265             << "  anchor: " << p0 << "\n"
266             << "  p1    : " << p1 << "\n"         266             << "  p1    : " << p1 << "\n"
267             << "  p2    : " << p2 << "\n"         267             << "  p2    : " << p2 << "\n"
268             << "  p3    : " << p3 << "\n"         268             << "  p3    : " << p3 << "\n"
269             << "  volume: "                       269             << "  volume: "
270             << std::abs((p1 - p0).cross(p2 - p    270             << std::abs((p1 - p0).cross(p2 - p0).dot(p3 - p0))/6.;
271     G4Exception("G4Tet::SetVertices()", "GeomS    271     G4Exception("G4Tet::SetVertices()", "GeomSolids0002",
272                 FatalException, message);         272                 FatalException, message);
273   }                                               273   }
274                                                   274 
275   // Set data members                             275   // Set data members
276   Initialize(p0, p1, p2, p3);                     276   Initialize(p0, p1, p2, p3);
277                                                   277 
278   // Set flag to rebuild polyhedron               278   // Set flag to rebuild polyhedron
279   fRebuildPolyhedron = true;                      279   fRebuildPolyhedron = true;
280 }                                                 280 }
281                                                   281 
282 //////////////////////////////////////////////    282 ////////////////////////////////////////////////////////////////////////
283 //                                                283 //
284 // Return four vertices                           284 // Return four vertices
285 //                                                285 //
286 void G4Tet::GetVertices(G4ThreeVector& p0,        286 void G4Tet::GetVertices(G4ThreeVector& p0,
287                         G4ThreeVector& p1,        287                         G4ThreeVector& p1,
288                         G4ThreeVector& p2,        288                         G4ThreeVector& p2,
289                         G4ThreeVector& p3) con    289                         G4ThreeVector& p3) const
290 {                                                 290 {
291   p0 = fVertex[0];                                291   p0 = fVertex[0];
292   p1 = fVertex[1];                                292   p1 = fVertex[1];
293   p2 = fVertex[2];                                293   p2 = fVertex[2];
294   p3 = fVertex[3];                                294   p3 = fVertex[3];
295 }                                                 295 }
296                                                   296 
297 //////////////////////////////////////////////    297 ////////////////////////////////////////////////////////////////////////
298 //                                                298 //
299 // Return std::vector of vertices                 299 // Return std::vector of vertices
300 //                                                300 //
301 std::vector<G4ThreeVector> G4Tet::GetVertices(    301 std::vector<G4ThreeVector> G4Tet::GetVertices() const
302 {                                                 302 {
303   std::vector<G4ThreeVector> vertices(4);         303   std::vector<G4ThreeVector> vertices(4);
304   for (G4int i = 0; i < 4; ++i) { vertices[i]     304   for (G4int i = 0; i < 4; ++i) { vertices[i] = fVertex[i]; }
305   return vertices;                                305   return vertices;
306 }                                                 306 }
307                                                   307 
308 //////////////////////////////////////////////    308 ////////////////////////////////////////////////////////////////////////
309 //                                                309 //
310 // Dispatch to parameterisation for replicatio    310 // Dispatch to parameterisation for replication mechanism dimension
311 // computation & modification.                    311 // computation & modification.
312 //                                                312 //
313 void G4Tet::ComputeDimensions(G4VPVParameteris    313 void G4Tet::ComputeDimensions(G4VPVParameterisation* ,
314                               const G4int ,       314                               const G4int ,
315                               const G4VPhysica    315                               const G4VPhysicalVolume* )
316 {                                                 316 {
317 }                                                 317 }
318                                                   318 
319 //////////////////////////////////////////////    319 ////////////////////////////////////////////////////////////////////////
320 //                                                320 //
321 // Set bounding box                               321 // Set bounding box
322 //                                                322 //
323 void G4Tet::SetBoundingLimits(const G4ThreeVec    323 void G4Tet::SetBoundingLimits(const G4ThreeVector& pMin,
324                               const G4ThreeVec    324                               const G4ThreeVector& pMax)
325 {                                                 325 {
326   G4int iout[4] = { 0, 0, 0, 0 };                 326   G4int iout[4] = { 0, 0, 0, 0 };
327   for (G4int i = 0; i < 4; ++i)                   327   for (G4int i = 0; i < 4; ++i)
328   {                                               328   {
329     iout[i] = (G4int)(fVertex[i].x() < pMin.x( << 329     iout[i] = (fVertex[i].x() < pMin.x() ||
330                       fVertex[i].y() < pMin.y( << 330                fVertex[i].y() < pMin.y() ||
331                       fVertex[i].z() < pMin.z( << 331                fVertex[i].z() < pMin.z() ||
332                       fVertex[i].x() > pMax.x( << 332                fVertex[i].x() > pMax.x() ||
333                       fVertex[i].y() > pMax.y( << 333                fVertex[i].y() > pMax.y() ||
334                       fVertex[i].z() > pMax.z( << 334                fVertex[i].z() > pMax.z());
335   }                                               335   }
336   if (iout[0] + iout[1] + iout[2] + iout[3] !=    336   if (iout[0] + iout[1] + iout[2] + iout[3] != 0)
337   {                                               337   {
338     std::ostringstream message;                   338     std::ostringstream message;
339     message << "Attempt to set bounding box th    339     message << "Attempt to set bounding box that does not encapsulate solid: "
340             << GetName() << " !\n"                340             << GetName() << " !\n"
341             << "  Specified bounding box limit    341             << "  Specified bounding box limits:\n"
342             << "    pmin: " << pMin << "\n"       342             << "    pmin: " << pMin << "\n"
343             << "    pmax: " << pMax << "\n"       343             << "    pmax: " << pMax << "\n"
344             << "  Tetrahedron vertices:\n"        344             << "  Tetrahedron vertices:\n"
345             << "    anchor " << fVertex[0] <<  << 345             << "    anchor " << fVertex[0] << ((iout[0]) ? " is outside\n" : "\n")
346             << "    p1 "     << fVertex[1] <<  << 346             << "    p1 "     << fVertex[1] << ((iout[1]) ? " is outside\n" : "\n")
347             << "    p2 "     << fVertex[2] <<  << 347             << "    p2 "     << fVertex[2] << ((iout[2]) ? " is outside\n" : "\n")
348             << "    p3 "     << fVertex[3] <<  << 348             << "    p3 "     << fVertex[3] << ((iout[3]) ? " is outside"   : "");
349     G4Exception("G4Tet::SetBoundingLimits()",     349     G4Exception("G4Tet::SetBoundingLimits()", "GeomSolids0002",
350                 FatalException, message);         350                 FatalException, message);
351   }                                               351   }
352   fBmin = pMin;                                   352   fBmin = pMin;
353   fBmax = pMax;                                   353   fBmax = pMax;
354 }                                                 354 }
355                                                   355 
356 //////////////////////////////////////////////    356 ////////////////////////////////////////////////////////////////////////
357 //                                                357 //
358 // Return bounding box                            358 // Return bounding box
359 //                                                359 //
360 void G4Tet::BoundingLimits(G4ThreeVector& pMin    360 void G4Tet::BoundingLimits(G4ThreeVector& pMin, G4ThreeVector& pMax) const
361 {                                                 361 {
362   pMin = fBmin;                                   362   pMin = fBmin;
363   pMax = fBmax;                                   363   pMax = fBmax;
364 }                                                 364 }
365                                                   365 
366 //////////////////////////////////////////////    366 ////////////////////////////////////////////////////////////////////////
367 //                                                367 //
368 // Calculate extent under transform and specif    368 // Calculate extent under transform and specified limit
369 //                                                369 //
370 G4bool G4Tet::CalculateExtent(const EAxis pAxi    370 G4bool G4Tet::CalculateExtent(const EAxis pAxis,
371                               const G4VoxelLim    371                               const G4VoxelLimits& pVoxelLimit,
372                               const G4AffineTr    372                               const G4AffineTransform& pTransform,
373                                     G4double&     373                                     G4double& pMin, G4double& pMax) const
374 {                                                 374 {
375   G4ThreeVector bmin, bmax;                       375   G4ThreeVector bmin, bmax;
376                                                   376 
377   // Check bounding box (bbox)                    377   // Check bounding box (bbox)
378   //                                              378   //
379   BoundingLimits(bmin,bmax);                      379   BoundingLimits(bmin,bmax);
380   G4BoundingEnvelope bbox(bmin,bmax);             380   G4BoundingEnvelope bbox(bmin,bmax);
381                                                   381 
382   // Use simple bounding-box to help in the ca    382   // Use simple bounding-box to help in the case of complex 3D meshes
383   //                                              383   //
384   return bbox.CalculateExtent(pAxis,pVoxelLimi    384   return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
385                                                   385 
386 #if 0                                             386 #if 0
387   // Precise extent computation (disabled by d    387   // Precise extent computation (disabled by default for this shape)
388   //                                              388   //
389   G4bool exist;                                   389   G4bool exist;
390   if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVox    390   if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVoxelLimit,pTransform,pMin,pMax))
391   {                                               391   {
392     return exist = (pMin < pMax) ? true : fals    392     return exist = (pMin < pMax) ? true : false;
393   }                                               393   }
394                                                   394 
395   // Set bounding envelope (benv) and calculat    395   // Set bounding envelope (benv) and calculate extent
396   //                                              396   //
397   std::vector<G4ThreeVector> vec = GetVertices    397   std::vector<G4ThreeVector> vec = GetVertices();
398                                                   398 
399   G4ThreeVectorList anchor(1);                    399   G4ThreeVectorList anchor(1);
400   anchor[0].set(vec[0].x(),vec[0].y(),vec[0].z    400   anchor[0].set(vec[0].x(),vec[0].y(),vec[0].z());
401                                                   401 
402   G4ThreeVectorList base(3);                      402   G4ThreeVectorList base(3);
403   base[0].set(vec[1].x(),vec[1].y(),vec[1].z()    403   base[0].set(vec[1].x(),vec[1].y(),vec[1].z());
404   base[1].set(vec[2].x(),vec[2].y(),vec[2].z()    404   base[1].set(vec[2].x(),vec[2].y(),vec[2].z());
405   base[2].set(vec[3].x(),vec[3].y(),vec[3].z()    405   base[2].set(vec[3].x(),vec[3].y(),vec[3].z());
406                                                   406 
407   std::vector<const G4ThreeVectorList *> polyg    407   std::vector<const G4ThreeVectorList *> polygons(2);
408   polygons[0] = &anchor;                          408   polygons[0] = &anchor;
409   polygons[1] = &base;                            409   polygons[1] = &base;
410                                                   410 
411   G4BoundingEnvelope benv(bmin,bmax,polygons);    411   G4BoundingEnvelope benv(bmin,bmax,polygons);
412   return exists = benv.CalculateExtent(pAxis,p    412   return exists = benv.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
413 #endif                                            413 #endif
414 }                                                 414 }
415                                                   415 
416 //////////////////////////////////////////////    416 ////////////////////////////////////////////////////////////////////////
417 //                                                417 //
418 // Return whether point inside/outside/on surf    418 // Return whether point inside/outside/on surface
419 //                                                419 //
420 EInside G4Tet::Inside(const G4ThreeVector& p)     420 EInside G4Tet::Inside(const G4ThreeVector& p) const
421 {                                                 421 {
422   G4double dd[4];                                 422   G4double dd[4];
423   for (G4int i = 0; i < 4; ++i) { dd[i] = fNor    423   for (G4int i = 0; i < 4; ++i) { dd[i] = fNormal[i].dot(p) - fDist[i]; }
424                                                   424 
425   G4double dist = std::max(std::max(std::max(d    425   G4double dist = std::max(std::max(std::max(dd[0], dd[1]), dd[2]), dd[3]);
426   return (dist <= -halfTolerance) ?               426   return (dist <= -halfTolerance) ?
427     kInside : ((dist <= halfTolerance) ? kSurf    427     kInside : ((dist <= halfTolerance) ? kSurface : kOutside);
428 }                                                 428 }
429                                                   429 
430 //////////////////////////////////////////////    430 ////////////////////////////////////////////////////////////////////////
431 //                                                431 //
432 // Return unit normal to surface at p             432 // Return unit normal to surface at p
433 //                                                433 //
434 G4ThreeVector G4Tet::SurfaceNormal( const G4Th    434 G4ThreeVector G4Tet::SurfaceNormal( const G4ThreeVector& p) const
435 {                                                 435 {
436   G4double k[4];                                  436   G4double k[4];
437   for (G4int i = 0; i < 4; ++i)                   437   for (G4int i = 0; i < 4; ++i)
438   {                                               438   {
439     k[i] = (G4double)(std::abs(fNormal[i].dot( << 439     k[i] = std::abs(fNormal[i].dot(p) - fDist[i]) <= halfTolerance;
440   }                                               440   }
441   G4double nsurf = k[0] + k[1] + k[2] + k[3];     441   G4double nsurf = k[0] + k[1] + k[2] + k[3];
442   G4ThreeVector norm =                            442   G4ThreeVector norm =
443     k[0]*fNormal[0] + k[1]*fNormal[1] + k[2]*f    443     k[0]*fNormal[0] + k[1]*fNormal[1] + k[2]*fNormal[2] + k[3]*fNormal[3];
444                                                   444 
445   if (nsurf == 1.) return norm;                   445   if (nsurf == 1.) return norm;
446   else if (nsurf > 1.) return norm.unit(); //     446   else if (nsurf > 1.) return norm.unit(); // edge or vertex
447   {                                               447   {
448 #ifdef G4SPECSDEBUG                               448 #ifdef G4SPECSDEBUG
449     std::ostringstream message;                   449     std::ostringstream message;
450     G4long oldprc = message.precision(16);        450     G4long oldprc = message.precision(16);
451     message << "Point p is not on surface (!?)    451     message << "Point p is not on surface (!?) of solid: "
452             << GetName() << "\n";                 452             << GetName() << "\n";
453     message << "Position:\n";                     453     message << "Position:\n";
454     message << "   p.x() = " << p.x()/mm << "     454     message << "   p.x() = " << p.x()/mm << " mm\n";
455     message << "   p.y() = " << p.y()/mm << "     455     message << "   p.y() = " << p.y()/mm << " mm\n";
456     message << "   p.z() = " << p.z()/mm << "     456     message << "   p.z() = " << p.z()/mm << " mm";
457     G4cout.precision(oldprc);                     457     G4cout.precision(oldprc);
458     G4Exception("G4Tet::SurfaceNormal(p)", "Ge    458     G4Exception("G4Tet::SurfaceNormal(p)", "GeomSolids1002",
459                 JustWarning, message );           459                 JustWarning, message );
460     DumpInfo();                                   460     DumpInfo();
461 #endif                                            461 #endif
462     return ApproxSurfaceNormal(p);                462     return ApproxSurfaceNormal(p);
463   }                                               463   }
464 }                                                 464 }
465                                                   465 
466 //////////////////////////////////////////////    466 ////////////////////////////////////////////////////////////////////////
467 //                                                467 //
468 // Find surface nearest to point and return co    468 // Find surface nearest to point and return corresponding normal
469 // This method normally should not be called      469 // This method normally should not be called
470 //                                                470 //
471 G4ThreeVector G4Tet::ApproxSurfaceNormal(const    471 G4ThreeVector G4Tet::ApproxSurfaceNormal(const G4ThreeVector& p) const
472 {                                                 472 {
473   G4double dist = -DBL_MAX;                       473   G4double dist = -DBL_MAX;
474   G4int iside = 0;                                474   G4int iside = 0;
475   for (G4int i = 0; i < 4; ++i)                   475   for (G4int i = 0; i < 4; ++i)
476   {                                               476   {
477     G4double d = fNormal[i].dot(p) - fDist[i];    477     G4double d = fNormal[i].dot(p) - fDist[i];
478     if (d > dist) { dist = d; iside = i; }        478     if (d > dist) { dist = d; iside = i; }
479   }                                               479   }
480   return fNormal[iside];                          480   return fNormal[iside];
481 }                                                 481 }
482                                                   482 
483 //////////////////////////////////////////////    483 ////////////////////////////////////////////////////////////////////////
484 //                                                484 //
485 // Calculate distance to surface from outside,    485 // Calculate distance to surface from outside,
486 // return kInfinity if no intersection            486 // return kInfinity if no intersection
487 //                                                487 //
488 G4double G4Tet::DistanceToIn(const G4ThreeVect    488 G4double G4Tet::DistanceToIn(const G4ThreeVector& p,
489                              const G4ThreeVect    489                              const G4ThreeVector& v) const
490 {                                                 490 {
491   G4double tin = -DBL_MAX, tout = DBL_MAX;        491   G4double tin = -DBL_MAX, tout = DBL_MAX;
492   for (G4int i = 0; i < 4; ++i)                   492   for (G4int i = 0; i < 4; ++i)
493   {                                               493   {
494     G4double cosa = fNormal[i].dot(v);            494     G4double cosa = fNormal[i].dot(v);
495     G4double dist = fNormal[i].dot(p) - fDist[    495     G4double dist = fNormal[i].dot(p) - fDist[i];
496     if (dist >= -halfTolerance)                   496     if (dist >= -halfTolerance)
497     {                                             497     {
498       if (cosa >= 0.) { return kInfinity; }       498       if (cosa >= 0.) { return kInfinity; }
499       tin = std::max(tin, -dist/cosa);            499       tin = std::max(tin, -dist/cosa);
500     }                                             500     }
501     else if (cosa > 0.)                           501     else if (cosa > 0.)
502     {                                             502     {
503       tout = std::min(tout, -dist/cosa);          503       tout = std::min(tout, -dist/cosa);
504     }                                             504     }
505   }                                               505   }
506                                                   506 
507   return (tout - tin <= halfTolerance) ?          507   return (tout - tin <= halfTolerance) ?
508     kInfinity : ((tin < halfTolerance) ? 0. :     508     kInfinity : ((tin < halfTolerance) ? 0. : tin);
509 }                                                 509 }
510                                                   510 
511 //////////////////////////////////////////////    511 ////////////////////////////////////////////////////////////////////////
512 //                                                512 //
513 // Estimate safety distance to surface from ou    513 // Estimate safety distance to surface from outside
514 //                                                514 //
515 G4double G4Tet::DistanceToIn(const G4ThreeVect    515 G4double G4Tet::DistanceToIn(const G4ThreeVector& p) const
516 {                                                 516 {
517   G4double dd[4];                                 517   G4double dd[4];
518   for (G4int i = 0; i < 4; ++i) { dd[i] = fNor    518   for (G4int i = 0; i < 4; ++i) { dd[i] = fNormal[i].dot(p) - fDist[i]; }
519                                                   519 
520   G4double dist = std::max(std::max(std::max(d    520   G4double dist = std::max(std::max(std::max(dd[0], dd[1]), dd[2]), dd[3]);
521   return (dist > 0.) ? dist : 0.;                 521   return (dist > 0.) ? dist : 0.;
522 }                                                 522 }
523                                                   523 
524 //////////////////////////////////////////////    524 ////////////////////////////////////////////////////////////////////////
525 //                                                525 //
526 // Calcluate distance to surface from inside      526 // Calcluate distance to surface from inside
527 //                                                527 //
528 G4double G4Tet::DistanceToOut(const G4ThreeVec    528 G4double G4Tet::DistanceToOut(const G4ThreeVector& p,
529                               const G4ThreeVec    529                               const G4ThreeVector& v,
530                               const G4bool cal    530                               const G4bool calcNorm,
531                                     G4bool* va    531                                     G4bool* validNorm,
532                                     G4ThreeVec    532                                     G4ThreeVector* n) const
533 {                                                 533 {
534   // Calculate distances and cosines              534   // Calculate distances and cosines
535   G4double cosa[4], dist[4];                      535   G4double cosa[4], dist[4];
536   G4int ind[4] = {0}, nside = 0;                  536   G4int ind[4] = {0}, nside = 0;
537   for (G4int i = 0; i < 4; ++i)                   537   for (G4int i = 0; i < 4; ++i)
538   {                                               538   {
539     G4double tmp = fNormal[i].dot(v);             539     G4double tmp = fNormal[i].dot(v);
540     cosa[i] = tmp;                                540     cosa[i] = tmp;
541     ind[nside] = (G4int)(tmp > 0) * i;         << 541     ind[nside] = (tmp > 0) * i;
542     nside += (G4int)(tmp > 0);                 << 542     nside += (tmp > 0);
543     dist[i] = fNormal[i].dot(p) - fDist[i];       543     dist[i] = fNormal[i].dot(p) - fDist[i];
544   }                                               544   }
545                                                   545 
546   // Find intersection (in most of cases nside    546   // Find intersection (in most of cases nside == 1)
547   G4double tout = DBL_MAX;                        547   G4double tout = DBL_MAX;
548   G4int iside = 0;                                548   G4int iside = 0;
549   for (G4int i = 0; i < nside; ++i)               549   for (G4int i = 0; i < nside; ++i)
550   {                                               550   {
551     G4int k = ind[i];                             551     G4int k = ind[i];
552     // Check: leaving the surface                 552     // Check: leaving the surface
553     if (dist[k] >= -halfTolerance) { tout = 0.    553     if (dist[k] >= -halfTolerance) { tout = 0.; iside = k; break; }
554     // Compute distance to intersection           554     // Compute distance to intersection
555     G4double tmp = -dist[k]/cosa[k];              555     G4double tmp = -dist[k]/cosa[k];
556     if (tmp < tout) { tout = tmp; iside = k; }    556     if (tmp < tout) { tout = tmp; iside = k; }
557   }                                               557   }
558                                                   558 
559   // Set normal, if required, and return dista    559   // Set normal, if required, and return distance to out
560   if (calcNorm)                                   560   if (calcNorm)
561   {                                               561   {
562     *validNorm = true;                            562     *validNorm = true;
563     *n = fNormal[iside];                          563     *n = fNormal[iside];
564   }                                               564   }
565   return tout;                                    565   return tout;
566 }                                                 566 }
567                                                   567 
568 //////////////////////////////////////////////    568 ////////////////////////////////////////////////////////////////////////
569 //                                                569 //
570 // Calculate safety distance to surface from i    570 // Calculate safety distance to surface from inside
571 //                                                571 //
572 G4double G4Tet::DistanceToOut(const G4ThreeVec    572 G4double G4Tet::DistanceToOut(const G4ThreeVector& p) const
573 {                                                 573 {
574   G4double dd[4];                                 574   G4double dd[4];
575   for (G4int i = 0; i < 4; ++i) { dd[i] = fDis    575   for (G4int i = 0; i < 4; ++i) { dd[i] = fDist[i] - fNormal[i].dot(p); }
576                                                   576 
577   G4double dist = std::min(std::min(std::min(d    577   G4double dist = std::min(std::min(std::min(dd[0], dd[1]), dd[2]), dd[3]);
578   return (dist > 0.) ? dist : 0.;                 578   return (dist > 0.) ? dist : 0.;
579 }                                                 579 }
580                                                   580 
581 //////////////////////////////////////////////    581 ////////////////////////////////////////////////////////////////////////
582 //                                                582 //
583 // GetEntityType                                  583 // GetEntityType
584 //                                                584 //
585 G4GeometryType G4Tet::GetEntityType() const       585 G4GeometryType G4Tet::GetEntityType() const
586 {                                                 586 {
587   return {"G4Tet"};                            << 587   return G4String("G4Tet");
588 }                                              << 
589                                                << 
590 ////////////////////////////////////////////// << 
591 //                                             << 
592 // IsFaceted                                   << 
593 //                                             << 
594 G4bool G4Tet::IsFaceted() const                << 
595 {                                              << 
596   return true;                                 << 
597 }                                                 588 }
598                                                   589 
599 //////////////////////////////////////////////    590 ////////////////////////////////////////////////////////////////////////
600 //                                                591 //
601 // Make a clone of the object                     592 // Make a clone of the object
602 //                                                593 //
603 G4VSolid* G4Tet::Clone() const                    594 G4VSolid* G4Tet::Clone() const
604 {                                                 595 {
605   return new G4Tet(*this);                        596   return new G4Tet(*this);
606 }                                                 597 }
607                                                   598 
608 //////////////////////////////////////////////    599 ////////////////////////////////////////////////////////////////////////
609 //                                                600 //
610 // Stream object contents to an output stream     601 // Stream object contents to an output stream
611 //                                                602 //
612 std::ostream& G4Tet::StreamInfo(std::ostream&     603 std::ostream& G4Tet::StreamInfo(std::ostream& os) const
613 {                                                 604 {
614   G4long oldprc = os.precision(16);               605   G4long oldprc = os.precision(16);
615   os << "-------------------------------------    606   os << "-----------------------------------------------------------\n"
616      << "    *** Dump for solid - " << GetName    607      << "    *** Dump for solid - " << GetName() << " ***\n"
617      << "    =================================    608      << "    ===================================================\n"
618      << " Solid type: " << GetEntityType() <<     609      << " Solid type: " << GetEntityType() << "\n"
619      << " Parameters: \n"                         610      << " Parameters: \n"
620      << "    anchor: " << fVertex[0]/mm << " m    611      << "    anchor: " << fVertex[0]/mm << " mm\n"
621      << "    p1    : " << fVertex[1]/mm << " m    612      << "    p1    : " << fVertex[1]/mm << " mm\n"
622      << "    p2    : " << fVertex[2]/mm << " m    613      << "    p2    : " << fVertex[2]/mm << " mm\n"
623      << "    p3    : " << fVertex[3]/mm << " m    614      << "    p3    : " << fVertex[3]/mm << " mm\n"
624      << "-------------------------------------    615      << "-----------------------------------------------------------\n";
625   os.precision(oldprc);                           616   os.precision(oldprc);
626   return os;                                      617   return os;
627 }                                                 618 }
628                                                   619 
629 //////////////////////////////////////////////    620 ////////////////////////////////////////////////////////////////////////
630 //                                                621 //
631 // Return random point on the surface             622 // Return random point on the surface
632 //                                                623 //
633 G4ThreeVector G4Tet::GetPointOnSurface() const    624 G4ThreeVector G4Tet::GetPointOnSurface() const
634 {                                                 625 {
635   constexpr G4int iface[4][3] = { {0,1,2}, {0,    626   constexpr G4int iface[4][3] = { {0,1,2}, {0,2,3}, {0,3,1}, {1,2,3} };
636                                                   627 
637   // Select face                                  628   // Select face
638   G4double select = fSurfaceArea*G4QuickRand()    629   G4double select = fSurfaceArea*G4QuickRand();
639   G4int i = 0;                                    630   G4int i = 0;
640   i += (G4int)(select > fArea[0]);             << 631   for ( ; i < 4; ++i) { if ((select -= fArea[i]) <= 0.) break; }
641   i += (G4int)(select > fArea[0] + fArea[1]);  << 
642   i += (G4int)(select > fArea[0] + fArea[1] +  << 
643                                                   632 
644   // Set selected triangle                        633   // Set selected triangle
645   G4ThreeVector p0 = fVertex[iface[i][0]];        634   G4ThreeVector p0 = fVertex[iface[i][0]];
646   G4ThreeVector e1 = fVertex[iface[i][1]] - p0    635   G4ThreeVector e1 = fVertex[iface[i][1]] - p0;
647   G4ThreeVector e2 = fVertex[iface[i][2]] - p0    636   G4ThreeVector e2 = fVertex[iface[i][2]] - p0;
648                                                   637 
649   // Return random point                          638   // Return random point
650   G4double r1 = G4QuickRand();                    639   G4double r1 = G4QuickRand();
651   G4double r2 = G4QuickRand();                    640   G4double r2 = G4QuickRand();
652   return (r1 + r2 > 1.) ?                         641   return (r1 + r2 > 1.) ?
653     p0 + e1*(1. - r1) + e2*(1. - r2) : p0 + e1    642     p0 + e1*(1. - r1) + e2*(1. - r2) : p0 + e1*r1 + e2*r2;
654 }                                                 643 }
655                                                   644 
656 //////////////////////////////////////////////    645 ////////////////////////////////////////////////////////////////////////
657 //                                                646 //
658 // Return volume of the tetrahedron               647 // Return volume of the tetrahedron
659 //                                                648 //
660 G4double G4Tet::GetCubicVolume()                  649 G4double G4Tet::GetCubicVolume()
661 {                                                 650 {
662   return fCubicVolume;                            651   return fCubicVolume;
663 }                                                 652 }
664                                                   653 
665 //////////////////////////////////////////////    654 ////////////////////////////////////////////////////////////////////////
666 //                                                655 //
667 // Return surface area of the tetrahedron         656 // Return surface area of the tetrahedron
668 //                                                657 //
669 G4double G4Tet::GetSurfaceArea()                  658 G4double G4Tet::GetSurfaceArea()
670 {                                                 659 {
671   return fSurfaceArea;                            660   return fSurfaceArea;
672 }                                                 661 }
673                                                   662 
674 //////////////////////////////////////////////    663 ////////////////////////////////////////////////////////////////////////
675 //                                                664 //
676 // Methods for visualisation                      665 // Methods for visualisation
677 //                                                666 //
678 void G4Tet::DescribeYourselfTo (G4VGraphicsSce    667 void G4Tet::DescribeYourselfTo (G4VGraphicsScene& scene) const
679 {                                                 668 {
680   scene.AddSolid (*this);                         669   scene.AddSolid (*this);
681 }                                                 670 }
682                                                   671 
683 //////////////////////////////////////////////    672 ////////////////////////////////////////////////////////////////////////
684 //                                                673 //
685 // Return VisExtent                               674 // Return VisExtent
686 //                                                675 //
687 G4VisExtent G4Tet::GetExtent() const              676 G4VisExtent G4Tet::GetExtent() const
688 {                                                 677 {
689   return { fBmin.x(), fBmax.x(),               << 678   return G4VisExtent(fBmin.x(), fBmax.x(),
690            fBmin.y(), fBmax.y(),               << 679                      fBmin.y(), fBmax.y(),
691            fBmin.z(), fBmax.z() };             << 680                      fBmin.z(), fBmax.z());
692 }                                                 681 }
693                                                   682 
694 //////////////////////////////////////////////    683 ////////////////////////////////////////////////////////////////////////
695 //                                                684 //
696 // CreatePolyhedron                               685 // CreatePolyhedron
697 //                                                686 //
698 G4Polyhedron* G4Tet::CreatePolyhedron() const     687 G4Polyhedron* G4Tet::CreatePolyhedron() const
699 {                                                 688 {
700   // Check orientation of vertices                689   // Check orientation of vertices
701   G4ThreeVector v1 = fVertex[1] - fVertex[0];     690   G4ThreeVector v1 = fVertex[1] - fVertex[0];
702   G4ThreeVector v2 = fVertex[2] - fVertex[0];     691   G4ThreeVector v2 = fVertex[2] - fVertex[0];
703   G4ThreeVector v3 = fVertex[3] - fVertex[0];     692   G4ThreeVector v3 = fVertex[3] - fVertex[0];
704   G4bool invert = v1.cross(v2).dot(v3) < 0.;      693   G4bool invert = v1.cross(v2).dot(v3) < 0.;
705   G4int k2 = (invert) ? 3 : 2;                    694   G4int k2 = (invert) ? 3 : 2;
706   G4int k3 = (invert) ? 2 : 3;                    695   G4int k3 = (invert) ? 2 : 3;
707                                                   696 
708   // Set coordinates of vertices                  697   // Set coordinates of vertices
709   G4double xyz[4][3];                             698   G4double xyz[4][3];
710   for (G4int i = 0; i < 3; ++i)                   699   for (G4int i = 0; i < 3; ++i)
711   {                                               700   {
712     xyz[0][i] = fVertex[0][i];                    701     xyz[0][i] = fVertex[0][i];
713     xyz[1][i] = fVertex[1][i];                    702     xyz[1][i] = fVertex[1][i];
714     xyz[2][i] = fVertex[k2][i];                   703     xyz[2][i] = fVertex[k2][i];
715     xyz[3][i] = fVertex[k3][i];                   704     xyz[3][i] = fVertex[k3][i];
716   }                                               705   }
717                                                   706 
718   // Create polyhedron                            707   // Create polyhedron
719   G4int faces[4][4] = { {1,3,2,0}, {1,4,3,0},     708   G4int faces[4][4] = { {1,3,2,0}, {1,4,3,0}, {1,2,4,0}, {2,3,4,0} };
720   auto  ph = new G4Polyhedron;                 << 709   G4Polyhedron* ph = new G4Polyhedron;
721   ph->createPolyhedron(4,4,xyz,faces);            710   ph->createPolyhedron(4,4,xyz,faces);
722                                                   711 
723   return ph;                                      712   return ph;
724 }                                                 713 }
725                                                   714 
726 //////////////////////////////////////////////    715 ////////////////////////////////////////////////////////////////////////
727 //                                                716 //
728 // GetPolyhedron                                  717 // GetPolyhedron
729 //                                                718 //
730 G4Polyhedron* G4Tet::GetPolyhedron() const        719 G4Polyhedron* G4Tet::GetPolyhedron() const
731 {                                                 720 {
732   if (fpPolyhedron == nullptr ||                  721   if (fpPolyhedron == nullptr ||
733       fRebuildPolyhedron ||                       722       fRebuildPolyhedron ||
734       fpPolyhedron->GetNumberOfRotationStepsAt    723       fpPolyhedron->GetNumberOfRotationStepsAtTimeOfCreation() !=
735       fpPolyhedron->GetNumberOfRotationSteps()    724       fpPolyhedron->GetNumberOfRotationSteps())
736   {                                               725   {
737     G4AutoLock l(&polyhedronMutex);               726     G4AutoLock l(&polyhedronMutex);
738     delete fpPolyhedron;                          727     delete fpPolyhedron;
739     fpPolyhedron = CreatePolyhedron();            728     fpPolyhedron = CreatePolyhedron();
740     fRebuildPolyhedron = false;                   729     fRebuildPolyhedron = false;
741     l.unlock();                                   730     l.unlock();
742   }                                               731   }
743   return fpPolyhedron;                            732   return fpPolyhedron;
744 }                                                 733 }
745                                                   734 
746 #endif                                            735 #endif
747                                                   736