From 7379efb3c9c846f93831fe0a3dfd9263e78842b1 Mon Sep 17 00:00:00 2001
From: Christophe Geuzaine <cgeuzaine@ulg.ac.be>
Date: Fri, 2 Jul 2004 02:40:48 +0000
Subject: [PATCH] - All extrusion commands now return a list of 2 numbers
 (instead of 1):   the first, as before, is the number of the "top" of the
 extruded region   (i.e., a point for extrude point, a line for extrude line,
 ...), the   second is the number of the "body" of the extruded region (i.e.,
 a   line for extrude point, a surface for extrude line, ...).

- "Extrude Surface" now always creates a new volume (automatically),
  EVEN WHEN THERE IS NO LAYERS SPECIFICATION. This makes it consistent
  with "Extrude Point" and "Extrude Line", which always create new
  curves and surfaces, respectively.

  Important Note: you will have to modify your old .geo files to avoid
  duplicate volume definitions if you use "Extrude Surface" without
  extruding the mesh (i.e., without the "Layers" command). These
  duplicate volumes would be harmless, but they would srew up your
  physical volume definitions later on...

  * Solution 1: use the new volumes (recommended). To do this, just
  remove your old extra volume definitions and let Gmsh create the
  extruded volumes for you. (To retrieve the volume number created by
  Gmsh, use "aa[] = Extrude Surface {...};;": the volume number is
  "aa[1]".)

  * Solution 2: keep the old volumes.

  a) clean way: retrieve the new volume number (aa[] = Extrude Surface
  {...};;) and delete the new volume with "Delete { Volume aa[1]; }"

  b) dirty (but handy) way: since, in order to create the new volumes
  with the less impact possible, Gmsh uses "low" numbers (actually,
  forcing "Geometry.OldNewreg=0") for the new volumes, just remove all
  "low number volumes". For example, if you have 4 "Extrude Surface" in
  your file, you can then just do "Delete{ Volume {1:4}; }"

Voila :-)
---
 Geo/CAD.cpp                                |  79 ++-
 Geo/CAD.h                                  |   2 +-
 Mesh/3D_Extrude.cpp                        |  18 +-
 Parser/Gmsh.tab.cpp                        | 528 ++++++++++++---------
 Parser/Gmsh.y                              | 146 +++++-
 Parser/Gmsh.yy.cpp                         |   4 +-
 TODO                                       |  34 +-
 benchmarks/bugs/bug-gcc2.95-clscale1.8.geo |   7 +-
 benchmarks/bugs/disk.geo                   |   3 -
 benchmarks/bugs/fil.geo                    |   4 +-
 benchmarks/bugs/p19-bug.geo                |  13 -
 benchmarks/bugs/piece-bad.geo              |   9 +-
 benchmarks/bugs/t2.geo                     |  31 --
 benchmarks/extrude/Cube-02-ExtrMesh.geo    |   2 -
 benchmarks/extrude/Cube-05-ExtrMesh.geo    |   5 +-
 benchmarks/extrude/Cube-06-ExtrMesh.geo    |   1 -
 benchmarks/extrude/hybrid.geo              |   5 +-
 benchmarks/extrude/p7-ExtrMesh.geo         |   5 -
 demos/piece.geo                            |   8 -
 doc/VERSIONS                               |   8 +-
 doc/texinfo/gmsh.texi                      |  19 +-
 tutorial/t2.geo                            |  62 ++-
 22 files changed, 596 insertions(+), 397 deletions(-)

diff --git a/Geo/CAD.cpp b/Geo/CAD.cpp
index 2526b0a100..e536a04fe0 100644
--- a/Geo/CAD.cpp
+++ b/Geo/CAD.cpp
@@ -1,4 +1,4 @@
-// $Id: CAD.cpp,v 1.76 2004-07-01 19:40:59 geuzaine Exp $
+// $Id: CAD.cpp,v 1.77 2004-07-02 02:40:43 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -420,6 +420,7 @@ void DeletePoint(int ip)
   if(v->Num == THEM->MaxPointNum)
     THEM->MaxPointNum--;
   Tree_Suppress(THEM->Points, &v);
+  Free_Vertex(&v, NULL);
 }
 
 void DeleteCurve(int ip)
@@ -440,12 +441,11 @@ void DeleteCurve(int ip)
   if(c->Num == THEM->MaxLineNum)
     THEM->MaxLineNum--;
   Tree_Suppress(THEM->Curves, &c);
+  Free_Curve(&c, NULL);
 }
 
 void DeleteSurface(int is)
 {
-  // Il faut absolument coder une
-  // structure coherente pour les volumes.
   Surface *s = FindSurface(is, THEM);
   if(!s)
     return;
@@ -454,7 +454,7 @@ void DeleteSurface(int is)
     Volume *v;
     List_Read(Vols, i, &v);
     for(int j = 0; j < List_Nbr(v->Surfaces); j++) {
-      if(!compareCurve(List_Pointer(v->Surfaces, j), &s))
+      if(!compareSurface(List_Pointer(v->Surfaces, j), &s))
         return;
     }
   }
@@ -462,6 +462,18 @@ void DeleteSurface(int is)
   if(s->Num == THEM->MaxSurfaceNum)
     THEM->MaxSurfaceNum--;
   Tree_Suppress(THEM->Surfaces, &s);
+  Free_Surface(&s, NULL);
+}
+
+void DeleteVolume(int iv)
+{
+  Volume *v = FindVolume(iv, THEM);
+  if(!v)
+    return;
+  if(v->Num == THEM->MaxVolumeNum)
+    THEM->MaxVolumeNum--;
+  Tree_Suppress(THEM->Volumes, &v);
+  Free_Volume(&v, NULL);
 }
 
 void DeleteShape(int Type, int Num)
@@ -486,6 +498,9 @@ void DeleteShape(int Type, int Num)
   case MSH_SURF_PLAN:
     DeleteSurface(Num);
     break;
+  case MSH_VOLUME:
+    DeleteVolume(Num);
+    break;
   default:
     Msg(GERROR, "Impossible to delete entity %d (of type %d)", Num, Type);
     break;
@@ -1413,13 +1428,14 @@ int Extrude_ProtudeSurface(int type, int is,
 			   double T0, double T1, double T2,
 			   double A0, double A1, double A2,
 			   double X0, double X1, double X2, double alpha,
-			   int NewVolume, ExtrudeParams * e)
+			   Volume **pv, ExtrudeParams * e)
 {
   double matrix[4][4], T[3], Ax[3];
   Curve *c, *c2;
   int i;
   Surface *s, *ps, *chapeau;
-  Volume *pv = NULL;
+
+  *pv = NULL;
 
   if(!(ps = FindSurface(is, THEM)))
     return 0;
@@ -1450,25 +1466,41 @@ int Extrude_ProtudeSurface(int type, int is,
       c->Extrude->mesh = e->mesh;
   }
 
-  if(NewVolume) {
-    pv = Create_Volume(NewVolume, 0);
-    pv->Extrude = new ExtrudeParams;
-    pv->Extrude->fill(type, T0, T1, T2, A0, A1, A2, X0, X1, X2, alpha);
-    pv->Extrude->geo.Source = is;
-    if(e)
-      pv->Extrude->mesh = e->mesh;
-    if(pv)
-      List_Add(pv->Surfaces, &ps);
-  }
-  if(pv)
-    List_Add(pv->Surfaces, &chapeau);
+  // FIXME: this is a really ugly hack for backward compatibility, so
+  // that we don't screw up the old .geo files too much. (Before
+  // version 1.54, we didn't always create new volumes during "Extrude
+  // Surface". Now we do, but with "CTX.geom.old_newreg==1", this
+  // bumps the NEWREG() counter, and thus changes the whole automatic
+  // numbering sequence.) So we locally force old_newreg to 0: in most
+  // cases, since we define points, curves, etc., before defining
+  // volumes, the NEWVOLUME() call below will return a fairly low
+  // number, that will not interfere with the other numbers...
+  int tmp = CTX.geom.old_newreg;
+  CTX.geom.old_newreg = 0;
+  Volume *v = Create_Volume(NEWVOLUME(), MSH_VOLUME);
+  CTX.geom.old_newreg = tmp;
+
+  v->Extrude = new ExtrudeParams;
+  v->Extrude->fill(type, T0, T1, T2, A0, A1, A2, X0, X1, X2, alpha);
+  v->Extrude->geo.Source = is;
+  if(e)
+    v->Extrude->mesh = e->mesh;
+  int ori = 1;;
+  List_Add(v->Surfaces, &ps);
+  List_Add(v->SurfacesOrientations, &ori);
+  ori = -1;
+  List_Add(v->Surfaces, &chapeau);
+  List_Add(v->SurfacesOrientations, &ori);
 
   for(i = 0; i < List_Nbr(ps->Generatrices); i++) {
     List_Read(ps->Generatrices, i, &c);
     Extrude_ProtudeCurve(type, c->Num, T0, T1, T2, A0, A1, A2, X0, X1, X2,
 			 alpha, &s, 0, e);
-    if(pv && s)
-      List_Add(pv->Surfaces, &s);
+    if(s){
+      ori = -1;
+      List_Add(v->Surfaces, &s);
+      List_Add(v->SurfacesOrientations, &ori);
+    }
   }
 
   switch (type) {
@@ -1536,14 +1568,15 @@ int Extrude_ProtudeSurface(int type, int is,
     return ps->Num;
   }
 
-  // why do we do this? only for backward compatibility?
+  // FIXME: why do we do this? only for backward compatibility?
   Tree_Suppress(THEM->Surfaces, &chapeau);
   chapeau->Num = NEWSURFACE();
   THEM->MaxSurfaceNum = chapeau->Num;
   Tree_Add(THEM->Surfaces, &chapeau);
 
-  if(pv)
-    Tree_Add(THEM->Volumes, &pv);
+  Tree_Add(THEM->Volumes, &v);
+
+  *pv = v;
 
   if(CTX.geom.auto_coherence)
     ReplaceAllDuplicates(THEM);
diff --git a/Geo/CAD.h b/Geo/CAD.h
index a2f66f7af0..71d0662915 100644
--- a/Geo/CAD.h
+++ b/Geo/CAD.h
@@ -81,7 +81,7 @@ int Extrude_ProtudeSurface(int type, int is,
 			   double T0, double T1, double T2,
 			   double A0, double A1, double A2,
 			   double X0, double X1, double X2, double alpha,
-			   int NewVolume, ExtrudeParams *e);
+			   Volume **pv, ExtrudeParams *e);
 
 
 void ReplaceAllDuplicates(Mesh *m);
diff --git a/Mesh/3D_Extrude.cpp b/Mesh/3D_Extrude.cpp
index c0ab9572f1..f0372fea40 100644
--- a/Mesh/3D_Extrude.cpp
+++ b/Mesh/3D_Extrude.cpp
@@ -1,4 +1,4 @@
-// $Id: 3D_Extrude.cpp,v 1.82 2004-06-23 18:52:45 geuzaine Exp $
+// $Id: 3D_Extrude.cpp,v 1.83 2004-07-02 02:40:43 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -355,7 +355,7 @@ void Create_HexPri(int iEnt, Vertex * v[8])
 
   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;
+    newh->iEnt = (iEnt && ep->useZonLayer()) ? iEnt : THEV->Num;
     Tree_Add(THEV->Hexahedra, &newh);
     return;
   }
@@ -378,12 +378,12 @@ void Create_HexPri(int iEnt, Vertex * v[8])
           v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]);
       return;
     }
-    newp->iEnt = iEnt;
+    newp->iEnt = (iEnt && ep->useZonLayer()) ? iEnt : THEV->Num;
     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;
+    newh->iEnt = (iEnt && ep->useZonLayer()) ? iEnt : THEV->Num;
     Tree_Add(THEV->Hexahedra, &newh);
     if(j)
       Msg(GERROR, "Degenerated hexahedron %d (nodes %d %d %d %d %d %d %d %d)",
@@ -400,7 +400,7 @@ void Create_PriPyrTet(int iEnt, Vertex * v[6])
 
   if(CTX.mesh.allow_degenerated_extrude) {
     newp = Create_Prism(v[0], v[1], v[2], v[3], v[4], v[5]);
-    newp->iEnt = iEnt;
+    newp->iEnt = (iEnt && ep->useZonLayer()) ? iEnt : THEV->Num;
     Tree_Add(THEV->Prisms, &newp);
     return;
   }
@@ -416,7 +416,7 @@ void Create_PriPyrTet(int iEnt, Vertex * v[6])
       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;
+    news->iEnt = (iEnt && ep->useZonLayer()) ? iEnt : THEV->Num;
     Tree_Add(THEV->Simplexes, &news);
   }
   else if(j == 1) {
@@ -426,12 +426,12 @@ void Create_PriPyrTet(int iEnt, Vertex * v[6])
       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;
+    newpyr->iEnt = (iEnt && ep->useZonLayer()) ? iEnt : THEV->Num;
     Tree_Add(THEV->Pyramids, &newpyr);
   }
   else {
     newp = Create_Prism(v[0], v[1], v[2], v[3], v[4], v[5]);
-    newp->iEnt = iEnt;
+    newp->iEnt = (iEnt && ep->useZonLayer()) ? iEnt : THEV->Num;
     Tree_Add(THEV->Prisms, &newp);
     if(j)
       Msg(GERROR, "Degenerated prism %d (nodes %d %d %d %d %d %d)",
@@ -447,7 +447,7 @@ void Create_Sim(int iEnt, Vertex * v1, Vertex * v2, Vertex * v3, Vertex * v4)
      (v1->Num != v2->Num && v1->Num != v3->Num && v1->Num != v4->Num &&
       v2->Num != v3->Num && v2->Num != v4->Num && v3->Num != v4->Num)) {
     news = Create_Simplex(v1, v2, v3, v4);
-    news->iEnt = iEnt;
+    news->iEnt = (iEnt && ep->useZonLayer()) ? iEnt : THEV->Num;
     Tree_Add(THEV->Simplexes, &news);
   }
 }
