diff --git a/Fltk/contextWindow.cpp b/Fltk/contextWindow.cpp
index c853a37be7c95f8a6c99688232288d28e5b88e12..b5e713e6193e5d38a3ffabad8015b0bebbd1c24b 100644
--- a/Fltk/contextWindow.cpp
+++ b/Fltk/contextWindow.cpp
@@ -170,18 +170,60 @@ elementaryContextWindow::elementaryContextWindow(int deltaFontSize)
     {
       group[3] = new Fl_Group
         (WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Ellipse");
+      input[14] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "Center X coordinate");
+      input[14]->value("0");
+      input[15] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Center Y coordinate");
+      input[15]->value("0");
+      input[16] = new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Center Z coordinate");
+      input[16]->value("0");
+      input[17] = new Fl_Input(2 * WB, 2 * WB + 4 * BH, IW, BH, "X radius");
+      input[17]->value("1");
+      input[18] = new Fl_Input(2 * WB, 2 * WB + 4 * BH, IW, BH, "Y radius");
+      input[18]->value("0.5");
+      input[19] = new Fl_Input(2 * WB, 2 * WB + 5 * BH, IW, BH, "Angle 1");
+      input[19]->value("");
+      input[20] = new Fl_Input(2 * WB, 2 * WB + 6 * BH, IW, BH, "Angle 2");
+      input[20]->value("");
+      for(int i = 14; i < 21; i++)
+        input[i]->align(FL_ALIGN_RIGHT);
       group[3]->end();
     }
     // 4: Disk
     {
       group[4] = new Fl_Group
         (WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Disk");
+      input[21] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "Center X coordinate");
+      input[21]->value("0");
+      input[22] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Center Y coordinate");
+      input[22]->value("0");
+      input[23] = new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Center Z coordinate");
+      input[23]->value("0");
+      input[24] = new Fl_Input(2 * WB, 2 * WB + 4 * BH, IW, BH, "X radius");
+      input[24]->value("1");
+      input[25] = new Fl_Input(2 * WB, 2 * WB + 4 * BH, IW, BH, "Y radius");
+      input[25]->value("0.5");
+      for(int i = 21; i < 26; i++)
+        input[i]->align(FL_ALIGN_RIGHT);
       group[4]->end();
     }
     // 5: Rectangle
     {
       group[5] = new Fl_Group
         (WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Rectangle");
+      input[26] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "Bottom left X coordinate");
+      input[26]->value("0");
+      input[27] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Bottom left Y coordinate");
+      input[27]->value("0");
+      input[28] = new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Bottom left Z coordinate");
+      input[28]->value("0");
+      input[29] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "Width");
+      input[29]->value("1");
+      input[30] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Height");
+      input[30]->value("0.5");
+      input[31] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Rounded radius");
+      input[31]->value("");
+      for(int i = 26; i < 32; i++)
+        input[i]->align(FL_ALIGN_RIGHT);
       group[5]->end();
     }
     tab1->end();
diff --git a/Fltk/contextWindow.h b/Fltk/contextWindow.h
index c02a65278f18081b487b1d91c9c7accc33289219..357f2757a6f7a7254f499302a67af40071e8f188 100644
--- a/Fltk/contextWindow.h
+++ b/Fltk/contextWindow.h
@@ -19,7 +19,7 @@ class elementaryContextWindow{
  public:
   Fl_Window *win;
   Fl_Tabs *tab1, *tab2;
-  Fl_Input *input[30];
+  Fl_Input *input[50];
   Fl_Value_Input *value[10];
   Fl_Group *group[20];
   Fl_Check_Button *_butt[3];
diff --git a/Fltk/graphicWindow.cpp b/Fltk/graphicWindow.cpp
index b724ec78ae94c6c5c7223d39f1dc20b1b1b8b09d..e64d583c09d09218dcfe44f53d4e3dd965902cc3 100644
--- a/Fltk/graphicWindow.cpp
+++ b/Fltk/graphicWindow.cpp
@@ -646,19 +646,11 @@ void geometry_remove_last_command_cb(Fl_Widget *w, void *data)
   drawContext::global()->draw();
 }
 
