0030391: Improvement of the method BRepOffset_Tool::EnLargeFace
authorjgv <jgv@opencascade.com>
Mon, 3 Dec 2018 10:58:20 +0000 (13:58 +0300)
committerapn <apn@opencascade.com>
Tue, 11 Dec 2018 16:15:54 +0000 (19:15 +0300)
Add options to set the length of enlargement for each of 4 directions.
Add restriction of enlargement in the case of singularity on the surface.

src/BRepOffset/BRepOffset_Tool.cxx
src/BRepOffset/BRepOffset_Tool.hxx
src/QABugs/QABugs_20.cxx
tests/bugs/modalg_7/bug30391_1 [new file with mode: 0644]
tests/bugs/modalg_7/bug30391_2 [new file with mode: 0644]
tests/bugs/modalg_7/bug30391_3 [new file with mode: 0644]

index e8965ec..bd5e98a 100644 (file)
@@ -2667,21 +2667,25 @@ static void MakeFace(const Handle(Geom_Surface)& S,
 //purpose  : 
 //=======================================================================
 
-static Standard_Boolean EnlargeGeometry(Handle(Geom_Surface)& S,
-                                       Standard_Real&        U1,
-                                       Standard_Real&        U2,
-                                       Standard_Real&        V1,
-                                       Standard_Real&        V2,
-                                       Standard_Boolean&     IsV1degen,
-                                       Standard_Boolean&     IsV2degen,
-                                       const Standard_Real   uf1,
-                                       const Standard_Real   uf2,
-                                       const Standard_Real   vf1,
-                                       const Standard_Real   vf2,
-                                       const Standard_Boolean GlobalEnlargeU,
-                                       const Standard_Boolean GlobalEnlargeVfirst,
-                                       const Standard_Boolean GlobalEnlargeVlast,
-                                        const Standard_Real    coeff)
+static Standard_Boolean EnlargeGeometry(Handle(Geom_Surface)&  S,
+                                       Standard_Real&         U1,
+                                       Standard_Real&         U2,
+                                       Standard_Real&         V1,
+                                       Standard_Real&         V2,
+                                       Standard_Boolean&      IsV1degen,
+                                       Standard_Boolean&      IsV2degen,
+                                       const Standard_Real    uf1,
+                                       const Standard_Real    uf2,
+                                       const Standard_Real    vf1,
+                                       const Standard_Real    vf2,
+                                        const Standard_Real    coeff,
+                                       const Standard_Boolean theGlobalEnlargeU,
+                                       const Standard_Boolean theGlobalEnlargeVfirst,
+                                       const Standard_Boolean theGlobalEnlargeVlast,
+                                        const Standard_Real    theLenBeforeUfirst,
+                                        const Standard_Real    theLenAfterUlast,
+                                        const Standard_Real    theLenBeforeVfirst,
+                                        const Standard_Real    theLenAfterVlast)
 {
   const Standard_Real TolApex = 1.e-5;
 
@@ -2689,12 +2693,14 @@ static Standard_Boolean EnlargeGeometry(Handle(Geom_Surface)& S,
   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,coeff);
-    if (!GlobalEnlargeVfirst)
+                   uf1,uf2,vf1,vf2,coeff,
+                    theGlobalEnlargeU, theGlobalEnlargeVfirst, theGlobalEnlargeVlast,
+                    theLenBeforeUfirst, theLenAfterUlast, theLenBeforeVfirst, theLenAfterVlast);
+    if (!theGlobalEnlargeVfirst)
       V1 = vf1;
-    if (!GlobalEnlargeVlast)
+    if (!theGlobalEnlargeVlast)
       V2 = vf2;
-    if (!GlobalEnlargeVfirst || !GlobalEnlargeVlast)
+    if (!theGlobalEnlargeVfirst || !theGlobalEnlargeVlast)
       //Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->SetTrim( U1, U2, V1, V2 );
       S = new Geom_RectangularTrimmedSurface( BS, U1, U2, V1, V2 );
     else
@@ -2704,159 +2710,178 @@ 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,coeff);
+                                   uf1,uf2,vf1,vf2,coeff,
+                                    theGlobalEnlargeU, theGlobalEnlargeVfirst, theGlobalEnlargeVlast,
+                                    theLenBeforeUfirst, theLenAfterUlast, theLenBeforeVfirst, theLenAfterVlast);
     Handle(Geom_OffsetSurface)::DownCast(S)->SetBasisSurface(Surf);
   }
   else if (S->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion) ||
           S->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfRevolution))
