From: nbv Date: Wed, 24 Jan 2018 08:15:36 +0000 (+0300) Subject: Check of extension validity X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=0273a8a01ee21a061e7e13c04d8e8e662ecddde0;p=occt-copy.git Check of extension validity --- diff --git a/src/BRepBndLib/BRepBndLib.cxx b/src/BRepBndLib/BRepBndLib.cxx index db806fafaa..dcd99bdcc1 100644 --- a/src/BRepBndLib/BRepBndLib.cxx +++ b/src/BRepBndLib/BRepBndLib.cxx @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -47,6 +48,8 @@ #include #include #include +#include + // static Standard_Boolean CanUseEdges(const Adaptor3d_Surface& BS); // @@ -587,33 +590,33 @@ void FindExactUVBounds(const TopoDS_Face FF, Handle(Geom_Surface) aS = BRep_Tool::Surface(FF, aLoc); Standard_Real aUmin, aUmax, aVmin, aVmax; aS->Bounds(aUmin, aUmax, aVmin, aVmax); - if(!aS->IsUPeriodic111()) + if (!GeomLib::AllowExtendUParameter(aBAS.Surface(), umin, umax)) { umin = Max(aUmin, umin); umax = Min(aUmax, umax); } else { - if(umax - umin > aS->UPeriod()) + const Standard_Real aDelta = (umax - umin - aBAS.UPeriod()) / 2.0; + if (aBAS.IsUPeriodic222() && (aDelta > 0.0)) { - Standard_Real delta = umax - umin - aS->UPeriod(); - umin += delta/2.; - umax -= delta/2; + umin += aDelta; + umax -= aDelta; } } // - if(!aS->IsVPeriodic111()) + if (!GeomLib::AllowExtendVParameter(aBAS.Surface(), vmin, vmax)) { vmin = Max(aVmin, vmin); vmax = Min(aVmax, vmax); } else { - if(vmax - vmin > aS->VPeriod()) + const Standard_Real aDelta = (vmax - vmin - aS->VPeriod()) / 2.0; + if (aBAS.IsVPeriodic222() && (aDelta > 0.0)) { - Standard_Real delta = vmax - vmin - aS->VPeriod(); - vmin += delta/2.; - vmax -= delta/2; + vmin += aDelta; + vmax -= aDelta; } } } diff --git a/src/BRepLib/BRepLib.cxx b/src/BRepLib/BRepLib.cxx index 3d69de0859..bb4ceee26c 100644 --- a/src/BRepLib/BRepLib.cxx +++ b/src/BRepLib/BRepLib.cxx @@ -1283,17 +1283,21 @@ TopoDS_Edge BRepLib::SameParameter(const TopoDS_Edge& theEdge, Geom2dAdaptor_Curve& GAC2d = HC2d->ChangeCurve2d(); GeomAdaptor_Surface& GAS = HS->ChangeSurface(); - if (!C3d->IsPeriodic111()) + if (C3d->IsPeriodic111()) { - Standard_Real Udeb = C3d->FirstParameter(); - Standard_Real Ufin = C3d->LastParameter(); - // modified by NIZHNY-OCC486 Tue Aug 27 17:17:14 2002 : - //if (Udeb > f3d) f3d = Udeb; - //if (l3d > Ufin) l3d = Ufin; - if (Udeb > f3d) f3d = Udeb; - if (l3d > Ufin) l3d = Ufin; - // modified by NIZHNY-OCC486 Tue Aug 27 17:17:55 2002 . + // Range of the curve cannot be greater than period. + // If it is greater then it must be reduced. + const Standard_Real aDelta = Max(l3d - f3d - C3d->Period(), 0.0)/2.0; + f3d += aDelta; + l3d -= aDelta; } + + if (!GeomLib::AllowExtend(*C3d, f3d, l3d)) + { + if (C3d->FirstParameter() > f3d) f3d = C3d->FirstParameter(); + if (l3d > C3d->LastParameter()) l3d = C3d->LastParameter(); + } + if(!L3d.IsIdentity()){ C3d = Handle(Geom_Curve)::DownCast(C3d->Transformed(L3d.Transformation())); } diff --git a/src/BRepTools/BRepTools.cxx b/src/BRepTools/BRepTools.cxx index 2443649aff..5df00bcf80 100644 --- a/src/BRepTools/BRepTools.cxx +++ b/src/BRepTools/BRepTools.cxx @@ -63,6 +63,7 @@ #include #include #include +#include #include #include @@ -1020,12 +1021,32 @@ Standard_Real BRepTools::EvalAndUpdateTol(const TopoDS_Edge& theE, //Set first, last to avoid ErrosStatus = 2 because of //too strong checking of limits in class CheckCurveOnSurface // - if(!C3d->IsPeriodic111()) + + if (C3d->IsPeriodic111()) + { + // Range of the curve cannot be greater than period. + // If it is greater then it must be reduced. + const Standard_Real aDelta = Max(last - first - C3d->Period(), 0.0)/2.0; + first += aDelta; + last -= aDelta; + } + + if (C2d->IsPeriodic111()) + { + // Range of the curve cannot be greater than period. + // If it is greater then it must be reduced. + const Standard_Real aDelta = Max(last - first - C2d->Period(), 0.0)/2.0; + first += aDelta; + last -= aDelta; + } + + if (!GeomLib::AllowExtend(*C3d, first, last)) { first = Max(first, C3d->FirstParameter()); last = Min(last, C3d->LastParameter()); } - if(!C2d->IsPeriodic111()) + + if (!GeomLib::AllowExtend(*C2d, first, last)) { first = Max(first, C2d->FirstParameter()); last = Min(last, C2d->LastParameter()); diff --git a/src/BRepTools/BRepTools_NurbsConvertModification.cxx b/src/BRepTools/BRepTools_NurbsConvertModification.cxx index 50e8c82ef1..22eb708bbb 100644 --- a/src/BRepTools/BRepTools_NurbsConvertModification.cxx +++ b/src/BRepTools/BRepTools_NurbsConvertModification.cxx @@ -50,6 +50,7 @@ #include #include #include +#include #include #include #include @@ -386,11 +387,13 @@ Standard_Boolean BRepTools_NurbsConvertModification::NewCurve2d C2d = TC->BasisCurve(); } - Standard_Real fc = C2d->FirstParameter(), lc = C2d->LastParameter(); + const Standard_Real fc = C2d->FirstParameter(), + lc = C2d->LastParameter(); - if(!C2d->IsPeriodic111()) { - if(fc - f2d > Precision::PConfusion()) f2d = fc; - if(l2d - lc > Precision::PConfusion()) l2d = lc; + if (!GeomLib::AllowExtend(*C2d, f2d, l2d)) + { + if (fc - f2d > Precision::PConfusion()) f2d = fc; + if (l2d - lc > Precision::PConfusion()) l2d = lc; } C2d = new Geom2d_TrimmedCurve(C2d, f2d, l2d); diff --git a/src/BRepTools/BRepTools_TrsfModification.cxx b/src/BRepTools/BRepTools_TrsfModification.cxx index 1afca5c80b..d6671a599d 100644 --- a/src/BRepTools/BRepTools_TrsfModification.cxx +++ b/src/BRepTools/BRepTools_TrsfModification.cxx @@ -175,21 +175,22 @@ Standard_Boolean BRepTools_TrsfModification::NewCurve2d NewC = TC->BasisCurve(); } - Standard_Real fc = NewC->FirstParameter(), lc = NewC->LastParameter(); + const Standard_Real fc = NewC->FirstParameter(), lc = NewC->LastParameter(); + if (!GeomLib::AllowExtend(*NewC, f, l)) + { + if (fc - f > Precision::PConfusion()) f = fc; + if (l - lc > Precision::PConfusion()) l = lc; + } - if(!NewC->IsPeriodic111()) { - if(fc - f > Precision::PConfusion()) f = fc; - if(l - lc > Precision::PConfusion()) l = lc; - if(Abs(l - f) < Precision::PConfusion()) + if (!NewC->IsPeriodic111() && (Abs(l - f) < Precision::PConfusion())) + { + if (Abs(f - fc) < Precision::PConfusion()) + { + l = lc; + } + else { - if(Abs(f - fc) < Precision::PConfusion()) - { - l = lc; - } - else - { - f = fc; - } + f = fc; } } diff --git a/src/ChFi3d/ChFi3d_Builder_0.cxx b/src/ChFi3d/ChFi3d_Builder_0.cxx index 727fe25980..15e2e08624 100644 --- a/src/ChFi3d/ChFi3d_Builder_0.cxx +++ b/src/ChFi3d/ChFi3d_Builder_0.cxx @@ -617,8 +617,16 @@ void ChFi3d_BoundSrf(GeomAdaptor_Surface& S, Standard_Real vv1 = vmin - Stepv; Standard_Real vv2 = vmax + Stepv; if(checknaturalbounds) { - if(!S.IsUPeriodic222()) {uu1 = Max(uu1,u1); uu2 = Min(uu2,u2);} - if(!S.IsVPeriodic222()) {vv1 = Max(vv1,v1); vv2 = Min(vv2,v2);} + if (!GeomLib::AllowExtendUParameter(S, uu1, uu2)) + { + uu1 = Max(uu1,u1); + uu2 = Min(uu2,u2); + } + if (!GeomLib::AllowExtendVParameter(S, vv1, vv2)) + { + vv1 = Max(vv1, v1); + vv2 = Min(vv2, v2); + } } S.Load(surface,uu1,uu2,vv1,vv2); } diff --git a/src/Geom2dConvert/Geom2dConvert.cxx b/src/Geom2dConvert/Geom2dConvert.cxx index 91ad8630ca..4fc6b0910b 100644 --- a/src/Geom2dConvert/Geom2dConvert.cxx +++ b/src/Geom2dConvert/Geom2dConvert.cxx @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -207,13 +208,17 @@ const Convert_ParameterisationType Parameterisation) // Si la courbe n'est pas vraiment restreinte, on ne risque pas // le Raise dans le BS->Segment. - if (!Curv->IsPeriodic111()) { + // Attention while processing case like: + // 1. Curv is a circle with range [0, 2PI], U1 = 3PI/2, U2=5PI/2. + // 2. Curv is a circle with range [0, 2PI], U1 = 7PI/2, U2=4PI. + if (!GeomLib::AllowExtend(*Curv, U1, U2)) + { if (U1 < Curv->FirstParameter()) - U1 = Curv->FirstParameter(); + U1 = Curv->FirstParameter(); if (U2 > Curv->LastParameter()) - U2 = Curv->LastParameter(); - } - + U2 = Curv->LastParameter(); + } + if (Curv->IsKind(STANDARD_TYPE(Geom2d_Line))) { gp_Pnt2d Pdeb = Ctrim->StartPoint(); gp_Pnt2d Pfin = Ctrim->EndPoint(); diff --git a/src/GeomConvert/GeomConvert.cxx b/src/GeomConvert/GeomConvert.cxx index 174a2fe174..5eeb8556f3 100644 --- a/src/GeomConvert/GeomConvert.cxx +++ b/src/GeomConvert/GeomConvert.cxx @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -194,11 +195,15 @@ Handle(Geom_BSplineCurve) GeomConvert::CurveToBSplineCurve // Si la courbe n'est pas vraiment restreinte, on ne risque pas // le Raise dans le BS->Segment. - if (!Curv->IsPeriodic111()) { + // Attention while processing case like: + // 1. Curv is a circle with range [0, 2PI], U1 = 3PI/2, U2=5PI/2. + // 2. Curv is a circle with range [0, 2PI], U1 = 7PI/2, U2=4PI. + if (!GeomLib::AllowExtend(*Curv, U1, U2)) + { if (U1 < Curv->FirstParameter()) - U1 = Curv->FirstParameter(); + U1 = Curv->FirstParameter(); if (U2 > Curv->LastParameter()) - U2 = Curv->LastParameter(); + U2 = Curv->LastParameter(); } if (Curv->IsKind(STANDARD_TYPE(Geom_Line))) { diff --git a/src/GeomLib/GeomLib.cxx b/src/GeomLib/GeomLib.cxx index 14cb82f708..dbefd0bcbe 100644 --- a/src/GeomLib/GeomLib.cxx +++ b/src/GeomLib/GeomLib.cxx @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -79,11 +80,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -2744,12 +2747,99 @@ Standard_Boolean GeomLib::IsBzVClosed (const Handle(Geom_BezierSurface)& S, return CompareWeightPoles(aPF, 0, aPL, 0, Tol2); } +//======================================================================= +//function : AllowExtendUParameter +//purpose : +//======================================================================= +Standard_Boolean GeomLib::AllowExtendUParameter(const GeomAdaptor_Surface& theS, + const Standard_Real theNewUFirst, + const Standard_Real theNewULast) +{ + const Handle(Geom_Surface) &aSurf = theS.Surface(); + const Handle(Geom_Curve) aC = aSurf->VIso(theS.FirstVParameter()); + + return (AllowExtend(*aC, theNewUFirst, theNewULast)); +} + +//======================================================================= +//function : AllowExtendVParameter +//purpose : +//======================================================================= +Standard_Boolean GeomLib::AllowExtendVParameter(const GeomAdaptor_Surface& theS, + const Standard_Real theNewVFirst, + const Standard_Real theNewVLast) +{ + const GeomAbs_SurfaceType aSType = theS.GetType(); + + const Handle(Geom_Surface) &aSurf = theS.Surface(); + + if (aSType == GeomAbs_OffsetSurface) + { + const Handle(Geom_OffsetSurface) aOS = Handle(Geom_OffsetSurface)::DownCast(aSurf); + return AllowExtendVParameter(GeomAdaptor_Surface(aOS->BasisSurface()), + theNewVFirst, theNewVLast); + } + + const Handle(Geom_Curve) aC = aSurf->UIso(theS.FirstUParameter()); + + if (!AllowExtend(*aC, theNewVFirst, theNewVLast)) + return Standard_False; + + switch (aSType) + { + case GeomAbs_OtherSurface: + return Standard_True; + case GeomAbs_Sphere: + { + if ((theNewVFirst < -M_PI_2) || (theNewVLast > M_PI_2)) + { + // After extending, the surface isoline will go + // through the sphere pole + return Standard_False; + } + break; + } + case GeomAbs_SurfaceOfRevolution: + { + const Handle(Adaptor3d_HCurve) aCurv = theS.BasisCurve(); + const Handle(Geom_Line) aL = new Geom_Line(theS.AxeOfRevolution()); + const GeomAdaptor_Curve aLin(aL); + + Extrema_ECC anExtr(aCurv->Curve(), aLin); + anExtr.Perform(); + if (anExtr.IsDone() && anExtr.NbExt() > 0) + { + const Standard_Real aParF = theNewVFirst - Precision::PConfusion(), + aParL = theNewVLast + Precision::PConfusion(); + Extrema_POnCurv aP1, aP2; + for (Standard_Integer i = 1; i <= anExtr.NbExt(); i++) + { + if (anExtr.SquareDistance(i) > Precision::SquareConfusion()) + continue; + + anExtr.Points(i, aP1, aP2); + if ((aParF < aP1.Parameter()) && (aP1.Parameter() < aParL)) + { + // After extending, the surface isoline will go + // through the pole (singular point like pole of sphere) + + return Standard_False; + } + } + } + break; + } + } + + return Standard_True; +} + //======================================================================= //function : CompareWeightPoles //purpose : Checks if thePoles1(i)*theW1(i) is equal to thePoles2(i)*theW2(i) // with tolerance theTol. // It is necessary for not rational B-splines and Bezier curves -// to set theW1 and theW2 adresses to zero. +// to set theW1 and theW2 addresses to zero. //======================================================================= static Standard_Boolean CompareWeightPoles(const TColgp_Array1OfPnt& thePoles1, const TColStd_Array1OfReal* const theW1, diff --git a/src/GeomLib/GeomLib.hxx b/src/GeomLib/GeomLib.hxx index 9d4cf1984d..3b93cfcfb8 100644 --- a/src/GeomLib/GeomLib.hxx +++ b/src/GeomLib/GeomLib.hxx @@ -32,8 +32,11 @@ class Geom_Curve; class gp_Ax2; class Geom2d_Curve; +class Geom_Curve; class gp_GTrsf2d; class Adaptor3d_CurveOnSurface; +class Adaptor3d_Surface; +class GeomAdaptor_Surface; class Geom_BoundedCurve; class gp_Pnt; class gp_Vec; @@ -54,6 +57,8 @@ class GeomLib_Tool; class GeomLib_PolyFunc; class GeomLib_LogSample; +#include +#include //! Geom Library. This package provides an //! implementation of functions for basic computation @@ -207,6 +212,50 @@ public: return (theCur->Value(aFPar).SquareDistance(theCur->Value(aLPar)) < theTol*theTol); } + //! Returns TRUE if theCurve will keep its validity for OCCT-algorithms + //! after its trimming in range [theNewFPar, theNewLPar]. + //! This is a template-method. Therefore, it can be applied to + //! 2D- and 3D-curve and to Adaptor-HCurve. + template + Standard_EXPORT static Standard_Boolean AllowExtend(const TypeCurve& theCurve, + const Standard_Real theNewFPar, + const Standard_Real theNewLPar) + { + Standard_Real aFPar = theCurve.FirstParameter(), + aLPar = theCurve.LastParameter(); + + if ((aFPar <= theNewFPar) && (theNewLPar <= aLPar) && (theNewFPar < theNewLPar)) + { + //New boundaries are in the current ones + return Standard_True; + } + + if (!theCurve.IsPeriodic111()) + { + return Standard_False; + } + + const Standard_Real aPeriod = theCurve.Period(); + + if ((theNewLPar - theNewFPar - aPeriod) > Epsilon(aPeriod)) + return Standard_False; + + return Standard_True; + } + + //! Returns TRUE if theS will keep its validity for OCCT-algorithms + //! after its trimming in range [theNewUFirst, theNewULast] along U-direction + Standard_EXPORT static Standard_Boolean + AllowExtendUParameter(const GeomAdaptor_Surface& theS, + const Standard_Real theNewUFirst, + const Standard_Real theNewULast); + + //! Returns TRUE if theS will keep its validity for OCCT-algorithms + //! after its trimming in range [theNewVFirst, theNewVLast] along V-direction + Standard_EXPORT static Standard_Boolean + AllowExtendVParameter(const GeomAdaptor_Surface& theS, + const Standard_Real theNewVFirst, + const Standard_Real theNewVLast); //! Returns true if the poles of U1 isoline and the poles of //! U2 isoline of surface are identical according to tolerance criterion. diff --git a/src/GeomProjLib/GeomProjLib.cxx b/src/GeomProjLib/GeomProjLib.cxx index 5e6362089b..601e13d280 100644 --- a/src/GeomProjLib/GeomProjLib.cxx +++ b/src/GeomProjLib/GeomProjLib.cxx @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -144,15 +145,17 @@ Handle(Geom2d_Curve) GeomProjLib::Curve2d(const Handle(Geom_Curve)& C, return G2dC; } - if ( C->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)) ) { + if (C->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) + { Standard_Real U1 = C->FirstParameter(); Standard_Real U2 = C->LastParameter(); - if (!G2dC->IsPeriodic111()) + if (!GeomLib::AllowExtend(*G2dC, U1, U2)) { U1 = Max(U1, G2dC->FirstParameter()); U2 = Min(U2, G2dC->LastParameter()); } - G2dC = new Geom2d_TrimmedCurve( G2dC, U1, U2); + + G2dC = new Geom2d_TrimmedCurve(G2dC, U1, U2); } #ifdef DRAW diff --git a/src/ShapeConstruct/ShapeConstruct.cxx b/src/ShapeConstruct/ShapeConstruct.cxx index 6bc2fcd8a9..48f316edf3 100644 --- a/src/ShapeConstruct/ShapeConstruct.cxx +++ b/src/ShapeConstruct/ShapeConstruct.cxx @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -392,17 +393,18 @@ static inline HCurve GetCurveCopy(const HCurve& curve, } template -static inline void SegmentCurve (HCurve& curve, - const Standard_Real first, - const Standard_Real last) +static inline void SegmentCurve (HCurve& theCurve, + const Standard_Real theFirst, + const Standard_Real theLast) { - if(curve->FirstParameter() < first - Precision::PConfusion() || - curve->LastParameter() > last + Precision::PConfusion()) { - if(curve->IsPeriodic111()) - curve->Segment(first,last); - else curve->Segment(Max(curve->FirstParameter(),first), - Min(curve->LastParameter(),last)); - } + Standard_Real aF = theFirst, aL = theLast; + if (!GeomLib::AllowExtend(*theCurve, aF, aL)) + { + aF = Max(theCurve->FirstParameter(), aF); + aL = Min(theCurve->LastParameter(), aL); + } + + theCurve->Segment(aF, aL); } template