0025880: fuzzy booleans with multiple tools
[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 aT1, aT2;
288   //
289   aT1=aC3D->FirstParameter();
290   aT2=aC3D->LastParameter();
291   //
292   BOPTools_AlgoTools2D::AdjustPCurveOnFace (aF, aT1, aT2, aC2D, aC2DA);
293 }
294 //=======================================================================
295 //function : AdjustPCurveOnFace
296 //purpose  : 
297 //=======================================================================
298 void BOPTools_AlgoTools2D::AdjustPCurveOnFace 
299   (const TopoDS_Face& aF,
300    const Standard_Real aT1,
301    const Standard_Real aT2,
302    const Handle(Geom2d_Curve)& aC2D, 
303    Handle(Geom2d_Curve)& aC2DA)
304 {
305   BRepAdaptor_Surface aBAS(aF, Standard_True);
306   //
307   BOPTools_AlgoTools2D::AdjustPCurveOnFace(aBAS, aT1, aT2, 
308                                            aC2D, aC2DA);
309 }
310
311 //=======================================================================
312 //function : AdjustPCurveOnFace
313 //purpose  : 
314 //=======================================================================
315 void BOPTools_AlgoTools2D::AdjustPCurveOnFace 
316   (const BRepAdaptor_Surface& aBAS,
317    const Standard_Real aFirst,
318    const Standard_Real aLast,
319    const Handle(Geom2d_Curve)& aC2D, 
320    Handle(Geom2d_Curve)& aC2DA)
321 {
322   Standard_Boolean mincond, maxcond;
323   Standard_Real UMin, UMax, VMin, VMax, aT, u2, v2, du, dv, aDelta;
324   Standard_Real aUPeriod;
325   //
326   const TopoDS_Face& aF=aBAS.Face();
327   UMin=aBAS.FirstUParameter();
328   UMax=aBAS.LastUParameter();
329   VMin=aBAS.FirstVParameter();
330   VMax=aBAS.LastVParameter();
331   //
332   //BRepAdaptor_Surface aBAS(aF, Standard_False);
333   //BRepTools::UVBounds(aF, UMin, UMax, VMin, VMax);
334   //
335   aDelta=Precision::PConfusion(); 
336   
337   aT =.5*(aFirst+aLast);
338
339   gp_Pnt2d pC2D; 
340   aC2D->D0(aT, pC2D);
341
342   u2 = pC2D.X();
343   v2 = pC2D.Y();
344   //
345   // du
346   du = 0.;
347   if (aBAS.IsUPeriodic()) {
348     aUPeriod = aBAS.UPeriod(); 
349     
350     //
351     // a. try to clarify u2 using the precision (aDelta)
352     if (fabs(u2-UMin) < aDelta) {
353       u2=UMin;
354     }
355     else if (fabs(u2-UMin-aUPeriod) < aDelta) {
356       u2=UMin+aUPeriod;
357     }
358     // b. compute du again using clarified value of u2
359     GeomInt::AdjustPeriodic(u2, UMin, UMax, aUPeriod, u2, du, 0.);
360     //
361     if (du==0.) {
362       if (aBAS.GetType()==GeomAbs_Cylinder) {
363         Standard_Real aR, dFi, aTol;
364         //
365         gp_Cylinder aCylinder=aBAS.Cylinder();
366         aR=aCylinder.Radius();
367         aTol=MaxToleranceEdge(aF);
368         dFi=aTol/aR;
369         if (dFi<aDelta) {
370           dFi=aDelta;
371         }
372         //
373         mincond = (UMin - u2 > dFi);
374         maxcond = (u2 - UMax > dFi);
375         if (mincond || maxcond) {
376           du = ( mincond ) ? aUPeriod : -aUPeriod;
377         }
378       }
379     } 
380   }
381   
382   // dv
383   dv = 0.;
384   if (aBAS.IsVPeriodic()) {
385     Standard_Real aVPeriod, aVm, aVr, aVmid, dVm, dVr;
386     //
387     aVPeriod = aBAS.VPeriod();
388     mincond = (VMin - v2 > aDelta);
389     maxcond = (v2 - VMax > aDelta);
390     //
391     if (mincond || maxcond) {
392       dv = ( mincond ) ? aVPeriod : -aVPeriod;
393     }
394     //
395     if ((VMax-VMin<aVPeriod) && dv) {
396       aVm=v2;
397       aVr=v2+dv;
398       aVmid=0.5*(VMin+VMax);
399       dVm=fabs(aVm-aVmid);
400       dVr=fabs(aVr-aVmid);
401       if (dVm<dVr) {
402         dv=0.;
403       }
404     }
405   }
406   //
407   {
408     //check the point with classifier
409     Standard_Real u,v;
410     u = u2 + du;
411     v = v2 + dv;
412     if (aBAS.IsUPeriodic()) {
413       aUPeriod = aBAS.UPeriod(); 
414       if ((UMax - UMin - 2*aDelta) > aUPeriod) {
415         if ((u > (UMin + aDelta + aUPeriod)) ||
416             (u < (UMax - aDelta - aUPeriod))) {
417           BRepClass_FaceClassifier aClassifier;
418           aClassifier.Perform(aF, gp_Pnt2d(u, v), aDelta);
419           TopAbs_State Status = aClassifier.State();
420           if (Status == TopAbs_OUT) {
421             du += (u > (UMin + aDelta + aUPeriod)) ? -aUPeriod : aUPeriod;
422           }
423         }
424       }
425     }
426     //
427     u = u2 + du;
428     if (aBAS.IsVPeriodic()) {
429       Standard_Real aVPeriod = aBAS.VPeriod(); 
430       if ((VMax - VMin - 2*aDelta) > aVPeriod) {
431         if ((v > (VMin + aDelta + aVPeriod)) ||
432             (v < (VMax - aDelta - aVPeriod))) {
433           BRepClass_FaceClassifier aClassifier;
434           aClassifier.Perform(aF, gp_Pnt2d(u, v), aDelta);
435           TopAbs_State Status = aClassifier.State();
436           if (Status == TopAbs_OUT) {
437             dv += (v > (VMin + aDelta + aVPeriod)) ? -aVPeriod : aVPeriod;
438           }
439         }
440       }
441     }
442   }
443   // Translation if necessary
444   Handle(Geom2d_Curve) aC2Dx=aC2D;
445
446   if ( du != 0. || dv != 0.) {
447     Handle(Geom2d_Curve) PCT = Handle(Geom2d_Curve)::DownCast(aC2Dx->Copy());
448     gp_Vec2d aV2D(du,dv);
449     PCT->Translate(aV2D);
450     aC2Dx = PCT;
451   }
452
453   aC2DA=aC2Dx;
454 }
455
456 //=======================================================================
457 //function : IntermediatePoint
458 //purpose  : 
459 //=======================================================================
460 Standard_Real BOPTools_AlgoTools2D::IntermediatePoint 
461   (const Standard_Real aFirst,
462    const Standard_Real aLast)
463 {
464   //define parameter division number as 10*e^(-PI) = 0.43213918
465   const Standard_Real PAR_T = 0.43213918;
466   Standard_Real aParm;
467   aParm=(1.-PAR_T)*aFirst + PAR_T*aLast;
468   return aParm;
469 }
470 //=======================================================================
471 //function : IntermediatePoint
472 //purpose  : 
473 //=======================================================================
474 Standard_Real BOPTools_AlgoTools2D::IntermediatePoint 
475   (const TopoDS_Edge& aE)
476                                                 
477 {
478   Standard_Real aT, aT1, aT2;
479
480   Handle(Geom_Curve)aC1=BRep_Tool::Curve(aE, aT1, aT2);
481   if (aC1.IsNull())
482     BRep_Tool::Range(aE, aT1, aT2);
483
484   aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2);
485   return aT;
486 }
487
488 //=======================================================================
489 //function : BuildPCurveForEdgeOnPlane
490 //purpose  : 
491 //=======================================================================
492 void BOPTools_AlgoTools2D::BuildPCurveForEdgeOnPlane 
493   (const TopoDS_Edge& aE,
494    const TopoDS_Face& aF)
495 {
496   Standard_Boolean bToUpdate;
497   Standard_Real aTolE, aT1, aT2;
498   Handle(Geom2d_Curve) aC2D;
499   BRep_Builder aBB;
500   //
501   aC2D=BRep_Tool_CurveOnSurface(aE, aF, aT1, aT2, bToUpdate);
502   if (bToUpdate) {
503     aTolE=BRep_Tool::Tolerance(aE);
504     aBB.UpdateEdge(aE, aC2D, aF, aTolE);
505   }
506 }
507 //=======================================================================
508 // function: BuildPCurveForEdgesOnPlane
509 // purpose: 
510 //=======================================================================
511 void BOPTools_AlgoTools2D::BuildPCurveForEdgesOnPlane 
512   (const BOPCol_ListOfShape& aLE,
513    const TopoDS_Face& aF)
514 {
515   BOPCol_ListIteratorOfListOfShape aIt;
516   //
517   aIt.Initialize(aLE);
518   for(; aIt.More(); aIt.Next()) {
519     const TopoDS_Edge& aE=(*(TopoDS_Edge *)&aIt.Value());
520     BOPTools_AlgoTools2D::BuildPCurveForEdgeOnPlane (aE, aF);
521   }
522 }
523 //=======================================================================
524 //function : Make2D
525 //purpose  : 
526 //=======================================================================
527 void BOPTools_AlgoTools2D::Make2D (const TopoDS_Edge& aE,
528                                    const TopoDS_Face& aF,
529                                    Handle(Geom2d_Curve)& aC2D,
530                                    Standard_Real& aFirst,
531                                    Standard_Real& aLast,
532                                    Standard_Real& aToler)
533 {
534   Standard_Boolean aLocIdentity;
535   Standard_Real f3d, l3d;
536   TopLoc_Location aLoc;
537
538   Handle(Geom2d_Curve) C2D; 
539   
540   
541   C2D=BRep_Tool::CurveOnSurface(aE, aF, aFirst, aLast);
542   
543   if (!C2D.IsNull()) {
544     aC2D=C2D;
545     return;
546   }
547
548   Handle(Geom_Curve) C3D2, C3D;
549   C3D = BRep_Tool::Curve(aE, aLoc, f3d, l3d);
550   //
551   if (C3D.IsNull()) { 
552     // aE has no 3D curve, so nothing is done
553   }
554   //
555   aLocIdentity=aLoc.IsIdentity();
556     
557   if (aLocIdentity) {
558     C3D2 = C3D;
559   }
560   else {
561     C3D2 = Handle(Geom_Curve)::
562       DownCast(C3D->Transformed(aLoc.Transformation()));
563   }
564   
565   //
566   aToler = BRep_Tool::Tolerance(aE);
567   BOPTools_AlgoTools2D::MakePCurveOnFace(aF, C3D2, f3d, l3d, aC2D, aToler);
568   //
569   aFirst = f3d; 
570   aLast  = l3d;
571 }
572
573 //=======================================================================
574 //function : MakePCurveOnFace
575 //purpose  : 
576 //=======================================================================
577 void BOPTools_AlgoTools2D::MakePCurveOnFace (const TopoDS_Face& aF,
578                                              const Handle(Geom_Curve)& aC3D,
579                                              Handle(Geom2d_Curve)& aC2D, //->
580                                              Standard_Real& TolReached2d)
581 {
582   Standard_Real aFirst, aLast;
583
584   aFirst = aC3D -> FirstParameter();
585   aLast  = aC3D -> LastParameter();
586   //
587   TolReached2d=0.;
588   //
589   BOPTools_AlgoTools2D::MakePCurveOnFace (aF, aC3D, aFirst, 
590                                           aLast, aC2D, TolReached2d);
591 }
592
593 //=======================================================================
594 //function : MakePCurveOnFace
595 //purpose  : 
596 //=======================================================================
597 void BOPTools_AlgoTools2D::MakePCurveOnFace 
598   (const TopoDS_Face& aF,
599    const Handle(Geom_Curve)& aC3D,
600    const Standard_Real aT1,
601    const Standard_Real aT2,
602    Handle(Geom2d_Curve)& aC2D, 
603    Standard_Real& TolReached2d)
604 {
605   Standard_Real aTolR, aT;
606   Standard_Real aUMin, aUMax, aVMin, aVMax;
607   Handle(Geom2d_Curve) aC2DA;
608   Handle(GeomAdaptor_HSurface) aBAHS;
609   Handle(GeomAdaptor_HCurve) aBAHC;
610   Handle(Geom_Surface) aS;
611   //
612   BRepAdaptor_Surface aBAS(aF, Standard_True);
613   aUMin=aBAS.FirstUParameter();
614   aUMax=aBAS.LastUParameter();
615   aVMin=aBAS.FirstVParameter();
616   aVMax=aBAS.LastVParameter();
617   aS=aBAS.Surface().Surface();
618   aS=Handle(Geom_Surface)::DownCast(aS->Transformed(aBAS.Trsf()));
619   GeomAdaptor_Surface aGAS(aS, aUMin, aUMax, aVMin, aVMax);
620   //
621   aBAHS=new GeomAdaptor_HSurface(aGAS);
622   aBAHC=new GeomAdaptor_HCurve(aC3D, aT1, aT2);
623   //
624   //when the type of surface is GeomAbs_SurfaceOfRevolution
625   if (aGAS.GetType() == GeomAbs_SurfaceOfRevolution) {
626     Standard_Real aTR;
627     //
628     aTR=Precision::Confusion();//1.e-7;
629     if (TolReached2d > aTR) {
630       aTR=TolReached2d;
631     }
632     //
633     ProjLib_ProjectedCurve aProj1(aBAHS, aBAHC, aTR);
634     BOPTools_AlgoTools2D::MakePCurveOfType(aProj1, aC2D);
635     aTolR = aProj1.GetTolerance();
636   } 
637   else {
638     ProjLib_ProjectedCurve aProjCurv(aBAHS, aBAHC);// 1
639     BOPTools_AlgoTools2D::MakePCurveOfType(aProjCurv, aC2D);
640     aTolR=aProjCurv.GetTolerance();
641   }
642   //
643   if (aC2D.IsNull()) { 
644     ProjLib_ProjectedCurve aProjCurvAgain(aBAHS, aBAHC, TolReached2d);// 2
645     BOPTools_AlgoTools2D::MakePCurveOfType(aProjCurvAgain, aC2D);
646     aTolR = aProjCurvAgain.GetTolerance();
647     //
648     if (aC2D.IsNull()) { 
649       Standard_Real aTR=0.0001;
650       ProjLib_ProjectedCurve aProj3(aBAHS, aBAHC, aTR);// 3
651       BOPTools_AlgoTools2D::MakePCurveOfType(aProj3, aC2D);
652       aTolR = aProj3.GetTolerance();
653     }
654   }
655   TolReached2d=aTolR;
656   BOPTools_AlgoTools2D::AdjustPCurveOnFace (aBAS, aT1, aT2, 
657                                             aC2D, aC2DA);
658   //
659   aC2D=aC2DA;
660   //
661   // compute the appropriate tolerance for the edge
662   if (IntTools_Tools::ComputeTolerance
663       (aC3D, aC2D, aS, aT1, aT2, aTolR, aT)) {
664     if (aTolR > TolReached2d) {
665       TolReached2d = aTolR;
666     }
667   }
668 }
669
670 //=======================================================================
671 //function : MakePCurveOfType
672 //purpose  : 
673 //=======================================================================
674 void  BOPTools_AlgoTools2D::MakePCurveOfType
675   (const ProjLib_ProjectedCurve& PC, 
676    Handle(Geom2d_Curve)& C2D)
677 {
678   
679   switch (PC.GetType()) {
680
681   case GeomAbs_Line : 
682     C2D = new Geom2d_Line(PC.Line()); 
683     break;
684   case GeomAbs_Circle : 
685     C2D = new Geom2d_Circle(PC.Circle());
686     break;
687   case GeomAbs_Ellipse :
688     C2D = new Geom2d_Ellipse(PC.Ellipse());
689     break;
690   case GeomAbs_Parabola : 
691     C2D = new Geom2d_Parabola(PC.Parabola()); 
692     break;
693   case GeomAbs_Hyperbola : 
694     C2D = new Geom2d_Hyperbola(PC.Hyperbola()); 
695     break;
696   case GeomAbs_BSplineCurve :
697     C2D = PC.BSpline(); 
698     break;
699   case GeomAbs_BezierCurve : 
700   case GeomAbs_OtherCurve : 
701     default :
702     Standard_NotImplemented::Raise
703       ("BOPTools_AlgoTools2D::MakePCurveOfType");
704     break;
705   }
706 }
707 //=======================================================================
708 //function : CheckEdgeLength
709 //purpose  : 
710 //=======================================================================
711 Standard_Boolean CheckEdgeLength (const TopoDS_Edge& E)
712 {
713   BRepAdaptor_Curve BC(E);
714
715   BOPCol_IndexedMapOfShape aM;
716   BOPTools::MapShapes(E, TopAbs_VERTEX, aM);
717   Standard_Integer i, anExtent, aN=10;
718   Standard_Real ln=0., d, t, f, l, dt; 
719   anExtent=aM.Extent();
720
721   if (anExtent!=1) 
722     return Standard_True;
723     
724   gp_Pnt p1, p2;
725   f = BC.FirstParameter();
726   l = BC.LastParameter();
727   dt=(l-f)/aN;
728   
729   BC.D0(f, p1);
730   for (i=1; i<=aN; i++) {
731     t=f+i*dt;
732     
733     if (i==aN) 
734       BC.D0(l, p2);
735     else 
736       BC.D0(t, p2);
737     
738     d=p1.Distance(p2);
739     ln+=d;
740     p1=p2;
741   }
742   //
743   return (ln > Precision::Confusion()); 
744 }
745 //=======================================================================
746 //function : BRep_Tool_CurveOnSurface
747 //purpose  : 
748 //=======================================================================
749 Handle(Geom2d_Curve) BRep_Tool_CurveOnSurface(const TopoDS_Edge& E, 
750                                               const TopoDS_Face& F,
751                                               Standard_Real& First,
752                                               Standard_Real& Last,
753                                               Standard_Boolean& bToUpdate)
754 {
755   TopLoc_Location l;
756   const Handle(Geom_Surface)& S = BRep_Tool::Surface(F,l);
757   TopoDS_Edge aLocalEdge = E;
758   if (F.Orientation() == TopAbs_REVERSED) {
759     aLocalEdge.Reverse();
760   }
761   //
762   return BRep_Tool_CurveOnSurface(aLocalEdge,S,l,First,Last,bToUpdate);
763 }
764 //=======================================================================
765 //function : BRep_Tool_CurveOnSurface
766 //purpose  : 
767 //=======================================================================
768 Handle(Geom2d_Curve) BRep_Tool_CurveOnSurface
769        (const TopoDS_Edge& E, 
770         const Handle(Geom_Surface)& S,
771         const TopLoc_Location& L,
772         Standard_Real& First,
773         Standard_Real& Last,
774         Standard_Boolean& bToUpdate)
775 {
776   static const Handle(Geom2d_Curve) nullPCurve;
777   bToUpdate=Standard_False;
778   TopLoc_Location loc = L.Predivided(E.Location());
779   Standard_Boolean Eisreversed = (E.Orientation() == TopAbs_REVERSED);
780
781   // find the representation
782   BRep_ListIteratorOfListOfCurveRepresentation itcr
783     ((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves());
784
785   while (itcr.More()) {
786     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
787     if (cr->IsCurveOnSurface(S,loc)) {
788       const Handle(BRep_GCurve)& GC = *((Handle(BRep_GCurve)*)&cr);
789       GC->Range(First,Last);
790       if (GC->IsCurveOnClosedSurface() && Eisreversed)
791         return GC->PCurve2();
792       else
793         return GC->PCurve();
794     }
795     itcr.Next();
796   }
797
798   // for planar surface and 3d curve try a projection
799   // modif 21-05-97 : for RectangularTrimmedSurface, try a projection
800   Handle(Geom_Plane) GP;
801   Handle(Geom_RectangularTrimmedSurface) GRTS;
802   GRTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(S);
803   if(!GRTS.IsNull())
804     GP = Handle(Geom_Plane)::DownCast(GRTS->BasisSurface());
805   else
806     GP = Handle(Geom_Plane)::DownCast(S);
807   //fin modif du 21-05-97
808
809   if (!GP.IsNull()) {
810
811     Handle(GeomAdaptor_HCurve) HC;
812     Handle(GeomAdaptor_HSurface) HS;
813
814     HC = new GeomAdaptor_HCurve();
815     HS = new GeomAdaptor_HSurface();
816
817     TopLoc_Location LC;
818
819     Standard_Real f, l;// for those who call with (u,u).
820     Handle(Geom_Curve) C3d =
821       BRep_Tool::Curve(E,/*LC,*/f,l); // transforming plane instead of curve
822     // we can loose scale factor of Curve transformation (eap 13 May 2002)
823
824     LC = L/*.Predivided(LC)*/;
825
826     if (C3d.IsNull()) return nullPCurve;
827
828     Handle(Geom_Plane) Plane = GP;
829     if (!LC.IsIdentity()) {
830       const gp_Trsf& T = LC.Transformation();
831       Handle(Geom_Geometry) GPT = GP->Transformed(T);
832       Plane = *((Handle(Geom_Plane)*)&GPT);
833     }
834     GeomAdaptor_Surface& GAS = HS->ChangeSurface();
835     GAS.Load(Plane);
836     
837     Handle(Geom_Curve) ProjOnPlane = 
838       GeomProjLib::ProjectOnPlane(new Geom_TrimmedCurve(C3d,f,l),
839                                   Plane,
840                                   Plane->Position().Direction(),
841                                   Standard_True);
842     
843     GeomAdaptor_Curve& GAC = HC->ChangeCurve();
844     GAC.Load(ProjOnPlane);
845
846     ProjLib_ProjectedCurve Proj(HS,HC);
847     Handle(Geom2d_Curve) pc = Geom2dAdaptor::MakeCurve(Proj);
848
849     if (pc->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
850       Handle(Geom2d_TrimmedCurve) TC = 
851         (*((Handle(Geom2d_TrimmedCurve)*)&pc));
852       pc = TC->BasisCurve();
853     }
854     First = f; Last = l;
855     //
856     bToUpdate=Standard_True;
857     //
858     return pc;
859   }
860   
861   return nullPCurve;
862 }
863 //=======================================================================
864 //function : MaxToleranceEdge
865 //purpose  : 
866 //=======================================================================
867 Standard_Real MaxToleranceEdge (const TopoDS_Face& aF) 
868 {
869   Standard_Real aTol, aTolMax;
870   TopExp_Explorer aExp;
871   //
872   aTolMax=0.;
873   aExp.Init(aF, TopAbs_EDGE);
874   for (; aExp.More(); aExp.Next()) {
875     const TopoDS_Edge& aE=*((TopoDS_Edge *)&aExp.Current());
876     aTol=BRep_Tool::Tolerance(aE);
877     if (aTol>aTolMax) {
878       aTolMax=aTol;
879     }
880   }
881   return aTolMax;
882 }