[GRASS-SVN] r47343 - in grass/trunk: gui/wxpython/gui_modules include lib/nviz lib/ogsf

svn_grass at osgeo.org svn_grass at osgeo.org
Tue Aug 2 02:42:11 EDT 2011


Author: annakrat
Date: 2011-08-01 23:42:11 -0700 (Mon, 01 Aug 2011)
New Revision: 47343

Modified:
   grass/trunk/gui/wxpython/gui_modules/nviz_mapdisp.py
   grass/trunk/gui/wxpython/gui_modules/toolbars.py
   grass/trunk/gui/wxpython/gui_modules/wxnviz.py
   grass/trunk/include/gstypes.h
   grass/trunk/include/nviz.h
   grass/trunk/include/ogsf_proto.h
   grass/trunk/lib/nviz/change_view.c
   grass/trunk/lib/ogsf/GS2.c
   grass/trunk/lib/ogsf/gsd_views.c
Log:
wxNviz: rotate 3D scene by mouse dragging

Modified: grass/trunk/gui/wxpython/gui_modules/nviz_mapdisp.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/nviz_mapdisp.py	2011-08-02 05:54:01 UTC (rev 47342)
+++ grass/trunk/gui/wxpython/gui_modules/nviz_mapdisp.py	2011-08-02 06:42:11 UTC (rev 47343)
@@ -111,7 +111,8 @@
         self.textdict = {}
         self.dragid = None
         self.hitradius = 5
-        
+        self.lastMouseVector = (0,0)
+        self.sumdxdy = [0, 0]
         if self.lmgr:
             self.log = self.lmgr.goutput
             logerr = self.lmgr.goutput.cmd_stderr
@@ -381,6 +382,7 @@
     def OnLeftDown(self, event):
         """!On left mouse down"""
         self.mouse['begin'] = event.GetPositionTuple()
+        self.mouse['tmp'] = event.GetPositionTuple()
         if self.mouse['use'] == "lookHere":
             pos = event.GetPosition()
             size = self.GetClientSize()
@@ -413,11 +415,13 @@
             pos = event.GetPosition()
             size = self.GetClientSize()
             self.SetDrawScalebar((pos[0], size[1] - pos[1]))
-            
+        
+        if self.mouse['use'] == 'pan':
+            pass
+                
         if self.mouse['use'] == 'pointer':
             # get decoration or text id
             self.dragid = None
-            self.mouse['tmp'] = self.mouse['begin']
             idlist = self.pdc.FindObjects(self.mouse['tmp'][0], self.mouse['tmp'][1],
                                           self.hitradius)                            
             if idlist != []:
@@ -434,10 +438,18 @@
             if x is not None: 
                 self.cplanes[idx]['position']['x'] = x
                 self.cplanes[idx]['position']['y'] = y 
-            
+                
         if self.mouse['use'] == 'pointer':
             self.DragItem(self.dragid, event)
-                
+            
+        if self.mouse['use'] == 'pan':    
+            dx, dy = event.GetX() - self.mouse['tmp'][0], event.GetY() - self.mouse['tmp'][1]
+            self.mouse['tmp'] = event.GetPositionTuple()
+            angle, x, y, z = self._display.GetRotationParameters(dx, dy)
+            self._display.Rotate(angle, x, y, z)
+            
+            self.render['quick'] = True
+            self.Refresh(False)
         event.Skip()
             
     def Pixel2Cell(self, (x, y)):
@@ -485,10 +497,15 @@
                 self.overlays[self.dragid]['coords'] = self.pdc.GetIdBounds(self.dragid)
             elif self.dragid > 100 and self.dragid in self.textdict:
                 self.textdict[self.dragid]['bbox'] = self.pdc.GetIdBounds(self.dragid)
-                
-            self.dragid = None
+            if self.dragid:    
+                self.dragid = None
+                self.Refresh(False)
+            
+        elif self.mouse['use'] == 'pan':
+            self._display.UnsetRotation()
+            self.render['quick'] = False
             self.Refresh(False)
-    
+            
     def OnDClick(self, event):
         """!On mouse double click"""
         if self.mouse['use'] != 'pointer': return
@@ -1264,7 +1281,7 @@
         
         self.view['twist']['value'] = UserSettings.Get(group = 'nviz', key = 'view',
                                                        subkey = ('twist', 'value'))
-                                                    
+        self._display.ResetRotation()
         self._display.LookAtCenter()
         focus = self.iview['focus']
         focus['x'], focus['y'], focus['z'] = self._display.GetFocus()

