diff --git a/Mesh/2D_Elliptic.cpp b/Mesh/2D_Elliptic.cpp
index 416c65d776440006305116bfed67a6d747baa15d..7c8be057f1e374faef2d40abe3b869b535b7885b 100644
--- a/Mesh/2D_Elliptic.cpp
+++ b/Mesh/2D_Elliptic.cpp
@@ -1,4 +1,4 @@
-// $Id: 2D_Elliptic.cpp,v 1.18 2004-05-25 04:10:04 geuzaine Exp $
+// $Id: 2D_Elliptic.cpp,v 1.19 2004-05-27 20:49:03 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -37,7 +37,7 @@ int MeshEllipticSurface(Surface * sur)
   List_T *l1, *l2, *l3, *l4;
 
   if(sur->Method != ELLIPTIC)
-    return (0);
+    return 0;
 
   nb = List_Nbr(sur->Generatrices);
 
@@ -65,8 +65,11 @@ int MeshEllipticSurface(Surface * sur)
         for(k = 1; k < List_Nbr(GG[j]->Vertices); k++)
           List_Add(l1, List_Pointer(GG[j]->Vertices, k));
         j = (j + 1 < nb) ? j + 1 : 0;
-        if(j == i)
+        if(j == i){
+	  Msg(WARNING, "Wrong definition of Elliptic Surface %d", sur->Num);
+	  List_Delete(l1);
           return 0;
+	}
       }
       while(compareVertex(&GG[j]->beg, &S[1]));
     }
@@ -83,8 +86,12 @@ int MeshEllipticSurface(Surface * sur)
         for(k = 1; k < List_Nbr(GG[j]->Vertices); k++)
           List_Add(l2, List_Pointer(GG[j]->Vertices, k));
         j = (j + 1 < nb) ? j + 1 : 0;
-        if(j == i)
+        if(j == i){
+	  Msg(WARNING, "Wrong definition of Elliptic Surface %d", sur->Num);
+	  List_Delete(l1);
+	  List_Delete(l2);
           return 0;
+	}
       }
       while(compareVertex(&GG[j]->beg, &S[2]));
     }
@@ -101,8 +108,13 @@ int MeshEllipticSurface(Surface * sur)
         for(k = 1; k < List_Nbr(GG[j]->Vertices); k++)
           List_Add(l3, List_Pointer(GG[j]->Vertices, k));
         j = (j + 1 < nb) ? j + 1 : 0;
-        if(j == i)
+        if(j == i){
+	  Msg(WARNING, "Wrong definition of Elliptic Surface %d", sur->Num);
+	  List_Delete(l1);
+	  List_Delete(l2);
+	  List_Delete(l3);
           return 0;
+	}
       }
       while(compareVertex(&GG[j]->beg, &S[3]));
     }
@@ -119,8 +131,14 @@ int MeshEllipticSurface(Surface * sur)
         for(k = 1; k < List_Nbr(GG[j]->Vertices); k++)
           List_Add(l4, List_Pointer(GG[j]->Vertices, k));
         j = (j + 1 < nb) ? j + 1 : 0;
-        if(j == i)
+        if(j == i){
+	  Msg(WARNING, "Wrong definition of Elliptic Surface %d", sur->Num);
+	  List_Delete(l1);
+	  List_Delete(l2);
+	  List_Delete(l3);
+	  List_Delete(l4);
           return 0;
+	}
       }
       while(compareVertex(&GG[j]->beg, &S[0]));
     }
@@ -131,6 +149,7 @@ int MeshEllipticSurface(Surface * sur)
   N3 = List_Nbr(l3);
   N4 = List_Nbr(l4);
   if(N1 != N3 || N2 != N4) {
+    Msg(WARNING, "Wrong definition of Elliptic Surface %d", sur->Num);
     List_Delete(l1);
     List_Delete(l2);
     List_Delete(l3);
@@ -175,15 +194,19 @@ int MeshEllipticSurface(Surface * sur)
                      (S[1]->lc * (1 - u) * (1. + v)) +
                      (S[2]->lc * (1 - u) * (1. - v)) +
                      (S[3]->lc * (1 + u) * (1. - v)));
-
-        list[i + N1 * j] =
-          Create_Vertex(++THEM->MaxPointNum, x, y, z, lc, 0.0);
+        list[i + N1 * j] = Create_Vertex(++THEM->MaxPointNum, x, y, z, lc, 0.0);
+	Tree_Insert(sur->Vertices, &list[i + N1 * j]);
+        List_Add(sur->TrsfVertices, &list[i + N1 * j]);
       }
     }
   }
 
-  k = 0;
+  List_Delete(l1);
+  List_Delete(l2);
+  List_Delete(l3);
+  List_Delete(l4);
 