+  {
+    Standard_Real du_first = 0., du_last = 0.,
+      dv_first = 0., dv_last = 0.;
+    Handle( Geom_Curve ) uiso, viso, uiso1, uiso2, viso1, viso2;
+    Standard_Real u1, u2, v1, v2;
+    Standard_Boolean enlargeU = theGlobalEnlargeU, enlargeV = Standard_True;
+    Standard_Boolean enlargeUfirst = enlargeU, enlargeUlast = enlargeU;
+    Standard_Boolean enlargeVfirst = theGlobalEnlargeVfirst, enlargeVlast = theGlobalEnlargeVlast;
+    S->Bounds( u1, u2, v1, v2 );
+    if (Precision::IsInfinite(u1) || Precision::IsInfinite(u2))
     {
-      Standard_Real du=0., dv=0.;
-      Handle( Geom_Curve ) uiso, viso, uiso1, uiso2, viso1, viso2;
-      Standard_Real u1, u2, v1, v2;
-      Standard_Boolean enlargeU = GlobalEnlargeU, enlargeV = Standard_True;
-      Standard_Boolean enlargeUfirst = enlargeU, enlargeUlast = enlargeU;
-      Standard_Boolean enlargeVfirst = GlobalEnlargeVfirst, enlargeVlast = GlobalEnlargeVlast;
-      S->Bounds( u1, u2, v1, v2 );
-      if (Precision::IsInfinite(u1) || Precision::IsInfinite(u2))
-       {
-         du = uf2-uf1;
-         u1 = uf1-du;
-         u2 = uf2+du;
-         enlargeU = Standard_False;
-       }
-      else if (S->IsUClosed())
-       enlargeU = Standard_False;
-      else
-       {
-         viso = S->VIso( vf1 );
-         GeomAdaptor_Curve gac( viso );
-         du = GCPnts_AbscissaPoint::Length( gac ) * coeff;
-         uiso1 = S->UIso( uf1 );
-         uiso2 = S->UIso( uf2 );
-         if (BRepOffset_Tool::Gabarit( uiso1 ) <= TolApex)
-           enlargeUfirst = Standard_False;
-         if (BRepOffset_Tool::Gabarit( uiso2 ) <= TolApex)
-           enlargeUlast = Standard_False;
-       }
-      if (Precision::IsInfinite(v1) || Precision::IsInfinite(v2))
-       {
-         dv = vf2-vf1;
-         v1 = vf1-dv;
-         v2 = vf2+dv;
-         enlargeV = Standard_False;
-       }
-      else if (S->IsVClosed())
-       enlargeV = Standard_False;
-      else
-       {
-         uiso = S->UIso( uf1 );
-         GeomAdaptor_Curve gac( uiso );
-         dv = GCPnts_AbscissaPoint::Length( gac ) * coeff;
-         viso1 = S->VIso( vf1 );
-         viso2 = S->VIso( vf2 );
-         if (BRepOffset_Tool::Gabarit( viso1 ) <= TolApex)
-           {
-             enlargeVfirst = Standard_False;
-             IsV1degen = Standard_True;
-           }
-         if (BRepOffset_Tool::Gabarit( viso2 ) <= TolApex)
-           {
-             enlargeVlast = Standard_False;
-             IsV2degen = Standard_True;
-           }
-       }
-      Handle(Geom_BoundedSurface) aSurf = new Geom_RectangularTrimmedSurface( S, u1, u2, v1, v2 );
-      if (enlargeU)
-       {
-         if (enlargeUfirst)
-           GeomLib::ExtendSurfByLength (aSurf, du, 1, Standard_True, Standard_False);
-         if (enlargeUlast)
-           GeomLib::ExtendSurfByLength (aSurf, du, 1, Standard_True, Standard_True);
-       }
-      if (enlargeV)
-       {
-         if (enlargeVfirst)
-           GeomLib::ExtendSurfByLength (aSurf, dv, 1, Standard_False, Standard_False);
-         if (enlargeVlast)
-           GeomLib::ExtendSurfByLength (aSurf, dv, 1, Standard_False, Standard_True);
-       }
-      S = aSurf;
-      S->Bounds( U1, U2, V1, V2 );
-      SurfaceChange = Standard_True;
+      du_first = du_last = uf2-uf1;
+      u1 = uf1 - du_first;
+      u2 = uf2 + du_last;
+      enlargeU = Standard_False;
+    }
+    else if (S->IsUClosed())
+      enlargeU = Standard_False;
+    else
+    {
+      viso = S->VIso( vf1 );
+      GeomAdaptor_Curve gac( viso );
+      Standard_Real du_default = GCPnts_AbscissaPoint::Length( gac ) * coeff;
+      du_first = (theLenBeforeUfirst == -1)? du_default : theLenBeforeUfirst;
+      du_last  = (theLenAfterUlast == -1)? du_default : theLenAfterUlast;
+      uiso1 = S->UIso( uf1 );
+      uiso2 = S->UIso( uf2 );
+      if (BRepOffset_Tool::Gabarit( uiso1 ) <= TolApex)
+        enlargeUfirst = Standard_False;
+      if (BRepOffset_Tool::Gabarit( uiso2 ) <= TolApex)
+        enlargeUlast = Standard_False;
+    }
+    if (Precision::IsInfinite(v1) || Precision::IsInfinite(v2))
+    {
+      dv_first = dv_last = vf2-vf1;
+      v1 = vf1 - dv_first;
+      v2 = vf2 + dv_last;
+      enlargeV = Standard_False;
+    }
+    else if (S->IsVClosed())
+      enlargeV = Standard_False;
+    else
+    {
+      uiso = S->UIso( uf1 );
+      GeomAdaptor_Curve gac( uiso );
+      Standard_Real dv_default = GCPnts_AbscissaPoint::Length( gac ) * coeff;
+      dv_first = (theLenBeforeVfirst == -1)? dv_default : theLenBeforeVfirst;
+      dv_last  = (theLenAfterVlast == -1)? dv_default : theLenAfterVlast;
+      viso1 = S->VIso( vf1 );
+      viso2 = S->VIso( vf2 );
+      if (BRepOffset_Tool::Gabarit( viso1 ) <= TolApex)
+      {
+        enlargeVfirst = Standard_False;
+        IsV1degen = Standard_True;
+      }
+      if (BRepOffset_Tool::Gabarit( viso2 ) <= TolApex)
+      {
+        enlargeVlast = Standard_False;
+        IsV2degen = Standard_True;
+      }
     }
+    Handle(Geom_BoundedSurface) aSurf = new Geom_RectangularTrimmedSurface( S, u1, u2, v1, v2 );
+    if (enlargeU)
+    {
+      if (enlargeUfirst && du_first != 0.)
+        GeomLib::ExtendSurfByLength (aSurf, du_first, 1, Standard_True, Standard_False);
+      if (enlargeUlast && du_last != 0.)
+        GeomLib::ExtendSurfByLength (aSurf, du_last, 1, Standard_True, Standard_True);
+    }
+    if (enlargeV)
+    {
+      if (enlargeVfirst && dv_first != 0.)
+        GeomLib::ExtendSurfByLength (aSurf, dv_first, 1, Standard_False, Standard_False);
+      if (enlargeVlast && dv_last != 0.)
+        GeomLib::ExtendSurfByLength (aSurf, dv_last, 1, Standard_False, Standard_True);
+    }
+    S = aSurf;
+    S->Bounds( U1, U2, V1, V2 );
+    SurfaceChange = Standard_True;
+  }
   else if (S->DynamicType() == STANDARD_TYPE(Geom_BezierSurface) ||
           S->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface))
