diff --git a/CMakeLists.txt b/CMakeLists.txt
index f32171826d6aecf9a9c59a9ef28ba2103388e1ef..a1335759971411fa62f8167e6231828eaad5f2d0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1408,7 +1408,7 @@ if(NOOPT OR ENABLE_BUILD_IOS)
   set_compile_flags(NOOPT_SRC "-O0")
 endif(NOOPT OR ENABLE_BUILD_IOS)
 
-#enable Revoropt and set compile flags for the corresponding plugin
+# enable Revoropt and set compile flags for the corresponding plugin
 if(ENABLE_REVOROPT)
   find_path(EIGEN3_INC "eigen3/Eigen/Dense")
   if(EIGEN3_INC AND HAVE_MESH AND HAVE_PLUGINS AND HAVE_ANN AND HAVE_BFGS)
diff --git a/Common/gmsh.cpp b/Common/gmsh.cpp
index dd4d4077fdc1e7a6c72682250b390d559148885f..684ad366c86bbec7502badd4a9e6ce26b82dd983 100644
--- a/Common/gmsh.cpp
+++ b/Common/gmsh.cpp
@@ -4,6 +4,7 @@
 // bugs and problems to the public mailing list <gmsh@onelab.info>.
 
 #include "gmsh.h"
+#include "GmshConfig.h"
 #include "GmshGlobal.h"
 #include "GModel.h"
 #include "GModelIO_GEO.h"
@@ -22,6 +23,10 @@
 #include "MPyramid.h"
 #include "ExtrudeParams.h"
 
+#if defined(HAVE_MESH)
+#include "Field.h"
+#endif
+
 // gmsh
 
 int gmshInitialize(int argc, char **argv)
@@ -471,8 +476,8 @@ int gmshModelEmbed(const int dim, const std::vector<int> &tags,
 
 // gmshModelGeo
 
-int gmshModelGeoAddVertex(const int tag, const double x, const double y, const double z,
-                          int &outTag, const double meshSize)
+int gmshModelGeoAddPoint(const int tag, const double x, const double y, const double z,
+                         int &outTag, const double meshSize)
 {
   outTag = tag;
   return !GModel::current()->getGEOInternals()->addVertex(outTag, x, y, z, meshSize);
@@ -669,8 +674,8 @@ static void createOcc()
   if(!GModel::current()->getOCCInternals()) GModel::current()->createOCCInternals();
 }
 
-int gmshModelOccAddVertex(const int tag, const double x, const double y, const double z,
-                          int &outTag, const double meshSize)
+int gmshModelOccAddPoint(const int tag, const double x, const double y, const double z,
+                         int &outTag, const double meshSize)
 {
   createOcc();
   outTag = tag;
@@ -1037,8 +1042,7 @@ int gmshModelOccRemoveAllDuplicates()
 }
 
 int gmshModelOccImportShapes(const std::string &fileName, vector_pair &outDimTags,
-                             const bool highestDimOnly,
-                             const std::string &format)
+                             const bool highestDimOnly, const std::string &format)
 {
   createOcc();
   return !GModel::current()->getOCCInternals()->importShapes
@@ -1051,3 +1055,123 @@ int gmshModelOccSynchronize()
   GModel::current()->getOCCInternals()->synchronize(GModel::current());
   return 0;
 }