+  k = 0;
   while(1) {
     k++;
     if(k > 1000)
@@ -224,10 +247,8 @@ int MeshEllipticSurface(Surface * sur)
                             2. * beta * (v33->Pos.Z - v13->Pos.Z -
                                          v31->Pos.Z + v11->Pos.Z))
           / (alpha + gamma);
-
       }
     }
-
   }
   for(i = 0; i < N1 - 1; i++) {
     for(j = 0; j < N2 - 1; j++) {
@@ -253,5 +274,7 @@ int MeshEllipticSurface(Surface * sur)
     }
   }
 
+  Free(list);
+
   return 1;
 }
diff --git a/Mesh/2D_SMesh.cpp b/Mesh/2D_SMesh.cpp
deleted file mode 100644
index f2983477c60c8a50c854b5352a5471c9d7fd1fcb..0000000000000000000000000000000000000000
--- a/Mesh/2D_SMesh.cpp
+++ /dev/null
@@ -1,302 +0,0 @@
-// $Id: 2D_SMesh.cpp,v 1.18 2004-05-25 04:10:04 geuzaine Exp $
-//
-// Copyright (C) 1997-2004 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>.
-
-/*  
-  Maillage transfini surfacique                                                 
-                                            *s2
-       s3     c2    s2                     /|  
-        *-----------*                     / |
-        |           |                  c2/  |c1   
-      c3|           |c1                 /   |  
-        |           |                  /    |
-  v     *-----------*                 *-----*
-  |    s0     c0    s1               s0  c0  s1
-  *--u
-
-  Decoupages :  |
-                *--*
-                |\ |
-                | \|   
-                *--*-- 
-               s0    -> s1
-*/
-
-#include "Gmsh.h"
-#include "Geo.h"
-#include "Mesh.h"
-#include "Numeric.h"
-#include "Interpolation.h"
-
-extern Mesh *THEM;
-
-int index1d(int flag, int N, int n)
-{
-  switch (flag) {
-  case 0:
-    return n;
-  case 1:
-    return (N - n - 1);
-  default:
-    return -1;
-  }
-}
-
-int MeshTransfiniteSurface(Surface * sur)
-{
-  int i, j, k, flag, nb, N1, N2, issphere;
-  Curve *G[4], *GG[4];
-  Vertex V, *c1, *c2, **list, *CP[2];
-  Simplex *simp;
-  Quadrangle *quad;
-  double u, v;
-  int C_flag[4];
-  Vertex *C[4], *S[4];
-
-  static int tab1qua[] = { 0, 1, 1, 2, 3, 2, 0, 3 };
-  static int tab1tri[] = { 0, 1, 1, 2, 0, 2 };
-  static int tab2[] = { 0, 1, 1, 0 };
-
-  if(sur->Method != TRANSFINI)
-    return (0);
-
-  switch (sur->Typ) {
-
-  case MSH_SURF_REGL:
-  case MSH_SURF_PLAN:
-  case MSH_SURF_TRIC:
-  case MSH_SURF_NURBS:
-
-    nb = List_Nbr(sur->Generatrices);
-    if(nb != 3 && nb != 4)
-      return 0;
-    if(nb != List_Nbr(sur->TrsfPoints))
-      return 0;
-
-    for(i = 0; i < 4; i++)
-      G[i] = NULL;
-
-    for(i = 0; i < nb; i++){
-      List_Read(sur->TrsfPoints, i, &S[i]);
-      List_Read(sur->Generatrices, i, &GG[i]);
-    }
-
-    for(i = 0; i < nb; i++) {
-      List_Read(GG[i]->Control_Points, 0, &CP[0]);
-      List_Read(GG[i]->Control_Points, List_Nbr(GG[i]->Control_Points) - 1,
-                &CP[1]);
-
-      for(flag = 0; flag < 2; flag++) {
-        for(k = 0; k < nb; k++) {
-          if(nb == 4) {
-            if(S[tab1qua[2 * k]]->Num == CP[tab2[2 * flag]]->Num &&
-               S[tab1qua[2 * k + 1]]->Num == CP[tab2[2 * flag + 1]]->Num) {
-              G[k] = GG[i];
-              C_flag[k] = flag;
-            }
-          }
-          else {
-            if(S[tab1tri[2 * k]]->Num == CP[tab2[2 * flag]]->Num &&
-               S[tab1tri[2 * k + 1]]->Num == CP[tab2[2 * flag + 1]]->Num) {
-              G[k] = GG[i];
-              C_flag[k] = flag;
-            }
-          }
-        }
-      }
-    }
-
-    for(i = 0; i < nb; i++)
-      if(G[i] == NULL) {
-        Msg(WARNING, "Wrong definition of Transfinite Surface %d", sur->Num);
-        return 0;
-      }
-
-    if(nb == 4) {
-      if((N1 = List_Nbr(G[0]->Vertices)) != List_Nbr(G[2]->Vertices))
-        return 0;
-      if((N2 = List_Nbr(G[1]->Vertices)) != List_Nbr(G[3]->Vertices))
-        return 0;
-    }
-    else {
-      if((N1 = List_Nbr(G[0]->Vertices)) != List_Nbr(G[2]->Vertices))
-        return 0;
-      N2 = List_Nbr(G[1]->Vertices);
-    }
-
-    sur->Nu = N1;
-    sur->Nv = N2;
-    list = (Vertex **) Malloc(N1 * N2 * sizeof(Vertex *));
-
-    issphere = 1;
-    for(i = 0; i < nb; i++) {
-      if(G[i]->Typ != MSH_SEGM_CIRC && G[i]->Typ != MSH_SEGM_CIRC_INV) {
-        issphere = 0;
-      }
-      else if(issphere) {
-        if(!i) {
-          List_Read(G[i]->Control_Points, 1, &c1);
-        }
-        else {
-          List_Read(G[i]->Control_Points, 1, &c2);
-          if(compareVertex(&c1, &c2))
-            issphere = 0;
-        }
-      }
-    }
-
-    for(i = 0; i < N1; i++) {
-      List_Read(G[0]->Vertices, index1d(C_flag[0], N1, i), &C[0]);
-      List_Read(G[2]->Vertices, index1d(C_flag[2], N1, i), &C[2]);
-
-      if((G[0]->Num > 0 && C_flag[0]) || (G[0]->Num < 0 && !C_flag[0]))
-        u = 1. - C[0]->u;
-      else
-        u = C[0]->u;
-
-      for(j = 0; j < N2; j++) {
-        List_Read(G[1]->Vertices, index1d(C_flag[1], N2, j), &C[1]);
-        if(nb == 4)
-          List_Read(G[3]->Vertices, index1d(C_flag[3], N2, j), &C[3]);
-
-        if((G[1]->Num > 0 && C_flag[1]) || (G[1]->Num < 0 && !C_flag[1]))
-          v = 1. - C[1]->u;
-        else
-          v = C[1]->u;
-
-        if(i && j && i != N1 - 1 && j != N2 - 1) {
-          if(sur->Typ == MSH_SURF_NURBS)
-            V = InterpolateSurface(sur, u, v, 0, 0);
-          else if(nb == 4)
-            V =
-              TransfiniteQua(*C[0], *C[1], *C[2], *C[3], *S[0], *S[1], *S[2],
-                             *S[3], u, v);
-          else
-            V =
-              TransfiniteTri(*C[0], *C[1], *C[2], *S[0], *S[1], *S[2], u, v);
-          if(issphere)
-            TransfiniteSph(*C[0], *c1, &V);
-          list[i + N1 * j] =
-            Create_Vertex(++THEM->MaxPointNum, V.Pos.X, V.Pos.Y, V.Pos.Z,
-                          V.lc, 0.0);
-        }
-        else if(!i)
-          list[i + N1 * j] = (nb == 4) ? C[3] : C[2];
-        else if(!j)
-          list[i + N1 * j] = C[0];
-        else if(i == N1 - 1)
-          list[i + N1 * j] = C[1];
-        else if(j == N2 - 1)
-          list[i + N1 * j] = C[2];
-
-        list[i + N1 * j]->us[0] = u;
-        list[i + N1 * j]->us[1] = v;
-      }
-    }
-
-
-    for(i = 0; i < N1; i++) {
-      for(j = 0; j < N2; j++) {
-        List_Add(sur->TrsfVertices, &list[i + N1 * j]);
-      }
-    }
-
-    if(nb == 4) {
-      for(i = 0; i < N1; i++) {
-        for(j = 0; j < N2; j++) {
-          Tree_Insert(sur->Vertices, &list[i + N1 * j]);
-        }
-      }
-      for(i = 0; i < N1 - 1; i++) {
-        for(j = 0; j < N2 - 1; j++) {
-          if(sur->Recombine) {
-            quad = Create_Quadrangle(list[(i) + N1 * (j)],
-				     list[(i + 1) + N1 * (j)],
-				     list[(i + 1) + N1 * (j + 1)],
-				     list[(i) + N1 * (j + 1)]);
-            quad->iEnt = sur->Num;
-            Tree_Add(sur->Quadrangles, &quad);
-          }
-          else {
-            simp = Create_Simplex(list[(i) + N1 * (j)], 
-				  list[(i + 1) + N1 * (j)],
-				  list[(i) + N1 * (j + 1)], NULL);
-            simp->iEnt = sur->Num;
-            Tree_Add(sur->Simplexes, &simp);
-
-            simp = Create_Simplex(list[(i + 1) + N1 * (j + 1)],
-				  list[(i) + N1 * (j + 1)],
-				  list[(i + 1) + N1 * (j)], NULL);
-            simp->iEnt = sur->Num;
-            Tree_Add(sur->Simplexes, &simp);
-          }
-        }
-      }
-    }
-    else if(nb == 3) {
-      Tree_Insert(sur->Vertices, &list[0]);
-      for(i = 1; i < N1; i++) {
-        for(j = 0; j < N2; j++) {
-          Tree_Insert(sur->Vertices, &list[i + N1 * j]);
-        }
-      }
-      for(j = 0; j < N2 - 1; j++) {
-        simp = Create_Simplex(list[1 + N1 * (j + 1)], 
-			      list[N1 * (j + 1)],
-			      list[1 + N1 * (j)], NULL);
-        simp->iEnt = sur->Num;
-        Tree_Add(sur->Simplexes, &simp);
-      }
-      for(i = 1; i < N1 - 1; i++) {
-        for(j = 0; j < N2 - 1; j++) {
-          if(sur->Recombine) {
-            quad = Create_Quadrangle(list[(i) + N1 * (j)],
-				     list[(i + 1) + N1 * (j)],
-				     list[(i + 1) + N1 * (j + 1)],
-				     list[i + N1 * (j + 1)]);
-            quad->iEnt = sur->Num;
-            Tree_Add(sur->Quadrangles, &quad);
-          }
-          else {
-            simp = Create_Simplex(list[(i) + N1 * (j)], 
-				  list[(i + 1) + N1 * (j)],
-				  list[(i) + N1 * (j + 1)], NULL);
-            simp->iEnt = sur->Num;
-            Tree_Add(sur->Simplexes, &simp);
-
-            simp = Create_Simplex(list[(i + 1) + N1 * (j + 1)],
-				  list[(i) + N1 * (j + 1)],
-				  list[(i + 1) + N1 * (j)], NULL);
-            simp->iEnt = sur->Num;
-            Tree_Add(sur->Simplexes, &simp);
-          }
-        }
-      }
-
-    }
-    Free(list);
-    break;
-
-  default:
-    return 0;
-  }
-
-  return 1;
-}
diff --git a/Mesh/2D_Transfinite.cpp b/Mesh/2D_Transfinite.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..dd887cd482dc847656e396132335105b37614291
--- /dev/null
+++ b/Mesh/2D_Transfinite.cpp
@@ -0,0 +1,285 @@
+// $Id: 2D_Transfinite.cpp,v 1.1 2004-05-27 20:49:03 geuzaine Exp $
+//
+// Copyright (C) 1997-2004 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>.
+
+/*  
+  Maillage transfini surfacique                                                 
+                                            *s2
+       s3     c2    s2                     /|  
+        *-----------*                     / |
+        |           |                  c2/  |c1   
+      c3|           |c1                 /   |  
+        |           |                  /    |
+  v     *-----------*                 *-----*
+  |    s0     c0    s1               s0  c0  s1
+  *--u
+
+  Decoupages :  |
+                *--*
+                |\ |
+                | \|   
+                *--*-- 
+               s0    -> s1
+*/
+
+#include "Gmsh.h"
+#include "Geo.h"
+#include "Mesh.h"
+#include "Numeric.h"
+#include "Interpolation.h"
+
+extern Mesh *THEM;
+
+int index1d(int flag, int N, int n)
+{
+  switch (flag) {
+  case 0:
+    return n;
+  case 1:
+    return (N - n - 1);
+  default:
+    return -1;
+  }
+}
+
+int MeshTransfiniteSurface(Surface * sur)
+{
+  int i, j, k, flag, nb, N1, N2, issphere;
+  Curve *G[4], *GG[4];
+  Vertex V, *c1, *c2, **list, *CP[2];
+  Simplex *simp;
+  Quadrangle *quad;
+  double u, v;
+  int C_flag[4];
+  Vertex *C[4], *S[4];
+
+  static int tab1qua[] = { 0, 1, 1, 2, 3, 2, 0, 3 };
+  static int tab1tri[] = { 0, 1, 1, 2, 0, 2 };
+  static int tab2[] = { 0, 1, 1, 0 };
+
+  if(sur->Method != TRANSFINI)
+    return 0;
+
+  nb = List_Nbr(sur->Generatrices);
+  if(nb != 3 && nb != 4)
+    return 0;
+  if(nb != List_Nbr(sur->TrsfPoints))
+    return 0;
+  
+  for(i = 0; i < 4; i++)
+    G[i] = NULL;
+  
+  for(i = 0; i < nb; i++){
+    List_Read(sur->TrsfPoints, i, &S[i]);
+    List_Read(sur->Generatrices, i, &GG[i]);
+  }
+  
+  for(i = 0; i < nb; i++) {
+    List_Read(GG[i]->Control_Points, 0, &CP[0]);
+    List_Read(GG[i]->Control_Points, List_Nbr(GG[i]->Control_Points) - 1, &CP[1]);
+    
+    for(flag = 0; flag < 2; flag++) {
+      for(k = 0; k < nb; k++) {
+	if(nb == 4) {
+	  if(S[tab1qua[2 * k]]->Num == CP[tab2[2 * flag]]->Num &&
+	     S[tab1qua[2 * k + 1]]->Num == CP[tab2[2 * flag + 1]]->Num) {
+	    G[k] = GG[i];
+	    C_flag[k] = flag;
+	  }
+	}
+	else {
+	  if(S[tab1tri[2 * k]]->Num == CP[tab2[2 * flag]]->Num &&
+	     S[tab1tri[2 * k + 1]]->Num == CP[tab2[2 * flag + 1]]->Num) {
+	    G[k] = GG[i];
+	    C_flag[k] = flag;
+	  }
+	}
+      }
+    }
+  }
+  
+  for(i = 0; i < nb; i++)
+    if(G[i] == NULL) {
+      Msg(WARNING, "Wrong definition of Transfinite Surface %d", sur->Num);
+      return 0;
+    }
+  
+  if(nb == 4) {
+    if((N1 = List_Nbr(G[0]->Vertices)) != List_Nbr(G[2]->Vertices))
+      return 0;
+    if((N2 = List_Nbr(G[1]->Vertices)) != List_Nbr(G[3]->Vertices))
+      return 0;
+  }
+  else {
+    if((N1 = List_Nbr(G[0]->Vertices)) != List_Nbr(G[2]->Vertices))
+      return 0;
+    N2 = List_Nbr(G[1]->Vertices);
+  }
+  
+  sur->Nu = N1;
+  sur->Nv = N2;
+  list = (Vertex **) Malloc(N1 * N2 * sizeof(Vertex *));
+  
+  issphere = 1;
+  for(i = 0; i < nb; i++) {
+    if(G[i]->Typ != MSH_SEGM_CIRC && G[i]->Typ != MSH_SEGM_CIRC_INV) {
+      issphere = 0;
+    }
+    else if(issphere) {
+      if(!i) {
+	List_Read(G[i]->Control_Points, 1, &c1);
+      }
+      else {
+	List_Read(G[i]->Control_Points, 1, &c2);
+	if(compareVertex(&c1, &c2))
+	  issphere = 0;
+      }
+    }
+  }
+  
+  for(i = 0; i < N1; i++) {
+    List_Read(G[0]->Vertices, index1d(C_flag[0], N1, i), &C[0]);
+    List_Read(G[2]->Vertices, index1d(C_flag[2], N1, i), &C[2]);
+    
+    if((G[0]->Num > 0 && C_flag[0]) || (G[0]->Num < 0 && !C_flag[0]))
+      u = 1. - C[0]->u;
+    else
+      u = C[0]->u;
+    
+    for(j = 0; j < N2; j++) {
+      List_Read(G[1]->Vertices, index1d(C_flag[1], N2, j), &C[1]);
+      if(nb == 4)
+	List_Read(G[3]->Vertices, index1d(C_flag[3], N2, j), &C[3]);
+      
+      if((G[1]->Num > 0 && C_flag[1]) || (G[1]->Num < 0 && !C_flag[1]))
+	v = 1. - C[1]->u;
+      else
+	v = C[1]->u;
+      
+      if(i && j && i != N1 - 1 && j != N2 - 1) {
+	if(sur->Typ == MSH_SURF_NURBS)
+	  V = InterpolateSurface(sur, u, v, 0, 0);
+	else if(nb == 4)
+	  V = TransfiniteQua(*C[0], *C[1], *C[2], *C[3], *S[0], *S[1], *S[2],
+			     *S[3], u, v);
+	else
+	  V = TransfiniteTri(*C[0], *C[1], *C[2], *S[0], *S[1], *S[2], u, v);
+	if(issphere)
+	  TransfiniteSph(*C[0], *c1, &V);
+	list[i + N1 * j] =
+	  Create_Vertex(++THEM->MaxPointNum, V.Pos.X, V.Pos.Y, V.Pos.Z, V.lc, 0.0);
+      }
+      else if(!i)
+	list[i + N1 * j] = (nb == 4) ? C[3] : C[2];
+      else if(!j)
+	list[i + N1 * j] = C[0];
+      else if(i == N1 - 1)
+	list[i + N1 * j] = C[1];
+      else if(j == N2 - 1)
+	list[i + N1 * j] = C[2];
+      
+      list[i + N1 * j]->us[0] = u;
+      list[i + N1 * j]->us[1] = v;
+    }
+  }
+  
+  for(i = 0; i < N1; i++) {
+    for(j = 0; j < N2; j++) {
+      List_Add(sur->TrsfVertices, &list[i + N1 * j]);
+    }
+  }
+  
+  if(nb == 4) {
+    for(i = 0; i < N1; i++) {
+      for(j = 0; j < N2; j++) {
+	Tree_Insert(sur->Vertices, &list[i + N1 * j]);
+      }
+    }
+    for(i = 0; i < N1 - 1; i++) {
+      for(j = 0; j < N2 - 1; j++) {
+	if(sur->Recombine) {
+	  quad = Create_Quadrangle(list[(i) + N1 * (j)],
+				   list[(i + 1) + N1 * (j)],
+				   list[(i + 1) + N1 * (j + 1)],
+				   list[(i) + N1 * (j + 1)]);
+	  quad->iEnt = sur->Num;
+	  Tree_Add(sur->Quadrangles, &quad);
+	}
+	else {
+	  simp = Create_Simplex(list[(i) + N1 * (j)], 
+				list[(i + 1) + N1 * (j)],
+				list[(i) + N1 * (j + 1)], NULL);
+	  simp->iEnt = sur->Num;
+	  Tree_Add(sur->Simplexes, &simp);
+	  
+	  simp = Create_Simplex(list[(i + 1) + N1 * (j + 1)],
+				list[(i) + N1 * (j + 1)],
+				list[(i + 1) + N1 * (j)], NULL);
+	  simp->iEnt = sur->Num;
+	  Tree_Add(sur->Simplexes, &simp);
+	}
+      }
+    }
+  }
+  else if(nb == 3) {
+    Tree_Insert(sur->Vertices, &list[0]);
+    for(i = 1; i < N1; i++) {
+      for(j = 0; j < N2; j++) {
+	Tree_Insert(sur->Vertices, &list[i + N1 * j]);
+      }
+    }
+    for(j = 0; j < N2 - 1; j++) {
+      simp = Create_Simplex(list[1 + N1 * (j + 1)], 
+			    list[N1 * (j + 1)],
+			    list[1 + N1 * (j)], NULL);
+      simp->iEnt = sur->Num;
+      Tree_Add(sur->Simplexes, &simp);
+    }
+    for(i = 1; i < N1 - 1; i++) {
+      for(j = 0; j < N2 - 1; j++) {
+	if(sur->Recombine) {
+	  quad = Create_Quadrangle(list[(i) + N1 * (j)],
+				   list[(i + 1) + N1 * (j)],
+				   list[(i + 1) + N1 * (j + 1)],
+				   list[i + N1 * (j + 1)]);
+	  quad->iEnt = sur->Num;
+	  Tree_Add(sur->Quadrangles, &quad);
+	}
+	else {
+	  simp = Create_Simplex(list[(i) + N1 * (j)], 
+				list[(i + 1) + N1 * (j)],
+				list[(i) + N1 * (j + 1)], NULL);
+	  simp->iEnt = sur->Num;
+	  Tree_Add(sur->Simplexes, &simp);
+	  
+	  simp = Create_Simplex(list[(i + 1) + N1 * (j + 1)],
+				list[(i) + N1 * (j + 1)],
+				list[(i + 1) + N1 * (j)], NULL);
+	  simp->iEnt = sur->Num;
+	  Tree_Add(sur->Simplexes, &simp);
+	}
+      }
+    }
+    
+  }
+  Free(list);
+
+  return 1;
+}
diff --git a/Mesh/3D_SMesh.cpp b/Mesh/3D_Transfinite.cpp
similarity index 98%
rename from Mesh/3D_SMesh.cpp
rename to Mesh/3D_Transfinite.cpp
index 3f87cfb03627f7a2edce1c899f5b08be0e0bb18a..7cf1ef648029710644f32b8958ea316ee53233ab 100644
--- a/Mesh/3D_SMesh.cpp
+++ b/Mesh/3D_Transfinite.cpp
@@ -1,4 +1,4 @@
-// $Id: 3D_SMesh.cpp,v 1.23 2004-05-26 00:33:37 geuzaine Exp $
+// $Id: 3D_Transfinite.cpp,v 1.1 2004-05-27 20:49:03 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -200,7 +200,7 @@ int MeshTransfiniteVolume(Volume * vol)
 			0, 3, 2, 1 };
 
   if(vol->Method != TRANSFINI)
