diff --git a/Mesh/3D_Bricks.cpp b/Mesh/3D_Bricks.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fec85ea54023d090fa2556efbe492565ef6207c2
--- /dev/null
+++ b/Mesh/3D_Bricks.cpp
@@ -0,0 +1,97 @@
+// $Id: 3D_Bricks.cpp,v 1.18 2006-01-28 18:44:19 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 "Mesh.h"
+
+void AddSimplexInGrid(Mesh * m, Simplex * s, int boule_boite)
+{
+  double XminBox = 0., XmaxBox = 0., YminBox = 0., YmaxBox = 0., ZmaxBox = 0., ZminBox = 0.;
+  int Ix1, Ix2, Iy1, Iy2, Iz1, Iz2;
+  int i, j, k, index;
+  Brick Br, *pBrick;
+
+  if(!m->Grid.init) {
+    m->Grid.Bricks =
+      List_Create(m->Grid.Nx * m->Grid.Ny * m->Grid.Nz, 10, sizeof(Brick));
+    for(i = 0; i < m->Grid.Nx * m->Grid.Ny * m->Grid.Nz; i++) {
+      Br.pT = List_Create(2, 2, sizeof(Simplex *));
+      Br.N = i + 1;
+      List_Add(m->Grid.Bricks, &Br);
+    }
+    m->Grid.init = 1;
+  }
+
+  if(boule_boite == BOITE) {
+    XminBox = XmaxBox = s->V[0]->Pos.X;
+    YminBox = YmaxBox = s->V[0]->Pos.Y;
+    ZminBox = ZmaxBox = s->V[0]->Pos.Z;
+    for(i = 1; i < 4; i++) {
+      XminBox = DMIN(XminBox, s->V[i]->Pos.X);
+      XmaxBox = DMAX(XmaxBox, s->V[i]->Pos.X);
+      YminBox = DMIN(YminBox, s->V[i]->Pos.Y);
+      YmaxBox = DMAX(YmaxBox, s->V[i]->Pos.Y);
+      ZminBox = DMIN(ZminBox, s->V[i]->Pos.Z);
+      ZmaxBox = DMAX(ZmaxBox, s->V[i]->Pos.Z);
+    }
+  }
+  else if(boule_boite == BOULE) {
+    XminBox = s->Center.X - s->Radius;
+    XmaxBox = s->Center.X + s->Radius;
+    YminBox = s->Center.Y - s->Radius;
+    YmaxBox = s->Center.Y + s->Radius;
+    ZminBox = s->Center.Z - s->Radius;
+    ZmaxBox = s->Center.Z + s->Radius;
+  }
+
+
+  Ix1 = (int)((double)m->Grid.Nx * (XminBox - m->Grid.min.X) /
+              (m->Grid.max.X - m->Grid.min.X));
+  Ix2 = (int)((double)m->Grid.Nx * (XmaxBox - m->Grid.min.X) /
+              (m->Grid.max.X - m->Grid.min.X));
+  Iy1 = (int)((double)m->Grid.Ny * (YminBox - m->Grid.min.Y) /
+              (m->Grid.max.Y - m->Grid.min.Y));
+  Iy2 = (int)((double)m->Grid.Ny * (YmaxBox - m->Grid.min.Y) /
+              (m->Grid.max.Y - m->Grid.min.Y));
+  Iz1 = (int)((double)m->Grid.Nz * (ZminBox - m->Grid.min.Z) /
+              (m->Grid.max.Z - m->Grid.min.Z));
+  Iz2 = (int)((double)m->Grid.Nz * (ZmaxBox - m->Grid.min.Z) /
+              (m->Grid.max.Z - m->Grid.min.Z));
+
+  Ix1 = IMAX(Ix1, 0);
+  Ix2 = IMIN(Ix2, m->Grid.Nx - 1);
+  Iy1 = IMAX(Iy1, 0);
+  Iy2 = IMIN(Iy2, m->Grid.Ny - 1);
+  Iz1 = IMAX(Iz1, 0);
+  Iz2 = IMIN(Iz2, m->Grid.Nz - 1);
+
+  for(i = Ix1; i <= Ix2; i++) {
+    for(j = Iy1; j <= Iy2; j++) {
+      for(k = Iz1; k <= Iz2; k++) {
+        index = i + j * m->Grid.Nx + k * m->Grid.Nx * m->Grid.Ny;
+        pBrick = (Brick *) List_Pointer(m->Grid.Bricks, index);
+        List_Add(pBrick->pT, &s);
+      }
+    }
+  }
+
+}
diff --git a/Mesh/3D_Mesh_Old.cpp b/Mesh/3D_Mesh_Old.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3066460bce67bee795a8272374a55507891832f2
--- /dev/null
+++ b/Mesh/3D_Mesh_Old.cpp
@@ -0,0 +1,874 @@
+// $Id: 3D_Mesh_Old.cpp,v 1.16 2006-01-28 18:44:19 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>.
+
+/*
+  Isotropic Delaunay 3D
+
+  tant que l'arbre des tetraedres de qualites inacceptables 
+  n'est pas vide {
+    prendre le plus mauvais tetraedre;
+    creer un nouveau point;
+    eliminer les tetraedres dont le cercle circonscrit contient le point;
+    reconstruire le volume convexe;
+  } 
+
+*/
+
+
+#include "Gmsh.h"
+#include "Numeric.h"
+#include "Mesh.h"
+#include "3D_Mesh.h"
+#include "Create.h"
+#include "Context.h"
+
+extern Mesh *THEM, *LOCAL;
+extern Context_T CTX;
+extern int FACE_DIMENSION;
+
+static Tree_T *Tsd, *Sim_Sur_Le_Bord, *POINTS_TREE;
+static List_T *Simplexes_Destroyed, *Simplexes_New, *Suppress;
+static List_T *LLL, *POINTS;
+static Simplex *THES;
+static Vertex *THEV;
+static Tree_T *SimXFac;
+static double volume, LC3D;
+static int ZONEELIMINEE, Methode = 0;
+
+Simplex MyNewBoundary;
+int Alerte_Point_Scabreux;
+
+void DebugSimplexe(Simplex * s)
+{
+  int i;
+
+  fprintf(stderr, "Simplexe %p = %d %d %d %d \n",
+          s, s->V[0]->Num, s->V[1]->Num, s->V[2]->Num, s->V[3]->Num);
+
+  for(i = 0; i < 4; i++) {
+    if(s->S[i] != &MyNewBoundary)
+      printf(" face : %d %d %d -> Simplexe %p\n",
+             s->F[i].V[0]->Num, s->F[i].V[1]->Num, s->F[i].V[2]->Num,
+             s->S[i]);
+    else
+      printf(" face : %d %d %d -> Simplexe Boundary\n",
+             s->F[i].V[0]->Num, s->F[i].V[1]->Num, s->F[i].V[2]->Num);
+  }
+}
+
+void VSIM(void *a, void *b)
+{
+  Simplex *S;
+
+  S = *(Simplex **) a;
+  if(S->V[3])
+    volume += fabs(S->Volume_Simplexe());
+}
+
+void add_points(void *a, void *b)
+{
+  Tree_Insert(POINTS_TREE, a);
+}
+
+void add_points_2(void *a, void *b)
+{
+  List_Add(POINTS, a);
+}
+
+
+double Interpole_lcTetraedre(Simplex * s, Vertex * v)
+{
+  double mat[3][3], rhs[3], sol[3], det;
+
+  s->matsimpl(mat);
+  rhs[0] = v->Pos.X - s->V[0]->Pos.X;
+  rhs[1] = v->Pos.Y - s->V[0]->Pos.Y;
+  rhs[2] = v->Pos.Z - s->V[0]->Pos.Z;
+
+  sys3x3(mat, rhs, sol, &det);
+  if(det == 0.0 ||
+     (1. - sol[0] - sol[1] - sol[2]) > 1. ||
+     (1. - sol[0] - sol[1] - sol[2]) < 0. ||
+     sol[0] > 1. ||
+     sol[1] > 1. ||
+     sol[2] > 1. || sol[0] < 0. || sol[1] < 0. || sol[2] < 0.) {
+    return DMAX(s->V[0]->lc,
+                DMAX(s->V[1]->lc, DMAX(s->V[2]->lc, s->V[3]->lc)));
+    //sol[0] = sol[1] = sol[2] = 0.25;
+  }
+
+  return (s->V[0]->lc * (1. - sol[0] - sol[1] - sol[2]) +
+          sol[0] * s->V[1]->lc + sol[1] * s->V[2]->lc + sol[2] * s->V[3]->lc);
+}
+
+Vertex *NewVertex(Simplex * s)
+{
+  Vertex *v;
+
+  v =
+    Create_Vertex(++THEM->MaxPointNum, s->Center.X, s->Center.Y, s->Center.Z,
+                  1., 0.0);
+  v->lc = Interpole_lcTetraedre(s, v);
+
+  return (v);
+}
+
+int Pt_In_Circum(Simplex * s, Vertex * v)
+{
+  double d1, d2, eps;
+
+  /* Determine si un point est dans le cercle circonscrit a un simplexe */
+
+  d1 = s->Radius;
+  d2 = sqrt(DSQR(v->Pos.X - s->Center.X) +
+            DSQR(v->Pos.Y - s->Center.Y) + DSQR(v->Pos.Z - s->Center.Z));
+
+  eps = fabs(d1 - d2) / (d1 + d2);
+
+  if(eps < 1.e-12) {
+    return (0); // return 1 ? 0 ?
+  }
+
+  if(d2 < d1)
+    return (1);
+
+  return (0);
+}
+
+void Action_First_Simplexes(void *a, void *b)
+{
+  Simplex **q;
+
+  if(!THES) {
+    q = (Simplex **) a;
+    if(Pt_In_Circum(*q, THEV)) {
+      THES = *q;
+    }
+  }
+}
+
+void LiS(void *a, void *b)
+{
+  int j, N;
+  SxF SXF, *pSXF;
+  Simplex **pS, *S;
+
+  pS = (Simplex **) a;
+  S = *pS;
+  N = (S->V[3]) ? 4 : 3;
+
+  for(j = 0; j < N; j++) {
+    SXF.F = S->F[j];
+    if((pSXF = (SxF *) Tree_PQuery(SimXFac, &SXF))) {
+      /* Creation du lien */
+      S->S[j] = pSXF->S;
+      pSXF->S->S[pSXF->NumFaceSimpl] = S;
+    }
+    else {
+      SXF.S = S;
+      SXF.NumFaceSimpl = j;
+      Tree_Add(SimXFac, &SXF);
+    }
+  }
+}
+
+void RzS(void *a, void *b)
+{
+  int j, N;
+  Simplex **pS, *S;
+  pS = (Simplex **) a;
+  S = *pS;
+
+  N = (S->V[3]) ? 4 : 3;
+
+  for(j = 0; j < N; j++) {
+    if((S->S[j]) == NULL) {
+      S->S[j] = &MyNewBoundary;
+    }
+  }
+}
+
+/* Cree les liens entre les simplexes, c.a.d recherche les voisins */
+
+void Link_Simplexes(List_T * Sim, Tree_T * Tim)
+{
+  Simplex *S;
+  int i;
+
+  SimXFac = Tree_Create(sizeof(SxF), compareSxF);
+  if(Sim) {
+    for(i = 0; i < List_Nbr(Sim); i++) {
+      List_Read(Sim, i, &S);
+      LiS(&S, NULL);
+    }
+    for(i = 0; i < List_Nbr(Sim); i++) {
+      List_Read(Sim, i, &S);
+      RzS(&S, NULL);
+    }
+  }
+  else {
+    Tree_Action(Tim, LiS);
+    Tree_Action(Tim, RzS);
+  }
+  Tree_Delete(SimXFac);
+}
+
+void Box_6_Tetraedron(List_T * P, Mesh * m)
+{
+#define FACT 1.1
+#define LOIN 0.2
+
+  int i, j;
+  static int pts[8][3] = { {0, 0, 0},
+  {1, 0, 0},
+  {1, 1, 0},
+  {0, 1, 0},
+  {0, 0, 1},
+  {1, 0, 1},
+  {1, 1, 1},
+  {0, 1, 1}
+  };
+  static int tet[6][4] = { {1, 5, 2, 4},
+  {2, 5, 6, 4},
+  {4, 5, 6, 8},
+  {6, 4, 8, 7},
+  {6, 4, 7, 3},
+  {2, 3, 4, 6}
+  };
+  double Xm, Ym, Zm, XM, YM, ZM, Xc, Yc, Zc;
+  Simplex *S, *ps;
+  Vertex *V, *v, *pv;
+  List_T *smp;
+
+  smp = List_Create(8, 1, sizeof(Simplex *));
+
+  V = (Vertex *) Malloc(8 * sizeof(Vertex));
+
+  for(i = 0; i < List_Nbr(P); i++) {
+    List_Read(P, i, &v);
+    if(!i) {
+      Xm = XM = v->Pos.X;
+      Ym = YM = v->Pos.Y;
+      Zm = ZM = v->Pos.Z;
+    }
+    else {
+      Xm = DMIN(Xm, v->Pos.X);
+      XM = DMAX(XM, v->Pos.X);
+      Ym = DMIN(Ym, v->Pos.Y);
+      YM = DMAX(YM, v->Pos.Y);
+      Zm = DMIN(Zm, v->Pos.Z);
+      ZM = DMAX(ZM, v->Pos.Z);
+    }
+  }
+  if(Xm == XM)
+    XM = Xm + 1.;
+  if(Ym == YM)
+    YM = Ym + 1.;
+  if(Zm == ZM)
+    ZM = Zm + 1.;
+
+  Xc = XM - Xm;
+  Yc = YM - Ym;
+  Zc = ZM - Zm;
+
+  /* initialisation de la grille */
+
+  m->Grid.init = 0;
+  m->Grid.min.X = Xm - LOIN * FACT * Xc;
+  m->Grid.min.Y = Ym - LOIN * FACT * Yc;
+  m->Grid.min.Z = Zm - LOIN * FACT * Zc;
+  m->Grid.max.X = XM + LOIN * FACT * Xc;
+  m->Grid.max.Y = YM + LOIN * FACT * Yc;
+  m->Grid.max.Z = ZM + LOIN * FACT * Zc;
+
+  m->Grid.Nx = m->Grid.Ny = m->Grid.Nz = 20;
+
+  /* Longueur Caracteristique */
+
+  LC3D = sqrt(Xc * Xc + Yc * Yc + Zc * Zc);
+
+  /* Points de la boite de 1 a 8 
+
+     Z    8____________7
+     |   /|           /|
+     |  / |          / |
+     | /  |         /  |
+     5|/___|________/6  |
+     |   4|________|___|3
+     |   /         |   /
+     |  / Y        |  /
+     | /           | /
+     |/____________|/___ X
+     1             2
+
+   */
+
+  for(i = 0; i < 8; i++) {
+    if(pts[i][0])
+      V[i].Pos.X = Xm - LOIN * Xc;
+    else
+      V[i].Pos.X = XM + LOIN * Xc;
+
+    if(pts[i][1])
+      V[i].Pos.Y = Ym - LOIN * Yc;
+    else
+      V[i].Pos.Y = YM + LOIN * Yc;
+
+    if(pts[i][2])
+      V[i].Pos.Z = Zm - LOIN * Zc;
+    else
+      V[i].Pos.Z = ZM + LOIN * Zc;
+
+    V[i].Num = -(++THEM->MaxPointNum);
+    pv = &V[i];
+    pv->lc = 1.0;
+    pv->Mov = NULL;
+    Tree_Replace(m->Vertices, &pv);
+  }
+
+  /* 6 Tetraedres forment le maillage de la boite */
+
+  for(i = 0; i < 6; i++) {
+    S = Create_Simplex(&V[tet[i][0] - 1], &V[tet[i][1] - 1],
+                       &V[tet[i][2] - 1], &V[tet[i][3] - 1]);
+    List_Add(smp, &S);
+  }
+
+  Link_Simplexes(smp, NULL);
+  for(i = 0; i < List_Nbr(smp); i++) {
+    List_Read(smp, i, &ps);
+    for(j = 0; j < 4; j++)
+      if(ps->S[j] == NULL)
+        ps->S[j] = &MyNewBoundary;
+    Tree_Replace(m->Simplexes, &ps);
+  }
+
+}
+
+
+void Fill_Sim_Des(void *a, void *b)
+{
+  Simplex **S;
+  S = (Simplex **) a;
+  if(Pt_In_Circum(*S, THEV))
+    List_Add(Simplexes_Destroyed, a);
+}
+
+void TStoLS(void *a, void *b)
+{
+  List_Add(Simplexes_Destroyed, a);
+}
+
+void TAtoLA(void *a, void *b)
+{
+  List_Add(Simplexes_New, a);
+}
+
+void CrSi(void *a, void *b)
+{
+  SxF *S;
+  Simplex *s;
+  S = (SxF *) a;
+  if(S->NumFaceSimpl == 1) {
+    s = Create_Simplex(THEV, S->F.V[0], S->F.V[1], S->F.V[2]);
+    s->iEnt = ZONEELIMINEE;
+    THEM->Metric->setSimplexQuality(s);
+    List_Add(Simplexes_New, &s);
+  }
+  else if(S->NumFaceSimpl != 2) {
+    Msg(WARNING, "Huh! Panic in CrSi");
+  }
+}
+
+
+void NewSimplexes(Mesh * m, List_T * Sim, List_T * news)
+{
+  int i, j;
+  Tree_T *SimXFac;
+  Simplex *S;
+  SxF SXF, *pSXF;
+
+  SimXFac = Tree_Create(sizeof(SxF), compareSxF);
+
+  for(i = 0; i < List_Nbr(Sim); i++) {
+    List_Read(Sim, i, &S);
+    if(!i)
+      ZONEELIMINEE = S->iEnt;
+    else {
+      if(S->iEnt != ZONEELIMINEE) {
+        Msg(WARNING, "Huh! The elimination failed %d %d",
+            S->iEnt, ZONEELIMINEE);
+      }
+    }
+    for(j = 0; j < 4; j++) {
+      SXF.F = S->F[j];
+      if((pSXF = (SxF *) Tree_PQuery(SimXFac, &SXF))) {
+        (pSXF->NumFaceSimpl)++;
+      }
+      else {
+        SXF.NumFaceSimpl = 1;
+        Tree_Add(SimXFac, &SXF);
+      }
+    }
+  }
+
+  /* Les faces non communes sont obligatoirement a la frontiere ... 
+     -> Nouveaux simplexes */
+
+  Tree_Action(SimXFac, CrSi);
+  Tree_Delete(SimXFac);
+}
+
+
+
+/* Methode recursive : Rempli Tsd les simplexes detruits 
+   Invariant : Le simplexe est a eliminer
+   Le simplexe n'est pas encore considere */
+
+int recur_bowyer(Simplex * s)
+{
+  int i;
+
+  Tree_Insert(Tsd, &s);
+  for(i = 0; i < 4; i++) {
+    if(s->S[i] && s->S[i] != &MyNewBoundary && !Tree_Query(Tsd, &s->S[i])) {
+      if(Pt_In_Circum(s->S[i], THEV) && (s->iEnt == s->S[i]->iEnt)) {
+        recur_bowyer(s->S[i]);
+      }
+      else {
+        if(s->iEnt != s->S[i]->iEnt) {
+          //Msg(WARNING, "Point scabreux %d", s->S[i]->Num);
+          Alerte_Point_Scabreux = 1;
+        }
+        Tree_Insert(Sim_Sur_Le_Bord, &s->S[i]);
+      }
+    }
+  }
+  return 1;
+}
+
+bool Bowyer_Watson(Mesh * m, Vertex * v, Simplex * S, int force)
+{
+  int i;
+  Simplex *s;
+  double volumeold, volumenew;
+
+  THEV = v;
+
+  double x =
+    (S->V[0]->Pos.X + S->V[1]->Pos.X + S->V[2]->Pos.X + S->V[3]->Pos.X) / 4.;
+  double y =
+    (S->V[0]->Pos.Y + S->V[1]->Pos.Y + S->V[2]->Pos.Y + S->V[3]->Pos.Y) / 4.;
+  double z =
+    (S->V[0]->Pos.Z + S->V[1]->Pos.Z + S->V[2]->Pos.Z + S->V[3]->Pos.Z) / 4.;
+
+  if(force)
+    THEM->Metric->Identity();
+  else
+    THEM->Metric->setMetric(x, y, z);
+
+  Tsd = Tree_Create(sizeof(Simplex *), compareSimplex);
+  Sim_Sur_Le_Bord = Tree_Create(sizeof(Simplex *), compareSimplex);
+  List_Reset(Simplexes_Destroyed);
+  List_Reset(Simplexes_New);
+
+  if(Methode) {
+    Tree_Action(m->Simplexes, Fill_Sim_Des);
+  }
+  else {
+    recur_bowyer(S);
+  }
+
+  Tree_Action(Tsd, TStoLS);
+  NewSimplexes(m, Simplexes_Destroyed, Simplexes_New);
+
+  /* calcul des volumes des simplexes crees */
+
+  if(Alerte_Point_Scabreux || !CTX.mesh.speed_max) {
+    volume = 0.0;
+    for(i = 0; i < List_Nbr(Simplexes_Destroyed); i++) {
+      VSIM(List_Pointer(Simplexes_Destroyed, i), NULL);
+    }
+    volumeold = volume;
+    volume = 0.0;
+    for(i = 0; i < List_Nbr(Simplexes_New); i++) {
+      VSIM(List_Pointer(Simplexes_New, i), NULL);
+    }
+    volumenew = volume;
+  }
+  else {
+    volumeold = 1.0;
+    volumenew = 1.0;
+  }
+
+  /* critere du volume */
+
+  if((fabs(volumeold - volumenew) / (volumeold + volumenew)) > 1.e-8) {
+    if(Tree_Suppress(m->Simplexes, &S)) {
+      S->Quality = 0.0;
+      Tree_Add(m->Simplexes, &S);
+    }
+    if(force) {
+      List_Reset(Simplexes_Destroyed);
+      List_Reset(Simplexes_New);
+      Tree_Delete(Sim_Sur_Le_Bord);
+      Tree_Delete(Tsd);
+      //printf(" Aie Aie Aie volume changed %g -> %g\n",volumeold,volumenew);
+      return false;
+    }
+  }
+  else {
+    Tree_Add(m->Vertices, &THEV);
+    for(i = 0; i < List_Nbr(Simplexes_New); i++) {
+      Tree_Add(m->Simplexes, List_Pointer(Simplexes_New, i));
+    }
+
+    /* Suppression des simplexes elimines */
+
+    for(i = 0; i < List_Nbr(Simplexes_Destroyed); i++) {
+      List_Read(Simplexes_Destroyed, i, &s);
+      if(!Tree_Suppress(m->Simplexes, &s))
+        Msg(GERROR, "Impossible to delete simplex");
+      Free_Simplex(&s, 0);
+    }
+
+    /* Creation des liens entre nouveaux simplexes */
+
+    Tree_Action(Sim_Sur_Le_Bord, TAtoLA);
+    Link_Simplexes(Simplexes_New, m->Simplexes);
+  }
+
+  Tree_Delete(Sim_Sur_Le_Bord);
+  Tree_Delete(Tsd);
+  return true;
+}
+
+void Convex_Hull_Mesh(List_T * Points, Mesh * m)
+{
+  int i, j, N, n;
+  int Nbr_OK = 0, Nbr_NOTOK = 0;
+
+  N = List_Nbr(Points);
+  n = IMAX(N / 20, 1);
+
+  Box_6_Tetraedron(Points, m);
+  // List_Sort (Points, comparePosition);
+
+  for(i = 0; i < N; i++) {
+    THES = NULL;
+    List_Read(Points, i, &THEV);
+
+    if(Simplexes_New)
+      for(j = 0; j < List_Nbr(Simplexes_New); j++) {
+        Action_First_Simplexes(List_Pointer(Simplexes_New, j), NULL);
+      }
+
+    if(!THES) {
+      Tree_Action(m->Simplexes, Action_First_Simplexes);
+      Nbr_OK++;
+    }
+    else {
+      Nbr_NOTOK++;
+    }
+    if(i % n == n - 1) {
+      volume = 0.0;
+      Tree_Action(m->Simplexes, VSIM);
+      Msg(STATUS3, "Nod=%d/%d Elm=%d", i + 1, N, Tree_Nbr(m->Simplexes));
+      Msg(STATUS1, "Vol=%g", volume);
+    }
+    if(!THES) {
+      Msg(WARNING, "Vertex (%g,%g,%g) in no simplex", THEV->Pos.X,
+          THEV->Pos.Y, THEV->Pos.Z);
+      THEV->Pos.X +=
+        CTX.mesh.rand_factor * LC3D * (1. -
+                                       (double)rand() / (double)RAND_MAX);
+      THEV->Pos.Y +=
+        CTX.mesh.rand_factor * LC3D * (1. -
+                                       (double)rand() / (double)RAND_MAX);
+      THEV->Pos.Z +=
+        CTX.mesh.rand_factor * LC3D * (1. -
+                                       (double)rand() / (double)RAND_MAX);
+      Tree_Action(m->Simplexes, Action_First_Simplexes);
+    }
+    bool ca_marche = Bowyer_Watson(m, THEV, THES, 1);
+    int count = 0;
+    while(!ca_marche) {
+      count++;
+      double dx =
+        CTX.mesh.rand_factor * LC3D * (1. -
+                                       (double)rand() / (double)RAND_MAX);
+      double dy =
+        CTX.mesh.rand_factor * LC3D * (1. -
+                                       (double)rand() / (double)RAND_MAX);
+      double dz =
+        CTX.mesh.rand_factor * LC3D * (1. -
+                                       (double)rand() / (double)RAND_MAX);
+      THEV->Pos.X += dx;
+      THEV->Pos.Y += dy;
+      THEV->Pos.Z += dz;
+      THES = NULL;
+      Tree_Action(m->Simplexes, Action_First_Simplexes);
+      ca_marche = Bowyer_Watson(m, THEV, THES, 1);
+      THEV->Pos.X -= dx;
+      THEV->Pos.Y -= dy;
+      THEV->Pos.Z -= dz;
+      if(count > 5) {
+        N++;
+        List_Add(POINTS, &THEV);
+        Msg(WARNING, "Unable to add point %d (will try it later)", THEV->Num);
+        break;
+      }
+    }
+  }
+}
+
+void suppress_vertex(void *data, void *dum)
+{
+  Vertex **pv;
+
+  pv = (Vertex **) data;
+  if((*pv)->Num < 0)
+    List_Add(Suppress, pv);
+}
+
+void suppress_simplex(void *data, void *dum)
+{
+  Simplex **pv;
+
+  pv = (Simplex **) data;
+  if((*pv)->iEnt == 0)
+    List_Add(Suppress, pv);
+}
+
+void add_in_bgm(void *a, void *b)
+{
+  Simplex **s, *S;
+
+  s = (Simplex **) a;
+  S = *s;
+  List_Add(LLL, S);
+}
+
+void Bgm_With_Points(Mesh * bgm)
+{
+  int i;
+  Simplex *s;
+
+  bgm->BGM.bgm = List_Create(Tree_Nbr(bgm->Simplexes), 10, sizeof(Simplex));
+  LLL = bgm->BGM.bgm;
+  Tree_Action(bgm->Simplexes, add_in_bgm);
+  for(i = 0; i < List_Nbr(LLL); i++) {
+    s = (Simplex *) List_Pointer(LLL, i);
+    AddSimplexInGrid(bgm, s, BOITE);
+  }
+}
+
+void Create_BgMesh(int Type, double lc, Mesh * m)
+{
+  m->BGM.Typ = Type;
+  switch (Type) {
+  case CONSTANT:
+    m->BGM.lc = lc;
+    break;
+  case ONFILE:
+    break;
+  case WITHPOINTS:
+    m->BGM.bgm = NULL;
+    break;
+  }
+}
+
+void Maillage_Volume(void *data, void *dum)
+{
+  Volume *v, **pv;
+  Mesh M;
+  Surface S, *s;
+  Simplex *simp;
+  Vertex *newv;
+  int n, N;
+  double uvw[3];
+  int i;
+
+  FACE_DIMENSION = 2;
+
+  pv = (Volume **) data;
+  v = *pv;
+
+  if(v->Dirty) {
+    Msg(INFO, "Not meshing dirty Volume %d", v->Num);
+    return;
+  }
+
+  if(Extrude_Mesh(v)) {
+  }
+  else if(MeshTransfiniteVolume(v)) {
+  }
+  else if(v->Typ == 99999) {
+
+    Simplexes_New = List_Create(10, 10, sizeof(Simplex *));
+    Simplexes_Destroyed = List_Create(10, 10, sizeof(Simplex *));
+
+    LOCAL = &M;
+    Create_BgMesh(THEM->BGM.Typ, .2, LOCAL);
+    s = &S;
+
+    POINTS_TREE = Tree_Create(sizeof(Vertex *), comparePosition);
+    POINTS = List_Create(100, 100, sizeof(Vertex *));
+    LOCAL->Simplexes = v->Simplexes;
+    LOCAL->Vertices = v->Vertices;
+
+    for(i = 0; i < List_Nbr(v->Surfaces); i++) {
+      List_Read(v->Surfaces, i, &s);
+      Tree_Action(s->Vertices, add_points);
+    }
+    Tree_Action(POINTS_TREE, add_points_2);
+    Tree_Delete(POINTS_TREE);
+
+    N = List_Nbr(POINTS);
+    n = N / 30 + 1;
+
+    if(!N)
+      return;
+
+    /* Creation d'un maillage initial respectant la frontiere */
+
+    Msg(STATUS2, "Mesh 3D... (initial)");
+
+    Convex_Hull_Mesh(POINTS, LOCAL);
+
+    if(!Coherence(v, LOCAL))
+      Msg(GERROR,
+          "Surface recovery failed (send a bug report with the geo file to <gmsh@geuz.org>!)");
+
+    Link_Simplexes(NULL, LOCAL->Simplexes);
+
+    if(CTX.mesh.initial_only == 3) {
+      POINTS_TREE = THEM->Vertices;
+      Tree_Action(v->Vertices, add_points);
+      POINTS_TREE = THEM->Simplexes;
+      Tree_Action(v->Simplexes, add_points);
+      return;
+    }
+
+    /* Suppression des noeuds de num < 0 */
+
+    Suppress = List_Create(10, 10, sizeof(Vertex *));
+    Tree_Action(v->Vertices, suppress_vertex);
+    for(i = 0; i < List_Nbr(Suppress); i++) {
+      Tree_Suppress(v->Vertices, List_Pointer(Suppress, i));
+    }
+    List_Delete(Suppress);
+
+    /* Suppression des elements dont le num de vol == 0 (cad qui
+       n'appartiennent a auncun volume defini) */
+
+    Suppress = List_Create(10, 10, sizeof(Simplex *));
+    Tree_Action(v->Simplexes, suppress_simplex);
+    for(i = 0; i < List_Nbr(Suppress); i++) {
+      Tree_Suppress(v->Simplexes, List_Pointer(Suppress, i));
+    }
+
+    List_Delete(Suppress);
+
+    if(Tree_Nbr(LOCAL->Simplexes) == 0)
+      return;
+
+    /* Si il reste quelque chose a mailler en volume : */
+
+    Msg(STATUS2, "Mesh 3D... (final)");
+
+    v->Simplexes = LOCAL->Simplexes;
+
+    Bgm_With_Points(LOCAL);
+    POINTS_TREE = THEM->Simplexes;
+
+    Tree_Right(LOCAL->Simplexes, &simp);
+    i = 0;
+
+    while(simp->Quality > CONV_VALUE) {
+      newv = NewVertex(simp);
+      while(!simp->Pt_In_Simplexe(newv, uvw, 1.e-5) &&
+            (simp->S[0] == &MyNewBoundary ||
+             !simp->S[0]->Pt_In_Simplexe(newv, uvw, 1.e-5)) &&
+            (simp->S[1] == &MyNewBoundary ||
+             !simp->S[1]->Pt_In_Simplexe(newv, uvw, 1.e-5)) &&
+            (simp->S[2] == &MyNewBoundary ||
+             !simp->S[2]->Pt_In_Simplexe(newv, uvw, 1.e-5)) &&
+            (simp->S[3] == &MyNewBoundary ||
+             !simp->S[3]->Pt_In_Simplexe(newv, uvw, 1.e-5))) {
+        Tree_Suppress(LOCAL->Simplexes, &simp);
+        simp->Quality = 0.1;
+        Tree_Insert(LOCAL->Simplexes, &simp);
+        Tree_Right(LOCAL->Simplexes, &simp);
+        if(simp->Quality < CONV_VALUE)
+          break;
+        newv = NewVertex(simp);
+      }
+      if(simp->Quality < CONV_VALUE)
+        break;
+      i++;
+      if(i % n == n - 1) {
+        volume = 0.0;
+        Tree_Action(LOCAL->Simplexes, VSIM);
+        Msg(STATUS3, "Nod=%d Elm=%d",
+            Tree_Nbr(LOCAL->Vertices), Tree_Nbr(LOCAL->Simplexes));
+        Msg(STATUS1, "Vol(%g) Conv(%g->%g)", volume, simp->Quality,
+            CONV_VALUE);
+        double adv = 100. * (CONV_VALUE / simp->Quality);
+      }
+      Bowyer_Watson(LOCAL, newv, simp, 0);
+      Tree_Right(LOCAL->Simplexes, &simp);
+    }
+
+    POINTS_TREE = THEM->Vertices;
+    Tree_Action(v->Vertices, add_points);
+    POINTS_TREE = THEM->Simplexes;
+    Tree_Action(v->Simplexes, add_points);
+
+    if(CTX.mesh.quality) {
+      extern void SwapEdges3D(Mesh * M, Volume * v, double GammaPrescribed,
+                              bool order);
+      Msg(STATUS3, "Swapping edges (1st pass)");
+      SwapEdges3D(THEM, v, CTX.mesh.quality, true);
+      Msg(STATUS3, "Swapping edges (2nd pass)");
+      SwapEdges3D(THEM, v, CTX.mesh.quality, false);
+      Msg(STATUS3, "Swapping edges (last pass)");
+      SwapEdges3D(THEM, v, CTX.mesh.quality, true);
+    }
+
+    if(CTX.mesh.nb_smoothing) {
+      /*
+         Msg(STATUS3, "Smoothing volume %d", v->Num);
+         tnxe = Tree_Create (sizeof (NXE), compareNXE);
+         create_NXE (v->Vertices, v->Simplexes, tnxe);
+         for (int i = 0; i < CTX.mesh.nb_smoothing; i++)
+         Tree_Action (tnxe, ActionLiss);
+         delete_NXE (tnxe);
+         Msg(STATUS3, "Swapping edges (last pass)");
+         SwapEdges3D (THEM, v, 0.5, true);
+       */
+    }
+
+    List_Delete(Simplexes_New);
+    List_Delete(Simplexes_Destroyed);
+  }
+
+}
diff --git a/Mesh/mGeomSearch.h b/Mesh/mGeomSearch.h
new file mode 100644
index 0000000000000000000000000000000000000000..7d36f2c91794efb5c160befc64986328e9d9833b
--- /dev/null
+++ b/Mesh/mGeomSearch.h
@@ -0,0 +1,186 @@
+#ifndef _MGEOM_SEARCH_H
+#define _MGEOM_SEARCH_H
+
+#include <vector>
+#include <algorithm>
+
+#define MIN(x,y) ((x<y)?(x):(y))
+#define MAX(x,y) ((x>y)?(x):(y))
+#define TOL 1.e-06
+
+namespace AOMD {
+
+  template <class T>
+  class Brick
+  {
+  public:
+    std::vector<T*> Objects;
+    Brick(){}
+    T* operator [] (int i)
+    {
+      if(i < 0 || i >= Objects.size())throw i;
+      T *obj = Objects[i];
+      return obj;
+    }
+    int size(){return Objects.size();}
+  };
+
+  template <class T, class GetBox, class InteriorCheck>
+  class mGeomSearch
+  {
+    Brick<T> *theTable;
+    int Nx,Ny,Nz;
+    double Xmin,Xmax,Ymin,Ymax,Zmin,Zmax;
+    int getBrickId (double X, double Y, double Z)
+    {
+      int Ix = (int)((double)Nx * (X-Xmin) / (Xmax-Xmin)); 
+      int Iy = (int)((double)Ny * (Y-Ymin) / (Ymax-Ymin)); 
+      int Iz = (int)((double)Nz * (Z-Zmin) / (Zmax-Zmin)); 
+      Ix = MIN(Ix,Nx-1);
+      Iy = MIN(Iy,Ny-1);
+      Iz = MIN(Iz,Nz-1);
+      if(Ix<0)Ix=0;
+      if(Iy<0)Iy=0;
+      if(Iz<0)Iz=0;
+      int index = Ix + Iy * Nx + Iz * Nx * Ny;
+      return index;
+    }
+    Brick<T> * getBrick (int index)
+    {
+      if(index <0 || index >= Nx*Ny*Nz)throw index;
+      Brick<T> *b = &(theTable[index]);
+      return b;
+    }
+    GetBox getBox;
+    InteriorCheck interiorCheck;
+  public:
+    mGeomSearch (double x1,
+		 double x2,
+		 double y1, 
+		 double y2, 
+		 double z1, 
+		 double z2,
+		 GetBox g,
+		 InteriorCheck i,
+		 int nx = 10, 
+		 int ny = 10, 
+		 int nz = 10) :	Nx(nx), Ny(ny), Nz(nz),getBox(g),interiorCheck(i)
+    {
+      Xmin = x1-TOL; Xmax  = x2+TOL;
+      Ymin = y1-TOL; Ymax  = y2+TOL;
+      Zmin = z1-TOL; Zmax  = z2+TOL;
+      
+      theTable = new Brick<T> [Nx*Ny*Nz];
+    }
+  
+    ~mGeomSearch ()
+    {
+      delete [] theTable;
+    };
+    Brick<T> *getBrick(double X, double Y, double Z)
+    {
+      return (getBrick(getBrickId(X,Y,Z)));
+    }
+    T * find (double X[3] , double U[3]);
+    bool AddObject ( T *);
+    bool RemoveObject ( T *);
+  };
+
+  template <class T,class GetBox, class InteriorCheck> 
+  T *  mGeomSearch<T,GetBox,InteriorCheck> :: find ( double X[3] ,
+						     double U[3] )
+  {
+    Brick<T> *b = getBrick (X[0],X[1],X[2]);
+    if(!b) return 0;
+
+    for(int i=0;i<b->size();i++)
+      {
+	T * obj = (*b)[i];	
+	if(interiorCheck(obj,X,U))return obj;
+      }
+    return 0;
+  }
+
+  template <class T,class GetBox, class InteriorCheck> 
+  bool mGeomSearch<T,GetBox, InteriorCheck> :: AddObject ( T * obj )
+  {
+    int     Ix1,Ix2,Iy1,Iy2,Iz1,Iz2;
+    int     i,j,k,index;
+    Brick<T>   *pBrick;
+  
+    /*Template Objects must overload getBox function*/
+    double min[3];
+    double max[3];
+    getBox(obj,min,max);
+  
+    Ix1 = (int)( (double)Nx * (min[0] - Xmin) /( Xmax - Xmin )); 
+    Ix2 = (int)( (double)Nx * (max[0] - Xmin) /( Xmax - Xmin )); 
+    Iy1 = (int)( (double)Ny * (min[1] - Ymin) /( Ymax - Ymin ));  
+    Iy2 = (int)( (double)Ny * (max[1] - Ymin) /( Ymax - Ymin ));  
+    Iz1 = (int)( (double)Nz * (min[2] - Zmin) /( Zmax - Zmin ));  
+    Iz2 = (int)( (double)Nz * (max[2] - Zmin) /( Zmax - Zmin )); 
+  
+  
+    Ix1 = MAX(Ix1,0);
+    Ix2 = MIN(Ix2,Nx-1);
+    Iy1 = MAX(Iy1,0);
+    Iy2 = MIN(Iy2,Ny-1);
+    Iz1 = MAX(Iz1,0);
+    Iz2 = MIN(Iz2,Nz-1);
+ 
+    for(i=Ix1;i<=Ix2;i++){
+      for(j=Iy1;j<=Iy2;j++){
+	for(k=Iz1;k<=Iz2;k++){
+	  index = i + j * Nx + k * Nx * Ny;
+	  pBrick = getBrick(index);
+	  pBrick->Objects.push_back(obj);
+	}
+      }
+    }
+    return true;
+  }
+
+  template <class T,class GetBox, class InteriorCheck> 
+  bool mGeomSearch<T,GetBox, InteriorCheck> :: RemoveObject ( T * obj )
+  {
+    int     Ix1,Ix2,Iy1,Iy2,Iz1,Iz2;
+    int     i,j,k,index;
+    Brick<T>   *pBrick;
+    
+    /*Template Objects must overload getBox function*/
+    double min[3];
+    double max[3];
+    getBox(obj,min,max);
+    
+    Ix1 = (int)( (double)Nx * (min[0] - Xmin) /( Xmax - Xmin )); 
+    Ix2 = (int)( (double)Nx * (max[0] - Xmin) /( Xmax - Xmin )); 
+    Iy1 = (int)( (double)Ny * (min[1] - Ymin) /( Ymax - Ymin ));  
+    Iy2 = (int)( (double)Ny * (max[1] - Ymin) /( Ymax - Ymin ));  
+    Iz1 = (int)( (double)Nz * (min[2] - Zmin) /( Zmax - Zmin ));  
+    Iz2 = (int)( (double)Nz * (max[2] - Zmin) /( Zmax - Zmin )); 
+  
+  
+    Ix1 = MAX(Ix1,0);
+    Ix2 = MIN(Ix2,Nx-1);
+    Iy1 = MAX(Iy1,0);
+    Iy2 = MIN(Iy2,Ny-1);
+    Iz1 = MAX(Iz1,0);
+    Iz2 = MIN(Iz2,Nz-1);
+ 
+    for(i=Ix1;i<=Ix2;i++){
+      for(j=Iy1;j<=Iy2;j++){
+	for(k=Iz1;k<=Iz2;k++){
+	  index = i + j * Nx + k * Nx * Ny;
+	  pBrick = getBrick(index);
+	  pBrick->Objects.erase ( std::remove (pBrick->Objects.begin(),pBrick->Objects.end(),obj) , 
+				  pBrick->Objects.end () );
+	}
+      }
+    }
+    return true;
+  }
+
+} // end of namespace
+
+#undef TOL
+#endif
diff --git a/examples/cube.geo b/examples/cube.geo
deleted file mode 100644
index decdd4a696bb42dae6ae5bda42e91f3bb5b099e1..0000000000000000000000000000000000000000
--- a/examples/cube.geo
+++ /dev/null
@@ -1,83 +0,0 @@
-lcar1 = .0275;
-
-length = 0.25;
-height = 1.0;
-depth = 0.25;
-
-Point(newp) = {length/2,height/2,depth,lcar1}; /* Point      1 */
-Point(newp) = {length/2,height/2,0,lcar1}; /* Point      2 */
-Point(newp) = {-length/2,height/2,depth,lcar1}; /* Point      3 */
-Point(newp) = {-length/2,-height/2,depth,lcar1}; /* Point      4 */
-Point(newp) = {length/2,-height/2,depth,lcar1}; /* Point      5 */
-Point(newp) = {length/2,-height/2,0,lcar1}; /* Point      6 */
-Point(newp) = {-length/2,height/2,0,lcar1}; /* Point      7 */
-Point(newp) = {-length/2,-height/2,0,lcar1}; /* Point      8 */
-Line(1) = {3,1};
-Line(2) = {3,7};
-Line(3) = {7,2};
-Line(4) = {2,1};
-Line(5) = {1,5};
-Line(6) = {5,4};
-Line(7) = {4,8};
-Line(8) = {8,6};
-Line(9) = {6,5};
-Line(10) = {6,2};
-Line(11) = {3,4};
-Line(12) = {8,7};
-Line Loop(13) = {-6,-5,-1,11};
-Plane Surface(14) = {13};
-Line Loop(15) = {4,5,-9,10};
-Plane Surface(16) = {15};
-Line Loop(17) = {-3,-12,8,10};
-Plane Surface(18) = {17};
-Line Loop(19) = {7,12,-2,11};
-Plane Surface(20) = {19};
-Line Loop(21) = {-4,-3,-2,1};
-Plane Surface(22) = {21};
-Line Loop(23) = {8,9,6,7};
-Plane Surface(24) = {23};
-
-Surface Loop(25) = {14,24,-18,22,16,-20};
-Complex Volume(26) = {25};
-
-n = 21;
-
-/*
-sizex = 4;
-sizey = 6;
-sizez = 4;
-*/
-sizex = n*length;
-sizey = n*height;
-sizez = n*depth;
-
-sizex = 9;
-sizey = 33;
-sizez = 9;
-
-
-Transfinite Line {2,4,9,7} = sizez;
-Transfinite Line {11,5,10,12} = sizey;
-Transfinite Line {3,1,6,8} = sizex;
-
-Transfinite Surface {14} = {5,4,3,1};
-Transfinite Surface {16} = {6,2,1,5};
-Transfinite Surface {18} = {6,2,7,8};
-Transfinite Surface {20} = {3,7,8,4};
-Transfinite Surface {22} = {3,7,2,1};
-Transfinite Surface {24} = {4,8,6,5};
-
-Recombine Surface {14,16,18,20,22,24};
-
-Transfinite Volume {26} = {3,7,2,1,4,8,6,5};
-
-Physical Surface(200) = {14,16,18,20,24};
-
-Physical Volume(100) = {26};
-/*
-Mesh.use_cut_plane = 1;
-Mesh.cut_planea = 0;
-Mesh.cut_planeb = 0;
-Mesh.cut_planec = 1;
-Mesh.cut_planed = -0.125;
-*/
\ No newline at end of file