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