-    return (0);
+    return 0;
 
   nbs = List_Nbr(vol->Surfaces);
 
@@ -279,7 +279,7 @@ int MeshTransfiniteVolume(Volume * vol)
   if(nbs == 6 && NbFacesFound != 6) {
     Msg(WARNING, "Wrong definition of hexahedric Transfinite Volume %d",
         vol->Num);
-    return (0);
+    return 0;
   }
 
   if(nbs == 5 && NbFacesFound != 5) {
@@ -287,7 +287,7 @@ int MeshTransfiniteVolume(Volume * vol)
         vol->Num);
     Msg(WARNING2, "Possibly because the first and fourth points are not the");
     Msg(WARNING3, "degenerated ones");
-    return (0);
+    return 0;
   }
 
   if(nbs == 6) {
@@ -295,7 +295,7 @@ int MeshTransfiniteVolume(Volume * vol)
       if(G[i] == NULL) {
         Msg(WARNING, "Wrong definition of hexahedric Transfinite Volume %d",
             vol->Num);
-        return (0);
+        return 0;
       }
     }
   }
@@ -308,7 +308,7 @@ int MeshTransfiniteVolume(Volume * vol)
           Msg(WARNING2,
               "Possibly because the first and fourth points are not the");
           Msg(WARNING3, "degenerated ones");
