diff --git a/Fltk/Callbacks.cpp b/Fltk/Callbacks.cpp
index fb37ef93ead6d5ee2dad8a324570a9d13112b676..1799562d750212d9e737b8d36696f87783687bf4 100644
--- a/Fltk/Callbacks.cpp
+++ b/Fltk/Callbacks.cpp
@@ -1,4 +1,4 @@
-// $Id: Callbacks.cpp,v 1.462 2006-10-09 13:26:26 geuzaine Exp $
+// $Id: Callbacks.cpp,v 1.463 2006-10-31 20:20:21 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -476,13 +476,13 @@ void status_xyz1p_cb(CALLBACK_ARGS)
   }
   else if(!strcmp(str, "S")){ // mouse selection
     if(Fl::event_state(FL_SHIFT)){
-      // full mouse hover and select for geometry and mesh
+      // mouse hover and select for geometry and mesh
       opt_general_mouse_selection(0, GMSH_SET | GMSH_GUI, 2);
     }
     else if(Fl::event_state(FL_META)){
-      // full hover and select, even for mesh elements
+      // mouse hover and select for geometry and mesh, and mouse
+      // select for individual mesh elements
       opt_general_mouse_selection(0, GMSH_SET | GMSH_GUI, 3);
-      CTX.mesh.changed = ENT_ALL; // need to regenerate the mesh reps
     }
     else if(CTX.enable_mouse_selection){
       // mouse does nothing
@@ -930,9 +930,10 @@ void general_options_rotation_center_select_cb(CALLBACK_ARGS)
   std::vector<GEdge*> edges;
   std::vector<GFace*> faces;
   std::vector<GRegion*> regions;
+  std::vector<MElement*> elements;
 
   Msg(ONSCREEN, "Select entity\n[Press 'q' to abort]");
-  char ib = SelectEntity(ENT_ALL, vertices, edges, faces, regions);
+  char ib = SelectEntity(ENT_ALL, vertices, edges, faces, regions, elements);
   if(ib == 'l') {
     SPoint3 pc(0., 0., 0.);
     if(vertices.size())
@@ -943,6 +944,8 @@ void general_options_rotation_center_select_cb(CALLBACK_ARGS)
       pc = faces[0]->bounds().center();
     else if(regions.size())
       pc = regions[0]->bounds().center();
+    else if(elements.size())
+      pc = elements[0]->barycenter();
     opt_general_rotation_center_cg(0, GMSH_SET, WID->gen_butt[15]->value());
     opt_general_rotation_center0(0, GMSH_SET|GMSH_GUI, pc.x());
     opt_general_rotation_center1(0, GMSH_SET|GMSH_GUI, pc.y());
@@ -2510,7 +2513,8 @@ void geometry_elementary_add_new_point_cb(CALLBACK_ARGS)
     std::vector<GEdge*> edges;
     std::vector<GFace*> faces;
     std::vector<GRegion*> regions;
-    char ib = SelectEntity(ENT_NONE, vertices, edges, faces, regions);
+    std::vector<MElement*> elements;
+    char ib = SelectEntity(ENT_NONE, vertices, edges, faces, regions, elements);
     if(ib == 'e'){
       add_point(CTX.filename,
 		(char*)WID->context_geometry_input[2]->value(),
@@ -2535,6 +2539,7 @@ static void _new_multiline(int type)
   std::vector<GEdge*> edges;
   std::vector<GFace*> faces;
   std::vector<GRegion*> regions;
+  std::vector<MElement*> elements;
   int p[100];
 
   opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
@@ -2549,10 +2554,13 @@ static void _new_multiline(int type)
     else
       Msg(ONSCREEN, "Select control points\n"
 	  "[Press 'e' to end selection, 'u' to undo last selection or 'q' to abort]");
-    char ib = SelectEntity(ENT_POINT, vertices, edges, faces, regions);
+    char ib = SelectEntity(ENT_POINT, vertices, edges, faces, regions, elements);
     if(ib == 'l') {
-      for(unsigned int i = 0; i < vertices.size(); i++)
+      for(unsigned int i = 0; i < vertices.size(); i++){
+	HighlightEntity(vertices[i], true);
 	p[n++] = vertices[i]->tag();
+      }
+      Draw();
     }
     if(ib == 'r') {
       Msg(WARNING, "Entity de-selection not supported yet during multi-line creation");
@@ -2607,6 +2615,7 @@ void geometry_elementary_add_new_line_cb(CALLBACK_ARGS)
   std::vector<GEdge*> edges;
   std::vector<GFace*> faces;
   std::vector<GRegion*> regions;
+  std::vector<MElement*> elements;
   int p[100];
 
   opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
@@ -2621,8 +2630,10 @@ void geometry_elementary_add_new_line_cb(CALLBACK_ARGS)
     if(n == 1)
       Msg(ONSCREEN, "Select end point\n"
 	  "[Press 'u' to undo last selection or 'q' to abort]");
-    char ib = SelectEntity(ENT_POINT, vertices, edges, faces, regions);
+    char ib = SelectEntity(ENT_POINT, vertices, edges, faces, regions, elements);
     if(ib == 'l') {
+      HighlightEntity(vertices[0], true);
+      Draw();
       p[n++] = vertices[0]->tag();
     }
     if(ib == 'r') {
@@ -2668,6 +2679,7 @@ void geometry_elementary_add_new_circle_cb(CALLBACK_ARGS)
   std::vector<GEdge*> edges;
   std::vector<GFace*> faces;
   std::vector<GRegion*> regions;
+  std::vector<MElement*> elements;
   int p[100];
 
   opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
@@ -2685,8 +2697,10 @@ void geometry_elementary_add_new_circle_cb(CALLBACK_ARGS)
     if(n == 2)
       Msg(ONSCREEN, "Select end point\n"
 	  "[Press 'u' to undo last selection or 'q' to abort]");
-    char ib = SelectEntity(ENT_POINT, vertices, edges, faces, regions);
+    char ib = SelectEntity(ENT_POINT, vertices, edges, faces, regions, elements);
     if(ib == 'l') {
+      HighlightEntity(vertices[0], true);
+      Draw();
       p[n++] = vertices[0]->tag();
     }
     if(ib == 'r') {
@@ -2722,6 +2736,7 @@ void geometry_elementary_add_new_ellipse_cb(CALLBACK_ARGS)
   std::vector<GEdge*> edges;
   std::vector<GFace*> faces;
   std::vector<GRegion*> regions;
+  std::vector<MElement*> elements;
   int p[100];
 
   opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
@@ -2742,8 +2757,10 @@ void geometry_elementary_add_new_ellipse_cb(CALLBACK_ARGS)
     if(n == 3)
       Msg(ONSCREEN, "Select end point\n"
 	  "[Press 'u' to undo last selection or 'q' to abort]");
-    char ib = SelectEntity(ENT_POINT, vertices, edges, faces, regions);
+    char ib = SelectEntity(ENT_POINT, vertices, edges, faces, regions, elements);
     if(ib == 'l') {
+      HighlightEntity(vertices[0], true);
+      Draw();
       p[n++] = vertices[0]->tag();
     }
     if(ib == 'r') {
@@ -2779,6 +2796,7 @@ static void _new_surface_volume(int mode)
   std::vector<GEdge*> edges;
   std::vector<GFace*> faces;
   std::vector<GRegion*> regions;
+  std::vector<MElement*> elements;
   int type, num;
 
   List_T *List1 = List_Create(10, 10, sizeof(int));
@@ -2818,7 +2836,7 @@ static void _new_surface_volume(int mode)
 	      "[Press 'u' to undo last selection or 'q' to abort]");
       }
 
-      char ib = SelectEntity(type, vertices, edges, faces, regions);
+      char ib = SelectEntity(type, vertices, edges, faces, regions, elements);
       if(ib == 'q') {
         ZeroHighlight();
         Draw();
@@ -2854,7 +2872,7 @@ static void _new_surface_volume(int mode)
 	    else
 	      Msg(ONSCREEN, "Select hole boundaries\n"
 		  "[Press 'e' to end selection, 'u' to undo last selection or 'q' to abort]");
-	    ib = SelectEntity(type, vertices, edges, faces, regions);
+	    ib = SelectEntity(type, vertices, edges, faces, regions, elements);
 	    if(ib == 'q') {
 	      ZeroHighlight();
 	      Draw();
@@ -2936,6 +2954,7 @@ static void _action_point_line_surface_volume(int action, int mode, char *what)
   std::vector<GEdge*> edges;
   std::vector<GFace*> faces;
   std::vector<GRegion*> regions;
+  std::vector<MElement*> elements;
   int type;
   char *str;
 
@@ -2982,7 +3001,7 @@ static void _action_point_line_surface_volume(int action, int mode, char *what)
       Msg(ONSCREEN, "Select %s\n"
 	  "[Press 'e' to end selection, 'u' to undo last selection or 'q' to abort]", str);
 
-    char ib = SelectEntity(type, vertices, edges, faces, regions);
+    char ib = SelectEntity(type, vertices, edges, faces, regions, elements);
     if(ib == 'l') {
       // we don't use List_Insert in order to keep the original
       // ordering (this is slower, but this way undo works as
@@ -2991,6 +3010,7 @@ static void _action_point_line_surface_volume(int action, int mode, char *what)
       switch (type) {
       case ENT_POINT: 
 	for(unsigned int i = 0; i < vertices.size(); i++){
+	  HighlightEntity(vertices[i], true);
 	  tag = vertices[i]->tag();
 	  if(List_ISearchSeq(List1, &tag, fcmp_int) < 0)
 	    List_Add(List1, &tag);
@@ -2998,6 +3018,7 @@ static void _action_point_line_surface_volume(int action, int mode, char *what)
 	break;
       case ENT_LINE:
 	for(unsigned int i = 0; i < edges.size(); i++){
+	  HighlightEntity(edges[i], true);
 	  tag = edges[i]->tag();
 	  if(List_ISearchSeq(List1, &tag, fcmp_int) < 0)
 	    List_Add(List1, &tag);
@@ -3005,6 +3026,7 @@ static void _action_point_line_surface_volume(int action, int mode, char *what)
 	break;
       case ENT_SURFACE:
 	for(unsigned int i = 0; i < faces.size(); i++){
+	  HighlightEntity(faces[i], true);
 	  tag = faces[i]->tag();
 	  if(List_ISearchSeq(List1, &tag, fcmp_int) < 0)
 	    List_Add(List1, &tag);
@@ -3012,12 +3034,14 @@ static void _action_point_line_surface_volume(int action, int mode, char *what)
 	break;
       case ENT_VOLUME:
 	for(unsigned int i = 0; i < regions.size(); i++){
+	  HighlightEntity(regions[i], true);
 	  tag = regions[i]->tag();
 	  if(List_ISearchSeq(List1, &tag, fcmp_int) < 0)
 	    List_Add(List1, &tag);
 	}
 	break;
       }
+      Draw();
     }
     if(ib == 'r') {
       // we don't use List_Suppress in order to keep the original
@@ -3497,14 +3521,120 @@ void mesh_edit_cb(CALLBACK_ARGS)
   WID->set_context(menu_mesh_edit, 0);
 }
 
-void mesh_parameterize_cb(CALLBACK_ARGS)
+void mesh_delete_cb(CALLBACK_ARGS)
 {
-  printf("LAUNCH REPARAMETERIZATION WINDOW!\n");
+  WID->set_context(menu_mesh_delete, 0);
+}
+
+void mesh_delete_parts_cb(CALLBACK_ARGS)
+{
+  char *str = (char*)data;
+  int meshSelection;
+
+  if(!strcmp(str, "elements")){
+    opt_general_mouse_selection(0, GMSH_SET | GMSH_GUI, 3);
+    meshSelection = 2;
+  }
+  else if(!strcmp(str, "surfaces")){
+    opt_general_mouse_selection(0, GMSH_SET | GMSH_GUI, 2);
+    meshSelection = 1;
+  }
+  else{
+    Msg(GERROR, "Unknown mesh edit action");
+    return;
+  }
+  CTX.mesh.changed = ENT_ALL;
+
+  std::vector<GVertex*> vertices;
+  std::vector<GEdge*> edges;
+  std::vector<GFace*> faces, fac;
+  std::vector<GRegion*> regions;
+  std::vector<MElement*> elements, ele;
+
+  while(1) {
+    CTX.mesh.changed = ENT_ALL;
+    Draw();
+
+    if(!ele.size())
+      Msg(ONSCREEN, "Select %s\n"
+	  "[Press 'e' to end selection or 'q' to abort]", str);
+    else
+      Msg(ONSCREEN, "Select %s\n"
+	  "[Press 'e' to end selection, 'u' to undo last selection or 'q' to abort]", str);
+
+    char ib = SelectEntity(ENT_ALL, vertices, edges, faces, regions, 
+			   elements, meshSelection);
+    if(ib == 'l') {
+      if(meshSelection == 2){
+	for(unsigned int i = 0; i < elements.size(); i++){
+	  if(elements[i]->getVisibility() != 2){
+	    elements[i]->setVisibility(2);
+	    ele.push_back(elements[i]);
+	  }
+	}
+      }
+      else{
+	for(unsigned int i = 0; i < faces.size(); i++){
+	  if(faces[i]->getSelection() != 1){
+	    faces[i]->setSelection(1);
+	    fac.push_back(faces[i]);
+	  }
+	}
+      }
+    }
+    if(ib == 'r') {
+      if(meshSelection == 2){
+	for(unsigned int i = 0; i < elements.size(); i++)
+	  elements[i]->setVisibility(1);
+      }
+      else{
+	for(unsigned int i = 0; i < faces.size(); i++)
+	  faces[i]->setSelection(0);
+      }
+    }
+    if(ib == 'u') {
+      if(meshSelection == 2){
+	if(ele.size()){
+	  ele[ele.size() - 1]->setVisibility(1);
+	  ele.pop_back();
+	}
+      }
+      else{
+	if(fac.size()){
+	  fac[fac.size() - 1]->setSelection(0);
+	  fac.pop_back();
+	}
+      }
+    }
+    if(ib == 'e') {
+      if(meshSelection == 2){
+	for(unsigned int i = 0; i < ele.size(); i++)
+	  if(ele[i]->getVisibility() == 2) ele[i]->setVisibility(0);
+      }
+      else{
+	for(unsigned int i = 0; i < fac.size(); i++)
+	  if(fac[i]->getSelection() == 1) fac[i]->setVisibility(0);
+      }
+      GMODEL->removeInvisible();
+      ele.clear();
+      fac.clear();
+    }
+    if(ib == 'q') {
+      for(unsigned int i = 0; i < ele.size(); i++)
+	if(ele[i]->getVisibility() == 2) ele[i]->setVisibility(1);
+      ZeroHighlight();
+      break;
+    }
+  }
+
+  CTX.mesh.changed = ENT_ALL;
+  Draw();  
+  Msg(ONSCREEN, "");
 }
 
-void mesh_cut_parts_cb(CALLBACK_ARGS)
+void mesh_parameterize_cb(CALLBACK_ARGS)
 {
-  printf("LAUNCH CUTTING TOOL!\n");
+  printf("LAUNCH REPARAMETERIZATION WINDOW!\n");
 }
 
 void mesh_degree_cb(CALLBACK_ARGS)
@@ -3543,11 +3673,6 @@ void mesh_update_edges_cb(CALLBACK_ARGS)
   Msg(GERROR, "BDS->classify() must be reinterfaced");
 }
 
-void mesh_update_more_edges_cb(CALLBACK_ARGS)
-{
-  _action_point_line_surface_volume(10, 0, "Line");
-}
-
 void mesh_define_length_cb(CALLBACK_ARGS)
 {
   _action_point_line_surface_volume(8, 0, "Point");
@@ -3569,6 +3694,7 @@ static void _add_transfinite_elliptic(int type, int dim)
   std::vector<GEdge*> edges;
   std::vector<GFace*> faces;
   std::vector<GRegion*> regions;
+  std::vector<MElement*> elements;
   char ib;
   int p[100];
 
@@ -3590,15 +3716,15 @@ static void _add_transfinite_elliptic(int type, int dim)
       else
 	Msg(ONSCREEN, "Select lines\n"
 	    "[Press 'e' to end selection, 'u' to undo last selection or 'q' to abort]");
-      ib = SelectEntity(ENT_LINE, vertices, edges, faces, regions);
+      ib = SelectEntity(ENT_LINE, vertices, edges, faces, regions, elements);
       break;
     case 2:
       Msg(ONSCREEN, "Select surface\n[Press 'q' to abort]");
-      ib = SelectEntity(ENT_SURFACE, vertices, edges, faces, regions);
+      ib = SelectEntity(ENT_SURFACE, vertices, edges, faces, regions, elements);
       break;
     case 3:
       Msg(ONSCREEN, "Select volume\n[Press 'q' to abort]");
-      ib = SelectEntity(ENT_VOLUME, vertices, edges, faces, regions);
+      ib = SelectEntity(ENT_VOLUME, vertices, edges, faces, regions, elements);
       break;
     default:
       ib = 'l';
@@ -3637,14 +3763,22 @@ static void _add_transfinite_elliptic(int type, int dim)
     if(ib == 'l') {
       switch (dim) {
       case 1:
+	HighlightEntity(edges[0], true);
+	Draw();
         p[n++] = edges[0]->tag();
         break;
       case 2:
       case 3:
-	if(dim == 2)
+	if(dim == 2){
+	  HighlightEntity(faces[0], true);
+	  Draw();
 	  p[n++] = faces[0]->tag(); 
-	else
+	}
+	else{
+	  HighlightEntity(regions[0], true);
+	  Draw();
 	  p[n++] = regions[0]->tag(); 
+	}
         while(1) {
 	  if(n == 1)
 	    Msg(ONSCREEN, "Select (ordered) boundary points\n"
@@ -3652,8 +3786,10 @@ static void _add_transfinite_elliptic(int type, int dim)
 	  else
 	    Msg(ONSCREEN, "Select (ordered) boundary points\n"
 		"[Press 'e' to end selection, 'u' to undo last selection or 'q' to abort]");
-          ib = SelectEntity(ENT_POINT, vertices, edges, faces, regions);
+          ib = SelectEntity(ENT_POINT, vertices, edges, faces, regions, elements);
           if(ib == 'l') {
+	    HighlightEntity(vertices[0], true);
+	    Draw();
             p[n++] = vertices[0]->tag();
           }
 	  if(ib == 'u') {
diff --git a/Fltk/Callbacks.h b/Fltk/Callbacks.h
index 23a71247b91571ee70f05c7e457e271be7f3daee..85921b125390e0cbc6a0207a4d9df2e40b997b23 100644
--- a/Fltk/Callbacks.h
+++ b/Fltk/Callbacks.h
@@ -272,10 +272,10 @@ void mesh_1d_cb(CALLBACK_ARGS);
 void mesh_2d_cb(CALLBACK_ARGS); 
 void mesh_3d_cb(CALLBACK_ARGS); 
 void mesh_edit_cb(CALLBACK_ARGS);
+void mesh_delete_cb(CALLBACK_ARGS);
+void mesh_delete_parts_cb(CALLBACK_ARGS);
 void mesh_remesh_cb(CALLBACK_ARGS); 
 void mesh_update_edges_cb(CALLBACK_ARGS); 
-void mesh_update_more_edges_cb(CALLBACK_ARGS);
-void mesh_cut_parts_cb(CALLBACK_ARGS);
 void mesh_parameterize_cb(CALLBACK_ARGS);
 void mesh_degree_cb(CALLBACK_ARGS); 
 void mesh_optimize_cb(CALLBACK_ARGS); 
diff --git a/Fltk/GUI.cpp b/Fltk/GUI.cpp
index c78f92e732ec7fca11f10257461ca27b5e5f70f3..573cb7b3c7fba53b5b9a9b94c24be5fa888fec75 100644
--- a/Fltk/GUI.cpp
+++ b/Fltk/GUI.cpp
@@ -1,4 +1,4 @@
-// $Id: GUI.cpp,v 1.554 2006-10-10 14:04:13 geuzaine Exp $
+// $Id: GUI.cpp,v 1.555 2006-10-31 20:20:21 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -336,13 +336,18 @@ Context_Item menu_mesh[] = {
 };  
     Context_Item menu_mesh_edit[] = {
       {"1Mesh>Edit", NULL} ,
-      {"Cut parts", (Fl_Callback *)mesh_cut_parts_cb} ,
+      {"Delete", (Fl_Callback *)mesh_delete_cb} ,
       {"Parameterize", (Fl_Callback *)mesh_parameterize_cb} ,
       //{"Update edges",   (Fl_Callback *)mesh_update_edges_cb} ,
-      //{"Manually add edges", (Fl_Callback *)mesh_update_more_edges_cb} , 
       //{"Remesh",         (Fl_Callback *)mesh_remesh_cb} , 
       {0} 
     };  
+        Context_Item menu_mesh_delete[] = {
+          {"1Mesh>Edit>Delete", NULL} ,
+          {"Elements", (Fl_Callback *)mesh_delete_parts_cb, (void*)"elements"} ,
+          {"Surfaces", (Fl_Callback *)mesh_delete_parts_cb, (void*)"surfaces"} ,
+          {0} 
+        };  
     Context_Item menu_mesh_define[] = {
       {"1Mesh>Define", NULL} ,
       {"Characteristic length", (Fl_Callback *)mesh_define_length_cb  } ,
diff --git a/Fltk/GUI.h b/Fltk/GUI.h
index fa08a446aa7f1cd09188d906faa8073058425a2a..67b33d7871c0f3ef3acc0c09910adc7dafd0b238 100644
--- a/Fltk/GUI.h
+++ b/Fltk/GUI.h
@@ -89,6 +89,7 @@ extern    Context_Item menu_geometry_physical[];
 extern        Context_Item menu_geometry_physical_add[]; 
 extern Context_Item menu_mesh[]; 
 extern    Context_Item menu_mesh_edit[]; 
+extern        Context_Item menu_mesh_delete[]; 
 extern    Context_Item menu_mesh_define[]; 
 extern        Context_Item menu_mesh_define_transfinite[]; 
 extern Context_Item menu_solver[]; 
diff --git a/Fltk/Opengl.cpp b/Fltk/Opengl.cpp
index 0daf57d8a07231743c44d1cfa71f2311d1808a8c..d1f5f20b39f5a786a24f3d519ba36d9089b474e8 100644
--- a/Fltk/Opengl.cpp
+++ b/Fltk/Opengl.cpp
@@ -1,4 +1,4 @@
-// $Id: Opengl.cpp,v 1.67 2006-08-23 19:53:38 geuzaine Exp $
+// $Id: Opengl.cpp,v 1.68 2006-10-31 20:20:21 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -189,11 +189,13 @@ void Draw_OnScreenMessages()
 
 // Select entity routine
 
-char SelectEntity(int type,
+char SelectEntity(int type, 
 		  std::vector<GVertex*> &vertices,
 		  std::vector<GEdge*> &edges,
 		  std::vector<GFace*> &faces,
-		  std::vector<GRegion*> &regions)
+		  std::vector<GRegion*> &regions,
+		  std::vector<MElement*> &elements,
+		  int meshSelection)
 {
   if(!WID) return 'q';
 
@@ -211,6 +213,7 @@ char SelectEntity(int type,
     edges.clear();
     faces.clear();
     regions.clear();
+    elements.clear();
     WID->wait();
     if(WID->quit_selection) {
       WID->selection = ENT_NONE;
@@ -237,32 +240,19 @@ char SelectEntity(int type,
 	WID->g_opengl_window->SelectionMode = false;
 	return 'c';
       }
-      else if(ProcessSelectionBuffer(WID->selection, multi, true,
+      else if(ProcessSelectionBuffer(WID->selection, multi,
 				     WID->try_selection_xywh[0],
 				     WID->try_selection_xywh[1], 
 				     WID->try_selection_xywh[2],
 				     WID->try_selection_xywh[3], 
-				     vertices, edges, faces, regions)){
+				     vertices, edges, faces, regions,
+				     elements, meshSelection)){
 	WID->selection = ENT_NONE;
 	WID->g_opengl_window->SelectionMode = false;
-	if(add){
-	  for(unsigned int i = 0; i < vertices.size(); i++)
-	    HighlightEntity(vertices[i], true);
-	  for(unsigned int i = 0; i < edges.size(); i++)
-	    HighlightEntity(edges[i], true);
-	  for(unsigned int i = 0; i < faces.size(); i++)
-	    HighlightEntity(faces[i], true);
-	  for(unsigned int i = 0; i < regions.size(); i++)
-	    HighlightEntity(regions[i], true);
-	  Draw();
+	if(add)
 	  return 'l';
-	}
-	else{
-	  // Don't call ZeroHighlight here if we try to deselect:
-	  // deselection is not supported in all cases, so it's better
-	  // to de-highlight the entities in the callback later
+	else
 	  return 'r';
-	}
       }
     }
   }
diff --git a/Fltk/Opengl_Window.cpp b/Fltk/Opengl_Window.cpp
index d3b0ef4e8dd422a57afe0c1ea4cc91c4b42050c3..35a4e5970b62d7320c3808fae7574ae6fd5cbbb8 100644
--- a/Fltk/Opengl_Window.cpp
+++ b/Fltk/Opengl_Window.cpp
@@ -1,4 +1,4 @@
-// $Id: Opengl_Window.cpp,v 1.72 2006-10-10 13:57:10 geuzaine Exp $
+// $Id: Opengl_Window.cpp,v 1.73 2006-10-31 20:20:21 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -378,10 +378,12 @@ int Opengl_Window::handle(int event)
 	std::vector<GEdge*> edges;
 	std::vector<GFace*> faces;
 	std::vector<GRegion*> regions;
-	bool something = ProcessSelectionBuffer(WID->selection, false, 
-						CTX.enable_mouse_selection > 1,
+	std::vector<MElement*> elements;
+	int meshSelection = CTX.enable_mouse_selection > 1 ? 1 : 0;
+	bool something = ProcessSelectionBuffer(WID->selection, false,
 						(int)curr.win[0], (int)curr.win[1], 5, 5, 
-						vertices, edges, faces, regions);
+						vertices, edges, faces, regions,
+						elements, meshSelection);
 	if((WID->selection == ENT_ALL && something) ||
 	   (WID->selection == ENT_POINT && vertices.size()) ||
 	   (WID->selection == ENT_LINE && edges.size()) || 
diff --git a/Geo/GModel.cpp b/Geo/GModel.cpp
index 888a474fe8505ef5e5418b54001654813d49cf21..909dbd75884ccc1178086382d768c9b4ea48b591 100644
--- a/Geo/GModel.cpp
+++ b/Geo/GModel.cpp
@@ -1,4 +1,4 @@
-// $Id: GModel.cpp,v 1.16 2006-08-20 03:54:54 geuzaine Exp $
+// $Id: GModel.cpp,v 1.17 2006-10-31 20:20:21 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -81,6 +81,11 @@ GVertex * GModel::vertexByTag(int n) const
     return 0;
 }
 
+void GModel::removeInvisible()
+{
+  printf("deleting all invisible entities/elements\n");
+}
+
 int GModel::renumberMeshVertices()
 {
   int numVertices = 0;
@@ -179,6 +184,24 @@ int GModel::getMeshStatus()
   return -1;
 }
 
+int GModel::numElement()
+{
+  int n = 0;
+  for(eiter it = firstEdge(); it != lastEdge(); ++it)
+    n += (*it)->lines.size();
+  for(fiter it = firstFace(); it != lastFace(); ++it){
+    n += (*it)->triangles.size();
+    n += (*it)->quadrangles.size();
+  }
+  for(riter it = firstRegion(); it != lastRegion(); ++it){
+    n += (*it)->tetrahedra.size();
+    n += (*it)->hexahedra.size();
+    n += (*it)->prisms.size();
+    n += (*it)->pyramids.size();
+  }
+  return n;
+}
+
 std::set<int> &GModel::recomputeMeshPartitions()
 {
   for(eiter it = firstEdge(); it != lastEdge(); ++it)
diff --git a/Geo/GModel.h b/Geo/GModel.h
index c6794a90daac14a61424ae347ed5a83059b4c0ec..6bd08c30dc264fa987397d0be67e0009269dd4fd 100644
--- a/Geo/GModel.h
+++ b/Geo/GModel.h
@@ -91,6 +91,9 @@ class GModel
   void remove(GEdge *e) { edges.erase(std::find(firstEdge(), lastEdge(), e)); }
   void remove(GVertex *v) { vertices.erase(std::find(firstVertex(), lastVertex(), v)); }
 
+  // Deletes all invisble stuff (entities and elements)
+  void removeInvisible();
+
   // Renumber all the mesh vertices in a continuous sequence
   int renumberMeshVertices();
 
@@ -109,6 +112,9 @@ class GModel
   // Returns the mesh status for the entire model.
   virtual int getMeshStatus();
 
+  // Returns the total number of elements in the mesh
+  virtual int numElement();
+
   // The list of partitions
   virtual std::set<int> &getMeshPartitions() { return meshPartitions; }
   virtual std::set<int> &recomputeMeshPartitions();
diff --git a/Geo/fourierModel.cpp b/Geo/fourierModel.cpp
index 4e478d72c77772a67e0ae8c47b1fdde8b19d235b..0d0918ca32df362fd90da3dec8d94368a89dfe64 100644
--- a/Geo/fourierModel.cpp
+++ b/Geo/fourierModel.cpp
@@ -526,6 +526,8 @@ fourierModel::fourierModel(const std::string &name)
   // mesh each face with quads
   std::for_each(firstFace(), lastFace(), meshCartesian());
 
+  return;
+
   // compute partition of unity
   std::for_each(firstFace(), lastFace(), computePartitionOfUnity());
 
diff --git a/Graphics/Mesh.cpp b/Graphics/Mesh.cpp
index f6814248d9d5c875ab5f6cd8ce4d68b15b8d4ddf..c5710a4c0ad9b461b0cb27352d0e3050cc473f2d 100644
--- a/Graphics/Mesh.cpp
+++ b/Graphics/Mesh.cpp
@@ -1,4 +1,4 @@
-// $Id: Mesh.cpp,v 1.184 2006-08-24 01:14:59 geuzaine Exp $
+// $Id: Mesh.cpp,v 1.185 2006-10-31 20:20:22 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -34,28 +34,6 @@ extern Context_T CTX;
 
 // General helper routines
 
-static unsigned int getColorByElement(MElement *ele)
-{
-  if(CTX.mesh.color_carousel == 0){ // by element type
-    switch(ele->getNumEdges()){
-    case 1: return CTX.color.mesh.line;
-    case 3: return CTX.color.mesh.triangle;
-    case 4: return CTX.color.mesh.quadrangle;
-    case 6: return CTX.color.mesh.tetrahedron;
-    case 12: return CTX.color.mesh.hexahedron;
-    case 9: return CTX.color.mesh.prism;
-    case 8: return CTX.color.mesh.pyramid;
-    default: return CTX.color.mesh.vertex;
-    }
-  }
-  else if(CTX.mesh.color_carousel == 3){ // by partition
-    return CTX.color.mesh.carousel[abs(ele->getPartition() % 20)];
-  }
-  else{
-    return CTX.color.fg;
-  }
-}
-
 static unsigned int getColorByEntity(GEntity *e)
 {
   if(e->getSelection()){ // selection
@@ -82,6 +60,33 @@ static unsigned int getColorByEntity(GEntity *e)
   }
 }
 
+static unsigned int getColorByElement(MElement *ele)
+{
+  if(ele->getVisibility() > 1){ // selection
+    switch(ele->getDim()){
+    case 0: return CTX.color.geom.point_sel;
+    case 1: return CTX.color.geom.line_sel;
+    case 2: return CTX.color.geom.surface_sel;
+    default: return CTX.color.geom.volume_sel;
+    }
+  }
+  else if(CTX.mesh.color_carousel == 3){ // by partition
+    return CTX.color.mesh.carousel[abs(ele->getPartition() % 20)];
+  }
+  else{ // by element type
+    switch(ele->getNumEdges()){
+    case 1: return CTX.color.mesh.line;
+    case 3: return CTX.color.mesh.triangle;
+    case 4: return CTX.color.mesh.quadrangle;
+    case 6: return CTX.color.mesh.tetrahedron;
+    case 12: return CTX.color.mesh.hexahedron;
+    case 9: return CTX.color.mesh.prism;
+    case 8: return CTX.color.mesh.pyramid;
+    default: return CTX.color.mesh.vertex;
+    }
+  }
+}
+
 static double intersectCutPlane(MElement *ele)
 {
   MVertex *v = ele->getVertex(0);
@@ -470,6 +475,9 @@ static void drawArrays(GEntity *e, VertexArray *va, GLint type, bool useNormalAr
     glDisableClientState(GL_COLOR_ARRAY);
     glColor4ubv((GLubyte *) & color);
   }
+  else if(CTX.enable_mouse_selection > 2){
+    glEnableClientState(GL_COLOR_ARRAY);
+  }
   else if(!e->getSelection() && (CTX.mesh.color_carousel == 0 || 
 				 CTX.mesh.color_carousel == 3)){
     glEnableClientState(GL_COLOR_ARRAY);
@@ -607,6 +615,10 @@ class initMeshGFace {
        CTX.mesh.explode != 1. || !m->allElementsVisible)
       useEdges = false;
 
+    // mouse selection of individual elements is complicated if we
+    // don't draw everything per element
+    if(CTX.enable_mouse_selection > 2) useEdges = false;
+
     // Further optimizations are possible when useEdges is true:
     // 1) store the unique vertices in the vertex array and use
     //    glDrawElements() instead of glDrawArrays(). Question:
@@ -635,14 +647,14 @@ class drawMeshGFace {
   void operator () (GFace *f)
   {  
     if(!f->getVisibility()) return;
+
+    MRep *m = f->meshRep;
     
     if(CTX.render_mode == GMSH_SELECT) {
       glPushName(2);
       glPushName(f->tag());
     }
 
-    MRep *m = f->meshRep;
-
     if(CTX.mesh.surfaces_edges){
       if(m->va_lines && m->va_lines->getNumVertices()){
 	drawArrays(f, m->va_lines, GL_LINES, CTX.mesh.light && CTX.mesh.light_lines, 
@@ -717,6 +729,10 @@ class initMeshGRegion {
        CTX.mesh.explode != 1. || !m->allElementsVisible)
       useEdges = false;
     
+    // mouse selection of individual elements is complicated if we
+    // don't draw everything per element
+    if(CTX.enable_mouse_selection > 2) useEdges = false;
+
     if(useEdges){
       Msg(DEBUG, "Using edges to draw volume %d", r->tag());
       m->generateEdgeRep();
diff --git a/Graphics/SelectBuffer.cpp b/Graphics/SelectBuffer.cpp
index 096e2539ba545b727b756f138ab0be1eebf87299..8313750c1aff1c07154ccb5962246a44fa7c663d 100644
--- a/Graphics/SelectBuffer.cpp
+++ b/Graphics/SelectBuffer.cpp
@@ -1,4 +1,4 @@
-// $Id: SelectBuffer.cpp,v 1.4 2006-08-24 17:26:26 geuzaine Exp $
+// $Id: SelectBuffer.cpp,v 1.5 2006-10-31 20:20:22 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -47,21 +47,26 @@ class hitDepthLessThan{
 };
 
 bool ProcessSelectionBuffer(int entityType, bool multipleSelection, 
-			    bool selectMesh, int x, int y, int w, int h,
+			    int x, int y, int w, int h,
 			    std::vector<GVertex*> &vertices,
 			    std::vector<GEdge*> &edges,
 			    std::vector<GFace*> &faces,
-			    std::vector<GRegion*> &regions)
+			    std::vector<GRegion*> &regions,
+			    std::vector<MElement*> &elements,
+			    int meshSelection)
 {
   vertices.clear();
   edges.clear();
   faces.clear();
   regions.clear();
+  elements.clear();
 
   // In our case the selection buffer size is equal to between 5 and 7
   // times the maximum number of possible hits
-  int size = 5 * (GMODEL->numVertex() + GMODEL->numEdge() + 
-		  GMODEL->numFace() + GMODEL->numRegion()) + 1000;
+  int size = 
+    7 * (GMODEL->numVertex() + GMODEL->numEdge() + GMODEL->numFace() + 
+	 GMODEL->numRegion() + (meshSelection > 1 ? 3 * GMODEL->numElement() : 0)) ;
+
   GLuint *selectionBuffer = new GLuint[size];
   glSelectBuffer(size, selectionBuffer);
 
@@ -73,7 +78,7 @@ bool ProcessSelectionBuffer(int entityType, bool multipleSelection,
   InitProjection(x, y, w, h);
   InitPosition();
   Draw_Geom();
-  if(selectMesh) Draw_Mesh();
+  if(meshSelection) Draw_Mesh();
   glPopMatrix();
 
   GLint numhits = glRenderMode(GL_RENDER);
@@ -166,7 +171,7 @@ bool ProcessSelectionBuffer(int entityType, bool multipleSelection,
 	  }
 	  if(hits[i].type2 && e->meshRep){
 	    MElement *ele = e->meshRep->getElement(hits[i].type2, hits[i].ient2);
-	    if(ele) printf("element %d\n", ele->getNum());
+	    if(ele) elements.push_back(ele);
 	  }
 	  edges.push_back(e);
 	  if(!multipleSelection) return true;
@@ -181,7 +186,7 @@ bool ProcessSelectionBuffer(int entityType, bool multipleSelection,
 	  }
 	  if(hits[i].type2 && f->meshRep){
 	    MElement *ele = f->meshRep->getElement(hits[i].type2, hits[i].ient2);
-	    if(ele) printf("element %d\n", ele->getNum());
+	    if(ele) elements.push_back(ele);
 	  }
 	  faces.push_back(f);
 	  if(!multipleSelection) return true;
@@ -196,7 +201,7 @@ bool ProcessSelectionBuffer(int entityType, bool multipleSelection,
 	  }
 	  if(hits[i].type2 && r->meshRep){
 	    MElement *ele = r->meshRep->getElement(hits[i].type2, hits[i].ient2);
-	    if(ele) printf("element %d\n", ele->getNum());
+	    if(ele) elements.push_back(ele);
 	  }
 	  regions.push_back(r);
 	  if(!multipleSelection) return true;
diff --git a/Graphics/SelectBuffer.h b/Graphics/SelectBuffer.h
index 78146179867841841e8ed9cb52f4b86b7c90f88c..b591bdb621b2a0bde5e8c961da53aaad95729019 100644
--- a/Graphics/SelectBuffer.h
+++ b/Graphics/SelectBuffer.h
@@ -36,16 +36,20 @@
 #include "GRegion.h"
 
 bool ProcessSelectionBuffer(int entityType, bool multipleSelection,
-			    bool selectMesh, int x, int y, int w, int h, 
+			    int x, int y, int w, int h, 
 			    std::vector<GVertex*> &vertices,
 			    std::vector<GEdge*> &edges,
 			    std::vector<GFace*> &faces,
-			    std::vector<GRegion*> &regions);
+			    std::vector<GRegion*> &regions,
+			    std::vector<MElement*> &elements,
+			    int meshSelection);
 char SelectEntity(int entityType,
 		  std::vector<GVertex*> &vertices,
 		  std::vector<GEdge*> &edges,
 		  std::vector<GFace*> &faces,
-		  std::vector<GRegion*> &regions);
+		  std::vector<GRegion*> &regions,
+		  std::vector<MElement*> &elements,
+		  int meshSelection=1);
 
 void HighlightEntity(GEntity *e, bool permanent=false);
 void HighlightEntity(GVertex *v, GEdge *e, GFace *f, GRegion *r, bool permanent=false);
diff --git a/Graphics/gl2ps.cpp b/Graphics/gl2ps.cpp
index 89fa20ddcaf4e686135e1468386a9bee5e435ccc..49896490e3480229c2a62480edb2bad0ad14fd5b 100644
--- a/Graphics/gl2ps.cpp
+++ b/Graphics/gl2ps.cpp
@@ -1,4 +1,4 @@
-/* $Id: gl2ps.cpp,v 1.109 2006-08-11 18:48:39 geuzaine Exp $ */
+/* $Id: gl2ps.cpp,v 1.110 2006-10-31 20:20:22 geuzaine Exp $ */
 /*
  * GL2PS, an OpenGL to PostScript Printing Library
  * Copyright (C) 1999-2006 Christophe Geuzaine <geuz@geuz.org>
@@ -48,7 +48,9 @@
  *   Shai Ayal <shaiay@gmail.com>
  *   Fabian Wenzel <wenzel@tu-harburg.de>
  *   Ian D. Gay <gay@sfu.ca>
- *   Cosmin Truta and Baiju Devani <cosmin@cs.toronto.edu>
+ *   Cosmin Truta <cosmin@cs.toronto.edu>
+ *   Baiju Devani <b.devani@gmail.com>
+ *   Alexander Danilov <danilov@lanl.gov>
  *
  * For the latest info about gl2ps, see http://www.geuz.org/gl2ps/.
  * Please report all bugs and problems to <gl2ps@geuz.org>.
@@ -1686,15 +1688,15 @@ static void gl2psRescaleAndOffset()
         (prim->verts[2].xyz[0] - prim->verts[1].xyz[0]) * 
         (prim->verts[1].xyz[1] - prim->verts[0].xyz[1]);
       dZdX = 
-        (prim->verts[2].xyz[1] - prim->verts[1].xyz[1]) *
-        (prim->verts[1].xyz[2] - prim->verts[0].xyz[2]) -
-        (prim->verts[1].xyz[1] - prim->verts[0].xyz[1]) *
-        (prim->verts[2].xyz[2] - prim->verts[1].xyz[2]) / area;
+        ((prim->verts[2].xyz[1] - prim->verts[1].xyz[1]) *
+         (prim->verts[1].xyz[2] - prim->verts[0].xyz[2]) -
+         (prim->verts[1].xyz[1] - prim->verts[0].xyz[1]) *
+         (prim->verts[2].xyz[2] - prim->verts[1].xyz[2])) / area;
       dZdY = 
-        (prim->verts[1].xyz[0] - prim->verts[0].xyz[0]) *
-        (prim->verts[2].xyz[2] - prim->verts[1].xyz[2]) -
-        (prim->verts[2].xyz[0] - prim->verts[1].xyz[0]) *
-        (prim->verts[1].xyz[2] - prim->verts[0].xyz[2]) / area;
+        ((prim->verts[1].xyz[0] - prim->verts[0].xyz[0]) *
+         (prim->verts[2].xyz[2] - prim->verts[1].xyz[2]) -
+         (prim->verts[2].xyz[0] - prim->verts[1].xyz[0]) *
+         (prim->verts[1].xyz[2] - prim->verts[0].xyz[2])) / area;
       maxdZ = (GLfloat)sqrt(dZdX * dZdX + dZdY * dZdY);
       dZ = factor * maxdZ + units;
       prim->verts[0].xyz[2] += dZ;
@@ -2904,7 +2906,9 @@ static void gl2psEndPostScriptLine(void)
 static void gl2psParseStipplePattern(GLushort pattern, GLint factor, 
                                      int *nb, int array[10])
 {
-  int i, n, on[5] = {0, 0, 0, 0, 0}, off[5] = {0, 0, 0, 0, 0};
+  int i, n;
+  int on[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+  int off[8] = {0, 0, 0, 0, 0, 0, 0, 0};
   char tmp[16];
 
   /* extract the 16 bits from the OpenGL stipple pattern */
@@ -2912,22 +2916,24 @@ static void gl2psParseStipplePattern(GLushort pattern, GLint factor,
     tmp[n] = (char)(pattern & 0x01);
     pattern >>= 1;
   }
-  /* compute the on/off pixel sequence (since the PostScript
-     specification allows for at most 11 elements in the on/off array,
-     we limit ourselves to 5 couples of on/off states) */
+  /* compute the on/off pixel sequence */
   n = 0;
-  for(i = 0; i < 5; i++){
+  for(i = 0; i < 8; i++){
     while(n < 16 && !tmp[n]){ off[i]++; n++; }
     while(n < 16 && tmp[n]){ on[i]++; n++; }
-    if(n >= 15) break;
+    if(n >= 15){ i++; break; }
   }
+
   /* store the on/off array from right to left, starting with off
-     pixels (the longest possible array is: [on4 off4 on3 off3 on2
-     off2 on1 off1 on0 off0]) */
+     pixels. The PostScript specification allows for at most 11
+     elements in the on/off array, so we limit ourselves to 5 on/off
+     couples (our longest possible array is thus [on4 off4 on3 off3
+     on2 off2 on1 off1 on0 off0]) */
   *nb = 0;
-  for(n = i; n >= 0; n--){
+  for(n = i - 1; n >= 0; n--){
     array[(*nb)++] = factor * on[n];
     array[(*nb)++] = factor * off[n];
+    if(*nb == 10) break;
   }
 }
 
@@ -4839,29 +4845,34 @@ static void gl2psSVGGetColorString(GL2PSrgba rgba, char str[32])
 
 static void gl2psPrintSVGHeader(void)
 {
+  int x, y, width, height;
   char col[32];
   time_t now;
-
+  
+  time(&now);
+  
+  if (gl2ps->options & GL2PS_LANDSCAPE){
+    x = (int)gl2ps->viewport[1];
+    y = (int)gl2ps->viewport[0];
+    width = (int)gl2ps->viewport[3];
+    height = (int)gl2ps->viewport[2];
+  }
+  else{
+    x = (int)gl2ps->viewport[0];
+    y = (int)gl2ps->viewport[1];
+    width = (int)gl2ps->viewport[2];
+    height = (int)gl2ps->viewport[3];
+  }
+  
   /* Compressed SVG files (.svgz) are simply gzipped SVG files */
   gl2psPrintGzipHeader();
-
-  time(&now);
-
+  
   gl2psPrintf("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n");
   gl2psPrintf("<svg xmlns=\"http://www.w3.org/2000/svg\"\n");
-  gl2psPrintf("     xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n");
-  gl2psPrintf("     viewBox=\"%d %d %d %d\">\n",
-              (gl2ps->options & GL2PS_LANDSCAPE) ? (int)gl2ps->viewport[1] : 
-              (int)gl2ps->viewport[0],
-              (gl2ps->options & GL2PS_LANDSCAPE) ? (int)gl2ps->viewport[0] :
-              (int)gl2ps->viewport[1],
-              (gl2ps->options & GL2PS_LANDSCAPE) ? (int)gl2ps->viewport[3] : 
-              (int)gl2ps->viewport[2],
-              (gl2ps->options & GL2PS_LANDSCAPE) ? (int)gl2ps->viewport[2] :
-              (int)gl2ps->viewport[3]);
-  gl2psPrintf("<title>\n");
-  gl2psPrintf("%s\n", gl2ps->title);
-  gl2psPrintf("</title>\n");
+  gl2psPrintf("     xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n"
+	      "     width=\"%dpx\" height=\"%dpx\" viewBox=\"%d %d %d %d\">\n",
+	      width, height, x, y, width, height);
+  gl2psPrintf("<title>%s</title>\n", gl2ps->title);
   gl2psPrintf("<desc>\n");
   gl2psPrintf("Creator: GL2PS %d.%d.%d%s, %s\n"
               "For: %s\n"