diff --git a/Common/Options.cpp b/Common/Options.cpp
index 5f4e4372550ed62e33a5ceaa2add01742e80eeca..3c9047963d3ea24532569cfe1fd18856f707618c 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -1,4 +1,4 @@
-// $Id: Options.cpp,v 1.115 2003-10-25 03:26:40 geuzaine Exp $
+// $Id: Options.cpp,v 1.116 2003-10-26 16:53:12 geuzaine Exp $
 //
 // Copyright (C) 1997-2003 C. Geuzaine, J.-F. Remacle
 //
@@ -79,12 +79,13 @@ void Init_Options(int num)
   char *tmp;
 
   // Home directory
+  if((tmp = getenv("GMSH_HOME")))
+    strcpy(CTX.home_dir, tmp);
 #if !defined(WIN32)     // Some WinNT systems have bad HOME variables...
-  if((tmp = getenv("HOME")))
+  else if((tmp = getenv("HOME")))
     strcpy(CTX.home_dir, tmp);
-  else
 #endif
-  if((tmp = getenv("TMP")))
+  else if((tmp = getenv("TMP")))
     strcpy(CTX.home_dir, tmp);
   else if((tmp = getenv("TEMP")))
     strcpy(CTX.home_dir, tmp);
diff --git a/Geo/CAD.cpp b/Geo/CAD.cpp
index d08667a22bd79e44e52177503808beb7c81b0c81..f5c04965e5f9a660712384c404f1dd6eb2a08c8a 100644
--- a/Geo/CAD.cpp
+++ b/Geo/CAD.cpp
@@ -1,4 +1,4 @@
-// $Id: CAD.cpp,v 1.66 2003-09-22 07:26:38 geuzaine Exp $
+// $Id: CAD.cpp,v 1.67 2003-10-26 16:53:12 geuzaine Exp $
 //
 // Copyright (C) 1997-2003 C. Geuzaine, J.-F. Remacle
 //
