From 98a4cb20a1acc04182633cbca299df7090b98984 Mon Sep 17 00:00:00 2001 From: Christophe Geuzaine <cgeuzaine@ulg.ac.be> Date: Wed, 1 Nov 2006 22:19:27 +0000 Subject: [PATCH] more work on mesh editing --- Common/Context.h | 1 + Common/Options.cpp | 7 +--- Common/VertexArray.cpp | 9 ++--- Fltk/Callbacks.cpp | 40 ++++++------------- Fltk/Opengl.cpp | 9 ++--- Fltk/Opengl_Window.cpp | 6 +-- Geo/GModel.cpp | 83 ++++++++++++++++++++++++++++++++++++++- Geo/GModel.h | 3 +- Graphics/Mesh.cpp | 10 ++--- Graphics/SelectBuffer.cpp | 14 +++---- Graphics/SelectBuffer.h | 9 ++--- 11 files changed, 125 insertions(+), 66 deletions(-) diff --git a/Common/Context.h b/Common/Context.h index d6e791b8ae..f5a3dfeb0a 100644 --- a/Common/Context.h +++ b/Common/Context.h @@ -134,6 +134,7 @@ public : int forced_bbox; // dynamic variable tracking if the bbox is currently imposed int enable_mouse_selection; // enable selection using the mouse + int pick_elements; // allow individual element picking int expert_mode; // to disable some warnings for beginners int printing; // dynamic: equal to 1 while gmsh is printing diff --git a/Common/Options.cpp b/Common/Options.cpp index 8e78bd5988..e23d4f30a0 100644 --- a/Common/Options.cpp +++ b/Common/Options.cpp @@ -1,4 +1,4 @@ -// $Id: Options.cpp,v 1.312 2006-09-24 05:59:13 geuzaine Exp $ +// $Id: Options.cpp,v 1.313 2006-11-01 22:19:26 geuzaine Exp $ // // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle // @@ -134,6 +134,7 @@ void Init_Options(int num) CTX.printing = 0; CTX.mesh_timer[0] = CTX.mesh_timer[1] = CTX.mesh_timer[2] = 0.; CTX.draw_rotation_center = 0; + CTX.pick_elements = 0; CTX.mesh.draw = 1; CTX.post.draw = 1; CTX.post.list = NULL; @@ -2783,10 +2784,6 @@ double opt_general_mouse_selection(OPT_ARGS_NUM) if(!CTX.batch) Msg(STATUS2N, "Mouse selection ON (with mesh hover)"); WID->g_status_butt[9]->color(FL_GREEN); break; - case 3: - if(!CTX.batch) Msg(STATUS2N, "Mouse selection ON (with element hover)"); - WID->g_status_butt[9]->color(FL_YELLOW); - break; case 0: default: if(!CTX.batch) Msg(STATUS2N, "Mouse selection OFF"); diff --git a/Common/VertexArray.cpp b/Common/VertexArray.cpp index 733fd3ca85..9e746bd1f8 100644 --- a/Common/VertexArray.cpp +++ b/Common/VertexArray.cpp @@ -1,4 +1,4 @@ -// $Id: VertexArray.cpp,v 1.15 2006-08-24 01:14:55 geuzaine Exp $ +// $Id: VertexArray.cpp,v 1.16 2006-11-01 22:19:26 geuzaine Exp $ // // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle // @@ -60,8 +60,7 @@ void VertexArray::add(float x, float y, float z, float n0, float n1, float n2, _colors.push_back(b); _colors.push_back(a); - if(ele && CTX.enable_mouse_selection > 2) - _elements.push_back(ele); + if(ele && CTX.pick_elements) _elements.push_back(ele); } void VertexArray::add(float x, float y, float z, unsigned int col, MElement *ele) @@ -79,11 +78,9 @@ void VertexArray::add(float x, float y, float z, unsigned int col, MElement *ele _colors.push_back(b); _colors.push_back(a); - if(ele && CTX.enable_mouse_selection > 2) - _elements.push_back(ele); + if(ele && CTX.pick_elements) _elements.push_back(ele); } - class AlphaElement { public: AlphaElement(float *vp, char *np, unsigned char *cp) : v(vp), n(np), c(cp) {} diff --git a/Fltk/Callbacks.cpp b/Fltk/Callbacks.cpp index 89a9836c15..e2145a86eb 100644 --- a/Fltk/Callbacks.cpp +++ b/Fltk/Callbacks.cpp @@ -1,4 +1,4 @@ -// $Id: Callbacks.cpp,v 1.464 2006-10-31 20:50:35 geuzaine Exp $ +// $Id: Callbacks.cpp,v 1.465 2006-11-01 22:19:26 geuzaine Exp $ // // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle // @@ -479,11 +479,6 @@ void status_xyz1p_cb(CALLBACK_ARGS) // mouse hover and select for geometry and mesh opt_general_mouse_selection(0, GMSH_SET | GMSH_GUI, 2); } - else if(Fl::event_state(FL_META)){ - // mouse hover and select for geometry and mesh, and mouse - // select for individual mesh elements - opt_general_mouse_selection(0, GMSH_SET | GMSH_GUI, 3); - } else if(CTX.enable_mouse_selection){ // mouse does nothing opt_general_mouse_selection(0, GMSH_SET | GMSH_GUI, 0); @@ -491,7 +486,7 @@ void status_xyz1p_cb(CALLBACK_ARGS) } else{ // mouse hover and select for geometry, but mouse select only - // for mesh (default) + // for mesh (default, for performance reasons) opt_general_mouse_selection(0, GMSH_SET | GMSH_GUI, 1); } } @@ -3529,20 +3524,11 @@ void mesh_delete_cb(CALLBACK_ARGS) void mesh_delete_parts_cb(CALLBACK_ARGS) { char *str = (char*)data; - int meshSelection; - if(!strcmp(str, "elements")){ - opt_general_mouse_selection(0, GMSH_SET | GMSH_GUI, 3); - meshSelection = 2; - } - else if(!strcmp(str, "surfaces")){ - opt_general_mouse_selection(0, GMSH_SET | GMSH_GUI, 2); - meshSelection = 1; - } - else{ - Msg(GERROR, "Unknown mesh edit action"); - return; - } + if(!strcmp(str, "elements")) + CTX.pick_elements = 1; + else + CTX.pick_elements = 0; CTX.mesh.changed = ENT_ALL; std::vector<GVertex*> vertices; @@ -3552,7 +3538,7 @@ void mesh_delete_parts_cb(CALLBACK_ARGS) std::vector<MElement*> elements, ele; while(1) { - CTX.mesh.changed = ENT_ALL; + if(CTX.pick_elements) CTX.mesh.changed = ENT_ALL; Draw(); if(ele.size() || fac.size()) @@ -3562,10 +3548,9 @@ void mesh_delete_parts_cb(CALLBACK_ARGS) Msg(ONSCREEN, "Select %s\n" "[Press 'e' to end selection or 'q' to abort]", str); - char ib = SelectEntity(ENT_ALL, vertices, edges, faces, regions, - elements, meshSelection); + char ib = SelectEntity(ENT_ALL, vertices, edges, faces, regions, elements); if(ib == 'l') { - if(meshSelection == 2){ + if(CTX.pick_elements){ for(unsigned int i = 0; i < elements.size(); i++){ if(elements[i]->getVisibility() != 2){ elements[i]->setVisibility(2); @@ -3583,7 +3568,7 @@ void mesh_delete_parts_cb(CALLBACK_ARGS) } } if(ib == 'r') { - if(meshSelection == 2){ + if(CTX.pick_elements){ for(unsigned int i = 0; i < elements.size(); i++) elements[i]->setVisibility(1); } @@ -3593,7 +3578,7 @@ void mesh_delete_parts_cb(CALLBACK_ARGS) } } if(ib == 'u') { - if(meshSelection == 2){ + if(CTX.pick_elements){ if(ele.size()){ ele[ele.size() - 1]->setVisibility(1); ele.pop_back(); @@ -3607,7 +3592,7 @@ void mesh_delete_parts_cb(CALLBACK_ARGS) } } if(ib == 'e') { - if(meshSelection == 2){ + if(CTX.pick_elements){ for(unsigned int i = 0; i < ele.size(); i++) if(ele[i]->getVisibility() == 2) ele[i]->setVisibility(0); } @@ -3627,6 +3612,7 @@ void mesh_delete_parts_cb(CALLBACK_ARGS) } } + CTX.pick_elements = 0; CTX.mesh.changed = ENT_ALL; Draw(); Msg(ONSCREEN, ""); diff --git a/Fltk/Opengl.cpp b/Fltk/Opengl.cpp index d1f5f20b39..a690878377 100644 --- a/Fltk/Opengl.cpp +++ b/Fltk/Opengl.cpp @@ -1,4 +1,4 @@ -// $Id: Opengl.cpp,v 1.68 2006-10-31 20:20:21 geuzaine Exp $ +// $Id: Opengl.cpp,v 1.69 2006-11-01 22:19:26 geuzaine Exp $ // // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle // @@ -194,8 +194,7 @@ char SelectEntity(int type, std::vector<GEdge*> &edges, std::vector<GFace*> &faces, std::vector<GRegion*> ®ions, - std::vector<MElement*> &elements, - int meshSelection) + std::vector<MElement*> &elements) { if(!WID) return 'q'; @@ -240,13 +239,13 @@ char SelectEntity(int type, WID->g_opengl_window->SelectionMode = false; return 'c'; } - else if(ProcessSelectionBuffer(WID->selection, multi, + else if(ProcessSelectionBuffer(WID->selection, multi, true, WID->try_selection_xywh[0], WID->try_selection_xywh[1], WID->try_selection_xywh[2], WID->try_selection_xywh[3], vertices, edges, faces, regions, - elements, meshSelection)){ + elements)){ WID->selection = ENT_NONE; WID->g_opengl_window->SelectionMode = false; if(add) diff --git a/Fltk/Opengl_Window.cpp b/Fltk/Opengl_Window.cpp index 35a4e5970b..8758caac57 100644 --- a/Fltk/Opengl_Window.cpp +++ b/Fltk/Opengl_Window.cpp @@ -1,4 +1,4 @@ -// $Id: Opengl_Window.cpp,v 1.73 2006-10-31 20:20:21 geuzaine Exp $ +// $Id: Opengl_Window.cpp,v 1.74 2006-11-01 22:19:26 geuzaine Exp $ // // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle // @@ -379,11 +379,11 @@ int Opengl_Window::handle(int event) std::vector<GFace*> faces; std::vector<GRegion*> regions; std::vector<MElement*> elements; - int meshSelection = CTX.enable_mouse_selection > 1 ? 1 : 0; bool something = ProcessSelectionBuffer(WID->selection, false, + CTX.enable_mouse_selection > 1, (int)curr.win[0], (int)curr.win[1], 5, 5, vertices, edges, faces, regions, - elements, meshSelection); + elements); if((WID->selection == ENT_ALL && something) || (WID->selection == ENT_POINT && vertices.size()) || (WID->selection == ENT_LINE && edges.size()) || diff --git a/Geo/GModel.cpp b/Geo/GModel.cpp index 909dbd7588..1f4d58a47e 100644 --- a/Geo/GModel.cpp +++ b/Geo/GModel.cpp @@ -1,4 +1,4 @@ -// $Id: GModel.cpp,v 1.17 2006-10-31 20:20:21 geuzaine Exp $ +// $Id: GModel.cpp,v 1.18 2006-11-01 22:19:26 geuzaine Exp $ // // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle // @@ -81,9 +81,88 @@ GVertex * GModel::vertexByTag(int n) const return 0; } +template<class T> +static bool removeElement(MElement *e, std::vector<T*> &vec) +{ + typename std::vector<T*>::iterator it = std::find(vec.begin(), vec.end(), e); + if(it == vec.end()) return false; + vec.erase(it); + delete e; + return true; +} + +bool GModel::remove(MElement *e) +{ + switch(e->getDim()){ + case 3: + for(riter it = firstRegion(); it != lastRegion(); ++it){ + if(removeElement(e, (*it)->tetrahedra)) return true; + if(removeElement(e, (*it)->hexahedra)) return true; + if(removeElement(e, (*it)->prisms)) return true; + if(removeElement(e, (*it)->pyramids)) return true; + } + break; + case 2: + for(fiter it = firstFace(); it != lastFace(); ++it){ + if(removeElement(e, (*it)->triangles)) return true; + if(removeElement(e, (*it)->quadrangles)) return true; + } + break; + case 1: + for(eiter it = firstEdge(); it != lastEdge(); ++it){ + if(removeElement(e, (*it)->lines)) return true; + } + break; + } + return false; +} + void GModel::removeInvisible() { - printf("deleting all invisible entities/elements\n"); + // FIXME: should make this faster + std::vector<MElement*> ele; + for(riter it = firstRegion(); it != lastRegion(); ++it){ + for(unsigned int i = 0; i < (*it)->tetrahedra.size(); i++) + if(!(*it)->tetrahedra[i]->getVisibility()) ele.push_back((*it)->tetrahedra[i]); + for(unsigned int i = 0; i < (*it)->hexahedra.size(); i++) + if(!(*it)->hexahedra[i]->getVisibility()) ele.push_back((*it)->hexahedra[i]); + for(unsigned int i = 0; i < (*it)->prisms.size(); i++) + if(!(*it)->prisms[i]->getVisibility()) ele.push_back((*it)->prisms[i]); + for(unsigned int i = 0; i < (*it)->pyramids.size(); i++) + if(!(*it)->pyramids[i]->getVisibility()) ele.push_back((*it)->pyramids[i]); + } + for(fiter it = firstFace(); it != lastFace(); ++it){ + for(unsigned int i = 0; i < (*it)->triangles.size(); i++) + if(!(*it)->triangles[i]->getVisibility()) ele.push_back((*it)->triangles[i]); + for(unsigned int i = 0; i < (*it)->quadrangles.size(); i++) + if(!(*it)->quadrangles[i]->getVisibility()) ele.push_back((*it)->quadrangles[i]); + } + for(eiter it = firstEdge(); it != lastEdge(); ++it){ + for(unsigned int i = 0; i < (*it)->lines.size(); i++) + if(!(*it)->lines[i]->getVisibility()) ele.push_back((*it)->lines[i]); + } + for(unsigned int i = 0; i < ele.size(); i++) + remove(ele[i]); + + std::vector<GRegion*> r; + for(riter it = firstRegion(); it != lastRegion(); ++it) + if(!(*it)->getVisibility()) r.push_back(*it); + for(unsigned int i = 0; i < r.size(); i++){ remove(r[i]); delete r[i]; } + + std::vector<GFace*> f; + for(fiter it = firstFace(); it != lastFace(); ++it) + if(!(*it)->getVisibility()) f.push_back(*it); + for(unsigned int i = 0; i < f.size(); i++){ remove(f[i]); delete f[i]; } + + std::vector<GEdge*> e; + for(eiter it = firstEdge(); it != lastEdge(); ++it) + if(!(*it)->getVisibility()) e.push_back(*it); + for(unsigned int i = 0; i < e.size(); i++){ remove(e[i]); delete e[i]; } + + std::vector<GVertex*> v; + for(viter it = firstVertex(); it != lastVertex(); ++it) + if(!(*it)->getVisibility()) v.push_back(*it); + for(unsigned int i = 0; i < v.size(); i++){ remove(v[i]); delete v[i]; } } int GModel::renumberMeshVertices() diff --git a/Geo/GModel.h b/Geo/GModel.h index 6bd08c30dc..a4e1acc013 100644 --- a/Geo/GModel.h +++ b/Geo/GModel.h @@ -90,6 +90,7 @@ class GModel void remove(GFace *f) { faces.erase(std::find(firstFace(), lastFace(), f)); } void remove(GEdge *e) { edges.erase(std::find(firstEdge(), lastEdge(), e)); } void remove(GVertex *v) { vertices.erase(std::find(firstVertex(), lastVertex(), v)); } + bool remove(MElement *e); // Deletes all invisble stuff (entities and elements) void removeInvisible(); @@ -154,7 +155,7 @@ class GModel // Export flat Gmsh geo model (only implemented for gmshModel at the moment) virtual int writeGEO(const std::string &name){ return 0; } - // FIXME: this will be removed (and rewritten) + // A container for smooth normals smooth_normals *normals; }; diff --git a/Graphics/Mesh.cpp b/Graphics/Mesh.cpp index c5710a4c0a..654bb21cfa 100644 --- a/Graphics/Mesh.cpp +++ b/Graphics/Mesh.cpp @@ -1,4 +1,4 @@ -// $Id: Mesh.cpp,v 1.185 2006-10-31 20:20:22 geuzaine Exp $ +// $Id: Mesh.cpp,v 1.186 2006-11-01 22:19:26 geuzaine Exp $ // // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle // @@ -442,7 +442,7 @@ static void drawArrays(GEntity *e, VertexArray *va, GLint type, bool useNormalAr // If we want to be enable picking of individual elements we need to // draw each one separately - if(CTX.render_mode == GMSH_SELECT && CTX.enable_mouse_selection > 2) { + if(CTX.render_mode == GMSH_SELECT && CTX.pick_elements) { if(va->getNumElementPointers() == va->getNumVertices()){ for(int i = 0; i < va->getNumVertices(); i += va->getType()){ glPushName(va->getType()); @@ -475,7 +475,7 @@ static void drawArrays(GEntity *e, VertexArray *va, GLint type, bool useNormalAr glDisableClientState(GL_COLOR_ARRAY); glColor4ubv((GLubyte *) & color); } - else if(CTX.enable_mouse_selection > 2){ + else if(CTX.pick_elements){ glEnableClientState(GL_COLOR_ARRAY); } else if(!e->getSelection() && (CTX.mesh.color_carousel == 0 || @@ -617,7 +617,7 @@ class initMeshGFace { // mouse selection of individual elements is complicated if we // don't draw everything per element - if(CTX.enable_mouse_selection > 2) useEdges = false; + if(CTX.pick_elements) useEdges = false; // Further optimizations are possible when useEdges is true: // 1) store the unique vertices in the vertex array and use @@ -731,7 +731,7 @@ class initMeshGRegion { // mouse selection of individual elements is complicated if we // don't draw everything per element - if(CTX.enable_mouse_selection > 2) useEdges = false; + if(CTX.pick_elements) useEdges = false; if(useEdges){ Msg(DEBUG, "Using edges to draw volume %d", r->tag()); diff --git a/Graphics/SelectBuffer.cpp b/Graphics/SelectBuffer.cpp index 8313750c1a..85b793e3fa 100644 --- a/Graphics/SelectBuffer.cpp +++ b/Graphics/SelectBuffer.cpp @@ -1,4 +1,4 @@ -// $Id: SelectBuffer.cpp,v 1.5 2006-10-31 20:20:22 geuzaine Exp $ +// $Id: SelectBuffer.cpp,v 1.6 2006-11-01 22:19:27 geuzaine Exp $ // // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle // @@ -46,14 +46,14 @@ class hitDepthLessThan{ } }; -bool ProcessSelectionBuffer(int entityType, bool multipleSelection, +bool ProcessSelectionBuffer(int entityType, + bool multipleSelection, bool meshSelection, int x, int y, int w, int h, std::vector<GVertex*> &vertices, std::vector<GEdge*> &edges, std::vector<GFace*> &faces, std::vector<GRegion*> ®ions, - std::vector<MElement*> &elements, - int meshSelection) + std::vector<MElement*> &elements) { vertices.clear(); edges.clear(); @@ -63,9 +63,9 @@ bool ProcessSelectionBuffer(int entityType, bool multipleSelection, // In our case the selection buffer size is equal to between 5 and 7 // times the maximum number of possible hits - int size = - 7 * (GMODEL->numVertex() + GMODEL->numEdge() + GMODEL->numFace() + - GMODEL->numRegion() + (meshSelection > 1 ? 3 * GMODEL->numElement() : 0)) ; + int eles = (meshSelection && CTX.pick_elements) ? 3 * GMODEL->numElement() : 0; + int size = 7 * (GMODEL->numVertex() + GMODEL->numEdge() + GMODEL->numFace() + + GMODEL->numRegion() + eles) ; GLuint *selectionBuffer = new GLuint[size]; glSelectBuffer(size, selectionBuffer); diff --git a/Graphics/SelectBuffer.h b/Graphics/SelectBuffer.h index b591bdb621..c2bbebd555 100644 --- a/Graphics/SelectBuffer.h +++ b/Graphics/SelectBuffer.h @@ -35,21 +35,20 @@ #include "GFace.h" #include "GRegion.h" -bool ProcessSelectionBuffer(int entityType, bool multipleSelection, +bool ProcessSelectionBuffer(int entityType, + bool multipleSelection, bool meshSelection, int x, int y, int w, int h, std::vector<GVertex*> &vertices, std::vector<GEdge*> &edges, std::vector<GFace*> &faces, std::vector<GRegion*> ®ions, - std::vector<MElement*> &elements, - int meshSelection); + std::vector<MElement*> &elements); char SelectEntity(int entityType, std::vector<GVertex*> &vertices, std::vector<GEdge*> &edges, std::vector<GFace*> &faces, std::vector<GRegion*> ®ions, - std::vector<MElement*> &elements, - int meshSelection=1); + std::vector<MElement*> &elements); void HighlightEntity(GEntity *e, bool permanent=false); void HighlightEntity(GVertex *v, GEdge *e, GFace *f, GRegion *r, bool permanent=false); -- GitLab