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