diff --git a/Fltk/GUI_Projection.cpp b/Fltk/GUI_Projection.cpp
index a3d30ce7a88fd4261119b20ea05ba9ad184aadac..421c58af22dad908deefed1fa32ebdde9e29a24e 100644
--- a/Fltk/GUI_Projection.cpp
+++ b/Fltk/GUI_Projection.cpp
@@ -2,15 +2,92 @@
 #include "GmshUI.h"
 #include "GModel.h"
 #include "projectionFace.h"
+#include "Draw.h"
+#include "Context.h"
+
+#include "Shortcut_Window.h"
+
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Return_Button.H>
+#include <FL/Fl_Value_Slider.H>
 
 extern GModel *GMODEL;
+extern Context_T CTX;
+
+int projection_editor(char *title, double &a, double &b, double &c)
+{
+  struct _editor{
+    Fl_Window *window;
+    Fl_Value_Slider *sa, *sb, *sc;
+    Fl_Button *cancel;
+  };
+  static _editor *editor = 0;
+
+  const int BH = 2 * CTX.fontsize + 1;
+  const int BB = 7 * CTX.fontsize;
+  const int WB = 7;
+
+  if(!editor){
+    editor = new _editor;
+    editor->window = new Dialog_Window(2 * BB + 3 * WB, 4 * BH + 3 * WB);
+    editor->sa = new Fl_Value_Slider(WB, WB, BB, BH, "blabla");
+    editor->sa->type(FL_HOR_SLIDER);
+    editor->sa->align(FL_ALIGN_RIGHT);
+    editor->sb = new Fl_Value_Slider(WB, WB + BH, BB, BH, "blibli");
+    editor->sb->type(FL_HOR_SLIDER);
+    editor->sb->align(FL_ALIGN_RIGHT);
+    editor->sc = new Fl_Value_Slider(WB, WB + 2 * BH, BB, BH, "blublu");
+    editor->sc->type(FL_HOR_SLIDER);
+    editor->sc->align(FL_ALIGN_RIGHT);
+    editor->cancel = new Fl_Button(2 * WB + BB, 2 * WB + 3 * BH, BB, BH, "Cancel");
+    editor->window->end();
+    editor->window->hotspot(editor->window);
+  }
+  
+  editor->window->label(title);
+  editor->sa->value(a);
+  editor->sb->value(b);
+  editor->sc->value(c);
+  editor->window->show();
+
+  while(editor->window->shown()){
+    Fl::wait();
+    for (;;) {
+      Fl_Widget* o = Fl::readqueue();
+      if (!o) break;
+
+      Draw();
+
+      if (o == editor->sa)
+	a = editor->sa->value();
+      if (o == editor->sb)
+	b = editor->sb->value();
+      if (o == editor->sc)
+	c = editor->sc->value();
+      if (o == editor->window || o == editor->cancel){
+	editor->window->hide();
+	return 0;
+      }
+    }
+  }
+  return 0;
+}
 
 void mesh_parameterize_cb(Fl_Widget* w, void* data)
 {
-  parabolicCylinder *p = new parabolicCylinder(GMODEL,10000);
+  projectionFace *p = new parabolicCylinder(GMODEL,10000);
 
   GMODEL->add( p );
 
-  Msg(GERROR, "Model added: %d faces", GMODEL->numFace());
-	
+  CTX.mesh.changed = ENT_SURFACE;
+  CTX.geom.surfaces = 1;
+  
+  double a=0., b=0., c=0.;
+  projection_editor("Projection editor", a, b, c);
+
+  Draw();
+
+  //SBoundingBox3d bb = GMODEL->bounds();
+
+  Msg(INFO, "Model added: %d faces", GMODEL->numFace());
 }
diff --git a/Fltk/Makefile b/Fltk/Makefile
index 8b4647219ab94c66d014357fe9db58fe5048e6ed..9d319bbf79622803477e5293c31eea1253ab701b 100644
--- a/Fltk/Makefile
+++ b/Fltk/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.118 2006-11-29 20:40:47 geuzaine Exp $
+# $Id: Makefile,v 1.119 2006-12-05 18:34:58 geuzaine Exp $
 #
 # Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 #
@@ -130,7 +130,10 @@ GUI_Projection.o: GUI_Projection.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../Geo/MElement.h ../Geo/SPoint2.h ../Geo/SVector3.h ../Geo/Pair.h \
   ../Geo/ExtrudeParams.h ../Geo/GRegion.h ../Geo/GEntity.h \
   ../Geo/MElement.h ../Geo/ExtrudeParams.h ../Geo/SBoundingBox3d.h \
-  ../Common/SmoothNormals.h ../Geo/projectionFace.h ../Geo/GFace.h
+  ../Common/SmoothNormals.h ../Geo/projectionFace.h ../Geo/GFace.h \
+  ../Graphics/Draw.h ../Common/Views.h ../Common/ColorTable.h \
+  ../Common/VertexArray.h ../Common/SmoothNormals.h \
+  ../Common/AdaptiveViews.h ../Common/GmshMatrix.h Shortcut_Window.h
 Callbacks.o: Callbacks.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 \
