diff --git a/Fltk/Callbacks.cpp b/Fltk/Callbacks.cpp index fb37ef93ead6d5ee2dad8a324570a9d13112b676..1799562d750212d9e737b8d36696f87783687bf4 100644 --- a/Fltk/Callbacks.cpp +++ b/Fltk/Callbacks.cpp @@ -1,4 +1,4 @@ -// $Id: Callbacks.cpp,v 1.462 2006-10-09 13:26:26 geuzaine Exp $ +// $Id: Callbacks.cpp,v 1.463 2006-10-31 20:20:21 geuzaine Exp $ // // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle // @@ -476,13 +476,13 @@ void status_xyz1p_cb(CALLBACK_ARGS) } else if(!strcmp(str, "S")){ // mouse selection if(Fl::event_state(FL_SHIFT)){ - // full mouse hover and select for geometry and mesh + // 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)){ - // full hover and select, even for mesh elements + // 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); - CTX.mesh.changed = ENT_ALL; // need to regenerate the mesh reps } else if(CTX.enable_mouse_selection){ // mouse does nothing @@ -930,9 +930,10 @@ void general_options_rotation_center_select_cb(CALLBACK_ARGS) std::vector<GEdge*> edges; std::vector<GFace*> faces; std::vector<GRegion*> regions; + std::vector<MElement*> elements; Msg(ONSCREEN, "Select entity\n[Press 'q' to abort]"); - char ib = SelectEntity(ENT_ALL, vertices, edges, faces, regions); + char ib = SelectEntity(ENT_ALL, vertices, edges, faces, regions, elements); if(ib == 'l') { SPoint3 pc(0., 0., 0.); if(vertices.size()) @@ -943,6 +944,8 @@ void general_options_rotation_center_select_cb(CALLBACK_ARGS) pc = faces[0]->bounds().center(); else if(regions.size()) pc = regions[0]->bounds().center(); + else if(elements.size()) + pc = elements[0]->barycenter(); opt_general_rotation_center_cg(0, GMSH_SET, WID->gen_butt[15]->value()); opt_general_rotation_center0(0, GMSH_SET|GMSH_GUI, pc.x()); opt_general_rotation_center1(0, GMSH_SET|GMSH_GUI, pc.y()); @@ -2510,7 +2513,8 @@ void geometry_elementary_add_new_point_cb(CALLBACK_ARGS) std::vector<GEdge*> edges; std::vector<GFace*> faces; std::vector<GRegion*> regions; - char ib = SelectEntity(ENT_NONE, vertices, edges, faces, regions); + std::vector<MElement*> elements; + char ib = SelectEntity(ENT_NONE, vertices, edges, faces, regions, elements); if(ib == 'e'){ add_point(CTX.filename, (char*)WID->context_geometry_input[2]->value(), @@ -2535,6 +2539,7 @@ static void _new_multiline(int type) std::vector<GEdge*> edges; std::vector<GFace*> faces; std::vector<GRegion*> regions; + std::vector<MElement*> elements; int p[100]; opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1); @@ -2549,10 +2554,13 @@ static void _new_multiline(int type) else Msg(ONSCREEN, "Select control points\n" "[Press 'e' to end selection, 'u' to undo last selection or 'q' to abort]"); - char ib = SelectEntity(ENT_POINT, vertices, edges, faces, regions); + char ib = SelectEntity(ENT_POINT, vertices, edges, faces, regions, elements); if(ib == 'l') { - for(unsigned int i = 0; i < vertices.size(); i++) + for(unsigned int i = 0; i < vertices.size(); i++){ + HighlightEntity(vertices[i], true); p[n++] = vertices[i]->tag(); + } + Draw(); } if(ib == 'r') { Msg(WARNING, "Entity de-selection not supported yet during multi-line creation"); @@ -2607,6 +2615,7 @@ void geometry_elementary_add_new_line_cb(CALLBACK_ARGS) std::vector<GEdge*> edges; std::vector<GFace*> faces; std::vector<GRegion*> regions; + std::vector<MElement*> elements; int p[100]; opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1); @@ -2621,8 +2630,10 @@ void geometry_elementary_add_new_line_cb(CALLBACK_ARGS) if(n == 1) Msg(ONSCREEN, "Select end point\n" "[Press 'u' to undo last selection or 'q' to abort]"); - char ib = SelectEntity(ENT_POINT, vertices, edges, faces, regions); + char ib = SelectEntity(ENT_POINT, vertices, edges, faces, regions, elements); if(ib == 'l') { + HighlightEntity(vertices[0], true); + Draw(); p[n++] = vertices[0]->tag(); } if(ib == 'r') { @@ -2668,6 +2679,7 @@ void geometry_elementary_add_new_circle_cb(CALLBACK_ARGS) std::vector<GEdge*> edges; std::vector<GFace*> faces; std::vector<GRegion*> regions; + std::vector<MElement*> elements; int p[100]; opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1); @@ -2685,8 +2697,10 @@ void geometry_elementary_add_new_circle_cb(CALLBACK_ARGS) if(n == 2) Msg(ONSCREEN, "Select end point\n" "[Press 'u' to undo last selection or 'q' to abort]"); - char ib = SelectEntity(ENT_POINT, vertices, edges, faces, regions); + char ib = SelectEntity(ENT_POINT, vertices, edges, faces, regions, elements); if(ib == 'l') { + HighlightEntity(vertices[0], true); + Draw(); p[n++] = vertices[0]->tag(); } if(ib == 'r') { @@ -2722,6 +2736,7 @@ void geometry_elementary_add_new_ellipse_cb(CALLBACK_ARGS) std::vector<GEdge*> edges; std::vector<GFace*> faces; std::vector<GRegion*> regions; + std::vector<MElement*> elements; int p[100]; opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1); @@ -2742,8 +2757,10 @@ void geometry_elementary_add_new_ellipse_cb(CALLBACK_ARGS) if(n == 3) Msg(ONSCREEN, "Select end point\n" "[Press 'u' to undo last selection or 'q' to abort]"); - char ib = SelectEntity(ENT_POINT, vertices, edges, faces, regions); + char ib = SelectEntity(ENT_POINT, vertices, edges, faces, regions, elements); if(ib == 'l') { + HighlightEntity(vertices[0], true); + Draw(); p[n++] = vertices[0]->tag(); } if(ib == 'r') { @@ -2779,6 +2796,7 @@ static void _new_surface_volume(int mode) std::vector<GEdge*> edges; std::vector<GFace*> faces; std::vector<GRegion*> regions; + std::vector<MElement*> elements; int type, num; List_T *List1 = List_Create(10, 10, sizeof(int)); @@ -2818,7 +2836,7 @@ static void _new_surface_volume(int mode) "[Press 'u' to undo last selection or 'q' to abort]"); } - char ib = SelectEntity(type, vertices, edges, faces, regions); + char ib = SelectEntity(type, vertices, edges, faces, regions, elements); if(ib == 'q') { ZeroHighlight(); Draw(); @@ -2854,7 +2872,7 @@ static void _new_surface_volume(int mode) else Msg(ONSCREEN, "Select hole boundaries\n" "[Press 'e' to end selection, 'u' to undo last selection or 'q' to abort]"); - ib = SelectEntity(type, vertices, edges, faces, regions); + ib = SelectEntity(type, vertices, edges, faces, regions, elements); if(ib == 'q') { ZeroHighlight(); Draw(); @@ -2936,6 +2954,7 @@ static void _action_point_line_surface_volume(int action, int mode, char *what) std::vector<GEdge*> edges; std::vector<GFace*> faces; std::vector<GRegion*> regions; + std::vector<MElement*> elements; int type; char *str; @@ -2982,7 +3001,7 @@ static void _action_point_line_surface_volume(int action, int mode, char *what) Msg(ONSCREEN, "Select %s\n" "[Press 'e' to end selection, 'u' to undo last selection or 'q' to abort]", str); - char ib = SelectEntity(type, vertices, edges, faces, regions); + char ib = SelectEntity(type, vertices, edges, faces, regions, elements); if(ib == 'l') { // we don't use List_Insert in order to keep the original // ordering (this is slower, but this way undo works as @@ -2991,6 +3010,7 @@ static void _action_point_line_surface_volume(int action, int mode, char *what) switch (type) { case ENT_POINT: for(unsigned int i = 0; i < vertices.size(); i++){ + HighlightEntity(vertices[i], true); tag = vertices[i]->tag(); if(List_ISearchSeq(List1, &tag, fcmp_int) < 0) List_Add(List1, &tag); @@ -2998,6 +3018,7 @@ static void _action_point_line_surface_volume(int action, int mode, char *what) break; case ENT_LINE: for(unsigned int i = 0; i < edges.size(); i++){ + HighlightEntity(edges[i], true); tag = edges[i]->tag(); if(List_ISearchSeq(List1, &tag, fcmp_int) < 0) List_Add(List1, &tag); @@ -3005,6 +3026,7 @@ static void _action_point_line_surface_volume(int action, int mode, char *what) break; case ENT_SURFACE: for(unsigned int i = 0; i < faces.size(); i++){ + HighlightEntity(faces[i], true); tag = faces[i]->tag(); if(List_ISearchSeq(List1, &tag, fcmp_int) < 0) List_Add(List1, &tag); @@ -3012,12 +3034,14 @@ static void _action_point_line_surface_volume(int action, int mode, char *what) break; case ENT_VOLUME: for(unsigned int i = 0; i < regions.size(); i++){ + HighlightEntity(regions[i], true); tag = regions[i]->tag(); if(List_ISearchSeq(List1, &tag, fcmp_int) < 0) List_Add(List1, &tag); } break; } + Draw(); } if(ib == 'r') { // we don't use List_Suppress in order to keep the original @@ -3497,14 +3521,120 @@ void mesh_edit_cb(CALLBACK_ARGS) WID->set_context(menu_mesh_edit, 0); } -void mesh_parameterize_cb(CALLBACK_ARGS) +void mesh_delete_cb(CALLBACK_ARGS) { - printf("LAUNCH REPARAMETERIZATION WINDOW!\n"); + WID->set_context(menu_mesh_delete, 0); +} + +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; + } + CTX.mesh.changed = ENT_ALL; + + std::vector<GVertex*> vertices; + std::vector<GEdge*> edges; + std::vector<GFace*> faces, fac; + std::vector<GRegion*> regions; + std::vector<MElement*> elements, ele; + + while(1) { + CTX.mesh.changed = ENT_ALL; + Draw(); + + if(!ele.size()) + Msg(ONSCREEN, "Select %s\n" + "[Press 'e' to end selection or 'q' to abort]", str); + else + Msg(ONSCREEN, "Select %s\n" + "[Press 'e' to end selection, 'u' to undo last selection or 'q' to abort]", str); + + char ib = SelectEntity(ENT_ALL, vertices, edges, faces, regions, + elements, meshSelection); + if(ib == 'l') { + if(meshSelection == 2){ + for(unsigned int i = 0; i < elements.size(); i++){ + if(elements[i]->getVisibility() != 2){ + elements[i]->setVisibility(2); + ele.push_back(elements[i]); + } + } + } + else{ + for(unsigned int i = 0; i < faces.size(); i++){ + if(faces[i]->getSelection() != 1){ + faces[i]->setSelection(1); + fac.push_back(faces[i]); + } + } + } + } + if(ib == 'r') { + if(meshSelection == 2){ + for(unsigned int i = 0; i < elements.size(); i++) + elements[i]->setVisibility(1); + } + else{ + for(unsigned int i = 0; i < faces.size(); i++) + faces[i]->setSelection(0); + } + } + if(ib == 'u') { + if(meshSelection == 2){ + if(ele.size()){ + ele[ele.size() - 1]->setVisibility(1); + ele.pop_back(); + } + } + else{ + if(fac.size()){ + fac[fac.size() - 1]->setSelection(0); + fac.pop_back(); + } + } + } + if(ib == 'e') { + if(meshSelection == 2){ + for(unsigned int i = 0; i < ele.size(); i++) + if(ele[i]->getVisibility() == 2) ele[i]->setVisibility(0); + } + else{ + for(unsigned int i = 0; i < fac.size(); i++) + if(fac[i]->getSelection() == 1) fac[i]->setVisibility(0); + } + GMODEL->removeInvisible(); + ele.clear(); + fac.clear(); + } + if(ib == 'q') { + for(unsigned int i = 0; i < ele.size(); i++) + if(ele[i]->getVisibility() == 2) ele[i]->setVisibility(1); + ZeroHighlight(); + break; + } + } + + CTX.mesh.changed = ENT_ALL; + Draw(); + Msg(ONSCREEN, ""); } -void mesh_cut_parts_cb(CALLBACK_ARGS) +void mesh_parameterize_cb(CALLBACK_ARGS) { - printf("LAUNCH CUTTING TOOL!\n"); + printf("LAUNCH REPARAMETERIZATION WINDOW!\n"); } void mesh_degree_cb(CALLBACK_ARGS) @@ -3543,11 +3673,6 @@ void mesh_update_edges_cb(CALLBACK_ARGS) Msg(GERROR, "BDS->classify() must be reinterfaced"); } -void mesh_update_more_edges_cb(CALLBACK_ARGS) -{ - _action_point_line_surface_volume(10, 0, "Line"); -} - void mesh_define_length_cb(CALLBACK_ARGS) { _action_point_line_surface_volume(8, 0, "Point"); @@ -3569,6 +3694,7 @@ static void _add_transfinite_elliptic(int type, int dim) std::vector<GEdge*> edges; std::vector<GFace*> faces; std::vector<GRegion*> regions; + std::vector<MElement*> elements; char ib; int p[100]; @@ -3590,15 +3716,15 @@ static void _add_transfinite_elliptic(int type, int dim) else Msg(ONSCREEN, "Select lines\n" "[Press 'e' to end selection, 'u' to undo last selection or 'q' to abort]"); - ib = SelectEntity(ENT_LINE, vertices, edges, faces, regions); + ib = SelectEntity(ENT_LINE, vertices, edges, faces, regions, elements); break; case 2: Msg(ONSCREEN, "Select surface\n[Press 'q' to abort]"); - ib = SelectEntity(ENT_SURFACE, vertices, edges, faces, regions); + ib = SelectEntity(ENT_SURFACE, vertices, edges, faces, regions, elements); break; case 3: Msg(ONSCREEN, "Select volume\n[Press 'q' to abort]"); - ib = SelectEntity(ENT_VOLUME, vertices, edges, faces, regions); + ib = SelectEntity(ENT_VOLUME, vertices, edges, faces, regions, elements); break; default: ib = 'l'; @@ -3637,14 +3763,22 @@ static void _add_transfinite_elliptic(int type, int dim) if(ib == 'l') { switch (dim) { case 1: + HighlightEntity(edges[0], true); + Draw(); p[n++] = edges[0]->tag(); break; case 2: case 3: - if(dim == 2) + if(dim == 2){ + HighlightEntity(faces[0], true); + Draw(); p[n++] = faces[0]->tag(); - else + } + else{ + HighlightEntity(regions[0], true); + Draw(); p[n++] = regions[0]->tag(); + } while(1) { if(n == 1) Msg(ONSCREEN, "Select (ordered) boundary points\n" @@ -3652,8 +3786,10 @@ static void _add_transfinite_elliptic(int type, int dim) else Msg(ONSCREEN, "Select (ordered) boundary points\n" "[Press 'e' to end selection, 'u' to undo last selection or 'q' to abort]"); - ib = SelectEntity(ENT_POINT, vertices, edges, faces, regions); + ib = SelectEntity(ENT_POINT, vertices, edges, faces, regions, elements); if(ib == 'l') { + HighlightEntity(vertices[0], true); + Draw(); p[n++] = vertices[0]->tag(); } if(ib == 'u') { diff --git a/Fltk/Callbacks.h b/Fltk/Callbacks.h index 23a71247b91571ee70f05c7e457e271be7f3daee..85921b125390e0cbc6a0207a4d9df2e40b997b23 100644 --- a/Fltk/Callbacks.h +++ b/Fltk/Callbacks.h @@ -272,10 +272,10 @@ void mesh_1d_cb(CALLBACK_ARGS); void mesh_2d_cb(CALLBACK_ARGS); void mesh_3d_cb(CALLBACK_ARGS); void mesh_edit_cb(CALLBACK_ARGS); +void mesh_delete_cb(CALLBACK_ARGS); +void mesh_delete_parts_cb(CALLBACK_ARGS); void mesh_remesh_cb(CALLBACK_ARGS); void mesh_update_edges_cb(CALLBACK_ARGS); -void mesh_update_more_edges_cb(CALLBACK_ARGS); -void mesh_cut_parts_cb(CALLBACK_ARGS); void mesh_parameterize_cb(CALLBACK_ARGS); void mesh_degree_cb(CALLBACK_ARGS); void mesh_optimize_cb(CALLBACK_ARGS); diff --git a/Fltk/GUI.cpp b/Fltk/GUI.cpp index c78f92e732ec7fca11f10257461ca27b5e5f70f3..573cb7b3c7fba53b5b9a9b94c24be5fa888fec75 100644 --- a/Fltk/GUI.cpp +++ b/Fltk/GUI.cpp @@ -1,4 +1,4 @@ -// $Id: GUI.cpp,v 1.554 2006-10-10 14:04:13 geuzaine Exp $ +// $Id: GUI.cpp,v 1.555 2006-10-31 20:20:21 geuzaine Exp $ // // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle // @@ -336,13 +336,18 @@ Context_Item menu_mesh[] = { }; Context_Item menu_mesh_edit[] = { {"1Mesh>Edit", NULL} , - {"Cut parts", (Fl_Callback *)mesh_cut_parts_cb} , + {"Delete", (Fl_Callback *)mesh_delete_cb} , {"Parameterize", (Fl_Callback *)mesh_parameterize_cb} , //{"Update edges", (Fl_Callback *)mesh_update_edges_cb} , - //{"Manually add edges", (Fl_Callback *)mesh_update_more_edges_cb} , //{"Remesh", (Fl_Callback *)mesh_remesh_cb} , {0} }; + Context_Item menu_mesh_delete[] = { + {"1Mesh>Edit>Delete", NULL} , + {"Elements", (Fl_Callback *)mesh_delete_parts_cb, (void*)"elements"} , + {"Surfaces", (Fl_Callback *)mesh_delete_parts_cb, (void*)"surfaces"} , + {0} + }; Context_Item menu_mesh_define[] = { {"1Mesh>Define", NULL} , {"Characteristic length", (Fl_Callback *)mesh_define_length_cb } , diff --git a/Fltk/GUI.h b/Fltk/GUI.h index fa08a446aa7f1cd09188d906faa8073058425a2a..67b33d7871c0f3ef3acc0c09910adc7dafd0b238 100644 --- a/Fltk/GUI.h +++ b/Fltk/GUI.h @@ -89,6 +89,7 @@ extern Context_Item menu_geometry_physical[]; extern Context_Item menu_geometry_physical_add[]; extern Context_Item menu_mesh[]; extern Context_Item menu_mesh_edit[]; +extern Context_Item menu_mesh_delete[]; extern Context_Item menu_mesh_define[]; extern Context_Item menu_mesh_define_transfinite[]; extern Context_Item menu_solver[]; diff --git a/Fltk/Opengl.cpp b/Fltk/Opengl.cpp index 0daf57d8a07231743c44d1cfa71f2311d1808a8c..d1f5f20b39f5a786a24f3d519ba36d9089b474e8 100644 --- a/Fltk/Opengl.cpp +++ b/Fltk/Opengl.cpp @@ -1,4 +1,4 @@ -// $Id: Opengl.cpp,v 1.67 2006-08-23 19:53:38 geuzaine Exp $ +// $Id: Opengl.cpp,v 1.68 2006-10-31 20:20:21 geuzaine Exp $ // // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle // @@ -189,11 +189,13 @@ void Draw_OnScreenMessages() // Select entity routine -char SelectEntity(int type, +char SelectEntity(int type, std::vector<GVertex*> &vertices, std::vector<GEdge*> &edges, std::vector<GFace*> &faces, - std::vector<GRegion*> ®ions) + std::vector<GRegion*> ®ions, + std::vector<MElement*> &elements, + int meshSelection) { if(!WID) return 'q'; @@ -211,6 +213,7 @@ char SelectEntity(int type, edges.clear(); faces.clear(); regions.clear(); + elements.clear(); WID->wait(); if(WID->quit_selection) { WID->selection = ENT_NONE; @@ -237,32 +240,19 @@ char SelectEntity(int type, WID->g_opengl_window->SelectionMode = false; return 'c'; } - else if(ProcessSelectionBuffer(WID->selection, multi, true, + else if(ProcessSelectionBuffer(WID->selection, multi, WID->try_selection_xywh[0], WID->try_selection_xywh[1], WID->try_selection_xywh[2], WID->try_selection_xywh[3], - vertices, edges, faces, regions)){ + vertices, edges, faces, regions, + elements, meshSelection)){ WID->selection = ENT_NONE; WID->g_opengl_window->SelectionMode = false; - if(add){ - for(unsigned int i = 0; i < vertices.size(); i++) - HighlightEntity(vertices[i], true); - for(unsigned int i = 0; i < edges.size(); i++) - HighlightEntity(edges[i], true); - for(unsigned int i = 0; i < faces.size(); i++) - HighlightEntity(faces[i], true); - for(unsigned int i = 0; i < regions.size(); i++) - HighlightEntity(regions[i], true); - Draw(); + if(add) return 'l'; - } - else{ - // Don't call ZeroHighlight here if we try to deselect: - // deselection is not supported in all cases, so it's better - // to de-highlight the entities in the callback later + else return 'r'; - } } } } diff --git a/Fltk/Opengl_Window.cpp b/Fltk/Opengl_Window.cpp index d3b0ef4e8dd422a57afe0c1ea4cc91c4b42050c3..35a4e5970b62d7320c3808fae7574ae6fd5cbbb8 100644 --- a/Fltk/Opengl_Window.cpp +++ b/Fltk/Opengl_Window.cpp @@ -1,4 +1,4 @@ -// $Id: Opengl_Window.cpp,v 1.72 2006-10-10 13:57:10 geuzaine Exp $ +// $Id: Opengl_Window.cpp,v 1.73 2006-10-31 20:20:21 geuzaine Exp $ // // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle // @@ -378,10 +378,12 @@ int Opengl_Window::handle(int event) std::vector<GEdge*> edges; std::vector<GFace*> faces; std::vector<GRegion*> regions; - bool something = ProcessSelectionBuffer(WID->selection, false, - CTX.enable_mouse_selection > 1, + std::vector<MElement*> elements; + int meshSelection = CTX.enable_mouse_selection > 1 ? 1 : 0; + bool something = ProcessSelectionBuffer(WID->selection, false, (int)curr.win[0], (int)curr.win[1], 5, 5, - vertices, edges, faces, regions); + vertices, edges, faces, regions, + elements, meshSelection); 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 888a474fe8505ef5e5418b54001654813d49cf21..909dbd75884ccc1178086382d768c9b4ea48b591 100644 --- a/Geo/GModel.cpp +++ b/Geo/GModel.cpp @@ -1,4 +1,4 @@ -// $Id: GModel.cpp,v 1.16 2006-08-20 03:54:54 geuzaine Exp $ +// $Id: GModel.cpp,v 1.17 2006-10-31 20:20:21 geuzaine Exp $ // // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle // @@ -81,6 +81,11 @@ GVertex * GModel::vertexByTag(int n) const return 0; } +void GModel::removeInvisible() +{ + printf("deleting all invisible entities/elements\n"); +} + int GModel::renumberMeshVertices() { int numVertices = 0; @@ -179,6 +184,24 @@ int GModel::getMeshStatus() return -1; } +int GModel::numElement() +{ + int n = 0; + for(eiter it = firstEdge(); it != lastEdge(); ++it) + n += (*it)->lines.size(); + for(fiter it = firstFace(); it != lastFace(); ++it){ + n += (*it)->triangles.size(); + n += (*it)->quadrangles.size(); + } + for(riter it = firstRegion(); it != lastRegion(); ++it){ + n += (*it)->tetrahedra.size(); + n += (*it)->hexahedra.size(); + n += (*it)->prisms.size(); + n += (*it)->pyramids.size(); + } + return n; +} + std::set<int> &GModel::recomputeMeshPartitions() { for(eiter it = firstEdge(); it != lastEdge(); ++it) diff --git a/Geo/GModel.h b/Geo/GModel.h index c6794a90daac14a61424ae347ed5a83059b4c0ec..6bd08c30dc264fa987397d0be67e0009269dd4fd 100644 --- a/Geo/GModel.h +++ b/Geo/GModel.h @@ -91,6 +91,9 @@ class GModel void remove(GEdge *e) { edges.erase(std::find(firstEdge(), lastEdge(), e)); } void remove(GVertex *v) { vertices.erase(std::find(firstVertex(), lastVertex(), v)); } + // Deletes all invisble stuff (entities and elements) + void removeInvisible(); + // Renumber all the mesh vertices in a continuous sequence int renumberMeshVertices(); @@ -109,6 +112,9 @@ class GModel // Returns the mesh status for the entire model. virtual int getMeshStatus(); + // Returns the total number of elements in the mesh + virtual int numElement(); + // The list of partitions virtual std::set<int> &getMeshPartitions() { return meshPartitions; } virtual std::set<int> &recomputeMeshPartitions(); diff --git a/Geo/fourierModel.cpp b/Geo/fourierModel.cpp index 4e478d72c77772a67e0ae8c47b1fdde8b19d235b..0d0918ca32df362fd90da3dec8d94368a89dfe64 100644 --- a/Geo/fourierModel.cpp +++ b/Geo/fourierModel.cpp @@ -526,6 +526,8 @@ fourierModel::fourierModel(const std::string &name) // mesh each face with quads std::for_each(firstFace(), lastFace(), meshCartesian()); + return; + // compute partition of unity std::for_each(firstFace(), lastFace(), computePartitionOfUnity()); diff --git a/Graphics/Mesh.cpp b/Graphics/Mesh.cpp index f6814248d9d5c875ab5f6cd8ce4d68b15b8d4ddf..c5710a4c0ad9b461b0cb27352d0e3050cc473f2d 100644 --- a/Graphics/Mesh.cpp +++ b/Graphics/Mesh.cpp @@ -1,4 +1,4 @@ -// $Id: Mesh.cpp,v 1.184 2006-08-24 01:14:59 geuzaine Exp $ +// $Id: Mesh.cpp,v 1.185 2006-10-31 20:20:22 geuzaine Exp $ // // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle // @@ -34,28 +34,6 @@ extern Context_T CTX; // General helper routines -static unsigned int getColorByElement(MElement *ele) -{ - if(CTX.mesh.color_carousel == 0){ // by element type - switch(ele->getNumEdges()){ - case 1: return CTX.color.mesh.line; - case 3: return CTX.color.mesh.triangle; - case 4: return CTX.color.mesh.quadrangle; - case 6: return CTX.color.mesh.tetrahedron; - case 12: return CTX.color.mesh.hexahedron; - case 9: return CTX.color.mesh.prism; - case 8: return CTX.color.mesh.pyramid; - default: return CTX.color.mesh.vertex; - } - } - else if(CTX.mesh.color_carousel == 3){ // by partition - return CTX.color.mesh.carousel[abs(ele->getPartition() % 20)]; - } - else{ - return CTX.color.fg; - } -} - static unsigned int getColorByEntity(GEntity *e) { if(e->getSelection()){ // selection @@ -82,6 +60,33 @@ static unsigned int getColorByEntity(GEntity *e) } } +static unsigned int getColorByElement(MElement *ele) +{ + if(ele->getVisibility() > 1){ // selection + switch(ele->getDim()){ + case 0: return CTX.color.geom.point_sel; + case 1: return CTX.color.geom.line_sel; + case 2: return CTX.color.geom.surface_sel; + default: return CTX.color.geom.volume_sel; + } + } + else if(CTX.mesh.color_carousel == 3){ // by partition + return CTX.color.mesh.carousel[abs(ele->getPartition() % 20)]; + } + else{ // by element type + switch(ele->getNumEdges()){ + case 1: return CTX.color.mesh.line; + case 3: return CTX.color.mesh.triangle; + case 4: return CTX.color.mesh.quadrangle; + case 6: return CTX.color.mesh.tetrahedron; + case 12: return CTX.color.mesh.hexahedron; + case 9: return CTX.color.mesh.prism; + case 8: return CTX.color.mesh.pyramid; + default: return CTX.color.mesh.vertex; + } + } +} + static double intersectCutPlane(MElement *ele) { MVertex *v = ele->getVertex(0); @@ -470,6 +475,9 @@ 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){ + glEnableClientState(GL_COLOR_ARRAY); + } else if(!e->getSelection() && (CTX.mesh.color_carousel == 0 || CTX.mesh.color_carousel == 3)){ glEnableClientState(GL_COLOR_ARRAY); @@ -607,6 +615,10 @@ class initMeshGFace { 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.enable_mouse_selection > 2) 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(). Question: @@ -635,14 +647,14 @@ class drawMeshGFace { void operator () (GFace *f) { if(!f->getVisibility()) return; + + MRep *m = f->meshRep; if(CTX.render_mode == GMSH_SELECT) { glPushName(2); glPushName(f->tag()); } - MRep *m = f->meshRep; - if(CTX.mesh.surfaces_edges){ if(m->va_lines && m->va_lines->getNumVertices()){ drawArrays(f, m->va_lines, GL_LINES, CTX.mesh.light && CTX.mesh.light_lines, @@ -717,6 +729,10 @@ class initMeshGRegion { 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.enable_mouse_selection > 2) useEdges = false; + if(useEdges){ Msg(DEBUG, "Using edges to draw volume %d", r->tag()); m->generateEdgeRep(); diff --git a/Graphics/SelectBuffer.cpp b/Graphics/SelectBuffer.cpp index 096e2539ba545b727b756f138ab0be1eebf87299..8313750c1aff1c07154ccb5962246a44fa7c663d 100644 --- a/Graphics/SelectBuffer.cpp +++ b/Graphics/SelectBuffer.cpp @@ -1,4 +1,4 @@ -// $Id: SelectBuffer.cpp,v 1.4 2006-08-24 17:26:26 geuzaine Exp $ +// $Id: SelectBuffer.cpp,v 1.5 2006-10-31 20:20:22 geuzaine Exp $ // // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle // @@ -47,21 +47,26 @@ class hitDepthLessThan{ }; bool ProcessSelectionBuffer(int entityType, bool multipleSelection, - bool selectMesh, int x, int y, int w, int h, + 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<GRegion*> ®ions, + std::vector<MElement*> &elements, + int meshSelection) { vertices.clear(); edges.clear(); faces.clear(); regions.clear(); + elements.clear(); // In our case the selection buffer size is equal to between 5 and 7 // times the maximum number of possible hits - int size = 5 * (GMODEL->numVertex() + GMODEL->numEdge() + - GMODEL->numFace() + GMODEL->numRegion()) + 1000; + int size = + 7 * (GMODEL->numVertex() + GMODEL->numEdge() + GMODEL->numFace() + + GMODEL->numRegion() + (meshSelection > 1 ? 3 * GMODEL->numElement() : 0)) ; + GLuint *selectionBuffer = new GLuint[size]; glSelectBuffer(size, selectionBuffer); @@ -73,7 +78,7 @@ bool ProcessSelectionBuffer(int entityType, bool multipleSelection, InitProjection(x, y, w, h); InitPosition(); Draw_Geom(); - if(selectMesh) Draw_Mesh(); + if(meshSelection) Draw_Mesh(); glPopMatrix(); GLint numhits = glRenderMode(GL_RENDER); @@ -166,7 +171,7 @@ bool ProcessSelectionBuffer(int entityType, bool multipleSelection, } if(hits[i].type2 && e->meshRep){ MElement *ele = e->meshRep->getElement(hits[i].type2, hits[i].ient2); - if(ele) printf("element %d\n", ele->getNum()); + if(ele) elements.push_back(ele); } edges.push_back(e); if(!multipleSelection) return true; @@ -181,7 +186,7 @@ bool ProcessSelectionBuffer(int entityType, bool multipleSelection, } if(hits[i].type2 && f->meshRep){ MElement *ele = f->meshRep->getElement(hits[i].type2, hits[i].ient2); - if(ele) printf("element %d\n", ele->getNum()); + if(ele) elements.push_back(ele); } faces.push_back(f); if(!multipleSelection) return true; @@ -196,7 +201,7 @@ bool ProcessSelectionBuffer(int entityType, bool multipleSelection, } if(hits[i].type2 && r->meshRep){ MElement *ele = r->meshRep->getElement(hits[i].type2, hits[i].ient2); - if(ele) printf("element %d\n", ele->getNum()); + if(ele) elements.push_back(ele); } regions.push_back(r); if(!multipleSelection) return true; diff --git a/Graphics/SelectBuffer.h b/Graphics/SelectBuffer.h index 78146179867841841e8ed9cb52f4b86b7c90f88c..b591bdb621b2a0bde5e8c961da53aaad95729019 100644 --- a/Graphics/SelectBuffer.h +++ b/Graphics/SelectBuffer.h @@ -36,16 +36,20 @@ #include "GRegion.h" bool ProcessSelectionBuffer(int entityType, bool multipleSelection, - bool selectMesh, int x, int y, int w, int h, + 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<GRegion*> ®ions, + std::vector<MElement*> &elements, + int meshSelection); char SelectEntity(int entityType, std::vector<GVertex*> &vertices, std::vector<GEdge*> &edges, std::vector<GFace*> &faces, - std::vector<GRegion*> ®ions); + std::vector<GRegion*> ®ions, + std::vector<MElement*> &elements, + int meshSelection=1); void HighlightEntity(GEntity *e, bool permanent=false); void HighlightEntity(GVertex *v, GEdge *e, GFace *f, GRegion *r, bool permanent=false); diff --git a/Graphics/gl2ps.cpp b/Graphics/gl2ps.cpp index 89fa20ddcaf4e686135e1468386a9bee5e435ccc..49896490e3480229c2a62480edb2bad0ad14fd5b 100644 --- a/Graphics/gl2ps.cpp +++ b/Graphics/gl2ps.cpp @@ -1,4 +1,4 @@ -/* $Id: gl2ps.cpp,v 1.109 2006-08-11 18:48:39 geuzaine Exp $ */ +/* $Id: gl2ps.cpp,v 1.110 2006-10-31 20:20:22 geuzaine Exp $ */ /* * GL2PS, an OpenGL to PostScript Printing Library * Copyright (C) 1999-2006 Christophe Geuzaine <geuz@geuz.org> @@ -48,7 +48,9 @@ * Shai Ayal <shaiay@gmail.com> * Fabian Wenzel <wenzel@tu-harburg.de> * Ian D. Gay <gay@sfu.ca> - * Cosmin Truta and Baiju Devani <cosmin@cs.toronto.edu> + * Cosmin Truta <cosmin@cs.toronto.edu> + * Baiju Devani <b.devani@gmail.com> + * Alexander Danilov <danilov@lanl.gov> * * For the latest info about gl2ps, see http://www.geuz.org/gl2ps/. * Please report all bugs and problems to <gl2ps@geuz.org>. @@ -1686,15 +1688,15 @@ static void gl2psRescaleAndOffset() (prim->verts[2].xyz[0] - prim->verts[1].xyz[0]) * (prim->verts[1].xyz[1] - prim->verts[0].xyz[1]); dZdX = - (prim->verts[2].xyz[1] - prim->verts[1].xyz[1]) * - (prim->verts[1].xyz[2] - prim->verts[0].xyz[2]) - - (prim->verts[1].xyz[1] - prim->verts[0].xyz[1]) * - (prim->verts[2].xyz[2] - prim->verts[1].xyz[2]) / area; + ((prim->verts[2].xyz[1] - prim->verts[1].xyz[1]) * + (prim->verts[1].xyz[2] - prim->verts[0].xyz[2]) - + (prim->verts[1].xyz[1] - prim->verts[0].xyz[1]) * + (prim->verts[2].xyz[2] - prim->verts[1].xyz[2])) / area; dZdY = - (prim->verts[1].xyz[0] - prim->verts[0].xyz[0]) * - (prim->verts[2].xyz[2] - prim->verts[1].xyz[2]) - - (prim->verts[2].xyz[0] - prim->verts[1].xyz[0]) * - (prim->verts[1].xyz[2] - prim->verts[0].xyz[2]) / area; + ((prim->verts[1].xyz[0] - prim->verts[0].xyz[0]) * + (prim->verts[2].xyz[2] - prim->verts[1].xyz[2]) - + (prim->verts[2].xyz[0] - prim->verts[1].xyz[0]) * + (prim->verts[1].xyz[2] - prim->verts[0].xyz[2])) / area; maxdZ = (GLfloat)sqrt(dZdX * dZdX + dZdY * dZdY); dZ = factor * maxdZ + units; prim->verts[0].xyz[2] += dZ; @@ -2904,7 +2906,9 @@ static void gl2psEndPostScriptLine(void) static void gl2psParseStipplePattern(GLushort pattern, GLint factor, int *nb, int array[10]) { - int i, n, on[5] = {0, 0, 0, 0, 0}, off[5] = {0, 0, 0, 0, 0}; + int i, n; + int on[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + int off[8] = {0, 0, 0, 0, 0, 0, 0, 0}; char tmp[16]; /* extract the 16 bits from the OpenGL stipple pattern */ @@ -2912,22 +2916,24 @@ static void gl2psParseStipplePattern(GLushort pattern, GLint factor, tmp[n] = (char)(pattern & 0x01); pattern >>= 1; } - /* compute the on/off pixel sequence (since the PostScript - specification allows for at most 11 elements in the on/off array, - we limit ourselves to 5 couples of on/off states) */ + /* compute the on/off pixel sequence */ n = 0; - for(i = 0; i < 5; i++){ + for(i = 0; i < 8; i++){ while(n < 16 && !tmp[n]){ off[i]++; n++; } while(n < 16 && tmp[n]){ on[i]++; n++; } - if(n >= 15) break; + if(n >= 15){ i++; break; } } + /* store the on/off array from right to left, starting with off - pixels (the longest possible array is: [on4 off4 on3 off3 on2 - off2 on1 off1 on0 off0]) */ + pixels. The PostScript specification allows for at most 11 + elements in the on/off array, so we limit ourselves to 5 on/off + couples (our longest possible array is thus [on4 off4 on3 off3 + on2 off2 on1 off1 on0 off0]) */ *nb = 0; - for(n = i; n >= 0; n--){ + for(n = i - 1; n >= 0; n--){ array[(*nb)++] = factor * on[n]; array[(*nb)++] = factor * off[n]; + if(*nb == 10) break; } } @@ -4839,29 +4845,34 @@ static void gl2psSVGGetColorString(GL2PSrgba rgba, char str[32]) static void gl2psPrintSVGHeader(void) { + int x, y, width, height; char col[32]; time_t now; - + + time(&now); + + if (gl2ps->options & GL2PS_LANDSCAPE){ + x = (int)gl2ps->viewport[1]; + y = (int)gl2ps->viewport[0]; + width = (int)gl2ps->viewport[3]; + height = (int)gl2ps->viewport[2]; + } + else{ + x = (int)gl2ps->viewport[0]; + y = (int)gl2ps->viewport[1]; + width = (int)gl2ps->viewport[2]; + height = (int)gl2ps->viewport[3]; + } + /* Compressed SVG files (.svgz) are simply gzipped SVG files */ gl2psPrintGzipHeader(); - - time(&now); - + gl2psPrintf("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"); gl2psPrintf("<svg xmlns=\"http://www.w3.org/2000/svg\"\n"); - gl2psPrintf(" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n"); - gl2psPrintf(" viewBox=\"%d %d %d %d\">\n", - (gl2ps->options & GL2PS_LANDSCAPE) ? (int)gl2ps->viewport[1] : - (int)gl2ps->viewport[0], - (gl2ps->options & GL2PS_LANDSCAPE) ? (int)gl2ps->viewport[0] : - (int)gl2ps->viewport[1], - (gl2ps->options & GL2PS_LANDSCAPE) ? (int)gl2ps->viewport[3] : - (int)gl2ps->viewport[2], - (gl2ps->options & GL2PS_LANDSCAPE) ? (int)gl2ps->viewport[2] : - (int)gl2ps->viewport[3]); - gl2psPrintf("<title>\n"); - gl2psPrintf("%s\n", gl2ps->title); - gl2psPrintf("</title>\n"); + gl2psPrintf(" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n" + " width=\"%dpx\" height=\"%dpx\" viewBox=\"%d %d %d %d\">\n", + width, height, x, y, width, height); + gl2psPrintf("<title>%s</title>\n", gl2ps->title); gl2psPrintf("<desc>\n"); gl2psPrintf("Creator: GL2PS %d.%d.%d%s, %s\n" "For: %s\n"