From 153881abdcbfae51efb54bf47db9dca51f3d29e9 Mon Sep 17 00:00:00 2001
From: Jean-Francois Remacle <jean-francois.remacle@uclouvain.be>
Date: Mon, 27 Jun 2005 15:03:46 +0000
Subject: [PATCH] *** empty log message ***

---
 Common/GmshMatrix.h      |   29 +
 Fltk/Callbacks.cpp       |   16 +-
 Fltk/Callbacks.h         |    4 +
 Fltk/GUI.cpp             |   52 +-
 Graphics/Geom.cpp        | 1234 +++++++++++++++++++-------------------
 Mesh/BDS.cpp             |  407 ++++++++++---
 Mesh/BDS.h               |   97 +--
 Mesh/DiscreteSurface.cpp |   24 +-
 Parser/OpenFile.cpp      |    5 +-
 9 files changed, 1094 insertions(+), 774 deletions(-)

diff --git a/Common/GmshMatrix.h b/Common/GmshMatrix.h
index f8dcf55bf0..4c02c183ec 100644
--- a/Common/GmshMatrix.h
+++ b/Common/GmshMatrix.h
@@ -1,6 +1,8 @@
 #ifndef _GMSH_BOOSTMATRIX_
 #define _GMSH_BOOSTMATRIX_
 
+#include <assert.h>
+
 template <class SCALAR>
 class Gmsh_Vector
 {
@@ -42,6 +44,10 @@ public:
   {
     for (int i=0;i<r;++i)data[i]=other.data[i];
   }
+  inline void lu_solve (const  Gmsh_Vector<SCALAR>& rhs,  Gmsh_Vector<SCALAR> & result)
+      {
+	  throw;
+      }
 };
 
 template <class SCALAR>
@@ -97,6 +103,7 @@ public:
 };
 
 #ifdef HAVE_GSL
+#include <gsl/gsl_linalg.h>
 #include <gsl/gsl_matrix.h>
 #include <gsl/gsl_blas.h>
 class GSL_Vector
@@ -161,6 +168,28 @@ public:
     gsl_blas_dgemm (CblasNoTrans,CblasNoTrans, 1.0, data, x.data, 1.0, b.data);
   }
 
+  inline void least_squares (const GSL_Vector & rhs, GSL_Vector & result)
+      {
+	  assert (r > c);
+	  assert (rhs.size() == r);
+	  assert (result.size() == c);
+	  GSL_Matrix *ls     = new GSL_Matrix(c, c);
+	  GSL_Vector *ls_rhs = new GSL_Vector(c);
+	  gsl_blas_dgemm (CblasTrans,CblasNoTrans, 1.0, data, data, 1.0, ls->data);
+	  gsl_blas_dgemv (CblasTrans, 1.0, data, rhs.data, 1.0, ls_rhs->data);
+	  ls->lu_solve (*ls_rhs,result);
+	  delete ls;
+	  delete ls_rhs;
+      }
+  inline void lu_solve (const GSL_Vector & rhs, GSL_Vector & result)
+      {
+	  int s;
+	  gsl_permutation * p = gsl_permutation_alloc (size1());
+	  gsl_linalg_LU_decomp ( data, p, &s);
+	  gsl_linalg_LU_solve ( data ,  p, rhs.data, result.data ) ;
+	  gsl_permutation_free (p);
+      }
+
   inline void mult (const GSL_Vector & x, GSL_Vector & b )
   {
     gsl_blas_dgemv (CblasNoTrans, 1.0, data, x.data, 1.0, b.data);
diff --git a/Fltk/Callbacks.cpp b/Fltk/Callbacks.cpp
index 328dd2fc6e..8f7f6b7331 100644
--- a/Fltk/Callbacks.cpp
+++ b/Fltk/Callbacks.cpp
@@ -1,4 +1,4 @@
-// $Id: Callbacks.cpp,v 1.356 2005-06-10 20:59:14 geuzaine Exp $
+// $Id: Callbacks.cpp,v 1.357 2005-06-27 15:03:45 remacle Exp $
 //
 // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle
 //
@@ -25,6 +25,7 @@
 #include <signal.h>
 #include <map>
 
+#include "BDS.h"
 #include "Gmsh.h"
 #include "GmshUI.h"
 #include "Geo.h"
@@ -829,6 +830,19 @@ void options_restore_defaults_cb(CALLBACK_ARGS)
   Draw();
 }
 
+void wizard_update_edges_cb(CALLBACK_ARGS)
+{
+    extern  void BDS_To_Mesh(Mesh *m);
+    if (THEM && THEM->bds && WID)
+    {
+	const double angle = WID->swiz_value[0]->value() * M_PI / 180;
+	printf ("value = %g\n",angle);
+	THEM->bds->classify (angle);
+	BDS_To_Mesh (THEM); 
+	Draw();
+    }
+}
+
 void options_ok_cb(CALLBACK_ARGS)
 {
   general_options_ok_cb(w, data);
diff --git a/Fltk/Callbacks.h b/Fltk/Callbacks.h
index 15a4a52603..6d4b6fe31d 100644
--- a/Fltk/Callbacks.h
+++ b/Fltk/Callbacks.h
@@ -291,5 +291,9 @@ void solver_kill_cb(CALLBACK_ARGS);
 void solver_choose_executable_cb(CALLBACK_ARGS);
 void solver_ok_cb(CALLBACK_ARGS);
 
+// SURFACE MESH WIZARD
+
+void wizard_update_edges_cb(CALLBACK_ARGS);
+
 #endif
 
diff --git a/Fltk/GUI.cpp b/Fltk/GUI.cpp
index 3c0caf0b73..7dd1f5e0fe 100644
--- a/Fltk/GUI.cpp
+++ b/Fltk/GUI.cpp
@@ -1,4 +1,4 @@
-// $Id: GUI.cpp,v 1.443 2005-06-09 22:28:24 geuzaine Exp $
+// $Id: GUI.cpp,v 1.444 2005-06-27 15:03:45 remacle Exp $
 //
 // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle
 //
@@ -812,6 +812,7 @@ GUI::GUI(int argc, char **argv)
   int i;
 
   // initialize static windows
+  swiz_window = NULL;
   m_window = NULL;
   g_window = NULL;
   opt_window = NULL;
@@ -901,6 +902,9 @@ GUI::GUI(int argc, char **argv)
   }
   call_for_solver_plugin(-1);
 
+  // create the surface mesh wizard
+  create_surface_mesh_wizard();
+
   // Draw the scene
   g_opengl_window->redraw();
 }
