80 G4int localNoDaughters;
85 motherSolid = motherLogical->
GetSolid();
91 G4cout <<
"*** G4VoxelSafety::ComputeSafety(): ***" <<
G4endl;
100 #ifdef G4DEBUG_NAVIGATION
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;
145 currentPhysical, 0.0, ourSafety);
146 ourSafety=
std::min( motherSafety, daughterSafety );
163 G4int curNoVolumes, contentNo, sampleNo;
172 for ( contentNo=curNoVolumes-1; contentNo>=0; contentNo-- )
174 sampleNo = curVoxelNode->
GetVolume(contentNo);
183 samplePoint = sampleTf.TransformPoint(localPoint);
187 ourSafety =
std::min( sampleSafety, ourSafety );
191 G4cout <<
"*** G4VoxelSafety::SafetyForVoxelNode(): ***" <<
G4endl
192 <<
" Invoked DistanceToIn(p) for daughter solid: "
194 <<
". Solid replied: " << sampleSafety <<
G4endl
195 <<
" For local point p: " << samplePoint
196 <<
", to be considered as 'daughter safety'." <<
G4endl;
225 EAxis targetHeaderAxis;
226 G4double targetHeaderMin, targetHeaderMax, targetHeaderNodeWidth;
227 G4int targetHeaderNoSlices;
230 G4double minSafety = previousMinSafety;
232 unsigned int checkedNum= 0;
237 targetHeaderAxis = targetVoxelHeader->
GetAxis();
238 targetHeaderNoSlices = targetVoxelHeader->
GetNoSlices();
242 targetHeaderNodeWidth = (targetHeaderMax-targetHeaderMin)
243 / targetHeaderNoSlices;
245 G4double localCrd = localPoint(targetHeaderAxis);
247 const G4int candNodeNo =
G4int( (localCrd-targetHeaderMin)
248 / targetHeaderNodeWidth );
251 #ifdef G4DEBUG_VOXELISATION
252 if( candNodeNo < 0 || candNodeNo > targetHeaderNoSlices-1 )
255 ed <<
" Potential ERROR."
256 <<
" Point is outside range of Voxel in current coordinate" <<
G4endl;
257 ed <<
" Node number of point " << localPoint
258 <<
"is outside the range. " <<
G4endl;
259 ed <<
" Voxel node Num= " << candNodeNo <<
" versus minimum= " << 0
260 <<
" and maximum= " << targetHeaderNoSlices-1 <<
G4endl;
261 ed <<
" Axis = " << targetHeaderAxis
262 <<
" No of slices = " << targetHeaderNoSlices <<
G4endl;
263 ed <<
" Local coord = " << localCrd
264 <<
" Voxel Min = " << targetHeaderMin
265 <<
" Max = " << targetHeaderMax <<
G4endl;
267 ed <<
" Current volume (physical) = " << currentPhysical.
GetName()
272 G4Exception(
"G4VoxelSafety::SafetyForVoxelHeader()",
"GeomNav1003",
274 "Point is outside range of Voxel in current coordinate");
278 const G4int pointNodeNo =
285 G4cout <<
"**** G4VoxelSafety::SafetyForVoxelHeader " <<
G4endl;
287 G4cout <<
" Calculated pointNodeNo= " << pointNodeNo
288 <<
" from position= " << localPoint(targetHeaderAxis)
289 <<
" min= " << targetHeaderMin
290 <<
" max= " << targetHeaderMax
291 <<
" width= " << targetHeaderNodeWidth
292 <<
" no-slices= " << targetHeaderNoSlices
293 <<
" axis= " << targetHeaderAxis <<
G4endl;
298 <<
" Number of Slices = " << targetHeaderNoSlices
299 <<
" Header (address) = " << targetVoxelHeader <<
G4endl;
311 G4int trialUp = -1, trialDown = -1;
316 G4int nextUp = pointNodeNo+1;
317 G4int nextDown = pointNodeNo-1;
319 G4int nextNodeNo = pointNodeNo;
323 G4bool nextIsInside =
false;
330 targetNodeNo = pointNodeNo;
338 sampleProxy = targetVoxelHeader->
GetSlice(targetNodeNo);
340 #ifdef G4DEBUG_NAVIGATION
341 assert( sampleProxy != 0);
344 G4cout <<
" -Checking node " << targetNodeNo
345 <<
" is proxy with address " << sampleProxy <<
G4endl;
349 if ( sampleProxy == 0 )
352 ed <<
" Problem for node number= " << targetNodeNo
353 <<
" Number of slides = " << targetHeaderNoSlices
355 G4Exception(
"G4VoxelSafety::SafetyForVoxelHeader()",
"GeomNav0003",
357 "Problem sampleProxy is Zero. Failure in loop.");
359 else if ( sampleProxy->
IsNode() )
361 targetVoxelNode = sampleProxy->
GetNode();
366 #ifdef G4DEBUG_NAVIGATION
369 G4cout <<
" -- It is a Node ";
370 G4cout <<
" its safety= " << nodeSafety
371 <<
" our level Saf = " << ourSafety
372 <<
" MinSaf= " << minSafety <<
G4endl;
375 ourSafety=
std::min( ourSafety, nodeSafety );
385 distCombined_Sq = distUpperDepth_Sq + distAxis*distAxis;
387 #ifdef G4DEBUG_NAVIGATION
390 G4double distCombined= std::sqrt( distCombined_Sq );
391 G4double distUpperDepth= std::sqrt ( distUpperDepth_Sq );
393 G4cout <<
" Recurse to deal with next level, fVoxelDepth= "
395 G4cout <<
" Distances: Upper= " << distUpperDepth
396 <<
" Axis= " << distAxis
397 <<
" Combined= " << distCombined <<
G4endl;
404 maxLength, currentPhysical,
405 distCombined_Sq, minSafety);
406 ourSafety =
std::min( ourSafety, headerSafety );
408 #ifdef G4DEBUG_NAVIGATION
411 G4cout <<
" >> Header safety = " << headerSafety
412 <<
" our level Saf = " << ourSafety <<
G4endl;
418 minSafety =
std::min( minSafety, ourSafety );
424 if( targetNodeNo >= pointNodeNo )
428 G4double lowerEdgeOfNext = targetHeaderMin
429 + nextUp * targetHeaderNodeWidth;
430 distUp = lowerEdgeOfNext-localCrd ;
435 #ifdef G4DEBUG_NAVIGATION
443 if( targetNodeNo <= pointNodeNo )
445 nextDown = trialDown;
447 G4double upperEdgeOfNext = targetHeaderMin
448 + (nextDown+1) * targetHeaderNodeWidth;
449 distDown = localCrd-upperEdgeOfNext;
454 #ifdef G4DEBUG_NAVIGATION
457 G4cout <<
" > Updated nextDown= " << nextDown <<
G4endl;
462 #ifdef G4DEBUG_NAVIGATION
465 G4cout <<
" Node= " << pointNodeNo
466 <<
" Up: next= " << nextUp <<
" d# "
467 << nextUp - pointNodeNo
468 <<
" trialUp= " << trialUp <<
" d# "
469 << trialUp - pointNodeNo
470 <<
" Down: next= " << nextDown <<
" d# "
471 << targetNodeNo - nextDown
472 <<
" trialDwn= " << trialDown <<
" d# "
473 << targetNodeNo - trialDown
474 <<
" condition (next is Inside)= " << nextIsInside
480 UpIsClosest = distUp < distDown;
482 if( (nextUp < targetHeaderNoSlices)
483 && (UpIsClosest || (nextDown < 0)) )
492 <<
" Nodes: next= " << nextNodeNo
493 <<
" new nextUp= " << nextUp
494 <<
" Dist = " << distAxis <<
G4endl;
500 nextNodeNo = nextDown;
507 <<
" Nodes: next= " << nextNodeNo
508 <<
" new nextDown= " << nextDown
509 <<
" Dist = " << distAxis <<
G4endl;
514 nextIsInside = (nextNodeNo >= 0) && (nextNodeNo < targetHeaderNoSlices);
517 targetNodeNo= nextNodeNo;
519 #ifdef G4DEBUG_NAVIGATION
520 assert( targetVoxelHeader->
GetSlice(nextNodeNo) != 0 );
521 G4bool bContinue = (distAxis<minSafety);
526 G4cout <<
" Can skip remaining at depth " << targetHeaderAxis
527 <<
" >> distAxis= " << distAxis
528 <<
" minSafety= " << minSafety <<
G4endl;
535 #ifdef G4DEBUG_NAVIGATION
539 G4cout <<
" VoxSaf> No more candidates: nodeDown= " << nextDown
540 <<
" nodeUp= " << nextUp
541 <<
" lastSlice= " << targetHeaderNoSlices <<
G4endl;
548 distMaxInterest =
std::min( minSafety, maxLength );
550 }
while ( nextIsInside && ( distAxis*distAxis + distUpperDepth_Sq
551 < distMaxInterest*distMaxInterest ) );
556 G4cout <<
" Ended for targetNodeNo -- checked " << checkedNum <<
" out of "
557 << targetHeaderNoSlices <<
" slices." <<
G4endl;
558 G4cout <<
" ===== Returning from SafetyForVoxelHeader "