0024002: Overall code and build procedure refactoring -- automatic
[occt.git] / src / IntTools / IntTools_EdgeFace.cxx
1 // Created on: 2001-02-26
2 // Created by: Peter KURNEV
3 // Copyright (c) 2001-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16
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;
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, i, 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 (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    Standard_Integer i = 0;
1145
1146    for(i = 1; i <= anExactIntersector.NbPoints(); i++) {
1147      const IntCurveSurface_IntersectionPoint& aPoint = anExactIntersector.Point(i);
1148       
1149      if((aPoint.W() >= aTF) && (aPoint.W() <= aTL)) {
1150        aDist2=0.;
1151        aTx = aPoint.W();
1152      }
1153    }
1154  }
1155  // modified by NIZHNY-MKK  Thu Jul 21 11:35:40 2005.END
1156       }
1157     }
1158     else {
1159       return theflag;
1160     }
1161   }
1162
1163   Standard_Real aBoundaryDist;
1164
1165   aBoundaryDist = DistanceFunction(aTF) + myCriteria;
1166   if(aBoundaryDist * aBoundaryDist < aDist2) {
1167     aDist2 = aBoundaryDist * aBoundaryDist;
1168     aTx = aTF;
1169   }
1170   
1171   aBoundaryDist = DistanceFunction(aTL) + myCriteria;
1172   if(aBoundaryDist * aBoundaryDist < aDist2) {
1173     aDist2 = aBoundaryDist * aBoundaryDist;
1174     aTx = aTL;
1175   }
1176
1177   Standard_Real aParameter = (aTF + aTL) * 0.5;
1178   aBoundaryDist = DistanceFunction(aParameter) + myCriteria;
1179   if(aBoundaryDist * aBoundaryDist < aDist2) {
1180     aDist2 = aBoundaryDist * aBoundaryDist;
1181     aTx = aParameter;
1182   }
1183
1184   if(aDist2 > myCriteria * myCriteria) {
1185     return theflag;
1186   }
1187   
1188   if (fabs (aTx-aTF) < myEpsT) {
1189     return !theflag;
1190   }
1191
1192   if (fabs (aTx-aTL) < myEpsT) {
1193     return !theflag;
1194   }
1195
1196   if (aTx>aTF && aTx<aTL) {
1197     return !theflag;
1198   }
1199
1200   return theflag;
1201 }
1202 //=======================================================================
1203 //function : Perform
1204 //purpose  : 
1205 //=======================================================================
1206 void IntTools_EdgeFace::Perform() 
1207 {
1208   Standard_Integer i, aNb;
1209   IntTools_CommonPrt aCommonPrt;
1210   //
1211   aCommonPrt.SetEdge1(myEdge);
1212   //
1213   myErrorStatus=0;
1214   CheckData();
1215   if (myErrorStatus) {
1216     return;
1217   }
1218   //
1219   if (myContext.IsNull()) {
1220     myContext=new IntTools_Context;
1221   }
1222   //
1223   myIsDone = Standard_False;
1224   myC.Initialize(myEdge);
1225   GeomAbs_CurveType aCurveType;
1226   aCurveType=myC.GetType();
1227   //
1228   // Prepare myCriteria
1229   if (aCurveType==GeomAbs_BSplineCurve||
1230       aCurveType==GeomAbs_BezierCurve) {
1231     //--- 5112
1232     Standard_Real diff1 = (myTolE/myTolF);
1233     Standard_Real diff2 = (myTolF/myTolE);
1234     if( diff1 > 100 || diff2 > 100 ) {
1235       myCriteria = Max(myTolE,myTolF);
1236     }
1237     else //--- 5112
1238       myCriteria=1.5*myTolE+myTolF;
1239   }
1240   else {
1241     myCriteria=myTolE+myTolF;
1242   }
1243   
1244   myTmin=myRange.First();
1245   myTmax=myRange.Last();
1246   
1247   myS.Initialize (myFace,Standard_True);
1248   
1249   if(myContext.IsNull()) {
1250     myFClass2d.Init(myFace, 1.e-6);
1251   }
1252   
1253   IntTools_BeanFaceIntersector anIntersector(myC, myS, myTolE, myTolF);
1254   anIntersector.SetBeanParameters(myRange.First(), myRange.Last());
1255   //
1256   anIntersector.SetContext(myContext);
1257   //
1258   anIntersector.Perform();
1259   
1260   if(!anIntersector.IsDone()) {
1261     return;
1262   }
1263   
1264   for(Standard_Integer r = 1; r <= anIntersector.Result().Length(); r++) {
1265     const IntTools_Range& aRange = anIntersector.Result().Value(r);
1266     
1267     if(IsProjectable(IntTools_Tools::IntermediatePoint(aRange.First(), aRange.Last()))) {
1268       aCommonPrt.SetRange1(aRange.First(), aRange.Last());
1269       mySeqOfCommonPrts.Append(aCommonPrt);
1270     }
1271   }
1272
1273   aNb = mySeqOfCommonPrts.Length();
1274
1275   for (i=1; i<=aNb; i++) {
1276     IntTools_CommonPrt& aCP=mySeqOfCommonPrts.ChangeValue(i);
1277     //
1278     Standard_Real aTx1, aTx2;
1279     gp_Pnt aPx1, aPx2;
1280     //
1281     aCP.Range1(aTx1, aTx2);
1282     myC.D0(aTx1, aPx1);
1283     myC.D0(aTx2, aPx2);
1284     aCP.SetBoundingPoints(aPx1, aPx2);
1285     //
1286     MakeType (aCP); 
1287   }
1288   {
1289     // Line\Cylinder's Common Parts treatement
1290     GeomAbs_CurveType   aCType;
1291     GeomAbs_SurfaceType aSType;
1292     TopAbs_ShapeEnum aType;
1293     Standard_Boolean bIsTouch;
1294     Standard_Real aTx;
1295     
1296     aCType=myC.GetType();
1297     aSType=myS.GetType();
1298     
1299     if (aCType==GeomAbs_Line && aSType==GeomAbs_Cylinder) {
1300       for (i=1; i<=aNb; i++) {
1301         IntTools_CommonPrt& aCP=mySeqOfCommonPrts(i);
1302         aType=aCP.Type();
1303         if (aType==TopAbs_EDGE) {
1304           bIsTouch=CheckTouch (aCP, aTx);
1305           if (bIsTouch) {
1306             aCP.SetType(TopAbs_VERTEX);
1307             aCP.SetVertexParameter1(aTx);
1308             //aCP.SetRange1 (aTx, aTx);
1309           }
1310         }
1311         else if (aType==TopAbs_VERTEX) {
1312           bIsTouch=CheckTouchVertex (aCP, aTx);
1313           if (bIsTouch) {
1314             aCP.SetVertexParameter1(aTx);
1315             //aCP.SetRange1 (aTx, aTx);
1316           }
1317         }
1318       }
1319     }
1320     
1321     // Circle\Plane's Common Parts treatement
1322     
1323     if (aCType==GeomAbs_Circle && aSType==GeomAbs_Plane) {
1324       Standard_Boolean bIsCoplanar, bIsRadius;
1325       bIsCoplanar=IsCoplanar(myC, myS);
1326       bIsRadius=IsRadius(myC, myS, myCriteria);
1327       if (!bIsCoplanar && !bIsRadius) {
1328         for (i=1; i<=aNb; i++) {
1329           IntTools_CommonPrt& aCP=mySeqOfCommonPrts(i);
1330           aType=aCP.Type();
1331           if (aType==TopAbs_EDGE) {
1332             bIsTouch=CheckTouch (aCP, aTx);
1333             if (bIsTouch) {
1334               aCP.SetType(TopAbs_VERTEX);
1335               aCP.SetVertexParameter1(aTx);
1336               //aCP.SetRange1 (aTx, aTx);
1337             }
1338           }
1339           else if (aType==TopAbs_VERTEX) {
1340             bIsTouch=CheckTouchVertex (aCP, aTx);
1341             if (bIsTouch) {
1342               aCP.SetVertexParameter1(aTx);
1343               //aCP.SetRange1 (aTx, aTx);
1344             }
1345           }
1346         }
1347       }
1348     }
1349   }
1350   myIsDone=Standard_True;
1351 }
1352
1353 //
1354 // myErrorStatus
1355 // 1 - the method Perform() is not invoked  
1356 // 2,3,4,5 -the method CheckData() fails
1357 // 6 - PrepareArgs() problems
1358 // 7 - No Projectable ranges
1359 // 8,9 - PrepareArgs() problems occured inside  projectable Ranges
1360 // 11 - can't fill array  aFunc(i) in PrepareArgsFuncArrays 
1361
1362
1363 //=======================================================================
1364 //function : CheckTouch 
1365 //purpose  : 
1366 //=======================================================================
1367 Standard_Boolean IntTools_EdgeFace::CheckTouchVertex 
1368   (const IntTools_CommonPrt& aCP,
1369    Standard_Real& aTx) 
1370 {
1371   Standard_Real aTF, aTL, Tol, U1f,U1l,V1f,V1l;
1372   Standard_Real aEpsT, af, al,aDist2, aMinDist2, aTm, aDist2New;
1373   Standard_Boolean theflag=Standard_False;
1374   Standard_Integer aNbExt, i, iLower ;
1375   GeomAbs_CurveType aType;
1376   //
1377   aCP.Range1(aTF, aTL);
1378   aType=myC.GetType();
1379   //
1380   aEpsT=8.e-5;
1381   if (aType==GeomAbs_Line) {
1382     aEpsT=9.e-5;
1383   }
1384   //
1385   aTm=0.5*(aTF+aTL);
1386   aDist2=DistanceFunction(aTm);
1387   aDist2 *= aDist2;
1388
1389   Tol = Precision::PConfusion();
1390
1391   const Handle(Geom_Curve)&  Curve =BRep_Tool::Curve  (myC.Edge(), af, al);
1392   const Handle(Geom_Surface)& Surface=BRep_Tool::Surface(myS.Face());
1393
1394   Surface->Bounds(U1f,U1l,V1f,V1l);
1395   
1396   GeomAdaptor_Curve   TheCurve   (Curve,aTF, aTL);
1397   GeomAdaptor_Surface TheSurface (Surface, U1f, U1l, V1f, V1l); 
1398      
1399   Extrema_ExtCS anExtrema (TheCurve, TheSurface, Tol, Tol);
1400    
1401   if(!anExtrema.IsDone()) {
1402     return theflag;
1403   }
1404   if (anExtrema.IsParallel()) {
1405     return theflag;
1406   }
1407   
1408   aNbExt=anExtrema.NbExt() ;
1409   if (!aNbExt) {
1410      return theflag;
1411   }
1412
1413   iLower=1;
1414   aMinDist2=1.e100;
1415   for (i=1; i<=aNbExt; ++i) {
1416     aDist2=anExtrema.SquareDistance(i);
1417     if (aDist2 < aMinDist2) {
1418       aMinDist2=aDist2;
1419       iLower=i;
1420     }
1421   }
1422
1423   aDist2New=anExtrema.SquareDistance(iLower);
1424   
1425   if (aDist2New > aDist2) {
1426     aTx=aTm;
1427     return !theflag;
1428   }
1429   
1430   if (aDist2New > myCriteria * myCriteria) {
1431     return theflag;
1432   }
1433
1434   Extrema_POnCurv aPOnC;
1435   Extrema_POnSurf aPOnS;
1436   anExtrema.Points(iLower, aPOnC, aPOnS);
1437
1438  
1439   aTx=aPOnC.Parameter();
1440   ///
1441   if (fabs (aTx-aTF) < aEpsT) {
1442     return theflag;
1443   }
1444
1445   if (fabs (aTx-aTL) < aEpsT) {
1446     return theflag;
1447   }
1448
1449   if (aTx>aTF && aTx<aTL) {
1450     return !theflag;
1451   }
1452
1453   return theflag;
1454 }
1455
1456
1457 //=======================================================================
1458 //function :  IsCoplanar
1459 //purpose  : 
1460 //=======================================================================
1461 Standard_Boolean IsCoplanar (const BRepAdaptor_Curve& aCurve ,
1462                              const BRepAdaptor_Surface& aSurface)
1463 {
1464   Standard_Boolean bFlag=Standard_False;
1465
1466   GeomAbs_CurveType   aCType;
1467   GeomAbs_SurfaceType aSType;
1468
1469   aCType=aCurve.GetType();
1470   aSType=aSurface.GetType();
1471     
1472   if (aCType==GeomAbs_Circle && aSType==GeomAbs_Plane) {
1473     gp_Circ aCirc=aCurve.Circle();
1474     const gp_Ax1& anAx1=aCirc.Axis();
1475     const gp_Dir& aDirAx1=anAx1.Direction();
1476     
1477     gp_Pln aPln=aSurface.Plane();
1478     const gp_Ax1& anAx=aPln.Axis();
1479     const gp_Dir& aDirPln=anAx.Direction();
1480
1481     bFlag=IntTools_Tools::IsDirsCoinside(aDirAx1, aDirPln);
1482   }
1483   return bFlag;
1484 }
1485 //=======================================================================
1486 //function :  IsRadius
1487 //purpose  : 
1488 //=======================================================================
1489 Standard_Boolean IsRadius (const BRepAdaptor_Curve& aCurve,
1490                            const BRepAdaptor_Surface& aSurface,
1491                            const Standard_Real aCriteria)
1492 {
1493   Standard_Boolean bFlag=Standard_False;
1494
1495   GeomAbs_CurveType   aCType;
1496   GeomAbs_SurfaceType aSType;
1497
1498   aCType=aCurve.GetType();
1499   aSType=aSurface.GetType();
1500     
1501   if (aCType==GeomAbs_Circle && aSType==GeomAbs_Plane) {
1502     gp_Circ aCirc=aCurve.Circle();
1503     const gp_Pnt aCenter=aCirc.Location();
1504     Standard_Real aR=aCirc.Radius();
1505     gp_Pln aPln=aSurface.Plane();
1506     Standard_Real aD=aPln.Distance(aCenter);
1507     if (fabs (aD-aR) < aCriteria) {
1508       return !bFlag;
1509     }
1510   }
1511   return bFlag;
1512 }
1513 //
1514 //=======================================================================
1515 //function :  AdaptiveDiscret
1516 //purpose  : 
1517 //=======================================================================
1518 Standard_Integer AdaptiveDiscret (const Standard_Integer iDiscret,
1519                                   const BRepAdaptor_Curve& aCurve ,
1520                                   const BRepAdaptor_Surface& aSurface)
1521 {
1522   Standard_Integer iDiscretNew;
1523
1524   iDiscretNew=iDiscret;
1525
1526   GeomAbs_SurfaceType aSType;
1527
1528   aSType=aSurface.GetType();
1529     
1530   if (aSType==GeomAbs_Cylinder) {
1531    Standard_Real aELength, aRadius, dLR;
1532
1533    aELength=IntTools::Length(aCurve.Edge());
1534    
1535    gp_Cylinder aCylinder=aSurface.Cylinder();
1536    aRadius=aCylinder.Radius();
1537    dLR=2*aRadius;
1538
1539    iDiscretNew=(Standard_Integer)(aELength/dLR);
1540    
1541    if (iDiscretNew<iDiscret) {
1542      iDiscretNew=iDiscret;
1543    }
1544      
1545   }
1546   return iDiscretNew;
1547 }
1548
1549
1550 #ifdef WNT
1551 #pragma warning ( default : 4101 )
1552 #endif