From bdd09cfaf4fe4d7643d0c1c3d1d4cf9e8037a32a Mon Sep 17 00:00:00 2001
From: ifv <ifv@opencascade.com>
Date: Wed, 18 Dec 2019 13:53:11 +0300
Subject: [PATCH] 0031242: Scaling with different coefficients along axes
 produces invalid shape

GeomConvert_1.cxx:
Creation periodic BSpline surfaces from trimmed periodic surface if trim is boundaries of periodic domain is allowed

BRepTools_NurbsConvertModification.cxx:
Checking domain of 2dCurves if surfaces are periodic is added

Test case tests/bugs/mesh/bug30008_2 is modified according to current behavior

Test case tests/bugs/modalg_7/bug31242 is added
---
 .../BRepTools_NurbsConvertModification.cxx        | 15 +++++++++++++++
 src/GeomConvert/GeomConvert_1.cxx                 | 14 +++++++++-----
 tests/bugs/mesh/bug30008_2                        |  2 +-
 tests/bugs/modalg_7/bug31242                      | 13 +++++++++++++
 4 files changed, 38 insertions(+), 6 deletions(-)
 create mode 100644 tests/bugs/modalg_7/bug31242

diff --git a/src/BRepTools/BRepTools_NurbsConvertModification.cxx b/src/BRepTools/BRepTools_NurbsConvertModification.cxx
index 1a8de56f7e..101a548f5a 100644
--- a/src/BRepTools/BRepTools_NurbsConvertModification.cxx
+++ b/src/BRepTools/BRepTools_NurbsConvertModification.cxx
@@ -482,6 +482,8 @@ Standard_Boolean BRepTools_NurbsConvertModification::NewCurve2d
       }
       return Standard_True;
     }
+
+    //
     GeomAdaptor_Surface GAS(S,Uinf-u,Usup+u,Vinf-v,Vsup+v);
 
     Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(GAS);
