diff --git a/Common/gmsh.cpp b/Common/gmsh.cpp
index 7a342eb79b3be2ad021cfeb695bb274f060e66e0..d7e309a145f86a27f9e27c628af2a31a51008bf4 100644
--- a/Common/gmsh.cpp
+++ b/Common/gmsh.cpp
@@ -3,8 +3,10 @@
 // See the LICENSE.txt file for license information. Please report all
 // bugs and problems to the public mailing list <gmsh@onelab.info>.
 
+#include <sstream>
 #include "gmsh.h"
 #include "GmshConfig.h"
+#include "GmshDefines.h"
 #include "GmshGlobal.h"
 #include "GModel.h"
 #include "GModelIO_GEO.h"
@@ -13,6 +15,10 @@
 #include "GEdge.h"
 #include "GFace.h"
 #include "GRegion.h"
+#include "discreteVertex.h"
+#include "discreteEdge.h"
+#include "discreteFace.h"
+#include "discreteRegion.h"
 #include "MPoint.h"
 #include "MLine.h"
 #include "MTriangle.h"
@@ -28,13 +34,11 @@
 #include "Field.h"
 #endif
 
-#define GMSH_API std::vector<int>
-#define GMSH_OK std::vector<int>(1, 0)
-#define GMSH_ERROR(n) std::vector<int>(1, n)
+#define GMSH_ERROR(n) { throw n; }
 
 static int _initialized = 0;
 
-static bool isInitialized()
+static bool _isInitialized()
 {
   if(!_initialized){
     // make sure stuff gets printed out
@@ -47,66 +51,62 @@ static bool isInitialized()
 
 // gmsh
 
-GMSH_API gmshInitialize(int argc, char **argv)
+void gmshInitialize(int argc, char **argv)
 {
   if(_initialized){
     Msg::Error("Gmsh has aleady been initialized");
-    return GMSH_ERROR(1);
+    GMSH_ERROR(1);
   }
   if(GmshInitialize(argc, argv)){
     _initialized = 1;
-    return GMSH_OK;
+    return;
   }
-  return GMSH_ERROR(1);
+  GMSH_ERROR(-1);
 }
 
-GMSH_API gmshFinalize()
+void gmshFinalize()
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   if(GmshFinalize()){
     _initialized = 0;
-    return GMSH_OK;
+    return;
   }
   Msg::Error("Something went wrong when finalizing Gmsh");
-  return GMSH_ERROR(1);
+  GMSH_ERROR(1);
 }
 
-GMSH_API gmshOpen(const std::string &fileName)
+void gmshOpen(const std::string &fileName)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  if(GmshOpenProject(fileName))
-    return GMSH_OK;
-  return GMSH_ERROR(1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  if(GmshOpenProject(fileName)) return;
+  GMSH_ERROR(1);
 }
 
-GMSH_API gmshMerge(const std::string &fileName)
+void gmshMerge(const std::string &fileName)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  if(GmshMergeFile(fileName))
-    return GMSH_OK;
-  return GMSH_ERROR(1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  if(GmshMergeFile(fileName)) return;
+  GMSH_ERROR(1);
 }
 
-GMSH_API gmshExport(const std::string &fileName)
+void gmshExport(const std::string &fileName)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  if(GmshWriteFile(fileName))
-    return GMSH_OK;
-  return GMSH_ERROR(1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  if(GmshWriteFile(fileName)) return;
+  GMSH_ERROR(1);
 }
 
-GMSH_API gmshClear()
+void gmshClear()
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  if(GmshClearProject())
-    return GMSH_OK;
-  return GMSH_ERROR(1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  if(GmshClearProject()) return;
+  GMSH_ERROR(1);
 }
 
 // gmshOption
 
-static void splitOptionName(const std::string &fullName, std::string &category,
-                            std::string &name, int &index)
+static void _splitOptionName(const std::string &fullName, std::string &category,
+                             std::string &name, int &index)
 {
   std::string::size_type d = fullName.find_first_of('.');
   if(d == std::string::npos){
@@ -130,97 +130,91 @@ static void splitOptionName(const std::string &fullName, std::string &category,
              name.c_str(), index);
 }
 
-GMSH_API gmshOptionSetNumber(const std::string &name, const double value)
+void gmshOptionSetNumber(const std::string &name, const double value)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   std::string c, n;
   int i;
-  splitOptionName(name, c, n, i);
-  if(GmshSetOption(c, n, value, i))
-    return GMSH_OK;
-  return GMSH_ERROR(1);
+  _splitOptionName(name, c, n, i);
+  if(GmshSetOption(c, n, value, i)) return;
+  GMSH_ERROR(1);
 }
 
-GMSH_API gmshOptionGetNumber(const std::string &name, double &value)
+void gmshOptionGetNumber(const std::string &name, double &value)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   std::string c, n;
   int i;
-  splitOptionName(name, c, n, i);
-  if(GmshGetOption(c, n, value, i))
-    return GMSH_OK;
-  return GMSH_ERROR(1);
+  _splitOptionName(name, c, n, i);
+  if(GmshGetOption(c, n, value, i)) return;
+  GMSH_ERROR(1);
 }
 
-GMSH_API gmshOptionSetString(const std::string &name, const std::string &value)
+void gmshOptionSetString(const std::string &name, const std::string &value)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   std::string c, n;
   int i;
-  splitOptionName(name, c, n, i);
-  if(GmshSetOption(c, n, value, i))
-    return GMSH_OK;
-  return GMSH_ERROR(1);
+  _splitOptionName(name, c, n, i);
+  if(GmshSetOption(c, n, value, i)) return;
+  GMSH_ERROR(1);
 }
 
-GMSH_API gmshOptionGetString(const std::string &name, std::string &value)
+void gmshOptionGetString(const std::string &name, std::string &value)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   std::string c, n;
   int i;
-  splitOptionName(name, c, n, i);
-  if(GmshGetOption(c, n, value, i))
-    return GMSH_OK;
-  return GMSH_ERROR(1);
+  _splitOptionName(name, c, n, i);
+  if(GmshGetOption(c, n, value, i)) return;
+  GMSH_ERROR(1);
 }
 
 // gmshModel
 
-GMSH_API gmshModelCreate(const std::string &name)
+void gmshModelCreate(const std::string &name)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   GModel *m = new GModel(name);
-  if(m)
-    return GMSH_OK;
-  return GMSH_ERROR(1);
+  if(!m){ GMSH_ERROR(1); }
 }
 
-GMSH_API gmshModelSetCurrent(const std::string &name)
+void gmshModelDelete()
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  GModel *m = GModel::findByName(name);
-  if(m){
-    GModel::setCurrent(m);
-    return GMSH_OK;
-  }
-  return GMSH_ERROR(1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  GModel *m = GModel::current();
+  if(!m){ GMSH_ERROR(1); }
+  delete m;
 }
 
-GMSH_API gmshModelDestroy()
+void gmshModelList(std::vector<std::string> &names)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  GModel *m = GModel::current();
-  if(m){
-    delete m;
-    return GMSH_OK;
-  }
-  return GMSH_ERROR(1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  for(unsigned int i = 0; i < GModel::list.size(); i++)
+    names.push_back(GModel::list[i]->getName());
+}
+
+void gmshModelSetCurrent(const std::string &name)
+{
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  GModel *m = GModel::findByName(name);
+  if(!m){ GMSH_ERROR(1); }
+  GModel::setCurrent(m);
 }
 
-GMSH_API gmshModelGetEntities(vector_pair &dimTags, const int dim)
+void gmshModelGetEntities(vector_pair &dimTags, const int dim)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   dimTags.clear();
   std::vector<GEntity*> entities;
   GModel::current()->getEntities(entities, dim);
   for(unsigned int i = 0; i < entities.size(); i++)
     dimTags.push_back(std::pair<int, int>(entities[i]->dim(), entities[i]->tag()));
-  return GMSH_OK;
 }
 
-GMSH_API gmshModelGetPhysicalGroups(vector_pair &dimTags, const int dim)
+void gmshModelGetPhysicalGroups(vector_pair &dimTags, const int dim)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   dimTags.clear();
   std::map<int, std::vector<GEntity*> > groups[4];
   GModel::current()->getPhysicalGroups(groups);
@@ -231,26 +225,12 @@ GMSH_API gmshModelGetPhysicalGroups(vector_pair &dimTags, const int dim)
         dimTags.push_back(std::pair<int, int>(d, it->first));
     }
   }
-  return GMSH_OK;
-}
-
-GMSH_API gmshModelAddPhysicalGroup(const int dim, const int tag,
-                                   const std::vector<int> &tags)
-{
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  bool r = GModel::current()->getGEOInternals()->modifyPhysicalGroup
-    (dim, tag, 0, tags);
-  if(r){
-    GModel::current()->getGEOInternals()->synchronize(GModel::current());
-    return GMSH_OK;
-  }
-  return GMSH_ERROR(1);
 }
 
-GMSH_API gmshModelGetEntitiesForPhysicalGroup(const int dim, const int tag,
-                                              std::vector<int> &tags)
+void gmshModelGetEntitiesForPhysicalGroup(const int dim, const int tag,
+                                          std::vector<int> &tags)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   tags.clear();
   std::map<int, std::vector<GEntity*> > groups;
   GModel::current()->getPhysicalGroups(dim, groups);
@@ -259,125 +239,182 @@ GMSH_API gmshModelGetEntitiesForPhysicalGroup(const int dim, const int tag,
     for(unsigned j = 0; j < it->second.size(); j++)
       tags.push_back(it->second[j]->tag());
   }
-  return GMSH_OK;
 }
 
-GMSH_API gmshModelSetPhysicalName(const int dim, const int tag,
-                                  const std::string &name)
+int gmshModelAddPhysicalGroup(const int dim, const std::vector<int> &tags,
+                              const int tag)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  GModel::current()->setPhysicalName(name, dim, tag);
-  return GMSH_OK;
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  int outTag = tag;
+  if(outTag < 0)
+    outTag = GModel::current()->getGEOInternals()->getMaxPhysicalTag() + 1;
+  if(!GModel::current()->getGEOInternals()->modifyPhysicalGroup
+     (dim, outTag, 0, tags)){
+    GMSH_ERROR(1);
+  }
+  GModel::current()->getGEOInternals()->synchronize(GModel::current());
+  return outTag;
 }
 
-GMSH_API gmshModelGetPhysicalName(const int dim, const int tag,
-                                  std::string &name)
+void gmshModelSetPhysicalName(const int dim, const int tag,
+                              const std::string &name)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  name = GModel::current()->getPhysicalName(dim, tag);
-  return GMSH_OK;
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  GModel::current()->setPhysicalName(name, dim, tag);
 }
 
-GMSH_API gmshModelGetVertexCoordinates(const int tag, double &x, double &y,
-                                       double &z)
+void gmshModelGetPhysicalName(const int dim, const int tag, std::string &name)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  GVertex *gv = GModel::current()->getVertexByTag(tag);
-  if(gv){
-    x = gv->x();
-    y = gv->y();
-    z = gv->z();
-    return GMSH_OK;
-  }
-  return GMSH_ERROR(1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  name = GModel::current()->getPhysicalName(dim, tag);
 }
 
-GMSH_API gmshModelGetBoundary(const vector_pair &inDimTags, vector_pair &outDimTags,
-                              const bool combined, const bool oriented,
-                              const bool recursive)
+void gmshModelGetBoundary(const vector_pair &dimTags, vector_pair &outDimTags,
+                          const bool combined, const bool oriented,
+                          const bool recursive)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   outDimTags.clear();
-  bool r = GModel::current()->getBoundaryTags(inDimTags, outDimTags, combined,
-                                              oriented, recursive);
-  if(r) return GMSH_OK;
-  return GMSH_ERROR(1);
+  if(!GModel::current()->getBoundaryTags(dimTags, outDimTags, combined,
+                                         oriented, recursive)){
+    GMSH_ERROR(1);
+  }
 }
 
-GMSH_API gmshModelGetEntitiesInBoundingBox(const double x1, const double y1,
-                                           const double z1, const double x2,
-                                           const double y2, const double z2,
-                                           vector_pair &dimTags, const int dim)
+void gmshModelGetEntitiesInBoundingBox(const double xmin, const double ymin,
+                                       const double zmin, const double xmax,
+                                       const double ymax, const double zmax,
+                                       vector_pair &dimTags, const int dim)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   dimTags.clear();
-  SBoundingBox3d box(x1, y1, z1, x2, y2, z2);
+  SBoundingBox3d box(xmin, ymin, zmin, xmax, ymax, zmax);
   std::vector<GEntity*> entities;
   GModel::current()->getEntitiesInBox(entities, box, dim);
   for(unsigned int i = 0; i < entities.size(); i++)
     dimTags.push_back(std::pair<int, int>(entities[i]->dim(), entities[i]->tag()));
-  return GMSH_OK;
 }
 
-GMSH_API gmshModelGetBoundingBox(const int dim, const int tag, double &x1, double &y1,
-                                 double &z1, double &x2, double &y2, double &z2)
+static std::string _entityName(int dim, int tag)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  std::stringstream stream;
+  switch(dim){
+  case 0 : stream << "Point "; break;
+  case 1 : stream << "Line "; break;
+  case 2 : stream << "Surface "; break;
+  case 3 : stream << "Volume "; break;
+  }
+  stream << tag;
+  return stream.str();
+}
+
+void gmshModelGetBoundingBox(const int dim, const int tag, double &xmin,
+                             double &ymin, double &zmin, double &xmax,
+                             double &ymax, double &zmax)
+{
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   GEntity *ge = GModel::current()->getEntityByTag(dim, tag);
-  if(!ge) return GMSH_ERROR(1);
+  if(!ge){
+    Msg::Error("%s does not exist", _entityName(dim, tag).c_str());
+    GMSH_ERROR(2);
+  }
   SBoundingBox3d box = ge->bounds();
-  if(box.empty()) return GMSH_ERROR(2);
-  x1 = box.min().x();
-  y1 = box.min().y();
-  z1 = box.min().z();
-  x2 = box.max().x();
-  y2 = box.max().y();
-  z2 = box.max().z();
-  return GMSH_OK;
+  if(box.empty()){ GMSH_ERROR(3); }
+  xmin = box.min().x();
+  ymin = box.min().y();
+  zmin = box.min().z();
+  xmax = box.max().x();
+  ymax = box.max().y();
+  zmax = box.max().z();
 }
 
-GMSH_API gmshModelRemove(const vector_pair &dimTags, const bool recursive)
+int gmshModelAddDiscreteEntity(const int dim, const int tag,
+                               const std::vector<int> &boundary)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  int outTag = tag;
+  if(outTag < 0){
+    outTag = GModel::current()->getMaxElementaryNumber(dim);
+  }
+  GEntity *e = GModel::current()->getEntityByTag(dim, outTag);
+  if(e){
+    Msg::Error("%s already exists", _entityName(dim, outTag).c_str());
+    GMSH_ERROR(2);
+  }
+  // FIXME: check and set boundary entities to construct topology!
+  switch(dim){
+  case 0: {
+    GVertex *gv = new discreteVertex(GModel::current(), outTag);
+    GModel::current()->add(gv);
+    e = gv;
+    break;
+  }
+  case 1: {
+    GEdge *ge = new discreteEdge(GModel::current(), outTag, 0, 0);
+    GModel::current()->add(ge);
+    break;
+  }
+  case 2: {
+    GFace *gf = new discreteFace(GModel::current(), outTag);
+    GModel::current()->add(gf);
+    break;
+  }
+  case 3: {
+    GRegion *gr = new discreteRegion(GModel::current(), outTag);
+    GModel::current()->add(gr);
+    break;
+  }
+  default :
+    GMSH_ERROR(2);
+  }
+  return outTag;
+}
+
+void gmshModelRemove(const vector_pair &dimTags, const bool recursive)
+{
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   GModel::current()->remove(dimTags, recursive);
-  return GMSH_OK;
 }
 
-GMSH_API gmshModelMesh(int dim)
+void gmshModelMesh(int dim)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   GModel *m = GModel::current();
-  if(m){
-    m->mesh(dim);
-    return GMSH_OK;
-  }
-  return GMSH_ERROR(1);
+  if(!m){ GMSH_ERROR(1); }
+  m->mesh(dim);
 }
 
-GMSH_API gmshModelGetMeshVertices(const int dim, const int tag,
-                                  std::vector<int> &vertexTags,
-                                  std::vector<double> &coords)
+void gmshModelGetMeshVertices(const int dim, const int tag,
+                              std::vector<int> &vertexTags,
+                              std::vector<double> &coord,
+                              std::vector<double> &parametricCoord)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   vertexTags.clear();
-  coords.clear();
+  coord.clear();
   GEntity *ge = GModel::current()->getEntityByTag(dim, tag);
-  if(!ge) return GMSH_ERROR(1);
+  if(!ge){
+    Msg::Error("%s does not exist", _entityName(dim, tag).c_str());
+    GMSH_ERROR(2);
+  }
   for(unsigned int i = 0; i < ge->mesh_vertices.size(); i++){
     MVertex *v = ge->mesh_vertices[i];
     vertexTags.push_back(v->getNum());
-    coords.push_back(v->x());
-    coords.push_back(v->y());
-    coords.push_back(v->z());
+    coord.push_back(v->x());
+    coord.push_back(v->y());
+    coord.push_back(v->z());
+    double par;
+    for(int j = 0; j < dim; j++){
+      if(v->getParameter(j, par)) parametricCoord.push_back(par);
+    }
   }
-  return GMSH_OK;
 }
 
 template<class T>
-static void addElementInfo(const std::vector<T*> &ele,
-                           std::vector<int> &elementType,
-                           std::vector<std::vector<int> > &elementTags,
-                           std::vector<std::vector<int> > &vertexTags)
+static void _addElementInfo(const std::vector<T*> &ele,
+                            std::vector<int> &elementType,
+                            std::vector<std::vector<int> > &elementTags,
+                            std::vector<std::vector<int> > &vertexTags)
 {
   if(ele.empty()) return;
   elementType.push_back(ele.front()->getTypeForMSH());
@@ -391,45 +428,232 @@ static void addElementInfo(const std::vector<T*> &ele,
   }
 }
 
-GMSH_API gmshModelGetMeshElements(const int dim, const int tag,
-                                  std::vector<int> &types,
-                                  std::vector<std::vector<int> > &elementTags,
-                                  std::vector<std::vector<int> > &vertexTags)
+void gmshModelGetMeshElements(const int dim, const int tag,
+                              std::vector<int> &types,
+                              std::vector<std::vector<int> > &elementTags,
+                              std::vector<std::vector<int> > &vertexTags)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   types.clear();
   elementTags.clear();
   vertexTags.clear();
   GEntity *ge = GModel::current()->getEntityByTag(dim, tag);
-  if(!ge) return GMSH_ERROR(1);
+  if(!ge){
+    Msg::Error("%s does not exist", _entityName(dim, tag).c_str());
+    GMSH_ERROR(2);
+  }
   switch(dim){
   case 0: {
     GVertex *v = static_cast<GVertex*>(ge);
-    addElementInfo(v->points, types, elementTags, vertexTags);
+    _addElementInfo(v->points, types, elementTags, vertexTags);
     break; }
   case 1: {
     GEdge *e = static_cast<GEdge*>(ge);
-    addElementInfo(e->lines, types, elementTags, vertexTags);
+    _addElementInfo(e->lines, types, elementTags, vertexTags);
     break; }
   case 2: {
     GFace *f = static_cast<GFace*>(ge);
-    addElementInfo(f->triangles, types, elementTags, vertexTags);
-    addElementInfo(f->quadrangles, types, elementTags, vertexTags);
+    _addElementInfo(f->triangles, types, elementTags, vertexTags);
+    _addElementInfo(f->quadrangles, types, elementTags, vertexTags);
     break; }
   case 3: {
     GRegion *r = static_cast<GRegion*>(ge);
-    addElementInfo(r->tetrahedra, types, elementTags, vertexTags);
-    addElementInfo(r->hexahedra, types, elementTags, vertexTags);
-    addElementInfo(r->prisms, types, elementTags, vertexTags);
-    addElementInfo(r->pyramids, types, elementTags, vertexTags);
+    _addElementInfo(r->tetrahedra, types, elementTags, vertexTags);
+    _addElementInfo(r->hexahedra, types, elementTags, vertexTags);
+    _addElementInfo(r->prisms, types, elementTags, vertexTags);
+    _addElementInfo(r->pyramids, types, elementTags, vertexTags);
     break; }
   }
-  return GMSH_OK;
 }
 
-GMSH_API gmshModelSetMeshSize(const vector_pair &dimTags, const double size)
+void gmshModelSetMeshVertices(const int dim, const int tag,
+                              const std::vector<int> &vertexTags,
+                              const std::vector<double> &coord,
+                              const std::vector<double> &parametricCoord)
+{
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  GEntity *ge = GModel::current()->getEntityByTag(dim, tag);
+  if(!ge){
+    Msg::Error("%s does not exist", _entityName(dim, tag).c_str());
+    GMSH_ERROR(2);
+  }
+  if(coord.size() != 3 * vertexTags.size()){
+    Msg::Error("Wrong number of coord");
+    GMSH_ERROR(2);
+  }
+  bool param = false;
+  if(parametricCoord.size()){
+    if(parametricCoord.size() != dim * vertexTags.size()){
+      Msg::Error("Wrong number of parametric coord");
+      GMSH_ERROR(2);
+    }
+    param = true;
+  }
+  ge->deleteMesh(); // this will also delete the model mesh cache
+  for(unsigned int i = 0; i < vertexTags.size(); i++){
+    int n = vertexTags[i];
+    double x = coord[3 * i];
+    double y = coord[3 * i + 1];
+    double z = coord[3 * i + 2];
+    MVertex *vv = 0;
+    if(param && dim == 1){
+      double u = parametricCoord[i];
+      vv = new MEdgeVertex(x, y, z, ge, u, n);
+    }
+    else if(param && dim == 2){
+      double u = parametricCoord[i];
+      double v = parametricCoord[i + 1];
+      vv = new MFaceVertex(x, y, z, ge, u, v, n);
+    }
+    else
+      vv = new MVertex(x, y, z, ge, n);
+    ge->mesh_vertices.push_back(vv);
+  }
+}
+
+template<class T>
+static void _addElements(int dim, int tag, const std::vector<MElement*> &src,
+                         std::vector<T*> &dst)
+{
+  if(dst.size())
+    Msg::Warning("%s already contains mesh elements - appending the new ones",
+                 _entityName(dim, tag).c_str());
+  for(unsigned int i = 0; i < src.size(); i++)
+    dst.push_back(static_cast<T*>(src[i]));
+}
+
+void gmshModelSetMeshElements(const int dim, const int tag,
+                              const std::vector<int> &types,
+                              const std::vector<std::vector<int> > &elementTags,
+                              const std::vector<std::vector<int> > &vertexTags)
+{
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  GEntity *ge = GModel::current()->getEntityByTag(dim, tag);
+  if(!ge){
+    Msg::Error("%s does not exist", _entityName(dim, tag).c_str());
+    GMSH_ERROR(2);
+  }
+  if(types.size() != elementTags.size()){
+    Msg::Error("Wrong number of element tags");
+    GMSH_ERROR(2);
+  }
+  if(types.size() != vertexTags.size()){
+    Msg::Error("Wrong number of vertex tags");
+    GMSH_ERROR(2);
+  }
+  for(unsigned int i = 0; i < types.size(); i++){
+    int type = types[i];
+    int numEle = elementTags[i].size();
+    int numVertPerEle = MElement::getInfoMSH(type);
+    if(!numEle) continue;
+    if(numEle * numVertPerEle != vertexTags[i].size()){
+      Msg::Error("Wrong number of vertex tags for element type %d", type);
+      GMSH_ERROR(2);
+    }
+    std::vector<MElement*> elements(numEle);
+    std::vector<MVertex*> vertices(numVertPerEle);
+    for(unsigned int j = 0; j < numEle; j++){
+      int etag = elementTags[i][j];
+      MElementFactory f;
+      for(unsigned int k = 0; k < numVertPerEle; k++){
+        int vtag = vertexTags[i][numVertPerEle * j + k];
+        // this will rebuild the vertex cache if necessary
+        vertices[k] = GModel::current()->getMeshVertexByTag(vtag);
+        if(!vertices[k]){
+          Msg::Error("Unknown mesh vertex %d", vtag);
+          GMSH_ERROR(2);
+        }
+      }
+      elements[j] = f.create(type, vertices, etag);
+    }
+    bool ok = true;
+    switch(dim){
+    case 0:
+      if(elements[0]->getType() == TYPE_PNT)
+        _addElements(dim, tag, elements, static_cast<GVertex*>(ge)->points);
+      else
+        ok = false;
+      break;
+    case 1:
+      if(elements[0]->getType() == TYPE_LIN)
+        _addElements(dim, tag, elements, static_cast<GEdge*>(ge)->lines);
+      else
+        ok = false;
+     break;
+    case 2:
+      if(elements[0]->getType() == TYPE_TRI)
+        _addElements(dim, tag, elements, static_cast<GFace*>(ge)->triangles);
+      else if(elements[0]->getType() == TYPE_QUA)
+        _addElements(dim, tag, elements, static_cast<GFace*>(ge)->quadrangles);
+      else
+        ok = false;
+      break;
+    case 3:
+      if(elements[0]->getType() == TYPE_TET)
+        _addElements(dim, tag, elements, static_cast<GRegion*>(ge)->tetrahedra);
+      else if(elements[0]->getType() == TYPE_HEX)
+        _addElements(dim, tag, elements, static_cast<GRegion*>(ge)->hexahedra);
+      else if(elements[0]->getType() == TYPE_PRI)
+        _addElements(dim, tag, elements, static_cast<GRegion*>(ge)->prisms);
+      else if(elements[0]->getType() == TYPE_PYR)
+        _addElements(dim, tag, elements, static_cast<GRegion*>(ge)->pyramids);
+      else
+        ok = false;
+      break;
+    }
+    if(!ok){
+      Msg::Error("Wrong type of element for %s", _entityName(dim, tag).c_str());
+      GMSH_ERROR(2);
+    }
+  }
+}
+
+void gmshModelGetMeshVertex(const int vertexTag,
+                            std::vector<double> &coord,
+                            std::vector<double> &parametricCoord)
+{
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  MVertex *v = GModel::current()->getMeshVertexByTag(vertexTag);
+  if(!v){
+    Msg::Error("Unknown mesh vertex %d", vertexTag);
+    GMSH_ERROR(2);
+  }
+  coord.clear();
+  coord.push_back(v->x());
+  coord.push_back(v->x());
+  coord.push_back(v->x());
+  parametricCoord.clear();
+  double u;
+  if(v->getParameter(0, u))
+    parametricCoord.push_back(u);
+  if(v->getParameter(1, u))
+    parametricCoord.push_back(u);
+}
+
+void gmshModelGetMeshElement(const int elementTag, int &type,
+                             std::vector<int> &vertexTags)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  MElement *e = GModel::current()->getMeshElementByTag(elementTag);
+  if(!e){
+    Msg::Error("Unknown mesh element %d", elementTag);
+    GMSH_ERROR(2);
+  }
+  type = e->getTypeForMSH();
+  vertexTags.clear();
+  for(int i = 0; i < e->getNumVertices(); i++){
+    MVertex *v = e->getVertex(i);
+    if(!v){
+      Msg::Error("Unknown mesh vertex in element %d", elementTag);
+      GMSH_ERROR(2);
+    }
+    vertexTags.push_back(v->getNum());
+  }
+}
+
+void gmshModelSetMeshSize(const vector_pair &dimTags, const double size)
+{
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   for(unsigned int i = 0; i < dimTags.size(); i++){
     int dim = dimTags[i].first, tag = dimTags[i].second;
     if(dim == 0){
@@ -437,316 +661,323 @@ GMSH_API gmshModelSetMeshSize(const vector_pair &dimTags, const double size)
       if(gv) gv->setPrescribedMeshSizeAtVertex(size);
     }
   }
-  return GMSH_OK;
 }
 
-GMSH_API gmshModelSetTransfiniteLine(const int tag, const int nPoints,
-                                     const std::string &type, const double coef)
+void gmshModelSetTransfiniteLine(const int tag, const int numVertices,
+                                 const std::string &type, const double coef)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   GEdge *ge = GModel::current()->getEdgeByTag(tag);
-  if(ge){
-    ge->meshAttributes.method = MESH_TRANSFINITE;
-    ge->meshAttributes.nbPointsTransfinite = nPoints;
-    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 GMSH_OK;
-  }
-  return GMSH_ERROR(1);
-}
-
-GMSH_API gmshModelSetTransfiniteSurface(const int tag,
-                                        const std::string &arrangement,
-                                        const std::vector<int> &cornerTags)
-{
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!ge){
+    Msg::Error("%s does not exist", _entityName(1, tag).c_str());
+    GMSH_ERROR(2);
+  }
+  ge->meshAttributes.method = MESH_TRANSFINITE;
+  ge->meshAttributes.nbPointsTransfinite = numVertices;
+  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;
+}
+
+void gmshModelSetTransfiniteSurface(const int tag,
+                                    const std::string &arrangement,
+                                    const std::vector<int> &cornerTags)
+{
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   GFace *gf = GModel::current()->getFaceByTag(tag);
-  if(gf){
-    gf->meshAttributes.method = MESH_TRANSFINITE;
-    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]);
-        if(gv)
-          gf->meshAttributes.corners.push_back(gv);
-      }
+  if(!gf){
+    Msg::Error("%s does not exist", _entityName(2, tag).c_str());
+    GMSH_ERROR(2);
+  }
+  gf->meshAttributes.method = MESH_TRANSFINITE;
+  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]);
+      if(gv)
+        gf->meshAttributes.corners.push_back(gv);
     }
-    return GMSH_OK;
   }
-  return GMSH_ERROR(1);
 }
 