+  {
+    Standard_Boolean enlargeU = theGlobalEnlargeU, enlargeV = Standard_True;
+    Standard_Boolean enlargeUfirst = enlargeU, enlargeUlast = enlargeU;
+    Standard_Boolean enlargeVfirst = theGlobalEnlargeVfirst, enlargeVlast = theGlobalEnlargeVlast;
+    if (S->IsUClosed())
+      enlargeU = Standard_False;
+    if (S->IsVClosed())
+      enlargeV = Standard_False;
+    
+    Standard_Real duf = uf2-uf1, dvf = vf2-vf1;
+    Standard_Real u1, u2, v1, v2;
+    S->Bounds( u1, u2, v1, v2 );
+    
+    Standard_Real du_first = 0., du_last = 0.,
+      dv_first = 0., dv_last = 0.;
+    Handle( Geom_Curve ) uiso1, uiso2, viso1, viso2;
+    Standard_Real gabarit_uiso1, gabarit_uiso2, gabarit_viso1, gabarit_viso2;
+
+    uiso1 = S->UIso( u1 );
+    uiso2 = S->UIso( u2 );
+    viso1 = S->VIso( v1 );
+    viso2 = S->VIso( v2 );
+    gabarit_uiso1 = BRepOffset_Tool::Gabarit( uiso1 );
+    gabarit_uiso2 = BRepOffset_Tool::Gabarit( uiso2 );
+    gabarit_viso1 = BRepOffset_Tool::Gabarit( viso1 );
+    gabarit_viso2 = BRepOffset_Tool::Gabarit( viso2 );
+    if (gabarit_viso1 <= TolApex ||
+        gabarit_viso2 <= TolApex)
+      enlargeU = Standard_False;
+    if (gabarit_uiso1 <= TolApex ||
+        gabarit_uiso2 <= TolApex)
+      enlargeV = Standard_False;
+    
+    GeomAdaptor_Curve gac;
+    if (enlargeU)
     {
-      Standard_Boolean enlargeU = GlobalEnlargeU, enlargeV = Standard_True;
-      Standard_Boolean enlargeUfirst = enlargeU, enlargeUlast = enlargeU;
-      Standard_Boolean enlargeVfirst = GlobalEnlargeVfirst, enlargeVlast = GlobalEnlargeVlast;
-      if (S->IsUClosed())
-       enlargeU = Standard_False;
-      if (S->IsVClosed())
-       enlargeV = Standard_False;
-
-      Standard_Real duf = uf2-uf1, dvf = vf2-vf1;
-      Standard_Real u1, u2, v1, v2;
-      S->Bounds( u1, u2, v1, v2 );
-
-      Standard_Real du=0., dv=0.;
-      Handle( Geom_Curve ) uiso, viso, uiso1, uiso2, viso1, viso2;
-      GeomAdaptor_Curve gac;
-      if (enlargeU)
-       {
-         viso = S->VIso( v1 );
-         gac.Load( viso );
-         du = GCPnts_AbscissaPoint::Length( gac ) * coeff;
-         uiso1 = S->UIso( u1 );
-         uiso2 = S->UIso( u2 );
-         if (BRepOffset_Tool::Gabarit( uiso1 ) <= TolApex)
-           enlargeUfirst = Standard_False;
-         if (BRepOffset_Tool::Gabarit( uiso2 ) <= TolApex)
-           enlargeUlast = Standard_False;
-       }
-      if (enlargeV)
-       {
-         uiso = S->UIso( u1 );
-         gac.Load( uiso );
-         dv = GCPnts_AbscissaPoint::Length( gac ) * coeff;
-         viso1 = S->VIso( v1 );
-         viso2 = S->VIso( v2 );
-         if (BRepOffset_Tool::Gabarit( viso1 ) <= TolApex)
-           {
-             enlargeVfirst = Standard_False;
-             IsV1degen = Standard_True;
-           }
-         if (BRepOffset_Tool::Gabarit( viso2 ) <= TolApex)
-           {
-             enlargeVlast = Standard_False;
-             IsV2degen = Standard_True;
-           }
-       }
-
-      Handle(Geom_BoundedSurface) aSurf = Handle(Geom_BoundedSurface)::DownCast (S);
-      if (enlargeU)
-       {
-         if (enlargeUfirst && uf1-u1 < duf)
-           GeomLib::ExtendSurfByLength (aSurf, du, 1, Standard_True, Standard_False);
-         if (enlargeUlast && u2-uf2 < duf)
-           GeomLib::ExtendSurfByLength (aSurf, du, 1, Standard_True, Standard_True);
-       }
-      if (enlargeV)
-       {
-         if (enlargeVfirst && vf1-v1 < dvf)
-           GeomLib::ExtendSurfByLength (aSurf, dv, 1, Standard_False, Standard_False);
-         if (enlargeVlast && v2-vf2 < dvf)
-           GeomLib::ExtendSurfByLength (aSurf, dv, 1, Standard_False, Standard_True);
-       }
-      S = aSurf;
-
-      S->Bounds( U1, U2, V1, V2 );
-      SurfaceChange = Standard_True;
+      gac.Load( viso1 );
+      Standard_Real du_default = GCPnts_AbscissaPoint::Length( gac ) * coeff;
+      du_first = (theLenBeforeUfirst == -1)? du_default : theLenBeforeUfirst;
+      du_last  = (theLenAfterUlast == -1)? du_default : theLenAfterUlast;
+      if (gabarit_uiso1 <= TolApex)
+        enlargeUfirst = Standard_False;
+      if (gabarit_uiso2 <= TolApex)
+        enlargeUlast = Standard_False;
+    }
+    if (enlargeV)
+    {
+      gac.Load( uiso1 );
+      Standard_Real dv_default = GCPnts_AbscissaPoint::Length( gac ) * coeff;
+      dv_first = (theLenBeforeVfirst == -1)? dv_default : theLenBeforeVfirst;
+      dv_last  = (theLenAfterVlast == -1)? dv_default : theLenAfterVlast;
+      if (gabarit_viso1 <= TolApex)
+      {
+        enlargeVfirst = Standard_False;
+        IsV1degen = Standard_True;
+      }
+      if (gabarit_viso2 <= TolApex)
+      {
+        enlargeVlast = Standard_False;
+        IsV2degen = Standard_True;
+      }
     }
-//  else if (S->DynamicType() == STANDARD_TYPE(Geom_BezierSurface) ||
-//        S->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface)) {
-//    S->Bounds(U1,U2,V1,V2);
-//  }
+    
+    Handle(Geom_BoundedSurface) aSurf = Handle(Geom_BoundedSurface)::DownCast (S);
+    if (enlargeU)
+    {
+      if (enlargeUfirst && uf1-u1 < duf && du_first != 0.)
+        GeomLib::ExtendSurfByLength (aSurf, du_first, 1, Standard_True, Standard_False);
+      if (enlargeUlast && u2-uf2 < duf && du_last != 0.)
+        GeomLib::ExtendSurfByLength (aSurf, du_last, 1, Standard_True, Standard_True);
+    }
+    if (enlargeV)
+    {
+      if (enlargeVfirst && vf1-v1 < dvf && dv_first != 0.)
+        GeomLib::ExtendSurfByLength (aSurf, dv_first, 1, Standard_False, Standard_False);
+      if (enlargeVlast && v2-vf2 < dvf && dv_last != 0.)
+        GeomLib::ExtendSurfByLength (aSurf, dv_last, 1, Standard_False, Standard_True);
+    }
+    S = aSurf;
+    
+    S->Bounds( U1, U2, V1, V2 );
+    SurfaceChange = Standard_True;
+  }
   else { 
     Standard_Real UU1,UU2,VV1,VV2;
     S->Bounds(UU1,UU2,VV1,VV2);
@@ -3063,10 +3088,14 @@ Standard_Boolean BRepOffset_Tool::EnLargeFace
  TopoDS_Face&             BF,
  const Standard_Boolean   CanExtentSurface,
  const Standard_Boolean   UpdatePCurve,
- const Standard_Boolean   enlargeU,
- const Standard_Boolean   enlargeVfirst,
- const Standard_Boolean   enlargeVlast,
- const Standard_Integer   ExtensionMode)
+ const Standard_Boolean   theEnlargeU,
+ const Standard_Boolean   theEnlargeVfirst,
+ const Standard_Boolean   theEnlargeVlast,
+ const Standard_Integer   theExtensionMode,
+ const Standard_Real      theLenBeforeUfirst,
+ const Standard_Real      theLenAfterUlast,
+ const Standard_Real      theLenBeforeVfirst,
+ const Standard_Real      theLenAfterVlast)
 {
   //---------------------------
   // extension de la geometrie.
@@ -3089,7 +3118,7 @@ Standard_Boolean BRepOffset_Tool::EnLargeFace
 
   S->Bounds            (US1,US2,VS1,VS2);
   Standard_Real coeff;
-  if (ExtensionMode == 1)
+  if (theExtensionMode == 1)
   {
     UU1 = VV1 = - TheInfini;
     UU2 = VV2 =   TheInfini;
@@ -3107,8 +3136,9 @@ Standard_Boolean BRepOffset_Tool::EnLargeFace
   }
   
   if (CanExtentSurface) {
-    SurfaceChange = EnlargeGeometry( S, UU1, UU2, VV1, VV2, isVV1degen, isVV2degen, UF1, UF2, VF1, VF2,
-                                    enlargeU, enlargeVfirst, enlargeVlast, coeff );
+    SurfaceChange = EnlargeGeometry(S, UU1, UU2, VV1, VV2, isVV1degen, isVV2degen, UF1, UF2, VF1, VF2, coeff,
+                                    theEnlargeU, theEnlargeVfirst, theEnlargeVlast,
+                                    theLenBeforeUfirst, theLenAfterUlast, theLenBeforeVfirst, theLenAfterVlast);
   }
   else {
     UU1 = Max(US1,UU1); UU2 = Min(UU2,US2); 
@@ -3157,13 +3187,13 @@ Standard_Boolean BRepOffset_Tool::EnLargeFace
        }
     }
 
