From 179fa592ce0c73be01091d10cfde8f21db8681e2 Mon Sep 17 00:00:00 2001 From: Jean-Francois Remacle <jean-francois.remacle@uclouvain.be> Date: Thu, 13 Feb 2014 10:15:39 +0000 Subject: [PATCH] addded an option to delaunay 3D --- Mesh/meshGRegionDelaunayInsertion.cpp | 108 ++++++++++++++++---------- Mesh/meshGRegionDelaunayInsertion.h | 2 +- 2 files changed, 68 insertions(+), 42 deletions(-) diff --git a/Mesh/meshGRegionDelaunayInsertion.cpp b/Mesh/meshGRegionDelaunayInsertion.cpp index 525bcce4fe..285fe3ade7 100644 --- a/Mesh/meshGRegionDelaunayInsertion.cpp +++ b/Mesh/meshGRegionDelaunayInsertion.cpp @@ -365,39 +365,40 @@ void recurFindCavity(std::vector<faceXtet> & shell, int circ = neigh->inCircumSphere(v); if (circ && (neigh->onWhat() == t->onWhat())) recurFindCavity(shell, cavity, v, neigh); - else{ - shell.push_back(fxt); - } + else + shell.push_back(fxt); } } } -void nonrecurFindCavity(std::list<faceXtet> & shell, - std::list<MTet4*> & cavity, - MVertex *v , - MTet4 *t) +void nonrecurFindCavity(std::vector<faceXtet> & shell, + std::vector<MTet4*> & cavity, + MVertex *v , + MTet4 *t, + std::stack<MTet4*> &_stack) { - 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)); + if (!t->isDeleted()){ + t->setDeleted(true); + cavity.push_back(t); + + for (int i = 0; i < 4; i++){ + MTet4 *neigh = t->getNeigh(i) ; + faceXtet fxt (t, i); + if (!neigh) + shell.push_back(fxt); + else if (!neigh->isDeleted()){ + int circ = neigh->inCircumSphere(v); + if (circ && (neigh->onWhat() == t->onWhat())) + _stack.push(neigh); + else + shell.push_back(fxt); + } } } } @@ -1696,14 +1697,17 @@ int straddling_segment_intersects_triangle(SPoint3 &p1,SPoint3 &p2, double s2 = robustPredicates::orient3d(p1, p2, q3, q1); double s3 = robustPredicates::orient3d(p1, p2, q1, q2); + if (s1*s2 < 0.0 || s2 * s3 < 0.0) return false; + + double s4 = robustPredicates::orient3d(q1, q2, q3, p1); double s5 = robustPredicates::orient3d(q3, q2, q1, p2); - return (s1*s2 >= 0.0 && s2 * s3 >= 0.0 && s4*s5 >= 0) ; + return (s4*s5 >= 0) ; } -int intersect_line_triangle(double X[3], double Y[3], double Z[3] , - double P[3], double N[3], double); +//int intersect_line_triangle(double X[3], double Y[3], double Z[3] , +// double P[3], double N[3], double); static MTet4* search4Tet (MTet4 *t, MVertex *v, int _size,int & ITER) { if (t->inCircumSphere(v)) return t; @@ -1718,7 +1722,7 @@ static MTet4* search4Tet (MTet4 *t, MVertex *v, int _size,int & ITER) { // t->setDeleted(true); SPoint3 p1 = t->tet()->barycenter(); int found = -1; - int nbIntersect = 0; + // int nbIntersect = 0; MTet4 *neighOK = 0; for (int i = 0; i < 4; i++){ MTet4 *neigh = t->getNeigh(i); @@ -1738,8 +1742,8 @@ static MTet4* search4Tet (MTet4 *t, MVertex *v, int _size,int & ITER) { if ( straddling_segment_intersects_triangle (p1,p2,q1,q2,q3)){ // if (intersect_line_triangle(X,Y,Z,p1,p1-p2, 0.0) > 0) { found = i; - nbIntersect++; - //break; + // nbIntersect++; + break; } } } @@ -1774,7 +1778,7 @@ MTet4 * getTetToBreak (MVertex *v, std::vector<MTet4*> &t, int &NB_GLOBAL_SEARCH MTet4 *start = t[k]; start = search4Tet (start,v,(int)t.size(),ITER); if (start)return start; - printf("Global Search has to be done\n"); + // printf("Global Search has to be done\n"); NB_GLOBAL_SEARCH++; for (size_t i = 0;i<t.size();i++){ if (!t[i]->isDeleted() && t[i]->inCircumSphere(v))return t[i]; @@ -1789,13 +1793,15 @@ bool tetOnBox (MTetrahedron *t, MVertex *box[8]){ return false; } -void delaunayMeshIn3D(std::vector<MVertex*> &v, std::vector<MTetrahedron*> &result) + void delaunayMeshIn3D(std::vector<MVertex*> &v, std::vector<MTetrahedron*> &result, bool removeBox) { + removeBox = false; std::vector<MTet4*> t; t.reserve (v.size()*7); std::vector<faceXtet> conn; std::vector<faceXtet> shell; std::vector<MTet4*> cavity; + // std::stack<MTet4*> _stack; MVertex *box[8]; initialCube (v,box,t); @@ -1803,13 +1809,17 @@ void delaunayMeshIn3D(std::vector<MVertex*> &v, std::vector<MTetrahedron*> &resu int AVG_ITER = 0; SortHilbert(v); double t1 = Cpu(); + + double ta=0,tb=0,tc=0,td=0,T; for (size_t i=0;i<v.size();i++){ MVertex *pv = v[i]; // if (i%10000 == 0)printf("PT(%7d)\n",i); int NITER = 0; + T = Cpu(); MTet4 * found = getTetToBreak (pv,t,NB_GLOBAL_SEARCH,NITER); + ta += Cpu()-T; // printf("NITER = %d\n",NITER); AVG_ITER += NITER; if(!found) { @@ -1818,9 +1828,22 @@ void delaunayMeshIn3D(std::vector<MVertex*> &v, std::vector<MTetrahedron*> &resu } shell.clear(); cavity.clear(); + T = Cpu(); recurFindCavity(shell, cavity, pv, found); + tb += Cpu()-T; + // int cs = cavity.size(),ss=shell.size(); + double V = 0.0; + for (unsigned int k=0;k<cavity.size();k++)V+=fabs(cavity[k]->tet()->getVolume()); + // shell.clear(); + // cavity.clear(); + // recurFindCavity(shell, cavity, pv, found); + // printf("%d %d -- %d %d\n",cs,cavity.size(),ss,shell.size()); + std::vector<MTet4*> extended_cavity; + double Vb = 0.0; + + T = Cpu(); for (unsigned int count = 0; count < shell.size(); count++){ const faceXtet &fxt = shell[count]; MTetrahedron *tr; @@ -1842,10 +1865,15 @@ void delaunayMeshIn3D(std::vector<MVertex*> &v, std::vector<MTetrahedron*> &resu t4 = new MTet4(tr, 0.0); t.push_back(t4); } + Vb+= fabs(tr->getVolume()); extended_cavity.push_back(t4); if (otherSide) extended_cavity.push_back(otherSide); } + tc += Cpu()-T; + + if (fabs(Vb-V) > 1.e-8 * (Vb+V))printf("%12.5E %12.5E\n",Vb,V); + // reuse memory --> reinitialize MTet4s for (unsigned int k=0;k<cavity.size();k++){ cavity[k]->setDeleted(false); @@ -1853,22 +1881,20 @@ void delaunayMeshIn3D(std::vector<MVertex*> &v, std::vector<MTetrahedron*> &resu cavity[k]->setNeigh(l,0); } } - - // printf("connecting %i tets\n",extended_cavity.size()); + T = Cpu(); connectTets_vector2(extended_cavity,conn); - // printf("done\n"); - //connectTets_vector(extended_cavity.begin(),extended_cavity.end()); + td += Cpu()-T; } double t2 = Cpu(); Msg::Info("Delaunay 3D done for %d points : CPU = %g, %d global searches, AVG walk size %g",v.size(), t2-t1,NB_GLOBAL_SEARCH,1.+(double)AVG_ITER/v.size()); // printf("%d tets allocated (to compare with 7 #V = %d)\n",t.size(),7*v.size()); - + // printf("%g %g %g %g --> %g(%g)\n",ta,tb,tc,td,t2-t1,ta+tb+tc+td); - //FILE *f = fopen ("tet.pos","w"); + // FILE *f = fopen ("tet.pos","w"); // fprintf(f,"View \"\"{\n"); for (size_t i = 0;i<t.size();i++){ - if (t[i]->isDeleted() || tetOnBox (t[i]->tet(),box)) delete t[i]->tet(); + if (t[i]->isDeleted() || (removeBox && tetOnBox (t[i]->tet(),box))) delete t[i]->tet(); else { result.push_back(t[i]->tet()); // t[i]->tet()->writePOS (f, false,false,true,false,false,false); @@ -1876,9 +1902,9 @@ void delaunayMeshIn3D(std::vector<MVertex*> &v, std::vector<MTetrahedron*> &resu delete t[i]; } - for (int i=0;i<8;i++)delete box[i]; - + if (removeBox)for (int i=0;i<8;i++)delete box[i]; + else for (int i=0;i<8;i++)v.push_back(box[i]); + // fprintf(f,"};\n"); // fclose(f); } - diff --git a/Mesh/meshGRegionDelaunayInsertion.h b/Mesh/meshGRegionDelaunayInsertion.h index df64be601a..996c8c75e2 100644 --- a/Mesh/meshGRegionDelaunayInsertion.h +++ b/Mesh/meshGRegionDelaunayInsertion.h @@ -175,7 +175,7 @@ class MTet4 void connectTets(std::list<MTet4*> &); void connectTets(std::vector<MTet4*> &); // IN --> Vertices ---- OUT --> Tets -void delaunayMeshIn3D(std::vector<MVertex*> &, std::vector<MTetrahedron*> &); +void delaunayMeshIn3D(std::vector<MVertex*> &, std::vector<MTetrahedron*> &, bool removeBox = true); void insertVerticesInRegion(GRegion *gr, int maxVert = 2000000000, bool _classify = true); void bowyerWatsonFrontalLayers(GRegion *gr, bool hex); GRegion *getRegionFromBoundingFaces(GModel *model, -- GitLab