From 37922a573f5bc3e31d23edccd439eba7d05cc0b5 Mon Sep 17 00:00:00 2001 From: Christophe Geuzaine <cgeuzaine@ulg.ac.be> Date: Mon, 27 Nov 2006 01:33:28 +0000 Subject: [PATCH] extrude edge+face (only "recombined" for now; we'll implement subdivision into simplices "globally" later) --- Common/Context.h | 2 +- Common/DefaultOptions.h | 2 - Common/Options.cpp | 9 +--- Common/Options.h | 1 - Geo/gmshEdge.cpp | 3 +- Geo/gmshRegion.cpp | 3 +- Mesh/Makefile | 3 +- Mesh/meshGEdge.cpp | 58 ++++++++++----------- Mesh/meshGEdge.h | 2 + Mesh/meshGFaceExtruded.cpp | 102 +++++++++++++++++++++++++++---------- 10 files changed, 114 insertions(+), 71 deletions(-) diff --git a/Common/Context.h b/Common/Context.h index 915c2c33be..981c9c3324 100644 --- a/Common/Context.h +++ b/Common/Context.h @@ -185,7 +185,7 @@ public : return val; } int oldxtrude, oldxtrude_recombine; - int allow_degenerated_extrude, save_all, stl_binary, msh_binary, bdf_field_format; + int save_all, stl_binary, msh_binary, bdf_field_format; char *triangle_options; int smooth_normals, reverse_all_normals; double angle_smooth_normals; diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h index b290b3ebcc..7dee45baaf 100644 --- a/Common/DefaultOptions.h +++ b/Common/DefaultOptions.h @@ -841,8 +841,6 @@ StringXNumber MeshOptions_Number[] = { "2D mesh algorithm (1=isotropic, 2=anisotropic, 3=triangle)" }, { F|O, "Algorithm3D" , opt_mesh_algo3d , DELAUNAY_ISO , "3D mesh algorithm (1=isotropic, 4=netgen, 5=tetgen)" }, - { F, "AllowDegeneratedExtrude" , opt_mesh_allow_degenerated_extrude , 0. , - "Allow the generation of degenerated hexahedra or prisms during extrusion" }, { F|O, "AngleSmoothNormals" , opt_mesh_angle_smooth_normals , 30.0 , "Threshold angle below which normals are not smoothed" }, diff --git a/Common/Options.cpp b/Common/Options.cpp index 12aca03032..b4126c403b 100644 --- a/Common/Options.cpp +++ b/Common/Options.cpp @@ -1,4 +1,4 @@ -// $Id: Options.cpp,v 1.317 2006-11-25 20:08:39 geuzaine Exp $ +// $Id: Options.cpp,v 1.318 2006-11-27 01:33:27 geuzaine Exp $ // // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle // @@ -4976,13 +4976,6 @@ double opt_mesh_cut_planed(OPT_ARGS_NUM) return CTX.mesh.cut_planed; } -double opt_mesh_allow_degenerated_extrude(OPT_ARGS_NUM) -{ - if(action & GMSH_SET) - CTX.mesh.allow_degenerated_extrude = (int)val; - return CTX.mesh.allow_degenerated_extrude; -} - double opt_mesh_save_all(OPT_ARGS_NUM) { if(action & GMSH_SET) diff --git a/Common/Options.h b/Common/Options.h index 78f5b802c0..dc6eb0d607 100644 --- a/Common/Options.h +++ b/Common/Options.h @@ -478,7 +478,6 @@ double opt_mesh_cut_planea(OPT_ARGS_NUM); double opt_mesh_cut_planeb(OPT_ARGS_NUM); double opt_mesh_cut_planec(OPT_ARGS_NUM); double opt_mesh_cut_planed(OPT_ARGS_NUM); -double opt_mesh_allow_degenerated_extrude(OPT_ARGS_NUM); double opt_mesh_save_all(OPT_ARGS_NUM); double opt_mesh_color_carousel(OPT_ARGS_NUM); double opt_mesh_nb_nodes(OPT_ARGS_NUM); diff --git a/Geo/gmshEdge.cpp b/Geo/gmshEdge.cpp index caed9ae6ef..4fd610c710 100644 --- a/Geo/gmshEdge.cpp +++ b/Geo/gmshEdge.cpp @@ -1,4 +1,4 @@ -// $Id: gmshEdge.cpp,v 1.19 2006-11-25 16:52:43 geuzaine Exp $ +// $Id: gmshEdge.cpp,v 1.20 2006-11-27 01:33:27 geuzaine Exp $ // // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle // @@ -34,6 +34,7 @@ gmshEdge::gmshEdge(GModel *model, Curve *edge, GVertex *v1, GVertex *v2) meshAttributes.nbPointsTransfinite = c->ipar[0]; meshAttributes.coeffTransfinite = c->dpar[0]; meshAttributes.typeTransfinite = c->ipar[1]; + meshAttributes.extrude = c->Extrude; } gmshEdge::gmshEdge(GModel *model, int num) diff --git a/Geo/gmshRegion.cpp b/Geo/gmshRegion.cpp index 280721bf22..d29ab45453 100644 --- a/Geo/gmshRegion.cpp +++ b/Geo/gmshRegion.cpp @@ -1,4 +1,4 @@ -// $Id: gmshRegion.cpp,v 1.8 2006-11-25 16:52:43 geuzaine Exp $ +// $Id: gmshRegion.cpp,v 1.9 2006-11-27 01:33:27 geuzaine Exp $ // // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle // @@ -39,6 +39,7 @@ gmshRegion::gmshRegion(GModel *m, ::Volume * volume) l_faces.push_back(f); l_dirs.push_back(ori); } + meshAttributes.extrude = volume->Extrude; } gmshRegion::gmshRegion(GModel *m, int num) diff --git a/Mesh/Makefile b/Mesh/Makefile index b290d039e8..5cef9c9845 100644 --- a/Mesh/Makefile +++ b/Mesh/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.147 2006-11-26 04:36:46 geuzaine Exp $ +# $Id: Makefile,v 1.148 2006-11-27 01:33:28 geuzaine Exp $ # # Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle # @@ -32,6 +32,7 @@ CFLAGS = ${OPTIM} ${FLAGS} ${INCLUDE} SRC = Generator.cpp \ meshGEdge.cpp \ + meshGEdgeExtruded.cpp \ meshGFace.cpp \ meshGFaceTransfinite.cpp \ meshGFaceExtruded.cpp \ diff --git a/Mesh/meshGEdge.cpp b/Mesh/meshGEdge.cpp index c8e70dc1b1..cc2ed927de 100644 --- a/Mesh/meshGEdge.cpp +++ b/Mesh/meshGEdge.cpp @@ -1,4 +1,4 @@ -// $Id: meshGEdge.cpp,v 1.19 2006-11-25 18:03:49 geuzaine Exp $ +// $Id: meshGEdge.cpp,v 1.20 2006-11-27 01:33:28 geuzaine Exp $ // // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle // @@ -38,20 +38,20 @@ double F_LC_ANALY (double xx, double yy, double zz) // return 0.005 + 0.05*fabs (sin(5*xx) + sin(15*yy) + sin(15*zz)); // return 0.02; // return 0.002 + 0.04*fabs (sin(6*xx) + sin(6*yy) + sin(6*zz)); - return 0.003 + 0.05*fabs (sin(8*xx) + sin(8*yy) + sin(8*zz)); - return 0.02 + 0.1*fabs (sin(3*xx) + sin(3*yy) + sin(3*zz)); - return 0.01 + 0.1*fabs(sin((xx*xx+(zz-0.7)*(zz-0.7)-.25))) ; - return 0.05 + .1*fabs(xx*yy) ; + return 0.003 + 0.05*fabs(sin(8*xx) + sin(8*yy) + sin(8*zz)); + return 0.02 + 0.1*fabs(sin(3*xx) + sin(3*yy) + sin(3*zz)); + return 0.01 + 0.1*fabs(sin((xx*xx+(zz-0.7)*(zz-0.7)-.25))); + return 0.05 + 0.1*fabs(xx*yy); } -double F_Lc_bis(double t) +double F_Lc(double t) { // const double nb_points_per_radius_of_curv = 2; - GPoint point = _myGEdge -> point(t) ; - const double fact = (t-t_begin)/(t_end-t_begin); - double lc_here = lc_begin + fact * (lc_end-lc_begin); - SVector3 der = _myGEdge -> firstDer(t) ; - const double d = norm(der); + GPoint point = _myGEdge->point(t) ; + const double fact = (t - t_begin) / (t_end - t_begin); + double lc_here = lc_begin + fact * (lc_end - lc_begin); + SVector3 der = _myGEdge->firstDer(t) ; + const double d = norm(der); if(CTX.mesh.bgmesh_type == ONFILE) { const double Lc = BGMXYZ(point.x(), point.y(), point.z()); @@ -64,16 +64,16 @@ double F_Lc_bis(double t) return d/lc_here; } -double F_Transfini_bis(double t) +double F_Transfinite(double t) { double val, r; - SVector3 der = _myGEdge -> firstDer(t) ; + SVector3 der = _myGEdge->firstDer(t) ; double d = norm(der); double coef = _myGEdge->meshAttributes.coeffTransfinite; - int type = _myGEdge->meshAttributes.typeTransfinite; - int nbpt = _myGEdge->meshAttributes.nbPointsTransfinite; + int type = _myGEdge->meshAttributes.typeTransfinite; + int nbpt = _myGEdge->meshAttributes.nbPointsTransfinite; if(coef <= 0.0 || coef == 1.0) { // coef < 0 should never happen @@ -121,9 +121,9 @@ double F_Transfini_bis(double t) return val; } -double F_One_bis(double t) +double F_One(double t) { - SVector3 der = _myGEdge -> firstDer(t) ; + SVector3 der = _myGEdge->firstDer(t) ; return norm(der); } @@ -132,7 +132,7 @@ typedef struct{ double t, lc, p; }IntPoint; -double trapeze(IntPoint * P1, IntPoint * P2) +double trapezoidal(IntPoint * P1, IntPoint * P2) { return (0.5 * (P1->lc + P2->lc) * (P2->t - P1->t)); } @@ -149,9 +149,9 @@ void RecursiveIntegration(IntPoint * from, IntPoint * to, P.t = 0.5 * (from->t + to->t); P.lc = f(P.t); - val1 = trapeze(from, to); - val2 = trapeze(from, &P); - val3 = trapeze(&P, to); + val1 = trapezoidal(from, to); + val2 = trapezoidal(from, &P); + val3 = trapezoidal(&P, to); err = fabs(val1 - val2 - val3); // Msg(INFO,"Int %22.15 E %22.15 E %22.15 E\n", val1,val2,val3); @@ -210,6 +210,8 @@ void meshGEdge :: operator() (GEdge *ge) deMeshGEdge dem; dem(ge); + if(MeshExtrudedCurve(ge)) return; + // Create a list of integration points List_T *Points = List_Create(10, 10, sizeof(IntPoint)); @@ -218,31 +220,30 @@ void meshGEdge :: operator() (GEdge *ge) // to pass an extra argument... _myGEdge = ge; - // compute bounds _myGEdgeBounds = ge->parBounds(0) ; t_begin = _myGEdgeBounds.low(); - t_end = _myGEdgeBounds.high(); + t_end = _myGEdgeBounds.high(); // first compute the length of the curve by integrating one _myGEdgeLength = Integration(_myGEdgeBounds.low(), _myGEdgeBounds.high(), - F_One_bis, Points, 1.e-4); + F_One, Points, 1.e-4); List_Reset(Points); - lc_begin = _myGEdge->getBeginVertex()->prescribedMeshSizeAtVertex(); - lc_end = _myGEdge->getEndVertex()->prescribedMeshSizeAtVertex(); + lc_begin = _myGEdge->getBeginVertex()->prescribedMeshSizeAtVertex(); + lc_end = _myGEdge->getEndVertex()->prescribedMeshSizeAtVertex(); // Integrate detJ/lc du double a; int N; if(ge->meshAttributes.Method == TRANSFINI){ a = Integration(_myGEdgeBounds.low(), _myGEdgeBounds.high(), - F_Transfini_bis, Points, 1.e-7); + F_Transfinite, Points, 1.e-7); N = ge->meshAttributes.nbPointsTransfinite; } else{ a = Integration(_myGEdgeBounds.low(), _myGEdgeBounds.high(), - F_Lc_bis, Points, 1.e-4); + F_Lc, Points, 1.e-4); N = std::max(ge->minimumMeshSegments() + 1, (int)(a + 1.)); } const double b = a / (double)(N - 1); @@ -282,4 +283,3 @@ void meshGEdge :: operator() (GEdge *ge) ge->lines.push_back(new MLine(v0, v1)); } } - diff --git a/Mesh/meshGEdge.h b/Mesh/meshGEdge.h index 40d22be02b..03bce0c693 100644 --- a/Mesh/meshGEdge.h +++ b/Mesh/meshGEdge.h @@ -35,4 +35,6 @@ class deMeshGEdge void operator () ( GEdge * ); }; +int MeshExtrudedCurve(GEdge *ge); + #endif diff --git a/Mesh/meshGFaceExtruded.cpp b/Mesh/meshGFaceExtruded.cpp index 7264c806bf..68e9554a84 100644 --- a/Mesh/meshGFaceExtruded.cpp +++ b/Mesh/meshGFaceExtruded.cpp @@ -1,4 +1,4 @@ -// $Id: meshGFaceExtruded.cpp,v 1.4 2006-11-26 21:56:26 geuzaine Exp $ +// $Id: meshGFaceExtruded.cpp,v 1.5 2006-11-27 01:33:28 geuzaine Exp $ // // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle // @@ -24,7 +24,8 @@ #include "GModel.h" #include "Message.h" -int extrudeMesh(GEdge *from, GFace *to) +void extrudeMesh(GEdge *from, GFace *to, + std::set<MVertex*, MVertexLessThanLexicographic> &pos) { ExtrudeParams *ep = to->meshAttributes.extrude; @@ -32,35 +33,69 @@ int extrudeMesh(GEdge *from, GFace *to) for(unsigned int i = 0; i < from->mesh_vertices.size(); i++){ MVertex *v = from->mesh_vertices[i]; for(int j = 0; j < ep->mesh.NbLayer; j++) { - for(int k = 1; k < ep->mesh.NbElmLayer[j]; k++) { + for(int k = 0; k < ep->mesh.NbElmLayer[j]; k++) { double x = v->x(), y = v->y(), z = v->z(); - ep->Extrude(j, k, x, y, z); - to->mesh_vertices.push_back(new MVertex(x, y, z, to)); + ep->Extrude(j, k + 1, x, y, z); + if(j != ep->mesh.NbLayer - 1 || k != ep->mesh.NbElmLayer[j] - 1){ + MVertex *newv = new MVertex(x, y, z, to); + to->mesh_vertices.push_back(newv); + pos.insert(newv); + } } } } // create elements + std::set<MVertex*, MVertexLessThanLexicographic>::iterator itp; + for(unsigned int i = 0; i < from->lines.size(); i++){ + MVertex *v0 = from->lines[i]->getVertex(0); + MVertex *v1 = from->lines[i]->getVertex(1); + for(int j = 0; j < ep->mesh.NbLayer; j++) { + for(int k = 0; k < ep->mesh.NbElmLayer[j]; k++) { + std::vector<MVertex*> verts; + double x[4], y[4], z[4]; + x[0] = v0->x(); y[0] = v0->y(); z[0] = v0->z(); + ep->Extrude(j, k, x[0], y[0], z[0]); + x[1] = v1->x(); y[1] = v1->y(); z[1] = v1->z(); + ep->Extrude(j, k, x[1], y[1], z[1]); + x[2] = v0->x(); y[2] = v0->y(); z[2] = v0->z(); + ep->Extrude(j, k + 1, x[2], y[2], z[2]); + x[3] = v1->x(); y[3] = v1->y(); z[3] = v1->z(); + ep->Extrude(j, k + 1, x[3], y[3], z[3]); + for(int p = 0; p < 4; p++){ + MVertex tmp(x[p], y[p], z[p], 0, -1); + itp = pos.find(&tmp); + if(itp == pos.end()) { + Msg(GERROR, "Could not find extruded vertex in surface %d", to->tag()); + return; + } + verts.push_back(*itp); + } + if(verts[0] == verts[1] || verts[1] == verts[3]){ + to->triangles.push_back(new MTriangle(verts[0], verts[3], verts[2])); + } + else if(verts[0] == verts[2] || verts[2] == verts[3]){ + to->triangles.push_back(new MTriangle(verts[0], verts[1], verts[3])); + } + else if(verts[0] == verts[3] || verts[1] == verts[2]){ + Msg(GERROR, "Uncoherent quadrangle in extrusion"); + return; + } + else{ + to->quadrangles.push_back(new MQuadrangle(verts[0], verts[1], + verts[3], verts[2])); + } + } + } + } } -int copyMesh(GFace *from, GFace *to) +void copyMesh(GFace *from, GFace *to, + std::set<MVertex*, MVertexLessThanLexicographic> &pos) { ExtrudeParams *ep = to->meshAttributes.extrude; - // build a set with all the vertices on the boundary of to - std::set<MVertex*, MVertexLessThanLexicographic> pos; - std::list<GEdge*> edges = to->edges(); - std::list<GEdge*>::iterator it = edges.begin(); - while(it != edges.end()){ - pos.insert((*it)->mesh_vertices.begin(), (*it)->mesh_vertices.end()); - pos.insert((*it)->getBeginVertex()->mesh_vertices.begin(), - (*it)->getBeginVertex()->mesh_vertices.end()); - pos.insert((*it)->getEndVertex()->mesh_vertices.begin(), - (*it)->getEndVertex()->mesh_vertices.end()); - ++it; - } - - // create new vertices + // create vertices for(unsigned int i = 0; i < from->mesh_vertices.size(); i++){ MVertex *v = from->mesh_vertices[i]; double x = v->x(), y = v->y(), z = v->z(); @@ -71,19 +106,19 @@ int copyMesh(GFace *from, GFace *to) pos.insert(newv); } - // create new elements + // create elements std::set<MVertex*, MVertexLessThanLexicographic>::iterator itp; for(unsigned int i = 0; i < from->triangles.size(); i++){ std::vector<MVertex*> verts; for(int j = 0; j < 3; j++){ MVertex *v = from->triangles[i]->getVertex(j); - MVertex tmp(v->x(), v->y(), v->z(), 0, 0); + MVertex tmp(v->x(), v->y(), v->z(), 0, -1); ep->Extrude(ep->mesh.NbLayer - 1, ep->mesh.NbElmLayer[ep->mesh.NbLayer - 1], tmp.x(), tmp.y(), tmp.z()); itp = pos.find(&tmp); if(itp == pos.end()) { Msg(GERROR, "Could not find extruded vertex in surface %d", to->tag()); - return 0; + return; } verts.push_back(*itp); } @@ -93,13 +128,13 @@ int copyMesh(GFace *from, GFace *to) std::vector<MVertex*> verts; for(int j = 0; j < 4; j++){ MVertex *v = from->quadrangles[i]->getVertex(j); - MVertex tmp(v->x(), v->y(), v->z(), 0, 0); + MVertex tmp(v->x(), v->y(), v->z(), 0, -1); ep->Extrude(ep->mesh.NbLayer - 1, ep->mesh.NbElmLayer[ep->mesh.NbLayer - 1], tmp.x(), tmp.y(), tmp.z()); itp = pos.find(&tmp); if(itp == pos.end()) { Msg(GERROR, "Could not find extruded vertex in surface %d", to->tag()); - return 0; + return; } verts.push_back(*itp); } @@ -114,17 +149,30 @@ int MeshExtrudedSurface(GFace *gf) if(!ep || !ep->mesh.ExtrudeMesh) return 0; + // build a set with all the vertices on the boundary of gf + std::set<MVertex*, MVertexLessThanLexicographic> pos; + std::list<GEdge*> edges = gf->edges(); + std::list<GEdge*>::iterator it = edges.begin(); + while(it != edges.end()){ + pos.insert((*it)->mesh_vertices.begin(), (*it)->mesh_vertices.end()); + pos.insert((*it)->getBeginVertex()->mesh_vertices.begin(), + (*it)->getBeginVertex()->mesh_vertices.end()); + pos.insert((*it)->getEndVertex()->mesh_vertices.begin(), + (*it)->getEndVertex()->mesh_vertices.end()); + ++it; + } + if(ep->geo.Mode == EXTRUDED_ENTITY) { // surface is extruded from a curve GEdge *from = gf->model()->edgeByTag(std::abs(ep->geo.Source)); if(!from) return 0; - extrudeMesh(from, gf); + extrudeMesh(from, gf, pos); } else { // surface is a copy of another surface ("chapeau") GFace *from = gf->model()->faceByTag(std::abs(ep->geo.Source)); if(!from) return 0; - copyMesh(from, gf); + copyMesh(from, gf, pos); } return 1; -- GitLab