diff --git a/Fltk/FlGui.cpp b/Fltk/FlGui.cpp
index c771c0c679c0760cf0aa8b7f8ae2d43af44a4a21..fd8afdc7628ec2c1c3fe0933ee91e9e3c5eb6c0e 100644
--- a/Fltk/FlGui.cpp
+++ b/Fltk/FlGui.cpp
@@ -478,6 +478,7 @@ FlGui::FlGui(int argc, char **argv)
   clipping = new clippingWindow(CTX::instance()->deltaFontSize);
   manip = new manipWindow(CTX::instance()->deltaFontSize);
   elementaryContext = new elementaryContextWindow(CTX::instance()->deltaFontSize);
+  transformContext = new transformContextWindow(CTX::instance()->deltaFontSize);
   physicalContext = new physicalContextWindow(CTX::instance()->deltaFontSize);
   meshContext = new meshContextWindow(CTX::instance()->deltaFontSize);
   help = new helpWindow();
@@ -1244,6 +1245,8 @@ void window_cb(Fl_Widget *w, void *data)
       FlGui::instance()->fields->win->show();
     if(FlGui::instance()->elementaryContext->win->shown())
       FlGui::instance()->elementaryContext->win->show();
+    if(FlGui::instance()->transformContext->win->shown())
+      FlGui::instance()->transformContext->win->show();
     if(FlGui::instance()->physicalContext->win->shown())
       FlGui::instance()->physicalContext->win->show();
     if(FlGui::instance()->meshContext->win->shown())
diff --git a/Fltk/FlGui.h b/Fltk/FlGui.h
index b1ad8bd291dd7cc9d2b9e692ef3d5f03cb231120..116ef21880cb6b10ee06f44dc6d21d1dad084a97 100644
--- a/Fltk/FlGui.h
+++ b/Fltk/FlGui.h
@@ -31,6 +31,7 @@ class highOrderToolsWindow;
 class clippingWindow;
 class manipWindow;
 class elementaryContextWindow;
+class transformContextWindow;
 class physicalContextWindow;
 class meshContextWindow;
 class helpWindow;
@@ -69,6 +70,7 @@ class FlGui{
   clippingWindow *clipping;
   manipWindow *manip;
   elementaryContextWindow *elementaryContext;
+  transformContextWindow *transformContext;
   physicalContextWindow *physicalContext;
   meshContextWindow *meshContext;
   helpWindow *help;
diff --git a/Fltk/contextWindow.cpp b/Fltk/contextWindow.cpp
index 498893a43f3785f935f33dabf72274739132e746..ece8e5659b19778e86a8ae3296f51ba4a615a9a2 100644
--- a/Fltk/contextWindow.cpp
+++ b/Fltk/contextWindow.cpp
@@ -16,30 +16,118 @@
 #include "Context.h"
 #include "MallocUtils.h"
 
-static void elementary_define_parameter_cb(Fl_Widget *w, void *data)
+static void elementary_add_parameter_cb(Fl_Widget *w, void *data)
 {
   add_param(FlGui::instance()->elementaryContext->input[0]->value(),
             FlGui::instance()->elementaryContext->input[1]->value(),
-            FlGui::instance()->elementaryContext->input[24]->value(),
-            FlGui::instance()->elementaryContext->input[25]->value(),
+            FlGui::instance()->elementaryContext->input[2]->value(),
+            FlGui::instance()->elementaryContext->input[3]->value(),
             GModel::current()->getFileName());
   FlGui::instance()->resetVisibility();
   FlGui::instance()->rebuildTree(true);
 }
 
-static void elementary_define_point_cb(Fl_Widget *w, void *data)
+static void elementary_add_point_cb(Fl_Widget *w, void *data)
 {
   add_point(GModel::current()->getFileName(),
-            FlGui::instance()->elementaryContext->input[2]->value(),
-            FlGui::instance()->elementaryContext->input[3]->value(),
             FlGui::instance()->elementaryContext->input[4]->value(),
-            FlGui::instance()->elementaryContext->input[5]->value());
+            FlGui::instance()->elementaryContext->input[5]->value(),
+            FlGui::instance()->elementaryContext->input[6]->value(),
+            FlGui::instance()->elementaryContext->input[7]->value());
+  FlGui::instance()->resetVisibility();
+  GModel::current()->setSelection(0);
+  SetBoundingBox();
+  drawContext::global()->draw();
+}
+
+static void elementary_add_circle_cb(Fl_Widget *w, void *data)
+{
+  add_circle(GModel::current()->getFileName(),
+             FlGui::instance()->elementaryContext->input[8]->value(),
+             FlGui::instance()->elementaryContext->input[9]->value(),
+             FlGui::instance()->elementaryContext->input[10]->value(),
+             FlGui::instance()->elementaryContext->input[11]->value(),
+             FlGui::instance()->elementaryContext->input[12]->value(),
+             FlGui::instance()->elementaryContext->input[13]->value());
+  FlGui::instance()->resetVisibility();
+  GModel::current()->setSelection(0);
+  SetBoundingBox();
+  drawContext::global()->draw();
+}
+
+static void elementary_add_ellipse_cb(Fl_Widget *w, void *data)
+{
+  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());
   FlGui::instance()->resetVisibility();
   GModel::current()->setSelection(0);
   SetBoundingBox();
   drawContext::global()->draw();
 }
 
