diff --git a/Common/CommandLine.cpp b/Common/CommandLine.cpp
index 737de44f56e0a6b0092328778f81c70f86bfdc09..f77e3a63154706da32886212555932f45d092e05 100644
--- a/Common/CommandLine.cpp
+++ b/Common/CommandLine.cpp
@@ -1,4 +1,4 @@
-// $Id: CommandLine.cpp,v 1.79 2006-09-03 07:44:09 geuzaine Exp $
+// $Id: CommandLine.cpp,v 1.80 2006-09-07 16:03:32 remacle Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -428,7 +428,9 @@ void Get_Options(int argc, char *argv[])
           else if(!strncmp(argv[i], "netgen", 6))
             CTX.mesh.algo3d = FRONTAL_NETGEN;
           else if(!strncmp(argv[i], "tetgen", 6))
-            CTX.mesh.algo3d = DELAUNAY_TETGEN;
+	    {
+	      CTX.mesh.algo3d = DELAUNAY_TETGEN;
+	    }
           else {
             fprintf(stderr, ERROR_STR "Unknown mesh algorithm\n");
             exit(1);
diff --git a/Mesh/meshGFaceTransfinite.cpp b/Mesh/meshGFaceTransfinite.cpp
index 6a4c36bc392d6d69b75c6cd965bb5d6e75c24bca..1a191019ebd5f8d733b29ed36c590611babd526d 100644
--- a/Mesh/meshGFaceTransfinite.cpp
+++ b/Mesh/meshGFaceTransfinite.cpp
@@ -1,4 +1,4 @@
-// $Id: meshGFaceTransfinite.cpp,v 1.2 2006-09-06 10:25:24 remacle Exp $
+// $Id: meshGFaceTransfinite.cpp,v 1.3 2006-09-07 16:03:32 remacle Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -86,6 +86,15 @@ int MeshTransfiniteSurface( GFace *gf)
   int L = N2-N1;
   int H = N3-N2;
 
+  int Lb = N4-N3;
+  int Hb = m_vertices.size()-N4;
+
+  if (Lb != L || Hb != H)
+    {
+      Msg(GERROR,"Surface %d cannot be meshed using the transfinite algo",gf->tag());
+      return 0;
+    }
+
   std::vector<double> lengths_i;
   std::vector<double> lengths_j;
 
@@ -155,6 +164,8 @@ int MeshTransfiniteSurface( GFace *gf)
   double VC3 = V[N3];
   double VC4 = V[N4];
 
+
+  //create points using transfinite interpolation
   for(int i = 1; i<L; i++) 
     {
       double u = lengths_i[i]/L_i;
@@ -168,7 +179,7 @@ int MeshTransfiniteSurface( GFace *gf)
 	  
 	  double Up = TRAN_QUA ( U[iP1], U[iP2], U[iP3], U[iP4] , UC1, UC2, UC3, UC4, u, v ); 
 	  double Vp = TRAN_QUA ( V[iP1], V[iP2], V[iP3], V[iP4] , VC1, VC2, VC3, VC4, u, v ); 
-
+	  
 	  GPoint gp = gf->point (SPoint2(Up,Vp));
 	  MFaceVertex *newv  = new MFaceVertex ( gp.x(),gp.y(),gp.z(), gf, Up, Vp );
 	  gf->mesh_vertices.push_back (newv);	  	  
@@ -176,51 +187,62 @@ int MeshTransfiniteSurface( GFace *gf)
 	}
     }
 
