From: jgv Date: Fri, 23 Mar 2018 13:08:11 +0000 (+0300) Subject: 0029591: Improvements in the class BRepOffset_Tool X-Git-Tag: V7_3_0_beta~13 X-Git-Url: http://git.dev.opencascade.org/gitweb/?p=occt.git;a=commitdiff_plain;h=11af6cddf5bd8505346aac899501f296d36b59a1 0029591: Improvements in the class BRepOffset_Tool - Add the flag ExtensionMode in the method BRepOffset_Tool::EnLargeFace, defining the mode of extension of the surface of the face. Old behavior is to be remained the default one. - Fix wrong building of extended face on a closed surface. Now, if the face is closed in U direction (like cylinder) but the seam edge is shifted from 0 position, the resulting extended face has properly connected seam edge. - Add new public static method BRepTools::DetectClosedness(), which checks whether a face is closed in U and V directions. --- diff --git a/src/BRepOffset/BRepOffset_Tool.cxx b/src/BRepOffset/BRepOffset_Tool.cxx index f0d32609b0..e8965ecf71 100644 --- a/src/BRepOffset/BRepOffset_Tool.cxx +++ b/src/BRepOffset/BRepOffset_Tool.cxx @@ -2430,6 +2430,8 @@ static void MakeFace(const Handle(Geom_Surface)& S, const Standard_Real UM, const Standard_Real Vm, const Standard_Real VM, + const Standard_Boolean uclosed, + const Standard_Boolean vclosed, const Standard_Boolean isVminDegen, const Standard_Boolean isVmaxDegen, TopoDS_Face& F) @@ -2438,11 +2440,6 @@ static void MakeFace(const Handle(Geom_Surface)& S, Standard_Real UMax = UM; Standard_Real VMin = Vm; Standard_Real VMax = VM; - Standard_Real epsilon = Precision::Confusion(); - - Standard_Real umin,umax,vmin,vmax; - S->Bounds(umin,umax,vmin,vmax); - // compute infinite flags Standard_Boolean umininf = Precision::IsNegativeInfinite(UMin); @@ -2450,25 +2447,6 @@ static void MakeFace(const Handle(Geom_Surface)& S, Standard_Boolean vmininf = Precision::IsNegativeInfinite(VMin); Standard_Boolean vmaxinf = Precision::IsPositiveInfinite(VMax); - // closed flag - Standard_Boolean IsSuclosed = S->IsUClosed(), IsSvclosed = S->IsVClosed(); - if (S->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface)) - { - Handle(Geom_Surface) BasisSurf = Handle(Geom_OffsetSurface)::DownCast (S)->BasisSurface(); - IsSuclosed = BasisSurf->IsUClosed(); - IsSvclosed = BasisSurf->IsVClosed(); - } - - Standard_Boolean uclosed = - IsSuclosed && - Abs(UMin - umin) < epsilon && - Abs(UMax - umax) < epsilon; - - Standard_Boolean vclosed = - IsSvclosed && - Abs(VMin - vmin) < epsilon && - Abs(VMax - vmax) < epsilon; - // degenerated flags (for cones) Standard_Boolean vmindegen = isVminDegen, vmaxdegen = isVmaxDegen; Handle(Geom_Surface) theSurf = S; @@ -2702,16 +2680,16 @@ static Standard_Boolean EnlargeGeometry(Handle(Geom_Surface)& S, const Standard_Real vf2, const Standard_Boolean GlobalEnlargeU, const Standard_Boolean GlobalEnlargeVfirst, - const Standard_Boolean GlobalEnlargeVlast) + const Standard_Boolean GlobalEnlargeVlast, + const Standard_Real coeff) { - const Standard_Real coeff = 4.; const Standard_Real TolApex = 1.e-5; Standard_Boolean SurfaceChange = Standard_False; if ( S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) { Handle(Geom_Surface) BS = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface(); EnlargeGeometry(BS,U1,U2,V1,V2,IsV1degen,IsV2degen, - uf1,uf2,vf1,vf2,GlobalEnlargeU,GlobalEnlargeVfirst,GlobalEnlargeVlast); + uf1,uf2,vf1,vf2,GlobalEnlargeU,GlobalEnlargeVfirst,GlobalEnlargeVlast,coeff); if (!GlobalEnlargeVfirst) V1 = vf1; if (!GlobalEnlargeVlast) @@ -2726,7 +2704,7 @@ static Standard_Boolean EnlargeGeometry(Handle(Geom_Surface)& S, else if (S->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface)) { Handle(Geom_Surface) Surf = Handle(Geom_OffsetSurface)::DownCast (S)->BasisSurface(); SurfaceChange = EnlargeGeometry(Surf,U1,U2,V1,V2,IsV1degen,IsV2degen, - uf1,uf2,vf1,vf2,GlobalEnlargeU,GlobalEnlargeVfirst,GlobalEnlargeVlast); + uf1,uf2,vf1,vf2,GlobalEnlargeU,GlobalEnlargeVfirst,GlobalEnlargeVlast,coeff); Handle(Geom_OffsetSurface)::DownCast(S)->SetBasisSurface(Surf); } else if (S->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion) || @@ -2752,7 +2730,7 @@ static Standard_Boolean EnlargeGeometry(Handle(Geom_Surface)& S, { viso = S->VIso( vf1 ); GeomAdaptor_Curve gac( viso ); - du = GCPnts_AbscissaPoint::Length( gac ) / coeff; + du = GCPnts_AbscissaPoint::Length( gac ) * coeff; uiso1 = S->UIso( uf1 ); uiso2 = S->UIso( uf2 ); if (BRepOffset_Tool::Gabarit( uiso1 ) <= TolApex) @@ -2773,7 +2751,7 @@ static Standard_Boolean EnlargeGeometry(Handle(Geom_Surface)& S, { uiso = S->UIso( uf1 ); GeomAdaptor_Curve gac( uiso ); - dv = GCPnts_AbscissaPoint::Length( gac ) / coeff; + dv = GCPnts_AbscissaPoint::Length( gac ) * coeff; viso1 = S->VIso( vf1 ); viso2 = S->VIso( vf2 ); if (BRepOffset_Tool::Gabarit( viso1 ) <= TolApex) @@ -2828,7 +2806,7 @@ static Standard_Boolean EnlargeGeometry(Handle(Geom_Surface)& S, { viso = S->VIso( v1 ); gac.Load( viso ); - du = GCPnts_AbscissaPoint::Length( gac ) / coeff; + du = GCPnts_AbscissaPoint::Length( gac ) * coeff; uiso1 = S->UIso( u1 ); uiso2 = S->UIso( u2 ); if (BRepOffset_Tool::Gabarit( uiso1 ) <= TolApex) @@ -2840,7 +2818,7 @@ static Standard_Boolean EnlargeGeometry(Handle(Geom_Surface)& S, { uiso = S->UIso( u1 ); gac.Load( uiso ); - dv = GCPnts_AbscissaPoint::Length( gac ) / coeff; + dv = GCPnts_AbscissaPoint::Length( gac ) * coeff; viso1 = S->VIso( v1 ); viso2 = S->VIso( v2 ); if (BRepOffset_Tool::Gabarit( viso1 ) <= TolApex) @@ -3087,7 +3065,8 @@ Standard_Boolean BRepOffset_Tool::EnLargeFace const Standard_Boolean UpdatePCurve, const Standard_Boolean enlargeU, const Standard_Boolean enlargeVfirst, - const Standard_Boolean enlargeVlast) + const Standard_Boolean enlargeVlast, + const Standard_Integer ExtensionMode) { //--------------------------- // extension de la geometrie. @@ -3109,12 +3088,27 @@ Standard_Boolean BRepOffset_Tool::EnLargeFace } S->Bounds (US1,US2,VS1,VS2); - UU1 = VV1 = - TheInfini; - UU2 = VV2 = TheInfini; + Standard_Real coeff; + if (ExtensionMode == 1) + { + UU1 = VV1 = - TheInfini; + UU2 = VV2 = TheInfini; + coeff = 0.25; + } + else + { + Standard_Real FaceDU = UF2 - UF1; + Standard_Real FaceDV = VF2 - VF1; + UU1 = UF1 - 10*FaceDU; + UU2 = UF2 + 10*FaceDU; + VV1 = VF1 - 10*FaceDV; + VV2 = VF2 + 10*FaceDV; + coeff = 1.; + } if (CanExtentSurface) { SurfaceChange = EnlargeGeometry( S, UU1, UU2, VV1, VV2, isVV1degen, isVV2degen, UF1, UF2, VF1, VF2, - enlargeU, enlargeVfirst, enlargeVlast ); + enlargeU, enlargeVfirst, enlargeVlast, coeff ); } else { UU1 = Max(US1,UU1); UU2 = Min(UU2,US2); @@ -3172,7 +3166,11 @@ Standard_Boolean BRepOffset_Tool::EnLargeFace if (!enlargeVlast) VV2 = VF2; - MakeFace(S,UU1,UU2,VV1,VV2,isVV1degen,isVV2degen,BF); + //Detect closedness in U and V directions + Standard_Boolean uclosed = Standard_False, vclosed = Standard_False; + BRepTools::DetectClosedness(F, uclosed, vclosed); + + MakeFace(S,UU1,UU2,VV1,VV2,uclosed,vclosed,isVV1degen,isVV2degen,BF); BF.Location(L); /* if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) { diff --git a/src/BRepOffset/BRepOffset_Tool.hxx b/src/BRepOffset/BRepOffset_Tool.hxx index 47e827bcdf..5ce1bc2704 100644 --- a/src/BRepOffset/BRepOffset_Tool.hxx +++ b/src/BRepOffset/BRepOffset_Tool.hxx @@ -136,13 +136,20 @@ public: //! if is TRUE, update the pcurves of the //! edges of on the new surface.if the surface has been changed, //! Returns True if The Surface of has changed. + //! is a mode of extension of the surface of the face: + //! if equals 1, potentially infinite surfaces are extended by maximum value, + //! and limited surfaces are extended by 25%. + //! if equals 2, potentially infinite surfaces are extended by + //! 10*(correspondent size of face), + //! and limited surfaces are extended by 100%. Standard_EXPORT static Standard_Boolean EnLargeFace (const TopoDS_Face& F, TopoDS_Face& NF, const Standard_Boolean ChangeGeom, const Standard_Boolean UpDatePCurve = Standard_False, const Standard_Boolean enlargeU = Standard_True, const Standard_Boolean enlargeVfirst = Standard_True, - const Standard_Boolean enlargeVlast = Standard_True); + const Standard_Boolean enlargeVlast = Standard_True, + const Standard_Integer ExtensionMode = 1); Standard_EXPORT static void ExtentFace (const TopoDS_Face& F, TopTools_DataMapOfShapeShape& ConstShapes, diff --git a/src/BRepTools/BRepTools.cxx b/src/BRepTools/BRepTools.cxx index 449a9c6530..5a707a0da1 100644 --- a/src/BRepTools/BRepTools.cxx +++ b/src/BRepTools/BRepTools.cxx @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -64,6 +65,27 @@ #include #include #include + + +//======================================================================= +//function : IsPCurveUiso +//purpose : +//======================================================================= + +static Standard_Boolean IsPCurveUiso(const Handle(Geom2d_Curve)& thePCurve, + Standard_Real theFirstPar, + Standard_Real theLastPar) +{ + gp_Pnt2d FirstP2d = thePCurve->Value(theFirstPar); + gp_Pnt2d LastP2d = thePCurve->Value(theLastPar); + + Standard_Real DeltaU = Abs(FirstP2d.X() - LastP2d.X()); + Standard_Real DeltaV = Abs(FirstP2d.Y() - LastP2d.Y()); + + return (DeltaU < DeltaV); +} + + //======================================================================= //function : UVBounds //purpose : @@ -994,6 +1016,43 @@ Standard_Boolean BRepTools::IsReallyClosed(const TopoDS_Edge& E, return nbocc == 2; } +//======================================================================= +//function : DetectClosedness +//purpose : +//======================================================================= + +void BRepTools::DetectClosedness(const TopoDS_Face& theFace, + Standard_Boolean& theUclosed, + Standard_Boolean& theVclosed) +{ + theUclosed = theVclosed = Standard_False; + + BRepAdaptor_Surface BAsurf(theFace, Standard_False); + Standard_Boolean IsSurfUclosed = BAsurf.IsUClosed(); + Standard_Boolean IsSurfVclosed = BAsurf.IsVClosed(); + if (!IsSurfUclosed && !IsSurfVclosed) + return; + + TopExp_Explorer Explo(theFace, TopAbs_EDGE); + for (; Explo.More(); Explo.Next()) + { + const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current()); + if (BRepTools::IsReallyClosed(anEdge, theFace)) + { + Standard_Real fpar, lpar; + Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface(anEdge, theFace, fpar, lpar); + Standard_Boolean IsUiso = IsPCurveUiso(aPCurve, fpar, lpar); + if (IsSurfUclosed && IsUiso) + theUclosed = Standard_True; + if (IsSurfVclosed && !IsUiso) + theVclosed = Standard_True; + + if (theUclosed && theVclosed) + break; + } + } +} + //======================================================================= //function : EvalAndUpdateTol //purpose : diff --git a/src/BRepTools/BRepTools.hxx b/src/BRepTools/BRepTools.hxx index cc49cc1044..fb0ff959a2 100644 --- a/src/BRepTools/BRepTools.hxx +++ b/src/BRepTools/BRepTools.hxx @@ -186,6 +186,11 @@ public: //! the face before calling BRep_Tool::IsClosed. Standard_EXPORT static Standard_Boolean IsReallyClosed (const TopoDS_Edge& E, const TopoDS_Face& F); + //! Detect closedness of face in U and V directions + Standard_EXPORT static void DetectClosedness (const TopoDS_Face& theFace, + Standard_Boolean& theUclosed, + Standard_Boolean& theVclosed); + //! Dumps the topological structure and the geometry //! of on the stream . Standard_EXPORT static void Dump (const TopoDS_Shape& Sh, Standard_OStream& S);