diff --git a/Common/CommandLine.cpp b/Common/CommandLine.cpp index d22d86a2aa2e42a90e5fb212ffd8946318ab8f39..92b6e6ea8fa1b1556cdee7bcd3ad0083d6dcb609 100644 --- a/Common/CommandLine.cpp +++ b/Common/CommandLine.cpp @@ -486,7 +486,9 @@ void GetOptions(int argc, char *argv[]) else if(!strcmp(argv[i] + 1, "algo")) { i++; if(argv[i]) { - if(!strncmp(argv[i], "meshadapt", 9) || !strncmp(argv[i], "iso", 3)) + if(!strncmp(argv[i], "auto", 4)) + CTX::instance()->mesh.algo2d = ALGO_2D_AUTO; + else if(!strncmp(argv[i], "meshadapt", 9) || !strncmp(argv[i], "iso", 3)) CTX::instance()->mesh.algo2d = ALGO_2D_MESHADAPT; else if(!strncmp(argv[i], "bds", 3)) CTX::instance()->mesh.algo2d = ALGO_2D_MESHADAPT_OLD; @@ -497,7 +499,7 @@ void GetOptions(int argc, char *argv[]) else if(!strncmp(argv[i], "bamg",4)) CTX::instance()->mesh.algo2d = ALGO_2D_BAMG; else if(!strncmp(argv[i], "del3d", 5) || !strncmp(argv[i], "tetgen", 6)) - CTX::instance()->mesh.algo2d = ALGO_3D_DELAUNAY; + CTX::instance()->mesh.algo3d = ALGO_3D_DELAUNAY; else if(!strncmp(argv[i], "front3d", 7) || !strncmp(argv[i], "netgen", 6)) CTX::instance()->mesh.algo3d = ALGO_3D_FRONTAL; else diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h index 36e2fc450fb25d7f78b3dfc72180e0a3acd2e109..54c2ded3d0e77cacc0a209dcabdce70f10d07252 100644 --- a/Common/DefaultOptions.h +++ b/Common/DefaultOptions.h @@ -1004,8 +1004,8 @@ StringXNumber GeometryOptions_Number[] = { } ; StringXNumber MeshOptions_Number[] = { - { F|O, "Algorithm" , opt_mesh_algo2d , ALGO_2D_MESHADAPT , - "2D mesh algorithm (1=MeshAdapt, 5=Delaunay, 6=Frontal, 7=bamg)" }, + { F|O, "Algorithm" , opt_mesh_algo2d , ALGO_2D_AUTO , + "2D mesh algorithm (1=MeshAdapt, 2=Automatic, 5=Delaunay, 6=Frontal, 7=bamg)" }, { F|O, "Algorithm3D" , opt_mesh_algo3d , #if defined(HAVE_TETGEN) ALGO_3D_DELAUNAY , diff --git a/Common/GmshDefines.h b/Common/GmshDefines.h index b3d0697fb485278350306ae01c3c20191293c596..bcf4835fc9a27f912f570250d0f7269730906254 100644 --- a/Common/GmshDefines.h +++ b/Common/GmshDefines.h @@ -163,6 +163,7 @@ // 2D meshing algorithms (numbers should not be changed) #define ALGO_2D_MESHADAPT 1 +#define ALGO_2D_AUTO 2 #define ALGO_2D_MESHADAPT_OLD 4 #define ALGO_2D_DELAUNAY 5 #define ALGO_2D_FRONTAL 6 diff --git a/Common/Options.cpp b/Common/Options.cpp index b26823f52f0bb4c08c5eaccb96c127e30ae27e38..46ece0afb26db12f4daaccc94f80036391ba50a9 100644 --- a/Common/Options.cpp +++ b/Common/Options.cpp @@ -5630,13 +5630,16 @@ double opt_mesh_algo2d(OPT_ARGS_NUM) #if defined(HAVE_FLTK) if(FlGui::available() && (action & GMSH_GUI)) { switch (CTX::instance()->mesh.algo2d) { - case ALGO_2D_DELAUNAY: + case ALGO_2D_MESHADAPT: FlGui::instance()->options->mesh.choice[2]->value(1); break; - case ALGO_2D_FRONTAL: + case ALGO_2D_DELAUNAY: FlGui::instance()->options->mesh.choice[2]->value(2); break; - case ALGO_2D_MESHADAPT: + case ALGO_2D_FRONTAL: + FlGui::instance()->options->mesh.choice[2]->value(3); + break; + case ALGO_2D_AUTO: default: FlGui::instance()->options->mesh.choice[2]->value(0); break; diff --git a/Fltk/optionWindow.cpp b/Fltk/optionWindow.cpp index 21b5b678b5f9cf2ec145445e830a2d2dc59840c6..be56fc25c4efd0f6c6f99fa2cbeb14ddbe9a0887 100644 --- a/Fltk/optionWindow.cpp +++ b/Fltk/optionWindow.cpp @@ -458,9 +458,10 @@ static void mesh_options_ok_cb(Fl_Widget *w, void *data) opt_mesh_point_type(0, GMSH_SET, o->mesh.choice[0]->value()); opt_mesh_algo2d(0, GMSH_SET, - (o->mesh.choice[2]->value() == 0) ? ALGO_2D_MESHADAPT : - (o->mesh.choice[2]->value() == 1) ? ALGO_2D_DELAUNAY : - ALGO_2D_FRONTAL); + (o->mesh.choice[2]->value() == 1) ? ALGO_2D_MESHADAPT : + (o->mesh.choice[2]->value() == 2) ? ALGO_2D_DELAUNAY : + (o->mesh.choice[2]->value() == 3) ? ALGO_2D_FRONTAL : + ALGO_2D_AUTO); opt_mesh_algo3d(0, GMSH_SET, (o->mesh.choice[3]->value() == 0) ? ALGO_3D_DELAUNAY : ALGO_3D_FRONTAL); @@ -1998,6 +1999,7 @@ optionWindow::optionWindow(int deltaFontSize) o->hide(); static Fl_Menu_Item menu_2d_algo[] = { + {"Automatic", 0, 0, 0}, {"MeshAdapt", 0, 0, 0}, {"Delaunay", 0, 0, 0}, {"Frontal", 0, 0, 0}, @@ -2044,7 +2046,7 @@ optionWindow::optionWindow(int deltaFontSize) mesh.choice[3]->callback(mesh_options_ok_cb); mesh.choice[1] = new Fl_Choice - (L + 2 * WB, 2 * WB + 3 * BH, IW, BH, "Recombination algorithm"); + (L + 2 * WB, 2 * WB + 3 * BH, IW, BH, "2D Recombination algorithm"); mesh.choice[1]->menu(menu_recombination_algo); mesh.choice[1]->align(FL_ALIGN_RIGHT); mesh.choice[1]->callback(mesh_options_ok_cb); diff --git a/Mesh/meshGFace.cpp b/Mesh/meshGFace.cpp index 8c207127fd9350c47211367fcae2bebec0cef556..7cafc430e62c4b3c645292cafc7bce66fca16f88 100644 --- a/Mesh/meshGFace.cpp +++ b/Mesh/meshGFace.cpp @@ -295,10 +295,17 @@ static void remeshUnrecoveredEdges(std::map<MVertex*, BDS_Point*> &recoverMapInv static bool algoDelaunay2D(GFace *gf) { - if(noSeam(gf) && (CTX::instance()->mesh.algo2d == ALGO_2D_DELAUNAY || - CTX::instance()->mesh.algo2d == ALGO_2D_BAMG || - CTX::instance()->mesh.algo2d == ALGO_2D_FRONTAL)) + if(!noSeam(gf)) + return false; + + if(CTX::instance()->mesh.algo2d == ALGO_2D_DELAUNAY || + CTX::instance()->mesh.algo2d == ALGO_2D_BAMG || + CTX::instance()->mesh.algo2d == ALGO_2D_FRONTAL) + return true; + + if(CTX::instance()->mesh.algo2d == ALGO_2D_AUTO && gf->geomType() == GEntity::Plane) return true; + return false; } @@ -877,7 +884,8 @@ static bool meshGenerator(GFace *gf, int RECUR_ITER, if(algoDelaunay2D(gf)){ if(CTX::instance()->mesh.algo2d == ALGO_2D_FRONTAL) bowyerWatsonFrontal(gf); - else if(CTX::instance()->mesh.algo2d == ALGO_2D_DELAUNAY) + else if(CTX::instance()->mesh.algo2d == ALGO_2D_DELAUNAY || + CTX::instance()->mesh.algo2d == ALGO_2D_AUTO) bowyerWatson(gf); else { bowyerWatson(gf); @@ -1460,7 +1468,8 @@ static bool meshGeneratorPeriodic(GFace *gf, bool debug = true) if(algoDelaunay2D(gf)){ if(CTX::instance()->mesh.algo2d == ALGO_2D_FRONTAL) bowyerWatsonFrontal(gf); - else if(CTX::instance()->mesh.algo2d == ALGO_2D_DELAUNAY) + else if(CTX::instance()->mesh.algo2d == ALGO_2D_DELAUNAY || + CTX::instance()->mesh.algo2d == ALGO_2D_AUTO) bowyerWatson(gf); else meshGFaceBamg(gf); @@ -1528,16 +1537,16 @@ void meshGFace::operator() (GFace *gf) } const char *algo = "Unknown"; - if(CTX::instance()->mesh.algo2d == ALGO_2D_FRONTAL) - algo = "Frontal"; - else if(CTX::instance()->mesh.algo2d == ALGO_2D_DELAUNAY) - algo = "Delaunay"; - else if(CTX::instance()->mesh.algo2d == ALGO_2D_MESHADAPT_OLD) - algo = "MeshAdapt (old)"; - else if(CTX::instance()->mesh.algo2d == ALGO_2D_BAMG) - algo = "Bamg"; - else - algo = "MeshAdapt"; + switch(CTX::instance()->mesh.algo2d){ + case ALGO_2D_MESHADAPT : algo = "MeshAdapt"; break; + case ALGO_2D_FRONTAL : algo = "Frontal"; break; + case ALGO_2D_DELAUNAY : algo = "Delaunay"; break; + case ALGO_2D_MESHADAPT_OLD : algo = "MeshAdapt (old)"; break; + case ALGO_2D_BAMG : algo = "Bamg"; break; + case ALGO_2D_AUTO : + algo = (gf->geomType() == GEntity::Plane) ? "Delaunay" : "MeshAdapt"; + break; + } Msg::Info("Meshing surface %d (%s, %s)", gf->tag(), gf->getTypeString().c_str(), algo); diff --git a/Mesh/meshGFaceBDS.cpp b/Mesh/meshGFaceBDS.cpp index 5a63eb51250abc4678d1e8fe44d434355d3e18ee..17b081036fdc9dd10499c0cefe3c515db77a3c3d 100644 --- a/Mesh/meshGFaceBDS.cpp +++ b/Mesh/meshGFaceBDS.cpp @@ -414,12 +414,14 @@ void swapEdgePass(GFace *gf, BDS_Mesh &m, int &nb_swap) // result = 0 => whatever // result = 1 => oblige to swap because the quality is greatly improved if (!(*it)->deleted){ - double qual = CTX::instance()->mesh.algo2d == ALGO_2D_MESHADAPT_OLD ? 1 : 5; - int result = edgeSwapTestQuality(*it,qual); - if (CTX::instance()->mesh.algo2d == ALGO_2D_MESHADAPT_OLD) - { if (m.swap_edge(*it, BDS_SwapEdgeTestQuality(true)))nb_swap++; } - else if ( result >= 0 && edgeSwapTestDelaunay(*it,gf)) - { if (m.swap_edge(*it, BDS_SwapEdgeTestQuality(false))) nb_swap++; } + double qual = (CTX::instance()->mesh.algo2d == ALGO_2D_MESHADAPT_OLD) ? 1 : 5; + int result = edgeSwapTestQuality(*it, qual); + if (CTX::instance()->mesh.algo2d == ALGO_2D_MESHADAPT_OLD){ + if (m.swap_edge(*it, BDS_SwapEdgeTestQuality(true))) nb_swap++; + } + else if (result >= 0 && edgeSwapTestDelaunay(*it, gf)){ + if (m.swap_edge(*it, BDS_SwapEdgeTestQuality(false))) nb_swap++; + } } ++it; } diff --git a/doc/texinfo/gmsh.texi b/doc/texinfo/gmsh.texi index da52456569c0cea2407793d62c0f3b09c64d7c13..675b661130b88e850c88385b69c5a8c2f466dd56 100644 --- a/doc/texinfo/gmsh.texi +++ b/doc/texinfo/gmsh.texi @@ -2612,6 +2612,11 @@ choice. When high element quality is important, the ``Frontal'' algorithm should be tried. For very large meshes of plane surfaces the ``Delaunay'' algorithm is the fastest. +The ``Automatic'' algorithm tries to select the best algorithm +automatically for each surface in the model. As of Gmsh 2.5, the +``Automatic'' algorithm selects ``Delaunay'' for plane surfaces and +``MeshAdapt'' for all other surfaces. + In 3D two unstructured algorithms are available: @enumerate