diff --git a/Common/Context.h b/Common/Context.h
index 8c2900debc4c32b115a149bcdfde7a9b6fb1eb59..73e27ae76422a938944b9a3ce393b977af6dacd9 100644
--- a/Common/Context.h
+++ b/Common/Context.h
@@ -174,7 +174,7 @@ public :
     int histogram, initial_only;
     double normals, tangents, explode;
     int color_scheme, color_carousel ;
-    int use_cut_plane;
+    int use_cut_plane, cut_plane_as_surface;
     double cut_planea,cut_planeb,cut_planec,cut_planed;
     double evalCutPlane (double x, double y, double z){
       double val = cut_planea * x + cut_planeb * y + cut_planec * z + cut_planed; 
diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h
index 1ab63e4eab94cecebd390e4be975d45c1d18361b..70da94164be1eccf5e74efe96155959da1168eaa 100644
--- a/Common/DefaultOptions.h
+++ b/Common/DefaultOptions.h
@@ -720,6 +720,8 @@ StringXNumber MeshOptions_Number[] = {
     "CPU time for the generation of the current mesh (in seconds)" },
   { F,   "CutPlane" , opt_mesh_use_cut_plane , 0 ,
     "Enable mesh cut plane" },
+  { F,   "CutPlaneAsSurface" , opt_mesh_cut_plane_as_surface , 1 ,
+    "Draw the cut as a surface to speed up drawing" },
   { F,   "CutPlaneA" , opt_mesh_cut_planea , 1. , 
     "First cut plane equation coefficient (`A' in `AX+BY+CZ+D=0')" },
   { F,   "CutPlaneB" , opt_mesh_cut_planeb , 0. , 
diff --git a/Common/Options.cpp b/Common/Options.cpp
index 11d5bddcbc4de1ed71342ce5c69087b1cf38c8e9..a3ac107f4bfa965436d0448b3e007116b1f9c950 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -1,4 +1,4 @@
-// $Id: Options.cpp,v 1.146 2004-04-20 21:47:36 geuzaine Exp $
+// $Id: Options.cpp,v 1.147 2004-04-21 04:26:44 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -3475,13 +3475,32 @@ double opt_mesh_use_cut_plane(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
     CTX.mesh.use_cut_plane = (int)val;
+#if defined(HAVE_FLTK)
+  if(WID && (action & GMSH_GUI))
+    WID->mesh_butt[16]->value(CTX.mesh.use_cut_plane);
+#endif
   return CTX.mesh.use_cut_plane;
 }
 
+double opt_mesh_cut_plane_as_surface(OPT_ARGS_NUM)
+{
+  if(action & GMSH_SET)
+    CTX.mesh.cut_plane_as_surface = (int)val;
+#if defined(HAVE_FLTK)
+  if(WID && (action & GMSH_GUI))
+    WID->mesh_butt[22]->value(CTX.mesh.cut_plane_as_surface);
+#endif
+  return CTX.mesh.cut_plane_as_surface;
+}
+
 double opt_mesh_cut_planea(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
     CTX.mesh.cut_planea = val;
+#if defined(HAVE_FLTK)
+  if(WID && (action & GMSH_GUI))
+    WID->mesh_value[14]->value(CTX.mesh.cut_planea);
+#endif
   return CTX.mesh.cut_planea;
 }
 
@@ -3489,6 +3508,10 @@ double opt_mesh_cut_planeb(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
     CTX.mesh.cut_planeb = val;
+#if defined(HAVE_FLTK)
+  if(WID && (action & GMSH_GUI))
+    WID->mesh_value[15]->value(CTX.mesh.cut_planeb);
+#endif
   return CTX.mesh.cut_planeb;
 }
 
@@ -3496,6 +3519,10 @@ double opt_mesh_cut_planec(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
     CTX.mesh.cut_planec = val;
+#if defined(HAVE_FLTK)
+  if(WID && (action & GMSH_GUI))
+    WID->mesh_value[16]->value(CTX.mesh.cut_planec);
+#endif
   return CTX.mesh.cut_planec;
 }
 
@@ -3503,6 +3530,10 @@ double opt_mesh_cut_planed(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
     CTX.mesh.cut_planed = val;
+#if defined(HAVE_FLTK)
+  if(WID && (action & GMSH_GUI))
+    WID->mesh_value[17]->value(CTX.mesh.cut_planed);
+#endif
   return CTX.mesh.cut_planed;
 }
 
diff --git a/Common/Options.h b/Common/Options.h
index 861c679a71bb6ab94ebf95fcc1d32483c13b7a3c..442350e7cfa0fc490a7b660a889496a69e3bb012 100644
--- a/Common/Options.h
+++ b/Common/Options.h
@@ -376,6 +376,7 @@ double opt_mesh_order(OPT_ARGS_NUM);
 double opt_mesh_dual(OPT_ARGS_NUM);
 double opt_mesh_interactive(OPT_ARGS_NUM);
 double opt_mesh_use_cut_plane(OPT_ARGS_NUM);
+double opt_mesh_cut_plane_as_surface(OPT_ARGS_NUM);
 double opt_mesh_cut_planea(OPT_ARGS_NUM);
 double opt_mesh_cut_planeb(OPT_ARGS_NUM);
 double opt_mesh_cut_planec(OPT_ARGS_NUM);
diff --git a/Fltk/Callbacks.cpp b/Fltk/Callbacks.cpp
index 93d1eb4edb92b805a426a11eb1ba2bb555a6d89c..47b86f0aea569e66c4ce50fa24645e64493a7168 100644
--- a/Fltk/Callbacks.cpp
+++ b/Fltk/Callbacks.cpp
@@ -1,4 +1,4 @@
-// $Id: Callbacks.cpp,v 1.217 2004-04-21 00:28:50 geuzaine Exp $
+// $Id: Callbacks.cpp,v 1.218 2004-04-21 04:26:44 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -1087,6 +1087,8 @@ void mesh_options_ok_cb(CALLBACK_ARGS)
   opt_mesh_lines_num(0, GMSH_SET, WID->mesh_butt[13]->value());
   opt_mesh_surfaces_num(0, GMSH_SET, WID->mesh_butt[14]->value());
   opt_mesh_volumes_num(0, GMSH_SET, WID->mesh_butt[15]->value());
+  opt_mesh_use_cut_plane(0, GMSH_SET, WID->mesh_butt[16]->value());
+  opt_mesh_cut_plane_as_surface(0, GMSH_SET, WID->mesh_butt[22]->value());
   opt_mesh_light(0, GMSH_SET, WID->mesh_butt[17]->value());
   opt_mesh_color_carousel(0, GMSH_SET,
 			  WID->mesh_butt[18]->value()? 0 :
@@ -1107,6 +1109,10 @@ void mesh_options_ok_cb(CALLBACK_ARGS)
   opt_mesh_tangents(0, GMSH_SET, WID->mesh_value[13]->value());
   opt_mesh_point_size(0, GMSH_SET, WID->mesh_value[10]->value());
   opt_mesh_line_width(0, GMSH_SET, WID->mesh_value[11]->value());
+  opt_mesh_cut_planea(0, GMSH_SET, WID->mesh_value[14]->value());
+  opt_mesh_cut_planeb(0, GMSH_SET, WID->mesh_value[15]->value());
+  opt_mesh_cut_planec(0, GMSH_SET, WID->mesh_value[16]->value());
+  opt_mesh_cut_planed(0, GMSH_SET, WID->mesh_value[17]->value());
 
   opt_mesh_point_type(0, GMSH_SET, WID->mesh_choice[0]->value());
   opt_mesh_line_type(0, GMSH_SET, WID->mesh_choice[1]->value());
diff --git a/Fltk/GUI.cpp b/Fltk/GUI.cpp
index 030bf8dbf62a8c8d2e6ba6871ca7cefed0c4495a..baacff23e5616cfe288e4d8f6724bbce9f64b336 100644
--- a/Fltk/GUI.cpp
+++ b/Fltk/GUI.cpp
@@ -1,4 +1,4 @@
-// $Id: GUI.cpp,v 1.286 2004-04-21 00:28:50 geuzaine Exp $
+// $Id: GUI.cpp,v 1.287 2004-04-21 04:26:45 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -1853,7 +1853,6 @@ void GUI::create_option_window()
       mesh_butt[17]->type(FL_TOGGLE_BUTTON);
       mesh_butt[17]->down_box(TOGGLE_BOX);
       mesh_butt[17]->selection_color(TOGGLE_COLOR);
-      mesh_butt[17]->selection_color(RADIO_COLOR);
 
       mesh_value[9] = new Fl_Value_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Explode elements");
       mesh_value[9]->minimum(0);
@@ -1912,6 +1911,27 @@ void GUI::create_option_window()
       s->end();
       o->end();
     }
+    {
+      Fl_Group *o = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Cut plane");
+      o->hide();
+      mesh_butt[16] = new Fl_Check_Button(2 * WB, 2 * WB + 1 * BH, BW, BH, "Enable");
+      mesh_butt[16]->type(FL_TOGGLE_BUTTON);
+      mesh_butt[16]->down_box(TOGGLE_BOX);
+      mesh_butt[16]->selection_color(TOGGLE_COLOR);
+      mesh_butt[22] = new Fl_Check_Button(2 * WB, 2 * WB + 2 * BH, BW, BH, "Draw intersecting layer as surface");
+      mesh_butt[22]->type(FL_TOGGLE_BUTTON);
+      mesh_butt[22]->down_box(TOGGLE_BOX);
+      mesh_butt[22]->selection_color(TOGGLE_COLOR);
+
+      mesh_value[14] = new Fl_Value_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "A");
+      mesh_value[15] = new Fl_Value_Input(2 * WB, 2 * WB + 4 * BH, IW, BH, "B");
+      mesh_value[16] = new Fl_Value_Input(2 * WB, 2 * WB + 5 * BH, IW, BH, "C");
+      mesh_value[17] = new Fl_Value_Input(2 * WB, 2 * WB + 6 * BH, IW, BH, "D");
+      for(i = 14; i <= 17; i++) {
+        mesh_value[i]->align(FL_ALIGN_RIGHT);
+      }
+      o->end();
+    }
     o->end();
   }
   mesh_window->end();
