diff --git a/Mesh/meshGFaceDelaunayInsertion.cpp b/Mesh/meshGFaceDelaunayInsertion.cpp index b9e6bd3e0caed23b645000d08545af1a712da2af..4351dffde54b6ecc6024cd6a3fccffa11ec9d2e8 100644 --- a/Mesh/meshGFaceDelaunayInsertion.cpp +++ b/Mesh/meshGFaceDelaunayInsertion.cpp @@ -25,7 +25,9 @@ #include "surfaceFiller.h" double LIMIT_ = 0.5 * sqrt(2.0) * 1; - +int N_GLOBAL_SEARCH; +int N_SEARCH; +double DT_INSERT_VERTEX; int MTri3::radiusNorm = 2; /* @@ -401,14 +403,17 @@ int inCircumCircle(MTriangle *base, template <class ITER> void connectTris(ITER beg, ITER end) { - std::set<edgeXface> conn; + std::vector<edgeXface> conn; + // std::set<edgeXface> conn; while (beg != end){ if (!(*beg)->isDeleted()){ for (int i = 0; i < 3; i++){ edgeXface fxt(*beg, i); - std::set<edgeXface>::iterator found = conn.find(fxt); + // std::set<edgeXface>::iterator found = conn.find(fxt); + std::vector<edgeXface>::iterator found = std::find(conn.begin(), conn.end(), fxt); if (found == conn.end()) - conn.insert(fxt); + conn.push_back(fxt); + // conn.insert(fxt); else if (found->t1 != *beg){ found->t1->setNeigh(found->i1, *beg); (*beg)->setNeigh(i, found->t1); @@ -553,7 +558,8 @@ bool insertVertex(bool force, GFace *gf, MVertex *v, double *param , MTri3 *t, std::vector<SMetric3> &vMetricsBGM, std::vector<double> &Us, std::vector<double> &Vs, - double *metric = 0) + double *metric, + MTri3 **oneNewTriangle) { std::list<edgeXface> shell; std::list<MTri3*> cavity; @@ -567,6 +573,7 @@ bool insertVertex(bool force, GFace *gf, MVertex *v, double *param , MTri3 *t, recurFindCavityAniso(gf, shell, cavity, metric, param, t, Us, Vs); } + // check that volume is conserved double newVolume = 0; double oldVolume = 0; @@ -596,7 +603,7 @@ bool insertVertex(bool force, GFace *gf, MVertex *v, double *param , MTri3 *t, MTri3 *t4; t4 = new MTri3(t, LL,0,&Us,&Vs,gf); - + if (oneNewTriangle) *oneNewTriangle = t4; // double din = t->getInnerRadius(); double d1 = distance(it->v[0],v); @@ -605,7 +612,7 @@ bool insertVertex(bool force, GFace *gf, MVertex *v, double *param , MTri3 *t, // avoid angles that are too obtuse double cosv = ((d1*d1+d2*d2-d3*d3)/(2.*d1*d2)); - + if ((d1 < LL * .0025 || d2 < LL * .0025 || cosv < -.9999999) && !force) { onePointIsTooClose = true; } @@ -628,7 +635,10 @@ bool insertVertex(bool force, GFace *gf, MVertex *v, double *param , MTri3 *t, if (fabs(oldVolume - newVolume) < 1.e-12 * oldVolume && shell.size() > 3 && !onePointIsTooClose){ connectTris(new_cavity.begin(), new_cavity.end()); + // clock_t t1 = clock(); allTets.insert(newTris, newTris + shell.size()); + // clock_t t2 = clock(); + // DT_INSERT_VERTEX += (double)(t2-t1)/CLOCKS_PER_SEC; if (activeTets){ for (std::list<MTri3*>::iterator i = new_cavity.begin(); i != new_cavity.end(); ++i){ int active_edge; @@ -661,21 +671,25 @@ bool insertVertex(bool force, GFace *gf, MVertex *v, double *param , MTri3 *t, for (unsigned int i = 0; i < shell.size(); i++) delete newTris[i]; delete [] newTris; // throw; + // clock_t t2 = clock(); + // DT_INSERT_VERTEX += (double)(t2-t1)/CLOCKS_PER_SEC; return false; } } - static MTri3* search4Triangle (MTri3 *t, double pt[2], std::vector<double> &Us, std::vector<double> &Vs, - std::set<MTri3*,compareTri3Ptr> &AllTris, double uv[2]) { + std::set<MTri3*,compareTri3Ptr> &AllTris, double uv[2], bool force = false) { + + // bool inside = t->inCircumCircle(pt); + bool inside = invMapUV(t->tri(), pt, Us, Vs, uv, 1.e-8); - bool inside = invMapUV(t->tri(), pt, Us, Vs, uv, 1.e-8); // printf("inside = %d (%g %g)\n",inside,pt[0],pt[1]); if (inside) return t; SPoint3 q1(pt[0],pt[1],0); int ITER = 0; while (1){ + N_SEARCH ++ ; SPoint3 q2((Us[t->tri()->getVertex(0)->getIndex()] + Us[t->tri()->getVertex(1)->getIndex()] + Us[t->tri()->getVertex(2)->getIndex()]) / 3.0, @@ -701,8 +715,9 @@ static MTri3* search4Triangle (MTri3 *t, double pt[2], if (ITER++ > (int)AllTris.size()) break; } - return 0; // FIXME: removing this leads to horrible performance + if (!force)return 0; // FIXME: removing this leads to horrible performance + N_GLOBAL_SEARCH ++ ; for(std::set<MTri3*,compareTri3Ptr>::iterator itx = AllTris.begin(); itx != AllTris.end();++itx){ if (!(*itx)->isDeleted()){ @@ -723,8 +738,9 @@ static bool insertAPoint(GFace *gf, std::set<MTri3*,compareTri3Ptr>::iterator it std::vector<SMetric3> &vMetricsBGM, std::set<MTri3*,compareTri3Ptr> &AllTris, std::set<MTri3*,compareTri3Ptr> *ActiveTris = 0, - MTri3 *worst = 0) + MTri3 *worst = 0, MTri3 **oneNewTriangle = 0) { + if (worst){ it = AllTris.find(worst); if (worst != *it){ @@ -734,11 +750,12 @@ static bool insertAPoint(GFace *gf, std::set<MTri3*,compareTri3Ptr>::iterator it } else worst = *it; + MTri3 *ptin = 0; bool inside = false; double uv[2]; // printf("inserting %g %g\n",center[0],center[1]); - ptin = search4Triangle (worst, center, Us, Vs, AllTris,uv); + ptin = search4Triangle (worst, center, Us, Vs, AllTris,uv, oneNewTriangle ? true : false); if (ptin) inside = true; if (inside) { @@ -767,9 +784,12 @@ static bool insertAPoint(GFace *gf, std::set<MTri3*,compareTri3Ptr>::iterator it Us.push_back(center[0]); Vs.push_back(center[1]); + + // clock_t t1 = clock(); + if(!p.succeeded() || !insertVertex (false, gf, v, center, ptin, AllTris,ActiveTris, vSizes, vSizesBGM,vMetricsBGM, - Us, Vs, metric) ) { + Us, Vs, metric, oneNewTriangle) ) { // Msg::Debug("Point %g %g cannot be inserted because %d", // center[0], center[1], p.succeeded() ); // printf("Point %g %g cannot be inserted because %d", @@ -782,6 +802,8 @@ static bool insertAPoint(GFace *gf, std::set<MTri3*,compareTri3Ptr>::iterator it } else { // printf("done ! %d\n",AllTris.size()); + // clock_t t2 = clock(); + // DT_INSERT_VERTEX += (double)(t2-t1)/CLOCKS_PER_SEC; gf->mesh_vertices.push_back(v); return true; } @@ -1421,7 +1443,7 @@ void buildBackGroundMesh (GFace *gf) int CurvControl = CTX::instance()->mesh.lcFromCurvature; CTX::instance()->mesh.lcFromCurvature = 0; // Do a background mesh - bowyerWatson(gf); + bowyerWatson(gf,4000); // Re-enable curv control if asked CTX::instance()->mesh.lcFromCurvature = CurvControl; // apply this to the BGM @@ -1577,9 +1599,10 @@ void bowyerWatsonParallelograms(GFace *gf) std::vector<double> vSizes, vSizesBGM, Us, Vs; std::vector<SMetric3> vMetricsBGM; std::vector<MVertex*> packed; + std::vector<SMetric3> metrics; printf("creating the points\n"); - packingOfParallelograms(gf, packed); + packingOfParallelograms(gf, packed, metrics); printf("points created\n"); buildMeshGenerationDataStructures @@ -1591,8 +1614,14 @@ void bowyerWatsonParallelograms(GFace *gf) // printf("CARNAVAL !!!\n"); - // std::sort(packed.begin(), packed.end(), lexicographicSort()); + std::sort(packed.begin(), packed.end(), MVertexLessThanLexicographic()); + printf("staring to insert points\n"); + N_GLOBAL_SEARCH = 0; + N_SEARCH = 0; + DT_INSERT_VERTEX = 0; + clock_t t1 = clock(); + MTri3 *oneNewTriangle = 0; for (unsigned int i=0;i<packed.size();){ MTri3 *worst = *AllTris.begin(); if (worst->isDeleted()){ @@ -1607,12 +1636,35 @@ void bowyerWatsonParallelograms(GFace *gf) delete packed[i]; double metric[3]; buildMetric(gf, newPoint, metric); + SMetric3 ANIZO_MESH = metrics[i]; + bool success = insertAPoint(gf, AllTris.begin(), newPoint, metric, Us, Vs, vSizes, - vSizesBGM, vMetricsBGM, AllTris, 0, worst); - if (!success) printf("success %d %d\n", success, (int)AllTris.size()); + vSizesBGM, vMetricsBGM, AllTris, 0, oneNewTriangle, &oneNewTriangle); + if (!success) oneNewTriangle = 0; + // if (!success)printf("success %d %d\n",success,AllTris.size()); i++; } + + if(1.0* AllTris.size() > 2.5 * vSizes.size()){ + int n1 = AllTris.size(); + std::set<MTri3*,compareTri3Ptr>::iterator itd = AllTris.begin(); + while(itd != AllTris.end()){ + if((*itd)->isDeleted()){ + delete *itd; + AllTris.erase(itd++); + } + else + itd++; + } + // Msg::Info("cleaning up the memory %d -> %d", n1, AllTris.size()); + } + + } + printf("%d vertices \n",packed.size()); + clock_t t2 = clock(); + double DT = (double)(t2-t1)/CLOCKS_PER_SEC; + if (packed.size())printf("points inserted DT %12.5E points per minut : %12.5E %d global searchs %d seachs per insertion\n",DT,60.*packed.size()/DT,N_GLOBAL_SEARCH,N_SEARCH / packed.size()); transferDataStructure(gf, AllTris, Us, Vs); backgroundMesh::unset(); }