-  // elliptic smoother
-  for (int IT = 0;IT< 15;IT++)
+  if (gf->geomType() == GEntity::Plane) // some work 2 be done to smooth the stuff in parametric coords
+                                        // parametric coords are available (MFaceVertex) !
     {
-      for(int i = 1; i<L; i++) 
+      // elliptic smoother
+      for (int IT = 0;IT< 10;IT++)
 	{
-	  for(int j = 1; j < H; j++) 
+	  for(int i = 1; i<L; i++) 
 	    {
-	      MVertex *v11 = tab[std::make_pair(i-1,j-1)];
-	      MVertex *v12 = tab[std::make_pair(i-1,j)];
-	      MVertex *v13 = tab[std::make_pair(i-1,j+1)];	      
-	      MVertex *v21 = tab[std::make_pair(i,j-1)];
-	      MVertex *v22 = tab[std::make_pair(i,j)];
-	      MVertex *v23 = tab[std::make_pair(i,j+1)];
-	      MVertex *v31 = tab[std::make_pair(i+1,j-1)];
-	      MVertex *v32 = tab[std::make_pair(i+1,j)];
-	      MVertex *v33 = tab[std::make_pair(i+1,j+1)];
-	      
-	      double alpha = 0.25 * (DSQR(v23->x() - v21->x()) +
-				     DSQR(v23->y() - v21->y()));
-	      double gamma = 0.25 * (DSQR(v32->x() - v12->x()) +
-				     DSQR(v32->y() - v12->y()));
-	      double beta = 0.0625 * ((v32->x() - v12->x()) *
-				      (v23->x() - v21->x()) +
-				      (v32->y() - v12->y()) *
-				      (v23->y() - v21->y()));
-	
-	      v22->x() = 0.5 * (alpha * (v32->x() + v12->x()) +
-				  gamma * (v23->x() + v21->x()) -
-				  2. * beta * (v33->x() - v13->x() -
-					       v31->x() + v11->x()))
-		/ (alpha + gamma);
-	      v22->y() = 0.5 * (alpha * (v32->y() + v12->y()) +
-                            gamma * (v23->y() + v21->y()) -
-				  2. * beta * (v33->y() - v13->y() -
-					       v31->y() + v11->y()))
-		/ (alpha + gamma);
-	      v22->z() = 0.5 * (alpha * (v32->z() + v12->z()) +
-				  gamma * (v23->z() + v21->z()) -
-				  2. * beta * (v33->z() - v13->z() -
-					       v31->z() + v11->z()))
-		/ (alpha + gamma);
+	      for(int j = 1; j < H; j++) 
+		{
+		  MVertex *v11 = tab[std::make_pair(i-1,j-1)];
+		  MVertex *v12 = tab[std::make_pair(i-1,j)];
+		  MVertex *v13 = tab[std::make_pair(i-1,j+1)];	      
+		  MVertex *v21 = tab[std::make_pair(i,j-1)];
+		  MVertex *v22 = tab[std::make_pair(i,j)];
+		  MVertex *v23 = tab[std::make_pair(i,j+1)];
+		  MVertex *v31 = tab[std::make_pair(i+1,j-1)];
+		  MVertex *v32 = tab[std::make_pair(i+1,j)];
+		  MVertex *v33 = tab[std::make_pair(i+1,j+1)];
+		  
+		  double alpha = 0.25 * (DSQR(v23->x() - v21->x()) +
+					 DSQR(v23->y() - v21->y()) +
+					 DSQR(v23->z() - v21->z()) 
+					 );
+		  double gamma = 0.25 * (DSQR(v32->x() - v12->x()) +
+					 DSQR(v32->y() - v12->y()) +
+					 DSQR(v32->z() - v12->z())
+					 );
+		  double beta = 0.0625 * ((v32->x() - v12->x()) *
+					  (v23->x() - v21->x()) +
+					  (v32->y() - v12->y()) *
+					  (v23->y() - v21->y()) +
+					  (v32->z() - v12->z()) *
+					  (v23->z() - v21->z())
+					  );
+		  
+		  v22->x() = 0.5 * (alpha * (v32->x() + v12->x()) +
+				    gamma * (v23->x() + v21->x()) -
+				    2. * beta * (v33->x() - v13->x() -
+						 v31->x() + v11->x()))
+		    / (alpha + gamma);
+		  v22->y() = 0.5 * (alpha * (v32->y() + v12->y()) +
+				    gamma * (v23->y() + v21->y()) -
+				    2. * beta * (v33->y() - v13->y() -
+						 v31->y() + v11->y()))
+		    / (alpha + gamma);
+		  v22->z() = 0.5 * (alpha * (v32->z() + v12->z()) +
+				    gamma * (v23->z() + v21->z()) -
+				    2. * beta * (v33->z() - v13->z() -
+						 v31->z() + v11->z()))
+		    / (alpha + gamma);
+		}
 	    }
 	}
     }