@@ -1088,6 +1088,7 @@ int Extrude_ProtudePoint(int type, int ip,
     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;
 
@@ -1325,6 +1326,7 @@ int Extrude_ProtudeCurve(int type, int ic,
   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;
diff --git a/Geo/ExtrudeParams.cpp b/Geo/ExtrudeParams.cpp
index 6fad9364e0964b9f3477150cc57732da4c48c1c4..2f4d52bdb6ae754fef1ccef02b5c5c0ff850e226 100644
--- a/Geo/ExtrudeParams.cpp
+++ b/Geo/ExtrudeParams.cpp
@@ -1,4 +1,4 @@
-// $Id: ExtrudeParams.cpp,v 1.13 2003-03-21 00:52:38 geuzaine Exp $
+// $Id: ExtrudeParams.cpp,v 1.14 2003-10-26 16:53:12 geuzaine Exp $
 //
 // Copyright (C) 1997-2003 C. Geuzaine, J.-F. Remacle
 //
@@ -38,6 +38,7 @@ void Projette(double p[3], double mat[3][3])
 
 ExtrudeParams::ExtrudeParams(int ModeEx)
 {
+  _useZonLayer = true;
   geo.Mode = ModeEx;
   geo.Source = -1;
   mesh.ExtrudeMesh = false;
diff --git a/Geo/ExtrudeParams.h b/Geo/ExtrudeParams.h
index 96a571f1815b814dc80748b8c5fe4521652f07e7..e2d784f3c05162bc299fc5b9173680643d4d7141 100644
--- a/Geo/ExtrudeParams.h
+++ b/Geo/ExtrudeParams.h
@@ -30,7 +30,8 @@
 #define TRANSLATE_ROTATE 3
 
 class ExtrudeParams{
-  
+private :
+  bool  _useZonLayer;
 public :
   ExtrudeParams(int Mode = EXTRUDED_ENTITY);
   void fill(int type,
@@ -41,6 +42,8 @@ public :
 	       double &dx, double &dy, double &dz);
   void Extrude(double t, double &x, double &y, double &z);
   void Rotate(double matr[3][3]);
+  void useZonLayer(bool val){ _useZonLayer = val; };
+  bool useZonLayer(){ return _useZonLayer; };
   struct{
     bool    ExtrudeMesh;
     bool    Recombine;
diff --git a/Mesh/1D_Mesh.cpp b/Mesh/1D_Mesh.cpp
index 37a360e65c19debf9cf494db1418f3bf10b2dd41..4c60fd48e2ab4d4446465c972f0d64ba3ce18a02 100644
--- a/Mesh/1D_Mesh.cpp
+++ b/Mesh/1D_Mesh.cpp
@@ -1,4 +1,4 @@
-// $Id: 1D_Mesh.cpp,v 1.34 2003-06-14 04:37:42 geuzaine Exp $
+// $Id: 1D_Mesh.cpp,v 1.35 2003-10-26 16:53:12 geuzaine Exp $
 //
 // Copyright (C) 1997-2003 C. Geuzaine, J.-F. Remacle
 //
@@ -157,89 +157,95 @@ void Maillage_Curve(void *data, void *dummy)
     return;
   }
 
-  if(c->Method == TRANSFINI || !Extrude_Mesh(c)) {
-    if(c->Method == TRANSFINI) {
-      Points = List_Create(10, 10, sizeof(IntPoint));
-      a = Integration(c->ubeg, c->uend, F_Transfini, Points, 1.e-7);
-      N = c->ipar[0];
+  if(Extrude_Mesh(c)){
+    if(CTX.mesh.order == 2){
+      Degre2(c->Simplexes, c, NULL);
     }
-    else {
-      Points = List_Create(10, 10, sizeof(IntPoint));
-      a = Integration(c->ubeg, c->uend, F_Lc, Points, 1.e-4);
-      N = IMAX(2, (int)(a + 1.));
+    THEM->Statistics[4] += List_Nbr(c->Vertices);
+    return;
+  }
 
-      if(c->Typ == MSH_SEGM_CIRC ||
-         c->Typ == MSH_SEGM_CIRC_INV ||
-         c->Typ == MSH_SEGM_ELLI || c->Typ == MSH_SEGM_ELLI_INV) {
-        N = IMAX(N, (int)(fabs(c->Circle.t1 - c->Circle.t2) *
-                          (double)CTX.mesh.min_circ_points / Pi));
-      }
-      else if(c->Typ == MSH_SEGM_NURBS) {
-        N = IMAX(N, 2);
-      }
+  if(c->Method == TRANSFINI) {
+    Points = List_Create(10, 10, sizeof(IntPoint));
+    a = Integration(c->ubeg, c->uend, F_Transfini, Points, 1.e-7);
+    N = c->ipar[0];
+  }
+  else {
+    Points = List_Create(10, 10, sizeof(IntPoint));
+    a = Integration(c->ubeg, c->uend, F_Lc, Points, 1.e-4);
+    N = IMAX(2, (int)(a + 1.));
+    
+    if(c->Typ == MSH_SEGM_CIRC ||
+       c->Typ == MSH_SEGM_CIRC_INV ||
+       c->Typ == MSH_SEGM_ELLI || c->Typ == MSH_SEGM_ELLI_INV) {
+      N = IMAX(N, (int)(fabs(c->Circle.t1 - c->Circle.t2) *
+			(double)CTX.mesh.min_circ_points / Pi));
     }
-    b = a / (double)(N - 1);
-    c->Vertices = List_Create(N, 2, sizeof(Vertex *));
-
-    v = &c->beg;
-    if((vexist = (Vertex **) Tree_PQuery(THEM->Vertices, v))) {
-      (*vexist)->u = c->ubeg;
-      if((*vexist)->ListCurves)
-        List_Add((*vexist)->ListCurves, &c);
-      List_Add(c->Vertices, vexist);
+    else if(c->Typ == MSH_SEGM_NURBS) {
+      N = IMAX(N, 2);
     }
-    else {
-      pV = Create_Vertex((*v)->Num, (*v)->Pos.X, (*v)->Pos.Y,
-                         (*v)->Pos.Z, (*v)->lc, c->ubeg);
+  }
+  b = a / (double)(N - 1);
+  c->Vertices = List_Create(N, 2, sizeof(Vertex *));
+  
+  v = &c->beg;
+  if((vexist = (Vertex **) Tree_PQuery(THEM->Vertices, v))) {
+    (*vexist)->u = c->ubeg;
+    if((*vexist)->ListCurves)
+      List_Add((*vexist)->ListCurves, &c);
+    List_Add(c->Vertices, vexist);
+  }
+  else {
+    pV = Create_Vertex((*v)->Num, (*v)->Pos.X, (*v)->Pos.Y,
+		       (*v)->Pos.Z, (*v)->lc, c->ubeg);
+    pV->ListCurves = List_Create(1, 1, sizeof(Curve *));
+    List_Add(pV->ListCurves, &c);
+    Tree_Add(THEM->Vertices, &pV);
+    List_Add(c->Vertices, &pV);
+  }
+  
+  count = NUMP = 1;
+  while(NUMP < N - 1) {
+    List_Read(Points, count - 1, &P1);
+    List_Read(Points, count, &P2);
+    d = (double)NUMP *b;
+    
+    if((fabs(P2.p) >= fabs(d)) && (fabs(P1.p) < fabs(d))) {
+      dt = P2.t - P1.t;
+      dp = P2.p - P1.p;
+      t = P1.t + dt / dp * (d - P1.p);
+      V = InterpolateCurve(c, t, 0);
+      pV = Create_Vertex(++THEM->MaxPointNum, V.Pos.X, V.Pos.Y, V.Pos.Z, V.lc, t);
+      pV->w = V.w;
       pV->ListCurves = List_Create(1, 1, sizeof(Curve *));
       List_Add(pV->ListCurves, &c);
       Tree_Add(THEM->Vertices, &pV);
       List_Add(c->Vertices, &pV);
-    }
-
-    count = NUMP = 1;
-    while(NUMP < N - 1) {
-      List_Read(Points, count - 1, &P1);
-      List_Read(Points, count, &P2);
-      d = (double)NUMP *b;
-
-      if((fabs(P2.p) >= fabs(d)) && (fabs(P1.p) < fabs(d))) {
-        dt = P2.t - P1.t;
-        dp = P2.p - P1.p;
-        t = P1.t + dt / dp * (d - P1.p);
-        V = InterpolateCurve(c, t, 0);
-        pV = Create_Vertex(++THEM->MaxPointNum, V.Pos.X, V.Pos.Y, V.Pos.Z, V.lc, t);
-        pV->w = V.w;
-        pV->ListCurves = List_Create(1, 1, sizeof(Curve *));
-        List_Add(pV->ListCurves, &c);
-        Tree_Add(THEM->Vertices, &pV);
-        List_Add(c->Vertices, &pV);
-        NUMP++;
-      }
-      else {
-        count++;
-      }
-    }
-
-    List_Delete(Points);
-
-    v = &c->end;
-    if((vexist = (Vertex **) Tree_PQuery(THEM->Vertices, v))) {
-      (*vexist)->u = c->uend;
-      if((*vexist)->ListCurves)
-        List_Add((*vexist)->ListCurves, &c);
-      List_Add(c->Vertices, vexist);
+      NUMP++;
     }
     else {
-      pV = Create_Vertex((*v)->Num, (*v)->Pos.X, (*v)->Pos.Y,
-                         (*v)->Pos.Z, (*v)->lc, c->uend);
-      pV->ListCurves = List_Create(1, 1, sizeof(Curve *));
-      List_Add(pV->ListCurves, &c);
-      Tree_Add(THEM->Vertices, &pV);
-      List_Add(c->Vertices, &pV);
+      count++;
     }
   }
-
+  
+  List_Delete(Points);
+  
+  v = &c->end;
+  if((vexist = (Vertex **) Tree_PQuery(THEM->Vertices, v))) {
+    (*vexist)->u = c->uend;
+    if((*vexist)->ListCurves)
+      List_Add((*vexist)->ListCurves, &c);
+    List_Add(c->Vertices, vexist);
+  }
+  else {
+    pV = Create_Vertex((*v)->Num, (*v)->Pos.X, (*v)->Pos.Y,
+		       (*v)->Pos.Z, (*v)->lc, c->uend);
+    pV->ListCurves = List_Create(1, 1, sizeof(Curve *));
+    List_Add(pV->ListCurves, &c);
+    Tree_Add(THEM->Vertices, &pV);
+    List_Add(c->Vertices, &pV);
+  }
+  
   for(i = 0; i < List_Nbr(c->Vertices) - 1; i++) {
     List_Read(c->Vertices, i, &v1);
     List_Read(c->Vertices, i + 1, &v2);
@@ -254,15 +260,4 @@ void Maillage_Curve(void *data, void *dummy)
   }
 
   THEM->Statistics[4] += List_Nbr(c->Vertices);
-
-#if 0
-  if(fabs(c->Num) != 41)
-    return;
-  printf("curve %d : ", c->Num);
-  for(i = 0; i < List_Nbr(c->Vertices); i++) {
-    List_Read(c->Vertices, i, &v1);
-    printf(" %d (%g %g %g)", v1->Num, v1->Pos.X, v1->Pos.Y, v1->Pos.Z);
-  }
-  printf("\n");
-#endif
 }
diff --git a/Mesh/3D_Extrude.cpp b/Mesh/3D_Extrude.cpp
index 78180286c9700470c9f5dd69e5179aec8c083282..cbb2c790281b99dde40382eb7e3bad632cf9cc17 100644
--- a/Mesh/3D_Extrude.cpp
+++ b/Mesh/3D_Extrude.cpp
@@ -1,4 +1,4 @@
-// $Id: 3D_Extrude.cpp,v 1.64 2003-03-21 00:52:41 geuzaine Exp $
+// $Id: 3D_Extrude.cpp,v 1.65 2003-10-26 16:53:12 geuzaine Exp $
 //
 // Copyright (C) 1997-2003 C. Geuzaine, J.-F. Remacle
 //
@@ -658,13 +658,16 @@ void Extrude_Surface3(Surface * s)
 }
 
 
-void Create_Tri(Vertex * v1, Vertex * v2, Vertex * v3)
+void Create_Tri(int iEnt, Vertex * v1, Vertex * v2, Vertex * v3)
 {
   Simplex *s;
   if(CTX.mesh.allow_degenerated_extrude ||
      (v1->Num != v2->Num && v1->Num != v3->Num && v2->Num != v3->Num)) {
     s = Create_Simplex(v1, v2, v3, NULL);
-    s->iEnt = THES->Num;
+    if(!ep->useZonLayer())
+      s->iEnt = THES->Num;
+    else
+      s->iEnt = iEnt;
     s->Num = -s->Num;   //Tag triangles to re-extrude
     Tree_Add(THES->Simplexes, &s);
   }
@@ -701,7 +704,10 @@ void Extrude_Seg(Vertex * V1, Vertex * V2)
         }
         else
           s = Create_Quadrangle(v1, v2, v4, v3);
-        s->iEnt = THES->Num;
+        if(!ep->useZonLayer())
+	  s->iEnt = THES->Num;
+	else
+	  s->iEnt = ep->mesh.ZonLayer[i];
         s->Num = -s->Num;       //Tag quadrangles to re-extrude
         Tree_Add(THES->Simplexes, &s);
 
@@ -710,12 +716,12 @@ void Extrude_Seg(Vertex * V1, Vertex * V2)
       }
       else {
         if(are_exist(v3, v2, Tree_Ares)) {
-          Create_Tri(v3, v2, v1);
-          Create_Tri(v3, v4, v2);
+          Create_Tri(ep->mesh.ZonLayer[i], v3, v2, v1);
+          Create_Tri(ep->mesh.ZonLayer[i], v3, v4, v2);
         }
         else {
-          Create_Tri(v3, v4, v1);
-          Create_Tri(v1, v4, v2);
+          Create_Tri(ep->mesh.ZonLayer[i], v3, v4, v1);
+          Create_Tri(ep->mesh.ZonLayer[i], v1, v4, v2);
         }
       }
       k++;
@@ -820,12 +826,22 @@ void copy_mesh(Curve * from, Curve * to, int direction)
     List_Add(to->Vertices, &newv);
   }
 
+  for(int i = 0; i < List_Nbr(to->Vertices) - 1; i++) {
+    Vertex *v1, *v2;
+    List_Read(to->Vertices, i, &v1);
+    List_Read(to->Vertices, i + 1, &v2);
+    Simplex *s = Create_Simplex(v1, v2, NULL, NULL);
+    s->iEnt = to->Num;
+    Tree_Add(to->Simplexes, &s);
+    List_Add(to->TrsfSimplexes, &s);
+  }
+
 }
 
 int Extrude_Mesh(Curve * c)
 {
-  int i;
-  Vertex **vexist, *v, *newv;
+  int i, j;
+  Vertex **vexist, *v, *newv, *v1, *v2;
   List_T *L;
 
   if(!c->Extrude || !c->Extrude->mesh.ExtrudeMesh)
@@ -881,15 +897,37 @@ int Extrude_Mesh(Curve * c)
       Tree_Add(THEM->Vertices, &newv);
       List_Add(c->Vertices, &newv);
     }
-    return true;
+
+    int k = 0, iEnt;
+    for(i = 0; i < ep->mesh.NbLayer; i++) {
+      for(j = 0; j < ep->mesh.NbElmLayer[i]; j++) {
+	if(k >= List_Nbr(c->Vertices) - 1){
+	  Msg(GERROR, "Something wrong in number of elements in extruded curve %d",
+	      c->Num);
+	  return false;
+	}
+	List_Read(c->Vertices, k, &v1);
+	List_Read(c->Vertices, k + 1, &v2);
+	Simplex *s = Create_Simplex(v1, v2, NULL, NULL);
+	if(!ep->useZonLayer())
+	  s->iEnt = c->Num;
+	else
+	  s->iEnt = ep->mesh.ZonLayer[i];
+	Tree_Add(c->Simplexes, &s);
+	List_Add(c->TrsfSimplexes, &s);
+	k++;
+      }
+    }
+
   }
   else {
     Curve *cc = FindCurve(abs(ep->geo.Source), THEM);
     if(!cc)
       return false;
     copy_mesh(cc, c, sign(ep->geo.Source));
-    return true;
   }
+
+  return true;
 }
 
 void copy_mesh(Surface * from, Surface * to)
diff --git a/doc/README.win32 b/doc/README.win32
index 498ff59c592ae5830018f1e6fa7f10ff35cbb3fc..ce2a9eb33d54e4bc444f0004ce5d7bf0f71c4355 100644
--- a/doc/README.win32
+++ b/doc/README.win32
@@ -1,4 +1,4 @@
-$Id: README.win32,v 1.2 2003-03-06 23:01:17 geuzaine Exp $
+$Id: README.win32,v 1.3 2003-10-26 16:53:12 geuzaine Exp $
 
 1) About opengl32.dll and glu32.dll:
 
@@ -17,8 +17,7 @@ of applications sharing the library and running simultaneously.
 
 3) About configuration files:
 
