diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index 211947114619783be54cc2ca29504acf124480b0..82cb863927feb3312da2adce42467252bc233281 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -3,10 +3,10 @@
 functions to reduce the number of synchronizations for complex models; small bug
 fixes.
 
-* Incompatible API changes: new optional argument to mesh/clear; new argument to
-  mesh/getBasisFunctions; removed mesh/preallocateBasisFunctions,
-  mesh/precomputeBasisFunctions and mesh/getBasisFunctionsForElements; renamed
-  occ/setMeshSize as occ/mesh/setSize
+* Incompatible API changes: new optional arguments to mesh/clear and
+  mesh/createTopology; new argument to mesh/getBasisFunctions; removed
+  mesh/preallocateBasisFunctions, mesh/precomputeBasisFunctions and
+  mesh/getBasisFunctionsForElements; renamed occ/setMeshSize as occ/mesh/setSize
 
 4.5.6 (March 30, 2020): better calculation of OCC bounding boxes using STL; API
 tutorials; small bug fixes.
diff --git a/Common/gmsh.cpp b/Common/gmsh.cpp
index 7312c2f478651bfa8557a20a8df3b58139986d77..f938b53ac9aa9d484ee10d3666b1eb58f5f4d275 100644
--- a/Common/gmsh.cpp
+++ b/Common/gmsh.cpp
@@ -3920,10 +3920,20 @@ GMSH_API void gmsh::model::mesh::createGeometry()
   GModel::current()->createGeometryOfDiscreteEntities();
 }
 
-GMSH_API void gmsh::model::mesh::createTopology()
+GMSH_API void gmsh::model::mesh::createTopology(const bool makeSimplyConnected,
+                                                const bool exportDiscrete)
 {
   if(!_isInitialized()) { throw - 1; }
+
+  if(makeSimplyConnected) {
+    GModel::current()->makeDiscreteRegionsSimplyConnected();
+    GModel::current()->makeDiscreteFacesSimplyConnected();
+  }
   GModel::current()->createTopologyFromMesh();
+  if(exportDiscrete) {
+    // Warning: this clears GEO_Internals!
+    GModel::current()->exportDiscreteGEOInternals();
+  }
 }
 
 GMSH_API void
diff --git a/Geo/GModel.cpp b/Geo/GModel.cpp
index 66634544d95110e8fc0059e328e6f99ae6e14b2a..0c8524118af5f429b8d45eed9ce836e7ea1b44f4 100644
--- a/Geo/GModel.cpp
+++ b/Geo/GModel.cpp
@@ -41,7 +41,6 @@
 #include "OpenFile.h"
 #include "CreateFile.h"
 #include "Options.h"
-#include "GModelCreateTopologyFromMesh.h"
 #include "GModelParametrize.h"
 
 #if defined(HAVE_MESH)
@@ -2725,14 +2724,6 @@ void GModel::makeDiscreteFacesSimplyConnected()
   Msg::Info("Done making discrete faces simply connected");
 }
 
-void GModel::createTopologyFromMesh()
-{
-  makeDiscreteRegionsSimplyConnected();
-  makeDiscreteFacesSimplyConnected();
-  createTopologyFromMeshNew();
-  exportDiscreteGEOInternals();
-}
-
 static void
 makeSimplyConnected(std::map<int, std::vector<MElement *> > elements[11])
 {
diff --git a/Geo/GModel.h b/Geo/GModel.h
index 0ca29be06ae702318bf9ed2032e4caee1ab4ff93..429f51f6fe048fc5ef7734d4c961a4c972a8c666 100644
--- a/Geo/GModel.h
+++ b/Geo/GModel.h
@@ -605,12 +605,13 @@ public:
   // discrete entities
   void createGeometryOfDiscreteEntities();
 
-  // create topology from mesh
-  void createTopologyFromMeshNew();
-  void createTopologyFromMesh();
+  // make discrete entities simply connected
   void makeDiscreteRegionsSimplyConnected();
   void makeDiscreteFacesSimplyConnected();
 
+  // create topology from mesh
+  void createTopologyFromMesh();
+
   // align periodic boundaries
   void alignPeriodicBoundaries();
 
diff --git a/Geo/GModelCreateTopologyFromMesh.cpp b/Geo/GModelCreateTopologyFromMesh.cpp
index a4f5c476819df565806255e503606626b5caff45..fa2538e69cd4d4af328b29ed38b170832a70bec2 100644
--- a/Geo/GModelCreateTopologyFromMesh.cpp
+++ b/Geo/GModelCreateTopologyFromMesh.cpp
@@ -6,8 +6,8 @@
 #include <stack>
 #include <set>
 #include <map>
+#include <sstream>
 #include "OS.h"
-#include "GModelCreateTopologyFromMesh.h"
 #include "GModel.h"
 #include "discreteFace.h"
 #include "discreteEdge.h"
@@ -23,8 +23,7 @@
 #include "MHexahedron.h"
 #include "MPrism.h"
 #include "MPyramid.h"
-
-#include <sstream>
+#include "Context.h"
 
 // Assumption: The input mesh is potentially (partially) coloured
 
@@ -45,7 +44,7 @@ bool topoExists(GModel *gm)
   return true;
 }
 
-// FIXME : To TIMES THE SAME MLINE IN EACH CONNECTED PART IF PERIODIC
+// FIXME: Two times the same MLine in each connected part if periodic
 std::vector<GEdge *> ensureSimplyConnectedEdge(GEdge *ge)
 {
   std::vector<GEdge *> _all;
@@ -54,7 +53,7 @@ std::vector<GEdge *> ensureSimplyConnectedEdge(GEdge *ge)
 
   _all.push_back(ge);
 
-  // create vertex to edge connectivity : only To neighbors are considered ...
+  // create vertex to edge connectivity: only two neighbors are considered...
   for(std::size_t i = 0; i < ge->lines.size(); i++) {
     _lines.insert(ge->lines[i]);
     for(int j = 0; j < 2; j++) {
@@ -221,13 +220,13 @@ void createTopologyFromMesh1D(GModel *gm, int &num)
     if(gv->mesh_vertices.size()) {
       MVertex *mv = gv->mesh_vertices[0];
       mVertexToGVertex[mv] = gv;
-      Msg::Info("The model already has point %i, containing node %i",
-                gv->tag(), mv->getNum());
+      Msg::Debug("The model already has point %i, containing node %i",
+                 gv->tag(), mv->getNum());
     }
   }
 
-  // create bundles of edges for each MVertex on the GEdge
-  // if GVertex already present, link it to the GEdge
+  // create bundles of edges for each MVertex on the GEdge; if GVertex already
+  // present, link it to the GEdge
 
   MVertexToGEdgesMap mVertexToGEdges;
   GEdgeToGVerticesMap gEdgeToGVertices;
@@ -280,9 +279,8 @@ void createTopologyFromMesh1D(GModel *gm, int &num)
     }
   }
 
-  // link all GEdge to GVertex and vice versa
-  // we expect to see two GVertex per GEdge
-  // unless it is periodic !!!!
+  // link all GEdge to GVertex and vice versa (we expect to see two GVertex per
+  // GEdge unless it is periodic!)
 
   for(GEdgeToGVerticesMap::iterator gEIter = gEdgeToGVertices.begin();
       gEIter != gEdgeToGVertices.end(); ++gEIter) {
@@ -321,8 +319,8 @@ void createTopologyFromMesh1D(GModel *gm, int &num)
     }
   }
 
-  // add GVertex for self-intersecting GEdge
-  // we still need to check this is actually the case ...
+  // add GVertex for self-intersecting GEdge; we still need to check this is
+  // actually the case...
 
   for(GModel::eiter it = gm->firstEdge(); it != gm->lastEdge(); it++) {
     if(!(*it)->getBeginVertex() || !(*it)->getEndVertex()) {
@@ -570,8 +568,8 @@ void createTopologyFromMesh3D(GModel *gm, int &num)
     }
   }
 
-  // create inverse dictionary for all other faces
-  // This is the most time consuming part !
+  // create inverse dictionary for all other faces; this is the most time
+  // consuming part!
 
   TFaceToGRegionPairMap tFaceToGRegionPair;
   GRegionToGFacesMap gRegionToGFaces;
@@ -680,17 +678,16 @@ void createTopologyFromMesh3D(GModel *gm, int &num)
   }
 }
 
