diff --git a/Geo/GeoInterpolation.cpp b/Geo/GeoInterpolation.cpp
index 0cc31ca392801b798057390f9cc6596283c8cb7a..1e558076a346fe1067c6987f3745f2121826325d 100644
--- a/Geo/GeoInterpolation.cpp
+++ b/Geo/GeoInterpolation.cpp
@@ -1,4 +1,4 @@
-// $Id: GeoInterpolation.cpp,v 1.7 2006-12-20 15:50:57 remacle Exp $
+// $Id: GeoInterpolation.cpp,v 1.8 2006-12-21 09:33:41 remacle Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -452,9 +452,32 @@ Vertex InterpolateRuledSurface(Surface * s, double u, double v,
     S[0] = C[0]->beg;
     S[1] = C[1]->beg;
     S[2] = C[2]->beg;
-    V[0] = InterpolateCurve(C[0], u, 0);
-    V[1] = InterpolateCurve(C[1], v, 0);
-    V[2] = InterpolateCurve(C[2], 1. - u, 0);
+
+    if (C[0]->Num < 0)
+      {
+	Curve *C0 = FindCurve(-C[0]->Num);
+	V[0] = InterpolateCurve(C0, C0->ubeg + (C0->uend - C0->ubeg) * (1.-u), 0);
+      }
+    else
+      V[0] = InterpolateCurve(C[0], C[0]->ubeg + (C[0]->uend - C[0]->ubeg) * u, 0);
+    if (C[1]->Num < 0)
+      {
+	Curve *C1 = FindCurve(-C[1]->Num);
+	V[1] = InterpolateCurve(C1, C1->ubeg + (C1->uend - C1->ubeg) * (1.-v), 0);
+      }
+    else
+      V[1] = InterpolateCurve(C[1], C[1]->ubeg + (C[1]->uend - C[1]->ubeg) * v, 0);
+    if (C[2]->Num < 0)
+      {
+	Curve *C2 = FindCurve(-C[2]->Num);
+	V[2] = InterpolateCurve(C2, C2->ubeg + (C2->uend - C2->ubeg) * u, 0);
+      }
+    else
+      V[2] = InterpolateCurve(C[2], C[2]->ubeg + (C[2]->uend - C[2]->ubeg) * (1.-u), 0);
+
+//     V[0] = InterpolateCurve(C[0], u, 0);
+//     V[1] = InterpolateCurve(C[1], v, 0);
+//     V[2] = InterpolateCurve(C[2], 1. - u, 0);
     
     T = TransfiniteTri(V[0], V[1], V[2], *S[0], *S[1], *S[2], u, v);
     if(issphere)
diff --git a/Geo/gmshEdge.cpp b/Geo/gmshEdge.cpp
index 4a05989c1a2248077eb4407c4d6b8106fc9fad6f..9290f2111f6915e2f5e8618384177c1796849069 100644
--- a/Geo/gmshEdge.cpp
+++ b/Geo/gmshEdge.cpp
@@ -1,4 +1,4 @@
-// $Id: gmshEdge.cpp,v 1.23 2006-12-20 15:50:57 remacle Exp $
+// $Id: gmshEdge.cpp,v 1.24 2006-12-21 09:33:41 remacle Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -200,6 +200,58 @@ SPoint2 gmshEdge::reparamOnFace(GFace *face, double epar,int dir) const
 // 	     p1.x(),p1.y(),p1.z(),p2.x(),p2.y(),p2.z(),
 // 	     sqrt((p1.x()-p2.x())*(p1.x()-p2.x())+(p1.y()-p2.y())*(p1.y()-p2.y())+(p1.z()-p2.z())*(p1.z()-p2.z())));
 
