46 fVoxelAxisStack(kNavigatorVoxelStackMax,
kXAxis),
47 fVoxelNoSlicesStack(kNavigatorVoxelStackMax,0),
48 fVoxelSliceWidthStack(kNavigatorVoxelStackMax,0.),
49 fVoxelNodeNoStack(kNavigatorVoxelStackMax,0),
80 G4int localNoDaughters;
84 fpMotherLogical= motherLogical;
85 motherSolid = motherLogical->
GetSolid();
91 G4cout <<
"*** G4VoxelSafety::ComputeSafety(): ***" <<
G4endl;
100#ifdef G4DEBUG_NAVIGATION
103 std::ostringstream message;
104 message <<
"Safety method called for location outside current Volume."
106 <<
"Location for safety is Outside this volume. " <<
G4endl
107 <<
"The approximate distance to the solid "
108 <<
"(safety from outside) is: "
110 message <<
" Problem occurred with physical volume: "
111 <<
" Name: " << currentPhysical.
GetName()
113 <<
" Local Point = " << localPoint <<
G4endl;
114 message <<
" Description of solid: " <<
G4endl
115 << *motherSolid <<
G4endl;
116 G4Exception(
"G4VoxelSafety::ComputeSafety()",
"GeomNav0003",
126 ourSafety = motherSafety;
131 G4cout <<
" Invoked DistanceToOut(p) for mother solid: "
133 <<
". Solid replied: " << motherSafety <<
G4endl
134 <<
" For local point p: " << localPoint
135 <<
", to be considered as 'mother safety'." <<
G4endl;
140 fBlockList.
Enlarge(localNoDaughters);
145 currentPhysical, 0.0, ourSafety);
146 ourSafety= std::min( motherSafety, daughterSafety );
163 G4long curNoVolumes, contentNo;
173 for ( contentNo=curNoVolumes-1; contentNo>=0; contentNo-- )
180 samplePhysical = fpMotherLogical->
GetDaughter(sampleNo);
188 ourSafety = std::min( sampleSafety, ourSafety );
190 if(( fCheck ) && ( fVerbose == 1 ))
192 G4cout <<
"*** G4VoxelSafety::SafetyForVoxelNode(): ***" <<
G4endl
193 <<
" Invoked DistanceToIn(p) for daughter solid: "
195 <<
". Solid replied: " << sampleSafety <<
G4endl
196 <<
" For local point p: " << samplePoint
197 <<
", to be considered as 'daughter safety'." <<
G4endl;
226 EAxis targetHeaderAxis;
227 G4double targetHeaderMin, targetHeaderMax, targetHeaderNodeWidth;
228 G4int targetHeaderNoSlices;
231 G4double minSafety = previousMinSafety;
233 unsigned int checkedNum= 0;
238 targetHeaderAxis = targetVoxelHeader->
GetAxis();
243 targetHeaderNodeWidth = (targetHeaderMax-targetHeaderMin)
244 / targetHeaderNoSlices;
246 G4double localCrd = localPoint(targetHeaderAxis);
248 const G4int candNodeNo =
G4int( (localCrd-targetHeaderMin)
249 / targetHeaderNodeWidth );
252#ifdef G4DEBUG_VOXELISATION
253 if( candNodeNo < 0 || candNodeNo > targetHeaderNoSlices-1 )
256 ed <<
" Potential ERROR."
257 <<
" Point is outside range of Voxel in current coordinate" <<
G4endl;
258 ed <<
" Node number of point " << localPoint
259 <<
"is outside the range. " <<
G4endl;
260 ed <<
" Voxel node Num= " << candNodeNo <<
" versus minimum= " << 0
261 <<
" and maximum= " << targetHeaderNoSlices-1 <<
G4endl;
262 ed <<
" Axis = " << targetHeaderAxis
263 <<
" No of slices = " << targetHeaderNoSlices <<
G4endl;
264 ed <<
" Local coord = " << localCrd
265 <<
" Voxel Min = " << targetHeaderMin
266 <<
" Max = " << targetHeaderMax <<
G4endl;
268 ed <<
" Current volume (physical) = " << currentPhysical.
GetName()
273 G4Exception(
"G4VoxelSafety::SafetyForVoxelHeader()",
"GeomNav1003",
275 "Point is outside range of Voxel in current coordinate");
279 const G4int pointNodeNo =
280 std::max( 0, std::min( candNodeNo, targetHeaderNoSlices-1 ) );
286 G4cout <<
"**** G4VoxelSafety::SafetyForVoxelHeader " <<
G4endl;
287 G4cout <<
" Called at Depth = " << fVoxelDepth;
288 G4cout <<
" Calculated pointNodeNo= " << pointNodeNo
289 <<
" from position= " << localPoint(targetHeaderAxis)
290 <<
" min= " << targetHeaderMin
291 <<
" max= " << targetHeaderMax
292 <<
" width= " << targetHeaderNodeWidth
293 <<
" no-slices= " << targetHeaderNoSlices
294 <<
" axis= " << targetHeaderAxis <<
G4endl;
296 else if (fVerbose == 1)
298 G4cout <<
" VoxelSafety: Depth = " << fVoxelDepth
299 <<
" Number of Slices = " << targetHeaderNoSlices
300 <<
" Header (address) = " << targetVoxelHeader <<
G4endl;
306 fVoxelAxisStack[fVoxelDepth] = targetHeaderAxis;
307 fVoxelNoSlicesStack[fVoxelDepth] = targetHeaderNoSlices;
308 fVoxelSliceWidthStack[fVoxelDepth] = targetHeaderNodeWidth;
310 fVoxelHeaderStack[fVoxelDepth] = pHeader;
312 G4int trialUp = -1, trialDown = -1;
317 G4int nextUp = pointNodeNo+1;
318 G4int nextDown = pointNodeNo-1;
320 G4int nextNodeNo = pointNodeNo;
324 G4bool nextIsInside =
false;
326 G4double distMaxInterest= std::min( previousMinSafety, maxLength);
331 targetNodeNo = pointNodeNo;
335 fVoxelNodeNoStack[fVoxelDepth] = targetNodeNo;
339 sampleProxy = targetVoxelHeader->
GetSlice(targetNodeNo);
341#ifdef G4DEBUG_NAVIGATION
342 assert( sampleProxy != 0);
345 G4cout <<
" -Checking node " << targetNodeNo
346 <<
" is proxy with address " << sampleProxy <<
G4endl;
350 if ( sampleProxy == 0 )
353 ed <<
" Problem for node number= " << targetNodeNo
354 <<
" Number of slides = " << targetHeaderNoSlices
356 G4Exception(
"G4VoxelSafety::SafetyForVoxelHeader()",
"GeomNav0003",
358 "Problem sampleProxy is Zero. Failure in loop.");
360 else if ( sampleProxy->
IsNode() )
362 targetVoxelNode = sampleProxy->
GetNode();
367#ifdef G4DEBUG_NAVIGATION
370 G4cout <<
" -- It is a Node ";
371 G4cout <<
" its safety= " << nodeSafety
372 <<
" our level Saf = " << ourSafety
373 <<
" MinSaf= " << minSafety <<
G4endl;
376 ourSafety= std::min( ourSafety, nodeSafety );
386 distCombined_Sq = distUpperDepth_Sq + distAxis*distAxis;
388#ifdef G4DEBUG_NAVIGATION
391 G4double distCombined= std::sqrt( distCombined_Sq );
392 G4double distUpperDepth= std::sqrt ( distUpperDepth_Sq );
394 G4cout <<
" Recurse to deal with next level, fVoxelDepth= "
395 << fVoxelDepth+1 <<
G4endl;
396 G4cout <<
" Distances: Upper= " << distUpperDepth
397 <<
" Axis= " << distAxis
398 <<
" Combined= " << distCombined <<
G4endl;
405 maxLength, currentPhysical,
406 distCombined_Sq, minSafety);
407 ourSafety = std::min( ourSafety, headerSafety );
409#ifdef G4DEBUG_NAVIGATION
412 G4cout <<
" >> Header safety = " << headerSafety
413 <<
" our level Saf = " << ourSafety <<
G4endl;
419 minSafety = std::min( minSafety, ourSafety );
425 if( targetNodeNo >= pointNodeNo )
429 G4double lowerEdgeOfNext = targetHeaderMin
430 + nextUp * targetHeaderNodeWidth;
431 distUp = lowerEdgeOfNext-localCrd ;
436#ifdef G4DEBUG_NAVIGATION
444 if( targetNodeNo <= pointNodeNo )
446 nextDown = trialDown;
448 G4double upperEdgeOfNext = targetHeaderMin
449 + (nextDown+1) * targetHeaderNodeWidth;
450 distDown = localCrd-upperEdgeOfNext;
455#ifdef G4DEBUG_NAVIGATION
458 G4cout <<
" > Updated nextDown= " << nextDown <<
G4endl;
463#ifdef G4DEBUG_NAVIGATION
466 G4cout <<
" Node= " << pointNodeNo
467 <<
" Up: next= " << nextUp <<
" d# "
468 << nextUp - pointNodeNo
469 <<
" trialUp= " << trialUp <<
" d# "
470 << trialUp - pointNodeNo
471 <<
" Down: next= " << nextDown <<
" d# "
472 << targetNodeNo - nextDown
473 <<
" trialDwn= " << trialDown <<
" d# "
474 << targetNodeNo - trialDown
475 <<
" condition (next is Inside)= " << nextIsInside
481 UpIsClosest = distUp < distDown;
483 if( (nextUp < targetHeaderNoSlices)
484 && (UpIsClosest || (nextDown < 0)) )
492 G4cout <<
" > Chose Up. Depth= " << fVoxelDepth
493 <<
" Nodes: next= " << nextNodeNo
494 <<
" new nextUp= " << nextUp
495 <<
" Dist = " << distAxis <<
G4endl;
501 nextNodeNo = nextDown;
507 G4cout <<
" > Chose Down. Depth= " << fVoxelDepth
508 <<
" Nodes: next= " << nextNodeNo
509 <<
" new nextDown= " << nextDown
510 <<
" Dist = " << distAxis <<
G4endl;
515 nextIsInside = (nextNodeNo >= 0) && (nextNodeNo < targetHeaderNoSlices);
518 targetNodeNo= nextNodeNo;
520#ifdef G4DEBUG_NAVIGATION
521 assert( targetVoxelHeader->
GetSlice(nextNodeNo) != 0 );
522 G4bool bContinue = (distAxis<minSafety);
527 G4cout <<
" Can skip remaining at depth " << targetHeaderAxis
528 <<
" >> distAxis= " << distAxis
529 <<
" minSafety= " << minSafety <<
G4endl;
536#ifdef G4DEBUG_NAVIGATION
540 G4cout <<
" VoxSaf> No more candidates: nodeDown= " << nextDown
541 <<
" nodeUp= " << nextUp
542 <<
" lastSlice= " << targetHeaderNoSlices <<
G4endl;
549 distMaxInterest = std::min( minSafety, maxLength );
551 }
while ( nextIsInside && ( distAxis*distAxis + distUpperDepth_Sq
552 < distMaxInterest*distMaxInterest ) );
557 G4cout <<
" Ended for targetNodeNo -- checked " << checkedNum <<
" out of "
558 << targetHeaderNoSlices <<
" slices." <<
G4endl;
559 G4cout <<
" ===== Returning from SafetyForVoxelHeader "
560 <<
" Depth= " << fVoxelDepth <<
G4endl
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
G4GLOB_DLL std::ostream G4cout
void BlockVolume(const G4int v)
void Enlarge(const G4int nv)
G4bool IsBlocked(const G4int v) const
G4double GetSurfaceTolerance() const
static G4GeometryTolerance * GetInstance()
G4VSolid * GetSolid() const
std::size_t GetNoDaughters() const
G4VPhysicalVolume * GetDaughter(const std::size_t i) const
const G4String & GetName() const
G4SmartVoxelHeader * GetVoxelHeader() const
G4int GetMaxEquivalentSliceNo() const
G4int GetVolume(G4int pVolumeNo) const
std::size_t GetNoContained() const
G4int GetMinEquivalentSliceNo() const
G4SmartVoxelNode * GetNode() const
G4SmartVoxelHeader * GetHeader() const
const G4RotationMatrix * GetRotation() const
const G4ThreeVector GetTranslation() const
G4LogicalVolume * GetLogicalVolume() const
virtual G4int GetCopyNo() const =0
const G4String & GetName() const
virtual EInside Inside(const G4ThreeVector &p) const =0
virtual G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=false, G4bool *validNorm=nullptr, G4ThreeVector *n=nullptr) const =0
virtual G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const =0
virtual G4GeometryType GetEntityType() const =0
G4double ComputeSafety(const G4ThreeVector &localPoint, const G4VPhysicalVolume ¤tPhysical, G4double maxLength=DBL_MAX)
G4double SafetyForVoxelHeader(const G4SmartVoxelHeader *pHead, const G4ThreeVector &localPoint, G4double maxLength, const G4VPhysicalVolume ¤tPhysical, G4double distUpperDepth=0.0, G4double previousMinSafety=DBL_MAX)
G4double SafetyForVoxelNode(const G4SmartVoxelNode *curVoxelNode, const G4ThreeVector &localPoint)