diff --git a/Parser/Gmsh.tab.cpp b/Parser/Gmsh.tab.cpp
index ca51ec31b0..1d125e459b 100644
--- a/Parser/Gmsh.tab.cpp
+++ b/Parser/Gmsh.tab.cpp
@@ -192,7 +192,7 @@
 
 #line 1 "Gmsh.y"
 
-// $Id: Gmsh.tab.cpp,v 1.197 2004-07-01 19:40:59 geuzaine Exp $
+// $Id: Gmsh.tab.cpp,v 1.198 2004-07-02 02:40:43 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -759,24 +759,24 @@ static const short yyrline[] = { 0,
   2308,  2324,  2344,  2358,  2368,  2378,  2382,  2391,  2405,  2413,
   2418,  2429,  2442,  2483,  2497,  2512,  2521,  2530,  2534,  2538,
   2542,  2553,  2569,  2583,  2608,  2633,  2660,  2666,  2671,  2676,
-  2680,  2688,  2702,  2713,  2724,  2729,  2740,  2745,  2756,  2761,
-  2774,  2792,  2810,  2828,  2833,  2851,  2856,  2874,  2879,  2900,
-  2917,  2934,  2951,  2956,  2973,  2979,  2996,  3002,  3021,  3025,
-  3030,  3057,  3081,  3089,  3108,  3126,  3144,  3171,  3197,  3223,
-  3237,  3255,  3260,  3269,  3271,  3272,  3273,  3274,  3277,  3279,
-  3280,  3281,  3282,  3283,  3284,  3285,  3286,  3293,  3294,  3295,
-  3296,  3297,  3298,  3299,  3300,  3301,  3302,  3303,  3304,  3305,
-  3306,  3307,  3308,  3309,  3310,  3311,  3312,  3313,  3314,  3315,
-  3316,  3317,  3318,  3319,  3320,  3321,  3322,  3323,  3324,  3326,
-  3327,  3328,  3329,  3330,  3331,  3332,  3333,  3334,  3335,  3336,
-  3337,  3338,  3339,  3340,  3341,  3342,  3343,  3344,  3345,  3346,
-  3351,  3356,  3357,  3358,  3362,  3374,  3393,  3406,  3418,  3440,
-  3457,  3474,  3491,  3510,  3515,  3519,  3523,  3527,  3533,  3538,
-  3542,  3546,  3552,  3556,  3561,  3565,  3570,  3574,  3578,  3584,
-  3590,  3597,  3603,  3607,  3611,  3622,  3629,  3640,  3660,  3670,
-  3680,  3692,  3708,  3726,  3749,  3776,  3782,  3786,  3790,  3802,
-  3807,  3819,  3825,  3845,  3850,  3863,  3869,  3875,  3880,  3888,
-  3902,  3906,  3925,  3941
+  2680,  2688,  2707,  2723,  2739,  2744,  2760,  2765,  2781,  2786,
+  2804,  2827,  2850,  2873,  2878,  2901,  2906,  2929,  2934,  2960,
+  2983,  3006,  3029,  3034,  3057,  3063,  3086,  3092,  3117,  3121,
+  3126,  3153,  3177,  3185,  3204,  3222,  3240,  3267,  3293,  3319,
+  3333,  3351,  3356,  3365,  3367,  3368,  3369,  3370,  3373,  3375,
+  3376,  3377,  3378,  3379,  3380,  3381,  3382,  3389,  3390,  3391,
+  3392,  3393,  3394,  3395,  3396,  3397,  3398,  3399,  3400,  3401,
+  3402,  3403,  3404,  3405,  3406,  3407,  3408,  3409,  3410,  3411,
+  3412,  3413,  3414,  3415,  3416,  3417,  3418,  3419,  3420,  3422,
+  3423,  3424,  3425,  3426,  3427,  3428,  3429,  3430,  3431,  3432,
+  3433,  3434,  3435,  3436,  3437,  3438,  3439,  3440,  3441,  3442,
+  3447,  3452,  3453,  3454,  3458,  3470,  3489,  3502,  3514,  3536,
+  3553,  3570,  3587,  3606,  3611,  3615,  3619,  3623,  3629,  3634,
+  3638,  3642,  3648,  3652,  3657,  3661,  3666,  3670,  3674,  3680,
+  3686,  3693,  3699,  3703,  3707,  3718,  3725,  3736,  3756,  3766,
+  3776,  3788,  3804,  3822,  3845,  3872,  3878,  3882,  3886,  3898,
+  3903,  3915,  3921,  3941,  3946,  3959,  3965,  3971,  3976,  3984,
+  3998,  4002,  4021,  4037
 };
 #endif
 
@@ -7334,12 +7334,17 @@ case 302:
 					  0., 0., 0., 0., 0., 0., 0.,
 					  &pc, &prc, 1, NULL);
       TheShape.Type = MSH_POINT;
-      yyval.l = List_Create(1, 1, sizeof(Shape));
+      yyval.l = List_Create(2, 1, sizeof(Shape));
       List_Add(yyval.l, &TheShape);
+      if(pc){
+	TheShape.Num = pc->Num;
+	TheShape.Type = pc->Typ;
+	List_Add(yyval.l, &TheShape);
+      }
     ;
     break;}
 case 303:
-#line 2703 "Gmsh.y"
+#line 2708 "Gmsh.y"
 {
       Curve *pc, *prc;
       Shape TheShape;
@@ -7347,12 +7352,17 @@ case 303:
 					  yyvsp[-6].v[0], yyvsp[-6].v[1], yyvsp[-6].v[2], yyvsp[-4].v[0], yyvsp[-4].v[1], yyvsp[-4].v[2], yyvsp[-2].d,
 					  &pc, &prc, 1, NULL);
       TheShape.Type = MSH_POINT;
-      yyval.l = List_Create(1, 1, sizeof(Shape));
+      yyval.l = List_Create(2, 1, sizeof(Shape));
       List_Add(yyval.l, &TheShape);
+      if(pc){
+	TheShape.Num = pc->Num;
+	TheShape.Type = pc->Typ;
+	List_Add(yyval.l, &TheShape);
+      }
     ;
     break;}
 case 304:
-#line 2714 "Gmsh.y"
+#line 2724 "Gmsh.y"
 {
       Curve *pc, *prc;
       Shape TheShape;
@@ -7360,19 +7370,24 @@ case 304:
 					  yyvsp[-6].v[0], yyvsp[-6].v[1], yyvsp[-6].v[2], yyvsp[-4].v[0], yyvsp[-4].v[1], yyvsp[-4].v[2], yyvsp[-2].d,
 					  &pc, &prc, 1, NULL);
       TheShape.Type = MSH_POINT;
-      yyval.l = List_Create(1, 1, sizeof(Shape));
+      yyval.l = List_Create(2, 1, sizeof(Shape));
       List_Add(yyval.l, &TheShape);
+      if(pc){
+	TheShape.Num = pc->Num;
+	TheShape.Type = pc->Typ;
+	List_Add(yyval.l, &TheShape);
+      }
     ;
     break;}
 case 305:
-#line 2725 "Gmsh.y"
+#line 2740 "Gmsh.y"
 {
       extr.mesh.ExtrudeMesh = false;
       extr.mesh.Recombine = false;
     ;
     break;}
 case 306:
-#line 2730 "Gmsh.y"
+#line 2745 "Gmsh.y"
 {
       Curve *pc, *prc;
       Shape TheShape;
@@ -7380,19 +7395,24 @@ case 306:
 					  0., 0., 0., 0., 0., 0., 0.,
 					  &pc, &prc, 1, &extr);
       TheShape.Type = MSH_POINT;
-      yyval.l = List_Create(1, 1, sizeof(Shape));
+      yyval.l = List_Create(2, 1, sizeof(Shape));
       List_Add(yyval.l, &TheShape);
+      if(pc){
+	TheShape.Num = pc->Num;
+	TheShape.Type = pc->Typ;
+	List_Add(yyval.l, &TheShape);
+      }
     ;
     break;}
 case 307:
-#line 2741 "Gmsh.y"
+#line 2761 "Gmsh.y"
 {
       extr.mesh.ExtrudeMesh = false;
       extr.mesh.Recombine = false;
     ;
     break;}
 case 308:
-#line 2746 "Gmsh.y"
+#line 2766 "Gmsh.y"
 {
       Curve *pc, *prc;
       Shape TheShape;
@@ -7400,19 +7420,24 @@ case 308:
 					  yyvsp[-10].v[0], yyvsp[-10].v[1], yyvsp[-10].v[2], yyvsp[-8].v[0], yyvsp[-8].v[1], yyvsp[-8].v[2], yyvsp[-6].d,
 					  &pc, &prc, 1, &extr);
       TheShape.Type = MSH_POINT;
-      yyval.l = List_Create(1, 1, sizeof(Shape));
+      yyval.l = List_Create(2, 1, sizeof(Shape));
       List_Add(yyval.l, &TheShape);
+      if(pc){
+	TheShape.Num = pc->Num;
+	TheShape.Type = pc->Typ;
+	List_Add(yyval.l, &TheShape);
+      }
     ;
     break;}
 case 309:
-#line 2757 "Gmsh.y"
+#line 2782 "Gmsh.y"
 {
       extr.mesh.ExtrudeMesh = false;
       extr.mesh.Recombine = false;
     ;
     break;}
 case 310:
-#line 2762 "Gmsh.y"
+#line 2787 "Gmsh.y"
 {
       Curve *pc, *prc;
       Shape TheShape;
@@ -7420,12 +7445,17 @@ case 310:
 					  yyvsp[-10].v[0], yyvsp[-10].v[1], yyvsp[-10].v[2], yyvsp[-8].v[0], yyvsp[-8].v[1], yyvsp[-8].v[2], yyvsp[-6].d,
 					  &pc, &prc, 1, &extr);
       TheShape.Type = MSH_POINT;
-      yyval.l = List_Create(1, 1, sizeof(Shape));
+      yyval.l = List_Create(2, 1, sizeof(Shape));
       List_Add(yyval.l, &TheShape);
+      if(pc){
+	TheShape.Num = pc->Num;
+	TheShape.Type = pc->Typ;
+	List_Add(yyval.l, &TheShape);
+      }
     ;
     break;}
 case 311:
-#line 2775 "Gmsh.y"
+#line 2805 "Gmsh.y"
 {
       Surface *ps;
       Shape TheShape;
@@ -7440,12 +7470,17 @@ case 311:
       else{
 	TheShape.Type = c->Typ;
       }
-      yyval.l = List_Create(1, 1, sizeof(Shape));
+      yyval.l = List_Create(2, 1, sizeof(Shape));
       List_Add(yyval.l, &TheShape);
+      if(ps){
+	TheShape.Num = ps->Num;
+	TheShape.Type = ps->Typ;
+	List_Add(yyval.l, &TheShape);
+      }
     ;
     break;}
 case 312:
-#line 2793 "Gmsh.y"
+#line 2828 "Gmsh.y"
 {
       Surface *ps;
       Shape TheShape;
@@ -7460,12 +7495,17 @@ case 312:
       else{
 	TheShape.Type = c->Typ;
       }
-      yyval.l = List_Create(1, 1, sizeof(Shape));
+      yyval.l = List_Create(2, 1, sizeof(Shape));
       List_Add(yyval.l, &TheShape);
+      if(ps){
+	TheShape.Num = ps->Num;
+	TheShape.Type = ps->Typ;
+	List_Add(yyval.l, &TheShape);
+      }
     ;
     break;}
 case 313:
-#line 2811 "Gmsh.y"
+#line 2851 "Gmsh.y"
 {
       Surface *ps;
       Shape TheShape;
@@ -7480,19 +7520,24 @@ case 313:
       else{
 	TheShape.Type = c->Typ;
       }
-      yyval.l = List_Create(1, 1, sizeof(Shape));
+      yyval.l = List_Create(2, 1, sizeof(Shape));
       List_Add(yyval.l, &TheShape);
+      if(ps){
+	TheShape.Num = ps->Num;
+	TheShape.Type = ps->Typ;
+	List_Add(yyval.l, &TheShape);
+      }
     ;
     break;}
 case 314:
