0030760: Modeling Algorithms - Intersection fails in Occt 7.3.0
[occt.git] / src / BOPTools / BOPTools_AlgoTools2D.cxx
1 // Created by: Peter KURNEV
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15
16 #include <BOPTools_AlgoTools2D.hxx>
17 #include <BRep_Builder.hxx>
18 #include <BRep_CurveRepresentation.hxx>
19 #include <BRep_GCurve.hxx>
20 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
21 #include <BRep_TEdge.hxx>
22 #include <BRep_Tool.hxx>
23 #include <BRepAdaptor_Curve.hxx>
24 #include <BRepAdaptor_HSurface.hxx>
25 #include <BRepAdaptor_Surface.hxx>
26 #include <BRepClass_FaceClassifier.hxx>
27 #include <BRepTools.hxx>
28 #include <Geom2d_BSplineCurve.hxx>
29 #include <Geom2d_Circle.hxx>
30 #include <Geom2d_Curve.hxx>
31 #include <Geom2d_Ellipse.hxx>
32 #include <Geom2d_Hyperbola.hxx>
33 #include <Geom2d_Line.hxx>
34 #include <Geom2d_Parabola.hxx>
35 #include <Geom2d_TrimmedCurve.hxx>
36 #include <Geom2dAdaptor.hxx>
37 #include <Geom_Curve.hxx>
38 #include <Geom_Plane.hxx>
39 #include <Geom_RectangularTrimmedSurface.hxx>
40 #include <Geom_Surface.hxx>
41 #include <Geom_TrimmedCurve.hxx>
42 #include <GeomAdaptor_Curve.hxx>
43 #include <GeomAdaptor_HCurve.hxx>
44 #include <GeomAdaptor_HSurface.hxx>
45 #include <GeomAdaptor_Surface.hxx>
46 #include <GeomInt.hxx>
47 #include <GeomLib.hxx>
48 #include <GeomProjLib.hxx>
49 #include <gp.hxx>
50 #include <gp_Cylinder.hxx>
51 #include <gp_Pnt.hxx>
52 #include <gp_Pnt2d.hxx>
53 #include <gp_Vec.hxx>
54 #include <gp_Vec2d.hxx>
55 #include <IntTools_Context.hxx>
56 #include <IntTools_Tools.hxx>
57 #include <Precision.hxx>
58 #include <ProjLib_ProjectedCurve.hxx>
59 #include <ProjLib.hxx>
60 #include <Standard_ConstructionError.hxx>
61 #include <Standard_NotImplemented.hxx>
62 #include <TopExp.hxx>
63 #include <TopExp_Explorer.hxx>
64 #include <TopLoc_Location.hxx>
65 #include <TopoDS_Edge.hxx>
66 #include <TopoDS_Face.hxx>
67
68 static
69   Standard_Real MaxToleranceEdge (const TopoDS_Face& );
70
71 //=======================================================================
72 //function : BuildPCurveForEdgeOnFace
73 //purpose  : 
74 //=======================================================================
75 void BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace (const TopoDS_Edge& aE,
76                                                      const TopoDS_Face& aF,
77                                                      const Handle(IntTools_Context)& theContext)
78 {
79   BRep_Builder aBB;
80   Handle(Geom2d_Curve) aC2D;
81   Standard_Real  aTolPC, aTolFact, aTolEdge, aFirst, aLast;
82   
83   Standard_Boolean aHasOld;
84   aHasOld=BOPTools_AlgoTools2D::HasCurveOnSurface (aE, aF, aC2D, 
85                                                    aFirst, aLast, 
86                                                    aTolEdge);
87   if (aHasOld) {
88     return;
89   }
90   
91
92   BOPTools_AlgoTools2D::CurveOnSurface(aE, aF, aC2D, aTolPC, theContext);
93   
94   aTolEdge=BRep_Tool::Tolerance(aE);
95
96   aTolFact=Max(aTolEdge, aTolPC);
97
98   aBB.UpdateEdge(aE, aC2D, aF, aTolFact);
99   return;
100 }
101
102 //=======================================================================
103 //function : EdgeTangent
104 //purpose  : 
105 //=======================================================================
106 Standard_Boolean BOPTools_AlgoTools2D::EdgeTangent
107   (const TopoDS_Edge& anEdge, 
108    const Standard_Real aT,
109    gp_Vec& aTau)
110 {
111   Standard_Boolean isdgE;
112   Standard_Real first, last;
113   
114   isdgE = BRep_Tool::Degenerated(anEdge); 
115   if (isdgE) {
116     return Standard_False;
117   }
118
119   Handle(Geom_Curve) aC=BRep_Tool::Curve(anEdge, first, last);
120   gp_Pnt aP;
121   aC->D1(aT, aP, aTau);
122   Standard_Real mod = aTau.Magnitude();
123   if(mod > gp::Resolution()) {
124     aTau /= mod;
125   }
126   else {
127     return Standard_False;
128   }
129   //aTau.Normalize(); 
130   if (anEdge.Orientation() == TopAbs_REVERSED){
131     aTau.Reverse();
132   }
133   return Standard_True;
134 }
135
136 //=======================================================================
137 //function : PointOnOnSurface
138 //purpose  : 
139 //=======================================================================
140 void BOPTools_AlgoTools2D::PointOnSurface (const TopoDS_Edge& aE,
141                                            const TopoDS_Face& aF,
142                                            const Standard_Real aParameter,
143                                            Standard_Real& U,
144                                            Standard_Real& V,
145                                            const Handle(IntTools_Context)& theContext)
146 {
147   gp_Pnt2d aP2D;
148   Handle(Geom2d_Curve) aC2D;
149   Standard_Real aToler, aFirst, aLast;
150
151   BOPTools_AlgoTools2D::CurveOnSurface (aE, aF, aC2D, aFirst, aLast, aToler, theContext);
152   aC2D->D0(aParameter, aP2D);
153   U=aP2D.X();
154   V=aP2D.Y();
155   return;
156 }
157
158 //=======================================================================
159 //function : CurveOnSurface
160 //purpose  : 
161 //=======================================================================
162 void BOPTools_AlgoTools2D::CurveOnSurface (const TopoDS_Edge& aE,
163                                            const TopoDS_Face& aF,
164                                            Handle(Geom2d_Curve)& aC2D,
165                                            Standard_Real& aToler,
166                                            const Handle(IntTools_Context)& theContext)
167 {
168   Standard_Real aFirst, aLast; 
169   //
170   BOPTools_AlgoTools2D::CurveOnSurface(aE, aF, aC2D, aFirst, aLast, aToler, theContext); 
171   //
172   return;
173 }
174 //=======================================================================
175 //function : CurveOnSurface
176 //purpose  : 
177 //=======================================================================
178 void BOPTools_AlgoTools2D::CurveOnSurface (const TopoDS_Edge& aE,
179                                            const TopoDS_Face& aF,
180                                            Handle(Geom2d_Curve)& aC2D,
181                                            Standard_Real& aFirst,
182                                            Standard_Real& aLast,
183                                            Standard_Real& aToler,
184                                            const Handle(IntTools_Context)& theContext)
185 {
186   Standard_Boolean aHasOld;
187   Handle(Geom2d_Curve) C2D;
188
189   aHasOld=BOPTools_AlgoTools2D::HasCurveOnSurface (aE, aF, C2D, 
190                                                    aFirst, aLast, 
191                                                    aToler);
192   if (aHasOld) {
193     aC2D=C2D;
194     return;
195   }
196
197   BOPTools_AlgoTools2D::Make2D(aE, aF, C2D, aFirst, aLast, aToler, theContext);
198   aC2D=C2D;
199   return;
200 }
201 //=======================================================================
202 //function : HasCurveOnSurface
203 //purpose  : 
204 //=======================================================================
205 Standard_Boolean BOPTools_AlgoTools2D::HasCurveOnSurface 
206   (const TopoDS_Edge& aE,
207    const TopoDS_Face& aF,
208    Handle(Geom2d_Curve)& aC2D,
209    Standard_Real& aFirst,
210    Standard_Real& aLast,
211    Standard_Real& aToler)
212 {
213   Standard_Boolean aHasOld;
214   
215   aToler=BRep_Tool::Tolerance(aE);
216   BRep_Tool::Range(aE, aFirst, aLast);
217
218   if((aLast - aFirst) < Precision::PConfusion()) {
219     return Standard_False;
220   }
221
222   aC2D=BRep_Tool::CurveOnSurface(aE, aF, aFirst, aLast);
223   aHasOld=!aC2D.IsNull();
224   return aHasOld;
225 }
226 //=======================================================================
227 //function : HasCurveOnSurface
228 //purpose  : 
229 //=======================================================================
230 Standard_Boolean BOPTools_AlgoTools2D::HasCurveOnSurface 
231   (const TopoDS_Edge& aE,
232    const TopoDS_Face& aF)
233 {
234   Standard_Boolean bHasOld;
235   Handle(Geom2d_Curve) aC2D;
236   Standard_Real aFirst, aLast;
237   //
238   BRep_Tool::Range(aE, aFirst, aLast);
239   //
240   if((aLast - aFirst) < Precision::PConfusion()) {
241     return Standard_False;
242   }
243   //
244   aC2D=BRep_Tool::CurveOnSurface(aE, aF, aFirst, aLast);
245   bHasOld=!aC2D.IsNull();
246   //
247   return bHasOld;
248 }
249 //=======================================================================
250 //function : AdjustPCurveOnFace
251 //purpose  : 
252 //=======================================================================
253 void BOPTools_AlgoTools2D::AdjustPCurveOnFace
254   (const TopoDS_Face& theF,
255    const Handle(Geom_Curve)&   theC3D,
256    const Handle(Geom2d_Curve)& theC2D,
257    Handle(Geom2d_Curve)& theC2DA,
258    const Handle(IntTools_Context)& theContext)
259 {
260   Standard_Real aT1 = theC3D->FirstParameter();
261   Standard_Real aT2 = theC3D->LastParameter();
262   //
263   BOPTools_AlgoTools2D::AdjustPCurveOnFace (theF, aT1, aT2, theC2D, theC2DA, theContext);
264 }
265 //=======================================================================
266 //function : AdjustPCurveOnFace
267 //purpose  : 
268 //=======================================================================
269 void BOPTools_AlgoTools2D::AdjustPCurveOnFace 
270   (const TopoDS_Face& theF,
271    const Standard_Real theFirst,
272    const Standard_Real theLast,
273    const Handle(Geom2d_Curve)& theC2D, 
274    Handle(Geom2d_Curve)& theC2DA,
275    const Handle(IntTools_Context)& theContext)
276 {
277   BRepAdaptor_Surface aBASTmp;
278   const BRepAdaptor_Surface* pBAS;
279   if (!theContext.IsNull()) {
280     pBAS = &theContext->SurfaceAdaptor(theF);
281   }
282   else {
283     aBASTmp.Initialize(theF, Standard_True);
284     pBAS = &aBASTmp;
285   }
286   //
287   BOPTools_AlgoTools2D::AdjustPCurveOnSurf(*pBAS, theFirst, theLast, theC2D, theC2DA);
288 }
289 //=======================================================================
290 //function : AdjustPCurveOnFace
291 //purpose  : 
292 //=======================================================================
293 void BOPTools_AlgoTools2D::AdjustPCurveOnSurf
294   (const BRepAdaptor_Surface& aBAS,
295    const Standard_Real aFirst,
296    const Standard_Real aLast,
297    const Handle(Geom2d_Curve)& aC2D,
298    Handle(Geom2d_Curve)& aC2DA)
299 {
300   Standard_Boolean mincond, maxcond;
301   Standard_Real UMin, UMax, VMin, VMax, aT, u2, v2, du, dv, aDelta;
302   Standard_Real aUPeriod;
303   //
304   const TopoDS_Face& aF=aBAS.Face();
305   UMin=aBAS.FirstUParameter();
306   UMax=aBAS.LastUParameter();
307   VMin=aBAS.FirstVParameter();
308   VMax=aBAS.LastVParameter();
309   //
310   aDelta=Precision::PConfusion(); 
311   
312   aT =.5*(aFirst+aLast);
313
314   gp_Pnt2d pC2D; 
315   aC2D->D0(aT, pC2D);
316
317   u2 = pC2D.X();
318   v2 = pC2D.Y();
319   //
320   // du
321   du = 0.;
322   if (aBAS.IsUPeriodic()) {
323     aUPeriod = aBAS.UPeriod(); 
324     
325     //
326     // a. try to clarify u2 using the precision (aDelta)
327     if (fabs(u2-UMin) < aDelta) {
328       u2=UMin;
329     }
330     else if (fabs(u2-UMin-aUPeriod) < aDelta) {
331       u2=UMin+aUPeriod;
332     }
333     // b. compute du again using clarified value of u2
334     GeomInt::AdjustPeriodic(u2, UMin, UMax, aUPeriod, u2, du, 0.);
335     //
336     if (du==0.) {
337       if (aBAS.GetType()==GeomAbs_Cylinder) {
338         Standard_Real aR, dFi, aTol;
339         //
340         gp_Cylinder aCylinder=aBAS.Cylinder();
341         aR=aCylinder.Radius();
342         aTol=MaxToleranceEdge(aF);
343         dFi=aTol/aR;
344         if (dFi<aDelta) {
345           dFi=aDelta;
346         }
347         //
348         mincond = (UMin - u2 > dFi);
349         maxcond = (u2 - UMax > dFi);
350         if (mincond || maxcond) {
351           du = ( mincond ) ? aUPeriod : -aUPeriod;
352         }
353       }
354     } 
355   }
356   
357   // dv
358   dv = 0.;
359   if (aBAS.IsVPeriodic()) {
360     Standard_Real aVPeriod, aVm, aVr, aVmid, dVm, dVr;
361     //
362     aVPeriod = aBAS.VPeriod();
363     mincond = (VMin - v2 > aDelta);
364     maxcond = (v2 - VMax > aDelta);
365     //
366     if (mincond || maxcond) {
367       dv = ( mincond ) ? aVPeriod : -aVPeriod;
368     }
369     //
370     if ((VMax-VMin<aVPeriod) && dv) {
371       aVm=v2;
372       aVr=v2+dv;
373       aVmid=0.5*(VMin+VMax);
374       dVm=fabs(aVm-aVmid);
375       dVr=fabs(aVr-aVmid);
376       if (dVm<dVr) {
377         dv=0.;
378       }
379     }
380   }
381   //
382   {
383     //check the point with classifier
384     Standard_Real u,v;
385     u = u2 + du;
386     v = v2 + dv;
387     if (aBAS.IsUPeriodic()) {
388       aUPeriod = aBAS.UPeriod(); 
389       if ((UMax - UMin - 2*aDelta) > aUPeriod) {
390         if ((u > (UMin + aDelta + aUPeriod)) ||
391             (u < (UMax - aDelta - aUPeriod))) {
392           BRepClass_FaceClassifier aClassifier;
393           aClassifier.Perform(aF, gp_Pnt2d(u, v), aDelta);
394           TopAbs_State Status = aClassifier.State();
395           if (Status == TopAbs_OUT) {
396             du += (u > (UMin + aDelta + aUPeriod)) ? -aUPeriod : aUPeriod;
397           }
398         }
399       }
400     }
401     //
402     u = u2 + du;
403     if (aBAS.IsVPeriodic()) {
404       Standard_Real aVPeriod = aBAS.VPeriod(); 
405       if ((VMax - VMin - 2*aDelta) > aVPeriod) {
406         if ((v > (VMin + aDelta + aVPeriod)) ||
407             (v < (VMax - aDelta - aVPeriod))) {
408           BRepClass_FaceClassifier aClassifier;
409           aClassifier.Perform(aF, gp_Pnt2d(u, v), aDelta);
410           TopAbs_State Status = aClassifier.State();
411           if (Status == TopAbs_OUT) {
412             dv += (v > (VMin + aDelta + aVPeriod)) ? -aVPeriod : aVPeriod;
413           }
414         }
415       }
416     }
417   }
418   // Translation if necessary
419   Handle(Geom2d_Curve) aC2Dx=aC2D;
420
421   if ( du != 0. || dv != 0.) {
422     Handle(Geom2d_Curve) PCT = Handle(Geom2d_Curve)::DownCast(aC2Dx->Copy());
423     gp_Vec2d aV2D(du,dv);
424     PCT->Translate(aV2D);
425     aC2Dx = PCT;
426   }
427
428   aC2DA=aC2Dx;
429 }
430
431 //=======================================================================
432 //function : IntermediatePoint
433 //purpose  : 
434 //=======================================================================
435 Standard_Real BOPTools_AlgoTools2D::IntermediatePoint 
436   (const Standard_Real aFirst,
437    const Standard_Real aLast)
438 {
439   //define parameter division number as 10*e^(-PI) = 0.43213918
440   const Standard_Real PAR_T = 0.43213918;
441   Standard_Real aParm;
442   aParm=(1.-PAR_T)*aFirst + PAR_T*aLast;
443   return aParm;
444 }
445 //=======================================================================
446 //function : IntermediatePoint
447 //purpose  : 
448 //=======================================================================
449 Standard_Real BOPTools_AlgoTools2D::IntermediatePoint 
450   (const TopoDS_Edge& aE)
451                                                 
452 {
453   Standard_Real aT, aT1, aT2;
454
455   Handle(Geom_Curve)aC1=BRep_Tool::Curve(aE, aT1, aT2);
456   if (aC1.IsNull())
457     BRep_Tool::Range(aE, aT1, aT2);
458
459   aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2);
460   return aT;
461 }
462 //=======================================================================
463 //function : Make2D
464 //purpose  : 
465 //=======================================================================
466 void BOPTools_AlgoTools2D::Make2D (const TopoDS_Edge& aE,
467                                    const TopoDS_Face& aF,
468                                    Handle(Geom2d_Curve)& aC2D,
469                                    Standard_Real& aFirst,
470                                    Standard_Real& aLast,
471                                    Standard_Real& aToler,
472                                    const Handle(IntTools_Context)& theContext)
473 {
474   Standard_Boolean aLocIdentity;
475   Standard_Real f3d, l3d;
476   TopLoc_Location aLoc;
477
478   Handle(Geom2d_Curve) C2D; 
479   
480   
481   C2D=BRep_Tool::CurveOnSurface(aE, aF, aFirst, aLast);
482   
483   if (!C2D.IsNull()) {
484     aC2D=C2D;
485     return;
486   }
487
488   Handle(Geom_Curve) C3D2, C3D;
489   C3D = BRep_Tool::Curve(aE, aLoc, f3d, l3d);
490   //
491   if (C3D.IsNull()) { 
492     // aE has no 3D curve, so nothing is done
493   }
494   //
495   aLocIdentity=aLoc.IsIdentity();
496     
497   if (aLocIdentity) {
498     C3D2 = C3D;
499   }
500   else {
501     C3D2 = Handle(Geom_Curve)::
502       DownCast(C3D->Transformed(aLoc.Transformation()));
503   }
504   
505   //
506   aToler = BRep_Tool::Tolerance(aE);
507   BOPTools_AlgoTools2D::MakePCurveOnFace(aF, C3D2, f3d, l3d, aC2D, aToler, theContext);
508   //
509   aFirst = f3d; 
510   aLast  = l3d;
511 }
512
513 //=======================================================================
514 //function : MakePCurveOnFace
515 //purpose  : 
516 //=======================================================================
517 void BOPTools_AlgoTools2D::MakePCurveOnFace (const TopoDS_Face& aF,
518                                              const Handle(Geom_Curve)& aC3D,
519                                              Handle(Geom2d_Curve)& aC2D, //->
520                                              Standard_Real& TolReached2d,
521                                              const Handle(IntTools_Context)& theContext)
522 {
523   Standard_Real aFirst, aLast;
524
525   aFirst = aC3D -> FirstParameter();
526   aLast  = aC3D -> LastParameter();
527   //
528   TolReached2d=0.;
529   //
530   BOPTools_AlgoTools2D::MakePCurveOnFace
531     (aF, aC3D, aFirst, aLast, aC2D, TolReached2d, theContext);
532 }
533
534 //=======================================================================
535 //function : MakePCurveOnFace
536 //purpose  : 
537 //=======================================================================
538 void BOPTools_AlgoTools2D::MakePCurveOnFace
539   (const TopoDS_Face& aF,
540    const Handle(Geom_Curve)& aC3D,
541    const Standard_Real aT1,
542    const Standard_Real aT2,
543    Handle(Geom2d_Curve)& aC2D,
544    Standard_Real& TolReached2d,
545    const Handle(IntTools_Context)& theContext)
546 {
547   BRepAdaptor_Surface aBASTmp;
548   const BRepAdaptor_Surface* pBAS;
549   if (!theContext.IsNull()) {
550     pBAS = &theContext->SurfaceAdaptor(aF);
551   }
552   else {
553     aBASTmp.Initialize(aF, Standard_True);
554     pBAS = &aBASTmp;
555   }
556   //
557   Handle(BRepAdaptor_HSurface) aBAHS = new BRepAdaptor_HSurface(*pBAS);
558   Handle(GeomAdaptor_HCurve) aBAHC = new GeomAdaptor_HCurve(aC3D, aT1, aT2);
559   //
560   Standard_Real aTolR;
561   Standard_Real aTR = Precision::Confusion();//1.e-7;
562   Standard_Real aMaxTol = 1.e3 * aTR; //0.0001
563   Standard_Boolean isAnaSurf =  ProjLib::IsAnaSurf(aBAHS);
564
565   //when the type of surface is GeomAbs_SurfaceOfRevolution
566   if (pBAS->GetType() == GeomAbs_SurfaceOfRevolution) 
567   {
568     if (TolReached2d > aTR) {
569       aTR=TolReached2d;
570     }
571     //
572     ProjLib_ProjectedCurve aProj1(aBAHS, aBAHC, aTR);
573     ProjLib::MakePCurveOfType(aProj1, aC2D);
574     aTolR = aProj1.GetTolerance();
575   } 
576   else 
577   {
578     ProjLib_ProjectedCurve aProjCurv(aBAHS);
579     Standard_Integer aDegMin = -1, aDegMax = -1, aMaxSegments = -1;
580     Standard_Real aMaxDist = -1;
581     AppParCurves_Constraint aBndPnt = AppParCurves_TangencyPoint;
582     if ((TolReached2d  >= 10. * aTR) && (TolReached2d <= aMaxTol || isAnaSurf))
583     {
584       aTR = Min(aMaxTol, 0.1*TolReached2d);
585       aMaxSegments = 100;
586       aMaxDist = 1.e3*TolReached2d;
587       if(!isAnaSurf || TolReached2d > 1.)
588       {
589         aBndPnt = AppParCurves_PassPoint;
590       }
591     }
592     else if(TolReached2d > aMaxTol)
593     {
594       aTR = Min(TolReached2d, 1.e3 * aMaxTol);
595       aMaxDist = 1.e2 * aTR;
596       aMaxSegments = 100;
597     }
598     aProjCurv.Load(aTR);
599     aProjCurv.SetDegree(aDegMin, aDegMax);
600     aProjCurv.SetMaxSegments(aMaxSegments);
601     aProjCurv.SetBndPnt(aBndPnt);
602     aProjCurv.SetMaxDist(aMaxDist);
603     aProjCurv.Perform(aBAHC);
604     ProjLib::MakePCurveOfType(aProjCurv, aC2D);
605     aTolR=aProjCurv.GetTolerance();
606   }
607   //
608   if (aC2D.IsNull() && (aTR < aMaxTol || aTR < TolReached2d))
609   { 
610     aTR = Max(TolReached2d, aMaxTol);
611     ProjLib_ProjectedCurve aProjCurvAgain(aBAHS, aBAHC, aTR);// 2
612     ProjLib::MakePCurveOfType(aProjCurvAgain, aC2D);
613     aTolR = aProjCurvAgain.GetTolerance();
614   }
615   //
616   if(aC2D.IsNull())
617   {
618     throw Standard_ConstructionError("BOPTools_AlgoTools2D::MakePCurveOnFace : PCurve is Null");
619   }
620   //
621   TolReached2d=aTolR;
622
623   // Adjust curve for periodic surface
624   Handle(Geom2d_Curve) aC2DA;
625   BOPTools_AlgoTools2D::AdjustPCurveOnSurf (*pBAS, aT1, aT2, aC2D, aC2DA);
626   aC2D = aC2DA;
627
628   // Make sure that the range of the 2D curve is sufficient for representation of the 3D curve.
629   Standard_Real aTCFirst = aC2D->FirstParameter();
630   Standard_Real aTCLast  = aC2D->LastParameter();
631   if ((aTCFirst - aT1) > Precision::PConfusion() ||
632       (aT2 - aTCLast ) > Precision::PConfusion())
633   {
634     if (aTCFirst < aT1) aTCFirst = aT1;
635     if (aTCLast  > aT2) aTCLast  = aT2;
636
637     GeomLib::SameRange(Precision::PConfusion(), aC2D,
638                        aTCFirst, aTCLast, aT1, aT2, aC2D);
639   }
640
641   // compute the appropriate tolerance for the edge
642   Handle(Geom_Surface) aS = pBAS->Surface().Surface();
643   aS = Handle(Geom_Surface)::DownCast(aS->Transformed(pBAS->Trsf()));
644   //
645   Standard_Real aT;
646   if (IntTools_Tools::ComputeTolerance
647       (aC3D, aC2D, aS, aT1, aT2, aTolR, aT)) {
648     if (aTolR > TolReached2d) {
649       TolReached2d = aTolR;
650     }
651   }
652 }
653
654 //=======================================================================
655 //function : MaxToleranceEdge
656 //purpose  : 
657 //=======================================================================
658 Standard_Real MaxToleranceEdge (const TopoDS_Face& aF) 
659 {
660   Standard_Real aTol, aTolMax;
661   TopExp_Explorer aExp;
662   //
663   aTolMax=0.;
664   aExp.Init(aF, TopAbs_EDGE);
665   for (; aExp.More(); aExp.Next()) {
666     const TopoDS_Edge& aE=*((TopoDS_Edge *)&aExp.Current());
667     aTol=BRep_Tool::Tolerance(aE);
668     if (aTol>aTolMax) {
669       aTolMax=aTol;
670     }
671   }
672   return aTolMax;
673 }
674
675 //=======================================================================
676 //function : IsEdgeIsoline
677 //purpose  : 
678 //=======================================================================
679 void BOPTools_AlgoTools2D::IsEdgeIsoline( const TopoDS_Edge& theE,
680                                           const TopoDS_Face& theF,
681                                           Standard_Boolean& isTheUIso,
682                                           Standard_Boolean& isTheVIso)
683 {
684   isTheUIso = isTheVIso = Standard_False;
685
686   gp_Vec2d aT;
687   gp_Pnt2d aP;
688   Standard_Real aFirst = 0.0, aLast = 0.0;
689   const Handle(Geom2d_Curve) aPC = BRep_Tool::CurveOnSurface(theE, theF, aFirst, aLast);
690
691   aPC->D1(0.5*(aFirst+aLast), aP, aT);
692
693   const Standard_Real aSqMagn = aT.SquareMagnitude();
694   if(aSqMagn <= gp::Resolution())
695     return;
696
697   //Normalyze aT
698   aT /= sqrt(aSqMagn);
699
700   //sin(da) ~ da, when da->0.
701   const Standard_Real aTol = Precision::Angular();
702   const gp_Vec2d aRefVDir(0.0, 1.0), aRefUDir(1.0, 0.0);
703
704   const Standard_Real aDPv = aT.CrossMagnitude(aRefVDir),
705                       aDPu = aT.CrossMagnitude(aRefUDir);
706
707   isTheUIso = (aDPv <= aTol);
708   isTheVIso = (aDPu <= aTol);
709 }