0029591: Improvements in the class BRepOffset_Tool
authorjgv <jgv@opencascade.com>
Fri, 23 Mar 2018 13:08:11 +0000 (16:08 +0300)
committerbugmaster <bugmaster@opencascade.com>
Mon, 9 Apr 2018 08:07:37 +0000 (11:07 +0300)
- 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.

src/BRepOffset/BRepOffset_Tool.cxx
src/BRepOffset/BRepOffset_Tool.hxx
src/BRepTools/BRepTools.cxx
src/BRepTools/BRepTools.hxx

index f0d3260..e8965ec 100644 (file)
@@ -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)) {
index 47e827b..5ce1bc2 100644 (file)
@@ -136,13 +136,20 @@ public:
   //! if <UpdatePCurve>  is  TRUE, update the  pcurves of the
   //! edges of <F> on   the new surface.if the surface has  been changed,
   //! Returns  True if The Surface of  <NF> has changed.
+  //! <ExtensionMode> is a mode of extension of the surface of the face:
+  //! if <ExtensionMode> equals 1, potentially infinite surfaces are extended by maximum value,
+  //! and limited surfaces are extended by 25%.
+  //! if <ExtensionMode> 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,
index 449a9c6..5a707a0 100644 (file)
@@ -25,6 +25,7 @@
 #include <BRepTools.hxx>
 #include <BRepTools_MapOfVertexPnt2d.hxx>
 #include <BRepTools_ShapeSet.hxx>
+#include <BRepAdaptor_Surface.hxx>
 #include <ElCLib.hxx>
 #include <Geom2d_Curve.hxx>
 #include <Geom2dAdaptor_Curve.hxx>
 #include <TopTools_SequenceOfShape.hxx>
 #include <GeomLib_CheckCurveOnSurface.hxx>
 #include <errno.h>
+
+
+//=======================================================================
+//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  : 
@@ -995,6 +1017,43 @@ Standard_Boolean BRepTools::IsReallyClosed(const TopoDS_Edge& E,
 }
 
 //=======================================================================
+//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  : 
 //=======================================================================
index cc49cc1..fb0ff95 100644 (file)
@@ -186,6 +186,11 @@ public:
   //! the face <F> 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 <Sh> on the stream <S>.
   Standard_EXPORT static void Dump (const TopoDS_Shape& Sh, Standard_OStream& S);