-static void add_new_point_based_entity(int which)
+static void add_new_point_based_entity(const std::string &what, int pane)
 {
   opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
   drawContext::global()->draw();
 
-  std::string name;
-  int pane;
-  switch(which){
-  case 0: name = "point"; pane = 1; break;
-  case 1: name = "circle"; pane = 2; break;
-  case 2: name = "sphere"; pane = 6; break;
-  }
-
   FlGui::instance()->elementaryContext->show(pane);
 
   while(1) {
@@ -666,20 +658,20 @@ static void add_new_point_based_entity(int which)
       for(unsigned int j = 0; j < FlGui::instance()->graph[i]->gl.size(); j++)
         FlGui::instance()->graph[i]->gl[j]->addPointMode = 1;
     std::string msg = std::string("Move mouse and/or enter coordinates\n") +
-      "[Press 'Shift' to hold position, 'e' to add " + name +
+      "[Press 'Shift' to hold position, 'e' to add " + what +
       " or 'q' to abort]";
     Msg::StatusGl(msg.c_str());
     char ib = FlGui::instance()->selectEntity(ENT_NONE);
     if(ib == 'e'){
-      switch(which){
-      case 0:
+      switch(pane){
+      case 1:
         add_point(GModel::current()->getFileName(),
                   FlGui::instance()->elementaryContext->input[4]->value(),
                   FlGui::instance()->elementaryContext->input[5]->value(),
                   FlGui::instance()->elementaryContext->input[6]->value(),
                   FlGui::instance()->elementaryContext->input[7]->value());
         break;
-      case 1:
+      case 2:
         add_circle(GModel::current()->getFileName(),
                    FlGui::instance()->elementaryContext->input[8]->value(),
                    FlGui::instance()->elementaryContext->input[9]->value(),
@@ -688,7 +680,34 @@ static void add_new_point_based_entity(int which)
                    FlGui::instance()->elementaryContext->input[12]->value(),
                    FlGui::instance()->elementaryContext->input[13]->value());
         break;
-      case 2:
+      case 3:
+        add_ellipse(GModel::current()->getFileName(),
+                    FlGui::instance()->elementaryContext->input[14]->value(),
+                    FlGui::instance()->elementaryContext->input[15]->value(),
+                    FlGui::instance()->elementaryContext->input[16]->value(),
+                    FlGui::instance()->elementaryContext->input[17]->value(),
+                    FlGui::instance()->elementaryContext->input[18]->value(),
+                    FlGui::instance()->elementaryContext->input[19]->value(),
+                    FlGui::instance()->elementaryContext->input[20]->value());
+        break;
+      case 4:
+        add_disk(GModel::current()->getFileName(),
+                 FlGui::instance()->elementaryContext->input[21]->value(),
+                 FlGui::instance()->elementaryContext->input[22]->value(),
+                 FlGui::instance()->elementaryContext->input[23]->value(),
+                 FlGui::instance()->elementaryContext->input[24]->value(),
+                 FlGui::instance()->elementaryContext->input[25]->value());
+        break;
+      case 5:
+        add_rectangle(GModel::current()->getFileName(),
+                      FlGui::instance()->elementaryContext->input[26]->value(),
+                      FlGui::instance()->elementaryContext->input[27]->value(),
+                      FlGui::instance()->elementaryContext->input[28]->value(),
+                      FlGui::instance()->elementaryContext->input[29]->value(),
+                      FlGui::instance()->elementaryContext->input[30]->value(),
+                      FlGui::instance()->elementaryContext->input[31]->value());
+        break;
+      case 6:
         add_sphere(GModel::current()->getFileName(),
                    FlGui::instance()->elementaryContext->input[4]->value(),
                    FlGui::instance()->elementaryContext->input[5]->value(),
@@ -1125,7 +1144,7 @@ static void geometry_elementary_add_new_cb(Fl_Widget *w, void *data)
   if(str == "Parameter")
     FlGui::instance()->elementaryContext->show(0);
   else if(str == "Point")
-    add_new_point_based_entity(0);
+    add_new_point_based_entity(str, 1);
   else if(str == "Line")
     add_new_line();
   else if(str == "Spline")
@@ -1135,17 +1154,33 @@ static void geometry_elementary_add_new_cb(Fl_Widget *w, void *data)
   else if(str == "Circle arc")
     add_new_circle_arc();
   else if(str == "Circle")
-    add_new_point_based_entity(1);
+    add_new_point_based_entity(str, 2);
   else if(str == "Ellipse arc")
     add_new_ellipse_arc();
+  else if(str == "Ellipse")
+    add_new_point_based_entity(str, 3);
+  else if(str == "Disk")
+    add_new_point_based_entity(str, 4);
+  else if(str == "Rectangle")
+    add_new_point_based_entity(str, 5);
+  else if(str == "Sphere")
+    add_new_point_based_entity(str, 6);
+  else if(str == "Block")
+    add_new_point_based_entity(str, 7);
+  else if(str == "Torus")
+    add_new_point_based_entity(str, 8);
+  else if(str == "Cone")
+    add_new_point_based_entity(str, 9);
+  else if(str == "Wedge")
+    add_new_point_based_entity(str, 10);
   else if(str == "Plane Surface")
     add_new_surface_volume(0);
   else if(str == "Surface")
     add_new_surface_volume(1);
+  else if(str == "Sphere")
+    add_new_point_based_entity(str, 11);
   else if(str == "Volume")
     add_new_surface_volume(2);
-  else if(str == "Sphere")
-    add_new_point_based_entity(2);
   else
     Msg::Error("Unknown entity to create: %s", str.c_str());
 }
diff --git a/Geo/GModelIO_OCC.cpp b/Geo/GModelIO_OCC.cpp
index 0a31d69b283bb1172ed061dfe30803630a79f897..4b8bdd2739003c71f0e472b7f0618c9ad7cefe2f 100644
--- a/Geo/GModelIO_OCC.cpp
+++ b/Geo/GModelIO_OCC.cpp
@@ -296,14 +296,6 @@ void OCC_Internals::unbind(TopoDS_Vertex vertex, int tag, bool recursive)
 
 void OCC_Internals::unbind(TopoDS_Edge edge, int tag, bool recursive)
 {
-  TopTools_DataMapIteratorOfDataMapOfIntegerShape exp0(_tagWire);
-  for(; exp0.More(); exp0.Next()){
-    TopoDS_Wire wire = TopoDS::Wire(exp0.Value());
-    TopExp_Explorer exp1;
-    for(exp1.Init(wire, TopAbs_EDGE); exp1.More(); exp1.Next()){
-      if(exp1.Current().IsSame(edge)) return;
-    }
-  }
   TopTools_DataMapIteratorOfDataMapOfIntegerShape exp2(_tagFace);
   for(; exp2.More(); exp2.Next()){
     TopoDS_Face face = TopoDS::Face(exp2.Value());
@@ -356,17 +348,9 @@ void OCC_Internals::unbind(TopoDS_Wire wire, int tag, bool recursive)
 
 void OCC_Internals::unbind(TopoDS_Face face, int tag, bool recursive)
 {
-  TopTools_DataMapIteratorOfDataMapOfIntegerShape exp0(_tagShell);
-  for(; exp0.More(); exp0.Next()){
-    TopoDS_Shell shell = TopoDS::Shell(exp0.Value());
-    TopExp_Explorer exp1;
-    for(exp1.Init(shell, TopAbs_FACE); exp1.More(); exp1.Next()){
-      if(exp1.Current().IsSame(face)) return;
-    }
-  }
   TopTools_DataMapIteratorOfDataMapOfIntegerShape exp2(_tagSolid);
-  for(; exp0.More(); exp0.Next()){
-    TopoDS_Solid solid = TopoDS::Solid(exp0.Value());
+  for(; exp2.More(); exp2.Next()){
+    TopoDS_Solid solid = TopoDS::Solid(exp2.Value());
     TopExp_Explorer exp1;
     for(exp1.Init(solid, TopAbs_FACE); exp1.More(); exp1.Next()){
       if(exp1.Current().IsSame(face)) return;
@@ -897,22 +881,17 @@ bool OCC_Internals::addLineLoop(int tag, const std::vector<int> &edgeTags)
   return addWire(tag, edgeTags, true);
 }
 
-bool OCC_Internals::addRectangle(int tag, double x1, double y1, double z1,
-                                 double x2, double y2, double z2,
-                                 double roundedRadius)
+bool OCC_Internals::addRectangle(int tag, double x, double y, double z,
+                                 double dx, double dy,  double roundedRadius)
 {
   if(tag > 0 && _tagFace.IsBound(tag)){
     Msg::Error("OpenCASCADE face with tag %d already exists", tag);
     return false;
   }
-  if(z1 != z2){
-    Msg::Error("Rectangle currently requires z1=z2");
-    return false;
-  }
-
   TopoDS_Face result;
   try{
     TopoDS_Wire wire;
+    double x1 = x, y1 = y, z1 = z, x2 = x1 + dx, y2 = y1 + dy;
     if(roundedRadius <= 0.){
       TopoDS_Vertex v1 = BRepBuilderAPI_MakeVertex(gp_Pnt(x1, y1, z1));
       TopoDS_Vertex v2 = BRepBuilderAPI_MakeVertex(gp_Pnt(x2, y1, z1));
@@ -1235,8 +1214,8 @@ bool OCC_Internals::addSphere(int tag, double xc, double yc, double zc,
   return true;
 }
 
-bool OCC_Internals::addBlock(int tag, double x1, double y1, double z1,
-                             double x2, double y2, double z2)
+bool OCC_Internals::addBlock(int tag, double x, double y, double z,
+                             double dx, double dy, double dz)
 {
   if(tag > 0 && _tagSolid.IsBound(tag)){
     Msg::Error("OpenCASCADE region with tag %d already exists", tag);
@@ -1245,8 +1224,8 @@ bool OCC_Internals::addBlock(int tag, double x1, double y1, double z1,
 
   TopoDS_Solid result;
   try{
-    gp_Pnt P1(x1, y1, z1);
-    gp_Pnt P2(x2, y2, z2);
+    gp_Pnt P1(x, y, z);
+    gp_Pnt P2(x + dx, y + dy, z + dz);
     BRepPrimAPI_MakeBox b(P1, P2);
     b.Build();
     if(!b.IsDone()){
@@ -1264,26 +1243,23 @@ bool OCC_Internals::addBlock(int tag, double x1, double y1, double z1,
   return true;
 }
 
-bool OCC_Internals::addCylinder(int tag, double x1, double y1, double z1,
-                                double x2, double y2, double z2, double r,
+bool OCC_Internals::addCylinder(int tag, double x, double y, double z,
+                                double dx, double dy, double dz, double r,
                                 double angle)
 {
   if(tag > 0 && _tagSolid.IsBound(tag)){
     Msg::Error("OpenCASCADE region with tag %d already exists", tag);
     return false;
   }
-
-  const double H = sqrt((x2 - x1) * (x2 - x1) +
-                        (y2 - y1) * (y2 - y1) +
-                        (z2 - z1) * (z2 - z1));
+  const double H = sqrt(dx * dx + dy * dy + dz * dz);
   if(!H){
     Msg::Error("Cannot build cylinder of zero height");
     return false;
   }
   TopoDS_Solid result;
   try{
-    gp_Pnt aP(x1, y1, z1);
-    gp_Vec aV((x2 - x1) / H, (y2 - y1) / H, (z2 - z1) / H);
+    gp_Pnt aP(x, y, z);
+    gp_Vec aV(dx / H, dy / H, dz / H);
     gp_Ax2 anAxes(aP, aV);
     BRepPrimAPI_MakeCylinder c(anAxes, r, H, angle);
     c.Build();
@@ -1331,8 +1307,8 @@ bool OCC_Internals::addTorus(int tag, double x, double y, double z,
   return true;
 }
 
-bool OCC_Internals::addCone(int tag, double x1, double y1, double z1,
-                            double x2, double y2, double z2, double r1,
+bool OCC_Internals::addCone(int tag, double x, double y, double z,
+                            double dx, double dy, double dz, double r1,
                             double r2, double angle)
 {
   if(tag > 0 && _tagSolid.IsBound(tag)){
@@ -1340,16 +1316,15 @@ bool OCC_Internals::addCone(int tag, double x1, double y1, double z1,
     return false;
   }
 
-  const double H = sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1) +
-                        (z2 - z1) * (z2 - z1));
+  const double H = sqrt(dx * dx + dy * dy + dz * dz);
   if(!H){
     Msg::Error("Cannot build cone of zero height");
     return false;
   }
   TopoDS_Solid result;
   try{
-    gp_Pnt aP(x1, y1, z1);
-    gp_Vec aV((x2 - x1) / H, (y2 - y1) / H, (z2 - z1) / H);
+    gp_Pnt aP(x, y, z);
+    gp_Vec aV(dx / H, dy / H, dz / H);
     gp_Ax2 anAxes(aP, aV);
     BRepPrimAPI_MakeCone c(anAxes, r1, r2, H, angle);
     c.Build();
@@ -1368,8 +1343,8 @@ bool OCC_Internals::addCone(int tag, double x1, double y1, double z1,
   return true;
 }
 
-bool OCC_Internals::addWedge(int tag, double x, double y, double z, double dx, double dy,
-                             double dz, double ltx)
+bool OCC_Internals::addWedge(int tag, double x, double y, double z,
+                             double dx, double dy, double dz, double ltx)
 {
   if(tag > 0 && _tagSolid.IsBound(tag)){
     Msg::Error("OpenCASCADE region with tag %d already exists", tag);
@@ -2014,9 +1989,9 @@ bool OCC_Internals::_transform(const std::vector<std::pair<int, int> > &inDimTag
                  dim, tag);
       return false;
     }
-    TopoDS_Shape result;
+    TopoDS_Shape object = find(dim, tag), result;
     if(tfo){
-      tfo->Perform(find(dim, tag), Standard_False);
+      tfo->Perform(object, Standard_False);
       if(!tfo->IsDone()){
         Msg::Error("Could not apply transformation");
         return false;
@@ -2024,13 +1999,14 @@ bool OCC_Internals::_transform(const std::vector<std::pair<int, int> > &inDimTag
       result = tfo->Shape();
     }
     else if(gtfo){
-      gtfo->Perform(find(dim, tag), Standard_False);
+      gtfo->Perform(object, Standard_False);
       if(!gtfo->IsDone()){
         Msg::Error("Could not apply transformation");
         return false;
       }
       result = gtfo->Shape();
     }
+    unbind(object, dim, tag, true);
     bind(result, dim, tag, true);
   }
   return true;
diff --git a/Geo/GModelIO_OCC.h b/Geo/GModelIO_OCC.h
index aa1a6e60d14153bb15b904365f4a710c19ece7d6..cdc425420cf6d5a86e088521035a31b2926ecbf0 100644
--- a/Geo/GModelIO_OCC.h
+++ b/Geo/GModelIO_OCC.h
@@ -167,8 +167,8 @@ class OCC_Internals {
   bool addBSpline(int tag, const std::vector<int> &vertexTags);
   bool addWire(int tag, const std::vector<int> &edgeTags, bool checkClosed);
   bool addLineLoop(int tag, const std::vector<int> &edgeTags);
-  bool addRectangle(int tag, double x1, double y1, double z1,
-                    double x2, double y2, double z2, double roundedRadius=0.);
+  bool addRectangle(int tag, double x, double y, double z,
+                    double dx, double dy, double roundedRadius=0.);
   bool addDisk(int tag, double xc, double yc, double zc, double rx, double ry);
   bool addPlaneSurface(int tag, const std::vector<int> &wireTags);
   bool addSurfaceFilling(int tag, int wireTag);
@@ -176,12 +176,12 @@ class OCC_Internals {
   bool addVolume(int tag, const std::vector<int> &shellTags);
   bool addSphere(int tag, double xc, double yc, double zc, double radius,
                  double angle1, double angle2, double angle3);
-  bool addBlock(int tag, double x1, double y1, double z1,
-                double x2, double y2, double z2);
-  bool addCylinder(int tag, double x1, double y1, double z1, double x2, double y2,
-                   double z2, double r, double angle);
-  bool addCone(int tag, double x1, double y1, double z1, double x2, double y2,
-               double z2, double r1, double r2, double angle);
+  bool addBlock(int tag, double x, double y, double z,
+                double dx, double dy, double dz);
+  bool addCylinder(int tag, double x, double y, double z,
+                   double dx, double dy, double dz, double r, double angle);
+  bool addCone(int tag, double x, double y, double z,
+               double dx, double dy, double dz, double r1, double r2, double angle);
   bool addWedge(int tag, double x, double y, double z, double dx, double dy,
                 double dz, double ltx);
   bool addTorus(int tag, double x, double y, double z, double r1, double r2,
@@ -350,8 +350,8 @@ public:
   {
     return _error("add line loop");
   }
-  bool addRectangle(int tag, double x1, double y1, double z1,
-                    double x2, double y2, double z2, double roundedRadius=0.)
+  bool addRectangle(int tag, double x, double y, double z,
+                    double dx, double dy, double roundedRadius=0.)
   {
     return _error("add rectangle");
   }
@@ -380,18 +380,18 @@ public:
   {
     return _error("add sphere");
   }
-  bool addBlock(int tag, double x1, double y1, double z1,
-                double x2, double y2, double z2)
+  bool addBlock(int tag, double x, double y, double z,
+                double dx, double dy, double dz)
   {
     return _error("add block");
   }
-  bool addCylinder(int tag, double x1, double y1, double z1, double x2, double y2,
-                   double z2, double r, double angle)
+  bool addCylinder(int tag, double x, double y, double z,
+                   double dx, double dy, double dz, double r, double angle)
   {
     return _error("add cylinder");
   }
-  bool addCone(int tag, double x1, double y1, double z1, double x2, double y2,
-               double z2, double r1, double r2, double angle)
+  bool addCone(int tag, double x, double y, double z,
+               double dx, double dy, double dz, double r1, double r2, double angle)
   {
     return _error("add cone");
   }
diff --git a/Geo/GeoStringInterface.cpp b/Geo/GeoStringInterface.cpp
index 121856b3413aa7fa263f16bfc8e0ac9a39980ade..29652d6ebbdac93aa221d6e3fefd8318ec5f21bf 100644
--- a/Geo/GeoStringInterface.cpp
+++ b/Geo/GeoStringInterface.cpp
@@ -434,12 +434,13 @@ void add_circle(const std::string &fileName, const std::string &x, const std::st
   add_infile(sstream.str(), fileName);
 }
 
-void add_disk(const std::string &fileName, const std::string &x, const std::string &y,
-                const std::string &z, const std::string &r, const std::string &alpha1,
-                const std::string &alpha2)
+void add_ellipse(const std::string &fileName, const std::string &x, const std::string &y,
+                 const std::string &z, const std::string &rx, const std::string &ry,
+                 const std::string &alpha1, const std::string &alpha2)
 {
   std::ostringstream sstream;
-  sstream << "Disk(" << NEWSURFACE() << ") = {" << x << "," << y << "," << z << "," << r;
+  sstream << "Ellipse(" << NEWLINE() << ") = {" << x << "," << y << "," << z << ","
+          << rx << ", " << ry;
   if(alpha1.size())
     sstream << ", " << alpha1;
   if(alpha1.size() && alpha2.size())
@@ -448,6 +449,28 @@ void add_disk(const std::string &fileName, const std::string &x, const std::stri
   add_infile(sstream.str(), fileName);
 }
 
+void add_disk(const std::string &fileName, const std::string &x, const std::string &y,
+                const std::string &z, const std::string &rx, const std::string &ry)
+{
+  std::ostringstream sstream;
+  sstream << "Disk(" << NEWSURFACE() << ") = {" << x << "," << y << "," << z << ","
+          << rx << ", " << ry << "};";
+  add_infile(sstream.str(), fileName);
+}
+
+void add_rectangle(const std::string &fileName, const std::string &x, const std::string &y,
+                   const std::string &z, const std::string &dx, const std::string &dy,
+                   const std::string &roundedRadius)
+{
+  std::ostringstream sstream;
+  sstream << "Rectangle(" << NEWSURFACE() << ") = {" << x << "," << y << "," << z << ","
+          << dx << ", " << dy;
+  if(roundedRadius.size())
+    sstream << ", " << roundedRadius;
+  sstream << "};";
+  add_infile(sstream.str(), fileName);
+}
+
 void add_sphere(const std::string &fileName, const std::string &x, const std::string &y,
                 const std::string &z, const std::string &r, const std::string &alpha1,
                 const std::string &alpha2, const std::string &alpha3)
diff --git a/Geo/GeoStringInterface.h b/Geo/GeoStringInterface.h
index 6fb8c8659e2640cd27bf746e0be0709931a12db4..8f7596601b2597e815c9d05dfffe953ed4ed21a2 100644
--- a/Geo/GeoStringInterface.h
+++ b/Geo/GeoStringInterface.h
@@ -50,9 +50,14 @@ void add_compound(const std::string &type, List_T *list, const std::string &file
 void add_circle(const std::string &fileName, const std::string &x,
                 const std::string &y, const std::string &z, const std::string &r,
                 const std::string &alpha1, const std::string &alpha2);
-void add_disk(const std::string &fileName, const std::string &x,
-              const std::string &y, const std::string &z, const std::string &r,
-              const std::string &alpha1, const std::string &alpha2);
+void add_ellipse(const std::string &fileName, const std::string &x, const std::string &y,
+                 const std::string &z, const std::string &rx, const std::string &ry,
+                 const std::string &alpha1, const std::string &alpha2);
+void add_disk(const std::string &fileName, const std::string &x, const std::string &y,
+              const std::string &z, const std::string &rx, const std::string &ry);
+void add_rectangle(const std::string &fileName, const std::string &x, const std::string &y,
+                   const std::string &z, const std::string &dx, const std::string &dy,
+                   const std::string &roundedRadius);
 void add_sphere(const std::string &fileName, const std::string &x,
                 const std::string &y, const std::string &z, const std::string &r,
                 const std::string &alpha1, const std::string &alpha2,
diff --git a/Parser/Gmsh.tab.cpp b/Parser/Gmsh.tab.cpp
index 4177beb6262673d3e0140638b81663948d165c2f..c68207eed3feb7062b4f08c4d93a90975ef83aff 100644
--- a/Parser/Gmsh.tab.cpp
+++ b/Parser/Gmsh.tab.cpp
@@ -8555,13 +8555,13 @@ yyreduce:
       std::vector<double> param; ListOfDouble2Vector((yyvsp[(6) - (7)].l), param);
       bool r = true;
       if(factory == "OpenCASCADE" && GModel::current()->getOCCInternals()){
-        if(param.size() == 6 || param.size() == 7){
-          double r = (param.size() == 7) ? param[6] : 0.;
+        if(param.size() == 5 || param.size() == 6){
+          double r = (param.size() == 6) ? param[5] : 0.;
           r = GModel::current()->getOCCInternals()->addRectangle
-            (num, param[0], param[1], param[2], param[3], param[4], param[5], r);
+            (num, param[0], param[1], param[2], param[3], param[4], r);
         }
         else{
-          yymsg(0, "Rectangle requires 6 ou 7 parameters");
+          yymsg(0, "Rectangle requires 5 ou 6 parameters");
         }
       }
       else{
diff --git a/Parser/Gmsh.y b/Parser/Gmsh.y
index 2ca28c1cd052dd93ab4ba83405bef96912067be5..22d56c1149ce7fc1b191abf5167bebbcb005dd71 100644
--- a/Parser/Gmsh.y
+++ b/Parser/Gmsh.y
@@ -2001,13 +2001,13 @@ Shape :
       std::vector<double> param; ListOfDouble2Vector($6, param);
       bool r = true;
       if(factory == "OpenCASCADE" && GModel::current()->getOCCInternals()){
-        if(param.size() == 6 || param.size() == 7){
-          double r = (param.size() == 7) ? param[6] : 0.;
+        if(param.size() == 5 || param.size() == 6){
+          double r = (param.size() == 6) ? param[5] : 0.;
           r = GModel::current()->getOCCInternals()->addRectangle
-            (num, param[0], param[1], param[2], param[3], param[4], param[5], r);
+            (num, param[0], param[1], param[2], param[3], param[4], r);
         }
         else{
-          yymsg(0, "Rectangle requires 6 ou 7 parameters");
+          yymsg(0, "Rectangle requires 5 ou 6 parameters");
         }
       }
       else{
diff --git a/demos/boolean/boolean.geo b/demos/boolean/boolean.geo
index c36bfdb5d241aba2b3d875fde325f014ef74e95a..9c63dbcade18fdc38e4e2e4185fb7ae5a740b8cd 100644
--- a/demos/boolean/boolean.geo
+++ b/demos/boolean/boolean.geo
@@ -13,15 +13,15 @@ Rs = DefineNumber[ R*.7 , Min 0.1, Max 2, Step 0.01,
 Rt = DefineNumber[ R*1.25, Min 0.1, Max 2, Step 0.01,
   Name "Parameters/Sphere radius" ];
 
-Block(1) = {-R,-R,-R, R,R,R};
+Block(1) = {-R,-R,-R, 2*R,2*R,2*R};
 
 Sphere(2) = {0,0,0,Rt};
 
 BooleanIntersection(3) = { Volume{1}; Delete; }{ Volume{2}; Delete; };
 
-Cylinder(4) = {-2*R,0,0, 2*R,0,0, Rs};
-Cylinder(5) = {0,-2*R,0, 0,2*R,0, Rs};
-Cylinder(6) = {0,0,-2*R, 0,0,2*R, Rs};
+Cylinder(4) = {-2*R,0,0, 4*R,0,0, Rs};
+Cylinder(5) = {0,-2*R,0, 0,4*R,0, Rs};
+Cylinder(6) = {0,0,-2*R, 0,0,4*R, Rs};
 
 BooleanUnion(7) = { Volume{4}; Delete; }{ Volume{5,6}; Delete; };
 BooleanDifference(8) = { Volume{3}; Delete; }{ Volume{7}; Delete; };
diff --git a/demos/boolean/compsolid.geo b/demos/boolean/compsolid.geo
index 28ddfedea7c84094f3fc0a02b48706c954c108c2..1fcb6c02ec87266e22bf89964ac2091913cdf4fe 100644
--- a/demos/boolean/compsolid.geo
+++ b/demos/boolean/compsolid.geo
@@ -19,8 +19,8 @@ DefineConstant[
   dz2 = {3, Min 0.1, Max 5, Step 0.1, Name "Bloc 2/dz"}
 ];
 
-Block(1) = {x,y,z, x+dx,y+dy,z+dz};
-Block(2) = {x2,y2,z2, x2+dx2,y2+dy2,z2+dz2};
+Block(1) = {x,y,z, dx,dy,dz};
+Block(2) = {x2,y2,z2, dx2,dy2,dz2};
 
 f() = BooleanFragments { Volume{1}; Delete; }{ Volume{2}; Delete; };
 
diff --git a/demos/boolean/compsolid2.geo b/demos/boolean/compsolid2.geo
index ab67e8f73de886b60719add091633839bcbf8daf..9f74cd40bc0d339fc06d63dee35bf922917152e4 100644
--- a/demos/boolean/compsolid2.geo
+++ b/demos/boolean/compsolid2.geo
@@ -13,7 +13,7 @@ DefineConstant[
 
 Block(1) = {0,0,0, 2,2,2};
 Sphere(2) = {xx, 1, 1, rr};
-Block(3) = {2,0,0, 4,2,2};
+Block(3) = {2,0,0, 2,2,2};
 
 f() = BooleanFragments { Volume{1}; Delete; }{ Volume{2,3}; Delete; };
 
diff --git a/demos/boolean/fillet.geo b/demos/boolean/fillet.geo
index e3e30057ef7d1c2e0d5e4a0a54d7de7f353bf958..9daa1a956c14570bd2c33fe93b1efb1bb753ea43 100644
--- a/demos/boolean/fillet.geo
+++ b/demos/boolean/fillet.geo
@@ -9,7 +9,8 @@ e() = Unique(Abs(Boundary{ Surface{f()}; }));
 
 Fillet{1}{e()}{0.2}
 
-tmp() = Fillet{1}{1,2,4}{0.05};
-Translate{2,0,0} { Volume{tmp(0)}; }
+tmp2() = Fillet{1}{1,2,4}{0.05};
+
+Translate{2,0,0} { Volume{tmp2(0)}; }
 
 Recursive Delete{ Volume{1}; }
diff --git a/demos/boolean/fillet3.geo b/demos/boolean/fillet3.geo
index ba6646dff45ad9b2cd2aa8262769028b465f9769..d83202da2f00e15abc99285a3ab68611d4b9cb46 100644
--- a/demos/boolean/fillet3.geo
+++ b/demos/boolean/fillet3.geo
@@ -8,7 +8,7 @@ r_in = 0.1; r_out = r_in+w;
 v_out = newv;
 Block(v_out) = {
   -dx_out/2,-dy_out/2,-dz_out/2,
-   dx_out/2, dy_out/2, dz_out/2
+   dx_out, dy_out, dz_out
 };
 v_ = v_out;
 f_[] = Abs(Boundary{ Volume{v_}; });
@@ -19,7 +19,7 @@ Recursive Delete{ Volume{v_}; }
 v_in = newv;
 Block(v_in) = {
   -dx_in/2,-dy_in/2,-dz_in/2,
-   dx_in/2, dy_in/2, dz_in/2
+   dx_in, dy_in, dz_in
 };
 v_ = v_in;
 f_[] = Abs(Boundary{ Volume{v_}; });
diff --git a/demos/boolean/import.geo b/demos/boolean/import.geo
index e66405f618c4763c67a7ddc95efacd0e70d355b0..86d8a121b696a99a266cd7a6f835bcd31ffcb4a3 100644
--- a/demos/boolean/import.geo
+++ b/demos/boolean/import.geo
@@ -11,7 +11,7 @@ DefineConstant[
 a() = ShapeFromFile("component8.step");
 
 b() = 2;
-Block(b(0)) = {0,156,z, 10,170,z+10};
+Block(b(0)) = {0,156,z, 10,14,10};
 
 If(sph)
   b() += 3;
diff --git a/demos/boolean/intersect_line_volume.geo b/demos/boolean/intersect_line_volume.geo
index cee16d62bb33482ce644eeec3dacc299992974e0..9e6bbcfb8de7588ce1e26dbf7516f9c3c02e0739 100644
--- a/demos/boolean/intersect_line_volume.geo
+++ b/demos/boolean/intersect_line_volume.geo
@@ -5,7 +5,7 @@ Geometry.LineNumbers = 1;
 
 xw_ = 0.1; yw_ = 0.1;
 s_wire = news;
-Rectangle(news) = {-xw_, -yw_, 0.,  xw_,  yw_, 0.};
+Rectangle(news) = {-xw_, -yw_, 0.,  2*xw_,  2*yw_};
 l_wire[] = Abs(Boundary{Surface{s_wire};});
 Delete{ Surface{s_wire}; } // Surface s_wire is deleted to keep only its boundary
 Printf("init: l_wire[] = ", l_wire[]);
@@ -17,13 +17,15 @@ DefineConstant[
 ];
 
 dx = 0.4; dy = 0.4; dz = 0.4;
-x_min_ = (flag_Symmetry_X)? 0. : -dx/2;
-y_min_ = (flag_Symmetry_Y)? 0. : -dy/2;
-z_min_ = (flag_Symmetry_Z)? 0. : -dz/2;
+x_min_ = flag_Symmetry_X ? 0. : -dx/2;
+y_min_ = flag_Symmetry_Y ? 0. : -dy/2;
+z_min_ = flag_Symmetry_Z ? 0. : -dz/2;
+ddx = flag_Symmetry_X ? dx / 2 : dx;
+ddy = flag_Symmetry_Y ? dy / 2 : dy;
+ddz = flag_Symmetry_Z ? dz / 2 : dz;
 
 v_box=newv;
-Block(newv) = {x_min_, y_min_, z_min_,  dx/2, dy/2, dz/2};
-
+Block(newv) = {x_min_, y_min_, z_min_, ddx, ddy, ddz};
 
 l_wire[] = BooleanIntersection { Line{l_wire[]}; Delete; }{ Volume{v_box}; };
 
diff --git a/demos/boolean/primitives.geo b/demos/boolean/primitives.geo
index 7988ead324348e0407a1021723e791afdd57a6d9..797e2435546726b769f8a948c9969cbc883f1762 100644
--- a/demos/boolean/primitives.geo
+++ b/demos/boolean/primitives.geo
@@ -11,21 +11,21 @@ Sphere(newv) = {x++,y,0, 0.3, Pi/4};
 Sphere(newv) = {x++,y,0, 0.3, -Pi/4, Pi/4};
 Sphere(newv) = {x++,y,0, 0.3, -Pi/4, Pi/4, Pi/2};
 Sphere(newv) = {x++,y,0, 0.3, -Pi/2, Pi/2, Pi/4};
-Cylinder(newv) = {x++,y,0, x-0.5,y,0, 0.5};
-Cylinder(newv) = {x++,y,0, x-0.5,y,0, 0.5, Pi/3};
-Block(newv) = {x++,y,0, x-0.5,y+0.5,0.5};
+Cylinder(newv) = {x++,y,0, 0.5,0,0, 0.5};
+Cylinder(newv) = {x++,y,0, 0.5,0,0, 0.5, Pi/3};
+Block(newv) = {x++,y,0, 0.5,0.5,0.5};
 Torus(newv) = {x++,y,0, 0.3, 0.1};
 Torus(newv) = {x++,y,0, 0.3, 0.1, Pi/3};
-Cone(newv) = {x++,y,0, x-0.5,y,0, 0.5,0};
-Cone(newv) = {x++,y,0, x-0.5,y,0, 0.5,0, Pi/3};
-Cone(newv) = {x++,y,0, x-0.5,y,0, 0.5,0.2, Pi/3};
+Cone(newv) = {x++,y,0, 0.5,0,0, 0.5,0};
+Cone(newv) = {x++,y,0, 0.5,0,0, 0.5,0, Pi/3};
+Cone(newv) = {x++,y,0, 0.5,0,0, 0.5,0.2, Pi/3};
 Wedge(newv) = {x++,y,0, 0.5,0.5,0.5, 0};
 Wedge(newv) = {x++,y,0, 0.5,0.5,0.5, 0.8};
 
 // 2D
 x = 0; y = -1.5;
-Rectangle(news) = {x++,y,0, x-0.5,y+0.5,0};
-Rectangle(news) = {x++,y,0, x-0.5,y+0.5,0, 0.1};
+Rectangle(news) = {x++,y,0, 0.5,0.5};
+Rectangle(news) = {x++,y,0, 0.5,0.5, 0.1};
 Disk(news) = {x++,y,0, 0.3};
 Disk(news) = {x++,y,0, 0.4,0.2};
 
diff --git a/demos/boolean/simple4.geo b/demos/boolean/simple4.geo
index b46b6ccbf22c211227ec710d03118247216bacaa..42f978649dd4e29850df6d99170662734dbb8c5b 100644
--- a/demos/boolean/simple4.geo
+++ b/demos/boolean/simple4.geo
@@ -30,5 +30,5 @@ Plane Surface(5) = {5};
 Surface Loop(1) = {1,2,3,4,5};
 Volume(1) = {1};
 
-Cylinder(2) = {0.5,0.5,-0.5, 0.5,0.5,1.5, 0.2};
+Cylinder(2) = {0.5,0.5,-0.5, 0,0,2, 0.2};
 BooleanFragments{ Volume{1}; Delete; }{ Volume{2}; Delete; }
diff --git a/demos/boolean/simple5.geo b/demos/boolean/simple5.geo
index 991c0d201a343c3a98353cc78c95ca61b95743d7..ef5f91e358f3ce16c82ff118546c2b5bfae1439e 100644
--- a/demos/boolean/simple5.geo
+++ b/demos/boolean/simple5.geo
@@ -10,6 +10,6 @@ For i In {1:5}
   Translate {0,0,i/5} { Surface{i}; }
 EndFor
 
-Cylinder(1) = {0,0,-0.5, 0,0,1.5, 0.5};
+Cylinder(1) = {0,0,-0.5, 0,0,2, 0.5};
 
 BooleanFragments{ Volume{1}; Delete; }{ Surface{1:5}; Delete; }
diff --git a/demos/boolean/transfinite.geo b/demos/boolean/transfinite.geo
index df25a1281268497de4a41b397aff9e34038b91fc..5e4025fad945514e1c856f2c3a4e9c8fdd9b47ea 100644
--- a/demos/boolean/transfinite.geo
+++ b/demos/boolean/transfinite.geo
@@ -5,7 +5,7 @@ Mesh.CharacteristicLengthMin = 1;
 Mesh.CharacteristicLengthMax = 1;
 
 Block(1) = {0,0,0, 1,1,1};
-Cylinder(2) = {0.5,0,0, 0.5,1,0, 0.7};
+Cylinder(2) = {0.5,0,0, 0,1,0, 0.7};
 BooleanDifference(3) = { Volume{1}; Delete; }{ Volume{2}; Delete; };
 
 s() = Abs(Boundary{ Volume{3}; });
diff --git a/demos/boolean/transform.geo b/demos/boolean/transform.geo
index 6871f60ed0e1d7e8c29b12e770c57adce293e274..7a654f290c85f8a880f9084c12eb75b1d9dc74a8 100644
--- a/demos/boolean/transform.geo
+++ b/demos/boolean/transform.geo
@@ -19,8 +19,8 @@ DefineConstant[
   dz2 = {3, Min 0.1, Max 5, Step 0.1, Name "Bloc 2/dz"}
 ];
 
-Block(1) = {x,y,z, x+dx,y+dy,z+dz};
-Block(2) = {x2,y2,z2, x2+dx2,y2+dy2,z2+dz2};
+Block(1) = {x,y,z, dx,dy,dz};
+Block(2) = {x2,y2,z2, dx2,dy2,dz2};
 
 Translate{0.2,0.2,0.2}{ Volume{1}; }
 Rotate { {1,0,0}, {0,0,0}, Pi/3 } { Volume{1}; }