diff --git a/Common/Context.h b/Common/Context.h index 169e5478dbcd6c0efbd8dc8dd4e3565034bb990d..a09e3e81f883bda6098e56b0bf9caf65593c1d25 100644 --- a/Common/Context.h +++ b/Common/Context.h @@ -116,7 +116,8 @@ class Context_T { double shine, shine_exponent; // material specular reflection parameters int render_mode; // GMSH_RENDER, GMSH_SELECT, GMSH_FEEDBACK int clip[6]; // status of clip planes (bit arrays) - double clip_plane[6][4]; // clip planes + double clip_plane[6][4]; // clipping planes + int clip_whole_elements, clip_only_draw_intersecting_volume, clip_only_volume; // clip options int polygon_offset, polygon_offset_always; // polygon offset control double polygon_offset_factor, polygon_offset_units; // params for glPolygonOffset double pixel_equiv_x, pixel_equiv_y; // approx equiv model length of a pixel @@ -178,8 +179,6 @@ class Context_T { int min_circ_points, min_curv_points; double normals, tangents, explode; int color_carousel; - int use_cut_plane, cut_plane_draw_intersect, cut_plane_only_volume; - double cut_planea, cut_planeb, cut_planec, cut_planed; int save_all, save_groups_of_nodes, stl_binary, msh_binary, bdf_field_format; int smooth_normals, reverse_all_normals; double angle_smooth_normals; diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h index b3bae8bf32b7113df570aed2e858fecfc9fc6b8c..0aee27331f20821b99417905302e90d45cd52bb0 100644 --- a/Common/DefaultOptions.h +++ b/Common/DefaultOptions.h @@ -534,10 +534,17 @@ StringXNumber GeneralOptions_Number[] = { "Fourth coefficient in equation for clipping plane 5" }, { F, "ClipFactor" , opt_general_clip_factor , 5.0 , "Near and far clipping plane distance factor (decrease value for better z-buffer resolution)" }, + { F|O, "ClipOnlyDrawIntersectingVolume" , opt_general_clip_only_draw_intersecting_volume , 0. , + "Only draw layer of elements that intersect the clipping plane" }, + { F|O, "ClipOnlyVolume" , opt_general_clip_only_volume , 0. , + "Only clip volume elements" }, { F|S, "ClipPositionX" , opt_general_clip_position0 , 650. , "Horizontal position (in pixels) of the upper left corner of the clipping planes window" }, { F|S, "ClipPositionY" , opt_general_clip_position1 , 150. , "Vertical position (in pixels) of the upper left corner of the clipping planes window" }, + { F|O, "ClipWholeElements" , opt_general_clip_whole_elements , 0. , + "Clip whole elements" }, + { F|O, "ColorScheme", opt_general_color_scheme , 1. , "Default color scheme (0=dark, 1=light or 2=grayscale)" }, { F|O, "ConfirmOverwrite" , opt_general_confirm_overwrite, 1. , @@ -927,20 +934,6 @@ StringXNumber MeshOptions_Number[] = { "Mesh coloring (0=by element type, 1=by elementary entity, 2=by physical entity, 3=by partition)" }, { F, "CpuTime" , opt_mesh_cpu_time , 0. , "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, "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 , - "First cut plane equation coefficient (`A' in `AX+BY+CZ+D=0')" }, - { F, "CutPlaneB" , opt_mesh_cut_planeb , 0.0 , - "Second cut plane equation coefficient (`B' in `AX+BY+CZ+D=0')" }, - { F, "CutPlaneC" , opt_mesh_cut_planec , 0.0 , - "Third cut plane equation coefficient (`C' in `AX+BY+CZ+D=0')" }, - { F, "CutPlaneD" , opt_mesh_cut_planed , 0.0 , - "Fourth cut plane equation coefficient (`D' in `AX+BY+CZ+D=0')" }, { F|O, "DrawSkinOnly" , opt_mesh_draw_skin_only , 0. , "Draw only the skin of 3D meshes?" }, diff --git a/Common/Options.cpp b/Common/Options.cpp index 24b6a03bef1b372d7a95692e3b984384bfbf497d..ec29d3c21556f47dcd6214250dc531de7334e4a2 100644 --- a/Common/Options.cpp +++ b/Common/Options.cpp @@ -1,4 +1,4 @@ -// $Id: Options.cpp,v 1.401 2008-06-20 11:50:00 geuzaine Exp $ +// $Id: Options.cpp,v 1.402 2008-06-28 17:06:54 geuzaine Exp $ // // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle // @@ -3764,6 +3764,41 @@ double opt_general_clip5d(OPT_ARGS_NUM) return CTX.clip_plane[5][3]; } +double opt_general_clip_whole_elements(OPT_ARGS_NUM) +{ + if(action & GMSH_SET) + CTX.clip_whole_elements = (int)val; +#if defined(HAVE_FLTK) + if(WID && (action & GMSH_GUI)){ + WID->clip_butt[0]->value(CTX.clip_whole_elements); + activate_cb(NULL, (void*)"clip_whole_elements"); + } +#endif + return CTX.clip_whole_elements; +} + +double opt_general_clip_only_draw_intersecting_volume(OPT_ARGS_NUM) +{ + if(action & GMSH_SET) + CTX.clip_only_draw_intersecting_volume = (int)val; +#if defined(HAVE_FLTK) + if(WID && (action & GMSH_GUI)) + WID->clip_butt[1]->value(CTX.clip_only_draw_intersecting_volume); +#endif + return CTX.clip_only_draw_intersecting_volume; +} + +double opt_general_clip_only_volume(OPT_ARGS_NUM) +{ + if(action & GMSH_SET) + CTX.clip_only_volume = (int)val; +#if defined(HAVE_FLTK) + if(WID && (action & GMSH_GUI)) + WID->clip_butt[2]->value(CTX.clip_only_volume); +#endif + return CTX.clip_only_volume; +} + double opt_general_light0(OPT_ARGS_NUM) { if(action & GMSH_SET) @@ -5173,117 +5208,6 @@ double opt_mesh_draw_skin_only(OPT_ARGS_NUM) return CTX.mesh.draw_skin_only; } -double opt_mesh_use_cut_plane(OPT_ARGS_NUM) -{ - if(action & GMSH_SET){ - if(CTX.mesh.use_cut_plane != (int)val) - CTX.mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME); - CTX.mesh.use_cut_plane = (int)val; -#if defined(HAVE_FLTK) - if(WID){ - double val1 = 0; - for(int i = 0; i < 3; i++) - val1 = std::max(val1, std::max(fabs(CTX.min[i]), fabs(CTX.max[i]))); - val1 *= 1.5; - WID->mesh_value[17]->step(val1/200.); - WID->mesh_value[17]->minimum(-val1); - WID->mesh_value[17]->maximum(val1); - } -#endif - } -#if defined(HAVE_FLTK) - if(WID && (action & GMSH_GUI)){ - WID->mesh_butt[16]->value(CTX.mesh.use_cut_plane); - activate_cb(NULL, (void*)"mesh_cut_plane"); - } -#endif - return CTX.mesh.use_cut_plane; -} - -double opt_mesh_cut_plane_draw_intersect(OPT_ARGS_NUM) -{ - if(action & GMSH_SET){ - if(CTX.mesh.cut_plane_draw_intersect != (int)val) - CTX.mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME); - 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_draw_intersect); -#endif - return CTX.mesh.cut_plane_draw_intersect; -} - -double opt_mesh_cut_plane_only_volume(OPT_ARGS_NUM) -{ - if(action & GMSH_SET){ - if(CTX.mesh.cut_plane_only_volume != (int)val) - CTX.mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME); - CTX.mesh.cut_plane_only_volume = (int)val; - } -#if defined(HAVE_FLTK) - if(WID && (action & GMSH_GUI)) - WID->mesh_butt[23]->value(CTX.mesh.cut_plane_only_volume); -#endif - return CTX.mesh.cut_plane_only_volume; -} - -double opt_mesh_cut_planea(OPT_ARGS_NUM) -{ - if(action & GMSH_SET){ - if(CTX.mesh.cut_planea != val) - CTX.mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME); - CTX.mesh.cut_planea = val; - } -#if defined(HAVE_FLTK) - if(WID && (action & GMSH_GUI)) - WID->mesh_value[14]->value(CTX.mesh.cut_planea); -#endif - return CTX.mesh.cut_planea; -} - -double opt_mesh_cut_planeb(OPT_ARGS_NUM) -{ - if(action & GMSH_SET){ - if(CTX.mesh.cut_planeb != val) - CTX.mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME); - CTX.mesh.cut_planeb = val; - } -#if defined(HAVE_FLTK) - if(WID && (action & GMSH_GUI)) - WID->mesh_value[15]->value(CTX.mesh.cut_planeb); -#endif - return CTX.mesh.cut_planeb; -} - -double opt_mesh_cut_planec(OPT_ARGS_NUM) -{ - if(action & GMSH_SET){ - if(CTX.mesh.cut_planec != val) - CTX.mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME); - CTX.mesh.cut_planec = val; - } -#if defined(HAVE_FLTK) - if(WID && (action & GMSH_GUI)) - WID->mesh_value[16]->value(CTX.mesh.cut_planec); -#endif - return CTX.mesh.cut_planec; -} - -double opt_mesh_cut_planed(OPT_ARGS_NUM) -{ - if(action & GMSH_SET){ - if(CTX.mesh.cut_planed != val) - CTX.mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME); - CTX.mesh.cut_planed = val; - } -#if defined(HAVE_FLTK) - if(WID && (action & GMSH_GUI)) - WID->mesh_value[17]->value(CTX.mesh.cut_planed); -#endif - return CTX.mesh.cut_planed; -} - double opt_mesh_save_all(OPT_ARGS_NUM) { if(action & GMSH_SET) diff --git a/Common/Options.h b/Common/Options.h index 7dbce6a5ab0c2057fdec6102c04fe4d058310f0d..f427dba05ad51c46ab172da19e8750895874d95b 100644 --- a/Common/Options.h +++ b/Common/Options.h @@ -366,6 +366,9 @@ double opt_general_clip5a(OPT_ARGS_NUM); double opt_general_clip5b(OPT_ARGS_NUM); double opt_general_clip5c(OPT_ARGS_NUM); double opt_general_clip5d(OPT_ARGS_NUM); +double opt_general_clip_whole_elements(OPT_ARGS_NUM); +double opt_general_clip_only_draw_intersecting_volume(OPT_ARGS_NUM); +double opt_general_clip_only_volume(OPT_ARGS_NUM); double opt_general_light0(OPT_ARGS_NUM); double opt_general_light00(OPT_ARGS_NUM); double opt_general_light01(OPT_ARGS_NUM); @@ -497,13 +500,6 @@ double opt_mesh_second_order_linear(OPT_ARGS_NUM); double opt_mesh_second_order_incomplete(OPT_ARGS_NUM); double opt_mesh_dual(OPT_ARGS_NUM); double opt_mesh_draw_skin_only(OPT_ARGS_NUM); -double opt_mesh_use_cut_plane(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); -double opt_mesh_cut_planec(OPT_ARGS_NUM); -double opt_mesh_cut_planed(OPT_ARGS_NUM); double opt_mesh_save_all(OPT_ARGS_NUM); double opt_mesh_save_groups_of_nodes(OPT_ARGS_NUM); double opt_mesh_color_carousel(OPT_ARGS_NUM); diff --git a/Fltk/Callbacks.cpp b/Fltk/Callbacks.cpp index fa6a6c641488e6cd87d0bcf2d3a270706023959c..533769170814b688ccd627f142118c6c46560b19 100644 --- a/Fltk/Callbacks.cpp +++ b/Fltk/Callbacks.cpp @@ -1,4 +1,4 @@ -// $Id: Callbacks.cpp,v 1.585 2008-06-19 15:58:40 geuzaine Exp $ +// $Id: Callbacks.cpp,v 1.586 2008-06-28 17:06:54 geuzaine Exp $ // // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle // @@ -295,14 +295,6 @@ void activate_cb(CALLBACK_ARGS) WID->view_input[6]->deactivate(); } } - else if(!strcmp(str, "mesh_cut_plane")){ - if(WID->mesh_butt[16]->value()){ - WID->mesh_cut_plane->activate(); - } - else{ - WID->mesh_cut_plane->deactivate(); - } - } else if(!strcmp(str, "mesh_light")){ if(WID->mesh_butt[17]->value()){ WID->mesh_butt[18]->activate(); @@ -1105,16 +1097,6 @@ void mesh_options_ok_cb(CALLBACK_ARGS) { activate_cb(NULL, data); - if(data){ - char *name = (char*)data; - if(!strcmp(name, "cut_plane_invert")){ - WID->mesh_value[14]->value(-WID->mesh_value[14]->value()); - WID->mesh_value[15]->value(-WID->mesh_value[15]->value()); - WID->mesh_value[16]->value(-WID->mesh_value[16]->value()); - WID->mesh_value[17]->value(-WID->mesh_value[17]->value()); - } - } - opt_mesh_reverse_all_normals(0, GMSH_SET, WID->mesh_butt[0]->value()); opt_mesh_lc_from_curvature(0, GMSH_SET, WID->mesh_butt[1]->value()); opt_mesh_lc_from_points(0, GMSH_SET, WID->mesh_butt[5]->value()); @@ -1140,9 +1122,6 @@ void mesh_options_ok_cb(CALLBACK_ARGS) opt_mesh_lines_num(0, GMSH_SET, WID->mesh_butt[13]->value()); 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_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()); opt_mesh_smooth_normals(0, GMSH_SET, WID->mesh_butt[19]->value()); @@ -1162,10 +1141,6 @@ void mesh_options_ok_cb(CALLBACK_ARGS) opt_mesh_point_size(0, GMSH_SET, WID->mesh_value[10]->value()); opt_mesh_line_width(0, GMSH_SET, WID->mesh_value[11]->value()); opt_mesh_label_frequency(0, GMSH_SET, WID->mesh_value[12]->value()); - opt_mesh_cut_planea(0, GMSH_SET, WID->mesh_value[14]->value()); - opt_mesh_cut_planeb(0, GMSH_SET, WID->mesh_value[15]->value()); - opt_mesh_cut_planec(0, GMSH_SET, WID->mesh_value[16]->value()); - opt_mesh_cut_planed(0, GMSH_SET, WID->mesh_value[17]->value()); opt_mesh_angle_smooth_normals(0, GMSH_SET, WID->mesh_value[18]->value()); opt_mesh_point_type(0, GMSH_SET, WID->mesh_choice[0]->value()); @@ -2380,6 +2355,20 @@ void clip_update_cb(CALLBACK_ARGS) CTX.clip_plane[5][3] = (c[2] + d[2] / 2.); } + if(CTX.clip_whole_elements || CTX.clip_whole_elements != WID->clip_butt[0]->value()){ + for(int clip = 0; clip < 6; clip++){ + if(CTX.clip[clip] & 2) + CTX.mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME); + for(unsigned int index = 0; index < PView::list.size(); index++) + if(CTX.clip[clip] & (1 << (2 + index))) + PView::list[index]->setChanged(true); + } + } + + CTX.clip_whole_elements = WID->clip_butt[0]->value(); + CTX.clip_only_draw_intersecting_volume = WID->clip_butt[1]->value(); + CTX.clip_only_volume = WID->clip_butt[2]->value(); + int old = CTX.draw_bbox; CTX.draw_bbox = 1; if(CTX.fast_redraw) @@ -2404,6 +2393,13 @@ void clip_reset_cb(CALLBACK_ARGS) for(int j = 1; j < 4; j++) CTX.clip_plane[i][j] = 0.; } + + if(CTX.clip_whole_elements){ + CTX.mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME); + for(unsigned int index = 0; index < PView::list.size(); index++) + PView::list[index]->setChanged(true); + } + WID->reset_clip_browser(); Draw(); } diff --git a/Fltk/GUI.cpp b/Fltk/GUI.cpp index 04e9406ac3d27b7701e911243a46a9cb70adee11..ad0cd0a390d7e24e5d32ab80d95032c8f471b16a 100644 --- a/Fltk/GUI.cpp +++ b/Fltk/GUI.cpp @@ -1,4 +1,4 @@ -// $Id: GUI.cpp,v 1.691 2008-06-19 15:58:41 geuzaine Exp $ +// $Id: GUI.cpp,v 1.692 2008-06-28 17:06:54 geuzaine Exp $ // // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle // @@ -71,7 +71,7 @@ Fl_Menu_Item m_menubar_table[] = { {"&Options...", FL_CTRL+FL_SHIFT+'n', (Fl_Callback *)options_cb, 0}, {"Pl&ugins...", FL_CTRL+FL_SHIFT+'u', (Fl_Callback *)view_plugin_cb, (void*)(-1)}, {"&Visibility", FL_CTRL+FL_SHIFT+'v', (Fl_Callback *)visibility_cb, 0}, - {"&Clipping Planes", FL_CTRL+FL_SHIFT+'c', (Fl_Callback *)clip_cb, 0}, + {"&Clipping", FL_CTRL+FL_SHIFT+'c', (Fl_Callback *)clip_cb, 0}, {"&Manipulator", FL_CTRL+FL_SHIFT+'m', (Fl_Callback *)manip_cb, 0, FL_MENU_DIVIDER}, {"S&tatistics", FL_CTRL+'i', (Fl_Callback *)statistics_cb, 0}, {"M&essage Console", FL_CTRL+'l', (Fl_Callback *)message_cb, 0}, @@ -112,7 +112,7 @@ Fl_Menu_Item m_sys_menubar_table[] = { {"Options...", FL_META+FL_SHIFT+'n', (Fl_Callback *)options_cb, 0}, {"Plugins...", FL_META+FL_SHIFT+'u', (Fl_Callback *)view_plugin_cb, (void*)(-1)}, {"Visibility", FL_META+FL_SHIFT+'v', (Fl_Callback *)visibility_cb, 0}, - {"Clipping Planes", FL_META+FL_SHIFT+'c', (Fl_Callback *)clip_cb, 0}, + {"Clipping", FL_META+FL_SHIFT+'c', (Fl_Callback *)clip_cb, 0}, {"Manipulator", FL_META+FL_SHIFT+'m', (Fl_Callback *)manip_cb, 0, FL_MENU_DIVIDER}, {"Statistics", FL_META+'i', (Fl_Callback *)statistics_cb, 0}, {"Message Console", FL_META+'l', (Fl_Callback *)message_cb, 0}, @@ -2657,61 +2657,6 @@ void GUI::create_option_window() o->end(); } - { - Fl_Group *o = new Fl_Group(L + WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Cutting"); - o->hide(); - - mesh_butt[16] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 1 * BH, BW, BH, "Enable element-by-element cutting plane"); - mesh_butt[16]->type(FL_TOGGLE_BUTTON); - mesh_butt[16]->callback(mesh_options_ok_cb, (void*)"mesh_cut_plane"); - - mesh_cut_plane = new Fl_Group(L + 2 * WB, 2 * WB + 2 * BH, width - 2 * WB, 4 * BH, 0); - - int ii = fontsize; - Fl_Button *invert = new Fl_Button(L + 2 * WB, 2 * WB + 2 * BH, ii, 4*BH, "-"); - invert->tooltip("Invert orientation"); - invert->callback(mesh_options_ok_cb, (void*)"cut_plane_invert"); - - mesh_value[14] = new Fl_Value_Input(L + 2 * WB + ii, 2 * WB + 2 * BH, IW - ii, BH, "A"); - mesh_value[14]->align(FL_ALIGN_RIGHT); - mesh_value[14]->step(0.01); - mesh_value[14]->minimum(-1.0); - mesh_value[14]->maximum(1.0); - mesh_value[14]->callback(mesh_options_ok_cb); - - mesh_value[15] = new Fl_Value_Input(L + 2 * WB + ii, 2 * WB + 3 * BH, IW - ii, BH, "B"); - mesh_value[15]->align(FL_ALIGN_RIGHT); - mesh_value[15]->step(0.01); - mesh_value[15]->minimum(-1.0); - mesh_value[15]->maximum(1.0); - mesh_value[15]->callback(mesh_options_ok_cb); - - mesh_value[16] = new Fl_Value_Input(L + 2 * WB + ii, 2 * WB + 4 * BH, IW - ii, BH, "C"); - mesh_value[16]->align(FL_ALIGN_RIGHT); - mesh_value[16]->step(0.01); - mesh_value[16]->minimum(-1.0); - mesh_value[16]->maximum(1.0); - mesh_value[16]->callback(mesh_options_ok_cb); - - mesh_value[17] = new Fl_Value_Input(L + 2 * WB + ii, 2 * WB + 5 * BH, IW - ii, BH, "D"); - mesh_value[17]->align(FL_ALIGN_RIGHT); - mesh_value[17]->step(0.01); - mesh_value[17]->minimum(-1.0); - mesh_value[17]->maximum(1.0); - mesh_value[17]->callback(mesh_options_ok_cb); - - mesh_cut_plane->end(); - - 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]->callback(mesh_options_ok_cb); - - mesh_butt[23] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 7 * BH, BW, BH, "Cut only volume elements"); - mesh_butt[23]->type(FL_TOGGLE_BUTTON); - mesh_butt[23]->callback(mesh_options_ok_cb); - - o->end(); - } { Fl_Group *o = new Fl_Group(L + WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Aspect"); o->hide(); @@ -4583,34 +4528,34 @@ void GUI::create_clip_window() {0} }; - int width = 3 * BB + 4 * WB; - int height = 8 * BH + 5 * WB; - int brw = BB; - int BW = width - brw - 3 * WB - 3 * fontsize; + int width = 26 * fontsize; + int height = 10 * BH + 5 * WB; + int L = 7 * fontsize; - clip_window = new Dialog_Window(width, height, CTX.non_modal_windows, "Clipping Planes"); + clip_window = new Dialog_Window(width, height, CTX.non_modal_windows, "Clipping"); clip_window->box(GMSH_WINDOW_BOX); - clip_browser = new Fl_Multi_Browser(1 * WB, 1 * WB, brw, height - BH - 3 * WB); + clip_browser = new Fl_Multi_Browser(WB, WB, L - WB, height - BH - 3 * WB); clip_browser->callback(clip_update_cb); - Fl_Tabs *o = new Fl_Tabs(2 * WB + brw, WB, width - 3 * WB - brw, height - 3 * WB - BH); + Fl_Tabs *o = new Fl_Tabs(L + WB, WB, width - L - 2 * WB, height - 3 * WB - 4 * BH); { - clip_group[0] = new Fl_Group(2 * WB + brw, WB + BH, width - 3 * WB - brw, height - 3 * WB - 2 * BH, "Planes"); + clip_group[0] = new Fl_Group(L + WB, WB + BH, width - L - 2 * WB, height - 3 * WB - 5 * BH, "Planes"); - int ii = fontsize; - Fl_Button *invert = new Fl_Button(3 * WB + brw, 2 * WB + 2 * BH, ii, 4*BH, "-"); - invert->callback(clip_invert_cb); - invert->tooltip("Invert orientation"); + int BW = width - L - 4 * WB - 4 * fontsize; - clip_choice = new Fl_Choice(3 * WB + brw, 2 * WB + 1 * BH, BW, BH); + clip_choice = new Fl_Choice(L + 2 * WB, 2 * WB + 1 * BH, BW, BH); clip_choice->menu(plane_number); clip_choice->callback(clip_num_cb); + + Fl_Button *invert = new Fl_Button(L + 2 * WB, 2 * WB + 2 * BH, fontsize, 4 * BH, "-"); + invert->callback(clip_invert_cb); + invert->tooltip("Invert orientation"); - clip_value[0] = new Fl_Value_Input(3 * WB + brw + ii, 2 * WB + 2 * BH, BW - ii, BH, "A"); - clip_value[1] = new Fl_Value_Input(3 * WB + brw + ii, 2 * WB + 3 * BH, BW - ii, BH, "B"); - clip_value[2] = new Fl_Value_Input(3 * WB + brw + ii, 2 * WB + 4 * BH, BW - ii, BH, "C"); - clip_value[3] = new Fl_Value_Input(3 * WB + brw + ii, 2 * WB + 5 * BH, BW - ii, BH, "D"); + clip_value[0] = new Fl_Value_Input(L + 2 * WB + fontsize, 2 * WB + 2 * BH, BW - fontsize, BH, "A"); + clip_value[1] = new Fl_Value_Input(L + 2 * WB + fontsize, 2 * WB + 3 * BH, BW - fontsize, BH, "B"); + clip_value[2] = new Fl_Value_Input(L + 2 * WB + fontsize, 2 * WB + 4 * BH, BW - fontsize, BH, "C"); + clip_value[3] = new Fl_Value_Input(L + 2 * WB + fontsize, 2 * WB + 5 * BH, BW - fontsize, BH, "D"); for(int i = 0; i < 4; i++){ clip_value[i]->align(FL_ALIGN_RIGHT); clip_value[i]->callback(clip_update_cb); @@ -4619,15 +4564,17 @@ void GUI::create_clip_window() clip_group[0]->end(); } { - clip_group[1] = new Fl_Group(2 * WB + brw, WB + BH, width - 3 * WB - brw, height - 3 * WB - 2 * BH, "Box"); + clip_group[1] = new Fl_Group(L + WB, WB + BH, width - L - 2 * WB, height - 3 * WB - 5 * BH, "Box"); clip_group[1]->hide(); - clip_value[4] = new Fl_Value_Input(3 * WB + brw, 2 * WB + 1 * BH, BW, BH, "Cx"); - clip_value[5] = new Fl_Value_Input(3 * WB + brw, 2 * WB + 2 * BH, BW, BH, "Cy"); - clip_value[6] = new Fl_Value_Input(3 * WB + brw, 2 * WB + 3 * BH, BW, BH, "Cz"); - clip_value[7] = new Fl_Value_Input(3 * WB + brw, 2 * WB + 4 * BH, BW, BH, "Wx"); - clip_value[8] = new Fl_Value_Input(3 * WB + brw, 2 * WB + 5 * BH, BW, BH, "Wy"); - clip_value[9] = new Fl_Value_Input(3 * WB + brw, 2 * WB + 6 * BH, BW, BH, "Wz"); + int w2 = (width - L - 4 * WB) / 2; + int BW = w2 - 2 * fontsize; + clip_value[4] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 1 * BH, BW, BH, "Cx"); + clip_value[5] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 2 * BH, BW, BH, "Cy"); + clip_value[6] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 3 * BH, BW, BH, "Cz"); + clip_value[7] = new Fl_Value_Input(L + 2 * WB + w2, 2 * WB + 1 * BH, BW, BH, "Wx"); + clip_value[8] = new Fl_Value_Input(L + 2 * WB + w2, 2 * WB + 2 * BH, BW, BH, "Wy"); + clip_value[9] = new Fl_Value_Input(L + 2 * WB + w2, 2 * WB + 3 * BH, BW, BH, "Wz"); for(int i = 4; i < 10; i++){ clip_value[i]->align(FL_ALIGN_RIGHT); clip_value[i]->callback(clip_update_cb); @@ -4638,6 +4585,14 @@ void GUI::create_clip_window() o->callback(clip_reset_cb); o->end(); + clip_butt[0] = new Fl_Check_Button(L + WB, 3 * WB + 6 * BH, width - L - 2 * WB, BH, "Keep whole elements"); + clip_butt[1] = new Fl_Check_Button(L + WB, 3 * WB + 7 * BH, width - L - 2 * WB, BH, "Only draw intersecting volume layer"); + clip_butt[2] = new Fl_Check_Button(L + WB, 3 * WB + 8 * BH, width - L - 2 * WB, BH, "Cut only volume elements"); + for(int i = 0; i < 3; i++){ + clip_butt[i]->type(FL_TOGGLE_BUTTON); + clip_butt[i]->callback(clip_update_cb); + } + reset_clip_browser(); { diff --git a/Fltk/GUI.h b/Fltk/GUI.h index de959267c9ad69d3aaaa10555a57b2943ac3fc73..95e557621743263e234d5eb7a98e0a7e3a650916 100644 --- a/Fltk/GUI.h +++ b/Fltk/GUI.h @@ -264,7 +264,7 @@ public: Fl_Choice *clip_choice; Fl_Multi_Browser *clip_browser; Fl_Value_Input *clip_value[10]; - Fl_Check_Button *clip_butt[2]; + Fl_Check_Button *clip_butt[3]; Fl_Group *clip_group[2]; // manipulator window diff --git a/Graphics/Geom.cpp b/Graphics/Geom.cpp index 3f002180b6e964285495519995ff17404e06aa3d..abb77c124192f3a20d0011ccc7b973a40d3ce60e 100644 --- a/Graphics/Geom.cpp +++ b/Graphics/Geom.cpp @@ -1,4 +1,4 @@ -// $Id: Geom.cpp,v 1.157 2008-06-25 07:58:54 geuzaine Exp $ +// $Id: Geom.cpp,v 1.158 2008-06-28 17:06:55 geuzaine Exp $ // // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle // @@ -486,11 +486,6 @@ void Draw_Geom() CTX.max[0], CTX.max[1], CTX.max[2], CTX.clip_plane[i][0], CTX.clip_plane[i][1], CTX.clip_plane[i][2], CTX.clip_plane[i][3]); - if(CTX.mesh.use_cut_plane) - Draw_PlaneInBoundingBox(CTX.min[0], CTX.min[1], CTX.min[2], - CTX.max[0], CTX.max[1], CTX.max[2], - CTX.mesh.cut_planea, CTX.mesh.cut_planeb, - CTX.mesh.cut_planec, CTX.mesh.cut_planed); } if(CTX.axes){ diff --git a/Graphics/Mesh.cpp b/Graphics/Mesh.cpp index 93d27de4d88e1ad31a3554d3dc69676c56d0f4e5..cc6111146e467e95ddb63cf59f6cde693ae7ca6d 100644 --- a/Graphics/Mesh.cpp +++ b/Graphics/Mesh.cpp @@ -1,4 +1,4 @@ -// $Id: Mesh.cpp,v 1.223 2008-06-27 13:50:35 geuzaine Exp $ +// $Id: Mesh.cpp,v 1.224 2008-06-28 17:06:55 geuzaine Exp $ // // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle // @@ -92,19 +92,19 @@ static unsigned int getColorByElement(MElement *ele) return CTX.color.fg; } -static double evalCutPlane(double x, double y, double z) +static double evalClipPlane(int clip, double x, double y, double z) { - return CTX.mesh.cut_planea * x + CTX.mesh.cut_planeb * y + - CTX.mesh.cut_planec * z + CTX.mesh.cut_planed; + return CTX.clip_plane[clip][0] * x + CTX.clip_plane[clip][1] * y + + CTX.clip_plane[clip][2] * z + CTX.clip_plane[clip][3]; } -static double intersectCutPlane(MElement *ele) +static double intersectClipPlane(int clip, MElement *ele) { MVertex *v = ele->getVertex(0); - double val = evalCutPlane(v->x(), v->y(), v->z()); + double val = evalClipPlane(clip, v->x(), v->y(), v->z()); for(int i = 1; i < ele->getNumVertices(); i++){ v = ele->getVertex(i); - if(val * evalCutPlane(v->x(), v->y(), v->z()) <= 0) + if(val * evalClipPlane(clip, v->x(), v->y(), v->z()) <= 0) return 0.; // the element intersects the cut plane } return val; @@ -127,10 +127,26 @@ static bool isElementVisible(MElement *ele) 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){ + if(CTX.clip_whole_elements){ + bool hidden = false; + for(int clip = 0; clip < 6; clip++){ + if(CTX.clip[clip] & 2){ + if(ele->getDim() < 3 && CTX.clip_only_volume){ + } + else{ + double d = intersectClipPlane(clip, ele); + if(ele->getDim() == 3 && CTX.clip_only_draw_intersecting_volume && d){ + hidden = true; + break; + } + else if(d < 0){ + hidden = true; + break; + } + } + } } - else if(intersectCutPlane(ele) < 0) return false; + if(hidden) return false; } return true; } @@ -399,9 +415,6 @@ static void addElementsInArrays(GEntity *e, std::vector<T*> &elements, if(!isElementVisible(ele) || ele->getDim() < 1) continue; - if(CTX.mesh.use_cut_plane && CTX.mesh.cut_plane_draw_intersect) - if(e->dim() == 3 && intersectCutPlane(ele)) continue; - unsigned int c = getColorByElement(ele); unsigned int col[4] = {c, c, c, c}; @@ -712,6 +725,16 @@ class drawMeshGFace { class initMeshGRegion { private: bool _curved; + int _estimateIfClipped(int num) + { + if(CTX.clip_whole_elements && CTX.clip_only_draw_intersecting_volume){ + for(int clip = 0; clip < 6; clip++){ + if(CTX.clip[clip] & 2) + return (int)sqrt((double)num); + } + } + return num; + } int _estimateNumLines(GRegion *r) { int num = 0; @@ -719,8 +742,7 @@ class initMeshGRegion { // suppose edge shared by 4 elements on averge (pessmistic) num += (12 * r->tetrahedra.size() + 24 * r->hexahedra.size() + 18 * r->prisms.size() + 16 * r->pyramids.size()) / 4; - if(CTX.mesh.use_cut_plane && CTX.mesh.cut_plane_draw_intersect) - num = (int)sqrt((double)num); + num = _estimateIfClipped(num); if(CTX.mesh.explode != 1.) num *= 4; if(_curved) num *= 2; } @@ -732,8 +754,7 @@ class initMeshGRegion { if(CTX.mesh.volumes_faces){ num += (4 * r->tetrahedra.size() + 12 * r->hexahedra.size() + 8 * r->prisms.size() + 6 * r->pyramids.size()) / 2; - if(CTX.mesh.use_cut_plane && CTX.mesh.cut_plane_draw_intersect) - num = (int)sqrt((double)num); + num = _estimateIfClipped(num); if(CTX.mesh.explode != 1.) num *= 2; if(_curved) num *= 4; } @@ -852,11 +873,13 @@ void Draw_Mesh() else glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); - for(int i = 0; i < 6; i++) - if(CTX.clip[i] & 2) - glEnable((GLenum)(GL_CLIP_PLANE0 + i)); - else - glDisable((GLenum)(GL_CLIP_PLANE0 + i)); + if(!CTX.clip_whole_elements){ + for(int i = 0; i < 6; i++) + if(CTX.clip[i] & 2) + glEnable((GLenum)(GL_CLIP_PLANE0 + i)); + else + glDisable((GLenum)(GL_CLIP_PLANE0 + i)); + } static bool busy = false; if(!busy){ diff --git a/Graphics/Post.cpp b/Graphics/Post.cpp index 02a486dd5301d634c6198877d9b62ec763e95a46..1262d7c7db36e5d587ce83b94b31e1543bb9abe6 100644 --- a/Graphics/Post.cpp +++ b/Graphics/Post.cpp @@ -1,4 +1,4 @@ -// $Id: Post.cpp,v 1.170 2008-06-27 13:50:35 geuzaine Exp $ +// $Id: Post.cpp,v 1.171 2008-06-28 17:06:55 geuzaine Exp $ // // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle // @@ -19,6 +19,7 @@ // // Please report all bugs and problems to <gmsh@geuz.org>. +#include <math.h> #include <algorithm> #include "Message.h" #include "GmshUI.h" @@ -279,24 +280,45 @@ static void changeCoordinates(PView *p, int ient, int iele, int numNodes, } } - -/* -static double evalCutPlane(double x, double y, double z) +static double evalClipPlane(int clip, double x, double y, double z) { - return CTX.mesh.cut_planea * x + CTX.mesh.cut_planeb * y + - CTX.mesh.cut_planec * z + CTX.mesh.cut_planed; + return CTX.clip_plane[clip][0] * x + CTX.clip_plane[clip][1] * y + + CTX.clip_plane[clip][2] * z + CTX.clip_plane[clip][3]; } -static double intersectCutPlane(int numNodes, double xyz[NMAX][3]) +static double intersectClipPlane(int clip, int numNodes, double xyz[NMAX][3]) { - double val = evalCutPlane(xyz[0][0], xyz[0][1], xyz[0][2]); + double val = evalClipPlane(clip, xyz[0][0], xyz[0][1], xyz[0][2]); for(int i = 1; i < numNodes; i++){ - if(val * evalCutPlane(xyz[i][0], xyz[i][1], xyz[i][2]) <= 0) + if(val * evalClipPlane(clip, xyz[i][0], xyz[i][1], xyz[i][2]) <= 0) return 0.; // the element intersects the cut plane } return val; } -*/ + +static bool isElementVisible(int index, int dim, int numNodes, double xyz[NMAX][3]) +{ + if(!CTX.clip_whole_elements) return true; + bool hidden = false; + for(int clip = 0; clip < 6; clip++){ + if(CTX.clip[clip] & (1 << (2 + index))){ + if(dim < 3 && CTX.clip_only_volume){ + } + else{ + double d = intersectClipPlane(clip, numNodes, xyz); + if(dim == 3 && CTX.clip_only_draw_intersecting_volume && d){ + hidden = true; + break; + } + else if(d < 0){ + hidden = true; + break; + } + } + } + } + return !hidden; +} static void addOutlinePoint(PView *p, double xyz[NMAX][3], unsigned int color, bool pre, int i0=0) @@ -940,25 +962,9 @@ static void addElementsInArrays(PView *p, bool preprocessNormalsOnly) data->getValue(opt->TimeStep, ent, i, j, k, val[j][k]); } changeCoordinates(p, ent, i, numNodes, numEdges, numComp, xyz, val); + int dim = data->getDimension(opt->TimeStep, ent, i); + if(!isElementVisible(p->getIndex(), dim, numNodes, xyz)) continue; - /* FIXME: This works--just need to add an option to enable it by - view (and put the UI in the clipping plane dialog, along with - the UI for mesh cuts) */ - /* - if(CTX.mesh.use_cut_plane){ - int dim = data->getDimension(opt->TimeStep, ent, i); - if(dim < 3 && CTX.mesh.cut_plane_only_volume){ - } - else{ - double d = intersectCutPlane(numNodes, xyz); - if(dim == 3 && CTX.mesh.cut_plane_draw_intersect && d) - continue; - else if(d < 0) - continue; - } - } - */ - for(int j = 0; j < numNodes; j++) opt->TmpBBox += SPoint3(xyz[j][0], xyz[j][1], xyz[j][2]); @@ -1234,6 +1240,16 @@ class initPView { // we try to estimate how many primitives will end up in the vertex // arrays, since reallocating the arrays takes a huge amount of time // on Windows/Cygwin + int _estimateIfClipped(PView *p, int num) + { + if(CTX.clip_whole_elements && CTX.clip_only_draw_intersecting_volume){ + for(int clip = 0; clip < 6; clip++){ + if(CTX.clip[clip] & (1 << (2 + p->getIndex()))) + return (int)sqrt((double)num); + } + } + return num; + } int _estimateNumPoints(PView *p) { PViewData *data = p->getData(true); @@ -1267,6 +1283,7 @@ class initPView { else if(opt->IntervalsType == PViewOptions::Discrete) heuristic = (tris + 2 * quads + 6 * tets + 8 * prisms + 6 * pyrs + 12 * hexas) * 2; + heuristic = _estimateIfClipped(p, heuristic); return heuristic + 10000; } int _estimateNumVectors(PView *p) @@ -1274,6 +1291,7 @@ class initPView { PViewData *data = p->getData(true); PViewOptions *opt = p->getOptions(); int heuristic = data->getNumVectors(opt->TimeStep); + heuristic = _estimateIfClipped(p, heuristic); return heuristic + 1000; } public : @@ -1361,12 +1379,14 @@ class drawPView { else glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); - for(int i = 0; i < 6; i++) - if(CTX.clip[i] & (1 << (2 + p->getIndex()))) - glEnable((GLenum)(GL_CLIP_PLANE0 + i)); - else - glDisable((GLenum)(GL_CLIP_PLANE0 + i)); - + if(!CTX.clip_whole_elements){ + for(int i = 0; i < 6; i++) + if(CTX.clip[i] & (1 << (2 + p->getIndex()))) + glEnable((GLenum)(GL_CLIP_PLANE0 + i)); + else + glDisable((GLenum)(GL_CLIP_PLANE0 + i)); + } + if(CTX.alpha && ColorTable_IsAlpha(&opt->CT)){ if(opt->FakeTransparency){ // simple additive blending "a la xpost": diff --git a/doc/TODO b/doc/TODO index cbb1145270abc1ba3f23174ac85850ba03139c75..5f53004f7607a7184dd824e8baacc205eab341e8 100644 --- a/doc/TODO +++ b/doc/TODO @@ -1,8 +1,4 @@ -$Id: TODO,v 1.74 2008-06-19 15:58:42 geuzaine Exp $ - -******************************************************************** - -merge clipping & cutting plane GUI + extend cutting plane to post-pro +$Id: TODO,v 1.75 2008-06-28 17:06:55 geuzaine Exp $ ******************************************************************** diff --git a/doc/VERSIONS b/doc/VERSIONS index 15a0297ce796e4f7c4e1eff115649e99df606916..7ac318dd04cc341151d588a412e954202b1417d6 100644 --- a/doc/VERSIONS +++ b/doc/VERSIONS @@ -1,4 +1,6 @@ -$Id: VERSIONS,v 1.411 2008-06-20 05:51:37 geuzaine Exp $ +$Id: VERSIONS,v 1.412 2008-06-28 17:06:55 geuzaine Exp $ + +2.2.3 (): enhanced clipping interface. 2.2.2 (Jun 20, 2008): added geometrical transformations on volumes; fixed bug in high order mesh generation. diff --git a/doc/texinfo/opt_general.texi b/doc/texinfo/opt_general.texi index e2562a8fdd289e9d93e744bc4d4e2b93244eefbe..2e60f93f483c2733e351168eaf0eb6a704a6e4b1 100644 --- a/doc/texinfo/opt_general.texi +++ b/doc/texinfo/opt_general.texi @@ -334,6 +334,16 @@ Near and far clipping plane distance factor (decrease value for better z-buffer Default value: @code{5}@* Saved in: @code{-} +@item General.ClipOnlyDrawIntersectingVolume +Only draw layer of elements that intersect the clipping plane@* +Default value: @code{0}@* +Saved in: @code{General.OptionsFileName} + +@item General.ClipOnlyVolume +Only clip volume elements@* +Default value: @code{0}@* +Saved in: @code{General.OptionsFileName} + @item General.ClipPositionX Horizontal position (in pixels) of the upper left corner of the clipping planes window@* Default value: @code{650}@* @@ -344,6 +354,11 @@ Vertical position (in pixels) of the upper left corner of the clipping planes wi Default value: @code{150}@* Saved in: @code{General.SessionFileName} +@item General.ClipWholeElements +Clip whole elements@* +Default value: @code{0}@* +Saved in: @code{General.OptionsFileName} + @item General.ColorScheme Default color scheme (0=dark, 1=light or 2=grayscale)@* Default value: @code{1}@* diff --git a/doc/texinfo/opt_mesh.texi b/doc/texinfo/opt_mesh.texi index a99ba8330c5a1b48076175102adb1bdc4a307ca7..fd6bc1897c43db6d3455257a0f1ccb7983e19d81 100644 --- a/doc/texinfo/opt_mesh.texi +++ b/doc/texinfo/opt_mesh.texi @@ -74,41 +74,6 @@ CPU time (in seconds) for the generation of the current mesh (read-only)@* Default value: @code{0}@* Saved in: @code{-} -@item Mesh.CutPlane -Enable mesh cut plane@* -Default value: @code{0}@* -Saved in: @code{-} - -@item Mesh.CutPlaneDrawIntersect -Draw only the volume elements that intersect with the cut plane@* -Default value: @code{0}@* -Saved in: @code{-} - -@item Mesh.CutPlaneOnlyVolume -Cut only the volume elements@* -Default value: @code{0}@* -Saved in: @code{-} - -@item Mesh.CutPlaneA -First cut plane equation coefficient (`A' in `AX+BY+CZ+D=0')@* -Default value: @code{1}@* -Saved in: @code{-} - -@item Mesh.CutPlaneB -Second cut plane equation coefficient (`B' in `AX+BY+CZ+D=0')@* -Default value: @code{0}@* -Saved in: @code{-} - -@item Mesh.CutPlaneC -Third cut plane equation coefficient (`C' in `AX+BY+CZ+D=0')@* -Default value: @code{0}@* -Saved in: @code{-} - -@item Mesh.CutPlaneD -Fourth cut plane equation coefficient (`D' in `AX+BY+CZ+D=0')@* -Default value: @code{0}@* -Saved in: @code{-} - @item Mesh.DrawSkinOnly Draw only the skin of 3D meshes?@* Default value: @code{0}@*