0028165: Improve performance of Boolean Operations
[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 <BOPCol_IndexedMapOfShape.hxx>
17 #include <BOPTools.hxx>
18 #include <BOPTools_AlgoTools2D.hxx>
19 #include <BRep_Builder.hxx>
20 #include <BRep_CurveRepresentation.hxx>
21 #include <BRep_GCurve.hxx>
22 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
23 #include <BRep_TEdge.hxx>
24 #include <BRep_Tool.hxx>
25 #include <BRepAdaptor_Curve.hxx>
26 #include <BRepAdaptor_HSurface.hxx>
27 #include <BRepAdaptor_Surface.hxx>
28 #include <BRepClass_FaceClassifier.hxx>
29 #include <BRepTools.hxx>
30 #include <Geom2d_BSplineCurve.hxx>
31 #include <Geom2d_Circle.hxx>
32 #include <Geom2d_Curve.hxx>
33 #include <Geom2d_Ellipse.hxx>
34 #include <Geom2d_Hyperbola.hxx>
35 #include <Geom2d_Line.hxx>
36 #include <Geom2d_Parabola.hxx>
37 #include <Geom2d_TrimmedCurve.hxx>
38 #include <Geom2dAdaptor.hxx>
39 #include <Geom_Curve.hxx>
40 #include <Geom_Plane.hxx>
41 #include <Geom_RectangularTrimmedSurface.hxx>
42 #include <Geom_Surface.hxx>
43 #include <Geom_TrimmedCurve.hxx>
44 #include <GeomAdaptor_Curve.hxx>
45 #include <GeomAdaptor_HCurve.hxx>
46 #include <GeomAdaptor_HSurface.hxx>
47 #include <GeomAdaptor_Surface.hxx>
48 #include <GeomInt.hxx>
49 #include <GeomProjLib.hxx>
50 #include <gp.hxx>
51 #include <gp_Cylinder.hxx>
52 #include <gp_Pnt.hxx>
53 #include <gp_Pnt2d.hxx>
54 #include <gp_Vec.hxx>
55 #include <gp_Vec2d.hxx>
56 #include <IntTools_Context.hxx>
57 #include <IntTools_Tools.hxx>
58 #include <Precision.hxx>
59 #include <ProjLib_ProjectedCurve.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_Boolean CheckEdgeLength (const TopoDS_Edge& );
70
71 static
72   Handle(Geom2d_Curve) BRep_Tool_CurveOnSurface(const TopoDS_Edge& , 
73                                                 const TopoDS_Face& ,
74                                                 Standard_Real& ,
75                                                 Standard_Real& ,
76                                                 Standard_Boolean& );
77 static
78   Handle(Geom2d_Curve) BRep_Tool_CurveOnSurface(const TopoDS_Edge& , 
79                                                 const Handle(Geom_Surface)& ,
80                                                 const TopLoc_Location& ,
81                                                 Standard_Real& ,
82                                                 Standard_Real& ,
83                                                 Standard_Boolean& );
84 static
85   Standard_Real MaxToleranceEdge (const TopoDS_Face& );
86
87 //=======================================================================
88 //function : BuildPCurveForEdgeOnFace
89 //purpose  : 
90 //=======================================================================
91 void BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace (const TopoDS_Edge& aE,
92                                                      const TopoDS_Face& aF,
93                                                      const Handle(IntTools_Context)& theContext)
94 {
95   BRep_Builder aBB;
96   Handle(Geom2d_Curve) aC2D;
97   Standard_Real  aTolPC, aTolFact, aTolEdge, aFirst, aLast;
98   
99   Standard_Boolean aHasOld;
100   aHasOld=BOPTools_AlgoTools2D::HasCurveOnSurface (aE, aF, aC2D, 
101                                                    aFirst, aLast, 
102                                                    aTolEdge);
103   if (aHasOld) {
104     return;
105   }
106   
107
108   BOPTools_AlgoTools2D::CurveOnSurface(aE, aF, aC2D, aTolPC, theContext);
109   
110   aTolEdge=BRep_Tool::Tolerance(aE);
111
112   aTolFact=Max(aTolEdge, aTolPC);
113
114   aBB.UpdateEdge(aE, aC2D, aF, aTolFact);
115   return;
116 }
117
118 //=======================================================================
119 //function : EdgeTangent
120 //purpose  : 
121 //=======================================================================
122 Standard_Boolean BOPTools_AlgoTools2D::EdgeTangent
123   (const TopoDS_Edge& anEdge, 
124    const Standard_Real aT,
125    gp_Vec& aTau)
126 {
127   Standard_Boolean isdgE;
128   Standard_Real first, last;
129   
130   isdgE = BRep_Tool::Degenerated(anEdge); 
131   if (isdgE) {
132     return Standard_False;
133   }
134   if (!CheckEdgeLength(anEdge)) {
135     return Standard_False;
136   }
137
138   Handle(Geom_Curve) aC=BRep_Tool::Curve(anEdge, first, last);
139   gp_Pnt aP;
140   aC->D1(aT, aP, aTau);
141   Standard_Real mod = aTau.Magnitude();
142   if(mod > gp::Resolution()) {
143     aTau /= mod;
144   }
145   else {
146     return Standard_False;
147   }
148   //aTau.Normalize(); 
149   if (anEdge.Orientation() == TopAbs_REVERSED){
150     aTau.Reverse();
151   }
152   return Standard_True;
153 }
154
155 //=======================================================================
156 //function : PointOnOnSurface
157 //purpose  : 
158 //=======================================================================
159 void BOPTools_AlgoTools2D::PointOnSurface (const TopoDS_Edge& aE,
160                                            const TopoDS_Face& aF,
161                                            const Standard_Real aParameter,
162                                            Standard_Real& U,
163                                            Standard_Real& V,
164                                            const Handle(IntTools_Context)& theContext)
165 {
166   gp_Pnt2d aP2D;
167   Handle(Geom2d_Curve) aC2D;
168   Standard_Real aToler, aFirst, aLast;
169
170   BOPTools_AlgoTools2D::CurveOnSurface (aE, aF, aC2D, aFirst, aLast, aToler, theContext);
171   aC2D->D0(aParameter, aP2D);
172   U=aP2D.X();
173   V=aP2D.Y();
174   return;
175 }
176
177 //=======================================================================
178 //function : CurveOnSurface
179 //purpose  : 
180 //=======================================================================
181 void BOPTools_AlgoTools2D::CurveOnSurface (const TopoDS_Edge& aE,
182                                            const TopoDS_Face& aF,
183                                            Handle(Geom2d_Curve)& aC2D,
184                                            Standard_Real& aToler,
185                                            const Handle(IntTools_Context)& theContext)
186 {
187   Standard_Real aFirst, aLast; 
188   //
189   BOPTools_AlgoTools2D::CurveOnSurface(aE, aF, aC2D, aFirst, aLast, aToler, theContext); 
190   //
191   return;
192 }
193 //=======================================================================
194 //function : CurveOnSurface
195 //purpose  : 
196 //=======================================================================
197 void BOPTools_AlgoTools2D::CurveOnSurface (const TopoDS_Edge& aE,
198                                            const TopoDS_Face& aF,
199                                            Handle(Geom2d_Curve)& aC2D,
200                                            Standard_Real& aFirst,
201                                            Standard_Real& aLast,
202                                            Standard_Real& aToler,
203                                            const Handle(IntTools_Context)& theContext)
204 {
205   Standard_Boolean aHasOld;
206   Handle(Geom2d_Curve) C2D;
207
208   aHasOld=BOPTools_AlgoTools2D::HasCurveOnSurface (aE, aF, C2D, 
209                                                    aFirst, aLast, 
210                                                    aToler);
211   if (aHasOld) {
212     aC2D=C2D;
213     return;
214   }
215
216   BOPTools_AlgoTools2D::Make2D(aE, aF, C2D, aFirst, aLast, aToler, theContext);
217   aC2D=C2D;
218   return;
219 }
220 //=======================================================================
221 //function : HasCurveOnSurface
222 //purpose  : 
223 //=======================================================================
224 Standard_Boolean BOPTools_AlgoTools2D::HasCurveOnSurface 
225   (const TopoDS_Edge& aE,
226    const TopoDS_Face& aF,
227    Handle(Geom2d_Curve)& aC2D,
228    Standard_Real& aFirst,
229    Standard_Real& aLast,
230    Standard_Real& aToler)
231 {
232   Standard_Boolean aHasOld;
233   
234   aToler=BRep_Tool::Tolerance(aE);
235   BRep_Tool::Range(aE, aFirst, aLast);
236
237   if((aLast - aFirst) < Precision::PConfusion()) {
238     return Standard_False;
239   }
240
241   aC2D=BRep_Tool::CurveOnSurface(aE, aF, aFirst, aLast);
242   aHasOld=!aC2D.IsNull();
243   return aHasOld;
244 }
245 //=======================================================================
246 //function : HasCurveOnSurface
247 //purpose  : 
248 //=======================================================================
249 Standard_Boolean BOPTools_AlgoTools2D::HasCurveOnSurface 
250   (const TopoDS_Edge& aE,
251    const TopoDS_Face& aF)
252 {
253   Standard_Boolean bHasOld;
254   Handle(Geom2d_Curve) aC2D;
255   Standard_Real aFirst, aLast;
256   //
257   BRep_Tool::Range(aE, aFirst, aLast);
258   //
259   if((aLast - aFirst) < Precision::PConfusion()) {
260     return Standard_False;
261   }
262   //
263   aC2D=BRep_Tool::CurveOnSurface(aE, aF, aFirst, aLast);
264   bHasOld=!aC2D.IsNull();
265   //
266   return bHasOld;
267 }
268 //=======================================================================
269 //function : AdjustPCurveOnFace
270 //purpose  : 
271 //=======================================================================
272 void BOPTools_AlgoTools2D::AdjustPCurveOnFace
273   (const TopoDS_Face& theF,
274    const Handle(Geom_Curve)&   theC3D,
275    const Handle(Geom2d_Curve)& theC2D,
276    Handle(Geom2d_Curve)& theC2DA,
277    const Handle(IntTools_Context)& theContext)
278 {
279   Standard_Real aT1 = theC3D->FirstParameter();
280   Standard_Real aT2 = theC3D->LastParameter();
281   //
282   BOPTools_AlgoTools2D::AdjustPCurveOnFace (theF, aT1, aT2, theC2D, theC2DA, theContext);
283 }
284 //=======================================================================
285 //function : AdjustPCurveOnFace
286 //purpose  : 
287 //=======================================================================
288 void BOPTools_AlgoTools2D::AdjustPCurveOnFace 
289   (const TopoDS_Face& theF,
290    const Standard_Real theFirst,
291    const Standard_Real theLast,
292    const Handle(Geom2d_Curve)& theC2D, 
293    Handle(Geom2d_Curve)& theC2DA,
294    const Handle(IntTools_Context)& theContext)
295 {
296   BRepAdaptor_Surface aBASTmp;
297   const BRepAdaptor_Surface* pBAS;
298   if (!theContext.IsNull()) {
299     pBAS = &theContext->SurfaceAdaptor(theF);
300   }
301   else {
302     aBASTmp.Initialize(theF, Standard_True);
303     pBAS = &aBASTmp;
304   }
305   //
306   BOPTools_AlgoTools2D::AdjustPCurveOnSurf(*pBAS, theFirst, theLast, theC2D, theC2DA);
307 }
308 //=======================================================================
309 //function : AdjustPCurveOnFace
310 //purpose  : 
311 //=======================================================================
312 void BOPTools_AlgoTools2D::AdjustPCurveOnSurf
313   (const BRepAdaptor_Surface& aBAS,
314    const Standard_Real aFirst,
315    const Standard_Real aLast,
316    const Handle(Geom2d_Curve)& aC2D,
317    Handle(Geom2d_Curve)& aC2DA)
318 {
319   Standard_Boolean mincond, maxcond;
320   Standard_Real UMin, UMax, VMin, VMax, aT, u2, v2, du, dv, aDelta;
321   Standard_Real aUPeriod;
322   //
323   const TopoDS_Face& aF=aBAS.Face();
324   UMin=aBAS.FirstUParameter();
325   UMax=aBAS.LastUParameter();
326   VMin=aBAS.FirstVParameter();
327   VMax=aBAS.LastVParameter();
328   //
329   aDelta=Precision::PConfusion(); 
330   
331   aT =.5*(aFirst+aLast);
332
333   gp_Pnt2d pC2D; 
334   aC2D->D0(aT, pC2D);
335
336   u2 = pC2D.X();
337   v2 = pC2D.Y();
338   //
339   // du
340   du = 0.;
341   if (aBAS.IsUPeriodic()) {
342     aUPeriod = aBAS.UPeriod(); 
343     
344     //
345     // a. try to clarify u2 using the precision (aDelta)
346     if (fabs(u2-UMin) < aDelta) {
347       u2=UMin;
348     }
349     else if (fabs(u2-UMin-aUPeriod) < aDelta) {
350       u2=UMin+aUPeriod;
351     }
352     // b. compute du again using clarified value of u2
353     GeomInt::AdjustPeriodic(u2, UMin, UMax, aUPeriod, u2, du, 0.);
354     //
355     if (du==0.) {
356       if (aBAS.GetType()==GeomAbs_Cylinder) {
357         Standard_Real aR, dFi, aTol;
358         //
359         gp_Cylinder aCylinder=aBAS.Cylinder();
360         aR=aCylinder.Radius();
361         aTol=MaxToleranceEdge(aF);
362         dFi=aTol/aR;
363         if (dFi<aDelta) {
364           dFi=aDelta;
365         }
366         //
367         mincond = (UMin - u2 > dFi);
368         maxcond = (u2 - UMax > dFi);
369         if (mincond || maxcond) {
370           du = ( mincond ) ? aUPeriod : -aUPeriod;
371         }
372       }
373     } 
374   }
375   
376   // dv
377   dv = 0.;
378   if (aBAS.IsVPeriodic()) {
379     Standard_Real aVPeriod, aVm, aVr, aVmid, dVm, dVr;
380     //
381     aVPeriod = aBAS.VPeriod();
382     mincond = (VMin - v2 > aDelta);
383     maxcond = (v2 - VMax > aDelta);
384     //
385     if (mincond || maxcond) {
386       dv = ( mincond ) ? aVPeriod : -aVPeriod;
387     }
388     //
389     if ((VMax-VMin<aVPeriod) && dv) {
390       aVm=v2;
391       aVr=v2+dv;
392       aVmid=0.5*(VMin+VMax);
393       dVm=fabs(aVm-aVmid);
394       dVr=fabs(aVr-aVmid);
395       if (dVm<dVr) {
396         dv=0.;
397       }
398     }
399   }
400   //
401   {
402     //check the point with classifier
403     Standard_Real u,v;
404     u = u2 + du;
405     v = v2 + dv;
406     if (aBAS.IsUPeriodic()) {
407       aUPeriod = aBAS.UPeriod(); 
408       if ((UMax - UMin - 2*aDelta) > aUPeriod) {
409         if ((u > (UMin + aDelta + aUPeriod)) ||
410             (u < (UMax - aDelta - aUPeriod))) {
411           BRepClass_FaceClassifier aClassifier;
412           aClassifier.Perform(aF, gp_Pnt2d(u, v), aDelta);
413           TopAbs_State Status = aClassifier.State();
414           if (Status == TopAbs_OUT) {
415             du += (u > (UMin + aDelta + aUPeriod)) ? -aUPeriod : aUPeriod;
416           }
417         }
418       }
419     }
420     //
421     u = u2 + du;
422     if (aBAS.IsVPeriodic()) {
423       Standard_Real aVPeriod = aBAS.VPeriod(); 
424       if ((VMax - VMin - 2*aDelta) > aVPeriod) {
425         if ((v > (VMin + aDelta + aVPeriod)) ||
426             (v < (VMax - aDelta - aVPeriod))) {
427           BRepClass_FaceClassifier aClassifier;
428           aClassifier.Perform(aF, gp_Pnt2d(u, v), aDelta);
429           TopAbs_State Status = aClassifier.State();
430           if (Status == TopAbs_OUT) {
431             dv += (v > (VMin + aDelta + aVPeriod)) ? -aVPeriod : aVPeriod;
432           }
433         }
434       }
435     }
436   }
437   // Translation if necessary
438   Handle(Geom2d_Curve) aC2Dx=aC2D;
439
440   if ( du != 0. || dv != 0.) {
441     Handle(Geom2d_Curve) PCT = Handle(Geom2d_Curve)::DownCast(aC2Dx->Copy());
442     gp_Vec2d aV2D(du,dv);
443     PCT->Translate(aV2D);
444     aC2Dx = PCT;
445   }
446
447   aC2DA=aC2Dx;
448 }
449
450 //=======================================================================
451 //function : IntermediatePoint
452 //purpose  : 
453 //=======================================================================
454 Standard_Real BOPTools_AlgoTools2D::IntermediatePoint 
455   (const Standard_Real aFirst,
456    const Standard_Real aLast)
457 {
458   //define parameter division number as 10*e^(-PI) = 0.43213918
459   const Standard_Real PAR_T = 0.43213918;
460   Standard_Real aParm;
461   aParm=(1.-PAR_T)*aFirst + PAR_T*aLast;
462   return aParm;
463 }
464 //=======================================================================
465 //function : IntermediatePoint
466 //purpose  : 
467 //=======================================================================
468 Standard_Real BOPTools_AlgoTools2D::IntermediatePoint 
469   (const TopoDS_Edge& aE)
470                                                 
471 {
472   Standard_Real aT, aT1, aT2;
473
474   Handle(Geom_Curve)aC1=BRep_Tool::Curve(aE, aT1, aT2);
475   if (aC1.IsNull())
476     BRep_Tool::Range(aE, aT1, aT2);
477
478   aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2);
479   return aT;
480 }
481
482 //=======================================================================
483 //function : BuildPCurveForEdgeOnPlane
484 //purpose  : 
485 //=======================================================================
486 void BOPTools_AlgoTools2D::BuildPCurveForEdgeOnPlane 
487   (const TopoDS_Edge& aE,
488    const TopoDS_Face& aF)
489 {
490   Standard_Boolean bToUpdate;
491   Standard_Real aTolE, aT1, aT2;
492   Handle(Geom2d_Curve) aC2D;
493   BRep_Builder aBB;
494   //
495   aC2D=BRep_Tool_CurveOnSurface(aE, aF, aT1, aT2, bToUpdate);
496   if (bToUpdate) {
497     aTolE=BRep_Tool::Tolerance(aE);
498     aBB.UpdateEdge(aE, aC2D, aF, aTolE);
499   }
500 }
501
502 //=======================================================================
503 //function : BuildPCurveForEdgeOnPlane
504 //purpose  : 
505 //=======================================================================
506 void BOPTools_AlgoTools2D::BuildPCurveForEdgeOnPlane 
507   (const TopoDS_Edge& aE,
508    const TopoDS_Face& aF,
509    Handle(Geom2d_Curve)& aC2D,
510    Standard_Boolean& bToUpdate)
511 {
512   Standard_Real aT1, aT2;
513   aC2D=BRep_Tool_CurveOnSurface(aE, aF, aT1, aT2, bToUpdate);
514 }
515
516 //=======================================================================
517 // function: BuildPCurveForEdgesOnPlane
518 // purpose: 
519 //=======================================================================
520 void BOPTools_AlgoTools2D::BuildPCurveForEdgesOnPlane 
521   (const BOPCol_ListOfShape& aLE,
522    const TopoDS_Face& aF)
523 {
524   BOPCol_ListIteratorOfListOfShape aIt;
525   //
526   aIt.Initialize(aLE);
527   for(; aIt.More(); aIt.Next()) {
528     const TopoDS_Edge& aE=(*(TopoDS_Edge *)&aIt.Value());
529     BOPTools_AlgoTools2D::BuildPCurveForEdgeOnPlane (aE, aF);
530   }
531 }
532 //=======================================================================
533 //function : Make2D
534 //purpose  : 
535 //=======================================================================
536 void BOPTools_AlgoTools2D::Make2D (const TopoDS_Edge& aE,
537                                    const TopoDS_Face& aF,
538                                    Handle(Geom2d_Curve)& aC2D,
539                                    Standard_Real& aFirst,
540                                    Standard_Real& aLast,
541                                    Standard_Real& aToler,
542                                    const Handle(IntTools_Context)& theContext)
543 {
544   Standard_Boolean aLocIdentity;
545   Standard_Real f3d, l3d;
546   TopLoc_Location aLoc;
547
548   Handle(Geom2d_Curve) C2D; 
549   
550   
551   C2D=BRep_Tool::CurveOnSurface(aE, aF, aFirst, aLast);
552   
553   if (!C2D.IsNull()) {
554     aC2D=C2D;
555     return;
556   }
557
558   Handle(Geom_Curve) C3D2, C3D;
559   C3D = BRep_Tool::Curve(aE, aLoc, f3d, l3d);
560   //
561   if (C3D.IsNull()) { 
562     // aE has no 3D curve, so nothing is done
563   }
564   //
565   aLocIdentity=aLoc.IsIdentity();
566     
567   if (aLocIdentity) {
568     C3D2 = C3D;
569   }
570   else {
571     C3D2 = Handle(Geom_Curve)::
572       DownCast(C3D->Transformed(aLoc.Transformation()));
573   }
574   
575   //
576   aToler = BRep_Tool::Tolerance(aE);
577   BOPTools_AlgoTools2D::MakePCurveOnFace(aF, C3D2, f3d, l3d, aC2D, aToler, theContext);
578   //
579   aFirst = f3d; 
580   aLast  = l3d;
581 }
582
583 //=======================================================================
584 //function : MakePCurveOnFace
585 //purpose  : 
586 //=======================================================================
587 void BOPTools_AlgoTools2D::MakePCurveOnFace (const TopoDS_Face& aF,
588                                              const Handle(Geom_Curve)& aC3D,
589                                              Handle(Geom2d_Curve)& aC2D, //->
590                                              Standard_Real& TolReached2d,
591                                              const Handle(IntTools_Context)& theContext)
592 {
593   Standard_Real aFirst, aLast;
594
595   aFirst = aC3D -> FirstParameter();
596   aLast  = aC3D -> LastParameter();
597   //
598   TolReached2d=0.;
599   //
600   BOPTools_AlgoTools2D::MakePCurveOnFace
601     (aF, aC3D, aFirst, aLast, aC2D, TolReached2d, theContext);
602 }
603
604 //=======================================================================
605 //function : MakePCurveOnFace
606 //purpose  : 
607 //=======================================================================
608 void BOPTools_AlgoTools2D::MakePCurveOnFace
609   (const TopoDS_Face& aF,
610    const Handle(Geom_Curve)& aC3D,
611    const Standard_Real aT1,
612    const Standard_Real aT2,
613    Handle(Geom2d_Curve)& aC2D,
614    Standard_Real& TolReached2d,
615    const Handle(IntTools_Context)& theContext)
616 {
617   BRepAdaptor_Surface aBASTmp;
618   const BRepAdaptor_Surface* pBAS;
619   if (!theContext.IsNull()) {
620     pBAS = &theContext->SurfaceAdaptor(aF);
621   }
622   else {
623     aBASTmp.Initialize(aF, Standard_True);
624     pBAS = &aBASTmp;
625   }
626   //
627   Handle(BRepAdaptor_HSurface) aBAHS = new BRepAdaptor_HSurface(*pBAS);
628   Handle(GeomAdaptor_HCurve) aBAHC = new GeomAdaptor_HCurve(aC3D, aT1, aT2);
629   //
630   Standard_Real aTolR;
631   //when the type of surface is GeomAbs_SurfaceOfRevolution
632   if (pBAS->GetType() == GeomAbs_SurfaceOfRevolution) {
633     Standard_Real aTR;
634     //
635     aTR=Precision::Confusion();//1.e-7;
636     if (TolReached2d > aTR) {
637       aTR=TolReached2d;
638     }
639     //
640     ProjLib_ProjectedCurve aProj1(aBAHS, aBAHC, aTR);
641     BOPTools_AlgoTools2D::MakePCurveOfType(aProj1, aC2D);
642     aTolR = aProj1.GetTolerance();
643   } 
644   else {
645     ProjLib_ProjectedCurve aProjCurv(aBAHS, aBAHC);// 1
646     BOPTools_AlgoTools2D::MakePCurveOfType(aProjCurv, aC2D);
647     aTolR=aProjCurv.GetTolerance();
648   }
649   //
650   if (aC2D.IsNull()) { 
651     ProjLib_ProjectedCurve aProjCurvAgain(aBAHS, aBAHC, TolReached2d);// 2
652     BOPTools_AlgoTools2D::MakePCurveOfType(aProjCurvAgain, aC2D);
653     aTolR = aProjCurvAgain.GetTolerance();
654     //
655     if (aC2D.IsNull()) { 
656       Standard_Real aTR=0.0001;
657       ProjLib_ProjectedCurve aProj3(aBAHS, aBAHC, aTR);// 3
658       BOPTools_AlgoTools2D::MakePCurveOfType(aProj3, aC2D);
659       aTolR = aProj3.GetTolerance();
660     }
661   }
662   //
663   if(aC2D.IsNull())
664   {
665     Standard_ConstructionError::Raise("BOPTools_AlgoTools2D::MakePCurveOnFace : PCurve is Null");
666   }
667   //
668   TolReached2d=aTolR;
669   //
670   Handle(Geom2d_Curve) aC2DA;
671   BOPTools_AlgoTools2D::AdjustPCurveOnSurf (*pBAS, aT1, aT2, aC2D, aC2DA);
672   //
673   aC2D=aC2DA;
674   //
675   // compute the appropriate tolerance for the edge
676   Handle(Geom_Surface) aS = pBAS->Surface().Surface();
677   aS = Handle(Geom_Surface)::DownCast(aS->Transformed(pBAS->Trsf()));
678   //
679   Standard_Real aT;
680   if (IntTools_Tools::ComputeTolerance
681       (aC3D, aC2D, aS, aT1, aT2, aTolR, aT)) {
682     if (aTolR > TolReached2d) {
683       TolReached2d = aTolR;
684     }
685   }
686 }
687
688 //=======================================================================
689 //function : MakePCurveOfType
690 //purpose  : 
691 //=======================================================================
692 void  BOPTools_AlgoTools2D::MakePCurveOfType
693   (const ProjLib_ProjectedCurve& PC, 
694    Handle(Geom2d_Curve)& C2D)
695 {
696   
697   switch (PC.GetType()) {
698
699   case GeomAbs_Line : 
700     C2D = new Geom2d_Line(PC.Line()); 
701     break;
702   case GeomAbs_Circle : 
703     C2D = new Geom2d_Circle(PC.Circle());
704     break;
705   case GeomAbs_Ellipse :
706     C2D = new Geom2d_Ellipse(PC.Ellipse());
707     break;
708   case GeomAbs_Parabola : 
709     C2D = new Geom2d_Parabola(PC.Parabola()); 
710     break;
711   case GeomAbs_Hyperbola : 
712     C2D = new Geom2d_Hyperbola(PC.Hyperbola()); 
713     break;
714   case GeomAbs_BSplineCurve :
715     C2D = PC.BSpline(); 
716     break;
717   case GeomAbs_BezierCurve : 
718   case GeomAbs_OtherCurve : 
719     default :
720     Standard_NotImplemented::Raise
721       ("BOPTools_AlgoTools2D::MakePCurveOfType");
722     break;
723   }
724 }
725 //=======================================================================
726 //function : CheckEdgeLength
727 //purpose  : 
728 //=======================================================================
729 Standard_Boolean CheckEdgeLength (const TopoDS_Edge& E)
730 {
731   BRepAdaptor_Curve BC(E);
732
733   BOPCol_IndexedMapOfShape aM;
734   BOPTools::MapShapes(E, TopAbs_VERTEX, aM);
735   Standard_Integer i, anExtent, aN=10;
736   Standard_Real ln=0., d, t, f, l, dt; 
737   anExtent=aM.Extent();
738
739   if (anExtent!=1) 
740     return Standard_True;
741     
742   gp_Pnt p1, p2;
743   f = BC.FirstParameter();
744   l = BC.LastParameter();
745   dt=(l-f)/aN;
746   
747   BC.D0(f, p1);
748   for (i=1; i<=aN; i++) {
749     t=f+i*dt;
750     
751     if (i==aN) 
752       BC.D0(l, p2);
753     else 
754       BC.D0(t, p2);
755     
756     d=p1.Distance(p2);
757     ln+=d;
758     p1=p2;
759   }
760   //
761   return (ln > Precision::Confusion()); 
762 }
763 //=======================================================================
764 //function : BRep_Tool_CurveOnSurface
765 //purpose  : 
766 //=======================================================================
767 Handle(Geom2d_Curve) BRep_Tool_CurveOnSurface(const TopoDS_Edge& E, 
768                                               const TopoDS_Face& F,
769                                               Standard_Real& First,
770                                               Standard_Real& Last,
771                                               Standard_Boolean& bToUpdate)
772 {
773   TopLoc_Location l;
774   const Handle(Geom_Surface)& S = BRep_Tool::Surface(F,l);
775   TopoDS_Edge aLocalEdge = E;
776   if (F.Orientation() == TopAbs_REVERSED) {
777     aLocalEdge.Reverse();
778   }
779   //
780   return BRep_Tool_CurveOnSurface(aLocalEdge,S,l,First,Last,bToUpdate);
781 }
782 //=======================================================================
783 //function : BRep_Tool_CurveOnSurface
784 //purpose  : 
785 //=======================================================================
786 Handle(Geom2d_Curve) BRep_Tool_CurveOnSurface
787        (const TopoDS_Edge& E, 
788         const Handle(Geom_Surface)& S,
789         const TopLoc_Location& L,
790         Standard_Real& First,
791         Standard_Real& Last,
792         Standard_Boolean& bToUpdate)
793 {
794   static const Handle(Geom2d_Curve) nullPCurve;
795   bToUpdate=Standard_False;
796   TopLoc_Location loc = L.Predivided(E.Location());
797   Standard_Boolean Eisreversed = (E.Orientation() == TopAbs_REVERSED);
798
799   // find the representation
800   BRep_ListIteratorOfListOfCurveRepresentation itcr
801     ((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves());
802
803   while (itcr.More()) {
804     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
805     if (cr->IsCurveOnSurface(S,loc)) {
806       Handle(BRep_GCurve) GC (Handle(BRep_GCurve)::DownCast (cr));
807       GC->Range(First,Last);
808       if (GC->IsCurveOnClosedSurface() && Eisreversed)
809         return GC->PCurve2();
810       else
811         return GC->PCurve();
812     }
813     itcr.Next();
814   }
815
816   // for planar surface and 3d curve try a projection
817   // modif 21-05-97 : for RectangularTrimmedSurface, try a projection
818   Handle(Geom_Plane) GP;
819   Handle(Geom_RectangularTrimmedSurface) GRTS;
820   GRTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(S);
821   if(!GRTS.IsNull())
822     GP = Handle(Geom_Plane)::DownCast(GRTS->BasisSurface());
823   else
824     GP = Handle(Geom_Plane)::DownCast(S);
825   //fin modif du 21-05-97
826
827   if (!GP.IsNull()) {
828
829     Handle(GeomAdaptor_HCurve) HC;
830     Handle(GeomAdaptor_HSurface) HS;
831
832     HC = new GeomAdaptor_HCurve();
833     HS = new GeomAdaptor_HSurface();
834
835     TopLoc_Location LC;
836
837     Standard_Real f, l;// for those who call with (u,u).
838     Handle(Geom_Curve) C3d =
839       BRep_Tool::Curve(E,/*LC,*/f,l); // transforming plane instead of curve
840     // we can loose scale factor of Curve transformation (eap 13 May 2002)
841
842     LC = L/*.Predivided(LC)*/;
843
844     if (C3d.IsNull()) return nullPCurve;
845
846     Handle(Geom_Plane) Plane = GP;
847     if (!LC.IsIdentity()) {
848       const gp_Trsf& T = LC.Transformation();
849       Handle(Geom_Geometry) GPT = GP->Transformed(T);
850       Plane = Handle(Geom_Plane)::DownCast (GPT);
851     }
852     GeomAdaptor_Surface& GAS = HS->ChangeSurface();
853     GAS.Load(Plane);
854     
855     Handle(Geom_Curve) ProjOnPlane = 
856       GeomProjLib::ProjectOnPlane(new Geom_TrimmedCurve(C3d,f,l),
857                                   Plane,
858                                   Plane->Position().Direction(),
859                                   Standard_True);
860     
861     GeomAdaptor_Curve& GAC = HC->ChangeCurve();
862     GAC.Load(ProjOnPlane);
863
864     ProjLib_ProjectedCurve Proj(HS,HC);
865     Handle(Geom2d_Curve) pc = Geom2dAdaptor::MakeCurve(Proj);
866
867     if (pc->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
868       Handle(Geom2d_TrimmedCurve) TC = 
869         Handle(Geom2d_TrimmedCurve)::DownCast (pc);
870       pc = TC->BasisCurve();
871     }
872     First = f; Last = l;
873     //
874     bToUpdate=Standard_True;
875     //
876     return pc;
877   }
878   
879   return nullPCurve;
880 }
881 //=======================================================================
882 //function : MaxToleranceEdge
883 //purpose  : 
884 //=======================================================================
885 Standard_Real MaxToleranceEdge (const TopoDS_Face& aF) 
886 {
887   Standard_Real aTol, aTolMax;
888   TopExp_Explorer aExp;
889   //
890   aTolMax=0.;
891   aExp.Init(aF, TopAbs_EDGE);
892   for (; aExp.More(); aExp.Next()) {
893     const TopoDS_Edge& aE=*((TopoDS_Edge *)&aExp.Current());
894     aTol=BRep_Tool::Tolerance(aE);
895     if (aTol>aTolMax) {
896       aTolMax=aTol;
897     }
898   }
899   return aTolMax;
900 }
901
902 //=======================================================================
903 //function : IsEdgeIsoline
904 //purpose  : 
905 //=======================================================================
906 void BOPTools_AlgoTools2D::IsEdgeIsoline( const TopoDS_Edge& theE,
907                                           const TopoDS_Face& theF,
908                                           Standard_Boolean& isTheUIso,
909                                           Standard_Boolean& isTheVIso)
910 {
911   isTheUIso = isTheVIso = Standard_False;
912
913   gp_Vec2d aT;
914   gp_Pnt2d aP;
915   Standard_Real aFirst = 0.0, aLast = 0.0;
916   const Handle(Geom2d_Curve) aPC = BRep_Tool::CurveOnSurface(theE, theF, aFirst, aLast);
917
918   aPC->D1(0.5*(aFirst+aLast), aP, aT);
919
920   const Standard_Real aSqMagn = aT.SquareMagnitude();
921   if(aSqMagn <= gp::Resolution())
922     return;
923
924   //Normalyze aT
925   aT /= sqrt(aSqMagn);
926
927   //sin(da) ~ da, when da->0.
928   const Standard_Real aTol = Precision::Angular();
929   const gp_Vec2d aRefVDir(0.0, 1.0), aRefUDir(1.0, 0.0);
930
931   const Standard_Real aDPv = aT.CrossMagnitude(aRefVDir),
932                       aDPu = aT.CrossMagnitude(aRefUDir);
933
934   isTheUIso = (aDPv <= aTol);
935   isTheVIso = (aDPu <= aTol);
936 }