From 2a826626c49bbf79f8102a415af7cd0d4b74d1eb Mon Sep 17 00:00:00 2001
From: Christophe Geuzaine <cgeuzaine@ulg.ac.be>
Date: Thu, 30 Mar 2017 14:56:07 +0800
Subject: [PATCH] first steps of new gui for occ entities

---
 Fltk/FlGui.cpp             |   3 +
 Fltk/FlGui.h               |   2 +
 Fltk/contextWindow.cpp     | 354 +++++++++++++++++++++++++++----------
 Fltk/contextWindow.h       |  18 +-
 Fltk/graphicWindow.cpp     | 195 +++++++++++++-------
 Fltk/openglWindow.cpp      |   7 +-
 Fltk/openglWindow.h        |   3 +-
 Geo/GeoStringInterface.cpp |  51 +++++-
 Geo/GeoStringInterface.h   |  14 +-
 9 files changed, 478 insertions(+), 169 deletions(-)

diff --git a/Fltk/FlGui.cpp b/Fltk/FlGui.cpp
index c771c0c679..fd8afdc762 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 b1ad8bd291..116ef21880 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 498893a43f..c853a37be7 100644
--- a/Fltk/contextWindow.cpp
+++ b/Fltk/contextWindow.cpp
@@ -16,30 +16,57 @@
 #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_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();
@@ -58,7 +85,7 @@ elementaryContextWindow::elementaryContextWindow(int deltaFontSize)
                           "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 +94,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);
+        o->callback(elementary_add_parameter_cb);
       }
       group[0]->end();
     }
@@ -84,22 +110,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,
@@ -111,95 +137,103 @@ 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);
+        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 + 7 * 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");
-      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[i]->align(FL_ALIGN_RIGHT);
-      }
+        (WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Ellipse");
       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++) {
-        input[i]->align(FL_ALIGN_RIGHT);
-      }
+        (WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Disk");
       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++) {
-        input[i]->align(FL_ALIGN_RIGHT);
-      }
+        (WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Rectangle");
       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");
+      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 +247,148 @@ 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);
+      }
     }
   }
 }
 
 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 ac54bc2700..c02a65278f 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_Tabs *tab1, *tab2;
   Fl_Input *input[30];
   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 88fca79a68..b724ec78ae 100644
--- a/Fltk/graphicWindow.cpp
+++ b/Fltk/graphicWindow.cpp
@@ -646,34 +646,64 @@ 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(int which)
 {
   opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
   drawContext::global()->draw();
 
-  FlGui::instance()->elementaryContext->show(1);
+  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) {
     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 " + name +
+      " 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(which){
+      case 0:
+        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:
+        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 2:
+        add_sphere(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;
+      }
       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 +813,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 +853,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 +864,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 +907,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 +1108,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,23 +1125,27 @@ 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(0);
   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();
-  else if(str == "Ellipse")
-    add_new_ellipse();
+    add_new_point_based_entity(1);
+  else if(str == "Ellipse arc")
+    add_new_ellipse_arc();
   else if(str == "Plane Surface")
     add_new_surface_volume(0);
   else if(str == "Surface")
     add_new_surface_volume(1);
   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());
 }
@@ -1313,49 +1356,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 +1450,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 +3697,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 +3711,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 +3819,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 +3827,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 8c5dd4f0f9..02e1d62dd3 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 a4e66245e9..998f03a304 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/GeoStringInterface.cpp b/Geo/GeoStringInterface.cpp
index 7093bf5ae0..121856b341 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,50 @@ 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_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)
+{
+  std::ostringstream sstream;
+  sstream << "Disk(" << NEWSURFACE() << ") = {" << x << "," << y << "," << z << "," << r;
+  if(alpha1.size())
+    sstream << ", " << alpha1;
+  if(alpha1.size() && alpha2.size())
+    sstream << ", " << alpha2;
+  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 eb47250dd9..6fb8c8659e 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,16 @@ 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_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_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);
-- 
GitLab