-          return (0);
+          return 0;
         }
       }
     }
@@ -501,7 +501,7 @@ int MeshTransfiniteVolume(Volume * vol)
           else {
             Msg(WARNING, "Wrong surface recombining in Transfinite Volume %d",
                 vol->Num);
-            return (0);
+            return 0;
           }
         }
       }
@@ -553,7 +553,7 @@ int MeshTransfiniteVolume(Volume * vol)
         else {
           Msg(WARNING, "Wrong surface recombining in Transfinite Volume %d",
               vol->Num);
-          return (0);
+          return 0;
         }
       }
     }
@@ -605,13 +605,13 @@ int MeshTransfiniteVolume(Volume * vol)
           else {
             Msg(WARNING, "Wrong surface recombining in Transfinite Volume %d",
                 vol->Num);
-            return (0);
+            return 0;
           }
         }
       }
     }
   }
 
-  return (1);
+  return 1;
 
 }
diff --git a/Mesh/Makefile b/Mesh/Makefile
index da26bb79492a7bdfea6ad9c71eddb30beaa76978..c76625ad5e90b17c94b997c5cc0d271a463840e3 100644
--- a/Mesh/Makefile
+++ b/Mesh/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.63 2004-05-25 23:16:26 geuzaine Exp $
+# $Id: Makefile,v 1.64 2004-05-27 20:49:03 geuzaine Exp $
 #
 # Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 #
