0022792: Globally defined symbol PI conflicts with VTK definition (Intel compiler)
[occt.git] / src / BOPTools / BOPTools_Tools2D.cxx
1 // File:        BOPTools_Tools2D.cxx
2 // Created:     Mon Apr  2 12:29:22 2001
3 // Author:      Peter KURNEV
4 //              <pkv@irinox>
5
6
7 #include <BOPTools_Tools2D.ixx>
8
9 #include <Standard_NotImplemented.hxx>
10 #include <Precision.hxx>
11 #include <gp.hxx>
12
13 #include <gp_Pnt.hxx>
14 #include <gp_Pnt2d.hxx>
15 #include <gp_Vec.hxx>
16 #include <gp_Vec2d.hxx>
17
18 #include <Geom2d_Curve.hxx>
19 #include <Geom2d_Line.hxx>
20 #include <Geom2d_Circle.hxx>
21 #include <Geom2d_Ellipse.hxx>
22 #include <Geom2d_Parabola.hxx>
23 #include <Geom2d_Hyperbola.hxx>
24
25 #include <Geom_Curve.hxx>
26 #include <GeomAdaptor_HCurve.hxx>
27 #include <Geom_TrimmedCurve.hxx>
28 #include <Geom_Surface.hxx>
29
30 #include <TopLoc_Location.hxx>
31 #include <TopTools_IndexedMapOfShape.hxx>
32 #include <TopExp.hxx>
33
34 #include <ProjLib_ProjectedCurve.hxx>
35
36 #include <BRep_Tool.hxx>
37 #include <BRepTools.hxx>
38 #include <BRepAdaptor_HSurface.hxx>
39 #include <BRepAdaptor_Curve.hxx>
40 #include <BRep_Builder.hxx>
41 #include <BRepAdaptor_Surface.hxx>
42
43
44 static 
45   Standard_Boolean CheckEdgeLength (const TopoDS_Edge& E);
46
47 //=======================================================================
48 //function : EdgeTangent
49 //purpose  : 
50 //=======================================================================
51   Standard_Boolean BOPTools_Tools2D::EdgeTangent(const TopoDS_Edge& anEdge, 
52                                                  const Standard_Real aT,
53                                                  gp_Vec& aTau)
54 {
55   Standard_Boolean isdgE;
56   Standard_Real first, last;
57   
58   isdgE = BRep_Tool::Degenerated(anEdge); 
59   if (isdgE) {
60     return Standard_False;
61   }
62   if (!CheckEdgeLength(anEdge)) {
63     return Standard_False;
64   }
65
66   Handle(Geom_Curve) aC=BRep_Tool::Curve(anEdge, first, last);
67   gp_Pnt aP;
68   aC->D1(aT, aP, aTau);
69   Standard_Real mod = aTau.Magnitude();
70   if(mod > gp::Resolution()) {
71     aTau /= mod;
72   }
73   else {
74     return Standard_False;
75   }
76   //aTau.Normalize(); 
77   if (anEdge.Orientation() == TopAbs_REVERSED){
78     aTau.Reverse();
79   }
80   return Standard_True;
81 }
82
83
84 //=======================================================================
85 //function : FaceNormal
86 //purpose  : 
87 //=======================================================================
88   void BOPTools_Tools2D::FaceNormal (const TopoDS_Face& aF,
89                                      const Standard_Real U,
90                                      const Standard_Real V,
91                                      gp_Vec& aN)
92 {
93   gp_Pnt aPnt ;
94   gp_Vec aD1U, aD1V;
95   Handle(Geom_Surface) aSurface;
96
97   aSurface=BRep_Tool::Surface(aF);
98   aSurface->D1 (U, V, aPnt, aD1U, aD1V);
99   aN=aD1U.Crossed(aD1V);
100   aN.Normalize();  
101   if (aF.Orientation() == TopAbs_REVERSED){
102     aN.Reverse();
103   }
104   return;
105 }
106 //=======================================================================
107 //function : RemovePCurveForEdgeOnFace
108 //purpose  : 
109 //=======================================================================
110   void BOPTools_Tools2D::RemovePCurveForEdgeOnFace (const TopoDS_Edge& aE,
111                                                     const TopoDS_Face& aF)
112 {
113   BRep_Builder aBB;
114   Handle(Geom2d_Curve) aC2D;
115   Standard_Real  aTol;
116
117   aTol=BRep_Tool::Tolerance(aE);
118   aBB.UpdateEdge(aE, aC2D, aF, aTol);
119 }
120 //=======================================================================
121 //function : BuildPCurveForEdgeOnFace
122 //purpose  : 
123 //=======================================================================
124   void BOPTools_Tools2D::BuildPCurveForEdgeOnFace (const TopoDS_Edge& aE,
125                                                    const TopoDS_Face& aF)
126 {
127   BRep_Builder aBB;
128   Handle(Geom2d_Curve) aC2D;
129   Standard_Real  aTolPC, aTolFact, aTolEdge, aFirst, aLast;
130   
131   Standard_Boolean aHasOld;
132   aHasOld=BOPTools_Tools2D::HasCurveOnSurface (aE, aF, aC2D, aFirst, aLast, aTolEdge);
133   if (aHasOld) {
134     return;
135   }
136   
137
138   BOPTools_Tools2D::CurveOnSurface(aE, aF, aC2D, aTolPC, Standard_True);
139   
140   aTolEdge=BRep_Tool::Tolerance(aE);
141
142   aTolFact=Max(aTolEdge, aTolPC);
143
144   aBB.UpdateEdge(aE, aC2D, aF, aTolFact);
145   return;
146 }
147 //=======================================================================
148 //function : PointOnOnSurface
149 //purpose  : 
150 //=======================================================================
151   void BOPTools_Tools2D::PointOnSurface (const TopoDS_Edge& aE,
152                                          const TopoDS_Face& aF,
153                                          const Standard_Real aParameter,
154                                          Standard_Real& U,
155                                          Standard_Real& V)
156 {
157   gp_Pnt2d aP2D;
158   Handle(Geom2d_Curve) aC2D;
159   Standard_Real aToler, aFirst, aLast;
160
161   BOPTools_Tools2D::CurveOnSurface (aE, aF, aC2D, aFirst, aLast, aToler, Standard_True); 
162   aC2D->D0(aParameter, aP2D);
163   U=aP2D.X();
164   V=aP2D.Y();
165   return;
166 }
167
168 //=======================================================================
169 //function : CurveOnSurface
170 //purpose  : 
171 //=======================================================================
172   void BOPTools_Tools2D::CurveOnSurface (const TopoDS_Edge& aE,
173                                          const TopoDS_Face& aF,
174                                          Handle(Geom2d_Curve)& aC2D,
175                                          Standard_Real& aToler,
176                                          const Standard_Boolean trim3d)
177 {
178   Standard_Real aFirst, aLast; 
179
180   BOPTools_Tools2D::CurveOnSurface (aE, aF, aC2D, aFirst, aLast, aToler, trim3d); 
181
182   return;
183 }
184 //=======================================================================
185 //function : CurveOnSurface
186 //purpose  : 
187 //=======================================================================
188   void BOPTools_Tools2D::CurveOnSurface (const TopoDS_Edge& aE,
189                                          const TopoDS_Face& aF,
190                                          Handle(Geom2d_Curve)& aC2D,
191                                          Standard_Real& aFirst,
192                                          Standard_Real& aLast,
193                                          Standard_Real& aToler,
194                                          const Standard_Boolean trim3d)
195 {
196   Standard_Boolean aHasOld;
197   Handle(Geom2d_Curve) C2D;
198
199   aHasOld=BOPTools_Tools2D::HasCurveOnSurface (aE, aF, C2D, aFirst, aLast, aToler);
200   if (aHasOld) {
201     aC2D=C2D;
202     return;
203   }
204
205   BOPTools_Tools2D::Make2D(aE, aF, C2D, aFirst, aLast, aToler, trim3d);
206   aC2D=C2D;
207   return;
208 }
209
210 //=======================================================================
211 //function : HasCurveOnSurface
212 //purpose  : 
213 //=======================================================================
214   Standard_Boolean BOPTools_Tools2D::HasCurveOnSurface (const TopoDS_Edge& aE,
215                                                         const TopoDS_Face& aF,
216                                                         Handle(Geom2d_Curve)& aC2D,
217                                                         Standard_Real& aFirst,
218                                                         Standard_Real& aLast,
219                                                         Standard_Real& aToler)
220 {
221   Standard_Boolean aHasOld;
222   
223   aToler=BRep_Tool::Tolerance(aE);
224   BRep_Tool::Range(aE, aFirst, aLast);
225
226   if((aLast - aFirst) < Precision::PConfusion()) {
227     return Standard_False;
228   }
229
230   aC2D  =BRep_Tool::CurveOnSurface(aE, aF, aFirst, aLast);
231   aHasOld=!aC2D.IsNull();
232   return aHasOld;
233 }
234 //=======================================================================
235 //function : HasCurveOnSurface
236 //purpose  : 
237 //=======================================================================
238   Standard_Boolean BOPTools_Tools2D::HasCurveOnSurface (const TopoDS_Edge& aE,
239                                                         const TopoDS_Face& aF)
240                                                    
241 {
242   Standard_Boolean aHasOld;
243   Handle(Geom2d_Curve) aC2D;
244   Standard_Real aFirst, aLast;
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 : MakeCurveOnSurface
257 //purpose  : 
258 //=======================================================================
259   void BOPTools_Tools2D::MakeCurveOnSurface (const TopoDS_Edge& aE,
260                                              const TopoDS_Face& aF,
261                                              Handle(Geom2d_Curve)& aC2D,
262                                              Standard_Real& aFirst,
263                                              Standard_Real& aLast,
264                                              Standard_Real& aToler,
265                                              const Standard_Boolean trim3d)
266 {
267   BOPTools_Tools2D::Make2D(aE, aF, aC2D, aFirst, aLast, aToler, trim3d);
268 }
269
270 //=======================================================================
271 //function : Make2D
272 //purpose  : 
273 //=======================================================================
274   void BOPTools_Tools2D::Make2D (const TopoDS_Edge& aE,
275                                  const TopoDS_Face& aF,
276                                  Handle(Geom2d_Curve)& aC2D,
277                                  Standard_Real& aFirst,
278                                  Standard_Real& aLast,
279                                  Standard_Real& aToler,
280                                  const Standard_Boolean trim3d)
281 {
282   Standard_Boolean aLocIdentity;
283   Standard_Real f3d, l3d;
284   TopLoc_Location aLoc;
285
286   Handle(Geom2d_Curve) C2D; 
287   
288   
289   C2D=BRep_Tool::CurveOnSurface(aE, aF, aFirst, aLast);
290   
291   if (!C2D.IsNull()) {
292     aC2D=C2D;
293     return;
294   }
295
296   Handle(Geom_Curve) C3D3, C3D2, C3D;
297   C3D = BRep_Tool::Curve(aE, aLoc, f3d, l3d);
298   //
299   if (C3D.IsNull()) { 
300     // aE has no 3D curve, so nothing is done
301   }
302   //
303   aLocIdentity=aLoc.IsIdentity();
304     
305   if (aLocIdentity) {
306     C3D2 = C3D;
307   }
308   else {
309     C3D2 = Handle(Geom_Curve)::
310       DownCast(C3D->Transformed(aLoc.Transformation()));
311   }
312   
313   if (trim3d) {
314     
315     C3D3=C3D2;
316   }
317   
318   else {
319     C3D3=C3D2;
320   }
321   //
322   aToler=.5*BRep_Tool::Tolerance(aE);
323   BOPTools_Tools2D::MakePCurveOnFace(aF, C3D3, f3d, l3d, aC2D, aToler);
324   //
325   aFirst = f3d; 
326   aLast  = l3d;
327 }
328
329 //=======================================================================
330 //function : MakePCurveOnFace
331 //purpose  : 
332 //=======================================================================
333   void BOPTools_Tools2D::MakePCurveOnFace (const TopoDS_Face& aF,
334                                            const Handle(Geom_Curve)& aC3D,
335                                            Handle(Geom2d_Curve)& aC2D, //->
336                                            Standard_Real& TolReached2d)
337 {
338   Standard_Real aFirst, aLast;
339
340   aFirst = aC3D -> FirstParameter();
341   aLast  = aC3D -> LastParameter();
342   //
343   TolReached2d=0.;
344   //
345   BOPTools_Tools2D::MakePCurveOnFace (aF, aC3D, aFirst, aLast, aC2D, TolReached2d);
346 }
347
348 //=======================================================================
349 //function : MakePCurveOnFace
350 //purpose  : 
351 //=======================================================================
352   void BOPTools_Tools2D::MakePCurveOnFace (const TopoDS_Face& aF,
353                                            const Handle(Geom_Curve)& aC3D,
354                                            const Standard_Real aFirst,
355                                            const Standard_Real aLast,
356                                            Handle(Geom2d_Curve)& aC2D, 
357                                            Standard_Real& TolReached2d)
358 {
359   Standard_Real aTolR;
360   Handle(Geom2d_Curve) aC2DA;
361
362   BRepAdaptor_Surface aBAS(aF, Standard_False);
363   Handle(BRepAdaptor_HSurface) aBAHS = new BRepAdaptor_HSurface(aBAS);
364   Handle(GeomAdaptor_HCurve)   aBAHC = new GeomAdaptor_HCurve(aC3D, aFirst, aLast);
365   
366   ProjLib_ProjectedCurve aProjCurv(aBAHS, aBAHC);// 1
367   BOPTools_Tools2D::MakePCurveOfType(aProjCurv, aC2D);
368   aTolR=aProjCurv.GetTolerance();
369   //
370   if (aC2D.IsNull()) { 
371     ProjLib_ProjectedCurve aProjCurvAgain(aBAHS, aBAHC, TolReached2d);// 2
372     BOPTools_Tools2D::MakePCurveOfType(aProjCurvAgain, aC2D);
373     aTolR = aProjCurvAgain.GetTolerance();
374     //
375     if (aC2D.IsNull()) { 
376       Standard_Real aTR=0.0001;
377       ProjLib_ProjectedCurve aProj3(aBAHS, aBAHC, aTR);// 3
378       BOPTools_Tools2D::MakePCurveOfType(aProj3, aC2D);
379       aTolR = aProj3.GetTolerance();
380     }
381   }
382   TolReached2d=aTolR;
383   
384   BOPTools_Tools2D::AdjustPCurveOnFace (aF, aFirst, aLast, aC2D, aC2DA);
385   aC2D=aC2DA;
386 }
387
388 //=======================================================================
389 //function : AdjustPCurveOnFace
390 //purpose  : 
391 //=======================================================================
392   void BOPTools_Tools2D::AdjustPCurveOnFace (const TopoDS_Face& aF,
393                                              const Handle(Geom_Curve)&   aC3D,
394                                              const Handle(Geom2d_Curve)& aC2D, 
395                                              Handle(Geom2d_Curve)& aC2DA)
396 {
397   Standard_Real first, last;
398
399   first = aC3D -> FirstParameter();
400   last  = aC3D -> LastParameter();
401  
402   BOPTools_Tools2D::AdjustPCurveOnFace (aF, first, last, aC2D, aC2DA);
403
404 //=======================================================================
405 //function : AdjustPCurveOnFace
406 //purpose  : 
407 //=======================================================================
408   void BOPTools_Tools2D::AdjustPCurveOnFace (const TopoDS_Face& aF,
409                                              const Standard_Real aFirst,
410                                              const Standard_Real aLast,
411                                              const Handle(Geom2d_Curve)& aC2D, 
412                                              Handle(Geom2d_Curve)& aC2DA)
413 {
414   Standard_Boolean mincond, maxcond, decalu, decalv;
415   Standard_Integer k, iCnt;
416   Standard_Real UMin, UMax, VMin, VMax, aT, u2, v2, du, dv, aDelta;
417   Standard_Real aUPeriod, aUP2, aUP1, aUNew, aDif, aUx;
418   //
419   aDelta=Precision::PConfusion();
420   
421   BRepAdaptor_Surface aBAS(aF, Standard_False);
422  
423   BRepTools::UVBounds(aF, UMin, UMax, VMin, VMax);
424   
425   aT =.5*(aFirst+aLast);
426
427   gp_Pnt2d pC2D; 
428   aC2D->D0(aT, pC2D);
429
430   u2 = pC2D.X();
431   v2 = pC2D.Y();
432  
433   du = 0.;
434   if (aBAS.IsUPeriodic()) {
435     aUPeriod=aBAS.UPeriod(); 
436     mincond = (u2 < UMin-aDelta);
437     maxcond = (u2 > UMax+aDelta); 
438     
439     decalu = mincond || maxcond;
440     if (decalu) {
441       //modified by NIZNHY-PKV Mon Mar 25 16:44:46 2008f
442       //du = ( mincond ) ? UPeriod : -UPeriod;
443       //
444       iCnt=1;
445       aUP2=aUPeriod+aUPeriod+aDelta;
446       aUP1=aUPeriod+aDelta;
447       //
448       if (u2 > aUP2) {
449         for(k=1; 1; ++k) {
450           aUx=u2-k*aUPeriod;
451           if (aUx < aUP1) {
452             iCnt=k;
453             break;
454           }
455         }
456       }
457       else if (u2 < -aUP2) {
458         for(k=1; 1; ++k) {
459           aUx=u2+k*aUPeriod;
460           if (aUx > -aUP1) {
461             iCnt=k;
462             break;
463           }
464         }
465       }
466       du = ( mincond ) ? aUPeriod : -aUPeriod;
467       du=iCnt*du;
468       //modified by NIZNHY-PKV Mon Mar 25 16:44:49 2008t
469     }
470     //
471     aUNew=u2+du;
472     if (aUNew<(UMin-aDelta) || 
473         aUNew>(UMax+aDelta)) {
474       // So previous correction was wrong.
475       // Try to be closer to UMin or UMax.
476       du=0.;
477       if (u2>UMax){
478         aDif=u2-UMax;
479         if (aDif < 4.e-7) {
480           du=-aDif;
481         }
482       }
483     }
484   } // if (BAHS->IsUPeriodic())
485   //
486   // dv
487   dv = 0.;
488   if (aBAS.IsVPeriodic()) {
489     Standard_Real aVPeriod, aVm, aVr, aVmid, dVm, dVr;
490     //
491     aVPeriod=aBAS.VPeriod();
492     mincond = (VMin - v2 > aDelta);
493     maxcond = (v2 - VMax > aDelta);
494     decalv = mincond || maxcond;
495     if (decalv) {
496       dv = ( mincond ) ? aVPeriod : -aVPeriod;
497     }
498     //
499     //xf
500     if ((VMax-VMin<aVPeriod) && dv) {
501       aVm=v2;
502       aVr=v2+dv;
503       aVmid=0.5*(VMin+VMax);
504       dVm=fabs(aVm-aVmid);
505       dVr=fabs(aVr-aVmid);
506       if (dVm<dVr) {
507         dv=0.;
508       }
509     }
510     //xt
511   }
512   //
513   // Translation if necessary
514   Handle(Geom2d_Curve) aC2Dx=aC2D;
515
516   if ( du != 0. || dv != 0.) {
517     Handle(Geom2d_Curve) PCT = Handle(Geom2d_Curve)::DownCast(aC2Dx->Copy());
518     gp_Vec2d aV2D(du,dv);
519     PCT->Translate(aV2D);
520     aC2Dx = PCT;
521   }
522
523   aC2DA=aC2Dx;
524 }
525
526
527 //=======================================================================
528 //function : MakePCurveOfType
529 //purpose  : 
530 //=======================================================================
531   void  BOPTools_Tools2D::MakePCurveOfType(const ProjLib_ProjectedCurve& PC, 
532                                            Handle(Geom2d_Curve)& C2D)
533 {
534   
535   switch (PC.GetType()) {
536
537   case GeomAbs_Line : 
538     C2D = new Geom2d_Line(PC.Line()); 
539     break;
540   case GeomAbs_Circle : 
541     C2D = new Geom2d_Circle(PC.Circle());
542     break;
543   case GeomAbs_Ellipse :
544     C2D = new Geom2d_Ellipse(PC.Ellipse());
545     break;
546   case GeomAbs_Parabola : 
547     C2D = new Geom2d_Parabola(PC.Parabola()); 
548     break;
549   case GeomAbs_Hyperbola : 
550     C2D = new Geom2d_Hyperbola(PC.Hyperbola()); 
551     break;
552   case GeomAbs_BSplineCurve :
553     C2D = PC.BSpline(); 
554     break;
555   case GeomAbs_BezierCurve : 
556   case GeomAbs_OtherCurve : 
557     default :
558     Standard_NotImplemented::Raise("BOPTools_Tools2D::MakePCurveOfType");
559     break;
560   }
561 }
562
563 //=======================================================================
564 //function : TangentOnEdge
565 //purpose  : 
566 //=======================================================================
567   Standard_Boolean BOPTools_Tools2D::TangentOnEdge(const Standard_Real par, 
568                                                    const TopoDS_Edge& E, 
569                                                    gp_Vec& Tg)
570 {
571   Standard_Boolean isdgE;
572   
573   isdgE = BRep_Tool::Degenerated(E); 
574   if (isdgE) {
575     return Standard_False;
576   }
577   if (!CheckEdgeLength(E)) {
578     return Standard_False;
579   }
580
581   BRepAdaptor_Curve BC(E);
582   //
583   // Body 
584   Standard_Real f, l, tolE, tolp;
585   Standard_Boolean onf, onl, inbounds;
586
587   f = BC.FirstParameter();
588   l = BC.LastParameter();
589   tolE = BC.Tolerance(); 
590   tolp = BC.Resolution(tolE);
591   
592   onf = Abs(f-par)<tolp; 
593   onl = Abs(l-par)<tolp; 
594   inbounds = (f<par) && (par<l);
595
596   if ((!inbounds) && (!onf) && (!onl)) {
597     return Standard_False;
598   }
599   
600   
601   gp_Pnt aP;
602
603   BC.D1(par, aP, Tg);
604   Tg.Normalize(); 
605   
606   return Standard_True;
607 }
608 //=======================================================================
609 //function : TangentOnEdge
610 //purpose  : 
611 //=======================================================================
612   Standard_Boolean BOPTools_Tools2D::TangentOnEdge(const TopoDS_Edge& aE, 
613                                                    gp_Dir& DTg)
614 {
615   Standard_Real aT;
616   gp_Vec aTg;
617
618   DTg.SetCoord(1.,0.,0.);
619
620   aT= BOPTools_Tools2D::IntermediatePoint (aE);
621   Standard_Boolean bIsFound=BOPTools_Tools2D::TangentOnEdge(aT, aE, aTg);
622   if (bIsFound) {
623     gp_Dir aDTmp(aTg);
624     DTg=aDTmp;
625   }
626   return bIsFound;
627 }
628   
629 //=======================================================================
630 //function : TangentOnVertex
631 //purpose  : 
632 //=======================================================================
633   Standard_Boolean BOPTools_Tools2D::TangentOnVertex (const TopoDS_Vertex& v, 
634                                                       const TopoDS_Vertex& vl, 
635                                                       const TopoDS_Edge& e,
636                                                       gp_Vec& aVec)
637 // tg oriented INSIDE 1d(e)
638 // vl : last vertex of e
639 {
640   Standard_Boolean ok;
641   Standard_Real par;
642   gp_Vec tg; 
643
644   par = BRep_Tool::Parameter(v, e);  
645   ok =BOPTools_Tools2D::TangentOnEdge (par, e, tg);
646   if (!ok) {
647     return ok;
648   }
649   if (v.IsSame(vl)) {
650     tg.Reverse();
651   }
652   aVec=tg;
653
654   return ok;
655 }
656
657 //=======================================================================
658 //function : EdgeBounds
659 //purpose  : 
660 //=======================================================================
661   void BOPTools_Tools2D::EdgeBounds (const TopoDS_Edge& aE,
662                                      Standard_Real& aFirst,
663                                      Standard_Real& aLast)
664 {
665   BRepAdaptor_Curve aBC(aE);
666   aFirst= aBC.FirstParameter();
667   aLast = aBC.LastParameter();
668 }
669
670 //=======================================================================
671 //function : IntermediatePoint
672 //purpose  : 
673 //=======================================================================
674   Standard_Real BOPTools_Tools2D::IntermediatePoint (const Standard_Real aFirst,
675                                                      const Standard_Real aLast)
676 {
677   //define parameter division number as 10*e^(-M_PI) = 0.43213918
678   const Standard_Real PAR_T = 0.43213918;
679   Standard_Real aParm;
680   aParm=(1.-PAR_T)*aFirst + PAR_T*aLast;
681   return aParm;
682 }
683 //=======================================================================
684 //function : IntermediatePoint
685 //purpose  : 
686 //=======================================================================
687   Standard_Real BOPTools_Tools2D::IntermediatePoint (const TopoDS_Edge& aE)
688                                                 
689 {
690   Standard_Real aT, aT1, aT2;
691
692   Handle(Geom_Curve)aC1=BRep_Tool::Curve(aE, aT1, aT2);
693   aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
694   return aT;
695 }
696
697 //=======================================================================
698 //function : CheckEdgeLength
699 //purpose  : 
700 //=======================================================================
701 Standard_Boolean CheckEdgeLength (const TopoDS_Edge& E)
702 {
703   BRepAdaptor_Curve BC(E);
704
705   TopTools_IndexedMapOfShape aM;
706   TopExp::MapShapes(E, TopAbs_VERTEX, aM);
707   Standard_Integer i, anExtent, aN=10;
708   Standard_Real ln=0., d, t, f, l, dt; 
709   anExtent=aM.Extent();
710
711   if (anExtent!=1) 
712     return Standard_True;
713     
714   gp_Pnt p1, p2;
715   f = BC.FirstParameter();
716   l = BC.LastParameter();
717   dt=(l-f)/aN;
718   
719   BC.D0(f, p1);
720   for (i=1; i<=aN; i++) {
721     t=f+i*dt;
722     
723     if (i==aN) 
724       BC.D0(l, p2);
725       else 
726         BC.D0(t, p2);
727     
728     d=p1.Distance(p2);
729     ln+=d;
730     p1=p2;
731   }
732   
733   return (ln > Precision::Confusion()); 
734 }