+
+// gmshModelField
+
+int gmshModelFieldAdd(const int tag, const std::string &type)
+{
+#if defined(HAVE_MESH)
+  if(!GModel::current()->getFields()->newField(tag, type)){
+    Msg::Error("Cannot create Field %i of type '%s'", tag, type.c_str());
+    return 1;
+  }
+  return 0;
+#else
+  return 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){
+    Msg::Error("No field with id %i", tag);
+    return 0;
+  }
+  FieldOption *o = field->options[option];
+  if(!o){
+    Msg::Error("Unknown option '%s' in field %i of type '%s'", option.c_str(),
+               tag, field->getName());
+    return 0;
+  }
+  return o;
+}
+#endif
+
+int gmshModelFieldSetNumber(const int tag, const std::string &option,
+                            const double value)
+{
+#if defined(HAVE_MESH)
+  FieldOption *o = getFieldOption(tag, option);
+  if(!o) return 1;
+  try { o->numericalValue(value); }
+  catch(...){
+    Msg::Error("Cannot set numerical value to option '%s' in field %i",
+               option.c_str(), tag);
+    return 1;
+  }
+  return 0;
+#else
+  return 1;
+#endif
+}
+
+int gmshModelFieldSetString(const int tag, const std::string &option,
+                            const std::string &value)
+{
+#if defined(HAVE_MESH)
+  FieldOption *o = getFieldOption(tag, option);
+  if(!o) return 1;
+  try { o->string(value); }
+  catch(...){
+    Msg::Error("Cannot set string value to option '%s' in field %i",
+               option.c_str(), tag);
+    return 1;
+  }
+  return 0;
+#else
+  return 1;
+#endif
+}
+
+int gmshModelFieldSetNumbers(const int tag, const std::string &option,
+                             const std::vector<double> &value)
+{
+#if defined(HAVE_MESH)
+  FieldOption *o = getFieldOption(tag, option);
+  if(!o) return 1;
+  try {
+    if(o->getType() == FIELD_OPTION_LIST) {
+      std::list<int> vl;
+      for(unsigned int i = 0; i < value.size(); i++)
+        vl.push_back((int)value[i]);
+      o->list(vl);
+    }
+    else{
+      std::list<double> vl;
+      for(unsigned int i = 0; i < value.size(); i++)
+        vl.push_back(value[i]);
+      o->listdouble(vl);
+    }
+  }
+  catch(...){
+    Msg::Error("Cannot set numeric values to option '%s' in field %i",
+               option.c_str(), tag);
+    return 1;
+  }
+  return 0;
+#else
+  return 1;
+#endif
+}
+
+int gmshModelFieldSetAsBackground(const int tag)
+{
+#if defined(HAVE_MESH)
+  GModel::current()->getFields()->setBackgroundFieldId(tag);
+  return 0;
+#else
+  return 1;
+#endif
+}
+
+int gmshModelFieldDelete(const int tag)
+{
+#if defined(HAVE_MESH)
+  GModel::current()->getFields()->deleteField(tag);
+  return 0;
+#else
+  return 1;
+#endif
+}
diff --git a/Common/gmsh.h b/Common/gmsh.h
index b895e7d25aee4402e8ebde130448a2f130e48ff3..bd21a51d20149e4209fa131c976740ebfb292f8a 100644
--- a/Common/gmsh.h
+++ b/Common/gmsh.h
@@ -88,8 +88,8 @@ GMSH_API gmshModelEmbed(const int dim, const std::vector<int> &tags, const int i
                         const int inTag);
 
 // gmshModelGeo
