diff --git a/Fltk/Callbacks.cpp b/Fltk/Callbacks.cpp index 997b39fd5672e4717fb129d2167c9c3488588931..34bac55ba99ee99fce1230af4d51bface8b8c814 100644 --- a/Fltk/Callbacks.cpp +++ b/Fltk/Callbacks.cpp @@ -1,4 +1,4 @@ -// $Id: Callbacks.cpp,v 1.445 2006-08-20 14:12:40 geuzaine Exp $ +// $Id: Callbacks.cpp,v 1.446 2006-08-20 17:02:27 geuzaine Exp $ // // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle // @@ -1112,12 +1112,12 @@ void mesh_options_ok_cb(CALLBACK_ARGS) opt_mesh_constrained_bgmesh(0, GMSH_SET, WID->mesh_butt[5]->value()); opt_mesh_points(0, GMSH_SET, WID->mesh_butt[6]->value()); opt_mesh_lines(0, GMSH_SET, WID->mesh_butt[7]->value()); - opt_mesh_triangles(0, GMSH_SET, WID->mesh_menu_butt->menu()[0].value()); - opt_mesh_quadrangles(0, GMSH_SET, WID->mesh_menu_butt->menu()[1].value()); - opt_mesh_tetrahedra(0, GMSH_SET, WID->mesh_menu_butt->menu()[2].value()); - opt_mesh_hexahedra(0, GMSH_SET, WID->mesh_menu_butt->menu()[3].value()); - opt_mesh_prisms(0, GMSH_SET, WID->mesh_menu_butt->menu()[4].value()); - opt_mesh_pyramids(0, GMSH_SET, WID->mesh_menu_butt->menu()[5].value()); + opt_mesh_triangles(0, GMSH_SET, WID->mesh_menu_butt->menu()[0].value() ? 1 : 0); + opt_mesh_quadrangles(0, GMSH_SET, WID->mesh_menu_butt->menu()[1].value() ? 1 : 0); + opt_mesh_tetrahedra(0, GMSH_SET, WID->mesh_menu_butt->menu()[2].value() ? 1 : 0); + opt_mesh_hexahedra(0, GMSH_SET, WID->mesh_menu_butt->menu()[3].value() ? 1 : 0); + opt_mesh_prisms(0, GMSH_SET, WID->mesh_menu_butt->menu()[4].value() ? 1 : 0); + opt_mesh_pyramids(0, GMSH_SET, WID->mesh_menu_butt->menu()[5].value() ? 1 : 0); opt_mesh_surfaces_edges(0, GMSH_SET, WID->mesh_butt[8]->value()); opt_mesh_surfaces_faces(0, GMSH_SET, WID->mesh_butt[9]->value()); opt_mesh_volumes_edges(0, GMSH_SET, WID->mesh_butt[10]->value()); diff --git a/Geo/MRep.h b/Geo/MRep.h index da0a64355deb6d742fe9d95d6e3e8853b1f7ecca..625c8ed7c4d6abd25ee19df77851a01cf1ff24b1 100644 --- a/Geo/MRep.h +++ b/Geo/MRep.h @@ -54,7 +54,14 @@ class MRep { public: MRep() : va_lines(0), va_triangles(0), va_quads(0), allElementsVisible(true) {} - virtual ~MRep(){} + virtual ~MRep(){ destroy(); } + + // destroy everything + void destroy(){ + resetArrays(); + edges.clear(); + allElementsVisible = true; + } // generates the edge representation virtual void generateEdgeRep() = 0; diff --git a/Mesh/Makefile b/Mesh/Makefile index 273162b322a3cba8c82c937dc946a9aba990d214..c43f4a73d9a58de872cf8828ae80243591d6df8a 100644 --- a/Mesh/Makefile +++ b/Mesh/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.123 2006-08-20 14:12:41 geuzaine Exp $ +# $Id: Makefile,v 1.124 2006-08-20 17:02:28 geuzaine Exp $ # # Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle # @@ -472,8 +472,10 @@ SecondOrder.o: SecondOrder.cpp ../Geo/GModel.h ../Geo/GVertex.h \ ../Common/Context.h ../DataStr/List.h ../Geo/GFace.h ../Geo/GPoint.h \ ../Geo/GEntity.h ../Geo/MElement.h ../Geo/SPoint2.h ../Geo/SVector3.h \ ../Geo/Pair.h ../Geo/GRegion.h ../Geo/GEntity.h ../Geo/MElement.h \ - ../Geo/SBoundingBox3d.h ../Common/SmoothNormals.h ../Common/Message.h \ - ../Common/OS.h + ../Geo/SBoundingBox3d.h ../Common/SmoothNormals.h ../Geo/MRep.h \ + ../Geo/GEdge.h ../Geo/GFace.h ../Geo/GRegion.h ../Geo/MVertex.h \ + ../Geo/MEdge.h ../Geo/MElement.h ../Common/VertexArray.h \ + ../Common/Message.h ../Common/OS.h # 1 "/Users/geuzaine/.gmsh/Mesh//" PartitionMesh.o: PartitionMesh.cpp ../Common/Gmsh.h ../Common/Message.h \ ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \ diff --git a/Mesh/SecondOrder.cpp b/Mesh/SecondOrder.cpp index 66e3703fee9a7356c284376a8ae2d319df004144..f737b56fcd6ec5cab69fec2804061851b95956f2 100644 --- a/Mesh/SecondOrder.cpp +++ b/Mesh/SecondOrder.cpp @@ -1,4 +1,4 @@ -// $Id: SecondOrder.cpp,v 1.41 2006-08-20 14:12:42 geuzaine Exp $ +// $Id: SecondOrder.cpp,v 1.42 2006-08-20 17:02:28 geuzaine Exp $ // // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle // @@ -23,139 +23,238 @@ #include "GFace.h" #include "GEdge.h" #include "MElement.h" +#include "MRep.h" #include "Message.h" #include "OS.h" extern GModel *GMODEL; -// Creation of middle-edge vertices - -MVertex *addEdgeVertex(GEdge *e, std::pair<MVertex*, MVertex*> &p, bool linear) +void getEdgeVertices(GEdge *ge, MElement *ele, std::vector<MVertex*> &ve, + std::map<std::pair<MVertex*,MVertex*>, MVertex* > &edgeVertices, + bool linear) { - MVertex *v0(p.first), *v1(p.second), *v; - MEdge edge(v0, v1); - - if(linear){ - SPoint3 pc = edge.barycenter(); - v = new MVertex(pc.x(), pc.y(), pc.z(), e); - } - else{ - double u0 = 1e6, u1 = 1e6; - Range<double> bounds = e->parBounds(0); - if(e->getBeginVertex()->mesh_vertices.size() && - e->getBeginVertex()->mesh_vertices[0] == v0) - u0 = bounds.low(); - else if(e->getEndVertex()->mesh_vertices.size() && - e->getEndVertex()->mesh_vertices[0] == v0) - u0 = bounds.high(); - else - v0->getParameter(0, u0); - if(e->getBeginVertex()->mesh_vertices.size() && - e->getBeginVertex()->mesh_vertices[0] == v1) - u1 = bounds.low(); - else if(e->getEndVertex()->mesh_vertices.size() && - e->getEndVertex()->mesh_vertices[0] == v1) - u1 = bounds.high(); - else - v1->getParameter(0, u1); - - printf("u12 = %g %g\n", u0, u1); - if(u0 < 1e6 && u1 < 1e6){ - double uc = 0.5 * (u0 + u1); - GPoint pc = e->point(uc); - v = new MEdgeVertex(pc.x(), pc.y(), pc.z(), e, uc); + for(int i = 0; i < ele->getNumEdges(); i++){ + MEdge edge = ele->getEdge(i); + std::pair<MVertex*, MVertex*> p(edge.getMinVertex(), edge.getMaxVertex()); + if(edgeVertices.count(p)){ + ve.push_back(edgeVertices[p]); } else{ - SPoint3 pc = edge.barycenter(); - v = new MVertex(pc.x(), pc.y(), pc.z(), e); + MVertex *v, *v0 = edge.getVertex(0), *v1 = edge.getVertex(1); + if(linear || ge->geomType() == GEntity::DiscreteCurve){ + SPoint3 pc = edge.barycenter(); + v = new MVertex(pc.x(), pc.y(), pc.z(), ge); + } + else{ + double u0 = 1e6, u1 = 1e6; + Range<double> bounds = ge->parBounds(0); + if(ge->getBeginVertex() && ge->getBeginVertex()->mesh_vertices[0] == v0) + u0 = bounds.low(); + else if(ge->getEndVertex() && ge->getEndVertex()->mesh_vertices[0] == v0) + u0 = bounds.high(); + else + v0->getParameter(0, u0); + if(ge->getBeginVertex() && ge->getBeginVertex()->mesh_vertices[0] == v1) + u1 = bounds.low(); + else if(ge->getEndVertex() && ge->getEndVertex()->mesh_vertices[0] == v1) + u1 = bounds.high(); + else + v1->getParameter(0, u1); + if(u0 < 1e6 && u1 < 1e6){ + double uc = 0.5 * (u0 + u1); + GPoint pc = ge->point(uc); + v = new MEdgeVertex(pc.x(), pc.y(), pc.z(), ge, uc); + } + else{ + // we should normally never end up here + SPoint3 pc = edge.barycenter(); + v = new MVertex(pc.x(), pc.y(), pc.z(), ge); + } + } + edgeVertices[p] = v; + ge->mesh_vertices.push_back(v); + ve.push_back(v); } } - e->mesh_vertices.push_back(v); - return v; -} +} -MVertex *addEdgeVertex(GFace *f, std::pair<MVertex* , MVertex*> &p, bool linear) +void getEdgeVertices(GFace *gf, MElement *ele, std::vector<MVertex*> &ve, + std::map<std::pair<MVertex*,MVertex*>, MVertex* > &edgeVertices, + bool linear) { - MVertex *v0(p.first), *v1(p.second), *v; - MEdge edge(v0, v1); - - if(linear){ - SPoint3 pc = edge.barycenter(); - v = new MVertex(pc.x(), pc.y(), pc.z(), f); - } - else{ - SPoint2 p1 = f->parFromPoint(SPoint3(v0->x(), v0->y(), v0->z())); - SPoint2 p2 = f->parFromPoint(SPoint3(v1->x(), v1->y(), v1->z())); - double uc = 0.5 * (p1[0] + p2[0]); - double vc = 0.5 * (p1[1] + p2[1]); - GPoint pc = f->point(uc, vc); - v = new MFaceVertex(pc.x(), pc.y(), pc.z(), f, uc, vc); + for(int i = 0; i < ele->getNumEdges(); i++){ + MEdge edge = ele->getEdge(i); + std::pair<MVertex*, MVertex*> p(edge.getMinVertex(), edge.getMaxVertex()); + if(edgeVertices.count(p)){ + ve.push_back(edgeVertices[p]); + } + else{ + MVertex *v, *v0 = edge.getVertex(0), *v1 = edge.getVertex(1); + if(linear || gf->geomType() == GEntity::DiscreteSurface){ + SPoint3 pc = edge.barycenter(); + v = new MVertex(pc.x(), pc.y(), pc.z(), gf); + } + else{ + SPoint2 p0 = gf->parFromPoint(SPoint3(v0->x(), v0->y(), v0->z())); + SPoint2 p1 = gf->parFromPoint(SPoint3(v1->x(), v1->y(), v1->z())); + double uc = 0.5 * (p0[0] + p1[0]); + double vc = 0.5 * (p0[1] + p1[1]); + GPoint pc = gf->point(uc, vc); + v = new MFaceVertex(pc.x(), pc.y(), pc.z(), gf, uc, vc); + } + edgeVertices[p] = v; + gf->mesh_vertices.push_back(v); + ve.push_back(v); + } } - f->mesh_vertices.push_back(v); - return v; } -MVertex *addEdgeVertex(GRegion *r, std::pair<MVertex* , MVertex*> &p, bool linear) +void getEdgeVertices(GRegion *gr, MElement *ele, std::vector<MVertex*> &ve, + std::map<std::pair<MVertex*,MVertex*>, MVertex* > &edgeVertices, + bool linear) { - MVertex *v0(p.first), *v1(p.second), *v; - MEdge edge(v0, v1); - SPoint3 pc = edge.barycenter(); - v = new MVertex(pc.x(), pc.y(), pc.z(), r); - r->mesh_vertices.push_back(v); - return v; + for(int i = 0; i < ele->getNumEdges(); i++){ + MEdge edge = ele->getEdge(i); + std::pair<MVertex*, MVertex*> p(edge.getMinVertex(), edge.getMaxVertex()); + if(edgeVertices.count(p)){ + ve.push_back(edgeVertices[p]); + } + else{ + SPoint3 pc = edge.barycenter(); + MVertex *v = new MVertex(pc.x(), pc.y(), pc.z(), gr); + edgeVertices[p] = v; + gr->mesh_vertices.push_back(v); + ve.push_back(v); + } + } } -template<class T, class U> -void addEdgeVertices(U *ge, std::vector<T*> &elements, bool linear, - std::map<std::pair<MVertex*,MVertex*>, MVertex* > &edgeVertices) +void getFaceVertices(GFace *gf, MElement *ele, std::vector<MVertex*> &vf, + std::map<std::vector<MVertex*>, MVertex* > &faceVertices, + bool linear) { - for(unsigned int i = 0; i < elements.size(); i++){ - for(int j = 0; j < elements[i]->getNumEdges(); j++){ - MEdge e = elements[i]->getEdge(j); - std::pair<MVertex*, MVertex*> p(e.getMinVertex(), e.getMaxVertex()); - if(!edgeVertices.count(p)) edgeVertices[p] = addEdgeVertex(ge, p, linear); + vf.clear(); + for(int i = 0; i < ele->getNumFaces(); i++){ + MFace face = ele->getFace(i); + if(face.getNumVertices() != 4) continue; + std::vector<MVertex*> p; + face.getOrderedVertices(p); + if(faceVertices.count(p)){ + vf.push_back(faceVertices[p]); + } + else{ + MVertex *v; + if(linear || gf->geomType() == GEntity::DiscreteSurface){ + SPoint3 pc = face.barycenter(); + v = new MVertex(pc.x(), pc.y(), pc.z(), gf); + } + else{ + SPoint2 p0 = gf->parFromPoint(SPoint3(p[0]->x(), p[0]->y(), p[0]->z())); + SPoint2 p1 = gf->parFromPoint(SPoint3(p[1]->x(), p[1]->y(), p[1]->z())); + SPoint2 p2 = gf->parFromPoint(SPoint3(p[2]->x(), p[2]->y(), p[2]->z())); + SPoint2 p3 = gf->parFromPoint(SPoint3(p[3]->x(), p[3]->y(), p[3]->z())); + double uc = 0.25 * (p0[0] + p1[0] + p2[0] + p3[0]); + double vc = 0.25 * (p0[1] + p1[1] + p2[1] + p3[1]); + GPoint pc = gf->point(uc, vc); + v = new MFaceVertex(pc.x(), pc.y(), pc.z(), gf, uc, vc); + } + faceVertices[p] = v; + gf->mesh_vertices.push_back(v); + vf.push_back(v); } } } -// Creation of middle-face vertices - -MVertex *addFaceVertex(GFace *f, std::vector<MVertex*> &p, bool linear) +void getFaceVertices(GRegion *gr, MElement *ele, std::vector<MVertex*> &vf, + std::map<std::vector<MVertex*>, MVertex* > &faceVertices, + bool linear) { - //MVertex *v; - if(linear){ - // just interpolate linear between the 4 + vf.clear(); + for(int i = 0; i < ele->getNumFaces(); i++){ + MFace face = ele->getFace(i); + if(face.getNumVertices() != 4) continue; + std::vector<MVertex*> p; + face.getOrderedVertices(p); + if(faceVertices.count(p)){ + vf.push_back(faceVertices[p]); + } + else{ + SPoint3 pc = face.barycenter(); + MVertex *v = new MVertex(pc.x(), pc.y(), pc.z(), gr); + faceVertices[p] = v; + gr->mesh_vertices.push_back(v); + vf.push_back(v); + } } - else{ - //xyz2uv(); - // interpolate +} + +void setSecondOrder(GEdge *ge, + std::map<std::pair<MVertex*,MVertex*>, MVertex* > &edgeVertices, + bool linear) +{ + std::vector<MLine*> l2; + for(unsigned int i = 0; i < ge->lines.size(); i++){ + MLine *l = ge->lines[i]; + std::vector<MVertex*> ve; + getEdgeVertices(ge, l, ve, edgeVertices, linear); + l2.push_back(new MLine2(l->getVertex(0), l->getVertex(1), ve[0])); + delete l; } - //f->mesh_vertices.push_back(v); - return 0; + ge->lines = l2; + ge->meshRep->destroy(); } -MVertex *addFaceVertex(GRegion *r, std::vector<MVertex*> &p, bool linear) +void setSecondOrder(GFace *gf, + std::map<std::pair<MVertex*,MVertex*>, MVertex* > &edgeVertices, + std::map<std::vector<MVertex*>, MVertex* > &faceVertices, + bool linear) { - //MVertex *v; - // just interpolate linear between the 4 - //r->mesh_vertices.push_back(v); - return 0; + std::vector<MTriangle*> t2; + for(unsigned int i = 0; i < gf->triangles.size(); i++){ + MTriangle *t = gf->triangles[i]; + std::vector<MVertex*> ve; + getEdgeVertices(gf, t, ve, edgeVertices, linear); + t2.push_back(new MTriangle2(t->getVertex(0), t->getVertex(1), t->getVertex(2), + ve[0], ve[1], ve[2])); + delete t; + } + gf->triangles = t2; + + std::vector<MQuadrangle*> q2; + for(unsigned int i = 0; i < gf->quadrangles.size(); i++){ + MQuadrangle *q = gf->quadrangles[i]; + std::vector<MVertex*> ve, vf; + getEdgeVertices(gf, q, ve, edgeVertices, linear); + getFaceVertices(gf, q, vf, faceVertices, linear); + q2.push_back(new MQuadrangle2(q->getVertex(0), q->getVertex(1), q->getVertex(2), + q->getVertex(3), ve[0], ve[1], ve[2], ve[3], vf[0])); + delete q; + } + gf->quadrangles = q2; + + gf->meshRep->destroy(); } -template<class T, class U> -void addFaceVertices(U *ge, std::vector<T*> &elements, bool linear, - std::map<std::vector<MVertex*>, MVertex* > &faceVertices) +void setSecondOrder(GRegion *gr, + std::map<std::pair<MVertex*,MVertex*>, MVertex* > &edgeVertices, + std::map<std::vector<MVertex*>, MVertex* > &faceVertices, + bool linear) { - for(unsigned int i = 0; i < elements.size(); i++){ - for(int j = 0; j < elements[i]->getNumFaces(); j++){ - MFace f = elements[i]->getFace(j); - if(f.getNumVertices() == 4){ - std::vector<MVertex*> p; - f.getOrderedVertices(p); - if(!faceVertices.count(p)) faceVertices[p] = addFaceVertex(ge, p, linear); - } - } + std::vector<MTetrahedron*> t2; + for(unsigned int i = 0; i < gr->tetrahedra.size(); i++){ + MTetrahedron *t = gr->tetrahedra[i]; + std::vector<MVertex*> ve; + getEdgeVertices(gr, t, ve, edgeVertices, linear); + t2.push_back(new MTetrahedron2(t->getVertex(0), t->getVertex(1), t->getVertex(2), + t->getVertex(3), + ve[0], ve[1], ve[2], ve[3], ve[4], ve[5])); + delete t; } + gr->tetrahedra = t2; + + // hexa prisms pyr + + gr->meshRep->destroy(); } // Main routines @@ -163,11 +262,11 @@ void addFaceVertices(U *ge, std::vector<T*> &elements, bool linear, void Degre1() { // loop on all elements + // - if polynomialOrder() == 2 // - get their edge/face/volume vertices mark them with setVisibility(-1); // - generate a first order element for each element // - swap lists at the end // loop on all vertices and delete all vertices marked (-1) - } void Degre2(int dim) @@ -175,35 +274,18 @@ void Degre2(int dim) Msg(STATUS1, "Mesh second order..."); double t1 = Cpu(); - //bool linear = true; - bool linear = false; + bool linear = true; + //bool linear = false; std::map<std::pair<MVertex*,MVertex*>, MVertex* > edgeVertices; std::map<std::vector<MVertex*>, MVertex* > faceVertices; - // loop over all elements and create unique edges and faces and - // their associated new vertices - for(GModel::eiter it = GMODEL->firstEdge(); it != GMODEL->lastEdge(); ++it){ - addEdgeVertices(*it, (*it)->lines, linear, edgeVertices); - } - for(GModel::fiter it = GMODEL->firstFace(); it != GMODEL->lastFace(); ++it){ - addEdgeVertices(*it, (*it)->triangles, linear, edgeVertices); - addEdgeVertices(*it, (*it)->quadrangles, linear, edgeVertices); - addFaceVertices(*it, (*it)->quadrangles, linear, faceVertices); - } - for(GModel::riter it = GMODEL->firstRegion(); it != GMODEL->lastRegion(); ++it){ - addEdgeVertices(*it, (*it)->tetrahedra, linear, edgeVertices); - addEdgeVertices(*it, (*it)->hexahedra, linear, edgeVertices); - addEdgeVertices(*it, (*it)->prisms, linear, edgeVertices); - addEdgeVertices(*it, (*it)->pyramids, linear, edgeVertices); - addFaceVertices(*it, (*it)->hexahedra, linear, faceVertices); - addFaceVertices(*it, (*it)->prisms, linear, faceVertices); - addFaceVertices(*it, (*it)->pyramids, linear, faceVertices); - } + for(GModel::eiter it = GMODEL->firstEdge(); it != GMODEL->lastEdge(); ++it) + setSecondOrder(*it, edgeVertices, linear); + for(GModel::fiter it = GMODEL->firstFace(); it != GMODEL->lastFace(); ++it) + setSecondOrder(*it, edgeVertices, faceVertices, linear); + for(GModel::riter it = GMODEL->firstRegion(); it != GMODEL->lastRegion(); ++it) + setSecondOrder(*it, edgeVertices, faceVertices, linear); - printf("%d edges, %d faces\n", edgeVertices.size(), faceVertices.size()); - - // loop on all elements again and create one new element from each - // old one, querying the edge/face maps to get the extra vertices double t2 = Cpu(); Msg(STATUS1, "Mesh second order complete (%g s)", t2 - t1); }