diff --git a/Graphics/Geom.cpp b/Graphics/Geom.cpp
index 0a88f23cca2efe062d66a97b2d9f4bf8e950b529..719e5990bc6c685076711f72ba8d7cf3c5a3c531 100644
--- a/Graphics/Geom.cpp
+++ b/Graphics/Geom.cpp
@@ -1,4 +1,4 @@
-// $Id: Geom.cpp,v 1.65 2004-05-31 18:36:20 geuzaine Exp $
+// $Id: Geom.cpp,v 1.66 2004-06-22 17:34:10 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -285,6 +285,8 @@ void Draw_Triangulated_Surface(Surface * s)
   }  
 }
 
+void Get_SurfaceNormal(Surface *s, double n[3]);
+
 void Draw_Plane_Surface(Surface * s)
 {
   int i, j, k;
@@ -441,10 +443,12 @@ void Draw_Plane_Surface(Surface * s)
     if(CTX.geom.normals) {
       List_Read(s->Orientations, 0, &vv1);
       List_Read(s->Orientations, 1, &vv2);
-      n[0] = s->plan[2][0];
-      n[1] = s->plan[2][1];
-      n[2] = s->plan[2][2];
-      norme(n);
+      // don't rely on MeanPlane: teh orientation is arbotrary
+      //n[0] = s->plan[2][0];
+      //n[1] = s->plan[2][1];
+      //n[2] = s->plan[2][2];
+      //norme(n);
+      Get_SurfaceNormal(s, n);
       n[0] *= CTX.geom.normals * CTX.pixel_equiv_x / CTX.s[0];
       n[1] *= CTX.geom.normals * CTX.pixel_equiv_x / CTX.s[1];
       n[2] *= CTX.geom.normals * CTX.pixel_equiv_x / CTX.s[2];
@@ -516,25 +520,16 @@ void Draw_NonPlane_Surface(Surface * s)
   }
 
   if(CTX.geom.normals) {
-    Vertex n1 = InterpolateSurface(s, 0.5, 0.5, 0, 0);
-    Vertex n2 = InterpolateSurface(s, 0.6, 0.5, 0, 0);
-    Vertex n3 = InterpolateSurface(s, 0.5, 0.6, 0, 0);
-    double nx[3], ny[3], n[3];
-    nx[0] = n2.Pos.X - n1.Pos.X;
-    nx[1] = n2.Pos.Y - n1.Pos.Y;
-    nx[2] = n2.Pos.Z - n1.Pos.Z;
-    ny[0] = n3.Pos.X - n1.Pos.X;
-    ny[1] = n3.Pos.Y - n1.Pos.Y;
-    ny[2] = n3.Pos.Z - n1.Pos.Z;
-    prodve(nx, ny, n);
-    norme(n);
+    Vertex v = InterpolateSurface(s, 0.5, 0.5, 0, 0);
+    double n[3];
+    Get_SurfaceNormal(s, n);
     n[0] *= CTX.geom.normals * CTX.pixel_equiv_x / CTX.s[0];
     n[1] *= CTX.geom.normals * CTX.pixel_equiv_x / CTX.s[1];
     n[2] *= CTX.geom.normals * CTX.pixel_equiv_x / CTX.s[2];
     glColor4ubv((GLubyte *) & CTX.color.geom.normals);
     Draw_Vector(CTX.vector_type, 0, CTX.arrow_rel_head_radius, 
 		CTX.arrow_rel_stem_length, CTX.arrow_rel_stem_radius,
-		n1.Pos.X, n1.Pos.Y, n1.Pos.Z, n[0], n[1], n[2], NULL,
+		v.Pos.X, v.Pos.Y, v.Pos.Z, n[0], n[1], n[2], NULL,
 		CTX.geom.light);
   }
 }
diff --git a/Mesh/2D_Mesh.cpp b/Mesh/2D_Mesh.cpp
index 1533d96d95a16bfbd3b95ad079a359516ffbad43..a39659cda36d06bf6fa10b7c2a131f2bbdda6a1d 100644
--- a/Mesh/2D_Mesh.cpp
+++ b/Mesh/2D_Mesh.cpp
@@ -1,4 +1,4 @@
-// $Id: 2D_Mesh.cpp,v 1.60 2004-06-22 00:58:20 geuzaine Exp $
+// $Id: 2D_Mesh.cpp,v 1.61 2004-06-22 17:34:10 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -789,6 +789,62 @@ void ActionInvertTriQua(void *a, void *b)
   }
 }
 
