diff --git a/Common/Context.h b/Common/Context.h index 5a452845d2a182615c70f61a987eb0ae007decb7..54dfcdfcf895553e32bd6e0baf5ce1c657a884f1 100644 --- a/Common/Context.h +++ b/Common/Context.h @@ -94,6 +94,7 @@ public : double rot[16]; // current rotation matrix double r[3]; // current Euler angles (in degrees!) double t[3], s[3]; // current translation and scale + double t_init[3]; // initial translation before applying modelview transform double clip_factor; // clipping plane distance factor double quaternion[4]; // current quaternion used for "trackball" rotation int useTrackball; // do or do not use the trackball for rotations @@ -147,7 +148,6 @@ public : double model[16], proj[16]; // the modelview and projection matrix as they were // at the time of the last InitPosition() call - double model_init[16]; // the modelview matrix before applying s, t and rot int forced_bbox; // dynamic variable tracking if the bbox is currently imposed diff --git a/Common/Options.cpp b/Common/Options.cpp index b9a708d6713f8aa15cf167ed112c88b3101e5184..ad8bd09fb53bd01e8af93462e925431354acce1e 100644 --- a/Common/Options.cpp +++ b/Common/Options.cpp @@ -1,4 +1,4 @@ -// $Id: Options.cpp,v 1.264 2005-12-16 17:35:32 geuzaine Exp $ +// $Id: Options.cpp,v 1.265 2005-12-18 21:10:54 geuzaine Exp $ // // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle // @@ -2759,13 +2759,12 @@ double opt_general_orthographic(OPT_ARGS_NUM) if(WID && (action & GMSH_GUI)) { if(CTX.ortho){ WID->gen_choice[2]->value(0); - //WID->persp_bmp->label(WID->g_status_butt[4]); + Msg(STATUS1N, "Orthographic projection"); } else{ WID->gen_choice[2]->value(1); - //WID->ortho_bmp->label(WID->g_status_butt[4]); + Msg(STATUS1N, "Perspective projection"); } - //WID->g_status_butt[4]->redraw(); } #endif return CTX.ortho; diff --git a/Fltk/Bitmaps.h b/Fltk/Bitmaps.h index 94fe5bf80ce9ac1bc9e1e5fc55551d4dfcae2ca3..ec615af45b768eb21774d45d8272ad00f2e169a8 100644 --- a/Fltk/Bitmaps.h +++ b/Fltk/Bitmaps.h @@ -81,14 +81,7 @@ static unsigned char ortho_bits[] = { 0x12, 0x09, 0x12, 0x09, 0xf2, 0x0f, 0x0a, 0x05, 0x06, 0x03, 0xfe, 0x01, 0x00, 0x00 }; -// 'Perspective projection' bitmap -#define persp_width 13 -#define persp_height 13 -static unsigned char persp_bits[] = { - 0x00, 0x00, 0xf0, 0x0f, 0x10, 0x0c, 0x18, 0x0a, 0x18, 0x09, 0x94, 0x08, - 0x7c, 0x08, 0x54, 0x08, 0xf4, 0x0f, 0x44, 0x03, 0xfc, 0x00, 0x00, 0x00, - 0x00, 0x00 }; - +// '90 degrees rotation' bitmap #define rotate_width 12 #define rotate_height 13 static unsigned char rotate_bits[] = { diff --git a/Fltk/Callbacks.cpp b/Fltk/Callbacks.cpp index 1b28f880816b6df883287ce688f6b5ca24ecc990..17387790e5b7b1d192dfd55183c22936f49d948a 100644 --- a/Fltk/Callbacks.cpp +++ b/Fltk/Callbacks.cpp @@ -1,4 +1,4 @@ -// $Id: Callbacks.cpp,v 1.386 2005-12-16 20:20:17 geuzaine Exp $ +// $Id: Callbacks.cpp,v 1.387 2005-12-18 21:10:54 geuzaine Exp $ // // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle // @@ -449,7 +449,7 @@ void status_xyz1p_cb(CALLBACK_ARGS) CTX.setQuaternionFromEulerAngles(); Draw(); } - else if(!strcmp(str, "p")){ // switch projection mode + else if(!strcmp(str, "p")){ // toggle projection mode opt_general_orthographic(0, GMSH_SET | GMSH_GUI, !opt_general_orthographic(0, GMSH_GET, 0)); Draw(); @@ -1012,7 +1012,7 @@ void general_options_ok_cb(CALLBACK_ARGS) } opt_general_vector_type(0, GMSH_SET, val); opt_general_graphics_font(0, GMSH_SET, (char *)WID->gen_choice[1]->text()); - opt_general_orthographic(0, GMSH_SET | GMSH_GUI, !WID->gen_choice[2]->value()); + opt_general_orthographic(0, GMSH_SET, !WID->gen_choice[2]->value()); opt_general_axes(0, GMSH_SET, WID->gen_choice[4]->value()); opt_general_background_gradient(0, GMSH_SET, WID->gen_choice[5]->value()); } diff --git a/Fltk/GUI.cpp b/Fltk/GUI.cpp index 049adbbe103e772c2540b5972879dfe6d4ad233a..3dd3e9cbd0933a8d3ffd5a56be94e39a1aa571fc 100644 --- a/Fltk/GUI.cpp +++ b/Fltk/GUI.cpp @@ -1,4 +1,4 @@ -// $Id: GUI.cpp,v 1.472 2005-12-16 17:35:32 geuzaine Exp $ +// $Id: GUI.cpp,v 1.473 2005-12-18 21:10:54 geuzaine Exp $ // // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle // @@ -1360,15 +1360,12 @@ void GUI::create_graphic_window() g_status_butt[3]->callback(status_xyz1p_cb, (void *)"1:1"); g_status_butt[3]->tooltip("Set unit scale"); - //FIXME: remove this until we do the perspective projection properly - //FIXME: need to change the button number!! - //g_status_butt[4] = new Fl_Button(x, glheight + 2, sw, sh - 4); - //x += sw; - //g_status_butt[4]->callback(status_xyz1p_cb, (void *)"p"); - //g_status_butt[4]->tooltip("Set orthographic/perspective projection"); + g_status_butt[8] = new Fl_Button(x, glheight + 2, sw, sh - 4); + x += sw; + g_status_butt[8]->callback(status_xyz1p_cb, (void *)"p"); + g_status_butt[8]->tooltip("Toggle projection mode (Alt+o)"); ortho_bmp = new Fl_Bitmap(ortho_bits, ortho_width, ortho_height); - persp_bmp = new Fl_Bitmap(persp_bits, persp_width, persp_height); - //persp_bmp->label(g_status_butt[4]); + ortho_bmp->label(g_status_butt[8]); g_status_butt[5] = new Fl_Button(x, glheight + 2, sw, sh - 4, "?"); x += sw; @@ -1378,10 +1375,10 @@ void GUI::create_graphic_window() g_status_butt[6] = new Fl_Button(x, glheight + 2, sw, sh - 4); x += sw; g_status_butt[6]->callback(status_rewind_cb); + g_status_butt[6]->tooltip("Rewind animation"); rewind_bmp = new Fl_Bitmap(rewind_bits, rewind_width, rewind_height); rewind_bmp->label(g_status_butt[6]); g_status_butt[6]->deactivate(); - g_status_butt[6]->tooltip("Rewind animation"); g_status_butt[7] = new Fl_Button(x, glheight + 2, sw, sh - 4); x += sw; @@ -1392,7 +1389,7 @@ void GUI::create_graphic_window() stop_bmp = new Fl_Bitmap(stop_bits, stop_width, stop_height); g_status_butt[7]->deactivate(); - for(i = 0; i < 8; i++) { + for(i = 0; i < 9; i++) { g_status_butt[i]->box(FL_FLAT_BOX); g_status_butt[i]->selection_color(FL_WHITE); g_status_butt[i]->align(FL_ALIGN_CENTER | FL_ALIGN_INSIDE | FL_ALIGN_CLIP); diff --git a/Fltk/GUI.h b/Fltk/GUI.h index 1617338295bc6980148e943913d9fa676ba57c17..df3a05ccce6e1f677accfc0372c792bf185d7f6b 100644 --- a/Fltk/GUI.h +++ b/Fltk/GUI.h @@ -126,14 +126,12 @@ class GUI{ Fl_Scroll *m_scroll; // Bitmaps - Fl_Bitmap *abort_bmp, *start_bmp, *stop_bmp, *rewind_bmp, *rotate_bmp ; + Fl_Bitmap *abort_bmp, *start_bmp, *stop_bmp, *rewind_bmp, *rotate_bmp, *ortho_bmp ; void add_post_plugins ( Fl_Menu_Button *button , int iView); void add_multiline_in_browser(Fl_Browser *o, char* prefix, char *str); public: - Fl_Bitmap *ortho_bmp, *persp_bmp; - // menu window Fl_Window *m_window ; #if defined(__APPLE__) && defined(HAVE_FLTK_1_1_5_OR_ABOVE) @@ -153,7 +151,7 @@ public: // graphic window Fl_Window *g_window ; Opengl_Window *g_opengl_window ; - Fl_Button *g_status_butt[8] ; + Fl_Button *g_status_butt[9] ; Fl_Box *g_status_label[3] ; // Option window diff --git a/Fltk/Opengl_Window.cpp b/Fltk/Opengl_Window.cpp index 3f00be67a0f20218dbf79680a6b928672dff2ca7..43c126ba37095d5592ed90bba69c83ba5e6022b3 100644 --- a/Fltk/Opengl_Window.cpp +++ b/Fltk/Opengl_Window.cpp @@ -1,4 +1,4 @@ -// $Id: Opengl_Window.cpp,v 1.55 2005-12-18 18:10:46 geuzaine Exp $ +// $Id: Opengl_Window.cpp,v 1.56 2005-12-18 21:10:54 geuzaine Exp $ // // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle // @@ -44,53 +44,24 @@ void MousePosition::set() win[1] = (double)Fl::event_y(); win[2] = 0.; - wnr[0] = (CTX.vxmin + win[0] / (double)CTX.viewport[2] * - (CTX.vxmax - CTX.vxmin)) / CTX.s[0] - CTX.t[0]; - wnr[1] = (CTX.vymax - win[1] / (double)CTX.viewport[3] * - (CTX.vymax - CTX.vymin)) / CTX.s[1] - CTX.t[1]; + wnr[0] = + (CTX.vxmin + win[0] / (double)CTX.viewport[2] * (CTX.vxmax - CTX.vxmin)) + / CTX.s[0] - CTX.t[0] + CTX.t_init[0] / CTX.s[0]; + wnr[1] = + (CTX.vymax - win[1] / (double)CTX.viewport[3] * (CTX.vymax - CTX.vymin)) + / CTX.s[1] - CTX.t[1] + CTX.t_init[1] / CTX.s[1]; wnr[2] = 0.; - - // might need this later - // Viewport2World(win, world); } void MousePosition::recenter() { - // this computes the equivalent translation to apply after the - // scaling so that the scaling is done around the point which was - // clicked. FIXME: needs to be generalized to the case where an - // initial translation is done BEFORE the scaling (necessary for the - // general perspective case, with the line of sight in the middle of - // the screen, and not just the z-axis). + // compute the equivalent translation to apply *after* the scaling + // so that the scaling is done around the point which was clicked: CTX.t[0] = t[0] * (s[0] / CTX.s[0]) - wnr[0] * (1. - (s[0] / CTX.s[0])); CTX.t[1] = t[1] * (s[1] / CTX.s[1]) - wnr[1] * (1. - (s[1] / CTX.s[1])); - - /* - double sx, sy; - double tx0, ty0; - double tx, ty; - double model_new[16]; - - glPushMatrix(); - glLoadMatrix(CTX.model_init); - glTranslated(tx0, ty0, 0.); - glScaled(sx, sy, sz); - glTranslated(-tx0, -ty0, 0.); - glTranslated(tx, ty, 0.); - glGetDoublev(GL_MODELVIEW_MATRIX, model_new); - glPopMatrix(); - - CTX.s[0] = model_new[0][0]; - CTX.s[1] = model_new[1][1]; - CTX.s[2] = model_new[2][2]; - - CTX.t[0] = model_new[0][3]; - CTX.t[1] = model_new[1][3]; - CTX.t[2] = model_new[2][3]; - */ } -void myZoom(MousePosition &click1, MousePosition &click2) +void lasso_zoom(MousePosition &click1, MousePosition &click2) { if(click1.win[0] == click2.win[0] || click1.win[1] == click2.win[1]) return; @@ -99,6 +70,7 @@ void myZoom(MousePosition &click1, MousePosition &click2) CTX.s[1] *= (double)CTX.viewport[3] / (click2.win[1] - click1.win[1]); CTX.s[2] = MIN(CTX.s[0], CTX.s[1]); // bof... + // recenter around the center of the lasso rectangle MousePosition tmp(click1); tmp.wnr[0] = 0.5 * (click1.wnr[0] + click2.wnr[0]); tmp.wnr[1] = 0.5 * (click1.wnr[1] + click2.wnr[1]); @@ -210,7 +182,7 @@ int Opengl_Window::handle(int event) } else if(ZoomMode) { ZoomMode = false; - myZoom(click, curr); + lasso_zoom(click, curr); } else { WID->try_selection = 1; diff --git a/Fltk/Opengl_Window.h b/Fltk/Opengl_Window.h index 3e6f8e80a8a75aaa0b1cb5909846899a01a86f69..0525470918f629f9f3e98b999dbdb641a27ce63b 100644 --- a/Fltk/Opengl_Window.h +++ b/Fltk/Opengl_Window.h @@ -28,18 +28,16 @@ class MousePosition { public: double win[3]; // window coordinates double wnr[3]; // world coordinates BEFORE rotation - double world[3]; // world coordinates (in a given plane // to screen) double s[3]; // scaling state when the event was recorded double t[3]; // translation state when the event was recorded MousePosition(){ for(int i = 0; i < 3; i++) - win[i] = wnr[i] = world[i] = s[i] = t[i] = 0.; + win[i] = wnr[i] = s[i] = t[i] = 0.; } MousePosition(const MousePosition &instance){ for(int i = 0; i < 3; i++){ win[i] = instance.win[i]; wnr[i] = instance.wnr[i]; - world[i] = instance.world[i]; s[i] = instance.s[i]; t[i] = instance.t[i]; } diff --git a/Graphics/Draw.cpp b/Graphics/Draw.cpp index 00b5e2c71e3a8ea0da3a4ae45102f11caffbf627..186b73dcf27143bad79c6219cfb6da294ff534a5 100644 --- a/Graphics/Draw.cpp +++ b/Graphics/Draw.cpp @@ -1,4 +1,4 @@ -// $Id: Draw.cpp,v 1.84 2005-12-18 18:10:46 geuzaine Exp $ +// $Id: Draw.cpp,v 1.85 2005-12-18 21:10:54 geuzaine Exp $ // // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle // @@ -162,6 +162,9 @@ void InitProjection(int x, int y) CTX.pixel_equiv_x = (CTX.vxmax - CTX.vxmin) / (CTX.viewport[2] - CTX.viewport[0]); CTX.pixel_equiv_y = (CTX.vymax - CTX.vymin) / (CTX.viewport[3] - CTX.viewport[1]); + // no initial translation of the model + CTX.t_init[0] = CTX.t_init[1] = CTX.t_init[2] = 0.; + // setup ortho or perspective projection matrix glMatrixMode(GL_PROJECTION); glLoadIdentity(); @@ -192,21 +195,19 @@ void InitProjection(int x, int y) double near = 0.75 * CTX.clip_factor * CTX.lc; double far = 75. * CTX.clip_factor * CTX.lc; // recenter the model such that the perspective is always at the - // center of the screen. FIXME: this screws up the zoom, so let's - // leave it out for now - //double w = (CTX.max[0] - CTX.min[0]) / 2.; - //double h = (CTX.max[1] - CTX.min[1]) / 2.; - //CTX.vxmin -= w; - //CTX.vxmax -= w; - //CTX.vymin -= h; - //CTX.vymax -= h; - double w = 0.; - double h = 0.; + // center of gravity (we should maybe add an option to choose + // this, as we do for the rotation center) + CTX.t_init[0] = CTX.cg[0]; + CTX.t_init[1] = CTX.cg[1]; + CTX.vxmin -= CTX.t_init[0]; + CTX.vxmax -= CTX.t_init[0]; + CTX.vymin -= CTX.t_init[1]; + CTX.vymax -= CTX.t_init[1]; glFrustum(CTX.vxmin, CTX.vxmax, CTX.vymin, CTX.vymax, near, far); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - glTranslated(-5 * w, -5 * h, -5 * near); - glScaled(5., 5., 5.); + glTranslated(-10 * CTX.t_init[0], -10 * CTX.t_init[1], -10 * near); + glScaled(10., 10., 10.); gradient_zdist = 0.99 * far; gradient_xyfact = far / near; } @@ -301,11 +302,6 @@ void InitRenderModel(void) void InitPosition(void) { - // store the model transfo matrix before we position the object - // (this way we can isolate the scaling/translation/rotation) from - // any transformations made before to adjust the viewpoint - glGetDoublev(GL_MODELVIEW_MATRIX, CTX.model_init); - glScaled(CTX.s[0], CTX.s[1], CTX.s[2]); glTranslated(CTX.t[0], CTX.t[1], CTX.t[2]);