-GMSH_API gmshModelSetTransfiniteVolume(const int tag,
-                                       const std::vector<int> &cornerTags)
+void gmshModelSetTransfiniteVolume(const int tag,
+                                   const std::vector<int> &cornerTags)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   GRegion *gr = GModel::current()->getRegionByTag(tag);
-  if(gr){
-    gr->meshAttributes.method = MESH_TRANSFINITE;
-    if(cornerTags.empty() || cornerTags.size() == 6 || cornerTags.size() == 8){
-      for(unsigned int i = 0; i < cornerTags.size(); i++){
-        GVertex *gv = GModel::current()->getVertexByTag(cornerTags[i]);
-        if(gv)
-          gr->meshAttributes.corners.push_back(gv);
-      }
+  if(!gr){
+    Msg::Error("%s does not exist", _entityName(3, tag).c_str());
+    GMSH_ERROR(2);
+  }
+  gr->meshAttributes.method = MESH_TRANSFINITE;
+  if(cornerTags.empty() || cornerTags.size() == 6 || cornerTags.size() == 8){
+    for(unsigned int i = 0; i < cornerTags.size(); i++){
+      GVertex *gv = GModel::current()->getVertexByTag(cornerTags[i]);
+      if(gv)
+        gr->meshAttributes.corners.push_back(gv);
     }
-    return GMSH_OK;
   }
-  return GMSH_ERROR(1);
 }
 
-GMSH_API gmshModelSetRecombine(const int dim, const int tag, const double angle)
+void gmshModelSetRecombine(const int dim, const int tag)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  if(dim != 2){ GMSH_ERROR(2); }
   GFace *gf = GModel::current()->getFaceByTag(tag);
-  if(gf){
-    gf->meshAttributes.recombine = 1;
-    gf->meshAttributes.recombineAngle = angle;
-    return GMSH_OK;
+  if(!gf){
+    Msg::Error("%s does not exist", _entityName(dim, tag).c_str());
+    GMSH_ERROR(2);
   }
-  return GMSH_ERROR(1);
+  gf->meshAttributes.recombine = 1;
+  gf->meshAttributes.recombineAngle = 45.;
 }
 
-GMSH_API gmshModelSetSmoothing(const int dim, const int tag, const int val)
+void gmshModelSetSmoothing(const int dim, const int tag, const int val)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  if(dim != 2) return GMSH_ERROR(1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  if(dim != 2){ GMSH_ERROR(2); }
   GFace *gf = GModel::current()->getFaceByTag(tag);
-  if(gf){
-    gf->meshAttributes.transfiniteSmoothing = val;
-    return GMSH_OK;
+  if(!gf){
+    Msg::Error("%s does not exist", _entityName(dim, tag).c_str());
+    GMSH_ERROR(2);
   }
-  return GMSH_ERROR(1);
+  gf->meshAttributes.transfiniteSmoothing = val;
 }
 
-GMSH_API gmshModelSetReverseMesh(const int dim, const int tag, const bool val)
+void gmshModelSetReverseMesh(const int dim, const int tag, const bool val)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   if(dim == 1){
     GEdge *ge = GModel::current()->getEdgeByTag(tag);
-    if(ge){
-      ge->meshAttributes.reverseMesh = val;
-      return GMSH_OK;
+    if(!ge){
+      Msg::Error("%s does not exist", _entityName(dim, tag).c_str());
+      GMSH_ERROR(2);
     }
+    ge->meshAttributes.reverseMesh = val;
   }
   else if(dim == 2){
     GFace *gf = GModel::current()->getFaceByTag(tag);
-    if(gf){
-      gf->meshAttributes.reverseMesh = val;
-      return GMSH_OK;
+    if(!gf){
+      Msg::Error("%s does not exist", _entityName(dim, tag).c_str());
+      GMSH_ERROR(2);
     }
+    gf->meshAttributes.reverseMesh = val;
   }
-  return GMSH_ERROR(1);
 }
 
-GMSH_API gmshModelEmbed(const int dim, const std::vector<int> &tags,
-                        const int inDim, const int inTag)
+void gmshModelEmbed(const int dim, const std::vector<int> &tags,
+                    const int inDim, const int inTag)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   if(inDim == 2){
     GFace *gf = GModel::current()->getFaceByTag(inTag);
-    if(gf){
-      for(unsigned int i = 0; i < tags.size(); i++){
-        if(dim == 0){
-          GVertex *gv = GModel::current()->getVertexByTag(tags[i]);
-          if(gv)
-            gf->addEmbeddedVertex(gv);
+    if(!gf){
+      Msg::Error("%s does not exist", _entityName(2, inTag).c_str());
+      GMSH_ERROR(2);
+    }
+    for(unsigned int i = 0; i < tags.size(); i++){
+      if(dim == 0){
+        GVertex *gv = GModel::current()->getVertexByTag(tags[i]);
+        if(!gv){
+          Msg::Error("%s does not exist", _entityName(0, tags[i]).c_str());
+          GMSH_ERROR(2);
         }
-        else if(dim == 1){
-          GEdge *ge = GModel::current()->getEdgeByTag(tags[i]);
-          if(ge)
-            gf->addEmbeddedEdge(ge);
+        gf->addEmbeddedVertex(gv);
+      }
+      else if(dim == 1){
+        GEdge *ge = GModel::current()->getEdgeByTag(tags[i]);
+        if(!ge){
+          Msg::Error("%s does not exist", _entityName(1, tags[i]).c_str());
+          GMSH_ERROR(2);
         }
+        gf->addEmbeddedEdge(ge);
       }
     }
   }
   else if(inDim == 3){
     GRegion *gr = GModel::current()->getRegionByTag(inTag);
-    if(gr){
-      for(unsigned int i = 0; i < tags.size(); i++){
-        if(dim == 0){
-          GVertex *gv = GModel::current()->getVertexByTag(tags[i]);
-          if(gv)
-            gr->addEmbeddedVertex(gv);
+    if(!gr){
+      Msg::Error("%s does not exist", _entityName(3, inTag).c_str());
+      GMSH_ERROR(2);
+    }
+    for(unsigned int i = 0; i < tags.size(); i++){
+      if(dim == 0){
+        GVertex *gv = GModel::current()->getVertexByTag(tags[i]);
+        if(!gv){
+          Msg::Error("%s does not exist", _entityName(0, tags[i]).c_str());
+          GMSH_ERROR(2);
         }
-        else if(dim == 1){
-          GEdge *ge = GModel::current()->getEdgeByTag(tags[i]);
-          if(ge)
-            gr->addEmbeddedEdge(ge);
+        gr->addEmbeddedVertex(gv);
+      }
+      else if(dim == 1){
+        GEdge *ge = GModel::current()->getEdgeByTag(tags[i]);
+        if(!ge){
+          Msg::Error("%s does not exist", _entityName(1, tags[i]).c_str());
+          GMSH_ERROR(2);
         }
-        else if(dim == 2){
-          GFace *gf = GModel::current()->getFaceByTag(tags[i]);
-          if(gf)
-            gr->addEmbeddedFace(gf);
+        gr->addEmbeddedEdge(ge);
+      }
+      else if(dim == 2){
+        GFace *gf = GModel::current()->getFaceByTag(tags[i]);
+        if(!gf){
+          Msg::Error("%s does not exist", _entityName(2, tags[i]).c_str());
+          GMSH_ERROR(2);
         }
+        gr->addEmbeddedFace(gf);
       }
     }
   }
-  return GMSH_OK;
 }
 
 // gmshModelGeo
 
-GMSH_API gmshModelGeoAddPoint(const int tag, const double x, const double y,
-                              const double z, const double meshSize)
+int gmshModelGeoAddPoint(const double x, const double y, const double z,
+                         const double meshSize, const int tag)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   int outTag = tag;
   double xx = CTX::instance()->geom.scalingFactor * x;
   double yy = CTX::instance()->geom.scalingFactor * y;
   double zz = CTX::instance()->geom.scalingFactor * z;
   double lc = CTX::instance()->geom.scalingFactor * meshSize;
-  if(GModel::current()->getGEOInternals()->addVertex(outTag, xx, yy, zz, lc)){
-    std::vector<int> ret(1, 0); ret.push_back(outTag);
-    return ret;
+  if(!GModel::current()->getGEOInternals()->addVertex(outTag, xx, yy, zz, lc)){
+    GMSH_ERROR(1);
   }
-  return GMSH_ERROR(1);
+  return outTag;
 }
 
-GMSH_API gmshModelGeoAddLine(const int tag, const int startTag, const int endTag)
+int gmshModelGeoAddLine(const int startTag, const int endTag, const int tag)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   int outTag = tag;
-  if(GModel::current()->getGEOInternals()->addLine(outTag, startTag, endTag)){
-    std::vector<int> ret(1, 0); ret.push_back(outTag);
-    return ret;
+  if(!GModel::current()->getGEOInternals()->addLine(outTag, startTag, endTag)){
+    GMSH_ERROR(1);
   }
-  return GMSH_ERROR(1);
+  return outTag;
 }
 
-GMSH_API gmshModelGeoAddCircleArc(const int tag, const int startTag,
-                                  const int centerTag, const int endTag,
-                                  const double nx, const double ny, const double nz)
+int gmshModelGeoAddCircleArc(const int startTag, const int centerTag,
+                             const int endTag, const int tag, const double nx,
+                             const double ny, const double nz)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   int outTag = tag;
-  if(GModel::current()->getGEOInternals()->addCircleArc
+  if(!GModel::current()->getGEOInternals()->addCircleArc
      (outTag, startTag, centerTag, endTag, nx, ny, nz)){
-    std::vector<int> ret(1, 0); ret.push_back(outTag);
-    return ret;
+    GMSH_ERROR(1);
   }
-  return GMSH_ERROR(1);
+  return outTag;
 }
 
-GMSH_API gmshModelGeoAddEllipseArc(const int tag, const int startTag,
-                                   const int centerTag, const int majorTag,
-                                   const int endTag, const double nx, const double ny,
-                                   const double nz)
+int gmshModelGeoAddEllipseArc(const int startTag, const int centerTag,
+                              const int majorTag, const int endTag,
+                              const int tag, const double nx, const double ny,
+                              const double nz)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   int outTag = tag;
-  if(GModel::current()->getGEOInternals()->addEllipseArc
+  if(!GModel::current()->getGEOInternals()->addEllipseArc
      (outTag, startTag, centerTag, majorTag, endTag, nx, ny, nz)){
-    std::vector<int> ret(1, 0); ret.push_back(outTag);
-    return ret;
+    GMSH_ERROR(1);
   }
-  return GMSH_ERROR(1);
+  return outTag;
 }
 
-GMSH_API gmshModelGeoAddSpline(const int tag, const std::vector<int> &vertexTags)
+int gmshModelGeoAddSpline(const std::vector<int> &vertexTags, const int tag)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   int outTag = tag;
-  if(GModel::current()->getGEOInternals()->addSpline(outTag, vertexTags)){
-    std::vector<int> ret(1, 0); ret.push_back(outTag);
-    return ret;
+  if(!GModel::current()->getGEOInternals()->addSpline(outTag, vertexTags)){
+    GMSH_ERROR(1);
   }
-  return GMSH_ERROR(1);
+  return outTag;
 }
 
-GMSH_API gmshModelGeoAddBSpline(const int tag, const std::vector<int> &vertexTags)
+int gmshModelGeoAddBSpline(const std::vector<int> &vertexTags, const int tag)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   int outTag = tag;
-  if(GModel::current()->getGEOInternals()->addBSpline(outTag, vertexTags)){
-    std::vector<int> ret(1, 0); ret.push_back(outTag);
-    return ret;
+  if(!GModel::current()->getGEOInternals()->addBSpline(outTag, vertexTags)){
+    GMSH_ERROR(1);
   }
-  return GMSH_ERROR(1);
+  return outTag;
 }
 
-GMSH_API gmshModelGeoAddBezier(const int tag, const std::vector<int> &vertexTags)
+int gmshModelGeoAddBezier(const std::vector<int> &vertexTags, const int tag)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   int outTag = tag;
-  if(GModel::current()->getGEOInternals()->addBezier(outTag, vertexTags)){
-    std::vector<int> ret(1, 0); ret.push_back(outTag);
-    return ret;
+  if(!GModel::current()->getGEOInternals()->addBezier(outTag, vertexTags)){
+    GMSH_ERROR(1);
   }
-  return GMSH_ERROR(1);
+  return outTag;
 }
 
-GMSH_API gmshModelGeoAddLineLoop(const int tag, const std::vector<int> &edgeTags)
+int gmshModelGeoAddLineLoop(const std::vector<int> &edgeTags, const int tag)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   int outTag = tag;
-  if(GModel::current()->getGEOInternals()->addLineLoop(outTag, edgeTags)){
-    std::vector<int> ret(1, 0); ret.push_back(outTag);
-    return ret;
+  if(!GModel::current()->getGEOInternals()->addLineLoop(outTag, edgeTags)){
+    GMSH_ERROR(1);
   }
-  return GMSH_ERROR(1);
+  return outTag;
 }
 
-GMSH_API gmshModelGeoAddPlaneSurface(const int tag, const std::vector<int> &wireTags)
+int gmshModelGeoAddPlaneSurface(const std::vector<int> &wireTags, const int tag)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   int outTag = tag;
-  if(GModel::current()->getGEOInternals()->addPlaneSurface(outTag, wireTags)){
-    std::vector<int> ret(1, 0); ret.push_back(outTag);
-    return ret;
+  if(!GModel::current()->getGEOInternals()->addPlaneSurface(outTag, wireTags)){
+    GMSH_ERROR(1);
   }
-  return GMSH_ERROR(1);
+  return outTag;
 }
 
-GMSH_API gmshModelGeoAddSurfaceFilling(const int tag, const std::vector<int> &wireTags,
-                                       const int sphereCenterTag)
+int gmshModelGeoAddSurfaceFilling(const std::vector<int> &wireTags, const int tag,
+                                  const int sphereCenterTag)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   int outTag = tag;
-  if(GModel::current()->getGEOInternals()->addSurfaceFilling
+  if(!GModel::current()->getGEOInternals()->addSurfaceFilling
      (outTag, wireTags, sphereCenterTag)){
-    std::vector<int> ret(1, 0); ret.push_back(outTag);
-    return ret;
+    GMSH_ERROR(1);
   }
-  return GMSH_ERROR(1);
+  return outTag;
 }
 
-GMSH_API gmshModelGeoAddSurfaceLoop(const int tag, const std::vector<int> &faceTags)
+int gmshModelGeoAddSurfaceLoop(const std::vector<int> &faceTags, const int tag)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   int outTag = tag;
-  if(GModel::current()->getGEOInternals()->addSurfaceLoop(outTag, faceTags)){
-    std::vector<int> ret(1, 0); ret.push_back(outTag);
-    return ret;
+  if(!GModel::current()->getGEOInternals()->addSurfaceLoop(outTag, faceTags)){
+    GMSH_ERROR(1);
   }
-  return GMSH_ERROR(1);
+  return outTag;
 }
 
-GMSH_API gmshModelGeoAddVolume(const int tag, const std::vector<int> &shellTags)
+int gmshModelGeoAddVolume(const std::vector<int> &shellTags, const int tag)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   int outTag = tag;
-  if(GModel::current()->getGEOInternals()->addVolume(outTag, shellTags)){
-    std::vector<int> ret(1, 0); ret.push_back(outTag);
-    return ret;
+  if(!GModel::current()->getGEOInternals()->addVolume(outTag, shellTags)){
+    GMSH_ERROR(1);
   }
-  return GMSH_ERROR(1);
+  return outTag;
 }
 
-static ExtrudeParams *getExtrudeParams(const std::vector<int> &numElements,
-                                       const std::vector<double> &heights,
-                                       const bool recombine)
+static ExtrudeParams *_getExtrudeParams(const std::vector<int> &numElements,
+                                        const std::vector<double> &heights,
+                                        const bool recombine)
 {
   ExtrudeParams *e = 0;
   if(numElements.size()){
@@ -766,127 +997,128 @@ static ExtrudeParams *getExtrudeParams(const std::vector<int> &numElements,
   return e;
 }
 
-GMSH_API gmshModelGeoExtrude(const vector_pair &inDimTags,
-                             const double dx, const double dy, const double dz,
-                             vector_pair &outDimTags,
-                             const std::vector<int> &numElements,
-                             const std::vector<double> &heights,
-                             const bool recombine)
+void gmshModelGeoExtrude(const vector_pair &dimTags,
+                         const double dx, const double dy, const double dz,
+                         vector_pair &outDimTags,
+                         const std::vector<int> &numElements,
+                         const std::vector<double> &heights,
+                         const bool recombine)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   outDimTags.clear();
-  if(GModel::current()->getGEOInternals()->extrude
-     (inDimTags, dx, dy, dz, outDimTags,
-      getExtrudeParams(numElements, heights, recombine)))
-    return GMSH_OK;
-  return GMSH_ERROR(1);
-}
-
-GMSH_API gmshModelGeoRevolve(const vector_pair &inDimTags,
-                             const double x, const double y, const double z,
-                             const double ax, const double ay, const double az,
-                             const double angle, vector_pair &outDimTags,
-                             const std::vector<int> &numElements,
-                             const std::vector<double> &heights,
-                             const bool recombine)
-{
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!GModel::current()->getGEOInternals()->extrude
+     (dimTags, dx, dy, dz, outDimTags,
+      _getExtrudeParams(numElements, heights, recombine))){
+    GMSH_ERROR(1);
+  }
+}
+
+void gmshModelGeoRevolve(const vector_pair &dimTags,
+                         const double x, const double y, const double z,
+                         const double ax, const double ay, const double az,
+                         const double angle,
+                         vector_pair &outDimTags,
+                         const std::vector<int> &numElements,
+                         const std::vector<double> &heights,
+                         const bool recombine)
+{
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   outDimTags.clear();
-  if(GModel::current()->getGEOInternals()->revolve
-    (inDimTags, x, y, z, ax, ay, az, angle, outDimTags,
-     getExtrudeParams(numElements, heights, recombine)))
-    return GMSH_OK;
-  return GMSH_ERROR(1);
-}
-
-GMSH_API gmshModelGeoTwist(const vector_pair &inDimTags,
-                           const double x, const double y, const double z,
-                           const double dx, const double dy, const double dz,
-                           const double ax, const double ay, const double az,
-                           const double angle, vector_pair &outDimTags,
-                           const std::vector<int> &numElements,
-                           const std::vector<double> &heights,
-                           const bool recombine)
-{
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!GModel::current()->getGEOInternals()->revolve
+     (dimTags, x, y, z, ax, ay, az, angle, outDimTags,
+      _getExtrudeParams(numElements, heights, recombine))){
+    GMSH_ERROR(1);
+  }
+}
+
+void gmshModelGeoTwist(const vector_pair &dimTags,
+                       const double x, const double y, const double z,
+                       const double dx, const double dy, const double dz,
+                       const double ax, const double ay, const double az,
+                       const double angle,
+                       vector_pair &outDimTags,
+                       const std::vector<int> &numElements,
+                       const std::vector<double> &heights,
+                       const bool recombine)
+{
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   outDimTags.clear();
-  if(GModel::current()->getGEOInternals()->twist
-    (inDimTags, x, y, z, dx, dy, dz, ax, ay, az, angle, outDimTags,
-     getExtrudeParams(numElements, heights, recombine)))
-    return GMSH_OK;
-  return GMSH_ERROR(1);
+  if(!GModel::current()->getGEOInternals()->twist
+     (dimTags, x, y, z, dx, dy, dz, ax, ay, az, angle, outDimTags,
+      _getExtrudeParams(numElements, heights, recombine))){
+    GMSH_ERROR(1);
+  }
 }
 
-GMSH_API gmshModelGeoTranslate(const vector_pair &dimTags, const double dx,
-                               const double dy, const double dz)
+void gmshModelGeoTranslate(const vector_pair &dimTags, const double dx,
+                           const double dy, const double dz)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  if(GModel::current()->getGEOInternals()->translate(dimTags, dx, dy, dz))
-    return GMSH_OK;
-  return GMSH_ERROR(1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  if(!GModel::current()->getGEOInternals()->translate(dimTags, dx, dy, dz)){
+    GMSH_ERROR(1);
+  }
 }
 
-GMSH_API gmshModelGeoRotate(const vector_pair &dimTags, const double x,
-                            const double y, const double z, const double ax,
-                            const double ay, const double az, const double angle)
+void gmshModelGeoRotate(const vector_pair &dimTags, const double x,
+                        const double y, const double z, const double ax,
+                        const double ay, const double az, const double angle)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  if(GModel::current()->getGEOInternals()->rotate
-     (dimTags, x, y, z, ax, ay, az, angle))
-    return GMSH_OK;
-  return GMSH_ERROR(1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  if(!GModel::current()->getGEOInternals()->rotate
+     (dimTags, x, y, z, ax, ay, az, angle)){
+    GMSH_ERROR(1);
+  }
 }
 
-GMSH_API gmshModelGeoDilate(const vector_pair &dimTags, const double x,
-                            const double y, const double z, const double a,
-                            const double b, const double c)
+void gmshModelGeoDilate(const vector_pair &dimTags, const double x,
+                        const double y, const double z, const double a,
+                        const double b, const double c)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  if(GModel::current()->getGEOInternals()->dilate
-     (dimTags, x, y, z, a, b, c))
-    return GMSH_OK;
-  return GMSH_ERROR(1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  if(!GModel::current()->getGEOInternals()->dilate
+     (dimTags, x, y, z, a, b, c)){
+    GMSH_ERROR(1);
+  }
 }
 
-GMSH_API gmshModelGeoSymmetry(const vector_pair &dimTags, const double a,
-                              const double b, const double c, const double d)
+void gmshModelGeoSymmetry(const vector_pair &dimTags, const double a,
+                          const double b, const double c, const double d)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  if(GModel::current()->getGEOInternals()->symmetry
-     (dimTags, a, b, c, d))
-    return GMSH_OK;
-  return GMSH_ERROR(1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  if(!GModel::current()->getGEOInternals()->symmetry
+     (dimTags, a, b, c, d)){
+    GMSH_ERROR(1);
+  }
 }
 
-GMSH_API gmshModelGeoCopy(const vector_pair &inDimTags, vector_pair &outDimTags)
+void gmshModelGeoCopy(const vector_pair &dimTags, vector_pair &outDimTags)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   outDimTags.clear();
-  if(GModel::current()->getGEOInternals()->copy(inDimTags, outDimTags))
-    return GMSH_OK;
-  return GMSH_ERROR(1);
+  if(!GModel::current()->getGEOInternals()->copy(dimTags, outDimTags)){
+    GMSH_ERROR(1);
+  }
 }
 
-GMSH_API gmshModelGeoRemove(const vector_pair &dimTags, const bool recursive)
+void gmshModelGeoRemove(const vector_pair &dimTags, const bool recursive)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  if(GModel::current()->getGEOInternals()->remove(dimTags, recursive))
-    return GMSH_OK;
-  return GMSH_ERROR(1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  if(!GModel::current()->getGEOInternals()->remove(dimTags, recursive)){
+    GMSH_ERROR(1);
+  }
 }
 
-GMSH_API gmshModelGeoRemoveAllDuplicates()
+void gmshModelGeoRemoveAllDuplicates()
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   GModel::current()->getGEOInternals()->removeAllDuplicates();
-  return GMSH_OK;
 }
 
-GMSH_API gmshModelGeoSetTransfiniteLine(const int tag, const int nPoints,
-                                        const std::string &type,
-                                        const double coef)
+void gmshModelGeoSetTransfiniteLine(const int tag, const int nPoints,
+                                    const std::string &type,
+                                    const double coef)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   int t =
     (type == "Progression" || type == "Power") ? 1 :
     (type == "Bump") ? 2 :
@@ -895,14 +1127,13 @@ GMSH_API gmshModelGeoSetTransfiniteLine(const int tag, const int nPoints,
   // 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 GMSH_OK;
 }
 
-GMSH_API gmshModelGeoSetTransfiniteSurface(const int tag,
-                                           const std::string &arrangement,
-                                           const std::vector<int> &cornerTags)
+void gmshModelGeoSetTransfiniteSurface(const int tag,
+                                       const std::string &arrangement,
+                                       const std::vector<int> &cornerTags)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   int t =
     (arrangement == "Right") ? 1 :
     (arrangement == "Left") ? -1 :
@@ -911,663 +1142,660 @@ GMSH_API gmshModelGeoSetTransfiniteSurface(const int tag,
     (arrangement == "Alternate") ? 2 :
     -1;
   GModel::current()->getGEOInternals()->setTransfiniteSurface(tag, t, cornerTags);
-  return GMSH_OK;
 }
 
-GMSH_API gmshModelGeoSetTransfiniteVolume(const int tag,
-                                          const std::vector<int> &cornerTags)
+void gmshModelGeoSetTransfiniteVolume(const int tag,
+                                      const std::vector<int> &cornerTags)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   GModel::current()->getGEOInternals()->setTransfiniteVolume(tag, cornerTags);
-  return GMSH_OK;
 }
 
-GMSH_API gmshModelGeoSetRecombine(const int dim, const int tag, const double angle)
+void gmshModelGeoSetRecombine(const int dim, const int tag, const double angle)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   GModel::current()->getGEOInternals()->setRecombine(dim, tag, angle);
-  return GMSH_OK;
 }
 
-GMSH_API gmshModelGeoSetSmoothing(const int dim, const int tag, const int val)
+void gmshModelGeoSetSmoothing(const int dim, const int tag, const int val)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  if(dim != 2) return GMSH_ERROR(1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  if(dim != 2){ GMSH_ERROR(2); }
   GModel::current()->getGEOInternals()->setSmoothing(tag, val);
-  return GMSH_OK;
 }
 
-GMSH_API gmshModelGeoSetReverseMesh(const int dim, const int tag, const bool val)
+void gmshModelGeoSetReverseMesh(const int dim, const int tag, const bool val)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   GModel::current()->getGEOInternals()->setReverseMesh(dim, tag, val);
-  return GMSH_OK;
 }
 
-GMSH_API gmshModelGeoSetMeshSize(const vector_pair &dimTags, const double size)
+void gmshModelGeoSetMeshSize(const vector_pair &dimTags, const double size)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   for(unsigned int i = 0; i < dimTags.size(); i++){
     int dim = dimTags[i].first, tag = dimTags[i].second;
     GModel::current()->getGEOInternals()->setMeshSize(dim, tag, size);
   }
-  return GMSH_OK;
 }
 
-GMSH_API gmshModelGeoSynchronize()
+void gmshModelGeoSynchronize()
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
   GModel::current()->getGEOInternals()->synchronize(GModel::current());
-  return GMSH_OK;
 }
 
 // gmshModelOcc
 
-static void createOcc()
+static void _createOcc()
 {
   if(!GModel::current()->getOCCInternals()) GModel::current()->createOCCInternals();
 }
 
-GMSH_API gmshModelOccAddPoint(const int tag, const double x, const double y,
-                              const double z, const double meshSize)
+int gmshModelOccAddPoint(const double x, const double y, const double z,
+                         const double meshSize, const int tag)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  createOcc();
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  _createOcc();
   int outTag = tag;
-  if(GModel::current()->getOCCInternals()->addVertex(outTag, x, y, z, meshSize)){
-    std::vector<int> ret(1, 0); ret.push_back(outTag);
-    return ret;
+  if(!GModel::current()->getOCCInternals()->addVertex(outTag, x, y, z, meshSize)){
+    GMSH_ERROR(1);
   }
-  return GMSH_ERROR(1);
+  return outTag;
 }
 
-GMSH_API gmshModelOccAddLine(const int tag, const int startTag, const int endTag)
+int gmshModelOccAddLine(const int startTag, const int endTag, const int tag)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  createOcc();
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  _createOcc();
   int outTag = tag;
-  if(GModel::current()->getOCCInternals()->addLine(outTag, startTag, endTag)){
-    std::vector<int> ret(1, 0); ret.push_back(outTag);
-    return ret;
+  if(!GModel::current()->getOCCInternals()->addLine(outTag, startTag, endTag)){
+    GMSH_ERROR(1);
   }
-  return GMSH_ERROR(1);
+  return outTag;
 }
 
-GMSH_API gmshModelOccAddCircleArc(const int tag, const int startTag,
-                                  const int centerTag, const int endTag)
+int gmshModelOccAddCircleArc(const int startTag, const int centerTag,
+                             const int endTag, const int tag)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  createOcc();
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  _createOcc();
   int outTag = tag;
-  if(GModel::current()->getOCCInternals()->addCircleArc
+  if(!GModel::current()->getOCCInternals()->addCircleArc
      (outTag, startTag, centerTag, endTag)){
-    std::vector<int> ret(1, 0); ret.push_back(outTag);
-    return ret;
+    GMSH_ERROR(1);
   }
-  return GMSH_ERROR(1);
+  return outTag;
 }
 
-GMSH_API gmshModelOccAddCircle(const int tag, const double x, const double y,
-                               const double z, const double r, const double angle1,
-                               const double angle2)
+int gmshModelOccAddCircle(const double x, const double y, const double z,
+                          const double r, const int tag,
+                          const double angle1, const double angle2)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  createOcc();
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  _createOcc();
   int outTag = tag;
-  if(GModel::current()->getOCCInternals()->addCircle
+  if(!GModel::current()->getOCCInternals()->addCircle
      (outTag, x, y, z, r, angle1, angle2)){
-    std::vector<int> ret(1, 0); ret.push_back(outTag);
-    return ret;
+    GMSH_ERROR(1);
   }
-  return GMSH_ERROR(1);
+  return outTag;
 }
 
-GMSH_API gmshModelOccAddEllipseArc(const int tag, const int startTag,
-                                   const int centerTag, const int endTag)
+int gmshModelOccAddEllipseArc(const int startTag, const int centerTag,
+                              const int endTag, const int tag)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  createOcc();
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  _createOcc();
   int outTag = tag;
-  if(GModel::current()->getOCCInternals()->addEllipseArc
+  if(!GModel::current()->getOCCInternals()->addEllipseArc
      (outTag, startTag, centerTag, endTag)){
-    std::vector<int> ret(1, 0); ret.push_back(outTag);
-    return ret;
+    GMSH_ERROR(1);
   }
-  return GMSH_ERROR(1);
+  return outTag;
 }
 
-GMSH_API gmshModelOccAddEllipse(const int tag, const double x, const double y,
-                                const double z, const double r1, const double r2,
-                                const double angle1, const double angle2)
+int gmshModelOccAddEllipse(const double x, const double y, const double z,
+                           const double r1, const double r2,
+                           const int tag,
+                           const double angle1, const double angle2)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  createOcc();
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  _createOcc();
   int outTag = tag;
-  if(GModel::current()->getOCCInternals()->addEllipse
+  if(!GModel::current()->getOCCInternals()->addEllipse
      (outTag, x, y, z, r1, r2, angle1, angle2)){
-    std::vector<int> ret(1, 0); ret.push_back(outTag);
-    return ret;
+    GMSH_ERROR(1);
   }
-  return GMSH_ERROR(1);
+  return outTag;
 }
 
-GMSH_API gmshModelOccAddSpline(const int tag, const std::vector<int> &vertexTags)
+int gmshModelOccAddSpline(const std::vector<int> &vertexTags, const int tag)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  createOcc();
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  _createOcc();
   int outTag = tag;
-  if(GModel::current()->getOCCInternals()->addSpline(outTag, vertexTags)){
-    std::vector<int> ret(1, 0); ret.push_back(outTag);
-    return ret;
+  if(!GModel::current()->getOCCInternals()->addSpline(outTag, vertexTags)){
+    GMSH_ERROR(1);
   }
-  return GMSH_ERROR(1);
+  return outTag;
 }
 
-GMSH_API gmshModelOccAddBezier(const int tag, const std::vector<int> &vertexTags)
+int gmshModelOccAddBezier(const std::vector<int> &vertexTags, const int tag)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  createOcc();
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  _createOcc();
   int outTag = tag;
-  if(GModel::current()->getOCCInternals()->addBezier(outTag, vertexTags)){
-    std::vector<int> ret(1, 0); ret.push_back(outTag);
-    return ret;
+  if(!GModel::current()->getOCCInternals()->addBezier(outTag, vertexTags)){
+    GMSH_ERROR(1);
   }
-  return GMSH_ERROR(1);
+  return outTag;
 }
 
-GMSH_API gmshModelOccAddBSpline(const int tag, const std::vector<int> &vertexTags)
+int gmshModelOccAddBSpline(const std::vector<int> &vertexTags, const int tag)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  createOcc();
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  _createOcc();
   int outTag = tag;
-  if(GModel::current()->getOCCInternals()->addBSpline(outTag, vertexTags)){
-    std::vector<int> ret(1, 0); ret.push_back(outTag);
-    return ret;
+  if(!GModel::current()->getOCCInternals()->addBSpline(outTag, vertexTags)){
+    GMSH_ERROR(1);
   }
-  return GMSH_ERROR(1);
+  return outTag;
 }
 
-GMSH_API gmshModelOccAddWire(const int tag, const std::vector<int> &edgeTags,
-                             const bool checkClosed)
+int gmshModelOccAddWire(const std::vector<int> &edgeTags, const int tag,
+                        const bool checkClosed)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  createOcc();
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  _createOcc();
   int outTag = tag;
-  if(GModel::current()->getOCCInternals()->addWire
+  if(!GModel::current()->getOCCInternals()->addWire
      (outTag, edgeTags, checkClosed)){
-    std::vector<int> ret(1, 0); ret.push_back(outTag);
-    return ret;
+    GMSH_ERROR(1);
   }
-  return GMSH_ERROR(1);
+  return outTag;
 }
 
-GMSH_API gmshModelOccAddLineLoop(const int tag, const std::vector<int> &edgeTags)
+int gmshModelOccAddLineLoop(const std::vector<int> &edgeTags, const int tag)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  createOcc();
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  _createOcc();
   int outTag = tag;
-  if(GModel::current()->getOCCInternals()->addLineLoop(outTag, edgeTags)){
-    std::vector<int> ret(1, 0); ret.push_back(outTag);
-    return ret;
+  if(!GModel::current()->getOCCInternals()->addLineLoop(outTag, edgeTags)){
+    GMSH_ERROR(1);
   }
-  return GMSH_ERROR(1);
+  return outTag;
 }
 
-GMSH_API gmshModelOccAddRectangle(const int tag, const double x, const double y,
-                                  const double z, const double dx, const double dy,
-                                  const double roundedRadius)
+int gmshModelOccAddRectangle(const double x, const double y, const double z,
+                             const double dx, const double dy, const int tag,
+                             const double roundedRadius)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  createOcc();
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  _createOcc();
   int outTag = tag;
-  if(GModel::current()->getOCCInternals()->addRectangle
+  if(!GModel::current()->getOCCInternals()->addRectangle
      (outTag, x, y, z, dx, dy, roundedRadius)){
-    std::vector<int> ret(1, 0); ret.push_back(outTag);
-    return ret;
+    GMSH_ERROR(1);
   }
-  return GMSH_ERROR(1);
+  return outTag;
 }
 
-GMSH_API gmshModelOccAddDisk(const int tag, const double xc, const double yc,
-                             const double zc, const double rx, const double ry)
+int gmshModelOccAddDisk(const double xc, const double yc, const double zc,
+                        const double rx, const double ry, const int tag)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  createOcc();
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  _createOcc();
   int outTag = tag;
-  if(GModel::current()->getOCCInternals()->addDisk
+  if(!GModel::current()->getOCCInternals()->addDisk
      (outTag, xc, yc, zc, rx, ry)){
-    std::vector<int> ret(1, 0); ret.push_back(outTag);
-    return ret;
+    GMSH_ERROR(1);
   }
-  return GMSH_ERROR(1);
+  return outTag;
 }
 
-GMSH_API gmshModelOccAddPlaneSurface(const int tag, const std::vector<int> &wireTags)
+int gmshModelOccAddPlaneSurface(const std::vector<int> &wireTags, const int tag)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  createOcc();
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  _createOcc();
   int outTag = tag;
-  if(GModel::current()->getOCCInternals()->addPlaneSurface(outTag, wireTags)){
-    std::vector<int> ret(1, 0); ret.push_back(outTag);
-    return ret;
+  if(!GModel::current()->getOCCInternals()->addPlaneSurface(outTag, wireTags)){
+    GMSH_ERROR(1);
   }
-  return GMSH_ERROR(1);
+  return outTag;
 }
 
-GMSH_API gmshModelOccAddSurfaceFilling(const int tag, const int wireTag)
+int gmshModelOccAddSurfaceFilling(const int wireTag, const int tag)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  createOcc();
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  _createOcc();
   int outTag = tag;
-  if(GModel::current()->getOCCInternals()->addSurfaceFilling(outTag, wireTag)){
-    std::vector<int> ret(1, 0); ret.push_back(outTag);
-    return ret;
+  if(!GModel::current()->getOCCInternals()->addSurfaceFilling(outTag, wireTag)){
+    GMSH_ERROR(1);
   }
-  return GMSH_ERROR(1);
+  return outTag;
 }
 
-GMSH_API gmshModelOccAddSurfaceLoop(const int tag, const std::vector<int> &faceTags)
+int gmshModelOccAddSurfaceLoop(const std::vector<int> &faceTags, const int tag)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  createOcc();
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  _createOcc();
   int outTag = tag;
-  if(GModel::current()->getOCCInternals()->addSurfaceLoop(outTag, faceTags)){
-    std::vector<int> ret(1, 0); ret.push_back(outTag);
-    return ret;
+  if(!GModel::current()->getOCCInternals()->addSurfaceLoop(outTag, faceTags)){
+    GMSH_ERROR(1);
   }
-  return GMSH_ERROR(1);
+  return outTag;
 }
 
-GMSH_API gmshModelOccAddVolume(const int tag, const std::vector<int> &shellTags)
+int gmshModelOccAddVolume(const std::vector<int> &shellTags, const int tag)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  createOcc();
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  _createOcc();
   int outTag = tag;
-  if(GModel::current()->getOCCInternals()->addVolume(outTag, shellTags)){
-    std::vector<int> ret(1, 0); ret.push_back(outTag);
-    return ret;
+  if(!GModel::current()->getOCCInternals()->addVolume(outTag, shellTags)){
+    GMSH_ERROR(1);
   }
-  return GMSH_ERROR(1);
+  return outTag;
 }
 
-GMSH_API gmshModelOccAddSphere(const int tag, const double xc, const double yc,
-                               const double zc, const double radius,
-                               const double angle1, const double angle2,
-                               const double angle3)
+int gmshModelOccAddSphere(const double xc, const double yc, const double zc,
+                          const double radius, const int tag,
+                          const double angle1, const double angle2,
+                          const double angle3)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  createOcc();
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  _createOcc();
   int outTag = tag;
-  if(GModel::current()->getOCCInternals()->addSphere
+  if(!GModel::current()->getOCCInternals()->addSphere
      (outTag, xc, yc, zc, radius, angle1, angle2, angle3)){
-    std::vector<int> ret(1, 0); ret.push_back(outTag);
-    return ret;
+    GMSH_ERROR(1);
   }
-  return GMSH_ERROR(1);
+  return outTag;
 }
 
-GMSH_API gmshModelOccAddBox(const int tag, const double x, const double y,
-                            const double z, const double dx, const double dy,
-                            const double dz)
+int gmshModelOccAddBox(const double x, const double y, const double z,
+                       const double dx, const double dy, const double dz,
+                       const int tag)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  createOcc();
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  _createOcc();
   int outTag = tag;
-  if(GModel::current()->getOCCInternals()->addBox
+  if(!GModel::current()->getOCCInternals()->addBox
      (outTag, x, y, z, dx, dy, dz)){
-    std::vector<int> ret(1, 0); ret.push_back(outTag);
-    return ret;
+    GMSH_ERROR(1);
   }
-  return GMSH_ERROR(1);
+  return outTag;
 }
 
-GMSH_API gmshModelOccAddCylinder(const int tag, const double x, const double y,
-                                 const double z, const double dx, const double dy,
-                                 const double dz, const double r, const double angle)
+int gmshModelOccAddCylinder(const double x, const double y, const double z,
+                            const double dx, const double dy, const double dz,
+                            const double r, const int tag, const double angle)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  createOcc();
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  _createOcc();
   int outTag = tag;
-  if(GModel::current()->getOCCInternals()->addCylinder
+  if(!GModel::current()->getOCCInternals()->addCylinder
      (outTag, x, y, z, dx, dy, dz, r, angle)){
-    std::vector<int> ret(1, 0); ret.push_back(outTag);
-    return ret;
+    GMSH_ERROR(1);
   }
-  return GMSH_ERROR(1);
+  return outTag;
 }
 
-GMSH_API gmshModelOccAddCone(const int tag, const double x, const double y,
-                             const double z, const double dx, const double dy,
-                             const double dz, const double r1, const double r2,
-                             const double angle)
+int gmshModelOccAddCone(const double x, const double y, const double z,
+                        const double dx, const double dy, const double dz,
+                        const double r1, const double r2, const int tag,
+                        const double angle)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  createOcc();
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  _createOcc();
   int outTag = tag;
-  if(GModel::current()->getOCCInternals()->addCone
+  if(!GModel::current()->getOCCInternals()->addCone
      (outTag, x, y, z, dx, dy, dz, r1, r2, angle)){
-    std::vector<int> ret(1, 0); ret.push_back(outTag);
-    return ret;
+    GMSH_ERROR(1);
   }
-  return GMSH_ERROR(1);
+  return outTag;
 }
 
-GMSH_API gmshModelOccAddWedge(const int tag, const double x, const double y,
-                              const double z, const double dx, const double dy,
-                              const double dz, const double ltx)
+int gmshModelOccAddWedge(const double x, const double y, const double z,
+                         const double dx, const double dy, const double dz,
+                         const int tag, const double ltx)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  createOcc();
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  _createOcc();
   int outTag = tag;
-  if(GModel::current()->getOCCInternals()->addWedge
+  if(!GModel::current()->getOCCInternals()->addWedge
      (outTag, x, y, z, dx, dy, dz, ltx)){
-    std::vector<int> ret(1, 0); ret.push_back(outTag);
-    return ret;
+    GMSH_ERROR(1);
   }
-  return GMSH_ERROR(1);
+  return outTag;
 }
 
-GMSH_API gmshModelOccAddTorus(const int tag, const double x, const double y,
-                              const double z, const double r1, const double r2,
-                              const double angle)
+int gmshModelOccAddTorus(const double x, const double y, const double z,
+                         const double r1, const double r2, const int tag,
+                         const double angle)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  createOcc();
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  _createOcc();
   int outTag = tag;
-  if(GModel::current()->getOCCInternals()->addTorus
+  if(!GModel::current()->getOCCInternals()->addTorus
      (outTag, x, y, z, r1, r2, angle)){
-    std::vector<int> ret(1, 0); ret.push_back(outTag);
-    return ret;
+    GMSH_ERROR(1);
   }
-  return GMSH_ERROR(1);
+  return outTag;
 }
 
-GMSH_API gmshModelOccAddThruSections(const int tag, const std::vector<int> &wireTags,
-                                     vector_pair &outDimTags, const bool makeSolid,
-                                     const bool makeRuled)
+int gmshModelOccAddThruSections(const std::vector<int> &wireTags,
+                                vector_pair &outDimTags,
+                                const int tag, const bool makeSolid,
+                                const bool makeRuled)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  createOcc();
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  _createOcc();
+  int outTag = tag;
   outDimTags.clear();
-  if(GModel::current()->getOCCInternals()->addThruSections
-    (tag, wireTags, makeSolid, makeRuled, outDimTags))
-    return GMSH_OK;
-  return GMSH_ERROR(1);
+  if(!GModel::current()->getOCCInternals()->addThruSections
+     (outTag, wireTags, makeSolid, makeRuled, outDimTags)){
+    GMSH_ERROR(1);
+  }
+  return outTag;
 }
 
-GMSH_API addThickSolid(const int tag, const int solidTag,
-                       const std::vector<int> &excludeFaceTags,
-                       const double offset, vector_pair &outDimTags)
+int addThickSolid(const int solidTag,
+                  const std::vector<int> &excludeFaceTags,
+                  const double offset, vector_pair &outDimTags,
+                  const int tag)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  createOcc();
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  _createOcc();
+  int outTag = tag;
   outDimTags.clear();
-  if(GModel::current()->getOCCInternals()->addThickSolid
-    (tag, solidTag, excludeFaceTags, offset, outDimTags))
-    return GMSH_OK;
-  return GMSH_ERROR(1);
+  if(!GModel::current()->getOCCInternals()->addThickSolid
+     (outTag, solidTag, excludeFaceTags, offset, outDimTags)){
+    GMSH_ERROR(1);
+  }
+  return outTag;
 }
 
-GMSH_API gmshModelOccExtrude(const vector_pair &inDimTags,
-                             const double dx, const double dy, const double dz,
-                             vector_pair &outDimTags,
-                             const std::vector<int> &numElements,
-                             const std::vector<double> &heights,
-                             const bool recombine)
+void gmshModelOccExtrude(const vector_pair &dimTags,
+                         const double dx, const double dy, const double dz,
+                         vector_pair &outDimTags,
+                         const std::vector<int> &numElements,
+                         const std::vector<double> &heights,
+                         const bool recombine)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  createOcc();
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  _createOcc();
   outDimTags.clear();
-  if(GModel::current()->getOCCInternals()->extrude
-    (inDimTags, dx, dy, dz, outDimTags,
-     getExtrudeParams(numElements, heights, recombine)))
-    return GMSH_OK;
-  return GMSH_ERROR(1);
-}
-
-GMSH_API gmshModelOccRevolve(const vector_pair &inDimTags,
-                             const double x, const double y, const double z,
-                             const double ax, const double ay, const double az,
-                             const double angle, vector_pair &outDimTags,
-                             const std::vector<int> &numElements,
-                             const std::vector<double> &heights,
-                             const bool recombine)
-{
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  createOcc();
+  if(!GModel::current()->getOCCInternals()->extrude
+    (dimTags, dx, dy, dz, outDimTags,
+     _getExtrudeParams(numElements, heights, recombine))){
+    GMSH_ERROR(1);
+  }
+}
+
+void gmshModelOccRevolve(const vector_pair &dimTags,
+                         const double x, const double y, const double z,
+                         const double ax, const double ay, const double az,
+                         const double angle, vector_pair &outDimTags,
+                         const std::vector<int> &numElements,
+                         const std::vector<double> &heights,
+                         const bool recombine)
+{
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  _createOcc();
   outDimTags.clear();
-  if(GModel::current()->getOCCInternals()->revolve
-    (inDimTags, x, y, z, ax, ay, az, angle, outDimTags,
-     getExtrudeParams(numElements, heights, recombine)))
-    return GMSH_OK;
-  return GMSH_ERROR(1);
+  if(!GModel::current()->getOCCInternals()->revolve
+     (dimTags, x, y, z, ax, ay, az, angle, outDimTags,
+      _getExtrudeParams(numElements, heights, recombine))){
+    GMSH_ERROR(1);
+  }
 }
 
-GMSH_API gmshModelOccAddPipe(const vector_pair &inDimTags, const int wireTag,
-                             vector_pair &outDimTags)
+void gmshModelOccAddPipe(const vector_pair &dimTags, const int wireTag,
+                         vector_pair &outDimTags)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  createOcc();
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  _createOcc();
   outDimTags.clear();
-  if(GModel::current()->getOCCInternals()->addPipe
-    (inDimTags, wireTag, outDimTags))
-    return GMSH_OK;
-  return GMSH_ERROR(1);
+  if(!GModel::current()->getOCCInternals()->addPipe
+     (dimTags, wireTag, outDimTags)){
+    GMSH_ERROR(1);
+  }
 }
 
-GMSH_API gmshModelOccFillet(const std::vector<int> &regionTags,
-                            const std::vector<int> &edgeTags,
-                            const double radius, vector_pair &outDimTags,
-                            const bool removeRegion)
+void gmshModelOccFillet(const std::vector<int> &regionTags,
+                        const std::vector<int> &edgeTags,
+                        const double radius, vector_pair &outDimTags,
+                        const bool removeRegion)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  createOcc();
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  _createOcc();
   outDimTags.clear();
-  if(GModel::current()->getOCCInternals()->fillet
-    (regionTags, edgeTags, radius, outDimTags, removeRegion))
-    return GMSH_OK;
-  return GMSH_ERROR(1);
+  if(!GModel::current()->getOCCInternals()->fillet
+     (regionTags, edgeTags, radius, outDimTags, removeRegion)){
+    GMSH_ERROR(1);
+  }
 }
 
