diff --git a/Fltk/Callbacks.cpp b/Fltk/Callbacks.cpp
index ad562b6ff7294dca9b5e5da7639473030ebe98df..997b39fd5672e4717fb129d2167c9c3488588931 100644
--- a/Fltk/Callbacks.cpp
+++ b/Fltk/Callbacks.cpp
@@ -1,4 +1,4 @@
-// $Id: Callbacks.cpp,v 1.444 2006-08-19 19:46:07 geuzaine Exp $
+// $Id: Callbacks.cpp,v 1.445 2006-08-20 14:12:40 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -30,6 +30,7 @@
 #include "ExtractContour.h"
 #include "Mesh.h"
 #include "Draw.h"
+#include "SelectBuffer.h"
 #include "Views.h"
 #include "CreateFile.h"
 #include "OpenFile.h"
diff --git a/Fltk/Makefile b/Fltk/Makefile
index f7b13b6416e5d5d702a3d27c3e39ce6cfddcc40b..d7dcd644478fb3627501fb8fb385c7abca126b55 100644
--- a/Fltk/Makefile
+++ b/Fltk/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.101 2006-08-16 17:14:56 geuzaine Exp $
+# $Id: Makefile,v 1.102 2006-08-20 14:12:40 geuzaine Exp $
 #
 # Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 #
@@ -150,22 +150,22 @@ Callbacks.o: Callbacks.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../Graphics/Draw.h ../Common/Views.h ../Common/ColorTable.h \
   ../Common/VertexArray.h ../Common/SmoothNormals.h ../Numeric/Numeric.h \
   ../Common/GmshMatrix.h ../Common/AdaptiveViews.h ../Common/GmshMatrix.h \
-  ../Parser/CreateFile.h ../Parser/OpenFile.h ../Common/CommandLine.h \
-  ../Common/Context.h ../Common/Options.h GUI.h Opengl_Window.h \
-  Colorbar_Window.h Popup_Button.h GUI_Extras.h Callbacks.h \
-  ../Plugin/Plugin.h ../Plugin/PluginManager.h ../Plugin/Plugin.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/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/SVector3.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 ../Geo/GModel.h ../Geo/GVertex.h ../Geo/GEdge.h \
-  ../Geo/GFace.h ../Geo/GRegion.h ../Geo/SBoundingBox3d.h
+  ../Graphics/SelectBuffer.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/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/SVector3.h \
+  ../Geo/MFace.h ../Geo/MVertex.h ../Geo/SVector3.h ../Common/Context.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 ../Parser/CreateFile.h \
+  ../Parser/OpenFile.h ../Common/CommandLine.h ../Common/Options.h GUI.h \
+  Opengl_Window.h Colorbar_Window.h Popup_Button.h GUI_Extras.h \
+  Callbacks.h ../Plugin/Plugin.h ../Plugin/PluginManager.h \
+  ../Plugin/Plugin.h ../Common/Visibility.h ../Common/GmshDefines.h \
+  Solvers.h ../Common/OS.h ../Geo/GModel.h ../Geo/GVertex.h \
+  ../Geo/GEdge.h ../Geo/GFace.h ../Geo/GRegion.h ../Geo/SBoundingBox3d.h
 # 1 "/Users/geuzaine/.gmsh/Fltk//"
 Opengl.o: Opengl.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
@@ -174,14 +174,23 @@ Opengl.o: Opengl.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../Geo/Geo.h ../Graphics/Draw.h ../Common/Views.h \
   ../Common/ColorTable.h ../Common/VertexArray.h \
   ../Common/SmoothNormals.h ../Common/GmshMatrix.h \
-  ../Common/AdaptiveViews.h ../Common/GmshMatrix.h GUI.h Opengl_Window.h \
-  ../Mesh/Mesh.h ../Common/GmshDefines.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 Colorbar_Window.h \
-  Popup_Button.h ../Graphics/gl2ps.h
+  ../Common/AdaptiveViews.h ../Common/GmshMatrix.h \
+  ../Graphics/SelectBuffer.h ../Geo/GVertex.h ../Geo/GEntity.h \
+  ../Geo/Range.h ../Geo/SPoint3.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/SVector3.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 GUI.h \
+  Opengl_Window.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 Colorbar_Window.h Popup_Button.h ../Graphics/gl2ps.h
 # 1 "/Users/geuzaine/.gmsh/Fltk//"
 Opengl_Window.o: Opengl_Window.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
@@ -190,14 +199,23 @@ Opengl_Window.o: Opengl_Window.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../Geo/Geo.h ../Graphics/Draw.h ../Common/Views.h \
   ../Common/ColorTable.h ../Common/VertexArray.h \
   ../Common/SmoothNormals.h ../Common/GmshMatrix.h \
-  ../Common/AdaptiveViews.h ../Common/GmshMatrix.h GUI.h Opengl_Window.h \
-  ../Mesh/Mesh.h ../Common/GmshDefines.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 Colorbar_Window.h \
-  Popup_Button.h
+  ../Common/AdaptiveViews.h ../Common/GmshMatrix.h \
+  ../Graphics/SelectBuffer.h ../Geo/GVertex.h ../Geo/GEntity.h \
+  ../Geo/Range.h ../Geo/SPoint3.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/SVector3.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 GUI.h \
+  Opengl_Window.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 Colorbar_Window.h Popup_Button.h
 # 1 "/Users/geuzaine/.gmsh/Fltk//"
 Colorbar_Window.o: Colorbar_Window.cpp ../Common/Gmsh.h \
   ../Common/Message.h ../DataStr/Malloc.h ../DataStr/List.h \
diff --git a/Fltk/Opengl.cpp b/Fltk/Opengl.cpp
index f388de855e830f6e6c45a26951d9d62745bf4a46..df8ee63ca5bc88a599a9c1bc9ff946f155d0f9ca 100644
--- a/Fltk/Opengl.cpp
+++ b/Fltk/Opengl.cpp
@@ -1,4 +1,4 @@
-// $Id: Opengl.cpp,v 1.65 2006-08-19 01:12:39 geuzaine Exp $
+// $Id: Opengl.cpp,v 1.66 2006-08-20 14:12:40 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -25,6 +25,7 @@
 #include "Context.h"
 #include "Geo.h"
 #include "Draw.h"
+#include "SelectBuffer.h"
 #include "GUI.h"
 #include "gl2ps.h"
 
diff --git a/Fltk/Opengl_Window.cpp b/Fltk/Opengl_Window.cpp
index 285f11a4b5b6cdea4f3b8714b62a347d5a4e8318..da374fba140056a01bcb3f582944f94538af026d 100644
--- a/Fltk/Opengl_Window.cpp
+++ b/Fltk/Opengl_Window.cpp
@@ -1,4 +1,4 @@
-// $Id: Opengl_Window.cpp,v 1.67 2006-08-19 01:12:39 geuzaine Exp $
+// $Id: Opengl_Window.cpp,v 1.68 2006-08-20 14:12:40 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -25,6 +25,7 @@
 #include "Context.h"
 #include "Geo.h"
 #include "Draw.h"
