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