From f78a08a8cbf904d2081a4cd1ed31f289a0e4380d Mon Sep 17 00:00:00 2001 From: Christophe Geuzaine <cgeuzaine@ulg.ac.be> Date: Fri, 26 Jan 2007 17:51:56 +0000 Subject: [PATCH] - nicer display of second order elements (don't draw internal edges) - nicer display of second order vertices (color like in 1.65) --- Common/Context.h | 2 +- Common/DefaultOptions.h | 3 ++ Common/Options.cpp | 33 +++++++++++------ Common/Options.h | 1 + Geo/MVertex.h | 30 ++++++++++++++-- Graphics/Mesh.cpp | 75 +++++++++++++++++++++++++++------------ Mesh/SecondOrder.cpp | 20 +++++------ doc/TODO | 7 +++- doc/texinfo/opt_mesh.texi | 5 +++ 9 files changed, 127 insertions(+), 49 deletions(-) diff --git a/Common/Context.h b/Common/Context.h index d47f674dad..2a65486c34 100644 --- a/Common/Context.h +++ b/Common/Context.h @@ -228,7 +228,7 @@ public : unsigned int tangents, normals; } geom; struct{ - unsigned int vertex, line, triangle, quadrangle; + unsigned int vertex, vertex_sup, line, triangle, quadrangle; unsigned int tetrahedron, hexahedron, prism, pyramid; unsigned int carousel[20]; unsigned int tangents, normals; diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h index 2dc828e0da..db0baaa058 100644 --- a/Common/DefaultOptions.h +++ b/Common/DefaultOptions.h @@ -1470,6 +1470,9 @@ StringXColor MeshOptions_Color[] = { { F|O, "Points" , opt_mesh_color_points , {0, 0, 255, 255}, {0, 0, 255, 255}, {0, 0, 0, 255}, "Mesh node color" }, + { F|O, "PointsSup" , opt_mesh_color_points_sup , + {255, 0, 255, 255}, {255, 0, 255, 255}, {0, 0, 0, 255}, + "Second order mesh node color" }, { F|O, "Lines" , opt_mesh_color_lines , {0, 0, 0, 255}, {0, 0, 0, 255}, {0, 0, 0, 255}, "Mesh line color" }, diff --git a/Common/Options.cpp b/Common/Options.cpp index e6c70adf00..8db80e2915 100644 --- a/Common/Options.cpp +++ b/Common/Options.cpp @@ -1,4 +1,4 @@ -// $Id: Options.cpp,v 1.332 2007-01-24 10:53:04 geuzaine Exp $ +// $Id: Options.cpp,v 1.333 2007-01-26 17:51:55 geuzaine Exp $ // // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle // @@ -7193,6 +7193,17 @@ unsigned int opt_mesh_color_points(OPT_ARGS_COL) return CTX.color.mesh.vertex; } +unsigned int opt_mesh_color_points_sup(OPT_ARGS_COL) +{ + if(action & GMSH_SET) { + CTX.color.mesh.vertex_sup = val; + } +#if defined(HAVE_FLTK) + CCC(CTX.color.mesh.vertex_sup, WID->mesh_col[1]); +#endif + return CTX.color.mesh.vertex_sup; +} + unsigned int opt_mesh_color_lines(OPT_ARGS_COL) { if(action & GMSH_SET) { @@ -7203,7 +7214,7 @@ unsigned int opt_mesh_color_lines(OPT_ARGS_COL) CTX.color.mesh.line = val; } #if defined(HAVE_FLTK) - CCC(CTX.color.mesh.line, WID->mesh_col[1]); + CCC(CTX.color.mesh.line, WID->mesh_col[2]); #endif return CTX.color.mesh.line; } @@ -7218,7 +7229,7 @@ unsigned int opt_mesh_color_triangles(OPT_ARGS_COL) CTX.color.mesh.triangle = val; } #if defined(HAVE_FLTK) - CCC(CTX.color.mesh.triangle, WID->mesh_col[2]); + CCC(CTX.color.mesh.triangle, WID->mesh_col[3]); #endif return CTX.color.mesh.triangle; } @@ -7233,7 +7244,7 @@ unsigned int opt_mesh_color_quadrangles(OPT_ARGS_COL) CTX.color.mesh.quadrangle = val; } #if defined(HAVE_FLTK) - CCC(CTX.color.mesh.quadrangle, WID->mesh_col[3]); + CCC(CTX.color.mesh.quadrangle, WID->mesh_col[4]); #endif return CTX.color.mesh.quadrangle; } @@ -7248,7 +7259,7 @@ unsigned int opt_mesh_color_tetrahedra(OPT_ARGS_COL) CTX.color.mesh.tetrahedron = val; } #if defined(HAVE_FLTK) - CCC(CTX.color.mesh.tetrahedron, WID->mesh_col[4]); + CCC(CTX.color.mesh.tetrahedron, WID->mesh_col[5]); #endif return CTX.color.mesh.tetrahedron; } @@ -7263,7 +7274,7 @@ unsigned int opt_mesh_color_hexahedra(OPT_ARGS_COL) CTX.color.mesh.hexahedron = val; } #if defined(HAVE_FLTK) - CCC(CTX.color.mesh.hexahedron, WID->mesh_col[5]); + CCC(CTX.color.mesh.hexahedron, WID->mesh_col[6]); #endif return CTX.color.mesh.hexahedron; } @@ -7278,7 +7289,7 @@ unsigned int opt_mesh_color_prisms(OPT_ARGS_COL) CTX.color.mesh.prism = val; } #if defined(HAVE_FLTK) - CCC(CTX.color.mesh.prism, WID->mesh_col[6]); + CCC(CTX.color.mesh.prism, WID->mesh_col[7]); #endif return CTX.color.mesh.prism; } @@ -7293,7 +7304,7 @@ unsigned int opt_mesh_color_pyramid(OPT_ARGS_COL) CTX.color.mesh.pyramid = val; } #if defined(HAVE_FLTK) - CCC(CTX.color.mesh.pyramid, WID->mesh_col[7]); + CCC(CTX.color.mesh.pyramid, WID->mesh_col[8]); #endif return CTX.color.mesh.pyramid; } @@ -7304,7 +7315,7 @@ unsigned int opt_mesh_color_tangents(OPT_ARGS_COL) CTX.color.mesh.tangents = val; } #if defined(HAVE_FLTK) - CCC(CTX.color.mesh.tangents, WID->mesh_col[8]); + CCC(CTX.color.mesh.tangents, WID->mesh_col[9]); #endif return CTX.color.mesh.tangents; } @@ -7315,7 +7326,7 @@ unsigned int opt_mesh_color_normals(OPT_ARGS_COL) CTX.color.mesh.normals = val; } #if defined(HAVE_FLTK) - CCC(CTX.color.mesh.normals, WID->mesh_col[9]); + CCC(CTX.color.mesh.normals, WID->mesh_col[10]); #endif return CTX.color.mesh.normals; } @@ -7330,7 +7341,7 @@ unsigned int opt_mesh_color_(int i, OPT_ARGS_COL) CTX.color.mesh.carousel[i] = val; } #if defined(HAVE_FLTK) - CCC(CTX.color.mesh.carousel[i], WID->mesh_col[10+i]); + CCC(CTX.color.mesh.carousel[i], WID->mesh_col[11+i]); #endif return CTX.color.mesh.carousel[i]; } diff --git a/Common/Options.h b/Common/Options.h index 751ec42d12..bbffc964b1 100644 --- a/Common/Options.h +++ b/Common/Options.h @@ -656,6 +656,7 @@ unsigned int opt_geometry_color_highlight2(OPT_ARGS_COL); unsigned int opt_geometry_color_tangents(OPT_ARGS_COL); unsigned int opt_geometry_color_normals(OPT_ARGS_COL); unsigned int opt_mesh_color_points(OPT_ARGS_COL); +unsigned int opt_mesh_color_points_sup(OPT_ARGS_COL); unsigned int opt_mesh_color_lines(OPT_ARGS_COL); unsigned int opt_mesh_color_triangles(OPT_ARGS_COL); unsigned int opt_mesh_color_quadrangles(OPT_ARGS_COL); diff --git a/Geo/MVertex.h b/Geo/MVertex.h index 8b1660578a..3501aa8735 100644 --- a/Geo/MVertex.h +++ b/Geo/MVertex.h @@ -56,6 +56,9 @@ class MVertex{ virtual char getVisibility(){ return _visible; } virtual void setVisibility(char val){ _visible = val; } + // get the "order" of the vertex + virtual int getOrder(){ return 1; } + // get/set the coordinates inline double x() const {return _x;} inline double y() const {return _y;} @@ -99,6 +102,13 @@ class MVertex{ void writeBDF(FILE *fp, int format=0, double scalingFactor=1.0); }; +class MVertex2 : public MVertex { + public: + MVertex2(double x, double y, double z, GEntity *ge=0, int num=0) + : MVertex(x, y, z, ge, num){} + virtual int getOrder(){ return 2; } +}; + class MEdgeVertex : public MVertex{ protected: double _u; @@ -107,11 +117,18 @@ class MEdgeVertex : public MVertex{ : MVertex(x, y, z, ge), _u(u) { } - ~MEdgeVertex(){} + virtual ~MEdgeVertex(){} virtual bool getParameter(int i, double &par){ par = _u; return true; } virtual bool setParameter(int i, double par){ _u = par; return true; } }; +class MEdgeVertex2 : public MEdgeVertex{ + public: + MEdgeVertex2(double x, double y, double z, GEntity *ge, double u) + : MEdgeVertex(x, y, z, ge, u) {} + virtual int getOrder(){ return 2; } +}; + class MFaceVertex : public MVertex{ protected: double _u, _v; @@ -120,11 +137,18 @@ class MFaceVertex : public MVertex{ : MVertex(x, y, z, ge), _u(u), _v(v) { } - ~MFaceVertex(){} + virtual ~MFaceVertex(){} virtual bool getParameter(int i, double &par){ par = (i ? _v : _u); return true; } virtual bool setParameter(int i, double par){ if(!i) _u = par; else _v = par; return true; } }; +class MFaceVertex2 : public MFaceVertex{ + public: + MFaceVertex2(double x, double y, double z, GEntity *ge, double u, double v) + : MFaceVertex(x, y, z, ge, u, v){} + virtual int getOrder(){ return 2; } +}; + template<class T> class MDataFaceVertex : public MFaceVertex{ private: @@ -134,7 +158,7 @@ class MDataFaceVertex : public MFaceVertex{ : MFaceVertex(x, y, z, ge, u, v), _data(data) { } - ~MDataFaceVertex(){} + virtual ~MDataFaceVertex(){} virtual bool getData(T &data){ data = _data; return true; } virtual void *getData(){ return (void*)&_data; } }; diff --git a/Graphics/Mesh.cpp b/Graphics/Mesh.cpp index 1947d0b8ec..b76c422a80 100644 --- a/Graphics/Mesh.cpp +++ b/Graphics/Mesh.cpp @@ -1,4 +1,4 @@ -// $Id: Mesh.cpp,v 1.194 2007-01-25 08:56:14 geuzaine Exp $ +// $Id: Mesh.cpp,v 1.195 2007-01-26 17:51:55 geuzaine Exp $ // // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle // @@ -129,6 +129,14 @@ static bool areAllElementsVisible(std::vector<T*> &elements) return true; } +template<class T> +static bool areSomeElementsCurved(std::vector<T*> &elements) +{ + for(unsigned int i = 0; i < elements.size(); i++) + if(elements[i]->getPolynomialOrder() > 1 ) return true; + return false; +} + static int getLabelStep(int total) { int step; @@ -226,19 +234,26 @@ static void drawVertexLabel(GEntity *e, MVertex *v, int partition=-1) sprintf(str, "%d", e->tag()); else sprintf(str, "%d", v->getNum()); + + if(v->getOrder() > 1) + glColor4ubv((GLubyte *) & CTX.color.mesh.vertex_sup); + else + glColor4ubv((GLubyte *) & CTX.color.mesh.vertex); glRasterPos3d(v->x(), v->y(), v->z()); Draw_String(str); } static void drawVerticesPerEntity(GEntity *e) { - glColor4ubv((GLubyte *) & CTX.color.mesh.vertex); - if(CTX.mesh.points) { if(CTX.mesh.point_type) { for(unsigned int i = 0; i < e->mesh_vertices.size(); i++){ MVertex *v = e->mesh_vertices[i]; if(!v->getVisibility()) continue; + if(v->getOrder() > 1) + glColor4ubv((GLubyte *) & CTX.color.mesh.vertex_sup); + else + glColor4ubv((GLubyte *) & CTX.color.mesh.vertex); Draw_Sphere(CTX.mesh.point_size, v->x(), v->y(), v->z(), CTX.mesh.light); } } @@ -247,6 +262,10 @@ static void drawVerticesPerEntity(GEntity *e) for(unsigned int i = 0; i < e->mesh_vertices.size(); i++){ MVertex *v = e->mesh_vertices[i]; if(!v->getVisibility()) continue; + if(v->getOrder() > 1) + glColor4ubv((GLubyte *) & CTX.color.mesh.vertex_sup); + else + glColor4ubv((GLubyte *) & CTX.color.mesh.vertex); glVertex3d(v->x(), v->y(), v->z()); } glEnd(); @@ -262,14 +281,16 @@ static void drawVerticesPerEntity(GEntity *e) template<class T> static void drawVerticesPerElement(GEntity *e, std::vector<T*> &elements) { - glColor4ubv((GLubyte *) & CTX.color.mesh.vertex); - for(unsigned int i = 0; i < elements.size(); i++){ MElement *ele = elements[i]; for(int j = 0; j < ele->getNumVertices(); j++){ MVertex *v = ele->getVertex(j); if(isElementVisible(ele) && v->getVisibility()){ if(CTX.mesh.points) { + if(v->getOrder() > 1) + glColor4ubv((GLubyte *) & CTX.color.mesh.vertex_sup); + else + glColor4ubv((GLubyte *) & CTX.color.mesh.vertex); if(CTX.mesh.point_type) Draw_Sphere(CTX.mesh.point_size, v->x(), v->y(), v->z(), CTX.mesh.light); else{ @@ -423,7 +444,7 @@ static void addElementsInArrays(GEntity *e, std::vector<T*> &elements) } } } - else{ + if(!ele->getNumFacesRep() || ele->getPolynomialOrder() > 1){ SPoint3 pc; if(CTX.mesh.explode != 1.) pc = ele->barycenter(); for(int j = 0; j < ele->getNumEdgesRep(); j++){ @@ -619,14 +640,14 @@ class initMeshGFace { CTX.mesh.triangles && areAllElementsVisible(f->triangles) && CTX.mesh.quadrangles && areAllElementsVisible(f->quadrangles); - bool useEdges = CTX.mesh.surfaces_edges ? true : false; - if(CTX.mesh.surfaces_faces /*this will change!*/ || - CTX.mesh.explode != 1. || !m->allElementsVisible) - useEdges = false; + bool curvedElements = + areSomeElementsCurved(f->triangles) || + areSomeElementsCurved(f->quadrangles); - // mouse selection of individual elements is complicated if we - // don't draw everything per element - if(CTX.pick_elements) useEdges = false; + bool useEdges = CTX.mesh.surfaces_edges ? true : false; + if(CTX.mesh.surfaces_faces || CTX.mesh.explode != 1. || + CTX.pick_elements || !m->allElementsVisible) + useEdges = false; // cannot use edges in these cases // Further optimizations are possible when useEdges is true: // 1) store the unique vertices in the vertex array and use @@ -643,6 +664,9 @@ class initMeshGFace { addEdgesInArrays(f); } else if(CTX.mesh.surfaces_edges || CTX.mesh.surfaces_faces){ + if(curvedElements) // cannot simply draw polygon outlines! + m->va_lines = new VertexArray(2, 6 * f->triangles.size() + + 8 * f->quadrangles.size()); m->va_triangles = new VertexArray(3, f->triangles.size()); m->va_quads = new VertexArray(4, f->quadrangles.size()); if(CTX.mesh.triangles) addElementsInArrays(f, f->triangles); @@ -736,20 +760,20 @@ class initMeshGRegion { CTX.mesh.pyramids && areAllElementsVisible(r->pyramids); bool useEdges = CTX.mesh.volumes_edges ? true : false; - if(CTX.mesh.volumes_faces /*this will change!*/ || - CTX.mesh.explode != 1. || !m->allElementsVisible) - useEdges = false; - - // mouse selection of individual elements is complicated if we - // don't draw everything per element - if(CTX.pick_elements) useEdges = false; + if(CTX.mesh.volumes_faces || CTX.mesh.explode != 1. || + CTX.pick_elements || !m->allElementsVisible) + useEdges = false; // cannot use edges in these cases + + bool curvedElements = + areSomeElementsCurved(r->tetrahedra) || + areSomeElementsCurved(r->hexahedra) || + areSomeElementsCurved(r->prisms) || + areSomeElementsCurved(r->pyramids); bool useSkin = CTX.mesh.volumes_faces ? true : false; if(CTX.mesh.explode != 1. || !m->allElementsVisible) useSkin = false; - - // TODO - useSkin = false; + useSkin = false; // FIXME: to do if(useSkin){ Msg(DEBUG, "Using boundary faces to draw volume %d", r->tag()); @@ -765,6 +789,11 @@ class initMeshGRegion { addEdgesInArrays(r); } else if(CTX.mesh.volumes_edges || CTX.mesh.volumes_faces){ + if(curvedElements) // cannot simply draw polygon outlines! + m->va_lines = new VertexArray(2, 12 * r->tetrahedra.size() + + 24 * r->hexahedra.size() + + 18 * r->prisms.size() + + 16 * r->pyramids.size()); m->va_triangles = new VertexArray(3, 4 * r->tetrahedra.size() + 2 * r->prisms.size() + 4 * r->pyramids.size()); diff --git a/Mesh/SecondOrder.cpp b/Mesh/SecondOrder.cpp index d9f2bc452b..cadc79b241 100644 --- a/Mesh/SecondOrder.cpp +++ b/Mesh/SecondOrder.cpp @@ -1,4 +1,4 @@ -// $Id: SecondOrder.cpp,v 1.49 2007-01-22 16:31:43 geuzaine Exp $ +// $Id: SecondOrder.cpp,v 1.50 2007-01-26 17:51:56 geuzaine Exp $ // // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle // @@ -43,7 +43,7 @@ void getEdgeVertices(GEdge *ge, MElement *ele, std::vector<MVertex*> &ve, 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); + v = new MVertex2(pc.x(), pc.y(), pc.z(), ge); } else{ double u0 = 1e6, u1 = 1e6; @@ -63,12 +63,12 @@ void getEdgeVertices(GEdge *ge, MElement *ele, std::vector<MVertex*> &ve, 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); + v = new MEdgeVertex2(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); + v = new MVertex2(pc.x(), pc.y(), pc.z(), ge); } } edgeVertices[p] = v; @@ -92,7 +92,7 @@ void getEdgeVertices(GFace *gf, MElement *ele, std::vector<MVertex*> &ve, 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); + v = new MVertex2(pc.x(), pc.y(), pc.z(), gf); } else{ SPoint2 p0 = gf->parFromPoint(SPoint3(v0->x(), v0->y(), v0->z())); @@ -100,7 +100,7 @@ void getEdgeVertices(GFace *gf, MElement *ele, std::vector<MVertex*> &ve, 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); + v = new MFaceVertex2(pc.x(), pc.y(), pc.z(), gf, uc, vc); } edgeVertices[p] = v; gf->mesh_vertices.push_back(v); @@ -121,7 +121,7 @@ void getEdgeVertices(GRegion *gr, MElement *ele, std::vector<MVertex*> &ve, } else{ SPoint3 pc = edge.barycenter(); - MVertex *v = new MVertex(pc.x(), pc.y(), pc.z(), gr); + MVertex *v = new MVertex2(pc.x(), pc.y(), pc.z(), gr); edgeVertices[p] = v; gr->mesh_vertices.push_back(v); ve.push_back(v); @@ -145,7 +145,7 @@ void getFaceVertices(GFace *gf, MElement *ele, std::vector<MVertex*> &vf, MVertex *v; if(linear || gf->geomType() == GEntity::DiscreteSurface){ SPoint3 pc = face.barycenter(); - v = new MVertex(pc.x(), pc.y(), pc.z(), gf); + v = new MVertex2(pc.x(), pc.y(), pc.z(), gf); } else{ SPoint2 p0 = gf->parFromPoint(SPoint3(p[0]->x(), p[0]->y(), p[0]->z())); @@ -155,7 +155,7 @@ void getFaceVertices(GFace *gf, MElement *ele, std::vector<MVertex*> &vf, 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); + v = new MFaceVertex2(pc.x(), pc.y(), pc.z(), gf, uc, vc); } faceVertices[p] = v; gf->mesh_vertices.push_back(v); @@ -178,7 +178,7 @@ void getFaceVertices(GRegion *gr, MElement *ele, std::vector<MVertex*> &vf, } else{ SPoint3 pc = face.barycenter(); - MVertex *v = new MVertex(pc.x(), pc.y(), pc.z(), gr); + MVertex *v = new MVertex2(pc.x(), pc.y(), pc.z(), gr); faceVertices[p] = v; gr->mesh_vertices.push_back(v); vf.push_back(v); diff --git a/doc/TODO b/doc/TODO index 0d0d02fc76..08d0868ba4 100644 --- a/doc/TODO +++ b/doc/TODO @@ -1,4 +1,9 @@ -$Id: TODO,v 1.39 2007-01-22 16:31:44 geuzaine Exp $ +$Id: TODO,v 1.40 2007-01-26 17:51:56 geuzaine Exp $ + +******************************************************************** + +better drawing of 2nd order elements (no extra edges in the middle, +2nd order nodes in different color) ******************************************************************** diff --git a/doc/texinfo/opt_mesh.texi b/doc/texinfo/opt_mesh.texi index a7cf88c753..207f7c34dd 100644 --- a/doc/texinfo/opt_mesh.texi +++ b/doc/texinfo/opt_mesh.texi @@ -374,6 +374,11 @@ Mesh node color@* Default value: @code{@{0,0,255@}}@* Saved in: @code{General.OptionsFileName} +@item Mesh.Color.PointsSup +Second order mesh node color@* +Default value: @code{@{255,0,255@}}@* +Saved in: @code{General.OptionsFileName} + @item Mesh.Color.Lines Mesh line color@* Default value: @code{@{0,0,0@}}@* -- GitLab