1de8f4436a6a3adc517730090ee203cc75eb4af8
[occt.git] / src / IntTools / IntTools_EdgeEdge.cxx
1 // Created on: 2000-10-26
2 // Created by: Peter KURNEV
3 // Copyright (c) 2000-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 <Precision.hxx>
19
20 #include <TColStd_SequenceOfReal.hxx>
21
22 #include <gp_Circ.hxx>
23 #include <gp_Ax1.hxx>
24 #include <gp_Lin.hxx>
25 #include <gp_Dir.hxx>
26 #include <gp_Pnt.hxx>
27
28 #include <ElCLib.hxx>
29 #include <Geom_Curve.hxx>
30
31 #include <Geom_BSplineCurve.hxx>
32 #include <GeomAdaptor_Curve.hxx>
33
34 #include <CPnts_AbscissaPoint.hxx>
35
36 #include <GeomAPI_ProjectPointOnCurve.hxx>
37
38 #include <Extrema_ExtElC.hxx>
39 #include <Extrema_POnCurv.hxx>
40 #include <Extrema_ExtCC.hxx>
41
42 #include <TopoDS_Iterator.hxx>
43 #include <BRep_Tool.hxx>
44
45 #include <IntTools.hxx>
46 #include <IntTools_Range.hxx>
47 #include <IntTools_CArray1OfReal.hxx>
48 #include <IntTools_CommonPrt.hxx>
49 #include <IntTools_SequenceOfRanges.hxx>
50 #include <IntTools_Tools.hxx>
51 #include <IntTools_BeanBeanIntersector.hxx>
52
53
54 //=======================================================================
55 //function : IntTools_EdgeEdge::IntTools_EdgeEdge
56 //purpose  : 
57 //=======================================================================
58 IntTools_EdgeEdge::IntTools_EdgeEdge()
59 {
60   myTol1=1.e-7;
61   myTol2=1.e-7;
62   myDiscret=30;
63   myEpsT=1e-12;
64   myEpsNull=1e-12;
65   myDeflection=0.01;
66   myIsDone=Standard_False;
67   myErrorStatus=1;
68   myOrder=Standard_False;
69
70   myPar1=0.;
71   myParallel=Standard_False;
72 }
73
74 //=======================================================================
75 //function : SetEdge1
76 //purpose  : 
77 //=======================================================================
78   void IntTools_EdgeEdge::SetEdge1(const TopoDS_Edge& anEdge)
79 {
80   myEdge1=anEdge;
81 }
82 //=======================================================================
83 //function : SetEdge2
84 //purpose  : 
85 //=======================================================================
86   void IntTools_EdgeEdge::SetEdge2(const TopoDS_Edge& anEdge)
87 {
88   myEdge2=anEdge;
89 }
90
91 //=======================================================================
92 //function : SetTolerance1
93 //purpose  : 
94 //=======================================================================
95   void IntTools_EdgeEdge::SetTolerance1(const Standard_Real aTol) 
96 {
97   myTol1=aTol;
98
99 //=======================================================================
100 //function : SetTolerance2
101 //purpose  : 
102 //=======================================================================
103   void IntTools_EdgeEdge::SetTolerance2(const Standard_Real aTol) 
104 {
105   myTol2=aTol;
106
107
108 //=======================================================================
109 //function : SetDiscretize
110 //purpose  : 
111 //=======================================================================
112   void IntTools_EdgeEdge::SetDiscretize(const Standard_Integer aDiscret)
113 {
114   myDiscret=aDiscret;
115 }
116 //=======================================================================
117 //function : SetDeflection
118 //purpose  : 
119 //=======================================================================
120   void IntTools_EdgeEdge::SetDeflection(const Standard_Real aDefl) 
121 {
122   myDeflection=aDefl;
123
124 //=======================================================================
125 //function : SetEpsilonT
126 //purpose  : 
127 //=======================================================================
128   void IntTools_EdgeEdge::SetEpsilonT(const Standard_Real anEpsT) 
129 {
130   myEpsT=anEpsT;
131
132 //=======================================================================
133 //function : SetEpsilonNull
134 //purpose  : 
135 //=======================================================================
136   void IntTools_EdgeEdge::SetEpsilonNull(const Standard_Real anEpsNull) 
137 {
138   myEpsNull=anEpsNull;
139
140
141 //=======================================================================
142 //function : SetRange1
143 //purpose  : 
144 //=======================================================================
145   void IntTools_EdgeEdge::SetRange1(const Standard_Real aFirst,
146                                     const Standard_Real aLast) 
147 {
148   myRange1.SetFirst (aFirst);
149   myRange1.SetLast  (aLast);
150
151 //=======================================================================
152 //function : SetRange2
153 //purpose  : 
154 //=======================================================================
155   void IntTools_EdgeEdge::SetRange2(const Standard_Real aFirst,
156                                     const Standard_Real aLast) 
157 {
158   myRange2.SetFirst (aFirst);
159   myRange2.SetLast  (aLast);
160
161
162 //=======================================================================
163 //function : SetRange1
164 //purpose  : 
165 //=======================================================================
166   void IntTools_EdgeEdge::SetRange1(const IntTools_Range& aRange) 
167 {
168   myRange1.SetFirst (aRange.First());
169   myRange1.SetLast  (aRange.Last());
170
171 //=======================================================================
172 //function : SetRange2
173 //purpose  : 
174 //=======================================================================
175   void IntTools_EdgeEdge::SetRange2(const IntTools_Range& aRange) 
176 {
177   myRange2.SetFirst (aRange.First());
178   myRange2.SetLast  (aRange.Last());
179
180
181 //=======================================================================
182 //function : Order
183 //purpose  : 
184 //=======================================================================
185   Standard_Boolean IntTools_EdgeEdge::Order()const 
186 {
187   return myOrder;
188
189 //=======================================================================
190 //function : IsDone
191 //purpose  : 
192 //=======================================================================
193   Standard_Boolean IntTools_EdgeEdge::IsDone()const 
194 {
195   return myIsDone;
196
197 //=======================================================================
198 //function : ErrorStatus
199 //purpose  : 
200 //=======================================================================
201   Standard_Integer IntTools_EdgeEdge::ErrorStatus()const 
202 {
203   return myErrorStatus;
204
205
206 //=======================================================================
207 //function : CommonParts
208 //purpose  : 
209 //=======================================================================
210   const IntTools_SequenceOfCommonPrts& IntTools_EdgeEdge::CommonParts() const 
211 {
212   return mySeqOfCommonPrts;
213 }
214 //=======================================================================
215 //function : Range1
216 //purpose  : 
217 //=======================================================================
218   const IntTools_Range&  IntTools_EdgeEdge::Range1() const
219 {
220   return myRange1;
221
222 //=======================================================================
223 //function : Range2
224 //purpose  : 
225 //=======================================================================
226   const IntTools_Range&  IntTools_EdgeEdge::Range2() const
227 {
228   return myRange2;
229 }
230 //=======================================================================
231 //function : Perform
232 //purpose  : 
233 //=======================================================================
234   void IntTools_EdgeEdge::Perform() 
235 {
236   Standard_Boolean bIsSameCurves;
237   Standard_Integer i, pri, aNbCommonPrts, aNbRange;
238   Standard_Real aT1, aT2, aPC;
239   IntTools_CommonPrt aCommonPrt;
240   GeomAbs_CurveType aCTFrom, aCTTo;
241   //
242   myIsDone=Standard_False;
243   myErrorStatus=0;
244   //
245   CheckData();
246   if (myErrorStatus)
247     return;
248   //
249   Prepare();
250
251   if (myErrorStatus) {
252     return;
253   }
254   //
255   aCTFrom = myCFrom.GetType();
256   aCTTo   = myCTo.GetType();
257   //
258   if(aCTFrom==GeomAbs_Line && aCTTo==GeomAbs_Line) {
259     ComputeLineLine();
260     if (myOrder) {
261       TopoDS_Edge aTmp;
262       aTmp=myEdge1;
263       myEdge1=myEdge2;
264       myEdge2=aTmp;
265     }
266     return;
267   }
268   //
269   bIsSameCurves=IsSameCurves();
270   if (bIsSameCurves) {
271     aCommonPrt.SetType(TopAbs_EDGE);
272     aCommonPrt.SetRange1 (myTminFrom, myTmaxFrom);
273     aCommonPrt.AppendRange2 (myTminTo, myTmaxTo);
274     mySeqOfCommonPrts.Append(aCommonPrt);
275     myIsDone=Standard_True;
276     return;
277   }
278   //
279   IntTools_BeanBeanIntersector anIntersector(myCFrom, myCTo, myTolFrom, myTolTo);
280   anIntersector.SetBeanParameters(Standard_True, myTminFrom, myTmaxFrom);
281   anIntersector.SetBeanParameters(Standard_False, myTminTo, myTmaxTo);
282   //
283   anIntersector.Perform();
284   if(!anIntersector.IsDone()) {
285     myIsDone = Standard_False;
286     return;
287   }
288   //
289   aPC=Precision::PConfusion();
290   aCommonPrt.SetEdge1(myCFrom.Edge());
291   aCommonPrt.SetEdge2(myCTo.Edge());
292   //
293   const IntTools_SequenceOfRanges& aSR=anIntersector.Result();
294   aNbRange=aSR.Length();
295   for(i=1; i <=aNbRange; ++i) {
296     const IntTools_Range& aRange =aSR.Value(i);
297     aT1=aRange.First();
298     aT2=aRange.Last();
299     //
300     if(IsProjectable(IntTools_Tools::IntermediatePoint(aT1, aT2))) {
301       aCommonPrt.SetRange1(aT1, aT2);
302       //
303       if(((aT1 - myTminFrom)<aPC) && ((myTmaxFrom  - aT2)<aPC)) {
304         aCommonPrt.SetAllNullFlag(Standard_True);
305       }
306       mySeqOfCommonPrts.Append(aCommonPrt);
307     }
308   }
309   //
310   aNbCommonPrts=mySeqOfCommonPrts.Length();
311   for (i=1; i<=aNbCommonPrts; ++i) {
312     IntTools_CommonPrt& aCmnPrt=mySeqOfCommonPrts.ChangeValue(i);
313     pri=FindRangeOnCurve2 (aCmnPrt); 
314     if (pri) {
315       myErrorStatus=10;
316       return;
317     }
318   }
319   //
320   // Line Circle's Common Parts treatement
321   if ((aCTFrom==GeomAbs_Line   && aCTTo==GeomAbs_Circle) || 
322       (aCTFrom==GeomAbs_Circle && aCTTo==GeomAbs_Line) ||
323       (aCTFrom==GeomAbs_Ellipse && aCTTo==GeomAbs_Ellipse) ||
324       (aCTFrom==GeomAbs_Circle && aCTTo==GeomAbs_Circle))  {
325     for (i=1; i<=aNbCommonPrts; i++) {
326       IntTools_CommonPrt& aCP=mySeqOfCommonPrts(i);
327       TopAbs_ShapeEnum aType=aCP.Type();
328       Standard_Boolean bIsTouch;
329       Standard_Real aTx1, aTx2;
330       //
331       if ((aType==TopAbs_EDGE) && !aCommonPrt.AllNullFlag()) {
332         bIsTouch=CheckTouch (aCP, aTx1, aTx2);
333         if (bIsTouch) {
334           aCP.SetType(TopAbs_VERTEX);
335           aCP.SetVertexParameter1(aTx1);
336           aCP.SetRange1 (aTx1, aTx1);
337           IntTools_Range& aRange2=(aCP.ChangeRanges2()).ChangeValue(1);
338           aRange2.SetFirst(aTx2);
339           aRange2.SetLast (aTx2);
340         }
341       }
342       //
343       if (aType==TopAbs_VERTEX) {
344         if(aCTFrom==GeomAbs_Line || aCTTo==GeomAbs_Line) {
345           bIsTouch=CheckTouchVertex (aCP, aTx1, aTx2);
346           if (bIsTouch) {
347             aCP.SetVertexParameter1(aTx1);
348             aCP.SetRange1 (aTx1, aTx1);
349             IntTools_Range& aRange2=(aCP.ChangeRanges2()).ChangeValue(1);
350             aRange2.SetFirst(aTx2);
351             aRange2.SetLast (aTx2);
352           }
353         }
354       }
355     }
356   }
357   //
358   if (myOrder) {
359     TopoDS_Edge aTmp;
360     aTmp=myEdge1;
361     myEdge1=myEdge2;
362     myEdge2=aTmp;
363   }
364   //
365   myIsDone=Standard_True;
366
367
368 //=======================================================================
369 //function : CheckData
370 //purpose  : 
371 //=======================================================================
372   void IntTools_EdgeEdge::CheckData()
373 {
374   if (BRep_Tool::Degenerated(myEdge1)) {
375     myErrorStatus=2;
376   }
377   if (!BRep_Tool::IsGeometric(myEdge1)) { 
378      myErrorStatus=3;
379   }
380   if (BRep_Tool::Degenerated(myEdge2)) {
381     myErrorStatus=4;
382   }
383   if (!BRep_Tool::IsGeometric(myEdge2)) { 
384      myErrorStatus=5;
385   } 
386 }
387 //=======================================================================
388 //function : Prepare
389 //purpose  : 
390 //=======================================================================
391   void IntTools_EdgeEdge::Prepare() 
392 {
393   Standard_Real aLE1, aLE2, aT1, aT2, aTol1, aTol2;
394   GeomAdaptor_Curve aGAC;
395   GeomAbs_CurveType aCT1, aCT2;
396   //
397   // 1.Prepare Curves' data
398   const Handle(Geom_Curve)& aC1=BRep_Tool::Curve  (myEdge1, aT1, aT2);
399   aT1=myRange1.First();
400   aT2=myRange1.Last();
401   aGAC.Load(aC1, myRange1.First(), myRange1.Last());
402   aLE1=CPnts_AbscissaPoint::Length(aGAC, aT1, aT2);
403   //
404   const Handle(Geom_Curve)& aC2=BRep_Tool::Curve  (myEdge2,  aT1, aT2);
405   aT1=myRange2.First();
406   aT2=myRange2.Last();
407   aGAC.Load(aC2, aT1, aT2);
408   aLE2=CPnts_AbscissaPoint::Length(aGAC, aT1, aT2);
409   //
410   myOrder=Standard_False;
411   if (aLE1 <= aLE2) {
412     myCFrom.Initialize(myEdge1);
413     myCTo  .Initialize(myEdge2);
414     myTolFrom=myTol1;
415     myTolTo=myTol2;
416     myTminFrom=myRange1.First();
417     myTmaxFrom=myRange1.Last ();
418     myTminTo  =myRange2.First();
419     myTmaxTo  =myRange2.Last ();
420   }
421   else {
422     myCFrom.Initialize(myEdge2);
423     myCTo  .Initialize(myEdge1);
424     myTolFrom=myTol2;
425     myTolTo=myTol1;
426     myTminFrom=myRange2.First();
427     myTmaxFrom=myRange2.Last ();
428     myTminTo  =myRange1.First();
429     myTmaxTo  =myRange1.Last ();
430     //
431     myOrder=Standard_True; // revesed order
432   }
433   //
434   // 2.Prepare myCriteria
435   aCT1=myCFrom.GetType();
436   aCT2=myCTo.GetType();
437   //
438   aTol1=myTol1;
439   if(aCT1==GeomAbs_BSplineCurve|| aCT1==GeomAbs_BezierCurve){
440     aTol1=1.2*myTol1;
441   }
442   aTol2=myTol2;
443   if(aCT2==GeomAbs_BSplineCurve|| aCT2==GeomAbs_BezierCurve){
444     aTol2=1.2*myTol2;
445   }
446   myCriteria=aTol1+aTol2;
447 }
448 //=======================================================================
449 //function : IsProjectable
450 //purpose  : 
451 //=======================================================================
452   Standard_Integer IntTools_EdgeEdge::IsProjectable(const Standard_Real t) const
453
454   Standard_Integer aNbProj;
455   Standard_Real f, l;
456   gp_Pnt aPFrom;
457
458   GeomAPI_ProjectPointOnCurve aProjector;
459   const TopoDS_Edge& aEFrom=myCFrom.Edge();
460   Handle(Geom_Curve)aCurveFrom=BRep_Tool::Curve (aEFrom, f, l);
461   aCurveFrom->D0(t, aPFrom);
462   
463   Handle(Geom_Curve)aCurveTo=BRep_Tool::Curve (myCTo.Edge(), f, l);
464   aProjector.Init(aCurveTo, myTminTo, myTmaxTo);
465   aProjector.Perform(aPFrom);
466   aNbProj=aProjector.NbPoints();
467   //
468   if (myCTo.GetType()==GeomAbs_Circle) {
469     gp_Circ aCirc=myCTo.Circle();
470     const gp_Pnt& aCenter=aCirc.Location();
471     if (aCenter.SquareDistance(aPFrom) < 1.e-7) {
472       aNbProj=1;
473     }
474   }
475   return aNbProj;
476 }
477
478 //=======================================================================
479 //function : DistanceFunction
480 //purpose  : 
481 //=======================================================================
482   Standard_Real IntTools_EdgeEdge::DistanceFunction(const Standard_Real t)//const
483 {
484   Standard_Real aD, f, l;
485   GeomAPI_ProjectPointOnCurve aProjector;
486   gp_Pnt aPFrom; //ZZ , aPTo;
487
488   const TopoDS_Edge& aEFrom=myCFrom.Edge();
489   const TopoDS_Edge& aETo  =myCTo.Edge();
490   
491   Handle(Geom_Curve)aCurveFrom=BRep_Tool::Curve (aEFrom, f, l);
492   aCurveFrom->D0 (t, aPFrom);
493   Handle(Geom_Curve)aCurveTo=BRep_Tool::Curve (aETo, f, l);
494
495   if (myCTo.GetType()==GeomAbs_Circle) {
496     gp_Circ aCirc=myCTo.Circle();
497     const gp_Pnt& aCenter=aCirc.Location();
498     const gp_Ax1& anAx1  =aCirc.Axis();
499     const gp_Dir& aDir   =anAx1.Direction();
500     gp_Lin aLin(aCenter, aDir);
501     Standard_Real dPFromLin=aLin.Distance(aPFrom);
502     if (dPFromLin < 1.e-7) {
503       gp_Pnt anAnyPTo;
504       aCurveTo->D0 (myTminTo, anAnyPTo);
505       aD=aPFrom.Distance(anAnyPTo);
506       
507       aD=aD-myCriteria;
508       return aD; 
509     }
510   }
511   
512   aProjector.Init(aCurveTo, myTminTo, myTmaxTo);
513   aProjector.Perform(aPFrom);
514   //
515   Standard_Integer j, aNbPoints;
516   //
517   aNbPoints =aProjector.NbPoints();
518   if (!aNbPoints) {
519     for (j=0; j<=1; j++) {
520       Standard_Real tt;
521       tt=t+myEpsT;
522       if (j) {
523         tt=t-myEpsT;
524       }
525         
526       aCurveFrom->D0 (tt, aPFrom);
527       aProjector.Init(aCurveTo, myTminTo, myTmaxTo);
528       aProjector.Perform(aPFrom);
529       aNbPoints=aProjector.NbPoints();
530       if (aNbPoints) {
531         break;
532       }
533     }
534   }
535   
536
537   if (!aNbPoints) {
538     // Can't find projection.
539     myErrorStatus=11;
540     aD=100.;
541     return aD;
542   }
543     
544   aD=aProjector.LowerDistance();
545   //
546   aD=aD-myCriteria;
547   return aD; 
548 }
549
550 //=======================================================================
551 //function : DerivativeFunction
552 //purpose  : 
553 //=======================================================================
554   Standard_Real IntTools_EdgeEdge::DerivativeFunction(const Standard_Real t2)
555 {
556   Standard_Real t1, t3, aD1, aD2, aD3;
557   Standard_Real dt=1.e-7;
558   t1=t2-dt;
559   aD1=DistanceFunction(t1);
560   t3=t2+dt;
561   aD3=DistanceFunction(t3);
562   
563   aD2=.5*(aD3-aD1)/dt;
564   return aD2; 
565 }
566
567
568 //=======================================================================
569 //function : FindSimpleRoot
570 //purpose  : [private]
571 //=======================================================================
572   Standard_Real IntTools_EdgeEdge::FindSimpleRoot (const Standard_Integer IP,
573                                                    const Standard_Real tA,
574                                                    const Standard_Real tB,
575                                                    const Standard_Real fA)
576 {
577   Standard_Real r, a, b, y, x0, s;
578   
579   a=tA; b=tB; r=fA;
580
581   Standard_Integer step = 1, stepcheck = 1000, steplimit = 100000;
582   Standard_Real value = (IP==1) ? DistanceFunction(0.5*(a+b)) : DerivativeFunction(0.5*(a+b));
583   
584   for(;;) {
585     x0=.5*(a+b);
586
587     if (IP==1)
588       y=DistanceFunction(x0);
589     else 
590       y=DerivativeFunction(x0);
591
592     Standard_Real aMaxAB100 = 100.*Max(a, b);
593     Standard_Real anEps     = Epsilon(aMaxAB100);
594     Standard_Real anEpsT    = Max(anEps, myEpsT);
595 //    if (fabs(b-a) < myEpsT || y==0.) {
596     if (fabs(b-a) < anEpsT || y==0.) {
597       return x0;
598     }
599     
600     if( step == stepcheck ) {
601       if( Abs(value - y) <= 1.e-9 ) {
602         return x0;
603       }
604       else {
605         value = y;
606         step = 1;
607       }
608     }
609
610     if( step == steplimit ) {
611       return x0;
612     }
613
614     s=y*r;
615
616     if (s<0.) {
617       b=x0;
618       continue;
619     }
620
621     if (s>0.) {
622       a=x0; r=y;
623     }
624
625     step++;
626
627   }
628 }
629
630 //=======================================================================
631 //function : FindRangeOnCurve2
632 //purpose  : 
633 //=======================================================================
634 Standard_Integer IntTools_EdgeEdge::FindRangeOnCurve2(IntTools_CommonPrt&  aCommonPrt)
635 {
636   Standard_Integer pri;
637   //
638   pri=0;
639   if (aCommonPrt.AllNullFlag()) {
640     aCommonPrt.SetType(TopAbs_EDGE);
641     aCommonPrt.AppendRange2 (myTminTo, myTmaxTo);
642     return pri;
643   }
644   //
645   Standard_Real ttmp, f, l, af1, al1, am1, af2, al2, am2;
646   gp_Pnt aPf1, aPl1, aPm1, aPf2, aPl2, aPm2;
647   GeomAPI_ProjectPointOnCurve aProjector;
648
649   aCommonPrt.Range1(af1, al1);
650   am1=.5*(af1+al1);
651
652   const TopoDS_Edge& anEdgeTo=myCTo.Edge();
653   Handle(Geom_Curve)aCurveTo=BRep_Tool::Curve (anEdgeTo, f, l);
654
655   const TopoDS_Edge& anEdgeFrom=myCFrom.Edge();
656   Handle(Geom_Curve)aCurveFrom=BRep_Tool::Curve (anEdgeFrom, f, l);
657   //
658   // af2, aPf2
659   aCurveFrom->D0 (af1, aPf1); 
660   pri=GetParameterOnCurve2 (af1, af2);
661   if (pri) {
662     return 1;
663   }
664   aCurveTo->D0(af2, aPf2);
665   //
666   // al2, aPl2
667   aCurveFrom->D0 (al1, aPl1);
668   pri=GetParameterOnCurve2 (al1, al2);
669   if (pri) {
670     return 1;
671   }
672   aCurveTo->D0(al2, aPl2);
673   //
674   // am2, aPm2
675   aCurveFrom->D0 (am1, aPm1);
676   pri=GetParameterOnCurve2 (am1, am2);
677   if (pri) {
678     return 1;
679   }
680   aCurveTo->D0(am2, aPm2);
681   //
682   // Reverse C2 points if it is necessary  
683   Standard_Boolean reverse = (af2 > al2);
684
685   if (reverse) {
686     ttmp=af2;
687     af2=al2;
688     al2=ttmp;
689     gp_Pnt aPTmp;
690     aPTmp=aPf2;
691     aPf2=aPl2;
692     aPl2=aPTmp;
693   }
694
695   if((Abs(af2 - myTminTo) < Precision::PConfusion()) &&
696      (Abs(al2 - myTmaxTo) < Precision::PConfusion())) {
697     aCommonPrt.SetAllNullFlag(Standard_True);
698   }
699   //
700   //
701   Standard_Boolean aVFlag1, aVFlag2, aGeomFlag1, aGeomFlag2;
702   Standard_Real Df2m2, Dm2l2, Df2l2, df2m2, dm2l2, df2l2, df1m1, dm1l1, df1l1;
703   Standard_Real tV1, tV2;
704   //
705   // parametric differences for C2
706   Df2m2=fabs(af2-am2);
707   Dm2l2=fabs(am2-al2);
708   Df2l2=fabs(af2-al2);
709   //
710   // geometric distances for C2
711   df2m2=aPf2.Distance(aPm2);
712   dm2l2=aPm2.Distance(aPl2);
713   df2l2=aPf2.Distance(aPl2);
714
715   aVFlag1=(Df2m2<myEpsT && Dm2l2<myEpsT);
716   aVFlag2=(df2m2 < myCriteria && dm2l2 < myCriteria);
717
718   //
719   //  Two perpendicular lines => VERTEX
720   if ( aVFlag1 && aVFlag2) { 
721     // V e r t e x
722     aCommonPrt.SetType(TopAbs_VERTEX);
723     pri=TreatVertexType(am1, am2, aCommonPrt);
724     
725     if (pri) { 
726       tV2=.5*(af2+al2);
727       aCommonPrt.SetVertexParameter2(tV2);
728       aCommonPrt.AppendRange2 (af2, al2);
729       
730       tV1=.5*(af1+al1);
731       aCommonPrt.SetVertexParameter1(tV1);
732       aCommonPrt.SetRange1 (af1, al1);
733     }
734     return 0;
735   }
736   //
737   // geometric distances for C1
738   df1m1=aPf1.Distance(aPm1);
739   dm1l1=aPm1.Distance(aPl1);
740   df1l1=aPf1.Distance(aPl1);
741   //
742   // if geometric distances between boundaries is less than myCriteria
743   // we have VERTEX
744   aGeomFlag1=(df1l1 < myCriteria);
745   aGeomFlag2=(df2l2 < myCriteria);
746   if (aGeomFlag1 && aGeomFlag2) { 
747     aCommonPrt.SetType(TopAbs_VERTEX);
748     
749     tV2=.5*(af2+al2);
750     aCommonPrt.SetVertexParameter2(tV2);
751     aCommonPrt.AppendRange2 (af2, al2);
752       
753     tV1=.5*(af1+al1);
754     aCommonPrt.SetVertexParameter1(tV1);
755     aCommonPrt.SetRange1 (af1, al1);
756     return 0;
757   }
758   //
759   //  ???
760   if (Df2l2 < myEpsT &&  !aVFlag1) { 
761     if (aPf1.Distance(aPl1) < myCriteria && aPf2.Distance(aPl2) < myCriteria) { 
762       af1=myTminTo;
763       al2=myTmaxTo;
764       aCommonPrt.AppendRange2 (af1, al2);
765       aCommonPrt.SetType(TopAbs_EDGE);
766       return 0;
767     }
768   }
769   //
770   aProjector.Init(aCurveFrom, myTminFrom, myTmaxFrom);
771   aProjector.Perform(aPm2);
772   Standard_Integer aNbPoints=aProjector.NbPoints();
773   if (aNbPoints) { 
774     Standard_Real aDD=aProjector.LowerDistance();
775     if (aDD > myCriteria) { 
776       // Passed through 0
777       aCommonPrt.SetType(TopAbs_EDGE);
778       aCommonPrt.AppendRange2 (myTminTo, af2);
779       aCommonPrt.AppendRange2 (al2, myTmaxTo);
780       return 0;
781     }
782   }
783   else {
784     // Passed through 0
785     aCommonPrt.SetType(TopAbs_EDGE); 
786     aCommonPrt.AppendRange2 (myTminTo, af2);
787     aCommonPrt.AppendRange2 (al2, myTmaxTo);
788     return 0;
789   }
790
791   IsIntersection (af1, al1);
792   if (!myParallel && !aCommonPrt.AllNullFlag()) {
793     Standard_Real aPar2;
794     GetParameterOnCurve2 (myPar1, aPar2);
795     aCommonPrt.SetType(TopAbs_VERTEX);
796
797     Standard_Boolean IsmyPar1 = Standard_True;
798
799     if(Abs(af1-myTminFrom) < Precision::PConfusion()) {
800       IsmyPar1 = Standard_False;
801       aCommonPrt.SetVertexParameter1(af1);
802       if(reverse)
803         aCommonPrt.SetVertexParameter2(al2);
804       else
805         aCommonPrt.SetVertexParameter2(af2);
806     }
807
808     if(Abs(al1-myTmaxFrom) < Precision::PConfusion()) {
809       IsmyPar1 = Standard_False;
810       aCommonPrt.SetVertexParameter1(al1);
811
812       if(reverse)
813         aCommonPrt.SetVertexParameter2(af2);
814       else
815         aCommonPrt.SetVertexParameter2(al2);
816     }
817
818     if(Abs(af2-myTminTo) < Precision::PConfusion()) {
819       IsmyPar1 = Standard_False;
820       aCommonPrt.SetVertexParameter2(af2);
821
822       if(reverse)
823         aCommonPrt.SetVertexParameter1(al1);
824       else
825         aCommonPrt.SetVertexParameter1(af1);
826     }
827
828     if(Abs(al2-myTmaxTo) < Precision::PConfusion()) {
829       IsmyPar1 = Standard_False;
830       aCommonPrt.SetVertexParameter2(al2);
831
832       if(reverse)
833         aCommonPrt.SetVertexParameter1(af1);
834       else
835         aCommonPrt.SetVertexParameter1(al1);
836     }
837     //     aCommonPrt.SetVertexParameter1(myPar1);
838     //     aCommonPrt.SetRange1 (af1, al1);
839     
840     //     aCommonPrt.SetVertexParameter2(aPar2);
841     if(IsmyPar1) {
842       aCommonPrt.SetVertexParameter1(myPar1);
843       aCommonPrt.SetRange1 (af1, al1);
844       
845       aCommonPrt.SetVertexParameter2(aPar2);
846     }
847     aCommonPrt.AppendRange2 (af2, al2);
848     return 0;
849   }
850
851   
852
853   aCommonPrt.SetType(TopAbs_EDGE);
854   aCommonPrt.AppendRange2 (af2, al2);
855   return 0;
856 }
857  
858 //=======================================================================
859 //function : IsIntersection
860 //purpose  : 
861 //=======================================================================
862   void IntTools_EdgeEdge::IsIntersection (const Standard_Real ta, 
863                                           const Standard_Real tb) 
864 {
865   Standard_Integer i, aNb, pri;
866   Standard_Real t, f;
867   GeomAbs_CurveType aCT1, aCT2;
868   IntTools_CArray1OfReal anArgs, aFunc;
869   //
870   aCT1=myCFrom.GetType();
871   aCT2=myCTo.GetType();
872   if((aCT1==GeomAbs_Line) && (aCT2==GeomAbs_Line)) {
873     const Handle(Geom_Curve)&  Curve1=BRep_Tool::Curve  (myCFrom.Edge(), t, f);
874     const Handle(Geom_Curve)&  Curve2=BRep_Tool::Curve  (myCTo.Edge()  , t, f);
875     
876     GeomAdaptor_Curve   TheCurve1   (Curve1);
877     GeomAdaptor_Curve   TheCurve2   (Curve2);
878     Extrema_ExtCC anExtrema (TheCurve1, TheCurve2);
879
880     if(anExtrema.IsDone() && anExtrema.IsParallel()) {
881       myParallel = Standard_True;
882       return;
883     }
884   }
885   //
886   if (aCT1==GeomAbs_Circle && aCT2==GeomAbs_Circle) {
887     Standard_Boolean bIsDone, bIsParallel;
888     Standard_Integer aNbExt;
889     Standard_Real aD2, aCriteria2, aT1;
890     gp_Circ aCirc1, aCirc2;
891     Extrema_POnCurv aPC1, aPC2;
892     //
893     aCirc1=myCFrom.Circle();
894     aCirc2=myCTo.Circle();
895     //
896     Extrema_ExtElC aExtElC(aCirc1, aCirc2);
897     //
898     bIsDone=aExtElC.IsDone();
899     if (bIsDone) {
900       bIsParallel=aExtElC.IsParallel();
901       if (!bIsParallel) {
902         aCriteria2=myCriteria*myCriteria;
903         aNbExt=aExtElC.NbExt();
904         for (i=1; i<=aNbExt; ++i) {
905           aD2=aExtElC.SquareDistance(i);
906           if (aD2<aCriteria2) {
907             aExtElC.Points(i, aPC1, aPC2);
908             aT1=aPC1.Parameter();
909             if (aT1>ta && aT1<tb) {
910               myPar1=aT1;
911               myParallel=Standard_False;
912               return;
913             }
914           }
915         }
916       }
917     }
918   }
919   //
920   // Prepare values of arguments for the interval [ta, tb]
921   pri=IntTools::PrepareArgs (myCFrom, tb, ta, myDiscret, myDeflection, anArgs);
922   aNb=anArgs.Length();
923
924   aFunc.Resize(aNb);
925   for (i=0; i<aNb; i++) {
926     t=anArgs(i);
927     f=DistanceFunction(t);
928     if (fabs(f) < myEpsNull) { 
929       f=0.;
930     }
931     aFunc(i)=f;
932   }
933   FindDerivativeRoot(anArgs, aFunc);
934   return ;
935 }
936
937 //=======================================================================
938 //function : FindDerivativeRoot
939 //purpose  : 
940 //=======================================================================
941   void IntTools_EdgeEdge::FindDerivativeRoot(const IntTools_CArray1OfReal& t,
942                                              const IntTools_CArray1OfReal& f)  
943 {
944   Standard_Integer i, n, k;
945   Standard_Real fr, tr, anEpsNull;
946   IntTools_CArray1OfReal fd;
947   TColStd_SequenceOfReal aTSeq, aFSeq;
948   
949   anEpsNull=100.*myEpsNull;
950   myPar1=0.;
951   myParallel=Standard_True;
952   
953   n=t.Length();
954   fd.Resize(n+1);
955   //
956   // Table of derivatives
957   fd(0)=(f(1)-f(0))/(t(1)-t(0));
958   if (fabs(fd(0)) < anEpsNull) {
959     fd(0)=0.;
960   }
961   k=n-1;
962   for (i=1; i<k; i++) {
963     fd(i)=.5*(f(i+1)-f(i-1))/(t(i)-t(i-1));
964     if (fabs(fd(i)) < anEpsNull) {
965       fd(i)=0.;
966     }
967   }
968   fd(n-1)=(f(n-1)-f(n-2))/(t(n-1)-t(n-2));
969   if (fabs(fd(n-1)) < anEpsNull) {
970     fd(n-1)=0.;
971   }
972   //
973   // Finding the range where the derivatives have different signs
974   // for neighbouring points
975   for (i=1; i<n; i++) {
976     Standard_Real fd1, fd2, t1, t2, fabsfd1, fabsfd2;
977     Standard_Boolean bF1, bF2;
978     t1 =t(i-1);
979     t2 =t(i);
980     fd1=fd(i-1);
981     fd2=fd(i);
982
983     fabsfd1=fabs(fd1);
984     bF1=fabsfd1 < myEpsNull;
985     
986     fabsfd2=fabs(fd2);
987     bF2=fabsfd2 < myEpsNull;
988
989     //aa
990     if (fd1*fd2 < 0.) {
991       tr=FindSimpleRoot(2, t1, t2, fd1);
992       fr=DistanceFunction(tr);
993       myPar1=tr;
994       myParallel=Standard_False;
995       break;
996     }
997     
998     if (!bF1 && bF2) {
999       tr=t2;
1000       fr=fd2;
1001       myPar1=tr;
1002       myParallel=Standard_False;
1003       break;
1004     }
1005     
1006     if (bF1 && !bF2) {
1007       tr=t1;
1008       fr=fd1;
1009       myPar1=tr;
1010       myParallel=Standard_False;
1011       break;
1012     }
1013
1014   }
1015 }
1016
1017 //=======================================================================
1018 //function : GetParameterOnCurve2
1019 //purpose  : 
1020 //=======================================================================
1021   Standard_Integer IntTools_EdgeEdge::GetParameterOnCurve2(const Standard_Real aT1, 
1022                                                            Standard_Real& aT2) const
1023 {
1024   Standard_Real f, l;
1025   Standard_Integer j, found, aNbPoints;
1026   const TopoDS_Edge& anEdgeTo=myCTo.Edge();
1027   const TopoDS_Edge& anEdgeFrom=myCFrom.Edge();
1028   
1029   Handle(Geom_Curve)aCurveFrom=BRep_Tool::Curve (anEdgeFrom, f, l);
1030   Handle(Geom_Curve)aCurveTo  =BRep_Tool::Curve (anEdgeTo,   f, l);
1031
1032   gp_Pnt aP1;
1033   aCurveFrom->D0 (aT1, aP1);
1034   GeomAPI_ProjectPointOnCurve aProjector;
1035   aProjector.Init(aCurveTo, myTminTo, myTmaxTo);
1036   aProjector.Perform(aP1);
1037   aNbPoints=aProjector.NbPoints();
1038   found=1;
1039   if (!aNbPoints) {
1040     found=0;
1041     for (j=0; j<=1; j++) {
1042       Standard_Real tt;
1043       tt=aT1+myEpsT;
1044       if (j) {
1045         tt=aT1-myEpsT;
1046       }
1047       aCurveFrom->D0 (tt, aP1);
1048       aProjector.Init(aCurveTo, myTminTo, myTmaxTo);
1049       aProjector.Perform(aP1);
1050       aNbPoints=aProjector.NbPoints();
1051       if (aNbPoints) {
1052         found=1;
1053         break;
1054       }
1055     }
1056   }
1057
1058   if (!found) {
1059     aCurveFrom->D0 (aT1, aP1);
1060     Standard_Real aDistance = RealLast();
1061
1062     for(Standard_Integer pIt=0; pIt < 2; pIt++) {
1063       Standard_Real adist = aDistance;
1064       if(pIt)
1065         adist = aP1.Distance(aCurveTo->Value(myTminTo));
1066       else
1067         adist = aP1.Distance(aCurveTo->Value(myTmaxTo));
1068       
1069       if(adist < myCriteria) {
1070         found = Standard_True;
1071
1072         if(adist < aDistance) {
1073           aT2 = (pIt) ? myTminTo : myTmaxTo;
1074           aDistance = adist;
1075         }
1076       }      
1077     }
1078     if(found)
1079       return 0;
1080   }
1081
1082   if (!found) {
1083     aT2=0.;
1084     return 1;
1085   }
1086
1087   for (j=1; j<=aNbPoints; j++) {
1088     aT2=aProjector.Parameter(j);
1089     f=aProjector.Distance(j);
1090   }
1091
1092   aT2=aProjector.LowerDistanceParameter();
1093   if (aT2 < myTminTo) {
1094     aT2=myTminTo;
1095   }
1096   if (aT2 > myTmaxTo) {
1097     aT2=myTmaxTo;
1098   }
1099   return 0;
1100 }
1101  
1102 //=======================================================================
1103 //function : TreatVertexType
1104 //purpose  : 
1105 //=======================================================================
1106   Standard_Integer IntTools_EdgeEdge::TreatVertexType(const Standard_Real am1,
1107                                                       const Standard_Real am2,
1108                                                       IntTools_CommonPrt&  aCommonPrt) 
1109 {
1110   Standard_Real  f1, l1, f2, l2, Alfa , aPeriod;
1111   gp_Pnt aPm1, aPm2, aP;
1112   gp_Vec aVm1, aVm2;
1113   
1114
1115   const TopoDS_Edge& anEdgeFrom=myCFrom.Edge();
1116   Handle(Geom_Curve)aCurveFrom=BRep_Tool::Curve (anEdgeFrom, f1, l1);
1117   aCurveFrom->D1 (am1, aPm1, aVm1);
1118   aVm1.Normalize();
1119
1120   const TopoDS_Edge& anEdgeTo=myCTo.Edge();
1121   Handle(Geom_Curve)aCurveTo=BRep_Tool::Curve (anEdgeTo, f2, l2);
1122   aCurveTo->D1 (am2, aPm2, aVm2);
1123   aVm2.Normalize();
1124
1125   Alfa=aVm1.Angle(aVm2);
1126
1127   if (Alfa < Precision::Angular()) {
1128     return 1;
1129   }
1130
1131   Standard_Real sinAlfa, cosAlfa, dd, tf1, tl1, tf2, tl2, aL1, aL2;
1132   Standard_Integer ip;
1133   
1134   sinAlfa=sin(Alfa);
1135   cosAlfa=cos(Alfa);
1136     
1137   dd=aPm1.Distance(aPm2);
1138   // aL2
1139   if (dd>myCriteria) {
1140     return 1;
1141   }
1142   aL2=(myTolTo*cosAlfa+myTolFrom)/sinAlfa;
1143   // left point
1144   aP.SetXYZ(aPm2.XYZ()-aVm2.XYZ()*aL2);
1145   ip=IntTools::Parameter (aP, aCurveTo, tf2);
1146   if (ip){
1147     return ip;
1148   }
1149   // 
1150   if(aP.Distance(aCurveTo->Value(tf2)) > myTolTo)
1151     return 1;
1152
1153   // right point
1154   aP.SetXYZ(aPm2.XYZ()+aVm2.XYZ()*aL2);
1155   ip=IntTools::Parameter (aP, aCurveTo, tl2);
1156   if (ip){
1157     return ip;
1158   }
1159
1160   if(aP.Distance(aCurveTo->Value(tl2)) > myTolTo)
1161     return 1;
1162   
1163   // aL1
1164   if (dd>myCriteria) {
1165     return 1;
1166   }
1167  
1168   aL1=(myTolFrom*cosAlfa+myTolTo)/sinAlfa;
1169   // left point
1170   aP.SetXYZ(aPm1.XYZ()-aVm1.XYZ()*aL1);
1171   ip=IntTools::Parameter (aP, aCurveFrom, tf1);
1172   if (ip){
1173     return ip;
1174   }
1175
1176   if(aP.Distance(aCurveFrom->Value(tf1)) > myTolFrom)
1177     return 1;
1178
1179   // right point
1180   aP.SetXYZ(aPm1.XYZ()+aVm1.XYZ()*aL1);
1181   ip=IntTools::Parameter (aP, aCurveFrom, tl1);
1182   if (ip){
1183     return ip;
1184   }
1185
1186   if(aP.Distance(aCurveFrom->Value(tl1)) > myTolFrom)
1187     return 1;
1188
1189   //
1190   if (aCurveFrom->IsPeriodic()) {
1191     aPeriod=aCurveFrom->Period();
1192     if (tf1<f1 || tf1>l1) {
1193       tf1=tf1+aPeriod;
1194     }
1195     if (tl1<f1 || tl1>l1) {
1196       tl1=tl1+aPeriod;
1197     }
1198   }
1199   //
1200   // First range
1201   aCommonPrt.SetRange1    (tf1, tl1);
1202   aCommonPrt.SetVertexParameter1((tf1 + tl1) * 0.5);
1203   //
1204   // Second Range(s) 
1205   if (aCurveTo->IsPeriodic() && tf2 > tl2) {
1206     // aCurveTo is periodic curve and we pass through 0.
1207     
1208     aPeriod=aCurveTo->Period();
1209     aCommonPrt.AppendRange2 (tf2, aPeriod);
1210     aCommonPrt.AppendRange2 (0., tl2);
1211     aCommonPrt.SetVertexParameter2((tf2 + aPeriod) * 0.5);
1212   }
1213   else {
1214     // usual cases 
1215     return 1;
1216     //
1217   }
1218   return 0;
1219 }
1220  
1221
1222 //
1223 //
1224 // Print block
1225
1226 // myErrorStatus
1227 // 1 - the method Perform() is not invoked  
1228 // 2,3,4,5 -the method CheckData() fails
1229 // 6 - PrepareArgs() problems
1230 // 7 - No Projectable ranges
1231 // 8,9 - PrepareArgs() problems occured inside  projectable Ranges
1232 // 10 - problems in FindRange2
1233 // 11 - can't fill array  aFunc(i) in PrepareArgsFuncArrays: 
1234 //      possible reason is that no points on myCFrom that could be projected
1235 //      on myCTo
1236 //   
1237
1238
1239 //=======================================================================
1240 //function : CheckTouchVertex 
1241 //purpose  : line/Circle refinement
1242 //=======================================================================
1243   Standard_Boolean IntTools_EdgeEdge::CheckTouchVertex (const IntTools_CommonPrt& aCP,
1244                                                         Standard_Real& aTx1,
1245                                                         Standard_Real& aTx2) const
1246 {
1247   Standard_Boolean bFlag;
1248   Standard_Real aTFR1, aTLR1, aTFR2, aTLR2;
1249   Standard_Real aTL1, aTL2, aTC1, aTC2;
1250   Standard_Real aRC, aDLC, aD2, aC2, aTLx, aTCx;
1251   GeomAbs_CurveType aTFrom, aTTo;
1252   gp_Circ aCirc;
1253   gp_Lin  aLine;
1254   gp_Pnt aPC, aPLx, aPCx;
1255   //
1256   bFlag=Standard_False;
1257   aCP.Range1(aTFR1, aTLR1);
1258   (aCP.Ranges2())(1).Range(aTFR2, aTLR2);
1259   //
1260   aTFrom=myCFrom.GetType();
1261   aTTo  =myCTo.GetType();
1262   //
1263   aTL1=aTFR1;
1264   aTL2=aTLR1;
1265   aTC1=aTFR2;
1266   aTC2=aTLR2;
1267   if (aTFrom==GeomAbs_Circle) {
1268     aCirc=myCFrom.Circle();
1269     aLine=myCTo.Line();
1270     aTL1=aTFR2;
1271     aTL2=aTLR2;
1272     aTC1=aTFR1;
1273     aTC2=aTLR1;
1274   }
1275   else {
1276     aCirc=myCTo.Circle();
1277     aLine=myCFrom.Line();
1278   }
1279   //
1280   aPC=aCirc.Location();
1281   aRC=aCirc.Radius();
1282   //
1283   aDLC=aLine.Distance(aPC);
1284   if (fabs(aDLC-aRC)>myCriteria) {
1285     return bFlag;
1286   }
1287   //
1288   aTLx=ElCLib::Parameter(aLine, aPC);
1289   aPLx=ElCLib::Value(aTLx, aLine);
1290   aTCx=ElCLib::Parameter(aCirc, aPLx);
1291   aPCx=ElCLib::Value(aTCx, aCirc);
1292   aD2=aPLx.SquareDistance(aPCx);
1293   aC2=myCriteria*myCriteria;
1294   if (aD2>aC2) {
1295     return bFlag;
1296   }
1297   //
1298   if (aTLx<aTL1 || aTLx>aTL2) {
1299     return bFlag;
1300   }
1301   if (aTCx<aTC1 || aTCx>aTC2) {
1302     return bFlag;
1303   }
1304   //
1305   aTx1=aTLx;
1306   aTx2=aTCx;
1307   if (aTFrom==GeomAbs_Circle) {
1308     aTx1=aTCx;
1309     aTx2=aTLx;
1310   }
1311   //
1312   return !bFlag;
1313 }
1314 //=======================================================================
1315 //function : CheckTouch 
1316 //purpose  : 
1317 //=======================================================================
1318   Standard_Boolean IntTools_EdgeEdge::CheckTouch(const IntTools_CommonPrt& aCP,
1319                                                  Standard_Real& aTx1,
1320                                                  Standard_Real& aTx2) 
1321 {
1322   Standard_Real aTF1, aTL1, aTF2, aTL2, Tol, af, al,aDist2, aMinDist2;
1323   Standard_Boolean theflag=Standard_False;
1324   Standard_Integer aNbExt, i, iLower;
1325
1326   aCP.Range1(aTF1, aTL1);
1327   (aCP.Ranges2())(1).Range(aTF2, aTL2);
1328
1329   Tol = Precision::PConfusion();
1330
1331   const Handle(Geom_Curve)&  Curve1   =BRep_Tool::Curve  (myCFrom.Edge(), af, al);
1332   const Handle(Geom_Curve)&  Curve2   =BRep_Tool::Curve  (myCTo.Edge()  , af, al);
1333   
1334   GeomAdaptor_Curve   TheCurve1   (Curve1, aTF1, aTL1);
1335   GeomAdaptor_Curve   TheCurve2   (Curve2, aTF2, aTL2);
1336
1337   {
1338     Standard_Real aTol1 = TheCurve1.Resolution(myCriteria);
1339     aTol1 = (Tol < aTol1) ? Tol : aTol1;
1340     
1341     Standard_Boolean isfirst = (Abs(myTminFrom - aTF1) < aTol1);
1342     Standard_Boolean islast  = (Abs(myTmaxFrom - aTL1) < aTol1);
1343     
1344     if(!isfirst || !islast) {
1345       if(isfirst) {
1346         aTx1 = aTF1;
1347         GeomAPI_ProjectPointOnCurve aProjector;
1348         aProjector.Init(Curve2, aTF2, aTL2);
1349         aProjector.Perform(Curve1->Value(aTx1));
1350         //
1351         if(aProjector.NbPoints() > 0)
1352           aTx2 = aProjector.LowerDistanceParameter();
1353         else {
1354           if(Curve1->Value(aTx1).Distance(Curve2->Value(aTF2)) < myCriteria)
1355             aTx2 = aTF2;
1356           else
1357             aTx2 = aTL2;
1358         }
1359         return !theflag;
1360       }
1361       
1362       if(islast) {
1363         aTx1 = aTL1;
1364         GeomAPI_ProjectPointOnCurve aProjector;
1365         aProjector.Init(Curve2, aTF2, aTL2);
1366         aProjector.Perform(Curve1->Value(aTx1));
1367         if(aProjector.NbPoints() > 0)
1368           aTx2 = aProjector.LowerDistanceParameter();
1369         else {
1370           if(Curve1->Value(aTx1).Distance(Curve2->Value(aTL2)) < myCriteria)
1371             aTx2 = aTL2;
1372           else
1373             aTx2 = aTF2;
1374         }
1375         return !theflag;
1376       }
1377     }
1378   }
1379                                  
1380   Extrema_ExtCC anExtrema (TheCurve1, TheCurve2, aTF1-Tol, aTL1+Tol, aTF2-Tol, aTL2+Tol, Tol, Tol);
1381   
1382   if(!anExtrema.IsDone()) {
1383     return theflag;
1384   }
1385   if (anExtrema.IsParallel()) {
1386     return theflag;
1387   }
1388   
1389   aNbExt=anExtrema.NbExt() ;
1390   if (!aNbExt) {
1391      return theflag;
1392   }
1393
1394   Standard_Boolean istouch = Standard_True;
1395   Standard_Integer avalidindex = 0;
1396
1397   iLower=1;
1398   aMinDist2=1.e100;
1399   for (i=1; i<=aNbExt; ++i) {
1400     aDist2=anExtrema.SquareDistance(i);
1401     if (aDist2 < aMinDist2) {
1402       aMinDist2=aDist2;
1403       iLower=i;
1404     }
1405
1406     if(aDist2 < myCriteria * myCriteria) {
1407       if(avalidindex) {
1408         Extrema_POnCurv aPOnC1, aPOnC2;
1409         anExtrema.Points(i, aPOnC1, aPOnC2);
1410         Standard_Real aPar1 = aPOnC1.Parameter();
1411         anExtrema.Points(avalidindex, aPOnC1, aPOnC2);
1412         Standard_Real aPar2 = aPOnC1.Parameter();
1413         
1414         if(Abs(aPar1 - aPar2) > Precision::PConfusion()) {
1415           istouch = Standard_False;
1416         }
1417       }
1418       avalidindex = i;
1419     }
1420   }
1421
1422   aDist2=anExtrema.SquareDistance(iLower);
1423   if (aDist2 > myCriteria * myCriteria) {
1424     return theflag;
1425   }
1426
1427   Extrema_POnCurv aPOnC1, aPOnC2;
1428   anExtrema.Points(iLower, aPOnC1, aPOnC2);
1429   
1430   aTx1=aPOnC1.Parameter();
1431   aTx2=aPOnC2.Parameter();
1432
1433   if((myCFrom.GetType() == GeomAbs_Line   && myCTo.GetType() == GeomAbs_Circle) || 
1434      (myCFrom.GetType() == GeomAbs_Circle && myCTo.GetType() == GeomAbs_Line))
1435   {
1436     Standard_Real aRadius;
1437     GeomAbs_CurveType aTFrom, aTTo;
1438     gp_Circ aCirc;
1439     gp_Lin  aLine;
1440     gp_Pnt aPCenter, aPOnLine;
1441
1442     aTFrom=myCFrom.GetType();
1443     aTTo  =myCTo.GetType();
1444     
1445     if (aTFrom==GeomAbs_Circle) {
1446       aCirc=myCFrom.Circle();
1447       aLine=myCTo.Line();
1448       Curve2->D0(aTx2, aPOnLine);
1449     }
1450
1451     else {
1452       aCirc=myCTo.Circle();
1453       aLine=myCFrom.Line();
1454       Curve1->D0(aTx1, aPOnLine);
1455     }
1456     
1457
1458     aPCenter=aCirc.Location();
1459     aRadius =aCirc.Radius();
1460   
1461     aDist2=aPOnLine.SquareDistance(aPCenter);
1462     aDist2=fabs (sqrt(aDist2)-aRadius);
1463     aDist2 *= aDist2;
1464     if (aDist2 < Tol * Tol) {
1465       return !theflag;
1466     }
1467   }
1468   
1469   GeomAPI_ProjectPointOnCurve aProjector;
1470   Standard_Real aMidPar, aMidDist;   
1471   aMidPar = (aTF1 + aTL1) * 0.5;  
1472   aProjector.Init(Curve2, aTF2, aTL2);
1473   aProjector.Perform(Curve1->Value(aMidPar));
1474   if(aProjector.NbPoints() > 0) {
1475     aMidDist=aProjector.LowerDistance();
1476     if(aMidDist * aMidDist < aDist2 || !istouch) {
1477       aTx1 = aMidPar;
1478       aTx2 = aProjector.LowerDistanceParameter();
1479     }
1480   }
1481   
1482   if (fabs (aTx1-aTF1) < Tol) {
1483     return !theflag;
1484   }
1485
1486   if (fabs (aTx1-aTL1) < Tol) {
1487     return !theflag;
1488   }
1489
1490   if (aTx1 > (aTF1-Tol) && aTx1 < (aTL1+Tol) ) {
1491     return !theflag;
1492   }
1493
1494   return theflag;
1495 }
1496
1497 //=======================================================================
1498 //function : ComputeLineLine 
1499 //purpose  : 
1500 //=======================================================================
1501   void IntTools_EdgeEdge::ComputeLineLine()
1502 {
1503   Standard_Boolean IsParallel, IsCoincide;
1504   Standard_Real Tolang2, Tol2;
1505   gp_Pnt P11, P12, P21, P22;
1506   //
1507   myIsDone = Standard_True;
1508   //
1509   IsParallel = Standard_False;
1510   IsCoincide = Standard_False;
1511   Tolang2 = Precision::Angular();
1512   Tol2 = myCriteria*myCriteria; 
1513   //
1514   gp_Lin C1 = myCFrom.Line();
1515   gp_Lin C2 = myCTo.Line();
1516   const gp_Dir& D1 = C1.Position().Direction();
1517   const gp_Dir& D2 = C2.Position().Direction();
1518   Standard_Real aCos = D1.Dot(D2);
1519   Standard_Real Ang2;
1520
1521   if(aCos >= 0. ) {
1522     Ang2 = 2.*(1. - aCos);
1523   }
1524   else {
1525     Ang2 = 2.*(1. + aCos);
1526   }
1527
1528   if(Ang2 <= Tolang2) {
1529     IsParallel = Standard_True;
1530     if(C2.SquareDistance(C1.Location()) <= Tol2) {
1531       IsCoincide = Standard_True;
1532       P11 = ElCLib::Value(myTminFrom, C1);
1533       P12 = ElCLib::Value(myTmaxFrom, C1);
1534     }
1535   }
1536   else {
1537     //Check coincidence of extremity points;
1538     //Check only shortest line
1539     P11 = ElCLib::Value(myTminFrom, C1);
1540     P12 = ElCLib::Value(myTmaxFrom, C1);
1541     if(C2.SquareDistance(P11) <= Tol2 && C2.SquareDistance(P12) <= Tol2) {
1542       IsCoincide = Standard_True;
1543     }
1544   }
1545
1546   if(IsCoincide) {
1547     Standard_Real t21, t22;
1548     t21 = ElCLib::Parameter(C2, P11);
1549     t22 = ElCLib::Parameter(C2, P12);
1550
1551     if((t21 > myTmaxTo && t22 > myTmaxTo) || (t21 < myTminTo && t22 < myTminTo)) {
1552       return;
1553     }
1554
1555     Standard_Real temp;
1556     if(t21 > t22) {
1557       temp = t21;
1558       t21 = t22;
1559       t22 = temp;
1560     }
1561
1562     IntTools_CommonPrt aCommonPrt;
1563     aCommonPrt.SetEdge1(myCFrom.Edge());
1564     aCommonPrt.SetEdge2(myCTo.Edge());
1565     if(t21 >= myTminTo) {
1566       if(t22 <= myTmaxTo) {
1567         aCommonPrt.SetRange1(myTminFrom, myTmaxFrom);
1568         aCommonPrt.SetAllNullFlag(Standard_True);
1569         aCommonPrt.AppendRange2(t21, t22);
1570       }
1571       else {
1572         aCommonPrt.SetRange1(myTminFrom, myTmaxFrom - (t22 - myTmaxTo));
1573         aCommonPrt.AppendRange2(t21, myTmaxTo);
1574       }
1575     }
1576     else {
1577       aCommonPrt.SetRange1(myTminFrom + (myTminTo - t21), myTmaxFrom);
1578       aCommonPrt.AppendRange2(myTminTo, t22);
1579     }
1580     aCommonPrt.SetType(TopAbs_EDGE);  
1581     mySeqOfCommonPrts.Append(aCommonPrt);
1582     return;
1583
1584   }
1585
1586   if(IsParallel) {
1587     return;
1588   }
1589   //
1590   {
1591     TopoDS_Iterator aIt1, aIt2;
1592     //
1593     aIt1.Initialize(myEdge1);
1594     for (; aIt1.More(); aIt1.Next()) {
1595       const TopoDS_Shape& aV1=aIt1.Value();
1596       aIt2.Initialize(myEdge2);
1597       for (; aIt2.More(); aIt2.Next()) {
1598         const TopoDS_Shape& aV2=aIt2.Value();
1599         if (aV2.IsSame(aV1)) {
1600           // the two straight lines have commpn vertex
1601           return;
1602         }
1603       }
1604     }
1605   }
1606   //
1607   Standard_Real aSin2 = 1. - aCos*aCos;
1608   gp_Pnt O1 = C1.Location();
1609   gp_Pnt O2 = C2.Location();
1610   gp_Vec O1O2 (O1,O2);
1611   Standard_Real U2 = (D1.XYZ()*(O1O2.Dot(D1))-(O1O2.XYZ())).Dot(D2.XYZ());
1612   U2 /= aSin2;
1613   if(U2 < myTminTo || U2 > myTmaxTo) {
1614     return;
1615   }
1616   
1617   gp_Pnt P2(ElCLib::Value(U2,C2));
1618   Standard_Real U1 = (gp_Vec(O1,P2)).Dot(D1);
1619   if(U1 < myTminFrom || U1 > myTmaxFrom) {
1620     return;
1621   }
1622
1623   gp_Pnt P1(ElCLib::Value(U1,C1));
1624   Standard_Real d2 = P1.SquareDistance(P2);
1625
1626   if(d2 > Tol2) {
1627     return;
1628   }
1629   //
1630   IntTools_CommonPrt aCommonPrt;
1631   aCommonPrt.SetEdge1(myCFrom.Edge());
1632   aCommonPrt.SetEdge2(myCTo.Edge());
1633   aCommonPrt.SetRange1(U1 - myCriteria, U1 + myCriteria);
1634   aCommonPrt.AppendRange2(U2 - myCriteria, U2 + myCriteria);
1635   aCommonPrt.SetType(TopAbs_VERTEX);
1636   aCommonPrt.SetVertexParameter1(U1);
1637   aCommonPrt.SetVertexParameter2(U2);
1638   mySeqOfCommonPrts.Append(aCommonPrt);
1639   
1640 }