-GMSH_API gmshModelGeoAddVertex(const int tag, const double x, const double y,
-                               const double z, int &outTag, const double meshSize = 0.);
+GMSH_API gmshModelGeoAddPoint(const int tag, const double x, const double y,
+                              const double z, int &outTag, const double meshSize = 0.);
 GMSH_API gmshModelGeoAddLine(const int tag, const int startTag, const int endTag,
                              int &outTag);
 GMSH_API gmshModelGeoAddCircleArc(const int tag, const int startTag, const int centerTag,
@@ -154,8 +154,8 @@ GMSH_API gmshModelGeoRemoveAllDuplicates();
 GMSH_API gmshModelGeoSynchronize();
 
 // gmshModelOcc
-GMSH_API gmshModelOccAddVertex(const int tag, const double x, const double y,
-                               const double z, int &outTag, const double meshSize = 0.);
+GMSH_API gmshModelOccAddPoint(const int tag, const double x, const double y,
+                              const double z, int &outTag, const double meshSize = 0.);
 GMSH_API gmshModelOccAddLine(const int tag, const int startTag, const int endTag,
                              int &outTag);
 GMSH_API gmshModelOccAddCircleArc(const int tag, const int startTag, const int centerTag,
@@ -275,12 +275,22 @@ GMSH_API gmshModelOccSymmetry(const vector_pair &dimTags, const double a,
 GMSH_API gmshModelOccCopy(const vector_pair &inDimTags, vector_pair &outDimTags);
 GMSH_API gmshModelOccRemove(const vector_pair &dimTags, const bool recursive);
 GMSH_API gmshModelOccRemoveAllDuplicates();
-GMSH_API importShapes(const std::string &fileName, vector_pair &outDimTags,
-                      const bool highestDimOnly = true,
-                      const std::string &format = "");
+GMSH_API gmshModelOccImportShapes(const std::string &fileName, vector_pair &outDimTags,
+                                  const bool highestDimOnly = true,
+                                  const std::string &format = "");
 GMSH_API gmshModelOccSynchronize();
 
-// gmshField
+// gmshModelField
+
+GMSH_API gmshModelFieldAdd(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);
 
 // gmshSolver
 
diff --git a/Geo/GModel.cpp b/Geo/GModel.cpp
index e898cfe9c936740602b96705a09c0a0e32de892d..b75eebe0d2a865fe14e14050428a026203a22b56 100644
--- a/Geo/GModel.cpp
+++ b/Geo/GModel.cpp
@@ -2488,7 +2488,7 @@ void GModel::createTopologyFromMesh()
   Msg::StatusBar(true, "Done creating topology from mesh (%g s)", t2 - t1);
 }
 
-void makeSimplyConnected(std::map<int, std::vector<MElement*> > elements[11])
+static void makeSimplyConnected(std::map<int, std::vector<MElement*> > elements[11])
 {
   //only for tetras and triangles
   Msg::Info("Make simply connected regions and surfaces");
diff --git a/Geo/MElement.h b/Geo/MElement.h
index f9e20c25ce9964a0b6524f4f87c4f5da4f082199..2d39d73929e3f26d6b2c6bc87c2c898382005bf4 100644
--- a/Geo/MElement.h
+++ b/Geo/MElement.h
@@ -424,8 +424,9 @@ class MElement
 
 class MElementFactory{
  public:
-  MElement *create(int type, std::vector< MVertex* > &v, int num=0, int part=0,
-                   bool owner=false, int parent=0, MElement *parent_ptr=NULL, MElement *d1 = 0, MElement *d2 = 0);
+  MElement *create(int type, std::vector< MVertex* > &v, int num = 0, int part = 0,
+                   bool owner = false, int parent = 0, MElement *parent_ptr = NULL,
+                   MElement *d1 = 0, MElement *d2 = 0);
   MElement *create(int num, int type, const std::vector<int> &data, GModel *model);
 };
 
diff --git a/demos/api/t1.cpp b/demos/api/t1.cpp
index 22b9320bd6ee5c53ea5cffdacbb607d78a06ef42..8b4eeff0674f16da3112b14b3c71178831dc572c 100644
--- a/demos/api/t1.cpp
+++ b/demos/api/t1.cpp
@@ -11,10 +11,10 @@ int main(int argc, char **argv)
 
   double lc = 1e-2;
   int o;
-  gmshModelGeoAddVertex(1, 0, 0, 0, o, lc);
-  gmshModelGeoAddVertex(2, .1, 0,  0, o, lc);
-  gmshModelGeoAddVertex(3, .1, .3, 0, o, lc);
-  gmshModelGeoAddVertex(4, 0,  .3, 0, o, lc);
+  gmshModelGeoAddPoint(1, 0, 0, 0, o, lc);
+  gmshModelGeoAddPoint(2, .1, 0,  0, o, lc);
+  gmshModelGeoAddPoint(3, .1, .3, 0, o, lc);
+  gmshModelGeoAddPoint(4, 0,  .3, 0, o, lc);
 
   gmshModelGeoAddLine(1, 1, 2, o);
   gmshModelGeoAddLine(2, 3, 2, o);
diff --git a/demos/api/t10.cpp b/demos/api/t10.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..551d532ed399cf9d6f99bd3595b1f670db950a6c
--- /dev/null
+++ b/demos/api/t10.cpp
@@ -0,0 +1,69 @@
+#include <gmsh.h>
+#include <sstream>
+
+// this reimplements gmsh/tutorial/t10.geo
+
+int main(int argc, char **argv)
+{
+  gmshInitialize(argc, argv);
+  gmshOptionSetNumber("General.Terminal", 1);
+
+  gmshModelCreate("t1");
+
+  int o;
+  double lc = .15;
+  gmshModelGeoAddPoint(1, 0.0,0.0,0, o,lc);
+  gmshModelGeoAddPoint(2, 1,0.0,0, o,lc);
+  gmshModelGeoAddPoint(3, 1,1,0, o,lc);
+  gmshModelGeoAddPoint(4, 0,1,0, o,lc);
+  gmshModelGeoAddPoint(5, 0.2,.5,0, o,lc);
+
+  gmshModelGeoAddLine(1, 1,2, o);
+  gmshModelGeoAddLine(2, 2,3, o);
+  gmshModelGeoAddLine(3, 3,4, o);
+  gmshModelGeoAddLine(4, 4,1, o);
+
+  gmshModelGeoAddLineLoop(5, {1,2,3,4}, o);
+  gmshModelGeoAddPlaneSurface(6, {5}, o);
+
+  gmshModelFieldAdd(1, "Attractor");
+  gmshModelFieldSetNumbers(1, "NodesList", {5});
+  gmshModelFieldSetNumber(1, "NNodesByEdge", 100);
+  gmshModelFieldSetNumbers(1, "EdgesList", {2});
+
+  gmshModelFieldAdd(2, "Threshold");
+  gmshModelFieldSetNumber(2, "IField", 1);
+  gmshModelFieldSetNumber(2, "LcMin", lc / 30);
+  gmshModelFieldSetNumber(2, "LcMax", lc);
+  gmshModelFieldSetNumber(2, "DistMin", 0.15);
+  gmshModelFieldSetNumber(2, "DistMax", 0.5);
+
+  gmshModelFieldAdd(3, "MathEval");
+  gmshModelFieldSetString(3, "F", "Cos(4*3.14*x) * Sin(4*3.14*y) / 10 + 0.101");
+
+  gmshModelFieldAdd(4, "Attractor");
+  gmshModelFieldSetNumbers(4, "NodesList", {1});
+
+  gmshModelFieldAdd(5, "MathEval");
+  std::stringstream stream;
+  stream << "F4^3 + " << lc / 100;
+  gmshModelFieldSetString(5, "F", stream.str());
+
+  gmshModelFieldAdd(6, "Box");
+  gmshModelFieldSetNumber(6, "VIn", lc / 15);
+  gmshModelFieldSetNumber(6, "VOut", lc);
+  gmshModelFieldSetNumber(6, "XMin", 0.3);
+  gmshModelFieldSetNumber(6, "XMax", 0.6);
+  gmshModelFieldSetNumber(6, "YMin", 0.3);
+  gmshModelFieldSetNumber(6, "YMax", 0.6);
+
+  gmshModelFieldAdd(7, "Min");
+  gmshModelFieldSetNumbers(7, "FieldsList", {2, 3, 5, 6});
+
+  gmshModelFieldSetAsBackground(7);
+
+  gmshModelGeoSynchronize();
+  gmshModelMesh(2);
+  gmshExport("t10.msh");
+  return 0;
+}
diff --git a/tutorial/t13.geo b/tutorial/t13.geo
index 7ab78936bbad37f60e518f3b06d87be39cfe62fe..2930151910b697fb147053485f5bc68faac79567 100644
--- a/tutorial/t13.geo
+++ b/tutorial/t13.geo
@@ -32,7 +32,7 @@ Compound Surface{ss[]};
 
 // element size imposed by a size field
 Field[1] = MathEval;
-Field[1].F = "1.5";
+Field[1].F = "4";
 Background Field = 1;
 
 funny = DefineNumber[0, Choices{0,1}, Name "Parameters/Apply funny mesh size field?" ];