From 4fbec4e23ec897b69b78cc7b6eac7381a8c5d603 Mon Sep 17 00:00:00 2001 From: Jean-Francois Remacle <jean-francois.remacle@uclouvain.be> Date: Sun, 14 Oct 2007 17:30:42 +0000 Subject: [PATCH] *** empty log message *** --- Mesh/BDS.cpp | 129 ++++++++++++++++++++++++++++++++++++++++++++- Mesh/BDS.h | 1 + Mesh/meshGFace.cpp | 87 +++++++++++++++++++++++++++--- 3 files changed, 208 insertions(+), 9 deletions(-) diff --git a/Mesh/BDS.cpp b/Mesh/BDS.cpp index a682301007..ec9bb8a5ce 100644 --- a/Mesh/BDS.cpp +++ b/Mesh/BDS.cpp @@ -1,4 +1,4 @@ -// $Id: BDS.cpp,v 1.81 2007-10-11 14:34:04 remacle Exp $ +// $Id: BDS.cpp,v 1.82 2007-10-14 17:30:42 remacle Exp $ // // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle // @@ -645,6 +645,131 @@ void BDS_Mesh::split_edge(BDS_Edge * e, BDS_Point *mid) } +void BDS_Mesh::saturate_edge(BDS_Edge * e, std::vector<BDS_Point *> &mids) +{ + BDS_Point *op[2]; + BDS_Point *p1 = e->p1; + BDS_Point *p2 = e->p2; + + BDS_Point *pts1[4]; + e->faces(0)->getNodes(pts1); + + int orientation = 0; + for(int i = 0; i < 3; i++) { + if(pts1[i] == p1) { + if(pts1[(i + 1) % 3] == p2) + orientation = 1; + else + orientation = -1; + + break; + } + } + + // printf("sat %d\n",mids.size()); + + // we should project + e->oppositeof(op); + BDS_GeomEntity *g1 = 0, *g2 = 0, *ge = e->g; + + BDS_Edge *p1_op1 = find_edge(p1, op[0], e->faces(0)); + BDS_Edge *op1_p2 = find_edge(op[0], p2, e->faces(0)); + BDS_Edge *p1_op2 = find_edge(p1, op[1], e->faces(1)); + BDS_Edge *op2_p2 = find_edge(op[1], p2, e->faces(1)); + + if(e->faces(0)) { + g1 = e->faces(0)->g; + del_face(e->faces(0)); + } + // not a bug !!! + if(e->faces(0)) { + g2 = e->faces(0)->g; + del_face(e->faces(0)); + } + + // double t_l = e->target_length; + + del_edge(e); + + // create all the sub-edges of e + std::vector<BDS_Edge*> subs; + for (int i=0; i<mids.size()+1; i++) + { + BDS_Point *a,*b; + if (i == 0)a = p1; + else a = mids[i-1]; + if (i == mids.size())b = p2; + else b = mids[i]; + BDS_Edge *sub = new BDS_Edge(a, b); + // printf("%g %g -> %g %g\n",a->X,a->Y,b->X,b->Y); + edges.push_back(sub); + subs.push_back(sub); + sub->g = ge; + } + // create edges that connect op1 and op2 + std::vector<BDS_Edge*> conn1,conn2; + for (int i=0;i<mids.size();i++) + { + BDS_Edge *c1 = new BDS_Edge(mids[i], op[0]); + edges.push_back(c1); + conn1.push_back(c1); + BDS_Edge *c2 = new BDS_Edge(mids[i], op[1]); + edges.push_back(c2); + conn2.push_back(c2); + c1->g = g1; + c2->g = g2; + mids[i]->g = ge; + } + + // create the triangles + + for (int i=0;i<mids.size()+1;i++) + { + BDS_Edge *e1,*e2,*e3=subs[i]; + + // printf("--> %d %g %g ->%d %g %g\n",e3->p1->iD,e3->p1->X,e3->p1->Y,e3->p2->iD,e3->p2->X,e3->p2->Y); + + + if (i==0)e1 = p1_op1; + else e1 = conn1[i-1]; + if (i==mids.size())e2 = op1_p2; + else e2 = conn1[i]; + +// printf("--> %d %g %g ->%d %g %g\n",e1->p1->iD,e1->p1->X,e1->p1->Y,e1->p2->iD,e1->p2->X,e1->p2->Y); +// printf("--> %d %g %g ->%d %g %g\n",e2->p1->iD,e2->p1->X,e2->p1->Y,e2->p2->iD,e2->p2->X,e2->p2->Y); + + BDS_Face *t1; + if(orientation == 1) + t1 = new BDS_Face(e3, e2, e1); + else + t1 = new BDS_Face(e3, e1, e2); + + + if (i==0)e1 = p1_op2; + else e1 = conn2[i-1]; + if (i==mids.size())e2 = op2_p2; + else e2 = conn2[i]; + + BDS_Face *t2; + if(orientation != 1) + t2 = new BDS_Face(e3, e2, e1); + else + t2 = new BDS_Face(e3, e1, e2); + t1->g = g1; + t2->g = g2; + + triangles.push_back(t1); + triangles.push_back(t2); + } + // config has changed + p1->config_modified = true; + p2->config_modified = true; + op[0]->config_modified = true; + op[1]->config_modified = true; +} + + + // This function does actually the swap without taking into account // the feasability of the operation. Those conditions have to be @@ -682,6 +807,7 @@ bool BDS_Mesh::swap_edge(BDS_Edge * e, const BDS_SwapEdgeTest &theTest) // we test if the edge is deleted // return false; + if(e->deleted) return false; @@ -692,6 +818,7 @@ bool BDS_Mesh::swap_edge(BDS_Edge * e, const BDS_SwapEdgeTest &theTest) if(e->g && e->g->classif_degree == 1) return false; + BDS_Point *op[2]; BDS_Point *p1 = e->p1; BDS_Point *p2 = e->p2; diff --git a/Mesh/BDS.h b/Mesh/BDS.h index eabd18d6f8..d3b7c74310 100644 --- a/Mesh/BDS.h +++ b/Mesh/BDS.h @@ -457,6 +457,7 @@ public: bool smooth_point_centroid(BDS_Point * p, GFace *gf); bool move_point(BDS_Point *p , double X, double Y, double Z); void split_edge(BDS_Edge *, BDS_Point *); + void saturate_edge(BDS_Edge *, std::vector<BDS_Point *>&); bool edge_constraint ( BDS_Point *p1, BDS_Point *p2 ); bool recombine_edge ( BDS_Edge *e ); // Global operators diff --git a/Mesh/meshGFace.cpp b/Mesh/meshGFace.cpp index e819f854b4..b9dce76f47 100644 --- a/Mesh/meshGFace.cpp +++ b/Mesh/meshGFace.cpp @@ -1,4 +1,4 @@ -// $Id: meshGFace.cpp,v 1.96 2007-10-11 16:08:23 remacle Exp $ +// $Id: meshGFace.cpp,v 1.97 2007-10-14 17:30:42 remacle Exp $ // // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle // @@ -255,6 +255,14 @@ double NewGetLc(BDS_Edge *e, GFace *f) return 2*linearLength / (l1 + l2); } +double NewGetLc(BDS_Point *p1,BDS_Point *p2, GFace *f) +{ + double linearLength = computeEdgeLinearLength(p1,p2,f); + double l1 = NewGetLc(p1); + double l2 = NewGetLc(p2); + return 2*linearLength / (l1 + l2); +} + bool edgeSwapTest(BDS_Edge *e,GFace *gf) { BDS_Point *op[2]; @@ -318,9 +326,15 @@ bool edgeSwapTestDelaunay(BDS_Edge *e,GFace *gf) double p2x[3] = {e->p2->X,e->p2->Y,e->p2->Z}; double op1x[3] = {op[0]->X,op[0]->Y,op[0]->Z}; double op2x[3] = {op[1]->X,op[1]->Y,op[1]->Z}; + double p1u[2] = {e->p1->u,e->p1->v}; + double p2u[2] = {e->p2->u,e->p2->v}; + double op1u[2] = {op[0]->u,op[0]->v}; + double op2u[2] = {op[1]->u,op[1]->v}; double fourth[3]; fourthPoint(p1x,p2x,op1x,fourth); double result = gmsh::insphere(p1x, p2x, op1x, fourth, op2x) * gmsh::orient3d(p1x, p2x, op1x, fourth); + //double result = gmsh::incircle(p1u, p2u, op1u, op2u) * gmsh::orient2d(p1u, p2u, op1u); + // printf("result = a%12.5E\n",result); return result > 0.; } @@ -404,11 +418,13 @@ void swapEdgePass ( GFace *gf, BDS_Mesh &m, int &nb_swap ) { int result = edgeSwapTestQuality(*it,5); if (result >= 0) - if(edgeSwapTestDelaunay(*it,gf) || result > 0) - if (m.swap_edge ( *it , BDS_SwapEdgeTestParametric())) - nb_swap++; - ++it; + { + if(edgeSwapTestDelaunay(*it,gf) || result > 0) + if (m.swap_edge ( *it , BDS_SwapEdgeTestParametric())) + nb_swap++; + } } + ++it; } } @@ -425,13 +441,18 @@ void splitEdgePass ( GFace *gf, BDS_Mesh &m, double MAXE_, int &nb_split) double lone = NewGetLc ( *it,gf); if ((*it)->numfaces() == 2 && (lone > MAXE_)) { + +// BDS_Point *op[2]; +// (*it)->oppositeof(op); +// double lone1 = NewGetLc ( op[0],mid,gf); +// double lone2 = NewGetLc ( op[1],mid,gf); + const double coord = 0.5; BDS_Point *mid ; mid = m.add_point(++m.MAXPOINTNUMBER, coord * (*it)->p1->u + (1 - coord) * (*it)->p2->u, coord * (*it)->p1->v + (1 - coord) * (*it)->p2->v,gf); - double l1; - // if (BGMExists()) + mid->lcBGM() = BGM_MeshSize(gf, (coord * (*it)->p1->u + (1 - coord) * (*it)->p2->u)*m.scalingU, (coord * (*it)->p1->v + (1 - coord) * (*it)->p2->v)*m.scalingV, @@ -440,6 +461,52 @@ void splitEdgePass ( GFace *gf, BDS_Mesh &m, double MAXE_, int &nb_split) mid->lc() = 0.5 * ( (*it)->p1->lc() + (*it)->p2->lc() ); m.split_edge ( *it, mid ); nb_split++; + } + } + ++it; + } +} + +void saturateEdgePass ( GFace *gf, BDS_Mesh &m, double MAXE_, int &nb_split) +{ + int NN1 = m.edges.size(); + int NN2 = 0; + std::list<BDS_Edge*>::iterator it = m.edges.begin(); + while (1) + { + if (NN2++ >= NN1)break; + if (!(*it)->deleted) + { + double lone = NewGetLc ( *it,gf); + if ((*it)->numfaces() == 2 && (lone > MAXE_)) + { + int nbSub = (int) (lone/MAXE_) ; + // nbSub = std::min(nbSub,2); + // printf("%d %g\n",nbSub,lone/MAXE_); + std::vector<BDS_Point*> mids; + for (int i=0;i<nbSub;i++) + { + const double coord = (double)(i+1)/(nbSub+1); + BDS_Point *mid ; + mid = m.add_point(++m.MAXPOINTNUMBER, + (1.-coord) * (*it)->p1->u + coord * (*it)->p2->u, + (1.-coord) * (*it)->p1->v + coord * (*it)->p2->v,gf); + double l1; + // if (BGMExists()) + mid->lcBGM() = BGM_MeshSize(gf, + ((1.-coord) * (*it)->p1->u + (coord) * (*it)->p2->u)*m.scalingU, + ((1.-coord) * (*it)->p1->v + (coord) * (*it)->p2->v)*m.scalingV, + mid->X,mid->Y,mid->Z); + //mid->lc() = 2./ ( 1./(*it)->p1->lc() + 1./(*it)->p2->lc() ); + mid->lc() = ( (1.-coord)*(*it)->p1->lc() + coord*(*it)->p2->lc() ); + mids.push_back(mid); + // printf("new point %g %g lc %g\n",mid->X,mid->Y,mid->lc()); + } + // printf("saturating an edge with %d points %d triangles\n",mids.size(),m.triangles.size()); + if(nbSub>0)m.saturate_edge ( *it, mids ); + // printf("-> %d triangles\n",m.triangles.size()); + nb_split++; + // if (nb_split == )break; } } ++it; @@ -518,7 +585,7 @@ void RefineMesh ( GFace *gf, BDS_Mesh &m , const int NIT) double t_spl=0, t_sw=0,t_col=0,t_sm=0; - const double MINE_ = 0.7, MAXE_=1.4; + const double MINE_ = 0.67, MAXE_=1.4; while (1) { // we count the number of local mesh modifs. @@ -558,6 +625,7 @@ void RefineMesh ( GFace *gf, BDS_Mesh &m , const int NIT) double minE = MINE_;//std::min(MINE_,minL * 1.2); clock_t t1 = clock(); splitEdgePass ( gf, m, maxE, nb_split); + //saturateEdgePass ( gf, m, maxE, nb_split); clock_t t2 = clock(); swapEdgePass ( gf, m, nb_swap); clock_t t3 = clock(); @@ -567,12 +635,15 @@ void RefineMesh ( GFace *gf, BDS_Mesh &m , const int NIT) clock_t t5 = clock(); smoothVertexPass ( gf, m, nb_smooth); clock_t t6 = clock(); + swapEdgePass ( gf, m, nb_swap); + clock_t t7 = clock(); // clean up the mesh t_spl += (double)(t2-t1)/CLOCKS_PER_SEC; t_sw += (double)(t3-t2)/CLOCKS_PER_SEC; t_sw += (double)(t5-t4)/CLOCKS_PER_SEC; + t_sw += (double)(t7-t6)/CLOCKS_PER_SEC; t_col += (double)(t4-t3)/CLOCKS_PER_SEC; t_sm += (double)(t6-t5)/CLOCKS_PER_SEC; -- GitLab