diff --git a/Geo/GFace.cpp b/Geo/GFace.cpp
index 058239095053ecfa780cbff1f1f8b2f451418855..f80e5d58b72aa923ea5ff86333a1166c32560b75 100644
--- a/Geo/GFace.cpp
+++ b/Geo/GFace.cpp
@@ -1,4 +1,4 @@
-// $Id: GFace.cpp,v 1.17 2006-11-14 17:11:33 remacle Exp $
+// $Id: GFace.cpp,v 1.18 2006-11-14 20:20:18 remacle Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -23,6 +23,7 @@
 #include "GFace.h"
 #include "GEdge.h"
 #include "Message.h"
+#include "Utils.h"
 
 #if defined(HAVE_GSL)
 #include <gsl/gsl_vector.h>
@@ -393,3 +394,90 @@ void GFace :: computeDirs ()
 {
   throw;
 }
+
+void GFace::XYZtoUV(const double X, const double Y, const double Z, 
+		    double &U, double &V,
+		    const double relax) const
+{
+  const double Precision = 1.e-8;
+  const int MaxIter = 25;
+  const int NumInitGuess = 11;
+
+  double Unew = 0., Vnew = 0., err,err2;
+  int iter;
+  double mat[3][3], jac[3][3];
+  double umin, umax, vmin, vmax;
+  double init[NumInitGuess] = {0.487, 0.6, 0.4, 0.7, 0.3, 0.8, 0.2, 0.9, 0.1,0,1};
+  
+  Range<double> ru = parBounds(0);
+  Range<double> rv = parBounds(1);
+  umin = ru.low();
+  umax = ru.high();
+  vmin = rv.low();
+  vmax = rv.high();
+
+  for(int i = 0; i < NumInitGuess; i++){
+    for(int j = 0; j < NumInitGuess; j++){
+    
+      U = init[i];
+      V = init[j];
+      err = 1.0;
+      iter = 1;
+      
+      while(err > Precision && iter < MaxIter) {
+	GPoint P = point(U,V);
+	Pair<SVector3,SVector3> der = firstDer(SPoint2(U,V)); 
+	mat[0][0] = der.left().x();
+	mat[0][1] = der.left().y();
+	mat[0][2] = der.left().z();
+	mat[1][0] = der.right().x();
+	mat[1][1] = der.right().y();
+	mat[1][2] = der.right().z();
+	mat[2][0] = 0.;
+	mat[2][1] = 0.;
+	mat[2][2] = 0.;
+	invert_singular_matrix3x3(mat, jac);
+	
+	Unew = U + relax *
+	  (jac[0][0] * (X - P.x()) + jac[1][0] * (Y - P.y()) +
+	   jac[2][0] * (Z - P.z()));
+	Vnew = V + relax * 
+	  (jac[0][1] * (X - P.x()) + jac[1][1] * (Y - P.y()) +
+	   jac[2][1] * (Z - P.z()));
+	
+	err = DSQR(Unew - U) + DSQR(Vnew - V);
+	// A BETTER TEST !! (JFR/AUG 2006)
+	err2 = DSQR(X - P.x()) + DSQR(Y - P.y()) + DSQR(Z - P.z());	
+	iter++;
+	U = Unew;
+	V = Vnew;
+      }
+      
+      
+      if(iter < MaxIter && err <= Precision && err2 <= 1.e-5 &&
+	 Unew <= umax && Vnew <= vmax && 
+	 Unew >= umin && Vnew >= vmin){
+	if (err2 > Precision)
+	  Msg(WARNING,"converged for i=%d j=%d (err=%g iter=%d) BUT err2 = %g", i, j, err, iter,err2);
+	return;	
+      }
+    }
+  }
+  
+  if(relax < 1.e-6)
+    Msg(GERROR, "Could not converge: surface mesh will be wrong");
+  else {
+    Msg(INFO, "Relaxation factor = %g", 0.75 * relax);
+    XYZtoUV(X, Y, Z, U, V, 0.75 * relax);
+  }  
+}
+
+
+SPoint2 GFace::parFromPoint(const SPoint3 &p) const
+{
+  double U,V;
+  
+  XYZtoUV(p.x(),p.y(),p.z(),U,V,1.0);
+
+  return SPoint2(U,V);
+}
diff --git a/Geo/GFace.h b/Geo/GFace.h
index 233b5913a5fb70fcddb025442fcdc6c187dce6c7..53037481eaea393a3cc2a4e052522671db3f7266 100644
--- a/Geo/GFace.h
+++ b/Geo/GFace.h
@@ -68,6 +68,11 @@ class GFace : public GEntity
   virtual int dim() const {return 2;}
   virtual void setVisibility(char val, bool recursive=false);
 
