0025833: Visualization, ray tracing - Problems with the backside of triangles
[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, aT;
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   // compute the appropriate tolerance for the edge
623   if (IntTools_Tools::ComputeTolerance
624       (aC3D, aC2D, aS, aFirst, aLast, aTolR, aT)) {
625     if (aTolR > TolReached2d) {
626       TolReached2d = aTolR;
627     }
628   }
629 }
630
631 //=======================================================================
632 //function : MakePCurveOfType
633 //purpose  : 
634 //=======================================================================
635 void  BOPTools_AlgoTools2D::MakePCurveOfType
636   (const ProjLib_ProjectedCurve& PC, 
637    Handle(Geom2d_Curve)& C2D)
638 {
639   
640   switch (PC.GetType()) {
641
642   case GeomAbs_Line : 
643     C2D = new Geom2d_Line(PC.Line()); 
644     break;
645   case GeomAbs_Circle : 
646     C2D = new Geom2d_Circle(PC.Circle());
647     break;
648   case GeomAbs_Ellipse :
649     C2D = new Geom2d_Ellipse(PC.Ellipse());
650     break;
651   case GeomAbs_Parabola : 
652     C2D = new Geom2d_Parabola(PC.Parabola()); 
653     break;
654   case GeomAbs_Hyperbola : 
655     C2D = new Geom2d_Hyperbola(PC.Hyperbola()); 
656     break;
657   case GeomAbs_BSplineCurve :
658     C2D = PC.BSpline(); 
659     break;
660   case GeomAbs_BezierCurve : 
661   case GeomAbs_OtherCurve : 
662     default :
663     Standard_NotImplemented::Raise
664       ("BOPTools_AlgoTools2D::MakePCurveOfType");
665     break;
666   }
667 }
668 //=======================================================================
669 //function : CheckEdgeLength
670 //purpose  : 
671 //=======================================================================
672 Standard_Boolean CheckEdgeLength (const TopoDS_Edge& E)
673 {
674   BRepAdaptor_Curve BC(E);
675
676   BOPCol_IndexedMapOfShape aM;
677   BOPTools::MapShapes(E, TopAbs_VERTEX, aM);
678   Standard_Integer i, anExtent, aN=10;
679   Standard_Real ln=0., d, t, f, l, dt; 
680   anExtent=aM.Extent();
681
682   if (anExtent!=1) 
683     return Standard_True;
684     
685   gp_Pnt p1, p2;
686   f = BC.FirstParameter();
687   l = BC.LastParameter();
688   dt=(l-f)/aN;
689   
690   BC.D0(f, p1);
691   for (i=1; i<=aN; i++) {
692     t=f+i*dt;
693     
694     if (i==aN) 
695       BC.D0(l, p2);
696     else 
697       BC.D0(t, p2);
698     
699     d=p1.Distance(p2);
700     ln+=d;
701     p1=p2;
702   }
703   //
704   return (ln > Precision::Confusion()); 
705 }
706 //=======================================================================
707 //function : BRep_Tool_CurveOnSurface
708 //purpose  : 
709 //=======================================================================
710 Handle(Geom2d_Curve) BRep_Tool_CurveOnSurface(const TopoDS_Edge& E, 
711                                               const TopoDS_Face& F,
712                                               Standard_Real& First,
713                                               Standard_Real& Last,
714                                               Standard_Boolean& bToUpdate)
715 {
716   TopLoc_Location l;
717   const Handle(Geom_Surface)& S = BRep_Tool::Surface(F,l);
718   TopoDS_Edge aLocalEdge = E;
719   if (F.Orientation() == TopAbs_REVERSED) {
720     aLocalEdge.Reverse();
721   }
722   //
723   return BRep_Tool_CurveOnSurface(aLocalEdge,S,l,First,Last,bToUpdate);
724 }
725 //=======================================================================
726 //function : BRep_Tool_CurveOnSurface
727 //purpose  : 
728 //=======================================================================
729 Handle(Geom2d_Curve) BRep_Tool_CurveOnSurface
730        (const TopoDS_Edge& E, 
731         const Handle(Geom_Surface)& S,
732         const TopLoc_Location& L,
733         Standard_Real& First,
734         Standard_Real& Last,
735         Standard_Boolean& bToUpdate)
736 {
737   static const Handle(Geom2d_Curve) nullPCurve;
738   bToUpdate=Standard_False;
739   TopLoc_Location loc = L.Predivided(E.Location());
740   Standard_Boolean Eisreversed = (E.Orientation() == TopAbs_REVERSED);
741
742   // find the representation
743   BRep_ListIteratorOfListOfCurveRepresentation itcr
744     ((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves());
745
746   while (itcr.More()) {
747     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
748     if (cr->IsCurveOnSurface(S,loc)) {
749       const Handle(BRep_GCurve)& GC = *((Handle(BRep_GCurve)*)&cr);
750       GC->Range(First,Last);
751       if (GC->IsCurveOnClosedSurface() && Eisreversed)
752         return GC->PCurve2();
753       else
754         return GC->PCurve();
755     }
756     itcr.Next();
757   }
758
759   // for planar surface and 3d curve try a projection
760   // modif 21-05-97 : for RectangularTrimmedSurface, try a projection
761   Handle(Geom_Plane) GP;
762   Handle(Geom_RectangularTrimmedSurface) GRTS;
763   GRTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(S);
764   if(!GRTS.IsNull())
765     GP = Handle(Geom_Plane)::DownCast(GRTS->BasisSurface());
766   else
767     GP = Handle(Geom_Plane)::DownCast(S);
768   //fin modif du 21-05-97
769
770   if (!GP.IsNull()) {
771
772     Handle(GeomAdaptor_HCurve) HC;
773     Handle(GeomAdaptor_HSurface) HS;
774
775     HC = new GeomAdaptor_HCurve();
776     HS = new GeomAdaptor_HSurface();
777
778     TopLoc_Location LC;
779
780     Standard_Real f, l;// for those who call with (u,u).
781     Handle(Geom_Curve) C3d =
782       BRep_Tool::Curve(E,/*LC,*/f,l); // transforming plane instead of curve
783     // we can loose scale factor of Curve transformation (eap 13 May 2002)
784
785     LC = L/*.Predivided(LC)*/;
786
787     if (C3d.IsNull()) return nullPCurve;
788
789     Handle(Geom_Plane) Plane = GP;
790     if (!LC.IsIdentity()) {
791       const gp_Trsf& T = LC.Transformation();
792       Handle(Geom_Geometry) GPT = GP->Transformed(T);
793       Plane = *((Handle(Geom_Plane)*)&GPT);
794     }
795     GeomAdaptor_Surface& GAS = HS->ChangeSurface();
796     GAS.Load(Plane);
797     
798     Handle(Geom_Curve) ProjOnPlane = 
799       GeomProjLib::ProjectOnPlane(new Geom_TrimmedCurve(C3d,f,l),
800                                   Plane,
801                                   Plane->Position().Direction(),
802                                   Standard_True);
803     
804     GeomAdaptor_Curve& GAC = HC->ChangeCurve();
805     GAC.Load(ProjOnPlane);
806
807     ProjLib_ProjectedCurve Proj(HS,HC);
808     Handle(Geom2d_Curve) pc = Geom2dAdaptor::MakeCurve(Proj);
809
810     if (pc->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
811       Handle(Geom2d_TrimmedCurve) TC = 
812         (*((Handle(Geom2d_TrimmedCurve)*)&pc));
813       pc = TC->BasisCurve();
814     }
815     First = f; Last = l;
816     //
817     bToUpdate=Standard_True;
818     //
819     return pc;
820   }
821   
822   return nullPCurve;
823 }
824 //=======================================================================
825 //function : MaxToleranceEdge
826 //purpose  : 
827 //=======================================================================
828 Standard_Real MaxToleranceEdge (const TopoDS_Face& aF) 
829 {
830   Standard_Real aTol, aTolMax;
831   TopExp_Explorer aExp;
832   //
833   aTolMax=0.;
834   aExp.Init(aF, TopAbs_EDGE);
835   for (; aExp.More(); aExp.Next()) {
836     const TopoDS_Edge& aE=*((TopoDS_Edge *)&aExp.Current());
837     aTol=BRep_Tool::Tolerance(aE);
838     if (aTol>aTolMax) {
839       aTolMax=aTol;
840     }
841   }
842   return aTolMax;
843 }