1 // File: BOPTools_Tools2D.cxx
2 // Created: Mon Apr 2 12:29:22 2001
3 // Author: Peter KURNEV
7 #include <BOPTools_Tools2D.ixx>
9 #include <Standard_NotImplemented.hxx>
10 #include <Precision.hxx>
14 #include <gp_Pnt2d.hxx>
16 #include <gp_Vec2d.hxx>
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>
25 #include <Geom_Curve.hxx>
26 #include <GeomAdaptor_HCurve.hxx>
27 #include <Geom_TrimmedCurve.hxx>
28 #include <Geom_Surface.hxx>
30 #include <TopLoc_Location.hxx>
31 #include <TopTools_IndexedMapOfShape.hxx>
34 #include <ProjLib_ProjectedCurve.hxx>
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>
45 Standard_Boolean CheckEdgeLength (const TopoDS_Edge& E);
47 //=======================================================================
48 //function : EdgeTangent
50 //=======================================================================
51 Standard_Boolean BOPTools_Tools2D::EdgeTangent(const TopoDS_Edge& anEdge,
52 const Standard_Real aT,
55 Standard_Boolean isdgE;
56 Standard_Real first, last;
58 isdgE = BRep_Tool::Degenerated(anEdge);
60 return Standard_False;
62 if (!CheckEdgeLength(anEdge)) {
63 return Standard_False;
66 Handle(Geom_Curve) aC=BRep_Tool::Curve(anEdge, first, last);
69 Standard_Real mod = aTau.Magnitude();
70 if(mod > gp::Resolution()) {
74 return Standard_False;
77 if (anEdge.Orientation() == TopAbs_REVERSED){
84 //=======================================================================
85 //function : FaceNormal
87 //=======================================================================
88 void BOPTools_Tools2D::FaceNormal (const TopoDS_Face& aF,
89 const Standard_Real U,
90 const Standard_Real V,
95 Handle(Geom_Surface) aSurface;
97 aSurface=BRep_Tool::Surface(aF);
98 aSurface->D1 (U, V, aPnt, aD1U, aD1V);
99 aN=aD1U.Crossed(aD1V);
101 if (aF.Orientation() == TopAbs_REVERSED){
106 //=======================================================================
107 //function : RemovePCurveForEdgeOnFace
109 //=======================================================================
110 void BOPTools_Tools2D::RemovePCurveForEdgeOnFace (const TopoDS_Edge& aE,
111 const TopoDS_Face& aF)
114 Handle(Geom2d_Curve) aC2D;
117 aTol=BRep_Tool::Tolerance(aE);
118 aBB.UpdateEdge(aE, aC2D, aF, aTol);
120 //=======================================================================
121 //function : BuildPCurveForEdgeOnFace
123 //=======================================================================
124 void BOPTools_Tools2D::BuildPCurveForEdgeOnFace (const TopoDS_Edge& aE,
125 const TopoDS_Face& aF)
128 Handle(Geom2d_Curve) aC2D;
129 Standard_Real aTolPC, aTolFact, aTolEdge, aFirst, aLast;
131 Standard_Boolean aHasOld;
132 aHasOld=BOPTools_Tools2D::HasCurveOnSurface (aE, aF, aC2D, aFirst, aLast, aTolEdge);
138 BOPTools_Tools2D::CurveOnSurface(aE, aF, aC2D, aTolPC, Standard_True);
140 aTolEdge=BRep_Tool::Tolerance(aE);
142 aTolFact=Max(aTolEdge, aTolPC);
144 aBB.UpdateEdge(aE, aC2D, aF, aTolFact);
147 //=======================================================================
148 //function : PointOnOnSurface
150 //=======================================================================
151 void BOPTools_Tools2D::PointOnSurface (const TopoDS_Edge& aE,
152 const TopoDS_Face& aF,
153 const Standard_Real aParameter,
158 Handle(Geom2d_Curve) aC2D;
159 Standard_Real aToler, aFirst, aLast;
161 BOPTools_Tools2D::CurveOnSurface (aE, aF, aC2D, aFirst, aLast, aToler, Standard_True);
162 aC2D->D0(aParameter, aP2D);
168 //=======================================================================
169 //function : CurveOnSurface
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)
178 Standard_Real aFirst, aLast;
180 BOPTools_Tools2D::CurveOnSurface (aE, aF, aC2D, aFirst, aLast, aToler, trim3d);
184 //=======================================================================
185 //function : CurveOnSurface
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)
196 Standard_Boolean aHasOld;
197 Handle(Geom2d_Curve) C2D;
199 aHasOld=BOPTools_Tools2D::HasCurveOnSurface (aE, aF, C2D, aFirst, aLast, aToler);
205 BOPTools_Tools2D::Make2D(aE, aF, C2D, aFirst, aLast, aToler, trim3d);
210 //=======================================================================
211 //function : HasCurveOnSurface
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)
221 Standard_Boolean aHasOld;
223 aToler=BRep_Tool::Tolerance(aE);
224 BRep_Tool::Range(aE, aFirst, aLast);
226 if((aLast - aFirst) < Precision::PConfusion()) {
227 return Standard_False;
230 aC2D =BRep_Tool::CurveOnSurface(aE, aF, aFirst, aLast);
231 aHasOld=!aC2D.IsNull();
234 //=======================================================================
235 //function : HasCurveOnSurface
237 //=======================================================================
238 Standard_Boolean BOPTools_Tools2D::HasCurveOnSurface (const TopoDS_Edge& aE,
239 const TopoDS_Face& aF)
242 Standard_Boolean aHasOld;
243 Handle(Geom2d_Curve) aC2D;
244 Standard_Real aFirst, aLast;
245 BRep_Tool::Range(aE, aFirst, aLast);
247 if((aLast - aFirst) < Precision::PConfusion()) {
248 return Standard_False;
251 aC2D =BRep_Tool::CurveOnSurface(aE, aF, aFirst, aLast);
252 aHasOld=!aC2D.IsNull();
255 //=======================================================================
256 //function : MakeCurveOnSurface
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)
267 BOPTools_Tools2D::Make2D(aE, aF, aC2D, aFirst, aLast, aToler, trim3d);
270 //=======================================================================
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)
282 Standard_Boolean aLocIdentity;
283 Standard_Real f3d, l3d;
284 TopLoc_Location aLoc;
286 Handle(Geom2d_Curve) C2D;
289 C2D=BRep_Tool::CurveOnSurface(aE, aF, aFirst, aLast);
296 Handle(Geom_Curve) C3D3, C3D2, C3D;
297 C3D = BRep_Tool::Curve(aE, aLoc, f3d, l3d);
300 // aE has no 3D curve, so nothing is done
303 aLocIdentity=aLoc.IsIdentity();
309 C3D2 = Handle(Geom_Curve)::
310 DownCast(C3D->Transformed(aLoc.Transformation()));
322 aToler=.5*BRep_Tool::Tolerance(aE);
323 BOPTools_Tools2D::MakePCurveOnFace(aF, C3D3, f3d, l3d, aC2D, aToler);
329 //=======================================================================
330 //function : MakePCurveOnFace
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)
338 Standard_Real aFirst, aLast;
340 aFirst = aC3D -> FirstParameter();
341 aLast = aC3D -> LastParameter();
345 BOPTools_Tools2D::MakePCurveOnFace (aF, aC3D, aFirst, aLast, aC2D, TolReached2d);
348 //=======================================================================
349 //function : MakePCurveOnFace
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)
360 Handle(Geom2d_Curve) aC2DA;
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);
366 ProjLib_ProjectedCurve aProjCurv(aBAHS, aBAHC);// 1
367 BOPTools_Tools2D::MakePCurveOfType(aProjCurv, aC2D);
368 aTolR=aProjCurv.GetTolerance();
371 ProjLib_ProjectedCurve aProjCurvAgain(aBAHS, aBAHC, TolReached2d);// 2
372 BOPTools_Tools2D::MakePCurveOfType(aProjCurvAgain, aC2D);
373 aTolR = aProjCurvAgain.GetTolerance();
376 Standard_Real aTR=0.0001;
377 ProjLib_ProjectedCurve aProj3(aBAHS, aBAHC, aTR);// 3
378 BOPTools_Tools2D::MakePCurveOfType(aProj3, aC2D);
379 aTolR = aProj3.GetTolerance();
384 BOPTools_Tools2D::AdjustPCurveOnFace (aF, aFirst, aLast, aC2D, aC2DA);
388 //=======================================================================
389 //function : AdjustPCurveOnFace
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)
397 Standard_Real first, last;
399 first = aC3D -> FirstParameter();
400 last = aC3D -> LastParameter();
402 BOPTools_Tools2D::AdjustPCurveOnFace (aF, first, last, aC2D, aC2DA);
404 //=======================================================================
405 //function : AdjustPCurveOnFace
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)
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;
419 aDelta=Precision::PConfusion();
421 BRepAdaptor_Surface aBAS(aF, Standard_False);
423 BRepTools::UVBounds(aF, UMin, UMax, VMin, VMax);
425 aT =.5*(aFirst+aLast);
434 if (aBAS.IsUPeriodic()) {
435 aUPeriod=aBAS.UPeriod();
436 mincond = (u2 < UMin-aDelta);
437 maxcond = (u2 > UMax+aDelta);
439 decalu = mincond || maxcond;
441 //modified by NIZNHY-PKV Mon Mar 25 16:44:46 2008f
442 //du = ( mincond ) ? UPeriod : -UPeriod;
445 aUP2=aUPeriod+aUPeriod+aDelta;
446 aUP1=aUPeriod+aDelta;
457 else if (u2 < -aUP2) {
466 du = ( mincond ) ? aUPeriod : -aUPeriod;
468 //modified by NIZNHY-PKV Mon Mar 25 16:44:49 2008t
472 if (aUNew<(UMin-aDelta) ||
473 aUNew>(UMax+aDelta)) {
474 // So previous correction was wrong.
475 // Try to be closer to UMin or UMax.
484 } // if (BAHS->IsUPeriodic())
488 if (aBAS.IsVPeriodic()) {
489 Standard_Real aVPeriod, aVm, aVr, aVmid, dVm, dVr;
491 aVPeriod=aBAS.VPeriod();
492 mincond = (VMin - v2 > aDelta);
493 maxcond = (v2 - VMax > aDelta);
494 decalv = mincond || maxcond;
496 dv = ( mincond ) ? aVPeriod : -aVPeriod;
500 if ((VMax-VMin<aVPeriod) && dv) {
503 aVmid=0.5*(VMin+VMax);
513 // Translation if necessary
514 Handle(Geom2d_Curve) aC2Dx=aC2D;
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);
527 //=======================================================================
528 //function : MakePCurveOfType
530 //=======================================================================
531 void BOPTools_Tools2D::MakePCurveOfType(const ProjLib_ProjectedCurve& PC,
532 Handle(Geom2d_Curve)& C2D)
535 switch (PC.GetType()) {
538 C2D = new Geom2d_Line(PC.Line());
540 case GeomAbs_Circle :
541 C2D = new Geom2d_Circle(PC.Circle());
543 case GeomAbs_Ellipse :
544 C2D = new Geom2d_Ellipse(PC.Ellipse());
546 case GeomAbs_Parabola :
547 C2D = new Geom2d_Parabola(PC.Parabola());
549 case GeomAbs_Hyperbola :
550 C2D = new Geom2d_Hyperbola(PC.Hyperbola());
552 case GeomAbs_BSplineCurve :
555 case GeomAbs_BezierCurve :
556 case GeomAbs_OtherCurve :
558 Standard_NotImplemented::Raise("BOPTools_Tools2D::MakePCurveOfType");
563 //=======================================================================
564 //function : TangentOnEdge
566 //=======================================================================
567 Standard_Boolean BOPTools_Tools2D::TangentOnEdge(const Standard_Real par,
568 const TopoDS_Edge& E,
571 Standard_Boolean isdgE;
573 isdgE = BRep_Tool::Degenerated(E);
575 return Standard_False;
577 if (!CheckEdgeLength(E)) {
578 return Standard_False;
581 BRepAdaptor_Curve BC(E);
584 Standard_Real f, l, tolE, tolp;
585 Standard_Boolean onf, onl, inbounds;
587 f = BC.FirstParameter();
588 l = BC.LastParameter();
589 tolE = BC.Tolerance();
590 tolp = BC.Resolution(tolE);
592 onf = Abs(f-par)<tolp;
593 onl = Abs(l-par)<tolp;
594 inbounds = (f<par) && (par<l);
596 if ((!inbounds) && (!onf) && (!onl)) {
597 return Standard_False;
606 return Standard_True;
608 //=======================================================================
609 //function : TangentOnEdge
611 //=======================================================================
612 Standard_Boolean BOPTools_Tools2D::TangentOnEdge(const TopoDS_Edge& aE,
618 DTg.SetCoord(1.,0.,0.);
620 aT= BOPTools_Tools2D::IntermediatePoint (aE);
621 Standard_Boolean bIsFound=BOPTools_Tools2D::TangentOnEdge(aT, aE, aTg);
629 //=======================================================================
630 //function : TangentOnVertex
632 //=======================================================================
633 Standard_Boolean BOPTools_Tools2D::TangentOnVertex (const TopoDS_Vertex& v,
634 const TopoDS_Vertex& vl,
635 const TopoDS_Edge& e,
637 // tg oriented INSIDE 1d(e)
638 // vl : last vertex of e
644 par = BRep_Tool::Parameter(v, e);
645 ok =BOPTools_Tools2D::TangentOnEdge (par, e, tg);
657 //=======================================================================
658 //function : EdgeBounds
660 //=======================================================================
661 void BOPTools_Tools2D::EdgeBounds (const TopoDS_Edge& aE,
662 Standard_Real& aFirst,
663 Standard_Real& aLast)
665 BRepAdaptor_Curve aBC(aE);
666 aFirst= aBC.FirstParameter();
667 aLast = aBC.LastParameter();
670 //=======================================================================
671 //function : IntermediatePoint
673 //=======================================================================
674 Standard_Real BOPTools_Tools2D::IntermediatePoint (const Standard_Real aFirst,
675 const Standard_Real aLast)
677 //define parameter division number as 10*e^(-M_PI) = 0.43213918
678 const Standard_Real PAR_T = 0.43213918;
680 aParm=(1.-PAR_T)*aFirst + PAR_T*aLast;
683 //=======================================================================
684 //function : IntermediatePoint
686 //=======================================================================
687 Standard_Real BOPTools_Tools2D::IntermediatePoint (const TopoDS_Edge& aE)
690 Standard_Real aT, aT1, aT2;
692 Handle(Geom_Curve)aC1=BRep_Tool::Curve(aE, aT1, aT2);
693 aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
697 //=======================================================================
698 //function : CheckEdgeLength
700 //=======================================================================
701 Standard_Boolean CheckEdgeLength (const TopoDS_Edge& E)
703 BRepAdaptor_Curve BC(E);
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();
712 return Standard_True;
715 f = BC.FirstParameter();
716 l = BC.LastParameter();
720 for (i=1; i<=aN; i++) {
733 return (ln > Precision::Confusion());