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