Modified: grass/trunk/gui/wxpython/gui_modules/toolbars.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/toolbars.py	2011-08-02 05:54:01 UTC (rev 47342)
+++ grass/trunk/gui/wxpython/gui_modules/toolbars.py	2011-08-02 06:42:11 UTC (rev 47343)
@@ -340,8 +340,7 @@
         
     def Enable2D(self, enabled):
         """!Enable/Disable 2D display mode specific tools"""
-        for tool in (self.pan,
-                     self.zoomin,
+        for tool in (self.zoomin,
                      self.zoomout,
                      self.zoomback,
                      self.zoommenu,

Modified: grass/trunk/gui/wxpython/gui_modules/wxnviz.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/wxnviz.py	2011-08-02 05:54:01 UTC (rev 47342)
+++ grass/trunk/gui/wxpython/gui_modules/wxnviz.py	2011-08-02 06:42:11 UTC (rev 47343)
@@ -22,6 +22,8 @@
 
 import sys
 from threading import Thread
+from math import sqrt
+from numpy import matrix
 
 from ctypes import *
 from grass.lib.gis   import *
@@ -1651,10 +1653,10 @@
         """
         return Nviz_set_scalebar(self.data, id, sx, sy, size, Nviz_color_from_str(color))
     
-##    def DrawScalebar(self):
-##        """!Draw scale bar
-##        """
-##        return Nviz_draw_scalebar(self.data)
+    def DrawScalebar(self):
+        """!Draw scale bar
+        """
+        return Nviz_draw_scalebar(self.data)
     
     def DeleteScalebar(self, id):
         """!Delete scalebar
@@ -1706,3 +1708,44 @@
                                   byref(d), int(useExag))
         
         return d.value
+
+    def GetRotationParameters(self, dx, dy):
+        """!Get rotation parameters (angle, x, y, z axes)
+        
+        @param dx,dy difference from previous mouse drag event
+        """
+        modelview = (c_double * 16)()
+        Nviz_get_modelview(byref(modelview))
+        
+        angle = sqrt(dx*dx+dy*dy)/float(self.width+1)*180.0
+        m = []
+        row = []
+        for i, item in enumerate(modelview):
+            row.append(item)
+            if (i+1) % 4 == 0:
+                m.append(row)
+                row = []
+        inv = matrix(m).I
+        ax, ay, az = dy, dx, 0.
+        x = inv[0,0]*ax + inv[1,0]*ay + inv[2,0]*az
+        y = inv[0,1]*ax + inv[1,1]*ay + inv[2,1]*az
+        z = inv[0,2]*ax + inv[1,2]*ay + inv[2,2]*az
+        
+        return angle, x, y, z 
+       
+    def Rotate(self, angle, x, y, z):
+        """!Set rotation parameters
+        Rotate scene (difference from current state).
+
+        @param angle angle
+        @param x,y,z axis coordinate
+        """
+        Nviz_set_rotation(angle, x, y, z)
+        
+    def UnsetRotation(self):
+        """!Stop rotating the scene"""
+        Nviz_unset_rotation()
+        
+    def ResetRotation(self):
+        """!Reset scene rotation"""
+        Nviz_init_rotation()

Modified: grass/trunk/include/gstypes.h
===================================================================
--- grass/trunk/include/gstypes.h	2011-08-02 05:54:01 UTC (rev 47342)
+++ grass/trunk/include/gstypes.h	2011-08-02 06:42:11 UTC (rev 47343)
@@ -362,12 +362,21 @@
     float shine;		/* 0. to 128. */
 };
 
+struct georot
+{
+    int do_rot;			/* do rotation */
+    double rot_angle;		/* rotation angle */
+    double rot_axes[3];		/* rotation axis */
+    GLdouble rotMatrix[16];	/* rotation matrix */
+};
+
 typedef struct
 {
     int coord_sys;		/* latlon, equal area, etc */
     int view_proj;		/* perspective, ortho */
     int infocus;		/* fixed center of view - true or false */
     float from_to[2][4];
+    struct georot rotate;
     int twist, fov, incl, look;	/* 10ths of degrees */
     float real_to[4], vert_exag;	/* a global Z exag */
     float scale;

Modified: grass/trunk/include/nviz.h
===================================================================
--- grass/trunk/include/nviz.h	2011-08-02 05:54:01 UTC (rev 47342)
+++ grass/trunk/include/nviz.h	2011-08-02 06:42:11 UTC (rev 47343)
@@ -153,6 +153,10 @@
 int Nviz_set_viewpoint_twist(int);
 int Nviz_change_exag(nv_data *, double);
 int Nviz_look_here(double, double);
+void Nviz_get_modelview(double *);
+void Nviz_set_rotation(double, double, double, double);
+void Nviz_unset_rotation(void);
+void Nviz_init_rotation(void);
 
 /* cplanes_obj.c */
 int Nviz_new_cplane(nv_data *, int);

Modified: grass/trunk/include/ogsf_proto.h
===================================================================
--- grass/trunk/include/ogsf_proto.h	2011-08-02 05:54:01 UTC (rev 47342)
+++ grass/trunk/include/ogsf_proto.h	2011-08-02 06:42:11 UTC (rev 47343)
@@ -168,6 +168,9 @@
 void GS_get_viewdir(float *);
 void GS_set_viewdir(float *);
 void GS_set_fov(int);
+void GS_set_rotation(double, double, double, double);
+void GS_init_rotation(void);
+void GS_unset_rotation(void);
 int GS_get_fov(void);
 int GS_get_twist(void);
 void GS_set_twist(int);
@@ -587,6 +590,7 @@
 void gsd_real2model(Point3);
 void gsd_model2real(Point3);
 void gsd_model2surf(geosurf *, Point3);
+void gsd_surf2model(Point3);
 void gsd_surf2real(geosurf *, Point3);
 void gsd_real2surf(geosurf *, Point3);
 

Modified: grass/trunk/lib/nviz/change_view.c
===================================================================
--- grass/trunk/lib/nviz/change_view.c	2011-08-02 05:54:01 UTC (rev 47342)
+++ grass/trunk/lib/nviz/change_view.c	2011-08-02 06:42:11 UTC (rev 47343)
@@ -235,4 +235,43 @@
      return 1;
 }
 
+/*!
+  \brief Get current modelview matrix
+*/
+void Nviz_get_modelview(double *modelMatrix)
+{
+    glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);
+}
 
+/*!
+  \brief Set rotation parameters
+
+  Rotate scene by given parameters related to mouse drag event
+  (difference from current state).
+  Coordinates determine the second point of rotation axis,
+  the first point is (0, 0, 0).
+
+  \param angle angle
+  \param x,y,z axis coordinate
+*/
+void Nviz_set_rotation(double angle, double x, double y, double z)
+{
+    G_debug(3, "Nviz_set_rotation(): angle = %f, x = %f, y = %f, z = %f", angle, x, y, z); 
+    GS_set_rotation(angle, x, y, z);
+}
+
+/*!
+  \brief Stop scene rotation
+*/
+void Nviz_unset_rotation(void)
+{
+    GS_unset_rotation();
+}
+
+/*!
+  \brief Stop scene rotation
+*/
+void Nviz_init_rotation(void)
+{
+    GS_init_rotation();
+}

Modified: grass/trunk/lib/ogsf/GS2.c
===================================================================
--- grass/trunk/lib/ogsf/GS2.c	2011-08-02 05:54:01 UTC (rev 47342)
+++ grass/trunk/lib/ogsf/GS2.c	2011-08-02 06:42:11 UTC (rev 47343)
@@ -2878,6 +2878,48 @@
 }
 
 /*!
+   \brief Set rotation params
+ */
+void GS_set_rotation(double angle, double x, double y, double z)
+{
+    Gv.rotate.rot_angle = angle;
+    Gv.rotate.rot_axes[0] = x;
+    Gv.rotate.rot_axes[1] = y;
+    Gv.rotate.rot_axes[2] = z;
+    Gv.rotate.do_rot = 1;
+
+    return;
+}
+
+/*!
+   \brief Stop scene rotation
+ */
+void GS_unset_rotation(void)
+{
+    Gv.rotate.do_rot = 0;
+}
+
+/*!
+   \brief Reset scene rotation
+ */
+void GS_init_rotation(void)
+{
+    int i;
+
+    for (i = 0; i < 16; i++) {
+	if (i == 0 || i == 5 || i == 10 || i == 15)
+	    Gv.rotate.rotMatrix[i] = 1.0;
+	else
+	    Gv.rotate.rotMatrix[i] = 0.0;
+    }
+    Gv.rotate.rot_angle = 0.0;
+    Gv.rotate.rot_axes[0] = 0.0;
+    Gv.rotate.rot_axes[1] = 0.0;
+    Gv.rotate.rot_axes[2] = 0.0;
+    Gv.rotate.do_rot = 0;
+    
+}
+/*!
    \brief Unset focus
  */
 void GS_set_nofocus(void)
@@ -3276,6 +3318,7 @@
  */
 void GS_init_view(void)
 {
+    int i;
     static int first = 1;
 
     G_debug(3, "GS_init_view");
@@ -3309,6 +3352,9 @@
 	/* replace these with something meaningful */
 	Gv.fov = 450;
 	Gv.twist = 0;
+
+	GS_init_rotation();
+
 	Gv.from_to[FROM][X] = Gv.from_to[FROM][Y] =
 	    Gv.from_to[FROM][Z] = GS_UNIT_SIZE / 2.;
 

Modified: grass/trunk/lib/ogsf/gsd_views.c
===================================================================
--- grass/trunk/lib/ogsf/gsd_views.c	2011-08-02 05:54:01 UTC (rev 47342)
+++ grass/trunk/lib/ogsf/gsd_views.c	2011-08-02 06:42:11 UTC (rev 47343)
@@ -88,7 +88,7 @@
     return (1);
 }
 
-
+#if 0
 /*!
    \brief Set view
 
@@ -134,7 +134,79 @@
 
     return;
 }
+#endif
+/*!
+   \brief Set view
 
+   Establishes viewing & projection matrices
+
+   \param gv view (geoview)
+   \param dp display (geodisplay)
+ */
+void gsd_set_view(geoview * gv, geodisplay * gd)
+{
+    double up[3];
+    float pos[3];
+    int i;
+    GLdouble modelMatrix[16];
+    GLint mm;
+
+    /* will expand when need to check for in focus, ortho, etc. */
+
+    gsd_check_focus(gv);
+    gsd_get_zup(gv, up);
+
+    gd->aspect = GS_get_aspect();
+
+    glGetIntegerv(GL_MATRIX_MODE, &mm);
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    gluPerspective((double).1 * (gv->fov), (double)gd->aspect,
+		   (double)gd->nearclip, (double)gd->farclip);
+
+    glMatrixMode(mm);
+    
+    glLoadIdentity();
+
+    /* update twist parm */
+    glRotatef((float)(gv->twist / 10.), 0.0, 0.0, 1.0);
+
+    /* OGLXXX lookat: replace UPx with vector */
+    gluLookAt((double)gv->from_to[FROM][X], (double)gv->from_to[FROM][Y],
+	      (double)gv->from_to[FROM][Z], (double)gv->from_to[TO][X],
+	      (double)gv->from_to[TO][Y], (double)gv->from_to[TO][Z],
+	      (double)up[X], (double)up[Y], (double)up[Z]);
+	      
+    /* rotate to get rotation matrix and then save it*/
+    if (gv->rotate.do_rot) {
+
+	glPushMatrix();
+	glLoadMatrixd(gv->rotate.rotMatrix);
+
+	glRotated(gv->rotate.rot_angle, gv->rotate.rot_axes[0], 
+		  gv->rotate.rot_axes[1], gv->rotate.rot_axes[2]);
+	glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);
+
+	for (i = 0; i < 16; i++) {
+	    gv->rotate.rotMatrix[i] = modelMatrix[i];
+	}
+
+	glPopMatrix();
+    }
+    
+    gs_get_datacenter(pos);
+    gsd_surf2model(pos);
+    /* translate rotation center to view center, rotate and translate back */
+    glTranslatef(pos[0], pos[1], pos[2]);
+    glMultMatrixd(gv->rotate.rotMatrix);
+    glTranslatef(-pos[0], -pos[1], -pos[2]);
+
+    /* have to redefine clipping planes when view changes */
+
+    gsd_update_cplanes();
+
+    return;
+}
 /*!
    \brief Check focus
 
@@ -361,7 +433,28 @@
 
     return;
 }
+/*!
+   \brief Convert surface to model coordinates
 
+   \param point 3d point (Point3)
+ */
+void gsd_surf2model(Point3 point)
+{
+    float min, max, sx, sy, sz;
+
+    /* need to undo z scaling & translate */
+    GS_get_scale(&sx, &sy, &sz, 1);
+    GS_get_zrange(&min, &max, 0);
+
+    point[Z] = (sz ? (point[Z] - min) * sz : 0.0);
+
+    /* need to unscale x & y */
+    point[X] = (sx ? point[X] * sx : 0.0);
+    point[Y] = (sy ? point[Y] * sy : 0.0);
+
+
+    return;
+}
 /*!
    \brief Convert surface to real coordinates
 



More information about the grass-commit mailing list