// Created by: Peter KURNEV // Copyright (c) 1999-2012 OPEN CASCADE SAS // // The content of this file is subject to the Open CASCADE Technology Public // License Version 6.5 (the "License"). You may not use the content of this file // except in compliance with the License. Please obtain a copy of the License // at http://www.opencascade.org and read it completely before using this file. // // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. // // The Original Code and all software distributed under the License is // distributed on an "AS IS" basis, without warranty of any kind, and the // Initial Developer hereby disclaims all such warranties, including without // limitation, any warranties of merchantability, fitness for a particular // purpose or non-infringement. Please see the License for the specific terms // and conditions governing the rights and limitations under the License. #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static Standard_Boolean CheckEdgeLength (const TopoDS_Edge& E); //======================================================================= //function : BuildPCurveForEdgeOnFace //purpose : //======================================================================= void BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace (const TopoDS_Edge& aE, const TopoDS_Face& aF) { BRep_Builder aBB; Handle(Geom2d_Curve) aC2D; Standard_Real aTolPC, aTolFact, aTolEdge, aFirst, aLast; Standard_Boolean aHasOld; aHasOld=BOPTools_AlgoTools2D::HasCurveOnSurface (aE, aF, aC2D, aFirst, aLast, aTolEdge); if (aHasOld) { return; } BOPTools_AlgoTools2D::CurveOnSurface(aE, aF, aC2D, aTolPC); aTolEdge=BRep_Tool::Tolerance(aE); aTolFact=Max(aTolEdge, aTolPC); aBB.UpdateEdge(aE, aC2D, aF, aTolFact); return; } //======================================================================= //function : EdgeTangent //purpose : //======================================================================= Standard_Boolean BOPTools_AlgoTools2D::EdgeTangent(const TopoDS_Edge& anEdge, const Standard_Real aT, gp_Vec& aTau) { Standard_Boolean isdgE; Standard_Real first, last; isdgE = BRep_Tool::Degenerated(anEdge); if (isdgE) { return Standard_False; } if (!CheckEdgeLength(anEdge)) { return Standard_False; } Handle(Geom_Curve) aC=BRep_Tool::Curve(anEdge, first, last); gp_Pnt aP; aC->D1(aT, aP, aTau); Standard_Real mod = aTau.Magnitude(); if(mod > gp::Resolution()) { aTau /= mod; } else { return Standard_False; } //aTau.Normalize(); if (anEdge.Orientation() == TopAbs_REVERSED){ aTau.Reverse(); } return Standard_True; } //======================================================================= //function : PointOnOnSurface //purpose : //======================================================================= void BOPTools_AlgoTools2D::PointOnSurface (const TopoDS_Edge& aE, const TopoDS_Face& aF, const Standard_Real aParameter, Standard_Real& U, Standard_Real& V) { gp_Pnt2d aP2D; Handle(Geom2d_Curve) aC2D; Standard_Real aToler, aFirst, aLast; BOPTools_AlgoTools2D::CurveOnSurface (aE, aF, aC2D, aFirst, aLast, aToler); aC2D->D0(aParameter, aP2D); U=aP2D.X(); V=aP2D.Y(); return; } //======================================================================= //function : CurveOnSurface //purpose : //======================================================================= void BOPTools_AlgoTools2D::CurveOnSurface (const TopoDS_Edge& aE, const TopoDS_Face& aF, Handle(Geom2d_Curve)& aC2D, Standard_Real& aToler) { Standard_Real aFirst, aLast; BOPTools_AlgoTools2D::CurveOnSurface (aE, aF, aC2D, aFirst, aLast, aToler); return; } //======================================================================= //function : CurveOnSurface //purpose : //======================================================================= void BOPTools_AlgoTools2D::CurveOnSurface (const TopoDS_Edge& aE, const TopoDS_Face& aF, Handle(Geom2d_Curve)& aC2D, Standard_Real& aFirst, Standard_Real& aLast, Standard_Real& aToler) { Standard_Boolean aHasOld; Handle(Geom2d_Curve) C2D; aHasOld=BOPTools_AlgoTools2D::HasCurveOnSurface (aE, aF, C2D, aFirst, aLast, aToler); if (aHasOld) { aC2D=C2D; return; } BOPTools_AlgoTools2D::Make2D(aE, aF, C2D, aFirst, aLast, aToler); aC2D=C2D; return; } //======================================================================= //function : HasCurveOnSurface //purpose : //======================================================================= Standard_Boolean BOPTools_AlgoTools2D::HasCurveOnSurface (const TopoDS_Edge& aE, const TopoDS_Face& aF, Handle(Geom2d_Curve)& aC2D, Standard_Real& aFirst, Standard_Real& aLast, Standard_Real& aToler) { Standard_Boolean aHasOld; aToler=BRep_Tool::Tolerance(aE); BRep_Tool::Range(aE, aFirst, aLast); if((aLast - aFirst) < Precision::PConfusion()) { return Standard_False; } aC2D =BRep_Tool::CurveOnSurface(aE, aF, aFirst, aLast); aHasOld=!aC2D.IsNull(); return aHasOld; } //======================================================================= //function : HasCurveOnSurface //purpose : //======================================================================= Standard_Boolean BOPTools_AlgoTools2D::HasCurveOnSurface (const TopoDS_Edge& aE, const TopoDS_Face& aF) { Standard_Boolean aHasOld; Handle(Geom2d_Curve) aC2D; Standard_Real aFirst, aLast; BRep_Tool::Range(aE, aFirst, aLast); if((aLast - aFirst) < Precision::PConfusion()) { return Standard_False; } aC2D =BRep_Tool::CurveOnSurface(aE, aF, aFirst, aLast); aHasOld=!aC2D.IsNull(); return aHasOld; } //======================================================================= //function : AdjustPCurveOnFace //purpose : //======================================================================= void BOPTools_AlgoTools2D::AdjustPCurveOnFace (const TopoDS_Face& aF, const Handle(Geom_Curve)& aC3D, const Handle(Geom2d_Curve)& aC2D, Handle(Geom2d_Curve)& aC2DA) { Standard_Real first, last; first = aC3D -> FirstParameter(); last = aC3D -> LastParameter(); BOPTools_AlgoTools2D::AdjustPCurveOnFace (aF, first, last, aC2D, aC2DA); } //======================================================================= //function : AdjustPCurveOnFace //purpose : //======================================================================= void BOPTools_AlgoTools2D::AdjustPCurveOnFace (const TopoDS_Face& aF, const Standard_Real aFirst, const Standard_Real aLast, const Handle(Geom2d_Curve)& aC2D, Handle(Geom2d_Curve)& aC2DA) { Standard_Boolean mincond, maxcond, decalu, decalv; Standard_Integer k, iCnt; Standard_Real UMin, UMax, VMin, VMax, aT, u2, v2, du, dv, aDelta; Standard_Real aUPeriod, aUP2, aUP1, aUNew, aDif, aUx; // aDelta=Precision::PConfusion(); BRepAdaptor_Surface aBAS(aF, Standard_False); BRepTools::UVBounds(aF, UMin, UMax, VMin, VMax); aT =.5*(aFirst+aLast); gp_Pnt2d pC2D; aC2D->D0(aT, pC2D); u2 = pC2D.X(); v2 = pC2D.Y(); du = 0.; if (aBAS.IsUPeriodic()) { aUPeriod=aBAS.UPeriod(); mincond = (u2 < UMin-aDelta); maxcond = (u2 > UMax+aDelta); decalu = mincond || maxcond; if (decalu) { //du = ( mincond ) ? UPeriod : -UPeriod; // iCnt=1; aUP2=aUPeriod+aUPeriod+aDelta; aUP1=aUPeriod+aDelta; // if (u2 > aUP2) { for(k=1; 1; ++k) { aUx=u2-k*aUPeriod; if (aUx < aUP1) { iCnt=k; break; } } } else if (u2 < -aUP2) { for(k=1; 1; ++k) { aUx=u2+k*aUPeriod; if (aUx > -aUP1) { iCnt=k+1; break; } } } du = ( mincond ) ? aUPeriod : -aUPeriod; du=iCnt*du; } // aUNew=u2+du; if (aUNew<(UMin-aDelta) || aUNew>(UMax+aDelta)) { // So previous correction was wrong. // Try to be closer to UMin or UMax. du=0.; if (u2>UMax){ aDif=u2-UMax; if (aDif < 4.e-7) { du=-aDif; } } } } // if (BAHS->IsUPeriodic()) // // dv dv = 0.; if (aBAS.IsVPeriodic()) { Standard_Real aVPeriod, aVm, aVr, aVmid, dVm, dVr; // aVPeriod=aBAS.VPeriod(); mincond = (VMin - v2 > aDelta); maxcond = (v2 - VMax > aDelta); decalv = mincond || maxcond; if (decalv) { dv = ( mincond ) ? aVPeriod : -aVPeriod; } // //xf if ((VMax-VMinCopy()); gp_Vec2d aV2D(du,dv); PCT->Translate(aV2D); aC2Dx = PCT; } aC2DA=aC2Dx; } //======================================================================= //function : IntermediatePoint //purpose : //======================================================================= Standard_Real BOPTools_AlgoTools2D::IntermediatePoint (const Standard_Real aFirst, const Standard_Real aLast) { //define parameter division number as 10*e^(-PI) = 0.43213918 const Standard_Real PAR_T = 0.43213918; Standard_Real aParm; aParm=(1.-PAR_T)*aFirst + PAR_T*aLast; return aParm; } //======================================================================= //function : IntermediatePoint //purpose : //======================================================================= Standard_Real BOPTools_AlgoTools2D::IntermediatePoint (const TopoDS_Edge& aE) { Standard_Real aT, aT1, aT2; Handle(Geom_Curve)aC1=BRep_Tool::Curve(aE, aT1, aT2); if (aC1.IsNull()) BRep_Tool::Range(aE, aT1, aT2); aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2); return aT; } //======================================================================= //function : BuildPCurveForEdgeOnPlane //purpose : //======================================================================= void BOPTools_AlgoTools2D::BuildPCurveForEdgeOnPlane (const TopoDS_Edge& aE, const TopoDS_Face& aF) { Standard_Real aTolE; TopLoc_Location aLoc; Handle(Geom2d_Curve) aC2D; Handle(Geom_Plane) aGP; Handle(Geom_RectangularTrimmedSurface) aGRTS; BRep_Builder aBB; // const Handle(Geom_Surface)& aS = BRep_Tool::Surface(aF, aLoc); aGRTS=Handle(Geom_RectangularTrimmedSurface)::DownCast(aS); if(!aGRTS.IsNull()){ aGP=Handle(Geom_Plane)::DownCast(aGRTS->BasisSurface()); } else { aGP=Handle(Geom_Plane)::DownCast(aS); } // if (aGP.IsNull()) { return; } // BOPTools_AlgoTools2D::CurveOnSurface(aE, aF, aC2D, aTolE); aBB.UpdateEdge(aE, aC2D, aF, aTolE); // return; } //======================================================================= //function : Make2D //purpose : //======================================================================= void BOPTools_AlgoTools2D::Make2D (const TopoDS_Edge& aE, const TopoDS_Face& aF, Handle(Geom2d_Curve)& aC2D, Standard_Real& aFirst, Standard_Real& aLast, Standard_Real& aToler) { Standard_Boolean aLocIdentity; Standard_Real f3d, l3d; TopLoc_Location aLoc; Handle(Geom2d_Curve) C2D; C2D=BRep_Tool::CurveOnSurface(aE, aF, aFirst, aLast); if (!C2D.IsNull()) { aC2D=C2D; return; } Handle(Geom_Curve) C3D2, C3D; C3D = BRep_Tool::Curve(aE, aLoc, f3d, l3d); // if (C3D.IsNull()) { // aE has no 3D curve, so nothing is done } // aLocIdentity=aLoc.IsIdentity(); if (aLocIdentity) { C3D2 = C3D; } else { C3D2 = Handle(Geom_Curve):: DownCast(C3D->Transformed(aLoc.Transformation())); } // aToler=.5*BRep_Tool::Tolerance(aE); BOPTools_AlgoTools2D::MakePCurveOnFace(aF, C3D2, f3d, l3d, aC2D, aToler); // aFirst = f3d; aLast = l3d; } //======================================================================= //function : MakePCurveOnFace //purpose : //======================================================================= void BOPTools_AlgoTools2D::MakePCurveOnFace (const TopoDS_Face& aF, const Handle(Geom_Curve)& aC3D, Handle(Geom2d_Curve)& aC2D, //-> Standard_Real& TolReached2d) { Standard_Real aFirst, aLast; aFirst = aC3D -> FirstParameter(); aLast = aC3D -> LastParameter(); // TolReached2d=0.; // BOPTools_AlgoTools2D::MakePCurveOnFace (aF, aC3D, aFirst, aLast, aC2D, TolReached2d); } //======================================================================= //function : MakePCurveOnFace //purpose : //======================================================================= void BOPTools_AlgoTools2D::MakePCurveOnFace (const TopoDS_Face& aF, const Handle(Geom_Curve)& aC3D, const Standard_Real aFirst, const Standard_Real aLast, Handle(Geom2d_Curve)& aC2D, Standard_Real& TolReached2d) { Standard_Real aTolR; Handle(Geom2d_Curve) aC2DA; BRepAdaptor_Surface aBAS(aF, Standard_False); Handle(BRepAdaptor_HSurface) aBAHS = new BRepAdaptor_HSurface(aBAS); Handle(GeomAdaptor_HCurve) aBAHC = new GeomAdaptor_HCurve(aC3D, aFirst, aLast); //when the type of surface is GeomAbs_SurfaceOfRevolution if (aBAS.GetType() == GeomAbs_SurfaceOfRevolution) { Standard_Real aTR = 1.e-7; ProjLib_ProjectedCurve aProj1(aBAHS, aBAHC, aTR); BOPTools_AlgoTools2D::MakePCurveOfType(aProj1, aC2D); aTolR = aProj1.GetTolerance(); } else { ProjLib_ProjectedCurve aProjCurv(aBAHS, aBAHC);// 1 BOPTools_AlgoTools2D::MakePCurveOfType(aProjCurv, aC2D); aTolR=aProjCurv.GetTolerance(); } // if (aC2D.IsNull()) { ProjLib_ProjectedCurve aProjCurvAgain(aBAHS, aBAHC, TolReached2d);// 2 BOPTools_AlgoTools2D::MakePCurveOfType(aProjCurvAgain, aC2D); aTolR = aProjCurvAgain.GetTolerance(); // if (aC2D.IsNull()) { Standard_Real aTR=0.0001; ProjLib_ProjectedCurve aProj3(aBAHS, aBAHC, aTR);// 3 BOPTools_AlgoTools2D::MakePCurveOfType(aProj3, aC2D); aTolR = aProj3.GetTolerance(); } } TolReached2d=aTolR; BOPTools_AlgoTools2D::AdjustPCurveOnFace (aF, aFirst, aLast, aC2D, aC2DA); aC2D=aC2DA; } //======================================================================= //function : MakePCurveOfType //purpose : //======================================================================= void BOPTools_AlgoTools2D::MakePCurveOfType(const ProjLib_ProjectedCurve& PC, Handle(Geom2d_Curve)& C2D) { switch (PC.GetType()) { case GeomAbs_Line : C2D = new Geom2d_Line(PC.Line()); break; case GeomAbs_Circle : C2D = new Geom2d_Circle(PC.Circle()); break; case GeomAbs_Ellipse : C2D = new Geom2d_Ellipse(PC.Ellipse()); break; case GeomAbs_Parabola : C2D = new Geom2d_Parabola(PC.Parabola()); break; case GeomAbs_Hyperbola : C2D = new Geom2d_Hyperbola(PC.Hyperbola()); break; case GeomAbs_BSplineCurve : C2D = PC.BSpline(); break; case GeomAbs_BezierCurve : case GeomAbs_OtherCurve : default : Standard_NotImplemented::Raise("BOPTools_AlgoTools2D::MakePCurveOfType"); break; } } //======================================================================= //function : CheckEdgeLength //purpose : //======================================================================= Standard_Boolean CheckEdgeLength (const TopoDS_Edge& E) { BRepAdaptor_Curve BC(E); BOPCol_IndexedMapOfShape aM; BOPTools::MapShapes(E, TopAbs_VERTEX, aM); Standard_Integer i, anExtent, aN=10; Standard_Real ln=0., d, t, f, l, dt; anExtent=aM.Extent(); if (anExtent!=1) return Standard_True; gp_Pnt p1, p2; f = BC.FirstParameter(); l = BC.LastParameter(); dt=(l-f)/aN; BC.D0(f, p1); for (i=1; i<=aN; i++) { t=f+i*dt; if (i==aN) BC.D0(l, p2); else BC.D0(t, p2); d=p1.Distance(p2); ln+=d; p1=p2; } return (ln > Precision::Confusion()); } /* //======================================================================= //function : FaceNormal //purpose : //======================================================================= void BOPTools_AlgoTools2D::FaceNormal (const TopoDS_Face& aF, const Standard_Real U, const Standard_Real V, gp_Vec& aN) { gp_Pnt aPnt ; gp_Vec aD1U, aD1V; Handle(Geom_Surface) aSurface; aSurface=BRep_Tool::Surface(aF); aSurface->D1 (U, V, aPnt, aD1U, aD1V); aN=aD1U.Crossed(aD1V); aN.Normalize(); if (aF.Orientation() == TopAbs_REVERSED){ aN.Reverse(); } return; } //======================================================================= //function : RemovePCurveForEdgeOnFace //purpose : //======================================================================= void BOPTools_AlgoTools2D::RemovePCurveForEdgeOnFace (const TopoDS_Edge& aE, const TopoDS_Face& aF) { BRep_Builder aBB; Handle(Geom2d_Curve) aC2D; Standard_Real aTol; aTol=BRep_Tool::Tolerance(aE); aBB.UpdateEdge(aE, aC2D, aF, aTol); } //======================================================================= //function : MakeCurveOnSurface //purpose : //======================================================================= void BOPTools_AlgoTools2D::MakeCurveOnSurface (const TopoDS_Edge& aE, const TopoDS_Face& aF, Handle(Geom2d_Curve)& aC2D, Standard_Real& aFirst, Standard_Real& aLast, Standard_Real& aToler) { BOPTools_AlgoTools2D::Make2D(aE, aF, aC2D, aFirst, aLast, aToler); } //======================================================================= //function : TangentOnEdge //purpose : //======================================================================= Standard_Boolean BOPTools_AlgoTools2D::TangentOnEdge(const Standard_Real par, const TopoDS_Edge& E, gp_Vec& Tg) { Standard_Boolean isdgE; isdgE = BRep_Tool::Degenerated(E); if (isdgE) { return Standard_False; } if (!CheckEdgeLength(E)) { return Standard_False; } BRepAdaptor_Curve BC(E); // // Body Standard_Real f, l, tolE, tolp; Standard_Boolean onf, onl, inbounds; f = BC.FirstParameter(); l = BC.LastParameter(); tolE = BC.Tolerance(); tolp = BC.Resolution(tolE); onf = Abs(f-par)