From 3ae0ca8c1981e6e909ea6ccc2677bcb8d6b264ac Mon Sep 17 00:00:00 2001 From: Jonathan Westhues Date: Thu, 1 Jan 2009 20:06:47 -0800 Subject: [PATCH] Add menu items to snap view to nearest orthogonal or iso view. [git-p4: depot-paths = "//depot/solvespace/": change = 1882] --- graphicswin.cpp | 65 ++++++++++++++++++++++++++++++++++++++++++++++- ui.h | 3 +++ win32/w32main.cpp | 13 ++++++++++ 3 files changed, 80 insertions(+), 1 deletion(-) diff --git a/graphicswin.cpp b/graphicswin.cpp index c2ca0c7..49db02c 100644 --- a/graphicswin.cpp +++ b/graphicswin.cpp @@ -10,6 +10,7 @@ #define mHelp (&SolveSpace::MenuHelp) #define S 0x100 #define C 0x200 +#define F(k) (0xf0+(k)) const GraphicsWindow::MenuEntry GraphicsWindow::menu[] = { { 0, "&File", 0, NULL }, { 1, "&New\tCtrl+N", MNU_NEW, 'N'|C, mFile }, @@ -38,6 +39,9 @@ const GraphicsWindow::MenuEntry GraphicsWindow::menu[] = { { 1, "Zoom &Out\t-", MNU_ZOOM_OUT, '-', mView }, { 1, "Zoom To &Fit\tF", MNU_ZOOM_TO_FIT, 'F', mView }, { 1, NULL, 0, NULL }, +{ 1, "Nearest &Ortho View\tF1", MNU_NEAREST_ORTHO, F(1), mView }, +{ 1, "Nearest &Iso View\tF2", MNU_NEAREST_ISO, F(2), mView }, +{ 1, NULL, 0, NULL }, { 1, "Show Text &Window\tTab", MNU_SHOW_TEXT_WND, '\t', mView }, { 1, NULL, 0, NULL }, { 1, "Dimensions in &Inches", MNU_UNITS_INCHES, 0, mView }, @@ -185,13 +189,17 @@ Vector GraphicsWindow::ProjectPoint4(Vector p, double *w) { return r; } -void GraphicsWindow::AnimateOntoWorkplane(void) { +void GraphicsWindow::AnimateOntoWorkplane(void) { if(!LockedInWorkplane()) return; Entity *w = SS.GetEntity(ActiveWorkplane()); Quaternion quatf = w->Normal()->NormalGetNum(); Vector offsetf = (SS.GetEntity(w->point[0])->PointGetNum()).ScaledBy(-1); + AnimateOnto(quatf, offsetf); +} + +void GraphicsWindow::AnimateOnto(Quaternion quatf, Vector offsetf) { // Get our initial orientation and translation. Quaternion quat0 = Quaternion::From(projRight, projUp); Vector offset0 = offset; @@ -327,6 +335,61 @@ void GraphicsWindow::MenuView(int id) { SS.GW.ZoomToFit(); break; + case MNU_NEAREST_ORTHO: + case MNU_NEAREST_ISO: { + static const Vector ortho[3] = { + Vector::From(1, 0, 0), + Vector::From(0, 1, 0), + Vector::From(0, 0, 1) + }; + double sqrt2 = sqrt(2.0), sqrt6 = sqrt(6.0); + Quaternion quat0 = Quaternion::From(SS.GW.projRight, SS.GW.projUp); + Quaternion quatf = quat0; + double dmin = 1e10; + + // There are 24 possible views; 3*2*2*2 + int i, j, negi, negj; + for(i = 0; i < 3; i++) { + for(j = 0; j < 3; j++) { + if(i == j) continue; + for(negi = 0; negi < 2; negi++) { + for(negj = 0; negj < 2; negj++) { + Vector ou = ortho[i], ov = ortho[j]; + if(negi) ou = ou.ScaledBy(-1); + if(negj) ov = ov.ScaledBy(-1); + Vector on = ou.Cross(ov); + + Vector u, v; + if(id == MNU_NEAREST_ORTHO) { + u = ou; + v = ov; + } else { + u = + ou.ScaledBy(1/sqrt2).Plus( + on.ScaledBy(-1/sqrt2)); + v = + ou.ScaledBy(-1/sqrt6).Plus( + ov.ScaledBy(2/sqrt6).Plus( + on.ScaledBy(-1/sqrt6))); + } + + Quaternion quatt = Quaternion::From(u, v); + double d = min( + (quatt.Minus(quat0)).Magnitude(), + (quatt.Plus(quat0)).Magnitude()); + if(d < dmin) { + dmin = d; + quatf = quatt; + } + } + } + } + } + + SS.GW.AnimateOnto(quatf, SS.GW.offset); + break; + } + case MNU_SHOW_TEXT_WND: SS.GW.showTextWindow = !SS.GW.showTextWindow; SS.GW.EnsureValidActives(); diff --git a/ui.h b/ui.h index 261cbec..157b94f 100644 --- a/ui.h +++ b/ui.h @@ -184,6 +184,8 @@ public: MNU_ZOOM_IN, MNU_ZOOM_OUT, MNU_ZOOM_TO_FIT, + MNU_NEAREST_ORTHO, + MNU_NEAREST_ISO, MNU_SHOW_TEXT_WND, MNU_UNITS_INCHES, MNU_UNITS_MM, @@ -280,6 +282,7 @@ public: Point2d ProjectPoint(Vector p); Vector ProjectPoint3(Vector p); Vector ProjectPoint4(Vector p, double *w); + void AnimateOnto(Quaternion quatf, Vector offsetf); void AnimateOntoWorkplane(void); Vector VectorFromProjs(Vector rightUpForward); void HandlePointForZoomToFit(Vector p, Point2d *pmax, Point2d *pmin, diff --git a/win32/w32main.cpp b/win32/w32main.cpp index b1f751c..b997bdd 100644 --- a/win32/w32main.cpp +++ b/win32/w32main.cpp @@ -527,6 +527,19 @@ static BOOL ProcessKeyDown(WPARAM wParam) case VK_DELETE: c = 127; break; case VK_TAB: c = '\t'; break; + case VK_F1: + case VK_F2: + case VK_F3: + case VK_F4: + case VK_F5: + case VK_F6: + case VK_F7: + case VK_F8: + case VK_F9: + case VK_F10: + case VK_F11: + case VK_F12: c = (wParam - VK_F1) + 0xf1; break; + // These overlap with some character codes that I'm using, so // don't let them trigger by accident. case VK_F16: