diff --git a/Numeric/Numeric.cpp b/Numeric/Numeric.cpp
index f1eabcea63876b067555aeb1fc355ba66d14315e..bfcfff8451c3534987947ad817cd220d09113b30 100644
--- a/Numeric/Numeric.cpp
+++ b/Numeric/Numeric.cpp
@@ -67,6 +67,24 @@ void normal3points(double x0, double y0, double z0,
   norme(n);
 }
 
+void normal2points(double x0, double y0, double z0,
+                   double x1, double y1, double z1,
+                   double n[3])
+{
+  // this computes one of the normals to the edge
+  double t[3] = {x1 - x0, y1 - y0, z1 - z0};
+  double ex[3] = {0., 0., 0.};
+  if(t[0] == 0.)
+    ex[0] = 1.;
+  else if(t[1] == 0.)
+    ex[1] = 1.;
+  else
+    ex[2] = 1.;
+  prodve(t, ex, n);
+  norme(n);
+}
+
+
 int sys2x2(double mat[2][2], double b[2], double res[2])
 {
   double det, ud, norm;
@@ -108,10 +126,10 @@ double trace3x3(double mat[3][3])
 
 double trace2 (double mat[3][3])
 {
-  double a00 =  mat[0][0] * mat[0][0] + mat[1][0] * mat[0][1] + mat[2][0] * mat[0][2]; 
-  double a11 =  mat[1][0] * mat[0][1] + mat[1][1] * mat[1][1] + mat[1][2] * mat[2][1]; 
+  double a00 =  mat[0][0] * mat[0][0] + mat[1][0] * mat[0][1] + mat[2][0] * mat[0][2];
+  double a11 =  mat[1][0] * mat[0][1] + mat[1][1] * mat[1][1] + mat[1][2] * mat[2][1];
   double a22 =  mat[2][0] * mat[0][2] + mat[2][1] * mat[1][2] + mat[2][2] * mat[2][2];
-  
+
   return a00 + a11 + a22;
 }
 
@@ -179,7 +197,7 @@ double det2x3(double mat[2][3])
   double v1[3] = {mat[0][0], mat[0][1], mat[0][2]};
   double v2[3] = {mat[1][0], mat[1][1], mat[1][2]};
   double n[3];
-  
+
   prodve(v1, v2, n);
   return norm3(n);
 }