@@ -28,7 +28,7 @@ CFLAGS  = ${OPTIM} ${FLAGS} ${INCLUDE}
 
 SRC = 1D_Mesh.cpp \
       2D_Mesh.cpp \
-        2D_SMesh.cpp \
+        2D_Transfinite.cpp \
         2D_Elliptic.cpp \
         2D_BGMesh.cpp \
         2D_Recombine.cpp \
@@ -44,7 +44,7 @@ SRC = 1D_Mesh.cpp \
         2D_Mesh_Aniso.cpp \
         2D_Mesh_Triangle.cpp \
         3D_Mesh.cpp \
-        3D_SMesh.cpp \
+        3D_Transfinite.cpp \
         3D_BGMesh.cpp \
         3D_Extrude.cpp \
         3D_Extrude_Old.cpp \
@@ -111,7 +111,7 @@ depend:
   ../Mesh/Simplex.h ../Mesh/Face.h ../Mesh/Edge.h ../Geo/ExtrudeParams.h \
   ../Mesh/STL.h ../Mesh/Metric.h ../Mesh/Matrix.h Utils.h Create.h \
   2D_Mesh.h ../Common/Context.h
-2D_SMesh.o: 2D_SMesh.cpp ../Common/Gmsh.h ../Common/Message.h \
+2D_Transfinite.o: 2D_Transfinite.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
   ../DataStr/avl.h ../DataStr/Tools.h ../Geo/Geo.h Mesh.h Vertex.h \
   Element.h Simplex.h Face.h Edge.h ../Geo/ExtrudeParams.h STL.h Metric.h \
