From bbfea7de9ede98e45a0b7a6f979ed1cd14783d3a Mon Sep 17 00:00:00 2001
From: Christophe Geuzaine <cgeuzaine@ulg.ac.be>
Date: Sat, 25 Nov 2006 16:52:53 +0000
Subject: [PATCH] bidir db: phase 3 -- move all the old geo stuff into Geo/

---
 Box/Box.cpp                                   |    3 +-
 Common/DefaultOptions.h                       |    2 -
 Common/GmshDefines.h                          |   17 -
 Common/Makefile                               |   22 +-
 Common/Options.cpp                            |    3 +-
 Fltk/Callbacks.cpp                            |    9 +-
 Fltk/GUI.cpp                                  |    3 +-
 Fltk/GUI_Extras.cpp                           |    4 +-
 Fltk/Main.cpp                                 |    4 +-
 Fltk/Makefile                                 |  130 +-
 Fltk/Opengl.cpp                               |    3 +-
 Fltk/Opengl_Window.h                          |    1 -
 Fltk/Solvers.cpp                              |    3 +-
 Geo/CAD.cpp                                   | 2429 -------------
 Geo/CAD.h                                     |   88 -
 Geo/ExtrudeParams.cpp                         |    3 +-
 Geo/GModelIO_Geo.cpp                          |    3 +-
 Geo/Geo.cpp                                   | 3190 +++++++++++++++--
 Geo/Geo.h                                     |  285 +-
 ...tractContour.cpp => GeoExtractContour.cpp} |    4 +-
 Geo/{ExtractContour.h => GeoExtractContour.h} |    4 +-
 .../GeoInterpolation.cpp                      |  430 ++-
 .../Interpolation.h => Geo/GeoInterpolation.h |   17 +-
 Geo/GeoStringInterface.cpp                    |  545 +++
 Geo/GeoStringInterface.h                      |   64 +
 Geo/GeoUtils.cpp                              |   23 +-
 Geo/GeoUtils.h                                |    2 +-
 Geo/Makefile                                  |  257 +-
 Geo/OCCEdge.cpp                               |    4 +-
 Geo/OCCEdge.h                                 |    1 -
 Geo/OCCRegion.h                               |    1 -
 Geo/OCCVertex.h                               |    1 -
 Geo/gmshEdge.cpp                              |    7 +-
 Geo/gmshEdge.h                                |    2 +-
 Geo/gmshFace.cpp                              |    7 +-
 Geo/gmshFace.h                                |    2 +-
 Geo/gmshRegion.cpp                            |    4 +-
 Geo/gmshRegion.h                              |    2 +-
 Geo/gmshVertex.h                              |    2 +-
 Graphics/Draw.cpp                             |    3 +-
 Graphics/Makefile                             |    8 +-
 Mesh/BackgroundMesh.cpp                       |    5 +-
 Mesh/{Nurbs.h => BackgroundMesh.h}            |   19 +-
 Mesh/Create.cpp                               |  611 ----
 Mesh/Create.h                                 |   62 -
 Mesh/DivideAndConquer.cpp                     |   11 +-
 Mesh/{Mesh.h => DivideAndConquer.h}           |  138 +-
 Mesh/Generator.cpp                            |   12 +-
 Mesh/Generator.h                              |   31 +
 Mesh/Makefile                                 |  135 +-
 Mesh/Nurbs.cpp                                |  449 ---
 Mesh/SecondOrder.h                            |   26 +
 Mesh/Utils.cpp                                |    9 +-
 Mesh/Utils.h                                  |    9 +-
 Mesh/Vertex.cpp                               |  186 -
 Mesh/Vertex.h                                 |   60 -
 Mesh/meshGEdge.cpp                            |    6 +-
 Mesh/meshGFace.cpp                            |    4 +-
 Parser/Gmsh.l                                 |    3 +-
 Parser/Gmsh.tab.cpp                           |  745 ++--
 Parser/Gmsh.y                                 |   15 +-
 Parser/Gmsh.yy.cpp                            |  301 +-
 Parser/Makefile                               |   65 +-
 Parser/OpenFile.cpp                           |    4 +-
 Plugin/Makefile                               |   15 +-
 Plugin/Triangulate.cpp                        |    4 +-
 66 files changed, 5080 insertions(+), 5437 deletions(-)
 delete mode 100644 Geo/CAD.cpp
 delete mode 100644 Geo/CAD.h
 rename Geo/{ExtractContour.cpp => GeoExtractContour.cpp} (98%)
 rename Geo/{ExtractContour.h => GeoExtractContour.h} (93%)
 rename Mesh/Interpolation.cpp => Geo/GeoInterpolation.cpp (61%)
 rename Mesh/Interpolation.h => Geo/GeoInterpolation.h (74%)
 create mode 100644 Geo/GeoStringInterface.cpp
 create mode 100644 Geo/GeoStringInterface.h
 rename Mesh/{Nurbs.h => BackgroundMesh.h} (56%)
 delete mode 100644 Mesh/Create.cpp
 delete mode 100644 Mesh/Create.h
 rename Mesh/{Mesh.h => DivideAndConquer.h} (50%)
 create mode 100644 Mesh/Generator.h
 delete mode 100644 Mesh/Nurbs.cpp
 create mode 100644 Mesh/SecondOrder.h
 delete mode 100644 Mesh/Vertex.cpp
 delete mode 100644 Mesh/Vertex.h

diff --git a/Box/Box.cpp b/Box/Box.cpp
index 6cd202ae0f..54a8686dfd 100644
--- a/Box/Box.cpp
+++ b/Box/Box.cpp
@@ -1,4 +1,4 @@
-// $Id: Box.cpp,v 1.28 2006-11-14 15:21:02 geuzaine Exp $
+// $Id: Box.cpp,v 1.29 2006-11-25 16:52:41 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -23,7 +23,6 @@
 #include "Gmsh.h"
 #include "Numeric.h"
 #include "Geo.h"
-#include "Mesh.h"
 #include "Views.h"
 #include "Parser.h"
 #include "Context.h"
diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h
index 97a4886dbb..b290b3ebcc 100644
--- a/Common/DefaultOptions.h
+++ b/Common/DefaultOptions.h
@@ -947,8 +947,6 @@ StringXNumber MeshOptions_Number[] = {
     "Number of partitions applied to the final mesh" },
   { F|O, "Points" , opt_mesh_points , 0. , 
     "Display mesh vertices (nodes)?" },
-  { F|O, "PointInsertion" , opt_mesh_point_insertion, CENTER_CIRCCIRC ,
-    "Point insertion method for isotropic 2D algorithm (1=center of circumscribed circle, 2=center of gravity)" },
   { F|O, "PointNumbers" , opt_mesh_points_num , 0. , 
     "Display mesh node numbers?" },
   { F|O, "PointSize" , opt_mesh_point_size , 4. , 
diff --git a/Common/GmshDefines.h b/Common/GmshDefines.h
index 45be8448b9..36447c7cf2 100644
--- a/Common/GmshDefines.h
+++ b/Common/GmshDefines.h
@@ -69,23 +69,6 @@
 #define FRONTAL_NETGEN 4
 #define DELAUNAY_TETGEN 5
 
-#define CONV_VALUE    0.8
-
-#define NOTTOLINK 1
-#define TOLINK    2
-
-#define BOF         1
-#define A_TOUT_PRIX 2
-
-#define CENTER_CIRCCIRC 1
-#define BARYCENTER      2
-
-#define EXTERN      1
-#define INTERN      2
-
-#define ONFILE      2
-#define WITHPOINTS  3
-
 #define TRANSFINI 1
 #define LIBRE     2
 #define ELLIPTIC  3
diff --git a/Common/Makefile b/Common/Makefile
index 5cf1de051a..5794e7f067 100644
--- a/Common/Makefile
+++ b/Common/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.117 2006-11-25 02:47:39 geuzaine Exp $
+# $Id: Makefile,v 1.118 2006-11-25 16:52:41 geuzaine Exp $
 #
 # Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 #
@@ -96,21 +96,19 @@ Options.o: Options.cpp Gmsh.h Message.h ../DataStr/Malloc.h \
   ../Graphics/Draw.h ../Common/Views.h ../Common/ColorTable.h \
   ../Common/VertexArray.h ../Common/SmoothNormals.h ../Numeric/Numeric.h \
   ../Common/AdaptiveViews.h ../Common/GmshMatrix.h Context.h Options.h \
-  ../Plugin/PluginManager.h ../Plugin/Plugin.h ../Common/Options.h \
-  ../Common/Message.h ../Fltk/Solvers.h ../Fltk/GUI.h \
-  ../Fltk/Opengl_Window.h ../Mesh/Mesh.h ../Common/GmshDefines.h \
-  ../Mesh/Vertex.h ../Geo/ExtrudeParams.h ../Fltk/Colorbar_Window.h \
-  ../Common/GmshUI.h ../Fltk/Popup_Button.h \
-  ../Fltk/SpherePosition_Widget.h
+  ../Mesh/BackgroundMesh.h ../Plugin/PluginManager.h ../Plugin/Plugin.h \
+  ../Common/Options.h ../Common/Message.h ../Fltk/Solvers.h ../Fltk/GUI.h \
+  ../Fltk/Opengl_Window.h ../Fltk/Colorbar_Window.h ../Common/GmshUI.h \
+  ../Fltk/Popup_Button.h ../Fltk/SpherePosition_Widget.h
 CommandLine.o: CommandLine.cpp Gmsh.h Message.h ../DataStr/Malloc.h \
   ../DataStr/List.h ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h \
   ../DataStr/List.h ../DataStr/Tree.h GmshUI.h GmshDefines.h \
   GmshVersion.h CommandLine.h ../Numeric/Numeric.h Context.h Options.h \
-  ../Geo/Geo.h Views.h ColorTable.h VertexArray.h SmoothNormals.h \
-  AdaptiveViews.h GmshMatrix.h ../Parser/OpenFile.h \
-  ../Parser/CreateFile.h ../Parser/Parser.h ../Geo/GModel.h \
-  ../Geo/GVertex.h ../Geo/GEntity.h ../Geo/Range.h ../Geo/SPoint3.h \
-  ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../Common/GmshDefines.h \
+  ../Geo/Geo.h ../Common/GmshDefines.h ../Geo/ExtrudeParams.h Views.h \
+  ColorTable.h VertexArray.h SmoothNormals.h AdaptiveViews.h GmshMatrix.h \
+  ../Parser/OpenFile.h ../Parser/CreateFile.h ../Parser/Parser.h \
+  ../Geo/GModel.h ../Geo/GVertex.h ../Geo/GEntity.h ../Geo/Range.h \
+  ../Geo/SPoint3.h ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h \
   ../Geo/MVertex.h ../Geo/SPoint3.h ../Geo/GPoint.h ../Geo/SPoint2.h \
   ../Geo/GEdge.h ../Geo/GEntity.h ../Geo/GVertex.h ../Geo/SVector3.h \
   ../Geo/SPoint3.h ../Geo/SPoint3.h ../Geo/SPoint2.h ../Geo/MElement.h \
diff --git a/Common/Options.cpp b/Common/Options.cpp
index 0899e89604..74b84cbae7 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -1,4 +1,4 @@
-// $Id: Options.cpp,v 1.315 2006-11-22 02:39:17 geuzaine Exp $
+// $Id: Options.cpp,v 1.316 2006-11-25 16:52:41 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -25,6 +25,7 @@
 #include "Draw.h"
 #include "Context.h"
 #include "Options.h"
+#include "BackgroundMesh.h"
 #include "PluginManager.h"
 
 extern Context_T CTX;
diff --git a/Fltk/Callbacks.cpp b/Fltk/Callbacks.cpp
index 50a4be6ef1..ca083b9c1a 100644
--- a/Fltk/Callbacks.cpp
+++ b/Fltk/Callbacks.cpp
@@ -1,4 +1,4 @@
-// $Id: Callbacks.cpp,v 1.476 2006-11-25 02:47:39 geuzaine Exp $
+// $Id: Callbacks.cpp,v 1.477 2006-11-25 16:52:41 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -26,9 +26,10 @@
 #include "Gmsh.h"
 #include "GmshUI.h"
 #include "Geo.h"
-#include "CAD.h"
-#include "ExtractContour.h"
-#include "Mesh.h"
+#include "GeoStringInterface.h"
+#include "GeoExtractContour.h"
+#include "Generator.h"
+#include "SecondOrder.h"
 #include "Draw.h"
 #include "SelectBuffer.h"
 #include "Views.h"
diff --git a/Fltk/GUI.cpp b/Fltk/GUI.cpp
index 5302b39439..50da1a9ec8 100644
--- a/Fltk/GUI.cpp
+++ b/Fltk/GUI.cpp
@@ -1,4 +1,4 @@
-// $Id: GUI.cpp,v 1.562 2006-11-22 02:39:17 geuzaine Exp $
+// $Id: GUI.cpp,v 1.563 2006-11-25 16:52:42 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -67,6 +67,7 @@
 
 #include "Gmsh.h"
 #include "GmshUI.h"
+#include "GmshDefines.h"
 #include "Numeric.h"
 #include "Context.h"
 #include "Options.h"
diff --git a/Fltk/GUI_Extras.cpp b/Fltk/GUI_Extras.cpp
index e8c80b77d1..6487a724f9 100644
--- a/Fltk/GUI_Extras.cpp
+++ b/Fltk/GUI_Extras.cpp
@@ -1,4 +1,4 @@
-// $Id: GUI_Extras.cpp,v 1.26 2006-09-23 15:54:20 geuzaine Exp $
+// $Id: GUI_Extras.cpp,v 1.27 2006-11-25 16:52:43 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -21,7 +21,7 @@
 
 #include "Gmsh.h"
 #include "GmshUI.h"
-#include "Mesh.h"
+#include "GmshDefines.h"
 #include "File_Picker.h"
 #include "Shortcut_Window.h"
 #include "CreateFile.h"
diff --git a/Fltk/Main.cpp b/Fltk/Main.cpp
index a97a9439ac..37d6cb06f3 100644
--- a/Fltk/Main.cpp
+++ b/Fltk/Main.cpp
@@ -1,4 +1,4 @@
-// $Id: Main.cpp,v 1.98 2006-11-14 15:21:02 geuzaine Exp $
+// $Id: Main.cpp,v 1.99 2006-11-25 16:52:43 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -26,8 +26,8 @@
 #include "Gmsh.h"
 #include "GmshUI.h"
 #include "Geo.h"
+#include "Generator.h"
 #include "CreateFile.h"
-#include "Mesh.h"
 #include "Draw.h"
 #include "Context.h"
 #include "Options.h"
diff --git a/Fltk/Makefile b/Fltk/Makefile
index c23e757dca..024fad4ddf 100644
--- a/Fltk/Makefile
+++ b/Fltk/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.112 2006-11-25 02:47:39 geuzaine Exp $
+# $Id: Makefile,v 1.113 2006-11-25 16:52:43 geuzaine Exp $
 #
 # Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 #
@@ -63,15 +63,15 @@ depend:
 	rm -f Makefile.new
 
 # DO NOT DELETE THIS LINE
-Main.o: Main.cpp GUI.h Opengl_Window.h ../Mesh/Mesh.h \
-  ../Common/GmshDefines.h ../DataStr/List.h ../DataStr/Tree.h \
-  ../DataStr/avl.h ../Mesh/Vertex.h ../Geo/ExtrudeParams.h \
-  Colorbar_Window.h ../Common/GmshUI.h ../Common/ColorTable.h \
-  Popup_Button.h SpherePosition_Widget.h ../Common/Gmsh.h \
-  ../Common/Message.h ../DataStr/Malloc.h ../DataStr/Tools.h \
-  ../DataStr/List.h ../DataStr/Tree.h ../Geo/Geo.h ../Parser/CreateFile.h \
-  ../Graphics/Draw.h ../Common/Views.h ../Common/ColorTable.h \
-  ../Common/VertexArray.h ../Common/SmoothNormals.h ../Numeric/Numeric.h \
+Main.o: Main.cpp GUI.h Opengl_Window.h Colorbar_Window.h \
+  ../Common/GmshUI.h ../Common/ColorTable.h Popup_Button.h \
+  SpherePosition_Widget.h ../Common/Gmsh.h ../Common/Message.h \
+  ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
+  ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
+  ../Geo/Geo.h ../Common/GmshDefines.h ../Geo/ExtrudeParams.h \
+  ../Mesh/Generator.h ../Parser/CreateFile.h ../Graphics/Draw.h \
+  ../Common/Views.h ../Common/ColorTable.h ../Common/VertexArray.h \
+  ../Common/SmoothNormals.h ../Numeric/Numeric.h \
   ../Common/AdaptiveViews.h ../Common/GmshMatrix.h ../Common/Context.h \
   ../Common/Options.h ../Parser/Parser.h ../Parser/OpenFile.h \
   ../Common/CommandLine.h Solvers.h ../Plugin/PluginManager.h \
@@ -91,38 +91,36 @@ Message.o: Message.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
   ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
   ../Common/GmshUI.h ../Common/Context.h ../Common/Options.h GUI.h \
-  Opengl_Window.h ../Mesh/Mesh.h ../Common/GmshDefines.h ../Mesh/Vertex.h \
-  ../Geo/ExtrudeParams.h Colorbar_Window.h ../Common/ColorTable.h \
-  Popup_Button.h SpherePosition_Widget.h GUI_Extras.h ../Common/OS.h
+  Opengl_Window.h Colorbar_Window.h ../Common/ColorTable.h Popup_Button.h \
+  SpherePosition_Widget.h GUI_Extras.h ../Common/OS.h
 GUI.o: GUI.cpp ../Common/Gmsh.h ../Common/Message.h ../DataStr/Malloc.h \
   ../DataStr/List.h ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h \
   ../DataStr/List.h ../DataStr/Tree.h ../Common/GmshUI.h \
-  ../Numeric/Numeric.h ../Common/Context.h ../Common/Options.h \
-  ../Graphics/Draw.h ../Common/Views.h ../Common/ColorTable.h \
-  ../Common/VertexArray.h ../Common/SmoothNormals.h \
-  ../Common/AdaptiveViews.h ../Common/GmshMatrix.h GUI.h Opengl_Window.h \
-  ../Mesh/Mesh.h ../Common/GmshDefines.h ../Mesh/Vertex.h \
-  ../Geo/ExtrudeParams.h Colorbar_Window.h Popup_Button.h \
-  SpherePosition_Widget.h Callbacks.h Bitmaps.h Win32Icon.h \
-  ../Parser/OpenFile.h ../Common/CommandLine.h Solvers.h \
+  ../Common/GmshDefines.h ../Numeric/Numeric.h ../Common/Context.h \
+  ../Common/Options.h ../Graphics/Draw.h ../Common/Views.h \
+  ../Common/ColorTable.h ../Common/VertexArray.h \
+  ../Common/SmoothNormals.h ../Common/AdaptiveViews.h \
+  ../Common/GmshMatrix.h GUI.h Opengl_Window.h Colorbar_Window.h \
+  Popup_Button.h SpherePosition_Widget.h Callbacks.h Bitmaps.h \
+  Win32Icon.h ../Parser/OpenFile.h ../Common/CommandLine.h Solvers.h \
   ../Plugin/PluginManager.h ../Plugin/Plugin.h Shortcut_Window.h
 GUI_Extras.o: GUI_Extras.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
   ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
-  ../Common/GmshUI.h ../Mesh/Mesh.h ../Common/GmshDefines.h \
-  ../Mesh/Vertex.h ../Geo/ExtrudeParams.h File_Picker.h Shortcut_Window.h \
-  ../Parser/CreateFile.h ../Common/Options.h ../Common/Context.h \
-  ../Graphics/Draw.h ../Common/Views.h ../Common/ColorTable.h \
-  ../Common/VertexArray.h ../Common/SmoothNormals.h ../Numeric/Numeric.h \
+  ../Common/GmshUI.h ../Common/GmshDefines.h File_Picker.h \
+  Shortcut_Window.h ../Parser/CreateFile.h ../Common/Options.h \
+  ../Common/Context.h ../Graphics/Draw.h ../Common/Views.h \
+  ../Common/ColorTable.h ../Common/VertexArray.h \
+  ../Common/SmoothNormals.h ../Numeric/Numeric.h \
   ../Common/AdaptiveViews.h ../Common/GmshMatrix.h
 Callbacks.o: Callbacks.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
   ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
-  ../Common/GmshUI.h ../Geo/Geo.h ../Geo/CAD.h ../Mesh/Mesh.h \
-  ../Common/GmshDefines.h ../Mesh/Vertex.h ../Geo/ExtrudeParams.h \
-  ../Geo/ExtrudeParams.h ../Geo/ExtractContour.h ../Graphics/Draw.h \
-  ../Common/Views.h ../Common/ColorTable.h ../Common/VertexArray.h \
-  ../Common/SmoothNormals.h ../Numeric/Numeric.h \
+  ../Common/GmshUI.h ../Geo/Geo.h ../Common/GmshDefines.h \
+  ../Geo/ExtrudeParams.h ../Geo/GeoStringInterface.h ../Geo/Geo.h \
+  ../Geo/GeoExtractContour.h ../Mesh/Generator.h ../Mesh/SecondOrder.h \
+  ../Graphics/Draw.h ../Common/Views.h ../Common/ColorTable.h \
+  ../Common/VertexArray.h ../Common/SmoothNormals.h ../Numeric/Numeric.h \
   ../Common/AdaptiveViews.h ../Common/GmshMatrix.h \
   ../Graphics/SelectBuffer.h ../Geo/GVertex.h ../Geo/GEntity.h \
   ../Geo/Range.h ../Geo/SPoint3.h ../Geo/SBoundingBox3d.h \
@@ -147,58 +145,56 @@ Opengl.o: Opengl.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
   ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
   ../Common/GmshUI.h ../Numeric/Numeric.h ../Common/Context.h \
-  ../Geo/Geo.h ../Graphics/Draw.h ../Common/Views.h \
-  ../Common/ColorTable.h ../Common/VertexArray.h \
-  ../Common/SmoothNormals.h ../Common/AdaptiveViews.h \
-  ../Common/GmshMatrix.h ../Graphics/SelectBuffer.h ../Geo/GVertex.h \
-  ../Geo/GEntity.h ../Geo/Range.h ../Geo/SPoint3.h \
-  ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../Common/GmshDefines.h \
-  ../Geo/MVertex.h ../Geo/SPoint3.h ../Geo/GPoint.h ../Geo/SPoint2.h \
-  ../Geo/GEdge.h ../Geo/GEntity.h ../Geo/GVertex.h ../Geo/SVector3.h \
-  ../Geo/SPoint3.h ../Geo/SPoint3.h ../Geo/SPoint2.h ../Geo/MElement.h \
-  ../Geo/MVertex.h ../Geo/MEdge.h ../Geo/MVertex.h ../Geo/SVector3.h \
-  ../Common/Hash.h ../Geo/MFace.h ../Geo/MVertex.h ../Geo/SVector3.h \
+  ../Graphics/Draw.h ../Common/Views.h ../Common/ColorTable.h \
+  ../Common/VertexArray.h ../Common/SmoothNormals.h \
+  ../Common/AdaptiveViews.h ../Common/GmshMatrix.h \
+  ../Graphics/SelectBuffer.h ../Geo/GVertex.h ../Geo/GEntity.h \
+  ../Geo/Range.h ../Geo/SPoint3.h ../Geo/SBoundingBox3d.h \
+  ../Geo/SPoint3.h ../Common/GmshDefines.h ../Geo/MVertex.h \
+  ../Geo/SPoint3.h ../Geo/GPoint.h ../Geo/SPoint2.h ../Geo/GEdge.h \
+  ../Geo/GEntity.h ../Geo/GVertex.h ../Geo/SVector3.h ../Geo/SPoint3.h \
+  ../Geo/SPoint3.h ../Geo/SPoint2.h ../Geo/MElement.h ../Geo/MVertex.h \
+  ../Geo/MEdge.h ../Geo/MVertex.h ../Geo/SVector3.h ../Common/Hash.h \
+  ../Geo/MFace.h ../Geo/MVertex.h ../Geo/SVector3.h \
   ../Geo/ExtrudeParams.h ../Geo/GFace.h ../Geo/GPoint.h ../Geo/GEntity.h \
   ../Geo/GEdgeLoop.h ../Geo/GEdge.h ../Geo/MElement.h ../Geo/SPoint2.h \
   ../Geo/SVector3.h ../Geo/Pair.h ../Geo/ExtrudeParams.h ../Geo/GRegion.h \
   ../Geo/GEntity.h ../Geo/MElement.h ../Geo/ExtrudeParams.h GUI.h \
-  Opengl_Window.h ../Mesh/Mesh.h ../Mesh/Vertex.h Colorbar_Window.h \
-  Popup_Button.h SpherePosition_Widget.h ../Graphics/gl2ps.h
+  Opengl_Window.h Colorbar_Window.h Popup_Button.h \
+  SpherePosition_Widget.h ../Graphics/gl2ps.h
 Opengl_Window.o: Opengl_Window.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
   ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
   ../Numeric/Numeric.h ../Common/GmshUI.h ../Common/Context.h \
-  ../Geo/Geo.h ../Graphics/Draw.h ../Common/Views.h \
-  ../Common/ColorTable.h ../Common/VertexArray.h \
-  ../Common/SmoothNormals.h ../Common/AdaptiveViews.h \
-  ../Common/GmshMatrix.h ../Graphics/SelectBuffer.h ../Geo/GVertex.h \
-  ../Geo/GEntity.h ../Geo/Range.h ../Geo/SPoint3.h \
-  ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../Common/GmshDefines.h \
-  ../Geo/MVertex.h ../Geo/SPoint3.h ../Geo/GPoint.h ../Geo/SPoint2.h \
-  ../Geo/GEdge.h ../Geo/GEntity.h ../Geo/GVertex.h ../Geo/SVector3.h \
-  ../Geo/SPoint3.h ../Geo/SPoint3.h ../Geo/SPoint2.h ../Geo/MElement.h \
-  ../Geo/MVertex.h ../Geo/MEdge.h ../Geo/MVertex.h ../Geo/SVector3.h \
-  ../Common/Hash.h ../Geo/MFace.h ../Geo/MVertex.h ../Geo/SVector3.h \
-  ../Geo/ExtrudeParams.h ../Geo/GFace.h ../Geo/GPoint.h ../Geo/GEntity.h \
-  ../Geo/GEdgeLoop.h ../Geo/GEdge.h ../Geo/MElement.h ../Geo/SPoint2.h \
-  ../Geo/SVector3.h ../Geo/Pair.h ../Geo/ExtrudeParams.h ../Geo/GRegion.h \
-  ../Geo/GEntity.h ../Geo/MElement.h ../Geo/ExtrudeParams.h GUI.h \
-  Opengl_Window.h ../Mesh/Mesh.h ../Mesh/Vertex.h Colorbar_Window.h \
+  ../Geo/Geo.h ../Common/GmshDefines.h ../Geo/ExtrudeParams.h \
+  ../Graphics/Draw.h ../Common/Views.h ../Common/ColorTable.h \
+  ../Common/VertexArray.h ../Common/SmoothNormals.h \
+  ../Common/AdaptiveViews.h ../Common/GmshMatrix.h \
+  ../Graphics/SelectBuffer.h ../Geo/GVertex.h ../Geo/GEntity.h \
+  ../Geo/Range.h ../Geo/SPoint3.h ../Geo/SBoundingBox3d.h \
+  ../Geo/SPoint3.h ../Geo/MVertex.h ../Geo/SPoint3.h ../Geo/GPoint.h \
+  ../Geo/SPoint2.h ../Geo/GEdge.h ../Geo/GEntity.h ../Geo/GVertex.h \
+  ../Geo/SVector3.h ../Geo/SPoint3.h ../Geo/SPoint3.h ../Geo/SPoint2.h \
+  ../Geo/MElement.h ../Geo/MVertex.h ../Geo/MEdge.h ../Geo/MVertex.h \
+  ../Geo/SVector3.h ../Common/Hash.h ../Geo/MFace.h ../Geo/MVertex.h \
+  ../Geo/SVector3.h ../Geo/ExtrudeParams.h ../Geo/GFace.h ../Geo/GPoint.h \
+  ../Geo/GEntity.h ../Geo/GEdgeLoop.h ../Geo/GEdge.h ../Geo/MElement.h \
+  ../Geo/SPoint2.h ../Geo/SVector3.h ../Geo/Pair.h ../Geo/ExtrudeParams.h \
+  ../Geo/GRegion.h ../Geo/GEntity.h ../Geo/MElement.h \
+  ../Geo/ExtrudeParams.h GUI.h Opengl_Window.h Colorbar_Window.h \
   Popup_Button.h SpherePosition_Widget.h
 Colorbar_Window.o: Colorbar_Window.cpp ../Common/Gmsh.h \
   ../Common/Message.h ../DataStr/Malloc.h ../DataStr/List.h \
   ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h \
   ../DataStr/Tree.h ../Common/GmshUI.h GUI.h Opengl_Window.h \
-  ../Mesh/Mesh.h ../Common/GmshDefines.h ../Mesh/Vertex.h \
-  ../Geo/ExtrudeParams.h Colorbar_Window.h ../Common/ColorTable.h \
-  Popup_Button.h SpherePosition_Widget.h ../Common/Context.h
+  Colorbar_Window.h ../Common/ColorTable.h Popup_Button.h \
+  SpherePosition_Widget.h ../Common/Context.h
 Solvers.o: Solvers.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
   ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
   Solvers.h GmshServer.h ../Parser/OpenFile.h ../Common/GmshUI.h GUI.h \
-  Opengl_Window.h ../Mesh/Mesh.h ../Common/GmshDefines.h ../Mesh/Vertex.h \
-  ../Geo/ExtrudeParams.h Colorbar_Window.h ../Common/ColorTable.h \
-  Popup_Button.h SpherePosition_Widget.h ../Graphics/Draw.h \
-  ../Common/Views.h ../Common/ColorTable.h ../Common/VertexArray.h \
+  Opengl_Window.h Colorbar_Window.h ../Common/ColorTable.h Popup_Button.h \
+  SpherePosition_Widget.h ../Graphics/Draw.h ../Common/Views.h \
+  ../Common/ColorTable.h ../Common/VertexArray.h \
   ../Common/SmoothNormals.h ../Numeric/Numeric.h \
   ../Common/AdaptiveViews.h ../Common/GmshMatrix.h ../Common/Context.h
diff --git a/Fltk/Opengl.cpp b/Fltk/Opengl.cpp
index a690878377..6ef55d9092 100644
--- a/Fltk/Opengl.cpp
+++ b/Fltk/Opengl.cpp
@@ -1,4 +1,4 @@
-// $Id: Opengl.cpp,v 1.69 2006-11-01 22:19:26 geuzaine Exp $
+// $Id: Opengl.cpp,v 1.70 2006-11-25 16:52:43 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -23,7 +23,6 @@
 #include "GmshUI.h"
 #include "Numeric.h"
 #include "Context.h"
-#include "Geo.h"
 #include "Draw.h"
 #include "SelectBuffer.h"
 #include "GUI.h"
diff --git a/Fltk/Opengl_Window.h b/Fltk/Opengl_Window.h
index c3e2f63f24..7117e1a40a 100644
--- a/Fltk/Opengl_Window.h
+++ b/Fltk/Opengl_Window.h
@@ -22,7 +22,6 @@
 
 #include <FL/Fl_Gl_Window.H>
 #include <FL/Fl_Box.H>
-#include "Mesh.h"
 
 class MousePosition {
  public:
diff --git a/Fltk/Solvers.cpp b/Fltk/Solvers.cpp
index 6503efabbe..377b3c34ce 100644
--- a/Fltk/Solvers.cpp
+++ b/Fltk/Solvers.cpp
@@ -1,4 +1,4 @@
-// $Id: Solvers.cpp,v 1.52 2006-08-07 14:15:14 geuzaine Exp $
+// $Id: Solvers.cpp,v 1.53 2006-11-25 16:52:43 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -25,7 +25,6 @@
 #include "OpenFile.h"
 #include "GmshUI.h"
 #include "GUI.h"
-#include "Mesh.h"
 #include "Draw.h"
 #include "Context.h"
 
diff --git a/Geo/CAD.cpp b/Geo/CAD.cpp
deleted file mode 100644
index e82d0e2ca3..0000000000
--- a/Geo/CAD.cpp
+++ /dev/null
@@ -1,2429 +0,0 @@
-// $Id: CAD.cpp,v 1.101 2006-11-25 02:47:39 geuzaine Exp $
-//
-// Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-// USA.
-// 
-// Please report all bugs and problems to <gmsh@geuz.org>.
-
-#include "Gmsh.h"
-#include "Numeric.h"
-#include "Geo.h"
-#include "Mesh.h"
-#include "Interpolation.h"
-#include "Create.h"
-#include "CAD.h"
-#include "Context.h"
-
-extern Mesh *THEM;
-extern Context_T CTX;
-
-static List_T *ListOfTransformedPoints = NULL;
-
-// Basic functions
-
-int NEWPOINT(void)
-{
-  return (THEM->MaxPointNum + 1);
-}
-
-int NEWLINE(void)
-{
-  if(CTX.geom.old_newreg)
-    return NEWREG();
-  else
-    return (THEM->MaxLineNum + 1);
-}
-
-int NEWLINELOOP(void)
-{
-  if(CTX.geom.old_newreg)
-    return NEWREG();
-  else
-    return (THEM->MaxLineLoopNum + 1);
-}
-
-int NEWSURFACE(void)
-{
-  if(CTX.geom.old_newreg)
-    return NEWREG();
-  else
-    return (THEM->MaxSurfaceNum + 1);
-}
-
-int NEWSURFACELOOP(void)
-{
-  if(CTX.geom.old_newreg)
-    return NEWREG();
-  else
-    return (THEM->MaxSurfaceLoopNum + 1);
-}
-
-int NEWVOLUME(void)
-{
-  if(CTX.geom.old_newreg)
-    return NEWREG();
-  else
-    return (THEM->MaxVolumeNum + 1);
-}
-
-int NEWPHYSICAL(void)
-{
-  if(CTX.geom.old_newreg)
-    return NEWREG();
-  else
-    return (THEM->MaxPhysicalNum + 1);
-}
-
-int NEWREG(void)
-{
-  return (IMAX(THEM->MaxLineNum,
-               IMAX(THEM->MaxLineLoopNum,
-                    IMAX(THEM->MaxSurfaceNum,
-                         IMAX(THEM->MaxSurfaceLoopNum,
-                              IMAX(THEM->MaxVolumeNum,
-                                   THEM->MaxPhysicalNum)))))
-          + 1);
-}
-
-
-
-
-int compare2Lists(List_T * List1, List_T * List2,
-                  int (*fcmp) (const void *a, const void *b))
-{
-  int i, found;
-
-  if(!List_Nbr(List1) && !List_Nbr(List2))
-    return 0;
-
-  if(!List_Nbr(List1) || !List_Nbr(List2) || 
-     (List_Nbr(List1) != List_Nbr(List2)))
-    return List_Nbr(List1) - List_Nbr(List2);
-  
-  List_T *List1Prime = List_Create(List_Nbr(List1), 1, List1->size);
-  List_T *List2Prime = List_Create(List_Nbr(List2), 1, List2->size);
-  List_Copy(List1, List1Prime);
-  List_Copy(List2, List2Prime);
-  List_Sort(List1Prime, fcmp);
-  List_Sort(List2Prime, fcmp);
-
-  for(i = 0; i < List_Nbr(List1Prime); i++) {
-    found = fcmp(List_Pointer(List1Prime, i), List_Pointer(List2Prime, i));
-    if(found != 0) {
-      List_Delete(List1Prime);
-      List_Delete(List2Prime);
-      return found;
-    }
-  }
-  List_Delete(List1Prime);
-  List_Delete(List2Prime);
-  return 0;
-}
-
-Vertex *FindPoint(int inum)
-{
-  Vertex C, *pc;
-  pc = &C;
-  pc->Num = inum;
-  if(Tree_Query(THEM->Points, &pc)) {
-    return pc;
-  }
-  return NULL;
-}
-
-Vertex *FindVertex(int inum)
-{
-  Vertex C, *pc;
-  pc = &C;
-  pc->Num = inum;
-  if(Tree_Query(THEM->Vertices, &pc)) {
-    return pc;
-  }
-  return NULL;
-}
-
-Curve *FindCurve(int inum)
-{
-  Curve C, *pc;
-  pc = &C;
-  pc->Num = inum;
-  if(Tree_Query(THEM->Curves, &pc)) {
-    return pc;
-  }
-  return NULL;
-}
-
-Surface *FindSurface(int inum)
-{
-  Surface S, *ps;
-  ps = &S;
-  ps->Num = inum;
-  if(Tree_Query(THEM->Surfaces, &ps)) {
-    return ps;
-  }
-  return NULL;
-}
-
-Volume *FindVolume(int inum)
-{
-  Volume V, *pv;
-  pv = &V;
-  pv->Num = inum;
-  if(Tree_Query(THEM->Volumes, &pv)) {
-    return pv;
-  }
-  return NULL;
-}
-
-EdgeLoop *FindEdgeLoop(int inum)
-{
-  EdgeLoop S, *ps;
-  ps = &S;
-  ps->Num = inum;
-  if(Tree_Query(THEM->EdgeLoops, &ps)) {
-    return ps;
-  }
-  return NULL;
-}
-
-SurfaceLoop *FindSurfaceLoop(int inum)
-{
-  SurfaceLoop S, *ps;
-  ps = &S;
-  ps->Num = inum;
-  if(Tree_Query(THEM->SurfaceLoops, &ps)) {
-    return ps;
-  }
-  return NULL;
-}
-
-PhysicalGroup *FindPhysicalGroup(int num, int type)
-{
-  PhysicalGroup P, *pp, **ppp;
-  pp = &P;
-  pp->Num = num;
-  pp->Typ = type;
-  if((ppp = (PhysicalGroup **) List_PQuery(THEM->PhysicalGroups, &pp,
-                                           comparePhysicalGroup))) {
-    return *ppp;
-  }
-  return NULL;
-}
-
-void CopyVertex(Vertex * v, Vertex * vv)
-{
-  vv->lc = v->lc;
-  vv->u = v->u;
-  vv->Pos.X = v->Pos.X;
-  vv->Pos.Y = v->Pos.Y;
-  vv->Pos.Z = v->Pos.Z;
-  vv->Freeze.X = v->Freeze.X;
-  vv->Freeze.Y = v->Freeze.Y;
-  vv->Freeze.Z = v->Freeze.Z;
-}
-
-Vertex *DuplicateVertex(Vertex * v)
-{
-  if(!v) return NULL;
-  Vertex *pv = Create_Vertex(NEWPOINT(), 0, 0, 0, 0, 0);
-  CopyVertex(v, pv);
-  Tree_Insert(THEM->Points, &pv);
-  return pv;
-}
-
-int compareAbsCurve(const void *a, const void *b)
-{
-  Curve **q, **w;
-
-  q = (Curve **) a;
-  w = (Curve **) b;
-  return (abs((*q)->Num) - abs((*w)->Num));
-}
-
-void CopyCurve(Curve * c, Curve * cc)
-{
-  int i, j;
-  cc->Typ = c->Typ;
-  // We should not copy the meshing method : if the meshes are to be
-  // copied, the meshing algorithm will take care of it
-  // (e.g. ExtrudeMesh()).
-  //cc->Method = c->Method; 
-  for(i = 0; i < 4; i++)
-    cc->ipar[i] = c->ipar[i];
-  for(i = 0; i < 4; i++)
-    cc->dpar[i] = c->dpar[i];
-  cc->l = c->l;
-  for(i = 0; i < 4; i++)
-    for(j = 0; j < 4; j++)
-      cc->mat[i][j] = c->mat[i][j];
-  cc->beg = c->beg;
-  cc->end = c->end;
-  cc->ubeg = c->ubeg;
-  cc->uend = c->uend;
-  cc->Control_Points =
-    List_Create(List_Nbr(c->Control_Points), 1, sizeof(Vertex *));
-  List_Copy(c->Control_Points, cc->Control_Points);
-  if(c->Typ == MSH_SEGM_PARAMETRIC){
-    strcpy(cc->functu, c->functu);
-    strcpy(cc->functv, c->functv);
-    strcpy(cc->functw, c->functw);
-  }
-  End_Curve(cc);
-  Tree_Insert(THEM->Curves, &cc);
-}
-
-Curve *DuplicateCurve(Curve * c)
-{
-  Curve *pc;
-  Vertex *v, *newv;
-  pc = Create_Curve(NEWLINE(), 0, 1, NULL, NULL, -1, -1, 0., 1.);
-  CopyCurve(c, pc);
-  for(int i = 0; i < List_Nbr(c->Control_Points); i++) {
-    List_Read(pc->Control_Points, i, &v);
-    newv = DuplicateVertex(v);
-    List_Write(pc->Control_Points, i, &newv);
-  }
-  pc->beg = DuplicateVertex(c->beg);
-  pc->end = DuplicateVertex(c->end);
-  CreateReversedCurve(pc);
-
-  return pc;
-}
-
-void CopySurface(Surface * s, Surface * ss)
-{
-  int i, j;
-  ss->Typ = s->Typ;
-  // We should not copy the meshing method (or the recombination
-  // status): if the meshes are to be copied, the meshing algorithm
-  // will take care of it (e.g. ExtrudeMesh()).
-  //ss->Method = s->Method;
-  //ss->Recombine = s->Recombine;
-  //ss->RecombineAngle = s->RecombineAngle;
-  for(i = 0; i < 4; i++)
-    ss->ipar[i] = s->ipar[i];
-  ss->Nu = s->Nu;
-  ss->Nv = s->Nv;
-  ss->a = s->a;
-  ss->b = s->b;
-  ss->c = s->c;
-  ss->d = s->d;
-  for(i = 0; i < 3; i++)
-    for(j = 0; j < 3; j++)
-      ss->plan[i][j] = s->plan[i][j];
-  for(i = 0; i < 3; i++)
-    for(j = 0; j < 3; j++)
-      ss->invplan[i][j] = s->invplan[i][j];
-  ss->Generatrices =
-    List_Create(List_Nbr(s->Generatrices), 1, sizeof(Curve *));
-  List_Copy(s->Generatrices, ss->Generatrices);
-  if(s->Control_Points) {
-    ss->Control_Points =
-      List_Create(List_Nbr(s->Control_Points), 1, sizeof(Vertex *));
-    List_Copy(s->Control_Points, ss->Control_Points);
-  }
-  End_Surface(ss);
-  Tree_Insert(THEM->Surfaces, &ss);
-}
-
-Surface *DuplicateSurface(Surface * s)
-{
-  Surface *ps;
-  Curve *c, *newc;
-  Vertex *v, *newv;
-  int i;
-
-  ps = Create_Surface(NEWSURFACE(), 0);
-  CopySurface(s, ps);
-  for(i = 0; i < List_Nbr(ps->Generatrices); i++) {
-    List_Read(ps->Generatrices, i, &c);
-    newc = DuplicateCurve(c);
-    List_Write(ps->Generatrices, i, &newc);
-  }
-
-  for(i = 0; i < List_Nbr(ps->Control_Points); i++) {
-    List_Read(ps->Control_Points, i, &v);
-    newv = DuplicateVertex(v);
-    List_Write(ps->Control_Points, i, &newv);
-  }
-
-  return ps;
-}
-
-void CopyShape(int Type, int Num, int *New)
-{
-  Surface *s, *news;
-  Curve *c, *newc;
-  Vertex *v, *newv;
-
-  switch (Type) {
-  case MSH_POINT:
-    if(!(v = FindPoint(Num))) {
-      Msg(GERROR, "Unknown vertex %d", Num);
-      return;
-    }
-    newv = DuplicateVertex(v);
-    *New = newv->Num;
-    break;
-  case MSH_SEGM_LINE:
-  case MSH_SEGM_SPLN:
-  case MSH_SEGM_BSPLN:
-  case MSH_SEGM_BEZIER:
-  case MSH_SEGM_CIRC:
-  case MSH_SEGM_CIRC_INV:
-  case MSH_SEGM_ELLI:
-  case MSH_SEGM_ELLI_INV:
-  case MSH_SEGM_NURBS:
-  case MSH_SEGM_PARAMETRIC:
-    if(!(c = FindCurve(Num))) {
-      Msg(GERROR, "Unknown curve %d", Num);
-      return;
-    }
-    newc = DuplicateCurve(c);
-    *New = newc->Num;
-    break;
-  case MSH_SURF_NURBS:
-  case MSH_SURF_TRIC:
-  case MSH_SURF_REGL:
-  case MSH_SURF_PLAN:
-    if(!(s = FindSurface(Num))) {
-      Msg(GERROR, "Unknown surface %d", Num);
-      return;
-    }
-    news = DuplicateSurface(s);
-    *New = news->Num;
-    break;
-  default:
-    Msg(GERROR, "Impossible to copy entity %d (of type %d)", Num, Type);
-    break;
-  }
-}
-
-void DeletePoint(int ip)
-{
-  Vertex *v = FindPoint(ip);
-  if(!v)
-    return;
-  List_T *Curves = Tree2List(THEM->Curves);
-  for(int i = 0; i < List_Nbr(Curves); i++) {
-    Curve *c;
-    List_Read(Curves, i, &c);
-    for(int j = 0; j < List_Nbr(c->Control_Points); j++) {
-      if(!compareVertex(List_Pointer(c->Control_Points, j), &v)){
-	List_Delete(Curves);
-        return;
-      }
-    }
-  }
-  List_Delete(Curves);
-  if(v->Num == THEM->MaxPointNum)
-    THEM->MaxPointNum--;
-  Tree_Suppress(THEM->Points, &v);
-  Free_Vertex(&v, NULL);
-}
-
-void DeleteCurve(int ip)
-{
-  Curve *c = FindCurve(ip);
-  if(!c)
-    return;
-  List_T *Surfs = Tree2List(THEM->Surfaces);
-  for(int i = 0; i < List_Nbr(Surfs); i++) {
-    Surface *s;
-    List_Read(Surfs, i, &s);
-    for(int j = 0; j < List_Nbr(s->Generatrices); j++) {
-      if(!compareAbsCurve(List_Pointer(s->Generatrices, j), &c)){
-	List_Delete(Surfs);
-        return;
-      }
-    }
-  }
-  List_Delete(Surfs);
-  if(c->Num == THEM->MaxLineNum)
-    THEM->MaxLineNum--;
-  Tree_Suppress(THEM->Curves, &c);
-  Free_Curve(&c, NULL);
-}
-
-void DeleteSurface(int is)
-{
-  Surface *s = FindSurface(is);
-  if(!s)
-    return;
-  List_T *Vols = Tree2List(THEM->Volumes);
-  for(int i = 0; i < List_Nbr(Vols); i++) {
-    Volume *v;
-    List_Read(Vols, i, &v);
-    for(int j = 0; j < List_Nbr(v->Surfaces); j++) {
-      if(!compareSurface(List_Pointer(v->Surfaces, j), &s)){
-	List_Delete(Vols);
-        return;
-      }
-    }
-  }
-  List_Delete(Vols);
-  if(s->Num == THEM->MaxSurfaceNum)
-    THEM->MaxSurfaceNum--;
-  Tree_Suppress(THEM->Surfaces, &s);
-  Free_Surface(&s, NULL);
-}
-
-void DeleteVolume(int iv)
-{
-  Volume *v = FindVolume(iv);
-  if(!v)
-    return;
-  if(v->Num == THEM->MaxVolumeNum)
-    THEM->MaxVolumeNum--;
-  Tree_Suppress(THEM->Volumes, &v);
-  Free_Volume(&v, NULL);
-}
-
-void DeleteShape(int Type, int Num)
-{
-  switch (Type) {
-  case MSH_POINT:
-    DeletePoint(Num);
-    break;
-  case MSH_SEGM_LINE:
-  case MSH_SEGM_SPLN:
-  case MSH_SEGM_BSPLN:
-  case MSH_SEGM_BEZIER:
-  case MSH_SEGM_CIRC:
-  case MSH_SEGM_CIRC_INV:
-  case MSH_SEGM_ELLI:
-  case MSH_SEGM_ELLI_INV:
-  case MSH_SEGM_NURBS:
-  case MSH_SEGM_PARAMETRIC:
-    DeleteCurve(Num);
-    DeleteCurve(-Num);
-    break;
-  case MSH_SURF_NURBS:
-  case MSH_SURF_TRIC:
-  case MSH_SURF_REGL:
-  case MSH_SURF_PLAN:
-    DeleteSurface(Num);
-    break;
-  case MSH_VOLUME:
-    DeleteVolume(Num);
-    break;
-  default:
-    Msg(GERROR, "Impossible to delete entity %d (of type %d)", Num, Type);
-    break;
-  }
-}
-
-void ColorCurve(int ip, unsigned int col)
-{
-  Curve *c = FindCurve(ip);
-  if(!c)
-    return;
-  c->Color.type = 1;
-  c->Color.mesh = c->Color.geom = col;
-}
-
-void ColorSurface(int is, unsigned int col)
-{
-  Surface *s = FindSurface(is);
-  if(!s)
-    return;
-  s->Color.type = 1;
-  s->Color.mesh = s->Color.geom = col;
-}
-
-void ColorVolume(int iv, unsigned int col)
-{
-  Volume *v = FindVolume(iv);
-  if(!v)
-    return;
-  v->Color.type = 1;
-  v->Color.mesh = v->Color.geom = col;
-}
-
-void ColorShape(int Type, int Num, unsigned int Color)
-{
-  switch (Type) {
-  case MSH_POINT:
-    break;
-  case MSH_SEGM_LINE:
-  case MSH_SEGM_SPLN:
-  case MSH_SEGM_BSPLN:
-  case MSH_SEGM_BEZIER:
-  case MSH_SEGM_CIRC:
-  case MSH_SEGM_CIRC_INV:
-  case MSH_SEGM_ELLI:
-  case MSH_SEGM_ELLI_INV:
-  case MSH_SEGM_NURBS:
-  case MSH_SEGM_PARAMETRIC:
-  case MSH_SEGM_DISCRETE:
-    ColorCurve(Num, Color);
-    break;
-  case MSH_SURF_NURBS:
-  case MSH_SURF_TRIC:
-  case MSH_SURF_REGL:
-  case MSH_SURF_PLAN:
-  case MSH_SURF_DISCRETE:
-    ColorSurface(Num, Color);
-    break;
-  case MSH_VOLUME:
-  case MSH_VOLUME_DISCRETE:
-    ColorVolume(Num, Color);
-    break;
-  default:
-    break;
-  }
-}
-
-void VisibilityShape(int Type, int Num, int Mode)
-{
-  Vertex *v;
-  Curve *c;
-  Surface *s;
-  Volume *V;
-
-  switch (Type) {
-  case MSH_POINT:
-    if((v = FindPoint(Num)))
-      v->Visible = Mode;
-    else
-      Msg(WARNING, "Unknown point %d (use '*' to hide/show all points)", Num);
-    break;
-  case MSH_SEGM_LINE:
-  case MSH_SEGM_SPLN:
-  case MSH_SEGM_BSPLN:
-  case MSH_SEGM_BEZIER:
-  case MSH_SEGM_CIRC:
-  case MSH_SEGM_CIRC_INV:
-  case MSH_SEGM_ELLI:
-  case MSH_SEGM_ELLI_INV:
-  case MSH_SEGM_NURBS:
-  case MSH_SEGM_PARAMETRIC:
-  case MSH_SEGM_DISCRETE:
-    if((c = FindCurve(Num)))
-      c->Visible = Mode;
-    else
-      Msg(WARNING, "Unknown line %d (use '*' to hide/show all lines)", Num);
-    break;
-  case MSH_SURF_NURBS:
-  case MSH_SURF_TRIC:
-  case MSH_SURF_REGL:
-  case MSH_SURF_PLAN:
-  case MSH_SURF_DISCRETE:
-    if((s = FindSurface(Num)))
-      s->Visible = Mode;
-    else
-      Msg(WARNING, "Unknown surface %d (use '*' to hide/show all surfaces)", Num);
-    break;
-  case MSH_VOLUME:
-  case MSH_VOLUME_DISCRETE:
-    if((V = FindVolume(Num)))
-      V->Visible = Mode;
-    else
-      Msg(WARNING, "Unknown volume %d (use '*' to hide/show all volumes)", Num);
-    break;
-  default:
-    break;
-  }
-}
-
-static int vmode;
-static void vis_nod(void *a, void *b){ (*(Vertex **) a)->Visible = vmode; }
-static void vis_cur(void *a, void *b){ (*(Curve **) a)->Visible = vmode; }
-static void vis_sur(void *a, void *b){ (*(Surface **) a)->Visible = vmode; }
-static void vis_vol(void *a, void *b){ (*(Volume **) a)->Visible = vmode; }
-
-void VisibilityShape(char *str, int Type, int Mode)
-{
-  vmode = Mode;
-
-  if(!strcmp(str, "all") || !strcmp(str, "*")) {
-    switch (Type) {
-    case 0: Tree_Action(THEM->Points, vis_nod); break;
-    case 1: Tree_Action(THEM->Curves, vis_cur); break;
-    case 2: Tree_Action(THEM->Surfaces, vis_sur); break;
-    case 3: Tree_Action(THEM->Volumes, vis_vol); break;
-    }
-  }
-  else {
-    VisibilityShape(Type, atoi(str), Mode);
-  }
-}
-
-Curve *CreateReversedCurve(Curve * c)
-{
-  Curve *newc;
-  Vertex *e1, *e2, *e3, *e4;
-  int i;
-  newc = Create_Curve(-c->Num, c->Typ, 1, NULL, NULL, -1, -1, 0., 1.);
-
-  if(List_Nbr(c->Control_Points)){
-    newc->Control_Points =
-      List_Create(List_Nbr(c->Control_Points), 1, sizeof(Vertex *));
-    if(c->Typ == MSH_SEGM_ELLI || c->Typ == MSH_SEGM_ELLI_INV) {
-      List_Read(c->Control_Points, 0, &e1);
-      List_Read(c->Control_Points, 1, &e2);
-      List_Read(c->Control_Points, 2, &e3);
-      List_Read(c->Control_Points, 3, &e4);
-      List_Add(newc->Control_Points, &e4);
-      List_Add(newc->Control_Points, &e2);
-      List_Add(newc->Control_Points, &e3);
-      List_Add(newc->Control_Points, &e1);
-    }
-    else
-      List_Invert(c->Control_Points, newc->Control_Points);
-  }
-
-  if(c->Typ == MSH_SEGM_NURBS && c->k) {
-    newc->k =
-      (float *)malloc((c->degre + List_Nbr(c->Control_Points) + 1) *
-                      sizeof(float));
-    for(i = 0; i < c->degre + List_Nbr(c->Control_Points) + 1; i++)
-      newc->k[c->degre + List_Nbr(c->Control_Points) - i] = c->k[i];
-  }
-
-  if(c->Typ == MSH_SEGM_CIRC)
-    newc->Typ = MSH_SEGM_CIRC_INV;
-  if(c->Typ == MSH_SEGM_CIRC_INV)
-    newc->Typ = MSH_SEGM_CIRC;
-  if(c->Typ == MSH_SEGM_ELLI)
-    newc->Typ = MSH_SEGM_ELLI_INV;
-  if(c->Typ == MSH_SEGM_ELLI_INV)
-    newc->Typ = MSH_SEGM_ELLI;
-  newc->Method = c->Method;
-  newc->degre = c->degre;
-  newc->beg = c->end;
-  newc->end = c->beg;
-  newc->ubeg = 1. - c->uend;
-  newc->uend = 1. - c->ubeg;
-  End_Curve(newc);
-
-  Curve **pc;
-
-  if((pc = (Curve **) Tree_PQuery(THEM->Curves, &newc))) {
-    Free_Curve(&newc, NULL);
-    return *pc;
-  }
-  else{
-    Tree_Add(THEM->Curves, &newc);
-    return newc;
-  }
-}
-
-void ModifyLcPoint(int ip, double lc)
-{
-  Vertex *v = FindPoint(ip);
-  if(v)
-    v->lc = lc;
-}
-
-int recognize_seg(int typ, List_T * liste, int *seg)
-{
-  int i, beg, end;
-  Curve *pc;
-
-  List_T *temp = Tree2List(THEM->Curves);
-  List_Read(liste, 0, &beg);
-  List_Read(liste, List_Nbr(liste) - 1, &end);
-  for(i = 0; i < List_Nbr(temp); i++) {
-    List_Read(temp, i, &pc);
-    if(pc->Typ == typ && pc->beg->Num == beg && pc->end->Num == end) {
-      List_Delete(temp);
-      *seg = pc->Num;
-      return 1;
-    }
-  }
-  List_Delete(temp);
-  return 0;
-}
-
-int recognize_loop(List_T * liste, int *loop)
-{
-  int i, res;
-  EdgeLoop *pe;
-
-  res = 0;
-  *loop = 0;
-  List_T *temp = Tree2List(THEM->EdgeLoops);
-  for(i = 0; i < List_Nbr(temp); i++) {
-    List_Read(temp, i, &pe);
-    if(!compare2Lists(pe->Curves, liste, fcmp_absint)) {
-      res = 1;
-      *loop = pe->Num;
-      break;
-    }
-  }
-  List_Delete(temp);
-  return res;
-}
-
-int recognize_surfloop(List_T * liste, int *loop)
-{
-  int i, res;
-  EdgeLoop *pe;
-
-  res = 0;
-  *loop = 0;
-  List_T *temp = Tree2List(THEM->SurfaceLoops);
-  for(i = 0; i < List_Nbr(temp); i++) {
-    List_Read(temp, i, &pe);
-    if(!compare2Lists(pe->Curves, liste, fcmp_absint)) {
-      res = 1;
-      *loop = pe->Num;
-      break;
-    }
-  }
-  List_Delete(temp);
-  return res;
-}
-
-// Linear applications
-
-void SetTranslationMatrix(double matrix[4][4], double T[3])
-{
-  int i, j;
-
-  for(i = 0; i < 4; i++) {
-    for(j = 0; j < 4; j++) {
-      matrix[i][j] = (i == j) ? 1.0 : 0.0;
-    }
-  }
-  for(i = 0; i < 3; i++)
-    matrix[i][3] = T[i];
-}
-
-void SetSymmetryMatrix(double matrix[4][4], double A, double B, double C,
-                       double D)
-{
-  double F = -2.0 / (A * A + B * B + C * C);
-  matrix[0][0] = 1. + A * A * F;
-  matrix[0][1] = A * B * F;
-  matrix[0][2] = A * C * F;
-  matrix[0][3] = A * D * F;
-  matrix[1][0] = A * B * F;
-  matrix[1][1] = 1. + B * B * F;
-  matrix[1][2] = B * C * F;
-  matrix[1][3] = B * D * F;
-  matrix[2][0] = A * C * F;
-  matrix[2][1] = B * C * F;
-  matrix[2][2] = 1. + C * C * F;
-  matrix[2][3] = C * D * F;
-  matrix[3][0] = B * C * F;
-  matrix[3][1] = 0.0;
-  matrix[3][2] = 0.0;
-  matrix[3][3] = 1.0;
-}
-
-void SetDilatationMatrix(double matrix[4][4], double T[3], double A)
-{
-  matrix[0][0] = A;
-  matrix[0][1] = 0.0;
-  matrix[0][2] = 0.0;
-  matrix[0][3] = T[0] * (1.0 - A);
-  matrix[1][0] = 0.0;
-  matrix[1][1] = A;
-  matrix[1][2] = 0.0;
-  matrix[1][3] = T[1] * (1.0 - A);
-  matrix[2][0] = 0.0;
-  matrix[2][1] = 0.0;
-  matrix[2][2] = A;
-  matrix[2][3] = T[2] * (1.0 - A);
-  matrix[3][0] = 0.0;
-  matrix[3][1] = 0.0;
-  matrix[3][2] = 0.0;
-  matrix[3][3] = 1.0;
-}
-
-static void GramSchmidt(double v1[3], double v2[3], double v3[3])
-{
-  double tmp[3];
-  norme(v1);
-  prodve(v3, v1, tmp);
-  norme(tmp);
-  v2[0] = tmp[0];
-  v2[1] = tmp[1];
-  v2[2] = tmp[2];
-  prodve(v1, v2, v3);
-  norme(v3);
-}
-
-void SetRotationMatrix(double matrix[4][4], double Axe[3], double alpha)
-{
-  double t1[3], t2[3];
-  if(Axe[0] != 0.0) {
-    t1[0] = 0.0;
-    t1[1] = 1.0;
-    t1[2] = 0.0;
-    t2[0] = 0.0;
-    t2[1] = 0.0;
-    t2[2] = 1.0;
-  }
-  else if(Axe[1] != 0.0) {
-    t1[0] = 1.0;
-    t1[1] = 0.0;
-    t1[2] = 0.0;
-    t2[0] = 0.0;
-    t2[1] = 0.0;
-    t2[2] = 1.0;
-  }
-  else {
-    t1[0] = 1.0;
-    t1[1] = 0.0;
-    t1[2] = 0.0;
-    t2[0] = 0.0;
-    t2[1] = 1.0;
-    t2[2] = 0.0;
-  }
-  GramSchmidt(Axe, t1, t2);
-  double rot[3][3], plan[3][3], invplan[3][3];
-  plan[0][0] = Axe[0];
-  plan[0][1] = Axe[1];
-  plan[0][2] = Axe[2];
-  plan[1][0] = t1[0];
-  plan[1][1] = t1[1];
-  plan[1][2] = t1[2];
-  plan[2][0] = t2[0];
-  plan[2][1] = t2[1];
-  plan[2][2] = t2[2];
-  rot[2][2] = cos(alpha);
-  rot[2][1] = sin(alpha);
-  rot[2][0] = 0.;
-  rot[1][2] = -sin(alpha);
-  rot[1][1] = cos(alpha);
-  rot[1][0] = 0.;
-  rot[0][2] = 0.;
-  rot[0][1] = 0.;
-  rot[0][0] = 1.;
-  int i, j, k;
-  for(i = 0; i < 3; i++)
-    for(j = 0; j < 3; j++)
-      invplan[i][j] = plan[j][i];
-  double interm[3][3];
-  for(i = 0; i < 3; i++)
-    for(j = 0; j < 3; j++) {
-      interm[i][j] = 0.0;
-      for(k = 0; k < 3; k++)
-        interm[i][j] += invplan[i][k] * rot[k][j];
-    }
-  for(i = 0; i < 4; i++)
-    for(j = 0; j < 4; j++)
-      matrix[i][j] = 0.0;
-  for(i = 0; i < 3; i++)
-    for(j = 0; j < 3; j++) {
-      for(k = 0; k < 3; k++)
-        matrix[i][j] += interm[i][k] * plan[k][j];
-    }
-  matrix[3][3] = 1.0;
-}
-
-static void vecmat4x4(double mat[4][4], double vec[4], double res[4])
-{
-  int i, j;
-  for(i = 0; i < 4; i++) {
-    res[i] = 0.0;
-    for(j = 0; j < 4; j++) {
-      res[i] += mat[i][j] * vec[j];
-    }
-  }
-}
-
-void printCurve(Curve * c)
-{
-  Vertex *v;
-  int N = List_Nbr(c->Control_Points);
-  Msg(DEBUG, "Curve %d %d cp (%d->%d)", c->Num, N, c->beg->Num, c->end->Num);
-  for(int i = 0; i < N; i++) {
-    List_Read(c->Control_Points, i, &v);
-    Msg(DEBUG, "Vertex %d (%g,%g,%g,%g)", v->Num, v->Pos.X, v->Pos.Y,
-        v->Pos.Z, v->lc);
-  }
-}
-
-void printSurface(Surface * s)
-{
-  Curve *c;
-  int N = List_Nbr(s->Generatrices);
-
-  Msg(DEBUG, "Surface %d, %d generatrices", s->Num, N);
-  for(int i = 0; i < N; i++) {
-    List_Read(s->Generatrices, i, &c);
-    printCurve(c);
-  }
-}
-
-void ApplyTransformationToPoint(double matrix[4][4], Vertex * v,
-				bool end_curve_surface=false)
-{
-  double pos[4], vec[4];
-
-  if(!ListOfTransformedPoints)
-    ListOfTransformedPoints = List_Create(50, 50, sizeof(int));
-
-  if(!List_Search(ListOfTransformedPoints, &v->Num, fcmp_absint)) {
-    List_Add(ListOfTransformedPoints, &v->Num);
-  }
-  else
-    return;
-
-  vec[0] = v->Pos.X;
-  vec[1] = v->Pos.Y;
-  vec[2] = v->Pos.Z;
-  vec[3] = v->w;
-  vecmat4x4(matrix, vec, pos);
-  v->Pos.X = pos[0];
-  v->Pos.Y = pos[1];
-  v->Pos.Z = pos[2];
-  v->w = pos[3];
-
-  // Warning: in theory we should always redo these checks if
-  // end_curve_surface is true; but in practice this is so slow for
-  // big models that we need to provide a way to bypass it (which is
-  // OK if the guy who builds the geometry knowns what he's
-  // doing). Instead of adding one more option, let's just bypass all
-  // the checks if auto_coherence==0...
-  if(CTX.geom.auto_coherence && end_curve_surface){
-    List_T *All = Tree2List(THEM->Curves);
-    for(int i = 0; i < List_Nbr(All); i++) {
-      Curve *c;
-      List_Read(All, i, &c);
-      for(int j = 0; j < List_Nbr(c->Control_Points); j++) {
-	Vertex *pv = *(Vertex **) List_Pointer(c->Control_Points, j);
-	if(pv->Num == v->Num){
-	  End_Curve(c);
-	  break;
-	}
-      }
-    }
-    List_Delete(All);
-    All = Tree2List(THEM->Surfaces);
-    for(int i = 0; i < List_Nbr(All); i++) {
-      Surface *s;
-      List_Read(All, i, &s);
-      for(int j = 0; j < List_Nbr(s->Control_Points); j++) {
-	Vertex *pv = *(Vertex **) List_Pointer(s->Control_Points, j);
-	if(pv->Num == v->Num){
-	  End_Surface(s);
-	  break;
-	}
-      }
-    }
-    List_Delete(All);
-  }
-}
-
-void ApplyTransformationToCurve(double matrix[4][4], Curve * c)
-{
-  Vertex *v;
-
-  if(!c->beg || !c->end){
-    Msg(GERROR, "Cannot transform curve with no begin/end points");
-    return;
-  }
-
-  ApplyTransformationToPoint(matrix, c->beg);
-  ApplyTransformationToPoint(matrix, c->end);
-
-  for(int i = 0; i < List_Nbr(c->Control_Points); i++) {
-    List_Read(c->Control_Points, i, &v);
-    ApplyTransformationToPoint(matrix, v);
-  }
-  End_Curve(c);
-}
-
-void ApplyTransformationToSurface(double matrix[4][4], Surface * s)
-{
-  Curve *c;
-  Vertex *v;
-  int i;
-
-  for(i = 0; i < List_Nbr(s->Generatrices); i++) {
-    List_Read(s->Generatrices, i, &c);
-    // FIXME: this fixes benchmarks/bug/transfo_neg_curves.geo, but is
-    // it the correct fix?
-    //ApplyTransformationToCurve(matrix, c);
-    Curve *cc = FindCurve(abs(c->Num));
-    ApplyTransformationToCurve(matrix, cc);
-  }
-  for(i = 0; i < List_Nbr(s->Control_Points); i++) {
-    List_Read(s->Control_Points, i, &v);
-    ApplyTransformationToPoint(matrix, v);
-  }
-  End_Surface(s);
-}
-
-void ApplicationOnShapes(double matrix[4][4], List_T * ListShapes)
-{
-  int i;
-  Shape O;
-  Vertex *v;
-  Curve *c;
-  Surface *s;
-
-  List_Reset(ListOfTransformedPoints);
-
-  for(i = 0; i < List_Nbr(ListShapes); i++) {
-    List_Read(ListShapes, i, &O);
-    switch (O.Type) {
-    case MSH_POINT:
-      v = FindPoint(O.Num);
-      if(v)
-        ApplyTransformationToPoint(matrix, v, true);
-      else
-        Msg(GERROR, "Unknown point %d", O.Num);
-      break;
-    case MSH_SEGM_LINE:
-    case MSH_SEGM_SPLN:
-    case MSH_SEGM_BSPLN:
-    case MSH_SEGM_BEZIER:
-    case MSH_SEGM_CIRC:
-    case MSH_SEGM_CIRC_INV:
-    case MSH_SEGM_ELLI:
-    case MSH_SEGM_ELLI_INV:
-    case MSH_SEGM_NURBS:
-    case MSH_SEGM_PARAMETRIC:
-      c = FindCurve(O.Num);
-      if(c)
-        ApplyTransformationToCurve(matrix, c);
-      else
-        Msg(GERROR, "Unknown curve %d", O.Num);
-      break;
-    case MSH_SURF_NURBS:
-    case MSH_SURF_REGL:
-    case MSH_SURF_TRIC:
-    case MSH_SURF_PLAN:
-      s = FindSurface(O.Num);
-      if(s)
-        ApplyTransformationToSurface(matrix, s);
-      else
-        Msg(GERROR, "Unknown surface %d", O.Num);
-      break;
-    default:
-      Msg(GERROR, "Impossible to transform entity %d (of type %d)", O.Num,
-          O.Type);
-      break;
-    }
-  }
-
-  List_Reset(ListOfTransformedPoints);
-}
-
-void TranslateShapes(double X, double Y, double Z,
-                     List_T * ListShapes, int final)
-{
-  double T[3], matrix[4][4];
-
-  T[0] = X;
-  T[1] = Y;
-  T[2] = Z;
-  SetTranslationMatrix(matrix, T);
-  ApplicationOnShapes(matrix, ListShapes);
-
-  if(CTX.geom.auto_coherence && final)
-    ReplaceAllDuplicates();
-}
-
-void DilatShapes(double X, double Y, double Z, double A,
-                 List_T * ListShapes, int final)
-{
-  double T[3], matrix[4][4];
-
-  T[0] = X;
-  T[1] = Y;
-  T[2] = Z;
-  SetDilatationMatrix(matrix, T, A);
-  ApplicationOnShapes(matrix, ListShapes);
-
-  if(CTX.geom.auto_coherence && final)
-    ReplaceAllDuplicates();
-}
-
-void RotateShapes(double Ax, double Ay, double Az,
-                  double Px, double Py, double Pz,
-                  double alpha, List_T * ListShapes, int final)
-{
-  double A[3], T[3], matrix[4][4];
-
-  T[0] = -Px;
-  T[1] = -Py;
-  T[2] = -Pz;
-  SetTranslationMatrix(matrix, T);
-  ApplicationOnShapes(matrix, ListShapes);
-
-  A[0] = Ax;
-  A[1] = Ay;
-  A[2] = Az;
-  SetRotationMatrix(matrix, A, alpha);
-  ApplicationOnShapes(matrix, ListShapes);
-
-  T[0] = Px;
-  T[1] = Py;
-  T[2] = Pz;
-  SetTranslationMatrix(matrix, T);
-  ApplicationOnShapes(matrix, ListShapes);
-
-  if(CTX.geom.auto_coherence && final)
-    ReplaceAllDuplicates();
-}
-
-void SymmetryShapes(double A, double B, double C,
-                    double D, List_T * ListShapes, int final)
-{
-  double matrix[4][4];
-
-  SetSymmetryMatrix(matrix, A, B, C, D);
-  ApplicationOnShapes(matrix, ListShapes);
-
-  if(CTX.geom.auto_coherence && final)
-    ReplaceAllDuplicates();
-}
-
-
-// Extrusion routines
-
-void ProtudeXYZ(double &x, double &y, double &z, ExtrudeParams * e)
-{
-  double matrix[4][4];
-  double T[3];
-  Vertex v(x, y, z);
-
-  T[0] = -e->geo.pt[0];
-  T[1] = -e->geo.pt[1];
-  T[2] = -e->geo.pt[2];
-  SetTranslationMatrix(matrix, T);
-  List_Reset(ListOfTransformedPoints);
-  ApplyTransformationToPoint(matrix, &v);
-
-  SetRotationMatrix(matrix, e->geo.axe, e->geo.angle);
-  List_Reset(ListOfTransformedPoints);
-  ApplyTransformationToPoint(matrix, &v);
-
-  T[0] = -T[0];
-  T[1] = -T[1];
-  T[2] = -T[2];
-  SetTranslationMatrix(matrix, T);
-  List_Reset(ListOfTransformedPoints);
-  ApplyTransformationToPoint(matrix, &v);
-
-  x = v.Pos.X;
-  y = v.Pos.Y;
-  z = v.Pos.Z;
-
-  List_Reset(ListOfTransformedPoints);
-}
-
-int Extrude_ProtudePoint(int type, int ip,
-			 double T0, double T1, double T2,
-			 double A0, double A1, double A2,
-			 double X0, double X1, double X2, double alpha,
-			 Curve ** pc, Curve ** prc, int final, 
-			 ExtrudeParams * e)
-{
-  double matrix[4][4], T[3], Ax[3], d;
-  Vertex V, *pv, *newp, *chapeau;
-  Curve *c;
-  int i;
-
-  pv = &V;
-  pv->Num = ip;
-  *pc = *prc = NULL;
-  if(!Tree_Query(THEM->Points, &pv))
-    return 0;
-
-  Msg(DEBUG, "Extrude Point %d", ip);
-
-  chapeau = DuplicateVertex(pv);
-
-  switch (type) {
-
-  case TRANSLATE:
-    T[0] = T0;
-    T[1] = T1;
-    T[2] = T2;
-    SetTranslationMatrix(matrix, T);
-    List_Reset(ListOfTransformedPoints);
-    ApplyTransformationToPoint(matrix, chapeau);
-
-    if(!comparePosition(&pv, &chapeau))
-      return pv->Num;
-    c = Create_Curve(NEWLINE(), MSH_SEGM_LINE, 1, NULL, NULL, -1, -1, 0., 1.);
-    c->Control_Points = List_Create(2, 1, sizeof(Vertex *));
-    c->Extrude = new ExtrudeParams;
-    c->Extrude->fill(type, T0, T1, T2, A0, A1, A2, X0, X1, X2, alpha);
-    c->Extrude->useZonLayer(final);
-    if(e)
-      c->Extrude->mesh = e->mesh;
-
-    List_Add(c->Control_Points, &pv);
-    List_Add(c->Control_Points, &chapeau);
-    c->beg = pv;
-    c->end = chapeau;
-    break;
-
-  case ROTATE:
-    T[0] = -X0;
-    T[1] = -X1;
-    T[2] = -X2;
-    SetTranslationMatrix(matrix, T);
-    List_Reset(ListOfTransformedPoints);
-    ApplyTransformationToPoint(matrix, chapeau);
-
-    Ax[0] = A0;
-    Ax[1] = A1;
-    Ax[2] = A2;
-    SetRotationMatrix(matrix, Ax, alpha);
-    List_Reset(ListOfTransformedPoints);
-    ApplyTransformationToPoint(matrix, chapeau);
-
-    T[0] = X0;
-    T[1] = X1;
-    T[2] = X2;
-    SetTranslationMatrix(matrix, T);
-    List_Reset(ListOfTransformedPoints);
-    ApplyTransformationToPoint(matrix, chapeau);
-
-    if(!comparePosition(&pv, &chapeau))
-      return pv->Num;
-    c = Create_Curve(NEWLINE(), MSH_SEGM_CIRC, 1, NULL, NULL, -1, -1, 0., 1.);
-    c->Control_Points = List_Create(3, 1, sizeof(Vertex *));
-    c->Extrude = new ExtrudeParams;
-    c->Extrude->fill(type, T0, T1, T2, A0, A1, A2, X0, X1, X2, alpha);
-    if(e)
-      c->Extrude->mesh = e->mesh;
-    List_Add(c->Control_Points, &pv);
-    // compute circle center
-    newp = DuplicateVertex(pv);
-    Ax[0] = A0;
-    Ax[1] = A1;
-    Ax[2] = A2;
-    norme(Ax);
-    T[0] = pv->Pos.X - X0;
-    T[1] = pv->Pos.Y - X1;
-    T[2] = pv->Pos.Z - X2;
-    prosca(T, Ax, &d);
-    newp->Pos.X = X0 + d * Ax[0];
-    newp->Pos.Y = X1 + d * Ax[1]; 
-    newp->Pos.Z = X2 + d * Ax[2]; 
-    List_Add(c->Control_Points, &newp);
-    List_Add(c->Control_Points, &chapeau);
-    c->beg = pv;
-    c->end = chapeau;
-    break;
-
-  case TRANSLATE_ROTATE:
-    d = CTX.geom.extrude_spline_points;
-    d = d ? d : 1;
-    c = Create_Curve(NEWLINE(), MSH_SEGM_SPLN, 1, NULL, NULL, -1, -1, 0., 1.);
-    c->Control_Points =
-      List_Create(CTX.geom.extrude_spline_points + 1, 1, sizeof(Vertex *));
-    c->Extrude = new ExtrudeParams;
-    c->Extrude->fill(type, T0, T1, T2, A0, A1, A2, X0, X1, X2, alpha);
-    if(e)
-      c->Extrude->mesh = e->mesh;
-    List_Add(c->Control_Points, &pv);
-    c->beg = pv;
-    for(i = 0; i < CTX.geom.extrude_spline_points; i++) {
-      if(i)
-        chapeau = DuplicateVertex(chapeau);
-
-      T[0] = -X0;
-      T[1] = -X1;
-      T[2] = -X2;
-      SetTranslationMatrix(matrix, T);
-      List_Reset(ListOfTransformedPoints);
-      ApplyTransformationToPoint(matrix, chapeau);
-
-      Ax[0] = A0;
-      Ax[1] = A1;
-      Ax[2] = A2;
-      SetRotationMatrix(matrix, Ax, alpha / d);
-      List_Reset(ListOfTransformedPoints);
-      ApplyTransformationToPoint(matrix, chapeau);
-
-      T[0] = X0;
-      T[1] = X1;
-      T[2] = X2;
-      SetTranslationMatrix(matrix, T);
-      List_Reset(ListOfTransformedPoints);
-      ApplyTransformationToPoint(matrix, chapeau);
-
-      T[0] = T0 / d;
-      T[1] = T1 / d;
-      T[2] = T2 / d;
-      SetTranslationMatrix(matrix, T);
-      List_Reset(ListOfTransformedPoints);
-      ApplyTransformationToPoint(matrix, chapeau);
-
-      List_Add(c->Control_Points, &chapeau);
-    }
-    c->end = chapeau;
-    break;
-
-  default:
-    Msg(GERROR, "Unknown extrusion type");
-    return pv->Num;
-  }
-
-  End_Curve(c);
-  Tree_Add(THEM->Curves, &c);
-  CreateReversedCurve(c);
-  *pc = c;
-  *prc = FindCurve(-c->Num);
-
-  List_Reset(ListOfTransformedPoints);
-
-  if(CTX.geom.auto_coherence && final)
-    ReplaceAllDuplicates();
-
-  return chapeau->Num;
-}
-
-int Extrude_ProtudeCurve(int type, int ic,
-			 double T0, double T1, double T2,
-			 double A0, double A1, double A2,
-			 double X0, double X1, double X2, double alpha,
-			 Surface ** ps, int final, 
-			 ExtrudeParams * e)
-{
-  double matrix[4][4], T[3], Ax[3];
-  Curve *CurveBeg, *CurveEnd;
-  Curve *ReverseChapeau, *ReverseBeg, *ReverseEnd;
-  Curve *pc, *revpc, *chapeau;
-  Surface *s;
-
-  pc = FindCurve(ic);
-  revpc = FindCurve(-ic);
-  *ps = NULL;
-
-  if(!pc || !revpc){
-    return 0;
-  }
-
-  if(!pc->beg || !pc->end){
-    Msg(GERROR, "Cannot extrude curve with no begin/end points");
-    return 0;
-  }
-
-  Msg(DEBUG, "Extrude Curve %d", ic);
-
-  chapeau = DuplicateCurve(pc);
-
-  chapeau->Extrude = new ExtrudeParams(COPIED_ENTITY);
-  chapeau->Extrude->fill(type, T0, T1, T2, A0, A1, A2, X0, X1, X2, alpha);
-  chapeau->Extrude->geo.Source = pc->Num;
-  if(e)
-    chapeau->Extrude->mesh = e->mesh;
-
-  switch (type) {
-  case TRANSLATE:
-    T[0] = T0;
-    T[1] = T1;
-    T[2] = T2;
-    SetTranslationMatrix(matrix, T);
-    List_Reset(ListOfTransformedPoints);
-    ApplyTransformationToCurve(matrix, chapeau);
-    break;
-  case ROTATE:
-    T[0] = -X0;
-    T[1] = -X1;
-    T[2] = -X2;
-    SetTranslationMatrix(matrix, T);
-    List_Reset(ListOfTransformedPoints);
-    ApplyTransformationToCurve(matrix, chapeau);
-
-    Ax[0] = A0;
-    Ax[1] = A1;
-    Ax[2] = A2;
-    SetRotationMatrix(matrix, Ax, alpha);
-    List_Reset(ListOfTransformedPoints);
-    ApplyTransformationToCurve(matrix, chapeau);
-
-    T[0] = X0;
-    T[1] = X1;
-    T[2] = X2;
-    SetTranslationMatrix(matrix, T);
-    List_Reset(ListOfTransformedPoints);
-    ApplyTransformationToCurve(matrix, chapeau);
-    break;
-  case TRANSLATE_ROTATE:
-    T[0] = -X0;
-    T[1] = -X1;
-    T[2] = -X2;
-    SetTranslationMatrix(matrix, T);
-    List_Reset(ListOfTransformedPoints);
-    ApplyTransformationToCurve(matrix, chapeau);
-
-    Ax[0] = A0;
-    Ax[1] = A1;
-    Ax[2] = A2;
-    SetRotationMatrix(matrix, Ax, alpha);
-    List_Reset(ListOfTransformedPoints);
-    ApplyTransformationToCurve(matrix, chapeau);
-
-    T[0] = X0;
-    T[1] = X1;
-    T[2] = X2;
-    SetTranslationMatrix(matrix, T);
-    List_Reset(ListOfTransformedPoints);
-    ApplyTransformationToCurve(matrix, chapeau);
-
-    T[0] = T0;
-    T[1] = T1;
-    T[2] = T2;
-    SetTranslationMatrix(matrix, T);
-    List_Reset(ListOfTransformedPoints);
-    ApplyTransformationToCurve(matrix, chapeau);
-    break;
-  default:
-    Msg(GERROR, "Unknown extrusion type");
-    return pc->Num;
-  }
-
-  Extrude_ProtudePoint(type, pc->beg->Num, T0, T1, T2,
-                       A0, A1, A2, X0, X1, X2, alpha,
-                       &CurveBeg, &ReverseBeg, 0, e);
-  Extrude_ProtudePoint(type, pc->end->Num, T0, T1, T2,
-                       A0, A1, A2, X0, X1, X2, alpha,
-                       &CurveEnd, &ReverseEnd, 0, e);
-
-  if(!CurveBeg && !CurveEnd){
-    return pc->Num;
-  }
-
-  if(!CurveBeg || !CurveEnd)
-    s = Create_Surface(NEWSURFACE(), MSH_SURF_TRIC);
-  else
-    s = Create_Surface(NEWSURFACE(), MSH_SURF_REGL);
-
-  s->Generatrices = List_Create(4, 1, sizeof(Curve *));
-  s->Extrude = new ExtrudeParams;
-  s->Extrude->fill(type, T0, T1, T2, A0, A1, A2, X0, X1, X2, alpha);
-  s->Extrude->useZonLayer(final);
-  s->Extrude->geo.Source = pc->Num;
-  if(e)
-    s->Extrude->mesh = e->mesh;
-
-  ReverseChapeau = FindCurve(-chapeau->Num);
-
-  if(!CurveBeg) {
-    List_Add(s->Generatrices, &pc);
-    List_Add(s->Generatrices, &CurveEnd);
-    List_Add(s->Generatrices, &ReverseChapeau);
-  }
-  else if(!CurveEnd) {
-    List_Add(s->Generatrices, &ReverseChapeau);
-    List_Add(s->Generatrices, &ReverseBeg);
-    List_Add(s->Generatrices, &pc);
-  }
-  else {
-    List_Add(s->Generatrices, &pc);
-    List_Add(s->Generatrices, &CurveEnd);
-    List_Add(s->Generatrices, &ReverseChapeau);
-    List_Add(s->Generatrices, &ReverseBeg);
-  }
-
-  End_Surface(s);
-  Tree_Add(THEM->Surfaces, &s);
-
-  List_Reset(ListOfTransformedPoints);
-
-  *ps = s;
-
-  if(CTX.geom.auto_coherence && final)
-    ReplaceAllDuplicates();
-
-  return chapeau->Num;
-}
-
-int Extrude_ProtudeSurface(int type, int is,
-			   double T0, double T1, double T2,
-			   double A0, double A1, double A2,
-			   double X0, double X1, double X2, double alpha,
-			   Volume **pv, ExtrudeParams * e)
-{
-  double matrix[4][4], T[3], Ax[3];
-  Curve *c, *c2;
-  int i;
-  Surface *s, *ps, *chapeau;
-
-  *pv = NULL;
-
-  if(!(ps = FindSurface(is)))
-    return 0;
-
-  Msg(DEBUG, "Extrude Surface %d", is);
-
-  chapeau = DuplicateSurface(ps);
-
-  chapeau->Extrude = new ExtrudeParams(COPIED_ENTITY);
-  chapeau->Extrude->fill(type, T0, T1, T2, A0, A1, A2, X0, X1, X2, alpha);
-  chapeau->Extrude->geo.Source = ps->Num;
-  if(e)
-    chapeau->Extrude->mesh = e->mesh;
-
-  for(i = 0; i < List_Nbr(chapeau->Generatrices); i++) {
-    List_Read(ps->Generatrices, i, &c2);
-    List_Read(chapeau->Generatrices, i, &c);
-    if(c->Num < 0)
-      if(!(c = FindCurve(-c->Num))) {
-        Msg(GERROR, "Unknown curve %d", -c->Num);
-        return ps->Num;
-      }
-    c->Extrude = new ExtrudeParams(COPIED_ENTITY);
-    c->Extrude->fill(type, T0, T1, T2, A0, A1, A2, X0, X1, X2, alpha);
-    //pas de abs()! il faut le signe pour copy_mesh dans ExtrudeMesh
-    c->Extrude->geo.Source = c2->Num;
-    if(e)
-      c->Extrude->mesh = e->mesh;
-  }
-
-  // FIXME: this is a really ugly hack for backward compatibility, so
-  // that we don't screw up the old .geo files too much. (Before
-  // version 1.54, we didn't always create new volumes during "Extrude
-  // Surface". Now we do, but with "CTX.geom.old_newreg==1", this
-  // bumps the NEWREG() counter, and thus changes the whole automatic
-  // numbering sequence.) So we locally force old_newreg to 0: in most
-  // cases, since we define points, curves, etc., before defining
-  // volumes, the NEWVOLUME() call below will return a fairly low
-  // number, that will not interfere with the other numbers...
-  int tmp = CTX.geom.old_newreg;
-  CTX.geom.old_newreg = 0;
-  Volume *v = Create_Volume(NEWVOLUME(), MSH_VOLUME);
-  CTX.geom.old_newreg = tmp;
-
-  v->Extrude = new ExtrudeParams;
-  v->Extrude->fill(type, T0, T1, T2, A0, A1, A2, X0, X1, X2, alpha);
-  v->Extrude->geo.Source = is;
-  if(e)
-    v->Extrude->mesh = e->mesh;
-  int ori = -1;
-  List_Add(v->Surfaces, &ps);
-  List_Add(v->SurfacesOrientations, &ori);
-  ori = 1;
-  List_Add(v->Surfaces, &chapeau);
-  List_Add(v->SurfacesOrientations, &ori);
-
-  for(i = 0; i < List_Nbr(ps->Generatrices); i++) {
-    List_Read(ps->Generatrices, i, &c);
-    Extrude_ProtudeCurve(type, c->Num, T0, T1, T2, A0, A1, A2, X0, X1, X2,
-			 alpha, &s, 0, e);
-    if(s){
-      if(c < 0)
-	ori = -1;
-      else
-	ori = 1;
-      List_Add(v->Surfaces, &s);
-      List_Add(v->SurfacesOrientations, &ori);
-    }
-  }
-
-  switch (type) {
-  case TRANSLATE:
-    T[0] = T0;
-    T[1] = T1;
-    T[2] = T2;
-    SetTranslationMatrix(matrix, T);
-    List_Reset(ListOfTransformedPoints);
-    ApplyTransformationToSurface(matrix, chapeau);
-    break;
-  case ROTATE:
-    T[0] = -X0;
-    T[1] = -X1;
-    T[2] = -X2;
-    SetTranslationMatrix(matrix, T);
-    List_Reset(ListOfTransformedPoints);
-    ApplyTransformationToSurface(matrix, chapeau);
-
-    Ax[0] = A0;
-    Ax[1] = A1;
-    Ax[2] = A2;
-    SetRotationMatrix(matrix, Ax, alpha);
-    List_Reset(ListOfTransformedPoints);
-    ApplyTransformationToSurface(matrix, chapeau);
-
-    T[0] = X0;
-    T[1] = X1;
-    T[2] = X2;
-    SetTranslationMatrix(matrix, T);
-    List_Reset(ListOfTransformedPoints);
-    ApplyTransformationToSurface(matrix, chapeau);
-    break;
-  case TRANSLATE_ROTATE:
-    T[0] = -X0;
-    T[1] = -X1;
-    T[2] = -X2;
-    SetTranslationMatrix(matrix, T);
-    List_Reset(ListOfTransformedPoints);
-    ApplyTransformationToSurface(matrix, chapeau);
-
-    Ax[0] = A0;
-    Ax[1] = A1;
-    Ax[2] = A2;
-    SetRotationMatrix(matrix, Ax, alpha);
-    List_Reset(ListOfTransformedPoints);
-    ApplyTransformationToSurface(matrix, chapeau);
-
-    T[0] = X0;
-    T[1] = X1;
-    T[2] = X2;
-    SetTranslationMatrix(matrix, T);
-    List_Reset(ListOfTransformedPoints);
-    ApplyTransformationToSurface(matrix, chapeau);
-
-    T[0] = T0;
-    T[1] = T1;
-    T[2] = T2;
-    SetTranslationMatrix(matrix, T);
-    List_Reset(ListOfTransformedPoints);
-    ApplyTransformationToSurface(matrix, chapeau);
-    break;
-  default:
-    Msg(GERROR, "Unknown extrusion type");
-    return ps->Num;
-  }
-
-  // FIXME: why do we do this? only for backward compatibility?
-  Tree_Suppress(THEM->Surfaces, &chapeau);
-  chapeau->Num = NEWSURFACE();
-  THEM->MaxSurfaceNum = chapeau->Num;
-  Tree_Add(THEM->Surfaces, &chapeau);
-
-  Tree_Add(THEM->Volumes, &v);
-
-  *pv = v;
-
-  if(CTX.geom.auto_coherence)
-    ReplaceAllDuplicates();
-
-  List_Reset(ListOfTransformedPoints);
-
-  return chapeau->Num;
-}
-
-void ExtrudeShape(int extrude_type, int shape_type, int shape_num,
-		  double T0, double T1, double T2,
-		  double A0, double A1, double A2,
-		  double X0, double X1, double X2, double alpha,
-		  ExtrudeParams *e,
-		  List_T *out)
-{
-  Shape shape;
-  shape.Type = shape_type;
-  shape.Num = shape_num;
-  List_T *tmp = List_Create(1, 1, sizeof(Shape));
-  List_Add(tmp, &shape);
-  ExtrudeShapes(extrude_type, tmp,
-		T0, T1, T2,
-		A0, A1, A2,
-		X0, X1, X2, alpha,
-		e,
-		out);
-  List_Delete(tmp);
-}
-
-void ExtrudeShapes(int type, List_T *in, 
-		   double T0, double T1, double T2,
-		   double A0, double A1, double A2,
-		   double X0, double X1, double X2, double alpha,
-		   ExtrudeParams *e,
-		   List_T *out)
-{
-  Shape O, TheShape;
-  Curve *pc, *prc;
-  Surface *ps;
-  Volume *pv;
-      
-  for(int i = 0; i < List_Nbr(in); i++){
-    List_Read(in, i, &O);
-    switch(O.Type){
-    case MSH_POINT:
-      TheShape.Num = Extrude_ProtudePoint(type, O.Num, T0, T1, T2,
-					  A0, A1, A2, X0, X1, X2, alpha,
-					  &pc, &prc, 1, e);
-      TheShape.Type = MSH_POINT;
-      List_Add(out, &TheShape);
-      if(pc){
-	TheShape.Num = pc->Num;
-	TheShape.Type = pc->Typ;
-	List_Add(out, &TheShape);
-      }
-      break;
-    case MSH_SEGM_LINE:
-    case MSH_SEGM_SPLN:
-    case MSH_SEGM_BSPLN:
-    case MSH_SEGM_BEZIER:
-    case MSH_SEGM_CIRC:
-    case MSH_SEGM_CIRC_INV:
-    case MSH_SEGM_ELLI:
-    case MSH_SEGM_ELLI_INV:
-    case MSH_SEGM_NURBS:
-    case MSH_SEGM_PARAMETRIC:
-      TheShape.Num = Extrude_ProtudeCurve(type, O.Num, T0, T1, T2,
-					  A0, A1, A2, X0, X1, X2, alpha,
-					  &ps, 1, e);
-      pc = FindCurve(TheShape.Num);
-      if(!pc){
-	//Msg(WARNING, "Unknown curve %d", TheShape.Num);
-	TheShape.Type = 0;
-      }
-      else{
-	TheShape.Type = pc->Typ;
-      }
-      List_Add(out, &TheShape);
-      if(ps){
-	TheShape.Num = ps->Num;
-	TheShape.Type = ps->Typ;
-	List_Add(out, &TheShape);
-      }
-      break;
-    case MSH_SURF_NURBS:
-    case MSH_SURF_REGL:
-    case MSH_SURF_TRIC:
-    case MSH_SURF_PLAN:
-      TheShape.Num = Extrude_ProtudeSurface(type, O.Num, T0, T1, T2,
-					    A0, A1, A2, X0, X1, X2, alpha,
-					    &pv, e);
-      ps = FindSurface(TheShape.Num);
-      if(!ps){
-	//Msg(WARNING, "Unknown surface %d", TheShape.Num);
-	TheShape.Type = 0;
-      }
-      else{
-	TheShape.Type = ps->Typ;
-      }
-      List_Add(out, &TheShape);
-      if(pv){
-	TheShape.Num = pv->Num;
-	TheShape.Type = pv->Typ;
-	List_Add(out, &TheShape);
-      }
-      break;
-    default:
-      Msg(GERROR, "Impossible to extrude entity %d (of type %d)", O.Num,
-          O.Type);
-      break;
-    }
-  }
-}
-
-// Duplicate removal
-
-int compareTwoCurves(const void *a, const void *b)
-{
-  Curve *c1 = *(Curve **) a;
-  Curve *c2 = *(Curve **) b;
-  int comp;
-
-  if(c1->Typ != c2->Typ){
-    if((c1->Typ == MSH_SEGM_CIRC && c2->Typ == MSH_SEGM_CIRC_INV) ||
-       (c1->Typ == MSH_SEGM_CIRC_INV && c2->Typ == MSH_SEGM_CIRC) ||
-       (c1->Typ == MSH_SEGM_ELLI && c2->Typ == MSH_SEGM_ELLI_INV) ||
-       (c1->Typ == MSH_SEGM_ELLI_INV && c2->Typ == MSH_SEGM_ELLI)){
-      // this is still ok
-    }
-    else
-      return c1->Typ - c2->Typ;
-  }
-
-  if(List_Nbr(c1->Control_Points) != List_Nbr(c2->Control_Points))
-    return List_Nbr(c1->Control_Points) - List_Nbr(c2->Control_Points);
-  
-  if(!List_Nbr(c1->Control_Points)){
-    if(!c1->beg || !c2->beg)
-      return 1;
-    comp = compareVertex(&c1->beg, &c2->beg);
-    if(comp)
-      return comp;
-    if(!c1->end || !c2->end)
-      return 1;
-    comp = compareVertex(&c1->end, &c2->end);
-    if(comp)
-      return comp;
-  }
-  else {
-    for(int i = 0; i < List_Nbr(c1->Control_Points); i++){
-      Vertex *v1, *v2;
-      List_Read(c1->Control_Points, i, &v1);
-      List_Read(c2->Control_Points, i, &v2);
-      comp = compareVertex(&v1, &v2);
-      if(comp)
-	return comp;
-    }
-  }
-
-  return 0;
-}
-
-int compareTwoSurfaces(const void *a, const void *b)
-{
-  Surface *s1 = *(Surface **) a;
-  Surface *s2 = *(Surface **) b;
-  return compare2Lists(s1->Generatrices, s2->Generatrices, compareAbsCurve);
-}
-
-void MaxNumPoint(void *a, void *b)
-{
-  Vertex *v = *(Vertex **) a;
-  THEM->MaxPointNum = MAX(THEM->MaxPointNum, v->Num);
-}
-
-void MaxNumCurve(void *a, void *b)
-{
-  Curve *c = *(Curve **) a;
-  THEM->MaxLineNum = MAX(THEM->MaxLineNum, c->Num);
-}
-
-void MaxNumSurface(void *a, void *b)
-{
-  Surface *s = *(Surface **) a;
-  THEM->MaxSurfaceNum = MAX(THEM->MaxSurfaceNum, s->Num);
-}
-
-void ReplaceDuplicatePoints()
-{
-  List_T *All;
-  Tree_T *allNonDuplicatedPoints;
-  Vertex *v, **pv, **pv2;
-  Curve *c;
-  Surface *s;
-  Volume *vol;
-  int i, j, start, end;
-
-  List_T *points2delete = List_Create(100, 100, sizeof(Vertex *));
-
-  // Create unique points
-
-  start = Tree_Nbr(THEM->Points);
-
-  All = Tree2List(THEM->Points);
-  allNonDuplicatedPoints = Tree_Create(sizeof(Vertex *), comparePosition);
-  for(i = 0; i < List_Nbr(All); i++) {
-    List_Read(All, i, &v);
-    if(!Tree_Search(allNonDuplicatedPoints, &v)) {
-      Tree_Insert(allNonDuplicatedPoints, &v);
-    }
-    else {
-      Tree_Suppress(THEM->Points, &v);
-      Tree_Suppress(THEM->Vertices, &v);
-      //List_Add(points2delete,&v);      
-    }
-  }
-  List_Delete(All);
-
-  end = Tree_Nbr(THEM->Points);
-
-  if(start == end) {
-    Tree_Delete(allNonDuplicatedPoints);
-    List_Delete(points2delete);
-    return;
-  }
-
-  Msg(DEBUG, "Removed %d duplicate points", start - end);
-
-  if(CTX.geom.old_newreg) {
-    THEM->MaxPointNum = 0;
-    Tree_Action(THEM->Points, MaxNumPoint);
-    Tree_Action(THEM->Vertices, MaxNumPoint);
-  }
-
-  // Replace old points in curves
-
-  All = Tree2List(THEM->Curves);
-  for(i = 0; i < List_Nbr(All); i++) {
-    List_Read(All, i, &c);
-    if(!Tree_Query(allNonDuplicatedPoints, &c->beg))
-      Msg(GERROR, "Weird point %d in Coherence", c->beg->Num);
-    if(!Tree_Query(allNonDuplicatedPoints, &c->end))
-      Msg(GERROR, "Weird point %d in Coherence", c->end->Num);
-    for(j = 0; j < List_Nbr(c->Control_Points); j++) {
-      pv = (Vertex **) List_Pointer(c->Control_Points, j);
-      if(!(pv2 = (Vertex **) Tree_PQuery(allNonDuplicatedPoints, pv)))
-        Msg(GERROR, "Weird point %d in Coherence", (*pv)->Num);
-      else
-        List_Write(c->Control_Points, j, pv2);
-    }
-  }
-  List_Delete(All);
-
-  // Replace old points in surfaces
-
-  All = Tree2List(THEM->Surfaces);
-  for(i = 0; i < List_Nbr(All); i++) {
-    List_Read(All, i, &s);
-    for(j = 0; j < List_Nbr(s->Control_Points); j++) {
-      pv = (Vertex **) List_Pointer(s->Control_Points, j);
-      if(!(pv2 = (Vertex **) Tree_PQuery(allNonDuplicatedPoints, pv)))
-        Msg(GERROR, "Weird point %d in Coherence", (*pv)->Num);
-      else
-        List_Write(s->Control_Points, j, pv2);
-    }
-    for(j = 0; j < List_Nbr(s->TrsfPoints); j++){
-      pv = (Vertex **) List_Pointer(s->TrsfPoints, j);
-      if(!(pv2 = (Vertex **) Tree_PQuery(allNonDuplicatedPoints, pv)))
-	Msg(GERROR, "Weird point %d in Coherence", (*pv)->Num);
-      else
-	List_Write(s->TrsfPoints, j, pv2);
-    }
-  }
-  List_Delete(All);
-  
-  // Replace old points in volumes
-
-  All = Tree2List(THEM->Volumes);
-  for(i = 0; i < List_Nbr(All); i++) {
-    List_Read(All, i, &vol);
-    for(j = 0; j < List_Nbr(vol->TrsfPoints); j++){
-      pv = (Vertex **) List_Pointer(vol->TrsfPoints, j);
-      if(!(pv2 = (Vertex **) Tree_PQuery(allNonDuplicatedPoints, pv)))
-	Msg(GERROR, "Weird point %d in Coherence", (*pv)->Num);
-      else
-	List_Write(vol->TrsfPoints, j, pv2);
-    }
-  }
-  List_Delete(All);
-
-  for(int k = 0; k < List_Nbr(points2delete); k++) {
-    List_Read(points2delete, i, &v);
-    Free_Vertex(&v, 0);
-  }
-
-  Tree_Delete(allNonDuplicatedPoints);
-  List_Delete(points2delete);
-
-}
-
-void ReplaceDuplicateCurves()
-{
-  List_T *All;
-  Tree_T *allNonDuplicatedCurves;
-  Curve *c, *c2, **pc, **pc2;
-  Surface *s;
-  int i, j, start, end;
-
-  // Create unique curves
-
-  start = Tree_Nbr(THEM->Curves);
-
-  All = Tree2List(THEM->Curves);
-  allNonDuplicatedCurves = Tree_Create(sizeof(Curve *), compareTwoCurves);
-  for(i = 0; i < List_Nbr(All); i++) {
-    List_Read(All, i, &c);
-    if(c->Num > 0) {
-      if(!Tree_Search(allNonDuplicatedCurves, &c)) {
-        Tree_Insert(allNonDuplicatedCurves, &c);
-        if(!(c2 = FindCurve(-c->Num))) {
-          Msg(GERROR, "Unknown curve %d", -c->Num);
-          List_Delete(All);
-          return;
-        }
-        Tree_Insert(allNonDuplicatedCurves, &c2);
-      }
-      else {
-        Tree_Suppress(THEM->Curves, &c);
-        if(!(c2 = FindCurve(-c->Num))) {
-          Msg(GERROR, "Unknown curve %d", -c->Num);
-          List_Delete(All);
-          return;
-        }
-        Tree_Suppress(THEM->Curves, &c2);
-      }
-    }
-  }
-  List_Delete(All);
-
-  end = Tree_Nbr(THEM->Curves);
-
-  if(start == end) {
-    Tree_Delete(allNonDuplicatedCurves);
-    return;
-  }
-
-  Msg(DEBUG, "Removed %d duplicate curves", start - end);
-
-  if(CTX.geom.old_newreg) {
-    THEM->MaxLineNum = 0;
-    Tree_Action(THEM->Curves, MaxNumCurve);
-  }
-
-  // Replace old curves in surfaces
-
-  All = Tree2List(THEM->Surfaces);
-  for(i = 0; i < List_Nbr(All); i++) {
-    List_Read(All, i, &s);
-    for(j = 0; j < List_Nbr(s->Generatrices); j++) {
-      pc = (Curve **) List_Pointer(s->Generatrices, j);
-      if(!(pc2 = (Curve **) Tree_PQuery(allNonDuplicatedCurves, pc)))
-        Msg(GERROR, "Weird curve %d in Coherence", (*pc)->Num);
-      else {
-        List_Write(s->Generatrices, j, pc2);
-        // Arghhh. Revoir compareTwoCurves !
-        End_Curve(*pc2);
-      }
-    }
-  }
-  List_Delete(All);
-
-  Tree_Delete(allNonDuplicatedCurves);
-}
-
-void ReplaceDuplicateSurfaces()
-{
-  List_T *All;
-  Tree_T *allNonDuplicatedSurfaces;
-  Surface *s, **ps, **ps2;
-  Volume *vol;
-  int i, j, start, end;
-
-  // Create unique surfaces
-
-  start = Tree_Nbr(THEM->Surfaces);
-
-  All = Tree2List(THEM->Surfaces);
-  allNonDuplicatedSurfaces = Tree_Create(sizeof(Curve *), compareTwoSurfaces);
-  for(i = 0; i < List_Nbr(All); i++) {
-    List_Read(All, i, &s);
-    if(s->Num > 0) {
-      if(!Tree_Search(allNonDuplicatedSurfaces, &s)) {
-        Tree_Insert(allNonDuplicatedSurfaces, &s);
-      }
-      else {
-        Tree_Suppress(THEM->Surfaces, &s);
-      }
-    }
-  }
-  List_Delete(All);
-
-  end = Tree_Nbr(THEM->Surfaces);
-
-  if(start == end) {
-    Tree_Delete(allNonDuplicatedSurfaces);
-    return;
-  }
-
-  Msg(DEBUG, "Removed %d duplicate surfaces", start - end);
-
-  if(CTX.geom.old_newreg) {
-    THEM->MaxSurfaceNum = 0;
-    Tree_Action(THEM->Surfaces, MaxNumSurface);
-  } 
-
-  // Replace old surfaces in volumes
-
-  All = Tree2List(THEM->Volumes);
-  for(i = 0; i < List_Nbr(All); i++) {
-    List_Read(All, i, &vol);
-    for(j = 0; j < List_Nbr(vol->Surfaces); j++) {
-      ps = (Surface **) List_Pointer(vol->Surfaces, j);
-      if(!(ps2 = (Surface **) Tree_PQuery(allNonDuplicatedSurfaces, ps)))
-        Msg(GERROR, "Weird surface %d in Coherence", (*ps)->Num);
-      else
-        List_Write(vol->Surfaces, j, ps2);
-    }
-  }
-  List_Delete(All);
-
-  Tree_Delete(allNonDuplicatedSurfaces);
-}
-
-void ReplaceAllDuplicates()
-{
-  ReplaceDuplicatePoints();
-  ReplaceDuplicateCurves();
-  ReplaceDuplicateSurfaces();
-}
-
-
-// Projection of point on curve or surface
-
-static Curve *CURVE, *CURVE_2;
-static Surface *SURFACE;
-static Vertex *VERTEX;
-
-double min1d(double (*funct) (double), double *xmin)
-{
-  // we should think about the tolerance more carefully...
-  double ax = 1.e-15, bx = 1.e-12, cx = 1.e-11, fa, fb, fx, tol = 1.e-4;
-  mnbrak(&ax, &bx, &cx, &fa, &fx, &fb, funct);
-  //Msg(INFO, "--MIN1D : ax %12.5E bx %12.5E cx %12.5E",ax,bx,cx);  
-  return (brent(ax, bx, cx, funct, tol, xmin));
-}
-
-static void projectPS(int N, double x[], double res[])
-{
-  //x[1] = u x[2] = v
-  Vertex du, dv, c;
-  c = InterpolateSurface(SURFACE, x[1], x[2], 0, 0);
-  du = InterpolateSurface(SURFACE, x[1], x[2], 1, 1);
-  dv = InterpolateSurface(SURFACE, x[1], x[2], 1, 2);
-  res[1] =
-    (c.Pos.X - VERTEX->Pos.X) * du.Pos.X +
-    (c.Pos.Y - VERTEX->Pos.Y) * du.Pos.Y +
-    (c.Pos.Z - VERTEX->Pos.Z) * du.Pos.Z;
-  res[2] =
-    (c.Pos.X - VERTEX->Pos.X) * dv.Pos.X +
-    (c.Pos.Y - VERTEX->Pos.Y) * dv.Pos.Y +
-    (c.Pos.Z - VERTEX->Pos.Z) * dv.Pos.Z;
-}
-
-static double projectPC(double u)
-{
-  //x[1] = u x[2] = v
-  if(u < CURVE->ubeg)
-    u = CURVE->ubeg;
-  if(u < CURVE->ubeg)
-    u = CURVE->ubeg;
-  Vertex c;
-  c = InterpolateCurve(CURVE, u, 0);
-  return sqrt(DSQR(c.Pos.X - VERTEX->Pos.X) +
-              DSQR(c.Pos.Y - VERTEX->Pos.Y) + DSQR(c.Pos.Z - VERTEX->Pos.Z));
-}
-
-static int UFIXED = 0;
-static double FIX;
-static double projectPCS(double u)
-{
-  //x[1] = u x[2] = v
-  double tmin, tmax;
-  if(UFIXED) {
-    tmin = SURFACE->kv[0];
-    tmax = SURFACE->kv[SURFACE->Nv + SURFACE->OrderV];
-  }
-  else {
-    tmin = SURFACE->ku[0];
-    tmax = SURFACE->ku[SURFACE->Nu + SURFACE->OrderU];
-  }
-
-  if(u < tmin)
-    u = tmin;
-  if(u > tmax)
-    u = tmax;
-  Vertex c;
-  if(UFIXED)
-    c = InterpolateSurface(SURFACE, FIX, u, 0, 0);
-  else
-    c = InterpolateSurface(SURFACE, u, FIX, 0, 0);
-  return sqrt(DSQR(c.Pos.X - VERTEX->Pos.X) +
-              DSQR(c.Pos.Y - VERTEX->Pos.Y) + DSQR(c.Pos.Z - VERTEX->Pos.Z));
-}
-
-bool ProjectPointOnCurve(Curve * c, Vertex * v, Vertex * RES, Vertex * DER)
-{
-  double xmin;
-  CURVE = c;
-  VERTEX = v;
-  min1d(projectPC, &xmin);
-  *RES = InterpolateCurve(CURVE, xmin, 0);
-  *DER = InterpolateCurve(CURVE, xmin, 1);
-  if(xmin > c->uend) {
-    xmin = c->uend;
-    *RES = InterpolateCurve(CURVE, c->uend, 0);
-    *DER = InterpolateCurve(CURVE, c->uend, 1);
-  }
-  else if(xmin < c->ubeg) {
-    xmin = c->ubeg;
-    *RES = InterpolateCurve(CURVE, c->ubeg, 0);
-    *DER = InterpolateCurve(CURVE, c->ubeg, 1);
-  }  
-  return true;
-}
-
-bool search_in_boundary(Surface * s, Vertex * p, double t, int Fixu,
-                        double *uu, double *vv)
-{
-  double l, umin = 0., vmin = 0., lmin = 1.e200;
-  int i, N;
-  Vertex vr;
-  double tmin, tmax, u, v;
-
-  if(Fixu) {
-    tmin = s->kv[0];
-    tmax = s->kv[s->Nv + s->OrderV];
-    N = 3 * s->Nu;
-  }
-  else {
-    tmin = s->ku[0];
-    tmax = s->ku[s->Nu + s->OrderU];
-    N = 3 * s->Nv;
-  }
-  for(i = 0; i < N; i++) {
-    if(Fixu) {
-      u = t;
-      v = tmin + (tmax - tmin) * (double)(i) / (double)(N - 1);
-    }
-    else {
-      v = t;
-      u = tmin + (tmax - tmin) * (double)(i) / (double)(N - 1);
-    }
-    vr = InterpolateSurface(SURFACE, u, v, 0, 0);
-    l = sqrt(DSQR(vr.Pos.X - p->Pos.X) +
-             DSQR(vr.Pos.Y - p->Pos.Y) + DSQR(vr.Pos.Z - p->Pos.Z));
-    if(l < lmin) {
-      lmin = l;
-      umin = u;
-      vmin = v;
-    }
-  }
-
-  FIX = t;
-  UFIXED = Fixu;
-  double xm;
-  if(Fixu)
-    xm = vmin;
-  else
-    xm = umin;
-  if(lmin > 1.e-3)
-    min1d(projectPCS, &xm);
-  if(Fixu) {
-    *uu = t;
-    *vv = xm;
-  }
-  else {
-    *vv = t;
-    *uu = xm;
-  }
-  vr = InterpolateSurface(SURFACE, *uu, *vv, 0, 0);
-  l = sqrt(DSQR(vr.Pos.X - p->Pos.X) +
-           DSQR(vr.Pos.Y - p->Pos.Y) + DSQR(vr.Pos.Z - p->Pos.Z));
-  if(l < 1.e-3)
-    return true;
-  return false;
-}
-
-bool try_a_value(Surface * s, Vertex * p, double u, double v, double *uu,
-                 double *vv)
-{
-  Vertex vr = InterpolateSurface(s, u, v, 0, 0);
-  double l = sqrt(DSQR(vr.Pos.X - p->Pos.X) +
-                  DSQR(vr.Pos.Y - p->Pos.Y) + DSQR(vr.Pos.Z - p->Pos.Z));
-  *uu = u;
-  *vv = v;
-  if(l < 1.e-3)
-    return true;
-  return false;
-}
-
-bool ProjectPointOnSurface(Surface * s, Vertex & p)
-{
-  double x[3] = { 0.5, 0.5, 0.5 };
-  Vertex vv;
-  int check;
-  SURFACE = s;
-  VERTEX = &p;
-  double UMIN = 0.;
-  double UMAX = 1.;
-  double VMIN = 0.;
-  double VMAX = 1.;
-  while(1) {
-    newt(x, 2, &check, projectPS);
-    vv = InterpolateSurface(s, x[1], x[2], 0, 0);
-    if(x[1] >= UMIN && x[1] <= UMAX && x[2] >= VMIN && x[2] <= VMAX)
-      break;
-    x[1] = UMIN + (UMAX - UMIN) * ((rand() % 10000) / 10000.);
-    x[2] = VMIN + (VMAX - VMIN) * ((rand() % 10000) / 10000.);
-  }
-  p.Pos.X = vv.Pos.X;
-  p.Pos.Y = vv.Pos.Y;
-  p.Pos.Z = vv.Pos.Z;
-  p.us[0] = x[1];
-  p.us[1] = x[2];
-  if(!check) {
-    return false;
-  }
-  return true;
-}
-
-bool ProjectPointOnSurface(Surface * s, Vertex * p, double *u, double *v)
-{
-  static double x[3];
-  int check;
-  static int deb = 1;
-  double VMIN, VMAX, UMIN, UMAX, l, lmin;
-  Vertex vv;
-
-  SURFACE = s;
-  VERTEX = p;
-  lmin = 1.e24;
-  UMAX = s->ku[s->Nu + s->OrderU];
-  UMIN = s->ku[0];
-  VMAX = s->kv[s->Nv + s->OrderV];
-  VMIN = s->kv[0];
-  if(deb) {
-    x[1] = UMIN + (UMAX - UMIN) * ((rand() % 10000) / 10000.);
-    x[2] = VMIN + (VMAX - VMIN) * ((rand() % 10000) / 10000.);
-    deb = 0;
-  }
-
-  if(try_a_value(SURFACE, VERTEX, SURFACE->ku[0] + VERTEX->u,
-                 SURFACE->kv[0], u, v))
-    return true;
-  if(try_a_value(SURFACE, VERTEX, SURFACE->ku[0] + VERTEX->u,
-                 SURFACE->kv[SURFACE->Nv + SURFACE->OrderV], u, v))
-    return true;
-  if(try_a_value
-     (SURFACE, VERTEX, SURFACE->ku[SURFACE->Nu + SURFACE->OrderU] - VERTEX->u,
-      SURFACE->kv[0], u, v))
-    return true;
-  if(try_a_value
-     (SURFACE, VERTEX, SURFACE->ku[SURFACE->Nu + SURFACE->OrderU] - VERTEX->u,
-      SURFACE->kv[SURFACE->Nv + SURFACE->OrderV], u, v))
-    return true;
-  if(try_a_value
-     (SURFACE, VERTEX, SURFACE->ku[0], SURFACE->kv[0] + VERTEX->u, u, v))
-    return true;
-  if(try_a_value(SURFACE, VERTEX, SURFACE->ku[0],
-                 SURFACE->kv[SURFACE->Nv + SURFACE->OrderV] - VERTEX->u, u,
-                 v))
-    return true;
-  if(try_a_value(SURFACE, VERTEX, SURFACE->ku[SURFACE->Nu + SURFACE->OrderU],
-                 SURFACE->kv[0] + VERTEX->u, u, v))
-    return true;
-  if(try_a_value(SURFACE, VERTEX, SURFACE->ku[SURFACE->Nu + SURFACE->OrderU],
-                 SURFACE->kv[SURFACE->Nv + SURFACE->OrderV] - VERTEX->u, u,
-                 v))
-    return true;
-
-
-  if(search_in_boundary(SURFACE, VERTEX, SURFACE->kv[0], 0, u, v))
-    return true;
-  if(search_in_boundary
-     (SURFACE, VERTEX, SURFACE->kv[SURFACE->Nv + SURFACE->OrderV], 0, u, v))
-    return true;
-  if(search_in_boundary(SURFACE, VERTEX, SURFACE->ku[0], 1, u, v))
-    return true;
-  if(search_in_boundary
-     (SURFACE, VERTEX, SURFACE->ku[SURFACE->Nu + SURFACE->OrderU], 1, u, v))
-    return true;
-
-  while(1) {
-    newt(x, 2, &check, projectPS);
-    vv = InterpolateSurface(s, x[1], x[2], 0, 0);
-    l = sqrt(DSQR(vv.Pos.X - p->Pos.X) +
-             DSQR(vv.Pos.Y - p->Pos.Y) + DSQR(vv.Pos.Z - p->Pos.Z));
-    if(l < 1.e-1)
-      break;
-    else {
-      x[1] = UMIN + (UMAX - UMIN) * ((rand() % 10000) / 10000.);
-      x[2] = VMIN + (VMAX - VMIN) * ((rand() % 10000) / 10000.);
-    }
-  }
-  *u = x[1];
-  *v = x[2];
-
-  if(!check) {
-    return false;
-  }
-  return true;
-}
-
diff --git a/Geo/CAD.h b/Geo/CAD.h
deleted file mode 100644
index 73ed40a726..0000000000
--- a/Geo/CAD.h
+++ /dev/null
@@ -1,88 +0,0 @@
-#ifndef _CAD_H_
-#define _CAD_H_
-
-// Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-// USA.
-// 
-// Please report all bugs and problems to <gmsh@geuz.org>.
-
-#include "List.h"
-#include "Mesh.h"
-#include "Vertex.h"
-#include "ExtrudeParams.h"
-
-int NEWPOINT(void);
-int NEWLINE(void);
-int NEWLINELOOP(void);
-int NEWSURFACE(void);
-int NEWSURFACELOOP(void);
-int NEWVOLUME(void);
-int NEWPHYSICAL(void);
-int NEWREG(void);
-
-Vertex *FindPoint(int inum);
-Vertex *FindVertex(int inum);
-Curve *FindCurve(int inum);
-Surface *FindSurface(int inum);
-Volume *FindVolume(int inum);
-EdgeLoop *FindEdgeLoop(int inum);
-SurfaceLoop *FindSurfaceLoop(int inum);
-PhysicalGroup *FindPhysicalGroup(int inum, int type);
-
-Curve *CreateReversedCurve(Curve *c);
-void ModifyLcPoint(int ip, double lc);
-
-void TranslateShapes(double X,double Y,double Z,
-                     List_T *ListShapes, int final);
-void DilatShapes(double X,double Y,double Z, double A,
-                 List_T *ListShapes, int final);
-void RotateShapes(double Ax,double Ay,double Az,
-		  double Px,double Py, double Pz,
-		  double alpha, List_T *ListShapes, int final);
-void SymmetryShapes(double A,double B,double C,
-		    double D, List_T *ListShapes, int final);
-void CopyShape(int Type, int Num, int *New);
-void DeleteShape(int Type, int Num);
-void ColorShape(int Type, int Num, unsigned int Color);
-void VisibilityShape(int Type, int Num, int Mode);
-void VisibilityShape(char *str, int Type, int Mode);
-void ExtrudeShape(int extrude_type, int shape_type, int shape_num,
-		  double T0, double T1, double T2,
-		  double A0, double A1, double A2,
-		  double X0, double X1, double X2, double alpha,
-		  ExtrudeParams *e,
-		  List_T *out);
-void ExtrudeShapes(int extrude_type, List_T *in,
-		   double T0, double T1, double T2,
-		   double A0, double A1, double A2,
-		   double X0, double X1, double X2, double alpha,
-		   ExtrudeParams *e,
-		   List_T *out);
-
-void ProtudeXYZ(double &x, double &y, double &z, ExtrudeParams *e);
-
-void ReplaceAllDuplicates();
-
-bool ProjectPointOnCurve(Curve *c, Vertex *v, Vertex *RES, Vertex *DER);
-bool ProjectPointOnSurface(Surface *s, Vertex &p);
-bool ProjectPointOnSurface(Surface *s, Vertex *p,double *u, double *v);
-
-int recognize_seg(int typ, List_T *liste, int *seg);
-int recognize_loop(List_T *liste, int *loop);
-int recognize_surfloop(List_T *liste, int *loop);
-
-#endif
diff --git a/Geo/ExtrudeParams.cpp b/Geo/ExtrudeParams.cpp
index 6afdedcda4..06a078af9c 100644
--- a/Geo/ExtrudeParams.cpp
+++ b/Geo/ExtrudeParams.cpp
@@ -1,4 +1,4 @@
-// $Id: ExtrudeParams.cpp,v 1.18 2006-01-06 00:34:24 geuzaine Exp $
+// $Id: ExtrudeParams.cpp,v 1.19 2006-11-25 16:52:43 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -21,7 +21,6 @@
 
 #include "Gmsh.h"
 #include "Geo.h"
-#include "CAD.h"
 #include "ExtrudeParams.h"
 
 void Projette(double p[3], double mat[3][3])
diff --git a/Geo/GModelIO_Geo.cpp b/Geo/GModelIO_Geo.cpp
index 9eb704e9df..f5490390fd 100644
--- a/Geo/GModelIO_Geo.cpp
+++ b/Geo/GModelIO_Geo.cpp
@@ -1,4 +1,4 @@
-// $Id: GModelIO_Geo.cpp,v 1.1 2006-11-15 13:19:56 geuzaine Exp $
+// $Id: GModelIO_Geo.cpp,v 1.2 2006-11-25 16:52:43 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -20,7 +20,6 @@
 // Please report all bugs and problems to <gmsh@geuz.org>.
 
 #include "GModel.h"
-#include "Mesh.h"
 #include "Geo.h"
 #include "OpenFile.h"
 #include "Tools.h"
diff --git a/Geo/Geo.cpp b/Geo/Geo.cpp
index 7bfcd110d7..e8d0d69d47 100644
--- a/Geo/Geo.cpp
+++ b/Geo/Geo.cpp
@@ -1,4 +1,4 @@
-// $Id: Geo.cpp,v 1.58 2006-11-14 15:21:03 geuzaine Exp $
+// $Id: Geo.cpp,v 1.59 2006-11-25 16:52:43 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -22,524 +22,3040 @@
 #include "Gmsh.h"
 #include "Numeric.h"
 #include "Geo.h"
-#include "CAD.h"
-#include "Parser.h"
+#include "GeoInterpolation.h"
+#include "Utils.h"
 #include "Context.h"
-#include "GModel.h"
 
+extern Mesh *THEM;
 extern Context_T CTX;
-extern GModel *GMODEL;
 
-#define BUFFSIZE 128000
+static List_T *ListOfTransformedPoints = NULL;
 
-// Some old systems don't have snprintf... Just call sprintf instead.
+// Comparison routines
 
-#if defined(HAVE_NO_SNPRINTF)
-int snprintf(char *str, size_t size, const char* fmt, ...){
-  va_list args;
-  va_start(args, fmt);
-  int ret = vsprintf(str, fmt, args);
-  va_end(args);
-  return ret;
+int compareVertex(const void *a, const void *b)
+{
+  int i, j;
+  Vertex **q, **w;
+
+  q = (Vertex **) a;
+  w = (Vertex **) b;
+  i = abs((*q)->Num);
+  j = abs((*w)->Num);
+  return (i - j);
 }
-#endif
 
-double evaluate_scalarfunction(char *var, double val, char *funct)
+int comparePosition(const void *a, const void *b)
 {
-  FILE *tempf;
-  tempf = yyin;
-
-  if(!(yyin = fopen(CTX.tmp_filename_fullpath, "w"))) {
-    Msg(GERROR, "Unable to open temporary file '%s'", CTX.tmp_filename_fullpath);
-    return 0.;
+  int i, j;
+  Vertex **q, **w;
+  // TOLERANCE ! WARNING WARNING
+  double eps = 1.e-6 * CTX.lc; 
+  // the above tol was changed in 1.61 (before 1.61, it was set to
+  // double eps = 1.e-10 * CTX.lc;
+
+  q = (Vertex **) a;
+  w = (Vertex **) b;
+  i = ((*q)->Num);
+  j = ((*w)->Num);
+
+  if((*q)->Pos.X - (*w)->Pos.X > eps)
+    return (1);
+  if((*q)->Pos.X - (*w)->Pos.X < -eps)
+    return (-1);
+  if((*q)->Pos.Y - (*w)->Pos.Y > eps)
+    return (1);
+  if((*q)->Pos.Y - (*w)->Pos.Y < -eps)
+    return (-1);
+  if((*q)->Pos.Z - (*w)->Pos.Z > eps)
+    return (1);
+  if((*q)->Pos.Z - (*w)->Pos.Z < -eps)
+    return (-1);
+
+  if(i != j) {
+    /*
+     *w = *q;
+     printf("Les points %d et %d sont a la meme position\n",i,j);
+     printf("%12.5E %12.5E %12.5E\n",(*w)->Pos.X,(*w)->Pos.Y,(*w)->Pos.Z);
+     printf("%12.5E %12.5E %12.5E\n",(*q)->Pos.X,(*q)->Pos.Y,(*q)->Pos.Z);
+     */
   }
+  return 0;
+
+}
+
+int compareSurfaceLoop(const void *a, const void *b)
+{
+  SurfaceLoop **q, **w;
+
+  q = (SurfaceLoop **) a;
+  w = (SurfaceLoop **) b;
+  return ((*q)->Num - (*w)->Num);
+}
+
+int compareEdgeLoop(const void *a, const void *b)
+{
+  EdgeLoop **q, **w;
+
+  q = (EdgeLoop **) a;
+  w = (EdgeLoop **) b;
+  return ((*q)->Num - (*w)->Num);
+}
+
+int compareCurve(const void *a, const void *b)
+{
+  Curve **q, **w;
+
+  q = (Curve **) a;
+  w = (Curve **) b;
+  return ((*q)->Num - (*w)->Num);
+}
+
+int compareSurface(const void *a, const void *b)
+{
+  Surface **q, **w;
+
+  q = (Surface **) a;
+  w = (Surface **) b;
+  return ((*q)->Num - (*w)->Num);
+}
+
+int compareVolume(const void *a, const void *b)
+{
+  Volume **q, **w;
+
+  q = (Volume **) a;
+  w = (Volume **) b;
+  return ((*q)->Num - (*w)->Num);
+}
+
+int comparePhysicalGroup(const void *a, const void *b)
+{
+  PhysicalGroup *q, *w;
+  int cmp;
+
+  q = *(PhysicalGroup **) a;
+  w = *(PhysicalGroup **) b;
+  cmp = q->Typ - w->Typ;
+
+  if(cmp)
+    return cmp;
+  else
+    return (q->Num - w->Num);
+}
 
-  // pose "variable = function" and evaluate function
-  fprintf(yyin, "%s = %.16g ;\n", var, val);
-  fprintf(yyin, "ValeurTemporaire__ = %s ;\n", funct);
-  fclose(yyin);
-  yyin = fopen(CTX.tmp_filename_fullpath, "r");
-  while(!feof(yyin)) {
-    yyparse();
+// Basic entity creation/deletion functions
+
+Vertex *Create_Vertex(int Num, double X, double Y, double Z, double lc,
+                      double u)
+{
+  Vertex *pV;
+
+  pV = new Vertex(X, Y, Z, lc);
+  pV->w = 1.0;
+  pV->Num = Num;
+  THEM->MaxPointNum = IMAX(THEM->MaxPointNum, Num);
+  pV->u = u;
+  return pV;
+}
+
+void Delete_Vertex(Vertex * pV)
+{
+  if(pV) {
+    delete pV;
   }
-  fclose(yyin);
-  yyin = tempf;
+}
 
-  // retreive value
-  Symbol TheSymbol, *TheSymbol_P;
-  TheSymbol.Name = (char *)Malloc(100*sizeof(char));
-  strcpy(TheSymbol.Name, "ValeurTemporaire__");
-  if(!(TheSymbol_P = (Symbol*)Tree_PQuery(Symbol_T, &TheSymbol))) {
-    Free(TheSymbol.Name);
-    return 0.0;
+void Free_Vertex(void *a, void *b)
+{
+  Vertex *v = *(Vertex **) a;
+  if(v) {
+    Delete_Vertex(v);
+    v = NULL;
   }
-  Free(TheSymbol.Name);
-  return *(double *)List_Pointer(TheSymbol_P->val, 0);
 }
 
-void add_infile(char *text, char *fich, bool deleted_something)
+PhysicalGroup *Create_PhysicalGroup(int Num, int typ, List_T * intlist)
 {
-  FILE *file;
+  PhysicalGroup *p = (PhysicalGroup *) Malloc(sizeof(PhysicalGroup));
+  p->Entities = List_Create(List_Nbr(intlist), 1, sizeof(int));
+  p->Num = Num;
+  THEM->MaxPhysicalNum = IMAX(THEM->MaxPhysicalNum, Num);
+  p->Typ = typ;
+  p->Visible = 1;
+  for(int i = 0; i < List_Nbr(intlist); i++) {
+    int j;
+    List_Read(intlist, i, &j);
+    List_Add(p->Entities, &j);
+  }
+  return p;
+}
 
-  if(!(yyin = fopen(CTX.tmp_filename_fullpath, "w"))) {
-    Msg(GERROR, "Unable to open temporary file '%s'", CTX.tmp_filename_fullpath);
-    return;
+void Free_PhysicalGroup(void *a, void *b)
+{
+  PhysicalGroup *p = *(PhysicalGroup **) a;
+  if(p) {
+    List_Delete(p->Entities);
+    Free(p);
+    p = NULL;
   }
-  if(!(file = fopen(fich, "a"))) {
-    Msg(GERROR, "Unable to open file '%s'", fich);
-    return;
+}
+
+EdgeLoop *Create_EdgeLoop(int Num, List_T * intlist)
+{
+  EdgeLoop *l = (EdgeLoop *) Malloc(sizeof(EdgeLoop));
+  l->Curves = List_Create(List_Nbr(intlist), 1, sizeof(int));
+  l->Num = Num;
+  THEM->MaxLineLoopNum = IMAX(THEM->MaxLineLoopNum, Num);
+  for(int i = 0; i < List_Nbr(intlist); i++) {
+    int j;
+    List_Read(intlist, i, &j);
+    List_Add(l->Curves, &j);
   }
-  fprintf(yyin, "%s\n", text);
-  Msg(STATUS2, "%s", text);
-  fclose(yyin);
-  yyin = fopen(CTX.tmp_filename_fullpath, "r");
-  while(!feof(yyin)) {
-    yyparse();
+  return l;
+}
+
+void Free_EdgeLoop(void *a, void *b)
+{
+  EdgeLoop *l = *(EdgeLoop **) a;
+  if(l) {
+    List_Delete(l->Curves);
+    Free(l);
+    l = NULL;
   }
-  fclose(yyin);
-  fprintf(file, "%s\n", text);
-  fclose(file);
+}
 
-  if(deleted_something){
-    // we need to start from scratch since the command just parsed
-    // could have deleted some entities
-    GMODEL->destroy();
+SurfaceLoop *Create_SurfaceLoop(int Num, List_T * intlist)
+{
+  SurfaceLoop *l = (SurfaceLoop *) Malloc(sizeof(SurfaceLoop));
+  l->Surfaces = List_Create(List_Nbr(intlist), 1, sizeof(int));
+  l->Num = Num;
+  THEM->MaxSurfaceLoopNum = IMAX(THEM->MaxSurfaceLoopNum, Num);
+  for(int i = 0; i < List_Nbr(intlist); i++) {
+    int j;
+    List_Read(intlist, i, &j);
+    List_Add(l->Surfaces, &j);
   }
-  GMODEL->importTHEM();
-  CTX.mesh.changed = ENT_ALL;
+  return l;
 }
 
-void coherence(char *fich)
+void Free_SurfaceLoop(void *a, void *b)
 {
-  add_infile("Coherence;", fich, true);
+  SurfaceLoop *l = *(SurfaceLoop **) a;
+  if(l) {
+    List_Delete(l->Surfaces);
+    Free(l);
+    l = NULL;
+  }
 }
 
-void strncat_list(char *text, List_T *list)
+void End_Curve(Curve * c)
 {
-  char text2[BUFFSIZE];
-  for(int i = 0; i < List_Nbr(list); i++){
-    int num;
-    List_Read(list, i, &num);
-    if(!i)
-      snprintf(text2, BUFFSIZE, "%d", num);
+  double R2, mat[3][3], R, A3, A1, A4;
+  Vertex *v[4], v0, v2, v3;
+  double f1, f2, dir32[3], dir12[3], n[3], m[3], dir42[3];
+  double rhs[2], sys[2][2], sol[2];
+  int i;
+  Curve *Curve;
+
+  if(c->Typ == MSH_SEGM_CIRC || c->Typ == MSH_SEGM_CIRC_INV ||
+     c->Typ == MSH_SEGM_ELLI || c->Typ == MSH_SEGM_ELLI_INV) {
+
+    Curve = c;
+
+    // v[0] = first point
+    // v[1] = center
+    // v[2] = last point
+    // v[3] = major axis point
+
+    if(List_Nbr(Curve->Control_Points) == 4)
+      List_Read(Curve->Control_Points, 2, &v[3]);
     else
-      snprintf(text2, BUFFSIZE, ",%d", num);
-    strncat(text, text2, BUFFSIZE-strlen(text));
+      v[3] = NULL;
+
+    if(Curve->Typ == MSH_SEGM_CIRC_INV || Curve->Typ == MSH_SEGM_ELLI_INV) {
+      List_Read(Curve->Control_Points, 0, &v[2]);
+      List_Read(Curve->Control_Points, 1, &v[1]);
+      if(!v[3])
+        List_Read(Curve->Control_Points, 2, &v[0]);
+      else
+        List_Read(Curve->Control_Points, 3, &v[0]);
+    }
+    else {
+      List_Read(Curve->Control_Points, 0, &v[0]);
+      List_Read(Curve->Control_Points, 1, &v[1]);
+      if(!v[3])
+        List_Read(Curve->Control_Points, 2, &v[2]);
+      else
+        List_Read(Curve->Control_Points, 3, &v[2]);
+    }
+
+    direction(v[1], v[0], dir12);
+    direction(v[1], v[2], dir32);
+    if(v[3])
+      direction(v[1], v[3], dir42);
+
+    // v0 = vector center->first pt
+    // v2 = vector center->last pt
+    // v3 = vector center->major axis pt
+
+    v0.Pos.X = dir12[0];
+    v0.Pos.Y = dir12[1];
+    v0.Pos.Z = dir12[2];
+    v2.Pos.X = dir32[0];
+    v2.Pos.Y = dir32[1];
+    v2.Pos.Z = dir32[2];
+    if(v[3]) {
+      v3.Pos.X = dir42[0];
+      v3.Pos.Y = dir42[1];
+      v3.Pos.Z = dir42[2];
+    }
+
+    norme(dir12);
+    norme(dir32);
+    prodve(dir12, dir32, n);
+    norme(n);
+    // use provided plane if unable to compute it from input points...
+    if(fabs(n[0]) < 1.e-5 && fabs(n[1]) < 1.e-5 && fabs(n[2]) < 1.e-5) {
+      n[0] = Curve->Circle.n[0];
+      n[1] = Curve->Circle.n[1];
+      n[2] = Curve->Circle.n[2];
+      norme(n);
+    }
+    prodve(n, dir12, m);
+    norme(m);
+
+    mat[2][0] = Curve->Circle.invmat[0][2] = n[0];
+    mat[2][1] = Curve->Circle.invmat[1][2] = n[1];
+    mat[2][2] = Curve->Circle.invmat[2][2] = n[2];
+    mat[1][0] = Curve->Circle.invmat[0][1] = m[0];
+    mat[1][1] = Curve->Circle.invmat[1][1] = m[1];
+    mat[1][2] = Curve->Circle.invmat[2][1] = m[2];
+    mat[0][0] = Curve->Circle.invmat[0][0] = dir12[0];
+    mat[0][1] = Curve->Circle.invmat[1][0] = dir12[1];
+    mat[0][2] = Curve->Circle.invmat[2][0] = dir12[2];
+
+    // assume circle in z=0 plane
+    if(CTX.geom.old_circle) {
+      if(n[0] == 0.0 && n[1] == 0.0) {
+        mat[2][0] = Curve->Circle.invmat[0][2] = 0;
+        mat[2][1] = Curve->Circle.invmat[1][2] = 0;
+        mat[2][2] = Curve->Circle.invmat[2][2] = 1;
+        mat[1][0] = Curve->Circle.invmat[0][1] = 0;
+        mat[1][1] = Curve->Circle.invmat[1][1] = 1;
+        mat[1][2] = Curve->Circle.invmat[2][1] = 0;
+        mat[0][0] = Curve->Circle.invmat[0][0] = 1;
+        mat[0][1] = Curve->Circle.invmat[1][0] = 0;
+        mat[0][2] = Curve->Circle.invmat[2][0] = 0;
+      }
+    }
+
+    Projette(&v0, mat);
+    Projette(&v2, mat);
+    if(v[3])
+      Projette(&v3, mat);
+
+    R = sqrt(v0.Pos.X * v0.Pos.X + v0.Pos.Y * v0.Pos.Y);
+    R2 = sqrt(v2.Pos.X * v2.Pos.X + v2.Pos.Y * v2.Pos.Y);
+
+    if(!R || !R2)       // check radius
+      Msg(GERROR, "Zero radius in Circle/Ellipse %d", c->Num);
+    else if(!v[3] && fabs((R - R2) / (R + R2)) > 0.1)   // check cocircular pts (allow 10% error)
+      Msg(GERROR, "Control points of Circle %d are not cocircular %g %g",
+          c->Num, R, R2);
+
+    // A1 = angle first pt
+    // A3 = angle last pt
+    // A4 = angle major axis
+
+    if(v[3]) {
+      A4 = myatan2(v3.Pos.Y, v3.Pos.X);
+      A4 = angle_02pi(A4);
+      double x1 = v0.Pos.X * cos(A4) + v0.Pos.Y * sin(A4);
+      double y1 = -v0.Pos.X * sin(A4) + v0.Pos.Y * cos(A4);
+      double x3 = v2.Pos.X * cos(A4) + v2.Pos.Y * sin(A4);
+      double y3 = -v2.Pos.X * sin(A4) + v2.Pos.Y * cos(A4);
+      sys[0][0] = x1 * x1;
+      sys[0][1] = y1 * y1;
+      sys[1][0] = x3 * x3;
+      sys[1][1] = y3 * y3;
+      rhs[0] = 1;
+      rhs[1] = 1;
+      sys2x2(sys, rhs, sol);
+      if(sol[0] <= 0 || sol[1] <= 0) {
+        Msg(GERROR, "Ellipse %d is wrong", Curve->Num);
+        A1 = A3 = 0.;
+        f1 = f2 = R;
+      }
+      else {
+        f1 = sqrt(1. / sol[0]);
+        f2 = sqrt(1. / sol[1]);
+        // myasin() permet de contourner les problemes de precision
+        // sur y1/f2 ou y3/f2, qui peuvent legerement etre hors de
+        // [-1,1]
+        if(x1 < 0)
+          A1 = -myasin(y1 / f2) + A4 + Pi;
+        else
+          A1 = myasin(y1 / f2) + A4;
+        if(x3 < 0)
+          A3 = -myasin(y3 / f2) + A4 + Pi;
+        else
+          A3 = myasin(y3 / f2) + A4;
+      }
+    }
+    else {
+      A1 = myatan2(v0.Pos.Y, v0.Pos.X);
+      A3 = myatan2(v2.Pos.Y, v2.Pos.X);
+      A4 = 0.;
+      f1 = f2 = R;
+    }
+
+    A1 = angle_02pi(A1);
+    A3 = angle_02pi(A3);
+    if(A1 >= A3)
+      A3 += 2 * Pi;
+
+    //printf("f1=%g f2=%g a1=%g a3=%g a4=%g\n", 
+    //     f1, f2, A1*180./M_PI, A3*180./Pi, A4*180./Pi);
+
+    Curve->Circle.t1 = A1;
+    Curve->Circle.t2 = A3;
+    Curve->Circle.incl = A4;
+    Curve->Circle.f1 = f1;
+    Curve->Circle.f2 = f2;
+
+    for(i = 0; i < 4; i++)
+      Curve->Circle.v[i] = v[i];
+
+    if(!CTX.expert_mode && Curve->Num > 0 && A3-A1 >= Pi){
+      Msg(GERROR1, "Circle or ellipse arc %d greater than/equal to Pi (angle=%g)",
+	  Curve->Num, A3-A1);
+      Msg(GERROR2, "(If you understand what this implies, you can disable this error");
+      Msg(GERROR2, "message by selecting `Enable expert mode' in the option dialog.");
+      Msg(GERROR3, "Otherwise, please subdivide the arc in smaller pieces.)");
+    }
+
+  }
+
+  if(c->cp){
+    Free(c->cp);
+    c->cp = NULL;
+  }
+
+  if(List_Nbr(c->Control_Points)){
+    c->cp = (float *)Malloc(4 * List_Nbr(c->Control_Points) * sizeof(float));
+    for(i = 0; i < List_Nbr(c->Control_Points); i++) {
+      List_Read(c->Control_Points, i, &v[0]);
+      c->cp[4 * i] = v[0]->Pos.X;
+      c->cp[4 * i + 1] = v[0]->Pos.Y;
+      c->cp[4 * i + 2] = v[0]->Pos.Z;
+      c->cp[4 * i + 3] = v[0]->w;
+    }
   }
 }
 
-void delet(List_T *list, char *fich, char *what)
+void End_Surface(Surface * s, int reset_orientations)
 {
-  char text[BUFFSIZE];
+  int i;
+  Vertex *v;
+  
+  if(reset_orientations) 
+    List_Reset(s->Orientations);
+
+  if(!s->Control_Points || !List_Nbr(s->Control_Points))
+    return;
+
+  s->cp = (float *)Malloc(4 * List_Nbr(s->Control_Points) * sizeof(float));
+  for(i = 0; i < List_Nbr(s->Control_Points); i++) {
+    List_Read(s->Control_Points, i, &v);
+    s->cp[4 * i] = v->Pos.X;
+    s->cp[4 * i + 1] = v->Pos.Y;
+    s->cp[4 * i + 2] = v->Pos.Z;
+    s->cp[4 * i + 3] = v->w;
+  }
 
-  snprintf(text, BUFFSIZE, "Delete {\n  %s{", what);
-  strncat_list(text, list);
-  strncat(text, "};\n}", BUFFSIZE-strlen(text));
-  add_infile(text, fich, true);
 }
 
-void add_trsfellisurf(int type, int N, int *l, char *fich, char *dir)
+
+Curve *Create_Curve(int Num, int Typ, int Order, List_T * Liste,
+                    List_T * Knots, int p1, int p2, double u1, double u2)
 {
-  char text[BUFFSIZE], text2[BUFFSIZE];
+  double matcr[4][4] = { {-0.5, 1.5, -1.5, 0.5},
+			 {1.0, -2.5, 2.0, -0.5},
+			 {-0.5, 0.0, 0.5, 0.0},
+			 {0.0, 1.0, 0.0, 0.0} };
+  double matbs[4][4] = { {-1.0, 3, -3, 1},
+			 {3, -6, 3.0, 0},
+			 {-3, 0.0, 3, 0.0},
+			 {1, 4, 1, 0.0} };
+  double matbez[4][4] = { {-1.0, 3, -3, 1},
+			  {3, -6, 3.0, 0},
+			  {-3, 3.0, 0, 0.0},
+			  {1, 0, 0, 0.0} };
+
+  Curve *pC = (Curve *) Malloc(sizeof(Curve));
+  pC->Color.type = 0;
+  pC->Visible = 1;
+  pC->cp = NULL;
+  pC->Extrude = NULL;
+  pC->Typ = Typ;
+  pC->Num = Num;
+  THEM->MaxLineNum = IMAX(THEM->MaxLineNum, Num);
+  pC->Method = LIBRE;
+  pC->degre = Order;
+  pC->Circle.n[0] = 0.0;
+  pC->Circle.n[1] = 0.0;
+  pC->Circle.n[2] = 1.0;
+  for(int i = 0; i < 4; i++) {
+    pC->ipar[i] = 0;
+    pC->dpar[i] = 0.0;
+  }
 
-  snprintf(text, BUFFSIZE, "%s Surface {%d} = {", 
-	   type ? "Elliptic" : "Transfinite", l[0]);
-  for(int i = 1; i < N; i++) {
-    if(i == 1)
-      snprintf(text2, BUFFSIZE, "%d", l[i]);
-    else
-      snprintf(text2, BUFFSIZE, ",%d", l[i]);
-    strncat(text, text2, BUFFSIZE-strlen(text));
+  if(Typ == MSH_SEGM_SPLN) {
+    for(int i = 0; i < 4; i++)
+      for(int j = 0; j < 4; j++)
+        pC->mat[i][j] = matcr[i][j];
+  }
+  else if(Typ == MSH_SEGM_BSPLN) {
+    for(int i = 0; i < 4; i++)
+      for(int j = 0; j < 4; j++)
+        pC->mat[i][j] = matbs[i][j] / 6.0;
+  }
+  else if(Typ == MSH_SEGM_BEZIER) {
+    for(int i = 0; i < 4; i++)
+      for(int j = 0; j < 4; j++)
+        pC->mat[i][j] = matbez[i][j];
+  }
+
+  pC->ubeg = u1;
+  pC->uend = u2;
+
+  if(Knots) {
+    pC->k = (float *)Malloc(List_Nbr(Knots) * sizeof(float));
+    double kmin = .0, kmax = 1.;
+    List_Read(Knots, 0, &kmin);
+    List_Read(Knots, List_Nbr(Knots) - 1, &kmax);
+    pC->ubeg = kmin;
+    pC->uend = kmax;
+    for(int i = 0; i < List_Nbr(Knots); i++) {
+      double d;
+      List_Read(Knots, i, &d);
+      pC->k[i] = (float)d;
+    }
   }
-  if (!strcmp(dir,"Left"))
-    snprintf(text2, BUFFSIZE, "};");
   else
-    snprintf(text2, BUFFSIZE, "} %s;",dir);
+    pC->k = NULL;
+
+  if(Liste) {
+    pC->Control_Points = List_Create(List_Nbr(Liste), 1, sizeof(Vertex *));
+    for(int j = 0; j < List_Nbr(Liste); j++) {
+      int iPnt;
+      List_Read(Liste, j, &iPnt);
+      Vertex *v;
+      if((v = FindPoint(iPnt)))
+        List_Add(pC->Control_Points, &v);
+      else{
+        Msg(GERROR, "Unknown control point %d in Curve %d", iPnt, pC->Num);
+      }
+    }
+  }
+  else {
+    pC->Control_Points = NULL;
+    pC->beg = NULL;
+    pC->end = NULL;
+    return pC;
+  }
 
-  strncat(text, text2, BUFFSIZE-strlen(text));
-  add_infile(text, fich);
+  if(p1 < 0) {
+    List_Read(pC->Control_Points, 0, &pC->beg);
+    List_Read(pC->Control_Points, List_Nbr(pC->Control_Points) - 1, &pC->end);
+  }
+  else {
+    Vertex *v;
+    if((v = FindPoint(p1))) {
+      Msg(INFO, "Curve %d first control point %d ", pC->Num, v->Num);
+      pC->beg = v;
+    }
+    else {
+      Msg(GERROR, "Unknown control point %d in Curve %d", p1, pC->Num);
+    }
+    if((v = FindPoint(p2))) {
+      Msg(INFO, "Curve %d first control point %d ", pC->Num, v->Num);
+      pC->end = v;
+    }
+    else {
+      Msg(GERROR, "Unknown control point %d in Curve %d", p2, pC->Num);
+    }
+  }
+
+  End_Curve(pC);
+
+  return pC;
 }
 
-void add_charlength(List_T *list, char *fich, char *lc)
+void Free_Curve(void *a, void *b)
 {
-  char text[BUFFSIZE];
+  Curve *pC = *(Curve **) a;
+  if(pC) {
+    Free(pC->k);
+    List_Delete(pC->Control_Points);
+    Free(pC->cp);
+    Free(pC);
+    pC = NULL;
+  }
+}
 
-  snprintf(text, BUFFSIZE, "Characteristic Length {");
-  strncat_list(text, list);
-  strncat(text, "} = ", BUFFSIZE-strlen(text));
-  strncat(text, lc, BUFFSIZE-strlen(text));
-  strncat(text, ";", BUFFSIZE-strlen(text));
-  add_infile(text, fich);
+Surface *Create_Surface(int Num, int Typ)
+{
+  Surface *pS = (Surface *) Malloc(sizeof(Surface));
+  pS->Color.type = 0;
+  pS->Visible = 1;
+  pS->Num = Num;
+  THEM->MaxSurfaceNum = IMAX(THEM->MaxSurfaceNum, Num);
+  pS->Typ = Typ;
+  pS->Method = LIBRE;
+  for(int i = 0; i < 5; i++)
+    pS->ipar[i] = 0;
+  pS->Recombine = 0;
+  pS->Recombine_Dir = 1;
+  pS->RecombineAngle = 75;
+  pS->TrsfPoints = List_Create(4, 4, sizeof(Vertex *));
+  pS->Contours = List_Create(1, 1, sizeof(List_T *));
+  pS->Orientations = List_Create(20, 2, sizeof(Vertex));
+  pS->Support = pS;
+  pS->Control_Points = List_Create(1, 10, sizeof(Vertex *));
+  pS->Generatrices = NULL;
+  pS->EmbeddedPoints = NULL;
+  pS->EmbeddedCurves = NULL;
+  pS->Extrude = NULL;
+  return (pS);
 }
 
-void add_recosurf(List_T *list, char *fich)
+void Free_Surface(void *a, void *b)
 {
-  char text[BUFFSIZE];
+  Surface *pS = *(Surface **) a;
+  if(pS) {
+    List_Delete(pS->TrsfPoints);
+    List_Delete(pS->Contours);
+    List_Delete(pS->Orientations);
+    List_Delete(pS->Control_Points);
+    List_Delete(pS->Generatrices);
+    List_Delete(pS->EmbeddedCurves);
+    List_Delete(pS->EmbeddedPoints);
+    Free(pS);
+    pS = NULL;
+  }
+}
 
-  snprintf(text, BUFFSIZE, "Recombine Surface {");
-  strncat_list(text, list);
-  strncat(text, "};", BUFFSIZE-strlen(text));
-  add_infile(text, fich);
+Volume *Create_Volume(int Num, int Typ)
+{
+  Volume *pV = (Volume *) Malloc(sizeof(Volume));
+  pV->Color.type = 0;
+  pV->Visible = 1;
+  pV->Num = Num;
+  THEM->MaxVolumeNum = IMAX(THEM->MaxVolumeNum, Num);
+  pV->Typ = Typ;
+  pV->Method = LIBRE;
+  for(int i = 0; i < 8; i++)
+    pV->ipar[i] = 0;
+  pV->TrsfPoints = List_Create(6, 6, sizeof(Vertex *));
+  pV->Surfaces = List_Create(1, 2, sizeof(Surface *));
+  pV->SurfacesOrientations = List_Create(1, 2, sizeof(int));
+  pV->Extrude = NULL;
+  return pV;
 }
 
-void add_trsfline(int N, int *l, char *fich, char *type, char *typearg, char *pts)
+void Free_Volume(void *a, void *b)
 {
-  char text[BUFFSIZE], text2[BUFFSIZE];
+  Volume *pV = *(Volume **) a;
+  Free_Volume_But_Not_Elements(a, b);
+}
 
-  snprintf(text, BUFFSIZE, "Transfinite Line {");
-  for(int i = 0; i < N; i++) {
-    if(!i)
-      snprintf(text2, BUFFSIZE, "%d", l[i]);
-    else
-      snprintf(text2, BUFFSIZE, ",%d", l[i]);
-    strncat(text, text2, BUFFSIZE-strlen(text));
+void Free_Volume_But_Not_Elements(void *a, void *b)
+{
+  Volume *pV = *(Volume **) a;
+  if(pV) {
+    List_Delete(pV->TrsfPoints);
+    List_Delete(pV->Surfaces);  // surfaces freed elsewhere
+    List_Delete(pV->SurfacesOrientations);
+    Free(pV);
+    pV = NULL;
   }
-  if(strlen(typearg))
-    snprintf(text2, BUFFSIZE, "} = %s Using %s %s;", pts, type, typearg);
+}
+
+int NEWPOINT(void)
+{
+  return (THEM->MaxPointNum + 1);
+}
+
+int NEWLINE(void)
+{
+  if(CTX.geom.old_newreg)
+    return NEWREG();
   else
-    snprintf(text2, BUFFSIZE, "} = %s;", pts);
-  strncat(text, text2, BUFFSIZE-strlen(text));
-  add_infile(text, fich);
+    return (THEM->MaxLineNum + 1);
 }
 
-void add_param(char *par, char *value, char *fich)
+int NEWLINELOOP(void)
 {
-  char text[BUFFSIZE];
-  snprintf(text, BUFFSIZE, "%s = %s;", par, value);
-  add_infile(text, fich);
+  if(CTX.geom.old_newreg)
+    return NEWREG();
+  else
+    return (THEM->MaxLineLoopNum + 1);
 }
 
-void add_point(char *fich, char *x, char *y, char *z, char *lc)
+int NEWSURFACE(void)
 {
-  char text[BUFFSIZE];
-  int ip = NEWPOINT();
-  snprintf(text, BUFFSIZE, "Point(%d) = {%s,%s,%s,%s};", ip, x, y, z, lc);
-  add_infile(text, fich);
+  if(CTX.geom.old_newreg)
+    return NEWREG();
+  else
+    return (THEM->MaxSurfaceNum + 1);
 }
 
-void add_attractor(char *fich, int ip, int typ, char *ax, char *ay, char *ad)
+int NEWSURFACELOOP(void)
 {
-  char text[BUFFSIZE];
-  if(typ == 0) {
-    snprintf(text, BUFFSIZE, "Attractor Point {%d} = {%s,%s,%s} = ;", ip, ax, ay, ad);
+  if(CTX.geom.old_newreg)
+    return NEWREG();
+  else
+    return (THEM->MaxSurfaceLoopNum + 1);
+}
+
+int NEWVOLUME(void)
+{
+  if(CTX.geom.old_newreg)
+    return NEWREG();
+  else
+    return (THEM->MaxVolumeNum + 1);
+}
+
+int NEWPHYSICAL(void)
+{
+  if(CTX.geom.old_newreg)
+    return NEWREG();
+  else
+    return (THEM->MaxPhysicalNum + 1);
+}
+
+int NEWREG(void)
+{
+  return (IMAX(THEM->MaxLineNum,
+               IMAX(THEM->MaxLineLoopNum,
+                    IMAX(THEM->MaxSurfaceNum,
+                         IMAX(THEM->MaxSurfaceLoopNum,
+                              IMAX(THEM->MaxVolumeNum,
+                                   THEM->MaxPhysicalNum)))))
+          + 1);
+}
+
+
+
+
+int compare2Lists(List_T * List1, List_T * List2,
+                  int (*fcmp) (const void *a, const void *b))
+{
+  int i, found;
+
+  if(!List_Nbr(List1) && !List_Nbr(List2))
+    return 0;
+
+  if(!List_Nbr(List1) || !List_Nbr(List2) || 
+     (List_Nbr(List1) != List_Nbr(List2)))
+    return List_Nbr(List1) - List_Nbr(List2);
+  
+  List_T *List1Prime = List_Create(List_Nbr(List1), 1, List1->size);
+  List_T *List2Prime = List_Create(List_Nbr(List2), 1, List2->size);
+  List_Copy(List1, List1Prime);
+  List_Copy(List2, List2Prime);
+  List_Sort(List1Prime, fcmp);
+  List_Sort(List2Prime, fcmp);
+
+  for(i = 0; i < List_Nbr(List1Prime); i++) {
+    found = fcmp(List_Pointer(List1Prime, i), List_Pointer(List2Prime, i));
+    if(found != 0) {
+      List_Delete(List1Prime);
+      List_Delete(List2Prime);
+      return found;
+    }
   }
-  else if(typ == 1) {
-    snprintf(text, BUFFSIZE, "Attractor Line {%d} = {%s,%s,%s};", ip, ax, ay, ad);
+  List_Delete(List1Prime);
+  List_Delete(List2Prime);
+  return 0;
+}
+
+Vertex *FindPoint(int inum)
+{
+  Vertex C, *pc;
+  pc = &C;
+  pc->Num = inum;
+  if(Tree_Query(THEM->Points, &pc)) {
+    return pc;
   }
-  else if(typ == 2) {
-    snprintf(text, BUFFSIZE, "Attractor Surface {%d} = {%s,%s,%s};", ip, ax, ay, ad);
+  return NULL;
+}
+
+Curve *FindCurve(int inum)
+{
+  Curve C, *pc;
+  pc = &C;
+  pc->Num = inum;
+  if(Tree_Query(THEM->Curves, &pc)) {
+    return pc;
   }
-  add_infile(text, fich);
+  return NULL;
 }
 
+Surface *FindSurface(int inum)
+{
+  Surface S, *ps;
+  ps = &S;
+  ps->Num = inum;
+  if(Tree_Query(THEM->Surfaces, &ps)) {
+    return ps;
+  }
+  return NULL;
+}
 
-void add_line(int p1, int p2, char *fich)
+Volume *FindVolume(int inum)
 {
-  char text[BUFFSIZE];
-  int iseg;
-  List_T *list = List_Create(2, 2, sizeof(int));
-  List_Add(list, &p1);
-  List_Add(list, &p2);
-  if((recognize_seg(MSH_SEGM_LINE, list, &iseg))) {
-    List_Delete(list);
-    return;
+  Volume V, *pv;
+  pv = &V;
+  pv->Num = inum;
+  if(Tree_Query(THEM->Volumes, &pv)) {
+    return pv;
   }
-  List_Delete(list);
+  return NULL;
+}
 
-  snprintf(text, BUFFSIZE, "Line(%d) = {%d,%d};", NEWLINE(), p1, p2);
-  add_infile(text, fich);
+EdgeLoop *FindEdgeLoop(int inum)
+{
+  EdgeLoop S, *ps;
+  ps = &S;
+  ps->Num = inum;
+  if(Tree_Query(THEM->EdgeLoops, &ps)) {
+    return ps;
+  }
+  return NULL;
 }
 
-void add_circ(int p1, int p2, int p3, char *fich)
+SurfaceLoop *FindSurfaceLoop(int inum)
 {
-  char text[BUFFSIZE];
+  SurfaceLoop S, *ps;
+  ps = &S;
+  ps->Num = inum;
+  if(Tree_Query(THEM->SurfaceLoops, &ps)) {
+    return ps;
+  }
+  return NULL;
+}
 
-  snprintf(text, BUFFSIZE, "Circle(%d) = {%d,%d,%d};", NEWLINE(), p1, p2, p3);
-  add_infile(text, fich);
+PhysicalGroup *FindPhysicalGroup(int num, int type)
+{
+  PhysicalGroup P, *pp, **ppp;
+  pp = &P;
+  pp->Num = num;
+  pp->Typ = type;
+  if((ppp = (PhysicalGroup **) List_PQuery(THEM->PhysicalGroups, &pp,
+                                           comparePhysicalGroup))) {
+    return *ppp;
+  }
+  return NULL;
 }
 
-void add_ell(int p1, int p2, int p3, int p4, char *fich)
+void CopyVertex(Vertex * v, Vertex * vv)
 {
-  char text[BUFFSIZE];
+  vv->lc = v->lc;
+  vv->u = v->u;
+  vv->Pos.X = v->Pos.X;
+  vv->Pos.Y = v->Pos.Y;
+  vv->Pos.Z = v->Pos.Z;
+}
 
-  snprintf(text, BUFFSIZE, "Ellipse(%d) = {%d,%d,%d,%d};", NEWLINE(), p1, p2,
-           p3, p4);
-  add_infile(text, fich);
+Vertex *DuplicateVertex(Vertex * v)
+{
+  if(!v) return NULL;
+  Vertex *pv = Create_Vertex(NEWPOINT(), 0, 0, 0, 0, 0);
+  CopyVertex(v, pv);
+  Tree_Insert(THEM->Points, &pv);
+  return pv;
 }
 
-void add_spline(int N, int *p, char *fich)
+int compareAbsCurve(const void *a, const void *b)
 {
-  char text[BUFFSIZE], text2[BUFFSIZE];
+  Curve **q, **w;
 
-  snprintf(text, BUFFSIZE, "CatmullRom(%d) = {", NEWLINE());
-  for(int i = 0; i < N; i++) {
-    if(i != N - 1)
-      snprintf(text2, BUFFSIZE, "%d,", p[i]);
-    else
-      snprintf(text2, BUFFSIZE, "%d};", p[i]);
-    strncat(text, text2, BUFFSIZE-strlen(text));
+  q = (Curve **) a;
+  w = (Curve **) b;
+  return (abs((*q)->Num) - abs((*w)->Num));
+}
+
+void CopyCurve(Curve * c, Curve * cc)
+{
+  int i, j;
+  cc->Typ = c->Typ;
+  // We should not copy the meshing method : if the meshes are to be
+  // copied, the meshing algorithm will take care of it
+  // (e.g. ExtrudeMesh()).
+  //cc->Method = c->Method; 
+  for(i = 0; i < 4; i++)
+    cc->ipar[i] = c->ipar[i];
+  for(i = 0; i < 4; i++)
+    cc->dpar[i] = c->dpar[i];
+  cc->l = c->l;
+  for(i = 0; i < 4; i++)
+    for(j = 0; j < 4; j++)
+      cc->mat[i][j] = c->mat[i][j];
+  cc->beg = c->beg;
+  cc->end = c->end;
+  cc->ubeg = c->ubeg;
+  cc->uend = c->uend;
+  cc->Control_Points =
+    List_Create(List_Nbr(c->Control_Points), 1, sizeof(Vertex *));
+  List_Copy(c->Control_Points, cc->Control_Points);
+  if(c->Typ == MSH_SEGM_PARAMETRIC){
+    strcpy(cc->functu, c->functu);
+    strcpy(cc->functv, c->functv);
+    strcpy(cc->functw, c->functw);
   }
-  add_infile(text, fich);
+  End_Curve(cc);
+  Tree_Insert(THEM->Curves, &cc);
 }
 
-void add_bezier(int N, int *p, char *fich)
+Curve *DuplicateCurve(Curve * c)
 {
-  char text[BUFFSIZE], text2[BUFFSIZE];
+  Curve *pc;
+  Vertex *v, *newv;
+  pc = Create_Curve(NEWLINE(), 0, 1, NULL, NULL, -1, -1, 0., 1.);
+  CopyCurve(c, pc);
+  for(int i = 0; i < List_Nbr(c->Control_Points); i++) {
+    List_Read(pc->Control_Points, i, &v);
+    newv = DuplicateVertex(v);
+    List_Write(pc->Control_Points, i, &newv);
+  }
+  pc->beg = DuplicateVertex(c->beg);
+  pc->end = DuplicateVertex(c->end);
+  CreateReversedCurve(pc);
 
-  snprintf(text, BUFFSIZE, "Bezier(%d) = {", NEWLINE());
-  for(int i = 0; i < N; i++) {
-    if(i != N - 1)
-      snprintf(text2, BUFFSIZE, "%d,", p[i]);
-    else
-      snprintf(text2, BUFFSIZE, "%d};", p[i]);
-    strncat(text, text2, BUFFSIZE-strlen(text));
+  return pc;
+}
+
+void CopySurface(Surface * s, Surface * ss)
+{
+  int i, j;
+  ss->Typ = s->Typ;
+  // We should not copy the meshing method (or the recombination
+  // status): if the meshes are to be copied, the meshing algorithm
+  // will take care of it (e.g. ExtrudeMesh()).
+  //ss->Method = s->Method;
+  //ss->Recombine = s->Recombine;
+  //ss->RecombineAngle = s->RecombineAngle;
+  for(i = 0; i < 4; i++)
+    ss->ipar[i] = s->ipar[i];
+  ss->Nu = s->Nu;
+  ss->Nv = s->Nv;
+  ss->a = s->a;
+  ss->b = s->b;
+  ss->c = s->c;
+  ss->d = s->d;
+  for(i = 0; i < 3; i++)
+    for(j = 0; j < 3; j++)
+      ss->plan[i][j] = s->plan[i][j];
+  for(i = 0; i < 3; i++)
+    for(j = 0; j < 3; j++)
+      ss->invplan[i][j] = s->invplan[i][j];
+  ss->Generatrices =
+    List_Create(List_Nbr(s->Generatrices), 1, sizeof(Curve *));
+  List_Copy(s->Generatrices, ss->Generatrices);
+  if(s->Control_Points) {
+    ss->Control_Points =
+      List_Create(List_Nbr(s->Control_Points), 1, sizeof(Vertex *));
+    List_Copy(s->Control_Points, ss->Control_Points);
   }
-  add_infile(text, fich);
+  End_Surface(ss);
+  Tree_Insert(THEM->Surfaces, &ss);
 }
 
+Surface *DuplicateSurface(Surface * s)
+{
+  Surface *ps;
+  Curve *c, *newc;
+  Vertex *v, *newv;
+  int i;
+
+  ps = Create_Surface(NEWSURFACE(), 0);
+  CopySurface(s, ps);
+  for(i = 0; i < List_Nbr(ps->Generatrices); i++) {
+    List_Read(ps->Generatrices, i, &c);
+    newc = DuplicateCurve(c);
+    List_Write(ps->Generatrices, i, &newc);
+  }
+
+  for(i = 0; i < List_Nbr(ps->Control_Points); i++) {
+    List_Read(ps->Control_Points, i, &v);
+    newv = DuplicateVertex(v);
+    List_Write(ps->Control_Points, i, &newv);
+  }
+
+  return ps;
+}
 
-void add_bspline(int N, int *p, char *fich)
+void CopyShape(int Type, int Num, int *New)
 {
-  char text[BUFFSIZE], text2[BUFFSIZE];
+  Surface *s, *news;
+  Curve *c, *newc;
+  Vertex *v, *newv;
+
+  switch (Type) {
+  case MSH_POINT:
+    if(!(v = FindPoint(Num))) {
+      Msg(GERROR, "Unknown vertex %d", Num);
+      return;
+    }
+    newv = DuplicateVertex(v);
+    *New = newv->Num;
+    break;
+  case MSH_SEGM_LINE:
+  case MSH_SEGM_SPLN:
+  case MSH_SEGM_BSPLN:
+  case MSH_SEGM_BEZIER:
+  case MSH_SEGM_CIRC:
+  case MSH_SEGM_CIRC_INV:
+  case MSH_SEGM_ELLI:
+  case MSH_SEGM_ELLI_INV:
+  case MSH_SEGM_NURBS:
+  case MSH_SEGM_PARAMETRIC:
+    if(!(c = FindCurve(Num))) {
+      Msg(GERROR, "Unknown curve %d", Num);
+      return;
+    }
+    newc = DuplicateCurve(c);
+    *New = newc->Num;
+    break;
+  case MSH_SURF_NURBS:
+  case MSH_SURF_TRIC:
+  case MSH_SURF_REGL:
+  case MSH_SURF_PLAN:
+    if(!(s = FindSurface(Num))) {
+      Msg(GERROR, "Unknown surface %d", Num);
+      return;
+    }
+    news = DuplicateSurface(s);
+    *New = news->Num;
+    break;
+  default:
+    Msg(GERROR, "Impossible to copy entity %d (of type %d)", Num, Type);
+    break;
+  }
+}
 
-  snprintf(text, BUFFSIZE, "BSpline(%d) = {", NEWLINE());
-  for(int i = 0; i < N; i++) {
-    if(i != N - 1)
-      snprintf(text2, BUFFSIZE, "%d,", p[i]);
-    else
-      snprintf(text2, BUFFSIZE, "%d};", p[i]);
-    strncat(text, text2, BUFFSIZE-strlen(text));
+void DeletePoint(int ip)
+{
+  Vertex *v = FindPoint(ip);
+  if(!v)
+    return;
+  List_T *Curves = Tree2List(THEM->Curves);
+  for(int i = 0; i < List_Nbr(Curves); i++) {
+    Curve *c;
+    List_Read(Curves, i, &c);
+    for(int j = 0; j < List_Nbr(c->Control_Points); j++) {
+      if(!compareVertex(List_Pointer(c->Control_Points, j), &v)){
+	List_Delete(Curves);
+        return;
+      }
+    }
   }
-  add_infile(text, fich);
+  List_Delete(Curves);
+  if(v->Num == THEM->MaxPointNum)
+    THEM->MaxPointNum--;
+  Tree_Suppress(THEM->Points, &v);
+  Free_Vertex(&v, NULL);
 }
 
-void add_multline(int N, int *p, char *fich)
+void DeleteCurve(int ip)
 {
-  char text[BUFFSIZE], text2[BUFFSIZE];
-  int iseg;
+  Curve *c = FindCurve(ip);
+  if(!c)
+    return;
+  List_T *Surfs = Tree2List(THEM->Surfaces);
+  for(int i = 0; i < List_Nbr(Surfs); i++) {
+    Surface *s;
+    List_Read(Surfs, i, &s);
+    for(int j = 0; j < List_Nbr(s->Generatrices); j++) {
+      if(!compareAbsCurve(List_Pointer(s->Generatrices, j), &c)){
+	List_Delete(Surfs);
+        return;
+      }
+    }
+  }
+  List_Delete(Surfs);
+  if(c->Num == THEM->MaxLineNum)
+    THEM->MaxLineNum--;
+  Tree_Suppress(THEM->Curves, &c);
+  Free_Curve(&c, NULL);
+}
 
-  List_T *list = List_Create(N, 2, sizeof(int));
-  for(int i = 0; i < N; i++)
-    List_Add(list, &p[i]);
-  if((recognize_seg(MSH_SEGM_LINE, list, &iseg))) {
-    List_Delete(list);
+void DeleteSurface(int is)
+{
+  Surface *s = FindSurface(is);
+  if(!s)
     return;
+  List_T *Vols = Tree2List(THEM->Volumes);
+  for(int i = 0; i < List_Nbr(Vols); i++) {
+    Volume *v;
+    List_Read(Vols, i, &v);
+    for(int j = 0; j < List_Nbr(v->Surfaces); j++) {
+      if(!compareSurface(List_Pointer(v->Surfaces, j), &s)){
+	List_Delete(Vols);
+        return;
+      }
+    }
   }
-  List_Delete(list);
+  List_Delete(Vols);
+  if(s->Num == THEM->MaxSurfaceNum)
+    THEM->MaxSurfaceNum--;
+  Tree_Suppress(THEM->Surfaces, &s);
+  Free_Surface(&s, NULL);
+}
 
-  snprintf(text, BUFFSIZE, "Line(%d) = {", NEWLINE());
-  for(int i = 0; i < N; i++) {
-    if(i != N - 1)
-      snprintf(text2, BUFFSIZE, "%d,", p[i]);
-    else
-      snprintf(text2, BUFFSIZE, "%d};", p[i]);
-    strncat(text, text2, BUFFSIZE-strlen(text));
+void DeleteVolume(int iv)
+{
+  Volume *v = FindVolume(iv);
+  if(!v)
+    return;
+  if(v->Num == THEM->MaxVolumeNum)
+    THEM->MaxVolumeNum--;
+  Tree_Suppress(THEM->Volumes, &v);
+  Free_Volume(&v, NULL);
+}
+
+void DeleteShape(int Type, int Num)
+{
+  switch (Type) {
+  case MSH_POINT:
+    DeletePoint(Num);
+    break;
+  case MSH_SEGM_LINE:
+  case MSH_SEGM_SPLN:
+  case MSH_SEGM_BSPLN:
+  case MSH_SEGM_BEZIER:
+  case MSH_SEGM_CIRC:
+  case MSH_SEGM_CIRC_INV:
+  case MSH_SEGM_ELLI:
+  case MSH_SEGM_ELLI_INV:
+  case MSH_SEGM_NURBS:
+  case MSH_SEGM_PARAMETRIC:
+    DeleteCurve(Num);
+    DeleteCurve(-Num);
+    break;
+  case MSH_SURF_NURBS:
+  case MSH_SURF_TRIC:
+  case MSH_SURF_REGL:
+  case MSH_SURF_PLAN:
+    DeleteSurface(Num);
+    break;
+  case MSH_VOLUME:
+    DeleteVolume(Num);
+    break;
+  default:
+    Msg(GERROR, "Impossible to delete entity %d (of type %d)", Num, Type);
+    break;
   }
-  add_infile(text, fich);
 }
 
-void add_lineloop(List_T *list, char *fich, int *numloop)
+void ColorCurve(int ip, unsigned int col)
 {
-  char text[BUFFSIZE];
+  Curve *c = FindCurve(ip);
+  if(!c)
+    return;
+  c->Color.type = 1;
+  c->Color.mesh = c->Color.geom = col;
+}
 
-  if((recognize_loop(list, numloop)))
+void ColorSurface(int is, unsigned int col)
+{
+  Surface *s = FindSurface(is);
+  if(!s)
     return;
+  s->Color.type = 1;
+  s->Color.mesh = s->Color.geom = col;
+}
+
+void ColorVolume(int iv, unsigned int col)
+{
+  Volume *v = FindVolume(iv);
+  if(!v)
+    return;
+  v->Color.type = 1;
+  v->Color.mesh = v->Color.geom = col;
+}
+
+void ColorShape(int Type, int Num, unsigned int Color)
+{
+  switch (Type) {
+  case MSH_POINT:
+    break;
+  case MSH_SEGM_LINE:
+  case MSH_SEGM_SPLN:
+  case MSH_SEGM_BSPLN:
+  case MSH_SEGM_BEZIER:
+  case MSH_SEGM_CIRC:
+  case MSH_SEGM_CIRC_INV:
+  case MSH_SEGM_ELLI:
+  case MSH_SEGM_ELLI_INV:
+  case MSH_SEGM_NURBS:
+  case MSH_SEGM_PARAMETRIC:
+  case MSH_SEGM_DISCRETE:
+    ColorCurve(Num, Color);
+    break;
+  case MSH_SURF_NURBS:
+  case MSH_SURF_TRIC:
+  case MSH_SURF_REGL:
+  case MSH_SURF_PLAN:
+  case MSH_SURF_DISCRETE:
+    ColorSurface(Num, Color);
+    break;
+  case MSH_VOLUME:
+  case MSH_VOLUME_DISCRETE:
+    ColorVolume(Num, Color);
+    break;
+  default:
+    break;
+  }
+}
+
+void VisibilityShape(int Type, int Num, int Mode)
+{
+  Vertex *v;
+  Curve *c;
+  Surface *s;
+  Volume *V;
+
+  switch (Type) {
+  case MSH_POINT:
+    if((v = FindPoint(Num)))
+      v->Visible = Mode;
+    else
+      Msg(WARNING, "Unknown point %d (use '*' to hide/show all points)", Num);
+    break;
+  case MSH_SEGM_LINE:
+  case MSH_SEGM_SPLN:
+  case MSH_SEGM_BSPLN:
+  case MSH_SEGM_BEZIER:
+  case MSH_SEGM_CIRC:
+  case MSH_SEGM_CIRC_INV:
+  case MSH_SEGM_ELLI:
+  case MSH_SEGM_ELLI_INV:
+  case MSH_SEGM_NURBS:
+  case MSH_SEGM_PARAMETRIC:
+  case MSH_SEGM_DISCRETE:
+    if((c = FindCurve(Num)))
+      c->Visible = Mode;
+    else
+      Msg(WARNING, "Unknown line %d (use '*' to hide/show all lines)", Num);
+    break;
+  case MSH_SURF_NURBS:
+  case MSH_SURF_TRIC:
+  case MSH_SURF_REGL:
+  case MSH_SURF_PLAN:
+  case MSH_SURF_DISCRETE:
+    if((s = FindSurface(Num)))
+      s->Visible = Mode;
+    else
+      Msg(WARNING, "Unknown surface %d (use '*' to hide/show all surfaces)", Num);
+    break;
+  case MSH_VOLUME:
+  case MSH_VOLUME_DISCRETE:
+    if((V = FindVolume(Num)))
+      V->Visible = Mode;
+    else
+      Msg(WARNING, "Unknown volume %d (use '*' to hide/show all volumes)", Num);
+    break;
+  default:
+    break;
+  }
+}
+
+static int vmode;
+static void vis_nod(void *a, void *b){ (*(Vertex **) a)->Visible = vmode; }
+static void vis_cur(void *a, void *b){ (*(Curve **) a)->Visible = vmode; }
+static void vis_sur(void *a, void *b){ (*(Surface **) a)->Visible = vmode; }
+static void vis_vol(void *a, void *b){ (*(Volume **) a)->Visible = vmode; }
 
-  *numloop = NEWLINELOOP();
-  snprintf(text, BUFFSIZE, "Line Loop(%d) = {", *numloop);
-  strncat_list(text, list);
-  strncat(text, "};", BUFFSIZE-strlen(text));
-  add_infile(text, fich);
+void VisibilityShape(char *str, int Type, int Mode)
+{
+  vmode = Mode;
+
+  if(!strcmp(str, "all") || !strcmp(str, "*")) {
+    switch (Type) {
+    case 0: Tree_Action(THEM->Points, vis_nod); break;
+    case 1: Tree_Action(THEM->Curves, vis_cur); break;
+    case 2: Tree_Action(THEM->Surfaces, vis_sur); break;
+    case 3: Tree_Action(THEM->Volumes, vis_vol); break;
+    }
+  }
+  else {
+    VisibilityShape(Type, atoi(str), Mode);
+  }
 }
 
+Curve *CreateReversedCurve(Curve * c)
+{
+  Curve *newc;
+  Vertex *e1, *e2, *e3, *e4;
+  int i;
+  newc = Create_Curve(-c->Num, c->Typ, 1, NULL, NULL, -1, -1, 0., 1.);
+
+  if(List_Nbr(c->Control_Points)){
+    newc->Control_Points =
+      List_Create(List_Nbr(c->Control_Points), 1, sizeof(Vertex *));
+    if(c->Typ == MSH_SEGM_ELLI || c->Typ == MSH_SEGM_ELLI_INV) {
+      List_Read(c->Control_Points, 0, &e1);
+      List_Read(c->Control_Points, 1, &e2);
+      List_Read(c->Control_Points, 2, &e3);
+      List_Read(c->Control_Points, 3, &e4);
+      List_Add(newc->Control_Points, &e4);
+      List_Add(newc->Control_Points, &e2);
+      List_Add(newc->Control_Points, &e3);
+      List_Add(newc->Control_Points, &e1);
+    }
+    else
+      List_Invert(c->Control_Points, newc->Control_Points);
+  }
 
-void add_surf(List_T *list, char *fich, int support, int typ)
+  if(c->Typ == MSH_SEGM_NURBS && c->k) {
+    newc->k =
+      (float *)malloc((c->degre + List_Nbr(c->Control_Points) + 1) *
+                      sizeof(float));
+    for(i = 0; i < c->degre + List_Nbr(c->Control_Points) + 1; i++)
+      newc->k[c->degre + List_Nbr(c->Control_Points) - i] = c->k[i];
+  }
+
+  if(c->Typ == MSH_SEGM_CIRC)
+    newc->Typ = MSH_SEGM_CIRC_INV;
+  if(c->Typ == MSH_SEGM_CIRC_INV)
+    newc->Typ = MSH_SEGM_CIRC;
+  if(c->Typ == MSH_SEGM_ELLI)
+    newc->Typ = MSH_SEGM_ELLI_INV;
+  if(c->Typ == MSH_SEGM_ELLI_INV)
+    newc->Typ = MSH_SEGM_ELLI;
+  newc->Method = c->Method;
+  newc->degre = c->degre;
+  newc->beg = c->end;
+  newc->end = c->beg;
+  newc->ubeg = 1. - c->uend;
+  newc->uend = 1. - c->ubeg;
+  End_Curve(newc);
+
+  Curve **pc;
+
+  if((pc = (Curve **) Tree_PQuery(THEM->Curves, &newc))) {
+    Free_Curve(&newc, NULL);
+    return *pc;
+  }
+  else{
+    Tree_Add(THEM->Curves, &newc);
+    return newc;
+  }
+}
+
+void ModifyLcPoint(int ip, double lc)
 {
-  char text[BUFFSIZE];
+  Vertex *v = FindPoint(ip);
+  if(v)
+    v->lc = lc;
+}
 
-  if(typ == 1) {
-    snprintf(text, BUFFSIZE, "Ruled Surface(%d) = {", NEWSURFACE());
+int recognize_seg(int typ, List_T * liste, int *seg)
+{
+  int i, beg, end;
+  Curve *pc;
+
+  List_T *temp = Tree2List(THEM->Curves);
+  List_Read(liste, 0, &beg);
+  List_Read(liste, List_Nbr(liste) - 1, &end);
+  for(i = 0; i < List_Nbr(temp); i++) {
+    List_Read(temp, i, &pc);
+    if(pc->Typ == typ && pc->beg->Num == beg && pc->end->Num == end) {
+      List_Delete(temp);
+      *seg = pc->Num;
+      return 1;
+    }
   }
-  else if(typ == 2) {
-    snprintf(text, BUFFSIZE, "Plane Surface(%d) = {", NEWSURFACE());
+  List_Delete(temp);
+  return 0;
+}
+
+int recognize_loop(List_T * liste, int *loop)
+{
+  int i, res;
+  EdgeLoop *pe;
+
+  res = 0;
+  *loop = 0;
+  List_T *temp = Tree2List(THEM->EdgeLoops);
+  for(i = 0; i < List_Nbr(temp); i++) {
+    List_Read(temp, i, &pe);
+    if(!compare2Lists(pe->Curves, liste, fcmp_absint)) {
+      res = 1;
+      *loop = pe->Num;
+      break;
+    }
+  }
+  List_Delete(temp);
+  return res;
+}
+
+int recognize_surfloop(List_T * liste, int *loop)
+{
+  int i, res;
+  EdgeLoop *pe;
+
+  res = 0;
+  *loop = 0;
+  List_T *temp = Tree2List(THEM->SurfaceLoops);
+  for(i = 0; i < List_Nbr(temp); i++) {
+    List_Read(temp, i, &pe);
+    if(!compare2Lists(pe->Curves, liste, fcmp_absint)) {
+      res = 1;
+      *loop = pe->Num;
+      break;
+    }
+  }
+  List_Delete(temp);
+  return res;
+}
+
+// Linear applications
+
+void SetTranslationMatrix(double matrix[4][4], double T[3])
+{
+  int i, j;
+
+  for(i = 0; i < 4; i++) {
+    for(j = 0; j < 4; j++) {
+      matrix[i][j] = (i == j) ? 1.0 : 0.0;
+    }
+  }
+  for(i = 0; i < 3; i++)
+    matrix[i][3] = T[i];
+}
+
+void SetSymmetryMatrix(double matrix[4][4], double A, double B, double C,
+                       double D)
+{
+  double F = -2.0 / (A * A + B * B + C * C);
+  matrix[0][0] = 1. + A * A * F;
+  matrix[0][1] = A * B * F;
+  matrix[0][2] = A * C * F;
+  matrix[0][3] = A * D * F;
+  matrix[1][0] = A * B * F;
+  matrix[1][1] = 1. + B * B * F;
+  matrix[1][2] = B * C * F;
+  matrix[1][3] = B * D * F;
+  matrix[2][0] = A * C * F;
+  matrix[2][1] = B * C * F;
+  matrix[2][2] = 1. + C * C * F;
+  matrix[2][3] = C * D * F;
+  matrix[3][0] = B * C * F;
+  matrix[3][1] = 0.0;
+  matrix[3][2] = 0.0;
+  matrix[3][3] = 1.0;
+}
+
+void SetDilatationMatrix(double matrix[4][4], double T[3], double A)
+{
+  matrix[0][0] = A;
+  matrix[0][1] = 0.0;
+  matrix[0][2] = 0.0;
+  matrix[0][3] = T[0] * (1.0 - A);
+  matrix[1][0] = 0.0;
+  matrix[1][1] = A;
+  matrix[1][2] = 0.0;
+  matrix[1][3] = T[1] * (1.0 - A);
+  matrix[2][0] = 0.0;
+  matrix[2][1] = 0.0;
+  matrix[2][2] = A;
+  matrix[2][3] = T[2] * (1.0 - A);
+  matrix[3][0] = 0.0;
+  matrix[3][1] = 0.0;
+  matrix[3][2] = 0.0;
+  matrix[3][3] = 1.0;
+}
+
+static void GramSchmidt(double v1[3], double v2[3], double v3[3])
+{
+  double tmp[3];
+  norme(v1);
+  prodve(v3, v1, tmp);
+  norme(tmp);
+  v2[0] = tmp[0];
+  v2[1] = tmp[1];
+  v2[2] = tmp[2];
+  prodve(v1, v2, v3);
+  norme(v3);
+}
+
+void SetRotationMatrix(double matrix[4][4], double Axe[3], double alpha)
+{
+  double t1[3], t2[3];
+  if(Axe[0] != 0.0) {
+    t1[0] = 0.0;
+    t1[1] = 1.0;
+    t1[2] = 0.0;
+    t2[0] = 0.0;
+    t2[1] = 0.0;
+    t2[2] = 1.0;
+  }
+  else if(Axe[1] != 0.0) {
+    t1[0] = 1.0;
+    t1[1] = 0.0;
+    t1[2] = 0.0;
+    t2[0] = 0.0;
+    t2[1] = 0.0;
+    t2[2] = 1.0;
   }
   else {
-    snprintf(text, BUFFSIZE, "Trimmed Surface(%d) = %d {", NEWSURFACE(), support);
+    t1[0] = 1.0;
+    t1[1] = 0.0;
+    t1[2] = 0.0;
+    t2[0] = 0.0;
+    t2[1] = 1.0;
+    t2[2] = 0.0;
+  }
+  GramSchmidt(Axe, t1, t2);
+  double rot[3][3], plan[3][3], invplan[3][3];
+  plan[0][0] = Axe[0];
+  plan[0][1] = Axe[1];
+  plan[0][2] = Axe[2];
+  plan[1][0] = t1[0];
+  plan[1][1] = t1[1];
+  plan[1][2] = t1[2];
+  plan[2][0] = t2[0];
+  plan[2][1] = t2[1];
+  plan[2][2] = t2[2];
+  rot[2][2] = cos(alpha);
+  rot[2][1] = sin(alpha);
+  rot[2][0] = 0.;
+  rot[1][2] = -sin(alpha);
+  rot[1][1] = cos(alpha);
+  rot[1][0] = 0.;
+  rot[0][2] = 0.;
+  rot[0][1] = 0.;
+  rot[0][0] = 1.;
+  int i, j, k;
+  for(i = 0; i < 3; i++)
+    for(j = 0; j < 3; j++)
+      invplan[i][j] = plan[j][i];
+  double interm[3][3];
+  for(i = 0; i < 3; i++)
+    for(j = 0; j < 3; j++) {
+      interm[i][j] = 0.0;
+      for(k = 0; k < 3; k++)
+        interm[i][j] += invplan[i][k] * rot[k][j];
+    }
+  for(i = 0; i < 4; i++)
+    for(j = 0; j < 4; j++)
+      matrix[i][j] = 0.0;
+  for(i = 0; i < 3; i++)
+    for(j = 0; j < 3; j++) {
+      for(k = 0; k < 3; k++)
+        matrix[i][j] += interm[i][k] * plan[k][j];
+    }
+  matrix[3][3] = 1.0;
+}
+
+static void vecmat4x4(double mat[4][4], double vec[4], double res[4])
+{
+  int i, j;
+  for(i = 0; i < 4; i++) {
+    res[i] = 0.0;
+    for(j = 0; j < 4; j++) {
+      res[i] += mat[i][j] * vec[j];
+    }
+  }
+}
+
+void printCurve(Curve * c)
+{
+  Vertex *v;
+  int N = List_Nbr(c->Control_Points);
+  Msg(DEBUG, "Curve %d %d cp (%d->%d)", c->Num, N, c->beg->Num, c->end->Num);
+  for(int i = 0; i < N; i++) {
+    List_Read(c->Control_Points, i, &v);
+    Msg(DEBUG, "Vertex %d (%g,%g,%g,%g)", v->Num, v->Pos.X, v->Pos.Y,
+        v->Pos.Z, v->lc);
   }
-  strncat_list(text, list);
-  strncat(text, "};", BUFFSIZE-strlen(text));
-  add_infile(text, fich);
 }
 
-void add_surfloop(List_T *list, char *fich, int *numvol)
+void printSurface(Surface * s)
 {
-  char text[BUFFSIZE];
+  Curve *c;
+  int N = List_Nbr(s->Generatrices);
 
-  if((recognize_surfloop(list, numvol)))
+  Msg(DEBUG, "Surface %d, %d generatrices", s->Num, N);
+  for(int i = 0; i < N; i++) {
+    List_Read(s->Generatrices, i, &c);
+    printCurve(c);
+  }
+}
+
+void ApplyTransformationToPoint(double matrix[4][4], Vertex * v,
+				bool end_curve_surface=false)
+{
+  double pos[4], vec[4];
+
+  if(!ListOfTransformedPoints)
+    ListOfTransformedPoints = List_Create(50, 50, sizeof(int));
+
+  if(!List_Search(ListOfTransformedPoints, &v->Num, fcmp_absint)) {
+    List_Add(ListOfTransformedPoints, &v->Num);
+  }
+  else
     return;
 
-  *numvol = NEWSURFACELOOP();
-  snprintf(text, BUFFSIZE, "Surface Loop(%d) = {", *numvol);
-  strncat_list(text, list);
-  strncat(text, "};", BUFFSIZE-strlen(text));
-  add_infile(text, fich);
+  vec[0] = v->Pos.X;
+  vec[1] = v->Pos.Y;
+  vec[2] = v->Pos.Z;
+  vec[3] = v->w;
+  vecmat4x4(matrix, vec, pos);
+  v->Pos.X = pos[0];
+  v->Pos.Y = pos[1];
+  v->Pos.Z = pos[2];
+  v->w = pos[3];
+
+  // Warning: in theory we should always redo these checks if
+  // end_curve_surface is true; but in practice this is so slow for
+  // big models that we need to provide a way to bypass it (which is
+  // OK if the guy who builds the geometry knowns what he's
+  // doing). Instead of adding one more option, let's just bypass all
+  // the checks if auto_coherence==0...
+  if(CTX.geom.auto_coherence && end_curve_surface){
+    List_T *All = Tree2List(THEM->Curves);
+    for(int i = 0; i < List_Nbr(All); i++) {
+      Curve *c;
+      List_Read(All, i, &c);
+      for(int j = 0; j < List_Nbr(c->Control_Points); j++) {
+	Vertex *pv = *(Vertex **) List_Pointer(c->Control_Points, j);
+	if(pv->Num == v->Num){
+	  End_Curve(c);
+	  break;
+	}
+      }
+    }
+    List_Delete(All);
+    All = Tree2List(THEM->Surfaces);
+    for(int i = 0; i < List_Nbr(All); i++) {
+      Surface *s;
+      List_Read(All, i, &s);
+      for(int j = 0; j < List_Nbr(s->Control_Points); j++) {
+	Vertex *pv = *(Vertex **) List_Pointer(s->Control_Points, j);
+	if(pv->Num == v->Num){
+	  End_Surface(s);
+	  break;
+	}
+      }
+    }
+    List_Delete(All);
+  }
 }
 
-void add_vol(List_T *list, char *fich)
+void ApplyTransformationToCurve(double matrix[4][4], Curve * c)
 {
-  char text[BUFFSIZE];
+  Vertex *v;
 
-  snprintf(text, BUFFSIZE, "Volume(%d) = {", NEWVOLUME());
-  strncat_list(text, list);
-  strncat(text, "};", BUFFSIZE-strlen(text));
-  add_infile(text, fich);
+  if(!c->beg || !c->end){
+    Msg(GERROR, "Cannot transform curve with no begin/end points");
+    return;
+  }
+
+  ApplyTransformationToPoint(matrix, c->beg);
+  ApplyTransformationToPoint(matrix, c->end);
+
+  for(int i = 0; i < List_Nbr(c->Control_Points); i++) {
+    List_Read(c->Control_Points, i, &v);
+    ApplyTransformationToPoint(matrix, v);
+  }
+  End_Curve(c);
 }
 
-void add_trsfvol(int N, int *l, char *fich)
+void ApplyTransformationToSurface(double matrix[4][4], Surface * s)
 {
-  char text[BUFFSIZE], text2[BUFFSIZE];
+  Curve *c;
+  Vertex *v;
+  int i;
+
+  for(i = 0; i < List_Nbr(s->Generatrices); i++) {
+    List_Read(s->Generatrices, i, &c);
+    // FIXME: this fixes benchmarks/bug/transfo_neg_curves.geo, but is
+    // it the correct fix?
+    //ApplyTransformationToCurve(matrix, c);
+    Curve *cc = FindCurve(abs(c->Num));
+    ApplyTransformationToCurve(matrix, cc);
+  }
+  for(i = 0; i < List_Nbr(s->Control_Points); i++) {
+    List_Read(s->Control_Points, i, &v);
+    ApplyTransformationToPoint(matrix, v);
+  }
+  End_Surface(s);
+}
 
-  snprintf(text, BUFFSIZE, "Transfinite Volume{%d} = {", l[0]);
-  for(int i = 1; i < N; i++) {
-    if(i == 1)
-      snprintf(text2, BUFFSIZE, "%d", l[i]);
-    else
-      snprintf(text2, BUFFSIZE, ",%d", l[i]);
-    strncat(text, text2, BUFFSIZE-strlen(text));
+void ApplicationOnShapes(double matrix[4][4], List_T * ListShapes)
+{
+  int i;
+  Shape O;
+  Vertex *v;
+  Curve *c;
+  Surface *s;
+
+  List_Reset(ListOfTransformedPoints);
+
+  for(i = 0; i < List_Nbr(ListShapes); i++) {
+    List_Read(ListShapes, i, &O);
+    switch (O.Type) {
+    case MSH_POINT:
+      v = FindPoint(O.Num);
+      if(v)
+        ApplyTransformationToPoint(matrix, v, true);
+      else
+        Msg(GERROR, "Unknown point %d", O.Num);
+      break;
+    case MSH_SEGM_LINE:
+    case MSH_SEGM_SPLN:
+    case MSH_SEGM_BSPLN:
+    case MSH_SEGM_BEZIER:
+    case MSH_SEGM_CIRC:
+    case MSH_SEGM_CIRC_INV:
+    case MSH_SEGM_ELLI:
+    case MSH_SEGM_ELLI_INV:
+    case MSH_SEGM_NURBS:
+    case MSH_SEGM_PARAMETRIC:
+      c = FindCurve(O.Num);
+      if(c)
+        ApplyTransformationToCurve(matrix, c);
+      else
+        Msg(GERROR, "Unknown curve %d", O.Num);
+      break;
+    case MSH_SURF_NURBS:
+    case MSH_SURF_REGL:
+    case MSH_SURF_TRIC:
+    case MSH_SURF_PLAN:
+      s = FindSurface(O.Num);
+      if(s)
+        ApplyTransformationToSurface(matrix, s);
+      else
+        Msg(GERROR, "Unknown surface %d", O.Num);
+      break;
+    default:
+      Msg(GERROR, "Impossible to transform entity %d (of type %d)", O.Num,
+          O.Type);
+      break;
+    }
   }
-  snprintf(text2, BUFFSIZE, "};");
-  strncat(text, text2, BUFFSIZE-strlen(text));
-  add_infile(text, fich);
+
+  List_Reset(ListOfTransformedPoints);
 }
 
-int add_physical(List_T *list, char *fich, int type)
+void TranslateShapes(double X, double Y, double Z,
+                     List_T * ListShapes, int final)
 {
-  char text[BUFFSIZE];
-  int num = NEWPHYSICAL();
-  
+  double T[3], matrix[4][4];
+
+  T[0] = X;
+  T[1] = Y;
+  T[2] = Z;
+  SetTranslationMatrix(matrix, T);
+  ApplicationOnShapes(matrix, ListShapes);
+
+  if(CTX.geom.auto_coherence && final)
+    ReplaceAllDuplicates();
+}
+
+void DilatShapes(double X, double Y, double Z, double A,
+                 List_T * ListShapes, int final)
+{
+  double T[3], matrix[4][4];
+
+  T[0] = X;
+  T[1] = Y;
+  T[2] = Z;
+  SetDilatationMatrix(matrix, T, A);
+  ApplicationOnShapes(matrix, ListShapes);
+
+  if(CTX.geom.auto_coherence && final)
+    ReplaceAllDuplicates();
+}
+
+void RotateShapes(double Ax, double Ay, double Az,
+                  double Px, double Py, double Pz,
+                  double alpha, List_T * ListShapes, int final)
+{
+  double A[3], T[3], matrix[4][4];
+
+  T[0] = -Px;
+  T[1] = -Py;
+  T[2] = -Pz;
+  SetTranslationMatrix(matrix, T);
+  ApplicationOnShapes(matrix, ListShapes);
+
+  A[0] = Ax;
+  A[1] = Ay;
+  A[2] = Az;
+  SetRotationMatrix(matrix, A, alpha);
+  ApplicationOnShapes(matrix, ListShapes);
+
+  T[0] = Px;
+  T[1] = Py;
+  T[2] = Pz;
+  SetTranslationMatrix(matrix, T);
+  ApplicationOnShapes(matrix, ListShapes);
+
+  if(CTX.geom.auto_coherence && final)
+    ReplaceAllDuplicates();
+}
+
+void SymmetryShapes(double A, double B, double C,
+                    double D, List_T * ListShapes, int final)
+{
+  double matrix[4][4];
+
+  SetSymmetryMatrix(matrix, A, B, C, D);
+  ApplicationOnShapes(matrix, ListShapes);
+
+  if(CTX.geom.auto_coherence && final)
+    ReplaceAllDuplicates();
+}
+
+
+// Extrusion routines
+
+void ProtudeXYZ(double &x, double &y, double &z, ExtrudeParams * e)
+{
+  double matrix[4][4];
+  double T[3];
+  Vertex v(x, y, z);
+
+  T[0] = -e->geo.pt[0];
+  T[1] = -e->geo.pt[1];
+  T[2] = -e->geo.pt[2];
+  SetTranslationMatrix(matrix, T);
+  List_Reset(ListOfTransformedPoints);
+  ApplyTransformationToPoint(matrix, &v);
+
+  SetRotationMatrix(matrix, e->geo.axe, e->geo.angle);
+  List_Reset(ListOfTransformedPoints);
+  ApplyTransformationToPoint(matrix, &v);
+
+  T[0] = -T[0];
+  T[1] = -T[1];
+  T[2] = -T[2];
+  SetTranslationMatrix(matrix, T);
+  List_Reset(ListOfTransformedPoints);
+  ApplyTransformationToPoint(matrix, &v);
+
+  x = v.Pos.X;
+  y = v.Pos.Y;
+  z = v.Pos.Z;
+
+  List_Reset(ListOfTransformedPoints);
+}
+
+int Extrude_ProtudePoint(int type, int ip,
+			 double T0, double T1, double T2,
+			 double A0, double A1, double A2,
+			 double X0, double X1, double X2, double alpha,
+			 Curve ** pc, Curve ** prc, int final, 
+			 ExtrudeParams * e)
+{
+  double matrix[4][4], T[3], Ax[3], d;
+  Vertex V, *pv, *newp, *chapeau;
+  Curve *c;
+  int i;
+
+  pv = &V;
+  pv->Num = ip;
+  *pc = *prc = NULL;
+  if(!Tree_Query(THEM->Points, &pv))
+    return 0;
+
+  Msg(DEBUG, "Extrude Point %d", ip);
+
+  chapeau = DuplicateVertex(pv);
+
   switch (type) {
-  case ENT_POINT:
-    snprintf(text, BUFFSIZE, "Physical Point(%d) = {", num);
+
+  case TRANSLATE:
+    T[0] = T0;
+    T[1] = T1;
+    T[2] = T2;
+    SetTranslationMatrix(matrix, T);
+    List_Reset(ListOfTransformedPoints);
+    ApplyTransformationToPoint(matrix, chapeau);
+
+    if(!comparePosition(&pv, &chapeau))
+      return pv->Num;
+    c = Create_Curve(NEWLINE(), MSH_SEGM_LINE, 1, NULL, NULL, -1, -1, 0., 1.);
+    c->Control_Points = List_Create(2, 1, sizeof(Vertex *));
+    c->Extrude = new ExtrudeParams;
+    c->Extrude->fill(type, T0, T1, T2, A0, A1, A2, X0, X1, X2, alpha);
+    c->Extrude->useZonLayer(final);
+    if(e)
+      c->Extrude->mesh = e->mesh;
+
+    List_Add(c->Control_Points, &pv);
+    List_Add(c->Control_Points, &chapeau);
+    c->beg = pv;
+    c->end = chapeau;
+    break;
+
+  case ROTATE:
+    T[0] = -X0;
+    T[1] = -X1;
+    T[2] = -X2;
+    SetTranslationMatrix(matrix, T);
+    List_Reset(ListOfTransformedPoints);
+    ApplyTransformationToPoint(matrix, chapeau);
+
+    Ax[0] = A0;
+    Ax[1] = A1;
+    Ax[2] = A2;
+    SetRotationMatrix(matrix, Ax, alpha);
+    List_Reset(ListOfTransformedPoints);
+    ApplyTransformationToPoint(matrix, chapeau);
+
+    T[0] = X0;
+    T[1] = X1;
+    T[2] = X2;
+    SetTranslationMatrix(matrix, T);
+    List_Reset(ListOfTransformedPoints);
+    ApplyTransformationToPoint(matrix, chapeau);
+
+    if(!comparePosition(&pv, &chapeau))
+      return pv->Num;
+    c = Create_Curve(NEWLINE(), MSH_SEGM_CIRC, 1, NULL, NULL, -1, -1, 0., 1.);
+    c->Control_Points = List_Create(3, 1, sizeof(Vertex *));
+    c->Extrude = new ExtrudeParams;
+    c->Extrude->fill(type, T0, T1, T2, A0, A1, A2, X0, X1, X2, alpha);
+    if(e)
+      c->Extrude->mesh = e->mesh;
+    List_Add(c->Control_Points, &pv);
+    // compute circle center
+    newp = DuplicateVertex(pv);
+    Ax[0] = A0;
+    Ax[1] = A1;
+    Ax[2] = A2;
+    norme(Ax);
+    T[0] = pv->Pos.X - X0;
+    T[1] = pv->Pos.Y - X1;
+    T[2] = pv->Pos.Z - X2;
+    prosca(T, Ax, &d);
+    newp->Pos.X = X0 + d * Ax[0];
+    newp->Pos.Y = X1 + d * Ax[1]; 
+    newp->Pos.Z = X2 + d * Ax[2]; 
+    List_Add(c->Control_Points, &newp);
+    List_Add(c->Control_Points, &chapeau);
+    c->beg = pv;
+    c->end = chapeau;
+    break;
+
+  case TRANSLATE_ROTATE:
+    d = CTX.geom.extrude_spline_points;
+    d = d ? d : 1;
+    c = Create_Curve(NEWLINE(), MSH_SEGM_SPLN, 1, NULL, NULL, -1, -1, 0., 1.);
+    c->Control_Points =
+      List_Create(CTX.geom.extrude_spline_points + 1, 1, sizeof(Vertex *));
+    c->Extrude = new ExtrudeParams;
+    c->Extrude->fill(type, T0, T1, T2, A0, A1, A2, X0, X1, X2, alpha);
+    if(e)
+      c->Extrude->mesh = e->mesh;
+    List_Add(c->Control_Points, &pv);
+    c->beg = pv;
+    for(i = 0; i < CTX.geom.extrude_spline_points; i++) {
+      if(i)
+        chapeau = DuplicateVertex(chapeau);
+
+      T[0] = -X0;
+      T[1] = -X1;
+      T[2] = -X2;
+      SetTranslationMatrix(matrix, T);
+      List_Reset(ListOfTransformedPoints);
+      ApplyTransformationToPoint(matrix, chapeau);
+
+      Ax[0] = A0;
+      Ax[1] = A1;
+      Ax[2] = A2;
+      SetRotationMatrix(matrix, Ax, alpha / d);
+      List_Reset(ListOfTransformedPoints);
+      ApplyTransformationToPoint(matrix, chapeau);
+
+      T[0] = X0;
+      T[1] = X1;
+      T[2] = X2;
+      SetTranslationMatrix(matrix, T);
+      List_Reset(ListOfTransformedPoints);
+      ApplyTransformationToPoint(matrix, chapeau);
+
+      T[0] = T0 / d;
+      T[1] = T1 / d;
+      T[2] = T2 / d;
+      SetTranslationMatrix(matrix, T);
+      List_Reset(ListOfTransformedPoints);
+      ApplyTransformationToPoint(matrix, chapeau);
+
+      List_Add(c->Control_Points, &chapeau);
+    }
+    c->end = chapeau;
     break;
-  case ENT_LINE:
-    snprintf(text, BUFFSIZE, "Physical Line(%d) = {", num);
+
+  default:
+    Msg(GERROR, "Unknown extrusion type");
+    return pv->Num;
+  }
+
+  End_Curve(c);
+  Tree_Add(THEM->Curves, &c);
+  CreateReversedCurve(c);
+  *pc = c;
+  *prc = FindCurve(-c->Num);
+
+  List_Reset(ListOfTransformedPoints);
+
+  if(CTX.geom.auto_coherence && final)
+    ReplaceAllDuplicates();
+
+  return chapeau->Num;
+}
+
+int Extrude_ProtudeCurve(int type, int ic,
+			 double T0, double T1, double T2,
+			 double A0, double A1, double A2,
+			 double X0, double X1, double X2, double alpha,
+			 Surface ** ps, int final, 
+			 ExtrudeParams * e)
+{
+  double matrix[4][4], T[3], Ax[3];
+  Curve *CurveBeg, *CurveEnd;
+  Curve *ReverseChapeau, *ReverseBeg, *ReverseEnd;
+  Curve *pc, *revpc, *chapeau;
+  Surface *s;
+
+  pc = FindCurve(ic);
+  revpc = FindCurve(-ic);
+  *ps = NULL;
+
+  if(!pc || !revpc){
+    return 0;
+  }
+
+  if(!pc->beg || !pc->end){
+    Msg(GERROR, "Cannot extrude curve with no begin/end points");
+    return 0;
+  }
+
+  Msg(DEBUG, "Extrude Curve %d", ic);
+
+  chapeau = DuplicateCurve(pc);
+
+  chapeau->Extrude = new ExtrudeParams(COPIED_ENTITY);
+  chapeau->Extrude->fill(type, T0, T1, T2, A0, A1, A2, X0, X1, X2, alpha);
+  chapeau->Extrude->geo.Source = pc->Num;
+  if(e)
+    chapeau->Extrude->mesh = e->mesh;
+
+  switch (type) {
+  case TRANSLATE:
+    T[0] = T0;
+    T[1] = T1;
+    T[2] = T2;
+    SetTranslationMatrix(matrix, T);
+    List_Reset(ListOfTransformedPoints);
+    ApplyTransformationToCurve(matrix, chapeau);
     break;
-  case ENT_SURFACE:
-    snprintf(text, BUFFSIZE, "Physical Surface(%d) = {", num);
+  case ROTATE:
+    T[0] = -X0;
+    T[1] = -X1;
+    T[2] = -X2;
+    SetTranslationMatrix(matrix, T);
+    List_Reset(ListOfTransformedPoints);
+    ApplyTransformationToCurve(matrix, chapeau);
+
+    Ax[0] = A0;
+    Ax[1] = A1;
+    Ax[2] = A2;
+    SetRotationMatrix(matrix, Ax, alpha);
+    List_Reset(ListOfTransformedPoints);
+    ApplyTransformationToCurve(matrix, chapeau);
+
+    T[0] = X0;
+    T[1] = X1;
+    T[2] = X2;
+    SetTranslationMatrix(matrix, T);
+    List_Reset(ListOfTransformedPoints);
+    ApplyTransformationToCurve(matrix, chapeau);
     break;
-  case ENT_VOLUME:
-    snprintf(text, BUFFSIZE, "Physical Volume(%d) = {", num);
+  case TRANSLATE_ROTATE:
+    T[0] = -X0;
+    T[1] = -X1;
+    T[2] = -X2;
+    SetTranslationMatrix(matrix, T);
+    List_Reset(ListOfTransformedPoints);
+    ApplyTransformationToCurve(matrix, chapeau);
+
+    Ax[0] = A0;
+    Ax[1] = A1;
+    Ax[2] = A2;
+    SetRotationMatrix(matrix, Ax, alpha);
+    List_Reset(ListOfTransformedPoints);
+    ApplyTransformationToCurve(matrix, chapeau);
+
+    T[0] = X0;
+    T[1] = X1;
+    T[2] = X2;
+    SetTranslationMatrix(matrix, T);
+    List_Reset(ListOfTransformedPoints);
+    ApplyTransformationToCurve(matrix, chapeau);
+
+    T[0] = T0;
+    T[1] = T1;
+    T[2] = T2;
+    SetTranslationMatrix(matrix, T);
+    List_Reset(ListOfTransformedPoints);
+    ApplyTransformationToCurve(matrix, chapeau);
     break;
+  default:
+    Msg(GERROR, "Unknown extrusion type");
+    return pc->Num;
   }
 
-  strncat_list(text, list);
-  strncat(text, "};", BUFFSIZE-strlen(text));
-  add_infile(text, fich);
+  Extrude_ProtudePoint(type, pc->beg->Num, T0, T1, T2,
+                       A0, A1, A2, X0, X1, X2, alpha,
+                       &CurveBeg, &ReverseBeg, 0, e);
+  Extrude_ProtudePoint(type, pc->end->Num, T0, T1, T2,
+                       A0, A1, A2, X0, X1, X2, alpha,
+                       &CurveEnd, &ReverseEnd, 0, e);
+
+  if(!CurveBeg && !CurveEnd){
+    return pc->Num;
+  }
+
+  if(!CurveBeg || !CurveEnd)
+    s = Create_Surface(NEWSURFACE(), MSH_SURF_TRIC);
+  else
+    s = Create_Surface(NEWSURFACE(), MSH_SURF_REGL);
+
+  s->Generatrices = List_Create(4, 1, sizeof(Curve *));
+  s->Extrude = new ExtrudeParams;
+  s->Extrude->fill(type, T0, T1, T2, A0, A1, A2, X0, X1, X2, alpha);
+  s->Extrude->useZonLayer(final);
+  s->Extrude->geo.Source = pc->Num;
+  if(e)
+    s->Extrude->mesh = e->mesh;
+
+  ReverseChapeau = FindCurve(-chapeau->Num);
+
+  if(!CurveBeg) {
+    List_Add(s->Generatrices, &pc);
+    List_Add(s->Generatrices, &CurveEnd);
+    List_Add(s->Generatrices, &ReverseChapeau);
+  }
+  else if(!CurveEnd) {
+    List_Add(s->Generatrices, &ReverseChapeau);
+    List_Add(s->Generatrices, &ReverseBeg);
+    List_Add(s->Generatrices, &pc);
+  }
+  else {
+    List_Add(s->Generatrices, &pc);
+    List_Add(s->Generatrices, &CurveEnd);
+    List_Add(s->Generatrices, &ReverseChapeau);
+    List_Add(s->Generatrices, &ReverseBeg);
+  }
+
+  End_Surface(s);
+  Tree_Add(THEM->Surfaces, &s);
+
+  List_Reset(ListOfTransformedPoints);
+
+  *ps = s;
+
+  if(CTX.geom.auto_coherence && final)
+    ReplaceAllDuplicates();
+
+  return chapeau->Num;
+}
+
+int Extrude_ProtudeSurface(int type, int is,
+			   double T0, double T1, double T2,
+			   double A0, double A1, double A2,
+			   double X0, double X1, double X2, double alpha,
+			   Volume **pv, ExtrudeParams * e)
+{
+  double matrix[4][4], T[3], Ax[3];
+  Curve *c, *c2;
+  int i;
+  Surface *s, *ps, *chapeau;
+
+  *pv = NULL;
+
+  if(!(ps = FindSurface(is)))
+    return 0;
+
+  Msg(DEBUG, "Extrude Surface %d", is);
+
+  chapeau = DuplicateSurface(ps);
+
+  chapeau->Extrude = new ExtrudeParams(COPIED_ENTITY);
+  chapeau->Extrude->fill(type, T0, T1, T2, A0, A1, A2, X0, X1, X2, alpha);
+  chapeau->Extrude->geo.Source = ps->Num;
+  if(e)
+    chapeau->Extrude->mesh = e->mesh;
+
+  for(i = 0; i < List_Nbr(chapeau->Generatrices); i++) {
+    List_Read(ps->Generatrices, i, &c2);
+    List_Read(chapeau->Generatrices, i, &c);
+    if(c->Num < 0)
+      if(!(c = FindCurve(-c->Num))) {
+        Msg(GERROR, "Unknown curve %d", -c->Num);
+        return ps->Num;
+      }
+    c->Extrude = new ExtrudeParams(COPIED_ENTITY);
+    c->Extrude->fill(type, T0, T1, T2, A0, A1, A2, X0, X1, X2, alpha);
+    //pas de abs()! il faut le signe pour copy_mesh dans ExtrudeMesh
+    c->Extrude->geo.Source = c2->Num;
+    if(e)
+      c->Extrude->mesh = e->mesh;
+  }
+
+  // FIXME: this is a really ugly hack for backward compatibility, so
+  // that we don't screw up the old .geo files too much. (Before
+  // version 1.54, we didn't always create new volumes during "Extrude
+  // Surface". Now we do, but with "CTX.geom.old_newreg==1", this
+  // bumps the NEWREG() counter, and thus changes the whole automatic
+  // numbering sequence.) So we locally force old_newreg to 0: in most
+  // cases, since we define points, curves, etc., before defining
+  // volumes, the NEWVOLUME() call below will return a fairly low
+  // number, that will not interfere with the other numbers...
+  int tmp = CTX.geom.old_newreg;
+  CTX.geom.old_newreg = 0;
+  Volume *v = Create_Volume(NEWVOLUME(), MSH_VOLUME);
+  CTX.geom.old_newreg = tmp;
+
+  v->Extrude = new ExtrudeParams;
+  v->Extrude->fill(type, T0, T1, T2, A0, A1, A2, X0, X1, X2, alpha);
+  v->Extrude->geo.Source = is;
+  if(e)
+    v->Extrude->mesh = e->mesh;
+  int ori = -1;
+  List_Add(v->Surfaces, &ps);
+  List_Add(v->SurfacesOrientations, &ori);
+  ori = 1;
+  List_Add(v->Surfaces, &chapeau);
+  List_Add(v->SurfacesOrientations, &ori);
+
+  for(i = 0; i < List_Nbr(ps->Generatrices); i++) {
+    List_Read(ps->Generatrices, i, &c);
+    Extrude_ProtudeCurve(type, c->Num, T0, T1, T2, A0, A1, A2, X0, X1, X2,
+			 alpha, &s, 0, e);
+    if(s){
+      if(c < 0)
+	ori = -1;
+      else
+	ori = 1;
+      List_Add(v->Surfaces, &s);
+      List_Add(v->SurfacesOrientations, &ori);
+    }
+  }
+
+  switch (type) {
+  case TRANSLATE:
+    T[0] = T0;
+    T[1] = T1;
+    T[2] = T2;
+    SetTranslationMatrix(matrix, T);
+    List_Reset(ListOfTransformedPoints);
+    ApplyTransformationToSurface(matrix, chapeau);
+    break;
+  case ROTATE:
+    T[0] = -X0;
+    T[1] = -X1;
+    T[2] = -X2;
+    SetTranslationMatrix(matrix, T);
+    List_Reset(ListOfTransformedPoints);
+    ApplyTransformationToSurface(matrix, chapeau);
+
+    Ax[0] = A0;
+    Ax[1] = A1;
+    Ax[2] = A2;
+    SetRotationMatrix(matrix, Ax, alpha);
+    List_Reset(ListOfTransformedPoints);
+    ApplyTransformationToSurface(matrix, chapeau);
+
+    T[0] = X0;
+    T[1] = X1;
+    T[2] = X2;
+    SetTranslationMatrix(matrix, T);
+    List_Reset(ListOfTransformedPoints);
+    ApplyTransformationToSurface(matrix, chapeau);
+    break;
+  case TRANSLATE_ROTATE:
+    T[0] = -X0;
+    T[1] = -X1;
+    T[2] = -X2;
+    SetTranslationMatrix(matrix, T);
+    List_Reset(ListOfTransformedPoints);
+    ApplyTransformationToSurface(matrix, chapeau);
+
+    Ax[0] = A0;
+    Ax[1] = A1;
+    Ax[2] = A2;
+    SetRotationMatrix(matrix, Ax, alpha);
+    List_Reset(ListOfTransformedPoints);
+    ApplyTransformationToSurface(matrix, chapeau);
+
+    T[0] = X0;
+    T[1] = X1;
+    T[2] = X2;
+    SetTranslationMatrix(matrix, T);
+    List_Reset(ListOfTransformedPoints);
+    ApplyTransformationToSurface(matrix, chapeau);
+
+    T[0] = T0;
+    T[1] = T1;
+    T[2] = T2;
+    SetTranslationMatrix(matrix, T);
+    List_Reset(ListOfTransformedPoints);
+    ApplyTransformationToSurface(matrix, chapeau);
+    break;
+  default:
+    Msg(GERROR, "Unknown extrusion type");
+    return ps->Num;
+  }
+
+  // FIXME: why do we do this? only for backward compatibility?
+  Tree_Suppress(THEM->Surfaces, &chapeau);
+  chapeau->Num = NEWSURFACE();
+  THEM->MaxSurfaceNum = chapeau->Num;
+  Tree_Add(THEM->Surfaces, &chapeau);
+
+  Tree_Add(THEM->Volumes, &v);
+
+  *pv = v;
+
+  if(CTX.geom.auto_coherence)
+    ReplaceAllDuplicates();
+
+  List_Reset(ListOfTransformedPoints);
+
+  return chapeau->Num;
+}
+
+void ExtrudeShape(int extrude_type, int shape_type, int shape_num,
+		  double T0, double T1, double T2,
+		  double A0, double A1, double A2,
+		  double X0, double X1, double X2, double alpha,
+		  ExtrudeParams *e,
+		  List_T *out)
+{
+  Shape shape;
+  shape.Type = shape_type;
+  shape.Num = shape_num;
+  List_T *tmp = List_Create(1, 1, sizeof(Shape));
+  List_Add(tmp, &shape);
+  ExtrudeShapes(extrude_type, tmp,
+		T0, T1, T2,
+		A0, A1, A2,
+		X0, X1, X2, alpha,
+		e,
+		out);
+  List_Delete(tmp);
+}
+
+void ExtrudeShapes(int type, List_T *in, 
+		   double T0, double T1, double T2,
+		   double A0, double A1, double A2,
+		   double X0, double X1, double X2, double alpha,
+		   ExtrudeParams *e,
+		   List_T *out)
+{
+  Shape O, TheShape;
+  Curve *pc, *prc;
+  Surface *ps;
+  Volume *pv;
+      
+  for(int i = 0; i < List_Nbr(in); i++){
+    List_Read(in, i, &O);
+    switch(O.Type){
+    case MSH_POINT:
+      TheShape.Num = Extrude_ProtudePoint(type, O.Num, T0, T1, T2,
+					  A0, A1, A2, X0, X1, X2, alpha,
+					  &pc, &prc, 1, e);
+      TheShape.Type = MSH_POINT;
+      List_Add(out, &TheShape);
+      if(pc){
+	TheShape.Num = pc->Num;
+	TheShape.Type = pc->Typ;
+	List_Add(out, &TheShape);
+      }
+      break;
+    case MSH_SEGM_LINE:
+    case MSH_SEGM_SPLN:
+    case MSH_SEGM_BSPLN:
+    case MSH_SEGM_BEZIER:
+    case MSH_SEGM_CIRC:
+    case MSH_SEGM_CIRC_INV:
+    case MSH_SEGM_ELLI:
+    case MSH_SEGM_ELLI_INV:
+    case MSH_SEGM_NURBS:
+    case MSH_SEGM_PARAMETRIC:
+      TheShape.Num = Extrude_ProtudeCurve(type, O.Num, T0, T1, T2,
+					  A0, A1, A2, X0, X1, X2, alpha,
+					  &ps, 1, e);
+      pc = FindCurve(TheShape.Num);
+      if(!pc){
+	//Msg(WARNING, "Unknown curve %d", TheShape.Num);
+	TheShape.Type = 0;
+      }
+      else{
+	TheShape.Type = pc->Typ;
+      }
+      List_Add(out, &TheShape);
+      if(ps){
+	TheShape.Num = ps->Num;
+	TheShape.Type = ps->Typ;
+	List_Add(out, &TheShape);
+      }
+      break;
+    case MSH_SURF_NURBS:
+    case MSH_SURF_REGL:
+    case MSH_SURF_TRIC:
+    case MSH_SURF_PLAN:
+      TheShape.Num = Extrude_ProtudeSurface(type, O.Num, T0, T1, T2,
+					    A0, A1, A2, X0, X1, X2, alpha,
+					    &pv, e);
+      ps = FindSurface(TheShape.Num);
+      if(!ps){
+	//Msg(WARNING, "Unknown surface %d", TheShape.Num);
+	TheShape.Type = 0;
+      }
+      else{
+	TheShape.Type = ps->Typ;
+      }
+      List_Add(out, &TheShape);
+      if(pv){
+	TheShape.Num = pv->Num;
+	TheShape.Type = pv->Typ;
+	List_Add(out, &TheShape);
+      }
+      break;
+    default:
+      Msg(GERROR, "Impossible to extrude entity %d (of type %d)", O.Num,
+          O.Type);
+      break;
+    }
+  }
+}
+
+// Duplicate removal
+
+int compareTwoCurves(const void *a, const void *b)
+{
+  Curve *c1 = *(Curve **) a;
+  Curve *c2 = *(Curve **) b;
+  int comp;
+
+  if(c1->Typ != c2->Typ){
+    if((c1->Typ == MSH_SEGM_CIRC && c2->Typ == MSH_SEGM_CIRC_INV) ||
+       (c1->Typ == MSH_SEGM_CIRC_INV && c2->Typ == MSH_SEGM_CIRC) ||
+       (c1->Typ == MSH_SEGM_ELLI && c2->Typ == MSH_SEGM_ELLI_INV) ||
+       (c1->Typ == MSH_SEGM_ELLI_INV && c2->Typ == MSH_SEGM_ELLI)){
+      // this is still ok
+    }
+    else
+      return c1->Typ - c2->Typ;
+  }
+
+  if(List_Nbr(c1->Control_Points) != List_Nbr(c2->Control_Points))
+    return List_Nbr(c1->Control_Points) - List_Nbr(c2->Control_Points);
   
-  return num;
+  if(!List_Nbr(c1->Control_Points)){
+    if(!c1->beg || !c2->beg)
+      return 1;
+    comp = compareVertex(&c1->beg, &c2->beg);
+    if(comp)
+      return comp;
+    if(!c1->end || !c2->end)
+      return 1;
+    comp = compareVertex(&c1->end, &c2->end);
+    if(comp)
+      return comp;
+  }
+  else {
+    for(int i = 0; i < List_Nbr(c1->Control_Points); i++){
+      Vertex *v1, *v2;
+      List_Read(c1->Control_Points, i, &v1);
+      List_Read(c2->Control_Points, i, &v2);
+      comp = compareVertex(&v1, &v2);
+      if(comp)
+	return comp;
+    }
+  }
+
+  return 0;
 }
 
-void translate(int add, List_T *list, char *fich, char *what, char *tx, char *ty, char *tz)
+int compareTwoSurfaces(const void *a, const void *b)
 {
-  char text[BUFFSIZE];
+  Surface *s1 = *(Surface **) a;
+  Surface *s2 = *(Surface **) b;
+  return compare2Lists(s1->Generatrices, s2->Generatrices, compareAbsCurve);
+}
 
-  if(add)
-    snprintf(text, BUFFSIZE, "Translate {%s,%s,%s} {\n  Duplicata { %s{", tx, ty, tz, what);
-  else
-    snprintf(text, BUFFSIZE, "Translate {%s,%s,%s} {\n  %s{", tx, ty, tz, what);
+void MaxNumPoint(void *a, void *b)
+{
+  Vertex *v = *(Vertex **) a;
+  THEM->MaxPointNum = MAX(THEM->MaxPointNum, v->Num);
+}
 
-  strncat_list(text, list);
+void MaxNumCurve(void *a, void *b)
+{
+  Curve *c = *(Curve **) a;
+  THEM->MaxLineNum = MAX(THEM->MaxLineNum, c->Num);
+}
+
+void MaxNumSurface(void *a, void *b)
+{
+  Surface *s = *(Surface **) a;
+  THEM->MaxSurfaceNum = MAX(THEM->MaxSurfaceNum, s->Num);
+}
+
+void ReplaceDuplicatePoints()
+{
+  List_T *All;
+  Tree_T *allNonDuplicatedPoints;
+  Vertex *v, **pv, **pv2;
+  Curve *c;
+  Surface *s;
+  Volume *vol;
+  int i, j, start, end;
+
+  List_T *points2delete = List_Create(100, 100, sizeof(Vertex *));
+
+  // Create unique points
+
+  start = Tree_Nbr(THEM->Points);
+
+  All = Tree2List(THEM->Points);
+  allNonDuplicatedPoints = Tree_Create(sizeof(Vertex *), comparePosition);
+  for(i = 0; i < List_Nbr(All); i++) {
+    List_Read(All, i, &v);
+    if(!Tree_Search(allNonDuplicatedPoints, &v)) {
+      Tree_Insert(allNonDuplicatedPoints, &v);
+    }
+    else {
+      Tree_Suppress(THEM->Points, &v);
+      //List_Add(points2delete,&v);      
+    }
+  }
+  List_Delete(All);
+
+  end = Tree_Nbr(THEM->Points);
+
+  if(start == end) {
+    Tree_Delete(allNonDuplicatedPoints);
+    List_Delete(points2delete);
+    return;
+  }
+
+  Msg(DEBUG, "Removed %d duplicate points", start - end);
+
+  if(CTX.geom.old_newreg) {
+    THEM->MaxPointNum = 0;
+    Tree_Action(THEM->Points, MaxNumPoint);
+  }
+
+  // Replace old points in curves
+
+  All = Tree2List(THEM->Curves);
+  for(i = 0; i < List_Nbr(All); i++) {
+    List_Read(All, i, &c);
+    if(!Tree_Query(allNonDuplicatedPoints, &c->beg))
+      Msg(GERROR, "Weird point %d in Coherence", c->beg->Num);
+    if(!Tree_Query(allNonDuplicatedPoints, &c->end))
+      Msg(GERROR, "Weird point %d in Coherence", c->end->Num);
+    for(j = 0; j < List_Nbr(c->Control_Points); j++) {
+      pv = (Vertex **) List_Pointer(c->Control_Points, j);
+      if(!(pv2 = (Vertex **) Tree_PQuery(allNonDuplicatedPoints, pv)))
+        Msg(GERROR, "Weird point %d in Coherence", (*pv)->Num);
+      else
+        List_Write(c->Control_Points, j, pv2);
+    }
+  }
+  List_Delete(All);
+
+  // Replace old points in surfaces
+
+  All = Tree2List(THEM->Surfaces);
+  for(i = 0; i < List_Nbr(All); i++) {
+    List_Read(All, i, &s);
+    for(j = 0; j < List_Nbr(s->Control_Points); j++) {
+      pv = (Vertex **) List_Pointer(s->Control_Points, j);
+      if(!(pv2 = (Vertex **) Tree_PQuery(allNonDuplicatedPoints, pv)))
+        Msg(GERROR, "Weird point %d in Coherence", (*pv)->Num);
+      else
+        List_Write(s->Control_Points, j, pv2);
+    }
+    for(j = 0; j < List_Nbr(s->TrsfPoints); j++){
+      pv = (Vertex **) List_Pointer(s->TrsfPoints, j);
+      if(!(pv2 = (Vertex **) Tree_PQuery(allNonDuplicatedPoints, pv)))
+	Msg(GERROR, "Weird point %d in Coherence", (*pv)->Num);
+      else
+	List_Write(s->TrsfPoints, j, pv2);
+    }
+  }
+  List_Delete(All);
   
-  if(add)
-    strncat(text, "}; }\n}", BUFFSIZE-strlen(text));
-  else
-    strncat(text, "};\n}", BUFFSIZE-strlen(text));
+  // Replace old points in volumes
+
+  All = Tree2List(THEM->Volumes);
+  for(i = 0; i < List_Nbr(All); i++) {
+    List_Read(All, i, &vol);
+    for(j = 0; j < List_Nbr(vol->TrsfPoints); j++){
+      pv = (Vertex **) List_Pointer(vol->TrsfPoints, j);
+      if(!(pv2 = (Vertex **) Tree_PQuery(allNonDuplicatedPoints, pv)))
+	Msg(GERROR, "Weird point %d in Coherence", (*pv)->Num);
+      else
+	List_Write(vol->TrsfPoints, j, pv2);
+    }
+  }
+  List_Delete(All);
+
+  for(int k = 0; k < List_Nbr(points2delete); k++) {
+    List_Read(points2delete, i, &v);
+    Free_Vertex(&v, 0);
+  }
+
+  Tree_Delete(allNonDuplicatedPoints);
+  List_Delete(points2delete);
 
-  add_infile(text, fich);
 }
 
-void rotate(int add, List_T *list, char *fich, char *what, char *ax, char *ay, char *az,
-	    char *px, char *py, char *pz, char *angle)
+void ReplaceDuplicateCurves()
 {
-  char text[BUFFSIZE];
+  List_T *All;
+  Tree_T *allNonDuplicatedCurves;
+  Curve *c, *c2, **pc, **pc2;
+  Surface *s;
+  int i, j, start, end;
+
+  // Create unique curves
+
+  start = Tree_Nbr(THEM->Curves);
+
+  All = Tree2List(THEM->Curves);
+  allNonDuplicatedCurves = Tree_Create(sizeof(Curve *), compareTwoCurves);
+  for(i = 0; i < List_Nbr(All); i++) {
+    List_Read(All, i, &c);
+    if(c->Num > 0) {
+      if(!Tree_Search(allNonDuplicatedCurves, &c)) {
+        Tree_Insert(allNonDuplicatedCurves, &c);
+        if(!(c2 = FindCurve(-c->Num))) {
+          Msg(GERROR, "Unknown curve %d", -c->Num);
+          List_Delete(All);
+          return;
+        }
+        Tree_Insert(allNonDuplicatedCurves, &c2);
+      }
+      else {
+        Tree_Suppress(THEM->Curves, &c);
+        if(!(c2 = FindCurve(-c->Num))) {
+          Msg(GERROR, "Unknown curve %d", -c->Num);
+          List_Delete(All);
+          return;
+        }
+        Tree_Suppress(THEM->Curves, &c2);
+      }
+    }
+  }
+  List_Delete(All);
 
-  if(add)
-    snprintf(text, BUFFSIZE, "Rotate {{%s,%s,%s}, {%s,%s,%s}, %s} {\n  Duplicata { %s{",
-             ax, ay, az, px, py, pz, angle, what);
-  else
-    snprintf(text, BUFFSIZE, "Rotate {{%s,%s,%s}, {%s,%s,%s}, %s} {\n  %s{",
-             ax, ay, az, px, py, pz, angle, what);
+  end = Tree_Nbr(THEM->Curves);
 
-  strncat_list(text, list);
+  if(start == end) {
+    Tree_Delete(allNonDuplicatedCurves);
+    return;
+  }
 
-  if(add)
-    strncat(text, "}; }\n}", BUFFSIZE-strlen(text));
-  else
-    strncat(text, "};\n}", BUFFSIZE-strlen(text));
+  Msg(DEBUG, "Removed %d duplicate curves", start - end);
 
-  add_infile(text, fich);
+  if(CTX.geom.old_newreg) {
+    THEM->MaxLineNum = 0;
+    Tree_Action(THEM->Curves, MaxNumCurve);
+  }
+
+  // Replace old curves in surfaces
+
+  All = Tree2List(THEM->Surfaces);
+  for(i = 0; i < List_Nbr(All); i++) {
+    List_Read(All, i, &s);
+    for(j = 0; j < List_Nbr(s->Generatrices); j++) {
+      pc = (Curve **) List_Pointer(s->Generatrices, j);
+      if(!(pc2 = (Curve **) Tree_PQuery(allNonDuplicatedCurves, pc)))
+        Msg(GERROR, "Weird curve %d in Coherence", (*pc)->Num);
+      else {
+        List_Write(s->Generatrices, j, pc2);
+        // Arghhh. Revoir compareTwoCurves !
+        End_Curve(*pc2);
+      }
+    }
+  }
+  List_Delete(All);
+
+  Tree_Delete(allNonDuplicatedCurves);
 }
 
-void dilate(int add, List_T *list, char *fich, char *what, char *dx, char *dy, char *dz, char *df)
+void ReplaceDuplicateSurfaces()
 {
-  char text[BUFFSIZE];
+  List_T *All;
+  Tree_T *allNonDuplicatedSurfaces;
+  Surface *s, **ps, **ps2;
+  Volume *vol;
+  int i, j, start, end;
+
+  // Create unique surfaces
+
+  start = Tree_Nbr(THEM->Surfaces);
+
+  All = Tree2List(THEM->Surfaces);
+  allNonDuplicatedSurfaces = Tree_Create(sizeof(Curve *), compareTwoSurfaces);
+  for(i = 0; i < List_Nbr(All); i++) {
+    List_Read(All, i, &s);
+    if(s->Num > 0) {
+      if(!Tree_Search(allNonDuplicatedSurfaces, &s)) {
+        Tree_Insert(allNonDuplicatedSurfaces, &s);
+      }
+      else {
+        Tree_Suppress(THEM->Surfaces, &s);
+      }
+    }
+  }
+  List_Delete(All);
 
-  if(add)
-    snprintf(text, BUFFSIZE, "Dilate {{%s,%s,%s}, %s} {\n  Duplicata { %s{",
-             dx, dy, dz, df, what);
-  else
-    snprintf(text, BUFFSIZE, "Dilate {{%s,%s,%s}, %s} {\n  %s{",
-             dx, dy, dz, df, what);
+  end = Tree_Nbr(THEM->Surfaces);
 
-  strncat_list(text, list);
+  if(start == end) {
+    Tree_Delete(allNonDuplicatedSurfaces);
+    return;
+  }
 
-  if(add)
-    strncat(text, "}; }\n}", BUFFSIZE-strlen(text));
-  else
-    strncat(text, "};\n}", BUFFSIZE-strlen(text));
+  Msg(DEBUG, "Removed %d duplicate surfaces", start - end);
+
+  if(CTX.geom.old_newreg) {
+    THEM->MaxSurfaceNum = 0;
+    Tree_Action(THEM->Surfaces, MaxNumSurface);
+  } 
+
+  // Replace old surfaces in volumes
+
+  All = Tree2List(THEM->Volumes);
+  for(i = 0; i < List_Nbr(All); i++) {
+    List_Read(All, i, &vol);
+    for(j = 0; j < List_Nbr(vol->Surfaces); j++) {
+      ps = (Surface **) List_Pointer(vol->Surfaces, j);
+      if(!(ps2 = (Surface **) Tree_PQuery(allNonDuplicatedSurfaces, ps)))
+        Msg(GERROR, "Weird surface %d in Coherence", (*ps)->Num);
+      else
+        List_Write(vol->Surfaces, j, ps2);
+    }
+  }
+  List_Delete(All);
 
-  add_infile(text, fich);
+  Tree_Delete(allNonDuplicatedSurfaces);
 }
 
-void symmetry(int add, List_T *list, char *fich, char *what, char *sa, char *sb, char *sc, char *sd)
+void ReplaceAllDuplicates()
 {
-  char text[BUFFSIZE];
+  ReplaceDuplicatePoints();
+  ReplaceDuplicateCurves();
+  ReplaceDuplicateSurfaces();
+}
 
-  if(add)
-    snprintf(text, BUFFSIZE, "Symmetry {%s,%s,%s,%s} {\n  Duplicata { %s{",
-             sa, sb, sc, sd, what);
-  else
-    snprintf(text, BUFFSIZE, "Symmetry {%s,%s,%s,%s} {\n  %s{",
-             sa, sb, sc, sd, what);
 
-  strncat_list(text, list);
+// Projection of point on curve or surface
+
+static Curve *CURVE, *CURVE_2;
+static Surface *SURFACE;
+static Vertex *VERTEX;
+
+double min1d(double (*funct) (double), double *xmin)
+{
+  // we should think about the tolerance more carefully...
+  double ax = 1.e-15, bx = 1.e-12, cx = 1.e-11, fa, fb, fx, tol = 1.e-4;
+  mnbrak(&ax, &bx, &cx, &fa, &fx, &fb, funct);
+  //Msg(INFO, "--MIN1D : ax %12.5E bx %12.5E cx %12.5E",ax,bx,cx);  
+  return (brent(ax, bx, cx, funct, tol, xmin));
+}
+
+static void projectPS(int N, double x[], double res[])
+{
+  //x[1] = u x[2] = v
+  Vertex du, dv, c;
+  c = InterpolateSurface(SURFACE, x[1], x[2], 0, 0);
+  du = InterpolateSurface(SURFACE, x[1], x[2], 1, 1);
+  dv = InterpolateSurface(SURFACE, x[1], x[2], 1, 2);
+  res[1] =
+    (c.Pos.X - VERTEX->Pos.X) * du.Pos.X +
+    (c.Pos.Y - VERTEX->Pos.Y) * du.Pos.Y +
+    (c.Pos.Z - VERTEX->Pos.Z) * du.Pos.Z;
+  res[2] =
+    (c.Pos.X - VERTEX->Pos.X) * dv.Pos.X +
+    (c.Pos.Y - VERTEX->Pos.Y) * dv.Pos.Y +
+    (c.Pos.Z - VERTEX->Pos.Z) * dv.Pos.Z;
+}
+
+static double projectPC(double u)
+{
+  //x[1] = u x[2] = v
+  if(u < CURVE->ubeg)
+    u = CURVE->ubeg;
+  if(u < CURVE->ubeg)
+    u = CURVE->ubeg;
+  Vertex c;
+  c = InterpolateCurve(CURVE, u, 0);
+  return sqrt(DSQR(c.Pos.X - VERTEX->Pos.X) +
+              DSQR(c.Pos.Y - VERTEX->Pos.Y) + DSQR(c.Pos.Z - VERTEX->Pos.Z));
+}
+
+static int UFIXED = 0;
+static double FIX;
+static double projectPCS(double u)
+{
+  //x[1] = u x[2] = v
+  double tmin, tmax;
+  if(UFIXED) {
+    tmin = SURFACE->kv[0];
+    tmax = SURFACE->kv[SURFACE->Nv + SURFACE->OrderV];
+  }
+  else {
+    tmin = SURFACE->ku[0];
+    tmax = SURFACE->ku[SURFACE->Nu + SURFACE->OrderU];
+  }
 
-  if(add)
-    strncat(text, "}; }\n}", BUFFSIZE-strlen(text));
+  if(u < tmin)
+    u = tmin;
+  if(u > tmax)
+    u = tmax;
+  Vertex c;
+  if(UFIXED)
+    c = InterpolateSurface(SURFACE, FIX, u, 0, 0);
   else
-    strncat(text, "};\n}", BUFFSIZE-strlen(text));
+    c = InterpolateSurface(SURFACE, u, FIX, 0, 0);
+  return sqrt(DSQR(c.Pos.X - VERTEX->Pos.X) +
+              DSQR(c.Pos.Y - VERTEX->Pos.Y) + DSQR(c.Pos.Z - VERTEX->Pos.Z));
+}
 
-  add_infile(text, fich);
+bool ProjectPointOnCurve(Curve * c, Vertex * v, Vertex * RES, Vertex * DER)
+{
+  double xmin;
+  CURVE = c;
+  VERTEX = v;
+  min1d(projectPC, &xmin);
+  *RES = InterpolateCurve(CURVE, xmin, 0);
+  *DER = InterpolateCurve(CURVE, xmin, 1);
+  if(xmin > c->uend) {
+    xmin = c->uend;
+    *RES = InterpolateCurve(CURVE, c->uend, 0);
+    *DER = InterpolateCurve(CURVE, c->uend, 1);
+  }
+  else if(xmin < c->ubeg) {
+    xmin = c->ubeg;
+    *RES = InterpolateCurve(CURVE, c->ubeg, 0);
+    *DER = InterpolateCurve(CURVE, c->ubeg, 1);
+  }  
+  return true;
 }
 
-void extrude(List_T *list, char *fich, char *what, char *tx, char *ty, char *tz)
+bool search_in_boundary(Surface * s, Vertex * p, double t, int Fixu,
+                        double *uu, double *vv)
 {
-  char text[BUFFSIZE];
+  double l, umin = 0., vmin = 0., lmin = 1.e200;
+  int i, N;
+  Vertex vr;
+  double tmin, tmax, u, v;
+
+  if(Fixu) {
+    tmin = s->kv[0];
+    tmax = s->kv[s->Nv + s->OrderV];
+    N = 3 * s->Nu;
+  }
+  else {
+    tmin = s->ku[0];
+    tmax = s->ku[s->Nu + s->OrderU];
+    N = 3 * s->Nv;
+  }
+  for(i = 0; i < N; i++) {
+    if(Fixu) {
+      u = t;
+      v = tmin + (tmax - tmin) * (double)(i) / (double)(N - 1);
+    }
+    else {
+      v = t;
+      u = tmin + (tmax - tmin) * (double)(i) / (double)(N - 1);
+    }
+    vr = InterpolateSurface(SURFACE, u, v, 0, 0);
+    l = sqrt(DSQR(vr.Pos.X - p->Pos.X) +
+             DSQR(vr.Pos.Y - p->Pos.Y) + DSQR(vr.Pos.Z - p->Pos.Z));
+    if(l < lmin) {
+      lmin = l;
+      umin = u;
+      vmin = v;
+    }
+  }
 
-  snprintf(text, BUFFSIZE, "Extrude {%s,%s,%s} {\n  %s{", tx, ty, tz, what);
-  strncat_list(text, list);
-  strncat(text, "};\n}", BUFFSIZE-strlen(text));
-  add_infile(text, fich);
+  FIX = t;
+  UFIXED = Fixu;
+  double xm;
+  if(Fixu)
+    xm = vmin;
+  else
+    xm = umin;
+  if(lmin > 1.e-3)
+    min1d(projectPCS, &xm);
+  if(Fixu) {
+    *uu = t;
+    *vv = xm;
+  }
+  else {
+    *vv = t;
+    *uu = xm;
+  }
+  vr = InterpolateSurface(SURFACE, *uu, *vv, 0, 0);
+  l = sqrt(DSQR(vr.Pos.X - p->Pos.X) +
+           DSQR(vr.Pos.Y - p->Pos.Y) + DSQR(vr.Pos.Z - p->Pos.Z));
+  if(l < 1.e-3)
+    return true;
+  return false;
+}
+
+bool try_a_value(Surface * s, Vertex * p, double u, double v, double *uu,
+                 double *vv)
+{
+  Vertex vr = InterpolateSurface(s, u, v, 0, 0);
+  double l = sqrt(DSQR(vr.Pos.X - p->Pos.X) +
+                  DSQR(vr.Pos.Y - p->Pos.Y) + DSQR(vr.Pos.Z - p->Pos.Z));
+  *uu = u;
+  *vv = v;
+  if(l < 1.e-3)
+    return true;
+  return false;
+}
+
+bool ProjectPointOnSurface(Surface * s, Vertex & p)
+{
+  double x[3] = { 0.5, 0.5, 0.5 };
+  Vertex vv;
+  int check;
+  SURFACE = s;
+  VERTEX = &p;
+  double UMIN = 0.;
+  double UMAX = 1.;
+  double VMIN = 0.;
+  double VMAX = 1.;
+  while(1) {
+    newt(x, 2, &check, projectPS);
+    vv = InterpolateSurface(s, x[1], x[2], 0, 0);
+    if(x[1] >= UMIN && x[1] <= UMAX && x[2] >= VMIN && x[2] <= VMAX)
+      break;
+    x[1] = UMIN + (UMAX - UMIN) * ((rand() % 10000) / 10000.);
+    x[2] = VMIN + (VMAX - VMIN) * ((rand() % 10000) / 10000.);
+  }
+  p.Pos.X = vv.Pos.X;
+  p.Pos.Y = vv.Pos.Y;
+  p.Pos.Z = vv.Pos.Z;
+  p.us[0] = x[1];
+  p.us[1] = x[2];
+  if(!check) {
+    return false;
+  }
+  return true;
 }
 
-void protude(List_T *list, char *fich, char *what, char *ax, char *ay, char *az,
-	     char *px, char *py, char *pz, char *angle)
+bool ProjectPointOnSurface(Surface * s, Vertex * p, double *u, double *v)
 {
-  char text[BUFFSIZE];
+  static double x[3];
+  int check;
+  static int deb = 1;
+  double VMIN, VMAX, UMIN, UMAX, l, lmin;
+  Vertex vv;
+
+  SURFACE = s;
+  VERTEX = p;
+  lmin = 1.e24;
+  UMAX = s->ku[s->Nu + s->OrderU];
+  UMIN = s->ku[0];
+  VMAX = s->kv[s->Nv + s->OrderV];
+  VMIN = s->kv[0];
+  if(deb) {
+    x[1] = UMIN + (UMAX - UMIN) * ((rand() % 10000) / 10000.);
+    x[2] = VMIN + (VMAX - VMIN) * ((rand() % 10000) / 10000.);
+    deb = 0;
+  }
 
-  snprintf(text, BUFFSIZE, "Extrude {{%s,%s,%s}, {%s,%s,%s}, %s} {\n  %s{",
-           ax, ay, az, px, py, pz, angle, what);
-  strncat_list(text, list);
-  strncat(text, "};\n}", BUFFSIZE-strlen(text));
-  add_infile(text, fich);
+  if(try_a_value(SURFACE, VERTEX, SURFACE->ku[0] + VERTEX->u,
+                 SURFACE->kv[0], u, v))
+    return true;
+  if(try_a_value(SURFACE, VERTEX, SURFACE->ku[0] + VERTEX->u,
+                 SURFACE->kv[SURFACE->Nv + SURFACE->OrderV], u, v))
+    return true;
+  if(try_a_value
+     (SURFACE, VERTEX, SURFACE->ku[SURFACE->Nu + SURFACE->OrderU] - VERTEX->u,
+      SURFACE->kv[0], u, v))
+    return true;
+  if(try_a_value
+     (SURFACE, VERTEX, SURFACE->ku[SURFACE->Nu + SURFACE->OrderU] - VERTEX->u,
+      SURFACE->kv[SURFACE->Nv + SURFACE->OrderV], u, v))
+    return true;
+  if(try_a_value
+     (SURFACE, VERTEX, SURFACE->ku[0], SURFACE->kv[0] + VERTEX->u, u, v))
+    return true;
+  if(try_a_value(SURFACE, VERTEX, SURFACE->ku[0],
+                 SURFACE->kv[SURFACE->Nv + SURFACE->OrderV] - VERTEX->u, u,
+                 v))
+    return true;
+  if(try_a_value(SURFACE, VERTEX, SURFACE->ku[SURFACE->Nu + SURFACE->OrderU],
+                 SURFACE->kv[0] + VERTEX->u, u, v))
+    return true;
+  if(try_a_value(SURFACE, VERTEX, SURFACE->ku[SURFACE->Nu + SURFACE->OrderU],
+                 SURFACE->kv[SURFACE->Nv + SURFACE->OrderV] - VERTEX->u, u,
+                 v))
+    return true;
+
+
+  if(search_in_boundary(SURFACE, VERTEX, SURFACE->kv[0], 0, u, v))
+    return true;
+  if(search_in_boundary
+     (SURFACE, VERTEX, SURFACE->kv[SURFACE->Nv + SURFACE->OrderV], 0, u, v))
+    return true;
+  if(search_in_boundary(SURFACE, VERTEX, SURFACE->ku[0], 1, u, v))
+    return true;
+  if(search_in_boundary
+     (SURFACE, VERTEX, SURFACE->ku[SURFACE->Nu + SURFACE->OrderU], 1, u, v))
+    return true;
+
+  while(1) {
+    newt(x, 2, &check, projectPS);
+    vv = InterpolateSurface(s, x[1], x[2], 0, 0);
+    l = sqrt(DSQR(vv.Pos.X - p->Pos.X) +
+             DSQR(vv.Pos.Y - p->Pos.Y) + DSQR(vv.Pos.Z - p->Pos.Z));
+    if(l < 1.e-1)
+      break;
+    else {
+      x[1] = UMIN + (UMAX - UMIN) * ((rand() % 10000) / 10000.);
+      x[2] = VMIN + (VMAX - VMIN) * ((rand() % 10000) / 10000.);
+    }
+  }
+  *u = x[1];
+  *v = x[2];
+
+  if(!check) {
+    return false;
+  }
+  return true;
 }
+
diff --git a/Geo/Geo.h b/Geo/Geo.h
index c355cf0140..c46a8a4d5d 100644
--- a/Geo/Geo.h
+++ b/Geo/Geo.h
@@ -20,7 +20,11 @@
 // 
 // Please report all bugs and problems to <gmsh@geuz.org>.
 
+#include <math.h>
+#include "GmshDefines.h"
 #include "List.h"
+#include "Tree.h"
+#include "ExtrudeParams.h"
 
 #define INFILE     1
 #define INSTRING   2
@@ -71,6 +75,157 @@
 #define MSH_PHYSICAL_SURFACE 320
 #define MSH_PHYSICAL_VOLUME  330
 
+class DrawingColor{
+ public:
+  int type;
+  unsigned int geom, mesh;
+};
+
+struct _Surf{
+  int Num;
+  int Typ;
+  char Visible;
+  int Method;
+  int Recombine;
+  int Recombine_Dir; // -1 is left, +1 is right, 0 is alternated
+  double RecombineAngle;
+  int ipar[5];
+  int Nu, Nv;
+  List_T *Generatrices;
+  List_T *EmbeddedCurves;
+  List_T *EmbeddedPoints;
+  List_T *Control_Points;
+  List_T *TrsfPoints;
+  double plan[3][3];
+  double invplan[3][3];
+  double a, b, c, d;
+  List_T *Orientations;
+  List_T *Contours;
+  int OrderU, OrderV;
+  float *ku, *kv, *cp;
+  struct _Surf *Support;
+  ExtrudeParams *Extrude;
+  DrawingColor Color;
+};
+
+typedef struct _Surf Surface;
+
+typedef struct{
+  int Num;
+  List_T *Curves;
+}EdgeLoop;
+
+typedef struct{
+  int Num;
+  List_T *Surfaces;
+}SurfaceLoop;
+
+typedef struct{
+  int Num;
+  int Typ;
+  char Visible;
+  List_T *Entities;
+}PhysicalGroup;
+
+typedef struct {
+  int Num;
+  int Typ;
+  char Visible;
+  int Method;
+  int ipar[8];
+  ExtrudeParams *Extrude;
+  List_T *TrsfPoints;
+  List_T *Surfaces;
+  List_T *SurfacesOrientations;
+  DrawingColor Color;
+}Volume;
+
+typedef struct _Mesh Mesh;
+
+struct Coord{
+  double X,Y,Z;
+};
+
+class Vertex {
+  public :
+  int Num;
+  char Visible;
+  double lc, u, us[3], w;
+  Coord Pos;
+  Vertex()
+  {
+    Visible = 1;
+    Pos.X = 0.0;
+    Pos.Y = 0.0;
+    Pos.Z = 0.0;
+    w = 1.0;
+    lc = 1.0;
+  }
+  Vertex(double X,double Y,double Z=0.0, double l=1.0, double W=1.0)
+  {
+    Visible = 1;
+    Pos.X = X;
+    Pos.Y = Y;
+    Pos.Z = Z;
+    w = W;
+    lc = l;
+  }
+  void norme()
+  {
+    double d = sqrt(Pos.X * Pos.X + Pos.Y * Pos.Y + Pos.Z * Pos.Z);
+    if(d == 0.0)
+      return;
+    Pos.X /= d;
+    Pos.Y /= d;
+    Pos.Z /= d;
+  }
+  Vertex operator %(Vertex & autre)
+  {       // cross product
+    return Vertex(Pos.Y * autre.Pos.Z - Pos.Z * autre.Pos.Y,
+		  -(Pos.X * autre.Pos.Z - Pos.Z * autre.Pos.X),
+		  Pos.X * autre.Pos.Y - Pos.Y * autre.Pos.X, lc, w);
+  }
+};
+
+typedef struct{
+  double t1, t2, f1, f2, incl;
+  Vertex *v[4];
+  double invmat[3][3];
+  double n[3];
+}CircParam;
+
+typedef struct{
+  int Num;
+  int Typ;
+  char Visible;
+  int Method;
+  int ipar[4];
+  double dpar[4];
+  double l;
+  double mat[4][4];
+  Vertex *beg, *end;
+  double ubeg, uend;
+  List_T *Control_Points;
+  ExtrudeParams *Extrude;
+  float *k, *cp;
+  int degre;
+  CircParam Circle;
+  char functu[256], functv[256], functw[256];
+  DrawingColor Color;
+}Curve;
+
+struct _Mesh{
+  Tree_T *Points;
+  Tree_T *Curves;
+  Tree_T *Surfaces;
+  Tree_T *Volumes;
+  Tree_T *SurfaceLoops;
+  Tree_T *EdgeLoops;
+  List_T *PhysicalGroups;
+  int MaxPointNum, MaxLineNum, MaxLineLoopNum, MaxSurfaceNum;
+  int MaxSurfaceLoopNum, MaxVolumeNum, MaxPhysicalNum;
+};
+
 typedef struct {
   int Type;
   int Num;
@@ -82,42 +237,98 @@ typedef struct {
   } obj;
 } Shape;
 
-double evaluate_scalarfunction (char *var, double val, char *funct);
-
-void coherence(char *fich);
-void delet(List_T *list, char *fich, char *what);
-void add_infile(char *text, char *fich, bool deleted_something=false);
-void add_trsfline(int N, int *l, char *fich, char *type, char *typearg, char *pts);
-void add_trsfellisurf(int type, int N, int *l, char *fich, char *dir);
-void add_trsfvol(int N, int *l, char *fich);
-void add_charlength(List_T *list, char *fich, char *lc);
-void add_recosurf(List_T *list, char *fich);
-void add_param(char *par, char *value, char *fich);
-void add_point(char *fich, char *x, char *y, char *z, char *lc);
-void add_attractor(char *fich, int ip, int typ);
-void add_line(int p1, int p2, char *fich);
-void add_circ(int p1, int p2, int p3, char *fich);
-void add_ell(int p1, int p2, int p3, int p4, char *fich);
-void add_spline(int N, int *p, char *fich);
-void add_bezier(int N, int *p, char *fich);
-void add_bspline(int N, int *p, char *fich);
-void add_multline(int N, int *p, char *fich);
-void add_lineloop(List_T *list, char *fich, int *numloop);
-void add_surf(List_T *list, char *fich, int support, int typ);
-void add_surfloop(List_T *list, char *fich, int *numvol);
-void add_vol(List_T *list, char *fich);
-int add_physical(List_T *list, char *fich, int type);
-void translate(int add, List_T *list, char *fich, char *what,
-	       char *tx, char *ty, char *tz);
-void rotate(int add, List_T *list, char *fich, char *what, 
-	    char *ax, char *ay, char *az,
-	    char *px, char *py, char *pz, char *angle);
-void dilate(int add, List_T *list, char *fich, char *what,
-	    char *dx, char *dy, char *dz, char *df);
-void symmetry(int add, List_T *list, char *fich, char *what, 
-	      char *sa, char *sb, char *sc, char *sd);
-void extrude(List_T *list, char *fich, char *what, char *tx, char *ty, char *tz);
-void protude(List_T *list, char *fich, char *what, char *ax, char *ay, char *az,
-	     char *px, char *py, char *pz, char *angle);
+int compareVertex (const void *a, const void *b);
+int comparePosition (const void *a, const void *b);
+int compareSurfaceLoop(const void *a, const void *b);
+int compareEdgeLoop(const void *a, const void *b);
+int compareQuality(const void *a, const void *b);
+int compareCurve(const void *a, const void *b);
+int compareSurface(const void *a, const void *b);
+int compareVolume(const void *a, const void *b);
+int compareSxF(const void *a, const void *b);
+int compareMeshPartitionNum(const void *a, const void *b);
+int compareMeshPartitionIndex(const void *a, const void *b);
+int comparePhysicalGroup(const void *a, const void *b);
+
+Vertex        *Create_Vertex (int Num, double X, double Y, double Z, double lc, double u);
+PhysicalGroup *Create_PhysicalGroup(int Num, int typ, List_T * intlist);
+Curve         *Create_Curve(int Num, int Typ, int Order, List_T * Liste,
+			    List_T * Knots, int p1, int p2, double u1, double u2);
+Surface       *Create_Surface(int Num, int Typ);
+Volume        *Create_Volume(int Num, int Typ);
+EdgeLoop      *Create_EdgeLoop(int Num, List_T * intlist);
+SurfaceLoop   *Create_SurfaceLoop(int Num, List_T * intlist);
+
+void Free_Vertex (void *a, void *b);
+void Free_PhysicalGroup(void *a, void *b);
+void Free_MeshPartition(void *a, void *b);
+void Free_Surface(void *a, void *b);
+void Free_Volume(void *a, void *b);
+void Free_Volume_But_Not_Elements(void *a, void *b);
+void Free_Curve(void *a, void *b);
+void Free_EdgeLoop(void *a, void *b);
+void Free_SurfaceLoop(void *a, void *b);
+
+void End_Curve(Curve * c);
+void End_Surface(Surface * s, int reset_orientations=1);
+
+int NEWPOINT(void);
+int NEWLINE(void);
+int NEWLINELOOP(void);
+int NEWSURFACE(void);
+int NEWSURFACELOOP(void);
+int NEWVOLUME(void);
+int NEWPHYSICAL(void);
+int NEWREG(void);
+
+Vertex *FindPoint(int inum);
+Curve *FindCurve(int inum);
+Surface *FindSurface(int inum);
+Volume *FindVolume(int inum);
+EdgeLoop *FindEdgeLoop(int inum);
+SurfaceLoop *FindSurfaceLoop(int inum);
+PhysicalGroup *FindPhysicalGroup(int inum, int type);
+
+Curve *CreateReversedCurve(Curve *c);
+void ModifyLcPoint(int ip, double lc);
+
+void TranslateShapes(double X,double Y,double Z,
+                     List_T *ListShapes, int final);
+void DilatShapes(double X,double Y,double Z, double A,
+                 List_T *ListShapes, int final);
+void RotateShapes(double Ax,double Ay,double Az,
+		  double Px,double Py, double Pz,
+		  double alpha, List_T *ListShapes, int final);
+void SymmetryShapes(double A,double B,double C,
+		    double D, List_T *ListShapes, int final);
+void CopyShape(int Type, int Num, int *New);
+void DeleteShape(int Type, int Num);
+void ColorShape(int Type, int Num, unsigned int Color);
+void VisibilityShape(int Type, int Num, int Mode);
+void VisibilityShape(char *str, int Type, int Mode);
+void ExtrudeShape(int extrude_type, int shape_type, int shape_num,
+		  double T0, double T1, double T2,
+		  double A0, double A1, double A2,
+		  double X0, double X1, double X2, double alpha,
+		  ExtrudeParams *e,
+		  List_T *out);
+void ExtrudeShapes(int extrude_type, List_T *in,
+		   double T0, double T1, double T2,
+		   double A0, double A1, double A2,
+		   double X0, double X1, double X2, double alpha,
+		   ExtrudeParams *e,
+		   List_T *out);
+
+void ProtudeXYZ(double &x, double &y, double &z, ExtrudeParams *e);
+
+void ReplaceAllDuplicates();
+
+bool ProjectPointOnCurve(Curve *c, Vertex *v, Vertex *RES, Vertex *DER);
+bool ProjectPointOnSurface(Surface *s, Vertex &p);
+bool ProjectPointOnSurface(Surface *s, Vertex *p,double *u, double *v);
+
+int recognize_seg(int typ, List_T *liste, int *seg);
+int recognize_loop(List_T *liste, int *loop);
+int recognize_surfloop(List_T *liste, int *loop);
 
 #endif
diff --git a/Geo/ExtractContour.cpp b/Geo/GeoExtractContour.cpp
similarity index 98%
rename from Geo/ExtractContour.cpp
rename to Geo/GeoExtractContour.cpp
index 3b694805a6..b18d96b450 100644
--- a/Geo/ExtractContour.cpp
+++ b/Geo/GeoExtractContour.cpp
@@ -1,4 +1,4 @@
-// $Id: ExtractContour.cpp,v 1.9 2006-11-25 00:44:25 geuzaine Exp $
+// $Id: GeoExtractContour.cpp,v 1.1 2006-11-25 16:52:43 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -22,8 +22,6 @@
 #include "Gmsh.h"
 #include "Geo.h"
 #include "GeoUtils.h"
-#include "CAD.h"
-#include "Mesh.h"
 #include "Numeric.h"
 
 // Note: we use List_ISearchSeq so that the input lists don't get
diff --git a/Geo/ExtractContour.h b/Geo/GeoExtractContour.h
similarity index 93%
rename from Geo/ExtractContour.h
rename to Geo/GeoExtractContour.h
index 76cc354d79..2b0e89c602 100644
--- a/Geo/ExtractContour.h
+++ b/Geo/GeoExtractContour.h
@@ -1,5 +1,5 @@
-#ifndef _EXTRACT_CONTOUR_H_
-#define _EXTRACT_CONTOUR_H_
+#ifndef _GEO_EXTRACT_CONTOUR_H_
+#define _GEO_EXTRACT_CONTOUR_H_
 
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
diff --git a/Mesh/Interpolation.cpp b/Geo/GeoInterpolation.cpp
similarity index 61%
rename from Mesh/Interpolation.cpp
rename to Geo/GeoInterpolation.cpp
index 685a9ac52e..c1f5f850bb 100644
--- a/Mesh/Interpolation.cpp
+++ b/Geo/GeoInterpolation.cpp
@@ -1,4 +1,4 @@
-// $Id: Interpolation.cpp,v 1.30 2006-11-25 02:47:40 geuzaine Exp $
+// $Id: GeoInterpolation.cpp,v 1.1 2006-11-25 16:52:43 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -20,13 +20,12 @@
 // Please report all bugs and problems to <gmsh@geuz.org>.
 
 #include "Gmsh.h"
-#include "Numeric.h"
 #include "Geo.h"
-#include "Nurbs.h"
-#include "CAD.h"
-#include "Mesh.h"
+#include "GeoInterpolation.h"
+#include "GeoStringInterface.h"
+#include "GeoUtils.h"
 #include "Utils.h"
-#include "Interpolation.h"
+#include "Numeric.h"
 
 extern Mesh *THEM;
 
@@ -585,3 +584,422 @@ void HessianNormal2Surface(Surface * s, double u, double v, double n[3])
   prodve(t1, t2, n);
   norme(n);
 }
+
+// Cubic spline
+
+Vertex InterpolateCubicSpline(Vertex * v[4], double t, double mat[4][4],
+                              int derivee, double t1, double t2)
+{
+  Vertex V;
+  int i, j;
+  double vec[4], T[4];
+
+  V.Pos.X = V.Pos.Y = V.Pos.Z = 0.0;
+  V.lc = (1 - t) * v[1]->lc + t * v[2]->lc;
+  V.w = (1 - t) * v[1]->w + t * v[2]->w;
+
+  if(derivee) {
+    T[3] = 0.;
+    T[2] = 1.;
+    T[1] = 2. * t;
+    T[0] = 3. * t * t;
+  }
+  else {
+    T[3] = 1.;
+    T[2] = t;
+    T[1] = t * t;
+    T[0] = t * t * t;
+  }
+
+  for(i = 0; i < 4; i++) {
+    vec[i] = 0.0;
+  }
+
+  /* X */
+  for(i = 0; i < 4; i++) {
+    for(j = 0; j < 4; j++) {
+      vec[i] += mat[i][j] * v[j]->Pos.X;
+    }
+  }
+
+  for(j = 0; j < 4; j++) {
+    V.Pos.X += T[j] * vec[j];
+    vec[j] = 0.0;
+  }
+
+  /* Y */
+  for(i = 0; i < 4; i++) {
+    for(j = 0; j < 4; j++) {
+      vec[i] += mat[i][j] * v[j]->Pos.Y;
+    }
+  }
+
+  for(j = 0; j < 4; j++) {
+    V.Pos.Y += T[j] * vec[j];
+    vec[j] = 0.0;
+  }
+
+  /* Z */
+  for(i = 0; i < 4; i++) {
+    for(j = 0; j < 4; j++) {
+      vec[i] += mat[i][j] * v[j]->Pos.Z;
+    }
+  }
+  for(j = 0; j < 4; j++) {
+    V.Pos.Z += T[j] * vec[j];
+    vec[j] = 0.0;
+  }
+
+  if(derivee) {
+    V.Pos.X /= ((t2 - t1));
+    V.Pos.Y /= ((t2 - t1));
+    V.Pos.Z /= ((t2 - t1));
+  }
+
+  return V;
+}
+
+
+// Uniform BSplines
+
+Vertex InterpolateUBS(Curve * Curve, double u, int derivee)
+{
+  int NbControlPoints, NbCurves, iCurve;
+  double t, t1, t2;
+  Vertex *v[4];
+
+  NbControlPoints = List_Nbr(Curve->Control_Points);
+  NbCurves = NbControlPoints - 3;
+
+  iCurve = (int)(u * (double)NbCurves) + 1;
+
+  if(iCurve > NbCurves)
+    iCurve = NbCurves;
+  else if (iCurve < 1)
+    iCurve = 1;
+
+  t1 = (double)(iCurve - 1) / (double)(NbCurves);
+  t2 = (double)(iCurve) / (double)(NbCurves);
+
+  t = (u - t1) / (t2 - t1);
+
+  List_Read(Curve->Control_Points, iCurve - 1, &v[0]);
+  List_Read(Curve->Control_Points, iCurve, &v[1]);
+  List_Read(Curve->Control_Points, iCurve + 1, &v[2]);
+  List_Read(Curve->Control_Points, iCurve + 2, &v[3]);
+
+  return InterpolateCubicSpline(v, t, Curve->mat, derivee, t1, t2);
+}
+
+// Non Uniform BSplines
+
+int findSpan(double u, int deg, int n, float *U)
+{
+  if(u >= U[n])
+    return n - 1;
+  if(u <= U[0])
+    return deg;
+
+  int low = deg;
+  int high = n + 1;
+  int mid = (low + high) / 2;
+
+  while(u < U[mid] || u >= U[mid + 1]) {
+    if(u < U[mid])
+      high = mid;
+    else
+      low = mid;
+    mid = (low + high) / 2;
+  }
+  return mid;
+}
+
+void basisFuns(double u, int i, int deg, float *U, double *N)
+{
+  double left[1000];
+  double *right = &left[deg + 1];
+
+  double temp, saved;
+
+  //N.resize(deg+1) ;
+
+  N[0] = 1.0;
+  for(int j = 1; j <= deg; j++) {
+    left[j] = u - U[i + 1 - j];
+    right[j] = U[i + j] - u;
+    saved = 0.0;
+    for(int r = 0; r < j; r++) {
+      temp = N[r] / (right[r + 1] + left[j - r]);
+      N[r] = saved + right[r + 1] * temp;
+      saved = left[j - r] * temp;
+    }
+    N[j] = saved;
+  }
+}
+
+Vertex InterpolateNurbs(Curve * Curve, double u, int derivee)
+{
+  static double Nb[1000];
+  int span =
+    findSpan(u, Curve->degre, List_Nbr(Curve->Control_Points), Curve->k);
+  Vertex p, *v;
+
+  basisFuns(u, span, Curve->degre, Curve->k, Nb);
+  p.Pos.X = p.Pos.Y = p.Pos.Z = p.w = p.lc = 0.0;
+  for(int i = Curve->degre; i >= 0; --i) {
+    List_Read(Curve->Control_Points, span - Curve->degre + i, &v);
+    p.Pos.X += Nb[i] * v->Pos.X;
+    p.Pos.Y += Nb[i] * v->Pos.Y;
+    p.Pos.Z += Nb[i] * v->Pos.Z;
+    p.w += Nb[i] * v->w;
+    p.lc += Nb[i] * v->lc;
+  }
+  return p;
+}
+
+Vertex InterpolateNurbsSurface(Surface * s, double u, double v)
+{
+  int uspan = findSpan(u, s->OrderU, s->Nu, s->ku);
+  int vspan = findSpan(v, s->OrderV, s->Nv, s->kv);
+  double Nu[1000], Nv[1000];
+  Vertex sp, temp[1000], *pv;
+
+  basisFuns(u, uspan, s->OrderU, s->ku, Nu);
+  basisFuns(v, vspan, s->OrderV, s->kv, Nv);
+
+  int l, ll, kk;
+  for(l = 0; l <= s->OrderV; l++) {
+    temp[l].Pos.X = temp[l].Pos.Y = temp[l].Pos.Z = temp[l].w = temp[l].lc =
+      0.0;
+    for(int k = 0; k <= s->OrderU; k++) {
+      kk = uspan - s->OrderU + k;
+      ll = vspan - s->OrderV + l;
+      List_Read(s->Control_Points, kk + s->Nu * ll, &pv);
+      temp[l].Pos.X += Nu[k] * pv->Pos.X;
+      temp[l].Pos.Y += Nu[k] * pv->Pos.Y;
+      temp[l].Pos.Z += Nu[k] * pv->Pos.Z;
+      temp[l].w += Nu[k] * pv->w;
+      temp[l].lc += Nu[k] * pv->lc;
+    }
+  }
+  sp.Pos.X = sp.Pos.Y = sp.Pos.Z = sp.w = sp.lc = 0.0;
+  for(l = 0; l <= s->OrderV; l++) {
+    sp.Pos.X += Nv[l] * temp[l].Pos.X;
+    sp.Pos.Y += Nv[l] * temp[l].Pos.Y;
+    sp.Pos.Z += Nv[l] * temp[l].Pos.Z;
+    sp.w += Nv[l] * temp[l].w;
+    sp.lc += Nv[l] * temp[l].lc;
+  }
+  return sp;
+}
+
+
+// Surface creation helpers
+
+void CreateNurbsSurfaceSupport(int Num, int Order1, int Order2,
+                               List_T * List, List_T * ku, List_T * kv)
+{
+  // This routine has been heavily modified to fit the new interfaces,
+  // but has not been tested since then. It's probably full of bugs
+  // now.
+  List_T *ListOfDouble_L;
+  List_T *ListCP = List_Create(2, 2, sizeof(int));
+
+  for(int j = 0; j < List_Nbr(List); j++) {
+    List_Read(List, j, &ListOfDouble_L);
+    for(int i = 0; i < List_Nbr(ListOfDouble_L); i++) {
+      double d;
+      List_Read(ListOfDouble_L, i, &d);
+      int N = (int)d;
+      List_Add(ListCP, &N);
+    }
+  }
+  List_Read(List, 0, &ListOfDouble_L);
+  int Nu = List_Nbr(List);
+  int Nv = List_Nbr(ListOfDouble_L);
+
+  Surface *s = Create_Surface(Num, MSH_SURF_NURBS);
+  s->Support = NULL;
+  s->Control_Points = List_Create(4, 1, sizeof(Vertex *));
+  s->OrderU = Order1;
+  s->OrderV = Order2;
+  s->Nu = Nu;
+  s->Nv = Nv;
+  for(int i = 0; i < List_Nbr(ListCP); i++) {
+    int j;
+    List_Read(ListCP, i, &j);
+    Vertex *v = FindPoint(j);
+    if(v){
+      List_Add(s->Control_Points, &v);
+    }
+    else{
+      Msg(GERROR, "Unknown control point %d in nurbs surface", j);
+    }
+  }
+
+  s->ku = (float *)malloc(List_Nbr(ku) * sizeof(float));
+  s->kv = (float *)malloc(List_Nbr(kv) * sizeof(float));
+
+  double kumin = 0., kumax = 1.;
+  double kvmin = 0., kvmax = 1.;
+
+  for(int i = 0; i < List_Nbr(ku); i++) {
+    double d;
+    List_Read(ku, i, &d);
+    float f = (float)((d - kumin) / (kumax - kumin));
+    s->ku[i] = f;
+  }
+  for(int i = 0; i < List_Nbr(kv); i++) {
+    double d;
+    List_Read(kv, i, &d);
+    float f = (float)((d - kvmin) / (kvmax - kvmin));
+    s->kv[i] = f;
+  }
+
+  List_Delete(ListCP);
+
+  End_Surface(s);
+  Tree_Add(THEM->Surfaces, &s);
+}
+
+void CreateNurbsSurface(int Num, int Order1, int Order2, List_T * List,
+                        List_T * ku, List_T * kv)
+{
+  // This routine has been heavily modified to fit the new interfaces,
+  // but has not been tested since then. It's probably full of bugs
+  // now.
+
+  List_T *ListOfDouble_L, *Listint, *ListCP;
+  int Loop[4];
+
+  ListCP = List_Create(2, 2, sizeof(int));
+
+  double kumin, kumax;
+  List_Read(ku, 0, &kumin);
+  List_Read(ku, List_Nbr(ku) - 1, &kumax);
+  double kvmin, kvmax;
+  List_Read(kv, 0, &kvmin);
+  List_Read(kv, List_Nbr(kv) - 1, &kvmax);
+  for(int j = 0; j < List_Nbr(List); j++) {
+    List_Read(List, j, &ListOfDouble_L);
+    for(int i = 0; i < List_Nbr(ListOfDouble_L); i++) {
+      double d;
+      List_Read(ListOfDouble_L, i, &d);
+      int N = (int)d;
+      List_Add(ListCP, &N);
+    }
+  }
+
+  // 1st and 3rd gen
+  List_Read(List, 0, &ListOfDouble_L);
+  Listint = ListOfDouble2ListOfInt(ListOfDouble_L);
+  if(recognize_seg(MSH_SEGM_NURBS, Listint, &Loop[0])) {
+  }
+  else {
+    Loop[0] = NEWREG();
+    Curve *c = Create_Curve(Loop[0], MSH_SEGM_NURBS, Order1, Listint, NULL, 
+			    -1, -1, kumin, kumax);
+    Tree_Add(THEM->Curves, &c);
+    CreateReversedCurve(c);
+    c->k = (float *)malloc(4 * List_Nbr(ku) * sizeof(float));
+    for(int i = 0; i < List_Nbr(ku); i++) {
+      double d;
+      List_Read(ku, i, &d);
+      c->k[i] = (float)d /*((d-kumin)/(kumax-kumin)) */ ;
+    }
+  }
+  List_Delete(Listint);
+
+  List_Read(List, List_Nbr(List) - 1, &ListOfDouble_L);
+  Listint = ListOfDouble2ListOfInt(ListOfDouble_L);
+  if(recognize_seg(MSH_SEGM_NURBS, Listint, &Loop[2])) {
+  }
+  else {
+    Loop[2] = NEWREG();
+    Curve *c = Create_Curve(Loop[2], MSH_SEGM_NURBS, Order1, Listint, NULL, 
+			    -1, -1, kumin, kumax);
+    Tree_Add(THEM->Curves, &c);
+    CreateReversedCurve(c);
+    c->k = (float *)malloc(4 * List_Nbr(ku) * sizeof(float));
+    for(int i = 0; i < List_Nbr(ku); i++) {
+      double d;
+      List_Read(ku, i, &d);
+      c->k[i] = (float)d /*((d-kumin)/(kumax-kumin)) */ ;
+    }
+  }
+  List_Delete(Listint);
+
+  // 2nd and 4th gen
+  List_T *List1 = List_Create(List_Nbr(List), 1, sizeof(double));
+  List_T *List2 = List_Create(List_Nbr(List), 1, sizeof(double));
+  for(int i = 0; i < List_Nbr(List); i++) {
+    List_Read(List, i, &ListOfDouble_L);
+    List_Add(List1, List_Pointer(ListOfDouble_L, 0));
+    List_Add(List2, List_Pointer(ListOfDouble_L, List_Nbr(ListOfDouble_L) - 1));
+  }
+
+  Listint = ListOfDouble2ListOfInt(List1);
+  if(recognize_seg(MSH_SEGM_NURBS, Listint, &Loop[1])) {
+  }
+  else {
+    Loop[1] = NEWREG();
+    Curve *c = Create_Curve(Loop[1], MSH_SEGM_NURBS, Order2, Listint, NULL, 
+			    -1, -1, kumin, kumax);
+    Tree_Add(THEM->Curves, &c);
+    CreateReversedCurve(c);
+    c->k = (float *)malloc(4 * List_Nbr(kv) * sizeof(float));
+    for(int i = 0; i < List_Nbr(kv); i++) {
+      double d;
+      List_Read(kv, i, &d);
+      c->k[i] = (float)d /*((d-kvmin)/(kvmax-kvmin)) */ ;
+    }
+  }
+  List_Delete(Listint);
+
+  Listint = ListOfDouble2ListOfInt(List2);
+  if(recognize_seg(MSH_SEGM_NURBS, Listint, &Loop[3])) {
+  }
+  else {
+    Loop[3] = NEWREG();
+    Curve *c = Create_Curve(Loop[3], MSH_SEGM_NURBS, Order2, Listint, NULL,
+			    -1, -1, kumin, kumax);
+    Tree_Add(THEM->Curves, &c);
+    CreateReversedCurve(c);
+    c->k = (float *)malloc(4 * List_Nbr(kv) * sizeof(float));
+    for(int i = 0; i < List_Nbr(kv); i++) {
+      double d;
+      List_Read(kv, i, &d);
+      c->k[i] = (float)d /*((d-kvmin)/(kvmax-kvmin)) */ ;
+    }
+  }
+  List_Delete(Listint);
+  List_Delete(List1);
+  List_Delete(List2);
+
+  Listint = List_Create(10, 10, sizeof(int));
+  int l0 = -Loop[0];
+  List_Add(Listint, &l0);
+  List_Add(Listint, &Loop[1]);
+  List_Add(Listint, &Loop[2]);
+  int l3 = -Loop[3];
+  List_Add(Listint, &l3);
+
+  int topnew = NEWREG();
+  CreateNurbsSurfaceSupport(topnew, Order1, Order2, List, ku, kv);
+
+  int il = NEWREG();
+  SurfaceLoop *l = Create_SurfaceLoop(il, Listint);
+  Tree_Add(THEM->SurfaceLoops, &l);
+  List_Reset(Listint);
+  List_Add(Listint, &il);
+
+  Surface *s = Create_Surface(NEWREG(), MSH_SURF_TRIMMED);
+  setSurfaceGeneratrices(s, Listint);
+  s->Support = s;
+  End_Surface(s);
+  Tree_Add(THEM->Surfaces, &s);
+
+  List_Delete(Listint);
+  List_Delete(ListCP);
+}
+
diff --git a/Mesh/Interpolation.h b/Geo/GeoInterpolation.h
similarity index 74%
rename from Mesh/Interpolation.h
rename to Geo/GeoInterpolation.h
index f58638c91b..a155eb95c7 100644
--- a/Mesh/Interpolation.h
+++ b/Geo/GeoInterpolation.h
@@ -1,5 +1,5 @@
-#ifndef _INTERPOLATION_H_
-#define _INTERPOLATION_H_
+#ifndef _GEO_INTERPOLATION_H_
+#define _GEO_INTERPOLATION_H_
 
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -20,8 +20,7 @@
 // 
 // Please report all bugs and problems to <gmsh@geuz.org>.
 
-#include "Vertex.h"
-#include "Mesh.h"
+#include "Geo.h"
 
 Vertex InterpolateCurve (Curve * Curve, double u, int derivee);
 
@@ -48,6 +47,16 @@ void TransfiniteSph (Vertex S, Vertex center, Vertex * T);
 
 void Normal2Surface (Surface * s, double u, double v, double n[3]);
 
+Vertex InterpolateCubicSpline (Vertex * v[4], double t, double mat[4][4],
+                               int derivee, double t1, double t2);
+Vertex InterpolateUBS (Curve * Curve, double u, int derivee);
+Vertex InterpolateNurbs (Curve * Curve, double u, int derivee);
+Vertex InterpolateNurbsSurface (Surface * s, double u, double v);
+
+void CreateNurbsSurface (int Num, int Order1, int Order2, List_T *, List_T *, List_T *);
+void CreateNurbsSurfaceSupport (int Num, int Order2, int Order1, 
+                                List_T * List, List_T *, List_T *);
+
 #endif
 
 
diff --git a/Geo/GeoStringInterface.cpp b/Geo/GeoStringInterface.cpp
new file mode 100644
index 0000000000..ff238b56ba
--- /dev/null
+++ b/Geo/GeoStringInterface.cpp
@@ -0,0 +1,545 @@
+// $Id: GeoStringInterface.cpp,v 1.1 2006-11-25 16:52:43 geuzaine Exp $
+//
+// Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+// 
+// Please report all bugs and problems to <gmsh@geuz.org>.
+
+#include "Gmsh.h"
+#include "Numeric.h"
+#include "Geo.h"
+#include "GeoStringInterface.h"
+#include "Parser.h"
+#include "Context.h"
+#include "GModel.h"
+
+extern Context_T CTX;
+extern GModel *GMODEL;
+
+#define BUFFSIZE 128000
+
+// Some old systems don't have snprintf... Just call sprintf instead.
+
+#if defined(HAVE_NO_SNPRINTF)
+int snprintf(char *str, size_t size, const char* fmt, ...){
+  va_list args;
+  va_start(args, fmt);
+  int ret = vsprintf(str, fmt, args);
+  va_end(args);
+  return ret;
+}
+#endif
+
+double evaluate_scalarfunction(char *var, double val, char *funct)
+{
+  FILE *tempf;
+  tempf = yyin;
+
+  if(!(yyin = fopen(CTX.tmp_filename_fullpath, "w"))) {
+    Msg(GERROR, "Unable to open temporary file '%s'", CTX.tmp_filename_fullpath);
+    return 0.;
+  }
+
+  // pose "variable = function" and evaluate function
+  fprintf(yyin, "%s = %.16g ;\n", var, val);
+  fprintf(yyin, "ValeurTemporaire__ = %s ;\n", funct);
+  fclose(yyin);
+  yyin = fopen(CTX.tmp_filename_fullpath, "r");
+  while(!feof(yyin)) {
+    yyparse();
+  }
+  fclose(yyin);
+  yyin = tempf;
+
+  // retreive value
+  Symbol TheSymbol, *TheSymbol_P;
+  TheSymbol.Name = (char *)Malloc(100*sizeof(char));
+  strcpy(TheSymbol.Name, "ValeurTemporaire__");
+  if(!(TheSymbol_P = (Symbol*)Tree_PQuery(Symbol_T, &TheSymbol))) {
+    Free(TheSymbol.Name);
+    return 0.0;
+  }
+  Free(TheSymbol.Name);
+  return *(double *)List_Pointer(TheSymbol_P->val, 0);
+}
+
+void add_infile(char *text, char *fich, bool deleted_something)
+{
+  FILE *file;
+
+  if(!(yyin = fopen(CTX.tmp_filename_fullpath, "w"))) {
+    Msg(GERROR, "Unable to open temporary file '%s'", CTX.tmp_filename_fullpath);
+    return;
+  }
+  if(!(file = fopen(fich, "a"))) {
+    Msg(GERROR, "Unable to open file '%s'", fich);
+    return;
+  }
+  fprintf(yyin, "%s\n", text);
+  Msg(STATUS2, "%s", text);
+  fclose(yyin);
+  yyin = fopen(CTX.tmp_filename_fullpath, "r");
+  while(!feof(yyin)) {
+    yyparse();
+  }
+  fclose(yyin);
+  fprintf(file, "%s\n", text);
+  fclose(file);
+
+  if(deleted_something){
+    // we need to start from scratch since the command just parsed
+    // could have deleted some entities
+    GMODEL->destroy();
+  }
+  GMODEL->importTHEM();
+  CTX.mesh.changed = ENT_ALL;
+}
+
+void coherence(char *fich)
+{
+  add_infile("Coherence;", fich, true);
+}
+
+void strncat_list(char *text, List_T *list)
+{
+  char text2[BUFFSIZE];
+  for(int i = 0; i < List_Nbr(list); i++){
+    int num;
+    List_Read(list, i, &num);
+    if(!i)
+      snprintf(text2, BUFFSIZE, "%d", num);
+    else
+      snprintf(text2, BUFFSIZE, ",%d", num);
+    strncat(text, text2, BUFFSIZE-strlen(text));
+  }
+}
+
+void delet(List_T *list, char *fich, char *what)
+{
+  char text[BUFFSIZE];
+
+  snprintf(text, BUFFSIZE, "Delete {\n  %s{", what);
+  strncat_list(text, list);
+  strncat(text, "};\n}", BUFFSIZE-strlen(text));
+  add_infile(text, fich, true);
+}
+
+void add_trsfellisurf(int type, int N, int *l, char *fich, char *dir)
+{
+  char text[BUFFSIZE], text2[BUFFSIZE];
+
+  snprintf(text, BUFFSIZE, "%s Surface {%d} = {", 
+	   type ? "Elliptic" : "Transfinite", l[0]);
+  for(int i = 1; i < N; i++) {
+    if(i == 1)
+      snprintf(text2, BUFFSIZE, "%d", l[i]);
+    else
+      snprintf(text2, BUFFSIZE, ",%d", l[i]);
+    strncat(text, text2, BUFFSIZE-strlen(text));
+  }
+  if (!strcmp(dir,"Left"))
+    snprintf(text2, BUFFSIZE, "};");
+  else
+    snprintf(text2, BUFFSIZE, "} %s;",dir);
+
+  strncat(text, text2, BUFFSIZE-strlen(text));
+  add_infile(text, fich);
+}
+
+void add_charlength(List_T *list, char *fich, char *lc)
+{
+  char text[BUFFSIZE];
+
+  snprintf(text, BUFFSIZE, "Characteristic Length {");
+  strncat_list(text, list);
+  strncat(text, "} = ", BUFFSIZE-strlen(text));
+  strncat(text, lc, BUFFSIZE-strlen(text));
+  strncat(text, ";", BUFFSIZE-strlen(text));
+  add_infile(text, fich);
+}
+
+void add_recosurf(List_T *list, char *fich)
+{
+  char text[BUFFSIZE];
+
+  snprintf(text, BUFFSIZE, "Recombine Surface {");
+  strncat_list(text, list);
+  strncat(text, "};", BUFFSIZE-strlen(text));
+  add_infile(text, fich);
+}
+
+void add_trsfline(int N, int *l, char *fich, char *type, char *typearg, char *pts)
+{
+  char text[BUFFSIZE], text2[BUFFSIZE];
+
+  snprintf(text, BUFFSIZE, "Transfinite Line {");
+  for(int i = 0; i < N; i++) {
+    if(!i)
+      snprintf(text2, BUFFSIZE, "%d", l[i]);
+    else
+      snprintf(text2, BUFFSIZE, ",%d", l[i]);
+    strncat(text, text2, BUFFSIZE-strlen(text));
+  }
+  if(strlen(typearg))
+    snprintf(text2, BUFFSIZE, "} = %s Using %s %s;", pts, type, typearg);
+  else
+    snprintf(text2, BUFFSIZE, "} = %s;", pts);
+  strncat(text, text2, BUFFSIZE-strlen(text));
+  add_infile(text, fich);
+}
+
+void add_param(char *par, char *value, char *fich)
+{
+  char text[BUFFSIZE];
+  snprintf(text, BUFFSIZE, "%s = %s;", par, value);
+  add_infile(text, fich);
+}
+
+void add_point(char *fich, char *x, char *y, char *z, char *lc)
+{
+  char text[BUFFSIZE];
+  int ip = NEWPOINT();
+  snprintf(text, BUFFSIZE, "Point(%d) = {%s,%s,%s,%s};", ip, x, y, z, lc);
+  add_infile(text, fich);
+}
+
+void add_attractor(char *fich, int ip, int typ, char *ax, char *ay, char *ad)
+{
+  char text[BUFFSIZE];
+  if(typ == 0) {
+    snprintf(text, BUFFSIZE, "Attractor Point {%d} = {%s,%s,%s} = ;", ip, ax, ay, ad);
+  }
+  else if(typ == 1) {
+    snprintf(text, BUFFSIZE, "Attractor Line {%d} = {%s,%s,%s};", ip, ax, ay, ad);
+  }
+  else if(typ == 2) {
+    snprintf(text, BUFFSIZE, "Attractor Surface {%d} = {%s,%s,%s};", ip, ax, ay, ad);
+  }
+  add_infile(text, fich);
+}
+
+
+void add_line(int p1, int p2, char *fich)
+{
+  char text[BUFFSIZE];
+  int iseg;
+  List_T *list = List_Create(2, 2, sizeof(int));
+  List_Add(list, &p1);
+  List_Add(list, &p2);
+  if((recognize_seg(MSH_SEGM_LINE, list, &iseg))) {
+    List_Delete(list);
+    return;
+  }
+  List_Delete(list);
+
+  snprintf(text, BUFFSIZE, "Line(%d) = {%d,%d};", NEWLINE(), p1, p2);
+  add_infile(text, fich);
+}
+
+void add_circ(int p1, int p2, int p3, char *fich)
+{
+  char text[BUFFSIZE];
+
+  snprintf(text, BUFFSIZE, "Circle(%d) = {%d,%d,%d};", NEWLINE(), p1, p2, p3);
+  add_infile(text, fich);
+}
+
+void add_ell(int p1, int p2, int p3, int p4, char *fich)
+{
+  char text[BUFFSIZE];
+
+  snprintf(text, BUFFSIZE, "Ellipse(%d) = {%d,%d,%d,%d};", NEWLINE(), p1, p2,
+           p3, p4);
+  add_infile(text, fich);
+}
+
+void add_spline(int N, int *p, char *fich)
+{
+  char text[BUFFSIZE], text2[BUFFSIZE];
+
+  snprintf(text, BUFFSIZE, "CatmullRom(%d) = {", NEWLINE());
+  for(int i = 0; i < N; i++) {
+    if(i != N - 1)
+      snprintf(text2, BUFFSIZE, "%d,", p[i]);
+    else
+      snprintf(text2, BUFFSIZE, "%d};", p[i]);
+    strncat(text, text2, BUFFSIZE-strlen(text));
+  }
+  add_infile(text, fich);
+}
+
+void add_bezier(int N, int *p, char *fich)
+{
+  char text[BUFFSIZE], text2[BUFFSIZE];
+
+  snprintf(text, BUFFSIZE, "Bezier(%d) = {", NEWLINE());
+  for(int i = 0; i < N; i++) {
+    if(i != N - 1)
+      snprintf(text2, BUFFSIZE, "%d,", p[i]);
+    else
+      snprintf(text2, BUFFSIZE, "%d};", p[i]);
+    strncat(text, text2, BUFFSIZE-strlen(text));
+  }
+  add_infile(text, fich);
+}
+
+
+void add_bspline(int N, int *p, char *fich)
+{
+  char text[BUFFSIZE], text2[BUFFSIZE];
+
+  snprintf(text, BUFFSIZE, "BSpline(%d) = {", NEWLINE());
+  for(int i = 0; i < N; i++) {
+    if(i != N - 1)
+      snprintf(text2, BUFFSIZE, "%d,", p[i]);
+    else
+      snprintf(text2, BUFFSIZE, "%d};", p[i]);
+    strncat(text, text2, BUFFSIZE-strlen(text));
+  }
+  add_infile(text, fich);
+}
+
+void add_multline(int N, int *p, char *fich)
+{
+  char text[BUFFSIZE], text2[BUFFSIZE];
+  int iseg;
+
+  List_T *list = List_Create(N, 2, sizeof(int));
+  for(int i = 0; i < N; i++)
+    List_Add(list, &p[i]);
+  if((recognize_seg(MSH_SEGM_LINE, list, &iseg))) {
+    List_Delete(list);
+    return;
+  }
+  List_Delete(list);
+
+  snprintf(text, BUFFSIZE, "Line(%d) = {", NEWLINE());
+  for(int i = 0; i < N; i++) {
+    if(i != N - 1)
+      snprintf(text2, BUFFSIZE, "%d,", p[i]);
+    else
+      snprintf(text2, BUFFSIZE, "%d};", p[i]);
+    strncat(text, text2, BUFFSIZE-strlen(text));
+  }
+  add_infile(text, fich);
+}
+
+void add_lineloop(List_T *list, char *fich, int *numloop)
+{
+  char text[BUFFSIZE];
+
+  if((recognize_loop(list, numloop)))
+    return;
+
+  *numloop = NEWLINELOOP();
+  snprintf(text, BUFFSIZE, "Line Loop(%d) = {", *numloop);
+  strncat_list(text, list);
+  strncat(text, "};", BUFFSIZE-strlen(text));
+  add_infile(text, fich);
+}
+
+
+void add_surf(List_T *list, char *fich, int support, int typ)
+{
+  char text[BUFFSIZE];
+
+  if(typ == 1) {
+    snprintf(text, BUFFSIZE, "Ruled Surface(%d) = {", NEWSURFACE());
+  }
+  else if(typ == 2) {
+    snprintf(text, BUFFSIZE, "Plane Surface(%d) = {", NEWSURFACE());
+  }
+  else {
+    snprintf(text, BUFFSIZE, "Trimmed Surface(%d) = %d {", NEWSURFACE(), support);
+  }
+  strncat_list(text, list);
+  strncat(text, "};", BUFFSIZE-strlen(text));
+  add_infile(text, fich);
+}
+
+void add_surfloop(List_T *list, char *fich, int *numvol)
+{
+  char text[BUFFSIZE];
+
+  if((recognize_surfloop(list, numvol)))
+    return;
+
+  *numvol = NEWSURFACELOOP();
+  snprintf(text, BUFFSIZE, "Surface Loop(%d) = {", *numvol);
+  strncat_list(text, list);
+  strncat(text, "};", BUFFSIZE-strlen(text));
+  add_infile(text, fich);
+}
+
+void add_vol(List_T *list, char *fich)
+{
+  char text[BUFFSIZE];
+
+  snprintf(text, BUFFSIZE, "Volume(%d) = {", NEWVOLUME());
+  strncat_list(text, list);
+  strncat(text, "};", BUFFSIZE-strlen(text));
+  add_infile(text, fich);
+}
+
+void add_trsfvol(int N, int *l, char *fich)
+{
+  char text[BUFFSIZE], text2[BUFFSIZE];
+
+  snprintf(text, BUFFSIZE, "Transfinite Volume{%d} = {", l[0]);
+  for(int i = 1; i < N; i++) {
+    if(i == 1)
+      snprintf(text2, BUFFSIZE, "%d", l[i]);
+    else
+      snprintf(text2, BUFFSIZE, ",%d", l[i]);
+    strncat(text, text2, BUFFSIZE-strlen(text));
+  }
+  snprintf(text2, BUFFSIZE, "};");
+  strncat(text, text2, BUFFSIZE-strlen(text));
+  add_infile(text, fich);
+}
+
+int add_physical(List_T *list, char *fich, int type)
+{
+  char text[BUFFSIZE];
+  int num = NEWPHYSICAL();
+  
+  switch (type) {
+  case ENT_POINT:
+    snprintf(text, BUFFSIZE, "Physical Point(%d) = {", num);
+    break;
+  case ENT_LINE:
+    snprintf(text, BUFFSIZE, "Physical Line(%d) = {", num);
+    break;
+  case ENT_SURFACE:
+    snprintf(text, BUFFSIZE, "Physical Surface(%d) = {", num);
+    break;
+  case ENT_VOLUME:
+    snprintf(text, BUFFSIZE, "Physical Volume(%d) = {", num);
+    break;
+  }
+
+  strncat_list(text, list);
+  strncat(text, "};", BUFFSIZE-strlen(text));
+  add_infile(text, fich);
+  
+  return num;
+}
+
+void translate(int add, List_T *list, char *fich, char *what, char *tx, char *ty, char *tz)
+{
+  char text[BUFFSIZE];
+
+  if(add)
+    snprintf(text, BUFFSIZE, "Translate {%s,%s,%s} {\n  Duplicata { %s{", tx, ty, tz, what);
+  else
+    snprintf(text, BUFFSIZE, "Translate {%s,%s,%s} {\n  %s{", tx, ty, tz, what);
+
+  strncat_list(text, list);
+  
+  if(add)
+    strncat(text, "}; }\n}", BUFFSIZE-strlen(text));
+  else
+    strncat(text, "};\n}", BUFFSIZE-strlen(text));
+
+  add_infile(text, fich);
+}
+
+void rotate(int add, List_T *list, char *fich, char *what, char *ax, char *ay, char *az,
+	    char *px, char *py, char *pz, char *angle)
+{
+  char text[BUFFSIZE];
+
+  if(add)
+    snprintf(text, BUFFSIZE, "Rotate {{%s,%s,%s}, {%s,%s,%s}, %s} {\n  Duplicata { %s{",
+             ax, ay, az, px, py, pz, angle, what);
+  else
+    snprintf(text, BUFFSIZE, "Rotate {{%s,%s,%s}, {%s,%s,%s}, %s} {\n  %s{",
+             ax, ay, az, px, py, pz, angle, what);
+
+  strncat_list(text, list);
+
+  if(add)
+    strncat(text, "}; }\n}", BUFFSIZE-strlen(text));
+  else
+    strncat(text, "};\n}", BUFFSIZE-strlen(text));
+
+  add_infile(text, fich);
+}
+
+void dilate(int add, List_T *list, char *fich, char *what, char *dx, char *dy, char *dz, char *df)
+{
+  char text[BUFFSIZE];
+
+  if(add)
+    snprintf(text, BUFFSIZE, "Dilate {{%s,%s,%s}, %s} {\n  Duplicata { %s{",
+             dx, dy, dz, df, what);
+  else
+    snprintf(text, BUFFSIZE, "Dilate {{%s,%s,%s}, %s} {\n  %s{",
+             dx, dy, dz, df, what);
+
+  strncat_list(text, list);
+
+  if(add)
+    strncat(text, "}; }\n}", BUFFSIZE-strlen(text));
+  else
+    strncat(text, "};\n}", BUFFSIZE-strlen(text));
+
+  add_infile(text, fich);
+}
+
+void symmetry(int add, List_T *list, char *fich, char *what, char *sa, char *sb, char *sc, char *sd)
+{
+  char text[BUFFSIZE];
+
+  if(add)
+    snprintf(text, BUFFSIZE, "Symmetry {%s,%s,%s,%s} {\n  Duplicata { %s{",
+             sa, sb, sc, sd, what);
+  else
+    snprintf(text, BUFFSIZE, "Symmetry {%s,%s,%s,%s} {\n  %s{",
+             sa, sb, sc, sd, what);
+
+  strncat_list(text, list);
+
+  if(add)
+    strncat(text, "}; }\n}", BUFFSIZE-strlen(text));
+  else
+    strncat(text, "};\n}", BUFFSIZE-strlen(text));
+
+  add_infile(text, fich);
+}
+
+void extrude(List_T *list, char *fich, char *what, char *tx, char *ty, char *tz)
+{
+  char text[BUFFSIZE];
+
+  snprintf(text, BUFFSIZE, "Extrude {%s,%s,%s} {\n  %s{", tx, ty, tz, what);
+  strncat_list(text, list);
+  strncat(text, "};\n}", BUFFSIZE-strlen(text));
+  add_infile(text, fich);
+}
+
+void protude(List_T *list, char *fich, char *what, char *ax, char *ay, char *az,
+	     char *px, char *py, char *pz, char *angle)
+{
+  char text[BUFFSIZE];
+
+  snprintf(text, BUFFSIZE, "Extrude {{%s,%s,%s}, {%s,%s,%s}, %s} {\n  %s{",
+           ax, ay, az, px, py, pz, angle, what);
+  strncat_list(text, list);
+  strncat(text, "};\n}", BUFFSIZE-strlen(text));
+  add_infile(text, fich);
+}
diff --git a/Geo/GeoStringInterface.h b/Geo/GeoStringInterface.h
new file mode 100644
index 0000000000..6ed594299c
--- /dev/null
+++ b/Geo/GeoStringInterface.h
@@ -0,0 +1,64 @@
+#ifndef _GEO_STRING_INTERFACE_H_
+#define _GEO_STRING_INTERFACE_H_
+
+// Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+// 
+// Please report all bugs and problems to <gmsh@geuz.org>.
+
+#include "Geo.h"
+#include "List.h"
+
+double evaluate_scalarfunction (char *var, double val, char *funct);
+
+void coherence(char *fich);
+void delet(List_T *list, char *fich, char *what);
+void add_infile(char *text, char *fich, bool deleted_something=false);
+void add_trsfline(int N, int *l, char *fich, char *type, char *typearg, char *pts);
+void add_trsfellisurf(int type, int N, int *l, char *fich, char *dir);
+void add_trsfvol(int N, int *l, char *fich);
+void add_charlength(List_T *list, char *fich, char *lc);
+void add_recosurf(List_T *list, char *fich);
+void add_param(char *par, char *value, char *fich);
+void add_point(char *fich, char *x, char *y, char *z, char *lc);
+void add_attractor(char *fich, int ip, int typ);
+void add_line(int p1, int p2, char *fich);
+void add_circ(int p1, int p2, int p3, char *fich);
+void add_ell(int p1, int p2, int p3, int p4, char *fich);
+void add_spline(int N, int *p, char *fich);
+void add_bezier(int N, int *p, char *fich);
+void add_bspline(int N, int *p, char *fich);
+void add_multline(int N, int *p, char *fich);
+void add_lineloop(List_T *list, char *fich, int *numloop);
+void add_surf(List_T *list, char *fich, int support, int typ);
+void add_surfloop(List_T *list, char *fich, int *numvol);
+void add_vol(List_T *list, char *fich);
+int add_physical(List_T *list, char *fich, int type);
+void translate(int add, List_T *list, char *fich, char *what,
+	       char *tx, char *ty, char *tz);
+void rotate(int add, List_T *list, char *fich, char *what, 
+	    char *ax, char *ay, char *az,
+	    char *px, char *py, char *pz, char *angle);
+void dilate(int add, List_T *list, char *fich, char *what,
+	    char *dx, char *dy, char *dz, char *df);
+void symmetry(int add, List_T *list, char *fich, char *what, 
+	      char *sa, char *sb, char *sc, char *sd);
+void extrude(List_T *list, char *fich, char *what, char *tx, char *ty, char *tz);
+void protude(List_T *list, char *fich, char *what, char *ax, char *ay, char *az,
+	     char *px, char *py, char *pz, char *angle);
+
+#endif
diff --git a/Geo/GeoUtils.cpp b/Geo/GeoUtils.cpp
index 9daaa0c5de..be05570529 100644
--- a/Geo/GeoUtils.cpp
+++ b/Geo/GeoUtils.cpp
@@ -1,4 +1,4 @@
-// $Id: GeoUtils.cpp,v 1.15 2006-11-25 00:44:25 geuzaine Exp $
+// $Id: GeoUtils.cpp,v 1.16 2006-11-25 16:52:43 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -21,8 +21,6 @@
 
 #include "Gmsh.h"
 #include "Geo.h"
-#include "CAD.h"
-#include "Mesh.h"
 #include "Numeric.h"
 
 extern Mesh *THEM;
@@ -41,25 +39,8 @@ void sortEdgesInLoop(int num, List_T *edges)
   for(int i = 0; i < nbEdges; i++) {
     int j;
     List_Read(edges, i, &j);
-    if((c = FindCurve(j))){
+    if((c = FindCurve(j)))
       List_Add(temp, &c);
-      if(c->Typ == MSH_SEGM_DISCRETE){
-	// fill-in vertices in reverse discrete curves
-	if(c->Num < 0 && !List_Nbr(c->Vertices)){
-	  Curve *rc = FindCurve(-c->Num);
-	  if(rc)
-	    for(int k = List_Nbr(rc->Vertices) - 1; k >= 0; k--)
-	      List_Add(c->Vertices, List_Pointer(rc->Vertices, k));
-	}
-	// set end points for discrete curves
-	if(!c->beg && !c->end && List_Nbr(c->Vertices)){
-	  Vertex *first = *(Vertex**)List_Pointer(c->Vertices, 0);
-	  Vertex *last = *(Vertex**)List_Pointer(c->Vertices, List_Nbr(c->Vertices) - 1);
-	  c->beg = FindPoint(first->Num);
-	  c->end = FindPoint(last->Num);
-	}
-      }
-    }
     else
       Msg(GERROR, "Unknown curve %d in line loop %d", j, num);
   }
diff --git a/Geo/GeoUtils.h b/Geo/GeoUtils.h
index 28ee80d9f3..63cd211ee3 100644
--- a/Geo/GeoUtils.h
+++ b/Geo/GeoUtils.h
@@ -20,7 +20,7 @@
 // 
 // Please report all bugs and problems to <gmsh@geuz.org>.
 
-#include "Mesh.h"
+#include "Geo.h"
 #include "List.h"
 
 void sortEdgesInLoop(int num, List_T *edges);
diff --git a/Geo/Makefile b/Geo/Makefile
index dd5074085e..ee7d667839 100644
--- a/Geo/Makefile
+++ b/Geo/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.114 2006-11-25 02:47:39 geuzaine Exp $
+# $Id: Makefile,v 1.115 2006-11-25 16:52:43 geuzaine Exp $
 #
 # Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 #
@@ -26,35 +26,25 @@ INCLUDE = -I../Common -I../DataStr -I../Geo -I../Mesh -I../Numeric\
           -I../Parser -I../Fltk -I../contrib/NR -I../contrib/FourierModel
 CFLAGS  = ${OPTIM} ${FLAGS} ${INCLUDE} 
 
-SRC = CAD.cpp \
+SRC = GEntity.cpp\
+        GVertex.cpp GEdge.cpp GEdgeLoop.cpp GFace.cpp GRegion.cpp\
+        gmshEdge.cpp gmshFace.cpp gmshRegion.cpp\
+        OCCVertex.cpp OCCEdge.cpp OCCFace.cpp OCCRegion.cpp\
+        projectionFace.cpp\
+      GModel.cpp\
+        GModelIO_Geo.cpp\
+        GModelIO_Mesh.cpp\
+        GModelIO_Fourier.cpp\
+        GModelIO_OCC.cpp\
+        GModelIO_CGNS.cpp\
       ExtrudeParams.cpp \
       Geo.cpp \
-      GeoUtils.cpp \
-      GEntity.cpp\
-      GVertex.cpp\
-      GEdge.cpp\
-      GEdgeLoop.cpp\
-      GFace.cpp\
-      GRegion.cpp\
+	GeoStringInterface.cpp GeoInterpolation.cpp\
+        GeoUtils.cpp GeoExtractContour.cpp\
       MVertex.cpp \
       MElement.cpp \
-      GModel.cpp\
-      GModelIO_Mesh.cpp\
-      GModelIO_Geo.cpp\
-      GModelIO_Fourier.cpp\
-      GModelIO_OCC.cpp\
-      GModelIO_CGNS.cpp\
-      gmshEdge.cpp\
-      gmshFace.cpp\
-      gmshRegion.cpp\
-      OCCVertex.cpp\
-      OCCEdge.cpp\
-      OCCFace.cpp\
-      OCCRegion.cpp\
       SVector3.cpp\
-      SBoundingBox3d.cpp\
-      projectionFace.cpp\
-      ExtractContour.cpp
+      SBoundingBox3d.cpp
 
 OBJ = ${SRC:.cpp=.o}
 
@@ -79,32 +69,6 @@ depend:
 	rm -f Makefile.new
 
 # DO NOT DELETE THIS LINE
-CAD.o: CAD.cpp ../Common/Gmsh.h ../Common/Message.h ../DataStr/Malloc.h \
-  ../DataStr/List.h ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h \
-  ../DataStr/List.h ../DataStr/Tree.h ../Numeric/Numeric.h Geo.h \
-  ../Mesh/Mesh.h ../Common/GmshDefines.h ../Mesh/Vertex.h \
-  ../Geo/ExtrudeParams.h ../Mesh/Interpolation.h ../Mesh/Vertex.h \
-  ../Mesh/Mesh.h ../Mesh/Create.h ../Mesh/Vertex.h ../Mesh/Mesh.h CAD.h \
-  ExtrudeParams.h ../Common/Context.h
-ExtrudeParams.o: ExtrudeParams.cpp ../Common/Gmsh.h ../Common/Message.h \
-  ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
-  ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
-  Geo.h CAD.h ../Mesh/Mesh.h ../Common/GmshDefines.h ../Mesh/Vertex.h \
-  ../Geo/ExtrudeParams.h ExtrudeParams.h
-Geo.o: Geo.cpp ../Common/Gmsh.h ../Common/Message.h ../DataStr/Malloc.h \
-  ../DataStr/List.h ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h \
-  ../DataStr/List.h ../DataStr/Tree.h ../Numeric/Numeric.h Geo.h CAD.h \
-  ../Mesh/Mesh.h ../Common/GmshDefines.h ../Mesh/Vertex.h \
-  ../Geo/ExtrudeParams.h ExtrudeParams.h ../Parser/Parser.h \
-  ../Common/Context.h GModel.h GVertex.h GEntity.h Range.h SPoint3.h \
-  SBoundingBox3d.h MVertex.h GPoint.h SPoint2.h GEdge.h SVector3.h \
-  MElement.h MEdge.h ../Common/Hash.h MFace.h GFace.h GEdgeLoop.h Pair.h \
-  GRegion.h ../Common/SmoothNormals.h
-GeoUtils.o: GeoUtils.cpp ../Common/Gmsh.h ../Common/Message.h \
-  ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
-  ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
-  Geo.h CAD.h ../Mesh/Mesh.h ../Common/GmshDefines.h ../Mesh/Vertex.h \
-  ../Geo/ExtrudeParams.h ExtrudeParams.h ../Numeric/Numeric.h
 GEntity.o: GEntity.cpp GEntity.h Range.h SPoint3.h SBoundingBox3d.h \
   ../Common/GmshDefines.h MRep.h GEdge.h GVertex.h MVertex.h GPoint.h \
   SPoint2.h SVector3.h MElement.h MEdge.h ../Common/Hash.h MFace.h \
@@ -133,137 +97,150 @@ GFace.o: GFace.cpp GModel.h GVertex.h GEntity.h Range.h SPoint3.h \
   ../Numeric/Numeric.h ../Common/Context.h ../DataStr/List.h \
   ExtrudeParams.h GFace.h GEdgeLoop.h Pair.h GRegion.h \
   ../Common/SmoothNormals.h ../Common/Message.h ../Mesh/Utils.h \
-  ../Mesh/Vertex.h ../Mesh/Mesh.h ../DataStr/Tree.h ../DataStr/avl.h \
-  ../Mesh/Vertex.h ../Geo/ExtrudeParams.h
+  ../Geo/Geo.h ../DataStr/Tree.h ../DataStr/avl.h ../Geo/ExtrudeParams.h
 GRegion.o: GRegion.cpp GModel.h GVertex.h GEntity.h Range.h SPoint3.h \
   SBoundingBox3d.h ../Common/GmshDefines.h MVertex.h GPoint.h SPoint2.h \
   GEdge.h SVector3.h MElement.h MEdge.h ../Common/Hash.h MFace.h \
   ../Numeric/Numeric.h ../Common/Context.h ../DataStr/List.h \
   ExtrudeParams.h GFace.h GEdgeLoop.h Pair.h GRegion.h \
   ../Common/SmoothNormals.h
-MVertex.o: MVertex.cpp MVertex.h SPoint3.h
-MElement.o: MElement.cpp MElement.h ../Common/GmshDefines.h MVertex.h \
-  SPoint3.h MEdge.h SVector3.h ../Common/Hash.h MFace.h \
-  ../Numeric/Numeric.h ../Common/Context.h ../DataStr/List.h GEntity.h \
-  Range.h SBoundingBox3d.h
-GModel.o: GModel.cpp GModel.h GVertex.h GEntity.h Range.h SPoint3.h \
-  SBoundingBox3d.h ../Common/GmshDefines.h MVertex.h GPoint.h SPoint2.h \
-  GEdge.h SVector3.h MElement.h MEdge.h ../Common/Hash.h MFace.h \
-  ../Numeric/Numeric.h ../Common/Context.h ../DataStr/List.h \
-  ExtrudeParams.h GFace.h GEdgeLoop.h Pair.h GRegion.h \
-  ../Common/SmoothNormals.h MRep.h ../Common/VertexArray.h \
-  ../Common/Message.h ../Common/OS.h
-GModelIO_Mesh.o: GModelIO_Mesh.cpp ../Common/Message.h \
-  ../Common/GmshDefines.h GModel.h GVertex.h GEntity.h Range.h SPoint3.h \
-  SBoundingBox3d.h MVertex.h GPoint.h SPoint2.h GEdge.h SVector3.h \
-  MElement.h MEdge.h ../Common/Hash.h MFace.h ../Numeric/Numeric.h \
-  ../Common/Context.h ../DataStr/List.h ExtrudeParams.h GFace.h \
-  GEdgeLoop.h Pair.h GRegion.h ../Common/SmoothNormals.h gmshRegion.h \
-  ../Mesh/Mesh.h ../DataStr/Tree.h ../DataStr/avl.h ../Mesh/Vertex.h \
-  ../Geo/ExtrudeParams.h gmshFace.h gmshVertex.h gmshEdge.h
-GModelIO_Geo.o: GModelIO_Geo.cpp GModel.h GVertex.h GEntity.h Range.h \
-  SPoint3.h SBoundingBox3d.h ../Common/GmshDefines.h MVertex.h GPoint.h \
-  SPoint2.h GEdge.h SVector3.h MElement.h MEdge.h ../Common/Hash.h \
-  MFace.h ../Numeric/Numeric.h ../Common/Context.h ../DataStr/List.h \
-  ExtrudeParams.h GFace.h GEdgeLoop.h Pair.h GRegion.h \
-  ../Common/SmoothNormals.h ../Mesh/Mesh.h ../DataStr/Tree.h \
-  ../DataStr/avl.h ../Mesh/Vertex.h ../Geo/ExtrudeParams.h Geo.h \
-  ../Parser/OpenFile.h ../DataStr/Tools.h ../DataStr/List.h \
-  ../DataStr/Tree.h ../Common/Message.h gmshVertex.h gmshFace.h \
-  gmshEdge.h gmshRegion.h
-GModelIO_Fourier.o: GModelIO_Fourier.cpp GModel.h GVertex.h GEntity.h \
-  Range.h SPoint3.h SBoundingBox3d.h ../Common/GmshDefines.h MVertex.h \
-  GPoint.h SPoint2.h GEdge.h SVector3.h MElement.h MEdge.h \
+gmshEdge.o: gmshEdge.cpp gmshEdge.h Geo.h ../Common/GmshDefines.h \
+  ../DataStr/List.h ../DataStr/Tree.h ../DataStr/avl.h ExtrudeParams.h \
+  GEdge.h GEntity.h Range.h SPoint3.h SBoundingBox3d.h GVertex.h \
+  MVertex.h GPoint.h SPoint2.h SVector3.h MElement.h MEdge.h \
   ../Common/Hash.h MFace.h ../Numeric/Numeric.h ../Common/Context.h \
-  ../DataStr/List.h ExtrudeParams.h GFace.h GEdgeLoop.h Pair.h GRegion.h \
-  ../Common/SmoothNormals.h fourierFace.h ../Common/Message.h \
-  ../Common/Views.h ../Common/ColorTable.h ../Common/VertexArray.h \
-  ../Common/SmoothNormals.h ../Common/AdaptiveViews.h \
-  ../Common/GmshMatrix.h
-GModelIO_OCC.o: GModelIO_OCC.cpp GModel.h GVertex.h GEntity.h Range.h \
-  SPoint3.h SBoundingBox3d.h ../Common/GmshDefines.h MVertex.h GPoint.h \
-  SPoint2.h GEdge.h SVector3.h MElement.h MEdge.h ../Common/Hash.h \
-  MFace.h ../Numeric/Numeric.h ../Common/Context.h ../DataStr/List.h \
-  ExtrudeParams.h GFace.h GEdgeLoop.h Pair.h GRegion.h \
-  ../Common/SmoothNormals.h ../Common/Message.h OCCIncludes.h OCCVertex.h \
-  ../Mesh/Mesh.h ../DataStr/Tree.h ../DataStr/avl.h ../Mesh/Vertex.h \
-  ../Geo/ExtrudeParams.h OCCEdge.h OCCFace.h OCCRegion.h
-GModelIO_CGNS.o: GModelIO_CGNS.cpp GModel.h GVertex.h GEntity.h Range.h \
-  SPoint3.h SBoundingBox3d.h ../Common/GmshDefines.h MVertex.h GPoint.h \
-  SPoint2.h GEdge.h SVector3.h MElement.h MEdge.h ../Common/Hash.h \
-  MFace.h ../Numeric/Numeric.h ../Common/Context.h ../DataStr/List.h \
-  ExtrudeParams.h GFace.h GEdgeLoop.h Pair.h GRegion.h \
-  ../Common/SmoothNormals.h ../Common/Message.h MNeighbour.h
-gmshEdge.o: gmshEdge.cpp gmshEdge.h GEdge.h GEntity.h Range.h SPoint3.h \
-  SBoundingBox3d.h ../Common/GmshDefines.h GVertex.h MVertex.h GPoint.h \
-  SPoint2.h SVector3.h MElement.h MEdge.h ../Common/Hash.h MFace.h \
-  ../Numeric/Numeric.h ../Common/Context.h ../DataStr/List.h \
-  ExtrudeParams.h gmshVertex.h ../Mesh/Mesh.h ../DataStr/Tree.h \
-  ../DataStr/avl.h ../Mesh/Vertex.h ../Geo/ExtrudeParams.h \
-  ../Mesh/Interpolation.h ../Mesh/Vertex.h ../Mesh/Mesh.h CAD.h Geo.h \
-  ../Mesh/Create.h ../Mesh/Vertex.h ../Mesh/Mesh.h
+  gmshVertex.h GeoInterpolation.h
 gmshFace.o: gmshFace.cpp GModel.h GVertex.h GEntity.h Range.h SPoint3.h \
   SBoundingBox3d.h ../Common/GmshDefines.h MVertex.h GPoint.h SPoint2.h \
   GEdge.h SVector3.h MElement.h MEdge.h ../Common/Hash.h MFace.h \
   ../Numeric/Numeric.h ../Common/Context.h ../DataStr/List.h \
   ExtrudeParams.h GFace.h GEdgeLoop.h Pair.h GRegion.h \
-  ../Common/SmoothNormals.h gmshVertex.h ../Mesh/Mesh.h ../DataStr/Tree.h \
-  ../DataStr/avl.h ../Mesh/Vertex.h ../Geo/ExtrudeParams.h gmshEdge.h \
-  gmshFace.h ../Mesh/Interpolation.h ../Mesh/Vertex.h ../Mesh/Mesh.h \
-  CAD.h Geo.h ../Mesh/Create.h ../Mesh/Vertex.h ../Mesh/Mesh.h \
-  ../Mesh/Utils.h ../Mesh/Vertex.h ../Mesh/Mesh.h ../Common/Message.h
+  ../Common/SmoothNormals.h gmshVertex.h Geo.h ../DataStr/Tree.h \
+  ../DataStr/avl.h gmshEdge.h gmshFace.h GeoInterpolation.h \
+  ../Mesh/Utils.h ../Geo/Geo.h ../Common/Message.h
 gmshRegion.o: gmshRegion.cpp GModel.h GVertex.h GEntity.h Range.h \
   SPoint3.h SBoundingBox3d.h ../Common/GmshDefines.h MVertex.h GPoint.h \
   SPoint2.h GEdge.h SVector3.h MElement.h MEdge.h ../Common/Hash.h \
   MFace.h ../Numeric/Numeric.h ../Common/Context.h ../DataStr/List.h \
   ExtrudeParams.h GFace.h GEdgeLoop.h Pair.h GRegion.h \
-  ../Common/SmoothNormals.h gmshFace.h gmshVertex.h ../Mesh/Mesh.h \
-  ../DataStr/Tree.h ../DataStr/avl.h ../Mesh/Vertex.h \
-  ../Geo/ExtrudeParams.h gmshRegion.h Geo.h ../Mesh/Create.h \
-  ../Mesh/Vertex.h ../Mesh/Mesh.h
+  ../Common/SmoothNormals.h gmshFace.h Geo.h ../DataStr/Tree.h \
+  ../DataStr/avl.h gmshVertex.h gmshRegion.h
 OCCVertex.o: OCCVertex.cpp GModel.h GVertex.h GEntity.h Range.h SPoint3.h \
   SBoundingBox3d.h ../Common/GmshDefines.h MVertex.h GPoint.h SPoint2.h \
   GEdge.h SVector3.h MElement.h MEdge.h ../Common/Hash.h MFace.h \
   ../Numeric/Numeric.h ../Common/Context.h ../DataStr/List.h \
   ExtrudeParams.h GFace.h GEdgeLoop.h Pair.h GRegion.h \
-  ../Common/SmoothNormals.h OCCVertex.h ../Mesh/Mesh.h ../DataStr/Tree.h \
-  ../DataStr/avl.h ../Mesh/Vertex.h ../Geo/ExtrudeParams.h OCCIncludes.h \
-  OCCEdge.h OCCFace.h
+  ../Common/SmoothNormals.h OCCVertex.h OCCIncludes.h OCCEdge.h OCCFace.h
 OCCEdge.o: OCCEdge.cpp GModel.h GVertex.h GEntity.h Range.h SPoint3.h \
   SBoundingBox3d.h ../Common/GmshDefines.h MVertex.h GPoint.h SPoint2.h \
   GEdge.h SVector3.h MElement.h MEdge.h ../Common/Hash.h MFace.h \
   ../Numeric/Numeric.h ../Common/Context.h ../DataStr/List.h \
   ExtrudeParams.h GFace.h GEdgeLoop.h Pair.h GRegion.h \
   ../Common/SmoothNormals.h ../Common/Message.h OCCEdge.h OCCVertex.h \
-  ../Mesh/Mesh.h ../DataStr/Tree.h ../DataStr/avl.h ../Mesh/Vertex.h \
-  ../Geo/ExtrudeParams.h OCCIncludes.h OCCFace.h
+  OCCIncludes.h OCCFace.h
 OCCFace.o: OCCFace.cpp GModel.h GVertex.h GEntity.h Range.h SPoint3.h \
   SBoundingBox3d.h ../Common/GmshDefines.h MVertex.h GPoint.h SPoint2.h \
   GEdge.h SVector3.h MElement.h MEdge.h ../Common/Hash.h MFace.h \
   ../Numeric/Numeric.h ../Common/Context.h ../DataStr/List.h \
   ExtrudeParams.h GFace.h GEdgeLoop.h Pair.h GRegion.h \
-  ../Common/SmoothNormals.h OCCVertex.h ../Mesh/Mesh.h ../DataStr/Tree.h \
-  ../DataStr/avl.h ../Mesh/Vertex.h ../Geo/ExtrudeParams.h OCCIncludes.h \
-  OCCEdge.h OCCFace.h ../Common/Message.h ../Mesh/Utils.h \
-  ../Mesh/Vertex.h ../Mesh/Mesh.h
+  ../Common/SmoothNormals.h OCCVertex.h OCCIncludes.h OCCEdge.h OCCFace.h \
+  ../Common/Message.h ../Mesh/Utils.h ../Geo/Geo.h ../DataStr/Tree.h \
+  ../DataStr/avl.h ../Geo/ExtrudeParams.h
 OCCRegion.o: OCCRegion.cpp GModel.h GVertex.h GEntity.h Range.h SPoint3.h \
   SBoundingBox3d.h ../Common/GmshDefines.h MVertex.h GPoint.h SPoint2.h \
   GEdge.h SVector3.h MElement.h MEdge.h ../Common/Hash.h MFace.h \
   ../Numeric/Numeric.h ../Common/Context.h ../DataStr/List.h \
   ExtrudeParams.h GFace.h GEdgeLoop.h Pair.h GRegion.h \
-  ../Common/SmoothNormals.h OCCVertex.h ../Mesh/Mesh.h ../DataStr/Tree.h \
-  ../DataStr/avl.h ../Mesh/Vertex.h ../Geo/ExtrudeParams.h OCCIncludes.h \
-  OCCEdge.h OCCFace.h OCCRegion.h ../Common/Message.h
-SVector3.o: SVector3.cpp SVector3.h SPoint3.h
-SBoundingBox3d.o: SBoundingBox3d.cpp SBoundingBox3d.h SPoint3.h
+  ../Common/SmoothNormals.h OCCVertex.h OCCIncludes.h OCCEdge.h OCCFace.h \
+  OCCRegion.h ../Common/Message.h
 projectionFace.o: projectionFace.cpp projectionFace.h GFace.h GPoint.h \
   GEntity.h Range.h SPoint3.h SBoundingBox3d.h ../Common/GmshDefines.h \
   GEdgeLoop.h GEdge.h GVertex.h MVertex.h SPoint2.h SVector3.h MElement.h \
   MEdge.h ../Common/Hash.h MFace.h ../Numeric/Numeric.h \
   ../Common/Context.h ../DataStr/List.h ExtrudeParams.h Pair.h
-ExtractContour.o: ExtractContour.cpp ../Common/Gmsh.h ../Common/Message.h \
+GModel.o: GModel.cpp GModel.h GVertex.h GEntity.h Range.h SPoint3.h \
+  SBoundingBox3d.h ../Common/GmshDefines.h MVertex.h GPoint.h SPoint2.h \
+  GEdge.h SVector3.h MElement.h MEdge.h ../Common/Hash.h MFace.h \
+  ../Numeric/Numeric.h ../Common/Context.h ../DataStr/List.h \
+  ExtrudeParams.h GFace.h GEdgeLoop.h Pair.h GRegion.h \
+  ../Common/SmoothNormals.h MRep.h ../Common/VertexArray.h \
+  ../Common/Message.h ../Common/OS.h
+GModelIO_Geo.o: GModelIO_Geo.cpp GModel.h GVertex.h GEntity.h Range.h \
+  SPoint3.h SBoundingBox3d.h ../Common/GmshDefines.h MVertex.h GPoint.h \
+  SPoint2.h GEdge.h SVector3.h MElement.h MEdge.h ../Common/Hash.h \
+  MFace.h ../Numeric/Numeric.h ../Common/Context.h ../DataStr/List.h \
+  ExtrudeParams.h GFace.h GEdgeLoop.h Pair.h GRegion.h \
+  ../Common/SmoothNormals.h Geo.h ../DataStr/Tree.h ../DataStr/avl.h \
+  ../Parser/OpenFile.h ../DataStr/Tools.h ../DataStr/List.h \
+  ../DataStr/Tree.h ../Common/Message.h gmshVertex.h gmshFace.h \
+  gmshEdge.h gmshRegion.h
+GModelIO_Mesh.o: GModelIO_Mesh.cpp ../Common/Message.h \
+  ../Common/GmshDefines.h GModel.h GVertex.h GEntity.h Range.h SPoint3.h \
+  SBoundingBox3d.h MVertex.h GPoint.h SPoint2.h GEdge.h SVector3.h \
+  MElement.h MEdge.h ../Common/Hash.h MFace.h ../Numeric/Numeric.h \
+  ../Common/Context.h ../DataStr/List.h ExtrudeParams.h GFace.h \
+  GEdgeLoop.h Pair.h GRegion.h ../Common/SmoothNormals.h gmshRegion.h \
+  Geo.h ../DataStr/Tree.h ../DataStr/avl.h gmshFace.h gmshVertex.h \
+  gmshEdge.h
+GModelIO_Fourier.o: GModelIO_Fourier.cpp GModel.h GVertex.h GEntity.h \
+  Range.h SPoint3.h SBoundingBox3d.h ../Common/GmshDefines.h MVertex.h \
+  GPoint.h SPoint2.h GEdge.h SVector3.h MElement.h MEdge.h \
+  ../Common/Hash.h MFace.h ../Numeric/Numeric.h ../Common/Context.h \
+  ../DataStr/List.h ExtrudeParams.h GFace.h GEdgeLoop.h Pair.h GRegion.h \
+  ../Common/SmoothNormals.h fourierFace.h ../Common/Message.h \
+  ../Common/Views.h ../Common/ColorTable.h ../Common/VertexArray.h \
+  ../Common/SmoothNormals.h ../Common/AdaptiveViews.h \
+  ../Common/GmshMatrix.h
+GModelIO_OCC.o: GModelIO_OCC.cpp GModel.h GVertex.h GEntity.h Range.h \
+  SPoint3.h SBoundingBox3d.h ../Common/GmshDefines.h MVertex.h GPoint.h \
+  SPoint2.h GEdge.h SVector3.h MElement.h MEdge.h ../Common/Hash.h \
+  MFace.h ../Numeric/Numeric.h ../Common/Context.h ../DataStr/List.h \
+  ExtrudeParams.h GFace.h GEdgeLoop.h Pair.h GRegion.h \
+  ../Common/SmoothNormals.h ../Common/Message.h OCCIncludes.h OCCVertex.h \
+  OCCEdge.h OCCFace.h OCCRegion.h
+GModelIO_CGNS.o: GModelIO_CGNS.cpp GModel.h GVertex.h GEntity.h Range.h \
+  SPoint3.h SBoundingBox3d.h ../Common/GmshDefines.h MVertex.h GPoint.h \
+  SPoint2.h GEdge.h SVector3.h MElement.h MEdge.h ../Common/Hash.h \
+  MFace.h ../Numeric/Numeric.h ../Common/Context.h ../DataStr/List.h \
+  ExtrudeParams.h GFace.h GEdgeLoop.h Pair.h GRegion.h \
+  ../Common/SmoothNormals.h ../Common/Message.h MNeighbour.h
+ExtrudeParams.o: ExtrudeParams.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
   ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
-  Geo.h GeoUtils.h ../Mesh/Mesh.h ../Common/GmshDefines.h \
-  ../Mesh/Vertex.h ../Geo/ExtrudeParams.h CAD.h ExtrudeParams.h \
-  ../Numeric/Numeric.h
+  Geo.h ../Common/GmshDefines.h ExtrudeParams.h
+Geo.o: Geo.cpp ../Common/Gmsh.h ../Common/Message.h ../DataStr/Malloc.h \
+  ../DataStr/List.h ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h \
+  ../DataStr/List.h ../DataStr/Tree.h ../Numeric/Numeric.h Geo.h \
+  ../Common/GmshDefines.h ExtrudeParams.h GeoInterpolation.h \
+  ../Mesh/Utils.h ../Geo/Geo.h ../Common/Context.h
+GeoStringInterface.o: GeoStringInterface.cpp ../Common/Gmsh.h \
+  ../Common/Message.h ../DataStr/Malloc.h ../DataStr/List.h \
+  ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h \
+  ../DataStr/Tree.h ../Numeric/Numeric.h Geo.h ../Common/GmshDefines.h \
+  ExtrudeParams.h GeoStringInterface.h ../Parser/Parser.h \
+  ../Common/Context.h GModel.h GVertex.h GEntity.h Range.h SPoint3.h \
+  SBoundingBox3d.h MVertex.h GPoint.h SPoint2.h GEdge.h SVector3.h \
+  MElement.h MEdge.h ../Common/Hash.h MFace.h GFace.h GEdgeLoop.h Pair.h \
+  GRegion.h ../Common/SmoothNormals.h
+GeoInterpolation.o: GeoInterpolation.cpp ../Common/Gmsh.h \
+  ../Common/Message.h ../DataStr/Malloc.h ../DataStr/List.h \
+  ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h \
+  ../DataStr/Tree.h Geo.h ../Common/GmshDefines.h ExtrudeParams.h \
+  GeoInterpolation.h GeoStringInterface.h GeoUtils.h ../Mesh/Utils.h \
+  ../Geo/Geo.h ../Numeric/Numeric.h
+GeoUtils.o: GeoUtils.cpp ../Common/Gmsh.h ../Common/Message.h \
+  ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
+  ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
+  Geo.h ../Common/GmshDefines.h ExtrudeParams.h ../Numeric/Numeric.h
+GeoExtractContour.o: GeoExtractContour.cpp ../Common/Gmsh.h \
+  ../Common/Message.h ../DataStr/Malloc.h ../DataStr/List.h \
+  ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h \
+  ../DataStr/Tree.h Geo.h ../Common/GmshDefines.h ExtrudeParams.h \
+  GeoUtils.h ../Numeric/Numeric.h
+MVertex.o: MVertex.cpp MVertex.h SPoint3.h
+MElement.o: MElement.cpp MElement.h ../Common/GmshDefines.h MVertex.h \
+  SPoint3.h MEdge.h SVector3.h ../Common/Hash.h MFace.h \
+  ../Numeric/Numeric.h ../Common/Context.h ../DataStr/List.h GEntity.h \
+  Range.h SBoundingBox3d.h
+SVector3.o: SVector3.cpp SVector3.h SPoint3.h
+SBoundingBox3d.o: SBoundingBox3d.cpp SBoundingBox3d.h SPoint3.h
diff --git a/Geo/OCCEdge.cpp b/Geo/OCCEdge.cpp
index 08e34712bf..bd896a0fa1 100644
--- a/Geo/OCCEdge.cpp
+++ b/Geo/OCCEdge.cpp
@@ -1,4 +1,4 @@
-// $Id: OCCEdge.cpp,v 1.10 2006-11-22 13:57:25 remacle Exp $
+// $Id: OCCEdge.cpp,v 1.11 2006-11-25 16:52:43 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -210,7 +210,7 @@ int OCCEdge::minimumDrawSegments () const
   else if(geomType() == Circle || geomType() == Ellipse)
     return CTX.geom.circle_points;
   else
-    return 10 * n;
+    return 20 * n;
 }
 
 
diff --git a/Geo/OCCEdge.h b/Geo/OCCEdge.h
index f3a909e69c..725299aa1b 100644
--- a/Geo/OCCEdge.h
+++ b/Geo/OCCEdge.h
@@ -23,7 +23,6 @@
 #include "GEdge.h"
 #include "GModel.h"
 #include "OCCVertex.h"
-#include "Mesh.h"
 #include "Range.h"
 
 class OCCFace;
diff --git a/Geo/OCCRegion.h b/Geo/OCCRegion.h
index 82501d2d5e..0af7d0883a 100644
--- a/Geo/OCCRegion.h
+++ b/Geo/OCCRegion.h
@@ -20,7 +20,6 @@
 // 
 // Please report all bugs and problems to <gmsh@geuz.org>.
 
-#include "Mesh.h"
 #include "GRegion.h"
 
 #if defined(HAVE_OCC)
diff --git a/Geo/OCCVertex.h b/Geo/OCCVertex.h
index 2783057a96..cefdb97963 100644
--- a/Geo/OCCVertex.h
+++ b/Geo/OCCVertex.h
@@ -20,7 +20,6 @@
 // 
 // Please report all bugs and problems to <gmsh@geuz.org>.
 
-#include "Mesh.h"
 #include "GModel.h"
 #include "OCCIncludes.h"
 #include "GVertex.h"
diff --git a/Geo/gmshEdge.cpp b/Geo/gmshEdge.cpp
index aadfd86547..caed9ae6ef 100644
--- a/Geo/gmshEdge.cpp
+++ b/Geo/gmshEdge.cpp
@@ -1,4 +1,4 @@
-// $Id: gmshEdge.cpp,v 1.18 2006-11-25 00:44:25 geuzaine Exp $
+// $Id: gmshEdge.cpp,v 1.19 2006-11-25 16:52:43 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -20,11 +20,8 @@
 // Please report all bugs and problems to <gmsh@geuz.org>.
 
 #include "gmshEdge.h"
-#include "Interpolation.h"
-#include "CAD.h"
 #include "Geo.h"
-#include "Mesh.h"
-#include "Create.h"
+#include "GeoInterpolation.h"
 #include "Context.h"
 
 extern Context_T CTX;
diff --git a/Geo/gmshEdge.h b/Geo/gmshEdge.h
index bcfcb0d7e1..4ec754043b 100644
--- a/Geo/gmshEdge.h
+++ b/Geo/gmshEdge.h
@@ -20,9 +20,9 @@
 // 
 // Please report all bugs and problems to <gmsh@geuz.org>.
 
+#include "Geo.h"
 #include "GEdge.h"
 #include "gmshVertex.h"
-#include "Mesh.h"
 #include "Range.h"
 
 class gmshEdge : public GEdge {
diff --git a/Geo/gmshFace.cpp b/Geo/gmshFace.cpp
index 4f41bf06cb..29e7047dc1 100644
--- a/Geo/gmshFace.cpp
+++ b/Geo/gmshFace.cpp
@@ -1,4 +1,4 @@
-// $Id: gmshFace.cpp,v 1.21 2006-11-14 20:20:18 remacle Exp $
+// $Id: gmshFace.cpp,v 1.22 2006-11-25 16:52:43 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -23,11 +23,8 @@
 #include "gmshVertex.h"
 #include "gmshEdge.h"
 #include "gmshFace.h"
-#include "Interpolation.h"
-#include "CAD.h"
 #include "Geo.h"
-#include "Mesh.h"
-#include "Create.h"
+#include "GeoInterpolation.h"
 #include "Utils.h"
 #include "Message.h"
 
diff --git a/Geo/gmshFace.h b/Geo/gmshFace.h
index d4b16475a1..774a1161e7 100644
--- a/Geo/gmshFace.h
+++ b/Geo/gmshFace.h
@@ -20,9 +20,9 @@
 // 
 // Please report all bugs and problems to <gmsh@geuz.org>.
 
+#include "Geo.h"
 #include "GFace.h"
 #include "gmshVertex.h"
-#include "Mesh.h"
 #include "Range.h"
 
 class gmshFace : public GFace {
diff --git a/Geo/gmshRegion.cpp b/Geo/gmshRegion.cpp
index fa5cc073a9..280721bf22 100644
--- a/Geo/gmshRegion.cpp
+++ b/Geo/gmshRegion.cpp
@@ -1,4 +1,4 @@
-// $Id: gmshRegion.cpp,v 1.7 2006-11-14 15:21:03 geuzaine Exp $
+// $Id: gmshRegion.cpp,v 1.8 2006-11-25 16:52:43 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -23,8 +23,6 @@
 #include "gmshFace.h"
 #include "gmshRegion.h"
 #include "Geo.h"
-#include "Mesh.h"
-#include "Create.h"
 
 extern Mesh *THEM;
 
diff --git a/Geo/gmshRegion.h b/Geo/gmshRegion.h
index 58c5ce8084..e4603e66e1 100644
--- a/Geo/gmshRegion.h
+++ b/Geo/gmshRegion.h
@@ -20,7 +20,7 @@
 // 
 // Please report all bugs and problems to <gmsh@geuz.org>.
 
-#include "Mesh.h"
+#include "Geo.h"
 #include "GRegion.h"
 
 class gmshRegion : public GRegion {
diff --git a/Geo/gmshVertex.h b/Geo/gmshVertex.h
index d3c8ebce45..0b7bc4796b 100644
--- a/Geo/gmshVertex.h
+++ b/Geo/gmshVertex.h
@@ -20,7 +20,7 @@
 // 
 // Please report all bugs and problems to <gmsh@geuz.org>.
 
-#include "Mesh.h"
+#include "Geo.h"
 #include "GVertex.h"
 
 class gmshVertex : public GVertex {
diff --git a/Graphics/Draw.cpp b/Graphics/Draw.cpp
index c73ca07279..38dd2ac885 100644
--- a/Graphics/Draw.cpp
+++ b/Graphics/Draw.cpp
@@ -1,4 +1,4 @@
-// $Id: Draw.cpp,v 1.107 2006-08-26 13:34:46 geuzaine Exp $
+// $Id: Draw.cpp,v 1.108 2006-11-25 16:52:43 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -22,7 +22,6 @@
 #include "Gmsh.h"
 #include "GmshUI.h"
 #include "GmshDefines.h"
-#include "CAD.h"
 #include "Draw.h"
 #include "Context.h"
 #include "Numeric.h"
diff --git a/Graphics/Makefile b/Graphics/Makefile
index 0dde8fa19e..53eaf7c1a6 100644
--- a/Graphics/Makefile
+++ b/Graphics/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.107 2006-11-25 02:47:39 geuzaine Exp $
+# $Id: Makefile,v 1.108 2006-11-25 16:52:43 geuzaine Exp $
 #
 # Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 #
@@ -72,10 +72,8 @@ depend:
 Draw.o: Draw.cpp ../Common/Gmsh.h ../Common/Message.h ../DataStr/Malloc.h \
   ../DataStr/List.h ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h \
   ../DataStr/List.h ../DataStr/Tree.h ../Common/GmshUI.h \
-  ../Common/GmshDefines.h ../Geo/CAD.h ../Mesh/Mesh.h ../Mesh/Vertex.h \
-  ../Geo/ExtrudeParams.h ../Geo/ExtrudeParams.h Draw.h ../Common/Views.h \
-  ../Common/ColorTable.h ../Common/VertexArray.h \
-  ../Common/SmoothNormals.h ../Numeric/Numeric.h \
+  ../Common/GmshDefines.h Draw.h ../Common/Views.h ../Common/ColorTable.h \
+  ../Common/VertexArray.h ../Common/SmoothNormals.h ../Numeric/Numeric.h \
   ../Common/AdaptiveViews.h ../Common/GmshMatrix.h ../Common/Context.h \
   ../Geo/GModel.h ../Geo/GVertex.h ../Geo/GEntity.h ../Geo/Range.h \
   ../Geo/SPoint3.h ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h \
diff --git a/Mesh/BackgroundMesh.cpp b/Mesh/BackgroundMesh.cpp
index 9f280613e2..7b069a08ac 100644
--- a/Mesh/BackgroundMesh.cpp
+++ b/Mesh/BackgroundMesh.cpp
@@ -1,4 +1,4 @@
-// $Id: BackgroundMesh.cpp,v 1.1 2006-11-25 02:47:39 geuzaine Exp $
+// $Id: BackgroundMesh.cpp,v 1.2 2006-11-25 16:52:43 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -20,13 +20,12 @@
 // Please report all bugs and problems to <gmsh@geuz.org>.
 
 #include "Gmsh.h"
-#include "Mesh.h"
 #include "Views.h"
+#include "BackgroundMesh.h"
 #include "Numeric.h"
 #include "Context.h"
 #include "OctreePost.h"
 
-extern Mesh *THEM;
 extern Context_T CTX;
 
 static OctreePost *BGM_OCTREE = NULL;
diff --git a/Mesh/Nurbs.h b/Mesh/BackgroundMesh.h
similarity index 56%
rename from Mesh/Nurbs.h
rename to Mesh/BackgroundMesh.h
index c7057f7f57..d51d259403 100644
--- a/Mesh/Nurbs.h
+++ b/Mesh/BackgroundMesh.h
@@ -1,5 +1,5 @@
-#ifndef _NURBS_H_
-#define _NURBS_H_
+#ifndef _BACKGROUND_MESH_H_
+#define _BACKGROUND_MESH_H_
 
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -20,18 +20,11 @@
 // 
 // Please report all bugs and problems to <gmsh@geuz.org>.
 
-#include "Vertex.h"
-#include "Mesh.h"
-#include "List.h"
 
-Vertex InterpolateCubicSpline (Vertex * v[4], double t, double mat[4][4],
-                               int derivee, double t1, double t2);
-Vertex InterpolateUBS (Curve * Curve, double u, int derivee);
-Vertex InterpolateNurbs (Curve * Curve, double u, int derivee);
-Vertex InterpolateNurbsSurface (Surface * s, double u, double v);
+#define ONFILE      2
+#define WITHPOINTS  3
 
-void CreateNurbsSurface (int Num, int Order1, int Order2, List_T *, List_T *, List_T *);
-void CreateNurbsSurfaceSupport (int Num, int Order2, int Order1, 
-                                List_T * List, List_T *, List_T *);
+double BGMXYZ(double X, double Y, double Z);
+int BGMExists();
 
 #endif
diff --git a/Mesh/Create.cpp b/Mesh/Create.cpp
deleted file mode 100644
index d09e9f5a6a..0000000000
--- a/Mesh/Create.cpp
+++ /dev/null
@@ -1,611 +0,0 @@
-// $Id: Create.cpp,v 1.88 2006-11-25 03:30:03 geuzaine Exp $
-//
-// Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-// USA.
-// 
-// Please report all bugs and problems to <gmsh@geuz.org>.
-
-#include "Gmsh.h"
-#include "Numeric.h"
-#include "Geo.h"
-#include "CAD.h"
-#include "Mesh.h"
-#include "Utils.h"
-#include "Context.h"
-#include "Create.h"
-
-// This file contains the C-style interface for creation/deletion of
-// objects. All this could be easily rewritten in C++ (and split into
-// separate classes: Line, Surface, Volume, etc.).
-
-extern Mesh *THEM;
-extern Context_T CTX;
-
-int compareSurfaceLoop(const void *a, const void *b)
-{
-  SurfaceLoop **q, **w;
-
-  q = (SurfaceLoop **) a;
-  w = (SurfaceLoop **) b;
-  return ((*q)->Num - (*w)->Num);
-}
-
-int compareEdgeLoop(const void *a, const void *b)
-{
-  EdgeLoop **q, **w;
-
-  q = (EdgeLoop **) a;
-  w = (EdgeLoop **) b;
-  return ((*q)->Num - (*w)->Num);
-}
-
-int compareCurve(const void *a, const void *b)
-{
-  Curve **q, **w;
-
-  q = (Curve **) a;
-  w = (Curve **) b;
-  return ((*q)->Num - (*w)->Num);
-}
-
-int compareSurface(const void *a, const void *b)
-{
-  Surface **q, **w;
-
-  q = (Surface **) a;
-  w = (Surface **) b;
-  return ((*q)->Num - (*w)->Num);
-}
-
-int compareVolume(const void *a, const void *b)
-{
-  Volume **q, **w;
-
-  q = (Volume **) a;
-  w = (Volume **) b;
-  return ((*q)->Num - (*w)->Num);
-}
-
-int comparePhysicalGroup(const void *a, const void *b)
-{
-  PhysicalGroup *q, *w;
-  int cmp;
-
-  q = *(PhysicalGroup **) a;
-  w = *(PhysicalGroup **) b;
-  cmp = q->Typ - w->Typ;
-
-  if(cmp)
-    return cmp;
-  else
-    return (q->Num - w->Num);
-}
-
-PhysicalGroup *Create_PhysicalGroup(int Num, int typ, List_T * intlist)
-{
-  PhysicalGroup *p = (PhysicalGroup *) Malloc(sizeof(PhysicalGroup));
-  p->Entities = List_Create(List_Nbr(intlist), 1, sizeof(int));
-  p->Num = Num;
-  THEM->MaxPhysicalNum = IMAX(THEM->MaxPhysicalNum, Num);
-  p->Typ = typ;
-  p->Visible = 1;
-  for(int i = 0; i < List_Nbr(intlist); i++) {
-    int j;
-    List_Read(intlist, i, &j);
-    List_Add(p->Entities, &j);
-  }
-  return p;
-}
-
-void Free_PhysicalGroup(void *a, void *b)
-{
-  PhysicalGroup *p = *(PhysicalGroup **) a;
-  if(p) {
-    List_Delete(p->Entities);
-    Free(p);
-    p = NULL;
-  }
-}
-
-EdgeLoop *Create_EdgeLoop(int Num, List_T * intlist)
-{
-  EdgeLoop *l = (EdgeLoop *) Malloc(sizeof(EdgeLoop));
-  l->Curves = List_Create(List_Nbr(intlist), 1, sizeof(int));
-  l->Num = Num;
-  THEM->MaxLineLoopNum = IMAX(THEM->MaxLineLoopNum, Num);
-  for(int i = 0; i < List_Nbr(intlist); i++) {
-    int j;
-    List_Read(intlist, i, &j);
-    List_Add(l->Curves, &j);
-  }
-  return l;
-}
-
-void Free_EdgeLoop(void *a, void *b)
-{
-  EdgeLoop *l = *(EdgeLoop **) a;
-  if(l) {
-    List_Delete(l->Curves);
-    Free(l);
-    l = NULL;
-  }
-}
-
-SurfaceLoop *Create_SurfaceLoop(int Num, List_T * intlist)
-{
-  SurfaceLoop *l = (SurfaceLoop *) Malloc(sizeof(SurfaceLoop));
-  l->Surfaces = List_Create(List_Nbr(intlist), 1, sizeof(int));
-  l->Num = Num;
-  THEM->MaxSurfaceLoopNum = IMAX(THEM->MaxSurfaceLoopNum, Num);
-  for(int i = 0; i < List_Nbr(intlist); i++) {
-    int j;
-    List_Read(intlist, i, &j);
-    List_Add(l->Surfaces, &j);
-  }
-  return l;
-}
-
-void Free_SurfaceLoop(void *a, void *b)
-{
-  SurfaceLoop *l = *(SurfaceLoop **) a;
-  if(l) {
-    List_Delete(l->Surfaces);
-    Free(l);
-    l = NULL;
-  }
-}
-
-void End_Curve(Curve * c)
-{
-  double R2, mat[3][3], R, A3, A1, A4;
-  Vertex *v[4], v0, v2, v3;
-  double f1, f2, dir32[3], dir12[3], n[3], m[3], dir42[3];
-  double rhs[2], sys[2][2], sol[2];
-  int i;
-  Curve *Curve;
-
-  if(c->Typ == MSH_SEGM_CIRC || c->Typ == MSH_SEGM_CIRC_INV ||
-     c->Typ == MSH_SEGM_ELLI || c->Typ == MSH_SEGM_ELLI_INV) {
-
-    Curve = c;
-
-    // v[0] = first point
-    // v[1] = center
-    // v[2] = last point
-    // v[3] = major axis point
-
-    if(List_Nbr(Curve->Control_Points) == 4)
-      List_Read(Curve->Control_Points, 2, &v[3]);
-    else
-      v[3] = NULL;
-
-    if(Curve->Typ == MSH_SEGM_CIRC_INV || Curve->Typ == MSH_SEGM_ELLI_INV) {
-      List_Read(Curve->Control_Points, 0, &v[2]);
-      List_Read(Curve->Control_Points, 1, &v[1]);
-      if(!v[3])
-        List_Read(Curve->Control_Points, 2, &v[0]);
-      else
-        List_Read(Curve->Control_Points, 3, &v[0]);
-    }
-    else {
-      List_Read(Curve->Control_Points, 0, &v[0]);
-      List_Read(Curve->Control_Points, 1, &v[1]);
-      if(!v[3])
-        List_Read(Curve->Control_Points, 2, &v[2]);
-      else
-        List_Read(Curve->Control_Points, 3, &v[2]);
-    }
-
-    direction(v[1], v[0], dir12);
-    direction(v[1], v[2], dir32);
-    if(v[3])
-      direction(v[1], v[3], dir42);
-
-    // v0 = vector center->first pt
-    // v2 = vector center->last pt
-    // v3 = vector center->major axis pt
-
-    v0.Pos.X = dir12[0];
-    v0.Pos.Y = dir12[1];
-    v0.Pos.Z = dir12[2];
-    v2.Pos.X = dir32[0];
-    v2.Pos.Y = dir32[1];
-    v2.Pos.Z = dir32[2];
-    if(v[3]) {
-      v3.Pos.X = dir42[0];
-      v3.Pos.Y = dir42[1];
-      v3.Pos.Z = dir42[2];
-    }
-
-    norme(dir12);
-    norme(dir32);
-    prodve(dir12, dir32, n);
-    norme(n);
-    // use provided plane if unable to compute it from input points...
-    if(fabs(n[0]) < 1.e-5 && fabs(n[1]) < 1.e-5 && fabs(n[2]) < 1.e-5) {
-      n[0] = Curve->Circle.n[0];
-      n[1] = Curve->Circle.n[1];
-      n[2] = Curve->Circle.n[2];
-      norme(n);
-    }
-    prodve(n, dir12, m);
-    norme(m);
-
-    mat[2][0] = Curve->Circle.invmat[0][2] = n[0];
-    mat[2][1] = Curve->Circle.invmat[1][2] = n[1];
-    mat[2][2] = Curve->Circle.invmat[2][2] = n[2];
-    mat[1][0] = Curve->Circle.invmat[0][1] = m[0];
-    mat[1][1] = Curve->Circle.invmat[1][1] = m[1];
-    mat[1][2] = Curve->Circle.invmat[2][1] = m[2];
-    mat[0][0] = Curve->Circle.invmat[0][0] = dir12[0];
-    mat[0][1] = Curve->Circle.invmat[1][0] = dir12[1];
-    mat[0][2] = Curve->Circle.invmat[2][0] = dir12[2];
-
-    // assume circle in z=0 plane
-    if(CTX.geom.old_circle) {
-      if(n[0] == 0.0 && n[1] == 0.0) {
-        mat[2][0] = Curve->Circle.invmat[0][2] = 0;
-        mat[2][1] = Curve->Circle.invmat[1][2] = 0;
-        mat[2][2] = Curve->Circle.invmat[2][2] = 1;
-        mat[1][0] = Curve->Circle.invmat[0][1] = 0;
-        mat[1][1] = Curve->Circle.invmat[1][1] = 1;
-        mat[1][2] = Curve->Circle.invmat[2][1] = 0;
-        mat[0][0] = Curve->Circle.invmat[0][0] = 1;
-        mat[0][1] = Curve->Circle.invmat[1][0] = 0;
-        mat[0][2] = Curve->Circle.invmat[2][0] = 0;
-      }
-    }
-
-    Projette(&v0, mat);
-    Projette(&v2, mat);
-    if(v[3])
-      Projette(&v3, mat);
-
-    R = sqrt(v0.Pos.X * v0.Pos.X + v0.Pos.Y * v0.Pos.Y);
-    R2 = sqrt(v2.Pos.X * v2.Pos.X + v2.Pos.Y * v2.Pos.Y);
-
-    if(!R || !R2)       // check radius
-      Msg(GERROR, "Zero radius in Circle/Ellipse %d", c->Num);
-    else if(!v[3] && fabs((R - R2) / (R + R2)) > 0.1)   // check cocircular pts (allow 10% error)
-      Msg(GERROR, "Control points of Circle %d are not cocircular %g %g",
-          c->Num, R, R2);
-
-    // A1 = angle first pt
-    // A3 = angle last pt
-    // A4 = angle major axis
-
-    if(v[3]) {
-      A4 = myatan2(v3.Pos.Y, v3.Pos.X);
-      A4 = angle_02pi(A4);
-      double x1 = v0.Pos.X * cos(A4) + v0.Pos.Y * sin(A4);
-      double y1 = -v0.Pos.X * sin(A4) + v0.Pos.Y * cos(A4);
-      double x3 = v2.Pos.X * cos(A4) + v2.Pos.Y * sin(A4);
-      double y3 = -v2.Pos.X * sin(A4) + v2.Pos.Y * cos(A4);
-      sys[0][0] = x1 * x1;
-      sys[0][1] = y1 * y1;
-      sys[1][0] = x3 * x3;
-      sys[1][1] = y3 * y3;
-      rhs[0] = 1;
-      rhs[1] = 1;
-      sys2x2(sys, rhs, sol);
-      if(sol[0] <= 0 || sol[1] <= 0) {
-        Msg(GERROR, "Ellipse %d is wrong", Curve->Num);
-        A1 = A3 = 0.;
-        f1 = f2 = R;
-      }
-      else {
-        f1 = sqrt(1. / sol[0]);
-        f2 = sqrt(1. / sol[1]);
-        // myasin() permet de contourner les problemes de precision
-        // sur y1/f2 ou y3/f2, qui peuvent legerement etre hors de
-        // [-1,1]
-        if(x1 < 0)
-          A1 = -myasin(y1 / f2) + A4 + Pi;
-        else
-          A1 = myasin(y1 / f2) + A4;
-        if(x3 < 0)
-          A3 = -myasin(y3 / f2) + A4 + Pi;
-        else
-          A3 = myasin(y3 / f2) + A4;
-      }
-    }
-    else {
-      A1 = myatan2(v0.Pos.Y, v0.Pos.X);
-      A3 = myatan2(v2.Pos.Y, v2.Pos.X);
-      A4 = 0.;
-      f1 = f2 = R;
-    }
-
-    A1 = angle_02pi(A1);
-    A3 = angle_02pi(A3);
-    if(A1 >= A3)
-      A3 += 2 * Pi;
-
-    //printf("f1=%g f2=%g a1=%g a3=%g a4=%g\n", 
-    //     f1, f2, A1*180./M_PI, A3*180./Pi, A4*180./Pi);
-
-    Curve->Circle.t1 = A1;
-    Curve->Circle.t2 = A3;
-    Curve->Circle.incl = A4;
-    Curve->Circle.f1 = f1;
-    Curve->Circle.f2 = f2;
-
-    for(i = 0; i < 4; i++)
-      Curve->Circle.v[i] = v[i];
-
-    if(!CTX.expert_mode && Curve->Num > 0 && A3-A1 >= Pi){
-      Msg(GERROR1, "Circle or ellipse arc %d greater than/equal to Pi (angle=%g)",
-	  Curve->Num, A3-A1);
-      Msg(GERROR2, "(If you understand what this implies, you can disable this error");
-      Msg(GERROR2, "message by selecting `Enable expert mode' in the option dialog.");
-      Msg(GERROR3, "Otherwise, please subdivide the arc in smaller pieces.)");
-    }
-
-  }
-
-  if(c->cp){
-    Free(c->cp);
-    c->cp = NULL;
-  }
-
-  if(List_Nbr(c->Control_Points)){
-    c->cp = (float *)Malloc(4 * List_Nbr(c->Control_Points) * sizeof(float));
-    for(i = 0; i < List_Nbr(c->Control_Points); i++) {
-      List_Read(c->Control_Points, i, &v[0]);
-      c->cp[4 * i] = v[0]->Pos.X;
-      c->cp[4 * i + 1] = v[0]->Pos.Y;
-      c->cp[4 * i + 2] = v[0]->Pos.Z;
-      c->cp[4 * i + 3] = v[0]->w;
-    }
-  }
-}
-
-void End_Surface(Surface * s, int reset_orientations)
-{
-  int i;
-  Vertex *v;
-  
-  if(reset_orientations) 
-    List_Reset(s->Orientations);
-
-  if(!s->Control_Points || !List_Nbr(s->Control_Points))
-    return;
-
-  s->cp = (float *)Malloc(4 * List_Nbr(s->Control_Points) * sizeof(float));
-  for(i = 0; i < List_Nbr(s->Control_Points); i++) {
-    List_Read(s->Control_Points, i, &v);
-    s->cp[4 * i] = v->Pos.X;
-    s->cp[4 * i + 1] = v->Pos.Y;
-    s->cp[4 * i + 2] = v->Pos.Z;
-    s->cp[4 * i + 3] = v->w;
-  }
-
-}
-
-
-Curve *Create_Curve(int Num, int Typ, int Order, List_T * Liste,
-                    List_T * Knots, int p1, int p2, double u1, double u2)
-{
-  double matcr[4][4] = { {-0.5, 1.5, -1.5, 0.5},
-			 {1.0, -2.5, 2.0, -0.5},
-			 {-0.5, 0.0, 0.5, 0.0},
-			 {0.0, 1.0, 0.0, 0.0} };
-  double matbs[4][4] = { {-1.0, 3, -3, 1},
-			 {3, -6, 3.0, 0},
-			 {-3, 0.0, 3, 0.0},
-			 {1, 4, 1, 0.0} };
-  double matbez[4][4] = { {-1.0, 3, -3, 1},
-			  {3, -6, 3.0, 0},
-			  {-3, 3.0, 0, 0.0},
-			  {1, 0, 0, 0.0} };
-
-  Curve *pC = (Curve *) Malloc(sizeof(Curve));
-  pC->Color.type = 0;
-  pC->Visible = 1;
-  pC->cp = NULL;
-  pC->Vertices = List_Create(2, 20, sizeof(Vertex *));
-  pC->Extrude = NULL;
-  pC->Typ = Typ;
-  pC->Num = Num;
-  THEM->MaxLineNum = IMAX(THEM->MaxLineNum, Num);
-  pC->Method = LIBRE;
-  pC->degre = Order;
-  pC->Circle.n[0] = 0.0;
-  pC->Circle.n[1] = 0.0;
-  pC->Circle.n[2] = 1.0;
-  for(int i = 0; i < 4; i++) {
-    pC->ipar[i] = 0;
-    pC->dpar[i] = 0.0;
-  }
-
-  if(Typ == MSH_SEGM_SPLN) {
-    for(int i = 0; i < 4; i++)
-      for(int j = 0; j < 4; j++)
-        pC->mat[i][j] = matcr[i][j];
-  }
-  else if(Typ == MSH_SEGM_BSPLN) {
-    for(int i = 0; i < 4; i++)
-      for(int j = 0; j < 4; j++)
-        pC->mat[i][j] = matbs[i][j] / 6.0;
-  }
-  else if(Typ == MSH_SEGM_BEZIER) {
-    for(int i = 0; i < 4; i++)
-      for(int j = 0; j < 4; j++)
-        pC->mat[i][j] = matbez[i][j];
-  }
-
-  pC->ubeg = u1;
-  pC->uend = u2;
-
-  if(Knots) {
-    pC->k = (float *)Malloc(List_Nbr(Knots) * sizeof(float));
-    double kmin = .0, kmax = 1.;
-    List_Read(Knots, 0, &kmin);
-    List_Read(Knots, List_Nbr(Knots) - 1, &kmax);
-    pC->ubeg = kmin;
-    pC->uend = kmax;
-    for(int i = 0; i < List_Nbr(Knots); i++) {
-      double d;
-      List_Read(Knots, i, &d);
-      pC->k[i] = (float)d;
-    }
-  }
-  else
-    pC->k = NULL;
-
-  if(Liste) {
-    pC->Control_Points = List_Create(List_Nbr(Liste), 1, sizeof(Vertex *));
-    for(int j = 0; j < List_Nbr(Liste); j++) {
-      int iPnt;
-      List_Read(Liste, j, &iPnt);
-      Vertex *v;
-      if((v = FindPoint(iPnt)))
-        List_Add(pC->Control_Points, &v);
-      else{
-        Msg(GERROR, "Unknown control point %d in Curve %d", iPnt, pC->Num);
-      }
-    }
-  }
-  else {
-    pC->Control_Points = NULL;
-    pC->beg = NULL;
-    pC->end = NULL;
-    return pC;
-  }
-
-  if(p1 < 0) {
-    List_Read(pC->Control_Points, 0, &pC->beg);
-    List_Read(pC->Control_Points, List_Nbr(pC->Control_Points) - 1, &pC->end);
-  }
-  else {
-    Vertex *v;
-    if((v = FindPoint(p1))) {
-      Msg(INFO, "Curve %d first control point %d ", pC->Num, v->Num);
-      pC->beg = v;
-    }
-    else {
-      Msg(GERROR, "Unknown control point %d in Curve %d", p1, pC->Num);
-    }
-    if((v = FindPoint(p2))) {
-      Msg(INFO, "Curve %d first control point %d ", pC->Num, v->Num);
-      pC->end = v;
-    }
-    else {
-      Msg(GERROR, "Unknown control point %d in Curve %d", p2, pC->Num);
-    }
-  }
-
-  End_Curve(pC);
-
-  return pC;
-}
-
-void Free_Curve(void *a, void *b)
-{
-  Curve *pC = *(Curve **) a;
-  if(pC) {
-    List_Delete(pC->Vertices);
-    Free(pC->k);
-    List_Delete(pC->Control_Points);
-    Free(pC->cp);
-    Free(pC);
-    pC = NULL;
-  }
-}
-
-Surface *Create_Surface(int Num, int Typ)
-{
-  Surface *pS = (Surface *) Malloc(sizeof(Surface));
-  pS->Color.type = 0;
-  pS->Visible = 1;
-  pS->Num = Num;
-  THEM->MaxSurfaceNum = IMAX(THEM->MaxSurfaceNum, Num);
-  pS->Typ = Typ;
-  pS->Method = LIBRE;
-  for(int i = 0; i < 5; i++)
-    pS->ipar[i] = 0;
-  pS->Recombine = 0;
-  pS->Recombine_Dir = 1;
-  pS->RecombineAngle = 75;
-  pS->TrsfPoints = List_Create(4, 4, sizeof(Vertex *));
-  pS->Vertices = Tree_Create(sizeof(Vertex *), compareVertex);
-  pS->Contours = List_Create(1, 1, sizeof(List_T *));
-  pS->Orientations = List_Create(20, 2, sizeof(Vertex));
-  pS->Support = pS;
-  pS->Control_Points = List_Create(1, 10, sizeof(Vertex *));
-  pS->Generatrices = NULL;
-  pS->EmbeddedPoints = NULL;
-  pS->EmbeddedCurves = NULL;
-  pS->Extrude = NULL;
-  return (pS);
-}
-
-void Free_Surface(void *a, void *b)
-{
-  Surface *pS = *(Surface **) a;
-  if(pS) {
-    List_Delete(pS->TrsfPoints);
-    Tree_Delete(pS->Vertices);
-    List_Delete(pS->Contours);
-    List_Delete(pS->Orientations);
-    List_Delete(pS->Control_Points);
-    List_Delete(pS->Generatrices);
-    List_Delete(pS->EmbeddedCurves);
-    List_Delete(pS->EmbeddedPoints);
-    Free(pS);
-    pS = NULL;
-  }
-}
-
-Volume *Create_Volume(int Num, int Typ)
-{
-  Volume *pV = (Volume *) Malloc(sizeof(Volume));
-  pV->Color.type = 0;
-  pV->Visible = 1;
-  pV->Num = Num;
-  THEM->MaxVolumeNum = IMAX(THEM->MaxVolumeNum, Num);
-  pV->Typ = Typ;
-  pV->Method = LIBRE;
-  for(int i = 0; i < 8; i++)
-    pV->ipar[i] = 0;
-  pV->TrsfPoints = List_Create(6, 6, sizeof(Vertex *));
-  pV->Surfaces = List_Create(1, 2, sizeof(Surface *));
-  pV->SurfacesOrientations = List_Create(1, 2, sizeof(int));
-  pV->Vertices = Tree_Create(sizeof(Vertex *), compareVertex);
-  pV->Extrude = NULL;
-  return pV;
-}
-
-void Free_Volume(void *a, void *b)
-{
-  Volume *pV = *(Volume **) a;
-  Free_Volume_But_Not_Elements(a, b);
-}
-
-void Free_Volume_But_Not_Elements(void *a, void *b)
-{
-  Volume *pV = *(Volume **) a;
-  if(pV) {
-    List_Delete(pV->TrsfPoints);
-    List_Delete(pV->Surfaces);  // surfaces freed elsewhere
-    List_Delete(pV->SurfacesOrientations);
-    Tree_Delete(pV->Vertices);  // vertices freed elsewhere
-    Free(pV);
-    pV = NULL;
-  }
-}
-
diff --git a/Mesh/Create.h b/Mesh/Create.h
deleted file mode 100644
index 292f6320e2..0000000000
--- a/Mesh/Create.h
+++ /dev/null
@@ -1,62 +0,0 @@
-#ifndef _CREATE_H_
-#define _CREATE_H_
-
-// Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-// USA.
-// 
-// Please report all bugs and problems to <gmsh@geuz.org>.
-
-#include "List.h"
-#include "Vertex.h"
-#include "Mesh.h"
-
-int compareNXE(const void *a, const void *b);
-int compareFxE(const void *a, const void *b);
-int compareSurfaceLoop(const void *a, const void *b);
-int compareEdgeLoop(const void *a, const void *b);
-int compareQuality(const void *a, const void *b);
-int compareCurve(const void *a, const void *b);
-int compareSurface(const void *a, const void *b);
-int compareVolume(const void *a, const void *b);
-int compareSxF(const void *a, const void *b);
-int compareMeshPartitionNum(const void *a, const void *b);
-int compareMeshPartitionIndex(const void *a, const void *b);
-int comparePhysicalGroup(const void *a, const void *b);
-
-PhysicalGroup *Create_PhysicalGroup(int Num, int typ, List_T * intlist);
-Curve         *Create_Curve(int Num, int Typ, int Order, List_T * Liste,
-			    List_T * Knots, int p1, int p2, double u1, double u2);
-Surface       *Create_Surface(int Num, int Typ);
-Volume        *Create_Volume(int Num, int Typ);
-EdgeLoop      *Create_EdgeLoop(int Num, List_T * intlist);
-SurfaceLoop   *Create_SurfaceLoop(int Num, List_T * intlist);
-
-void Free_PhysicalGroup(void *a, void *b);
-void Free_MeshPartition(void *a, void *b);
-void Free_Surface(void *a, void *b);
-void Free_Volume(void *a, void *b);
-void Free_Volume_But_Not_Elements(void *a, void *b);
-void Free_Curve(void *a, void *b);
-void Free_EdgeLoop(void *a, void *b);
-void Free_SurfaceLoop(void *a, void *b);
-
-void End_Curve(Curve * c);
-void End_Surface(Surface * s, int reset_orientations=1);
-
-int  Add_MeshPartition(int Num, Mesh * M);
-
-#endif
diff --git a/Mesh/DivideAndConquer.cpp b/Mesh/DivideAndConquer.cpp
index b1829d8090..0993d94ad6 100644
--- a/Mesh/DivideAndConquer.cpp
+++ b/Mesh/DivideAndConquer.cpp
@@ -1,4 +1,4 @@
-// $Id: DivideAndConquer.cpp,v 1.1 2006-11-25 02:47:39 geuzaine Exp $
+// $Id: DivideAndConquer.cpp,v 1.2 2006-11-25 16:52:44 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -39,9 +39,15 @@
 
 #include "Gmsh.h"
 #include "Numeric.h"
-#include "Mesh.h"
+#include "DivideAndConquer.h"
 #include "Context.h"
 
+#define EXTERN    1
+#define INTERN    2
+
+#define NOTTOLINK 1
+#define TOLINK    2
+
 extern Context_T CTX;
 
 static PointRecord *pPointArray;
@@ -569,7 +575,6 @@ void filldel(Delaunay * deladd, int aa, int bb, int cc,
 {
   double qual, newqual;
   MPoint pt2;
-  Vertex *v, *dum;
 
   deladd->t.a = aa;
   deladd->t.b = bb;
diff --git a/Mesh/Mesh.h b/Mesh/DivideAndConquer.h
similarity index 50%
rename from Mesh/Mesh.h
rename to Mesh/DivideAndConquer.h
index 139215b7b6..6a66cc1ec4 100644
--- a/Mesh/Mesh.h
+++ b/Mesh/DivideAndConquer.h
@@ -1,5 +1,5 @@
-#ifndef _MESH_H_
-#define _MESH_H_
+#ifndef _DIVIDE_AND_CONQUER_H_
+#define _DIVIDE_AND_CONQUER_H_
 
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -20,12 +20,6 @@
 // 
 // Please report all bugs and problems to <gmsh@geuz.org>.
 
-#include "GmshDefines.h"
-#include "List.h"
-#include "Tree.h"
-#include "Vertex.h"
-#include "ExtrudeParams.h"
-
 typedef struct _POINT PointRecord, *PointPeek;
 typedef struct _CONTOUR ContourRecord, *ContourPeek;
 typedef struct _DOC DocRecord, *DocPeek;
@@ -54,11 +48,6 @@ struct _POINT{
   void *data;
 };
 
-typedef struct{
-  int Num;
-  double t, lc, p;
-}IntPoint;
-
 struct _CDLIST{
   PointNumero point_num;
   DListPeek next, prev;
@@ -122,129 +111,6 @@ struct _MAILLAGE{
   int zone;
 };
 
-class DrawingColor{
- public:
-  int type;
-  unsigned int geom, mesh;
-};
-
-struct _Surf{
-  int Num;
-  int Typ;
-  char Visible;
-  int Method;
-  int Recombine;
-  int Recombine_Dir; // -1 is left, +1 is right, 0 is alternated
-  double RecombineAngle;
-  int ipar[5];
-  int Nu, Nv;
-  List_T *Generatrices;
-  List_T *EmbeddedCurves;
-  List_T *EmbeddedPoints;
-  List_T *Control_Points;
-  List_T *TrsfPoints;
-  double plan[3][3];
-  double invplan[3][3];
-  double a, b, c, d;
-  List_T *Orientations;
-  List_T *Contours;
-  Tree_T *Vertices;
-  int OrderU, OrderV;
-  float *ku, *kv, *cp;
-  struct _Surf *Support;
-  ExtrudeParams *Extrude;
-  DrawingColor Color;
-};
-
-typedef struct _Surf Surface;
-
-typedef struct{
-  int Num;
-  List_T *Curves;
-}EdgeLoop;
-
-typedef struct{
-  int Num;
-  List_T *Surfaces;
-}SurfaceLoop;
-
-typedef struct{
-  int Num;
-  int Typ;
-  char Visible;
-  List_T *Entities;
-}PhysicalGroup;
-
-typedef struct {
-  int Num;
-  int Typ;
-  char Visible;
-  int Method;
-  int ipar[8];
-  ExtrudeParams *Extrude;
-  List_T *TrsfPoints;
-  List_T *Surfaces;
-  List_T *SurfacesOrientations;
-  Tree_T *Vertices;
-  DrawingColor Color;
-}Volume;
-
-typedef struct _Mesh Mesh;
-
-typedef struct{
-  double t1, t2, f1, f2, incl;
-  Vertex *v[4];
-  double invmat[3][3];
-  double n[3];
-}CircParam;
-
-typedef struct{
-  int Num;
-  int Typ;
-  char Visible;
-  int Method;
-  int ipar[4];
-  double dpar[4];
-  double l;
-  double mat[4][4];
-  Vertex *beg, *end;
-  double ubeg, uend;
-  List_T *Control_Points;
-  List_T *Vertices;
-  ExtrudeParams *Extrude;
-  float *k, *cp;
-  int degre;
-  CircParam Circle;
-  char functu[256], functv[256], functw[256];
-  DrawingColor Color;
-}Curve;
-
-struct _Mesh{
-  Tree_T *Points;
-  Tree_T *Vertices;
-  Tree_T *Curves;
-  Tree_T *Surfaces;
-  Tree_T *Volumes;
-  Tree_T *SurfaceLoops;
-  Tree_T *EdgeLoops;
-  List_T *PhysicalGroups;
-  int MaxPointNum, MaxLineNum, MaxLineLoopNum, MaxSurfaceNum;
-  int MaxSurfaceLoopNum, MaxVolumeNum, MaxPhysicalNum;
-};
-
-// public functions
-
-void mai3d(int Asked);
-void Init_Mesh0();
-void Init_Mesh();
-void Maillage_Dimension_1();
-void Maillage_Dimension_2();
-void Maillage_Dimension_3();
 void Make_Mesh_With_Points(DocRecord * ptr, PointRecord * Liste, int Numpoints);
-double BGMXYZ(double X, double Y, double Z);
-int BGMExists();
-void ApplyLcFactor();
-void Degre1();
-void Degre2(bool linear=true, bool incomplete=false);
 
 #endif
diff --git a/Mesh/Generator.cpp b/Mesh/Generator.cpp
index 75a6ec9141..c120ff30b6 100644
--- a/Mesh/Generator.cpp
+++ b/Mesh/Generator.cpp
@@ -1,4 +1,4 @@
-// $Id: Generator.cpp,v 1.100 2006-11-25 03:30:03 geuzaine Exp $
+// $Id: Generator.cpp,v 1.101 2006-11-25 16:52:44 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -20,9 +20,8 @@
 // Please report all bugs and problems to <gmsh@geuz.org>.
 
 #include "Gmsh.h"
+#include "Geo.h"
 #include "Numeric.h"
-#include "Mesh.h"
-#include "Create.h"
 #include "Context.h"
 #include "OpenFile.h"
 #include "Views.h"
@@ -31,6 +30,8 @@
 #include "meshGFace.h"
 #include "meshGRegion.h"
 #include "GModel.h"
+#include "BackgroundMesh.h"
+#include "SecondOrder.h"
 
 extern Mesh *THEM;
 extern Context_T CTX;
@@ -254,7 +255,6 @@ void Maillage_Dimension_3()
 
 void Init_Mesh0()
 {
-  THEM->Vertices = NULL;
   THEM->Points = NULL;
   THEM->Curves = NULL;
   THEM->SurfaceLoops = NULL;
@@ -274,9 +274,6 @@ void Init_Mesh()
   THEM->MaxVolumeNum = 0;
   THEM->MaxPhysicalNum = 0;
 
-  Tree_Action(THEM->Vertices, Free_Vertex);  
-  Tree_Delete(THEM->Vertices);
-
   Tree_Action(THEM->Points, Free_Vertex);  
   Tree_Delete(THEM->Points);
 
@@ -298,7 +295,6 @@ void Init_Mesh()
   List_Action(THEM->PhysicalGroups, Free_PhysicalGroup);
   List_Delete(THEM->PhysicalGroups);
 
-  THEM->Vertices = Tree_Create(sizeof(Vertex *), compareVertex);
   THEM->Points = Tree_Create(sizeof(Vertex *), compareVertex);
   THEM->Curves = Tree_Create(sizeof(Curve *), compareCurve);
   THEM->SurfaceLoops = Tree_Create(sizeof(SurfaceLoop *), compareSurfaceLoop);
diff --git a/Mesh/Generator.h b/Mesh/Generator.h
new file mode 100644
index 0000000000..d8ebb27866
--- /dev/null
+++ b/Mesh/Generator.h
@@ -0,0 +1,31 @@
+#ifndef _GENERATOR_H_
+#define _GENERATOR_H_
+
+// Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+// 
+// Please report all bugs and problems to <gmsh@geuz.org>.
+
+void mai3d(int Asked);
+void Init_Mesh0();
+void Init_Mesh();
+void Maillage_Dimension_1();
+void Maillage_Dimension_2();
+void Maillage_Dimension_3();
+void ApplyLcFactor();
+
+#endif
diff --git a/Mesh/Makefile b/Mesh/Makefile
index 31615e8cce..d08c771ada 100644
--- a/Mesh/Makefile
+++ b/Mesh/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.139 2006-11-25 02:49:27 geuzaine Exp $
+# $Id: Makefile,v 1.140 2006-11-25 16:52:44 geuzaine Exp $
 #
 # Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 #
@@ -33,7 +33,6 @@ CFLAGS  =  ${OPTIM} ${FLAGS} ${INCLUDE}
 SRC = DivideAndConquer.cpp \
       BackgroundMesh.cpp \
       BDS.cpp \
-      Create.cpp \
       Generator.cpp \
       Utils.cpp \
       meshGEdge.cpp \
@@ -41,10 +40,7 @@ SRC = DivideAndConquer.cpp \
       meshGFaceTransfinite.cpp \
       meshGRegionDelaunayInsertion.cpp \
       meshGRegion.cpp \
-      Nurbs.cpp \
-      Interpolation.cpp \
-      SecondOrder.cpp \
-      Vertex.cpp
+      SecondOrder.cpp
 
 OBJ = ${SRC:.cpp=.o}
 
@@ -79,16 +75,16 @@ depend:
 DivideAndConquer.o: DivideAndConquer.cpp ../Common/Gmsh.h \
   ../Common/Message.h ../DataStr/Malloc.h ../DataStr/List.h \
   ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h \
-  ../DataStr/Tree.h ../Numeric/Numeric.h Mesh.h ../Common/GmshDefines.h \
-  Vertex.h ../Geo/ExtrudeParams.h ../Common/Context.h
+  ../DataStr/Tree.h ../Numeric/Numeric.h DivideAndConquer.h \
+  ../Common/Context.h
 BackgroundMesh.o: BackgroundMesh.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
   ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
-  Mesh.h ../Common/GmshDefines.h Vertex.h ../Geo/ExtrudeParams.h \
   ../Common/Views.h ../Common/ColorTable.h ../Common/VertexArray.h \
   ../Common/SmoothNormals.h ../Numeric/Numeric.h \
-  ../Common/AdaptiveViews.h ../Common/GmshMatrix.h ../Common/Context.h \
-  ../Common/OctreePost.h ../Common/Octree.h ../Common/OctreeInternals.h
+  ../Common/AdaptiveViews.h ../Common/GmshMatrix.h BackgroundMesh.h \
+  ../Common/Context.h ../Common/OctreePost.h ../Common/Octree.h \
+  ../Common/OctreeInternals.h
 BDS.o: BDS.cpp ../Numeric/Numeric.h ../Common/GmshMatrix.h BDS.h \
   ../Geo/GFace.h ../Geo/GPoint.h ../Geo/GEntity.h ../Geo/Range.h \
   ../Geo/SPoint3.h ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h \
@@ -103,72 +99,65 @@ BDS.o: BDS.cpp ../Numeric/Numeric.h ../Common/GmshMatrix.h BDS.h \
   ../Geo/ExtrudeParams.h ../Common/Views.h ../Common/ColorTable.h \
   ../Common/VertexArray.h ../Common/SmoothNormals.h \
   ../Common/AdaptiveViews.h ../Common/GmshMatrix.h ../Common/Message.h
-Create.o: Create.cpp ../Common/Gmsh.h ../Common/Message.h \
-  ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
-  ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
-  ../Numeric/Numeric.h ../Geo/Geo.h ../Geo/CAD.h ../Mesh/Mesh.h \
-  ../Common/GmshDefines.h ../Mesh/Vertex.h ../Geo/ExtrudeParams.h \
-  ../Geo/ExtrudeParams.h Mesh.h Utils.h Vertex.h ../Common/Context.h \
-  Create.h
 Generator.o: Generator.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
   ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
-  ../Numeric/Numeric.h Mesh.h ../Common/GmshDefines.h Vertex.h \
-  ../Geo/ExtrudeParams.h Create.h ../Common/Context.h \
-  ../Parser/OpenFile.h ../Common/Views.h ../Common/ColorTable.h \
-  ../Common/VertexArray.h ../Common/SmoothNormals.h \
-  ../Common/AdaptiveViews.h ../Common/GmshMatrix.h ../Common/OS.h \
-  meshGEdge.h meshGFace.h meshGRegion.h ../Geo/GModel.h ../Geo/GVertex.h \
-  ../Geo/GEntity.h ../Geo/Range.h ../Geo/SPoint3.h \
-  ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../Geo/MVertex.h \
-  ../Geo/SPoint3.h ../Geo/GPoint.h ../Geo/SPoint2.h ../Geo/GEdge.h \
-  ../Geo/GEntity.h ../Geo/GVertex.h ../Geo/SVector3.h ../Geo/SPoint3.h \
-  ../Geo/SPoint3.h ../Geo/SPoint2.h ../Geo/MElement.h ../Geo/MVertex.h \
-  ../Geo/MEdge.h ../Geo/MVertex.h ../Geo/SVector3.h ../Common/Hash.h \
-  ../Geo/MFace.h ../Geo/MVertex.h ../Geo/SVector3.h \
-  ../Geo/ExtrudeParams.h ../Geo/GFace.h ../Geo/GPoint.h ../Geo/GEntity.h \
-  ../Geo/GEdgeLoop.h ../Geo/GEdge.h ../Geo/MElement.h ../Geo/SPoint2.h \
-  ../Geo/SVector3.h ../Geo/Pair.h ../Geo/ExtrudeParams.h ../Geo/GRegion.h \
-  ../Geo/GEntity.h ../Geo/MElement.h ../Geo/ExtrudeParams.h \
-  ../Geo/SBoundingBox3d.h
+  ../Geo/Geo.h ../Common/GmshDefines.h ../Geo/ExtrudeParams.h \
+  ../Numeric/Numeric.h ../Common/Context.h ../Parser/OpenFile.h \
+  ../Common/Views.h ../Common/ColorTable.h ../Common/VertexArray.h \
+  ../Common/SmoothNormals.h ../Common/AdaptiveViews.h \
+  ../Common/GmshMatrix.h ../Common/OS.h meshGEdge.h meshGFace.h \
+  meshGRegion.h ../Geo/GModel.h ../Geo/GVertex.h ../Geo/GEntity.h \
+  ../Geo/Range.h ../Geo/SPoint3.h ../Geo/SBoundingBox3d.h \
+  ../Geo/SPoint3.h ../Geo/MVertex.h ../Geo/SPoint3.h ../Geo/GPoint.h \
+  ../Geo/SPoint2.h ../Geo/GEdge.h ../Geo/GEntity.h ../Geo/GVertex.h \
+  ../Geo/SVector3.h ../Geo/SPoint3.h ../Geo/SPoint3.h ../Geo/SPoint2.h \
+  ../Geo/MElement.h ../Geo/MVertex.h ../Geo/MEdge.h ../Geo/MVertex.h \
+  ../Geo/SVector3.h ../Common/Hash.h ../Geo/MFace.h ../Geo/MVertex.h \
+  ../Geo/SVector3.h ../Geo/ExtrudeParams.h ../Geo/GFace.h ../Geo/GPoint.h \
+  ../Geo/GEntity.h ../Geo/GEdgeLoop.h ../Geo/GEdge.h ../Geo/MElement.h \
+  ../Geo/SPoint2.h ../Geo/SVector3.h ../Geo/Pair.h ../Geo/ExtrudeParams.h \
+  ../Geo/GRegion.h ../Geo/GEntity.h ../Geo/MElement.h \
+  ../Geo/ExtrudeParams.h ../Geo/SBoundingBox3d.h BackgroundMesh.h \
+  SecondOrder.h
 Utils.o: Utils.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
   ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
-  ../Numeric/Numeric.h ../Geo/Geo.h ../Geo/CAD.h ../Mesh/Mesh.h \
-  ../Common/GmshDefines.h ../Mesh/Vertex.h ../Geo/ExtrudeParams.h \
-  ../Geo/ExtrudeParams.h Mesh.h Interpolation.h Vertex.h \
+  ../Geo/Geo.h ../Common/GmshDefines.h ../Geo/ExtrudeParams.h \
+  ../Geo/GeoInterpolation.h ../Geo/Geo.h Utils.h ../Numeric/Numeric.h \
   ../Common/Context.h
-meshGEdge.o: meshGEdge.cpp meshGEdge.h ../Geo/GEdge.h ../Geo/GEntity.h \
-  ../Geo/Range.h ../Geo/SPoint3.h ../Geo/SBoundingBox3d.h \
-  ../Geo/SPoint3.h ../Common/GmshDefines.h ../Geo/GVertex.h \
-  ../Geo/GEntity.h ../Geo/MVertex.h ../Geo/SPoint3.h ../Geo/GPoint.h \
-  ../Geo/SPoint2.h ../Geo/SVector3.h ../Geo/SPoint3.h ../Geo/SPoint3.h \
+meshGEdge.o: meshGEdge.cpp ../Common/Gmsh.h ../Common/Message.h \
+  ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
+  ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
+  meshGEdge.h ../Geo/GEdge.h ../Geo/GEntity.h ../Geo/Range.h \
+  ../Geo/SPoint3.h ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h \
+  ../Common/GmshDefines.h ../Geo/GVertex.h ../Geo/GEntity.h \
+  ../Geo/MVertex.h ../Geo/SPoint3.h ../Geo/GPoint.h ../Geo/SPoint2.h \
+  ../Geo/SVector3.h ../Geo/SPoint3.h ../Geo/SPoint3.h ../Geo/SPoint2.h \
+  ../Geo/MElement.h ../Geo/MVertex.h ../Geo/MEdge.h ../Geo/MVertex.h \
+  ../Geo/SVector3.h ../Common/Hash.h ../Geo/MFace.h ../Geo/MVertex.h \
+  ../Geo/SVector3.h ../Numeric/Numeric.h ../Common/Context.h \
+  ../Geo/ExtrudeParams.h ../Geo/GFace.h ../Geo/GPoint.h ../Geo/GEntity.h \
+  ../Geo/GEdgeLoop.h ../Geo/GEdge.h ../Geo/MElement.h ../Geo/SPoint2.h \
+  ../Geo/SVector3.h ../Geo/Pair.h ../Geo/ExtrudeParams.h Utils.h \
+  ../Geo/Geo.h ../Geo/ExtrudeParams.h BackgroundMesh.h
+meshGFace.o: meshGFace.cpp meshGFace.h DivideAndConquer.h \
+  BackgroundMesh.h ../Geo/GVertex.h ../Geo/GEntity.h ../Geo/Range.h \
+  ../Geo/SPoint3.h ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h \
+  ../Common/GmshDefines.h ../Geo/MVertex.h ../Geo/SPoint3.h \
+  ../Geo/GPoint.h ../Geo/SPoint2.h ../Geo/GEdge.h ../Geo/GEntity.h \
+  ../Geo/GVertex.h ../Geo/SVector3.h ../Geo/SPoint3.h ../Geo/SPoint3.h \
   ../Geo/SPoint2.h ../Geo/MElement.h ../Geo/MVertex.h ../Geo/MEdge.h \
   ../Geo/MVertex.h ../Geo/SVector3.h ../Common/Hash.h ../Geo/MFace.h \
   ../Geo/MVertex.h ../Geo/SVector3.h ../Numeric/Numeric.h \
   ../Common/Context.h ../DataStr/List.h ../Geo/ExtrudeParams.h \
   ../Geo/GFace.h ../Geo/GPoint.h ../Geo/GEntity.h ../Geo/GEdgeLoop.h \
   ../Geo/GEdge.h ../Geo/MElement.h ../Geo/SPoint2.h ../Geo/SVector3.h \
-  ../Geo/Pair.h ../Geo/ExtrudeParams.h ../Common/Gmsh.h \
-  ../Common/Message.h ../DataStr/Malloc.h ../DataStr/Tree.h \
-  ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
-  Utils.h Vertex.h Mesh.h
-meshGFace.o: meshGFace.cpp meshGFace.h ../Geo/GVertex.h ../Geo/GEntity.h \
-  ../Geo/Range.h ../Geo/SPoint3.h ../Geo/SBoundingBox3d.h \
-  ../Geo/SPoint3.h ../Common/GmshDefines.h ../Geo/MVertex.h \
-  ../Geo/SPoint3.h ../Geo/GPoint.h ../Geo/SPoint2.h ../Geo/GEdge.h \
-  ../Geo/GEntity.h ../Geo/GVertex.h ../Geo/SVector3.h ../Geo/SPoint3.h \
-  ../Geo/SPoint3.h ../Geo/SPoint2.h ../Geo/MElement.h ../Geo/MVertex.h \
-  ../Geo/MEdge.h ../Geo/MVertex.h ../Geo/SVector3.h ../Common/Hash.h \
-  ../Geo/MFace.h ../Geo/MVertex.h ../Geo/SVector3.h ../Numeric/Numeric.h \
-  ../Common/Context.h ../DataStr/List.h ../Geo/ExtrudeParams.h \
-  ../Geo/GFace.h ../Geo/GPoint.h ../Geo/GEntity.h ../Geo/GEdgeLoop.h \
-  ../Geo/GEdge.h ../Geo/MElement.h ../Geo/SPoint2.h ../Geo/SVector3.h \
-  ../Geo/Pair.h ../Geo/ExtrudeParams.h Utils.h Vertex.h Mesh.h \
-  ../DataStr/Tree.h ../DataStr/avl.h ../Common/Message.h BDS.h \
-  ../Common/Views.h ../Common/ColorTable.h ../Common/VertexArray.h \
-  ../Common/SmoothNormals.h ../Common/AdaptiveViews.h \
-  ../Common/GmshMatrix.h
+  ../Geo/Pair.h ../Geo/ExtrudeParams.h Utils.h ../Geo/Geo.h \
+  ../DataStr/Tree.h ../DataStr/avl.h ../Geo/ExtrudeParams.h \
+  ../Common/Message.h BDS.h ../Common/Views.h ../Common/ColorTable.h \
+  ../Common/VertexArray.h ../Common/SmoothNormals.h \
+  ../Common/AdaptiveViews.h ../Common/GmshMatrix.h
 meshGFaceTransfinite.o: meshGFaceTransfinite.cpp meshGFace.h \
   ../Geo/GVertex.h ../Geo/GEntity.h ../Geo/Range.h ../Geo/SPoint3.h \
   ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../Common/GmshDefines.h \
@@ -208,19 +197,6 @@ meshGRegion.o: meshGRegion.cpp meshGRegion.h ../Geo/GModel.h \
   ../Common/Views.h ../Common/ColorTable.h ../Common/VertexArray.h \
   ../Common/SmoothNormals.h ../Common/AdaptiveViews.h \
   ../Common/GmshMatrix.h ../Common/Message.h
-Nurbs.o: Nurbs.cpp ../Common/Gmsh.h ../Common/Message.h \
-  ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
-  ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
-  Nurbs.h Vertex.h Mesh.h ../Common/GmshDefines.h ../Geo/ExtrudeParams.h \
-  ../Geo/Geo.h ../Geo/GeoUtils.h ../Mesh/Mesh.h Create.h ../Geo/CAD.h \
-  ../Mesh/Vertex.h ../Geo/ExtrudeParams.h
-Interpolation.o: Interpolation.cpp ../Common/Gmsh.h ../Common/Message.h \
-  ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
-  ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
-  ../Numeric/Numeric.h ../Geo/Geo.h Nurbs.h Vertex.h Mesh.h \
-  ../Common/GmshDefines.h ../Geo/ExtrudeParams.h ../Geo/CAD.h \
-  ../Mesh/Mesh.h ../Mesh/Vertex.h ../Geo/ExtrudeParams.h Utils.h \
-  Interpolation.h
 SecondOrder.o: SecondOrder.cpp ../Geo/GModel.h ../Geo/GVertex.h \
   ../Geo/GEntity.h ../Geo/Range.h ../Geo/SPoint3.h \
   ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../Common/GmshDefines.h \
@@ -238,8 +214,3 @@ SecondOrder.o: SecondOrder.cpp ../Geo/GModel.h ../Geo/GVertex.h \
   ../Geo/GEdge.h ../Geo/GFace.h ../Geo/GRegion.h ../Geo/MVertex.h \
   ../Geo/MEdge.h ../Geo/MElement.h ../Common/VertexArray.h \
   ../Common/Message.h ../Common/OS.h
-Vertex.o: Vertex.cpp ../Common/Gmsh.h ../Common/Message.h \
-  ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
-  ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
-  ../Numeric/Numeric.h Vertex.h Mesh.h ../Common/GmshDefines.h \
-  ../Geo/ExtrudeParams.h ../Common/Context.h
diff --git a/Mesh/Nurbs.cpp b/Mesh/Nurbs.cpp
deleted file mode 100644
index d3fcb2ce68..0000000000
--- a/Mesh/Nurbs.cpp
+++ /dev/null
@@ -1,449 +0,0 @@
-// $Id: Nurbs.cpp,v 1.19 2006-11-25 00:44:25 geuzaine Exp $
-//
-// Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-// USA.
-// 
-// Please report all bugs and problems to <gmsh@geuz.org>.
-
-#include "Gmsh.h"
-#include "Nurbs.h"
-#include "Mesh.h"
-#include "Geo.h"
-#include "GeoUtils.h"
-#include "Create.h"
-#include "CAD.h"
-
-extern Mesh *THEM;
-
-// Cubic spline
-
-Vertex InterpolateCubicSpline(Vertex * v[4], double t, double mat[4][4],
-                              int derivee, double t1, double t2)
-{
-  Vertex V;
-  int i, j;
-  double vec[4], T[4];
-
-  V.Pos.X = V.Pos.Y = V.Pos.Z = 0.0;
-  V.lc = (1 - t) * v[1]->lc + t * v[2]->lc;
-  V.w = (1 - t) * v[1]->w + t * v[2]->w;
-
-  if(derivee) {
-    T[3] = 0.;
-    T[2] = 1.;
-    T[1] = 2. * t;
-    T[0] = 3. * t * t;
-  }
-  else {
-    T[3] = 1.;
-    T[2] = t;
-    T[1] = t * t;
-    T[0] = t * t * t;
-  }
-
-  for(i = 0; i < 4; i++) {
-    vec[i] = 0.0;
-  }
-
-  /* X */
-  for(i = 0; i < 4; i++) {
-    for(j = 0; j < 4; j++) {
-      vec[i] += mat[i][j] * v[j]->Pos.X;
-    }
-  }
-
-  for(j = 0; j < 4; j++) {
-    V.Pos.X += T[j] * vec[j];
-    vec[j] = 0.0;
-  }
-
-  /* Y */
-  for(i = 0; i < 4; i++) {
-    for(j = 0; j < 4; j++) {
-      vec[i] += mat[i][j] * v[j]->Pos.Y;
-    }
-  }
-
-  for(j = 0; j < 4; j++) {
-    V.Pos.Y += T[j] * vec[j];
-    vec[j] = 0.0;
-  }
-
-  /* Z */
-  for(i = 0; i < 4; i++) {
-    for(j = 0; j < 4; j++) {
-      vec[i] += mat[i][j] * v[j]->Pos.Z;
-    }
-  }
-  for(j = 0; j < 4; j++) {
-    V.Pos.Z += T[j] * vec[j];
-    vec[j] = 0.0;
-  }
-
-  if(derivee) {
-    V.Pos.X /= ((t2 - t1));
-    V.Pos.Y /= ((t2 - t1));
-    V.Pos.Z /= ((t2 - t1));
-  }
-
-  return V;
-}
-
-
-// Uniform BSplines
-
-Vertex InterpolateUBS(Curve * Curve, double u, int derivee)
-{
-  int NbControlPoints, NbCurves, iCurve;
-  double t, t1, t2;
-  Vertex *v[4];
-
-  NbControlPoints = List_Nbr(Curve->Control_Points);
-  NbCurves = NbControlPoints - 3;
-
-  iCurve = (int)(u * (double)NbCurves) + 1;
-
-  if(iCurve > NbCurves)
-    iCurve = NbCurves;
-  else if (iCurve < 1)
-    iCurve = 1;
-
-  t1 = (double)(iCurve - 1) / (double)(NbCurves);
-  t2 = (double)(iCurve) / (double)(NbCurves);
-
-  t = (u - t1) / (t2 - t1);
-
-  List_Read(Curve->Control_Points, iCurve - 1, &v[0]);
-  List_Read(Curve->Control_Points, iCurve, &v[1]);
-  List_Read(Curve->Control_Points, iCurve + 1, &v[2]);
-  List_Read(Curve->Control_Points, iCurve + 2, &v[3]);
-
-  return InterpolateCubicSpline(v, t, Curve->mat, derivee, t1, t2);
-}
-
-// Non Uniform BSplines
-
-int findSpan(double u, int deg, int n, float *U)
-{
-  if(u >= U[n])
-    return n - 1;
-  if(u <= U[0])
-    return deg;
-
-  int low = deg;
-  int high = n + 1;
-  int mid = (low + high) / 2;
-
-  while(u < U[mid] || u >= U[mid + 1]) {
-    if(u < U[mid])
-      high = mid;
-    else
-      low = mid;
-    mid = (low + high) / 2;
-  }
-  return mid;
-}
-
-void basisFuns(double u, int i, int deg, float *U, double *N)
-{
-  double left[1000];
-  double *right = &left[deg + 1];
-
-  double temp, saved;
-
-  //N.resize(deg+1) ;
-
-  N[0] = 1.0;
-  for(int j = 1; j <= deg; j++) {
-    left[j] = u - U[i + 1 - j];
-    right[j] = U[i + j] - u;
-    saved = 0.0;
-    for(int r = 0; r < j; r++) {
-      temp = N[r] / (right[r + 1] + left[j - r]);
-      N[r] = saved + right[r + 1] * temp;
-      saved = left[j - r] * temp;
-    }
-    N[j] = saved;
-  }
-}
-
-Vertex InterpolateNurbs(Curve * Curve, double u, int derivee)
-{
-  static double Nb[1000];
-  int span =
-    findSpan(u, Curve->degre, List_Nbr(Curve->Control_Points), Curve->k);
-  Vertex p, *v;
-
-  basisFuns(u, span, Curve->degre, Curve->k, Nb);
-  p.Pos.X = p.Pos.Y = p.Pos.Z = p.w = p.lc = 0.0;
-  for(int i = Curve->degre; i >= 0; --i) {
-    List_Read(Curve->Control_Points, span - Curve->degre + i, &v);
-    p.Pos.X += Nb[i] * v->Pos.X;
-    p.Pos.Y += Nb[i] * v->Pos.Y;
-    p.Pos.Z += Nb[i] * v->Pos.Z;
-    p.w += Nb[i] * v->w;
-    p.lc += Nb[i] * v->lc;
-  }
-  return p;
-}
-
-Vertex InterpolateNurbsSurface(Surface * s, double u, double v)
-{
-  int uspan = findSpan(u, s->OrderU, s->Nu, s->ku);
-  int vspan = findSpan(v, s->OrderV, s->Nv, s->kv);
-  double Nu[1000], Nv[1000];
-  Vertex sp, temp[1000], *pv;
-
-  basisFuns(u, uspan, s->OrderU, s->ku, Nu);
-  basisFuns(v, vspan, s->OrderV, s->kv, Nv);
-
-  int l, ll, kk;
-  for(l = 0; l <= s->OrderV; l++) {
-    temp[l].Pos.X = temp[l].Pos.Y = temp[l].Pos.Z = temp[l].w = temp[l].lc =
-      0.0;
-    for(int k = 0; k <= s->OrderU; k++) {
-      kk = uspan - s->OrderU + k;
-      ll = vspan - s->OrderV + l;
-      List_Read(s->Control_Points, kk + s->Nu * ll, &pv);
-      temp[l].Pos.X += Nu[k] * pv->Pos.X;
-      temp[l].Pos.Y += Nu[k] * pv->Pos.Y;
-      temp[l].Pos.Z += Nu[k] * pv->Pos.Z;
-      temp[l].w += Nu[k] * pv->w;
-      temp[l].lc += Nu[k] * pv->lc;
-    }
-  }
-  sp.Pos.X = sp.Pos.Y = sp.Pos.Z = sp.w = sp.lc = 0.0;
-  for(l = 0; l <= s->OrderV; l++) {
-    sp.Pos.X += Nv[l] * temp[l].Pos.X;
-    sp.Pos.Y += Nv[l] * temp[l].Pos.Y;
-    sp.Pos.Z += Nv[l] * temp[l].Pos.Z;
-    sp.w += Nv[l] * temp[l].w;
-    sp.lc += Nv[l] * temp[l].lc;
-  }
-  return sp;
-}
-
-
-// Surface creation helpers
-
-void CreateNurbsSurfaceSupport(int Num, int Order1, int Order2,
-                               List_T * List, List_T * ku, List_T * kv)
-{
-  // This routine has been heavily modified to fit the new interfaces,
-  // but has not been tested since then. It's probably full of bugs
-  // now.
-  List_T *ListOfDouble_L;
-  List_T *ListCP = List_Create(2, 2, sizeof(int));
-
-  for(int j = 0; j < List_Nbr(List); j++) {
-    List_Read(List, j, &ListOfDouble_L);
-    for(int i = 0; i < List_Nbr(ListOfDouble_L); i++) {
-      double d;
-      List_Read(ListOfDouble_L, i, &d);
-      int N = (int)d;
-      List_Add(ListCP, &N);
-    }
-  }
-  List_Read(List, 0, &ListOfDouble_L);
-  int Nu = List_Nbr(List);
-  int Nv = List_Nbr(ListOfDouble_L);
-
-  Surface *s = Create_Surface(Num, MSH_SURF_NURBS);
-  s->Support = NULL;
-  s->Control_Points = List_Create(4, 1, sizeof(Vertex *));
-  s->OrderU = Order1;
-  s->OrderV = Order2;
-  s->Nu = Nu;
-  s->Nv = Nv;
-  for(int i = 0; i < List_Nbr(ListCP); i++) {
-    int j;
-    List_Read(ListCP, i, &j);
-    Vertex *v = FindPoint(j);
-    if(v){
-      List_Add(s->Control_Points, &v);
-    }
-    else{
-      Msg(GERROR, "Unknown control point %d in nurbs surface", j);
-    }
-  }
-
-  s->ku = (float *)malloc(List_Nbr(ku) * sizeof(float));
-  s->kv = (float *)malloc(List_Nbr(kv) * sizeof(float));
-
-  double kumin = 0., kumax = 1.;
-  double kvmin = 0., kvmax = 1.;
-
-  for(int i = 0; i < List_Nbr(ku); i++) {
-    double d;
-    List_Read(ku, i, &d);
-    float f = (float)((d - kumin) / (kumax - kumin));
-    s->ku[i] = f;
-  }
-  for(int i = 0; i < List_Nbr(kv); i++) {
-    double d;
-    List_Read(kv, i, &d);
-    float f = (float)((d - kvmin) / (kvmax - kvmin));
-    s->kv[i] = f;
-  }
-
-  List_Delete(ListCP);
-
-  End_Surface(s);
-  Tree_Add(THEM->Surfaces, &s);
-}
-
-void CreateNurbsSurface(int Num, int Order1, int Order2, List_T * List,
-                        List_T * ku, List_T * kv)
-{
-  // This routine has been heavily modified to fit the new interfaces,
-  // but has not been tested since then. It's probably full of bugs
-  // now.
-
-  List_T *ListOfDouble_L, *Listint, *ListCP;
-  int Loop[4];
-
-  ListCP = List_Create(2, 2, sizeof(int));
-
-  double kumin, kumax;
-  List_Read(ku, 0, &kumin);
-  List_Read(ku, List_Nbr(ku) - 1, &kumax);
-  double kvmin, kvmax;
-  List_Read(kv, 0, &kvmin);
-  List_Read(kv, List_Nbr(kv) - 1, &kvmax);
-  for(int j = 0; j < List_Nbr(List); j++) {
-    List_Read(List, j, &ListOfDouble_L);
-    for(int i = 0; i < List_Nbr(ListOfDouble_L); i++) {
-      double d;
-      List_Read(ListOfDouble_L, i, &d);
-      int N = (int)d;
-      List_Add(ListCP, &N);
-    }
-  }
-
-  // 1st and 3rd gen
-  List_Read(List, 0, &ListOfDouble_L);
-  Listint = ListOfDouble2ListOfInt(ListOfDouble_L);
-  if(recognize_seg(MSH_SEGM_NURBS, Listint, &Loop[0])) {
-  }
-  else {
-    Loop[0] = NEWREG();
-    Curve *c = Create_Curve(Loop[0], MSH_SEGM_NURBS, Order1, Listint, NULL, 
-			    -1, -1, kumin, kumax);
-    Tree_Add(THEM->Curves, &c);
-    CreateReversedCurve(c);
-    c->k = (float *)malloc(4 * List_Nbr(ku) * sizeof(float));
-    for(int i = 0; i < List_Nbr(ku); i++) {
-      double d;
-      List_Read(ku, i, &d);
-      c->k[i] = (float)d /*((d-kumin)/(kumax-kumin)) */ ;
-    }
-  }
-  List_Delete(Listint);
-
-  List_Read(List, List_Nbr(List) - 1, &ListOfDouble_L);
-  Listint = ListOfDouble2ListOfInt(ListOfDouble_L);
-  if(recognize_seg(MSH_SEGM_NURBS, Listint, &Loop[2])) {
-  }
-  else {
-    Loop[2] = NEWREG();
-    Curve *c = Create_Curve(Loop[2], MSH_SEGM_NURBS, Order1, Listint, NULL, 
-			    -1, -1, kumin, kumax);
-    Tree_Add(THEM->Curves, &c);
-    CreateReversedCurve(c);
-    c->k = (float *)malloc(4 * List_Nbr(ku) * sizeof(float));
-    for(int i = 0; i < List_Nbr(ku); i++) {
-      double d;
-      List_Read(ku, i, &d);
-      c->k[i] = (float)d /*((d-kumin)/(kumax-kumin)) */ ;
-    }
-  }
-  List_Delete(Listint);
-
-  // 2nd and 4th gen
-  List_T *List1 = List_Create(List_Nbr(List), 1, sizeof(double));
-  List_T *List2 = List_Create(List_Nbr(List), 1, sizeof(double));
-  for(int i = 0; i < List_Nbr(List); i++) {
-    List_Read(List, i, &ListOfDouble_L);
-    List_Add(List1, List_Pointer(ListOfDouble_L, 0));
-    List_Add(List2, List_Pointer(ListOfDouble_L, List_Nbr(ListOfDouble_L) - 1));
-  }
-
-  Listint = ListOfDouble2ListOfInt(List1);
-  if(recognize_seg(MSH_SEGM_NURBS, Listint, &Loop[1])) {
-  }
-  else {
-    Loop[1] = NEWREG();
-    Curve *c = Create_Curve(Loop[1], MSH_SEGM_NURBS, Order2, Listint, NULL, 
-			    -1, -1, kumin, kumax);
-    Tree_Add(THEM->Curves, &c);
-    CreateReversedCurve(c);
-    c->k = (float *)malloc(4 * List_Nbr(kv) * sizeof(float));
-    for(int i = 0; i < List_Nbr(kv); i++) {
-      double d;
-      List_Read(kv, i, &d);
-      c->k[i] = (float)d /*((d-kvmin)/(kvmax-kvmin)) */ ;
-    }
-  }
-  List_Delete(Listint);
-
-  Listint = ListOfDouble2ListOfInt(List2);
-  if(recognize_seg(MSH_SEGM_NURBS, Listint, &Loop[3])) {
-  }
-  else {
-    Loop[3] = NEWREG();
-    Curve *c = Create_Curve(Loop[3], MSH_SEGM_NURBS, Order2, Listint, NULL,
-			    -1, -1, kumin, kumax);
-    Tree_Add(THEM->Curves, &c);
-    CreateReversedCurve(c);
-    c->k = (float *)malloc(4 * List_Nbr(kv) * sizeof(float));
-    for(int i = 0; i < List_Nbr(kv); i++) {
-      double d;
-      List_Read(kv, i, &d);
-      c->k[i] = (float)d /*((d-kvmin)/(kvmax-kvmin)) */ ;
-    }
-  }
-  List_Delete(Listint);
-  List_Delete(List1);
-  List_Delete(List2);
-
-  Listint = List_Create(10, 10, sizeof(int));
-  int l0 = -Loop[0];
-  List_Add(Listint, &l0);
-  List_Add(Listint, &Loop[1]);
-  List_Add(Listint, &Loop[2]);
-  int l3 = -Loop[3];
-  List_Add(Listint, &l3);
-
-  int topnew = NEWREG();
-  CreateNurbsSurfaceSupport(topnew, Order1, Order2, List, ku, kv);
-
-  int il = NEWREG();
-  SurfaceLoop *l = Create_SurfaceLoop(il, Listint);
-  Tree_Add(THEM->SurfaceLoops, &l);
-  List_Reset(Listint);
-  List_Add(Listint, &il);
-
-  Surface *s = Create_Surface(NEWREG(), MSH_SURF_TRIMMED);
-  setSurfaceGeneratrices(s, Listint);
-  s->Support = s;
-  End_Surface(s);
-  Tree_Add(THEM->Surfaces, &s);
-
-  List_Delete(Listint);
-  List_Delete(ListCP);
-}
-
diff --git a/Mesh/SecondOrder.h b/Mesh/SecondOrder.h
new file mode 100644
index 0000000000..5f249e888b
--- /dev/null
+++ b/Mesh/SecondOrder.h
@@ -0,0 +1,26 @@
+#ifndef _SECOND_ORDER_H_
+#define _SECOND_ORDER_H_
+
+// Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+// 
+// Please report all bugs and problems to <gmsh@geuz.org>.
+
+void Degre1();
+void Degre2(bool linear=true, bool incomplete=false);
+
+#endif
diff --git a/Mesh/Utils.cpp b/Mesh/Utils.cpp
index 4a1ededfc1..6ee7c7a85a 100644
--- a/Mesh/Utils.cpp
+++ b/Mesh/Utils.cpp
@@ -1,4 +1,4 @@
-// $Id: Utils.cpp,v 1.34 2006-08-26 15:13:22 remacle Exp $
+// $Id: Utils.cpp,v 1.35 2006-11-25 16:52:44 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -24,11 +24,10 @@
 //
 
 #include "Gmsh.h"
-#include "Numeric.h"
 #include "Geo.h"
-#include "CAD.h"
-#include "Mesh.h"
-#include "Interpolation.h"
+#include "GeoInterpolation.h"
+#include "Utils.h"
+#include "Numeric.h"
 #include "Context.h"
 
 #if defined(HAVE_GSL)
diff --git a/Mesh/Utils.h b/Mesh/Utils.h
index 31ea74d1cd..ed7a834415 100644
--- a/Mesh/Utils.h
+++ b/Mesh/Utils.h
@@ -20,9 +20,8 @@
 // 
 // Please report all bugs and problems to <gmsh@geuz.org>.
 
+#include "Geo.h"
 #include "List.h"
-#include "Vertex.h"
-#include "Mesh.h"
 
 void invert_singular_matrix3x3(double MM[3][3], double II[3][3]);
 void direction (Vertex * v1, Vertex * v2, double d[3]);
@@ -38,6 +37,12 @@ int Oriente (List_T * cu, double n[3]);
 double angle_3p (Vertex * V, Vertex * P1, Vertex * P2);
 double angle_plan (Vertex * V, Vertex * P1, Vertex * P2, double n[3]);
 double angle_3pts (Vertex * a, Vertex * b, Vertex * c);
+
+typedef struct{
+  int Num;
+  double t, lc, p;
+}IntPoint;
+
 double trapeze (IntPoint * P1, IntPoint * P2);
 void RecursiveIntegration (IntPoint * from, IntPoint * to, double (*f) (double X),
                            List_T * pPoints, double Prec, int *depth);
diff --git a/Mesh/Vertex.cpp b/Mesh/Vertex.cpp
deleted file mode 100644
index 50e1129bec..0000000000
--- a/Mesh/Vertex.cpp
+++ /dev/null
@@ -1,186 +0,0 @@
-// $Id: Vertex.cpp,v 1.31 2006-11-25 02:47:40 geuzaine Exp $
-//
-// Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-// USA.
-// 
-// Please report all bugs and problems to <gmsh@geuz.org>.
-
-#include "Gmsh.h"
-#include "Numeric.h"
-#include "Vertex.h"
-#include "Mesh.h"
-#include "Context.h"
-
-extern Context_T CTX;
-extern Mesh *THEM;
-
-Vertex::Vertex()
-{
-  Frozen = 0;
-  Visible = 1;
-  Degree = 1;
-  Pos.X = 0.0;
-  Pos.Y = 0.0;
-  Pos.Z = 0.0;
-  w = 1.0;
-  lc = 1.0;
-  Mov = NULL;
-  ListSurf = NULL;
-  ListCurves = NULL;
-}
-
-Vertex::Vertex(double X, double Y, double Z, double l, double W)
-{
-  Frozen = 0;
-  Visible = 1;
-  Degree = 1;
-  Pos.X = X;
-  Pos.Y = Y;
-  Pos.Z = Z;
-  w = W;
-  lc = l;
-  Mov = NULL;
-  ListSurf = NULL;
-  ListCurves = NULL;
-}
-
-void Vertex::norme()
-{
-  double d = sqrt(Pos.X * Pos.X + Pos.Y * Pos.Y + Pos.Z * Pos.Z);
-  if(d == 0.0)
-    return;
-  Pos.X /= d;
-  Pos.Y /= d;
-  Pos.Z /= d;
-}
-
-
-Vertex Vertex::operator +(const Vertex & other)
-{
-  return Vertex(Pos.X + other.Pos.X, Pos.Y +
-                other.Pos.Y, Pos.Z + other.Pos.Z, lc, w);
-}
-
-Vertex Vertex::operator -(const Vertex & other)
-{
-  return Vertex(Pos.X - other.Pos.X, Pos.Y -
-                other.Pos.Y, Pos.Z - other.Pos.Z, lc, w);
-}
-
-Vertex Vertex::operator /(double d)
-{
-  return Vertex(Pos.X / d, Pos.Y / d, Pos.Z / d, lc, w);
-}
-
-Vertex Vertex::operator *(double d)
-{
-  return Vertex(Pos.X * d, Pos.Y * d, Pos.Z * d, lc, w);
-}
-
-Vertex Vertex::operator %(Vertex & autre)
-{       // cross product
-  return Vertex(Pos.Y * autre.Pos.Z - Pos.Z * autre.Pos.Y,
-                -(Pos.X * autre.Pos.Z - Pos.Z * autre.Pos.X),
-                Pos.X * autre.Pos.Y - Pos.Y * autre.Pos.X, lc, w);
-}
-
-double Vertex::operator *(const Vertex & other)
-{
-  return Pos.X * other.Pos.X + Pos.Y * other.Pos.Y + Pos.Z * other.Pos.Z;
-}
-
-Vertex *Create_Vertex(int Num, double X, double Y, double Z, double lc,
-                      double u)
-{
-  Vertex *pV;
-
-  pV = new Vertex(X, Y, Z, lc);
-  pV->w = 1.0;
-  pV->Num = Num;
-  THEM->MaxPointNum = IMAX(THEM->MaxPointNum, Num);
-  pV->u = u;
-  return pV;
-}
-
-void Delete_Vertex(Vertex * pV)
-{
-  if(pV) {
-    List_Delete(pV->ListSurf);
-    List_Delete(pV->ListCurves);
-    delete pV;
-  }
-}
-
-void Free_Vertex(void *a, void *b)
-{
-  Vertex *v = *(Vertex **) a;
-  if(v) {
-    Delete_Vertex(v);
-    v = NULL;
-  }
-}
-
-int compareVertex(const void *a, const void *b)
-{
-  int i, j;
-  Vertex **q, **w;
-
-  q = (Vertex **) a;
-  w = (Vertex **) b;
-  i = abs((*q)->Num);
-  j = abs((*w)->Num);
-  return (i - j);
-}
-
-int comparePosition(const void *a, const void *b)
-{
-  int i, j;
-  Vertex **q, **w;
-  // TOLERANCE ! WARNING WARNING
-  double eps = 1.e-6 * CTX.lc; 
-  // the above tol was changed in 1.61 (before 1.61, it was set to
-  // double eps = 1.e-10 * CTX.lc;
-
-  q = (Vertex **) a;
-  w = (Vertex **) b;
-  i = ((*q)->Num);
-  j = ((*w)->Num);
-
-  if((*q)->Pos.X - (*w)->Pos.X > eps)
-    return (1);
-  if((*q)->Pos.X - (*w)->Pos.X < -eps)
-    return (-1);
-  if((*q)->Pos.Y - (*w)->Pos.Y > eps)
-    return (1);
-  if((*q)->Pos.Y - (*w)->Pos.Y < -eps)
-    return (-1);
-  if((*q)->Pos.Z - (*w)->Pos.Z > eps)
-    return (1);
-  if((*q)->Pos.Z - (*w)->Pos.Z < -eps)
-    return (-1);
-
-  if(i != j) {
-    /*
-     *w = *q;
-     printf("Les points %d et %d sont a la meme position\n",i,j);
-     printf("%12.5E %12.5E %12.5E\n",(*w)->Pos.X,(*w)->Pos.Y,(*w)->Pos.Z);
-     printf("%12.5E %12.5E %12.5E\n",(*q)->Pos.X,(*q)->Pos.Y,(*q)->Pos.Z);
-     */
-  }
-  return 0;
-
-}
diff --git a/Mesh/Vertex.h b/Mesh/Vertex.h
deleted file mode 100644
index 3a98170caa..0000000000
--- a/Mesh/Vertex.h
+++ /dev/null
@@ -1,60 +0,0 @@
-#ifndef _VERTEX_H_
-#define _VERTEX_H_
-
-// Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-// USA.
-// 
-// Please report all bugs and problems to <gmsh@geuz.org>.
-
-#include "List.h"
-
-struct Coord{
-  double X,Y,Z;
-};
-
-class Vertex {
-  public :
-  int     Num;
-  char    Visible, Degree;
-  int     Frozen;
-  double  lc,u,us[3],w;
-  Coord   Pos;
-  Coord  *Mov;
-  Coord   Freeze;
-  List_T *ListSurf;
-  List_T *ListCurves;
-  List_T *Extruded_Points;
-  Vertex ();
-  Vertex (double x,double y,double z =0.0, double lc = 1.0, double w = 1.0);
-  Vertex operator + ( const Vertex &other);
-  Vertex operator - ( const Vertex &other);
-  double operator * ( const Vertex &other);
-  Vertex operator * ( double d );
-  Vertex operator / ( double d );
-  Vertex operator % (Vertex &autre); // cross product
-  void norme();
-};
-
-int compareVertex (const void *a, const void *b);
-int comparePosition (const void *a, const void *b);
-
-Vertex *Create_Vertex (int Num, double X, double Y, double Z, double lc, double u);
-void Delete_Vertex (Vertex *pV);
-void Free_Vertex (void *a, void *b);
-void Free_ExtrudedPoints(List_T* Extruded_Points);
-
-#endif
diff --git a/Mesh/meshGEdge.cpp b/Mesh/meshGEdge.cpp
index e805dd4fbb..06473a926b 100644
--- a/Mesh/meshGEdge.cpp
+++ b/Mesh/meshGEdge.cpp
@@ -1,4 +1,4 @@
-// $Id: meshGEdge.cpp,v 1.17 2006-11-21 23:52:59 remacle Exp $
+// $Id: meshGEdge.cpp,v 1.18 2006-11-25 16:52:44 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -19,12 +19,12 @@
 // 
 // Please report all bugs and problems to <gmsh@geuz.org>.
 
+#include "Gmsh.h"
 #include "meshGEdge.h"
 #include "GEdge.h"
 #include "GFace.h"
-#include "Gmsh.h"
 #include "Utils.h"
-#include "Mesh.h"
+#include "BackgroundMesh.h"
 #include "Context.h"
 #include "Message.h"
 
diff --git a/Mesh/meshGFace.cpp b/Mesh/meshGFace.cpp
index 82deee9025..28b0f293d0 100644
--- a/Mesh/meshGFace.cpp
+++ b/Mesh/meshGFace.cpp
@@ -1,4 +1,4 @@
-// $Id: meshGFace.cpp,v 1.25 2006-11-25 02:47:40 geuzaine Exp $
+// $Id: meshGFace.cpp,v 1.26 2006-11-25 16:52:44 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -20,6 +20,8 @@
 // Please report all bugs and problems to <gmsh@geuz.org>.
 
 #include "meshGFace.h"
+#include "DivideAndConquer.h"
+#include "BackgroundMesh.h"
 #include "GVertex.h"
 #include "GEdge.h"
 #include "GFace.h"
diff --git a/Parser/Gmsh.l b/Parser/Gmsh.l
index 770f5cb1a5..2b76b55c95 100644
--- a/Parser/Gmsh.l
+++ b/Parser/Gmsh.l
@@ -1,5 +1,5 @@
 %{
-// $Id: Gmsh.l,v 1.79 2006-11-22 15:01:28 geuzaine Exp $
+// $Id: Gmsh.l,v 1.80 2006-11-25 16:52:44 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -28,7 +28,6 @@
 #include "Gmsh.h"
 #include "Numeric.h"
 #include "Geo.h"
-#include "CAD.h"
 #include "Gmsh.tab.hpp"
 
 char yyname[256] = "";
diff --git a/Parser/Gmsh.tab.cpp b/Parser/Gmsh.tab.cpp
index f8c2295b93..ff0d604344 100644
--- a/Parser/Gmsh.tab.cpp
+++ b/Parser/Gmsh.tab.cpp
@@ -126,7 +126,7 @@
 
 #line 1 "Gmsh.y"
 
-// $Id: Gmsh.tab.cpp,v 1.278 2006-11-25 03:30:03 geuzaine Exp $
+// $Id: Gmsh.tab.cpp,v 1.279 2006-11-25 16:52:44 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -155,12 +155,10 @@
 #include "Numeric.h"
 #include "Context.h"
 #include "Geo.h"
+#include "GeoInterpolation.h"
 #include "GeoUtils.h"
-#include "Nurbs.h"
-#include "CAD.h"
-#include "Mesh.h"
+#include "Generator.h"
 #include "Draw.h"
-#include "Create.h"
 #include "Views.h"
 #include "Options.h"
 #include "Colors.h"
@@ -172,13 +170,6 @@
 #include "OS.h"
 #include "CreateFile.h"
 
-#include "GModel.h"
-#include "gmshVertex.h"
-#include "gmshEdge.h"
-#include "gmshFace.h"
-#include "gmshRegion.h"
-extern GModel *GMODEL;
-
 Tree_T *Symbol_T = NULL;
 
 extern Context_T CTX;
@@ -206,7 +197,7 @@ void skip_until(char *skip, char *until);
 int PrintListOfDouble(char *format, List_T *list, char *buffer);
 int CheckViewErrorFlags(Post_View *v);
 
-#line 83 "Gmsh.y"
+#line 74 "Gmsh.y"
 typedef union {
   char *c;
   int i;
@@ -519,40 +510,40 @@ static const short yyrhs[] = {   143,
 
 #if YYDEBUG != 0
 static const short yyrline[] = { 0,
-   148,   150,   155,   157,   160,   162,   163,   164,   165,   166,
-   167,   168,   169,   170,   171,   172,   173,   174,   175,   178,
-   183,   189,   195,   210,   223,   251,   259,   268,   276,   277,
-   278,   279,   280,   281,   284,   287,   291,   294,   298,   489,
-   507,   517,   523,   530,   538,   544,   550,   557,   565,   571,
-   579,   584,   588,   597,   599,   600,   601,   602,   605,   607,
-   610,   645,   684,   738,   755,   773,   784,   803,   817,   834,
-   860,   887,   901,   918,   932,   949,   969,   992,  1002,  1017,
-  1037,  1053,  1060,  1079,  1097,  1115,  1133,  1159,  1177,  1203,
-  1223,  1247,  1271,  1297,  1314,  1321,  1340,  1359,  1398,  1423,
-  1442,  1461,  1477,  1497,  1514,  1531,  1551,  1557,  1562,  1567,
-  1574,  1576,  1577,  1580,  1585,  1589,  1605,  1621,  1637,  1657,
-  1672,  1678,  1684,  1695,  1705,  1715,  1729,  1747,  1761,  1768,
-  1774,  1783,  1796,  1842,  1857,  1868,  1888,  1898,  1920,  1924,
-  1929,  1934,  1944,  1961,  1977,  2003,  2030,  2062,  2069,  2074,
-  2080,  2084,  2092,  2101,  2109,  2117,  2122,  2130,  2135,  2143,
-  2148,  2158,  2165,  2172,  2179,  2186,  2193,  2200,  2207,  2214,
-  2221,  2226,  2233,  2238,  2245,  2250,  2257,  2262,  2269,  2274,
-  2281,  2286,  2293,  2298,  2305,  2310,  2317,  2322,  2332,  2336,
-  2341,  2368,  2392,  2400,  2419,  2437,  2455,  2484,  2519,  2546,
-  2573,  2587,  2605,  2612,  2618,  2621,  2627,  2632,  2641,  2643,
-  2644,  2645,  2646,  2647,  2648,  2649,  2650,  2657,  2658,  2659,
-  2660,  2661,  2662,  2663,  2664,  2665,  2666,  2667,  2668,  2669,
-  2670,  2671,  2672,  2673,  2674,  2675,  2676,  2677,  2678,  2679,
-  2680,  2681,  2682,  2683,  2684,  2685,  2686,  2687,  2688,  2690,
-  2691,  2692,  2693,  2694,  2695,  2696,  2697,  2698,  2699,  2700,
-  2701,  2702,  2703,  2704,  2705,  2706,  2707,  2708,  2709,  2710,
-  2715,  2720,  2721,  2722,  2723,  2724,  2725,  2729,  2745,  2760,
-  2780,  2794,  2807,  2830,  2848,  2866,  2884,  2902,  2909,  2914,
-  2918,  2922,  2926,  2932,  2937,  2941,  2945,  2951,  2955,  2959,
-  2965,  2971,  2978,  2984,  2988,  2993,  2997,  3008,  3015,  3026,
-  3046,  3056,  3066,  3076,  3093,  3112,  3136,  3164,  3170,  3174,
-  3178,  3190,  3195,  3207,  3214,  3235,  3240,  3254,  3260,  3266,
-  3271,  3279,  3287,  3301,  3315,  3319,  3338,  3360
+   139,   141,   146,   148,   151,   153,   154,   155,   156,   157,
+   158,   159,   160,   161,   162,   163,   164,   165,   166,   169,
+   174,   180,   186,   201,   214,   242,   250,   259,   267,   268,
+   269,   270,   271,   272,   275,   278,   282,   285,   289,   480,
+   498,   508,   514,   521,   529,   535,   541,   548,   556,   562,
+   570,   575,   579,   588,   590,   591,   592,   593,   596,   598,
+   601,   636,   675,   729,   746,   764,   775,   794,   808,   825,
+   851,   878,   892,   909,   923,   940,   960,   983,   993,  1008,
+  1028,  1044,  1051,  1070,  1088,  1106,  1124,  1150,  1168,  1194,
+  1214,  1238,  1262,  1288,  1305,  1312,  1331,  1350,  1389,  1414,
+  1433,  1452,  1468,  1488,  1505,  1522,  1542,  1548,  1553,  1558,
+  1565,  1567,  1568,  1571,  1576,  1580,  1596,  1612,  1628,  1648,
+  1663,  1669,  1675,  1686,  1696,  1706,  1720,  1738,  1752,  1759,
+  1765,  1774,  1787,  1833,  1848,  1859,  1879,  1889,  1911,  1915,
+  1920,  1925,  1935,  1952,  1968,  1994,  2021,  2053,  2060,  2065,
+  2071,  2075,  2083,  2092,  2100,  2108,  2113,  2121,  2126,  2134,
+  2139,  2149,  2156,  2163,  2170,  2177,  2184,  2191,  2198,  2205,
+  2212,  2217,  2224,  2229,  2236,  2241,  2248,  2253,  2260,  2265,
+  2272,  2277,  2284,  2289,  2296,  2301,  2308,  2313,  2323,  2327,
+  2332,  2359,  2383,  2391,  2410,  2428,  2446,  2475,  2510,  2537,
+  2564,  2578,  2596,  2603,  2609,  2612,  2618,  2623,  2632,  2634,
+  2635,  2636,  2637,  2638,  2639,  2640,  2641,  2648,  2649,  2650,
+  2651,  2652,  2653,  2654,  2655,  2656,  2657,  2658,  2659,  2660,
+  2661,  2662,  2663,  2664,  2665,  2666,  2667,  2668,  2669,  2670,
+  2671,  2672,  2673,  2674,  2675,  2676,  2677,  2678,  2679,  2681,
+  2682,  2683,  2684,  2685,  2686,  2687,  2688,  2689,  2690,  2691,
+  2692,  2693,  2694,  2695,  2696,  2697,  2698,  2699,  2700,  2701,
+  2706,  2711,  2712,  2713,  2714,  2715,  2716,  2720,  2736,  2751,
+  2771,  2785,  2798,  2821,  2839,  2857,  2875,  2893,  2900,  2905,
+  2909,  2913,  2917,  2923,  2928,  2932,  2936,  2942,  2946,  2950,
+  2956,  2962,  2969,  2975,  2979,  2984,  2988,  2999,  3006,  3017,
+  3037,  3047,  3057,  3067,  3084,  3103,  3127,  3155,  3161,  3165,
+  3169,  3181,  3186,  3198,  3205,  3226,  3231,  3245,  3251,  3257,
+  3262,  3270,  3278,  3292,  3306,  3310,  3329,  3351
 };
 #endif
 
@@ -2801,90 +2792,90 @@ yyreduce:
   switch (yyn) {
 
 case 2:
-#line 150 "Gmsh.y"
+#line 141 "Gmsh.y"
 { yyerrok; return 1; ;
     break;}
 case 5:
-#line 161 "Gmsh.y"
+#line 152 "Gmsh.y"
 { return 1; ;
     break;}
 case 6:
-#line 162 "Gmsh.y"
+#line 153 "Gmsh.y"
 { return 1; ;
     break;}
 case 7:
-#line 163 "Gmsh.y"
+#line 154 "Gmsh.y"
 { return 1; ;
     break;}
 case 8:
-#line 164 "Gmsh.y"
+#line 155 "Gmsh.y"
 { return 1; ;
     break;}
 case 9:
-#line 165 "Gmsh.y"
+#line 156 "Gmsh.y"
 { List_Delete(yyvsp[0].l); return 1; ;
     break;}
 case 10:
-#line 166 "Gmsh.y"
+#line 157 "Gmsh.y"
 { List_Delete(yyvsp[0].l); return 1; ;
     break;}
 case 11:
-#line 167 "Gmsh.y"
+#line 158 "Gmsh.y"
 { return 1; ;
     break;}
 case 12:
-#line 168 "Gmsh.y"
+#line 159 "Gmsh.y"
 { return 1; ;
     break;}
 case 13:
-#line 169 "Gmsh.y"
+#line 160 "Gmsh.y"
 { return 1; ;
     break;}
 case 14:
-#line 170 "Gmsh.y"
+#line 161 "Gmsh.y"
 { List_Delete(yyvsp[0].l); return 1; ;
     break;}
 case 15:
-#line 171 "Gmsh.y"
+#line 162 "Gmsh.y"
 { return 1; ;
     break;}
 case 16:
-#line 172 "Gmsh.y"
+#line 163 "Gmsh.y"
 { return 1; ;
     break;}
 case 17:
-#line 173 "Gmsh.y"
+#line 164 "Gmsh.y"
 { return 1; ;
     break;}
 case 18:
-#line 174 "Gmsh.y"
+#line 165 "Gmsh.y"
 { return 1; ;
     break;}
 case 19:
-#line 175 "Gmsh.y"
+#line 166 "Gmsh.y"
 { return 1; ;
     break;}
 case 20:
-#line 180 "Gmsh.y"
+#line 171 "Gmsh.y"
 {
       yyval.c = "w";
     ;
     break;}
 case 21:
-#line 184 "Gmsh.y"
+#line 175 "Gmsh.y"
 {
       yyval.c = "a";
     ;
     break;}
 case 22:
-#line 191 "Gmsh.y"
+#line 182 "Gmsh.y"
 {
       Msg(DIRECT, yyvsp[-2].c);
       Free(yyvsp[-2].c);
     ;
     break;}
 case 23:
-#line 196 "Gmsh.y"
+#line 187 "Gmsh.y"
 {
       char tmpstring[1024];
       FixRelativePath(yyvsp[-1].c, tmpstring);
@@ -2901,7 +2892,7 @@ case 23:
     ;
     break;}
 case 24:
-#line 211 "Gmsh.y"
+#line 202 "Gmsh.y"
 {
       char tmpstring[1024];
       int i = PrintListOfDouble(yyvsp[-4].c, yyvsp[-2].l, tmpstring);
@@ -2916,7 +2907,7 @@ case 24:
     ;
     break;}
 case 25:
-#line 224 "Gmsh.y"
+#line 215 "Gmsh.y"
 {
       char tmpstring[1024];
       int i = PrintListOfDouble(yyvsp[-6].c, yyvsp[-4].l, tmpstring);
@@ -2942,7 +2933,7 @@ case 25:
     ;
     break;}
 case 26:
-#line 253 "Gmsh.y"
+#line 244 "Gmsh.y"
 { 
       if(!strcmp(yyvsp[-5].c, "View") && !CheckViewErrorFlags(View)){
 	EndView(View, 0, yyname, yyvsp[-4].c);
@@ -2951,7 +2942,7 @@ case 26:
     ;
     break;}
 case 27:
-#line 260 "Gmsh.y"
+#line 251 "Gmsh.y"
 {
       if(!strcmp(yyvsp[-7].c, "View") && !CheckViewErrorFlags(View)){
 	EndView(View, 0, yyname, yyvsp[-6].c);
@@ -2960,7 +2951,7 @@ case 27:
     ;
     break;}
 case 28:
-#line 270 "Gmsh.y"
+#line 261 "Gmsh.y"
 {
       View = BeginView(1); 
       for(int i = 0; i < VIEW_NB_ELEMENT_TYPES; i++){
@@ -2969,23 +2960,23 @@ case 28:
     ;
     break;}
 case 35:
-#line 286 "Gmsh.y"
+#line 277 "Gmsh.y"
 { ViewCoord[ViewCoordIdx] = yyvsp[0].d; ViewCoordIdx++; ;
     break;}
 case 36:
-#line 288 "Gmsh.y"
+#line 279 "Gmsh.y"
 { ViewCoord[ViewCoordIdx] = yyvsp[0].d; ViewCoordIdx++; ;
     break;}
 case 37:
-#line 293 "Gmsh.y"
+#line 284 "Gmsh.y"
 { if(ViewValueList) List_Add(ViewValueList, &yyvsp[0].d); ;
     break;}
 case 38:
-#line 295 "Gmsh.y"
+#line 286 "Gmsh.y"
 { if(ViewValueList) List_Add(ViewValueList, &yyvsp[0].d); ;
     break;}
 case 39:
-#line 300 "Gmsh.y"
+#line 291 "Gmsh.y"
 {
       if(!strcmp(yyvsp[0].c, "SP")){
 	ViewElementIdx = 0; ViewNumNodes = 1; ViewNumComp = 1;
@@ -3177,7 +3168,7 @@ case 39:
     ;
     break;}
 case 40:
-#line 490 "Gmsh.y"
+#line 481 "Gmsh.y"
 {
       if(ViewValueList){
 	if(ViewCoordIdx != 3 * ViewNumNodes){
@@ -3197,7 +3188,7 @@ case 40:
     ;
     break;}
 case 41:
-#line 508 "Gmsh.y"
+#line 499 "Gmsh.y"
 {
       if(ViewValueList){  
 	if((List_Nbr(ViewValueList) - ViewNumListTmp) % (ViewNumComp * ViewNumNodes)) 
@@ -3207,21 +3198,21 @@ case 41:
     ;
     break;}
 case 42:
-#line 519 "Gmsh.y"
+#line 510 "Gmsh.y"
 { 
       for(int i = 0; i < (int)strlen(yyvsp[0].c)+1; i++) List_Add(View->T2C, &yyvsp[0].c[i]); 
       Free(yyvsp[0].c);
     ;
     break;}
 case 43:
-#line 524 "Gmsh.y"
+#line 515 "Gmsh.y"
 { 
       for(int i = 0; i < (int)strlen(yyvsp[0].c)+1; i++) List_Add(View->T2C, &yyvsp[0].c[i]); 
       Free(yyvsp[0].c);
     ;
     break;}
 case 44:
-#line 532 "Gmsh.y"
+#line 523 "Gmsh.y"
 { 
       List_Add(View->T2D, &yyvsp[-5].d); List_Add(View->T2D, &yyvsp[-3].d);
       List_Add(View->T2D, &yyvsp[-1].d); 
@@ -3230,27 +3221,27 @@ case 44:
     ;
     break;}
 case 45:
-#line 539 "Gmsh.y"
+#line 530 "Gmsh.y"
 {
       View->NbT2++;
     ;
     break;}
 case 46:
-#line 546 "Gmsh.y"
+#line 537 "Gmsh.y"
 { 
       for(int i = 0; i < (int)strlen(yyvsp[0].c)+1; i++) List_Add(View->T3C, &yyvsp[0].c[i]); 
       Free(yyvsp[0].c);
     ;
     break;}
 case 47:
-#line 551 "Gmsh.y"
+#line 542 "Gmsh.y"
 { 
       for(int i = 0; i < (int)strlen(yyvsp[0].c)+1; i++) List_Add(View->T3C, &yyvsp[0].c[i]); 
       Free(yyvsp[0].c);
     ;
     break;}
 case 48:
-#line 559 "Gmsh.y"
+#line 550 "Gmsh.y"
 { 
       List_Add(View->T3D, &yyvsp[-7].d); List_Add(View->T3D, &yyvsp[-5].d);
       List_Add(View->T3D, &yyvsp[-3].d); List_Add(View->T3D, &yyvsp[-1].d); 
@@ -3259,64 +3250,64 @@ case 48:
     ;
     break;}
 case 49:
-#line 566 "Gmsh.y"
+#line 557 "Gmsh.y"
 {
       View->NbT3++;
     ;
     break;}
 case 50:
-#line 574 "Gmsh.y"
+#line 565 "Gmsh.y"
 {
       View->adaptive = new Adaptive_Post_View(View, yyvsp[-5].l, yyvsp[-2].l);
     ;
     break;}
 case 51:
-#line 581 "Gmsh.y"
+#line 572 "Gmsh.y"
 {
       ViewValueList = View->Time;
     ;
     break;}
 case 52:
-#line 585 "Gmsh.y"
+#line 576 "Gmsh.y"
 {
     ;
     break;}
 case 53:
-#line 590 "Gmsh.y"
+#line 581 "Gmsh.y"
 {
       (*View->Grains) [(int)yyvsp[-3].d] = yyvsp[-1].l;
     ;
     break;}
 case 54:
-#line 598 "Gmsh.y"
+#line 589 "Gmsh.y"
 { yyval.i = 0; ;
     break;}
 case 55:
-#line 599 "Gmsh.y"
+#line 590 "Gmsh.y"
 { yyval.i = 1; ;
     break;}
 case 56:
-#line 600 "Gmsh.y"
+#line 591 "Gmsh.y"
 { yyval.i = 2; ;
     break;}
 case 57:
-#line 601 "Gmsh.y"
+#line 592 "Gmsh.y"
 { yyval.i = 3; ;
     break;}
 case 58:
-#line 602 "Gmsh.y"
+#line 593 "Gmsh.y"
 { yyval.i = 4; ;
     break;}
 case 59:
-#line 606 "Gmsh.y"
+#line 597 "Gmsh.y"
 { yyval.i = 1; ;
     break;}
 case 60:
-#line 607 "Gmsh.y"
+#line 598 "Gmsh.y"
 { yyval.i = -1; ;
     break;}
 case 61:
-#line 615 "Gmsh.y"
+#line 606 "Gmsh.y"
 {
       Symbol TheSymbol;
       TheSymbol.Name = yyvsp[-3].c;
@@ -3349,7 +3340,7 @@ case 61:
     ;
     break;}
 case 62:
-#line 646 "Gmsh.y"
+#line 637 "Gmsh.y"
 {
       Symbol TheSymbol;
       TheSymbol.Name = yyvsp[-6].c;
@@ -3390,7 +3381,7 @@ case 62:
     ;
     break;}
 case 63:
-#line 685 "Gmsh.y"
+#line 676 "Gmsh.y"
 {
       if(List_Nbr(yyvsp[-5].l) != List_Nbr(yyvsp[-1].l)){
 	yymsg(GERROR, "Incompatible array dimensions in affectation");
@@ -3446,7 +3437,7 @@ case 63:
     ;
     break;}
 case 64:
-#line 739 "Gmsh.y"
+#line 730 "Gmsh.y"
 {
       Symbol TheSymbol;
       TheSymbol.Name = yyvsp[-5].c;
@@ -3465,7 +3456,7 @@ case 64:
     ;
     break;}
 case 65:
-#line 756 "Gmsh.y"
+#line 747 "Gmsh.y"
 {
       // appends to the list
       Symbol TheSymbol;
@@ -3485,7 +3476,7 @@ case 65:
     ;
     break;}
 case 66:
-#line 774 "Gmsh.y"
+#line 765 "Gmsh.y"
 {
       Symbol TheSymbol;
       TheSymbol.Name = yyvsp[-2].c;
@@ -3498,7 +3489,7 @@ case 66:
     ;
     break;}
 case 67:
-#line 785 "Gmsh.y"
+#line 776 "Gmsh.y"
 {
       Symbol TheSymbol;
       TheSymbol.Name = yyvsp[-5].c;
@@ -3516,7 +3507,7 @@ case 67:
     ;
     break;}
 case 68:
-#line 804 "Gmsh.y"
+#line 795 "Gmsh.y"
 { 
       char* (*pStrOpt)(int num, int action, char *value);
       StringXString *pStrCat;
@@ -3532,7 +3523,7 @@ case 68:
     ;
     break;}
 case 69:
-#line 818 "Gmsh.y"
+#line 809 "Gmsh.y"
 { 
       char* (*pStrOpt)(int num, int action, char *value);
       StringXString *pStrCat;
@@ -3548,7 +3539,7 @@ case 69:
     ;
     break;}
 case 70:
-#line 835 "Gmsh.y"
+#line 826 "Gmsh.y"
 {
       double (*pNumOpt)(int num, int action, double value);
       StringXNumber *pNumCat;
@@ -3576,7 +3567,7 @@ case 70:
     ;
     break;}
 case 71:
-#line 861 "Gmsh.y"
+#line 852 "Gmsh.y"
 {
       double (*pNumOpt)(int num, int action, double value);
       StringXNumber *pNumCat;
@@ -3605,7 +3596,7 @@ case 71:
     ;
     break;}
 case 72:
-#line 888 "Gmsh.y"
+#line 879 "Gmsh.y"
 {
       double (*pNumOpt)(int num, int action, double value);
       StringXNumber *pNumCat;
@@ -3621,7 +3612,7 @@ case 72:
     ;
     break;}
 case 73:
-#line 902 "Gmsh.y"
+#line 893 "Gmsh.y"
 {
       double (*pNumOpt)(int num, int action, double value);
       StringXNumber *pNumCat;
@@ -3637,7 +3628,7 @@ case 73:
     ;
     break;}
 case 74:
-#line 919 "Gmsh.y"
+#line 910 "Gmsh.y"
 {
       unsigned int (*pColOpt)(int num, int action, unsigned int value);
       StringXColor *pColCat;
@@ -3653,7 +3644,7 @@ case 74:
     ;
     break;}
 case 75:
-#line 933 "Gmsh.y"
+#line 924 "Gmsh.y"
 {
       unsigned int (*pColOpt)(int num, int action, unsigned int value);
       StringXColor *pColCat;
@@ -3669,7 +3660,7 @@ case 75:
     ;
     break;}
 case 76:
-#line 950 "Gmsh.y"
+#line 941 "Gmsh.y"
 {
       GmshColorTable *ct = Get_ColorTable(0);
       if(!ct)
@@ -3691,7 +3682,7 @@ case 76:
     ;
     break;}
 case 77:
-#line 970 "Gmsh.y"
+#line 961 "Gmsh.y"
 {
       GmshColorTable *ct = Get_ColorTable((int)yyvsp[-6].d);
       if(!ct)
@@ -3713,7 +3704,7 @@ case 77:
     ;
     break;}
 case 78:
-#line 993 "Gmsh.y"
+#line 984 "Gmsh.y"
 {
       try {
 	GMSH_PluginManager::instance()->setPluginOption(yyvsp[-6].c, yyvsp[-3].c, yyvsp[-1].d); 
@@ -3725,7 +3716,7 @@ case 78:
     ;
     break;}
 case 79:
-#line 1003 "Gmsh.y"
+#line 994 "Gmsh.y"
 {
       try {
 	GMSH_PluginManager::instance()->setPluginOption(yyvsp[-6].c, yyvsp[-3].c, yyvsp[-1].c); 
@@ -3737,7 +3728,7 @@ case 79:
     ;
     break;}
 case 80:
-#line 1022 "Gmsh.y"
+#line 1013 "Gmsh.y"
 {
       int num = (int)yyvsp[-4].d;
       if(FindPoint(num)){
@@ -3755,7 +3746,7 @@ case 80:
     ;
     break;}
 case 81:
-#line 1038 "Gmsh.y"
+#line 1029 "Gmsh.y"
 {
       int num = (int)yyvsp[-4].d;
       if(FindPhysicalGroup(num, MSH_PHYSICAL_POINT)){
@@ -3773,7 +3764,7 @@ case 81:
     ;
     break;}
 case 82:
-#line 1054 "Gmsh.y"
+#line 1045 "Gmsh.y"
 {
       yymsg(GERROR, "Attractors are deprecated");
       List_Delete(yyvsp[-9].l);
@@ -3782,7 +3773,7 @@ case 82:
     ;
     break;}
 case 83:
-#line 1061 "Gmsh.y"
+#line 1052 "Gmsh.y"
 {
       for(int i = 0; i < List_Nbr(yyvsp[-3].l); i++){
 	double d;
@@ -3800,7 +3791,7 @@ case 83:
     ;
     break;}
 case 84:
-#line 1080 "Gmsh.y"
+#line 1071 "Gmsh.y"
 {
       int num = (int)yyvsp[-4].d;
       if(FindCurve(num)){
@@ -3820,7 +3811,7 @@ case 84:
     ;
     break;}
 case 85:
-#line 1098 "Gmsh.y"
+#line 1089 "Gmsh.y"
 {
       int num = (int)yyvsp[-4].d;
       if(FindCurve(num)){
@@ -3840,7 +3831,7 @@ case 85:
     ;
     break;}
 case 86:
-#line 1116 "Gmsh.y"
+#line 1107 "Gmsh.y"
 {
       int num = (int)yyvsp[-4].d;
       if(FindCurve(num)){
@@ -3860,7 +3851,7 @@ case 86:
     ;
     break;}
 case 87:
-#line 1134 "Gmsh.y"
+#line 1125 "Gmsh.y"
 {
       int num = (int)yyvsp[-6].d;
       if(FindCurve(num)){
@@ -3888,7 +3879,7 @@ case 87:
     ;
     break;}
 case 88:
-#line 1160 "Gmsh.y"
+#line 1151 "Gmsh.y"
 {
       int num = (int)yyvsp[-4].d;
       if(FindCurve(num)){
@@ -3908,7 +3899,7 @@ case 88:
     ;
     break;}
 case 89:
-#line 1178 "Gmsh.y"
+#line 1169 "Gmsh.y"
 {
       int num = (int)yyvsp[-6].d;
       if(FindCurve(num)){
@@ -3936,7 +3927,7 @@ case 89:
     ;
     break;}
 case 90:
-#line 1205 "Gmsh.y"
+#line 1196 "Gmsh.y"
 {
       int num = (int)yyvsp[-14].d;
       if(FindCurve(num)){
@@ -3957,7 +3948,7 @@ case 90:
     ;
     break;}
 case 91:
-#line 1224 "Gmsh.y"
+#line 1215 "Gmsh.y"
 {
       int num = (int)yyvsp[-4].d;
       if(List_Nbr(yyvsp[-1].l) < 4){
@@ -3983,7 +3974,7 @@ case 91:
     ;
     break;}
 case 92:
-#line 1248 "Gmsh.y"
+#line 1239 "Gmsh.y"
 {
       int num = (int)yyvsp[-4].d;
       if(List_Nbr(yyvsp[-1].l) < 4){
@@ -4009,7 +4000,7 @@ case 92:
     ;
     break;}
 case 93:
-#line 1272 "Gmsh.y"
+#line 1263 "Gmsh.y"
 {
       int num = (int)yyvsp[-8].d;
       if(List_Nbr(yyvsp[-5].l) + (int)yyvsp[-1].d + 1 != List_Nbr(yyvsp[-3].l)){
@@ -4037,7 +4028,7 @@ case 93:
     ;
     break;}
 case 94:
-#line 1298 "Gmsh.y"
+#line 1289 "Gmsh.y"
 {
       int num = (int)yyvsp[-4].d;
       if(FindEdgeLoop(num)){
@@ -4056,7 +4047,7 @@ case 94:
     ;
     break;}
 case 95:
-#line 1315 "Gmsh.y"
+#line 1306 "Gmsh.y"
 {
       yymsg(GERROR, "Attractors are deprecated");
       List_Delete(yyvsp[-9].l);
@@ -4065,7 +4056,7 @@ case 95:
     ;
     break;}
 case 96:
-#line 1322 "Gmsh.y"
+#line 1313 "Gmsh.y"
 {
       int num = (int)yyvsp[-4].d;
       if(FindPhysicalGroup(num, MSH_PHYSICAL_LINE)){
@@ -4083,7 +4074,7 @@ case 96:
     ;
     break;}
 case 97:
-#line 1341 "Gmsh.y"
+#line 1332 "Gmsh.y"
 {
       int num = (int)yyvsp[-4].d;
       if(FindSurface(num)){
@@ -4104,7 +4095,7 @@ case 97:
     ;
     break;}
 case 98:
-#line 1360 "Gmsh.y"
+#line 1351 "Gmsh.y"
 {
       int num = (int)yyvsp[-4].d, type = 0;
       if(FindSurface(num)){
@@ -4145,7 +4136,7 @@ case 98:
     ;
     break;}
 case 99:
-#line 1399 "Gmsh.y"
+#line 1390 "Gmsh.y"
 {
       int num = (int)yyvsp[-8].d;
       Surface *support = FindSurface((int)yyvsp[-4].d);
@@ -4172,7 +4163,7 @@ case 99:
     ;
     break;}
 case 100:
-#line 1426 "Gmsh.y"
+#line 1417 "Gmsh.y"
 {
       int num = (int)yyvsp[-16].d;
       if(FindSurface(num)){
@@ -4191,7 +4182,7 @@ case 100:
     ;
     break;}
 case 101:
-#line 1445 "Gmsh.y"
+#line 1436 "Gmsh.y"
 {
       int num = (int)yyvsp[-16].d;
       if(FindSurface(num)){
@@ -4210,7 +4201,7 @@ case 101:
     ;
     break;}
 case 102:
-#line 1462 "Gmsh.y"
+#line 1453 "Gmsh.y"
 {
       int num = (int)yyvsp[-4].d;
       if(FindSurfaceLoop(num)){
@@ -4228,7 +4219,7 @@ case 102:
     ;
     break;}
 case 103:
-#line 1478 "Gmsh.y"
+#line 1469 "Gmsh.y"
 {
       int num = (int)yyvsp[-4].d;
       if(FindPhysicalGroup(num, MSH_PHYSICAL_SURFACE)){
@@ -4246,7 +4237,7 @@ case 103:
     ;
     break;}
 case 104:
-#line 1498 "Gmsh.y"
+#line 1489 "Gmsh.y"
 {
       int num = (int)yyvsp[-4].d;
       if(FindVolume(num)){
@@ -4265,7 +4256,7 @@ case 104:
     ;
     break;}
 case 105:
-#line 1515 "Gmsh.y"
+#line 1506 "Gmsh.y"
 {
       int num = (int)yyvsp[-4].d;
       if(FindVolume(num)){
@@ -4284,7 +4275,7 @@ case 105:
     ;
     break;}
 case 106:
-#line 1532 "Gmsh.y"
+#line 1523 "Gmsh.y"
 {
       int num = (int)yyvsp[-4].d;
       if(FindPhysicalGroup(num, MSH_PHYSICAL_VOLUME)){
@@ -4302,59 +4293,59 @@ case 106:
     ;
     break;}
 case 107:
-#line 1553 "Gmsh.y"
+#line 1544 "Gmsh.y"
 {
       TranslateShapes(yyvsp[-3].v[0], yyvsp[-3].v[1], yyvsp[-3].v[2], yyvsp[-1].l, 1);
       yyval.l = yyvsp[-1].l;
     ;
     break;}
 case 108:
-#line 1558 "Gmsh.y"
+#line 1549 "Gmsh.y"
 {
       RotateShapes(yyvsp[-8].v[0], yyvsp[-8].v[1], yyvsp[-8].v[2], yyvsp[-6].v[0], yyvsp[-6].v[1], yyvsp[-6].v[2], yyvsp[-4].d, yyvsp[-1].l, 1);
       yyval.l = yyvsp[-1].l;
     ;
     break;}
 case 109:
-#line 1563 "Gmsh.y"
+#line 1554 "Gmsh.y"
 {
       SymmetryShapes(yyvsp[-3].v[0], yyvsp[-3].v[1], yyvsp[-3].v[2], yyvsp[-3].v[3], yyvsp[-1].l, 1);
       yyval.l = yyvsp[-1].l;
     ;
     break;}
 case 110:
-#line 1568 "Gmsh.y"
+#line 1559 "Gmsh.y"
 {
       DilatShapes(yyvsp[-6].v[0], yyvsp[-6].v[1], yyvsp[-6].v[2], yyvsp[-4].d, yyvsp[-1].l, 1);
       yyval.l = yyvsp[-1].l;
     ;
     break;}
 case 111:
-#line 1575 "Gmsh.y"
+#line 1566 "Gmsh.y"
 { yyval.l = yyvsp[0].l; ;
     break;}
 case 112:
-#line 1576 "Gmsh.y"
+#line 1567 "Gmsh.y"
 { yyval.l = yyvsp[0].l; ;
     break;}
 case 113:
-#line 1577 "Gmsh.y"
+#line 1568 "Gmsh.y"
 { yyval.l = yyvsp[0].l; ;
     break;}
 case 114:
-#line 1582 "Gmsh.y"
+#line 1573 "Gmsh.y"
 {
       yyval.l = List_Create(3, 3, sizeof(Shape));
     ;
     break;}
 case 115:
-#line 1586 "Gmsh.y"
+#line 1577 "Gmsh.y"
 {
       List_Add(yyval.l, &yyvsp[0].s);
     ;
     break;}
 case 116:
-#line 1590 "Gmsh.y"
+#line 1581 "Gmsh.y"
 {
       for(int i = 0; i < List_Nbr(yyvsp[-2].l); i++){
 	double d;
@@ -4372,7 +4363,7 @@ case 116:
     ;
     break;}
 case 117:
-#line 1606 "Gmsh.y"
+#line 1597 "Gmsh.y"
 {
       for(int i = 0; i < List_Nbr(yyvsp[-2].l); i++){
 	double d;
@@ -4390,7 +4381,7 @@ case 117:
     ;
     break;}
 case 118:
-#line 1622 "Gmsh.y"
+#line 1613 "Gmsh.y"
 {
       for(int i = 0; i < List_Nbr(yyvsp[-2].l); i++){
 	double d;
@@ -4408,7 +4399,7 @@ case 118:
     ;
     break;}
 case 119:
-#line 1638 "Gmsh.y"
+#line 1629 "Gmsh.y"
 {
       for(int i = 0; i < List_Nbr(yyvsp[-2].l); i++){
 	double d;
@@ -4426,7 +4417,7 @@ case 119:
     ;
     break;}
 case 120:
-#line 1659 "Gmsh.y"
+#line 1650 "Gmsh.y"
 {
       yyval.l = List_Create(3, 3, sizeof(Shape));
       for(int i = 0; i < List_Nbr(yyvsp[-1].l); i++){
@@ -4441,7 +4432,7 @@ case 120:
     ;
     break;}
 case 121:
-#line 1673 "Gmsh.y"
+#line 1664 "Gmsh.y"
 {
       if(!strcmp(yyvsp[-4].c, "View")) AliasView((int)yyvsp[-2].d, 0);
       Free(yyvsp[-4].c);
@@ -4449,7 +4440,7 @@ case 121:
     ;
     break;}
 case 122:
-#line 1679 "Gmsh.y"
+#line 1670 "Gmsh.y"
 {
       if(!strcmp(yyvsp[-4].c, "View")) AliasView((int)yyvsp[-2].d, 0);
       Free(yyvsp[-4].c);
@@ -4457,7 +4448,7 @@ case 122:
     ;
     break;}
 case 123:
-#line 1685 "Gmsh.y"
+#line 1676 "Gmsh.y"
 {
       if(!strcmp(yyvsp[-4].c, "View")) AliasView((int)yyvsp[-2].d, 1);
       Free(yyvsp[-4].c);
@@ -4465,7 +4456,7 @@ case 123:
     ;
     break;}
 case 124:
-#line 1697 "Gmsh.y"
+#line 1688 "Gmsh.y"
 {
       for(int i = 0; i < List_Nbr(yyvsp[-1].l); i++){
 	Shape TheShape;
@@ -4476,7 +4467,7 @@ case 124:
     ;
     break;}
 case 125:
-#line 1706 "Gmsh.y"
+#line 1697 "Gmsh.y"
 {
       if(!strcmp(yyvsp[-4].c, "View")){
 	RemoveViewByIndex((int)yyvsp[-2].d);
@@ -4488,7 +4479,7 @@ case 125:
     ;
     break;}
 case 126:
-#line 1716 "Gmsh.y"
+#line 1707 "Gmsh.y"
 {
       if(!strcmp(yyvsp[-1].c, "Meshes") || !strcmp(yyvsp[-1].c, "All")){
 	Init_Mesh();
@@ -4504,7 +4495,7 @@ case 126:
     ;
     break;}
 case 127:
-#line 1730 "Gmsh.y"
+#line 1721 "Gmsh.y"
 {
       if(!strcmp(yyvsp[-2].c, "Empty") && !strcmp(yyvsp[-1].c, "Views")){
 	for(int i = List_Nbr(CTX.post.list) - 1; i >= 0; i--){
@@ -4520,7 +4511,7 @@ case 127:
     ;
     break;}
 case 128:
-#line 1749 "Gmsh.y"
+#line 1740 "Gmsh.y"
 {
       for(int i = 0; i < List_Nbr(yyvsp[-1].l); i++){
 	Shape TheShape;
@@ -4531,7 +4522,7 @@ case 128:
     ;
     break;}
 case 129:
-#line 1763 "Gmsh.y"
+#line 1754 "Gmsh.y"
 {
       for(int i = 0; i < 4; i++)
 	VisibilityShape(yyvsp[-1].c, i, 1);
@@ -4539,7 +4530,7 @@ case 129:
     ;
     break;}
 case 130:
-#line 1769 "Gmsh.y"
+#line 1760 "Gmsh.y"
 {
       for(int i = 0; i < 4; i++)
 	VisibilityShape(yyvsp[-1].c, i, 0);
@@ -4547,7 +4538,7 @@ case 130:
     ;
     break;}
 case 131:
-#line 1775 "Gmsh.y"
+#line 1766 "Gmsh.y"
 {
       for(int i = 0; i < List_Nbr(yyvsp[-1].l); i++){
 	Shape TheShape;
@@ -4558,7 +4549,7 @@ case 131:
     ;
     break;}
 case 132:
-#line 1784 "Gmsh.y"
+#line 1775 "Gmsh.y"
 {
       for(int i = 0; i < List_Nbr(yyvsp[-1].l); i++){
 	Shape TheShape;
@@ -4569,7 +4560,7 @@ case 132:
     ;
     break;}
 case 133:
-#line 1798 "Gmsh.y"
+#line 1789 "Gmsh.y"
 {
       if(!strcmp(yyvsp[-2].c, "Include")){
 	char tmpstring[1024];
@@ -4616,7 +4607,7 @@ case 133:
     ;
     break;}
 case 134:
-#line 1843 "Gmsh.y"
+#line 1834 "Gmsh.y"
 {
       if(!strcmp(yyvsp[-6].c, "Save") && !strcmp(yyvsp[-5].c, "View")){
 	Post_View **vv = (Post_View **)List_Pointer_Test(CTX.post.list, (int)yyvsp[-3].d);
@@ -4633,7 +4624,7 @@ case 134:
     ;
     break;}
 case 135:
-#line 1858 "Gmsh.y"
+#line 1849 "Gmsh.y"
 {
       if(!strcmp(yyvsp[-6].c, "Background") && !strcmp(yyvsp[-5].c, "Mesh")  && !strcmp(yyvsp[-4].c, "View")){
 	Post_View **vv = (Post_View **)List_Pointer_Test(CTX.post.list, (int)yyvsp[-2].d);
@@ -4646,7 +4637,7 @@ case 135:
     ;
     break;}
 case 136:
-#line 1869 "Gmsh.y"
+#line 1860 "Gmsh.y"
 {
       if(!strcmp(yyvsp[-2].c, "Sleep")){
 	SleepInSeconds(yyvsp[-1].d);
@@ -4668,7 +4659,7 @@ case 136:
     ;
     break;}
 case 137:
-#line 1889 "Gmsh.y"
+#line 1880 "Gmsh.y"
 {
        try {
 	 GMSH_PluginManager::instance()->action(yyvsp[-4].c, yyvsp[-1].c, 0);
@@ -4680,7 +4671,7 @@ case 137:
      ;
     break;}
 case 138:
-#line 1899 "Gmsh.y"
+#line 1890 "Gmsh.y"
 {
       if(!strcmp(yyvsp[-1].c, "ElementsFromAllViews"))
 	CombineViews(0, 1, CTX.post.combine_remove_orig);
@@ -4704,27 +4695,27 @@ case 138:
     ;
     break;}
 case 139:
-#line 1921 "Gmsh.y"
+#line 1912 "Gmsh.y"
 {
       exit(0);
     ;
     break;}
 case 140:
-#line 1925 "Gmsh.y"
+#line 1916 "Gmsh.y"
 {
       CTX.forced_bbox = 0;
       SetBoundingBox();
     ;
     break;}
 case 141:
-#line 1930 "Gmsh.y"
+#line 1921 "Gmsh.y"
 {
       CTX.forced_bbox = 1;
       SetBoundingBox(yyvsp[-12].d, yyvsp[-10].d, yyvsp[-8].d, yyvsp[-6].d, yyvsp[-4].d, yyvsp[-2].d);
     ;
     break;}
 case 142:
-#line 1935 "Gmsh.y"
+#line 1926 "Gmsh.y"
 {
 #if defined(HAVE_FLTK)
       Draw();
@@ -4732,7 +4723,7 @@ case 142:
     ;
     break;}
 case 143:
-#line 1947 "Gmsh.y"
+#line 1938 "Gmsh.y"
 {
       LoopControlVariablesTab[ImbricatedLoop][0] = yyvsp[-3].d;
       LoopControlVariablesTab[ImbricatedLoop][1] = yyvsp[-1].d;
@@ -4749,7 +4740,7 @@ case 143:
     ;
     break;}
 case 144:
-#line 1962 "Gmsh.y"
+#line 1953 "Gmsh.y"
 {
       LoopControlVariablesTab[ImbricatedLoop][0] = yyvsp[-5].d;
       LoopControlVariablesTab[ImbricatedLoop][1] = yyvsp[-3].d;
@@ -4767,7 +4758,7 @@ case 144:
     ;
     break;}
 case 145:
-#line 1978 "Gmsh.y"
+#line 1969 "Gmsh.y"
 {
       LoopControlVariablesTab[ImbricatedLoop][0] = yyvsp[-3].d;
       LoopControlVariablesTab[ImbricatedLoop][1] = yyvsp[-1].d;
@@ -4795,7 +4786,7 @@ case 145:
     ;
     break;}
 case 146:
-#line 2004 "Gmsh.y"
+#line 1995 "Gmsh.y"
 {
       LoopControlVariablesTab[ImbricatedLoop][0] = yyvsp[-5].d;
       LoopControlVariablesTab[ImbricatedLoop][1] = yyvsp[-3].d;
@@ -4824,7 +4815,7 @@ case 146:
     ;
     break;}
 case 147:
-#line 2031 "Gmsh.y"
+#line 2022 "Gmsh.y"
 {
       if(ImbricatedLoop <= 0){
 	yymsg(GERROR, "Invalid For/EndFor loop");
@@ -4858,7 +4849,7 @@ case 147:
     ;
     break;}
 case 148:
-#line 2063 "Gmsh.y"
+#line 2054 "Gmsh.y"
 {
       if(!FunctionManager::Instance()->createFunction(yyvsp[0].c, yyin, yyname, yylineno))
 	yymsg(GERROR, "Redefinition of function %s", yyvsp[0].c);
@@ -4867,14 +4858,14 @@ case 148:
     ;
     break;}
 case 149:
-#line 2070 "Gmsh.y"
+#line 2061 "Gmsh.y"
 {
       if(!FunctionManager::Instance()->leaveFunction(&yyin, yyname, yylineno))
 	yymsg(GERROR, "Error while exiting function");
     ;
     break;}
 case 150:
-#line 2075 "Gmsh.y"
+#line 2066 "Gmsh.y"
 {
       if(!FunctionManager::Instance()->enterFunction(yyvsp[-1].c, &yyin, yyname, yylineno))
 	yymsg(GERROR, "Unknown function %s", yyvsp[-1].c);
@@ -4882,18 +4873,18 @@ case 150:
     ;
     break;}
 case 151:
-#line 2081 "Gmsh.y"
+#line 2072 "Gmsh.y"
 {
       if(!yyvsp[-1].d) skip_until("If", "EndIf");
     ;
     break;}
 case 152:
-#line 2085 "Gmsh.y"
+#line 2076 "Gmsh.y"
 {
     ;
     break;}
 case 153:
-#line 2094 "Gmsh.y"
+#line 2085 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(Shape));
       ExtrudeShapes(TRANSLATE, yyvsp[-1].l, 
@@ -4903,7 +4894,7 @@ case 153:
     ;
     break;}
 case 154:
-#line 2102 "Gmsh.y"
+#line 2093 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(Shape));
       ExtrudeShapes(ROTATE, yyvsp[-1].l, 
@@ -4913,7 +4904,7 @@ case 154:
     ;
     break;}
 case 155:
-#line 2110 "Gmsh.y"
+#line 2101 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(Shape));
       ExtrudeShapes(TRANSLATE_ROTATE, yyvsp[-1].l, 
@@ -4923,14 +4914,14 @@ case 155:
     ;
     break;}
 case 156:
-#line 2118 "Gmsh.y"
+#line 2109 "Gmsh.y"
 {
       extr.mesh.ExtrudeMesh = false;
       extr.mesh.Recombine = false;
     ;
     break;}
 case 157:
-#line 2123 "Gmsh.y"
+#line 2114 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(Shape));
       ExtrudeShapes(TRANSLATE, yyvsp[-3].l, 
@@ -4940,14 +4931,14 @@ case 157:
     ;
     break;}
 case 158:
-#line 2131 "Gmsh.y"
+#line 2122 "Gmsh.y"
 {
       extr.mesh.ExtrudeMesh = false;
       extr.mesh.Recombine = false;
     ;
     break;}
 case 159:
-#line 2136 "Gmsh.y"
+#line 2127 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(Shape));
       ExtrudeShapes(ROTATE, yyvsp[-3].l, 
@@ -4957,14 +4948,14 @@ case 159:
     ;
     break;}
 case 160:
-#line 2144 "Gmsh.y"
+#line 2135 "Gmsh.y"
 {
       extr.mesh.ExtrudeMesh = false;
       extr.mesh.Recombine = false;
     ;
     break;}
 case 161:
-#line 2149 "Gmsh.y"
+#line 2140 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(Shape));
       ExtrudeShapes(TRANSLATE_ROTATE, yyvsp[-3].l, 
@@ -4974,7 +4965,7 @@ case 161:
     ;
     break;}
 case 162:
-#line 2159 "Gmsh.y"
+#line 2150 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE, MSH_POINT, (int)yyvsp[-4].d, 
@@ -4983,7 +4974,7 @@ case 162:
     ;
     break;}
 case 163:
-#line 2166 "Gmsh.y"
+#line 2157 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE, MSH_SEGM_LINE, (int)yyvsp[-4].d, 
@@ -4992,7 +4983,7 @@ case 163:
     ;
     break;}
 case 164:
-#line 2173 "Gmsh.y"
+#line 2164 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE, MSH_SURF_PLAN, (int)yyvsp[-4].d, 
@@ -5001,7 +4992,7 @@ case 164:
     ;
     break;}
 case 165:
-#line 2180 "Gmsh.y"
+#line 2171 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(ROTATE, MSH_POINT, (int)yyvsp[-8].d, 
@@ -5010,7 +5001,7 @@ case 165:
     ;
     break;}
 case 166:
-#line 2187 "Gmsh.y"
+#line 2178 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(ROTATE, MSH_SEGM_LINE, (int)yyvsp[-8].d, 
@@ -5019,7 +5010,7 @@ case 166:
     ;
     break;}
 case 167:
-#line 2194 "Gmsh.y"
+#line 2185 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(ROTATE, MSH_SURF_PLAN, (int)yyvsp[-8].d, 
@@ -5028,7 +5019,7 @@ case 167:
     ;
     break;}
 case 168:
-#line 2201 "Gmsh.y"
+#line 2192 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE_ROTATE, MSH_POINT, (int)yyvsp[-10].d, 
@@ -5037,7 +5028,7 @@ case 168:
     ;
     break;}
 case 169:
-#line 2208 "Gmsh.y"
+#line 2199 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE_ROTATE, MSH_SEGM_LINE, (int)yyvsp[-10].d, 
@@ -5046,7 +5037,7 @@ case 169:
     ;
     break;}
 case 170:
-#line 2215 "Gmsh.y"
+#line 2206 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE_ROTATE, MSH_SURF_PLAN, (int)yyvsp[-10].d, 
@@ -5055,14 +5046,14 @@ case 170:
     ;
     break;}
 case 171:
-#line 2222 "Gmsh.y"
+#line 2213 "Gmsh.y"
 {
       extr.mesh.ExtrudeMesh = false;
       extr.mesh.Recombine = false;
     ;
     break;}
 case 172:
-#line 2227 "Gmsh.y"
+#line 2218 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE, MSH_POINT, (int)yyvsp[-8].d, 
@@ -5071,14 +5062,14 @@ case 172:
     ;
     break;}
 case 173:
-#line 2234 "Gmsh.y"
+#line 2225 "Gmsh.y"
 {
       extr.mesh.ExtrudeMesh = false;
       extr.mesh.Recombine = false;
     ;
     break;}
 case 174:
-#line 2239 "Gmsh.y"
+#line 2230 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE, MSH_SEGM_LINE, (int)yyvsp[-8].d, 
@@ -5087,14 +5078,14 @@ case 174:
     ;
     break;}
 case 175:
-#line 2246 "Gmsh.y"
+#line 2237 "Gmsh.y"
 {
       extr.mesh.ExtrudeMesh = false;
       extr.mesh.Recombine = false;
     ;
     break;}
 case 176:
-#line 2251 "Gmsh.y"
+#line 2242 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE, MSH_SURF_PLAN, (int)yyvsp[-8].d, 
@@ -5103,14 +5094,14 @@ case 176:
     ;
     break;}
 case 177:
-#line 2258 "Gmsh.y"
+#line 2249 "Gmsh.y"
 {
       extr.mesh.ExtrudeMesh = false;
       extr.mesh.Recombine = false;
     ;
     break;}
 case 178:
-#line 2263 "Gmsh.y"
+#line 2254 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(ROTATE, MSH_POINT, (int)yyvsp[-12].d, 
@@ -5119,14 +5110,14 @@ case 178:
     ;
     break;}
 case 179:
-#line 2270 "Gmsh.y"
+#line 2261 "Gmsh.y"
 {
       extr.mesh.ExtrudeMesh = false;
       extr.mesh.Recombine = false;
     ;
     break;}
 case 180:
-#line 2275 "Gmsh.y"
+#line 2266 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(ROTATE, MSH_SEGM_LINE, (int)yyvsp[-12].d, 
@@ -5135,14 +5126,14 @@ case 180:
     ;
     break;}
 case 181:
-#line 2282 "Gmsh.y"
+#line 2273 "Gmsh.y"
 {
       extr.mesh.ExtrudeMesh = false;
       extr.mesh.Recombine = false;
     ;
     break;}
 case 182:
-#line 2287 "Gmsh.y"
+#line 2278 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(ROTATE, MSH_SURF_PLAN, (int)yyvsp[-12].d, 
@@ -5151,14 +5142,14 @@ case 182:
     ;
     break;}
 case 183:
-#line 2294 "Gmsh.y"
+#line 2285 "Gmsh.y"
 {
       extr.mesh.ExtrudeMesh = false;
       extr.mesh.Recombine = false;
     ;
     break;}
 case 184:
-#line 2299 "Gmsh.y"
+#line 2290 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE_ROTATE, MSH_POINT, (int)yyvsp[-14].d, 
@@ -5167,14 +5158,14 @@ case 184:
     ;
     break;}
 case 185:
-#line 2306 "Gmsh.y"
+#line 2297 "Gmsh.y"
 {
       extr.mesh.ExtrudeMesh = false;
       extr.mesh.Recombine = false;
     ;
     break;}
 case 186:
-#line 2311 "Gmsh.y"
+#line 2302 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE_ROTATE, MSH_SEGM_LINE, (int)yyvsp[-14].d, 
@@ -5183,14 +5174,14 @@ case 186:
     ;
     break;}
 case 187:
-#line 2318 "Gmsh.y"
+#line 2309 "Gmsh.y"
 {
       extr.mesh.ExtrudeMesh = false;
       extr.mesh.Recombine = false;
     ;
     break;}
 case 188:
-#line 2323 "Gmsh.y"
+#line 2314 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE_ROTATE, MSH_SURF_PLAN, (int)yyvsp[-14].d, 
@@ -5199,17 +5190,17 @@ case 188:
     ;
     break;}
 case 189:
-#line 2334 "Gmsh.y"
+#line 2325 "Gmsh.y"
 {
     ;
     break;}
 case 190:
-#line 2337 "Gmsh.y"
+#line 2328 "Gmsh.y"
 {
     ;
     break;}
 case 191:
-#line 2343 "Gmsh.y"
+#line 2334 "Gmsh.y"
 {
       double d;
       extr.mesh.ExtrudeMesh = true;
@@ -5237,7 +5228,7 @@ case 191:
     ;
     break;}
 case 192:
-#line 2369 "Gmsh.y"
+#line 2360 "Gmsh.y"
 {
       double d;
       extr.mesh.ExtrudeMesh = true;
@@ -5263,13 +5254,13 @@ case 192:
     ;
     break;}
 case 193:
-#line 2393 "Gmsh.y"
+#line 2384 "Gmsh.y"
 {
       extr.mesh.Recombine = true;
     ;
     break;}
 case 194:
-#line 2402 "Gmsh.y"
+#line 2393 "Gmsh.y"
 {
       for(int i = 0; i < List_Nbr(yyvsp[-3].l); i++){
 	double d;
@@ -5289,7 +5280,7 @@ case 194:
     ;
     break;}
 case 195:
-#line 2420 "Gmsh.y"
+#line 2411 "Gmsh.y"
 {
       for(int i = 0; i < List_Nbr(yyvsp[-6].l); i++){
 	double d;
@@ -5309,7 +5300,7 @@ case 195:
     ;
     break;}
 case 196:
-#line 2438 "Gmsh.y"
+#line 2429 "Gmsh.y"
 {
       for(int i = 0; i < List_Nbr(yyvsp[-6].l); i++){
 	double d;
@@ -5329,7 +5320,7 @@ case 196:
     ;
     break;}
 case 197:
-#line 2456 "Gmsh.y"
+#line 2447 "Gmsh.y"
 {
       Surface *s = FindSurface((int)yyvsp[-4].d);
       if(!s)
@@ -5360,7 +5351,7 @@ case 197:
     ;
     break;}
 case 198:
-#line 2485 "Gmsh.y"
+#line 2476 "Gmsh.y"
 {
       Surface *s = FindSurface((int)yyvsp[-5].d);
       if(!s)
@@ -5397,7 +5388,7 @@ case 198:
     ;
     break;}
 case 199:
-#line 2520 "Gmsh.y"
+#line 2511 "Gmsh.y"
 {
       Surface *s = FindSurface((int)yyvsp[-4].d);
       if(!s)
@@ -5426,7 +5417,7 @@ case 199:
     ;
     break;}
 case 200:
-#line 2547 "Gmsh.y"
+#line 2538 "Gmsh.y"
 {
       Volume *v = FindVolume((int)yyvsp[-4].d);
       if(!v)
@@ -5455,7 +5446,7 @@ case 200:
     ;
     break;}
 case 201:
-#line 2574 "Gmsh.y"
+#line 2565 "Gmsh.y"
 {
       for(int i = 0; i < List_Nbr(yyvsp[-3].l); i++){
 	double d;
@@ -5471,7 +5462,7 @@ case 201:
     ;
     break;}
 case 202:
-#line 2588 "Gmsh.y"
+#line 2579 "Gmsh.y"
 {
       for(int i = 0; i < List_Nbr(yyvsp[-1].l); i++){
 	double d;
@@ -5486,7 +5477,7 @@ case 202:
     ;
     break;}
 case 203:
-#line 2607 "Gmsh.y"
+#line 2598 "Gmsh.y"
 { 
       Surface *s = FindSurface((int)yyvsp[-1].d);
       if(s)
@@ -5494,7 +5485,7 @@ case 203:
     ;
     break;}
 case 204:
-#line 2613 "Gmsh.y"
+#line 2604 "Gmsh.y"
 {
       Surface *s = FindSurface((int)yyvsp[-1].d);
       if(s)
@@ -5502,61 +5493,61 @@ case 204:
     ;
     break;}
 case 205:
-#line 2619 "Gmsh.y"
+#line 2610 "Gmsh.y"
 {
     ;
     break;}
 case 206:
-#line 2622 "Gmsh.y"
+#line 2613 "Gmsh.y"
 {
     ;
     break;}
 case 207:
-#line 2629 "Gmsh.y"
+#line 2620 "Gmsh.y"
 { 
       ReplaceAllDuplicates();
     ;
     break;}
 case 208:
-#line 2633 "Gmsh.y"
+#line 2624 "Gmsh.y"
 { 
       yymsg(GERROR, "Intersect is deprecated");
     ;
     break;}
 case 209:
-#line 2642 "Gmsh.y"
+#line 2633 "Gmsh.y"
 { yyval.d = yyvsp[0].d;           ;
     break;}
 case 210:
-#line 2643 "Gmsh.y"
+#line 2634 "Gmsh.y"
 { yyval.d = yyvsp[-1].d;           ;
     break;}
 case 211:
-#line 2644 "Gmsh.y"
+#line 2635 "Gmsh.y"
 { yyval.d = -yyvsp[0].d;          ;
     break;}
 case 212:
-#line 2645 "Gmsh.y"
+#line 2636 "Gmsh.y"
 { yyval.d = yyvsp[0].d;           ;
     break;}
 case 213:
-#line 2646 "Gmsh.y"
+#line 2637 "Gmsh.y"
 { yyval.d = !yyvsp[0].d;          ;
     break;}
 case 214:
-#line 2647 "Gmsh.y"
+#line 2638 "Gmsh.y"
 { yyval.d = yyvsp[-2].d - yyvsp[0].d;      ;
     break;}
 case 215:
-#line 2648 "Gmsh.y"
+#line 2639 "Gmsh.y"
 { yyval.d = yyvsp[-2].d + yyvsp[0].d;      ;
     break;}
 case 216:
-#line 2649 "Gmsh.y"
+#line 2640 "Gmsh.y"
 { yyval.d = yyvsp[-2].d * yyvsp[0].d;      ;
     break;}
 case 217:
-#line 2651 "Gmsh.y"
+#line 2642 "Gmsh.y"
 { 
       if(!yyvsp[0].d)
 	yymsg(GERROR, "Division by zero in '%g / %g'", yyvsp[-2].d, yyvsp[0].d);
@@ -5565,247 +5556,247 @@ case 217:
     ;
     break;}
 case 218:
-#line 2657 "Gmsh.y"
+#line 2648 "Gmsh.y"
 { yyval.d = (int)yyvsp[-2].d % (int)yyvsp[0].d;  ;
     break;}
 case 219:
-#line 2658 "Gmsh.y"
+#line 2649 "Gmsh.y"
 { yyval.d = pow(yyvsp[-2].d, yyvsp[0].d);  ;
     break;}
 case 220:
-#line 2659 "Gmsh.y"
+#line 2650 "Gmsh.y"
 { yyval.d = yyvsp[-2].d < yyvsp[0].d;      ;
     break;}
 case 221:
-#line 2660 "Gmsh.y"
+#line 2651 "Gmsh.y"
 { yyval.d = yyvsp[-2].d > yyvsp[0].d;      ;
     break;}
 case 222:
-#line 2661 "Gmsh.y"
+#line 2652 "Gmsh.y"
 { yyval.d = yyvsp[-2].d <= yyvsp[0].d;     ;
     break;}
 case 223:
-#line 2662 "Gmsh.y"
+#line 2653 "Gmsh.y"
 { yyval.d = yyvsp[-2].d >= yyvsp[0].d;     ;
     break;}
 case 224:
-#line 2663 "Gmsh.y"
+#line 2654 "Gmsh.y"
 { yyval.d = yyvsp[-2].d == yyvsp[0].d;     ;
     break;}
 case 225:
-#line 2664 "Gmsh.y"
+#line 2655 "Gmsh.y"
 { yyval.d = yyvsp[-2].d != yyvsp[0].d;     ;
     break;}
 case 226:
-#line 2665 "Gmsh.y"
+#line 2656 "Gmsh.y"
 { yyval.d = yyvsp[-2].d && yyvsp[0].d;     ;
     break;}
 case 227:
-#line 2666 "Gmsh.y"
+#line 2657 "Gmsh.y"
 { yyval.d = yyvsp[-2].d || yyvsp[0].d;     ;
     break;}
 case 228:
-#line 2667 "Gmsh.y"
+#line 2658 "Gmsh.y"
 { yyval.d = yyvsp[-4].d? yyvsp[-2].d : yyvsp[0].d;  ;
     break;}
 case 229:
-#line 2668 "Gmsh.y"
+#line 2659 "Gmsh.y"
 { yyval.d = exp(yyvsp[-1].d);      ;
     break;}
 case 230:
-#line 2669 "Gmsh.y"
+#line 2660 "Gmsh.y"
 { yyval.d = log(yyvsp[-1].d);      ;
     break;}
 case 231:
-#line 2670 "Gmsh.y"
+#line 2661 "Gmsh.y"
 { yyval.d = log10(yyvsp[-1].d);    ;
     break;}
 case 232:
-#line 2671 "Gmsh.y"
+#line 2662 "Gmsh.y"
 { yyval.d = sqrt(yyvsp[-1].d);     ;
     break;}
 case 233:
-#line 2672 "Gmsh.y"
+#line 2663 "Gmsh.y"
 { yyval.d = sin(yyvsp[-1].d);      ;
     break;}
 case 234:
-#line 2673 "Gmsh.y"
+#line 2664 "Gmsh.y"
 { yyval.d = asin(yyvsp[-1].d);     ;
     break;}
 case 235:
-#line 2674 "Gmsh.y"
+#line 2665 "Gmsh.y"
 { yyval.d = cos(yyvsp[-1].d);      ;
     break;}
 case 236:
-#line 2675 "Gmsh.y"
+#line 2666 "Gmsh.y"
 { yyval.d = acos(yyvsp[-1].d);     ;
     break;}
 case 237:
-#line 2676 "Gmsh.y"
+#line 2667 "Gmsh.y"
 { yyval.d = tan(yyvsp[-1].d);      ;
     break;}
 case 238:
-#line 2677 "Gmsh.y"
+#line 2668 "Gmsh.y"
 { yyval.d = atan(yyvsp[-1].d);     ;
     break;}
 case 239:
-#line 2678 "Gmsh.y"
+#line 2669 "Gmsh.y"
 { yyval.d = atan2(yyvsp[-3].d, yyvsp[-1].d);;
     break;}
 case 240:
-#line 2679 "Gmsh.y"
+#line 2670 "Gmsh.y"
 { yyval.d = sinh(yyvsp[-1].d);     ;
     break;}
 case 241:
-#line 2680 "Gmsh.y"
+#line 2671 "Gmsh.y"
 { yyval.d = cosh(yyvsp[-1].d);     ;
     break;}
 case 242:
-#line 2681 "Gmsh.y"
+#line 2672 "Gmsh.y"
 { yyval.d = tanh(yyvsp[-1].d);     ;
     break;}
 case 243:
-#line 2682 "Gmsh.y"
+#line 2673 "Gmsh.y"
 { yyval.d = fabs(yyvsp[-1].d);     ;
     break;}
 case 244:
-#line 2683 "Gmsh.y"
+#line 2674 "Gmsh.y"
 { yyval.d = floor(yyvsp[-1].d);    ;
     break;}
 case 245:
-#line 2684 "Gmsh.y"
+#line 2675 "Gmsh.y"
 { yyval.d = ceil(yyvsp[-1].d);     ;
     break;}
 case 246:
-#line 2685 "Gmsh.y"
+#line 2676 "Gmsh.y"
 { yyval.d = fmod(yyvsp[-3].d, yyvsp[-1].d); ;
     break;}
 case 247:
-#line 2686 "Gmsh.y"
+#line 2677 "Gmsh.y"
 { yyval.d = fmod(yyvsp[-3].d, yyvsp[-1].d); ;
     break;}
 case 248:
-#line 2687 "Gmsh.y"
+#line 2678 "Gmsh.y"
 { yyval.d = sqrt(yyvsp[-3].d*yyvsp[-3].d+yyvsp[-1].d*yyvsp[-1].d); ;
     break;}
 case 249:
-#line 2688 "Gmsh.y"
+#line 2679 "Gmsh.y"
 { yyval.d = yyvsp[-1].d*(double)rand()/(double)RAND_MAX; ;
     break;}
 case 250:
-#line 2690 "Gmsh.y"
+#line 2681 "Gmsh.y"
 { yyval.d = exp(yyvsp[-1].d);      ;
     break;}
 case 251:
-#line 2691 "Gmsh.y"
+#line 2682 "Gmsh.y"
 { yyval.d = log(yyvsp[-1].d);      ;
     break;}
 case 252:
-#line 2692 "Gmsh.y"
+#line 2683 "Gmsh.y"
 { yyval.d = log10(yyvsp[-1].d);    ;
     break;}
 case 253:
-#line 2693 "Gmsh.y"
+#line 2684 "Gmsh.y"
 { yyval.d = sqrt(yyvsp[-1].d);     ;
     break;}
 case 254:
-#line 2694 "Gmsh.y"
+#line 2685 "Gmsh.y"
 { yyval.d = sin(yyvsp[-1].d);      ;
     break;}
 case 255:
-#line 2695 "Gmsh.y"
+#line 2686 "Gmsh.y"
 { yyval.d = asin(yyvsp[-1].d);     ;
     break;}
 case 256:
-#line 2696 "Gmsh.y"
+#line 2687 "Gmsh.y"
 { yyval.d = cos(yyvsp[-1].d);      ;
     break;}
 case 257:
-#line 2697 "Gmsh.y"
+#line 2688 "Gmsh.y"
 { yyval.d = acos(yyvsp[-1].d);     ;
     break;}
 case 258:
-#line 2698 "Gmsh.y"
+#line 2689 "Gmsh.y"
 { yyval.d = tan(yyvsp[-1].d);      ;
     break;}
 case 259:
-#line 2699 "Gmsh.y"
+#line 2690 "Gmsh.y"
 { yyval.d = atan(yyvsp[-1].d);     ;
     break;}
 case 260:
-#line 2700 "Gmsh.y"
+#line 2691 "Gmsh.y"
 { yyval.d = atan2(yyvsp[-3].d, yyvsp[-1].d);;
     break;}
 case 261:
-#line 2701 "Gmsh.y"
+#line 2692 "Gmsh.y"
 { yyval.d = sinh(yyvsp[-1].d);     ;
     break;}
 case 262:
-#line 2702 "Gmsh.y"
+#line 2693 "Gmsh.y"
 { yyval.d = cosh(yyvsp[-1].d);     ;
     break;}
 case 263:
-#line 2703 "Gmsh.y"
+#line 2694 "Gmsh.y"
 { yyval.d = tanh(yyvsp[-1].d);     ;
     break;}
 case 264:
-#line 2704 "Gmsh.y"
+#line 2695 "Gmsh.y"
 { yyval.d = fabs(yyvsp[-1].d);     ;
     break;}
 case 265:
-#line 2705 "Gmsh.y"
+#line 2696 "Gmsh.y"
 { yyval.d = floor(yyvsp[-1].d);    ;
     break;}
 case 266:
-#line 2706 "Gmsh.y"
+#line 2697 "Gmsh.y"
 { yyval.d = ceil(yyvsp[-1].d);     ;
     break;}
 case 267:
-#line 2707 "Gmsh.y"
+#line 2698 "Gmsh.y"
 { yyval.d = fmod(yyvsp[-3].d, yyvsp[-1].d); ;
     break;}
 case 268:
-#line 2708 "Gmsh.y"
+#line 2699 "Gmsh.y"
 { yyval.d = fmod(yyvsp[-3].d, yyvsp[-1].d); ;
     break;}
 case 269:
-#line 2709 "Gmsh.y"
+#line 2700 "Gmsh.y"
 { yyval.d = sqrt(yyvsp[-3].d*yyvsp[-3].d+yyvsp[-1].d*yyvsp[-1].d); ;
     break;}
 case 270:
-#line 2710 "Gmsh.y"
+#line 2701 "Gmsh.y"
 { yyval.d = yyvsp[-1].d*(double)rand()/(double)RAND_MAX; ;
     break;}
 case 271:
-#line 2719 "Gmsh.y"
+#line 2710 "Gmsh.y"
 { yyval.d = yyvsp[0].d; ;
     break;}
 case 272:
-#line 2720 "Gmsh.y"
+#line 2711 "Gmsh.y"
 { yyval.d = 3.141592653589793; ;
     break;}
 case 273:
-#line 2721 "Gmsh.y"
+#line 2712 "Gmsh.y"
 { yyval.d = ParUtil::Instance()->rank(); ;
     break;}
 case 274:
-#line 2722 "Gmsh.y"
+#line 2713 "Gmsh.y"
 { yyval.d = ParUtil::Instance()->size(); ;
     break;}
 case 275:
-#line 2723 "Gmsh.y"
+#line 2714 "Gmsh.y"
 { yyval.d = Get_GmshMajorVersion(); ;
     break;}
 case 276:
-#line 2724 "Gmsh.y"
+#line 2715 "Gmsh.y"
 { yyval.d = Get_GmshMinorVersion(); ;
     break;}
 case 277:
-#line 2725 "Gmsh.y"
+#line 2716 "Gmsh.y"
 { yyval.d = Get_GmshPatchVersion(); ;
     break;}
 case 278:
-#line 2730 "Gmsh.y"
+#line 2721 "Gmsh.y"
 {
       Symbol TheSymbol;
       TheSymbol.Name = yyvsp[0].c;
@@ -5820,7 +5811,7 @@ case 278:
     ;
     break;}
 case 279:
-#line 2746 "Gmsh.y"
+#line 2737 "Gmsh.y"
 {
       char tmpstring[1024];
       sprintf(tmpstring, "%s_%d", yyvsp[-4].c, (int)yyvsp[-1].d) ;
@@ -5837,7 +5828,7 @@ case 279:
     ;
     break;}
 case 280:
-#line 2761 "Gmsh.y"
+#line 2752 "Gmsh.y"
 {
       Symbol TheSymbol;
       TheSymbol.Name = yyvsp[-3].c;
@@ -5859,7 +5850,7 @@ case 280:
     ;
     break;}
 case 281:
-#line 2781 "Gmsh.y"
+#line 2772 "Gmsh.y"
 {
       Symbol TheSymbol;
       TheSymbol.Name = yyvsp[-2].c;
@@ -5875,7 +5866,7 @@ case 281:
     ;
     break;}
 case 282:
-#line 2795 "Gmsh.y"
+#line 2786 "Gmsh.y"
 {
       Symbol TheSymbol;
       TheSymbol.Name = yyvsp[-1].c;
@@ -5890,7 +5881,7 @@ case 282:
     ;
     break;}
 case 283:
-#line 2808 "Gmsh.y"
+#line 2799 "Gmsh.y"
 {
       Symbol TheSymbol;
       TheSymbol.Name = yyvsp[-4].c;
@@ -5912,7 +5903,7 @@ case 283:
     ;
     break;}
 case 284:
-#line 2831 "Gmsh.y"
+#line 2822 "Gmsh.y"
 {
       double (*pNumOpt)(int num, int action, double value);
       StringXNumber *pNumCat;
@@ -5932,7 +5923,7 @@ case 284:
     ;
     break;}
 case 285:
-#line 2849 "Gmsh.y"
+#line 2840 "Gmsh.y"
 {
       double (*pNumOpt)(int num, int action, double value);
       StringXNumber *pNumCat;
@@ -5952,7 +5943,7 @@ case 285:
     ;
     break;}
 case 286:
-#line 2867 "Gmsh.y"
+#line 2858 "Gmsh.y"
 {
       double (*pNumOpt)(int num, int action, double value);
       StringXNumber *pNumCat;
@@ -5972,7 +5963,7 @@ case 286:
     ;
     break;}
 case 287:
-#line 2885 "Gmsh.y"
+#line 2876 "Gmsh.y"
 {
       double (*pNumOpt)(int num, int action, double value);
       StringXNumber *pNumCat;
@@ -5992,124 +5983,124 @@ case 287:
     ;
     break;}
 case 288:
-#line 2903 "Gmsh.y"
+#line 2894 "Gmsh.y"
 { 
       yyval.d = GetValue(yyvsp[-3].c, yyvsp[-1].d);
       Free(yyvsp[-3].c);
     ;
     break;}
 case 289:
-#line 2911 "Gmsh.y"
+#line 2902 "Gmsh.y"
 {
       memcpy(yyval.v, yyvsp[0].v, 5*sizeof(double));
     ;
     break;}
 case 290:
-#line 2915 "Gmsh.y"
+#line 2906 "Gmsh.y"
 {
       for(int i = 0; i < 5; i++) yyval.v[i] = -yyvsp[0].v[i];
     ;
     break;}
 case 291:
-#line 2919 "Gmsh.y"
+#line 2910 "Gmsh.y"
 { 
       for(int i = 0; i < 5; i++) yyval.v[i] = yyvsp[0].v[i];
     ;
     break;}
 case 292:
-#line 2923 "Gmsh.y"
+#line 2914 "Gmsh.y"
 { 
       for(int i = 0; i < 5; i++) yyval.v[i] = yyvsp[-2].v[i] - yyvsp[0].v[i];
     ;
     break;}
 case 293:
-#line 2927 "Gmsh.y"
+#line 2918 "Gmsh.y"
 {
       for(int i = 0; i < 5; i++) yyval.v[i] = yyvsp[-2].v[i] + yyvsp[0].v[i];
     ;
     break;}
 case 294:
-#line 2934 "Gmsh.y"
+#line 2925 "Gmsh.y"
 { 
       yyval.v[0] = yyvsp[-9].d;  yyval.v[1] = yyvsp[-7].d;  yyval.v[2] = yyvsp[-5].d;  yyval.v[3] = yyvsp[-3].d; yyval.v[4] = yyvsp[-1].d;
     ;
     break;}
 case 295:
-#line 2938 "Gmsh.y"
+#line 2929 "Gmsh.y"
 { 
       yyval.v[0] = yyvsp[-7].d;  yyval.v[1] = yyvsp[-5].d;  yyval.v[2] = yyvsp[-3].d;  yyval.v[3] = yyvsp[-1].d; yyval.v[4] = 1.0;
     ;
     break;}
 case 296:
-#line 2942 "Gmsh.y"
+#line 2933 "Gmsh.y"
 {
       yyval.v[0] = yyvsp[-5].d;  yyval.v[1] = yyvsp[-3].d;  yyval.v[2] = yyvsp[-1].d;  yyval.v[3] = 0.0; yyval.v[4] = 1.0;
     ;
     break;}
 case 297:
-#line 2946 "Gmsh.y"
+#line 2937 "Gmsh.y"
 {
       yyval.v[0] = yyvsp[-5].d;  yyval.v[1] = yyvsp[-3].d;  yyval.v[2] = yyvsp[-1].d;  yyval.v[3] = 0.0; yyval.v[4] = 1.0;
     ;
     break;}
 case 298:
-#line 2953 "Gmsh.y"
+#line 2944 "Gmsh.y"
 {
     ;
     break;}
 case 299:
-#line 2956 "Gmsh.y"
+#line 2947 "Gmsh.y"
 {
        yyval.l = yyvsp[-1].l;
     ;
     break;}
 case 300:
-#line 2960 "Gmsh.y"
+#line 2951 "Gmsh.y"
 {
        yyval.l = yyvsp[-1].l;
     ;
     break;}
 case 301:
-#line 2967 "Gmsh.y"
+#line 2958 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(List_T*));
       List_Add(yyval.l, &(yyvsp[0].l));
     ;
     break;}
 case 302:
-#line 2972 "Gmsh.y"
+#line 2963 "Gmsh.y"
 {
       List_Add(yyval.l, &(yyvsp[0].l));
     ;
     break;}
 case 303:
-#line 2980 "Gmsh.y"
+#line 2971 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(double));
       List_Add(yyval.l, &(yyvsp[0].d));
     ;
     break;}
 case 304:
-#line 2985 "Gmsh.y"
+#line 2976 "Gmsh.y"
 {
       yyval.l = yyvsp[0].l;
     ;
     break;}
 case 305:
-#line 2989 "Gmsh.y"
+#line 2980 "Gmsh.y"
 {
       // creates an empty list
       yyval.l = List_Create(2, 1, sizeof(double));
     ;
     break;}
 case 306:
-#line 2994 "Gmsh.y"
+#line 2985 "Gmsh.y"
 {
       yyval.l = yyvsp[-1].l;
     ;
     break;}
 case 307:
-#line 2998 "Gmsh.y"
+#line 2989 "Gmsh.y"
 {
       yyval.l = yyvsp[-1].l;
       double *pd;
@@ -6120,7 +6111,7 @@ case 307:
     ;
     break;}
 case 308:
-#line 3010 "Gmsh.y"
+#line 3001 "Gmsh.y"
 { 
       yyval.l = List_Create(2, 1, sizeof(double)); 
       for(double d = yyvsp[-2].d; (yyvsp[-2].d < yyvsp[0].d) ? (d <= yyvsp[0].d) : (d >= yyvsp[0].d); (yyvsp[-2].d < yyvsp[0].d) ? (d += 1.) : (d -= 1.)) 
@@ -6128,7 +6119,7 @@ case 308:
     ;
     break;}
 case 309:
-#line 3016 "Gmsh.y"
+#line 3007 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(double)); 
       if(!yyvsp[0].d || (yyvsp[-4].d < yyvsp[-2].d && yyvsp[0].d < 0) || (yyvsp[-4].d > yyvsp[-2].d && yyvsp[0].d > 0)){
@@ -6141,7 +6132,7 @@ case 309:
    ;
     break;}
 case 310:
-#line 3027 "Gmsh.y"
+#line 3018 "Gmsh.y"
 {
       // Returns the coordinates of a point and fills a list with it.
       // This allows to ensure e.g. that relative point positions are
@@ -6163,7 +6154,7 @@ case 310:
     ;
     break;}
 case 311:
-#line 3047 "Gmsh.y"
+#line 3038 "Gmsh.y"
 {
       yyval.l = List_Create(List_Nbr(yyvsp[0].l), 1, sizeof(double));
       for(int i = 0; i < List_Nbr(yyvsp[0].l); i++){
@@ -6175,7 +6166,7 @@ case 311:
     ;
     break;}
 case 312:
-#line 3057 "Gmsh.y"
+#line 3048 "Gmsh.y"
 {
       yyval.l = List_Create(List_Nbr(yyvsp[0].l), 1, sizeof(double));
       for(int i = 0; i < List_Nbr(yyvsp[0].l); i++){
@@ -6187,7 +6178,7 @@ case 312:
     ;
     break;}
 case 313:
-#line 3067 "Gmsh.y"
+#line 3058 "Gmsh.y"
 {
       yyval.l = List_Create(List_Nbr(yyvsp[0].l), 1, sizeof(double));
       for(int i = 0; i < List_Nbr(yyvsp[0].l); i++){
@@ -6199,7 +6190,7 @@ case 313:
     ;
     break;}
 case 314:
-#line 3077 "Gmsh.y"
+#line 3068 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(double));
       Symbol TheSymbol;
@@ -6218,7 +6209,7 @@ case 314:
     ;
     break;}
 case 315:
-#line 3094 "Gmsh.y"
+#line 3085 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(double));
       Symbol TheSymbol;
@@ -6239,7 +6230,7 @@ case 315:
     ;
     break;}
 case 316:
-#line 3113 "Gmsh.y"
+#line 3104 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(double));
       Symbol TheSymbol;
@@ -6265,7 +6256,7 @@ case 316:
     ;
     break;}
 case 317:
-#line 3137 "Gmsh.y"
+#line 3128 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(double));
       Symbol TheSymbol;
@@ -6293,26 +6284,26 @@ case 317:
     ;
     break;}
 case 318:
-#line 3166 "Gmsh.y"
+#line 3157 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(double));
       List_Add(yyval.l, &(yyvsp[0].d));
     ;
     break;}
 case 319:
-#line 3171 "Gmsh.y"
+#line 3162 "Gmsh.y"
 {
       yyval.l = yyvsp[0].l;
     ;
     break;}
 case 320:
-#line 3175 "Gmsh.y"
+#line 3166 "Gmsh.y"
 {
       List_Add(yyval.l, &(yyvsp[0].d));
     ;
     break;}
 case 321:
-#line 3179 "Gmsh.y"
+#line 3170 "Gmsh.y"
 {
       for(int i = 0; i < List_Nbr(yyvsp[0].l); i++){
 	double d;
@@ -6323,19 +6314,19 @@ case 321:
     ;
     break;}
 case 322:
-#line 3192 "Gmsh.y"
+#line 3183 "Gmsh.y"
 {
       yyval.u = CTX.PACK_COLOR((int)yyvsp[-7].d, (int)yyvsp[-5].d, (int)yyvsp[-3].d, (int)yyvsp[-1].d);
     ;
     break;}
 case 323:
-#line 3196 "Gmsh.y"
+#line 3187 "Gmsh.y"
 {
       yyval.u = CTX.PACK_COLOR((int)yyvsp[-5].d, (int)yyvsp[-3].d, (int)yyvsp[-1].d, 255);
     ;
     break;}
 case 324:
-#line 3208 "Gmsh.y"
+#line 3199 "Gmsh.y"
 {
       int flag;
       yyval.u = Get_ColorForString(ColorString, -1, yyvsp[0].c, &flag);
@@ -6344,7 +6335,7 @@ case 324:
     ;
     break;}
 case 325:
-#line 3215 "Gmsh.y"
+#line 3206 "Gmsh.y"
 {
       unsigned int (*pColOpt)(int num, int action, unsigned int value);
       StringXColor *pColCat;
@@ -6365,13 +6356,13 @@ case 325:
     ;
     break;}
 case 326:
-#line 3237 "Gmsh.y"
+#line 3228 "Gmsh.y"
 {
       yyval.l = yyvsp[-1].l;
     ;
     break;}
 case 327:
-#line 3241 "Gmsh.y"
+#line 3232 "Gmsh.y"
 {
       yyval.l = List_Create(256, 10, sizeof(unsigned int));
       GmshColorTable *ct = Get_ColorTable((int)yyvsp[-3].d);
@@ -6385,26 +6376,26 @@ case 327:
     ;
     break;}
 case 328:
-#line 3256 "Gmsh.y"
+#line 3247 "Gmsh.y"
 {
       yyval.l = List_Create(256, 10, sizeof(unsigned int));
       List_Add(yyval.l, &(yyvsp[0].u));
     ;
     break;}
 case 329:
-#line 3261 "Gmsh.y"
+#line 3252 "Gmsh.y"
 {
       List_Add(yyval.l, &(yyvsp[0].u));
     ;
     break;}
 case 330:
-#line 3268 "Gmsh.y"
+#line 3259 "Gmsh.y"
 {
       yyval.c = yyvsp[0].c;
     ;
     break;}
 case 331:
-#line 3272 "Gmsh.y"
+#line 3263 "Gmsh.y"
 {
       yyval.c = (char *)Malloc(32*sizeof(char));
       time_t now;
@@ -6414,7 +6405,7 @@ case 331:
     ;
     break;}
 case 332:
-#line 3280 "Gmsh.y"
+#line 3271 "Gmsh.y"
 {
       yyval.c = (char *)Malloc((strlen(yyvsp[-3].c)+strlen(yyvsp[-1].c)+1)*sizeof(char));
       strcpy(yyval.c, yyvsp[-3].c);
@@ -6424,7 +6415,7 @@ case 332:
     ;
     break;}
 case 333:
-#line 3288 "Gmsh.y"
+#line 3279 "Gmsh.y"
 {
       yyval.c = (char *)Malloc((strlen(yyvsp[-1].c)+1)*sizeof(char));
       int i;
@@ -6440,7 +6431,7 @@ case 333:
     ;
     break;}
 case 334:
-#line 3302 "Gmsh.y"
+#line 3293 "Gmsh.y"
 {
       yyval.c = (char *)Malloc((strlen(yyvsp[-1].c)+1)*sizeof(char));
       int i;
@@ -6456,13 +6447,13 @@ case 334:
     ;
     break;}
 case 335:
-#line 3316 "Gmsh.y"
+#line 3307 "Gmsh.y"
 {
       yyval.c = yyvsp[-1].c;
     ;
     break;}
 case 336:
-#line 3320 "Gmsh.y"
+#line 3311 "Gmsh.y"
 {
       char tmpstring[1024];
       int i = PrintListOfDouble(yyvsp[-3].c, yyvsp[-1].l, tmpstring);
@@ -6483,7 +6474,7 @@ case 336:
     ;
     break;}
 case 337:
-#line 3339 "Gmsh.y"
+#line 3330 "Gmsh.y"
 { 
       char* (*pStrOpt)(int num, int action, char *value);
       StringXString *pStrCat;
@@ -6507,7 +6498,7 @@ case 337:
     ;
     break;}
 case 338:
-#line 3361 "Gmsh.y"
+#line 3352 "Gmsh.y"
 { 
       char* (*pStrOpt)(int num, int action, char *value);
       StringXString *pStrCat;
@@ -6752,7 +6743,7 @@ yyerrhandle:
     }
   return 1;
 }
-#line 3384 "Gmsh.y"
+#line 3375 "Gmsh.y"
 
 
 void DeleteSymbol(void *a, void *b){
diff --git a/Parser/Gmsh.y b/Parser/Gmsh.y
index 93d98a74c9..acf50af9f5 100644
--- a/Parser/Gmsh.y
+++ b/Parser/Gmsh.y
@@ -1,5 +1,5 @@
 %{
-// $Id: Gmsh.y,v 1.238 2006-11-25 03:30:03 geuzaine Exp $
+// $Id: Gmsh.y,v 1.239 2006-11-25 16:52:53 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -28,12 +28,10 @@
 #include "Numeric.h"
 #include "Context.h"
 #include "Geo.h"
+#include "GeoInterpolation.h"
 #include "GeoUtils.h"
-#include "Nurbs.h"
-#include "CAD.h"
-#include "Mesh.h"
+#include "Generator.h"
 #include "Draw.h"
-#include "Create.h"
 #include "Views.h"
 #include "Options.h"
 #include "Colors.h"
@@ -45,13 +43,6 @@
 #include "OS.h"
 #include "CreateFile.h"
 
-#include "GModel.h"
-#include "gmshVertex.h"
-#include "gmshEdge.h"
-#include "gmshFace.h"
-#include "gmshRegion.h"
-extern GModel *GMODEL;
-
 Tree_T *Symbol_T = NULL;
 
 extern Context_T CTX;
diff --git a/Parser/Gmsh.yy.cpp b/Parser/Gmsh.yy.cpp
index ce26e1a7c1..1bd4495dbe 100644
--- a/Parser/Gmsh.yy.cpp
+++ b/Parser/Gmsh.yy.cpp
@@ -2,7 +2,7 @@
 /* A lexical scanner generated by flex */
 
 /* Scanner skeleton version:
- * $Header: /cvsroot/gmsh/Parser/Gmsh.yy.cpp,v 1.277 2006-11-25 03:30:03 geuzaine Exp $
+ * $Header: /cvsroot/gmsh/Parser/Gmsh.yy.cpp,v 1.278 2006-11-25 16:52:53 geuzaine Exp $
  */
 
 #define FLEX_SCANNER
@@ -727,7 +727,7 @@ char *yytext;
 #line 1 "Gmsh.l"
 #define INITIAL 0
 #line 2 "Gmsh.l"
-// $Id: Gmsh.yy.cpp,v 1.277 2006-11-25 03:30:03 geuzaine Exp $
+// $Id: Gmsh.yy.cpp,v 1.278 2006-11-25 16:52:53 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -756,7 +756,6 @@ char *yytext;
 #include "Gmsh.h"
 #include "Numeric.h"
 #include "Geo.h"
-#include "CAD.h"
 #include "Gmsh.tab.hpp"
 
 char yyname[256] = "";
@@ -789,7 +788,7 @@ void   skipline(void);
 	     && ferror( yyin ) )					\
      Msg(FATAL, "Input in flex scanner failed");
 
-#line 793 "Gmsh.yy.cpp"
+#line 792 "Gmsh.yy.cpp"
 
 /* Macros after this point can all be overridden by user definitions in
  * section 1.
@@ -940,10 +939,10 @@ YY_DECL
 	register char *yy_cp, *yy_bp;
 	register int yy_act;
 
-#line 80 "Gmsh.l"
+#line 79 "Gmsh.l"
 
 
-#line 947 "Gmsh.yy.cpp"
+#line 946 "Gmsh.yy.cpp"
 
 	if ( yy_init )
 		{
@@ -1028,711 +1027,711 @@ do_action:	/* This label is used only to access EOF actions. */
 
 case 1:
 YY_RULE_SETUP
-#line 82 "Gmsh.l"
+#line 81 "Gmsh.l"
 /* none */;
 	YY_BREAK
 case 2:
 YY_RULE_SETUP
-#line 83 "Gmsh.l"
+#line 82 "Gmsh.l"
 return tEND;
 	YY_BREAK
 case 3:
 YY_RULE_SETUP
-#line 84 "Gmsh.l"
+#line 83 "Gmsh.l"
 skipcomments();
 	YY_BREAK
 case 4:
 YY_RULE_SETUP
-#line 85 "Gmsh.l"
+#line 84 "Gmsh.l"
 skipline();
 	YY_BREAK
 case 5:
 YY_RULE_SETUP
-#line 86 "Gmsh.l"
+#line 85 "Gmsh.l"
 {parsestring('\"'); return tBIGSTR;}
 	YY_BREAK
 case 6:
 YY_RULE_SETUP
-#line 87 "Gmsh.l"
+#line 86 "Gmsh.l"
 {parsestring('\''); return tBIGSTR;}
 	YY_BREAK
 case 7:
 YY_RULE_SETUP
-#line 88 "Gmsh.l"
+#line 87 "Gmsh.l"
 {yylval.d = NEWREG(); return tDOUBLE;}
 	YY_BREAK
 case 8:
 YY_RULE_SETUP
-#line 89 "Gmsh.l"
+#line 88 "Gmsh.l"
 {yylval.d = NEWPOINT(); return tDOUBLE;}
 	YY_BREAK
 case 9:
 YY_RULE_SETUP
-#line 90 "Gmsh.l"
+#line 89 "Gmsh.l"
 {yylval.d = NEWLINE(); return tDOUBLE;}
 	YY_BREAK
 case 10:
 YY_RULE_SETUP
-#line 91 "Gmsh.l"
+#line 90 "Gmsh.l"
 {yylval.d = NEWLINE(); return tDOUBLE;}
 	YY_BREAK
 case 11:
 YY_RULE_SETUP
-#line 92 "Gmsh.l"
+#line 91 "Gmsh.l"
 {yylval.d = NEWLINELOOP(); return tDOUBLE;}
 	YY_BREAK
 case 12:
 YY_RULE_SETUP
-#line 93 "Gmsh.l"
+#line 92 "Gmsh.l"
 {yylval.d = NEWSURFACE(); return tDOUBLE;}
 	YY_BREAK
 case 13:
 YY_RULE_SETUP
-#line 94 "Gmsh.l"
+#line 93 "Gmsh.l"
 {yylval.d = NEWSURFACELOOP(); return tDOUBLE;}
 	YY_BREAK
 case 14:
 YY_RULE_SETUP
-#line 95 "Gmsh.l"
+#line 94 "Gmsh.l"
 {yylval.d = NEWVOLUME(); return tDOUBLE;}
 	YY_BREAK
 case 15:
 YY_RULE_SETUP
-#line 96 "Gmsh.l"
+#line 95 "Gmsh.l"
 return tAFFECT;
 	YY_BREAK
 case 16:
 YY_RULE_SETUP
-#line 97 "Gmsh.l"
+#line 96 "Gmsh.l"
 return tAFFECTPLUS;
 	YY_BREAK
 case 17:
 YY_RULE_SETUP
-#line 98 "Gmsh.l"
+#line 97 "Gmsh.l"
 return tAFFECTMINUS;
 	YY_BREAK
 case 18:
 YY_RULE_SETUP
-#line 99 "Gmsh.l"
+#line 98 "Gmsh.l"
 return tAFFECTTIMES;
 	YY_BREAK
 case 19:
 YY_RULE_SETUP
-#line 100 "Gmsh.l"
+#line 99 "Gmsh.l"
 return tAFFECTDIVIDE;
 	YY_BREAK
 case 20:
 YY_RULE_SETUP
-#line 101 "Gmsh.l"
+#line 100 "Gmsh.l"
 return tDOTS;
 	YY_BREAK
 case 21:
 YY_RULE_SETUP
-#line 102 "Gmsh.l"
+#line 101 "Gmsh.l"
 return tDOTS;
 	YY_BREAK
 case 22:
 YY_RULE_SETUP
-#line 103 "Gmsh.l"
+#line 102 "Gmsh.l"
 return tCROSSPRODUCT;
 	YY_BREAK
 case 23:
 YY_RULE_SETUP
-#line 104 "Gmsh.l"
+#line 103 "Gmsh.l"
 return tOR;
 	YY_BREAK
 case 24:
 YY_RULE_SETUP
-#line 105 "Gmsh.l"
+#line 104 "Gmsh.l"
 return tAND;
 	YY_BREAK
 case 25:
 YY_RULE_SETUP
-#line 106 "Gmsh.l"
+#line 105 "Gmsh.l"
 return tPLUSPLUS;
 	YY_BREAK
 case 26:
 YY_RULE_SETUP
-#line 107 "Gmsh.l"
+#line 106 "Gmsh.l"
 return tMINUSMINUS;
 	YY_BREAK
 case 27:
 YY_RULE_SETUP
-#line 108 "Gmsh.l"
+#line 107 "Gmsh.l"
 return tEQUAL;
 	YY_BREAK
 case 28:
 YY_RULE_SETUP
-#line 109 "Gmsh.l"
+#line 108 "Gmsh.l"
 return tNOTEQUAL;
 	YY_BREAK
 case 29:
 YY_RULE_SETUP
-#line 110 "Gmsh.l"
+#line 109 "Gmsh.l"
 return tAPPROXEQUAL;
 	YY_BREAK
 case 30:
 YY_RULE_SETUP
-#line 111 "Gmsh.l"
+#line 110 "Gmsh.l"
 return tLESSOREQUAL;
 	YY_BREAK
 case 31:
 YY_RULE_SETUP
-#line 112 "Gmsh.l"
+#line 111 "Gmsh.l"
 return tGREATEROREQUAL;
 	YY_BREAK
 case 32:
 YY_RULE_SETUP
-#line 114 "Gmsh.l"
+#line 113 "Gmsh.l"
 return tAcos;
 	YY_BREAK
 case 33:
 YY_RULE_SETUP
-#line 115 "Gmsh.l"
+#line 114 "Gmsh.l"
 return tAcos;
 	YY_BREAK
 case 34:
 YY_RULE_SETUP
-#line 116 "Gmsh.l"
+#line 115 "Gmsh.l"
 return tAlias;
 	YY_BREAK
 case 35:
 YY_RULE_SETUP
-#line 117 "Gmsh.l"
+#line 116 "Gmsh.l"
 return tAliasWithOptions;
 	YY_BREAK
 case 36:
 YY_RULE_SETUP
-#line 118 "Gmsh.l"
+#line 117 "Gmsh.l"
 return tAsin;
 	YY_BREAK
 case 37:
 YY_RULE_SETUP
-#line 119 "Gmsh.l"
+#line 118 "Gmsh.l"
 return tAsin;
 	YY_BREAK
 case 38:
 YY_RULE_SETUP
-#line 120 "Gmsh.l"
+#line 119 "Gmsh.l"
 return tAtan;
 	YY_BREAK
 case 39:
 YY_RULE_SETUP
-#line 121 "Gmsh.l"
+#line 120 "Gmsh.l"
 return tAtan;
 	YY_BREAK
 case 40:
 YY_RULE_SETUP
-#line 122 "Gmsh.l"
+#line 121 "Gmsh.l"
 return tAtan2;
 	YY_BREAK
 case 41:
 YY_RULE_SETUP
-#line 123 "Gmsh.l"
+#line 122 "Gmsh.l"
 return tAtan2;
 	YY_BREAK
 case 42:
 YY_RULE_SETUP
-#line 124 "Gmsh.l"
+#line 123 "Gmsh.l"
 return tAttractor;
 	YY_BREAK
 case 43:
 YY_RULE_SETUP
-#line 126 "Gmsh.l"
+#line 125 "Gmsh.l"
 return tBezier;
 	YY_BREAK
 case 44:
 YY_RULE_SETUP
-#line 127 "Gmsh.l"
+#line 126 "Gmsh.l"
 return tBump;
 	YY_BREAK
 case 45:
 YY_RULE_SETUP
-#line 128 "Gmsh.l"
+#line 127 "Gmsh.l"
 return tBSpline;
 	YY_BREAK
 case 46:
 YY_RULE_SETUP
-#line 129 "Gmsh.l"
+#line 128 "Gmsh.l"
 return tBounds;
 	YY_BREAK
 case 47:
 YY_RULE_SETUP
-#line 130 "Gmsh.l"
+#line 129 "Gmsh.l"
 return tBoundingBox;
 	YY_BREAK
 case 48:
 YY_RULE_SETUP
-#line 132 "Gmsh.l"
+#line 131 "Gmsh.l"
 return tCeil;
 	YY_BREAK
 case 49:
 YY_RULE_SETUP
-#line 133 "Gmsh.l"
+#line 132 "Gmsh.l"
 return tCombine;
 	YY_BREAK
 case 50:
 YY_RULE_SETUP
-#line 134 "Gmsh.l"
+#line 133 "Gmsh.l"
 return tCosh;
 	YY_BREAK
 case 51:
 YY_RULE_SETUP
-#line 135 "Gmsh.l"
+#line 134 "Gmsh.l"
 return tCos;
 	YY_BREAK
 case 52:
 YY_RULE_SETUP
-#line 136 "Gmsh.l"
+#line 135 "Gmsh.l"
 return tCharacteristic;
 	YY_BREAK
 case 53:
 YY_RULE_SETUP
-#line 137 "Gmsh.l"
+#line 136 "Gmsh.l"
 return tCircle;
 	YY_BREAK
 case 54:
 YY_RULE_SETUP
-#line 138 "Gmsh.l"
+#line 137 "Gmsh.l"
 return tCoherence;
 	YY_BREAK
 case 55:
 YY_RULE_SETUP
-#line 139 "Gmsh.l"
+#line 138 "Gmsh.l"
 return tComplex;
 	YY_BREAK
 case 56:
 YY_RULE_SETUP
-#line 140 "Gmsh.l"
+#line 139 "Gmsh.l"
 return tColor;
 	YY_BREAK
 case 57:
 YY_RULE_SETUP
-#line 141 "Gmsh.l"
+#line 140 "Gmsh.l"
 return tColorTable;
 	YY_BREAK
 case 58:
 YY_RULE_SETUP
-#line 142 "Gmsh.l"
+#line 141 "Gmsh.l"
 return tSpline;
 	YY_BREAK
 case 59:
 YY_RULE_SETUP
-#line 143 "Gmsh.l"
+#line 142 "Gmsh.l"
 return tCall;
 	YY_BREAK
 case 60:
 YY_RULE_SETUP
-#line 145 "Gmsh.l"
+#line 144 "Gmsh.l"
 return tDelete;
 	YY_BREAK
 case 61:
 YY_RULE_SETUP
-#line 146 "Gmsh.l"
+#line 145 "Gmsh.l"
 return tDilate;
 	YY_BREAK
 case 62:
 YY_RULE_SETUP
-#line 147 "Gmsh.l"
+#line 146 "Gmsh.l"
 return tDuplicata;
 	YY_BREAK
 case 63:
 YY_RULE_SETUP
-#line 148 "Gmsh.l"
+#line 147 "Gmsh.l"
 return tDraw;
 	YY_BREAK
 case 64:
 YY_RULE_SETUP
-#line 150 "Gmsh.l"
+#line 149 "Gmsh.l"
 return tExp;
 	YY_BREAK
 case 65:
 YY_RULE_SETUP
-#line 151 "Gmsh.l"
+#line 150 "Gmsh.l"
 return tEllipse;
 	YY_BREAK
 case 66:
 YY_RULE_SETUP
-#line 152 "Gmsh.l"
+#line 151 "Gmsh.l"
 return tEllipse;
 	YY_BREAK
 case 67:
 YY_RULE_SETUP
-#line 153 "Gmsh.l"
+#line 152 "Gmsh.l"
 return tExtrude;
 	YY_BREAK
 case 68:
 YY_RULE_SETUP
-#line 154 "Gmsh.l"
+#line 153 "Gmsh.l"
 return tElliptic;
 	YY_BREAK
 case 69:
 YY_RULE_SETUP
-#line 155 "Gmsh.l"
+#line 154 "Gmsh.l"
 return tEndFor;
 	YY_BREAK
 case 70:
 YY_RULE_SETUP
-#line 156 "Gmsh.l"
+#line 155 "Gmsh.l"
 return tEndIf;
 	YY_BREAK
 case 71:
 YY_RULE_SETUP
-#line 157 "Gmsh.l"
+#line 156 "Gmsh.l"
 return tExit;
 	YY_BREAK
 case 72:
 YY_RULE_SETUP
-#line 159 "Gmsh.l"
+#line 158 "Gmsh.l"
 return tFabs;
 	YY_BREAK
 case 73:
 YY_RULE_SETUP
-#line 160 "Gmsh.l"
+#line 159 "Gmsh.l"
 return tFloor;
 	YY_BREAK
 case 74:
 YY_RULE_SETUP
-#line 161 "Gmsh.l"
+#line 160 "Gmsh.l"
 return tFmod;
 	YY_BREAK
 case 75:
 YY_RULE_SETUP
-#line 162 "Gmsh.l"
+#line 161 "Gmsh.l"
 return tFor;
 	YY_BREAK
 case 76:
 YY_RULE_SETUP
-#line 163 "Gmsh.l"
+#line 162 "Gmsh.l"
 return tFunction;
 	YY_BREAK
 case 77:
 YY_RULE_SETUP
-#line 165 "Gmsh.l"
+#line 164 "Gmsh.l"
 return tGetValue;
 	YY_BREAK
 case 78:
 YY_RULE_SETUP
-#line 166 "Gmsh.l"
+#line 165 "Gmsh.l"
 return tGMSH_MAJOR_VERSION;
 	YY_BREAK
 case 79:
 YY_RULE_SETUP
-#line 167 "Gmsh.l"
+#line 166 "Gmsh.l"
 return tGMSH_MINOR_VERSION;
 	YY_BREAK
 case 80:
 YY_RULE_SETUP
-#line 168 "Gmsh.l"
+#line 167 "Gmsh.l"
 return tGMSH_PATCH_VERSION;
 	YY_BREAK
 case 81:
 YY_RULE_SETUP
-#line 170 "Gmsh.l"
+#line 169 "Gmsh.l"
 return tHide;
 	YY_BREAK
 case 82:
 YY_RULE_SETUP
-#line 171 "Gmsh.l"
+#line 170 "Gmsh.l"
 return tHypot;
 	YY_BREAK
 case 83:
 YY_RULE_SETUP
-#line 173 "Gmsh.l"
+#line 172 "Gmsh.l"
 return tIn;
 	YY_BREAK
 case 84:
 YY_RULE_SETUP
-#line 174 "Gmsh.l"
+#line 173 "Gmsh.l"
 return tIf;
 	YY_BREAK
 case 85:
 YY_RULE_SETUP
-#line 175 "Gmsh.l"
+#line 174 "Gmsh.l"
 return tIntersect;
 	YY_BREAK
 case 86:
 YY_RULE_SETUP
-#line 177 "Gmsh.l"
+#line 176 "Gmsh.l"
 return tKnots;
 	YY_BREAK
 case 87:
 YY_RULE_SETUP
-#line 179 "Gmsh.l"
+#line 178 "Gmsh.l"
 return tLength;
 	YY_BREAK
 case 88:
 YY_RULE_SETUP
-#line 180 "Gmsh.l"
+#line 179 "Gmsh.l"
 return tLine;
 	YY_BREAK
 case 89:
 YY_RULE_SETUP
-#line 181 "Gmsh.l"
+#line 180 "Gmsh.l"
 return tLoop;
 	YY_BREAK
 case 90:
 YY_RULE_SETUP
-#line 182 "Gmsh.l"
+#line 181 "Gmsh.l"
 return tLog;
 	YY_BREAK
 case 91:
 YY_RULE_SETUP
-#line 183 "Gmsh.l"
+#line 182 "Gmsh.l"
 return tLog10;
 	YY_BREAK
 case 92:
 YY_RULE_SETUP
-#line 184 "Gmsh.l"
+#line 183 "Gmsh.l"
 return tLayers;
 	YY_BREAK
 case 93:
 YY_RULE_SETUP
-#line 186 "Gmsh.l"
+#line 185 "Gmsh.l"
 return tModulo;
 	YY_BREAK
 case 94:
 YY_RULE_SETUP
-#line 187 "Gmsh.l"
+#line 186 "Gmsh.l"
 return tMPI_Rank;
 	YY_BREAK
 case 95:
 YY_RULE_SETUP
-#line 188 "Gmsh.l"
+#line 187 "Gmsh.l"
 return tMPI_Size;
 	YY_BREAK
 case 96:
 YY_RULE_SETUP
-#line 190 "Gmsh.l"
+#line 189 "Gmsh.l"
 return tNurbs;
 	YY_BREAK
 case 97:
 YY_RULE_SETUP
-#line 192 "Gmsh.l"
+#line 191 "Gmsh.l"
 return tOrder;
 	YY_BREAK
 case 98:
 YY_RULE_SETUP
-#line 194 "Gmsh.l"
+#line 193 "Gmsh.l"
 return tPhysical;
 	YY_BREAK
 case 99:
 YY_RULE_SETUP
-#line 195 "Gmsh.l"
+#line 194 "Gmsh.l"
 return tPi;
 	YY_BREAK
 case 100:
 YY_RULE_SETUP
-#line 196 "Gmsh.l"
+#line 195 "Gmsh.l"
 return tPlane;
 	YY_BREAK
 case 101:
 YY_RULE_SETUP
-#line 197 "Gmsh.l"
+#line 196 "Gmsh.l"
 return tPoint;
 	YY_BREAK
 case 102:
 YY_RULE_SETUP
-#line 198 "Gmsh.l"
+#line 197 "Gmsh.l"
 return tProgression;
 	YY_BREAK
 case 103:
 YY_RULE_SETUP
-#line 199 "Gmsh.l"
+#line 198 "Gmsh.l"
 return tProgression;
 	YY_BREAK
 case 104:
 YY_RULE_SETUP
-#line 200 "Gmsh.l"
+#line 199 "Gmsh.l"
 return tParametric;
 	YY_BREAK
 case 105:
 YY_RULE_SETUP
-#line 201 "Gmsh.l"
+#line 200 "Gmsh.l"
 return tPrintf;
 	YY_BREAK
 case 106:
 YY_RULE_SETUP
-#line 202 "Gmsh.l"
+#line 201 "Gmsh.l"
 return tPlugin;
 	YY_BREAK
 case 107:
 YY_RULE_SETUP
-#line 204 "Gmsh.l"
+#line 203 "Gmsh.l"
 return tRecombine;
 	YY_BREAK
 case 108:
 YY_RULE_SETUP
-#line 205 "Gmsh.l"
+#line 204 "Gmsh.l"
 return tRotate;
 	YY_BREAK
 case 109:
 YY_RULE_SETUP
-#line 206 "Gmsh.l"
+#line 205 "Gmsh.l"
 return tRuled;
 	YY_BREAK
 case 110:
 YY_RULE_SETUP
-#line 207 "Gmsh.l"
+#line 206 "Gmsh.l"
 return tRand;
 	YY_BREAK
 case 111:
 YY_RULE_SETUP
-#line 208 "Gmsh.l"
+#line 207 "Gmsh.l"
 return tReturn;
 	YY_BREAK
 case 112:
 YY_RULE_SETUP
-#line 210 "Gmsh.l"
+#line 209 "Gmsh.l"
 return tSqrt;
 	YY_BREAK
 case 113:
 YY_RULE_SETUP
-#line 211 "Gmsh.l"
+#line 210 "Gmsh.l"
 return tSin;
 	YY_BREAK
 case 114:
 YY_RULE_SETUP
-#line 212 "Gmsh.l"
+#line 211 "Gmsh.l"
 return tSinh;
 	YY_BREAK
 case 115:
 YY_RULE_SETUP
-#line 213 "Gmsh.l"
+#line 212 "Gmsh.l"
 return tSpline;
 	YY_BREAK
 case 116:
 YY_RULE_SETUP
-#line 214 "Gmsh.l"
+#line 213 "Gmsh.l"
 return tSurface;
 	YY_BREAK
 case 117:
 YY_RULE_SETUP
-#line 215 "Gmsh.l"
+#line 214 "Gmsh.l"
 return tSymmetry;
 	YY_BREAK
 case 118:
 YY_RULE_SETUP
-#line 216 "Gmsh.l"
+#line 215 "Gmsh.l"
 return tSprintf;
 	YY_BREAK
 case 119:
 YY_RULE_SETUP
-#line 217 "Gmsh.l"
+#line 216 "Gmsh.l"
 return tStrCat;
 	YY_BREAK
 case 120:
 YY_RULE_SETUP
-#line 218 "Gmsh.l"
+#line 217 "Gmsh.l"
 return tStrPrefix;
 	YY_BREAK
 case 121:
 YY_RULE_SETUP
-#line 219 "Gmsh.l"
+#line 218 "Gmsh.l"
 return tStrRelative;
 	YY_BREAK
 case 122:
 YY_RULE_SETUP
-#line 220 "Gmsh.l"
+#line 219 "Gmsh.l"
 return tShow;
 	YY_BREAK
 case 123:
 YY_RULE_SETUP
-#line 222 "Gmsh.l"
+#line 221 "Gmsh.l"
 return tTransfinite;
 	YY_BREAK
 case 124:
 YY_RULE_SETUP
-#line 223 "Gmsh.l"
+#line 222 "Gmsh.l"
 return tTranslate;
 	YY_BREAK
 case 125:
 YY_RULE_SETUP
-#line 224 "Gmsh.l"
+#line 223 "Gmsh.l"
 return tTanh;
 	YY_BREAK
 case 126:
 YY_RULE_SETUP
-#line 225 "Gmsh.l"
+#line 224 "Gmsh.l"
 return tTan;
 	YY_BREAK
 case 127:
 YY_RULE_SETUP
-#line 226 "Gmsh.l"
+#line 225 "Gmsh.l"
 return tTrimmed;
 	YY_BREAK
 case 128:
 YY_RULE_SETUP
-#line 227 "Gmsh.l"
+#line 226 "Gmsh.l"
 return tToday;
 	YY_BREAK
 case 129:
 YY_RULE_SETUP
-#line 229 "Gmsh.l"
+#line 228 "Gmsh.l"
 return tUsing;
 	YY_BREAK
 case 130:
 YY_RULE_SETUP
-#line 231 "Gmsh.l"
+#line 230 "Gmsh.l"
 return tVolume;
 	YY_BREAK
 case 131:
 YY_RULE_SETUP
-#line 233 "Gmsh.l"
+#line 232 "Gmsh.l"
 return tWith;
 	YY_BREAK
 case 132:
 YY_RULE_SETUP
-#line 235 "Gmsh.l"
+#line 234 "Gmsh.l"
 return tText2D;
 	YY_BREAK
 case 133:
 YY_RULE_SETUP
-#line 236 "Gmsh.l"
+#line 235 "Gmsh.l"
 return tText3D;
 	YY_BREAK
 case 134:
 YY_RULE_SETUP
-#line 237 "Gmsh.l"
+#line 236 "Gmsh.l"
 return tInterpolationScheme;
 	YY_BREAK
 case 135:
 YY_RULE_SETUP
-#line 238 "Gmsh.l"
+#line 237 "Gmsh.l"
 return tTime;
 	YY_BREAK
 case 136:
 YY_RULE_SETUP
-#line 239 "Gmsh.l"
+#line 238 "Gmsh.l"
 return tGrain;
 	YY_BREAK
 case 137:
-#line 242 "Gmsh.l"
+#line 241 "Gmsh.l"
 case 138:
-#line 243 "Gmsh.l"
+#line 242 "Gmsh.l"
 case 139:
-#line 244 "Gmsh.l"
+#line 243 "Gmsh.l"
 case 140:
 YY_RULE_SETUP
-#line 244 "Gmsh.l"
+#line 243 "Gmsh.l"
 {yylval.d = atof((char *)yytext); return tDOUBLE;}
 	YY_BREAK
 case 141:
 YY_RULE_SETUP
-#line 246 "Gmsh.l"
+#line 245 "Gmsh.l"
 {yylval.c = strsave((char*)yytext); return tSTRING;}
 	YY_BREAK
 case 142:
 YY_RULE_SETUP
-#line 248 "Gmsh.l"
+#line 247 "Gmsh.l"
 return yytext[0];
 	YY_BREAK
 case 143:
 YY_RULE_SETUP
-#line 250 "Gmsh.l"
+#line 249 "Gmsh.l"
 ECHO;
 	YY_BREAK
-#line 1736 "Gmsh.yy.cpp"
+#line 1735 "Gmsh.yy.cpp"
 case YY_STATE_EOF(INITIAL):
 	yyterminate();
 
@@ -2618,7 +2617,7 @@ int main()
 	return 0;
 	}
 #endif
-#line 250 "Gmsh.l"
+#line 249 "Gmsh.l"
 
 
 #undef yywrap
diff --git a/Parser/Makefile b/Parser/Makefile
index f2ee7e1af0..137f80e488 100644
--- a/Parser/Makefile
+++ b/Parser/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.108 2006-11-25 02:47:41 geuzaine Exp $
+# $Id: Makefile,v 1.109 2006-11-25 16:52:53 geuzaine Exp $
 #
 # Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 #
@@ -83,33 +83,16 @@ Gmsh.tab.o: Gmsh.tab.cpp ../Plugin/PluginManager.h ../Plugin/Plugin.h \
   ../Common/AdaptiveViews.h ../Common/GmshMatrix.h ../Parallel/ParUtil.h \
   ../Common/Gmsh.h ../Common/Message.h ../DataStr/Malloc.h \
   ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h \
-  ../DataStr/Tree.h ../Common/Context.h ../Geo/Geo.h ../Geo/GeoUtils.h \
-  ../Mesh/Mesh.h ../Common/GmshDefines.h ../Mesh/Vertex.h \
-  ../Geo/ExtrudeParams.h ../Mesh/Nurbs.h ../Mesh/Vertex.h ../Mesh/Mesh.h \
-  ../Geo/CAD.h ../Geo/ExtrudeParams.h ../Graphics/Draw.h ../Mesh/Create.h \
-  ../Mesh/Vertex.h ../Mesh/Mesh.h ../Common/Colors.h ../Common/Options.h \
-  Parser.h OpenFile.h ../Common/CommandLine.h FunctionManager.h \
-  ../Common/OS.h CreateFile.h ../Geo/GModel.h ../Geo/GVertex.h \
-  ../Geo/GEntity.h ../Geo/Range.h ../Geo/SPoint3.h \
-  ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../Geo/MVertex.h \
-  ../Geo/SPoint3.h ../Geo/GPoint.h ../Geo/SPoint2.h ../Geo/GEdge.h \
-  ../Geo/GEntity.h ../Geo/GVertex.h ../Geo/SVector3.h ../Geo/SPoint3.h \
-  ../Geo/SPoint3.h ../Geo/SPoint2.h ../Geo/MElement.h ../Geo/MVertex.h \
-  ../Geo/MEdge.h ../Geo/MVertex.h ../Geo/SVector3.h ../Common/Hash.h \
-  ../Geo/MFace.h ../Geo/MVertex.h ../Geo/SVector3.h \
-  ../Geo/ExtrudeParams.h ../Geo/GFace.h ../Geo/GPoint.h ../Geo/GEntity.h \
-  ../Geo/GEdgeLoop.h ../Geo/GEdge.h ../Geo/MElement.h ../Geo/SPoint2.h \
-  ../Geo/SVector3.h ../Geo/Pair.h ../Geo/ExtrudeParams.h ../Geo/GRegion.h \
-  ../Geo/GEntity.h ../Geo/MElement.h ../Geo/ExtrudeParams.h \
-  ../Geo/SBoundingBox3d.h ../Geo/gmshVertex.h ../Geo/GVertex.h \
-  ../Geo/gmshEdge.h ../Geo/GEdge.h ../Geo/gmshVertex.h ../Geo/Range.h \
-  ../Geo/gmshFace.h ../Geo/GFace.h ../Geo/gmshVertex.h ../Geo/Range.h \
-  ../Geo/gmshRegion.h ../Geo/GRegion.h
+  ../DataStr/Tree.h ../Common/Context.h ../Geo/Geo.h \
+  ../Common/GmshDefines.h ../Geo/ExtrudeParams.h \
+  ../Geo/GeoInterpolation.h ../Geo/Geo.h ../Geo/GeoUtils.h ../Geo/Geo.h \
+  ../Mesh/Generator.h ../Graphics/Draw.h ../Common/Colors.h \
+  ../Common/Options.h Parser.h OpenFile.h ../Common/CommandLine.h \
+  FunctionManager.h ../Common/OS.h CreateFile.h
 Gmsh.yy.o: Gmsh.yy.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
   ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
-  ../Numeric/Numeric.h ../Geo/Geo.h ../Geo/CAD.h ../Mesh/Mesh.h \
-  ../Common/GmshDefines.h ../Mesh/Vertex.h ../Geo/ExtrudeParams.h \
+  ../Numeric/Numeric.h ../Geo/Geo.h ../Common/GmshDefines.h \
   ../Geo/ExtrudeParams.h Gmsh.tab.hpp
 OpenFile.o: OpenFile.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
@@ -127,26 +110,26 @@ OpenFile.o: OpenFile.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../Geo/MElement.h ../Geo/SPoint2.h ../Geo/SVector3.h ../Geo/Pair.h \
   ../Geo/ExtrudeParams.h ../Geo/GRegion.h ../Geo/GEntity.h \
   ../Geo/MElement.h ../Geo/ExtrudeParams.h ../Geo/SBoundingBox3d.h \
-  ../Common/SmoothNormals.h Parser.h OpenFile.h ../Common/CommandLine.h \
-  ../Common/Views.h ../Common/ColorTable.h ../Common/VertexArray.h \
-  ../Common/SmoothNormals.h ../Common/AdaptiveViews.h \
-  ../Common/GmshMatrix.h ../Mesh/Mesh.h ../Mesh/Vertex.h \
-  ../Graphics/ReadImg.h ../Common/OS.h ../Common/GmshUI.h \
-  ../Graphics/Draw.h ../Graphics/SelectBuffer.h ../Fltk/GUI.h \
-  ../Fltk/Opengl_Window.h ../Fltk/Colorbar_Window.h \
-  ../Fltk/Popup_Button.h ../Fltk/SpherePosition_Widget.h
+  ../Common/SmoothNormals.h Parser.h ../Mesh/Generator.h OpenFile.h \
+  ../Common/CommandLine.h ../Common/Views.h ../Common/ColorTable.h \
+  ../Common/VertexArray.h ../Common/SmoothNormals.h \
+  ../Common/AdaptiveViews.h ../Common/GmshMatrix.h ../Graphics/ReadImg.h \
+  ../Common/OS.h ../Common/GmshUI.h ../Graphics/Draw.h \
+  ../Graphics/SelectBuffer.h ../Fltk/GUI.h ../Fltk/Opengl_Window.h \
+  ../Fltk/Colorbar_Window.h ../Fltk/Popup_Button.h \
+  ../Fltk/SpherePosition_Widget.h
 CreateFile.o: CreateFile.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
   ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
   OpenFile.h ../Common/Context.h ../Common/Options.h ../Geo/Geo.h \
-  ../Geo/GModel.h ../Geo/GVertex.h ../Geo/GEntity.h ../Geo/Range.h \
-  ../Geo/SPoint3.h ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h \
-  ../Common/GmshDefines.h ../Geo/MVertex.h ../Geo/SPoint3.h \
-  ../Geo/GPoint.h ../Geo/SPoint2.h ../Geo/GEdge.h ../Geo/GEntity.h \
-  ../Geo/GVertex.h ../Geo/SVector3.h ../Geo/SPoint3.h ../Geo/SPoint3.h \
-  ../Geo/SPoint2.h ../Geo/MElement.h ../Geo/MVertex.h ../Geo/MEdge.h \
-  ../Geo/MVertex.h ../Geo/SVector3.h ../Common/Hash.h ../Geo/MFace.h \
-  ../Geo/MVertex.h ../Geo/SVector3.h ../Numeric/Numeric.h \
+  ../Common/GmshDefines.h ../Geo/ExtrudeParams.h ../Geo/GModel.h \
+  ../Geo/GVertex.h ../Geo/GEntity.h ../Geo/Range.h ../Geo/SPoint3.h \
+  ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../Geo/MVertex.h \
+  ../Geo/SPoint3.h ../Geo/GPoint.h ../Geo/SPoint2.h ../Geo/GEdge.h \
+  ../Geo/GEntity.h ../Geo/GVertex.h ../Geo/SVector3.h ../Geo/SPoint3.h \
+  ../Geo/SPoint3.h ../Geo/SPoint2.h ../Geo/MElement.h ../Geo/MVertex.h \
+  ../Geo/MEdge.h ../Geo/MVertex.h ../Geo/SVector3.h ../Common/Hash.h \
+  ../Geo/MFace.h ../Geo/MVertex.h ../Geo/SVector3.h ../Numeric/Numeric.h \
   ../Geo/ExtrudeParams.h ../Geo/GFace.h ../Geo/GPoint.h ../Geo/GEntity.h \
   ../Geo/GEdgeLoop.h ../Geo/GEdge.h ../Geo/MElement.h ../Geo/SPoint2.h \
   ../Geo/SVector3.h ../Geo/Pair.h ../Geo/ExtrudeParams.h ../Geo/GRegion.h \
diff --git a/Parser/OpenFile.cpp b/Parser/OpenFile.cpp
index 3c8dd3e83a..6c94266e0b 100644
--- a/Parser/OpenFile.cpp
+++ b/Parser/OpenFile.cpp
@@ -1,4 +1,4 @@
-// $Id: OpenFile.cpp,v 1.129 2006-11-22 02:39:18 geuzaine Exp $
+// $Id: OpenFile.cpp,v 1.130 2006-11-25 16:52:53 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -28,10 +28,10 @@
 #include "Numeric.h"
 #include "Context.h"
 #include "Parser.h"
+#include "Generator.h"
 #include "OpenFile.h"
 #include "CommandLine.h"
 #include "Views.h"
-#include "Mesh.h"
 #include "ReadImg.h"
 #include "OS.h"
 
diff --git a/Plugin/Makefile b/Plugin/Makefile
index 323ebb439b..68c06fcfca 100644
--- a/Plugin/Makefile
+++ b/Plugin/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.114 2006-11-25 02:47:41 geuzaine Exp $
+# $Id: Makefile,v 1.115 2006-11-25 16:52:53 geuzaine Exp $
 #
 # Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 #
@@ -156,10 +156,8 @@ Triangulate.o: Triangulate.cpp ../Common/Gmsh.h ../Common/Message.h \
   Plugin.h ../Common/Options.h ../Common/Views.h ../Common/ColorTable.h \
   ../Common/VertexArray.h ../Common/SmoothNormals.h ../Numeric/Numeric.h \
   ../Common/AdaptiveViews.h ../Common/GmshMatrix.h Triangulate.h \
-  ../Common/Context.h ../Geo/Geo.h ../Mesh/Mesh.h ../Common/GmshDefines.h \
-  ../Mesh/Vertex.h ../Geo/ExtrudeParams.h ../Mesh/Utils.h \
-  ../Mesh/Vertex.h ../Mesh/Mesh.h ../Mesh/Create.h ../Mesh/Vertex.h \
-  ../Mesh/Mesh.h
+  ../Common/Context.h ../Geo/Geo.h ../Common/GmshDefines.h \
+  ../Geo/ExtrudeParams.h ../Mesh/Utils.h
 Warp.o: Warp.cpp Plugin.h ../Common/Options.h ../Common/Message.h \
   ../Common/Views.h ../Common/ColorTable.h ../DataStr/List.h \
   ../Common/VertexArray.h ../Common/SmoothNormals.h ../Numeric/Numeric.h \
@@ -234,10 +232,9 @@ Annotate.o: Annotate.cpp Plugin.h ../Common/Options.h ../Common/Message.h \
   ../Common/VertexArray.h ../Common/SmoothNormals.h ../Numeric/Numeric.h \
   ../Common/AdaptiveViews.h ../Common/GmshMatrix.h Annotate.h \
   ../Common/Context.h ../Common/GmshUI.h ../Fltk/GUI.h \
-  ../Fltk/Opengl_Window.h ../Mesh/Mesh.h ../Common/GmshDefines.h \
-  ../DataStr/Tree.h ../DataStr/avl.h ../Mesh/Vertex.h \
-  ../Geo/ExtrudeParams.h ../Fltk/Colorbar_Window.h ../Fltk/Popup_Button.h \
-  ../Fltk/SpherePosition_Widget.h ../Graphics/Draw.h
+  ../Fltk/Opengl_Window.h ../Fltk/Colorbar_Window.h \
+  ../Fltk/Popup_Button.h ../Fltk/SpherePosition_Widget.h \
+  ../Graphics/Draw.h
 Remove.o: Remove.cpp Plugin.h ../Common/Options.h ../Common/Message.h \
   ../Common/Views.h ../Common/ColorTable.h ../DataStr/List.h \
   ../Common/VertexArray.h ../Common/SmoothNormals.h ../Numeric/Numeric.h \
diff --git a/Plugin/Triangulate.cpp b/Plugin/Triangulate.cpp
index 35f6bc1433..79a2241b25 100644
--- a/Plugin/Triangulate.cpp
+++ b/Plugin/Triangulate.cpp
@@ -1,4 +1,4 @@
-// $Id: Triangulate.cpp,v 1.30 2006-01-06 00:34:33 geuzaine Exp $
+// $Id: Triangulate.cpp,v 1.31 2006-11-25 16:52:53 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -28,9 +28,7 @@
 #include "Context.h"
 #include "Malloc.h"
 #include "Geo.h"
-#include "Mesh.h"
 #include "Utils.h"
-#include "Create.h"
 
 extern Context_T CTX;
 
-- 
GitLab