0023100: Wrong adjustment of p-curves on a cylinder
[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       iCnt=1;
457       aUP2=aUPeriod+aUPeriod+aDelta;
458       aUP1=aUPeriod+aDelta;
459       //
460       if (u2 > aUP2) {
461         for(k=1; 1; ++k) {
462           aUx=u2-k*aUPeriod;
463           if (aUx < aUP1) {
464             iCnt=k;
465             break;
466           }
467         }
468       }
469       else if (u2 < -aUP2) {
470         for(k=1; 1; ++k) {
471           aUx=u2+k*aUPeriod;
472           if (aUx > -aUP1) {
473             //modified by NIZNHY-PKV Thu Apr 12 08:12:09 2012f
474             iCnt=k+1;
475             //iCnt=k;
476             //modified by NIZNHY-PKV Thu Apr 12 08:12:11 2012t
477             break;
478           }
479         }
480       }
481       du = ( mincond ) ? aUPeriod : -aUPeriod;
482       du=iCnt*du;
483     }
484     //
485     aUNew=u2+du;
486     if (aUNew<(UMin-aDelta) || 
487         aUNew>(UMax+aDelta)) {
488       // So previous correction was wrong.
489       // Try to be closer to UMin or UMax.
490       du=0.;
491       if (u2>UMax){
492         aDif=u2-UMax;
493         if (aDif < 4.e-7) {
494           du=-aDif;
495         }
496       }
497     }
498   } // if (BAHS->IsUPeriodic())
499   //
500   // dv
501   dv = 0.;
502   if (aBAS.IsVPeriodic()) {
503     Standard_Real aVPeriod, aVm, aVr, aVmid, dVm, dVr;
504     //
505     aVPeriod=aBAS.VPeriod();
506     mincond = (VMin - v2 > aDelta);
507     maxcond = (v2 - VMax > aDelta);
508     decalv = mincond || maxcond;
509     if (decalv) {
510       dv = ( mincond ) ? aVPeriod : -aVPeriod;
511     }
512     //
513     //xf
514     if ((VMax-VMin<aVPeriod) && dv) {
515       aVm=v2;
516       aVr=v2+dv;
517       aVmid=0.5*(VMin+VMax);
518       dVm=fabs(aVm-aVmid);
519       dVr=fabs(aVr-aVmid);
520       if (dVm<dVr) {
521         dv=0.;
522       }
523     }
524     //xt
525   }
526   //
527   // Translation if necessary
528   Handle(Geom2d_Curve) aC2Dx=aC2D;
529
530   if ( du != 0. || dv != 0.) {
531     Handle(Geom2d_Curve) PCT = Handle(Geom2d_Curve)::DownCast(aC2Dx->Copy());
532     gp_Vec2d aV2D(du,dv);
533     PCT->Translate(aV2D);
534     aC2Dx = PCT;
535   }
536
537   aC2DA=aC2Dx;
538 }
539
540
541 //=======================================================================
542 //function : MakePCurveOfType
543 //purpose  : 
544 //=======================================================================
545   void  BOPTools_Tools2D::MakePCurveOfType(const ProjLib_ProjectedCurve& PC, 
546                                            Handle(Geom2d_Curve)& C2D)
547 {
548   
549   switch (PC.GetType()) {
550
551   case GeomAbs_Line : 
552     C2D = new Geom2d_Line(PC.Line()); 
553     break;
554   case GeomAbs_Circle : 
555     C2D = new Geom2d_Circle(PC.Circle());
556     break;
557   case GeomAbs_Ellipse :
558     C2D = new Geom2d_Ellipse(PC.Ellipse());
559     break;
560   case GeomAbs_Parabola : 
561     C2D = new Geom2d_Parabola(PC.Parabola()); 
562     break;
563   case GeomAbs_Hyperbola : 
564     C2D = new Geom2d_Hyperbola(PC.Hyperbola()); 
565     break;
566   case GeomAbs_BSplineCurve :
567     C2D = PC.BSpline(); 
568     break;
569   case GeomAbs_BezierCurve : 
570   case GeomAbs_OtherCurve : 
571     default :
572     Standard_NotImplemented::Raise("BOPTools_Tools2D::MakePCurveOfType");
573     break;
574   }
575 }
576
577 //=======================================================================
578 //function : TangentOnEdge
579 //purpose  : 
580 //=======================================================================
581   Standard_Boolean BOPTools_Tools2D::TangentOnEdge(const Standard_Real par, 
582                                                    const TopoDS_Edge& E, 
583                                                    gp_Vec& Tg)
584 {
585   Standard_Boolean isdgE;
586   
587   isdgE = BRep_Tool::Degenerated(E); 
588   if (isdgE) {
589     return Standard_False;
590   }
591   if (!CheckEdgeLength(E)) {
592     return Standard_False;
593   }
594
595   BRepAdaptor_Curve BC(E);
596   //
597   // Body 
598   Standard_Real f, l, tolE, tolp;
599   Standard_Boolean onf, onl, inbounds;
600
601   f = BC.FirstParameter();
602   l = BC.LastParameter();
603   tolE = BC.Tolerance(); 
604   tolp = BC.Resolution(tolE);
605   
606   onf = Abs(f-par)<tolp; 
607   onl = Abs(l-par)<tolp; 
608   inbounds = (f<par) && (par<l);
609
610   if ((!inbounds) && (!onf) && (!onl)) {
611     return Standard_False;
612   }
613   
614   
615   gp_Pnt aP;
616
617   BC.D1(par, aP, Tg);
618   Tg.Normalize(); 
619   
620   return Standard_True;
621 }
622 //=======================================================================
623 //function : TangentOnEdge
624 //purpose  : 
625 //=======================================================================
626   Standard_Boolean BOPTools_Tools2D::TangentOnEdge(const TopoDS_Edge& aE, 
627                                                    gp_Dir& DTg)
628 {
629   Standard_Real aT;
630   gp_Vec aTg;
631
632   DTg.SetCoord(1.,0.,0.);
633
634   aT= BOPTools_Tools2D::IntermediatePoint (aE);
635   Standard_Boolean bIsFound=BOPTools_Tools2D::TangentOnEdge(aT, aE, aTg);
636   if (bIsFound) {
637     gp_Dir aDTmp(aTg);
638     DTg=aDTmp;
639   }
640   return bIsFound;
641 }
642   
643 //=======================================================================
644 //function : TangentOnVertex
645 //purpose  : 
646 //=======================================================================
647   Standard_Boolean BOPTools_Tools2D::TangentOnVertex (const TopoDS_Vertex& v, 
648                                                       const TopoDS_Vertex& vl, 
649                                                       const TopoDS_Edge& e,
650                                                       gp_Vec& aVec)
651 // tg oriented INSIDE 1d(e)
652 // vl : last vertex of e
653 {
654   Standard_Boolean ok;
655   Standard_Real par;
656   gp_Vec tg; 
657
658   par = BRep_Tool::Parameter(v, e);  
659   ok =BOPTools_Tools2D::TangentOnEdge (par, e, tg);
660   if (!ok) {
661     return ok;
662   }
663   if (v.IsSame(vl)) {
664     tg.Reverse();
665   }
666   aVec=tg;
667
668   return ok;
669 }
670
671 //=======================================================================
672 //function : EdgeBounds
673 //purpose  : 
674 //=======================================================================
675   void BOPTools_Tools2D::EdgeBounds (const TopoDS_Edge& aE,
676                                      Standard_Real& aFirst,
677                                      Standard_Real& aLast)
678 {
679   BRepAdaptor_Curve aBC(aE);
680   aFirst= aBC.FirstParameter();
681   aLast = aBC.LastParameter();
682 }
683
684 //=======================================================================
685 //function : IntermediatePoint
686 //purpose  : 
687 //=======================================================================
688   Standard_Real BOPTools_Tools2D::IntermediatePoint (const Standard_Real aFirst,
689                                                      const Standard_Real aLast)
690 {
691   //define parameter division number as 10*e^(-M_PI) = 0.43213918
692   const Standard_Real PAR_T = 0.43213918;
693   Standard_Real aParm;
694   aParm=(1.-PAR_T)*aFirst + PAR_T*aLast;
695   return aParm;
696 }
697 //=======================================================================
698 //function : IntermediatePoint
699 //purpose  : 
700 //=======================================================================
701   Standard_Real BOPTools_Tools2D::IntermediatePoint (const TopoDS_Edge& aE)
702                                                 
703 {
704   Standard_Real aT, aT1, aT2;
705
706   Handle(Geom_Curve)aC1=BRep_Tool::Curve(aE, aT1, aT2);
707   aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
708   return aT;
709 }
710
711 //=======================================================================
712 //function : CheckEdgeLength
713 //purpose  : 
714 //=======================================================================
715 Standard_Boolean CheckEdgeLength (const TopoDS_Edge& E)
716 {
717   BRepAdaptor_Curve BC(E);
718
719   TopTools_IndexedMapOfShape aM;
720   TopExp::MapShapes(E, TopAbs_VERTEX, aM);
721   Standard_Integer i, anExtent, aN=10;
722   Standard_Real ln=0., d, t, f, l, dt; 
723   anExtent=aM.Extent();
724
725   if (anExtent!=1) 
726     return Standard_True;
727     
728   gp_Pnt p1, p2;
729   f = BC.FirstParameter();
730   l = BC.LastParameter();
731   dt=(l-f)/aN;
732   
733   BC.D0(f, p1);
734   for (i=1; i<=aN; i++) {
735     t=f+i*dt;
736     
737     if (i==aN) 
738       BC.D0(l, p2);
739       else 
740         BC.D0(t, p2);
741     
742     d=p1.Distance(p2);
743     ln+=d;
744     p1=p2;
745   }
746   
747   return (ln > Precision::Confusion()); 
748 }