diff --git a/Fltk/graphicWindow.cpp b/Fltk/graphicWindow.cpp
index e6c5691380f2124432a8af142a981a7e9b03ae6e..0e6d35205138e2725d3224d920477d9c26594768 100644
--- a/Fltk/graphicWindow.cpp
+++ b/Fltk/graphicWindow.cpp
@@ -2042,8 +2042,8 @@ static std::vector<std::string> getInfoStrings(MElement *ele)
     std::ostringstream sstream;
     sstream.precision(12);
     sstream << " Quality: "
-        << "gamma = " << ele->gammaShapeMeasure() << " "
-        << "rho = " << ele->rhoShapeMeasure();
+            << "gamma = " << ele->gammaShapeMeasure() << " "
+            << "rho = " << ele->rhoShapeMeasure();
     info.push_back(sstream.str());
   }
   {
@@ -2172,7 +2172,7 @@ static void mesh_define_recombine_cb(Fl_Widget *w, void *data)
   action_point_line_surface_volume(9, "Surface");
 }
 
-static void add_transfinite_embedded(int dim, bool embed)
+static void mesh_define_transfinite(int dim)
 {
   opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
   switch (dim) {
@@ -2263,20 +2263,18 @@ static void add_transfinite_embedded(int dim, bool embed)
         }
         while(1) {
           if(p.size() == 1)
-            Msg::StatusGl("Select %s points\n"
-                          "[Press 'e' to end selection or 'q' to abort]",
-                          embed ? "embedded" : "(ordered) boundary");
+            Msg::StatusGl("Select (ordered) boundary points\n"
+                          "[Press 'e' to end selection or 'q' to abort]");
           else
-            Msg::StatusGl("Select %s points\n"
+            Msg::StatusGl("Select (ordered) boundary points\n"
                           "[Press 'e' to end selection, 'u' to undo last selection "
-                          "or 'q' to abort]",
-                          embed ? "embedded" : "(ordered) boundary");
+                          "or 'q' to abort]");
           ib = FlGui::instance()->selectEntity(ENT_POINT);
           if(ib == 'l') {
             for(unsigned int i = 0; i < FlGui::instance()->selectedVertices.size(); i++){
               FlGui::instance()->selectedVertices[i]->setSelection(1);
               p.push_back(FlGui::instance()->selectedVertices[i]->tag());
-              if(!embed) break;
+              break;
             }
             drawContext::global()->draw();
           }
@@ -2295,10 +2293,7 @@ static void add_transfinite_embedded(int dim, bool embed)
           if(ib == 'e') {
             switch (dim) {
             case 2:
-              if(embed && p.size())
-                add_embedded("Point", p, GModel::current()->getFileName());
-              else if(!embed &&
-                      (p.size() == 0 + 1 || p.size() == 3 + 1 || p.size() == 4 + 1))
+              if((p.size() == 0 + 1 || p.size() == 3 + 1 || p.size() == 4 + 1))
                 add_trsfsurf(p, GModel::current()->getFileName(),
                              FlGui::instance()->meshContext->choice[1]->text());
               else
@@ -2334,25 +2329,25 @@ static void add_transfinite_embedded(int dim, bool embed)
 static void mesh_define_transfinite_line_cb(Fl_Widget *w, void *data)
 {
   FlGui::instance()->meshContext->show(1);
-  add_transfinite_embedded(1, false);
+  mesh_define_transfinite(1);
   FlGui::instance()->meshContext->hide();
 }
 
 static void mesh_define_transfinite_surface_cb(Fl_Widget *w, void *data)
 {
   FlGui::instance()->meshContext->show(2);
-  add_transfinite_embedded(2, false);
+  mesh_define_transfinite(2);
   FlGui::instance()->meshContext->hide();
 }
 
 static void mesh_define_transfinite_volume_cb(Fl_Widget *w, void *data)
 {
-  add_transfinite_embedded(3, false);
+  mesh_define_transfinite(3);
 }
 
 static void mesh_define_embedded_cb(Fl_Widget *w, void *data)
 {
-  add_transfinite_embedded(2, true);
+  // TODO
 }
 
 static void mesh_define_compound_entity_cb(Fl_Widget *w, void *data)
@@ -4084,12 +4079,14 @@ static menuItem static_modules[] = {
    (Fl_Callback *)mesh_define_length_cb  } ,
   {"0Modules/Mesh/Define/Size fields",
    (Fl_Callback *)field_cb},
+  /* TODO:
   {"0Modules/Mesh/Define/Embedded/Point",
    (Fl_Callback *)mesh_define_embedded_cb, (void*)"Point" } ,
   {"0Modules/Mesh/Define/Embedded/Line",
    (Fl_Callback *)mesh_define_embedded_cb, (void*)"Line" } ,
   {"0Modules/Mesh/Define/Embedded/Surface",
    (Fl_Callback *)mesh_define_embedded_cb, (void*)"Surface" } ,
+  */
   {"0Modules/Mesh/Define/Transfinite/Line",
    (Fl_Callback *)mesh_define_transfinite_line_cb} ,
   {"0Modules/Mesh/Define/Transfinite/Surface",
diff --git a/Geo/GModelIO_OCC.cpp b/Geo/GModelIO_OCC.cpp
index 208928cf3158e7812c87a33322c2dfab3787a26a..46e27fb6cd5111267fe3f8346935943a782595ef 100644
--- a/Geo/GModelIO_OCC.cpp
+++ b/Geo/GModelIO_OCC.cpp
@@ -804,24 +804,31 @@ bool OCC_Internals::_addSpline(int tag, const std::vector<int> &vertexTags, int
       if(i == 0) start = vertex;
       if(i == vertexTags.size() - 1) end = vertex;
     }
-    if(mode == 0){
-      Handle(Geom_BezierCurve) curve = new Geom_BezierCurve(ctrlPoints);
+    if(mode == 0){ // BSpline through points (called "Spline" in Gmsh)
+      Handle(Geom_BSplineCurve) curve = GeomAPI_PointsToBSpline(ctrlPoints).Curve();
       BRepBuilderAPI_MakeEdge e(curve, start, end);
       if(!e.IsDone()){
-        Msg::Error("Could not create Bezier curve");
+        Msg::Error("Could not create spline");
         return false;
       }
       result = e.Edge();
     }
-    else{
-      Handle(Geom_BSplineCurve) curve = GeomAPI_PointsToBSpline(ctrlPoints).Curve();
+    else if(mode == 1){
+      Handle(Geom_BezierCurve) curve = new Geom_BezierCurve(ctrlPoints);
       BRepBuilderAPI_MakeEdge e(curve, start, end);
       if(!e.IsDone()){
-        Msg::Error("Could not create BSpline curve");
+        Msg::Error("Could not create Bezier curve");
         return false;
       }
       result = e.Edge();
     }
+    else if(mode == 2){
+      // TODO: BSpline treat periodic case, allow to set order, etc.
+      // Handle(Geom_BSplineCurve) curve = new Geom_BSplineCurve(ctrlPoints, ...);
+      // ...
+      Msg::Error("OpenCASCADE BSpline not implemented yet");
+      return false;
+    }
   }
   catch(Standard_Failure &err){
     Msg::Error("OpenCASCADE exception %s", err.GetMessageString());
@@ -832,16 +839,21 @@ bool OCC_Internals::_addSpline(int tag, const std::vector<int> &vertexTags, int
   return true;
 }
 
-bool OCC_Internals::addBezier(int tag, const std::vector<int> &vertexTags)
+bool OCC_Internals::addSpline(int tag, const std::vector<int> &vertexTags)
 {
   return _addSpline(tag, vertexTags, 0);
 }
 
-bool OCC_Internals::addBSpline(int tag, const std::vector<int> &vertexTags)
+bool OCC_Internals::addBezier(int tag, const std::vector<int> &vertexTags)
 {
   return _addSpline(tag, vertexTags, 1);
 }
 
+bool OCC_Internals::addBSpline(int tag, const std::vector<int> &vertexTags)
+{
+  return _addSpline(tag, vertexTags, 2);
+}
+
 bool OCC_Internals::addWire(int tag, const std::vector<int> &edgeTags,
                             bool checkClosed)
 {
diff --git a/Geo/GModelIO_OCC.h b/Geo/GModelIO_OCC.h
index 8868ff2ed9460b30b660ced3455299c8bf49a8b5..19abd9dd106b5b53d599c7cea72a8ecc06743d7d 100644
--- a/Geo/GModelIO_OCC.h
+++ b/Geo/GModelIO_OCC.h
@@ -163,6 +163,7 @@ class OCC_Internals {
   bool addEllipseArc(int tag, int startTag, int centerTag, int endTag);
   bool addEllipse(int tag, double x, double y, double z, double r1, double r2,
                   double angle1, double angle2);
+  bool addSpline(int tag, const std::vector<int> &vertexTags);
   bool addBezier(int tag, const std::vector<int> &vertexTags);
   bool addBSpline(int tag, const std::vector<int> &vertexTags);
   bool addWire(int tag, const std::vector<int> &edgeTags, bool checkClosed);
@@ -335,6 +336,10 @@ public:
   {
     return _error("add ellipse");
   }
+  bool addSpline(int tag, const std::vector<int> &vertexTags)
+  {
+    return _error("add spline");
+  }
   bool addBezier(int tag, const std::vector<int> &vertexTags)
   {
     return _error("add Bezier");
diff --git a/Parser/Gmsh.tab.cpp b/Parser/Gmsh.tab.cpp
index ea3f6e91fc08106f7e6c6904457e1af6aadbeeb0..e510d43be2de0645e7a7a0b0c1f254dffe3e060b 100644
--- a/Parser/Gmsh.tab.cpp
+++ b/Parser/Gmsh.tab.cpp
@@ -8151,7 +8151,7 @@ yyreduce:
       std::vector<int> tags; ListOfDouble2Vector((yyvsp[(6) - (7)].l), tags);
       bool r = true;
       if(factory == "OpenCASCADE" && GModel::current()->getOCCInternals()){
-        yymsg(0, "Spline not available with OpenCASCADE factory");
+        r = GModel::current()->getOCCInternals()->addSpline(num, tags);
       }
       else{
         r = GModel::current()->getGEOInternals()->addSpline(num, tags);
@@ -8253,7 +8253,7 @@ yyreduce:
       std::vector<int> tags; ListOfDouble2Vector((yyvsp[(6) - (7)].l), tags);
       bool r = true;
       if(factory == "OpenCASCADE" && GModel::current()->getOCCInternals()){
-        r = GModel::current()->getOCCInternals()->addBSpline(num, tags);
+        yymsg(0, "BSpline not yet available with OpenCASCADE factory");
       }
       else{
         r = GModel::current()->getGEOInternals()->addBSpline(num, tags);
diff --git a/Parser/Gmsh.y b/Parser/Gmsh.y
index 20fedd2ddb7a07d0923eaabc140f0bfb9a88f774..3ddacbd3c2fd370b205495093788a4a5c77b3337 100644
--- a/Parser/Gmsh.y
+++ b/Parser/Gmsh.y
@@ -1653,7 +1653,7 @@ Shape :
       std::vector<int> tags; ListOfDouble2Vector($6, tags);
       bool r = true;
       if(factory == "OpenCASCADE" && GModel::current()->getOCCInternals()){
-        yymsg(0, "Spline not available with OpenCASCADE factory");
+        r = GModel::current()->getOCCInternals()->addSpline(num, tags);
       }
       else{
         r = GModel::current()->getGEOInternals()->addSpline(num, tags);
@@ -1746,7 +1746,7 @@ Shape :
       std::vector<int> tags; ListOfDouble2Vector($6, tags);
       bool r = true;
       if(factory == "OpenCASCADE" && GModel::current()->getOCCInternals()){
-        r = GModel::current()->getOCCInternals()->addBSpline(num, tags);
+        yymsg(0, "BSpline not yet available with OpenCASCADE factory");
       }
       else{
         r = GModel::current()->getGEOInternals()->addBSpline(num, tags);
diff --git a/demos/boolean/pipe.geo b/demos/boolean/pipe.geo
index 052ed3903426afb28fd1f0d5f05e3158698ae6a4..e585759993fb02b28715482e19cb5324f691ba5f 100644
--- a/demos/boolean/pipe.geo
+++ b/demos/boolean/pipe.geo
@@ -35,7 +35,7 @@ For i In {0:5}
 EndFor
 Point(106) = {-0.1, -2, 6};
 
-BSpline(100) = {100:105};
+Spline(100) = {100:105};
 Line(101) = {105:106};
 
 Wire(100) = {100,101};
diff --git a/demos/boolean/primitives.geo b/demos/boolean/primitives.geo
index 797e2435546726b769f8a948c9969cbc883f1762..a06b669190a5339d96339130babc2aa57f1644e8 100644
--- a/demos/boolean/primitives.geo
+++ b/demos/boolean/primitives.geo
@@ -69,7 +69,7 @@ Ellipse(newl) = {x++,y,0, 0.4,0.1, Pi/3};
 Ellipse(newl) = {x++,y,0, 0.4,0.1, -Pi/3, Pi/3};
 
 p = newp; Point(p) = {x++,y,0}; Point(p+1) = {x-0.5,y+0.3,0}; Point(p+2) = {x-0.2,y,0};
-BSpline(newl) = {p:p+2};
+Spline(newl) = {p:p+2};
 
 p = newp; Point(p) = {x++,y,0}; Point(p+1) = {x-0.5,y+0.3,0}; Point(p+2) = {x-0.2,y,0};
 Bezier(newl) = {p:p+2};
diff --git a/demos/boolean/spline.geo b/demos/boolean/spline.geo
index 71ccbf49f619f57ac0c07f383b9bd6e258ba8e4c..d3798840b1ef67ffc00a1172007e5836842fbdd2 100644
--- a/demos/boolean/spline.geo
+++ b/demos/boolean/spline.geo
@@ -9,4 +9,4 @@ For i In {1:10}
 EndFor
 Line(1) = {1,10};
 Bezier(2) = {1:10};
-BSpline(3) = {1:10};
+Spline(3) = {1:10};
diff --git a/doc/texinfo/gmsh.texi b/doc/texinfo/gmsh.texi
index 9ace4c9450d66116e1bfcb2773db061c71232e5a..1d348c3431249fb897e57625dbb75d233dd662e7 100644
--- a/doc/texinfo/gmsh.texi
+++ b/doc/texinfo/gmsh.texi
@@ -2028,43 +2028,6 @@ automatically created).
 @cindex Lines, physical
 
 @ftable @code
-@c @item Bezier ( @var{expression} ) = @{ @var{expression-list} @};
-@c Creates a Bezier curve. The @var{expression} inside the parentheses is the
-@c Bezier curve's identification number; the @var{expression-list} on the right
-@c hand side should contain the identification numbers of all the curve's
-@c control points.
-
-@item BSpline ( @var{expression} ) = @{ @var{expression-list} @};
-Creates a B-spline curve. The @var{expression} inside the parentheses is the
-B-spline curve's identification number; the @var{expression-list} on the
-right hand side should contain the identification numbers of all the
-B-spline's control points. Repeating control points has the expected effect.
-
-@item Circle ( @var{expression} ) = @{ @var{expression}, @var{expression}, @var{expression} @};
-Creates a circle arc (strictly) smaller than Pi. The @var{expression} inside
-the parentheses is the circle arc's identification number; the first
-@var{expression} inside the braces on the right hand side gives the
-identification number of the start point of the arc; the second
-@var{expression} gives the identification number of the center of the
-circle; the last @var{expression} gives the identification number of the end
-point of the arc.
-
-@c todo:
-@c @item Circle ( @var{expression} ) = @{ @var{expression}, @var{expression}, @var{expression} @} Plane @{ @var{expression}, @var{expression}, @var{expression} @};
-
-@item CatmullRom ( @var{expression} ) = @{ @var{expression-list} @};
-@code{CatmullRom} is a synonym for @code{Spline}.
-
-@item Ellipse ( @var{expression} ) = @{ @var{expression}, @var{expression}, @var{expression}, @var{expression} @};
-Creates an ellipse arc. The @var{expression} inside the parentheses is the
-ellipse arc's identification number; the first @var{expression} inside the
-braces on the right hand side gives the identification number of the start
-point of the arc; the second @var{expression} gives the identification
-number of the center of the ellipse; the third @var{expression} gives the
-identification number of any point located on the major axis of the ellipse;
-the last @var{expression} gives the identification number of the end point
-of the arc.
-
 @item Line ( @var{expression} ) = @{ @var{expression}, @var{expression} @};
 Creates a straight line segment. The @var{expression} inside the parentheses
 is the line segment's identification number; the two @w{@var{expression}s}
@@ -2072,17 +2035,31 @@ inside the braces on the right hand side give identification numbers of the
 start and end points of the segment.
 @c todo: multi-lines not authorized yet
 
-@c todo:
-@c @item Nurbs ( @var{expression} ) = @{ @var{expression-list} @};
+@item Bezier ( @var{expression} ) = @{ @var{expression-list} @};
+Creates a Bezier curve. The @var{expression-list} contains the
+identification numbers of the control points.
 
-@c todo:
-@c @item Parametric ( @var{expression} ) = @{ @var{expression}, @var{expression}, "@var{string}", "@var{string}", "@var{string}" @};
+@item BSpline ( @var{expression} ) = @{ @var{expression-list} @};
+Creates a BSpline. The @var{expression-list} contains the identification
+numbers of the control points.
 
 @item Spline ( @var{expression} ) = @{ @var{expression-list} @};
-Creates a spline curve. The @var{expression} inside the parentheses is the
-spline's identification number; the @var{expression-list} on the right hand
-side should contain the identification numbers of all the spline's control
-points.
+Creates a spline going through the points in @var{expression-list}. With
+the built-in geometry kernel this constructs a Catmull-Rom spline. With
+the OpenCASCADE kernel, this constructs a BSpline passing through the
+points with a given tolerance.
+
+@item Circle ( @var{expression} ) = @{ @var{expression}, @var{expression}, @var{expression} @};
+Creates a circle arc. The three @var{expression}s on the right-hand-side
+define the start point, the center and the end point of the arc. With
+the built-in geometry kernel the arc should be strictly smaller than Pi.
+@c todo: document < Plane @{ @var{expression}, @var{expression}, @var{expression} @}; >
+
+@item Ellipse ( @var{expression} ) = @{ @var{expression}, @var{expression}, @var{expression}, @var{expression} @};
+Creates an ellipse arc. The four @var{expression}s on the
+right-hand-side define the start point, the center point, a major axis
+point and the end point of the ellipse. The third point can be omitted
+with the OpenCASCADE kernel.
 
 @item Line Loop ( @var{expression} ) = @{ @var{expression-list} @};
 Creates an oriented line loop. The @var{expression} inside the parentheses
@@ -2097,6 +2074,11 @@ supports it, it is not recommended to specify multiple line loops (or
 subloops) in a single @code{Line Loop} command. (Line loops are used to
 create surfaces: see @ref{Surfaces}.)
 
+@item Wire ( @var{expression} ) = @{ @var{expression-list} @};
+Creates a path made of lines. Wires are only available with the
+OpenCASCADE kernel. They are used to create @code{ThruSections} and
+extrusions along paths.
+
 @item Compound Line ( @var{expression} ) = @{ @var{expression-list} @};
 Creates a compound line from several elementary lines.  When meshed, a
 compound line will be reparametrized as a single line, whose mesh can