0028599: Replacement of old Boolean operations with new ones in BRepProj_Projection...
[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_BeanFaceIntersector.hxx>
43 #include <IntTools_CArray1OfInteger.hxx>
44 #include <IntTools_CommonPrt.hxx>
45 #include <IntTools_Context.hxx>
46 #include <IntTools_EdgeFace.hxx>
47 #include <IntTools_FClass2d.hxx>
48 #include <IntTools_Range.hxx>
49 #include <IntTools_Root.hxx>
50 #include <IntTools_Tools.hxx>
51 #include <Precision.hxx>
52 #include <TopoDS_Edge.hxx>
53 #include <TopoDS_Face.hxx>
54
55 #include <algorithm>
56 static
57   Standard_Boolean IsCoplanar (const BRepAdaptor_Curve&  ,
58                                const BRepAdaptor_Surface& );
59 static
60   Standard_Boolean IsRadius (const BRepAdaptor_Curve& aCurve ,
61                              const BRepAdaptor_Surface& aSurface,
62                              const Standard_Real aCriteria);
63
64 //=======================================================================
65 //function : IntTools_EdgeFace::IntTools_EdgeFace
66 //purpose  : 
67 //=======================================================================
68   IntTools_EdgeFace::IntTools_EdgeFace()
69 {
70   myFuzzyValue = Precision::Confusion();
71   myIsDone=Standard_False;
72   myErrorStatus=1;
73   myQuickCoincidenceCheck=Standard_False;
74 }
75 //=======================================================================
76 //function :  IsCoincident
77 //purpose  : 
78 //=======================================================================
79 Standard_Boolean IntTools_EdgeFace::IsCoincident() 
80 {
81   Standard_Integer i, iCnt;
82   Standard_Real dT, aT, aD, aT1, aT2, aU, aV;
83
84   gp_Pnt aP;
85   TopAbs_State aState;
86   gp_Pnt2d aP2d;
87   //
88   GeomAPI_ProjectPointOnSurf& aProjector=myContext->ProjPS(myFace);
89
90   Standard_Integer aNbSeg=23;
91   if (myC.GetType() == GeomAbs_Line &&
92       myS.GetType() == GeomAbs_Plane)
93     aNbSeg = 2; // Check only three points for Line/Plane intersection
94
95   const Standard_Real aTresh=0.5;
96   const Standard_Integer aTreshIdxF = RealToInt((aNbSeg+1)*0.25),
97                          aTreshIdxL = RealToInt((aNbSeg+1)*0.75);
98   const Handle(Geom_Surface) aSurf = BRep_Tool::Surface(myFace);
99
100   aT1=myRange.First();
101   aT2=myRange.Last();
102   dT=(aT2-aT1)/aNbSeg;
103   //
104   Standard_Boolean isClassified = Standard_False;
105   iCnt=0;
106   for(i=0; i <= aNbSeg; ++i) {
107     aT = aT1+i*dT;
108     aP=myC.Value(aT);
109     //
110     aProjector.Perform(aP);
111     if (!aProjector.IsDone()) {
112       continue;
113     }
114     //
115     
116     aD=aProjector.LowerDistance();
117     if (aD>myCriteria) {
118       continue;
119     }
120     //
121
122     ++iCnt; 
123
124     //We classify only three points: in the begin, in the 
125     //end and in the middle of the edge.
126     //However, exact middle point (when i == (aNbSeg + 1)/2)
127     //can be unprojectable. Therefore, it will not be able to
128     //be classified. Therefore, points with indexes in 
129     //[aTreshIdxF, aTreshIdxL] range are made available 
130     //for classification.
131     //isClassified == TRUE if MIDDLE point has been choosen and
132     //classified correctly.
133
134     if(((0 < i) && (i < aTreshIdxF)) || ((aTreshIdxL < i ) && (i < aNbSeg)))
135       continue;
136
137     if(isClassified && (i != aNbSeg))
138       continue;
139
140     aProjector.LowerDistanceParameters(aU, aV);
141     aP2d.SetX(aU);
142     aP2d.SetY(aV);
143
144     IntTools_FClass2d& aClass2d=myContext->FClass2d(myFace);
145     aState = aClass2d.Perform(aP2d);
146     
147     if(aState == TopAbs_OUT)
148       return Standard_False;
149
150     if(i != 0)
151       isClassified = Standard_True;
152   }
153   //
154   const Standard_Real aCoeff=(Standard_Real)iCnt/((Standard_Real)aNbSeg+1);
155   return (aCoeff > aTresh);
156 }
157 //=======================================================================
158 //function : CheckData
159 //purpose  : 
160 //=======================================================================
161 void IntTools_EdgeFace::CheckData()
162 {
163   if (BRep_Tool::Degenerated(myEdge)) {
164     myErrorStatus=2;
165   }
166   if (!BRep_Tool::IsGeometric(myEdge)) { 
167      myErrorStatus=3;
168   }
169 }
170
171 //=======================================================================
172 //function : IsProjectable
173 //purpose  : 
174 //=======================================================================
175 Standard_Boolean IntTools_EdgeFace::IsProjectable
176   (const Standard_Real aT) const
177 {
178   Standard_Boolean bFlag; 
179   gp_Pnt aPC;
180   //
181   myC.D0(aT, aPC);
182   bFlag=myContext->IsValidPointForFace(aPC, myFace, myCriteria);
183   //
184   return bFlag;
185 }
186 //=======================================================================
187 //function : DistanceFunction
188 //purpose  : 
189 //=======================================================================
190 Standard_Real IntTools_EdgeFace::DistanceFunction
191   (const Standard_Real t)
192 {
193   Standard_Real aD;
194
195   //
196   gp_Pnt P;
197   myC.D0(t, P);
198   //
199   Standard_Boolean bIsEqDistance;
200
201   bIsEqDistance= IntTools_EdgeFace::IsEqDistance(P, myS, 1.e-7, aD); 
202   if (bIsEqDistance) {
203     aD=aD-myCriteria;
204     return aD; 
205   }
206   
207   //
208   Standard_Boolean bFlag = Standard_False;
209
210   GeomAPI_ProjectPointOnSurf& aLocProj = myContext->ProjPS(myFace);
211   aLocProj.Perform(P);
212   bFlag = aLocProj.IsDone();
213   
214   if(bFlag) {
215     aD = aLocProj.LowerDistance();
216   }
217   //
218   
219   if (!bFlag) {
220     myErrorStatus = 4;
221     return 99.;
222   }
223   
224   // 
225   //   aD=aProjector.LowerDistance();
226   // 
227   aD=aD-myCriteria;
228   return aD; 
229 }
230 //
231 //=======================================================================
232 //function : IsEqDistance
233 //purpose  : 
234 //=======================================================================
235 Standard_Boolean IntTools_EdgeFace::IsEqDistance
236   (const gp_Pnt& aP,
237    const BRepAdaptor_Surface& aBAS,
238    const Standard_Real aTol,
239    Standard_Real& aD)
240 {
241   Standard_Boolean bRetFlag=Standard_True;
242
243   GeomAbs_SurfaceType aSurfType=aBAS.GetType();
244
245   if (aSurfType==GeomAbs_Cylinder) {
246     gp_Cylinder aCyl=aBAS.Cylinder();
247     const gp_Ax1& anAx1  =aCyl.Axis();
248     gp_Lin aLinAxis(anAx1);
249     Standard_Real aDC, aRadius=aCyl.Radius();
250     aDC=aLinAxis.Distance(aP);
251     if (aDC < aTol) {
252       aD=aRadius;
253       return bRetFlag; 
254     }
255   }
256
257   if (aSurfType==GeomAbs_Cone) {
258     gp_Cone aCone=aBAS.Cone();
259     const gp_Ax1& anAx1  =aCone.Axis();
260     gp_Lin aLinAxis(anAx1);
261     Standard_Real aDC, aRadius, aDS, aSemiAngle;
262     aDC=aLinAxis.Distance(aP);
263     if (aDC < aTol) {
264       gp_Pnt anApex=aCone.Apex();
265       aSemiAngle=aCone.SemiAngle();
266       aDS=aP.Distance(anApex);
267       
268       aRadius=aDS*tan(aSemiAngle);
269       aD=aRadius;
270       return bRetFlag; 
271     }
272   }
273
274   if (aSurfType==GeomAbs_Torus) {
275     Standard_Real aMajorRadius, aMinorRadius, aDC;
276
277     gp_Torus aTorus=aBAS.Torus();
278     gp_Pnt aPLoc=aTorus.Location();
279     aMajorRadius=aTorus.MajorRadius();
280     
281     aDC=fabs(aPLoc.Distance(aP)-aMajorRadius);
282     if (aDC < aTol) {
283       aMinorRadius=aTorus.MinorRadius();
284       aD=aMinorRadius;
285       return bRetFlag; 
286     }
287   }
288   return !bRetFlag; 
289 }
290 //
291 //=======================================================================
292 //function : MakeType
293 //purpose  : 
294 //=======================================================================
295 Standard_Integer IntTools_EdgeFace::MakeType
296   (IntTools_CommonPrt&  aCommonPrt)
297 {
298   Standard_Real  af1, al1;
299   Standard_Real  df1, tm;
300   Standard_Boolean bAllNullFlag;
301   //
302   bAllNullFlag=aCommonPrt.AllNullFlag();
303   if (bAllNullFlag) {
304     aCommonPrt.SetType(TopAbs_EDGE);
305     return 0;
306   }
307   //
308   aCommonPrt.Range1(af1, al1);
309
310   {
311     gp_Pnt aPF, aPL;
312     myC.D0(af1, aPF);
313     myC.D0(al1, aPL);
314     df1=aPF.Distance(aPL);
315     Standard_Boolean isWholeRange = Standard_False;
316     
317     if((Abs(af1 - myRange.First()) < myC.Resolution(myCriteria)) &&
318        (Abs(al1 - myRange.Last()) < myC.Resolution(myCriteria)))
319       isWholeRange = Standard_True;
320     
321     
322     if ((df1 > myCriteria * 2.) && isWholeRange) {
323       aCommonPrt.SetType(TopAbs_EDGE);
324     }
325     else {
326       if(isWholeRange) {
327         tm = (af1 + al1) * 0.5;
328         
329         if(aPF.Distance(myC.Value(tm)) > myCriteria * 2.) {
330           aCommonPrt.SetType(TopAbs_EDGE);
331           return 0;
332         }
333       }
334       
335       if(!CheckTouch(aCommonPrt, tm)) {
336         tm = (af1 + al1) * 0.5;
337       }
338       aCommonPrt.SetType(TopAbs_VERTEX);
339       aCommonPrt.SetVertexParameter1(tm);
340       aCommonPrt.SetRange1 (af1, al1);
341     }
342   }
343  return 0;
344 }
345
346
347 //=======================================================================
348 //function : CheckTouch 
349 //purpose  : 
350 //=======================================================================
351 Standard_Boolean IntTools_EdgeFace::CheckTouch
352   (const IntTools_CommonPrt& aCP,
353    Standard_Real&            aTx) 
354 {
355   if (myC.GetType() == GeomAbs_Line &&
356       myS.GetType() == GeomAbs_Plane) {
357     return Standard_False;
358   }
359   //
360   Standard_Real aTF, aTL, Tol, U1f, U1l, V1f, V1l, af, al,aDist2, aMinDist2;
361   Standard_Boolean theflag=Standard_False;
362   Standard_Integer aNbExt, iLower;
363
364   aCP.Range1(aTF, aTL);
365
366   //
367   Standard_Real aCR;
368   aCR=myC.Resolution(myCriteria);
369   if((Abs(aTF - myRange.First()) < aCR) &&
370      (Abs(aTL - myRange.Last())  < aCR)) {
371     return theflag; // EDGE 
372   }
373   //
374
375   Tol = Precision::PConfusion();
376
377   const Handle(Geom_Curve)&  Curve   =BRep_Tool::Curve  (myC.Edge(), af, al);
378   const Handle(Geom_Surface)& Surface=BRep_Tool::Surface(myS.Face());
379   //   Surface->Bounds(U1f,U1l,V1f,V1l);
380   U1f = myS.FirstUParameter();
381   U1l = myS.LastUParameter();
382   V1f = myS.FirstVParameter();
383   V1l = myS.LastVParameter();
384   
385   GeomAdaptor_Curve   TheCurve   (Curve,aTF, aTL);
386   GeomAdaptor_Surface TheSurface (Surface, U1f, U1l, V1f, V1l); 
387      
388   Extrema_ExtCS anExtrema (TheCurve, TheSurface, Tol, Tol);
389
390   aDist2 = 1.e100;
391
392   if(anExtrema.IsDone()) {
393     aMinDist2 = aDist2;
394
395     if(!anExtrema.IsParallel()) {
396       aNbExt=anExtrema.NbExt();
397       
398       if(aNbExt > 0) {
399  iLower=1;
400  for (Standard_Integer i=1; i<=aNbExt; i++) {
401    aDist2=anExtrema.SquareDistance(i);
402    if (aDist2 < aMinDist2) {
403      aMinDist2=aDist2;
404      iLower=i;
405    }
406  }
407  aDist2=anExtrema.SquareDistance(iLower);
408  Extrema_POnCurv aPOnC;
409  Extrema_POnSurf aPOnS;
410  anExtrema.Points(iLower, aPOnC, aPOnS);
411  aTx=aPOnC.Parameter();
412       }
413       else {
414  // modified by NIZHNY-MKK  Thu Jul 21 11:35:32 2005.BEGIN
415  IntCurveSurface_HInter anExactIntersector;
416   
417  Handle(GeomAdaptor_HCurve) aCurve     = new GeomAdaptor_HCurve(TheCurve);
418  Handle(GeomAdaptor_HSurface) aSurface = new GeomAdaptor_HSurface(TheSurface);
419  
420  anExactIntersector.Perform(aCurve, aSurface);
421
422  if(anExactIntersector.IsDone()) {
423    for(Standard_Integer i = 1; i <= anExactIntersector.NbPoints(); i++) {
424      const IntCurveSurface_IntersectionPoint& aPoint = anExactIntersector.Point(i);
425       
426      if((aPoint.W() >= aTF) && (aPoint.W() <= aTL)) {
427        aDist2=0.;
428        aTx = aPoint.W();
429      }
430    }
431  }
432  // modified by NIZHNY-MKK  Thu Jul 21 11:35:40 2005.END
433       }
434     }
435     else {
436       return theflag;
437     }
438   }
439
440   Standard_Real aBoundaryDist;
441
442   aBoundaryDist = DistanceFunction(aTF) + myCriteria;
443   if(aBoundaryDist * aBoundaryDist < aDist2) {
444     aDist2 = aBoundaryDist * aBoundaryDist;
445     aTx = aTF;
446   }
447   
448   aBoundaryDist = DistanceFunction(aTL) + myCriteria;
449   if(aBoundaryDist * aBoundaryDist < aDist2) {
450     aDist2 = aBoundaryDist * aBoundaryDist;
451     aTx = aTL;
452   }
453
454   Standard_Real aParameter = (aTF + aTL) * 0.5;
455   aBoundaryDist = DistanceFunction(aParameter) + myCriteria;
456   if(aBoundaryDist * aBoundaryDist < aDist2) {
457     aDist2 = aBoundaryDist * aBoundaryDist;
458     aTx = aParameter;
459   }
460
461   if(aDist2 > myCriteria * myCriteria) {
462     return theflag;
463   }
464   
465   if (fabs (aTx-aTF) < Precision::PConfusion()) {
466     return !theflag;
467   }
468
469   if (fabs (aTx-aTL) < Precision::PConfusion()) {
470     return !theflag;
471   }
472
473   if (aTx>aTF && aTx<aTL) {
474     return !theflag;
475   }
476
477   return theflag;
478 }
479
480 //=======================================================================
481 //function : Perform
482 //purpose  : 
483 //=======================================================================
484 void IntTools_EdgeFace::Perform() 
485 {
486   Standard_Integer i, aNb;
487   IntTools_CommonPrt aCommonPrt;
488   //
489   aCommonPrt.SetEdge1(myEdge);
490   //
491   myErrorStatus=0;
492   CheckData();
493   if (myErrorStatus) {
494     return;
495   }
496   //
497   if (myContext.IsNull()) {
498     myContext=new IntTools_Context;
499   }
500   //
501   myIsDone = Standard_False;
502   myC.Initialize(myEdge);
503   GeomAbs_CurveType aCurveType;
504   aCurveType=myC.GetType();
505   //
506   // Prepare myCriteria
507   Standard_Real aFuzz = myFuzzyValue / 2.;
508   Standard_Real aTolF = BRep_Tool::Tolerance(myFace) + aFuzz;
509   Standard_Real aTolE = BRep_Tool::Tolerance(myEdge) + aFuzz;
510   if (aCurveType == GeomAbs_BSplineCurve ||
511       aCurveType==GeomAbs_BezierCurve) {
512     //--- 5112
513     Standard_Real diff1 = (aTolE/aTolF);
514     Standard_Real diff2 = (aTolF/aTolE);
515     if( diff1 > 100 || diff2 > 100 ) {
516       myCriteria = Max(aTolE,aTolF);
517     }
518     else //--- 5112
519       myCriteria = 1.5*aTolE + aTolF;
520   }
521   else {
522     myCriteria = aTolE + aTolF;
523   }
524   
525   myS = myContext->SurfaceAdaptor(myFace);
526   
527   if (myQuickCoincidenceCheck) {
528     if (IsCoincident()) {
529       aCommonPrt.SetType(TopAbs_EDGE);
530       aCommonPrt.SetRange1(myRange.First(), myRange.Last());
531       mySeqOfCommonPrts.Append(aCommonPrt);
532       myIsDone=Standard_True;
533       return;
534     }
535   }
536   //
537   IntTools_BeanFaceIntersector anIntersector(myC, myS, aTolE, aTolF);
538   anIntersector.SetBeanParameters(myRange.First(), myRange.Last());
539   //
540   anIntersector.SetContext(myContext);
541   //
542   anIntersector.Perform();
543   
544   if(!anIntersector.IsDone()) {
545     return;
546   }
547   
548   for(Standard_Integer r = 1; r <= anIntersector.Result().Length(); r++) {
549     const IntTools_Range& aRange = anIntersector.Result().Value(r);
550     
551     if(IsProjectable(IntTools_Tools::IntermediatePoint(aRange.First(), aRange.Last()))) {
552       aCommonPrt.SetRange1(aRange.First(), aRange.Last());
553       mySeqOfCommonPrts.Append(aCommonPrt);
554     }
555   }
556
557   aNb = mySeqOfCommonPrts.Length();
558
559   for (i=1; i<=aNb; i++) {
560     IntTools_CommonPrt& aCP=mySeqOfCommonPrts.ChangeValue(i);
561     //
562     Standard_Real aTx1, aTx2;
563     gp_Pnt aPx1, aPx2;
564     //
565     aCP.Range1(aTx1, aTx2);
566     myC.D0(aTx1, aPx1);
567     myC.D0(aTx2, aPx2);
568     aCP.SetBoundingPoints(aPx1, aPx2);
569     //
570     MakeType (aCP); 
571   }
572   {
573     // Line\Cylinder's Common Parts treatement
574     GeomAbs_CurveType   aCType;
575     GeomAbs_SurfaceType aSType;
576     TopAbs_ShapeEnum aType;
577     Standard_Boolean bIsTouch;
578     Standard_Real aTx;
579     
580     aCType=myC.GetType();
581     aSType=myS.GetType();
582     
583     if (aCType==GeomAbs_Line && aSType==GeomAbs_Cylinder) {
584       for (i=1; i<=aNb; i++) {
585         IntTools_CommonPrt& aCP=mySeqOfCommonPrts(i);
586         aType=aCP.Type();
587         if (aType==TopAbs_EDGE) {
588           bIsTouch=CheckTouch (aCP, aTx);
589           if (bIsTouch) {
590             aCP.SetType(TopAbs_VERTEX);
591             aCP.SetVertexParameter1(aTx);
592             //aCP.SetRange1 (aTx, aTx);
593           }
594         }
595         else if (aType==TopAbs_VERTEX) {
596           bIsTouch=CheckTouchVertex (aCP, aTx);
597           if (bIsTouch) {
598             aCP.SetVertexParameter1(aTx);
599             //aCP.SetRange1 (aTx, aTx);
600           }
601         }
602       }
603     }
604     
605     // Circle\Plane's Common Parts treatement
606     
607     if (aCType==GeomAbs_Circle && aSType==GeomAbs_Plane) {
608       Standard_Boolean bIsCoplanar, bIsRadius;
609       bIsCoplanar=IsCoplanar(myC, myS);
610       bIsRadius=IsRadius(myC, myS, myCriteria);
611       if (!bIsCoplanar && !bIsRadius) {
612         for (i=1; i<=aNb; i++) {
613           IntTools_CommonPrt& aCP=mySeqOfCommonPrts(i);
614           aType=aCP.Type();
615           if (aType==TopAbs_EDGE) {
616             bIsTouch=CheckTouch (aCP, aTx);
617             if (bIsTouch) {
618               aCP.SetType(TopAbs_VERTEX);
619               aCP.SetVertexParameter1(aTx);
620               //aCP.SetRange1 (aTx, aTx);
621             }
622           }
623           else if (aType==TopAbs_VERTEX) {
624             bIsTouch=CheckTouchVertex (aCP, aTx);
625             if (bIsTouch) {
626               aCP.SetVertexParameter1(aTx);
627               //aCP.SetRange1 (aTx, aTx);
628             }
629           }
630         }
631       }
632     }
633   }
634   myIsDone=Standard_True;
635 }
636
637 //=======================================================================
638 //function : CheckTouch 
639 //purpose  : 
640 //=======================================================================
641 Standard_Boolean IntTools_EdgeFace::CheckTouchVertex 
642   (const IntTools_CommonPrt& aCP,
643    Standard_Real& aTx) 
644 {
645   Standard_Real aTF, aTL, Tol, U1f,U1l,V1f,V1l;
646   Standard_Real aEpsT, af, al,aDist2, aMinDist2, aTm, aDist2New;
647   Standard_Boolean theflag=Standard_False;
648   Standard_Integer aNbExt, i, iLower ;
649   GeomAbs_CurveType aType;
650   //
651   aCP.Range1(aTF, aTL);
652   aType=myC.GetType();
653   //
654   aEpsT=8.e-5;
655   if (aType==GeomAbs_Line) {
656     aEpsT=9.e-5;
657   }
658   //
659   aTm=0.5*(aTF+aTL);
660   aDist2=DistanceFunction(aTm);
661   aDist2 *= aDist2;
662
663   Tol = Precision::PConfusion();
664
665   const Handle(Geom_Curve)&  Curve =BRep_Tool::Curve  (myC.Edge(), af, al);
666   const Handle(Geom_Surface)& Surface=BRep_Tool::Surface(myS.Face());
667
668   Surface->Bounds(U1f,U1l,V1f,V1l);
669   
670   GeomAdaptor_Curve   TheCurve   (Curve,aTF, aTL);
671   GeomAdaptor_Surface TheSurface (Surface, U1f, U1l, V1f, V1l); 
672      
673   Extrema_ExtCS anExtrema (TheCurve, TheSurface, Tol, Tol);
674    
675   if(!anExtrema.IsDone()) {
676     return theflag;
677   }
678   if (anExtrema.IsParallel()) {
679     return theflag;
680   }
681   
682   aNbExt=anExtrema.NbExt() ;
683   if (!aNbExt) {
684      return theflag;
685   }
686
687   iLower=1;
688   aMinDist2=1.e100;
689   for (i=1; i<=aNbExt; ++i) {
690     aDist2=anExtrema.SquareDistance(i);
691     if (aDist2 < aMinDist2) {
692       aMinDist2=aDist2;
693       iLower=i;
694     }
695   }
696
697   aDist2New=anExtrema.SquareDistance(iLower);
698   
699   if (aDist2New > aDist2) {
700     aTx=aTm;
701     return !theflag;
702   }
703   
704   if (aDist2New > myCriteria * myCriteria) {
705     return theflag;
706   }
707
708   Extrema_POnCurv aPOnC;
709   Extrema_POnSurf aPOnS;
710   anExtrema.Points(iLower, aPOnC, aPOnS);
711
712  
713   aTx=aPOnC.Parameter();
714   ///
715   if (fabs (aTx-aTF) < aEpsT) {
716     return theflag;
717   }
718
719   if (fabs (aTx-aTL) < aEpsT) {
720     return theflag;
721   }
722
723   if (aTx>aTF && aTx<aTL) {
724     return !theflag;
725   }
726
727   return theflag;
728 }
729
730
731 //=======================================================================
732 //function :  IsCoplanar
733 //purpose  : 
734 //=======================================================================
735 Standard_Boolean IsCoplanar (const BRepAdaptor_Curve& aCurve ,
736                              const BRepAdaptor_Surface& aSurface)
737 {
738   Standard_Boolean bFlag=Standard_False;
739
740   GeomAbs_CurveType   aCType;
741   GeomAbs_SurfaceType aSType;
742
743   aCType=aCurve.GetType();
744   aSType=aSurface.GetType();
745     
746   if (aCType==GeomAbs_Circle && aSType==GeomAbs_Plane) {
747     gp_Circ aCirc=aCurve.Circle();
748     const gp_Ax1& anAx1=aCirc.Axis();
749     const gp_Dir& aDirAx1=anAx1.Direction();
750     
751     gp_Pln aPln=aSurface.Plane();
752     const gp_Ax1& anAx=aPln.Axis();
753     const gp_Dir& aDirPln=anAx.Direction();
754
755     bFlag=IntTools_Tools::IsDirsCoinside(aDirAx1, aDirPln);
756   }
757   return bFlag;
758 }
759 //=======================================================================
760 //function :  IsRadius
761 //purpose  : 
762 //=======================================================================
763 Standard_Boolean IsRadius (const BRepAdaptor_Curve& aCurve,
764                            const BRepAdaptor_Surface& aSurface,
765                            const Standard_Real aCriteria)
766 {
767   Standard_Boolean bFlag=Standard_False;
768
769   GeomAbs_CurveType   aCType;
770   GeomAbs_SurfaceType aSType;
771
772   aCType=aCurve.GetType();
773   aSType=aSurface.GetType();
774     
775   if (aCType==GeomAbs_Circle && aSType==GeomAbs_Plane) {
776     gp_Circ aCirc=aCurve.Circle();
777     const gp_Pnt aCenter=aCirc.Location();
778     Standard_Real aR=aCirc.Radius();
779     gp_Pln aPln=aSurface.Plane();
780     Standard_Real aD=aPln.Distance(aCenter);
781     if (fabs (aD-aR) < aCriteria) {
782       return !bFlag;
783     }
784   }
785   return bFlag;
786 }
787 //
788 //=======================================================================
789 //function :  AdaptiveDiscret
790 //purpose  : 
791 //=======================================================================
792 Standard_Integer AdaptiveDiscret (const Standard_Integer iDiscret,
793                                   const BRepAdaptor_Curve& aCurve ,
794                                   const BRepAdaptor_Surface& aSurface)
795 {
796   Standard_Integer iDiscretNew;
797
798   iDiscretNew=iDiscret;
799
800   GeomAbs_SurfaceType aSType;
801
802   aSType=aSurface.GetType();
803     
804   if (aSType==GeomAbs_Cylinder) {
805    Standard_Real aELength, aRadius, dLR;
806
807    aELength=IntTools::Length(aCurve.Edge());
808    
809    gp_Cylinder aCylinder=aSurface.Cylinder();
810    aRadius=aCylinder.Radius();
811    dLR=2*aRadius;
812
813    iDiscretNew=(Standard_Integer)(aELength/dLR);
814    
815    if (iDiscretNew<iDiscret) {
816      iDiscretNew=iDiscret;
817    }
818      
819   }
820   return iDiscretNew;
821 }