diff --git a/Common/CommandLine.cpp b/Common/CommandLine.cpp
index 506ddd80c79fa2282a85019e18108e8f94ad677b..830661872b89e05343ce86a55e215ced649f8a94 100644
--- a/Common/CommandLine.cpp
+++ b/Common/CommandLine.cpp
@@ -78,6 +78,7 @@ std::vector<std::pair<std::string, std::string> > GetUsage()
   s.push_back(mp("-order int",         "Set mesh order (1, ..., 5)"));
   s.push_back(mp("-optimize[_netgen]", "Optimize quality of tetrahedral elements"));
   s.push_back(mp("-optimize_ho",       "Optimize high order meshes"));
+  s.push_back(mp("-ho_[min,max,nlayers]", "High-order optimization parameters"));
   s.push_back(mp("-optimize_lloyd",    "Optimize 2D meshes using Lloyd algorithm"));
   s.push_back(mp("-microstructure",    "Generate polycrystal Voronoi geometry"));
   s.push_back(mp("-clscale float",     "Set global mesh element size scaling factor"));
@@ -445,13 +446,6 @@ void GetOptions(int argc, char *argv[])
         CTX::instance()->mesh.optimize = 1;
         i++;
       }
-      else if(!strcmp(argv[i] + 1, "bunin")) {
-        i++;
-        if(argv[i])
-          CTX::instance()->mesh.bunin = atoi(argv[i++]);
-        else
-          Msg::Fatal("Missing cavity size in bunin optimization");
-      }
       else if(!strcmp(argv[i] + 1, "optimize_netgen")) {
         CTX::instance()->mesh.optimizeNetgen = 1;
         i++;
@@ -461,24 +455,21 @@ void GetOptions(int argc, char *argv[])
         i++;
         opt_mesh_ho_optimize(0, GMSH_SET, 1);
       }
