From 54befb5842d893c1f7dd225e5eaa0bea9da09524 Mon Sep 17 00:00:00 2001 From: Jean-Francois Remacle <jean-francois.remacle@uclouvain.be> Date: Thu, 17 Jan 2008 17:48:39 +0000 Subject: [PATCH] Aniso delaunay surface mesher is now fast : the initial mesh is now "delaunized" using swaps using a "fast" algorithm --- Geo/OCCFace.cpp | 3 +- Mesh/BDS.cpp | 6 +-- Mesh/meshGFace.cpp | 6 +-- Mesh/meshGFaceDelaunayInsertion.cpp | 10 ++-- Mesh/meshGFaceOptimize.cpp | 80 +++++++++++++++++++++-------- 5 files changed, 72 insertions(+), 33 deletions(-) diff --git a/Geo/OCCFace.cpp b/Geo/OCCFace.cpp index 7b05b04e28..2e3182fc2e 100644 --- a/Geo/OCCFace.cpp +++ b/Geo/OCCFace.cpp @@ -1,4 +1,4 @@ -// $Id: OCCFace.cpp,v 1.24 2007-11-11 19:53:57 remacle Exp $ +// $Id: OCCFace.cpp,v 1.25 2008-01-17 17:48:38 remacle Exp $ // // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle // @@ -52,6 +52,7 @@ OCCFace::OCCFace(GModel *m, TopoDS_Face _s, int num, TopTools_IndexedMapOfShape GEdge *e = m->edgeByTag(index); if(!e) throw; l_wire.push_back(e); + Msg(DEBUG2,"Edge %d",e->tag()); e->addFace(this); if(!e->is3D()){ OCCEdge *occe = (OCCEdge*)e; diff --git a/Mesh/BDS.cpp b/Mesh/BDS.cpp index 1d4fc36ac9..00131e7940 100644 --- a/Mesh/BDS.cpp +++ b/Mesh/BDS.cpp @@ -1,4 +1,4 @@ -// $Id: BDS.cpp,v 1.88 2008-01-15 19:50:58 remacle Exp $ +// $Id: BDS.cpp,v 1.89 2008-01-17 17:48:38 remacle Exp $ // // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle // @@ -44,7 +44,7 @@ void outputScalarField(std::list < BDS_Face * >t, const char *iii, int param) fprintf(f, "ST(%g,%g,%g,%g,%g,%g,%g,%g,%g){%g,%g,%g};\n", pts[0]->u, pts[0]->v, 0.0, pts[1]->u, pts[1]->v, 0.0, - pts[2]->u, pts[2]->v, 0.0,(double)pts[0]->lc(),(double)pts[1]->lc(),(double)pts[2]->lc()); + pts[2]->u, pts[2]->v, 0.0,(double)pts[0]->iD,(double)pts[1]->iD,(double)pts[2]->iD); else fprintf(f, "ST(%g,%g,%g,%g,%g,%g,%g,%g,%g){%g,%g,%g};\n", pts[0]->X, pts[0]->Y, pts[0]->Z, @@ -1326,7 +1326,7 @@ bool BDS_Mesh::smooth_point_centroid(BDS_Point * p, GFace *gf) double sold = fabs(surface_triangle_param(n[0],n[1],n[2])); s2 += sold; // printf("%22.15E %22.15E\n",snew,sold); - // if ( snew < .1 * sold) return false; + if ( snew < .1 * sold) return false; // if (!test_move_point_parametric_triangle ( p, U, V, t)){ // return false; diff --git a/Mesh/meshGFace.cpp b/Mesh/meshGFace.cpp index 74e28e80d9..9a4670f893 100644 --- a/Mesh/meshGFace.cpp +++ b/Mesh/meshGFace.cpp @@ -1,4 +1,4 @@ -// $Id: meshGFace.cpp,v 1.105 2008-01-15 19:50:58 remacle Exp $ +// $Id: meshGFace.cpp,v 1.106 2008-01-17 17:48:38 remacle Exp $ // // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle // @@ -2253,8 +2253,8 @@ void meshGFace::operator() (GFace *gf) { Msg(DEBUG1, "Generating the mesh"); if(noseam (gf) || gf->getNativeType() == GEntity::GmshModel || gf->edgeLoops.empty()){ - //gmsh2DMeshGenerator(gf,0, true); - gmsh2DMeshGenerator(gf,0, false); + gmsh2DMeshGenerator(gf,0, true); + //gmsh2DMeshGenerator(gf,0, false); } else{ if(!gmsh2DMeshGeneratorPeriodic(gf,false)) diff --git a/Mesh/meshGFaceDelaunayInsertion.cpp b/Mesh/meshGFaceDelaunayInsertion.cpp index 42cd02777d..c8624ed87b 100644 --- a/Mesh/meshGFaceDelaunayInsertion.cpp +++ b/Mesh/meshGFaceDelaunayInsertion.cpp @@ -1,4 +1,4 @@ -// $Id: meshGFaceDelaunayInsertion.cpp,v 1.7 2008-01-14 21:29:14 remacle Exp $ +// $Id: meshGFaceDelaunayInsertion.cpp,v 1.8 2008-01-17 17:48:39 remacle Exp $ // // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle // @@ -584,15 +584,13 @@ void insertVerticesInFace (GFace *gf, BDS_Mesh *bds) gf->triangles.clear(); connectTris ( AllTris.begin(), AllTris.end() ); + Msg(DEBUG,"All %d tris were connected",AllTris.size()); // _printTris ("before.pos", AllTris, Us,Vs); - // this should be MUCH faster ! - for (int i=0;i<1200;i++) - if(!edgeSwapPass(gf,AllTris,SWCR_DEL,Us,Vs,vSizes,vSizesBGM))break; - + int nbSwaps = edgeSwapPass(gf,AllTris,SWCR_DEL,Us,Vs,vSizes,vSizesBGM); // _printTris ("after2.pos", AllTris, Us,Vs); + Msg(DEBUG,"Delaunization of the initial mesh done (%d swaps)",nbSwaps); - Msg(DEBUG,"All %d tris were connected",AllTris.size()); // here the classification should be done diff --git a/Mesh/meshGFaceOptimize.cpp b/Mesh/meshGFaceOptimize.cpp index f460af3b7c..d20d091e6a 100644 --- a/Mesh/meshGFaceOptimize.cpp +++ b/Mesh/meshGFaceOptimize.cpp @@ -127,9 +127,29 @@ double surfaceTriangleUV (MVertex *v1, MVertex *v2, MVertex *v3, return 0.5*fabs (v12[0]*v13[1]-v12[1]*v13[0]); } +struct swapquad{ + int v[4]; + bool operator < (const swapquad &o) const{ + if (v[0] < o.v[0])return true; + if (v[0] > o.v[0])return false; + if (v[1] < o.v[1])return true; + if (v[1] > o.v[1])return false; + if (v[2] < o.v[2])return true; + if (v[2] > o.v[2])return false; + if (v[3] < o.v[3])return true; + return false; + } + swapquad(MVertex *v1,MVertex *v2,MVertex *v3,MVertex *v4){ + v[0] = v1->getNum(); + v[1] = v2->getNum(); + v[2] = v3->getNum(); + v[3] = v4->getNum(); + std::sort(v,v+4); + } +}; - -bool gmshEdgeSwap(MTri3 *t1, +bool gmshEdgeSwap(std::set<swapquad> & configs, + MTri3 *t1, GFace *gf, int iLocalEdge, std::vector<MTri3*> &newTris, @@ -137,7 +157,7 @@ bool gmshEdgeSwap(MTri3 *t1, const std::vector<double> & Us, const std::vector<double> & Vs, const std::vector<double> & vSizes , - const std::vector<double> & vSizesBGM ){ + const std::vector<double> & vSizesBGM){ MTri3 *t2 = t1->getNeigh(iLocalEdge); if (!t2) return false; @@ -149,6 +169,16 @@ bool gmshEdgeSwap(MTri3 *t1, for (int i=0;i<3;i++) if (t2->tri()->getVertex(i) != v1 && t2->tri()->getVertex(i) != v2) v4 = t2->tri()->getVertex(i); + + // printf("%d %d %d %d %d\n",Us.size(),v1->getNum(),v2->getNum(),v3->getNum(),v4->getNum()); + + // printf("%d %d %d %d\n",tv1,tv2,tv3,tv4); + + swapquad sq (v1,v2,v3,v4); + if (configs.find(sq) != configs.end())return false; + configs.insert(sq); + + // if (tv1 != 0 && tv1 == tv2 && tv1 == tv3 && tv1 == tv4)return false; const double volumeRef = surfaceTriangleUV (v1,v2,v3,Us,Vs) + surfaceTriangleUV (v1,v2,v4,Us,Vs); @@ -182,8 +212,8 @@ bool gmshEdgeSwap(MTri3 *t1, } case SWCR_DEL: { - double edgeCenter[2] ={(Us[v1->getNum()]+Us[v2->getNum()])*.5, - (Vs[v1->getNum()]+Vs[v2->getNum()])*.5}; + double edgeCenter[2] ={(Us[v1->getNum()]+Us[v2->getNum()]+Us[v3->getNum()]+Us[v4->getNum()])*.25, + (Vs[v1->getNum()]+Vs[v2->getNum()]+Vs[v3->getNum()]+Vs[v4->getNum()])*.25}; double uv4[2] ={Us[v4->getNum()],Vs[v4->getNum()]}; double metric[3]; buildMetric ( gf , edgeCenter , metric); @@ -255,6 +285,7 @@ bool gmshEdgeSwap(MTri3 *t1, connectTriangles ( cavity ); newTris.push_back(t1b3); newTris.push_back(t2b3); + return true; } @@ -572,6 +603,8 @@ bool gmshVertexCollapse(const double lMin, return true; } + + int edgeSwapPass (GFace *gf, std::set<MTri3*,compareTri3Ptr> &allTris, const gmshSwapCriterion &cr, const std::vector<double> & Us , @@ -580,27 +613,34 @@ int edgeSwapPass (GFace *gf, std::set<MTri3*,compareTri3Ptr> &allTris, const std::vector<double> & vSizesBGM) { typedef std::set<MTri3*,compareTri3Ptr> CONTAINER ; - std::vector<MTri3*> newTris; - int nbSwap = 0; - - for (CONTAINER::iterator it = allTris.begin();it!=allTris.end();++it){ - if (!(*it)->isDeleted()){ - for (int i=0;i<3;i++){ - if (gmshEdgeSwap(*it,gf,i,newTris,cr,Us,Vs,vSizes,vSizesBGM)) {nbSwap++;break;} + int nbSwapTot=0; + std::set<swapquad> configs; + for (int iter=0;iter<1200;iter++){ + int nbSwap = 0; + std::vector<MTri3*> newTris; + for (CONTAINER::iterator it = allTris.begin();it!=allTris.end();++it){ + if (!(*it)->isDeleted()){ + for (int i=0;i<3;i++){ + if (gmshEdgeSwap(configs,*it,gf,i,newTris,cr,Us,Vs,vSizes,vSizesBGM)) {nbSwap++;break;} + } + } + else{ + delete *it; + CONTAINER::iterator itb = it; + ++it; + allTris.erase(itb); } } - else{ - CONTAINER::iterator itb = it; - ++it; - delete *itb; - allTris.erase(itb); - } + allTris.insert(newTris.begin(),newTris.end()); + // printf("iter %d nbswam %d\n",iter,nbSwap); + nbSwapTot+=nbSwap; + if (nbSwap == 0)break; } + // printf("B %d %d tris ",allTris.size(),newTris.size()); - allTris.insert(newTris.begin(),newTris.end()); // printf("A %d %d tris\n",allTris.size(),newTris.size()); - return nbSwap; + return nbSwapTot; } int edgeSplitPass (double maxLC, -- GitLab