-GMSH_API gmshModelOccBooleanUnion(const int tag,
-                                  const vector_pair &objectDimTags,
-                                  const vector_pair &toolDimTags,
-                                  vector_pair &outDimTags,
-                                  std::vector<vector_pair > &outDimTagsMap,
-                                  const bool removeObject,
-                                  const bool removeTool)
+int gmshModelOccBooleanUnion(const vector_pair &objectDimTags,
+                             const vector_pair &toolDimTags,
+                             vector_pair &outDimTags,
+                             std::vector<vector_pair > &outDimTagsMap,
+                             const int tag,
+                             const bool removeObject,
+                             const bool removeTool)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  createOcc();
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  _createOcc();
+  int outTag = tag;
   outDimTags.clear();
   outDimTagsMap.clear();
-  if(GModel::current()->getOCCInternals()->booleanUnion
-    (tag, objectDimTags, toolDimTags, outDimTags, outDimTagsMap,
-     removeObject, removeTool))
-    return GMSH_OK;
-  return GMSH_ERROR(1);
-}
-
-GMSH_API gmshModelOccBooleanIntersection(const int tag,
-                                         const vector_pair &objectDimTags,
-                                         const vector_pair &toolDimTags,
-                                         vector_pair &outDimTags,
-                                         std::vector<vector_pair> &outDimTagsMap,
-                                         const bool removeObject,
-                                         const bool removeTool)
-{
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  createOcc();
+  if(!GModel::current()->getOCCInternals()->booleanUnion
+     (outTag, objectDimTags, toolDimTags, outDimTags, outDimTagsMap,
+      removeObject, removeTool)){
+    GMSH_ERROR(1);
+  }
+  return outTag;
+}
+
+int gmshModelOccBooleanIntersection(const vector_pair &objectDimTags,
+                                    const vector_pair &toolDimTags,
+                                    vector_pair &outDimTags,
+                                    std::vector<vector_pair> &outDimTagsMap,
+                                    const int tag,
+                                    const bool removeObject,
+                                    const bool removeTool)
+{
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  _createOcc();
+  int outTag = tag;
   outDimTags.clear();
   outDimTagsMap.clear();
-  if(GModel::current()->getOCCInternals()->booleanIntersection
-    (tag, objectDimTags, toolDimTags, outDimTags, outDimTagsMap,
-     removeObject, removeTool))
-    return GMSH_OK;
-  return GMSH_ERROR(1);
-}
-
-GMSH_API gmshModelOccBooleanDifference(const int tag,
-                                       const vector_pair &objectDimTags,
-                                       const vector_pair &toolDimTags,
-                                       vector_pair &outDimTags,
-                                       std::vector<vector_pair> &outDimTagsMap,
-                                       const bool removeObject,
-                                       const bool removeTool)
-{
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  createOcc();
+  if(!GModel::current()->getOCCInternals()->booleanIntersection
+     (outTag, objectDimTags, toolDimTags, outDimTags, outDimTagsMap,
+      removeObject, removeTool)){
+    GMSH_ERROR(1);
+  }
+  return outTag;
+}
+
+int gmshModelOccBooleanDifference(const vector_pair &objectDimTags,
+                                  const vector_pair &toolDimTags,
+                                  vector_pair &outDimTags,
+                                  std::vector<vector_pair> &outDimTagsMap,
+                                  const int tag,
+                                  const bool removeObject,
+                                  const bool removeTool)
+{
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  _createOcc();
+  int outTag = tag;
   outDimTags.clear();
   outDimTagsMap.clear();
-  if(GModel::current()->getOCCInternals()->booleanDifference
-    (tag, objectDimTags, toolDimTags, outDimTags, outDimTagsMap,
-     removeObject, removeTool))
-    return GMSH_OK;
-  return GMSH_ERROR(1);
-}
-
-GMSH_API gmshModelOccBooleanFragments(const int tag,
-                                      const vector_pair &objectDimTags,
-                                      const vector_pair &toolDimTags,
-                                      vector_pair &outDimTags,
-                                      std::vector<vector_pair> &outDimTagsMap,
-                                      const bool removeObject,
-                                      const bool removeTool)
-{
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  createOcc();
+  if(!GModel::current()->getOCCInternals()->booleanDifference
+     (outTag, objectDimTags, toolDimTags, outDimTags, outDimTagsMap,
+      removeObject, removeTool)){
+    GMSH_ERROR(1);
+  }
+  return outTag;
+}
+
+int gmshModelOccBooleanFragments(const vector_pair &objectDimTags,
+                                 const vector_pair &toolDimTags,
+                                 vector_pair &outDimTags,
+                                 std::vector<vector_pair> &outDimTagsMap,
+                                 const int tag,
+                                 const bool removeObject,
+                                 const bool removeTool)
+{
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  _createOcc();
+  int outTag = tag;
   outDimTags.clear();
   outDimTagsMap.clear();
-  if(GModel::current()->getOCCInternals()->booleanFragments
-    (tag, objectDimTags, toolDimTags, outDimTags, outDimTagsMap,
-     removeObject, removeTool))
-    return GMSH_OK;
-  return GMSH_ERROR(1);
+  if(!GModel::current()->getOCCInternals()->booleanFragments
+     (outTag, objectDimTags, toolDimTags, outDimTags, outDimTagsMap,
+      removeObject, removeTool)){
+    GMSH_ERROR(1);
+  }
+  return outTag;
 }
 
-GMSH_API gmshModelOccTranslate(const vector_pair &dimTags, const double dx,
-                               const double dy, const double dz)
+void gmshModelOccTranslate(const vector_pair &dimTags, const double dx,
+                           const double dy, const double dz)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  createOcc();
-  if(GModel::current()->getOCCInternals()->translate(dimTags, dx, dy, dz))
-    return GMSH_OK;
-  return GMSH_ERROR(1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  _createOcc();
+  if(!GModel::current()->getOCCInternals()->translate(dimTags, dx, dy, dz)){
+    GMSH_ERROR(1);
+  }
 }
 
-GMSH_API gmshModelOccRotate(const vector_pair &dimTags, const double x,
-                            const double y, const double z, const double ax,
-                            const double ay, const double az, const double angle)
+void gmshModelOccRotate(const vector_pair &dimTags, const double x,
+                        const double y, const double z, const double ax,
+                        const double ay, const double az, const double angle)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  createOcc();
-  if(GModel::current()->getOCCInternals()->rotate
-    (dimTags, x, y, z, ax, ay, az, angle))
-    return GMSH_OK;
-  return GMSH_ERROR(1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  _createOcc();
+  if(!GModel::current()->getOCCInternals()->rotate
+     (dimTags, x, y, z, ax, ay, az, angle)){
+    GMSH_ERROR(1);
+  }
 }
 
-GMSH_API gmshModelOccDilate(const vector_pair &dimTags, const double x,
-                            const double y, const double z, const double a,
-                            const double b, const double c)
+void gmshModelOccDilate(const vector_pair &dimTags, const double x,
+                        const double y, const double z, const double a,
+                        const double b, const double c)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  createOcc();
-  if(GModel::current()->getOCCInternals()->dilate
-    (dimTags, x, y, z, a, b, c))
-    return GMSH_OK;
-  return GMSH_ERROR(1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  _createOcc();
+  if(!GModel::current()->getOCCInternals()->dilate
+     (dimTags, x, y, z, a, b, c)){
+    GMSH_ERROR(1);
+  }
 }
 
-GMSH_API gmshModelOccSymmetry(const vector_pair &dimTags, const double a,
-                              const double b, const double c, const double d)
+void gmshModelOccSymmetry(const vector_pair &dimTags, const double a,
+                          const double b, const double c, const double d)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  createOcc();
-  if(GModel::current()->getOCCInternals()->symmetry
-    (dimTags, a, b, c, d))
-    return GMSH_OK;
-  return GMSH_ERROR(1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  _createOcc();
+  if(!GModel::current()->getOCCInternals()->symmetry(dimTags, a, b, c, d)){
+    GMSH_ERROR(1);
+  }
 }
 
-GMSH_API gmshModelOccCopy(const vector_pair &inDimTags, vector_pair &outDimTags)
+void gmshModelOccCopy(const vector_pair &dimTags, vector_pair &outDimTags)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  createOcc();
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  _createOcc();
   outDimTags.clear();
-  if(GModel::current()->getOCCInternals()->copy(inDimTags, outDimTags))
-    return GMSH_OK;
-  return GMSH_ERROR(1);
+  if(!GModel::current()->getOCCInternals()->copy(dimTags, outDimTags)){
+    GMSH_ERROR(1);
+  }
 }
 
-GMSH_API gmshModelOccRemove(const vector_pair &dimTags, const bool recursive)
+void gmshModelOccRemove(const vector_pair &dimTags, const bool recursive)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  createOcc();
-  if(GModel::current()->getOCCInternals()->remove(dimTags, recursive))
-    return GMSH_OK;
-  return GMSH_ERROR(1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  _createOcc();
+  if(!GModel::current()->getOCCInternals()->remove(dimTags, recursive)){
+    GMSH_ERROR(1);
+  }
 }
 
-GMSH_API gmshModelOccRemoveAllDuplicates()
+void gmshModelOccRemoveAllDuplicates()
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  createOcc();
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  _createOcc();
   GModel::current()->getOCCInternals()->removeAllDuplicates();
-  return GMSH_OK;
 }
 
-GMSH_API gmshModelOccImportShapes(const std::string &fileName,
-                                  vector_pair &outDimTags,
-                                  const bool highestDimOnly,
-                                  const std::string &format)
+void gmshModelOccImportShapes(const std::string &fileName,
+                              vector_pair &outDimTags,
+                              const bool highestDimOnly,
+                              const std::string &format)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  createOcc();
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  _createOcc();
   outDimTags.clear();
-  if(GModel::current()->getOCCInternals()->importShapes
-    (fileName, highestDimOnly, outDimTags, format))
-    return GMSH_OK;
-  return GMSH_ERROR(1);
+  if(!GModel::current()->getOCCInternals()->importShapes
+     (fileName, highestDimOnly, outDimTags, format)){
+    GMSH_ERROR(1);
+  }
 }
 
-GMSH_API gmshModelOccSetMeshSize(const vector_pair &dimTags, const double size)
+void gmshModelOccSetMeshSize(const vector_pair &dimTags, const double size)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  createOcc();
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  _createOcc();
   for(unsigned int i = 0; i < dimTags.size(); i++){
     int dim = dimTags[i].first, tag = dimTags[i].second;
     GModel::current()->getOCCInternals()->setMeshSize(dim, tag, size);
   }
-  return GMSH_OK;
 }
 
-GMSH_API gmshModelOccSynchronize()
+void gmshModelOccSynchronize()
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
-  createOcc();
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  _createOcc();
   GModel::current()->getOCCInternals()->synchronize(GModel::current());
-  return GMSH_OK;
 }
 
 // gmshModelField
 
-GMSH_API gmshModelFieldCreate(const int tag, const std::string &type)
+int gmshModelFieldCreate(const std::string &type, const int tag)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
+  int outTag = tag;
 #if defined(HAVE_MESH)
+  if(outTag < 0){
+    outTag = GModel::current()->getFields()->newId();
+  }
   if(!GModel::current()->getFields()->newField(tag, type)){
     Msg::Error("Cannot create Field %i of type '%s'", tag, type.c_str());
-    return GMSH_ERROR(1);
+    GMSH_ERROR(1);
   }
-  return GMSH_OK;
 #else
-  return GMSH_ERROR(1);
+  Msg::Error("Fields require the mesh module");
+  GMSH_ERROR(-1);
 #endif
+  return outTag;
 }
 
+void gmshModelFieldDelete(const int tag)
+{
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
 #if defined(HAVE_MESH)
-static FieldOption *getFieldOption(const int tag, const std::string &option)
+  GModel::current()->getFields()->deleteField(tag);
+#else
+  Msg::Error("Fields require the mesh module");
+  GMSH_ERROR(-1);
+#endif
+}
+
+#if defined(HAVE_MESH)
+static FieldOption *_getFieldOption(const int tag, const std::string &option)
 {
   Field *field = GModel::current()->getFields()->get(tag);
   if(!field){
@@ -1584,51 +1812,51 @@ static FieldOption *getFieldOption(const int tag, const std::string &option)
 }
 #endif
 
-GMSH_API gmshModelFieldSetNumber(const int tag, const std::string &option,
-                                 const double value)
+void gmshModelFieldSetNumber(const int tag, const std::string &option,
+                             const double value)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
 #if defined(HAVE_MESH)
-  FieldOption *o = getFieldOption(tag, option);
-  if(!o) return GMSH_ERROR(1);
+  FieldOption *o = _getFieldOption(tag, option);
+  if(!o){ GMSH_ERROR(1); }
   try { o->numericalValue(value); }
   catch(...){
     Msg::Error("Cannot set numerical value to option '%s' in field %i",
                option.c_str(), tag);
-    return GMSH_ERROR(1);
+    GMSH_ERROR(1);
   }
-  return GMSH_OK;
 #else
-  return GMSH_ERROR(1);
+  Msg::Error("Fields require the mesh module");
+  GMSH_ERROR(-1);
 #endif
 }
 
-GMSH_API gmshModelFieldSetString(const int tag, const std::string &option,
-                                 const std::string &value)
+void gmshModelFieldSetString(const int tag, const std::string &option,
+                             const std::string &value)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
 #if defined(HAVE_MESH)
-  FieldOption *o = getFieldOption(tag, option);
-  if(!o) return GMSH_ERROR(1);
+  FieldOption *o = _getFieldOption(tag, option);
+  if(!o){ GMSH_ERROR(1); }
   try { o->string(value); }
   catch(...){
     Msg::Error("Cannot set string value to option '%s' in field %i",
                option.c_str(), tag);
-    return GMSH_ERROR(1);
+    GMSH_ERROR(1);
   }
-  return GMSH_OK;
 #else
-  return GMSH_ERROR(1);
+  Msg::Error("Fields require the mesh module");
+  GMSH_ERROR(-1);
 #endif
 }
 
-GMSH_API gmshModelFieldSetNumbers(const int tag, const std::string &option,
-                                  const std::vector<double> &value)
+void gmshModelFieldSetNumbers(const int tag, const std::string &option,
+                              const std::vector<double> &value)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
 #if defined(HAVE_MESH)