-      else if(!strcmp(argv[i] + 1, "ho_mindisto") ||
-              !strcmp(argv[i] + 1, "hoMindisto")) {
+      else if(!strcmp(argv[i] + 1, "ho_min")) {
         i++;
         if(argv[i])
-          opt_mesh_ho_mindisto(0, GMSH_SET, atof(argv[i++]));
+          opt_mesh_ho_threshold_min(0, GMSH_SET, atof(argv[i++]));
         else
           Msg::Fatal("Missing number");
       }
-      else if(!strcmp(argv[i] + 1, "ho_poisson") ||
-              !strcmp(argv[i] + 1, "hoElasticity")) {
+      else if(!strcmp(argv[i] + 1, "ho_max")) {
         i++;
         if(argv[i])
-          opt_mesh_ho_poisson(0, GMSH_SET, atof(argv[i++]));
+          opt_mesh_ho_threshold_max(0, GMSH_SET, atof(argv[i++]));
         else
           Msg::Fatal("Missing number");
       }
-      else if(!strcmp(argv[i] + 1, "ho_nlayers") ||
-              !strcmp(argv[i] + 1, "hoNlayers")) {
+      else if(!strcmp(argv[i] + 1, "ho_nlayers")) {
         i++;
         if(argv[i])
           opt_mesh_ho_nlayers(0, GMSH_SET, atoi(argv[i++]));
@@ -492,7 +483,14 @@ void GetOptions(int argc, char *argv[])
         else
           Msg::Fatal("Missing number of lloyd iterations");
       }
-      #if defined(HAVE_MESH)
+      else if(!strcmp(argv[i] + 1, "bunin")) {
+        i++;
+        if(argv[i])
+          CTX::instance()->mesh.bunin = atoi(argv[i++]);
+        else
+          Msg::Fatal("Missing cavity size in bunin optimization");
+      }
+#if defined(HAVE_MESH)
       else if(!strcmp(argv[i] + 1, "microstructure")) {
         i++;
         int j;
@@ -518,7 +516,7 @@ void GetOptions(int argc, char *argv[])
           vm2.correspondance(0.00001);
         }
       }
-      #endif
+#endif
       else if(!strcmp(argv[i] + 1, "nopopup")) {
         CTX::instance()->noPopup = 1;
         i++;
diff --git a/Common/Context.h b/Common/Context.h
index c41cdc3907c46e545ed4587ca004bab5de8821df..d1758cd94d3685744251431d64574c5810a9d480 100644
--- a/Common/Context.h
+++ b/Common/Context.h
@@ -41,9 +41,9 @@ struct contextMeshOptions {
   int remeshParam, remeshAlgo;
   int order, secondOrderLinear, secondOrderIncomplete;
   int secondOrderExperimental, meshOnlyVisible;
-  int hoOptimize, minCircPoints, minCurvPoints;
-  int smoothNLayers;
-  double smoothDistoThreshold, smoothPoissonRatio;
+  int minCircPoints, minCurvPoints;
+  int hoOptimize, hoNLayers;
+  double hoThresholdMin, hoThresholdMax, hoPoissonRatio;
   int saveAll, saveTri, saveGroupsOfNodes, binary, bdfFieldFormat, saveParametric;
   int smoothNormals, reverseAllNormals, zoneDefinition, clip;
   int saveElementTagType;
diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h
index 744de7d00cd0cadc914686d46e8fc11bbe1dd7ad..59bbfc296b5dfd795022f0d1531487826b9d88d7 100644
--- a/Common/DefaultOptions.h
+++ b/Common/DefaultOptions.h
@@ -757,7 +757,7 @@ StringXNumber GeometryOptions_Number[] = {
     "Display width of lines (in pixels)" },
 
   { F|O, "MatchGeomAndMesh" , opt_geometry_match_geom_and_mesh, 0 ,
-    "Matches geometries and meshes." },
+    "Matches geometries and meshes" },
 
   { F|O, "Normals" , opt_geometry_normals , 0. ,
     "Display size of normal vectors (in pixels)" },
@@ -879,7 +879,7 @@ StringXNumber MeshOptions_Number[] = {
     "Apply n barycentric smoothing passes to the cross field" },
 
   { F|O, "CgnsImportOrder" , opt_mesh_cgns_import_order , 1. ,
-   "Enable the creation of high-order mesh from CGNS structured meshes."
+   "Enable the creation of high-order mesh from CGNS structured meshes"
    "(1, 2, 4, 8, ...)" },
   { F|O, "ChacoArchitecture" , opt_mesh_partition_chaco_architecture, 1. ,
     "(Adv. Chaco): Parallel architecture topology (0=hypercube, 1-3=mesh "
@@ -964,10 +964,12 @@ StringXNumber MeshOptions_Number[] = {
   { F|O, "HighOrderOptimize" , opt_mesh_ho_optimize , 0.,
     "Optimize high order meshes?" },
   { F|0, "HighOrderPoissonRatio", opt_mesh_ho_poisson, 0.33,
-    "Poisson ratio of the material used in the elastic smoother for high order meshes."
+    "Poisson ratio of the material used in the elastic smoother for high order meshes"
     "Must be between -1.0 and 0.5, excluded"},
-  { F|O, "HighOrderSmoothingThreshold", opt_mesh_ho_mindisto, 0.5,
-    "Distorition threshold when choosing which high order element to optimize."},
+  { F|O, "HighOrderThresholdMin", opt_mesh_ho_threshold_min, 0.2,
+    "Minimum threshold for high order element optimization"},
+  { F|O, "HighOrderThresholdMax", opt_mesh_ho_threshold_max, 2.0,
+    "Maximum threshold for high order element optimization"},
 
   { F|O, "LabelSampling" , opt_mesh_label_sampling , 1. ,
     "Label sampling rate (display one label every `LabelSampling' elements)" },
diff --git a/Common/Options.cpp b/Common/Options.cpp
index 5e6e48f817c5dab0cb12097bb6417cceb3e39833..851da3d11f2c6b89cbe7bafb0ad8123e247178be 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -5605,15 +5605,22 @@ double opt_mesh_ho_optimize(OPT_ARGS_NUM)
 double opt_mesh_ho_nlayers(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX::instance()->mesh.smoothNLayers = (int)val;
-  return CTX::instance()->mesh.smoothNLayers;
+    CTX::instance()->mesh.hoNLayers = (int)val;
+  return CTX::instance()->mesh.hoNLayers;
 }
 
-double opt_mesh_ho_mindisto(OPT_ARGS_NUM)
+double opt_mesh_ho_threshold_min(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX::instance()->mesh.smoothDistoThreshold = val;
-  return CTX::instance()->mesh.smoothDistoThreshold;
+    CTX::instance()->mesh.hoThresholdMin = val;
+  return CTX::instance()->mesh.hoThresholdMin;
+}
+
+double opt_mesh_ho_threshold_max(OPT_ARGS_NUM)
+{
+  if(action & GMSH_SET)
+    CTX::instance()->mesh.hoThresholdMax = val;
+  return CTX::instance()->mesh.hoThresholdMax;
 }
 
 double opt_mesh_ho_poisson(OPT_ARGS_NUM)
@@ -5624,9 +5631,9 @@ double opt_mesh_ho_poisson(OPT_ARGS_NUM)
       ratio = -0.999;
     else if (ratio >= 0.5)
       ratio = 0.499;
-    CTX::instance()->mesh.smoothPoissonRatio = ratio;
+    CTX::instance()->mesh.hoPoissonRatio = ratio;
   }
-  return CTX::instance()->mesh.smoothPoissonRatio;
+  return CTX::instance()->mesh.hoPoissonRatio;
 }
 
 double opt_mesh_second_order_experimental(OPT_ARGS_NUM)
diff --git a/Common/Options.h b/Common/Options.h
index 3b156db98d78e7731e394de90d454ac1a2e80a4f..c4f8e3246e0df4f3f52ebba53e4bf11d4cfc9c55 100644
--- a/Common/Options.h
+++ b/Common/Options.h
@@ -448,7 +448,8 @@ double opt_mesh_multiple_passes(OPT_ARGS_NUM);
 double opt_mesh_order(OPT_ARGS_NUM);
 double opt_mesh_ho_optimize(OPT_ARGS_NUM);
 double opt_mesh_ho_nlayers(OPT_ARGS_NUM);
-double opt_mesh_ho_mindisto(OPT_ARGS_NUM);
+double opt_mesh_ho_threshold_min(OPT_ARGS_NUM);
+double opt_mesh_ho_threshold_max(OPT_ARGS_NUM);
 double opt_mesh_ho_poisson(OPT_ARGS_NUM);
 double opt_mesh_second_order_experimental(OPT_ARGS_NUM);
 double opt_mesh_second_order_linear(OPT_ARGS_NUM);
diff --git a/Mesh/Generator.cpp b/Mesh/Generator.cpp
index 45bc5e09e7773aa68ebe959e887c766a9fac4adf..1e2410e235862b468baa6476ec7b5feee4db3399 100644
--- a/Mesh/Generator.cpp
+++ b/Mesh/Generator.cpp
@@ -35,6 +35,11 @@
 #include "simple3D.h"
 #include "yamakawa.h"
 
+#if defined(HAVE_OPTHOM)
+#include "OptHomRun.h"
+#include "OptHomElastic.h"
+#endif
+
 #if defined(HAVE_POST)
 #include "PView.h"
 #include "PViewData.h"
@@ -746,6 +751,25 @@ void GenerateMesh(GModel *m, int ask)
     SetOrderN(m, CTX::instance()->mesh.order, CTX::instance()->mesh.secondOrderLinear,
               CTX::instance()->mesh.secondOrderIncomplete);
 
+  // Optimize high order elements
+  if(CTX::instance()->mesh.hoOptimize){
+#if defined(HAVE_OPTHOM)
+    if(CTX::instance()->mesh.hoOptimize < 0){
+      ElasticAnalogy(GModel::current(), CTX::instance()->mesh.hoThresholdMin, false);
+    }
+    else{
+      OptHomParameters p;
+      p.nbLayers = CTX::instance()->mesh.hoNLayers;
+      p.BARRIER_MIN = CTX::instance()->mesh.hoThresholdMin;
+      p.BARRIER_MAX = CTX::instance()->mesh.hoThresholdMax;
+      p.dim = GModel::current()->getDim();
+      HighOrderMeshOptimizer(GModel::current(), p);
+    }
+#else
+    Msg::Error("High-order mesh optimization requires the OPTHOM module");
+#endif
+  }
+
   Msg::Info("%d vertices %d elements",
             m->getNumMeshVertices(), m->getNumMeshElements());
 
diff --git a/contrib/HighOrderMeshOptimizer/OptHomElastic.cpp b/contrib/HighOrderMeshOptimizer/OptHomElastic.cpp
index 42fdd93daf32a1073a1759faeaf369d60addb76a..bac2a7a4020524881001358f36d782cf067e44cd 100644
--- a/contrib/HighOrderMeshOptimizer/OptHomElastic.cpp
+++ b/contrib/HighOrderMeshOptimizer/OptHomElastic.cpp
@@ -69,7 +69,7 @@ void ElasticAnalogy(GModel *m, double threshold, bool onlyVisible)
       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);
+      hot.applySmoothingTo(v, 1.e32, false);
     }
   }
   checkHighOrderTetrahedron("File volume Mesh", m, bad, worst);