+void Get_SurfaceNormal(Surface *s, double n[3])
+{
+  double t1[3], t2[3];
+
+  if(s->Typ == MSH_SURF_PLAN){
+    // don't use s->plan and co.: these are computed in MeanPlane,
+    // which borks the orientation...  we cannot use
+    // InterpolateSurface euther, since we use Calcule_Z_plan in
+    // there, which relies in the MeanPlane stuff too.
+    List_T *points = List_Create(10, 10, sizeof(Vertex *));
+    for(int i = 0; i < List_Nbr(s->Generatrices); i++) {
+      Curve *c;
+      List_Read(s->Generatrices, i, &c);
+      // no need to play with beg/end: negative curves are already inverted
+      List_Add(points, &c->beg);
+    }
+    if(List_Nbr(points) > 2){
+      Vertex *v1 = *(Vertex**)List_Pointer(points, 0);
+      Vertex *v2 = *(Vertex**)List_Pointer(points, 1);
+      t1[0] = v2->Pos.X - v1->Pos.X;
+      t1[1] = v2->Pos.Y - v1->Pos.Y;
+      t1[2] = v2->Pos.Z - v1->Pos.Z;
+      for(int i = 2; i < List_Nbr(points); i++){
+	Vertex *v3 = *(Vertex**)List_Pointer(points, i);
+	t2[0] = v3->Pos.X - v1->Pos.X;
+	t2[1] = v3->Pos.Y - v1->Pos.Y;
+	t2[2] = v3->Pos.Z - v1->Pos.Z;
+	prodve(t1, t2, n);
+	if(norme(n))
+	  break;
+      }
+    }
+    if(List_Nbr(points) <= 2 || !norme(n)){
+      Msg(WARNING, "Couldn't compute normal to Surface %d using control points: "
+	  "reverting to mean plane", s->Num);
+      n[0] = s->a;
+      n[1] = s->b;
+      n[2] = s->c;
+    }
+    List_Delete(points);
+  }
+  else{
+    Vertex v1 = InterpolateSurface(s, 0.5, 0.5, 0, 0);
+    Vertex v2 = InterpolateSurface(s, 0.6, 0.5, 0, 0);
+    Vertex v3 = InterpolateSurface(s, 0.5, 0.6, 0, 0);
+    t1[0] = v2.Pos.X - v1.Pos.X;
+    t1[1] = v2.Pos.Y - v1.Pos.Y;
+    t1[2] = v2.Pos.Z - v1.Pos.Z;
+    t2[0] = v3.Pos.X - v1.Pos.X;
+    t2[1] = v3.Pos.Y - v1.Pos.Y;
+    t2[2] = v3.Pos.Z - v1.Pos.Z;
+    prodve(t1, t2, n);
+    norme(n);
+  }
+}
+
 void Maillage_Surface(void *data, void *dum)
 {
   Surface **pS, *s;
@@ -892,30 +948,13 @@ void Maillage_Surface(void *data, void *dum)
     End_Surface(s->Support, 0);
     End_Surface(s, 0);
 
-    // Horrible (tm) hack to orient the elements correctly. This
+    // Horrible (tm) hack to orient the elements correctly. This is
     // *definitely* not the best way to do it, but I don't have time
     // to look into this issue right now.
     Simplex *simp;
     if(Tree_Right(s->Simplexes, &simp)){
       double t1[3], t2[3], n1[3], n2[3], res;
-      if(s->Typ == MSH_SURF_PLAN){
-	n1[0] = s->plan[2][0];
-	n1[1] = s->plan[2][1];
-	n1[2] = s->plan[2][2];
-      }
-      else{
-	Vertex v1 = InterpolateSurface(s, 0.5, 0.5, 0, 0);
-	Vertex v2 = InterpolateSurface(s, 0.6, 0.5, 0, 0);
-	Vertex v3 = InterpolateSurface(s, 0.5, 0.6, 0, 0);
-	t1[0] = v2.Pos.X - v1.Pos.X;
-	t1[1] = v2.Pos.Y - v1.Pos.Y;
-	t1[2] = v2.Pos.Z - v1.Pos.Z;
-	t2[0] = v3.Pos.X - v1.Pos.X;
-	t2[1] = v3.Pos.Y - v1.Pos.Y;
-	t2[2] = v3.Pos.Z - v1.Pos.Z;
-	prodve(t1, t2, n1);
-      }
-      norme(n1);
+      Get_SurfaceNormal(s, n1);
       t1[0] = simp->V[1]->Pos.X - simp->V[0]->Pos.X;
       t1[1] = simp->V[1]->Pos.Y - simp->V[0]->Pos.Y;
       t1[2] = simp->V[1]->Pos.Z - simp->V[0]->Pos.Z;
@@ -942,3 +981,4 @@ void Maillage_Surface(void *data, void *dum)
   }
 
 }
+