diff --git a/src/GeomInt/GeomInt_IntSS.hxx b/src/GeomInt/GeomInt_IntSS.hxx index 943a59bf27..d961567e09 100644 --- a/src/GeomInt/GeomInt_IntSS.hxx +++ b/src/GeomInt/GeomInt_IntSS.hxx @@ -93,6 +93,15 @@ public: //! converts RLine to Geom(2d)_Curve. Standard_EXPORT static void TreatRLine (const Handle(IntPatch_RLine)& theRL, const Handle(GeomAdaptor_Surface)& theHS1, const Handle(GeomAdaptor_Surface)& theHS2, Handle(Geom_Curve)& theC3d, Handle(Geom2d_Curve)& theC2d1, Handle(Geom2d_Curve)& theC2d2, Standard_Real& theTolReached); + //! creates 2D-curve on given surface from given 3D-curve + Standard_EXPORT static void BuildPCurves (const Standard_Real theFirst, const Standard_Real theLast, + const Standard_Real theUmin, const Standard_Real theUmax, + const Standard_Real theVmin, const Standard_Real theVmax, + Standard_Real& theTol, + const Handle(Geom_Surface)& theSurface, + const Handle(Geom_Curve)& theCurve, + Handle(Geom2d_Curve)& theCurve2d); + //! creates 2D-curve on given surface from given 3D-curve Standard_EXPORT static void BuildPCurves (const Standard_Real f, const Standard_Real l, Standard_Real& Tol, const Handle(Geom_Surface)& S, const Handle(Geom_Curve)& C, Handle(Geom2d_Curve)& C2d); diff --git a/src/GeomInt/GeomInt_IntSS_1.cxx b/src/GeomInt/GeomInt_IntSS_1.cxx index d75c6cdc81..9672735301 100644 --- a/src/GeomInt/GeomInt_IntSS_1.cxx +++ b/src/GeomInt/GeomInt_IntSS_1.cxx @@ -1074,94 +1074,92 @@ void GeomInt_IntSS::TreatRLine(const Handle(IntPatch_RLine)& theRL, //function : BuildPCurves //purpose : //======================================================================= -void GeomInt_IntSS::BuildPCurves (Standard_Real f, - Standard_Real l, - Standard_Real& Tol, - const Handle (Geom_Surface)& S, - const Handle (Geom_Curve)& C, - Handle (Geom2d_Curve)& C2d) +void GeomInt_IntSS::BuildPCurves (const Standard_Real theFirst, const Standard_Real theLast, + const Standard_Real theUmin, const Standard_Real theUmax, + const Standard_Real theVmin, const Standard_Real theVmax, + Standard_Real& theTol, + const Handle(Geom_Surface)& theSurface, + const Handle(Geom_Curve)& theCurve, + Handle(Geom2d_Curve)& theCurve2d) { - if (!C2d.IsNull()) { + if (!theCurve2d.IsNull() || theSurface.IsNull()) { return; } // - Standard_Real umin,umax,vmin,vmax; - // - S->Bounds(umin, umax, vmin, vmax); // in class ProjLib_Function the range of parameters is shrank by 1.e-09 - if((l - f) > 2.e-09) { - C2d = GeomProjLib::Curve2d(C,f,l,S,umin,umax,vmin,vmax,Tol); - if (C2d.IsNull()) { + if ((theLast - theFirst) > 2.e-09) { + theCurve2d = GeomProjLib::Curve2d(theCurve, theFirst, theLast, theSurface, theUmin, theUmax, theVmin, theVmax, theTol); + if (theCurve2d.IsNull()) { // proj. a circle that goes through the pole on a sphere to the sphere - Tol += Precision::Confusion(); - C2d = GeomProjLib::Curve2d(C,f,l,S,Tol); + theTol += Precision::Confusion(); + theCurve2d = GeomProjLib::Curve2d(theCurve, theFirst, theLast, theSurface, theTol); } - const Handle(Standard_Type)& aType = C2d->DynamicType(); - if ( aType == STANDARD_TYPE(Geom2d_BSplineCurve)) - { + const Handle(Standard_Type)& aType = theCurve2d->DynamicType(); + if (aType == STANDARD_TYPE(Geom2d_BSplineCurve)) + { //Check first, last knots to avoid problems with trimming //First, last knots can differ from f, l because of numerical error //of projection and approximation //The same checking as in Geom2d_TrimmedCurve - if((C2d->FirstParameter() - f > Precision::PConfusion()) || - (l - C2d->LastParameter() > Precision::PConfusion())) + if ((theCurve2d->FirstParameter() - theFirst > Precision::PConfusion()) || + (theLast - theCurve2d->LastParameter() > Precision::PConfusion())) { - Handle(Geom2d_BSplineCurve) aBspl = Handle(Geom2d_BSplineCurve)::DownCast(C2d); + Handle(Geom2d_BSplineCurve) aBspl = Handle(Geom2d_BSplineCurve)::DownCast(theCurve2d); TColStd_Array1OfReal aKnots(1, aBspl->NbKnots()); aBspl->Knots(aKnots); - BSplCLib::Reparametrize(f, l, aKnots); + BSplCLib::Reparametrize(theFirst, theLast, aKnots); aBspl->SetKnots(aKnots); } } } else { - if((l - f) > Epsilon(Abs(f))) + if ((theLast - theFirst) > Epsilon(Abs(theFirst))) { //The domain of C2d is [Epsilon(Abs(f)), 2.e-09] //On this small range C2d can be considered as segment //of line. - Standard_Real aU=0., aV=0.; + Standard_Real aU = 0., aV = 0.; GeomAdaptor_Surface anAS; - anAS.Load(S); + anAS.Load(theSurface); Extrema_ExtPS anExtr; - const gp_Pnt aP3d1 = C->Value(f); - const gp_Pnt aP3d2 = C->Value(l); + const gp_Pnt aP3d1 = theCurve->Value(theFirst); + const gp_Pnt aP3d2 = theCurve->Value(theLast); anExtr.SetAlgo(Extrema_ExtAlgo_Grad); - anExtr.Initialize(anAS, umin, umax, vmin, vmax, - Precision::Confusion(), Precision::Confusion()); + anExtr.Initialize(anAS, theUmin, theUmax, theVmin, theVmax, + Precision::Confusion(), Precision::Confusion()); anExtr.Perform(aP3d1); - if(ParametersOfNearestPointOnSurface(anExtr, aU, aV)) + if (ParametersOfNearestPointOnSurface(anExtr, aU, aV)) { const gp_Pnt2d aP2d1(aU, aV); anExtr.Perform(aP3d2); - if(ParametersOfNearestPointOnSurface(anExtr, aU, aV)) + if (ParametersOfNearestPointOnSurface(anExtr, aU, aV)) { const gp_Pnt2d aP2d2(aU, aV); - if(aP2d1.Distance(aP2d2) > gp::Resolution()) + if (aP2d1.Distance(aP2d2) > gp::Resolution()) { - TColgp_Array1OfPnt2d poles(1,2); - TColStd_Array1OfReal knots(1,2); - TColStd_Array1OfInteger mults(1,2); + TColgp_Array1OfPnt2d poles(1, 2); + TColStd_Array1OfReal knots(1, 2); + TColStd_Array1OfInteger mults(1, 2); poles(1) = aP2d1; poles(2) = aP2d2; - knots(1) = f; - knots(2) = l; + knots(1) = theFirst; + knots(2) = theLast; mults(1) = mults(2) = 2; - C2d = new Geom2d_BSplineCurve(poles,knots,mults,1); + theCurve2d = new Geom2d_BSplineCurve(poles, knots, mults, 1); //Check same parameter in middle point .begin - const gp_Pnt PMid(C->Value(0.5*(f+l))); + const gp_Pnt PMid(theCurve->Value(0.5*(theFirst + theLast))); const gp_Pnt2d pmidcurve2d(0.5*(aP2d1.XY() + aP2d2.XY())); const gp_Pnt aPC(anAS.Value(pmidcurve2d.X(), pmidcurve2d.Y())); const Standard_Real aDist = PMid.Distance(aPC); - Tol = Max(aDist, Tol); + theTol = Max(aDist, theTol); //Check same parameter in middle point .end } } @@ -1169,27 +1167,51 @@ void GeomInt_IntSS::BuildPCurves (Standard_Real f, } } // - if (S->IsUPeriodic() && !C2d.IsNull()) { + if (theSurface->IsUPeriodic() && !theCurve2d.IsNull()) { // Recadre dans le domaine UV de la face Standard_Real aTm, U0, aEps, period, du, U0x; Standard_Boolean bAdjust; // aEps = Precision::PConfusion(); - period = S->UPeriod(); + period = theSurface->UPeriod(); // - aTm = .5*(f + l); - gp_Pnt2d pm = C2d->Value(aTm); + aTm = .5 * (theFirst + theLast); + gp_Pnt2d pm = theCurve2d->Value(aTm); U0 = pm.X(); // - bAdjust = - GeomInt::AdjustPeriodic(U0, umin, umax, period, U0x, du, aEps); + bAdjust = + GeomInt::AdjustPeriodic(U0, theUmin, theUmax, period, U0x, du, aEps); if (bAdjust) { gp_Vec2d T1(du, 0.); - C2d->Translate(T1); + theCurve2d->Translate(T1); } } } + + +//======================================================================= +//function : BuildPCurves +//purpose : +//======================================================================= +void GeomInt_IntSS::BuildPCurves (const Standard_Real f, + const Standard_Real l, + Standard_Real& Tol, + const Handle (Geom_Surface)& S, + const Handle (Geom_Curve)& C, + Handle (Geom2d_Curve)& C2d) +{ + if (!C2d.IsNull() || S.IsNull()) { + return; + } + // + Standard_Real umin,umax,vmin,vmax; + // + S->Bounds(umin, umax, vmin, vmax); + + BuildPCurves(f, l, umin, umax, vmin, vmax, Tol, S, C, C2d); +} + //======================================================================= //function : TrimILineOnSurfBoundaries //purpose : This function finds intersection points of given curves with diff --git a/src/IntTools/IntTools_FaceFace.cxx b/src/IntTools/IntTools_FaceFace.cxx index 27f20299b2..b95022f00b 100644 --- a/src/IntTools/IntTools_FaceFace.cxx +++ b/src/IntTools/IntTools_FaceFace.cxx @@ -990,15 +990,19 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index, if (typl == IntPatch_Circle || typl == IntPatch_Ellipse) {//// if(myApprox1) { Handle (Geom2d_Curve) C2d; - GeomInt_IntSS::BuildPCurves(fprm, lprm, Tolpc, - myHS1->Surface(), newc, C2d); + GeomInt_IntSS::BuildPCurves(fprm, lprm, + myHS1->FirstUParameter(), myHS1->LastUParameter(), + myHS1->FirstVParameter(), myHS1->LastVParameter(), + Tolpc, myHS1->Surface(), newc, C2d); aCurve.SetFirstCurve2d(C2d); } if(myApprox2) { Handle (Geom2d_Curve) C2d; - GeomInt_IntSS::BuildPCurves(fprm,lprm,Tolpc, - myHS2->Surface(),newc,C2d); + GeomInt_IntSS::BuildPCurves(fprm, lprm, + myHS2->FirstUParameter(), myHS2->LastUParameter(), + myHS2->FirstVParameter(), myHS2->LastVParameter(), + Tolpc, myHS2->Surface(), newc, C2d); aCurve.SetSecondCurve2d(C2d); } } @@ -1059,15 +1063,19 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index, if(myApprox1) { Handle (Geom2d_Curve) C2d; - GeomInt_IntSS::BuildPCurves(fprm, lprm, Tolpc, - myHS1->Surface(), newc, C2d); + GeomInt_IntSS::BuildPCurves(fprm, lprm, + myHS1->FirstUParameter(), myHS1->LastUParameter(), + myHS1->FirstVParameter(), myHS1->LastVParameter(), + Tolpc, myHS1->Surface(), newc, C2d); aCurve.SetFirstCurve2d(C2d); } if(myApprox2) { Handle (Geom2d_Curve) C2d; - GeomInt_IntSS::BuildPCurves(fprm, lprm, Tolpc, - myHS2->Surface(), newc, C2d); + GeomInt_IntSS::BuildPCurves(fprm, lprm, + myHS2->FirstUParameter(), myHS2->LastUParameter(), + myHS2->FirstVParameter(), myHS2->LastVParameter(), + Tolpc, myHS2->Surface(), newc, C2d); aCurve.SetSecondCurve2d(C2d); } }// end of if (typl == IntPatch_Circle || typl == IntPatch_Ellipse) diff --git a/tests/bugs/modalg_8/bug33247 b/tests/bugs/modalg_8/bug33247 new file mode 100644 index 0000000000..dd33c0e85d --- /dev/null +++ b/tests/bugs/modalg_8/bug33247 @@ -0,0 +1,13 @@ +puts "============" +puts "0033247: Modeling Algorithms - BOP report small edges problem and produce empty result" +puts "============" +puts "" + +restore [locate_data_file bug33247_object.brep] a +restore [locate_data_file bug33247_tool.brep] b +bcommon r a b + +checknbshapes r -vertex 98 -edge 131 -wire 35 -face 26 +checkprops r -s 157.39 + +checkview -display r -2d -path ${imagedir}/${test_image}.png