Geant4 Cross Reference |
1 // 2 // ******************************************************************** 3 // * License and Disclaimer * 4 // * * 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. * 10 // * * 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitation of liability. * 17 // * * 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************************************** 25 // 26 // class G4VoxelNavigation Inline implementation 27 // 28 // -------------------------------------------------------------------- 29 30 // ******************************************************************** 31 // VoxelLocate 32 // ******************************************************************** 33 // 34 inline 35 G4SmartVoxelNode* 36 G4VoxelNavigation::VoxelLocate( G4SmartVoxelHeader* pHead, 37 const G4ThreeVector& localPoint ) 38 { 39 G4SmartVoxelHeader* targetVoxelHeader = pHead; 40 G4SmartVoxelNode* targetVoxelNode = nullptr; 41 G4SmartVoxelProxy* sampleProxy; 42 EAxis targetHeaderAxis; 43 G4double targetHeaderMin, targetHeaderNodeWidth; 44 G4int targetHeaderNoSlices, targetNodeNo; 45 46 fVoxelDepth = 0; 47 48 while ( targetVoxelNode == nullptr ) 49 { 50 targetHeaderAxis = targetVoxelHeader->GetAxis(); 51 targetHeaderNoSlices = G4int(targetVoxelHeader->GetNoSlices()); 52 targetHeaderMin = targetVoxelHeader->GetMinExtent(); 53 targetHeaderNodeWidth = (targetVoxelHeader->GetMaxExtent()-targetHeaderMin) 54 / targetHeaderNoSlices; 55 targetNodeNo = G4int( (localPoint(targetHeaderAxis)-targetHeaderMin) 56 / targetHeaderNodeWidth); 57 // Rounding protection 58 // 59 if ( targetNodeNo<0 ) 60 { 61 targetNodeNo = 0; 62 } 63 else if ( targetNodeNo>=targetHeaderNoSlices ) 64 { 65 targetNodeNo = targetHeaderNoSlices-1; 66 } 67 // Stack info for stepping 68 // 69 fVoxelAxisStack[fVoxelDepth] = targetHeaderAxis; 70 fVoxelNoSlicesStack[fVoxelDepth] = targetHeaderNoSlices; 71 fVoxelSliceWidthStack[fVoxelDepth] = targetHeaderNodeWidth; 72 fVoxelNodeNoStack[fVoxelDepth] = targetNodeNo; 73 fVoxelHeaderStack[fVoxelDepth] = targetVoxelHeader; 74 sampleProxy = targetVoxelHeader->GetSlice(targetNodeNo); 75 76 if ( sampleProxy->IsNode() ) 77 { 78 targetVoxelNode = sampleProxy->GetNode(); 79 } 80 else 81 { 82 targetVoxelHeader = sampleProxy->GetHeader(); 83 ++fVoxelDepth; 84 } 85 } 86 fVoxelNode = targetVoxelNode; 87 return targetVoxelNode; 88 } 89 90 // ******************************************************************** 91 // LevelLocate 92 // ******************************************************************** 93 // 94 inline 95 G4bool 96 G4VoxelNavigation::LevelLocate( G4NavigationHistory& history, 97 const G4VPhysicalVolume* blockedVol, 98 const G4int, 99 const G4ThreeVector& globalPoint, 100 const G4ThreeVector* globalDirection, 101 const G4bool pLocatedOnEdge, 102 G4ThreeVector& localPoint ) 103 { 104 G4SmartVoxelHeader *targetVoxelHeader; 105 G4SmartVoxelNode *targetVoxelNode; 106 G4VPhysicalVolume *targetPhysical, *samplePhysical; 107 G4LogicalVolume *targetLogical; 108 G4VSolid *sampleSolid; 109 G4ThreeVector samplePoint; 110 G4int targetNoDaughters; 111 112 targetPhysical = history.GetTopVolume(); 113 targetLogical = targetPhysical->GetLogicalVolume(); 114 targetVoxelHeader = targetLogical->GetVoxelHeader(); 115 116 // Find the voxel containing the point 117 // 118 targetVoxelNode = VoxelLocate(targetVoxelHeader,localPoint); 119 120 targetNoDaughters = G4int(targetVoxelNode->GetNoContained()); 121 if ( targetNoDaughters==0 ) { return false; } 122 123 // 124 // Search daughters in volume 125 // 126 127 for ( auto sampleNo=targetNoDaughters-1; sampleNo>=0; sampleNo-- ) 128 { 129 samplePhysical = targetLogical-> 130 GetDaughter(targetVoxelNode->GetVolume(sampleNo)); 131 if ( samplePhysical!=blockedVol ) 132 { 133 // Setup history 134 // 135 history.NewLevel(samplePhysical, kNormal, samplePhysical->GetCopyNo()); 136 sampleSolid = samplePhysical->GetLogicalVolume()->GetSolid(); 137 samplePoint = history.GetTopTransform().TransformPoint(globalPoint); 138 139 if( G4AuxiliaryNavServices::CheckPointOnSurface(sampleSolid, 140 samplePoint, 141 globalDirection, 142 history.GetTopTransform(), 143 pLocatedOnEdge) ) 144 { 145 // Enter this daughter 146 // 147 localPoint = samplePoint; 148 return true; 149 } 150 history.BackLevel(); 151 } 152 } 153 return false; 154 } 155 156 // ******************************************************************** 157 // GetVerboseLevel 158 // ******************************************************************** 159 // 160 inline 161 G4int G4VoxelNavigation::GetVerboseLevel() const 162 { 163 return fLogger->GetVerboseLevel(); 164 } 165 166 // ******************************************************************** 167 // EnableBestSafety 168 // ******************************************************************** 169 // 170 inline 171 void G4VoxelNavigation::EnableBestSafety(G4bool flag) 172 { 173 fBestSafety = flag; 174 } 175