@@ -195,7 +195,7 @@ depend:
   ../DataStr/avl.h ../DataStr/Tools.h ../Numeric/Numeric.h Mesh.h \
   Vertex.h Element.h Simplex.h Face.h Edge.h ../Geo/ExtrudeParams.h STL.h \
   Metric.h Matrix.h 3D_Mesh.h Create.h ../Common/Context.h
-3D_SMesh.o: 3D_SMesh.cpp ../Common/Gmsh.h ../Common/Message.h \
+3D_Transfinite.o: 3D_Transfinite.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
   ../DataStr/avl.h ../DataStr/Tools.h Mesh.h Vertex.h Element.h Simplex.h \
   Face.h Edge.h ../Geo/ExtrudeParams.h STL.h Metric.h Matrix.h \
diff --git a/doc/VERSIONS b/doc/VERSIONS
index abd918e620b90c9aa534d31ad1364781000d26fc..f0737049eb288a4dd9dbab9f696a79b1c91db98d 100644
--- a/doc/VERSIONS
+++ b/doc/VERSIONS
@@ -1,4 +1,4 @@
-$Id: VERSIONS,v 1.211 2004-05-25 23:16:32 geuzaine Exp $
+$Id: VERSIONS,v 1.212 2004-05-27 20:49:03 geuzaine Exp $
 
 New in 1.53: completed support for second order elements (lines,
 triangles, quadrangles, tetrahedra, hexahedra, prisms and pyramids);
