0024751: Performance improvements in the Edge/Edge intersection algorithm
[occt.git] / src / IntTools / IntTools_EdgeFace.cxx
1 // Created on: 2001-02-26
2 // Created by: Peter KURNEV
3 // Copyright (c) 2001-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 under
8 // the terms of the GNU Lesser General Public License 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_EdgeFace.ixx>
17
18
19
20 #include <IntTools_CArray1OfReal.hxx>
21 #include <IntTools.hxx>
22 #include <IntTools_CArray1OfInteger.hxx>
23 #include <IntTools_Range.hxx>
24 #include <IntTools_Tools.hxx>
25 #include <IntTools_Array1OfRange.hxx>
26 #include <IntTools_QuickSortRange.hxx>
27 #include <IntTools_CompareRange.hxx>
28 #include <IntTools_CommonPrt.hxx>
29 #include <IntTools_Root.hxx>
30 #include <IntTools_BeanFaceIntersector.hxx>
31 #include <BOPInt_Context.hxx>
32
33 #include <BRep_Tool.hxx>
34
35 #include <GeomAdaptor_Surface.hxx>
36 #include <GeomAdaptor_Curve.hxx>
37
38 #include <Geom_Surface.hxx>
39 #include <Geom_Curve.hxx>
40
41 #include <GeomAPI_ProjectPointOnSurf.hxx>
42
43 #include <Precision.hxx>
44
45 #include <Bnd_Box.hxx>
46 #include <BndLib_AddSurface.hxx>
47
48 #include <gp_Cylinder.hxx>
49 #include <gp_Ax1.hxx>
50 #include <gp_Lin.hxx>
51 #include <gp_Cone.hxx>
52 #include <gp_Torus.hxx>
53 #include <gp_Circ.hxx>
54 #include <gp_Pln.hxx>
55
56
57 #include <Extrema_ExtCS.hxx>
58 #include <Extrema_POnCurv.hxx>
59 #include <Extrema_POnSurf.hxx>
60
61 // modified by NIZHNY-MKK  Thu Jul 21 11:35:59 2005
62 #include <IntCurveSurface_HInter.hxx>
63 #include <GeomAdaptor_HCurve.hxx>
64 #include <GeomAdaptor_HSurface.hxx>
65 #include <IntCurveSurface_IntersectionPoint.hxx>
66
67 #ifdef WNT
68 #pragma warning ( disable : 4101 )
69 #endif
70
71 static
72   Standard_Boolean IsCoplanar (const BRepAdaptor_Curve&  ,
73                                const BRepAdaptor_Surface& );
74 static
75   Standard_Boolean IsRadius (const BRepAdaptor_Curve& aCurve ,
76                              const BRepAdaptor_Surface& aSurface);
77 static
78   Standard_Integer AdaptiveDiscret (const Standard_Integer iDiscret,
79                                     const BRepAdaptor_Curve& aCurve ,
80                                     const BRepAdaptor_Surface& aSurface);
81
82 //=======================================================================
83 //function : IntTools_EdgeFace::IntTools_EdgeFace
84 //purpose  : 
85 //=======================================================================
86   IntTools_EdgeFace::IntTools_EdgeFace()
87 {
88   myTolE=1.e-7;
89   myTolF=1.e-7;
90   myDiscret=30;
91   myEpsT   =1e-12;
92   myEpsNull=1e-12;
93   myDeflection=0.01;
94   myIsDone=Standard_False;
95   myErrorStatus=1;
96   myParallel=Standard_False;
97   myPar1=0.;
98 }
99 //=======================================================================
100 //function : SetContext
101 //purpose  : 
102 //=======================================================================
103 void IntTools_EdgeFace::SetContext(const Handle(BOPInt_Context)& theContext) 
104 {
105   myContext = theContext;
106 }
107
108 //=======================================================================
109 //function : Context
110 //purpose  : 
111 //=======================================================================
112 const Handle(BOPInt_Context)& IntTools_EdgeFace::Context()const 
113 {
114   return myContext;
115 }
116 //=======================================================================
117 //function : SetEdge
118 //purpose  : 
119 //=======================================================================
120   void IntTools_EdgeFace::SetEdge(const TopoDS_Edge& anEdge)
121 {
122   myEdge=anEdge;
123 }
124
125 //=======================================================================
126 //function : SetFace
127 //purpose  : 
128 //=======================================================================
129   void IntTools_EdgeFace::SetFace(const TopoDS_Face& aFace)
130 {
131   myFace=aFace;
132 }
133
134 //=======================================================================
135 //function : SetTolE
136 //purpose  : 
137 //=======================================================================
138   void IntTools_EdgeFace::SetTolE(const Standard_Real aTol) 
139 {
140   myTolE=aTol;
141
142 //=======================================================================
143 //function : SetTolF
144 //purpose  : 
145 //=======================================================================
146   void IntTools_EdgeFace::SetTolF(const Standard_Real aTol) 
147 {
148   myTolF=aTol;
149
150
151 //=======================================================================
152 //function : SetDiscretize
153 //purpose  : 
154 //=======================================================================
155   void IntTools_EdgeFace::SetDiscretize(const Standard_Integer aDiscret)
156 {
157   myDiscret=aDiscret;
158 }
159 //=======================================================================
160 //function : SetDeflection
161 //purpose  : 
162 //=======================================================================
163   void IntTools_EdgeFace::SetDeflection(const Standard_Real aDefl) 
164 {
165   myDeflection=aDefl;
166
167 //=======================================================================
168 //function : SetEpsilonT
169 //purpose  : 
170 //=======================================================================
171   void IntTools_EdgeFace::SetEpsilonT(const Standard_Real anEpsT) 
172 {
173   myEpsT=anEpsT;
174
175 //=======================================================================
176 //function : SetEpsilonNull
177 //purpose  : 
178 //=======================================================================
179   void IntTools_EdgeFace::SetEpsilonNull(const Standard_Real anEpsNull) 
180 {
181   myEpsNull=anEpsNull;
182
183
184 //=======================================================================
185 //function : SetRange
186 //purpose  : 
187 //=======================================================================
188   void IntTools_EdgeFace::SetRange(const Standard_Real aFirst,
189                                    const Standard_Real aLast) 
190 {
191   myRange.SetFirst (aFirst);
192   myRange.SetLast  (aLast);
193
194
195 //=======================================================================
196 //function : SetRange
197 //purpose  : 
198 //=======================================================================
199   void IntTools_EdgeFace::SetRange(const IntTools_Range& aRange) 
200 {
201   myRange.SetFirst (aRange.First());
202   myRange.SetLast  (aRange.Last());
203
204 //=======================================================================
205 //function : IsDone
206 //purpose  : 
207 //=======================================================================
208 Standard_Boolean IntTools_EdgeFace::IsDone()const 
209 {
210   return myIsDone;
211
212 //=======================================================================
213 //function : ErrorStatus
214 //purpose  : 
215 //=======================================================================
216 Standard_Integer IntTools_EdgeFace::ErrorStatus()const 
217 {
218   return myErrorStatus;
219 }
220 //=======================================================================
221 //function : CommonParts
222 //purpose  : 
223 //=======================================================================
224 const IntTools_SequenceOfCommonPrts& IntTools_EdgeFace::CommonParts() const 
225 {
226   return mySeqOfCommonPrts;
227 }
228 //=======================================================================
229 //function : Range
230 //purpose  : 
231 //=======================================================================
232 const IntTools_Range&  IntTools_EdgeFace::Range() const
233 {
234   return myRange;
235
236
237 //=======================================================================
238 //function : CheckData
239 //purpose  : 
240 //=======================================================================
241 void IntTools_EdgeFace::CheckData()
242 {
243   if (BRep_Tool::Degenerated(myEdge)) {
244     myErrorStatus=2;
245   }
246   if (!BRep_Tool::IsGeometric(myEdge)) { 
247      myErrorStatus=3;
248   }
249 }
250 //=======================================================================
251 //function : Prepare
252 //purpose  : 
253 //=======================================================================
254   void IntTools_EdgeFace::Prepare() 
255 {
256   Standard_Integer pri;
257   IntTools_CArray1OfReal aPars;
258  
259   //
260   // 1.Prepare Curve's data and Surface's data
261   myC.Initialize(myEdge);
262   GeomAbs_CurveType aCurveType;
263   aCurveType=myC.GetType();
264   //
265   // 2.Prepare myCriteria
266   if (aCurveType==GeomAbs_BSplineCurve||
267         aCurveType==GeomAbs_BezierCurve) {
268     myCriteria=1.5*myTolE+myTolF;
269   }
270   else {
271     myCriteria=myTolE+myTolF;
272   }
273   // 2.a myTmin, myTmax
274   myTmin=myRange.First();
275   myTmax=myRange.Last();
276   // 2.b myFClass2d
277   myS.Initialize (myFace,Standard_True);
278   myFClass2d.Init(myFace, 1.e-6);
279   //
280   // 2.c Prepare adaptive myDiscret
281   myDiscret=AdaptiveDiscret(myDiscret, myC, myS);
282   //
283   //
284   // 3.Prepare myPars 
285   pri = IntTools::PrepareArgs(myC, myTmax, myTmin, myDiscret, myDeflection, aPars);
286   if (pri) {
287     myErrorStatus=6;
288     return;
289   }
290   // 4.
291   //ProjectableRanges
292   Standard_Integer i, iProj, aNb, aNbProj, ind0, ind1;
293   Standard_Real t0, t1, tRoot;
294   
295   //
296   // Table of Projection's function values
297   aNb=aPars.Length();
298   IntTools_CArray1OfInteger anArrProjectability;
299   anArrProjectability.Resize(aNb);
300   
301   for (iProj=0, i=0; i<aNb; i++) {
302     t0=aPars(i);
303     aNbProj=IsProjectable (t0); 
304     
305     anArrProjectability(i)=0;
306     if (aNbProj) {
307       anArrProjectability(i)=1;
308       iProj++;
309     }
310   }
311   //
312   // Checking
313   if (!iProj ) {
314     myErrorStatus=7;
315     return;
316   }
317   
318   //
319   // Projectable Ranges
320   IntTools_Range aRange;
321   
322   ind0=anArrProjectability(0);
323   if (ind0) {
324     t0=aPars(0);
325     aRange.SetFirst(t0);
326   }
327   
328   for(i=1; i<aNb; i++) {
329     ind1=anArrProjectability(i);
330     t0=aPars(i-1);
331     t1=aPars(i);
332
333     if (i==(aNb-1)) {
334       if (ind1 && ind0) {
335         aRange.SetLast(t1);
336         myProjectableRanges.Append(aRange);
337       }
338       if (ind1 && !ind0) {
339         FindProjectableRoot(t0, t1, ind0, ind1, tRoot);
340         aRange.SetFirst(tRoot);
341         aRange.SetLast(t1);
342         myProjectableRanges.Append(aRange);
343       }
344       //
345       if (ind0 && !ind1) {
346         FindProjectableRoot(t0, t1, ind0, ind1, tRoot);
347         aRange.SetLast(tRoot);
348         myProjectableRanges.Append(aRange);
349       }
350       //
351       break;
352     }
353     
354     if (ind0 != ind1) {
355       FindProjectableRoot(t0, t1, ind0, ind1, tRoot);
356       
357       if (ind0 && !ind1) {
358         aRange.SetLast(tRoot);
359         myProjectableRanges.Append(aRange);
360       }
361       else {
362         aRange.SetFirst(tRoot);
363       }
364     } // if (ind0 != ind1)
365     ind0=ind1;
366   } // for(i=1; i<aNb; i++) {
367 }
368
369 //=======================================================================
370 //function : FindProjectableRoot
371 //purpose  : 
372 //=======================================================================
373   void IntTools_EdgeFace::FindProjectableRoot (const Standard_Real tt1,
374                                                const Standard_Real tt2,
375                                                const Standard_Integer ff1,
376                                                const Standard_Integer ff2,
377                                                Standard_Real& tRoot)
378 {
379   Standard_Real tm, t1, t2, aEpsT;
380   Standard_Integer anIsProj1, anIsProj2, anIsProjm;
381   aEpsT=0.5*myEpsT;
382   //
383   // Root is inside [tt1, tt2]
384   t1=tt1;  
385   t2=tt2;
386   anIsProj1=ff1;
387   anIsProj2=ff2;
388   
389   for(;;) {
390     if (fabs(t1-t2) < aEpsT) {
391       tRoot=(anIsProj1) ? t1 : t2;
392       return;
393     }
394     tm=.5*(t1+t2);
395     anIsProjm=IsProjectable(tm);
396     
397     if (anIsProjm != anIsProj1) {
398       t2=tm;
399       anIsProj2=anIsProjm;
400     }
401     else {
402       t1=tm;
403       anIsProj1=anIsProjm;
404     }
405   }
406 }
407 //=======================================================================
408 //function : IsProjectable
409 //purpose  : 
410 //=======================================================================
411 Standard_Boolean IntTools_EdgeFace::IsProjectable(const Standard_Real aT) const
412 {
413   Standard_Boolean bFlag; 
414   gp_Pnt aPC;
415   //
416   myC.D0(aT, aPC);
417   bFlag=myContext->IsValidPointForFace(aPC, myFace, myCriteria);
418   //
419   return bFlag;
420 }
421 //=======================================================================
422 //function : DistanceFunction
423 //purpose  : 
424 //=======================================================================
425 Standard_Real IntTools_EdgeFace::DistanceFunction(const Standard_Real t)
426 {
427   Standard_Real aD;
428
429   //
430   gp_Pnt P;
431   myC.D0(t, P);
432   //
433   Standard_Boolean bIsEqDistance;
434
435   bIsEqDistance= IntTools_EdgeFace::IsEqDistance(P, myS, 1.e-7, aD); 
436   if (bIsEqDistance) {
437     aD=aD-myCriteria;
438     return aD; 
439   }
440   
441   //
442   Standard_Boolean bFlag = Standard_False;
443
444   GeomAPI_ProjectPointOnSurf& aLocProj = myContext->ProjPS(myFace);
445   aLocProj.Perform(P);
446   bFlag = aLocProj.IsDone();
447   
448   if(bFlag) {
449     aD = aLocProj.LowerDistance();
450   }
451   //
452   
453   if (!bFlag) {
454     myErrorStatus=11;
455     return 99.;
456   }
457   
458   // 
459   //   aD=aProjector.LowerDistance();
460   // 
461   aD=aD-myCriteria;
462   return aD; 
463 }
464 //
465 //=======================================================================
466 //function : IsEqDistance
467 //purpose  : 
468 //=======================================================================
469   Standard_Boolean IntTools_EdgeFace::IsEqDistance(const gp_Pnt& aP,
470                                                    const BRepAdaptor_Surface& aBAS,
471                                                    const Standard_Real aTol,
472                                                    Standard_Real& aD)
473 {
474   Standard_Boolean bRetFlag=Standard_True;
475
476   GeomAbs_SurfaceType aSurfType=aBAS.GetType();
477
478   if (aSurfType==GeomAbs_Cylinder) {
479     gp_Cylinder aCyl=aBAS.Cylinder();
480     const gp_Ax1& anAx1  =aCyl.Axis();
481     gp_Lin aLinAxis(anAx1);
482     Standard_Real aDC, aRadius=aCyl.Radius();
483     aDC=aLinAxis.Distance(aP);
484     if (aDC < aTol) {
485       aD=aRadius;
486       return bRetFlag; 
487     }
488   }
489
490   if (aSurfType==GeomAbs_Cone) {
491     gp_Cone aCone=aBAS.Cone();
492     const gp_Ax1& anAx1  =aCone.Axis();
493     gp_Lin aLinAxis(anAx1);
494     Standard_Real aDC, aRadius, aDS, aSemiAngle;
495     aDC=aLinAxis.Distance(aP);
496     if (aDC < aTol) {
497       gp_Pnt anApex=aCone.Apex();
498       aSemiAngle=aCone.SemiAngle();
499       aDS=aP.Distance(anApex);
500       
501       aRadius=aDS*tan(aSemiAngle);
502       aD=aRadius;
503       return bRetFlag; 
504     }
505   }
506
507   if (aSurfType==GeomAbs_Torus) {
508     Standard_Real aMajorRadius, aMinorRadius, aDC;
509
510     gp_Torus aTorus=aBAS.Torus();
511     gp_Pnt aPLoc=aTorus.Location();
512     aMajorRadius=aTorus.MajorRadius();
513     
514     aDC=fabs(aPLoc.Distance(aP)-aMajorRadius);
515     if (aDC < aTol) {
516       aMinorRadius=aTorus.MinorRadius();
517       aD=aMinorRadius;
518       return bRetFlag; 
519     }
520   }
521   return !bRetFlag; 
522 }
523 //
524 //=======================================================================
525 //function : PrepareArgsFuncArrays
526 //purpose  : Obtain 
527 //           myFuncArray and myArgsArray for the interval [ta, tb]
528 //=======================================================================               
529   void IntTools_EdgeFace::PrepareArgsFuncArrays(const Standard_Real ta,
530                                                 const Standard_Real tb)
531 {
532   IntTools_CArray1OfReal anArgs, aFunc;
533   Standard_Integer i, aNb, pri;
534   Standard_Real t, f, f1;
535   //
536   // Prepare values of arguments for the interval [ta, tb]
537   pri=IntTools::PrepareArgs (myC, tb, ta, myDiscret, myDeflection, anArgs);
538   
539   if (pri) {
540     myErrorStatus=8;
541     return;
542   }
543   //...
544   aNb=anArgs.Length();
545
546   if (!aNb){
547     myErrorStatus=9;
548     return;
549   }
550   //
551   // Prepare values of functions for the interval [ta, tb]
552   aFunc.Resize(aNb);
553   for (i=0; i<aNb; i++) {
554     t=anArgs(i);
555     f1=DistanceFunction(t);
556     f=f1+myCriteria; 
557
558     if (myErrorStatus==11)
559       return;
560     
561     if (f1 < myEpsNull) { 
562       f=0.;
563     }
564     aFunc(i)=f;
565   }
566   //
567   // Add points where the derivative = 0  
568   AddDerivativePoints(anArgs, aFunc);
569
570 }
571
572
573 //=======================================================================
574 //function : AddDerivativePoints
575 //purpose  : 
576 //=======================================================================
577   void IntTools_EdgeFace::AddDerivativePoints(const IntTools_CArray1OfReal& t,
578                                               const IntTools_CArray1OfReal& f)  
579 {
580   Standard_Integer i, j, n, k, nn=100;
581   Standard_Real fr, tr, tr1, dEpsNull=10.*myEpsNull;
582   IntTools_CArray1OfReal fd;
583   TColStd_SequenceOfReal aTSeq, aFSeq;  
584
585   n=t.Length();
586   fd.Resize(n+1);
587   //
588   // Table of derivatives
589   Standard_Real dfx, tx, tx1, fx, fx1, dt=1.e-6;
590   // Left limit
591   tx=t(0);
592   tx1=tx+dt;
593   fx=f(0);
594   fx1=DistanceFunction(tx1);
595   fx1=fx1+myCriteria;
596   if (fx1 < myEpsNull) { 
597     fx1=0.;
598   }
599   dfx=(fx1-fx)/dt;
600   fd(0)=dfx;
601   
602   if (fabs(fd(0)) < dEpsNull){
603     fd(0)=0.;
604   }
605   
606
607   k=n-1;
608   for (i=1; i<k; i++) {
609     fd(i)=.5*(f(i+1)-f(i-1))/(t(i)-t(i-1));
610     if (fabs(fd(i)) < dEpsNull){
611       fd(i)=0.;
612     }
613   }
614   // Right limit
615   tx=t(n-1);
616   tx1=tx-dt;
617   fx=f(n-1);
618   fx1=DistanceFunction(tx1);
619   fx1=fx1+myCriteria;
620   if (fx1 < myEpsNull) { 
621     fx1=0.;
622   }
623   dfx=(fx-fx1)/dt;
624   fd(n-1)=dfx;
625   
626   if (fabs(fd(n-1)) < dEpsNull){
627     fd(n-1)=0.;
628   }
629   //
630   // Finding the range where the derivatives have different signs
631   // for neighbouring points
632   for (i=1; i<n; i++) {
633     Standard_Real fd1, fd2, t1, t2;
634     t1 =t(i-1);
635     t2 =t(i);
636     fd1=fd(i-1);
637     fd2=fd(i);
638
639     if (fd1*fd2 < 0.) {
640       if (fabs(fd1) < myEpsNull) {
641         tr=t1;
642         fr=DistanceFunction(tr);//fd1;
643       }
644       else if (fabs(fd2) < myEpsNull) {
645         tr=t2;
646         fr=DistanceFunction(tr);
647       }
648       else {
649         tr=FindSimpleRoot(2, t1, t2, fd1);
650         fr=DistanceFunction(tr);
651       }
652       
653       aTSeq.Append(tr);
654       aFSeq.Append(fr);
655     }
656   } // end of for (i=1; i<n; i++)
657   //
658   // remove identical t, f
659   nn=aTSeq.Length();
660   if (nn) {
661     for (i=1; i<=aTSeq.Length(); i++) {
662       tr=aTSeq(i);
663       for (j=0; j<n; j++) {
664         tr1=t(j);
665         if (fabs (tr1-tr) < myEpsT) {
666           aTSeq.Remove(i);
667           aFSeq.Remove(i);
668         }
669       }
670     }
671     nn=aTSeq.Length();
672   }
673   //
674   // sorting args and funcs in increasing order
675   if (nn) {
676     k=nn+n;
677     IntTools_Array1OfRange anArray1OfRange(1, k);
678     for (i=1; i<=n; i++) {
679       anArray1OfRange(i).SetFirst(t(i-1));
680       anArray1OfRange(i).SetLast (f(i-1));
681     }
682     for (i=1; i<=nn; i++) {
683       anArray1OfRange(n+i).SetFirst(aTSeq(i));
684       anArray1OfRange(n+i).SetLast (aFSeq(i));
685     }
686     
687     IntTools_QuickSortRange aQuickSortRange;
688     IntTools_CompareRange aComparator;
689     aQuickSortRange.Sort (anArray1OfRange, aComparator);
690     
691     // filling the  output arrays
692     myArgsArray.Resize(k);
693     myFuncArray.Resize(k);
694     for (i=1; i<=k; i++) {
695       myArgsArray(i-1)=anArray1OfRange(i).First();
696       myFuncArray(i-1)=anArray1OfRange(i).Last ();
697     }
698   }
699   
700   else { // nn=0
701     myArgsArray.Resize(n);
702     myFuncArray.Resize(n);
703     for (i=0; i<n; i++) {
704       myArgsArray(i)=t(i); 
705       myFuncArray(i)=f(i); 
706     }
707   }
708 }
709
710 //=======================================================================
711 //function : DerivativeFunction
712 //purpose  : 
713 //=======================================================================
714   Standard_Real IntTools_EdgeFace::DerivativeFunction(const Standard_Real t2)
715 {
716   Standard_Real t1, t3, aD1, aD2, aD3;
717   Standard_Real dt=1.e-9;
718   t1=t2-dt;
719   aD1=DistanceFunction(t1);
720   t3=t2+dt;
721   aD3=DistanceFunction(t3);
722   
723   aD2=.5*(aD3-aD1)/dt;
724   return aD2; 
725 }
726
727 //=======================================================================
728 //function : FindSimpleRoot
729 //purpose  : [private]
730 //=======================================================================
731   Standard_Real IntTools_EdgeFace::FindSimpleRoot (const Standard_Integer IP,
732                                                    const Standard_Real tA,
733                                                    const Standard_Real tB,
734                                                    const Standard_Real fA)
735 {
736   Standard_Real r, a, b, y, x0, s;
737   
738   a=tA; b=tB; r=fA;
739   
740   for(;;) {
741     x0=.5*(a+b);
742
743     if (IP==1)
744       y=DistanceFunction(x0);
745     else 
746       y=DerivativeFunction(x0);
747     
748     if (fabs(b-a) < myEpsT || y==0.) {
749       return x0;
750     }
751     
752         
753     s=y*r;
754
755     if (s<0.) {
756       b=x0;
757       continue;
758     }
759
760     if (s>0.) {
761       a=x0; r=y;
762     }
763   }
764 }
765 //=======================================================================
766 //function : FindGoldRoot
767 //purpose  : [private]
768 //=======================================================================
769   Standard_Real IntTools_EdgeFace::FindGoldRoot (const Standard_Real tA,
770                                                  const Standard_Real tB,
771                                                  const Standard_Real coeff)
772 {
773   Standard_Real gs=0.61803399;
774   Standard_Real a, b, xp, xl, yp, yl;
775
776   a=tA;  b=tB;
777   
778   xp=a+(b-a)*gs;
779   xl=b-(b-a)*gs;
780   yp=coeff*DistanceFunction(xp);
781   yl=coeff*DistanceFunction(xl);
782   
783  
784   for(;;) {
785     
786     if (fabs(b-a) < myEpsT) {
787       return .5*(b+a);
788     }
789     
790     if (yp < yl) {
791       a=xl;
792       xl=xp;
793       xp=a+(b-a)*gs;
794       yp=coeff*DistanceFunction(xp);
795     }
796     
797     else {
798       b=xp;
799       xp=xl;
800       yp=yl;
801       xl=b-(b-a)*gs;
802       yl=coeff*DistanceFunction(xl);
803     }
804   }
805 }  
806
807 //=======================================================================
808 //function : MakeType
809 //purpose  : 
810 //=======================================================================
811   Standard_Integer IntTools_EdgeFace::MakeType(IntTools_CommonPrt&  aCommonPrt)
812 {
813   Standard_Real  af1, al1;
814   Standard_Real  df1, tm;
815   Standard_Boolean bAllNullFlag;
816   //
817   bAllNullFlag=aCommonPrt.AllNullFlag();
818   if (bAllNullFlag) {
819     aCommonPrt.SetType(TopAbs_EDGE);
820     return 0;
821   }
822   //
823   aCommonPrt.Range1(af1, al1);
824
825   {
826     gp_Pnt aPF, aPL;
827     myC.D0(af1, aPF);
828     myC.D0(al1, aPL);
829     df1=aPF.Distance(aPL);
830     Standard_Boolean isWholeRange = Standard_False;
831     
832     if((Abs(af1 - myRange.First()) < myC.Resolution(myCriteria)) &&
833        (Abs(al1 - myRange.Last()) < myC.Resolution(myCriteria)))
834       isWholeRange = Standard_True;
835
836     
837     if ((df1 > myCriteria * 2.) && isWholeRange) {
838       aCommonPrt.SetType(TopAbs_EDGE);
839     }
840     else {
841       if(isWholeRange) {
842         tm = (af1 + al1) * 0.5;
843
844         if(aPF.Distance(myC.Value(tm)) > myCriteria * 2.) {
845           aCommonPrt.SetType(TopAbs_EDGE);
846           return 0;
847         }
848       }
849
850       if(!CheckTouch(aCommonPrt, tm)) {
851         tm = (af1 + al1) * 0.5;
852       }
853       aCommonPrt.SetType(TopAbs_VERTEX);
854       aCommonPrt.SetVertexParameter1(tm);
855       aCommonPrt.SetRange1 (af1, al1);
856     }
857          return 0;
858   }
859   
860   /*
861   dt=al1-af1;
862   if (dt<1.e-5) {
863     gp_Pnt aPF, aPL;
864     myC.D0(af1, aPF);
865     myC.D0(al1, aPL);
866     df1=aPF.Distance(aPL);
867     if (df1<myCriteria) {
868       //
869       tm=.5*(af1+al1);
870       aCommonPrt.SetType(TopAbs_VERTEX);
871       aCommonPrt.SetVertexParameter1(tm);
872       aCommonPrt.SetRange1 (af1, al1);
873       return 0;
874     }
875   }
876   //
877   IsIntersection (af1, al1);
878   //
879   if (!myParallel) {
880     aCommonPrt.SetType(TopAbs_VERTEX);
881     aCommonPrt.SetVertexParameter1(myPar1);
882     aCommonPrt.SetRange1 (af1, al1);
883   }
884   else {
885     dt=al1-af1;
886     if (dt<1.e-5) {
887       df1=DistanceFunction(af1);
888       df2=DistanceFunction(al1);
889       tm=(df1 < df2) ? af1 : al1;
890       aCommonPrt.SetType(TopAbs_VERTEX);
891       aCommonPrt.SetVertexParameter1(tm);
892       aCommonPrt.SetRange1 (af1, al1);
893     }
894
895     else {
896       aCommonPrt.SetType(TopAbs_EDGE);
897     }
898   }
899
900   return 0;*/
901 }
902
903
904 //=======================================================================
905 //function : IsIntersection
906 //purpose  : 
907 //=======================================================================
908   void IntTools_EdgeFace::IsIntersection (const Standard_Real ta, 
909                                           const Standard_Real tb) 
910 {
911   IntTools_CArray1OfReal anArgs, aFunc;
912   Standard_Integer i, aNb, aCnt=0;
913   //
914   Standard_Integer aCntIncreasing=1, aCntDecreasing=1;
915   Standard_Real t, f, f1;
916   //
917   // Prepare values of arguments for the interval [ta, tb]
918   IntTools::PrepareArgs (myC, tb, ta, myDiscret, myDeflection, anArgs);
919   aNb=anArgs.Length();
920   
921   aFunc.Resize(aNb);
922   for (i=0; i<aNb; i++) {
923     t=anArgs(i);
924     
925     f1=DistanceFunction(t);
926     f=f1+myCriteria; 
927
928     if (fabs(f1) < myEpsNull) { 
929       aCnt++;
930       f=0.;
931     }
932     aFunc(i)=f;
933     //
934     if (i) {
935       if (aFunc(i)>aFunc(i-1)) {
936         aCntIncreasing++;
937       }
938       if (aFunc(i)<aFunc(i-1)) {
939         aCntDecreasing++;
940       }
941     }
942     //
943   }
944
945   if (aCnt==aNb) {
946     myParallel=Standard_True;
947     return;
948   }
949   
950   FindDerivativeRoot(anArgs, aFunc);
951
952   //
953   if (myParallel) {
954     if (!(myC.GetType()==GeomAbs_Line 
955           && 
956           myS.GetType()==GeomAbs_Cylinder)) {
957       if (aCntDecreasing==aNb) {
958         myPar1=anArgs(aNb-1);
959         myParallel=Standard_False;
960       }
961       if (aCntIncreasing==aNb) {
962         myPar1=anArgs(0);
963         myParallel=Standard_False;
964       }
965     }
966   }
967   //
968   return ;
969 }
970
971 //=======================================================================
972 //function : FindDerivativeRoot
973 //purpose  : 
974 //=======================================================================
975   void IntTools_EdgeFace::FindDerivativeRoot(const IntTools_CArray1OfReal& t,
976                                              const IntTools_CArray1OfReal& f)  
977 {
978   Standard_Integer i, n, k;
979   Standard_Real tr;
980   IntTools_CArray1OfReal fd;
981   TColStd_SequenceOfReal aTSeq, aFSeq;  
982   
983   myPar1=0.;
984   myParallel=Standard_True;
985   
986   n=t.Length();
987   fd.Resize(n+1);
988   //
989   // Table of derivatives
990   fd(0)=(f(1)-f(0))/(t(1)-t(0));
991   if (fabs(fd(0)) < myEpsNull) {
992     fd(0)=0.;
993   }
994
995   k=n-1;
996   for (i=1; i<k; i++) {
997     fd(i)=.5*(f(i+1)-f(i-1))/(t(i)-t(i-1));
998     if (fabs(fd(i)) < myEpsNull) {
999       fd(i)=0.;
1000     }
1001   }
1002
1003   fd(n-1)=(f(n-1)-f(n-2))/(t(n-1)-t(n-2));
1004   if (fabs(fd(n-1)) < myEpsNull) {
1005     fd(n-1)=0.;
1006   }
1007   //
1008   // Finding the range where the derivatives have different signs
1009   // for neighbouring points
1010   for (i=1; i<n; i++) {
1011     Standard_Real fd1, fd2, t1, t2, fabsfd1, fabsfd2;
1012     Standard_Boolean bF1, bF2;
1013     t1 =t(i-1);
1014     t2 =t(i);
1015     fd1=fd(i-1);
1016     fd2=fd(i);
1017
1018     fabsfd1=fabs(fd1);
1019     bF1=fabsfd1 < myEpsNull;
1020     
1021     fabsfd2=fabs(fd2);
1022     bF2=fabsfd2 < myEpsNull;
1023     //
1024     if (fd1*fd2 < 0.) {
1025       tr=FindSimpleRoot(2, t1, t2, fd1);
1026       DistanceFunction(tr);
1027       myPar1=tr;
1028       myParallel=Standard_False;
1029       break;
1030     }
1031     
1032     if (!bF1 && bF2) {
1033       tr=t2;
1034       myPar1=tr;
1035       myParallel=Standard_False;
1036       break;
1037     }
1038     
1039     if (bF1 && !bF2) {
1040       tr=t1;
1041       myPar1=tr;
1042       myParallel=Standard_False;
1043       break;
1044     }
1045
1046   }
1047 }
1048 //=======================================================================
1049 //function : RemoveIdenticalRoots 
1050 //purpose  : 
1051 //=======================================================================
1052   void IntTools_EdgeFace::RemoveIdenticalRoots()
1053 {
1054   Standard_Integer aNbRoots, j, k;
1055
1056   aNbRoots=mySequenceOfRoots.Length();
1057   for (j=1; j<=aNbRoots; j++) { 
1058     const IntTools_Root& aRj=mySequenceOfRoots(j);
1059     for (k=j+1; k<=aNbRoots; k++) {
1060       const IntTools_Root& aRk=mySequenceOfRoots(k);
1061       
1062       Standard_Real aTj, aTk, aDistance;
1063       gp_Pnt aPj, aPk;
1064
1065       aTj=aRj.Root();
1066       aTk=aRk.Root();
1067
1068       myC.D0(aTj, aPj);
1069       myC.D0(aTk, aPk);
1070
1071       aDistance=aPj.Distance(aPk);
1072       if (aDistance < myCriteria) {
1073         mySequenceOfRoots.Remove(k);
1074         aNbRoots=mySequenceOfRoots.Length();
1075       }
1076     }
1077   }
1078 }
1079
1080 //=======================================================================
1081 //function : CheckTouch 
1082 //purpose  : 
1083 //=======================================================================
1084   Standard_Boolean IntTools_EdgeFace::CheckTouch(const IntTools_CommonPrt& aCP,
1085                                                  Standard_Real&            aTx) 
1086 {
1087   Standard_Real aTF, aTL, Tol, U1f, U1l, V1f, V1l, af, al,aDist2, aMinDist2;
1088   Standard_Boolean theflag=Standard_False;
1089   Standard_Integer aNbExt, i, iLower ;
1090
1091   aCP.Range1(aTF, aTL);
1092
1093   //
1094   Standard_Real aCR;
1095   aCR=myC.Resolution(myCriteria);
1096   if((Abs(aTF - myRange.First()) < aCR) &&
1097      (Abs(aTL - myRange.Last())  < aCR)) {
1098     return theflag; // EDGE 
1099   }
1100   //
1101
1102   Tol = Precision::PConfusion();
1103
1104   const Handle(Geom_Curve)&  Curve   =BRep_Tool::Curve  (myC.Edge(), af, al);
1105   const Handle(Geom_Surface)& Surface=BRep_Tool::Surface(myS.Face());
1106   //   Surface->Bounds(U1f,U1l,V1f,V1l);
1107   U1f = myS.FirstUParameter();
1108   U1l = myS.LastUParameter();
1109   V1f = myS.FirstVParameter();
1110   V1l = myS.LastVParameter();
1111   
1112   GeomAdaptor_Curve   TheCurve   (Curve,aTF, aTL);
1113   GeomAdaptor_Surface TheSurface (Surface, U1f, U1l, V1f, V1l); 
1114                                  
1115   Extrema_ExtCS anExtrema (TheCurve, TheSurface, Tol, Tol);
1116
1117   aDist2 = 1.e100;
1118
1119   if(anExtrema.IsDone()) {
1120     aMinDist2 = aDist2;
1121
1122     if(!anExtrema.IsParallel()) {
1123       aNbExt=anExtrema.NbExt();
1124       
1125       if(aNbExt > 0) {
1126         iLower=1;
1127         for (i=1; i<=aNbExt; i++) {
1128           aDist2=anExtrema.SquareDistance(i);
1129           if (aDist2 < aMinDist2) {
1130             aMinDist2=aDist2;
1131             iLower=i;
1132           }
1133         }
1134         aDist2=anExtrema.SquareDistance(iLower);
1135         Extrema_POnCurv aPOnC;
1136         Extrema_POnSurf aPOnS;
1137         anExtrema.Points(iLower, aPOnC, aPOnS);
1138         aTx=aPOnC.Parameter();
1139       }
1140       else {
1141         // modified by NIZHNY-MKK  Thu Jul 21 11:35:32 2005.BEGIN
1142         IntCurveSurface_HInter anExactIntersector;
1143   
1144         Handle(GeomAdaptor_HCurve) aCurve     = new GeomAdaptor_HCurve(TheCurve);
1145         Handle(GeomAdaptor_HSurface) aSurface = new GeomAdaptor_HSurface(TheSurface);
1146         
1147         anExactIntersector.Perform(aCurve, aSurface);
1148
1149         if(anExactIntersector.IsDone()) {
1150           Standard_Integer i = 0;
1151
1152           for(i = 1; i <= anExactIntersector.NbPoints(); i++) {
1153             const IntCurveSurface_IntersectionPoint& aPoint = anExactIntersector.Point(i);
1154       
1155             if((aPoint.W() >= aTF) && (aPoint.W() <= aTL)) {
1156               aDist2=0.;
1157               aTx = aPoint.W();
1158             }
1159           }
1160         }
1161         // modified by NIZHNY-MKK  Thu Jul 21 11:35:40 2005.END
1162       }
1163     }
1164     else {
1165       return theflag;
1166     }
1167   }
1168
1169   Standard_Real aBoundaryDist;
1170
1171   aBoundaryDist = DistanceFunction(aTF) + myCriteria;
1172   if(aBoundaryDist * aBoundaryDist < aDist2) {
1173     aDist2 = aBoundaryDist * aBoundaryDist;
1174     aTx = aTF;
1175   }
1176   
1177   aBoundaryDist = DistanceFunction(aTL) + myCriteria;
1178   if(aBoundaryDist * aBoundaryDist < aDist2) {
1179     aDist2 = aBoundaryDist * aBoundaryDist;
1180     aTx = aTL;
1181   }
1182
1183   Standard_Real aParameter = (aTF + aTL) * 0.5;
1184   aBoundaryDist = DistanceFunction(aParameter) + myCriteria;
1185   if(aBoundaryDist * aBoundaryDist < aDist2) {
1186     aDist2 = aBoundaryDist * aBoundaryDist;
1187     aTx = aParameter;
1188   }
1189
1190   if(aDist2 > myCriteria * myCriteria) {
1191     return theflag;
1192   }
1193   
1194   if (fabs (aTx-aTF) < myEpsT) {
1195     return !theflag;
1196   }
1197
1198   if (fabs (aTx-aTL) < myEpsT) {
1199     return !theflag;
1200   }
1201
1202   if (aTx>aTF && aTx<aTL) {
1203     return !theflag;
1204   }
1205
1206   return theflag;
1207 }
1208
1209
1210 //=======================================================================
1211 //function : Perform
1212 //purpose  : 
1213 //=======================================================================
1214   void IntTools_EdgeFace::Perform() 
1215 {
1216   Standard_Integer i, aNb;
1217   IntTools_CommonPrt aCommonPrt;
1218   //
1219   aCommonPrt.SetEdge1(myEdge);
1220   //
1221   myErrorStatus=0;
1222   CheckData();
1223   if (myErrorStatus) {
1224     return;
1225   }
1226   //
1227   if (myContext.IsNull()) {
1228     myContext=new BOPInt_Context;
1229   }
1230   //
1231   myIsDone = Standard_False;
1232   myC.Initialize(myEdge);
1233   GeomAbs_CurveType aCurveType;
1234   aCurveType=myC.GetType();
1235   //
1236   // Prepare myCriteria
1237   if (aCurveType==GeomAbs_BSplineCurve||
1238         aCurveType==GeomAbs_BezierCurve) {
1239     //--- 5112
1240     Standard_Real diff1 = (myTolE/myTolF);
1241     Standard_Real diff2 = (myTolF/myTolE);
1242     if( diff1 > 100 || diff2 > 100 ) {
1243       myCriteria = Max(myTolE,myTolF);
1244     }
1245     else //--- 5112
1246       myCriteria=1.5*myTolE+myTolF;
1247   }
1248   else {
1249     myCriteria=myTolE+myTolF;
1250   }
1251
1252   myTmin=myRange.First();
1253   myTmax=myRange.Last();
1254
1255   myS.Initialize (myFace,Standard_True);
1256
1257   if(myContext.IsNull()) {
1258     myFClass2d.Init(myFace, 1.e-6);
1259   }
1260
1261   IntTools_BeanFaceIntersector anIntersector(myC, myS, myTolE, myTolF);
1262   anIntersector.SetBeanParameters(myRange.First(), myRange.Last());
1263   //
1264   anIntersector.SetContext(myContext);
1265   //
1266   anIntersector.Perform();
1267
1268   if(!anIntersector.IsDone()) {
1269     return;
1270   }
1271
1272   for(Standard_Integer r = 1; r <= anIntersector.Result().Length(); r++) {
1273     const IntTools_Range& aRange = anIntersector.Result().Value(r);
1274     
1275     if(IsProjectable(IntTools_Tools::IntermediatePoint(aRange.First(), aRange.Last()))) {
1276       aCommonPrt.SetRange1(aRange.First(), aRange.Last());
1277       mySeqOfCommonPrts.Append(aCommonPrt);
1278     }
1279   }
1280
1281   aNb = mySeqOfCommonPrts.Length();
1282
1283   for (i=1; i<=aNb; i++) {
1284     IntTools_CommonPrt& aCP=mySeqOfCommonPrts.ChangeValue(i);
1285     //
1286     Standard_Real aTx1, aTx2;
1287     gp_Pnt aPx1, aPx2;
1288     //
1289     aCP.Range1(aTx1, aTx2);
1290     myC.D0(aTx1, aPx1);
1291     myC.D0(aTx2, aPx2);
1292     aCP.SetBoundingPoints(aPx1, aPx2);
1293     //
1294     MakeType (aCP); 
1295   }
1296   {
1297     // Line\Cylinder's Common Parts treatement
1298     GeomAbs_CurveType   aCType;
1299     GeomAbs_SurfaceType aSType;
1300     TopAbs_ShapeEnum aType;
1301     Standard_Boolean bIsTouch;
1302     Standard_Real aTx;
1303
1304     aCType=myC.GetType();
1305     aSType=myS.GetType();
1306     
1307     if (aCType==GeomAbs_Line && aSType==GeomAbs_Cylinder) {
1308       for (i=1; i<=aNb; i++) {
1309         IntTools_CommonPrt& aCP=mySeqOfCommonPrts(i);
1310         aType=aCP.Type();
1311         if (aType==TopAbs_EDGE) {
1312           bIsTouch=CheckTouch (aCP, aTx);
1313           if (bIsTouch) {
1314             aCP.SetType(TopAbs_VERTEX);
1315             aCP.SetVertexParameter1(aTx);
1316             aCP.SetRange1 (aTx, aTx);
1317           }
1318         }
1319         if (aType==TopAbs_VERTEX) {
1320           bIsTouch=CheckTouchVertex (aCP, aTx);
1321           if (bIsTouch) {
1322             aCP.SetVertexParameter1(aTx);
1323             aCP.SetRange1 (aTx, aTx);
1324           }
1325         }
1326       }
1327     }
1328
1329     // Circle\Plane's Common Parts treatement
1330     
1331     if (aCType==GeomAbs_Circle && aSType==GeomAbs_Plane) {
1332       Standard_Boolean bIsCoplanar, bIsRadius;
1333       bIsCoplanar=IsCoplanar(myC, myS);
1334       bIsRadius=IsRadius(myC, myS);
1335       if (!bIsCoplanar && !bIsRadius) {
1336         for (i=1; i<=aNb; i++) {
1337           IntTools_CommonPrt& aCP=mySeqOfCommonPrts(i);
1338           aType=aCP.Type();
1339           if (aType==TopAbs_EDGE) {
1340             bIsTouch=CheckTouch (aCP, aTx);
1341             if (bIsTouch) {
1342               aCP.SetType(TopAbs_VERTEX);
1343               aCP.SetVertexParameter1(aTx);
1344               aCP.SetRange1 (aTx, aTx);
1345             }
1346           }
1347         }
1348       }
1349     }
1350   }
1351   myIsDone=Standard_True;
1352 }
1353
1354 //
1355 // myErrorStatus
1356 // 1 - the method Perform() is not invoked  
1357 // 2,3,4,5 -the method CheckData() fails
1358 // 6 - PrepareArgs() problems
1359 // 7 - No Projectable ranges
1360 // 8,9 - PrepareArgs() problems occured inside  projectable Ranges
1361 // 11 - can't fill array  aFunc(i) in PrepareArgsFuncArrays 
1362
1363
1364 //=======================================================================
1365 //function : CheckTouch 
1366 //purpose  : 
1367 //=======================================================================
1368   Standard_Boolean IntTools_EdgeFace::CheckTouchVertex (const IntTools_CommonPrt& aCP,
1369                                                         Standard_Real& aTx) 
1370 {
1371   Standard_Real aTF, aTL, Tol, U1f,U1l,V1f,V1l, af, al,aDist2, aMinDist2, aTm, aDist2New;
1372   Standard_Real aEpsT;
1373   Standard_Boolean theflag=Standard_False;
1374   Standard_Integer aNbExt, i, iLower ;
1375
1376   aCP.Range1(aTF, aTL);
1377   aEpsT=8.e-5;
1378   aTm=0.5*(aTF+aTL);
1379   aDist2=DistanceFunction(aTm);
1380   aDist2 *= aDist2;
1381
1382   Tol = Precision::PConfusion();
1383
1384   const Handle(Geom_Curve)&  Curve   =BRep_Tool::Curve  (myC.Edge(), af, al);
1385   const Handle(Geom_Surface)& Surface=BRep_Tool::Surface(myS.Face());
1386
1387   Surface->Bounds(U1f,U1l,V1f,V1l);
1388   
1389   GeomAdaptor_Curve   TheCurve   (Curve,aTF, aTL);
1390   GeomAdaptor_Surface TheSurface (Surface, U1f, U1l, V1f, V1l); 
1391                                  
1392   Extrema_ExtCS anExtrema (TheCurve, TheSurface, Tol, Tol);
1393    
1394   if(!anExtrema.IsDone()) {
1395     return theflag;
1396   }
1397   if (anExtrema.IsParallel()) {
1398     return theflag;
1399   }
1400   
1401   aNbExt=anExtrema.NbExt() ;
1402   if (!aNbExt) {
1403      return theflag;
1404   }
1405
1406   iLower=1;
1407   aMinDist2=1.e100;
1408   for (i=1; i<=aNbExt; ++i) {
1409     aDist2=anExtrema.SquareDistance(i);
1410     if (aDist2 < aMinDist2) {
1411       aMinDist2=aDist2;
1412       iLower=i;
1413     }
1414   }
1415
1416   aDist2New=anExtrema.SquareDistance(iLower);
1417   
1418   if (aDist2New > aDist2) {
1419     aTx=aTm;
1420     return !theflag;
1421   }
1422   
1423   if (aDist2New > myCriteria * myCriteria) {
1424     return theflag;
1425   }
1426
1427   Extrema_POnCurv aPOnC;
1428   Extrema_POnSurf aPOnS;
1429   anExtrema.Points(iLower, aPOnC, aPOnS);
1430
1431  
1432   aTx=aPOnC.Parameter();
1433   ///
1434   if (fabs (aTx-aTF) < aEpsT) {
1435     return theflag;
1436   }
1437
1438   if (fabs (aTx-aTL) < aEpsT) {
1439     return theflag;
1440   }
1441
1442   if (aTx>aTF && aTx<aTL) {
1443     return !theflag;
1444   }
1445
1446   return theflag;
1447 }
1448
1449
1450 //=======================================================================
1451 //function :  IsCoplanar
1452 //purpose  : 
1453 //=======================================================================
1454 Standard_Boolean IsCoplanar (const BRepAdaptor_Curve& aCurve ,
1455                                const BRepAdaptor_Surface& aSurface)
1456 {
1457   Standard_Boolean bFlag=Standard_False;
1458
1459   GeomAbs_CurveType   aCType;
1460   GeomAbs_SurfaceType aSType;
1461
1462   aCType=aCurve.GetType();
1463   aSType=aSurface.GetType();
1464     
1465   if (aCType==GeomAbs_Circle && aSType==GeomAbs_Plane) {
1466     gp_Circ aCirc=aCurve.Circle();
1467     const gp_Ax1& anAx1=aCirc.Axis();
1468     const gp_Dir& aDirAx1=anAx1.Direction();
1469     
1470     gp_Pln aPln=aSurface.Plane();
1471     const gp_Ax1& anAx=aPln.Axis();
1472     const gp_Dir& aDirPln=anAx.Direction();
1473
1474     bFlag=IntTools_Tools::IsDirsCoinside(aDirAx1, aDirPln);
1475   }
1476   return bFlag;
1477 }
1478 //=======================================================================
1479 //function :  IsRadius
1480 //purpose  : 
1481 //=======================================================================
1482 Standard_Boolean IsRadius (const BRepAdaptor_Curve& aCurve ,
1483                            const BRepAdaptor_Surface& aSurface)
1484 {
1485   Standard_Boolean bFlag=Standard_False;
1486
1487   GeomAbs_CurveType   aCType;
1488   GeomAbs_SurfaceType aSType;
1489
1490   aCType=aCurve.GetType();
1491   aSType=aSurface.GetType();
1492     
1493   if (aCType==GeomAbs_Circle && aSType==GeomAbs_Plane) {
1494     gp_Circ aCirc=aCurve.Circle();
1495     const gp_Pnt aCenter=aCirc.Location();
1496     Standard_Real aR=aCirc.Radius();
1497     gp_Pln aPln=aSurface.Plane();
1498     Standard_Real aD=aPln.Distance(aCenter);
1499     if (fabs (aD-aR) < 1.e-7) {
1500       return !bFlag;
1501     }
1502   }
1503   return bFlag;
1504 }
1505 //
1506 //=======================================================================
1507 //function :  AdaptiveDiscret
1508 //purpose  : 
1509 //=======================================================================
1510 Standard_Integer AdaptiveDiscret (const Standard_Integer iDiscret,
1511                                   const BRepAdaptor_Curve& aCurve ,
1512                                   const BRepAdaptor_Surface& aSurface)
1513 {
1514   Standard_Integer iDiscretNew;
1515
1516   iDiscretNew=iDiscret;
1517
1518   GeomAbs_SurfaceType aSType;
1519
1520   aSType=aSurface.GetType();
1521     
1522   if (aSType==GeomAbs_Cylinder) {
1523    Standard_Real aELength, aRadius, dLR;
1524
1525    aELength=IntTools::Length(aCurve.Edge());
1526    
1527    gp_Cylinder aCylinder=aSurface.Cylinder();
1528    aRadius=aCylinder.Radius();
1529    dLR=2*aRadius;
1530
1531    iDiscretNew=(Standard_Integer)(aELength/dLR);
1532    
1533    if (iDiscretNew<iDiscret) {
1534      iDiscretNew=iDiscret;
1535    }
1536      
1537   }
1538   return iDiscretNew;
1539 }
1540
1541
1542 #ifdef WNT
1543 #pragma warning ( default : 4101 )
1544 #endif