From d2e4a16b3c51b6fcefa3b44665a6cb3ee18a5743 Mon Sep 17 00:00:00 2001
From: Christophe Geuzaine <cgeuzaine@ulg.ac.be>
Date: Tue, 15 Aug 2006 02:17:27 +0000
Subject: [PATCH] *** empty log message ***

---
 Common/Makefile          |  38 ++--
 Common/Options.cpp       |  20 +-
 Common/VertexArray.cpp   |  14 +-
 Common/VertexArray.h     |   6 +-
 Fltk/GUI.cpp             |   6 +-
 Fltk/Makefile            |  16 +-
 Geo/GEntity.cpp          |   6 +
 Geo/GEntity.h            |  10 +-
 Geo/GModel.cpp           |  20 +-
 Geo/GModel.h             |   8 +-
 Geo/GRegion.cpp          |   1 +
 Geo/MEdge.h              |  52 +++++
 Geo/MElement.cpp         |  27 ++-
 Geo/MElement.h           | 168 ++++++--------
 Geo/MFace.h              |  28 +++
 Geo/MRep.h               |  87 +++++++
 Geo/Makefile             | 129 ++++++-----
 Graphics/Geom.cpp        |  22 +-
 Graphics/Iso.cpp         |   4 +-
 Graphics/Makefile        |  43 ++--
 Graphics/Mesh.cpp        | 477 +++++++++++++++++++++++++++------------
 Graphics/Post.cpp        |  14 +-
 Graphics/PostElement.cpp |   5 +-
 Mesh/Makefile            |  49 ++--
 Parser/Makefile          |  53 +++--
 25 files changed, 839 insertions(+), 464 deletions(-)
 create mode 100644 Geo/MEdge.h
 create mode 100644 Geo/MFace.h
 create mode 100644 Geo/MRep.h

diff --git a/Common/Makefile b/Common/Makefile
index 03311fdce4..9c5c3ab108 100644
--- a/Common/Makefile
+++ b/Common/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.102 2006-08-12 19:34:14 geuzaine Exp $
+# $Id: Makefile,v 1.103 2006-08-15 02:17:25 geuzaine Exp $
 #
 # Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 #
@@ -122,14 +122,15 @@ CommandLine.o: CommandLine.cpp Gmsh.h Message.h ../DataStr/Malloc.h \
   GmshMatrix.h AdaptiveViews.h ../Parser/OpenFile.h \
   ../Parser/CreateFile.h ../Parser/Parser.h ../Geo/GModel.h \
   ../Geo/GVertex.h ../Geo/GEntity.h ../Geo/Range.h ../Geo/SPoint3.h \
-  ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../Geo/MVertex.h \
-  ../Geo/SPoint3.h ../Common/GmshDefines.h ../Geo/MVertex.h \
-  ../Geo/GPoint.h ../Geo/GEdge.h ../Geo/GEntity.h ../Geo/GVertex.h \
-  ../Geo/SVector3.h ../Geo/SPoint3.h ../Geo/SPoint3.h ../Geo/SPoint2.h \
-  ../Geo/MElement.h ../Geo/MVertex.h ../Geo/GFace.h ../Geo/GPoint.h \
-  ../Geo/GEntity.h ../Geo/MElement.h ../Geo/SPoint2.h ../Geo/SVector3.h \
-  ../Geo/Pair.h ../Geo/GRegion.h ../Geo/GEntity.h ../Geo/MElement.h \
-  ../Geo/SBoundingBox3d.h OS.h
+  ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../Common/GmshDefines.h \
+  ../Geo/MVertex.h ../Geo/SPoint3.h ../Geo/GPoint.h ../Geo/GEdge.h \
+  ../Geo/GEntity.h ../Geo/GVertex.h ../Geo/SVector3.h ../Geo/SPoint3.h \
+  ../Geo/SPoint3.h ../Geo/SPoint2.h ../Geo/MElement.h ../Geo/MVertex.h \
+  ../Geo/MEdge.h ../Geo/MVertex.h ../Geo/MFace.h ../Geo/MVertex.h \
+  ../Geo/SVector3.h ../Geo/GFace.h ../Geo/GPoint.h ../Geo/GEntity.h \
+  ../Geo/MElement.h ../Geo/SPoint2.h ../Geo/SVector3.h ../Geo/Pair.h \
+  ../Geo/GRegion.h ../Geo/GEntity.h ../Geo/MElement.h \
+  ../Geo/SBoundingBox3d.h ../Common/SmoothNormals.h OS.h
 # 1 "/Users/geuzaine/.gmsh/Common//"
 OS.o: OS.cpp Message.h
 # 1 "/Users/geuzaine/.gmsh/Common//"
@@ -140,15 +141,16 @@ ColorTable.o: ColorTable.cpp Gmsh.h Message.h ../DataStr/Malloc.h \
 # 1 "/Users/geuzaine/.gmsh/Common//"
 Visibility.o: Visibility.cpp Visibility.h GmshDefines.h ../Geo/GVertex.h \
   ../Geo/GEntity.h ../Geo/Range.h ../Geo/SPoint3.h \
-  ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../Geo/MVertex.h \
-  ../Geo/SPoint3.h ../Common/GmshDefines.h ../Geo/MVertex.h \
-  ../Geo/GPoint.h ../Geo/GEdge.h ../Geo/GEntity.h ../Geo/GVertex.h \
-  ../Geo/SVector3.h ../Geo/SPoint3.h ../Geo/SPoint3.h ../Geo/SPoint2.h \
-  ../Geo/MElement.h ../Geo/MVertex.h ../Numeric/Numeric.h ../Geo/GFace.h \
-  ../Geo/GPoint.h ../Geo/GEntity.h ../Geo/MElement.h ../Geo/SPoint2.h \
-  ../Geo/SVector3.h ../Geo/Pair.h ../Geo/GRegion.h ../Geo/GEntity.h \
-  ../Geo/MElement.h ../Geo/GModel.h ../Geo/GVertex.h ../Geo/GEdge.h \
-  ../Geo/GFace.h ../Geo/GRegion.h ../Geo/SBoundingBox3d.h \
+  ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../Common/GmshDefines.h \
+  ../Geo/MVertex.h ../Geo/SPoint3.h ../Geo/GPoint.h ../Geo/GEdge.h \
+  ../Geo/GEntity.h ../Geo/GVertex.h ../Geo/SVector3.h ../Geo/SPoint3.h \
+  ../Geo/SPoint3.h ../Geo/SPoint2.h ../Geo/MElement.h ../Geo/MVertex.h \
+  ../Geo/MEdge.h ../Geo/MVertex.h ../Geo/MFace.h ../Geo/MVertex.h \
+  ../Geo/SVector3.h ../Numeric/Numeric.h ../Geo/GFace.h ../Geo/GPoint.h \
+  ../Geo/GEntity.h ../Geo/MElement.h ../Geo/SPoint2.h ../Geo/SVector3.h \
+  ../Geo/Pair.h ../Geo/GRegion.h ../Geo/GEntity.h ../Geo/MElement.h \
+  ../Geo/GModel.h ../Geo/GVertex.h ../Geo/GEdge.h ../Geo/GFace.h \
+  ../Geo/GRegion.h ../Geo/SBoundingBox3d.h ../Common/SmoothNormals.h \
   ../Parser/Parser.h ../DataStr/List.h ../DataStr/Tree.h ../DataStr/avl.h
 # 1 "/Users/geuzaine/.gmsh/Common//"
 Trackball.o: Trackball.cpp Trackball.h