+static void elementary_add_disk_cb(Fl_Widget *w, void *data)
+{
+  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());
+  FlGui::instance()->resetVisibility();
+  GModel::current()->setSelection(0);
+  SetBoundingBox();
+  drawContext::global()->draw();
+}
+
+static void elementary_add_rectangle_cb(Fl_Widget *w, void *data)
+{
+  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());
+  FlGui::instance()->resetVisibility();
+  GModel::current()->setSelection(0);
+  SetBoundingBox();
+  drawContext::global()->draw();
+}
+
+static void elementary_add_sphere_cb(Fl_Widget *w, void *data)
+{
+  add_sphere(GModel::current()->getFileName(),
+             FlGui::instance()->elementaryContext->input[32]->value(),
+             FlGui::instance()->elementaryContext->input[33]->value(),
+             FlGui::instance()->elementaryContext->input[34]->value(),
+             FlGui::instance()->elementaryContext->input[35]->value(),
+             FlGui::instance()->elementaryContext->input[36]->value(),
+             FlGui::instance()->elementaryContext->input[37]->value(),
+             FlGui::instance()->elementaryContext->input[38]->value());
+  FlGui::instance()->resetVisibility();
+  GModel::current()->setSelection(0);
+  SetBoundingBox();
+  drawContext::global()->draw();
+}
+
+static void elementary_switch_tabs_cb(Fl_Widget *w, void *data)
+{
+  if(FlGui::instance()->elementaryContext->tab1->visible()){
+    FlGui::instance()->elementaryContext->tab1->hide();
+    FlGui::instance()->elementaryContext->tab2->show();
+  }
+  else{
+    FlGui::instance()->elementaryContext->tab2->hide();
+    FlGui::instance()->elementaryContext->tab1->show();
+  }
+}
+
 static void elementary_snap_cb(Fl_Widget *w, void *data)
 {
   CTX::instance()->geom.snap[0] = FlGui::instance()->elementaryContext->value[0]->value();
@@ -52,13 +140,13 @@ elementaryContextWindow::elementaryContextWindow(int deltaFontSize)
   FL_NORMAL_SIZE -= deltaFontSize;
 
   int width = 31 * FL_NORMAL_SIZE;
-  int height = 4 * WB + 8 * BH;
+  int height = 4 * WB + 9 * BH;
 
   win = new paletteWindow(width, height, CTX::instance()->nonModalWindows ? true : false,
                           "Elementary Entity Context");
   win->box(GMSH_WINDOW_BOX);
   {
-    Fl_Tabs *o = new Fl_Tabs(WB, WB, width - 2 * WB, height - 2 * WB);
+    tab1 = new Fl_Tabs(WB, WB, width - 2 * WB, height - 2 * WB);
     // 0: Parameter
     {
       group[0] = new Fl_Group
@@ -67,16 +155,15 @@ elementaryContextWindow::elementaryContextWindow(int deltaFontSize)
       input[0]->value("lc");
       input[1] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Value");
       input[1]->value("0.1");
-      input[24] = new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Label");
-      input[24]->value("");
-      input[25] = new Fl_Input(2 * WB, 2 * WB + 4 * BH, IW, BH, "Path");
-      input[25]->value("Parameters");
-      for(int i = 0; i < 2; i++)   input[i]->align(FL_ALIGN_RIGHT);
-      for(int i = 24; i < 26; i++) input[i]->align(FL_ALIGN_RIGHT);
+      input[2] = new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Label");
+      input[2]->value("");
+      input[3] = new Fl_Input(2 * WB, 2 * WB + 4 * BH, IW, BH, "Path");
+      input[3]->value("Parameters");
+      for(int i = 0; i < 4; i++)   input[i]->align(FL_ALIGN_RIGHT);
       {
         Fl_Return_Button *o = new Fl_Return_Button
-          (width - BB - 2 * WB, 2 * WB + 7 * BH, BB, BH, "Add");
-        o->callback(elementary_define_parameter_cb);
+          (width - BB - 2 * WB, 2 * WB + 8 * BH, BB, BH, "Add");
+        o->callback(elementary_add_parameter_cb);
       }
       group[0]->end();
     }
@@ -84,22 +171,22 @@ elementaryContextWindow::elementaryContextWindow(int deltaFontSize)
     {
       group[1] = new Fl_Group
         (WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Point");
-      input[2] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "X coordinate");
-      input[2]->value("0");
-      input[3] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Y coordinate");
-      input[3]->value("0");
-      input[4] = new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Z coordinate");
+      input[4] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "X coordinate");
       input[4]->value("0");
+      input[5] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Y coordinate");
+      input[5]->value("0");
+      input[6] = new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Z coordinate");
+      input[6]->value("0");
+      input[7] = new Fl_Input(2 * WB, 2 * WB + 4 * BH, IW, BH,
+                              "Prescribed mesh element size at point");
+      input[7]->value("1.0");
+      for(int i = 4; i < 8; i++)
+        input[i]->align(FL_ALIGN_RIGHT);
+
       for(int i = 0; i < 3; i++)
         _butt[i] = new Fl_Check_Button
           (width - 2 * WB - IW, 2 * WB + (i+1) * BH, IW, BH, "Freeze");
 
-      input[5] = new Fl_Input(2 * WB, 2 * WB + 4 * BH, IW, BH,
-                              "Prescribed mesh element size at point");
-      input[5]->value("1.0");
-      for(int i = 2; i < 6; i++) {
-        input[i]->align(FL_ALIGN_RIGHT);
-      }
       value[0] = new Fl_Value_Input(2 * WB, 2 * WB + 5 * BH, IW/3, BH);
       value[1] = new Fl_Value_Input(2 * WB + IW/3, 2 * WB + 5 * BH, IW/3, BH);
       value[2] = new Fl_Value_Input(2 * WB + 2*IW/3, 2 * WB + 5 * BH, IW/3, BH,
@@ -110,97 +197,183 @@ elementaryContextWindow::elementaryContextWindow(int deltaFontSize)
       }
       {
         Fl_Return_Button *o = new Fl_Return_Button
-          (width - BB - 2 * WB, 2 * WB + 7 * BH, BB, BH, "Add");
-        o->callback(elementary_define_point_cb);
+          (width - BB - 2 * WB, 2 * WB + 8 * BH, BB, BH, "Add");
+        o->callback(elementary_add_point_cb);
       }
       group[1]->end();
     }
-    // 2: Translation
+    // 2: Circle
     {
       group[2] = new Fl_Group
-        (WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Translation");
-      input[6] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "X component");
-      input[6]->value("0");
-      input[7] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Y component");
-      input[7]->value("0");
-      input[8] = new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Z component");
-      input[8]->value("1");
-      for(int i = 6; i < 9; i++) {
+        (WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Circle");
+      input[8] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "Center X coordinate");
+      input[8]->value("0");
+      input[9] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Center Y coordinate");
+      input[9]->value("0");
+      input[10] = new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Center Z coordinate");
+      input[10]->value("0");
+      input[11] = new Fl_Input(2 * WB, 2 * WB + 4 * BH, IW, BH, "Radius");
+      input[11]->value("1");
+      input[12] = new Fl_Input(2 * WB, 2 * WB + 5 * BH, IW, BH, "Angle 1");
+      input[12]->value("");
+      input[13] = new Fl_Input(2 * WB, 2 * WB + 6 * BH, IW, BH, "Angle 2");
+      input[13]->value("");
+      for(int i = 8; i < 14; i++)
         input[i]->align(FL_ALIGN_RIGHT);
+      {
+        Fl_Return_Button *o = new Fl_Return_Button
+          (width - BB - 2 * WB, 2 * WB + 8 * BH, BB, BH, "Add");
+        o->callback(elementary_add_circle_cb);
       }
       group[2]->end();
     }
-    // 3: Rotation
+    // 3: Ellipse
     {
       group[3] = new Fl_Group
-        (WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Rotation");
-      input[9] = new Fl_Input
-        (2 * WB, 2 * WB + 1 * BH, IW, BH, "X coordinate of an axis point");
-      input[9]->value("0");
-      input[10] = new Fl_Input
-        (2 * WB, 2 * WB + 2 * BH, IW, BH, "Y coordinate of an axis point");
-      input[10]->value("0");
-      input[11] = new Fl_Input
-        (2 * WB, 2 * WB + 3 * BH, IW, BH, "Z coordinate of an axis point");
-      input[11]->value("0");
-      input[12] = new Fl_Input
-        (2 * WB, 2 * WB + 4 * BH, IW, BH, "X component of axis direction");
-      input[12]->value("0");
-      input[13] = new Fl_Input
-        (2 * WB, 2 * WB + 5 * BH, IW, BH, "Y component of axis direction");
-      input[13]->value("1");
-      input[14] = new Fl_Input
-        (2 * WB, 2 * WB + 6 * BH, IW, BH, "Z component of axis direction");
+        (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 + 7 * BH, IW, BH, "Angle in radians");
-      input[15]->value("Pi/4");
-      for(int i = 9; i < 16; i++) {
+      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);
+      {
+        Fl_Return_Button *o = new Fl_Return_Button
+          (width - BB - 2 * WB, 2 * WB + 8 * BH, BB, BH, "Add");
+        o->callback(elementary_add_ellipse_cb);
       }
       group[3]->end();
     }
-    // 4: Scale
+    // 4: Disk
     {
       group[4] = new Fl_Group
-        (WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Scale");
-      input[16] = new Fl_Input
-        (2 * WB, 2 * WB + 1 * BH, IW, BH, "X component of direction");
-      input[16]->value("0");
-      input[17] = new Fl_Input
-        (2 * WB, 2 * WB + 2 * BH, IW, BH, "Y component of direction");
-      input[17]->value("0");
-      input[18] = new Fl_Input
-        (2 * WB, 2 * WB + 3 * BH, IW, BH, "Z component of direction");
-      input[18]->value("0");
-      input[19] = new Fl_Input
-        (2 * WB, 2 * WB + 4 * BH, IW, BH, "Factor");
-      input[19]->value("0.5");
-      for(int i = 16; i < 20; i++) {
+        (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 + 5 * BH, IW, BH, "Y radius");
+      input[25]->value("0.5");
+      for(int i = 21; i < 26; i++)
         input[i]->align(FL_ALIGN_RIGHT);
+      {
+        Fl_Return_Button *o = new Fl_Return_Button
+          (width - BB - 2 * WB, 2 * WB + 8 * BH, BB, BH, "Add");
+        o->callback(elementary_add_disk_cb);
       }
       group[4]->end();
     }
-    // 5: Symmetry
+    // 5: Rectangle
     {
       group[5] = new Fl_Group
-        (WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Symmetry");
-      input[20] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "A");
-      input[20]->value("1");
-      input[21] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "B");
-      input[21]->value("0");
-      input[22] = new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "C");
-      input[22]->value("0");
-      input[23] = new Fl_Input(2 * WB, 2 * WB + 4 * BH, IW, BH, "D");
-      input[23]->value("1");
-      for(int i = 20; i < 24; i++) {
+        (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 + 4 * BH, IW, BH, "Width");
+      input[29]->value("1");
+      input[30] = new Fl_Input(2 * WB, 2 * WB + 5 * BH, IW, BH, "Height");
+      input[30]->value("0.5");
+      input[31] = new Fl_Input(2 * WB, 2 * WB + 6 * BH, IW, BH, "Rounded radius");
+      input[31]->value("");
+      for(int i = 26; i < 32; i++)
         input[i]->align(FL_ALIGN_RIGHT);
+      {
+        Fl_Return_Button *o = new Fl_Return_Button
+          (width - BB - 2 * WB, 2 * WB + 8 * BH, BB, BH, "Add");
+        o->callback(elementary_add_rectangle_cb);
       }
       group[5]->end();
     }
-    o->end();
+    tab1->end();
+  }
+  {
+    tab2 = new Fl_Tabs(WB, WB, width - 2 * WB, height - 2 * WB);
+    // 6: Sphere
+    {
+      group[6] = new Fl_Group
+        (WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Sphere");
+      input[32] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "Center X coordinate");
+      input[32]->value("0");
+      input[33] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Center Y coordinate");
+      input[33]->value("0");
+      input[34] = new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Center Z coordinate");
+      input[34]->value("0");
+      input[35] = new Fl_Input(2 * WB, 2 * WB + 4 * BH, IW, BH, "Radius");
+      input[35]->value("1");
+      input[36] = new Fl_Input(2 * WB, 2 * WB + 5 * BH, IW, BH, "Angle 1");
+      input[36]->value("");
+      input[37] = new Fl_Input(2 * WB, 2 * WB + 6 * BH, IW, BH, "Angle 2");
+      input[37]->value("");
+      input[38] = new Fl_Input(2 * WB, 2 * WB + 7 * BH, IW, BH, "Angle 3");
+      input[38]->value("");
+      for(int i = 32; i < 39; i++)
+        input[i]->align(FL_ALIGN_RIGHT);
+      {
+        Fl_Return_Button *o = new Fl_Return_Button
+          (width - BB - 2 * WB, 2 * WB + 8 * BH, BB, BH, "Add");
+        o->callback(elementary_add_sphere_cb);
+      }
+      group[6]->end();
+    }
+    // 7: Cylinder
+    {
+      group[7] = new Fl_Group
+        (WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Wedge");
+      group[7]->end();
+    }
+    // 8: Block
+    {
+      group[8] = new Fl_Group
+        (WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Block");
+      group[8]->end();
+    }
+    // 9: Torus
+    {
+      group[9] = new Fl_Group
+        (WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Torus");
+      group[9]->end();
+    }
+    // 10: Cone
+    {
+      group[10] = new Fl_Group
+        (WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Cone");
+      group[10]->end();
+    }
+    // 11: Wedge
+    {
+      group[11] = new Fl_Group
+        (WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Wedge");
+      group[11]->end();
+    }
+    tab2->end();
   }
 
+  {
+    Fl_Button *o = new Fl_Button(width - 4 * WB, WB, 3*WB, 3*WB, "...");
+    o->callback(elementary_switch_tabs_cb);
+  }
+
+  tab1->show();
+  tab2->hide();
+
   win->position(CTX::instance()->ctxPosition[0], CTX::instance()->ctxPosition[1]);
   win->end();
 
@@ -213,20 +386,152 @@ bool elementaryContextWindow::frozenPointCoord(int coord)
   return _butt[coord]->value() ? true : false;
 }
 
-void elementaryContextWindow::updatePoint(double pt[3])
+void elementaryContextWindow::updatePoint(double pt[3], int which)
 {
   for(int i = 0; i < 3; i++){
     if(!frozenPointCoord(i)){
       char str[32];
       sprintf(str, "%g", pt[i]);
-      input[2 + i]->value(str);
+      if(which == 1){
+        input[4 + i]->value(str);
+        input[8 + i]->value(str);
+        input[14 + i]->value(str);
+        input[21 + i]->value(str);
+        input[26 + i]->value(str);
+        input[32 + i]->value(str);
+      }
     }
   }
 }
 
 void elementaryContextWindow::show(int pane)
 {
-  for(int i = 0; i < 6; i++)
+  if(pane < 0 || pane > 10) return;
+
+  for(int i = 0; i < 11; i++)
+    group[i]->hide();
+
+  if(pane < 6){
+    tab1->show();
+    tab2->hide();
+  }
+  else{
+    tab1->hide();
+    tab2->show();
+  }
+
+  group[pane]->show();
+  win->show();
+}
+
+transformContextWindow::transformContextWindow(int deltaFontSize)
+{
+  FL_NORMAL_SIZE -= deltaFontSize;
+
+  int width = 31 * FL_NORMAL_SIZE;
+  int height = 4 * WB + 8 * BH;
+
+  win = new paletteWindow(width, height, CTX::instance()->nonModalWindows ? true : false,
+                          "Transformation Context");
+  win->box(GMSH_WINDOW_BOX);
+  {
+    Fl_Tabs *o = new Fl_Tabs(WB, WB, width - 2 * WB, height - 2 * WB);
+    // 0: Translation
+    {
+      group[0] = new Fl_Group
+        (WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Translation");
+      input[0] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "X component");
+      input[0]->value("0");
+      input[1] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Y component");
+      input[1]->value("0");
+      input[2] = new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Z component");
+      input[2]->value("1");
+      for(int i = 0; i < 3; i++) {
+        input[i]->align(FL_ALIGN_RIGHT);
+      }
+      group[0]->end();
+    }
+    // 1: Rotation
+    {
+      group[1] = new Fl_Group
+        (WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Rotation");
+      input[3] = new Fl_Input
+        (2 * WB, 2 * WB + 1 * BH, IW, BH, "X coordinate of an axis point");
+      input[3]->value("0");
+      input[4] = new Fl_Input
+        (2 * WB, 2 * WB + 2 * BH, IW, BH, "Y coordinate of an axis point");
+      input[4]->value("0");
+      input[5] = new Fl_Input
+        (2 * WB, 2 * WB + 3 * BH, IW, BH, "Z coordinate of an axis point");
+      input[5]->value("0");
+      input[6] = new Fl_Input
+        (2 * WB, 2 * WB + 4 * BH, IW, BH, "X component of axis direction");
+      input[6]->value("0");
+      input[7] = new Fl_Input
+        (2 * WB, 2 * WB + 5 * BH, IW, BH, "Y component of axis direction");
+      input[7]->value("1");
+      input[8] = new Fl_Input
+        (2 * WB, 2 * WB + 6 * BH, IW, BH, "Z component of axis direction");
+      input[8]->value("0");
+      input[9] = new Fl_Input
+        (2 * WB, 2 * WB + 7 * BH, IW, BH, "Angle in radians");
+      input[9]->value("Pi/4");
+      for(int i = 3; i < 10; i++) {
+        input[i]->align(FL_ALIGN_RIGHT);
+      }
+      group[1]->end();
+    }
+    // 2: Scale
+    {
+      group[2] = new Fl_Group
+        (WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Scale");
+      input[10] = new Fl_Input
+        (2 * WB, 2 * WB + 1 * BH, IW, BH, "X component of direction");
+      input[10]->value("0");
+      input[11] = new Fl_Input
+        (2 * WB, 2 * WB + 2 * BH, IW, BH, "Y component of direction");
+      input[11]->value("0");
+      input[12] = new Fl_Input
+        (2 * WB, 2 * WB + 3 * BH, IW, BH, "Z component of direction");
+      input[12]->value("0");
+      input[13] = new Fl_Input
+        (2 * WB, 2 * WB + 4 * BH, IW, BH, "Factor");
+      input[13]->value("0.5");
+      for(int i = 10; i < 14; i++) {
+        input[i]->align(FL_ALIGN_RIGHT);
+      }
+      group[2]->end();
+    }
+    // 3: Symmetry
+    {
+      group[3] = new Fl_Group
+        (WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Symmetry");
+      input[14] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "A");
+      input[14]->value("1");
+      input[15] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "B");
+      input[15]->value("0");
+      input[16] = new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "C");
+      input[16]->value("0");
+      input[17] = new Fl_Input(2 * WB, 2 * WB + 4 * BH, IW, BH, "D");
+      input[17]->value("1");
+      for(int i = 14; i < 18; i++) {
+        input[i]->align(FL_ALIGN_RIGHT);
+      }
+      group[3]->end();
+    }
+    o->end();
+  }
+
+  win->position(CTX::instance()->ctxPosition[0], CTX::instance()->ctxPosition[1]);
+  win->end();
+
+  FL_NORMAL_SIZE += deltaFontSize;
+}
+
+void transformContextWindow::show(int pane)
+{
+  if(pane < 0 || pane > 3) return;
+  for(int i = 0; i < 4; i++)
     group[i]->hide();
   group[pane]->show();
   win->show();
diff --git a/Fltk/contextWindow.h b/Fltk/contextWindow.h
index ac54bc27001db55ab98b7f35f2f3b7c0ffd2a154..357f2757a6f7a7254f499302a67af40071e8f188 100644
--- a/Fltk/contextWindow.h
+++ b/Fltk/contextWindow.h
@@ -13,21 +13,35 @@
 #include <FL/Fl_Check_Button.H>
 #include <FL/Fl_Choice.H>
 #include <FL/Fl_Group.H>
+#include <FL/Fl_Tabs.H>
 
 class elementaryContextWindow{
  public:
   Fl_Window *win;
-  Fl_Input *input[30];
+  Fl_Tabs *tab1, *tab2;
+  Fl_Input *input[50];
   Fl_Value_Input *value[10];
-  Fl_Group *group[10];
+  Fl_Group *group[20];
   Fl_Check_Button *_butt[3];
  public:
   elementaryContextWindow(int deltaFontSize=0);
   void show(int pane);
-  void updatePoint(double pt[3]);
+  void updatePoint(double pt[3], int which);
   bool frozenPointCoord(int coord);
 };
 
+class transformContextWindow{
+ public:
+  Fl_Window *win;
+  Fl_Input *input[30];
+  Fl_Value_Input *value[10];
+  Fl_Group *group[10];
+  Fl_Check_Button *_butt[3];
+ public:
+  transformContextWindow(int deltaFontSize=0);
+  void show(int pane);
+};
+
 class physicalContextWindow{
  public:
   Fl_Window *win;
diff --git a/Fltk/graphicWindow.cpp b/Fltk/graphicWindow.cpp
index 88fca79a6897811a3adc9adac14c71965ab8a865..289a515591a2e8614e9925590317614fb331ef0d 100644
--- a/Fltk/graphicWindow.cpp
+++ b/Fltk/graphicWindow.cpp
@@ -646,34 +646,87 @@ void geometry_remove_last_command_cb(Fl_Widget *w, void *data)
   drawContext::global()->draw();
 }
 
-static void add_new_point()
+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();
 
-  FlGui::instance()->elementaryContext->show(1);
+  FlGui::instance()->elementaryContext->show(pane);
 
   while(1) {
     for(unsigned int i = 0; i < FlGui::instance()->graph.size(); i++)
       for(unsigned int j = 0; j < FlGui::instance()->graph[i]->gl.size(); j++)
-        FlGui::instance()->graph[i]->gl[j]->addPointMode = true;
-    Msg::StatusGl("Move mouse and/or enter coordinates\n"
-                  "[Press 'Shift' to hold position, 'e' to add point "
-                  "or 'q' to abort]");
+        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 " + what +
+      " or 'q' to abort]";
+    Msg::StatusGl(msg.c_str());
     char ib = FlGui::instance()->selectEntity(ENT_NONE);
     if(ib == 'e'){
-      add_point(GModel::current()->getFileName(),
-                FlGui::instance()->elementaryContext->input[2]->value(),
-                FlGui::instance()->elementaryContext->input[3]->value(),
-                FlGui::instance()->elementaryContext->input[4]->value(),
-                FlGui::instance()->elementaryContext->input[5]->value());
+      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 2:
+        add_circle(GModel::current()->getFileName(),
+                   FlGui::instance()->elementaryContext->input[8]->value(),
+                   FlGui::instance()->elementaryContext->input[9]->value(),
+                   FlGui::instance()->elementaryContext->input[10]->value(),
+                   FlGui::instance()->elementaryContext->input[11]->value(),
+                   FlGui::instance()->elementaryContext->input[12]->value(),
+                   FlGui::instance()->elementaryContext->input[13]->value());
+        break;
+      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[32]->value(),
+                   FlGui::instance()->elementaryContext->input[33]->value(),
+                   FlGui::instance()->elementaryContext->input[34]->value(),
+                   FlGui::instance()->elementaryContext->input[35]->value(),
+                   FlGui::instance()->elementaryContext->input[36]->value(),
+                   FlGui::instance()->elementaryContext->input[37]->value(),
+                   FlGui::instance()->elementaryContext->input[38]->value());
+        break;
+      case 7:
+        break;
+      }
       FlGui::instance()->resetVisibility();
       drawContext::global()->draw();
     }
     if(ib == 'q'){
       for(unsigned int i = 0; i < FlGui::instance()->graph.size(); i++)
         for(unsigned int j = 0; j < FlGui::instance()->graph[i]->gl.size(); j++)
-          FlGui::instance()->graph[i]->gl[j]->addPointMode = false;
+          FlGui::instance()->graph[i]->gl[j]->addPointMode = 0;
       break;
     }
   }
@@ -783,7 +836,7 @@ static void add_new_line()
   Msg::StatusGl("");
 }
 
-static void add_new_circle()
+static void add_new_circle_arc()
 {
   opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
   opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1);
@@ -823,7 +876,7 @@ static void add_new_circle()
       break;
     }
     if(p.size() == 3) {
-      add_circ(p[0], p[1], p[2], GModel::current()->getFileName()); // begin, center, end
+      add_circle_arc(p[0], p[1], p[2], GModel::current()->getFileName()); // begin, center, end
       FlGui::instance()->resetVisibility();
       GModel::current()->setSelection(0);
       drawContext::global()->draw();
@@ -834,7 +887,7 @@ static void add_new_circle()
   Msg::StatusGl("");
 }
 
-static void add_new_ellipse()
+static void add_new_ellipse_arc()
 {
   opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
   opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1);
@@ -877,7 +930,7 @@ static void add_new_ellipse()
       break;
     }
     if(p.size() == 4) {
-      add_ell(p[0], p[1], p[2], p[3], GModel::current()->getFileName());
+      add_ellipse_arc(p[0], p[1], p[2], p[3], GModel::current()->getFileName());
       FlGui::instance()->resetVisibility();
       GModel::current()->setSelection(0);
       drawContext::global()->draw();
@@ -1078,6 +1131,15 @@ static void add_new_surface_volume(int mode)
   Msg::StatusGl("");
 }
 
+static void geometry_elementary_set_factory_cb(Fl_Widget *w, void *data)
+{
+  if(!data) return;
+  std::string str((const char*)data);
+  add_infile("SetFactory(\"" + str + "\");", GModel::current()->getFileName());
+  if(FlGui::available())
+    Msg::StatusBar(false, "Setting %s factory", str.c_str());
+}
+
 static void geometry_elementary_add_new_cb(Fl_Widget *w, void *data)
 {
   if(!data) return;
@@ -1086,21 +1148,41 @@ 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();
+    add_new_point_based_entity(str, 1);
   else if(str == "Line")
     add_new_line();
   else if(str == "Spline")
     add_new_multiline(str);
   else if(str == "BSpline")
     add_new_multiline(str);
+  else if(str == "Circle arc")
+    add_new_circle_arc();
   else if(str == "Circle")
-    add_new_circle();
+    add_new_point_based_entity(str, 2);
+  else if(str == "Ellipse arc")
+    add_new_ellipse_arc();
   else if(str == "Ellipse")
-    add_new_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
@@ -1313,49 +1395,49 @@ static void action_point_line_surface_volume(int action, int mode, const char *w
         switch (action) {
         case 0:
           translate(mode, List1, GModel::current()->getFileName(), what,
-                    FlGui::instance()->elementaryContext->input[6]->value(),
-                    FlGui::instance()->elementaryContext->input[7]->value(),
-                    FlGui::instance()->elementaryContext->input[8]->value());
+                    FlGui::instance()->transformContext->input[0]->value(),
+                    FlGui::instance()->transformContext->input[1]->value(),
+                    FlGui::instance()->transformContext->input[2]->value());
           break;
         case 1:
           rotate(mode, List1, GModel::current()->getFileName(), what,
-                 FlGui::instance()->elementaryContext->input[12]->value(),
-                 FlGui::instance()->elementaryContext->input[13]->value(),
-                 FlGui::instance()->elementaryContext->input[14]->value(),
-                 FlGui::instance()->elementaryContext->input[9]->value(),
-                 FlGui::instance()->elementaryContext->input[10]->value(),
-                 FlGui::instance()->elementaryContext->input[11]->value(),
-                 FlGui::instance()->elementaryContext->input[15]->value());
+                 FlGui::instance()->transformContext->input[6]->value(),
+                 FlGui::instance()->transformContext->input[7]->value(),
+                 FlGui::instance()->transformContext->input[8]->value(),
+                 FlGui::instance()->transformContext->input[3]->value(),
+                 FlGui::instance()->transformContext->input[4]->value(),
+                 FlGui::instance()->transformContext->input[5]->value(),
+                 FlGui::instance()->transformContext->input[9]->value());
           break;
         case 2:
           dilate(mode, List1, GModel::current()->getFileName(), what,
-                 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()->transformContext->input[10]->value(),
+                 FlGui::instance()->transformContext->input[11]->value(),
+                 FlGui::instance()->transformContext->input[12]->value(),
+                 FlGui::instance()->transformContext->input[13]->value());
           break;
         case 3:
           symmetry(mode, List1, GModel::current()->getFileName(), what,
-                   FlGui::instance()->elementaryContext->input[20]->value(),
-                   FlGui::instance()->elementaryContext->input[21]->value(),
-                   FlGui::instance()->elementaryContext->input[22]->value(),
-                   FlGui::instance()->elementaryContext->input[23]->value());
+                   FlGui::instance()->transformContext->input[14]->value(),
+                   FlGui::instance()->transformContext->input[15]->value(),
+                   FlGui::instance()->transformContext->input[16]->value(),
+                   FlGui::instance()->transformContext->input[17]->value());
           break;
         case 4:
           extrude(List1, GModel::current()->getFileName(), what,
-                  FlGui::instance()->elementaryContext->input[6]->value(),
-                  FlGui::instance()->elementaryContext->input[7]->value(),
-                  FlGui::instance()->elementaryContext->input[8]->value());
+                  FlGui::instance()->transformContext->input[0]->value(),
+                  FlGui::instance()->transformContext->input[1]->value(),
+                  FlGui::instance()->transformContext->input[2]->value());
           break;
         case 5:
           protude(List1, GModel::current()->getFileName(), what,
-                  FlGui::instance()->elementaryContext->input[12]->value(),
-                  FlGui::instance()->elementaryContext->input[13]->value(),
-                  FlGui::instance()->elementaryContext->input[14]->value(),
-                  FlGui::instance()->elementaryContext->input[9]->value(),
-                  FlGui::instance()->elementaryContext->input[10]->value(),
-                  FlGui::instance()->elementaryContext->input[11]->value(),
-                  FlGui::instance()->elementaryContext->input[15]->value());
+                  FlGui::instance()->transformContext->input[6]->value(),
+                  FlGui::instance()->transformContext->input[7]->value(),
+                  FlGui::instance()->transformContext->input[8]->value(),
+                  FlGui::instance()->transformContext->input[3]->value(),
+                  FlGui::instance()->transformContext->input[4]->value(),
+                  FlGui::instance()->transformContext->input[5]->value(),
+                  FlGui::instance()->transformContext->input[9]->value());
           break;
         case 6:
           delet(List1, GModel::current()->getFileName(), what);
@@ -1407,70 +1489,70 @@ static void action_point_line_surface_volume(int action, int mode, const char *w
 static void geometry_elementary_add_translate_cb(Fl_Widget *w, void *data)
 {
   if(!data) return;
-  FlGui::instance()->elementaryContext->show(2);
+  FlGui::instance()->transformContext->show(0);
   action_point_line_surface_volume(0, 1, (const char*)data);
 }
 
 static void geometry_elementary_add_rotate_cb(Fl_Widget *w, void *data)
 {
   if(!data) return;
-  FlGui::instance()->elementaryContext->show(3);
+  FlGui::instance()->transformContext->show(1);
   action_point_line_surface_volume(1, 1, (const char*)data);
 }
 
 static void geometry_elementary_add_scale_cb(Fl_Widget *w, void *data)
 {
   if(!data) return;
-  FlGui::instance()->elementaryContext->show(4);
+  FlGui::instance()->transformContext->show(2);
   action_point_line_surface_volume(2, 1, (const char*)data);
 }
 
 static void geometry_elementary_add_symmetry_cb(Fl_Widget *w, void *data)
 {
   if(!data) return;
-  FlGui::instance()->elementaryContext->show(5);
+  FlGui::instance()->transformContext->show(3);
   action_point_line_surface_volume(3, 1, (const char*)data);
 }
 
 static void geometry_elementary_translate_cb(Fl_Widget *w, void *data)
 {
   if(!data) return;
-  FlGui::instance()->elementaryContext->show(2);
+  FlGui::instance()->transformContext->show(0);
   action_point_line_surface_volume(0, 0, (const char*)data);
 }
 
 static void geometry_elementary_rotate_cb(Fl_Widget *w, void *data)
 {
   if(!data) return;
-  FlGui::instance()->elementaryContext->show(3);
+  FlGui::instance()->transformContext->show(1);
   action_point_line_surface_volume(1, 0, (const char*)data);
 }
 
 static void geometry_elementary_scale_cb(Fl_Widget *w, void *data)
 {
   if(!data) return;
-  FlGui::instance()->elementaryContext->show(4);
+  FlGui::instance()->transformContext->show(2);
   action_point_line_surface_volume(2, 0, (const char*)data);
 }
 
 static void geometry_elementary_symmetry_cb(Fl_Widget *w, void *data)
 {
   if(!data) return;
-  FlGui::instance()->elementaryContext->show(5);
+  FlGui::instance()->transformContext->show(3);
   action_point_line_surface_volume(3, 0, (const char*)data);
 }
 
 static void geometry_elementary_extrude_translate_cb(Fl_Widget *w, void *data)
 {
   if(!data) return;
-  FlGui::instance()->elementaryContext->show(2);
+  FlGui::instance()->transformContext->show(0);
   action_point_line_surface_volume(4, 0, (const char*)data);
 }
 
 static void geometry_elementary_extrude_rotate_cb(Fl_Widget *w, void *data)
 {
   if(!data) return;
-  FlGui::instance()->elementaryContext->show(3);
+  FlGui::instance()->transformContext->show(1);
   action_point_line_surface_volume(5, 0, (const char*)data);
 }
 
@@ -3654,6 +3736,10 @@ typedef struct{
 } menuItem;
 
 static menuItem static_modules[] = {
+  {"0Modules/Geometry/Elementary entities/Set factory/Gmsh",
+   (Fl_Callback *)geometry_elementary_set_factory_cb, (void*)"Gmsh"} ,
+  {"0Modules/Geometry/Elementary entities/Set factory/OpenCASCADE",
+   (Fl_Callback *)geometry_elementary_set_factory_cb, (void*)"OpenCASCADE"} ,
   {"0Modules/Geometry/Elementary entities/Add/Parameter",
    (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Parameter"} ,
   {"0Modules/Geometry/Elementary entities/Add/Point",
@@ -3664,14 +3750,36 @@ static menuItem static_modules[] = {
    (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Spline"} ,
   {"0Modules/Geometry/Elementary entities/Add/B-Spline",
    (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"BSpline"} ,
-  {"0Modules/Geometry/Elementary entities/Add/Circle arc",
+  {"0Modules/Geometry/Elementary entities/Add/Bezier",
+   (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Bezier"} ,
+  {"0Modules/Geometry/Elementary entities/Add/Circle",
    (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Circle"} ,
-  {"0Modules/Geometry/Elementary entities/Add/Ellipse arc",
+  {"0Modules/Geometry/Elementary entities/Add/Circle arc",
+   (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Circle arc"} ,
+  {"0Modules/Geometry/Elementary entities/Add/Ellipse",
    (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Ellipse"} ,
+  {"0Modules/Geometry/Elementary entities/Add/Ellipse arc",
+   (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Ellipse arc"} ,
+  {"0Modules/Geometry/Elementary entities/Add/Rectangle",
+   (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Rectangle"} ,
+  {"0Modules/Geometry/Elementary entities/Add/Disk",
+   (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Disk"} ,
   {"0Modules/Geometry/Elementary entities/Add/Plane surface",
    (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Plane Surface"} ,
-  {"0Modules/Geometry/Elementary entities/Add/Ruled surface",
+  {"0Modules/Geometry/Elementary entities/Add/Surface filling",
    (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Surface"} ,
+  {"0Modules/Geometry/Elementary entities/Add/Sphere",
+   (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Sphere"} ,
+  {"0Modules/Geometry/Elementary entities/Add/Cylinder",
+   (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Cylinder"} ,
+  {"0Modules/Geometry/Elementary entities/Add/Block",
+   (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Block"} ,
+  {"0Modules/Geometry/Elementary entities/Add/Torus",
+   (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Torus"} ,
+  {"0Modules/Geometry/Elementary entities/Add/Cone",
+   (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Cone"} ,
+  {"0Modules/Geometry/Elementary entities/Add/Wedge",
+   (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Wedge"} ,
   {"0Modules/Geometry/Elementary entities/Add/Volume",
    (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Volume"} ,
   {"0Modules/Geometry/Elementary entities/Translate/Point",
@@ -3750,8 +3858,6 @@ static menuItem static_modules[] = {
    (Fl_Callback *)geometry_elementary_add_symmetry_cb, (void*)"Surface"} ,
   {"0Modules/Geometry/Elementary entities/Symmetry/Duplicate volume",
    (Fl_Callback *)geometry_elementary_add_symmetry_cb, (void*)"Volume"} ,
-  {"0Modules/Geometry/Elementary entities/Split/Line",
-   (Fl_Callback *)geometry_elementary_split_cb,(void*)"Line"},
   {"0Modules/Geometry/Elementary entities/Delete/Point",
    (Fl_Callback *)geometry_elementary_delete_cb, (void*)"Point"} ,
   {"0Modules/Geometry/Elementary entities/Delete/Line",
@@ -3760,6 +3866,8 @@ static menuItem static_modules[] = {
    (Fl_Callback *)geometry_elementary_delete_cb, (void*)"Surface"} ,
   {"0Modules/Geometry/Elementary entities/Delete/Volume",
    (Fl_Callback *)geometry_elementary_delete_cb, (void*)"Volume"} ,
+  {"0Modules/Geometry/Elementary entities/Split line",
+   (Fl_Callback *)geometry_elementary_split_cb,(void*)"Line"},
   {"0Modules/Geometry/Elementary entities/Coherence",
    (Fl_Callback *)geometry_elementary_coherence_cb} ,
   {"0Modules/Geometry/Physical groups/Add/Point",
diff --git a/Fltk/openglWindow.cpp b/Fltk/openglWindow.cpp
index 8c5dd4f0f98ad69fdef1bf09a233fb7835f6da09..02e1d62dd3808d7858eab5c4adbff4a9179c6078 100644
--- a/Fltk/openglWindow.cpp
+++ b/Fltk/openglWindow.cpp
@@ -73,7 +73,8 @@ openglWindow::openglWindow(int x, int y, int w, int h)
   for(int i = 0; i < 4; i++) _trySelectionXYWH[i] = 0;
   _lassoXY[0] = _lassoXY[1] = 0;
 
-  addPointMode = lassoMode = selectionMode = false;
+  addPointMode = 0;
+  lassoMode = selectionMode = false;
   endSelection = undoSelection = invertSelection = quitSelection = 0;
 
   if(CTX::instance()->gamepad) Fl::add_timeout(.5, navigator_handler, (void*)this);
@@ -638,7 +639,7 @@ int openglWindow::handle(int event)
           }
         }
       }
-      FlGui::instance()->elementaryContext->updatePoint(_point);
+      FlGui::instance()->elementaryContext->updatePoint(_point, addPointMode);
       redraw();
     }
     else{ // hover mode
@@ -788,7 +789,7 @@ char openglWindow::selectEntity(int type,
       _selection = ENT_NONE;
       selectionMode = false;
       lassoMode = false;
-      addPointMode = false;
+      addPointMode = 0;
       cursor(FL_CURSOR_DEFAULT, FL_BLACK, FL_WHITE);
       return 'q';
     }
diff --git a/Fltk/openglWindow.h b/Fltk/openglWindow.h
index a4e66245e95837d5da6b3694ac904ca3e7781929..998f03a30440f677db9d091a1ed3d04581f5212a 100644
--- a/Fltk/openglWindow.h
+++ b/Fltk/openglWindow.h
@@ -45,7 +45,8 @@ class openglWindow : public Fl_Gl_Window {
   int pixel_h();
   time_t rawtime,  prev_rawtime;
   double response_frequency;
-  bool addPointMode, lassoMode, selectionMode;
+  int addPointMode;
+  bool lassoMode, selectionMode;
   int endSelection, undoSelection, invertSelection, quitSelection;
   std::string screenMessage[2];
   openglWindow(int x, int y, int w, int h);
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 7093bf5ae06dfbe89acede068d56bbe6f2dc7791..29652d6ebbdac93aa221d6e3fefd8318ec5f21bf 100644
--- a/Geo/GeoStringInterface.cpp
+++ b/Geo/GeoStringInterface.cpp
@@ -9,6 +9,7 @@
 #include "GmshMessage.h"
 #include "GModel.h"
 #include "GModelIO_GEO.h"
+#include "GModelIO_OCC.h"
 #include "Numeric.h"
 #include "StringUtils.h"
 #include "Geo.h"
@@ -102,6 +103,8 @@ void add_infile(const std::string &text, const std::string &fileName, bool force
     GModel::current()->destroy();
   }
   GModel::current()->getGEOInternals()->synchronize(GModel::current());
+  if(GModel::current()->getOCCInternals())
+    GModel::current()->getOCCInternals()->synchronize(GModel::current());
   GModel::current()->setName(split[1]);
   CTX::instance()->mesh.changed = ENT_ALL;
 
@@ -327,7 +330,7 @@ void add_multline(const std::string &type, std::vector<int> &p,
   add_infile(sstream.str(), fileName);
 }
 
-void add_circ(int p1, int p2, int p3, const std::string &fileName)
+void add_circle_arc(int p1, int p2, int p3, const std::string &fileName)
 {
   std::ostringstream sstream;
   sstream << "Circle(" << NEWLINE() << ") = {" << p1 << ", " << p2 << ", "
@@ -335,7 +338,7 @@ void add_circ(int p1, int p2, int p3, const std::string &fileName)
   add_infile(sstream.str(), fileName);
 }
 
-void add_ell(int p1, int p2, int p3, int p4, const std::string &fileName)
+void add_ellipse_arc(int p1, int p2, int p3, int p4, const std::string &fileName)
 {
   std::ostringstream sstream;
   sstream << "Ellipse(" << NEWLINE() << ") = {" << p1 << ", " << p2 << ", "
@@ -417,6 +420,73 @@ void add_compound(const std::string &type, List_T *list, const std::string &file
   add_infile(sstream.str(), fileName);
 }
 
+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)
+{
+  std::ostringstream sstream;
+  sstream << "Circle(" << NEWLINE() << ") = {" << x << "," << y << "," << z << "," << r;
+  if(alpha1.size())
+    sstream << ", " << alpha1;
+  if(alpha1.size() && alpha2.size())
+    sstream << ", " << alpha2;
+  sstream << "};";
+  add_infile(sstream.str(), fileName);
+}
+
+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 << "Ellipse(" << NEWLINE() << ") = {" << x << "," << y << "," << z << ","
+          << rx << ", " << ry;
+  if(alpha1.size())
+    sstream << ", " << alpha1;
+  if(alpha1.size() && alpha2.size())
+    sstream << ", " << alpha2;
+  sstream << "};";
+  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)
+{
+  std::ostringstream sstream;
+  sstream << "Sphere(" << NEWVOLUME() << ") = {" << x << "," << y << "," << z << "," << r;
+  if(alpha1.size())
+    sstream << ", " << alpha1;
+  if(alpha1.size() && alpha2.size())
+    sstream << ", " << alpha2;
+  if(alpha1.size() && alpha2.size() && alpha3.size())
+    sstream << ", " << alpha3;
+  sstream << "};";
+  add_infile(sstream.str(), fileName);
+}
+
 void translate(int add, List_T *list, const std::string &fileName,
                const std::string &what, const std::string &tx,
                const std::string &ty, const std::string &tz)
diff --git a/Geo/GeoStringInterface.h b/Geo/GeoStringInterface.h
index eb47250dd91768374c1c27feb057351fbc7aca93..8f7596601b2597e815c9d05dfffe953ed4ed21a2 100644
--- a/Geo/GeoStringInterface.h
+++ b/Geo/GeoStringInterface.h
@@ -31,8 +31,8 @@ void add_point(const std::string &fileName, const std::string &x,
                const std::string &y, const std::string &z, const std::string &lc);
 void add_multline(const std::string &type, std::vector<int> &p,
                   const std::string &fileName);
-void add_circ(int p1, int p2, int p3, const std::string &fileName);
-void add_ell(int p1, int p2, int p3, int p4, const std::string &fileName);
+void add_circle_arc(int p1, int p2, int p3, const std::string &fileName);
+void add_ellipse_arc(int p1, int p2, int p3, int p4, const std::string &fileName);
 void add_field_option(int field_id, const std::string &option_name,
                       const std::string &option_value, const std::string &fileName);
 void add_field(int field_id, const std::string &type_name,
@@ -47,6 +47,21 @@ void add_physical(const std::string &type, List_T *list, const std::string &file
                   const std::string &name, int forceTag, bool append,
                   const std::string &mode);
 void add_compound(const std::string &type, List_T *list, const std::string &fileName);
+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_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,
+                const std::string &alpha3);
 void translate(int add, List_T *list, const std::string &fileName,
                const std::string &what, const std::string &tx, const std::string &ty,
                const std::string &tz);
diff --git a/Mesh/meshGFace.cpp b/Mesh/meshGFace.cpp
index 95d26ebad3d9321620fe40ba7e9484bea793ec62..13772140cfc6264e33d01119d86b1f8452268b59 100644
--- a/Mesh/meshGFace.cpp
+++ b/Mesh/meshGFace.cpp
@@ -1794,14 +1794,18 @@ static bool buildConsecutiveListOfVertices(GFace *gf, GEdgeLoop &gel,
 
     std::vector<MVertex*> edgeLoop;
     if(found._sign == 1){
-      edgeLoop.push_back(found.ge->getBeginVertex()->mesh_vertices[0]);
-      for(unsigned int i = 0; i <found.ge->mesh_vertices.size(); i++)
-        edgeLoop.push_back(found.ge->mesh_vertices[i]);
+      if(found.ge->getBeginVertex()){
+        edgeLoop.push_back(found.ge->getBeginVertex()->mesh_vertices[0]);
+        for(unsigned int i = 0; i <found.ge->mesh_vertices.size(); i++)
+          edgeLoop.push_back(found.ge->mesh_vertices[i]);
+      }
     }
     else{
-      edgeLoop.push_back(found.ge->getEndVertex()->mesh_vertices[0]);
-      for(int i = found.ge->mesh_vertices.size() - 1; i >= 0; i--)
-        edgeLoop.push_back(found.ge->mesh_vertices[i]);
+      if(found.ge->getEndVertex()){
+        edgeLoop.push_back(found.ge->getEndVertex()->mesh_vertices[0]);
+        for(int i = found.ge->mesh_vertices.size() - 1; i >= 0; i--)
+          edgeLoop.push_back(found.ge->mesh_vertices[i]);
+      }
     }
 
     if(MYDEBUG)
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/Plugin/FaultZone.cpp b/Plugin/FaultZone.cpp
index bc9f956a5c78c63e69c864e4d03a9e71f02f5dcf..54ea09867cbbc889ec4c33c8b7aeb4399dcda44f 100644
--- a/Plugin/FaultZone.cpp
+++ b/Plugin/FaultZone.cpp
@@ -636,6 +636,8 @@ void GMSH_FaultZoneMesher::CreateJointElements(GModel* gModel, GFace* gFace,
   }
 
   // replace physical edges by physical surfaces
+
+#if 1 // FIXME this is wrong !?!
   for(int i = 0; i < List_Nbr(gModel->getGEOInternals()->PhysicalGroups); i++){
     PhysicalGroup *p = *(PhysicalGroup**)List_Pointer
       (GModel::current()->getGEOInternals()->PhysicalGroups, i);
@@ -671,6 +673,8 @@ void GMSH_FaultZoneMesher::CreateJointElements(GModel* gModel, GFace* gFace,
       List_Delete(faceEntities);
     }
   }
+#endif
+
 }
 
 //================================================================================
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}; }