Compute the length of a step to the next boundary. Do not test against pBlockedPhysical
. Identify the next candidate volume (if a daughter of current volume), and return it in pBlockedPhysical, blockedReplicaNo.
82{
88 G4double ourStep=currentProposedStepLength, ourSafety;
90 G4bool motherValidExitNormal =
false;
92
94
95 G4bool initialNode, noStep;
97 G4long curNoVolumes, contentNo;
99
100
101
106
109 motherSolid = motherLogical->
GetSolid();
110
111
112
113
114
116 ourSafety = motherSafety;
117
118#ifdef G4VERBOSE
120 {
121 if( motherSafety < 0.0 )
122 {
124 std::ostringstream message;
125 message <<
"Negative Safety In Voxel Navigation !" <<
G4endl
126 <<
" Current solid " << motherSolid->
GetName()
127 <<
" gave negative safety: " << motherSafety <<
G4endl
128 << " for the current (local) point " << localPoint;
129 G4Exception(
"G4ParameterisedNavigation::ComputeStep()",
131 }
133 {
134 std::ostringstream message;
135 message <<
"Point is outside Current Volume !" <<
G4endl
136 << " Point " << localPoint
137 <<
" is outside current volume " << motherPhysical->
GetName()
140 G4cout <<
" Estimated isotropic distance to solid (distToIn)= "
141 << estDistToSolid;
142 if( estDistToSolid > 100.0 * motherSolid->
GetTolerance() )
143 {
145 G4Exception(
"G4ParameterisedNavigation::ComputeStep()",
147 "Point is far outside Current Volume !");
148 }
149 else
150 {
151 G4Exception(
"G4ParameterisedNavigation::ComputeStep()",
153 "Point is a little outside Current Volume.");
154 }
155 }
156
157
158
159
160
161
163 localDirection,
164 true,
165 &motherValidExitNormal,
166 &motherExitNormal);
167
168 if( (motherStep >= kInfinity) || (motherStep < 0.0) )
169 {
170
171
173
174 ourStep = motherStep = 0.0;
175 exiting = true;
176 entering = false;
177
178
179 validExitNormal = motherValidExitNormal;
180 exitNormal = motherExitNormal;
181
182 *pBlockedPhysical = nullptr;
183 blockedReplicaNo = 0;
184
185 newSafety = 0.0;
186 return ourStep;
187 }
188 }
189#endif
190
191 initialNode = true;
192 noStep = true;
193
194
195
196
201
202
203
204 if (exiting && (*pBlockedPhysical==samplePhysical) && validExitNormal)
205 {
206 if (localDirection.
dot(exitNormal)>=kMinExitingNormalCosine)
207 {
208
209
211 ourSafety = 0;
212 }
213 }
214 exiting = false;
215 entering = false;
216
218
219
220
221 do
222 {
225
226 for ( contentNo=curNoVolumes-1; contentNo>=0; contentNo-- )
227 {
230 {
232
233
234
235 sampleSolid = IdentifyAndPlaceSolid( sampleNo, samplePhysical,
236 sampleParam );
237
240 sampleTf.Invert();
241 const G4ThreeVector samplePoint = sampleTf.TransformPoint(localPoint);
243 if ( sampleSafety<ourSafety )
244 {
245 ourSafety = sampleSafety;
246 }
247 if ( sampleSafety<=ourStep )
248 {
249 sampleDirection = sampleTf.TransformAxis(localDirection);
251 sampleSolid->
DistanceToIn(samplePoint, sampleDirection);
252 if ( sampleStep<=ourStep )
253 {
254 ourStep = sampleStep;
255 entering = true;
256 exiting = false;
257 *pBlockedPhysical = samplePhysical;
258 blockedReplicaNo = sampleNo;
259#ifdef G4VERBOSE
260
261
262
263
264 if ( (
fCheck ) && ( sampleStep < kInfinity ) )
265 {
267 intersectionPoint = samplePoint + sampleStep * sampleDirection;
268 EInside insideIntPt = sampleSolid->
Inside(intersectionPoint);
270 {
272 std::ostringstream message;
273 message << "Navigator gets conflicting response from Solid."
275 << " Inaccurate solid DistanceToIn"
277 << " Solid gave DistanceToIn = "
278 << sampleStep << " yet returns " ;
280 {
281 message << "-kInside-";
282 }
284 {
285 message << "-kOutside-";
286 }
287 else
288 {
289 message << "-kSurface-";
290 }
291 message <<
" for this point !" <<
G4endl
292 << " Point = " << intersectionPoint
295 {
296 message << " DistanceToIn(p) = "
298 }
300 {
301 message << " DistanceToOut(p) = "
303 }
304 G4Exception(
"G4ParameterisedNavigation::ComputeStep()",
306 G4cout.precision(oldcoutPrec);
307 }
308 }
309#endif
310 }
311 }
312 }
313 }
314
315 if ( initialNode )
316 {
317 initialNode = false;
318 voxelSafety = ComputeVoxelSafety(localPoint,axis);
319 if ( voxelSafety<ourSafety )
320 {
321 ourSafety = voxelSafety;
322 }
323 if ( currentProposedStepLength<ourSafety )
324 {
325
326
327 noStep = false;
328 entering = false;
329 exiting = false;
330 *pBlockedPhysical = nullptr;
331 ourStep = kInfinity;
332 }
333 else
334 {
335
336
337 if ( motherSafety<=ourStep )
338 {
340 {
342 localDirection,
343 true,
344 &motherValidExitNormal,
345 &motherExitNormal);
346 }
347
348 if( ( motherStep < 0.0 ) || ( motherStep >= kInfinity) )
349 {
350#ifdef G4VERBOSE
352 motherPhysical);
353#endif
354 ourStep = motherStep = 0.0;
355
356
357
358 }
359#ifdef G4VERBOSE
360 if( motherValidExitNormal && (
fCheck || (motherStep<=ourStep)) )
361 {
363 localPoint, localDirection,
364 motherStep, motherSolid,
365 "From motherSolid::DistanceToOut");
366 }
367#endif
368 if ( motherStep<=ourStep )
369 {
370 ourStep = motherStep;
371 exiting = true;
372 entering = false;
373 if ( validExitNormal )
374 {
376 if (rot != nullptr)
377 {
379 }
380 }
381 }
382 else
383 {
384 validExitNormal = false;
385 }
386 }
387 }
388 newSafety = ourSafety;
389 }
390 if (noStep)
391 {
392 noStep = LocateNextVoxel(localPoint, localDirection, ourStep, axis);
393 }
394 } while (noStep);
395
396 return ourStep;
397}
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
G4GLOB_DLL std::ostream G4cout
double dot(const Hep3Vector &) const
HepRotation inverse() const
void BlockVolume(const G4int v)
void Enlarge(const G4int nv)
G4bool IsBlocked(const G4int v) const
G4bool CheckAndReportBadNormal(const G4ThreeVector &unitNormal, const G4ThreeVector &localPoint, const G4ThreeVector &localDirection, G4double step, const G4VSolid *solid, const char *msg) const
void ReportOutsideMother(const G4ThreeVector &localPoint, const G4ThreeVector &localDirection, const G4VPhysicalVolume *motherPV, G4double tDist=30.0 *CLHEP::cm) const
const G4String & GetName() const
G4double GetTolerance() const
virtual EInside Inside(const G4ThreeVector &p) const =0
G4NavigationLogger * fLogger