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