-Gmsh saves session information and default options in the $TMP (or
-$TEMP) directory. If the variables $TMP and $TEMP are undefined, Gmsh
-will save/load its configuration files from the current working
-directory.
-
+Gmsh saves session information and default options in the $GMSH_HOME
+directory, or the $TMP or $TEMP directories if $GMSH_HOME is not
+defined. If none of theses variables are defined, Gmsh will save/load
+its configuration files from the current working directory.
diff --git a/doc/VERSIONS b/doc/VERSIONS
index f4c0ffe04cdededa5df9aa7c35ec557bad4c411d..c71f01f03aec27b668d31c5e9a89dd92f5cdff7b 100644
--- a/doc/VERSIONS
+++ b/doc/VERSIONS
@@ -1,10 +1,12 @@
-$Id: VERSIONS,v 1.156 2003-09-19 17:22:27 geuzaine Exp $
+$Id: VERSIONS,v 1.157 2003-10-26 16:53:12 geuzaine Exp $
 
-New in 1.47: fix extrusion of surfaces defined by only two curves;
+New in 1.47: fixed extrusion of surfaces defined by only two curves;
 new syntax to retrieve point coordinates and indices of entities
-created through geometrical transformations; new PDF output format;
+created through geometrical transformations; new PDF and compressed
+PostScript output formats; fixed numbering of elements created with
+"Extrude Point/Line"; use $GMSH_HOME as home directory if defined;
 
-New in 1.46: fix crash for very long command lines; new options for
+New in 1.46: fixed crash for very long command lines; new options for
 setting the displacement factor and Triangle's parameters + renamed a
 couple of options to more sensible names (View.VectorType,
 View.ArrowSize); various small bug fixes; documentation update;