diff --git a/Mesh/Generator.cpp b/Mesh/Generator.cpp index c54768843a4c75c423331a3019787d7f9ce64aac..d3ea91950c46dba3a704c06c9ed60f7e0a4204d3 100644 --- a/Mesh/Generator.cpp +++ b/Mesh/Generator.cpp @@ -369,18 +369,6 @@ static void PrintMesh2dStatistics(GModel *m) static void Mesh2D(GModel *m) { if(TooManyElements(m, 2)) return; - - if(!CTX::instance()->expertMode && (CTX::instance()->mesh.algo2d == ALGO_2D_DELAUNAY || - CTX::instance()->mesh.algo2d == ALGO_2D_FRONTAL)){ - if(!Msg::GetBinaryAnswer - ("The 2D Delaunay and Frontal algorithms are still experimental\n" - "and produce triangles with random orientations. Do you really\n" - "want to continue?\n\n" - "(To disable this warning in the future, select `Enable expert\n" - "mode' in the option dialog.)", - "Continue", "Cancel")) return; - } - Msg::StatusBar(1, true, "Meshing 2D..."); double t1 = Cpu(); diff --git a/Mesh/meshGFaceDelaunayInsertion.cpp b/Mesh/meshGFaceDelaunayInsertion.cpp index f96d7d54a0d3b4e4a07ba14693f341780c7f5e4a..2a4298869dfb550b0a7430a04541b4d27006854d 100644 --- a/Mesh/meshGFaceDelaunayInsertion.cpp +++ b/Mesh/meshGFaceDelaunayInsertion.cpp @@ -615,7 +615,7 @@ void gmshBowyerWatson(GFace *gf) std::set<MTri3*,compareTri3Ptr> AllTris; std::vector<double> vSizes, vSizesBGM, Us, Vs; - buidMeshGenerationDataStructures(gf, AllTris, vSizes, vSizesBGM, Us, Vs); + buildMeshGenerationDataStructures(gf, AllTris, vSizes, vSizesBGM, Us, Vs); // _printTris ("before.pos", AllTris, Us,Vs); int nbSwaps = edgeSwapPass(gf, AllTris, SWCR_DEL, Us, Vs, vSizes, vSizesBGM); @@ -701,7 +701,8 @@ void gmshBowyerWatsonFrontal(GFace *gf) std::set<MTri3*,compareTri3Ptr> AllTris; std::set<MTri3*,compareTri3Ptr> ActiveTris; std::vector<double> vSizes, vSizesBGM, Us, Vs; - buidMeshGenerationDataStructures(gf, AllTris, vSizes, vSizesBGM, Us, Vs); + + buildMeshGenerationDataStructures(gf, AllTris, vSizes, vSizesBGM, Us, Vs); // delaunise the initial mesh int nbSwaps = edgeSwapPass(gf, AllTris, SWCR_DEL, Us, Vs, vSizes, vSizesBGM); diff --git a/Mesh/meshGFaceOptimize.cpp b/Mesh/meshGFaceOptimize.cpp index d0df634c99295e7da5345ccbe0b6da9b3c79aeb2..9317b2dac3035b85175645778f7c2a05c27bb43c 100644 --- a/Mesh/meshGFaceOptimize.cpp +++ b/Mesh/meshGFaceOptimize.cpp @@ -11,6 +11,7 @@ #include "MVertex.h" #include "MElement.h" #include "BackgroundMesh.h" +#include "Numeric.h" #include "GmshMessage.h" #include "Generator.h" @@ -44,11 +45,12 @@ static void setLcs(MTriangle *t, std::map<MVertex*, double> &vSizes) } } -void buidMeshGenerationDataStructures(GFace *gf, std::set<MTri3*, compareTri3Ptr> &AllTris, - std::vector<double> &vSizes, - std::vector<double> &vSizesBGM, - std::vector<double> &Us, - std::vector<double> &Vs) +void buildMeshGenerationDataStructures(GFace *gf, + std::set<MTri3*, compareTri3Ptr> &AllTris, + std::vector<double> &vSizes, + std::vector<double> &vSizesBGM, + std::vector<double> &Us, + std::vector<double> &Vs) { std::map<MVertex*, double> vSizesMap; std::list<GEdge*> edges = gf->edges(); @@ -103,6 +105,31 @@ void transferDataStructure(GFace *gf, std::set<MTri3*, compareTri3Ptr> &AllTris) delete worst; AllTris.erase(AllTris.begin()); } + + // make sure all the triangles are oriented in the same way (in + // parameter space). FIXME: this is really ugly and slow. JF: we + // need to change the actual algorithm to ensure that we create + // correctly oriented triangles in the first place + if(gf->triangles.size() > 1){ + double u[3], v[3], n1[3], n2[3]; + MTriangle *t = gf->triangles[0]; + SPoint2 uv[3]; + for(int i = 0; i < 3; i++) + reparamMeshVertexOnFace(t->getVertex(i), gf, uv[i]); + normal3points(uv[0].x(), uv[0].y(), 0., + uv[1].x(), uv[1].y(), 0., + uv[2].x(), uv[2].y(), 0., n1); + for(unsigned int j = 1; j < gf->triangles.size(); j++){ + t = gf->triangles[j]; + for(int i = 0; i < 3; i++) + reparamMeshVertexOnFace(t->getVertex(i), gf, uv[i]); + normal3points(uv[0].x(), uv[0].y(), 0., + uv[1].x(), uv[1].y(), 0., + uv[2].x(), uv[2].y(), 0., n2); + double pp; prosca(n1, n2, &pp); + if(pp < 0) t->revert(); + } + } } template <class T> diff --git a/Mesh/meshGFaceOptimize.h b/Mesh/meshGFaceOptimize.h index a4b44c955e2a2d081e6a935a6876030902ade33c..fb96c8ea83b86cd654ca35033fbdf6fd0c99af3b 100644 --- a/Mesh/meshGFaceOptimize.h +++ b/Mesh/meshGFaceOptimize.h @@ -14,38 +14,44 @@ class GFace; class MVertex; + typedef std::map<MVertex*, std::vector<MElement*> > v2t_cont; -typedef std::map<MEdge, std::pair<MElement*,MElement*>, Less_Edge> e2t_cont; +typedef std::map<MEdge, std::pair<MElement*, MElement*>, Less_Edge> e2t_cont; + void buildVertexToTriangle(std::vector<MTriangle*> &, v2t_cont &adj); void buildEdgeToTriangle(std::vector<MTriangle*> &, e2t_cont &adj); void laplaceSmoothing(GFace *gf); void edgeSwappingLawson(GFace *gf); -enum gmshSwapCriterion {SWCR_DEL, SWCR_QUAL,SWCR_NORM, SWCR_CLOSE}; + +enum gmshSwapCriterion {SWCR_DEL, SWCR_QUAL, SWCR_NORM, SWCR_CLOSE}; enum gmshSplitCriterion {SPCR_CLOSE, SPCR_QUAL, SPCR_ALLWAYS}; -int edgeSwapPass(GFace *gf, std::set<MTri3*, compareTri3Ptr> &allTris, + +int edgeSwapPass(GFace *gf, + std::set<MTri3*, compareTri3Ptr> &allTris, const gmshSwapCriterion &cr, - const std::vector<double> &Us, + const std::vector<double> &Us, const std::vector<double> &Vs, - const std::vector<double> &vSizes, + const std::vector<double> &vSizes, const std::vector<double> &vSizesBGM); -int edgeSplitPass(double maxLC, - GFace *gf, std::set<MTri3*, compareTri3Ptr> &allTris, +int edgeSplitPass(double maxLC, GFace *gf, + std::set<MTri3*, compareTri3Ptr> &allTris, const gmshSplitCriterion &cr, - std::vector<double> &Us , + std::vector<double> &Us, std::vector<double> &Vs, std::vector<double> &vSizes , std::vector<double> &vSizesBGM); -int edgeCollapsePass(double minLC, - GFace *gf, std::set<MTri3*, compareTri3Ptr> &allTris, +int edgeCollapsePass(double minLC, GFace *gf, + std::set<MTri3*, compareTri3Ptr> &allTris, std::vector<double> &Us, std::vector<double> &Vs, std::vector<double> &vSizes , std::vector<double> &vSizesBGM); -void buidMeshGenerationDataStructures(GFace *gf, std::set<MTri3*, compareTri3Ptr> &AllTris, - std::vector<double> &vSizes, - std::vector<double> &vSizesBGM, - std::vector<double> &Us, - std::vector<double> &Vs); +void buildMeshGenerationDataStructures(GFace *gf, + std::set<MTri3*, compareTri3Ptr> &AllTris, + std::vector<double> &vSizes, + std::vector<double> &vSizesBGM, + std::vector<double> &Us, + std::vector<double> &Vs); void transferDataStructure (GFace *gf, std::set<MTri3*, compareTri3Ptr> &AllTris); void gmshRecombineIntoQuads(GFace *gf);