@@ -267,23 +285,23 @@ double angle_plan(double V[3], double P1[3], double P2[3], double n[3])
 double triangle_area(double p0[3], double p1[3], double p2[3])
 {
   double a[3], b[3], c[3];
-  
+
   a[0] = p2[0] - p1[0];
   a[1] = p2[1] - p1[1];
   a[2] = p2[2] - p1[2];
-  
+
   b[0] = p0[0] - p1[0];
   b[1] = p0[1] - p1[1];
   b[2] = p0[2] - p1[2];
-  
+
   prodve(a, b, c);
   return 0.5 * sqrt(c[0] * c[0] + c[1] * c[1] + c[2] * c[2]);
 }
 
 double triangle_area2d(double p0[2], double p1[2], double p2[2])
 {
-  const double c =  
-    (p2[0] - p1[0])*(p0[1] - p1[1]) - 
+  const double c =
+    (p2[0] - p1[0])*(p0[1] - p1[1]) -
     (p2[1] - p1[1])*(p0[0] - p1[0]);
 
   return 0.5 * sqrt(c*c);
@@ -335,7 +353,7 @@ void circumCenterXYZ(double *p1, double *p2, double *p3, double *res, double *uv
     double rhs[2] = {resP[0] - p1P[0], resP[1] - p1P[1]};
     sys2x2(mat, rhs, uv);
   }
-  
+
   res[0] = p1[0] + resP[0] * vx[0] + resP[1] * vy[0];
   res[1] = p1[1] + resP[0] * vx[1] + resP[1] * vy[1];
   res[2] = p1[2] + resP[0] * vx[2] + resP[1] * vy[2];
@@ -346,18 +364,18 @@ void planarQuad_xyz2xy(double *x, double *y, double *z, double *xn, double *yn)
   double v1[3] = {x[1] - x[0], y[1] - y[0], z[1] - z[0]};
   double v2[3] = {x[2] - x[0], y[2] - y[0], z[2] - z[0]};
   double v3[3] = {x[3] - x[0], y[3] - y[0], z[3] - z[0]};
-  
+
   double vx[3] = {x[1] - x[0], y[1] - y[0], z[1] - z[0]};
   double vy[3] = {x[2] - x[0], y[2] - y[0], z[2] - z[0]};
   double vz[3]; prodve(vx, vy, vz); prodve(vz, vx, vy);
-  
+
   norme(vx); norme(vy); norme(vz);
-  
+
   double p1P[2] = {0.0, 0.0};
   double p2P[2]; prosca(v1, vx, &p2P[0]); prosca(v1, vy, &p2P[1]);
   double p3P[2]; prosca(v2, vx, &p3P[0]); prosca(v2, vy, &p3P[1]);
   double p4P[2]; prosca(v3, vx, &p4P[0]); prosca(v3, vy, &p4P[1]);
-  
+
   xn[0] = p1P[0];
   xn[1] = p2P[0];
   xn[2] = p3P[0];
@@ -370,35 +388,35 @@ void planarQuad_xyz2xy(double *x, double *y, double *z, double *xn, double *yn)
 
 double computeInnerRadiusForQuad(double *x, double *y, int i)
 {
-  // parameters of the equations of the 3 edges   
+  // parameters of the equations of the 3 edges
   double a1 = y[(4+i)%4]-y[(5+i)%4];
   double a2 = y[(5+i)%4]-y[(6+i)%4];
   double a3 = y[(6+i)%4]-y[(7+i)%4];
-  
+
   double b1 = x[(5+i)%4]-x[(4+i)%4];
   double b2 = x[(6+i)%4]-x[(5+i)%4];
   double b3 = x[(7+i)%4]-x[(6+i)%4];
-  
+
   double c1 = y[(5+i)%4]*x[(4+i)%4]-y[(4+i)%4]*x[(5+i)%4];
   double c2 = y[(6+i)%4]*x[(5+i)%4]-y[(5+i)%4]*x[(6+i)%4];
   double c3 = y[(7+i)%4]*x[(6+i)%4]-y[(6+i)%4]*x[(7+i)%4];
-  
+
   // length of the 3 edges
   double l1 = sqrt(a1*a1+b1*b1);
   double l2 = sqrt(a2*a2+b2*b2);
   double l3 = sqrt(a3*a3+b3*b3);
-  
+
   // parameters of the 2 bisectors
   double a12 = a1/l1-a2/l2;
   double a23 = a2/l2-a3/l3;
-  
+
   double b12 = b1/l1-b2/l2;
   double b23 = b2/l2-b3/l3;
-  
+
   double c12 = c1/l1-c2/l2;
   double c23 = c2/l2-c3/l3;
-  
-  // compute the coordinates of the center of the incircle, 
+
+  // compute the coordinates of the center of the incircle,
   // that is the point where the 2 bisectors meet
   double x_s = (c12*b23-c23*b12)/(a23*b12-a12*b23);
   double y_s = 0.;
@@ -408,10 +426,10 @@ double computeInnerRadiusForQuad(double *x, double *y, int i)
   else {
     y_s = -a23/b23*x_s-c23/b23;
   }
-  
-  // finally get the radius of the circle 
+
+  // finally get the radius of the circle
   double r = (a1*x_s+b1*y_s+c1)/l1;
-  
+
   return r;
 }
 
@@ -477,12 +495,12 @@ double ComputeScalarRep(int numComp, double *val)
 }
 
 void eigenvalue2x2(double mat[2][2], double v[2])