+#include "SelectBuffer.h"
 #include "GUI.h"
 #include "Opengl_Window.h"
 
diff --git a/Geo/MFace.h b/Geo/MFace.h
index 8e66da502b22097017ff3043827ea59eb7056e23..b29075fbdca5db4f34a47f1e6038764ca116424b 100644
--- a/Geo/MFace.h
+++ b/Geo/MFace.h
@@ -20,6 +20,7 @@
 // 
 // Please report all bugs and problems to <gmsh@geuz.org>.
 
+#include <vector>
 #include "MVertex.h"
 #include "SVector3.h"
 #include "Numeric.h"
@@ -50,6 +51,12 @@ class MFace {
   }
   inline int getNumVertices() const { return _v[3] ? 4 : 3; }
   inline MVertex *getVertex(int i) const { return _v[i]; }
+  void getOrderedVertices(std::vector<MVertex*> &verts)
+  {
+    for(int i = 0; i < getNumVertices(); i++)
+      verts.push_back(getVertex(i));
+    std::sort(verts.begin(), verts.end());
+  }
   SVector3 normal()
   {
     double n[3];
diff --git a/Geo/MVertex.h b/Geo/MVertex.h
index 86e6584c40435777ff1dc06743e086b491d4fb29..7ed8592523b8756f2cd018c13e71bec0d1dfee6d 100644
--- a/Geo/MVertex.h
+++ b/Geo/MVertex.h
@@ -73,7 +73,7 @@ class MVertex{
   inline void setNum(int num) { _num = num; }
 
   // Get ith parameter
-  bool getParameter(int i, double &par){ return false; }
+  virtual bool getParameter(int i, double &par){ return false; }
 
   // IO routines
   void writeMSH(FILE *fp, bool binary=false, double scalingFactor=1.0);
@@ -93,7 +93,7 @@ class MEdgeVertex : public MVertex{
   {
   }
   ~MEdgeVertex(){}
-  bool getParameter(int i, double &par){ par = _u; return true; }
+  virtual bool getParameter(int i, double &par){ par = _u; return true; }
 };
 
 class MFaceVertex : public MVertex{
@@ -105,7 +105,7 @@ class MFaceVertex : public MVertex{
   {
   }
   ~MFaceVertex(){}
-  bool getParameter(int i, double &par){ par = i ? _v : _u; return true; }
+  virtual bool getParameter(int i, double &par){ par = (i ? _v : _u); return true; }
 };
 
 class MVertexLessThanLexicographic{
diff --git a/Geo/Makefile b/Geo/Makefile
index e5ab20422a6037470927f1a58283120a6e97835b..da9d22b924e90dd7d9ad8f1866ec4de0ffd9d4d3 100644
--- a/Geo/Makefile
+++ b/Geo/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.97 2006-08-19 18:48:06 geuzaine Exp $
+# $Id: Makefile,v 1.98 2006-08-20 14:12:40 geuzaine Exp $
 #
 # Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 #
@@ -207,16 +207,16 @@ gmshFace.o: gmshFace.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 ../Common/Context.h ../DataStr/List.h GFace.h \
-  Pair.h GRegion.h ../Common/SmoothNormals.h gmshEdge.h gmshVertex.h \
-  ../Mesh/Mesh.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
+  Pair.h GRegion.h ../Common/SmoothNormals.h gmshVertex.h ../Mesh/Mesh.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 gmshEdge.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 ../Common/GmshDefines.h MVertex.h \
diff --git a/Graphics/Draw.cpp b/Graphics/Draw.cpp
index cb539563954ac55a68015ec4a594794890ed35f1..8e463b71af5a4d7528301b976b29e9c763e0c587 100644
--- a/Graphics/Draw.cpp
+++ b/Graphics/Draw.cpp
@@ -1,4 +1,4 @@
-// $Id: Draw.cpp,v 1.105 2006-08-19 01:12:39 geuzaine Exp $
+// $Id: Draw.cpp,v 1.106 2006-08-20 14:12:40 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -346,158 +346,6 @@ void InitPosition(void)
     glClipPlane((GLenum)(GL_CLIP_PLANE0 + i), CTX.clip_plane[i]);
 }
 
-// Entity selection routines
-
-class hit{
-public:
-  GLuint type, ient, depth;
-  hit(GLuint t, GLuint i, GLuint d) : type(t), ient(i), depth(d) {}
-};
-
-class hitDepthLessThan{
- public:
-  bool operator()(const hit &h1, const hit &h2) const
-  {
-    return h1.depth < h2.depth;
-  }
-};
-
-bool ProcessSelectionBuffer(int entityType, bool multipleSelection, 
-			    bool selectMesh, int x, int y, int w, int h,
-			    std::vector<GVertex*> &vertices,
-			    std::vector<GEdge*> &edges,
-			    std::vector<GFace*> &faces,
-			    std::vector<GRegion*> &regions)
-{
-  vertices.clear();
-  edges.clear();
-  faces.clear();
-  regions.clear();
-
-  // In our case the selection buffer size is equal to 5 x the maximum
-  // number of possible hits
-  int size = 5 * (GMODEL->numVertex() + GMODEL->numEdge() + 
-		  GMODEL->numFace() + GMODEL->numRegion()) + 100;
-  GLuint *selectionBuffer = new GLuint[size];
-  glSelectBuffer(size, selectionBuffer);
-
-  glRenderMode(GL_SELECT);
-  CTX.render_mode = GMSH_SELECT;
-
-  glInitNames();
-  glPushMatrix();
-  InitProjection(x, y, w, h);
-  InitPosition();
-  Draw_Geom();
-  if(selectMesh) Draw_Mesh();
-  glPopMatrix();
-
-  GLint numhits = glRenderMode(GL_RENDER);
-  CTX.render_mode = GMSH_RENDER;
-
-  if(!numhits){ // no hits
-    delete [] selectionBuffer;
-    return false;
-  }
-  else if(numhits < 0){ // overflow
-    delete [] selectionBuffer;
-    Msg(WARNING, "Selection buffer size exceeded");
-    return false;
-  }
-
-  std::vector<hit> hits;
-  GLuint *ptr = selectionBuffer;
-  for(int i = 0; i < numhits; i++) {
-    // in Gmsh 'names' should always be 2 or 0. If names is 2, the
-    // first name is the type of the entity (0 for point, 1 for line,
-    // etc.) and the second is the entity number; if names is 0 there
-    // is nothing on the stack.
-    GLuint names = *ptr++; 
-    GLuint mindepth = *ptr++;
-    *ptr++; // maxdepth
-    if(names == 2){
-      GLuint depth = mindepth;
-      GLuint type = *ptr++; 
-      GLuint ient = *ptr++;
-      hits.push_back(hit(type, ient, depth));
-    }
-  }
-
-  delete [] selectionBuffer;
-  
-  if(!hits.size()){ // no entities
-    return false;
-  }
-
-  // sort hits to get closest entities first
-  std::sort(hits.begin(), hits.end(), hitDepthLessThan());
-
-  // filter result: if entityType == ENT_NONE, return the closest
-  // entity of "lowest dimension" (point < line < surface <
-  // volume). Otherwise, return the closest entity of type
-  // "entityType"
-  GLuint typmin = 4;
-  for(unsigned int i = 0; i < hits.size(); i++)
-    typmin = std::min(typmin, hits[i].type);
-
-  for(unsigned int i = 0; i < hits.size(); i++) {
-    if((entityType == ENT_ALL) ||
-       (entityType == ENT_NONE && hits[i].type == typmin) ||
-       (entityType == ENT_POINT && hits[i].type == 0) ||
-       (entityType == ENT_LINE && hits[i].type == 1) ||
-       (entityType == ENT_SURFACE && hits[i].type == 2) ||
-       (entityType == ENT_VOLUME && hits[i].type == 3)){
-      switch (hits[i].type) {
-      case 0:
-	{
-	  GVertex *v = GMODEL->vertexByTag(hits[i].ient);
-	  if(!v){
-	    Msg(GERROR, "Problem in point selection processing");
-	    return false;
-	  }
-	  vertices.push_back(v);
-	  if(!multipleSelection) return true;
-	}
-	break;
-      case 1:
-	{
-	  GEdge *e = GMODEL->edgeByTag(hits[i].ient);
-	  if(!e){
-	    Msg(GERROR, "Problem in line selection processing");
-	    return false;
-	  }
-	  edges.push_back(e);
-	  if(!multipleSelection) return true;
-	}
-	break;
-      case 2:
-	{
-	  GFace *f = GMODEL->faceByTag(hits[i].ient);
-	  if(!f){
-	    Msg(GERROR, "Problem in surface selection processing");
-	    return false;
-	  }
-	  faces.push_back(f);
-	  if(!multipleSelection) return true;
-	}
-	break;
-      case 3:
-	{
-	  GRegion *r = GMODEL->regionByTag(hits[i].ient);
-	  if(!r){
-	    Msg(GERROR, "Problem in volume selection processing");
-	    return false;
-	  }
-	  regions.push_back(r);
-	  if(!multipleSelection) return true;
-	}
-	break;
-      }
-    }
-  }
-  return true;
-}
-
 // Takes a cursor position in window coordinates and returns the line
 // (given by a point and a unit direction vector), in real space, that
 // corresponds to that cursor position
diff --git a/Graphics/Draw.h b/Graphics/Draw.h
index 5523ddf2cf6b9acbacfba62fbf87eb641e44795a..d76055fb8f267b04805fd17d4209892ce3009797 100644
--- a/Graphics/Draw.h
+++ b/Graphics/Draw.h
@@ -22,11 +22,6 @@
 
 #include "List.h"
 #include "Views.h"
-#include "GVertex.h"
-#include "GEdge.h"
-#include "GFace.h"
-#include "GRegion.h"
-#include <vector>
 
 #define GMSH_RENDER    1
 #define GMSH_SELECT    2
@@ -39,18 +34,6 @@ void InitProjection(int xpick=0, int ypick=0, int wpick=0, int hpick=0);
 void InitPosition(void);
 void InitRenderModel(void);
 
-bool ProcessSelectionBuffer(int entityType, bool multipleSelection,
-			    bool selectMesh, int x, int y, int w, int h, 
-			    std::vector<GVertex*> &vertices,
-			    std::vector<GEdge*> &edges,
-			    std::vector<GFace*> &faces,
-			    std::vector<GRegion*> &regions);
-char SelectEntity(int entityType,
-		  std::vector<GVertex*> &vertices,
-		  std::vector<GEdge*> &edges,
-		  std::vector<GFace*> &faces,
-		  std::vector<GRegion*> &regions);
-
 void Unproject(double x, double y, double p[3], double d[3]);
 void Viewport2World(double win[3], double xyz[3]);
 void World2Viewport(double xyz[3], double win[3]);
@@ -59,13 +42,6 @@ unsigned int PaletteContinuous(Post_View * View, double min, double max, double
 unsigned int PaletteContinuousLinear(Post_View * v, double min, double max, double val);
 unsigned int PaletteDiscrete(Post_View * View, int nbi, int i);
 
-void HighlightEntity(GEntity *e, bool permanent=false);
-void HighlightEntity(GVertex *v, GEdge *e, GFace *f, GRegion *r, bool permanent=false);
-void HighlightEntityNum(int v, int c, int s, int r, bool permanant=false);
-void ZeroHighlightEntity(GVertex *v, GEdge *c, GFace *s, GRegion *r);
-void ZeroHighlightEntityNum(int v, int c, int s, int r);
-void ZeroHighlight();
-
 void Draw3d(void);
 void Draw2d(void);
 void DrawPlugin(void (*draw)(void));
diff --git a/Graphics/Geom.cpp b/Graphics/Geom.cpp
index 0dea7d4487f3dd7127a39f01d559fa1c725970f5..8ecd1c2fe8f5ae27afcbbbfa7ebd7069ecdd7877 100644
--- a/Graphics/Geom.cpp
+++ b/Graphics/Geom.cpp
@@ -1,4 +1,4 @@
-// $Id: Geom.cpp,v 1.116 2006-08-19 01:12:40 geuzaine Exp $
+// $Id: Geom.cpp,v 1.117 2006-08-20 14:12:40 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -458,84 +458,3 @@ void Draw_Geom()
   }
 }
 
-void HighlightEntity(GEntity *e, bool permanent)
-{
-  if(permanent)
-    e->setSelection(1);
-  else
-    Msg(STATUS2N, "%s", e->getInfoString().c_str());
-}
-
-void HighlightEntity(GVertex *v, GEdge *c, GFace *s, GRegion *r, bool permanent)
-{
-  if(v) HighlightEntity(v, permanent);
-  else if(c) HighlightEntity(c, permanent);
-  else if(s) HighlightEntity(s, permanent);
-  else if(r) HighlightEntity(r, permanent);
-  else if(!permanent) Msg(STATUS2N, " ");
-}
-
-void HighlightEntityNum(int v, int c, int s, int r, bool permanent)
-{
-  if(v) {
-    GVertex *pv = GMODEL->vertexByTag(v);
-    if(pv) HighlightEntity(pv, permanent);
-  }
-  if(c) {
-    GEdge *pc = GMODEL->edgeByTag(c);
-    if(pc) HighlightEntity(pc, permanent);
-  }
-  if(s) {
-    GFace *ps = GMODEL->faceByTag(s);
-    if(ps) HighlightEntity(ps, permanent);
-  }
-  if(r) {
-    GRegion *pr = GMODEL->regionByTag(r);
-    if(pr) HighlightEntity(pr, permanent);
-  }
-}
-
-void ZeroHighlightEntity(GEntity *e)
-{
-  e->setSelection(0);
-}
-
-void ZeroHighlightEntity(GVertex *v, GEdge *c, GFace *s, GRegion *r)
-{
-  if(v) ZeroHighlightEntity(v);
-  if(c) ZeroHighlightEntity(c);
-  if(s) ZeroHighlightEntity(s);
-  if(r) ZeroHighlightEntity(r);
-}
-
-void ZeroHighlight()
-{
-  for(GModel::viter it = GMODEL->firstVertex(); it != GMODEL->lastVertex(); it++)
-    ZeroHighlightEntity(*it);
-  for(GModel::eiter it = GMODEL->firstEdge(); it != GMODEL->lastEdge(); it++)
-    ZeroHighlightEntity(*it);
-  for(GModel::fiter it = GMODEL->firstFace(); it != GMODEL->lastFace(); it++)
-    ZeroHighlightEntity(*it);
-  for(GModel::riter it = GMODEL->firstRegion(); it != GMODEL->lastRegion(); it++)
-    ZeroHighlightEntity(*it);
-}
-
-void ZeroHighlightEntityNum(int v, int c, int s, int r)
-{
-  if(v) {
-    GVertex *pv = GMODEL->vertexByTag(v);
-    if(pv) ZeroHighlightEntity(pv);
-  }
-  if(c) {
-    GEdge *pc = GMODEL->edgeByTag(c);
-    if(pc) ZeroHighlightEntity(pc);
-  }
-  if(s) {
-    GFace *ps = GMODEL->faceByTag(s);
-    if(ps) ZeroHighlightEntity(ps);
-  }
-  if(r) {
-    GRegion *pr = GMODEL->regionByTag(r);
-    if(pr) ZeroHighlightEntity(pr);
-  }
-}
diff --git a/Graphics/Makefile b/Graphics/Makefile
index 103fe3790013e154b43218b74fbfd1a4403a22a4..ab1eea8d3589b9e644fefc52816a3915ad970111 100644
--- a/Graphics/Makefile
+++ b/Graphics/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.98 2006-08-17 21:28:34 geuzaine Exp $
+# $Id: Makefile,v 1.99 2006-08-20 14:12:40 geuzaine Exp $
 #
 # Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 #
@@ -32,6 +32,7 @@ SRC = Draw.cpp \
       Geom.cpp \
       Post.cpp \
       PostElement.cpp \
+      SelectBuffer.cpp \
       Iso.cpp \
       Entity.cpp \
       ReadImg.cpp \
@@ -146,6 +147,25 @@ PostElement.o: PostElement.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../Common/GmshMatrix.h ../Common/AdaptiveViews.h ../Common/GmshMatrix.h \
   Iso.h ../Common/Context.h
 # 1 "/Users/geuzaine/.gmsh/Graphics//"
+SelectBuffer.o: SelectBuffer.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 ../Common/GmshDefines.h Draw.h ../Common/Views.h \
+  ../Common/ColorTable.h ../Common/VertexArray.h \
+  ../Common/SmoothNormals.h ../Numeric/Numeric.h ../Common/GmshMatrix.h \
+  ../Common/AdaptiveViews.h ../Common/GmshMatrix.h ../Common/Context.h \
+  SelectBuffer.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/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/SVector3.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/GModel.h ../Geo/GVertex.h ../Geo/GEdge.h ../Geo/GFace.h \
+  ../Geo/GRegion.h ../Geo/SBoundingBox3d.h
+# 1 "/Users/geuzaine/.gmsh/Graphics//"
 Iso.o: Iso.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 Draw.h \
diff --git a/Graphics/SelectBuffer.cpp b/Graphics/SelectBuffer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e03cf203c55c6dbf05a3109f89840052070b6693
--- /dev/null
+++ b/Graphics/SelectBuffer.cpp
@@ -0,0 +1,263 @@
+// $Id: SelectBuffer.cpp,v 1.1 2006-08-20 14:12:41 geuzaine Exp $
+//
+// Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+// 
+// Please report all bugs and problems to <gmsh@geuz.org>.
+
+#include "Gmsh.h"
+#include "GmshUI.h"
+#include "GmshDefines.h"
+#include "Draw.h"
+#include "Context.h"
+#include "SelectBuffer.h"
+#include "GModel.h"
+
+extern Context_T CTX;
+extern GModel *GMODEL;
+
+class hit{
+public:
+  GLuint type, ient, depth;
+  hit(GLuint t, GLuint i, GLuint d) : type(t), ient(i), depth(d) {}
+};
+
+class hitDepthLessThan{
+ public:
+  bool operator()(const hit &h1, const hit &h2) const
+  {
+    return h1.depth < h2.depth;
+  }
+};
+
+bool ProcessSelectionBuffer(int entityType, bool multipleSelection, 
+			    bool selectMesh, int x, int y, int w, int h,
+			    std::vector<GVertex*> &vertices,
+			    std::vector<GEdge*> &edges,
+			    std::vector<GFace*> &faces,
+			    std::vector<GRegion*> &regions)
+{
+  vertices.clear();
+  edges.clear();
+  faces.clear();
+  regions.clear();
+
+  // In our case the selection buffer size is equal to 5 x the maximum
+  // number of possible hits
+  int size = 5 * (GMODEL->numVertex() + GMODEL->numEdge() + 
+		  GMODEL->numFace() + GMODEL->numRegion()) + 100;
+  GLuint *selectionBuffer = new GLuint[size];
+  glSelectBuffer(size, selectionBuffer);
+
+  glRenderMode(GL_SELECT);
+  CTX.render_mode = GMSH_SELECT;
+
+  glInitNames();
+  glPushMatrix();
+  InitProjection(x, y, w, h);
+  InitPosition();
+  Draw_Geom();
+  if(selectMesh) Draw_Mesh();
+  glPopMatrix();
+
+  GLint numhits = glRenderMode(GL_RENDER);
+  CTX.render_mode = GMSH_RENDER;
+
+  if(!numhits){ // no hits
+    delete [] selectionBuffer;
+    return false;
+  }
+  else if(numhits < 0){ // overflow
+    delete [] selectionBuffer;
+    Msg(WARNING, "Selection buffer size exceeded");
+    return false;
+  }
+
+  std::vector<hit> hits;
+  GLuint *ptr = selectionBuffer;
+  for(int i = 0; i < numhits; i++) {
+    // in Gmsh 'names' should always be 2 or 0. If names is 2, the
+    // first name is the type of the entity (0 for point, 1 for line,
+    // etc.) and the second is the entity number; if names is 0 there
+    // is nothing on the stack.
+    GLuint names = *ptr++; 
+    GLuint mindepth = *ptr++;
+    *ptr++; // maxdepth
+    if(names == 2){
+      GLuint depth = mindepth;
+      GLuint type = *ptr++; 
+      GLuint ient = *ptr++;
+      hits.push_back(hit(type, ient, depth));
+    }
+  }
+
+  delete [] selectionBuffer;
+  
+  if(!hits.size()){ // no entities
+    return false;
+  }
+
+  // sort hits to get closest entities first
+  std::sort(hits.begin(), hits.end(), hitDepthLessThan());
+
+  // filter result: if entityType == ENT_NONE, return the closest
+  // entity of "lowest dimension" (point < line < surface <
+  // volume). Otherwise, return the closest entity of type
+  // "entityType"
+  GLuint typmin = 4;
+  for(unsigned int i = 0; i < hits.size(); i++)
+    typmin = std::min(typmin, hits[i].type);
+
+  for(unsigned int i = 0; i < hits.size(); i++) {
+    if((entityType == ENT_ALL) ||
+       (entityType == ENT_NONE && hits[i].type == typmin) ||
+       (entityType == ENT_POINT && hits[i].type == 0) ||
+       (entityType == ENT_LINE && hits[i].type == 1) ||
+       (entityType == ENT_SURFACE && hits[i].type == 2) ||
+       (entityType == ENT_VOLUME && hits[i].type == 3)){
+      switch (hits[i].type) {
+      case 0:
+	{
+	  GVertex *v = GMODEL->vertexByTag(hits[i].ient);
+	  if(!v){
+	    Msg(GERROR, "Problem in point selection processing");
+	    return false;
+	  }
+	  vertices.push_back(v);
+	  if(!multipleSelection) return true;
+	}
+	break;
+      case 1:
+	{
+	  GEdge *e = GMODEL->edgeByTag(hits[i].ient);
+	  if(!e){
+	    Msg(GERROR, "Problem in line selection processing");
+	    return false;
+	  }
+	  edges.push_back(e);
+	  if(!multipleSelection) return true;
+	}
+	break;
+      case 2:
+	{
+	  GFace *f = GMODEL->faceByTag(hits[i].ient);
+	  if(!f){
+	    Msg(GERROR, "Problem in surface selection processing");
+	    return false;
+	  }
+	  faces.push_back(f);
+	  if(!multipleSelection) return true;
+	}
+	break;
+      case 3:
+	{
+	  GRegion *r = GMODEL->regionByTag(hits[i].ient);
+	  if(!r){
+	    Msg(GERROR, "Problem in volume selection processing");
+	    return false;
+	  }
+	  regions.push_back(r);
+	  if(!multipleSelection) return true;
+	}
+	break;
+      }
+    }
+  }
+  return true;
+}
+
+void HighlightEntity(GEntity *e, bool permanent)
+{
+  if(permanent)
+    e->setSelection(1);
+  else
+    Msg(STATUS2N, "%s", e->getInfoString().c_str());
+}
+
+void HighlightEntity(GVertex *v, GEdge *c, GFace *s, GRegion *r, bool permanent)
+{
+  if(v) HighlightEntity(v, permanent);
+  else if(c) HighlightEntity(c, permanent);
+  else if(s) HighlightEntity(s, permanent);
+  else if(r) HighlightEntity(r, permanent);
+  else if(!permanent) Msg(STATUS2N, " ");
+}
+
+void HighlightEntityNum(int v, int c, int s, int r, bool permanent)
+{
+  if(v) {
+    GVertex *pv = GMODEL->vertexByTag(v);
+    if(pv) HighlightEntity(pv, permanent);
+  }
+  if(c) {
+    GEdge *pc = GMODEL->edgeByTag(c);
+    if(pc) HighlightEntity(pc, permanent);
+  }
+  if(s) {
+    GFace *ps = GMODEL->faceByTag(s);
+    if(ps) HighlightEntity(ps, permanent);
+  }
+  if(r) {
+    GRegion *pr = GMODEL->regionByTag(r);
+    if(pr) HighlightEntity(pr, permanent);
+  }
+}
+
+void ZeroHighlightEntity(GEntity *e)
+{
+  e->setSelection(0);
+}
+
+void ZeroHighlightEntity(GVertex *v, GEdge *c, GFace *s, GRegion *r)
+{
+  if(v) ZeroHighlightEntity(v);
+  if(c) ZeroHighlightEntity(c);
+  if(s) ZeroHighlightEntity(s);
+  if(r) ZeroHighlightEntity(r);
+}
+
+void ZeroHighlight()
+{
+  for(GModel::viter it = GMODEL->firstVertex(); it != GMODEL->lastVertex(); it++)
+    ZeroHighlightEntity(*it);
+  for(GModel::eiter it = GMODEL->firstEdge(); it != GMODEL->lastEdge(); it++)
+    ZeroHighlightEntity(*it);
+  for(GModel::fiter it = GMODEL->firstFace(); it != GMODEL->lastFace(); it++)
+    ZeroHighlightEntity(*it);
+  for(GModel::riter it = GMODEL->firstRegion(); it != GMODEL->lastRegion(); it++)
+    ZeroHighlightEntity(*it);
+}
+
+void ZeroHighlightEntityNum(int v, int c, int s, int r)
+{
+  if(v) {
+    GVertex *pv = GMODEL->vertexByTag(v);
+    if(pv) ZeroHighlightEntity(pv);
+  }
+  if(c) {
+    GEdge *pc = GMODEL->edgeByTag(c);
+    if(pc) ZeroHighlightEntity(pc);
+  }
+  if(s) {
+    GFace *ps = GMODEL->faceByTag(s);
+    if(ps) ZeroHighlightEntity(ps);
+  }
+  if(r) {
+    GRegion *pr = GMODEL->regionByTag(r);
+    if(pr) ZeroHighlightEntity(pr);
+  }
+}
diff --git a/Graphics/SelectBuffer.h b/Graphics/SelectBuffer.h
new file mode 100644
index 0000000000000000000000000000000000000000..78146179867841841e8ed9cb52f4b86b7c90f88c
--- /dev/null
+++ b/Graphics/SelectBuffer.h
@@ -0,0 +1,57 @@
+#ifndef _SELECT_BUFFER_H_
+#define _SELECT_BUFFER_H_
+/*
+ * Copyright (C) 1999-2006 Christophe Geuzaine <geuz@geuz.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of either:
+ *
+ * a) the GNU Library General Public License as published by the Free
+ * Software Foundation, either version 2 of the License, or (at your
+ * option) any later version; or
+ *
+ * b) the GL2PS License as published by Christophe Geuzaine, either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See either
+ * the GNU Library General Public License or the GL2PS License for
+ * more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library in the file named "COPYING.LGPL";
+ * if not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+ * Cambridge, MA 02139, USA.
+ *
+ * You should have received a copy of the GL2PS License with this
+ * library in the file named "COPYING.GL2PS"; if not, I will be glad
+ * to provide one.
+ */
+
+#include <vector>
+#include "GVertex.h"
+#include "GEdge.h"
+#include "GFace.h"
+#include "GRegion.h"
+
+bool ProcessSelectionBuffer(int entityType, bool multipleSelection,
+			    bool selectMesh, int x, int y, int w, int h, 
+			    std::vector<GVertex*> &vertices,
+			    std::vector<GEdge*> &edges,
+			    std::vector<GFace*> &faces,
+			    std::vector<GRegion*> &regions);
+char SelectEntity(int entityType,
+		  std::vector<GVertex*> &vertices,
+		  std::vector<GEdge*> &edges,
+		  std::vector<GFace*> &faces,
+		  std::vector<GRegion*> &regions);
+
+void HighlightEntity(GEntity *e, bool permanent=false);
+void HighlightEntity(GVertex *v, GEdge *e, GFace *f, GRegion *r, bool permanent=false);
+void HighlightEntityNum(int v, int c, int s, int r, bool permanant=false);
+void ZeroHighlightEntity(GVertex *v, GEdge *c, GFace *s, GRegion *r);
+void ZeroHighlightEntityNum(int v, int c, int s, int r);
+void ZeroHighlight();
+
+#endif
diff --git a/Mesh/Makefile b/Mesh/Makefile
index 6c9b3b33e04d56860d04b2d3cf36be890cc15df2..273162b322a3cba8c82c937dc946a9aba990d214 100644
--- a/Mesh/Makefile
+++ b/Mesh/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.122 2006-08-19 08:26:47 remacle Exp $
+# $Id: Makefile,v 1.123 2006-08-20 14:12:41 geuzaine Exp $
 #
 # Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 #
@@ -322,10 +322,16 @@ depend:
   ../Numeric/Numeric.h ../Common/Context.h
 # 1 "/Users/geuzaine/.gmsh/Mesh//"
 BDS.o: BDS.cpp ../Numeric/Numeric.h ../Common/GmshMatrix.h BDS.h \
-  ../Common/Views.h ../Common/ColorTable.h ../DataStr/List.h \
-  ../Common/VertexArray.h ../Common/SmoothNormals.h \
-  ../Common/GmshMatrix.h ../Common/AdaptiveViews.h ../Common/GmshMatrix.h \
-  ../Common/Message.h
+  ../Geo/GFace.h ../Geo/GPoint.h ../Geo/GEntity.h ../Geo/Range.h \
+  ../Geo/SPoint3.h ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h \
+  ../Common/GmshDefines.h ../Geo/MElement.h ../Geo/MVertex.h \
+  ../Geo/SPoint3.h ../Geo/MEdge.h ../Geo/MVertex.h ../Geo/SVector3.h \
+  ../Geo/SPoint3.h ../Geo/MFace.h ../Geo/MVertex.h ../Geo/SVector3.h \
+  ../Common/Context.h ../DataStr/List.h ../Geo/SPoint2.h \
+  ../Geo/SVector3.h ../Geo/Pair.h ../Common/Views.h \
+  ../Common/ColorTable.h ../Common/VertexArray.h \
+  ../Common/SmoothNormals.h ../Common/GmshMatrix.h \
+  ../Common/AdaptiveViews.h ../Common/GmshMatrix.h ../Common/Message.h
 # 1 "/Users/geuzaine/.gmsh/Mesh//"
 Create.o: Create.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
@@ -344,21 +350,21 @@ Generator.o: Generator.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
   ../Numeric/Numeric.h Mesh.h ../Common/GmshDefines.h Vertex.h Element.h \
   Simplex.h Face.h Edge.h ../Geo/ExtrudeParams.h Metric.h Matrix.h BDS.h \
-  ../Common/Views.h ../Common/ColorTable.h ../Common/VertexArray.h \
+  ../Geo/GFace.h ../Geo/GPoint.h ../Geo/GEntity.h ../Geo/Range.h \
+  ../Geo/SPoint3.h ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h \
+  ../Geo/MElement.h ../Geo/MVertex.h ../Geo/SPoint3.h ../Geo/MEdge.h \
+  ../Geo/MVertex.h ../Geo/SVector3.h ../Geo/SPoint3.h ../Geo/MFace.h \
+  ../Geo/MVertex.h ../Geo/SVector3.h ../Common/Context.h ../Geo/SPoint2.h \
+  ../Geo/SVector3.h ../Geo/Pair.h ../Common/Views.h \
+  ../Common/ColorTable.h ../Common/VertexArray.h \
   ../Common/SmoothNormals.h ../Common/GmshMatrix.h \
   ../Common/AdaptiveViews.h ../Common/GmshMatrix.h Create.h \
-  ../Common/Context.h ../Parser/OpenFile.h PartitionMesh.h ../Common/OS.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/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/SVector3.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
+  ../Parser/OpenFile.h PartitionMesh.h ../Common/OS.h meshGEdge.h \
+  meshGFace.h ../Geo/GModel.h ../Geo/GVertex.h ../Geo/GEntity.h \
+  ../Geo/MVertex.h ../Geo/GPoint.h ../Geo/GEdge.h ../Geo/GEntity.h \
+  ../Geo/GVertex.h ../Geo/SVector3.h ../Geo/SPoint3.h ../Geo/SPoint2.h \
+  ../Geo/MElement.h ../Geo/GFace.h ../Geo/GRegion.h ../Geo/GEntity.h \
+  ../Geo/MElement.h ../Geo/SBoundingBox3d.h
 # 1 "/Users/geuzaine/.gmsh/Mesh//"
 DiscreteSurface.o: DiscreteSurface.cpp ../Common/Gmsh.h \
   ../Common/Message.h ../DataStr/Malloc.h ../DataStr/List.h \
@@ -367,10 +373,16 @@ DiscreteSurface.o: DiscreteSurface.cpp ../Common/Gmsh.h \
   Vertex.h Element.h Simplex.h Face.h Edge.h ../Geo/ExtrudeParams.h \
   Metric.h Matrix.h ../Geo/CAD.h ../Mesh/Mesh.h ../Mesh/Vertex.h \
   ../Geo/ExtrudeParams.h ../Geo/Geo.h Create.h Interpolation.h \
-  ../Common/Context.h BDS.h ../Common/Views.h ../Common/ColorTable.h \
-  ../Common/VertexArray.h ../Common/SmoothNormals.h \
-  ../Common/GmshMatrix.h ../Common/AdaptiveViews.h ../Common/GmshMatrix.h \
-  PartitionMesh.h ../Common/OS.h
+  ../Common/Context.h BDS.h ../Geo/GFace.h ../Geo/GPoint.h \
+  ../Geo/GEntity.h ../Geo/Range.h ../Geo/SPoint3.h \
+  ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../Geo/MElement.h \
+  ../Geo/MVertex.h ../Geo/SPoint3.h ../Geo/MEdge.h ../Geo/MVertex.h \
+  ../Geo/SVector3.h ../Geo/SPoint3.h ../Geo/MFace.h ../Geo/MVertex.h \
+  ../Geo/SVector3.h ../Geo/SPoint2.h ../Geo/SVector3.h ../Geo/Pair.h \
+  ../Common/Views.h ../Common/ColorTable.h ../Common/VertexArray.h \
+  ../Common/SmoothNormals.h ../Common/GmshMatrix.h \
+  ../Common/AdaptiveViews.h ../Common/GmshMatrix.h PartitionMesh.h \
+  ../Common/OS.h
 # 1 "/Users/geuzaine/.gmsh/Mesh//"
 SwapEdge.o: SwapEdge.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
@@ -449,12 +461,19 @@ Interpolation.o: Interpolation.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../Geo/ExtrudeParams.h Metric.h Matrix.h ../Geo/CAD.h ../Mesh/Mesh.h \
   ../Mesh/Vertex.h ../Geo/ExtrudeParams.h Utils.h Interpolation.h
 # 1 "/Users/geuzaine/.gmsh/Mesh//"
-SecondOrder.o: SecondOrder.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 \
-  ../Geo/Geo.h Mesh.h ../Common/GmshDefines.h Vertex.h Element.h \
-  Simplex.h Face.h Edge.h ../Geo/ExtrudeParams.h Metric.h Matrix.h \
-  Utils.h Interpolation.h ../Numeric/Numeric.h ../Common/OS.h
+SecondOrder.o: SecondOrder.cpp ../Geo/GModel.h ../Geo/GVertex.h \
+  ../Geo/GEntity.h ../Geo/Range.h ../Geo/SPoint3.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/SVector3.h ../Geo/MFace.h \
+  ../Geo/MVertex.h ../Geo/SVector3.h ../Numeric/Numeric.h \
+  ../Common/Context.h ../DataStr/List.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/Message.h \
+  ../Common/OS.h
 # 1 "/Users/geuzaine/.gmsh/Mesh//"
 PartitionMesh.o: PartitionMesh.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
@@ -463,10 +482,15 @@ PartitionMesh.o: PartitionMesh.cpp ../Common/Gmsh.h ../Common/Message.h \
   Simplex.h Face.h Edge.h ../Geo/ExtrudeParams.h Metric.h Matrix.h \
   ../Geo/CAD.h ../Mesh/Mesh.h ../Mesh/Vertex.h ../Geo/ExtrudeParams.h \
   ../Geo/Geo.h Create.h Interpolation.h ../Common/Context.h BDS.h \
-  ../Common/Views.h ../Common/ColorTable.h ../Common/VertexArray.h \
-  ../Common/SmoothNormals.h ../Common/GmshMatrix.h \
-  ../Common/AdaptiveViews.h ../Common/GmshMatrix.h PartitionMesh.h \
-  ../Parser/OpenFile.h
+  ../Geo/GFace.h ../Geo/GPoint.h ../Geo/GEntity.h ../Geo/Range.h \
+  ../Geo/SPoint3.h ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h \
+  ../Geo/MElement.h ../Geo/MVertex.h ../Geo/SPoint3.h ../Geo/MEdge.h \
+  ../Geo/MVertex.h ../Geo/SVector3.h ../Geo/SPoint3.h ../Geo/MFace.h \
+  ../Geo/MVertex.h ../Geo/SVector3.h ../Geo/SPoint2.h ../Geo/SVector3.h \
+  ../Geo/Pair.h ../Common/Views.h ../Common/ColorTable.h \
+  ../Common/VertexArray.h ../Common/SmoothNormals.h \
+  ../Common/GmshMatrix.h ../Common/AdaptiveViews.h ../Common/GmshMatrix.h \
+  PartitionMesh.h ../Parser/OpenFile.h
 # 1 "/Users/geuzaine/.gmsh/Mesh//"
 Smoothing.o: Smoothing.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
diff --git a/Mesh/SecondOrder.cpp b/Mesh/SecondOrder.cpp
index d29d374d59b3fe4fcec324856c70a16da33bfd85..66e3703fee9a7356c284376a8ae2d319df004144 100644
--- a/Mesh/SecondOrder.cpp
+++ b/Mesh/SecondOrder.cpp
@@ -1,4 +1,4 @@
-// $Id: SecondOrder.cpp,v 1.40 2006-08-20 03:44:15 geuzaine Exp $
+// $Id: SecondOrder.cpp,v 1.41 2006-08-20 14:12:42 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -91,7 +91,6 @@ MVertex *addEdgeVertex(GFace *f, std::pair<MVertex* , MVertex*> &p, bool linear)
     GPoint pc = f->point(uc, vc);
     v = new MFaceVertex(pc.x(), pc.y(), pc.z(), f, uc, vc);
   }
-
   f->mesh_vertices.push_back(v);
   return v;
 }
