diff --git a/Common/Context.h b/Common/Context.h
index 6ddae285112c8878223de934d8a839441718ee6b..0071dd9b4af19a05c7a581a80a595f403ab5754c 100644
--- a/Common/Context.h
+++ b/Common/Context.h
@@ -145,6 +145,7 @@ public :
       return val;
     }
     int oldxtrude, oldxtrude_recombine, check_duplicates;
+    int allow_degenerated_extrude;
   } mesh;
 
   // post processing options 
diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h
index 2773aecb136fd89d80d90aec5e09ae00ec7f7d9d..0f8cb7772bedfc260519f6d552acc5ea1b68d177 100644
--- a/Common/DefaultOptions.h
+++ b/Common/DefaultOptions.h
@@ -391,6 +391,8 @@ StringXNumber MeshOptions_Number[] = {
     "Third clip plane equation coefficient ('C' in equation 'AX+BY+CZ+D=0')" },
   { F, "cut_planed" , opt_mesh_cut_planed , 0. , 
     "Fourth clip plane equation coefficient ('D' in equation 'AX+BY+CZ+D=0')" },
+  { F, "AllowDegeneratedExtrude" , opt_mesh_allow_degenerated_extrude , 0. , 
+    "Allow the generation of degenerated hexahedra or prisms during extrusion" },
   { 0, NULL , NULL , 0. , NULL }
 } ;
 
diff --git a/Common/GetOptions.cpp b/Common/GetOptions.cpp
index a341e2a80209665979befcd1cfbd50f1dee695c5..beed4bc2a6685c6054a3f2ed92ea0d65779c6cdc 100644
--- a/Common/GetOptions.cpp
+++ b/Common/GetOptions.cpp
@@ -1,4 +1,4 @@
-// $Id: GetOptions.cpp,v 1.37 2001-08-24 06:58:19 geuzaine Exp $
+// $Id: GetOptions.cpp,v 1.38 2001-08-28 20:40:21 geuzaine Exp $
 
 #include <unistd.h>
 #include "Gmsh.h"
