From 83190066857738ce215e7893cfaef1e587400fda Mon Sep 17 00:00:00 2001 From: Jean-Francois Remacle <jean-francois.remacle@uclouvain.be> Date: Wed, 21 Nov 2012 11:53:02 +0000 Subject: [PATCH] hopla --- Mesh/meshGRegionDelaunayInsertion.cpp | 190 ++++++++++++++++++++------ 1 file changed, 149 insertions(+), 41 deletions(-) diff --git a/Mesh/meshGRegionDelaunayInsertion.cpp b/Mesh/meshGRegionDelaunayInsertion.cpp index 5aedc64369..cce8ac8dd0 100644 --- a/Mesh/meshGRegionDelaunayInsertion.cpp +++ b/Mesh/meshGRegionDelaunayInsertion.cpp @@ -75,8 +75,38 @@ struct faceXtet{ if (v[2] < other.v[2]) return true; return false; } + inline bool operator == (const faceXtet & other) const + { + return (v[0] == other.v[0] && + v[1] == other.v[1] && + v[2] == other.v[2] ); + } }; +template <class ITER> +void connectTets_vector(ITER beg, ITER end) +{ + // std::set<faceXtet> conn; + std::vector<faceXtet> conn; + while (beg != end){ + if (!(*beg)->isDeleted()){ + for (int i = 0; i < 4; i++){ + faceXtet fxt(*beg, i); + std::vector<faceXtet>::iterator found = std::find(conn.begin(), conn.end(), fxt); + // std::set<faceXtet>::iterator found = conn.find(fxt); + if (found == conn.end()) + conn.push_back(fxt); + // conn.insert(fxt); + else if (found->t1 != *beg){ + found->t1->setNeigh(found->i1, *beg); + (*beg)->setNeigh(i, found->t1); + } + } + } + ++beg; + } +} + template <class ITER> void connectTets(ITER beg, ITER end) { @@ -85,9 +115,9 @@ void connectTets(ITER beg, ITER end) if (!(*beg)->isDeleted()){ for (int i = 0; i < 4; i++){ faceXtet fxt(*beg, i); - std::set<faceXtet>::iterator found = conn.find(fxt); + std::set<faceXtet>::iterator found = conn.find(fxt); if (found == conn.end()) - conn.insert(fxt); + conn.insert(fxt); else if (found->t1 != *beg){ found->t1->setNeigh(found->i1, *beg); (*beg)->setNeigh(i, found->t1); @@ -98,6 +128,7 @@ void connectTets(ITER beg, ITER end) } } + static void updateActiveFaces(MTet4 *t, double limit_, std::set<MFace,Less_Face> &front) { if (t->isDeleted()) return; @@ -160,8 +191,50 @@ void recurFindCavity(std::list<faceXtet> & shell, shell.push_back(faceXtet(t, i)); } } + // printf("cavity size %d\n",cavity.size()); } +void nonrecurFindCavity(std::list<faceXtet> & shell, + std::list<MTet4*> & cavity, + MVertex *v , + MTet4 *t) +{ + // Msg::Info("tet %d %d %d %d",t->tet()->getVertex(0)->getNum(), + // t->tet()->getVertex(1)->getNum(), + // t->tet()->getVertex(2)->getNum(), + // t->tet()->getVertex(3)->getNum()); + + // invariant : this one has to be inserted in the cavity + // consider this tet deleted + // remove its reference to its neighbors + + std::stack<MTet4*> _stack; + _stack.push(t); + while(!_stack.empty()){ + t = _stack.top(); + _stack.pop(); + t->setDeleted(true); + // the cavity that has to be removed + // because it violates delaunay criterion + cavity.push_back(t); + + for (int i = 0; i < 4; i++){ + MTet4 *neigh = t->getNeigh(i) ; + if (!neigh) + shell.push_back(faceXtet(t, i)); + else if (!neigh->isDeleted()){ + int circ = neigh->inCircumSphere(v); + if (circ && (neigh->onWhat() == t->onWhat())) + _stack.push(neigh); + else + shell.push_back(faceXtet(t, i)); + } + } + } + // printf("cavity size %d\n",cavity.size()); +} + + bool insertVertex(MVertex *v, MTet4 *t, MTet4Factory &myFactory, @@ -237,7 +310,7 @@ bool insertVertex(MVertex *v, // OK, the cavity is star shaped if (fabs(oldVolume - newVolume) < 1.e-10 * oldVolume && !onePointIsTooClose){ - connectTets(new_cavity.begin(), new_cavity.end()); + connectTets_vector(new_cavity.begin(), new_cavity.end()); allTets.insert(newTets, newTets + shell.size()); if (activeTets){ @@ -344,46 +417,76 @@ GRegion *getRegionFromBoundingFaces(GModel *model, return 0; } -void recur_classify(MTet4 *t, std::list<MTet4*> &theRegion, - std::set<GFace*> &faces_bound, GRegion *bidon, - GModel *model, const fs_cont &search) -{ - if (!t) Msg::Error("a tet is not connected by a boundary face"); - if (t->onWhat()) return; // should never return here... - theRegion.push_back(t); - t->setOnWhat(bidon); +// void recur_classify(MTet4 *t, std::list<MTet4*> &theRegion, +// std::set<GFace*> &faces_bound, GRegion *bidon, +// GModel *model, const fs_cont &search) +// { +// if (!t) Msg::Error("a tet is not connected by a boundary face"); +// if (t->onWhat()) { +// return; // should never return here... +// } +// theRegion.push_back(t); +// t->setOnWhat(bidon); + +// bool FF[4] = {0,0,0,0}; + +// for (int i = 0; i < 4; i++){ +// // if (!t->getNeigh(i) || !t->getNeigh(i)->onWhat()) +// { +// GFace* gfound = findInFaceSearchStructure (t->tet()->getVertex(faces[i][0]), +// t->tet()->getVertex(faces[i][1]), +// t->tet()->getVertex(faces[i][2]), +// search); +// if (gfound){ +// FF[i] = true; +// if (faces_bound.find(gfound) == faces_bound.end()) +// faces_bound.insert(gfound); +// } +// } +// } +// for (int i = 0; i < 4; i++){ +// if (!FF[i]) +// recur_classify(t->getNeigh(i), theRegion, faces_bound, bidon, model, search ); +// } +// } - bool FF[4] = {0,0,0,0}; +void non_recursive_classify(MTet4 *t, std::list<MTet4*> &theRegion, + std::set<GFace*> &faces_bound, GRegion *bidon, + GModel *model, const fs_cont &search) +{ - for (int i = 0; i < 4; i++){ - // if (!t->getNeigh(i) || !t->getNeigh(i)->onWhat()) - { - GFace* gfound = findInFaceSearchStructure (t->tet()->getVertex(faces[i][0]), - t->tet()->getVertex(faces[i][1]), - t->tet()->getVertex(faces[i][2]), - search); - if (gfound){ - FF[i] = true; - if (faces_bound.find(gfound) == faces_bound.end()) - faces_bound.insert(gfound); + std::stack<MTet4*> _stackounette; + _stackounette.push(t); + + while(!_stackounette.empty()){ + t = _stackounette.top(); + _stackounette.pop(); + if (!t) Msg::Error("a tet is not connected by a boundary face"); + if (!t->onWhat()) { + theRegion.push_back(t); + t->setOnWhat(bidon); + bool FF[4] = {0,0,0,0}; + for (int i = 0; i < 4; i++){ + GFace* gfound = findInFaceSearchStructure (t->tet()->getVertex(faces[i][0]), + t->tet()->getVertex(faces[i][1]), + t->tet()->getVertex(faces[i][2]), + search); + if (gfound){ + FF[i] = true; + if (faces_bound.find(gfound) == faces_bound.end()) + faces_bound.insert(gfound); + } + } + for (int i = 0; i < 4; i++){ + if (!FF[i]) + _stackounette.push(t->getNeigh(i)); } - -// MTriangle tri (t->tet()->getVertex (faces[i][0]), -// t->tet()->getVertex (faces[i][1]), -// t->tet()->getVertex (faces[i][2])); -// GFace *gfound; -// if (FF[i] = find_triangle_in_model(model, &tri, &gfound, false)){ -// if (faces_bound.find(gfound) == faces_bound.end()) -// faces_bound.insert(gfound); -// } } } - for (int i = 0; i < 4; i++){ - if (!FF[i]) - recur_classify(t->getNeigh(i), theRegion, faces_bound, bidon, model, search ); - } } + + void adaptMeshGRegion::operator () (GRegion *gr) { const qualityMeasure4Tet qm = QMTET_2; @@ -744,7 +847,7 @@ void optimizeMesh(GRegion *gr, const qualityMeasure4Tet &qm) } -static double tetcircumcenter(double a[3], double b[3], double c[3], double d[3], +double tetcircumcenter(double a[3], double b[3], double c[3], double d[3], double circumcenter[3], double *xi, double *eta, double *zeta){ double xba, yba, zba, xca, yca, zca, xda, yda, zda; double balength, calength, dalength; @@ -865,7 +968,7 @@ void insertVerticesInRegion (GRegion *gr) GRegion *bidon = (GRegion*)123; double _t1 = Cpu(); Msg::Debug("start with a non classified tet"); - recur_classify(*it, theRegion, faces_bound, bidon, gr->model(), search); + non_recursive_classify(*it, theRegion, faces_bound, bidon, gr->model(), search); double _t2 = Cpu(); Msg::Debug("found %d tets with %d faces (%g sec for the classification)", theRegion.size(), faces_bound.size(), _t2 - _t1); @@ -894,6 +997,8 @@ void insertVerticesInRegion (GRegion *gr) int ITER = 0; + int COUNT_MISS_1 = 0; + int COUNT_MISS_2 = 0; while(1){ if(allTets.empty()){ Msg::Error("No tetrahedra in region %d %d", gr->tag(), allTets.size()); @@ -908,8 +1013,8 @@ void insertVerticesInRegion (GRegion *gr) } else{ if(ITER++ %5000 == 0) - Msg::Info("%d points created -- Worst tet radius is %g", - vSizes.size(), worst->getRadius()); + Msg::Info("%d points created -- Worst tet radius is %g (MISSES %d %d)", + vSizes.size(), worst->getRadius(), COUNT_MISS_1,COUNT_MISS_2); if(worst->getRadius() < 1) break; double center[3]; double uvw[3]; @@ -956,6 +1061,7 @@ void insertVerticesInRegion (GRegion *gr) vSizesBGM.push_back(lc); // compute mesh spacing there if(!insertVertex(v, worst, myFactory, allTets, vSizes,vSizesBGM)){ + COUNT_MISS_1++; myFactory.changeTetRadius(allTets.begin(), 0.); delete v; } @@ -965,6 +1071,7 @@ void insertVerticesInRegion (GRegion *gr) else{ // printf("point outside %12.5E %12.5E %12.5E %12.5E %12.5E\n",VV,uvw[0], uvw[1], uvw[2],1-uvw[0]-uvw[1]-uvw[2]); myFactory.changeTetRadius(allTets.begin(), 0.0); + COUNT_MISS_2++; } } @@ -985,6 +1092,7 @@ void insertVerticesInRegion (GRegion *gr) Msg::Info("cleaning up the memory %d -> %d", n1, allTets.size()); } } + // relocate vertices int nbReloc = 0; @@ -1094,7 +1202,7 @@ void bowyerWatsonFrontalLayers(GRegion *gr, bool hex) GRegion *bidon = (GRegion*)123; double _t1 = Cpu(); Msg::Debug("start with a non classified tet"); - recur_classify(*it, theRegion, faces_bound, bidon, gr->model(), search); + non_recursive_classify(*it, theRegion, faces_bound, bidon, gr->model(), search); double _t2 = Cpu(); Msg::Debug("found %d tets with %d faces (%g sec for the classification)", theRegion.size(), faces_bound.size(), _t2 - _t1); -- GitLab