diff --git a/Common/gmsh.cpp b/Common/gmsh.cpp
index d7c7b5c31760111fcf75279cbc2cc963fd90e78b..f2426f2d2c916b7c7c40447abb9429c2713d8e42 100644
--- a/Common/gmsh.cpp
+++ b/Common/gmsh.cpp
@@ -411,7 +411,8 @@ int gmshModelSetMeshSize(const vector_pair &dimTags, const double size)
   return ret;
 }
 
-int gmshModelSetTransfiniteLine(const int tag, const int nPoints, const int type,
+int gmshModelSetTransfiniteLine(const int tag, const int nPoints,
+                                const std::string &type,
                                 const double coef)
 {
   if(!isInitialized()) return -1;
@@ -419,21 +420,32 @@ int gmshModelSetTransfiniteLine(const int tag, const int nPoints, const int type
   if(ge){
     ge->meshAttributes.method = MESH_TRANSFINITE;
     ge->meshAttributes.nbPointsTransfinite = nPoints;
-    ge->meshAttributes.typeTransfinite = type;
-    ge->meshAttributes.coeffTransfinite = coef;
+    ge->meshAttributes.typeTransfinite =
+      (type == "Progression" || type == "Power") ? 1 :
+      (type == "Bump") ? 2 :
+      1;
+    ge->meshAttributes.coeffTransfinite = std::abs(coef);
+    // in .geo file we use a negative tag to do this trick; it's a bad idea
+    if(coef < 0) ge->meshAttributes.typeTransfinite *= -1;
     return 0;
   }
   return 1;
 }
 
-int gmshModelSetTransfiniteSurface(const int tag, const int arrangement,
+int gmshModelSetTransfiniteSurface(const int tag, const std::string &arrangement,
                                    const std::vector<int> &cornerTags)
 {
   if(!isInitialized()) return -1;
   GFace *gf = GModel::current()->getFaceByTag(tag);
   if(gf){
     gf->meshAttributes.method = MESH_TRANSFINITE;
-    gf->meshAttributes.transfiniteArrangement = arrangement;
+    gf->meshAttributes.transfiniteArrangement =
+      (arrangement == "Right") ? 1 :
+      (arrangement == "Left") ? -1 :
+      (arrangement == "AlternateRight") ? 2 :
+      (arrangement == "AlternateLeft") ? -2 :
+      (arrangement == "Alternate") ? 2 :
+      -1;
     if(cornerTags.empty() || cornerTags.size() == 3 || cornerTags.size() == 4){
       for(unsigned int j = 0; j < cornerTags.size(); j++){
         GVertex *gv = GModel::current()->getVertexByTag(cornerTags[j]);
@@ -476,9 +488,10 @@ int gmshModelSetRecombine(const int dim, const int tag, const double angle)
   return 1;
 }
 
-int gmshModelSetSmoothing(const int tag, const int val)
+int gmshModelSetSmoothing(const int dim, const int tag, const int val)
 {
   if(!isInitialized()) return -1;
+  if(dim != 2) return 1;
   GFace *gf = GModel::current()->getFaceByTag(tag);
   if(gf){
     gf->meshAttributes.transfiniteSmoothing = val;
@@ -487,18 +500,24 @@ int gmshModelSetSmoothing(const int tag, const int val)
   return 1;
 }
 
-int gmshModelSetReverseMesh(const int dim, const int tag)
+int gmshModelSetReverseMesh(const int dim, const int tag, const bool val)
 {
   if(!isInitialized()) return -1;
   if(dim == 1){
     GEdge *ge = GModel::current()->getEdgeByTag(tag);
-    if(ge) ge->meshAttributes.reverseMesh = 1;
+    if(ge){
+      ge->meshAttributes.reverseMesh = val;
+      return 0;
+    }
   }
   else if(dim == 2){
     GFace *gf = GModel::current()->getFaceByTag(tag);
-    if(gf) gf->meshAttributes.reverseMesh = 1;
+    if(gf){
+      gf->meshAttributes.reverseMesh = val;
+      return 0;
+    }
   }
-  return 0;
+  return 1;
 }
 
 int gmshModelEmbed(const int dim, const std::vector<int> &tags,
@@ -770,24 +789,64 @@ int gmshModelGeoRemoveAllDuplicates()
   return 0;
 }
 
-int gmshModelGeoSetTransfiniteLine(const int tag, const int nPoints, const int type,
+int gmshModelGeoSetTransfiniteLine(const int tag, const int nPoints,
+                                   const std::string &type,
                                    const double coef)
 {
   if(!isInitialized()) return -1;
-  return 1;
+  int t =
+    (type == "Progression" || type == "Power") ? 1 :
+    (type == "Bump") ? 2 :
+    1;
+  double c = std::abs(coef);
+  // in .geo file we use a negative tag to do this trick; it's a bad idea
+  if(coef < 0) t = -t;
+  GModel::current()->getGEOInternals()->setTransfiniteLine(tag, nPoints, t, c);
+  return 0;
 }
 
-int gmshModelGeoSetTransfiniteSurface(const int tag, const int arrangement,
+int gmshModelGeoSetTransfiniteSurface(const int tag, const std::string &arrangement,
                                       const std::vector<int> &cornerTags)
 {
   if(!isInitialized()) return -1;
-  return 1;
+  int t =
+    (arrangement == "Right") ? 1 :
+    (arrangement == "Left") ? -1 :
+    (arrangement == "AlternateRight") ? 2 :
+    (arrangement == "AlternateLeft") ? -2 :
+    (arrangement == "Alternate") ? 2 :
+    -1;
+  GModel::current()->getGEOInternals()->setTransfiniteSurface(tag, t, cornerTags);
+  return 0;
 }
 
 int gmshModelGeoSetTransfiniteVolume(const int tag, const std::vector<int> &cornerTags)
 {
   if(!isInitialized()) return -1;
-  return 1;
+  GModel::current()->getGEOInternals()->setTransfiniteVolume(tag, cornerTags);
+  return 0;
+}
+
+int gmshModelGeoSetRecombine(const int dim, const int tag, const double angle)
+{
+  if(!isInitialized()) return -1;
+  GModel::current()->getGEOInternals()->setRecombine(dim, tag, angle);
+  return 0;
+}
+
+int gmshModelGeoSetSmoothing(const int dim, const int tag, const int val)
+{
+  if(!isInitialized()) return -1;
+  if(dim != 2) return 1;
+  GModel::current()->getGEOInternals()->setSmoothing(tag, val);
+  return 0;
+}
+
+int gmshModelGeoSetReverseMesh(const int dim, const int tag, const bool val)
+{
+  if(!isInitialized()) return -1;
+  GModel::current()->getGEOInternals()->setReverseMesh(dim, tag, val);
+  return 0;
 }
 
 int gmshModelGeoSetMeshSize(const vector_pair &dimTags, const double size)
diff --git a/Common/gmsh.h b/Common/gmsh.h
index 2a5981ef276ce34e0f8707806baaf59d1aeb915e..e72ed21c5d8c57154f76c414116fde2575c552f2 100644
--- a/Common/gmsh.h
+++ b/Common/gmsh.h
@@ -79,14 +79,17 @@ GMSH_API gmshModelGetMeshElements(const int dim, const int tag,
                                   std::vector<std::vector<int> > &vertexTags);
 GMSH_API gmshModelSetMeshSize(const vector_pair &dimTags, const double size);
 GMSH_API gmshModelSetTransfiniteLine(const int tag, const int nPoints,
-                                     const int type, const double coef);
-GMSH_API gmshModelSetTransfiniteSurface(const int tag, const int arrangement,
-                                        const std::vector<int> &cornerTags);
+                                     const std::string &type = "Progression",
+                                     const double coef = 1.);
+GMSH_API gmshModelSetTransfiniteSurface(const int tag,
+                                        const std::string &arrangement = "Left",
+                                        const std::vector<int> &cornerTags =
+                                        std::vector<int>());
 GMSH_API gmshModelSetTransfiniteVolume(const int tag,
                                        const std::vector<int> &cornerTags);
-GMSH_API gmshModelSetRecombine(const int dim, const int tag, const double angle);
-GMSH_API gmshModelSetSmoothing(const int tag, const int val);
-GMSH_API gmshModelSetReverseMesh(const int dim, const int tag);
+GMSH_API gmshModelSetRecombine(const int dim, const int tag, const double angle = 45.);
+GMSH_API gmshModelSetSmoothing(const int dim, const int tag, const int val);
+GMSH_API gmshModelSetReverseMesh(const int dim, const int tag, const bool val = true);
 GMSH_API gmshModelEmbed(const int dim, const std::vector<int> &tags, const int inDim,
                         const int inTag);
 
@@ -156,11 +159,18 @@ GMSH_API gmshModelGeoRemove(const vector_pair &dimTags, const bool recursive = f
 GMSH_API gmshModelGeoRemoveAllDuplicates();
 GMSH_API gmshModelGeoSetMeshSize(const vector_pair &dimTags, const double size);
 GMSH_API gmshModelGeoSetTransfiniteLine(const int tag, const int nPoints,
-                                        const int type, const double coef);
-GMSH_API gmshModelGeoSetTransfiniteSurface(const int tag, const int arrangement,
-                                           const std::vector<int> &cornerTags);
+                                        const std::string &type = "Progression",
+                                        const double coef = 1.);
+GMSH_API gmshModelGeoSetTransfiniteSurface(const int tag,
+                                           const std::string &arrangement = "Left",
+                                           const std::vector<int> &cornerTags =
+                                           std::vector<int>());
 GMSH_API gmshModelGeoSetTransfiniteVolume(const int tag,
-                                          const std::vector<int> &cornerTags);
+                                          const std::vector<int> &cornerTags =
+                                          std::vector<int>());
+GMSH_API gmshModelGeoSetRecombine(const int dim, const int tag, const double angle = 45.);
+GMSH_API gmshModelGeoSetSmoothing(const int dim, const int tag, const int val);
+GMSH_API gmshModelGeoSetReverseMesh(const int dim, const int tag, const bool val = true);
 GMSH_API gmshModelGeoSynchronize();
 
 // gmshModelOcc
@@ -283,7 +293,7 @@ GMSH_API gmshModelOccDilate(const vector_pair &dimTags, const double x,
 GMSH_API gmshModelOccSymmetry(const vector_pair &dimTags, const double a,
                               const double b, const double c, const double d);
 GMSH_API gmshModelOccCopy(const vector_pair &inDimTags, vector_pair &outDimTags);
-GMSH_API gmshModelOccRemove(const vector_pair &dimTags, const bool recursive);
+GMSH_API gmshModelOccRemove(const vector_pair &dimTags, const bool recursive = false);
 GMSH_API gmshModelOccRemoveAllDuplicates();
 GMSH_API gmshModelOccImportShapes(const std::string &fileName, vector_pair &outDimTags,
                                   const bool highestDimOnly = true,
diff --git a/Geo/GModelIO_GEO.cpp b/Geo/GModelIO_GEO.cpp
index be3e5cc6a3b698c19cc978aef5e6a6e2a3317053..e06256d0bfbf44acdead0d615442588cbaaef4a9 100644
--- a/Geo/GModelIO_GEO.cpp
+++ b/Geo/GModelIO_GEO.cpp
@@ -1008,7 +1008,7 @@ void GEO_Internals::setSmoothing(int tag, int val)
   _changed = true;
 }
 
-void GEO_Internals::setReverseMesh(int dim, int tag)
+void GEO_Internals::setReverseMesh(int dim, int tag, bool val)
 {
   if(dim == 1){
     if(!tag){
@@ -1016,13 +1016,13 @@ void GEO_Internals::setReverseMesh(int dim, int tag)
       for(int i = 0; i < List_Nbr(tmp); i++){
         Curve *c;
         List_Read(tmp, i, &c);
-        c->ReverseMesh = 1;
+        c->ReverseMesh = val ? 1 : 0;
       }
       List_Delete(tmp);
     }
     else{
       Curve *c = FindCurve(tag);
-      if(c) c->ReverseMesh = 1;
+      if(c) c->ReverseMesh = val ? 1 : 0;
     }
   }
   else if(dim == 2){
@@ -1031,13 +1031,13 @@ void GEO_Internals::setReverseMesh(int dim, int tag)
       for(int i = 0; i < List_Nbr(tmp); i++){
         Surface *s;
         List_Read(tmp, i, &s);
-        s->ReverseMesh = 1;
+        s->ReverseMesh = val ? 1 : 0;
       }
       List_Delete(tmp);
     }
     else{
       Surface *s = FindSurface(tag);
-      if(s) s->ReverseMesh = 1;
+      if(s) s->ReverseMesh = val ? 1 : 0;
     }
   }
   _changed = true;
diff --git a/Geo/GModelIO_GEO.h b/Geo/GModelIO_GEO.h
index bc3dee1da956d3477114275cee0cb4224bdafeab..ce4c780641918b9051d0efcbe59cdced2e39b22b 100644
--- a/Geo/GModelIO_GEO.h
+++ b/Geo/GModelIO_GEO.h
@@ -34,7 +34,7 @@ class GEO_Internals{
                 double dx, double dy, double dz,
                 double ax, double ay, double az, double angle,
                 std::vector<std::pair<int, int> > &outDimTags,
-                ExtrudeParams *e=0);
+                ExtrudeParams *e = 0);
  public:
   GEO_Internals(){ _allocateAll(); }
   ~GEO_Internals(){ _freeAll(); }
@@ -54,9 +54,9 @@ class GEO_Internals{
   bool addLine(int &tag, int startTag, int endTag);
   bool addLine(int &tag, const std::vector<int> &vertexTags);
   bool addCircleArc(int &tag, int startTag, int centerTag, int endTag,
-                    double nx=0., double ny=0., double nz=0.);
+                    double nx = 0., double ny = 0., double nz = 0.);
   bool addEllipseArc(int &tag, int startTag, int centerTag, int majorTag,
-                     int endTag, double nx=0., double ny=0., double nz=0.);
+                     int endTag, double nx = 0., double ny = 0., double nz = 0.);
   bool addSpline(int &tag, const std::vector<int> &vertexTags);
   bool addBSpline(int &tag, const std::vector<int> &vertexTags);
   bool addBezier(int &tag, const std::vector<int> &vertexTags);
@@ -67,10 +67,10 @@ class GEO_Internals{
   bool addPlaneSurface(int &tag, const std::vector<int> &wireTags);
   bool addDiscreteSurface(int &tag);
   bool addSurfaceFilling(int &tag, const std::vector<int> &wireTags,
-                         int sphereCenterTag=-1);
+                         int sphereCenterTag = -1);
   bool addSurfaceLoop(int &tag, const std::vector<int> &faceTags);
   bool addCompoundSurface(int &tag, const std::vector<int> &faceTags,
-                          std::vector<int> edgeTags[4]=0);
+                          std::vector<int> edgeTags[4] = 0);
   bool addVolume(int &tag, const std::vector<int> &shellTags);
   bool addCompoundVolume(int &tag, const std::vector<int> &regionTags);
 
@@ -78,21 +78,21 @@ class GEO_Internals{
   bool extrude(const std::vector<std::pair<int, int> > &inDimTags,
                double dx, double dy, double dz,
                std::vector<std::pair<int, int> > &outDimTags,
-               ExtrudeParams *e=0);
+               ExtrudeParams *e = 0);
   bool revolve(const std::vector<std::pair<int, int> > &inDimTags,
                double x, double y, double z,
                double ax, double ay, double az, double angle,
                std::vector<std::pair<int, int> > &outDimTags,
-               ExtrudeParams *e=0);
+               ExtrudeParams *e = 0);
   bool twist(const std::vector<std::pair<int, int> > &inDimTags,
              double x, double y, double z,
              double dx, double dy, double dz,
              double ax, double ay, double az, double angle,
              std::vector<std::pair<int, int> > &outDimTags,
-             ExtrudeParams *e=0);
+             ExtrudeParams *e = 0);
   bool boundaryLayer(const std::vector<std::pair<int, int> > &inDimTags,
                      std::vector<std::pair<int, int> > &outDimTags,
-                     ExtrudeParams *e=0);
+                     ExtrudeParams *e = 0);
 
   // apply transformations
   bool translate(const std::vector<std::pair<int, int> > &dimTags,
@@ -115,8 +115,8 @@ class GEO_Internals{
   // copy and remove
   bool copy(const std::vector<std::pair<int, int> > &inDimTags,
             std::vector<std::pair<int, int> > &outDimTags);
-  bool remove(int dim, int tag, bool recursive=false);
-  bool remove(const std::vector<std::pair<int, int> > &dimTags, bool recursive=false);
+  bool remove(int dim, int tag, bool recursive = false);
+  bool remove(const std::vector<std::pair<int, int> > &dimTags, bool recursive = false);
 
   // manipulate physical groups
   void resetPhysicalGroups();
@@ -139,7 +139,7 @@ class GEO_Internals{
   void setTransfiniteVolumeQuadTri(int tag);
   void setRecombine(int dim, int tag, double angle);
   void setSmoothing(int tag, int val);
-  void setReverseMesh(int dim, int tag);
+  void setReverseMesh(int dim, int tag, bool val = 1);
 
   // synchronize internal CAD data with the given GModel
   void synchronize(GModel *model);
diff --git a/demos/api/open2.cpp b/demos/api/explore.cpp
similarity index 100%
rename from demos/api/open2.cpp
rename to demos/api/explore.cpp
diff --git a/demos/api/open2.py b/demos/api/explore.py
similarity index 100%
rename from demos/api/open2.py
rename to demos/api/explore.py
diff --git a/demos/api/t1.cpp b/demos/api/t1.cpp
index 0447938fe40554e7b94206bf19d1381252a3054d..c2d08070956c93f2e7706b0dabc3f91feec4058b 100644
--- a/demos/api/t1.cpp
+++ b/demos/api/t1.cpp
@@ -1,7 +1,7 @@
 // This file reimplements gmsh/tutorial/t1.geo in C++. For all the elementary
 // explanations about the general philosphy of entities in Gmsh, see the
-// comments in the .geo file. Comments here will focus on the specifics of the
-// C++ API.
+// comments in the .geo file. Comments here focus on the specifics of the C++
+// API.
 
 // The Gmsh API is entirely defined in the <gmsh.h> header:
 #include <gmsh.h>
diff --git a/demos/api/t1.py b/demos/api/t1.py
index b7caa2b00ad7da8041727717ac6f8d3da3fadba4..532a0d8899108df441c17e7f93eaa1a0f7fda18d 100644
--- a/demos/api/t1.py
+++ b/demos/api/t1.py
@@ -1,9 +1,8 @@
 #!/usr/bin/env python
 
 # This file reimplements gmsh/tutorial/t1.geo in Python. For all the elementary
-# explanations about the general philosphy of entities in Gmsh, see the
-# comments in the .geo file. Comments here will focus on the specifics of the
-# Python API.
+# explanations about the general philosphy of entities in Gmsh, see the comments
+# in the .geo file. Comments here focus on the specifics of the Python API.
 
 # The API is entirely defined in the gmsh module
 from gmsh import *
diff --git a/demos/api/t16.py b/demos/api/t16.py
index 8c7706d9c638470dd94f3f48b03790c26b873351..9187d99d007fd03f0160687a783d3e7e64a1deb6 100644
--- a/demos/api/t16.py
+++ b/demos/api/t16.py
@@ -19,7 +19,7 @@ gmshModelOccBooleanDifference(3,[(3,1)], [(3,2)], ov, ovv)
 x = 0; y = 0.75; z = 0; r = 0.09
 
 holes = PairVector()
-for t in range(1, 5):
+for t in range(1, 6):
     x += 0.166
     z += 0.166
     gmshModelOccAddSphere(3 + t, x,y,z,r)
diff --git a/demos/api/t5.py b/demos/api/t5.py
index 8a97f9765b967c4ea5b8c797ba37e014e4c5ecf2..8dc12883c857587271a89c86b064efd757585024 100644
--- a/demos/api/t5.py
+++ b/demos/api/t5.py
@@ -3,9 +3,6 @@
 from gmsh import *
 import math
 
-def hypot(a, b):
-    return math.sqrt(a * a + b * b)
-
 gmshInitialize()
 gmshOptionSetNumber("General.Terminal", 1)
 
@@ -114,7 +111,7 @@ def cheeseHole(x, y, z, r, lc, shells, volumes):
     volumes.append(v)
 
 x = 0; y = 0.75; z = 0; r = 0.09
-for t in range(1,5):
+for t in range(1, 6):
     x += 0.166 ;
     z += 0.166 ;
     cheeseHole(x, y, z, r, lcar3, shells, volumes);
diff --git a/demos/api/t6.cpp b/demos/api/t6.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..528b02adf87d0b974422eb6336a16986a54a9287
--- /dev/null
+++ b/demos/api/t6.cpp
@@ -0,0 +1,95 @@
+// This file reimplements gmsh/tutorial/t6.geo in C++.
+
+#include <gmsh.h>
+
+int main(int argc, char **argv)
+{
+  gmshInitialize();
+  gmshOptionSetNumber("General.Terminal", 1);
+
+  gmshModelCreate("t2");
+
+  // Copied from t1.cpp...
+  double lc = 1e-2;
+  int o;
+  gmshModelGeoAddPoint(1, 0, 0, 0, o, lc);
+  gmshModelGeoAddPoint(2, .1, 0,  0, o, lc);
+  gmshModelGeoAddPoint(3, .1, .3, 0, o, lc);
+  gmshModelGeoAddPoint(4, 0,  .3, 0, o, lc);
+
+  gmshModelGeoAddLine(1, 1, 2, o);
+  gmshModelGeoAddLine(2, 3, 2, o);
+  gmshModelGeoAddLine(3, 3, 4, o);
+  gmshModelGeoAddLine(4, 4, 1, o);
+
+  gmshModelGeoAddLineLoop(1, {4, 1, -2, 3}, o);
+  gmshModelGeoAddPlaneSurface(1, {1}, o);
+  gmshModelAddPhysicalGroup(0, 1, {1, 2});
+  gmshModelAddPhysicalGroup(1, 2, {1, 2});
+  gmshModelAddPhysicalGroup(2, 6, {1});
+  gmshModelSetPhysicalName(2, 6, "My surface");
+  // ...end of copy
+
+  // Delete surface 1 and left boundary (line 4)
+  gmshModelGeoRemove({{2,1}, {1,4}});
+
+  // Replace left boundary with 3 new lines
+  int p1; gmshModelGeoAddPoint(-1, -0.05, 0.05, 0, p1, lc);
+  int p2; gmshModelGeoAddPoint(-1, -0.05, 0.1, 0, p2, lc);
+  int l1; gmshModelGeoAddLine(-1, 1, p1, l1);
+  int l2; gmshModelGeoAddLine(-1, p1, p2, l2);
+  int l3; gmshModelGeoAddLine(-1, p2, 4, l3);
+
+  // Recreate surface
+  gmshModelGeoAddLineLoop(2, {2, -1, l1, l2, l3, -3}, o);
+  gmshModelGeoAddPlaneSurface(1, {-2}, o);
+
+  // Put 20 points with a refinement toward the extremities on curve 2
+  gmshModelGeoSetTransfiniteLine(2, 20, "Bump", 0.05);
+
+  // Put 20 points total on combination of curves l1, l2 and l3 (beware that the
+  // points p1 and p2 are shared by the curves, so we do not create 6 + 6 + 10 =
+  // 22 points, but 20!)
+  gmshModelGeoSetTransfiniteLine(l1, 6);
+  gmshModelGeoSetTransfiniteLine(l2, 6);
+  gmshModelGeoSetTransfiniteLine(l3, 10);
+
+  // Put 30 points following a geometric progression on curve 1 (reversed) and
+  // on curve 3
+  gmshModelGeoSetTransfiniteLine(1, 30, "Progression", -1.2);
+  gmshModelGeoSetTransfiniteLine(3, 30, "Progression", 1.2);
+
+  // Define the Surface as transfinite, by specifying the four corners of the
+  // transfinite interpolation
+  gmshModelGeoSetTransfiniteSurface(1, "Left", {1,2,3,4});
+
+  // Recombine the triangles into quads
+  gmshModelGeoSetRecombine(2, 1);
+
+  // Apply an elliptic smoother to the grid
+  gmshOptionSetNumber("Mesh.Smoothing", 100);
+  gmshModelAddPhysicalGroup(2, 1, {1});
+
+  // When the surface has only 3 or 4 control points, the transfinite constraint
+  // can be applied automatically (without specifying the corners explictly).
+  gmshModelGeoAddPoint(7, 0.2, 0.2, 0, o, 1.0);
+  gmshModelGeoAddPoint(8, 0.2, 0.1, 0, o, 1.0);
+  gmshModelGeoAddPoint(9, 0, 0.3, 0, o, 1.0);
+  gmshModelGeoAddPoint(10, 0.25, 0.2, 0, o, 1.0);
+  gmshModelGeoAddPoint(11, 0.3, 0.1, 0, o, 1.0);
+  gmshModelGeoAddLine(10, 8, 11, o);
+  gmshModelGeoAddLine(11, 11, 10, o);
+  gmshModelGeoAddLine(12, 10, 7, o);
+  gmshModelGeoAddLine(13, 7, 8, o);
+  gmshModelGeoAddLineLoop(14, {13, 10, 11, 12}, o);
+  gmshModelGeoAddPlaneSurface(15, {14}, o);
+  for(int i = 10; i <= 13; i++)
+    gmshModelGeoSetTransfiniteLine(i, 10);
+  gmshModelGeoSetTransfiniteSurface(15);
+  gmshModelAddPhysicalGroup(2, 2, {15});
+
+  gmshModelMesh(2);
+  gmshExport("t6.msh");
+  gmshFinalize();
+  return 0;
+}
diff --git a/demos/api/t6.py b/demos/api/t6.py
new file mode 100644
index 0000000000000000000000000000000000000000..fbc64c7458cb5648850e1cfbe4f4c648a08eff9d
--- /dev/null
+++ b/demos/api/t6.py
@@ -0,0 +1,91 @@
+# This file reimplements gmsh/tutorial/t6.geo in Python.
+
+from gmsh import *
+import math
+
+gmshInitialize()
+gmshOptionSetNumber("General.Terminal", 1)
+
+gmshModelCreate("t6")
+
+# Copied from t1.py...
+lc = 1e-2
+gmshModelGeoAddPoint(1, 0, 0, 0, lc)
+gmshModelGeoAddPoint(2, .1, 0,  0, lc)
+gmshModelGeoAddPoint(3, .1, .3, 0, lc)
+gmshModelGeoAddPoint(4, 0,  .3, 0, lc)
+
+gmshModelGeoAddLine(1, 1, 2)
+gmshModelGeoAddLine(2, 3, 2)
+gmshModelGeoAddLine(3, 3, 4)
+gmshModelGeoAddLine(4, 4, 1)
+
+gmshModelGeoAddLineLoop(1, [4, 1, -2, 3])
+gmshModelGeoAddPlaneSurface(1, [1])
+gmshModelAddPhysicalGroup(0, 1, [1, 2])
+gmshModelAddPhysicalGroup(1, 2, [1, 2])
+gmshModelAddPhysicalGroup(2, 6, [1])
+gmshModelSetPhysicalName(2, 6, "My surface")
+# ...end of copy
+
+# Delete surface 1 and left boundary (line 4)
+gmshModelGeoRemove([[2,1], [1,4]])
+
+# Replace left boundary with 3 new lines
+p1 = gmshModelGeoAddPoint(-1, -0.05, 0.05, 0, lc)[1]
+p2 = gmshModelGeoAddPoint(-1, -0.05, 0.1, 0, lc)[1]
+l1 = gmshModelGeoAddLine(-1, 1, p1)[1]
+l2 = gmshModelGeoAddLine(-1, p1, p2)[1]
+l3 = gmshModelGeoAddLine(-1, p2, 4)[1]
+
+# Recreate surface
+gmshModelGeoAddLineLoop(2, [2, -1, l1, l2, l3, -3])
+gmshModelGeoAddPlaneSurface(1, [-2])
+
+# Put 20 points with a refinement toward the extremities on curve 2
+gmshModelGeoSetTransfiniteLine(2, 20, "Bump", 0.05)
+
+# Put 20 points total on combination of curves l1, l2 and l3 (beware that the
+# points p1 and p2 are shared by the curves, so we do not create 6 + 6 + 10 = 22
+# points, but 20!)
+gmshModelGeoSetTransfiniteLine(l1, 6)
+gmshModelGeoSetTransfiniteLine(l2, 6)
+gmshModelGeoSetTransfiniteLine(l3, 10)
+
+# Put 30 points following a geometric progression on curve 1 (reversed) and on
+# curve 3
+gmshModelGeoSetTransfiniteLine(1, 30, "Progression", -1.2)
+gmshModelGeoSetTransfiniteLine(3, 30, "Progression", 1.2)
+
+# Define the Surface as transfinite, by specifying the four corners of the
+# transfinite interpolation
+gmshModelGeoSetTransfiniteSurface(1, "Left", [1,2,3,4])
+
+# Recombine the triangles into quads
+gmshModelGeoSetRecombine(2, 1)
+
+# Apply an elliptic smoother to the grid
+gmshOptionSetNumber("Mesh.Smoothing", 100)
+gmshModelAddPhysicalGroup(2, 1, [1])
+
+# When the surface has only 3 or 4 control points, the transfinite constraint
+# can be applied automatically (without specifying the corners explictly).
+gmshModelGeoAddPoint(7, 0.2, 0.2, 0, 1.0)
+gmshModelGeoAddPoint(8, 0.2, 0.1, 0, 1.0)
+gmshModelGeoAddPoint(9, 0, 0.3, 0, 1.0)
+gmshModelGeoAddPoint(10, 0.25, 0.2, 0, 1.0)
+gmshModelGeoAddPoint(11, 0.3, 0.1, 0, 1.0)
+gmshModelGeoAddLine(10, 8, 11)
+gmshModelGeoAddLine(11, 11, 10)
+gmshModelGeoAddLine(12, 10, 7)
+gmshModelGeoAddLine(13, 7, 8)
+gmshModelGeoAddLineLoop(14, [13, 10, 11, 12])
+gmshModelGeoAddPlaneSurface(15, [14])
+for i in range(10,14):
+    gmshModelGeoSetTransfiniteLine(i, 10)
+gmshModelGeoSetTransfiniteSurface(15)
+gmshModelAddPhysicalGroup(2, 2, [15])
+
+gmshModelMesh(2)
+gmshExport("t6.msh")
+gmshFinalize()
diff --git a/tutorial/t1.geo b/tutorial/t1.geo
index 44124a137ef85eae208d9156f1fae438fc6c10a5..d4f1237cbb892ea36dd8dd76b7001bbabc7d865d 100644
--- a/tutorial/t1.geo
+++ b/tutorial/t1.geo
@@ -21,8 +21,8 @@ Point(1) = {0, 0, 0, lc};
 
 // The distribution of the mesh element sizes is then obtained by interpolation
 // of these characteristic lengths throughout the geometry. Another method to
-// specify characteristic lengths is to use a background mesh (see `t7.geo' and
-// `bgmesh.pos').
+// specify characteristic lengths is to use general mesh size Fields (see
+// `t10.geo'). A particular case is the use of a background mesh (see `t7.geo').
 
 // We can then define some additional points as well as our first curve.  Curves
 // are Gmsh's second type of elementery entities, and, amongst curves, straight
diff --git a/tutorial/t6.geo b/tutorial/t6.geo
index 2d47d580fce3f926f9959184e7cd3dc3ad6ce79d..28aa61f3b0f6998156141ef0015608dc97325e29 100644
--- a/tutorial/t6.geo
+++ b/tutorial/t6.geo
@@ -9,7 +9,7 @@
 // Let's use the geometry from the first tutorial as a basis for this one
 Include "t1.geo";
 
-// Delete the left line and create replace it with 3 new ones
+// Delete the left line and replace it with 3 new ones
 Delete{ Surface{1}; Line{4}; }
 
 p1 = newp; Point(p1) = {-0.05, 0.05, 0, lc};
@@ -70,3 +70,4 @@ Line Loop(14) = {13, 10, 11, 12};
 Plane Surface(15) = {14};
 Transfinite Line {10:13} = 10;
 Transfinite Surface{15};
+Physical Surface(2) = 15;