-{ 
+{
 
   double a=1;
   double b=-(mat[0][0]+mat[1][1]);
   double c= (mat[0][0]*mat[1][1])-(mat[0][1]*mat[1][0]);
-  
+
   double det = b*b-4.*a*c;
 
   v[0] = (-b+sqrt(det))/(2*a);
@@ -491,7 +509,7 @@ void eigenvalue2x2(double mat[2][2], double v[2])
 }
 
 void eigenvalue(double mat[3][3], double v[3])
-{            
+{
   // characteristic polynomial of T : find v root of
   // v^3 - I1 v^2 + I2 T - I3 = 0
   // I1 : first invariant , trace(T)
@@ -503,12 +521,12 @@ void eigenvalue(double mat[3][3], double v[3])
   c[2] = - trace3x3(mat);
   c[1] = 0.5 * (c[2] * c[2] - trace2(mat));
   c[0] = - det3x3(mat);
-  
+
   // printf("%g %g %g\n", mat[0][0], mat[0][1], mat[0][2]);
   // printf("%g %g %g\n", mat[1][0], mat[1][1], mat[1][2]);
   // printf("%g %g %g\n", mat[2][0], mat[2][1], mat[2][2]);
   // printf("%g x^3 + %g x^2 + %g x + %g = 0\n", c[3], c[2], c[1], c[0]);
-  
+
   double imag[3];
   FindCubicRoots(c, v, imag);
   eigsort(v);
@@ -529,7 +547,7 @@ void FindCubicRoots(const double coef[4], double real[3], double imag[3])
   b /= a;
   c /= a;
   d /= a;
-  
+
   double q = (3.0*c - (b*b))/9.0;
   double r = -(27.0*d) + b*(9.0*c - 2.0*(b*b));
   r /= 54.0;
@@ -554,7 +572,7 @@ void FindCubicRoots(const double coef[4], double real[3], double imag[3])
 
   // The remaining options are all real
   imag[1] = imag[2] = 0.0;
-  
+
   double r13;
   if (discrim == 0){ // All roots real, at least two are equal.
     r13 = ((r < 0) ? -pow(-r,(1.0/3.0)) : pow(r,(1.0/3.0)));
@@ -578,7 +596,7 @@ void eigsort(double d[3])
 {
   int k, j, i;
   double p;
-  
+
   for (i=0; i<3; i++) {
     p=d[k=i];
     for (j=i+1;j<3;j++)
@@ -633,13 +651,13 @@ bool newton_fd(void (*func)(fullVector<double> &, fullVector<double> &, void *),
   const int MAXIT = 50;
   const double EPS = 1.e-4;
   const int N = x.size();
-  
+
   fullMatrix<double> J(N, N);
   fullVector<double> f(N), feps(N), dx(N);
-  
+
   for (int iter = 0; iter < MAXIT; iter++){
      func(x, f, data);
-     
+
      bool isZero = false;
      for (int k=0; k<N; k++) {
          if (f(k) == 0. ) isZero = true;
@@ -658,16 +676,16 @@ bool newton_fd(void (*func)(fullVector<double> &, fullVector<double> &, void *),
       }
       x(j) -= h;
     }
-    
+
     if (N == 1)
       dx(0) = f(0) / J(0, 0);
     else
       J.luSolve(f, dx);
-    
+
     for (int i = 0; i < N; i++)
       x(i) -= relax * dx(i);
 
-    if(dx.norm() < tolx) return true; 
+    if(dx.norm() < tolx) return true;
   }
   return false;
 }
@@ -679,9 +697,9 @@ f(x+a*d) = f(x) + f'(x) (
 
 */
 
-void gmshLineSearch(double (*func)(fullVector<double> &, void *), void* data, 
-                    fullVector<double> &x, fullVector<double> &p,  
-                    fullVector<double> &g, double &f, 
+void gmshLineSearch(double (*func)(fullVector<double> &, void *), void* data,
+                    fullVector<double> &x, fullVector<double> &p,
+                    fullVector<double> &g, double &f,
                     double stpmax, int &check)
 {
   int i;
@@ -692,7 +710,7 @@ void gmshLineSearch(double (*func)(fullVector<double> &, void *), void* data,
 
   fullVector<double> xold(x);
   const double fold = (*func)(xold, data);
-  
+
   check=0;
   int n = x.size();
   double norm = p.norm();
@@ -707,8 +725,8 @@ void gmshLineSearch(double (*func)(fullVector<double> &, void *), void* data,
   /*
   for (int j=0;j<100;j++){
     double sx = (double)j/99;
-    for (i=0;i<n;i++) x(i)=xold(i)+10*sx*p(i);    
-    double jzede = (*func)(x,data); 
+    for (i=0;i<n;i++) x(i)=xold(i)+10*sx*p(i);
+    double jzede = (*func)(x,data);
   }
   */
 
@@ -723,7 +741,7 @@ void gmshLineSearch(double (*func)(fullVector<double> &, void *), void* data,
       //      printf("ALERT : alam %g alamin %g\n",alam,alamin);
       check = 1;
       return;
-    } 
+    }
     else if (f <= fold + ALF * alam * slope) return;
     else {
       if (alam == 1.0)
@@ -756,7 +774,7 @@ double minimize_grad_fd(double (*func)(fullVector<double> &, void *),
   const int MAXIT = 3;
   const double EPS = 1.e-4;
   const int N = x.size();
-  
+
   fullVector<double> grad(N);
   fullVector<double> dir(N);
   double f, feps, finit;
@@ -786,14 +804,14 @@ double minimize_grad_fd(double (*func)(fullVector<double> &, void *),
     // printf("Line search done x = (%g %g) f = %g\n",x(0),x(1),f);
     if (check == 1) break;
   }
-  
+
   return f;
 }
 
 /*
 P(p) = p1 + t1 xi + t2 eta
 
-t1 = (p2-p1) ; t2 = (p3-p1) ; 
+t1 = (p2-p1) ; t2 = (p3-p1) ;
 
 (P(p) - p) = d n
 
@@ -807,11 +825,11 @@ t1 xi + t2 eta + d n = p - p1
 distance to segment
 
    P(p) = p1 + t (p2-p1)
-   
+
    (p - P(p)) * (p2-p1) = 0
    (p - p1 - t (p2-p1) ) * (p2-p1) = 0
    - t ||p2-p1||^2 + (p-p1)(p2-p1) = 0
-   
+
    t = (p-p1)*(p2-p1)/||p2-p1||^2
 */
 
@@ -827,7 +845,7 @@ void signedDistancesPointsTriangle(std::vector<double> &distances,
   SVector3 t3 = p3 - p2;
   SVector3 n = crossprod(t1, t2);
   n.normalize();
-	
+
   double mat[3][3] = {{t1.x(), t2.x(), -n.x()},
                       {t1.y(), t2.y(), -n.y()},
                       {t1.z(), t2.z(), -n.z()}};
@@ -870,18 +888,18 @@ void signedDistancesPointsTriangle(std::vector<double> &distances,
       bool found = false;
       SPoint3 closePt;
       if (t12 >= 0 && t12 <= 1.){
-        d = sign * std::min(fabs(d), p.distance(p1 + (p2 - p1) * t12));  
+        d = sign * std::min(fabs(d), p.distance(p1 + (p2 - p1) * t12));
         closePt = p1 + (p2 - p1) * t12;
         found = true;
       }
       if (t13 >= 0 && t13 <= 1.){
         if (p.distance(p1 + (p3 - p1) * t13) < fabs(d)) closePt = p1 + (p3 - p1) * t13;
-        d = sign * std::min(fabs(d), p.distance(p1 + (p3 - p1) * t13));      
+        d = sign * std::min(fabs(d), p.distance(p1 + (p3 - p1) * t13));
         found = true;
-      }      
+      }
       if (t23 >= 0 && t23 <= 1.){
         if (p.distance(p2 + (p3 - p2) * t23) < fabs(d)) closePt = p2 + (p3 - p2) * t23;
-        d = sign * std::min(fabs(d), p.distance(p2 + (p3 - p2) * t23));      
+        d = sign * std::min(fabs(d), p.distance(p2 + (p3 - p2) * t23));
         found = true;
       }
       if (p.distance(p1) < fabs(d)){
@@ -901,10 +919,10 @@ void signedDistancesPointsTriangle(std::vector<double> &distances,
       distances[i] = d;
       closePts[i] = closePt;
     }
-  }                                        
+  }
 }
 
-void signedDistancePointLine(const SPoint3 &p1, const SPoint3 &p2, const SPoint3 &p, 
+void signedDistancePointLine(const SPoint3 &p1, const SPoint3 &p2, const SPoint3 &p,
                              double &d, SPoint3 &closePt)
 {
   SVector3 t1 = p2 - p1;
@@ -914,7 +932,7 @@ void signedDistancePointLine(const SPoint3 &p1, const SPoint3 &p2, const SPoint3
   d = 1.e10;
   bool found = false;
   if (t12 >= 0 && t12 <= 1.){
-    d =  std::min(fabs(d), p.distance(p1 + (p2 - p1) * t12)); 
+    d =  std::min(fabs(d), p.distance(p1 + (p2 - p1) * t12));
     closePt = p1 + (p2 - p1) * t12;
     found = true;
   }
@@ -1000,7 +1018,7 @@ void changeReferential(const int direction,const SPoint3 &p,const SPoint3 &close
 }
 
 int computeDistanceRatio(const double &y, const double &yp, const double &x,
-                         const double &xp, double *distance, const double &r1, 
+                         const double &xp, double *distance, const double &r1,
                          const double &r2)
 {
   double b;
@@ -1138,7 +1156,7 @@ void signedDistancesPointsEllipseLine(std::vector<double>&distances,
     SPoint3 closePt;
     const SPoint3 &p = pts[i];
     signedDistancePointLine(p1,p2,p,d,closePt);
-    
+
     distances[i] = d;
     closePts[i] = closePt;
     int direction=0;
@@ -1198,18 +1216,18 @@ void signedDistancesPointsEllipseLine(std::vector<double>&distances,
 }
 
 int intersection_segments(SPoint3 &p1, SPoint3 &p2,
-                          SPoint3 &q1, SPoint3 &q2, 
+                          SPoint3 &q1, SPoint3 &q2,
                           double x[2])
 {
-  double xp_max = std::max(p1.x(), p2.x()); 
-  double yp_max = std::max(p1.y(), p2.y()); 
-  double xq_max = std::max(q1.x(), q2.x()); 
-  double yq_max = std::max(q1.y(), q2.y()); 
-
-  double xp_min = std::min(p1.x(), p2.x()); 
-  double yp_min = std::min(p1.y(), p2.y()); 
-  double xq_min = std::min(q1.x(), q2.x()); 
-  double yq_min = std::min(q1.y(), q2.y()); 
+  double xp_max = std::max(p1.x(), p2.x());
+  double yp_max = std::max(p1.y(), p2.y());
+  double xq_max = std::max(q1.x(), q2.x());
+  double yq_max = std::max(q1.y(), q2.y());
+
+  double xp_min = std::min(p1.x(), p2.x());
+  double yp_min = std::min(p1.y(), p2.y());
+  double xq_min = std::min(q1.x(), q2.x());
+  double yq_min = std::min(q1.y(), q2.y());
   if (yq_min > yp_max || xq_min >  xp_max ||
       yq_max < yp_min || xq_max <  xp_min){
     return 0;
@@ -1293,7 +1311,7 @@ void computeMeanPlaneSimple(const std::vector<SPoint3> &points, mean_plane &mean
   meanPlane.a = res[0];
   meanPlane.b = res[1];
   meanPlane.c = res[2];
-  meanPlane.d = -res[3];//BUG HERE 
+  meanPlane.d = -res[3];//BUG HERE
 
   meanPlane.x = meanPlane.y = meanPlane.z = 0.;
   if(fabs(meanPlane.a) >= fabs(meanPlane.b) &&
@@ -1325,7 +1343,7 @@ void projectPointToPlane(const SPoint3 &pt, SPoint3 &ptProj, const mean_plane &m
   ptProj[0] =  u + a*t0;
   ptProj[1] =  v + b*t0;
   ptProj[2] =  w + c*t0;
-  
+
 }
 
 void projectPointsToPlane(const std::vector<SPoint3> &pts, std::vector<SPoint3> &ptsProj, const mean_plane &meanPlane)
@@ -1333,12 +1351,12 @@ void projectPointsToPlane(const std::vector<SPoint3> &pts, std::vector<SPoint3>
 
   ptsProj.resize(pts.size());
   for (int i= 0; i< pts.size(); i++){
-    projectPointToPlane(pts[i],ptsProj[i], meanPlane); 
+    projectPointToPlane(pts[i],ptsProj[i], meanPlane);
   }
 
 }
 
-void transformPointsIntoOrthoBasis(const std::vector<SPoint3> &ptsProj,  std::vector<SPoint3> &pointsUV, 
+void transformPointsIntoOrthoBasis(const std::vector<SPoint3> &ptsProj,  std::vector<SPoint3> &pointsUV,
 				   const SPoint3 &ptCG, const mean_plane &meanPlane)
 {
 
@@ -1349,9 +1367,9 @@ void transformPointsIntoOrthoBasis(const std::vector<SPoint3> &ptsProj,  std::ve
 
   for (int i= 0; i< ptsProj.size(); i++){
     SVector3 pp(ptsProj[i][0]-ptCG[0],ptsProj[i][1]-ptCG[1],ptsProj[i][2]-ptCG[2]) ;
-    pointsUV[i][0] = dot(pp, tangent); 
-    pointsUV[i][1] = dot(pp, binormal); 
-    pointsUV[i][2] = dot(pp, normal); 
+    pointsUV[i][0] = dot(pp, tangent);
+    pointsUV[i][1] = dot(pp, binormal);
+    pointsUV[i][2] = dot(pp, normal);
   }
-  
+
 }
diff --git a/Numeric/Numeric.h b/Numeric/Numeric.h
index 10ea14891be11aef86c20a5bf8f4cc8baea4d748..4610038168cce27cd198f58346fa95e2151444b4 100644
--- a/Numeric/Numeric.h
+++ b/Numeric/Numeric.h
@@ -69,6 +69,9 @@ void normal3points(double x0, double y0, double z0,
                    double x1, double y1, double z1,
                    double x2, double y2, double z2,
                    double n[3]);
+void normal2points(double x0, double y0, double z0,
+                   double x1, double y1, double z1,
+                   double n[3]);
 int sys2x2(double mat[2][2], double b[2], double res[2]);
 int sys3x3(double mat[3][3], double b[3], double res[3], double *det);
 int sys3x3_with_tol(double mat[3][3], double b[3], double res[3], double *det);
@@ -88,7 +91,7 @@ void circumCenterXYZ(double *p1, double *p2, double *p3, double *res, double *uv
 // operate a transformation on the 4 points of a Quad in 3D, to have an equivalent Quad in 2D
 void planarQuad_xyz2xy(double *x, double *y, double *z, double *xn, double *yn);
 // compute the radius of the circle that is tangent to the 3 edges defined by 4 points
-// edge_1=(x0,y0)->(x1,y1); edge_2=(x1,y1)->(x2,y2); edge_3=(x2,y2)->(x3,y3) 
+// edge_1=(x0,y0)->(x1,y1); edge_2=(x1,y1)->(x2,y2); edge_3=(x2,y2)->(x3,y3)
 double computeInnerRadiusForQuad(double *x, double *y, int i);
 char float2char(float f);
 float char2float(char c);
@@ -132,14 +135,14 @@ void signedDistancesPointsEllipseLine (std::vector<double>&distances,
                                        const SPoint3 &p1, const SPoint3 &p2);
 
 int intersection_segments (SPoint3 &p1, SPoint3 &p2,
-			   SPoint3 &q1, SPoint3 &q2, 
+			   SPoint3 &q1, SPoint3 &q2,
 			   double x[2]);
 
 //tools for projection onto plane
-void computeMeanPlaneSimple(const std::vector<SPoint3> &points, mean_plane &meanPlane); 
+void computeMeanPlaneSimple(const std::vector<SPoint3> &points, mean_plane &meanPlane);
 void projectPointToPlane(const SPoint3 &pt, SPoint3 &ptProj, const mean_plane &meanPlane);
 void projectPointsToPlane(const std::vector<SPoint3> &pts, std::vector<SPoint3> &ptsProj, const mean_plane &meanPlane);
-void transformPointsIntoOrthoBasis(const std::vector<SPoint3> &ptsProj,  std::vector<SPoint3> &pointsUV, 
+void transformPointsIntoOrthoBasis(const std::vector<SPoint3> &ptsProj,  std::vector<SPoint3> &pointsUV,
 				   const SPoint3 &ptCG, const mean_plane &meanPlane);
 
 #endif