Geant4 Cross Reference |
1 // << 2 // ******************************************* << 3 // * License and Disclaimer << 4 // * << 5 // * The Geant4 software is copyright of th << 6 // * the Geant4 Collaboration. It is provided << 7 // * conditions of the Geant4 Software License << 8 // * LICENSE and available at http://cern.ch/ << 9 // * include a list of copyright holders. << 10 // * << 11 // * Neither the authors of this software syst << 12 // * institutes,nor the agencies providing fin << 13 // * work make any representation or warran << 14 // * regarding this software system or assum << 15 // * use. Please see the license in the file << 16 // * for the full disclaimer and the limitatio << 17 // * << 18 // * This code implementation is the result << 19 // * technical work of the GEANT4 collaboratio << 20 // * By using, copying, modifying or distri << 21 // * any work based on the software) you ag << 22 // * use in resulting scientific publicati << 23 // * acceptance of all terms of the Geant4 Sof << 24 // ******************************************* << 25 // << 26 // Implementation of methods for the class G4I 1 // Implementation of methods for the class G4IntersectionSolid 27 // 2 // 28 // 12.09.98 V.Grichine: first implementation << 3 // History: 29 // ------------------------------------------- << 4 // 30 << 5 // 12.09.98 V.Grichine 31 #include <sstream> << 6 // 29.07.99 V.Grichine, modifications in DistanceToIn(p,v) 32 7 33 #include "G4IntersectionSolid.hh" 8 #include "G4IntersectionSolid.hh" >> 9 // #include "G4DisplacedSolid.hh" >> 10 >> 11 #include "G4RotationMatrix.hh" >> 12 #include "G4ThreeVector.hh" >> 13 #include "G4Transform3D.hh" >> 14 #include "G4AffineTransform.hh" 34 15 35 #include "G4SystemOfUnits.hh" << 36 #include "G4VoxelLimits.hh" 16 #include "G4VoxelLimits.hh" 37 #include "G4VPVParameterisation.hh" 17 #include "G4VPVParameterisation.hh" 38 18 39 #include "G4VGraphicsScene.hh" 19 #include "G4VGraphicsScene.hh" 40 #include "G4Polyhedron.hh" 20 #include "G4Polyhedron.hh" 41 #include "G4PolyhedronArbitrary.hh" << 21 #include "G4NURBS.hh" 42 #include "HepPolyhedronProcessor.h" << 22 #include "G4NURBSbox.hh" >> 23 #include "G4VisExtent.hh" 43 24 44 ////////////////////////////////////////////// << 25 ///////////////////////////////////////////////////////////////////// 45 // 26 // 46 // Transfer all data members to G4BooleanSolid 27 // Transfer all data members to G4BooleanSolid which is responsible 47 // for them. pName will be in turn sent to G4V 28 // for them. pName will be in turn sent to G4VSolid 48 // 29 // 49 30 50 G4IntersectionSolid::G4IntersectionSolid( cons << 31 G4IntersectionSolid:: G4IntersectionSolid( const G4String& pName, 51 << 32 G4VSolid* pSolidA , 52 << 33 G4VSolid* pSolidB ): 53 : G4BooleanSolid(pName,pSolidA,pSolidB) << 34 G4BooleanSolid(pName,pSolidA,pSolidB) 54 { 35 { >> 36 ; 55 } 37 } 56 38 57 ////////////////////////////////////////////// << 39 >> 40 /////////////////////////////////////////////////////////////////// 58 // 41 // 59 42 60 G4IntersectionSolid::G4IntersectionSolid( cons << 43 G4IntersectionSolid:: 61 << 44 G4IntersectionSolid( const G4String& pName, 62 << 45 G4VSolid* pSolidA , 63 << 46 G4VSolid* pSolidB, 64 cons << 47 G4RotationMatrix* rotMatrix, 65 : G4BooleanSolid(pName,pSolidA,pSolidB,rotMa << 48 const G4ThreeVector& transVector ): >> 49 G4BooleanSolid(pName,pSolidA,pSolidB,rotMatrix,transVector) 66 { 50 { >> 51 ; 67 } 52 } 68 53 69 ////////////////////////////////////////////// << 54 ////////////////////////////////////////////////////////////////// 70 // 55 // 71 // 56 // 72 57 73 G4IntersectionSolid::G4IntersectionSolid( cons << 58 G4IntersectionSolid:: 74 << 59 G4IntersectionSolid( const G4String& pName, 75 << 60 G4VSolid* pSolidA , 76 cons << 61 G4VSolid* pSolidB , 77 : G4BooleanSolid(pName,pSolidA,pSolidB,trans << 62 const G4Transform3D& transform ): >> 63 G4BooleanSolid(pName,pSolidA,pSolidB,transform) 78 { 64 { >> 65 ; 79 } 66 } 80 67 81 ////////////////////////////////////////////// << 82 // << 83 // Fake default constructor - sets only member << 84 // for usage restri << 85 68 86 G4IntersectionSolid::G4IntersectionSolid( __vo << 69 G4IntersectionSolid::~G4IntersectionSolid() 87 : G4BooleanSolid(a) << 88 { 70 { >> 71 ; 89 } 72 } 90 73 91 ////////////////////////////////////////////// << 74 /////////////////////////////////////////////////////////////// 92 // << 93 // << 94 << 95 G4IntersectionSolid::~G4IntersectionSolid() = << 96 << 97 ////////////////////////////////////////////// << 98 // << 99 // Copy constructor << 100 << 101 G4IntersectionSolid::G4IntersectionSolid(const << 102 << 103 ////////////////////////////////////////////// << 104 // << 105 // Assignment operator << 106 << 107 G4IntersectionSolid& << 108 G4IntersectionSolid::operator = (const G4Inter << 109 { << 110 // Check assignment to self << 111 // << 112 if (this == &rhs) { return *this; } << 113 << 114 // Copy base class data << 115 // << 116 G4BooleanSolid::operator=(rhs); << 117 << 118 return *this; << 119 } << 120 << 121 ////////////////////////////////////////////// << 122 // 75 // 123 // Get bounding box << 124 << 125 void << 126 G4IntersectionSolid::BoundingLimits(G4ThreeVec << 127 G4ThreeVec << 128 { << 129 G4ThreeVector minA,maxA, minB,maxB; << 130 fPtrSolidA->BoundingLimits(minA,maxA); << 131 fPtrSolidB->BoundingLimits(minB,maxB); << 132 << 133 pMin.set(std::max(minA.x(),minB.x()), << 134 std::max(minA.y(),minB.y()), << 135 std::max(minA.z(),minB.z())); << 136 << 137 pMax.set(std::min(maxA.x(),maxB.x()), << 138 std::min(maxA.y(),maxB.y()), << 139 std::min(maxA.z(),maxB.z())); << 140 << 141 // Check correctness of the bounding box << 142 // << 143 if (pMin.x() >= pMax.x() || pMin.y() >= pMax << 144 { << 145 std::ostringstream message; << 146 message << "Bad bounding box (min >= max) << 147 << GetName() << " !" << 148 << "\npMin = " << pMin << 149 << "\npMax = " << pMax; << 150 G4Exception("G4IntersectionSolid::Bounding << 151 JustWarning, message); << 152 DumpInfo(); << 153 } << 154 } << 155 << 156 ////////////////////////////////////////////// << 157 // 76 // 158 // Calculate extent under transform and specif << 159 77 160 G4bool 78 G4bool 161 G4IntersectionSolid::CalculateExtent(const EAx 79 G4IntersectionSolid::CalculateExtent(const EAxis pAxis, 162 const G4V << 80 const G4VoxelLimits& pVoxelLimit, 163 const G4A << 81 const G4AffineTransform& pTransform, 164 G4d << 82 G4double& pMin, G4double& pMax) const 165 G4d << 166 { 83 { 167 G4bool retA, retB, out; << 84 G4bool retA, retB; 168 G4double minA, minB, maxA, maxB; 85 G4double minA, minB, maxA, maxB; 169 86 170 retA = fPtrSolidA << 87 retA= fPtrSolidA->CalculateExtent( pAxis, pVoxelLimit, pTransform, minA, maxA); 171 ->CalculateExtent( pAxis, pVoxelLimi << 88 retB= fPtrSolidB->CalculateExtent( pAxis, pVoxelLimit, pTransform, minB, maxB); 172 retB = fPtrSolidB << 173 ->CalculateExtent( pAxis, pVoxelLimi << 174 89 175 if( retA && retB ) << 90 pMin = G4std::max( minA, minB ); 176 { << 91 pMax = G4std::min( maxA, maxB ); 177 pMin = std::max( minA, minB ); << 178 pMax = std::min( maxA, maxB ); << 179 out = (pMax > pMin); // true; << 180 } << 181 else << 182 { << 183 out = false; << 184 } << 185 92 186 return out; // It exists in this slice only << 93 return retA && retB ; // It exists in this slice only if both exist in it. 187 } 94 } 188 95 189 ////////////////////////////////////////////// << 96 ///////////////////////////////////////////////////// 190 // 97 // 191 // Touching ? Empty intersection ? 98 // Touching ? Empty intersection ? 192 99 193 EInside G4IntersectionSolid::Inside(const G4Th 100 EInside G4IntersectionSolid::Inside(const G4ThreeVector& p) const 194 { 101 { 195 EInside positionA = fPtrSolidA->Inside(p); << 102 EInside positionA = fPtrSolidA->Inside(p) ; 196 if(positionA == kOutside) return positionA; << 103 EInside positionB = fPtrSolidB->Inside(p) ; 197 << 104 198 EInside positionB = fPtrSolidB->Inside(p); << 105 if(positionA == kInside && positionB == kInside) 199 if(positionA == kInside) return positionB; << 106 { 200 << 107 return kInside ; 201 if(positionB == kOutside) return positionB; << 108 } 202 return kSurface; << 109 else >> 110 { >> 111 if((positionA == kInside && positionB == kSurface) || >> 112 (positionB == kInside && positionA == kSurface) || >> 113 (positionA == kSurface && positionB == kSurface) ) >> 114 { >> 115 return kSurface ; >> 116 } >> 117 else >> 118 { >> 119 return kOutside ; >> 120 } >> 121 } 203 } 122 } 204 123 205 ////////////////////////////////////////////// << 124 ////////////////////////////////////////////////////////////// >> 125 // 206 // 126 // 207 127 208 G4ThreeVector 128 G4ThreeVector 209 G4IntersectionSolid::SurfaceNormal( const G4Th 129 G4IntersectionSolid::SurfaceNormal( const G4ThreeVector& p ) const 210 { 130 { 211 G4ThreeVector normal; 131 G4ThreeVector normal; 212 EInside insideA, insideB; << 132 G4bool insideA, insideB; 213 133 214 insideA = fPtrSolidA->Inside(p); << 134 insideA= fPtrSolidA->Inside(p); 215 insideB = fPtrSolidB->Inside(p); << 135 insideB= fPtrSolidB->Inside(p); 216 136 217 #ifdef G4BOOLDEBUG << 137 // if( Inside(p) == kOutside ) 218 if( (insideA == kOutside) || (insideB == kOu 138 if( (insideA == kOutside) || (insideB == kOutside) ) 219 { 139 { 220 G4cout << "WARNING - Invalid call in " << 140 G4Exception("Invalid call in G4IntersectionSolid::SurfaceNormal(p), point p is outside") ; 221 << "G4IntersectionSolid::SurfaceNor << 222 << " Point p is outside !" << G4en << 223 G4cout << " p = " << p << G4endl; << 224 G4cerr << "WARNING - Invalid call in " << 225 << "G4IntersectionSolid::SurfaceNor << 226 << " Point p is outside !" << G4en << 227 G4cerr << " p = " << p << G4endl; << 228 } 141 } 229 #endif << 142 >> 143 // OLD: if(fPtrSolidA->DistanceToOut(p) <= fPtrSolidB->DistanceToOut(p) ) 230 144 231 // On the surface of both is difficult ... t 145 // On the surface of both is difficult ... treat it like on A now! 232 // 146 // >> 147 // if( (insideA == kSurface) && (insideB == kSurface) ) >> 148 // normal= fPtrSolidA->SurfaceNormal(p) ; >> 149 // else 233 if( insideA == kSurface ) 150 if( insideA == kSurface ) 234 { << 235 normal = fPtrSolidA->SurfaceNormal(p) ; << 236 } << 237 else if( insideB == kSurface ) << 238 { << 239 normal = fPtrSolidB->SurfaceNormal(p) ; << 240 } << 241 else // We are on neither surface, so we sh << 242 { << 243 if(fPtrSolidA->DistanceToOut(p) <= fPtrSol << 244 { << 245 normal= fPtrSolidA->SurfaceNormal(p) ; << 246 } << 247 else << 248 { 151 { 249 normal= fPtrSolidB->SurfaceNormal(p) ; << 152 normal= fPtrSolidA->SurfaceNormal(p) ; 250 } 153 } 251 #ifdef G4BOOLDEBUG << 154 else if( insideB == kSurface ) 252 G4cout << "WARNING - Invalid call in " << 155 { 253 << "G4IntersectionSolid::SurfaceNor << 156 normal= fPtrSolidB->SurfaceNormal(p) ; 254 << " Point p is out of surface !" << 157 } 255 G4cout << " p = " << p << G4endl; << 158 // We are on neither surface, so we should generate an exception 256 G4cerr << "WARNING - Invalid call in " << 159 else 257 << "G4IntersectionSolid::SurfaceNor << 160 { 258 << " Point p is out of surface !" << 161 G4Exception("Invalid call in G4IntersectionSolid::SurfaceNormal(p), point p is not on the surface of the volume.") ; 259 G4cerr << " p = " << p << G4endl; << 162 260 #endif << 163 // Or else >> 164 if(fPtrSolidA->DistanceToOut(p) <= fPtrSolidB->DistanceToOut(p) ) >> 165 normal= fPtrSolidA->SurfaceNormal(p) ; >> 166 else >> 167 normal= fPtrSolidB->SurfaceNormal(p) ; 261 } 168 } 262 169 263 return normal; 170 return normal; 264 } 171 } 265 172 266 ////////////////////////////////////////////// << 173 ///////////////////////////////////////////////////////////// 267 // 174 // 268 // The same algorithm as in DistanceToIn(p) 175 // The same algorithm as in DistanceToIn(p) 269 176 270 G4double 177 G4double 271 G4IntersectionSolid::DistanceToIn( const G4Thr 178 G4IntersectionSolid::DistanceToIn( const G4ThreeVector& p, 272 const G4Thr 179 const G4ThreeVector& v ) const 273 { 180 { 274 G4double dist = 0.0; << 181 G4double dist = 0.0, disTmp = 0.0 ; 275 if( Inside(p) == kInside ) 182 if( Inside(p) == kInside ) 276 { 183 { 277 #ifdef G4BOOLDEBUG << 184 G4Exception("Invalid call in G4IntersectionSolid::DistanceToIn(p,v), point p is inside") ; 278 G4cout << "WARNING - Invalid call in " << 279 << "G4IntersectionSolid::DistanceTo << 280 << " Point p is inside !" << G4end << 281 G4cout << " p = " << p << G4endl; << 282 G4cout << " v = " << v << G4endl; << 283 G4cerr << "WARNING - Invalid call in " << 284 << "G4IntersectionSolid::DistanceTo << 285 << " Point p is inside !" << G4end << 286 G4cerr << " p = " << p << G4endl; << 287 G4cerr << " v = " << v << G4endl; << 288 #endif << 289 } 185 } 290 else // if( Inside(p) == kSurface ) << 186 else 291 { 187 { 292 EInside wA = fPtrSolidA->Inside(p); << 188 if( fPtrSolidA->Inside(p) != kOutside ) 293 EInside wB = fPtrSolidB->Inside(p); << 294 << 295 G4ThreeVector pA = p, pB = p; << 296 G4double dA = 0., dA1=0., dA2=0.; << 297 G4double dB = 0., dB1=0., dB2=0.; << 298 G4bool doA = true, doB = true; << 299 << 300 static const std::size_t max_trials=10000; << 301 for (std::size_t trial=0; trial<max_trials << 302 { 189 { 303 if(doA) << 190 do 304 { 191 { 305 // find next valid range for A << 192 disTmp = fPtrSolidB->DistanceToIn(p+dist*v,v) ; 306 << 193 307 dA1 = 0.; << 194 if( disTmp != kInfinity ) 308 << 309 if( wA != kInside ) << 310 { 195 { 311 dA1 = fPtrSolidA->DistanceToIn(pA, v << 196 dist += disTmp ; 312 << 197 if(Inside(p+dist*v) == kOutside ) 313 if( dA1 == kInfinity ) return kInf << 198 { 314 << 199 disTmp = fPtrSolidA->DistanceToIn(p+dist*v,v) ; 315 pA += dA1*v; << 200 if( disTmp != kInfinity ) >> 201 { >> 202 dist += disTmp ; >> 203 } >> 204 else >> 205 { >> 206 return kInfinity ; >> 207 } >> 208 } >> 209 else >> 210 { >> 211 break ; >> 212 } 316 } 213 } 317 dA2 = dA1 + fPtrSolidA->DistanceToOut( << 214 else >> 215 { >> 216 return kInfinity ; >> 217 } 318 } 218 } 319 dA1 += dA; << 219 while( Inside(p+dist*v) == kOutside ) ; 320 dA2 += dA; << 220 // while( fPtrSolidB->Inside(p) != kOutside ) ; 321 << 221 } 322 if(doB) << 222 else if( fPtrSolidB->Inside(p) != kOutside ) >> 223 { >> 224 do 323 { 225 { 324 // find next valid range for B << 226 disTmp = fPtrSolidA->DistanceToIn(p+dist*v,v) ; 325 << 227 326 dB1 = 0.; << 228 if( disTmp != kInfinity ) 327 if(wB != kInside) << 328 { 229 { 329 dB1 = fPtrSolidB->DistanceToIn(pB, v << 230 dist += disTmp ; 330 << 231 if(Inside(p+dist*v) == kOutside ) 331 if(dB1 == kInfinity) return kInfin << 232 { 332 << 233 disTmp = fPtrSolidB->DistanceToIn(p+dist*v,v) ; 333 pB += dB1*v; << 234 if( disTmp != kInfinity ) >> 235 { >> 236 dist += disTmp ; >> 237 } >> 238 else >> 239 { >> 240 return kInfinity ; >> 241 } >> 242 } >> 243 else >> 244 { >> 245 break ; >> 246 } 334 } 247 } 335 dB2 = dB1 + fPtrSolidB->DistanceToOut( << 248 else 336 } << 249 { 337 dB1 += dB; << 250 return kInfinity ; 338 dB2 += dB; << 251 } 339 << 340 // check if they overlap << 341 << 342 if( dA1 < dB1 ) << 343 { << 344 if( dB1 < dA2 ) return dB1; << 345 << 346 dA = dA2; << 347 pA = p + dA*v; // continue from her << 348 wA = kSurface; << 349 doA = true; << 350 doB = false; << 351 } 252 } 352 else << 253 while( Inside(p+dist*v) == kOutside ) ; >> 254 } >> 255 else >> 256 { >> 257 do 353 { 258 { 354 if( dA1 < dB2 ) return dA1; << 259 disTmp = fPtrSolidB->DistanceToIn(p+dist*v,v) ; 355 << 260 356 dB = dB2; << 261 if( disTmp != kInfinity ) 357 pB = p + dB*v; // continue from her << 262 { 358 wB = kSurface; << 263 dist += disTmp ; 359 doB = true; << 264 if(Inside(p+dist*v) == kOutside ) 360 doA = false; << 265 { >> 266 disTmp = fPtrSolidA->DistanceToIn(p+dist*v,v) ; >> 267 if( disTmp != kInfinity ) >> 268 { >> 269 dist += disTmp ; >> 270 } >> 271 else >> 272 { >> 273 return kInfinity ; >> 274 } >> 275 } >> 276 else >> 277 { >> 278 break ; >> 279 } >> 280 } >> 281 else >> 282 { >> 283 return kInfinity ; >> 284 } 361 } 285 } >> 286 while( Inside(p+dist*v) == kOutside ) ; 362 } 287 } 363 } 288 } 364 #ifdef G4BOOLDEBUG << 365 G4Exception("G4IntersectionSolid::DistanceTo << 366 "GeomSolids0001", JustWarning, << 367 "Reached maximum number of itera << 368 #endif << 369 return dist ; 289 return dist ; 370 } 290 } 371 291 372 ////////////////////////////////////////////// << 292 //////////////////////////////////////////////////////// 373 // 293 // 374 // Approximate nearest distance from the point 294 // Approximate nearest distance from the point p to the intersection of 375 // two solids 295 // two solids 376 296 377 G4double 297 G4double 378 G4IntersectionSolid::DistanceToIn( const G4Thr 298 G4IntersectionSolid::DistanceToIn( const G4ThreeVector& p) const 379 { 299 { 380 #ifdef G4BOOLDEBUG << 381 if( Inside(p) == kInside ) 300 if( Inside(p) == kInside ) 382 { 301 { 383 G4cout << "WARNING - Invalid call in " << 302 G4Exception("Invalid call in G4IntersectionSolid::DistanceToIn(p), point p is inside") ; 384 << "G4IntersectionSolid::DistanceTo << 385 << " Point p is inside !" << G4end << 386 G4cout << " p = " << p << G4endl; << 387 G4cerr << "WARNING - Invalid call in " << 388 << "G4IntersectionSolid::DistanceTo << 389 << " Point p is inside !" << G4end << 390 G4cerr << " p = " << p << G4endl; << 391 } 303 } 392 #endif << 393 EInside sideA = fPtrSolidA->Inside(p) ; 304 EInside sideA = fPtrSolidA->Inside(p) ; 394 EInside sideB = fPtrSolidB->Inside(p) ; 305 EInside sideB = fPtrSolidB->Inside(p) ; 395 G4double dist=0.0 ; << 306 G4double dist ; 396 307 397 if( sideA != kInside && sideB != kOutside ) << 308 if( sideA != kInside && sideB != kOutside ) 398 { 309 { 399 dist = fPtrSolidA->DistanceToIn(p) ; 310 dist = fPtrSolidA->DistanceToIn(p) ; 400 } 311 } 401 else 312 else 402 { 313 { 403 if( sideB != kInside && sideA != kOutside << 314 if( sideB != kInside && sideA != kOutside ) 404 { 315 { 405 dist = fPtrSolidB->DistanceToIn(p) ; 316 dist = fPtrSolidB->DistanceToIn(p) ; 406 } 317 } 407 else 318 else 408 { 319 { 409 dist = std::min(fPtrSolidA->DistanceToI << 320 dist = G4std::min(fPtrSolidA->DistanceToIn(p), 410 fPtrSolidB->DistanceToI << 321 fPtrSolidB->DistanceToIn(p) ) ; 411 } 322 } 412 } 323 } 413 return dist ; 324 return dist ; 414 } 325 } 415 326 416 ////////////////////////////////////////////// << 327 ////////////////////////////////////////////////////////// 417 // 328 // 418 // The same algorithm as DistanceToOut(p) 329 // The same algorithm as DistanceToOut(p) 419 330 420 G4double 331 G4double 421 G4IntersectionSolid::DistanceToOut( const G4Th 332 G4IntersectionSolid::DistanceToOut( const G4ThreeVector& p, 422 const G4Th << 333 const G4ThreeVector& v, 423 const G4bo << 334 const G4bool calcNorm, 424 G4bo << 335 G4bool *validNorm, 425 G4Th << 336 G4ThreeVector *n ) const 426 { 337 { 427 G4bool validNormA, validNormB; << 428 G4ThreeVector nA, nB; << 429 << 430 #ifdef G4BOOLDEBUG << 431 if( Inside(p) == kOutside ) 338 if( Inside(p) == kOutside ) 432 { 339 { 433 G4cout << "Position:" << G4endl << G4endl << 340 G4Exception("Invalid call in G4IntersectionSolid::DistanceToOut(p,v), point p is outside") ; 434 G4cout << "p.x() = " << p.x()/mm << " mm << 435 G4cout << "p.y() = " << p.y()/mm << " mm << 436 G4cout << "p.z() = " << p.z()/mm << " mm << 437 G4cout << "Direction:" << G4endl << G4endl << 438 G4cout << "v.x() = " << v.x() << G4endl; << 439 G4cout << "v.y() = " << v.y() << G4endl; << 440 G4cout << "v.z() = " << v.z() << G4endl << 441 G4cout << "WARNING - Invalid call in " << 442 << "G4IntersectionSolid::DistanceTo << 443 << " Point p is outside !" << G4en << 444 G4cout << " p = " << p << G4endl; << 445 G4cout << " v = " << v << G4endl; << 446 G4cerr << "WARNING - Invalid call in " << 447 << "G4IntersectionSolid::DistanceTo << 448 << " Point p is outside !" << G4en << 449 G4cerr << " p = " << p << G4endl; << 450 G4cerr << " v = " << v << G4endl; << 451 } 341 } 452 #endif << 342 G4double distA = fPtrSolidA->DistanceToOut(p,v,calcNorm,validNorm,n) ; 453 G4double distA = fPtrSolidA->DistanceToOut(p << 343 G4double distB = fPtrSolidB->DistanceToOut(p,v,calcNorm,validNorm,n) ; 454 G4double distB = fPtrSolidB->DistanceToOut(p << 344 G4double dist = G4std::min(distA,distB) ; 455 << 456 G4double dist = std::min(distA,distB) ; << 457 << 458 if( calcNorm ) << 459 { << 460 if ( distA < distB ) << 461 { << 462 *validNorm = validNormA; << 463 *n = nA; << 464 } << 465 else << 466 { << 467 *validNorm = validNormB; << 468 *n = nB; << 469 } << 470 } << 471 << 472 return dist ; 345 return dist ; >> 346 // return G4std::min(fPtrSolidA->DistanceToOut(p,v,calcNorm,validNorm,n), >> 347 // fPtrSolidB->DistanceToOut(p,v,calcNorm,validNorm,n) ) ; 473 } 348 } 474 349 475 ////////////////////////////////////////////// << 350 ////////////////////////////////////////////////////////////// 476 // 351 // 477 // Inverted algorithm of DistanceToIn(p) 352 // Inverted algorithm of DistanceToIn(p) 478 353 479 G4double 354 G4double 480 G4IntersectionSolid::DistanceToOut( const G4Th 355 G4IntersectionSolid::DistanceToOut( const G4ThreeVector& p ) const 481 { 356 { 482 #ifdef G4BOOLDEBUG << 483 if( Inside(p) == kOutside ) 357 if( Inside(p) == kOutside ) 484 { 358 { 485 G4cout << "WARNING - Invalid call in " << 359 G4Exception("Invalid call in G4IntersectionSolid::DistanceToOut(p), point p is outside") ; 486 << "G4IntersectionSolid::DistanceTo << 487 << " Point p is outside !" << G4en << 488 G4cout << " p = " << p << G4endl; << 489 G4cerr << "WARNING - Invalid call in " << 490 << "G4IntersectionSolid::DistanceTo << 491 << " Point p is outside !" << G4en << 492 G4cerr << " p = " << p << G4endl; << 493 } 360 } 494 #endif << 495 361 496 return std::min(fPtrSolidA->DistanceToOut(p) << 362 497 fPtrSolidB->DistanceToOut(p) << 363 return G4std::min(fPtrSolidA->DistanceToOut(p), >> 364 fPtrSolidB->DistanceToOut(p) ) ; 498 365 499 } 366 } 500 367 501 ////////////////////////////////////////////// << 368 ////////////////////////////////////////////////////////////// >> 369 // 502 // 370 // 503 // ComputeDimensions << 504 371 505 void 372 void 506 G4IntersectionSolid::ComputeDimensions( G4VPVP << 373 G4IntersectionSolid::ComputeDimensions( G4VPVParameterisation* p, 507 const << 374 const G4int n, 508 const << 375 const G4VPhysicalVolume* pRep ) 509 { 376 { >> 377 return ; 510 } 378 } 511 379 512 ////////////////////////////////////////////// << 380 ///////////////////////////////////////////////// 513 // 381 // 514 // GetEntityType << 382 // 515 383 516 G4GeometryType G4IntersectionSolid::GetEntityT << 384 void >> 385 G4IntersectionSolid::DescribeYourselfTo ( G4VGraphicsScene& scene ) const 517 { 386 { 518 return {"G4IntersectionSolid"}; << 387 return ; 519 } 388 } 520 389 521 ////////////////////////////////////////////// << 390 ///////////////////////////////////////////////////////////// >> 391 // 522 // 392 // 523 // Make a clone of the object << 524 393 525 G4VSolid* G4IntersectionSolid::Clone() const << 394 G4VisExtent >> 395 G4IntersectionSolid::GetExtent () const 526 { 396 { 527 return new G4IntersectionSolid(*this); << 397 return G4VisExtent(-1.0,1.0,-1.0,1.0,-1.0,1.0) ; 528 } 398 } 529 399 530 ////////////////////////////////////////////// << 400 //////////////////////////////////////////////////// >> 401 // 531 // 402 // 532 // DescribeYourselfTo << 533 403 534 void << 404 G4Polyhedron* 535 G4IntersectionSolid::DescribeYourselfTo ( G4VG << 405 G4IntersectionSolid::CreatePolyhedron () const 536 { 406 { 537 scene.AddSolid (*this); << 407 return new G4PolyhedronBox (1.0, 1.0, 1.0); 538 } 408 } 539 409 540 ////////////////////////////////////////////// << 410 ///////////////////////////////////////////////////////// >> 411 // 541 // 412 // 542 // CreatePolyhedron << 543 413 544 G4Polyhedron* << 414 G4NURBS* 545 G4IntersectionSolid::CreatePolyhedron () const << 415 G4IntersectionSolid::CreateNURBS () const 546 { 416 { 547 if (fExternalBoolProcessor == nullptr) << 417 return new G4NURBSbox (1.0, 1.0, 1.0); 548 { << 549 HepPolyhedronProcessor processor; << 550 // Stack components and components of comp << 551 // See G4BooleanSolid::StackPolyhedron << 552 G4Polyhedron* top = StackPolyhedron(proces << 553 auto result = new G4Polyhedron(*top); << 554 if (processor.execute(*result)) << 555 { << 556 return result; << 557 } << 558 else << 559 { << 560 return nullptr; << 561 } << 562 } << 563 else << 564 { << 565 return fExternalBoolProcessor->Process(thi << 566 } << 567 } 418 } >> 419 >> 420 >> 421 >> 422 >> 423 568 424