@@ -490,6 +492,19 @@ Standard_Boolean BRepTools_NurbsConvertModification::NewCurve2d
 
     if(ProjOnCurve.IsDone()) {
       Curve2d = ProjOnCurve.BSpline();
+      if (S->IsUPeriodic() || S->IsVPeriodic())
+      {
+        //Surface is periodic, checking curve2d domain 
+        //Old domain
+        gp_Pnt2d aPf = C2d->Value(f2d);
+        //New domain
+        gp_Pnt2d aNewPf = Curve2d->Value(f2d);
+        gp_Vec2d aT(aNewPf, aPf);
+        if (aT.SquareMagnitude() > Precision::SquarePConfusion())
+        {
+          Curve2d = Handle(Geom2d_Curve)::DownCast(Curve2d->Translated(aT));
+        }
+      }
       Standard_Real newTol = BRepTools::EvalAndUpdateTol(newE, C3d, Curve2d, S, f3d, l3d);
       if(newTol > Tol)
       {
diff --git a/src/GeomConvert/GeomConvert_1.cxx b/src/GeomConvert/GeomConvert_1.cxx
index b8ec250f24..548a89cb3e 100644
--- a/src/GeomConvert/GeomConvert_1.cxx
+++ b/src/GeomConvert/GeomConvert_1.cxx
@@ -329,6 +329,7 @@ Handle(Geom_BSplineSurface) GeomConvert::SplitBSplineSurface
 Handle(Geom_BSplineSurface) GeomConvert::SurfaceToBSplineSurface
   (const Handle(Geom_Surface)& Sr) 
 {
+ 
   Standard_Real U1, U2, V1, V2;
   Sr->Bounds (U1, U2, V1, V2);
   Standard_Real UFirst = Min (U1, U2);
@@ -380,7 +381,10 @@ Handle(Geom_BSplineSurface) GeomConvert::SurfaceToBSplineSurface
         VFirst, VLast);
       return SurfaceToBSplineSurface(aStrim);
     }
-
+    //
+    //For cylinders, cones, spheres, toruses
+    const Standard_Boolean isUClosed = Abs((ULast - UFirst) - 2. * M_PI) <= Precision::PConfusion();
+    //
     if (Surf->IsKind(STANDARD_TYPE(Geom_Plane))) {
       TColgp_Array2OfPnt Poles (1, 2, 1, 2);
       Poles (1, 1) = Strim->Value (U1, V1);
@@ -409,7 +413,7 @@ Handle(Geom_BSplineSurface) GeomConvert::SurfaceToBSplineSurface
         Handle(Geom_CylindricalSurface)::DownCast(Surf);
 
       gp_Cylinder Cyl = TheElSurf->Cylinder();
-      if (Strim->IsUClosed()) {
+      if (isUClosed) {
         Convert_CylinderToBSplineSurface Convert (Cyl, VFirst, VLast);
         TheSurface = BSplineSurfaceBuilder (Convert);
       }
@@ -425,7 +429,7 @@ Handle(Geom_BSplineSurface) GeomConvert::SurfaceToBSplineSurface
       Handle(Geom_ConicalSurface) TheElSurf = 
         Handle(Geom_ConicalSurface)::DownCast(Surf);
       gp_Cone Co = TheElSurf->Cone();
-      if (Strim->IsUClosed()) {
+      if (isUClosed) {
         Convert_ConeToBSplineSurface Convert (Co, VFirst, VLast);
         TheSurface = BSplineSurfaceBuilder (Convert);
       }
@@ -442,7 +446,7 @@ Handle(Geom_BSplineSurface) GeomConvert::SurfaceToBSplineSurface
         Handle(Geom_SphericalSurface)::DownCast(Surf);
       gp_Sphere Sph = TheElSurf->Sphere();
       //OCC217
-      if (Strim->IsUClosed()) {
+      if (isUClosed) {
         //if (Strim->IsVClosed()) {
         //Convert_SphereToBSplineSurface Convert (Sph, UFirst, ULast);
         Convert_SphereToBSplineSurface Convert (Sph, VFirst, VLast, Standard_False);
@@ -461,7 +465,7 @@ Handle(Geom_BSplineSurface) GeomConvert::SurfaceToBSplineSurface
         Handle(Geom_ToroidalSurface)::DownCast(Surf);
 
       gp_Torus Tr = TheElSurf->Torus();
-      if (Strim->IsUClosed()) { 
+      if (isUClosed) {
         Convert_TorusToBSplineSurface Convert (Tr, VFirst, VLast, 
           Standard_False);
         TheSurface = BSplineSurfaceBuilder (Convert);
diff --git a/tests/bugs/mesh/bug30008_2 b/tests/bugs/mesh/bug30008_2
index e7997c15bc..4c2467a352 100644
--- a/tests/bugs/mesh/bug30008_2
+++ b/tests/bugs/mesh/bug30008_2
@@ -19,7 +19,7 @@ nurbsconvert result result
 incmesh result 0.15 -a 20
 
 tricheck result
-checktrinfo result -tri 193 -nod 147 -defl 0.04209 -tol_abs_defl 1.0e-6
+checktrinfo result -tri 191 -nod 146 -defl 0.0362596 -tol_abs_defl 1.0e-6
 
 vinit
 
diff --git a/tests/bugs/modalg_7/bug31242 b/tests/bugs/modalg_7/bug31242
new file mode 100644
index 0000000000..e770d27122
--- /dev/null
+++ b/tests/bugs/modalg_7/bug31242
@@ -0,0 +1,13 @@
+puts "======================================================="
+puts "0031242: Scaling with different coefficients along axes produces invalid shape"
+puts "======================================================="
+puts ""
+
+restore [locate_data_file bug31242.brep] f
+
+scalexyz result f 1 1 0.25
+
+checkshape result
+checkprops result -s  685.043
+
+checkview -display result -2d -path ${imagedir}/${test_image}.png