@@ -37,7 +37,7 @@ void Print_Usage(char *name){
   Msg(DIRECT, "  -1, -2, -3            perform batch 1D, 2D and 3D mesh generation");
   Msg(DIRECT, "  -o file               specify mesh output file name");
   Msg(DIRECT, "  -format msh|unv|gref  set output mesh format (default: msh)");
-  Msg(DIRECT, "  -algo iso|aniso|tri   select 2D mesh algorithm (default: iso)");
+  Msg(DIRECT, "  -algo iso|tri|aniso   select 2D mesh algorithm (default: iso)");
   Msg(DIRECT, "  -smooth int           set mesh smoothing (default: 0)");
   Msg(DIRECT, "  -degree int           set mesh degree (default: 1)");
   Msg(DIRECT, "  -scale float          set global scaling factor (default: 1.0)");
@@ -302,10 +302,10 @@ void Get_Options (int argc, char *argv[], int *nbfiles) {
         if(argv[i]!=NULL){
           if(!strncmp(argv[i],"iso",3))
             CTX.mesh.algo = DELAUNAY_ISO ;
-          else if(!strncmp(argv[i],"aniso",5))
-            CTX.mesh.algo = DELAUNAY_ANISO ;
           else if(!strncmp(argv[i],"tri",3))
             CTX.mesh.algo = DELAUNAY_SHEWCHUK ;
+          else if(!strncmp(argv[i],"aniso",5))
+            CTX.mesh.algo = DELAUNAY_ANISO ;
           else{
             fprintf(stderr, ERROR_STR "Unknown mesh algorithm\n");
             exit(1);
diff --git a/Common/Options.cpp b/Common/Options.cpp
index 35f60d020cc328ed3eb90b8dbcc037fbc23d6ab6..5cbabacb3c53e7f89f7958bb4b7a99b6436eec9f 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -1,4 +1,4 @@
-// $Id: Options.cpp,v 1.43 2001-08-24 06:58:19 geuzaine Exp $
+// $Id: Options.cpp,v 1.44 2001-08-28 20:40:21 geuzaine Exp $
 
 #include "Gmsh.h"
 #include "GmshUI.h"
@@ -1465,6 +1465,11 @@ double opt_mesh_cut_planed(OPT_ARGS_NUM){
     CTX.mesh.cut_planed = val;
   return CTX.mesh.cut_planed;
 }
+double opt_mesh_allow_degenerated_extrude(OPT_ARGS_NUM){
+  if(action & GMSH_SET) 
+    CTX.mesh.allow_degenerated_extrude = (int)val;
+  return CTX.mesh.allow_degenerated_extrude;
+}
 double opt_mesh_color_scheme(OPT_ARGS_NUM){
   if(action & GMSH_SET){
     CTX.mesh.color_scheme = (int)val;
diff --git a/Common/Options.h b/Common/Options.h
index 9b6eee7a1841073f70b442579e573bc6ffd813c2..d9fff827770358b32c89dd6745a6d96088183421 100644
--- a/Common/Options.h
+++ b/Common/Options.h
@@ -180,6 +180,7 @@ double opt_mesh_cut_planea(OPT_ARGS_NUM);
 double opt_mesh_cut_planeb(OPT_ARGS_NUM);
 double opt_mesh_cut_planec(OPT_ARGS_NUM);
 double opt_mesh_cut_planed(OPT_ARGS_NUM);
+double opt_mesh_allow_degenerated_extrude(OPT_ARGS_NUM);
 double opt_mesh_color_scheme(OPT_ARGS_NUM);
 double opt_mesh_color_carousel(OPT_ARGS_NUM);
 double opt_solver_getdp_popupmessages(OPT_ARGS_NUM);
diff --git a/Fltk/GUI.cpp b/Fltk/GUI.cpp
index 2fcefbd7d99209e1ccc256f6c417efaa991f4502..8ff269406f57aafe55bce24d9f42e2b81e9df332 100644
--- a/Fltk/GUI.cpp
+++ b/Fltk/GUI.cpp
@@ -1,4 +1,4 @@
-// $Id: GUI.cpp,v 1.111 2001-08-26 12:12:18 geuzaine Exp $
+// $Id: GUI.cpp,v 1.112 2001-08-28 20:40:21 geuzaine Exp $
 
 // To make the interface as visually consistent as possible, please:
 // - use the BH, BW, WB, IW values for button heights/widths, window borders, etc.
@@ -1525,13 +1525,13 @@ void GUI::create_post_options_window(){
 //*********************** Create the window for the statistics *************************
 
 void GUI::create_statistics_window(){
-  int i;
+  int i, num=0;
 
   if(!init_statistics_window){
     init_statistics_window = 1 ;
 
     int width = 24*CTX.fontsize;
-    int height = 5*WB+16*BH ;
+    int height = 5*WB+17*BH ;
 
     stat_window = new Fl_Window(width,height);
     stat_window->box(WINDOW_BOX);
@@ -1542,37 +1542,40 @@ void GUI::create_statistics_window(){
 	Fl_Group* o = new Fl_Group(WB, WB+BH, width-2*WB, height-3*WB-2*BH, "Geometry");
 	o->labelsize(CTX.fontsize);
 	o->hide();
-	stat_value[0] = new Fl_Output(2*WB, 2*WB+1*BH, IW, BH, "Points");
-	stat_value[1] = new Fl_Output(2*WB, 2*WB+2*BH, IW, BH, "Curves");
-	stat_value[2] = new Fl_Output(2*WB, 2*WB+3*BH, IW, BH, "Surfaces");
-	stat_value[3] = new Fl_Output(2*WB, 2*WB+4*BH, IW, BH, "Volumes");
+	stat_value[num++] = new Fl_Output(2*WB, 2*WB+1*BH, IW, BH, "Points");
+	stat_value[num++] = new Fl_Output(2*WB, 2*WB+2*BH, IW, BH, "Curves");
+	stat_value[num++] = new Fl_Output(2*WB, 2*WB+3*BH, IW, BH, "Surfaces");
+	stat_value[num++] = new Fl_Output(2*WB, 2*WB+4*BH, IW, BH, "Volumes");
 	o->end();
       }
       { 
 	Fl_Group* o = new Fl_Group(WB, WB+BH, width-2*WB, height-3*WB-2*BH, "Mesh");
 	o->labelsize(CTX.fontsize);
-	stat_value[4] = new Fl_Output(2*WB, 2*WB+1*BH, IW, BH, "Nodes on curves");
-	stat_value[5] = new Fl_Output(2*WB, 2*WB+2*BH, IW, BH, "Nodes on surfaces");
-	stat_value[6] = new Fl_Output(2*WB, 2*WB+3*BH, IW, BH, "Nodes in volumes");
-	stat_value[7] = new Fl_Output(2*WB, 2*WB+4*BH, IW, BH, "Triangles");
-	stat_value[8] = new Fl_Output(2*WB, 2*WB+5*BH, IW, BH, "Quadrangles");
-	stat_value[9] = new Fl_Output(2*WB, 2*WB+6*BH, IW, BH, "Tetrahedra");
-	stat_value[10] = new Fl_Output(2*WB, 2*WB+7*BH, IW, BH, "Hexahedra");
-	stat_value[11] = new Fl_Output(2*WB, 2*WB+8*BH, IW, BH, "Prisms");
-	stat_value[12] = new Fl_Output(2*WB, 2*WB+9*BH, IW, BH, "Time for 1D mesh");
-	stat_value[13] = new Fl_Output(2*WB, 2*WB+10*BH, IW, BH, "Time for 2D mesh");
-	stat_value[14] = new Fl_Output(2*WB, 2*WB+11*BH, IW, BH, "Time for 3D mesh");
-	stat_value[15] = new Fl_Output(2*WB, 2*WB+12*BH, IW, BH, "Gamma factor");
-	stat_value[16] = new Fl_Output(2*WB, 2*WB+13*BH, IW, BH, "Eta factor");
-	stat_value[17] = new Fl_Output(2*WB, 2*WB+14*BH, IW, BH, "Rho factor");
-
-	Fl_Button* b0 = new Fl_Button(width-BB-2*WB, 2*WB+12*BH, BB, BH, "List");
+	stat_value[num++] = new Fl_Output(2*WB, 2*WB+1*BH, IW, BH, "Nodes on curves");
+	stat_value[num++] = new Fl_Output(2*WB, 2*WB+2*BH, IW, BH, "Nodes on surfaces");
+	stat_value[num++] = new Fl_Output(2*WB, 2*WB+3*BH, IW, BH, "Nodes in volumes");
+	stat_value[num++] = new Fl_Output(2*WB, 2*WB+4*BH, IW, BH, "Triangles");
+	stat_value[num++] = new Fl_Output(2*WB, 2*WB+5*BH, IW, BH, "Quadrangles");
+	stat_value[num++] = new Fl_Output(2*WB, 2*WB+6*BH, IW, BH, "Tetrahedra");
+	stat_value[num++] = new Fl_Output(2*WB, 2*WB+7*BH, IW, BH, "Hexahedra");
+	stat_value[num++] = new Fl_Output(2*WB, 2*WB+8*BH, IW, BH, "Prisms");
+	stat_value[num++] = new Fl_Output(2*WB, 2*WB+9*BH, IW, BH, "Pyramids");
+
+	stat_value[num++] = new Fl_Output(2*WB, 2*WB+10*BH, IW, BH, "Time for 1D mesh");
+	stat_value[num++] = new Fl_Output(2*WB, 2*WB+11*BH, IW, BH, "Time for 2D mesh");
+	stat_value[num++] = new Fl_Output(2*WB, 2*WB+12*BH, IW, BH, "Time for 3D mesh");
+
+	stat_value[num++] = new Fl_Output(2*WB, 2*WB+13*BH, IW, BH, "Gamma factor");
+	stat_value[num++] = new Fl_Output(2*WB, 2*WB+14*BH, IW, BH, "Eta factor");
+	stat_value[num++] = new Fl_Output(2*WB, 2*WB+15*BH, IW, BH, "Rho factor");
+
+	Fl_Button* b0 = new Fl_Button(width-BB-2*WB, 2*WB+13*BH, BB, BH, "List");
 	b0->labelsize(CTX.fontsize);
 	b0->callback(opt_statistics_histogram_cb, (void*)0);
-	Fl_Button* b1 = new Fl_Button(width-BB-2*WB, 2*WB+13*BH, BB, BH, "List");
+	Fl_Button* b1 = new Fl_Button(width-BB-2*WB, 2*WB+14*BH, BB, BH, "List");
 	b1->labelsize(CTX.fontsize);
 	b1->callback(opt_statistics_histogram_cb, (void*)1);
-	Fl_Button* b2 = new Fl_Button(width-BB-2*WB, 2*WB+14*BH, BB, BH, "List");
+	Fl_Button* b2 = new Fl_Button(width-BB-2*WB, 2*WB+15*BH, BB, BH, "List");
 	b2->labelsize(CTX.fontsize);
 	b2->callback(opt_statistics_histogram_cb, (void*)2);
 
@@ -1582,17 +1585,17 @@ void GUI::create_statistics_window(){
 	Fl_Group* o = new Fl_Group(WB, WB+BH, width-2*WB, height-3*WB-2*BH, "Post-processing");
 	o->labelsize(CTX.fontsize);
 	o->hide();
-	stat_value[18] = new Fl_Output(2*WB, 2*WB+1*BH, IW, BH, "Views");
-	stat_value[19] = new Fl_Output(2*WB, 2*WB+2*BH, IW, BH, "Visible points");
-	stat_value[20] = new Fl_Output(2*WB, 2*WB+3*BH, IW, BH, "Visible lines");
-	stat_value[21] = new Fl_Output(2*WB, 2*WB+4*BH, IW, BH, "Visible triangles");
-	stat_value[22] = new Fl_Output(2*WB, 2*WB+5*BH, IW, BH, "Visible tetrahedra");
+	stat_value[num++] = new Fl_Output(2*WB, 2*WB+1*BH, IW, BH, "Views");
+	stat_value[num++] = new Fl_Output(2*WB, 2*WB+2*BH, IW, BH, "Visible points");
+	stat_value[num++] = new Fl_Output(2*WB, 2*WB+3*BH, IW, BH, "Visible lines");
+	stat_value[num++] = new Fl_Output(2*WB, 2*WB+4*BH, IW, BH, "Visible triangles");
+	stat_value[num++] = new Fl_Output(2*WB, 2*WB+5*BH, IW, BH, "Visible tetrahedra");
 	o->end();
       }
       o->end();
     }
 
-    for(i=0 ; i<23 ; i++){
+    for(i=0 ; i<num ; i++){
       stat_value[i]->labelsize(CTX.fontsize);
       stat_value[i]->textsize(CTX.fontsize);
       stat_value[i]->type(FL_HORIZONTAL);
@@ -1631,40 +1634,44 @@ void GUI::create_statistics_window(){
 
 void GUI::set_statistics(){
 
-  int i;	
+  int i,num=0;
   static double  s[50], p[20];
   static char    label[50][256];
 
   GetStatistics(s);
 
   // geom
-  sprintf(label[0], "%g", s[0]); stat_value[0]->value(label[0]);
-  sprintf(label[1], "%g", s[1]); stat_value[1]->value(label[1]);
-  sprintf(label[2], "%g", s[2]); stat_value[2]->value(label[2]);
-  sprintf(label[3], "%g", s[3]); stat_value[3]->value(label[3]);
+  sprintf(label[num], "%g", s[0]); stat_value[num]->value(label[num]); num++;
+  sprintf(label[num], "%g", s[1]); stat_value[num]->value(label[num]); num++;
+  sprintf(label[num], "%g", s[2]); stat_value[num]->value(label[num]); num++;
+  sprintf(label[num], "%g", s[3]); stat_value[num]->value(label[num]); num++;
 
   // mesh
-  sprintf(label[4], "%g", s[4]); stat_value[4]->value(label[4]);
-  sprintf(label[5], "%g", s[5]); stat_value[5]->value(label[5]);
-  sprintf(label[6], "%g", s[6]); stat_value[6]->value(label[6]);
-  sprintf(label[7], "%g", s[7]-s[8]); stat_value[7]->value(label[7]);
-  sprintf(label[8], "%g", s[8]); stat_value[8]->value(label[8]);
-  sprintf(label[9], "%g", s[9]); stat_value[9]->value(label[9]);
-  sprintf(label[10], "%g", s[10]); stat_value[10]->value(label[10]);
-  sprintf(label[11], "%g", s[11]); stat_value[11]->value(label[11]);
-  sprintf(label[12], "%g", s[12]); stat_value[12]->value(label[12]);
-  sprintf(label[13], "%g", s[13]); stat_value[13]->value(label[13]);
-  sprintf(label[14], "%g", s[14]); stat_value[14]->value(label[14]);
-  sprintf(label[15], "%.4g (%.4g->%.4g)", s[17], s[19], s[18]); 
-  stat_value[15]->value(label[15]);
-  sprintf(label[16], "%.4g (%.4g->%.4g)", s[20], s[22], s[21]); 
-  stat_value[16]->value(label[16]);
-  sprintf(label[17], "%.4g (%.4g->%.4g)", s[23], s[25], s[24]);
-  stat_value[17]->value(label[17]);
+  sprintf(label[num], "%g", s[4]);  stat_value[num]->value(label[num]); num++;
+  sprintf(label[num], "%g", s[5]);  stat_value[num]->value(label[num]); num++;
+  sprintf(label[num], "%g", s[6]);  stat_value[num]->value(label[num]); num++;
+  sprintf(label[num], "%g", s[7]-s[8]); 
+                                    stat_value[num]->value(label[num]); num++;
+  sprintf(label[num], "%g", s[8]);  stat_value[num]->value(label[num]); num++;
+  sprintf(label[num], "%g", s[9]);  stat_value[num]->value(label[num]); num++;
+  sprintf(label[num], "%g", s[10]); stat_value[num]->value(label[num]); num++;
+  sprintf(label[num], "%g", s[11]); stat_value[num]->value(label[num]); num++;
+  sprintf(label[num], "%g", s[12]); stat_value[num]->value(label[num]); num++;
+
+  sprintf(label[num], "%g", s[13]); stat_value[num]->value(label[num]); num++;
+  sprintf(label[num], "%g", s[14]); stat_value[num]->value(label[num]); num++;
+  sprintf(label[num], "%g", s[15]); stat_value[num]->value(label[num]); num++;
+
+  sprintf(label[num], "%.4g (%.4g->%.4g)", s[17], s[19], s[18]); 
+                                    stat_value[num]->value(label[num]); num++;
+  sprintf(label[num], "%.4g (%.4g->%.4g)", s[20], s[22], s[21]); 
+                                    stat_value[num]->value(label[num]); num++;
+  sprintf(label[num], "%.4g (%.4g->%.4g)", s[23], s[25], s[24]);
+                                    stat_value[num]->value(label[num]); num++;
 
   // post
   p[0] = List_Nbr(Post_ViewList) ;
-  sprintf(label[18], "%g", p[0]); stat_value[18]->value(label[18]);
+  sprintf(label[num], "%g", p[0]); stat_value[num]->value(label[num]); num++;
   p[1] = p[2] = p[3] = p[4] = p[5] = p[6] = p[7] = p[8] = 0 ;
   for(i=0 ; i<List_Nbr(Post_ViewList) ; i++){
     Post_View *v = (Post_View*)List_Pointer(Post_ViewList, i);
@@ -1687,10 +1694,10 @@ void GUI::set_statistics(){
    			            (v->DrawTensors ? v->NbTS : 0) ;
     }
   }
-  sprintf(label[19], "%g/%g", p[5],p[1]); stat_value[19]->value(label[19]);
-  sprintf(label[20], "%g/%g", p[6],p[2]); stat_value[20]->value(label[20]);
-  sprintf(label[21], "%g/%g", p[7],p[3]); stat_value[21]->value(label[21]);
-  sprintf(label[22], "%g/%g", p[8],p[4]); stat_value[22]->value(label[22]);
+  sprintf(label[num], "%g/%g", p[5],p[1]); stat_value[num]->value(label[num]); num++;
+  sprintf(label[num], "%g/%g", p[6],p[2]); stat_value[num]->value(label[num]); num++;
+  sprintf(label[num], "%g/%g", p[7],p[3]); stat_value[num]->value(label[num]); num++;
+  sprintf(label[num], "%g/%g", p[8],p[4]); stat_value[num]->value(label[num]); num++;
 }
 
 
diff --git a/Geo/CAD.cpp b/Geo/CAD.cpp
index d54d097834cd9c56c6fd5bfba956aa9d61df3279..23636e9d973e8d36d7840e039f3898b114f3a13f 100644
--- a/Geo/CAD.cpp
+++ b/Geo/CAD.cpp
@@ -1,4 +1,4 @@
-// $Id: CAD.cpp,v 1.30 2001-08-17 08:31:31 geuzaine Exp $
+// $Id: CAD.cpp,v 1.31 2001-08-28 20:40:21 geuzaine Exp $
 
 #include "Gmsh.h"
 #include "Numeric.h"
@@ -998,7 +998,11 @@ Surface *Extrude_ProtudeCurve(int ep, int ic,
   
   if(!CurveBeg && !CurveEnd) return NULL;
 
-  s = Create_Surface(MAXREG++,MSH_SURF_REGL,0);
+  if(!CurveBeg || !CurveEnd)
+    s = Create_Surface(MAXREG++,MSH_SURF_TRIC,0);
+  else
+    s = Create_Surface(MAXREG++,MSH_SURF_REGL,0);
+
   s->Generatrices = List_Create(4,1,sizeof(Curve*));
   
   // je me souviens
diff --git a/Graphics/Draw.h b/Graphics/Draw.h
index 9e40de96b7d8947ae594240cd5df0f80919f26a5..c06258d3a7260365e912162eda3fab435988485a 100644
--- a/Graphics/Draw.h
+++ b/Graphics/Draw.h
@@ -76,6 +76,7 @@ void Draw_Simplex_Curves(void *a,void *b);
 
 void Draw_Hexahedron_Volume (void *a, void *b);
 void Draw_Prism_Volume (void *a, void *b);
+void Draw_Pyramid_Volume (void *a, void *b);
 
 void Draw_ScalarPoint(Post_View *View, 
 		      double ValMin, double ValMax, double Raise[3][5],
diff --git a/Graphics/Mesh.cpp b/Graphics/Mesh.cpp
index 27590b76e48d491a77488bb65a09acd7e7ef6ecd..921224ec364a247f1d8c7967a78e70b562aa7826 100644
--- a/Graphics/Mesh.cpp
+++ b/Graphics/Mesh.cpp
@@ -1,4 +1,4 @@
-// $Id: Mesh.cpp,v 1.40 2001-08-13 12:10:30 geuzaine Exp $
+// $Id: Mesh.cpp,v 1.41 2001-08-28 20:40:21 geuzaine Exp $
 
 #include "Gmsh.h"
 #include "GmshUI.h"
@@ -155,6 +155,7 @@ void Draw_Mesh_Volumes(void *a, void *b){
   Tree_Action((*v)->Simplexes, Draw_Simplex_Volume);
   Tree_Action((*v)->Hexahedra, Draw_Hexahedron_Volume);
   Tree_Action((*v)->Prisms, Draw_Prism_Volume);
+  Tree_Action((*v)->Pyramids, Draw_Pyramid_Volume);
 }
 
 void Draw_Mesh_Surfaces (void *a,void *b){
@@ -814,3 +815,68 @@ void Draw_Prism_Volume (void *a, void *b){
 
 }
 
+/* ------------------------------------------------------------------------ */
+/*  D r a w _ P y r a m i d                                                 */
+/* ------------------------------------------------------------------------ */
+
+void Draw_Pyramid_Volume (void *a, void *b){
+  Pyramid **p;
+  int i ;
+  double Xc = 0.0 , Yc = 0.0, Zc = 0.0, X[5],Y[5],Z[5] ;
+  char Num[100];
+
+  p = (Pyramid**)a;
+
+  if(!EntiteEstElleVisible((*p)->iEnt)) return;
+
+  for(i=0 ; i<5 ; i++){
+    Xc += (*p)->V[i]->Pos.X;
+    Yc += (*p)->V[i]->Pos.Y;
+    Zc += (*p)->V[i]->Pos.Z;
+  }
+  Xc /= 5. ; 
+  Zc /= 5. ; 
+  Yc /= 5. ; 
+
+  if(CTX.mesh.use_cut_plane){
+    if(CTX.mesh.evalCutPlane(Xc,Yc,Zc) < 0)return;
+  }
+
+  if(CTX.mesh.color_carousel)
+    ColorSwitch((*p)->iEnt);
+  else
+    glColor4ubv((GLubyte*)&CTX.color.mesh.pyramid);
+
+  for (i=0 ; i<5 ; i++) {
+    X[i] = Xc + CTX.mesh.explode * ((*p)->V[i]->Pos.X - Xc);
+    Y[i] = Yc + CTX.mesh.explode * ((*p)->V[i]->Pos.Y - Yc);
+    Z[i] = Zc + CTX.mesh.explode * ((*p)->V[i]->Pos.Z - Zc);
+  }
+  
+  glBegin(GL_LINE_LOOP);
+  glVertex3d(X[0], Y[0], Z[0]);
+  glVertex3d(X[1], Y[1], Z[1]);
+  glVertex3d(X[2], Y[2], Z[2]);
+  glVertex3d(X[3], Y[3], Z[3]);
+  glEnd();    
+
+  glBegin(GL_LINES);
+  glVertex3d(X[0], Y[0], Z[0]);
+  glVertex3d(X[4], Y[4], Z[4]);
+  glVertex3d(X[1], Y[1], Z[1]);
+  glVertex3d(X[4], Y[4], Z[4]);
+  glVertex3d(X[2], Y[2], Z[2]);
+  glVertex3d(X[4], Y[4], Z[4]);
+  glVertex3d(X[3], Y[3], Z[3]);
+  glVertex3d(X[4], Y[4], Z[4]);
+  glEnd();    
+
+  if(CTX.mesh.volumes_num){
+    sprintf(Num,"%d",(*p)->Num);
+    glRasterPos3d(Xc,Yc,Zc);
+    Draw_String(Num);
+  }
+
+}
+
+
diff --git a/Mesh/3D_Extrude.cpp b/Mesh/3D_Extrude.cpp
index 2695f6b61bd6af3b09ca03934228001e872acbf2..8820140ff79e51a77ad6f2d11bca5b1a106e3d49 100644
--- a/Mesh/3D_Extrude.cpp
+++ b/Mesh/3D_Extrude.cpp
@@ -1,4 +1,4 @@
-// $Id: 3D_Extrude.cpp,v 1.42 2001-08-28 15:37:15 geuzaine Exp $
+// $Id: 3D_Extrude.cpp,v 1.43 2001-08-28 20:40:21 geuzaine Exp $
 
 #include "Gmsh.h"
 #include "Numeric.h"
@@ -8,6 +8,7 @@
 #include "Context.h"
 #include "Create.h"
 
+extern Context_T  CTX ;
 extern Mesh      *THEM;
 extern int        CurrentNodeNumber;
 
@@ -219,13 +220,101 @@ void Extrude_Simplex_Phase1 (void *data, void *dum){
   }
 }
 
+void Create_HexPri(int iEnt, Vertex *v[8]){
+  int i, j=0, dup[4];
+  Hexahedron *newh;
+  Prism *newp;
+
+  if(CTX.mesh.allow_degenerated_extrude){
+    newh = Create_Hexahedron(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7]);
+    newh->iEnt = iEnt;
+    Tree_Add(THEV->Hexahedra,&newh);
+    return;
+  }
+
+  for(i=0; i<4; i++)
+    if(v[i]->Num == v[i+4]->Num) dup[j++] = i;
+  
+  if(j==2){
+    if(dup[0]==0 && dup[1]==1)
+      newp = Create_Prism(v[0],v[3],v[7],v[1],v[6],v[2]);
+    else if(dup[0]==1 && dup[1]==2)
+      newp = Create_Prism(v[0],v[1],v[4],v[3],v[2],v[7]);
+    else if(dup[0]==2 && dup[1]==3)
+      newp = Create_Prism(v[0],v[3],v[4],v[1],v[5],v[7]);
+    else if(dup[0]==0 && dup[1]==3)
+      newp = Create_Prism(v[0],v[1],v[5],v[3],v[2],v[6]);
+    else{
+      Msg(GERROR, "Uncoherent hexahedron  (nodes %d %d %d %d %d %d %d %d)",
+	  v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7]);
+      return;
+    }
+    newp->iEnt = iEnt;
+    Tree_Add(THEV->Prisms,&newp);
+  }
+  else{
+    newh = Create_Hexahedron(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7]);
+    newh->iEnt = iEnt;
+    Tree_Add(THEV->Hexahedra,&newh);
+    if(j)
+      Msg(GERROR, "Degenerated hexahedron %d (nodes %d %d %d %d %d %d %d %d)", 
+	  newh->Num,v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7]);
+  }
+}
+
+void Create_PriPyrTet(int iEnt, Vertex *v[6]){
+  int i, j=0, dup[3];
+  Prism *newp;
+  Pyramid *newpyr;
+  Simplex *news;
+
+  if(CTX.mesh.allow_degenerated_extrude){
+    newp = Create_Prism(v[0],v[1],v[2],v[3],v[4],v[5]);
+    newp->iEnt = iEnt;
+    Tree_Add(THEV->Prisms,&newp);
+    return;
+  }
+
+  for(i=0; i<3; i++)
+    if(v[i]->Num == v[i+3]->Num) dup[j++] = i;
+
+  if(j==2){
+    if(dup[0]==0 && dup[1]==1)
+      news = Create_Simplex(v[0],v[1],v[2],v[5]);
+    else if(dup[0]==1 && dup[1]==2)
+      news = Create_Simplex(v[0],v[1],v[2],v[3]);
+    else
+      news = Create_Simplex(v[0],v[1],v[2],v[4]);
+    news->iEnt = iEnt;
+    Tree_Add(THEV->Simplexes,&news);
+  }
+  else if(j==1){
+    if(dup[0]==0)
+      newpyr = Create_Pyramid(v[1],v[4],v[5],v[2],v[0]);
+    else if(dup[0]==1)
+      newpyr = Create_Pyramid(v[0],v[2],v[5],v[3],v[1]);
+    else
+      newpyr = Create_Pyramid(v[0],v[1],v[4],v[3],v[2]);
+    newpyr->iEnt = iEnt;
+    Tree_Add(THEV->Pyramids,&newpyr);
+  }
+  else{
+    newp = Create_Prism(v[0],v[1],v[2],v[3],v[4],v[5]);
+    newp->iEnt = iEnt;
+    Tree_Add(THEV->Prisms,&newp);
+    if(j)
+      Msg(GERROR, "Degenerated prism %d (nodes %d %d %d %d %d %d %d %d)", 
+	  newp->Num,v[0],v[1],v[2],v[3],v[4],v[5]);
+  }
+
+}
+
+
 void Extrude_Simplex_Phase3 (void *data, void *dum){
 
   Simplex **pS, *s, *news;
-  Hexahedron *newh;
-  Prism *newp;
   int i, j, k;
-  Vertex *v1, *v2, *v3, *v4, *v5, *v6, *v7, *v8;
+  Vertex *v[8];
   List_T *L0, *L1, *L2, *L3;
 
   pS = (Simplex **) data;
@@ -246,127 +335,110 @@ void Extrude_Simplex_Phase3 (void *data, void *dum){
     for (j = 0; j < ep->mesh.NbElmLayer[i]; j++){
 
       if(s->V[3]){
-        List_Read(L0,k,&v1);
-        List_Read(L1,k,&v2);
-        List_Read(L2,k,&v3);
-        List_Read(L3,k,&v4);
-        List_Read(L0,k+1,&v5);
-        List_Read(L1,k+1,&v6);
-        List_Read(L2,k+1,&v7);
-        List_Read(L3,k+1,&v8);
+        List_Read(L0,k,&v[0]);
+        List_Read(L1,k,&v[1]);
+        List_Read(L2,k,&v[2]);
+        List_Read(L3,k,&v[3]);
+        List_Read(L0,k+1,&v[4]);
+        List_Read(L1,k+1,&v[5]);
+        List_Read(L2,k+1,&v[6]);
+        List_Read(L3,k+1,&v[7]);
       }		    
       else{	    
-        List_Read(L0, k, &v1);
-        List_Read(L1, k, &v2);
-        List_Read(L2, k, &v3);
-        List_Read(L0, k + 1, &v4);
-        List_Read(L1, k + 1, &v5);
-        List_Read(L2, k + 1, &v6);
+        List_Read(L0, k, &v[0]);
+        List_Read(L1, k, &v[1]);
+        List_Read(L2, k, &v[2]);
+        List_Read(L0, k + 1, &v[3]);
+        List_Read(L1, k + 1, &v[4]);
+        List_Read(L2, k + 1, &v[5]);
       }
 
       k++;
       if (ep->mesh.ZonLayer[i]){
 
         if(ep->mesh.Recombine){
-          if(s->V[3]){
-            newh = Create_Hexahedron(v1,v2,v3,v4,v5,v6,v7,v8);
-            newh->iEnt = ep->mesh.ZonLayer[i];
-            Tree_Add(THEV->Hexahedra,&newh);
-	    if(v1->Num == v5->Num || v2->Num == v6->Num ||
-	       v3->Num == v7->Num || v3->Num == v8->Num)
-	      Msg(WARNING, "Fixme! Hexahedron %d (nodes %d %d %d %d %d %d %d %d) is degenerated", 
-		  newh->Num, 
-		  v1->Num, v2->Num, v3->Num, v4->Num, 
-		  v5->Num, v6->Num, v7->Num, v8->Num);
-          }
-          else{
-            newp = Create_Prism(v1,v2,v3,v4,v5,v6);
-            newp->iEnt = ep->mesh.ZonLayer[i];
-            Tree_Add(THEV->Prisms,&newp);
-	    if(v1->Num == v4->Num || v2->Num == v5->Num || v3->Num == v6->Num)
-	      Msg(WARNING, "Fixme! Prism %d (nodes %d %d %d %d %d %d) is degenerated", 
-		  newp->Num, 
-		  v1->Num, v2->Num, v3->Num,
-		  v4->Num, v5->Num, v6->Num);
-          }
+          if(s->V[3])
+	    Create_HexPri(ep->mesh.ZonLayer[i],v);
+          else
+	    Create_PriPyrTet(ep->mesh.ZonLayer[i],v);
         }
         else{
           
-          if (are_exist (v4, v2, Tree_Ares) &&
-              are_exist (v5, v3, Tree_Ares) &&
-              are_exist (v4, v3, Tree_Ares)){
-            news = Create_Simplex (v1, v2, v3, v4);
+          if (are_exist (v[3], v[1], Tree_Ares) &&
+              are_exist (v[4], v[2], Tree_Ares) &&
+              are_exist (v[3], v[2], Tree_Ares)){
+            news = Create_Simplex (v[0], v[1], v[2], v[3]);
             news->iEnt = ep->mesh.ZonLayer[i];
             Tree_Add (THEV->Simplexes, &news);
-            news = Create_Simplex (v4, v5, v6, v3);
+            news = Create_Simplex (v[3], v[4], v[5], v[2]);
             news->iEnt = ep->mesh.ZonLayer[i];
             Tree_Add (THEV->Simplexes, &news);
-            news = Create_Simplex (v2, v4, v5, v3);
+            news = Create_Simplex (v[1], v[3], v[4], v[2]);
             news->iEnt = ep->mesh.ZonLayer[i];
             Tree_Add (THEV->Simplexes, &news);
           }
-          if (are_exist (v4, v2, Tree_Ares) &&
-              are_exist (v2, v6, Tree_Ares) &&
-              are_exist (v4, v3, Tree_Ares)){
-            news = Create_Simplex (v1, v2, v3, v4);
+          if (are_exist (v[3], v[1], Tree_Ares) &&
+              are_exist (v[1], v[5], Tree_Ares) &&
+              are_exist (v[3], v[2], Tree_Ares)){
+            news = Create_Simplex (v[0], v[1], v[2], v[3]);
             news->iEnt = ep->mesh.ZonLayer[i];
             Tree_Add (THEV->Simplexes, &news);
-            news = Create_Simplex (v4, v5, v6, v2);
+            news = Create_Simplex (v[3], v[4], v[5], v[1]);
             news->iEnt = ep->mesh.ZonLayer[i];
             Tree_Add (THEV->Simplexes, &news);
-            news = Create_Simplex (v4, v2, v6, v3);
+            news = Create_Simplex (v[3], v[1], v[5], v[2]);
             news->iEnt = ep->mesh.ZonLayer[i];
             Tree_Add (THEV->Simplexes, &news);
           }
-          if (are_exist (v4, v2, Tree_Ares) &&
-              are_exist (v2, v6, Tree_Ares) &&
-              are_exist (v6, v1, Tree_Ares)){
-            news = Create_Simplex (v1, v2, v3, v6);
+          if (are_exist (v[3], v[1], Tree_Ares) &&
+              are_exist (v[1], v[5], Tree_Ares) &&
+              are_exist (v[5], v[0], Tree_Ares)){
+            news = Create_Simplex (v[0], v[1], v[2], v[5]);
             news->iEnt = ep->mesh.ZonLayer[i];
             Tree_Add (THEV->Simplexes, &news);
-            news = Create_Simplex (v4, v5, v6, v2);
+            news = Create_Simplex (v[3], v[4], v[5], v[1]);
             news->iEnt = ep->mesh.ZonLayer[i];
             Tree_Add (THEV->Simplexes, &news);
-            news = Create_Simplex (v2, v4, v6, v1);
+            news = Create_Simplex (v[1], v[3], v[5], v[0]);
             news->iEnt = ep->mesh.ZonLayer[i];
             Tree_Add (THEV->Simplexes, &news);
           }
-          if (are_exist (v5, v1, Tree_Ares) &&
-              are_exist (v5, v3, Tree_Ares) &&
-              are_exist (v4, v3, Tree_Ares)){
-            news = Create_Simplex (v1, v2, v3, v5);
+          if (are_exist (v[4], v[0], Tree_Ares) &&
+              are_exist (v[4], v[2], Tree_Ares) &&
+              are_exist (v[3], v[2], Tree_Ares)){
+            news = Create_Simplex (v[0], v[1], v[2], v[4]);
             news->iEnt = ep->mesh.ZonLayer[i];
             Tree_Add (THEV->Simplexes, &news);
-            news = Create_Simplex (v4, v5, v6, v3);
+            news = Create_Simplex (v[3], v[4], v[5], v[2]);
             news->iEnt = ep->mesh.ZonLayer[i];
             Tree_Add (THEV->Simplexes, &news);
-            news = Create_Simplex (v1, v4, v5, v3);
+            news = Create_Simplex (v[0], v[3], v[4], v[2]);
             news->iEnt = ep->mesh.ZonLayer[i];
             Tree_Add (THEV->Simplexes, &news);
           }
-          if (are_exist (v5, v1, Tree_Ares) &&
-              are_exist (v5, v3, Tree_Ares) &&
-              are_exist (v6, v1, Tree_Ares)){
-            news = Create_Simplex (v1, v2, v3, v5);
+          if (are_exist (v[4], v[0], Tree_Ares) &&
+              are_exist (v[4], v[2], Tree_Ares) &&
+              are_exist (v[5], v[0], Tree_Ares)){
+            news = Create_Simplex (v[0], v[1], v[2], v[4]);
             news->iEnt = ep->mesh.ZonLayer[i];
             Tree_Add (THEV->Simplexes, &news);
-            news = Create_Simplex (v4, v5, v6, v1);
+            news = Create_Simplex (v[3], v[4], v[5], v[0]);
             news->iEnt = ep->mesh.ZonLayer[i];
             Tree_Add (THEV->Simplexes, &news);
-            news = Create_Simplex (v1, v3, v5, v6);
+            news = Create_Simplex (v[0], v[2], v[4], v[5]);
             news->iEnt = ep->mesh.ZonLayer[i];
             Tree_Add (THEV->Simplexes, &news);
           }
-          if (are_exist (v5, v1, Tree_Ares) &&
-              are_exist (v2, v6, Tree_Ares) &&
-              are_exist (v6, v1, Tree_Ares)){
-            news = Create_Simplex (v1, v2, v3, v6);
+          if (are_exist (v[4], v[0], Tree_Ares) &&
+              are_exist (v[1], v[5], Tree_Ares) &&
+              are_exist (v[5], v[0], Tree_Ares)){
+            news = Create_Simplex (v[0], v[1], v[2], v[5]);
             news->iEnt = ep->mesh.ZonLayer[i];
             Tree_Add (THEV->Simplexes, &news);
-            news = Create_Simplex (v4, v5, v6, v1);
+            news = Create_Simplex (v[3], v[4], v[5], v[0]);
             news->iEnt = ep->mesh.ZonLayer[i];
             Tree_Add (THEV->Simplexes, &news);
-            news = Create_Simplex (v1, v2, v5, v6);
+            news = Create_Simplex (v[0], v[1], v[4], v[5]);
             news->iEnt = ep->mesh.ZonLayer[i];
             Tree_Add (THEV->Simplexes, &news);
           }
diff --git a/Mesh/Create.cpp b/Mesh/Create.cpp
index 3e1af5ea15894ae32024c2127deb6daaa9c82d0e..ef85dabf5152b572b651753e3f4fa6479bceaf23 100644
--- a/Mesh/Create.cpp
+++ b/Mesh/Create.cpp
@@ -1,4 +1,4 @@
-// $Id: Create.cpp,v 1.24 2001-08-13 18:38:55 geuzaine Exp $
+// $Id: Create.cpp,v 1.25 2001-08-28 20:40:21 geuzaine Exp $
 
 #include "Gmsh.h"
 #include "Numeric.h"
@@ -31,14 +31,6 @@ int compareFxE (const void *a, const void *b){
   return (compareFace (&q->Sorted, &w->Sorted));
 }
 
-int compareHexahedron (const void *a, const void *b){
-  Hexahedron **q, **w;
-
-  q = (Hexahedron **) a;
-  w = (Hexahedron **) b;
-  return ((*q)->Num - (*w)->Num);
-}
-
 int compareSurfaceLoop (const void *a, const void *b){
   SurfaceLoop **q, **w;
 
@@ -55,6 +47,14 @@ int compareEdgeLoop (const void *a, const void *b){
   return ((*q)->Num - (*w)->Num);
 }
 
+int compareHexahedron (const void *a, const void *b){
+  Hexahedron **q, **w;
+
+  q = (Hexahedron **) a;
+  w = (Hexahedron **) b;
+  return ((*q)->Num - (*w)->Num);
+}
+
 int comparePrism (const void *a, const void *b){
   Prism **q, **w;
 
@@ -63,6 +63,14 @@ int comparePrism (const void *a, const void *b){
   return ((*q)->Num - (*w)->Num);
 }
 
+int comparePyramid (const void *a, const void *b){
+  Pyramid **q, **w;
+
+  q = (Pyramid **) a;
+  w = (Pyramid **) b;
+  return ((*q)->Num - (*w)->Num);
+}
+
 int compareQuality (const void *a, const void *b){
   double d;
   Simplex **q, **w;
@@ -592,6 +600,7 @@ Volume * Create_Volume (int Num, int Typ, int Mat){
   pV->Vertices = Tree_Create (sizeof (Vertex *), compareVertex);
   pV->Hexahedra = Tree_Create (sizeof (Hexahedron *), compareHexahedron);
   pV->Prisms = Tree_Create (sizeof (Prism *), comparePrism);
+  pV->Pyramids = Tree_Create (sizeof (Pyramid *), comparePyramid);
   pV->Simp_Surf = Tree_Create(sizeof(Simplex*),compareSimplex);// for old extrusion mesh generator
   pV->Extrude = NULL;
   pV->Edges = NULL;
@@ -612,16 +621,11 @@ void Free_Volume(void *a, void *b){
     Tree_Delete(pV->Hexahedra);
     Tree_Action(pV->Prisms, Free_Prism);
     Tree_Delete(pV->Prisms);
-    // MEMORY LEAK (JF)
-    if(pV->Edges)
-      {
-	Tree_Action(pV->Edges,Free_Edge);
-	Tree_Delete(pV->Edges);
-      }
-    if(pV->Faces)
-      {
-	Tree_Delete(pV->Faces);
-      }
+    Tree_Action(pV->Pyramids, Free_Pyramid);
+    Tree_Delete(pV->Pyramids);
+    Tree_Action(pV->Edges,Free_Edge);
+    Tree_Delete(pV->Edges);
+    Tree_Delete(pV->Faces);
     Free(pV);
     pV = NULL;
   }  
@@ -680,3 +684,28 @@ void Free_Prism(void *a, void *b){
     pP = NULL;
   }
 }
+
+Pyramid * Create_Pyramid (Vertex * v1, Vertex * v2, Vertex * v3, 
+			  Vertex * v4, Vertex * v5){
+  Pyramid *p;
+
+  p = (Pyramid *) Malloc (sizeof (Pyramid));
+  p->iEnt = -1;
+  p->Num = ++CurrentSimplexNumber;
+  p->V[0] = v1;
+  p->V[1] = v2;
+  p->V[2] = v3;
+  p->V[3] = v4;
+  p->V[4] = v5;
+  p->VSUP = NULL;
+
+  return (p);
+}
+
+void Free_Pyramid(void *a, void *b){
+  Pyramid *p = *(Pyramid**)a;
+  if(p){
+    Free(p);
+    p = NULL;
+  }
+}
diff --git a/Mesh/Create.h b/Mesh/Create.h
index 0f7b2471bf56b7392db49f4caf94b3a0de5ed1f4..5c8f44f6a7969caaeb33297f28e3b479e067bce2 100644
--- a/Mesh/Create.h
+++ b/Mesh/Create.h
@@ -3,10 +3,11 @@
 
 int compareNXE (const void *a, const void *b);
 int compareFxE (const void *a, const void *b);
-int compareHexahedron (const void *a, const void *b);
 int compareSurfaceLoop (const void *a, const void *b);
 int compareEdgeLoop (const void *a, const void *b);
+int compareHexahedron (const void *a, const void *b);
 int comparePrism (const void *a, const void *b);
+int comparePyramid (const void *a, const void *b);
 int compareQuality (const void *a, const void *b);
 int compareCurve (const void *a, const void *b);
 int compareAttractor (const void *a, const void *b);
@@ -41,4 +42,8 @@ Prism * Create_Prism (Vertex * v1, Vertex * v2, Vertex * v3,
                       Vertex * v4, Vertex * v5, Vertex * v6);
 void Free_Prism(void *a, void *b);
 
+Pyramid * Create_Pyramid (Vertex * v1, Vertex * v2, Vertex * v3,
+			  Vertex * v4, Vertex * v5);
+void Free_Pyramid(void *a, void *b);
+
 #endif
diff --git a/Mesh/Generator.cpp b/Mesh/Generator.cpp
index 0b0a1143ee12eaf2bbfe03a7fbe5c8e993273e9a..3bcfd898ab14ac1d8e4ba7fca4c9c801c3c7dec2 100644
--- a/Mesh/Generator.cpp
+++ b/Mesh/Generator.cpp
@@ -1,4 +1,4 @@
-// $Id: Generator.cpp,v 1.26 2001-08-15 08:16:30 geuzaine Exp $
+// $Id: Generator.cpp,v 1.27 2001-08-28 20:40:21 geuzaine Exp $
 
 #include "Gmsh.h"
 #include "Numeric.h"
@@ -58,7 +58,7 @@ void Maillage_Dimension_1 (Mesh * M){
   t1 = Cpu();
   Tree_Action (M->Curves, Maillage_Curve);
   t2 = Cpu();
-  M->Statistics[12] = t2 - t1;
+  M->Statistics[13] = t2 - t1;
 }
 
 void Maillage_Dimension_2 (Mesh * M){
@@ -90,7 +90,7 @@ void Maillage_Dimension_2 (Mesh * M){
 
   t2 = Cpu();  
 
-  M->Statistics[13] = t2 - t1;
+  M->Statistics[14] = t2 - t1;
 }
 
 void Maillage_Dimension_3 (Mesh * M){
@@ -125,7 +125,7 @@ void Maillage_Dimension_3 (Mesh * M){
 
   t2 = Cpu();
 
-  M->Statistics[14] = t2 - t1;
+  M->Statistics[15] = t2 - t1;
 }
 
 
diff --git a/Mesh/Mesh.h b/Mesh/Mesh.h
index cc32cf8ac3eb96840b6f214f4582df1bc7e277bb..de4d7fb8d94bc76b8ef64d0adfc1a93b115a4930 100644
--- a/Mesh/Mesh.h
+++ b/Mesh/Mesh.h
@@ -175,6 +175,13 @@ typedef struct{
   Vertex **VSUP;        /* noeuds supplem pour les elts de degre eleves */
 }Prism;
 
+typedef struct{
+  int Num;              /* Numero                                       */
+  int iEnt;             /* Entite geometrique                           */
+  Vertex *V[5];         /* 5 noeuds                                     */
+  Vertex **VSUP;        /* noeuds supplem pour les elts de degre eleves */
+}Pyramid;
+
 typedef struct{
   int N;
   List_T *pT;
@@ -266,6 +273,7 @@ typedef struct {
   Tree_T *Simp_Surf;//for old extrusion mesh generator
   Tree_T *Hexahedra;
   Tree_T *Prisms;
+  Tree_T *Pyramids;
   int Dirty; //flag to prevent any meshing
 }Volume;
 
diff --git a/Mesh/Print_Mesh.cpp b/Mesh/Print_Mesh.cpp
index 6e79357cefb85c83c8ef0e43e4572b47818202f5..b3138d821b7af3be9ea8c478bc78e5f98596d2b6 100644
--- a/Mesh/Print_Mesh.cpp
+++ b/Mesh/Print_Mesh.cpp
@@ -1,4 +1,4 @@
-// $Id: Print_Mesh.cpp,v 1.26 2001-08-13 20:05:42 geuzaine Exp $
+// $Id: Print_Mesh.cpp,v 1.27 2001-08-28 20:40:21 geuzaine Exp $
 
 #include "Gmsh.h"
 #include "Numeric.h"
@@ -228,6 +228,40 @@ void add_msh_prism (void *a, void *b){
   fprintf (mshfile, "\n");
 }
 
+void add_msh_pyramid (void *a, void *b){
+  Pyramid **P;
+  int i, type, nbn, nbs = 0;
+
+  P = (Pyramid **) a;
+
+  if (MSH_VOL_NUM && (MSH_VOL_NUM != (*P)->iEnt))
+    return;
+
+  if (!MSH_ADD){
+    MSH_ELEMENT_NUM++;
+    return;
+  }
+
+  nbn = 5;
+  if ((*P)->VSUP){
+    type = PYRAMID_2;
+    nbs = 10;
+  }
+  else{
+    type = PYRAMID;
+  }
+
+  fprintf (mshfile, "%d %d %d %d %d",
+           MSH_ELEMENT_NUM++, type, MSH_PHYSICAL_NUM, (*P)->iEnt, nbn + nbs);
+
+  for (i = 0; i < nbn; i++)
+    fprintf (mshfile, " %d", (*P)->V[i]->Num);
+  for (i = 0; i < nbs; i++)
+    fprintf (mshfile, " %d", (*P)->VSUP[i]->Num);
+
+  fprintf (mshfile, "\n");
+}
+
 void add_msh_point (Vertex * V){
 
   if (!MSH_ADD){
@@ -326,6 +360,7 @@ void add_msh_elements (Mesh * M){
           Tree_Action (pV->Simplexes, add_msh_simplex);
           Tree_Action (pV->Hexahedra, add_msh_hexahedron);
           Tree_Action (pV->Prisms, add_msh_prism);
+          Tree_Action (pV->Pyramids, add_msh_pyramid);
         }
       }
       break;
@@ -662,7 +697,7 @@ int process_3D_elements (FILE * funv, Mesh * m){
     List_Delete (Elements);
     nb += Tree_Nbr (v->Prisms);
     
-    // HEXAHEDRONS
+    // HEXAHEDRA
     Elements = Tree2List (v->Hexahedra);
     for (j = 0; j < List_Nbr (Elements); j++){
       List_Read (Elements, j, &hx);
diff --git a/Mesh/Read_Mesh.cpp b/Mesh/Read_Mesh.cpp
index 7be426290564fe169e235bd5a7ef02e57d8d128d..218a6bf7dde546a57dd8a9fc9fba738bd6370860 100644
--- a/Mesh/Read_Mesh.cpp
+++ b/Mesh/Read_Mesh.cpp
@@ -1,4 +1,4 @@
-// $Id: Read_Mesh.cpp,v 1.27 2001-08-14 10:50:03 geuzaine Exp $
+// $Id: Read_Mesh.cpp,v 1.28 2001-08-28 20:40:21 geuzaine Exp $
 
 #include "Gmsh.h"
 #include "Geo.h"
@@ -51,6 +51,7 @@ void Read_Mesh_MSH (Mesh *M, FILE *File_GEO){
   Simplex *simp ;
   Hexahedron *hex ;
   Prism *pri ;
+  Pyramid *pyr ;
   Curve   C , *c , **cc;
   Surface S , *s , **ss;
   Volume  V , *v , **vv;
@@ -152,7 +153,8 @@ void Read_Mesh_MSH (Mesh *M, FILE *File_GEO){
 	    else
 	      s = *ss;
 	    break;
-	  case TET1: case HEX1: case PRI1: case TET2: case HEX2: case PRI2: 
+	  case TET1: case HEX1: case PRI1: case PYR1:
+	  case TET2: case HEX2: case PRI2: case PYR2:
 	    v = &V; v->Num = Elementary;
 	    if(!(vv = (Volume**)Tree_PQuery(M->Volumes, &v))){
 	      v = Create_Volume(Elementary, MSH_VOLUME, Elementary);
@@ -257,6 +259,14 @@ void Read_Mesh_MSH (Mesh *M, FILE *File_GEO){
 	    Tree_Insert(v->Prisms, &pri) ;
 	    M->Statistics[11]++;
 	    break;
+	  case PYR1:
+	    pyr = Create_Pyramid(vertsp[0], vertsp[1], vertsp[2], 
+				 vertsp[3], vertsp[4]);
+	    pyr->Num = Num ;
+	    pyr->iEnt = Elementary ;
+	    Tree_Insert(v->Pyramids, &pyr) ;
+	    M->Statistics[12]++;
+	    break;
 	  case PNT:
 	    break;
 	  default :
diff --git a/Motif/CbGeneral.cpp b/Motif/CbGeneral.cpp
index e57b74b98d83cc90cdc358688f1fd1f16ecffc4f..003c42136d559b17d452f0ae5d41c21c61cecb77 100644
--- a/Motif/CbGeneral.cpp
+++ b/Motif/CbGeneral.cpp
@@ -1,4 +1,4 @@
-// $Id: CbGeneral.cpp,v 1.2 2001-01-09 14:24:11 geuzaine Exp $
+// $Id: CbGeneral.cpp,v 1.3 2001-08-28 20:40:21 geuzaine Exp $
 
 #include "Gmsh.h"
 #include "GmshUI.h"
@@ -58,7 +58,7 @@ void PopupHandler (Widget w, Widget pw, XEvent *event, Boolean *ctd ){
    ------------------------------------------------------------------------ */
 
 void CurrentInfoCb (Widget w, XtPointer client_data, XtPointer call_data){
-  double  s[50];
+  double  s[50], p[20];
   int     i;
   Post_View  *v ;
 
@@ -87,34 +87,35 @@ void CurrentInfoCb (Widget w, XtPointer client_data, XtPointer call_data){
     sprintf(label, "%g", s[9]);   XtVaSetValues(VLAB(9));
     sprintf(label, "%g", s[10]);  XtVaSetValues(VLAB(10));
     sprintf(label, "%g", s[11]);  XtVaSetValues(VLAB(11));
-
     sprintf(label, "%g", s[12]);  XtVaSetValues(VLAB(12));
+
     sprintf(label, "%g", s[13]);  XtVaSetValues(VLAB(13));
     sprintf(label, "%g", s[14]);  XtVaSetValues(VLAB(14));
+    sprintf(label, "%g", s[15]);  XtVaSetValues(VLAB(15));
 
-    sprintf(label, "%.4g (%.4g->%.4g)", s[17], s[19], s[18]); XtVaSetValues(VLAB(15));
-    sprintf(label, "%.4g (%.4g->%.4g)", s[20], s[22], s[21]); XtVaSetValues(VLAB(16));
-    sprintf(label, "%.4g (%.4g->%.4g)", s[23], s[25], s[24]); XtVaSetValues(VLAB(17));
+    sprintf(label, "%.4g (%.4g->%.4g)", s[17], s[19], s[18]); XtVaSetValues(VLAB(16));
+    sprintf(label, "%.4g (%.4g->%.4g)", s[20], s[22], s[21]); XtVaSetValues(VLAB(17));
+    sprintf(label, "%.4g (%.4g->%.4g)", s[23], s[25], s[24]); XtVaSetValues(VLAB(18));
 
     /* info post */
 
-    s[15] = List_Nbr(Post_ViewList) ;
-    sprintf(label, "%g", s[15]);  XtVaSetValues(VLAB(18));
+    p[0] = List_Nbr(Post_ViewList) ;
+    sprintf(label, "%g", p[0]);  XtVaSetValues(VLAB(19));
 
-    s[16] = s[17] = s[18] = s[19] = 0 ;
+    s[1] = s[2] = s[3] = s[4] = 0 ;
     for(i=0 ; i<List_Nbr(Post_ViewList) ; i++){
       v = (Post_View*)List_Pointer(Post_ViewList, i);
       if(v->Visible){
-	s[16] += v->NbSP + v->NbVP + v->NbTP;
-	s[17] += v->NbSL + v->NbVL + v->NbTL;
-	s[18] += v->NbST + v->NbVT + v->NbTT;
-	s[19] += v->NbSS + v->NbVS + v->NbTS;
+	s[1] += v->NbSP + v->NbVP + v->NbTP;
+	s[2] += v->NbSL + v->NbVL + v->NbTL;
+	s[3] += v->NbST + v->NbVT + v->NbTT;
+	s[4] += v->NbSS + v->NbVS + v->NbTS;
       }
     }
-    sprintf(label, "%g", s[16]); XtVaSetValues(VLAB(19));
-    sprintf(label, "%g", s[17]); XtVaSetValues(VLAB(20));
-    sprintf(label, "%g", s[18]); XtVaSetValues(VLAB(21));
-    sprintf(label, "%g", s[19]); XtVaSetValues(VLAB(22));
+    sprintf(label, "%g", s[1]); XtVaSetValues(VLAB(20));
+    sprintf(label, "%g", s[2]); XtVaSetValues(VLAB(21));
+    sprintf(label, "%g", s[3]); XtVaSetValues(VLAB(22));
+    sprintf(label, "%g", s[4]); XtVaSetValues(VLAB(23));
 
 #undef VLAB
 
diff --git a/Motif/Info.h b/Motif/Info.h
index 6ce1718e8618777e3a30a1ad413ab6bf3491efe1..21bd1d2d9c6166337a2d53b5142f6ae35db33b97 100644
--- a/Motif/Info.h
+++ b/Motif/Info.h
@@ -18,6 +18,7 @@ static char *txt_info [] =
     "Tetrahedra",
     "Hexahedra",
     "Prisms", 
+    "Pyramids", 
     "Time for 1D Mesh",
     "Time for 2D Mesh",
     "Time for 3D Mesh",
diff --git a/Motif/Widgets.h b/Motif/Widgets.h
index f79631b63de98cc05ba69fc52b7a8fcd104b4a3c..aa03ed0bde0074fefc9bf23a69ff74679f099478 100644
--- a/Motif/Widgets.h
+++ b/Motif/Widgets.h
@@ -5,9 +5,9 @@
 
 /* check Info.h */
 #define NB_INFO_GEOM   4
-#define NB_INFO_MESH   14
+#define NB_INFO_MESH   15
 #define NB_INFO_POST   5
-#define NB_INFO_MAX    23
+#define NB_INFO_MAX    24
 
 /* Holder for all Widgets */
 
diff --git a/doc/VERSIONS b/doc/VERSIONS
index 38f09fa8bbebbad9f8a37ac5bf2fe7c13668bc4a..059c026974edce5a40548374e28edbc684e78022 100644
--- a/doc/VERSIONS
+++ b/doc/VERSIONS
@@ -1,9 +1,13 @@
-$Id: VERSIONS,v 1.62 2001-08-28 15:12:01 geuzaine Exp $
+$Id: VERSIONS,v 1.63 2001-08-28 20:40:21 geuzaine Exp $
 
 New in 1.24: Fixed characteristic length interpolation for Splines;
-fixed edge swapping bug in 3D initial mesh generation; added BSplines;
-integrated Jonathan Shewchuk's Triangle as an alternative isotropic 2D
-mesh generator; added AngleSmoothNormals option;
+fixed edge swapping bug in 3D initial mesh; fixed degenerated case in
+geometrical extrusion (ruled surface with 3 borders); fixed generation
+of degenerated hexahedra and prisms for recombined+extruded meshes;
+added BSplines creation in the GUI; integrated Jonathan Shewchuk's
+Triangle as an alternative isotropic 2D mesh generator; added
+AngleSmoothNormals to control sharp edge display with smoothed
+normals; fixed random crash for lighted 3D iso surfaces;
 
 New in 1.23: Fixed duplicate elements generation + non-matching
 tetrahedra faces in 3D extruded meshes; Better display of displacement