-#line 2829 "Gmsh.y"
+#line 2874 "Gmsh.y"
 {
       extr.mesh.ExtrudeMesh = false;
       extr.mesh.Recombine = false;
     ;
     break;}
 case 315:
-#line 2834 "Gmsh.y"
+#line 2879 "Gmsh.y"
 {
       Surface *ps;
       Shape TheShape;
@@ -7507,19 +7552,24 @@ case 315:
       else{
 	TheShape.Type = c->Typ;
       }
-      yyval.l = List_Create(1, 1, sizeof(Shape));
+      yyval.l = List_Create(2, 1, sizeof(Shape));
       List_Add(yyval.l, &TheShape);
+      if(ps){
+	TheShape.Num = ps->Num;
+	TheShape.Type = ps->Typ;
+	List_Add(yyval.l, &TheShape);
+      }
     ;
     break;}
 case 316:
-#line 2852 "Gmsh.y"
+#line 2902 "Gmsh.y"
 {
       extr.mesh.ExtrudeMesh = false;
       extr.mesh.Recombine = false;
     ;
     break;}
 case 317:
-#line 2857 "Gmsh.y"
+#line 2907 "Gmsh.y"
 {
       Surface *ps;
       Shape TheShape;
@@ -7534,19 +7584,24 @@ case 317:
       else{
 	TheShape.Type = c->Typ;
       }
-      yyval.l = List_Create(1, 1, sizeof(Shape));
+      yyval.l = List_Create(2, 1, sizeof(Shape));
       List_Add(yyval.l, &TheShape);
+      if(ps){
+	TheShape.Num = ps->Num;
+	TheShape.Type = ps->Typ;
+	List_Add(yyval.l, &TheShape);
+      }
     ;
     break;}
 case 318:
-#line 2875 "Gmsh.y"
+#line 2930 "Gmsh.y"
 {
       extr.mesh.ExtrudeMesh = false;
       extr.mesh.Recombine = false;
     ;
     break;}
 case 319:
-#line 2880 "Gmsh.y"
+#line 2935 "Gmsh.y"
 {
       Surface *ps;
       Shape TheShape;
@@ -7561,17 +7616,23 @@ case 319:
       else{
 	TheShape.Type = c->Typ;
       }
-      yyval.l = List_Create(1, 1, sizeof(Shape));
+      yyval.l = List_Create(2, 1, sizeof(Shape));
       List_Add(yyval.l, &TheShape);
+      if(ps){
+	TheShape.Num = ps->Num;
+	TheShape.Type = ps->Typ;
+	List_Add(yyval.l, &TheShape);
+      }
     ;
     break;}
 case 320:
-#line 2901 "Gmsh.y"
+#line 2961 "Gmsh.y"
 {
+      Volume *pv;
       Shape TheShape;
       TheShape.Num = Extrude_ProtudeSurface(TRANSLATE, (int)yyvsp[-4].d, yyvsp[-2].v[0], yyvsp[-2].v[1], yyvsp[-2].v[2],
 					    0., 0., 0., 0., 0., 0., 0., 
-					    0, NULL);
+					    &pv, NULL);
       Surface *s = FindSurface(TheShape.Num, THEM);
       if(!s){
 	//yymsg(WARNING, "Unknown surface %d", TheShape.Num);
@@ -7580,17 +7641,23 @@ case 320:
       else{
 	TheShape.Type = s->Typ;
       }
-      yyval.l = List_Create(1, 1, sizeof(Shape));
+      yyval.l = List_Create(2, 1, sizeof(Shape));
       List_Add(yyval.l, &TheShape);
+      if(pv){
+	TheShape.Num = pv->Num;
+	TheShape.Type = pv->Typ;
+	List_Add(yyval.l, &TheShape);
+      }
     ;
     break;}
 case 321:
-#line 2918 "Gmsh.y"
+#line 2984 "Gmsh.y"
 {
+      Volume *pv;
       Shape TheShape;
       TheShape.Num = Extrude_ProtudeSurface(ROTATE, (int)yyvsp[-8].d, 0., 0., 0.,
 					    yyvsp[-6].v[0], yyvsp[-6].v[1], yyvsp[-6].v[2], yyvsp[-4].v[0], yyvsp[-4].v[1], yyvsp[-4].v[2], yyvsp[-2].d,
-					    0, NULL);
+					    &pv, NULL);
       Surface *s = FindSurface(TheShape.Num, THEM);
       if(!s){
 	//yymsg(WARNING, "Unknown surface %d", TheShape.Num);
@@ -7599,17 +7666,23 @@ case 321:
       else{
 	TheShape.Type = s->Typ;
       }
-      yyval.l = List_Create(1, 1, sizeof(Shape));
+      yyval.l = List_Create(2, 1, sizeof(Shape));
       List_Add(yyval.l, &TheShape);
+      if(pv){
+	TheShape.Num = pv->Num;
+	TheShape.Type = pv->Typ;
+	List_Add(yyval.l, &TheShape);
+      }
     ;
     break;}
 case 322:
-#line 2935 "Gmsh.y"
+#line 3007 "Gmsh.y"
 {
+      Volume *pv;
       Shape TheShape;
       TheShape.Num = Extrude_ProtudeSurface(TRANSLATE_ROTATE, (int)yyvsp[-10].d, yyvsp[-8].v[0], yyvsp[-8].v[1], yyvsp[-8].v[2],
 					    yyvsp[-6].v[0], yyvsp[-6].v[1], yyvsp[-6].v[2], yyvsp[-4].v[0], yyvsp[-4].v[1], yyvsp[-4].v[2], yyvsp[-2].d,
-					    0, NULL);
+					    &pv, NULL);
       Surface *s = FindSurface(TheShape.Num, THEM);
       if(!s){
 	//yymsg(WARNING, "Unknown surface %d", TheShape.Num);
@@ -7618,24 +7691,30 @@ case 322:
       else{
 	TheShape.Type = s->Typ;
       }
-      yyval.l = List_Create(1, 1, sizeof(Shape));
+      yyval.l = List_Create(2, 1, sizeof(Shape));
       List_Add(yyval.l, &TheShape);
+      if(pv){
+	TheShape.Num = pv->Num;
+	TheShape.Type = pv->Typ;
+	List_Add(yyval.l, &TheShape);
+      }
     ;
     break;}
 case 323:
-#line 2952 "Gmsh.y"
+#line 3030 "Gmsh.y"
 {
       extr.mesh.ExtrudeMesh = false;
       extr.mesh.Recombine = false;
     ;
     break;}
 case 324:
-#line 2957 "Gmsh.y"
+#line 3035 "Gmsh.y"
 {
+      Volume *pv;
       Shape TheShape;
       TheShape.Num = Extrude_ProtudeSurface(TRANSLATE, (int)yyvsp[-8].d, yyvsp[-6].v[0], yyvsp[-6].v[1], yyvsp[-6].v[2],
 					    0., 0., 0., 0., 0., 0., 0., 
-					    NEWREG(), &extr);
+					    &pv, &extr);
       Surface *s = FindSurface(TheShape.Num, THEM);
       if(!s){
 	//yymsg(WARNING, "Unknown surface %d", TheShape.Num);
@@ -7644,24 +7723,30 @@ case 324:
       else{
 	TheShape.Type = s->Typ;
       }
-      yyval.l = List_Create(1, 1, sizeof(Shape));
+      yyval.l = List_Create(2, 1, sizeof(Shape));
       List_Add(yyval.l, &TheShape);
+      if(pv){
+	TheShape.Num = pv->Num;
+	TheShape.Type = pv->Typ;
+	List_Add(yyval.l, &TheShape);
+      }
     ;
     break;}
 case 325:
-#line 2974 "Gmsh.y"
+#line 3058 "Gmsh.y"
 {
       extr.mesh.ExtrudeMesh = false;
       extr.mesh.Recombine = false;
     ;
     break;}
 case 326:
-#line 2980 "Gmsh.y"
+#line 3064 "Gmsh.y"
 {
+      Volume *pv;
       Shape TheShape;
       TheShape.Num = Extrude_ProtudeSurface(ROTATE, (int)yyvsp[-12].d, 0., 0., 0.,
 					    yyvsp[-10].v[0], yyvsp[-10].v[1], yyvsp[-10].v[2], yyvsp[-8].v[0], yyvsp[-8].v[1], yyvsp[-8].v[2], yyvsp[-6].d, 
-					    NEWREG(), &extr);
+					    &pv, &extr);
       Surface *s = FindSurface(TheShape.Num, THEM);
       if(!s){
 	//yymsg(WARNING, "Unknown surface %d", TheShape.Num);
@@ -7670,24 +7755,30 @@ case 326:
       else{
 	TheShape.Type = s->Typ;
       }
-      yyval.l = List_Create(1, 1, sizeof(Shape));
+      yyval.l = List_Create(2, 1, sizeof(Shape));
       List_Add(yyval.l, &TheShape);
+      if(pv){
+	TheShape.Num = pv->Num;
+	TheShape.Type = pv->Typ;
+	List_Add(yyval.l, &TheShape);
+      }
     ;
     break;}
 case 327:
-#line 2997 "Gmsh.y"
+#line 3087 "Gmsh.y"
 {
       extr.mesh.ExtrudeMesh = false;
       extr.mesh.Recombine = false;
     ;
     break;}
 case 328:
-#line 3003 "Gmsh.y"
+#line 3093 "Gmsh.y"
 {
+      Volume *pv;
       Shape TheShape;
       TheShape.Num = Extrude_ProtudeSurface(TRANSLATE_ROTATE, (int)yyvsp[-14].d, yyvsp[-12].v[0], yyvsp[-12].v[1], yyvsp[-12].v[2],
 					    yyvsp[-10].v[0], yyvsp[-10].v[1], yyvsp[-10].v[2], yyvsp[-8].v[0], yyvsp[-8].v[1], yyvsp[-8].v[2], yyvsp[-6].d,
-					    NEWREG(), &extr);
+					    &pv, &extr);
       Surface *s = FindSurface(TheShape.Num, THEM);
       if(!s){
 	//yymsg(WARNING, "Unknown surface %d", TheShape.Num);
@@ -7696,22 +7787,27 @@ case 328:
       else{
 	TheShape.Type = s->Typ;
       }
-      yyval.l = List_Create(1, 1, sizeof(Shape));
+      yyval.l = List_Create(2, 1, sizeof(Shape));
       List_Add(yyval.l, &TheShape);
+      if(pv){
+	TheShape.Num = pv->Num;
+	TheShape.Type = pv->Typ;
+	List_Add(yyval.l, &TheShape);
+      }
     ;
     break;}
 case 329:
-#line 3023 "Gmsh.y"
+#line 3119 "Gmsh.y"
 {
     ;
     break;}
 case 330:
-#line 3026 "Gmsh.y"
+#line 3122 "Gmsh.y"
 {
     ;
     break;}
 case 331:
-#line 3032 "Gmsh.y"
+#line 3128 "Gmsh.y"
 {
       double d;
       extr.mesh.ExtrudeMesh = true;
@@ -7739,7 +7835,7 @@ case 331:
     ;
     break;}
 case 332:
-#line 3058 "Gmsh.y"
+#line 3154 "Gmsh.y"
 {
       double d;
       extr.mesh.ExtrudeMesh = true;
@@ -7765,13 +7861,13 @@ case 332:
     ;
     break;}
 case 333:
-#line 3082 "Gmsh.y"
+#line 3178 "Gmsh.y"
 {
       extr.mesh.Recombine = true;
     ;
     break;}
 case 334:
-#line 3091 "Gmsh.y"
+#line 3187 "Gmsh.y"
 {
       for(int i = 0; i < List_Nbr(yyvsp[-3].l); i++){
 	double d;
@@ -7791,7 +7887,7 @@ case 334:
     ;
     break;}
 case 335:
-#line 3109 "Gmsh.y"
+#line 3205 "Gmsh.y"
 {
       for(int i = 0; i < List_Nbr(yyvsp[-6].l); i++){
 	double d;
@@ -7811,7 +7907,7 @@ case 335:
     ;
     break;}
 case 336:
-#line 3127 "Gmsh.y"
+#line 3223 "Gmsh.y"
 {
       for(int i = 0; i < List_Nbr(yyvsp[-6].l); i++){
 	double d;
@@ -7831,7 +7927,7 @@ case 336:
     ;
     break;}
 case 337:
-#line 3145 "Gmsh.y"
+#line 3241 "Gmsh.y"
 {
       Surface *s = FindSurface((int)yyvsp[-4].d, THEM);
       if(!s)
@@ -7860,7 +7956,7 @@ case 337:
     ;
     break;}
 case 338:
-#line 3172 "Gmsh.y"
+#line 3268 "Gmsh.y"
 {
       Surface *s = FindSurface((int)yyvsp[-4].d, THEM);
       if(!s)
@@ -7888,7 +7984,7 @@ case 338:
     ;
     break;}
 case 339:
-#line 3198 "Gmsh.y"
+#line 3294 "Gmsh.y"
 {
       Volume *v = FindVolume((int)yyvsp[-4].d, THEM);
       if(!v)
@@ -7916,7 +8012,7 @@ case 339:
     ;
     break;}
 case 340:
-#line 3224 "Gmsh.y"
+#line 3320 "Gmsh.y"
 {
       for(int i = 0; i < List_Nbr(yyvsp[-3].l); i++){
 	double d;
@@ -7932,7 +8028,7 @@ case 340:
     ;
     break;}
 case 341:
-#line 3238 "Gmsh.y"
+#line 3334 "Gmsh.y"
 {
       for(int i = 0; i < List_Nbr(yyvsp[-1].l); i++){
 	double d;
@@ -7947,71 +8043,71 @@ case 341:
     ;
     break;}
 case 342:
-#line 3257 "Gmsh.y"
+#line 3353 "Gmsh.y"
 { 
       ReplaceAllDuplicates(THEM);
     ;
     break;}
 case 343:
-#line 3261 "Gmsh.y"
+#line 3357 "Gmsh.y"
 { 
       IntersectAllSegmentsTogether();
     ;
     break;}
 case 344:
-#line 3270 "Gmsh.y"
+#line 3366 "Gmsh.y"
 {yyval.i = 1;;
     break;}
 case 345:
-#line 3271 "Gmsh.y"
+#line 3367 "Gmsh.y"
 {yyval.i = 0;;
     break;}
 case 346:
-#line 3272 "Gmsh.y"
+#line 3368 "Gmsh.y"
 {yyval.i = -1;;
     break;}
 case 347:
-#line 3273 "Gmsh.y"
+#line 3369 "Gmsh.y"
 {yyval.i = -1;;
     break;}
 case 348:
-#line 3274 "Gmsh.y"
+#line 3370 "Gmsh.y"
 {yyval.i = -1;;
     break;}
 case 349:
-#line 3278 "Gmsh.y"
+#line 3374 "Gmsh.y"
 { yyval.d = yyvsp[0].d;           ;
     break;}
 case 350:
-#line 3279 "Gmsh.y"
+#line 3375 "Gmsh.y"
 { yyval.d = yyvsp[-1].d;           ;
     break;}
 case 351:
-#line 3280 "Gmsh.y"
+#line 3376 "Gmsh.y"
 { yyval.d = -yyvsp[0].d;          ;
     break;}
 case 352:
-#line 3281 "Gmsh.y"
+#line 3377 "Gmsh.y"
 { yyval.d = yyvsp[0].d;           ;
     break;}
 case 353:
-#line 3282 "Gmsh.y"
+#line 3378 "Gmsh.y"
 { yyval.d = !yyvsp[0].d;          ;
     break;}
 case 354:
-#line 3283 "Gmsh.y"
+#line 3379 "Gmsh.y"
 { yyval.d = yyvsp[-2].d - yyvsp[0].d;      ;
     break;}
 case 355:
-#line 3284 "Gmsh.y"
+#line 3380 "Gmsh.y"
 { yyval.d = yyvsp[-2].d + yyvsp[0].d;      ;
     break;}
 case 356:
-#line 3285 "Gmsh.y"
+#line 3381 "Gmsh.y"
 { yyval.d = yyvsp[-2].d * yyvsp[0].d;      ;
     break;}
 case 357:
-#line 3287 "Gmsh.y"
+#line 3383 "Gmsh.y"
 { 
       if(!yyvsp[0].d)
 	yymsg(GERROR, "Division by zero in '%g / %g'", yyvsp[-2].d, yyvsp[0].d);
@@ -8020,235 +8116,235 @@ case 357:
     ;
     break;}
 case 358:
-#line 3293 "Gmsh.y"
+#line 3389 "Gmsh.y"
 { yyval.d = (int)yyvsp[-2].d % (int)yyvsp[0].d;  ;
     break;}
 case 359:
-#line 3294 "Gmsh.y"
+#line 3390 "Gmsh.y"
 { yyval.d = pow(yyvsp[-2].d, yyvsp[0].d);  ;
     break;}
 case 360:
-#line 3295 "Gmsh.y"
+#line 3391 "Gmsh.y"
 { yyval.d = yyvsp[-2].d < yyvsp[0].d;      ;
     break;}
 case 361:
-#line 3296 "Gmsh.y"
+#line 3392 "Gmsh.y"
 { yyval.d = yyvsp[-2].d > yyvsp[0].d;      ;
     break;}
 case 362:
-#line 3297 "Gmsh.y"
+#line 3393 "Gmsh.y"
 { yyval.d = yyvsp[-2].d <= yyvsp[0].d;     ;
     break;}
 case 363:
-#line 3298 "Gmsh.y"
+#line 3394 "Gmsh.y"
 { yyval.d = yyvsp[-2].d >= yyvsp[0].d;     ;
     break;}
 case 364:
-#line 3299 "Gmsh.y"
+#line 3395 "Gmsh.y"
 { yyval.d = yyvsp[-2].d == yyvsp[0].d;     ;
     break;}
 case 365:
-#line 3300 "Gmsh.y"
+#line 3396 "Gmsh.y"
 { yyval.d = yyvsp[-2].d != yyvsp[0].d;     ;
     break;}
 case 366:
-#line 3301 "Gmsh.y"
+#line 3397 "Gmsh.y"
 { yyval.d = yyvsp[-2].d && yyvsp[0].d;     ;
     break;}
 case 367:
-#line 3302 "Gmsh.y"
+#line 3398 "Gmsh.y"
 { yyval.d = yyvsp[-2].d || yyvsp[0].d;     ;
     break;}
 case 368:
-#line 3303 "Gmsh.y"
+#line 3399 "Gmsh.y"
 { yyval.d = yyvsp[-4].d? yyvsp[-2].d : yyvsp[0].d;  ;
     break;}
 case 369:
-#line 3304 "Gmsh.y"
+#line 3400 "Gmsh.y"
 { yyval.d = exp(yyvsp[-1].d);      ;
     break;}
 case 370:
-#line 3305 "Gmsh.y"
+#line 3401 "Gmsh.y"
 { yyval.d = log(yyvsp[-1].d);      ;
     break;}
 case 371:
-#line 3306 "Gmsh.y"
+#line 3402 "Gmsh.y"
 { yyval.d = log10(yyvsp[-1].d);    ;
     break;}
 case 372:
-#line 3307 "Gmsh.y"
+#line 3403 "Gmsh.y"
 { yyval.d = sqrt(yyvsp[-1].d);     ;
     break;}
 case 373:
-#line 3308 "Gmsh.y"
+#line 3404 "Gmsh.y"
 { yyval.d = sin(yyvsp[-1].d);      ;
     break;}
 case 374:
-#line 3309 "Gmsh.y"
+#line 3405 "Gmsh.y"
 { yyval.d = asin(yyvsp[-1].d);     ;
     break;}
 case 375:
-#line 3310 "Gmsh.y"
+#line 3406 "Gmsh.y"
 { yyval.d = cos(yyvsp[-1].d);      ;
     break;}
 case 376:
-#line 3311 "Gmsh.y"
+#line 3407 "Gmsh.y"
 { yyval.d = acos(yyvsp[-1].d);     ;
     break;}
 case 377:
-#line 3312 "Gmsh.y"
+#line 3408 "Gmsh.y"
 { yyval.d = tan(yyvsp[-1].d);      ;
     break;}
 case 378:
-#line 3313 "Gmsh.y"
+#line 3409 "Gmsh.y"
 { yyval.d = atan(yyvsp[-1].d);     ;
     break;}
 case 379:
-#line 3314 "Gmsh.y"
+#line 3410 "Gmsh.y"
 { yyval.d = atan2(yyvsp[-3].d, yyvsp[-1].d);;
     break;}
 case 380:
-#line 3315 "Gmsh.y"
+#line 3411 "Gmsh.y"
 { yyval.d = sinh(yyvsp[-1].d);     ;
     break;}
 case 381:
-#line 3316 "Gmsh.y"
+#line 3412 "Gmsh.y"
 { yyval.d = cosh(yyvsp[-1].d);     ;
     break;}
 case 382:
-#line 3317 "Gmsh.y"
+#line 3413 "Gmsh.y"
 { yyval.d = tanh(yyvsp[-1].d);     ;
     break;}
 case 383:
-#line 3318 "Gmsh.y"
+#line 3414 "Gmsh.y"
 { yyval.d = fabs(yyvsp[-1].d);     ;
     break;}
 case 384:
-#line 3319 "Gmsh.y"
+#line 3415 "Gmsh.y"
 { yyval.d = floor(yyvsp[-1].d);    ;
     break;}
 case 385:
-#line 3320 "Gmsh.y"
+#line 3416 "Gmsh.y"
 { yyval.d = ceil(yyvsp[-1].d);     ;
     break;}
 case 386:
-#line 3321 "Gmsh.y"
+#line 3417 "Gmsh.y"
 { yyval.d = fmod(yyvsp[-3].d, yyvsp[-1].d); ;
     break;}
 case 387:
-#line 3322 "Gmsh.y"
+#line 3418 "Gmsh.y"
 { yyval.d = fmod(yyvsp[-3].d, yyvsp[-1].d); ;
     break;}
 case 388:
-#line 3323 "Gmsh.y"
+#line 3419 "Gmsh.y"
 { yyval.d = sqrt(yyvsp[-3].d*yyvsp[-3].d+yyvsp[-1].d*yyvsp[-1].d); ;
     break;}
 case 389:
-#line 3324 "Gmsh.y"
+#line 3420 "Gmsh.y"
 { yyval.d = yyvsp[-1].d*(double)rand()/(double)RAND_MAX; ;
     break;}
 case 390:
-#line 3326 "Gmsh.y"
+#line 3422 "Gmsh.y"
 { yyval.d = exp(yyvsp[-1].d);      ;
     break;}
 case 391:
-#line 3327 "Gmsh.y"
+#line 3423 "Gmsh.y"
 { yyval.d = log(yyvsp[-1].d);      ;
     break;}
 case 392:
-#line 3328 "Gmsh.y"
+#line 3424 "Gmsh.y"
 { yyval.d = log10(yyvsp[-1].d);    ;
     break;}
 case 393:
-#line 3329 "Gmsh.y"
+#line 3425 "Gmsh.y"
 { yyval.d = sqrt(yyvsp[-1].d);     ;
     break;}
 case 394:
-#line 3330 "Gmsh.y"
+#line 3426 "Gmsh.y"
 { yyval.d = sin(yyvsp[-1].d);      ;
     break;}
 case 395:
-#line 3331 "Gmsh.y"
+#line 3427 "Gmsh.y"
 { yyval.d = asin(yyvsp[-1].d);     ;
     break;}
 case 396:
-#line 3332 "Gmsh.y"
+#line 3428 "Gmsh.y"
 { yyval.d = cos(yyvsp[-1].d);      ;
     break;}
 case 397:
-#line 3333 "Gmsh.y"
+#line 3429 "Gmsh.y"
 { yyval.d = acos(yyvsp[-1].d);     ;
     break;}
 case 398:
-#line 3334 "Gmsh.y"
+#line 3430 "Gmsh.y"
 { yyval.d = tan(yyvsp[-1].d);      ;
     break;}
 case 399:
-#line 3335 "Gmsh.y"
+#line 3431 "Gmsh.y"
 { yyval.d = atan(yyvsp[-1].d);     ;
     break;}
 case 400:
-#line 3336 "Gmsh.y"
+#line 3432 "Gmsh.y"
 { yyval.d = atan2(yyvsp[-3].d, yyvsp[-1].d);;
     break;}
 case 401:
-#line 3337 "Gmsh.y"
+#line 3433 "Gmsh.y"
 { yyval.d = sinh(yyvsp[-1].d);     ;
     break;}
 case 402:
-#line 3338 "Gmsh.y"
+#line 3434 "Gmsh.y"
 { yyval.d = cosh(yyvsp[-1].d);     ;
     break;}
 case 403:
-#line 3339 "Gmsh.y"
+#line 3435 "Gmsh.y"
 { yyval.d = tanh(yyvsp[-1].d);     ;
     break;}
 case 404:
-#line 3340 "Gmsh.y"
+#line 3436 "Gmsh.y"
 { yyval.d = fabs(yyvsp[-1].d);     ;
     break;}
 case 405:
-#line 3341 "Gmsh.y"
+#line 3437 "Gmsh.y"
 { yyval.d = floor(yyvsp[-1].d);    ;
     break;}
 case 406:
-#line 3342 "Gmsh.y"
+#line 3438 "Gmsh.y"
 { yyval.d = ceil(yyvsp[-1].d);     ;
     break;}
 case 407:
-#line 3343 "Gmsh.y"
+#line 3439 "Gmsh.y"
 { yyval.d = fmod(yyvsp[-3].d, yyvsp[-1].d); ;
     break;}
 case 408:
-#line 3344 "Gmsh.y"
+#line 3440 "Gmsh.y"
 { yyval.d = fmod(yyvsp[-3].d, yyvsp[-1].d); ;
     break;}
 case 409:
-#line 3345 "Gmsh.y"
+#line 3441 "Gmsh.y"
 { yyval.d = sqrt(yyvsp[-3].d*yyvsp[-3].d+yyvsp[-1].d*yyvsp[-1].d); ;
     break;}
 case 410:
-#line 3346 "Gmsh.y"
+#line 3442 "Gmsh.y"
 { yyval.d = yyvsp[-1].d*(double)rand()/(double)RAND_MAX; ;
     break;}
 case 411:
-#line 3355 "Gmsh.y"
+#line 3451 "Gmsh.y"
 { yyval.d = yyvsp[0].d; ;
     break;}
 case 412:
-#line 3356 "Gmsh.y"
+#line 3452 "Gmsh.y"
 { yyval.d = 3.141592653589793; ;
     break;}
 case 413:
-#line 3357 "Gmsh.y"
+#line 3453 "Gmsh.y"
 { yyval.d = ParUtil::Instance()->rank(); ;
     break;}
 case 414:
-#line 3358 "Gmsh.y"
+#line 3454 "Gmsh.y"
 { yyval.d = ParUtil::Instance()->size(); ;
     break;}
 case 415:
-#line 3363 "Gmsh.y"
+#line 3459 "Gmsh.y"
 {
       Symbol TheSymbol;
       TheSymbol.Name = yyvsp[0].c;
@@ -8262,7 +8358,7 @@ case 415:
     ;
     break;}
 case 416:
-#line 3375 "Gmsh.y"
+#line 3471 "Gmsh.y"
 {
       Symbol TheSymbol;
       TheSymbol.Name = yyvsp[-3].c;
@@ -8283,7 +8379,7 @@ case 416:
     ;
     break;}
 case 417:
-#line 3394 "Gmsh.y"
+#line 3490 "Gmsh.y"
 {
       Symbol TheSymbol;
       TheSymbol.Name = yyvsp[-2].c;
@@ -8298,7 +8394,7 @@ case 417:
     ;
     break;}
 case 418:
-#line 3407 "Gmsh.y"
+#line 3503 "Gmsh.y"
 {
       Symbol TheSymbol;
       TheSymbol.Name = yyvsp[-1].c;
@@ -8312,7 +8408,7 @@ case 418:
     ;
     break;}
 case 419:
-#line 3419 "Gmsh.y"
+#line 3515 "Gmsh.y"
 {
       Symbol TheSymbol;
       TheSymbol.Name = yyvsp[-4].c;
@@ -8333,7 +8429,7 @@ case 419:
     ;
     break;}
 case 420:
-#line 3441 "Gmsh.y"
+#line 3537 "Gmsh.y"
 {
       double (*pNumOpt)(int num, int action, double value);
       StringXNumber *pNumCat;
@@ -8352,7 +8448,7 @@ case 420:
     ;
     break;}
 case 421:
-#line 3458 "Gmsh.y"
+#line 3554 "Gmsh.y"
 {
       double (*pNumOpt)(int num, int action, double value);
       StringXNumber *pNumCat;
@@ -8371,7 +8467,7 @@ case 421:
     ;
     break;}
 case 422:
-#line 3475 "Gmsh.y"
+#line 3571 "Gmsh.y"
 {
       double (*pNumOpt)(int num, int action, double value);
       StringXNumber *pNumCat;
@@ -8390,7 +8486,7 @@ case 422:
     ;
     break;}
 case 423:
-#line 3492 "Gmsh.y"
+#line 3588 "Gmsh.y"
 {
       double (*pNumOpt)(int num, int action, double value);
       StringXNumber *pNumCat;
@@ -8409,130 +8505,130 @@ case 423:
     ;
     break;}
 case 424:
-#line 3512 "Gmsh.y"
+#line 3608 "Gmsh.y"
 {
       memcpy(yyval.v, yyvsp[0].v, 5*sizeof(double));
     ;
     break;}
 case 425:
-#line 3516 "Gmsh.y"
+#line 3612 "Gmsh.y"
 {
       for(int i = 0; i < 5; i++) yyval.v[i] = -yyvsp[0].v[i];
     ;
     break;}
 case 426:
-#line 3520 "Gmsh.y"
+#line 3616 "Gmsh.y"
 { 
       for(int i = 0; i < 5; i++) yyval.v[i] = yyvsp[0].v[i];
     ;
     break;}
 case 427:
-#line 3524 "Gmsh.y"
+#line 3620 "Gmsh.y"
 { 
       for(int i = 0; i < 5; i++) yyval.v[i] = yyvsp[-2].v[i] - yyvsp[0].v[i];
     ;
     break;}
 case 428:
-#line 3528 "Gmsh.y"
+#line 3624 "Gmsh.y"
 {
       for(int i = 0; i < 5; i++) yyval.v[i] = yyvsp[-2].v[i] + yyvsp[0].v[i];
     ;
     break;}
 case 429:
-#line 3535 "Gmsh.y"
+#line 3631 "Gmsh.y"
 { 
       yyval.v[0] = yyvsp[-9].d;  yyval.v[1] = yyvsp[-7].d;  yyval.v[2] = yyvsp[-5].d;  yyval.v[3] = yyvsp[-3].d; yyval.v[4] = yyvsp[-1].d;
     ;
     break;}
 case 430:
-#line 3539 "Gmsh.y"
+#line 3635 "Gmsh.y"
 { 
       yyval.v[0] = yyvsp[-7].d;  yyval.v[1] = yyvsp[-5].d;  yyval.v[2] = yyvsp[-3].d;  yyval.v[3] = yyvsp[-1].d; yyval.v[4] = 1.0;
     ;
     break;}
 case 431:
-#line 3543 "Gmsh.y"
+#line 3639 "Gmsh.y"
 {
       yyval.v[0] = yyvsp[-5].d;  yyval.v[1] = yyvsp[-3].d;  yyval.v[2] = yyvsp[-1].d;  yyval.v[3] = 0.0; yyval.v[4] = 1.0;
     ;
     break;}
 case 432:
-#line 3547 "Gmsh.y"
+#line 3643 "Gmsh.y"
 {
       yyval.v[0] = yyvsp[-5].d;  yyval.v[1] = yyvsp[-3].d;  yyval.v[2] = yyvsp[-1].d;  yyval.v[3] = 0.0; yyval.v[4] = 1.0;
     ;
     break;}
 case 433:
-#line 3554 "Gmsh.y"
+#line 3650 "Gmsh.y"
 {
     ;
     break;}
 case 434:
-#line 3557 "Gmsh.y"
+#line 3653 "Gmsh.y"
 {
     ;
     break;}
 case 435:
-#line 3563 "Gmsh.y"
+#line 3659 "Gmsh.y"
 {
     ;
     break;}
 case 436:
-#line 3566 "Gmsh.y"
+#line 3662 "Gmsh.y"
 {
     ;
     break;}
 case 437:
-#line 3572 "Gmsh.y"
+#line 3668 "Gmsh.y"
 {
     ;
     break;}
 case 438:
-#line 3575 "Gmsh.y"
+#line 3671 "Gmsh.y"
 {
        yyval.l = yyvsp[-1].l;
     ;
     break;}
 case 439:
-#line 3579 "Gmsh.y"
+#line 3675 "Gmsh.y"
 {
        yyval.l = yyvsp[-1].l;
     ;
     break;}
 case 440:
-#line 3586 "Gmsh.y"
+#line 3682 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(List_T*));
       List_Add(yyval.l, &(yyvsp[0].l));
     ;
     break;}
 case 441:
-#line 3591 "Gmsh.y"
+#line 3687 "Gmsh.y"
 {
       List_Add(yyval.l, &(yyvsp[0].l));
     ;
     break;}
 case 442:
-#line 3599 "Gmsh.y"
+#line 3695 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(double));
       List_Add(yyval.l, &(yyvsp[0].d));
     ;
     break;}
 case 443:
-#line 3604 "Gmsh.y"
+#line 3700 "Gmsh.y"
 {
       yyval.l = yyvsp[0].l;
     ;
     break;}
 case 444:
-#line 3608 "Gmsh.y"
+#line 3704 "Gmsh.y"
 {
       yyval.l = yyvsp[-1].l;
     ;
     break;}
 case 445:
-#line 3612 "Gmsh.y"
+#line 3708 "Gmsh.y"
 {
       yyval.l = yyvsp[-1].l;
       double *pd;
@@ -8543,7 +8639,7 @@ case 445:
     ;
     break;}
 case 446:
-#line 3624 "Gmsh.y"
+#line 3720 "Gmsh.y"
 { 
       yyval.l = List_Create(2, 1, sizeof(double)); 
       for(double d = yyvsp[-2].d; (yyvsp[-2].d < yyvsp[0].d) ? (d <= yyvsp[0].d) : (d >= yyvsp[0].d); (yyvsp[-2].d < yyvsp[0].d) ? (d += 1.) : (d -= 1.)) 
@@ -8551,7 +8647,7 @@ case 446:
     ;
     break;}
 case 447:
-#line 3630 "Gmsh.y"
+#line 3726 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(double)); 
       if(!yyvsp[0].d || (yyvsp[-4].d < yyvsp[-2].d && yyvsp[0].d < 0) || (yyvsp[-4].d > yyvsp[-2].d && yyvsp[0].d > 0)){
@@ -8564,7 +8660,7 @@ case 447:
    ;
     break;}
 case 448:
-#line 3641 "Gmsh.y"
+#line 3737 "Gmsh.y"
 {
       // Returns the coordinates of a point and fills a list with it.
       // This allows to ensure e.g. that relative point positions are
@@ -8586,7 +8682,7 @@ case 448:
     ;
     break;}
 case 449:
-#line 3661 "Gmsh.y"
+#line 3757 "Gmsh.y"
 {
       yyval.l = List_Create(List_Nbr(yyvsp[0].l), 1, sizeof(double));
       for(int i = 0; i < List_Nbr(yyvsp[0].l); i++){
@@ -8598,7 +8694,7 @@ case 449:
     ;
     break;}
 case 450:
-#line 3671 "Gmsh.y"
+#line 3767 "Gmsh.y"
 {
       yyval.l = List_Create(List_Nbr(yyvsp[0].l), 1, sizeof(double));
       for(int i = 0; i < List_Nbr(yyvsp[0].l); i++){
@@ -8610,7 +8706,7 @@ case 450:
     ;
     break;}
 case 451:
-#line 3681 "Gmsh.y"
+#line 3777 "Gmsh.y"
 {
       // FIXME: The syntax for this is ugly: we get double semi-colons
       // at the end of the line
@@ -8624,7 +8720,7 @@ case 451:
     ;
     break;}
 case 452:
-#line 3693 "Gmsh.y"
+#line 3789 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(double));
       Symbol TheSymbol;
@@ -8642,7 +8738,7 @@ case 452:
     ;
     break;}
 case 453:
-#line 3709 "Gmsh.y"
+#line 3805 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(double));
       Symbol TheSymbol;
@@ -8662,7 +8758,7 @@ case 453:
     ;
     break;}
 case 454:
-#line 3727 "Gmsh.y"
+#line 3823 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(double));
       Symbol TheSymbol;
@@ -8687,7 +8783,7 @@ case 454:
     ;
     break;}
 case 455:
-#line 3750 "Gmsh.y"
+#line 3846 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(double));
       Symbol TheSymbol;
@@ -8714,26 +8810,26 @@ case 455:
     ;
     break;}
 case 456:
-#line 3778 "Gmsh.y"
+#line 3874 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(double));
       List_Add(yyval.l, &(yyvsp[0].d));
     ;
     break;}
 case 457:
