From 08d2b8aa05c6a123f83afcbff32fc40902bd092f Mon Sep 17 00:00:00 2001
From: Christophe Geuzaine <cgeuzaine@ulg.ac.be>
Date: Thu, 31 Jan 2013 14:30:36 +0000
Subject: [PATCH] restore old 3-side transfinite interpolation with
 Geometry.OldRuledSurface option

(soupir)
---
 Common/Context.h         |  3 +-
 Common/DefaultOptions.h  |  2 +
 Common/Options.cpp       |  7 +++
 Common/Options.h         |  1 +
 Fltk/graphicWindow.cpp   |  8 +++-
 Geo/GeoInterpolation.cpp | 33 +++++++-------
 Geo/gmshEdge.cpp         | 95 ++++++++++++++++++++++++++--------------
 Graphics/drawGeom.cpp    |  1 +
 doc/texinfo/gmsh.texi    |  6 +--
 9 files changed, 101 insertions(+), 55 deletions(-)

diff --git a/Common/Context.h b/Common/Context.h
index fbfccbfee9..f18ea0054d 100644
--- a/Common/Context.h
+++ b/Common/Context.h
@@ -52,7 +52,8 @@ struct contextGeometryOptions {
   int pointsNum, linesNum, surfacesNum, volumesNum, labelType;
   double pointSize, lineWidth, selectedPointSize, selectedLineWidth;
   int pointType, lineType, surfaceType, numSubEdges;
-  int oldCircle, extrudeSplinePoints, extrudeReturnLateral, oldNewreg;
+  int oldCircle, oldNewreg, oldRuledSurface;
+  int extrudeSplinePoints, extrudeReturnLateral;
   double normals, tangents, scalingFactor;
   int autoCoherence, highlightOrphans, clip, useTransform;
   double tolerance, snap[3], transform[3][3], offset[3];
diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h
index a8af3330a5..8f2ecabc81 100644
--- a/Common/DefaultOptions.h
+++ b/Common/DefaultOptions.h
@@ -740,6 +740,8 @@ StringXNumber GeometryOptions_Number[] = {
     "Model display offset along Z-axis (in model coordinates)" },
   { F|O, "OldCircle" , opt_geometry_old_circle , 0. ,
     "Use old circle description (compatibility option for old Gmsh geometries)" },
+  { F|O, "OldRuledSurface" , opt_geometry_old_ruled_surface , 0. ,
+    "Use old 3-sided ruled surface interpolation (compatibility option for old Gmsh geometries)" },
   { F|O, "OldNewReg" , opt_geometry_old_newreg , 1. ,
     "Use old newreg definition for geometrical transformations (compatibility "
     "option for old Gmsh geometries)" },
diff --git a/Common/Options.cpp b/Common/Options.cpp
index d7a2615ede..c83c032dbc 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -4263,6 +4263,13 @@ double opt_geometry_old_circle(OPT_ARGS_NUM)
   return CTX::instance()->geom.oldCircle;
 }
 