@@ -1612,7 +1616,6 @@ void GUI::create_surface_mesh_wizard()
 {
     int width = 42 * fontsize;
     int height = 12 * BH + 5 * WB;
-    int L = 105 + WB;
 
     if(swiz_window) {
 	swiz_window->show();
@@ -1621,16 +1624,47 @@ void GUI::create_surface_mesh_wizard()
     swiz_window = new Dialog_Window(width, height);
     swiz_window->box(GMSH_WINDOW_BOX);
 
-    swiz_wiz = new Fl_Wizard(L, 0, width, height, "Surface Mesh Wizard");
+    swiz_wiz = new Fl_Wizard(0, 0, width, height, "Surface Mesh Wizard");
     {
-	Fl_Tabs *o = new Fl_Tabs(L + WB, WB, width - 2 * WB, height - 2 * WB);
+	Fl_Tabs *o = new Fl_Tabs(WB, WB, width - 2 * WB, height - 2 * WB);
 	{
-	    Fl_Group *o = new Fl_Group(L + WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Detect Edges");
-	    swiz_value[0] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 1 * BH, IW, BH, "Angle");
-	    swiz_value[0]->minimum(0.1);
-	    swiz_value[0]->maximum(50);
-	    swiz_value[0]->step(0.1);
+	    Fl_Group *o = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Model Edge Detection");
+	    swiz_value[0] = new Fl_Value_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "Treshold Dihedral Angle");
+	    swiz_value[0]->value(180/8);
+	    swiz_value[0]->minimum(0);
+	    swiz_value[0]->maximum(90);
+	    swiz_value[0]->step(1);
 	    swiz_value[0]->align(FL_ALIGN_RIGHT);
+	    {
+		Fl_Return_Button *b = new Fl_Return_Button(width - 3 * BB - 3 * WB, height - BH - WB, BB, BH, "Apply");
+		b->callback(wizard_update_edges_cb);
+	    }
+	    {
+		Fl_Button *b = new Fl_Button(width - 2 * BB - 2 * WB, height - BH - WB, BB, BH, "Next");
+//		b->callback(options_save_cb);
+	    }
+	    {
+		Fl_Button *b = new Fl_Button(width - BB - WB, height - BH - WB, BB, BH, "Cancel");
+		b->callback(cancel_cb, (void *)swiz_window);
+	    }
+
+	    o->end();
+	}	
+	{
+	    Fl_Group *o = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Reverse Engineering the CAD");
+	    {
+		Fl_Return_Button *b = new Fl_Return_Button(width - 3 * BB - 3 * WB, height - BH - WB, BB, BH, "Apply");
+//		b->callback(wizard_update_edges_cb);
+	    }
+	    {
+		Fl_Button *b = new Fl_Button(width - 2 * BB - 2 * WB, height - BH - WB, BB, BH, "Next");
+//		b->callback(options_save_cb);
+	    }
+	    {
+		Fl_Button *b = new Fl_Button(width - BB - WB, height - BH - WB, BB, BH, "Cancel");
+		b->callback(cancel_cb, (void *)swiz_window);
+	    }
+
 	    o->end();
 	}	
 	o->end();
diff --git a/Graphics/Geom.cpp b/Graphics/Geom.cpp
index 6830c1fa52..9fcf1c378d 100644
--- a/Graphics/Geom.cpp
+++ b/Graphics/Geom.cpp
@@ -1,4 +1,4 @@
-// $Id: Geom.cpp,v 1.84 2005-05-16 00:50:10 geuzaine Exp $
+// $Id: Geom.cpp,v 1.85 2005-06-27 15:03:45 remacle Exp $
 //
 // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle
 //
@@ -41,304 +41,299 @@ extern Mesh *THEM;
 
 void Draw_Geo_Point(void *a, void *b)
 {
-  char Num[100];
-
-  Vertex *v = *(Vertex **) a;
-
-  if(!(v->Visible & VIS_GEOM))
-    return;
-
-  if(CTX.render_mode == GMSH_SELECT) {
-    glLoadName(0);
-    glPushName(v->Num);
-  }
-
-  if(v->Frozen) {
-    glPointSize(CTX.geom.point_sel_size);
-    gl2psPointSize(CTX.geom.point_sel_size * CTX.print.eps_point_size_factor);
-    glColor4ubv((GLubyte *) & CTX.color.geom.point_sel);
-  }
-  else {
-    glPointSize(CTX.geom.point_size);
-    gl2psPointSize(CTX.geom.point_size * CTX.print.eps_point_size_factor);
-    glColor4ubv((GLubyte *) & CTX.color.geom.point);
-  }
-
-  if(CTX.geom.points) {
-    if(CTX.geom.point_type == 1) {
-      if(v->Frozen)
-        Draw_Sphere(CTX.geom.point_sel_size, v->Pos.X, v->Pos.Y, v->Pos.Z, 
-		    CTX.geom.light);
-      else
-        Draw_Sphere(CTX.geom.point_size, v->Pos.X, v->Pos.Y, v->Pos.Z,
-		    CTX.geom.light);
+    char Num[100];
+
+    Vertex *v = *(Vertex **) a;
+
+    if(!(v->Visible & VIS_GEOM))
+	return;
+
+    if(CTX.render_mode == GMSH_SELECT) {
+	glLoadName(0);
+	glPushName(v->Num);
     }
-    else if(CTX.geom.point_type == 2) {
-      GMSH_Solve_Plugin *sp = GMSH_PluginManager::instance()->findSolverPlugin();
-      if(sp) {
-	sp-> GL_enhancePoint (v);
-      }
-      glBegin(GL_POINTS);
-      glVertex3d(v->Pos.X, v->Pos.Y, v->Pos.Z);
-      glEnd();
+
+    if(v->Frozen) {
+	glPointSize(CTX.geom.point_sel_size);
+	gl2psPointSize(CTX.geom.point_sel_size * CTX.print.eps_point_size_factor);
+	glColor4ubv((GLubyte *) & CTX.color.geom.point_sel);
     }
     else {
-      glBegin(GL_POINTS);
-      glVertex3d(v->Pos.X, v->Pos.Y, v->Pos.Z);
-      glEnd();
+	glPointSize(CTX.geom.point_size);
+	gl2psPointSize(CTX.geom.point_size * CTX.print.eps_point_size_factor);
+	glColor4ubv((GLubyte *) & CTX.color.geom.point);
     }
 
-  }
+    if(CTX.geom.points) {
+	if(CTX.geom.point_type == 1) {
+	    if(v->Frozen)
+		Draw_Sphere(CTX.geom.point_sel_size, v->Pos.X, v->Pos.Y, v->Pos.Z, 
+			    CTX.geom.light);
+	    else
+		Draw_Sphere(CTX.geom.point_size, v->Pos.X, v->Pos.Y, v->Pos.Z,
+			    CTX.geom.light);
+	}
+	else if(CTX.geom.point_type == 2) {
+	    GMSH_Solve_Plugin *sp = GMSH_PluginManager::instance()->findSolverPlugin();
+	    if(sp) {
+		sp-> GL_enhancePoint (v);
+	    }
+	    glBegin(GL_POINTS);
+	    glVertex3d(v->Pos.X, v->Pos.Y, v->Pos.Z);
+	    glEnd();
+	}
+	else {
+	    glBegin(GL_POINTS);
+	    glVertex3d(v->Pos.X, v->Pos.Y, v->Pos.Z);
+	    glEnd();
+	}
+
+    }
 
-  if(CTX.geom.points_num) {
-    sprintf(Num, "%d", v->Num);
-    double offset = (0.5 * CTX.geom.point_size + 0.3 * CTX.gl_fontsize) * CTX.pixel_equiv_x;
-    glRasterPos3d(v->Pos.X + offset / CTX.s[0],
-                  v->Pos.Y + offset / CTX.s[1],
-                  v->Pos.Z + offset / CTX.s[2]);
-    Draw_String(Num);
-  }
+    if(CTX.geom.points_num) {
+	sprintf(Num, "%d", v->Num);
+	double offset = (0.5 * CTX.geom.point_size + 0.3 * CTX.gl_fontsize) * CTX.pixel_equiv_x;
+	glRasterPos3d(v->Pos.X + offset / CTX.s[0],
+		      v->Pos.Y + offset / CTX.s[1],
+		      v->Pos.Z + offset / CTX.s[2]);
+	Draw_String(Num);
+    }
 
-  if(CTX.render_mode == GMSH_SELECT) {
-    glPopName();
-  }
+    if(CTX.render_mode == GMSH_SELECT) {
+	glPopName();
+    }
 }
 
 // Curves
 
 void Draw_Curve(void *a, void *b)
 {
-  int N;
-  double mod, x[2], y[2], z[2];
-  char Num[100];
-  Vertex v, dv;
-
-  Curve *c = *(Curve **) a;
-
-  if(c->Num < 0 || !(c->Visible & VIS_GEOM))
-    return;
-
-  if(CTX.render_mode == GMSH_SELECT) {
-    glLoadName(1);
-    glPushName(c->Num);
-  }
-
-  if(c->ipar[3]) {
-    glLineWidth(CTX.geom.line_sel_width);
-    gl2psLineWidth(CTX.geom.line_sel_width * CTX.print.eps_line_width_factor);
-    glColor4ubv((GLubyte *) & CTX.color.geom.line_sel);
-  }
-  else {
-    glLineWidth(CTX.geom.line_width);
-    gl2psLineWidth(CTX.geom.line_width * CTX.print.eps_line_width_factor);
-    glColor4ubv((GLubyte *) & CTX.color.geom.line);
-  }
-
-  if(CTX.geom.lines) {
-    int n = List_Nbr(c->Control_Points);
-    switch (c->Typ) {
-    case MSH_SEGM_LINE:
-      N = n;
-      break;
-    case MSH_SEGM_CIRC:
-    case MSH_SEGM_CIRC_INV:
-    case MSH_SEGM_ELLI:
-    case MSH_SEGM_ELLI_INV:
-      N = CTX.geom.circle_points;
-      break;
-    default:
-      N = 10 * n;
-      break;
-    }
-    if(c->bds) {
-      std::set<BDS_Edge*, EdgeLessThan>::iterator it  = c->bds->edges.begin();
-      std::set<BDS_Edge*, EdgeLessThan>::iterator ite = c->bds->edges.end();
-      while (it!=ite)
-      {
-	  if ((*it)->g && (*it)->g->classif_degree == 1&& c->Num == (*it)->g->classif_tag)
-	  { 
-	      BDS_Edge *e = (*it);
-	      glBegin(GL_LINES);
-	      glVertex3d(e->p1->X,e->p1->Y,e->p1->Z);
-	      glVertex3d(e->p2->X,e->p2->Y,e->p2->Z);
-	      glEnd();
-	  }
-	  ++it;
-      }
-    }
-    else if(c->Typ == MSH_SEGM_DISCRETE) {
-      // do nothing
+    int N;
+    double mod, x[2], y[2], z[2];
+    char Num[100];
+    Vertex v, dv;
+
+    Curve *c = *(Curve **) a;
+
+    if(c->Num < 0 || !(c->Visible & VIS_GEOM))
+	return;
+
+    if(CTX.render_mode == GMSH_SELECT) {
+	glLoadName(1);
+	glPushName(c->Num);
+    }
+
+    if(c->ipar[3]) {
+	glLineWidth(CTX.geom.line_sel_width);
+	gl2psLineWidth(CTX.geom.line_sel_width * CTX.print.eps_line_width_factor);
+	glColor4ubv((GLubyte *) & CTX.color.geom.line_sel);
     }
     else {
-      if(CTX.geom.line_type >= 1) {
-        for(int i = 0; i < N - 1; i++) {
-          v = InterpolateCurve(c, (double)i / (double)(N - 1), 0);
-          dv = InterpolateCurve(c, (double)(i + 1) / (double)(N - 1), 0);
-          x[0] = v.Pos.X;
-          y[0] = v.Pos.Y;
-          z[0] = v.Pos.Z;
-          x[1] = dv.Pos.X;
-          y[1] = dv.Pos.Y;
-          z[1] = dv.Pos.Z;
-          Draw_Cylinder(c->ipar[3] ? CTX.geom.line_sel_width : CTX.geom.line_width,
-			x, y, z, CTX.geom.light);
-        }
-	if(CTX.geom.line_type == 2) {
-	  GMSH_Solve_Plugin *sp = GMSH_PluginManager::instance()->findSolverPlugin();
-	  if(sp) {
-	    int NN=(N>1)?N:1;
-	    const double eps=0.e-2;
-	    for(int i = 0; i < NN - 1; i++) {
-	      v = InterpolateCurve(c, (double)i / (double)(NN - 1)-eps, 0);
-	      dv = InterpolateCurve(c, (double)(i + 1) / (double)(NN - 1)+eps, 0);
-	      sp-> GL_enhanceLine (c->Num,&v,&dv);
+	glLineWidth(CTX.geom.line_width);
+	gl2psLineWidth(CTX.geom.line_width * CTX.print.eps_line_width_factor);
+	glColor4ubv((GLubyte *) & CTX.color.geom.line);
+    }
+
+    if(CTX.geom.lines) {
+	int n = List_Nbr(c->Control_Points);
+	switch (c->Typ) {
+	    case MSH_SEGM_LINE:
+		N = n;
+		break;
+	    case MSH_SEGM_CIRC:
+	    case MSH_SEGM_CIRC_INV:
+	    case MSH_SEGM_ELLI:
+	    case MSH_SEGM_ELLI_INV:
+		N = CTX.geom.circle_points;
+		break;
+	    default:
+		N = 10 * n;
+		break;
+	}
+	if(c->Typ == MSH_SEGM_DISCRETE && c->bds) {
+
+	    BDS_GeomEntity *g = c->bds->get_geom ( c->Num,1);	
+	    std::list<BDS_Edge*>::iterator it  = g->e.begin();
+	    std::list<BDS_Edge*>::iterator ite = g->e.end();
+	    while (it!=ite)
+	    {
+		BDS_Edge *e = (*it);
+		glBegin(GL_LINES);
+		glVertex3d(e->p1->X,e->p1->Y,e->p1->Z);
+		glVertex3d(e->p2->X,e->p2->Y,e->p2->Z);
+		glEnd();
+		++it;
+	    }
+	}
+	else {
+	    if(CTX.geom.line_type >= 1) {
+		for(int i = 0; i < N - 1; i++) {
+		    v = InterpolateCurve(c, (double)i / (double)(N - 1), 0);
+		    dv = InterpolateCurve(c, (double)(i + 1) / (double)(N - 1), 0);
+		    x[0] = v.Pos.X;
+		    y[0] = v.Pos.Y;
+		    z[0] = v.Pos.Z;
+		    x[1] = dv.Pos.X;
+		    y[1] = dv.Pos.Y;
+		    z[1] = dv.Pos.Z;
+		    Draw_Cylinder(c->ipar[3] ? CTX.geom.line_sel_width : CTX.geom.line_width,
+				  x, y, z, CTX.geom.light);
+		}
+		if(CTX.geom.line_type == 2) {
+		    GMSH_Solve_Plugin *sp = GMSH_PluginManager::instance()->findSolverPlugin();
+		    if(sp) {
+			int NN=(N>1)?N:1;
+			const double eps=0.e-2;
+			for(int i = 0; i < NN - 1; i++) {
+			    v = InterpolateCurve(c, (double)i / (double)(NN - 1)-eps, 0);
+			    dv = InterpolateCurve(c, (double)(i + 1) / (double)(NN - 1)+eps, 0);
+			    sp-> GL_enhanceLine (c->Num,&v,&dv);
+			}
+		    }
+		}
+	    }
+	    else {
+		glBegin(GL_LINE_STRIP);
+		for(int i = 0; i < N; i++) {
+		    v = InterpolateCurve(c, (double)i / (double)(N - 1), 0);
+		    glVertex3d(v.Pos.X, v.Pos.Y, v.Pos.Z);
+		}
+		glEnd();
 	    }
-	  }
 	}
-      }
-      else {
-        glBegin(GL_LINE_STRIP);
-        for(int i = 0; i < N; i++) {
-          v = InterpolateCurve(c, (double)i / (double)(N - 1), 0);
-          glVertex3d(v.Pos.X, v.Pos.Y, v.Pos.Z);
-        }
-        glEnd();
-      }
-    }
-  }
-
-  if(CTX.geom.lines_num) {
-    v = InterpolateCurve(c, 0.5, 0);
-    sprintf(Num, "%d", c->Num);
-    double offset = (0.5 * CTX.geom.line_width + 0.3 * CTX.gl_fontsize) * CTX.pixel_equiv_x;
-    glRasterPos3d(v.Pos.X + offset / CTX.s[0],
-                  v.Pos.Y + offset / CTX.s[1],
-                  v.Pos.Z + offset / CTX.s[2]);
-    Draw_String(Num);
-  }
-
-  if(CTX.geom.tangents) {
-    v = InterpolateCurve(c, 0.5, 0);
-    dv = InterpolateCurve(c, 0.5, 1);
-    mod = sqrt(dv.Pos.X * dv.Pos.X + dv.Pos.Y * dv.Pos.Y + dv.Pos.Z * dv.Pos.Z);
-    dv.Pos.X = dv.Pos.X / mod * CTX.geom.tangents * CTX.pixel_equiv_x / CTX.s[0];
-    dv.Pos.Y = dv.Pos.Y / mod * CTX.geom.tangents * CTX.pixel_equiv_x / CTX.s[1];
-    dv.Pos.Z = dv.Pos.Z / mod * CTX.geom.tangents * CTX.pixel_equiv_x / CTX.s[2];
-    glColor4ubv((GLubyte *) & CTX.color.geom.tangents);
-    Draw_Vector(CTX.vector_type, 0, CTX.arrow_rel_head_radius, 
-		CTX.arrow_rel_stem_length, CTX.arrow_rel_stem_radius,
-		v.Pos.X, v.Pos.Y, v.Pos.Z,
-                dv.Pos.X, dv.Pos.Y, dv.Pos.Z, CTX.geom.light);
-  }
-
-  if(CTX.render_mode == GMSH_SELECT) {
-    glPopName();
-  }
+    }
+
+    if(CTX.geom.lines_num) {
+	v = InterpolateCurve(c, 0.5, 0);
+	sprintf(Num, "%d", c->Num);
+	double offset = (0.5 * CTX.geom.line_width + 0.3 * CTX.gl_fontsize) * CTX.pixel_equiv_x;
+	glRasterPos3d(v.Pos.X + offset / CTX.s[0],
+		      v.Pos.Y + offset / CTX.s[1],
+		      v.Pos.Z + offset / CTX.s[2]);
+	Draw_String(Num);
+    }
+
+    if(CTX.geom.tangents) {
+	v = InterpolateCurve(c, 0.5, 0);
+	dv = InterpolateCurve(c, 0.5, 1);
+	mod = sqrt(dv.Pos.X * dv.Pos.X + dv.Pos.Y * dv.Pos.Y + dv.Pos.Z * dv.Pos.Z);
+	dv.Pos.X = dv.Pos.X / mod * CTX.geom.tangents * CTX.pixel_equiv_x / CTX.s[0];
+	dv.Pos.Y = dv.Pos.Y / mod * CTX.geom.tangents * CTX.pixel_equiv_x / CTX.s[1];
+	dv.Pos.Z = dv.Pos.Z / mod * CTX.geom.tangents * CTX.pixel_equiv_x / CTX.s[2];
+	glColor4ubv((GLubyte *) & CTX.color.geom.tangents);
+	Draw_Vector(CTX.vector_type, 0, CTX.arrow_rel_head_radius, 
+		    CTX.arrow_rel_stem_length, CTX.arrow_rel_stem_radius,
+		    v.Pos.X, v.Pos.Y, v.Pos.Z,
+		    dv.Pos.X, dv.Pos.Y, dv.Pos.Z, CTX.geom.light);
+    }
+
+    if(CTX.render_mode == GMSH_SELECT) {
+	glPopName();
+    }
 }
 
 // Surfaces
 
 void putZ(Vertex * v, Surface * s)
 {
-  Vertex V;
-  V.Pos.X = s->a;
-  V.Pos.Y = s->b;
-  V.Pos.Z = s->c;
-  Projette(&V, s->plan);
-  if(V.Pos.Z != 0.0)
-    v->Pos.Z = (s->d - V.Pos.X * v->Pos.X - V.Pos.Y * v->Pos.Y) / V.Pos.Z;
-  else
-    v->Pos.Z = 0.0;
-
-  Projette(v, s->invplan);
+    Vertex V;
+    V.Pos.X = s->a;
+    V.Pos.Y = s->b;
+    V.Pos.Z = s->c;
+    Projette(&V, s->plan);
+    if(V.Pos.Z != 0.0)
+	v->Pos.Z = (s->d - V.Pos.X * v->Pos.X - V.Pos.Y * v->Pos.Y) / V.Pos.Z;
+    else
+	v->Pos.Z = 0.0;
+
+    Projette(v, s->invplan);
 }
 
 int isPointOnPlanarSurface(Surface * S, double X, double Y, double Z,
                            double n[3])
 {
-  double Angle = 0.0;
-  Vertex V;
-  V.Pos.X = X;
-  V.Pos.Y = Y;
-  V.Pos.Z = Z;
+    double Angle = 0.0;
+    Vertex V;
+    V.Pos.X = X;
+    V.Pos.Y = Y;
+    V.Pos.Z = Z;
 
-  for(int i = 0; i < List_Nbr(S->Generatrices); i++) {
+    for(int i = 0; i < List_Nbr(S->Generatrices); i++) {
 
-    Curve *C;
-    List_Read(S->Generatrices, i, &C);
+	Curve *C;
+	List_Read(S->Generatrices, i, &C);
 
-    int N = (C->Typ == MSH_SEGM_LINE) ? 1 : 10;
+	int N = (C->Typ == MSH_SEGM_LINE) ? 1 : 10;
 
-    for(int j = 0; j < N; j++) {
-      double u1 = (double)j / (double)(N);
-      double u2 = (double)(j + 1) / (double)(N);
-      Vertex P1 = InterpolateCurve(C, u1, 0);
-      Vertex P2 = InterpolateCurve(C, u2, 0);
-      Angle += angle_plan(&V, &P1, &P2, n);
-    }
+	for(int j = 0; j < N; j++) {
+	    double u1 = (double)j / (double)(N);
+	    double u2 = (double)(j + 1) / (double)(N);
+	    Vertex P1 = InterpolateCurve(C, u1, 0);
+	    Vertex P2 = InterpolateCurve(C, u2, 0);
+	    Angle += angle_plan(&V, &P1, &P2, n);
+	}
 
-  }
+    }
 
-  // if Angle == 2*pi, we're inside
+    // if Angle == 2*pi, we're inside
 
-  if(fabs(Angle) > 2*M_PI-0.5 && fabs(Angle) < 2*M_PI+0.5) 
-    return 1;
-  return 0;
+    if(fabs(Angle) > 2*M_PI-0.5 && fabs(Angle) < 2*M_PI+0.5) 
+	return 1;
+    return 0;
 }
 
 void getPlaneSurfaceNormal(Surface *s, double x, double y, double z, double n[3])
 {
-  double t1[3], t2[3];
-  Curve *c;
-
-  for(int i = 0; i < 3; i++)
-    n[i] = 0.0;
-
-  if(s->Typ != MSH_SURF_PLAN)
-    return;
-
-  // We cannot use s->plan or InterpolateSurface here (they both rely
-  // on the mean plane, which borks the orientation). So we need to
-  // use this trick:
-
-  if(List_Nbr(s->Generatrices) > 1){
-    List_Read(s->Generatrices, 0, &c);
-    if(c->beg){
-      t1[0] = x - c->beg->Pos.X;
-      t1[1] = y - c->beg->Pos.Y;
-      t1[2] = z - c->beg->Pos.Z;
-      for(int i = 1; i < List_Nbr(s->Generatrices); i++){
-	List_Read(s->Generatrices, i, &c);
-	t2[0] = x - c->beg->Pos.X;
-	t2[1] = y - c->beg->Pos.Y;
-	t2[2] = z - c->beg->Pos.Z;
-	prodve(t1, t2, n);
-	if(norme(n))
-	  break;
-      }
-    }
-  }
-  if(List_Nbr(s->Generatrices) < 2 || !norme(n)){
-    Msg(WARNING, "Reverting to mean plane normal for surface %d", s->Num);
-    n[0] = s->a;
-    n[1] = s->b;
-    n[2] = s->c;
-    norme(n);
-  }
+    double t1[3], t2[3];
+    Curve *c;
+
+    for(int i = 0; i < 3; i++)
+	n[i] = 0.0;
+
+    if(s->Typ != MSH_SURF_PLAN)
+	return;
+
+    // We cannot use s->plan or InterpolateSurface here (they both rely
+    // on the mean plane, which borks the orientation). So we need to
+    // use this trick:
+
+    if(List_Nbr(s->Generatrices) > 1){
+	List_Read(s->Generatrices, 0, &c);
+	if(c->beg){
+	    t1[0] = x - c->beg->Pos.X;
+	    t1[1] = y - c->beg->Pos.Y;
+	    t1[2] = z - c->beg->Pos.Z;
+	    for(int i = 1; i < List_Nbr(s->Generatrices); i++){
+		List_Read(s->Generatrices, i, &c);
+		t2[0] = x - c->beg->Pos.X;
+		t2[1] = y - c->beg->Pos.Y;
+		t2[2] = z - c->beg->Pos.Z;
+		prodve(t1, t2, n);
+		if(norme(n))
+		    break;
+	    }
+	}
+    }
+    if(List_Nbr(s->Generatrices) < 2 || !norme(n)){
+	Msg(WARNING, "Reverting to mean plane normal for surface %d", s->Num);
+	n[0] = s->a;
+	n[1] = s->b;
+	n[2] = s->c;
+	norme(n);
+    }
 }
 
 void Draw_Polygonal_Surface(Surface * s)
 {
-  if(CTX.geom.surfaces) {
-    if(CTX.geom.light) glEnable(GL_LIGHTING);
-    glEnable(GL_POLYGON_OFFSET_FILL); // always!
-
-    std::list<BDS_Triangle*>::iterator it  = s->bds->triangles.begin();
-    std::list<BDS_Triangle*>::iterator ite = s->bds->triangles.end();
-    while (it!=ite)
-    {
-	if (!(*it)->g || s->Num == (*it)->g->classif_tag)
-	{ 
+    if(CTX.geom.surfaces) {
+	if(CTX.geom.light) glEnable(GL_LIGHTING);
+	glEnable(GL_POLYGON_OFFSET_FILL); // always!
+
+	BDS_GeomEntity *g = s->bds->get_geom ( s->Num,2);	
+	std::list<BDS_Triangle*>::iterator it  = g->t.begin();
+	std::list<BDS_Triangle*>::iterator ite = g->t.end();
+	while (it!=ite)
+	{
 	    glBegin(GL_TRIANGLES);
 	    BDS_Point *n[3];
 	    BDS_Triangle *t = (*it);
@@ -352,290 +347,289 @@ void Draw_Polygonal_Surface(Surface * s)
 	    if(CTX.geom.light) glNormal3dv(c);
 	    glVertex3d(n[2]->X,n[2]->Y,n[2]->Z);
 	    glEnd();
+	    ++it;
 	}
-	++it;
-    }
-    glDisable(GL_POLYGON_OFFSET_FILL);
-    glDisable(GL_LIGHTING);
-  }  
+	glDisable(GL_POLYGON_OFFSET_FILL);
+	glDisable(GL_LIGHTING);
+    }  
 }
 
 void Draw_Plane_Surface(Surface * s)
 {
-  Curve *c;
-  Vertex V[4], vv, vv1, vv2;
-  double n[3];
+    Curve *c;
+    Vertex V[4], vv, vv1, vv2;
+    double n[3];
 
-  if(!CTX.threads_lock && List_Nbr(s->Orientations) < 1) {
-    CTX.threads_lock = 1;
+    if(!CTX.threads_lock && List_Nbr(s->Orientations) < 1) {
+	CTX.threads_lock = 1;
 
-    List_T *points = List_Create(10, 10, sizeof(Vertex *));
-    for(int i = 0; i < List_Nbr(s->Generatrices); i++) {
-      List_Read(s->Generatrices, i, &c);
-      for(int j = 0; j < List_Nbr(c->Control_Points); j++) {
-        List_Add(points, List_Pointer(c->Control_Points, j));
-      }
-    }
+	List_T *points = List_Create(10, 10, sizeof(Vertex *));
+	for(int i = 0; i < List_Nbr(s->Generatrices); i++) {
+	    List_Read(s->Generatrices, i, &c);
+	    for(int j = 0; j < List_Nbr(c->Control_Points); j++) {
+		List_Add(points, List_Pointer(c->Control_Points, j));
+	    }
+	}
 
-    if(!List_Nbr(points)){
-      List_Delete(points);      
-      CTX.threads_lock = 0;
-      return;
-    }
-    MeanPlane(points, s);
-    List_Delete(points);
+	if(!List_Nbr(points)){
+	    List_Delete(points);      
+	    CTX.threads_lock = 0;
+	    return;
+	}
+	MeanPlane(points, s);
+	List_Delete(points);
     
-    // compute (rough) bounding box of surface
-    double minx = 0., miny = 0., maxx = 0., maxy = 0.;
-    for(int i = 0; i < List_Nbr(s->Generatrices); i++) {
-      List_Read(s->Generatrices, i, &c);
-      Vertex P1 = InterpolateCurve(c, 0.0, 0);
-      Vertex P2 = InterpolateCurve(c, 0.5, 0);
-      Vertex P3 = InterpolateCurve(c, 1.0, 0);
-      Projette(&P1, s->plan);
-      Projette(&P2, s->plan);
-      Projette(&P3, s->plan);
-      if(!i) {
-        minx = maxx = P1.Pos.X;
-        miny = maxy = P1.Pos.Y;
-      }
-      minx = DMIN(DMIN(DMIN(minx, P1.Pos.X), P2.Pos.X), P3.Pos.X);
-      miny = DMIN(DMIN(DMIN(miny, P1.Pos.Y), P2.Pos.Y), P3.Pos.Y);
-      maxx = DMAX(DMAX(DMAX(maxx, P1.Pos.X), P2.Pos.X), P3.Pos.X);
-      maxy = DMAX(DMAX(DMAX(maxy, P1.Pos.Y), P2.Pos.Y), P3.Pos.Y);
-    }
-
-    V[0].Pos.X = minx;
-    V[0].Pos.Y = miny;
-    V[1].Pos.X = maxx;
-    V[1].Pos.Y = miny;
-    V[2].Pos.X = maxx;
-    V[2].Pos.Y = maxy;
-    V[3].Pos.X = minx;
-    V[3].Pos.Y = maxy;
-
-    for(int i = 0; i < 4; i++) {
-      V[i].Pos.Z = 0.0;
-      putZ(&V[i], s);
-    }
-
-    n[0] = s->plan[2][0];
-    n[1] = s->plan[2][1];
-    n[2] = s->plan[2][2];
-    norme(n);
-
-    // compute which parts of the "middle cross" lie inside the surface
-    const int numPoints = 200;
-    for(int cross = 0; cross < 2; cross++) {
-      int k = 0;
-      for(int i = 0; i < numPoints; i++) {
-	double t = (double)i / (double)(numPoints-1);
-	if(!cross){
-	  vv.Pos.X = t * 0.5 * (V[0].Pos.X + V[1].Pos.X) + 
-	    (1. - t) * 0.5 * (V[2].Pos.X + V[3].Pos.X);
-	  vv.Pos.Y = t * 0.5 * (V[0].Pos.Y + V[1].Pos.Y) + 
-	    (1. - t) * 0.5 * (V[2].Pos.Y + V[3].Pos.Y);
-	  vv.Pos.Z = t * 0.5 * (V[0].Pos.Z + V[1].Pos.Z) + 
-	    (1. - t) * 0.5 * (V[2].Pos.Z + V[3].Pos.Z);
+	// compute (rough) bounding box of surface
+	double minx = 0., miny = 0., maxx = 0., maxy = 0.;
+	for(int i = 0; i < List_Nbr(s->Generatrices); i++) {
+	    List_Read(s->Generatrices, i, &c);
+	    Vertex P1 = InterpolateCurve(c, 0.0, 0);
+	    Vertex P2 = InterpolateCurve(c, 0.5, 0);
+	    Vertex P3 = InterpolateCurve(c, 1.0, 0);
+	    Projette(&P1, s->plan);
+	    Projette(&P2, s->plan);
+	    Projette(&P3, s->plan);
+	    if(!i) {
+		minx = maxx = P1.Pos.X;
+		miny = maxy = P1.Pos.Y;
+	    }
+	    minx = DMIN(DMIN(DMIN(minx, P1.Pos.X), P2.Pos.X), P3.Pos.X);
+	    miny = DMIN(DMIN(DMIN(miny, P1.Pos.Y), P2.Pos.Y), P3.Pos.Y);
+	    maxx = DMAX(DMAX(DMAX(maxx, P1.Pos.X), P2.Pos.X), P3.Pos.X);
+	    maxy = DMAX(DMAX(DMAX(maxy, P1.Pos.Y), P2.Pos.Y), P3.Pos.Y);
 	}
-	else{
-	  vv.Pos.X = t * .5 * (V[0].Pos.X + V[3].Pos.X) + 
-	    (1. - t) * .5 * (V[2].Pos.X + V[1].Pos.X);
-	  vv.Pos.Y = t * .5 * (V[0].Pos.Y + V[3].Pos.Y) + 
-	    (1. - t) * .5 * (V[2].Pos.Y + V[1].Pos.Y);
-	  vv.Pos.Z = t * .5 * (V[0].Pos.Z + V[3].Pos.Z) + 
-	    (1. - t) * .5 * (V[2].Pos.Z + V[1].Pos.Z);
+
+	V[0].Pos.X = minx;
+	V[0].Pos.Y = miny;
+	V[1].Pos.X = maxx;
+	V[1].Pos.Y = miny;
+	V[2].Pos.X = maxx;
+	V[2].Pos.Y = maxy;
+	V[3].Pos.X = minx;
+	V[3].Pos.Y = maxy;
+
+	for(int i = 0; i < 4; i++) {
+	    V[i].Pos.Z = 0.0;
+	    putZ(&V[i], s);
 	}
-	if(isPointOnPlanarSurface(s, vv.Pos.X, vv.Pos.Y, vv.Pos.Z, n)) {
-	  if(!k) {
-	    List_Add(s->Orientations, &vv);
-	    k = 1;
-	  }
+
+	n[0] = s->plan[2][0];
+	n[1] = s->plan[2][1];
+	n[2] = s->plan[2][2];
+	norme(n);
+
+	// compute which parts of the "middle cross" lie inside the surface
+	const int numPoints = 200;
+	for(int cross = 0; cross < 2; cross++) {
+	    int k = 0;
+	    for(int i = 0; i < numPoints; i++) {
+		double t = (double)i / (double)(numPoints-1);
+		if(!cross){
+		    vv.Pos.X = t * 0.5 * (V[0].Pos.X + V[1].Pos.X) + 
+			(1. - t) * 0.5 * (V[2].Pos.X + V[3].Pos.X);
+		    vv.Pos.Y = t * 0.5 * (V[0].Pos.Y + V[1].Pos.Y) + 
+			(1. - t) * 0.5 * (V[2].Pos.Y + V[3].Pos.Y);
+		    vv.Pos.Z = t * 0.5 * (V[0].Pos.Z + V[1].Pos.Z) + 
+			(1. - t) * 0.5 * (V[2].Pos.Z + V[3].Pos.Z);
+		}
+		else{
+		    vv.Pos.X = t * .5 * (V[0].Pos.X + V[3].Pos.X) + 
+			(1. - t) * .5 * (V[2].Pos.X + V[1].Pos.X);
+		    vv.Pos.Y = t * .5 * (V[0].Pos.Y + V[3].Pos.Y) + 
+			(1. - t) * .5 * (V[2].Pos.Y + V[1].Pos.Y);
+		    vv.Pos.Z = t * .5 * (V[0].Pos.Z + V[3].Pos.Z) + 
+			(1. - t) * .5 * (V[2].Pos.Z + V[1].Pos.Z);
+		}
+		if(isPointOnPlanarSurface(s, vv.Pos.X, vv.Pos.Y, vv.Pos.Z, n)) {
+		    if(!k) {
+			List_Add(s->Orientations, &vv);
+			k = 1;
+		    }
+		}
+		else {
+		    if(k) {
+			List_Add(s->Orientations, &vv);
+			k = 0;
+		    }
+		}
+	    }
+	    if(k)
+		List_Add(s->Orientations, &vv);
 	}
-	else {
-	  if(k) {
+
+	Msg(STATUS2, "Plane Surface %d (%d cross points)", 
+	    s->Num, List_Nbr(s->Orientations));
+    
+	if(!List_Nbr(s->Orientations)){ // add dummy
 	    List_Add(s->Orientations, &vv);
-	    k = 0;
-	  }
+	    //printf("surf %d: min=%g %g max=%g %g\n", s->Num, minx, miny, maxx, maxy);
 	}
-      }
-      if(k)
-	List_Add(s->Orientations, &vv);
-    }
 
-    Msg(STATUS2, "Plane Surface %d (%d cross points)", 
-	s->Num, List_Nbr(s->Orientations));
-    
-    if(!List_Nbr(s->Orientations)){ // add dummy
-      List_Add(s->Orientations, &vv);
-      //printf("surf %d: min=%g %g max=%g %g\n", s->Num, minx, miny, maxx, maxy);
+	CTX.threads_lock = 0;
     }
-
-    CTX.threads_lock = 0;
-  }
   
-  if(List_Nbr(s->Orientations) > 1) {
+    if(List_Nbr(s->Orientations) > 1) {
+
+	if(CTX.geom.surfaces) {
+	    glEnable(GL_LINE_STIPPLE);
+	    glLineStipple(1, 0x1F1F);
+	    gl2psEnable(GL2PS_LINE_STIPPLE);
+	    glBegin(GL_LINES);
+	    for(int i = 0; i < List_Nbr(s->Orientations); i++) {
+		List_Read(s->Orientations, i, &vv);
+		glVertex3d(vv.Pos.X, vv.Pos.Y, vv.Pos.Z);
+	    }
+	    glEnd();
+	    glDisable(GL_LINE_STIPPLE);
+	    gl2psDisable(GL2PS_LINE_STIPPLE);
+	}
 
-    if(CTX.geom.surfaces) {
-      glEnable(GL_LINE_STIPPLE);
-      glLineStipple(1, 0x1F1F);
-      gl2psEnable(GL2PS_LINE_STIPPLE);
-      glBegin(GL_LINES);
-      for(int i = 0; i < List_Nbr(s->Orientations); i++) {
-	List_Read(s->Orientations, i, &vv);
-	glVertex3d(vv.Pos.X, vv.Pos.Y, vv.Pos.Z);
-      }
-      glEnd();
-      glDisable(GL_LINE_STIPPLE);
-      gl2psDisable(GL2PS_LINE_STIPPLE);
-    }
+	if(CTX.geom.surfaces_num) {
+	    List_Read(s->Orientations, 0, &vv1);
+	    List_Read(s->Orientations, 1, &vv2);
+	    char Num[100];
+	    sprintf(Num, "%d", s->Num);
+	    double offset = 0.3 * CTX.gl_fontsize * CTX.pixel_equiv_x;
+	    glRasterPos3d((vv2.Pos.X + vv1.Pos.X) / 2. + offset / CTX.s[0],
+			  (vv2.Pos.Y + vv1.Pos.Y) / 2. + offset / CTX.s[1],
+			  (vv2.Pos.Z + vv1.Pos.Z) / 2. + offset / CTX.s[2]);
+	    Draw_String(Num);
+	}
 
-    if(CTX.geom.surfaces_num) {
-      List_Read(s->Orientations, 0, &vv1);
-      List_Read(s->Orientations, 1, &vv2);
-      char Num[100];
-      sprintf(Num, "%d", s->Num);
-      double offset = 0.3 * CTX.gl_fontsize * CTX.pixel_equiv_x;
-      glRasterPos3d((vv2.Pos.X + vv1.Pos.X) / 2. + offset / CTX.s[0],
-                    (vv2.Pos.Y + vv1.Pos.Y) / 2. + offset / CTX.s[1],
-                    (vv2.Pos.Z + vv1.Pos.Z) / 2. + offset / CTX.s[2]);
-      Draw_String(Num);
-    }
+	if(CTX.geom.normals) {
+	    List_Read(s->Orientations, 0, &vv1);
+	    List_Read(s->Orientations, 1, &vv2);
+	    double x = (vv1.Pos.X + vv2.Pos.X) / 2.;
+	    double y = (vv1.Pos.Y + vv2.Pos.Y) / 2.;
+	    double z = (vv1.Pos.Z + vv2.Pos.Z) / 2.;
+	    getPlaneSurfaceNormal(s, x, y, z, 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, 
+			x, y, z, n[0], n[1], n[2], CTX.geom.light);
+	}
 
-    if(CTX.geom.normals) {
-      List_Read(s->Orientations, 0, &vv1);
-      List_Read(s->Orientations, 1, &vv2);
-      double x = (vv1.Pos.X + vv2.Pos.X) / 2.;
-      double y = (vv1.Pos.Y + vv2.Pos.Y) / 2.;
-      double z = (vv1.Pos.Z + vv2.Pos.Z) / 2.;
-      getPlaneSurfaceNormal(s, x, y, z, 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, 
-		  x, y, z, n[0], n[1], n[2], CTX.geom.light);
-    }
-
-  }
+    }
 }
 
 void Draw_NonPlane_Surface(Surface * s)
 {
-  if(CTX.geom.surfaces) {
-    if(s->Typ == MSH_SURF_NURBS) {
-      if(CTX.geom.light) glEnable(GL_LIGHTING);
-      if(CTX.polygon_offset) glEnable(GL_POLYGON_OFFSET_FILL);
-      GLUnurbsObj *nurb;
-      nurb = gluNewNurbsRenderer();
+    if(CTX.geom.surfaces) {
+	if(s->Typ == MSH_SURF_NURBS) {
+	    if(CTX.geom.light) glEnable(GL_LIGHTING);
+	    if(CTX.polygon_offset) glEnable(GL_POLYGON_OFFSET_FILL);
+	    GLUnurbsObj *nurb;
+	    nurb = gluNewNurbsRenderer();
 #if defined(GLU_VERSION_1_3)
-      gluNurbsProperty(nurb, (GLenum) GLU_SAMPLING_TOLERANCE, 50.0);
-      gluNurbsProperty(nurb, (GLenum) GLU_DISPLAY_MODE, GLU_FILL);
+	    gluNurbsProperty(nurb, (GLenum) GLU_SAMPLING_TOLERANCE, 50.0);
+	    gluNurbsProperty(nurb, (GLenum) GLU_DISPLAY_MODE, GLU_FILL);
 #endif
-      gluBeginSurface(nurb);
-      gluNurbsSurface(nurb, s->Nu + s->OrderU + 1, s->ku,
-		      s->Nv + s->OrderV + 1, s->kv, 4, 4 * s->Nu, s->cp,
-		      s->OrderU + 1, s->OrderV + 1, GL_MAP2_VERTEX_4);
-      gluEndSurface(nurb);
-      gluDeleteNurbsRenderer(nurb);
-      glDisable(GL_POLYGON_OFFSET_FILL);
-      glDisable(GL_LIGHTING);
+	    gluBeginSurface(nurb);
+	    gluNurbsSurface(nurb, s->Nu + s->OrderU + 1, s->ku,
+			    s->Nv + s->OrderV + 1, s->kv, 4, 4 * s->Nu, s->cp,
+			    s->OrderU + 1, s->OrderV + 1, GL_MAP2_VERTEX_4);
+	    gluEndSurface(nurb);
+	    gluDeleteNurbsRenderer(nurb);
+	    glDisable(GL_POLYGON_OFFSET_FILL);
+	    glDisable(GL_LIGHTING);
+	}
+	else{
+	    glEnable(GL_LINE_STIPPLE);
+	    glLineStipple(1, 0x1F1F);
+	    gl2psEnable(GL2PS_LINE_STIPPLE);
+	    int N = 50;
+	    glBegin(GL_LINE_STRIP);
+	    for(int i = 0; i < N + 1; i++) {
+		double u = (double)i / (double)N;
+		Vertex v = InterpolateSurface(s, u, 0.5, 0, 0);
+		glVertex3d(v.Pos.X, v.Pos.Y, v.Pos.Z);
+	    }
+	    glEnd();
+	    glBegin(GL_LINE_STRIP);
+	    for(int i = 0; i < N + 1; i++) {
+		double u = (double)i / (double)N;
+		Vertex v = InterpolateSurface(s, 0.5, u, 0, 0);
+		glVertex3d(v.Pos.X, v.Pos.Y, v.Pos.Z);
+	    }
+	    glEnd();
+	    glDisable(GL_LINE_STIPPLE);
+	    gl2psDisable(GL2PS_LINE_STIPPLE);
+	}
+    }
+
+    if(CTX.geom.surfaces_num) {
+	Vertex v = InterpolateSurface(s, 0.5, 0.5, 0, 0);
+	char Num[100];
+	sprintf(Num, "%d", s->Num);
+	double offset = 0.3 * CTX.gl_fontsize * CTX.pixel_equiv_x;
+	glRasterPos3d(v.Pos.X + offset / CTX.s[0],
+		      v.Pos.Y + offset / CTX.s[1],
+		      v.Pos.Z + offset / CTX.s[2]);
+	Draw_String(Num);
+    }
+
+    if(CTX.geom.normals) {
+	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);
+	double n[3];
+	normal3points(v1.Pos.X, v1.Pos.Y, v1.Pos.Z, 
+		      v2.Pos.X, v2.Pos.Y, v2.Pos.Z, 
+		      v3.Pos.X, v3.Pos.Y, v3.Pos.Z, 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,
+		    v1.Pos.X, v1.Pos.Y, v1.Pos.Z, n[0], n[1], n[2],
+		    CTX.geom.light);
     }
-    else{
-      glEnable(GL_LINE_STIPPLE);
-      glLineStipple(1, 0x1F1F);
-      gl2psEnable(GL2PS_LINE_STIPPLE);
-      int N = 50;
-      glBegin(GL_LINE_STRIP);
-      for(int i = 0; i < N + 1; i++) {
-	double u = (double)i / (double)N;
-	Vertex v = InterpolateSurface(s, u, 0.5, 0, 0);
-	glVertex3d(v.Pos.X, v.Pos.Y, v.Pos.Z);
-      }
-      glEnd();
-      glBegin(GL_LINE_STRIP);
-      for(int i = 0; i < N + 1; i++) {
-	double u = (double)i / (double)N;
-	Vertex v = InterpolateSurface(s, 0.5, u, 0, 0);
-	glVertex3d(v.Pos.X, v.Pos.Y, v.Pos.Z);
-      }
-      glEnd();
-      glDisable(GL_LINE_STIPPLE);
-      gl2psDisable(GL2PS_LINE_STIPPLE);
-    }
-  }
-
-  if(CTX.geom.surfaces_num) {
-    Vertex v = InterpolateSurface(s, 0.5, 0.5, 0, 0);
-    char Num[100];
-    sprintf(Num, "%d", s->Num);
-    double offset = 0.3 * CTX.gl_fontsize * CTX.pixel_equiv_x;
-    glRasterPos3d(v.Pos.X + offset / CTX.s[0],
-                  v.Pos.Y + offset / CTX.s[1],
-                  v.Pos.Z + offset / CTX.s[2]);
-    Draw_String(Num);
-  }
-
-  if(CTX.geom.normals) {
-    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);
-    double n[3];
-    normal3points(v1.Pos.X, v1.Pos.Y, v1.Pos.Z, 
-		  v2.Pos.X, v2.Pos.Y, v2.Pos.Z, 
-		  v3.Pos.X, v3.Pos.Y, v3.Pos.Z, 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,
-		v1.Pos.X, v1.Pos.Y, v1.Pos.Z, n[0], n[1], n[2],
-		CTX.geom.light);
-  }
 }
 
 void Draw_Surface(void *a, void *b)
 {
-  Surface *s = *(Surface **) a;
-
-  if(!s || !s->Support || !(s->Visible & VIS_GEOM))
-    return;
-
-  if(CTX.render_mode == GMSH_SELECT) {
-    glLoadName(2);
-    glPushName(s->Num);
-  }
-
-  if(s->ipar[4]) {
-    glLineWidth(CTX.geom.line_sel_width / 2.);
-    gl2psLineWidth(CTX.geom.line_sel_width / 2. *
-		   CTX.print.eps_line_width_factor);
-    glColor4ubv((GLubyte *) & CTX.color.geom.surface_sel);
-  }
-  else {
-    glLineWidth(CTX.geom.line_width / 2.);
-    gl2psLineWidth(CTX.geom.line_width / 2. * CTX.print.eps_line_width_factor);
-    glColor4ubv((GLubyte *) & CTX.color.geom.surface);
-  }
-
-  if(s->bds){
-    Draw_Polygonal_Surface(s);
-  }
-  else if(s->Typ == MSH_SURF_DISCRETE){
-    // do nothing
-  }
-  else if(s->Typ == MSH_SURF_PLAN){
-    Draw_Plane_Surface(s);
-  }
-  else{
-    Draw_NonPlane_Surface(s);
-  }
-
-  if(CTX.render_mode == GMSH_SELECT) {
-    glPopName();
-  }
+    Surface *s = *(Surface **) a;
+
+    if(!s || !s->Support || !(s->Visible & VIS_GEOM))
+	return;
+
+    if(CTX.render_mode == GMSH_SELECT) {
+	glLoadName(2);
+	glPushName(s->Num);
+    }
+
+    if(s->ipar[4]) {
+	glLineWidth(CTX.geom.line_sel_width / 2.);
+	gl2psLineWidth(CTX.geom.line_sel_width / 2. *
+		       CTX.print.eps_line_width_factor);
+	glColor4ubv((GLubyte *) & CTX.color.geom.surface_sel);
+    }
+    else {
+	glLineWidth(CTX.geom.line_width / 2.);
+	gl2psLineWidth(CTX.geom.line_width / 2. * CTX.print.eps_line_width_factor);
+	glColor4ubv((GLubyte *) & CTX.color.geom.surface);
+    }
+
+    if(s->bds){
+	Draw_Polygonal_Surface(s);
+    }
+    else if(s->Typ == MSH_SURF_DISCRETE){
+	// do nothing
+    }
+    else if(s->Typ == MSH_SURF_PLAN){
+	Draw_Plane_Surface(s);
+    }
+    else{
+	Draw_NonPlane_Surface(s);
+    }
+
+    if(CTX.render_mode == GMSH_SELECT) {
+	glPopName();
+    }
 }
 
 // Volumes
@@ -648,152 +642,152 @@ void DrawVolumes(Mesh * m)
 
 void Draw_Geom(Mesh * m)
 {
-  if(m->status == -1)
-    return;
-
-  if(CTX.geom.points || CTX.geom.points_num)
-    Tree_Action(m->Points, Draw_Geo_Point);
-  if(CTX.geom.lines || CTX.geom.lines_num || CTX.geom.tangents)
-    Tree_Action(m->Curves, Draw_Curve);
-  if(CTX.geom.surfaces || CTX.geom.surfaces_num || CTX.geom.normals)
-    Tree_Action(m->Surfaces, Draw_Surface);
-  if(CTX.geom.volumes || CTX.geom.volumes_num)
-    DrawVolumes(m);
+    if(m->status == -1)
+	return;
+
+    if(CTX.geom.points || CTX.geom.points_num)
+	Tree_Action(m->Points, Draw_Geo_Point);
+    if(CTX.geom.lines || CTX.geom.lines_num || CTX.geom.tangents)
+	Tree_Action(m->Curves, Draw_Curve);
+    if(CTX.geom.surfaces || CTX.geom.surfaces_num || CTX.geom.normals)
+	Tree_Action(m->Surfaces, Draw_Surface);
+    if(CTX.geom.volumes || CTX.geom.volumes_num)
+	DrawVolumes(m);
 }
 
 // Highlight routines
 
 void HighlightEntity(Vertex * v, Curve * c, Surface * s, int permanent)
 {
-  Curve *cc;
-  char Message[256], temp[256];
+    Curve *cc;
+    char Message[256], temp[256];
 
-  if(permanent){
-    // we want to draw incrementally (in-between to "Draw()" calls):
-    // we need to make sure that the opengl context is set correctly
-    SetOpenglContext();
-  }
-
-  if(v) {
-    if(permanent){
-      v->Frozen = 1;
-      Draw_Geo_Point(&v,NULL);
-    }
-    else{
-      Msg(STATUS1N, "Point %d {%.5g,%.5g,%.5g} (%.5g)", v->Num, v->Pos.X,
-	  v->Pos.Y, v->Pos.Z, v->lc);
-    }
-  }
-  else if(c) {
     if(permanent){
-      c->ipar[3] = 1;
-      Draw_Curve(&c,NULL);
-    }
-    else{
-      if(c->beg && c->end)
-	Msg(STATUS1N, "Curve %d {%d->%d}", c->Num, c->beg->Num, c->end->Num);
-      else
-	Msg(STATUS1N, "Curve %d", c->Num);
+	// we want to draw incrementally (in-between to "Draw()" calls):
+	// we need to make sure that the opengl context is set correctly
+	SetOpenglContext();
     }
-  }
-  else if(s) {
-    if(permanent){
-      s->ipar[4] = 1;
-      Draw_Surface(&s,NULL);
+
+    if(v) {
+	if(permanent){
+	    v->Frozen = 1;
+	    Draw_Geo_Point(&v,NULL);
+	}
+	else{
+	    Msg(STATUS1N, "Point %d {%.5g,%.5g,%.5g} (%.5g)", v->Num, v->Pos.X,
+		v->Pos.Y, v->Pos.Z, v->lc);
+	}
     }
-    else{
-      int nbg = List_Nbr(s->Generatrices);
-      if(nbg){
-	sprintf(Message, "Surface %d {", s->Num);
-	if(nbg < 10) {
-	  for(int i = 0; i < nbg; i++) {
-	    List_Read(s->Generatrices, i, &cc);
-	    if(!i)
-	      sprintf(temp, "%d", cc->Num);
+    else if(c) {
+	if(permanent){
+	    c->ipar[3] = 1;
+	    Draw_Curve(&c,NULL);
+	}
+	else{
+	    if(c->beg && c->end)
+		Msg(STATUS1N, "Curve %d {%d->%d}", c->Num, c->beg->Num, c->end->Num);
 	    else
-	      sprintf(temp, ",%d", cc->Num);
-	    strcat(Message, temp);
-	  }
+		Msg(STATUS1N, "Curve %d", c->Num);
 	}
-	else {
-	  strcat(Message, "...");
+    }
+    else if(s) {
+	if(permanent){
+	    s->ipar[4] = 1;
+	    Draw_Surface(&s,NULL);
 	}
-	strcat(Message, "}");
-	Msg(STATUS1N, Message);
-      }
-      else{
-	Msg(STATUS1N, "Surface %d", s->Num);
-      }
-    }
-  }
-  else{
-    if(!permanent)
-      Msg(STATUS1N, " ");
-  }
+	else{
+	    int nbg = List_Nbr(s->Generatrices);
+	    if(nbg){
+		sprintf(Message, "Surface %d {", s->Num);
+		if(nbg < 10) {
+		    for(int i = 0; i < nbg; i++) {
+			List_Read(s->Generatrices, i, &cc);
+			if(!i)
+			    sprintf(temp, "%d", cc->Num);
+			else
+			    sprintf(temp, ",%d", cc->Num);
+			strcat(Message, temp);
+		    }
+		}
+		else {
+		    strcat(Message, "...");
+		}
+		strcat(Message, "}");
+		Msg(STATUS1N, Message);
+	    }
+	    else{
+		Msg(STATUS1N, "Surface %d", s->Num);
+	    }
+	}
+    }
+    else{
+	if(!permanent)
+	    Msg(STATUS1N, " ");
+    }
 }
 
 void HighlightEntityNum(int v, int c, int s, int permanent)
 {
-  if(v) {
-    Vertex *pv = FindPoint(v, THEM);
-    if(pv)
-      HighlightEntity(pv, NULL, NULL, permanent);
-  }
-  if(c) {
-    Curve *pc = FindCurve(c, THEM);
-    if(pc)
-      HighlightEntity(NULL, pc, NULL, permanent);
-  }
-  if(s) {
-    Surface *ps = FindSurface(s, THEM);
-    if(ps)
-      HighlightEntity(NULL, NULL, ps, permanent);
-  }
+    if(v) {
+	Vertex *pv = FindPoint(v, THEM);
+	if(pv)
+	    HighlightEntity(pv, NULL, NULL, permanent);
+    }
+    if(c) {
+	Curve *pc = FindCurve(c, THEM);
+	if(pc)
+	    HighlightEntity(NULL, pc, NULL, permanent);
+    }
+    if(s) {
+	Surface *ps = FindSurface(s, THEM);
+	if(ps)
+	    HighlightEntity(NULL, NULL, ps, permanent);
+    }
 }
 
 void ZeroHighlightPoint(void *a, void *b)
 {
-  Vertex *v;
-  v = *(Vertex **) a;
-  v->Frozen = 0;
+    Vertex *v;
+    v = *(Vertex **) a;
+    v->Frozen = 0;
 }
 
 void ZeroHighlightCurve(void *a, void *b)
 {
-  Curve *c;
-  c = *(Curve **) a;
-  c->ipar[3] = 0;
+    Curve *c;
+    c = *(Curve **) a;
+    c->ipar[3] = 0;
 }
 
 void ZeroHighlightSurface(void *a, void *b)
 {
-  Surface *s;
-  s = *(Surface **) a;
-  s->ipar[4] = 0;
+    Surface *s;
+    s = *(Surface **) a;
+    s->ipar[4] = 0;
 }
 
 void ZeroHighlight(Mesh * m)
 {
-  Tree_Action(m->Points, ZeroHighlightPoint);
-  Tree_Action(m->Curves, ZeroHighlightCurve);
-  Tree_Action(m->Surfaces, ZeroHighlightSurface);
+    Tree_Action(m->Points, ZeroHighlightPoint);
+    Tree_Action(m->Curves, ZeroHighlightCurve);
+    Tree_Action(m->Surfaces, ZeroHighlightSurface);
 }
 
 void ZeroHighlightEntityNum(int v, int c, int s)
 {
-  if(v) {
-    Vertex *pv = FindPoint(v, THEM);
-    if(pv)
-      ZeroHighlightPoint(&pv, NULL);
-  }
-  if(c) {
-    Curve *pc = FindCurve(c, THEM);
-    if(pc)
-      ZeroHighlightCurve(&pc, NULL);
-  }
-  if(s) {
-    Surface *ps = FindSurface(s, THEM);
-    if(ps)
-      ZeroHighlightSurface(&ps, NULL);
-  }
+    if(v) {
+	Vertex *pv = FindPoint(v, THEM);
+	if(pv)
+	    ZeroHighlightPoint(&pv, NULL);
+    }
+    if(c) {
+	Curve *pc = FindCurve(c, THEM);
+	if(pc)
+	    ZeroHighlightCurve(&pc, NULL);
+    }
+    if(s) {
+	Surface *ps = FindSurface(s, THEM);
+	if(ps)
+	    ZeroHighlightSurface(&ps, NULL);
+    }
 }
diff --git a/Mesh/BDS.cpp b/Mesh/BDS.cpp
index 4ba79899f8..7df60c5e87 100644
--- a/Mesh/BDS.cpp
+++ b/Mesh/BDS.cpp
@@ -3,6 +3,8 @@
 #include <math.h>
 #include <stdio.h>
 #include "Numeric.h"
+#include "GmshMatrix.h"
+#include "EigSolve.h"
 
 /*
   (X-Xc)^2 = R^2
@@ -11,7 +13,28 @@
 
 */
 
+BDS_Vector::BDS_Vector (const BDS_Point &p2,const BDS_Point &p1)
+    : x(p2.X-p1.X),y(p2.Y-p1.Y),z(p2.Z-p1.Z)
+{    
+}
+
 
+BDS_Vector BDS_Point::N() const
+{
+    std::list<BDS_Triangle *> t;
+    getTriangles (t); 	
+    std::list<BDS_Triangle *>::iterator tit  = t.begin(); 	
+    std::list<BDS_Triangle *>::iterator tite =  t.end();
+    BDS_Vector SumN;
+    while (tit!=tite)
+    {
+	SumN += (*tit)->N();
+	++tit;
+    }
+    double NORM = sqrt(SumN*SumN);
+    SumN /= NORM;
+    return SumN;
+}
 
 BDS_Sphere :: BDS_Sphere( BDS_Point *p1, BDS_Point *p2, BDS_Point *p3, BDS_Point *p4)
 {
@@ -183,11 +206,11 @@ BDS_Plane::BDS_Plane (BDS_Point *p1, BDS_Point *p2, BDS_Point *p3)
 }
 
 
-void BDS_Point::getTriangles (std::list<BDS_Triangle *> &t)
+void BDS_Point::getTriangles (std::list<BDS_Triangle *> &t) const
 {
   t.clear ();
-  std::list<BDS_Edge*>::iterator it  = edges.begin();
-  std::list<BDS_Edge*>::iterator ite = edges.end();
+  std::list<BDS_Edge*>::const_iterator it  = edges.begin();
+  std::list<BDS_Edge*>::const_iterator ite = edges.end();
   while(it!=ite)
     {
       int NF = (*it)->numfaces();
@@ -342,6 +365,7 @@ void recur_tag ( BDS_Triangle *t , BDS_GeomEntity *g )
   if (!t->g)
     {
       t->g = g;
+      g->t.push_back(t);
       if ( ! t->e1->g && t->e1->numfaces() == 2)
 	{
 	  recur_tag (t->e1->otherFace (t) , g);
@@ -377,18 +401,15 @@ void BDS_Mesh :: reverseEngineerCAD ( )
 	{
 	    std::set<BDS_Point*,PointLessThan> pts;
 
-	    std::list<BDS_Triangle*>::iterator tit  = triangles.begin();
-	    std::list<BDS_Triangle*>::iterator tite = triangles.end();
+	    std::list<BDS_Triangle*>::iterator tit  = (*it)->t.begin();
+	    std::list<BDS_Triangle*>::iterator tite = (*it)->t.end();
 	    while (tit!=tite)
 	    {
-		if ((*tit)->g == (*it))
-		{
-		    BDS_Point *nod[3];
-		    (*tit)->getNodes (nod);
-		    pts.insert(nod[0]);
-		    pts.insert(nod[1]);
-		    pts.insert(nod[2]);
-		}
+		BDS_Point *nod[3];
+		(*tit)->getNodes (nod);
+		pts.insert(nod[0]);
+		pts.insert(nod[1]);
+		pts.insert(nod[2]);
 		tit++;
 	    }
 	    if(pts.size() > 3)
@@ -412,7 +433,14 @@ void BDS_Mesh :: reverseEngineerCAD ( )
 		    if (distmax < 1.e-6 * LC ) 
 		    {
 			(*it)->surf = plane;
-			printf("plane surface found %g\n",distmax); 
+//			printf("plane surface found %g\n",distmax); 
+			pit  = pts.begin();
+			while (pit!=pite)
+			{
+			    if ((*pit)->g->classif_degree == 2)
+				(*pit)->radius_of_curvature = 1.e22;
+			    pit++;
+			}
 		    }
 		    else
 		    { 
@@ -456,12 +484,100 @@ void BDS_Mesh :: reverseEngineerCAD ( )
     }
 }
 
+void BDS_Point :: compute_curvature ( )
+{
+  std::list<BDS_Triangle *> t; 	
+  getTriangles (t);
+
+//  printf("curvature using %d triangles\n",t.size());
+
+  if (t.size() > 4)
+  {
+      Double_Matrix M ( t.size() , 4 );
+      Double_Vector Nx ( t.size() );
+      Double_Vector Ny ( t.size() );
+      Double_Vector Nz ( t.size() );
+      Double_Vector Cx ( 4 );
+      Double_Vector Cy ( 4 );
+      Double_Vector Cz ( 4 );
+
+      std::list<BDS_Triangle *>::iterator tit  = t.begin(); 	
+      std::list<BDS_Triangle *>::iterator tite =  t.end();
+      int k = 0;
+      while (tit!=tite)
+      {
+	  const BDS_Vector cog = (*tit)->cog();
+	  M(k,0) = X-cog.x;
+	  M(k,1) = Y-cog.y;
+	  M(k,2) = Z-cog.z; 
+	  M(k,3) = 1.0;
+	  BDS_Vector N = (*tit)->N();
+	  Nx(k) = N.x;
+	  Ny(k) = N.y;
+	  Nz(k) = N.z;
+	  k++;
+	  ++tit;
+      }
+      M.least_squares (Nx,Cx);
+      M.least_squares (Ny,Cy);
+      M.least_squares (Nz,Cz);
+      
+      const double A[9] = { Cx(0),0.5*(Cx(1)+Cy(0)),  0.5*(Cx(2)+Cz(0)) ,
+			    0.5*(Cx(1)+Cy(0)), Cy(1), 0.5*(Cy(2)+Cz(1)) , 
+			    0.5*(Cx(2)+Cz(0)), 0.5*(Cy(2)+Cz(1)) ,Cz(2)};
+      
+      double v[9];
+      double wr[3],wi[3];
+      
+      EigSolve3x3 (A ,wr,wi,v);
+
+      if(wr[0]!=0.0)radius_of_curvature = fabs(1/wr[0]);
+//      printf(" curvature = %g %g %g R = %g\n",wr[0],wr[1],wr[2],radius_of_curvature);
+  }
+}
+  
+
 void BDS_Mesh :: classify ( double angle )
 {
 
-  printf("  classifying \n");
- 
+    printf("  classifying \n");
+    
     static BDS_GeomEntity EDGE_CLAS (0,1);
+
+    // clear everything
+    // pre classified meshes will fail to work, more 2 be done
+    { 
+	{
+	    std::set<BDS_Point*,PointLessThan>::iterator it  = points.begin();
+	    std::set<BDS_Point*,PointLessThan>::iterator ite = points.end();
+	    while (it != ite){ (*it)->g = 0; ++it;}
+	}
+
+	{
+	    std::set<BDS_Edge*, EdgeLessThan>::iterator it  = edges.begin();
+	    std::set<BDS_Edge*, EdgeLessThan>::iterator ite = edges.end();
+	    while (it != ite){ (*it)->g = 0; ++it;}
+	}
+	{
+	    std::list<BDS_Triangle*>::iterator it  = triangles.begin();
+	    std::list<BDS_Triangle*>::iterator ite = triangles.end();
+	    while (it!=ite){(*it)->g = 0;++it;}
+	}
+	geom.clear();
+    }
+
+
+    {
+	std::set<BDS_Point*,PointLessThan>::iterator it  = points.begin();
+	std::set<BDS_Point*,PointLessThan>::iterator ite = points.end();
+	while (it != ite)
+	{
+	    (*it)-> compute_curvature ( );
+	    ++it;
+	}	
+    }
+
+
     {
 	std::set<BDS_Edge*, EdgeLessThan>::iterator it  = edges.begin();
 	std::set<BDS_Edge*, EdgeLessThan>::iterator ite = edges.end();
@@ -472,19 +588,21 @@ void BDS_Mesh :: classify ( double angle )
 	    {
 		e.g = &EDGE_CLAS;		
 	    }
-
+	    
 	    else if (e.numfaces() == 2 && 
 		     e.faces(0)->g != e.faces(1)->g )
-	      {
+	    {
 		e.g = &EDGE_CLAS;
-	      }
-
+	    }
+	    
 	    else if (e.numfaces() == 2)
 	    {
 		BDS_Vector N0 = e.faces(0)->N();
 		BDS_Vector N1 = e.faces(1)->N();
 		double ag = N0.angle (N1);
-		if (fabs(ag) > angle)e.g = &EDGE_CLAS;
+		if (fabs(ag) > angle){
+		    e.g = &EDGE_CLAS;
+		}
 	    }
 	    else
 	    {
@@ -493,7 +611,8 @@ void BDS_Mesh :: classify ( double angle )
 	    ++it;
 	}
     }
-
+    
+/*
     {
       std::list<BDS_Triangle*>::iterator it  = triangles.begin();
       std::list<BDS_Triangle*>::iterator ite = triangles.end();
@@ -504,7 +623,10 @@ void BDS_Mesh :: classify ( double angle )
 	}
       geom.clear();
     }
+*/
 
+    printf("  classifying faces\n");
+  
     {
       int tag = 1;
       while (1)
@@ -527,7 +649,9 @@ void BDS_Mesh :: classify ( double angle )
 	  recur_tag ( start , g );
 	  tag++;
 	}
+      printf("  classifying edges (%d face tags found)\n",tag-1);
     }
+
     int edgetag = 1;
     {
 	std::map< std::pair<int,int> , int > edgetags;
@@ -539,20 +663,31 @@ void BDS_Mesh :: classify ( double angle )
 	    
 	    if (e.g)
 	    {	    
+		int MIN_FAC = 100000; 
+		int MAX_FAC = -100000; 
 		std::map< std::pair<int,int> , int >::iterator found;
 		BDS_GeomEntity *g;
 		if ( e.numfaces() == 1)
 		{
 		    found = edgetags.find (std::make_pair ( e.faces(0)->g->classif_tag,-1));
 		}
-		else if (e.numfaces() == 2 && e.faces(0)->g->classif_tag != e.faces(1)->g->classif_tag)
+		else if (e.numfaces() == 2)// && e.faces(0)->g->classif_tag != e.faces(1)->g->classif_tag)
 		{
 		    if (e.faces(0)->g->classif_tag > e.faces(1)->g->classif_tag)
 			found = edgetags.find (std::make_pair ( e.faces(1)->g->classif_tag,e.faces(0)->g->classif_tag));
 		    else
 			found = edgetags.find (std::make_pair ( e.faces(0)->g->classif_tag,e.faces(1)->g->classif_tag));
 		}
-
+		else
+		{
+		    for (int K=0;K<e.numfaces();K++)
+		    {
+			if (MIN_FAC > e.faces(K)->g->classif_tag)MIN_FAC =  e.faces(K)->g->classif_tag;
+			if (MAX_FAC < e.faces(K)->g->classif_tag)MAX_FAC =  e.faces(K)->g->classif_tag;
+			found = edgetags.find (std::make_pair ( MIN_FAC,MAX_FAC ) );
+		    }
+		}
+		
 		if (e.g)
 		{
 		    if (found == edgetags.end())
@@ -572,6 +707,11 @@ void BDS_Mesh :: classify ( double angle )
 				edgetags[std::make_pair ( e.faces(0)->g->classif_tag,e.faces(1)->g->classif_tag)] 
 				    = edgetag;
 			}
+			else
+			{
+			  edgetags[std::make_pair ( MIN_FAC,MAX_FAC) ]
+				    = edgetag;  
+			}
 			edgetag++;
 		    }
 		    else
@@ -579,15 +719,20 @@ void BDS_Mesh :: classify ( double angle )
 			g = get_geom(found->second,1);
 		    }
 		    e.g = g;
+		    g->e.push_back(&e);
 		}
 	    }
 	    else
 	    {
 		e.g = e.faces(0)->g;
+		e.g->e.push_back(&e);
 	    }	    
 	    ++it;
 	}
     }
+
+    printf("  classifying points\n");
+
     int vertextag = 1;
     {
 	std::set<BDS_Point*,PointLessThan>::iterator it  = points.begin();
@@ -625,37 +770,30 @@ void BDS_Mesh :: classify ( double angle )
 	std::set<BDS_Point*,PointLessThan>::iterator ite = points.end();
 	while (it != ite)
 	{
-	  if ((*it)->g->classif_degree > 1)
+	    if ((*it)->g->classif_degree > 1)
 	    {
-	      std::list<BDS_Triangle *> t; 	
-	      (*it)->getTriangles (t);
-	      std::list<BDS_Triangle *>::iterator tit  = t.begin(); 	
-	      std::list<BDS_Triangle *>::iterator tite =  t.end();
-	      BDS_Vector SumN;
-	      while (tit!=tite)
-		{
-		  SumN += (*tit)->N();
-		  ++tit;
-		}
-	      double max_angle = 0;
-	      double NORM = sqrt(SumN*SumN);
-	      SumN /= NORM;
-	      tit  = t.begin(); 	
-	      while (tit!=tite)
+		std::list<BDS_Triangle *> t; 	
+		(*it)->getTriangles (t);
+		BDS_Vector SumN  = (*it)->N();
+		std::list<BDS_Triangle *>::iterator tit  = t.begin(); 	
+		std::list<BDS_Triangle *>::iterator tite =  t.end();
+		double max_angle = 0;
+		while (tit!=tite)
 		{
-		  double ag = SumN.angle ((*tit)->N());
-		  if (fabs(ag) > max_angle) max_angle = fabs(ag);
-		  ++tit;
+		    double ag = SumN.angle ((*tit)->N());
+		    if (fabs(ag) > max_angle) max_angle = fabs(ag);
+		    ++tit;
 		}
-	      if (fabs(max_angle) > angle)
+		if (fabs(max_angle) > angle)
 		{
-		  add_geom (vertextag, 0);
+		    add_geom (vertextag, 0);
 		  (*it)->g = get_geom(vertextag++,0);
 		}
-	    }	    
-	  ++it;
+	    }
+	    ++it;
 	}	
     }
+    printf(" reverse engineering surfaces\n");
     reverseEngineerCAD ( ) ;
 
   printf("  end classifying %d edgetags %d vertextags\n",edgetag-1,vertextag-1);
@@ -1234,6 +1372,9 @@ bool BDS_Mesh ::split_edge ( BDS_Edge *e, double coord)
 				coord * p1->Y + (1-coord) * p2->Y, 
 				coord * p1->Z + (1-coord) * p2->Z);
 
+    mid->radius_of_curvature  =   
+	coord * p1->radius_of_curvature + (1-coord) * p2->radius_of_curvature;	
+
     // we should project 
     e->oppositeof (op);
     BDS_GeomEntity *g1=0,*g2=0,*ge=e->g;
@@ -1399,7 +1540,7 @@ bool BDS_Mesh ::swap_edge ( BDS_Edge *e)
     triangles.push_back(t2); 
     return true;
 }
-bool BDS_Mesh ::collapse_edge ( BDS_Edge *e, BDS_Point *p, const double eps)
+bool BDS_Mesh ::collapse_edge ( BDS_Edge *e, BDS_Point *p, const double eps, const double l)
 {
 
     if (e->numfaces() != 2)return false;
@@ -1439,25 +1580,29 @@ bool BDS_Mesh ::collapse_edge ( BDS_Edge *e, BDS_Point *p, const double eps)
 //	    print_face(t);
 	    if (t->e1 != e && t->e2 != e && t->e3 != e)
 	      {
-		double n1[3],n2[3];
+		BDS_Vector n1,n2;
  		BDS_Point *pts[3];
 		t->getNodes (pts); 
 		p->X = o->X;
 		p->Y = o->Y;
 		p->Z = o->Z;
 		double s_after = surface_triangle (pts[0],pts[1],pts[2]); 
-		normal_triangle (pts[0],pts[1],pts[2], n1); // normal after collapse
+		n1 = t->N();
 		p->X = X;
 		p->Y = Y;
 		p->Z = Z;
-		normal_triangle (pts[0],pts[1],pts[2], n2); // normal before collapse
+		n2 = t->N();
 		double s_before = surface_triangle (pts[0],pts[1],pts[2]); 
 		// normals should not be opposed or change too dramatically
 		// this does not concern the triangles with the small edge that
 		// are collapsed too
-		double ps = n1[0] * n2[0] + n1[1] * n2[1] + n1[2] * n2[2];
-		if ( ps < eps ) return false;
-		if (fabs (s_after - s_before) < 0.01 * fabs (s_after + s_before))return false; 
+		double angle = n1.angle(n2);
+		if (fabs(angle) > M_PI/2 )return false;
+		if ( e->length() > 0.1 *l && fabs(angle) > M_PI/4 ) return false;
+		if (s_after < 1.e-2 * s_before)
+		{
+		    return false; 
+		}
 		gs[nt] = t->g;
 		pt[0][nt]   = (pts[0] == p) ? o->iD : pts[0]->iD ;
 		pt[1][nt]   = (pts[1] == p) ? o->iD : pts[1]->iD ;
@@ -1517,6 +1662,85 @@ bool BDS_Mesh ::collapse_edge ( BDS_Edge *e, BDS_Point *p, const double eps)
     return true;
 }
 
+/*
+
+   t(123) 
+
+   p
+
+*/
+
+
+void project_point_on_a_list_of_triangles ( BDS_Point *p , 
+					    const std::list<BDS_Triangle*> &t,
+					    double &X, double &Y, double &Z)
+{
+    int p_classif = p->g->classif_tag;
+    BDS_Vector N = p->N();
+    std::list<BDS_Triangle *>::const_iterator it = t.begin();
+    std::list<BDS_Triangle *>::const_iterator ite = t.end() ;
+    double dist = 1.e22;
+    double XX = p->X;
+    double YY = p->Y;
+    double ZZ = p->Z;
+
+//    printf("looking at %d triangles\n",t.size());
+
+    while (it != ite)
+    { 
+	if ((*it)->g->classif_tag == p_classif && fabs(N.angle((*it)->N())) < (M_PI/6))
+	{
+	    BDS_Point *pts[3];
+	    (*it)->getNodes (pts); 
+	    double xp,yp,zp;
+	    proj_point_plane ( p->X,p->Y,p->Z,pts[0],pts[1],pts[2],xp,yp,zp);
+	    BDS_Point ppp (0,xp,yp,zp);
+	    double a1 = surface_triangle ( &ppp, pts[0],pts[1] );
+	    double a2 = surface_triangle ( &ppp, pts[1],pts[2] );
+	    double a3 = surface_triangle ( &ppp, pts[2],pts[0] );
+	    double a  = surface_triangle ( pts[0], pts[1],pts[2] );
+	    if ( fabs (a-a1-a2-a3) < 1.e-2 * a)
+	    {
+		double d = sqrt ((xp-X)*(xp-X)+(yp-Y)*(yp-Y)+(zp-Z)*(zp-Z));
+		if (d < dist )
+		{
+//		    printf("one found %g %g %g %g\n",a,a1,a2,a3);
+		    XX = xp; YY = yp; ZZ = zp;
+		    dist = d;
+		}
+	    }
+	}
+	++it;
+    }
+    X = XX;
+    Y = YY;
+    Z = ZZ;
+}
+
+bool BDS_Mesh ::smooth_point_b ( BDS_Point *p  )
+{
+    if (p->g && p->g->classif_degree <= 1)return false;
+    
+    std::list<BDS_Edge*>::iterator eit  = p->edges.begin(); 
+
+    double l_max  = 0;
+    BDS_Edge *e_max;
+
+    while (eit!=p->edges.end())
+    {
+	++eit;
+    }
+
+    if (p->g->surf)
+    {
+//	p->g->surf->projection ( X,Y,Z,p->X,p->Y,p->Z);
+//	printf("coucou\n");
+    }
+    else
+    {
+    }
+}
+
 bool BDS_Mesh ::smooth_point ( BDS_Point *p , BDS_Mesh *geom_mesh )
 {
 
@@ -1548,50 +1772,15 @@ bool BDS_Mesh ::smooth_point ( BDS_Point *p , BDS_Mesh *geom_mesh )
     }
     else
     {
-	std::list<BDS_Triangle *> t; 	
-	std::list<BDS_Triangle *>::iterator it ;
-	std::list<BDS_Triangle *>::iterator ite;
-	if (geom_mesh)
-	{
-	    it = geom_mesh->triangles.begin();
-	    ite = geom_mesh->triangles.end();
-	}
-	else
-	{
-	    p->getTriangles (t); 
-	    it = t.begin();	
-	    ite = t.end();
-	}
-	
-	double dist = 1.e22;
-	double XX = X,YY=Y,ZZ=Z;
-	
-	int p_classif = p->g->classif_tag;
-	
-	while (it != ite)
-	{ 
-	    if ((*it)->g->classif_tag == p_classif)
-	    {
-		BDS_Point *pts[3];
-		(*it)->getNodes (pts); 
-		double xp,yp,zp;
-		proj_point_plane ( X,Y,Z,pts[0],pts[1],pts[2],xp,yp,zp);
-		double d = sqrt ((xp-X)*(xp-X)+(yp-Y)*(yp-Y)+(zp-Z)*(zp-Z));
-		if (d < dist)
-		{
-		    XX = xp; YY = yp; ZZ = zp;
-		    dist = d;
-		}
-	    }
-	    ++it;
-	}
-	X = XX;
-	Y = YY;
-	Z = ZZ;
-	
+//	return false;
 	p->X = X;
 	p->Y = Y;
 	p->Z = Z;
+	std::list<BDS_Triangle *>t;
+	p->getTriangles (t);
+	project_point_on_a_list_of_triangles ( p , t, p->X,p->Y,p->Z);	
+	if (geom_mesh)
+	    project_point_on_a_list_of_triangles ( p , geom_mesh->triangles, p->X,p->Y,p->Z);
     }
     return true;
 }
@@ -1627,7 +1816,12 @@ int BDS_Mesh :: adapt_mesh ( double l, bool smooth, BDS_Mesh *geom_mesh)
 	      double ll = sqrt((op[0]->X-op[1]->X)*(op[0]->X-op[1]->X)+
 			       (op[0]->Y-op[1]->Y)*(op[0]->Y-op[1]->Y)+
 			       (op[0]->Z-op[1]->Z)*(op[0]->Z-op[1]->Z));
-	      if (!(*it)->deleted && (*it)->length() > l/0.7 && ll > 0.25 * l){
+	      double curv = 0.5 * (*it)->p1->radius_of_curvature + 
+		  0.5 * (*it)->p2->radius_of_curvature;
+	      double LLL = l;
+///	      if (l > .50 * curv ) LLL = .50*curv;
+
+	      if (!(*it)->deleted && (*it)->length() > LLL/0.7 && ll > 0.25 * LLL){
 		split_edge (*it, 0.5 );
 		nb_modif++;
 	      }
@@ -1654,9 +1848,22 @@ int BDS_Mesh :: adapt_mesh ( double l, bool smooth, BDS_Mesh *geom_mesh)
 	std::set<BDS_Edge*, EdgeLessThan>::iterator ite  = small_to_long.end();
 	while (it != ite)
 	{
-	    if (!(*it)->deleted && (*it)->length() < 0.7 * l ){
-		if (collapse_edge (*it, (*it)->p1, 0.1 ))
-		    nb_modif++;
+	    double curv = 0.5 * (*it)->p1->radius_of_curvature + 
+		0.5 * (*it)->p2->radius_of_curvature;
+	    double LLL = l;
+//	    if (l > .50 * curv ) LLL = .50*curv;
+
+	    if (!(*it)->deleted && (*it)->length() < 0.7 * LLL ){
+		if (nb_modif %2 )
+		{
+		    if (collapse_edge (*it, (*it)->p1, 0.1,LLL ))
+			nb_modif++;
+		}
+		else
+		{
+		    if (collapse_edge (*it, (*it)->p2, 0.1,LLL ))
+			nb_modif++;
+		}
 	    }
 	    ++it;
 	}
@@ -1738,6 +1945,7 @@ int BDS_Mesh :: adapt_mesh ( double l, bool smooth, BDS_Mesh *geom_mesh)
 
 BDS_Mesh::BDS_Mesh (const BDS_Mesh &other)
 {
+    MAXPOINTNUMBER = other.MAXPOINTNUMBER;
 
     for (std::set<BDS_GeomEntity*,GeomLessThan>::const_iterator it = other.geom.begin();
 	 it != other.geom.end();
@@ -1753,6 +1961,7 @@ BDS_Mesh::BDS_Mesh (const BDS_Mesh &other)
     {
 	BDS_Point *p =  add_point((*it)->iD,(*it)->X,(*it)->Y,(*it)->Z);
 	p->g = ((*it)->g)? get_geom  ((*it)->g->classif_tag,(*it)->g->classif_degree) : 0;
+	p->radius_of_curvature = (*it)->radius_of_curvature ;
     }
     for ( std::set<BDS_Edge*, EdgeLessThan>::const_iterator it  = other.edges.begin();
 	  it != other.edges.end();
diff --git a/Mesh/BDS.h b/Mesh/BDS.h
index 0ea17a2b6d..97c1a988c9 100644
--- a/Mesh/BDS.h
+++ b/Mesh/BDS.h
@@ -30,6 +30,9 @@ public:
     int classif_tag;
     int classif_degree;
 
+    std::list<BDS_Triangle *> t;
+    std::list<BDS_Edge *>     e;
+
     BDS_Surface *surf;
 
     inline bool operator <  ( const BDS_GeomEntity & other ) const
@@ -48,39 +51,6 @@ public:
 
 void print_face (BDS_Triangle *t);
 
-class BDS_Point
-{
-public:
-    int iD;
-    double X,Y,Z;
-    BDS_GeomEntity *g;
-    std::list<BDS_Edge*> edges;
-    inline bool operator <  ( const BDS_Point & other ) const
-	{
-	    return iD < other.iD;
-	}
-    inline void del (BDS_Edge *e)
-	{
-	    std::list<BDS_Edge*>::iterator it  = edges.begin();
-	    std::list<BDS_Edge*>::iterator ite = edges.end();
-	    while(it!=ite)
-	    {
-		if (*it == e) 
-		{
-		    edges.erase(it);
-		    break;
-		}
-		++it;
-	    }
-	}
-    void getTriangles (std::list<BDS_Triangle *> &t); 	
-
-    BDS_Point ( int id, double x=0, double y=0, double z=0 )
-    : iD(id),X(x),Y(y),Z(z),g(0)
-	{	    
-	}
-};
-
 class BDS_Vector
 {
 public:
@@ -141,11 +111,8 @@ public:
   {
     return (x*v.x+y*v.y+z*v.z);
   }
-  BDS_Vector (const BDS_Point &p2,const BDS_Point &p1)
-      : x(p2.X-p1.X),y(p2.Y-p1.Y),z(p2.Z-p1.Z)
-      {
-	  
-      }
+  BDS_Vector (const BDS_Point &p2,const BDS_Point &p1);
+
   BDS_Vector (double ix=0, double iy=0, double iz=0)
     //    : x(ix),(iy),z(iz)
   {
@@ -156,6 +123,44 @@ public:
 };
 
 
+class BDS_Point
+{
+public:
+    int iD;
+    double X,Y,Z,radius_of_curvature;
+    BDS_GeomEntity *g;
+    std::list<BDS_Edge*> edges;
+
+    BDS_Vector N() const;
+
+    inline bool operator <  ( const BDS_Point & other ) const
+	{
+	    return iD < other.iD;
+	}
+    inline void del (BDS_Edge *e)
+	{
+	    std::list<BDS_Edge*>::iterator it  = edges.begin();
+	    std::list<BDS_Edge*>::iterator ite = edges.end();
+	    while(it!=ite)
+	    {
+		if (*it == e) 
+		{
+		    edges.erase(it);
+		    break;
+		}
+		++it;
+	    }
+	}
+    void getTriangles (std::list<BDS_Triangle *> &t) const; 	
+
+    void compute_curvature ( );
+
+    BDS_Point ( int id, double x=0, double y=0, double z=0 )
+	: iD(id),X(x),Y(y),Z(z),radius_of_curvature(1.e22),g(0)
+	{	    
+	}
+};
+
 class BDS_Edge
 {
     std::vector <BDS_Triangle *> _faces;
@@ -242,6 +247,15 @@ public:
     BDS_Vector N() const ;
     BDS_GeomEntity *g;
 
+    inline BDS_Vector cog() const
+	{
+	    BDS_Point *n[3];
+	    getNodes (n);
+	    return BDS_Vector ((n[0]->X+n[1]->X+n[2]->X)/3.,
+			       (n[0]->Y+n[1]->Y+n[2]->Y)/3.,
+			       (n[0]->Z+n[1]->Z+n[2]->Z)/3.);
+	}
+
     inline void getNodes (BDS_Point *n[3]) const
 	{
 	  n[0] = e1->commonvertex (e3);
@@ -362,8 +376,9 @@ class BDS_Mesh
     BDS_Edge  *find_edge (BDS_Point *p1, BDS_Point *p2, BDS_Triangle *t)const;
     BDS_GeomEntity *get_geom  (int p1, int p2);
     bool swap_edge ( BDS_Edge *);
-    bool collapse_edge ( BDS_Edge *, BDS_Point*, const double eps);
-    bool smooth_point ( BDS_Point* , BDS_Mesh *geom = 0);
+    bool collapse_edge ( BDS_Edge *, BDS_Point*, const double eps, const double l);
+    bool smooth_point   ( BDS_Point* , BDS_Mesh *geom = 0);
+    bool smooth_point_b ( BDS_Point* );
     bool split_edge ( BDS_Edge *, double coord);
     void classify ( double angle);
     void reverseEngineerCAD ( ) ;
@@ -378,3 +393,5 @@ class BDS_Mesh
     void save_gmsh_format (const char *filename);
 };
 void normal_triangle (BDS_Point *p1, BDS_Point *p2, BDS_Point *p3, double c[3]);
+void project_point_on_a_list_of_triangles ( BDS_Point *p , const std::list<BDS_Triangle*> &t,
+					    double &X, double &Y, double &Z);	   
diff --git a/Mesh/DiscreteSurface.cpp b/Mesh/DiscreteSurface.cpp
index 80f2468eab..82d320df74 100644
--- a/Mesh/DiscreteSurface.cpp
+++ b/Mesh/DiscreteSurface.cpp
@@ -1,4 +1,4 @@
-// $Id: DiscreteSurface.cpp,v 1.15 2005-06-03 17:32:29 geuzaine Exp $
+// $Id: DiscreteSurface.cpp,v 1.16 2005-06-27 15:03:46 remacle Exp $
 //
 // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle
 //
@@ -63,6 +63,13 @@ void Mesh_To_BDS(Surface *s, BDS_Mesh *m)
 
 void BDS_To_Mesh(Mesh *m)
 {
+    Tree_Action(m->Surfaces, Free_Surface);
+    Tree_Action(m->Curves, Free_Curve);
+    Tree_Delete(m->Surfaces);
+    Tree_Delete(m->Curves);
+    m->Curves = Tree_Create(sizeof(Curve *), compareCurve);
+    m->Surfaces = Tree_Create(sizeof(Surface *), compareSurface);
+
     std::set<BDS_GeomEntity*,GeomLessThan>::iterator it  = m->bds->geom.begin(); 
     std::set<BDS_GeomEntity*,GeomLessThan>::iterator ite = m->bds->geom.end(); 
     
@@ -70,21 +77,30 @@ void BDS_To_Mesh(Mesh *m)
     {
 	if ((*it)->classif_degree ==2 )
 	{
-	    Surface *_Surf = Create_Surface((*it)->classif_tag, MSH_SURF_DISCRETE);	
+	    Surface *_Surf = 0; 
+	    _Surf = FindSurface((*it)->classif_tag, m);
+	    if (!_Surf) 
+		_Surf = Create_Surface((*it)->classif_tag, MSH_SURF_DISCRETE);	
 	    _Surf->bds = m->bds;
 	    End_Surface(_Surf);
 	    Tree_Add(m->Surfaces, &_Surf);
 	}
 	else if ((*it)->classif_degree ==1  )
 	{
-	    Curve *_c = Create_Curve((*it)->classif_tag, MSH_SEGM_DISCRETE, 1, NULL, NULL, -1, -1, 0., 1.);	
+	    Curve *_c = 0; 
+	    _c = FindCurve((*it)->classif_tag, m);
+	    if (!_c) 
+		_c = Create_Curve((*it)->classif_tag, MSH_SEGM_DISCRETE, 1, NULL, NULL, -1, -1, 0., 1.);	
 	    _c->bds = m->bds;
 	    End_Curve(_c);
 	    Tree_Add(m->Curves, &_c);
 	}
 	++it;
     }
-    printf ("%d surfaces\n",Tree_Nbr(m->Surfaces));
+
+    CTX.mesh.changed = 1;
+
+    printf ("%d surfaces %d curves\n",Tree_Nbr(m->Surfaces), Tree_Nbr(m->Curves) );
 
 }
 
diff --git a/Parser/OpenFile.cpp b/Parser/OpenFile.cpp
index 7d7856dfb8..9eced090e5 100644
--- a/Parser/OpenFile.cpp
+++ b/Parser/OpenFile.cpp
@@ -1,4 +1,4 @@
-// $Id: OpenFile.cpp,v 1.79 2005-05-16 00:50:11 geuzaine Exp $
+// $Id: OpenFile.cpp,v 1.80 2005-06-27 15:03:46 remacle Exp $
 //
 // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle
 //
@@ -293,6 +293,9 @@ int MergeProblem(char *name, int warn_if_missing)
       }
     THEM->bds->save_gmsh_format ( "1.msh" );
     THEM->bds->classify ( M_PI / 8 );
+#if defined(HAVE_FLTK)
+    WID->create_surface_mesh_wizard();
+#endif
     THEM->bds->save_gmsh_format ( "2.msh" );
     BDS_To_Mesh (THEM);
     SetBoundingBox();
-- 
GitLab