-#line 3783 "Gmsh.y"
+#line 3879 "Gmsh.y"
 {
       yyval.l = yyvsp[0].l;
     ;
     break;}
 case 458:
-#line 3787 "Gmsh.y"
+#line 3883 "Gmsh.y"
 {
       List_Add(yyval.l, &(yyvsp[0].d));
     ;
     break;}
 case 459:
-#line 3791 "Gmsh.y"
+#line 3887 "Gmsh.y"
 {
       for(int i = 0; i < List_Nbr(yyvsp[0].l); i++){
 	double d;
@@ -8744,19 +8840,19 @@ case 459:
     ;
     break;}
 case 460:
-#line 3804 "Gmsh.y"
+#line 3900 "Gmsh.y"
 {
       yyval.u = PACK_COLOR((int)yyvsp[-7].d, (int)yyvsp[-5].d, (int)yyvsp[-3].d, (int)yyvsp[-1].d);
     ;
     break;}
 case 461:
-#line 3808 "Gmsh.y"
+#line 3904 "Gmsh.y"
 {
       yyval.u = PACK_COLOR((int)yyvsp[-5].d, (int)yyvsp[-3].d, (int)yyvsp[-1].d, 255);
     ;
     break;}
 case 462:
-#line 3820 "Gmsh.y"
+#line 3916 "Gmsh.y"
 {
       int flag;
       yyval.u = Get_ColorForString(ColorString, -1, yyvsp[0].c, &flag);
@@ -8764,7 +8860,7 @@ case 462:
     ;
     break;}
 case 463:
-#line 3826 "Gmsh.y"
+#line 3922 "Gmsh.y"
 {
       unsigned int (*pColOpt)(int num, int action, unsigned int value);
       StringXColor *pColCat;
@@ -8784,13 +8880,13 @@ case 463:
     ;
     break;}
 case 464:
-#line 3847 "Gmsh.y"
+#line 3943 "Gmsh.y"
 {
       yyval.l = yyvsp[-1].l;
     ;
     break;}
 case 465:
-#line 3851 "Gmsh.y"
+#line 3947 "Gmsh.y"
 {
       yyval.l = List_Create(256, 10, sizeof(unsigned int));
       GmshColorTable *ct = Get_ColorTable((int)yyvsp[-3].d);
@@ -8803,26 +8899,26 @@ case 465:
     ;
     break;}
 case 466:
-#line 3865 "Gmsh.y"
+#line 3961 "Gmsh.y"
 {
       yyval.l = List_Create(256, 10, sizeof(unsigned int));
       List_Add(yyval.l, &(yyvsp[0].u));
     ;
     break;}
 case 467:
-#line 3870 "Gmsh.y"
+#line 3966 "Gmsh.y"
 {
       List_Add(yyval.l, &(yyvsp[0].u));
     ;
     break;}
 case 468:
-#line 3877 "Gmsh.y"
+#line 3973 "Gmsh.y"
 {
       yyval.c = yyvsp[0].c;
     ;
     break;}
 case 469:
-#line 3881 "Gmsh.y"
+#line 3977 "Gmsh.y"
 {
       yyval.c = (char *)Malloc((strlen(yyvsp[-3].c)+strlen(yyvsp[-1].c)+1)*sizeof(char));
       strcpy(yyval.c, yyvsp[-3].c);  
@@ -8832,7 +8928,7 @@ case 469:
     ;
     break;}
 case 470:
-#line 3889 "Gmsh.y"
+#line 3985 "Gmsh.y"
 {
       yyval.c = (char *)Malloc((strlen(yyvsp[-1].c)+1)*sizeof(char));
       int i;
@@ -8848,13 +8944,13 @@ case 470:
     ;
     break;}
 case 471:
-#line 3903 "Gmsh.y"
+#line 3999 "Gmsh.y"
 {
       yyval.c = yyvsp[-1].c;
     ;
     break;}
 case 472:
-#line 3907 "Gmsh.y"
+#line 4003 "Gmsh.y"
 {
       char tmpstring[1024];
       int i = PrintListOfDouble(yyvsp[-3].c, yyvsp[-1].l, tmpstring);
@@ -8875,7 +8971,7 @@ case 472:
     ;
     break;}
 case 473:
-#line 3926 "Gmsh.y"
+#line 4022 "Gmsh.y"
 { 
       char* (*pStrOpt)(int num, int action, char *value);
       StringXString *pStrCat;
@@ -8893,7 +8989,7 @@ case 473:
     ;
     break;}
 case 474:
-#line 3942 "Gmsh.y"
+#line 4038 "Gmsh.y"
 { 
       char* (*pStrOpt)(int num, int action, char *value);
       StringXString *pStrCat;
@@ -9132,7 +9228,7 @@ yyerrhandle:
     }
   return 1;
 }
