From c8c30d8ca1ec617e4d720402a60545a5c70b2db2 Mon Sep 17 00:00:00 2001
From: Christophe Geuzaine <cgeuzaine@ulg.ac.be>
Date: Thu, 12 Aug 2004 16:57:32 +0000
Subject: [PATCH] added vertex arrays in volumes to store the boundary of the
 cuts when we draw them "as surfaces" (for Philou, not tested yet)

---
 Common/Options.cpp   |   4 +-
 Graphics/Mesh.cpp    | 517 +++++++++++++++++++++++++++++--------------
 Mesh/Create.cpp      |   8 +-
 Mesh/Face.cpp        |  71 ++++--
 Mesh/Mesh.h          |  60 ++---
 Mesh/SecondOrder.cpp |  11 +-
 6 files changed, 458 insertions(+), 213 deletions(-)

diff --git a/Common/Options.cpp b/Common/Options.cpp
index f605cb619f..a3ad3c0e3d 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -1,4 +1,4 @@
-// $Id: Options.cpp,v 1.176 2004-07-30 12:22:01 geuzaine Exp $
+// $Id: Options.cpp,v 1.177 2004-08-12 16:57:32 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -3433,6 +3433,7 @@ double opt_mesh_surfaces_faces(OPT_ARGS_NUM)
 double opt_mesh_volumes_edges(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
+    if(CTX.mesh.volumes_edges != val) CTX.mesh.changed = 1;
     CTX.mesh.volumes_edges = (int)val;
   }
 #if defined(HAVE_FLTK)
@@ -3445,6 +3446,7 @@ double opt_mesh_volumes_edges(OPT_ARGS_NUM)
 double opt_mesh_volumes_faces(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
+    if(CTX.mesh.volumes_faces != val) CTX.mesh.changed = 1;
     CTX.mesh.volumes_faces = (int)val;
   }
 #if defined(HAVE_FLTK)
diff --git a/Graphics/Mesh.cpp b/Graphics/Mesh.cpp
index 50fa6e898d..9714fc979c 100644
--- a/Graphics/Mesh.cpp
+++ b/Graphics/Mesh.cpp
@@ -1,4 +1,4 @@
-// $Id: Mesh.cpp,v 1.106 2004-07-23 01:28:57 geuzaine Exp $
+// $Id: Mesh.cpp,v 1.107 2004-08-12 16:57:32 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -38,9 +38,17 @@ extern int edges_hexa[12][2];
 extern int edges_prism[9][2];
 extern int edges_pyramid[8][2];
 
+extern int trifaces_tetra[4][3];
+extern int trifaces_prism[2][3];
+extern int trifaces_pyramid[4][3];
+extern int quadfaces_hexa[6][4];
+extern int quadfaces_prism[3][4];
+extern int quadfaces_pyramid[1][4];
+
 static DrawingColor theColor;
 static int thePhysical = 0;
 static Surface *theSurface = NULL;
+static Volume *theVolume = NULL;
 
 void draw_polygon_2d(double r, double g, double b, int n,
                      double *x, double *y, double *z)
@@ -249,12 +257,57 @@ void Draw_Mesh_Volume(void *a, void *b)
   Volume *v = *(Volume **) a;
   if(!(v->Visible & VIS_MESH))
     return;
+
+  theVolume = v;
   theColor = v->Color;
   thePhysical = getFirstPhysical(MSH_PHYSICAL_VOLUME, v->Num);
-  Tree_Action(v->Simplexes, Draw_Mesh_Tetrahedron);
-  Tree_Action(v->Hexahedra, Draw_Mesh_Hexahedron);
-  Tree_Action(v->Prisms, Draw_Mesh_Prism);
-  Tree_Action(v->Pyramids, Draw_Mesh_Pyramid);
+
+  // we don't use vertex arrays for every volume primitive: on;y for
+  // volume cuts drawn "as surfaces" (using vefrtex arrays for
+  // everything would require quite a bit of memory)
+  if(CTX.mesh.use_cut_plane && CTX.mesh.cut_plane_as_surface && 
+     CTX.mesh.vertex_arrays){
+    if(CTX.mesh.changed){
+      Msg(DEBUG, "regenerate volume mesh vertex arrays");
+      // triangles
+      if(v->TriVertexArray) delete v->TriVertexArray;
+      v->TriVertexArray = new VertexArray(3, 1000);
+      v->TriVertexArray->fill = 1;
+      // quadrangles
+      if(v->QuadVertexArray) delete v->QuadVertexArray;
+      v->QuadVertexArray = new VertexArray(4, 1000);
+      v->QuadVertexArray->fill = 1;
+      Tree_Action(v->Simplexes, Draw_Mesh_Tetrahedron);
+      Tree_Action(v->Hexahedra, Draw_Mesh_Hexahedron);
+      Tree_Action(v->Prisms, Draw_Mesh_Prism);
+      Tree_Action(v->Pyramids, Draw_Mesh_Pyramid);
+      if(v->TriVertexArray){
+	Msg(DEBUG, "%d triangles in volume vertex array", v->TriVertexArray->num);
+	v->TriVertexArray->fill = 0;
+      }
+      if(v->QuadVertexArray){
+	Msg(DEBUG, "%d quads in volume vertex array", v->QuadVertexArray->num);
+	v->QuadVertexArray->fill = 0;
+      }
+    }
+    if(v->TriVertexArray)
+      Draw_Mesh_Array(v->TriVertexArray,
+		      CTX.mesh.surfaces_faces, CTX.mesh.surfaces_edges);
+    if(v->QuadVertexArray)
+      Draw_Mesh_Array(v->QuadVertexArray,
+		      CTX.mesh.surfaces_faces, CTX.mesh.surfaces_edges);
+  }
+
+  if(!CTX.mesh.use_cut_plane || !CTX.mesh.cut_plane_as_surface ||
+     !v->TriVertexArray || !v->QuadVertexArray ||
+     CTX.mesh.volumes_faces || CTX.mesh.volumes_edges ||
+     CTX.mesh.dual || CTX.mesh.volumes_num || CTX.mesh.normals){
+    Msg(DEBUG, "classic volume data path");
+    Tree_Action(v->Simplexes, Draw_Mesh_Tetrahedron);
+    Tree_Action(v->Hexahedra, Draw_Mesh_Hexahedron);
+    Tree_Action(v->Prisms, Draw_Mesh_Prism);
+    Tree_Action(v->Pyramids, Draw_Mesh_Pyramid);
+  }
 }
 
 static int preproNormals = 0;