-  if (!enlargeU)
+  if (!theEnlargeU)
     {
       UU1 = UF1; UU2 = UF2;
     }
-  if (!enlargeVfirst)
+  if (!theEnlargeVfirst)
     VV1 = VF1;
-  if (!enlargeVlast)
+  if (!theEnlargeVlast)
     VV2 = VF2;
 
   //Detect closedness in U and V directions
index 5ce1bc2..82c4ba3 100644 (file)
@@ -131,17 +131,22 @@ public:
                                            Standard_Boolean& enlargeVfirst,
                                            Standard_Boolean& enlargeVlast);
   
+  //! Returns  True if The Surface of  <NF> has changed.
   //! if <ChangeGeom> is TRUE  ,   the surface  can  be
   //! changed .
   //! 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,
+  //! edges of <F> on   the new surface if the surface has  been changed.
+  //! <enlargeU>, <enlargeVfirst>, <enlargeVlast> allow or forbid
+  //! enlargement in U and V directions correspondingly.
+  //! <theExtensionMode> is a mode of extension of the surface of the face:
+  //! if <theExtensionMode> 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
+  //! if <theExtensionMode> equals 2, potentially infinite surfaces are extended by
   //! 10*(correspondent size of face),
   //! and limited surfaces are extended by 100%.
