From 2ee127b352f5b9bbc00166b55682205513735a3e Mon Sep 17 00:00:00 2001 From: Christophe Geuzaine <cgeuzaine@ulg.ac.be> Date: Wed, 16 Aug 2006 21:11:41 +0000 Subject: [PATCH] *** empty log message *** --- Common/Context.h | 2 +- Common/DefaultOptions.h | 4 +- Common/Options.cpp | 12 +- Common/Options.h | 2 +- Fltk/Callbacks.cpp | 4 +- Fltk/GUI.cpp | 23 +-- Geo/MRep.h | 9 +- Graphics/Mesh.cpp | 402 +++++++++++++++++++++++----------------- 8 files changed, 262 insertions(+), 196 deletions(-) diff --git a/Common/Context.h b/Common/Context.h index 9d1fd3b53f..f885cbbf66 100644 --- a/Common/Context.h +++ b/Common/Context.h @@ -176,7 +176,7 @@ public : int histogram, initial_only; double normals, tangents, explode; int color_carousel; - int use_cut_plane, cut_plane_as_surface, cut_plane_only_volume; + int use_cut_plane, cut_plane_draw_intersect, cut_plane_only_volume; double cut_planea, cut_planeb, cut_planec, cut_planed; double evalCutPlane (double x, double y, double z){ double val = cut_planea * x + cut_planeb * y + cut_planec * z + cut_planed; diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h index 243938e97a..a2f37938fb 100644 --- a/Common/DefaultOptions.h +++ b/Common/DefaultOptions.h @@ -860,8 +860,8 @@ StringXNumber MeshOptions_Number[] = { "CPU time (in seconds) for the generation of the current mesh (read-only)" }, { F, "CutPlane" , opt_mesh_use_cut_plane , 0 , "Enable mesh cut plane" }, - { F, "CutPlaneAsSurface" , opt_mesh_cut_plane_as_surface , 0 , - "Draw the intersection volume layer as a surface" }, + { F, "CutPlaneDrawIntersect" , opt_mesh_cut_plane_draw_intersect , 0 , + "Draw only the volume elements that intersect with the cut plane" }, { F, "CutPlaneOnlyVolume" , opt_mesh_cut_plane_only_volume , 0 , "Cut only the volume elements" }, { F, "CutPlaneA" , opt_mesh_cut_planea , 1.0 , diff --git a/Common/Options.cpp b/Common/Options.cpp index 0150f5df1a..9a70401150 100644 --- a/Common/Options.cpp +++ b/Common/Options.cpp @@ -1,4 +1,4 @@ -// $Id: Options.cpp,v 1.290 2006-08-15 21:22:12 geuzaine Exp $ +// $Id: Options.cpp,v 1.291 2006-08-16 21:11:41 geuzaine Exp $ // // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle // @@ -4722,17 +4722,17 @@ double opt_mesh_use_cut_plane(OPT_ARGS_NUM) return CTX.mesh.use_cut_plane; } -double opt_mesh_cut_plane_as_surface(OPT_ARGS_NUM) +double opt_mesh_cut_plane_draw_intersect(OPT_ARGS_NUM) { if(action & GMSH_SET){ - if(CTX.mesh.cut_plane_as_surface != (int)val) CTX.mesh.changed = 1; - CTX.mesh.cut_plane_as_surface = (int)val; + if(CTX.mesh.cut_plane_draw_intersect != (int)val) CTX.mesh.changed = 1; + CTX.mesh.cut_plane_draw_intersect = (int)val; } #if defined(HAVE_FLTK) if(WID && (action & GMSH_GUI)) - WID->mesh_butt[22]->value(CTX.mesh.cut_plane_as_surface); + WID->mesh_butt[22]->value(CTX.mesh.cut_plane_draw_intersect); #endif - return CTX.mesh.cut_plane_as_surface; + return CTX.mesh.cut_plane_draw_intersect; } double opt_mesh_cut_plane_only_volume(OPT_ARGS_NUM) diff --git a/Common/Options.h b/Common/Options.h index 92444ef109..97d782bae5 100644 --- a/Common/Options.h +++ b/Common/Options.h @@ -461,7 +461,7 @@ double opt_mesh_dual(OPT_ARGS_NUM); double opt_mesh_interactive(OPT_ARGS_NUM); double opt_mesh_initial_only(OPT_ARGS_NUM); double opt_mesh_use_cut_plane(OPT_ARGS_NUM); -double opt_mesh_cut_plane_as_surface(OPT_ARGS_NUM); +double opt_mesh_cut_plane_draw_intersect(OPT_ARGS_NUM); double opt_mesh_cut_plane_only_volume(OPT_ARGS_NUM); double opt_mesh_cut_planea(OPT_ARGS_NUM); double opt_mesh_cut_planeb(OPT_ARGS_NUM); diff --git a/Fltk/Callbacks.cpp b/Fltk/Callbacks.cpp index 862d4b61b1..c49032122d 100644 --- a/Fltk/Callbacks.cpp +++ b/Fltk/Callbacks.cpp @@ -1,4 +1,4 @@ -// $Id: Callbacks.cpp,v 1.431 2006-08-15 21:22:12 geuzaine Exp $ +// $Id: Callbacks.cpp,v 1.432 2006-08-16 21:11:41 geuzaine Exp $ // // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle // @@ -1122,7 +1122,7 @@ void mesh_options_ok_cb(CALLBACK_ARGS) opt_mesh_surfaces_num(0, GMSH_SET, WID->mesh_butt[14]->value()); opt_mesh_volumes_num(0, GMSH_SET, WID->mesh_butt[15]->value()); opt_mesh_use_cut_plane(0, GMSH_SET, WID->mesh_butt[16]->value()); - opt_mesh_cut_plane_as_surface(0, GMSH_SET, WID->mesh_butt[22]->value()); + opt_mesh_cut_plane_draw_intersect(0, GMSH_SET, WID->mesh_butt[22]->value()); opt_mesh_cut_plane_only_volume(0, GMSH_SET, WID->mesh_butt[23]->value()); opt_mesh_light(0, GMSH_SET, WID->mesh_butt[17]->value()); opt_mesh_light_two_side(0, GMSH_SET, WID->mesh_butt[18]->value()); diff --git a/Fltk/GUI.cpp b/Fltk/GUI.cpp index ed06b27ba7..00590c140a 100644 --- a/Fltk/GUI.cpp +++ b/Fltk/GUI.cpp @@ -1,4 +1,4 @@ -// $Id: GUI.cpp,v 1.517 2006-08-15 21:22:12 geuzaine Exp $ +// $Id: GUI.cpp,v 1.518 2006-08-16 21:11:41 geuzaine Exp $ // // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle // @@ -725,24 +725,20 @@ int GUI::global_shortcuts(int event) return 1; } else if(Fl::test_shortcut(FL_ALT + FL_SHIFT + 'l')) { - opt_mesh_surfaces_edges(0, GMSH_SET | GMSH_GUI, - !opt_mesh_surfaces_edges(0, GMSH_GET, 0)); + opt_mesh_lines(0, GMSH_SET | GMSH_GUI, + !opt_mesh_lines(0, GMSH_GET, 0)); redraw_opengl(); return 1; } else if(Fl::test_shortcut(FL_ALT + FL_SHIFT + 's')) { - int old = opt_mesh_surfaces_edges(0, GMSH_GET, 0) || - opt_mesh_surfaces_faces(0, GMSH_GET, 0); - opt_mesh_surfaces_edges(0, GMSH_SET | GMSH_GUI, !old); - opt_mesh_surfaces_faces(0, GMSH_SET | GMSH_GUI, !old); + opt_mesh_surfaces_edges(0, GMSH_SET | GMSH_GUI, + !opt_mesh_surfaces_edges(0, GMSH_GET, 0)); redraw_opengl(); return 1; } else if(Fl::test_shortcut(FL_ALT + FL_SHIFT + 'v')) { - int old = opt_mesh_volumes_edges(0, GMSH_GET, 0) || - opt_mesh_volumes_faces(0, GMSH_GET, 0); - opt_mesh_volumes_edges(0, GMSH_SET | GMSH_GUI, !old); - opt_mesh_volumes_faces(0, GMSH_SET | GMSH_GUI, !old); + opt_mesh_volumes_edges(0, GMSH_SET | GMSH_GUI, + !opt_mesh_volumes_edges(0, GMSH_GET, 0)); redraw_opengl(); return 1; } @@ -2361,7 +2357,7 @@ void GUI::create_option_window() mesh_butt[8]->selection_color(GMSH_TOGGLE_COLOR); mesh_butt[9] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 4 * BH, BW / 2 - WB, BH, "Surface element faces"); - mesh_butt[9]->tooltip("(Alt+Shift+s, Alt+Shift+d)"); + mesh_butt[9]->tooltip("(Alt+Shift+d)"); mesh_butt[9]->type(FL_TOGGLE_BUTTON); mesh_butt[9]->down_box(GMSH_TOGGLE_BOX); mesh_butt[9]->selection_color(GMSH_TOGGLE_COLOR); @@ -2373,7 +2369,6 @@ void GUI::create_option_window() mesh_butt[10]->selection_color(GMSH_TOGGLE_COLOR); mesh_butt[11] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 6 * BH, BW / 2 - WB, BH, "Volume element faces"); - mesh_butt[11]->tooltip("(Alt+Shift+v)"); mesh_butt[11]->type(FL_TOGGLE_BUTTON); mesh_butt[11]->down_box(GMSH_TOGGLE_BOX); mesh_butt[11]->selection_color(GMSH_TOGGLE_COLOR); @@ -2503,7 +2498,7 @@ void GUI::create_option_window() mesh_value[17]->minimum(-1.0); mesh_value[17]->maximum(1.0); - mesh_butt[22] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 6 * BH, BW, BH, "Draw intersecting volume layer as surface"); + mesh_butt[22] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 6 * BH, BW, BH, "Draw only intersecting volume layer"); mesh_butt[22]->type(FL_TOGGLE_BUTTON); mesh_butt[22]->down_box(GMSH_TOGGLE_BOX); mesh_butt[22]->selection_color(GMSH_TOGGLE_COLOR); diff --git a/Geo/MRep.h b/Geo/MRep.h index 2497aca4b2..b22e83beeb 100644 --- a/Geo/MRep.h +++ b/Geo/MRep.h @@ -43,7 +43,6 @@ class MRep { template<class T> void generateEdgeRep(std::vector<T*> &elements) { - if(edges.size()) return; for(unsigned int i = 0; i < elements.size(); i++){ for(int j = 0; j < elements[i]->getNumEdgesRep(); j++){ MEdge e = elements[i]->getEdgeRep(j); @@ -54,7 +53,7 @@ class MRep { } public: - MRep() : va_lines(0), va_triangles(0), va_quads(0) {} + MRep() : va_lines(0), va_triangles(0), va_quads(0), allElementsVisible(true) {} virtual ~MRep(){} // generates the edge representation @@ -78,6 +77,9 @@ class MRep { if(va_quads) delete va_quads; va_quads = 0; } + + // a flag telling if all the elements in the entity are visible + bool allElementsVisible; }; class MRepEdge : public MRep { @@ -89,6 +91,7 @@ class MRepEdge : public MRep { virtual ~MRepEdge(){} virtual void generateEdgeRep() { + if(edges.size()) return; MRep::generateEdgeRep(_e->lines); } }; @@ -102,6 +105,7 @@ class MRepFace : public MRep { virtual ~MRepFace(){} virtual void generateEdgeRep() { + if(edges.size()) return; double t = Cpu(); MRep::generateEdgeRep(_f->triangles); MRep::generateEdgeRep(_f->quadrangles); @@ -119,6 +123,7 @@ class MRepRegion : public MRep { virtual ~MRepRegion(){} virtual void generateEdgeRep() { + if(edges.size()) return; double t = Cpu(); MRep::generateEdgeRep(_r->tetrahedra); MRep::generateEdgeRep(_r->hexahedra); diff --git a/Graphics/Mesh.cpp b/Graphics/Mesh.cpp index b588fb65a4..17ea383fe3 100644 --- a/Graphics/Mesh.cpp +++ b/Graphics/Mesh.cpp @@ -1,4 +1,4 @@ -// $Id: Mesh.cpp,v 1.170 2006-08-16 17:14:57 geuzaine Exp $ +// $Id: Mesh.cpp,v 1.171 2006-08-16 21:11:41 geuzaine Exp $ // // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle // @@ -58,24 +58,51 @@ static unsigned int getColor(GEntity *e, int forceColor, unsigned int color) return color; } -static double intersectCutPlane(MElement *ele, int *edges=0, int *faces=0) +static double intersectCutPlane(MElement *ele) { MVertex *v = ele->getVertex(0); double val = CTX.mesh.evalCutPlane(v->x(), v->y(), v->z()); for(int i = 1; i < ele->getNumVertices(); i++){ v = ele->getVertex(i); - if(val * CTX.mesh.evalCutPlane(v->x(), v->y(), v->z()) <= 0){ - // the element intersects the cut plane - if(CTX.mesh.cut_plane_as_surface){ - if(!*edges) *edges = CTX.mesh.surfaces_edges; - if(!*faces) *faces = CTX.mesh.surfaces_faces; - } - return 1.; - } + if(val * CTX.mesh.evalCutPlane(v->x(), v->y(), v->z()) <= 0) + return 0.; // the element intersects the cut plane } return val; } +static bool isElementVisible(MElement *ele) +{ + if(!ele->getVisibility()) return false; + if(CTX.mesh.quality_sup) { + double q; + if(CTX.mesh.quality_type == 2) + q = ele->rhoShapeMeasure(); + else if(CTX.mesh.quality_type == 1) + q = ele->etaShapeMeasure(); + else + q = ele->gammaShapeMeasure(); + if(q < CTX.mesh.quality_inf || q > CTX.mesh.quality_sup) return false; + } + if(CTX.mesh.radius_sup) { + double r = ele->maxEdge(); + if(r < CTX.mesh.radius_inf || r > CTX.mesh.radius_sup) return false; + } + if(CTX.mesh.use_cut_plane){ + if(ele->getDim() < 3 && CTX.mesh.cut_plane_only_volume){ + } + else if(intersectCutPlane(ele) < 0) return false; + } + return true; +} + +template<class T> +static bool areAllElementsVisible(std::vector<T*> &elements) +{ + for(unsigned int i = 0; i < elements.size(); i++) + if(!isElementVisible(elements[i])) return false; + return true; +} + static int getLabelStep(int total) { int step; @@ -87,15 +114,18 @@ static int getLabelStep(int total) } template<class T> -static void drawLabels(GEntity *e, std::vector<T*> &elements, int labelStep, - int &labelNum, int forceColor, unsigned int color) +static void drawElementLabels(GEntity *e, std::vector<T*> &elements, + int forceColor, unsigned int color) { unsigned col = getColor(e, forceColor, color); glColor4ubv((GLubyte *) & col); + + int labelStep = getLabelStep(elements.size()); + for(unsigned int i = 0; i < elements.size(); i++){ MElement *ele = elements[i]; - labelNum++; - if(labelNum % labelStep == 0) { + if(!isElementVisible(ele)) continue; + if(i % labelStep == 0) { SPoint3 pc = ele->barycenter(); char str[256]; if(CTX.mesh.label_type == 4) @@ -129,10 +159,12 @@ static void drawNormals(std::vector<T*> &elements) { glColor4ubv((GLubyte *) & CTX.color.mesh.normals); for(unsigned int i = 0; i < elements.size(); i++){ - SVector3 n = elements[i]->getFaceRep(0).normal(); + MElement *ele = elements[i]; + if(!isElementVisible(ele)) continue; + SVector3 n = ele->getFaceRep(0).normal(); for(int j = 0; j < 3; j++) n[j] *= CTX.mesh.normals * CTX.pixel_equiv_x / CTX.s[j]; - SPoint3 pc = elements[i]->barycenter(); + SPoint3 pc = ele->barycenter(); Draw_Vector(CTX.vector_type, 0, CTX.arrow_rel_head_radius, CTX.arrow_rel_stem_length, CTX.arrow_rel_stem_radius, pc.x(), pc.y(), pc.z(), n[0], n[1], n[2], CTX.mesh.light); @@ -144,17 +176,45 @@ static void drawTangents(std::vector<T*> &elements) { glColor4ubv((GLubyte *) & CTX.color.mesh.tangents); for(unsigned int i = 0; i < elements.size(); i++){ - SVector3 t = elements[i]->getEdgeRep(0).tangent(); + MElement *ele = elements[i]; + if(!isElementVisible(ele)) continue; + SVector3 t = ele->getEdgeRep(0).tangent(); for(int j = 0; j < 3; j++) t[j] *= CTX.mesh.tangents * CTX.pixel_equiv_x / CTX.s[j]; - SPoint3 pc = elements[i]->barycenter(); + SPoint3 pc = ele->barycenter(); Draw_Vector(CTX.vector_type, 0, CTX.arrow_rel_head_radius, CTX.arrow_rel_stem_length, CTX.arrow_rel_stem_radius, pc.x(), pc.y(), pc.z(), t[0], t[1], t[2], CTX.mesh.light); } } -static void drawVertices(GEntity *e) +static void drawVertexLabel(GEntity *e, MVertex *v, int partition=-1) +{ + int np = e->physicals.size(); + int physical = np ? e->physicals[np - 1] : 0; + char str[256]; + if(CTX.mesh.label_type == 4) + sprintf(str, "(%g,%g,%g)", v->x(), v->y(), v->z()); + else if(CTX.mesh.label_type == 3){ + if(partition < 0) + sprintf(str, "NA"); + else + sprintf(str, "%d", partition); + } + else if(CTX.mesh.label_type == 2) + sprintf(str, "%d", physical); + else if(CTX.mesh.label_type == 1) + sprintf(str, "%d", e->tag()); + else + sprintf(str, "%d", v->getNum()); + double offset = 0.3 * (CTX.mesh.point_size + CTX.gl_fontsize) * CTX.pixel_equiv_x; + glRasterPos3d(v->x() + offset / CTX.s[0], + v->y() + offset / CTX.s[1], + v->z() + offset / CTX.s[2]); + Draw_String(str); +} + +static void drawVerticesPerEntity(GEntity *e) { glColor4ubv((GLubyte *) & CTX.color.mesh.vertex); @@ -162,6 +222,7 @@ static void drawVertices(GEntity *e) 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; Draw_Sphere(CTX.mesh.point_size, v->x(), v->y(), v->z(), CTX.mesh.light); } } @@ -169,37 +230,40 @@ static void drawVertices(GEntity *e) glBegin(GL_POINTS); for(unsigned int i = 0; i < e->mesh_vertices.size(); i++){ MVertex *v = e->mesh_vertices[i]; + if(!v->getVisibility()) continue; glVertex3d(v->x(), v->y(), v->z()); } glEnd(); } } - - int np = e->physicals.size(); - int physical = np ? e->physicals[np - 1] : 0; - const int labelStep = getLabelStep(e->mesh_vertices.size()); - int labelNum = 0; if(CTX.mesh.points_num) { - for(unsigned int i = 0; i < e->mesh_vertices.size(); i++){ - MVertex *v = e->mesh_vertices[i]; - labelNum++; - if(labelNum % labelStep == 0) { - char str[256]; - if(CTX.mesh.label_type == 4) - sprintf(str, "(%g,%g,%g)", v->x(), v->y(), v->z()); - else if(CTX.mesh.label_type == 3) - sprintf(str, "NA"); - else if(CTX.mesh.label_type == 2) - sprintf(str, "%d", physical); - else if(CTX.mesh.label_type == 1) - sprintf(str, "%d", e->tag()); - else - sprintf(str, "%d", v->getNum()); - double offset = 0.3 * (CTX.mesh.point_size + CTX.gl_fontsize) * CTX.pixel_equiv_x; - glRasterPos3d(v->x() + offset / CTX.s[0], - v->y() + offset / CTX.s[1], - v->z() + offset / CTX.s[2]); - Draw_String(str); + int labelStep = getLabelStep(e->mesh_vertices.size()); + for(unsigned int i = 0; i < e->mesh_vertices.size(); i++) + if(i % labelStep == 0) drawVertexLabel(e, e->mesh_vertices[i]); + } +} + +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(CTX.mesh.point_type) + Draw_Sphere(CTX.mesh.point_size, v->x(), v->y(), v->z(), CTX.mesh.light); + else{ + glBegin(GL_POINTS); + glVertex3d(v->x(), v->y(), v->z()); + glEnd(); + } + } + if(CTX.mesh.points_num) + drawVertexLabel(e, v); } } } @@ -215,6 +279,7 @@ static void drawBarycentricDual(std::vector<T*> &elements) glBegin(GL_LINES); for(unsigned int i = 0; i < elements.size(); i++){ MElement *ele = elements[i]; + if(!isElementVisible(ele)) continue; SPoint3 pc = ele->barycenter(); if(ele->getDim() == 2){ for(int j = 0; j < ele->getNumEdges(); j++){ @@ -245,81 +310,91 @@ static void drawBarycentricDual(std::vector<T*> &elements) gl2psDisable(GL2PS_LINE_STIPPLE); } +// Routine to fill the smooth normal container + template<class T> -static bool allElementsVisible(std::vector<T*> &elements) +static void addSmoothNormals(GEntity *e, std::vector<T*> &elements) { - for(unsigned int i = 0; i < elements.size(); i++) - if(!elements[i]->getVisibility()) return false; - return true; + for(unsigned int i = 0; i < elements.size(); i++){ + MElement *ele = elements[i]; + for(int j = 0; j < ele->getNumFacesRep(); j++){ + MFace fr = ele->getFaceRep(j); + SVector3 n = fr.normal(); + SPoint3 pc; + if(CTX.mesh.explode != 1.) pc = ele->barycenter(); + for(int k = 0; k < fr.getNumVertices(); k++){ + MVertex *v = fr.getVertex(k); + SPoint3 p(v->x(), v->y(), v->z()); + if(CTX.mesh.explode != 1.){ + for(int l = 0; l < 3; l++) + p[l] = pc[l] + CTX.mesh.explode * (p[l] - pc[l]); + } + e->model()->normals->add(p[0], p[1], p[2], n[0], n[1], n[2]); + } + } + } } // Routines for filling and drawing the vertex arrays -static void addEdgesInArrays(GEntity *e, VertexArray *va, MRep *m) +static void addEdgesInArrays(GEntity *e) { + MRep *m = e->meshRep; for(MRep::eriter it = m->firstEdgeRep(); it != m->lastEdgeRep(); ++it){ MVertex *v[2] = {it->first.first, it->first.second}; MElement *ele = it->second; SVector3 n = ele->getFace(0).normal(); int part = ele->getPartition(); for(int i = 0; i < 2; i++){ - if(CTX.mesh.smooth_normals) + if(e->dim() == 2 && CTX.mesh.smooth_normals) e->model()->normals->get(v[i]->x(), v[i]->y(), v[i]->z(), n[0], n[1], n[2]); - va->add(v[i]->x(), v[i]->y(), v[i]->z(), n[0], n[1], n[2], - CTX.color.mesh.carousel[abs(part % 20)]); + m->va_lines->add(v[i]->x(), v[i]->y(), v[i]->z(), n[0], n[1], n[2], + CTX.color.mesh.carousel[abs(part % 20)]); } } } template<class T> -static void addElementsInArrays(GEntity *e, VertexArray *va, std::vector<T*> &elements) +static void addElementsInArrays(GEntity *e, std::vector<T*> &elements) { + MRep *m = e->meshRep; for(unsigned int i = 0; i < elements.size(); i++){ MElement *ele = elements[i]; - int part = ele->getPartition(); - if(CTX.mesh.quality_sup) { - double q; - if(CTX.mesh.quality_type == 2) - q = ele->rhoShapeMeasure(); - else if(CTX.mesh.quality_type == 1) - q = ele->etaShapeMeasure(); - else - q = ele->gammaShapeMeasure(); - if(q < CTX.mesh.quality_inf || q > CTX.mesh.quality_sup) continue; - } - if(CTX.mesh.radius_sup) { - double r = ele->maxEdge(); - if(r < CTX.mesh.radius_inf || r > CTX.mesh.radius_sup) continue; - } - if(CTX.mesh.use_cut_plane && !CTX.mesh.cut_plane_only_volume){ - if(intersectCutPlane(ele) < 0) continue; + if(!isElementVisible(ele)) continue; + if(CTX.mesh.use_cut_plane && CTX.mesh.cut_plane_draw_intersect){ + if(e->dim() == 3 && intersectCutPlane(ele)) continue; } + int part = ele->getPartition(); + SPoint3 pc; + if(CTX.mesh.explode != 1.) pc = ele->barycenter(); if(ele->getNumFacesRep()){ for(int j = 0; j < ele->getNumFacesRep(); j++){ MFace fr = ele->getFaceRep(j); - if(fr.getNumVertices() != va->type) continue; SVector3 n = fr.normal(); - SPoint3 pc; - if(CTX.mesh.explode != 1.) pc = ele->barycenter(); - for(int k = 0; k < fr.getNumVertices(); k++){ + int numverts = fr.getNumVertices(); + for(int k = 0; k < numverts; k++){ MVertex *v = fr.getVertex(k); SPoint3 p(v->x(), v->y(), v->z()); if(CTX.mesh.explode != 1.){ for(int l = 0; l < 3; l++) p[l] = pc[l] + CTX.mesh.explode * (p[l] - pc[l]); } - if(CTX.mesh.smooth_normals) + if(e->dim() == 2 && CTX.mesh.smooth_normals) e->model()->normals->get(p[0], p[1], p[2], n[0], n[1], n[2]); - va->add(p[0], p[1], p[2], n[0], n[1], n[2], - CTX.color.mesh.carousel[abs(part % 20)]); + if(numverts == 3) + m->va_triangles->add(p[0], p[1], p[2], n[0], n[1], n[2], + CTX.color.mesh.carousel[abs(part % 20)]); + else if(numverts == 4) + m->va_quads->add(p[0], p[1], p[2], n[0], n[1], n[2], + CTX.color.mesh.carousel[abs(part % 20)]); } } } else{ + SPoint3 pc; + if(CTX.mesh.explode != 1.) pc = ele->barycenter(); for(int j = 0; j < ele->getNumEdgesRep(); j++){ MEdge er = ele->getEdgeRep(j); - SPoint3 pc; - if(CTX.mesh.explode != 1.) pc = ele->barycenter(); for(int k = 0; k < er.getNumVertices(); k++){ MVertex *v = er.getVertex(k); SPoint3 p(v->x(), v->y(), v->z()); @@ -327,7 +402,7 @@ static void addElementsInArrays(GEntity *e, VertexArray *va, std::vector<T*> &el for(int l = 0; l < 3; l++) p[l] = pc[l] + CTX.mesh.explode * (p[l] - pc[l]); } - va->add(p[0], p[1], p[2], CTX.color.mesh.carousel[abs(part % 20)]); + m->va_lines->add(p[0], p[1], p[2], CTX.color.mesh.carousel[abs(part % 20)]); } } } @@ -389,7 +464,7 @@ class drawMeshGVertex { } if(CTX.mesh.points || CTX.mesh.points_num) - drawVertices(v); + drawVerticesPerEntity(v); if(CTX.render_mode == GMSH_SELECT) { glPopName(); @@ -410,10 +485,11 @@ class initMeshGEdge { MRep *m = e->meshRep; m->resetArrays(); + m->allElementsVisible = areAllElementsVisible(e->lines); if(CTX.mesh.lines){ m->va_lines = new VertexArray(2, e->lines.size()); - addElementsInArrays(e, m->va_lines, e->lines); + addElementsInArrays(e, e->lines); } } }; @@ -435,14 +511,15 @@ class drawMeshGEdge { drawArrays(m->va_lines, GL_LINES, false, CTX.mesh.color_carousel == 3, false, getColor(e, false, CTX.color.mesh.line)); - if(CTX.mesh.lines_num) { - const int labelStep = getLabelStep(e->lines.size()); - int labelNum = 0; - drawLabels(e, e->lines, labelStep, labelNum, false, CTX.color.mesh.line); - } + if(CTX.mesh.lines_num) + drawElementLabels(e, e->lines, false, CTX.color.mesh.line); - if(CTX.mesh.points || CTX.mesh.points_num) - drawVertices(e); + if(CTX.mesh.points || CTX.mesh.points_num){ + if(m->allElementsVisible) + drawVerticesPerEntity(e); + else + drawVerticesPerElement(e, e->lines); + } if(CTX.mesh.tangents) drawTangents(e->lines); @@ -457,34 +534,11 @@ class drawMeshGEdge { // GFace drawing routines class initSmoothNormalsGFace { - private: - template<class T> - void _addSmoothNormals(GFace *f, std::vector<T*> &elements) - { - for(unsigned int i = 0; i < elements.size(); i++){ - MElement *ele = elements[i]; - for(int j = 0; j < ele->getNumFacesRep(); j++){ - MFace fr = ele->getFaceRep(j); - SVector3 n = fr.normal(); - SPoint3 pc; - if(CTX.mesh.explode != 1.) pc = ele->barycenter(); - for(int k = 0; k < fr.getNumVertices(); k++){ - MVertex *v = fr.getVertex(k); - SPoint3 p(v->x(), v->y(), v->z()); - if(CTX.mesh.explode != 1.){ - for(int l = 0; l < 3; l++) - p[l] = pc[l] + CTX.mesh.explode * (p[l] - pc[l]); - } - f->model()->normals->add(p[0], p[1], p[2], n[0], n[1], n[2]); - } - } - } - } public : void operator () (GFace *f) { - _addSmoothNormals(f, f->triangles); - _addSmoothNormals(f, f->quadrangles); + addSmoothNormals(f, f->triangles); + addSmoothNormals(f, f->quadrangles); } }; @@ -498,31 +552,32 @@ class initMeshGFace { MRep *m = f->meshRep; m->resetArrays(); + m->allElementsVisible = + areAllElementsVisible(f->triangles) && + areAllElementsVisible(f->quadrangles); - // TODO: further optimizations are possible when useEdges is true: - // - // 1) store the unique vertices in the vertex array and use - // glDrawElements() instead of glDrawArrays(). - // 2) use tc to stripe the triangles and draw strips instead of individual - // triangles bool useEdges = CTX.mesh.surfaces_edges ? true : false; - if(CTX.mesh.surfaces_faces /*this will change!*/ || CTX.mesh.explode != 1. || - CTX.mesh.quality_sup || CTX.mesh.radius_sup || CTX.mesh.use_cut_plane || - !allElementsVisible(f->triangles) || !allElementsVisible(f->quadrangles)) + if(CTX.mesh.surfaces_faces /*this will change!*/ || + CTX.mesh.explode != 1. || !m->allElementsVisible) useEdges = false; + + // Further optimizations are possible when useEdges is true: + // 1) store the unique vertices in the vertex array and use + // glDrawElements() instead of glDrawArrays(). + // 2) use tc to stripe the triangles and draw strips instead of + // individual triangles if(useEdges){ Msg(DEBUG, "Using edges to draw surface %d", f->tag()); m->generateEdgeRep(); m->va_lines = new VertexArray(2, m->getNumEdgeRep()); - addEdgesInArrays(f, m->va_lines, m); + addEdgesInArrays(f); } else if(CTX.mesh.surfaces_edges || CTX.mesh.surfaces_faces){ m->va_triangles = new VertexArray(3, f->triangles.size()); - addElementsInArrays(f, m->va_triangles, f->triangles); - m->va_quads = new VertexArray(4, f->quadrangles.size()); - addElementsInArrays(f, m->va_quads, f->quadrangles); + addElementsInArrays(f, f->triangles); + addElementsInArrays(f, f->quadrangles); } } }; @@ -566,16 +621,18 @@ class drawMeshGFace { } if(CTX.mesh.surfaces_num) { - const int labelStep = getLabelStep(f->triangles.size() + f->quadrangles.size()); - int labelNum = 0; - drawLabels(f, f->triangles, labelStep, labelNum, - CTX.mesh.surfaces_faces, CTX.color.mesh.line); - drawLabels(f, f->quadrangles, labelStep, labelNum, - CTX.mesh.surfaces_faces, CTX.color.mesh.line); + drawElementLabels(f, f->triangles, CTX.mesh.surfaces_faces, CTX.color.mesh.line); + drawElementLabels(f, f->quadrangles, CTX.mesh.surfaces_faces, CTX.color.mesh.line); } - if(CTX.mesh.points || CTX.mesh.points_num) - drawVertices(f); + if(CTX.mesh.points || CTX.mesh.points_num){ + if(m->allElementsVisible) + drawVerticesPerEntity(f); + else{ + drawVerticesPerElement(f, f->triangles); + drawVerticesPerElement(f, f->quadrangles); + } + } if(CTX.mesh.normals) { drawNormals(f->triangles); @@ -606,34 +663,34 @@ class initMeshGRegion { MRep *m = r->meshRep; m->resetArrays(); + m->allElementsVisible = + areAllElementsVisible(r->tetrahedra) && + areAllElementsVisible(r->hexahedra) && + areAllElementsVisible(r->prisms) && + areAllElementsVisible(r->pyramids); bool useEdges = CTX.mesh.volumes_edges ? true : false; - if(CTX.mesh.volumes_faces /*this will change!*/ || CTX.mesh.explode != 1. || - CTX.mesh.quality_sup || CTX.mesh.radius_sup || CTX.mesh.use_cut_plane || - !allElementsVisible(r->tetrahedra) || !allElementsVisible(r->hexahedra) || - !allElementsVisible(r->prisms) || !allElementsVisible(r->pyramids)) + if(CTX.mesh.volumes_faces /*this will change!*/ || + CTX.mesh.explode != 1. || !m->allElementsVisible) useEdges = false; - + if(useEdges){ Msg(DEBUG, "Using edges to draw volume %d", r->tag()); m->generateEdgeRep(); m->va_lines = new VertexArray(2, m->getNumEdgeRep()); - addEdgesInArrays(r, m->va_lines, m); + addEdgesInArrays(r); } else if(CTX.mesh.volumes_edges || CTX.mesh.volumes_faces){ m->va_triangles = new VertexArray(3, 4 * r->tetrahedra.size() + 2 * r->prisms.size() + 4 * r->pyramids.size()); - addElementsInArrays(r, m->va_triangles, r->tetrahedra); - addElementsInArrays(r, m->va_triangles, r->prisms); - addElementsInArrays(r, m->va_triangles, r->pyramids); - m->va_quads = new VertexArray(4, 6 * r->hexahedra.size() + 3 * r->prisms.size() + r->pyramids.size()); - addElementsInArrays(r, m->va_quads, r->hexahedra); - addElementsInArrays(r, m->va_quads, r->prisms); - addElementsInArrays(r, m->va_quads, r->pyramids); + addElementsInArrays(r, r->tetrahedra); + addElementsInArrays(r, r->hexahedra); + addElementsInArrays(r, r->prisms); + addElementsInArrays(r, r->pyramids); } } }; @@ -653,7 +710,7 @@ class drawMeshGRegion { if(CTX.mesh.volumes_edges){ if(m->va_lines && m->va_lines->n()){ - drawArrays(m->va_lines, GL_LINES, false, + drawArrays(m->va_lines, GL_LINES, CTX.mesh.light && CTX.mesh.light_lines, CTX.mesh.color_carousel == 3, false, getColor(r, CTX.mesh.volumes_faces, CTX.color.mesh.line)); } @@ -668,31 +725,40 @@ class drawMeshGRegion { } if(CTX.mesh.volumes_faces){ + // Note: color will be incorrect for mixed meshes when coloring + // by element type + unsigned int col3 = r->tetrahedra.size() ? CTX.color.mesh.tetrahedron : + r->prisms.size() ? CTX.color.mesh.prism : CTX.color.mesh.pyramid; drawArrays(m->va_triangles, GL_TRIANGLES, CTX.mesh.light, - CTX.mesh.color_carousel == 3, CTX.polygon_offset, - getColor(r, 0, CTX.color.mesh.tetrahedron)); + CTX.mesh.color_carousel == 3, CTX.polygon_offset, getColor(r, 0, col3)); + unsigned int col4 = r->hexahedra.size() ? CTX.color.mesh.hexahedron : + r->prisms.size() ? CTX.color.mesh.prism : CTX.color.mesh.pyramid; drawArrays(m->va_quads, GL_QUADS, CTX.mesh.light, - CTX.mesh.color_carousel == 3, CTX.polygon_offset, - getColor(r, 0, CTX.color.mesh.hexahedron)); + CTX.mesh.color_carousel == 3, CTX.polygon_offset, getColor(r, 0, col4)); } - + if(CTX.mesh.volumes_num) { - const int labelStep = getLabelStep(r->tetrahedra.size() + r->hexahedra.size() + - r->prisms.size() + r->pyramids.size()); - int labelNum = 0; - drawLabels(r, r->tetrahedra, labelStep, labelNum, - CTX.mesh.volumes_faces || CTX.mesh.surfaces_faces, CTX.color.mesh.line); - drawLabels(r, r->hexahedra, labelStep, labelNum, - CTX.mesh.volumes_faces || CTX.mesh.surfaces_faces, CTX.color.mesh.line); - drawLabels(r, r->prisms, labelStep, labelNum, - CTX.mesh.volumes_faces || CTX.mesh.surfaces_faces, CTX.color.mesh.line); - drawLabels(r, r->pyramids, labelStep, labelNum, - CTX.mesh.volumes_faces || CTX.mesh.surfaces_faces, CTX.color.mesh.line); + drawElementLabels(r, r->tetrahedra, CTX.mesh.volumes_faces || + CTX.mesh.surfaces_faces, CTX.color.mesh.line); + drawElementLabels(r, r->hexahedra, CTX.mesh.volumes_faces || + CTX.mesh.surfaces_faces, CTX.color.mesh.line); + drawElementLabels(r, r->prisms, CTX.mesh.volumes_faces || + CTX.mesh.surfaces_faces, CTX.color.mesh.line); + drawElementLabels(r, r->pyramids, CTX.mesh.volumes_faces || + CTX.mesh.surfaces_faces, CTX.color.mesh.line); + } + + if(CTX.mesh.points || CTX.mesh.points_num){ + if(m->allElementsVisible) + drawVerticesPerEntity(r); + else{ + drawVerticesPerElement(r, r->tetrahedra); + drawVerticesPerElement(r, r->hexahedra); + drawVerticesPerElement(r, r->prisms); + drawVerticesPerElement(r, r->pyramids); + } } - if(CTX.mesh.points || CTX.mesh.points_num) - drawVertices(r); - if(CTX.mesh.dual) { drawBarycentricDual(r->tetrahedra); drawBarycentricDual(r->hexahedra); -- GitLab