diff --git a/Common/Context.h b/Common/Context.h
index 39918459273b46f0f3300599f814d995accc10e5..856a0557e8b71c74aacbe7acda1058c646db4f0b 100644
--- a/Common/Context.h
+++ b/Common/Context.h
@@ -102,7 +102,7 @@ class CTX {
   int tooltips;
   // position and size of various windows in the GUI
   int menuPosition[2], glPosition[2], glSize[2], msgSize;
-  int optPosition[2], visPosition[2], clipPosition[2], manipPosition[2];
+  int optPosition[2], visPosition[2], hotPosition[2], clipPosition[2], manipPosition[2];
   int statPosition[2], ctxPosition[2], solverPosition[2], solverSize[2];
   int pluginPosition[2], pluginSize[2], fieldPosition[2], fieldSize[2];
   int fileChooserPosition[2];
diff --git a/Fltk/CMakeLists.txt b/Fltk/CMakeLists.txt
index d0910168d2a2b9d2ef7d758757afdbd2db04e394..930d9657cd253b4e5b7ed9165e14f431c0d6bb05 100644
--- a/Fltk/CMakeLists.txt
+++ b/Fltk/CMakeLists.txt
@@ -14,6 +14,7 @@ set(SRC
     pluginWindow.cpp
     statisticsWindow.cpp
     visibilityWindow.cpp
+    highOrderToolsWindow.cpp
     clippingWindow.cpp
     manipWindow.cpp
     contextWindow.cpp
diff --git a/Fltk/FlGui.cpp b/Fltk/FlGui.cpp
index 6d44efe0beb67cb0cb79086c62be763d27ea19e2..8c18de758f8798380c0a2dc0119135552a6340dd 100644
--- a/Fltk/FlGui.cpp
+++ b/Fltk/FlGui.cpp
@@ -25,6 +25,7 @@ typedef unsigned long intptr_t;
 #include "pluginWindow.h"
 #include "statisticsWindow.h"
 #include "visibilityWindow.h"
+#include "highOrderToolsWindow.h"
 #include "clippingWindow.h"
 #include "manipWindow.h"
 #include "contextWindow.h"
@@ -292,6 +293,7 @@ FlGui::FlGui(int argc, char **argv) : _openedThroughMacFinder(false)
   plugins = new pluginWindow(CTX::instance()->deltaFontSize);
   stats = new statisticsWindow(CTX::instance()->deltaFontSize);
   visibility = new visibilityWindow(CTX::instance()->deltaFontSize);
+  highordertools = new highOrderToolsWindow(CTX::instance()->deltaFontSize);
   clipping = new clippingWindow(CTX::instance()->deltaFontSize);
   manip = new manipWindow(CTX::instance()->deltaFontSize);
   geoContext = new geometryContextWindow(CTX::instance()->deltaFontSize);
@@ -831,6 +833,8 @@ void FlGui::storeCurrentWindowsInfo()
   CTX::instance()->statPosition[1] = stats->win->y();
   CTX::instance()->visPosition[0] = visibility->win->x();
   CTX::instance()->visPosition[1] = visibility->win->y();
+  CTX::instance()->hotPosition[0] = highordertools->win->x();
+  CTX::instance()->hotPosition[1] = highordertools->win->y();
   CTX::instance()->clipPosition[0] = clipping->win->x();
   CTX::instance()->clipPosition[1] = clipping->win->y();
   CTX::instance()->manipPosition[0] = manip->win->x();
@@ -877,6 +881,8 @@ void window_cb(Fl_Widget *w, void *data)
       FlGui::instance()->fields->win->iconize();
     if(FlGui::instance()->visibility->win->shown())
       FlGui::instance()->visibility->win->iconize();
+    if(FlGui::instance()->highordertools->win->shown())
+      FlGui::instance()->highordertools->win->iconize();
     if(FlGui::instance()->clipping->win->shown())
       FlGui::instance()->clipping->win->iconize();
     if(FlGui::instance()->manip->win->shown())
@@ -932,6 +938,8 @@ void window_cb(Fl_Widget *w, void *data)
 #endif
     if(FlGui::instance()->visibility->win->shown())
       FlGui::instance()->visibility->win->show();
+    if(FlGui::instance()->highordertools->win->shown())
+      FlGui::instance()->highordertools->win->show();
     if(FlGui::instance()->clipping->win->shown())
       FlGui::instance()->clipping->win->show();
     if(FlGui::instance()->manip->win->shown())
diff --git a/Fltk/FlGui.h b/Fltk/FlGui.h
index 3d0a99ee344b8b3d425a1214ceb69b0915800179..7e08c61aa99af07b241ab51eb657b5fe4a0661fb 100644
--- a/Fltk/FlGui.h
+++ b/Fltk/FlGui.h
@@ -26,6 +26,7 @@ class fieldWindow;
 class pluginWindow;
 class statisticsWindow;
 class visibilityWindow;
+class highOrderToolsWindow;
 class clippingWindow;
 class manipWindow;
 class geometryContextWindow;
@@ -58,6 +59,7 @@ class FlGui{
   pluginWindow *plugins;
   statisticsWindow *stats;
   visibilityWindow *visibility;
+  highOrderToolsWindow *highordertools;
   clippingWindow *clipping;
   manipWindow *manip;
   geometryContextWindow *geoContext;
diff --git a/Fltk/highOrderToolsWindow.cpp b/Fltk/highOrderToolsWindow.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..142b217e0175cab07112735f5af503953a146dc7
--- /dev/null
+++ b/Fltk/highOrderToolsWindow.cpp
@@ -0,0 +1,293 @@
+// Gmsh - Copyright (C) 1997-2012 C. Geuzaine, J.-F. Remacle
+//
+// See the LICENSE.txt file for license information. Please report all
+// bugs and problems to <gmsh@geuz.org>.
+
+#include "GmshConfig.h"
+#if !defined(HAVE_NO_STDINT_H)
+#include <stdint.h>
+#elif defined(HAVE_NO_INTPTR_T)
+typedef unsigned long intptr_t;
+#endif
+#include <string>
+#include <sstream>
+#include <map>
+#include <vector>
+#include <string.h>
+#include <FL/Fl_Tabs.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Return_Button.H>
+#include <FL/Fl_Value_Input.H>
+#include "GmshConfig.h"
+#include "FlGui.h"
+#include "drawContext.h"
+#include "highOrderToolsWindow.h"
+#include "paletteWindow.h"
+#include "contextWindow.h"
+#include "graphicWindow.h"
+#include "GmshDefines.h"
+#include "GmshMessage.h"
+#include "GModel.h"
+#include "MElement.h"
+#include "PView.h"
+#include "PViewData.h"
+#include "GeoStringInterface.h"
+#include "Options.h"
+#include "Context.h"
+#include "HighOrder.h"
+
+#if defined(HAVE_PARSER)
+#include "Parser.h"
+#endif
+
+static void highordertools_runp_cb(Fl_Widget *w, void *data)
+{
+  highOrderToolsWindow *o = FlGui::instance()->highordertools;
+  
+  int order = (int)o->value[0]->value();
+  bool linear = !(bool)o->butt[2]->value(); 
+  bool incomplete = (bool)o->butt[0]->value(); 
+  bool elastic = (bool)o->butt[3]->value(); 
+  double threshold = o->value[1]->value(); 
+  bool onlyVisible = (bool)o->butt[1]->value(); 
+  int nLayers = (int) o->value[2]->value(); 
+
+  SetOrderN(GModel::current(), order, linear, incomplete, onlyVisible);
+
+  CTX::instance()->mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
+  drawContext::global()->draw();
+ 
+}
+
+static void highordertools_runelas_cb(Fl_Widget *w, void *data)
+{
+  highOrderToolsWindow *o = FlGui::instance()->highordertools;
+  
+  int order = (int)o->value[0]->value();
+  bool linear = !(bool)o->butt[2]->value(); 
+  bool incomplete = (bool)o->butt[0]->value(); 
+  bool elastic = (bool)o->butt[3]->value(); 
+  double threshold = o->value[1]->value(); 
+  bool onlyVisible = (bool)o->butt[1]->value(); 
+  int nLayers = (int) o->value[2]->value(); 
+
+  if(elastic)ElasticAnalogy(GModel::current(), threshold, onlyVisible);
+
+  CTX::instance()->mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
+  drawContext::global()->draw();
+ 
+}
+
+highOrderToolsWindow::highOrderToolsWindow(int deltaFontSize)
+{
+  FL_NORMAL_SIZE -= deltaFontSize;
+
+  static int cols[5] = {2 * WB, BB, BB, 2 * BB, 0};
+  int width = cols[0] + cols[1] + cols[2] + cols[3] + 6 * WB;
+  int height = 23 * BH;
+
+  win = new paletteWindow
+    (width, height, CTX::instance()->nonModalWindows ? true : false, "High Order Tools");
+  win->box(GMSH_WINDOW_BOX);
+
+  //  Fl_Tabs *o = new Fl_Tabs
+  //    (WB, WB, width - 2 * WB, height - 3 * WB - BH);
+  //  {
+  //    Fl_Group *g = new Fl_Group
+  //      (WB, WB + BH, width - 2 * WB, height - 3 * WB - 2 * BH, "Check Validity");    
+  //    g->end();
+  //    Fl_Group::current()->resizable(g);
+  //  }
+  {
+    //    Fl_Group *g = new Fl_Group
+    //      (WB, WB + BH, width - 2 * WB, height - 3 * WB - 2 * BH, "Generate High Order Mesh");
+
+    //    int y = 3 * WB + BH;
+    int y = WB;
+    int x = 2*WB;
+
+    butt[1] = new Fl_Check_Button
+      (x,y, IW, BH, "Apply to visible entities only");
+    butt[1]->type(FL_TOGGLE_BUTTON);
+    butt[1]->value(1);
+
+    {
+      y += BH / 2;
+      Fl_Box* b = new Fl_Box(x, y + BH - WB, width - 4 * WB, 2);
+      b->box(FL_ENGRAVED_FRAME);
+      b->labeltype(FL_NO_LABEL);
+    }
+
+    {
+      y += BH;
+      Fl_Box *b = new Fl_Box
+	(x, y, width, BH, "Generate high order nodes");
+      b->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
+    }
+
+    y += BH;
+
+    value[0] = new Fl_Value_Input
+      (x,y, IW, BH, "Polynomial Order");
+    value[0]->minimum(1);
+    value[0]->maximum(10);
+    value[0]->step(1);
+    value[0]->align(FL_ALIGN_RIGHT);
+    value[0]->value(1);
+
+    y += BH;
+
+    butt[0] = new Fl_Check_Button
+      (x,y, IW, BH, "Use Incomplete Elements");
+    butt[0]->type(FL_TOGGLE_BUTTON);
+    butt[0]->value(0);
+
+    y += BH;
+
+
+    butt[2] = new Fl_Check_Button
+      (x,y, IW, BH, "Generate curvilinear elements");
+    butt[2]->type(FL_TOGGLE_BUTTON);
+    butt[2]->value(1);
+
+    y += 1.2*BH;
+    push[0] = new Fl_Button
+      (x, y, (int)(1.2*BB), BH, "Apply");
+    push[0]->callback(highordertools_runp_cb);
+
+
+  //   g->end();
+  //   Fl_Group::current()->resizable(g);
+  // }
+  // {
+  //   Fl_Group *g = new Fl_Group
+  //     (WB, WB + BH, width - 2 * WB, height - 3 * WB - 2 * BH, "Optimize");
+
+
+    {
+      y += BH / 2;
+      Fl_Box* b = new Fl_Box(x, y + BH - WB, width - 4 * WB, 2);
+      b->box(FL_ENGRAVED_FRAME);
+      b->labeltype(FL_NO_LABEL);
+    }
+
+    {
+      y += BH;
+      Fl_Box *b = new Fl_Box
+	(x, y, width, BH, "Optimization");
+      b->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
+    }
+    {
+      y += BH;
+      
+      value[1] = new Fl_Value_Input
+	(x,y, IW, BH, "Distorsion threshold");
+      value[1]->minimum(0);
+      value[1]->maximum(1);
+      value[1]->step(.01);
+      value[1]->align(FL_ALIGN_RIGHT);
+      value[1]->value(0.1);
+      
+      y += 1.2*BH;
+      value[2] = new Fl_Value_Input
+	(x,y, IW, BH, "Number of Layers");
+      value[2]->minimum(1);
+      value[2]->maximum(20);
+      value[2]->step(1);
+      value[2]->align(FL_ALIGN_RIGHT);
+      value[2]->value(3);
+    }
+    {
+      y += BH;
+      butt[3] = new Fl_Check_Button
+	(x,y, IW, BH, "Relocate mesh vertices through Elastic Analogy");
+      butt[3]->type(FL_TOGGLE_BUTTON);
+      butt[3]->value(0);
+
+    }
+    {
+      y += BH;
+      butt[4] = new Fl_Check_Button
+	(x,y, IW, BH, "Use Optimization for relocating mesh vertices");
+      butt[4]->type(FL_TOGGLE_BUTTON);
+      butt[4]->value(0);
+
+      static Fl_Menu_Item menu_opti[] = {
+        {"IpOpt", 0, 0, 0},
+        {"LBFGS", 0, 0, 0},
+        {"Conjugate Gradients", 0, 0, 0},
+        {0}
+      };
+
+      static Fl_Menu_Item menu_objective[] = {
+        {"Log Barriers", 0, 0, 0},
+        {"Polynomial", 0, 0, 0},
+        {0}
+      };
+
+      y += BH;
+      choice[0] = new Fl_Choice
+        (x,y, IW, BH, "Optimization Package");
+      choice[0]->menu(menu_opti);
+      choice[0]->align(FL_ALIGN_RIGHT);
+
+      y += BH;
+      choice[0] = new Fl_Choice
+        (x,y, IW, BH, "Objective Function");
+      choice[0]->menu(menu_objective);
+      choice[0]->align(FL_ALIGN_RIGHT);
+
+      y += 1.2*BH;
+      value[3] = new Fl_Value_Input
+	(x,y, IW, BH, "Maximum nb. of Iterations");
+      value[3]->minimum(1);
+      value[3]->maximum(10000);
+      value[3]->step(10);
+      value[3]->align(FL_ALIGN_RIGHT);
+      value[3]->value(300);
+
+      y += 1.2*BH;
+      value[4] = new Fl_Value_Input
+	(x,y, IW, BH, "Tolerance");
+      value[4]->minimum(1.e-12);
+      value[4]->maximum(0.1);
+      value[4]->step(1.e-5);
+      value[4]->align(FL_ALIGN_RIGHT);
+      value[4]->value(1.e-4);
+      
+      y += 1.2*BH;
+      push[0] = new Fl_Button
+	(x, y, (int)(1.2*BB), BH, "Apply");
+      push[0]->callback(highordertools_runelas_cb);
+      
+
+    }
+    
+
+    //    g->end();    
+    //    Fl_Group::current()->resizable(g);
+  }
+
+  //  win->resizable(o);
+  win->position(CTX::instance()->hotPosition[0], CTX::instance()->hotPosition[1]);
+  win->end();
+  FL_NORMAL_SIZE += deltaFontSize;
+}
+
+void highOrderToolsWindow::show(bool redrawOnly)
+{
+  if(win->shown() && redrawOnly)
+    win->redraw();
+  else
+    win->show();
+}
+void highordertools_cb(Fl_Widget *w, void *data)
+{
+  // get the visibility info from the model, and update the browser
+  // accordingly
+  const char *str = (const char*)data;
+  if(str && !strcmp(str, "redraw_only"))
+    FlGui::instance()->highordertools->show(true);
+  else
+    FlGui::instance()->highordertools->show(false);
+}
diff --git a/Fltk/highOrderToolsWindow.h b/Fltk/highOrderToolsWindow.h
new file mode 100644
index 0000000000000000000000000000000000000000..9a1506dd107269060e9a3c925f367a457b866b79
--- /dev/null
+++ b/Fltk/highOrderToolsWindow.h
@@ -0,0 +1,32 @@
+// Gmsh - Copyright (C) 1997-2012 C. Geuzaine, J.-F. Remacle
+//
+// See the LICENSE.txt file for license information. Please report all
+// bugs and problems to <gmsh@geuz.org>.
+
+#ifndef _HIGHORDERTOOLS_WINDOW_H_
+#define _HIGHORDERTOOLS_WINDOW_H_
+
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Choice.H>
+#include <FL/Fl_Browser.H>
+#include <FL/Fl_Multi_Browser.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Check_Button.H>
+#include <FL/Fl_Input.H>
+#include "GmshConfig.h"
+
+class highOrderToolsWindow{
+ public:
+  Fl_Window *win;
+  Fl_Check_Button *butt[20];
+  Fl_Value_Input *value[20];
+  Fl_Choice *choice[20];
+  Fl_Button *push[20];
+ public:
+  highOrderToolsWindow(int deltaFontSize=0);
+  void show(bool redrawOnly);
+};
+
+void highordertools_cb(Fl_Widget *w, void *data);
+
+#endif
diff --git a/Fltk/menuWindow.cpp b/Fltk/menuWindow.cpp
index 21609da8ef517f6cf3bdadbb1f2465006a2b4403..bd6cd213fee29ab3abf03beb4d35e998e9904009 100644
--- a/Fltk/menuWindow.cpp
+++ b/Fltk/menuWindow.cpp
@@ -26,6 +26,7 @@ typedef unsigned long intptr_t;
 #include "statisticsWindow.h"
 #include "contextWindow.h"
 #include "visibilityWindow.h"
+#include "highOrderToolsWindow.h"
 #include "clippingWindow.h"
 #include "manipWindow.h"
 #include "fieldWindow.h"
@@ -2369,6 +2370,7 @@ static Fl_Menu_Item bar_table[] = {
     {"&Options",         FL_CTRL+FL_SHIFT+'n', (Fl_Callback *)options_cb, 0},
     {"Pl&ugins",         FL_CTRL+FL_SHIFT+'u', (Fl_Callback *)plugin_cb, (void*)(-1)},
     {"&Visibility",      FL_CTRL+FL_SHIFT+'v', (Fl_Callback *)visibility_cb, 0},
+    {"&High Order Tools", FL_CTRL+FL_SHIFT+'h', (Fl_Callback *)highordertools_cb, 0},
     {"&Clipping",        FL_CTRL+FL_SHIFT+'c', (Fl_Callback *)clip_cb, 0},
     {"&Manipulator",     FL_CTRL+FL_SHIFT+'m', (Fl_Callback *)manip_cb, 0},
 #if defined(HAVE_ONELAB)
@@ -2437,6 +2439,7 @@ static Fl_Menu_Item sysbar_table[] = {
     {"Options",         FL_META+FL_SHIFT+'n', (Fl_Callback *)options_cb, 0},
     {"Plugins",         FL_META+FL_SHIFT+'u', (Fl_Callback *)plugin_cb, (void*)(-1)},
     {"Visibility",      FL_META+FL_SHIFT+'v', (Fl_Callback *)visibility_cb, 0},
+    {"&High Order Tools", FL_META+FL_SHIFT+'h', (Fl_Callback *)highordertools_cb, 0},
     {"Clipping",        FL_META+FL_SHIFT+'c', (Fl_Callback *)clip_cb, 0},
     {"Manipulator",     FL_META+FL_SHIFT+'m', (Fl_Callback *)manip_cb, 0},
 #if defined(HAVE_ONELAB)
diff --git a/Mesh/HighOrder.cpp b/Mesh/HighOrder.cpp
index 82015f3824dd265cc7b02795f6524d1ced2429ee..26fb4a802bf7e4ac9eb001157ca9a67a8b08dbe4 100644
--- a/Mesh/HighOrder.cpp
+++ b/Mesh/HighOrder.cpp
@@ -121,7 +121,7 @@ static bool computeEquidistantParameters0(GEdge *ge, double u0, double uN, int N
   return false;
 }
 // 1 = geodesics
-static int method_for_computing_intermediary_points = 1;
+static int method_for_computing_intermediary_points = 0;
 static bool computeEquidistantParameters(GEdge *ge, double u0, double uN, int N,
                                          double *u, double underRelax){
   if (method_for_computing_intermediary_points == 0) // use linear abscissa
@@ -534,7 +534,7 @@ static void reorientQuadPoints(std::vector<MVertex*> &vtcs, int orientation,
       start++;
     }
     else{
-      int i1,i2,i3,i4;
+      int i1(0),i2(0),i3(0),i4(0);
       if (!swap){
 	if      (orientation == 0){ i1 = 0; i2 = 1; i3 = 2; i4 = 3; }
 	else if (orientation == 1){ i1 = 3; i2 = 0; i3 = 1; i4 = 2; }
@@ -1051,8 +1051,9 @@ static void setHighOrder(GRegion *gr, edgeContainer &edgeVertices,
 }
 
 template<class T>
-static void setFirstOrder(GEntity *e, std::vector<T*> &elements)
+static void setFirstOrder(GEntity *e, std::vector<T*> &elements, bool onlyVisible)
 {
+  if (onlyVisible && !e->getVisibility())return;
   std::vector<T*> elements1;
   for(unsigned int i = 0; i < elements.size(); i++){
     T *ele = elements[i];
@@ -1067,8 +1068,9 @@ static void setFirstOrder(GEntity *e, std::vector<T*> &elements)
   e->deleteVertexArrays();
 }
 
-static void removeHighOrderVertices(GEntity *e)
+static void removeHighOrderVertices(GEntity *e, bool onlyVisible)
 {
+  if (onlyVisible && !e->getVisibility())return;
   std::vector<MVertex*> v1;
   for(unsigned int i = 0; i < e->mesh_vertices.size(); i++){
     if(e->mesh_vertices[i]->getPolynomialOrder() > 1)
@@ -1079,32 +1081,32 @@ static void removeHighOrderVertices(GEntity *e)
   e->mesh_vertices = v1;
 }
 
-void SetOrder1(GModel *m)
+void SetOrder1(GModel *m,  bool onlyVisible)
 {
   m->destroyMeshCaches();
 
   // replace all elements with first order elements
   for(GModel::eiter it = m->firstEdge(); it != m->lastEdge(); ++it){
-    setFirstOrder(*it, (*it)->lines);
+    setFirstOrder(*it, (*it)->lines, onlyVisible);
   }
   for(GModel::fiter it = m->firstFace(); it != m->lastFace(); ++it){
-    setFirstOrder(*it, (*it)->triangles);
-    setFirstOrder(*it, (*it)->quadrangles);
+    setFirstOrder(*it, (*it)->triangles, onlyVisible);
+    setFirstOrder(*it, (*it)->quadrangles, onlyVisible);
   }
   for(GModel::riter it = m->firstRegion(); it != m->lastRegion(); ++it){
-    setFirstOrder(*it, (*it)->tetrahedra);
-    setFirstOrder(*it, (*it)->hexahedra);
-    setFirstOrder(*it, (*it)->prisms);
-    setFirstOrder(*it, (*it)->pyramids);
+    setFirstOrder(*it, (*it)->tetrahedra, onlyVisible);
+    setFirstOrder(*it, (*it)->hexahedra, onlyVisible);
+    setFirstOrder(*it, (*it)->prisms, onlyVisible);
+    setFirstOrder(*it, (*it)->pyramids, onlyVisible);
   }
 
   // remove all high order vertices
   for(GModel::eiter it = m->firstEdge(); it != m->lastEdge(); ++it)
-    removeHighOrderVertices(*it);
+    removeHighOrderVertices(*it, onlyVisible);
   for(GModel::fiter it = m->firstFace(); it != m->lastFace(); ++it)
-    removeHighOrderVertices(*it);
+    removeHighOrderVertices(*it, onlyVisible);
   for(GModel::riter it = m->firstRegion(); it != m->lastRegion(); ++it)
-    removeHighOrderVertices(*it);
+    removeHighOrderVertices(*it, onlyVisible);
 }
 
 void checkHighOrderTriangles(const char* cc, GModel *m,
@@ -1232,7 +1234,43 @@ void printJacobians(GModel *m, const char *nm)
   fclose(f);
 }
 
-void SetOrderN(GModel *m, int order, bool linear, bool incomplete)
+void ElasticAnalogy ( GModel *m, double threshold, bool onlyVisible) {
+  
+  highOrderTools hot(m);
+  // now we smooth mesh the internal vertices of the faces
+  // we do that model face by model face
+  std::vector<MElement*> bad;
+  double worst;
+  checkHighOrderTriangles("Surface mesh", m, bad, worst);
+  {
+    for(GModel::fiter it = m->firstFace(); it != m->lastFace(); ++it) {
+      if (onlyVisible && !(*it)->getVisibility())continue;
+      std::vector<MElement*> v;
+      v.insert(v.begin(), (*it)->triangles.begin(), (*it)->triangles.end());
+      v.insert(v.end(), (*it)->quadrangles.begin(), (*it)->quadrangles.end());
+      hot.applySmoothingTo(v, (*it));
+    }
+  }
+  //    hot.ensureMinimumDistorsion(0.1);
+  checkHighOrderTriangles("Final surface mesh", m, bad, worst);
+
+  checkHighOrderTetrahedron("Volume Mesh", m, bad, worst);
+  {
+    for(GModel::riter it = m->firstRegion(); it != m->lastRegion(); ++it) {
+      if (onlyVisible && !(*it)->getVisibility())continue;
+      std::vector<MElement*> v;
+      v.insert(v.begin(), (*it)->tetrahedra.begin(), (*it)->tetrahedra.end());
+      v.insert(v.end(), (*it)->hexahedra.begin(), (*it)->hexahedra.end());
+      v.insert(v.end(), (*it)->prisms.begin(), (*it)->prisms.end());
+      hot.applySmoothingTo(v,1.e32,false);
+    }
+  }
+
+  // m->writeMSH("CORRECTED.msh");
+}
+
+
+void SetOrderN(GModel *m, int order, bool linear, bool incomplete, bool onlyVisible)
 {
   // replace all the elements in the mesh with second order elements
   // by creating unique vertices on the edges/faces of the mesh:
@@ -1249,6 +1287,8 @@ void SetOrderN(GModel *m, int order, bool linear, bool incomplete)
   //   edges (creating 8-node quads, 20-node hexas, etc., instead of
   //   9-node quads, 27-node hexas, etc.)
 
+  // - if onlyVisible is true, then only the visible entities will be curved.
+
   int nPts = order - 1;
 
   if (!linear)
@@ -1259,16 +1299,7 @@ void SetOrderN(GModel *m, int order, bool linear, bool incomplete)
   double t1 = Cpu();
 
   // first, make sure to remove any existsing second order vertices/elements
-  SetOrder1(m);
-
-  // m->writeMSH("BEFORE.msh");
-
-  /*
-  if(CTX::instance()->mesh.smoothInternalEdges){
-    displ2D = new highOrderSmoother(2);
-    displ3D = new highOrderSmoother(3);
-  }
-  */
+  SetOrder1(m, onlyVisible);
 
   // then create new second order vertices/elements
   edgeContainer edgeVertices;
@@ -1278,6 +1309,7 @@ void SetOrderN(GModel *m, int order, bool linear, bool incomplete)
   for(GModel::eiter it = m->firstEdge(); it != m->lastEdge(); ++it) {
     Msg::StatusBar(2, true, "Meshing curves order %d (%i/%i)...", order, counter, m->getNumEdges());
     counter++;
+    if (onlyVisible && !(*it)->getVisibility())continue;
     setHighOrder(*it, edgeVertices, linear, nPts);
   }
 
@@ -1285,6 +1317,7 @@ void SetOrderN(GModel *m, int order, bool linear, bool incomplete)
   for(GModel::fiter it = m->firstFace(); it != m->lastFace(); ++it) {
     Msg::StatusBar(2, true, "Meshing surfaces order %d (%i/%i)...", order, counter, m->getNumFaces());
     counter++;
+    if (onlyVisible && !(*it)->getVisibility())continue;
     setHighOrder(*it, edgeVertices, faceVertices, linear, incomplete, nPts);
   }
 
@@ -1298,39 +1331,22 @@ void SetOrderN(GModel *m, int order, bool linear, bool incomplete)
   // printJacobians(m, "smoothness_b.pos");
   // m->writeMSH("RAW.msh");
 
-  /*if (displ2D){
-    checkHighOrderTriangles("Before optimization", m, bad, worst);
-    for(GModel::fiter it = m->firstFace(); it != m->lastFace(); ++it)
-      displ2D->optimize(*it,edgeVertices,faceVertices);
-    checkHighOrderTriangles("After optimization", m, bad, worst);
-    }
-  */
-
   counter = 1;
   for(GModel::riter it = m->firstRegion(); it != m->lastRegion(); ++it) {
     Msg::StatusBar(2, true, "Meshing volumes order %d (%i/%i)...", order, counter, m->getNumRegions());
     counter++;
+    if (onlyVisible && !(*it)->getVisibility())continue;
     setHighOrder(*it, edgeVertices, faceVertices, linear, incomplete, nPts);
   }
 
-/*
-  // smooth the 3D regions
-  if (displ3D){
-    checkHighOrderTetrahedron("Before optimization", m, bad, worst);
-    for(GModel::riter it = m->firstRegion(); it != m->lastRegion(); ++it)
-      displ3D->smooth(*it);
-    checkHighOrderTetrahedron("After optimization", m, bad, worst);
-  }
-*/
-
   double t2 = Cpu();
 
   // printJacobians(m, "smoothness.pos");
-  // m->writeMSH("SMOOTHED.msh");
-  // FIXME !!
+
   checkHighOrderTriangles("Surface mesh", m, bad, worst);
   if (!linear && CTX::instance()->mesh.smoothInternalEdges){
     for(GModel::fiter it = m->firstFace(); it != m->lastFace(); ++it) {
+      if (onlyVisible && !(*it)->getVisibility())continue;
       std::vector<MElement*> v;
       v.insert(v.begin(), (*it)->triangles.begin(), (*it)->triangles.end());
       v.insert(v.end(), (*it)->quadrangles.begin(), (*it)->quadrangles.end());
@@ -1340,7 +1356,7 @@ void SetOrderN(GModel *m, int order, bool linear, bool incomplete)
     //    hot.ensureMinimumDistorsion(0.1);
     checkHighOrderTriangles("Final surface mesh", m, bad, worst);
   }
-
+  
   // m->writeMSH("CORRECTED.msh");
 
   Msg::StatusBar(2, true, "Done meshing order %d (%g s)", order, t2 - t1);
diff --git a/Mesh/HighOrder.h b/Mesh/HighOrder.h
index a0c0e1a068b130fa06b20f02db9bb0b2e054da7c..b1d09169f729c29628e94cfffde5b95ad7e13d71 100644
--- a/Mesh/HighOrder.h
+++ b/Mesh/HighOrder.h
@@ -19,8 +19,9 @@ typedef std::map<std::pair<MVertex*, MVertex*>, std::vector<MVertex*> > edgeCont
 // are the high order representation of the face
 typedef std::map<MFace, std::vector<MVertex*>, Less_Face> faceContainer;
 
-void SetOrder1(GModel *m);
-void SetOrderN(GModel *m, int order, bool linear=true, bool incomplete=false);
+void SetOrder1(GModel *m, bool onlyVisible = false);
+void SetOrderN(GModel *m, int order, bool linear=true, bool incomplete=false, bool onlyVisible = false);
+void ElasticAnalogy ( GModel *m, double threshold, bool onlyVisible);
 MTriangle* setHighOrder(MTriangle *t, GFace *gf, 
                         edgeContainer &edgeVertices, 
                         faceContainer &faceVertices, 
diff --git a/Mesh/highOrderTools.cpp b/Mesh/highOrderTools.cpp
index 28fcbfe3cd966bed4bfe46b46c33307c2799766f..71df3f6a7aceea9dfceff3a51e85c6c678b1e260 100644
--- a/Mesh/highOrderTools.cpp
+++ b/Mesh/highOrderTools.cpp
@@ -724,9 +724,7 @@ double highOrderTools::applySmoothingTo (std::vector<MElement*> &all,
     moveToStraightSidedLocation(all[i]);
   // apply the displacement
 
-  _gm->writeMSH("straightSided.msh");
-
-  printf("argh\n");
+  // _gm->writeMSH("straightSided.msh");
 
   char sm[] = "sm.msh";
   double percentage_of_what_is_left = apply_incremental_displacement (1., all, mixed, -100000000, sm, all);
diff --git a/benchmarks/2d/conge.geo b/benchmarks/2d/conge.geo
index b61af396b53d9e75a2fc658bddd30b61687f766c..05eb0a27cf98e14610763b2e8da6da63cd499566 100644
--- a/benchmarks/2d/conge.geo
+++ b/benchmarks/2d/conge.geo
@@ -69,7 +69,7 @@ Circle(19) = {25,23,22};
 Line(20) = {21,22};
 
 Line Loop(21) = {17,-15,18,19,-20,16};
-//Plane Surface(22) = {21};
+Plane Surface(22) = {21};
 Line Loop(23) = {11,-12,13,14,1,2,-3,4,5,6,7,-8,9,10};
 Plane Surface(24) = {23,21};
 
@@ -78,5 +78,5 @@ Physical Line(25) = {12,13,14,15,16,17,18,19,20,10};
 Physical Surface(26) = {24};
 Physical Line(27) = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 14, 13, 12, 11};
 Physical Line(28) = {17, 16, 20, 19, 18, 15};
-Recombine Surface {24, 22};
+//Recombine Surface {24, 22};
 Mesh.RecombinationAlgorithm=1;
\ No newline at end of file