0024516: Copyright information has been corrupted within some headers
[occt.git] / src / IntTools / IntTools_EdgeEdge_1.cxx
1 // Created on: 2012-11-29
2 // Created by: Peter KURNEV
3 // Copyright (c) 2012-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and / or modify it
8 // under the terms of the GNU Lesser General Public version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <IntTools_EdgeEdge.ixx>
17
18 #include <gp_Elips.hxx>
19 #include <gp_Ax1.hxx>
20 #include <gp_Dir.hxx>
21 #include <gp_XYZ.hxx>
22 #include <gp_Ax2.hxx>
23 #include <gp_Pnt.hxx>
24 //
25 #include <Geom_Curve.hxx>
26 #include <Geom_Line.hxx>
27 #include <Geom_Circle.hxx>
28 #include <Geom_Ellipse.hxx>
29 #include <Geom_Parabola.hxx>
30 #include <Geom_Hyperbola.hxx>
31 #include <Geom_BezierCurve.hxx>
32 #include <Geom_BSplineCurve.hxx>
33 #include <Geom_TrimmedCurve.hxx>
34 #include <Geom_OffsetCurve.hxx>
35 //
36 #include <GeomAPI_ProjectPointOnCurve.hxx>
37 //
38 #include <BRep_Tool.hxx>
39
40
41 //=======================================================================
42 //class    : IntTools_ComparatorCurve
43 //purpose  : 
44 //=======================================================================
45 class IntTools_ComparatorCurve {
46  public: 
47   IntTools_ComparatorCurve() {
48     myT11=0.;
49     myT12=0.;
50     myT21=0.;
51     myT22=0.;
52     myIsSame=Standard_False;
53   };
54   //
55   virtual ~IntTools_ComparatorCurve(){
56   }; 
57   //
58   void SetCurve1(const BRepAdaptor_Curve& aBC3D) {
59     myBC1=aBC3D;
60   };
61   //
62   const BRepAdaptor_Curve& Curve1()const {
63     return myBC1;
64   };
65   //
66   void SetRange1(const Standard_Real aT1,
67                  const Standard_Real aT2) {
68     myT11=aT1;
69     myT12=aT2;
70   };
71   //
72   void Range1(Standard_Real& aT1, Standard_Real& aT2)const {
73     aT1=myT11;
74     aT2=myT12;
75   };
76   //
77   void SetCurve2(const BRepAdaptor_Curve& aBC3D){
78     myBC2=aBC3D;
79   };
80   //
81   const BRepAdaptor_Curve& Curve2()const{
82     return myBC2;
83   };
84   //
85   void SetRange2(const Standard_Real aT1,
86                  const Standard_Real aT2){
87     myT21=aT1;
88     myT22=aT2;
89   };
90   //
91   void Range2(Standard_Real& aT1, 
92               Standard_Real& aT2)const {
93     aT1=myT21;
94     aT2=myT22;
95   };
96   //
97   Standard_Boolean IsSame()const {
98     return myIsSame;
99   }; 
100   //
101   void Perform();
102   //
103   //--------------------------------------
104  protected:
105   //
106   void IsSameElipse();
107   //
108   void IsSameBSplineCurve();
109   //
110   static 
111     Standard_Boolean 
112       IsSameReal(const Standard_Real aR1, 
113                  const Standard_Real aR2);
114   //
115   static
116     Standard_Boolean 
117       IsSameAx2(const gp_Ax2& aAx21, 
118                 const gp_Ax2& aAx22);
119   //
120   static
121     Standard_Boolean
122       IsSameAx1(const gp_Ax1& aAx1, 
123                 const gp_Ax1& aAx2);
124   //
125   static
126     Standard_Boolean 
127       IsSamePnt(const gp_Pnt& aP1, 
128                 const gp_Pnt& aP2);
129   static
130     Standard_Boolean 
131       IsSameDir(const gp_Dir& aDir1, 
132                 const gp_Dir& aDir2);
133   //
134   static
135     Standard_Boolean 
136       IsSameXYZ(const gp_XYZ& aXYZ1, 
137                 const gp_XYZ& aXYZ2);
138   //
139   static
140     void GetCurveBase(const Handle(Geom_Curve)& aC3D,
141                       GeomAbs_CurveType& aTypeBase,
142                       Handle(Geom_Curve)& aCurveBase);
143   //
144   static
145     Standard_Boolean 
146       IsTypeBase(const Handle(Geom_Curve)& aC,
147                  GeomAbs_CurveType& aTypeB);
148   //
149  protected:
150   BRepAdaptor_Curve myBC1;
151   Standard_Real myT11;
152   Standard_Real myT12;
153   //
154   BRepAdaptor_Curve myBC2;
155   Standard_Real myT21;
156   Standard_Real myT22;
157   //
158   Standard_Boolean myIsSame;
159 };
160 //
161 //=======================================================================
162 //function : Perform
163 //purpose  : 
164 //=======================================================================
165 void IntTools_ComparatorCurve::Perform()
166 {
167   GeomAbs_CurveType aCurveType1, aCurveType2;
168   //
169   myIsSame=Standard_False;
170   //
171   aCurveType1=myBC1.GetType();
172   aCurveType2=myBC2.GetType();
173   //
174   myIsSame=(aCurveType1==aCurveType2);
175   if (!myIsSame) {
176     return; 
177   }
178   // 
179   myIsSame=IsSameReal(myT11, myT21);
180   if (!myIsSame) {
181     return;
182   }
183   //
184   myIsSame=IsSameReal(myT12, myT22);
185   if (!myIsSame) {
186     return;
187   }
188   //
189   if (aCurveType1==GeomAbs_Ellipse) {
190     IsSameElipse();
191     return;
192   } 
193   else if (aCurveType1==GeomAbs_BSplineCurve) {
194     IsSameBSplineCurve();
195     return ;
196   }
197   else {
198     myIsSame=Standard_False;
199     return;
200   }
201 }
202 //=======================================================================
203 //function : IsSameBSplineCurve
204 //purpose  : 
205 //=======================================================================
206 void IntTools_ComparatorCurve::IsSameBSplineCurve()
207 {
208   Standard_Boolean bIsRational, bIsPreiodic;
209   Standard_Integer iNbPoles, iNbKnots, iDegree;
210   //
211   bIsRational=myBC1.IsRational();
212   myIsSame=(bIsRational==myBC2.IsRational());
213   if (!myIsSame) {
214     return;
215   }
216   //
217   iNbPoles=myBC1.NbPoles();
218   myIsSame=(iNbPoles==myBC2.NbPoles());
219   if (!myIsSame) {
220     return;
221   }
222   //
223   iNbKnots=myBC1.NbKnots();
224   myIsSame=(iNbKnots==myBC2.NbKnots());
225   if (!myIsSame) {
226     return;
227   }
228   //
229   iDegree=myBC1.Degree();
230   myIsSame=(iDegree==myBC2.Degree());
231   if (!myIsSame) {
232     return;
233   } 
234   //
235   bIsPreiodic=myBC1.IsPeriodic();
236   myIsSame=(bIsPreiodic==myBC2.IsPeriodic());
237   if (!myIsSame) {
238     return;
239   }
240  
241   //-------------------------------------------
242   Standard_Integer i, j, aM[2];
243   Standard_Real aT1, aT2, aX0[4], aX1[4];
244   GeomAbs_CurveType aTypeBase;
245   gp_Pnt aP;
246   Handle(Geom_Curve) aC;
247   Handle(Geom_BSplineCurve) aBSp[2];
248   TopoDS_Edge aE1, aE2;
249   //
250   aE1=myBC1.Edge();
251   aE2=myBC2.Edge();
252   //
253   aC=BRep_Tool::Curve (aE1, aT1, aT2);
254   GetCurveBase(aC, aTypeBase, aBSp[0]);
255   //
256   aC=BRep_Tool::Curve (aE2, aT1, aT2);
257   GetCurveBase(aC, aTypeBase, aBSp[1]);
258   //
259   // Poles / Weights
260   for(i=1; i<=iNbPoles; ++i) {
261     aP=aBSp[0]->Pole(i);
262     aP.Coord(aX0[0], aX0[1], aX0[2]);
263     aX0[3]=aBSp[0]->Weight(i);
264     //
265     aP=aBSp[1]->Pole(i);
266     aP.Coord(aX1[0], aX1[1], aX1[2]);
267     aX1[3]=aBSp[1]->Weight(i);
268     //
269     for (j=0; j<4; ++j) {
270       myIsSame=IsSameReal(aX0[j], aX1[j]);
271       if(!myIsSame) {
272         return;
273       }
274     }
275   }//for(i=1; i<iNbPoles; ++i) {
276   //
277   // Knots / Multiplicities
278   for(i=1; i<=iNbKnots; ++i) {
279     aX0[0]=aBSp[0]->Knot(i);
280     aX0[1]=aBSp[1]->Knot(i);
281     myIsSame=IsSameReal(aX0[0], aX0[1]);
282     if(!myIsSame) {
283       return;
284     }
285     //
286     aM[0]=aBSp[0]->Multiplicity(i);
287     aM[1]=aBSp[1]->Multiplicity(i);
288     myIsSame=(aM[0]==aM[1]);
289     if(!myIsSame) {
290       return;
291     }
292   }
293 }
294 //=======================================================================
295 //function : GetCurveBase
296 //purpose  : 
297 //=======================================================================
298 void IntTools_ComparatorCurve::GetCurveBase(const Handle(Geom_Curve)& aC3D,
299                                             GeomAbs_CurveType& aTypeBase,
300                                             Handle(Geom_Curve)& aCurveBase)
301 {
302   Standard_Boolean bIsTypeBase;
303   Standard_Integer  iTrimmed, iOffset;
304   Standard_Real aOffsetBase;
305   GeomAbs_CurveType aTypeB;
306   Handle(Geom_Curve) aC3DB;
307   Handle(Geom_TrimmedCurve) aCT3D;
308   Handle(Geom_OffsetCurve) aCF3D;
309   //
310   aTypeBase=GeomAbs_OtherCurve;
311   aOffsetBase=0.;
312   //
313   aC3DB=aC3D;
314   bIsTypeBase=IsTypeBase(aC3DB, aTypeB);
315   if (bIsTypeBase) {
316     aTypeBase=aTypeB;
317     aCurveBase=aC3D;
318     return;
319   }
320   //
321   for(;;) {
322     iTrimmed=0;
323     iOffset=0;
324     aCT3D=Handle(Geom_TrimmedCurve)::DownCast(aC3DB);
325     if (!aCT3D.IsNull()) {
326       aC3DB=aCT3D->BasisCurve();
327       ++iTrimmed;
328     }
329     //
330     aCF3D=Handle(Geom_OffsetCurve)::DownCast(aC3DB);
331     if (!aCF3D.IsNull()) {
332       Standard_Real aOffset;
333       //
334       aOffset=aCF3D->Offset();
335       aOffsetBase=aOffsetBase+aOffset;
336       //
337       aC3DB=aCF3D->BasisCurve();
338       ++iOffset;
339     }
340     //
341     if (!(iTrimmed || iOffset)) {
342       break;
343     }
344     //
345     bIsTypeBase=IsTypeBase(aC3DB, aTypeB);
346     if (bIsTypeBase) {
347       aTypeBase=aTypeB;
348       aCurveBase=aC3DB;
349       return;
350     }
351   }
352 }
353 //=======================================================================
354 //function : IsTypeBase
355 //purpose  : 
356 //=======================================================================
357 Standard_Boolean 
358   IntTools_ComparatorCurve::IsTypeBase(const Handle(Geom_Curve)& aC,
359                                        GeomAbs_CurveType& aTypeB)
360 {
361   Standard_Boolean bRet; 
362   Handle(Standard_Type) aType;
363   //
364   bRet=Standard_True;
365   //
366   aType=aC->DynamicType();
367   if (aType==STANDARD_TYPE(Geom_Line)) {
368     aTypeB=GeomAbs_Line;
369   }
370   else if (aType==STANDARD_TYPE(Geom_Circle)) {
371     aTypeB=GeomAbs_Circle;
372   }
373   else if (aType==STANDARD_TYPE(Geom_Ellipse)) {
374     aTypeB=GeomAbs_Ellipse;
375   }
376   else if (aType==STANDARD_TYPE(Geom_Parabola)) {
377     aTypeB=GeomAbs_Parabola;
378   }
379   else if (aType==STANDARD_TYPE(Geom_Hyperbola)) {
380     aTypeB=GeomAbs_Hyperbola;
381   }
382   else if (aType==STANDARD_TYPE(Geom_BezierCurve)) {
383     aTypeB=GeomAbs_BezierCurve;
384   }
385   else if (aType==STANDARD_TYPE(Geom_BSplineCurve)) {
386     aTypeB=GeomAbs_BSplineCurve;
387   }
388   else {
389     aTypeB=GeomAbs_OtherCurve;
390     bRet=!bRet;
391   }
392   return bRet;
393 }
394 //=======================================================================
395 //function : IsSameElipse
396 //purpose  : 
397 //=======================================================================
398 void IntTools_ComparatorCurve::IsSameElipse()
399 {
400   Standard_Real aR1, aR2;
401   gp_Elips aElips1, aElips2;
402   // 
403   myIsSame=Standard_False;
404   //
405   aElips1=myBC1.Ellipse();
406   aElips2=myBC2.Ellipse();
407   //
408   aR1=aElips1.MajorRadius();
409   aR2=aElips2.MajorRadius();
410   myIsSame=IsSameReal(aR1, aR2);
411   if (!myIsSame) {
412     return;
413   }
414   //
415   aR1=aElips1.MinorRadius();
416   aR2=aElips2.MinorRadius();
417   myIsSame=IsSameReal(aR1, aR2);
418   if (!myIsSame) {
419     return;
420   }
421   //
422   const gp_Ax2& aAx21=aElips1.Position();
423   const gp_Ax2& aAx22=aElips2.Position();
424   myIsSame=IsSameAx2(aAx21, aAx22);
425 }
426 //=======================================================================
427 //function : IsSameAx2
428 //purpose  : 
429 //=======================================================================
430 Standard_Boolean 
431   IntTools_ComparatorCurve::IsSameAx2(const gp_Ax2& aAx21, 
432                                       const gp_Ax2& aAx22)
433 {
434   Standard_Boolean bRet;
435   //
436   const gp_Ax1& aAx1=aAx21.Axis();
437   const gp_Ax1& aAx2=aAx22.Axis();
438   //
439   bRet=IsSameAx1(aAx1, aAx2);
440   if (!bRet) {
441     return bRet;
442   }
443   //
444   const gp_Dir& aDirX1=aAx21.XDirection();
445   const gp_Dir& aDirX2=aAx22.XDirection();
446   //
447   bRet=IsSameDir(aDirX1, aDirX2);
448   if (!bRet) {
449     return bRet;
450   }
451   //
452   //
453   const gp_Dir& aDirY1=aAx21.YDirection();
454   const gp_Dir& aDirY2=aAx22.YDirection();
455   //
456   bRet=IsSameDir(aDirY1, aDirY2);
457   //
458   return bRet;
459 }
460 //=======================================================================
461 //function : IsSamePnt
462 //purpose  : 
463 //=======================================================================
464 Standard_Boolean 
465   IntTools_ComparatorCurve::IsSamePnt(const gp_Pnt& aP1, 
466                                       const gp_Pnt& aP2)
467 {
468   const gp_XYZ& aXYZ1=aP1.XYZ();
469   const gp_XYZ& aXYZ2=aP2.XYZ();
470   return IsSameXYZ(aXYZ1, aXYZ2);
471 }
472 //=======================================================================
473 //function : IsSameAx1
474 //purpose  : 
475 //=======================================================================
476 Standard_Boolean 
477   IntTools_ComparatorCurve::IsSameAx1(const gp_Ax1& aAx1, 
478                                       const gp_Ax1& aAx2)
479 {
480   Standard_Boolean bRet;
481   //
482   const gp_Pnt& aP1=aAx1.Location();
483   const gp_Pnt& aP2=aAx2.Location();
484   //
485   bRet=IsSamePnt(aP1, aP2);
486   if (!bRet) {
487     return bRet;
488   }
489   //
490   const gp_Dir& aDir1=aAx1.Direction();
491   const gp_Dir& aDir2=aAx2.Direction();
492   //
493   bRet=IsSameDir(aDir1, aDir2);
494   return bRet;
495 }
496 //=======================================================================
497 //function : IsSameDir
498 //purpose  : 
499 //=======================================================================
500 Standard_Boolean 
501   IntTools_ComparatorCurve::IsSameDir(const gp_Dir& aDir1, 
502                                       const gp_Dir& aDir2)
503 {
504   const gp_XYZ& aXYZ1=aDir1.XYZ();
505   const gp_XYZ& aXYZ2=aDir2.XYZ();
506   return IsSameXYZ(aXYZ1, aXYZ2);
507 }
508 //=======================================================================
509 //function : IsSameXYZ
510 //purpose  : 
511 //=======================================================================
512 Standard_Boolean 
513   IntTools_ComparatorCurve::IsSameXYZ(const gp_XYZ& aXYZ1, 
514                                       const gp_XYZ& aXYZ2)
515 {
516   Standard_Boolean bRet = Standard_False;
517   Standard_Integer i;
518   Standard_Real aX1[3], aX2[3];
519   
520   aXYZ1.Coord(aX1[0], aX1[1], aX1[2]);
521   aXYZ2.Coord(aX2[0], aX2[1], aX2[2]);
522   //
523   for (i=0; i<3; ++i) {
524     bRet=IsSameReal(aX1[i], aX2[i]);
525     if(!bRet) {
526       break;
527     }
528   }
529   return bRet;
530 }
531 //=======================================================================
532 //function : IsSameReal
533 //purpose  : 
534 //=======================================================================
535 Standard_Boolean 
536   IntTools_ComparatorCurve::IsSameReal(const Standard_Real aR1, 
537                                        const Standard_Real aR2)
538 {
539   Standard_Boolean bRet;
540   Standard_Real aEpsilon;
541   //
542   aEpsilon=Epsilon(aR1);
543   bRet=(fabs(aR1-aR2)<aEpsilon);
544   return bRet;
545 }
546 //
547 //modified by NIZNHY-PKV Tue Jan 15 07:44:33 2013f
548 //=======================================================================
549 // class: IntTools_DistCC
550 // purpose  : 
551 //=======================================================================
552 class IntTools_DistCC {
553  public:
554   IntTools_DistCC() {
555     myT11=0.;
556     myT12=0.;
557     myT21=0.;
558     myT22=0.;
559     myErrorStatus=1;
560     myThreshold=1.e-7;
561     myDx=0.;
562     myTx=0.;
563     myNbP=10;
564     myIndent=0.3;
565     myEps=0.001;
566   };
567   //
568   ~IntTools_DistCC() {
569   };
570   //-------- 1
571   void SetCurve1(const Handle(Geom_Curve)& aC1) {
572     myC1=aC1;
573   };
574   //
575   const Handle(Geom_Curve)& Curve1()const {
576     return myC1;
577   };
578   //
579   void SetRange1(const Standard_Real aT11,
580                  const Standard_Real aT12) {
581     myT11=aT11;
582     myT12=aT12;
583   };
584   //
585   void Range1(Standard_Real& aT11,
586               Standard_Real& aT12)const {
587     aT11=myT11;
588     aT12=myT12;
589   };
590   //-------- 2
591   void SetCurve2(const Handle(Geom_Curve)& aC2) {
592     myC2=aC2;
593   };
594   //
595   const Handle(Geom_Curve)& Curve2()const {
596     return myC2;
597   };
598   //
599   void SetRange2(const Standard_Real aT21,
600                  const Standard_Real aT22) {
601     myT21=aT21;
602     myT22=aT22;
603   };
604   //
605   void Range2(Standard_Real& aT21,
606               Standard_Real& aT22)const {
607     aT21=myT21;
608     aT22=myT22;
609   };
610   //
611   void SetThreshold(const Standard_Real aD) {
612     myThreshold=aD;
613   }
614   //
615   Standard_Real Threshold() const {
616     return myThreshold;
617   }
618   //
619   void Perform();
620   //
621   Standard_Integer ErrorStatus()const {
622     return myErrorStatus;
623   };
624   //
625   Standard_Real MaxDeviation()const {
626     return myDx;
627   }
628   //
629   Standard_Real MaxParameter()const {
630     return myTx;
631   }
632  //-----------------------------------------------------
633  protected :  
634   //
635   void Init();
636   //
637   void CheckData();
638   //
639   Standard_Real Distance(const Standard_Real aT); 
640   //
641   void FindMaxDeviation();
642   //
643   void FindMaxLocal (const Standard_Real aT11,
644                      const Standard_Real aT12,
645                      const Standard_Real aEps,
646                      Standard_Real& aDx,
647                      Standard_Real& aTx);
648   
649   //
650  protected :
651   Standard_Real myT11;
652   Standard_Real myT12;
653   Handle(Geom_Curve) myC1;
654   
655   Standard_Real myT21;
656   Standard_Real myT22;
657   Handle(Geom_Curve) myC2;
658   //
659   Standard_Real myThreshold;
660   Standard_Integer myErrorStatus;
661   //
662   Standard_Real myDx;
663   Standard_Real myTx;
664   //
665   Standard_Integer myNbP;
666   Standard_Real myIndent;
667   Standard_Real myEps;
668   GeomAPI_ProjectPointOnCurve myPPC2; 
669 };
670
671 //=======================================================================
672 //function : Perform
673 //purpose  : 
674 //=======================================================================
675 void IntTools_DistCC::Perform()
676 {
677   myErrorStatus=0;
678   //
679   CheckData();
680   if (myErrorStatus){
681     return;
682   }
683   // Init
684   myPPC2.Init(myC2, myT21, myT22);
685   //
686   FindMaxDeviation();
687   if (myErrorStatus){
688     return;
689   }
690 }
691 //=======================================================================
692 //function : CheckData
693 //purpose  : 
694 //=======================================================================
695 void IntTools_DistCC::CheckData()
696 {
697   myErrorStatus=0;
698   //
699   if (myC1.IsNull()) {
700     myErrorStatus=2;
701     return;
702   }
703   //
704   if (myC2.IsNull()) {
705     myErrorStatus=3;
706     return;
707   }
708 }
709 //
710 //=======================================================================
711 //function : FindMaxDeviation
712 //purpose  : 
713 //=======================================================================
714 void IntTools_DistCC::FindMaxDeviation()
715
716   Standard_Integer i, aNbP1, aNbP2;
717   Standard_Real aTmax, aT, aT1, aT2, dT, aDmax, aEps, aD;
718   //
719   myErrorStatus=0;
720   myDx=0.;
721   myTx=0.;
722   //
723   aTmax=0;
724   aDmax=0.;
725   aEps=myEps*(myT12-myT11);
726   //
727   aNbP1=myNbP-1;
728   aNbP2=aNbP1-1;
729   dT=(myT12-myT11)/aNbP1;
730   for (i=0; i<aNbP1; ++i) {
731     aT1=myT11+i*dT;
732     aT2=aT1+dT;
733     //
734     if (!i) {
735       aT1=aT1+myIndent*dT;
736     }
737     else if (i==aNbP2) {
738       aT2=aT2-myIndent*dT;
739       if (aT2>myT12) {
740         aT2=myT12;
741       }
742     }
743     //
744     FindMaxLocal(aT1, aT2, aEps, aD, aT);
745     if (myErrorStatus) {
746       return ;
747     }
748     //
749     if (aD>aDmax) {
750       aDmax=aD;
751       aTmax=aT;
752     }
753   }
754   //
755   myTx=aTmax;
756   myDx=aDmax;
757 }
758 //=======================================================================
759 //function : FindMaxLocal
760 //purpose  : Solver: Golden Mean
761 //=======================================================================
762 void IntTools_DistCC::FindMaxLocal(const Standard_Real aT11,
763                                    const Standard_Real aT12,
764                                    const Standard_Real aEps,
765                                    Standard_Real& aDx,
766                                    Standard_Real& aTx)
767 {
768   Standard_Integer iErr;
769   Standard_Real aA, aB, aCf, aX1, aX2, aF1, aF2, aX, aF;
770   //
771   myErrorStatus=0;
772   iErr=0;
773   aDx=0.;
774   aTx=0.;
775   //
776   aCf=1.6180339887498948482045868343656;// =0.5*(1.+sqrt(5.));
777   //
778   aA=aT11;
779   aB=aT12;
780   //
781   aX1=aB-(aB-aA)/aCf;
782   aF1=Distance(aX1);
783   if (myErrorStatus) {
784     return ;
785   }
786   //
787   aX2=aA+(aB-aA)/aCf;
788   aF2=Distance(aX2);
789   if (myErrorStatus) {
790     return;
791   }
792   //
793   for(;;) {
794     if (fabs(aA-aB)<aEps) {
795       aX=0.5*(aA+aB);
796       aF=Distance(aX);
797       if (myErrorStatus) {
798         return;
799       }
800       //
801       break;
802     }
803     if (aF1<aF2){
804       aA=aX1;
805       aX1=aX2;
806       aF1=aF2;
807       aX2=aA+(aB-aA)/aCf;
808       aF2=Distance(aX2);
809       if (myErrorStatus) {
810         return ;
811       }
812     }
813     else {
814       aB=aX2;
815       aX2=aX1;
816       aF2=aF1;
817       aX1=aB-(aB-aA)/aCf;
818       aF1=Distance(aX1);
819       if (myErrorStatus) {
820         return;
821       }
822     }
823   }
824   //
825   aDx=aF;
826   aTx=aX;
827 }
828 //=======================================================================
829 //function : Distance
830 //purpose  : 
831 //=======================================================================
832 Standard_Real IntTools_DistCC::Distance(const Standard_Real aT)
833 {
834   Standard_Integer aNbP2;
835   Standard_Real aD;
836   gp_Pnt aP1;
837   //
838   aD=0.;
839   if (myErrorStatus) {
840     return aD;
841   }
842   //
843   myC1->D0(aT, aP1);
844   myPPC2.Perform(aP1);
845   //
846   aNbP2=myPPC2.NbPoints();
847   if (!aNbP2) {
848     myErrorStatus=4;
849     return aD;
850   }
851   //
852   aD=myPPC2.LowerDistance();
853   if (aD>myThreshold) {
854     myErrorStatus=10;
855   }
856   return aD;
857 }
858 //modified by NIZNHY-PKV Tue Jan 15 07:44:44 2013t
859 //
860 //=======================================================================
861 //function : IsSameCurves
862 //purpose  : 
863 //=======================================================================
864 Standard_Boolean IntTools_EdgeEdge::IsSameCurves()
865 {
866   Standard_Boolean bRet, bIsBC;
867   GeomAbs_CurveType aCT1, aCT2;
868   IntTools_ComparatorCurve aICC;
869   //
870   // 1. Check letter
871   aICC.SetCurve1(myCFrom);
872   aICC.SetRange1(myTminFrom, myTmaxFrom);
873   //
874   aICC.SetCurve2(myCTo);
875   aICC.SetRange2(myTminTo, myTmaxTo);
876   //
877   aICC.Perform();
878   bRet=aICC.IsSame();
879   if (bRet) {
880     return bRet;
881   }
882   //
883   // 2. Check inwards
884   aCT1=myCFrom.GetType();
885   aCT2=myCTo.GetType();
886   bIsBC=(aCT1==GeomAbs_BSplineCurve || 
887          aCT1==GeomAbs_BezierCurve  ||
888          aCT2==GeomAbs_BSplineCurve ||
889          aCT2==GeomAbs_BezierCurve);
890   //
891   if (bIsBC) {
892     Standard_Integer iErr;
893     Standard_Real aT11, aT12, aT21, aT22;
894     Handle(Geom_Curve) aC1, aC2;
895     IntTools_DistCC aDistCC; 
896     //
897     const TopoDS_Edge& aE1=myCFrom.Edge();
898     aC1=BRep_Tool::Curve(aE1, aT11, aT12);
899     //
900     const TopoDS_Edge& aE2=myCTo.Edge();
901     aC2=BRep_Tool::Curve(aE2, aT21, aT22);
902     //
903     aDistCC.SetCurve1(aC1);
904     aDistCC.SetRange1(myTminFrom, myTmaxFrom);
905     aDistCC.SetCurve2(aC2);
906     aDistCC.SetRange2(myTminTo, myTmaxTo);
907     aDistCC.SetThreshold(myCriteria);
908     //
909     aDistCC.Perform();
910     //
911     iErr=aDistCC.ErrorStatus();
912     //
913     bRet=(!iErr); 
914     //
915   }
916   return bRet;
917 }
918