42#include "G4SubtractionSolid.hh"
44#include "G4VoxelLimits.hh"
45#include "G4VPVParameterisation.hh"
46#include "G4GeometryTolerance.hh"
48#include "G4VGraphicsScene.hh"
49#include "G4Polyhedron.hh"
60G4SubtractionSolid::G4SubtractionSolid(
const G4String& pName,
63 : G4BooleanSolid(pName,pSolidA,pSolidB)
71G4SubtractionSolid::G4SubtractionSolid(
const G4String& pName,
74 G4RotationMatrix* rotMatrix,
75 const G4ThreeVector& transVector )
76 : G4BooleanSolid(pName,pSolidA,pSolidB,rotMatrix,transVector)
84G4SubtractionSolid::G4SubtractionSolid(
const G4String& pName,
87 const G4Transform3D& transform )
88 : G4BooleanSolid(pName,pSolidA,pSolidB,transform)
97G4SubtractionSolid::G4SubtractionSolid( __void__& a )
106G4SubtractionSolid::~G4SubtractionSolid()
115G4SubtractionSolid::CalculateExtent(
const EAxis pAxis,
116 const G4VoxelLimits& pVoxelLimit,
117 const G4AffineTransform& pTransform,
119 G4double&
pMax )
const
124 return fPtrSolidA->CalculateExtent( pAxis, pVoxelLimit,
132EInside G4SubtractionSolid::Inside(
const G4ThreeVector& p )
const
134 EInside positionA = fPtrSolidA->Inside(p);
135 if (positionA == kOutside)
return kOutside;
137 EInside positionB = fPtrSolidB->Inside(p);
139 if(positionA == kInside && positionB == kOutside)
145 if(( positionA == kInside && positionB == kSurface) ||
146 ( positionB == kOutside && positionA == kSurface) ||
147 ( positionA == kSurface && positionB == kSurface &&
148 ( fPtrSolidA->SurfaceNormal(p) -
149 fPtrSolidB->SurfaceNormal(p) ).mag2() >
150 1000*G4GeometryTolerance::GetInstance()->GetRadialTolerance() ) )
166G4SubtractionSolid::SurfaceNormal(
const G4ThreeVector& p )
const
168 G4ThreeVector normal;
169 if( Inside(p) == kOutside )
172 G4cout <<
"WARNING - Invalid call [1] in "
173 <<
"G4SubtractionSolid::SurfaceNormal(p)" << G4endl
174 <<
" Point p is inside !" << G4endl;
175 G4cout <<
" p = " << p << G4endl;
176 G4cerr <<
"WARNING - Invalid call [1] in "
177 <<
"G4SubtractionSolid::SurfaceNormal(p)" << G4endl
178 <<
" Point p is inside !" << G4endl;
179 G4cerr <<
" p = " << p << G4endl;
184 if( fPtrSolidA->Inside(p) == kSurface &&
185 fPtrSolidB->Inside(p) != kInside )
187 normal = fPtrSolidA->SurfaceNormal(p) ;
189 else if( fPtrSolidA->Inside(p) == kInside &&
190 fPtrSolidB->Inside(p) != kOutside )
192 normal = -fPtrSolidB->SurfaceNormal(p) ;
196 if ( fPtrSolidA->DistanceToOut(p) <= fPtrSolidB->DistanceToIn(p) )
198 normal = fPtrSolidA->SurfaceNormal(p) ;
202 normal = -fPtrSolidB->SurfaceNormal(p) ;
205 if(Inside(p) == kInside)
207 G4cout <<
"WARNING - Invalid call [2] in "
208 <<
"G4SubtractionSolid::SurfaceNormal(p)" << G4endl
209 <<
" Point p is inside !" << G4endl;
210 G4cout <<
" p = " << p << G4endl;
211 G4cerr <<
"WARNING - Invalid call [2] in "
212 <<
"G4SubtractionSolid::SurfaceNormal(p)" << G4endl
213 <<
" Point p is inside !" << G4endl;
214 G4cerr <<
" p = " << p << G4endl;
227G4SubtractionSolid::DistanceToIn(
const G4ThreeVector& p,
228 const G4ThreeVector&
v )
const
230 G4double dist = 0.0,disTmp = 0.0 ;
233 if( Inside(p) == kInside )
235 G4cout <<
"WARNING - Invalid call in "
236 <<
"G4SubtractionSolid::DistanceToIn(p,v)" << G4endl
237 <<
" Point p is inside !" << G4endl;
238 G4cout <<
" p = " << p << G4endl;
239 G4cout <<
" v = " <<
v << G4endl;
240 G4cerr <<
"WARNING - Invalid call in "
241 <<
"G4SubtractionSolid::DistanceToIn(p,v)" << G4endl
242 <<
" Point p is inside !" << G4endl;
243 G4cerr <<
" p = " << p << G4endl;
244 G4cerr <<
" v = " <<
v << G4endl;
249 if ( fPtrSolidB->Inside(p) != kOutside )
251 dist = fPtrSolidB->DistanceToOut(p,
v) ;
253 if( fPtrSolidA->Inside(p+dist*
v) != kInside )
257 disTmp = fPtrSolidA->DistanceToIn(p+dist*
v,
v) ;
259 if(disTmp == kInfinity)
265 if( Inside(p+dist*
v) == kOutside )
267 disTmp = fPtrSolidB->DistanceToOut(p+dist*
v,
v) ;
271 while( Inside(p+dist*
v) == kOutside ) ;
276 dist = fPtrSolidA->DistanceToIn(p,
v) ;
278 if( dist == kInfinity )
285 while( Inside(p+dist*
v) == kOutside )
289 std::cout<<
"G4SubtractionSolid::DistanceToIn loop >10000"<<std::endl;
292 disTmp = fPtrSolidB->DistanceToOut(p+dist*
v,
v) ;
295 if( Inside(p+dist*
v) == kOutside )
297 disTmp = fPtrSolidA->DistanceToIn(p+dist*
v,
v) ;
299 if(disTmp == kInfinity)
319G4SubtractionSolid::DistanceToIn(
const G4ThreeVector& p )
const
324 if( Inside(p) == kInside )
326 G4cout <<
"WARNING - Invalid call in "
327 <<
"G4SubtractionSolid::DistanceToIn(p)" << G4endl
328 <<
" Point p is inside !" << G4endl;
329 G4cout <<
" p = " << p << G4endl;
330 G4cerr <<
"WARNING - Invalid call in "
331 <<
"G4SubtractionSolid::DistanceToIn(p)" << G4endl
332 <<
" Point p is inside !" << G4endl;
333 G4cerr <<
" p = " << p << G4endl;
337 if( ( fPtrSolidA->Inside(p) != kOutside) &&
338 ( fPtrSolidB->Inside(p) != kOutside) )
340 dist= fPtrSolidB->DistanceToOut(p) ;
344 dist= fPtrSolidA->DistanceToIn(p) ;
355G4SubtractionSolid::DistanceToOut(
const G4ThreeVector& p,
356 const G4ThreeVector&
v,
357 const G4bool calcNorm,
359 G4ThreeVector *
n )
const
362 if( Inside(p) == kOutside )
364 G4cout <<
"Position:" << G4endl << G4endl;
365 G4cout <<
"p.x() = " << p.x()/mm <<
" mm" << G4endl;
366 G4cout <<
"p.y() = " << p.y()/mm <<
" mm" << G4endl;
367 G4cout <<
"p.z() = " << p.z()/mm <<
" mm" << G4endl << G4endl;
368 G4cout <<
"Direction:" << G4endl << G4endl;
369 G4cout <<
"v.x() = " <<
v.x() << G4endl;
370 G4cout <<
"v.y() = " <<
v.y() << G4endl;
371 G4cout <<
"v.z() = " <<
v.z() << G4endl << G4endl;
372 G4cout <<
"WARNING - Invalid call in "
373 <<
"G4SubtractionSolid::DistanceToOut(p,v)" << G4endl
374 <<
" Point p is outside !" << G4endl;
375 G4cout <<
" p = " << p << G4endl;
376 G4cout <<
" v = " <<
v << G4endl;
377 G4cerr <<
"WARNING - Invalid call in "
378 <<
"G4SubtractionSolid::DistanceToOut(p,v)" << G4endl
379 <<
" Point p is outside !" << G4endl;
380 G4cerr <<
" p = " << p << G4endl;
381 G4cerr <<
" v = " <<
v << G4endl;
386 G4double distA = fPtrSolidA->DistanceToOut(p,
v,calcNorm,validNorm,
n) ;
387 G4double distB = fPtrSolidB->DistanceToIn(p,
v) ;
392 *
n = -(fPtrSolidB->SurfaceNormal(p+distB*
v)) ;
409G4SubtractionSolid::DistanceToOut(
const G4ThreeVector& p )
const
413 if( Inside(p) == kOutside )
416 G4cout <<
"WARNING - Invalid call in "
417 <<
"G4SubtractionSolid::DistanceToOut(p)" << G4endl
418 <<
" Point p is outside" << G4endl;
419 G4cout <<
" p = " << p << G4endl;
420 G4cerr <<
"WARNING - Invalid call in "
421 <<
"G4SubtractionSolid::DistanceToOut(p)" << G4endl
422 <<
" Point p is outside" << G4endl;
423 G4cerr <<
" p = " << p << G4endl;
428 dist= std::min(fPtrSolidA->DistanceToOut(p),
429 fPtrSolidB->DistanceToIn(p) ) ;
438G4GeometryType G4SubtractionSolid::GetEntityType()
const
440 return G4String(
"G4SubtractionSolid");
448G4SubtractionSolid::ComputeDimensions( G4VPVParameterisation*,
450 const G4VPhysicalVolume* )
459G4SubtractionSolid::DescribeYourselfTo ( G4VGraphicsScene& scene )
const
461 scene.AddSolid (*
this);
469G4SubtractionSolid::CreatePolyhedron ()
const
471 G4Polyhedron* pA = fPtrSolidA->GetPolyhedron();
472 G4Polyhedron* pB = fPtrSolidB->GetPolyhedron();
475 G4Polyhedron* resultant =
new G4Polyhedron (pA->subtract(*pB));
480 std::ostringstream oss;
481 oss <<
"Solid - " << GetName()
482 <<
" - one of the Boolean components has no" << G4endl
483 <<
" corresponding polyhedron. Returning NULL !";
484 G4Exception(
"G4SubtractionSolid::CreatePolyhedron()",
"InvalidSetup",
485 JustWarning, oss.str().c_str());
495G4SubtractionSolid::CreateNURBS ()
const
**********Class see also m_nmax DOUBLE PRECISION m_amel DOUBLE PRECISION m_x2 DOUBLE PRECISION m_alfinv DOUBLE PRECISION m_Xenph INTEGER m_KeyWtm INTEGER m_idyfs DOUBLE PRECISION m_zini DOUBLE PRECISION m_q2 DOUBLE PRECISION m_Wt_KF DOUBLE PRECISION m_WtCut INTEGER m_KFfin *COMMON c_KarLud $ !Input CMS energy[GeV] $ !CMS energy after beam spread beam strahlung[GeV] $ !Beam energy spread[GeV] $ !z boost due to beam spread $ !electron beam mass *ff pair spectrum $ !minimum v