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