+  // compute XYZ from parametric UV
+  void XYZtoUV(const double X, const double Y, const double Z, 
+	       double &U, double &V,
+	       const double relax) const;
+
   // The bounding box
   virtual SBoundingBox3d bounds() const; 
 
@@ -81,7 +86,7 @@ class GFace : public GEntity
 
   // Return the parmater location on the face given a point in space
   // that is on the face.
-  virtual SPoint2 parFromPoint(const SPoint3 &) const = 0;
+  virtual SPoint2 parFromPoint(const SPoint3 &) const;
 
   // True if the parameter value is interior to the face.
   virtual int containsParam(const SPoint2 &pt) const = 0;
diff --git a/Geo/OCCEdge.cpp b/Geo/OCCEdge.cpp
index 52213ea47279531df7f7d79711c95e1a943cfdb9..16b5003d2a019b2f65c355c85c7074d670c9c5b6 100644
--- a/Geo/OCCEdge.cpp
+++ b/Geo/OCCEdge.cpp
@@ -1,4 +1,4 @@
-// $Id: OCCEdge.cpp,v 1.1 2006-11-14 17:11:33 remacle Exp $
+// $Id: OCCEdge.cpp,v 1.2 2006-11-14 20:20:18 remacle Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -75,7 +75,7 @@ GEntity::GeomType OCCEdge::geomType() const
 
 int OCCEdge::minimumMeshSegments () const
 {
-  return GEdge::minimumMeshSegments () ;
+  return CTX.mesh.min_circ_points; ;
 }
 
 int OCCEdge::minimumDrawSegments () const
diff --git a/Geo/OCCFace.cpp b/Geo/OCCFace.cpp
index 475d1cc5645bda855cd90e6ae4d4e56d994a3e1a..fee6ed52ffcaa9770740fc09621797463499d218 100644
--- a/Geo/OCCFace.cpp
+++ b/Geo/OCCFace.cpp
@@ -1,4 +1,4 @@
-// $Id: OCCFace.cpp,v 1.1 2006-11-14 17:11:33 remacle Exp $
+// $Id: OCCFace.cpp,v 1.2 2006-11-14 20:20:18 remacle Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -91,14 +91,23 @@ OCCFace::OCCFace(GModel *m, TopoDS_Face _s, int num, TopTools_IndexedMapOfShape
 
   Msg(INFO,"OCC Face %d with %d edges",num,l_edges.size());
   ShapeAnalysis::GetFaceUVBounds (s, umin, umax, vmin, vmax);
+  // we do that for the projections to converge on the 
+  // borders of the surface
+  umin -= fabs(umax-umin)/100.0;
+  vmin -= fabs(vmax-vmin)/100.0;
+  umax += fabs(umax-umin)/100.0;
+  vmax += fabs(vmax-vmin)/100.0;
   occface = BRep_Tool::Surface(s);
 }
 
 Range<double> OCCFace::parBounds(int i) const