@@ -190,8 +190,7 @@ double highOrderTools::applySmoothingTo(GFace *gf, double tres, bool mixed)
   std::vector<MElement*> v;
   v.insert(v.begin(), gf->triangles.begin(),gf->triangles.end());
   v.insert(v.begin(), gf->quadrangles.begin(),gf->quadrangles.end());
-  //  applySmoothingTo(v,gf);
-  return applySmoothingTo(v,tres, mixed);
+  return applySmoothingTo(v, tres, mixed);
 }
 
 void highOrderTools::ensureMinimumDistorsion (double threshold)
@@ -256,7 +255,7 @@ void highOrderTools::computeMetricInfo(GFace *gf,
   }
 }
 
-void highOrderTools::applySmoothingTo(std::vector<MElement*> & all, GFace *gf)
+void highOrderTools::applySmoothingTo(std::vector<MElement*> &all, GFace *gf)
 {
 #ifdef HAVE_TAUCS
   linearSystemCSRTaucs<double> *lsys = new linearSystemCSRTaucs<double>;
@@ -266,12 +265,12 @@ void highOrderTools::applySmoothingTo(std::vector<MElement*> & all, GFace *gf)
   // compute the straight sided positions of high order nodes that are
   // on the edges of the face in the UV plane
   dofManager<double> myAssembler(lsys);
-  elasticityTerm El(0, 1.0, CTX::instance()->mesh.smoothPoissonRatio, _tag);
+  elasticityTerm El(0, 1.0, CTX::instance()->mesh.hoPoissonRatio, _tag);
   std::vector<MElement*> layer, v;
   double minD;
-  getDistordedElements(all, CTX::instance()->mesh.smoothDistoThreshold, v, minD);
+  getDistordedElements(all, CTX::instance()->mesh.hoThresholdMin, v, minD);
   int numBad = v.size();
-  const int nbLayers = CTX::instance()->mesh.smoothNLayers;
+  const int nbLayers = CTX::instance()->mesh.hoNLayers;
   for (int i = 0; i < nbLayers; i++){
     addOneLayer(all, v, layer);
     v.insert(v.end(), layer.begin(), layer.end());
diff --git a/doc/texinfo/commandline.texi b/doc/texinfo/commandline.texi
index a39f2892468030962b13dd0d19b423b6925fcdca..89b2a301c15f37934a6ae0f8896a2d606d4fe02f 100644
--- a/doc/texinfo/commandline.texi
+++ b/doc/texinfo/commandline.texi
@@ -46,16 +46,12 @@ Select mesh algorithm (meshadapt, del2d, front2d, delquad, del3d, front3d, mmg3d
 Set number of mesh smoothing steps
 @item -order int
 Set mesh order (1, ..., 5)
-@item -hoOptimize
-Optimize high order meshes
-@item -hoMindisto float
-Min high-order element quality before optim (0.0->1.0)
-@item -hoNLayers int
-Number of high order element layers to optimize
-@item -hoElasticity float
-Poisson ration for elasticity analogy (nu in [-1.0,0.5])
 @item -optimize[_netgen]
 Optimize quality of tetrahedral elements
+@item -optimize_ho
+Optimize high order meshes
+@item -ho_[min,max,nlayers]
+High-order optimization parameters
 @item -optimize_lloyd
 Optimize 2D meshes using Lloyd algorithm
 @item -microstructure
diff --git a/doc/texinfo/opt_general.texi b/doc/texinfo/opt_general.texi
index 199508f4df741e62ea416f24bd88ce6b6a6b71db..396fbd4717b5ef6796f4eedde5bab727711f6653 100644
--- a/doc/texinfo/opt_general.texi
+++ b/doc/texinfo/opt_general.texi
@@ -569,6 +569,16 @@ Width (in pixels) of the graphic window@*
 Default value: @code{800}@*
 Saved in: @code{General.SessionFileName}
 
+@item General.HighOrderToolsPositionX
+Horizontal position (in pixels) of the upper left corner of the high order tools window@*
+Default value: @code{650}@*
+Saved in: @code{General.SessionFileName}
+
+@item General.HighOrderToolsPositionY
+Vertical position (in pixels) of the upper left corner of the high order tools window@*
+Default value: @code{150}@*
+Saved in: @code{General.SessionFileName}
+
 @item General.InitialModule
 Module launched on startup (0=automatic, 1=geometry, 2=mesh, 3=solver, 4=post-processing) @*
 Default value: @code{0}@*
diff --git a/doc/texinfo/opt_geometry.texi b/doc/texinfo/opt_geometry.texi
index 5cb2df48d7b2170d1b8fc2a7994a332c43f75100..8d8eb3b344b7e11453a79b2255d0ad90d3841474 100644
--- a/doc/texinfo/opt_geometry.texi
+++ b/doc/texinfo/opt_geometry.texi
@@ -85,7 +85,7 @@ Default value: @code{2}@*
 Saved in: @code{General.OptionsFileName}
 
 @item Geometry.MatchGeomAndMesh
-Matches geometries and meshes.@*
+Matches geometries and meshes@*
 Default value: @code{0}@*
 Saved in: @code{General.OptionsFileName}
 
diff --git a/doc/texinfo/opt_mesh.texi b/doc/texinfo/opt_mesh.texi
index af58d735fc65dcf0360a8ef2165ff7743e2e06c8..a493a99033335577f26e963477c4c80f8f08c0c6 100644
--- a/doc/texinfo/opt_mesh.texi
+++ b/doc/texinfo/opt_mesh.texi
@@ -55,7 +55,7 @@ Default value: @code{0}@*
 Saved in: @code{General.OptionsFileName}
 
 @item Mesh.CgnsImportOrder
-Enable the creation of high-order mesh from CGNS structured meshes.(1, 2, 4, 8, ...)@*
+Enable the creation of high-order mesh from CGNS structured meshes(1, 2, 4, 8, ...)@*
 Default value: @code{1}@*
 Saved in: @code{General.OptionsFileName}
 
@@ -215,23 +215,28 @@ Default value: @code{1}@*
 Saved in: @code{General.OptionsFileName}
 
 @item Mesh.HighOrderNumLayers
-Number of high order mesh elements to consider for optimization.@*
+Number of high order mesh elements to consider for optimization@*
 Default value: @code{3}@*
 Saved in: @code{-}
 
 @item Mesh.HighOrderOptimize
-Number of smoothing steps of internal edges for high order meshes@*
+Optimize high order meshes?@*
 Default value: @code{0}@*
 Saved in: @code{General.OptionsFileName}
 
 @item Mesh.HighOrderPoissonRatio
-Poisson ratio of the material used in the elastic smoother for high order meshes.Must be between -1.0 and 0.5, excluded.@*
+Poisson ratio of the material used in the elastic smoother for high order meshesMust be between -1.0 and 0.5, excluded@*
 Default value: @code{0.33}@*
 Saved in: @code{-}
 
-@item Mesh.HighOrderSmoothingThreshold
-Distorition threshold when choosing which high order element to optimize.@*
-Default value: @code{0.5}@*
+@item Mesh.HighOrderThresholdMin
+Minimum threshold for high order element optimization@*
+Default value: @code{0.2}@*
+Saved in: @code{General.OptionsFileName}
+
+@item Mesh.HighOrderThresholdMax
+Maximum threshold for high order element optimization@*
+Default value: @code{2}@*
 Saved in: @code{General.OptionsFileName}
 
 @item Mesh.LabelSampling