-
+  // create elements
   for(int i = 0; i < L ; i++) 
     {
       for(int j = 0; j < H; j++) 
diff --git a/Mesh/meshGRegion.cpp b/Mesh/meshGRegion.cpp
index 1c27b806c9bb443656baf554d6946a0ebc230843..b27532bc9ccaf876bef00dfa4c79cec21fc0eef2 100644
--- a/Mesh/meshGRegion.cpp
+++ b/Mesh/meshGRegion.cpp
@@ -5,25 +5,14 @@
 #include "Message.h"
 #include <vector>
 
-#if defined(HAVE_NETGEN)
-namespace nglib {
-#include "nglib.h"
-#include "nglib_addon.h"
-}
-using namespace nglib;
-
-Ng_Mesh * buildNetgenStructure (GRegion *gr, int importVolumeMesh, std::vector<MVertex*> & numberedV)
+void getAllBoundingVertices (GRegion *gr, int importVolumeMesh, std::set<MVertex*> &allBoundingVertices )
 {
-  NgAddOn_Init();
-  Ng_Mesh *_ngmesh = Ng_NewMesh();
-
   std::list<GFace*> faces = gr->faces();
   std::list<GFace*>::iterator it = faces.begin();
-  std::set<MVertex*> allBoundingVertices;
-  
+
   if (importVolumeMesh)
     allBoundingVertices.insert ( gr->mesh_vertices.begin() , gr->mesh_vertices.end() );
-
+  
   while (it != faces.end())
     {
       GFace *gf = (*it);      
@@ -36,6 +25,121 @@ Ng_Mesh * buildNetgenStructure (GRegion *gr, int importVolumeMesh, std::vector<M
 	}
       ++it;
     }
+}
+
+
+#if defined(HAVE_TETGEN)
+#include "tetgen.h"
+void buildTetgenStructure (  GRegion *gr, tetgenio &in, std::vector<MVertex*> & numberedV)
+{
+
+  std::set<MVertex*> allBoundingVertices;
+  getAllBoundingVertices (gr, 0, allBoundingVertices );
+
+  in.mesh_dim = 3;
+  in.firstnumber = 1;
+  
+  in.numberofpoints = allBoundingVertices.size();
+  in.pointlist = new REAL[in.numberofpoints * 3];
+  in.pointmarkerlist = NULL;
+
+  std::set<MVertex*>::iterator itv =  allBoundingVertices.begin();
+  int I=1;
+  while (itv != allBoundingVertices.end())
+    {
+      in.pointlist[(I-1)*3 + 0] = (*itv)->x();
+      in.pointlist[(I-1)*3 + 1] = (*itv)->y();
+      in.pointlist[(I-1)*3 + 2] = (*itv)->z();
+      (*itv)->setNum(I++);
+      numberedV.push_back(*itv);
+      ++itv;
+    }
+  
+  int nbFace = 0;
+
+  std::list<GFace*> faces = gr->faces();
+  std::list<GFace*>::iterator it = faces.begin();
+  while (it != faces.end())
+    {
+      GFace *gf = (*it);
+      nbFace += gf->triangles.size();
+      ++it;
+    }
+
+  Msg(INFO,"%d model faces -- NumFaces = %d",nbFace,faces.size());
+
+  in.numberoffacets = nbFace;
+  in.facetlist = new tetgenio::facet[in.numberoffacets];
+  in.facetmarkerlist = new int[in.numberoffacets];
+
+  it = faces.begin();
+  I= 0;
+  while (it != faces.end())
+    {
+      GFace *gf = (*it);
+      for (int i = 0; i< gf->triangles.size(); i++)
+	{
+	  MTriangle *t = gf->triangles[i];
+	  tetgenio::facet *f = &in.facetlist[I];
+	  tetgenio::init(f);    
+	  f->numberofholes = 0;
+	  f->numberofpolygons = 1;
+	  tetgenio::polygon *p = f->polygonlist = new tetgenio::polygon[f->numberofpolygons];
+	  tetgenio::init(p);    
+	  p->numberofvertices = 3;
+	  p->vertexlist = new int[p->numberofvertices];
+	  p->vertexlist[0] = t->getVertex(0)->getNum();
+	  p->vertexlist[1] = t->getVertex(1)->getNum();
+	  p->vertexlist[2] = t->getVertex(2)->getNum();
+	  //	  Msg(INFO,"Faces %d = %d %d %d",I,p->vertexlist[0] ,p->vertexlist[1] ,p->vertexlist[2] );
+	  in.facetmarkerlist[I] = gf->tag();	  
+	  ++I;
+	}
+      ++it;
+    }   
+}
+
+void TransferTetgenMesh(GRegion *gr, tetgenio &in, tetgenio &out, std::vector<MVertex*> & numberedV)
+{
+  int I = numberedV.size() + 1;
+  for (int i = 0; i < out.numberofpoints; i++) 
+    {
+      MVertex *v = new MVertex (out.pointlist[i * 3 + 0],out.pointlist[i * 3 + 1],out.pointlist[i * 3 + 2]); 
+      gr->mesh_vertices.push_back(v);
+      numberedV.push_back(v);
+    }
+ 
+  for (int i = 0; i < out.numberoftetrahedra; i++) {
+    MVertex *v1 = numberedV[out.tetrahedronlist[i * 4 + 0] -1];
+    MVertex *v2 = numberedV[out.tetrahedronlist[i * 4 + 1] -1];
+    MVertex *v3 = numberedV[out.tetrahedronlist[i * 4 + 2] -1];
+    MVertex *v4 = numberedV[out.tetrahedronlist[i * 4 + 3] -1];
+    MTetrahedron *t = new  MTetrahedron(v1,v2,v3,v4);
+    gr->tetrahedra.push_back(t);
+  }
+
+ 
+}
+  
+
+#endif
+
+
+#if defined(HAVE_NETGEN)
+namespace nglib {
+#include "nglib.h"
+#include "nglib_addon.h"
+}
+using namespace nglib;
+
+Ng_Mesh * buildNetgenStructure (GRegion *gr, int importVolumeMesh, std::vector<MVertex*> & numberedV)
+{
+  NgAddOn_Init();
+  Ng_Mesh *_ngmesh = Ng_NewMesh();
+
+  std::set<MVertex*> allBoundingVertices;
+  getAllBoundingVertices (gr, importVolumeMesh, allBoundingVertices );
+  
   std::set<MVertex*>::iterator itv =  allBoundingVertices.begin();
   int I=1;
   while (itv != allBoundingVertices.end())
@@ -50,7 +154,8 @@ Ng_Mesh * buildNetgenStructure (GRegion *gr, int importVolumeMesh, std::vector<M
       ++itv;
     }
   
-  it = faces.begin();
+  std::list<GFace*> faces = gr->faces();
+  std::list<GFace*>::iterator it = faces.begin();
   while (it != faces.end())
     {
       GFace *gf = (*it);      
@@ -261,6 +366,23 @@ void meshGRegion :: operator() (GRegion *gr)
   // orient the triangles of with respect to this region
   meshNormalsPointOutOfTheRegion (gr); 
   
+  if(CTX.mesh.algo3d == DELAUNAY_TETGEN)
+    {
+#if !defined(HAVE_TETGEN)
+    Msg(GERROR, "Tetgen is not compiled in this version of Gmsh");
+#else
+    tetgenio in, out;
+    std::vector<MVertex*> numberedV;
+    char opts[128];
+    buildTetgenStructure (  gr, in, numberedV);
+    sprintf(opts, "pq1.4Ya%f%c", (float)CTX.mesh.quality, 
+	    (CTX.verbosity < 3)? 'Q': (CTX.verbosity > 6)? 'V': '\0');
+    Msg(STATUS2, "Meshing with volume constraint %f", (float)CTX.mesh.quality);
+    tetrahedralize(opts, &in, &out);
+    TransferTetgenMesh(gr, in, out, numberedV);
+#endif
+    }
+
   if(CTX.mesh.algo3d == FRONTAL_NETGEN)
     {
 #if !defined(HAVE_NETGEN)
diff --git a/benchmarks/3d/Cube-01.geo b/benchmarks/3d/Cube-01.geo
index 2935afb6f6c8686fac4a34170d5daa033b5d59ea..fdd3497130e5473eae6e4823aa00bd572a20b066 100644
--- a/benchmarks/3d/Cube-01.geo
+++ b/benchmarks/3d/Cube-01.geo
@@ -10,4 +10,4 @@ Line(4) = {1,4};
 Line Loop(5) = {2,3,4,1};         
 Plane Surface(6) = {5};         
 Extrude Surface { 6, {0,0.0,1} };         
-Mesh.Algorithm3D = 4;
+