0029151: GCC 7.1 warnings "this statement may fall through" [-Wimplicit-fallthrough=]
[occt.git] / src / IntPatch / IntPatch_ALineToWLine.cxx
1 // Created on: 1993-11-26
2 // Created by: Modelistation
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <IntPatch_ALineToWLine.hxx>
18
19 #include <Adaptor3d_HSurface.hxx>
20 #include <ElSLib.hxx>
21 #include <IntPatch_ALine.hxx>
22 #include <IntPatch_Point.hxx>
23 #include <IntPatch_SpecialPoints.hxx>
24 #include <IntPatch_WLine.hxx>
25 #include <IntSurf.hxx>
26 #include <IntSurf_LineOn2S.hxx>
27
28 //=======================================================================
29 //function : AddPointIntoLine
30 //purpose  : 
31 //=======================================================================
32 static inline void AddPointIntoLine(Handle(IntSurf_LineOn2S) theLine,
33                                     const Standard_Real* const theArrPeriods,
34                                     IntSurf_PntOn2S &thePoint,
35                                     IntPatch_Point* theVertex = 0)
36 {
37    if(theLine->NbPoints() > 0)
38    {
39      if(thePoint.IsSame(theLine->Value(theLine->NbPoints()), Precision::Confusion()))
40        return;
41
42      IntPatch_SpecialPoints::AdjustPointAndVertex(theLine->Value(theLine->NbPoints()),
43                                                     theArrPeriods, thePoint, theVertex);
44    }
45
46    theLine->Add(thePoint);
47 }
48
49 //=======================================================================
50 //function : AddVertexPoint
51 //purpose  : Extracts IntSurf_PntOn2S from theVertex and adds result in theLine.
52 //=======================================================================
53 static void AddVertexPoint(Handle(IntSurf_LineOn2S)& theLine,
54                                        IntPatch_Point &theVertex,
55                                        const Standard_Real* const theArrPeriods)
56 {
57   IntSurf_PntOn2S anApexPoint = theVertex.PntOn2S();
58   AddPointIntoLine(theLine, theArrPeriods, anApexPoint, &theVertex);
59 }
60
61 //=======================================================================
62 //function : IsPoleOrSeam
63 //purpose  : Processes theVertex depending on its type
64 //            (pole/apex/point on boundary etc.) and adds it in theLine.
65 //           theSingularSurfaceID contains the ID of surface with
66 //            special point (0 - none, 1 - theS1, 2 - theS2)
67 //=======================================================================
68 static IntPatch_SpecPntType IsPoleOrSeam(const Handle(Adaptor3d_HSurface)& theS1,
69                                          const Handle(Adaptor3d_HSurface)& theS2,
70                                          Handle(IntSurf_LineOn2S)& theLine,
71                                          IntPatch_Point &theVertex,
72                                          const Standard_Real* const theArrPeriods,
73                                          const Standard_Real theTol3d,
74                                          Standard_Integer& theSingularSurfaceID)
75 {
76   const Standard_Integer aNbPnts = theLine->NbPoints();
77   if(aNbPnts == 0)
78     return IntPatch_SPntNone;
79
80   theSingularSurfaceID = 0;
81
82   for(Standard_Integer i = 0; i < 2; i++)
83   {
84     const Standard_Boolean isReversed = (i > 0);
85     const GeomAbs_SurfaceType aType = isReversed? theS2->GetType() : theS1->GetType();
86
87     IntPatch_SpecPntType anAddedPType = IntPatch_SPntNone;
88     IntSurf_PntOn2S anApexPoint;
89
90     switch(aType)
91     {
92     case GeomAbs_Sphere:
93     case GeomAbs_Cone:
94       {
95         if(IntPatch_SpecialPoints::
96               AddSingularPole((isReversed? theS2 : theS1), (isReversed? theS1 : theS2),
97                                theLine->Value(aNbPnts), theTol3d, theVertex,
98                                anApexPoint, isReversed, Standard_True))
99         {
100           anAddedPType = IntPatch_SPntPole;
101           break;
102         }
103       }
104       Standard_FALLTHROUGH
105     case GeomAbs_Torus:
106       if(aType == GeomAbs_Torus)
107       {
108         if(IntPatch_SpecialPoints::
109             AddCrossUVIsoPoint((isReversed? theS2 : theS1), (isReversed? theS1 : theS2),
110                                           theLine->Value(aNbPnts), theTol3d,
111                                           anApexPoint, isReversed))
112         {
113           anAddedPType = IntPatch_SPntSeamUV;
114           break;
115         }
116       }
117       Standard_FALLTHROUGH
118     case GeomAbs_Cylinder:
119       theSingularSurfaceID = i + 1;
120       AddVertexPoint(theLine, theVertex, theArrPeriods);
121       return IntPatch_SPntSeamU;
122
123     default:
124       break;
125     }
126
127     if(anAddedPType != IntPatch_SPntNone)
128     {
129       theSingularSurfaceID = i + 1;
130       AddPointIntoLine(theLine, theArrPeriods, anApexPoint, &theVertex);
131       return anAddedPType;
132     }
133   }
134
135   return IntPatch_SPntNone;
136 }
137
138 //=======================================================================
139 //function : IntPatch_ALineToWLine
140 //purpose  : 
141 //=======================================================================
142 IntPatch_ALineToWLine::IntPatch_ALineToWLine(const Handle(Adaptor3d_HSurface)& theS1,
143                                              const Handle(Adaptor3d_HSurface)& theS2,
144                                              const Standard_Integer theNbPoints) :
145   myS1(theS1),
146   myS2(theS2),
147   myNbPointsInWline(theNbPoints),
148   myTolOpenDomain(1.e-9),
149   myTolTransition(1.e-8),
150   myTol3D(Precision::Confusion())
151
152   const GeomAbs_SurfaceType aTyps1 = theS1->GetType();
153   const GeomAbs_SurfaceType aTyps2 = theS2->GetType();
154
155   switch(aTyps1)
156   {
157   case GeomAbs_Plane:
158     myQuad1.SetValue(theS1->Plane());
159     break;
160
161   case GeomAbs_Cylinder:
162     myQuad1.SetValue(theS1->Cylinder());
163     break;
164
165   case GeomAbs_Sphere:
166     myQuad1.SetValue(theS1->Sphere());
167     break;
168
169   case GeomAbs_Cone:
170     myQuad1.SetValue(theS1->Cone());
171     break;
172
173   case GeomAbs_Torus:
174     myQuad1.SetValue(theS1->Torus());
175     break;
176
177   default:
178     break;
179   }
180
181   switch(aTyps2)
182   {
183   case GeomAbs_Plane:
184     myQuad2.SetValue(theS2->Plane());
185     break;
186   case GeomAbs_Cylinder:
187     myQuad2.SetValue(theS2->Cylinder());
188     break;
189
190   case GeomAbs_Sphere:
191     myQuad2.SetValue(theS2->Sphere());
192     break;
193
194   case GeomAbs_Cone:
195     myQuad2.SetValue(theS2->Cone());
196     break;
197
198   case GeomAbs_Torus:
199     myQuad2.SetValue(theS2->Torus());
200     break;
201
202   default:
203     break;
204   }
205 }
206
207 //=======================================================================
208 //function : SetTol3D
209 //purpose  : 
210 //=======================================================================
211   void IntPatch_ALineToWLine::SetTol3D(const Standard_Real aTol)
212 {
213   myTol3D = aTol;
214 }
215 //=======================================================================
216 //function : Tol3D
217 //purpose  : 
218 //=======================================================================
219   Standard_Real IntPatch_ALineToWLine::Tol3D()const
220 {
221   return myTol3D;
222 }
223 //=======================================================================
224 //function : SetTolTransition
225 //purpose  : 
226 //=======================================================================
227   void IntPatch_ALineToWLine::SetTolTransition(const Standard_Real aTol)
228 {
229   myTolTransition = aTol;
230 }
231 //=======================================================================
232 //function : TolTransition
233 //purpose  : 
234 //=======================================================================
235   Standard_Real IntPatch_ALineToWLine::TolTransition()const
236 {
237   return myTolTransition;
238 }
239 //=======================================================================
240 //function : SetTolOpenDomain
241 //purpose  : 
242 //=======================================================================
243   void IntPatch_ALineToWLine::SetTolOpenDomain(const Standard_Real aTol)
244 {
245   myTolOpenDomain = aTol;
246 }
247 //=======================================================================
248 //function : TolOpenDomain
249 //purpose  : 
250 //=======================================================================
251   Standard_Real IntPatch_ALineToWLine::TolOpenDomain()const
252 {
253   return myTolOpenDomain;
254 }
255 //=======================================================================
256 //function : MakeWLine
257 //purpose  : 
258 //=======================================================================
259 void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theAline,
260                                       IntPatch_SequenceOfLine& theLines) const
261
262   Standard_Boolean included;
263   Standard_Real f = theAline->FirstParameter(included); 
264   if(!included) {
265     f+=myTolOpenDomain;
266   }
267   Standard_Real l = theAline->LastParameter(included); 
268   if(!included) { 
269     l-=myTolOpenDomain;
270   }
271
272   MakeWLine(theAline, f, l, theLines);
273 }
274
275 //=======================================================================
276 //function : MakeWLine
277 //purpose  : 
278 //=======================================================================
279 void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine,
280                                       const Standard_Real theFPar,
281                                       const Standard_Real theLPar,
282                                       IntPatch_SequenceOfLine& theLines) const 
283 {
284   const Standard_Integer aNbVert = theALine->NbVertex();
285   if (!aNbVert) {
286     return;
287   }
288   const Standard_Real aTol = 2.0*myTol3D+Precision::Confusion();
289   IntPatch_SpecPntType aPrePointExist = IntPatch_SPntNone;
290   
291   NCollection_Array1<Standard_Real> aVertexParams(1, aNbVert);
292   NCollection_Array1<IntPatch_Point> aSeqVertex(1, aNbVert);
293
294   //It is possible to have several vertices with equal parameters.
295   NCollection_Array1<Standard_Boolean> hasVertexBeenChecked(1, aNbVert);
296
297   Handle(IntSurf_LineOn2S) aLinOn2S;
298   Standard_Real aParameter = theFPar;
299   
300   for(Standard_Integer i = aVertexParams.Lower(); i <= aVertexParams.Upper(); i++)
301   {
302     const Standard_Real aPar = theALine->Vertex(i).ParameterOnLine();
303     aVertexParams(i) = aPar;
304     hasVertexBeenChecked(i) = Standard_False;
305   }
306
307   Standard_Integer aSingularSurfaceID = 0;
308   Standard_Real anArrPeriods[] = { 0.0,  //U1
309                                    0.0,  //V1
310                                    0.0,  //U2
311                                    0.0}; //V2
312
313   IntSurf::SetPeriod(myS1, myS2, anArrPeriods);
314
315   IntSurf_PntOn2S aPrevLPoint;
316
317   while(aParameter < theLPar)
318   {
319     Standard_Real aStep = (theLPar - aParameter) / (Standard_Real)(myNbPointsInWline - 1);
320     if(aStep < Epsilon(theLPar))
321       break;
322
323     Standard_Integer aNewVertID = 0;
324     aLinOn2S = new IntSurf_LineOn2S;
325     
326     const Standard_Real aStepMin = 0.1*aStep, aStepMax = 10.0*aStep;
327
328     Standard_Boolean isLast = Standard_False;
329     Standard_Real aPrevParam = aParameter;
330     for(; !isLast; aParameter += aStep)
331     {
332       IntSurf_PntOn2S aPOn2S;
333
334       if(theLPar <= aParameter)
335       {
336         isLast = Standard_True;
337         if(aPrePointExist != IntPatch_SPntNone)
338         {
339           break;
340         }
341         else
342         {
343           aParameter = theLPar;
344         }
345       }
346
347       Standard_Real aTgMagn = 0.0;
348       {
349         gp_Pnt aPnt3d;
350         gp_Vec aTg;
351         theALine->D1(aParameter, aPnt3d, aTg);
352         aTgMagn = aTg.Magnitude();
353         Standard_Real u1 = 0.0, v1 = 0.0, u2 = 0.0, v2 = 0.0;
354         myQuad1.Parameters(aPnt3d, u1, v1);
355         myQuad2.Parameters(aPnt3d, u2, v2);
356         aPOn2S.SetValue(aPnt3d, u1, v1, u2, v2);
357       }
358
359       if(aPrePointExist != IntPatch_SPntNone)
360       {
361         const Standard_Real aURes = Max(myS1->UResolution(myTol3D),
362                                                 myS2->UResolution(myTol3D)),
363                             aVRes = Max(myS1->VResolution(myTol3D),
364                                                 myS2->VResolution(myTol3D));
365
366         const Standard_Real aTol2d = (aPrePointExist == IntPatch_SPntPole) ? -1.0 : 
367                     (aPrePointExist == IntPatch_SPntSeamV)? aVRes :
368                     (aPrePointExist == IntPatch_SPntSeamUV)? Max(aURes, aVRes) : aURes;
369
370         IntSurf_PntOn2S aRPT = aPOn2S;
371
372         if (aPrePointExist == IntPatch_SPntPole)
373         {
374           Standard_Real aPrt = 0.5*(aPrevParam + theLPar);
375           for (Standard_Integer i = aVertexParams.Lower(); i <= aVertexParams.Upper(); i++)
376           {
377             const Standard_Real aParam = aVertexParams(i);
378
379             if (aParam <= aPrevParam)
380               continue;
381
382             aPrt = 0.5*(aParam + aPrevParam);
383             break;
384           }
385
386           const gp_Pnt aPnt3d(theALine->Value(aPrt));
387           Standard_Real u1, v1, u2, v2;
388           myQuad1.Parameters(aPnt3d, u1, v1);
389           myQuad2.Parameters(aPnt3d, u2, v2);
390           aRPT.SetValue(aPnt3d, u1, v1, u2, v2);
391
392           if (aPOn2S.IsSame(aPrevLPoint, Max(Precision::Approximation(), aTol)))
393           {
394             //Set V-parameter as precise value found on the previous step.
395             if (aSingularSurfaceID == 1)
396             {
397               aPOn2S.ParametersOnS1(u2, v2);
398               aPOn2S.SetValue(Standard_True, u1, v2);
399             }
400             else //if (aSingularSurfaceID == 2)
401             {
402               aPOn2S.ParametersOnS2(u1, v1);
403               aPOn2S.SetValue(Standard_False, u2, v1);
404             }
405           }
406         }
407
408         if(IntPatch_SpecialPoints::
409                       ContinueAfterSpecialPoint(myS1, myS2, aRPT,
410                                                 aPrePointExist, aTol2d,
411                                                 aPrevLPoint, Standard_False))
412         {
413           AddPointIntoLine(aLinOn2S, anArrPeriods, aPrevLPoint);
414         }
415         else if(aParameter == theLPar)
416         {// Strictly equal!!!
417           break;
418         }
419       }
420
421       aPrePointExist = IntPatch_SPntNone;
422
423       Standard_Integer aVertexNumber = -1;
424       for(Standard_Integer i = aVertexParams.Lower(); i <= aVertexParams.Upper(); i++)
425       {
426         if(hasVertexBeenChecked(i))
427           continue;
428
429         const Standard_Real aParam = aVertexParams(i);
430         if( ((aPrevParam < aParam) && (aParam <= aParameter)) ||
431             ((aPrevParam == aParameter) && (aParam == aParameter)))
432         {
433           aVertexNumber = i;
434           break;
435         }
436       }
437
438       aPrevParam = aParameter;
439       
440       if(aVertexNumber < 0)
441       {
442         StepComputing(theALine, aPOn2S, theLPar, aParameter, aTgMagn,
443                               aStepMin, aStepMax, myTol3D, aStep);
444         AddPointIntoLine(aLinOn2S, anArrPeriods, aPOn2S);
445         aPrevLPoint = aPOn2S;
446         continue;
447       }
448
449       IntPatch_Point aVtx = theALine->Vertex(aVertexNumber);
450       const Standard_Real aNewVertexParam = aLinOn2S->NbPoints() + 1;
451
452       //ATTENTION!!!
453       // IsPoleOrSeam inserts new point in aLinOn2S if aVtx respects
454       //to some special point. Otherwise, aLinOn2S is not changed.
455
456       aPrePointExist = IsPoleOrSeam(myS1, myS2, aLinOn2S, aVtx,
457                                 anArrPeriods, aTol, aSingularSurfaceID);
458
459       const Standard_Real aCurVertParam = aVtx.ParameterOnLine();
460       if(aPrePointExist != IntPatch_SPntNone)
461       {
462         aPrevParam = aParameter = aCurVertParam;
463       }
464       else
465       {
466         if(aVtx.Tolerance() > aTol)
467         {
468           aVtx.SetValue(aPOn2S);
469           AddPointIntoLine(aLinOn2S, anArrPeriods, aPOn2S);
470         }
471         else
472         {
473           AddVertexPoint(aLinOn2S, aVtx, anArrPeriods);
474         }
475       }
476
477       aPrevLPoint = aPOn2S = aLinOn2S->Value(aLinOn2S->NbPoints());
478
479       {
480         Standard_Boolean isFound = Standard_False;
481         const Standard_Real aSqTol = aTol*aTol;
482         const gp_Pnt aP1(theALine->Value(aCurVertParam));
483         const IntSurf_PntOn2S& aVertP2S = aVtx.PntOn2S();
484         const Standard_Real aVertToler  = aVtx.Tolerance();
485
486         for(Standard_Integer i = aVertexParams.Lower(); i <= aVertexParams.Upper(); i++)
487         {
488           if(hasVertexBeenChecked(i))
489             continue;
490
491           const gp_Pnt aP2(theALine->Value(aVertexParams(i)));
492           
493           if(aP1.SquareDistance(aP2) < aSqTol)
494           {
495             IntPatch_Point aLVtx = theALine->Vertex(i);
496             aLVtx.SetValue(aVertP2S);
497             aLVtx.SetTolerance(aVertToler);
498             aLVtx.SetParameter(aNewVertexParam);
499             aSeqVertex(++aNewVertID) = aLVtx;
500             hasVertexBeenChecked(i) = Standard_True;
501             isFound = Standard_True;
502           }
503           else if(isFound)
504           {
505             break;
506           }
507         }
508       }
509
510       if(aPrePointExist != IntPatch_SPntNone)
511         break;
512     }//for(; !isLast; aParameter += aStep)
513
514     if(aLinOn2S->NbPoints() < 2)
515     {
516       aParameter += aStep;
517       continue;
518     }
519
520     //-----------------------------------------------------------------
521     //--  Computation of transitions of the line on two surfaces    ---
522     //-----------------------------------------------------------------
523     IntSurf_TypeTrans trans1,trans2;
524     {
525       Standard_Integer indice1;
526       Standard_Real dotcross;
527       gp_Pnt aPP0, aPP1;
528       //
529       trans1=IntSurf_Undecided;
530       trans2=IntSurf_Undecided;
531       //
532       indice1 = aLinOn2S->NbPoints()/3;
533       if(indice1<=2) {
534         indice1 = 2;
535       }
536       //
537       aPP1=aLinOn2S->Value(indice1).Value();
538       aPP0=aLinOn2S->Value(indice1-1).Value();
539       //
540       gp_Vec tgvalid(aPP0, aPP1);
541       gp_Vec aNQ1 = myQuad1.Normale(aPP0);
542       gp_Vec aNQ2 = myQuad2.Normale(aPP0);
543       //
544       dotcross = tgvalid.DotCross(aNQ2, aNQ1);
545       if (dotcross > myTolTransition) {
546         trans1 = IntSurf_Out;
547         trans2 = IntSurf_In;
548       }
549       else if(dotcross < -myTolTransition) { 
550         trans1 = IntSurf_In;
551         trans2 = IntSurf_Out;
552       } 
553     }
554
555     //-----------------------------------------------------------------
556     //--              W  L  i  n  e     c  r  e  a  t  i  o  n      ---
557     //-----------------------------------------------------------------
558     Handle(IntPatch_WLine) aWLine;
559     //
560     if(theALine->TransitionOnS1() == IntSurf_Touch)  { 
561                                   aWLine = new IntPatch_WLine(aLinOn2S,
562                                   theALine->IsTangent(),
563                                   theALine->SituationS1(),
564                                   theALine->SituationS2());
565     }
566     else if(theALine->TransitionOnS1() == IntSurf_Undecided)  { 
567       aWLine = new IntPatch_WLine(aLinOn2S, theALine->IsTangent());
568     }
569     else { 
570       aWLine = new IntPatch_WLine(aLinOn2S, theALine->IsTangent(),
571                                   trans1, // aline->TransitionOnS1(),
572                                   trans2);  //aline->TransitionOnS2());
573     }
574
575     for(Standard_Integer i = aSeqVertex.Lower(); i <= aNewVertID; i++)
576     {
577       const IntPatch_Point& aVtx = aSeqVertex(i);
578       aWLine->AddVertex(aVtx);
579     }
580
581     aWLine->SetPeriod(anArrPeriods[0],anArrPeriods[1],anArrPeriods[2],anArrPeriods[3]);
582
583     //the method ComputeVertexParameters can reduce the number of points in <aWLine>
584     aWLine->ComputeVertexParameters(myTol3D);
585
586     if (aWLine->NbPnts() > 1)
587     {
588       aWLine->EnablePurging(Standard_False);
589       theLines.Append(aWLine);
590     }
591   }//while(aParameter < theLPar)
592 }
593
594 //=======================================================================
595 //function : CheckDeflection
596 //purpose  : Returns:
597 //            -1 - step is too small
598 //            0  - step is normal
599 //            +1 - step is too big
600 //=======================================================================
601 Standard_Integer IntPatch_ALineToWLine::CheckDeflection(const gp_XYZ& theMidPt,
602                                                         const Standard_Real theMaxDeflection) const
603 {
604   Standard_Real aDist = Abs(myQuad1.Distance(theMidPt));
605   if(aDist > theMaxDeflection)
606     return 1;
607
608   aDist = Max(Abs(myQuad2.Distance(theMidPt)), aDist);
609   
610   if(aDist > theMaxDeflection)
611     return 1;
612
613   if((aDist + aDist) < theMaxDeflection)
614     return -1;
615
616   return 0;
617 }
618
619 //=======================================================================
620 //function : StepComputing
621 //purpose  : 
622 //=======================================================================
623 Standard_Boolean IntPatch_ALineToWLine::
624                       StepComputing(const Handle(IntPatch_ALine)& theALine,
625                                     const IntSurf_PntOn2S& thePOn2S,
626                                     const Standard_Real theLastParOfAline,
627                                     const Standard_Real theCurParam,
628                                     const Standard_Real theTgMagnitude,
629                                     const Standard_Real theStepMin,
630                                     const Standard_Real theStepMax,
631                                     const Standard_Real theMaxDeflection,
632                                     Standard_Real& theStep) const
633 {
634   if(theTgMagnitude < Precision::Confusion())
635     return Standard_False;
636   
637   const Standard_Real anEps = myTol3D;
638
639   //Indeed, 1.0e+15 < 2^50 < 1.0e+16. Therefore,
640   //if we apply bisection method to the range with length
641   //1.0e+6 then we will be able to find solution with max error ~1.0e-9.
642   const Standard_Integer aNbIterMax = 50;
643
644   const Standard_Real aNotFilledRange = theLastParOfAline - theCurParam;
645   Standard_Real aMinStep = theStepMin, aMaxStep = Min(theStepMax, aNotFilledRange);
646
647   if(aMinStep > aMaxStep)
648   {
649     theStep = aMaxStep;
650     return Standard_True;
651   }
652
653   const Standard_Real aR = IntPatch_PointLine::
654                             CurvatureRadiusOfIntersLine(myS1, myS2, thePOn2S);
655
656   if(aR < 0.0)
657   {
658     return Standard_False;
659   }
660   else
661   {
662     //The 3D-step is defined as length of the tangent to the osculating circle
663     //by the condition that the distance from end point of the tangent to the
664     //circle is no greater than anEps. theStep is the step in
665     //parameter space of intersection curve (must be converted from 3D-step).
666
667     theStep = Min(sqrt(anEps*(2.0*aR + anEps))/theTgMagnitude, aMaxStep);
668     theStep = Max(theStep, aMinStep);
669   }
670
671   //The step value has been computed for osculating circle.
672   //Now it should be checked for real intersection curve
673   //and is made more precise in case of necessity.
674
675   Standard_Integer aNbIter = 0;
676   do
677   {
678     aNbIter++;
679
680     const gp_XYZ& aP1 = thePOn2S.Value().XYZ();
681     const gp_XYZ aP2(theALine->Value(theCurParam + theStep).XYZ());
682     const Standard_Integer aStatus = CheckDeflection(0.5*(aP1 + aP2), theMaxDeflection);
683
684     if(aStatus == 0)
685       break;
686
687     if(aStatus < 0)
688     {
689       aMinStep = theStep;
690     }
691     else //if(aStatus > 0)
692     {
693       aMaxStep = theStep;
694     }
695
696     theStep = 0.5*(aMinStep + aMaxStep);
697   }
698   while(((aMaxStep - aMinStep) > Precision::PConfusion()) && (aNbIter <= aNbIterMax));
699
700   if(aNbIter > aNbIterMax)
701     return Standard_False;
702
703   return Standard_True;
704 }