-void GModel::createTopologyFromMeshNew()
+void GModel::createTopologyFromMesh()
 {
-  const int dim = getDim();
-
-  double t1 = Cpu(), w1 = TimeOfDay();
-
   if(topoExists(this)) {
     Msg::Info("Topology exists: no need to create one from mesh");
     return;
   }
 
+  const int dim = getDim();
+  double t1 = Cpu(), w1 = TimeOfDay();
+
   Msg::Info("Creating topology from mesh...");
   int numF = 0, numE = 0, numV = 0;
   if(dim >= 3)
@@ -714,6 +711,8 @@ void GModel::createTopologyFromMeshNew()
   cc.insert(cc.begin(), vs.begin(), vs.end());
   _storeVerticesInEntities(cc);
 
+  CTX::instance()->mesh.changed = ENT_ALL;
+
   double t2 = Cpu(), w2 = TimeOfDay();
   Msg::Info("Done creating topology from mesh (Wall %gs, CPU %gs)",
             w2 - w1, t2 - t1);
diff --git a/Geo/GModelIO_CGNS.cpp b/Geo/GModelIO_CGNS.cpp
index 26ee9c635163d9beb3220473c958eb89d839a6c0..3933ecf4c916b19fdb6a91b26c25eb3ec6e34afa 100644
--- a/Geo/GModelIO_CGNS.cpp
+++ b/Geo/GModelIO_CGNS.cpp
@@ -48,7 +48,7 @@ int GModel::readCGNS(const std::string &name,
   // index start at 1 with empty name to account for unclassified elements
   std::vector<std::string> allGeomName(2, "");
 
-  // read number of zones (allZones[0] is dummy because index starts at 1) 
+  // read number of zones (allZones[0] is dummy because index starts at 1)
   int nbZone = 0;
   cgnsErr = cg_nzones(fileIndex, baseIndex, &nbZone);
   if(cgnsErr != CG_OK) return cgnsError(__FILE__, __LINE__, fileIndex);
@@ -63,7 +63,7 @@ int GModel::readCGNS(const std::string &name,
   // data structures for element and vertices
   std::vector<MVertex *> allVert;                     // all vertices
   std::map<int, std::vector<MElement *> > allElt[10]; // all elements by type
-  
+
    // vertex and element (global) tags per zone for postpro
   vertPerZone.resize(nbZone+1);
   eltPerZone.resize(nbZone+1);
@@ -105,7 +105,7 @@ int GModel::readCGNS(const std::string &name,
   setPeriodicityInEntities(allZones);
 
   // remove potential duplicate vertices if several zones (keeping vertices
-  // classified on entities of lowest dimension) 
+  // classified on entities of lowest dimension)
   // TODO: disable this through option ?
   if(nbZone > 1) removeDuplicateMeshVertices(CTX::instance()->geom.tolerance);
 
@@ -118,7 +118,7 @@ int GModel::readCGNS(const std::string &name,
   }
 
   // reconstruct geometrical topology if required
-  if(CTX::instance()->mesh.cgnsConstructTopology) createTopologyFromMeshNew();
+  if(CTX::instance()->mesh.cgnsConstructTopology) createTopologyFromMesh();
 
   return postpro ? 2 : 1;
 }
diff --git a/Parser/Gmsh.tab.cpp b/Parser/Gmsh.tab.cpp
index 8717a77d3ca87aace8cc6e975df6328630031dd3..30eff827af8fa02b32ada47667d43d99cf2f0edc 100644
--- a/Parser/Gmsh.tab.cpp
+++ b/Parser/Gmsh.tab.cpp
@@ -1503,42 +1503,42 @@ static const yytype_uint16 yyrline[] =
     3095,  3117,  3129,  3135,  3150,  3181,  3193,  3202,  3209,  3221,
     3241,  3245,  3250,  3254,  3259,  3266,  3273,  3280,  3292,  3365,
     3383,  3408,  3423,  3456,  3468,  3500,  3504,  3509,  3516,  3521,
-    3531,  3536,  3542,  3550,  3554,  3558,  3562,  3566,  3570,  3574,
-    3586,  3595,  3659,  3675,  3692,  3709,  3731,  3753,  3788,  3796,
-    3804,  3810,  3817,  3824,  3844,  3870,  3882,  3893,  3911,  3929,
-    3948,  3947,  3972,  3971,  3998,  3997,  4022,  4021,  4044,  4060,
-    4077,  4094,  4117,  4145,  4148,  4154,  4166,  4186,  4190,  4194,
-    4198,  4202,  4206,  4210,  4214,  4223,  4236,  4237,  4238,  4239,
-    4240,  4244,  4245,  4246,  4247,  4248,  4251,  4275,  4294,  4317,
-    4320,  4336,  4339,  4356,  4359,  4365,  4368,  4375,  4378,  4385,
-    4407,  4448,  4492,  4531,  4556,  4568,  4580,  4592,  4604,  4621,
-    4638,  4668,  4694,  4720,  4752,  4779,  4805,  4831,  4857,  4883,
-    4905,  4916,  4964,  5018,  5033,  5045,  5056,  5063,  5078,  5092,
-    5093,  5094,  5098,  5104,  5116,  5134,  5162,  5163,  5164,  5165,
-    5166,  5167,  5168,  5169,  5170,  5177,  5178,  5179,  5180,  5181,
-    5182,  5183,  5184,  5185,  5186,  5187,  5188,  5189,  5190,  5191,
-    5192,  5193,  5194,  5195,  5196,  5197,  5198,  5199,  5200,  5201,
-    5202,  5203,  5204,  5205,  5206,  5207,  5208,  5209,  5210,  5211,
-    5212,  5213,  5214,  5215,  5216,  5225,  5226,  5227,  5228,  5229,
-    5230,  5231,  5232,  5233,  5234,  5235,  5240,  5239,  5247,  5249,
-    5254,  5259,  5263,  5268,  5273,  5277,  5281,  5285,  5289,  5293,
-    5297,  5303,  5318,  5322,  5328,  5333,  5352,  5372,  5393,  5397,
-    5401,  5405,  5409,  5413,  5417,  5422,  5432,  5442,  5447,  5458,
-    5467,  5472,  5477,  5505,  5506,  5512,  5513,  5519,  5518,  5541,
-    5543,  5548,  5550,  5556,  5557,  5562,  5566,  5570,  5574,  5578,
-    5585,  5589,  5593,  5597,  5604,  5609,  5616,  5621,  5625,  5630,
-    5634,  5642,  5653,  5657,  5661,  5675,  5683,  5691,  5698,  5708,
-    5731,  5736,  5742,  5747,  5753,  5764,  5770,  5784,  5790,  5802,
-    5816,  5826,  5836,  5846,  5858,  5862,  5867,  5879,  5883,  5887,
-    5891,  5909,  5917,  5925,  5954,  5964,  5980,  5991,  5996,  6000,
-    6004,  6016,  6020,  6032,  6049,  6059,  6063,  6078,  6083,  6090,
-    6094,  6099,  6113,  6127,  6131,  6135,  6139,  6143,  6151,  6157,
-    6166,  6170,  6174,  6182,  6188,  6194,  6198,  6205,  6213,  6220,
-    6229,  6233,  6237,  6252,  6266,  6280,  6292,  6308,  6317,  6326,
-    6336,  6347,  6355,  6363,  6367,  6386,  6393,  6399,  6405,  6412,
-    6420,  6419,  6429,  6453,  6455,  6461,  6466,  6468,  6473,  6478,
-    6483,  6485,  6489,  6501,  6515,  6519,  6526,  6534,  6542,  6553,
-    6555,  6558
+    3531,  3536,  3542,  3550,  3558,  3562,  3566,  3570,  3574,  3578,
+    3590,  3599,  3663,  3679,  3696,  3713,  3735,  3757,  3792,  3800,
+    3808,  3814,  3821,  3828,  3848,  3874,  3886,  3897,  3915,  3933,
+    3952,  3951,  3976,  3975,  4002,  4001,  4026,  4025,  4048,  4064,
+    4081,  4098,  4121,  4149,  4152,  4158,  4170,  4190,  4194,  4198,
+    4202,  4206,  4210,  4214,  4218,  4227,  4240,  4241,  4242,  4243,
+    4244,  4248,  4249,  4250,  4251,  4252,  4255,  4279,  4298,  4321,
+    4324,  4340,  4343,  4360,  4363,  4369,  4372,  4379,  4382,  4389,
+    4411,  4452,  4496,  4535,  4560,  4572,  4584,  4596,  4608,  4625,
+    4642,  4672,  4698,  4724,  4756,  4783,  4809,  4835,  4861,  4887,
+    4909,  4920,  4968,  5022,  5037,  5049,  5060,  5067,  5082,  5096,
+    5097,  5098,  5102,  5108,  5120,  5138,  5166,  5167,  5168,  5169,
+    5170,  5171,  5172,  5173,  5174,  5181,  5182,  5183,  5184,  5185,
+    5186,  5187,  5188,  5189,  5190,  5191,  5192,  5193,  5194,  5195,
+    5196,  5197,  5198,  5199,  5200,  5201,  5202,  5203,  5204,  5205,
+    5206,  5207,  5208,  5209,  5210,  5211,  5212,  5213,  5214,  5215,
+    5216,  5217,  5218,  5219,  5220,  5229,  5230,  5231,  5232,  5233,
+    5234,  5235,  5236,  5237,  5238,  5239,  5244,  5243,  5251,  5253,
+    5258,  5263,  5267,  5272,  5277,  5281,  5285,  5289,  5293,  5297,
+    5301,  5307,  5322,  5326,  5332,  5337,  5356,  5376,  5397,  5401,
+    5405,  5409,  5413,  5417,  5421,  5426,  5436,  5446,  5451,  5462,
+    5471,  5476,  5481,  5509,  5510,  5516,  5517,  5523,  5522,  5545,
+    5547,  5552,  5554,  5560,  5561,  5566,  5570,  5574,  5578,  5582,
+    5589,  5593,  5597,  5601,  5608,  5613,  5620,  5625,  5629,  5634,
+    5638,  5646,  5657,  5661,  5665,  5679,  5687,  5695,  5702,  5712,
+    5735,  5740,  5746,  5751,  5757,  5768,  5774,  5788,  5794,  5806,
+    5820,  5830,  5840,  5850,  5862,  5866,  5871,  5883,  5887,  5891,
+    5895,  5913,  5921,  5929,  5958,  5968,  5984,  5995,  6000,  6004,
+    6008,  6020,  6024,  6036,  6053,  6063,  6067,  6082,  6087,  6094,
+    6098,  6103,  6117,  6131,  6135,  6139,  6143,  6147,  6155,  6161,
+    6170,  6174,  6178,  6186,  6192,  6198,  6202,  6209,  6217,  6224,
+    6233,  6237,  6241,  6256,  6270,  6284,  6296,  6312,  6321,  6330,
+    6340,  6351,  6359,  6367,  6371,  6390,  6397,  6403,  6409,  6416,
+    6424,  6423,  6433,  6457,  6459,  6465,  6470,  6472,  6477,  6482,
+    6487,  6489,  6493,  6505,  6519,  6523,  6530,  6538,  6546,  6557,
+    6559,  6562
 };
 #endif
 
@@ -10665,47 +10665,51 @@ yyreduce:
   case 283:
 #line 3551 "Gmsh.y"
     {
+      GModel::current()->makeDiscreteRegionsSimplyConnected();
+      GModel::current()->makeDiscreteFacesSimplyConnected();
       GModel::current()->createTopologyFromMesh();
+      // Warning: this clears GEO_Internals! Make it optional?
+      GModel::current()->exportDiscreteGEOInternals();
     ;}
     break;
 
   case 284:
-#line 3555 "Gmsh.y"
+#line 3559 "Gmsh.y"
     {
       GModel::current()->classifySurfaces((yyvsp[(3) - (9)].d), (yyvsp[(5) - (9)].d), (yyvsp[(7) - (9)].d), M_PI);
     ;}
     break;
 
   case 285:
-#line 3559 "Gmsh.y"
+#line 3563 "Gmsh.y"
     {
       GModel::current()->classifySurfaces((yyvsp[(3) - (11)].d), (yyvsp[(5) - (11)].d), (yyvsp[(7) - (11)].d), (yyvsp[(9) - (11)].d));
     ;}
     break;
 
   case 286:
-#line 3563 "Gmsh.y"
+#line 3567 "Gmsh.y"
     {
       GModel::current()->createGeometryOfDiscreteEntities();
     ;}
     break;
 
   case 287:
-#line 3567 "Gmsh.y"
+#line 3571 "Gmsh.y"
     {
       GModel::current()->renumberMeshVertices();
     ;}
     break;
 
   case 288:
-#line 3571 "Gmsh.y"
+#line 3575 "Gmsh.y"
     {
       GModel::current()->renumberMeshElements();
     ;}
     break;
 
   case 289:
-#line 3575 "Gmsh.y"
+#line 3579 "Gmsh.y"
     {
       if(GModel::current()->getOCCInternals() &&
          GModel::current()->getOCCInternals()->getChanged())
@@ -10720,7 +10724,7 @@ yyreduce:
     break;
 
   case 290:
-#line 3587 "Gmsh.y"
+#line 3591 "Gmsh.y"
     {
       if(GModel::current()->getOCCInternals() &&
          GModel::current()->getOCCInternals()->getChanged())
@@ -10732,7 +10736,7 @@ yyreduce:
     break;
 
   case 291:
-#line 3597 "Gmsh.y"
+#line 3601 "Gmsh.y"
     {
       int lock = CTX::instance()->lock;
       CTX::instance()->lock = 0;
@@ -10793,7 +10797,7 @@ yyreduce:
     break;
 
   case 292:
-#line 3660 "Gmsh.y"
+#line 3664 "Gmsh.y"
     {
 #if defined(HAVE_POPPLER)
        std::vector<int> is;
@@ -10808,7 +10812,7 @@ yyreduce:
     break;
 
   case 293:
-#line 3676 "Gmsh.y"
+#line 3680 "Gmsh.y"
     {
       LoopControlVariablesTab[ImbricatedLoop][0] = (yyvsp[(3) - (6)].d);
       LoopControlVariablesTab[ImbricatedLoop][1] = (yyvsp[(5) - (6)].d);
@@ -10828,7 +10832,7 @@ yyreduce:
     break;
 
   case 294:
-#line 3693 "Gmsh.y"
+#line 3697 "Gmsh.y"
     {
       LoopControlVariablesTab[ImbricatedLoop][0] = (yyvsp[(3) - (8)].d);
       LoopControlVariablesTab[ImbricatedLoop][1] = (yyvsp[(5) - (8)].d);
@@ -10848,7 +10852,7 @@ yyreduce:
     break;
 
   case 295:
-#line 3710 "Gmsh.y"
+#line 3714 "Gmsh.y"
     {
       LoopControlVariablesTab[ImbricatedLoop][0] = (yyvsp[(5) - (8)].d);
       LoopControlVariablesTab[ImbricatedLoop][1] = (yyvsp[(7) - (8)].d);
@@ -10873,7 +10877,7 @@ yyreduce:
     break;
 
   case 296:
-#line 3732 "Gmsh.y"
+#line 3736 "Gmsh.y"
     {
       LoopControlVariablesTab[ImbricatedLoop][0] = (yyvsp[(5) - (10)].d);
       LoopControlVariablesTab[ImbricatedLoop][1] = (yyvsp[(7) - (10)].d);
@@ -10898,7 +10902,7 @@ yyreduce:
     break;
 
   case 297:
-#line 3754 "Gmsh.y"
+#line 3758 "Gmsh.y"
     {
       if(ImbricatedLoop <= 0){
 	yymsg(0, "Invalid For/EndFor loop");
@@ -10936,7 +10940,7 @@ yyreduce:
     break;
 
   case 298:
-#line 3789 "Gmsh.y"
+#line 3793 "Gmsh.y"
     {
       if(!FunctionManager::Instance()->createFunction
          (std::string((yyvsp[(2) - (2)].c)), gmsh_yyin, gmsh_yyname, gmsh_yylineno))
@@ -10947,7 +10951,7 @@ yyreduce:
     break;
 
   case 299:
-#line 3797 "Gmsh.y"
+#line 3801 "Gmsh.y"
     {
       if(!FunctionManager::Instance()->createFunction
          (std::string((yyvsp[(2) - (2)].c)), gmsh_yyin, gmsh_yyname, gmsh_yylineno))
@@ -10958,7 +10962,7 @@ yyreduce:
     break;
 
   case 300:
-#line 3805 "Gmsh.y"
+#line 3809 "Gmsh.y"
     {
       if(!FunctionManager::Instance()->leaveFunction
          (&gmsh_yyin, gmsh_yyname, gmsh_yylineno))
@@ -10967,7 +10971,7 @@ yyreduce:
     break;
 
   case 301:
-#line 3811 "Gmsh.y"
+#line 3815 "Gmsh.y"
     {
       if(!FunctionManager::Instance()->enterFunction
          (std::string((yyvsp[(2) - (3)].c)), &gmsh_yyin, gmsh_yyname, gmsh_yylineno))
@@ -10977,7 +10981,7 @@ yyreduce:
     break;
 
   case 302:
-#line 3818 "Gmsh.y"
+#line 3822 "Gmsh.y"
     {
       if(!FunctionManager::Instance()->enterFunction
          (std::string((yyvsp[(2) - (3)].c)), &gmsh_yyin, gmsh_yyname, gmsh_yylineno))
@@ -10987,7 +10991,7 @@ yyreduce:
     break;
 
   case 303:
-#line 3825 "Gmsh.y"
+#line 3829 "Gmsh.y"
     {
       ImbricatedTest++;
       if(ImbricatedTest > MAX_RECUR_TESTS-1){
@@ -11010,7 +11014,7 @@ yyreduce:
     break;
 
   case 304:
-#line 3845 "Gmsh.y"
+#line 3849 "Gmsh.y"
     {
       if(ImbricatedTest > 0){
         if (statusImbricatedTests[ImbricatedTest]){
@@ -11039,7 +11043,7 @@ yyreduce:
     break;
 
   case 305:
-#line 3871 "Gmsh.y"
+#line 3875 "Gmsh.y"
     {
       if(ImbricatedTest > 0){
         if(statusImbricatedTests[ImbricatedTest]){
@@ -11054,7 +11058,7 @@ yyreduce:
     break;
 
   case 306:
-#line 3883 "Gmsh.y"
+#line 3887 "Gmsh.y"
     {
       ImbricatedTest--;
       if(ImbricatedTest < 0)
@@ -11063,7 +11067,7 @@ yyreduce:
     break;
 
   case 307:
-#line 3894 "Gmsh.y"
+#line 3898 "Gmsh.y"
     {
       std::vector<std::pair<int, int> > inDimTags, outDimTags;
       ListOfShapes2VectorOfPairs((yyvsp[(4) - (5)].l), inDimTags);
@@ -11084,7 +11088,7 @@ yyreduce:
     break;
 
   case 308:
-#line 3912 "Gmsh.y"
+#line 3916 "Gmsh.y"
     {
       std::vector<std::pair<int, int> > inDimTags, outDimTags;
       ListOfShapes2VectorOfPairs((yyvsp[(10) - (11)].l), inDimTags);
@@ -11105,7 +11109,7 @@ yyreduce:
     break;
 
   case 309:
-#line 3930 "Gmsh.y"
+#line 3934 "Gmsh.y"
     {
       std::vector<std::pair<int, int> > inDimTags, outDimTags;
       ListOfShapes2VectorOfPairs((yyvsp[(12) - (13)].l), inDimTags);
@@ -11126,7 +11130,7 @@ yyreduce:
     break;
 
   case 310:
-#line 3948 "Gmsh.y"
+#line 3952 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = extr.mesh.Recombine = false;
       extr.mesh.QuadToTri = NO_QUADTRI;
@@ -11135,7 +11139,7 @@ yyreduce:
     break;
 
   case 311:
-#line 3954 "Gmsh.y"
+#line 3958 "Gmsh.y"
     {
       std::vector<std::pair<int, int> > inDimTags, outDimTags;
       ListOfShapes2VectorOfPairs((yyvsp[(4) - (7)].l), inDimTags);
@@ -11156,7 +11160,7 @@ yyreduce:
     break;
 
   case 312:
-#line 3972 "Gmsh.y"
+#line 3976 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = extr.mesh.Recombine = false;
       extr.mesh.QuadToTri = NO_QUADTRI;
@@ -11165,7 +11169,7 @@ yyreduce:
     break;
 
   case 313:
-#line 3978 "Gmsh.y"
+#line 3982 "Gmsh.y"
     {
       std::vector<std::pair<int, int> > inDimTags, outDimTags;
       ListOfShapes2VectorOfPairs((yyvsp[(10) - (13)].l), inDimTags);
@@ -11188,7 +11192,7 @@ yyreduce:
     break;
 
   case 314:
-#line 3998 "Gmsh.y"
+#line 4002 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = extr.mesh.Recombine = false;
       extr.mesh.QuadToTri = NO_QUADTRI;
@@ -11197,7 +11201,7 @@ yyreduce:
     break;
 
   case 315:
-#line 4004 "Gmsh.y"
+#line 4008 "Gmsh.y"
     {
       std::vector<std::pair<int, int> > inDimTags, outDimTags;
       ListOfShapes2VectorOfPairs((yyvsp[(12) - (15)].l), inDimTags);
@@ -11218,7 +11222,7 @@ yyreduce:
     break;
 
   case 316:
-#line 4022 "Gmsh.y"
+#line 4026 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = extr.mesh.Recombine = false;
       extr.mesh.QuadToTri = NO_QUADTRI;
@@ -11227,7 +11231,7 @@ yyreduce:
     break;
 
   case 317:
-#line 4028 "Gmsh.y"
+#line 4032 "Gmsh.y"
     {
       std::vector<std::pair<int, int> > inDimTags, outDimTags;
       ListOfShapes2VectorOfPairs((yyvsp[(3) - (6)].l), inDimTags);
@@ -11247,7 +11251,7 @@ yyreduce:
     break;
 
   case 318:
-#line 4045 "Gmsh.y"
+#line 4049 "Gmsh.y"
     {
       std::vector<std::pair<int, int> > inDimTags, outDimTags;
       ListOfShapes2VectorOfPairs((yyvsp[(3) - (9)].l), inDimTags);
@@ -11266,7 +11270,7 @@ yyreduce:
     break;
 
   case 319:
-#line 4061 "Gmsh.y"
+#line 4065 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       bool r = true;
@@ -11286,7 +11290,7 @@ yyreduce:
     break;
 
   case 320:
-#line 4078 "Gmsh.y"
+#line 4082 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       bool r = true;
@@ -11306,7 +11310,7 @@ yyreduce:
     break;
 
   case 321:
-#line 4096 "Gmsh.y"
+#line 4100 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       bool r = true;
@@ -11331,7 +11335,7 @@ yyreduce:
     break;
 
   case 322:
-#line 4119 "Gmsh.y"
+#line 4123 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       bool r = true;
@@ -11358,19 +11362,19 @@ yyreduce:
     break;
 
   case 323:
-#line 4146 "Gmsh.y"
+#line 4150 "Gmsh.y"
     {
     ;}
     break;
 
   case 324:
-#line 4149 "Gmsh.y"
+#line 4153 "Gmsh.y"
     {
     ;}
     break;
 
   case 325:
-#line 4155 "Gmsh.y"
+#line 4159 "Gmsh.y"
     {
       int n = (int)fabs((yyvsp[(3) - (5)].d));
       if(n){ // we accept n==0 to easily disable layers
@@ -11385,7 +11389,7 @@ yyreduce:
     break;
 
   case 326:
-#line 4167 "Gmsh.y"
+#line 4171 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = true;
       extr.mesh.NbLayer = List_Nbr((yyvsp[(3) - (7)].l));
@@ -11408,56 +11412,56 @@ yyreduce:
     break;
 
   case 327:
-#line 4187 "Gmsh.y"
+#line 4191 "Gmsh.y"
     {
       extr.mesh.ScaleLast = true;
     ;}
     break;
 
   case 328:
-#line 4191 "Gmsh.y"
+#line 4195 "Gmsh.y"
     {
       extr.mesh.Recombine = true;
     ;}
     break;
 
   case 329:
-#line 4195 "Gmsh.y"
+#line 4199 "Gmsh.y"
     {
       extr.mesh.Recombine = (yyvsp[(2) - (3)].d) ? true : false;
     ;}
     break;
 
   case 330:
-#line 4199 "Gmsh.y"
+#line 4203 "Gmsh.y"
     {
       extr.mesh.QuadToTri = QUADTRI_ADDVERTS_1;
     ;}
     break;
 
   case 331:
-#line 4203 "Gmsh.y"
+#line 4207 "Gmsh.y"
     {
       extr.mesh.QuadToTri = QUADTRI_ADDVERTS_1_RECOMB;
     ;}
     break;
 
   case 332:
-#line 4207 "Gmsh.y"
+#line 4211 "Gmsh.y"
     {
       extr.mesh.QuadToTri = QUADTRI_NOVERTS_1;
     ;}
     break;
 
   case 333:
-#line 4211 "Gmsh.y"
+#line 4215 "Gmsh.y"
     {
       extr.mesh.QuadToTri = QUADTRI_NOVERTS_1_RECOMB;
     ;}
     break;
 
   case 334:
-#line 4215 "Gmsh.y"
+#line 4219 "Gmsh.y"
     {
       std::vector<int> tags; ListOfDouble2Vector((yyvsp[(6) - (9)].l), tags);
       int num = (int)(yyvsp[(3) - (9)].d);
@@ -11469,7 +11473,7 @@ yyreduce:
     break;
 
   case 335:
-#line 4224 "Gmsh.y"
+#line 4228 "Gmsh.y"
     {
       if(!strcmp((yyvsp[(2) - (6)].c), "Index"))
         extr.mesh.BoundaryLayerIndex = (yyvsp[(4) - (6)].d);
@@ -11480,57 +11484,57 @@ yyreduce:
     break;
 
   case 336:
-#line 4236 "Gmsh.y"
+#line 4240 "Gmsh.y"
     { (yyval.i) = OCC_Internals::Union; ;}
     break;
 
   case 337:
-#line 4237 "Gmsh.y"
+#line 4241 "Gmsh.y"
     { (yyval.i) = OCC_Internals::Intersection; ;}
     break;
 
   case 338:
-#line 4238 "Gmsh.y"
+#line 4242 "Gmsh.y"
     { (yyval.i) = OCC_Internals::Difference; ;}
     break;
 
   case 339:
-#line 4239 "Gmsh.y"
+#line 4243 "Gmsh.y"
     { (yyval.i) = OCC_Internals::Section; ;}
     break;
 
   case 340:
-#line 4240 "Gmsh.y"
+#line 4244 "Gmsh.y"
     { (yyval.i) = OCC_Internals::Fragments; ;}
     break;
 
   case 341:
-#line 4244 "Gmsh.y"
+#line 4248 "Gmsh.y"
     { (yyval.i) = 0; ;}
     break;
 
   case 342:
-#line 4245 "Gmsh.y"
+#line 4249 "Gmsh.y"
     { (yyval.i) = 1; ;}
     break;
 
   case 343:
-#line 4246 "Gmsh.y"
+#line 4250 "Gmsh.y"
     { (yyval.i) = 2; ;}
     break;
 
   case 344:
-#line 4247 "Gmsh.y"
+#line 4251 "Gmsh.y"
     { (yyval.i) = (yyvsp[(2) - (3)].d) ? 1 : 0; ;}
     break;
 
   case 345:
-#line 4248 "Gmsh.y"
+#line 4252 "Gmsh.y"
     { (yyval.i) = (yyvsp[(3) - (4)].d) ? 2 : 0; ;}
     break;
 
   case 346:
-#line 4253 "Gmsh.y"
+#line 4257 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       bool r = true;
@@ -11556,7 +11560,7 @@ yyreduce:
     break;
 
   case 347:
-#line 4276 "Gmsh.y"
+#line 4280 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       bool r = true;
@@ -11575,7 +11579,7 @@ yyreduce:
     break;
 
   case 348:
-#line 4296 "Gmsh.y"
+#line 4300 "Gmsh.y"
     {
       bool r = true;
       if(gmsh_yyfactory == "OpenCASCADE" && GModel::current()->getOCCInternals()){
@@ -11596,14 +11600,14 @@ yyreduce:
     break;
 
   case 349:
-#line 4317 "Gmsh.y"
+#line 4321 "Gmsh.y"
     {
       (yyval.v)[0] = (yyval.v)[1] = 1.;
     ;}
     break;
 
   case 350:
-#line 4321 "Gmsh.y"
+#line 4325 "Gmsh.y"
     {
       if(!strcmp((yyvsp[(2) - (3)].c), "Progression") || !strcmp((yyvsp[(2) - (3)].c), "Power"))
         (yyval.v)[0] = 1.;
@@ -11619,14 +11623,14 @@ yyreduce:
     break;
 
   case 351:
-#line 4336 "Gmsh.y"
+#line 4340 "Gmsh.y"
     {
       (yyval.i) = -1; // left
     ;}
     break;
 
   case 352:
-#line 4340 "Gmsh.y"
+#line 4344 "Gmsh.y"
     {
       if(!strcmp((yyvsp[(1) - (1)].c), "Right"))
         (yyval.i) = 1;
@@ -11643,49 +11647,49 @@ yyreduce:
     break;
 
   case 353:
-#line 4356 "Gmsh.y"
+#line 4360 "Gmsh.y"
     {
      (yyval.l) = List_Create(1, 1, sizeof(double));
    ;}
     break;
 
   case 354:
-#line 4360 "Gmsh.y"
+#line 4364 "Gmsh.y"
     {
      (yyval.l) = (yyvsp[(2) - (2)].l);
    ;}
     break;
 
   case 355:
-#line 4365 "Gmsh.y"
+#line 4369 "Gmsh.y"
     {
       (yyval.i) = 45;
     ;}
     break;
 
   case 356:
-#line 4369 "Gmsh.y"
+#line 4373 "Gmsh.y"
     {
       (yyval.i) = (int)(yyvsp[(2) - (2)].d);
     ;}
     break;
 
   case 357:
-#line 4375 "Gmsh.y"
+#line 4379 "Gmsh.y"
     {
       (yyval.l) = List_Create(1, 1, sizeof(double));
     ;}
     break;
 
   case 358:
-#line 4379 "Gmsh.y"
+#line 4383 "Gmsh.y"
     {
       (yyval.l) = (yyvsp[(2) - (2)].l);
     ;}
     break;
 
   case 359:
-#line 4386 "Gmsh.y"
+#line 4390 "Gmsh.y"
     {
       // mesh sizes at vertices are stored in internal CAD data, as they can be
       // specified during vertex creation and copied around during CAD
@@ -11710,7 +11714,7 @@ yyreduce:
     break;
 
   case 360:
-#line 4408 "Gmsh.y"
+#line 4412 "Gmsh.y"
     {
       // transfinite constraints are stored in GEO internals in addition to
       // GModel, as they can be copied around during GEO operations
@@ -11754,7 +11758,7 @@ yyreduce:
     break;
 
   case 361:
-#line 4449 "Gmsh.y"
+#line 4453 "Gmsh.y"
     {
       // transfinite constraints are stored in GEO internals in addition to
       // GModel, as they can be copied around during GEO operations
@@ -11801,7 +11805,7 @@ yyreduce:
     break;
 
   case 362:
-#line 4493 "Gmsh.y"
+#line 4497 "Gmsh.y"
     {
       // transfinite constraints are stored in GEO internals in addition to
       // GModel, as they can be copied around during GEO operations
@@ -11843,7 +11847,7 @@ yyreduce:
     break;
 
   case 363:
-#line 4532 "Gmsh.y"
+#line 4536 "Gmsh.y"
     {
       // transfinite constraints are stored in GEO internals in addition to
       // GModel, as they can be copied around during GEO operations
@@ -11871,7 +11875,7 @@ yyreduce:
     break;
 
   case 364:
-#line 4557 "Gmsh.y"
+#line 4561 "Gmsh.y"
     {
       int tag = (int)(yyvsp[(4) - (8)].d);
       GVertex *gf = GModel::current()->getVertexByTag(tag);
@@ -11886,7 +11890,7 @@ yyreduce:
     break;
 
   case 365:
-#line 4569 "Gmsh.y"
+#line 4573 "Gmsh.y"
     {
       int tag = (int)(yyvsp[(4) - (8)].d);
       GEdge *gf = GModel::current()->getEdgeByTag(tag);
@@ -11901,7 +11905,7 @@ yyreduce:
     break;
 
   case 366:
-#line 4581 "Gmsh.y"
+#line 4585 "Gmsh.y"
     {
       int tag = (int)(yyvsp[(4) - (8)].d);
       GFace *gf = GModel::current()->getFaceByTag(tag);
@@ -11916,7 +11920,7 @@ yyreduce:
     break;
 
   case 367:
-#line 4593 "Gmsh.y"
+#line 4597 "Gmsh.y"
     {
       int tag = (int)(yyvsp[(4) - (8)].d);
       GRegion *gf = GModel::current()->getRegionByTag(tag);
@@ -11931,7 +11935,7 @@ yyreduce:
     break;
 
   case 368:
-#line 4605 "Gmsh.y"
+#line 4609 "Gmsh.y"
     {
       // mesh algorithm constraints are stored in GEO internals in addition to
       // GModel, as they can be copied around during GEO operations
@@ -11951,7 +11955,7 @@ yyreduce:
     break;
 
   case 369:
-#line 4622 "Gmsh.y"
+#line 4626 "Gmsh.y"
     {
       // lcExtendFromBoundary onstraints are stored in GEO internals in addition
       // to GModel, as they can be copied around during GEO operations
@@ -11971,7 +11975,7 @@ yyreduce:
     break;
 
   case 370:
-#line 4639 "Gmsh.y"
+#line 4643 "Gmsh.y"
     {
       // recombine constraints are stored in GEO internals in addition to
       // GModel, as they can be copied around during GEO operations
@@ -12004,7 +12008,7 @@ yyreduce:
     break;
 
   case 371:
-#line 4669 "Gmsh.y"
+#line 4673 "Gmsh.y"
     {
       // recombine constraints are stored in GEO internals in addition to
       // GModel, as they can be copied around during GEO operations
@@ -12033,7 +12037,7 @@ yyreduce:
     break;
 
   case 372:
-#line 4695 "Gmsh.y"
+#line 4699 "Gmsh.y"
     {
       // smoothing constraints are stored in GEO internals in addition to
       // GModel, as they can be copied around during GEO operations
@@ -12062,7 +12066,7 @@ yyreduce:
     break;
 
   case 373:
-#line 4722 "Gmsh.y"
+#line 4726 "Gmsh.y"
     {
       if (List_Nbr((yyvsp[(4) - (11)].l)) != List_Nbr((yyvsp[(8) - (11)].l))){
         yymsg(0, "Number of master lines (%d) different from number of "
@@ -12096,7 +12100,7 @@ yyreduce:
     break;
 
   case 374:
-#line 4754 "Gmsh.y"
+#line 4758 "Gmsh.y"
     {
       if (List_Nbr((yyvsp[(4) - (11)].l)) != List_Nbr((yyvsp[(8) - (11)].l))){
         yymsg(0, "Number of master surfaces (%d) different from number of "
@@ -12125,7 +12129,7 @@ yyreduce:
     break;
 
   case 375:
-#line 4781 "Gmsh.y"
+#line 4785 "Gmsh.y"
     {
       if (List_Nbr((yyvsp[(4) - (18)].l)) != List_Nbr((yyvsp[(8) - (18)].l))){
         yymsg(0, "Number of master curves (%d) different from number of "
@@ -12153,7 +12157,7 @@ yyreduce:
     break;
 
   case 376:
-#line 4807 "Gmsh.y"
+#line 4811 "Gmsh.y"
     {
       if (List_Nbr((yyvsp[(4) - (18)].l)) != List_Nbr((yyvsp[(8) - (18)].l))){
         yymsg(0, "Number of master surfaces (%d) different from number of "
@@ -12181,7 +12185,7 @@ yyreduce:
     break;
 
   case 377:
-#line 4833 "Gmsh.y"
+#line 4837 "Gmsh.y"
     {
       if (List_Nbr((yyvsp[(4) - (12)].l)) != List_Nbr((yyvsp[(8) - (12)].l))){
         yymsg(0, "Number of master curves (%d) different from number of "
@@ -12209,7 +12213,7 @@ yyreduce:
     break;
 
   case 378:
-#line 4859 "Gmsh.y"
+#line 4863 "Gmsh.y"
     {
       if (List_Nbr((yyvsp[(4) - (12)].l)) != List_Nbr((yyvsp[(8) - (12)].l))){
         yymsg(0, "Number of master surfaces (%d) different from number of "
@@ -12237,7 +12241,7 @@ yyreduce:
     break;
 
   case 379:
-#line 4885 "Gmsh.y"
+#line 4889 "Gmsh.y"
     {
       if (List_Nbr((yyvsp[(5) - (12)].l)) != List_Nbr((yyvsp[(10) - (12)].l))){
         yymsg(0, "Number of master surface curves (%d) different from number of "
@@ -12261,7 +12265,7 @@ yyreduce:
     break;
 
   case 380:
-#line 4906 "Gmsh.y"
+#line 4910 "Gmsh.y"
     {
       if (((yyvsp[(6) - (10)].i)==2 || (yyvsp[(6) - (10)].i)==3) && (yyvsp[(1) - (10)].i)<(yyvsp[(6) - (10)].i) ) {
         std::vector<int> tags; ListOfDouble2Vector((yyvsp[(3) - (10)].l), tags);
@@ -12275,7 +12279,7 @@ yyreduce:
     break;
 
   case 381:
-#line 4917 "Gmsh.y"
+#line 4921 "Gmsh.y"
     {
       // reverse mesh constraints are stored in GEO internals in addition to
       // GModel, as they can be copied around during GEO operations
@@ -12326,7 +12330,7 @@ yyreduce:
     break;
 
   case 382:
-#line 4965 "Gmsh.y"
+#line 4969 "Gmsh.y"
     {
       if(GModel::current()->getOCCInternals() &&
          GModel::current()->getOCCInternals()->getChanged())
@@ -12383,7 +12387,7 @@ yyreduce:
     break;
 
   case 383:
-#line 5019 "Gmsh.y"
+#line 5023 "Gmsh.y"
     {
       if(GModel::current()->getOCCInternals() &&
          GModel::current()->getOCCInternals()->getChanged())
@@ -12401,7 +12405,7 @@ yyreduce:
     break;
 
   case 384:
-#line 5034 "Gmsh.y"
+#line 5038 "Gmsh.y"
     {
       for(int i = 0; i < List_Nbr((yyvsp[(3) - (4)].l)); i++){
 	double dnum;
@@ -12416,7 +12420,7 @@ yyreduce:
     break;
 
   case 385:
-#line 5046 "Gmsh.y"
+#line 5050 "Gmsh.y"
     {
       std::vector<int> tags; ListOfDouble2Vector((yyvsp[(3) - (4)].l), tags);
       GModel::current()->getGEOInternals()->setCompoundMesh((yyvsp[(2) - (4)].i), tags);
@@ -12425,7 +12429,7 @@ yyreduce:
     break;
 
   case 386:
-#line 5057 "Gmsh.y"
+#line 5061 "Gmsh.y"
     {
       if(gmsh_yyfactory == "OpenCASCADE" && GModel::current()->getOCCInternals())
         GModel::current()->getOCCInternals()->removeAllDuplicates();
@@ -12435,7 +12439,7 @@ yyreduce:
     break;
 
   case 387:
-#line 5064 "Gmsh.y"
+#line 5068 "Gmsh.y"
     {
       if(!strcmp((yyvsp[(2) - (3)].c), "Geometry")){
         if(gmsh_yyfactory == "OpenCASCADE" && GModel::current()->getOCCInternals())
@@ -12453,7 +12457,7 @@ yyreduce:
     break;
 
   case 388:
-#line 5079 "Gmsh.y"
+#line 5083 "Gmsh.y"
     {
       std::vector<int> tags; ListOfDouble2Vector((yyvsp[(4) - (6)].l), tags);
       if(gmsh_yyfactory == "OpenCASCADE" && GModel::current()->getOCCInternals())
@@ -12465,22 +12469,22 @@ yyreduce:
     break;
 
   case 389:
-#line 5092 "Gmsh.y"
+#line 5096 "Gmsh.y"
     { (yyval.c) = (char*)"Homology"; ;}
     break;
 
   case 390:
-#line 5093 "Gmsh.y"
+#line 5097 "Gmsh.y"
     { (yyval.c) = (char*)"Cohomology"; ;}
     break;
 
   case 391:
-#line 5094 "Gmsh.y"
+#line 5098 "Gmsh.y"
     { (yyval.c) = (char*)"Betti"; ;}
     break;
 
   case 392:
-#line 5099 "Gmsh.y"
+#line 5103 "Gmsh.y"
     {
       std::vector<int> domain, subdomain, dim;
       for(int i = 0; i < 4; i++) dim.push_back(i);
@@ -12489,7 +12493,7 @@ yyreduce:
     break;
 
   case 393:
-#line 5105 "Gmsh.y"
+#line 5109 "Gmsh.y"
     {
       std::vector<int> domain, subdomain, dim;
       for(int i = 0; i < List_Nbr((yyvsp[(3) - (5)].l)); i++){
@@ -12504,7 +12508,7 @@ yyreduce:
     break;
 
   case 394:
-#line 5117 "Gmsh.y"
+#line 5121 "Gmsh.y"
     {
       std::vector<int> domain, subdomain, dim;
       for(int i = 0; i < List_Nbr((yyvsp[(3) - (7)].l)); i++){
@@ -12525,7 +12529,7 @@ yyreduce:
     break;
 
   case 395:
-#line 5135 "Gmsh.y"
+#line 5139 "Gmsh.y"
     {
       std::vector<int> domain, subdomain, dim;
       for(int i = 0; i < List_Nbr((yyvsp[(6) - (10)].l)); i++){
@@ -12551,47 +12555,47 @@ yyreduce:
     break;
 
   case 396:
-#line 5162 "Gmsh.y"
+#line 5166 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (1)].d);           ;}
     break;
 
   case 397:
-#line 5163 "Gmsh.y"
+#line 5167 "Gmsh.y"
     { (yyval.d) = (yyvsp[(2) - (3)].d);           ;}
     break;
 
   case 398:
-#line 5164 "Gmsh.y"
+#line 5168 "Gmsh.y"
     { (yyval.d) = -(yyvsp[(2) - (2)].d);          ;}
     break;
 
   case 399:
-#line 5165 "Gmsh.y"
+#line 5169 "Gmsh.y"
     { (yyval.d) = (yyvsp[(2) - (2)].d);           ;}
     break;
 
   case 400:
-#line 5166 "Gmsh.y"
+#line 5170 "Gmsh.y"
     { (yyval.d) = !(yyvsp[(2) - (2)].d);          ;}
     break;
 
   case 401:
-#line 5167 "Gmsh.y"
+#line 5171 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (3)].d) - (yyvsp[(3) - (3)].d);      ;}
     break;
 
   case 402:
-#line 5168 "Gmsh.y"
+#line 5172 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (3)].d) + (yyvsp[(3) - (3)].d);      ;}
     break;
 
   case 403:
-#line 5169 "Gmsh.y"
+#line 5173 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (3)].d) * (yyvsp[(3) - (3)].d);      ;}
     break;
 
   case 404:
-#line 5171 "Gmsh.y"
+#line 5175 "Gmsh.y"
     {
       if(!(yyvsp[(3) - (3)].d))
 	yymsg(0, "Division by zero in '%g / %g'", (yyvsp[(1) - (3)].d), (yyvsp[(3) - (3)].d));
@@ -12601,267 +12605,267 @@ yyreduce:
     break;
 
   case 405:
-#line 5177 "Gmsh.y"
+#line 5181 "Gmsh.y"
     { (yyval.d) = (int)(yyvsp[(1) - (3)].d) | (int)(yyvsp[(3) - (3)].d); ;}
     break;
 
   case 406:
-#line 5178 "Gmsh.y"
+#line 5182 "Gmsh.y"
     { (yyval.d) = (int)(yyvsp[(1) - (3)].d) & (int)(yyvsp[(3) - (3)].d); ;}
     break;
 
   case 407:
-#line 5179 "Gmsh.y"
+#line 5183 "Gmsh.y"
     { (yyval.d) = (int)(yyvsp[(1) - (3)].d) % (int)(yyvsp[(3) - (3)].d); ;}
     break;
 
   case 408:
-#line 5180 "Gmsh.y"
+#line 5184 "Gmsh.y"
     { (yyval.d) = pow((yyvsp[(1) - (3)].d), (yyvsp[(3) - (3)].d));  ;}
     break;
 
   case 409:
-#line 5181 "Gmsh.y"
+#line 5185 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (3)].d) < (yyvsp[(3) - (3)].d);      ;}
     break;
 
   case 410:
-#line 5182 "Gmsh.y"
+#line 5186 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (3)].d) > (yyvsp[(3) - (3)].d);      ;}
     break;
 
   case 411:
-#line 5183 "Gmsh.y"
+#line 5187 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (3)].d) <= (yyvsp[(3) - (3)].d);     ;}
     break;
 
   case 412:
-#line 5184 "Gmsh.y"
+#line 5188 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (3)].d) >= (yyvsp[(3) - (3)].d);     ;}
     break;
 
   case 413:
-#line 5185 "Gmsh.y"
+#line 5189 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (3)].d) == (yyvsp[(3) - (3)].d);     ;}
     break;
 
   case 414:
-#line 5186 "Gmsh.y"
+#line 5190 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (3)].d) != (yyvsp[(3) - (3)].d);     ;}
     break;
 
   case 415:
-#line 5187 "Gmsh.y"
+#line 5191 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (3)].d) && (yyvsp[(3) - (3)].d);     ;}
     break;
 
   case 416:
-#line 5188 "Gmsh.y"
+#line 5192 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (3)].d) || (yyvsp[(3) - (3)].d);     ;}
     break;
 
   case 417:
-#line 5189 "Gmsh.y"
+#line 5193 "Gmsh.y"
     { (yyval.d) = ((int)(yyvsp[(1) - (3)].d) >> (int)(yyvsp[(3) - (3)].d)); ;}
     break;
 
   case 418:
-#line 5190 "Gmsh.y"
+#line 5194 "Gmsh.y"
     { (yyval.d) = ((int)(yyvsp[(1) - (3)].d) << (int)(yyvsp[(3) - (3)].d)); ;}
     break;
 
   case 419:
-#line 5191 "Gmsh.y"
+#line 5195 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (5)].d) ? (yyvsp[(3) - (5)].d) : (yyvsp[(5) - (5)].d); ;}
     break;
 
   case 420:
-#line 5192 "Gmsh.y"
+#line 5196 "Gmsh.y"
     { (yyval.d) = exp((yyvsp[(3) - (4)].d));      ;}
     break;
 
   case 421:
-#line 5193 "Gmsh.y"
+#line 5197 "Gmsh.y"
     { (yyval.d) = log((yyvsp[(3) - (4)].d));      ;}
     break;
 
   case 422:
-#line 5194 "Gmsh.y"
+#line 5198 "Gmsh.y"
     { (yyval.d) = log10((yyvsp[(3) - (4)].d));    ;}
     break;
 
   case 423:
-#line 5195 "Gmsh.y"
+#line 5199 "Gmsh.y"
     { (yyval.d) = sqrt((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 424:
-#line 5196 "Gmsh.y"
+#line 5200 "Gmsh.y"
     { (yyval.d) = sin((yyvsp[(3) - (4)].d));      ;}
     break;
 
   case 425:
-#line 5197 "Gmsh.y"
+#line 5201 "Gmsh.y"
     { (yyval.d) = asin((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 426:
-#line 5198 "Gmsh.y"
+#line 5202 "Gmsh.y"
     { (yyval.d) = cos((yyvsp[(3) - (4)].d));      ;}
     break;
 
   case 427:
-#line 5199 "Gmsh.y"
+#line 5203 "Gmsh.y"
     { (yyval.d) = acos((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 428:
-#line 5200 "Gmsh.y"
+#line 5204 "Gmsh.y"
     { (yyval.d) = tan((yyvsp[(3) - (4)].d));      ;}
     break;
 
   case 429:
-#line 5201 "Gmsh.y"
+#line 5205 "Gmsh.y"
     { (yyval.d) = atan((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 430:
-#line 5202 "Gmsh.y"
+#line 5206 "Gmsh.y"
     { (yyval.d) = atan2((yyvsp[(3) - (6)].d), (yyvsp[(5) - (6)].d));;}
     break;
 
   case 431:
-#line 5203 "Gmsh.y"
+#line 5207 "Gmsh.y"
     { (yyval.d) = sinh((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 432:
-#line 5204 "Gmsh.y"
+#line 5208 "Gmsh.y"
     { (yyval.d) = cosh((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 433:
-#line 5205 "Gmsh.y"
+#line 5209 "Gmsh.y"
     { (yyval.d) = tanh((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 434:
-#line 5206 "Gmsh.y"
+#line 5210 "Gmsh.y"
     { (yyval.d) = fabs((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 435:
-#line 5207 "Gmsh.y"
+#line 5211 "Gmsh.y"
     { (yyval.d) = std::abs((yyvsp[(3) - (4)].d)); ;}
     break;
 
   case 436:
-#line 5208 "Gmsh.y"
+#line 5212 "Gmsh.y"
     { (yyval.d) = floor((yyvsp[(3) - (4)].d));    ;}
     break;
 
   case 437:
-#line 5209 "Gmsh.y"
+#line 5213 "Gmsh.y"
     { (yyval.d) = ceil((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 438:
-#line 5210 "Gmsh.y"
+#line 5214 "Gmsh.y"
     { (yyval.d) = floor((yyvsp[(3) - (4)].d) + 0.5); ;}
     break;
 
   case 439:
-#line 5211 "Gmsh.y"
+#line 5215 "Gmsh.y"
     { (yyval.d) = fmod((yyvsp[(3) - (6)].d), (yyvsp[(5) - (6)].d)); ;}
     break;
 
   case 440:
-#line 5212 "Gmsh.y"
+#line 5216 "Gmsh.y"
     { (yyval.d) = fmod((yyvsp[(3) - (6)].d), (yyvsp[(5) - (6)].d)); ;}
     break;
 
   case 441:
-#line 5213 "Gmsh.y"
+#line 5217 "Gmsh.y"
     { (yyval.d) = sqrt((yyvsp[(3) - (6)].d) * (yyvsp[(3) - (6)].d) + (yyvsp[(5) - (6)].d) * (yyvsp[(5) - (6)].d)); ;}
     break;
 
   case 442:
-#line 5214 "Gmsh.y"
+#line 5218 "Gmsh.y"
     { (yyval.d) = (yyvsp[(3) - (4)].d) * (double)rand() / (double)RAND_MAX; ;}
     break;
 
   case 443:
-#line 5215 "Gmsh.y"
+#line 5219 "Gmsh.y"
     { (yyval.d) = std::max((yyvsp[(3) - (6)].d), (yyvsp[(5) - (6)].d)); ;}
     break;
 
   case 444:
-#line 5216 "Gmsh.y"
+#line 5220 "Gmsh.y"
     { (yyval.d) = std::min((yyvsp[(3) - (6)].d), (yyvsp[(5) - (6)].d)); ;}
     break;
 
   case 445:
-#line 5225 "Gmsh.y"
+#line 5229 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (1)].d); ;}
     break;
 
   case 446:
-#line 5226 "Gmsh.y"
+#line 5230 "Gmsh.y"
     { (yyval.d) = 3.141592653589793; ;}
     break;
 
   case 447:
-#line 5227 "Gmsh.y"
+#line 5231 "Gmsh.y"
     { (yyval.d) = (double)ImbricatedTest; ;}
     break;
 
   case 448:
-#line 5228 "Gmsh.y"
+#line 5232 "Gmsh.y"
     { (yyval.d) = Msg::GetCommRank(); ;}
     break;
 
   case 449:
-#line 5229 "Gmsh.y"
+#line 5233 "Gmsh.y"
     { (yyval.d) = Msg::GetCommSize(); ;}
     break;
 
   case 450:
-#line 5230 "Gmsh.y"
+#line 5234 "Gmsh.y"
     { (yyval.d) = GetGmshMajorVersion(); ;}
     break;
 
   case 451:
-#line 5231 "Gmsh.y"
+#line 5235 "Gmsh.y"
     { (yyval.d) = GetGmshMinorVersion(); ;}
     break;
 
   case 452:
-#line 5232 "Gmsh.y"
+#line 5236 "Gmsh.y"
     { (yyval.d) = GetGmshPatchVersion(); ;}
     break;
 
   case 453:
-#line 5233 "Gmsh.y"
+#line 5237 "Gmsh.y"
     { (yyval.d) = Cpu(); ;}
     break;
 
   case 454:
-#line 5234 "Gmsh.y"
+#line 5238 "Gmsh.y"
     { (yyval.d) = GetMemoryUsage()/1024./1024.; ;}
     break;
 
   case 455:
-#line 5235 "Gmsh.y"
+#line 5239 "Gmsh.y"
     { (yyval.d) = TotalRam(); ;}
     break;
 
   case 456:
-#line 5240 "Gmsh.y"
+#line 5244 "Gmsh.y"
     { init_options(); ;}
     break;
 
   case 457:
-#line 5242 "Gmsh.y"
+#line 5246 "Gmsh.y"
     {
       std::vector<double> val(1, (yyvsp[(3) - (6)].d));
       Msg::ExchangeOnelabParameter("", val, floatOptions, charOptions);
@@ -12870,12 +12874,12 @@ yyreduce:
     break;
 
   case 458:
-#line 5248 "Gmsh.y"
+#line 5252 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (1)].d); ;}
     break;
 
   case 459:
-#line 5250 "Gmsh.y"
+#line 5254 "Gmsh.y"
     {
       (yyval.d) = Msg::GetOnelabNumber((yyvsp[(3) - (4)].c));
       Free((yyvsp[(3) - (4)].c));
@@ -12883,7 +12887,7 @@ yyreduce:
     break;
 
   case 460:
-#line 5255 "Gmsh.y"
+#line 5259 "Gmsh.y"
     {
       (yyval.d) = Msg::GetOnelabNumber((yyvsp[(3) - (6)].c), (yyvsp[(5) - (6)].d));
       Free((yyvsp[(3) - (6)].c));
@@ -12891,70 +12895,70 @@ yyreduce:
     break;
 
   case 461:
-#line 5260 "Gmsh.y"
+#line 5264 "Gmsh.y"
     {
       (yyval.d) = treat_Struct_FullName_Float((yyvsp[(1) - (1)].c2).char1, (yyvsp[(1) - (1)].c2).char2);
     ;}
     break;
 
   case 462:
-#line 5265 "Gmsh.y"
+#line 5269 "Gmsh.y"
     {
       (yyval.d) = treat_Struct_FullName_Float(NULL, (yyvsp[(1) - (4)].c), 2, (int)(yyvsp[(3) - (4)].d));
     ;}
     break;
 
   case 463:
-#line 5270 "Gmsh.y"
+#line 5274 "Gmsh.y"
     {
       (yyval.d) = treat_Struct_FullName_Float(NULL, (yyvsp[(1) - (4)].c), 2, (int)(yyvsp[(3) - (4)].d));
     ;}
     break;
 
   case 464:
-#line 5274 "Gmsh.y"
+#line 5278 "Gmsh.y"
     {
       (yyval.d) = treat_Struct_FullName_Float((yyvsp[(3) - (4)].c2).char1, (yyvsp[(3) - (4)].c2).char2, 1, 0, 0., 1);
     ;}
     break;
 
   case 465:
-#line 5278 "Gmsh.y"
+#line 5282 "Gmsh.y"
     {
       (yyval.d) = treat_Struct_FullName_dot_tSTRING_Float((yyvsp[(3) - (6)].c2).char1, (yyvsp[(3) - (6)].c2).char2, (yyvsp[(5) - (6)].c), 0, 0., 1);
     ;}
     break;
 
   case 466:
-#line 5282 "Gmsh.y"
+#line 5286 "Gmsh.y"
     {
       (yyval.d) = treat_Struct_FullName_Float((yyvsp[(3) - (5)].c2).char1, (yyvsp[(3) - (5)].c2).char2, 1, 0, (yyvsp[(4) - (5)].d), 2);
     ;}
     break;
 
   case 467:
-#line 5286 "Gmsh.y"
+#line 5290 "Gmsh.y"
     {
       (yyval.d) = treat_Struct_FullName_dot_tSTRING_Float((yyvsp[(3) - (7)].c2).char1, (yyvsp[(3) - (7)].c2).char2, (yyvsp[(5) - (7)].c), 0, (yyvsp[(6) - (7)].d), 2);
     ;}
     break;
 
   case 468:
-#line 5290 "Gmsh.y"
+#line 5294 "Gmsh.y"
     {
       (yyval.d) = treat_Struct_FullName_Float((yyvsp[(3) - (8)].c2).char1, (yyvsp[(3) - (8)].c2).char2, 2, (int)(yyvsp[(5) - (8)].d), (yyvsp[(7) - (8)].d), 2);
     ;}
     break;
 
   case 469:
-#line 5294 "Gmsh.y"
+#line 5298 "Gmsh.y"
     {
       (yyval.d) = treat_Struct_FullName_dot_tSTRING_Float((yyvsp[(3) - (10)].c2).char1, (yyvsp[(3) - (10)].c2).char2, (yyvsp[(5) - (10)].c), (int)(yyvsp[(7) - (10)].d), (yyvsp[(9) - (10)].d), 2);
     ;}
     break;
 
   case 470:
-#line 5298 "Gmsh.y"
+#line 5302 "Gmsh.y"
     {
       std::string tmp = FixRelativePath(gmsh_yyname, (yyvsp[(3) - (4)].c));
       (yyval.d) = !StatFile(tmp);
@@ -12963,7 +12967,7 @@ yyreduce:
     break;
 
   case 471:
-#line 5304 "Gmsh.y"
+#line 5308 "Gmsh.y"
     {
       if(gmsh_yysymbols.count((yyvsp[(2) - (4)].c))){
         gmsh_yysymbol &s(gmsh_yysymbols[(yyvsp[(2) - (4)].c)]);
@@ -12981,14 +12985,14 @@ yyreduce:
     break;
 
   case 472:
-#line 5319 "Gmsh.y"
+#line 5323 "Gmsh.y"
     {
       (yyval.d) = treat_Struct_FullName_dot_tSTRING_Float_getDim((yyvsp[(2) - (6)].c2).char1, (yyvsp[(2) - (6)].c2).char2, (yyvsp[(4) - (6)].c));
     ;}
     break;
 
   case 473:
-#line 5323 "Gmsh.y"
+#line 5327 "Gmsh.y"
     {
       std::string struct_namespace((yyvsp[(3) - (4)].c));
       (yyval.d) = (double)gmsh_yynamespaces[struct_namespace].size();
@@ -12997,7 +13001,7 @@ yyreduce:
     break;
 
   case 474:
-#line 5329 "Gmsh.y"
+#line 5333 "Gmsh.y"
     {
       std::string struct_namespace(std::string(""));
       (yyval.d) = (double)gmsh_yynamespaces[struct_namespace].size();
@@ -13005,7 +13009,7 @@ yyreduce:
     break;
 
   case 475:
-#line 5334 "Gmsh.y"
+#line 5338 "Gmsh.y"
     {
       if(!gmsh_yysymbols.count((yyvsp[(1) - (2)].c))){
 	yymsg(0, "Unknown variable '%s'", (yyvsp[(1) - (2)].c));
@@ -13027,7 +13031,7 @@ yyreduce:
     break;
 
   case 476:
-#line 5353 "Gmsh.y"
+#line 5357 "Gmsh.y"
     {
       int index = (int)(yyvsp[(3) - (5)].d);
       if(!gmsh_yysymbols.count((yyvsp[(1) - (5)].c))){
@@ -13050,7 +13054,7 @@ yyreduce:
     break;
 
   case 477:
-#line 5373 "Gmsh.y"
+#line 5377 "Gmsh.y"
     {
       int index = (int)(yyvsp[(3) - (5)].d);
       if(!gmsh_yysymbols.count((yyvsp[(1) - (5)].c))){
@@ -13073,49 +13077,49 @@ yyreduce:
     break;
 
   case 478:
-#line 5394 "Gmsh.y"
+#line 5398 "Gmsh.y"
     {
       (yyval.d) = treat_Struct_FullName_dot_tSTRING_Float(NULL, (yyvsp[(1) - (3)].c), (yyvsp[(3) - (3)].c));
     ;}
     break;
 
   case 479:
-#line 5398 "Gmsh.y"
+#line 5402 "Gmsh.y"
     {
       (yyval.d) = treat_Struct_FullName_dot_tSTRING_Float((yyvsp[(1) - (5)].c), (yyvsp[(3) - (5)].c), (yyvsp[(5) - (5)].c));
     ;}
     break;
 
   case 480:
-#line 5402 "Gmsh.y"
+#line 5406 "Gmsh.y"
     {
       (yyval.d) = treat_Struct_FullName_dot_tSTRING_Float(NULL, (yyvsp[(1) - (6)].c), (yyvsp[(3) - (6)].c), (int)(yyvsp[(5) - (6)].d));
     ;}
     break;
 
   case 481:
-#line 5406 "Gmsh.y"
+#line 5410 "Gmsh.y"
     {
       (yyval.d) = treat_Struct_FullName_dot_tSTRING_Float((yyvsp[(1) - (8)].c), (yyvsp[(3) - (8)].c), (yyvsp[(5) - (8)].c), (int)(yyvsp[(7) - (8)].d));
     ;}
     break;
 
   case 482:
-#line 5410 "Gmsh.y"
+#line 5414 "Gmsh.y"
     {
       (yyval.d) = treat_Struct_FullName_dot_tSTRING_Float(NULL, (yyvsp[(1) - (6)].c), (yyvsp[(3) - (6)].c), (int)(yyvsp[(5) - (6)].d));
     ;}
     break;
 
   case 483:
-#line 5414 "Gmsh.y"
+#line 5418 "Gmsh.y"
     {
       (yyval.d) = treat_Struct_FullName_dot_tSTRING_Float((yyvsp[(1) - (8)].c), (yyvsp[(3) - (8)].c), (yyvsp[(5) - (8)].c), (int)(yyvsp[(7) - (8)].d));
     ;}
     break;
 
   case 484:
-#line 5418 "Gmsh.y"
+#line 5422 "Gmsh.y"
     {
       NumberOption(GMSH_GET, (yyvsp[(1) - (6)].c), (int)(yyvsp[(3) - (6)].d), (yyvsp[(6) - (6)].c), (yyval.d));
       Free((yyvsp[(1) - (6)].c)); Free((yyvsp[(6) - (6)].c));
@@ -13123,7 +13127,7 @@ yyreduce:
     break;
 
   case 485:
-#line 5423 "Gmsh.y"
+#line 5427 "Gmsh.y"
     {
       double d = 0.;
       if(NumberOption(GMSH_GET, (yyvsp[(1) - (4)].c), 0, (yyvsp[(3) - (4)].c), d)){
@@ -13136,7 +13140,7 @@ yyreduce:
     break;
 
   case 486:
-#line 5433 "Gmsh.y"
+#line 5437 "Gmsh.y"
     {
       double d = 0.;
       if(NumberOption(GMSH_GET, (yyvsp[(1) - (7)].c), (int)(yyvsp[(3) - (7)].d), (yyvsp[(6) - (7)].c), d)){
@@ -13149,7 +13153,7 @@ yyreduce:
     break;
 
   case 487:
-#line 5443 "Gmsh.y"
+#line 5447 "Gmsh.y"
     {
       (yyval.d) = Msg::GetValue((yyvsp[(3) - (6)].c), (yyvsp[(5) - (6)].d));
       Free((yyvsp[(3) - (6)].c));
@@ -13157,7 +13161,7 @@ yyreduce:
     break;
 
   case 488:
-#line 5448 "Gmsh.y"
+#line 5452 "Gmsh.y"
     {
       int matches = 0;
       for(int i = 0; i < List_Nbr((yyvsp[(3) - (6)].l)); i++){
@@ -13171,7 +13175,7 @@ yyreduce:
     break;
 
   case 489:
-#line 5459 "Gmsh.y"
+#line 5463 "Gmsh.y"
     {
       std::string s((yyvsp[(3) - (6)].c)), substr((yyvsp[(5) - (6)].c));
       if(s.find(substr) != std::string::npos)
@@ -13183,7 +13187,7 @@ yyreduce:
     break;
 
   case 490:
-#line 5468 "Gmsh.y"
+#line 5472 "Gmsh.y"
     {
       (yyval.d) = strlen((yyvsp[(3) - (4)].c));
       Free((yyvsp[(3) - (4)].c));
@@ -13191,7 +13195,7 @@ yyreduce:
     break;
 
   case 491:
-#line 5473 "Gmsh.y"
+#line 5477 "Gmsh.y"
     {
       (yyval.d) = strcmp((yyvsp[(3) - (6)].c), (yyvsp[(5) - (6)].c));
       Free((yyvsp[(3) - (6)].c)); Free((yyvsp[(5) - (6)].c));
@@ -13199,7 +13203,7 @@ yyreduce:
     break;
 
   case 492:
-#line 5478 "Gmsh.y"
+#line 5482 "Gmsh.y"
     {
       int align = 0, font = 0, fontsize = CTX::instance()->glFontSize;
       if(List_Nbr((yyvsp[(3) - (4)].l)) % 2){
@@ -13226,27 +13230,27 @@ yyreduce:
     break;
 
   case 493:
-#line 5505 "Gmsh.y"
+#line 5509 "Gmsh.y"
     { (yyval.d) = 0.; ;}
     break;
 
   case 494:
-#line 5507 "Gmsh.y"
+#line 5511 "Gmsh.y"
     { (yyval.d) = (yyvsp[(2) - (2)].d);;}
     break;
 
   case 495:
-#line 5512 "Gmsh.y"
+#line 5516 "Gmsh.y"
     { (yyval.c) = NULL; ;}
     break;
 
   case 496:
-#line 5514 "Gmsh.y"
+#line 5518 "Gmsh.y"
     { (yyval.c) = (yyvsp[(2) - (2)].c);;}
     break;
 
   case 497:
-#line 5519 "Gmsh.y"
+#line 5523 "Gmsh.y"
     {
       std::string struct_namespace((yyvsp[(2) - (3)].c2).char1? (yyvsp[(2) - (3)].c2).char1 : std::string("")),
         struct_name((yyvsp[(2) - (3)].c2).char2);
@@ -13256,7 +13260,7 @@ yyreduce:
     break;
 
   case 498:
-#line 5526 "Gmsh.y"
+#line 5530 "Gmsh.y"
     {
       std::string struct_namespace((yyvsp[(2) - (7)].c2).char1? (yyvsp[(2) - (7)].c2).char1 : std::string("")),
         struct_name((yyvsp[(2) - (7)].c2).char2);
@@ -13272,100 +13276,100 @@ yyreduce:
     break;
 
   case 499:
-#line 5542 "Gmsh.y"
+#line 5546 "Gmsh.y"
     { (yyval.c2).char1 = NULL; (yyval.c2).char2 = (yyvsp[(1) - (1)].c); ;}
     break;
 
   case 500:
-#line 5544 "Gmsh.y"
+#line 5548 "Gmsh.y"
     { (yyval.c2).char1 = (yyvsp[(1) - (3)].c); (yyval.c2).char2 = (yyvsp[(3) - (3)].c); ;}
     break;
 
   case 501:
-#line 5549 "Gmsh.y"
+#line 5553 "Gmsh.y"
     { (yyval.i) = 99; ;}
     break;
 
   case 502:
-#line 5551 "Gmsh.y"
+#line 5555 "Gmsh.y"
     { (yyval.i) = (int)(yyvsp[(2) - (2)].d); ;}
     break;
 
   case 503:
-#line 5556 "Gmsh.y"
+#line 5560 "Gmsh.y"
     { (yyval.i) = 0; ;}
     break;
 
   case 504:
-#line 5558 "Gmsh.y"
+#line 5562 "Gmsh.y"
     { (yyval.i) = (yyvsp[(2) - (3)].i); ;}
     break;
 
   case 505:
-#line 5563 "Gmsh.y"
+#line 5567 "Gmsh.y"
     {
       memcpy((yyval.v), (yyvsp[(1) - (1)].v), 5*sizeof(double));
     ;}
     break;
 
   case 506:
-#line 5567 "Gmsh.y"
+#line 5571 "Gmsh.y"
     {
       for(int i = 0; i < 5; i++) (yyval.v)[i] = -(yyvsp[(2) - (2)].v)[i];
     ;}
     break;
 
   case 507:
-#line 5571 "Gmsh.y"
+#line 5575 "Gmsh.y"
     {
       for(int i = 0; i < 5; i++) (yyval.v)[i] = (yyvsp[(2) - (2)].v)[i];
     ;}
     break;
 
   case 508:
-#line 5575 "Gmsh.y"
+#line 5579 "Gmsh.y"
     {
       for(int i = 0; i < 5; i++) (yyval.v)[i] = (yyvsp[(1) - (3)].v)[i] - (yyvsp[(3) - (3)].v)[i];
     ;}
     break;
 
   case 509:
-#line 5579 "Gmsh.y"
+#line 5583 "Gmsh.y"
     {
       for(int i = 0; i < 5; i++) (yyval.v)[i] = (yyvsp[(1) - (3)].v)[i] + (yyvsp[(3) - (3)].v)[i];
     ;}
     break;
 
   case 510:
-#line 5586 "Gmsh.y"
+#line 5590 "Gmsh.y"
     {
       (yyval.v)[0] = (yyvsp[(2) - (11)].d);  (yyval.v)[1] = (yyvsp[(4) - (11)].d);  (yyval.v)[2] = (yyvsp[(6) - (11)].d);  (yyval.v)[3] = (yyvsp[(8) - (11)].d); (yyval.v)[4] = (yyvsp[(10) - (11)].d);
     ;}
     break;
 
   case 511:
-#line 5590 "Gmsh.y"
+#line 5594 "Gmsh.y"
     {
       (yyval.v)[0] = (yyvsp[(2) - (9)].d);  (yyval.v)[1] = (yyvsp[(4) - (9)].d);  (yyval.v)[2] = (yyvsp[(6) - (9)].d);  (yyval.v)[3] = (yyvsp[(8) - (9)].d); (yyval.v)[4] = 1.0;
     ;}
     break;
 
   case 512:
-#line 5594 "Gmsh.y"
+#line 5598 "Gmsh.y"
     {
       (yyval.v)[0] = (yyvsp[(2) - (7)].d);  (yyval.v)[1] = (yyvsp[(4) - (7)].d);  (yyval.v)[2] = (yyvsp[(6) - (7)].d);  (yyval.v)[3] = 0.0; (yyval.v)[4] = 1.0;
     ;}
     break;
 
   case 513:
-#line 5598 "Gmsh.y"
+#line 5602 "Gmsh.y"
     {
       (yyval.v)[0] = (yyvsp[(2) - (7)].d);  (yyval.v)[1] = (yyvsp[(4) - (7)].d);  (yyval.v)[2] = (yyvsp[(6) - (7)].d);  (yyval.v)[3] = 0.0; (yyval.v)[4] = 1.0;
     ;}
     break;
 
   case 514:
-#line 5605 "Gmsh.y"
+#line 5609 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(List_T*));
       List_Add((yyval.l), &((yyvsp[(1) - (1)].l)));
@@ -13373,14 +13377,14 @@ yyreduce:
     break;
 
   case 515:
-#line 5610 "Gmsh.y"
+#line 5614 "Gmsh.y"
     {
       List_Add((yyval.l), &((yyvsp[(3) - (3)].l)));
     ;}
     break;
 
   case 516:
-#line 5617 "Gmsh.y"
+#line 5621 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(double));
       List_Add((yyval.l), &((yyvsp[(1) - (1)].d)));
@@ -13388,14 +13392,14 @@ yyreduce:
     break;
 
   case 517:
-#line 5622 "Gmsh.y"
+#line 5626 "Gmsh.y"
     {
       (yyval.l) = (yyvsp[(1) - (1)].l);
     ;}
     break;
 
   case 518:
-#line 5626 "Gmsh.y"
+#line 5630 "Gmsh.y"
     {
       // creates an empty list
       (yyval.l) = List_Create(2, 1, sizeof(double));
@@ -13403,14 +13407,14 @@ yyreduce:
     break;
 
   case 519:
-#line 5631 "Gmsh.y"
+#line 5635 "Gmsh.y"
     {
       (yyval.l) = (yyvsp[(2) - (3)].l);
     ;}
     break;
 
   case 520:
-#line 5635 "Gmsh.y"
+#line 5639 "Gmsh.y"
     {
       (yyval.l) = (yyvsp[(3) - (4)].l);
       for(int i = 0; i < List_Nbr((yyval.l)); i++){
@@ -13421,7 +13425,7 @@ yyreduce:
     break;
 
   case 521:
-#line 5643 "Gmsh.y"
+#line 5647 "Gmsh.y"
     {
       (yyval.l) = (yyvsp[(4) - (5)].l);
       for(int i = 0; i < List_Nbr((yyval.l)); i++){
@@ -13432,21 +13436,21 @@ yyreduce:
     break;
 
   case 522:
-#line 5654 "Gmsh.y"
+#line 5658 "Gmsh.y"
     {
       (yyval.l) = (yyvsp[(1) - (1)].l);
     ;}
     break;
 
   case 523:
-#line 5658 "Gmsh.y"
+#line 5662 "Gmsh.y"
     {
       (yyval.l) = 0;
     ;}
     break;
 
   case 524:
-#line 5662 "Gmsh.y"
+#line 5666 "Gmsh.y"
     {
       if(!strcmp((yyvsp[(1) - (1)].c), "*") || !strcmp((yyvsp[(1) - (1)].c), "all")){
         (yyval.l) = 0;
@@ -13460,7 +13464,7 @@ yyreduce:
     break;
 
   case 525:
-#line 5676 "Gmsh.y"
+#line 5680 "Gmsh.y"
     {
       (yyval.l) = (yyvsp[(2) - (2)].l);
       for(int i = 0; i < List_Nbr((yyval.l)); i++){
@@ -13471,7 +13475,7 @@ yyreduce:
     break;
 
   case 526:
-#line 5684 "Gmsh.y"
+#line 5688 "Gmsh.y"
     {
       (yyval.l) = (yyvsp[(3) - (3)].l);
       for(int i = 0; i < List_Nbr((yyval.l)); i++){
@@ -13482,7 +13486,7 @@ yyreduce:
     break;
 
   case 527:
-#line 5692 "Gmsh.y"
+#line 5696 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(double));
       for(double d = (yyvsp[(1) - (3)].d); ((yyvsp[(1) - (3)].d) < (yyvsp[(3) - (3)].d)) ? (d <= (yyvsp[(3) - (3)].d)) : (d >= (yyvsp[(3) - (3)].d));
@@ -13492,7 +13496,7 @@ yyreduce:
     break;
 
   case 528:
-#line 5699 "Gmsh.y"
+#line 5703 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(double));
       if(!(yyvsp[(5) - (5)].d)){  //|| ($1 < $3 && $5 < 0) || ($1 > $3 && $5 > 0)
@@ -13505,7 +13509,7 @@ yyreduce:
     break;
 
   case 529:
-#line 5709 "Gmsh.y"
+#line 5713 "Gmsh.y"
     {
       (yyval.l) = List_Create(3, 1, sizeof(double));
       int tag = (int)(yyvsp[(3) - (4)].d);
@@ -13531,7 +13535,7 @@ yyreduce:
     break;
 
   case 530:
-#line 5732 "Gmsh.y"
+#line 5736 "Gmsh.y"
     {
       (yyval.l) = List_Create(10, 10, sizeof(double));
       getAllElementaryTags(0, (yyval.l));
@@ -13539,7 +13543,7 @@ yyreduce:
     break;
 
   case 531:
-#line 5737 "Gmsh.y"
+#line 5741 "Gmsh.y"
     {
       (yyval.l) = List_Create(10, 10, sizeof(double));
       getAllElementaryTags(0, (yyval.l));
@@ -13548,7 +13552,7 @@ yyreduce:
     break;
 
   case 532:
-#line 5743 "Gmsh.y"
+#line 5747 "Gmsh.y"
     {
       (yyval.l) = List_Create(10, 10, sizeof(double));
       getAllElementaryTags((yyvsp[(1) - (4)].i), (yyval.l));
@@ -13556,7 +13560,7 @@ yyreduce:
     break;
 
   case 533:
-#line 5748 "Gmsh.y"
+#line 5752 "Gmsh.y"
     {
       (yyval.l) = List_Create(10, 10, sizeof(double));
       getAllElementaryTags((yyvsp[(1) - (2)].i), (yyval.l));
@@ -13565,7 +13569,7 @@ yyreduce:
     break;
 
   case 534:
-#line 5754 "Gmsh.y"
+#line 5758 "Gmsh.y"
     {
       (yyval.l) = List_Create(10, 10, sizeof(double));
       if(!(yyvsp[(3) - (3)].l)){
@@ -13579,7 +13583,7 @@ yyreduce:
     break;
 
   case 535:
-#line 5765 "Gmsh.y"
+#line 5769 "Gmsh.y"
     {
       (yyval.l) = List_Create(10, 10, sizeof(double));
       getParentTags((yyvsp[(2) - (3)].i), (yyvsp[(3) - (3)].l), (yyval.l));
@@ -13588,7 +13592,7 @@ yyreduce:
     break;
 
   case 536:
-#line 5771 "Gmsh.y"
+#line 5775 "Gmsh.y"
     {
       (yyval.l) = List_Create(10, 10, sizeof(double));
       if(List_Nbr((yyvsp[(4) - (4)].l)) < 6) {
@@ -13605,7 +13609,7 @@ yyreduce:
     break;
 
   case 537:
-#line 5785 "Gmsh.y"
+#line 5789 "Gmsh.y"
     {
       (yyval.l) = List_Create(10, 10, sizeof(double));
       getBoundingBox((yyvsp[(2) - (5)].i), (yyvsp[(4) - (5)].l), (yyval.l));
@@ -13614,7 +13618,7 @@ yyreduce:
     break;
 
   case 538:
-#line 5791 "Gmsh.y"
+#line 5795 "Gmsh.y"
     {
       (yyval.l) = List_Create(1, 1, sizeof(double));
       double m = 0;
@@ -13629,7 +13633,7 @@ yyreduce:
     break;
 
   case 539:
-#line 5803 "Gmsh.y"
+#line 5807 "Gmsh.y"
     {
       (yyval.l) = List_Create(3, 1, sizeof(double));
       double x = 0., y = 0., z = 0.;
@@ -13646,7 +13650,7 @@ yyreduce:
     break;
 
   case 540:
-#line 5817 "Gmsh.y"
+#line 5821 "Gmsh.y"
     {
       (yyval.l) = List_Create(List_Nbr((yyvsp[(1) - (1)].l)), 1, sizeof(double));
       for(int i = 0; i < List_Nbr((yyvsp[(1) - (1)].l)); i++){
@@ -13659,7 +13663,7 @@ yyreduce:
     break;
 
   case 541:
-#line 5827 "Gmsh.y"
+#line 5831 "Gmsh.y"
     {
       (yyval.l) = List_Create(List_Nbr((yyvsp[(1) - (1)].l)), 1, sizeof(double));
       for(int i = 0; i < List_Nbr((yyvsp[(1) - (1)].l)); i++){
@@ -13672,7 +13676,7 @@ yyreduce:
     break;
 
   case 542:
-#line 5837 "Gmsh.y"
+#line 5841 "Gmsh.y"
     {
       (yyval.l) = List_Create(List_Nbr((yyvsp[(1) - (1)].l)), 1, sizeof(double));
       for(int i = 0; i < List_Nbr((yyvsp[(1) - (1)].l)); i++){
@@ -13685,7 +13689,7 @@ yyreduce:
     break;
 
   case 543:
-#line 5847 "Gmsh.y"
+#line 5851 "Gmsh.y"
     {
       (yyval.l) = List_Create(20, 20, sizeof(double));
       if(!gmsh_yysymbols.count((yyvsp[(1) - (3)].c)))
@@ -13700,21 +13704,21 @@ yyreduce:
     break;
 
   case 544:
-#line 5859 "Gmsh.y"
+#line 5863 "Gmsh.y"
     {
       (yyval.l) = treat_Struct_FullName_dot_tSTRING_ListOfFloat(NULL, (yyvsp[(1) - (5)].c), (yyvsp[(3) - (5)].c));
     ;}
     break;
 
   case 545:
-#line 5863 "Gmsh.y"
+#line 5867 "Gmsh.y"
     {
       (yyval.l) = treat_Struct_FullName_dot_tSTRING_ListOfFloat((yyvsp[(1) - (7)].c), (yyvsp[(3) - (7)].c), (yyvsp[(5) - (7)].c));
     ;}
     break;
 
   case 546:
-#line 5868 "Gmsh.y"
+#line 5872 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(double));
       if(!gmsh_yysymbols.count((yyvsp[(3) - (4)].c)))
@@ -13729,28 +13733,28 @@ yyreduce:
     break;
 
   case 547:
-#line 5880 "Gmsh.y"
+#line 5884 "Gmsh.y"
     {
       (yyval.l) = (yyvsp[(3) - (4)].l);
     ;}
     break;
 
   case 548:
-#line 5884 "Gmsh.y"
+#line 5888 "Gmsh.y"
     {
       (yyval.l) = (yyvsp[(3) - (4)].l);
     ;}
     break;
 
   case 549:
-#line 5888 "Gmsh.y"
+#line 5892 "Gmsh.y"
     {
       (yyval.l) = (yyvsp[(4) - (6)].l);
     ;}
     break;
 
   case 550:
-#line 5892 "Gmsh.y"
+#line 5896 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(double));
       if(!gmsh_yysymbols.count((yyvsp[(1) - (6)].c)))
@@ -13771,7 +13775,7 @@ yyreduce:
     break;
 
   case 551:
-#line 5910 "Gmsh.y"
+#line 5914 "Gmsh.y"
     {
       (yyval.l) = List_Create(20,20,sizeof(double));
       for(int i = 0; i < (int)(yyvsp[(7) - (8)].d); i++) {
@@ -13782,7 +13786,7 @@ yyreduce:
     break;
 
   case 552:
-#line 5918 "Gmsh.y"
+#line 5922 "Gmsh.y"
     {
       (yyval.l) = List_Create(20,20,sizeof(double));
       for(int i = 0; i < (int)(yyvsp[(7) - (8)].d); i++) {
@@ -13793,7 +13797,7 @@ yyreduce:
     break;
 
   case 553:
-#line 5926 "Gmsh.y"
+#line 5930 "Gmsh.y"
     {
       Msg::Barrier();
       FILE *File;
@@ -13825,7 +13829,7 @@ yyreduce:
     break;
 
   case 554:
-#line 5955 "Gmsh.y"
+#line 5959 "Gmsh.y"
     {
       double x0 = (yyvsp[(3) - (14)].d), x1 = (yyvsp[(5) - (14)].d), y0 = (yyvsp[(7) - (14)].d), y1 = (yyvsp[(9) - (14)].d), ys = (yyvsp[(11) - (14)].d);
       int N = (int)(yyvsp[(13) - (14)].d);
@@ -13838,7 +13842,7 @@ yyreduce:
     break;
 
   case 555:
-#line 5965 "Gmsh.y"
+#line 5969 "Gmsh.y"
     {
       std::vector<double> tmp;
       for(int i = 0; i < List_Nbr((yyvsp[(3) - (4)].l)); i++){
@@ -13857,7 +13861,7 @@ yyreduce:
     break;
 
   case 556:
-#line 5981 "Gmsh.y"
+#line 5985 "Gmsh.y"
     {
       for(int i = 0; i < List_Nbr((yyvsp[(3) - (4)].l)); i++){
         double *d = (double*)List_Pointer((yyvsp[(3) - (4)].l), i);
@@ -13868,7 +13872,7 @@ yyreduce:
     break;
 
   case 557:
-#line 5992 "Gmsh.y"
+#line 5996 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(double));
       List_Add((yyval.l), &((yyvsp[(1) - (1)].d)));
@@ -13876,21 +13880,21 @@ yyreduce:
     break;
 
   case 558:
-#line 5997 "Gmsh.y"
+#line 6001 "Gmsh.y"
     {
       (yyval.l) = (yyvsp[(1) - (1)].l);
     ;}
     break;
 
   case 559:
-#line 6001 "Gmsh.y"
+#line 6005 "Gmsh.y"
     {
       List_Add((yyval.l), &((yyvsp[(3) - (3)].d)));
     ;}
     break;
 
   case 560:
-#line 6005 "Gmsh.y"
+#line 6009 "Gmsh.y"
     {
       for(int i = 0; i < List_Nbr((yyvsp[(3) - (3)].l)); i++){
 	double d;
@@ -13902,21 +13906,21 @@ yyreduce:
     break;
 
   case 561:
-#line 6017 "Gmsh.y"
+#line 6021 "Gmsh.y"
     {
       (yyval.u) = CTX::instance()->packColor((int)(yyvsp[(2) - (9)].d), (int)(yyvsp[(4) - (9)].d), (int)(yyvsp[(6) - (9)].d), (int)(yyvsp[(8) - (9)].d));
     ;}
     break;
 
   case 562:
-#line 6021 "Gmsh.y"
+#line 6025 "Gmsh.y"
     {
       (yyval.u) = CTX::instance()->packColor((int)(yyvsp[(2) - (7)].d), (int)(yyvsp[(4) - (7)].d), (int)(yyvsp[(6) - (7)].d), 255);
     ;}
     break;
 
   case 563:
-#line 6033 "Gmsh.y"
+#line 6037 "Gmsh.y"
     {
       int flag = 0;
       if(gmsh_yystringsymbols.count((yyvsp[(1) - (1)].c))){
@@ -13936,7 +13940,7 @@ yyreduce:
     break;
 
   case 564:
-#line 6050 "Gmsh.y"
+#line 6054 "Gmsh.y"
     {
       unsigned int val = 0;
       ColorOption(GMSH_GET, (yyvsp[(1) - (5)].c), 0, (yyvsp[(5) - (5)].c), val);
@@ -13946,14 +13950,14 @@ yyreduce:
     break;
 
   case 565:
-#line 6060 "Gmsh.y"
+#line 6064 "Gmsh.y"
     {
       (yyval.l) = (yyvsp[(2) - (3)].l);
     ;}
     break;
 
   case 566:
-#line 6064 "Gmsh.y"
+#line 6068 "Gmsh.y"
     {
       (yyval.l) = List_Create(256, 10, sizeof(unsigned int));
       GmshColorTable *ct = GetColorTable((int)(yyvsp[(3) - (6)].d));
@@ -13968,7 +13972,7 @@ yyreduce:
     break;
 
   case 567:
-#line 6079 "Gmsh.y"
+#line 6083 "Gmsh.y"
     {
       (yyval.l) = List_Create(256, 10, sizeof(unsigned int));
       List_Add((yyval.l), &((yyvsp[(1) - (1)].u)));
@@ -13976,21 +13980,21 @@ yyreduce:
     break;
 
   case 568:
-#line 6084 "Gmsh.y"
+#line 6088 "Gmsh.y"
     {
       List_Add((yyval.l), &((yyvsp[(3) - (3)].u)));
     ;}
     break;
 
   case 569:
-#line 6091 "Gmsh.y"
+#line 6095 "Gmsh.y"
     {
       (yyval.c) = (yyvsp[(1) - (1)].c);
     ;}
     break;
 
   case 570:
-#line 6095 "Gmsh.y"
+#line 6099 "Gmsh.y"
     {
       // No need to extend to Struct_FullName (a Tag is not a String)
       (yyval.c) = treat_Struct_FullName_String(NULL, (yyvsp[(1) - (1)].c));
@@ -13998,7 +14002,7 @@ yyreduce:
     break;
 
   case 571:
-#line 6100 "Gmsh.y"
+#line 6104 "Gmsh.y"
     {
       std::string val;
       int j = (int)(yyvsp[(3) - (4)].d);
@@ -14015,7 +14019,7 @@ yyreduce:
     break;
 
   case 572:
-#line 6114 "Gmsh.y"
+#line 6118 "Gmsh.y"
     {
       std::string val;
       int j = (int)(yyvsp[(3) - (4)].d);
@@ -14032,35 +14036,35 @@ yyreduce:
     break;
 
   case 573:
-#line 6128 "Gmsh.y"
+#line 6132 "Gmsh.y"
     {
       (yyval.c) = treat_Struct_FullName_dot_tSTRING_String(NULL, (yyvsp[(1) - (3)].c), (yyvsp[(3) - (3)].c));
     ;}
     break;
 
   case 574:
-#line 6132 "Gmsh.y"
+#line 6136 "Gmsh.y"
     {
       (yyval.c) = treat_Struct_FullName_dot_tSTRING_String((yyvsp[(1) - (5)].c), (yyvsp[(3) - (5)].c), (yyvsp[(5) - (5)].c));
     ;}
     break;
 
   case 575:
-#line 6136 "Gmsh.y"
+#line 6140 "Gmsh.y"
     {
       (yyval.c) = treat_Struct_FullName_dot_tSTRING_String(NULL, (yyvsp[(1) - (6)].c), (yyvsp[(3) - (6)].c), (int)(yyvsp[(5) - (6)].d));
     ;}
     break;
 
   case 576:
-#line 6140 "Gmsh.y"
+#line 6144 "Gmsh.y"
     {
       (yyval.c) = treat_Struct_FullName_dot_tSTRING_String((yyvsp[(1) - (8)].c), (yyvsp[(3) - (8)].c), (yyvsp[(5) - (8)].c), (int)(yyvsp[(7) - (8)].d));
     ;}
     break;
 
   case 577:
-#line 6144 "Gmsh.y"
+#line 6148 "Gmsh.y"
     {
       std::string out;
       StringOption(GMSH_GET, (yyvsp[(1) - (6)].c), (int)(yyvsp[(3) - (6)].d), (yyvsp[(6) - (6)].c), out);
@@ -14071,7 +14075,7 @@ yyreduce:
     break;
 
   case 578:
-#line 6152 "Gmsh.y"
+#line 6156 "Gmsh.y"
     {
       std::string name = GModel::current()->getElementaryName((yyvsp[(1) - (4)].i), (int)(yyvsp[(3) - (4)].d));
       (yyval.c) = (char*)Malloc((name.size() + 1) * sizeof(char));
@@ -14080,7 +14084,7 @@ yyreduce:
     break;
 
   case 579:
-#line 6158 "Gmsh.y"
+#line 6162 "Gmsh.y"
     {
       std::string name = GModel::current()->getPhysicalName((yyvsp[(2) - (5)].i), (int)(yyvsp[(4) - (5)].d));
       (yyval.c) = (char*)Malloc((name.size() + 1) * sizeof(char));
@@ -14089,21 +14093,21 @@ yyreduce:
     break;
 
   case 580:
-#line 6167 "Gmsh.y"
+#line 6171 "Gmsh.y"
     {
       (yyval.c) = (yyvsp[(1) - (1)].c);
     ;}
     break;
 
   case 581:
-#line 6171 "Gmsh.y"
+#line 6175 "Gmsh.y"
     {
       (yyval.c) = (yyvsp[(3) - (4)].c);
     ;}
     break;
 
   case 582:
-#line 6175 "Gmsh.y"
+#line 6179 "Gmsh.y"
     {
       (yyval.c) = (char *)Malloc(32 * sizeof(char));
       time_t now;
@@ -14114,7 +14118,7 @@ yyreduce:
     break;
 
   case 583:
-#line 6183 "Gmsh.y"
+#line 6187 "Gmsh.y"
     {
       std::string exe = Msg::GetExecutableName();
       (yyval.c) = (char *)Malloc(exe.size() + 1);
@@ -14123,7 +14127,7 @@ yyreduce:
     break;
 
   case 584:
-#line 6189 "Gmsh.y"
+#line 6193 "Gmsh.y"
     {
       std::string action = Msg::GetOnelabAction();
       (yyval.c) = (char *)Malloc(action.size() + 1);
@@ -14132,14 +14136,14 @@ yyreduce:
     break;
 
   case 585:
-#line 6195 "Gmsh.y"
+#line 6199 "Gmsh.y"
     {
       (yyval.c) = strsave((char*)"Gmsh");
     ;}
     break;
 
   case 586:
-#line 6199 "Gmsh.y"
+#line 6203 "Gmsh.y"
     {
       std::string env = GetEnvironmentVar((yyvsp[(3) - (4)].c));
       (yyval.c) = (char *)Malloc((env.size() + 1) * sizeof(char));
@@ -14149,7 +14153,7 @@ yyreduce:
     break;
 
   case 587:
-#line 6206 "Gmsh.y"
+#line 6210 "Gmsh.y"
     {
       std::string s = Msg::GetString((yyvsp[(3) - (6)].c), (yyvsp[(5) - (6)].c));
       (yyval.c) = (char *)Malloc((s.size() + 1) * sizeof(char));
@@ -14160,7 +14164,7 @@ yyreduce:
     break;
 
   case 588:
-#line 6214 "Gmsh.y"
+#line 6218 "Gmsh.y"
     {
       std::string s = Msg::GetOnelabString((yyvsp[(3) - (4)].c));
       (yyval.c) = (char *)Malloc((s.size() + 1) * sizeof(char));
@@ -14170,7 +14174,7 @@ yyreduce:
     break;
 
   case 589:
-#line 6221 "Gmsh.y"
+#line 6225 "Gmsh.y"
     {
       std::string s = Msg::GetOnelabString((yyvsp[(3) - (6)].c), (yyvsp[(5) - (6)].c));
       (yyval.c) = (char *)Malloc((s.size() + 1) * sizeof(char));
@@ -14181,21 +14185,21 @@ yyreduce:
     break;
 
   case 590:
-#line 6230 "Gmsh.y"
+#line 6234 "Gmsh.y"
     {
       (yyval.c) = treat_Struct_FullName_String(NULL, (yyvsp[(3) - (5)].c2).char2, 1, 0, (yyvsp[(4) - (5)].c), 2);
     ;}
     break;
 
   case 591:
-#line 6234 "Gmsh.y"
+#line 6238 "Gmsh.y"
     {
       (yyval.c) = treat_Struct_FullName_dot_tSTRING_String((yyvsp[(3) - (7)].c2).char1, (yyvsp[(3) - (7)].c2).char2, (yyvsp[(5) - (7)].c), 0, (yyvsp[(6) - (7)].c), 2);
     ;}
     break;
 
   case 592:
-#line 6238 "Gmsh.y"
+#line 6242 "Gmsh.y"
     {
       int size = 1;
       for(int i = 0; i < List_Nbr((yyvsp[(3) - (4)].l)); i++)
@@ -14213,7 +14217,7 @@ yyreduce:
     break;
 
   case 593:
-#line 6253 "Gmsh.y"
+#line 6257 "Gmsh.y"
     {
       (yyval.c) = (char *)Malloc((strlen((yyvsp[(3) - (4)].c)) + 1) * sizeof(char));
       int i;
@@ -14230,7 +14234,7 @@ yyreduce:
     break;
 
   case 594:
-#line 6267 "Gmsh.y"
+#line 6271 "Gmsh.y"
     {
       (yyval.c) = (char *)Malloc((strlen((yyvsp[(3) - (4)].c)) + 1) * sizeof(char));
       int i;
@@ -14247,7 +14251,7 @@ yyreduce:
     break;
 
   case 595:
-#line 6281 "Gmsh.y"
+#line 6285 "Gmsh.y"
     {
       std::string input = (yyvsp[(3) - (8)].c);
       std::string substr_old = (yyvsp[(5) - (8)].c);
@@ -14262,7 +14266,7 @@ yyreduce:
     break;
 
   case 596:
-#line 6293 "Gmsh.y"
+#line 6297 "Gmsh.y"
     {
       int size = 1;
       for(int i = 0; i < List_Nbr((yyvsp[(3) - (4)].l)); i++)
@@ -14281,7 +14285,7 @@ yyreduce:
     break;
 
   case 597:
-#line 6309 "Gmsh.y"
+#line 6313 "Gmsh.y"
     {
       int i = 0;
       while ((yyvsp[(3) - (4)].c)[i]) {
@@ -14293,7 +14297,7 @@ yyreduce:
     break;
 
   case 598:
-#line 6318 "Gmsh.y"
+#line 6322 "Gmsh.y"
     {
       int i = 0;
       while ((yyvsp[(3) - (4)].c)[i]) {
@@ -14305,7 +14309,7 @@ yyreduce:
     break;
 
   case 599:
-#line 6327 "Gmsh.y"
+#line 6331 "Gmsh.y"
     {
       int i = 0;
       while ((yyvsp[(3) - (4)].c)[i]) {
@@ -14318,7 +14322,7 @@ yyreduce:
     break;
 
   case 600:
-#line 6337 "Gmsh.y"
+#line 6341 "Gmsh.y"
     {
       if((yyvsp[(3) - (8)].d)){
         (yyval.c) = (yyvsp[(5) - (8)].c);
@@ -14332,7 +14336,7 @@ yyreduce:
     break;
 
   case 601:
-#line 6348 "Gmsh.y"
+#line 6352 "Gmsh.y"
     {
       std::string in = (yyvsp[(3) - (8)].c);
       std::string out = in.substr((int)(yyvsp[(5) - (8)].d), (int)(yyvsp[(7) - (8)].d));
@@ -14343,7 +14347,7 @@ yyreduce:
     break;
 
   case 602:
-#line 6356 "Gmsh.y"
+#line 6360 "Gmsh.y"
     {
       std::string in = (yyvsp[(3) - (6)].c);
       std::string out = in.substr((int)(yyvsp[(5) - (6)].d), std::string::npos);
@@ -14354,14 +14358,14 @@ yyreduce:
     break;
 
   case 603:
-#line 6364 "Gmsh.y"
+#line 6368 "Gmsh.y"
     {
       (yyval.c) = (yyvsp[(3) - (4)].c);
     ;}
     break;
 
   case 604:
-#line 6368 "Gmsh.y"
+#line 6372 "Gmsh.y"
     {
       char tmpstring[5000];
       int i = printListOfDouble((yyvsp[(3) - (6)].c), (yyvsp[(5) - (6)].l), tmpstring);
@@ -14383,7 +14387,7 @@ yyreduce:
     break;
 
   case 605:
-#line 6387 "Gmsh.y"
+#line 6391 "Gmsh.y"
     {
       std::string tmp = FixRelativePath(gmsh_yyname, (yyvsp[(3) - (4)].c));
       (yyval.c) = (char*)Malloc((tmp.size() + 1) * sizeof(char));
@@ -14393,7 +14397,7 @@ yyreduce:
     break;
 
   case 606:
-#line 6394 "Gmsh.y"
+#line 6398 "Gmsh.y"
     {
       std::string tmp = SplitFileName(GetAbsolutePath(gmsh_yyname))[0];
       (yyval.c) = (char*)Malloc((tmp.size() + 1) * sizeof(char));
@@ -14402,7 +14406,7 @@ yyreduce:
     break;
 
   case 607:
-#line 6400 "Gmsh.y"
+#line 6404 "Gmsh.y"
     {
       std::string tmp = GetFileNameWithoutPath(gmsh_yyname);
       (yyval.c) = (char*)Malloc((tmp.size() + 1) * sizeof(char));
@@ -14411,7 +14415,7 @@ yyreduce:
     break;
 
   case 608:
-#line 6406 "Gmsh.y"
+#line 6410 "Gmsh.y"
     {
       std::string tmp = SplitFileName((yyvsp[(3) - (4)].c))[0];
       (yyval.c) = (char*)Malloc((tmp.size() + 1) * sizeof(char));
@@ -14421,7 +14425,7 @@ yyreduce:
     break;
 
   case 609:
-#line 6413 "Gmsh.y"
+#line 6417 "Gmsh.y"
     {
       std::string tmp = GetAbsolutePath((yyvsp[(3) - (4)].c));
       (yyval.c) = (char*)Malloc((tmp.size() + 1) * sizeof(char));
@@ -14431,12 +14435,12 @@ yyreduce:
     break;
 
   case 610:
-#line 6420 "Gmsh.y"
+#line 6424 "Gmsh.y"
     { init_options(); ;}
     break;
 
   case 611:
-#line 6422 "Gmsh.y"
+#line 6426 "Gmsh.y"
     {
       std::string val((yyvsp[(3) - (6)].c));
       Msg::ExchangeOnelabParameter("", val, floatOptions, charOptions);
@@ -14447,7 +14451,7 @@ yyreduce:
     break;
 
   case 612:
-#line 6430 "Gmsh.y"
+#line 6434 "Gmsh.y"
     {
       std::string out;
       const std::string * key_struct = NULL;
@@ -14471,37 +14475,37 @@ yyreduce:
     break;
 
   case 613:
-#line 6454 "Gmsh.y"
+#line 6458 "Gmsh.y"
     { struct_namespace = std::string(""); (yyval.d) = (yyvsp[(2) - (2)].d); ;}
     break;
 
   case 614:
-#line 6456 "Gmsh.y"
+#line 6460 "Gmsh.y"
     { struct_namespace = (yyvsp[(1) - (4)].c); Free((yyvsp[(1) - (4)].c)); (yyval.d) = (yyvsp[(4) - (4)].d); ;}
     break;
 
   case 615:
-#line 6462 "Gmsh.y"
+#line 6466 "Gmsh.y"
     { (yyval.l) = (yyvsp[(3) - (4)].l); ;}
     break;
 
   case 616:
-#line 6467 "Gmsh.y"
+#line 6471 "Gmsh.y"
     { (yyval.l) = (yyvsp[(1) - (1)].l); ;}
     break;
 
   case 617:
-#line 6469 "Gmsh.y"
+#line 6473 "Gmsh.y"
     { (yyval.l) = (yyvsp[(1) - (1)].l); ;}
     break;
 
   case 618:
-#line 6474 "Gmsh.y"
+#line 6478 "Gmsh.y"
     { (yyval.l) = (yyvsp[(2) - (3)].l); ;}
     break;
 
   case 619:
-#line 6479 "Gmsh.y"
+#line 6483 "Gmsh.y"
     {
       (yyval.l) = List_Create(20,20,sizeof(char*));
       List_Add((yyval.l), &((yyvsp[(1) - (1)].c)));
@@ -14509,19 +14513,19 @@ yyreduce:
     break;
 
   case 620:
-#line 6484 "Gmsh.y"
+#line 6488 "Gmsh.y"
     { (yyval.l) = (yyvsp[(1) - (1)].l); ;}
     break;
 
   case 621:
-#line 6486 "Gmsh.y"
+#line 6490 "Gmsh.y"
     {
       List_Add((yyval.l), &((yyvsp[(3) - (3)].c)));
     ;}
     break;
 
   case 622:
-#line 6490 "Gmsh.y"
+#line 6494 "Gmsh.y"
     {
       for(int i = 0; i < List_Nbr((yyvsp[(3) - (3)].l)); i++){
 	char* c;
@@ -14533,7 +14537,7 @@ yyreduce:
     break;
 
   case 623:
-#line 6502 "Gmsh.y"
+#line 6506 "Gmsh.y"
     {
       (yyval.l) = List_Create(20, 20, sizeof(char *));
       if(!gmsh_yystringsymbols.count((yyvsp[(1) - (3)].c)))
@@ -14550,21 +14554,21 @@ yyreduce:
     break;
 
   case 624:
-#line 6516 "Gmsh.y"
+#line 6520 "Gmsh.y"
     {
       (yyval.l) = treat_Struct_FullName_dot_tSTRING_ListOfString(NULL, (yyvsp[(1) - (5)].c), (yyvsp[(3) - (5)].c));
     ;}
     break;
 
   case 625:
-#line 6520 "Gmsh.y"
+#line 6524 "Gmsh.y"
     {
       (yyval.l) = treat_Struct_FullName_dot_tSTRING_ListOfString((yyvsp[(1) - (7)].c), (yyvsp[(3) - (7)].c), (yyvsp[(5) - (7)].c));
     ;}
     break;
 
   case 626:
-#line 6527 "Gmsh.y"
+#line 6531 "Gmsh.y"
     {
       char tmpstr[256];
       sprintf(tmpstr, "_%d", (int)(yyvsp[(4) - (5)].d));
@@ -14575,7 +14579,7 @@ yyreduce:
     break;
 
   case 627:
-#line 6535 "Gmsh.y"
+#line 6539 "Gmsh.y"
     {
       char tmpstr[256];
       sprintf(tmpstr, "_%d", (int)(yyvsp[(4) - (5)].d));
@@ -14586,7 +14590,7 @@ yyreduce:
     break;
 
   case 628:
-#line 6543 "Gmsh.y"
+#line 6547 "Gmsh.y"
     {
       char tmpstr[256];
       sprintf(tmpstr, "_%d", (int)(yyvsp[(7) - (8)].d));
@@ -14597,23 +14601,23 @@ yyreduce:
     break;
 
   case 629:
-#line 6554 "Gmsh.y"
+#line 6558 "Gmsh.y"
     { (yyval.c) = (yyvsp[(1) - (1)].c); ;}
     break;
 
   case 630:
-#line 6556 "Gmsh.y"
+#line 6560 "Gmsh.y"
     { (yyval.c) = (yyvsp[(1) - (1)].c); ;}
     break;
 
   case 631:
-#line 6559 "Gmsh.y"
+#line 6563 "Gmsh.y"
     { (yyval.c) = (yyvsp[(3) - (4)].c); ;}
     break;
 
 
 /* Line 1267 of yacc.c.  */
-#line 14617 "Gmsh.tab.cpp"
+#line 14621 "Gmsh.tab.cpp"
       default: break;
     }
   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
@@ -14827,7 +14831,7 @@ yyreturn:
 }
 
 
-#line 6562 "Gmsh.y"
+#line 6566 "Gmsh.y"
 
 
 void assignVariable(const std::string &name, int index, int assignType,
diff --git a/Parser/Gmsh.y b/Parser/Gmsh.y
index 48d4a7b70c1153e6b875f604ac80e636638bc0e3..76b1e6563d197f86d732519aae96cdf52f76064e 100644
--- a/Parser/Gmsh.y
+++ b/Parser/Gmsh.y
@@ -3549,7 +3549,11 @@ Command :
     }
    | tCreateTopology tEND
     {
+      GModel::current()->makeDiscreteRegionsSimplyConnected();
+      GModel::current()->makeDiscreteFacesSimplyConnected();
       GModel::current()->createTopologyFromMesh();
+      // Warning: this clears GEO_Internals! Make it optional?
+      GModel::current()->exportDiscreteGEOInternals();
     }
   | tClassifySurfaces '{' FExpr ',' FExpr ',' FExpr '}' tEND
     {
diff --git a/api/api.texi b/api/api.texi
index cb492d754aa639b4a888221a84a39a973886a7de..bf858b3abe93129f9c1477316b75363e70ca9f58 100644
--- a/api/api.texi
+++ b/api/api.texi
@@ -1788,11 +1788,14 @@ assuming that each can be parametrized with a single map.
 @item gmsh/model/mesh/createTopology
 Create a boundary representation from the mesh if the model does not have one
 (e.g. when imported from mesh file formats with no BRep representation of the
-underlying model).
+underlying model). If @code{makeSimplyConnected} is set, enforce simply
+connected discrete surfaces and volumes. If @code{exportDiscrete} is set, clear
+any built-in CAD kernel entities and export the discrete entities in the built-
+in CAD kernel.
 
 @table @asis
 @item Input:
--
+@code{makeSimplyConnected = True}, @code{exportDiscrete = True}
 @item Output:
 -
 @item Return:
diff --git a/api/gen.py b/api/gen.py
index ba6fdcf79dc70e468ed0ef8b4ba1d2c21b81e36a..8a8a3082afc236d4bb3a270cd808253caac6e9e6 100644
--- a/api/gen.py
+++ b/api/gen.py
@@ -407,8 +407,8 @@ mesh.add('classifySurfaces', doc, None, idouble('angle'), ibool('boundary', 'tru
 doc = '''Create a parametrization for discrete curves and surfaces (i.e. curves and surfaces represented solely by a mesh, without an underlying CAD description), assuming that each can be parametrized with a single map.'''
 mesh.add('createGeometry', doc, None)
 
-doc = '''Create a boundary representation from the mesh if the model does not have one (e.g. when imported from mesh file formats with no BRep representation of the underlying model).'''
-mesh.add('createTopology', doc, None)
+doc = '''Create a boundary representation from the mesh if the model does not have one (e.g. when imported from mesh file formats with no BRep representation of the underlying model). If `makeSimplyConnected' is set, enforce simply connected discrete surfaces and volumes. If `exportDiscrete' is set, clear any built-in CAD kernel entities and export the discrete entities in the built-in CAD kernel.'''
+mesh.add('createTopology', doc, None, ibool('makeSimplyConnected', 'true', 'True'), ibool('exportDiscrete', 'true', 'True'))
 
 doc = '''Compute a basis representation for homology spaces after a mesh has been generated. The computation domain is given in a list of physical group tags `domainTags'; if empty, the whole mesh is the domain. The computation subdomain for relative homology computation is given in a list of physical group tags `subdomainTags'; if empty, absolute homology is computed. The dimensions homology bases to be computed are given in the list `dim'; if empty, all bases are computed. Resulting basis representation chains are stored as physical groups in the mesh.'''
 mesh.add('computeHomology', doc, None, ivectorint('domainTags', 'std::vector<int>()', "[]", "[]"), ivectorint('subdomainTags', 'std::vector<int>()', "[]", "[]"), ivectorint('dims', 'std::vector<int>()', "[]", "[]"))
diff --git a/api/gmsh.h b/api/gmsh.h
index c7824400e1f2d3619eec0f40ab88990de03c2486..d3e5bb8fc0ab0583d1fdb5a386580e7366ecc8ea 100644
--- a/api/gmsh.h
+++ b/api/gmsh.h
@@ -1249,8 +1249,12 @@ namespace gmsh { // Top-level functions
       //
       // Create a boundary representation from the mesh if the model does not have
       // one (e.g. when imported from mesh file formats with no BRep representation
-      // of the underlying model).
-      GMSH_API void createTopology();
+      // of the underlying model). If `makeSimplyConnected' is set, enforce simply
+      // connected discrete surfaces and volumes. If `exportDiscrete' is set, clear
+      // any built-in CAD kernel entities and export the discrete entities in the
+      // built-in CAD kernel.
+      GMSH_API void createTopology(const bool makeSimplyConnected = true,
+                                   const bool exportDiscrete = true);
 
       // gmsh::model::mesh::computeHomology
       //
diff --git a/api/gmsh.h_cwrap b/api/gmsh.h_cwrap
index 0d5a0c00a96e4c3dd238564ca0ee4fe42ce873f4..efbcaf38c53d7fb3ca5926e3e72190af48c4f603 100644
--- a/api/gmsh.h_cwrap
+++ b/api/gmsh.h_cwrap
@@ -1870,11 +1870,15 @@ namespace gmsh { // Top-level functions
 
       // Create a boundary representation from the mesh if the model does not have
       // one (e.g. when imported from mesh file formats with no BRep representation
-      // of the underlying model).
-      inline void createTopology()
+      // of the underlying model). If `makeSimplyConnected' is set, enforce simply
+      // connected discrete surfaces and volumes. If `exportDiscrete' is set, clear
+      // any built-in CAD kernel entities and export the discrete entities in the
+      // built-in CAD kernel.
+      inline void createTopology(const bool makeSimplyConnected = true,
+                                 const bool exportDiscrete = true)
       {
         int ierr = 0;
-        gmshModelMeshCreateTopology(&ierr);
+        gmshModelMeshCreateTopology((int)makeSimplyConnected, (int)exportDiscrete, &ierr);
         if(ierr) throw ierr;
       }
 
diff --git a/api/gmsh.jl b/api/gmsh.jl
index 01deabd5afc8d0650f812e97d4fae3307e03c0d4..bf441c6b7a3964325bbc5fba22e6b358ba7a4a5d 100644
--- a/api/gmsh.jl
+++ b/api/gmsh.jl
@@ -2321,17 +2321,19 @@ function createGeometry()
 end
 
 """
-    gmsh.model.mesh.createTopology()
+    gmsh.model.mesh.createTopology(makeSimplyConnected = true, exportDiscrete = true)
 
 Create a boundary representation from the mesh if the model does not have one
 (e.g. when imported from mesh file formats with no BRep representation of the
-underlying model).
+underlying model). If `makeSimplyConnected` is set, enforce simply connected
+discrete surfaces and volumes. If `exportDiscrete` is set, clear any built-in
+CAD kernel entities and export the discrete entities in the built-in CAD kernel.
 """
-function createTopology()
+function createTopology(makeSimplyConnected = true, exportDiscrete = true)
     ierr = Ref{Cint}()
     ccall((:gmshModelMeshCreateTopology, gmsh.lib), Cvoid,
-          (Ptr{Cint},),
-          ierr)
+          (Cint, Cint, Ptr{Cint}),
+          makeSimplyConnected, exportDiscrete, ierr)
     ierr[] != 0 && error("gmshModelMeshCreateTopology returned non-zero error code: $(ierr[])")
     return nothing
 end
diff --git a/api/gmsh.py b/api/gmsh.py
index 5aacadf0c98d52cfbaae2c945175f00294f8d53d..e6aa77fb8dcf78abd5c33007f9645ee86a639fda 100644
--- a/api/gmsh.py
+++ b/api/gmsh.py
@@ -2957,16 +2957,21 @@ class model:
                     ierr.value)
 
         @staticmethod
-        def createTopology():
+        def createTopology(makeSimplyConnected=True, exportDiscrete=True):
             """
-            gmsh.model.mesh.createTopology()
+            gmsh.model.mesh.createTopology(makeSimplyConnected=True, exportDiscrete=True)
 
             Create a boundary representation from the mesh if the model does not have
             one (e.g. when imported from mesh file formats with no BRep representation
-            of the underlying model).
+            of the underlying model). If `makeSimplyConnected' is set, enforce simply
+            connected discrete surfaces and volumes. If `exportDiscrete' is set, clear
+            any built-in CAD kernel entities and export the discrete entities in the
+            built-in CAD kernel.
             """
             ierr = c_int()
             lib.gmshModelMeshCreateTopology(
+                c_int(bool(makeSimplyConnected)),
+                c_int(bool(exportDiscrete)),
                 byref(ierr))
             if ierr.value != 0:
                 raise ValueError(
diff --git a/api/gmshc.cpp b/api/gmshc.cpp
index 3d70e4aa53056fdfb511a2e891534ae154b21b07..a4edaab8faeef88925daa9ac34d3cec6c61198e9 100644
--- a/api/gmshc.cpp
+++ b/api/gmshc.cpp
@@ -1605,11 +1605,11 @@ GMSH_API void gmshModelMeshCreateGeometry(int * ierr)
   }
 }
 
-GMSH_API void gmshModelMeshCreateTopology(int * ierr)
+GMSH_API void gmshModelMeshCreateTopology(const int makeSimplyConnected, const int exportDiscrete, int * ierr)
 {
   if(ierr) *ierr = 0;
   try {
-    gmsh::model::mesh::createTopology();
+    gmsh::model::mesh::createTopology(makeSimplyConnected, exportDiscrete);
   }
   catch(int api_ierr_){
     if(ierr) *ierr = api_ierr_;
diff --git a/api/gmshc.h b/api/gmshc.h
index b32dd00af6a17ade9106d4649c85f767f7b18c3b..f7f5459d637efceeb36ae607e1939d22a286c354 100644
--- a/api/gmshc.h
+++ b/api/gmshc.h
@@ -1091,8 +1091,13 @@ GMSH_API void gmshModelMeshCreateGeometry(int * ierr);
 
 /* Create a boundary representation from the mesh if the model does not have
  * one (e.g. when imported from mesh file formats with no BRep representation
- * of the underlying model). */
-GMSH_API void gmshModelMeshCreateTopology(int * ierr);
+ * of the underlying model). If `makeSimplyConnected' is set, enforce simply
+ * connected discrete surfaces and volumes. If `exportDiscrete' is set, clear
+ * any built-in CAD kernel entities and export the discrete entities in the
+ * built-in CAD kernel. */
+GMSH_API void gmshModelMeshCreateTopology(const int makeSimplyConnected,
+                                          const int exportDiscrete,
+                                          int * ierr);
 
 /* Compute a basis representation for homology spaces after a mesh has been
  * generated. The computation domain is given in a list of physical group tags
diff --git a/doc/texinfo/api.texi b/doc/texinfo/api.texi
index cb492d754aa639b4a888221a84a39a973886a7de..bf858b3abe93129f9c1477316b75363e70ca9f58 100644
--- a/doc/texinfo/api.texi
+++ b/doc/texinfo/api.texi
@@ -1788,11 +1788,14 @@ assuming that each can be parametrized with a single map.
 @item gmsh/model/mesh/createTopology
 Create a boundary representation from the mesh if the model does not have one
 (e.g. when imported from mesh file formats with no BRep representation of the
-underlying model).
+underlying model). If @code{makeSimplyConnected} is set, enforce simply
+connected discrete surfaces and volumes. If @code{exportDiscrete} is set, clear
+any built-in CAD kernel entities and export the discrete entities in the built-
+in CAD kernel.
 
 @table @asis
 @item Input:
--
+@code{makeSimplyConnected = True}, @code{exportDiscrete = True}
 @item Output:
 -
 @item Return:
diff --git a/doc/texinfo/gmsh.texi b/doc/texinfo/gmsh.texi
index ceca61e4fb8ff636194d88b14026484f21a6ef97..140ebc0c810c0b863ef4766e0d91809a433a0f63 100644
--- a/doc/texinfo/gmsh.texi
+++ b/doc/texinfo/gmsh.texi
@@ -3154,9 +3154,11 @@ and extruded meshes). @value{SYNC}
 Removes all duplicate mesh nodes.
 
 @item CreateTopology;
-Creates a boundary representation from the mesh if the model does not
-have one (e.g. when imported from mesh file formats with no BRep
-representation of the underlying model).
+Creates a boundary representation from the mesh of the current model if
+the model does not have one (e.g. when imported from mesh file formats
+with no BRep representation of the underlying model), clears any
+built-in CAD kernel entities, and exports the discrete entities in the
+built-in CAD kernel.
 
 @item CreateGeometry;
 Creates a parametrization for curves and surfaces that do not have one