-{ 
+{  
+  double umin2, umax2, vmin2, vmax2;
+
+  ShapeAnalysis::GetFaceUVBounds (s, umin2, umax2, vmin2, vmax2);
   if (i==0)
-    return Range<double>(umin, umax);
-  return Range<double>(vmin, vmax);
+    return Range<double>(umin2, umax2);
+  return Range<double>(vmin2, vmax2);
 }
 
 SVector3 OCCFace::normal(const SPoint2 &param) const
@@ -164,9 +173,17 @@ int OCCFace::containsParam(const SPoint2 &pt) const
 
 SPoint2 OCCFace::parFromPoint(const SPoint3 &qp) const
 {
-
-  GPoint gp = closestPoint(qp);
-  return SPoint2(gp.u(), gp.v()); 
+  gp_Pnt pnt(qp.x(),qp.y(),qp.z());
+  GeomAPI_ProjectPointOnSurf proj(pnt, occface, umin, umax, vmin, vmax);
+  if (!proj.NbPoints())
+    {
+      Msg(GERROR,"OCC Project Point on Surface FAIL");
+      return GFace::parFromPoint(qp);
+    } 
+  pnt = proj.NearestPoint();
+  double pp[2];
+  proj.LowerDistanceParameters (pp[0], pp[1]);
+  return SPoint2(pp[0],pp[1]);
 }
 
 GEntity::GeomType OCCFace::geomType() const
diff --git a/Geo/OCCVertex.h b/Geo/OCCVertex.h
index 8b0b1c9016a98597664127668432f0fcda3f8af5..3b74e43a5ca64bc41397dd4e4f2b1833b31a6b33 100644
--- a/Geo/OCCVertex.h
+++ b/Geo/OCCVertex.h
@@ -25,6 +25,7 @@
 #include "GModel.h"
 #include "OCCIncludes.h"
 #include "GVertex.h"
+#include "Context.h"
 
 class OCCVertex : public GVertex {
  protected:
@@ -56,7 +57,11 @@ class OCCVertex : public GVertex {
     return pnt.Z();
   }
   void * getNativePtr() const { return (void*) &v; }
-  virtual double prescribedMeshSizeAtVertex() const { return  350; }
+  virtual double prescribedMeshSizeAtVertex() const { 
+    SBoundingBox3d b = model()->bounds();
+    double lc = norm ( SVector3 ( b.max() , b.min() ) );
+    return lc*CTX.mesh.lc_factor; 
+  }
 };
 
 #endif
diff --git a/Geo/gmshFace.cpp b/Geo/gmshFace.cpp
index 64fcaba8db4a1bff8cbd219bcff2f730213647b5..4f41bf06cb7d4e92c9ac718d08103a3f25bd1d18 100644
--- a/Geo/gmshFace.cpp
+++ b/Geo/gmshFace.cpp
@@ -1,4 +1,4 @@
-// $Id: gmshFace.cpp,v 1.20 2006-11-14 17:11:33 remacle Exp $
+// $Id: gmshFace.cpp,v 1.21 2006-11-14 20:20:18 remacle Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -201,18 +201,19 @@ int gmshFace::containsParam(const SPoint2 &pt) const
 
 SPoint2 gmshFace::parFromPoint(const SPoint3 &qp) const
 {
-  double u,v;
   if(s->Typ == MSH_SURF_PLAN){
+    double u,v;
     double x,y,z,VX[3],VY[3];
     getMeanPlaneData(VX, VY, x, y, z);
     double vec[3] = {qp.x()-x,qp.y()-y,qp.z()-z};
     prosca(vec,VX,&u);
     prosca(vec,VY,&v);
+    return SPoint2(u, v); 
   }
   else{
-    XYZtoUV(s, qp.x(), qp.y(), qp.z(), &u, &v, 1.0);
+    //    XYZtoUV(s, qp.x(), qp.y(), qp.z(), &u, &v, 1.0);
+    return GFace::parFromPoint(qp);
   }
-  return SPoint2(u, v); 
 }
 
 GEntity::GeomType gmshFace::geomType() const
diff --git a/Mesh/Utils.h b/Mesh/Utils.h
index c3eeff146809268251f7609dfc29f976e4eef45f..31ea74d1cd9225dd5facbbfed553f995d23e2703 100644
--- a/Mesh/Utils.h
+++ b/Mesh/Utils.h
@@ -24,6 +24,7 @@
 #include "Vertex.h"
 #include "Mesh.h"
 
+void invert_singular_matrix3x3(double MM[3][3], double II[3][3]);
 void direction (Vertex * v1, Vertex * v2, double d[3]);
 void Projette (Vertex * v, double mat[3][3]);
 void MeanPlane(List_T *point, Surface *s);
diff --git a/Parser/OpenFile.cpp b/Parser/OpenFile.cpp
index ac128c88a48d87b55e2e05da4001c67580c6314a..775b7271899e120e46c482373471cff6cad77fdc 100644
--- a/Parser/OpenFile.cpp
+++ b/Parser/OpenFile.cpp
@@ -1,4 +1,4 @@
-// $Id: OpenFile.cpp,v 1.125 2006-11-14 17:11:33 remacle Exp $
+// $Id: OpenFile.cpp,v 1.126 2006-11-14 20:20:18 remacle Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -293,7 +293,8 @@ int MergeProblem(char *name, int warn_if_missing)
   if(!strcmp(ext, ".stl") || !strcmp(ext, ".STL")){
     status = GMODEL->readSTL(name, CTX.mesh.stl_distance_tol);
   }
-  else if(!strcmp(ext, ".iges") || !strcmp(ext, ".IGES")){
+  else if(!strcmp(ext, ".iges") || !strcmp(ext, ".IGES") ||
+	  !strcmp(ext, ".igs") || !strcmp(ext, ".IGS")){
     GMODEL->readOCCIGES(std::string(name));
   }
   else if(!strcmp(ext, ".step") || !strcmp(ext, ".STEP")){