91 const G4double currentProposedStepLength,
99 G4int& blockedReplicaNo )
105 G4double ourStep=currentProposedStepLength, ourSafety;
107 G4int localNoDaughters, sampleNo;
109 G4bool initialNode, noStep;
111 G4long curNoVolumes, contentNo;
116 motherSolid = motherLogical->
GetSolid();
123 ourSafety = motherSafety;
128 fLogger->PreComputeStepLog (motherPhysical, motherSafety, localPoint);
138 if ( exiting && validExitNormal )
140 if ( localDirection.
dot(exitNormal)>=kMinExitingNormalCosine )
144 blockedExitedVol = *pBlockedPhysical;
152 G4bool motherValidExitNormal =
false;
163 &motherValidExitNormal,
170 fBList.Enlarge(localNoDaughters);
180 for (contentNo=curNoVolumes-1; contentNo>=0; contentNo--)
183 if ( !
fBList.IsBlocked(sampleNo) )
185 fBList.BlockVolume(sampleNo);
186 samplePhysical = motherLogical->
GetDaughter(sampleNo);
187 if ( samplePhysical!=blockedExitedVol )
199 if ( sampleSafety<ourSafety )
201 ourSafety = sampleSafety;
203 if ( sampleSafety<=ourStep )
207 sampleSolid->
DistanceToIn(samplePoint, sampleDirection);
211 fLogger->PrintDaughterLog(sampleSolid, samplePoint,
213 sampleDirection, sampleStep);
216 if ( sampleStep<=ourStep )
218 ourStep = sampleStep;
221 *pBlockedPhysical = samplePhysical;
222 blockedReplicaNo = -1;
228 fLogger->AlongComputeStepLog (sampleSolid, samplePoint,
229 sampleDirection, localDirection, sampleSafety, sampleStep);
234 if (
fCheck && ( sampleStep < kInfinity )
235 && ( sampleStep >= motherStep ) )
239 fLogger->CheckDaughterEntryPoint(sampleSolid,
240 samplePoint, sampleDirection,
242 localPoint, localDirection,
243 motherStep, sampleStep);
252 fLogger->PrintDaughterLog(sampleSolid, samplePoint,
265 if ( voxelSafety<ourSafety )
267 ourSafety = voxelSafety;
269 if ( currentProposedStepLength<ourSafety )
276 *pBlockedPhysical =
nullptr;
284 if ( motherSafety<=ourStep )
287 motherStep = motherSolid->
DistanceToOut(localPoint, localDirection,
288 true, &motherValidExitNormal, &motherExitNormal);
292 fLogger->PostComputeStepLog(motherSolid, localPoint, localDirection,
293 motherStep, motherSafety);
294 if( motherValidExitNormal )
296 fLogger->CheckAndReportBadNormal(motherExitNormal,
297 localPoint, localDirection,
298 motherStep, motherSolid,
299 "From motherSolid::DistanceToOut" );
303 if( (motherStep >= kInfinity) || (motherStep < 0.0) )
308 fLogger->ReportOutsideMother(localPoint, localDirection,
321 validExitNormal=
false;
323 *pBlockedPhysical =
nullptr;
324 blockedReplicaNo = 0;
330 if ( motherStep<=ourStep )
332 ourStep = motherStep;
338 validExitNormal = motherValidExitNormal;
339 exitNormal = motherExitNormal;
341 if ( validExitNormal )
350 fLogger->CheckAndReportBadNormal(exitNormal,
353 "From RotationMatrix" );
361 validExitNormal =
false;
365 newSafety = ourSafety;
390 G4double curNodeOffset, minCurCommonDelta, maxCurCommonDelta;
391 G4int minCurNodeNoDelta, maxCurNodeNoDelta;
392 G4int localVoxelDepth, curNodeNo;
405 curNodeOffset = curNodeNo*curNodeWidth;
406 maxCurNodeNoDelta =
fVoxelNode->GetMaxEquivalentSliceNo()-curNodeNo;
407 minCurNodeNoDelta = curNodeNo-
fVoxelNode->GetMinEquivalentSliceNo();
408 minCurCommonDelta = localPoint(curHeaderAxis)
410 maxCurCommonDelta = curNodeWidth-minCurCommonDelta;
412 if ( minCurNodeNoDelta<maxCurNodeNoDelta )
414 voxelSafety = minCurNodeNoDelta*curNodeWidth;
415 voxelSafety += minCurCommonDelta;
417 else if (maxCurNodeNoDelta < minCurNodeNoDelta)
419 voxelSafety = maxCurNodeNoDelta*curNodeWidth;
420 voxelSafety += maxCurCommonDelta;
424 voxelSafety = minCurNodeNoDelta*curNodeWidth;
425 voxelSafety += std::min(minCurCommonDelta,maxCurCommonDelta);
432 while ( (localVoxelDepth>0) && (voxelSafety>0) )
439 curNodeOffset = curNodeNo*curNodeWidth;
440 minCurCommonDelta = localPoint(curHeaderAxis)
442 maxCurCommonDelta = curNodeWidth-minCurCommonDelta;
444 if ( minCurCommonDelta<voxelSafety )
446 voxelSafety = minCurCommonDelta;
448 if ( maxCurCommonDelta<voxelSafety )
450 voxelSafety = maxCurCommonDelta;
483 G4double workNodeWidth, workMinExtent, workCoord;
484 G4double minVal, maxVal, newDistance=0.;
485 G4double newHeaderMin, newHeaderNodeWidth;
486 G4int depth=0, newDepth=0, workNodeNo=0, newNodeNo=0, newHeaderNoSlices=0;
487 EAxis workHeaderAxis, newHeaderAxis;
488 G4bool isNewVoxel =
false;
490 G4double currentDistance = currentStep;
496 targetPoint = localPoint+localDirection*currentDistance;
497 newDistance = currentDistance;
503 workCoord = targetPoint(workHeaderAxis);
504 minVal = workMinExtent+workNodeNo*workNodeWidth;
508 maxVal = minVal+workNodeWidth;
513 newNodeNo = workNodeNo+1;
514 newHeader = workHeader;
515 newDistance = (maxVal-localPoint(workHeaderAxis))
516 / localDirection(workHeaderAxis);
523 newNodeNo = workNodeNo-1;
524 newHeader = workHeader;
525 newDistance = (minVal-localPoint(workHeaderAxis))
526 / localDirection(workHeaderAxis);
530 currentDistance = newDistance;
532 targetPoint = localPoint+localDirection*currentDistance;
543 workCoord = targetPoint(workHeaderAxis);
544 minVal = workMinExtent+
fVoxelNode->GetMinEquivalentSliceNo()*workNodeWidth;
548 maxVal = workMinExtent+(
fVoxelNode->GetMaxEquivalentSliceNo()+1)
552 newNodeNo =
fVoxelNode->GetMaxEquivalentSliceNo()+1;
553 newHeader = workHeader;
554 newDistance = (maxVal-localPoint(workHeaderAxis))
555 / localDirection(workHeaderAxis);
562 newNodeNo =
fVoxelNode->GetMinEquivalentSliceNo()-1;
563 newHeader = workHeader;
564 newDistance = (minVal-localPoint(workHeaderAxis))
565 / localDirection(workHeaderAxis);
569 currentDistance = newDistance;
580 if ( (newNodeNo<0) || (newNodeNo>=
G4int(newHeader->GetNoSlices())))
591 voxelPoint = localPoint+localDirection*newDistance;
594 newVoxelNode =
nullptr;
595 while ( newVoxelNode ==
nullptr )
597 newProxy = newHeader->GetSlice(newNodeNo);
600 newVoxelNode = newProxy->
GetNode();
606 newHeaderAxis = newHeader->
GetAxis();
607 newHeaderNoSlices = (
G4int)newHeader->GetNoSlices();
608 newHeaderMin = newHeader->GetMinExtent();
609 newHeaderNodeWidth = (newHeader->GetMaxExtent()-newHeaderMin)
611 newNodeNo =
G4int( (voxelPoint(newHeaderAxis)-newHeaderMin)
612 / newHeaderNodeWidth );
619 else if ( newNodeNo>=newHeaderNoSlices )
621 newNodeNo = newHeaderNoSlices-1;
657 G4long curNoVolumes, contentNo;
662 motherSolid = motherLogical->
GetSolid();
666 return fpVoxelSafety->ComputeSafety( localPoint,*motherPhysical,maxLength );
674 ourSafety = motherSafety;
676 if( motherSafety == 0.0 )
678#ifdef G4DEBUG_NAVIGATION
685 message <<
"Safety method called for location outside current Volume." <<
G4endl
686 <<
"Location for safety is Outside this volume. " <<
G4endl
687 <<
"The approximate distance to the solid "
688 <<
"(safety from outside) is: "
690 message <<
" Problem occurred with physical volume: "
691 <<
" Name: " << motherPhysical->
GetName()
693 <<
" Local Point = " << localPoint <<
G4endl;
694 message <<
" Description of solid: " <<
G4endl
695 << *motherSolid <<
G4endl;
696 G4Exception(
"G4VoxelNavigation::ComputeSafety()",
"GeomNav0003",
707 messageIn <<
" Point is Inside, but safety is Zero ." <<
G4endl;
708 messageIn <<
" Inexact safety for volume " << motherPhysical->
GetName() <<
G4endl
709 <<
" Solid: Name= " << motherSolid->
GetName()
711 messageIn <<
" Local point= " << localPoint <<
G4endl;
712 messageIn <<
" Solid parameters: " <<
G4endl << *motherSolid <<
G4endl;
713 G4Exception(
"G4VoxelNavigation::ComputeSafety()",
"GeomNav0003",
724 fLogger->ComputeSafetyLog (motherSolid,localPoint,motherSafety,
true,1);
735 for ( contentNo=curNoVolumes-1; contentNo>=0; contentNo-- )
738 samplePhysical = motherLogical->
GetDaughter(sampleNo);
746 if ( sampleSafety<ourSafety )
748 ourSafety = sampleSafety;
753 fLogger->ComputeSafetyLog(sampleSolid, samplePoint,
754 sampleSafety,
false, 0);
759 if ( voxelSafety<ourSafety )
761 ourSafety = voxelSafety;
G4NavigationHistory is a class responsible for the maintenance of the history of the path taken throu...
G4VPhysicalVolume * GetTopVolume() const
G4double ComputeStep(const G4ThreeVector &localPoint, const G4ThreeVector &localDirection, const G4double currentProposedStepLength, G4double &newSafety, G4NavigationHistory &history, G4bool &validExitNormal, G4ThreeVector &exitNormal, G4bool &exiting, G4bool &entering, G4VPhysicalVolume *(*pBlockedPhysical), G4int &blockedReplicaNo) override