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