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