diff --git a/Graphics/Mesh.cpp b/Graphics/Mesh.cpp
index d63e3b1ced62e38fffc1602943ce2e7931968c1f..f54f2dda09c6e1ba3385e3cb7cbbadfa8302bb1a 100644
--- a/Graphics/Mesh.cpp
+++ b/Graphics/Mesh.cpp
@@ -1,4 +1,4 @@
-// $Id: Mesh.cpp,v 1.75 2004-04-20 22:36:39 geuzaine Exp $
+// $Id: Mesh.cpp,v 1.76 2004-04-21 04:26:45 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -151,7 +151,9 @@ void Draw_Mesh(Mesh * M)
       //printf("normal mesh drawing\n");
 
       if(M->status >= 3 && (CTX.mesh.volumes_faces || CTX.mesh.volumes_edges ||
-			    CTX.mesh.volumes_num)) {
+			    CTX.mesh.volumes_num || 
+			    (CTX.mesh.use_cut_plane && CTX.mesh.cut_plane_as_surface &&
+			     (CTX.mesh.surfaces_edges || CTX.mesh.surfaces_faces)))) {
 	Tree_Action(M->Volumes, Draw_Mesh_Volumes);
       }
 
@@ -637,6 +639,22 @@ void Draw_Simplex_Surface(void *a, void *b)
   }
 }
 