@@ -288,7 +341,7 @@ void Draw_Mesh_Surface(void *a, void *b)
       s->TriVertexArray->fill = 1;
       Tree_Action(s->Simplexes, Draw_Mesh_Triangle);
       if(s->TriVertexArray){
-	Msg(DEBUG, "%d triangles in vertex array", s->TriVertexArray->num);
+	Msg(DEBUG, "%d triangles in surface vertex array", s->TriVertexArray->num);
 	s->TriVertexArray->fill = 0;
       }
       // quads
@@ -297,7 +350,7 @@ void Draw_Mesh_Surface(void *a, void *b)
       s->QuadVertexArray->fill = 1;
       Tree_Action(s->Quadrangles, Draw_Mesh_Quadrangle);
       if(s->QuadVertexArray){
-	Msg(DEBUG, "%d quads in vertex array", s->QuadVertexArray->num);
+	Msg(DEBUG, "%d quads in surface vertex array", s->QuadVertexArray->num);
 	s->QuadVertexArray->fill = 0;
       }
     }
@@ -1000,6 +1053,11 @@ void Draw_Mesh_Tetrahedron(void *a, void *b)
     Z[i] = Zc + CTX.mesh.explode * (s->V[i]->Pos.Z - Zc);
   }
   if(s->VSUP){
+    if(theVolume && theVolume->TriVertexArray){
+      // vertex arrays not implemented for second order elements
+      delete theVolume->TriVertexArray;
+      theVolume->TriVertexArray = NULL;
+    }
     for(int i = 0; i < 6; i++) {
       X2[i] = Xc + CTX.mesh.explode * (s->VSUP[i]->Pos.X - Xc);
       Y2[i] = Yc + CTX.mesh.explode * (s->VSUP[i]->Pos.Y - Yc);
@@ -1007,47 +1065,66 @@ void Draw_Mesh_Tetrahedron(void *a, void *b)
     }
   }
 