+  //! <theLenBeforeUfirst>, <theLenAfterUlast>, <theLenBeforeVfirst>, <theLenAfterVlast>
+  //! set the values of enlargement on correspondent directions.
+  //! If some of them equals -1, the default value of enlargement is used.
   Standard_EXPORT static Standard_Boolean EnLargeFace (const TopoDS_Face& F,
                                                        TopoDS_Face& NF,
                                                        const Standard_Boolean ChangeGeom,
@@ -149,7 +154,11 @@ public:
                                                        const Standard_Boolean enlargeU = Standard_True,
                                                        const Standard_Boolean enlargeVfirst = Standard_True,
                                                        const Standard_Boolean enlargeVlast = Standard_True,
-                                                       const Standard_Integer ExtensionMode = 1);
+                                                       const Standard_Integer theExtensionMode = 1,
+                                                       const Standard_Real    theLenBeforeUfirst = -1.,
+                                                       const Standard_Real    theLenAfterUlast   = -1.,
+                                                       const Standard_Real    theLenBeforeVfirst = -1.,
+                                                       const Standard_Real    theLenAfterVlast   = -1.);
   
   Standard_EXPORT static void ExtentFace (const TopoDS_Face& F,
                                           TopTools_DataMapOfShapeShape& ConstShapes,
index 33a58bf..f391265 100644 (file)
@@ -3024,6 +3024,42 @@ static Standard_Integer OCC29311 (Draw_Interpretor& theDI, Standard_Integer theA
   return 0;
 }
 
+//=======================================================================
+//function : OCC30391
+//purpose  : 
+//=======================================================================
+#include <BRepOffset_Tool.hxx>
+static Standard_Integer OCC30391(Draw_Interpretor& theDI,
+                                 Standard_Integer theNArg,
+                                 const char** theArgV)
+{
+  if (theNArg < 7)
+  {
+    theDI << "Use: " << theArgV[0] << "result face LenBeforeUfirst LenAfterUlast LenBeforeVfirst LenAfterVlast\n";
+    return 1;
+  }
+
+  TopoDS_Shape aShape = DBRep::Get(theArgV[2], TopAbs_FACE);
+  if (aShape.IsNull())
+    return 1;
+
+  const TopoDS_Face& aFace = TopoDS::Face(aShape);
+
+  Standard_Real aLenBeforeUfirst = atof(theArgV[3]);
+  Standard_Real aLenAfterUlast   = atof(theArgV[4]);
+  Standard_Real aLenBeforeVfirst = atof(theArgV[5]);
+  Standard_Real aLenAfterVlast   = atof(theArgV[6]);
+
+  TopoDS_Face Result;
+  BRepOffset_Tool::EnLargeFace(aFace, Result,
+                               Standard_True,Standard_True,Standard_True,Standard_True,Standard_True,1,
+                               aLenBeforeUfirst, aLenAfterUlast,
+                               aLenBeforeVfirst, aLenAfterVlast);
+
+  DBRep::Set(theArgV[1], Result);
+  return 0;
+}
+
 void QABugs::Commands_20(Draw_Interpretor& theCommands) {
   const char *group = "QABugs";
 
@@ -3063,6 +3099,7 @@ void QABugs::Commands_20(Draw_Interpretor& theCommands) {
   theCommands.Add ("OCC29925", "OCC29925: check safety of character classification functions", __FILE__, OCC29925, group);
   theCommands.Add("OCC29807", "OCC29807 surface1 surface2 u1 v1 u2 v2", __FILE__, OCC29807, group);
   theCommands.Add("OCC29311", "OCC29311 shape counter nbiter: check performance of OBB calculation", __FILE__, OCC29311, group);
+  theCommands.Add("OCC30391", "OCC30391 result face LenBeforeUfirst LenAfterUlast LenBeforeVfirst LenAfterVlast", __FILE__, OCC30391, group);
 
   return;
 }
diff --git a/tests/bugs/modalg_7/bug30391_1 b/tests/bugs/modalg_7/bug30391_1
new file mode 100644 (file)
index 0000000..a9e92b6
--- /dev/null
@@ -0,0 +1,12 @@
+puts "================================================================"
+puts "OCC30391: Improvement of the method BRepOffset_Tool::EnLargeFace"
+puts "================================================================"
+puts ""
+
+pload QAcommands
+
+restore [locate_data_file bug30391_face1.brep] a
+
+OCC30391 result a 0 0 20 20
+
+checkprops result -s 98393.6
diff --git a/tests/bugs/modalg_7/bug30391_2 b/tests/bugs/modalg_7/bug30391_2
new file mode 100644 (file)
index 0000000..d56dcac
--- /dev/null
@@ -0,0 +1,12 @@
+puts "================================================================"
+puts "OCC30391: Improvement of the method BRepOffset_Tool::EnLargeFace"
+puts "================================================================"
+puts ""
+
+pload QAcommands
+
+restore [locate_data_file bug30391_face2.brep] a
+
+OCC30391 result a 0 10 10 0
+
+checkprops result -s 172862
diff --git a/tests/bugs/modalg_7/bug30391_3 b/tests/bugs/modalg_7/bug30391_3
new file mode 100644 (file)
index 0000000..111e64c
--- /dev/null
@@ -0,0 +1,12 @@
+puts "================================================================"
+puts "OCC30391: Improvement of the method BRepOffset_Tool::EnLargeFace"
+puts "================================================================"
+puts ""
+
+pload QAcommands
+
+restore [locate_data_file bug30391_face3.brep] a
+
+OCC30391 result a 1. 1. 1. 1.
+
+checkprops result -s 1.60173