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