+int intersectCutPlane(int num, Vertex **v, int *edges, int *faces)
+{
+  if(CTX.mesh.cut_plane_as_surface && 
+     (CTX.mesh.surfaces_edges || CTX.mesh.surfaces_faces)){
+    double val = CTX.mesh.evalCutPlane(v[0]->Pos.X, v[0]->Pos.Y, v[0]->Pos.Z);
+    for(int i = 1; i < num; i++){
+      if(val * CTX.mesh.evalCutPlane(v[i]->Pos.X, v[i]->Pos.Y, v[i]->Pos.Z) < 0){
+	*edges = CTX.mesh.surfaces_edges;
+	*faces = CTX.mesh.surfaces_faces;
+	return 1;
+      }
+    }
+  }
+  return 0;
+}
+
 void Draw_Simplex_Volume(void *a, void *b)
 {
   Simplex *s;
@@ -681,12 +699,16 @@ void Draw_Simplex_Volume(void *a, void *b)
   double Zc = .25 * (s->V[0]->Pos.Z + s->V[1]->Pos.Z +
                      s->V[2]->Pos.Z + s->V[3]->Pos.Z);
 
+  int edges = CTX.mesh.volumes_edges;
+  int faces = CTX.mesh.volumes_faces;
+
   if(CTX.mesh.use_cut_plane) {
-    if(CTX.mesh.evalCutPlane(Xc, Yc, Zc) < 0)
-      return;
+    if(!intersectCutPlane(3, s->V, &edges, &faces))
+      if(CTX.mesh.evalCutPlane(Xc, Yc, Zc) < 0)
+	return;
   }
 
-  if(CTX.mesh.surfaces_faces || CTX.mesh.volumes_faces){
+  if(CTX.mesh.surfaces_faces || faces){
     glColor4ubv((GLubyte *) & CTX.color.mesh.line);
   }
   else{
@@ -715,7 +737,7 @@ void Draw_Simplex_Volume(void *a, void *b)
     }
   }
 
-  if(CTX.mesh.volumes_edges) {
+  if(edges) {
     if(!s->VSUP){
       glBegin(GL_LINES);
       glVertex3d(X[0], Y[0], Z[0]); glVertex3d(X[1], Y[1], Z[1]);
@@ -778,7 +800,7 @@ void Draw_Simplex_Volume(void *a, void *b)
     gl2psDisable(GL2PS_LINE_STIPPLE);
   }
 
-  if(CTX.mesh.volumes_faces){
+  if(faces){
     if(theColor.type)
       glColor4ubv((GLubyte *) & theColor.mesh);
     else if(CTX.mesh.color_carousel == 1)
@@ -926,12 +948,16 @@ void Draw_Hexahedron_Volume(void *a, void *b)
   Zc *= .125;
   Yc *= .125;
 
+  int edges = CTX.mesh.volumes_edges;
+  int faces = CTX.mesh.volumes_faces;
+
   if(CTX.mesh.use_cut_plane) {
-    if(CTX.mesh.evalCutPlane(Xc, Yc, Zc) < 0)
-      return;
+    if(!intersectCutPlane(8, h->V, &edges, &faces))
+      if(CTX.mesh.evalCutPlane(Xc, Yc, Zc) < 0)
+	return;
   }
 
-  if(CTX.mesh.surfaces_faces || CTX.mesh.volumes_faces){
+  if(CTX.mesh.surfaces_faces || faces){
     glColor4ubv((GLubyte *) & CTX.color.mesh.line);
   }
   else{
@@ -953,7 +979,7 @@ void Draw_Hexahedron_Volume(void *a, void *b)
     Z[i] = Zc + CTX.mesh.explode * (h->V[i]->Pos.Z - Zc);
   }
 
-  if(CTX.mesh.volumes_edges){
+  if(edges){
     glBegin(GL_LINE_LOOP);
     glVertex3d(X[0], Y[0], Z[0]);
     glVertex3d(X[1], Y[1], Z[1]);
@@ -1025,7 +1051,7 @@ void Draw_Hexahedron_Volume(void *a, void *b)
     gl2psDisable(GL2PS_LINE_STIPPLE);
   }
 
-  if(CTX.mesh.volumes_faces){
+  if(faces){
     if(theColor.type)
       glColor4ubv((GLubyte *) & theColor.mesh);
     else if(CTX.mesh.color_carousel == 1)
@@ -1114,12 +1140,16 @@ void Draw_Prism_Volume(void *a, void *b)
   Zc /= 6.;
   Yc /= 6.;
 
+  int edges = CTX.mesh.volumes_edges;
+  int faces = CTX.mesh.volumes_faces;
+
   if(CTX.mesh.use_cut_plane) {
-    if(CTX.mesh.evalCutPlane(Xc, Yc, Zc) < 0)
-      return;
+    if(!intersectCutPlane(6, p->V, &edges, &faces))
+      if(CTX.mesh.evalCutPlane(Xc, Yc, Zc) < 0)
+	return;
   }
 
-  if(CTX.mesh.surfaces_faces || CTX.mesh.volumes_faces){
+  if(CTX.mesh.surfaces_faces || faces){
     glColor4ubv((GLubyte *) & CTX.color.mesh.line);
   }
   else{
@@ -1141,7 +1171,7 @@ void Draw_Prism_Volume(void *a, void *b)
     Z[i] = Zc + CTX.mesh.explode * (p->V[i]->Pos.Z - Zc);
   }
 
-  if(CTX.mesh.volumes_edges){
+  if(edges){
     glBegin(GL_LINE_LOOP);
     glVertex3d(X[0], Y[0], Z[0]);
     glVertex3d(X[1], Y[1], Z[1]);
@@ -1204,7 +1234,7 @@ void Draw_Prism_Volume(void *a, void *b)
     gl2psDisable(GL2PS_LINE_STIPPLE);
   }
 
-  if(CTX.mesh.volumes_faces){
+  if(faces){
     if(theColor.type)
       glColor4ubv((GLubyte *) & theColor.mesh);
     else if(CTX.mesh.color_carousel == 1)
@@ -1287,12 +1317,16 @@ void Draw_Pyramid_Volume(void *a, void *b)
   Zc /= 5.;
   Yc /= 5.;
 
+  int edges = CTX.mesh.volumes_edges;
+  int faces = CTX.mesh.volumes_faces;
+
   if(CTX.mesh.use_cut_plane) {
-    if(CTX.mesh.evalCutPlane(Xc, Yc, Zc) < 0)
-      return;
+    if(!intersectCutPlane(5, p->V, &edges, &faces))
+      if(CTX.mesh.evalCutPlane(Xc, Yc, Zc) < 0)
+	return;
   }
 
-  if(CTX.mesh.surfaces_faces || CTX.mesh.volumes_faces){
+  if(CTX.mesh.surfaces_faces || faces){
     glColor4ubv((GLubyte *) & CTX.color.mesh.line);
   }
   else{
@@ -1314,7 +1348,7 @@ void Draw_Pyramid_Volume(void *a, void *b)
     Z[i] = Zc + CTX.mesh.explode * (p->V[i]->Pos.Z - Zc);
   }
 
-  if(CTX.mesh.volumes_edges){
+  if(edges){
     glBegin(GL_LINE_LOOP);
     glVertex3d(X[0], Y[0], Z[0]);
     glVertex3d(X[1], Y[1], Z[1]);
@@ -1339,7 +1373,7 @@ void Draw_Pyramid_Volume(void *a, void *b)
     Draw_String(Num);
   }
 
-  if(CTX.mesh.volumes_faces){
+  if(faces){
     if(theColor.type)
       glColor4ubv((GLubyte *) & theColor.mesh);
     else if(CTX.mesh.color_carousel == 1)