@@ -11,7 +11,8 @@ other options); added "undo" capability during geometry creation;
 rewrote the contour guessing routines so that entities can be selected
 in an arbitrary order; Mac users can now double click on geo/msh/pos
 files in the Finder to launch Gmsh; removed support for fltk 1.0;
-rewrote most of the code related to quadrangles; many code cleanups;
+rewrote most of the code related to quadrangles; fixed 2d elliptic
+algorithm; many code cleanups;
 
 New in 1.52: new raster ("bitmap") PostScript/EPS/PDF output formats;
 new Plugin(Extract) to extract a given component from a
diff --git a/doc/texinfo/gmsh.texi b/doc/texinfo/gmsh.texi
index 90378c2d4736e0bfe1a9507058d1e7981e425f41..5ffa9a15b52d6f11190bf3ed9c126cf4ef5c39cf 100644
--- a/doc/texinfo/gmsh.texi
+++ b/doc/texinfo/gmsh.texi
@@ -1,5 +1,5 @@
 \input texinfo.tex @c -*-texinfo-*-
-@c $Id: gmsh.texi,v 1.114 2004-05-27 06:23:48 geuzaine Exp $
+@c $Id: gmsh.texi,v 1.115 2004-05-27 20:49:03 geuzaine Exp $
 @c
 @c Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 @c
