77 G4int localNoDaughters;
81 fpMotherLogical= motherLogical;
82 motherSolid = motherLogical->
GetSolid();
88 G4cout <<
"*** G4VoxelSafety::ComputeSafety(): ***" <<
G4endl;
97#ifdef G4DEBUG_NAVIGATION
100 std::ostringstream message;
101 message <<
"Safety method called for location outside current Volume."
103 <<
"Location for safety is Outside this volume. " <<
G4endl
104 <<
"The approximate distance to the solid "
105 <<
"(safety from outside) is: "
107 message <<
" Problem occurred with physical volume: "
108 <<
" Name: " << currentPhysical.
GetName()
110 <<
" Local Point = " << localPoint <<
G4endl;
111 message <<
" Description of solid: " <<
G4endl
112 << *motherSolid <<
G4endl;
113 G4Exception(
"G4VoxelSafety::ComputeSafety()",
"GeomNav0003",
123 ourSafety = motherSafety;
128 G4cout <<
" Invoked DistanceToOut(p) for mother solid: "
130 <<
". Solid replied: " << motherSafety <<
G4endl
131 <<
" For local point p: " << localPoint
132 <<
", to be considered as 'mother safety'." <<
G4endl;
137 fBlockList.
Enlarge(localNoDaughters);
142 currentPhysical, 0.0, ourSafety);
143 ourSafety= std::min( motherSafety, daughterSafety );
223 EAxis targetHeaderAxis;
224 G4double targetHeaderMin, targetHeaderMax, targetHeaderNodeWidth;
225 G4int targetHeaderNoSlices;
228 G4double minSafety = previousMinSafety;
230 unsigned int checkedNum= 0;
235 targetHeaderAxis = targetVoxelHeader->
GetAxis();
240 targetHeaderNodeWidth = (targetHeaderMax-targetHeaderMin)
241 / targetHeaderNoSlices;
243 G4double localCrd = localPoint(targetHeaderAxis);
245 const auto candNodeNo =
G4int( (localCrd-targetHeaderMin)
246 / targetHeaderNodeWidth );
249#ifdef G4DEBUG_VOXELISATION
250 if( candNodeNo < 0 || candNodeNo > targetHeaderNoSlices-1 )
253 ed <<
" Potential ERROR."
254 <<
" Point is outside range of Voxel in current coordinate" <<
G4endl;
255 ed <<
" Node number of point " << localPoint
256 <<
"is outside the range. " <<
G4endl;
257 ed <<
" Voxel node Num= " << candNodeNo <<
" versus minimum= " << 0
258 <<
" and maximum= " << targetHeaderNoSlices-1 <<
G4endl;
259 ed <<
" Axis = " << targetHeaderAxis
260 <<
" No of slices = " << targetHeaderNoSlices <<
G4endl;
261 ed <<
" Local coord = " << localCrd
262 <<
" Voxel Min = " << targetHeaderMin
263 <<
" Max = " << targetHeaderMax <<
G4endl;
265 ed <<
" Current volume (physical) = " << currentPhysical.
GetName()
270 G4Exception(
"G4VoxelSafety::SafetyForVoxelHeader()",
"GeomNav1003",
272 "Point is outside range of Voxel in current coordinate");
276 const G4int pointNodeNo =
277 std::max( 0, std::min( candNodeNo, targetHeaderNoSlices-1 ) );
283 G4cout <<
"**** G4VoxelSafety::SafetyForVoxelHeader " <<
G4endl;
284 G4cout <<
" Called at Depth = " << fVoxelDepth;
285 G4cout <<
" Calculated pointNodeNo= " << pointNodeNo
286 <<
" from position= " << localPoint(targetHeaderAxis)
287 <<
" min= " << targetHeaderMin
288 <<
" max= " << targetHeaderMax
289 <<
" width= " << targetHeaderNodeWidth
290 <<
" no-slices= " << targetHeaderNoSlices
291 <<
" axis= " << targetHeaderAxis <<
G4endl;
293 else if (fVerbose == 1)
295 G4cout <<
" VoxelSafety: Depth = " << fVoxelDepth
296 <<
" Number of Slices = " << targetHeaderNoSlices
297 <<
" Header (address) = " << targetVoxelHeader <<
G4endl;
303 fVoxelAxisStack[fVoxelDepth] = targetHeaderAxis;
304 fVoxelNoSlicesStack[fVoxelDepth] = targetHeaderNoSlices;
305 fVoxelSliceWidthStack[fVoxelDepth] = targetHeaderNodeWidth;
307 fVoxelHeaderStack[fVoxelDepth] = pHeader;
309 G4int trialUp = -1, trialDown = -1;
314 G4int nextUp = pointNodeNo+1;
315 G4int nextDown = pointNodeNo-1;
317 G4int nextNodeNo = pointNodeNo;
321 G4bool nextIsInside =
false;
323 G4double distMaxInterest= std::min( previousMinSafety, maxLength);
328 targetNodeNo = pointNodeNo;
332 fVoxelNodeNoStack[fVoxelDepth] = targetNodeNo;
336 sampleProxy = targetVoxelHeader->
GetSlice(targetNodeNo);
338#ifdef G4DEBUG_NAVIGATION
339 assert( sampleProxy != 0);
342 G4cout <<
" -Checking node " << targetNodeNo
343 <<
" is proxy with address " << sampleProxy <<
G4endl;
347 if ( sampleProxy ==
nullptr )
350 ed <<
" Problem for node number= " << targetNodeNo
351 <<
" Number of slides = " << targetHeaderNoSlices
353 G4Exception(
"G4VoxelSafety::SafetyForVoxelHeader()",
"GeomNav0003",
355 "Problem sampleProxy is Zero. Failure in loop.");
357 else if ( sampleProxy->
IsNode() )
359 targetVoxelNode = sampleProxy->
GetNode();
364#ifdef G4DEBUG_NAVIGATION
367 G4cout <<
" -- It is a Node ";
368 G4cout <<
" its safety= " << nodeSafety
369 <<
" our level Saf = " << ourSafety
370 <<
" MinSaf= " << minSafety <<
G4endl;
373 ourSafety= std::min( ourSafety, nodeSafety );
383 distCombined_Sq = distUpperDepth_Sq + distAxis*distAxis;
385#ifdef G4DEBUG_NAVIGATION
388 G4double distCombined= std::sqrt( distCombined_Sq );
389 G4double distUpperDepth= std::sqrt ( distUpperDepth_Sq );
391 G4cout <<
" Recurse to deal with next level, fVoxelDepth= "
392 << fVoxelDepth+1 <<
G4endl;
393 G4cout <<
" Distances: Upper= " << distUpperDepth
394 <<
" Axis= " << distAxis
395 <<
" Combined= " << distCombined <<
G4endl;
402 maxLength, currentPhysical,
403 distCombined_Sq, minSafety);
404 ourSafety = std::min( ourSafety, headerSafety );
406#ifdef G4DEBUG_NAVIGATION
409 G4cout <<
" >> Header safety = " << headerSafety
410 <<
" our level Saf = " << ourSafety <<
G4endl;
416 minSafety = std::min( minSafety, ourSafety );
422 if( targetNodeNo >= pointNodeNo )
426 G4double lowerEdgeOfNext = targetHeaderMin
427 + nextUp * targetHeaderNodeWidth;
428 distUp = lowerEdgeOfNext-localCrd ;
433#ifdef G4DEBUG_NAVIGATION
441 if( targetNodeNo <= pointNodeNo )
443 nextDown = trialDown;
445 G4double upperEdgeOfNext = targetHeaderMin
446 + (nextDown+1) * targetHeaderNodeWidth;
447 distDown = localCrd-upperEdgeOfNext;
452#ifdef G4DEBUG_NAVIGATION
455 G4cout <<
" > Updated nextDown= " << nextDown <<
G4endl;
460#ifdef G4DEBUG_NAVIGATION
463 G4cout <<
" Node= " << pointNodeNo
464 <<
" Up: next= " << nextUp <<
" d# "
465 << nextUp - pointNodeNo
466 <<
" trialUp= " << trialUp <<
" d# "
467 << trialUp - pointNodeNo
468 <<
" Down: next= " << nextDown <<
" d# "
469 << targetNodeNo - nextDown
470 <<
" trialDwn= " << trialDown <<
" d# "
471 << targetNodeNo - trialDown
472 <<
" condition (next is Inside)= " << nextIsInside
478 UpIsClosest = distUp < distDown;
480 if( (nextUp < targetHeaderNoSlices)
481 && (UpIsClosest || (nextDown < 0)) )
489 G4cout <<
" > Chose Up. Depth= " << fVoxelDepth
490 <<
" Nodes: next= " << nextNodeNo
491 <<
" new nextUp= " << nextUp
492 <<
" Dist = " << distAxis <<
G4endl;
498 nextNodeNo = nextDown;
504 G4cout <<
" > Chose Down. Depth= " << fVoxelDepth
505 <<
" Nodes: next= " << nextNodeNo
506 <<
" new nextDown= " << nextDown
507 <<
" Dist = " << distAxis <<
G4endl;
512 nextIsInside = (nextNodeNo >= 0) && (nextNodeNo < targetHeaderNoSlices);
515 targetNodeNo= nextNodeNo;
517#ifdef G4DEBUG_NAVIGATION
518 assert( targetVoxelHeader->
GetSlice(nextNodeNo) != 0 );
519 G4bool bContinue = (distAxis<minSafety);
524 G4cout <<
" Can skip remaining at depth " << targetHeaderAxis
525 <<
" >> distAxis= " << distAxis
526 <<
" minSafety= " << minSafety <<
G4endl;
533#ifdef G4DEBUG_NAVIGATION
537 G4cout <<
" VoxSaf> No more candidates: nodeDown= " << nextDown
538 <<
" nodeUp= " << nextUp
539 <<
" lastSlice= " << targetHeaderNoSlices <<
G4endl;
546 distMaxInterest = std::min( minSafety, maxLength );
548 }
while ( nextIsInside && ( distAxis*distAxis + distUpperDepth_Sq
549 < distMaxInterest*distMaxInterest ) );
554 G4cout <<
" Ended for targetNodeNo -- checked " << checkedNum <<
" out of "
555 << targetHeaderNoSlices <<
" slices." <<
G4endl;
556 G4cout <<
" ===== Returning from SafetyForVoxelHeader "
557 <<
" Depth= " << fVoxelDepth <<
G4endl