+      return SPoint2(U,V);
+    }
+  else if (s->Typ ==  MSH_SURF_TRIC)
+    {
+      double U,V;
+      Curve *C[3];
+      int iPos;
+      for(int i = 0; i < 3; i++) {
+	List_Read(s->Generatrices, i, &C[i]);
+      }
+
+      if (C[0]->Num == c->Num) {
+	U = (epar - C[0]->ubeg) / (C[0]->uend - C[0]->ubeg) ;
+	V = 0;
+	iPos = 0;
+      }
+      else if (C[0]->Num== -c->Num) {
+	U = (C[0]->uend - epar - C[0]->ubeg) / (C[0]->uend - C[0]->ubeg) ;
+	V = 0;
+	iPos = 0;
+      }
+      else if (C[1]->Num == c->Num) {
+	V = (epar - C[1]->ubeg) / (C[1]->uend - C[1]->ubeg) ;
+	U = 1;
+	iPos = 1;
+      }
+      else if (C[1]->Num== -c->Num ) {
+	V = (C[1]->uend - epar - C[1]->ubeg) / (C[1]->uend - C[1]->ubeg) ;
+	U = 1;
+	iPos = 1;
+      }
+      else if (C[2]->Num== c->Num) {
+	U = 1-(epar - C[2]->ubeg) / (C[2]->uend - C[2]->ubeg) ;
+	V   = 1;
+	iPos = 2;
+      }
+      else if (C[2]->Num== -c->Num) {
+	U = 1-(C[2]->uend - epar - C[2]->ubeg) / (C[2]->uend - C[2]->ubeg) ;
+	V   = 1;
+	iPos = 2;
+      }
+      else throw;
+
+//         GPoint p1 = point(epar);
+//         GPoint p2 = face->point(U,V);
+
+//         printf("iPos %1d face %2d (%2d %2d %2d) (%8.3f %8.3f) curve %2d (%8.3f) %8.3f %8.3f %8.3f vs %8.3f %8.3f %8.3f D = %8.3f\n",
+//   	     iPos,face->tag(),C[0]->Num,C[1]->Num,C[2]->Num,U,V,
+//   	     tag(),epar,
+//   	     p1.x(),p1.y(),p1.z(),p2.x(),p2.y(),p2.z(),
+//   	     sqrt((p1.x()-p2.x())*(p1.x()-p2.x())+(p1.y()-p2.y())*(p1.y()-p2.y())+(p1.z()-p2.z())*(p1.z()-p2.z())));
+
       return SPoint2(U,V);
     }
   else
diff --git a/Mesh/meshGFace.cpp b/Mesh/meshGFace.cpp
index 7864267e897dfc7e44269bc2ba9b0e5cdfbd1e2c..fdb226e9a4dd33869b766a5a5bd5cf19ba34a91b 100644
--- a/Mesh/meshGFace.cpp
+++ b/Mesh/meshGFace.cpp
@@ -1,4 +1,4 @@
-// $Id: meshGFace.cpp,v 1.43 2006-12-20 15:50:57 remacle Exp $
+// $Id: meshGFace.cpp,v 1.44 2006-12-21 09:33:41 remacle Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -541,7 +541,7 @@ bool recover_medge ( BDS_Mesh *m, GEdge *ge)
 bool gmsh2DMeshGenerator ( GFace *gf )
 {
 
-  //  if (gf->tag() != 575)return true;
+  //if (gf->tag() != 16)return true;
 
   typedef std::set<MVertex*> v_container ;
   v_container all_vertices;
diff --git a/Mesh/meshGFaceTransfinite.cpp b/Mesh/meshGFaceTransfinite.cpp
index 96bf29d92d1e9ca1ac13a6e1994865e558f67b55..d250c8e2e8aeca03c5697dbfd78c0866e00a19b5 100644
--- a/Mesh/meshGFaceTransfinite.cpp
+++ b/Mesh/meshGFaceTransfinite.cpp
@@ -1,4 +1,4 @@
-// $Id: meshGFaceTransfinite.cpp,v 1.13 2006-12-03 03:12:59 geuzaine Exp $
+// $Id: meshGFaceTransfinite.cpp,v 1.14 2006-12-21 09:33:41 remacle Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -103,7 +103,23 @@ int MeshTransfiniteSurface( GFace *gf)
 	return 0;
       }
     }
-    SPoint2 param = gf->parFromPoint(SPoint3(v->x(), v->y(), v->z()));
+
+    SPoint2 param;
+    if (v->onWhat()->dim() == 0)
+      {
+	GVertex *gv = (GVertex*)v->onWhat();
+	param=gv->reparamOnFace (gf,1);
+      }
+    else if (v->onWhat()->dim() == 1)
+	{
+	  GEdge *ge = (GEdge*)v->onWhat();
+	  double UU;
+	  v->getParameter(0,UU);
+	  param=ge->reparamOnFace (gf,UU,1);
+	}
+    else
+      param =  gf->parFromPoint (SPoint3(v->x(),v->y(),v->z()));
+
     U.push_back(param.x());
     V.push_back(param.y());
   }