@@ -108,13 +107,13 @@ MVertex *addEdgeVertex(GRegion *r, std::pair<MVertex* , MVertex*> &p, bool linea
 
 template<class T, class U>
 void addEdgeVertices(U *ge, std::vector<T*> &elements, bool linear,
-		     std::map<std::pair<MVertex*,MVertex*>, MVertex* > &edges)
+		     std::map<std::pair<MVertex*,MVertex*>, MVertex* > &edgeVertices)
 {
   for(unsigned int i = 0; i < elements.size(); i++){
     for(int j = 0; j < elements[i]->getNumEdges(); j++){
       MEdge e = elements[i]->getEdge(j);
       std::pair<MVertex*, MVertex*> p(e.getMinVertex(), e.getMaxVertex());
-      if(!edges.count(p)) edges[p] = addEdgeVertex(ge, p, linear);
+      if(!edgeVertices.count(p)) edgeVertices[p] = addEdgeVertex(ge, p, linear);
     }
   }
 }
@@ -123,36 +122,40 @@ void addEdgeVertices(U *ge, std::vector<T*> &elements, bool linear,
 
 MVertex *addFaceVertex(GFace *f, std::vector<MVertex*> &p, bool linear)
 {
-  /*
-  MVertex *v;
-  if(linear || e->dim() == 3){
+  //MVertex *v;
+  if(linear){
     // just interpolate linear between the 4
   }
-  else if(e->dim() == 2){
-    xyz2uv();
-    xyz2uv();
-    xyz2uv();
-    xyz2uv();
+  else{
+    //xyz2uv();
     // interpolate
   }
-  e->mesh_vertices.push_back(v);
-  */
+  //f->mesh_vertices.push_back(v);
   return 0;
 }
 
-template<class T>
-void addFaceVertices(GEntity *e, std::vector<T*> &elements)
+MVertex *addFaceVertex(GRegion *r, std::vector<MVertex*> &p, bool linear)
 {
+  //MVertex *v;
+  // just interpolate linear between the 4
+  //r->mesh_vertices.push_back(v);
+  return 0;
 }
 
-// Creation of middle-volume vertices
-
-MVertex *addVolumeVertex(GEntity *ge, MElement *elem)
+template<class T, class U>
+void addFaceVertices(U *ge, std::vector<T*> &elements, bool linear,
+		     std::map<std::vector<MVertex*>, MVertex* > &faceVertices)
 {
-  SPoint3 pc = elem->barycenter();
-  MVertex *v = new MVertex(pc.x(), pc.y(), pc.z(), ge);
-  ge->mesh_vertices.push_back(v);
-  return v;
+  for(unsigned int i = 0; i < elements.size(); i++){
+    for(int j = 0; j < elements[i]->getNumFaces(); j++){
+      MFace f = elements[i]->getFace(j);
+      if(f.getNumVertices() == 4){
+	std::vector<MVertex*> p;
+	f.getOrderedVertices(p);
+	if(!faceVertices.count(p)) faceVertices[p] = addFaceVertex(ge, p, linear);
+      }
+    }
+  }
 }
 
 // Main routines
@@ -174,28 +177,30 @@ void Degre2(int dim)
 
   //bool linear = true;
   bool linear = false;
-  std::map<std::pair<MVertex*,MVertex*>, MVertex* > edges;
-  std::map<std::vector<MVertex*>, MVertex* > quadFaces;
+  std::map<std::pair<MVertex*,MVertex*>, MVertex* > edgeVertices;
+  std::map<std::vector<MVertex*>, MVertex* > faceVertices;
 
   // loop over all elements and create unique edges and faces and
   // their associated new vertices
   for(GModel::eiter it = GMODEL->firstEdge(); it != GMODEL->lastEdge(); ++it){
-    addEdgeVertices(*it, (*it)->lines, linear, edges);
+    addEdgeVertices(*it, (*it)->lines, linear, edgeVertices);
   }
   for(GModel::fiter it = GMODEL->firstFace(); it != GMODEL->lastFace(); ++it){
-    addEdgeVertices(*it, (*it)->triangles, linear, edges);
-    addEdgeVertices(*it, (*it)->quadrangles, linear, edges);
-    //addFaceVertices(*it, (*it)->quadrangles, linear);
+    addEdgeVertices(*it, (*it)->triangles, linear, edgeVertices);
+    addEdgeVertices(*it, (*it)->quadrangles, linear, edgeVertices);
+    addFaceVertices(*it, (*it)->quadrangles, linear, faceVertices);
   }
   for(GModel::riter it = GMODEL->firstRegion(); it != GMODEL->lastRegion(); ++it){
-    addEdgeVertices(*it, (*it)->tetrahedra, linear, edges);
-    addEdgeVertices(*it, (*it)->hexahedra, linear, edges);
-    addEdgeVertices(*it, (*it)->prisms, linear, edges);
-    addEdgeVertices(*it, (*it)->pyramids, linear, edges);
-//     addFaceVertices(*it, (*it)->hexahedra, linear);
-//     addFaceVertices(*it, (*it)->prisms, linear);
-//     addFaceVertices(*it, (*it)->pyramids, linear);
+    addEdgeVertices(*it, (*it)->tetrahedra, linear, edgeVertices);
+    addEdgeVertices(*it, (*it)->hexahedra, linear, edgeVertices);
+    addEdgeVertices(*it, (*it)->prisms, linear, edgeVertices);
+    addEdgeVertices(*it, (*it)->pyramids, linear, edgeVertices);
+    addFaceVertices(*it, (*it)->hexahedra, linear, faceVertices);
+    addFaceVertices(*it, (*it)->prisms, linear, faceVertices);
+    addFaceVertices(*it, (*it)->pyramids, linear, faceVertices);
   }
+
+  printf("%d edges, %d faces\n", edgeVertices.size(), faceVertices.size());
   
   // loop on all elements again and create one new element from each
   // old one, querying the edge/face maps to get the extra vertices
diff --git a/Parser/Makefile b/Parser/Makefile
index b4231924c9448bdf60756d623ddf37949e0e3f0b..e0807af8dc8782642fc392f30103a8d0da16ccbf 100644
--- a/Parser/Makefile
+++ b/Parser/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.99 2006-08-17 21:28:34 geuzaine Exp $
+# $Id: Makefile,v 1.100 2006-08-20 14:12:42 geuzaine Exp $
 #
 # Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 #
@@ -130,9 +130,9 @@ OpenFile.o: OpenFile.cpp ../Common/Gmsh.h ../Common/Message.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
+  ../Common/OS.h ../Common/GmshUI.h ../Graphics/Draw.h \
+  ../Graphics/SelectBuffer.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 \
diff --git a/Parser/OpenFile.cpp b/Parser/OpenFile.cpp
index 3c7f847bfbf2aba3891d31c2868b4f19960002d8..e3f48e1c50503f63cc54aa9af6056e6768ea4d4d 100644
--- a/Parser/OpenFile.cpp
+++ b/Parser/OpenFile.cpp
@@ -1,4 +1,4 @@
-// $Id: OpenFile.cpp,v 1.114 2006-08-18 17:49:35 geuzaine Exp $
+// $Id: OpenFile.cpp,v 1.115 2006-08-20 14:12:42 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -38,6 +38,7 @@
 #if defined(HAVE_FLTK)
 #include "GmshUI.h"
 #include "Draw.h"
+#include "SelectBuffer.h"
 #include "GUI.h"
 extern GUI *WID;
 void UpdateViewsInGUI();
diff --git a/Plugin/Makefile b/Plugin/Makefile
index 9e7944f34da3d9f4339bd69b0cd19def8ead7591..d59a48b21525ee636a01f2ebb77888782fd1b427 100644
--- a/Plugin/Makefile
+++ b/Plugin/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.106 2006-08-13 02:46:54 geuzaine Exp $
+# $Id: Makefile,v 1.107 2006-08-20 14:12:42 geuzaine Exp $
 #
 # Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 #
@@ -213,7 +213,13 @@ ExtractEdges.o: ExtractEdges.cpp Plugin.h ../Common/Options.h \
   ../DataStr/List.h ../Common/VertexArray.h ../Common/SmoothNormals.h \
   ../Numeric/Numeric.h ../Common/GmshMatrix.h ../Common/AdaptiveViews.h \
   ../Common/GmshMatrix.h ExtractEdges.h ../DataStr/Tree.h \
-  ../DataStr/avl.h ../Common/Context.h ../DataStr/Malloc.h ../Mesh/BDS.h
+  ../DataStr/avl.h ../Common/Context.h ../DataStr/Malloc.h ../Mesh/BDS.h \
+  ../Geo/GFace.h ../Geo/GPoint.h ../Geo/GEntity.h ../Geo/Range.h \
+  ../Geo/SPoint3.h ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h \
+  ../Common/GmshDefines.h ../Geo/MElement.h ../Geo/MVertex.h \
+  ../Geo/SPoint3.h ../Geo/MEdge.h ../Geo/MVertex.h ../Geo/SVector3.h \
+  ../Geo/SPoint3.h ../Geo/MFace.h ../Geo/MVertex.h ../Geo/SVector3.h \
+  ../Geo/SPoint2.h ../Geo/SVector3.h ../Geo/Pair.h
 # 1 "/Users/geuzaine/.gmsh/Plugin//"
 DecomposeInSimplex.o: DecomposeInSimplex.cpp Plugin.h ../Common/Options.h \
   ../Common/Message.h ../Common/Views.h ../Common/ColorTable.h \