218{
221
223 EAxis targetHeaderAxis;
224 G4double targetHeaderMin, targetHeaderMax, targetHeaderNodeWidth;
225 G4int targetHeaderNoSlices;
227
228 G4double minSafety = previousMinSafety;
230 unsigned int checkedNum= 0;
231
232 ++fVoxelDepth;
233
234
235 targetHeaderAxis = targetVoxelHeader->
GetAxis();
239
240 targetHeaderNodeWidth = (targetHeaderMax-targetHeaderMin)
241 / targetHeaderNoSlices;
242
243 G4double localCrd = localPoint(targetHeaderAxis);
244
245 const auto candNodeNo =
G4int( (localCrd-targetHeaderMin)
246 / targetHeaderNodeWidth );
247
248
249#ifdef G4DEBUG_VOXELISATION
250 if( candNodeNo < 0 || candNodeNo > targetHeaderNoSlices-1 )
251 {
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");
273 }
274#endif
275
276 const G4int pointNodeNo =
277 std::max( 0, std::min( candNodeNo, targetHeaderNoSlices-1 ) );
278
279#ifdef G4VERBOSE
280 if( fVerbose > 2 )
281 {
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;
292 }
293 else if (fVerbose == 1)
294 {
295 G4cout <<
" VoxelSafety: Depth = " << fVoxelDepth
296 << " Number of Slices = " << targetHeaderNoSlices
297 <<
" Header (address) = " << targetVoxelHeader <<
G4endl;
298 }
299#endif
300
301
302
303 fVoxelAxisStack[fVoxelDepth] = targetHeaderAxis;
304 fVoxelNoSlicesStack[fVoxelDepth] = targetHeaderNoSlices;
305 fVoxelSliceWidthStack[fVoxelDepth] = targetHeaderNodeWidth;
306
307 fVoxelHeaderStack[fVoxelDepth] = pHeader;
308
309 G4int trialUp = -1, trialDown = -1;
311
312
313
314 G4int nextUp = pointNodeNo+1;
315 G4int nextDown = pointNodeNo-1;
316
317 G4int nextNodeNo = pointNodeNo;
319 distAxis = 0.0;
320
321 G4bool nextIsInside =
false;
322
323 G4double distMaxInterest= std::min( previousMinSafety, maxLength);
324
325
326
327
328 targetNodeNo = pointNodeNo;
329 do
330 {
332 fVoxelNodeNoStack[fVoxelDepth] = targetNodeNo;
333
334 ++checkedNum;
335
336 sampleProxy = targetVoxelHeader->
GetSlice(targetNodeNo);
337
338#ifdef G4DEBUG_NAVIGATION
339 assert( sampleProxy != 0);
340 if( fVerbose > 2 )
341 {
342 G4cout <<
" -Checking node " << targetNodeNo
343 <<
" is proxy with address " << sampleProxy <<
G4endl;
344 }
345#endif
346
347 if ( sampleProxy == nullptr )
348 {
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.");
356 }
357 else if ( sampleProxy->
IsNode() )
358 {
359 targetVoxelNode = sampleProxy->
GetNode();
360
361
362
364#ifdef G4DEBUG_NAVIGATION
365 if( fVerbose > 2 )
366 {
367 G4cout <<
" -- It is a Node ";
368 G4cout <<
" its safety= " << nodeSafety
369 << " our level Saf = " << ourSafety
370 <<
" MinSaf= " << minSafety <<
G4endl;
371 }
372#endif
373 ourSafety= std::min( ourSafety, nodeSafety );
374
377 }
378 else
379 {
381
383 distCombined_Sq = distUpperDepth_Sq + distAxis*distAxis;
384
385#ifdef G4DEBUG_NAVIGATION
386 if( fVerbose > 2 )
387 {
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;
396 }
397#endif
398
399
400
402 maxLength, currentPhysical,
403 distCombined_Sq, minSafety);
404 ourSafety = std::min( ourSafety, headerSafety );
405
406#ifdef G4DEBUG_NAVIGATION
407 if( fVerbose > 2 )
408 {
409 G4cout <<
" >> Header safety = " << headerSafety
410 <<
" our level Saf = " << ourSafety <<
G4endl;
411 }
412#endif
415 }
416 minSafety = std::min( minSafety, ourSafety );
417
418
419
420
421
422 if( targetNodeNo >= pointNodeNo )
423 {
424 nextUp = trialUp;
425
426 G4double lowerEdgeOfNext = targetHeaderMin
427 + nextUp * targetHeaderNodeWidth;
428 distUp = lowerEdgeOfNext-localCrd ;
429 if( distUp < 0.0 )
430 {
432 }
433#ifdef G4DEBUG_NAVIGATION
434 if( fVerbose > 2 )
435 {
437 }
438#endif
439 }
440
441 if( targetNodeNo <= pointNodeNo )
442 {
443 nextDown = trialDown;
444
445 G4double upperEdgeOfNext = targetHeaderMin
446 + (nextDown+1) * targetHeaderNodeWidth;
447 distDown = localCrd-upperEdgeOfNext;
448 if( distDown < 0.0 )
449 {
451 }
452#ifdef G4DEBUG_NAVIGATION
453 if( fVerbose > 2 )
454 {
455 G4cout <<
" > Updated nextDown= " << nextDown <<
G4endl;
456 }
457#endif
458 }
459
460#ifdef G4DEBUG_NAVIGATION
461 if( fVerbose > 2 )
462 {
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
474 }
475#endif
476
478 UpIsClosest = distUp < distDown;
479
480 if( (nextUp < targetHeaderNoSlices)
481 && (UpIsClosest || (nextDown < 0)) )
482 {
483 nextNodeNo = nextUp;
484 distAxis = distUp;
485 ++nextUp;
486#ifdef G4VERBOSE
487 if( fVerbose > 2 )
488 {
489 G4cout <<
" > Chose Up. Depth= " << fVoxelDepth
490 << " Nodes: next= " << nextNodeNo
491 << " new nextUp= " << nextUp
492 <<
" Dist = " << distAxis <<
G4endl;
493 }
494#endif
495 }
496 else
497 {
498 nextNodeNo = nextDown;
499 distAxis = distDown;
500 --nextDown;
501#ifdef G4VERBOSE
502 if( fVerbose > 2 )
503 {
504 G4cout <<
" > Chose Down. Depth= " << fVoxelDepth
505 << " Nodes: next= " << nextNodeNo
506 << " new nextDown= " << nextDown
507 <<
" Dist = " << distAxis <<
G4endl;
508 }
509#endif
510 }
511
512 nextIsInside = (nextNodeNo >= 0) && (nextNodeNo < targetHeaderNoSlices);
513 if( nextIsInside )
514 {
515 targetNodeNo= nextNodeNo;
516
517#ifdef G4DEBUG_NAVIGATION
518 assert( targetVoxelHeader->
GetSlice(nextNodeNo) != 0 );
519 G4bool bContinue = (distAxis<minSafety);
520 if( !bContinue )
521 {
522 if( fVerbose > 2 )
523 {
524 G4cout <<
" Can skip remaining at depth " << targetHeaderAxis
525 << " >> distAxis= " << distAxis
526 <<
" minSafety= " << minSafety <<
G4endl;
527 }
528 }
529#endif
530 }
531 else
532 {
533#ifdef G4DEBUG_NAVIGATION
534 if( fVerbose > 2)
535 {
537 G4cout <<
" VoxSaf> No more candidates: nodeDown= " << nextDown
538 << " nodeUp= " << nextUp
539 <<
" lastSlice= " << targetHeaderNoSlices <<
G4endl;
540 }
541#endif
542 }
543
544
545
546 distMaxInterest = std::min( minSafety, maxLength );
547
548 } while ( nextIsInside && ( distAxis*distAxis + distUpperDepth_Sq
549 < distMaxInterest*distMaxInterest ) );
550
551#ifdef G4VERBOSE
552 if( fVerbose > 0 )
553 {
554 G4cout <<
" Ended for targetNodeNo -- checked " << checkedNum <<
" out of "
555 << targetHeaderNoSlices <<
" slices." <<
G4endl;
556 G4cout <<
" ===== Returning from SafetyForVoxelHeader "
557 <<
" Depth= " << fVoxelDepth <<
G4endl
559 }
560#endif
561
562
563 fVoxelDepth--;
564
565 return ourSafety;
566}
std::ostringstream G4ExceptionDescription
const G4String & GetName() const
G4int GetMaxEquivalentSliceNo() const
G4int GetMinEquivalentSliceNo() const
G4SmartVoxelNode * GetNode() const
G4SmartVoxelHeader * GetHeader() const
virtual G4GeometryType GetEntityType() const =0
G4double SafetyForVoxelNode(const G4SmartVoxelNode *curVoxelNode, const G4ThreeVector &localPoint)