-#line 3959 "Gmsh.y"
+#line 4055 "Gmsh.y"
 
 
 void DeleteSymbol(void *a, void *b){
diff --git a/Parser/Gmsh.y b/Parser/Gmsh.y
index 242b762263..2ee15bcc1c 100644
--- a/Parser/Gmsh.y
+++ b/Parser/Gmsh.y
@@ -1,5 +1,5 @@
 %{
-// $Id: Gmsh.y,v 1.173 2004-07-01 19:41:00 geuzaine Exp $
+// $Id: Gmsh.y,v 1.174 2004-07-02 02:40:47 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -2696,8 +2696,13 @@ Extrude :
 					  0., 0., 0., 0., 0., 0., 0.,
 					  &pc, &prc, 1, NULL);
       TheShape.Type = MSH_POINT;
-      $$ = List_Create(1, 1, sizeof(Shape));
+      $$ = List_Create(2, 1, sizeof(Shape));
       List_Add($$, &TheShape);
+      if(pc){
+	TheShape.Num = pc->Num;
+	TheShape.Type = pc->Typ;
+	List_Add($$, &TheShape);
+      }
     }
   | tExtrude tPoint '{' FExpr ',' VExpr ',' VExpr ',' FExpr '}'  tEND
     {
@@ -2707,8 +2712,13 @@ Extrude :
 					  $6[0], $6[1], $6[2], $8[0], $8[1], $8[2], $10,
 					  &pc, &prc, 1, NULL);
       TheShape.Type = MSH_POINT;
-      $$ = List_Create(1, 1, sizeof(Shape));
+      $$ = List_Create(2, 1, sizeof(Shape));
       List_Add($$, &TheShape);
+      if(pc){
+	TheShape.Num = pc->Num;
+	TheShape.Type = pc->Typ;
+	List_Add($$, &TheShape);
+      }
     }
   | tExtrude tPoint '{' FExpr ',' VExpr ',' VExpr ',' VExpr ',' FExpr'}'  tEND
     {
@@ -2718,8 +2728,13 @@ Extrude :
 					  $8[0], $8[1], $8[2], $10[0], $10[1], $10[2], $12,
 					  &pc, &prc, 1, NULL);
       TheShape.Type = MSH_POINT;
-      $$ = List_Create(1, 1, sizeof(Shape));
+      $$ = List_Create(2, 1, sizeof(Shape));
       List_Add($$, &TheShape);
+      if(pc){
+	TheShape.Num = pc->Num;
+	TheShape.Type = pc->Typ;
+	List_Add($$, &TheShape);
+      }
     }
   | tExtrude tPoint '{' FExpr ',' VExpr '}'
     {
@@ -2734,8 +2749,13 @@ Extrude :
 					  0., 0., 0., 0., 0., 0., 0.,
 					  &pc, &prc, 1, &extr);
       TheShape.Type = MSH_POINT;
-      $$ = List_Create(1, 1, sizeof(Shape));
+      $$ = List_Create(2, 1, sizeof(Shape));
       List_Add($$, &TheShape);
+      if(pc){
+	TheShape.Num = pc->Num;
+	TheShape.Type = pc->Typ;
+	List_Add($$, &TheShape);
+      }
     }
   | tExtrude tPoint '{' FExpr ',' VExpr ',' VExpr ',' FExpr '}'
     {
@@ -2750,8 +2770,13 @@ Extrude :
 					  $6[0], $6[1], $6[2], $8[0], $8[1], $8[2], $10,
 					  &pc, &prc, 1, &extr);
       TheShape.Type = MSH_POINT;
-      $$ = List_Create(1, 1, sizeof(Shape));
+      $$ = List_Create(2, 1, sizeof(Shape));
       List_Add($$, &TheShape);
+      if(pc){
+	TheShape.Num = pc->Num;
+	TheShape.Type = pc->Typ;
+	List_Add($$, &TheShape);
+      }
     }
   | tExtrude tPoint '{' FExpr ',' VExpr ',' VExpr ',' VExpr ',' FExpr'}'
     {
@@ -2766,8 +2791,13 @@ Extrude :
 					  $8[0], $8[1], $8[2], $10[0], $10[1], $10[2], $12,
 					  &pc, &prc, 1, &extr);
       TheShape.Type = MSH_POINT;
-      $$ = List_Create(1, 1, sizeof(Shape));
+      $$ = List_Create(2, 1, sizeof(Shape));
       List_Add($$, &TheShape);
+      if(pc){
+	TheShape.Num = pc->Num;
+	TheShape.Type = pc->Typ;
+	List_Add($$, &TheShape);
+      }
     }
 
   // Lines
@@ -2786,8 +2816,13 @@ Extrude :
       else{
 	TheShape.Type = c->Typ;
       }
-      $$ = List_Create(1, 1, sizeof(Shape));
+      $$ = List_Create(2, 1, sizeof(Shape));
       List_Add($$, &TheShape);