diff --git a/Geo/GEntity.h b/Geo/GEntity.h
index f4577c4efc415b35ce5aecd9019d6b3e377b2029..4acc2a0cfa7b91a9fb1d8f487b933196d0ca2f8d 100644
--- a/Geo/GEntity.h
+++ b/Geo/GEntity.h
@@ -80,6 +80,7 @@ class GEntity {
     Torus,
     RuledSurface,
     ParametricSurface,
+    ProjectionSurface,
     BSplineSurface,
     DiscreteSurface,
     Volume,
@@ -107,6 +108,7 @@ class GEntity {
       "Torus",
       "Ruled surface",
       "Parametric surface",
+      "Projection surface",
       "BSpline surface",
       "Discrete surface",
       "Volume",
diff --git a/Geo/projectionFace.h b/Geo/projectionFace.h
index 77b4c69d057477a781a40ec417a5bbbe34f3078e..f2f6be5a9142a5aa765217d6d611f46cee7127db 100644
--- a/Geo/projectionFace.h
+++ b/Geo/projectionFace.h
@@ -52,7 +52,7 @@ class projectionFace : public GFace
   virtual double * nthDerivative(const SPoint2 &param, int n,  
  				 double *array) const {throw;}
   
-  virtual GEntity::GeomType geomType() const {throw;} 
+  virtual GEntity::GeomType geomType() const { return GEntity::ProjectionSurface; }
   virtual int geomDirection() const { return 1; }
   
   virtual bool continuous(int dim) const { return true; }
diff --git a/Graphics/Geom.cpp b/Graphics/Geom.cpp
index 78314d6f47e7d9613382ec4e2e088f59fa50b55b..a41a8e6ec9ec64ab5a41a98734f1bf1acafd3689 100644
--- a/Graphics/Geom.cpp
+++ b/Graphics/Geom.cpp
@@ -1,4 +1,4 @@
-// $Id: Geom.cpp,v 1.124 2006-11-27 22:22:14 geuzaine Exp $
+// $Id: Geom.cpp,v 1.125 2006-12-05 18:34:58 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -228,6 +228,27 @@ class drawGFace {
     }
   }
   
+  void _drawProjectionGFace(GFace *f)
+  {
+    Range<double> ubounds = f->parBounds(0);
+    Range<double> vbounds = f->parBounds(1);
+    const int N = 10;
+    
+    glBegin(GL_POINTS);
+    for(int i = 0; i < N; i++){
+      for(int j = 0; j < N; j++){
+	double u = ubounds.low() + (double)i/(double)(N-1) * 
+	  (ubounds.high() - ubounds.low());
+	double v = vbounds.low() + (double)j/(double)(N-1) * 
+	  (vbounds.high() - vbounds.low());
+	GPoint p = f->point(u, v);
+	printf("%g %g %g\n", p.x(), p.y(), p.z());
+	glVertex3d(p.x(), p.y(), p.z());
+      }
+    }
+    glEnd();
+  }
+
   void _drawPlaneGFace(GFace *f)
   {
     // We create data here and the routine is not designed to be
@@ -350,6 +371,8 @@ public :
     
     if(f->geomType() == GEntity::Plane)
       _drawPlaneGFace(f);
+    else if(f->geomType() == GEntity::ProjectionSurface)
+      _drawProjectionGFace(f);
     else
       _drawNonPlaneGFace(f);
     
diff --git a/Graphics/Mesh.cpp b/Graphics/Mesh.cpp
index c5353815776255d7cb41fb355dbd7ed5d1320866..0afb581af20def482a8a1875e3241d67fd416464 100644
--- a/Graphics/Mesh.cpp
+++ b/Graphics/Mesh.cpp
@@ -1,4 +1,4 @@
-// $Id: Mesh.cpp,v 1.190 2006-11-27 22:22:16 geuzaine Exp $
+// $Id: Mesh.cpp,v 1.191 2006-12-05 18:34:58 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -590,6 +590,8 @@ class drawMeshGEdge {
 
     MRep *m = e->meshRep;
 
+    if(!m) return;
+
     if(CTX.mesh.lines)
       drawArrays(e, m->va_lines, GL_LINES, false);
 
@@ -677,7 +679,9 @@ class drawMeshGFace {
     if(!f->getVisibility()) return;
 
     MRep *m = f->meshRep;
-    
+
+    if(!m) return;
+
     if(CTX.render_mode == GMSH_SELECT) {
       glPushName(2);
       glPushName(f->tag());
@@ -809,6 +813,8 @@ class drawMeshGRegion {
 
     MRep *m = r->meshRep;
 
+    if(!m) return;
+
     if(CTX.mesh.volumes_edges){
       if(m->va_lines && m->va_lines->getNumVertices()){
 	drawArrays(r, m->va_lines, GL_LINES, CTX.mesh.light && CTX.mesh.light_lines,