46fe699b277acbaf4b19e2007ca5c9169f087e51
[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   Standard_Real aTF, aTL, Tol, U1f, U1l, V1f, V1l, af, al,aDist2, aMinDist2;
356   Standard_Boolean theflag=Standard_False;
357   Standard_Integer aNbExt, iLower;
358
359   aCP.Range1(aTF, aTL);
360
361   //
362   Standard_Real aCR;
363   aCR=myC.Resolution(myCriteria);
364   if((Abs(aTF - myRange.First()) < aCR) &&
365      (Abs(aTL - myRange.Last())  < aCR)) {
366     return theflag; // EDGE 
367   }
368   //
369
370   Tol = Precision::PConfusion();
371
372   const Handle(Geom_Curve)&  Curve   =BRep_Tool::Curve  (myC.Edge(), af, al);
373   const Handle(Geom_Surface)& Surface=BRep_Tool::Surface(myS.Face());
374   //   Surface->Bounds(U1f,U1l,V1f,V1l);
375   U1f = myS.FirstUParameter();
376   U1l = myS.LastUParameter();
377   V1f = myS.FirstVParameter();
378   V1l = myS.LastVParameter();
379   
380   GeomAdaptor_Curve   TheCurve   (Curve,aTF, aTL);
381   GeomAdaptor_Surface TheSurface (Surface, U1f, U1l, V1f, V1l); 
382      
383   Extrema_ExtCS anExtrema (TheCurve, TheSurface, Tol, Tol);
384
385   aDist2 = 1.e100;
386
387   if(anExtrema.IsDone()) {
388     aMinDist2 = aDist2;
389
390     if(!anExtrema.IsParallel()) {
391       aNbExt=anExtrema.NbExt();
392       
393       if(aNbExt > 0) {
394  iLower=1;
395  for (Standard_Integer i=1; i<=aNbExt; i++) {
396    aDist2=anExtrema.SquareDistance(i);
397    if (aDist2 < aMinDist2) {
398      aMinDist2=aDist2;
399      iLower=i;
400    }
401  }
402  aDist2=anExtrema.SquareDistance(iLower);
403  Extrema_POnCurv aPOnC;
404  Extrema_POnSurf aPOnS;
405  anExtrema.Points(iLower, aPOnC, aPOnS);
406  aTx=aPOnC.Parameter();
407       }
408       else {
409  // modified by NIZHNY-MKK  Thu Jul 21 11:35:32 2005.BEGIN
410  IntCurveSurface_HInter anExactIntersector;
411   
412  Handle(GeomAdaptor_HCurve) aCurve     = new GeomAdaptor_HCurve(TheCurve);
413  Handle(GeomAdaptor_HSurface) aSurface = new GeomAdaptor_HSurface(TheSurface);
414  
415  anExactIntersector.Perform(aCurve, aSurface);
416
417  if(anExactIntersector.IsDone()) {
418    for(Standard_Integer i = 1; i <= anExactIntersector.NbPoints(); i++) {
419      const IntCurveSurface_IntersectionPoint& aPoint = anExactIntersector.Point(i);
420       
421      if((aPoint.W() >= aTF) && (aPoint.W() <= aTL)) {
422        aDist2=0.;
423        aTx = aPoint.W();
424      }
425    }
426  }
427  // modified by NIZHNY-MKK  Thu Jul 21 11:35:40 2005.END
428       }
429     }
430     else {
431       return theflag;
432     }
433   }
434
435   Standard_Real aBoundaryDist;
436
437   aBoundaryDist = DistanceFunction(aTF) + myCriteria;
438   if(aBoundaryDist * aBoundaryDist < aDist2) {
439     aDist2 = aBoundaryDist * aBoundaryDist;
440     aTx = aTF;
441   }
442   
443   aBoundaryDist = DistanceFunction(aTL) + myCriteria;
444   if(aBoundaryDist * aBoundaryDist < aDist2) {
445     aDist2 = aBoundaryDist * aBoundaryDist;
446     aTx = aTL;
447   }
448
449   Standard_Real aParameter = (aTF + aTL) * 0.5;
450   aBoundaryDist = DistanceFunction(aParameter) + myCriteria;
451   if(aBoundaryDist * aBoundaryDist < aDist2) {
452     aDist2 = aBoundaryDist * aBoundaryDist;
453     aTx = aParameter;
454   }
455
456   if(aDist2 > myCriteria * myCriteria) {
457     return theflag;
458   }
459   
460   if (fabs (aTx-aTF) < Precision::PConfusion()) {
461     return !theflag;
462   }
463
464   if (fabs (aTx-aTL) < Precision::PConfusion()) {
465     return !theflag;
466   }
467
468   if (aTx>aTF && aTx<aTL) {
469     return !theflag;
470   }
471
472   return theflag;
473 }
474
475 //=======================================================================
476 //function : Perform
477 //purpose  : 
478 //=======================================================================
479 void IntTools_EdgeFace::Perform() 
480 {
481   Standard_Integer i, aNb;
482   IntTools_CommonPrt aCommonPrt;
483   //
484   aCommonPrt.SetEdge1(myEdge);
485   //
486   myErrorStatus=0;
487   CheckData();
488   if (myErrorStatus) {
489     return;
490   }
491   //
492   if (myContext.IsNull()) {
493     myContext=new IntTools_Context;
494   }
495   //
496   myIsDone = Standard_False;
497   myC.Initialize(myEdge);
498   GeomAbs_CurveType aCurveType;
499   aCurveType=myC.GetType();
500   //
501   // Prepare myCriteria
502   Standard_Real aFuzz = myFuzzyValue / 2.;
503   Standard_Real aTolF = BRep_Tool::Tolerance(myFace) + aFuzz;
504   Standard_Real aTolE = BRep_Tool::Tolerance(myEdge) + aFuzz;
505   if (aCurveType == GeomAbs_BSplineCurve ||
506       aCurveType==GeomAbs_BezierCurve) {
507     //--- 5112
508     Standard_Real diff1 = (aTolE/aTolF);
509     Standard_Real diff2 = (aTolF/aTolE);
510     if( diff1 > 100 || diff2 > 100 ) {
511       myCriteria = Max(aTolE,aTolF);
512     }
513     else //--- 5112
514       myCriteria = 1.5*aTolE + aTolF;
515   }
516   else {
517     myCriteria = aTolE + aTolF;
518   }
519   
520   myS = myContext->SurfaceAdaptor(myFace);
521   
522   if (myQuickCoincidenceCheck) {
523     if (IsCoincident()) {
524       aCommonPrt.SetType(TopAbs_EDGE);
525       aCommonPrt.SetRange1(myRange.First(), myRange.Last());
526       mySeqOfCommonPrts.Append(aCommonPrt);
527       myIsDone=Standard_True;
528       return;
529     }
530   }
531   //
532   IntTools_BeanFaceIntersector anIntersector(myC, myS, aTolE, aTolF);
533   anIntersector.SetBeanParameters(myRange.First(), myRange.Last());
534   //
535   anIntersector.SetContext(myContext);
536   //
537   anIntersector.Perform();
538   
539   if(!anIntersector.IsDone()) {
540     return;
541   }
542   
543   for(Standard_Integer r = 1; r <= anIntersector.Result().Length(); r++) {
544     const IntTools_Range& aRange = anIntersector.Result().Value(r);
545     
546     if(IsProjectable(IntTools_Tools::IntermediatePoint(aRange.First(), aRange.Last()))) {
547       aCommonPrt.SetRange1(aRange.First(), aRange.Last());
548       mySeqOfCommonPrts.Append(aCommonPrt);
549     }
550   }
551
552   aNb = mySeqOfCommonPrts.Length();
553
554   for (i=1; i<=aNb; i++) {
555     IntTools_CommonPrt& aCP=mySeqOfCommonPrts.ChangeValue(i);
556     //
557     Standard_Real aTx1, aTx2;
558     gp_Pnt aPx1, aPx2;
559     //
560     aCP.Range1(aTx1, aTx2);
561     myC.D0(aTx1, aPx1);
562     myC.D0(aTx2, aPx2);
563     aCP.SetBoundingPoints(aPx1, aPx2);
564     //
565     MakeType (aCP); 
566   }
567   {
568     // Line\Cylinder's Common Parts treatement
569     GeomAbs_CurveType   aCType;
570     GeomAbs_SurfaceType aSType;
571     TopAbs_ShapeEnum aType;
572     Standard_Boolean bIsTouch;
573     Standard_Real aTx;
574     
575     aCType=myC.GetType();
576     aSType=myS.GetType();
577     
578     if (aCType==GeomAbs_Line && aSType==GeomAbs_Cylinder) {
579       for (i=1; i<=aNb; i++) {
580         IntTools_CommonPrt& aCP=mySeqOfCommonPrts(i);
581         aType=aCP.Type();
582         if (aType==TopAbs_EDGE) {
583           bIsTouch=CheckTouch (aCP, aTx);
584           if (bIsTouch) {
585             aCP.SetType(TopAbs_VERTEX);
586             aCP.SetVertexParameter1(aTx);
587             //aCP.SetRange1 (aTx, aTx);
588           }
589         }
590         else if (aType==TopAbs_VERTEX) {
591           bIsTouch=CheckTouchVertex (aCP, aTx);
592           if (bIsTouch) {
593             aCP.SetVertexParameter1(aTx);
594             //aCP.SetRange1 (aTx, aTx);
595           }
596         }
597       }
598     }
599     
600     // Circle\Plane's Common Parts treatement
601     
602     if (aCType==GeomAbs_Circle && aSType==GeomAbs_Plane) {
603       Standard_Boolean bIsCoplanar, bIsRadius;
604       bIsCoplanar=IsCoplanar(myC, myS);
605       bIsRadius=IsRadius(myC, myS, myCriteria);
606       if (!bIsCoplanar && !bIsRadius) {
607         for (i=1; i<=aNb; i++) {
608           IntTools_CommonPrt& aCP=mySeqOfCommonPrts(i);
609           aType=aCP.Type();
610           if (aType==TopAbs_EDGE) {
611             bIsTouch=CheckTouch (aCP, aTx);
612             if (bIsTouch) {
613               aCP.SetType(TopAbs_VERTEX);
614               aCP.SetVertexParameter1(aTx);
615               //aCP.SetRange1 (aTx, aTx);
616             }
617           }
618           else if (aType==TopAbs_VERTEX) {
619             bIsTouch=CheckTouchVertex (aCP, aTx);
620             if (bIsTouch) {
621               aCP.SetVertexParameter1(aTx);
622               //aCP.SetRange1 (aTx, aTx);
623             }
624           }
625         }
626       }
627     }
628   }
629   myIsDone=Standard_True;
630 }
631
632 //=======================================================================
633 //function : CheckTouch 
634 //purpose  : 
635 //=======================================================================
636 Standard_Boolean IntTools_EdgeFace::CheckTouchVertex 
637   (const IntTools_CommonPrt& aCP,
638    Standard_Real& aTx) 
639 {
640   Standard_Real aTF, aTL, Tol, U1f,U1l,V1f,V1l;
641   Standard_Real aEpsT, af, al,aDist2, aMinDist2, aTm, aDist2New;
642   Standard_Boolean theflag=Standard_False;
643   Standard_Integer aNbExt, i, iLower ;
644   GeomAbs_CurveType aType;
645   //
646   aCP.Range1(aTF, aTL);
647   aType=myC.GetType();
648   //
649   aEpsT=8.e-5;
650   if (aType==GeomAbs_Line) {
651     aEpsT=9.e-5;
652   }
653   //
654   aTm=0.5*(aTF+aTL);
655   aDist2=DistanceFunction(aTm);
656   aDist2 *= aDist2;
657
658   Tol = Precision::PConfusion();
659
660   const Handle(Geom_Curve)&  Curve =BRep_Tool::Curve  (myC.Edge(), af, al);
661   const Handle(Geom_Surface)& Surface=BRep_Tool::Surface(myS.Face());
662
663   Surface->Bounds(U1f,U1l,V1f,V1l);
664   
665   GeomAdaptor_Curve   TheCurve   (Curve,aTF, aTL);
666   GeomAdaptor_Surface TheSurface (Surface, U1f, U1l, V1f, V1l); 
667      
668   Extrema_ExtCS anExtrema (TheCurve, TheSurface, Tol, Tol);
669    
670   if(!anExtrema.IsDone()) {
671     return theflag;
672   }
673   if (anExtrema.IsParallel()) {
674     return theflag;
675   }
676   
677   aNbExt=anExtrema.NbExt() ;
678   if (!aNbExt) {
679      return theflag;
680   }
681
682   iLower=1;
683   aMinDist2=1.e100;
684   for (i=1; i<=aNbExt; ++i) {
685     aDist2=anExtrema.SquareDistance(i);
686     if (aDist2 < aMinDist2) {
687       aMinDist2=aDist2;
688       iLower=i;
689     }
690   }
691
692   aDist2New=anExtrema.SquareDistance(iLower);
693   
694   if (aDist2New > aDist2) {
695     aTx=aTm;
696     return !theflag;
697   }
698   
699   if (aDist2New > myCriteria * myCriteria) {
700     return theflag;
701   }
702
703   Extrema_POnCurv aPOnC;
704   Extrema_POnSurf aPOnS;
705   anExtrema.Points(iLower, aPOnC, aPOnS);
706
707  
708   aTx=aPOnC.Parameter();
709   ///
710   if (fabs (aTx-aTF) < aEpsT) {
711     return theflag;
712   }
713
714   if (fabs (aTx-aTL) < aEpsT) {
715     return theflag;
716   }
717
718   if (aTx>aTF && aTx<aTL) {
719     return !theflag;
720   }
721
722   return theflag;
723 }
724
725
726 //=======================================================================
727 //function :  IsCoplanar
728 //purpose  : 
729 //=======================================================================
730 Standard_Boolean IsCoplanar (const BRepAdaptor_Curve& aCurve ,
731                              const BRepAdaptor_Surface& aSurface)
732 {
733   Standard_Boolean bFlag=Standard_False;
734
735   GeomAbs_CurveType   aCType;
736   GeomAbs_SurfaceType aSType;
737
738   aCType=aCurve.GetType();
739   aSType=aSurface.GetType();
740     
741   if (aCType==GeomAbs_Circle && aSType==GeomAbs_Plane) {
742     gp_Circ aCirc=aCurve.Circle();
743     const gp_Ax1& anAx1=aCirc.Axis();
744     const gp_Dir& aDirAx1=anAx1.Direction();
745     
746     gp_Pln aPln=aSurface.Plane();
747     const gp_Ax1& anAx=aPln.Axis();
748     const gp_Dir& aDirPln=anAx.Direction();
749
750     bFlag=IntTools_Tools::IsDirsCoinside(aDirAx1, aDirPln);
751   }
752   return bFlag;
753 }
754 //=======================================================================
755 //function :  IsRadius
756 //purpose  : 
757 //=======================================================================
758 Standard_Boolean IsRadius (const BRepAdaptor_Curve& aCurve,
759                            const BRepAdaptor_Surface& aSurface,
760                            const Standard_Real aCriteria)
761 {
762   Standard_Boolean bFlag=Standard_False;
763
764   GeomAbs_CurveType   aCType;
765   GeomAbs_SurfaceType aSType;
766
767   aCType=aCurve.GetType();
768   aSType=aSurface.GetType();
769     
770   if (aCType==GeomAbs_Circle && aSType==GeomAbs_Plane) {
771     gp_Circ aCirc=aCurve.Circle();
772     const gp_Pnt aCenter=aCirc.Location();
773     Standard_Real aR=aCirc.Radius();
774     gp_Pln aPln=aSurface.Plane();
775     Standard_Real aD=aPln.Distance(aCenter);
776     if (fabs (aD-aR) < aCriteria) {
777       return !bFlag;
778     }
779   }
780   return bFlag;
781 }
782 //
783 //=======================================================================
784 //function :  AdaptiveDiscret
785 //purpose  : 
786 //=======================================================================
787 Standard_Integer AdaptiveDiscret (const Standard_Integer iDiscret,
788                                   const BRepAdaptor_Curve& aCurve ,
789                                   const BRepAdaptor_Surface& aSurface)
790 {
791   Standard_Integer iDiscretNew;
792
793   iDiscretNew=iDiscret;
794
795   GeomAbs_SurfaceType aSType;
796
797   aSType=aSurface.GetType();
798     
799   if (aSType==GeomAbs_Cylinder) {
800    Standard_Real aELength, aRadius, dLR;
801
802    aELength=IntTools::Length(aCurve.Edge());
803    
804    gp_Cylinder aCylinder=aSurface.Cylinder();
805    aRadius=aCylinder.Radius();
806    dLR=2*aRadius;
807
808    iDiscretNew=(Standard_Integer)(aELength/dLR);
809    
810    if (iDiscretNew<iDiscret) {
811      iDiscretNew=iDiscret;
812    }
813      
814   }
815   return iDiscretNew;
816 }