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