-  if(edges) {
-    if(CTX.mesh.surfaces_faces || faces)
-      glColor4ubv((GLubyte *) & CTX.color.mesh.line);
-    else
-      glColor4ubv((GLubyte *) & col);
-    glBegin(GL_LINES);
-    for(int i = 0; i < 6; i++){
-      int j = edges_tetra[i][0];
-      int k = edges_tetra[i][1];
-      glVertex3d(X[j], Y[j], Z[j]);
-      if(s->VSUP){
-	glVertex3d(X2[i], Y2[i], Z2[i]);
-	glVertex3d(X2[i], Y2[i], Z2[i]);
+  if(CTX.mesh.use_cut_plane && CTX.mesh.cut_plane_as_surface && 
+     (edges || faces) && !(CTX.mesh.volumes_edges || CTX.mesh.volumes_faces) &&
+     theVolume && theVolume->TriVertexArray){
+    if(theVolume->TriVertexArray->fill){
+      for(int i = 0; i < 4; i++){
+	int a = trifaces_tetra[i][0];
+	int b = trifaces_tetra[i][1];
+	int c = trifaces_tetra[i][2];
+	double n[3];
+	_normal3points(X[a], Y[a], Z[a], X[b], Y[b], Z[b], X[c], Y[c], Z[c], n);
+	theVolume->TriVertexArray->add(X[a], Y[a], Z[a], n[0], n[1], n[2], col);
+	theVolume->TriVertexArray->add(X[b], Y[b], Z[b], n[0], n[1], n[2], col);
+	theVolume->TriVertexArray->add(X[c], Y[c], Z[c], n[0], n[1], n[2], col);
+	theVolume->TriVertexArray->num++;
       }
-      glVertex3d(X[k], Y[k], Z[k]);
     }
-    glEnd();
-  }
-
-  if(faces){
-    glColor4ubv((GLubyte *) & col);
-    if(CTX.mesh.light) glEnable(GL_LIGHTING);
-    if(CTX.mesh.surfaces_edges || edges) glEnable(GL_POLYGON_OFFSET_FILL);
-    if(!s->VSUP){
-      glBegin(GL_TRIANGLES);
-      _triFace(X[0], Y[0], Z[0], X[2], Y[2], Z[2], X[1], Y[1], Z[1]);
-      _triFace(X[0], Y[0], Z[0], X[1], Y[1], Z[1], X[3], Y[3], Z[3]);
-      _triFace(X[0], Y[0], Z[0], X[3], Y[3], Z[3], X[2], Y[2], Z[2]);
-      _triFace(X[3], Y[3], Z[3], X[1], Y[1], Z[1], X[2], Y[2], Z[2]);
+  }    
+  else{
+    if(edges) {
+      if(CTX.mesh.surfaces_faces || faces)
+	glColor4ubv((GLubyte *) & CTX.color.mesh.line);
+      else
+	glColor4ubv((GLubyte *) & col);
+      glBegin(GL_LINES);
+      for(int i = 0; i < 6; i++){
+	int j = edges_tetra[i][0];
+	int k = edges_tetra[i][1];
+	glVertex3d(X[j], Y[j], Z[j]);
+	if(s->VSUP){
+	  glVertex3d(X2[i], Y2[i], Z2[i]);
+	  glVertex3d(X2[i], Y2[i], Z2[i]);
+	}
+	glVertex3d(X[k], Y[k], Z[k]);
+      }
       glEnd();
     }
-    else{
-      glBegin(GL_TRIANGLES);
-      _triFace2(X, Y, Z, X2, Y2, Z2, 0, 2, 1, 2, 1, 0);
-      _triFace2(X, Y, Z, X2, Y2, Z2, 0, 1, 3, 0, 5, 3);
-      _triFace2(X, Y, Z, X2, Y2, Z2, 0, 3, 2, 3, 4, 2);
-      _triFace2(X, Y, Z, X2, Y2, Z2, 3, 1, 2, 5, 1, 4);
-      glEnd();
+    
+    if(faces){
+      glColor4ubv((GLubyte *) & col);
+      if(CTX.mesh.light) glEnable(GL_LIGHTING);
+      if(CTX.mesh.surfaces_edges || edges) glEnable(GL_POLYGON_OFFSET_FILL);
+      if(!s->VSUP){
+	glBegin(GL_TRIANGLES);
+	_triFace(X[0], Y[0], Z[0], X[2], Y[2], Z[2], X[1], Y[1], Z[1]);
+	_triFace(X[0], Y[0], Z[0], X[1], Y[1], Z[1], X[3], Y[3], Z[3]);
+	_triFace(X[0], Y[0], Z[0], X[3], Y[3], Z[3], X[2], Y[2], Z[2]);
+	_triFace(X[3], Y[3], Z[3], X[1], Y[1], Z[1], X[2], Y[2], Z[2]);
+	glEnd();
+      }
+      else{
+	glBegin(GL_TRIANGLES);
+	_triFace2(X, Y, Z, X2, Y2, Z2, 0, 2, 1, 2, 1, 0);
+	_triFace2(X, Y, Z, X2, Y2, Z2, 0, 1, 3, 0, 5, 3);
+	_triFace2(X, Y, Z, X2, Y2, Z2, 0, 3, 2, 3, 4, 2);
+	_triFace2(X, Y, Z, X2, Y2, Z2, 3, 1, 2, 5, 1, 4);
+	glEnd();
+      }
+      glDisable(GL_POLYGON_OFFSET_FILL);
+      glDisable(GL_LIGHTING);
     }
-    glDisable(GL_POLYGON_OFFSET_FILL);
-    glDisable(GL_LIGHTING);
   }
 
   if(CTX.mesh.dual) {
@@ -1132,6 +1209,11 @@ void Draw_Mesh_Hexahedron(void *a, void *b)
     Z[i] = Zc + CTX.mesh.explode * (h->V[i]->Pos.Z - Zc);
   }
   if(h->VSUP){
+    if(theVolume && theVolume->QuadVertexArray){
+      // vertex arrays not implemented for second order elements
+      delete theVolume->QuadVertexArray;
+      theVolume->QuadVertexArray = NULL;
+    }
     for(int i = 0; i < 18; i++) {
       X2[i] = Xc + CTX.mesh.explode * (h->VSUP[i]->Pos.X - Xc);
       Y2[i] = Yc + CTX.mesh.explode * (h->VSUP[i]->Pos.Y - Yc);
@@ -1139,52 +1221,73 @@ void Draw_Mesh_Hexahedron(void *a, void *b)
     }
   }
 
-  if(edges){
-    if(CTX.mesh.surfaces_faces || faces)
-      glColor4ubv((GLubyte *) & CTX.color.mesh.line);
-    else
-      glColor4ubv((GLubyte *) & col);
-    glBegin(GL_LINES);
-    for(int i = 0; i < 12; i++){
-      int j = edges_hexa[i][0];
-      int k = edges_hexa[i][1];
-      glVertex3d(X[j], Y[j], Z[j]);
-      if(h->VSUP){
-	glVertex3d(X2[i], Y2[i], Z2[i]);
-	glVertex3d(X2[i], Y2[i], Z2[i]);
+  if(CTX.mesh.use_cut_plane && CTX.mesh.cut_plane_as_surface && 
+     (edges || faces) && !(CTX.mesh.volumes_edges || CTX.mesh.volumes_faces) &&
+     theVolume && theVolume->QuadVertexArray){
+    if(theVolume->QuadVertexArray->fill){
+      for(int i = 0; i < 6; i++){
+	int a = quadfaces_hexa[i][0];
+	int b = quadfaces_hexa[i][1];
+	int c = quadfaces_hexa[i][2];
+	int d = quadfaces_hexa[i][3];
+	double n[3];
+	_normal3points(X[a], Y[a], Z[a], X[b], Y[b], Z[b], X[c], Y[c], Z[c], n);
+	theVolume->QuadVertexArray->add(X[a], Y[a], Z[a], n[0], n[1], n[2], col);
+	theVolume->QuadVertexArray->add(X[b], Y[b], Z[b], n[0], n[1], n[2], col);
+	theVolume->QuadVertexArray->add(X[c], Y[c], Z[c], n[0], n[1], n[2], col);
+	theVolume->QuadVertexArray->add(X[d], Y[d], Z[d], n[0], n[1], n[2], col);
+	theVolume->QuadVertexArray->num++;
       }
-      glVertex3d(X[k], Y[k], Z[k]);
     }
-    glEnd();
-  }
-
-  if(faces){
-    glColor4ubv((GLubyte *) & col);
-    if(CTX.mesh.light) glEnable(GL_LIGHTING);
-    if(CTX.mesh.surfaces_edges || edges) glEnable(GL_POLYGON_OFFSET_FILL);
-    if(!h->VSUP){
-      glBegin(GL_QUADS);
-      _quadFace(X, Y, Z, 0, 3, 2, 1);
-      _quadFace(X, Y, Z, 4, 5, 6, 7);
-      _quadFace(X, Y, Z, 0, 1, 5, 4);
-      _quadFace(X, Y, Z, 1, 2, 6, 5);
-      _quadFace(X, Y, Z, 2, 3, 7, 6);
-      _quadFace(X, Y, Z, 0, 4, 7, 3);
+  }    
+  else{
+    if(edges){
+      if(CTX.mesh.surfaces_faces || faces)
+	glColor4ubv((GLubyte *) & CTX.color.mesh.line);
+      else
+	glColor4ubv((GLubyte *) & col);
+      glBegin(GL_LINES);
+      for(int i = 0; i < 12; i++){
+	int j = edges_hexa[i][0];
+	int k = edges_hexa[i][1];
+	glVertex3d(X[j], Y[j], Z[j]);
+	if(h->VSUP){
+	  glVertex3d(X2[i], Y2[i], Z2[i]);
+	  glVertex3d(X2[i], Y2[i], Z2[i]);
+	}
+	glVertex3d(X[k], Y[k], Z[k]);
+      }
       glEnd();
     }
-    else{
-      glBegin(GL_TRIANGLES);
-      _quadFace2(X, Y, Z, X2, Y2, Z2, 0, 3, 2, 1, 1, 5, 3, 0, 12);
-      _quadFace2(X, Y, Z, X2, Y2, Z2, 4, 5, 6, 7, 8, 10, 11, 9, 17);
-      _quadFace2(X, Y, Z, X2, Y2, Z2, 0, 1, 5, 4, 0, 4, 8, 2, 13);
-      _quadFace2(X, Y, Z, X2, Y2, Z2, 1, 2, 6, 5, 3, 6, 10, 4, 15);
-      _quadFace2(X, Y, Z, X2, Y2, Z2, 2, 3, 7, 6, 5, 7, 11, 6, 16);
-      _quadFace2(X, Y, Z, X2, Y2, Z2, 0, 4, 7, 3, 2, 9, 7, 1, 14);
-      glEnd();
+    
+    if(faces){
+      glColor4ubv((GLubyte *) & col);
+      if(CTX.mesh.light) glEnable(GL_LIGHTING);
+      if(CTX.mesh.surfaces_edges || edges) glEnable(GL_POLYGON_OFFSET_FILL);
+      if(!h->VSUP){
+	glBegin(GL_QUADS);
+	_quadFace(X, Y, Z, 0, 3, 2, 1);
+	_quadFace(X, Y, Z, 0, 1, 5, 4);
+	_quadFace(X, Y, Z, 0, 4, 7, 3);
+	_quadFace(X, Y, Z, 1, 2, 6, 5);
+	_quadFace(X, Y, Z, 2, 3, 7, 6);
+	_quadFace(X, Y, Z, 4, 5, 6, 7);
+	glEnd();
+      }
+      else{
+	glBegin(GL_TRIANGLES);
+	_quadFace2(X, Y, Z, X2, Y2, Z2, 0, 3, 2, 1, 1, 5, 3, 0, 12);
+	_quadFace2(X, Y, Z, X2, Y2, Z2, 0, 1, 5, 4, 0, 4, 8, 2, 13);
+	_quadFace2(X, Y, Z, X2, Y2, Z2, 0, 4, 7, 3, 2, 9, 7, 1, 14);
+	_quadFace2(X, Y, Z, X2, Y2, Z2, 1, 2, 6, 5, 3, 6, 10, 4, 15);
+	_quadFace2(X, Y, Z, X2, Y2, Z2, 2, 3, 7, 6, 5, 7, 11, 6, 16);
+	_quadFace2(X, Y, Z, X2, Y2, Z2, 4, 5, 6, 7, 8, 10, 11, 9, 17);
+	glEnd();
+      }
+      glDisable(GL_POLYGON_OFFSET_FILL);
+      glDisable(GL_LIGHTING);
     }
-    glDisable(GL_POLYGON_OFFSET_FILL);
-    glDisable(GL_LIGHTING);
-  }
+  }    
 
   if(CTX.mesh.dual) {
     glColor4ubv((GLubyte *) & CTX.color.fg);
@@ -1274,6 +1377,16 @@ void Draw_Mesh_Prism(void *a, void *b)
     Z[i] = Zc + CTX.mesh.explode * (p->V[i]->Pos.Z - Zc);
   }
   if(p->VSUP){
+    if(theVolume && theVolume->TriVertexArray){
+      // vertex arrays not implemented for second order elements
+      delete theVolume->TriVertexArray;
+      theVolume->TriVertexArray = NULL;
+    }
+    if(theVolume && theVolume->QuadVertexArray){
+      // vertex arrays not implemented for second order elements
+      delete theVolume->QuadVertexArray;
+      theVolume->QuadVertexArray = NULL;
+    }
     for(int i = 0; i < 12; i++) {
       X2[i] = Xc + CTX.mesh.explode * (p->VSUP[i]->Pos.X - Xc);
       Y2[i] = Yc + CTX.mesh.explode * (p->VSUP[i]->Pos.Y - Yc);
@@ -1281,51 +1394,85 @@ void Draw_Mesh_Prism(void *a, void *b)
     }
   }
 
-  if(edges){
-    if(CTX.mesh.surfaces_faces || faces)
-      glColor4ubv((GLubyte *) & CTX.color.mesh.line);
-    else
-      glColor4ubv((GLubyte *) & col);
-    glBegin(GL_LINES);
-    for(int i = 0; i < 9; i++){
-      int j = edges_prism[i][0];
-      int k = edges_prism[i][1];
-      glVertex3d(X[j], Y[j], Z[j]);
-      if(p->VSUP){
-	glVertex3d(X2[i], Y2[i], Z2[i]);
-	glVertex3d(X2[i], Y2[i], Z2[i]);
+  if(CTX.mesh.use_cut_plane && CTX.mesh.cut_plane_as_surface && 
+     (edges || faces) && !(CTX.mesh.volumes_edges || CTX.mesh.volumes_faces) &&
+     theVolume && theVolume->TriVertexArray && theVolume->QuadVertexArray){
+    if(theVolume->TriVertexArray->fill){
+      for(int i = 0; i < 2; i++){
+	int a = trifaces_prism[i][0];
+	int b = trifaces_prism[i][1];
+	int c = trifaces_prism[i][2];
+	double n[3];
+	_normal3points(X[a], Y[a], Z[a], X[b], Y[b], Z[b], X[c], Y[c], Z[c], n);
+	theVolume->TriVertexArray->add(X[a], Y[a], Z[a], n[0], n[1], n[2], col);
+	theVolume->TriVertexArray->add(X[b], Y[b], Z[b], n[0], n[1], n[2], col);
+	theVolume->TriVertexArray->add(X[c], Y[c], Z[c], n[0], n[1], n[2], col);
+	theVolume->TriVertexArray->num++;
       }
-      glVertex3d(X[k], Y[k], Z[k]);
     }
-    glEnd();
-  }
-
-  if(faces){
-    glColor4ubv((GLubyte *) & col);
-    if(CTX.mesh.light) glEnable(GL_LIGHTING);
-    if(CTX.mesh.surfaces_edges || edges) glEnable(GL_POLYGON_OFFSET_FILL);
-    if(!p->VSUP){
-      glBegin(GL_TRIANGLES);
-      _triFace(X[0], Y[0], Z[0], X[2], Y[2], Z[2], X[1], Y[1], Z[1]);
-      _triFace(X[3], Y[3], Z[3], X[4], Y[4], Z[4], X[5], Y[5], Z[5]);
-      glEnd();
-      glBegin(GL_QUADS);
-      _quadFace(X, Y, Z, 0, 1, 4, 3);
-      _quadFace(X, Y, Z, 1, 2, 5, 4);
-      _quadFace(X, Y, Z, 0, 3, 5, 2);
-      glEnd();
+    if(theVolume->QuadVertexArray->fill){
+      for(int i = 0; i < 3; i++){
+	int a = quadfaces_prism[i][0];
+	int b = quadfaces_prism[i][1];
+	int c = quadfaces_prism[i][2];
+	int d = quadfaces_prism[i][3];
+	double n[3];
+	_normal3points(X[a], Y[a], Z[a], X[b], Y[b], Z[b], X[c], Y[c], Z[c], n);
+	theVolume->QuadVertexArray->add(X[a], Y[a], Z[a], n[0], n[1], n[2], col);
+	theVolume->QuadVertexArray->add(X[b], Y[b], Z[b], n[0], n[1], n[2], col);
+	theVolume->QuadVertexArray->add(X[c], Y[c], Z[c], n[0], n[1], n[2], col);
+	theVolume->QuadVertexArray->add(X[d], Y[d], Z[d], n[0], n[1], n[2], col);
+	theVolume->QuadVertexArray->num++;
+      }
     }
-    else{
-      glBegin(GL_TRIANGLES);
-      _triFace2(X, Y, Z, X2, Y2, Z2, 0, 2, 1, 1, 3, 0);
-      _triFace2(X, Y, Z, X2, Y2, Z2, 3, 4, 5, 6, 8, 7);
-      _quadFace2(X, Y, Z, X2, Y2, Z2, 0, 1, 4, 3, 0, 4, 6, 2, 9);
-      _quadFace2(X, Y, Z, X2, Y2, Z2, 1, 2, 5, 4, 3, 5, 8, 4, 11);
-      _quadFace2(X, Y, Z, X2, Y2, Z2, 0, 3, 5, 2, 2, 7, 5, 1, 10);
+  }    
+  else{
+    if(edges){
+      if(CTX.mesh.surfaces_faces || faces)
+	glColor4ubv((GLubyte *) & CTX.color.mesh.line);
+      else
+	glColor4ubv((GLubyte *) & col);
+      glBegin(GL_LINES);
+      for(int i = 0; i < 9; i++){
+	int j = edges_prism[i][0];
+	int k = edges_prism[i][1];
+	glVertex3d(X[j], Y[j], Z[j]);
+	if(p->VSUP){
+	  glVertex3d(X2[i], Y2[i], Z2[i]);
+	  glVertex3d(X2[i], Y2[i], Z2[i]);
+	}
+	glVertex3d(X[k], Y[k], Z[k]);
+      }
       glEnd();
     }
-    glDisable(GL_POLYGON_OFFSET_FILL);
-    glDisable(GL_LIGHTING);
+    
+    if(faces){
+      glColor4ubv((GLubyte *) & col);
+      if(CTX.mesh.light) glEnable(GL_LIGHTING);
+      if(CTX.mesh.surfaces_edges || edges) glEnable(GL_POLYGON_OFFSET_FILL);
+      if(!p->VSUP){
+	glBegin(GL_TRIANGLES);
+	_triFace(X[0], Y[0], Z[0], X[2], Y[2], Z[2], X[1], Y[1], Z[1]);
+	_triFace(X[3], Y[3], Z[3], X[4], Y[4], Z[4], X[5], Y[5], Z[5]);
+	glEnd();
+	glBegin(GL_QUADS);
+	_quadFace(X, Y, Z, 0, 1, 4, 3);
+	_quadFace(X, Y, Z, 0, 3, 5, 2);
+	_quadFace(X, Y, Z, 1, 2, 5, 4);
+	glEnd();
+      }
+      else{
+	glBegin(GL_TRIANGLES);
+	_triFace2(X, Y, Z, X2, Y2, Z2, 0, 2, 1, 1, 3, 0);
+	_triFace2(X, Y, Z, X2, Y2, Z2, 3, 4, 5, 6, 8, 7);
+	_quadFace2(X, Y, Z, X2, Y2, Z2, 0, 1, 4, 3, 0, 4, 6, 2, 9);
+	_quadFace2(X, Y, Z, X2, Y2, Z2, 0, 3, 5, 2, 2, 7, 5, 1, 10);
+	_quadFace2(X, Y, Z, X2, Y2, Z2, 1, 2, 5, 4, 3, 5, 8, 4, 11);
+	glEnd();
+      }
+      glDisable(GL_POLYGON_OFFSET_FILL);
+      glDisable(GL_LIGHTING);
+    }
   }
 
   if(CTX.mesh.dual) {
@@ -1413,6 +1560,16 @@ void Draw_Mesh_Pyramid(void *a, void *b)
     Z[i] = Zc + CTX.mesh.explode * (p->V[i]->Pos.Z - Zc);
   }
   if(p->VSUP){
+    if(theVolume && theVolume->TriVertexArray){
+      // vertex arrays not implemented for second order elements
+      delete theVolume->TriVertexArray;
+      theVolume->TriVertexArray = NULL;
+    }
+    if(theVolume && theVolume->QuadVertexArray){
+      // vertex arrays not implemented for second order elements
+      delete theVolume->QuadVertexArray;
+      theVolume->QuadVertexArray = NULL;
+    }
     for(int i = 0; i < 9; i++) {
       X2[i] = Xc + CTX.mesh.explode * (p->VSUP[i]->Pos.X - Xc);
       Y2[i] = Yc + CTX.mesh.explode * (p->VSUP[i]->Pos.Y - Yc);
@@ -1420,51 +1577,83 @@ void Draw_Mesh_Pyramid(void *a, void *b)
     }
   }
 
-  if(edges){
-    if(CTX.mesh.surfaces_faces || faces)
-      glColor4ubv((GLubyte *) & CTX.color.mesh.line);
-    else
-      glColor4ubv((GLubyte *) & col);
-    glBegin(GL_LINES);
-    for(int i = 0; i < 8; i++){
-      int j = edges_pyramid[i][0];
-      int k = edges_pyramid[i][1];
-      glVertex3d(X[j], Y[j], Z[j]);
-      if(p->VSUP){
-	glVertex3d(X2[i], Y2[i], Z2[i]);
-	glVertex3d(X2[i], Y2[i], Z2[i]);
+  if(CTX.mesh.use_cut_plane && CTX.mesh.cut_plane_as_surface && 
+     (edges || faces) && !(CTX.mesh.volumes_edges || CTX.mesh.volumes_faces) &&
+     theVolume && theVolume->TriVertexArray && theVolume->QuadVertexArray){
+    if(theVolume->TriVertexArray->fill){
+      for(int i = 0; i < 4; i++){
+	int a = trifaces_pyramid[i][0];
+	int b = trifaces_pyramid[i][1];
+	int c = trifaces_pyramid[i][2];
+	double n[3];
+	_normal3points(X[a], Y[a], Z[a], X[b], Y[b], Z[b], X[c], Y[c], Z[c], n);
+	theVolume->TriVertexArray->add(X[a], Y[a], Z[a], n[0], n[1], n[2], col);
+	theVolume->TriVertexArray->add(X[b], Y[b], Z[b], n[0], n[1], n[2], col);
+	theVolume->TriVertexArray->add(X[c], Y[c], Z[c], n[0], n[1], n[2], col);
+	theVolume->TriVertexArray->num++;
       }
-      glVertex3d(X[k], Y[k], Z[k]);
     }
-    glEnd();
-  }
-
-  if(faces){
-    glColor4ubv((GLubyte *) & col);
-    if(CTX.mesh.light) glEnable(GL_LIGHTING);
-    if(CTX.mesh.surfaces_edges || edges) glEnable(GL_POLYGON_OFFSET_FILL);
-    if(!p->VSUP){
-      glBegin(GL_QUADS);
-      _quadFace(X, Y, Z, 0, 3, 2, 1);
-      glEnd();
-      glBegin(GL_TRIANGLES);
-      _triFace(X[1], Y[1], Z[1], X[2], Y[2], Z[2], X[4], Y[4], Z[4]);
-      _triFace(X[2], Y[2], Z[2], X[3], Y[3], Z[3], X[4], Y[4], Z[4]);
-      _triFace(X[3], Y[3], Z[3], X[0], Y[0], Z[0], X[4], Y[4], Z[4]);
-      _triFace(X[0], Y[0], Z[0], X[1], Y[1], Z[1], X[4], Y[4], Z[4]);
-      glEnd();
+    if(theVolume->QuadVertexArray->fill){
+      int a = quadfaces_pyramid[0][0];
+      int b = quadfaces_pyramid[0][1];
+      int c = quadfaces_pyramid[0][2];
+      int d = quadfaces_pyramid[0][3];
+      double n[3];
+      _normal3points(X[a], Y[a], Z[a], X[b], Y[b], Z[b], X[c], Y[c], Z[c], n);
+      theVolume->QuadVertexArray->add(X[a], Y[a], Z[a], n[0], n[1], n[2], col);
+      theVolume->QuadVertexArray->add(X[b], Y[b], Z[b], n[0], n[1], n[2], col);
+      theVolume->QuadVertexArray->add(X[c], Y[c], Z[c], n[0], n[1], n[2], col);
+      theVolume->QuadVertexArray->add(X[d], Y[d], Z[d], n[0], n[1], n[2], col);
+      theVolume->QuadVertexArray->num++;
     }
-    else{
-      glBegin(GL_TRIANGLES);
-      _quadFace2(X, Y, Z, X2, Y2, Z2, 0, 3, 2, 1, 1, 5, 3, 0, 8);
-      _triFace2(X, Y, Z, X2, Y2, Z2, 1, 2, 4, 3, 6, 4);
-      _triFace2(X, Y, Z, X2, Y2, Z2, 2, 3, 4, 5, 7, 6);
-      _triFace2(X, Y, Z, X2, Y2, Z2, 3, 0, 4, 1, 2, 7);
-      _triFace2(X, Y, Z, X2, Y2, Z2, 0, 1, 4, 0, 4, 2);
+  }    
+  else{
+    if(edges){
+      if(CTX.mesh.surfaces_faces || faces)
+	glColor4ubv((GLubyte *) & CTX.color.mesh.line);
+      else
+	glColor4ubv((GLubyte *) & col);
+      glBegin(GL_LINES);
+      for(int i = 0; i < 8; i++){
+	int j = edges_pyramid[i][0];
+	int k = edges_pyramid[i][1];
+	glVertex3d(X[j], Y[j], Z[j]);
+	if(p->VSUP){
+	  glVertex3d(X2[i], Y2[i], Z2[i]);
+	  glVertex3d(X2[i], Y2[i], Z2[i]);
+	}
+	glVertex3d(X[k], Y[k], Z[k]);
+      }
       glEnd();
     }
-    glDisable(GL_POLYGON_OFFSET_FILL);
-    glDisable(GL_LIGHTING);
+
+    if(faces){
+      glColor4ubv((GLubyte *) & col);
+      if(CTX.mesh.light) glEnable(GL_LIGHTING);
+      if(CTX.mesh.surfaces_edges || edges) glEnable(GL_POLYGON_OFFSET_FILL);
+      if(!p->VSUP){
+	glBegin(GL_QUADS);
+	_quadFace(X, Y, Z, 0, 3, 2, 1);
+	glEnd();
+	glBegin(GL_TRIANGLES);
+	_triFace(X[0], Y[0], Z[0], X[1], Y[1], Z[1], X[4], Y[4], Z[4]);
+	_triFace(X[3], Y[3], Z[3], X[0], Y[0], Z[0], X[4], Y[4], Z[4]);
+	_triFace(X[1], Y[1], Z[1], X[2], Y[2], Z[2], X[4], Y[4], Z[4]);
+	_triFace(X[2], Y[2], Z[2], X[3], Y[3], Z[3], X[4], Y[4], Z[4]);
+	glEnd();
+      }
+      else{
+	glBegin(GL_TRIANGLES);
+	_quadFace2(X, Y, Z, X2, Y2, Z2, 0, 3, 2, 1, 1, 5, 3, 0, 8);
+	_triFace2(X, Y, Z, X2, Y2, Z2, 0, 1, 4, 0, 4, 2);
+	_triFace2(X, Y, Z, X2, Y2, Z2, 3, 0, 4, 1, 2, 7);
+	_triFace2(X, Y, Z, X2, Y2, Z2, 1, 2, 4, 3, 6, 4);
+	_triFace2(X, Y, Z, X2, Y2, Z2, 2, 3, 4, 5, 7, 6);
+	glEnd();
+      }
+      glDisable(GL_POLYGON_OFFSET_FILL);
+      glDisable(GL_LIGHTING);
+    }
   }
 
   if(CTX.mesh.volumes_num) {
diff --git a/Mesh/Create.cpp b/Mesh/Create.cpp
index cdbcfb3015..9fdd5cfd77 100644
--- a/Mesh/Create.cpp
+++ b/Mesh/Create.cpp
@@ -1,4 +1,4 @@
-// $Id: Create.cpp,v 1.62 2004-07-16 18:02:20 geuzaine Exp $
+// $Id: Create.cpp,v 1.63 2004-08-12 16:57:32 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -734,6 +734,8 @@ Volume *Create_Volume(int Num, int Typ)
   // for old extrusion mesh generator
   pV->Simp_Surf = Tree_Create(sizeof(Simplex *), compareSimplex);
   pV->Quad_Surf = Tree_Create(sizeof(Simplex *), compareQuadrangle);
+  pV->TriVertexArray = NULL;
+  pV->QuadVertexArray = NULL;
   return pV;
 }
 
@@ -766,6 +768,10 @@ void Free_Volume_But_Not_Elements(void *a, void *b)
     Tree_Delete(pV->Pyramids);
     Tree_Delete(pV->Edges);
     Tree_Delete(pV->Faces);
+    if(pV->TriVertexArray)
+      delete pV->TriVertexArray;
+    if(pV->QuadVertexArray)
+      delete pV->QuadVertexArray;
     Free(pV);
     pV = NULL;
   }
diff --git a/Mesh/Face.cpp b/Mesh/Face.cpp
index 0fbc29177e..bb70e72b67 100644
--- a/Mesh/Face.cpp
+++ b/Mesh/Face.cpp
@@ -1,4 +1,4 @@
-// $Id: Face.cpp,v 1.1 2004-05-25 23:16:26 geuzaine Exp $
+// $Id: Face.cpp,v 1.2 2004-08-12 16:57:32 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -25,6 +25,25 @@
 
 // Simplex faces
 
+int trifaces_tetra[4][3] = {
+  {0, 2, 1},
+  {0, 1, 3},
+  {0, 3, 2},
+  {3, 1, 2}
+};
+
+int trifaces_prism[2][3] = {
+  {0, 2, 1},
+  {3, 4, 5}
+};
+
+int trifaces_pyramid[4][3] = {
+  {0, 1, 4},
+  {3, 0, 4},
+  {1, 2, 4},
+  {2, 3, 4}
+};
+
 extern int FACE_DIMENSION;
 
 int compareFace(const void *a, const void *b)
@@ -57,19 +76,45 @@ int compareFace(const void *a, const void *b)
 
 // Quad faces
 
+// define the faces to have exterior normals, so that we can use these
+// structures directly in the drawing routines
+
+// int quadfaces_hexa[6][4] = {
+//   {0, 1, 2, 3},
+//   {0, 1, 4, 5},
+//   {0, 3, 4, 7},
+//   {1, 2, 5, 6},
+//   {2, 3, 6, 7},
+//   {4, 5, 6, 7}
+// };
+
+// int quadfaces_prism[3][4] = {
+//   {0, 1, 3, 4},
+//   {0, 2, 3, 5},
+//   {1, 2, 4, 5}
+// };
+
+// int quadfaces_pyramid[1][4] = {
+//   {0, 1, 2, 3}
+// };
+
 int quadfaces_hexa[6][4] = {
-  {0, 1, 2, 3},
-  {0, 1, 4, 5},
-  {0, 3, 4, 7},
-  {1, 2, 5, 6},
-  {2, 3, 6, 7},
+  {0, 3, 2, 1},
+  {0, 1, 5, 4},
+  {0, 4, 7, 3},
+  {1, 2, 6, 5},
+  {2, 3, 7, 6},
   {4, 5, 6, 7}
 };
 
 int quadfaces_prism[3][4] = {
-  {0, 1, 3, 4},
-  {0, 2, 3, 5},
-  {1, 2, 4, 5}
+  {0, 1, 4, 3},
+  {0, 3, 5, 2},
+  {1, 2, 5, 4}
+};
+
+int quadfaces_pyramid[1][4] = {
+  {0, 3, 2, 1}
 };
 
 QuadFace::QuadFace()
@@ -211,10 +256,10 @@ void QuadFacesContainer::AddQuadFaces(Pyramid *p)
 {
   QuadFace F, *pF;
 
-  F.V[0] = p->V[0];
-  F.V[1] = p->V[1];
-  F.V[2] = p->V[2];
-  F.V[3] = p->V[3];
+  F.V[0] = p->V[quadfaces_pyramid[0][0]];
+  F.V[1] = p->V[quadfaces_pyramid[0][1]];
+  F.V[2] = p->V[quadfaces_pyramid[0][2]];
+  F.V[3] = p->V[quadfaces_pyramid[0][3]];
   qsort(F.V, 4, sizeof(Vertex *), compareVertex);
 
   if((pF = (QuadFace *) Tree_PQuery(AllFaces, &F))) {
diff --git a/Mesh/Mesh.h b/Mesh/Mesh.h
index 487b5689e1..35bc8b95a2 100644
--- a/Mesh/Mesh.h
+++ b/Mesh/Mesh.h
@@ -257,9 +257,9 @@ struct _Surf{
   POLY_rep *thePolyRep;
   int Dirty; // flag to prevent any meshing
   DrawingColor Color;
-  VertexArray * TriVertexArray;
-  VertexArray * QuadVertexArray;
-  smooth_normals * normals;
+  VertexArray *TriVertexArray;
+  VertexArray *QuadVertexArray;
+  smooth_normals *normals;
 };
 
 typedef struct _Surf Surface;
@@ -315,6 +315,8 @@ typedef struct {
   Tree_T *Pyramids;
   int Dirty; //flag to prevent any meshing
   DrawingColor Color;
+  VertexArray *TriVertexArray;
+  VertexArray *QuadVertexArray;
 }Volume;
 
 typedef struct {
@@ -437,13 +439,13 @@ struct Map{
 
 // public functions
 
-void mai3d(Mesh * M, int Asked);
+void mai3d(Mesh *M, int Asked);
 
-void Init_Mesh(Mesh * M);
-void Create_BgMesh(int i, double d, Mesh * m);
-void Print_Geo(Mesh * M, char *c);
-void Print_Mesh(Mesh * M, char *c, int Type);
-void Read_Mesh(Mesh * M, FILE *fp, char *filename, int Type);
+void Init_Mesh(Mesh *M);
+void Create_BgMesh(int i, double d, Mesh *m);
+void Print_Geo(Mesh *M, char *c);
+void Print_Mesh(Mesh *M, char *c, int Type);
+void Read_Mesh(Mesh *M, FILE *fp, char *filename, int Type);
 void GetStatistics(double s[50]);
 
 void Maillage_Dimension_1(Mesh *M);
@@ -454,28 +456,28 @@ void Maillage_Curve(void *data, void *dummy);
 void Maillage_Surface(void *data, void *dum);
 void Maillage_Volume(void *data, void *dum);
 
-int Extrude_Mesh(Curve * c);
-int Extrude_Mesh(Surface * s);
-int Extrude_Mesh(Volume * v);
-int Extrude_Mesh(Tree_T * Volumes);
+int Extrude_Mesh(Curve *c);
+int Extrude_Mesh(Surface *s);
+int Extrude_Mesh(Volume *v);
+int Extrude_Mesh(Tree_T *Volumes);
 void ExitExtrude();
 void Extrude_Mesh_Old(Mesh *M);
 
 int MeshTransfiniteSurface(Surface *sur);
 int MeshTransfiniteVolume(Volume *vol);
-int MeshCylindricalSurface(Surface * s);
-int MeshParametricSurface(Surface * s);
-int MeshEllipticSurface(Surface * sur);
+int MeshCylindricalSurface(Surface *s);
+int MeshParametricSurface(Surface *s);
+int MeshEllipticSurface(Surface *sur);
 
-int AlgorithmeMaillage2DAnisotropeModeJF(Surface * s);
-void Maillage_Automatique_VieuxCode(Surface * pS, Mesh * m, int ori);
+int AlgorithmeMaillage2DAnisotropeModeJF(Surface *s);
+void Maillage_Automatique_VieuxCode(Surface *pS, Mesh *m, int ori);
 int Mesh_Triangle(Surface *s);
-int Mesh_Netgen(Volume * v);
-void Optimize_Netgen(Volume * v);
-void Optimize_Netgen(Mesh * m);
+int Mesh_Netgen(Volume *v);
+void Optimize_Netgen(Volume *v);
+void Optimize_Netgen(Mesh *m);
 
-int Calcule_Contours(Surface * s);
-void Link_Simplexes(List_T * Sim, Tree_T * Tim);
+int Calcule_Contours(Surface *s);
+void Link_Simplexes(List_T *Sim, Tree_T *Tim);
 void Calcule_Z(void *data, void *dum);
 void Calcule_Z_Plan(void *data, void *dum);
 void Projette_Plan_Moyen(void *a, void *b);
@@ -484,23 +486,23 @@ void Freeze_Vertex(void *a, void *b);
 void deFreeze_Vertex(void *a, void *b);
 void ReOrientSurfaceMesh(Surface *s);
 
-double Lc_XYZ(double X, double Y, double Z, Mesh * m);
+double Lc_XYZ(double X, double Y, double Z, Mesh *m);
 void ActionLiss(void *data, void *dummy);
 void ActionLissSurf(void *data, void *dummy);
 int Recombine(Tree_T *TreeAllVert, Tree_T *TreeAllSimp, Tree_T *TreeAllQuad,
 		double a);
 void ApplyLcFactor(Mesh *M);
-void ExportLcFieldOnVolume(Mesh * M, char *filename);
-void ExportLcFieldOnSurfaces(Mesh * M, char *filename);
+void ExportLcFieldOnVolume(Mesh *M, char *filename);
+void ExportLcFieldOnSurfaces(Mesh *M, char *filename);
 
 void Degre1();
 void Degre2(int dim);
 void Degre2_Curve(void *a, void *b);
 void Degre2_Surface(void *a, void *b);
 
-void Gamma_Maillage(Mesh * m, double *gamma, double *gammamax, double *gammamin);
-void Eta_Maillage(Mesh * m, double *gamma, double *gammamax, double *gammamin);
-void R_Maillage(Mesh * m, double *gamma, double *gammamax, double *gammamin);
+void Gamma_Maillage(Mesh *m, double *gamma, double *gammamax, double *gammamin);
+void Eta_Maillage(Mesh *m, double *gamma, double *gammamax, double *gammamin);
+void R_Maillage(Mesh *m, double *gamma, double *gammamax, double *gammamin);
 void Mesh_Quality(Mesh *m);
 void Print_Histogram(int *h);
 
diff --git a/Mesh/SecondOrder.cpp b/Mesh/SecondOrder.cpp
index 1c88b4238f..4e7cff9e72 100644
--- a/Mesh/SecondOrder.cpp
+++ b/Mesh/SecondOrder.cpp
@@ -1,4 +1,4 @@
-// $Id: SecondOrder.cpp,v 1.26 2004-05-27 06:23:48 geuzaine Exp $
+// $Id: SecondOrder.cpp,v 1.27 2004-08-12 16:57:32 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -36,6 +36,7 @@ extern int edges_pyramid[8][2];
 
 extern int quadfaces_hexa[6][4];
 extern int quadfaces_prism[3][4];
+extern int quadfaces_pyramid[1][4];
 
 static Surface *THES = NULL;
 static Curve *THEC = NULL;
@@ -325,10 +326,10 @@ void putMiddleFacePoint(void *a, void *b)
 
   for(int i = 0; i < 2; i++) {
     if(fac->pyramid[i] && fac->pyramid[i]->VSUP){
-      F.V[0] = fac->pyramid[i]->V[0];
-      F.V[1] = fac->pyramid[i]->V[1];
-      F.V[2] = fac->pyramid[i]->V[2];
-      F.V[3] = fac->pyramid[i]->V[3];
+      F.V[0] = fac->pyramid[i]->V[quadfaces_pyramid[0][0]];
+      F.V[1] = fac->pyramid[i]->V[quadfaces_pyramid[0][1]];
+      F.V[2] = fac->pyramid[i]->V[quadfaces_pyramid[0][2]];
+      F.V[3] = fac->pyramid[i]->V[quadfaces_pyramid[0][3]];
       qsort(F.V, 4, sizeof(Vertex *), compareVertex);
       if(!compareQuadFace(fac, &F))
 	fac->pyramid[i]->VSUP[8] = v;
-- 
GitLab