1 // Created by: Peter KURNEV
2 // Copyright (c) 1999-2012 OPEN CASCADE SAS
4 // The content of this file is subject to the Open CASCADE Technology Public
5 // License Version 6.5 (the "License"). You may not use the content of this file
6 // except in compliance with the License. Please obtain a copy of the License
7 // at http://www.opencascade.org and read it completely before using this file.
9 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12 // The Original Code and all software distributed under the License is
13 // distributed on an "AS IS" basis, without warranty of any kind, and the
14 // Initial Developer hereby disclaims all such warranties, including without
15 // limitation, any warranties of merchantability, fitness for a particular
16 // purpose or non-infringement. Please see the License for the specific terms
17 // and conditions governing the rights and limitations under the License.
20 #include <BOPTools_AlgoTools2D.ixx>
22 #include <Standard_NotImplemented.hxx>
23 #include <Precision.hxx>
27 #include <gp_Pnt2d.hxx>
29 #include <gp_Vec2d.hxx>
31 #include <Geom2d_Curve.hxx>
32 #include <Geom2d_Line.hxx>
33 #include <Geom2d_Circle.hxx>
34 #include <Geom2d_Ellipse.hxx>
35 #include <Geom2d_Parabola.hxx>
36 #include <Geom2d_Hyperbola.hxx>
38 #include <Geom_Curve.hxx>
39 #include <GeomAdaptor_HCurve.hxx>
40 #include <Geom_TrimmedCurve.hxx>
41 #include <Geom_Surface.hxx>
43 #include <TopLoc_Location.hxx>
46 #include <ProjLib_ProjectedCurve.hxx>
48 #include <BRep_Tool.hxx>
49 #include <BRepTools.hxx>
50 #include <BRepAdaptor_HSurface.hxx>
51 #include <BRepAdaptor_Curve.hxx>
52 #include <BRep_Builder.hxx>
53 #include <BRepAdaptor_Surface.hxx>
54 #include <Geom2d_Curve.hxx>
55 #include <Geom_Plane.hxx>
56 #include <Geom_RectangularTrimmedSurface.hxx>
57 #include <BRep_Builder.hxx>
58 #include <Geom_Surface.hxx>
59 #include <BOPCol_IndexedMapOfShape.hxx>
60 #include <BOPTools.hxx>
64 Standard_Boolean CheckEdgeLength (const TopoDS_Edge& E);
66 //=======================================================================
67 //function : BuildPCurveForEdgeOnFace
69 //=======================================================================
70 void BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace (const TopoDS_Edge& aE,
71 const TopoDS_Face& aF)
74 Handle(Geom2d_Curve) aC2D;
75 Standard_Real aTolPC, aTolFact, aTolEdge, aFirst, aLast;
77 Standard_Boolean aHasOld;
78 aHasOld=BOPTools_AlgoTools2D::HasCurveOnSurface (aE, aF, aC2D, aFirst, aLast, aTolEdge);
84 BOPTools_AlgoTools2D::CurveOnSurface(aE, aF, aC2D, aTolPC);
86 aTolEdge=BRep_Tool::Tolerance(aE);
88 aTolFact=Max(aTolEdge, aTolPC);
90 aBB.UpdateEdge(aE, aC2D, aF, aTolFact);
94 //=======================================================================
95 //function : EdgeTangent
97 //=======================================================================
98 Standard_Boolean BOPTools_AlgoTools2D::EdgeTangent(const TopoDS_Edge& anEdge,
99 const Standard_Real aT,
102 Standard_Boolean isdgE;
103 Standard_Real first, last;
105 isdgE = BRep_Tool::Degenerated(anEdge);
107 return Standard_False;
109 if (!CheckEdgeLength(anEdge)) {
110 return Standard_False;
113 Handle(Geom_Curve) aC=BRep_Tool::Curve(anEdge, first, last);
115 aC->D1(aT, aP, aTau);
116 Standard_Real mod = aTau.Magnitude();
117 if(mod > gp::Resolution()) {
121 return Standard_False;
124 if (anEdge.Orientation() == TopAbs_REVERSED){
127 return Standard_True;
130 //=======================================================================
131 //function : PointOnOnSurface
133 //=======================================================================
134 void BOPTools_AlgoTools2D::PointOnSurface (const TopoDS_Edge& aE,
135 const TopoDS_Face& aF,
136 const Standard_Real aParameter,
141 Handle(Geom2d_Curve) aC2D;
142 Standard_Real aToler, aFirst, aLast;
144 BOPTools_AlgoTools2D::CurveOnSurface (aE, aF, aC2D, aFirst, aLast, aToler);
145 aC2D->D0(aParameter, aP2D);
151 //=======================================================================
152 //function : CurveOnSurface
154 //=======================================================================
155 void BOPTools_AlgoTools2D::CurveOnSurface (const TopoDS_Edge& aE,
156 const TopoDS_Face& aF,
157 Handle(Geom2d_Curve)& aC2D,
158 Standard_Real& aToler)
160 Standard_Real aFirst, aLast;
162 BOPTools_AlgoTools2D::CurveOnSurface (aE, aF, aC2D, aFirst, aLast, aToler);
166 //=======================================================================
167 //function : CurveOnSurface
169 //=======================================================================
170 void BOPTools_AlgoTools2D::CurveOnSurface (const TopoDS_Edge& aE,
171 const TopoDS_Face& aF,
172 Handle(Geom2d_Curve)& aC2D,
173 Standard_Real& aFirst,
174 Standard_Real& aLast,
175 Standard_Real& aToler)
177 Standard_Boolean aHasOld;
178 Handle(Geom2d_Curve) C2D;
180 aHasOld=BOPTools_AlgoTools2D::HasCurveOnSurface (aE, aF, C2D, aFirst, aLast, aToler);
186 BOPTools_AlgoTools2D::Make2D(aE, aF, C2D, aFirst, aLast, aToler);
191 //=======================================================================
192 //function : HasCurveOnSurface
194 //=======================================================================
195 Standard_Boolean BOPTools_AlgoTools2D::HasCurveOnSurface (const TopoDS_Edge& aE,
196 const TopoDS_Face& aF,
197 Handle(Geom2d_Curve)& aC2D,
198 Standard_Real& aFirst,
199 Standard_Real& aLast,
200 Standard_Real& aToler)
202 Standard_Boolean aHasOld;
204 aToler=BRep_Tool::Tolerance(aE);
205 BRep_Tool::Range(aE, aFirst, aLast);
207 if((aLast - aFirst) < Precision::PConfusion()) {
208 return Standard_False;
211 aC2D =BRep_Tool::CurveOnSurface(aE, aF, aFirst, aLast);
212 aHasOld=!aC2D.IsNull();
215 //=======================================================================
216 //function : HasCurveOnSurface
218 //=======================================================================
219 Standard_Boolean BOPTools_AlgoTools2D::HasCurveOnSurface (const TopoDS_Edge& aE,
220 const TopoDS_Face& aF)
223 Standard_Boolean aHasOld;
224 Handle(Geom2d_Curve) aC2D;
225 Standard_Real aFirst, aLast;
226 BRep_Tool::Range(aE, aFirst, aLast);
228 if((aLast - aFirst) < Precision::PConfusion()) {
229 return Standard_False;
232 aC2D =BRep_Tool::CurveOnSurface(aE, aF, aFirst, aLast);
233 aHasOld=!aC2D.IsNull();
237 //=======================================================================
238 //function : AdjustPCurveOnFace
240 //=======================================================================
241 void BOPTools_AlgoTools2D::AdjustPCurveOnFace (const TopoDS_Face& aF,
242 const Handle(Geom_Curve)& aC3D,
243 const Handle(Geom2d_Curve)& aC2D,
244 Handle(Geom2d_Curve)& aC2DA)
246 Standard_Real first, last;
248 first = aC3D -> FirstParameter();
249 last = aC3D -> LastParameter();
251 BOPTools_AlgoTools2D::AdjustPCurveOnFace (aF, first, last, aC2D, aC2DA);
253 //=======================================================================
254 //function : AdjustPCurveOnFace
256 //=======================================================================
257 void BOPTools_AlgoTools2D::AdjustPCurveOnFace (const TopoDS_Face& aF,
258 const Standard_Real aFirst,
259 const Standard_Real aLast,
260 const Handle(Geom2d_Curve)& aC2D,
261 Handle(Geom2d_Curve)& aC2DA)
263 Standard_Boolean mincond, maxcond, decalu, decalv;
264 Standard_Integer k, iCnt;
265 Standard_Real UMin, UMax, VMin, VMax, aT, u2, v2, du, dv, aDelta;
266 Standard_Real aUPeriod, aUP2, aUP1, aUNew, aDif, aUx;
268 aDelta=Precision::PConfusion();
270 BRepAdaptor_Surface aBAS(aF, Standard_False);
272 BRepTools::UVBounds(aF, UMin, UMax, VMin, VMax);
274 aT =.5*(aFirst+aLast);
283 if (aBAS.IsUPeriodic()) {
284 aUPeriod=aBAS.UPeriod();
285 mincond = (u2 < UMin-aDelta);
286 maxcond = (u2 > UMax+aDelta);
288 decalu = mincond || maxcond;
290 //du = ( mincond ) ? UPeriod : -UPeriod;
293 aUP2=aUPeriod+aUPeriod+aDelta;
294 aUP1=aUPeriod+aDelta;
305 else if (u2 < -aUP2) {
314 du = ( mincond ) ? aUPeriod : -aUPeriod;
319 if (aUNew<(UMin-aDelta) ||
320 aUNew>(UMax+aDelta)) {
321 // So previous correction was wrong.
322 // Try to be closer to UMin or UMax.
331 } // if (BAHS->IsUPeriodic())
335 if (aBAS.IsVPeriodic()) {
336 Standard_Real aVPeriod, aVm, aVr, aVmid, dVm, dVr;
338 aVPeriod=aBAS.VPeriod();
339 mincond = (VMin - v2 > aDelta);
340 maxcond = (v2 - VMax > aDelta);
341 decalv = mincond || maxcond;
343 dv = ( mincond ) ? aVPeriod : -aVPeriod;
347 if ((VMax-VMin<aVPeriod) && dv) {
350 aVmid=0.5*(VMin+VMax);
360 // Translation if necessary
361 Handle(Geom2d_Curve) aC2Dx=aC2D;
363 if ( du != 0. || dv != 0.) {
364 Handle(Geom2d_Curve) PCT = Handle(Geom2d_Curve)::DownCast(aC2Dx->Copy());
365 gp_Vec2d aV2D(du,dv);
366 PCT->Translate(aV2D);
373 //=======================================================================
374 //function : IntermediatePoint
376 //=======================================================================
377 Standard_Real BOPTools_AlgoTools2D::IntermediatePoint (const Standard_Real aFirst,
378 const Standard_Real aLast)
380 //define parameter division number as 10*e^(-PI) = 0.43213918
381 const Standard_Real PAR_T = 0.43213918;
383 aParm=(1.-PAR_T)*aFirst + PAR_T*aLast;
386 //=======================================================================
387 //function : IntermediatePoint
389 //=======================================================================
390 Standard_Real BOPTools_AlgoTools2D::IntermediatePoint (const TopoDS_Edge& aE)
393 Standard_Real aT, aT1, aT2;
395 Handle(Geom_Curve)aC1=BRep_Tool::Curve(aE, aT1, aT2);
397 BRep_Tool::Range(aE, aT1, aT2);
399 aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2);
403 //=======================================================================
404 //function : BuildPCurveForEdgeOnPlane
406 //=======================================================================
407 void BOPTools_AlgoTools2D::BuildPCurveForEdgeOnPlane (const TopoDS_Edge& aE,
408 const TopoDS_Face& aF)
411 TopLoc_Location aLoc;
412 Handle(Geom2d_Curve) aC2D;
413 Handle(Geom_Plane) aGP;
414 Handle(Geom_RectangularTrimmedSurface) aGRTS;
417 const Handle(Geom_Surface)& aS = BRep_Tool::Surface(aF, aLoc);
418 aGRTS=Handle(Geom_RectangularTrimmedSurface)::DownCast(aS);
420 aGP=Handle(Geom_Plane)::DownCast(aGRTS->BasisSurface());
423 aGP=Handle(Geom_Plane)::DownCast(aS);
430 BOPTools_AlgoTools2D::CurveOnSurface(aE, aF, aC2D, aTolE);
431 aBB.UpdateEdge(aE, aC2D, aF, aTolE);
436 //=======================================================================
439 //=======================================================================
440 void BOPTools_AlgoTools2D::Make2D (const TopoDS_Edge& aE,
441 const TopoDS_Face& aF,
442 Handle(Geom2d_Curve)& aC2D,
443 Standard_Real& aFirst,
444 Standard_Real& aLast,
445 Standard_Real& aToler)
447 Standard_Boolean aLocIdentity;
448 Standard_Real f3d, l3d;
449 TopLoc_Location aLoc;
451 Handle(Geom2d_Curve) C2D;
454 C2D=BRep_Tool::CurveOnSurface(aE, aF, aFirst, aLast);
461 Handle(Geom_Curve) C3D2, C3D;
462 C3D = BRep_Tool::Curve(aE, aLoc, f3d, l3d);
465 // aE has no 3D curve, so nothing is done
468 aLocIdentity=aLoc.IsIdentity();
474 C3D2 = Handle(Geom_Curve)::
475 DownCast(C3D->Transformed(aLoc.Transformation()));
479 aToler=.5*BRep_Tool::Tolerance(aE);
480 BOPTools_AlgoTools2D::MakePCurveOnFace(aF, C3D2, f3d, l3d, aC2D, aToler);
486 //=======================================================================
487 //function : MakePCurveOnFace
489 //=======================================================================
490 void BOPTools_AlgoTools2D::MakePCurveOnFace (const TopoDS_Face& aF,
491 const Handle(Geom_Curve)& aC3D,
492 Handle(Geom2d_Curve)& aC2D, //->
493 Standard_Real& TolReached2d)
495 Standard_Real aFirst, aLast;
497 aFirst = aC3D -> FirstParameter();
498 aLast = aC3D -> LastParameter();
502 BOPTools_AlgoTools2D::MakePCurveOnFace (aF, aC3D, aFirst, aLast, aC2D, TolReached2d);
505 //=======================================================================
506 //function : MakePCurveOnFace
508 //=======================================================================
509 void BOPTools_AlgoTools2D::MakePCurveOnFace (const TopoDS_Face& aF,
510 const Handle(Geom_Curve)& aC3D,
511 const Standard_Real aFirst,
512 const Standard_Real aLast,
513 Handle(Geom2d_Curve)& aC2D,
514 Standard_Real& TolReached2d)
517 Handle(Geom2d_Curve) aC2DA;
519 BRepAdaptor_Surface aBAS(aF, Standard_False);
520 Handle(BRepAdaptor_HSurface) aBAHS = new BRepAdaptor_HSurface(aBAS);
521 Handle(GeomAdaptor_HCurve) aBAHC = new GeomAdaptor_HCurve(aC3D, aFirst, aLast);
523 //when the type of surface is GeomAbs_SurfaceOfRevolution
524 if (aBAS.GetType() == GeomAbs_SurfaceOfRevolution) {
525 Standard_Real aTR = 1.e-7;
526 ProjLib_ProjectedCurve aProj1(aBAHS, aBAHC, aTR);
527 BOPTools_AlgoTools2D::MakePCurveOfType(aProj1, aC2D);
528 aTolR = aProj1.GetTolerance();
530 ProjLib_ProjectedCurve aProjCurv(aBAHS, aBAHC);// 1
531 BOPTools_AlgoTools2D::MakePCurveOfType(aProjCurv, aC2D);
532 aTolR=aProjCurv.GetTolerance();
536 ProjLib_ProjectedCurve aProjCurvAgain(aBAHS, aBAHC, TolReached2d);// 2
537 BOPTools_AlgoTools2D::MakePCurveOfType(aProjCurvAgain, aC2D);
538 aTolR = aProjCurvAgain.GetTolerance();
541 Standard_Real aTR=0.0001;
542 ProjLib_ProjectedCurve aProj3(aBAHS, aBAHC, aTR);// 3
543 BOPTools_AlgoTools2D::MakePCurveOfType(aProj3, aC2D);
544 aTolR = aProj3.GetTolerance();
549 BOPTools_AlgoTools2D::AdjustPCurveOnFace (aF, aFirst, aLast, aC2D, aC2DA);
553 //=======================================================================
554 //function : MakePCurveOfType
556 //=======================================================================
557 void BOPTools_AlgoTools2D::MakePCurveOfType(const ProjLib_ProjectedCurve& PC,
558 Handle(Geom2d_Curve)& C2D)
561 switch (PC.GetType()) {
564 C2D = new Geom2d_Line(PC.Line());
566 case GeomAbs_Circle :
567 C2D = new Geom2d_Circle(PC.Circle());
569 case GeomAbs_Ellipse :
570 C2D = new Geom2d_Ellipse(PC.Ellipse());
572 case GeomAbs_Parabola :
573 C2D = new Geom2d_Parabola(PC.Parabola());
575 case GeomAbs_Hyperbola :
576 C2D = new Geom2d_Hyperbola(PC.Hyperbola());
578 case GeomAbs_BSplineCurve :
581 case GeomAbs_BezierCurve :
582 case GeomAbs_OtherCurve :
584 Standard_NotImplemented::Raise("BOPTools_AlgoTools2D::MakePCurveOfType");
589 //=======================================================================
590 //function : CheckEdgeLength
592 //=======================================================================
593 Standard_Boolean CheckEdgeLength (const TopoDS_Edge& E)
595 BRepAdaptor_Curve BC(E);
597 BOPCol_IndexedMapOfShape aM;
598 BOPTools::MapShapes(E, TopAbs_VERTEX, aM);
599 Standard_Integer i, anExtent, aN=10;
600 Standard_Real ln=0., d, t, f, l, dt;
601 anExtent=aM.Extent();
604 return Standard_True;
607 f = BC.FirstParameter();
608 l = BC.LastParameter();
612 for (i=1; i<=aN; i++) {
625 return (ln > Precision::Confusion());
636 //=======================================================================
637 //function : FaceNormal
639 //=======================================================================
640 void BOPTools_AlgoTools2D::FaceNormal (const TopoDS_Face& aF,
641 const Standard_Real U,
642 const Standard_Real V,
647 Handle(Geom_Surface) aSurface;
649 aSurface=BRep_Tool::Surface(aF);
650 aSurface->D1 (U, V, aPnt, aD1U, aD1V);
651 aN=aD1U.Crossed(aD1V);
653 if (aF.Orientation() == TopAbs_REVERSED){
658 //=======================================================================
659 //function : RemovePCurveForEdgeOnFace
661 //=======================================================================
662 void BOPTools_AlgoTools2D::RemovePCurveForEdgeOnFace (const TopoDS_Edge& aE,
663 const TopoDS_Face& aF)
666 Handle(Geom2d_Curve) aC2D;
669 aTol=BRep_Tool::Tolerance(aE);
670 aBB.UpdateEdge(aE, aC2D, aF, aTol);
672 //=======================================================================
673 //function : MakeCurveOnSurface
675 //=======================================================================
676 void BOPTools_AlgoTools2D::MakeCurveOnSurface (const TopoDS_Edge& aE,
677 const TopoDS_Face& aF,
678 Handle(Geom2d_Curve)& aC2D,
679 Standard_Real& aFirst,
680 Standard_Real& aLast,
681 Standard_Real& aToler)
683 BOPTools_AlgoTools2D::Make2D(aE, aF, aC2D, aFirst, aLast, aToler);
686 //=======================================================================
687 //function : TangentOnEdge
689 //=======================================================================
690 Standard_Boolean BOPTools_AlgoTools2D::TangentOnEdge(const Standard_Real par,
691 const TopoDS_Edge& E,
694 Standard_Boolean isdgE;
696 isdgE = BRep_Tool::Degenerated(E);
698 return Standard_False;
700 if (!CheckEdgeLength(E)) {
701 return Standard_False;
704 BRepAdaptor_Curve BC(E);
707 Standard_Real f, l, tolE, tolp;
708 Standard_Boolean onf, onl, inbounds;
710 f = BC.FirstParameter();
711 l = BC.LastParameter();
712 tolE = BC.Tolerance();
713 tolp = BC.Resolution(tolE);
715 onf = Abs(f-par)<tolp;
716 onl = Abs(l-par)<tolp;
717 inbounds = (f<par) && (par<l);
719 if ((!inbounds) && (!onf) && (!onl)) {
720 return Standard_False;
729 return Standard_True;
731 //=======================================================================
732 //function : TangentOnEdge
734 //=======================================================================
735 Standard_Boolean BOPTools_AlgoTools2D::TangentOnEdge(const TopoDS_Edge& aE,
741 DTg.SetCoord(1.,0.,0.);
743 aT= BOPTools_AlgoTools2D::IntermediatePoint (aE);
744 Standard_Boolean bIsFound=BOPTools_AlgoTools2D::TangentOnEdge(aT, aE, aTg);
752 //=======================================================================
753 //function : TangentOnVertex
755 //=======================================================================
756 Standard_Boolean BOPTools_AlgoTools2D::TangentOnVertex (const TopoDS_Vertex& v,
757 const TopoDS_Vertex& vl,
758 const TopoDS_Edge& e,
760 // tg oriented INSIDE 1d(e)
761 // vl : last vertex of e
767 par = BRep_Tool::Parameter(v, e);
768 ok =BOPTools_AlgoTools2D::TangentOnEdge (par, e, tg);
780 //=======================================================================
781 //function : EdgeBounds
783 //=======================================================================
784 void BOPTools_AlgoTools2D::EdgeBounds (const TopoDS_Edge& aE,
785 Standard_Real& aFirst,
786 Standard_Real& aLast)
788 BRepAdaptor_Curve aBC(aE);
789 aFirst= aBC.FirstParameter();
790 aLast = aBC.LastParameter();