88{
94 G4double ourStep=currentProposedStepLength, motherSafety, ourSafety;
96
97 G4bool initialNode, noStep;
99 G4int curNoVolumes, contentNo;
101
102
103
108
111 motherSolid = motherLogical->
GetSolid();
112
113
114
115
116
118 ourSafety = motherSafety;
119
120#ifdef G4VERBOSE
122 {
123 if( motherSafety < 0.0 )
124 {
126 std::ostringstream message;
127 message <<
"Negative Safety In Voxel Navigation !" <<
G4endl
128 <<
" Current solid " << motherSolid->
GetName()
129 <<
" gave negative safety: " << motherSafety <<
G4endl
130 << " for the current (local) point " << localPoint;
131 G4Exception(
"G4ParameterisedNavigation::ComputeStep()",
133 }
135 {
136 std::ostringstream message;
137 message <<
"Point is outside Current Volume !" <<
G4endl
138 << " Point " << localPoint
139 <<
" is outside current volume " << motherPhysical->
GetName()
142 G4cout <<
" Estimated isotropic distance to solid (distToIn)= "
143 << estDistToSolid;
144 if( estDistToSolid > 100.0 * motherSolid->
GetTolerance() )
145 {
147 G4Exception(
"G4ParameterisedNavigation::ComputeStep()",
149 "Point is far outside Current Volume !");
150 }
151 else
152 G4Exception(
"G4ParameterisedNavigation::ComputeStep()",
154 "Point is a little outside Current Volume.");
155 }
156 }
157#endif
158
159
160
161
162
163 initialNode = true;
164 noStep = true;
165
166
167
168
173
174
175
176 if (exiting && (*pBlockedPhysical==samplePhysical) && validExitNormal)
177 {
178 if (localDirection.dot(exitNormal)>=kMinExitingNormalCosine)
179 {
180
181
183 ourSafety = 0;
184 }
185 }
186 exiting = false;
187 entering = false;
188
190
191 do
192 {
195
196 for ( contentNo=curNoVolumes-1; contentNo>=0; contentNo-- )
197 {
198 sampleNo = curVoxelNode->
GetVolume(contentNo);
200 {
202
203
204
205 sampleSolid = IdentifyAndPlaceSolid( sampleNo, samplePhysical,
206 sampleParam );
207
210 sampleTf.Invert();
211 const G4ThreeVector samplePoint = sampleTf.TransformPoint(localPoint);
213 if ( sampleSafety<ourSafety )
214 {
215 ourSafety = sampleSafety;
216 }
217 if ( sampleSafety<=ourStep )
218 {
219 sampleDirection = sampleTf.TransformAxis(localDirection);
221 sampleSolid->
DistanceToIn(samplePoint, sampleDirection);
222 if ( sampleStep<=ourStep )
223 {
224 ourStep = sampleStep;
225 entering = true;
226 exiting = false;
227 *pBlockedPhysical = samplePhysical;
228 blockedReplicaNo = sampleNo;
229#ifdef G4VERBOSE
230
231
232
233
234 if ( (
fCheck ) && ( sampleStep < kInfinity ) )
235 {
237 intersectionPoint= samplePoint + sampleStep * sampleDirection;
240 {
242 std::ostringstream message;
243 message << "Navigator gets conflicting response from Solid."
245 << " Inaccurate solid DistanceToIn"
247 << " Solid gave DistanceToIn = "
248 << sampleStep << " yet returns " ;
250 message << "-kInside-";
252 message << "-kOutside-";
253 else
254 message << "-kSurface-";
255 message <<
" for this point !" <<
G4endl
256 << " Point = " << intersectionPoint
259 message << " DistanceToIn(p) = "
262 message << " DistanceToOut(p) = "
264 G4Exception(
"G4ParameterisedNavigation::ComputeStep()",
266 G4cout.precision(oldcoutPrec);
267 }
268 }
269#endif
270 }
271 }
272 }
273 }
274
275 if ( initialNode )
276 {
277 initialNode = false;
278 voxelSafety = ComputeVoxelSafety(localPoint,axis);
279 if ( voxelSafety<ourSafety )
280 {
281 ourSafety = voxelSafety;
282 }
283 if ( currentProposedStepLength<ourSafety )
284 {
285
286
287 noStep = false;
288 entering = false;
289 exiting = false;
290 *pBlockedPhysical = 0;
291 ourStep = kInfinity;
292 }
293 else
294 {
295
296
297
298 if ( motherSafety<=ourStep )
299 {
301 localDirection,
302 true,
303 &validExitNormal,
304 &exitNormal);
305#ifdef G4VERBOSE
307 if( ( motherStep < 0.0 ) || ( motherStep >= kInfinity) )
308 {
311 std::ostringstream message;
312 message << "Current point is outside the current solid !"
314 <<
" Problem in Navigation" <<
G4endl
315 << " Point (local coordinates): "
317 << " Local Direction: "
318 << localDirection <<
G4endl
319 <<
" Solid: " << motherSolid->
GetName();
321 G4Exception(
"G4ParameterisedNavigation::ComputeStep()",
323 G4cout.precision(oldPrOut);
324 G4cerr.precision(oldPrErr);
325 }
326#endif
327 if ( motherStep<=ourStep )
328 {
329 ourStep = motherStep;
330 exiting = true;
331 entering = false;
332 if ( validExitNormal )
333 {
335 if (rot)
336 {
338 }
339 }
340 }
341 else
342 {
343 validExitNormal = false;
344 }
345 }
346 }
347 newSafety=ourSafety;
348 }
349 if (noStep)
350 {
351 noStep = LocateNextVoxel(localPoint, localDirection, ourStep, axis);
352 }
353 } while (noStep);
354
355 return ourStep;
356}
G4DLLIMPORT std::ostream G4cerr
G4DLLIMPORT std::ostream G4cout
HepRotation inverse() const
void BlockVolume(const G4int v)
void Enlarge(const G4int nv)
G4bool IsBlocked(const G4int v) const
const G4String & GetName() const
G4double GetTolerance() const
virtual EInside Inside(const G4ThreeVector &p) const =0
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)