From f942466ba4d2ef356c296487ade75d495af31b96 Mon Sep 17 00:00:00 2001 From: Christophe Geuzaine <cgeuzaine@ulg.ac.be> Date: Fri, 11 Mar 2005 08:56:38 +0000 Subject: [PATCH] - cleaned up (somewhat) + finished the euler angles/quaternion handling - added a new little dialog in gui to specify the rotations/scales/translations by hand. This is similar to what I did in the Motif version of Gmsh a looooong time ago, and I was really missing this capability... (e.g. being able to specify exact rotation angles) --- Common/Context.cpp | 84 +++++++++++++++++--------------- Common/Context.h | 19 ++++---- Common/DefaultOptions.h | 4 ++ Common/Makefile | 15 +++--- Common/Options.cpp | 56 ++++++++++++++++++++- Common/Options.h | 2 + Fltk/Callbacks.cpp | 58 ++++++++++++++-------- Fltk/Callbacks.h | 5 ++ Fltk/GUI.cpp | 99 ++++++++++++++++++++++++++++++++++++-- Fltk/GUI.h | 6 +++ Fltk/Message.cpp | 4 +- Fltk/Opengl.cpp | 30 +----------- Fltk/Opengl_Window.cpp | 71 +++++++++++++++------------ Geo/MinMax.cpp | 26 ++-------- Graphics/Draw.cpp | 22 +-------- Graphics/Draw.h | 4 -- doc/VERSIONS | 6 +-- doc/texinfo/shortcuts.texi | 2 + 18 files changed, 325 insertions(+), 188 deletions(-) diff --git a/Common/Context.cpp b/Common/Context.cpp index ea0d07974c..29a92dedc8 100644 --- a/Common/Context.cpp +++ b/Common/Context.cpp @@ -1,4 +1,4 @@ -// $Id: Context.cpp,v 1.54 2005-01-01 19:35:27 geuzaine Exp $ +// $Id: Context.cpp,v 1.55 2005-03-11 08:56:37 geuzaine Exp $ // // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle // @@ -21,48 +21,15 @@ #include "Gmsh.h" #include "Numeric.h" -#include "Geo.h" -#include "Mesh.h" -#include "Draw.h" #include "Context.h" -#include "Options.h" #include "DefaultOptions.h" #include "Trackball.h" -/* -00 01 02 03 0 1 2 3 -10 11 12 13 4 5 6 7 -20 21 22 23 8 9 10 11 -30 31 32 33 12 13 14 15 -*/ - -void Context_T::buildRotmatrix(void) +void Context_T::buildRotationMatrix(void) { if(useTrackball) { build_rotmatrix(rot, quaternion); - - // get Euler angles from rotation matrix - r[1] = asin(rot[8]); // Calculate Y-axis angle - double C = cos(r[1]); - r[1] *= 180. / Pi; - if(fabs(C) > 0.005){ // Gimball lock? - double tmpx = rot[10] / C; // No, so get X-axis angle - double tmpy = -rot[9] / C; - r[0] = atan2(tmpy, tmpx) * 180. / Pi; - tmpx = rot[0] / C; // Get Z-axis angle - tmpy = -rot[4] / C; - r[2] = atan2(tmpy, tmpx) * 180. / Pi; - } - else{ // Gimball lock has occurred - r[0] = 0.; // Set X-axis angle to zero - double tmpx = rot[5]; // And calculate Z-axis angle - double tmpy = rot[1]; - r[2] = atan2(tmpy, tmpx) * 180. / Pi; - } - // return only positive angles in [0,360] - if(r[0] < 0.) r[0] += 360.; - if(r[1] < 0.) r[1] += 360.; - if(r[2] < 0.) r[2] += 360.; + setEulerAnglesFromRotationMatrix(); } else { double x = r[0] * Pi / 180.; @@ -80,9 +47,7 @@ void Context_T::buildRotmatrix(void) rot[4] =-C*F; rot[5] =-BD*F+A*E; rot[6] = AD*F+B*E; rot[7] = 0.; rot[8] = D; rot[9] =-B*C; rot[10] = A*C; rot[11] = 0.; rot[12] = 0.; rot[13] = 0.; rot[14] = 0.; rot[15] = 1.; - - // get the quaternion from the Euler angles - // todo + setQuaternionFromEulerAngles(); } } @@ -100,3 +65,44 @@ void Context_T::setQuaternion(double q0, double q1, double q2, double q3) quaternion[2] = q2; quaternion[3] = q3; } + +void Context_T::setQuaternionFromEulerAngles() +{ + double x = r[0] * Pi / 180.; + double y = r[1] * Pi / 180.; + double z = r[2] * Pi / 180.; + double xx[3] = {1.,0.,0.}; + double yy[3] = {0.,1.,0.}; + double zz[3] = {0.,0.,1.}; + double q1[4], q2[4], q3[4], tmp[4]; + axis_to_quat(xx, -x, q1); + axis_to_quat(yy, -y, q2); + axis_to_quat(zz, -z, q3); + add_quats(q1, q2, tmp); + add_quats(tmp, q3, quaternion); +} + +void Context_T::setEulerAnglesFromRotationMatrix() +{ + r[1] = asin(rot[8]); // Calculate Y-axis angle + double C = cos(r[1]); + r[1] *= 180. / Pi; + if(fabs(C) > 0.005){ // Gimball lock? + double tmpx = rot[10] / C; // No, so get X-axis angle + double tmpy = -rot[9] / C; + r[0] = atan2(tmpy, tmpx) * 180. / Pi; + tmpx = rot[0] / C; // Get Z-axis angle + tmpy = -rot[4] / C; + r[2] = atan2(tmpy, tmpx) * 180. / Pi; + } + else{ // Gimball lock has occurred + r[0] = 0.; // Set X-axis angle to zero + double tmpx = rot[5]; // And calculate Z-axis angle + double tmpy = rot[1]; + r[2] = atan2(tmpy, tmpx) * 180. / Pi; + } + // return only positive angles in [0,360] + if(r[0] < 0.) r[0] += 360.; + if(r[1] < 0.) r[1] += 360.; + if(r[2] < 0.) r[2] += 360.; +} diff --git a/Common/Context.h b/Common/Context.h index a1d7ffe10a..b606bf9516 100644 --- a/Common/Context.h +++ b/Common/Context.h @@ -78,6 +78,7 @@ public : int opt_position[2]; // position of the option window on the screen int vis_position[2]; // position of the visibility window on the screen int clip_position[2]; // position of the clipping planes window on the screen + int manip_position[2]; // position of the manipulator window on the screen int stat_position[2]; // position of the statistics window on the screen int ctx_position[2]; // position of the geo/mesh context windows on the screen int solver_position[2]; // position of the solver windows on the screen @@ -90,12 +91,10 @@ public : int nopopup; // never popup dialogs in scripts (use default values instead) double rot[16]; // current rotation matrix - double r[3]; // position angles (if succ. rot. along x, y and z) + double r[3]; // current Euler angles (in degrees!) double t[3], s[3]; // current translation and scale double clip_factor; // clipping plane distance factor - int rlock[3], tlock[3], slock[3]; - // locks for r, t and s - double quaternion[4]; // the actual quaternion used for "trackball" rotating + double quaternion[4]; // current quaternion used for "trackball" rotation int useTrackball; // do or do not use the trackball for rotations double rotation_center[3]; // point around which to rotate the scene int rotation_center_cg; // rotate around the center of mass instead of rotation_center[] @@ -103,8 +102,8 @@ public : double max[3]; // x, y and z max for the current geometry double cg[3]; // "center of mass" of the current geometry double range[3]; // maximum range in the three directions - double lc, lc_middle; // characteristic lengths for the whole problem, - double lc_order; // and never used in mesh generation (->only for geo/post) + double lc; // characteristic length for the whole problem (never + // used in mesh generation ->only for geo/post) int db; // double buffer? int ortho; // orthogonal projection? @@ -240,9 +239,11 @@ public : } color; // trackball functions - void buildRotmatrix(void); - void setQuaternion (double p1x, double p1y, double p2x, double p2y); - void addQuaternion (double p1x, double p1y, double p2x, double p2y); + void buildRotationMatrix(void); + void setQuaternion(double p1x, double p1y, double p2x, double p2y); + void addQuaternion(double p1x, double p1y, double p2x, double p2y); + void setQuaternionFromEulerAngles(void); + void setEulerAnglesFromRotationMatrix(void); }; #endif diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h index c363e089b6..4871a25fab 100644 --- a/Common/DefaultOptions.h +++ b/Common/DefaultOptions.h @@ -571,6 +571,10 @@ StringXNumber GeneralOptions_Number[] = { { F|O, "LineWidth" , opt_general_line_width , 1.0 , "Display width of lines (in pixels)" }, + { F|S, "ManipulatorPositionX" , opt_general_manip_position0 , 650. , + "Horizontal position (in pixels) of the upper left corner of the manipulator window" }, + { F|S, "ManipulatorPositionY" , opt_general_manip_position1 , 150. , + "Vertical position (in pixels) of the upper left corner of the manipulator window" }, { F|S, "MenuPositionX" , opt_general_menu_position0 , 800. , "Horizontal position (in pixels) of the upper left corner of the menu window" }, { F|S, "MenuPositionY" , opt_general_menu_position1 , 50. , diff --git a/Common/Makefile b/Common/Makefile index 29191811a2..aea51f29d4 100644 --- a/Common/Makefile +++ b/Common/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.74 2005-02-20 06:36:52 geuzaine Exp $ +# $Id: Makefile,v 1.75 2005-03-11 08:56:37 geuzaine Exp $ # # Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle # @@ -64,13 +64,12 @@ depend: # DO NOT DELETE THIS LINE Context.o: Context.cpp Gmsh.h Message.h ../DataStr/Malloc.h \ ../DataStr/List.h ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h \ - ../Numeric/Numeric.h ../Geo/Geo.h ../Mesh/Mesh.h ../Mesh/Vertex.h \ - ../Mesh/Element.h ../Mesh/Simplex.h ../Mesh/Face.h ../Mesh/Edge.h \ - ../Geo/ExtrudeParams.h ../Mesh/DiscreteSurface.h \ - ../Common/VertexArray.h ../Common/SmoothNormals.h ../Mesh/Metric.h \ - ../Mesh/Matrix.h ../Graphics/Draw.h ../Common/Views.h \ - ../Common/ColorTable.h ../Common/GmshMatrix.h ../Common/AdaptiveViews.h \ - Context.h Options.h DefaultOptions.h Trackball.h + ../Numeric/Numeric.h Context.h DefaultOptions.h Options.h \ + ../Mesh/Mesh.h ../Mesh/Vertex.h ../Mesh/Element.h ../Mesh/Simplex.h \ + ../Mesh/Face.h ../Mesh/Edge.h ../Geo/ExtrudeParams.h \ + ../Mesh/DiscreteSurface.h ../Common/VertexArray.h \ + ../Common/SmoothNormals.h ../Mesh/Metric.h ../Mesh/Matrix.h Views.h \ + ColorTable.h GmshMatrix.h AdaptiveViews.h Trackball.h AdaptiveViews.o: AdaptiveViews.cpp AdaptiveViews.h ../DataStr/List.h \ GmshMatrix.h ../Plugin/Plugin.h ../Common/Options.h ../Common/Message.h \ ../Common/Views.h ../Common/ColorTable.h ../Common/VertexArray.h \ diff --git a/Common/Options.cpp b/Common/Options.cpp index 866a7c7b82..12e17092a0 100644 --- a/Common/Options.cpp +++ b/Common/Options.cpp @@ -1,4 +1,4 @@ -// $Id: Options.cpp,v 1.228 2005-03-11 05:47:54 geuzaine Exp $ +// $Id: Options.cpp,v 1.229 2005-03-11 08:56:37 geuzaine Exp $ // // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle // @@ -2149,6 +2149,20 @@ double opt_general_clip_position1(OPT_ARGS_NUM) return CTX.clip_position[1]; } +double opt_general_manip_position0(OPT_ARGS_NUM) +{ + if(action & GMSH_SET) + CTX.manip_position[0] = (int)val; + return CTX.manip_position[0]; +} + +double opt_general_manip_position1(OPT_ARGS_NUM) +{ + if(action & GMSH_SET) + CTX.manip_position[1] = (int)val; + return CTX.manip_position[1]; +} + double opt_general_visibility_mode(OPT_ARGS_NUM) { if(action & GMSH_SET) @@ -2253,6 +2267,10 @@ double opt_general_quaternion0(OPT_ARGS_NUM) { if(action & GMSH_SET) CTX.quaternion[0] = val; +#if defined(HAVE_FLTK) + if(WID && (action & GMSH_GUI)) + WID->update_manip_window(); +#endif return CTX.quaternion[0]; } @@ -2260,6 +2278,10 @@ double opt_general_quaternion1(OPT_ARGS_NUM) { if(action & GMSH_SET) CTX.quaternion[1] = val; +#if defined(HAVE_FLTK) + if(WID && (action & GMSH_GUI)) + WID->update_manip_window(); +#endif return CTX.quaternion[1]; } @@ -2267,6 +2289,10 @@ double opt_general_quaternion2(OPT_ARGS_NUM) { if(action & GMSH_SET) CTX.quaternion[2] = val; +#if defined(HAVE_FLTK) + if(WID && (action & GMSH_GUI)) + WID->update_manip_window(); +#endif return CTX.quaternion[2]; } @@ -2274,6 +2300,10 @@ double opt_general_quaternion3(OPT_ARGS_NUM) { if(action & GMSH_SET) CTX.quaternion[3] = val; +#if defined(HAVE_FLTK) + if(WID && (action & GMSH_GUI)) + WID->update_manip_window(); +#endif return CTX.quaternion[3]; } @@ -2281,6 +2311,10 @@ double opt_general_translation0(OPT_ARGS_NUM) { if(action & GMSH_SET) CTX.t[0] = val; +#if defined(HAVE_FLTK) + if(WID && (action & GMSH_GUI)) + WID->update_manip_window(); +#endif return CTX.t[0]; } @@ -2288,6 +2322,10 @@ double opt_general_translation1(OPT_ARGS_NUM) { if(action & GMSH_SET) CTX.t[1] = val; +#if defined(HAVE_FLTK) + if(WID && (action & GMSH_GUI)) + WID->update_manip_window(); +#endif return CTX.t[1]; } @@ -2295,6 +2333,10 @@ double opt_general_translation2(OPT_ARGS_NUM) { if(action & GMSH_SET) CTX.t[2] = val; +#if defined(HAVE_FLTK) + if(WID && (action & GMSH_GUI)) + WID->update_manip_window(); +#endif return CTX.t[2]; } @@ -2302,6 +2344,10 @@ double opt_general_scale0(OPT_ARGS_NUM) { if(action & GMSH_SET) CTX.s[0] = val ? val : 1.0; +#if defined(HAVE_FLTK) + if(WID && (action & GMSH_GUI)) + WID->update_manip_window(); +#endif return CTX.s[0]; } @@ -2309,6 +2355,10 @@ double opt_general_scale1(OPT_ARGS_NUM) { if(action & GMSH_SET) CTX.s[1] = val ? val : 1.0; +#if defined(HAVE_FLTK) + if(WID && (action & GMSH_GUI)) + WID->update_manip_window(); +#endif return CTX.s[1]; } @@ -2316,6 +2366,10 @@ double opt_general_scale2(OPT_ARGS_NUM) { if(action & GMSH_SET) CTX.s[2] = val ? val : 1.0; +#if defined(HAVE_FLTK) + if(WID && (action & GMSH_GUI)) + WID->update_manip_window(); +#endif return CTX.s[2]; } diff --git a/Common/Options.h b/Common/Options.h index 897fb36e71..507ac7b367 100644 --- a/Common/Options.h +++ b/Common/Options.h @@ -234,6 +234,8 @@ double opt_general_visibility_position0(OPT_ARGS_NUM); double opt_general_visibility_position1(OPT_ARGS_NUM); double opt_general_clip_position0(OPT_ARGS_NUM); double opt_general_clip_position1(OPT_ARGS_NUM); +double opt_general_manip_position0(OPT_ARGS_NUM); +double opt_general_manip_position1(OPT_ARGS_NUM); double opt_general_visibility_mode(OPT_ARGS_NUM); double opt_general_session_save(OPT_ARGS_NUM); double opt_general_options_save(OPT_ARGS_NUM); diff --git a/Fltk/Callbacks.cpp b/Fltk/Callbacks.cpp index 78a6759fc2..7682ff6991 100644 --- a/Fltk/Callbacks.cpp +++ b/Fltk/Callbacks.cpp @@ -1,4 +1,4 @@ -// $Id: Callbacks.cpp,v 1.340 2005-03-11 05:47:54 geuzaine Exp $ +// $Id: Callbacks.cpp,v 1.341 2005-03-11 08:56:37 geuzaine Exp $ // // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle // @@ -183,42 +183,36 @@ void window_cb(CALLBACK_ARGS) void status_xyz1p_cb(CALLBACK_ARGS) { - extern void set_r(int i, double val); - extern void set_t(int i, double val); - extern void set_s(int i, double val); - switch ((long)data) { case 0: if(CTX.useTrackball) CTX.setQuaternion(0., -1. / sqrt(2.), 0., 1. / sqrt(2.)); - set_r(0, 0.); - set_r(1, 90.); - set_r(2, 0.); + CTX.r[0] = 0.; + CTX.r[1] = 90.; + CTX.r[2] = 0.; Draw(); break; case 1: if(CTX.useTrackball) CTX.setQuaternion(1. / sqrt(2.), 0., 0., 1. / sqrt(2.)); - set_r(0, -90.); - set_r(1, 0.); - set_r(2, 0.); + CTX.r[0] = -90.; + CTX.r[1] = 0.; + CTX.r[2] = 0.; Draw(); break; + case 6: + CTX.t[0] = CTX.t[1] = CTX.t[2] = 0.; + CTX.s[0] = CTX.s[1] = CTX.s[2] = 1.; + // fall-through case 2: if(CTX.useTrackball) CTX.setQuaternion(0., 0., 0., 1.); - set_r(0, 0.); - set_r(1, 0.); - set_r(2, 0.); + CTX.r[0] = CTX.r[1] = CTX.r[2] = 0.; Draw(); break; case 3: - set_t(0, 0.); - set_t(1, 0.); - set_t(2, 0.); - set_s(0, 1.); - set_s(1, 1.); - set_s(2, 1.); + CTX.t[0] = CTX.t[1] = CTX.t[2] = 0.; + CTX.s[0] = CTX.s[1] = CTX.s[2] = 1.; Draw(); break; case 4: @@ -231,6 +225,7 @@ void status_xyz1p_cb(CALLBACK_ARGS) WID->create_message_window(); break; } + WID->update_manip_window(); } static int stop_anim, view_in_cycle = -1; @@ -1248,6 +1243,28 @@ void clip_reset_cb(CALLBACK_ARGS) Draw(); } +// Manipulator menu + +void manip_cb(CALLBACK_ARGS) +{ + WID->create_manip_window(); +} + +void manip_update_cb(CALLBACK_ARGS) +{ + CTX.r[0] = WID->manip_value[0]->value(); + CTX.r[1] = WID->manip_value[1]->value(); + CTX.r[2] = WID->manip_value[2]->value(); + CTX.t[0] = WID->manip_value[3]->value(); + CTX.t[1] = WID->manip_value[4]->value(); + CTX.t[2] = WID->manip_value[5]->value(); + CTX.s[0] = WID->manip_value[6]->value(); + CTX.s[1] = WID->manip_value[7]->value(); + CTX.s[2] = WID->manip_value[8]->value(); + CTX.setQuaternionFromEulerAngles(); + Draw(); +} + // Help Menu (if you change the following, please also change the // texinfo documentation in doc/texinfo/shortcuts.texi) @@ -1297,6 +1314,7 @@ void help_short_cb(CALLBACK_ARGS) Msg(DIRECT, " Ctrl+s Save file as"); Msg(DIRECT, " "); Msg(DIRECT, " Shift+Ctrl+c Show clipping plane window"); + Msg(DIRECT, " Shift+Ctrl+m Show manipulator window"); Msg(DIRECT, " Shift+Ctrl+n Show option window"); Msg(DIRECT, " Shift+Ctrl+o Merge file(s)"); Msg(DIRECT, " Shift+Ctrl+s Save mesh in default format"); diff --git a/Fltk/Callbacks.h b/Fltk/Callbacks.h index cf635fe910..01985c9ef8 100644 --- a/Fltk/Callbacks.h +++ b/Fltk/Callbacks.h @@ -166,6 +166,11 @@ void clip_invert_cb(CALLBACK_ARGS); void clip_num_cb(CALLBACK_ARGS); void clip_reset_cb(CALLBACK_ARGS); +// Manipulator Menu + +void manip_cb(CALLBACK_ARGS); +void manip_update_cb(CALLBACK_ARGS); + // Help Menu void help_short_cb(CALLBACK_ARGS); diff --git a/Fltk/GUI.cpp b/Fltk/GUI.cpp index ffe7f6c390..9e388e9347 100644 --- a/Fltk/GUI.cpp +++ b/Fltk/GUI.cpp @@ -1,4 +1,4 @@ -// $Id: GUI.cpp,v 1.421 2005-03-11 05:47:55 geuzaine Exp $ +// $Id: GUI.cpp,v 1.422 2005-03-11 08:56:38 geuzaine Exp $ // // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle // @@ -111,7 +111,8 @@ Fl_Menu_Item m_menubar_table[] = { {"&Tools", 0, 0, 0, FL_SUBMENU}, {"&Options...", FL_CTRL+FL_SHIFT+'n', (Fl_Callback *)options_cb, 0}, {"&Visibility", FL_CTRL+FL_SHIFT+'v', (Fl_Callback *)visibility_cb, 0}, - {"&Clipping Planes", FL_CTRL+FL_SHIFT+'c', (Fl_Callback *)clip_cb, 0, FL_MENU_DIVIDER}, + {"&Clipping Planes", 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}, {0}, @@ -143,7 +144,8 @@ Fl_Menu_Item m_sys_menubar_table[] = { {"Tools",0,0,0,FL_SUBMENU}, {"Options...", FL_CTRL+FL_SHIFT+'n', (Fl_Callback *)options_cb, 0}, {"Visibility", FL_CTRL+FL_SHIFT+'v', (Fl_Callback *)visibility_cb, 0}, - {"Clipping Planes", FL_CTRL+FL_SHIFT+'c', (Fl_Callback *)clip_cb, 0, FL_MENU_DIVIDER}, + {"Clipping Planes", FL_CTRL+FL_SHIFT+'c', (Fl_Callback *)clip_cb, 0}, + {"Manipulator", FL_CTRL+FL_SHIFT+'m', (Fl_Callback *)manip_cb, 0, FL_MENU_DIVIDER}, {"Statistics", FL_CTRL+'i', (Fl_Callback *)statistics_cb, 0}, {"Message Console", FL_CTRL+'l', (Fl_Callback *)message_cb, 0}, {0}, @@ -804,6 +806,7 @@ GUI::GUI(int argc, char **argv) msg_window = NULL; vis_window = NULL; clip_window = NULL; + manip_window = NULL; about_window = NULL; context_geometry_window = NULL; context_mesh_window = NULL; @@ -871,6 +874,7 @@ GUI::GUI(int argc, char **argv) create_statistics_window(); create_visibility_window(); create_clip_window(); + create_manip_window(); create_about_window(); create_geometry_context_window(0); create_mesh_context_window(0); @@ -3744,6 +3748,95 @@ void GUI::create_clip_window() clip_window->end(); } +// create the manipulator + +void GUI::update_manip_window(int force) +{ + if(force || manip_window->shown()){ + double val1 = CTX.lc; + for(int i = 0; i < 3; i++){ + manip_value[i]->value(CTX.r[i]); + manip_value[i]->minimum(-360.); + manip_value[i]->maximum(360.); + manip_value[i]->step(1.); + + manip_value[i+3]->value(CTX.t[i]); + manip_value[i+3]->minimum(-val1); + manip_value[i+3]->maximum(val1); + manip_value[i+3]->step(val1/200.); + + manip_value[i+6]->value(CTX.s[i]); + manip_value[i+6]->minimum(0.01); + manip_value[i+6]->maximum(100.); + manip_value[i+6]->step(0.01); + } + } +} + +void GUI::create_manip_window() +{ + if(manip_window) { + update_manip_window(1); + manip_window->show(); + return; + } + + int width = 4 * BB + 2 * WB; + int height = 5 * BH + 3 * WB; + + manip_window = new Dialog_Window(width, height, "Manipulator"); + manip_window->box(GMSH_WINDOW_BOX); + + Fl_Box *top[3], *left[3]; + top[0] = new Fl_Box(WB + 1 * BB, 1 * WB + 0 * BH, BB, BH, "X"); + top[1] = new Fl_Box(WB + 2 * BB, 1 * WB + 0 * BH, BB, BH, "Y"); + top[2] = new Fl_Box(WB + 3 * BB, 1 * WB + 0 * BH, BB, BH, "Z"); + left[0] = new Fl_Box(WB + 0 * BB, 1 * WB + 1 * BH, BB, BH, "Rotation"); + left[1] = new Fl_Box(WB + 0 * BB, 1 * WB + 2 * BH, BB, BH, "Translation"); + left[2] = new Fl_Box(WB + 0 * BB, 1 * WB + 3 * BH, BB, BH, "Scale"); + for(int i = 0; i < 3; i++){ + top[i]->align(FL_ALIGN_INSIDE|FL_ALIGN_CENTER); + left[i]->align(FL_ALIGN_INSIDE|FL_ALIGN_CENTER); + } + + manip_value[0] = new Fl_Value_Input(WB + 1 * BB, 1 * WB + 1 * BH, BB, BH); + manip_value[1] = new Fl_Value_Input(WB + 2 * BB, 1 * WB + 1 * BH, BB, BH); + manip_value[2] = new Fl_Value_Input(WB + 3 * BB, 1 * WB + 1 * BH, BB, BH); + manip_value[3] = new Fl_Value_Input(WB + 1 * BB, 1 * WB + 2 * BH, BB, BH); + manip_value[4] = new Fl_Value_Input(WB + 2 * BB, 1 * WB + 2 * BH, BB, BH); + manip_value[5] = new Fl_Value_Input(WB + 3 * BB, 1 * WB + 2 * BH, BB, BH); + manip_value[6] = new Fl_Value_Input(WB + 1 * BB, 1 * WB + 3 * BH, BB, BH); + manip_value[7] = new Fl_Value_Input(WB + 2 * BB, 1 * WB + 3 * BH, BB, BH); + manip_value[8] = new Fl_Value_Input(WB + 3 * BB, 1 * WB + 3 * BH, BB, BH); + + for(int i = 0; i < 9; i++){ + if(i < 3){ + manip_value[i]->minimum(0.); + manip_value[i]->maximum(360.); + manip_value[i]->step(1.); + } + else if(i > 5){ + manip_value[i]->minimum(0.1); + manip_value[i]->maximum(100.); + manip_value[i]->step(0.1); + } + manip_value[i]->align(FL_ALIGN_RIGHT); + manip_value[i]->callback(manip_update_cb); + } + + { + Fl_Button *o = new Fl_Button(width - 2 * BB - 2 * WB, height - BH - WB, BB, BH, "Reset"); + o->callback(status_xyz1p_cb, (void *)6); + } + { + Fl_Return_Button *o = new Fl_Return_Button(width - BB - WB, height - BH - WB, BB, BH, "Cancel"); + o->callback(cancel_cb, (void *)manip_window); + } + + manip_window->position(CTX.manip_position[0], CTX.manip_position[1]); + manip_window->end(); +} + // Create the about window void GUI::create_about_window() diff --git a/Fltk/GUI.h b/Fltk/GUI.h index 6dd0834788..12c094fbb5 100644 --- a/Fltk/GUI.h +++ b/Fltk/GUI.h @@ -229,6 +229,10 @@ public: Fl_Multi_Browser *clip_browser ; Fl_Value_Input *clip_value[4]; + // manipulator window + Fl_Window *manip_window ; + Fl_Value_Input *manip_value[9] ; + // about window Fl_Window *about_window ; @@ -264,6 +268,7 @@ public: void create_view_options_window(int numview); void create_visibility_window(); void create_clip_window(); + void create_manip_window(); void create_statistics_window(); void create_message_window(); void create_about_window(); @@ -297,6 +302,7 @@ public: void reset_visibility(); void reset_option_browser(); void reset_clip_browser(); + void update_manip_window(int force=0); void reset_external_view_list(); int selection, try_selection, quit_selection, end_selection, undo_selection; diff --git a/Fltk/Message.cpp b/Fltk/Message.cpp index 79c67fa072..352405214c 100644 --- a/Fltk/Message.cpp +++ b/Fltk/Message.cpp @@ -1,4 +1,4 @@ -// $Id: Message.cpp,v 1.63 2005-02-16 05:17:54 geuzaine Exp $ +// $Id: Message.cpp,v 1.64 2005-03-11 08:56:38 geuzaine Exp $ // // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle // @@ -243,6 +243,8 @@ void Exit(int level) CTX.vis_position[1] = WID->vis_window->y(); CTX.clip_position[0] = WID->clip_window->x(); CTX.clip_position[1] = WID->clip_window->y(); + CTX.manip_position[0] = WID->manip_window->x(); + CTX.manip_position[1] = WID->manip_window->y(); CTX.ctx_position[0] = WID->context_geometry_window->x(); CTX.ctx_position[1] = WID->context_geometry_window->y(); CTX.solver_position[0] = WID->solver[0].window->x(); diff --git a/Fltk/Opengl.cpp b/Fltk/Opengl.cpp index 58fb869c70..9b4b5a8ba8 100644 --- a/Fltk/Opengl.cpp +++ b/Fltk/Opengl.cpp @@ -1,4 +1,4 @@ -// $Id: Opengl.cpp,v 1.50 2005-03-11 05:47:55 geuzaine Exp $ +// $Id: Opengl.cpp,v 1.51 2005-03-11 08:56:38 geuzaine Exp $ // // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle // @@ -37,9 +37,6 @@ void Process_SelectionBuffer(int x, int y, int *n, GLuint * ii, GLuint * jj); void Filter_SelectionBuffer(int n, GLuint * typ, GLuint * ient, Vertex ** thev, Curve ** thec, Surface ** thes, Mesh * m); -void myZoom(GLdouble X1, GLdouble X2, GLdouble Y1, GLdouble Y2, GLdouble Xc1, - GLdouble Xc2, GLdouble Yc1, GLdouble Yc2); - // Draw specialization void InitOpengl(void) @@ -200,31 +197,6 @@ void Draw_OnScreenMessages() } } -// Euler angles set_XXX - -void set_r(int i, double val) -{ - if(!CTX.useTrackball) { - if(!CTX.rlock[i]) { - CTX.r[i] = val; - } - } -} - -void set_t(int i, double val) -{ - if(!CTX.tlock[i]) { - CTX.t[i] = val; - } -} - -void set_s(int i, double val) -{ - if(!CTX.slock[i]) { - CTX.s[i] = val; - } -} - // Select entity routines int check_type(int type, Vertex * v, Curve * c, Surface * s) diff --git a/Fltk/Opengl_Window.cpp b/Fltk/Opengl_Window.cpp index 27c9e5d8bb..a4ae8aa352 100644 --- a/Fltk/Opengl_Window.cpp +++ b/Fltk/Opengl_Window.cpp @@ -1,4 +1,4 @@ -// $Id: Opengl_Window.cpp,v 1.46 2005-03-09 02:18:40 geuzaine Exp $ +// $Id: Opengl_Window.cpp,v 1.47 2005-03-11 08:56:38 geuzaine Exp $ // // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle // @@ -39,8 +39,6 @@ void Process_SelectionBuffer(int x, int y, int *n, GLuint * ii, GLuint * jj); void Filter_SelectionBuffer(int n, GLuint * typ, GLuint * ient, Vertex ** thev, Curve ** thec, Surface ** thes, Mesh * m); -void myZoom(GLdouble X1, GLdouble X2, GLdouble Y1, GLdouble Y2, GLdouble Xc1, - GLdouble Xc2, GLdouble Yc1, GLdouble Yc2); int check_type(int type, Vertex * v, Curve * c, Surface * s); void Opengl_Window::draw() @@ -113,6 +111,27 @@ void Opengl_Window::draw() locked = 0; } +// FIXME: this is notoriously wrong :-) + +void myZoom(GLdouble X1, GLdouble X2, GLdouble Y1, GLdouble Y2, + GLdouble Xc1, GLdouble Xc2, GLdouble Yc1, GLdouble Yc2) +{ + GLdouble xscale1 = CTX.s[0]; + GLdouble yscale1 = CTX.s[1]; + CTX.s[0] *= (CTX.vxmax - CTX.vxmin) / (X2 - X1); + CTX.s[1] *= (CTX.vymax - CTX.vymin) / (Y1 - Y2); + CTX.s[2] = MIN(CTX.s[0], CTX.s[1]); // bof... + CTX.t[0] = CTX.t[0] * (xscale1 / CTX.s[0]) - + ((Xc1 + Xc2) / 2.) * (1. - (xscale1 / CTX.s[0])); + CTX.t[1] = CTX.t[1] * (yscale1 / CTX.s[1]) - + ((Yc1 + Yc2) / 2.) * (1. - (yscale1 / CTX.s[1])); + + WID->update_manip_window(); + InitPosition(); + Draw(); +} + + // The event model in FLTK is pretty different from other toolkits: // the events are passed to the widget handle of the widget that has // the focus. If this handle returns 1, then the event is considered @@ -167,8 +186,8 @@ int Opengl_Window::handle(int event) } else if(ibut == 2 || (ibut == 1 && Fl::event_state(FL_SHIFT))) { if(Fl::event_state(FL_CTRL) && !ZoomClick) { - set_s(1, CTX.s[0]); - set_s(2, CTX.s[0]); + CTX.s[1] = CTX.s[0]; + CTX.s[2] = CTX.s[0]; redraw(); } else { @@ -179,23 +198,17 @@ int Opengl_Window::handle(int event) if(Fl::event_state(FL_CTRL) && !ZoomClick) { if(CTX.useTrackball) CTX.setQuaternion(0., 0., 0., 1.); - else { - set_r(0, 0.); - set_r(1, 0.); - set_r(2, 0.); - } - set_t(0, 0.); - set_t(1, 0.); - set_t(2, 0.); - set_s(0, 1.); - set_s(1, 1.); - set_s(2, 1.); + else + CTX.r[0] = CTX.r[1] = CTX.r[2] = 0.; + CTX.t[0] = CTX.t[1] = CTX.t[2] = 0.; + CTX.s[0] = CTX.s[1] = CTX.s[2] = 1.; redraw(); } else { ZoomClick = false; } } + WID->update_manip_window(); return 1; case FL_RELEASE: @@ -237,25 +250,22 @@ int Opengl_Window::handle(int event) (2.0 * Fl::event_x() - w()) / w(), (h() - 2.0 * Fl::event_y()) / h()); else { - set_r(1, CTX.r[1] + ((abs(xmov) > abs(ymov)) ? - 180 * (double)xmov / (double)w() : 0)); - set_r(0, CTX.r[0] + ((abs(xmov) > abs(ymov)) ? - 0 : 180 * (double)ymov / (double)h())); + CTX.r[1] += ((abs(xmov) > abs(ymov)) ? 180 * (double)xmov / (double)w() : 0); + CTX.r[0] += ((abs(xmov) > abs(ymov)) ? 0 : 180 * (double)ymov / (double)h()); } } else if(ibut == 2 || (ibut == 1 && Fl::event_state(FL_SHIFT))) { if(!CTX.useTrackball) - set_r(2, CTX.r[2] + (abs(ymov) > abs(xmov) ? - 0 : -180 * (double)xmov / (double)w())); + CTX.r[2] += (abs(ymov) > abs(xmov) ? 0 : -180 * (double)xmov / (double)w()); double zoomfact = (ymov > 0) ? (double)(CTX.zoom_factor * abs(ymov) + h()) / (double)h() : (double)(h()) / (double)(CTX.zoom_factor * abs(ymov) + h()); - set_s(0, CTX.s[0] * (abs(ymov) > abs(xmov) ? zoomfact : 1.)); - set_s(1, CTX.s[0]); - set_s(2, CTX.s[0]); + CTX.s[0] *= (abs(ymov) > abs(xmov) ? zoomfact : 1.); + CTX.s[1] = CTX.s[0]; + CTX.s[2] = CTX.s[0]; if(abs(ymov) > abs(xmov)) { - set_t(0, xt1 * (xscale1 / CTX.s[0]) - xc1 * (1. - (xscale1 / CTX.s[0]))); - set_t(1, yt1 * (yscale1 / CTX.s[1]) - yc1 * (1. - (yscale1 / CTX.s[1]))); + CTX.t[0] = xt1 * (xscale1 / CTX.s[0]) - xc1 * (1. - (xscale1 / CTX.s[0])); + CTX.t[1] = yt1 * (yscale1 / CTX.s[1]) - yc1 * (1. - (yscale1 / CTX.s[1])); } } else { @@ -263,9 +273,9 @@ int Opengl_Window::handle(int event) / CTX.s[0]; yc = (CTX.vymax - ((double)ypos / (double)h()) * (CTX.vymax - CTX.vymin)) / CTX.s[1]; - set_t(0, xc - xc1); - set_t(1, yc - yc1); - set_t(2, 0.); + CTX.t[0] = xc - xc1; + CTX.t[1] = yc - yc1; + CTX.t[2] = 0.; } if(CTX.fast_redraw) { @@ -278,6 +288,7 @@ int Opengl_Window::handle(int event) xpos += xmov; ypos += ymov; + WID->update_manip_window(); return 1; case FL_MOVE: diff --git a/Geo/MinMax.cpp b/Geo/MinMax.cpp index 22aedbb114..4f6c9d62d8 100644 --- a/Geo/MinMax.cpp +++ b/Geo/MinMax.cpp @@ -1,4 +1,4 @@ -// $Id: MinMax.cpp,v 1.16 2005-01-01 19:35:28 geuzaine Exp $ +// $Id: MinMax.cpp,v 1.17 2005-03-11 08:56:38 geuzaine Exp $ // // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle // @@ -57,7 +57,7 @@ void CalculateMinMax(Tree_T * t, double *bbox) CTX.min[0] = CTX.min[1] = CTX.min[2] = -1.; CTX.max[0] = CTX.max[1] = CTX.max[2] = 1.; CTX.range[0] = CTX.range[1] = CTX.range[2] = 0.; - CTX.lc = CTX.lc_middle = 1.; + CTX.lc = 1.; return; } else { @@ -95,56 +95,40 @@ void CalculateMinMax(Tree_T * t, double *bbox) CTX.max[0] += 1.; CTX.max[1] += 1.; CTX.lc = 1.; - CTX.lc_middle = 0.; } else if(CTX.range[0] == 0. && CTX.range[1] == 0.) { - CTX.lc = CTX.lc_middle = CTX.range[2]; + CTX.lc = CTX.range[2]; CTX.min[0] -= CTX.lc; CTX.min[1] -= CTX.lc; CTX.max[0] += CTX.lc; CTX.max[1] += CTX.lc; } else if(CTX.range[0] == 0. && CTX.range[2] == 0.) { - CTX.lc = CTX.lc_middle = CTX.range[1]; + CTX.lc = CTX.range[1]; CTX.min[0] -= CTX.lc; CTX.max[0] += CTX.lc; } else if(CTX.range[1] == 0. && CTX.range[2] == 0.) { - CTX.lc = CTX.lc_middle = CTX.range[0]; + CTX.lc = CTX.range[0]; CTX.min[1] -= CTX.lc; CTX.max[1] += CTX.lc; } else if(CTX.range[0] == 0.) { CTX.lc = sqrt(DSQR(CTX.range[1]) + DSQR(CTX.range[2])); - CTX.lc_middle = DMIN(CTX.range[1], CTX.range[2]); CTX.min[0] -= CTX.lc; CTX.max[0] += CTX.lc; } else if(CTX.range[1] == 0.) { CTX.lc = sqrt(DSQR(CTX.range[0]) + DSQR(CTX.range[2])); - CTX.lc_middle = DMIN(CTX.range[0], CTX.range[2]); CTX.min[1] -= CTX.lc; CTX.max[1] += CTX.lc; } else if(CTX.range[2] == 0.) { CTX.lc = sqrt(DSQR(CTX.range[0]) + DSQR(CTX.range[1])); - CTX.lc_middle = DMIN(CTX.range[0], CTX.range[1]); } else { CTX.lc = sqrt(DSQR(CTX.range[0]) + DSQR(CTX.range[1]) + DSQR(CTX.range[2])); - if((CTX.range[1] <= CTX.range[0] && CTX.range[0] <= CTX.range[2]) - || (CTX.range[2] <= CTX.range[0] && CTX.range[0] <= CTX.range[1])) - CTX.lc_middle = CTX.range[0]; - else if((CTX.range[0] <= CTX.range[1] && CTX.range[1] <= CTX.range[2]) || - (CTX.range[2] <= CTX.range[1] && CTX.range[1] <= CTX.range[0])) - CTX.lc_middle = CTX.range[1]; - else - CTX.lc_middle = CTX.range[2]; } - // CTX.lc_order : CTX.lc == f * 10^CTX.lc_order with -1<f<1 - - frac = frexp(CTX.lc, &exp); - CTX.lc_order = (int)floor(log10(ldexp(frac, exp))); } diff --git a/Graphics/Draw.cpp b/Graphics/Draw.cpp index 43e94d931c..48d1efee27 100644 --- a/Graphics/Draw.cpp +++ b/Graphics/Draw.cpp @@ -1,4 +1,4 @@ -// $Id: Draw.cpp,v 1.74 2005-03-11 05:47:55 geuzaine Exp $ +// $Id: Draw.cpp,v 1.75 2005-03-11 08:56:38 geuzaine Exp $ // // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle // @@ -266,7 +266,7 @@ void InitPosition(void) CTX.rotation_center[1], CTX.rotation_center[2]); - CTX.buildRotmatrix(); + CTX.buildRotationMatrix(); glMultMatrixd(CTX.rot); if(CTX.rotation_center_cg) @@ -348,24 +348,6 @@ void Filter_SelectionBuffer(int n, GLuint * typ, GLuint * ient, } } -// FIXME: this is notoriously wrong :-) - -void myZoom(GLdouble X1, GLdouble X2, GLdouble Y1, GLdouble Y2, - GLdouble Xc1, GLdouble Xc2, GLdouble Yc1, GLdouble Yc2) -{ - GLdouble xscale1 = CTX.s[0]; - GLdouble yscale1 = CTX.s[1]; - set_s(0, CTX.s[0] * (CTX.vxmax - CTX.vxmin) / (X2 - X1)); - set_s(1, CTX.s[1] * (CTX.vymax - CTX.vymin) / (Y1 - Y2)); - set_s(2, MIN(CTX.s[0], CTX.s[1])); // bof... - set_t(0, CTX.t[0] * (xscale1 / CTX.s[0]) - - ((Xc1 + Xc2) / 2.) * (1. - (xscale1 / CTX.s[0]))); - set_t(1, CTX.t[1] * (yscale1 / CTX.s[1]) - - ((Yc1 + Yc2) / 2.) * (1. - (yscale1 / CTX.s[1]))); - InitPosition(); - Draw(); -} - // Takes a cursor position in window coordinates and returns the line // (given by a point and a unit direction vector), in real space, that // corresponds to that cursor position diff --git a/Graphics/Draw.h b/Graphics/Draw.h index c444654d99..3daecb2a55 100644 --- a/Graphics/Draw.h +++ b/Graphics/Draw.h @@ -38,10 +38,6 @@ void Orthogonalize(int x, int y); void ClearOpengl(void); void SetOpenglContext(void); -void set_r(int i, double val); -void set_t(int i, double val); -void set_s(int i, double val); - void unproject(double x, double y, double p[3], double d[3]); void Viewport2World(double win[3], double xyz[3]); void World2Viewport(double xyz[3], double win[3]); diff --git a/doc/VERSIONS b/doc/VERSIONS index 4d1bce9c62..d4e9d83fad 100644 --- a/doc/VERSIONS +++ b/doc/VERSIONS @@ -1,12 +1,12 @@ -$Id: VERSIONS,v 1.316 2005-03-11 05:47:56 geuzaine Exp $ +$Id: VERSIONS,v 1.317 2005-03-11 08:56:38 geuzaine Exp $ New since 1.59: added support for discrete curves; new Window menu on Mac OS X; generalized all octree-based plugins (CutGrid, StreamLines, Probe, etc.) to handle all element types (and not only scalar and vector triangles+tetrahedra); generalized Plugin(Evaluate) and Plugin(Extract); enhanced clipping plane interface; new grid options -for 3D post-processing views; various small enhancements and bug -fixes. +for 3D post-processing views; new manipulator dialog; various small +enhancements and bug fixes. New in 1.59: added support for discrete (triangulated) surfaces, either in STL format or with the new "Discrete Surface" command; added diff --git a/doc/texinfo/shortcuts.texi b/doc/texinfo/shortcuts.texi index c280ec2100..7279d9b5b8 100644 --- a/doc/texinfo/shortcuts.texi +++ b/doc/texinfo/shortcuts.texi @@ -73,6 +73,8 @@ Save file @item Shift+Ctrl+c Show clipping plane window +@item Shift+Ctrl+m +Show manipulator window @item Shift+Ctrl+n Show option window @item Shift+Ctrl+o -- GitLab