@@ -503,8 +503,8 @@ surfaces;
 @item
 Gmsh is not primarily a structured mesh generator: no automatic
 quadrilateral or hexahedral meshing algorithm is provided. If you want
-quadrangles, you have to use transfinite or extruded meshes or recombine
-unstructured triangular meshes. For hexahedra, your only choice is
+quadrangles, you have to use transfinite, elliptic or extruded meshes or
+recombine unstructured triangular meshes. For hexahedra, your only choice is
 transfinite or extruded meshes;
 @item
 Gmsh is not a multi-bloc generator: all meshes produced by Gmsh are
@@ -1754,12 +1754,12 @@ The 2D unstructured algorithms generate triangles or both triangles and
 quadrangles (when @code{Recombine Surface} is used: see @ref{Miscellaneous
 mesh commands}). The 3D unstructured algorithm only generates tetrahedra.
 
-The 2D structured algorithms (transfinite and extrusion) generate triangles
-by default, but quadrangles can be obtained by using the @code{Recombine}
-commands (see @ref{Structured grids}, and @ref{Miscellaneous mesh
-commands}). The 3D structured algorithms generate tetrahedra, hexahedra,
-prisms and pyramids, depending on the type of the surface meshes they are
-based on.
+The 2D structured algorithms (transfinite, elliptic and extrusion) generate
+triangles by default, but quadrangles can be obtained by using the
+@code{Recombine} commands (see @ref{Structured grids}, and
+@ref{Miscellaneous mesh commands}). The 3D structured algorithms generate
+tetrahedra, hexahedra, prisms and pyramids, depending on the type of the
+surface meshes they are based on.
 
 @menu
 * Elementary vs physical entities::  
@@ -1918,6 +1918,8 @@ numbers are listed in @var{expression-list}. The new value is given by
 @cindex Mesh, extrusion
 @cindex Transfinite, mesh
 @cindex Mesh, transfinite
+@cindex Elliptic, mesh
+@cindex Mesh, elliptic
 
 @ftable @code
 @c todo:
@@ -1987,6 +1989,14 @@ points on the boundary of the volume. The ordering of these point numbers
 defines the ordering and orientation of the mesh elements, and should thus
 follow the node ordering for prisms or hexahedra given in @ref{Gmsh node
 ordering}.
+
+@item Elliptic Surface @{ @var{expression} @} = @{ @var{expression-list} @};
+Selects the surface @var{expression} to be meshed with the 2D elliptic
+algorithm (the surface can only have four sides). The @var{expression-list}
+should contain the identification numbers of the points on the boundary of
+the surface. The ordering of these point numbers defines the ordering and
+orientation of the mesh elements, and should thus follow the node ordering
+for triangles or quadrangles given in @ref{Gmsh node ordering}.
 @end ftable
 
 @c .........................................................................