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