Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/geometry/solids/CSG/src/G4Box.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/CSG/src/G4Box.cc (Version 11.3.0) and /geometry/solids/CSG/src/G4Box.cc (Version 5.2)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                    <<   3 // * DISCLAIMER                                                       *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th <<   5 // * The following disclaimer summarizes all the specific disclaimers *
  6 // * the Geant4 Collaboration.  It is provided <<   6 // * of contributors to this software. The specific disclaimers,which *
  7 // * conditions of the Geant4 Software License <<   7 // * govern, are listed with their locations in:                      *
  8 // * LICENSE and available at  http://cern.ch/ <<   8 // *   http://cern.ch/geant4/license                                  *
  9 // * include a list of copyright holders.      << 
 10 // *                                                9 // *                                                                  *
 11 // * Neither the authors of this software syst     10 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     11 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     12 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     13 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file  <<  14 // * use.                                                             *
 16 // * for the full disclaimer and the limitatio << 
 17 // *                                               15 // *                                                                  *
 18 // * This  code  implementation is the result  <<  16 // * This  code  implementation is the  intellectual property  of the *
 19 // * technical work of the GEANT4 collaboratio <<  17 // * GEANT4 collaboration.                                            *
 20 // * By using,  copying,  modifying or  distri <<  18 // * By copying,  distributing  or modifying the Program (or any work *
 21 // * any work based  on the software)  you  ag <<  19 // * based  on  the Program)  you indicate  your  acceptance of  this *
 22 // * use  in  resulting  scientific  publicati <<  20 // * statement, and all its terms.                                    *
 23 // * acceptance of all terms of the Geant4 Sof << 
 24 // *******************************************     21 // ********************************************************************
 25 //                                                 22 //
                                                   >>  23 //
                                                   >>  24 // $Id: G4Box.cc,v 1.20 2003/06/16 16:53:34 gunter Exp $
                                                   >>  25 // GEANT4 tag $Name: geant4-05-02 $
                                                   >>  26 //
                                                   >>  27 // 
                                                   >>  28 //
 26 // Implementation for G4Box class                  29 // Implementation for G4Box class
 27 //                                                 30 //
 28 //  30.06.95 - P.Kent: First version           <<  31 //  24.06.98 - V. Grichine: insideEdge in DistanceToIn(p,v)
 29 //  20.09.98 - V.Grichine: new algorithm of Di     32 //  20.09.98 - V.Grichine: new algorithm of DistanceToIn(p,v)
 30 //  18.04.17 - E.Tcherniaev: complete revision <<  33 //  07.05.00 - V.Grichine: d= DistanceToIn(p,v), if d<e/2, d=0
 31 // ------------------------------------------- <<  34 //  09.06.00 - V.Grichine: safety in DistanceToIn(p) against Inside(p)=kOutside
                                                   >>  35 //             and information before exception in DistanceToOut(p,v,...)
                                                   >>  36 //  15.11.00 - D.Williams, V.Grichine: bug fixed in CalculateExtent - change
                                                   >>  37 //                                     algorithm for rotated vertices
                                                   >>  38 // ********************************************************************
 32                                                    39 
 33 #include "G4Box.hh"                                40 #include "G4Box.hh"
 34                                                    41 
 35 #if !defined(G4GEOM_USE_UBOX)                  << 
 36                                                << 
 37 #include "G4SystemOfUnits.hh"                  << 
 38 #include "G4VoxelLimits.hh"                        42 #include "G4VoxelLimits.hh"
 39 #include "G4AffineTransform.hh"                    43 #include "G4AffineTransform.hh"
 40 #include "G4BoundingEnvelope.hh"               << 
 41 #include "G4QuickRand.hh"                      << 
 42                                                    44 
 43 #include "G4VPVParameterisation.hh"                45 #include "G4VPVParameterisation.hh"
 44                                                    46 
 45 #include "G4VGraphicsScene.hh"                     47 #include "G4VGraphicsScene.hh"
                                                   >>  48 #include "G4Polyhedron.hh"
                                                   >>  49 #include "G4NURBS.hh"
                                                   >>  50 #include "G4NURBSbox.hh"
 46 #include "G4VisExtent.hh"                          51 #include "G4VisExtent.hh"
 47                                                    52 
 48 //////////////////////////////////////////////     53 ////////////////////////////////////////////////////////////////////////
 49 //                                                 54 //
 50 // Constructor - check & set half widths           55 // Constructor - check & set half widths
 51                                                    56 
 52 G4Box::G4Box(const G4String& pName,                57 G4Box::G4Box(const G4String& pName,
 53                    G4double pX,                    58                    G4double pX,
 54                    G4double pY,                    59                    G4double pY,
 55                    G4double pZ)                    60                    G4double pZ)
 56   : G4CSGSolid(pName), fDx(pX), fDy(pY), fDz(p <<  61   : G4CSGSolid(pName)
 57 {                                                  62 {
 58   delta = 0.5*kCarTolerance;                   <<  63   if ( (pX > 2*kCarTolerance)
 59   if (pX < 2*kCarTolerance ||                  <<  64     && (pY > 2*kCarTolerance)
 60       pY < 2*kCarTolerance ||                  <<  65     && (pZ > 2*kCarTolerance) )
 61       pZ < 2*kCarTolerance)  // limit to thick <<  66   {
 62   {                                            <<  67     fDx = pX ;
 63     std::ostringstream message;                <<  68     fDy = pY ; 
 64     message << "Dimensions too small for Solid <<  69     fDz = pZ ;
 65             << "     hX, hY, hZ = " << pX << " <<  70   }
 66     G4Exception("G4Box::G4Box()", "GeomSolids0 <<  71   else
                                                   >>  72   {
                                                   >>  73     G4cout << "ERROR - G4Box()::G4Box(): " << GetName() << G4endl
                                                   >>  74            << "        Dimensions too small ! - "
                                                   >>  75            << pX << ", " << pY << ", " << pZ << G4endl;
                                                   >>  76     G4cerr << "ERROR - G4Box()::G4Box(): " << GetName() << G4endl
                                                   >>  77            << "        Dimensions too small ! - "
                                                   >>  78            << pX << ", " << pY << ", " << pZ << G4endl;
                                                   >>  79     G4Exception("G4Box::G4Box() - invalid dimensions");
 67   }                                                80   }
 68 }                                              << 
 69                                                << 
 70 ////////////////////////////////////////////// << 
 71 //                                             << 
 72 // Fake default constructor - sets only member << 
 73 //                            for usage restri << 
 74                                                << 
 75 G4Box::G4Box( __void__& a )                    << 
 76   : G4CSGSolid(a)                              << 
 77 {                                              << 
 78 }                                                  81 }
 79                                                    82 
 80 //////////////////////////////////////////////     83 //////////////////////////////////////////////////////////////////////////
 81 //                                                 84 //
 82 // Destructor                                      85 // Destructor
 83                                                    86 
 84 G4Box::~G4Box() = default;                     <<  87 G4Box::~G4Box()
 85                                                << 
 86 ////////////////////////////////////////////// << 
 87 //                                             << 
 88 // Copy constructor                            << 
 89                                                << 
 90 G4Box::G4Box(const G4Box&) = default;          << 
 91                                                << 
 92 ////////////////////////////////////////////// << 
 93 //                                             << 
 94 // Assignment operator                         << 
 95                                                << 
 96 G4Box& G4Box::operator = (const G4Box& rhs)    << 
 97 {                                                  88 {
 98    // Check assignment to self                 << 
 99    //                                          << 
100    if (this == &rhs)  { return *this; }        << 
101                                                << 
102    // Copy base class data                     << 
103    //                                          << 
104    G4CSGSolid::operator=(rhs);                 << 
105                                                << 
106    // Copy data                                << 
107    //                                          << 
108    fDx = rhs.fDx;                              << 
109    fDy = rhs.fDy;                              << 
110    fDz = rhs.fDz;                              << 
111    delta = rhs.delta;                          << 
112                                                << 
113    return *this;                               << 
114 }                                                  89 }
115                                                    90 
116 ////////////////////////////////////////////// <<  91 //////////////////////////////////////////////////////////////////////////////
117 //                                             << 
118 //  Set X dimension                            << 
119                                                    92 
120 void G4Box::SetXHalfLength(G4double dx)            93 void G4Box::SetXHalfLength(G4double dx)
121 {                                                  94 {
122   if(dx > 2*kCarTolerance)  // limit to thickn <<  95   if(dx > 2*kCarTolerance)
123   {                                            << 
124     fDx = dx;                                      96     fDx = dx;
125   }                                            << 
126   else                                             97   else
127   {                                                98   {
128     std::ostringstream message;                <<  99     G4cout << "ERROR - G4Box()::SetXHalfLength(): " << GetName() << G4endl
129     message << "Dimension X too small for soli << 100            << "        Dimension X too small ! - "
130             << G4endl                          << 101            << dx << G4endl;
131             << "       hX = " << dx;           << 102     G4cerr << "ERROR - G4Box()::SetXHalfLength(): " << GetName() << G4endl
132     G4Exception("G4Box::SetXHalfLength()", "Ge << 103            << "        Dimension X too small ! - "
133                 FatalException, message);      << 104            << dx << G4endl;
134   }                                            << 105     G4Exception("G4Box::SetXHalfLength() - invalid dimensions");
135   fCubicVolume = 0.;                           << 106   }
136   fSurfaceArea = 0.;                           << 107 } 
137   fRebuildPolyhedron = true;                   << 
138 }                                              << 
139                                                << 
140 ////////////////////////////////////////////// << 
141 //                                             << 
142 //  Set Y dimension                            << 
143                                                   108 
144 void G4Box::SetYHalfLength(G4double dy)        << 109 void G4Box::SetYHalfLength(G4double dy) 
145 {                                                 110 {
146   if(dy > 2*kCarTolerance)  // limit to thickn << 111   if(dy > 2*kCarTolerance)
147   {                                            << 
148     fDy = dy;                                     112     fDy = dy;
149   }                                            << 
150   else                                            113   else
151   {                                               114   {
152     std::ostringstream message;                << 115     G4cout << "ERROR - G4Box()::SetYHalfLength(): " << GetName() << G4endl
153     message << "Dimension Y too small for soli << 116            << "        Dimension Y too small ! - "
154             << "       hY = " << dy;           << 117            << dy << G4endl;
155     G4Exception("G4Box::SetYHalfLength()", "Ge << 118     G4cerr << "ERROR - G4Box()::SetYHalfLength(): " << GetName() << G4endl
156                 FatalException, message);      << 119            << "        Dimension Y too small ! - "
157   }                                            << 120            << dy << G4endl;
158   fCubicVolume = 0.;                           << 121     G4Exception("G4Box::SetYHalfLength() - invalid dimensions");
159   fSurfaceArea = 0.;                           << 122   }
160   fRebuildPolyhedron = true;                   << 123 } 
161 }                                              << 
162                                                << 
163 ////////////////////////////////////////////// << 
164 //                                             << 
165 //  Set Z dimension                            << 
166                                                   124 
167 void G4Box::SetZHalfLength(G4double dz)        << 125 void G4Box::SetZHalfLength(G4double dz) 
168 {                                                 126 {
169   if(dz > 2*kCarTolerance)  // limit to thickn << 127   if(dz > 2*kCarTolerance)
170   {                                            << 
171     fDz = dz;                                     128     fDz = dz;
172   }                                            << 
173   else                                            129   else
174   {                                               130   {
175     std::ostringstream message;                << 131     G4cout << "ERROR - G4Box()::SetZHalfLength(): " << GetName() << G4endl
176     message << "Dimension Z too small for soli << 132            << "        Dimension Z too small ! - "
177             << "       hZ = " << dz;           << 133            << dz << G4endl;
178     G4Exception("G4Box::SetZHalfLength()", "Ge << 134     G4cerr << "ERROR - G4Box()::SetZHalfLength(): " << GetName() << G4endl
179                 FatalException, message);      << 135            << "        Dimension Z too small ! - "
180   }                                            << 136            << dz << G4endl;
181   fCubicVolume = 0.;                           << 137     G4Exception("G4Box::SetZHalfLength() - invalid dimensions");
182   fSurfaceArea = 0.;                           << 138   }
183   fRebuildPolyhedron = true;                   << 139 } 
184 }                                              << 140     
185                                                   141 
186 ////////////////////////////////////////////// << 142 
                                                   >> 143 ////////////////////////////////////////////////////////////////////////
187 //                                                144 //
188 // Dispatch to parameterisation for replicatio    145 // Dispatch to parameterisation for replication mechanism dimension
189 // computation & modification.                    146 // computation & modification.
190                                                   147 
191 void G4Box::ComputeDimensions(G4VPVParameteris    148 void G4Box::ComputeDimensions(G4VPVParameterisation* p,
192                               const G4int n,      149                               const G4int n,
193                               const G4VPhysica    150                               const G4VPhysicalVolume* pRep)
194 {                                                 151 {
195   p->ComputeDimensions(*this,n,pRep);             152   p->ComputeDimensions(*this,n,pRep);
196 }                                                 153 }
197                                                   154 
198 //////////////////////////////////////////////    155 //////////////////////////////////////////////////////////////////////////
199 //                                                156 //
200 // Get bounding box                            << 
201                                                << 
202 void G4Box::BoundingLimits(G4ThreeVector& pMin << 
203 {                                              << 
204   pMin.set(-fDx,-fDy,-fDz);                    << 
205   pMax.set( fDx, fDy, fDz);                    << 
206                                                << 
207   // Check correctness of the bounding box     << 
208   //                                           << 
209   if (pMin.x() >= pMax.x() || pMin.y() >= pMax << 
210   {                                            << 
211     std::ostringstream message;                << 
212     message << "Bad bounding box (min >= max)  << 
213             << GetName() << " !"               << 
214             << "\npMin = " << pMin             << 
215             << "\npMax = " << pMax;            << 
216     G4Exception("G4Box::BoundingLimits()", "Ge << 
217     DumpInfo();                                << 
218   }                                            << 
219 }                                              << 
220                                                << 
221 ////////////////////////////////////////////// << 
222 //                                             << 
223 // Calculate extent under transform and specif    157 // Calculate extent under transform and specified limit
224                                                   158 
225 G4bool G4Box::CalculateExtent(const EAxis pAxi    159 G4bool G4Box::CalculateExtent(const EAxis pAxis,
226                               const G4VoxelLim    160                               const G4VoxelLimits& pVoxelLimit,
227                               const G4AffineTr    161                               const G4AffineTransform& pTransform,
228                                     G4double&     162                                     G4double& pMin, G4double& pMax) const
229 {                                                 163 {
230   G4ThreeVector bmin, bmax;                    << 164   if (!pTransform.IsRotated())
                                                   >> 165   {
                                                   >> 166     // Special case handling for unrotated boxes
                                                   >> 167     // Compute x/y/z mins and maxs respecting limits, with early returns
                                                   >> 168     // if outside limits. Then switch() on pAxis
231                                                   169 
232   // Get bounding box                          << 170     G4double xoffset,xMin,xMax;
233   BoundingLimits(bmin,bmax);                   << 171     G4double yoffset,yMin,yMax;
                                                   >> 172     G4double zoffset,zMin,zMax;
234                                                   173 
235   // Find extent                               << 174     xoffset = pTransform.NetTranslation().x() ;
236   G4BoundingEnvelope bbox(bmin,bmax);          << 175     xMin    = xoffset - fDx ;
237   return bbox.CalculateExtent(pAxis,pVoxelLimi << 176     xMax    = xoffset + fDx ;
238 }                                              << 
239                                                   177 
240 ////////////////////////////////////////////// << 178     if (pVoxelLimit.IsXLimited())
                                                   >> 179     {
                                                   >> 180       if ( xMin > pVoxelLimit.GetMaxXExtent()+kCarTolerance || 
                                                   >> 181            xMax < pVoxelLimit.GetMinXExtent()-kCarTolerance    ) return false ;
                                                   >> 182       else
                                                   >> 183       {
                                                   >> 184         if (xMin < pVoxelLimit.GetMinXExtent())
                                                   >> 185         {
                                                   >> 186           xMin = pVoxelLimit.GetMinXExtent() ;
                                                   >> 187         }
                                                   >> 188         if (xMax > pVoxelLimit.GetMaxXExtent())
                                                   >> 189         {
                                                   >> 190           xMax = pVoxelLimit.GetMaxXExtent() ;
                                                   >> 191         }
                                                   >> 192       }
                                                   >> 193     }
                                                   >> 194     yoffset = pTransform.NetTranslation().y() ;
                                                   >> 195     yMin    = yoffset - fDy ;
                                                   >> 196     yMax    = yoffset + fDy ;
                                                   >> 197 
                                                   >> 198     if (pVoxelLimit.IsYLimited())
                                                   >> 199     {
                                                   >> 200       if ( yMin > pVoxelLimit.GetMaxYExtent()+kCarTolerance ||
                                                   >> 201            yMax < pVoxelLimit.GetMinYExtent()-kCarTolerance   ) return false ;
                                                   >> 202       else
                                                   >> 203       {
                                                   >> 204         if (yMin < pVoxelLimit.GetMinYExtent())
                                                   >> 205         {
                                                   >> 206           yMin = pVoxelLimit.GetMinYExtent() ;
                                                   >> 207         }
                                                   >> 208         if (yMax > pVoxelLimit.GetMaxYExtent())
                                                   >> 209         {
                                                   >> 210           yMax = pVoxelLimit.GetMaxYExtent() ;
                                                   >> 211         }
                                                   >> 212       }
                                                   >> 213     }
                                                   >> 214     zoffset = pTransform.NetTranslation().z() ;
                                                   >> 215     zMin    = zoffset - fDz ;
                                                   >> 216     zMax    = zoffset + fDz ;
                                                   >> 217 
                                                   >> 218     if (pVoxelLimit.IsZLimited())
                                                   >> 219     {
                                                   >> 220       if ( zMin > pVoxelLimit.GetMaxZExtent()+kCarTolerance ||
                                                   >> 221            zMax < pVoxelLimit.GetMinZExtent()-kCarTolerance   ) return false ;
                                                   >> 222       else
                                                   >> 223       {
                                                   >> 224         if (zMin < pVoxelLimit.GetMinZExtent())
                                                   >> 225         {
                                                   >> 226           zMin = pVoxelLimit.GetMinZExtent() ;
                                                   >> 227         }
                                                   >> 228         if (zMax > pVoxelLimit.GetMaxZExtent())
                                                   >> 229         {
                                                   >> 230           zMax = pVoxelLimit.GetMaxZExtent() ;
                                                   >> 231         }
                                                   >> 232       }
                                                   >> 233     }
                                                   >> 234     switch (pAxis)
                                                   >> 235     {
                                                   >> 236       case kXAxis:
                                                   >> 237         pMin = xMin ;
                                                   >> 238         pMax = xMax ;
                                                   >> 239         break ;
                                                   >> 240       case kYAxis:
                                                   >> 241         pMin=yMin;
                                                   >> 242         pMax=yMax;
                                                   >> 243         break;
                                                   >> 244       case kZAxis:
                                                   >> 245         pMin=zMin;
                                                   >> 246         pMax=zMax;
                                                   >> 247         break;
                                                   >> 248       default:
                                                   >> 249         break;
                                                   >> 250     }
                                                   >> 251     pMin -= kCarTolerance ;
                                                   >> 252     pMax += kCarTolerance ;
                                                   >> 253 
                                                   >> 254     return true;
                                                   >> 255   }
                                                   >> 256   else  // General rotated case - create and clip mesh to boundaries
                                                   >> 257   {
                                                   >> 258     G4bool existsAfterClip = false ;
                                                   >> 259     G4ThreeVectorList* vertices ;
                                                   >> 260 
                                                   >> 261     pMin = +kInfinity ;
                                                   >> 262     pMax = -kInfinity ;
                                                   >> 263 
                                                   >> 264     // Calculate rotated vertex coordinates
                                                   >> 265 
                                                   >> 266     vertices = CreateRotatedVertices(pTransform) ;
                                                   >> 267     ClipCrossSection(vertices,0,pVoxelLimit,pAxis,pMin,pMax) ;
                                                   >> 268     ClipCrossSection(vertices,4,pVoxelLimit,pAxis,pMin,pMax) ;
                                                   >> 269     ClipBetweenSections(vertices,0,pVoxelLimit,pAxis,pMin,pMax) ;
                                                   >> 270 
                                                   >> 271     if (pVoxelLimit.IsLimited(pAxis) == false) 
                                                   >> 272     {  
                                                   >> 273       if ( pMin != kInfinity || pMax != -kInfinity ) 
                                                   >> 274       {
                                                   >> 275         existsAfterClip = true ;
                                                   >> 276 
                                                   >> 277         // Add 2*tolerance to avoid precision troubles
                                                   >> 278 
                                                   >> 279         pMin           -= kCarTolerance;
                                                   >> 280         pMax           += kCarTolerance;
                                                   >> 281       }
                                                   >> 282     }      
                                                   >> 283     else
                                                   >> 284     {
                                                   >> 285       G4ThreeVector clipCentre(
                                                   >> 286        ( pVoxelLimit.GetMinXExtent()+pVoxelLimit.GetMaxXExtent())*0.5,
                                                   >> 287        ( pVoxelLimit.GetMinYExtent()+pVoxelLimit.GetMaxYExtent())*0.5,
                                                   >> 288        ( pVoxelLimit.GetMinZExtent()+pVoxelLimit.GetMaxZExtent())*0.5);
                                                   >> 289 
                                                   >> 290       if ( pMin != kInfinity || pMax != -kInfinity )
                                                   >> 291       {
                                                   >> 292         existsAfterClip = true ;
                                                   >> 293   
                                                   >> 294 
                                                   >> 295         // Check to see if endpoints are in the solid
                                                   >> 296 
                                                   >> 297         clipCentre(pAxis) = pVoxelLimit.GetMinExtent(pAxis);
                                                   >> 298 
                                                   >> 299         if (Inside(pTransform.Inverse().TransformPoint(clipCentre)) != kOutside)
                                                   >> 300         {
                                                   >> 301           pMin = pVoxelLimit.GetMinExtent(pAxis);
                                                   >> 302         }
                                                   >> 303         else
                                                   >> 304         {
                                                   >> 305           pMin -= kCarTolerance;
                                                   >> 306         }
                                                   >> 307         clipCentre(pAxis) = pVoxelLimit.GetMaxExtent(pAxis);
                                                   >> 308 
                                                   >> 309         if (Inside(pTransform.Inverse().TransformPoint(clipCentre)) != kOutside)
                                                   >> 310         {
                                                   >> 311           pMax = pVoxelLimit.GetMaxExtent(pAxis);
                                                   >> 312         }
                                                   >> 313         else
                                                   >> 314         {
                                                   >> 315           pMax += kCarTolerance;
                                                   >> 316         }
                                                   >> 317       }
                                                   >> 318 
                                                   >> 319       // Check for case where completely enveloping clipping volume
                                                   >> 320       // If point inside then we are confident that the solid completely
                                                   >> 321       // envelopes the clipping volume. Hence set min/max extents according
                                                   >> 322       // to clipping volume extents along the specified axis.
                                                   >> 323         
                                                   >> 324       else if (Inside(pTransform.Inverse().TransformPoint(clipCentre))
                                                   >> 325                       != kOutside)
                                                   >> 326       {
                                                   >> 327         existsAfterClip = true ;
                                                   >> 328         pMin            = pVoxelLimit.GetMinExtent(pAxis) ;
                                                   >> 329         pMax            = pVoxelLimit.GetMaxExtent(pAxis) ;
                                                   >> 330       }
                                                   >> 331     } 
                                                   >> 332     delete vertices;
                                                   >> 333     return existsAfterClip;
                                                   >> 334   } 
                                                   >> 335 } 
                                                   >> 336 
                                                   >> 337 /////////////////////////////////////////////////////////////////////////
241 //                                                338 //
242 // Return whether point inside/outside/on surf    339 // Return whether point inside/outside/on surface, using tolerance
243                                                   340 
244 EInside G4Box::Inside(const G4ThreeVector& p)     341 EInside G4Box::Inside(const G4ThreeVector& p) const
245 {                                                 342 {
246   G4double dist = std::max(std::max(           << 343   EInside in = kOutside ;
247                   std::abs(p.x())-fDx,         << 
248                   std::abs(p.y())-fDy),        << 
249                   std::abs(p.z())-fDz);        << 
250   return (dist > delta) ? kOutside :           << 
251     ((dist > -delta) ? kSurface : kInside);    << 
252 }                                              << 
253                                                   344 
254 ////////////////////////////////////////////// << 345   if ( fabs(p.x()) <= fDx - kCarTolerance*0.5 )
255 //                                             << 
256 // Detect the side(s) and return corresponding << 
257                                                << 
258 G4ThreeVector G4Box::SurfaceNormal( const G4Th << 
259 {                                              << 
260   G4ThreeVector norm(0,0,0);                   << 
261   G4double px = p.x();                         << 
262   if (std::abs(std::abs(px) - fDx) <= delta) n << 
263   G4double py = p.y();                         << 
264   if (std::abs(std::abs(py) - fDy) <= delta) n << 
265   G4double pz = p.z();                         << 
266   if (std::abs(std::abs(pz) - fDz) <= delta) n << 
267                                                << 
268   G4double nside = norm.mag2(); // number of s << 
269   if (nside == 1)                              << 
270     return norm;                               << 
271   else if (nside > 1)                          << 
272     return norm.unit(); // edge or corner      << 
273   else                                         << 
274   {                                               346   {
275     // Point is not on the surface             << 347     if (fabs(p.y()) <= fDy - kCarTolerance*0.5 )
276     //                                         << 348     {
277 #ifdef G4CSGDEBUG                              << 349       if      (fabs(p.z()) <= fDz - kCarTolerance*0.5 ) in = kInside ;
278     std::ostringstream message;                << 350       else if (fabs(p.z()) <= fDz + kCarTolerance*0.5 ) in = kSurface ;
279     G4int oldprc = message.precision(16);      << 351     }
280     message << "Point p is not on surface (!?) << 352     else if (fabs(p.y()) <= fDy + kCarTolerance*0.5 )
281             << GetName() << G4endl;            << 353     {
282     message << "Position:\n";                  << 354       if (fabs(p.z()) <= fDz + kCarTolerance*0.5 ) in = kSurface ;
283     message << "   p.x() = " << p.x()/mm << "  << 355     }
284     message << "   p.y() = " << p.y()/mm << "  << 
285     message << "   p.z() = " << p.z()/mm << "  << 
286     G4cout.precision(oldprc);                  << 
287     G4Exception("G4Box::SurfaceNormal(p)", "Ge << 
288                 JustWarning, message );        << 
289     DumpInfo();                                << 
290 #endif                                         << 
291     return ApproxSurfaceNormal(p);             << 
292   }                                               356   }
                                                   >> 357   else if (fabs(p.x()) <= fDx + kCarTolerance*0.5 )
                                                   >> 358   {
                                                   >> 359     if (fabs(p.y()) <= fDy + kCarTolerance*0.5 )
                                                   >> 360     {
                                                   >> 361       if (fabs(p.z()) <= fDz + kCarTolerance*0.5) in = kSurface ;
                                                   >> 362     }
                                                   >> 363   }
                                                   >> 364   return in ;
293 }                                                 365 }
294                                                   366 
295 ////////////////////////////////////////////// << 367 ///////////////////////////////////////////////////////////////////////
296 //                                                368 //
297 // Algorithm for SurfaceNormal() following the << 369 // Calculate side nearest to p, and return normal
298 // for points not on the surface               << 370 // If two sides are equidistant, normal of first side (x/y/z) 
                                                   >> 371 // encountered returned
299                                                   372 
300 G4ThreeVector G4Box::ApproxSurfaceNormal(const << 373 G4ThreeVector G4Box::SurfaceNormal( const G4ThreeVector& p) const
301 {                                                 374 {
302   G4double distx = std::abs(p.x()) - fDx;      << 375   G4double distx, disty, distz ;
303   G4double disty = std::abs(p.y()) - fDy;      << 376   G4ThreeVector norm ;
304   G4double distz = std::abs(p.z()) - fDz;      << 377 
305                                                << 378   // Calculate distances as if in 1st octant
306   if (distx >= disty && distx >= distz)        << 379 
307     return {std::copysign(1.,p.x()), 0., 0.};  << 380   distx = fabs(fabs(p.x()) - fDx) ;
308   if (disty >= distx && disty >= distz)        << 381   disty = fabs(fabs(p.y()) - fDy) ;
309     return {0., std::copysign(1.,p.y()), 0.};  << 382   distz = fabs(fabs(p.z()) - fDz) ;
                                                   >> 383 
                                                   >> 384   if ( distx <= disty )
                                                   >> 385   {
                                                   >> 386     if ( distx <= distz )     // Closest to X
                                                   >> 387     {
                                                   >> 388       if ( p.x() < 0 ) norm = G4ThreeVector(-1.0,0,0) ;
                                                   >> 389       else             norm = G4ThreeVector( 1.0,0,0) ;
                                                   >> 390     }
                                                   >> 391     else                      // Closest to Z
                                                   >> 392     {
                                                   >> 393       if ( p.z() < 0 ) norm = G4ThreeVector(0,0,-1.0) ;
                                                   >> 394       else             norm = G4ThreeVector(0,0, 1.0) ;
                                                   >> 395     }
                                                   >> 396   }
310   else                                            397   else
311     return {0., 0., std::copysign(1.,p.z())};  << 398   {
                                                   >> 399     if ( disty <= distz )      // Closest to Y
                                                   >> 400     {
                                                   >> 401       if ( p.y() < 0 ) norm = G4ThreeVector(0,-1.0,0) ;
                                                   >> 402       else             norm = G4ThreeVector(0, 1.0,0) ;
                                                   >> 403     }
                                                   >> 404     else                       // Closest to Z
                                                   >> 405     {
                                                   >> 406       if ( p.z() < 0 ) norm = G4ThreeVector(0,0,-1.0) ;
                                                   >> 407       else             norm = G4ThreeVector(0,0, 1.0) ;
                                                   >> 408     }
                                                   >> 409   }
                                                   >> 410   return norm;
312 }                                                 411 }
313                                                   412 
314 ////////////////////////////////////////////// << 413 ///////////////////////////////////////////////////////////////////////////
315 //                                                414 //
316 // Calculate distance to box from an outside p    415 // Calculate distance to box from an outside point
317 // - return kInfinity if no intersection       << 416 // - return kInfinity if no intersection.
                                                   >> 417 //
                                                   >> 418 // ALGORITHM:
318 //                                                419 //
                                                   >> 420 // Check that if point lies outside x/y/z extent of box, travel is towards
                                                   >> 421 // the box (ie. there is a possibility of an intersection)
                                                   >> 422 //
                                                   >> 423 // Calculate pairs of minimum and maximum distances for x/y/z travel for
                                                   >> 424 // intersection with the box's x/y/z extent.
                                                   >> 425 // If there is a valid intersection, it is given by the maximum min distance
                                                   >> 426 // (ie. distance to satisfy x/y/z intersections) *if* <= minimum max distance
                                                   >> 427 // (ie. distance after which 1+ of x/y/z intersections not satisfied)
                                                   >> 428 //
                                                   >> 429 // NOTE:
                                                   >> 430 //
                                                   >> 431 // `Inside' safe - meaningful answers given if point is inside the exact
                                                   >> 432 // shape.
319                                                   433 
320 G4double G4Box::DistanceToIn(const G4ThreeVect << 434 G4double G4Box::DistanceToIn(const G4ThreeVector& p,const G4ThreeVector& v) const
321                              const G4ThreeVect << 
322 {                                                 435 {
323   // Check if point is on the surface and trav << 436   G4double safx, safy, safz ;
324   //                                           << 437   G4double smin=0.0, sminy, sminz ; // , sminx ;
325   if ((std::abs(p.x()) - fDx) >= -delta && p.x << 438   G4double smax=kInfinity, smaxy, smaxz ; // , smaxx ;  // they always > 0
326   if ((std::abs(p.y()) - fDy) >= -delta && p.y << 439   G4double stmp ;
327   if ((std::abs(p.z()) - fDz) >= -delta && p.z << 440   G4double sOut=kInfinity, sOuty=kInfinity, sOutz=kInfinity ;
328                                                << 441 
329   // Find intersection                         << 442   safx = fabs(p.x()) - fDx ;     // minimum distance to x surface of shape
330   //                                           << 443   safy = fabs(p.y()) - fDy ;
331   G4double invx = (v.x() == 0) ? DBL_MAX : -1. << 444   safz = fabs(p.z()) - fDz ;
332   G4double dx = std::copysign(fDx,invx);       << 445 
333   G4double txmin = (p.x() - dx)*invx;          << 446   // Will we intersect?
334   G4double txmax = (p.x() + dx)*invx;          << 447   // If safx/y/z is >-tol/2 the point is outside/on the box's x/y/z extent.
335                                                << 448   // If both p.x/y/z and v.x/y/z repectively are both positive/negative,
336   G4double invy = (v.y() == 0) ? DBL_MAX : -1. << 449   // travel is in a direction away from the shape.
337   G4double dy = std::copysign(fDy,invy);       << 450 
338   G4double tymin = std::max(txmin,(p.y() - dy) << 451   if (    ((p.x()*v.x() >= 0.0) && safx > -kCarTolerance*0.5) 
339   G4double tymax = std::min(txmax,(p.y() + dy) << 452        || ((p.y()*v.y() >= 0.0) && safy > -kCarTolerance*0.5)
340                                                << 453        || ((p.z()*v.z() >= 0.0) && safz > -kCarTolerance*0.5)   ) 
341   G4double invz = (v.z() == 0) ? DBL_MAX : -1. << 454   {
342   G4double dz = std::copysign(fDz,invz);       << 455     return kInfinity ;  // travel away or parallel within tolerance
343   G4double tmin = std::max(tymin,(p.z() - dz)* << 456   }
344   G4double tmax = std::min(tymax,(p.z() + dz)* << 457 
                                                   >> 458   // Compute min / max distances for x/y/z travel:
                                                   >> 459   // X Planes
                                                   >> 460 
                                                   >> 461   if ( v.x())
                                                   >> 462   {
                                                   >> 463     stmp = 1.0/fabs(v.x()) ;
                                                   >> 464 
                                                   >> 465     if (safx >= 0.0)
                                                   >> 466     {
                                                   >> 467       smin = safx*stmp ;
                                                   >> 468       smax = (fDx+fabs(p.x()))*stmp ;
                                                   >> 469     }
                                                   >> 470     else
                                                   >> 471     {
                                                   >> 472       if (v.x() > 0)  sOut = (fDx - p.x())*stmp ;
                                                   >> 473       if (v.x() < 0)  sOut = (fDx + p.x())*stmp ;
                                                   >> 474     }
                                                   >> 475   }
                                                   >> 476 
                                                   >> 477   // Y Planes
                                                   >> 478 
                                                   >> 479   if ( v.y()) 
                                                   >> 480   {
                                                   >> 481     stmp = 1.0/fabs(v.y()) ;
                                                   >> 482 
                                                   >> 483     if (safy >= 0.0)
                                                   >> 484     {
                                                   >> 485       sminy = safy*stmp ;
                                                   >> 486       smaxy = (fDy+fabs(p.y()))*stmp ;
                                                   >> 487 
                                                   >> 488       if (sminy > smin) smin=sminy ;
                                                   >> 489       if (smaxy < smax) smax=smaxy ;
                                                   >> 490 
                                                   >> 491       if (smin >= smax-kCarTolerance*0.5)
                                                   >> 492       {
                                                   >> 493         return kInfinity ;  // touch XY corner
                                                   >> 494       }
                                                   >> 495     }
                                                   >> 496     else
                                                   >> 497     {
                                                   >> 498       if (v.y() > 0)  sOuty = (fDy - p.y())*stmp ;
                                                   >> 499       if (v.y() < 0)  sOuty = (fDy + p.y())*stmp ;
                                                   >> 500       if( sOuty < sOut ) sOut = sOuty ;
                                                   >> 501     }     
                                                   >> 502   }
                                                   >> 503 
                                                   >> 504   // Z planes
                                                   >> 505 
                                                   >> 506   if ( v.z() )
                                                   >> 507   {
                                                   >> 508     stmp = 1.0/fabs(v.z()) ;
                                                   >> 509 
                                                   >> 510     if ( safz >= 0.0)
                                                   >> 511     {
                                                   >> 512       sminz = safz*stmp ;
                                                   >> 513       smaxz = (fDz+fabs(p.z()))*stmp ;
                                                   >> 514 
                                                   >> 515       if (sminz > smin) smin = sminz ;
                                                   >> 516       if (smaxz < smax) smax = smaxz ;
345                                                   517 
346   if (tmax <= tmin + delta) return kInfinity;  << 518       if (smin >= smax-kCarTolerance*0.5)
347   return (tmin < delta) ? 0. : tmin;           << 519       { 
                                                   >> 520         return kInfinity ;    // touch ZX or ZY corners
                                                   >> 521       }
                                                   >> 522     }
                                                   >> 523     else
                                                   >> 524     {
                                                   >> 525       if (v.z() > 0)  sOutz = (fDz - p.z())*stmp ;
                                                   >> 526       if (v.z() < 0)  sOutz = (fDz + p.z())*stmp ;
                                                   >> 527       if( sOutz < sOut ) sOut = sOutz ;
                                                   >> 528     }
                                                   >> 529   }
                                                   >> 530 
                                                   >> 531   if ( sOut <= smin + 0.5*kCarTolerance) // travel over edge
                                                   >> 532   {
                                                   >> 533     return kInfinity ;
                                                   >> 534   }
                                                   >> 535   if (smin < 0.5*kCarTolerance)  smin = 0.0 ;
                                                   >> 536 
                                                   >> 537   return smin ;
348 }                                                 538 }
349                                                   539 
350 //////////////////////////////////////////////    540 //////////////////////////////////////////////////////////////////////////
351 //                                             << 541 // 
352 // Appoximate distance to box.                    542 // Appoximate distance to box.
353 // Returns largest perpendicular distance to t    543 // Returns largest perpendicular distance to the closest x/y/z sides of
354 // the box, which is the most fast estimation     544 // the box, which is the most fast estimation of the shortest distance to box
355 // - If inside return 0                           545 // - If inside return 0
356                                                   546 
357 G4double G4Box::DistanceToIn(const G4ThreeVect    547 G4double G4Box::DistanceToIn(const G4ThreeVector& p) const
358 {                                                 548 {
359   G4double dist = std::max(std::max(           << 549   G4double safex, safey, safez, safe = 0.0 ;
360                   std::abs(p.x())-fDx,         << 550 
361                   std::abs(p.y())-fDy),        << 551   safex = fabs(p.x()) - fDx ;
362                   std::abs(p.z())-fDz);        << 552   safey = fabs(p.y()) - fDy ;
363   return (dist > 0) ? dist : 0.;               << 553   safez = fabs(p.z()) - fDz ;
                                                   >> 554 
                                                   >> 555   if (safex > safe) safe = safex ;
                                                   >> 556   if (safey > safe) safe = safey ;
                                                   >> 557   if (safez > safe) safe = safez ;
                                                   >> 558 
                                                   >> 559   return safe ;
364 }                                                 560 }
365                                                   561 
366 ////////////////////////////////////////////// << 562 /////////////////////////////////////////////////////////////////////////
367 //                                                563 //
368 // Calculate distance to surface of the box fr << 564 // Calcluate distance to surface of box from inside
369 // find normal at exit point, if required      << 565 // by calculating distances to box's x/y/z planes.
370 // - when leaving the surface, return 0        << 566 // Smallest distance is exact distance to exiting.
                                                   >> 567 // - Eliminate one side of each pair by considering direction of v
                                                   >> 568 // - when leaving a surface & v.close, return 0
371                                                   569 
372 G4double G4Box::DistanceToOut( const G4ThreeVe << 570 G4double G4Box::DistanceToOut( const G4ThreeVector& p,const G4ThreeVector& v,
373                                const G4ThreeVe << 
374                                const G4bool ca    571                                const G4bool calcNorm,
375                                G4bool* validNo << 572                                      G4bool *validNorm,G4ThreeVector *n) const
376 {                                                 573 {
377   // Check if point is on the surface and trav << 574   ESide side = kUndefined ;
378   //                                           << 575   G4double pdist,stmp,snxt;
379   if ((std::abs(p.x()) - fDx) >= -delta && p.x << 576 
                                                   >> 577   if (calcNorm) *validNorm = true ; // All normals are valid
                                                   >> 578 
                                                   >> 579   if (v.x() > 0)   // X planes  
380   {                                               580   {
381     if (calcNorm)                              << 581     pdist = fDx - p.x() ;
                                                   >> 582 
                                                   >> 583     if (pdist > kCarTolerance*0.5)
                                                   >> 584     {
                                                   >> 585       snxt = pdist/v.x() ;
                                                   >> 586       side = kPX ;
                                                   >> 587     }
                                                   >> 588     else
382     {                                             589     {
383       *validNorm = true;                       << 590       if (calcNorm) *n    = G4ThreeVector(1,0,0) ;
384       n->set((p.x() < 0) ? -1. : 1., 0., 0.);  << 591       return         snxt = 0 ;
385     }                                             592     }
386     return 0.;                                 << 
387   }                                               593   }
388   if ((std::abs(p.y()) - fDy) >= -delta && p.y << 594   else if (v.x() < 0) 
389   {                                               595   {
390     if (calcNorm)                              << 596     pdist = fDx + p.x() ;
                                                   >> 597 
                                                   >> 598     if (pdist > kCarTolerance*0.5)
                                                   >> 599     {
                                                   >> 600       snxt = -pdist/v.x() ;
                                                   >> 601       side = kMX ;
                                                   >> 602     }
                                                   >> 603     else
391     {                                             604     {
392       *validNorm = true;                       << 605       if (calcNorm) *n   = G4ThreeVector(-1,0,0) ;
393       n->set(0., (p.y() < 0) ? -1. : 1., 0.);  << 606       return        snxt = 0 ;
394     }                                             607     }
395     return 0.;                                 << 
396   }                                               608   }
397   if ((std::abs(p.z()) - fDz) >= -delta && p.z << 609   else snxt = kInfinity ;
                                                   >> 610 
                                                   >> 611   if ( v.y() > 0 )   // Y planes  
398   {                                               612   {
399     if (calcNorm)                              << 613     pdist=fDy-p.y();
                                                   >> 614 
                                                   >> 615     if (pdist>kCarTolerance*0.5)
400     {                                             616     {
401       *validNorm = true;                       << 617       stmp=pdist/v.y();
402       n->set(0., 0., (p.z() < 0) ? -1. : 1.);  << 618 
                                                   >> 619       if (stmp<snxt)
                                                   >> 620       {
                                                   >> 621         snxt=stmp;
                                                   >> 622         side=kPY;
                                                   >> 623       }
                                                   >> 624     }
                                                   >> 625     else
                                                   >> 626     {
                                                   >> 627       if (calcNorm) *n    = G4ThreeVector(0,1,0) ;
                                                   >> 628       return         snxt = 0 ;
403     }                                             629     }
404     return 0.;                                 << 
405   }                                               630   }
                                                   >> 631   else if ( v.y() < 0 ) 
                                                   >> 632   {
                                                   >> 633     pdist = fDy + p.y() ;
406                                                   634 
407   // Find intersection                         << 635     if (pdist > kCarTolerance*0.5)
408   //                                           << 636     {
409   G4double vx = v.x();                         << 637       stmp=-pdist/v.y();
410   G4double tx = (vx == 0) ? DBL_MAX : (std::co << 
411                                                   638 
412   G4double vy = v.y();                         << 639       if (stmp<snxt)
413   G4double ty = (vy == 0) ? tx : (std::copysig << 640       {
414   G4double txy = std::min(tx,ty);              << 641         snxt=stmp;
                                                   >> 642         side=kMY;
                                                   >> 643       }
                                                   >> 644     }
                                                   >> 645     else
                                                   >> 646     {
                                                   >> 647       if (calcNorm) *n    = G4ThreeVector(0,-1,0) ;
                                                   >> 648       return         snxt = 0 ;
                                                   >> 649     }
                                                   >> 650   }
                                                   >> 651   if (v.z()>0)        // Z planes 
                                                   >> 652   {
                                                   >> 653     pdist=fDz-p.z();
415                                                   654 
416   G4double vz = v.z();                         << 655     if (pdist > kCarTolerance*0.5)
417   G4double tz = (vz == 0) ? txy : (std::copysi << 656     {
418   G4double tmax = std::min(txy,tz);            << 657       stmp=pdist/v.z();
419                                                   658 
420   // Set normal, if required, and return dista << 659       if (stmp < snxt)
421   //                                           << 660       {
422   if (calcNorm)                                << 661         snxt=stmp;
                                                   >> 662         side=kPZ;
                                                   >> 663       }
                                                   >> 664     }
                                                   >> 665     else
                                                   >> 666     {
                                                   >> 667       if (calcNorm) *n    = G4ThreeVector(0,0,1) ;
                                                   >> 668       return         snxt = 0 ;
                                                   >> 669     }
                                                   >> 670   }
                                                   >> 671   else if (v.z()<0) 
423   {                                               672   {
424     *validNorm = true;                         << 673     pdist = fDz + p.z() ;
425     if (tmax == tx)      n->set((v.x() < 0) ?  << 674 
426     else if (tmax == ty) n->set(0., (v.y() < 0 << 675     if (pdist > kCarTolerance*0.5)
427     else                 n->set(0., 0., (v.z() << 676     {
                                                   >> 677       stmp=-pdist/v.z();
                                                   >> 678 
                                                   >> 679       if (stmp < snxt)
                                                   >> 680       {
                                                   >> 681         snxt=stmp;
                                                   >> 682         side=kMZ;
                                                   >> 683       }
                                                   >> 684     }
                                                   >> 685     else
                                                   >> 686     {
                                                   >> 687       if (calcNorm) *n    = G4ThreeVector(0,0,-1) ;
                                                   >> 688       return         snxt = 0 ;
                                                   >> 689     }
                                                   >> 690   }
                                                   >> 691   if (calcNorm)
                                                   >> 692   {      
                                                   >> 693     switch (side)
                                                   >> 694     {
                                                   >> 695       case kPX:
                                                   >> 696         *n=G4ThreeVector(1,0,0);
                                                   >> 697         break;
                                                   >> 698       case kMX:
                                                   >> 699         *n=G4ThreeVector(-1,0,0);
                                                   >> 700         break;
                                                   >> 701       case kPY:
                                                   >> 702         *n=G4ThreeVector(0,1,0);
                                                   >> 703         break;
                                                   >> 704       case kMY:
                                                   >> 705         *n=G4ThreeVector(0,-1,0);
                                                   >> 706         break;
                                                   >> 707       case kPZ:
                                                   >> 708         *n=G4ThreeVector(0,0,1);
                                                   >> 709         break;
                                                   >> 710       case kMZ:
                                                   >> 711         *n=G4ThreeVector(0,0,-1);
                                                   >> 712         break;
                                                   >> 713       default:
                                                   >> 714         G4cout.precision(16);
                                                   >> 715         G4cout << G4endl;
                                                   >> 716         DumpInfo();
                                                   >> 717         G4cout << "Position:"  << G4endl << G4endl;
                                                   >> 718         G4cout << "p.x() = "   << p.x()/mm << " mm" << G4endl;
                                                   >> 719         G4cout << "p.y() = "   << p.y()/mm << " mm" << G4endl;
                                                   >> 720         G4cout << "p.z() = "   << p.z()/mm << " mm" << G4endl << G4endl;
                                                   >> 721         G4cout << "Direction:" << G4endl << G4endl;
                                                   >> 722         G4cout << "v.x() = "   << v.x() << G4endl;
                                                   >> 723         G4cout << "v.y() = "   << v.y() << G4endl;
                                                   >> 724         G4cout << "v.z() = "   << v.z() << G4endl << G4endl;
                                                   >> 725         G4cout << "Proposed distance :" << G4endl << G4endl;
                                                   >> 726         G4cout << "snxt = "    << snxt/mm << " mm" << G4endl << G4endl;
                                                   >> 727         G4Exception("G4Box::DistanceToOut() - Invalid enum");
                                                   >> 728         break;
                                                   >> 729     }
428   }                                               730   }
429   return tmax;                                 << 731   return snxt;
430 }                                                 732 }
431                                                   733 
432 //////////////////////////////////////////////    734 ////////////////////////////////////////////////////////////////////////////
433 //                                                735 //
434 // Calculate exact shortest distance to any bo    736 // Calculate exact shortest distance to any boundary from inside
435 // - if outside return 0                       << 737 // - If outside return 0
436                                                   738 
437 G4double G4Box::DistanceToOut(const G4ThreeVec    739 G4double G4Box::DistanceToOut(const G4ThreeVector& p) const
438 {                                                 740 {
                                                   >> 741   G4double safx1,safx2,safy1,safy2,safz1,safz2,safe;
                                                   >> 742 
439 #ifdef G4CSGDEBUG                                 743 #ifdef G4CSGDEBUG
440   if( Inside(p) == kOutside )                     744   if( Inside(p) == kOutside )
441   {                                               745   {
442     std::ostringstream message;                << 746      G4cout.precision(16) ;
443     G4int oldprc = message.precision(16);      << 747      G4cout << G4endl ;
444     message << "Point p is outside (!?) of sol << 748      DumpInfo();
445     message << "Position:\n";                  << 749      G4cout << "Position:"  << G4endl << G4endl ;
446     message << "   p.x() = " << p.x()/mm << "  << 750      G4cout << "p.x() = "   << p.x()/mm << " mm" << G4endl ;
447     message << "   p.y() = " << p.y()/mm << "  << 751      G4cout << "p.y() = "   << p.y()/mm << " mm" << G4endl ;
448     message << "   p.z() = " << p.z()/mm << "  << 752      G4cout << "p.z() = "   << p.z()/mm << " mm" << G4endl << G4endl ;
449     G4cout.precision(oldprc);                  << 753      G4cout << "G4Box::DistanceToOut(p) - point p is outside ?!" << G4endl ;
450     G4Exception("G4Box::DistanceToOut(p)", "Ge << 754      G4cerr << "G4Box::DistanceToOut(p) - point p is outside ?!" << G4endl ;
451                 JustWarning, message );        << 
452     DumpInfo();                                << 
453   }                                               755   }
454 #endif                                            756 #endif
455   G4double dist = std::min(std::min(           << 757 
456                   fDx-std::abs(p.x()),         << 758   safx1 = fDx - p.x() ;
457                   fDy-std::abs(p.y())),        << 759   safx2 = fDx + p.x() ;
458                   fDz-std::abs(p.z()));        << 760   safy1 = fDy - p.y() ;
459   return (dist > 0) ? dist : 0.;               << 761   safy2 = fDy + p.y() ;
                                                   >> 762   safz1 = fDz - p.z() ;
                                                   >> 763   safz2 = fDz + p.z() ;  
                                                   >> 764   
                                                   >> 765   // shortest Dist to any boundary now MIN(safx1,safx2,safy1..)
                                                   >> 766 
                                                   >> 767   if (safx2 < safx1) safe = safx2 ;
                                                   >> 768   else               safe = safx1 ;
                                                   >> 769   if (safy1 < safe)  safe = safy1 ;
                                                   >> 770   if (safy2 < safe)  safe = safy2 ;
                                                   >> 771   if (safz1 < safe)  safe = safz1 ;
                                                   >> 772   if (safz2 < safe)  safe = safz2 ;
                                                   >> 773 
                                                   >> 774   if (safe < 0) safe = 0 ;
                                                   >> 775   return safe ;  
460 }                                                 776 }
461                                                   777 
462 ////////////////////////////////////////////// << 778 ////////////////////////////////////////////////////////////////////////
463 //                                                779 //
464 // GetEntityType                               << 780 // Create a List containing the transformed vertices
465                                                << 781 // Ordering [0-3] -fDz cross section
466 G4GeometryType G4Box::GetEntityType() const    << 782 //          [4-7] +fDz cross section such that [0] is below [4],
467 {                                              << 783 //                                             [1] below [5] etc.
468   return {"G4Box"};                            << 784 // Note:
                                                   >> 785 //  Caller has deletion resposibility
                                                   >> 786 
                                                   >> 787 G4ThreeVectorList*
                                                   >> 788 G4Box::CreateRotatedVertices(const G4AffineTransform& pTransform) const
                                                   >> 789 {
                                                   >> 790   G4ThreeVectorList* vertices = new G4ThreeVectorList();
                                                   >> 791   vertices->reserve(8);
                                                   >> 792 
                                                   >> 793   if (vertices)
                                                   >> 794   {
                                                   >> 795     G4ThreeVector vertex0(-fDx,-fDy,-fDz) ;
                                                   >> 796     G4ThreeVector vertex1(fDx,-fDy,-fDz) ;
                                                   >> 797     G4ThreeVector vertex2(fDx,fDy,-fDz) ;
                                                   >> 798     G4ThreeVector vertex3(-fDx,fDy,-fDz) ;
                                                   >> 799     G4ThreeVector vertex4(-fDx,-fDy,fDz) ;
                                                   >> 800     G4ThreeVector vertex5(fDx,-fDy,fDz) ;
                                                   >> 801     G4ThreeVector vertex6(fDx,fDy,fDz) ;
                                                   >> 802     G4ThreeVector vertex7(-fDx,fDy,fDz) ;
                                                   >> 803 
                                                   >> 804     vertices->push_back(pTransform.TransformPoint(vertex0));
                                                   >> 805     vertices->push_back(pTransform.TransformPoint(vertex1));
                                                   >> 806     vertices->push_back(pTransform.TransformPoint(vertex2));
                                                   >> 807     vertices->push_back(pTransform.TransformPoint(vertex3));
                                                   >> 808     vertices->push_back(pTransform.TransformPoint(vertex4));
                                                   >> 809     vertices->push_back(pTransform.TransformPoint(vertex5));
                                                   >> 810     vertices->push_back(pTransform.TransformPoint(vertex6));
                                                   >> 811     vertices->push_back(pTransform.TransformPoint(vertex7));
                                                   >> 812   }
                                                   >> 813   else
                                                   >> 814   {
                                                   >> 815     DumpInfo();
                                                   >> 816     G4Exception("G4Box::CreateRotatedVertices() - Out of memory !");
                                                   >> 817   }
                                                   >> 818   return vertices;
469 }                                                 819 }
470                                                   820 
471 //////////////////////////////////////////////    821 //////////////////////////////////////////////////////////////////////////
472 //                                                822 //
473 // IsFaceted                                   << 823 // GetEntityType
474                                                   824 
475 G4bool G4Box::IsFaceted() const                << 825 G4GeometryType G4Box::GetEntityType() const
476 {                                                 826 {
477   return true;                                 << 827   return G4String("G4Box");
478 }                                                 828 }
479                                                   829 
480 //////////////////////////////////////////////    830 //////////////////////////////////////////////////////////////////////////
481 //                                                831 //
482 // Stream object contents to an output stream     832 // Stream object contents to an output stream
483                                                   833 
484 std::ostream& G4Box::StreamInfo(std::ostream&     834 std::ostream& G4Box::StreamInfo(std::ostream& os) const
485 {                                                 835 {
486   G4long oldprc = os.precision(16);            << 
487   os << "-------------------------------------    836   os << "-----------------------------------------------------------\n"
488      << "    *** Dump for solid - " << GetName    837      << "    *** Dump for solid - " << GetName() << " ***\n"
489      << "    =================================    838      << "    ===================================================\n"
490      << "Solid type: G4Box\n"                  << 839      << " Solid type: G4Box\n"
491      << "Parameters: \n"                       << 840      << " Parameters: \n"
492      << "   half length X: " << fDx/mm << " mm << 841      << "    half length X: " << fDx/mm << " mm \n"
493      << "   half length Y: " << fDy/mm << " mm << 842      << "    half length Y: " << fDy/mm << " mm \n"
494      << "   half length Z: " << fDz/mm << " mm << 843      << "    half length Z: " << fDz/mm << " mm \n"
495      << "-------------------------------------    844      << "-----------------------------------------------------------\n";
496   os.precision(oldprc);                        << 845 
497   return os;                                      846   return os;
498 }                                                 847 }
499                                                   848 
500 //////////////////////////////////////////////    849 //////////////////////////////////////////////////////////////////////////
501 //                                                850 //
502 // Return a point randomly and uniformly selec << 851 // Methods for visualisation
503                                                << 
504 G4ThreeVector G4Box::GetPointOnSurface() const << 
505 {                                              << 
506   G4double sxy = fDx*fDy, sxz = fDx*fDz, syz = << 
507   G4double select = (sxy + sxz + syz)*G4QuickR << 
508   G4double u = 2.*G4QuickRand() - 1.;          << 
509   G4double v = 2.*G4QuickRand() - 1.;          << 
510                                                << 
511   if (select < sxy)                            << 
512     return { u*fDx, v*fDy, ((select < 0.5*sxy) << 
513   else if (select < sxy + sxz)                 << 
514     return { u*fDx, ((select < sxy + 0.5*sxz)  << 
515   else                                         << 
516     return { ((select < sxy + sxz + 0.5*syz) ? << 
517 }                                              << 
518                                                   852 
519 ////////////////////////////////////////////// << 853 void G4Box::DescribeYourselfTo (G4VGraphicsScene& scene) const 
520 //                                             << 
521 // Make a clone of the object                  << 
522 //                                             << 
523 G4VSolid* G4Box::Clone() const                 << 
524 {                                                 854 {
525   return new G4Box(*this);                     << 855   scene.AddThis (*this);
526 }                                                 856 }
527                                                   857 
528 ////////////////////////////////////////////// << 858 G4VisExtent G4Box::GetExtent() const 
529 //                                             << 
530 // Methods for visualisation                   << 
531                                                << 
532 void G4Box::DescribeYourselfTo (G4VGraphicsSce << 
533 {                                                 859 {
534   scene.AddSolid (*this);                      << 860   return G4VisExtent (-fDx, fDx, -fDy, fDy, -fDz, fDz);
535 }                                                 861 }
536                                                   862 
537 G4VisExtent G4Box::GetExtent() const           << 863 G4Polyhedron* G4Box::CreatePolyhedron () const 
538 {                                                 864 {
539   return { -fDx, fDx, -fDy, fDy, -fDz, fDz };  << 865   return new G4PolyhedronBox (fDx, fDy, fDz);
540 }                                                 866 }
541                                                   867 
542 G4Polyhedron* G4Box::CreatePolyhedron () const << 868 G4NURBS* G4Box::CreateNURBS () const 
543 {                                                 869 {
544   return new G4PolyhedronBox (fDx, fDy, fDz);  << 870   return new G4NURBSbox (fDx, fDy, fDz);
545 }                                                 871 }
546 #endif                                         << 
547                                                   872