+      if(ps){
+	TheShape.Num = ps->Num;
+	TheShape.Type = ps->Typ;
+	List_Add($$, &TheShape);
+      }
     }
   | tExtrude tLine '{' FExpr ',' VExpr ',' VExpr ',' FExpr '}' tEND
     {
@@ -2804,8 +2839,13 @@ Extrude :
       else{
 	TheShape.Type = c->Typ;
       }
-      $$ = List_Create(1, 1, sizeof(Shape));
+      $$ = List_Create(2, 1, sizeof(Shape));
       List_Add($$, &TheShape);
+      if(ps){
+	TheShape.Num = ps->Num;
+	TheShape.Type = ps->Typ;
+	List_Add($$, &TheShape);
+      }
     }
   | tExtrude tLine '{' FExpr ',' VExpr ',' VExpr ',' VExpr ',' FExpr '}' tEND
     {
@@ -2822,8 +2862,13 @@ Extrude :
       else{
 	TheShape.Type = c->Typ;
       }
-      $$ = List_Create(1, 1, sizeof(Shape));
+      $$ = List_Create(2, 1, sizeof(Shape));
       List_Add($$, &TheShape);
+      if(ps){
+	TheShape.Num = ps->Num;
+	TheShape.Type = ps->Typ;
+	List_Add($$, &TheShape);
+      }
     }
   | tExtrude tLine '{' FExpr ',' VExpr '}'
     {
@@ -2845,8 +2890,13 @@ Extrude :
       else{
 	TheShape.Type = c->Typ;
       }
-      $$ = List_Create(1, 1, sizeof(Shape));
+      $$ = List_Create(2, 1, sizeof(Shape));
       List_Add($$, &TheShape);
+      if(ps){
+	TheShape.Num = ps->Num;
+	TheShape.Type = ps->Typ;
+	List_Add($$, &TheShape);
+      }
     }
   | tExtrude tLine '{' FExpr ',' VExpr ',' VExpr ',' FExpr '}'
     {
@@ -2868,8 +2918,13 @@ Extrude :
       else{
 	TheShape.Type = c->Typ;
       }
-      $$ = List_Create(1, 1, sizeof(Shape));
+      $$ = List_Create(2, 1, sizeof(Shape));
       List_Add($$, &TheShape);
+      if(ps){
+	TheShape.Num = ps->Num;
+	TheShape.Type = ps->Typ;
+	List_Add($$, &TheShape);
+      }
     }
   | tExtrude tLine '{' FExpr ',' VExpr ',' VExpr ',' VExpr ',' FExpr '}'
     {
@@ -2891,18 +2946,24 @@ Extrude :
       else{
 	TheShape.Type = c->Typ;
       }
-      $$ = List_Create(1, 1, sizeof(Shape));
+      $$ = List_Create(2, 1, sizeof(Shape));
       List_Add($$, &TheShape);
+      if(ps){
+	TheShape.Num = ps->Num;
+	TheShape.Type = ps->Typ;
+	List_Add($$, &TheShape);
+      }
     }
 
   // Surfaces
 
   | tExtrude tSurface '{' FExpr ',' VExpr '}' tEND
     {
+      Volume *pv;
       Shape TheShape;
       TheShape.Num = Extrude_ProtudeSurface(TRANSLATE, (int)$4, $6[0], $6[1], $6[2],
 					    0., 0., 0., 0., 0., 0., 0., 
-					    0, NULL);
+					    &pv, NULL);
       Surface *s = FindSurface(TheShape.Num, THEM);
       if(!s){
 	//yymsg(WARNING, "Unknown surface %d", TheShape.Num);
@@ -2911,15 +2972,21 @@ Extrude :
       else{
 	TheShape.Type = s->Typ;
       }
-      $$ = List_Create(1, 1, sizeof(Shape));
+      $$ = List_Create(2, 1, sizeof(Shape));
       List_Add($$, &TheShape);
+      if(pv){
+	TheShape.Num = pv->Num;
+	TheShape.Type = pv->Typ;
+	List_Add($$, &TheShape);
+      }
     }
   | tExtrude tSurface '{' FExpr ',' VExpr ',' VExpr ',' FExpr '}' tEND
     {
+      Volume *pv;
       Shape TheShape;
       TheShape.Num = Extrude_ProtudeSurface(ROTATE, (int)$4, 0., 0., 0.,
 					    $6[0], $6[1], $6[2], $8[0], $8[1], $8[2], $10,
-					    0, NULL);
+					    &pv, NULL);
       Surface *s = FindSurface(TheShape.Num, THEM);
       if(!s){
 	//yymsg(WARNING, "Unknown surface %d", TheShape.Num);
@@ -2928,15 +2995,21 @@ Extrude :
       else{
 	TheShape.Type = s->Typ;
       }
-      $$ = List_Create(1, 1, sizeof(Shape));
+      $$ = List_Create(2, 1, sizeof(Shape));
       List_Add($$, &TheShape);
+      if(pv){
+	TheShape.Num = pv->Num;
+	TheShape.Type = pv->Typ;
+	List_Add($$, &TheShape);
+      }
     }
   | tExtrude tSurface '{' FExpr ',' VExpr ',' VExpr ',' VExpr ',' FExpr '}' tEND
     {
+      Volume *pv;
       Shape TheShape;
       TheShape.Num = Extrude_ProtudeSurface(TRANSLATE_ROTATE, (int)$4, $6[0], $6[1], $6[2],
 					    $8[0], $8[1], $8[2], $10[0], $10[1], $10[2], $12,
-					    0, NULL);
+					    &pv, NULL);
       Surface *s = FindSurface(TheShape.Num, THEM);
       if(!s){
 	//yymsg(WARNING, "Unknown surface %d", TheShape.Num);
@@ -2945,8 +3018,13 @@ Extrude :
       else{
 	TheShape.Type = s->Typ;
       }
-      $$ = List_Create(1, 1, sizeof(Shape));
+      $$ = List_Create(2, 1, sizeof(Shape));
       List_Add($$, &TheShape);
+      if(pv){
+	TheShape.Num = pv->Num;
+	TheShape.Type = pv->Typ;
+	List_Add($$, &TheShape);
+      }
     }
   | tExtrude tSurface '{' FExpr ',' VExpr '}'
     {
@@ -2955,10 +3033,11 @@ Extrude :
     }
                       '{' ExtrudeParameters '}' tEND
     {
+      Volume *pv;
       Shape TheShape;
       TheShape.Num = Extrude_ProtudeSurface(TRANSLATE, (int)$4, $6[0], $6[1], $6[2],
 					    0., 0., 0., 0., 0., 0., 0., 
-					    NEWREG(), &extr);
+					    &pv, &extr);
       Surface *s = FindSurface(TheShape.Num, THEM);
       if(!s){
 	//yymsg(WARNING, "Unknown surface %d", TheShape.Num);
@@ -2967,8 +3046,13 @@ Extrude :
       else{
 	TheShape.Type = s->Typ;
       }
-      $$ = List_Create(1, 1, sizeof(Shape));
+      $$ = List_Create(2, 1, sizeof(Shape));
       List_Add($$, &TheShape);
+      if(pv){
+	TheShape.Num = pv->Num;
+	TheShape.Type = pv->Typ;
+	List_Add($$, &TheShape);
+      }
     }
   | tExtrude tSurface '{' FExpr ',' VExpr ',' VExpr ',' FExpr '}' 
     {
@@ -2978,10 +3062,11 @@ Extrude :
   
                       '{' ExtrudeParameters '}' tEND
     {
+      Volume *pv;
       Shape TheShape;
       TheShape.Num = Extrude_ProtudeSurface(ROTATE, (int)$4, 0., 0., 0.,
 					    $6[0], $6[1], $6[2], $8[0], $8[1], $8[2], $10, 
-					    NEWREG(), &extr);
+					    &pv, &extr);
       Surface *s = FindSurface(TheShape.Num, THEM);
       if(!s){
 	//yymsg(WARNING, "Unknown surface %d", TheShape.Num);
@@ -2990,8 +3075,13 @@ Extrude :
       else{
 	TheShape.Type = s->Typ;
       }
-      $$ = List_Create(1, 1, sizeof(Shape));
+      $$ = List_Create(2, 1, sizeof(Shape));
       List_Add($$, &TheShape);
+      if(pv){
+	TheShape.Num = pv->Num;
+	TheShape.Type = pv->Typ;
+	List_Add($$, &TheShape);
+      }
     }
   | tExtrude tSurface '{' FExpr ',' VExpr ',' VExpr ',' VExpr ',' FExpr '}'
     {
@@ -3001,10 +3091,11 @@ Extrude :
   
                       '{' ExtrudeParameters '}' tEND
     {
+      Volume *pv;
       Shape TheShape;
       TheShape.Num = Extrude_ProtudeSurface(TRANSLATE_ROTATE, (int)$4, $6[0], $6[1], $6[2],
 					    $8[0], $8[1], $8[2], $10[0], $10[1], $10[2], $12,
-					    NEWREG(), &extr);
+					    &pv, &extr);
       Surface *s = FindSurface(TheShape.Num, THEM);
       if(!s){
 	//yymsg(WARNING, "Unknown surface %d", TheShape.Num);
@@ -3013,8 +3104,13 @@ Extrude :
       else{
 	TheShape.Type = s->Typ;
       }
-      $$ = List_Create(1, 1, sizeof(Shape));
+      $$ = List_Create(2, 1, sizeof(Shape));
       List_Add($$, &TheShape);
+      if(pv){
+	TheShape.Num = pv->Num;
+	TheShape.Type = pv->Typ;
+	List_Add($$, &TheShape);
+      }
     }
 ;
 
diff --git a/Parser/Gmsh.yy.cpp b/Parser/Gmsh.yy.cpp
index 0684fd0ae9..5c28d463ad 100644
--- a/Parser/Gmsh.yy.cpp
+++ b/Parser/Gmsh.yy.cpp
@@ -2,7 +2,7 @@
 /* A lexical scanner generated by flex */
 
 /* Scanner skeleton version:
- * $Header: /cvsroot/gmsh/Parser/Gmsh.yy.cpp,v 1.196 2004-07-01 19:41:00 geuzaine Exp $
+ * $Header: /cvsroot/gmsh/Parser/Gmsh.yy.cpp,v 1.197 2004-07-02 02:40:47 geuzaine Exp $
  */
 
 #define FLEX_SCANNER
@@ -1019,7 +1019,7 @@ char *yytext;
 #line 1 "Gmsh.l"
 #define INITIAL 0
 #line 2 "Gmsh.l"
-// $Id: Gmsh.yy.cpp,v 1.196 2004-07-01 19:41:00 geuzaine Exp $
+// $Id: Gmsh.yy.cpp,v 1.197 2004-07-02 02:40:47 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
diff --git a/TODO b/TODO
index 5afb8231c7..d50e726b3d 100644
--- a/TODO
+++ b/TODO
@@ -1,4 +1,4 @@
-$Id: TODO,v 1.54 2004-06-30 01:49:41 geuzaine Exp $
+$Id: TODO,v 1.55 2004-07-02 02:40:43 geuzaine Exp $
 
 add an interactive way to choose the orientation of surfaces in
 surface loops and lines in line loops
@@ -7,6 +7,38 @@ surface loops and lines in line loops
 gauche", and all surface loops whould be oriented with exterior
 normals...)
 
+********************************************************************
+
+We could modify "Extrude Surface" to *always* create a new
+volume. This would make it consistent with "Extrude Point" and
+"Extrude Line", which always create new curves and surfaces,
+respectively. (with multi-layered exruded meshes, we could do exactly
+s we do with Extrude Line: if number==0, use the volume number...)
+
+I'm not sure if we should do it or not... This would introduce
+some incompatibilities in old geo files:
+
+- users could do a "Delete Volume" after the extrusion to fix the
+  old files (aa[] = Extrude Surface{..};; Delete{Volume aa[1];}
+
+- ...if the new volume creation didn't bork the automatic 
+  numbering. For this, we could use the following hack:
+
+  // FIXME: this is a really ugly hack for backward compatibility, so
+  // that we don't screw up the old .geo files too much. (Before
+  // version 1.54, we didn't always create new volumes during "Extrude
+  // Surface". Now we do, but with "CTX.geom.old_newreg==1", this
+  // bumps the NEWREG() counter, and thus changes the whole automatic
+  // numbering sequence.) So we locally force old_newreg to 0: in most
+  // cases, since we define points, curves, etc., before defining
+  // volumes, the NEWVOLUME() call below will return a fairly low
+  // number, that will not interfere with the other numbers...
+  int tmp = CTX.geom.old_newreg;
+  CTX.geom.old_newreg = 0;
+  Volume *v = Create_Volume(NEWVOLUME(), 0);
+  CTX.geom.old_newreg = tmp;
+
+
 ********************************************************************
 
 add ternary operator and <,>,<=,>=,== tests in MathEval
diff --git a/benchmarks/bugs/bug-gcc2.95-clscale1.8.geo b/benchmarks/bugs/bug-gcc2.95-clscale1.8.geo
index 36fea2165e..018c5c38fa 100644
--- a/benchmarks/bugs/bug-gcc2.95-clscale1.8.geo
+++ b/benchmarks/bugs/bug-gcc2.95-clscale1.8.geo
@@ -50,7 +50,9 @@ Plane Surface(46) = {45};
 
 Line Loop(47) = {3,4,1,2};
 Plane Surface(48) = {47,45};
-Extrude Surface {48, {0,0,0.4}};
+aa[] = Extrude Surface {48, {0,0,0.4}};  ;
+Delete {Volume{aa[1]};}
+
 Line Loop(91) = {57,54,55,56};
 Plane Surface(92) = {91};
 
@@ -97,7 +99,8 @@ Plane Surface(98) = {97,95};
 
 Line Loop(99) = {12,-8,-11,6};
 Plane Surface(100) = {99};
-Extrude Surface {96, {0,0,1}, {0,0,0}, 0.0349};
+aa[] = Extrude Surface {96, {0,0,1}, {0,0,0}, 0.0349};  ;
+Delete {Volume{aa[1]};}
 
 
 Line Loop(123) = {-9,-8,10,59};
diff --git a/benchmarks/bugs/disk.geo b/benchmarks/bugs/disk.geo
index a2919bcdc3..b7ec0322aa 100644
--- a/benchmarks/bugs/disk.geo
+++ b/benchmarks/bugs/disk.geo
@@ -43,6 +43,3 @@ l04  = newreg; Line (l04) = { p01, p04 };
 
 a1 = newreg; s1 = newreg; Line Loop ( a1 ) = { l01, l02, l03, -l04 } ;  Plane Surface ( s1 ) = { a1 };
 s11[] = Extrude Surface { s1, { 0, 1, 0 }, { 0.0, 0.0, 0.0 }, -angle  }; ;
-
-Surface Loop(28) = {18,5,14,27,22,26};
-Volume(29) = {28};
diff --git a/benchmarks/bugs/fil.geo b/benchmarks/bugs/fil.geo
index 7f7076d052..3e8135b6c0 100644
--- a/benchmarks/bugs/fil.geo
+++ b/benchmarks/bugs/fil.geo
@@ -78,7 +78,9 @@ Line(54) = {55,56};
 Line(55) = {56,2};
 Line Loop(56) = {-53,-52,-51,-50,-49,48,54,55};
 Plane Surface(57) = {56};
-Extrude Surface {57, {lsubstrat,0,0}};
+aa[] = Extrude Surface {57, {lsubstrat,0,0}};  ;
+Delete { Volume { aa[1] }; }
+
 Extrude Line {81, {0,0,hboite}};
 Extrude Line {69, {0,0,hboite}};
 Line(108) = {83,85};
diff --git a/benchmarks/bugs/p19-bug.geo b/benchmarks/bugs/p19-bug.geo
index 928cbd540c..0f430b2726 100644
--- a/benchmarks/bugs/p19-bug.geo
+++ b/benchmarks/bugs/p19-bug.geo
@@ -107,16 +107,3 @@ Extrude Surface {126, {0,0,hcav-hg} };
 Coherence;
 
 //Characteristic Length {58,71} = 0.01; 
-
-Point(85) = {0.0,0.0,0.0,1.0};
-Surface Loop(158) = {67,27,43,47,51,55,59,63,68};
-Volume(159) = {158};
-Surface Loop(159) = {112,29,84,67,125,92,96,100,104,108,116,120,124};
-Volume(160) = {159};
-
-GO      = 1 ;
-CAV     = 2 ;
-DIS     = 3 ; 
-CLDSRC  = 4 ;
-CLD     = 5 ;
-
diff --git a/benchmarks/bugs/piece-bad.geo b/benchmarks/bugs/piece-bad.geo
index 04ca2ba5bd..7936bd763f 100644
--- a/benchmarks/bugs/piece-bad.geo
+++ b/benchmarks/bugs/piece-bad.geo
@@ -87,12 +87,5 @@ Extrude Surface {49, {0,0,0.2}};
 Extrude Surface {91, {0,0,0.2}};
 Extrude Surface {47, {0,0,-0.2}};
 
-Surface Loop(373) = {90,371,359,78,82,363,367,86,325,329,317,
-  321,330,301,288,135,49,139,143,147,151,155,159,163,167,171,
-  175,179,183,187,191,195,199,203,207,211,215,219,223,227,231,
-  235,239,243,247,251,255,259,263,267,271,343,347,351,355,372,
-  305,309,313};
-Volume(374) = {373};
-
-Physical Volume(1) = 374 ;
+Physical Volume(1) = {1,2,3,4};
 Physical Surface(2) = {1:1000};
diff --git a/benchmarks/bugs/t2.geo b/benchmarks/bugs/t2.geo
index d1cb69c6a1..5585295436 100644
--- a/benchmarks/bugs/t2.geo
+++ b/benchmarks/bugs/t2.geo
@@ -57,34 +57,3 @@ Extrude Surface { 11, {0, 0, h} } ;
 // created points:
 
 Characteristic Length{6,22,2,3,16,12} = lc * 3 ;
-
-// If the transformation tools are handy to create complex geometries,
-// it is sometimes useful to generate the flat geometry, consisting
-// only of the explicit list elementary entities. This can be achieved
-// by selecting the 'File->Save as->GEO flattened geometry' menu or 
-// by typing
-//
-// > gmsh t2.geo -0
-//
-// on the command line.
-
-// Volumes are the fourth type of elementary entities in Gmsh. In the
-// same way one defines line loops to build surfaces, one has to
-// define surface loops to build volumes. The following volumes are
-// very simple, without holes (and thus consist of only one surface
-// loop):
-
-Surface Loop(145) = {121,11,131,135,139,144};
-Volume(146) = {145};
-
-Surface Loop(146) = {121,6,109,113,117,122};
-Volume(147) = {146};
-
-// To save all volumic (tetrahedral) elements of volume 146 and 147
-// with the associate region number 1, a Physical Volume must be
-// defined:
-
-Physical Volume (1) = {146,147} ;
-
-// Congratulations! You've created your first fully unstructured
-// tetrahedral 3D mesh!
diff --git a/benchmarks/extrude/Cube-02-ExtrMesh.geo b/benchmarks/extrude/Cube-02-ExtrMesh.geo
index e4cb6d8c1a..0a4f8a6a75 100644
--- a/benchmarks/extrude/Cube-02-ExtrMesh.geo
+++ b/benchmarks/extrude/Cube-02-ExtrMesh.geo
@@ -24,5 +24,3 @@ Line Loop(32) = {-31,-30,-29,1};
 Plane Surface(33) = {32};        
 Extrude Surface {33, {0,0.0,1}};        
 Coherence;        
-Surface Loop(56) = {27,33,42,46,50,55};
-Volume(57) = {56};
diff --git a/benchmarks/extrude/Cube-05-ExtrMesh.geo b/benchmarks/extrude/Cube-05-ExtrMesh.geo
index c89d3eb201..b284653ed7 100644
--- a/benchmarks/extrude/Cube-05-ExtrMesh.geo
+++ b/benchmarks/extrude/Cube-05-ExtrMesh.geo
@@ -28,8 +28,5 @@ Extrude Surface{11, {0.0,1,0}, {-.5,0.0,0.0}, 3.14159/4 }
 {                                                
       Layers { {5,15,5} , {10,20,10} , {.1,.9,1.} };
 } ;            
-Coherence;            
+
 Extrude Surface{24, {0.0,.3,0} };            
-Coherence;            
-Surface Loop(76) = {24,62,66,70,74,75};
-Complex Volume(77) = {76};
diff --git a/benchmarks/extrude/Cube-06-ExtrMesh.geo b/benchmarks/extrude/Cube-06-ExtrMesh.geo
index 12a38a2132..1d5278a416 100644
--- a/benchmarks/extrude/Cube-06-ExtrMesh.geo
+++ b/benchmarks/extrude/Cube-06-ExtrMesh.geo
@@ -27,4 +27,3 @@ Extrude Surface {11, {.0,0.0,.1}}
 {    
  Layers { {2,3,2} , {44,55,44} , {.1,.9,1.} };                 
 };        
-Coherence;        
diff --git a/benchmarks/extrude/hybrid.geo b/benchmarks/extrude/hybrid.geo
index 478eec10ac..ff47e26523 100644
--- a/benchmarks/extrude/hybrid.geo
+++ b/benchmarks/extrude/hybrid.geo
@@ -19,8 +19,7 @@ Extrude Surface{6, {0.0,1,0}, {0,0.0,0.0}, 3.14159/2}
             
 Coherence;              
 Extrude Surface {6, {0,0.0,2}} ; 
-Surface Loop(51) = {6,37,41,45,49,50}; 
-Complex Volume(52) = {51}; 
+
 Extrude Surface {45, {0,2,0.0}}
 {    
    Layers {{2,2,2},{111,222,111},{.3,.6,1.}};    
@@ -28,5 +27,3 @@ Extrude Surface {45, {0,2,0.0}}
 Coherence; 
 Extrude Surface {65, {-1,0,0}};
 
-Surface Loop(97) = {65,83,87,91,95,96};
-Volume(98) = {97};
diff --git a/benchmarks/extrude/p7-ExtrMesh.geo b/benchmarks/extrude/p7-ExtrMesh.geo
index 589549b258..f03e8dbc11 100644
--- a/benchmarks/extrude/p7-ExtrMesh.geo
+++ b/benchmarks/extrude/p7-ExtrMesh.geo
@@ -126,8 +126,3 @@ Extrude Surface {35, {0,0.0,19}}
 {  
 Layers { {3,3,3}, {100,200,300}, {.1,.9,1.}} ;  
 };  
-  
-Coherence;  
-
-Surface Loop(297) = {144,131,76,74,153,166,161,175,72,183,209,70,68,66,64,87,121,78,113,95,245,223,201,210,232,254,100,122,253,231,188,139};
-Complex Volume(298) = {297};
diff --git a/demos/piece.geo b/demos/piece.geo
index d189c038c2..7d63e9f281 100644
--- a/demos/piece.geo
+++ b/demos/piece.geo
@@ -83,11 +83,3 @@ Extrude Surface {47, {0,0,0.2}};
 Extrude Surface {49, {0,0,0.2}};
 Extrude Surface {91, {0,0,0.2}};
 Extrude Surface {47, {0,0,-0.2}};
-
-Surface Loop(373) = - {49,-135,-139,-143,-147,-151,-155,-159,-163,-167,
-  -171,-175,-179,-183,-187,-191,-195,-199,-203,-207,-211,-215,-219,-223,
-  -227,-231,-235,-239,-243,-247,-251,-255,-259,-263,-267,-271,-288,-313,
-  -301,-305,-309,-330,-317,-78,359,363,-82,-86,367,371,-90,-329,-325,
-  -321,372,343,347,351,355};
-Volume(374) = {373};
-
diff --git a/doc/VERSIONS b/doc/VERSIONS
index be8ebdf2af..1c7876e342 100644
--- a/doc/VERSIONS
+++ b/doc/VERSIONS
@@ -1,8 +1,10 @@
-$Id: VERSIONS,v 1.229 2004-06-30 18:18:23 geuzaine Exp $
+$Id: VERSIONS,v 1.230 2004-07-02 02:40:47 geuzaine Exp $
 
 New in 1.54: integrated Netgen (3D mesh quality optimization +
-alternative 3D algorithm); fixed UNV output; make Layers' region
-numbering consistent between lines/surfaces/volumes; fixed home
+alternative 3D algorithm); Extrude Surface now automatically creates a
+new volume (in the same way Extrude Point or Extrude Line create new
+lines and surfaces, respectively); fixed UNV output; make Layers'
+region numbering consistent between lines/surfaces/volumes; fixed home
 directory problem on Win98; new Plugin(CutParametric); the default
 project file is now created in the home directory if no current
 directory is defined (e.g. when double-clicking on the icon on
diff --git a/doc/texinfo/gmsh.texi b/doc/texinfo/gmsh.texi
index 818b7159c8..a74cb5407e 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.122 2004-06-30 21:15:58 geuzaine Exp $
+@c $Id: gmsh.texi,v 1.123 2004-07-02 02:40:47 geuzaine Exp $
 @c
 @c Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 @c
@@ -718,6 +718,9 @@ of a given geometry point (@pxref{Points}). The last two cases permit to
 retreive the indices of entities created through geometrical transformations
 adn extrusions (see @ref{Transformations}, and @ref{Extrusions}).
 
+@c todo: explain in detail what numbers are returned once we decide what to
+@c do (chapeau et body pour extrude, etc.)...
+
 To see the practical use of such expressions, have a look at the first
 couple of examples in @ref{Tutorial}. Note that, in order to lighten the
 syntax, you can always omit the braces @code{@{@}} enclosing an
@@ -1639,7 +1642,7 @@ giving the X, Y and Z components of any point on this axis; the last
 @findex @var{transform}
 
 Geometrical transformations can be applied to elementary entities, or to
-copies of geometrical entities (using the @code{Duplicata} command: see
+copies of elementary entities (using the @code{Duplicata} command: see
 below). The syntax of the transformation commands is:
 
 @var{transform}:
@@ -1949,13 +1952,11 @@ extruded and has the following syntax:
 The first @var{expression-list} defines how many elements should be created
 in each extruded layer. The second @var{expression-list} assigns a region
 number to each layer, which, if non-zero, overrides the elementary entity
-number of the extruded entity. This is for example useful when there is more
-than one layer (the elements in each layer can then be identitied in a
-unique way) or when one does not want to use the GUI to get the elementary
-entity numbers. The last @var{expression-list} gives the normalized height
-of each layer (the list should contain a sequence of @var{n} numbers 0 <
-@var{h1} < @var{h2} < @dots{} < @var{hn} <= 1). See @ref{t3.geo}, for an
-example.
+number of the extruded entity. This is useful when there is more than one
+layer, as the elements in each layer can then be identified in a unique
+way. The last @var{expression-list} gives the normalized height of each
+layer (the list should contain a sequence of @var{n} numbers 0 < @var{h1} <
+@var{h2} < @dots{} < @var{hn} <= 1). See @ref{t3.geo}, for an example.
 
 For line extrusions, the @code{Recombine} option will recombine triangles
 into quadrangles when possible.  For surface extrusions, the
diff --git a/tutorial/t2.geo b/tutorial/t2.geo
index 0de54c009e..3ec4488e81 100644
--- a/tutorial/t2.geo
+++ b/tutorial/t2.geo
@@ -22,30 +22,52 @@ Line(5) = {4, 5};
 // elementary entities or copies of elementary entities. For example,
 // the point 3 can be moved by 0.05 units to the left with:
 
-Translate {-0.05,0,0} { Point{3}; }
+Translate {-0.05, 0, 0} { Point{3}; }
 
 // The resulting point can also be duplicated and translated by 0.1
 // along the y axis:
 
-tmp[] = Translate {0,0.1,0} { Duplicata{ Point{3}; } } ;
+tmp[] = Translate {0, 0.1, 0} { Duplicata{ Point{3}; } } ;
 
 // In this case, we assign the result of the Translate command to a
 // list, so that we can retrieve the number of the newly created point
-// later.
+// and use it to create new lines and a new surface:
+
+Line(7) = {3,tmp[0]};
+Line(8) = {tmp[0],5};
+Line Loop(10) = {5,-8,-7,3};
+Plane Surface(11) = {10};
 
 // Of course, these transformation commands not only apply to points,
-// but also to lines and surfaces. The following command extrudes the
-// surface 6 defined in `t1.geo', as well as a new surface 11, along
-// the z axis:
+// but also to lines and surfaces. We can for example translate a copy
+// of surface 6 by 0.12 units along the z axis and define some
+// additional lines and surfaces with:
 
 h = 0.12;
-Extrude Surface { 6, {0, 0, h} };
+Translate {0, 0, h} { Duplicata{ Surface{6}; } }
 
-Line(7) = {3,tmp[0]};
-Line(8) = {tmp[0],5};
+Line(106) = {1,8};
+Line(107) = {2,12};
+Line(108) = {3,16};
+Line(109) = {4,7};
 
-Line Loop(10) = {5,-8,-7,3};
-Plane Surface(11) = {10};
+Line Loop(110) = {1,107,-103,-106}; Plane Surface(111) = {110};
+Line Loop(112) = {2,107,104,-108};  Plane Surface(113) = {112};
+Line Loop(114) = {3,109,-105,-108}; Plane Surface(115) = {114};
+Line Loop(116) = {4,106,-102,-109}; Plane Surface(117) = {116};
+
+// Volumes are the fourth type of elementary entities in Gmsh. In the
+// same way one defines line loops to build surfaces, one has to
+// define surface loops (i.e. `shells') to build volumes. The
+// following volume does not have holes and thus consists of a single
+// surface loop:
+
+Surface Loop(118) = {117,-6,111,-113,101,115};
+Volume(119) = {118};
+
+// Another way to define a volume is by extruding a surface. The
+// following command extrudes the surface 11 along the z axis and
+// automatically creates a new volume:
 
 Extrude Surface { 11, {0, 0, h} };
 
@@ -53,7 +75,7 @@ Extrude Surface { 11, {0, 0, h} };
 // elementary entities. The following command permits to manually
 // specify a characteristic length for some of the new points:
 
-Characteristic Length {tmp[0], 22, 2, 3, 16, 12} = lc * 4;
+Characteristic Length {tmp[0], 2, 12, 3, 16, 6, 22} = lc * 4;
 
 // Note that, if the transformation tools are handy to create complex
 // geometries, it is also sometimes useful to generate the `flat'
@@ -65,20 +87,8 @@ Characteristic Length {tmp[0], 22, 2, 3, 16, 12} = lc * 4;
 //
 // on the command line.
 
-// Volumes are the fourth type of elementary entities in Gmsh. In the
-// same way one defines line loops to build surfaces, one has to
-// define surface loops (i.e. `shells') to build volumes. The
-// following volumes don't have holes and thus consist of single
-// surface loops:
-
-Surface Loop(145) = {-121,11,-131,-135,-139,-144};
-Volume(146) = {145};
-
-Surface Loop(146) = {121,-6,109,113,117,122};
-Volume(147) = {146};
-
-// To save all the tetrahedra discretizing the volumes 146 and 147
+// To save all the tetrahedra discretizing the volumes 119 and 120
 // with a common region number, we finally define a physical
 // volume:
 
-Physical Volume (1) = {146,147};
+Physical Volume (1) = {119,120};
-- 
GitLab