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