diff --git a/Common/Options.cpp b/Common/Options.cpp
index 3744e4d199..d4a01a0782 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -1,4 +1,4 @@
-// $Id: Options.cpp,v 1.288 2006-08-12 19:34:14 geuzaine Exp $
+// $Id: Options.cpp,v 1.289 2006-08-15 02:17:25 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -4829,7 +4829,10 @@ double opt_mesh_save_all(OPT_ARGS_NUM)
 double opt_mesh_color_carousel(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    if(CTX.mesh.color_carousel != (int)val) CTX.mesh.changed = 1;
+    // vertex arrays need to be regenerated only when we color by
+    // partition
+    if(CTX.mesh.color_carousel != (int)val && val == 3.)
+      CTX.mesh.changed = 1;
     CTX.mesh.color_carousel = (int)val;
     if(CTX.mesh.color_carousel < 0 || CTX.mesh.color_carousel > 3)
       CTX.mesh.color_carousel = 0;
@@ -6974,7 +6977,6 @@ unsigned int opt_geometry_color_points_select(OPT_ARGS_COL)
 unsigned int opt_geometry_color_lines_select(OPT_ARGS_COL)
 {
   if(action & GMSH_SET){
-    if(CTX.color.geom.line_sel != val) CTX.mesh.changed = 1;
     CTX.color.geom.line_sel = val;
   }
 #if defined(HAVE_FLTK)
@@ -6986,7 +6988,6 @@ unsigned int opt_geometry_color_lines_select(OPT_ARGS_COL)
 unsigned int opt_geometry_color_surfaces_select(OPT_ARGS_COL)
 {
   if(action & GMSH_SET){
-    if(CTX.color.geom.surface_sel != val) CTX.mesh.changed = 1;
     CTX.color.geom.surface_sel = val;
   }
 #if defined(HAVE_FLTK)
@@ -7061,7 +7062,6 @@ unsigned int opt_mesh_color_lines(OPT_ARGS_COL)
 unsigned int opt_mesh_color_triangles(OPT_ARGS_COL)
 {
   if(action & GMSH_SET) {
-    if(CTX.color.mesh.triangle != val) CTX.mesh.changed = 1;
     CTX.color.mesh.triangle = val;
   }
 #if defined(HAVE_FLTK)
@@ -7073,7 +7073,6 @@ unsigned int opt_mesh_color_triangles(OPT_ARGS_COL)
 unsigned int opt_mesh_color_quadrangles(OPT_ARGS_COL)
 {
   if(action & GMSH_SET) {
-    if(CTX.color.mesh.quadrangle != val) CTX.mesh.changed = 1;
     CTX.color.mesh.quadrangle = val;
   }
 #if defined(HAVE_FLTK)
@@ -7085,7 +7084,6 @@ unsigned int opt_mesh_color_quadrangles(OPT_ARGS_COL)
 unsigned int opt_mesh_color_tetrahedra(OPT_ARGS_COL)
 {
   if(action & GMSH_SET) {
-    if(CTX.color.mesh.tetrahedron != val) CTX.mesh.changed = 1;
     CTX.color.mesh.tetrahedron = val;
   }
 #if defined(HAVE_FLTK)
@@ -7097,7 +7095,6 @@ unsigned int opt_mesh_color_tetrahedra(OPT_ARGS_COL)
 unsigned int opt_mesh_color_hexahedra(OPT_ARGS_COL)
 {
   if(action & GMSH_SET) {
-    if(CTX.color.mesh.hexahedron != val) CTX.mesh.changed = 1;
     CTX.color.mesh.hexahedron = val;
   }
 #if defined(HAVE_FLTK)
@@ -7109,7 +7106,6 @@ unsigned int opt_mesh_color_hexahedra(OPT_ARGS_COL)
 unsigned int opt_mesh_color_prisms(OPT_ARGS_COL)
 {
   if(action & GMSH_SET) {
-    if(CTX.color.mesh.prism != val) CTX.mesh.changed = 1;
     CTX.color.mesh.prism = val;
   }
 #if defined(HAVE_FLTK)
@@ -7121,7 +7117,6 @@ unsigned int opt_mesh_color_prisms(OPT_ARGS_COL)
 unsigned int opt_mesh_color_pyramid(OPT_ARGS_COL)
 {
   if(action & GMSH_SET) {
-    if(CTX.color.mesh.pyramid != val) CTX.mesh.changed = 1;
     CTX.color.mesh.pyramid = val;
   }
 #if defined(HAVE_FLTK)
@@ -7155,7 +7150,10 @@ unsigned int opt_mesh_color_normals(OPT_ARGS_COL)
 unsigned int opt_mesh_color_(int i, OPT_ARGS_COL)
 {
   if(action & GMSH_SET) {
-    if(CTX.color.mesh.carousel[i] != val) CTX.mesh.changed = 1;
+    // vertex arrays need to be regenerated only when we color by
+    // partition
+    if(CTX.color.mesh.carousel[i] != val && CTX.mesh.color_carousel == 3)
+      CTX.mesh.changed = 1;
     CTX.color.mesh.carousel[i] = val;
   }
 #if defined(HAVE_FLTK)
diff --git a/Common/VertexArray.cpp b/Common/VertexArray.cpp
index 7acb239980..d08dfb8773 100644
--- a/Common/VertexArray.cpp
+++ b/Common/VertexArray.cpp
@@ -1,4 +1,4 @@
-// $Id: VertexArray.cpp,v 1.10 2006-01-06 00:34:21 geuzaine Exp $
+// $Id: VertexArray.cpp,v 1.11 2006-08-15 02:17:25 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -33,7 +33,7 @@ VertexArray::VertexArray(int numNodesPerElement, int numElements)
     Msg(GERROR, "Vertex arrays not done for %d-node element", type);
     type = 3;
   }
-  num = fill = 0;
+  fill = 0;
   if(!numElements)
     numElements = 1;
   int nb = numElements * numNodesPerElement;
@@ -49,6 +49,11 @@ VertexArray::~VertexArray()
   List_Delete(colors);
 }
 
+int VertexArray::n()
+{
+  return List_Nbr(vertices) / 3;
+}
+
 void VertexArray::add(float x, float y, float z, 
 		      float n0, float n1, float n2, unsigned int col)
 {
@@ -115,10 +120,13 @@ void VertexArray::sort(double eye[3])
     return;
   }
 
+  // FIXME this assumes that the color and normals are always filled!
+
   theeye[0] = eye[0];
   theeye[1] = eye[1];
   theeye[2] = eye[2];
-  
+
+  int num = n() / 3;
   int nb = List_Nbr(vertices) + List_Nbr(normals) + List_Nbr(colors);
   float *tmp = new float[nb];
   
diff --git a/Common/VertexArray.h b/Common/VertexArray.h
index 7ee16f1748..f53b030fab 100644
--- a/Common/VertexArray.h
+++ b/Common/VertexArray.h
@@ -24,13 +24,17 @@
 
 class VertexArray{
  public:
-  int type, num, fill;
+  int type, fill;
   List_T *vertices, *normals, *colors;
   VertexArray(int numNodesPerElement, int numElements);
   ~VertexArray();
+  // return the number of nodes in the array
+  int n();
+  // add a node in the array
   void add(float x, float y, float z, 
 	   float n0, float n1, float n2, unsigned int col);
   void add(float x, float y, float z, unsigned int col);
+  // sort the elements back to fron wrt the eye position
   void sort(double eye[3]);
 };
 
diff --git a/Fltk/GUI.cpp b/Fltk/GUI.cpp
index 94272c8b37..20b712e9b1 100644
--- a/Fltk/GUI.cpp
+++ b/Fltk/GUI.cpp
@@ -1,4 +1,4 @@
-// $Id: GUI.cpp,v 1.513 2006-08-13 21:41:04 geuzaine Exp $
+// $Id: GUI.cpp,v 1.514 2006-08-15 02:17:25 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -1349,7 +1349,7 @@ void GUI::create_graphic_window()
   // bottom button bar
 
   Fl_Box *bottom = new Fl_Box(0, glheight, width, sh);
-  bottom->box(FL_THIN_UP_BOX);
+  bottom->box(FL_FLAT_BOX);
 
   int x = 2;
 
@@ -1422,7 +1422,7 @@ void GUI::create_graphic_window()
 
   x += 2;
   g_status_label[0] = new Fl_Box(x, glheight + 2, 
-				 (width - x - 1) / 3, sh - 4);
+				 (width - x - 2) / 3, sh - 4);
   g_status_label[1] = new Fl_Box(x + (width - x) / 3, glheight + 2, 
 				 2 * (width - x - 1) / 3, sh - 4);
   for(int i = 0; i < 2; i++) {
diff --git a/Fltk/Makefile b/Fltk/Makefile
index 6bc985f401..4122be2152 100644
--- a/Fltk/Makefile
+++ b/Fltk/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.99 2006-08-12 19:47:57 geuzaine Exp $
+# $Id: Makefile,v 1.100 2006-08-15 02:17:25 geuzaine Exp $
 #
 # Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 #
@@ -84,9 +84,10 @@ Main.o: Main.cpp GUI.h Opengl_Window.h ../Mesh/Mesh.h \
   ../Plugin/Plugin.h ../Geo/gmshModel.h ../Geo/GModel.h ../Geo/GVertex.h \
   ../Geo/GEntity.h ../Geo/Range.h ../Geo/SPoint3.h \
   ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../Geo/MVertex.h \
-  ../Geo/SPoint3.h ../Geo/MVertex.h ../Geo/GPoint.h ../Geo/GEdge.h \
-  ../Geo/GEntity.h ../Geo/GVertex.h ../Geo/SVector3.h ../Geo/SPoint3.h \
-  ../Geo/SPoint3.h ../Geo/SPoint2.h ../Geo/MElement.h ../Geo/MVertex.h \
+  ../Geo/SPoint3.h ../Geo/GPoint.h ../Geo/GEdge.h ../Geo/GEntity.h \
+  ../Geo/GVertex.h ../Geo/SVector3.h ../Geo/SPoint3.h ../Geo/SPoint3.h \
+  ../Geo/SPoint2.h ../Geo/MElement.h ../Geo/MVertex.h ../Geo/MEdge.h \
+  ../Geo/MVertex.h ../Geo/MFace.h ../Geo/MVertex.h ../Geo/SVector3.h \
   ../Geo/GFace.h ../Geo/GPoint.h ../Geo/GEntity.h ../Geo/MElement.h \
   ../Geo/SPoint2.h ../Geo/SVector3.h ../Geo/Pair.h ../Geo/GRegion.h \
   ../Geo/GEntity.h ../Geo/MElement.h ../Geo/SBoundingBox3d.h
@@ -155,9 +156,10 @@ Callbacks.o: Callbacks.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../Common/Visibility.h ../Common/GmshDefines.h ../Geo/GVertex.h \
   ../Geo/GEntity.h ../Geo/Range.h ../Geo/SPoint3.h \
   ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../Geo/MVertex.h \
-  ../Geo/SPoint3.h ../Geo/MVertex.h ../Geo/GPoint.h ../Geo/GEdge.h \
-  ../Geo/GEntity.h ../Geo/GVertex.h ../Geo/SVector3.h ../Geo/SPoint3.h \
-  ../Geo/SPoint3.h ../Geo/SPoint2.h ../Geo/MElement.h ../Geo/MVertex.h \
+  ../Geo/SPoint3.h ../Geo/GPoint.h ../Geo/GEdge.h ../Geo/GEntity.h \
+  ../Geo/GVertex.h ../Geo/SVector3.h ../Geo/SPoint3.h ../Geo/SPoint3.h \
+  ../Geo/SPoint2.h ../Geo/MElement.h ../Geo/MVertex.h ../Geo/MEdge.h \
+  ../Geo/MVertex.h ../Geo/MFace.h ../Geo/MVertex.h ../Geo/SVector3.h \
   ../Geo/GFace.h ../Geo/GPoint.h ../Geo/GEntity.h ../Geo/MElement.h \
   ../Geo/SPoint2.h ../Geo/SVector3.h ../Geo/Pair.h ../Geo/GRegion.h \
   ../Geo/GEntity.h ../Geo/MElement.h Solvers.h ../Common/OS.h \
diff --git a/Geo/GEntity.cpp b/Geo/GEntity.cpp
index c0265dcc52..4576f57a59 100644
--- a/Geo/GEntity.cpp
+++ b/Geo/GEntity.cpp
@@ -1,4 +1,10 @@
 #include "GEntity.h"
+#include "MRep.h"
+
+GEntity::~GEntity()
+{
+  if(meshRep) delete meshRep; 
+}
 
 std::string GEntity::getInfoString()
 {
diff --git a/Geo/GEntity.h b/Geo/GEntity.h
index 9c3d482fce..b138a14a63 100644
--- a/Geo/GEntity.h
+++ b/Geo/GEntity.h
@@ -4,7 +4,6 @@
 #include "Range.h"
 #include "SPoint3.h"
 #include "SBoundingBox3d.h"
-#include "MVertex.h"
 #include "GmshDefines.h"
 #include <list>
 #include <vector>
@@ -15,6 +14,7 @@ class GVertex;
 class GEdge;
 class GFace;
 class GRegion;
+class MVertex;
 class MRep;
 
 // A geometric model entity. All enitites are owned by a GModel.
@@ -22,7 +22,6 @@ class GEntity {
 
  private:
   GModel *_model;
-  MRep *_mrep;
   int _tag;
   char _visible, _flag;
   
@@ -80,9 +79,9 @@ class GEntity {
       return name[type];
   }
 
-  GEntity(GModel *m, int t) : _model(m), _mrep(0), _tag(t), _visible(true), _flag(0) {}
+  GEntity(GModel *m, int t) : _model(m), _tag(t), _visible(true), _flag(0), meshRep(0) {}
 
-  virtual ~GEntity() {};
+  virtual ~GEntity();
 
   // Spatial dimension of the entity 
   virtual int dim() const {throw;}
@@ -158,6 +157,9 @@ class GEntity {
 
   // The physical entitites (if any) that contain this entity
   std::vector<int> physicals;
+
+  // A representation of the mesh
+  MRep *meshRep;
 };
 
 class GEntityLessThan {
diff --git a/Geo/GModel.cpp b/Geo/GModel.cpp
index 3159750e89..76c6aa3707 100644
--- a/Geo/GModel.cpp
+++ b/Geo/GModel.cpp
@@ -1,5 +1,19 @@
 #include "GModel.h"
 
+GModel::~GModel()
+{ 
+  for(riter it = firstRegion(); it != lastRegion(); ++it)
+    delete *it;
+  for(fiter it = firstFace(); it != lastFace(); ++it)
+    delete *it;
+  for(eiter it = firstEdge(); it != lastEdge(); ++it)
+    delete *it;
+  for(viter it = firstVertex(); it != lastVertex(); ++it)
+    delete *it;
+
+  delete normals; 
+}
+
 GRegion * GModel::regionByTag(int n) const
 {
   GEntity tmp((GModel*)this, n);
@@ -46,13 +60,13 @@ int GModel::renumberMeshVertices()
   for(viter it = firstVertex(); it != lastVertex(); ++it)
     for(unsigned int i = 0; i < (*it)->mesh_vertices.size(); i++) 
       (*it)->mesh_vertices[i]->setNum(++numVertices);
-  for(GModel::eiter it = firstEdge(); it != lastEdge(); ++it)
+  for(eiter it = firstEdge(); it != lastEdge(); ++it)
     for(unsigned int i = 0; i < (*it)->mesh_vertices.size(); i++) 
       (*it)->mesh_vertices[i]->setNum(++numVertices);
-  for(GModel::fiter it = firstFace(); it != lastFace(); ++it)
+  for(fiter it = firstFace(); it != lastFace(); ++it)
     for(unsigned int i = 0; i < (*it)->mesh_vertices.size(); i++) 
       (*it)->mesh_vertices[i]->setNum(++numVertices);
-  for(GModel::riter it = firstRegion(); it != lastRegion(); ++it)
+  for(riter it = firstRegion(); it != lastRegion(); ++it)
     for(unsigned int i = 0; i < (*it)->mesh_vertices.size(); i++) 
       (*it)->mesh_vertices[i]->setNum(++numVertices);
   return numVertices;
diff --git a/Geo/GModel.h b/Geo/GModel.h
index 8e1eec73a0..64df467d9e 100644
--- a/Geo/GModel.h
+++ b/Geo/GModel.h
@@ -9,6 +9,7 @@
 #include "GFace.h"
 #include "GRegion.h"
 #include "SBoundingBox3d.h"
+#include "SmoothNormals.h"
 
 // A geometric model. The model is a non-manifold B-Rep.
 
@@ -23,8 +24,8 @@ class GModel
   std::set<int> meshPartitions;
 
  public:
-  GModel(const std::string &name) : modelName(name) {}
-  virtual ~GModel() {}
+  GModel(const std::string &name) : modelName(name), normals(0) {}
+  virtual ~GModel();
 
   virtual void import(){}
 
@@ -98,6 +99,9 @@ class GModel
   int writeUNV(const std::string &name, double scalingFactor=1.0);
   int readMESH(const std::string &name);
   int writeMESH(const std::string &name, double scalingFactor=1.0);
+
+  // FIXME: this will be removed (and rewritten)
+  smooth_normals *normals;
 };
 
 #endif
diff --git a/Geo/GRegion.cpp b/Geo/GRegion.cpp
index 6b8dccc41f..9749754fd0 100644
--- a/Geo/GRegion.cpp
+++ b/Geo/GRegion.cpp
@@ -74,3 +74,4 @@ void GRegion::recomputeMeshPartitions()
     if(part) model()->getMeshPartitions().insert(part);
   }
 }
+
diff --git a/Geo/MEdge.h b/Geo/MEdge.h
new file mode 100644
index 0000000000..af509e2930
--- /dev/null
+++ b/Geo/MEdge.h
@@ -0,0 +1,52 @@
+#ifndef _MEDGE_H_
+#define _MEDGE_H_
+
+#include <algorithm>
+#include "MVertex.h"
+
+class MElement;
+
+class MEdge {
+ private:
+  MVertex *_v[2];
+  
+  // Storing a pointer to (one of the) originating elements is a
+  // significant overhead, especially since I only use it to get a
+  // crude normal (for graphic purposes) or to know (one of) the
+  // adjacent mesh partitions. I will try to come up with something
+  // better later.
+  MElement *_element;
+  
+ public:
+  MEdge(MVertex *v0, MVertex *v1, MElement *e) 
+    : _element(e)
+  {
+    _v[0] = v0; _v[1] = v1;
+  }
+  inline MVertex *getVertex(int i) const { return _v[i]; }
+  inline MElement *getElement() const { return _element; }
+};
+
+class MEdgeLessThan {
+ public:
+  bool operator()(const MEdge &e1, const MEdge &e2) const
+  {
+    int e10 = e1.getVertex(0)->getNum();
+    int e11 = e1.getVertex(1)->getNum();
+    int e20 = e2.getVertex(0)->getNum();
+    int e21 = e2.getVertex(1)->getNum();
+    int i1 = std::min(e10, e11);
+    int i2 = std::min(e20, e21);
+    if(i1 < i2)
+      return true;
+    if(i1 > i2)
+      return false;
+    int j1 = std::max(e10, e11);
+    int j2 = std::max(e20, e21);
+    if(j1 < j2)
+      return true;
+    return false;
+  }
+};
+
+#endif
diff --git a/Geo/MElement.cpp b/Geo/MElement.cpp
index ca430e0407..4451fe8cc2 100644
--- a/Geo/MElement.cpp
+++ b/Geo/MElement.cpp
@@ -16,10 +16,9 @@ static double dist(MVertex *v1, MVertex *v2)
 double MElement::minEdge()
 {
   double m = 1.e25;
-  MVertex *v[2];
   for(int i = 0; i < getNumEdges(); i++){
-    getEdge(i, v);
-    m = std::min(m, dist(v[0], v[1]));
+    MEdge e = getEdge(i);
+    m = std::min(m, dist(e.getVertex(0), e.getVertex(1)));
   }
   return m;
 }
@@ -27,10 +26,9 @@ double MElement::minEdge()
 double MElement::maxEdge()
 {
   double m = 0.;
-  MVertex *v[2];
   for(int i = 0; i < getNumEdges(); i++){
-    getEdge(i, v);
-    m = std::max(m, dist(v[0], v[1]));
+    MEdge e = getEdge(i);
+    m = std::max(m, dist(e.getVertex(0), e.getVertex(1)));
   }
   return m;
 }
@@ -72,19 +70,20 @@ double MTetrahedron::etaShapeMeasure()
   return 12. * pow(0.9 * v * v, 1./3.) / lij2;
 }
 
-void MElement::cog(double &x, double &y, double &z)
+SPoint3 MElement::barycenter()
 {
-  x = y = z = 0.;
+  SPoint3 p(0., 0., 0.);
   int n = getNumVertices();
   for(int i = 0; i < n; i++) {
     MVertex *v = getVertex(i);
-    x += v->x();
-    y += v->y();
-    z += v->z();
+    p[0] += v->x();
+    p[1] += v->y();
+    p[2] += v->z();
   }
-  x /= (double)n;
-  y /= (double)n;
-  z /= (double)n;
+  p[0] /= (double)n;
+  p[1] /= (double)n;
+  p[2] /= (double)n;
+  return p;
 }
 
 void MElement::writeMSH(FILE *fp, double version, int num, int elementary, 
diff --git a/Geo/MElement.h b/Geo/MElement.h
index 553ed5d6b2..6c7ee7724b 100644
--- a/Geo/MElement.h
+++ b/Geo/MElement.h
@@ -5,6 +5,8 @@
 #include <algorithm>
 #include "GmshDefines.h"
 #include "MVertex.h"
+#include "MEdge.h"
+#include "MFace.h"
 #include "Numeric.h"
 
 // the reference topology is defined in Mesh/{Edge,Face}.cpp
@@ -66,25 +68,19 @@ class MElement
 
   // get the edges
   virtual int getNumEdges() = 0;
-  virtual void getEdge(int num, MVertex *v[2]) = 0;
+  virtual MEdge getEdge(int num) = 0;
 
   // get an edge representation for drawing
   virtual int getNumEdgesRep(){ return getNumEdges(); }
-  virtual void getEdgeRep(int num, MVertex *v[2]){ getEdgeRep(num, v); }
+  virtual MEdge getEdgeRep(int num){ return getEdge(num); }
 
   // get the faces
   virtual int getNumFaces() = 0;
-  virtual void getFace(int num, MVertex *v[4]) = 0;
+  virtual MFace getFace(int num) = 0;
 
   // get a face representation for drawing
   virtual int getNumFacesRep(){ return getNumFaces(); }
-  virtual void getFaceRep(int num, MVertex *v[4], double n[3]=0)
-  { 
-    getFace(num, v); 
-    if(n) normal3points(v[0]->x(), v[0]->y(), v[0]->y(),
-			v[1]->x(), v[1]->y(), v[1]->y(),
-			v[2]->x(), v[2]->y(), v[2]->y(), n);
-  }
+  virtual MFace getFaceRep(int num){ return getFace(num); }
 
   // get the max/min edge length
   virtual double maxEdge();
@@ -96,7 +92,7 @@ class MElement
   virtual double etaShapeMeasure(){ return 0.; }
 
   // computes the barycenter
-  virtual void cog(double &x, double &y, double &z);
+  virtual SPoint3 barycenter();
 
   // compute and change the orientation of 3D elements to get
   // positive volume
@@ -131,15 +127,9 @@ class MLine : public MElement {
   inline int getNumVertices(){ return 2; }
   inline MVertex *getVertex(int num){ return _v[num]; }
   virtual int getNumEdges(){ return 1; }
-  virtual void getEdge(int num, MVertex *v[2])
-  {
-    v[0] = _v[0]; v[1] = _v[1];
-  }
+  virtual MEdge getEdge(int num){ return MEdge(_v[0], _v[1], this); }
   virtual int getNumFaces(){ return 0; }
-  virtual void getFace(int num, MVertex *v[4]) 
-  { 
-    v[0] = v[1] = v[2] = v[3] = 0; 
-  }
+  virtual MFace getFace(int num){ throw; }
   int getTypeForMSH(){ return LGN1; }
   int getTypeForUNV(){ return 21; } // BEAM
   char *getStringForPOS(){ return "SL"; }
@@ -160,15 +150,14 @@ class MLine2 : public MLine {
   inline MVertex *getVertex(int num){ return num < 2 ? _v[num] : _vs[num - 2]; }
   inline int getNumEdgeVertices(){ return 1; }
   int getNumEdgesRep(){ return 2; }
-  void getEdgeRep(int num, MVertex *v[2])
+  MEdge getEdgeRep(int num)
   { 
     static int edges_lin2[2][2] = {
       {0, 2}, {2, 1},
     };
     int i0 = edges_lin2[num][0];
     int i1 = edges_lin2[num][1];
-    v[0] = i0 < 2? _v[i0] : _vs[i0 - 2];
-    v[1] = i1 < 2? _v[i1] : _vs[i1 - 2];
+    return MEdge(i0 < 2 ? _v[i0] : _vs[i0 - 2], i1 < 2 ? _v[i1] : _vs[i1 - 2], this);
   }
   int getTypeForMSH(){ return LGN2; }
   int getTypeForUNV(){ return 24; } // BEAM2
@@ -188,15 +177,14 @@ class MTriangle : public MElement {
   inline int getNumVertices(){ return 3; }
   inline MVertex *getVertex(int num){ return _v[num]; }
   virtual int getNumEdges(){ return 3; }
-  virtual void getEdge(int num, MVertex *v[2])
+  virtual MEdge getEdge(int num)
   {
-    v[0] = _v[edges_tetra[num][0]];
-    v[1] = _v[edges_tetra[num][1]];
+    return MEdge(_v[edges_tetra[num][0]], _v[edges_tetra[num][1]], this);
   }
   virtual int getNumFaces(){ return 1; }
-  virtual void getFace(int num, MVertex *v[4])
-  {
-    v[0] = _v[0]; v[1] = _v[1]; v[2] = _v[2]; v[3] = 0;
+  virtual MFace getFace(int num)
+  { 
+    return MFace(_v[0], _v[1], _v[2]); 
   }
   int getTypeForMSH(){ return TRI1; }
   int getTypeForUNV(){ return 91; } // THINSHLL
@@ -219,7 +207,7 @@ class MTriangle2 : public MTriangle {
   inline MVertex *getVertex(int num){ return num < 3 ? _v[num] : _vs[num - 3]; }
   inline int getNumEdgeVertices(){ return 3; }
   int getNumEdgesRep(){ return 6; }
-  void getEdgeRep(int num, MVertex *v[2])
+  MEdge getEdgeRep(int num)
   { 
     static int edges_tri2[6][2] = {
       {0, 3}, {3, 1},
@@ -228,11 +216,10 @@ class MTriangle2 : public MTriangle {
     };
     int i0 = edges_tri2[num][0];
     int i1 = edges_tri2[num][1];
-    v[0] = i0 < 3? _v[i0] : _vs[i0 - 3];
-    v[1] = i1 < 3? _v[i1] : _vs[i1 - 3];
+    return MEdge(i0 < 3 ? _v[i0] : _vs[i0 - 3], i1 < 3 ? _v[i1] : _vs[i1 - 3], this);
   }
   int getNumFacesRep(){ return 4; }
-  void getFaceRep(int num, MVertex *v[4], double n[3]=0)
+  MFace getFaceRep(int num)
   { 
     static int trifaces_tri2[4][3] = {
       {0, 3, 5},
@@ -243,13 +230,9 @@ class MTriangle2 : public MTriangle {
     int i0 = trifaces_tri2[num][0];
     int i1 = trifaces_tri2[num][1];
     int i2 = trifaces_tri2[num][2];
-    v[0] = i0 < 3? _v[i0] : _vs[i0 - 3];
-    v[1] = i1 < 3? _v[i1] : _vs[i1 - 3];
-    v[2] = i2 < 3? _v[i2] : _vs[i2 - 3];
-    v[3] = 0;
-    if(n) normal3points(v[0]->x(), v[0]->y(), v[0]->y(),
-			v[1]->x(), v[1]->y(), v[1]->y(),
-			v[2]->x(), v[2]->y(), v[2]->y(), n);
+    return MFace(i0 < 3 ? _v[i0] : _vs[i0 - 3],
+		 i1 < 3 ? _v[i1] : _vs[i1 - 3],
+		 i2 < 3 ? _v[i2] : _vs[i2 - 3]);
   }
   int getTypeForMSH(){ return TRI2; }
   int getTypeForUNV(){ return 92; } // THINSHLL2
@@ -269,16 +252,12 @@ class MQuadrangle : public MElement {
   inline int getNumVertices(){ return 4; }
   inline MVertex *getVertex(int num){ return _v[num]; }
   virtual int getNumEdges(){ return 4; }
-  virtual void getEdge(int num, MVertex *v[2])
+  virtual MEdge getEdge(int num)
   {
-    v[0] = _v[edges_quad[num][0]];
-    v[1] = _v[edges_quad[num][1]];
+    return MEdge(_v[edges_quad[num][0]], _v[edges_quad[num][1]], this);
   }
   virtual int getNumFaces(){ return 1; }
-  virtual void getFace(int num, MVertex *v[4])
-  {
-    v[0] = _v[0]; v[1] = _v[1]; v[2] = _v[2]; v[3] = _v[3];
-  }
+  virtual MFace getFace(int num){ return MFace(_v[0], _v[1], _v[2], _v[3]); }
   int getTypeForMSH(){ return QUA1; }
   int getTypeForUNV(){ return 94; } // QUAD
   char *getStringForPOS(){ return "SQ"; }
@@ -319,18 +298,16 @@ class MTetrahedron : public MElement {
   inline int getNumVertices(){ return 4; }
   inline MVertex *getVertex(int num){ return _v[num]; }
   virtual int getNumEdges(){ return 4; }
-  virtual void getEdge(int num, MVertex *v[2])
+  virtual MEdge getEdge(int num)
   {
-    v[0] = _v[edges_tetra[num][0]];
-    v[1] = _v[edges_tetra[num][1]];
+    return MEdge(_v[edges_tetra[num][0]], _v[edges_tetra[num][1]], this);
   }
   virtual int getNumFaces(){ return 4; }
-  virtual void getFace(int num, MVertex *v[4])
+  virtual MFace getFace(int num)
   {
-    v[0] = _v[trifaces_tetra[num][0]];
-    v[1] = _v[trifaces_tetra[num][1]];
-    v[2] = _v[trifaces_tetra[num][2]];
-    v[3] = 0;
+    return MFace(_v[trifaces_tetra[num][0]],
+		 _v[trifaces_tetra[num][1]],
+		 _v[trifaces_tetra[num][2]]);
   }
   int getTypeForMSH(){ return TET1; }
   int getTypeForUNV(){ return 111; } // SOLIDFEM
@@ -407,18 +384,17 @@ class MHexahedron : public MElement {
   inline int getNumVertices(){ return 8; }
   inline MVertex *getVertex(int num){ return _v[num]; }
   virtual int getNumEdges(){ return 12; }
-  virtual void getEdge(int num, MVertex *v[2])
+  virtual MEdge getEdge(int num)
   {
-    v[0] = _v[edges_hexa[num][0]];
-    v[1] = _v[edges_hexa[num][1]];
+    return MEdge(_v[edges_hexa[num][0]], _v[edges_hexa[num][1]], this);
   }
-  int getNumFaces(){ return 6; }
-  void getFace(int num, MVertex *v[4])
+  virtual int getNumFaces(){ return 6; }
+  virtual MFace getFace(int num)
   {
-    v[0] = _v[quadfaces_hexa[num][0]];
-    v[1] = _v[quadfaces_hexa[num][1]];
-    v[2] = _v[quadfaces_hexa[num][2]];
-    v[3] = _v[quadfaces_hexa[num][3]];
+    return MFace(_v[quadfaces_hexa[num][0]],
+		 _v[quadfaces_hexa[num][1]],
+		 _v[quadfaces_hexa[num][2]],
+		 _v[quadfaces_hexa[num][3]]);
   }
   int getTypeForMSH(){ return HEX1; }
   int getTypeForUNV(){ return 115; } // BRICK
@@ -506,26 +482,22 @@ class MPrism : public MElement {
   inline int getNumVertices(){ return 6; }
   inline MVertex *getVertex(int num){ return _v[num]; }
   virtual int getNumEdges(){ return 9; }
-  virtual void getEdge(int num, MVertex *v[2])
+  virtual MEdge getEdge(int num)
   {
-    v[0] = _v[edges_prism[num][0]];
-    v[1] = _v[edges_prism[num][1]];
+    return MEdge(_v[edges_prism[num][0]], _v[edges_prism[num][1]], this);
   }
-  int getNumFaces(){ return 5; }
-  void getFace(int num, MVertex *v[4])
+  virtual int getNumFaces(){ return 5; }
+  virtual MFace getFace(int num)
   {
-    if(num < 3){
-      v[0] = _v[trifaces_prism[num][0]];
-      v[1] = _v[trifaces_prism[num][1]];
-      v[2] = _v[trifaces_prism[num][2]];
-      v[3] = 0;
-    }
-    else{
-      v[0] = _v[quadfaces_prism[num - 3][0]];
-      v[1] = _v[quadfaces_prism[num - 3][1]];
-      v[2] = _v[quadfaces_prism[num - 3][2]];
-      v[3] = _v[quadfaces_prism[num - 3][3]];
-    }
+    if(num < 3)
+      return MFace(_v[trifaces_prism[num][0]],
+		   _v[trifaces_prism[num][1]],
+		   _v[trifaces_prism[num][2]]);
+    else
+      return MFace(_v[quadfaces_prism[num - 3][0]],
+		   _v[quadfaces_prism[num - 3][1]],
+		   _v[quadfaces_prism[num - 3][2]],
+		   _v[quadfaces_prism[num - 3][3]]);
   }
   int getTypeForMSH(){ return PRI1; }
   int getTypeForUNV(){ return 112; } // WEDGE
@@ -605,26 +577,22 @@ class MPyramid : public MElement {
   inline int getNumVertices(){ return 5; }
   inline MVertex *getVertex(int num){ return _v[num]; }
   virtual int getNumEdges(){ return 8; }
-  virtual void getEdge(int num, MVertex *v[2])
-  {
-    v[0] = _v[edges_pyramid[num][0]];
-    v[1] = _v[edges_pyramid[num][1]];
-  }
-  int getNumFaces(){ return 5; }
-  void getFace(int num, MVertex *v[4])
-  {
-    if(num < 4){
-      v[0] = _v[trifaces_pyramid[num][0]];
-      v[1] = _v[trifaces_pyramid[num][1]];
-      v[2] = _v[trifaces_pyramid[num][2]];
-      v[3] = 0;
-    }
-    else{
-      v[0] = _v[quadfaces_pyramid[num - 4][0]];
-      v[1] = _v[quadfaces_pyramid[num - 4][1]];
-      v[2] = _v[quadfaces_pyramid[num - 4][2]];
-      v[3] = _v[quadfaces_pyramid[num - 4][3]];
-    }
+  virtual MEdge getEdge(int num)
+  {
+    return MEdge(_v[edges_pyramid[num][0]], _v[edges_pyramid[num][1]], this);
+  }
+  virtual int getNumFaces(){ return 5; }
+  virtual MFace getFace(int num)
+  {
+    if(num < 4)
+      return MFace(_v[trifaces_pyramid[num][0]],
+		   _v[trifaces_pyramid[num][1]],
+		   _v[trifaces_pyramid[num][2]]);
+    else
+      return MFace(_v[quadfaces_pyramid[num - 4][0]],
+		   _v[quadfaces_pyramid[num - 4][1]],
+		   _v[quadfaces_pyramid[num - 4][2]],
+		   _v[quadfaces_pyramid[num - 4][3]]);
   }
   int getTypeForMSH(){ return PYR1; }
   int getTypeForUNV(){ throw; }
diff --git a/Geo/MFace.h b/Geo/MFace.h
new file mode 100644
index 0000000000..ee21ca0b22
--- /dev/null
+++ b/Geo/MFace.h
@@ -0,0 +1,28 @@
+#ifndef _MFACE_H_
+#define _MFACE_H_
+
+#include "MVertex.h"
+#include "SVector3.h"
+#include "Numeric.h"
+
+class MFace {
+ private:
+  MVertex *_v[4];
+ public:
+  MFace(MVertex *v0, MVertex *v1, MVertex *v2, MVertex *v3=0) 
+  {
+    _v[0] = v0; _v[1] = v1; _v[2] = v2; _v[3] = v3;
+  }
+  inline int getNumVertices() const { return _v[3] ? 4 : 3; }
+  inline MVertex *getVertex(int i) const { return _v[i]; }
+  SVector3 normal()
+  {
+    double n[3];
+    normal3points(_v[0]->x(), _v[0]->y(), _v[0]->z(),
+		  _v[1]->x(), _v[1]->y(), _v[1]->z(),
+		  _v[2]->x(), _v[2]->y(), _v[2]->z(), n);
+    return SVector3(n[0], n[1], n[2]);
+  }
+};
+
+#endif
diff --git a/Geo/MRep.h b/Geo/MRep.h
new file mode 100644
index 0000000000..f466914892
--- /dev/null
+++ b/Geo/MRep.h
@@ -0,0 +1,87 @@
+#ifndef _MREP_H_
+#define _MREP_H_
+
+#include <set>
+#include <algorithm>
+#include "GEdge.h"
+#include "GFace.h"
+#include "GRegion.h"
+#include "MVertex.h"
+#include "MEdge.h"
+#include "MElement.h"
+#include "VertexArray.h"
+#include "Message.h"
+
+class MRep {
+ public:
+  MRep() : va_lines(0), va_triangles(0), va_quads(0) {}
+  virtual ~MRep(){}
+  virtual void generateEdges() = 0;
+  std::set<MEdge, MEdgeLessThan> edges;
+  VertexArray *va_lines, *va_triangles, *va_quads;
+};
+
+class MRepEdge : public MRep {
+ private:
+  GEdge *_e;
+
+public:
+  MRepEdge(GEdge *e) : _e(e) {}
+  virtual ~MRepEdge(){}
+  virtual void generateEdges()
+  {
+    if(edges.size()) return;
+    for(unsigned int i = 0; i < _e->lines.size(); i++)
+      for(int j = 0; j < _e->lines[i]->getNumEdgesRep(); j++)
+	edges.insert(_e->lines[i]->getEdgeRep(j));
+    Msg(DEBUG, "%d edges in line %d", (int)edges.size(), _e->tag());
+  }
+};
+
+class MRepFace : public MRep {
+ private:
+  GFace *_f;
+
+ public:
+  MRepFace(GFace *f) : _f(f) {}
+  virtual ~MRepFace(){}
+  virtual void generateEdges()
+  {
+    if(edges.size()) return;
+    for(unsigned int i = 0; i < _f->triangles.size(); i++)
+      for(int j = 0; j < _f->triangles[i]->getNumEdgesRep(); j++)
+	edges.insert(_f->triangles[i]->getEdgeRep(j));
+    for(unsigned int i = 0; i < _f->quadrangles.size(); i++)
+      for(int j = 0; j < _f->quadrangles[i]->getNumEdgesRep(); j++)
+	edges.insert(_f->quadrangles[i]->getEdgeRep(j));
+    Msg(DEBUG, "%d edges in surface %d", (int)edges.size(), _f->tag());
+  }
+};
+
+class MRepRegion : public MRep {
+ private:
+  GRegion *_r;
+
+ public:
+  MRepRegion(GRegion *r) : _r(r) {}
+  virtual ~MRepRegion(){}
+  virtual void generateEdges()
+  {
+    if(edges.size()) return;
+    for(unsigned int i = 0; i < _r->tetrahedra.size(); i++)
+      for(int j = 0; j < _r->tetrahedra[i]->getNumEdgesRep(); j++)
+	edges.insert(_r->tetrahedra[i]->getEdgeRep(j));
+    for(unsigned int i = 0; i < _r->hexahedra.size(); i++)
+      for(int j = 0; j < _r->hexahedra[i]->getNumEdgesRep(); j++)
+	edges.insert(_r->hexahedra[i]->getEdgeRep(j));
+    for(unsigned int i = 0; i < _r->prisms.size(); i++)
+      for(int j = 0; j < _r->prisms[i]->getNumEdgesRep(); j++)
+	edges.insert(_r->prisms[i]->getEdgeRep(j));
+    for(unsigned int i = 0; i < _r->hexahedra.size(); i++)
+      for(int j = 0; j < _r->hexahedra[i]->getNumEdgesRep(); j++)
+	edges.insert(_r->hexahedra[i]->getEdgeRep(j));
+    Msg(DEBUG, "%d edges in volume %d", (int)edges.size(), _r->tag());
+  }
+};
+
+#endif
diff --git a/Geo/Makefile b/Geo/Makefile
index 4018df22fe..396ce35273 100644
--- a/Geo/Makefile
+++ b/Geo/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.92 2006-08-13 20:46:54 geuzaine Exp $
+# $Id: Makefile,v 1.93 2006-08-15 02:17:25 geuzaine Exp $
 #
 # Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 #
@@ -108,7 +108,8 @@ Geo.o: Geo.cpp ../Common/Gmsh.h ../Common/Message.h ../DataStr/Malloc.h \
   ../Mesh/Simplex.h ../Mesh/Mesh.h ../Mesh/Matrix.h ExtrudeParams.h \
   ../Parser/Parser.h ../Common/Context.h gmshModel.h GModel.h GVertex.h \
   GEntity.h Range.h SPoint3.h SBoundingBox3d.h MVertex.h GPoint.h GEdge.h \
-  SVector3.h SPoint2.h MElement.h GFace.h Pair.h GRegion.h
+  SVector3.h SPoint2.h MElement.h MEdge.h MFace.h GFace.h Pair.h \
+  GRegion.h ../Common/SmoothNormals.h
 # 1 "/Users/geuzaine/.gmsh/Geo//"
 GeoUtils.o: GeoUtils.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
@@ -122,30 +123,33 @@ GeoUtils.o: GeoUtils.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../Numeric/Numeric.h
 # 1 "/Users/geuzaine/.gmsh/Geo//"
 GEntity.o: GEntity.cpp GEntity.h Range.h SPoint3.h SBoundingBox3d.h \
-  MVertex.h ../Common/GmshDefines.h
+  ../Common/GmshDefines.h MRep.h GEdge.h GVertex.h MVertex.h GPoint.h \
+  SVector3.h SPoint2.h MElement.h MEdge.h MFace.h ../Numeric/Numeric.h \
+  GFace.h Pair.h GRegion.h ../Common/VertexArray.h ../DataStr/List.h \
+  ../Common/Message.h
 # 1 "/Users/geuzaine/.gmsh/Geo//"
 GVertex.o: GVertex.cpp GVertex.h GEntity.h Range.h SPoint3.h \
-  SBoundingBox3d.h MVertex.h ../Common/GmshDefines.h GPoint.h
+  SBoundingBox3d.h ../Common/GmshDefines.h MVertex.h GPoint.h
 # 1 "/Users/geuzaine/.gmsh/Geo//"
 GEdge.o: GEdge.cpp GModel.h GVertex.h GEntity.h Range.h SPoint3.h \
-  SBoundingBox3d.h MVertex.h ../Common/GmshDefines.h GPoint.h GEdge.h \
-  SVector3.h SPoint2.h MElement.h ../Numeric/Numeric.h GFace.h Pair.h \
-  GRegion.h
+  SBoundingBox3d.h ../Common/GmshDefines.h MVertex.h GPoint.h GEdge.h \
+  SVector3.h SPoint2.h MElement.h MEdge.h MFace.h ../Numeric/Numeric.h \
+  GFace.h Pair.h GRegion.h ../Common/SmoothNormals.h
 # 1 "/Users/geuzaine/.gmsh/Geo//"
 GFace.o: GFace.cpp GModel.h GVertex.h GEntity.h Range.h SPoint3.h \
-  SBoundingBox3d.h MVertex.h ../Common/GmshDefines.h GPoint.h GEdge.h \
-  SVector3.h SPoint2.h MElement.h ../Numeric/Numeric.h GFace.h Pair.h \
-  GRegion.h ../Common/Message.h
+  SBoundingBox3d.h ../Common/GmshDefines.h MVertex.h GPoint.h GEdge.h \
+  SVector3.h SPoint2.h MElement.h MEdge.h MFace.h ../Numeric/Numeric.h \
+  GFace.h Pair.h GRegion.h ../Common/SmoothNormals.h ../Common/Message.h
 # 1 "/Users/geuzaine/.gmsh/Geo//"
 GRegion.o: GRegion.cpp GModel.h GVertex.h GEntity.h Range.h SPoint3.h \
-  SBoundingBox3d.h MVertex.h ../Common/GmshDefines.h GPoint.h GEdge.h \
-  SVector3.h SPoint2.h MElement.h ../Numeric/Numeric.h GFace.h Pair.h \
-  GRegion.h
+  SBoundingBox3d.h ../Common/GmshDefines.h MVertex.h GPoint.h GEdge.h \
+  SVector3.h SPoint2.h MElement.h MEdge.h MFace.h ../Numeric/Numeric.h \
+  GFace.h Pair.h GRegion.h ../Common/SmoothNormals.h
 # 1 "/Users/geuzaine/.gmsh/Geo//"
 GModel.o: GModel.cpp GModel.h GVertex.h GEntity.h Range.h SPoint3.h \
-  SBoundingBox3d.h MVertex.h ../Common/GmshDefines.h GPoint.h GEdge.h \
-  SVector3.h SPoint2.h MElement.h ../Numeric/Numeric.h GFace.h Pair.h \
-  GRegion.h
+  SBoundingBox3d.h ../Common/GmshDefines.h MVertex.h GPoint.h GEdge.h \
+  SVector3.h SPoint2.h MElement.h MEdge.h MFace.h ../Numeric/Numeric.h \
+  GFace.h Pair.h GRegion.h ../Common/SmoothNormals.h
 # 1 "/Users/geuzaine/.gmsh/Geo//"
 GModelIO.o: GModelIO.cpp ../Common/Message.h ../Common/GmshDefines.h \
   gmshRegion.h ../Mesh/Mesh.h ../DataStr/List.h ../DataStr/Tree.h \
@@ -156,66 +160,69 @@ GModelIO.o: GModelIO.cpp ../Common/Message.h ../Common/GmshDefines.h \
   ../Mesh/Vertex.h ../Mesh/Simplex.h ../Mesh/Mesh.h ../Mesh/Matrix.h \
   gmshModel.h GModel.h GVertex.h GEntity.h Range.h SPoint3.h \
   SBoundingBox3d.h MVertex.h GPoint.h GEdge.h SVector3.h SPoint2.h \
-  MElement.h ../Numeric/Numeric.h GFace.h Pair.h GRegion.h gmshFace.h \
-  gmshVertex.h gmshEdge.h
+  MElement.h MEdge.h MFace.h ../Numeric/Numeric.h GFace.h Pair.h \
+  GRegion.h ../Common/SmoothNormals.h gmshFace.h gmshVertex.h gmshEdge.h
 # 1 "/Users/geuzaine/.gmsh/Geo//"
 MVertex.o: MVertex.cpp MVertex.h SPoint3.h
 # 1 "/Users/geuzaine/.gmsh/Geo//"
 MElement.o: MElement.cpp MElement.h ../Common/GmshDefines.h MVertex.h \
-  SPoint3.h ../Numeric/Numeric.h GEntity.h Range.h SBoundingBox3d.h
+  SPoint3.h MEdge.h MFace.h SVector3.h ../Numeric/Numeric.h GEntity.h \
+  Range.h SBoundingBox3d.h
 # 1 "/Users/geuzaine/.gmsh/Geo//"
 gmshModel.o: gmshModel.cpp gmshModel.h GModel.h GVertex.h GEntity.h \
-  Range.h SPoint3.h SBoundingBox3d.h MVertex.h ../Common/GmshDefines.h \
-  GPoint.h GEdge.h SVector3.h SPoint2.h MElement.h ../Numeric/Numeric.h \
-  GFace.h Pair.h GRegion.h ../Mesh/Mesh.h ../DataStr/List.h \
+  Range.h SPoint3.h SBoundingBox3d.h ../Common/GmshDefines.h MVertex.h \
+  GPoint.h GEdge.h SVector3.h SPoint2.h MElement.h MEdge.h MFace.h \
+  ../Numeric/Numeric.h GFace.h Pair.h GRegion.h ../Common/SmoothNormals.h \
+  ../Mesh/Mesh.h ../DataStr/List.h ../DataStr/Tree.h ../DataStr/avl.h \
+  ../Mesh/Vertex.h ../Mesh/Element.h ../Mesh/Vertex.h ../Mesh/Simplex.h \
+  ../Mesh/Vertex.h ../Mesh/Element.h ../Mesh/Face.h ../Mesh/Vertex.h \
+  ../Mesh/Element.h ../Mesh/Edge.h ../Mesh/Vertex.h ../Mesh/Simplex.h \
+  ../Geo/ExtrudeParams.h ../Mesh/Metric.h ../Mesh/Vertex.h \
+  ../Mesh/Simplex.h ../Mesh/Mesh.h ../Mesh/Matrix.h Geo.h \
+  ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
+  ../Common/Message.h gmshVertex.h gmshFace.h gmshEdge.h gmshRegion.h
+# 1 "/Users/geuzaine/.gmsh/Geo//"
+gmshEdge.o: gmshEdge.cpp gmshModel.h GModel.h GVertex.h GEntity.h Range.h \
+  SPoint3.h SBoundingBox3d.h ../Common/GmshDefines.h MVertex.h GPoint.h \
+  GEdge.h SVector3.h SPoint2.h MElement.h MEdge.h MFace.h \
+  ../Numeric/Numeric.h GFace.h Pair.h GRegion.h ../Common/SmoothNormals.h \
+  gmshEdge.h gmshVertex.h ../Mesh/Mesh.h ../DataStr/List.h \
   ../DataStr/Tree.h ../DataStr/avl.h ../Mesh/Vertex.h ../Mesh/Element.h \
   ../Mesh/Vertex.h ../Mesh/Simplex.h ../Mesh/Vertex.h ../Mesh/Element.h \
   ../Mesh/Face.h ../Mesh/Vertex.h ../Mesh/Element.h ../Mesh/Edge.h \
   ../Mesh/Vertex.h ../Mesh/Simplex.h ../Geo/ExtrudeParams.h \
   ../Mesh/Metric.h ../Mesh/Vertex.h ../Mesh/Simplex.h ../Mesh/Mesh.h \
-  ../Mesh/Matrix.h Geo.h ../DataStr/Tools.h ../DataStr/List.h \
-  ../DataStr/Tree.h ../Common/Message.h gmshVertex.h gmshFace.h \
-  gmshEdge.h gmshRegion.h
-# 1 "/Users/geuzaine/.gmsh/Geo//"
-gmshEdge.o: gmshEdge.cpp gmshModel.h GModel.h GVertex.h GEntity.h Range.h \
-  SPoint3.h SBoundingBox3d.h MVertex.h ../Common/GmshDefines.h GPoint.h \
-  GEdge.h SVector3.h SPoint2.h MElement.h ../Numeric/Numeric.h GFace.h \
-  Pair.h GRegion.h gmshEdge.h gmshVertex.h ../Mesh/Mesh.h \
-  ../DataStr/List.h ../DataStr/Tree.h ../DataStr/avl.h ../Mesh/Vertex.h \
-  ../Mesh/Element.h ../Mesh/Vertex.h ../Mesh/Simplex.h ../Mesh/Vertex.h \
-  ../Mesh/Element.h ../Mesh/Face.h ../Mesh/Vertex.h ../Mesh/Element.h \
-  ../Mesh/Edge.h ../Mesh/Vertex.h ../Mesh/Simplex.h \
-  ../Geo/ExtrudeParams.h ../Mesh/Metric.h ../Mesh/Vertex.h \
-  ../Mesh/Simplex.h ../Mesh/Mesh.h ../Mesh/Matrix.h \
-  ../Mesh/Interpolation.h ../Mesh/Vertex.h ../Mesh/Mesh.h CAD.h \
-  ExtrudeParams.h Geo.h ../Mesh/Create.h ../Mesh/Vertex.h ../Mesh/Mesh.h \
-  ../Common/Context.h
+  ../Mesh/Matrix.h ../Mesh/Interpolation.h ../Mesh/Vertex.h \
+  ../Mesh/Mesh.h CAD.h ExtrudeParams.h Geo.h ../Mesh/Create.h \
+  ../Mesh/Vertex.h ../Mesh/Mesh.h ../Common/Context.h
 # 1 "/Users/geuzaine/.gmsh/Geo//"
 gmshFace.o: gmshFace.cpp gmshModel.h GModel.h GVertex.h GEntity.h Range.h \
-  SPoint3.h SBoundingBox3d.h MVertex.h ../Common/GmshDefines.h GPoint.h \
-  GEdge.h SVector3.h SPoint2.h MElement.h ../Numeric/Numeric.h GFace.h \
-  Pair.h GRegion.h gmshEdge.h gmshVertex.h ../Mesh/Mesh.h \
-  ../DataStr/List.h ../DataStr/Tree.h ../DataStr/avl.h ../Mesh/Vertex.h \
-  ../Mesh/Element.h ../Mesh/Vertex.h ../Mesh/Simplex.h ../Mesh/Vertex.h \
-  ../Mesh/Element.h ../Mesh/Face.h ../Mesh/Vertex.h ../Mesh/Element.h \
-  ../Mesh/Edge.h ../Mesh/Vertex.h ../Mesh/Simplex.h \
-  ../Geo/ExtrudeParams.h ../Mesh/Metric.h ../Mesh/Vertex.h \
-  ../Mesh/Simplex.h ../Mesh/Mesh.h ../Mesh/Matrix.h gmshFace.h \
-  ../Mesh/Interpolation.h ../Mesh/Vertex.h ../Mesh/Mesh.h CAD.h \
-  ExtrudeParams.h Geo.h ../Mesh/Create.h ../Mesh/Vertex.h ../Mesh/Mesh.h \
-  ../Mesh/Utils.h ../Mesh/Vertex.h ../Mesh/Mesh.h ../Common/Message.h
+  SPoint3.h SBoundingBox3d.h ../Common/GmshDefines.h MVertex.h GPoint.h \
+  GEdge.h SVector3.h SPoint2.h MElement.h MEdge.h MFace.h \
+  ../Numeric/Numeric.h GFace.h Pair.h GRegion.h ../Common/SmoothNormals.h \
+  gmshEdge.h gmshVertex.h ../Mesh/Mesh.h ../DataStr/List.h \
+  ../DataStr/Tree.h ../DataStr/avl.h ../Mesh/Vertex.h ../Mesh/Element.h \
+  ../Mesh/Vertex.h ../Mesh/Simplex.h ../Mesh/Vertex.h ../Mesh/Element.h \
+  ../Mesh/Face.h ../Mesh/Vertex.h ../Mesh/Element.h ../Mesh/Edge.h \
+  ../Mesh/Vertex.h ../Mesh/Simplex.h ../Geo/ExtrudeParams.h \
+  ../Mesh/Metric.h ../Mesh/Vertex.h ../Mesh/Simplex.h ../Mesh/Mesh.h \
+  ../Mesh/Matrix.h gmshFace.h ../Mesh/Interpolation.h ../Mesh/Vertex.h \
+  ../Mesh/Mesh.h CAD.h ExtrudeParams.h Geo.h ../Mesh/Create.h \
+  ../Mesh/Vertex.h ../Mesh/Mesh.h ../Mesh/Utils.h ../Mesh/Vertex.h \
+  ../Mesh/Mesh.h ../Common/Message.h
 # 1 "/Users/geuzaine/.gmsh/Geo//"
 gmshRegion.o: gmshRegion.cpp gmshModel.h GModel.h GVertex.h GEntity.h \
-  Range.h SPoint3.h SBoundingBox3d.h MVertex.h ../Common/GmshDefines.h \
-  GPoint.h GEdge.h SVector3.h SPoint2.h MElement.h ../Numeric/Numeric.h \
-  GFace.h Pair.h GRegion.h gmshFace.h gmshVertex.h ../Mesh/Mesh.h \
-  ../DataStr/List.h ../DataStr/Tree.h ../DataStr/avl.h ../Mesh/Vertex.h \
-  ../Mesh/Element.h ../Mesh/Vertex.h ../Mesh/Simplex.h ../Mesh/Vertex.h \
-  ../Mesh/Element.h ../Mesh/Face.h ../Mesh/Vertex.h ../Mesh/Element.h \
-  ../Mesh/Edge.h ../Mesh/Vertex.h ../Mesh/Simplex.h \
-  ../Geo/ExtrudeParams.h ../Mesh/Metric.h ../Mesh/Vertex.h \
-  ../Mesh/Simplex.h ../Mesh/Mesh.h ../Mesh/Matrix.h gmshRegion.h Geo.h \
-  ../Mesh/Create.h ../Mesh/Vertex.h ../Mesh/Mesh.h
+  Range.h SPoint3.h SBoundingBox3d.h ../Common/GmshDefines.h MVertex.h \
+  GPoint.h GEdge.h SVector3.h SPoint2.h MElement.h MEdge.h MFace.h \
+  ../Numeric/Numeric.h GFace.h Pair.h GRegion.h ../Common/SmoothNormals.h \
+  gmshFace.h gmshVertex.h ../Mesh/Mesh.h ../DataStr/List.h \
+  ../DataStr/Tree.h ../DataStr/avl.h ../Mesh/Vertex.h ../Mesh/Element.h \
+  ../Mesh/Vertex.h ../Mesh/Simplex.h ../Mesh/Vertex.h ../Mesh/Element.h \
+  ../Mesh/Face.h ../Mesh/Vertex.h ../Mesh/Element.h ../Mesh/Edge.h \
+  ../Mesh/Vertex.h ../Mesh/Simplex.h ../Geo/ExtrudeParams.h \
+  ../Mesh/Metric.h ../Mesh/Vertex.h ../Mesh/Simplex.h ../Mesh/Mesh.h \
+  ../Mesh/Matrix.h gmshRegion.h Geo.h ../Mesh/Create.h ../Mesh/Vertex.h \
+  ../Mesh/Mesh.h
 # 1 "/Users/geuzaine/.gmsh/Geo//"
 SVector3.o: SVector3.cpp SVector3.h SPoint3.h
 # 1 "/Users/geuzaine/.gmsh/Geo//"
diff --git a/Graphics/Geom.cpp b/Graphics/Geom.cpp
index 13f4ffc9ec..a71ad144f8 100644
--- a/Graphics/Geom.cpp
+++ b/Graphics/Geom.cpp
@@ -1,4 +1,4 @@
-// $Id: Geom.cpp,v 1.111 2006-08-13 20:46:55 geuzaine Exp $
+// $Id: Geom.cpp,v 1.112 2006-08-15 02:17:25 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -30,9 +30,8 @@
 extern Context_T CTX;
 extern GModel *GMODEL;
 
-class drawGVertex
-{
-public :
+class drawGVertex {
+ public :
   void operator () (GVertex *v)
   {
     if(!v->getVisibility()) return;
@@ -87,9 +86,8 @@ public :
   }
 };
 
-class drawGEdge
-{
-public :
+class drawGEdge {
+ public :
   void operator () (GEdge *e)
   {
     if(!e->getVisibility() || e->geomType() == GEntity::DiscreteCurve)
@@ -173,9 +171,8 @@ public :
   }
 };
 
-class drawGFace
-{
-private:
+class drawGFace {
+ private:
   void _drawNonPlaneGFace(GFace *f)
   {
     if(CTX.geom.surfaces) {
@@ -354,9 +351,8 @@ public :
 };
 
 
-class drawGRegion
-{
-public :
+class drawGRegion {
+ public :
   void operator () (GRegion *r)
   {
     if(!r->getVisibility() || r->geomType() == GEntity::DiscreteVolume)
diff --git a/Graphics/Iso.cpp b/Graphics/Iso.cpp
index 75c38d7cff..3a0c56d5d4 100644
--- a/Graphics/Iso.cpp
+++ b/Graphics/Iso.cpp
@@ -1,4 +1,4 @@
-// $Id: Iso.cpp,v 1.37 2006-08-07 22:02:30 geuzaine Exp $
+// $Id: Iso.cpp,v 1.38 2006-08-15 02:17:26 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -56,7 +56,6 @@ void IsoTriangle(Post_View * View, double *X, double *Y, double *Z,
     if(View->LinVertexArray && View->LinVertexArray->fill && !View->LineType){
       View->LinVertexArray->add(Xp[0], Yp[0], Zp[0], color);
       View->LinVertexArray->add(Xp[1], Yp[1], Zp[1], color);
-      View->LinVertexArray->num++;
     }
     else{
       glColor4ubv((GLubyte *) & color);
@@ -493,7 +492,6 @@ void IsoSimplex(Post_View * View, int preproNormals,
 				norms[3*(i-1)], norms[3*(i-1)+1], norms[3*(i-1)+2], color);
       View->TriVertexArray->add(Xp[i], Yp[i], Zp[i],
 				norms[3*i], norms[3*i+1], norms[3*i+2], color);
-      View->TriVertexArray->num++;
     }
   }
   else{
diff --git a/Graphics/Makefile b/Graphics/Makefile
index 0185be82a2..00ec0d2793 100644
--- a/Graphics/Makefile
+++ b/Graphics/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.95 2006-08-13 02:46:53 geuzaine Exp $
+# $Id: Makefile,v 1.96 2006-08-15 02:17:26 geuzaine Exp $
 #
 # Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 #
@@ -83,10 +83,11 @@ Draw.o: Draw.cpp ../Common/Gmsh.h ../Common/Message.h ../DataStr/Malloc.h \
   ../Common/GmshMatrix.h ../Common/AdaptiveViews.h ../Common/GmshMatrix.h \
   ../Common/Context.h ../Geo/GModel.h ../Geo/GVertex.h ../Geo/GEntity.h \
   ../Geo/Range.h ../Geo/SPoint3.h ../Geo/SBoundingBox3d.h \
-  ../Geo/SPoint3.h ../Geo/MVertex.h ../Geo/SPoint3.h ../Geo/MVertex.h \
-  ../Geo/GPoint.h ../Geo/GEdge.h ../Geo/GEntity.h ../Geo/GVertex.h \
-  ../Geo/SVector3.h ../Geo/SPoint3.h ../Geo/SPoint3.h ../Geo/SPoint2.h \
-  ../Geo/MElement.h ../Geo/MVertex.h ../Geo/GFace.h ../Geo/GPoint.h \
+  ../Geo/SPoint3.h ../Geo/MVertex.h ../Geo/SPoint3.h ../Geo/GPoint.h \
+  ../Geo/GEdge.h ../Geo/GEntity.h ../Geo/GVertex.h ../Geo/SVector3.h \
+  ../Geo/SPoint3.h ../Geo/SPoint3.h ../Geo/SPoint2.h ../Geo/MElement.h \
+  ../Geo/MVertex.h ../Geo/MEdge.h ../Geo/MVertex.h ../Geo/MFace.h \
+  ../Geo/MVertex.h ../Geo/SVector3.h ../Geo/GFace.h ../Geo/GPoint.h \
   ../Geo/GEntity.h ../Geo/MElement.h ../Geo/SPoint2.h ../Geo/SVector3.h \
   ../Geo/Pair.h ../Geo/GRegion.h ../Geo/GEntity.h ../Geo/MElement.h \
   ../Geo/SBoundingBox3d.h
@@ -95,18 +96,21 @@ Mesh.o: Mesh.cpp ../Common/Gmsh.h ../Common/Message.h ../DataStr/Malloc.h \
   ../DataStr/List.h ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h \
   ../DataStr/List.h ../DataStr/Tree.h ../Common/GmshUI.h ../Geo/GModel.h \
   ../Geo/GVertex.h ../Geo/GEntity.h ../Geo/Range.h ../Geo/SPoint3.h \
-  ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../Geo/MVertex.h \
-  ../Geo/SPoint3.h ../Common/GmshDefines.h ../Geo/MVertex.h \
-  ../Geo/GPoint.h ../Geo/GEdge.h ../Geo/GEntity.h ../Geo/GVertex.h \
-  ../Geo/SVector3.h ../Geo/SPoint3.h ../Geo/SPoint3.h ../Geo/SPoint2.h \
-  ../Geo/MElement.h ../Geo/MVertex.h ../Numeric/Numeric.h ../Geo/GFace.h \
-  ../Geo/GPoint.h ../Geo/GEntity.h ../Geo/MElement.h ../Geo/SPoint2.h \
-  ../Geo/SVector3.h ../Geo/Pair.h ../Geo/GRegion.h ../Geo/GEntity.h \
-  ../Geo/MElement.h ../Geo/SBoundingBox3d.h Draw.h ../Common/Views.h \
-  ../Common/ColorTable.h ../Common/VertexArray.h \
+  ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../Common/GmshDefines.h \
+  ../Geo/MVertex.h ../Geo/SPoint3.h ../Geo/GPoint.h ../Geo/GEdge.h \
+  ../Geo/GEntity.h ../Geo/GVertex.h ../Geo/SVector3.h ../Geo/SPoint3.h \
+  ../Geo/SPoint3.h ../Geo/SPoint2.h ../Geo/MElement.h ../Geo/MVertex.h \
+  ../Geo/MEdge.h ../Geo/MVertex.h ../Geo/MFace.h ../Geo/MVertex.h \
+  ../Geo/SVector3.h ../Numeric/Numeric.h ../Geo/GFace.h ../Geo/GPoint.h \
+  ../Geo/GEntity.h ../Geo/MElement.h ../Geo/SPoint2.h ../Geo/SVector3.h \
+  ../Geo/Pair.h ../Geo/GRegion.h ../Geo/GEntity.h ../Geo/MElement.h \
+  ../Geo/SBoundingBox3d.h ../Common/SmoothNormals.h Draw.h \
+  ../Common/Views.h ../Common/ColorTable.h ../Common/VertexArray.h \
   ../Common/SmoothNormals.h ../Common/GmshMatrix.h \
   ../Common/AdaptiveViews.h ../Common/GmshMatrix.h ../Common/Context.h \
-  ../Common/OS.h gl2ps.h tc.h
+  ../Geo/MRep.h ../Geo/GEdge.h ../Geo/GFace.h ../Geo/GRegion.h \
+  ../Geo/MVertex.h ../Geo/MEdge.h ../Geo/MElement.h ../Common/OS.h \
+  gl2ps.h tc.h
 # 1 "/Users/geuzaine/.gmsh/Graphics//"
 Geom.o: Geom.cpp ../Common/Gmsh.h ../Common/Message.h ../DataStr/Malloc.h \
   ../DataStr/List.h ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h \
@@ -116,10 +120,11 @@ Geom.o: Geom.cpp ../Common/Gmsh.h ../Common/Message.h ../DataStr/Malloc.h \
   ../Common/AdaptiveViews.h ../Common/GmshMatrix.h ../Common/Context.h \
   gl2ps.h ../Geo/GModel.h ../Geo/GVertex.h ../Geo/GEntity.h \
   ../Geo/Range.h ../Geo/SPoint3.h ../Geo/SBoundingBox3d.h \
-  ../Geo/SPoint3.h ../Geo/MVertex.h ../Geo/SPoint3.h \
-  ../Common/GmshDefines.h ../Geo/MVertex.h ../Geo/GPoint.h ../Geo/GEdge.h \
-  ../Geo/GEntity.h ../Geo/GVertex.h ../Geo/SVector3.h ../Geo/SPoint3.h \
-  ../Geo/SPoint3.h ../Geo/SPoint2.h ../Geo/MElement.h ../Geo/MVertex.h \
+  ../Geo/SPoint3.h ../Common/GmshDefines.h ../Geo/MVertex.h \
+  ../Geo/SPoint3.h ../Geo/GPoint.h ../Geo/GEdge.h ../Geo/GEntity.h \
+  ../Geo/GVertex.h ../Geo/SVector3.h ../Geo/SPoint3.h ../Geo/SPoint3.h \
+  ../Geo/SPoint2.h ../Geo/MElement.h ../Geo/MVertex.h ../Geo/MEdge.h \
+  ../Geo/MVertex.h ../Geo/MFace.h ../Geo/MVertex.h ../Geo/SVector3.h \
   ../Geo/GFace.h ../Geo/GPoint.h ../Geo/GEntity.h ../Geo/MElement.h \
   ../Geo/SPoint2.h ../Geo/SVector3.h ../Geo/Pair.h ../Geo/GRegion.h \
   ../Geo/GEntity.h ../Geo/MElement.h ../Geo/SBoundingBox3d.h
diff --git a/Graphics/Mesh.cpp b/Graphics/Mesh.cpp
index da6e90ad6f..e648a3891a 100644
--- a/Graphics/Mesh.cpp
+++ b/Graphics/Mesh.cpp
@@ -1,4 +1,4 @@
-// $Id: Mesh.cpp,v 1.160 2006-08-13 18:11:17 geuzaine Exp $
+// $Id: Mesh.cpp,v 1.161 2006-08-15 02:17:26 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -24,7 +24,7 @@
 #include "GModel.h"
 #include "Draw.h"
 #include "Context.h"
-#include "VertexArray.h"
+#include "MRep.h"
 #include "OS.h"
 #include "gl2ps.h"
 
@@ -33,171 +33,350 @@ extern Context_T CTX;
 
 #include "tc.h"
 
-void renumberFaceVertices(GFace *f, List_T *xyz)
+static unsigned int getColor(GEntity *e, int forceColor, unsigned int color)
 {
-  std::list<GEdge*> ee = f->edges();
-  std::list<GVertex*> vv = f->vertices();
-
-  int num = 0;
+  if(forceColor) return color;
+  
+  if(e->getFlag() > 0)
+    return CTX.color.geom.surface_sel;
+  // else if(e->color)
+  //   return e->color;
+  else if(CTX.mesh.color_carousel == 1)
+    return CTX.color.mesh.carousel[abs(e->tag() % 20)];
+  else if(CTX.mesh.color_carousel == 2){
+    int np = e->physicals.size();
+    int p = np ? e->physicals[np - 1] : 0;
+    return CTX.color.mesh.carousel[abs(p % 20)];
+  }
+  return color;
+}
 
-  for(std::list<GVertex*>::const_iterator it = vv.begin(); it != vv.end(); ++it){
-    for(unsigned int i = 0; i < (*it)->mesh_vertices.size(); i++){
-      MVertex *v = (*it)->mesh_vertices[i]; v->setNum(num++); 
-      float x = v->x(), y = v->y(), z = v->z();
-      List_Add(xyz, &x); List_Add(xyz, &y); List_Add(xyz, &z);
+static double intersectCutPlane(MElement *e, int *edges=0, int *faces=0)
+{
+  MVertex *v = e->getVertex(0);
+  double val = CTX.mesh.evalCutPlane(v->x(), v->y(), v->z());
+  for(int i = 1; i < e->getNumVertices(); i++){
+    v = e->getVertex(i);
+    if(val * CTX.mesh.evalCutPlane(v->x(), v->y(), v->z()) <= 0){
+      // the element intersects the cut plane
+      if(CTX.mesh.cut_plane_as_surface){
+	if(!*edges) *edges = CTX.mesh.surfaces_edges;
+	if(!*faces) *faces = CTX.mesh.surfaces_faces;
+      }
+      return 1.;
     }
   }
-  for(std::list<GEdge*>::const_iterator it = ee.begin(); it != ee.end(); ++it){
-    for(unsigned int i = 0; i < (*it)->mesh_vertices.size(); i++){
-      MVertex *v = (*it)->mesh_vertices[i]; v->setNum(num++);
-      float x = v->x(), y = v->y(), z = v->z();
-      List_Add(xyz, &x); List_Add(xyz, &y); List_Add(xyz, &z);
-    }
+  return val;
+}
+
+static void drawArrays(VertexArray *va, GLint type, bool useColorArray, 
+		       bool useNormalArray, bool usePolygonOffset,
+		       unsigned int uniformColor, bool drawOutline=false)
+{
+  glVertexPointer(3, GL_FLOAT, 0, va->vertices->array);
+  glColorPointer(4, GL_UNSIGNED_BYTE, 0, va->colors->array);
+  glNormalPointer(GL_FLOAT, 0, va->normals->array);
+  
+  glEnableClientState(GL_VERTEX_ARRAY);
+  if(useColorArray)
+    glEnableClientState(GL_COLOR_ARRAY);
+  else{
+    glDisableClientState(GL_COLOR_ARRAY);
+    glColor4ubv((GLubyte *) & uniformColor);
   }
-  for(unsigned int i = 0; i < f->mesh_vertices.size(); i++){
-    MVertex *v = f->mesh_vertices[i]; v->setNum(num++);
-    float x = v->x(), y = v->y(), z = v->z();
-    List_Add(xyz, &x); List_Add(xyz, &y); List_Add(xyz, &z);
+  if(useNormalArray){
+    glEnable(GL_LIGHTING);
+    glEnableClientState(GL_NORMAL_ARRAY);
   }
+  else
+    glDisableClientState(GL_NORMAL_ARRAY);
+  
+  if(usePolygonOffset) 
+    glEnable(GL_POLYGON_OFFSET_FILL);
+  
+  if(drawOutline) 
+    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+  
+  glDrawArrays(type, 0, va->n());
+  
+  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+  glDisable(GL_POLYGON_OFFSET_FILL);
+  glDisable(GL_LIGHTING);
+  
+  glDisableClientState(GL_VERTEX_ARRAY);
+  glDisableClientState(GL_COLOR_ARRAY);
+  glDisableClientState(GL_NORMAL_ARRAY);
 }
 
-// define this to draw the vertex array by indexing elements
-//#define ELEM
+template<class T>
+void drawLabels(GEntity *e, std::vector<T*> elements, int stepLabelsDisplayed,
+		int &numLabelsDisplayed, int forceColor, unsigned int color)
+{
+  char str[256];
+  for(unsigned int i = 0; i < elements.size(); i++){
+    numLabelsDisplayed++;
+    if(numLabelsDisplayed % stepLabelsDisplayed == 0) {
+      unsigned col = getColor(e, forceColor, color);
+      glColor4ubv((GLubyte *) & col);
+      SPoint3 pc = elements[i]->barycenter();
+      if(CTX.mesh.label_type == 4)
+	sprintf(str, "(%g,%g,%g)", pc.x(), pc.y(), pc.z());
+      else if(CTX.mesh.label_type == 3)
+	sprintf(str, "%d", elements[i]->getPartition());
+      else if(CTX.mesh.label_type == 2){
+	int np = e->physicals.size();
+	int p = np ? e->physicals[np - 1] : 0;
+	sprintf(str, "%d", p);
+      }
+      else if(CTX.mesh.label_type == 1)
+	sprintf(str, "%d", e->tag());
+      else
+	sprintf(str, "%d", elements[i]->getNum());
+      glRasterPos3d(pc.x(), pc.y(), pc.z());
+      Draw_String(str);
+    }
+  }
+}
 
-class drawMeshGFace
+template<class T>
+void drawNormals(GEntity *e, std::vector<T*> elements)
 {
-public :
+  for(unsigned int i = 0; i < elements.size(); i++){
+    SVector3 n = elements[i]->getFace(0).normal();
+    for(int j = 0; j < 3; j++)
+      n[j] *= CTX.mesh.normals * CTX.pixel_equiv_x / CTX.s[j];
+    SPoint3 pc = elements[i]->barycenter();
+    glColor4ubv((GLubyte *) & CTX.color.mesh.normals);
+    Draw_Vector(CTX.vector_type, 0, CTX.arrow_rel_head_radius, 
+		CTX.arrow_rel_stem_length, CTX.arrow_rel_stem_radius,
+		pc.x(), pc.y(), pc.z(), n[0], n[1], n[2], CTX.mesh.light);
+  }
+}
+
+class initSmoothNormalsGFace {
+ private:
+  template<class T>
+  void _addNormals(GFace *f, std::vector<T*> elements)
+  {
+    for(unsigned int i = 0; i < elements.size(); i++){
+      for(int j = 0; j < elements[i]->getNumFacesRep(); j++){
+	MFace fr = elements[i]->getFaceRep(j);
+	SVector3 n = fr.normal();
+	SPoint3 pc;
+	if(CTX.mesh.explode != 1.) pc = elements[i]->barycenter();
+	for(int k = 0; k < fr.getNumVertices(); k++){
+	  MVertex *v = fr.getVertex(k);
+	  SPoint3 p(v->x(), v->y(), v->z());
+	  if(CTX.mesh.explode != 1.){
+	    for(int l = 0; l < 3; l++)
+	      p[l] = pc[l] + CTX.mesh.explode * (p[l] - pc[l]);
+	  }
+	  f->model()->normals->add(p[0], p[1], p[2], n[0], n[1], n[2]);
+	}
+      }
+    }
+  }
+ public :
   void operator () (GFace *f)
-  {  
+  {
+    _addNormals(f, f->triangles);
+    _addNormals(f, f->quadrangles);
+  }
+};
+
+class initMeshGFace {
+ private:
+  template<class T>
+  void _addInArray(GFace *f, VertexArray *va, std::vector<T*> elements)
+  {
+    for(unsigned int i = 0; i < elements.size(); i++){
+      int part = elements[i]->getPartition();
+      if(CTX.mesh.quality_sup && CTX.mesh.quality_type == 2) {
+	double q = elements[i]->rhoShapeMeasure();
+	if(q < CTX.mesh.quality_inf || q > CTX.mesh.quality_sup) continue;
+      }
+      if(CTX.mesh.radius_sup) {
+	double r = elements[i]->maxEdge();
+	if(r < CTX.mesh.radius_inf || r > CTX.mesh.radius_sup) continue;
+      }
+      if(CTX.mesh.use_cut_plane && !CTX.mesh.cut_plane_only_volume){
+	if(intersectCutPlane(elements[i]) < 0) continue;
+      }
+      for(int j = 0; j < elements[i]->getNumFacesRep(); j++){
+	MFace fr = elements[i]->getFaceRep(j);
+	SVector3 n = fr.normal();
+	SPoint3 pc;
+	if(CTX.mesh.explode != 1.) pc = elements[i]->barycenter();
+	for(int k = 0; k < fr.getNumVertices(); k++){
+	  MVertex *v = fr.getVertex(k);
+	  SPoint3 p(v->x(), v->y(), v->z());
+	  if(CTX.mesh.explode != 1.){
+	    for(int l = 0; l < 3; l++)
+	      p[l] = pc[l] + CTX.mesh.explode * (p[l] - pc[l]);
+	  }
+	  if(CTX.mesh.smooth_normals)
+	    f->model()->normals->get(p[0], p[1], p[2], n[0], n[1], n[2]);
+	  va->add(p[0], p[1], p[2], n[0], n[1], n[2],
+		  CTX.color.mesh.carousel[abs(part % 20)]);
+	}
+      }
+    }
+  }
+ public :
+  void operator () (GFace *f)
+  {
     if(!f->getVisibility())
       return;
-    
-    if(CTX.render_mode == GMSH_SELECT) {
-      glPushName(2);
-      glPushName(f->tag());
-    }
 
+    if(!f->meshRep)
+      f->meshRep = new MRepFace(f);
 
+    if(f->meshRep->va_lines) delete f->meshRep->va_lines;
+    f->meshRep->va_lines = new VertexArray(2, f->meshRep->edges.size());
 
-#if 0
-    static int first = 1;
-    static List_T *xyz;
-    static std::vector<List_T*> idx, idx2;
+    if(f->meshRep->va_triangles) delete f->meshRep->va_triangles;
+    f->meshRep->va_triangles = new VertexArray(3, f->triangles.size());
 
-    if(first){
-      first = 0;
-      printf("stripe surface %d\n", f->tag());
-      xyz = List_Create(f->mesh_vertices.size(), 1000, sizeof(float));
-      renumberFaceVertices(f, xyz);
+    if(f->meshRep->va_quads) delete f->meshRep->va_quads;
+    f->meshRep->va_quads = new VertexArray(4, f->quadrangles.size());
 
-      /*
-      for(int i = 0; i < List_Nbr(xyz)/3; i+=3){
-	float x, y, z;
-	List_Read(xyz, i, &x);
-	List_Read(xyz, i+1, &y);
-	List_Read(xyz, i+2, &z);
-	printf("xyz = %f %f %f\n", x, y, z);
-      }
-      */
-      ACTCData *tc = actcNew();
-      actcParami(tc, ACTC_OUT_MIN_FAN_VERTS, INT_MAX); // generate only strips
-      //actcParami(tc, ACTC_OUT_MAX_PRIM_VERTS, INT_MAX); // optimum 12?
-      actcParami(tc, ACTC_OUT_MAX_PRIM_VERTS, 100); // optimum 12?
-      actcBeginInput(tc);
-      for(unsigned int i = 0; i < f->triangles.size(); i++){
-	actcAddTriangle(tc, 
-			f->triangles[i]->getVertex(0)->getNum(),
-			f->triangles[i]->getVertex(1)->getNum(),
-			f->triangles[i]->getVertex(2)->getNum());
-      }
-      actcEndInput(tc);
-      actcBeginOutput(tc);
-      int strip, prim;
-      unsigned int v1, v2, v3;
-      strip = 0;
-      while((prim = actcStartNextPrim(tc, &v1, &v2)) != ACTC_DATABASE_EMPTY) {
-	strip++;
-#ifdef ELEM
-	idx.push_back(List_Create(100, 100, sizeof(unsigned int)));
-	List_Add(idx[strip - 1], &v1);
-	List_Add(idx[strip - 1], &v2);
-#else
-	idx2.push_back(List_Create(100, 100, sizeof(float)));
-	List_Add(idx2[strip - 1], List_Pointer_Fast(xyz, 3*v1));
-	List_Add(idx2[strip - 1], List_Pointer_Fast(xyz, 3*v1+1));
-	List_Add(idx2[strip - 1], List_Pointer_Fast(xyz, 3*v1+2));
-	List_Add(idx2[strip - 1], List_Pointer_Fast(xyz, 3*v2));
-	List_Add(idx2[strip - 1], List_Pointer_Fast(xyz, 3*v2+1));
-	List_Add(idx2[strip - 1], List_Pointer_Fast(xyz, 3*v2+2));
-#endif
-	while(actcGetNextVert(tc, &v3) != ACTC_PRIM_COMPLETE){
-#ifdef ELEM
-	  List_Add(idx[strip - 1], &v3);
-#else
-	  List_Add(idx2[strip - 1], List_Pointer_Fast(xyz, 3*v3));
-	  List_Add(idx2[strip - 1], List_Pointer_Fast(xyz, 3*v3+1));
-	  List_Add(idx2[strip - 1], List_Pointer_Fast(xyz, 3*v3+2));
-#endif
+    bool useEdges = true;
+
+    if(CTX.mesh.explode != 1. || CTX.mesh.quality_sup || CTX.mesh.radius_sup || 
+       CTX.mesh.use_cut_plane)
+      useEdges = false;
+
+    for(unsigned int i = 0; i < f->triangles.size(); i++){
+      if(!f->triangles[i]->getVisibility()){ useEdges = false; break; }
+    }
+    for(unsigned int i = 0; i < f->quadrangles.size(); i++){
+      if(!f->quadrangles[i]->getVisibility()){ useEdges = false; break; }
+    }
+    
+    if(useEdges) f->meshRep->generateEdges();
+
+    // TODO: further optimizations are possible when useEdges is true:
+    //
+    // 1) store the unique vertices in the vertex array and
+    //    glDrawElements() instead of glDrawArrays().
+    // 2) we can use tc to stripe the triangle to create strips
+
+    if(useEdges && CTX.mesh.surfaces_edges){
+      std::set<MEdge>::const_iterator it = f->meshRep->edges.begin();
+      for(; it != f->meshRep->edges.end(); ++it){
+	for(int i = 0; i < 2; i++){
+	  MVertex *v = it->getVertex(i);
+	  MElement *e = it->getElement();
+	  SVector3 n = e->getFace(0).normal();
+	  int part = e->getPartition();
+	  if(CTX.mesh.smooth_normals)
+	    f->model()->normals->get(v->x(), v->y(), v->z(), n[0], n[1], n[2]);
+	  f->meshRep->va_lines->add(v->x(), v->y(), v->z(), n[0], n[1], n[2],
+				    CTX.color.mesh.carousel[abs(part % 20)]);
 	}
       }
-      actcEndOutput(tc);
-      actcDelete(tc);
-      printf("stripe end\n");
-
     }
 
-    glEnableClientState(GL_VERTEX_ARRAY);
-#ifdef ELEM
-    glVertexPointer(3, GL_FLOAT, 0, xyz->array);
-    for(unsigned int i = 0; i < idx.size(); i++){
-      //printf("strip %d\n", i);
-      int n = List_Nbr(idx[i]);
-      glColor4ubv((GLubyte *)&CTX.color.mesh.carousel[i % 20]);
-      glDrawElements(GL_TRIANGLE_STRIP, n, GL_UNSIGNED_INT, idx[i]->array);
+    if(CTX.mesh.surfaces_faces || (!useEdges && CTX.mesh.surfaces_edges)){
+      _addInArray(f, f->meshRep->va_triangles, f->triangles);
+      _addInArray(f, f->meshRep->va_triangles, f->quadrangles);
     }
-#else
-    for(unsigned int i = 0; i < idx2.size(); i++){
-      //printf("strip %d\n", i);
-      int n = List_Nbr(idx2[i]);
-      glVertexPointer(3, GL_FLOAT, 0, idx2[i]->array);
-      glColor4ubv((GLubyte *)&CTX.color.mesh.carousel[i % 20]);
-      glDrawArrays(GL_TRIANGLE_STRIP, 0, n / 3);
+  }
+};
+
+class drawMeshGFace {
+ public:
+  void operator () (GFace *f)
+  {  
+    if(!f->getVisibility())
+      return;
+    
+    if(CTX.render_mode == GMSH_SELECT) {
+      glPushName(2);
+      glPushName(f->tag());
     }
-#endif
-    glDisableClientState(GL_VERTEX_ARRAY);
 
+    MRep *m = f->meshRep;
 
-#endif
+    if(CTX.mesh.surfaces_edges){
+      if(m->va_lines->n())
+	drawArrays(m->va_lines, GL_LINES, CTX.mesh.color_carousel == 3, 
+		   CTX.mesh.light && CTX.mesh.light_lines, false, 
+		   getColor(f, CTX.mesh.surfaces_faces, CTX.color.mesh.line));
+      else
+	drawArrays(m->va_triangles, GL_TRIANGLES, CTX.mesh.color_carousel == 3, 
+		   CTX.mesh.light && CTX.mesh.light_lines, false, 
+		   getColor(f, CTX.mesh.surfaces_faces, CTX.color.mesh.line), true);
+    }
+    
+    if(CTX.mesh.surfaces_faces){
+      drawArrays(m->va_triangles, GL_TRIANGLES, CTX.mesh.color_carousel == 3, 
+		 CTX.mesh.light, CTX.polygon_offset, 
+		 getColor(f, 0, CTX.color.mesh.triangle));
+      drawArrays(m->va_quads, GL_TRIANGLES, CTX.mesh.color_carousel == 3, 
+		 CTX.mesh.light, CTX.polygon_offset, 
+		 getColor(f, 0, CTX.color.mesh.quadrangle));
+    }
 
-    unsigned int col;
-    if(f->getFlag() > 0){
-      col = CTX.color.geom.surface_sel;
+    if(CTX.mesh.surfaces_num) {
+      int numLabels = f->triangles.size() + f->quadrangles.size();
+      int numLabelsDisplayed = 0;
+      int stepLabelsDisplayed;
+      if(CTX.mesh.label_frequency == 0.0) stepLabelsDisplayed = numLabels;
+      else stepLabelsDisplayed = (int)(100.0 / CTX.mesh.label_frequency);
+      if(stepLabelsDisplayed > numLabels) stepLabelsDisplayed = numLabels;
+      drawLabels(f, f->triangles, stepLabelsDisplayed, numLabelsDisplayed,
+		 CTX.mesh.surfaces_faces, CTX.color.mesh.line);
+      drawLabels(f, f->quadrangles, stepLabelsDisplayed, numLabelsDisplayed,
+		 CTX.mesh.surfaces_faces, CTX.color.mesh.line);
     }
-    else if(CTX.mesh.color_carousel == 1){
-      col = CTX.color.mesh.carousel[abs(f->tag() % 20)];
+
+    if(CTX.mesh.normals) {
+      drawNormals(f, f->triangles);
+      drawNormals(f, f->quadrangles);
     }
-    else if(CTX.mesh.color_carousel == 2){
-      int n = 1;
-      int np = f->physicals.size();
-      if(np) n = f->physicals[np - 1];
-      col = CTX.color.mesh.carousel[abs(n % 20)];
+
+    if(CTX.render_mode == GMSH_SELECT) {
+      glPopName();
+      glPopName();
     }
-    else if(CTX.mesh.color_carousel == 3){
-      // partition
+  }
+};
+
+class initMeshGRegion {
+ public :
+  void operator () (GRegion *r)
+  {  
+    if(!r->meshRep) 
+      r->meshRep = new MRepRegion(r);
+    if(CTX.mesh.volumes_edges)
+      r->meshRep->generateEdges();
+  
+  }
+};
+
+class drawMeshGRegion {
+ public :
+  void operator () (GRegion *r)
+  {  
+    if(!r->getVisibility())
+      return;
+
+    if(CTX.render_mode == GMSH_SELECT) {
+      glPushName(3);
+      glPushName(r->tag());
     }
-    else
-      col = CTX.color.mesh.triangle;
-    glColor4ubv((GLubyte *)&col);
 
-    glBegin(GL_TRIANGLES);
-    for(unsigned int i = 0; i < f->triangles.size(); i++){
-      MTriangle *t = f->triangles[i];
-      for(int j = 0; j < 3; j++){
-	MVertex *v = t->getVertex(j);
-	glVertex3d(v->x(), v->y(), v->z());
+    if(CTX.mesh.volumes_edges){
+      glBegin(GL_LINES);
+      for(std::set<MEdge>::const_iterator it = r->meshRep->edges.begin(); 
+	  it != r->meshRep->edges.end(); ++it){
+	MVertex *v0 = it->getVertex(0), *v1 = it->getVertex(1);
+	glVertex3d(v0->x(), v0->y(), v0->z());
+	glVertex3d(v1->x(), v1->y(), v1->z());
       }
+      glEnd();
     }
-    glEnd();
 
     if(CTX.render_mode == GMSH_SELECT) {
       glPopName();
@@ -206,6 +385,7 @@ public :
   }
 };
 
+
 void Draw_Mesh()
 {
   if(!CTX.mesh.draw) return;
@@ -227,18 +407,29 @@ void Draw_Mesh()
     else
       glDisable((GLenum)(GL_CLIP_PLANE0 + i));
   
-  /*
-  if(CTX.mesh.changed){
-    if(GMODEL->normals) delete GMODEL->normals;
-    GMODEL->normals = new smooth_normals(CTX.mesh.angle_smooth_normals);
-  }
-  */
+  if(!CTX.threads_lock){
+    CTX.threads_lock = 1; 
+
+    if(CTX.mesh.changed) {
+      if(CTX.mesh.smooth_normals){
+	if(GMODEL->normals) delete GMODEL->normals;
+	GMODEL->normals = new smooth_normals(CTX.mesh.angle_smooth_normals);
+	std::for_each(GMODEL->firstFace(), GMODEL->lastFace(), initSmoothNormalsGFace());
+      }
+      std::for_each(GMODEL->firstFace(), GMODEL->lastFace(), initMeshGFace());
+      std::for_each(GMODEL->firstRegion(), GMODEL->lastRegion(), initMeshGRegion());
+    }
+    
+    if(CTX.mesh.surfaces_faces || CTX.mesh.surfaces_edges)
+      std::for_each(GMODEL->firstFace(), GMODEL->lastFace(), drawMeshGFace());
+    
+    if(CTX.mesh.volumes_faces || CTX.mesh.volumes_edges)
+      std::for_each(GMODEL->firstRegion(), GMODEL->lastRegion(), drawMeshGRegion());
 
-  if(CTX.mesh.surfaces_faces || CTX.mesh.surfaces_edges)
-    std::for_each(GMODEL->firstFace(), GMODEL->lastFace(), drawMeshGFace());
+    CTX.mesh.changed = 0;
+    CTX.threads_lock = 0;
+  }
 
-  CTX.mesh.changed = 0;
-  
   for(int i = 0; i < 6; i++)
     glDisable((GLenum)(GL_CLIP_PLANE0 + i));
 }
diff --git a/Graphics/Post.cpp b/Graphics/Post.cpp
index 3691fa7b57..bb1f7a877b 100644
--- a/Graphics/Post.cpp
+++ b/Graphics/Post.cpp
@@ -1,4 +1,4 @@
-// $Id: Post.cpp,v 1.107 2006-08-07 22:02:30 geuzaine Exp $
+// $Id: Post.cpp,v 1.108 2006-08-15 02:17:26 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -783,16 +783,16 @@ void Draw_Post(void)
 
       pass_1:
 	if(v->TriVertexArray && v->TriVertexArray->fill){
-	  Msg(DEBUG, "View[%d]; %d tris in vertex array", v->Index, v->TriVertexArray->num);
+	  Msg(DEBUG, "View[%d]; %d tris in vertex array", v->Index, v->TriVertexArray->n()/3);
 	  v->TriVertexArray->fill = 0;
 	}
 	if(v->LinVertexArray && v->LinVertexArray->fill){
-	  Msg(DEBUG, "View[%d]; %d segs in vertex array", v->Index, v->LinVertexArray->num);
+	  Msg(DEBUG, "View[%d]; %d segs in vertex array", v->Index, v->LinVertexArray->n()/2);
 	  v->LinVertexArray->fill = 0;
 	}
       }
 
-      if(v->TriVertexArray && v->TriVertexArray->num){
+      if(v->TriVertexArray && v->TriVertexArray->n()){
 	if(CTX.alpha && ColorTable_IsAlpha(&v->CT) && !v->FakeTransparency &&
 	   (changedEye() || v->Changed)){
 	  Msg(DEBUG, "Sorting View[%d] for transparency (WITH vertex array)", v->Index);
@@ -812,7 +812,7 @@ void Draw_Post(void)
 	else
 	  glDisableClientState(GL_NORMAL_ARRAY);
 	if(CTX.polygon_offset) glEnable(GL_POLYGON_OFFSET_FILL);
-	glDrawArrays(GL_TRIANGLES, 0, 3 * v->TriVertexArray->num);
+	glDrawArrays(GL_TRIANGLES, 0, v->TriVertexArray->n());
 	glDisable(GL_POLYGON_OFFSET_FILL);
 	glDisable(GL_LIGHTING);
       
@@ -821,12 +821,12 @@ void Draw_Post(void)
 	glDisableClientState(GL_NORMAL_ARRAY);
       }
 
-      if(v->LinVertexArray && v->LinVertexArray->num){
+      if(v->LinVertexArray && v->LinVertexArray->n()){
 	glVertexPointer(3, GL_FLOAT, 0, v->LinVertexArray->vertices->array);
 	glColorPointer(4, GL_UNSIGNED_BYTE, 0, v->LinVertexArray->colors->array);
 	glEnableClientState(GL_VERTEX_ARRAY);
 	glEnableClientState(GL_COLOR_ARRAY);
-	glDrawArrays(GL_LINES, 0, 2 * v->LinVertexArray->num);
+	glDrawArrays(GL_LINES, 0, v->LinVertexArray->n());
 	glDisableClientState(GL_VERTEX_ARRAY);
 	glDisableClientState(GL_COLOR_ARRAY);
       }
diff --git a/Graphics/PostElement.cpp b/Graphics/PostElement.cpp
index cab2655ec5..61457d7f69 100644
--- a/Graphics/PostElement.cpp
+++ b/Graphics/PostElement.cpp
@@ -1,4 +1,4 @@
-// $Id: PostElement.cpp,v 1.75 2006-08-07 22:02:30 geuzaine Exp $
+// $Id: PostElement.cpp,v 1.76 2006-08-15 02:17:26 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -464,7 +464,6 @@ void Draw_ScalarTriangle(Post_View * View, int preproNormals,
 	  View->TriVertexArray->add(X[i], Y[i], Z[i], 
 				    norms[3*i], norms[3*i+1], norms[3*i+2], col);
 	}
-	View->TriVertexArray->num++;
       }
       else{
 	if(View->Light) glEnable(GL_LIGHTING);
@@ -509,7 +508,6 @@ void Draw_ScalarTriangle(Post_View * View, int preproNormals,
 	    col = PaletteContinuous(View, ValMin, ValMax, Vp[i]);
 	    View->TriVertexArray->add(Xp[i], Yp[i], Zp[i], 
 				      norms[3*i], norms[3*i+1], norms[3*i+2], col);
-	    View->TriVertexArray->num++;	    
 	  }
 	}
 	else{
@@ -563,7 +561,6 @@ void Draw_ScalarTriangle(Post_View * View, int preproNormals,
 					norms[3*(i-1)], norms[3*(i-1)+1], norms[3*(i-1)+2], col);
 	      View->TriVertexArray->add(Xp[i], Yp[i], Zp[i],
 					norms[3*i], norms[3*i+1], norms[3*i+2], col);
-	      View->TriVertexArray->num++;
 	    }
 	  }
 	  else{
diff --git a/Mesh/Makefile b/Mesh/Makefile
index 027a95758c..9128092b78 100644
--- a/Mesh/Makefile
+++ b/Mesh/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.118 2006-08-12 19:34:16 geuzaine Exp $
+# $Id: Makefile,v 1.119 2006-08-15 02:17:26 geuzaine Exp $
 #
 # Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 #
@@ -351,9 +351,10 @@ Generator.o: Generator.cpp ../Common/Gmsh.h ../Common/Message.h \
   meshGEdge.h meshGFace.h ../Geo/SPoint2.h ../Geo/GModel.h \
   ../Geo/GVertex.h ../Geo/GEntity.h ../Geo/Range.h ../Geo/SPoint3.h \
   ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../Geo/MVertex.h \
-  ../Geo/SPoint3.h ../Geo/MVertex.h ../Geo/GPoint.h ../Geo/GEdge.h \
-  ../Geo/GEntity.h ../Geo/GVertex.h ../Geo/SVector3.h ../Geo/SPoint3.h \
-  ../Geo/SPoint3.h ../Geo/SPoint2.h ../Geo/MElement.h ../Geo/MVertex.h \
+  ../Geo/SPoint3.h ../Geo/GPoint.h ../Geo/GEdge.h ../Geo/GEntity.h \
+  ../Geo/GVertex.h ../Geo/SVector3.h ../Geo/SPoint3.h ../Geo/SPoint3.h \
+  ../Geo/SPoint2.h ../Geo/MElement.h ../Geo/MVertex.h ../Geo/MEdge.h \
+  ../Geo/MVertex.h ../Geo/MFace.h ../Geo/MVertex.h ../Geo/SVector3.h \
   ../Geo/GFace.h ../Geo/GPoint.h ../Geo/GEntity.h ../Geo/MElement.h \
   ../Geo/SPoint2.h ../Geo/SVector3.h ../Geo/Pair.h ../Geo/GRegion.h \
   ../Geo/GEntity.h ../Geo/MElement.h ../Geo/SBoundingBox3d.h
@@ -403,28 +404,30 @@ Metric.o: Metric.cpp ../Common/Gmsh.h ../Common/Message.h \
 # 1 "/Users/geuzaine/.gmsh/Mesh//"
 meshGEdge.o: meshGEdge.cpp meshGEdge.h ../Geo/GEdge.h ../Geo/GEntity.h \
   ../Geo/Range.h ../Geo/SPoint3.h ../Geo/SBoundingBox3d.h \
-  ../Geo/SPoint3.h ../Geo/MVertex.h ../Geo/SPoint3.h \
-  ../Common/GmshDefines.h ../Geo/GVertex.h ../Geo/GEntity.h \
-  ../Geo/MVertex.h ../Geo/GPoint.h ../Geo/SVector3.h ../Geo/SPoint3.h \
-  ../Geo/SPoint3.h ../Geo/SPoint2.h ../Geo/MElement.h ../Geo/MVertex.h \
-  ../Numeric/Numeric.h ../Common/Gmsh.h ../Common/Message.h \
-  ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
-  ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
-  Utils.h Vertex.h Mesh.h Element.h Simplex.h Face.h Edge.h \
-  ../Geo/ExtrudeParams.h Metric.h Matrix.h ../Common/Context.h
+  ../Geo/SPoint3.h ../Common/GmshDefines.h ../Geo/GVertex.h \
+  ../Geo/GEntity.h ../Geo/MVertex.h ../Geo/SPoint3.h ../Geo/GPoint.h \
+  ../Geo/SVector3.h ../Geo/SPoint3.h ../Geo/SPoint3.h ../Geo/SPoint2.h \
+  ../Geo/MElement.h ../Geo/MVertex.h ../Geo/MEdge.h ../Geo/MVertex.h \
+  ../Geo/MFace.h ../Geo/MVertex.h ../Geo/SVector3.h ../Numeric/Numeric.h \
+  ../Common/Gmsh.h ../Common/Message.h ../DataStr/Malloc.h \
+  ../DataStr/List.h ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h \
+  ../DataStr/List.h ../DataStr/Tree.h Utils.h Vertex.h Mesh.h Element.h \
+  Simplex.h Face.h Edge.h ../Geo/ExtrudeParams.h Metric.h Matrix.h \
+  ../Common/Context.h
 # 1 "/Users/geuzaine/.gmsh/Mesh//"
 meshGFace.o: meshGFace.cpp meshGFace.h ../Geo/SPoint2.h ../Geo/GVertex.h \
   ../Geo/GEntity.h ../Geo/Range.h ../Geo/SPoint3.h \
-  ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../Geo/MVertex.h \
-  ../Geo/SPoint3.h ../Common/GmshDefines.h ../Geo/MVertex.h \
-  ../Geo/GPoint.h 2D_Mesh.h ../DataStr/List.h ../DataStr/Tree.h \
-  ../DataStr/avl.h Mesh.h Vertex.h Element.h Simplex.h Face.h Edge.h \
-  ../Geo/ExtrudeParams.h Metric.h Matrix.h ../Geo/GEdge.h \
-  ../Geo/GEntity.h ../Geo/GVertex.h ../Geo/SVector3.h ../Geo/SPoint3.h \
-  ../Geo/SPoint3.h ../Geo/SPoint2.h ../Geo/MElement.h ../Geo/MVertex.h \
-  ../Numeric/Numeric.h ../Geo/GFace.h ../Geo/GPoint.h ../Geo/GEntity.h \
-  ../Geo/MElement.h ../Geo/SPoint2.h ../Geo/SVector3.h ../Geo/Pair.h \
-  ../Common/Context.h Utils.h ../Common/Message.h BDS.h ../Common/Views.h \
+  ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../Common/GmshDefines.h \
+  ../Geo/MVertex.h ../Geo/SPoint3.h ../Geo/GPoint.h 2D_Mesh.h \
+  ../DataStr/List.h ../DataStr/Tree.h ../DataStr/avl.h Mesh.h Vertex.h \
+  Element.h Simplex.h Face.h Edge.h ../Geo/ExtrudeParams.h Metric.h \
+  Matrix.h ../Geo/GEdge.h ../Geo/GEntity.h ../Geo/GVertex.h \
+  ../Geo/SVector3.h ../Geo/SPoint3.h ../Geo/SPoint3.h ../Geo/SPoint2.h \
+  ../Geo/MElement.h ../Geo/MVertex.h ../Geo/MEdge.h ../Geo/MVertex.h \
+  ../Geo/MFace.h ../Geo/MVertex.h ../Geo/SVector3.h ../Numeric/Numeric.h \
+  ../Geo/GFace.h ../Geo/GPoint.h ../Geo/GEntity.h ../Geo/MElement.h \
+  ../Geo/SPoint2.h ../Geo/SVector3.h ../Geo/Pair.h ../Common/Context.h \
+  Utils.h ../Common/Message.h BDS.h ../Common/Views.h \
   ../Common/ColorTable.h ../Common/VertexArray.h \
   ../Common/SmoothNormals.h ../Common/GmshMatrix.h \
   ../Common/AdaptiveViews.h ../Common/GmshMatrix.h
diff --git a/Parser/Makefile b/Parser/Makefile
index 103ddf43fe..4a530abafc 100644
--- a/Parser/Makefile
+++ b/Parser/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.96 2006-08-13 02:46:53 geuzaine Exp $
+# $Id: Makefile,v 1.97 2006-08-15 02:17:27 geuzaine Exp $
 #
 # Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 #
@@ -112,25 +112,27 @@ OpenFile.o: OpenFile.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
   ../Geo/gmshModel.h ../Geo/GModel.h ../Geo/GVertex.h ../Geo/GEntity.h \
   ../Geo/Range.h ../Geo/SPoint3.h ../Geo/SBoundingBox3d.h \
-  ../Geo/SPoint3.h ../Geo/MVertex.h ../Geo/SPoint3.h \
-  ../Common/GmshDefines.h ../Geo/MVertex.h ../Geo/GPoint.h ../Geo/GEdge.h \
-  ../Geo/GEntity.h ../Geo/GVertex.h ../Geo/SVector3.h ../Geo/SPoint3.h \
-  ../Geo/SPoint3.h ../Geo/SPoint2.h ../Geo/MElement.h ../Geo/MVertex.h \
+  ../Geo/SPoint3.h ../Common/GmshDefines.h ../Geo/MVertex.h \
+  ../Geo/SPoint3.h ../Geo/GPoint.h ../Geo/GEdge.h ../Geo/GEntity.h \
+  ../Geo/GVertex.h ../Geo/SVector3.h ../Geo/SPoint3.h ../Geo/SPoint3.h \
+  ../Geo/SPoint2.h ../Geo/MElement.h ../Geo/MVertex.h ../Geo/MEdge.h \
+  ../Geo/MVertex.h ../Geo/MFace.h ../Geo/MVertex.h ../Geo/SVector3.h \
   ../Numeric/Numeric.h ../Geo/GFace.h ../Geo/GPoint.h ../Geo/GEntity.h \
   ../Geo/MElement.h ../Geo/SPoint2.h ../Geo/SVector3.h ../Geo/Pair.h \
   ../Geo/GRegion.h ../Geo/GEntity.h ../Geo/MElement.h \
-  ../Geo/SBoundingBox3d.h ../Common/Context.h Parser.h OpenFile.h \
-  ../Common/CommandLine.h ../Common/Views.h ../Common/ColorTable.h \
-  ../Common/VertexArray.h ../Common/SmoothNormals.h \
-  ../Common/GmshMatrix.h ../Common/AdaptiveViews.h ../Common/GmshMatrix.h \
-  ../Mesh/Mesh.h ../Mesh/Vertex.h ../Mesh/Element.h ../Mesh/Vertex.h \
-  ../Mesh/Simplex.h ../Mesh/Vertex.h ../Mesh/Element.h ../Mesh/Face.h \
-  ../Mesh/Vertex.h ../Mesh/Element.h ../Mesh/Edge.h ../Mesh/Vertex.h \
-  ../Mesh/Simplex.h ../Geo/ExtrudeParams.h ../Mesh/Metric.h \
-  ../Mesh/Vertex.h ../Mesh/Simplex.h ../Mesh/Mesh.h ../Mesh/Matrix.h \
-  ../Graphics/ReadImg.h ../Common/OS.h ../Common/GmshUI.h \
-  ../Graphics/Draw.h ../Fltk/GUI.h ../Fltk/Opengl_Window.h \
-  ../Fltk/Colorbar_Window.h ../Fltk/Popup_Button.h
+  ../Geo/SBoundingBox3d.h ../Common/SmoothNormals.h ../Common/Context.h \
+  Parser.h OpenFile.h ../Common/CommandLine.h ../Common/Views.h \
+  ../Common/ColorTable.h ../Common/VertexArray.h \
+  ../Common/SmoothNormals.h ../Common/GmshMatrix.h \
+  ../Common/AdaptiveViews.h ../Common/GmshMatrix.h ../Mesh/Mesh.h \
+  ../Mesh/Vertex.h ../Mesh/Element.h ../Mesh/Vertex.h ../Mesh/Simplex.h \
+  ../Mesh/Vertex.h ../Mesh/Element.h ../Mesh/Face.h ../Mesh/Vertex.h \
+  ../Mesh/Element.h ../Mesh/Edge.h ../Mesh/Vertex.h ../Mesh/Simplex.h \
+  ../Geo/ExtrudeParams.h ../Mesh/Metric.h ../Mesh/Vertex.h \
+  ../Mesh/Simplex.h ../Mesh/Mesh.h ../Mesh/Matrix.h ../Graphics/ReadImg.h \
+  ../Common/OS.h ../Common/GmshUI.h ../Graphics/Draw.h ../Fltk/GUI.h \
+  ../Fltk/Opengl_Window.h ../Fltk/Colorbar_Window.h \
+  ../Fltk/Popup_Button.h
 # 1 "/Users/geuzaine/.gmsh/Parser//"
 CreateFile.o: CreateFile.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
@@ -138,14 +140,15 @@ CreateFile.o: CreateFile.cpp ../Common/Gmsh.h ../Common/Message.h \
   OpenFile.h ../Common/Context.h ../Common/Options.h ../Geo/Geo.h \
   ../Geo/GModel.h ../Geo/GVertex.h ../Geo/GEntity.h ../Geo/Range.h \
   ../Geo/SPoint3.h ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h \
-  ../Geo/MVertex.h ../Geo/SPoint3.h ../Common/GmshDefines.h \
-  ../Geo/MVertex.h ../Geo/GPoint.h ../Geo/GEdge.h ../Geo/GEntity.h \
-  ../Geo/GVertex.h ../Geo/SVector3.h ../Geo/SPoint3.h ../Geo/SPoint3.h \
-  ../Geo/SPoint2.h ../Geo/MElement.h ../Geo/MVertex.h \
-  ../Numeric/Numeric.h ../Geo/GFace.h ../Geo/GPoint.h ../Geo/GEntity.h \
-  ../Geo/MElement.h ../Geo/SPoint2.h ../Geo/SVector3.h ../Geo/Pair.h \
-  ../Geo/GRegion.h ../Geo/GEntity.h ../Geo/MElement.h \
-  ../Geo/SBoundingBox3d.h ../Common/GmshUI.h ../Graphics/gl2ps.h \
+  ../Common/GmshDefines.h ../Geo/MVertex.h ../Geo/SPoint3.h \
+  ../Geo/GPoint.h ../Geo/GEdge.h ../Geo/GEntity.h ../Geo/GVertex.h \
+  ../Geo/SVector3.h ../Geo/SPoint3.h ../Geo/SPoint3.h ../Geo/SPoint2.h \
+  ../Geo/MElement.h ../Geo/MVertex.h ../Geo/MEdge.h ../Geo/MVertex.h \
+  ../Geo/MFace.h ../Geo/MVertex.h ../Geo/SVector3.h ../Numeric/Numeric.h \
+  ../Geo/GFace.h ../Geo/GPoint.h ../Geo/GEntity.h ../Geo/MElement.h \
+  ../Geo/SPoint2.h ../Geo/SVector3.h ../Geo/Pair.h ../Geo/GRegion.h \
+  ../Geo/GEntity.h ../Geo/MElement.h ../Geo/SBoundingBox3d.h \
+  ../Common/SmoothNormals.h ../Common/GmshUI.h ../Graphics/gl2ps.h \
   ../Graphics/gl2gif.h ../Graphics/PixelBuffer.h ../Graphics/Draw.h \
   ../Common/Views.h ../Common/ColorTable.h ../Common/VertexArray.h \
   ../Common/SmoothNormals.h ../Common/GmshMatrix.h \
-- 
GitLab