+double opt_geometry_old_ruled_surface(OPT_ARGS_NUM)
+{
+  if(action & GMSH_SET)
+    CTX::instance()->geom.oldRuledSurface = (int)val;
+  return CTX::instance()->geom.oldRuledSurface;
+}
+
 double opt_geometry_old_newreg(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
diff --git a/Common/Options.h b/Common/Options.h
index 8446614eef..17bc72829a 100644
--- a/Common/Options.h
+++ b/Common/Options.h
@@ -330,6 +330,7 @@ double opt_geometry_occ_sew_faces(OPT_ARGS_NUM);
 double opt_geometry_occ_connect_faces(OPT_ARGS_NUM);
 double opt_geometry_old_circle(OPT_ARGS_NUM);
 double opt_geometry_old_newreg(OPT_ARGS_NUM);
+double opt_geometry_old_ruled_surface(OPT_ARGS_NUM);
 double opt_geometry_num_sub_edges(OPT_ARGS_NUM);
 double opt_geometry_extrude_spline_points(OPT_ARGS_NUM);
 double opt_geometry_extrude_return_lateral(OPT_ARGS_NUM);
diff --git a/Fltk/graphicWindow.cpp b/Fltk/graphicWindow.cpp
index a4ac6c70d8..4830530ad4 100644
--- a/Fltk/graphicWindow.cpp
+++ b/Fltk/graphicWindow.cpp
@@ -549,8 +549,14 @@ void geometry_reload_cb(Fl_Widget *w, void *data)
 {
   std::string fileName = GModel::current()->getFileName();
   ClearProject();
-  // TODO: we should probably reset the onelab DB here, too
   OpenProject(fileName);
+
+  // TODO: we should probably reset the onelab DB here, too: calling
+  // onelab_cb(reset) seems to work, but we perform OpenProject *twice* (reset,
+  // then check) -- we should fix this before enabling the onelab reset
+  //
+  // onelab_cb(0, (void*)"reset");
+
   drawContext::global()->draw();
 }
 
diff --git a/Geo/GeoInterpolation.cpp b/Geo/GeoInterpolation.cpp
index a2cdc1f0b7..96deac1a5f 100644
--- a/Geo/GeoInterpolation.cpp
+++ b/Geo/GeoInterpolation.cpp
@@ -476,8 +476,6 @@ static Vertex TransfiniteQua(Vertex c1, Vertex c2, Vertex c3, Vertex c4,
 //   +----------+
 //  s1(0,0)     s2(1,0)
 
-#if 0
-
 // Old-style: TRAN_QUA with s1=s4=c4
 //
 // f(u,v) = u c2 (v) + (1-v) c1(u) + v c3(u) - u(1-v) s2 - uv s3
@@ -506,8 +504,6 @@ static Vertex TransfiniteTri(Vertex c1, Vertex c2, Vertex c3,
   return V;
 }
 
-#endif
-
 // New-style:
 //
 // f(u,v) = (1-u) (c1(u-v) + c3(1-v)     - s1) +
@@ -680,20 +676,21 @@ static Vertex InterpolateRuledSurface(Surface *s, double u, double v)
     S[0] = C[0]->beg;
     S[1] = C[1]->beg;
     S[2] = C[2]->beg;
-    /*
-    V[0] = InterpolateCurve(C[0], C[0]->ubeg + (C[0]->uend - C[0]->ubeg) * u, 0);
-    V[1] = InterpolateCurve(C[1], C[1]->ubeg + (C[1]->uend - C[1]->ubeg) * v, 0);
-    V[2] = InterpolateCurve(C[2], C[2]->ubeg + (C[2]->uend - C[2]->ubeg) * (1. - u), 0);
-    T = TransfiniteTri(V[0], V[1], V[2], *S[0], *S[1], *S[2], u, v);
-    */
-    V[0] = InterpolateCurve(C[0], C[0]->ubeg + (C[0]->uend - C[0]->ubeg) * (u-v), 0);
-    V[1] = InterpolateCurve(C[1], C[1]->ubeg + (C[1]->uend - C[1]->ubeg) * v, 0);
-    V[2] = InterpolateCurve(C[2], C[2]->ubeg + (C[2]->uend - C[2]->ubeg) * (1. - u), 0);
-    VB[0] = InterpolateCurve(C[0], C[0]->ubeg + (C[0]->uend - C[0]->ubeg) * u, 0);
-    VB[1] = InterpolateCurve(C[1], C[1]->ubeg + (C[1]->uend - C[1]->ubeg) * (1-u+v), 0);
-    VB[2] = InterpolateCurve(C[2], C[2]->ubeg + (C[2]->uend - C[2]->ubeg) * (1. - v), 0);
-    T = TransfiniteTriB(V[0],VB[0], V[1],VB[1], V[2],VB[2], *S[0], *S[1], *S[2], u, v);
-
+    if(CTX::instance()->geom.oldRuledSurface){
+      V[0] = InterpolateCurve(C[0], C[0]->ubeg + (C[0]->uend - C[0]->ubeg) * u, 0);
+      V[1] = InterpolateCurve(C[1], C[1]->ubeg + (C[1]->uend - C[1]->ubeg) * v, 0);
+      V[2] = InterpolateCurve(C[2], C[2]->ubeg + (C[2]->uend - C[2]->ubeg) * (1. - u), 0);
+      T = TransfiniteTri(V[0], V[1], V[2], *S[0], *S[1], *S[2], u, v);
+    }
+    else{
+      V[0] = InterpolateCurve(C[0], C[0]->ubeg + (C[0]->uend - C[0]->ubeg) * (u-v), 0);
+      V[1] = InterpolateCurve(C[1], C[1]->ubeg + (C[1]->uend - C[1]->ubeg) * v, 0);
+      V[2] = InterpolateCurve(C[2], C[2]->ubeg + (C[2]->uend - C[2]->ubeg) * (1. - u), 0);
+      VB[0] = InterpolateCurve(C[0], C[0]->ubeg + (C[0]->uend - C[0]->ubeg) * u, 0);
+      VB[1] = InterpolateCurve(C[1], C[1]->ubeg + (C[1]->uend - C[1]->ubeg) * (1-u+v), 0);
+      VB[2] = InterpolateCurve(C[2], C[2]->ubeg + (C[2]->uend - C[2]->ubeg) * (1. - v), 0);
+      T = TransfiniteTriB(V[0],VB[0], V[1],VB[1], V[2],VB[2], *S[0], *S[1], *S[2], u, v);
+    }
     if(isSphere) {
       TransfiniteSph(*S[0], *O, &T);
     }
diff --git a/Geo/gmshEdge.cpp b/Geo/gmshEdge.cpp
index 394d2d419c..4dc345cafb 100644
--- a/Geo/gmshEdge.cpp
+++ b/Geo/gmshEdge.cpp
@@ -249,41 +249,72 @@ SPoint2 gmshEdge::reparamOnFace(const GFace *face, double epar,int dir) const
     Curve *C[3];
     for(int i = 0; i < 3; i++)
       List_Read(s->Generatrices, i, &C[i]);
-
-    // FIXME: workaround for exact extrutions
-    bool hack = false;
-    if(CTX::instance()->geom.exactExtrusion && s->Extrude &&
-       s->Extrude->geo.Mode == EXTRUDED_ENTITY && s->Typ != MSH_SURF_PLAN)
-      hack = true;
-
     double U, V;
-    if (C[0]->Num == c->Num) {
-      U = (epar - C[0]->ubeg) / (C[0]->uend - C[0]->ubeg) ;
-      V = 0;
-    }
-    else if (C[0]->Num == -c->Num) {
-      U = (C[0]->uend - epar - C[0]->ubeg) / (C[0]->uend - C[0]->ubeg) ;
-      V = 0;
-    }
-    else if (C[1]->Num == c->Num) {
-      V = (epar - C[1]->ubeg) / (C[1]->uend - C[1]->ubeg) ;
-      U = 1;
-    }
-    else if (C[1]->Num == -c->Num) {
-      V = (C[1]->uend - epar - C[1]->ubeg) / (C[1]->uend - C[1]->ubeg) ;
-      U = 1;
-    }
-    else if (C[2]->Num == c->Num) {
-      U = 1-(epar - C[2]->ubeg) / (C[2]->uend - C[2]->ubeg) ;
-      V = hack ? 1 : U;
-    }
-    else if (C[2]->Num == -c->Num) {
-      U = 1-(C[2]->uend - epar - C[2]->ubeg) / (C[2]->uend - C[2]->ubeg) ;
-      V = hack ? 1 : U;
+    if(CTX::instance()->geom.oldRuledSurface){
+      if (C[0]->Num == c->Num) {
+        U = (epar - C[0]->ubeg) / (C[0]->uend - C[0]->ubeg) ;
+        V = 0;
+      }
+      else if (C[0]->Num == -c->Num) {
+        U = (C[0]->uend - epar - C[0]->ubeg) / (C[0]->uend - C[0]->ubeg) ;
+        V = 0;
+      }
+      else if (C[1]->Num == c->Num) {
+        V = (epar - C[1]->ubeg) / (C[1]->uend - C[1]->ubeg) ;
+        U = 1;
+      }
+      else if (C[1]->Num == -c->Num) {
+        V = (C[1]->uend - epar - C[1]->ubeg) / (C[1]->uend - C[1]->ubeg) ;
+        U = 1;
+      }
+      else if (C[2]->Num == c->Num) {
+        U = 1-(epar - C[2]->ubeg) / (C[2]->uend - C[2]->ubeg) ;
+        V = 1;
+      }
+      else if (C[2]->Num == -c->Num) {
+        U = 1-(C[2]->uend - epar - C[2]->ubeg) / (C[2]->uend - C[2]->ubeg) ;
+        V = 1;
+      }
+      else{
+        Msg::Info("Reparameterizing edge %d on face %d", c->Num, s->Num);
+        return GEdge::reparamOnFace(face, epar, dir);
+      }
+
     }
     else{
-      Msg::Info("Reparameterizing edge %d on face %d", c->Num, s->Num);
-      return GEdge::reparamOnFace(face, epar, dir);
+      // FIXME: workaround for exact extrusions
+      bool hack = false;
+      if(CTX::instance()->geom.exactExtrusion && s->Extrude &&
+         s->Extrude->geo.Mode == EXTRUDED_ENTITY && s->Typ != MSH_SURF_PLAN)
+        hack = true;
+      if (C[0]->Num == c->Num) {
+        U = (epar - C[0]->ubeg) / (C[0]->uend - C[0]->ubeg) ;
+        V = 0;
+      }
+      else if (C[0]->Num == -c->Num) {
+        U = (C[0]->uend - epar - C[0]->ubeg) / (C[0]->uend - C[0]->ubeg) ;
+        V = 0;
+      }
+      else if (C[1]->Num == c->Num) {
+        V = (epar - C[1]->ubeg) / (C[1]->uend - C[1]->ubeg) ;
+        U = 1;
+      }
+      else if (C[1]->Num == -c->Num) {
+        V = (C[1]->uend - epar - C[1]->ubeg) / (C[1]->uend - C[1]->ubeg) ;
+        U = 1;
+      }
+      else if (C[2]->Num == c->Num) {
+        U = 1-(epar - C[2]->ubeg) / (C[2]->uend - C[2]->ubeg) ;
+        V = hack ? 1 : U;
+      }
+      else if (C[2]->Num == -c->Num) {
+        U = 1-(C[2]->uend - epar - C[2]->ubeg) / (C[2]->uend - C[2]->ubeg) ;
+        V = hack ? 1 : U;
+      }
+      else{
+        Msg::Info("Reparameterizing edge %d on face %d", c->Num, s->Num);
+        return GEdge::reparamOnFace(face, epar, dir);
+      }
     }
     return SPoint2(U, V);
   }
diff --git a/Graphics/drawGeom.cpp b/Graphics/drawGeom.cpp
index 5478579caa..d98020607f 100644
--- a/Graphics/drawGeom.cpp
+++ b/Graphics/drawGeom.cpp
@@ -258,6 +258,7 @@ class drawGFace {
     Range<double> ubounds = f->parBounds(0);
     Range<double> vbounds = f->parBounds(1);
     bool tri = (f->geomType() == GEntity::RuledSurface && f->edges().size() == 3);
+    if(CTX::instance()->geom.oldRuledSurface) tri = false;
     double c = tri ? 0.75 : 0.5;
     double uav = c * (ubounds.high() + ubounds.low());
     double vav = (1-c) * (vbounds.high() + vbounds.low());
diff --git a/doc/texinfo/gmsh.texi b/doc/texinfo/gmsh.texi
index 5556978047..5dbb38bce0 100644
--- a/doc/texinfo/gmsh.texi
+++ b/doc/texinfo/gmsh.texi
@@ -4809,9 +4809,9 @@ information.
 @item Where does Gmsh save its configuration files?
 
 Gmsh will attempt to save temporary files and persistent configuration
-options first in the @code{$GMSH_HOME} directory, then in the
-@code{$HOME}, @code{$TMP} or @code{$TEMP} directories (in that order) if
-the @code{$GMSH_HOME} environment variable is not defined. If none of
+options first in the @code{$GMSH_HOME} directory, then in
+@code{$APPDATA} (on Windows) or @code{$HOME} (on other OSes), then in
+@code{$TMP}, and finally in @code{$TEMP}, in that order. If none of
 these variables are defined, Gmsh will try to save/load its
 configuration files from the current working directory.
 @end enumerate
-- 
GitLab