-  FieldOption *o = getFieldOption(tag, option);
-  if(!o) return GMSH_ERROR(1);
+  FieldOption *o = _getFieldOption(tag, option);
+  if(!o){ GMSH_ERROR(1); }
   try {
     if(o->getType() == FIELD_OPTION_LIST) {
       std::list<int> vl;
@@ -1646,32 +1874,22 @@ GMSH_API gmshModelFieldSetNumbers(const int tag, const std::string &option,
   catch(...){
     Msg::Error("Cannot set numeric values to option '%s' in field %i",
                option.c_str(), tag);
-    return GMSH_ERROR(1);
+    GMSH_ERROR(1);
   }
-  return GMSH_OK;
 #else
-  return GMSH_ERROR(1);
+  Msg::Error("Fields require the mesh module");
+  GMSH_ERROR(-1);
 #endif
 }
 
-GMSH_API gmshModelFieldSetAsBackground(const int tag)
+void gmshModelFieldSetAsBackground(const int tag)
 {
-  if(!isInitialized()) return GMSH_ERROR(-1);
+  if(!_isInitialized()){ GMSH_ERROR(-1); }
 #if defined(HAVE_MESH)
   GModel::current()->getFields()->setBackgroundFieldId(tag);
-  return GMSH_OK;
 #else
-  return GMSH_ERROR(1);
+  Msg::Error("Fields require the mesh module");
+  GMSH_ERROR(-1);
 #endif
 }
 
-GMSH_API gmshModelFieldDelete(const int tag)
-{
-  if(!isInitialized()) return GMSH_ERROR(-1);
-#if defined(HAVE_MESH)
-  GModel::current()->getFields()->deleteField(tag);
-  return GMSH_OK;
-#else
-  return GMSH_ERROR(1);
-#endif
-}
diff --git a/Common/gmsh.h b/Common/gmsh.h
index 3a05835b225d781c0fca27d8b7a13a8949a90a20..30cd91821c1b5bec0d1ab9f49da46eb11af20eaf 100644
--- a/Common/gmsh.h
+++ b/Common/gmsh.h
@@ -6,307 +6,566 @@
 #ifndef _GMSH_H_
 #define _GMSH_H_
 
-// This is the embryo of what will become the Gmsh API.
+// This file defines the Gmsh API.
 //
-// Don't use it yet, it's not ready :-) We plan to release a first version in
-// Gmsh 3.1, and something more complete in Gmsh 4.0.
-//
-// Your input is welcome: please contribute your ideas on
-// https://gitlab.onelab.info/gmsh/gmsh/issues/188
+// A first beta version will be released in Gmsh 3.1. The first stable release
+// in planned for Gmsh 4.0.
 //
 // By design, the API is purely functional, and only uses elementary C++ types
-// from the standard library. This design should not and will not change.
-
-// All functions return 0 as the first entry of the returned vector on
-// successful completion. Additional integer results can be appends to this
-// returned value, depending on context.
+// from the standard library. Python wrappers are automatically generated; a
+// JavaScript and a pure C version are also planned.
+//
+// See `gmsh/demos/api' for examples (in C++ and Python) on how to use the
+// API. In particular, `gmsh/demos/api' contains C++ and Python versions of
+// several of the .geo tutorials from `gmsh/tutorials'.
+//
+// Your input is very welcome: please contribute your ideas and suggestions on
+// https://gitlab.onelab.info/gmsh/gmsh/issues/188
 
 #include <cmath>
 #include <vector>
 #include <string>
 
 #if defined(WIN32)
-#define GMSH_API __declspec(dllexport) std::vector<int>
+#define GMSH_API __declspec(dllexport)
 #else
-#define GMSH_API std::vector<int>
+#define GMSH_API
 #endif
 
+// A geometrical entity in the Gmsh API is represented by two integers: its
+// dimension (dim = 0, 1, 2 or 3) and its tag (its unique identifier). When
+// dealing with multiple geometrical entities of possibly different dimensions,
+// the entities are packed as a vector of (dim, tag) integer pairs.
 typedef std::vector<std::pair<int, int> > vector_pair;
 
-// gmsh
-GMSH_API gmshInitialize(int argc = 0, char **argv = 0);
-GMSH_API gmshFinalize();
-GMSH_API gmshOpen(const std::string &fileName);
-GMSH_API gmshMerge(const std::string &fileName);
-GMSH_API gmshExport(const std::string &fileName);
-GMSH_API gmshClear();
-
-// gmshOption
-GMSH_API gmshOptionSetNumber(const std::string &name, const double value);
-GMSH_API gmshOptionGetNumber(const std::string &name, double &value);
-GMSH_API gmshOptionSetString(const std::string &name, const std::string &value);
-GMSH_API gmshOptionGetString(const std::string &name, std::string &value);
-
-// gmshModel
-GMSH_API gmshModelCreate(const std::string &name);
-GMSH_API gmshModelSetCurrent(const std::string &name);
-GMSH_API gmshModelDestroy();
-GMSH_API gmshModelGetEntities(vector_pair &dimTags, const int dim=-1);
-GMSH_API gmshModelGetPhysicalGroups(vector_pair &dimTags, const int dim=-1);
-GMSH_API gmshModelAddPhysicalGroup(const int dim, const int tag,
-                                   const std::vector<int> &tags);
-GMSH_API gmshModelGetEntitiesForPhysicalGroup(const int dim, const int tag,
-                                              std::vector<int> &tags);
-GMSH_API gmshModelSetPhysicalName(const int dim, const int tag,
-                                  const std::string &name);
-GMSH_API gmshModelGetPhysicalName(const int dim, const int tag,
-                                  std::string &name);
-GMSH_API gmshModelGetVertexCoordinates(const int tag, double &x, double &y,
-                                       double &z);
-GMSH_API gmshModelGetBoundary(const vector_pair &inDimTags, vector_pair &outDimTags,
-                              const bool combined = true, const bool oriented = true,
-                              const bool recursive = false);
-GMSH_API gmshModelGetEntitiesInBoundingBox(const double x1, const double y1,
-                                           const double z1, const double x2,
-                                           const double y2, const double z2,
-                                           vector_pair &tags, const int dim=-1);
-GMSH_API gmshModelGetBoundingBox(const int dim, const int tag, double &x1, double &y1,
-                                 double &z1, double &x2, double &y2, double &z2);
-GMSH_API gmshModelRemove(const vector_pair &dimTags, const bool recursive = false);
-GMSH_API gmshModelMesh(const int dim);
-GMSH_API gmshModelGetMeshVertices(const int dim, const int tag,
-                                  std::vector<int> &vertexTags,
-                                  std::vector<double> &coords);
-GMSH_API gmshModelGetMeshElements(const int dim, const int tag,
-                                  std::vector<int> &types,
-                                  std::vector<std::vector<int> > &elementTags,
-                                  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 std::string &type = "Progression",
-                                     const double coef = 1.);
-GMSH_API gmshModelSetTransfiniteSurface(const int tag,
-                                        const std::string &arrangement = "Left",
-                                        const std::vector<int> &cornerTags =
+// -----------------------------------------------------------------------------
+// Module "gmsh": top-level functions
+// -----------------------------------------------------------------------------
+
+// Initializes Gmsh. `gmshInitialize()' must be called before any call to the
+// other functions in the API. If argc and argv are are provided, they will be
+// handled in the same way as the command line arguments in the Gmsh app.
+GMSH_API void gmshInitialize(int argc = 0, char **argv = 0);
+
+// Finalizes Gmsh. This must be called when you are done using the Gmsh API.
+GMSH_API void gmshFinalize();
+
+// Opens a file and creates one (or more) new model(s). Equivalent to the
+// File->Open menu in the Gmsh app. Handling of the file depends on its
+// extension and/or its contents.
+GMSH_API void gmshOpen(const std::string &fileName);
+
+// Merges a file. Equivalent to the File->Merge menu in the Gmsh app. Handling
+// of the file depends on its extension and/or its contents.
+GMSH_API void gmshMerge(const std::string &fileName);
+
+// Exports a file. The export format is determined by the file extension.
+GMSH_API void gmshExport(const std::string &fileName);
+
+// Clears all loaded models and post-processing data, and creates a new empty
+// model.
+GMSH_API void gmshClear();
+
+// -----------------------------------------------------------------------------
+// Module "gmshOption": global option handling functions
+// -----------------------------------------------------------------------------
+
+// Sets a numerical option to `value'. `name' is of the form "category.option"
+// or "category[num].option". Available categories and options are listed in the
+// Gmsh reference manual.
+GMSH_API void gmshOptionSetNumber(const std::string &name, const double value);
+
+// Gets the `value' of a numerical option.
+GMSH_API void gmshOptionGetNumber(const std::string &name, double &value);
+
+// Sets a string option to `value'.
+GMSH_API void gmshOptionSetString(const std::string &name,
+                                  const std::string &value);
+
+// Gets the `value' of a string option.
+GMSH_API void gmshOptionGetString(const std::string &name, std::string &value);
+
+// -----------------------------------------------------------------------------
+// Module "gmshModel": per-model functions
+// -----------------------------------------------------------------------------
+
+// Creates a new model, with name `name', and sets it as the current model.
+GMSH_API void gmshModelCreate(const std::string &name);
+
+// Deletes the current model.
+GMSH_API void gmshModelDelete();
+
+// Lists the names of all models.
+GMSH_API void gmshModelList(std::vector<std::string> &names);
+
+// Sets the current model to the model with name `name'. If several models have
+// the same name, selects the one that was created first.
+GMSH_API void gmshModelSetCurrent(const std::string &name);
+
+// Gets all the (elementary) geometrical entities in the current model. If `dim'
+// is >= 0, returns only the entities of the specified dimension (e.g. points if
+// `dim' == 0). The entities are returned as a vector of (dim, tag) integer
+// pairs.
+GMSH_API void gmshModelGetEntities(vector_pair &dimTags, const int dim = -1);
+
+// Gets all the physical groups in the current model. If `dim' is >= 0, returns
+// only the entities of the specified dimension (e.g. physical points if `dim'
+// == 0). The entities are returned as a vector of (dim, tag) integer pairs.
+GMSH_API void gmshModelGetPhysicalGroups(vector_pair &dimTags,
+                                         const int dim = -1);
+
+// Gets the tags of all the (elementary) geometrical entities grouped in the
+// physical group of dimension `dim' and tag `tag'.
+GMSH_API void gmshModelGetEntitiesForPhysicalGroup(const int dim, const int tag,
+                                                   std::vector<int> &tags);
+
+// Adds a physical group of dimension `dim', grouping the elementary entities
+// with tags `tags'. The function returns the tag of the physical group, equal
+// to `tag' if `tag' > 0, or a new tag if not.
+GMSH_API int gmshModelAddPhysicalGroup(const int dim,
+                                       const std::vector<int> &tags,
+                                       int tag = -1);
+
+// Sets the name of the physical group of dimension `dim' and tag `tag'.
+GMSH_API void gmshModelSetPhysicalName(const int dim, const int tag,
+                                       const std::string &name);
+
+// Gets the name of the physical group of dimension `dim' and tag `tag'.
+GMSH_API void gmshModelGetPhysicalName(const int dim, const int tag,
+                                       std::string &name);
+
+// Gets the boundary of the geometrical entities `dimTags'. Returns in
+// `outDimTags' the boundary of the individual entities (if `combined' is false)
+// or the boundary of the combined geometrical shape formed by all input
+// entities (if `combined' is true). Returns tags multiplied by the sign of the
+// boundary entity if `oriented' is true. Applies the boundary operator
+// recursively down to dimension 0 (i.e. to points) if `recursive' is true.
+GMSH_API void gmshModelGetBoundary(const vector_pair &dimTags,
+                                   vector_pair &outDimTags,
+                                   const bool combined = true,
+                                   const bool oriented = true,
+                                   const bool recursive = false);
+
+// Gets the (elementary) geometrical entities in the bounding box defined by two
+// points (xmin, ymin, zmin) and (xmax, ymax, zmax).
+GMSH_API void gmshModelGetEntitiesInBoundingBox(const double xmin,
+                                                const double ymin,
+                                                const double zmin,
+                                                const double xmax,
+                                                const double ymax,
+                                                const double zmax,
+                                                vector_pair &tags,
+                                                const int dim=-1);
+
+// Gets the bounding box (xmin, ymin, zmin), (xmax, ymax, zmax) of the
+// geometrical entity of dimension `dim' and tag `tag'.
+GMSH_API void gmshModelGetBoundingBox(const int dim, const int tag, double &xmin,
+                                      double &ymin, double &zmin, double &xmax,
+                                      double &ymax, double &zmax);
+
+// Adds a discrete geometrical entity (defined by a mesh) of dimension `dim' in
+// the current model. The function returns the tag of the new discrete entity,
+// equal to `tag' if `tag' > 0, or a new tag if not. `boundary' specifies the
+// tags of the entities on the boundary of the entity, if any. Specyfing
+// `bounday' allows Gmsh to maintain the topology of the overall model.
+GMSH_API int gmshModelAddDiscreteEntity(const int dim,
+                                        const int tag = -1,
+                                        const std::vector<int> &boundary =
                                         std::vector<int>());
-GMSH_API gmshModelSetTransfiniteVolume(const int tag,
-                                       const std::vector<int> &cornerTags =
-                                       std::vector<int>());
-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);
-
-// gmshModelGeo
-GMSH_API gmshModelGeoAddPoint(const int tag, const double x, const double y,
-                              const double z, const double meshSize = 0.);
-GMSH_API gmshModelGeoAddLine(const int tag, const int startTag, const int endTag);
-GMSH_API gmshModelGeoAddCircleArc(const int tag, const int startTag,
-                                  const int centerTag, const int endTag,
-                                  const double nx = 0., const double ny = 0.,
-                                  const double nz = 0.);
-GMSH_API gmshModelGeoAddEllipseArc(const int tag, const int startTag, const int centerTag,
-                                   const int majorTag, const int endTag,
-                                   const double nx = 0., const double ny = 0.,
-                                   const double nz = 0.);
-GMSH_API gmshModelGeoAddSpline(const int tag, const std::vector<int> &vertexTags);
-GMSH_API gmshModelGeoAddBSpline(const int tag, const std::vector<int> &vertexTags);
-GMSH_API gmshModelGeoAddBezier(const int tag, const std::vector<int> &vertexTags);
-GMSH_API gmshModelGeoAddLineLoop(const int tag, const std::vector<int> &edgeTags);
-GMSH_API gmshModelGeoAddPlaneSurface(const int tag, const std::vector<int> &wireTags);
-GMSH_API gmshModelGeoAddSurfaceFilling(const int tag, const std::vector<int> &wireTags,
-                                       const int sphereCenterTag = -1);
-GMSH_API gmshModelGeoAddSurfaceLoop(const int tag, const std::vector<int> &faceTags);
-GMSH_API gmshModelGeoAddVolume(const int tag, const std::vector<int> &shellTags);
-GMSH_API gmshModelGeoExtrude(const vector_pair &inDimTags,
-                             const double dx, const double dy, const double dz,
-                             vector_pair &outDimTags,
-                             const std::vector<int> &numElements = std::vector<int>(),
-                             const std::vector<double> &heights = std::vector<double>(),
-                             const bool recombine = false);
-GMSH_API gmshModelGeoRevolve(const vector_pair &inDimTags,
-                             const double x, const double y, const double z,
-                             const double ax, const double ay,
-                             const double az, const double angle,
-                             vector_pair &outDimTags,
-                             const std::vector<int> &numElements = std::vector<int>(),
-                             const std::vector<double> &heights = std::vector<double>(),
-                             const bool recombine = false);
-GMSH_API gmshModelGeoTwist(const vector_pair &inDimTags,
-                           const double x, const double y, const double z,
-                           const double dx, const double dy, const double dz,
-                           const double ax, const double ay, const double az,
-                           const double angle,
-                           vector_pair &outDimTags,
-                           const std::vector<int> &numElements = std::vector<int>(),
-                           const std::vector<double> &heights = std::vector<double>(),
-                           const bool recombine = false);
-GMSH_API gmshModelGeoTranslate(const vector_pair &dimTags,
-                               const double dx, const double dy, const double dz);
-GMSH_API gmshModelGeoRotate(const vector_pair &dimTags, const double x, const double y,
-                            const double z, const double ax, const double ay,
-                            const double az, const double angle);
-GMSH_API gmshModelGeoDilate(const vector_pair &dimTags, const double x, const double y,
-                            const double z, const double a, const double b,
-                            const double c);
-GMSH_API gmshModelGeoSymmetry(const vector_pair &dimTags, const double a, const double b,
-                              const double c, const double d);
-GMSH_API gmshModelGeoCopy(const vector_pair &inDimTags, vector_pair &outDimTags);
-GMSH_API gmshModelGeoRemove(const vector_pair &dimTags, const bool recursive = false);
-GMSH_API gmshModelGeoRemoveAllDuplicates();
-GMSH_API gmshModelGeoSetMeshSize(const vector_pair &dimTags, const double size);
-GMSH_API gmshModelGeoSetTransfiniteLine(const int tag, const int nPoints,
-                                        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 =
-                                          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
-GMSH_API gmshModelOccAddPoint(const int tag, const double x, const double y,
-                              const double z, const double meshSize = 0.);
-GMSH_API gmshModelOccAddLine(const int tag, const int startTag, const int endTag);
-GMSH_API gmshModelOccAddCircleArc(const int tag, const int startTag, const int centerTag,
-                                  const int endTag);
-GMSH_API gmshModelOccAddCircle(const int tag, const double x, const double y,
-                               const double z, const double r,
-                               const double angle1 = 0., const double angle2 = 2*M_PI);
-GMSH_API gmshModelOccAddEllipseArc(const int tag, const int startTag, const int centerTag,
-                                   const int endTag);
-GMSH_API gmshModelOccAddEllipse(const int tag, const double x, const double y,
-                                const double z, const double r1, const double r2,
-                                const double angle1 = 0.,
-                                const double angle2 = 2*M_PI);
-GMSH_API gmshModelOccAddSpline(const int tag, const std::vector<int> &vertexTags);
-GMSH_API gmshModelOccAddBezier(const int tag, const std::vector<int> &vertexTags);
-GMSH_API gmshModelOccAddBSpline(const int tag, const std::vector<int> &vertexTags);
-GMSH_API gmshModelOccAddWire(const int tag, const std::vector<int> &edgeTags,
-                             const bool checkClosed = false);
-GMSH_API gmshModelOccAddLineLoop(const int tag, const std::vector<int> &edgeTags);
-GMSH_API gmshModelOccAddRectangle(const int tag, const double x, const double y,
-                                  const double z, const double dx, const double dy,
-                                  const double roundedRadius = 0.);
-GMSH_API gmshModelOccAddDisk(const int tag, const double xc, const double yc,
-                             const double zc, const double rx, const double ry);
-GMSH_API gmshModelOccAddPlaneSurface(const int tag, const std::vector<int> &wireTags);
-GMSH_API gmshModelOccAddSurfaceFilling(const int tag, int wireTag);
-GMSH_API gmshModelOccAddSurfaceLoop(const int tag, const std::vector<int> &faceTags);
-GMSH_API gmshModelOccAddVolume(const int tag, const std::vector<int> &shellTags);
-GMSH_API gmshModelOccAddSphere(const int tag, const double xc, const double yc,
-                               const double zc, const double radius,
-                               const double angle1 = -M_PI/2,
-                               const double angle2 = M_PI/2,
-                               const double angle3 = 2*M_PI);
-GMSH_API gmshModelOccAddBox(const int tag, const double x, const double y,
-                            const double z, const double dx, const double dy,
-                            const double dz);
-GMSH_API gmshModelOccAddCylinder(const int tag, const double x, const double y,
-                                 const double z, const double dx, const double dy,
-                                 const double dz, const double r,
-                                 double angle = 2*M_PI);
-GMSH_API gmshModelOccAddCone(const int tag, const double x, const double y,
-                             const double z, const double dx, const double dy,
-                             const double dz, const double r1, const double r2,
-                             const double angle = 2*M_PI);
-GMSH_API gmshModelOccAddWedge(const int tag, const double x, const double y,
-                              const double z, const double dx, const double dy,
-                              const double dz, const double ltx = 0.);
-GMSH_API gmshModelOccAddTorus(const int tag, const double x, const double y,
-                              const double z, const double r1, const double r2,
-                              const double angle = 2*M_PI);
-GMSH_API gmshModelOccAddThruSections(const int tag, const std::vector<int> &wireTags,
-                                     vector_pair &outDimTags, const bool makeSolid = true,
-                                     const bool makeRuled = false);
-GMSH_API addThickSolid(const int tag, const int solidTag,
-                       const std::vector<int> &excludeFaceTags,
-                       const double offset, vector_pair &outDimTags);
-GMSH_API gmshModelOccExtrude(const vector_pair &inDimTags, const double dx, const double dy,
-                             const double dz, vector_pair &outDimTags,
-                             const std::vector<int> &numElements = std::vector<int>(),
-                             const std::vector<double> &heights = std::vector<double>(),
-                             const bool recombine = false);
-GMSH_API gmshModelOccRevolve(const vector_pair &inDimTags,
-                             const double x, const double y, const double z,
-                             const double ax, const double ay, const double az,
-                             const double angle, vector_pair &outDimTags,
-                             const std::vector<int> &numElements = std::vector<int>(),
-                             const std::vector<double> &heights = std::vector<double>(),
-                             const bool recombine = false);
-GMSH_API gmshModelOccAddPipe(const vector_pair &inDimTags, int wireTag,
-                             vector_pair &outDimTags);
-GMSH_API gmshModelOccFillet(const std::vector<int> &regionTags,
-                            const std::vector<int> &edgeTags,
-                            const double radius, vector_pair &outDimTags,
-                            const bool removeRegion = true);
-GMSH_API gmshModelOccBooleanUnion(const int tag, const vector_pair &objectDimTags,
-                                  const vector_pair &toolDimTags,
+
+// Removes the entities `dimTags' of the current model. If `recursive' is true,
+// remove all the entities on their bundaries, down to dimension 0.
+GMSH_API void gmshModelRemove(const vector_pair &dimTags,
+                              const bool recursive = false);
+
+// Generates a mesh of the current model, up to dimension `dim' (0, 1, 2 or 3).
+GMSH_API void gmshModelMesh(const int dim);
+
+// Gets the mesh vertices of the entity of dimension `dim' and `tag'
+// tag. `vertextags' contains the vertex tags (unique identification
+// numbers). `coord` is a vector of length `3 * vertexTags.size()' that contains
+// the (x, y, z) coordinates of the vertices. `parametricCoord` contains the
+// parametric coordinates of the vertices, if available. The length of
+// `parametricCoord` can be 0, `vertexTags.size()' or `2 * vertexTags.size()'.
+GMSH_API void gmshModelGetMeshVertices(const int dim, const int tag,
+                                       std::vector<int> &vertexTags,
+                                       std::vector<double> &coord,
+                                       std::vector<double> &parametricCoord);
+
+// Gets the mesh elements of the entity of dimension `dim' and `tag'
+// tag. `types' contains the MSH types (e.g. 2 for 3-node triangles -- see the
+// Gmsh reference manual). `elementTags' is a vector of length `types.size()';
+// each entry is a vector containing the tags (unique identifiers) of the
+// elements of the corresponding type. `vertexTags' is a vector of length
+// `types.size()'; each entry is a vector of length equal to the number of
+// elements of the give type, times the number of vertices per element, that
+// contains the vertex tags of all the elements of the given type.
+GMSH_API void gmshModelGetMeshElements(const int dim, const int tag,
+                                       std::vector<int> &types,
+                                       std::vector<std::vector<int> > &elementTags,
+                                       std::vector<std::vector<int> > &vertexTags);
+
+// Sets the mesh vertices in the geometrical entity of dimension `dim' and tag
+// `tag'. `vertextags' contains the vertex tags (unique identification
+// numbers). `coord` is a vector of length `3 * vertexTags.size()' that contains
+// the (x, y, z) coordinates of the vertices. The optional `parametricCoord`
+// vector contains the parametric coordinates of the vertices, if any. The
+// length of `parametricCoord` can be 0 or `dim * vertexTags.size()'.
+GMSH_API void gmshModelSetMeshVertices(const int dim, const int tag,
+                                       const std::vector<int> &vertexTags,
+                                       const std::vector<double> &coord,
+                                       const std::vector<double> &parametricCoord =
+                                       std::vector<double>());
+
+// Sets the mesh elements of the entity of dimension `dim' and `tag'
+// tag. `types' contains the MSH types (e.g. 2 for 3-node triangles -- see the
+// Gmsh reference manual). `elementTags' is a vector of length `types.size()';
+// each entry is a vector containing the tags (unique identifiers) of the
+// elements of the corresponding type. `vertexTags' is a vector of length
+// `types.size()'; each entry is a vector of length equal to the number of
+// elements of the give type, times the number of vertices per element, that
+// contains the vertex tags of all the elements of the given type.
+GMSH_API void gmshModelSetMeshElements(const int dim, const int tag,
+                                       const std::vector<int> &types,
+                                       const std::vector<std::vector<int> > &elementTags,
+                                       const std::vector<std::vector<int> > &vertexTags);
+
+// Gets the coordinates and the parametric coordinates (if any) of the mesh
+// vertex with tag `tag'. This is an inefficient way of accessing mesh vertex
+// data, as it relies on a dynamic cache stored in the model. For large meshes
+// all the vertices in the model should be numbered in a continuous sequence of
+// tags from 1 to N to maintain reasonnable performance (in this case the
+// internal cache is based on a vector; otherwise it uses a map).
+GMSH_API void gmshModelGetMeshVertex(const int vertexTag,
+                                     std::vector<double> &coord,
+                                     std::vector<double> &parametricCoord);
+
+// Gets the type and vertex tags of the mesh element with tag `tag'. This is an
+// inefficient way of accessing mesh element data, as it relies on a dynamic
+// cache stored in the model. For large meshes all the elements in the model
+// should be numbered in a continuous sequence of tags from 1 to N to maintain
+// reasonnable performance (in this case the internal cache is based on a
+// vector; otherwise it uses a map).
+GMSH_API void gmshModelGetMeshElement(const int elementTag, int &type,
+                                      std::vector<int> &vertexTags);
+
+// Sets a mesh size constraint on the geometrical entities `dimTags'. Currently
+// only entities of dimension 0 (points) are handled.
+GMSH_API void gmshModelSetMeshSize(const vector_pair &dimTags, const double size);
+
+// Sets a transfinite meshing constraint on the line `tag', with `numVertices'
+// mesh vertices distributed according to `type' and `coef'. Currently supported
+// types are "Progression" (geometrical progression with power `coef') and
+// "Bump" (refinement toward both extreminties of the line0.
+GMSH_API void gmshModelSetTransfiniteLine(const int tag, const int numVertices,
+                                          const std::string &type = "Progression",
+                                          const double coef = 1.);
+
+// Sets a transfinite meshing constraint on the surface `tag'. `arrangement'
+// describes the arrangement of the triangles when the surface is not flagged as
+// recombined: currently supported values are "Left", "Right", "AlternateLeft"
+// and "AlternateRight". `cornerTags' can be used to specify the (3 or 4)
+// corners of the transfinite interpolation explicitly; specifying the corners
+// explicitly is mandatory if the surface has more that 3 or 4 points on its
+// boundary.
+GMSH_API void gmshModelSetTransfiniteSurface(const int tag,
+                                             const std::string &arrangement = "Left",
+                                             const std::vector<int> &cornerTags =
+                                             std::vector<int>());
+
+// Sets a transfinite meshing constraint on the surface `tag'. `cornerTags' can
+// be used to specify the (6 or 8) corners of the transfinite interpolation
+// explicitly.
+GMSH_API void gmshModelSetTransfiniteVolume(const int tag,
+                                            const std::vector<int> &cornerTags =
+                                            std::vector<int>());
+
+// Sets a recombination meshing constraint on the geometrical entity of
+// dimension `dim' and tag `tag'. Currently only entities of dimension 2 (to
+// recombine triangles into quadrangles) are supported.
+GMSH_API void gmshModelSetRecombine(const int dim, const int tag);
+
+// Sets a smoothing meshing constraint on the geometrical entity of dimension
+// `dim' and tag `tag'. `val' iterations of a Laplace smoother will be applied.
+GMSH_API void gmshModelSetSmoothing(const int dim, const int tag, const int val);
+
+// Sets a reverse meshing constraint on the geometrical entity of dimension
+// `dim' and tag `tag'. If `val' is true, the mesh orientation will be reverse
+// with respect to the natural mesh orientation (i.e. the orientation consistent
+// with the orientation of the geometrical entity). If `val' is false, the mesh
+// is left as-is.
+GMSH_API void gmshModelSetReverseMesh(const int dim, const int tag,
+                                      const bool val = true);
+
+// Emebds the geometrical entities of dimension `dim' and tags `tags' in the
+// (inDim, inTag) geometrical entity. `inDim' must be strictly greater than
+// `dim'.
+GMSH_API void gmshModelEmbed(const int dim, const std::vector<int> &tags,
+                             const int inDim, const int inTag);
+
+// -----------------------------------------------------------------------------
+// Section "gmshModelGeo": built-in CAD kernel functions for current model
+// -----------------------------------------------------------------------------
+
+GMSH_API int gmshModelGeoAddPoint(const double x, const double y, const double z,
+                                  const double meshSize = 0., const int tag = -1);
+GMSH_API int gmshModelGeoAddLine(const int startTag, const int endTag,
+                                 const int tag = -1);
+GMSH_API int gmshModelGeoAddCircleArc(const int startTag, const int centerTag,
+                                      const int endTag, const int tag = -1,
+                                      const double nx = 0., const double ny = 0.,
+                                      const double nz = 0.);
+GMSH_API int gmshModelGeoAddEllipseArc(const int startTag, const int centerTag,
+                                       const int majorTag, const int endTag,
+                                       const int tag = -1, const double nx = 0.,
+                                       const double ny = 0., const double nz = 0.);
+GMSH_API int gmshModelGeoAddSpline(const std::vector<int> &vertexTags,
+                                   const int tag = -1);
+GMSH_API int gmshModelGeoAddBSpline(const std::vector<int> &vertexTags,
+                                    const int tag = -1);
+GMSH_API int gmshModelGeoAddBezier(const std::vector<int> &vertexTags,
+                                   const int tag = -1);
+GMSH_API int gmshModelGeoAddLineLoop(const std::vector<int> &edgeTags,
+                                     const int tag = -1);
+GMSH_API int gmshModelGeoAddPlaneSurface(const std::vector<int> &wireTags,
+                                         const int tag = -1);
+GMSH_API int gmshModelGeoAddSurfaceFilling(const std::vector<int> &wireTags,
+                                           const int tag = -1,
+                                           const int sphereCenterTag = -1);
+GMSH_API int gmshModelGeoAddSurfaceLoop(const std::vector<int> &faceTags,
+                                        const int tag = -1);
+GMSH_API int gmshModelGeoAddVolume(const std::vector<int> &shellTags,
+                                   const int tag = -1);
+GMSH_API void gmshModelGeoExtrude(const vector_pair &dimTags,
+                                  const double dx, const double dy, const double dz,
+                                  vector_pair &outDimTags,
+                                  const std::vector<int> &numElements =
+                                  std::vector<int>(),
+                                  const std::vector<double> &heights =
+                                  std::vector<double>(),
+                                  const bool recombine = false);
+GMSH_API void gmshModelGeoRevolve(const vector_pair &dimTags,
+                                  const double x, const double y, const double z,
+                                  const double ax, const double ay,
+                                  const double az, const double angle,
                                   vector_pair &outDimTags,
-                                  std::vector<vector_pair> &outDimTagsMap,
-                                  const bool removeObject = true,
-                                  const bool removeTool = true);
-GMSH_API gmshModelOccBooleanIntersection(const int tag, const vector_pair &objectDimTags,
-                                         const vector_pair &toolDimTags,
+                                  const std::vector<int> &numElements =
+                                  std::vector<int>(),
+                                  const std::vector<double> &heights =
+                                  std::vector<double>(),
+                                  const bool recombine = false);
+GMSH_API void gmshModelGeoTwist(const vector_pair &dimTags,
+                                const double x, const double y, const double z,
+                                const double dx, const double dy, const double dz,
+                                const double ax, const double ay, const double az,
+                                const double angle,
+                                vector_pair &outDimTags,
+                                const std::vector<int> &numElements =
+                                std::vector<int>(),
+                                const std::vector<double> &heights =
+                                std::vector<double>(),
+                                const bool recombine = false);
+GMSH_API void gmshModelGeoTranslate(const vector_pair &dimTags, const double dx,
+                                    const double dy, const double dz);
+GMSH_API void gmshModelGeoRotate(const vector_pair &dimTags, const double x,
+                                 const double y, const double z, const double ax,
+                                 const double ay, const double az,
+                                 const double angle);
+GMSH_API void gmshModelGeoDilate(const vector_pair &dimTags, const double x,
+                                 const double y, const double z, const double a,
+                                 const double b, const double c);
+GMSH_API void gmshModelGeoSymmetry(const vector_pair &dimTags, const double a,
+                                   const double b, const double c, const double d);
+GMSH_API void gmshModelGeoCopy(const vector_pair &dimTags, vector_pair &outDimTags);
+GMSH_API void gmshModelGeoRemove(const vector_pair &dimTags,
+                                 const bool recursive = false);
+GMSH_API void gmshModelGeoRemoveAllDuplicates();
+GMSH_API void gmshModelGeoSetMeshSize(const vector_pair &dimTags, const double size);
+GMSH_API void gmshModelGeoSetTransfiniteLine(const int tag, const int nPoints,
+                                             const std::string &type = "Progression",
+                                             const double coef = 1.);
+GMSH_API void gmshModelGeoSetTransfiniteSurface(const int tag,
+                                                const std::string &arrangement = "Left",
+                                                const std::vector<int> &cornerTags =
+                                                std::vector<int>());
+GMSH_API void gmshModelGeoSetTransfiniteVolume(const int tag,
+                                               const std::vector<int> &cornerTags =
+                                               std::vector<int>());
+GMSH_API void gmshModelGeoSetRecombine(const int dim, const int tag,
+                                       const double angle = 45.);
+GMSH_API void gmshModelGeoSetSmoothing(const int dim, const int tag,
+                                       const int val);
+GMSH_API void gmshModelGeoSetReverseMesh(const int dim, const int tag,
+                                         const bool val = true);
+GMSH_API void gmshModelGeoSynchronize();
+
+// -----------------------------------------------------------------------------
+// Section "gmshModelOcc": OpenCASCADE CAD kernel functions for current model
+// -----------------------------------------------------------------------------
+
+GMSH_API int gmshModelOccAddPoint(const double x, const double y, const double z,
+                                  const double meshSize = 0., const int tag = -1);
+GMSH_API int gmshModelOccAddLine(const int startTag, const int endTag,
+                                 const int tag = -1);
+GMSH_API int gmshModelOccAddCircleArc(const int startTag, const int centerTag,
+                                      const int endTag, const int tag = -1);
+GMSH_API int gmshModelOccAddCircle(const double x, const double y, const double z,
+                                   const double r, const int tag = -1,
+                                   const double angle1 = 0.,
+                                   const double angle2 = 2*M_PI);
+GMSH_API int gmshModelOccAddEllipseArc(const int startTag, const int centerTag,
+                                       const int endTag, const int tag = -1);
+GMSH_API int gmshModelOccAddEllipse(const double x, const double y, const double z,
+                                    const double r1, const double r2,
+                                    const int tag = -1,
+                                    const double angle1 = 0.,
+                                    const double angle2 = 2*M_PI);
+GMSH_API int gmshModelOccAddSpline(const std::vector<int> &vertexTags,
+                                   const int tag = -1);
+GMSH_API int gmshModelOccAddBezier(const std::vector<int> &vertexTags,
+                                   const int tag = -1);
+GMSH_API int gmshModelOccAddBSpline(const std::vector<int> &vertexTags,
+                                    const int tag = -1);
+GMSH_API int gmshModelOccAddWire(const std::vector<int> &edgeTags,
+                                 const int tag = -1,
+                                 const bool checkClosed = false);
+GMSH_API int gmshModelOccAddLineLoop(const std::vector<int> &edgeTags,
+                                     const int tag = -1);
+GMSH_API int gmshModelOccAddRectangle(const double x, const double y,
+                                      const double z, const double dx,
+                                      const double dy,
+                                      const int tag = -1,
+                                      const double roundedRadius = 0.);
+GMSH_API int gmshModelOccAddDisk(const double xc, const double yc,
+                                 const double zc, const double rx,
+                                 const double ry, const int tag = -1);
+GMSH_API int gmshModelOccAddPlaneSurface(const std::vector<int> &wireTags,
+                                         const int tag = -1);
+GMSH_API int gmshModelOccAddSurfaceFilling(int wireTag, const int tag = -1);
+GMSH_API int gmshModelOccAddSurfaceLoop(const std::vector<int> &faceTags,
+                                        const int tag = -1);
+GMSH_API int gmshModelOccAddVolume(const std::vector<int> &shellTags,
+                                   const int tag = -1);
+GMSH_API int gmshModelOccAddSphere(const double xc, const double yc,
+                                   const double zc, const double radius,
+                                   const int tag = -1,
+                                   const double angle1 = -M_PI/2,
+                                   const double angle2 = M_PI/2,
+                                   const double angle3 = 2*M_PI);
+GMSH_API int gmshModelOccAddBox(const double x, const double y, const double z,
+                                const double dx, const double dy, const double dz,
+                                const int tag = -1);
+GMSH_API int gmshModelOccAddCylinder(const double x, const double y,
+                                     const double z, const double dx,
+                                     const double dy, const double dz,
+                                     const double r, const int tag = -1,
+                                     double angle = 2*M_PI);
+GMSH_API int gmshModelOccAddCone(const double x, const double y, const double z,
+                                 const double dx, const double dy, const double dz,
+                                 const double r1, const double r2,
+                                 const int tag = -1,
+                                 const double angle = 2*M_PI);
+GMSH_API int gmshModelOccAddWedge(const double x, const double y, const double z,
+                                  const double dx, const double dy, const double dz,
+                                  const int tag = -1, const double ltx = 0.);
+GMSH_API int gmshModelOccAddTorus(const double x, const double y, const double z,
+                                  const double r1, const double r2,
+                                  const int tag = -1,
+                                  const double angle = 2*M_PI);
+GMSH_API int gmshModelOccAddThruSections(const std::vector<int> &wireTags,
                                          vector_pair &outDimTags,
-                                         std::vector<vector_pair > &outDimTagsMap,
-                                         const bool removeObject = true,
-                                         const bool removeTool = true);
-GMSH_API gmshModelOccBooleanDifference(const int tag, const vector_pair &objectDimTags,
-                                       const vector_pair &toolDimTags,
-                                       vector_pair &outDimTags,
-                                       std::vector<vector_pair > &outDimTagsMap,
-                                       const bool removeObject = true,
-                                       const bool removeTool = true);
-GMSH_API gmshModelOccBooleanFragments(const int tag, const vector_pair &objectDimTags,
+                                         const int tag = -1,
+                                         const bool makeSolid = true,
+                                         const bool makeRuled = false);
+GMSH_API int addThickSolid(const int solidTag,
+                           const std::vector<int> &excludeFaceTags,
+                           const double offset, vector_pair &outDimTags,
+                           const int tag = -1);
+GMSH_API void gmshModelOccExtrude(const vector_pair &dimTags, const double dx,
+                                  const double dy, const double dz,
+                                  vector_pair &outDimTags,
+                                  const std::vector<int> &numElements =
+                                  std::vector<int>(),
+                                  const std::vector<double> &heights =
+                                  std::vector<double>(),
+                                  const bool recombine = false);
+GMSH_API void gmshModelOccRevolve(const vector_pair &dimTags,
+                                  const double x, const double y, const double z,
+                                  const double ax, const double ay, const double az,
+                                  const double angle, vector_pair &outDimTags,
+                                  const std::vector<int> &numElements =
+                                  std::vector<int>(),
+                                  const std::vector<double> &heights =
+                                  std::vector<double>(),
+                                  const bool recombine = false);
+GMSH_API void gmshModelOccAddPipe(const vector_pair &dimTags, int wireTag,
+                                  vector_pair &outDimTags);
+GMSH_API void gmshModelOccFillet(const std::vector<int> &regionTags,
+                                 const std::vector<int> &edgeTags,
+                                 const double radius, vector_pair &outDimTags,
+                                 const bool removeRegion = true);
+GMSH_API int gmshModelOccBooleanUnion(const vector_pair &objectDimTags,
                                       const vector_pair &toolDimTags,
                                       vector_pair &outDimTags,
                                       std::vector<vector_pair> &outDimTagsMap,
+                                      const int tag = -1,
                                       const bool removeObject = true,
                                       const bool removeTool = true);
-GMSH_API gmshModelOccTranslate(const vector_pair &dimTags, const double dx,
-                               const double dy, const double dz);
-GMSH_API gmshModelOccRotate(const vector_pair &dimTags, const double x,
-                            const double y, const double z, const double ax,
-                            const double ay, const double az, const double angle);
-GMSH_API gmshModelOccDilate(const vector_pair &dimTags, const double x,
-                            const double y, const double z, const double a,
-                            const double b, const double c);
-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 = false);
-GMSH_API gmshModelOccRemoveAllDuplicates();
-GMSH_API gmshModelOccImportShapes(const std::string &fileName, vector_pair &outDimTags,
-                                  const bool highestDimOnly = true,
-                                  const std::string &format = "");
-GMSH_API gmshModelOccSetMeshSize(const vector_pair &dimTags, const double size);
-GMSH_API gmshModelOccSynchronize();
-
-// gmshModelField
-
-GMSH_API gmshModelFieldCreate(const int tag, const std::string &type);
-GMSH_API gmshModelFieldSetNumber(const int tag, const std::string &option,
-                                 const double value);
-GMSH_API gmshModelFieldSetString(const int tag, const std::string &option,
-                                 const std::string &value);
-GMSH_API gmshModelFieldSetNumbers(const int tag, const std::string &option,
-                                  const std::vector<double> &value);
-GMSH_API gmshModelFieldSetAsBackground(const int tag);
-GMSH_API gmshModelFieldDelete(const int tag);
-
-// gmshView
-
-// gmshPlugin
-
-// gmshGraphics
+GMSH_API int gmshModelOccBooleanIntersection(const vector_pair &objectDimTags,
+                                             const vector_pair &toolDimTags,
+                                             vector_pair &outDimTags,
+                                             std::vector<vector_pair > &outDimTagsMap,
+                                             const int tag = -1,
+                                             const bool removeObject = true,
+                                             const bool removeTool = true);
+GMSH_API int gmshModelOccBooleanDifference(const vector_pair &objectDimTags,
+                                           const vector_pair &toolDimTags,
+                                           vector_pair &outDimTags,
+                                           std::vector<vector_pair > &outDimTagsMap,
+                                           const int tag = -1,
+                                           const bool removeObject = true,
+                                           const bool removeTool = true);
+GMSH_API int gmshModelOccBooleanFragments(const vector_pair &objectDimTags,
+                                          const vector_pair &toolDimTags,
+                                          vector_pair &outDimTags,
+                                          std::vector<vector_pair> &outDimTagsMap,
+                                          const int tag = -1,
+                                          const bool removeObject = true,
+                                          const bool removeTool = true);
+GMSH_API void gmshModelOccTranslate(const vector_pair &dimTags, const double dx,
+                                    const double dy, const double dz);
+GMSH_API void gmshModelOccRotate(const vector_pair &dimTags, const double x,
+                                 const double y, const double z, const double ax,
+                                 const double ay, const double az, const double angle);
+GMSH_API void gmshModelOccDilate(const vector_pair &dimTags, const double x,
+                                 const double y, const double z, const double a,
+                                 const double b, const double c);
+GMSH_API void gmshModelOccSymmetry(const vector_pair &dimTags, const double a,
+                                   const double b, const double c, const double d);
+GMSH_API void gmshModelOccCopy(const vector_pair &dimTags, vector_pair &outDimTags);
+GMSH_API void gmshModelOccRemove(const vector_pair &dimTags,
+                                 const bool recursive = false);
+GMSH_API void gmshModelOccRemoveAllDuplicates();
+GMSH_API void gmshModelOccImportShapes(const std::string &fileName,
+                                       vector_pair &outDimTags,
+                                       const bool highestDimOnly = true,
+                                       const std::string &format = "");
+GMSH_API void gmshModelOccSetMeshSize(const vector_pair &dimTags, const double size);
+GMSH_API void gmshModelOccSynchronize();
+
+// -----------------------------------------------------------------------------
+// Section "gmshModelField": mesh size field functions for current model
+// -----------------------------------------------------------------------------
+
+GMSH_API int gmshModelFieldCreate(const std::string &type, const int tag = -1);
+GMSH_API void gmshModelFieldDelete(const int tag);
+GMSH_API void gmshModelFieldSetNumber(const int tag, const std::string &option,
+                                      const double value);
+GMSH_API void gmshModelFieldSetString(const int tag, const std::string &option,
+                                      const std::string &value);
+GMSH_API void gmshModelFieldSetNumbers(const int tag, const std::string &option,
+                                       const std::vector<double> &value);
+GMSH_API void gmshModelFieldSetAsBackground(const int tag);
 
 #undef GMSH_API
 
diff --git a/Geo/GModel.h b/Geo/GModel.h
index 45a7b0077986d3cd3c0a6735bdeb7db2f7784821..7f8d8d743ec21a7a1a184401ff600de91f15eb7a 100644
--- a/Geo/GModel.h
+++ b/Geo/GModel.h
@@ -66,7 +66,7 @@ class GModel {
   // the visibility flag
   char _visible;
 
-  // vertex and element caches to speed-up direct access by tag (only
+  // vertex and element caches to speed-up direct access by tag (mostly
   // used for post-processing I/O)
   std::vector<MVertex*> _vertexVectorCache;
   std::map<int, MVertex*> _vertexMapCache;
diff --git a/Geo/GModelIO_MSH.cpp b/Geo/GModelIO_MSH.cpp
index 78a2e1c8bcb3f1a4a29fe18129cfc94ac9faf9fc..a5ba6b614204823e37ec197b4a7638187f61bfe4 100644
--- a/Geo/GModelIO_MSH.cpp
+++ b/Geo/GModelIO_MSH.cpp
@@ -305,7 +305,7 @@ int GModel::readMSH(const std::string &name)
                 if(fread(&u, sizeof(double), 1, fp) != 1){ fclose(fp); return 0; }
                 if(swap) SwapBytes((char*)&u, sizeof(double), 1);
               }
-              vertex = new MEdgeVertex(xyz[0], xyz[1], xyz[2], ge, u, -1.0, num);
+              vertex = new MEdgeVertex(xyz[0], xyz[1], xyz[2], ge, u, num);
             }
             break;
           case 2:
diff --git a/Geo/GModelIO_MSH2.cpp b/Geo/GModelIO_MSH2.cpp
index 8b51e51e68e20d0bc1057537888dced4d0be9307..0801379e902871730b98332d87e89ba4d03996b8 100644
--- a/Geo/GModelIO_MSH2.cpp
+++ b/Geo/GModelIO_MSH2.cpp
@@ -310,7 +310,7 @@ int GModel::_readMSH2(const std::string &name)
               if(fread(uv, sizeof(double), 1, fp) != 1){ fclose(fp); return 0; }
               if(swap) SwapBytes((char*)uv, sizeof(double), 1);
             }
-            newVertex = new MEdgeVertex(xyz[0], xyz[1], xyz[2], ge, uv[0], -1.0, num);
+            newVertex = new MEdgeVertex(xyz[0], xyz[1], xyz[2], ge, uv[0], num);
           }
           else if (iClasDim == 2){
             GFace *gf = getFaceByTag(iClasTag);
diff --git a/Geo/GeomMeshMatcher.cpp b/Geo/GeomMeshMatcher.cpp
index ba4d6d5ef0dec4678f7f6223977f7e123ef666c2..51cf479a3dad4f3ae9a994fdcb037340f10b759e 100644
--- a/Geo/GeomMeshMatcher.cpp
+++ b/Geo/GeomMeshMatcher.cpp
@@ -513,8 +513,8 @@ int GeomMeshMatcher::forceTomatch(GModel *geom, GModel *mesh, const double TOL)
 	  GEntity *gg = (GEntity*)gp.g();
 	  found=1;
 	  //	  printf("vertex %d matches GEdge %d on position %g\n",v->getNum(),gg->tag(),gp.u());
-	  gg->mesh_vertices.push_back(new MEdgeVertex (gp.x(),gp.y(),gp.z(),
-						       gg,gp.u(),-1.,v->getNum()));
+	  gg->mesh_vertices.push_back(new MEdgeVertex (gp.x(), gp.y(), gp.z(),
+						       gg, gp.u(), v->getNum()));
 	}
       }
       if (!found && v->onWhat()->dim() <= 2){
@@ -586,13 +586,13 @@ template <class GEType>
 static void copy_periodicity (std::vector<Pair<GEType*, GEType*> >& eCor,
                               std::map<MVertex*,MVertex*>& mesh_to_geom)
 {
-    
+
   typename std::multimap<GEType*,GEType*> eMap; // (eCor.begin(),eCor.end());
   typename std::vector<Pair<GEType*,GEType*> >::iterator eIter = eCor.begin();
   for (;eIter!=eCor.end();++eIter) {
     eMap.insert(std::make_pair(eIter->second(),eIter->first()));
   }
-  
+
   typename std::multimap<GEType*,GEType*>::iterator srcIter = eMap.begin();
 
   for (;srcIter!=eMap.end();++srcIter) {
@@ -600,17 +600,17 @@ static void copy_periodicity (std::vector<Pair<GEType*, GEType*> >& eCor,
     GEType* oldSrc = dynamic_cast<GEType*> (oldTgt->meshMaster());
 
     if (oldSrc != NULL && oldSrc != oldTgt) {
-      
+
       GEType* newTgt = srcIter->second;
       typename std::map<GEType*,GEType*>::iterator tgtIter = eMap.find(oldSrc);
       if (tgtIter == eMap.end()) {
-        Msg::Error("Could not find matched entity for %d", 
+        Msg::Error("Could not find matched entity for %d",
                    "which has a matched periodic counterpart %d",
                    oldSrc->tag(),oldTgt->tag());
       }
       GEType* newSrc = tgtIter->second;
       newTgt->setMeshMaster(newSrc,oldTgt->affineTransform);
-      
+
       std::map<MVertex*,MVertex*>& oldV2v = oldTgt->correspondingVertices;
       std::map<MVertex*,MVertex*>& newV2v = newTgt->correspondingVertices;
 
@@ -619,15 +619,15 @@ static void copy_periodicity (std::vector<Pair<GEType*, GEType*> >& eCor,
 
         MVertex* oldTgtV = vIter->first;
         MVertex* oldSrcV = vIter->second;
-        
+
         std::map<MVertex*,MVertex*>::iterator newTvIter = mesh_to_geom.find(oldTgtV);
         std::map<MVertex*,MVertex*>::iterator newSvIter = mesh_to_geom.find(oldSrcV);
-        
+
         if (newTvIter == mesh_to_geom.end()) {
           Msg::Error("Could not find copy of target vertex %d in entity %d of dim",
                      oldTgtV->getIndex(),oldTgt->tag(),oldTgt->dim());
         }
-        
+
         if (newSvIter == mesh_to_geom.end()) {
           Msg::Error("Could not find copy of source vertex %d in entity %d of dim",
                      oldSrcV->getIndex(),oldSrc->tag(),oldSrc->dim());
@@ -677,9 +677,8 @@ static void copy_vertices (GEdge* to, GEdge* from, std::map<MVertex*,MVertex*> &
   for (unsigned int i=0;i<from->mesh_vertices.size();i++){
     MVertex *v_from = from->mesh_vertices[i];
     double t;
-    GPoint gp = to->closestPoint(SPoint3(v_from->x(),v_from->y(),v_from->z()), t );
-    MEdgeVertex *v_to = new MEdgeVertex (gp.x(),gp.y(),gp.z(), to, gp.u() );
-    
+    GPoint gp = to->closestPoint(SPoint3(v_from->x(),v_from->y(),v_from->z()), t);
+    MEdgeVertex *v_to = new MEdgeVertex(gp.x(),gp.y(),gp.z(), to, gp.u());
     to->mesh_vertices.push_back(v_to);
     _mesh_to_geom[v_from] = v_to;
   }
@@ -789,8 +788,8 @@ void copy_elements (GModel *geom, GModel *mesh, std::map<MVertex*,MVertex*> &_me
 
 int GeomMeshMatcher::match(GModel *geom, GModel *mesh)
 {
-  
-  Msg::StatusBar(true,"Matching discrete mesh to actual CAD ...");  
+
+  Msg::StatusBar(true,"Matching discrete mesh to actual CAD ...");
   double t1 = Cpu();
 
   mesh->createTopologyFromMesh();
@@ -804,14 +803,14 @@ int GeomMeshMatcher::match(GModel *geom, GModel *mesh)
   std::vector<Pair<GRegion*, GRegion*> > *coresp_r = matchRegions (geom, mesh, coresp_f, ok);
 
   std::map<MVertex*,MVertex*> _mesh_to_geom;
-  
+
   copy_vertices(geom,mesh,_mesh_to_geom,coresp_v,coresp_e,coresp_f,coresp_r);
   copy_elements(geom,mesh,_mesh_to_geom,coresp_v,coresp_e,coresp_f,coresp_r);
-  
+
   copy_periodicity(*coresp_v,_mesh_to_geom);
   copy_periodicity(*coresp_e,_mesh_to_geom);
   copy_periodicity(*coresp_f,_mesh_to_geom);
-  
+
   delete coresp_v;
   delete coresp_e;
   delete coresp_f;
diff --git a/Geo/MElement.h b/Geo/MElement.h
index 2d39d73929e3f26d6b2c6bc87c2c898382005bf4..941459bab475e15f3bd64cebd4b4b8b745992feb 100644
--- a/Geo/MElement.h
+++ b/Geo/MElement.h
@@ -65,11 +65,13 @@ class MElement
   virtual int getPolynomialOrder() const { return 1; }
 
   // return true if the element can be considered as a serendipity element
-  virtual bool getIsAssimilatedSerendipity() const {
+  virtual bool getIsAssimilatedSerendipity() const
+  {
     return ElementType::SerendipityFromTag(getTypeForMSH()) > 0;
   }
   // return true if the element has to be considered as a serendipity element
-  virtual bool getIsOnlySerendipity() const {
+  virtual bool getIsOnlySerendipity() const
+  {
     return ElementType::SerendipityFromTag(getTypeForMSH()) > 1;
   }
 
diff --git a/Geo/MHexahedron.cpp b/Geo/MHexahedron.cpp
index 3f73d503eef00f37e87341480415f9dadd791984..ce6d4f139b05c3b9ab8cc042bcc438fe073c9b9d 100644
--- a/Geo/MHexahedron.cpp
+++ b/Geo/MHexahedron.cpp
@@ -438,20 +438,20 @@ int MHexahedron::getNumFacesRep(bool curved)
 
 int MHexahedron20::getNumFacesRep(bool curved)
 {
-  return curved ? 6 * (CTX::instance()->mesh.numSubEdges *
-                       CTX::instance()->mesh.numSubEdges * 2) : 12;
+  return curved ? 12 * gmsh_SQU(CTX::instance()->mesh.numSubEdges) :
+         MHexahedron::getNumFacesRep(curved);
 }
 
 int MHexahedron27::getNumFacesRep(bool curved)
 {
-  return curved ? 6 * (CTX::instance()->mesh.numSubEdges *
-                       CTX::instance()->mesh.numSubEdges * 2) : 12;
+  return curved ? 12 * gmsh_SQU(CTX::instance()->mesh.numSubEdges) :
+         MHexahedron::getNumFacesRep(curved);
 }
 
 int MHexahedronN::getNumFacesRep(bool curved)
 {
-  return curved ? 6 * (CTX::instance()->mesh.numSubEdges *
-                       CTX::instance()->mesh.numSubEdges * 2) : 12;
+  return curved ? 12 * gmsh_SQU(CTX::instance()->mesh.numSubEdges) :
+         MHexahedron::getNumFacesRep(curved);
 }
 
 void _getIndicesReversedHex(int order, indicesReversed &indices)
diff --git a/Geo/MPrism.cpp b/Geo/MPrism.cpp
index caa99c36c6889dfa1d7463fa7605052a222a686e..38306fe013514ce6801f96b681da6343bb3757f8 100644
--- a/Geo/MPrism.cpp
+++ b/Geo/MPrism.cpp
@@ -496,20 +496,20 @@ int MPrism::getNumFacesRep(bool curved)
 
 int MPrism15::getNumFacesRep(bool curved)
 {
-  return curved ? 4 * (CTX::instance()->mesh.numSubEdges *
-                       CTX::instance()->mesh.numSubEdges * 2) : 8;
+  return curved ? 8 * gmsh_SQU(CTX::instance()->mesh.numSubEdges) :
+         MPrism::getNumFacesRep(curved);
 }
 
 int MPrism18::getNumFacesRep(bool curved)
 {
-  return curved ? 4 * (CTX::instance()->mesh.numSubEdges *
-                       CTX::instance()->mesh.numSubEdges * 2) : 8;
+  return curved ? 8 * gmsh_SQU(CTX::instance()->mesh.numSubEdges) :
+         MPrism::getNumFacesRep(curved);
 }
 
 int MPrismN::getNumFacesRep(bool curved)
 {
-  return curved ? 4 * (CTX::instance()->mesh.numSubEdges *
-                       CTX::instance()->mesh.numSubEdges * 2) : 8;
+  return curved ? 8 * gmsh_SQU(CTX::instance()->mesh.numSubEdges) :
+         MPrism::getNumFacesRep(curved);
 }
 
 static void _addEdgeNodes(int num, bool reverse, int order,
diff --git a/Geo/MPyramid.cpp b/Geo/MPyramid.cpp
index 457a7f952a21aa7e4e333f5e8523f026331035e9..73ee2fe9aadc096751f7d0f0ade22fd61eb5990e 100644
--- a/Geo/MPyramid.cpp
+++ b/Geo/MPyramid.cpp
@@ -97,7 +97,8 @@ int MPyramidN::getNumFacesRep(bool curved)
 {
   // FIXME: remove !getIsAssimilatedSerendipity() when serendip are implemented
   return (curved && !getIsAssimilatedSerendipity()) ?
-    6 * gmsh_SQU(CTX::instance()->mesh.numSubEdges) : 6;
+         6 * gmsh_SQU(CTX::instance()->mesh.numSubEdges) :
+         MPyramid::getNumFacesRep(curved);
 }
 
 static void _myGetFaceRep(MPyramid *pyr, int num, double *x, double *y, double *z,
diff --git a/Geo/MQuadrangle.cpp b/Geo/MQuadrangle.cpp
index 9a2d1f07239b51fab31cc5eb0ffcb46e434ef283..b552a504ca0633f419d0909d755035d5f6f0ef05 100644
--- a/Geo/MQuadrangle.cpp
+++ b/Geo/MQuadrangle.cpp
@@ -17,8 +17,6 @@
 
 #include <cstring>
 
-#define SQU(a)      ((a)*(a))
-
 void MQuadrangle::getEdgeRep(bool curved, int num, double *x, double *y, double *z,
                              SVector3 *n)
 {
@@ -137,17 +135,20 @@ int MQuadrangle::getNumFacesRep(bool curved)
 
 int MQuadrangleN::getNumFacesRep(bool curved)
 {
-  return curved ? 2*SQU(CTX::instance()->mesh.numSubEdges) : 2;
+  return curved ? 2 * gmsh_SQU(CTX::instance()->mesh.numSubEdges) :
+         MQuadrangle::getNumFacesRep(curved);
 }
 
 int MQuadrangle8::getNumFacesRep(bool curved)
 {
-  return curved ? 2*SQU(CTX::instance()->mesh.numSubEdges) : 2;
+  return curved ? 2 * gmsh_SQU(CTX::instance()->mesh.numSubEdges) :
+         MQuadrangle::getNumFacesRep(curved);
 }
 
 int MQuadrangle9::getNumFacesRep(bool curved)
 {
-  return curved ? 2*SQU(CTX::instance()->mesh.numSubEdges) : 2;
+  return curved ? 2 * gmsh_SQU(CTX::instance()->mesh.numSubEdges) :
+         MQuadrangle::getNumFacesRep(curved);
 }
 
 static void _myGetFaceRep(MQuadrangle *t, int num, double *x, double *y, double *z,
diff --git a/Geo/MVertex.h b/Geo/MVertex.h
index df093d162aa6a33fc6606b177298adeb8f03724d..8fe6c822ed2db6d6147e84d9a814e1979c02c9e2 100644
--- a/Geo/MVertex.h
+++ b/Geo/MVertex.h
@@ -113,8 +113,8 @@ class MEdgeVertex : public MVertex{
  public:
   MVertexBoundaryLayerData* bl_data;
 
-  MEdgeVertex(double x, double y, double z, GEntity *ge, double u, double lc = -1.0,
-              int num = 0)
+  MEdgeVertex(double x, double y, double z, GEntity *ge, double u, int num = 0,
+              double lc = -1.0)
     : MVertex(x, y, z, ge,num), _u(u), _lc(lc), bl_data(0)
   {
   }
@@ -130,12 +130,16 @@ class MFaceVertex : public MVertex{
  public :
   MVertexBoundaryLayerData* bl_data;
 
-  MFaceVertex(double x, double y, double z, GEntity *ge, double u, double v, int num = 0)
+  MFaceVertex(double x, double y, double z, GEntity *ge, double u, double v,
+              int num = 0)
     : MVertex(x, y, z, ge, num), _u(u), _v(v), bl_data(0)
   {
   }
   virtual ~MFaceVertex(){ if(bl_data) delete bl_data; }
-  virtual bool getParameter(int i, double &par) const { par = (i ? _v : _u); return true; }
+  virtual bool getParameter(int i, double &par) const
+  {
+    par = (i ? _v : _u); return true;
+  }
   virtual bool setParameter(int i, double par)
   {
     if(!i)
diff --git a/Geo/discreteEdge.cpp b/Geo/discreteEdge.cpp
index 81863528f0332d95650c443069aab2fc4c962e4b..f26ec84da93799eccb7aee6e50547aeb2180cacd 100644
--- a/Geo/discreteEdge.cpp
+++ b/Geo/discreteEdge.cpp
@@ -295,7 +295,7 @@ void discreteEdge::parametrize(std::map<GFace*, std::map<MVertex*, MVertex*,
     MVertex *vR = lines[i]->getVertex(_orientation[i]);
     int param = i+1;
     MVertex *vNEW = new MEdgeVertex(vR->x(),vR->y(),vR->z(), this,
-                                    param, -1., vR->getNum());
+                                    param, vR->getNum());
     old2new.insert(std::make_pair(vR,vNEW));
     newVertices.push_back(vNEW);
     newLines.push_back(new MLine(vL, vNEW));
@@ -378,7 +378,7 @@ void discreteEdge::parametrize(std::map<MVertex*, MVertex*>& old2new)
     else vR = lines[i]->getVertex(0);
     int param = i+1;
     MVertex *vNEW = new MEdgeVertex(vR->x(),vR->y(),vR->z(), this,
-                                    param, -1., vR->getNum());
+                                    param, vR->getNum());
     old2new.insert(std::make_pair(vR,vNEW));
     newVertices.push_back(vNEW);
     newLines.push_back(new MLine(vL, vNEW));
diff --git a/Mesh/HighOrder.cpp b/Mesh/HighOrder.cpp
index fca6ece17873fb75e84510e983efa2ee92316128..3fb733953bb368d19b6c7a827c4ca93869ab59db 100644
--- a/Mesh/HighOrder.cpp
+++ b/Mesh/HighOrder.cpp
@@ -175,7 +175,7 @@ static bool getEdgeVerticesOnGeo(GEdge *ge, MVertex *v0, MVertex *v1,
     MVertex *v;
     int count = u0<u1? j + 1 : nPts + 1  - (j + 1);
     GPoint pc = ge->point(US[count]);
-    v = new MEdgeVertex(pc.x(), pc.y(), pc.z(), ge,US[count]);
+    v = new MEdgeVertex(pc.x(), pc.y(), pc.z(), ge, US[count]);
     // this destroys the ordering of the mesh vertices on the edge
     ve.push_back(v);
   }
diff --git a/Mesh/meshGEdge.cpp b/Mesh/meshGEdge.cpp
index 72fbcfa2f73189279ce29b69ce2bf449b22dc1b1..4b90125a2049831e5db54f1c20921ca07f9cb2c6 100644
--- a/Mesh/meshGEdge.cpp
+++ b/Mesh/meshGEdge.cpp
@@ -90,7 +90,6 @@ static double F_LcB(GEdge *ge, double t)
 
   /*  if (blf){
     double lc2 = (*blf)( p.x(), p.y(), p.z() , ge);
-    //    printf("p %g %g lc %g\n",p.x(),p.y(),lc2);
     lc = std::min(lc, lc2);
   }
   */
@@ -124,7 +123,6 @@ static double F_Lc(GEdge *ge, double t)
   /*
   if (blf){
     double lc2 = (*blf)( p.x(), p.y(), p.z() , ge);
-    //    printf("p %g %g lc %g\n",p.x(),p.y(),lc2);
     lc_here = std::min(lc_here, lc2);
   }
   */
@@ -461,7 +459,7 @@ static void createPoints(GVertex *gv, GEdge *ge, BoundaryLayerField *blf,
   while (1){
     if (L > blf->thickness || L > LEdge * .4) break;
     SPoint3 p (gv->x() + dir.x() * L, gv->y() + dir.y() * L, 0.0);
-    v.push_back(new MEdgeVertex(p.x(), p.y(), p.z(), ge,  ge->parFromPoint(p), blf->hfar));
+    v.push_back(new MEdgeVertex(p.x(), p.y(), p.z(), ge, ge->parFromPoint(p), 0, blf->hfar));
     int ith = v.size() ;
     L += hwall * pow (blf->ratio, ith);
   }
@@ -695,8 +693,7 @@ void meshGEdge::operator() (GEdge *ge)
         const double d = norm(der);
         double lc  = d/(P1.lc + dlc / dp * (d - P1.p));
         GPoint V = ge->point(t);
-	// printf("%d %g\n",NUMP-1,t);
-        mesh_vertices[NUMP - 1] = new MEdgeVertex(V.x(), V.y(), V.z(), ge, t, lc);
+        mesh_vertices[NUMP - 1] = new MEdgeVertex(V.x(), V.y(), V.z(), ge, t, 0, lc);
         NUMP++;
       }
       else {
diff --git a/Mesh/meshGFace.cpp b/Mesh/meshGFace.cpp
index e1ea164d64f394e3d207d14c937aea30c77751d5..2958b5bceefdd21d082197fc934c23da814533ca 100644
--- a/Mesh/meshGFace.cpp
+++ b/Mesh/meshGFace.cpp
@@ -481,7 +481,7 @@ static void remeshUnrecoveredEdges(std::map<MVertex*, BDS_Point*> &recoverMapInv
           double t = 0.5 * (t2 + t1);
           double lc = 0.5 * (lc1 + lc2);
           GPoint V = itr->ge->point(t);
-          MEdgeVertex * newv = new MEdgeVertex(V.x(), V.y(), V.z(), itr->ge, t, lc);
+          MEdgeVertex * newv = new MEdgeVertex(V.x(), V.y(), V.z(), itr->ge, t, 0, lc);
           newLines.push_back(new MLine(v1, newv));
           newLines.push_back(new MLine(newv, v2));
           delete itr->ge->lines[i];
@@ -2265,7 +2265,7 @@ static bool meshGeneratorPeriodic(GFace *gf, bool debug = true)
         if (mv1->onWhat()->dim() == 1) {
           double t;
           mv1->getParameter(0,t);
-          mv2 = new MEdgeVertex(mv1->x(),mv1->y(),mv1->z(),mv1->onWhat(), t,
+          mv2 = new MEdgeVertex(mv1->x(),mv1->y(),mv1->z(),mv1->onWhat(), t, 0,
                                 ((MEdgeVertex*)mv1)->getLc());
         }
         else if (mv1->onWhat()->dim() == 0) {
diff --git a/Mesh/meshGRegionBoundaryRecovery.cpp b/Mesh/meshGRegionBoundaryRecovery.cpp
index 6eedb2369c4b5a9989bdfcb976c535caf4543ea6..4fa6d0a3dbd9ed4e97210148368af8320b28080b 100644
--- a/Mesh/meshGRegionBoundaryRecovery.cpp
+++ b/Mesh/meshGRegionBoundaryRecovery.cpp
@@ -125,26 +125,26 @@ bool tetgenmesh::reconstructmesh(void *p)
   {
     std::set<MVertex*, MVertexLessThanNum> all;
     std::list<GFace*> f = _gr->faces();
-    for (std::list<GFace*>::iterator it = f.begin(); it != f.end(); ++it) {
+    for(std::list<GFace*>::iterator it = f.begin(); it != f.end(); ++it){
       GFace *gf = *it;
-      for (unsigned int i = 0; i < gf->triangles.size(); i++){
+      for(unsigned int i = 0; i < gf->triangles.size(); i++){
         all.insert(gf->triangles[i]->getVertex(0));
         all.insert(gf->triangles[i]->getVertex(1));
         all.insert(gf->triangles[i]->getVertex(2));
       }
     }
     std::list<GEdge*> e = _gr->embeddedEdges();
-    for (std::list<GEdge*>::iterator it = e.begin(); it != e.end(); ++it) {
+    for(std::list<GEdge*>::iterator it = e.begin(); it != e.end(); ++it){
       GEdge *ge = *it;
-      for (unsigned int i = 0; i < ge->lines.size(); i++){
+      for(unsigned int i = 0; i < ge->lines.size(); i++){
         all.insert(ge->lines[i]->getVertex(0));
         all.insert(ge->lines[i]->getVertex(1));
       }
     }
     std::list<GVertex*> v = _gr->embeddedVertices();
-    for (std::list<GVertex*>::iterator it = v.begin(); it != v.end(); ++it) {
+    for(std::list<GVertex*>::iterator it = v.begin(); it != v.end(); ++it){
       GVertex *gv = *it;
-      for (unsigned int i = 0; i < gv->points.size(); i++){
+      for(unsigned int i = 0; i < gv->points.size(); i++){
         all.insert(gv->points[i]->getVertex(0));
       }
     }
@@ -166,19 +166,19 @@ bool tetgenmesh::reconstructmesh(void *p)
     REAL x, y, z;
 
     // Read the points.
-    for (unsigned int i = 0; i < _vertices.size(); i++) {
+    for(unsigned int i = 0; i < _vertices.size(); i++){
       makepoint(&pointloop, UNUSEDVERTEX);
       // Read the point coordinates.
       x = pointloop[0] = _vertices[i]->x();
       y = pointloop[1] = _vertices[i]->y();
       z = pointloop[2] = _vertices[i]->z();
       // Determine the smallest and largest x, y and z coordinates.
-      if (i == 0) {
+      if(i == 0){
 	xmin = xmax = x;
 	ymin = ymax = y;
 	zmin = zmax = z;
       }
-      else {
+      else{
 	xmin = (x < xmin) ? x : xmin;
 	xmax = (x > xmax) ? x : xmax;
 	ymin = (y < ymin) ? y : ymin;
@@ -193,13 +193,13 @@ bool tetgenmesh::reconstructmesh(void *p)
     y = ymax - ymin;
     z = zmax - zmin;
     longest = sqrt(x * x + y * y + z * z);
-    if (longest == 0.0) {
+    if(longest == 0.0){
       Msg::Warning("The point set is trivial");
       return true;
     }
 
     // Two identical points are distinguished by 'lengthlimit'.
-    if (minedgelength == 0.0) {
+    if(minedgelength == 0.0){
       minedgelength = longest * b->epsilon;
     }
   }
@@ -209,13 +209,13 @@ bool tetgenmesh::reconstructmesh(void *p)
   // Create a map from indices to vertices.
   makeindex2pointmap(idx2verlist);
   // 'idx2verlist' has length 'in->numberofpoints + 1'.
-  if (in->firstnumber == 1) {
+  if(in->firstnumber == 1){
     idx2verlist[0] = dummypoint; // Let 0th-entry be dummypoint.
   }
 
   {
     // Index the vertices.
-    for (unsigned int i = 0; i < _vertices.size(); i++){
+    for(unsigned int i = 0; i < _vertices.size(); i++){
       _vertices[i]->setIndex(i);
     }
 
@@ -234,26 +234,26 @@ bool tetgenmesh::reconstructmesh(void *p)
 
     // Allocate an array that maps each vertex to its adjacent tets.
     ver2tetarray = new tetrahedron[_vertices.size() + 1];
-    //for (i = 0; i < in->numberofpoints + 1; i++) {
-    for (unsigned int i = in->firstnumber; i < _vertices.size() + in->firstnumber; i++) {
+    //for(i = 0; i < in->numberofpoints + 1; i++){
+    for(unsigned int i = in->firstnumber; i < _vertices.size() + in->firstnumber; i++){
       setpointtype(idx2verlist[i], VOLVERTEX); // initial type.
       ver2tetarray[i] = NULL;
     }
 
     // Create the tetrahedra and connect those that share a common face.
-    for (unsigned int i = 0; i < tets.size(); i++) {
+    for(unsigned int i = 0; i < tets.size(); i++){
       // Get the four vertices.
-      for (int j = 0; j < 4; j++) {
+      for(int j = 0; j < 4; j++){
 	p[j] = idx2verlist[tets[i]->getVertex(j)->getIndex()];
       }
       // Check the orientation.
       ori = orient3d(p[0], p[1], p[2], p[3]);
-      if (ori > 0.0) {
+      if(ori > 0.0){
 	// Swap the first two vertices.
 	q[0] = p[0]; p[0] = p[1]; p[1] = q[0];
       }
-      else if (ori == 0.0) {
-	if (!b->quiet) {
+      else if(ori == 0.0){
+	if(!b->quiet){
 	  printf("Warning:  Tet #%d is degenerate.\n", i + in->firstnumber);
 	}
       }
@@ -261,7 +261,7 @@ bool tetgenmesh::reconstructmesh(void *p)
       maketetrahedron(&tetloop); // tetloop.ver = 11.
       setvertices(tetloop, p[0], p[1], p[2], p[3]);
       // Try connecting this tet to others that share the common faces.
-      for (tetloop.ver = 0; tetloop.ver < 4; tetloop.ver++) {
+      for(tetloop.ver = 0; tetloop.ver < 4; tetloop.ver++){
 	p[3] = oppo(tetloop);
 	// Look for other tets having this vertex.
 	idx = pointmark(p[3]);
@@ -271,7 +271,7 @@ bool tetgenmesh::reconstructmesh(void *p)
 	// Push the current tet onto the stack.
 	ver2tetarray[idx] = encode(tetloop);
 	decode(tptr, checktet);
-	if (checktet.tet != NULL) {
+	if(checktet.tet != NULL){
 	  p[0] =  org(tetloop); // a
 	  p[1] = dest(tetloop); // b
 	  p[2] = apex(tetloop); // c
@@ -282,21 +282,21 @@ bool tetgenmesh::reconstructmesh(void *p)
 	    q[2] = apex(checktet); // c'
 	    // Check the three faces at 'd' in 'checktet'.
 	    bondflag = 0;
-	    for (int j = 0; j < 3; j++) {
+	    for(int j = 0; j < 3; j++){
 	      // Go to the face [b',a',d], or [c',b',d], or [a',c',d].
 	      esym(checktet, face2);
-	      if (face2.tet[face2.ver & 3] == NULL) {
+	      if(face2.tet[face2.ver & 3] == NULL){
 		k = ((j + 1) % 3);
-		if (q[k] == p[0]) {   // b', c', a' = a
-		  if (q[j] == p[1]) { // a', b', c' = b
+		if(q[k] == p[0]){   // b', c', a' = a
+		  if(q[j] == p[1]){ // a', b', c' = b
 		    // [#,#,d] is matched to [b,a,d].
 		    esym(tetloop, face1);
 		    bond(face1, face2);
 		    bondflag++;
 		  }
 		}
-		if (q[k] == p[1]) {   // b',c',a' = b
-		  if (q[j] == p[2]) { // a',b',c' = c
+		if(q[k] == p[1]){   // b',c',a' = b
+		  if(q[j] == p[2]){ // a',b',c' = c
 		    // [#,#,d] is matched to [c,b,d].
 		    enext(tetloop, face1);
 		    esymself(face1);
@@ -304,8 +304,8 @@ bool tetgenmesh::reconstructmesh(void *p)
 		    bondflag++;
 		  }
 		}
-		if (q[k] == p[2]) {   // b',c',a' = c
-		  if (q[j] == p[0]) { // a',b',c' = a
+		if(q[k] == p[2]){   // b',c',a' = c
+		  if(q[j] == p[0]){ // a',b',c' = a
 		    // [#,#,d] is matched to [a,c,d].
 		    eprev(tetloop, face1);
 		    esymself(face1);
@@ -314,26 +314,26 @@ bool tetgenmesh::reconstructmesh(void *p)
 		  }
 		}
 	      }
-              else {
+              else{
 		bondflag++;
 	      }
 	      enextself(checktet);
 	    } // j
 	    // Go to the next tet in the link.
 	    tptr = checktet.tet[8 + checktet.ver];
-	    if (bondflag == 3) {
+	    if(bondflag == 3){
 	      // All three faces at d in 'checktet' have been connected.
 	      // It can be removed from the link.
 	      prevchktet.tet[8 + prevchktet.ver] = tptr;
 	    }
-            else {
+            else{
 	      // Bakup the previous tet in the link.
 	      prevchktet = checktet;
 	    }
 	    decode(tptr, checktet);
 	  } while (checktet.tet != NULL);
-	} // if (checktet.tet != NULL)
-      } // for (tetloop.ver = 0; ...
+	} // if(checktet.tet != NULL)
+      } // for(tetloop.ver = 0; ...
     } // i
 
     // Remember a tet of the mesh.
@@ -345,10 +345,10 @@ bool tetgenmesh::reconstructmesh(void *p)
 
     tetrahedrons->traversalinit();
     tetloop.tet = tetrahedrontraverse();
-    while (tetloop.tet != (tetrahedron *) NULL) {
+    while (tetloop.tet != (tetrahedron *) NULL){
       tptr = encode(tetloop);
-      for (tetloop.ver = 0; tetloop.ver < 4; tetloop.ver++) {
-	if (tetloop.tet[tetloop.ver] == NULL) {
+      for(tetloop.ver = 0; tetloop.ver < 4; tetloop.ver++){
+	if(tetloop.tet[tetloop.ver] == NULL){
 	  // Create a hull tet.
 	  maketetrahedron(&hulltet);
 	  p[0] =  org(tetloop);
@@ -357,15 +357,15 @@ bool tetgenmesh::reconstructmesh(void *p)
 	  setvertices(hulltet, p[1], p[0], p[2], dummypoint);
 	  bond(tetloop, hulltet);
 	  // Try connecting this to others that share common hull edges.
-	  for (int j = 0; j < 3; j++) {
+	  for(int j = 0; j < 3; j++){
 	    fsym(hulltet, face2);
-	    while (1) {
-	      if (face2.tet == NULL) break;
+	    while (1){
+	      if(face2.tet == NULL) break;
 	      esymself(face2);
-	      if (apex(face2) == dummypoint) break;
+	      if(apex(face2) == dummypoint) break;
 	      fsymself(face2);
 	    }
-	    if (face2.tet != NULL) {
+	    if(face2.tet != NULL){
 	      // Found an adjacent hull tet.
 	      assert(face2.tet[face2.ver & 3] == NULL);
 	      esym(hulltet, face1);
@@ -399,12 +399,12 @@ bool tetgenmesh::reconstructmesh(void *p)
     point p[4];
     int idx;
 
-    for (std::list<GFace*>::iterator it = f_list.begin(); it != f_list.end(); ++it){
+    for(std::list<GFace*>::iterator it = f_list.begin(); it != f_list.end(); ++it){
       GFace *gf = *it;
-      for (unsigned int i = 0; i < gf->triangles.size(); i++) {
-	for (int j = 0; j < 3; j++) {
+      for(unsigned int i = 0; i < gf->triangles.size(); i++){
+	for(int j = 0; j < 3; j++){
 	  p[j] = idx2verlist[gf->triangles[i]->getVertex(j)->getIndex()];
-	  if (pointtype(p[j]) == VOLVERTEX) {
+	  if(pointtype(p[j]) == VOLVERTEX){
 	    setpointtype(p[j], FACETVERTEX);
 	  }
 	}
@@ -413,7 +413,7 @@ bool tetgenmesh::reconstructmesh(void *p)
 	setshvertices(newsh, p[0], p[1], p[2]);
 	setshellmark(newsh, gf->tag()); // the GFace's tag.
 	recentsh = newsh;
-	for (int j = 0; j < 3; j++) {
+	for(int j = 0; j < 3; j++){
 	  makeshellface(subsegs, &newseg);
 	  setshvertices(newseg, sorg(newsh), sdest(newsh), NULL);
 	  // Set the default segment marker '-1'.
@@ -441,15 +441,15 @@ bool tetgenmesh::reconstructmesh(void *p)
     // Process the set of PSC edges.
     // Remeber that all segments have default marker '-1'.
     //    int COUNTER = 0;
-    for (std::list<GEdge*>::iterator it = e_list.begin(); it != e_list.end();
-	 ++it) {
+    for(std::list<GEdge*>::iterator it = e_list.begin(); it != e_list.end();
+	 ++it){
       GEdge *ge = *it;
-      for (unsigned int i = 0; i < ge->lines.size(); i++) {
-	for (int j = 0; j < 2; j++) {
+      for(unsigned int i = 0; i < ge->lines.size(); i++){
+	for(int j = 0; j < 2; j++){
 	  p[j] = idx2verlist[ge->lines[i]->getVertex(j)->getIndex()];
 	  setpointtype(p[j], RIDGEVERTEX);
         }
-	if (p[0] == p[1]) {
+	if(p[0] == p[1]){
 	  // This is a potential problem in surface mesh.
 	  continue; // Skip this edge.
 	}
@@ -457,57 +457,57 @@ bool tetgenmesh::reconstructmesh(void *p)
 	newseg.sh = NULL;
 	searchsh.sh = NULL;
 	idx = pointmark(p[0]) - in->firstnumber;
-	for (int j = idx2shlist[idx]; j < idx2shlist[idx + 1]; j++) {
+	for(int j = idx2shlist[idx]; j < idx2shlist[idx + 1]; j++){
 	  checkpt = sdest(shperverlist[j]);
-	  if (checkpt == p[1]) {
+	  if(checkpt == p[1]){
 	    searchsh = shperverlist[j];
 	    break; // Found.
 	  }
-          else {
+          else{
 	    checkpt = sapex(shperverlist[j]);
-	    if (checkpt == p[1]) {
+	    if(checkpt == p[1]){
 	      senext2(shperverlist[j], searchsh);
 	      sesymself(searchsh);
 	      break;
 	    }
 	  }
 	} // j
-	if (searchsh.sh != NULL) {
+	if(searchsh.sh != NULL){
 	  // Check if this edge is already a segment of the mesh.
 	  sspivot(searchsh, checkseg);
-          if (checkseg.sh != NULL) {
+          if(checkseg.sh != NULL){
             // This segment already exist.
             newseg = checkseg;
           }
-          else {
+          else{
             // Create a new segment at this edge.
             makeshellface(subsegs, &newseg);
             setshvertices(newseg, p[0], p[1], NULL);
             ssbond(searchsh, newseg);
             spivot(searchsh, neighsh);
-            if (neighsh.sh != NULL) {
+            if(neighsh.sh != NULL){
               ssbond(neighsh, newseg);
             }
           }
 	}
-        else {
+        else{
 	  // It is a dangling segment (not belong to any facets).
 	  // Check if segment [p[0],p[1]] already exists.
 	  // TODO: Change the brute-force search. Slow!
 	  /*	  point *ppt;
 	  subsegs->traversalinit();
 	  segloop.sh = shellfacetraverse(subsegs);
-	  while (segloop.sh != NULL) {
+	  while (segloop.sh != NULL){
 	    ppt = (point *) &(segloop.sh[3]);
-	    if (((ppt[0] == p[0]) && (ppt[1] == p[1])) ||
-		((ppt[0] == p[1]) && (ppt[1] == p[0]))) {
+	    if(((ppt[0] == p[0]) && (ppt[1] == p[1])) ||
+		((ppt[0] == p[1]) && (ppt[1] == p[0]))){
 	      // Found!
 	      newseg = segloop;
 	      break;
 	    }
 	    segloop.sh = shellfacetraverse(subsegs);
 	    }*/
-	  if (newseg.sh == NULL) {
+	  if(newseg.sh == NULL){
 	    makeshellface(subsegs, &newseg);
 	    setshvertices(newseg, p[0], p[1], NULL);
 	  }
@@ -525,7 +525,7 @@ bool tetgenmesh::reconstructmesh(void *p)
     // The total number of iunput segments.
     insegments = subsegs->items;
 
-    if (0) {
+    if(0){
       outmesh2medit("dump2");
     }
 
@@ -541,7 +541,7 @@ bool tetgenmesh::reconstructmesh(void *p)
 
   carveholes();
 
-  if (subvertstack->objects > 0l) {
+  if(subvertstack->objects > 0l){
     suppresssteinerpoints();
   }
 
@@ -550,7 +550,7 @@ bool tetgenmesh::reconstructmesh(void *p)
   // let's try
   optimizemesh();
 
-  if ((dupverts > 0l) || (unuverts > 0l)) {
+  if((dupverts > 0l) || (unuverts > 0l)){
     // Remove hanging nodes.
     // cannot call this here due to 8 additional exterior vertices we inserted
     // jettisonnodes();
@@ -560,7 +560,7 @@ bool tetgenmesh::reconstructmesh(void *p)
 
   Msg::Debug("Statistics:\n");
   Msg::Debug("  Input points: %ld", _vertices.size());
-  if (b->plc) {
+  if(b->plc){
     Msg::Debug("  Input facets: %ld", f_list.size());
     Msg::Debug("  Input segments: %ld", e_list.size());
   }
@@ -568,50 +568,51 @@ bool tetgenmesh::reconstructmesh(void *p)
   tetnumber = tetrahedrons->items - hullsize;
   facenumber = (tetnumber * 4l + hullsize) / 2l;
 
-  if (b->weighted) { // -w option
+  if(b->weighted){ // -w option
     Msg::Debug(" Mesh points: %ld", points->items - nonregularcount);
   }
-  else {
+  else{
     Msg::Debug(" Mesh points: %ld", points->items);
   }
   Msg::Debug("  Mesh tetrahedra: %ld", tetnumber);
   Msg::Debug("  Mesh faces: %ld", facenumber);
-  if (meshedges > 0l) {
+  if(meshedges > 0l){
     Msg::Debug("  Mesh edges: %ld", meshedges);
-  } else {
-    if (!nonconvex) {
+  }
+  else{
+    if(!nonconvex){
       long vsize = points->items - dupverts - unuverts;
-      if (b->weighted) vsize -= nonregularcount;
+      if(b->weighted) vsize -= nonregularcount;
       meshedges = vsize + facenumber - tetnumber - 1;
       Msg::Debug("  Mesh edges: %ld", meshedges);
     }
   }
 
-  if (b->plc || b->refine) {
+  if(b->plc || b->refine){
     Msg::Debug("  Mesh faces on facets: %ld", subfaces->items);
     Msg::Debug("  Mesh edges on segments: %ld", subsegs->items);
-    if (st_volref_count > 0l) {
+    if(st_volref_count > 0l){
       Msg::Debug("  Steiner points inside domain: %ld", st_volref_count);
     }
-    if (st_facref_count > 0l) {
+    if(st_facref_count > 0l){
       Msg::Debug("  Steiner points on facets:  %ld", st_facref_count);
     }
-    if (st_segref_count > 0l) {
+    if(st_segref_count > 0l){
       Msg::Debug("  Steiner points on segments:  %ld", st_segref_count);
     }
   }
-  else {
+  else{
     Msg::Debug("  Convex hull faces: %ld", hullsize);
-    if (meshhulledges > 0l) {
+    if (meshhulledges > 0l){
       Msg::Debug("  Convex hull edges: %ld", meshhulledges);
     }
   }
-  if (b->weighted) { // -w option
+  if(b->weighted){ // -w option
     Msg::Debug("  Skipped non-regular points: %ld", nonregularcount);
   }
 
   // Debug
-  if (0) {
+  if(0){
     outmesh2medit("dump");
   }
 
@@ -626,17 +627,17 @@ bool tetgenmesh::reconstructmesh(void *p)
     // Find the list of GFaces, GEdges that have been modified.
     std::set<int> l_faces, l_edges;
 
-    if (points->items > (int)_vertices.size()) {
+    if(points->items > (int)_vertices.size()){
       face parentseg, parentsh, spinsh;
       point pointloop;
       // Create newly added mesh vertices.
       // The new vertices must be added at the end of the point list.
       points->traversalinit();
       pointloop = pointtraverse();
-      while (pointloop != (point) NULL) {
-        if (issteinerpoint(pointloop)) {
+      while (pointloop != (point) NULL){
+        if(issteinerpoint(pointloop)){
           // Check if this Steiner point locates on boundary.
-          if (pointtype(pointloop) == FREESEGVERTEX) {
+          if(pointtype(pointloop) == FREESEGVERTEX){
             sdecode(point2sh(pointloop), parentseg);
             assert(parentseg.sh != NULL);
             l_edges.insert(shellmark(parentseg));
@@ -644,18 +645,18 @@ bool tetgenmesh::reconstructmesh(void *p)
             GEdge *ge = NULL;
             GFace *gf = NULL;
             int etag = shellmark(parentseg);
-            for (std::list<GEdge*>::iterator it = e_list.begin();
-                 it != e_list.end(); ++it) {
-              if ((*it)->tag() == etag) {
+            for(std::list<GEdge*>::iterator it = e_list.begin();
+                 it != e_list.end(); ++it){
+              if((*it)->tag() == etag){
                 ge = *it;
                 break;
               }
             }
-            if (ge != NULL) {
+            if(ge != NULL){
               MEdgeVertex *v = new MEdgeVertex(pointloop[0], pointloop[1],
                                                pointloop[2], ge, 0);
               double uu = 0;
-              if (reparamMeshVertexOnEdge(v, ge, uu)) {
+              if(reparamMeshVertexOnEdge(v, ge, uu)){
                 v->setParameter(0, uu);
               }
               v->setIndex(pointmark(pointloop));
@@ -663,22 +664,22 @@ bool tetgenmesh::reconstructmesh(void *p)
 	      _extras[pointmark(pointloop)] = v;
             }
             spivot(parentseg, parentsh);
-            if (parentsh.sh != NULL) {
-              if (ge == NULL) {
+            if(parentsh.sh != NULL){
+              if(ge == NULL){
                 // We treat this vertex a facet vertex.
                 int ftag = shellmark(parentsh);
-                for (std::list<GFace*>::iterator it = f_list.begin();
-                     it != f_list.end(); ++it) {
-                  if ((*it)->tag() == ftag) {
+                for(std::list<GFace*>::iterator it = f_list.begin();
+                     it != f_list.end(); ++it){
+                  if((*it)->tag() == ftag){
                     gf = *it;
                     break;
                   }
                 }
-                if (gf != NULL) {
+                if(gf != NULL){
                   MFaceVertex *v = new MFaceVertex(pointloop[0], pointloop[1],
                                                    pointloop[2], gf, 0, 0);
                   SPoint2 param;
-                  if (reparamMeshVertexOnFace(v, gf, param)) {
+                  if(reparamMeshVertexOnFace(v, gf, param)){
                     v->setParameter(0, param.x());
                     v->setParameter(1, param.y());
                   }
@@ -689,38 +690,39 @@ bool tetgenmesh::reconstructmesh(void *p)
               }
               // Record all the GFaces' tag at this segment.
               spinsh = parentsh;
-              while (1) {
+              while (1){
                 l_faces.insert(shellmark(spinsh));
                 spivotself(spinsh);
-                if (spinsh.sh == parentsh.sh) break;
+                if(spinsh.sh == parentsh.sh) break;
               }
             }
-            if ((ge == NULL) && (gf == NULL)) {
+            if((ge == NULL) && (gf == NULL)){
               // Create an interior mesh vertex.
               MVertex *v = new MVertex(pointloop[0], pointloop[1], pointloop[2], _gr);
               v->setIndex(pointmark(pointloop));
 	      _extras[pointmark(pointloop)] = v;
-	      _gr->mesh_vertices.push_back(v);            }
+	      _gr->mesh_vertices.push_back(v);
+            }
           }
-          else if (pointtype(pointloop) == FREEFACETVERTEX) {
+          else if(pointtype(pointloop) == FREEFACETVERTEX){
             sdecode(point2sh(pointloop), parentsh);
             assert(parentsh.sh != NULL);
             l_faces.insert(shellmark(parentsh));
             // Get the GFace containing this vertex.
             GFace *gf = NULL;
             int ftag = shellmark(parentsh);
-            for (std::list<GFace*>::iterator it = f_list.begin();
-                 it != f_list.end(); ++it) {
-              if ((*it)->tag() == ftag) {
+            for(std::list<GFace*>::iterator it = f_list.begin();
+                 it != f_list.end(); ++it){
+              if((*it)->tag() == ftag){
                 gf = *it;
                 break;
               }
             }
-            if (gf != NULL) {
+            if(gf != NULL){
               MFaceVertex *v = new MFaceVertex(pointloop[0], pointloop[1],
                                                pointloop[2], gf, 0, 0);
               SPoint2 param;
-              if (reparamMeshVertexOnFace(v, gf, param)) {
+              if(reparamMeshVertexOnFace(v, gf, param)){
                 v->setParameter(0, param.x());
                 v->setParameter(1, param.y());
               }
@@ -728,7 +730,7 @@ bool tetgenmesh::reconstructmesh(void *p)
               _gr->mesh_vertices.push_back(v);
 	      _extras[pointmark(pointloop)] = v;
             }
-            else {
+            else{
               // Create a mesh vertex.
               MVertex *v = new MVertex(pointloop[0], pointloop[1], pointloop[2], _gr);
               v->setIndex(pointmark(pointloop));
@@ -736,7 +738,7 @@ bool tetgenmesh::reconstructmesh(void *p)
 	      _extras[pointmark(pointloop)] = v;
             }
           }
-          else {
+          else{
             MVertex *v = new MVertex(pointloop[0], pointloop[1], pointloop[2], _gr);
             v->setIndex(pointmark(pointloop));
             _gr->mesh_vertices.push_back(v);
@@ -745,23 +747,23 @@ bool tetgenmesh::reconstructmesh(void *p)
         }
         pointloop = pointtraverse();
       }
-      //      assert((int)_vertices.size() == points->items);
+      // assert((int)_vertices.size() == points->items);
     }
 
-    if (!_extras.empty())
+    if(!_extras.empty())
       Msg::Info("We add %d steiner points...", _extras.size());
 
-    if (l_edges.size() > 0) {
+    if(l_edges.size() > 0){
       // There are Steiner points on segments!
       face segloop;
       // Re-create the segment mesh in the corresponding GEdges.
-      for (std::set<int>::iterator it = l_edges.begin(); it!=l_edges.end(); ++it) {
+      for(std::set<int>::iterator it = l_edges.begin(); it!=l_edges.end(); ++it){
         // Find the GFace with tag = *it.
         GEdge *ge = NULL;
         int etag = *it;
-        for (std::list<GEdge*>::iterator eit = e_list.begin();
-             eit != e_list.end(); ++eit) {
-          if ((*eit)->tag() == etag) {
+        for(std::list<GEdge*>::iterator eit = e_list.begin();
+             eit != e_list.end(); ++eit){
+          if((*eit)->tag() == etag){
             ge = (*eit);
             break;
           }
@@ -777,8 +779,8 @@ bool tetgenmesh::reconstructmesh(void *p)
         segloop.shver = 0;
         subsegs->traversalinit();
         segloop.sh = shellfacetraverse(subsegs);
-        while (segloop.sh != NULL) {
-          if (shellmark(segloop) == etag) {
+        while (segloop.sh != NULL){
+          if(shellmark(segloop) == etag){
             p[0] = sorg(segloop);
             p[1] = sdest(segloop);
             MVertex *v1 = pointmark(p[0]) >= (int)_vertices.size() ?
@@ -796,17 +798,17 @@ bool tetgenmesh::reconstructmesh(void *p)
       } // it
     }
 
-    if (l_faces.size() > 0) {
+    if(l_faces.size() > 0){
       // There are Steiner points on facets!
       face subloop;
       // Re-create the surface mesh in the corresponding GFaces.
-      for (std::set<int>::iterator it = l_faces.begin(); it != l_faces.end(); ++it) {
+      for(std::set<int>::iterator it = l_faces.begin(); it != l_faces.end(); ++it){
         // Find the GFace with tag = *it.
         GFace *gf = NULL;
         int ftag = *it;
-        for (std::list<GFace*>::iterator fit = f_list.begin();
-             fit != f_list.end(); ++fit) {
-          if ((*fit)->tag() == ftag) {
+        for(std::list<GFace*>::iterator fit = f_list.begin();
+             fit != f_list.end(); ++fit){
+          if((*fit)->tag() == ftag){
             gf = (*fit);
             break;
           }
@@ -825,8 +827,8 @@ bool tetgenmesh::reconstructmesh(void *p)
         subloop.shver = 0;
         subfaces->traversalinit();
         subloop.sh = shellfacetraverse(subfaces);
-        while (subloop.sh != NULL) {
-          if (shellmark(subloop) == ftag) {
+        while (subloop.sh != NULL){
+          if(shellmark(subloop) == ftag){
             p[0] = sorg(subloop);
             p[1] = sdest(subloop);
             p[2] = sapex(subloop);
@@ -836,11 +838,11 @@ bool tetgenmesh::reconstructmesh(void *p)
               _extras[pointmark(p[1])] : _vertices[pointmark(p[1])];
             MVertex *v3 = pointmark(p[2]) >= (int)_vertices.size() ?
               _extras[pointmark(p[2])] : _vertices[pointmark(p[2])];
-	    // if (pointmark(p[0]) >= _vertices.size())
+	    // if(pointmark(p[0]) >= _vertices.size())
             //   printf("F %d %d\n",v1->getIndex(),pointmark(p[0]));
-	    // if (pointmark(p[1]) >= _vertices.size())
+	    // if(pointmark(p[1]) >= _vertices.size())
             //   printf("F %d %d\n",v2->getIndex(),pointmark(p[1]));
-	    // if (pointmark(p[2]) >= _vertices.size())
+	    // if(pointmark(p[2]) >= _vertices.size())
             //   printf("F %d %d\n",v3->getIndex(),pointmark(p[2]));
 	    // MVertex *v1 = _vertices[pointmark(p[0])];
 	    // MVertex *v2 = _vertices[pointmark(p[1])];
@@ -859,7 +861,7 @@ bool tetgenmesh::reconstructmesh(void *p)
     tetrahedrons->traversalinit();
     tetloop.tet = tetrahedrontraverse();
 
-    while (tetloop.tet != (tetrahedron *) NULL) {
+    while (tetloop.tet != (tetrahedron *) NULL){
       p[0] = org(tetloop);
       p[1] = dest(tetloop);
       p[2] = apex(tetloop);
@@ -873,13 +875,13 @@ bool tetgenmesh::reconstructmesh(void *p)
         _extras[pointmark(p[2])] : _vertices[pointmark(p[2])];
       MVertex *v4 = pointmark(p[3]) >= (int)_vertices.size() ?
         _extras[pointmark(p[3])] : _vertices[pointmark(p[3])];
-      // if (pointmark(p[0]) >= _vertices.size())
+      // if(pointmark(p[0]) >= _vertices.size())
       //   printf("%d %d\n",v1->getIndex(),pointmark(p[0]));
-      // if (pointmark(p[1]) >= _vertices.size())
+      // if(pointmark(p[1]) >= _vertices.size())
       //   printf("%d %d\n",v2->getIndex(),pointmark(p[1]));
-      // if (pointmark(p[2]) >= _vertices.size())
+      // if(pointmark(p[2]) >= _vertices.size())
       //   printf("%d %d\n",v3->getIndex(),pointmark(p[2]));
-      // if (pointmark(p[3]) >= _vertices.size())
+      // if(pointmark(p[3]) >= _vertices.size())
       ///   printf("%d %d\n",v4->getIndex(),pointmark(p[3]));
       // MVertex *v1 = _vertices[pointmark(p[0])];
       // MVertex *v2 = _vertices[pointmark(p[1])];
@@ -908,7 +910,7 @@ void tetgenmesh::outsurfacemesh(const char* mfilename)
   strcpy(sfilename, mfilename);
   strcat(sfilename, ".node");
   outfile = fopen(sfilename, "w");
-  if (!b->quiet) {
+  if(!b->quiet){
     printf("Writing %s.\n", sfilename);
   }
   fprintf(outfile, "%ld  3  0  0\n", points->items);
@@ -917,7 +919,7 @@ void tetgenmesh::outsurfacemesh(const char* mfilename)
   points->traversalinit();
   pointloop = pointtraverse();
   pointnumber = firstindex; // in->firstnumber;
-  while (pointloop != (point) NULL) {
+  while (pointloop != (point) NULL){
     // Point number, x, y and z coordinates.
     fprintf(outfile, "%4d    %.17g  %.17g  %.17g", pointnumber,
             pointloop[0], pointloop[1], pointloop[2]);
@@ -932,18 +934,18 @@ void tetgenmesh::outsurfacemesh(const char* mfilename)
   strcpy(sfilename, mfilename);
   strcat(sfilename, ".smesh");
   outfile = fopen(sfilename, "w");
-  if (!b->quiet) {
+  if(!b->quiet){
     printf("Writing %s.\n", sfilename);
   }
   int shift = 0; // Default no shiftment.
-  if ((in->firstnumber == 1) && (firstindex == 0)) {
+  if((in->firstnumber == 1) && (firstindex == 0)){
     shift = 1; // Shift the output indices by 1.
   }
   fprintf(outfile, "0 3 0 0\n");
   fprintf(outfile, "%ld  1\n", subfaces->items);
   subfaces->traversalinit();
   faceloop.sh = shellfacetraverse(subfaces);
-  while (faceloop.sh != (shellface *) NULL) {
+  while (faceloop.sh != (shellface *) NULL){
     torg = sorg(faceloop);
     tdest = sdest(faceloop);
     tapex = sapex(faceloop);
@@ -961,14 +963,14 @@ void tetgenmesh::outsurfacemesh(const char* mfilename)
   strcpy(sfilename, mfilename);
   strcat(sfilename, ".edge");
   outfile = fopen(sfilename, "w");
-  if (!b->quiet) {
+  if(!b->quiet){
     printf("Writing %s.\n", sfilename);
   }
   fprintf(outfile, "%ld  1\n", subsegs->items);
   subsegs->traversalinit();
   edgeloop.sh = shellfacetraverse(subsegs);
   edgenumber = firstindex; // in->firstnumber;
-  while (edgeloop.sh != (shellface *) NULL) {
+  while (edgeloop.sh != (shellface *) NULL){
     torg = sorg(edgeloop);
     tdest = sdest(edgeloop);
     fprintf(outfile, "%5d   %4d  %4d  %d\n", edgenumber,
@@ -992,18 +994,19 @@ void tetgenmesh::outmesh2medit(const char* mfilename)
   int shift = 0;
   int marker;
 
-  if (mfilename != (char *) NULL && mfilename[0] != '\0') {
+  if(mfilename != (char *) NULL && mfilename[0] != '\0'){
     strcpy(mefilename, mfilename);
-  } else {
+  }
+  else{
     strcpy(mefilename, "unnamed");
   }
   strcat(mefilename, ".mesh");
 
-  if (!b->quiet) {
+  if(!b->quiet){
     printf("Writing %s.\n", mefilename);
   }
   outfile = fopen(mefilename, "w");
-  if (outfile == (FILE *) NULL) {
+  if(outfile == (FILE *) NULL){
     printf("File I/O Error:  Cannot create file %s.\n", mefilename);
     return;
   }
@@ -1021,7 +1024,7 @@ void tetgenmesh::outmesh2medit(const char* mfilename)
   points->traversalinit();
   ptloop = pointtraverse();
   //pointnumber = 1;
-  while (ptloop != (point) NULL) {
+  while (ptloop != (point) NULL){
     // Point coordinates.
     fprintf(outfile, "%.17g  %.17g  %.17g", ptloop[0], ptloop[1], ptloop[2]);
     fprintf(outfile, "    0\n");
@@ -1031,9 +1034,10 @@ void tetgenmesh::outmesh2medit(const char* mfilename)
   }
 
   // Medit need start number form 1.
-  if (in->firstnumber == 1) {
+  if(in->firstnumber == 1){
     shift = 0;
-  } else {
+  }
+  else{
     shift = 1;
   }
 
@@ -1046,11 +1050,12 @@ void tetgenmesh::outmesh2medit(const char* mfilename)
 
   tetrahedrons->traversalinit();
   tetptr = tetrahedrontraverse();
-  while (tetptr != (tetrahedron *) NULL) {
-    if (!b->reversetetori) {
+  while (tetptr != (tetrahedron *) NULL){
+    if(!b->reversetetori){
       p1 = (point) tetptr[4];
       p2 = (point) tetptr[5];
-    } else {
+    }
+    else{
       p1 = (point) tetptr[5];
       p2 = (point) tetptr[4];
     }
@@ -1059,9 +1064,10 @@ void tetgenmesh::outmesh2medit(const char* mfilename)
     fprintf(outfile, "%5d  %5d  %5d  %5d",
             pointmark(p1)+shift, pointmark(p2)+shift,
             pointmark(p3)+shift, pointmark(p4)+shift);
-    if (numelemattrib > 0) {
+    if(numelemattrib > 0){
       fprintf(outfile, "  %.17g", elemattribute(tetptr, 0));
-    } else {
+    }
+    else{
       fprintf(outfile, "  0");
     }
     fprintf(outfile, "\n");
@@ -1078,7 +1084,7 @@ void tetgenmesh::outmesh2medit(const char* mfilename)
 
   subfaces->traversalinit();
   sface.sh = shellfacetraverse(subfaces);
-  while (sface.sh != NULL) {
+  while (sface.sh != NULL){
     p1 =  sorg(sface);
     p2 = sdest(sface);
     p3 = sapex(sface);
@@ -1109,6 +1115,39 @@ bool meshGRegionBoundaryRecovery(GRegion *gr)
       ret = false;
     }
     else if(err == 3){
+      std::map<int, MVertex *> all;
+      std::list<GFace*> f = gr->faces();
+      for(std::list<GFace*>::iterator it = f.begin(); it != f.end(); ++it){
+        GFace *gf = *it;
+        for(unsigned int i = 0; i < gf->triangles.size(); i++){
+          for(int j = 0; j < 3; j++){
+            MVertex *v = gf->triangles[i]->getVertex(j);
+            all[v->getIndex()] = v;
+          }
+        }
+      }
+      std::list<GEdge*> e = gr->embeddedEdges();
+      for(std::list<GEdge*>::iterator it = e.begin(); it != e.end(); ++it){
+        GEdge *ge = *it;
+        for(unsigned int i = 0; i < ge->lines.size(); i++){
+          for(int j = 0; j < 2; j++){
+            MVertex *v = ge->lines[i]->getVertex(j);
+            all[v->getIndex()] = v;
+          }
+        }
+      }
+      std::list<GVertex*> v = gr->embeddedVertices();
+      for(std::list<GVertex*>::iterator it = v.begin(); it != v.end(); ++it){
+        GVertex *gv = *it;
+        for(unsigned int i = 0; i < gv->points.size(); i++){
+          MVertex *v = gv->points[i]->getVertex(0);
+          all[v->getIndex()] = v;
+        }
+      }
+      for(unsigned int i = 0; i < gr->mesh_vertices.size(); i++){
+        MVertex *v = gr->mesh_vertices[i];
+        all[v->getIndex()] = v;
+      }
       std::string what;
       bool pnt = true;
       switch(tetgenBR::sevent.e_type){
@@ -1148,15 +1187,13 @@ bool meshGRegionBoundaryRecovery(GRegion *gr)
           }
         }
         for(int i = 0; i < 3; i++){
-          if(vtags[f][i]){
-            MVertex *v = gr->model()->getMeshVertexByTag(vtags[f][i]);
-            if(v){
-              gr->model()->addLastMeshVertexError(v);
-              x.push_back(v->x());
-              y.push_back(v->y());
-              z.push_back(v->z());
-              val.push_back(f + 1.);
-            }
+          MVertex *v = all[vtags[f][i]];
+          if(v){
+            gr->model()->addLastMeshVertexError(v);
+            x.push_back(v->x());
+            y.push_back(v->y());
+            z.push_back(v->z());
+            val.push_back(f + 1.);
           }
         }
       }
diff --git a/Mesh/qualityMeasuresJacobian.cpp b/Mesh/qualityMeasuresJacobian.cpp
index 2742a079780a064ee168a0c08c8d679246bf85de..b73bdc3a22b7692e7883df92e01c58ecc0141182 100644
--- a/Mesh/qualityMeasuresJacobian.cpp
+++ b/Mesh/qualityMeasuresJacobian.cpp
@@ -48,29 +48,27 @@ static inline void computeCoeffLengthVectors_(const fullMatrix<double> &mat,
                               pow_int(mat(i, 4), 2) +
                               pow_int(mat(i, 5), 2)  );
     }
-    if (mat.size2() > 6) { // if 3D
+    if (type == TYPE_TRI) {
+      for (int i = 0; i < sz1; i++) {
+        coeff(i, 2) = std::sqrt(pow_int(mat(i, 3) - mat(i, 0), 2) +
+                                pow_int(mat(i, 4) - mat(i, 1), 2) +
+                                pow_int(mat(i, 5) - mat(i, 2), 2)  );
+      }
+    }
+    else if (type != TYPE_QUA) { // if 3D
       for (int i = 0; i < sz1; i++) {
         coeff(i, 2) = std::sqrt(pow_int(mat(i, 6), 2) +
                                 pow_int(mat(i, 7), 2) +
                                 pow_int(mat(i, 8), 2)  );
       }
     }
-    else if (type == TYPE_TRI) {
+    if (type == TYPE_TET || type == TYPE_PRI) {
       for (int i = 0; i < sz1; i++) {
-        coeff(i, 2) = std::sqrt(pow_int(mat(i, 3) - mat(i, 0), 2) +
+        coeff(i, 3) = std::sqrt(pow_int(mat(i, 3) - mat(i, 0), 2) +
                                 pow_int(mat(i, 4) - mat(i, 1), 2) +
                                 pow_int(mat(i, 5) - mat(i, 2), 2)  );
       }
     }
-    switch (type) {
-      case TYPE_TET:
-      case TYPE_PRI:
-        for (int i = 0; i < sz1; i++) {
-          coeff(i, 3) = std::sqrt(pow_int(mat(i, 3) - mat(i, 0), 2) +
-                                  pow_int(mat(i, 4) - mat(i, 1), 2) +
-                                  pow_int(mat(i, 5) - mat(i, 2), 2)  );
-        }
-    }
     if (type == TYPE_TET) {
       for (int i = 0; i < sz1; i++) {
         coeff(i, 4) = std::sqrt(pow_int(mat(i, 6) - mat(i, 0), 2) +
diff --git a/Numeric/ElementType.cpp b/Numeric/ElementType.cpp
index b5e69bb1dbc01a39fda342b9809bce9d3cffe03b..66756f30c1aeb5cdfb3b4dc7837bb858b0ca72b1 100644
--- a/Numeric/ElementType.cpp
+++ b/Numeric/ElementType.cpp
@@ -325,7 +325,7 @@ int ElementType::DimensionFromTag(int tag)
     case(MSH_HEX_92):   case(MSH_HEX_104):
 
     case(MSH_TRIH_4):
-      
+
     case(MSH_POLYH_):
       return 3;
 
@@ -400,7 +400,7 @@ int ElementType::SerendipityFromTag(int tag)
   case MSH_PYR_285 : case MSH_PYR_385 :
 
   case MSH_TRIH_4 :
-    
+
     return 0; // Not Serendipity
 
 
@@ -563,6 +563,7 @@ int ElementType::getTag(int parentTag, int order, bool serendip)
   }
 }
 
-int ElementType::getPrimaryTag(int tag) {
+int ElementType::getPrimaryTag(int tag)
+{
   return getTag(ParentTypeFromTag(tag), 1);
 }
diff --git a/Numeric/ElementType.h b/Numeric/ElementType.h
index 0ecd1d51d316a6c3608325be43823b0283bc3be1..08463d981d4d5ad552fc2b2ece5f92e1a687d013 100644
--- a/Numeric/ElementType.h
+++ b/Numeric/ElementType.h
@@ -8,8 +8,7 @@
 
 namespace ElementType
 {
-  // Give parent type, order & dimension
-  // corresponding to any element type.
+  // Give parent type, order & dimension corresponding to any element type.
   int ParentTypeFromTag(int tag);
   int OrderFromTag(int tag);
   int DimensionFromTag(int tag);
diff --git a/contrib/HighOrderMeshOptimizer/BoundaryLayerCurver.h b/contrib/HighOrderMeshOptimizer/BoundaryLayerCurver.h
index aabcec0ba89a11233af06dfbfa034ef76502a874..3ec7e9ea0c969d47c072e340eb35387c3cf27c61 100644
--- a/contrib/HighOrderMeshOptimizer/BoundaryLayerCurver.h
+++ b/contrib/HighOrderMeshOptimizer/BoundaryLayerCurver.h
@@ -31,6 +31,7 @@
 #define _BOUNDARYLAYERCURVER_H_
 
 //#include <map>
+#include <algorithm>
 #include <list>
 
 #include "MEdge.h"
diff --git a/contrib/HighOrderMeshOptimizer/MetaEl.cpp b/contrib/HighOrderMeshOptimizer/MetaEl.cpp
index a180ff5e05d2f2d2708ab83233a700c11fcb5ff4..47645e02e5e65b286e327d53073864f466836b70 100644
--- a/contrib/HighOrderMeshOptimizer/MetaEl.cpp
+++ b/contrib/HighOrderMeshOptimizer/MetaEl.cpp
@@ -95,8 +95,8 @@ MetaEl::metaInfoType::metaInfoType(int type, int order)
   linBaseFaceBasis = BasisFactory::getNodalBasis(linBaseFaceTag);
   const int nbLinBaseShapeFunc = linBaseFaceBasis->getNumShapeFunctions();
   baseLinShapeFuncVal.resize(nbBaseVert, nbLinBaseShapeFunc);
-  
-  // Compute value of nodal bases of base face at base vertices 
+
+  // Compute value of nodal bases of base face at base vertices
   const fullMatrix<double> basePoints = baseFaceBasis->getReferenceNodes();
   for (int iV = 0; iV < baseFaceBasis->getNumShapeFunctions(); iV++) {
     const double &u = basePoints(iV, 0), &v = basePoints(iV, 1);
@@ -211,7 +211,7 @@ void MetaEl::computeBaseNorm(const SVector3 &metaNorm,
       MVertex *vert = baseVert[iSF];
       const double xyz[3] = {vert->x(), vert->y(), vert->z()};
       for (int iXYZ = 0; iXYZ < 3; iXYZ++) {
-        jac[iXYZ][0] += xyz[iXYZ] * _mInfo.baseGradShapeFuncVal(iV, 3*iSF); 
+        jac[iXYZ][0] += xyz[iXYZ] * _mInfo.baseGradShapeFuncVal(iV, 3*iSF);
         jac[iXYZ][1] += xyz[iXYZ] * _mInfo.baseGradShapeFuncVal(iV, 3*iSF+1);
       }
     }
@@ -256,7 +256,7 @@ MetaEl::MetaEl(int type, int order, const std::vector<MVertex*> &baseVert,
       double u, v;
       bVert->getParameter(0, u);
       bVert->getParameter(1, v);
-      _metaVert[baseInd[iV]] = new MEdgeVertex(bVert->x(), bVert->y(),
+      _metaVert[baseInd[iV]] = new MFaceVertex(bVert->x(), bVert->y(),
                                                bVert->z(), geomEnt, u, v);
     }
   }
diff --git a/demos/api/boolean.cpp b/demos/api/boolean.cpp
index 0cb8a9f97ce5a9602ab16457b0c2b95ae28eaa83..22eb6800eb76f1bdcb406e579f8f9e1158457e2b 100644
--- a/demos/api/boolean.cpp
+++ b/demos/api/boolean.cpp
@@ -19,14 +19,14 @@ int main(int argc, char **argv)
 
   std::vector<std::pair<int, int> > ov;
   std::vector<std::vector<std::pair<int, int> > > ovv;
-  gmshModelOccAddBox(1, -R,-R,-R, 2*R,2*R,2*R);
-  gmshModelOccAddSphere(2, 0,0,0,Rt);
-  gmshModelOccBooleanIntersection(3, {{3, 1}}, {{3, 2}}, ov, ovv);
-  gmshModelOccAddCylinder(4, -2*R,0,0, 4*R,0,0, Rs);
-  gmshModelOccAddCylinder(5, 0,-2*R,0, 0,4*R,0, Rs);
-  gmshModelOccAddCylinder(6, 0,0,-2*R, 0,0,4*R, Rs);
-  gmshModelOccBooleanUnion(7, {{3, 4}, {3, 5}}, {{3, 6}}, ov, ovv);
-  gmshModelOccBooleanDifference(8, {{3, 3}}, {{3, 7}}, ov, ovv);
+  gmshModelOccAddBox(-R,-R,-R, 2*R,2*R,2*R, 1);
+  gmshModelOccAddSphere(0,0,0,Rt, 2);
+  gmshModelOccBooleanIntersection({{3, 1}}, {{3, 2}}, ov, ovv, 3);
+  gmshModelOccAddCylinder(-2*R,0,0, 4*R,0,0, Rs, 4);
+  gmshModelOccAddCylinder(0,-2*R,0, 0,4*R,0, Rs, 5);
+  gmshModelOccAddCylinder(0,0,-2*R, 0,0,4*R, Rs, 6);
+  gmshModelOccBooleanUnion({{3, 4}, {3, 5}}, {{3, 6}}, ov, ovv, 7);
+  gmshModelOccBooleanDifference({{3, 3}}, {{3, 7}}, ov, ovv, 8);
 
   gmshModelOccSynchronize();
 
diff --git a/demos/api/boolean.py b/demos/api/boolean.py
index 8af1ff278ccb3495e8bc1fec5602884d1d71a12a..9bbfbf1a1a3b257e636bb5d8dee8a4fad9a51bb1 100644
--- a/demos/api/boolean.py
+++ b/demos/api/boolean.py
@@ -19,14 +19,14 @@ R = 1.4; Rs = R*.7; Rt = R*1.25
 
 ov = PairVector(); ovv = PairVectorVector()
 
-gmshModelOccAddBox(1, -R,-R,-R, 2*R,2*R,2*R)
-gmshModelOccAddSphere(2, 0,0,0,Rt)
-gmshModelOccBooleanIntersection(3, [(3, 1)], [(3, 2)], ov, ovv)
-gmshModelOccAddCylinder(4, -2*R,0,0, 4*R,0,0, Rs)
-gmshModelOccAddCylinder(5, 0,-2*R,0, 0,4*R,0, Rs)
-gmshModelOccAddCylinder(6, 0,0,-2*R, 0,0,4*R, Rs)
-gmshModelOccBooleanUnion(7, [(3, 4), (3, 5)], [(3, 6)], ov, ovv)
-gmshModelOccBooleanDifference(8, [(3, 3)], [(3, 7)], ov, ovv)
+gmshModelOccAddBox(-R,-R,-R, 2*R,2*R,2*R, 1)
+gmshModelOccAddSphere(0,0,0,Rt, 2)
+gmshModelOccBooleanIntersection([(3, 1)], [(3, 2)], ov, ovv, 3)
+gmshModelOccAddCylinder(-2*R,0,0, 4*R,0,0, Rs, 4)
+gmshModelOccAddCylinder(0,-2*R,0, 0,4*R,0, Rs, 5)
+gmshModelOccAddCylinder(0,0,-2*R, 0,0,4*R, Rs, 6)
+gmshModelOccBooleanUnion([(3, 4), (3, 5)], [(3, 6)], ov, ovv, 7)
+gmshModelOccBooleanDifference([(3, 3)], [(3, 7)], ov, ovv, 8)
 
 gmshModelOccSynchronize();
 
diff --git a/demos/api/discrete.cpp b/demos/api/discrete.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..25753dde17508bbbe60dc5107d2b1faa82b054dd
--- /dev/null
+++ b/demos/api/discrete.cpp
@@ -0,0 +1,33 @@
+#include <gmsh.h>
+
+int main(int argc, char **argv)
+{
+  gmshInitialize(argc, argv);
+  gmshOptionSetNumber("General.Terminal", 1);
+
+  gmshModelCreate("test");
+
+  // add discrete surface with tag 1
+  gmshModelAddDiscreteEntity(2, 1);
+
+  // add 4 mesh vertices
+  gmshModelSetMeshVertices(2, 1,
+                           {1, 2, 3, 4}, // vertex tags: 1, 2, 3, and 4
+                           {0., 0., 0., // coordinates of vertex 1
+                            1., 0., 0., // coordinates of vertex 2
+                            1., 1., 0., // ...
+                            0., 1., 0.});
+
+  // add 2 triangles
+  gmshModelSetMeshElements(2, 1,
+                           {2}, // single type : 3-node triangle
+                           {{1, 2}}, // triangle tags: 1 and 2
+                           {{1, 2, 3, // triangle 1: vertices 1, 2, 3
+                             1, 3, 4}}); // triangle 2: vertices 1, 3, 4
+
+  // export the mesh ; use explore.cpp to read and examine the mesh
+  gmshExport("test.msh");
+
+  gmshFinalize();
+  return 0;
+}
diff --git a/demos/api/discrete.py b/demos/api/discrete.py
new file mode 100644
index 0000000000000000000000000000000000000000..2bb70a03dd267a509c9560063a94a569da886fc4
--- /dev/null
+++ b/demos/api/discrete.py
@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+
+from gmsh import *
+import sys
+
+gmshInitialize(sys.argv)
+gmshOptionSetNumber("General.Terminal", 1)
+
+gmshModelCreate("test");
+
+# add discrete surface with tag 1
+gmshModelAddDiscreteEntity(2, 1)
+
+# add 4 mesh vertices
+gmshModelSetMeshVertices(2, 1,
+                         [1, 2, 3, 4], # vertex tags: 1, 2, 3, and 4
+                         [0., 0., 0., # coordinates of vertex 1
+                          1., 0., 0., # coordinates of vertex 2
+                          1., 1., 0., # ...
+                          0., 1., 0.])
+
+# add 2 triangles
+gmshModelSetMeshElements(2, 1,
+                         [2], # single type : 3-node triangle
+                         [[1, 2]], # triangle tags: 1 and 2
+                         [[1, 2, 3, # triangle 1: vertices 1, 2, 3
+                           1, 3, 4]]); # triangle 2: vertices 1, 3, 4
+
+# export the mesh ; use explore.py to read and examine the mesh
+gmshExport("test.msh")
+
+gmshFinalize()
+
diff --git a/demos/api/explore.cpp b/demos/api/explore.cpp
index 6b068c895e3bc02419173465ca7ac24c5f6a308a..6933ec3bfa5318da3918501379afec3fe4cb4a6a 100644
--- a/demos/api/explore.cpp
+++ b/demos/api/explore.cpp
@@ -4,14 +4,13 @@
 int main(int argc, char **argv)
 {
   if(argc < 2){
-    std::cout << "Usage: " << argv[0] << " file.geo [options]" << std::endl;
+    std::cout << "Usage: " << argv[0] << " file.msh [options]" << std::endl;
     return 1;
   }
 
   gmshInitialize();
   gmshOptionSetNumber("General.Terminal", 1);
   gmshOpen(argv[1]);
-  gmshModelMesh(3);
 
   // get all elementary entities in the model
   std::vector<std::pair<int, int> > entities;
@@ -21,9 +20,9 @@ int main(int argc, char **argv)
 
     // get the mesh vertices for each elementary entity
     std::vector<int> vertexTags;
-    std::vector<double> vertexCoords;
+    std::vector<double> vertexCoords, vertexParams;
     int dim = entities[i].first, tag = entities[i].second;
-    gmshModelGetMeshVertices(dim, tag, vertexTags, vertexCoords);
+    gmshModelGetMeshVertices(dim, tag, vertexTags, vertexCoords, vertexParams);
 
     // get the mesh elements for each elementary entity
     std::vector<int> elemTypes;
diff --git a/demos/api/explore.py b/demos/api/explore.py
index 5bec30b80c2702f1d1f7ba55f95d4795d5a7b89f..77059ac4a2ca26deb23983d3f8f731a50221738f 100644
--- a/demos/api/explore.py
+++ b/demos/api/explore.py
@@ -4,13 +4,12 @@ from gmsh import *
 import sys
 
 if len(sys.argv) < 2:
-    print "Usage: basic.py file.geo [options]"
+    print "Usage: " + sys.argv[0] + " file.msh [options]"
     exit(0)
 
 gmshInitialize()
 gmshOptionSetNumber("General.Terminal", 1)
 gmshOpen(sys.argv[1])
-gmshModelMesh(3)
 
 # get all elementary entities in the model
 entities = PairVector()
@@ -19,8 +18,8 @@ gmshModelGetEntities(entities)
 for e in entities:
     # get the mesh vertices for each elementary entity
     vertexTags = IntVector()
-    vertexCoords = DoubleVector()
-    gmshModelGetMeshVertices(e[0], e[1], vertexTags, vertexCoords)
+    vertexCoords = DoubleVector(); vertexParams = DoubleVector()
+    gmshModelGetMeshVertices(e[0], e[1], vertexTags, vertexCoords, vertexParams)
     # get the mesh elements for each elementary entity
     elemTypes = IntVector()
     elemTags = IntVectorVector(); elemVertexTags = IntVectorVector()
diff --git a/demos/api/open.py b/demos/api/open.py
index 968d905f784f3813c7f43e6a05eda0bcf434eda3..4f09a068f2c47915a3805fc20f7b594f64880627 100644
--- a/demos/api/open.py
+++ b/demos/api/open.py
@@ -4,7 +4,7 @@ from gmsh import *
 import sys
 
 if len(sys.argv) < 2:
-    print "Usage: basic.py file.geo [options]"
+    print "Usage: " + sys.argv[0] + " file.geo [options]"
     exit(0)
 
 gmshInitialize()
diff --git a/demos/api/t1.cpp b/demos/api/t1.cpp
index 522b7ee2f45081b70e78dec6c8569ab8616f93fd..dbecc7040a554a4912150798b7e70894451ff975 100644
--- a/demos/api/t1.cpp
+++ b/demos/api/t1.cpp
@@ -1,17 +1,15 @@
-// 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 focus on the specifics of the C++
-// API.
+// 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 focus on the
+// specifics of the C++ API.
 
 // The Gmsh API is entirely defined in the <gmsh.h> header:
 #include <gmsh.h>
 
 int main(int argc, char **argv)
 {
-  // Before using any functions in the C++ API, Gmsh must be initialized. All
-  // the functions in the API return a vector of integers. The first integer is
-  // 0 on successful completion; additional integers can be appended depending
-  // on context.
+  // Before using any functions in the C++ API, Gmsh must be initialized.
   gmshInitialize();
 
   // By default Gmsh will not print out any messages: in order to output
@@ -29,35 +27,37 @@ int main(int argc, char **argv)
   // have the "gmshModeGeo" prefix. To create geometrical points with the
   // built-in CAD kernel, one thus uses gmshModelGeoAddPoint():
   //
-  // - the first argument is the point tag
+  // - the first 3 arguments are the point coordinates (x, y, z)
   //
-  // - the next 3 arguments are the point coordinates (x, y, z)
+  // - the next (optional) argument is the target mesh size close to the point
   //
-  // - the last (optional) argument is the target mesh size close to the point
+  // - the last (optional) argument is the point tag
   double 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);
+  gmshModelGeoAddPoint(0, 0, 0, lc, 1);
+  gmshModelGeoAddPoint(.1, 0,  0, lc, 2);
+  gmshModelGeoAddPoint(.1, .3, 0, lc, 3);
+  gmshModelGeoAddPoint(0,  .3, 0, lc, 4);
 
   // The API to create lines with the built-in kernel follows the same
-  // conventions: the first argument is the line tag, followed by 2 point tags.
-  gmshModelGeoAddLine(1, 1, 2);
-  gmshModelGeoAddLine(2, 3, 2);
-  gmshModelGeoAddLine(3, 3, 4);
-  gmshModelGeoAddLine(4, 4, 1);
+  // conventions: the first 2 arguments are point tags, the last (optional one)
+  // is the line tag.
+  gmshModelGeoAddLine(1, 2, 1);
+  gmshModelGeoAddLine(3, 2, 2);
+  gmshModelGeoAddLine(3, 4, 3);
+  gmshModelGeoAddLine(4, 1, 4);
 
-  // The philosophy to construct line loops and surfaces is similar: the second
-  // arguments are now vectors of integers.
-  gmshModelGeoAddLineLoop(1, {4, 1, -2, 3});
-  gmshModelGeoAddPlaneSurface(1, {1});
+  // The philosophy to construct line loops and surfaces is similar: the first
+  // argument is now a vector of integers.
+  gmshModelGeoAddLineLoop({4, 1, -2, 3}, 1);
+  gmshModelGeoAddPlaneSurface({1}, 1);
 
   // Physical groups are defined by providing the dimension of the group (0 for
   // physical points, 1 for physical lines, 2 for physical surfaces and 3 for
-  // phsyical volumes) and its tag, followed by a vector of entity tags.
-  gmshModelAddPhysicalGroup(0, 1, {1, 2});
-  gmshModelAddPhysicalGroup(1, 2, {1, 2});
-  gmshModelAddPhysicalGroup(2, 6, {1});
+  // phsyical volumes) followed by a vector of entity tags. The last (optional)
+  // argument is the tag of the new group to create.
+  gmshModelAddPhysicalGroup(0, {1, 2}, 1);
+  gmshModelAddPhysicalGroup(1, {1, 2}, 2);
+  gmshModelAddPhysicalGroup(2, {1}, 6);
 
   // Physical names are also defined by providing the dimension and tag of the
   // entity.
diff --git a/demos/api/t1.py b/demos/api/t1.py
index 532a0d8899108df441c17e7f93eaa1a0f7fda18d..83d4fc447232ffcc1b949c52aeda7fdea900e53b 100644
--- a/demos/api/t1.py
+++ b/demos/api/t1.py
@@ -1,14 +1,15 @@
 #!/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 focus on the specifics of the Python API.
+# 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 focus on the specifics
+# of the Python API.
 
 # The API is entirely defined in the gmsh module
 from gmsh import *
 
-# Before using any functions in the Python API, Gmsh must be initialized.  All
-# the function in the API return 0 on successful completion.
+# Before using any functions in the Python API, Gmsh must be initialized.
 gmshInitialize()
 
 # By default Gmsh will not print out any messages: in order to output messages
@@ -20,45 +21,42 @@ gmshOptionSetNumber("General.Terminal", 1)
 # new default (unnamed) model will be created on the fly, if necessary.
 gmshModelCreate("t1")
 
-# The C++ API provides direct access to the internal CAD kernels. The built-in
-# CAD kernel was used in t1.geo: the corresponding API functions have the
-# "gmshModeGeo" prefix. To create geometrical points with the built-in CAD
+# The Python API provides direct access to the internal CAD kernels. The
+# built-in CAD kernel was used in t1.geo: the corresponding API functions have
+# the "gmshModeGeo" prefix. To create geometrical points with the built-in CAD
 # kernel, one thus uses gmshModelGeoAddPoint():
 #
-# - the first argument is the point tag; if positive, the point is created with
-#   this tag; if negative, a new (unused) tag will be assigned and returned as
-#   the second value after the return code, i.e. gmshModelGeoAddPoint(3, .1, .3,
-#   0, lc) will return [0 3]
+# - the first 3 arguments are the point coordinates (x, y, z)
 #
-# - the next 3 arguments are the point coordinates (x, y, z)
+# - the next (optional) argument is the target mesh size close to the point
 #
-# - the last (optional) argument is the target mesh size close to the point
-
+# - the last (optional) argument is the point tag
 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)
+gmshModelGeoAddPoint(0, 0, 0, lc, 1)
+gmshModelGeoAddPoint(.1, 0,  0, lc, 2)
+gmshModelGeoAddPoint(.1, .3, 0, lc, 3)
+gmshModelGeoAddPoint(0, .3, 0, lc, 4)
 
-# The API to create lines with the built-in kernel follows the same conventions:
-# the first argument is a tag (here positive to force it), followed by 2 point
-# tags, followed by the actual (returned) tag.
-gmshModelGeoAddLine(1, 1, 2)
-gmshModelGeoAddLine(2, 3, 2)
-gmshModelGeoAddLine(3, 3, 4)
-gmshModelGeoAddLine(4, 4, 1)
+# The API to create lines with the built-in kernel follows the same
+# conventions: the first 2 arguments are point tags, the last (optional one)
+# is the line tag.
+gmshModelGeoAddLine(1, 2, 1)
+gmshModelGeoAddLine(3, 2, 2)
+gmshModelGeoAddLine(3, 4, 3)
+gmshModelGeoAddLine(4, 1, 4)
 
-# The philosophy to construct line loops and surfaces is similar: the second
-# arguments are now vectors of integers.
-gmshModelGeoAddLineLoop(1, [4, 1, -2, 3])
-gmshModelGeoAddPlaneSurface(1, [1])
+# The philosophy to construct line loops and surfaces is similar: the first
+# argument is now a vector of integers.
+gmshModelGeoAddLineLoop([4, 1, -2, 3], 1)
+gmshModelGeoAddPlaneSurface([1], 1)
 
 # Physical groups are defined by providing the dimension of the group (0 for
 # physical points, 1 for physical lines, 2 for physical surfaces and 3 for
-# phsyical volumes) and its tag, followed by a vector of entity tags.
-gmshModelAddPhysicalGroup(0, 1, [1, 2])
-gmshModelAddPhysicalGroup(1, 2, [1, 2])
-gmshModelAddPhysicalGroup(2, 6, [1])
+# phsyical volumes) followed by a vector of entity tags. The last (optional)
+# argument is the tag of the new group to create.
+gmshModelAddPhysicalGroup(0, [1, 2], 1)
+gmshModelAddPhysicalGroup(1, [1, 2], 2)
+gmshModelAddPhysicalGroup(2, [1], 6)
 
 # Physical names are also defined by providing the dimension and tag of the
 # entity.
diff --git a/demos/api/t10.cpp b/demos/api/t10.cpp
index dfe51c67cdc77e0fa08982d33b343bf486aa04a8..517a20225e4c4a41850354ac568019e453119ef1 100644
--- a/demos/api/t10.cpp
+++ b/demos/api/t10.cpp
@@ -11,44 +11,44 @@ int main(int argc, char **argv)
   gmshModelCreate("t1");
 
   double lc = .15;
-  gmshModelGeoAddPoint(1, 0.0,0.0,0,lc);
-  gmshModelGeoAddPoint(2, 1,0.0,0,lc);
-  gmshModelGeoAddPoint(3, 1,1,0,lc);
-  gmshModelGeoAddPoint(4, 0,1,0,lc);
-  gmshModelGeoAddPoint(5, 0.2,.5,0,lc);
+  gmshModelGeoAddPoint(0.0,0.0,0,lc, 1);
+  gmshModelGeoAddPoint(1,0.0,0,lc, 2);
+  gmshModelGeoAddPoint(1,1,0,lc, 3);
+  gmshModelGeoAddPoint(0,1,0,lc, 4);
+  gmshModelGeoAddPoint(0.2,.5,0,lc, 5);
 
-  gmshModelGeoAddLine(1, 1,2);
-  gmshModelGeoAddLine(2, 2,3);
-  gmshModelGeoAddLine(3, 3,4);
-  gmshModelGeoAddLine(4, 4,1);
+  gmshModelGeoAddLine(1,2, 1);
+  gmshModelGeoAddLine(2,3, 2);
+  gmshModelGeoAddLine(3,4, 3);
+  gmshModelGeoAddLine(4,1, 4);
 
-  gmshModelGeoAddLineLoop(5, {1,2,3,4});
-  gmshModelGeoAddPlaneSurface(6, {5});
+  gmshModelGeoAddLineLoop({1,2,3,4}, 5);
+  gmshModelGeoAddPlaneSurface({5}, 6);
 
-  gmshModelFieldCreate(1, "Attractor");
+  gmshModelFieldCreate("Attractor", 1);
   gmshModelFieldSetNumbers(1, "NodesList", {5});
   gmshModelFieldSetNumber(1, "NNodesByEdge", 100);
   gmshModelFieldSetNumbers(1, "EdgesList", {2});
 
-  gmshModelFieldCreate(2, "Threshold");
+  gmshModelFieldCreate("Threshold", 2);
   gmshModelFieldSetNumber(2, "IField", 1);
   gmshModelFieldSetNumber(2, "LcMin", lc / 30);
   gmshModelFieldSetNumber(2, "LcMax", lc);
   gmshModelFieldSetNumber(2, "DistMin", 0.15);
   gmshModelFieldSetNumber(2, "DistMax", 0.5);
 
-  gmshModelFieldCreate(3, "MathEval");
+  gmshModelFieldCreate("MathEval", 3);
   gmshModelFieldSetString(3, "F", "Cos(4*3.14*x) * Sin(4*3.14*y) / 10 + 0.101");
 
-  gmshModelFieldCreate(4, "Attractor");
+  gmshModelFieldCreate("Attractor", 4);
   gmshModelFieldSetNumbers(4, "NodesList", {1});
 
-  gmshModelFieldCreate(5, "MathEval");
+  gmshModelFieldCreate("MathEval", 5);
   std::stringstream stream;
   stream << "F4^3 + " << lc / 100;
   gmshModelFieldSetString(5, "F", stream.str());
 
-  gmshModelFieldCreate(6, "Box");
+  gmshModelFieldCreate("Box", 6);
   gmshModelFieldSetNumber(6, "VIn", lc / 15);
   gmshModelFieldSetNumber(6, "VOut", lc);
   gmshModelFieldSetNumber(6, "XMin", 0.3);
@@ -56,7 +56,7 @@ int main(int argc, char **argv)
   gmshModelFieldSetNumber(6, "YMin", 0.3);
   gmshModelFieldSetNumber(6, "YMax", 0.6);
 
-  gmshModelFieldCreate(7, "Min");
+  gmshModelFieldCreate("Min", 7);
   gmshModelFieldSetNumbers(7, "FieldsList", {2, 3, 5, 6});
 
   gmshModelFieldSetAsBackground(7);
diff --git a/demos/api/t10.py b/demos/api/t10.py
index 7764f06d389824864feece32fda8440912de97ef..5514bf0a8e8829e0989fc52be23280ad4b8b2c90 100644
--- a/demos/api/t10.py
+++ b/demos/api/t10.py
@@ -11,43 +11,42 @@ gmshOptionSetNumber("General.Terminal", 1)
 gmshModelCreate("t10")
 
 lc = .15
-gmshModelGeoAddPoint(1, 0.0,0.0,0, lc)
-gmshModelGeoAddPoint(2, 1,0.0,0, lc)
-gmshModelGeoAddPoint(3, 1,1,0, lc)
-gmshModelGeoAddPoint(4, 0,1,0, lc)
-gmshModelGeoAddPoint(5, 0.2,.5,0, lc)
+gmshModelGeoAddPoint(0.0,0.0,0, lc, 1)
+gmshModelGeoAddPoint(1,0.0,0, lc, 2)
+gmshModelGeoAddPoint(1,1,0, lc, 3)
+gmshModelGeoAddPoint(0,1,0, lc, 4)
+gmshModelGeoAddPoint(0.2,.5,0, lc, 5)
 
-gmshModelGeoAddLine(1, 1,2);
-gmshModelGeoAddLine(2, 2,3);
-gmshModelGeoAddLine(3, 3,4);
-gmshModelGeoAddLine(4, 4,1);
+gmshModelGeoAddLine(1,2, 1);
+gmshModelGeoAddLine(2,3, 2);
+gmshModelGeoAddLine(3,4, 3);
+gmshModelGeoAddLine(4,1, 4);
 
-gmshModelGeoAddLineLoop(5, [1,2,3,4])
-gmshModelGeoAddPlaneSurface(6, [5])
+gmshModelGeoAddLineLoop([1,2,3,4], 5)
+gmshModelGeoAddPlaneSurface([5], 6)
 
-gmshModelFieldCreate(1, "Attractor")
+gmshModelFieldCreate("Attractor", 1)
 gmshModelFieldSetNumbers(1, "NodesList", [5])
 gmshModelFieldSetNumber(1, "NNodesByEdge", 100)
 gmshModelFieldSetNumbers(1, "EdgesList", [2])
 
-gmshModelFieldCreate(2, "Threshold");
+gmshModelFieldCreate("Threshold", 2);
 gmshModelFieldSetNumber(2, "IField", 1);
 gmshModelFieldSetNumber(2, "LcMin", lc / 30)
 gmshModelFieldSetNumber(2, "LcMax", lc)
 gmshModelFieldSetNumber(2, "DistMin", 0.15)
 gmshModelFieldSetNumber(2, "DistMax", 0.5)
 
-gmshModelFieldCreate(3, "MathEval")
+gmshModelFieldCreate("MathEval", 3)
 gmshModelFieldSetString(3, "F", "Cos(4*3.14*x) * Sin(4*3.14*y) / 10 + 0.101")
 
-gmshModelFieldCreate(4, "Attractor")
+gmshModelFieldCreate("Attractor", 4)
 gmshModelFieldSetNumbers(4, "NodesList", [1])
 
-gmshModelFieldCreate(5, "MathEval");
-
+gmshModelFieldCreate("MathEval", 5);
 gmshModelFieldSetString(5, "F", "F4^3 + " + str(lc / 100))
 
-gmshModelFieldCreate(6, "Box")
+gmshModelFieldCreate("Box", 6)
 gmshModelFieldSetNumber(6, "VIn", lc / 15)
 gmshModelFieldSetNumber(6, "VOut", lc)
 gmshModelFieldSetNumber(6, "XMin", 0.3)
@@ -55,7 +54,7 @@ gmshModelFieldSetNumber(6, "XMax", 0.6)
 gmshModelFieldSetNumber(6, "YMin", 0.3)
 gmshModelFieldSetNumber(6, "YMax", 0.6)
 
-gmshModelFieldCreate(7, "Min")
+gmshModelFieldCreate("Min", 7)
 gmshModelFieldSetNumbers(7, "FieldsList", [2, 3, 5, 6])
 
 gmshModelFieldSetAsBackground(7)
diff --git a/demos/api/t16.cpp b/demos/api/t16.cpp
index 65d38a899999fa7a8c13fa03a388b1fe74498018..055e0e3d23527be147159b379392dcd861f2d8d4 100644
--- a/demos/api/t16.cpp
+++ b/demos/api/t16.cpp
@@ -11,18 +11,18 @@ int main(int argc, char **argv)
 
   std::vector<std::pair<int, int> > ov;
   std::vector<std::vector<std::pair<int, int> > > ovv;
-  gmshModelOccAddBox(1, 0,0,0, 1,1,1);
-  gmshModelOccAddBox(2, 0,0,0, 0.5,0.5,0.5);
-  gmshModelOccBooleanDifference(3, {{3,1}}, {{3,2}}, ov, ovv);
+  gmshModelOccAddBox(0,0,0, 1,1,1, 1);
+  gmshModelOccAddBox(0,0,0, 0.5,0.5,0.5, 2);
+  gmshModelOccBooleanDifference({{3,1}}, {{3,2}}, ov, ovv, 3);
   double x = 0, y = 0.75, z = 0, r = 0.09 ;
   std::vector<std::pair<int, int> > holes;
   for(int t = 1; t <= 5; t++){
     x += 0.166 ;
     z += 0.166 ;
-    gmshModelOccAddSphere(3 + t, x,y,z,r);
+    gmshModelOccAddSphere(x,y,z,r, 3 + t);
     holes.push_back({3, 3 + t});
   }
-  gmshModelOccBooleanFragments(-1, {{3,3}}, holes, ov, ovv);
+  gmshModelOccBooleanFragments({{3,3}}, holes, ov, ovv);
 
   gmshModelOccSynchronize();
 
diff --git a/demos/api/t16.py b/demos/api/t16.py
index 9187d99d007fd03f0160687a783d3e7e64a1deb6..3343f9e97827249d58a30876f21b1aa062e0e028 100644
--- a/demos/api/t16.py
+++ b/demos/api/t16.py
@@ -12,9 +12,9 @@ gmshModelCreate("t16")
 
 ov = PairVector(); ovv = PairVectorVector()
 
-gmshModelOccAddBox(1, 0,0,0, 1,1,1)
-gmshModelOccAddBox(2, 0,0,0, 0.5,0.5,0.5)
-gmshModelOccBooleanDifference(3,[(3,1)], [(3,2)], ov, ovv)
+gmshModelOccAddBox(0,0,0, 1,1,1, 1)
+gmshModelOccAddBox(0,0,0, 0.5,0.5,0.5, 2)
+gmshModelOccBooleanDifference([(3,1)], [(3,2)], ov, ovv, 3)
 
 x = 0; y = 0.75; z = 0; r = 0.09
 
@@ -22,10 +22,10 @@ holes = PairVector()
 for t in range(1, 6):
     x += 0.166
     z += 0.166
-    gmshModelOccAddSphere(3 + t, x,y,z,r)
+    gmshModelOccAddSphere(x,y,z,r, 3 + t)
     holes.append((3, 3 + t))
 
-gmshModelOccBooleanFragments(-1, [(3,3)], holes, ov, ovv)
+gmshModelOccBooleanFragments([(3,3)], holes, ov, ovv)
 
 gmshModelOccSynchronize()
 
diff --git a/demos/api/t2.cpp b/demos/api/t2.cpp
index b60e48a6cac0fdae6ff36dca1eae262a52dde482..85666ba8d5b7d5ccabffd87d2160edfcc951c7a2 100644
--- a/demos/api/t2.cpp
+++ b/demos/api/t2.cpp
@@ -14,26 +14,24 @@ int main(int argc, char **argv)
 
   // Copied from t1.cpp...
   double 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});
+  gmshModelGeoAddPoint(0, 0, 0, lc, 1);
+  gmshModelGeoAddPoint(.1, 0,  0, lc, 2);
+  gmshModelGeoAddPoint(.1, .3, 0, lc, 3);
+  gmshModelGeoAddPoint(0,  .3, 0, lc, 4);
+  gmshModelGeoAddLine(1, 2, 1);
+  gmshModelGeoAddLine(3, 2, 2);
+  gmshModelGeoAddLine(3, 4, 3);
+  gmshModelGeoAddLine(4, 1, 4);
+  gmshModelGeoAddLineLoop({4, 1, -2, 3}, 1);
+  gmshModelGeoAddPlaneSurface({1}, 1);
+  gmshModelAddPhysicalGroup(0, {1, 2}, 1);
+  gmshModelAddPhysicalGroup(1, {1, 2}, 2);
+  gmshModelAddPhysicalGroup(2, {1}, 6);
   gmshModelSetPhysicalName(2, 6, "My surface");
   // ...end of copy
 
-  gmshModelGeoAddPoint(5, 0, .4, 0, lc);
-  gmshModelGeoAddLine(5, 4, 5);
+  gmshModelGeoAddPoint(0, .4, 0, lc, 5);
+  gmshModelGeoAddLine(4, 5, 5);
 
   // Geometrical transformations take a vector of pairs of integers as first
   // argument, which contains the list of entities, represented by (dimension,
@@ -44,52 +42,53 @@ int main(int argc, char **argv)
   // The "Duplicata" functionality in .geo files is handled by
   // gmshModelGeoCopy(), which takes a vector of (dim, tag) pairs as input, and
   // returns another vector of (dim, tag) pairs.
-  std::vector<std::pair<int, int> > ov, ov2;
+  std::vector<std::pair<int, int> > ov;
   gmshModelGeoCopy({{0, 3}}, ov);
   gmshModelGeoTranslate(ov, 0, 0.1, 0);
 
-  gmshModelGeoAddLine(7, 3, ov[0].second);
-  gmshModelGeoAddLine(8, ov[0].second, 5);
-  gmshModelGeoAddLineLoop(10, {5,-8,-7,3});
-  gmshModelGeoAddPlaneSurface(11, {10});
+  gmshModelGeoAddLine(3, ov[0].second, 7);
+  gmshModelGeoAddLine(ov[0].second, 5, 8);
+  gmshModelGeoAddLineLoop({5,-8,-7,3}, 10);
+  gmshModelGeoAddPlaneSurface({10}, 11);
 
   gmshModelGeoCopy({{2, 1}, {2, 11}}, ov);
   gmshModelGeoTranslate(ov, 0.12, 0, 0);
 
   std::printf("New surfaces '%d' and '%d'\n", ov[0].second, ov[1].second);
 
-  gmshModelGeoAddPoint(100, 0., 0.3, 0.13, lc);
-  gmshModelGeoAddPoint(101, 0.08, 0.3, 0.1, lc);
-  gmshModelGeoAddPoint(102, 0.08, 0.4, 0.1, lc);
-  gmshModelGeoAddPoint(103, 0., 0.4, 0.13, lc);
-
-  gmshModelGeoAddLine(110, 4, 100);
-  gmshModelGeoAddLine(111, 3, 101);
-  gmshModelGeoAddLine(112, 6, 102);
-  gmshModelGeoAddLine(113, 5, 103);
-  gmshModelGeoAddLine(114, 103, 100);
-  gmshModelGeoAddLine(115, 100, 101);
-  gmshModelGeoAddLine(116, 101, 102);
-  gmshModelGeoAddLine(117, 102, 103);
-
-  gmshModelGeoAddLineLoop(118, {115, -111, 3, 110});
-  gmshModelGeoAddPlaneSurface(119, {118});
-  gmshModelGeoAddLineLoop(120, {111, 116, -112, -7});
-  gmshModelGeoAddPlaneSurface(121, {120});
-  gmshModelGeoAddLineLoop(122, {112, 117, -113, -8});
-  gmshModelGeoAddPlaneSurface(123, {122});
-  gmshModelGeoAddLineLoop(124, {114, -110, 5, 113});
-  gmshModelGeoAddPlaneSurface(125, {124});
-  gmshModelGeoAddLineLoop(126, {115, 116, 117, 114});
-  gmshModelGeoAddPlaneSurface(127, {126});
+  gmshModelGeoAddPoint(0., 0.3, 0.13, lc, 100);
+  gmshModelGeoAddPoint(0.08, 0.3, 0.1, lc, 101);
+  gmshModelGeoAddPoint(0.08, 0.4, 0.1, lc, 102);
+  gmshModelGeoAddPoint(0., 0.4, 0.13, lc, 103);
+
+  gmshModelGeoAddLine(4, 100, 110);
+  gmshModelGeoAddLine(3, 101, 111);
+  gmshModelGeoAddLine(6, 102, 112);
+  gmshModelGeoAddLine(5, 103, 113);
+  gmshModelGeoAddLine(103, 100, 114);
+  gmshModelGeoAddLine(100, 101, 115);
+  gmshModelGeoAddLine(101, 102, 116);
+  gmshModelGeoAddLine(102, 103, 117);
+
+  gmshModelGeoAddLineLoop({115, -111, 3, 110}, 118);
+  gmshModelGeoAddPlaneSurface({118}, 119);
+  gmshModelGeoAddLineLoop({111, 116, -112, -7}, 120);
+  gmshModelGeoAddPlaneSurface({120}, 121);
+  gmshModelGeoAddLineLoop({112, 117, -113, -8}, 122);
+  gmshModelGeoAddPlaneSurface({122}, 123);
+  gmshModelGeoAddLineLoop({114, -110, 5, 113}, 124);
+  gmshModelGeoAddPlaneSurface({124}, 125);
+  gmshModelGeoAddLineLoop({115, 116, 117, 114}, 126);
+  gmshModelGeoAddPlaneSurface({126}, 127);
 
   // The API to create surface loops ("shells") and volumes is similar to the
   // one used to create line loops and surfaces.
-  gmshModelGeoAddSurfaceLoop(128, {127, 119, 121, 123, 125, 11});
-  gmshModelGeoAddVolume(129, {128});
+  gmshModelGeoAddSurfaceLoop({127, 119, 121, 123, 125, 11}, 128);
+  gmshModelGeoAddVolume({128}, 129);
 
   // Extrusion works as expected, by providing a vector of (dim, tag) pairs as
   // input, the translation vector, and a vector of (dim, tag) pairs as output.
+  std::vector<std::pair<int, int> > ov2;
   gmshModelGeoExtrude({ov[1]}, 0, 0, 0.12, ov2);
 
   // Mesh sizes associated to geometrical points can be set by passing a vector
@@ -97,7 +96,7 @@ int main(int argc, char **argv)
   gmshModelGeoSetMeshSize({{0,103}, {0,105}, {0,109}, {0,102}, {0,28},
                            {0, 24}, {0,6}, {0,5}}, lc * 3);
 
-  gmshModelAddPhysicalGroup(3, 1, {129,130});
+  gmshModelAddPhysicalGroup(3, {129,130}, 1);
   gmshModelSetPhysicalName(3, 1, "The volume");
 
   gmshModelGeoSynchronize();
diff --git a/demos/api/t2.py b/demos/api/t2.py
index 1907f5cd53d145e7568d83b5acc83cb4aca6bdbb..1e6f9857ddc8e6dbb447165fb039827dfe3507f7 100644
--- a/demos/api/t2.py
+++ b/demos/api/t2.py
@@ -16,26 +16,24 @@ gmshModelCreate("t2")
 
 # 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])
+gmshModelGeoAddPoint(0, 0, 0, lc, 1)
+gmshModelGeoAddPoint(.1, 0,  0, lc, 2)
+gmshModelGeoAddPoint(.1, .3, 0, lc, 3)
+gmshModelGeoAddPoint(0, .3, 0, lc, 4)
+gmshModelGeoAddLine(1, 2, 1)
+gmshModelGeoAddLine(3, 2, 2)
+gmshModelGeoAddLine(3, 4, 3)
+gmshModelGeoAddLine(4, 1, 4)
+gmshModelGeoAddLineLoop([4, 1, -2, 3], 1)
+gmshModelGeoAddPlaneSurface([1], 1)
+gmshModelAddPhysicalGroup(0, [1, 2], 1)
+gmshModelAddPhysicalGroup(1, [1, 2], 2)
+gmshModelAddPhysicalGroup(2, [1], 6)
 gmshModelSetPhysicalName(2, 6, "My surface")
 # ...end of copy
 
-gmshModelGeoAddPoint(5, 0, .4, 0, lc)
-gmshModelGeoAddLine(5, 4, 5)
+gmshModelGeoAddPoint(0, .4, 0, lc, 5)
+gmshModelGeoAddLine(4, 5, 5)
 
 # Geometrical transformations take a vector of pairs of integers as first
 # argument, which contains the list of entities, represented by (dimension, tag)
@@ -51,45 +49,45 @@ ov = PairVector()
 gmshModelGeoCopy([(0, 3)], ov)
 gmshModelGeoTranslate(ov, 0, 0.1, 0)
 
-gmshModelGeoAddLine(7, 3, ov[0][1])
-gmshModelGeoAddLine(8, ov[0][1], 5)
-gmshModelGeoAddLineLoop(10, [5,-8,-7,3])
-gmshModelGeoAddPlaneSurface(11, [10])
+gmshModelGeoAddLine(3, ov[0][1], 7)
+gmshModelGeoAddLine(ov[0][1], 5, 8)
+gmshModelGeoAddLineLoop([5,-8,-7,3], 10)
+gmshModelGeoAddPlaneSurface([10], 11)
 
 gmshModelGeoCopy([(2, 1), (2, 11)], ov)
 gmshModelGeoTranslate(ov, 0.12, 0, 0)
 
 print "New surfaces " + str(ov[0][1]) + " and " + str(ov[1][1])
 
-gmshModelGeoAddPoint(100, 0., 0.3, 0.13, lc)
-gmshModelGeoAddPoint(101, 0.08, 0.3, 0.1, lc)
-gmshModelGeoAddPoint(102, 0.08, 0.4, 0.1, lc)
-gmshModelGeoAddPoint(103, 0., 0.4, 0.13, lc)
-
-gmshModelGeoAddLine(110, 4, 100)
-gmshModelGeoAddLine(111, 3, 101)
-gmshModelGeoAddLine(112, 6, 102)
-gmshModelGeoAddLine(113, 5, 103)
-gmshModelGeoAddLine(114, 103, 100)
-gmshModelGeoAddLine(115, 100, 101)
-gmshModelGeoAddLine(116, 101, 102)
-gmshModelGeoAddLine(117, 102, 103)
-
-gmshModelGeoAddLineLoop(118, [115, -111, 3, 110])
-gmshModelGeoAddPlaneSurface(119, [118])
-gmshModelGeoAddLineLoop(120, [111, 116, -112, -7])
-gmshModelGeoAddPlaneSurface(121, [120])
-gmshModelGeoAddLineLoop(122, [112, 117, -113, -8])
-gmshModelGeoAddPlaneSurface(123, [122])
-gmshModelGeoAddLineLoop(124, [114, -110, 5, 113])
-gmshModelGeoAddPlaneSurface(125, [124])
-gmshModelGeoAddLineLoop(126, [115, 116, 117, 114])
-gmshModelGeoAddPlaneSurface(127, [126])
+gmshModelGeoAddPoint(0., 0.3, 0.13, lc, 100)
+gmshModelGeoAddPoint(0.08, 0.3, 0.1, lc, 101)
+gmshModelGeoAddPoint(0.08, 0.4, 0.1, lc, 102)
+gmshModelGeoAddPoint(0., 0.4, 0.13, lc, 103)
+
+gmshModelGeoAddLine(4, 100, 110)
+gmshModelGeoAddLine(3, 101, 111)
+gmshModelGeoAddLine(6, 102, 112)
+gmshModelGeoAddLine(5, 103, 113)
+gmshModelGeoAddLine(103, 100, 114)
+gmshModelGeoAddLine(100, 101, 115)
+gmshModelGeoAddLine(101, 102, 116)
+gmshModelGeoAddLine(102, 103, 117)
+
+gmshModelGeoAddLineLoop([115, -111, 3, 110], 118)
+gmshModelGeoAddPlaneSurface([118], 119)
+gmshModelGeoAddLineLoop([111, 116, -112, -7], 120)
+gmshModelGeoAddPlaneSurface([120], 121)
+gmshModelGeoAddLineLoop([112, 117, -113, -8], 122)
+gmshModelGeoAddPlaneSurface([122], 123)
+gmshModelGeoAddLineLoop([114, -110, 5, 113], 124)
+gmshModelGeoAddPlaneSurface([124], 125)
+gmshModelGeoAddLineLoop([115, 116, 117, 114], 126)
+gmshModelGeoAddPlaneSurface([126], 127)
 
 # The API to create surface loops ("shells") and volumes is similar to the
 # one used to create line loops and surfaces.
-gmshModelGeoAddSurfaceLoop(128, [127, 119, 121, 123, 125, 11])
-gmshModelGeoAddVolume(129, [128])
+gmshModelGeoAddSurfaceLoop([127, 119, 121, 123, 125, 11], 128)
+gmshModelGeoAddVolume([128], 129)
 
 # Extrusion works as expected, by providing a vector of (dim, tag) pairs as
 # input, the translation vector, and a vector of (dim, tag) pairs as output.
@@ -102,7 +100,7 @@ gmshModelGeoExtrude([ov[1]], 0, 0, 0.12, ov2)
 gmshModelGeoSetMeshSize([(0,103), (0,105), (0,109), (0,102), (0,28),
                          (0, 24), (0,6), (0,5)], lc * 3)
 
-gmshModelAddPhysicalGroup(3, 1, [129,130])
+gmshModelAddPhysicalGroup(3, [129,130], 1)
 gmshModelSetPhysicalName(3, 1, "The volume")
 
 gmshModelGeoSynchronize()
diff --git a/demos/api/t3.cpp b/demos/api/t3.cpp
index 0c6518fb60c830e48fccfdf216ce0003554d202d..cf60d3ad810e4579639bb142cf02f974a9b2f780 100644
--- a/demos/api/t3.cpp
+++ b/demos/api/t3.cpp
@@ -12,26 +12,23 @@ int main(int argc, char **argv)
 
   // Copied from t1.cpp...
   double 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});
+  gmshModelGeoAddPoint(0, 0, 0, lc, 1);
+  gmshModelGeoAddPoint(.1, 0,  0, lc, 2);
+  gmshModelGeoAddPoint(.1, .3, 0, lc, 3);
+  gmshModelGeoAddPoint(0,  .3, 0, lc, 4);
+  gmshModelGeoAddLine(1, 2, 1);
+  gmshModelGeoAddLine(3, 2, 2);
+  gmshModelGeoAddLine(3, 4, 3);
+  gmshModelGeoAddLine(4, 1, 4);
+  gmshModelGeoAddLineLoop({4, 1, -2, 3}, 1);
+  gmshModelGeoAddPlaneSurface({1}, 1);
+  gmshModelAddPhysicalGroup(0, {1, 2}, 1);
+  gmshModelAddPhysicalGroup(1, {1, 2}, 2);
+  gmshModelAddPhysicalGroup(2, {1}, 6);
   gmshModelSetPhysicalName(2, 6, "My surface");
-  // ... end of copy
+  // ...end of copy
 
   double h = 0.1, angle = 90.;
-
   std::vector<std::pair<int, int> > ov;
 
   // Extruding the mesh in addition to the geometry works as in .geo files: the
@@ -46,7 +43,7 @@ int main(int argc, char **argv)
   gmshModelGeoTwist({{2,50}}, 0,0.15,0.25, -2*h,0,0, 1,0,0, angle*M_PI/180.,
                     ov, {10}, {}, true);
 
-  gmshModelAddPhysicalGroup(3, 101, {1, 2, ov[1].second});
+  gmshModelAddPhysicalGroup(3, {1, 2, ov[1].second}, 101);
 
   gmshModelGeoSynchronize();
   gmshModelMesh(3);
diff --git a/demos/api/t3.py b/demos/api/t3.py
index ce0598635f2892e2fa0abfb9ff4a53ef77c71034..4a948910dd09552a4e7a7801c050465bbce00f33 100644
--- a/demos/api/t3.py
+++ b/demos/api/t3.py
@@ -12,21 +12,19 @@ gmshModelCreate("t3")
 
 # 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])
+gmshModelGeoAddPoint(0, 0, 0, lc, 1)
+gmshModelGeoAddPoint(.1, 0,  0, lc, 2)
+gmshModelGeoAddPoint(.1, .3, 0, lc, 3)
+gmshModelGeoAddPoint(0, .3, 0, lc, 4)
+gmshModelGeoAddLine(1, 2, 1)
+gmshModelGeoAddLine(3, 2, 2)
+gmshModelGeoAddLine(3, 4, 3)
+gmshModelGeoAddLine(4, 1, 4)
+gmshModelGeoAddLineLoop([4, 1, -2, 3], 1)
+gmshModelGeoAddPlaneSurface([1], 1)
+gmshModelAddPhysicalGroup(0, [1, 2], 1)
+gmshModelAddPhysicalGroup(1, [1, 2], 2)
+gmshModelAddPhysicalGroup(2, [1], 6)
 gmshModelSetPhysicalName(2, 6, "My surface")
 # ...end of copy
 
@@ -47,7 +45,7 @@ gmshModelGeoRevolve([(2,28)], -0.1,0,0.1, 0,1,0, -math.pi/2, ov, [7])
 gmshModelGeoTwist([(2,50)], 0,0.15,0.25, -2*h,0,0, 1,0,0, angle*math.pi/180.,
                   ov, [10], [], True)
 
-gmshModelAddPhysicalGroup(3, 101, [1, 2, ov[1][1]])
+gmshModelAddPhysicalGroup(3, [1, 2, ov[1][1]], 101)
 
 gmshModelGeoSynchronize()
 gmshModelMesh(3)
diff --git a/demos/api/t4.cpp b/demos/api/t4.cpp
index 7a47f21c99a91a1f81f9dcaa09351dafad7ede12..72cd55c56108eba367fafca57075b9493036f95f 100644
--- a/demos/api/t4.cpp
+++ b/demos/api/t4.cpp
@@ -22,63 +22,63 @@ int main(int argc, char **argv)
   double ccos = (-h5*R1 + e2 * hypot(h5, hypot(e2, R1))) / (h5*h5 + e2*e2);
   double ssin = sqrt(1 - ccos*ccos);
 
-  gmshModelGeoAddPoint(1, -e1-e2, 0    , 0, Lc1);
-  gmshModelGeoAddPoint(2, -e1-e2, h1   , 0, Lc1);
-  gmshModelGeoAddPoint(3, -e3-r , h1   , 0, Lc2);
-  gmshModelGeoAddPoint(4, -e3-r , h1+r , 0, Lc2);
-  gmshModelGeoAddPoint(5, -e3   , h1+r , 0, Lc2);
-  gmshModelGeoAddPoint(6, -e3   , h1+h2, 0, Lc1);
-  gmshModelGeoAddPoint(7,  e3   , h1+h2, 0, Lc1);
-  gmshModelGeoAddPoint(8,  e3   , h1+r , 0, Lc2);
-  gmshModelGeoAddPoint(9,  e3+r , h1+r , 0, Lc2);
-  gmshModelGeoAddPoint(10, e3+r , h1   , 0, Lc2);
-  gmshModelGeoAddPoint(11, e1+e2, h1   , 0, Lc1);
-  gmshModelGeoAddPoint(12, e1+e2, 0    , 0, Lc1);
-  gmshModelGeoAddPoint(13, e2   , 0    , 0, Lc1);
-
-  gmshModelGeoAddPoint(14,  R1 / ssin, h5+R1*ccos, 0, Lc2);
-  gmshModelGeoAddPoint(15,  0        , h5        , 0, Lc2);
-  gmshModelGeoAddPoint(16, -R1 / ssin, h5+R1*ccos, 0, Lc2);
-  gmshModelGeoAddPoint(17, -e2       , 0.0       , 0, Lc1);
-
-  gmshModelGeoAddPoint(18, -R2 , h1+h3   , 0, Lc2);
-  gmshModelGeoAddPoint(19, -R2 , h1+h3+h4, 0, Lc2);
-  gmshModelGeoAddPoint(20,  0  , h1+h3+h4, 0, Lc2);
-  gmshModelGeoAddPoint(21,  R2 , h1+h3+h4, 0, Lc2);
-  gmshModelGeoAddPoint(22,  R2 , h1+h3   , 0, Lc2);
-  gmshModelGeoAddPoint(23,  0  , h1+h3   , 0, Lc2);
-
-  gmshModelGeoAddPoint(24,  0, h1+h3+h4+R2, 0, Lc2);
-  gmshModelGeoAddPoint(25,  0, h1+h3-R2,    0, Lc2);
-
-  gmshModelGeoAddLine(1, 1 , 17);
-  gmshModelGeoAddLine(2, 17, 16);
-
-  gmshModelGeoAddCircleArc(3, 14,15,16);
-  gmshModelGeoAddLine(4, 14,13);
-  gmshModelGeoAddLine(5, 13,12);
-  gmshModelGeoAddLine(6, 12,11);
-  gmshModelGeoAddLine(7, 11,10);
-  gmshModelGeoAddCircleArc(8, 8,9,10);
-  gmshModelGeoAddLine(9, 8,7);
-  gmshModelGeoAddLine(10, 7,6);
-  gmshModelGeoAddLine(11, 6,5);
-  gmshModelGeoAddCircleArc(12, 3,4,5);
-  gmshModelGeoAddLine(13, 3,2);
-  gmshModelGeoAddLine(14, 2,1);
-  gmshModelGeoAddLine(15, 18,19);
-  gmshModelGeoAddCircleArc(16, 21,20,24);
-  gmshModelGeoAddCircleArc(17, 24,20,19);
-  gmshModelGeoAddCircleArc(18, 18,23,25);
-  gmshModelGeoAddCircleArc(19, 25,23,22);
-  gmshModelGeoAddLine(20, 21,22);
-
-  gmshModelGeoAddLineLoop(21, {17,-15,18,19,-20,16});
-  gmshModelGeoAddPlaneSurface(22, {21});
-  gmshModelGeoAddLineLoop(23, {11,-12,13,14,1,2,-3,4,5,6,7,-8,9,10});
+  gmshModelGeoAddPoint(-e1-e2, 0    , 0, Lc1, 1);
+  gmshModelGeoAddPoint(-e1-e2, h1   , 0, Lc1, 2);
+  gmshModelGeoAddPoint(-e3-r , h1   , 0, Lc2, 3);
+  gmshModelGeoAddPoint(-e3-r , h1+r , 0, Lc2, 4);
+  gmshModelGeoAddPoint(-e3   , h1+r , 0, Lc2, 5);
+  gmshModelGeoAddPoint(-e3   , h1+h2, 0, Lc1, 6);
+  gmshModelGeoAddPoint( e3   , h1+h2, 0, Lc1, 7);
+  gmshModelGeoAddPoint( e3   , h1+r , 0, Lc2, 8);
+  gmshModelGeoAddPoint( e3+r , h1+r , 0, Lc2, 9);
+  gmshModelGeoAddPoint( e3+r , h1   , 0, Lc2, 10);
+  gmshModelGeoAddPoint( e1+e2, h1   , 0, Lc1, 11);
+  gmshModelGeoAddPoint( e1+e2, 0    , 0, Lc1, 12);
+  gmshModelGeoAddPoint( e2   , 0    , 0, Lc1, 13);
+
+  gmshModelGeoAddPoint( R1 / ssin, h5+R1*ccos, 0, Lc2, 14);
+  gmshModelGeoAddPoint( 0        , h5        , 0, Lc2, 15);
+  gmshModelGeoAddPoint(-R1 / ssin, h5+R1*ccos, 0, Lc2, 16);
+  gmshModelGeoAddPoint(-e2       , 0.0       , 0, Lc1, 17);
+
+  gmshModelGeoAddPoint(-R2 , h1+h3   , 0, Lc2, 18);
+  gmshModelGeoAddPoint(-R2 , h1+h3+h4, 0, Lc2, 19);
+  gmshModelGeoAddPoint( 0  , h1+h3+h4, 0, Lc2, 20);
+  gmshModelGeoAddPoint( R2 , h1+h3+h4, 0, Lc2, 21);
+  gmshModelGeoAddPoint( R2 , h1+h3   , 0, Lc2, 22);
+  gmshModelGeoAddPoint( 0  , h1+h3   , 0, Lc2, 23);
+
+  gmshModelGeoAddPoint(0, h1+h3+h4+R2, 0, Lc2, 24);
+  gmshModelGeoAddPoint(0, h1+h3-R2,    0, Lc2, 25);
+
+  gmshModelGeoAddLine(1 , 17, 1);
+  gmshModelGeoAddLine(17, 16, 2);
+
+  gmshModelGeoAddCircleArc(14,15,16, 3);
+  gmshModelGeoAddLine(14,13, 4);
+  gmshModelGeoAddLine(13,12, 5);
+  gmshModelGeoAddLine(12,11, 6);
+  gmshModelGeoAddLine(11,10, 7);
+  gmshModelGeoAddCircleArc(8,9,10, 8);
+  gmshModelGeoAddLine(8,7, 9);
+  gmshModelGeoAddLine(7,6, 10);
+  gmshModelGeoAddLine(6,5, 11);
+  gmshModelGeoAddCircleArc(3,4,5, 12);
+  gmshModelGeoAddLine(3,2, 13);
+  gmshModelGeoAddLine(2,1, 14);
+  gmshModelGeoAddLine(18,19, 15);
+  gmshModelGeoAddCircleArc(21,20,24, 16);
+  gmshModelGeoAddCircleArc(24,20,19, 17);
+  gmshModelGeoAddCircleArc(18,23,25, 18);
+  gmshModelGeoAddCircleArc(25,23,22, 19);
+  gmshModelGeoAddLine(21,22, 20);
+
+  gmshModelGeoAddLineLoop({17,-15,18,19,-20,16}, 21);
+  gmshModelGeoAddPlaneSurface({21}, 22);
+  gmshModelGeoAddLineLoop({11,-12,13,14,1,2,-3,4,5,6,7,-8,9,10}, 23);
 
   // A surface with one hole is specified using 2 line loops:
-  gmshModelGeoAddPlaneSurface(24, {23,21});
+  gmshModelGeoAddPlaneSurface({23,21}, 24);
 
   // FIXME: this will be implemented through the gmshView API
   /*
diff --git a/demos/api/t4.py b/demos/api/t4.py
index c3ee26869efb2059091575367121920c6a91147c..3e442c83d9d56acf0ba403a238ef35086187501c 100644
--- a/demos/api/t4.py
+++ b/demos/api/t4.py
@@ -21,63 +21,63 @@ def hypot(a, b):
 ccos = (-h5*R1 + e2 * hypot(h5, hypot(e2, R1))) / (h5*h5 + e2*e2)
 ssin = math.sqrt(1 - ccos*ccos)
 
-gmshModelGeoAddPoint(1, -e1-e2, 0    , 0, Lc1)
-gmshModelGeoAddPoint(2, -e1-e2, h1   , 0, Lc1)
-gmshModelGeoAddPoint(3, -e3-r , h1   , 0, Lc2)
-gmshModelGeoAddPoint(4, -e3-r , h1+r , 0, Lc2)
-gmshModelGeoAddPoint(5, -e3   , h1+r , 0, Lc2)
-gmshModelGeoAddPoint(6, -e3   , h1+h2, 0, Lc1)
-gmshModelGeoAddPoint(7,  e3   , h1+h2, 0, Lc1)
-gmshModelGeoAddPoint(8,  e3   , h1+r , 0, Lc2)
-gmshModelGeoAddPoint(9,  e3+r , h1+r , 0, Lc2)
-gmshModelGeoAddPoint(10, e3+r , h1   , 0, Lc2)
-gmshModelGeoAddPoint(11, e1+e2, h1   , 0, Lc1)
-gmshModelGeoAddPoint(12, e1+e2, 0    , 0, Lc1)
-gmshModelGeoAddPoint(13, e2   , 0    , 0, Lc1)
-
-gmshModelGeoAddPoint(14,  R1 / ssin, h5+R1*ccos, 0, Lc2)
-gmshModelGeoAddPoint(15,  0        , h5        , 0, Lc2)
-gmshModelGeoAddPoint(16, -R1 / ssin, h5+R1*ccos, 0, Lc2)
-gmshModelGeoAddPoint(17, -e2       , 0.0       , 0, Lc1)
-
-gmshModelGeoAddPoint(18, -R2 , h1+h3   , 0, Lc2)
-gmshModelGeoAddPoint(19, -R2 , h1+h3+h4, 0, Lc2)
-gmshModelGeoAddPoint(20,  0  , h1+h3+h4, 0, Lc2)
-gmshModelGeoAddPoint(21,  R2 , h1+h3+h4, 0, Lc2)
-gmshModelGeoAddPoint(22,  R2 , h1+h3   , 0, Lc2)
-gmshModelGeoAddPoint(23,  0  , h1+h3   , 0, Lc2)
-
-gmshModelGeoAddPoint(24,  0, h1+h3+h4+R2, 0, Lc2)
-gmshModelGeoAddPoint(25,  0, h1+h3-R2,    0, Lc2)
-
-gmshModelGeoAddLine(1, 1 , 17)
-gmshModelGeoAddLine(2, 17, 16)
-
-gmshModelGeoAddCircleArc(3, 14,15,16)
-gmshModelGeoAddLine(4, 14,13)
-gmshModelGeoAddLine(5, 13,12)
-gmshModelGeoAddLine(6, 12,11)
-gmshModelGeoAddLine(7, 11,10)
-gmshModelGeoAddCircleArc(8, 8,9,10)
-gmshModelGeoAddLine(9, 8,7)
-gmshModelGeoAddLine(10, 7,6)
-gmshModelGeoAddLine(11, 6,5)
-gmshModelGeoAddCircleArc(12, 3,4,5)
-gmshModelGeoAddLine(13, 3,2)
-gmshModelGeoAddLine(14, 2,1)
-gmshModelGeoAddLine(15, 18,19)
-gmshModelGeoAddCircleArc(16, 21,20,24)
-gmshModelGeoAddCircleArc(17, 24,20,19)
-gmshModelGeoAddCircleArc(18, 18,23,25)
-gmshModelGeoAddCircleArc(19, 25,23,22)
-gmshModelGeoAddLine(20, 21,22)
-
-gmshModelGeoAddLineLoop(21, [17,-15,18,19,-20,16])
-gmshModelGeoAddPlaneSurface(22, [21])
-gmshModelGeoAddLineLoop(23, [11,-12,13,14,1,2,-3,4,5,6,7,-8,9,10])
+gmshModelGeoAddPoint(-e1-e2, 0    , 0, Lc1, 1)
+gmshModelGeoAddPoint(-e1-e2, h1   , 0, Lc1, 2)
+gmshModelGeoAddPoint(-e3-r , h1   , 0, Lc2, 3)
+gmshModelGeoAddPoint(-e3-r , h1+r , 0, Lc2, 4)
+gmshModelGeoAddPoint(-e3   , h1+r , 0, Lc2, 5)
+gmshModelGeoAddPoint(-e3   , h1+h2, 0, Lc1, 6)
+gmshModelGeoAddPoint( e3   , h1+h2, 0, Lc1, 7)
+gmshModelGeoAddPoint( e3   , h1+r , 0, Lc2, 8)
+gmshModelGeoAddPoint( e3+r , h1+r , 0, Lc2, 9)
+gmshModelGeoAddPoint( e3+r , h1   , 0, Lc2, 10)
+gmshModelGeoAddPoint( e1+e2, h1   , 0, Lc1, 11)
+gmshModelGeoAddPoint( e1+e2, 0    , 0, Lc1, 12)
+gmshModelGeoAddPoint( e2   , 0    , 0, Lc1, 13)
+
+gmshModelGeoAddPoint( R1 / ssin, h5+R1*ccos, 0, Lc2, 14)
+gmshModelGeoAddPoint( 0        , h5        , 0, Lc2, 15)
+gmshModelGeoAddPoint(-R1 / ssin, h5+R1*ccos, 0, Lc2, 16)
+gmshModelGeoAddPoint(-e2       , 0.0       , 0, Lc1, 17)
+
+gmshModelGeoAddPoint(-R2 , h1+h3   , 0, Lc2, 18)
+gmshModelGeoAddPoint(-R2 , h1+h3+h4, 0, Lc2, 19)
+gmshModelGeoAddPoint( 0  , h1+h3+h4, 0, Lc2, 20)
+gmshModelGeoAddPoint( R2 , h1+h3+h4, 0, Lc2, 21)
+gmshModelGeoAddPoint( R2 , h1+h3   , 0, Lc2, 22)
+gmshModelGeoAddPoint( 0  , h1+h3   , 0, Lc2, 23)
+                                                
+gmshModelGeoAddPoint( 0, h1+h3+h4+R2, 0, Lc2, 24)
+gmshModelGeoAddPoint( 0, h1+h3-R2,    0, Lc2, 25)
+
+gmshModelGeoAddLine(1 , 17, 1)
+gmshModelGeoAddLine(17, 16, 2)
+
+gmshModelGeoAddCircleArc(14,15,16, 3)
+gmshModelGeoAddLine(14,13, 4)
+gmshModelGeoAddLine(13,12, 5)
+gmshModelGeoAddLine(12,11, 6)
+gmshModelGeoAddLine(11,10, 7)
+gmshModelGeoAddCircleArc(8,9,10, 8)
+gmshModelGeoAddLine(8,7, 9)
+gmshModelGeoAddLine(7,6, 10)
+gmshModelGeoAddLine(6,5, 11)
+gmshModelGeoAddCircleArc(3,4,5, 12)
+gmshModelGeoAddLine(3,2, 13)
+gmshModelGeoAddLine(2,1, 14)
+gmshModelGeoAddLine(18,19, 15)
+gmshModelGeoAddCircleArc(21,20,24, 16)
+gmshModelGeoAddCircleArc(24,20,19, 17)
+gmshModelGeoAddCircleArc(18,23,25, 18)
+gmshModelGeoAddCircleArc(25,23,22, 19)
+gmshModelGeoAddLine(21,22, 20)
+
+gmshModelGeoAddLineLoop([17,-15,18,19,-20,16], 21)
+gmshModelGeoAddPlaneSurface([21], 22)
+gmshModelGeoAddLineLoop([11,-12,13,14,1,2,-3,4,5,6,7,-8,9,10], 23)
 
 # A surface with one hole is specified using 2 line loops:
-gmshModelGeoAddPlaneSurface(24, [23,21])
+gmshModelGeoAddPlaneSurface([23,21], 24)
 
 # FIXME: this will be implemented through the gmshView API
 #  View "comments" {
diff --git a/demos/api/t5.cpp b/demos/api/t5.cpp
index 9b7cbacf818641efe25e6fefee9e157673934683..fb07865d46f3b51cfba05c624158b52b6bcef8b7 100644
--- a/demos/api/t5.cpp
+++ b/demos/api/t5.cpp
@@ -6,49 +6,48 @@
 void cheeseHole(double x, double y, double z, double r, double lc,
                 std::vector<int> &shells, std::vector<int> &volumes)
 {
-  // When the tag (first argument) is negative, the next available tag for the
-  // corresponding entity is appended to the returned value
-  int p1 = gmshModelGeoAddPoint(-1, x,  y,  z,  lc)[1];
-  int p2 = gmshModelGeoAddPoint(-1, x+r,y,  z,   lc)[1];
-  int p3 = gmshModelGeoAddPoint(-1, x,  y+r,z,   lc)[1];
-  int p4 = gmshModelGeoAddPoint(-1, x,  y,  z+r, lc)[1];
-  int p5 = gmshModelGeoAddPoint(-1, x-r,y,  z,   lc)[1];
-  int p6 = gmshModelGeoAddPoint(-1, x,  y-r,z,   lc)[1];
-  int p7 = gmshModelGeoAddPoint(-1, x,  y,  z-r, lc)[1];
-
-  int c1 = gmshModelGeoAddCircleArc(-1, p2,p1,p7)[1];
-  int c2 = gmshModelGeoAddCircleArc(-1, p7,p1,p5)[1];
-  int c3 = gmshModelGeoAddCircleArc(-1, p5,p1,p4)[1];
-  int c4 = gmshModelGeoAddCircleArc(-1, p4,p1,p2)[1];
-  int c5 = gmshModelGeoAddCircleArc(-1, p2,p1,p3)[1];
-  int c6 = gmshModelGeoAddCircleArc(-1, p3,p1,p5)[1];
-  int c7 = gmshModelGeoAddCircleArc(-1, p5,p1,p6)[1];
-  int c8 = gmshModelGeoAddCircleArc(-1, p6,p1,p2)[1];
-  int c9 = gmshModelGeoAddCircleArc(-1, p7,p1,p3)[1];
-  int c10 = gmshModelGeoAddCircleArc(-1, p3,p1,p4)[1];
-  int c11 = gmshModelGeoAddCircleArc(-1, p4,p1,p6)[1];
-  int c12 = gmshModelGeoAddCircleArc(-1, p6,p1,p7)[1];
-
-  int l1 = gmshModelGeoAddLineLoop(-1, {c5,c10,c4})[1];
-  int l2 = gmshModelGeoAddLineLoop(-1, {c9,-c5,c1})[1];
-  int l3 = gmshModelGeoAddLineLoop(-1, {c12,-c8,-c1})[1];
-  int l4 = gmshModelGeoAddLineLoop(-1, {c8,-c4,c11})[1];
-  int l5 = gmshModelGeoAddLineLoop(-1, {-c10,c6,c3})[1];
-  int l6 = gmshModelGeoAddLineLoop(-1, {-c11,-c3,c7})[1];
-  int l7 = gmshModelGeoAddLineLoop(-1, {-c2,-c7,-c12})[1];
-  int l8 = gmshModelGeoAddLineLoop(-1, {-c6,-c9,c2})[1];
-
-  int s1 = gmshModelGeoAddSurfaceFilling(-1, {l1})[1];
-  int s2 = gmshModelGeoAddSurfaceFilling(-1, {l2})[1];
-  int s3 = gmshModelGeoAddSurfaceFilling(-1, {l3})[1];
-  int s4 = gmshModelGeoAddSurfaceFilling(-1, {l4})[1];
-  int s5 = gmshModelGeoAddSurfaceFilling(-1, {l5})[1];
-  int s6 = gmshModelGeoAddSurfaceFilling(-1, {l6})[1];
-  int s7 = gmshModelGeoAddSurfaceFilling(-1, {l7})[1];
-  int s8 = gmshModelGeoAddSurfaceFilling(-1, {l8})[1];
-
-  int sl = gmshModelGeoAddSurfaceLoop(-1, {s1, s2, s3, s4, s5, s6, s7, s8})[1];
-  int v = gmshModelGeoAddVolume(-1, {sl})[1];
+  // When the tag is not specified, a new one is automatically provided
+  int p1 = gmshModelGeoAddPoint(x,  y,  z,  lc);
+  int p2 = gmshModelGeoAddPoint(x+r,y,  z,   lc);
+  int p3 = gmshModelGeoAddPoint(x,  y+r,z,   lc);
+  int p4 = gmshModelGeoAddPoint(x,  y,  z+r, lc);
+  int p5 = gmshModelGeoAddPoint(x-r,y,  z,   lc);
+  int p6 = gmshModelGeoAddPoint(x,  y-r,z,   lc);
+  int p7 = gmshModelGeoAddPoint(x,  y,  z-r, lc);
+
+  int c1 = gmshModelGeoAddCircleArc(p2,p1,p7);
+  int c2 = gmshModelGeoAddCircleArc(p7,p1,p5);
+  int c3 = gmshModelGeoAddCircleArc(p5,p1,p4);
+  int c4 = gmshModelGeoAddCircleArc(p4,p1,p2);
+  int c5 = gmshModelGeoAddCircleArc(p2,p1,p3);
+  int c6 = gmshModelGeoAddCircleArc(p3,p1,p5);
+  int c7 = gmshModelGeoAddCircleArc(p5,p1,p6);
+  int c8 = gmshModelGeoAddCircleArc(p6,p1,p2);
+  int c9 = gmshModelGeoAddCircleArc(p7,p1,p3);
+  int c10 = gmshModelGeoAddCircleArc(p3,p1,p4);
+  int c11 = gmshModelGeoAddCircleArc(p4,p1,p6);
+  int c12 = gmshModelGeoAddCircleArc(p6,p1,p7);
+
+  int l1 = gmshModelGeoAddLineLoop({c5,c10,c4});
+  int l2 = gmshModelGeoAddLineLoop({c9,-c5,c1});
+  int l3 = gmshModelGeoAddLineLoop({c12,-c8,-c1});
+  int l4 = gmshModelGeoAddLineLoop({c8,-c4,c11});
+  int l5 = gmshModelGeoAddLineLoop({-c10,c6,c3});
+  int l6 = gmshModelGeoAddLineLoop({-c11,-c3,c7});
+  int l7 = gmshModelGeoAddLineLoop({-c2,-c7,-c12});
+  int l8 = gmshModelGeoAddLineLoop({-c6,-c9,c2});
+
+  int s1 = gmshModelGeoAddSurfaceFilling({l1});
+  int s2 = gmshModelGeoAddSurfaceFilling({l2});
+  int s3 = gmshModelGeoAddSurfaceFilling({l3});
+  int s4 = gmshModelGeoAddSurfaceFilling({l4});
+  int s5 = gmshModelGeoAddSurfaceFilling({l5});
+  int s6 = gmshModelGeoAddSurfaceFilling({l6});
+  int s7 = gmshModelGeoAddSurfaceFilling({l7});
+  int s8 = gmshModelGeoAddSurfaceFilling({l8});
+
+  int sl = gmshModelGeoAddSurfaceLoop({s1, s2, s3, s4, s5, s6, s7, s8});
+  int v = gmshModelGeoAddVolume({sl});
   shells.push_back(sl);
   volumes.push_back(v);
 }
@@ -62,65 +61,65 @@ int main(int argc, char **argv)
   double lcar2 = .0005;
   double lcar3 = .055;
 
-  gmshModelGeoAddPoint(1, 0.5,0.5,0.5, lcar2);
-  gmshModelGeoAddPoint(2, 0.5,0.5,0, lcar1);
-  gmshModelGeoAddPoint(3, 0,0.5,0.5, lcar1);
-  gmshModelGeoAddPoint(4, 0,0,0.5, lcar1);
-  gmshModelGeoAddPoint(5, 0.5,0,0.5, lcar1);
-  gmshModelGeoAddPoint(6, 0.5,0,0, lcar1);
-  gmshModelGeoAddPoint(7, 0,0.5,0, lcar1);
-  gmshModelGeoAddPoint(8, 0,1,0, lcar1);
-  gmshModelGeoAddPoint(9, 1,1,0, lcar1);
-  gmshModelGeoAddPoint(10, 0,0,1, lcar1);
-  gmshModelGeoAddPoint(11, 0,1,1, lcar1);
-  gmshModelGeoAddPoint(12, 1,1,1, lcar1);
-  gmshModelGeoAddPoint(13, 1,0,1, lcar1);
-  gmshModelGeoAddPoint(14, 1,0,0, lcar1);
-
-  gmshModelGeoAddLine(1, 8,9);
-  gmshModelGeoAddLine(2, 9,12);
-  gmshModelGeoAddLine(3, 12,11);
-  gmshModelGeoAddLine(4, 11,8);
-  gmshModelGeoAddLine(5, 9,14);
-  gmshModelGeoAddLine(6, 14,13);
-  gmshModelGeoAddLine(7, 13,12);
-  gmshModelGeoAddLine(8, 11,10);
-  gmshModelGeoAddLine(9, 10,13);
-  gmshModelGeoAddLine(10, 10,4);
-  gmshModelGeoAddLine(11, 4,5);
-  gmshModelGeoAddLine(12, 5,6);
-  gmshModelGeoAddLine(13, 6,2);
-  gmshModelGeoAddLine(14, 2,1);
-  gmshModelGeoAddLine(15, 1,3);
-  gmshModelGeoAddLine(16, 3,7);
-  gmshModelGeoAddLine(17, 7,2);
-  gmshModelGeoAddLine(18, 3,4);
-  gmshModelGeoAddLine(19, 5,1);
-  gmshModelGeoAddLine(20, 7,8);
-  gmshModelGeoAddLine(21, 6,14);
-
-  gmshModelGeoAddLineLoop(22, {-11,-19,-15,-18});
-  gmshModelGeoAddPlaneSurface(23, {22});
-  gmshModelGeoAddLineLoop(24, {16,17,14,15});
-  gmshModelGeoAddPlaneSurface(25, {24});
-  gmshModelGeoAddLineLoop(26, {-17,20,1,5,-21,13});
-  gmshModelGeoAddPlaneSurface(27, {26});
-  gmshModelGeoAddLineLoop(28, {-4,-1,-2,-3});
-  gmshModelGeoAddPlaneSurface(29, {28});
-  gmshModelGeoAddLineLoop(30, {-7,2,-5,-6});
-  gmshModelGeoAddPlaneSurface(31, {30});
-  gmshModelGeoAddLineLoop(32, {6,-9,10,11,12,21});
-  gmshModelGeoAddPlaneSurface(33, {32});
-  gmshModelGeoAddLineLoop(34, {7,3,8,9});
-  gmshModelGeoAddPlaneSurface(35, {34});
-  gmshModelGeoAddLineLoop(36, {-10,18,-16,-20,4,-8});
-  gmshModelGeoAddPlaneSurface(37, {36});
-  gmshModelGeoAddLineLoop(38, {-14,-13,-12,19});
-  gmshModelGeoAddPlaneSurface(39, {38});
+  gmshModelGeoAddPoint(0.5,0.5,0.5, lcar2, 1);
+  gmshModelGeoAddPoint(0.5,0.5,0, lcar1, 2);
+  gmshModelGeoAddPoint(0,0.5,0.5, lcar1, 3);
+  gmshModelGeoAddPoint(0,0,0.5, lcar1, 4);
+  gmshModelGeoAddPoint(0.5,0,0.5, lcar1, 5);
+  gmshModelGeoAddPoint(0.5,0,0, lcar1, 6);
+  gmshModelGeoAddPoint(0,0.5,0, lcar1, 7);
+  gmshModelGeoAddPoint(0,1,0, lcar1, 8);
+  gmshModelGeoAddPoint(1,1,0, lcar1, 9);
+  gmshModelGeoAddPoint(0,0,1, lcar1, 10);
+  gmshModelGeoAddPoint(0,1,1, lcar1, 11);
+  gmshModelGeoAddPoint(1,1,1, lcar1, 12);
+  gmshModelGeoAddPoint(1,0,1, lcar1, 13);
+  gmshModelGeoAddPoint(1,0,0, lcar1, 14);
+
+  gmshModelGeoAddLine(8,9, 1);
+  gmshModelGeoAddLine(9,12, 2);
+  gmshModelGeoAddLine(12,11, 3);
+  gmshModelGeoAddLine(11,8, 4);
+  gmshModelGeoAddLine(9,14, 5);
+  gmshModelGeoAddLine(14,13, 6);
+  gmshModelGeoAddLine(13,12, 7);
+  gmshModelGeoAddLine(11,10, 8);
+  gmshModelGeoAddLine(10,13, 9);
+  gmshModelGeoAddLine(10,4, 10);
+  gmshModelGeoAddLine(4,5, 11);
+  gmshModelGeoAddLine(5,6, 12);
+  gmshModelGeoAddLine(6,2, 13);
+  gmshModelGeoAddLine(2,1, 14);
+  gmshModelGeoAddLine(1,3, 15);
+  gmshModelGeoAddLine(3,7, 16);
+  gmshModelGeoAddLine(7,2, 17);
+  gmshModelGeoAddLine(3,4, 18);
+  gmshModelGeoAddLine(5,1, 19);
+  gmshModelGeoAddLine(7,8, 20);
+  gmshModelGeoAddLine(6,14, 21);
+
+  gmshModelGeoAddLineLoop({-11,-19,-15,-18}, 22);
+  gmshModelGeoAddPlaneSurface({22}, 23);
+  gmshModelGeoAddLineLoop({16,17,14,15}, 24);
+  gmshModelGeoAddPlaneSurface({24}, 25);
+  gmshModelGeoAddLineLoop({-17,20,1,5,-21,13}, 26);
+  gmshModelGeoAddPlaneSurface({26}, 27);
+  gmshModelGeoAddLineLoop({-4,-1,-2,-3}, 28);
+  gmshModelGeoAddPlaneSurface({28}, 29);
+  gmshModelGeoAddLineLoop({-7,2,-5,-6}, 30);
+  gmshModelGeoAddPlaneSurface({30}, 31);
+  gmshModelGeoAddLineLoop({6,-9,10,11,12,21}, 32);
+  gmshModelGeoAddPlaneSurface({32}, 33);
+  gmshModelGeoAddLineLoop({7,3,8,9}, 34);
+  gmshModelGeoAddPlaneSurface({34}, 35);
+  gmshModelGeoAddLineLoop({-10,18,-16,-20,4,-8}, 36);
+  gmshModelGeoAddPlaneSurface({36}, 37);
+  gmshModelGeoAddLineLoop({-14,-13,-12,19}, 38);
+  gmshModelGeoAddPlaneSurface({38}, 39);
 
   std::vector<int> shells, volumes;
 
-  int sl = gmshModelGeoAddSurfaceLoop(-1, {35,31,29,37,33,23,39,25,27})[1];
+  int sl = gmshModelGeoAddSurfaceLoop({35,31,29,37,33,23,39,25,27});
   shells.push_back(sl);
 
   double x = 0, y = 0.75, z = 0, r = 0.09 ;
@@ -128,14 +127,14 @@ int main(int argc, char **argv)
     x += 0.166 ;
     z += 0.166 ;
     cheeseHole(x, y, z, r, lcar3, shells, volumes);
-    gmshModelAddPhysicalGroup(3, t, {volumes.back()});
+    gmshModelAddPhysicalGroup(3, {volumes.back()}, t);
     std::printf("Hole %d (center = {%g,%g,%g}, radius = %g) has number %d!\n",
                 t, x, y, z, r, volumes.back());
   }
 
-  gmshModelGeoAddVolume(186, shells);
+  gmshModelGeoAddVolume(shells, 186);
 
-  gmshModelAddPhysicalGroup(3, 10, {186});
+  gmshModelAddPhysicalGroup(3, {186}, 10);
   gmshModelGeoSynchronize();
   gmshModelMesh(3);
   gmshExport("t5.msh");
diff --git a/demos/api/t5.py b/demos/api/t5.py
index 8dc12883c857587271a89c86b064efd757585024..9f1a3e7039d36b6168c91d47f356febb997832e9 100644
--- a/demos/api/t5.py
+++ b/demos/api/t5.py
@@ -12,101 +12,100 @@ lcar1 = .1
 lcar2 = .0005
 lcar3 = .055
 
-gmshModelGeoAddPoint(1, 0.5,0.5,0.5, lcar2)
-gmshModelGeoAddPoint(2, 0.5,0.5,0, lcar1)
-gmshModelGeoAddPoint(3, 0,0.5,0.5, lcar1)
-gmshModelGeoAddPoint(4, 0,0,0.5, lcar1)
-gmshModelGeoAddPoint(5, 0.5,0,0.5, lcar1)
-gmshModelGeoAddPoint(6, 0.5,0,0, lcar1)
-gmshModelGeoAddPoint(7, 0,0.5,0, lcar1)
-gmshModelGeoAddPoint(8, 0,1,0, lcar1)
-gmshModelGeoAddPoint(9, 1,1,0, lcar1)
-gmshModelGeoAddPoint(10, 0,0,1, lcar1)
-gmshModelGeoAddPoint(11, 0,1,1, lcar1)
-gmshModelGeoAddPoint(12, 1,1,1, lcar1)
-gmshModelGeoAddPoint(13, 1,0,1, lcar1)
-gmshModelGeoAddPoint(14, 1,0,0, lcar1)
+gmshModelGeoAddPoint(0.5,0.5,0.5, lcar2, 1)
+gmshModelGeoAddPoint(0.5,0.5,0, lcar1, 2)
+gmshModelGeoAddPoint(0,0.5,0.5, lcar1, 3)
+gmshModelGeoAddPoint(0,0,0.5, lcar1, 4)
+gmshModelGeoAddPoint(0.5,0,0.5, lcar1, 5)
+gmshModelGeoAddPoint(0.5,0,0, lcar1, 6)
+gmshModelGeoAddPoint(0,0.5,0, lcar1, 7)
+gmshModelGeoAddPoint(0,1,0, lcar1, 8)
+gmshModelGeoAddPoint(1,1,0, lcar1, 9)
+gmshModelGeoAddPoint(0,0,1, lcar1, 10)
+gmshModelGeoAddPoint(0,1,1, lcar1, 11)
+gmshModelGeoAddPoint(1,1,1, lcar1, 12)
+gmshModelGeoAddPoint(1,0,1, lcar1, 13)
+gmshModelGeoAddPoint(1,0,0, lcar1, 14)
 
-gmshModelGeoAddLine(1, 8,9);   gmshModelGeoAddLine(2, 9,12)
-gmshModelGeoAddLine(3, 12,11); gmshModelGeoAddLine(4, 11,8)
-gmshModelGeoAddLine(5, 9,14);  gmshModelGeoAddLine(6, 14,13)
-gmshModelGeoAddLine(7, 13,12); gmshModelGeoAddLine(8, 11,10)
-gmshModelGeoAddLine(9, 10,13); gmshModelGeoAddLine(10, 10,4)
-gmshModelGeoAddLine(11, 4,5);  gmshModelGeoAddLine(12, 5,6)
-gmshModelGeoAddLine(13, 6,2);  gmshModelGeoAddLine(14, 2,1)
-gmshModelGeoAddLine(15, 1,3);  gmshModelGeoAddLine(16, 3,7)
-gmshModelGeoAddLine(17, 7,2);  gmshModelGeoAddLine(18, 3,4)
-gmshModelGeoAddLine(19, 5,1);  gmshModelGeoAddLine(20, 7,8)
-gmshModelGeoAddLine(21, 6,14); 
+gmshModelGeoAddLine(8,9, 1);   gmshModelGeoAddLine(9,12, 2)
+gmshModelGeoAddLine(12,11, 3); gmshModelGeoAddLine(11,8, 4)
+gmshModelGeoAddLine(9,14, 5);  gmshModelGeoAddLine(14,13, 6)
+gmshModelGeoAddLine(13,12, 7); gmshModelGeoAddLine(11,10, 8)
+gmshModelGeoAddLine(10,13, 9); gmshModelGeoAddLine(10,4, 10)
+gmshModelGeoAddLine(4,5, 11);  gmshModelGeoAddLine(5,6, 12)
+gmshModelGeoAddLine(6,2, 13);  gmshModelGeoAddLine(2,1, 14)
+gmshModelGeoAddLine(1,3, 15);  gmshModelGeoAddLine(3,7, 16)
+gmshModelGeoAddLine(7,2, 17);  gmshModelGeoAddLine(3,4, 18)
+gmshModelGeoAddLine(5,1, 19);  gmshModelGeoAddLine(7,8, 20)
+gmshModelGeoAddLine(6,14, 21); 
 
-gmshModelGeoAddLineLoop(22, [-11,-19,-15,-18])
-gmshModelGeoAddPlaneSurface(23, [22])
-gmshModelGeoAddLineLoop(24, [16,17,14,15])
-gmshModelGeoAddPlaneSurface(25, [24])
-gmshModelGeoAddLineLoop(26, [-17,20,1,5,-21,13])
-gmshModelGeoAddPlaneSurface(27, [26])
-gmshModelGeoAddLineLoop(28, [-4,-1,-2,-3])
-gmshModelGeoAddPlaneSurface(29, [28])
-gmshModelGeoAddLineLoop(30, [-7,2,-5,-6])
-gmshModelGeoAddPlaneSurface(31, [30])
-gmshModelGeoAddLineLoop(32, [6,-9,10,11,12,21])
-gmshModelGeoAddPlaneSurface(33, [32])
-gmshModelGeoAddLineLoop(34, [7,3,8,9])
-gmshModelGeoAddPlaneSurface(35, [34])
-gmshModelGeoAddLineLoop(36, [-10,18,-16,-20,4,-8])
-gmshModelGeoAddPlaneSurface(37, [36])
-gmshModelGeoAddLineLoop(38, [-14,-13,-12,19])
-gmshModelGeoAddPlaneSurface(39, [38])
+gmshModelGeoAddLineLoop([-11,-19,-15,-18], 22)
+gmshModelGeoAddPlaneSurface([22], 23)
+gmshModelGeoAddLineLoop([16,17,14,15], 24)
+gmshModelGeoAddPlaneSurface([24], 25)
+gmshModelGeoAddLineLoop([-17,20,1,5,-21,13], 26)
+gmshModelGeoAddPlaneSurface([26], 27)
+gmshModelGeoAddLineLoop([-4,-1,-2,-3], 28)
+gmshModelGeoAddPlaneSurface([28], 29)
+gmshModelGeoAddLineLoop([-7,2,-5,-6], 30)
+gmshModelGeoAddPlaneSurface([30], 31)
+gmshModelGeoAddLineLoop([6,-9,10,11,12,21], 32)
+gmshModelGeoAddPlaneSurface([32], 33)
+gmshModelGeoAddLineLoop([7,3,8,9], 34)
+gmshModelGeoAddPlaneSurface([34], 35)
+gmshModelGeoAddLineLoop([-10,18,-16,-20,4,-8], 36)
+gmshModelGeoAddPlaneSurface([36], 37)
+gmshModelGeoAddLineLoop([-14,-13,-12,19], 38)
+gmshModelGeoAddPlaneSurface([38], 39)
 
 shells = IntVector(); volumes = IntVector()
 
-sl = gmshModelGeoAddSurfaceLoop(-1, [35,31,29,37,33,23,39,25,27])
-shells.push_back(sl[1])
+# When the tag is not specified, a new one is automatically provided
+sl = gmshModelGeoAddSurfaceLoop([35,31,29,37,33,23,39,25,27])
+shells.push_back(sl)
 
 def cheeseHole(x, y, z, r, lc, shells, volumes):
-    # When the tag (first argument) is negative, the next available tag for the
-    # corresponding entity is appended to the value returned by the function
-    p1 = gmshModelGeoAddPoint(-1, x,  y,  z,   lc)[1]
-    p2 = gmshModelGeoAddPoint(-1, x+r,y,  z,   lc)[1]
-    p3 = gmshModelGeoAddPoint(-1, x,  y+r,z,   lc)[1]
-    p4 = gmshModelGeoAddPoint(-1, x,  y,  z+r, lc)[1]
-    p5 = gmshModelGeoAddPoint(-1, x-r,y,  z,   lc)[1]
-    p6 = gmshModelGeoAddPoint(-1, x,  y-r,z,   lc)[1]
-    p7 = gmshModelGeoAddPoint(-1, x,  y,  z-r, lc)[1]
+    p1 = gmshModelGeoAddPoint(x,  y,  z,   lc)
+    p2 = gmshModelGeoAddPoint(x+r,y,  z,   lc)
+    p3 = gmshModelGeoAddPoint(x,  y+r,z,   lc)
+    p4 = gmshModelGeoAddPoint(x,  y,  z+r, lc)
+    p5 = gmshModelGeoAddPoint(x-r,y,  z,   lc)
+    p6 = gmshModelGeoAddPoint(x,  y-r,z,   lc)
+    p7 = gmshModelGeoAddPoint(x,  y,  z-r, lc)
 
-    c1 = gmshModelGeoAddCircleArc(-1, p2,p1,p7)[1]
-    c2 = gmshModelGeoAddCircleArc(-1, p7,p1,p5)[1]
-    c3 = gmshModelGeoAddCircleArc(-1, p5,p1,p4)[1]
-    c4 = gmshModelGeoAddCircleArc(-1, p4,p1,p2)[1]
-    c5 = gmshModelGeoAddCircleArc(-1, p2,p1,p3)[1]
-    c6 = gmshModelGeoAddCircleArc(-1, p3,p1,p5)[1]
-    c7 = gmshModelGeoAddCircleArc(-1, p5,p1,p6)[1]
-    c8 = gmshModelGeoAddCircleArc(-1, p6,p1,p2)[1]
-    c9 = gmshModelGeoAddCircleArc(-1, p7,p1,p3)[1]
-    c10 = gmshModelGeoAddCircleArc(-1, p3,p1,p4)[1]
-    c11 = gmshModelGeoAddCircleArc(-1, p4,p1,p6)[1]
-    c12 = gmshModelGeoAddCircleArc(-1, p6,p1,p7)[1]
+    c1 = gmshModelGeoAddCircleArc(p2,p1,p7)
+    c2 = gmshModelGeoAddCircleArc(p7,p1,p5)
+    c3 = gmshModelGeoAddCircleArc(p5,p1,p4)
+    c4 = gmshModelGeoAddCircleArc(p4,p1,p2)
+    c5 = gmshModelGeoAddCircleArc(p2,p1,p3)
+    c6 = gmshModelGeoAddCircleArc(p3,p1,p5)
+    c7 = gmshModelGeoAddCircleArc(p5,p1,p6)
+    c8 = gmshModelGeoAddCircleArc(p6,p1,p2)
+    c9 = gmshModelGeoAddCircleArc(p7,p1,p3)
+    c10 = gmshModelGeoAddCircleArc(p3,p1,p4)
+    c11 = gmshModelGeoAddCircleArc(p4,p1,p6)
+    c12 = gmshModelGeoAddCircleArc(p6,p1,p7)
     
-    l1 = gmshModelGeoAddLineLoop(-1, [c5,c10,c4])[1]
-    l2 = gmshModelGeoAddLineLoop(-1, [c9,-c5,c1])[1]
-    l3 = gmshModelGeoAddLineLoop(-1, [c12,-c8,-c1])[1]
-    l4 = gmshModelGeoAddLineLoop(-1, [c8,-c4,c11])[1]
-    l5 = gmshModelGeoAddLineLoop(-1, [-c10,c6,c3])[1]
-    l6 = gmshModelGeoAddLineLoop(-1, [-c11,-c3,c7])[1]
-    l7 = gmshModelGeoAddLineLoop(-1, [-c2,-c7,-c12])[1]
-    l8 = gmshModelGeoAddLineLoop(-1, [-c6,-c9,c2])[1]
+    l1 = gmshModelGeoAddLineLoop([c5,c10,c4])
+    l2 = gmshModelGeoAddLineLoop([c9,-c5,c1])
+    l3 = gmshModelGeoAddLineLoop([c12,-c8,-c1])
+    l4 = gmshModelGeoAddLineLoop([c8,-c4,c11])
+    l5 = gmshModelGeoAddLineLoop([-c10,c6,c3])
+    l6 = gmshModelGeoAddLineLoop([-c11,-c3,c7])
+    l7 = gmshModelGeoAddLineLoop([-c2,-c7,-c12])
+    l8 = gmshModelGeoAddLineLoop([-c6,-c9,c2])
     
-    s1 = gmshModelGeoAddSurfaceFilling(-1, [l1])[1]
-    s2 = gmshModelGeoAddSurfaceFilling(-1, [l2])[1]
-    s3 = gmshModelGeoAddSurfaceFilling(-1, [l3])[1]
-    s4 = gmshModelGeoAddSurfaceFilling(-1, [l4])[1]
-    s5 = gmshModelGeoAddSurfaceFilling(-1, [l5])[1]
-    s6 = gmshModelGeoAddSurfaceFilling(-1, [l6])[1]
-    s7 = gmshModelGeoAddSurfaceFilling(-1, [l7])[1]
-    s8 = gmshModelGeoAddSurfaceFilling(-1, [l8])[1]
+    s1 = gmshModelGeoAddSurfaceFilling([l1])
+    s2 = gmshModelGeoAddSurfaceFilling([l2])
+    s3 = gmshModelGeoAddSurfaceFilling([l3])
+    s4 = gmshModelGeoAddSurfaceFilling([l4])
+    s5 = gmshModelGeoAddSurfaceFilling([l5])
+    s6 = gmshModelGeoAddSurfaceFilling([l6])
+    s7 = gmshModelGeoAddSurfaceFilling([l7])
+    s8 = gmshModelGeoAddSurfaceFilling([l8])
     
-    sl = gmshModelGeoAddSurfaceLoop(-1, [s1, s2, s3, s4, s5, s6, s7, s8])[1]
-    v = gmshModelGeoAddVolume(-1, [sl])[1]
+    sl = gmshModelGeoAddSurfaceLoop([s1, s2, s3, s4, s5, s6, s7, s8])
+    v = gmshModelGeoAddVolume([sl])
     shells.append(sl)
     volumes.append(v)
 
@@ -115,11 +114,11 @@ for t in range(1, 6):
     x += 0.166 ;
     z += 0.166 ;
     cheeseHole(x, y, z, r, lcar3, shells, volumes);
-    gmshModelAddPhysicalGroup(3, t, [volumes.back()]);
+    gmshModelAddPhysicalGroup(3, [volumes.back()], t);
 
-gmshModelGeoAddVolume(186, shells);
+gmshModelGeoAddVolume(shells, 186);
       
-gmshModelAddPhysicalGroup(3, 10, [186]);
+gmshModelAddPhysicalGroup(3, [186], 10);
 gmshModelGeoSynchronize()
 gmshModelMesh(3)
 gmshExport("t5.msh")
diff --git a/demos/api/t6.cpp b/demos/api/t6.cpp
index da2a203436bb77dfbc9b252564c1c25b95abfdc2..579d6997eb77b3d8452d2009d37e98daeb9af3eb 100644
--- a/demos/api/t6.cpp
+++ b/demos/api/t6.cpp
@@ -9,23 +9,22 @@ int main(int argc, char **argv)
 
   gmshModelCreate("t2");
 
+
   // Copied from t1.cpp...
   double 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});
+  gmshModelGeoAddPoint(0, 0, 0, lc, 1);
+  gmshModelGeoAddPoint(.1, 0,  0, lc, 2);
+  gmshModelGeoAddPoint(.1, .3, 0, lc, 3);
+  gmshModelGeoAddPoint(0,  .3, 0, lc, 4);
+  gmshModelGeoAddLine(1, 2, 1);
+  gmshModelGeoAddLine(3, 2, 2);
+  gmshModelGeoAddLine(3, 4, 3);
+  gmshModelGeoAddLine(4, 1, 4);
+  gmshModelGeoAddLineLoop({4, 1, -2, 3}, 1);
+  gmshModelGeoAddPlaneSurface({1}, 1);
+  gmshModelAddPhysicalGroup(0, {1, 2}, 1);
+  gmshModelAddPhysicalGroup(1, {1, 2}, 2);
+  gmshModelAddPhysicalGroup(2, {1}, 6);
   gmshModelSetPhysicalName(2, 6, "My surface");
   // ...end of copy
 
@@ -33,15 +32,15 @@ int main(int argc, char **argv)
   gmshModelGeoRemove({{2,1}, {1,4}});
 
   // Replace left boundary with 3 new lines
-  int p1 = gmshModelGeoAddPoint(-1, -0.05, 0.05, 0, lc)[1];
-  int p2 = gmshModelGeoAddPoint(-1, -0.05, 0.1, 0, lc)[1];
-  int l1 = gmshModelGeoAddLine(-1, 1, p1)[1];
-  int l2 = gmshModelGeoAddLine(-1, p1, p2)[1];
-  int l3 = gmshModelGeoAddLine(-1, p2, 4)[1];
+  int p1 = gmshModelGeoAddPoint(-0.05, 0.05, 0, lc);
+  int p2 = gmshModelGeoAddPoint(-0.05, 0.1, 0, lc);
+  int l1 = gmshModelGeoAddLine(1, p1);
+  int l2 = gmshModelGeoAddLine(p1, p2);
+  int l3 = gmshModelGeoAddLine(p2, 4);
 
   // Recreate surface
-  gmshModelGeoAddLineLoop(2, {2, -1, l1, l2, l3, -3});
-  gmshModelGeoAddPlaneSurface(1, {-2});
+  gmshModelGeoAddLineLoop({2, -1, l1, l2, l3, -3}, 2);
+  gmshModelGeoAddPlaneSurface({-2}, 1);
 
   // Put 20 points with a refinement toward the extremities on curve 2
   gmshModelGeoSetTransfiniteLine(2, 20, "Bump", 0.05);
@@ -67,25 +66,25 @@ int main(int argc, char **argv)
 
   // Apply an elliptic smoother to the grid
   gmshOptionSetNumber("Mesh.Smoothing", 100);
-  gmshModelAddPhysicalGroup(2, 1, {1});
+  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});
+  gmshModelGeoAddPoint(0.2, 0.2, 0, 1.0, 7);
+  gmshModelGeoAddPoint(0.2, 0.1, 0, 1.0, 8);
+  gmshModelGeoAddPoint(0, 0.3, 0, 1.0, 9);
+  gmshModelGeoAddPoint(0.25, 0.2, 0, 1.0, 10);
+  gmshModelGeoAddPoint(0.3, 0.1, 0, 1.0, 11);
+  gmshModelGeoAddLine(8, 11, 10);
+  gmshModelGeoAddLine(11, 10, 11);
+  gmshModelGeoAddLine(10, 7, 12);
+  gmshModelGeoAddLine(7, 8, 13);
+  gmshModelGeoAddLineLoop({13, 10, 11, 12}, 14);
+  gmshModelGeoAddPlaneSurface({14}, 15);
   for(int i = 10; i <= 13; i++)
     gmshModelGeoSetTransfiniteLine(i, 10);
   gmshModelGeoSetTransfiniteSurface(15);
-  gmshModelAddPhysicalGroup(2, 2, {15});
+  gmshModelAddPhysicalGroup(2, {15}, 2);
 
   gmshModelMesh(2);
   gmshExport("t6.msh");
diff --git a/demos/api/t6.py b/demos/api/t6.py
index fbc64c7458cb5648850e1cfbe4f4c648a08eff9d..30a5bf14cd482a97239a7918e0585d4b74ee5f7d 100644
--- a/demos/api/t6.py
+++ b/demos/api/t6.py
@@ -10,21 +10,19 @@ 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])
+gmshModelGeoAddPoint(0, 0, 0, lc, 1)
+gmshModelGeoAddPoint(.1, 0,  0, lc, 2)
+gmshModelGeoAddPoint(.1, .3, 0, lc, 3)
+gmshModelGeoAddPoint(0, .3, 0, lc, 4)
+gmshModelGeoAddLine(1, 2, 1)
+gmshModelGeoAddLine(3, 2, 2)
+gmshModelGeoAddLine(3, 4, 3)
+gmshModelGeoAddLine(4, 1, 4)
+gmshModelGeoAddLineLoop([4, 1, -2, 3], 1)
+gmshModelGeoAddPlaneSurface([1], 1)
+gmshModelAddPhysicalGroup(0, [1, 2], 1)
+gmshModelAddPhysicalGroup(1, [1, 2], 2)
+gmshModelAddPhysicalGroup(2, [1], 6)
 gmshModelSetPhysicalName(2, 6, "My surface")
 # ...end of copy
 
@@ -32,15 +30,15 @@ gmshModelSetPhysicalName(2, 6, "My surface")
 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]
+p1 = gmshModelGeoAddPoint(-0.05, 0.05, 0, lc)
+p2 = gmshModelGeoAddPoint(-0.05, 0.1, 0, lc)
+l1 = gmshModelGeoAddLine(1, p1)
+l2 = gmshModelGeoAddLine(p1, p2)
+l3 = gmshModelGeoAddLine(p2, 4)
 
 # Recreate surface
-gmshModelGeoAddLineLoop(2, [2, -1, l1, l2, l3, -3])
-gmshModelGeoAddPlaneSurface(1, [-2])
+gmshModelGeoAddLineLoop([2, -1, l1, l2, l3, -3], 2)
+gmshModelGeoAddPlaneSurface([-2], 1)
 
 # Put 20 points with a refinement toward the extremities on curve 2
 gmshModelGeoSetTransfiniteLine(2, 20, "Bump", 0.05)
@@ -66,25 +64,25 @@ gmshModelGeoSetRecombine(2, 1)
 
 # Apply an elliptic smoother to the grid
 gmshOptionSetNumber("Mesh.Smoothing", 100)
-gmshModelAddPhysicalGroup(2, 1, [1])
+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])
+gmshModelGeoAddPoint(0.2, 0.2, 0, 1.0, 7)
+gmshModelGeoAddPoint(0.2, 0.1, 0, 1.0, 8)
+gmshModelGeoAddPoint(0, 0.3, 0, 1.0, 9)
+gmshModelGeoAddPoint(0.25, 0.2, 0, 1.0, 10)
+gmshModelGeoAddPoint(0.3, 0.1, 0, 1.0, 11)
+gmshModelGeoAddLine(8, 11, 10)
+gmshModelGeoAddLine(11, 10, 11)
+gmshModelGeoAddLine(10, 7, 12)
+gmshModelGeoAddLine(7, 8, 13)
+gmshModelGeoAddLineLoop([13, 10, 11, 12], 14)
+gmshModelGeoAddPlaneSurface([14], 15)
 for i in range(10,14):
     gmshModelGeoSetTransfiniteLine(i, 10)
 gmshModelGeoSetTransfiniteSurface(15)
-gmshModelAddPhysicalGroup(2, 2, [15])
+gmshModelAddPhysicalGroup(2, [15], 2)
 
 gmshModelMesh(2)
 gmshExport("t6.msh")
diff --git a/doc/texinfo/gmsh.texi b/doc/texinfo/gmsh.texi
index f645649b3bb3455828860c32ce8e6df91e2fa633..ba04d5467d2cbf2f847c15cd363a71426936a22c 100644
--- a/doc/texinfo/gmsh.texi
+++ b/doc/texinfo/gmsh.texi
@@ -3444,8 +3444,8 @@ being stored in @var{list-of-coords}). Defining @var{g}[@var{i}] =
 Sum(@var{j}=0, ..., @var{m}-1) @var{G}[@var{i}][@var{j}]
 @var{q}[@var{j}], with @var{q}[@var{j}] = @var{u}^@var{Q}[@var{j}][0]
 @var{v}^@var{Q}[@var{j}][1] @var{w}^@var{Q}[@var{j}][2], then
-@var{val-coef-matrix} denotes the @var{m} x @var{m} matrix @var{G} and
-@var{val-exp-matrix} denotes the @var{m} x @var{3} matrix @var{Q}.
+@var{geo-coef-matrix} denotes the @var{m} x @var{m} matrix @var{G} and
+@var{geo-exp-matrix} denotes the @var{m} x @var{3} matrix @var{Q}.
 
 Here are for example the interpolation matrices for a first order
 quadrangle: