0023947: Eliminate trivial compiler warnings in MSVC++ with warning level 4
[occt.git] / src / IntTools / IntTools_BeanBeanIntersector.cxx
1 // Copyright (c) 1999-2012 OPEN CASCADE SAS
2 //
3 // The content of this file is subject to the Open CASCADE Technology Public
4 // License Version 6.5 (the "License"). You may not use the content of this file
5 // except in compliance with the License. Please obtain a copy of the License
6 // at http://www.opencascade.org and read it completely before using this file.
7 //
8 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
9 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
10 //
11 // The Original Code and all software distributed under the License is
12 // distributed on an "AS IS" basis, without warranty of any kind, and the
13 // Initial Developer hereby disclaims all such warranties, including without
14 // limitation, any warranties of merchantability, fitness for a particular
15 // purpose or non-infringement. Please see the License for the specific terms
16 // and conditions governing the rights and limitations under the License.
17
18 #include <IntTools_BeanBeanIntersector.ixx>
19
20 #include <IntTools_Root.hxx>
21 #include <Precision.hxx>
22 #include <Extrema_POnCurv.hxx>
23 #include <BRep_Tool.hxx>
24 #include <Geom_Curve.hxx>
25 #include <TColStd_Array1OfReal.hxx>
26 #include <TColStd_Array1OfInteger.hxx>
27 #include <IntTools_CArray1OfReal.hxx>
28 #include <gp_Lin.hxx>
29 #include <Intf_Array1OfLin.hxx>
30 #include <Bnd_Box.hxx>
31 #include <Extrema_ExtCC.hxx>
32 #include <Extrema_ExtElC.hxx>
33 #include <Extrema_LocateExtPC.hxx>
34 #include <gp_Circ.hxx>
35 #include <gp_Elips.hxx>
36 #include <IntTools.hxx>
37 #include <ElCLib.hxx>
38 #include <Geom_Line.hxx>
39 #include <GeomAdaptor_HCurve.hxx>
40
41 static 
42   void LocalPrepareArgs(BRepAdaptor_Curve& theCurve,
43                         const Standard_Real      theFirstParameter,
44                         const Standard_Real      theLastParameter,
45                         Standard_Real&           theDeflection,
46                         IntTools_CArray1OfReal&  theArgs);
47
48 static 
49   Standard_Boolean SetEmptyResultRange(const Standard_Real      theParameter, 
50                                        IntTools_MarkedRangeSet& theMarkedRange);
51 static
52   Standard_Integer CheckCoincidence(const Standard_Real aT11, 
53                                     const Standard_Real aT12,
54                                     const Handle(Geom_Curve)& aC1,
55                                     const Standard_Real aT21, 
56                                     const Standard_Real aT22,
57                                     const Handle(Geom_Curve)& aC2,
58                                     const Standard_Real aCriteria,
59                                     const Standard_Real aCurveResolution1,
60                                     GeomAPI_ProjectPointOnCurve& aProjector);
61
62
63 // ==================================================================================
64 // function: IntTools_BeanBeanIntersector
65 // purpose: 
66 // ==================================================================================
67 IntTools_BeanBeanIntersector::IntTools_BeanBeanIntersector() :
68
69 myFirstParameter1(0.),
70 myLastParameter1(0.),
71 myFirstParameter2(0.),
72 myLastParameter2(0.),
73 myBeanTolerance1(0.),
74 myBeanTolerance2(0.),
75 myCurveResolution1(0.),
76 myCriteria(0.),
77 myIsDone(Standard_False)
78 {
79 }
80
81 // ==================================================================================
82 // function: IntTools_BeanBeanIntersector
83 // purpose: 
84 // ==================================================================================
85 IntTools_BeanBeanIntersector::IntTools_BeanBeanIntersector(const TopoDS_Edge& theEdge1,
86                                                            const TopoDS_Edge& theEdge2) :
87
88 myFirstParameter1(0.),
89 myLastParameter1(0.),
90 myFirstParameter2(0.),
91 myLastParameter2(0.),
92 myBeanTolerance1(0.),
93 myBeanTolerance2(0.),
94 myCurveResolution1(0.),
95 myCriteria(0.),
96 myIsDone(Standard_False)
97 {
98   Init(theEdge1, theEdge2);
99 }
100
101 // ==================================================================================
102 // function: IntTools_BeanBeanIntersector
103 // purpose: 
104 // ==================================================================================
105 IntTools_BeanBeanIntersector::IntTools_BeanBeanIntersector(const BRepAdaptor_Curve& theCurve1,
106                                                            const BRepAdaptor_Curve& theCurve2,
107                                                            const Standard_Real      theBeanTolerance1,
108                                                            const Standard_Real      theBeanTolerance2) :
109
110 myFirstParameter1(0.),
111 myLastParameter1(0.),
112 myFirstParameter2(0.),
113 myLastParameter2(0.),
114 myBeanTolerance1(0.),
115 myBeanTolerance2(0.),
116 myCurveResolution1(0.),
117 myCriteria(0.),
118 myIsDone(Standard_False)
119 {
120   Init(theCurve1, theCurve2, theBeanTolerance1, theBeanTolerance2);
121 }
122
123 // ==================================================================================
124 // function: IntTools_BeanBeanIntersector
125 // purpose: 
126 // ==================================================================================
127 IntTools_BeanBeanIntersector::IntTools_BeanBeanIntersector(const BRepAdaptor_Curve& theCurve1,
128                                                            const BRepAdaptor_Curve& theCurve2,
129                                                            const Standard_Real       theFirstParOnCurve1,
130                                                            const Standard_Real       theLastParOnCurve1,
131                                                            const Standard_Real       theFirstParOnCurve2,
132                                                            const Standard_Real       theLastParOnCurve2,
133                                                            const Standard_Real       theBeanTolerance1,
134                                                            const Standard_Real       theBeanTolerance2) :
135
136 myFirstParameter1(0.),
137 myLastParameter1(0.),
138 myFirstParameter2(0.),
139 myLastParameter2(0.),
140 myBeanTolerance1(0.),
141 myBeanTolerance2(0.),
142 myCurveResolution1(0.),
143 myCriteria(0.),
144 myIsDone(Standard_False)
145 {
146   Init(theCurve1, theCurve2, theFirstParOnCurve1, theLastParOnCurve1, 
147        theFirstParOnCurve2, theLastParOnCurve2, 
148        theBeanTolerance1, theBeanTolerance2);
149 }
150
151 // ==================================================================================
152 // function: Init
153 // purpose: 
154 // ==================================================================================
155 void IntTools_BeanBeanIntersector::Init(const TopoDS_Edge& theEdge1,
156                                         const TopoDS_Edge& theEdge2) 
157 {
158   myCurve1.Initialize(theEdge1);
159   myCurve2.Initialize(theEdge2);
160
161   myTrsfCurve1 = Handle(Geom_Curve)::DownCast(myCurve1.Curve().Curve()->Transformed(myCurve1.Trsf()));
162   myTrsfCurve2 = Handle(Geom_Curve)::DownCast(myCurve2.Curve().Curve()->Transformed(myCurve2.Trsf()));
163
164   SetBeanParameters(Standard_True, myCurve1.FirstParameter(), myCurve1.LastParameter());
165   SetBeanParameters(Standard_False, myCurve2.FirstParameter(), myCurve2.LastParameter());
166
167   myBeanTolerance1 = BRep_Tool::Tolerance(theEdge1);
168   myBeanTolerance2 = BRep_Tool::Tolerance(theEdge2);
169   myCriteria = myBeanTolerance1 + myBeanTolerance2;
170   myCurveResolution1 = myCurve1.Resolution(myCriteria);
171 }
172
173 // ==================================================================================
174 // function: Init
175 // purpose: 
176 // ==================================================================================
177 void IntTools_BeanBeanIntersector::Init(const BRepAdaptor_Curve& theCurve1,
178                                         const BRepAdaptor_Curve& theCurve2,
179                                         const Standard_Real      theBeanTolerance1,
180                                         const Standard_Real      theBeanTolerance2) 
181 {
182   myCurve1 = theCurve1;
183   myCurve2 = theCurve2;
184
185   SetBeanParameters(Standard_True, myCurve1.FirstParameter(), myCurve1.LastParameter());
186   SetBeanParameters(Standard_False, myCurve2.FirstParameter(), myCurve2.LastParameter());
187
188   myTrsfCurve1 = Handle(Geom_Curve)::DownCast(myCurve1.Curve().Curve()->Transformed(myCurve1.Trsf()));
189   myTrsfCurve2 = Handle(Geom_Curve)::DownCast(myCurve2.Curve().Curve()->Transformed(myCurve2.Trsf()));
190
191   myBeanTolerance1 = theBeanTolerance1;
192   myBeanTolerance2 = theBeanTolerance2;
193   myCriteria = myBeanTolerance1 + myBeanTolerance2;
194   myCurveResolution1 = myCurve1.Resolution(myCriteria);
195 }
196
197 // ==================================================================================
198 // function: Init
199 // purpose: 
200 // ==================================================================================
201 void IntTools_BeanBeanIntersector::Init(const BRepAdaptor_Curve& theCurve1,
202                                         const BRepAdaptor_Curve& theCurve2,
203                                         const Standard_Real      theFirstParOnCurve1,
204                                         const Standard_Real      theLastParOnCurve1,
205                                         const Standard_Real      theFirstParOnCurve2,
206                                         const Standard_Real      theLastParOnCurve2,
207                                         const Standard_Real      theBeanTolerance1,
208                                         const Standard_Real      theBeanTolerance2) 
209 {
210   myCurve1 = theCurve1;
211   myCurve2 = theCurve2;
212
213   myTrsfCurve1 = Handle(Geom_Curve)::DownCast(myCurve1.Curve().Curve()->Transformed(myCurve1.Trsf()));
214   myTrsfCurve2 = Handle(Geom_Curve)::DownCast(myCurve2.Curve().Curve()->Transformed(myCurve2.Trsf()));
215
216   SetBeanParameters(Standard_True, theFirstParOnCurve1, theLastParOnCurve1);
217   SetBeanParameters(Standard_False, theFirstParOnCurve2, theLastParOnCurve2);
218
219   myBeanTolerance1 = theBeanTolerance1;
220   myBeanTolerance2 = theBeanTolerance2;
221   myCriteria = myBeanTolerance1 + myBeanTolerance2;
222   myCurveResolution1 = myCurve1.Resolution(myCriteria);
223 }
224
225 // ==================================================================================
226 // function: SetBeanParameters
227 // purpose: 
228 // ==================================================================================
229 void IntTools_BeanBeanIntersector::SetBeanParameters(const Standard_Boolean IsFirstBean,
230                                                      const Standard_Real    theFirstParOnCurve,
231                                                      const Standard_Real    theLastParOnCurve) 
232 {
233   if(IsFirstBean) {
234     myFirstParameter1 = theFirstParOnCurve;
235     myLastParameter1  = theLastParOnCurve;
236   }
237   else {
238     myFirstParameter2 = theFirstParOnCurve;
239     myLastParameter2  = theLastParOnCurve;
240   }
241 }
242 // ==================================================================================
243 // function: Result
244 // purpose: 
245 // ==================================================================================
246 const IntTools_SequenceOfRanges& IntTools_BeanBeanIntersector::Result() const
247 {
248   return myResults;
249 }
250
251 // ==================================================================================
252 // function: Result
253 // purpose: 
254 // ==================================================================================
255  void IntTools_BeanBeanIntersector::Result(IntTools_SequenceOfRanges& theResults) const
256 {
257   theResults = myResults;
258 }
259 // ==================================================================================
260 // function: Perform
261 // purpose: 
262 // ==================================================================================
263 void IntTools_BeanBeanIntersector::Perform() 
264 {
265   Standard_Boolean bFastComputed;
266   Standard_Integer k, i, iFlag, aNbRanges, aNbResults;
267   Standard_Real aMidParameter, aCoeff, aParamDist, aPPC;
268   Standard_Real aCriteria2, aD2;
269   gp_Pnt aPi, aPh;
270   IntTools_CArray1OfReal aParams;
271   IntTools_Range aRange2, aRange;
272   // 
273   myIsDone = Standard_False;
274   myResults.Clear();
275   //
276   LocalPrepareArgs(myCurve1, myFirstParameter1, myLastParameter1, myDeflection, aParams);
277   //
278   myRangeManager.SetRanges(aParams, 0);
279   //
280   aNbRanges=myRangeManager.Length();
281   if(!aNbRanges) {
282     return;
283   }
284   //
285   bFastComputed=FastComputeIntersection();
286   if(bFastComputed) {
287     aRange.SetFirst(myFirstParameter1);
288     aRange.SetLast (myLastParameter1);
289     myResults.Append(aRange);
290     myIsDone = Standard_True;
291     return;
292   }
293   //
294   ComputeRoughIntersection();
295   
296   //Standard_Real aMidParameter = (myFirstParameter2 + myLastParameter2) * 0.5;
297   aCoeff=0.5753;
298   aMidParameter = myFirstParameter2+(myLastParameter2-myFirstParameter2)*aCoeff;
299   //
300   for(k = 0; k < 2; ++k) {
301     if(!k) {
302       aRange2.SetFirst(myFirstParameter2);
303       aRange2.SetLast(aMidParameter);
304     }
305     else {
306       aRange2.SetFirst(aMidParameter);
307       aRange2.SetLast(myLastParameter2);
308     }
309     
310     ComputeUsingExtrema(aRange2);
311     
312     ComputeNearRangeBoundaries(aRange2);
313   }
314   //
315   //  Legend iFlag
316   //
317   // 0 - just initialized 
318   // 1 - non-intersected
319   // 2 - roughly intersected
320   // 3 - intersection is not done
321   // 4 - coincided range
322   //
323   aPPC=Precision::PConfusion();
324   aCriteria2=myCriteria*myCriteria;
325   aNbRanges=myRangeManager.Length();
326   //
327   for(i=1; i<=aNbRanges; ++i) {
328     iFlag=myRangeManager.Flag(i);
329     //
330     if(iFlag==4) {
331       aRange=myRangeManager.Range(i);
332       aNbResults=myResults.Length();
333       if(aNbResults>0) {
334         const IntTools_Range& aLastRange = myResults.Last();
335         //
336         aParamDist = Abs(aRange.First() - aLastRange.Last());
337         if(aParamDist > myCurveResolution1) {
338           myResults.Append(aRange);
339         }
340         else {
341           aPi=myCurve1.Value(aRange.First());
342           aPh=myCurve1.Value(aLastRange.Last());
343           aD2=aPi.SquareDistance(aPh);
344           if(aParamDist<aPPC || aD2<aCriteria2) { 
345             myResults.ChangeValue(aNbResults).SetLast(aRange.Last());
346           }
347           else {
348             myResults.Append(aRange);
349           }
350         }
351       }// if(aNbR>0) {
352       else {
353         myResults.Append(aRange);
354       }
355     } //if(iFlag==4) {
356   } // for(i = 1; i <= myRangeManager.Length(); i++) {
357   myIsDone = Standard_True;
358 }
359 // ==================================================================================
360 // function: FastComputeIntersection
361 // purpose: 
362 // ==================================================================================
363 Standard_Boolean IntTools_BeanBeanIntersector::FastComputeIntersection() 
364 {
365   Standard_Boolean aresult;
366   GeomAbs_CurveType aCT1, aCT2;
367   //
368   aresult = Standard_False;
369   //
370   aCT1=myCurve1.GetType();
371   aCT2=myCurve2.GetType();
372   //
373   if(aCT1 != aCT2) {
374     return aresult;
375   }
376   //
377   // Line
378   if(aCT1==GeomAbs_Line) {
379     Standard_Real par1, par2;
380     
381     if((Distance(myFirstParameter1, par1) < myCriteria) &&
382        (Distance(myLastParameter1, par2) < myCriteria)) {
383
384       if((par1  >= myFirstParameter2) && (par1 <= myLastParameter2) &&
385          (par2  >= myFirstParameter2) && (par2 <= myLastParameter2)) {
386         myRangeManager.InsertRange(myFirstParameter1, myLastParameter1, 4);
387         aresult = Standard_True;
388       }
389     }
390     return aresult;
391   } 
392   //
393   // Circle
394   if(aCT1==GeomAbs_Circle) {
395     Standard_Real anAngle, aPA, aDistLoc, aDist, aDiff, aR1, aR2;
396     gp_Circ aCirc1, aCirc2;
397     gp_Dir aDir1, aDir2;
398     //
399     aCirc1=myCurve1.Circle();
400     aCirc2=myCurve2.Circle();
401     aR1=aCirc1.Radius();
402     aR2=aCirc2.Radius();
403     //
404     aPA=Precision::Angular();
405     aDir1 = aCirc1.Axis().Direction();
406     aDir2 = aCirc2.Axis().Direction();
407     //
408     anAngle = aDir1.Angle(aDir2);
409     if(anAngle > aPA) {
410       return aresult; //->
411     }
412     //
413     const gp_Pnt& aPLoc1=aCirc1.Location();
414     const gp_Pnt& aPLoc2=aCirc2.Location();
415     aDistLoc = aPLoc1.Distance(aPLoc2);
416     aDist=aDistLoc;
417     aDiff=aR1 - aR2;
418     aDist+=Abs(aDiff);
419     if(Abs(aDist) > myCriteria) {
420       return aresult; //->
421     }
422     //
423     Standard_Real aSinPA, atmpvalue, aprojectedradius;
424     //
425     aSinPA=sin(aPA);
426     atmpvalue = aR1*aSinPA;
427     atmpvalue *= atmpvalue;
428     aprojectedradius = sqrt(aR1*aR1 - atmpvalue);
429
430     aDiff = aprojectedradius - aR2;
431     aDist = aDistLoc + sqrt((aDiff * aDiff) + atmpvalue);
432     if(Abs(aDist) > myCriteria) {
433       return aresult; //->
434     }
435     //
436     Standard_Boolean newparfound;
437     Standard_Integer i;
438     Standard_Real afirstpar, alastpar, par1, par2, apar;
439     //
440     afirstpar = myFirstParameter1;
441     alastpar  = myLastParameter1;
442     
443     for(i = 0; i < 2; i++) {
444       if((Distance(afirstpar, par1) < myCriteria) &&
445          (Distance(alastpar , par2) < myCriteria)) {
446         
447         if(i || Distance((myFirstParameter1 + myLastParameter2) * 0.5, apar) < myCriteria) {
448           myRangeManager.InsertRange(afirstpar, alastpar, 4);
449           
450           if(!i) {
451             aresult = Standard_True;
452           }
453         }
454         break;
455       }
456       //
457       if(i) {
458         break;
459       }
460       // i=0 :
461       newparfound = Standard_False;
462       
463       if(Distance((myFirstParameter1 + myLastParameter2) * 0.5, apar) < myCriteria) {
464         afirstpar = myFirstParameter1 + myCriteria;
465         alastpar  = myLastParameter1  - myCriteria;
466         newparfound = Standard_True;
467         
468         if(alastpar <= afirstpar) {
469           newparfound = Standard_False;
470         }
471       }
472       //
473       if(!newparfound) {
474         break;
475       }
476     }// for(i = 0; i < 2; i++) {
477   } // if(aCT1==GeomAbs_Circle)
478   //modified by NIZNHY-PKV Mon Oct 08 14:08:19 2012f
479   if (aCT1==GeomAbs_BSplineCurve || aCT1==GeomAbs_BezierCurve) {
480     Standard_Integer iFlag;
481     //
482     iFlag=CheckCoincidence(myFirstParameter1,
483                            myLastParameter1,
484                            myTrsfCurve1,
485                            myFirstParameter2,
486                            myLastParameter2,
487                            myTrsfCurve2,
488                            myCriteria,
489                            myCurveResolution1,
490                            myProjector);
491     if (!iFlag) {
492       aresult=!aresult;
493     }
494   }
495   //modified by NIZNHY-PKV Mon Oct 08 14:08:23 2012t
496   return aresult;
497 }
498 // ==================================================================================
499 // function: Distance
500 // purpose: 
501 // ==================================================================================
502 Standard_Real IntTools_BeanBeanIntersector::Distance(const Standard_Real theArg,
503                                                      Standard_Real& theArgOnOtherBean) 
504 {
505   Standard_Real aDistance;
506   Standard_Integer aNbPoints;
507   gp_Pnt aPoint;
508   //
509   aDistance=RealLast();
510   //
511   aPoint=myCurve1.Value(theArg);
512   myProjector.Init(myTrsfCurve2, myFirstParameter2, myLastParameter2);
513   myProjector.Perform(aPoint);
514   //
515   aNbPoints=myProjector.NbPoints();
516   if(aNbPoints > 0) {
517     theArgOnOtherBean = myProjector.LowerDistanceParameter();
518     aDistance=myProjector.LowerDistance();
519   }
520   //
521   else {
522     Standard_Real aDistance1, aDistance2;
523     //
524     aDistance1 = aPoint.Distance(myCurve2.Value(myFirstParameter2));
525     aDistance2 = aPoint.Distance(myCurve2.Value(myLastParameter2));
526     //
527     theArgOnOtherBean = myLastParameter2;
528     aDistance=aDistance2;  
529     if(aDistance1 < aDistance2) {
530       theArgOnOtherBean = myFirstParameter2;
531       aDistance=aDistance1;
532     }
533   }
534   return aDistance;
535 }
536 // ==================================================================================
537 // function: ComputeRoughIntersection
538 // purpose: 
539 // ==================================================================================
540 void IntTools_BeanBeanIntersector::ComputeRoughIntersection() 
541 {
542   Standard_Boolean isintersection;
543   Standard_Integer i, aNbArgs, aNbArgs1, aNbRanges, j, aNbLines, k, pIt, extIt, iFlag;
544   Standard_Real aDeflection, aGPR, aCurDeflection, aT1, aT2, aD;
545   Standard_Real aMaxDistance, aDistance, aPPC, aPrm1, aPrm2, aPPA;
546   GeomAbs_CurveType aCT1, aCT2;
547   gp_Pnt aPoint1, aPoint2, aMidPOnCurve, aMidPOnLine, aP1, aP2;
548   IntTools_CArray1OfReal anArgs;
549   LocalPrepareArgs(myCurve2, myFirstParameter2, myLastParameter2, aDeflection, anArgs);
550   //
551   aNbArgs=anArgs.Length();
552   if(!aNbArgs) {
553     return;
554   }
555   //
556   aCT1=myCurve1.GetType();
557   aCT2=myCurve2.GetType();
558   aGPR=gp::Resolution();
559   aPPC=Precision::PConfusion();
560   aPPA=Precision::Angular();
561   aNbArgs1=aNbArgs-1;
562   //
563   Intf_Array1OfLin aLines(1, aNbArgs1);
564   TColStd_Array1OfInteger aLineFlags(1, aNbArgs1);
565   TColStd_Array1OfReal aDistances(1, aNbArgs1);
566   //
567   aT1=anArgs(0);
568   aPoint1 = myCurve2.Value(aT1);
569   for(i=1; i<aNbArgs; ++i) {
570     aT2=anArgs(i);
571     aPoint2 = myCurve2.Value(aT2);
572     gp_Vec aVec(aPoint1, aPoint2);
573     aD=aVec.Magnitude();
574     aDistances.SetValue(i, aD);
575     //
576     if(aD<=aGPR) {
577       aLineFlags.SetValue(i, 0);
578     }
579     else {
580       aLineFlags.SetValue(i, 1);
581       gp_Lin aLine(aPoint1, gp_Dir(aVec));
582       aLines.SetValue(i, aLine);
583       //
584       if((aCT2 == GeomAbs_BezierCurve) ||
585          (aCT2 == GeomAbs_BSplineCurve)) {
586         aMidPOnCurve = myCurve2.Value((aT1+aT2) * 0.5);
587         aMidPOnLine = ElCLib::Value((aDistances(i)*0.5), aLine);
588         aCurDeflection = aMidPOnCurve.Distance(aMidPOnLine);
589         if(aCurDeflection > aDeflection) {
590           aDeflection = aCurDeflection;
591         }
592       }
593     }
594     aT1=aT2;
595     aPoint1 = aPoint2;
596   }
597   //
598   aNbLines=aLines.Upper();
599   aMaxDistance = myCriteria + myDeflection + aDeflection;
600   
601   aT1=myRangeManager.Range(1).First();
602   aPoint1 = myCurve1.Value(aT1);
603   aNbRanges=myRangeManager.Length();
604   for(i = 1; i <= aNbRanges; ++i) {
605     const IntTools_Range& aRange = myRangeManager.Range(i);
606     aT2=aRange.Last();
607     aPoint2 = myCurve1.Value(aT2);
608     //
609     iFlag=myRangeManager.Flag(i);
610     if(iFlag==4) {// coincided
611       aT1=aT2;
612       aPoint1 = aPoint2;
613       continue;
614     }
615     //
616     myRangeManager.SetFlag(i, 1); // not intersected
617     
618     Bnd_Box aBox1;
619     aBox1.Add(aPoint1);
620     aBox1.Add(aPoint2);
621     aBox1.Enlarge(myBeanTolerance1 + myDeflection);
622
623     gp_Vec aVec(aPoint1, aPoint2);
624
625     aDistance=aVec.Magnitude();
626     if(aDistance <= aGPR) {
627       myRangeManager.SetFlag(i, 0);
628       continue;
629     }
630     //
631     gp_Lin aLine(aPoint1, gp_Dir(aVec));
632     //
633     if((aCT1 == GeomAbs_BezierCurve) ||
634        (aCT1 == GeomAbs_BSplineCurve)) {
635       aMidPOnCurve = myCurve1.Value((aRange.First() + aRange.Last()) * 0.5);
636       aMidPOnLine = ElCLib::Value((aDistance*0.5), aLine);
637       aCurDeflection = aMidPOnCurve.Distance(aMidPOnLine);
638       if(myDeflection < aCurDeflection) {
639         aMaxDistance += aCurDeflection - myDeflection;
640         myDeflection = aCurDeflection;  
641       }
642     }
643     //
644     for(j=1; j<=aNbLines; ++j) {
645       if(!aLineFlags(j)) {
646         myRangeManager.SetFlag(i, 0);
647         continue;
648       }
649       //
650       const gp_Lin& aL2=aLines(j);
651       //Handle(Geom_Line) aC2=new Geom_Line(aL2); // DEB ft
652       aD=aDistances(j);
653       aP1=ElCLib::Value(0., aL2);
654       aP2=ElCLib::Value(aD, aL2);
655       //
656       Extrema_ExtElC anExtrema(aLine, aL2, aPPA);
657       if(anExtrema.IsDone() && (anExtrema.IsParallel() || (anExtrema.NbExt() > 0))) {
658         isintersection = Standard_False;
659
660         if(anExtrema.IsParallel()) {
661           isintersection = (anExtrema.SquareDistance(1) < aMaxDistance * aMaxDistance);
662         }
663         else { //1
664           for(k = 1; !isintersection && k <= anExtrema.NbExt(); ++k) {
665             if(anExtrema.SquareDistance(k) < aMaxDistance * aMaxDistance) {
666               Extrema_POnCurv P1, P2;
667               anExtrema.Points(k, P1, P2);
668               aPrm1=P1.Parameter();
669               aPrm2=P2.Parameter();
670               if((aPrm1 >= -aMaxDistance) && (aPrm1 <= aDistance+aMaxDistance) &&
671                  (aPrm2 >= -aMaxDistance) && (aPrm2 <= aD+aMaxDistance)) {
672                 isintersection = Standard_True;
673               }
674               else { // 2
675                 Extrema_ExtPElC aPointProjector;
676
677                 for(pIt = 0; !isintersection && (pIt < 4); ++pIt) {
678                   switch (pIt) {
679                     case 0: {
680                       aPointProjector = 
681                         //Extrema_ExtPElC(aPoint1, aLines(j), aPPC, 0., aDistances(j));
682                         Extrema_ExtPElC(aPoint1, aL2, aPPC, -aMaxDistance, aD+aMaxDistance);
683                       break;
684                     }
685                     case 1: {
686                       aPointProjector =
687                         //Extrema_ExtPElC(aPoint2, aLines(j), aPPC, 0., aD);
688                         Extrema_ExtPElC(aPoint2, aL2, aPPC, -aMaxDistance, aD+aMaxDistance);
689                       break;
690                     }
691                     case 2: {
692                       aPointProjector = 
693                         //Extrema_ExtPElC(ElCLib::Value(0., aLines(j)), aLine, aPPC, 0., aDistance);
694                         Extrema_ExtPElC(aP1, aLine, aPPC, -aMaxDistance, aDistance+aMaxDistance);
695                       break;
696                     }
697                     case 3: {
698                       aPointProjector =
699                         //Extrema_ExtPElC(ElCLib::Value(aDistances(j), aLines(j)), aLine, aPPC, 0., aDistance);
700                         Extrema_ExtPElC(aP2, aLine, aPPC, -aMaxDistance, aDistance+aMaxDistance);
701                       break;
702                     }
703                     default: {
704                       break;
705                     }
706                   }
707                   //
708                   if(aPointProjector.IsDone()) {
709             Standard_Real aMaxDistance2 = aMaxDistance * aMaxDistance;
710                     for(extIt = 1; extIt <= aPointProjector.NbExt(); extIt++) {
711                       if(aPointProjector.SquareDistance(extIt) < aMaxDistance2) {
712                         isintersection = Standard_True;
713                       }
714                     }
715                   }
716                 } // end for
717               }// else { // 2
718             }//if(anExtrema.Value(k) < aMaxDistance) {
719           }//for(k = 1; !isintersection && k <= anExtrema.NbExt(); k++) {
720         }//else { //1
721         
722         if(isintersection) {
723           myRangeManager.SetFlag(i, 2); // roughly intersected
724           break;
725         }
726       }//if(anExtrema.IsDone() && (anExtrema.IsParallel() || (anExtrema.NbExt() > 0))) {
727       else {
728         Bnd_Box aBox2;
729         aBox2.Add(myCurve2.Value(anArgs(j-1)));
730         aBox2.Add(myCurve2.Value(anArgs(j)));
731         aBox2.Enlarge(myBeanTolerance2 + aDeflection);
732         //
733         if(!aBox1.IsOut(aBox2)) {
734           myRangeManager.SetFlag(i, 2); // roughly intersected
735           break;
736         }
737       }
738     }
739     aT1=aT2;
740     aPoint1 = aPoint2;
741   }
742 }
743
744 // ==================================================================================
745 // function: ComputeUsingExtrema
746 // purpose: 
747 // ==================================================================================
748 void IntTools_BeanBeanIntersector::ComputeUsingExtrema(const IntTools_Range& theRange2) 
749 {
750   //rln Dec 2008.
751   //Extrema_ExtCC is reused throughout this method to store caches computed on
752   //theRange2. However it is actually used only in a few calls of
753   //ComputeUsingExtrema(), so using a default constructor would add unnecessary overhead
754   //of initialization its internal fields. Since it is not manipulated by Handle then
755   //we will use a pointer to it and initialize it only when needed.
756   Extrema_ExtCC *apExtrema = 0; 
757   Handle(GeomAdaptor_HCurve) aHCurve1, aHCurve2; //will be initialized later, only if needed
758   //handles are used to guard pointers to GeomAdaptor_Curve inside Extrema
759   Standard_Real aCriteria2 = myCriteria * myCriteria;
760   for(Standard_Integer i = 1; i <= myRangeManager.Length(); i++) {
761
762     if(myRangeManager.Flag(i) == 2 || myRangeManager.Flag(i) == 0) {
763       const IntTools_Range& aParamRange = myRangeManager.Range(i);
764       
765       if(aParamRange.Last() - aParamRange.First() < Precision::PConfusion()) {
766
767         if(((i > 1) && (myRangeManager.Flag(i-1) == 4)) ||
768            ((i <  myRangeManager.Length()) && (myRangeManager.Flag(i+1) == 4))) {
769           myRangeManager.SetFlag(i, 4);
770           continue;
771         }
772       }
773       if (aHCurve2.IsNull()) {
774         //initialize only once 
775         apExtrema = new Extrema_ExtCC;
776         Standard_Real ftmp = theRange2.First() - Precision::PConfusion();
777         Standard_Real ltmp = theRange2.Last()  + Precision::PConfusion();
778         ftmp = (ftmp < myFirstParameter2) ? myFirstParameter2 : ftmp;
779         ltmp = (ltmp > myLastParameter2)  ? myLastParameter2  : ltmp;
780         aHCurve2 = new GeomAdaptor_HCurve (myTrsfCurve2, ftmp, ltmp);
781         apExtrema->SetCurve (2, aHCurve2->Curve(), theRange2.First(), theRange2.Last());
782       }
783       Extrema_ExtCC& anExtrema = *apExtrema;
784
785       Standard_Real ftmp = aParamRange.First() - Precision::PConfusion();
786       Standard_Real ltmp = aParamRange.Last()  + Precision::PConfusion();
787       ftmp = (ftmp < myFirstParameter1) ? myFirstParameter1 : ftmp;
788       ltmp = (ltmp > myLastParameter1)  ? myLastParameter1  : ltmp;
789       aHCurve1 = new GeomAdaptor_HCurve (myTrsfCurve1, ftmp, ltmp);
790       anExtrema.SetCurve (1, aHCurve1->Curve(), aParamRange.First(), aParamRange.Last());
791
792       anExtrema.Perform();
793
794       if(anExtrema.IsDone() && (anExtrema.IsParallel() || (anExtrema.NbExt() > 0))) {
795         Standard_Integer anOldNbRanges = myRangeManager.Length();
796
797         if (anExtrema.IsParallel()) {
798           if(anExtrema.SquareDistance(1) < aCriteria2) {
799             Standard_Real theParameter1, theParameter2;
800             Standard_Real adistance1 = Distance(aParamRange.First(), theParameter1);
801             Standard_Real adistance2 = Distance(aParamRange.Last(),  theParameter2);
802             Standard_Boolean validdistance1 = (adistance1 < myCriteria);
803             Standard_Boolean validdistance2 = (adistance2 < myCriteria);
804
805             if (validdistance1 && validdistance2) {
806               myRangeManager.InsertRange(aParamRange.First(), aParamRange.Last(), 4);
807               continue;
808             }
809             else {
810               if(validdistance1) {
811                 ComputeRangeFromStartPoint(Standard_True, aParamRange.First(), i, theParameter1, theRange2);
812               }
813               else {
814                 if(validdistance2) {
815                   ComputeRangeFromStartPoint(Standard_False, aParamRange.Last(), i, theParameter2, theRange2);
816                 }
817                 else {
818                   Standard_Real a  = aParamRange.First();
819                   Standard_Real b  = aParamRange.Last();
820                   Standard_Real da = adistance1;
821                   Standard_Real db = adistance2;
822                   Standard_Real asolution = a;
823                   Standard_Boolean found = Standard_False;
824                   
825                   while(((b - a) > myCurveResolution1) && !found) {
826                     asolution = (a+b)*0.5;
827                     Standard_Real adist = Distance(asolution, theParameter1);
828                     
829                     if(adist < myCriteria) {
830                       found = Standard_True;
831                     }
832                     else {
833                       if(da < db) {
834                         b = asolution;
835                         db = adist;
836                       }
837                       else {
838                         a = asolution;
839                         da = adist;
840                       }
841                     }
842                   } // end while
843
844                   if(found) {
845                     ComputeRangeFromStartPoint(Standard_False, asolution, i, theParameter1, theRange2);
846                     ComputeRangeFromStartPoint(Standard_True,  asolution, i, theParameter1, theRange2);
847                   }
848                   else {
849                     myRangeManager.SetFlag(i, 2);
850                   }
851                 }
852               }
853             }
854           }
855         }
856         else {
857
858           for(Standard_Integer j = 1 ; j <= anExtrema.NbExt(); j++) {
859             if(anExtrema.SquareDistance(j) < aCriteria2) {
860               Extrema_POnCurv p1, p2;
861               anExtrema.Points(j, p1, p2);
862
863               Standard_Integer aNbRanges = myRangeManager.Length();
864
865               Standard_Integer anIndex = myRangeManager.GetIndex(p1.Parameter(), Standard_False);
866               if(anIndex > 0) {
867                 ComputeRangeFromStartPoint(Standard_False, p1.Parameter(), anIndex, p2.Parameter(), theRange2);
868               }
869
870               anIndex = myRangeManager.GetIndex(p1.Parameter(), Standard_True);
871
872               if(anIndex > 0) {
873                 ComputeRangeFromStartPoint(Standard_True, p1.Parameter(), anIndex, p2.Parameter(), theRange2);
874               }
875
876               if(aNbRanges == myRangeManager.Length()) {
877                 SetEmptyResultRange(p1.Parameter(), myRangeManager);
878               }
879             }
880           } // end for
881         }
882         Standard_Integer adifference = myRangeManager.Length() - anOldNbRanges;
883
884         if(adifference > 0) {
885           i+=adifference;
886         }
887       }
888       else {
889         myRangeManager.SetFlag(i, 3); // intersection not done.
890       }
891     }
892   }
893   if (apExtrema) delete apExtrema;
894 }
895
896 // ==================================================================================
897 // function: ComputeNearRangeBoundaries
898 // purpose: 
899 // ==================================================================================
900 void IntTools_BeanBeanIntersector::ComputeNearRangeBoundaries(const IntTools_Range& theRange2) 
901 {
902   Standard_Real theParameter = theRange2.First();
903
904   for(Standard_Integer i = 1; i <= myRangeManager.Length(); i++) {
905     if(myRangeManager.Flag(i) != 3)
906       continue;
907
908     if((i > 1) && ((myRangeManager.Flag(i-1) == 1) || (myRangeManager.Flag(i-1) == 4))) {
909       myRangeManager.SetFlag(i, 2);
910       continue;
911     }
912
913     const IntTools_Range& aParamRange = myRangeManager.Range(i);
914     
915     if(Distance(aParamRange.First(), theParameter) < myCriteria) {
916       Standard_Integer aNbRanges = myRangeManager.Length();
917       
918       if(i > 1) {
919         ComputeRangeFromStartPoint(Standard_False, aParamRange.First(), i-1, theParameter, theRange2);
920       }
921       ComputeRangeFromStartPoint(Standard_True, aParamRange.First(), i + (myRangeManager.Length() - aNbRanges), theParameter, theRange2);
922
923       if(aNbRanges == myRangeManager.Length()) {
924         SetEmptyResultRange(aParamRange.First(), myRangeManager);
925       }
926     }
927     else {
928       myRangeManager.SetFlag(i, 2);
929     }
930   }
931
932   if((myRangeManager.Flag(myRangeManager.Length()) == 3) || 
933      (myRangeManager.Flag(myRangeManager.Length()) == 2)) {
934     const IntTools_Range& aParamRange = myRangeManager.Range(myRangeManager.Length());
935     
936     if(Distance(aParamRange.Last(), theParameter) < myCriteria) {
937       Standard_Integer aNbRanges = myRangeManager.Length();
938       myRangeManager.SetFlag(myRangeManager.Length(), 2);      
939
940       ComputeRangeFromStartPoint(Standard_False, aParamRange.Last(), myRangeManager.Length(), theParameter, theRange2);
941       
942       if(aNbRanges == myRangeManager.Length()) {
943         SetEmptyResultRange(aParamRange.Last(), myRangeManager);
944       }
945     }
946     else {
947       myRangeManager.SetFlag(myRangeManager.Length(), 2);
948     }
949   }
950 }
951
952 // ==================================================================================
953 // function: ComputeRangeFromStartPoint
954 // purpose: 
955 // ==================================================================================
956 void IntTools_BeanBeanIntersector::ComputeRangeFromStartPoint(const Standard_Boolean ToIncreaseParameter,
957                                                               const Standard_Real    theParameter,
958                                                               const Standard_Integer theIndex,
959                                                               const Standard_Real    theParameter2,
960                                                               const IntTools_Range&  theRange2) 
961 {
962
963   if(myRangeManager.Flag(theIndex) == 4 ||
964      myRangeManager.Flag(theIndex) == 1)
965     return;
966
967   Standard_Integer aValidIndex = theIndex;
968   Standard_Real aMinDelta        = myCurveResolution1 * 0.5;
969   Standard_Real aDeltaRestrictor = myLastParameter1 - myFirstParameter1;
970
971   if(Abs(aDeltaRestrictor) < Precision::PConfusion()) {
972     return;
973   }
974
975   if(aMinDelta > aDeltaRestrictor) {
976     aMinDelta = aDeltaRestrictor;
977   }
978   Standard_Real tenOfMinDelta    = aMinDelta * 10.;
979   Standard_Real aDelta           = myCurveResolution1;
980   Standard_Real aCurPar  = (ToIncreaseParameter) ? (theParameter + aDelta) : (theParameter - aDelta);
981   Standard_Real aPrevPar = theParameter;
982   IntTools_Range aCurrentRange = myRangeManager.Range(aValidIndex);
983
984   Standard_Boolean BoundaryCondition  = (ToIncreaseParameter) ? (aCurPar > aCurrentRange.Last()) : (aCurPar < aCurrentRange.First());
985   
986   if(BoundaryCondition) {
987     aCurPar = (ToIncreaseParameter) ? aCurrentRange.Last() : aCurrentRange.First();
988     BoundaryCondition = Standard_False;
989   }
990
991   Standard_Integer loopcounter = 0; // neccesary to have no infinite loop
992   Standard_Real aParameter = theParameter2;
993   Standard_Boolean anotherSolutionFound = Standard_False;
994
995   Standard_Boolean isboundaryindex = Standard_False;
996   Standard_Boolean isvalidindex = Standard_True;
997
998   Standard_Real aCriteria2 = myCriteria * myCriteria;
999
1000   while((aDelta >= aMinDelta) && (loopcounter <= 10)) {
1001     Standard_Boolean pointfound = Standard_False;
1002
1003     gp_Pnt aPoint = myCurve1.Value(aCurPar);
1004     GeomAdaptor_Curve aCurve2(myTrsfCurve2, theRange2.First(), theRange2.Last());
1005
1006     Extrema_LocateExtPC anExtrema(aPoint, aCurve2, aParameter, theRange2.First(), theRange2.Last(), 1.e-10);
1007
1008     if(anExtrema.IsDone()) {
1009       if(anExtrema.SquareDistance() < aCriteria2) {
1010         Extrema_POnCurv aPOnCurv = anExtrema.Point();
1011         aParameter = aPOnCurv.Parameter();
1012         pointfound = Standard_True;
1013       }
1014     }
1015     else {
1016       //       pointfound = (Distance(aCurPar, aParameter) < myCriteria);
1017       Standard_Real afoundparam = aParameter;
1018
1019       if(Distance(aCurPar, afoundparam) < myCriteria) {
1020         aParameter = afoundparam;
1021         pointfound = Standard_True;
1022       }
1023     }
1024
1025     if(pointfound) {
1026       aPrevPar = aCurPar;
1027       anotherSolutionFound = Standard_True;
1028
1029       if(BoundaryCondition && (isboundaryindex || !isvalidindex))
1030         break;
1031     }
1032     else {
1033       aDeltaRestrictor = aDelta;
1034     }
1035
1036     // if pointfound decide to increase aDelta using derivative of distance function
1037     //
1038
1039     aDelta = (pointfound) ? (aDelta * 2.) : (aDelta * 0.5);
1040     aDelta = (aDelta < aDeltaRestrictor) ? aDelta : aDeltaRestrictor;
1041     aCurPar = (ToIncreaseParameter) ? (aPrevPar + aDelta) : (aPrevPar - aDelta);
1042
1043     BoundaryCondition  = (ToIncreaseParameter) ? (aCurPar > aCurrentRange.Last()) : (aCurPar < aCurrentRange.First());
1044
1045     isboundaryindex = Standard_False;
1046     isvalidindex = Standard_True;
1047
1048     if(BoundaryCondition) {
1049       isboundaryindex = ((!ToIncreaseParameter && (aValidIndex == 1)) ||
1050                          (ToIncreaseParameter && (aValidIndex == myRangeManager.Length())));
1051
1052       if(!isboundaryindex) {
1053         if(pointfound) {
1054           Standard_Integer aFlag = (ToIncreaseParameter) ? myRangeManager.Flag(aValidIndex + 1) : myRangeManager.Flag(aValidIndex - 1);
1055           
1056           if(aFlag != 1 && aFlag != 4) {
1057             aValidIndex = (ToIncreaseParameter) ? (aValidIndex + 1) : (aValidIndex - 1);
1058             aCurrentRange = myRangeManager.Range(aValidIndex);
1059
1060             if((ToIncreaseParameter && (aCurPar > aCurrentRange.Last())) ||
1061                (!ToIncreaseParameter && (aCurPar < aCurrentRange.First()))) {
1062               aCurPar = (aCurrentRange.First() + aCurrentRange.Last()) * 0.5;
1063               aDelta*=0.5;
1064             }
1065           }
1066           else {
1067             isvalidindex = Standard_False;
1068             aCurPar = (ToIncreaseParameter) ? aCurrentRange.Last() : aCurrentRange.First();
1069           }
1070         }
1071       }
1072       else {
1073         aCurPar = (ToIncreaseParameter) ? aCurrentRange.Last() : aCurrentRange.First();
1074       }
1075
1076       if(aDelta < tenOfMinDelta) {
1077         loopcounter++;
1078       }
1079       else {
1080         loopcounter = 0;
1081       }
1082     } // end if(BoundaryCondition)
1083   }
1084
1085   if(anotherSolutionFound) {
1086     if(ToIncreaseParameter)
1087       myRangeManager.InsertRange(theParameter, aPrevPar, 4);
1088     else
1089       myRangeManager.InsertRange(aPrevPar, theParameter, 4);
1090   }
1091 }
1092
1093 // ---------------------------------------------------------------------------------
1094 // static function: LocalPrepareArgs
1095 // purpose: 
1096 // ---------------------------------------------------------------------------------
1097 static void LocalPrepareArgs(BRepAdaptor_Curve& theCurve,
1098                              const Standard_Real      theFirstParameter,
1099                              const Standard_Real      theLastParameter,
1100                              Standard_Real&           theDeflection,
1101                              IntTools_CArray1OfReal&  theArgs) {
1102   Standard_Integer aDiscretization = 30;
1103   Standard_Real aRelativeDeflection = 0.01;
1104   theDeflection = aRelativeDeflection;
1105   Standard_Boolean prepareargs = Standard_True;
1106   
1107   switch(theCurve.GetType()) {
1108   case GeomAbs_Line: {
1109     prepareargs = Standard_False;
1110     aDiscretization = 3;
1111     theArgs.Append(theFirstParameter);
1112
1113     if((theLastParameter - theFirstParameter) > Precision::PConfusion()) {
1114       theArgs.Append((theFirstParameter + theLastParameter)*0.5);
1115     }
1116     theArgs.Append(theLastParameter);
1117     theDeflection = Precision::Confusion();
1118     break;
1119   }
1120   case GeomAbs_Circle: {
1121     aDiscretization = 23;
1122     theDeflection = aRelativeDeflection * theCurve.Circle().Radius();
1123     break;
1124   }
1125   case GeomAbs_Ellipse: {
1126     aDiscretization = 40;
1127     theDeflection = 2 * aRelativeDeflection * theCurve.Ellipse().MajorRadius();
1128     break;
1129   }
1130   case GeomAbs_Hyperbola:
1131   case GeomAbs_Parabola: {
1132     aDiscretization = 40;
1133     theDeflection = aRelativeDeflection;
1134     break;
1135   }
1136   case GeomAbs_BezierCurve: {
1137     aDiscretization = 30;
1138     theDeflection = aRelativeDeflection;
1139     break;
1140   }
1141   case GeomAbs_BSplineCurve: {
1142     aDiscretization = 30;
1143     theDeflection = aRelativeDeflection;
1144     break;
1145   }
1146   default: {
1147     aDiscretization = 30;
1148     theDeflection = aRelativeDeflection;
1149   }
1150   }
1151
1152   if(prepareargs) {
1153     IntTools::PrepareArgs(theCurve, theLastParameter, theFirstParameter, aDiscretization, aRelativeDeflection, theArgs);
1154   }
1155 }
1156 // ---------------------------------------------------------------------------------
1157 // static function: SetEmptyResultRange
1158 // purpose:  
1159 // ---------------------------------------------------------------------------------
1160 static Standard_Boolean SetEmptyResultRange(const Standard_Real      theParameter, 
1161                                             IntTools_MarkedRangeSet& theMarkedRange) {
1162
1163   const TColStd_SequenceOfInteger& anIndices = theMarkedRange.GetIndices(theParameter);
1164   Standard_Boolean add = (anIndices.Length() > 0);
1165   
1166   for(Standard_Integer k = 1; k <= anIndices.Length(); k++) {
1167     if(theMarkedRange.Flag(anIndices(k)) == 4) {
1168       add = Standard_False;
1169       break;
1170     }
1171   }
1172   
1173   if(add) {
1174     theMarkedRange.InsertRange(theParameter, theParameter, 4);
1175   }
1176   
1177   return add;
1178 }
1179 //modified by NIZNHY-PKV Fri Oct 12 09:34:10 2012f
1180 static
1181  Standard_Integer DistPC(const Standard_Real aT1, 
1182                         const Handle(Geom_Curve)& aC1,
1183                         const Standard_Real aCriteria, 
1184                         GeomAPI_ProjectPointOnCurve& aProjector,
1185                         Standard_Real& aD, 
1186                         Standard_Real& aT2);
1187  
1188
1189 static
1190  Standard_Integer DistPC(const Standard_Real aT1, 
1191                         const Handle(Geom_Curve)& aC1,
1192                         const Standard_Real aCriteria,
1193                         GeomAPI_ProjectPointOnCurve& aProjector, 
1194                         Standard_Real& aD, 
1195                         Standard_Real& aT2,
1196                         Standard_Real& aDmax,
1197                         Standard_Real& aTmax);
1198
1199 static
1200   Standard_Integer FindMaxDistPC(const Standard_Real aT1A, 
1201                                  const Standard_Real aT1B,
1202                                  const Handle(Geom_Curve)& aC1,
1203                                  const Standard_Real aCriteria,
1204                                  const Standard_Real aEps1,
1205                                  GeomAPI_ProjectPointOnCurve& aProjector,
1206                                  Standard_Real& aDmax, 
1207                                  Standard_Real& aT1max);
1208
1209 //=======================================================================
1210 //function : CheckCoincidence
1211 //purpose  : 
1212 //=======================================================================
1213 Standard_Integer CheckCoincidence(const Standard_Real aT11, 
1214                                   const Standard_Real aT12,
1215                                   const Handle(Geom_Curve)& aC1,
1216                                   const Standard_Real aT21, 
1217                                   const Standard_Real aT22,
1218                                   const Handle(Geom_Curve)& aC2,
1219                                   const Standard_Real aCriteria,
1220                                   const Standard_Real aEps1,
1221                                   GeomAPI_ProjectPointOnCurve& aProjector)
1222 {
1223   Standard_Integer iErr, aNb1, i, aNbX;
1224   Standard_Real dT1, aT1, aT2, aD, aDmax, aTmax;
1225   Standard_Real aT1A, aT1B, aD1max,aT1max;
1226   //
1227   iErr=0; // the patches are coincided
1228   //
1229   //
1230   aProjector.Init(aC2, aT21, aT22);
1231   //
1232   aDmax=-1.;
1233   //
1234   // 1. Express evaluation
1235   //
1236   aNb1=10; // Number of intervals on the curve #1
1237   dT1=(aT12-aT11)/aNb1;
1238   for (i=1; i<aNb1; ++i) {
1239     aT1=aT11+i*dT1;
1240     //
1241     iErr=DistPC(aT1, aC1, aCriteria, aProjector, aD, aT2, aDmax, aTmax);
1242     if (iErr) {
1243       iErr=1;// a point from aC1 can not be projected on aC2
1244       return iErr;
1245     }
1246     //
1247     if (aDmax>aCriteria) {
1248       iErr=2; // the distance is too big
1249       return iErr;
1250     }
1251   }
1252   //
1253   // 2. Deep evaluation
1254   aD1max=aDmax;
1255   //
1256   aNbX=aNb1-1;
1257   for (i=1; i<aNbX; ++i) {
1258     aT1A=aT11+i*dT1; 
1259     aT1B=aT1A+dT1;
1260     //
1261     iErr=FindMaxDistPC(aT1A, aT1B, aC1, aCriteria, aEps1, aProjector, aD1max, aT1max);
1262     if (iErr) {
1263       iErr=1;
1264       return iErr;
1265     }
1266   }
1267   //
1268   return iErr;
1269 }
1270 //
1271 //=======================================================================
1272 //function : FindMaxDistPC
1273 //purpose  : 
1274 //=======================================================================
1275 Standard_Integer FindMaxDistPC(const Standard_Real aT1A, 
1276                                const Standard_Real aT1B,
1277                                const Handle(Geom_Curve)& aC1,
1278                                const Standard_Real aCriteria,
1279                                const Standard_Real aEps1,
1280                                GeomAPI_ProjectPointOnCurve& aProjector,
1281                                Standard_Real& aDmax, 
1282                                Standard_Real& aT1max) 
1283 {
1284   Standard_Integer iErr, iCnt;
1285   Standard_Real aGS, aXP, aA, aB, aXL, aYP, aYL, aT2P, aT2L, aX0;
1286   //
1287   iCnt=0;
1288   iErr=0;
1289   aDmax=0.;
1290   //
1291   aGS=0.6180339887498948482045868343656;// =0.5*(1.+sqrt(5.))-1.;
1292   aA=aT1A;
1293   aB=aT1B;
1294   //
1295   aXP=aA+(aB-aA)*aGS;
1296   aXL=aB-(aB-aA)*aGS;
1297   //
1298   iErr=DistPC(aXP, aC1, aCriteria, aProjector, aYP, aT2P, aDmax, aT1max);
1299   if(iErr){
1300     return iErr;
1301   }
1302   //
1303   iErr=DistPC(aXL, aC1, aCriteria, aProjector, aYL, aT2L, aDmax, aT1max);
1304   if(iErr){
1305     return iErr;
1306   }
1307   //
1308   for(;;) {
1309     if (aYP>aYL) {
1310       aA=aXL;
1311       aXL=aXP;
1312       aYL=aYP;
1313       aXP=aA+(aB-aA)*aGS;
1314       iErr=DistPC(aXP, aC1, aCriteria, aProjector, aYP, aT2P, aDmax, aT1max);
1315       if(iErr){
1316         return iErr;
1317       }
1318     }
1319     else {
1320       aB=aXP;
1321       aXP=aXL;
1322       aYP=aYL;
1323       aXL=aB-(aB-aA)*aGS;
1324       iErr=DistPC(aXL, aC1, aCriteria, aProjector, aYL, aT2L, aDmax, aT1max);
1325       if(iErr){
1326         return iErr;
1327       }
1328     }
1329     //
1330     if ((aB-aA)<aEps1) {
1331       aX0=0.5*(aA+aB);
1332       break;
1333     }
1334   }// while(1) {
1335   //
1336   return iErr;
1337 }
1338 //=======================================================================
1339 //function : DistPC
1340 //purpose  : 
1341 //=======================================================================
1342 Standard_Integer DistPC(const Standard_Real aT1, 
1343                         const Handle(Geom_Curve)& aC1,
1344                         const Standard_Real aCriteria,
1345                         GeomAPI_ProjectPointOnCurve& aProjector, 
1346                         Standard_Real& aD, 
1347                         Standard_Real& aT2,
1348                         Standard_Real& aDmax,
1349                         Standard_Real& aTmax)
1350 {
1351   Standard_Integer iErr;
1352   //
1353   iErr=DistPC(aT1, aC1, aCriteria, aProjector, aD, aT2);
1354   if (iErr) {
1355     return iErr;
1356   }
1357   //
1358   if (aD>aDmax) {
1359     aDmax=aD;
1360     aTmax=aT2;
1361   }
1362   //
1363   return iErr;
1364 }
1365 //=======================================================================
1366 //function : DistPC
1367 //purpose  : 
1368 //=======================================================================
1369 Standard_Integer DistPC(const Standard_Real aT1, 
1370                         const Handle(Geom_Curve)& aC1,
1371                         const Standard_Real aCriteria, 
1372                         GeomAPI_ProjectPointOnCurve& aProjector,
1373                         Standard_Real& aD, 
1374                         Standard_Real& aT2) 
1375 {
1376   Standard_Integer iErr, aNbP2;
1377   gp_Pnt aP1;
1378   //
1379   iErr=0;
1380   aC1->D0(aT1, aP1);
1381   //
1382   aProjector.Perform(aP1);
1383   aNbP2=aProjector.NbPoints();
1384   if (!aNbP2) {
1385     iErr=1;// the point from aC1 can not be projected on aC2
1386     return iErr;
1387   }
1388   //
1389   aD=aProjector.LowerDistance();
1390   aT2=aProjector.LowerDistanceParameter();
1391   if (aD>aCriteria) {
1392     iErr=2;// the distance is too big
1393   }
1394   //
1395   return iErr;
1396 }
1397 //modified by NIZNHY-PKV Fri Oct 12 09:34:12 2012t