0022922: Clean up warnings on uninitialized / unused variables
[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   Umin=myS.FirstUParameter();
408   Usup=myS.LastUParameter();
409   Vmin=myS.FirstVParameter();
410   Vsup=myS.LastVParameter ();
411   
412   gp_Pnt P;
413   myC.D0(t, P);
414   GeomAPI_ProjectPointOnSurf aProjector;
415   //
416   Standard_Real ULD, VLD;
417
418   GeomAPI_ProjectPointOnSurf& aLocProj = myContext->ProjPS(myFace);
419   aLocProj.Perform(P);
420   bFlag = aLocProj.IsDone();
421   
422   if(bFlag) {
423     aLocProj.LowerDistanceParameters(ULD, VLD);
424   }
425   //
426
427   if (bFlag) {
428     bFlag=Standard_False;
429
430     // 
431     TopAbs_State aState;
432     gp_Pnt2d aP2d(ULD, VLD);
433
434     aState = myContext->FClass2d(myFace).Perform(aP2d);
435     //
436     
437     if (aState==TopAbs_IN || aState==TopAbs_ON) {
438       bFlag=Standard_True;
439     }
440   }
441   return bFlag;
442 }
443
444 //=======================================================================
445 //function : DistanceFunction
446 //purpose  : 
447 //=======================================================================
448   Standard_Real IntTools_EdgeFace::DistanceFunction(const Standard_Real t)
449 {
450   Standard_Real Umin, Usup, Vmin, Vsup, aD;
451   //
452   gp_Pnt P;
453   myC.D0(t, P);
454   //
455   Standard_Boolean bIsEqDistance;
456
457   bIsEqDistance= IntTools_EdgeFace::IsEqDistance(P, myS, 1.e-7, aD); 
458   if (bIsEqDistance) {
459     aD=aD-myCriteria;
460     return aD; 
461   }
462   
463   Umin=myS.FirstUParameter();
464   Usup=myS.LastUParameter();
465   Vmin=myS.FirstVParameter();
466   Vsup=myS.LastVParameter ();
467   
468   //
469   Standard_Boolean bFlag = Standard_False;
470
471   GeomAPI_ProjectPointOnSurf& aLocProj = myContext->ProjPS(myFace);
472   aLocProj.Perform(P);
473   bFlag = aLocProj.IsDone();
474   
475   if(bFlag) {
476     aD = aLocProj.LowerDistance();
477   }
478   //
479   
480   if (!bFlag) {
481     myErrorStatus=11;
482     return 99.;
483   }
484   
485   // 
486   //   aD=aProjector.LowerDistance();
487   // 
488   aD=aD-myCriteria;
489   return aD; 
490 }
491 //
492 //=======================================================================
493 //function : IsEqDistance
494 //purpose  : 
495 //=======================================================================
496   Standard_Boolean IntTools_EdgeFace::IsEqDistance(const gp_Pnt& aP,
497                                                    const BRepAdaptor_Surface& aBAS,
498                                                    const Standard_Real aTol,
499                                                    Standard_Real& aD)
500 {
501   Standard_Boolean bRetFlag=Standard_True;
502
503   GeomAbs_SurfaceType aSurfType=aBAS.GetType();
504
505   if (aSurfType==GeomAbs_Cylinder) {
506     gp_Cylinder aCyl=aBAS.Cylinder();
507     const gp_Ax1& anAx1  =aCyl.Axis();
508     gp_Lin aLinAxis(anAx1);
509     Standard_Real aDC, aRadius=aCyl.Radius();
510     aDC=aLinAxis.Distance(aP);
511     if (aDC < aTol) {
512       aD=aRadius;
513       return bRetFlag; 
514     }
515   }
516
517   if (aSurfType==GeomAbs_Cone) {
518     gp_Cone aCone=aBAS.Cone();
519     const gp_Ax1& anAx1  =aCone.Axis();
520     gp_Lin aLinAxis(anAx1);
521     Standard_Real aDC, aRadius, aDS, aSemiAngle;
522     aDC=aLinAxis.Distance(aP);
523     if (aDC < aTol) {
524       gp_Pnt anApex=aCone.Apex();
525       aSemiAngle=aCone.SemiAngle();
526       aDS=aP.Distance(anApex);
527       
528       aRadius=aDS*tan(aSemiAngle);
529       aD=aRadius;
530       return bRetFlag; 
531     }
532   }
533
534   if (aSurfType==GeomAbs_Torus) {
535     Standard_Real aMajorRadius, aMinorRadius, aDC;
536
537     gp_Torus aTorus=aBAS.Torus();
538     gp_Pnt aPLoc=aTorus.Location();
539     aMajorRadius=aTorus.MajorRadius();
540     
541     aDC=fabs(aPLoc.Distance(aP)-aMajorRadius);
542     if (aDC < aTol) {
543       aMinorRadius=aTorus.MinorRadius();
544       aD=aMinorRadius;
545       return bRetFlag; 
546     }
547   }
548   return !bRetFlag; 
549 }
550 //
551 //=======================================================================
552 //function : PrepareArgsFuncArrays
553 //purpose  : Obtain 
554 //           myFuncArray and myArgsArray for the interval [ta, tb]
555 //=======================================================================               
556   void IntTools_EdgeFace::PrepareArgsFuncArrays(const Standard_Real ta,
557                                                 const Standard_Real tb)
558 {
559   IntTools_CArray1OfReal anArgs, aFunc;
560   Standard_Integer i, aNb, pri;
561   Standard_Real t, f, f1;
562   //
563   // Prepare values of arguments for the interval [ta, tb]
564   pri=IntTools::PrepareArgs (myC, tb, ta, myDiscret, myDeflection, anArgs);
565   
566   if (pri) {
567     myErrorStatus=8;
568     return;
569   }
570   //...
571   aNb=anArgs.Length();
572
573   if (!aNb){
574     myErrorStatus=9;
575     return;
576   }
577   //
578   // Prepare values of functions for the interval [ta, tb]
579   aFunc.Resize(aNb);
580   for (i=0; i<aNb; i++) {
581     t=anArgs(i);
582     f1=DistanceFunction(t);
583     f=f1+myCriteria; 
584
585     if (myErrorStatus==11)
586       return;
587     
588     if (f1 < myEpsNull) { 
589       f=0.;
590     }
591     aFunc(i)=f;
592   }
593   //
594   // Add points where the derivative = 0  
595   AddDerivativePoints(anArgs, aFunc);
596
597 }
598
599
600 //=======================================================================
601 //function : AddDerivativePoints
602 //purpose  : 
603 //=======================================================================
604   void IntTools_EdgeFace::AddDerivativePoints(const IntTools_CArray1OfReal& t,
605                                               const IntTools_CArray1OfReal& f)  
606 {
607   Standard_Integer i, j, n, k, nn=100;
608   Standard_Real fr, tr, tr1, dEpsNull=10.*myEpsNull;
609   IntTools_CArray1OfReal fd;
610   TColStd_SequenceOfReal aTSeq, aFSeq;  
611
612   n=t.Length();
613   fd.Resize(n+1);
614   //
615   // Table of derivatives
616   Standard_Real dfx, tx, tx1, fx, fx1, dt=1.e-6;
617   // Left limit
618   tx=t(0);
619   tx1=tx+dt;
620   fx=f(0);
621   fx1=DistanceFunction(tx1);
622   fx1=fx1+myCriteria;
623   if (fx1 < myEpsNull) { 
624     fx1=0.;
625   }
626   dfx=(fx1-fx)/dt;
627   fd(0)=dfx;
628   
629   if (fabs(fd(0)) < dEpsNull){
630     fd(0)=0.;
631   }
632   
633
634   k=n-1;
635   for (i=1; i<k; i++) {
636     Standard_Real ti, ti1;
637     ti=t(i);
638     ti1=t(i-1);
639     fd(i)=.5*(f(i+1)-f(i-1))/(t(i)-t(i-1));
640     if (fabs(fd(i)) < dEpsNull){
641       fd(i)=0.;
642     }
643   }
644   // Right limit
645   tx=t(n-1);
646   tx1=tx-dt;
647   fx=f(n-1);
648   fx1=DistanceFunction(tx1);
649   fx1=fx1+myCriteria;
650   if (fx1 < myEpsNull) { 
651     fx1=0.;
652   }
653   dfx=(fx-fx1)/dt;
654   fd(n-1)=dfx;
655   
656   if (fabs(fd(n-1)) < dEpsNull){
657     fd(n-1)=0.;
658   }
659   //
660   // Finding the range where the derivatives have different signs
661   // for neighbouring points
662   for (i=1; i<n; i++) {
663     Standard_Real fd1, fd2, t1, t2;
664     t1 =t(i-1);
665     t2 =t(i);
666     fd1=fd(i-1);
667     fd2=fd(i);
668
669     if (fd1*fd2 < 0.) {
670       if (fabs(fd1) < myEpsNull) {
671         tr=t1;
672         fr=DistanceFunction(tr);//fd1;
673       }
674       else if (fabs(fd2) < myEpsNull) {
675         tr=t2;
676         fr=DistanceFunction(tr);
677       }
678       else {
679         tr=FindSimpleRoot(2, t1, t2, fd1);
680         fr=DistanceFunction(tr);
681       }
682       
683       aTSeq.Append(tr);
684       aFSeq.Append(fr);
685     }
686   } // end of for (i=1; i<n; i++)
687   //
688   // remove identical t, f
689   nn=aTSeq.Length();
690   if (nn) {
691     for (i=1; i<=aTSeq.Length(); i++) {
692       tr=aTSeq(i);
693       for (j=0; j<n; j++) {
694         tr1=t(j);
695         if (fabs (tr1-tr) < myEpsT) {
696           aTSeq.Remove(i);
697           aFSeq.Remove(i);
698         }
699       }
700     }
701     nn=aTSeq.Length();
702   }
703   //
704   // sorting args and funcs in increasing order
705   if (nn) {
706     k=nn+n;
707     IntTools_Array1OfRange anArray1OfRange(1, k);
708     for (i=1; i<=n; i++) {
709       anArray1OfRange(i).SetFirst(t(i-1));
710       anArray1OfRange(i).SetLast (f(i-1));
711     }
712     for (i=1; i<=nn; i++) {
713       anArray1OfRange(n+i).SetFirst(aTSeq(i));
714       anArray1OfRange(n+i).SetLast (aFSeq(i));
715     }
716     
717     IntTools_QuickSortRange aQuickSortRange;
718     IntTools_CompareRange aComparator;
719     aQuickSortRange.Sort (anArray1OfRange, aComparator);
720     
721     // filling the  output arrays
722     myArgsArray.Resize(k);
723     myFuncArray.Resize(k);
724     for (i=1; i<=k; i++) {
725       myArgsArray(i-1)=anArray1OfRange(i).First();
726       myFuncArray(i-1)=anArray1OfRange(i).Last ();
727     }
728   }
729   
730   else { // nn=0
731     myArgsArray.Resize(n);
732     myFuncArray.Resize(n);
733     for (i=0; i<n; i++) {
734       myArgsArray(i)=t(i); 
735       myFuncArray(i)=f(i); 
736     }
737   }
738 }
739
740 //=======================================================================
741 //function : DerivativeFunction
742 //purpose  : 
743 //=======================================================================
744   Standard_Real IntTools_EdgeFace::DerivativeFunction(const Standard_Real t2)
745 {
746   Standard_Real t1, t3, aD1, aD2, aD3;
747   Standard_Real dt=1.e-9;
748   t1=t2-dt;
749   aD1=DistanceFunction(t1);
750   t3=t2+dt;
751   aD3=DistanceFunction(t3);
752   
753   aD2=.5*(aD3-aD1)/dt;
754   return aD2; 
755 }
756
757 //=======================================================================
758 //function : FindSimpleRoot
759 //purpose  : [private]
760 //=======================================================================
761   Standard_Real IntTools_EdgeFace::FindSimpleRoot (const Standard_Integer IP,
762                                                    const Standard_Real tA,
763                                                    const Standard_Real tB,
764                                                    const Standard_Real fA)
765 {
766   Standard_Real r, a, b, y, x0, s;
767   
768   a=tA; b=tB; r=fA;
769   
770   while (1) {
771     x0=.5*(a+b);
772
773     if (IP==1)
774       y=DistanceFunction(x0);
775     else 
776       y=DerivativeFunction(x0);
777     
778     if (fabs(b-a) < myEpsT || y==0.) {
779       return x0;
780     }
781     
782         
783     s=y*r;
784
785     if (s<0.) {
786       b=x0;
787       continue;
788     }
789
790     if (s>0.) {
791       a=x0; r=y;
792     }
793   }
794 }
795 //=======================================================================
796 //function : FindGoldRoot
797 //purpose  : [private]
798 //=======================================================================
799   Standard_Real IntTools_EdgeFace::FindGoldRoot (const Standard_Real tA,
800                                                  const Standard_Real tB,
801                                                  const Standard_Real coeff)
802 {
803   Standard_Real gs=0.61803399;
804   Standard_Real a, b, xp, xl, yp, yl;
805
806   a=tA;  b=tB;
807   
808   xp=a+(b-a)*gs;
809   xl=b-(b-a)*gs;
810   yp=coeff*DistanceFunction(xp);
811   yl=coeff*DistanceFunction(xl);
812   
813  
814   while (1) {
815     
816     if (fabs(b-a) < myEpsT) {
817       return .5*(b+a);
818     }
819     
820     if (yp < yl) {
821       a=xl;
822       xl=xp;
823       xp=a+(b-a)*gs;
824       yp=coeff*DistanceFunction(xp);
825     }
826     
827     else {
828       b=xp;
829       xp=xl;
830       yp=yl;
831       xl=b-(b-a)*gs;
832       yl=coeff*DistanceFunction(xl);
833     }
834   }
835 }  
836
837 //=======================================================================
838 //function : MakeType
839 //purpose  : 
840 //=======================================================================
841   Standard_Integer IntTools_EdgeFace::MakeType(IntTools_CommonPrt&  aCommonPrt)
842 {
843   Standard_Real  af1, al1;
844   Standard_Real dt, df1, df2, tm;
845   Standard_Boolean bAllNullFlag;
846   //
847   bAllNullFlag=aCommonPrt.AllNullFlag();
848   if (bAllNullFlag) {
849     aCommonPrt.SetType(TopAbs_EDGE);
850     return 0;
851   }
852   //
853   aCommonPrt.Range1(af1, al1);
854
855   {
856     gp_Pnt aPF, aPL;
857     myC.D0(af1, aPF);
858     myC.D0(al1, aPL);
859     df1=aPF.Distance(aPL);
860     Standard_Boolean isWholeRange = Standard_False;
861     
862     if((Abs(af1 - myRange.First()) < myC.Resolution(myCriteria)) &&
863        (Abs(al1 - myRange.Last()) < myC.Resolution(myCriteria)))
864       isWholeRange = Standard_True;
865
866     
867     if ((df1 > myCriteria * 2.) && isWholeRange) {
868       aCommonPrt.SetType(TopAbs_EDGE);
869     }
870     else {
871       if(isWholeRange) {
872         tm = (af1 + al1) * 0.5;
873
874         if(aPF.Distance(myC.Value(tm)) > myCriteria * 2.) {
875           aCommonPrt.SetType(TopAbs_EDGE);
876           return 0;
877         }
878       }
879
880       if(!CheckTouch(aCommonPrt, tm)) {
881         tm = (af1 + al1) * 0.5;
882       }
883       aCommonPrt.SetType(TopAbs_VERTEX);
884       aCommonPrt.SetVertexParameter1(tm);
885       aCommonPrt.SetRange1 (af1, al1);
886     }
887     return 0;
888   }
889
890   //
891   dt=al1-af1;
892   if (dt<1.e-5) {
893     gp_Pnt aPF, aPL;
894     myC.D0(af1, aPF);
895     myC.D0(al1, aPL);
896     df1=aPF.Distance(aPL);
897     if (df1<myCriteria) {
898       //
899       tm=.5*(af1+al1);
900       aCommonPrt.SetType(TopAbs_VERTEX);
901       aCommonPrt.SetVertexParameter1(tm);
902       aCommonPrt.SetRange1 (af1, al1);
903       return 0;
904     }
905   }
906   //
907   IsIntersection (af1, al1);
908   //
909   if (!myParallel) {
910     aCommonPrt.SetType(TopAbs_VERTEX);
911     aCommonPrt.SetVertexParameter1(myPar1);
912     aCommonPrt.SetRange1 (af1, al1);
913   }
914   else {
915     dt=al1-af1;
916     if (dt<1.e-5) {
917       df1=DistanceFunction(af1);
918       df2=DistanceFunction(al1);
919       tm=(df1 < df2) ? af1 : al1;
920       aCommonPrt.SetType(TopAbs_VERTEX);
921       aCommonPrt.SetVertexParameter1(tm);
922       aCommonPrt.SetRange1 (af1, al1);
923     }
924
925     else {
926       aCommonPrt.SetType(TopAbs_EDGE);
927     }
928   }
929   return 0;
930 }
931
932
933 //=======================================================================
934 //function : IsIntersection
935 //purpose  : 
936 //=======================================================================
937   void IntTools_EdgeFace::IsIntersection (const Standard_Real ta, 
938                                           const Standard_Real tb) 
939 {
940   IntTools_CArray1OfReal anArgs, aFunc;
941   Standard_Integer i, aNb, pri, aCnt=0;
942   //
943   Standard_Integer aCntIncreasing=1, aCntDecreasing=1;
944   Standard_Real t, f, f1;
945   //
946   // Prepare values of arguments for the interval [ta, tb]
947   pri=IntTools::PrepareArgs (myC, tb, ta, myDiscret, myDeflection, anArgs);
948   aNb=anArgs.Length();
949   
950   aFunc.Resize(aNb);
951   for (i=0; i<aNb; i++) {
952     t=anArgs(i);
953     
954     f1=DistanceFunction(t);
955     f=f1+myCriteria; 
956
957     if (fabs(f1) < myEpsNull) { 
958       aCnt++;
959       f=0.;
960     }
961     aFunc(i)=f;
962     //
963     if (i) {
964       if (aFunc(i)>aFunc(i-1)) {
965         aCntIncreasing++;
966       }
967       if (aFunc(i)<aFunc(i-1)) {
968         aCntDecreasing++;
969       }
970     }
971     //
972   }
973
974   if (aCnt==aNb) {
975     myParallel=Standard_True;
976     return;
977   }
978   
979   FindDerivativeRoot(anArgs, aFunc);
980
981   //
982   if (myParallel) {
983     if (!(myC.GetType()==GeomAbs_Line 
984           && 
985           myS.GetType()==GeomAbs_Cylinder)) {
986       if (aCntDecreasing==aNb) {
987         myPar1=anArgs(aNb-1);
988         myParallel=Standard_False;
989       }
990       if (aCntIncreasing==aNb) {
991         myPar1=anArgs(0);
992         myParallel=Standard_False;
993       }
994     }
995   }
996   //
997   return ;
998 }
999
1000 //=======================================================================
1001 //function : FindDerivativeRoot
1002 //purpose  : 
1003 //=======================================================================
1004   void IntTools_EdgeFace::FindDerivativeRoot(const IntTools_CArray1OfReal& t,
1005                                              const IntTools_CArray1OfReal& f)  
1006 {
1007   Standard_Integer i, n, k;
1008   Standard_Real fr, tr;
1009   IntTools_CArray1OfReal fd;
1010   TColStd_SequenceOfReal aTSeq, aFSeq;  
1011   
1012   myPar1=0.;
1013   myParallel=Standard_True;
1014   
1015   n=t.Length();
1016   fd.Resize(n+1);
1017   //
1018   // Table of derivatives
1019   fd(0)=(f(1)-f(0))/(t(1)-t(0));
1020   if (fabs(fd(0)) < myEpsNull) {
1021     fd(0)=0.;
1022   }
1023
1024   k=n-1;
1025   for (i=1; i<k; i++) {
1026     fd(i)=.5*(f(i+1)-f(i-1))/(t(i)-t(i-1));
1027     if (fabs(fd(i)) < myEpsNull) {
1028       fd(i)=0.;
1029     }
1030   }
1031
1032   fd(n-1)=(f(n-1)-f(n-2))/(t(n-1)-t(n-2));
1033   if (fabs(fd(n-1)) < myEpsNull) {
1034     fd(n-1)=0.;
1035   }
1036   //
1037   // Finding the range where the derivatives have different signs
1038   // for neighbouring points
1039   for (i=1; i<n; i++) {
1040     Standard_Real fd1, fd2, t1, t2, fabsfd1, fabsfd2;
1041     Standard_Boolean bF1, bF2;
1042     t1 =t(i-1);
1043     t2 =t(i);
1044     fd1=fd(i-1);
1045     fd2=fd(i);
1046
1047     fabsfd1=fabs(fd1);
1048     bF1=fabsfd1 < myEpsNull;
1049     
1050     fabsfd2=fabs(fd2);
1051     bF2=fabsfd2 < myEpsNull;
1052     //
1053     if (fd1*fd2 < 0.) {
1054       tr=FindSimpleRoot(2, t1, t2, fd1);
1055       fr=DistanceFunction(tr);
1056       myPar1=tr;
1057       myParallel=Standard_False;
1058       break;
1059     }
1060     
1061     if (!bF1 && bF2) {
1062       tr=t2;
1063       fr=fd2;
1064       myPar1=tr;
1065       myParallel=Standard_False;
1066       break;
1067     }
1068     
1069     if (bF1 && !bF2) {
1070       tr=t1;
1071       fr=fd1;
1072       myPar1=tr;
1073       myParallel=Standard_False;
1074       break;
1075     }
1076
1077   }
1078 }
1079 //=======================================================================
1080 //function : RemoveIdenticalRoots 
1081 //purpose  : 
1082 //=======================================================================
1083   void IntTools_EdgeFace::RemoveIdenticalRoots()
1084 {
1085   Standard_Integer aNbRoots, j, k;
1086
1087   aNbRoots=mySequenceOfRoots.Length();
1088   for (j=1; j<=aNbRoots; j++) { 
1089     const IntTools_Root& aRj=mySequenceOfRoots(j);
1090     for (k=j+1; k<=aNbRoots; k++) {
1091       const IntTools_Root& aRk=mySequenceOfRoots(k);
1092       
1093       Standard_Real aTj, aTk, aDistance;
1094       gp_Pnt aPj, aPk;
1095
1096       aTj=aRj.Root();
1097       aTk=aRk.Root();
1098
1099       myC.D0(aTj, aPj);
1100       myC.D0(aTk, aPk);
1101
1102       aDistance=aPj.Distance(aPk);
1103       if (aDistance < myCriteria) {
1104         mySequenceOfRoots.Remove(k);
1105         aNbRoots=mySequenceOfRoots.Length();
1106       }
1107     }
1108   }
1109 }
1110
1111 //=======================================================================
1112 //function : CheckTouch 
1113 //purpose  : 
1114 //=======================================================================
1115   Standard_Boolean IntTools_EdgeFace::CheckTouch(const IntTools_CommonPrt& aCP,
1116                                                  Standard_Real&            aTx) 
1117 {
1118   Standard_Real aTF, aTL, Tol, U1f, U1l, V1f, V1l, af, al,aDist2, aMinDist2;
1119   Standard_Boolean theflag=Standard_False;
1120   Standard_Integer aNbExt, i, iLower ;
1121
1122   aCP.Range1(aTF, aTL);
1123
1124   //
1125   Standard_Real aCR;
1126   aCR=myC.Resolution(myCriteria);
1127   if((Abs(aTF - myRange.First()) < aCR) &&
1128      (Abs(aTL - myRange.Last())  < aCR)) {
1129     return theflag; // EDGE 
1130   }
1131   //
1132
1133   Tol = Precision::PConfusion();
1134
1135   const Handle(Geom_Curve)&  Curve   =BRep_Tool::Curve  (myC.Edge(), af, al);
1136   const Handle(Geom_Surface)& Surface=BRep_Tool::Surface(myS.Face());
1137   //   Surface->Bounds(U1f,U1l,V1f,V1l);
1138   U1f = myS.FirstUParameter();
1139   U1l = myS.LastUParameter();
1140   V1f = myS.FirstVParameter();
1141   V1l = myS.LastVParameter();
1142   
1143   GeomAdaptor_Curve   TheCurve   (Curve,aTF, aTL);
1144   GeomAdaptor_Surface TheSurface (Surface, U1f, U1l, V1f, V1l); 
1145                                  
1146   Extrema_ExtCS anExtrema (TheCurve, TheSurface, Tol, Tol);
1147
1148   aDist2 = 1.e100;
1149
1150   if(anExtrema.IsDone()) {
1151     aMinDist2 = aDist2;
1152
1153     if(!anExtrema.IsParallel()) {
1154       aNbExt=anExtrema.NbExt();
1155       
1156       if(aNbExt > 0) {
1157         iLower=1;
1158         for (i=1; i<=aNbExt; i++) {
1159           aDist2=anExtrema.SquareDistance(i);
1160           if (aDist2 < aMinDist2) {
1161             aMinDist2=aDist2;
1162             iLower=i;
1163           }
1164         }
1165         aDist2=anExtrema.SquareDistance(iLower);
1166         Extrema_POnCurv aPOnC;
1167         Extrema_POnSurf aPOnS;
1168         anExtrema.Points(iLower, aPOnC, aPOnS);
1169         aTx=aPOnC.Parameter();
1170       }
1171       else {
1172         // modified by NIZHNY-MKK  Thu Jul 21 11:35:32 2005.BEGIN
1173         IntCurveSurface_HInter anExactIntersector;
1174   
1175         Handle(GeomAdaptor_HCurve) aCurve     = new GeomAdaptor_HCurve(TheCurve);
1176         Handle(GeomAdaptor_HSurface) aSurface = new GeomAdaptor_HSurface(TheSurface);
1177         
1178         anExactIntersector.Perform(aCurve, aSurface);
1179
1180         if(anExactIntersector.IsDone()) {
1181           Standard_Integer i = 0;
1182
1183           for(i = 1; i <= anExactIntersector.NbPoints(); i++) {
1184             const IntCurveSurface_IntersectionPoint& aPoint = anExactIntersector.Point(i);
1185       
1186             if((aPoint.W() >= aTF) && (aPoint.W() <= aTL)) {
1187               aDist2=0.;
1188               aTx = aPoint.W();
1189             }
1190           }
1191         }
1192         // modified by NIZHNY-MKK  Thu Jul 21 11:35:40 2005.END
1193       }
1194     }
1195     else {
1196       return theflag;
1197     }
1198   }
1199
1200   Standard_Real aBoundaryDist;
1201
1202   aBoundaryDist = DistanceFunction(aTF) + myCriteria;
1203   if(aBoundaryDist * aBoundaryDist < aDist2) {
1204     aDist2 = aBoundaryDist * aBoundaryDist;
1205     aTx = aTF;
1206   }
1207   
1208   aBoundaryDist = DistanceFunction(aTL) + myCriteria;
1209   if(aBoundaryDist * aBoundaryDist < aDist2) {
1210     aDist2 = aBoundaryDist * aBoundaryDist;
1211     aTx = aTL;
1212   }
1213
1214   Standard_Real aParameter = (aTF + aTL) * 0.5;
1215   aBoundaryDist = DistanceFunction(aParameter) + myCriteria;
1216   if(aBoundaryDist * aBoundaryDist < aDist2) {
1217     aDist2 = aBoundaryDist * aBoundaryDist;
1218     aTx = aParameter;
1219   }
1220
1221   if(aDist2 > myCriteria * myCriteria) {
1222     return theflag;
1223   }
1224   
1225   if (fabs (aTx-aTF) < myEpsT) {
1226     return !theflag;
1227   }
1228
1229   if (fabs (aTx-aTL) < myEpsT) {
1230     return !theflag;
1231   }
1232
1233   if (aTx>aTF && aTx<aTL) {
1234     return !theflag;
1235   }
1236
1237   return theflag;
1238 }
1239
1240
1241 //=======================================================================
1242 //function : Perform
1243 //purpose  : 
1244 //=======================================================================
1245   void IntTools_EdgeFace::Perform() 
1246 {
1247   Standard_Integer i, aNb;
1248   IntTools_CommonPrt aCommonPrt;
1249   //
1250   aCommonPrt.SetEdge1(myEdge);
1251   //
1252   myErrorStatus=0;
1253   CheckData();
1254   if (myErrorStatus) {
1255     return;
1256   }
1257   //
1258   if (myContext.IsNull()) {
1259     myContext=new IntTools_Context;
1260   }
1261   //
1262   myIsDone = Standard_False;
1263   myC.Initialize(myEdge);
1264   GeomAbs_CurveType aCurveType;
1265   aCurveType=myC.GetType();
1266   //
1267   // Prepare myCriteria
1268   if (aCurveType==GeomAbs_BSplineCurve||
1269         aCurveType==GeomAbs_BezierCurve) {
1270     //--- 5112
1271     Standard_Real diff1 = (myTolE/myTolF);
1272     Standard_Real diff2 = (myTolF/myTolE);
1273     if( diff1 > 100 || diff2 > 100 ) {
1274       myCriteria = Max(myTolE,myTolF);
1275     }
1276     else //--- 5112
1277       myCriteria=1.5*myTolE+myTolF;
1278   }
1279   else {
1280     myCriteria=myTolE+myTolF;
1281   }
1282
1283   myTmin=myRange.First();
1284   myTmax=myRange.Last();
1285
1286   myS.Initialize (myFace,Standard_True);
1287
1288   if(myContext.IsNull()) {
1289     myFClass2d.Init(myFace, 1.e-6);
1290   }
1291
1292   IntTools_BeanFaceIntersector anIntersector(myC, myS, myTolE, myTolF);
1293   anIntersector.SetBeanParameters(myRange.First(), myRange.Last());
1294   //
1295   anIntersector.SetContext(myContext);
1296   //
1297   anIntersector.Perform();
1298
1299   if(!anIntersector.IsDone()) {
1300     return;
1301   }
1302
1303   for(Standard_Integer r = 1; r <= anIntersector.Result().Length(); r++) {
1304     const IntTools_Range& aRange = anIntersector.Result().Value(r);
1305     
1306     if(IsProjectable(IntTools_Tools::IntermediatePoint(aRange.First(), aRange.Last()))) {
1307       aCommonPrt.SetRange1(aRange.First(), aRange.Last());
1308       mySeqOfCommonPrts.Append(aCommonPrt);
1309     }
1310   }
1311
1312   aNb = mySeqOfCommonPrts.Length();
1313
1314   for (i=1; i<=aNb; i++) {
1315     IntTools_CommonPrt& aCP=mySeqOfCommonPrts.ChangeValue(i);
1316     //
1317     Standard_Real aTx1, aTx2;
1318     gp_Pnt aPx1, aPx2;
1319     //
1320     aCP.Range1(aTx1, aTx2);
1321     myC.D0(aTx1, aPx1);
1322     myC.D0(aTx2, aPx2);
1323     aCP.SetBoundingPoints(aPx1, aPx2);
1324     //
1325     MakeType (aCP); 
1326   }
1327   {
1328     // Line\Cylinder's Common Parts treatement
1329     GeomAbs_CurveType   aCType;
1330     GeomAbs_SurfaceType aSType;
1331     TopAbs_ShapeEnum aType;
1332     Standard_Boolean bIsTouch;
1333     Standard_Real aTx;
1334
1335     aCType=myC.GetType();
1336     aSType=myS.GetType();
1337     
1338     if (aCType==GeomAbs_Line && aSType==GeomAbs_Cylinder) {
1339       for (i=1; i<=aNb; i++) {
1340         IntTools_CommonPrt& aCP=mySeqOfCommonPrts(i);
1341         aType=aCP.Type();
1342         if (aType==TopAbs_EDGE) {
1343           bIsTouch=CheckTouch (aCP, aTx);
1344           if (bIsTouch) {
1345             aCP.SetType(TopAbs_VERTEX);
1346             aCP.SetVertexParameter1(aTx);
1347             aCP.SetRange1 (aTx, aTx);
1348           }
1349         }
1350         if (aType==TopAbs_VERTEX) {
1351           bIsTouch=CheckTouchVertex (aCP, aTx);
1352           if (bIsTouch) {
1353             aCP.SetVertexParameter1(aTx);
1354             aCP.SetRange1 (aTx, aTx);
1355           }
1356         }
1357       }
1358     }
1359
1360     // Circle\Plane's Common Parts treatement
1361     
1362     if (aCType==GeomAbs_Circle && aSType==GeomAbs_Plane) {
1363       Standard_Boolean bIsCoplanar, bIsRadius;
1364       bIsCoplanar=IsCoplanar(myC, myS);
1365       bIsRadius=IsRadius(myC, myS);
1366       if (!bIsCoplanar && !bIsRadius) {
1367         for (i=1; i<=aNb; i++) {
1368           IntTools_CommonPrt& aCP=mySeqOfCommonPrts(i);
1369           aType=aCP.Type();
1370           if (aType==TopAbs_EDGE) {
1371             bIsTouch=CheckTouch (aCP, aTx);
1372             if (bIsTouch) {
1373               aCP.SetType(TopAbs_VERTEX);
1374               aCP.SetVertexParameter1(aTx);
1375               aCP.SetRange1 (aTx, aTx);
1376             }
1377           }
1378         }
1379       }
1380     }
1381   }
1382   myIsDone=Standard_True;
1383 }
1384
1385 //
1386 // myErrorStatus
1387 // 1 - the method Perform() is not invoked  
1388 // 2,3,4,5 -the method CheckData() fails
1389 // 6 - PrepareArgs() problems
1390 // 7 - No Projectable ranges
1391 // 8,9 - PrepareArgs() problems occured inside  projectable Ranges
1392 // 11 - can't fill array  aFunc(i) in PrepareArgsFuncArrays 
1393
1394
1395 //=======================================================================
1396 //function : CheckTouch 
1397 //purpose  : 
1398 //=======================================================================
1399   Standard_Boolean IntTools_EdgeFace::CheckTouchVertex (const IntTools_CommonPrt& aCP,
1400                                                         Standard_Real& aTx) 
1401 {
1402   Standard_Real aTF, aTL, Tol, U1f,U1l,V1f,V1l, af, al,aDist2, aMinDist2, aTm, aDist2New;
1403   Standard_Boolean theflag=Standard_False;
1404   Standard_Integer aNbExt, i, iLower ;
1405
1406   aCP.Range1(aTF, aTL);
1407
1408   aTm=0.5*(aTF+aTL);
1409   aDist2=DistanceFunction(aTm);
1410   aDist2 *= aDist2;
1411
1412   Tol = Precision::PConfusion();
1413
1414   const Handle(Geom_Curve)&  Curve   =BRep_Tool::Curve  (myC.Edge(), af, al);
1415   const Handle(Geom_Surface)& Surface=BRep_Tool::Surface(myS.Face());
1416
1417   Surface->Bounds(U1f,U1l,V1f,V1l);
1418   
1419   GeomAdaptor_Curve   TheCurve   (Curve,aTF, aTL);
1420   GeomAdaptor_Surface TheSurface (Surface, U1f, U1l, V1f, V1l); 
1421                                  
1422   Extrema_ExtCS anExtrema (TheCurve, TheSurface, Tol, Tol);
1423    
1424   if(!anExtrema.IsDone()) {
1425     return theflag;
1426   }
1427   if (anExtrema.IsParallel()) {
1428     return theflag;
1429   }
1430   
1431   aNbExt=anExtrema.NbExt() ;
1432   if (!aNbExt) {
1433      return theflag;
1434   }
1435
1436   iLower=1;
1437   aMinDist2=1.e100;
1438   for (i=1; i<=aNbExt; ++i) {
1439     aDist2=anExtrema.SquareDistance(i);
1440     if (aDist2 < aMinDist2) {
1441       aMinDist2=aDist2;
1442       iLower=i;
1443     }
1444   }
1445
1446   aDist2New=anExtrema.SquareDistance(iLower);
1447   
1448   if (aDist2New > aDist2) {
1449     aTx=aTm;
1450     return !theflag;
1451   }
1452   
1453   if (aDist2New > myCriteria * myCriteria) {
1454     return theflag;
1455   }
1456
1457   Extrema_POnCurv aPOnC;
1458   Extrema_POnSurf aPOnS;
1459   anExtrema.Points(iLower, aPOnC, aPOnS);
1460
1461   
1462   aTx=aPOnC.Parameter();
1463   
1464   if (fabs (aTx-aTF) < myEpsT) {
1465     return !theflag;
1466   }
1467
1468   if (fabs (aTx-aTL) < myEpsT) {
1469     return !theflag;
1470   }
1471
1472   if (aTx>aTF && aTx<aTL) {
1473     return !theflag;
1474   }
1475
1476   return theflag;
1477 }
1478
1479
1480 //=======================================================================
1481 //function :  IsCoplanar
1482 //purpose  : 
1483 //=======================================================================
1484 Standard_Boolean IsCoplanar (const BRepAdaptor_Curve& aCurve ,
1485                                const BRepAdaptor_Surface& aSurface)
1486 {
1487   Standard_Boolean bFlag=Standard_False;
1488
1489   GeomAbs_CurveType   aCType;
1490   GeomAbs_SurfaceType aSType;
1491
1492   aCType=aCurve.GetType();
1493   aSType=aSurface.GetType();
1494     
1495   if (aCType==GeomAbs_Circle && aSType==GeomAbs_Plane) {
1496     gp_Circ aCirc=aCurve.Circle();
1497     const gp_Ax1& anAx1=aCirc.Axis();
1498     const gp_Dir& aDirAx1=anAx1.Direction();
1499     
1500     gp_Pln aPln=aSurface.Plane();
1501     const gp_Ax1& anAx=aPln.Axis();
1502     const gp_Dir& aDirPln=anAx.Direction();
1503
1504     bFlag=IntTools_Tools::IsDirsCoinside(aDirAx1, aDirPln);
1505   }
1506   return bFlag;
1507 }
1508 //=======================================================================
1509 //function :  IsRadius
1510 //purpose  : 
1511 //=======================================================================
1512 Standard_Boolean IsRadius (const BRepAdaptor_Curve& aCurve ,
1513                            const BRepAdaptor_Surface& aSurface)
1514 {
1515   Standard_Boolean bFlag=Standard_False;
1516
1517   GeomAbs_CurveType   aCType;
1518   GeomAbs_SurfaceType aSType;
1519
1520   aCType=aCurve.GetType();
1521   aSType=aSurface.GetType();
1522     
1523   if (aCType==GeomAbs_Circle && aSType==GeomAbs_Plane) {
1524     gp_Circ aCirc=aCurve.Circle();
1525     const gp_Pnt aCenter=aCirc.Location();
1526     Standard_Real aR=aCirc.Radius();
1527     gp_Pln aPln=aSurface.Plane();
1528     Standard_Real aD=aPln.Distance(aCenter);
1529     if (fabs (aD-aR) < 1.e-7) {
1530       return !bFlag;
1531     }
1532   }
1533   return bFlag;
1534 }
1535 //
1536 //=======================================================================
1537 //function :  AdaptiveDiscret
1538 //purpose  : 
1539 //=======================================================================
1540 Standard_Integer AdaptiveDiscret (const Standard_Integer iDiscret,
1541                                   const BRepAdaptor_Curve& aCurve ,
1542                                   const BRepAdaptor_Surface& aSurface)
1543 {
1544   Standard_Integer iDiscretNew;
1545
1546   iDiscretNew=iDiscret;
1547
1548   GeomAbs_CurveType   aCType;
1549   GeomAbs_SurfaceType aSType;
1550
1551   aCType=aCurve.GetType();
1552   aSType=aSurface.GetType();
1553     
1554   if (aSType==GeomAbs_Cylinder) {
1555    Standard_Real aELength, aRadius, dL, dLR;
1556
1557    aELength=IntTools::Length(aCurve.Edge());
1558    dL=aELength/iDiscret;
1559    
1560    gp_Cylinder aCylinder=aSurface.Cylinder();
1561    aRadius=aCylinder.Radius();
1562    dLR=2*aRadius;
1563
1564    iDiscretNew=(Standard_Integer)(aELength/dLR);
1565    
1566    if (iDiscretNew<iDiscret) {
1567      iDiscretNew=iDiscret;
1568    }
1569      
1570   }
1571   return iDiscretNew;
1572 }
1573
1574
1575 #ifdef WNT
1576 #pragma warning ( default : 4101 )
1577 #endif