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