[GRASS-SVN] r49357 - in grass/branches/develbranch_6:
gui/icons/grass2 gui/wxpython gui/wxpython/docs
gui/wxpython/gui_modules gui/wxpython/icons include lib/nviz
lib/ogsf misc/m.nviz.image
svn_grass at osgeo.org
svn_grass at osgeo.org
Fri Nov 25 10:10:47 EST 2011
Author: annakrat
Date: 2011-11-25 07:10:47 -0800 (Fri, 25 Nov 2011)
New Revision: 49357
Added:
grass/branches/develbranch_6/gui/icons/grass2/3d-help.png
grass/branches/develbranch_6/gui/icons/grass2/3d-rotate.png
grass/branches/develbranch_6/gui/icons/grass2/3d-settings.png
grass/branches/develbranch_6/gui/wxpython/docs/wxGUI_nviz_tools_light.jpg
grass/branches/develbranch_6/gui/wxpython/gui_modules/nviz_animation.py
grass/branches/develbranch_6/misc/m.nviz.image/cplane.c
Modified:
grass/branches/develbranch_6/gui/wxpython/docs/wxGUI.Nviz.html
grass/branches/develbranch_6/gui/wxpython/docs/wxGUI_nviz_toolbar.jpg
grass/branches/develbranch_6/gui/wxpython/docs/wxGUI_nviz_tools_surface.jpg
grass/branches/develbranch_6/gui/wxpython/docs/wxGUI_nviz_tools_vector.jpg
grass/branches/develbranch_6/gui/wxpython/docs/wxGUI_nviz_tools_view.jpg
grass/branches/develbranch_6/gui/wxpython/docs/wxGUI_nviz_tools_volume.jpg
grass/branches/develbranch_6/gui/wxpython/gui_modules/colorrules.py
grass/branches/develbranch_6/gui/wxpython/gui_modules/gdialogs.py
grass/branches/develbranch_6/gui/wxpython/gui_modules/gselect.py
grass/branches/develbranch_6/gui/wxpython/gui_modules/layertree.py
grass/branches/develbranch_6/gui/wxpython/gui_modules/mapdisp.py
grass/branches/develbranch_6/gui/wxpython/gui_modules/mapdisp_window.py
grass/branches/develbranch_6/gui/wxpython/gui_modules/menuform.py
grass/branches/develbranch_6/gui/wxpython/gui_modules/nviz.py
grass/branches/develbranch_6/gui/wxpython/gui_modules/nviz_mapdisp.py
grass/branches/develbranch_6/gui/wxpython/gui_modules/nviz_preferences.py
grass/branches/develbranch_6/gui/wxpython/gui_modules/nviz_tools.py
grass/branches/develbranch_6/gui/wxpython/gui_modules/preferences.py
grass/branches/develbranch_6/gui/wxpython/gui_modules/render.py
grass/branches/develbranch_6/gui/wxpython/gui_modules/toolbars.py
grass/branches/develbranch_6/gui/wxpython/gui_modules/workspace.py
grass/branches/develbranch_6/gui/wxpython/gui_modules/wxnviz.py
grass/branches/develbranch_6/gui/wxpython/icons/icon.py
grass/branches/develbranch_6/gui/wxpython/wxgui.py
grass/branches/develbranch_6/include/gstypes.h
grass/branches/develbranch_6/include/nviz.h
grass/branches/develbranch_6/include/ogsf_proto.h
grass/branches/develbranch_6/lib/nviz/change_view.c
grass/branches/develbranch_6/lib/nviz/cplanes_obj.c
grass/branches/develbranch_6/lib/nviz/draw.c
grass/branches/develbranch_6/lib/nviz/lights.c
grass/branches/develbranch_6/lib/nviz/nviz.c
grass/branches/develbranch_6/lib/nviz/position.c
grass/branches/develbranch_6/lib/ogsf/GS2.c
grass/branches/develbranch_6/lib/ogsf/Gp3.c
grass/branches/develbranch_6/lib/ogsf/gs.c
grass/branches/develbranch_6/lib/ogsf/gsd_objs.c
grass/branches/develbranch_6/lib/ogsf/gsd_views.c
grass/branches/develbranch_6/misc/m.nviz.image/args.c
grass/branches/develbranch_6/misc/m.nviz.image/description.html
grass/branches/develbranch_6/misc/m.nviz.image/local_proto.h
grass/branches/develbranch_6/misc/m.nviz.image/main.c
grass/branches/develbranch_6/misc/m.nviz.image/surface.c
grass/branches/develbranch_6/misc/m.nviz.image/vector.c
grass/branches/develbranch_6/misc/m.nviz.image/volume.c
Log:
wxNviz backported from trunk
Added: grass/branches/develbranch_6/gui/icons/grass2/3d-help.png
===================================================================
(Binary files differ)
Property changes on: grass/branches/develbranch_6/gui/icons/grass2/3d-help.png
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: grass/branches/develbranch_6/gui/icons/grass2/3d-rotate.png
===================================================================
(Binary files differ)
Property changes on: grass/branches/develbranch_6/gui/icons/grass2/3d-rotate.png
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: grass/branches/develbranch_6/gui/icons/grass2/3d-settings.png
===================================================================
(Binary files differ)
Property changes on: grass/branches/develbranch_6/gui/icons/grass2/3d-settings.png
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Modified: grass/branches/develbranch_6/gui/wxpython/docs/wxGUI.Nviz.html
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/docs/wxGUI.Nviz.html 2011-11-25 14:58:21 UTC (rev 49356)
+++ grass/branches/develbranch_6/gui/wxpython/docs/wxGUI.Nviz.html 2011-11-25 15:10:47 UTC (rev 49357)
@@ -13,7 +13,8 @@
<p>
To start the wxGUI 3D view mode, choose '3D view' from the map
-toolbar.
+toolbar. You can switch between 2D and 3D view. The region in
+3D view is updated according to displayed region in 2D view.
<p>
wxNviz is emphasized on the ease and speed of viewer positioning and
provided flexibility for using a wide range of data. A low resolution
@@ -38,30 +39,9 @@
</center>
<dl>
- <dt><img src="icons/3d-view.png">
- <em>Switch to view page</em></dt>
- <dd>Switch 3D Layer Manager Toolbox's page to the <b>view</b>
- control page.</dd>
- <dt><img src="icons/3d-raster.png">
- <em>Switch to surface page</em></dt>
- <dd>Switch 3D Layer Manager Toolbox's page to the <b>surface</b>
- control page (data properties).</dd>
- <dt><img src="icons/3d-vector.png">
- <em>Switch to vector page</em></dt>
- <dd>Switch 3D Layer Manager Toolbox's page to the <b>vector</b>
- control page (data properties).</dd>
- <dt><img src="icons/3d-volume.png">
- <em>Switch to volume page</em></dt>
- <dd>Switch 3D Layer Manager Toolbox's page to the <b>volume</b>
- control page (data properties).</dd>
- <dt><img src="icons/3d-light.png">
- <em>Switch to light page</em></dt>
- <dd>Switch 3D Layer Manager Toolbox's page to the <b>light</b>
- control page (appearance).</dd>
- <dt><img src="icons/3d-fringe.png">
- <em>Switch to fringe page</em></dt>
- <dd>Switch 3D Layer Manager Toolbox's page to the <b>fringe</b>
- control page (appearance).</dd>
+ <dt><img src="icons/script-save.png">
+ <em>Generate command for m.nviz.image</em></dt>
+ <dd>Generate command for m.nviz.image based on current state.</dd>
<dt><img src="icons/settings.png">
<em>Show 3D view mode settings</em></dt>
<dd>Show dialog with settings for wxGUI 3D view mode. The user
@@ -69,10 +49,6 @@
<dt><img src="icons/help.png">
<em>Show help</em></dt>
<dd>Show this help.</dd>
- <dt><img src="icons/quit.png">
- <em>Quit</em></dt>
- <dd>Quit 3D view mode and switch map display to the 2D view
- mode.</dd>
</dl>
<h2>3D View Layer Manager Toolbox</h2>
@@ -81,9 +57,11 @@
has several tabs:
<ul>
- <li><b>View</b> for view controling,</li>
+ <li><b>View</b> for view controlling,</li>
<li><b>Data</b> for data properties,</li>
<li><b>Appearance</b> for appearance settings (lighting, fringes, ...).</li>
+ <li><b>Analysis</b> for various data analyses (only cutting planes so far).</li>
+ <li><b>Animation</b> for creating simple animations.</li>
</ul>
<h3>View</h3>
@@ -92,15 +70,26 @@
perspective</em> of the view. The position box shows a puck with a
direction line pointing to the center. The direction line indicates
the look direction (azimuth). You click and drag the puck to change
- the current eye position. The box annotations are North, South,
- East, and West. You can also set exact position using <em>Look
- at</em> choice control.
+ the current eye position. Another way to change eye position is
+ to press the buttons around the position box representing cardinal
+ and ordinal directions.
+
+<p>
+There are four other buttons for view control in the bottom of this panel
+(following label <em>Look:</em>):
+<ul>
+ <li><em>here</em> requires you to click on Map Display Window to determine
+ the point to look at.</li>
+ <li><em>center</em> changes the point you are looking at to the center.</li>
+ <li><em>top</em> moves the current eye position above the map center.</li>
+ <li><em>reset</em> returns all current view settings to their default values.</li>
+</ul>
<center>
<br><img src="wxGUI_nviz_tools_view.jpg" border="1"><br><br>
</center>
-You can adjust the viewer's height above the scene, angle of view or
+You can adjust the viewer's height above the scene, perspective and
twist value to rotate the scene about the horizontal axis. An angle of
0 is flat. The scene rotates between -90 and 90 degrees.
@@ -109,43 +98,35 @@
example, if the easting and northing are in meters and the elevation
in feet, a vertical exaggeration of 0.305 would produce a true
(unexaggerated) surface.
-
<p>
-<em>Reset</em> returns all current settings to their default values.
+View parameters can be controlled by sliders or edited directly in text box.
+It's possible to enter values which are out of slider's range (and it will
+adjust then).
-<h3>Data properties - Surface</h3>
+<h4>Fly-through mode</h4>
+View can be changed in fly-through mode (can be activated in Map Display toolbar),
+which enables to change the view smoothly and therefore it is suitable
+for creating animation (see below). To start flying, press left mouse button
+and hold it down to continue flying. Flight direction is controlled by mouse cursor
+position on screen. Flight speed can be increased/decreased stepwise by keys
+PageUp/PageDown, Home/End or Up/Down arrows.
+Speed is increased multiple times while Shift key is held down. Holding down
+Ctrl key switches flight mode in the way that position of viewpoint is
+changed (not the direction).
-Each active raster map layer from the current layer tree is displayed
-as surface in the 3D space. Separate raster data or constants can be
-used for various attributes of the surface:
+<h3>Data properties</h3>
+This tab allows to control parameters related to map layers. It consists
+of four collapsible panels - <em>Surface</em>, <em>Constant surface</em>,
+<em>Vector</em> and <em>Volume</em>.
-<ul>
- <li><b>topography</b> - raster map or constant values used as elevation (z
- values) for the current surface.</li>
- <li><b>color</b> - raster map or constant color to drape over the current
- surface. This option is useful for draping imagery such as aerial
- photography over a DEM.</li>
- <li><b>mask</b> - raster map that controls the areas displayed from
- the current surface.</li>
- <li><b>transparency</b> - raster map or constant value that controls
- the transparency of the current surface. The default is completely
- opaque. Range from 0 (opaque) to 255 (transparent).</li>
- <li><b>shininess</b> - raster map or constant value that controls
- the shininess (reflectivity) of the current surface. Range from 0 to
- 255.</li>
- <li><b>emission</b> - raster map or constant value that controls the
- light emitted from the current surface. Range from 0 to 255.</li>
-</ul>
+<h4>Surface</h4>
-This panel controls how loaded surfaces are drawn. The top half of the
-panel has options to set, unset or modify attributes of the current
-surface. The bottom half has drawing style options, masking or
-changing surface position in the space.
-
-<center>
- <br><img src="wxGUI_nviz_tools_surface.jpg" border="1"><br><br>
-</center>
-
+Each active raster map layer from the current layer tree is displayed
+as surface in the 3D space. This panel controls how loaded surfaces are drawn.
+To change parameters of a surface, it must be selected in the very top part of the
+panel.
+<p>
+The top half of the panel has drawing style options.
Surface can be drawn as a wire mesh or using filled polygons (most
realistic). You can set draw <b>mode</b> to <em>coarse</em> (fast
display mode), <em>fine</em> (draws surface as filled polygons with
@@ -170,10 +151,43 @@
cells. The surface appears faceted.
<p>
-To set given draw settings for all loaded surfaces press button "All".
+To set given draw settings for all loaded surfaces press button "Set to all".
-<h3>Data properties - Vector</h3>
+<p>
+The bottom half of the panel has options to set, unset or modify attributes
+of the current surface. Separate raster data or constants can be
+used for various attributes of the surface:
+<ul>
+ <li><b>color</b> - raster map or constant color to drape over the current
+ surface. This option is useful for draping imagery such as aerial
+ photography over a DEM.</li>
+ <li><b>mask</b> - raster map that controls the areas displayed from
+ the current surface.</li>
+ <li><b>transparency</b> - raster map or constant value that controls
+ the transparency of the current surface. The default is completely
+ opaque. Range from 0 (opaque) to 100 (transparent).</li>
+ <li><b>shininess</b> - raster map or constant value that controls
+ the shininess (reflectivity) of the current surface. Range from 0 to
+ 100.</li>
+</ul>
+<p>
+In the very bottom part of the panel position of surface can be set.
+To move the surface right (looking from the south) choose <em>X</em> axis
+and set some positive value. To reset the surface position press
+<em>Reset</em> button.
+
+<center>
+ <br><img src="wxGUI_nviz_tools_surface.jpg" border="1"><br><br>
+</center>
+
+<h4>Constant surface</h4>
+It is possible to add constant surface and set its properties like
+fine resolution, value (height), color and transparency. It behaves
+similarly to surface but it has less options.
+
+<h4>Vector</h4>
+
2D vector data can be draped on the selected surfaces with various
markers to represent point data; you can use attribute of vector
features to determine size, color, shape of glyph.
@@ -186,14 +200,12 @@
You can define the width (in pixels) of the line features, the color
used for lines or point markers.
-<center>
- <br><img src="wxGUI_nviz_tools_vector.jpg" border="1"><br><br>
-</center>
-
+<p>
If vector map is 2D you can display vector features as flat at a
specified elevation or drape it over a surface(s) at a specified
height. Use the height control to set the flat elevation or the drape
-height above the surface(s).
+height above the surface(s). In case of multiple surfaces it is possible
+to specify which surfaces is the vector map draped over.
<p>
For display purposes, it is better to set the height slightly above
@@ -201,10 +213,10 @@
disappear into the surface(s).
<p>
-For 2D/3D vector points you can also set the size of the markers and
-the width (in pixels) of the line used to draw the point markers (only
-applies to wire-frame markers). Currently are implemented these
-markers:
+For 2D/3D vector points you can also set the size of the markers.
+<!-- and the width (in pixels) of the line used to draw the point markers (only
+applies to wire-frame markers). -->
+ Currently are implemented these markers:
<ul>
<li><b>x</b> sets the current points markers to a 2D "X",</li>
@@ -216,14 +228,40 @@
<li><b>asterisk</b> - 3D line-star.</li>
</ul>
-<h3>Data properties - Volume</h3>
+<p>
+Thematic mapping can be used to determine marker color and size
+(and line color and width).
-Volumes can be displayed either as isosurfaces or slices. Various
-attributes of the isosurface can be defined, similarly to surface
+<center>
+ <br><img src="wxGUI_nviz_tools_vector.jpg" border="1"><br><br>
+</center>
+
+<h4>Volume</h4>
+
+Volumes (3D raster maps) can be displayed either as isosurfaces or slices.
+Similarly to surface panel you can define draw <b>shading</b>
+- <em>gouraud</em> (draws the volumes with a smooth shading to blend
+individual cell colors together) and <em>flat</em> (draws the volumes
+with flat shading with one color for every two cells. The volume
+appears faceted). As mentioned above currently are supported two
+visualization modes:
+
+<ul>
+ <li><b>isosurface</b> - the levels of values for drawing the
+ volume(s) as isosurfaces,</li>
+ <li>and <b>slice</b> - drawing the volume
+ as cross-sections.</li>
+</ul>
+<p>
+The middle part of the panel has controls to add, delete, move up/down selected
+isosurface or slice. The bottom part differs for isosurface and slice.
+When choosing isosurface, this part the of panel has options to set, unset
+or modify attributes of the current isosurface.
+Various attributes of the isosurface can be defined, similarly to surface
attributes:
<ul>
- <li><b>level</b> - reference isosurface level (height in map
+ <li><b>isosurface value</b> - reference isosurface value (height in map
units).</li>
<li><b>color</b> - raster map or constant color to drape over the
current volume.</li>
@@ -231,40 +269,79 @@
the current volume.</li>
<li><b>transparency</b> - raster map or constant value that controls
the transparency of the current volume. The default is completely
- opaque. Range from 0 (opaque) to 255 (transparent).</li>
+ opaque. Range from 0 (opaque) to 100 (transparent).</li>
<li><b>shininess</b> - raster map or constant value that controls
the shininess (reflectivity) of the current volume. Range from 0 to
- 255.</li>
- <li><b>emission</b> - raster map or constant value that controls the
- light emitted from the current volume. Range from 0 to 255.</li>
+ 100.</li>
</ul>
+In case of volume slice the bottom part of the panel controls the slice
+attributes (which axis is slice parallel to, position of slice edges,
+transparency). Press button <em>Reset</em> to reset slice position
+attributes.
<p>
-This panel controls how loaded volumes are drawn. Volume can be drawn
-in two different modes: <b>isosurface</b> or <b>slice</b>. The top
-part of the panel has drawing style options. The middle part has
-controls to add, delete, move up/down selected isosurface or
-slices. The bottom part has options to set, unset or modify attributes
-of the current isosurface or slice.
+Volumes can be moved the same way like surfaces do.
<center>
<br><img src="wxGUI_nviz_tools_volume.jpg" border="1"><br><br>
</center>
-Similarly to surface panel you can define draw <b>shading</b>
-- <em>gouraud</em> (draws the volumes with a smooth shading to blend
-individual cell colors together) and <em>flat</em> (draws the volumes
-with flat shading with one color for every two cells. The volume
-appears faceted). As mentioned above currently are supported two
-visualization modes:
+<h3>Analysis</h3>
+<em>Analysis</em> tab contains <em>Cutting planes</em> panel.
+<h4>Cutting planes</h4>
+Cutting planes allow to cut surfaces along a plane. You can switch
+between six planes; to disable cutting planes switch to <em>None</em>.
+Initially the plane is vertical, you can change it to horizontal by setting
+<em>tilt</em> 90 degrees. The <em>X</em> and <em>Y</em> values specify
+the rotation center of plane. You can see better what <em>X</em> and <em>Y</em>
+do when changing <em>rotation</em>.
+<em>Height</em> parameter has sense only when changing
+<em>tilt</em> too. Press button <em>Reset</em> to reset current cutting plane.
+<p>
+In case of multiple surfaces you can visualize the cutting plane by
+<em>Shading</em>. Shading is visible only when more than one surface
+is loaded and these surfaces must have the same fine resolution set.
+
+
+
+<h3>Appearance</h3>
+Appearance tab consists of three collapsible panels:
+
<ul>
- <li><b>isosurface</b> - the levels of values for drawing the
- volume(s) as isosurfaces,</li>
- <li>and <b>slice</b> - the levels of values for drawing the volume
- as cross-sections.</li>
+ <li><em>Lighting</em> for adjusting light source</li>
+ <li><em>Fringe</em> for drawing fringes
+ <li><em>Decorations</em> to display north arrow and scale bar</li>
</ul>
+<p>
+The <em>lighting</em> panel enables to change the position of light
+source, light color, brightness and ambient. Light position is controlled
+similarly to eye position. If option <em>Show light model</em> is enabled
+light model is displayed to visualize the light settings.
+<center>
+ <br><img src="wxGUI_nviz_tools_light.jpg" border="1"><br><br>
+</center>
+<p>
+The <em>Fringe</em> panel allows to draw fringes in different directions
+(North & East, South & East, South & West, North & West). It is possible
+to set fringe color and height of the bottom edge.
+<p>
+The <em>Decorations</em> panel enables to display north arrow and simple
+scale bar. North arrow and scale bar length is determined in map units.
+You can display more than one scale bar.
+
+<h3>Animation</h3>
+Animation panel enables to create a simple animation as a sequence of images.
+Press 'Record' button and start changing the view. Views are
+recorded in given interval (FPS - Frames Per Second). After recording,
+the animation can be replayed. To save the animation, fill in the
+directory and file prefix, choose image format (PPM or TIF) and then
+press 'Save'. Now wait until the last image is generated.
+
+It is recommended to record animations using fly-through mode to achieve
+smooth motion.
+
<h2>Settings</h2>
This panel has controls which allows user to set default surface,
@@ -276,15 +353,9 @@
<h2>To be implement</h2>
<ul>
- <li>Improve intuitive navigation (mouse, fly mode)</li>
- <li>Animation capabilities</li>
- <li>Arbitrary cutting planes</li>
- <li>Labels, decoration, etc.</li>
- <li>Scripting capabilities</li>
- <li>Better workspace support (view settings, lighting)
+ <li>Labels, decoration, etc. (Implemented, but not fully functional)</li>
<li>Surface - mask by zero/elevation, more interactive positioning</li>
<li>Vector points - implement display mode flat/surface for 2D points</li>
- <li>Volume - slice draw mode</li>
<li>...</li>
</ul>
Modified: grass/branches/develbranch_6/gui/wxpython/docs/wxGUI_nviz_toolbar.jpg
===================================================================
(Binary files differ)
Copied: grass/branches/develbranch_6/gui/wxpython/docs/wxGUI_nviz_tools_light.jpg (from rev 47650, grass/trunk/gui/wxpython/docs/wxGUI_nviz_tools_light.jpg)
===================================================================
(Binary files differ)
Modified: grass/branches/develbranch_6/gui/wxpython/docs/wxGUI_nviz_tools_surface.jpg
===================================================================
(Binary files differ)
Modified: grass/branches/develbranch_6/gui/wxpython/docs/wxGUI_nviz_tools_vector.jpg
===================================================================
(Binary files differ)
Modified: grass/branches/develbranch_6/gui/wxpython/docs/wxGUI_nviz_tools_view.jpg
===================================================================
(Binary files differ)
Modified: grass/branches/develbranch_6/gui/wxpython/docs/wxGUI_nviz_tools_volume.jpg
===================================================================
(Binary files differ)
Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/colorrules.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/colorrules.py 2011-11-25 14:58:21 UTC (rev 49356)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/colorrules.py 2011-11-25 15:10:47 UTC (rev 49357)
@@ -9,7 +9,6 @@
- ColorTable
- RasterColorTable
- VectorColorTable
- - ThematicVectorTable
- BuferedWindow
(C) 2008, 2010-2011 by the GRASS Development Team
@@ -316,9 +315,6 @@
**kwargs):
"""!Dialog for interactively entering rules for map management
commands
-
- @param raster True to raster otherwise vector
- @param nviz True if ColorTable is called from nviz thematic mapping
"""
self.parent = parent # GMFrame
wx.Frame.__init__(self, parent, id, title, style = style, **kwargs)
@@ -1622,55 +1618,6 @@
return ColorTable.OnApply(self, event)
-class ThematicVectorTable(VectorColorTable):
- def __init__(self, parent, vectorType, **kwargs):
- """!Dialog for interactively entering color/size rules
- for vector maps for thematic mapping in nviz"""
- self.vectorType = vectorType
- VectorColorTable.__init__(self, parent = parent, **kwargs)
-
- self.SetTitle(_("Thematic mapping for vector map in 3D view"))
-
- def _initLayer(self):
- """!Set initial layer when opening dialog"""
- self.inmap = self.parent.GetLayerData(nvizType = 'vector', nameOnly = True)
- self.selectionInput.SetValue(self.inmap)
- self.selectionInput.Disable()
-
- def OnApply(self, event):
- """!Apply selected color table
-
- @return True on success otherwise False
- """
- ret = self.CreateColorTable()
- if not ret:
- gcmd.GMessage(parent = self, message = _("No valid color rules given."))
-
- data = self.parent.GetLayerData(nvizType = 'vector')
- data['vector']['points']['thematic']['layer'] = int(self.properties['layer'])
-
- value = None
- if self.properties['storeColumn']:
- value = self.properties['storeColumn']
-
- if not self.colorTable:
- if self.attributeType == 'color':
- data['vector'][self.vectorType]['thematic']['rgbcolumn'] = value
- else:
- data['vector'][self.vectorType]['thematic']['sizecolumn'] = value
- else:
- if self.attributeType == 'color':
- data['vector'][self.vectorType]['thematic']['rgbcolumn'] = None
- else:
- data['vector'][self.vectorType]['thematic']['sizecolumn'] = None
-
- data['vector'][self.vectorType]['thematic']['update'] = None
-
- event = wxUpdateProperties(data = data)
- wx.PostEvent(self.parent.mapWindow, event)
- self.parent.mapWindow.Refresh(False)
-
- return ret
class BufferedWindow(wx.Window):
"""!A Buffered window class"""
Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/gdialogs.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/gdialogs.py 2011-11-25 14:58:21 UTC (rev 49356)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/gdialogs.py 2011-11-25 15:10:47 UTC (rev 49357)
@@ -528,7 +528,7 @@
resize.SetToolTipString(_("Click and drag on the map display to set legend"
" size and position and then press OK"))
resize.SetName('resize')
- if self.parent.toolbars['nviz']:
+ if self.parent.IsPaneShown('3d'):
resize.Disable()
box.Add(item = resize, proportion = 0, flag = wx.ALIGN_CENTRE|wx.ALL, border = 5)
sizer.Add(item = box, proportion = 0,
@@ -579,7 +579,7 @@
sizer.Fit(self)
# create overlay if doesn't exist
- self._CreateOverlay()
+ self._createOverlay()
if len(self.parent.MapWindow.overlays[self.ovlId]['cmd']) > 1:
if name == 'legend':
@@ -592,12 +592,12 @@
mapName)
- def _CreateOverlay(self):
+ def _createOverlay(self):
+ """!Creates overlay"""
if not self.parent.Map.GetOverlay(self.ovlId):
self.newOverlay = self.parent.Map.AddOverlay(id = self.ovlId, type = self.name,
command = self.cmd,
l_active = False, l_render = False, l_hidden = True)
-
prop = { 'layer' : self.newOverlay,
'params' : None,
'propwin' : None,
@@ -607,6 +607,7 @@
self.parent.MapWindow2D.overlays[self.ovlId] = prop
if self.parent.MapWindow3D:
self.parent.MapWindow3D.overlays[self.ovlId] = prop
+
else:
if self.parent.MapWindow.overlays[self.ovlId]['propwin'] == None:
return
@@ -615,10 +616,7 @@
def OnOptions(self, event):
- """ self.SetSizer(sizer)
- sizer.Fit(self)
-
- Sets option for decoration map overlays
+ """!Sets option for decoration map overlays
"""
if self.parent.MapWindow.overlays[self.ovlId]['propwin'] is None:
# build properties dialog
@@ -660,6 +658,9 @@
self.parent.Map.GetOverlay(self.ovlId).SetActive(self.chkbox.IsChecked())
# update map
+ if self.parent.IsPaneShown('3d'):
+ self.parent.MapWindow.UpdateOverlays()
+
self.parent.MapWindow.UpdateMap()
# close dialog
@@ -710,12 +711,14 @@
self.currClr = self.parent.MapWindow.textdict[self.ovlId]['color']
self.currRot = self.parent.MapWindow.textdict[self.ovlId]['rotation']
self.currCoords = self.parent.MapWindow.textdict[self.ovlId]['coords']
+ self.currBB = self.parent.MapWindow.textdict[self.ovlId]['bbox']
else:
self.currClr = wx.BLACK
self.currText = ''
self.currFont = self.GetFont()
self.currRot = 0.0
self.currCoords = [10, 10, 10, 10]
+ self.currBB = wx.Rect()
self.sizer = wx.BoxSizer(wx.VERTICAL)
box = wx.GridBagSizer(vgap = 5, hgap = 5)
Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/gselect.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/gselect.py 2011-11-25 14:58:21 UTC (rev 49356)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/gselect.py 2011-11-25 15:10:47 UTC (rev 49357)
@@ -279,6 +279,7 @@
'raster files':'rast',
'grid3':'rast3d',
'rast3d':'rast3d',
+ '3d-raster':'rast3d',
'raster3D':'rast3d',
'raster3D files':'rast3d',
'vector':'vect',
Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/layertree.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/layertree.py 2011-11-25 14:58:21 UTC (rev 49356)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/layertree.py 2011-11-25 15:10:47 UTC (rev 49357)
@@ -233,7 +233,9 @@
else:
vector = False
if self.mapdisplay.statusbarWin['render'].GetValue():
- self.mapdisplay.MapWindow.UpdateMap(render = True, renderVector = vector)
+ self.mapdisplay.MapWindow2D.UpdateMap(render = True, renderVector = vector)
+ if self.lmgr.IsPaneShown('toolbarNviz'): # nviz
+ self.mapdisplay.MapWindow3D.UpdateMap(render = True)
self.rerender = False
@@ -294,7 +296,7 @@
self.popupMenu.Enable(self.popupID['opacity'], False)
self.popupMenu.Enable(self.popupID['properties'], False)
- if ltype in ('raster', 'vector', '3d-raster') and self.mapdisplay.toolbars['nviz']:
+ if ltype in ('raster', 'vector', '3d-raster') and self.lmgr.IsPaneShown('toolbarNviz'):
self.popupMenu.Append(self.popupID['nviz'], _("3D view properties"))
self.Bind (wx.EVT_MENU, self.OnNvizProperties, id = self.popupID['nviz'])
@@ -876,7 +878,7 @@
# updated progress bar range (mapwindow statusbar)
if checked is True:
self.mapdisplay.statusbarWin['progress'].SetRange(len(self.Map.GetListOfLayers(l_active = True)))
-
+
return layer
def PropertiesDialog (self, layer, show = True):
@@ -1033,6 +1035,22 @@
# update progress bar range (mapwindow statusbar)
self.mapdisplay.statusbarWin['progress'].SetRange(len(self.Map.GetListOfLayers(l_active = True)))
+ #
+ # nviz
+ #
+ if self.lmgr.IsPaneShown('toolbarNviz') and \
+ self.GetPyData(item) is not None:
+ # nviz - load/unload data layer
+ mapLayer = self.GetPyData(item)[0]['maplayer']
+ self.mapdisplay.SetStatusText(_("Please wait, updating data..."), 0)
+ if mapLayer.type == 'raster':
+ self.mapdisplay.MapWindow.UnloadRaster(item)
+ elif mapLayer.type == '3d-raster':
+ self.mapdisplay.MapWindow.UnloadRaster3d(item)
+ elif mapLayer.type == 'vector':
+ self.mapdisplay.MapWindow.UnloadVector(item)
+ self.mapdisplay.SetStatusText("", 0)
+
event.Skip()
def OnLayerChecked(self, event):
@@ -1068,7 +1086,7 @@
self.mapdisplay.statusbarWin['progress'].SetRange(len(self.Map.GetListOfLayers(l_active = True)))
# nviz
- if self.mapdisplay.toolbars['nviz'] and \
+ if self.lmgr.IsPaneShown('toolbarNviz') and \
self.GetPyData(item) is not None:
# nviz - load/unload data layer
mapLayer = self.GetPyData(item)[0]['maplayer']
@@ -1179,7 +1197,7 @@
render = render)
# update nviz tools
- if self.mapdisplay.toolbars['nviz'] and \
+ if self.lmgr.IsPaneShown('toolbarNviz') and \
self.GetPyData(self.layer_selected) is not None:
if self.layer_selected.IsChecked():
# update Nviz tool window
@@ -1390,7 +1408,7 @@
render = render)
# update nviz session
- if self.mapdisplay.toolbars['nviz'] and dcmd:
+ if self.lmgr.IsPaneShown('toolbarNviz') and dcmd:
mapLayer = self.GetPyData(layer)[0]['maplayer']
mapWin = self.mapdisplay.MapWindow
if len(mapLayer.GetCmd()) > 0:
Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/mapdisp.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/mapdisp.py 2011-11-25 14:58:21 UTC (rev 49356)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/mapdisp.py 2011-11-25 15:10:47 UTC (rev 49357)
@@ -227,7 +227,7 @@
self.statusbarWin['projection'].SetToolTip(wx.ToolTip (_("Reproject coordinates displayed "
"in the statusbar. Projection can be "
"defined in GUI preferences dialog "
- "(tab 'Display')")))
+ "(tab 'Projection')")))
self.statusbarWin['projection'].Hide()
# mask
@@ -271,7 +271,7 @@
# Update fancy gui style
#
self._mgr.AddPane(self.MapWindow, wx.aui.AuiPaneInfo().CentrePane().
- Dockable(False).BestSize((-1,-1)).
+ Dockable(False).BestSize((-1,-1)).Name('2d').
CloseButton(False).DestroyOnClose(True).
Layer(0))
self._mgr.Update()
@@ -336,21 +336,23 @@
Map = self.Map, tree = self.tree,
lmgr = self._layerManager)
self.MapWindowVDigit.Show()
+ self._mgr.AddPane(self.MapWindowVDigit, wx.aui.AuiPaneInfo().CentrePane().
+ Dockable(False).BestSize((-1,-1)).Name('vdigit').
+ CloseButton(False).DestroyOnClose(True).
+ Layer(0))
self.MapWindow = self.MapWindowVDigit
- self._mgr.DetachPane(self.MapWindow2D)
- self.MapWindow2D.Hide()
-
+ if self._mgr.GetPane('2d').IsShown():
+ self._mgr.GetPane('2d').Hide()
+ elif self._mgr.GetPane('3d').IsShown():
+ self._mgr.GetPane('3d').Hide()
+ self._mgr.GetPane('vdigit').Show()
self.toolbars['vdigit'] = toolbars.VDigitToolbar(parent = self, mapcontent = self.Map,
layerTree = self.tree,
log = log)
self.MapWindowVDigit.SetToolbar(self.toolbars['vdigit'])
- self._mgr.AddPane(self.MapWindowVDigit, wx.aui.AuiPaneInfo().CentrePane().
- Dockable(False).BestSize((-1,-1)).
- CloseButton(False).DestroyOnClose(True).
- Layer(0))
self._mgr.AddPane(self.toolbars['vdigit'],
wx.aui.AuiPaneInfo().
Name("vdigittoolbar").Caption(_("Vector Digitizer Toolbar")).
@@ -365,72 +367,117 @@
self.MapWindow.pen = wx.Pen(colour = 'red', width = 2, style = wx.SOLID)
self.MapWindow.polypen = wx.Pen(colour = 'green', width = 2, style = wx.SOLID)
- def _addToolbarNviz(self):
- """!Add 3D view mode toolbar
+ def AddNviz(self):
+ """!Add 3D view mode window
"""
import nviz
# check for GLCanvas and OpenGL
if not nviz.haveNviz:
- self.toolbars['map'].combo.SetValue (_("2D view"))
+ self.toolbars['map'].combo.SetValue(_("2D view"))
gcmd.GError(parent = self,
message = _("Unable to switch to 3D display mode.\nThe Nviz python extension "
"was not found or loaded properly.\n"
"Switching back to 2D display mode.\n\nDetails: %s" % nviz.errorMsg))
return
- # add Nviz toolbar and disable 2D display mode tools
- self.toolbars['nviz'] = toolbars.NvizToolbar(self, self.Map)
+ # disable 3D mode for other displays
+ for page in range(0, self._layerManager.gm_cb.GetPageCount()):
+ if self._layerManager.gm_cb.GetPage(page) != self._layerManager.curr_page:
+ if '3D' in self._layerManager.gm_cb.GetPage(page).maptree.mapdisplay.toolbars['map'].combo.GetString(1):
+ self._layerManager.gm_cb.GetPage(page).maptree.mapdisplay.toolbars['map'].combo.Delete(1)
self.toolbars['map'].Enable2D(False)
-
+ # add rotate tool to map toolbar
+ self.toolbars['map'].InsertTool((('rotate', Icons['nviz']['rotate'],
+ self.OnRotate, wx.ITEM_CHECK, 7),)) # 7 is position
+ self.toolbars['map'].InsertTool((('flyThrough', Icons['nviz']['flyThrough'],
+ self.OnFlyThrough, wx.ITEM_CHECK, 8),))
+ self.toolbars['map'].ChangeToolsDesc(mode2d = False)
# update status bar
- self.statusbarWin['toggle'].Enable(False)
+ choice = globalvar.MAP_DISPLAY_STATUSBAR_MODE
+ self.statusbarWin['toggle'].SetItems((choice[0], choice[1], choice[2],
+ choice[8], choice[9]))
+ self.statusbarWin['toggle'].SetSelection(0)
# erase map window
self.MapWindow.EraseMap()
- self._layerManager.goutput.WriteCmdLog(_("Starting 3D view mode..."))
+ self._layerManager.goutput.WriteCmdLog(_("Starting 3D view mode..."),
+ switchPage = False)
self.statusbar.SetStatusText(_("Please wait, loading data..."), 0)
- # create GL window & NVIZ toolbar
+ # create GL window
if not self.MapWindow3D:
self.MapWindow3D = nviz.GLWindow(self, id = wx.ID_ANY,
Map = self.Map, tree = self.tree, lmgr = self._layerManager)
self.MapWindow = self.MapWindow3D
self.MapWindow.SetCursor(self.cursors["default"])
- # add Nviz notebookpage
- self._layerManager.AddNviz()
+ # add Nviz notebookpage
+ self._layerManager.AddNvizTools()
+ # switch from MapWindow to MapWindowGL
+ self._mgr.GetPane('2d').Hide()
+ self._mgr.AddPane(self.MapWindow3D, wx.aui.AuiPaneInfo().CentrePane().
+ Dockable(False).BestSize((-1,-1)).Name('3d').
+ CloseButton(False).DestroyOnClose(True).
+ Layer(0))
+
self.MapWindow3D.OnPaint(None) # -> LoadData
self.MapWindow3D.Show()
+ self.MapWindow3D.ResetViewHistory()
self.MapWindow3D.UpdateView(None)
else:
self.MapWindow = self.MapWindow3D
+ os.environ['GRASS_REGION'] = self.Map.SetRegion(windres = True)
+ self.MapWindow3D.GetDisplay().Init()
+ del os.environ['GRASS_REGION']
+
+ # switch from MapWindow to MapWindowGL
+ self._mgr.GetPane('2d').Hide()
+ self._mgr.GetPane('3d').Show()
+
# add Nviz notebookpage
- self._layerManager.AddNviz()
- self._layerManager.nviz.UpdatePage('view')
- self._layerManager.nviz.UpdatePage('light')
+ self._layerManager.AddNvizTools()
+ self.MapWindow3D.ResetViewHistory()
+ for page in ('view', 'light', 'fringe', 'constant', 'cplane', 'animation'):
+ self._layerManager.nviz.UpdatePage(page)
+
+ self.MapWindow3D.overlays = self.MapWindow2D.overlays
+ self.MapWindow3D.textdict = self.MapWindow2D.textdict
+ # update overlays needs to be called after because getClientSize
+ # is called during update and it must give reasonable values
+ wx.CallAfter(self.MapWindow3D.UpdateOverlays)
- # switch from MapWindow to MapWindowGL
- # add nviz toolbar
- self._mgr.DetachPane(self.MapWindow2D)
- self.MapWindow2D.Hide()
- self._mgr.AddPane(self.MapWindow3D, wx.aui.AuiPaneInfo().CentrePane().
- Dockable(False).BestSize((-1,-1)).
- CloseButton(False).DestroyOnClose(True).
- Layer(0))
- self._mgr.AddPane(self.toolbars['nviz'],
- wx.aui.AuiPaneInfo().
- Name("nviztoolbar").Caption(_("3D View Toolbar")).
- ToolbarPane().Top().Row(1).
- LeftDockable(False).RightDockable(False).
- BottomDockable(False).TopDockable(True).
- CloseButton(False).Layer(2).
- BestSize((self.toolbars['nviz'].GetBestSize())))
-
self.SetStatusText("", 0)
+ self._mgr.Update()
+
+ def RemoveNviz(self):
+ """!Restore 2D view"""
+ self.toolbars['map'].RemoveTool(self.toolbars['map'].rotate)
+ self.toolbars['map'].RemoveTool(self.toolbars['map'].flyThrough)
+ # update status bar
+ self.statusbarWin['toggle'].SetItems(globalvar.MAP_DISPLAY_STATUSBAR_MODE)
+ self.statusbarWin['toggle'].SetSelection(UserSettings.Get(group = 'display',
+ key = 'statusbarMode',
+ subkey = 'selection'))
+ self.statusbar.SetStatusText(_("Please wait, unloading data..."), 0)
+ self._layerManager.goutput.WriteCmdLog(_("Switching back to 2D view mode..."),
+ switchPage = False)
+ self.MapWindow3D.OnClose(event = None)
+ # switch from MapWindowGL to MapWindow
+ self._mgr.GetPane('2d').Show()
+ self._mgr.GetPane('3d').Hide()
+ self.MapWindow = self.MapWindow2D
+ # remove nviz notebook page
+ self._layerManager.RemoveNvizTools()
+
+ self.MapWindow2D.overlays = self.MapWindow3D.overlays
+ self.MapWindow2D.textdict = self.MapWindow3D.textdict
+ self.MapWindow.UpdateMap()
+ self._mgr.Update()
+
def AddToolbar(self, name):
"""!Add defined toolbar to the window
@@ -439,7 +486,6 @@
- 'vdigit' - vector digitizer
- 'gcpdisp' - GCP Manager Display
- 'georect' - georectifier
- - 'nviz' - 3D view mode
"""
# default toolbar
if name == "map":
@@ -448,7 +494,7 @@
self._mgr.AddPane(self.toolbars['map'],
wx.aui.AuiPaneInfo().
Name("maptoolbar").Caption(_("Map Toolbar")).
- ToolbarPane().Top().
+ ToolbarPane().Top().Name('mapToolbar').
LeftDockable(False).RightDockable(False).
BottomDockable(False).TopDockable(True).
CloseButton(False).Layer(2).
@@ -469,10 +515,6 @@
BottomDockable(False).TopDockable(True).
CloseButton(False).Layer(2).
BestSize((self.toolbars['georect'].GetBestSize())))
- # nviz
- elif name == "nviz":
- self._addToolbarNviz()
-
self._mgr.Update()
def RemoveToolbar (self, name):
@@ -489,38 +531,22 @@
self.toolbars[name] = None
if name == 'vdigit':
- self._mgr.DetachPane(self.MapWindowVDigit)
- self.MapWindowVDigit.Hide()
- self.MapWindow2D.Show()
- self._mgr.AddPane(self.MapWindow2D, wx.aui.AuiPaneInfo().CentrePane().
- Dockable(False).BestSize((-1,-1)).
- CloseButton(False).DestroyOnClose(True).
- Layer(0))
+ self._mgr.GetPane('vdigit').Hide()
+ self._mgr.GetPane('2d').Show()
self.MapWindow = self.MapWindow2D
-
- elif name == 'nviz':
- # unload data
- # self.MapWindow3D.Reset()
- # switch from MapWindowGL to MapWindow
- self._mgr.DetachPane(self.MapWindow3D)
- self.MapWindow3D.Hide()
- self.MapWindow2D.Show()
- self._mgr.AddPane(self.MapWindow2D, wx.aui.AuiPaneInfo().CentrePane().
- Dockable(False).BestSize((-1,-1)).
- CloseButton(False).DestroyOnClose(True).
- Layer(0))
- self.MapWindow = self.MapWindow2D
- # remove nviz notebook page
- self._layerManager.RemoveNviz()
- self.MapWindow.UpdateMap()
-
self.toolbars['map'].combo.SetValue(_("2D view"))
self.toolbars['map'].Enable2D(True)
self.statusbarWin['toggle'].Enable(True)
self._mgr.Update()
-
+
+ def IsPaneShown(self, name):
+ """!Check if pane (toolbar, mapWindow ...) of given name is currently shown"""
+ if self._mgr.GetPane(name).IsOk():
+ return self._mgr.GetPane(name).IsShown()
+ return False
+
def _initDisplay(self):
"""!Initialize map display, set dimensions and map region
"""
@@ -543,8 +569,7 @@
event.Skip()
def OnFocus(self, event):
- """
- Change choicebook page to match display.
+ """!Change choicebook page to match display.
Or set display for georectifying
"""
if self._layerManager and \
@@ -558,6 +583,8 @@
pgnum = self.layerbook.GetPageIndex(self.page)
if pgnum > -1:
self.layerbook.SetSelection(pgnum)
+ self._layerManager.curr_page = self.layerbook.GetCurrentPage()
+ self.layerbook
event.Skip()
@@ -679,13 +706,37 @@
# change the cursor
self.MapWindow.SetCursor(self.cursors["hand"])
-
+
+ def OnRotate(self, event):
+ """!Rotate 3D view
+ """
+ if self.toolbars['map']:
+ self.toolbars['map'].OnTool(event)
+ self.toolbars['map'].action['desc'] = ''
+
+ self.MapWindow.mouse['use'] = "rotate"
+
+ # change the cursor
+ self.MapWindow.SetCursor(self.cursors["hand"])
def OnErase(self, event):
"""
Erase the canvas
"""
self.MapWindow.EraseMap()
+ def OnFlyThrough(self, event):
+ """!Fly-through mode
+ """
+ if self.toolbars['map']:
+ self.toolbars['map'].OnTool(event)
+ self.toolbars['map'].action['desc'] = ''
+
+ self.MapWindow.mouse['use'] = "fly"
+
+ # change the cursor
+ self.MapWindow.SetCursor(self.cursors["hand"])
+ self.MapWindow.SetFocus()
+
def OnZoomRegion(self, event):
"""
Zoom to region
@@ -831,6 +882,9 @@
precision, region['center_northing']))
return
+ if self.IsPaneShown('3d'):
+ self.MapWindow.GoTo(e, n)
+ return
dn = (region['nsres'] * region['rows']) / 2.
region['n'] = region['center_northing'] + dn
@@ -859,15 +913,16 @@
self.statusbarWin['goto'].Hide()
self.statusbarWin['projection'].Hide()
self.mapScaleValue = self.ppm = None
-
- if self.statusbarWin['toggle'].GetSelection() == 0: # Coordinates
+ choice = globalvar.MAP_DISPLAY_STATUSBAR_MODE
+
+ if self.statusbarWin['toggle'].GetStringSelection() == choice[0]: # Coordinates
self.statusbar.SetStatusText("", 0)
# enable long help
self.StatusbarEnableLongHelp()
- elif self.statusbarWin['toggle'].GetSelection() in (1, 2): # Extent
- sel = self.statusbarWin['toggle'].GetSelection()
- if sel == 1:
+ elif self.statusbarWin['toggle'].GetStringSelection() in (choice[1], choice[2]): # Extent
+ sel = self.statusbarWin['toggle'].GetStringSelection()
+ if sel == choice[1]:
region = self.Map.region
else:
region = self.Map.GetRegion() # computation region
@@ -899,7 +954,7 @@
precision = precision)
e, n = utils.Deg2DMS(coord2[0], coord2[1], string = False,
precision = precision)
- if sel == 1:
+ if sel == choice[1]:
self.statusbar.SetStatusText("%s - %s, %s - %s" %
(w, e, s, n), 0)
else:
@@ -912,7 +967,7 @@
else:
w, s = coord1
e, n = coord2
- if sel == 1:
+ if sel == choice[1]:
self.statusbar.SetStatusText("%.*f - %.*f, %.*f - %.*f" %
(precision, w, precision, e,
precision, s, precision, n), 0)
@@ -930,7 +985,7 @@
string = False, precision = precision)
e, n = utils.Deg2DMS(region["e"], region["n"],
string = False, precision = precision)
- if sel == 1:
+ if sel == choice[1]:
self.statusbar.SetStatusText("%s - %s, %s - %s" %
(w, e, s, n), 0)
else:
@@ -941,7 +996,7 @@
else:
w, s = region["w"], region["s"]
e, n = region["e"], region["n"]
- if sel == 1:
+ if sel == choice[1]:
self.statusbar.SetStatusText("%.*f - %.*f, %.*f - %.*f" %
(precision, w, precision, e,
precision, s, precision, n), 0)
@@ -954,32 +1009,32 @@
# enable long help
self.StatusbarEnableLongHelp()
- elif self.statusbarWin['toggle'].GetSelection() == 3: # Show comp. extent
+ elif self.statusbarWin['toggle'].GetStringSelection() == choice[3]: # Show comp. extent
self.statusbar.SetStatusText("", 0)
self.statusbarWin['region'].Show()
# disable long help
self.StatusbarEnableLongHelp(False)
- elif self.statusbarWin['toggle'].GetSelection() == 4: # Align extent
+ elif self.statusbarWin['toggle'].GetStringSelection() == choice[4]: # Align extent
self.statusbar.SetStatusText("", 0)
self.statusbarWin['alignExtent'].Show()
# disable long help
self.StatusbarEnableLongHelp(False)
- elif self.statusbarWin['toggle'].GetSelection() == 5: # Display resolution
+ elif self.statusbarWin['toggle'].GetStringSelection() == choice[5]: # Display resolution
self.statusbar.SetStatusText("", 0)
self.statusbarWin['resolution'].Show()
# disable long help
self.StatusbarEnableLongHelp(False)
- elif self.statusbarWin['toggle'].GetSelection() == 6: # Display geometry
+ elif self.statusbarWin['toggle'].GetStringSelection() == choice[6]: # Display geometry
self.statusbar.SetStatusText("rows=%d; cols=%d; nsres=%.2f; ewres=%.2f" %
(self.Map.region["rows"], self.Map.region["cols"],
self.Map.region["nsres"], self.Map.region["ewres"]), 0)
# enable long help
self.StatusbarEnableLongHelp()
- elif self.statusbarWin['toggle'].GetSelection() == 7: # Map scale
+ elif self.statusbarWin['toggle'].GetStringSelection() == choice[7]: # Map scale
# TODO: need to be fixed...
### screen X region problem
### user should specify ppm
@@ -1028,7 +1083,7 @@
# disable long help
self.StatusbarEnableLongHelp(False)
- elif self.statusbarWin['toggle'].GetSelection() == 8: # go to
+ elif self.statusbarWin['toggle'].GetStringSelection() == choice[8]: # go to
self.statusbar.SetStatusText("")
region = self.Map.GetCurrentRegion()
precision = int(UserSettings.Get(group = 'projection', key = 'format',
@@ -1069,7 +1124,7 @@
# disable long help
self.StatusbarEnableLongHelp(False)
- elif self.statusbarWin['toggle'].GetSelection() == 9: # projection
+ elif self.statusbarWin['toggle'].GetStringSelection() == choice[9]: # projection
self.statusbar.SetStatusText("")
epsg = UserSettings.Get(group = 'projection', key = 'statusbar', subkey = 'epsg')
if epsg:
@@ -1131,10 +1186,10 @@
def SaveToFile(self, event):
"""!Save map to image
"""
- if self.toolbars['nviz']:
+ if self.IsPaneShown('3d'):
filetype = "PPM file (*.ppm)|*.ppm|TIF file (*.tif)|*.tif"
- ltype = [{ 'ext' : 'ppm', 'type' : -1 },
- { 'ext' : 'tif', 'type' : wx.BITMAP_TYPE_TIF }]
+ ltype = [{ 'ext' : 'ppm', 'type' : 'ppm' },
+ { 'ext' : 'tif', 'type' : 'tif' }]
else:
img = self.MapWindow.img
if not img:
@@ -1212,10 +1267,9 @@
maplayer = self.toolbars['vdigit'].GetLayer()
if maplayer:
self.toolbars['vdigit'].OnExit()
+ if self.IsPaneShown('3d'):
+ self.RemoveNviz()
- if self.toolbars['nviz']:
- self.toolbars['nviz'].OnExit()
-
if not self._layerManager:
self.Destroy()
elif self.page:
@@ -1231,29 +1285,7 @@
def GetWindow(self):
"""!Get map window"""
return self.MapWindow
-
- def OnNvizQuerySurface(self, event):
- """!Query current surface in 3D view mode"""
- if self.toolbars['map'].GetAction() == 'nvizQuerySurface':
- self.toolbars['map'].SelectDefault(event)
- return
- self.toolbars['map'].action['desc'] = 'nvizQuerySurface'
-
- self.MapWindow.mouse['use'] = "nvizQuerySurface"
- self._OnQuery()
-
- def OnNvizQueryVector(self, event):
- """!Query current vector in 3D view mode"""
- if self.toolbars['map'].GetAction() == 'nvizQueryVector':
- self.toolbars['map'].SelectDefault(event)
- return
-
- self.toolbars['map'].action['desc'] = 'nvizQueryVector'
-
- self.MapWindow.mouse['use'] = "nvizQueryVector"
- self._OnQuery()
-
def QueryMap(self, x, y):
"""!Query raster or vector map layers by r/v.what
@@ -1298,7 +1330,9 @@
rast.append(iname)
elif ltype in ('vector', 'thememap', 'themechart'):
vect.append(name)
-
+ # rasters are not queried this way in 3D, we don't want them now
+ if self.IsPaneShown('3d'):
+ rast = list()
# use display region settings instead of computation region settings
self.tmpreg = os.getenv("GRASS_REGION")
os.environ["GRASS_REGION"] = self.Map.SetRegion(windres = False)
@@ -1413,25 +1447,28 @@
cats = self.dialogs['attributes'].GetCats()
- try:
- qlayer = self.Map.GetListOfLayers(l_name = globalvar.QUERYLAYER)[0]
- except IndexError:
- qlayer = None
+ qlayer = None
+ if not self.IsPaneShown('3d'):
+ try:
+ qlayer = self.Map.GetListOfLayers(l_name = globalvar.QUERYLAYER)[0]
+ except IndexError:
+ pass
if self.dialogs['attributes'].mapDBInfo and cats:
- # highlight feature & re-draw map
- if qlayer:
- qlayer.SetCmd(self.AddTmpVectorMapLayer(mapName, cats,
- useId = False,
- addLayer = False))
- else:
- qlayer = self.AddTmpVectorMapLayer(mapName, cats, useId = False)
-
- # set opacity based on queried layer
- opacity = self.tree.GetPyData(self.tree.layer_selected)[0]['maplayer'].GetOpacity(float = True)
- qlayer.SetOpacity(opacity)
-
- self.MapWindow.UpdateMap(render = False, renderVector = False)
+ if not self.IsPaneShown('3d'):
+ # highlight feature & re-draw map
+ if qlayer:
+ qlayer.SetCmd(self.AddTmpVectorMapLayer(mapName, cats,
+ useId = False,
+ addLayer = False))
+ else:
+ qlayer = self.AddTmpVectorMapLayer(mapName, cats, useId = False)
+
+ # set opacity based on queried layer
+ opacity = self.tree.GetPyData(self.tree.layer_selected)[0]['maplayer'].GetOpacity(float = True)
+ qlayer.SetOpacity(opacity)
+
+ self.MapWindow.UpdateMap(render = False, renderVector = False)
if not self.dialogs['attributes'].IsShown():
self.dialogs['attributes'].Show()
else:
@@ -1446,40 +1483,20 @@
if self.toolbars['map']:
self.toolbars['map'].OnTool(event)
action = self.toolbars['map'].GetAction()
-
- if self.toolbars['nviz']:
- toolsmenu = wx.Menu()
- raster = wx.MenuItem(parentMenu = toolsmenu, id = wx.ID_ANY,
- text = _("Query surface (raster map)"),
- kind = wx.ITEM_CHECK)
- toolsmenu.AppendItem(raster)
- self.Bind(wx.EVT_MENU, self.OnNvizQuerySurface, raster)
- if action == "nvizQuerySurface":
- raster.Check(True)
- vector = wx.MenuItem(parentMenu = toolsmenu, id = wx.ID_ANY,
- text = _("Query vector map"),
- kind = wx.ITEM_CHECK)
- toolsmenu.AppendItem(vector)
- self.Bind(wx.EVT_MENU, self.OnNvizQueryVector, vector)
- if action == "nvizQueryVector":
- vector.Check(True)
-
- self.PopupMenu(toolsmenu)
- toolsmenu.Destroy()
- else:
- self.toolbars['map'].action['desc'] = 'queryMap'
- self.MapWindow.mouse['use'] = "query"
- if not self.IsStandalone():
- # switch to output console to show query results
- self._layerManager.notebook.SetSelectionByName('output')
-
- self.MapWindow.mouse['box'] = "point"
- self.MapWindow.zoomtype = 0
-
- # change the cursor
- self.MapWindow.SetCursor(self.cursors["cross"])
+ self.toolbars['map'].action['desc'] = 'queryMap'
+ self.MapWindow.mouse['use'] = "query"
+ if not self.IsStandalone():
+ # switch to output console to show query results
+ self._layerManager.notebook.SetSelectionByName('output')
+
+ self.MapWindow.mouse['box'] = "point"
+ self.MapWindow.zoomtype = 0
+
+ # change the cursor
+ self.MapWindow.SetCursor(self.cursors["cross"])
+
def AddTmpVectorMapLayer(self, name, cats, useId = False, addLayer = True):
"""!Add temporal vector map layer to map composition
@@ -1735,6 +1752,13 @@
AddScale.SetBitmap(icons["addBarscale"].GetBitmap(self.iconsize))
decmenu.AppendItem(AddScale)
self.Bind(wx.EVT_MENU, self.OnAddBarscale, AddScale)
+ # temporary
+ if self.IsPaneShown('3d'):
+ AddScale.Enable(False)
+ AddArrow = wx.MenuItem(decmenu, wx.ID_ANY, _("Add north arrow"))
+ AddArrow.SetBitmap(icons["addBarscale"].GetBitmap(self.iconsize))
+ decmenu.AppendItem(AddArrow)
+ self.Bind(wx.EVT_MENU, self.OnAddArrow, AddArrow)
AddLegend = wx.MenuItem(decmenu, wx.ID_ANY, icons["addLegend"].GetLabel())
AddLegend.SetBitmap(icons["addLegend"].GetBitmap(self.iconsize))
@@ -1818,13 +1842,14 @@
"""
if self.MapWindow.dragid > -1:
id = self.MapWindow.dragid
+ self.MapWindow.dragid = -1
else:
# index for overlay layer in render
if len(self.MapWindow.textdict.keys()) > 0:
- id = self.MapWindow.textdict.keys()[-1] + 1
+ id = max(self.MapWindow.textdict.keys()) + 1
else:
id = 101
-
+
self.dialogs['text'] = gdialogs.TextLayerDialog(parent = self, ovlId = id,
title = _('Add text layer'),
size = (400, 200))
@@ -1834,29 +1859,43 @@
if self.dialogs['text'].ShowModal() == wx.ID_OK:
text = self.dialogs['text'].GetValues()['text']
active = self.dialogs['text'].GetValues()['active']
- coords, w, h = self.MapWindow.TextBounds(self.dialogs['text'].GetValues())
# delete object if it has no text or is not active
if text == '' or active == False:
try:
- self.MapWindow.pdc.ClearId(id)
- self.MapWindow.pdc.RemoveId(id)
+ self.MapWindow2D.pdc.ClearId(id)
+ self.MapWindow2D.pdc.RemoveId(id)
del self.MapWindow.textdict[id]
+ if self.IsPaneShown('3d'):
+ self.MapWindow3D.UpdateOverlays()
+ self.MapWindow.UpdateMap()
+ else:
+ self.MapWindow2D.UpdateMap(render = False, renderVector = False)
except:
pass
return
- self.MapWindow.pdc.ClearId(id)
- self.MapWindow.pdc.SetId(id)
+
self.MapWindow.textdict[id] = self.dialogs['text'].GetValues()
- self.MapWindow.Draw(self.MapWindow.pdcDec, img = self.MapWindow.textdict[id],
- drawid = id, pdctype = 'text', coords = coords)
+ if self.IsPaneShown('3d'):
+ self.MapWindow3D.UpdateOverlays()
+ self.MapWindow3D.UpdateMap()
+ else:
+ self.MapWindow2D.pdc.ClearId(id)
+ self.MapWindow2D.pdc.SetId(id)
+ self.MapWindow2D.UpdateMap(render = False, renderVector = False)
- self.MapWindow.UpdateMap(render = False, renderVector = False)
-
self.MapWindow.mouse['use'] = 'pointer'
-
+
+ def OnAddArrow(self, event):
+ """!Handler for north arrow menu selection.
+ Opens Appearance page of nviz notebook.
+ """
+
+ self._layerManager.nviz.SetPage('decoration')
+ self.MapWindow3D.SetDrawArrow((70, 70))
+
def GetOptData(self, dcmd, type, params, propwin):
"""!Callback method for decoration overlay command generated by
dialog created in menuform.py
Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/mapdisp_window.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/mapdisp_window.py 2011-11-25 14:58:21 UTC (rev 49356)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/mapdisp_window.py 2011-11-25 15:10:47 UTC (rev 49357)
@@ -163,6 +163,7 @@
e, n = self.Pixel2Cell(event.GetPositionTuple())
except (TypeError, ValueError):
self.parent.statusbar.SetStatusText("", 0)
+ event.Skip()
return
updated = False
@@ -479,12 +480,12 @@
w, h = self.GetFullTextExtent(img['text'])[0:2]
pdc.SetFont(img['font'])
pdc.SetTextForeground(img['color'])
- coords, w, h = self.TextBounds(img)
+ coords, bbox = self.TextBounds(img)
if rotation == 0:
pdc.DrawText(img['text'], coords[0], coords[1])
else:
pdc.DrawRotatedText(img['text'], coords[0], coords[1], rotation)
- pdc.SetIdBounds(drawid, wx.Rect(coords[0], coords[1], w, h))
+ pdc.SetIdBounds(drawid, bbox)
pdc.EndDrawing()
@@ -492,11 +493,15 @@
return drawid
- def TextBounds(self, textinfo):
+ def TextBounds(self, textinfo, relcoords = False):
"""!Return text boundary data
@param textinfo text metadata (text, font, color, rotation)
@param coords reference point
+
+ @return coords of nonrotated text bbox (TL corner)
+ @return bbox of rotated text bbox (wx.Rect)
+ @return relCoords are text coord inside bbox
"""
if 'rotation' in textinfo:
rotation = float(textinfo['rotation'])
@@ -504,7 +509,8 @@
rotation = 0.0
coords = textinfo['coords']
-
+ bbox = wx.Rect(coords[0], coords[1], 0, 0)
+ relCoords = (0, 0)
Debug.msg (4, "BufferedWindow.TextBounds(): text=%s, rotation=%f" % \
(textinfo['text'], rotation))
@@ -515,15 +521,31 @@
w, h = self.GetTextExtent(textinfo['text'])
if rotation == 0:
- coords[2], coords[3] = coords[0] + w, coords[1] + h
- return coords, w, h
+ bbox[2], bbox[3] = w, h
+ if relcoords:
+ return coords, bbox, relCoords
+ else:
+ return coords, bbox
boxh = math.fabs(math.sin(math.radians(rotation)) * w) + h
boxw = math.fabs(math.cos(math.radians(rotation)) * w) + h
- coords[2] = coords[0] + boxw
- coords[3] = coords[1] + boxh
-
- return coords, boxw, boxh
+ if rotation > 0 and rotation < 90:
+ bbox[1] -= boxh
+ relCoords = (0, boxh)
+ elif rotation >= 90 and rotation < 180:
+ bbox[0] -= boxw
+ bbox[1] -= boxh
+ relCoords = (boxw, boxh)
+ elif rotation >= 180 and rotation < 270:
+ bbox[0] -= boxw
+ relCoords = (boxw, 0)
+ bbox[2] = boxw
+ bbox[3] = boxh
+ bbox.Inflate(h,h)
+ if relcoords:
+ return coords, bbox, relCoords
+ else:
+ return coords, bbox
def OnPaint(self, event):
"""!Draw PseudoDC's to buffered paint DC
@@ -960,7 +982,9 @@
if type(r2) is list:
r2 = wx.Rect(r[0], r[1], r[2], r[3])
if id > 100: # text
- self.textdict[id]['coords'] = r2
+ self.textdict[id]['bbox'] = r2
+ self.textdict[id]['coords'][0] += dx
+ self.textdict[id]['coords'][1] += dy
r = r.Union(r2)
r.Inflate(4,4)
self.RefreshRect(r, False)
@@ -1348,7 +1372,7 @@
if self.dragid < 99 and self.dragid in self.overlays:
self.overlays[self.dragid]['coords'] = self.pdc.GetIdBounds(self.dragid)
elif self.dragid > 100 and self.dragid in self.textdict:
- self.textdict[self.dragid]['coords'] = self.pdc.GetIdBounds(self.dragid)
+ self.textdict[self.dragid]['bbox'] = self.pdc.GetIdBounds(self.dragid)
else:
pass
self.dragid = None
Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/menuform.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/menuform.py 2011-11-25 14:58:21 UTC (rev 49356)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/menuform.py 2011-11-25 15:10:47 UTC (rev 49357)
@@ -2000,7 +2000,15 @@
self.notebookPages[kwargs['name']] = kwargs['page']
del kwargs['name']
super(GNotebook, self).AddPage(**kwargs)
-
+
+ def InsertPage(self, **kwargs):
+ """!Insert a new page
+ """
+ if 'name' in kwargs:
+ self.notebookPages[kwargs['name']] = kwargs['page']
+ del kwargs['name']
+ super(GNotebook, self).InsertPage(**kwargs)
+
def SetSelectionByName(self, page):
"""!Set notebook
Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/nviz.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/nviz.py 2011-11-25 14:58:21 UTC (rev 49356)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/nviz.py 2011-11-25 15:10:47 UTC (rev 49357)
@@ -8,13 +8,14 @@
Map Display supports standard 2D view mode ('mapdisp' module) and
2.5/3D mode ('nviz_mapdisp' module).
-(C) 2008, 2010 by the GRASS Development Team
+(C) 2008, 2010-2011 by the GRASS Development Team
This program is free software under the GNU General Public
License (>=v2). Read the file COPYING that comes with GRASS
for details.
@author Martin Landa <landa.martin gmail.com> (Google SoC 2008/2010)
+ at author Anna Kratochvilova <KratochAnna seznam.cz> (Google SoC 2011)
"""
errorMsg = ''
Added: grass/branches/develbranch_6/gui/wxpython/gui_modules/nviz_animation.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/nviz_animation.py (rev 0)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/nviz_animation.py 2011-11-25 15:10:47 UTC (rev 49357)
@@ -0,0 +1,208 @@
+"""!
+ at package nviz_animation.py
+
+ at brief Nviz (3D view) animation
+
+Classes:
+ - Animation
+
+(C) 2008-2011 by the GRASS Development Team
+
+This program is free software under the GNU General Public
+License (>=v2). Read the file COPYING that comes with GRASS
+for details.
+
+ at author Anna Kratochvilova <kratochanna gmail.com>
+"""
+import os
+import copy
+
+import wx
+from wx.lib.newevent import NewEvent
+
+wxAnimationFinished, EVT_ANIM_FIN = NewEvent()
+wxAnimationUpdateIndex, EVT_ANIM_UPDATE_IDX = NewEvent()
+
+
+class Animation:
+ """!Class represents animation as a sequence of states (views).
+ It enables to record, replay the sequence and finally generate
+ all image files. Recording and replaying is based on timer events.
+ There is no frame interpolation like in the Tcl/Tk based Nviz.
+ """
+ def __init__(self, mapWindow, timer):
+ """!Animation constructor
+
+ @param mapWindow glWindow where rendering takes place
+ @param timer timer for recording and replaying
+ """
+
+ self.animationList = [] # view states
+ self.timer = timer
+ self.mapWindow = mapWindow
+ self.actions = {'record': self.Record,
+ 'play': self.Play}
+ self.formats = ['ppm', 'tif'] # currently supported formats
+ self.mode = 'record' # current mode (record, play, save)
+ self.paused = False # recording/replaying paused
+ self.currentFrame = 0 # index of current frame
+ self.fps = 24 # user settings # Frames per second
+
+ self.stopSaving = False # stop during saving images
+ self.animationSaved = False # current animation saved or not
+
+ def Start(self):
+ """!Start recording/playing"""
+ self.timer.Start(self.GetInterval())
+
+ def Pause(self):
+ """!Pause recording/playing"""
+ self.timer.Stop()
+
+ def Stop(self):
+ """!Stop recording/playing"""
+ self.timer.Stop()
+ self.PostFinishedEvent()
+
+ def Update(self):
+ """!Record/play next view state (on timer event)"""
+ self.actions[self.mode]()
+
+ def Record(self):
+ """!Record new view state"""
+ self.animationList.append({'view' : copy.deepcopy(self.mapWindow.view),
+ 'iview': copy.deepcopy(self.mapWindow.iview)})
+ self.currentFrame += 1
+ self.PostUpdateIndexEvent(index = self.currentFrame)
+ self.animationSaved = False
+
+ def Play(self):
+ """!Render next frame"""
+ if not self.animationList:
+ self.Stop()
+ return
+ try:
+ self.IterAnimation()
+ except IndexError:
+ # no more frames
+ self.Stop()
+
+ def IterAnimation(self):
+ params = self.animationList[self.currentFrame]
+ self.UpdateView(params)
+ self.currentFrame += 1
+
+ self.PostUpdateIndexEvent(index = self.currentFrame)
+
+ def UpdateView(self, params):
+ """!Update view data in map window and render"""
+ toolWin = self.mapWindow.GetToolWin()
+ toolWin.UpdateState(view = params['view'], iview = params['iview'])
+
+ self.mapWindow.UpdateView()
+
+ self.mapWindow.render['quick'] = True
+ self.mapWindow.Refresh(False)
+
+ def IsRunning(self):
+ """!Test if timer is running"""
+ return self.timer.IsRunning()
+
+ def SetMode(self, mode):
+ """!Start animation mode
+
+ @param mode animation mode (record, play, save)
+ """
+ self.mode = mode
+
+ def GetMode(self):
+ """!Get animation mode (record, play, save)"""
+ return self.mode
+
+ def IsPaused(self):
+ """!Test if animation is paused"""
+ return self.paused
+
+ def SetPause(self, pause):
+ self.paused = pause
+
+ def Exists(self):
+ """!Returns if an animation has been recorded"""
+ return bool(self.animationList)
+
+ def GetFrameCount(self):
+ """!Return number of recorded frames"""
+ return len(self.animationList)
+
+ def Clear(self):
+ """!Clear all records"""
+ self.animationList = []
+ self.currentFrame = 0
+
+ def GoToFrame(self, index):
+ """!Render frame of given index"""
+ if index >= len(self.animationList):
+ return
+
+ self.currentFrame = index
+ params = self.animationList[self.currentFrame]
+ self.UpdateView(params)
+
+ def PostFinishedEvent(self):
+ """!Animation ends"""
+ toolWin = self.mapWindow.GetToolWin()
+ event = wxAnimationFinished(mode = self.mode)
+ wx.PostEvent(toolWin, event)
+
+ def PostUpdateIndexEvent(self, index):
+ """!Frame index changed, update tool window"""
+ toolWin = self.mapWindow.GetToolWin()
+ event = wxAnimationUpdateIndex(index = index, mode = self.mode)
+ wx.PostEvent(toolWin, event)
+
+ def StopSaving(self):
+ """!Abort image files generation"""
+ self.stopSaving = True
+
+ def IsSaved(self):
+ """"!Test if animation has been saved (to images)"""
+ return self.animationSaved
+
+ def SaveAnimationFile(self, path, prefix, format):
+ """!Generate image files
+
+ @param path path to direcory
+ @param prefix file prefix
+ @param format index of image file format
+ """
+ w, h = self.mapWindow.GetClientSizeTuple()
+ toolWin = self.mapWindow.GetToolWin()
+
+ self.currentFrame = 0
+ self.mode = 'save'
+ for params in self.animationList:
+ if not self.stopSaving:
+ self.UpdateView(params)
+ filename = prefix + "_" + str(self.currentFrame) + '.' + self.formats[format]
+ filepath = os.path.join(path, filename)
+ self.mapWindow.SaveToFile(FileName = filepath, FileType = self.formats[format],
+ width = w, height = h)
+ self.currentFrame += 1
+
+ wx.Yield()
+ toolWin.UpdateFrameIndex(index = self.currentFrame, goToFrame = False)
+ else:
+ self.stopSaving = False
+ break
+ self.animationSaved = True
+ self.PostFinishedEvent()
+
+ def SetFPS(self, fps):
+ """!Set Frames Per Second value
+ @param fps frames per second
+ """
+ self.fps = fps
+
+ def GetInterval(self):
+ """!Return timer interval in ms"""
+ return 1000. / self.fps
Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/nviz_mapdisp.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/nviz_mapdisp.py 2011-11-25 14:58:21 UTC (rev 49356)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/nviz_mapdisp.py 2011-11-25 15:10:47 UTC (rev 49357)
@@ -1,20 +1,22 @@
-"""
+"""!
@package nviz_mapdisp.py
- at brief Nviz extension for wxGUI
+ at brief wxGUI 3D view mode (map canvas)
-This module implements 3D visualization mode of map display.
+This module implements 3D visualization mode for map display.
List of classes:
+ - NvizThread
- GLWindow
-(C) 2008-2009 by the GRASS Development Team
+(C) 2008-2011 by the GRASS Development Team
This program is free software under the GNU General Public
License (>=v2). Read the file COPYING that comes with GRASS
for details.
- at author Martin Landa <landa.martin gmail.com> (Google SoC 2008)
+ at author Martin Landa <landa.martin gmail.com> (Google SoC 2008/2010)
+ at author Anna Kratochvilova <kratochanna gmail.com> (Google SoC 2011)
"""
import os
@@ -22,6 +24,8 @@
import time
import copy
import math
+import types
+import tempfile
from threading import Thread
@@ -32,22 +36,25 @@
import gcmd
import globalvar
+import grass.script as grass
from debug import Debug
from mapdisp_window import MapWindow
from goutput import wxCmdOutput
from preferences import globalSettings as UserSettings
from workspace import Nviz as NvizDefault
+from nviz_animation import Animation
import wxnviz
wxUpdateProperties, EVT_UPDATE_PROP = NewEvent()
wxUpdateView, EVT_UPDATE_VIEW = NewEvent()
wxUpdateLight, EVT_UPDATE_LIGHT = NewEvent()
+wxUpdateCPlane, EVT_UPDATE_CPLANE = NewEvent()
class NvizThread(Thread):
def __init__(self, log, progressbar, window):
Thread.__init__(self)
-
+ Debug.msg(5, "NvizThread.__init__():")
self.log = log
self.progressbar = progressbar
self.window = window
@@ -62,7 +69,7 @@
def GetDisplay(self):
"""!Get display instance"""
return self._display
-
+
class GLWindow(MapWindow, glcanvas.GLCanvas):
"""!OpenGL canvas for Map Display Window"""
def __init__(self, parent, id = wx.ID_ANY,
@@ -81,21 +88,41 @@
self.render = { 'quick' : False,
# do not render vector lines in quick mode
'vlines' : False,
- 'vpoints' : False }
-
+ 'vpoints' : False,
+ 'overlays': False }
+ self.mouse = {
+ 'use': 'pointer'
+ }
+ self.cursors = {
+ 'default' : wx.StockCursor(wx.CURSOR_ARROW),
+ 'cross' : wx.StockCursor(wx.CURSOR_CROSS),
+ }
# list of loaded map layers (layer tree items)
self.layers = list()
+ # list of constant surfaces
+ self.constants = list()
+ # id of base surface (when vector is loaded and no surface exist)
+ self.baseId = -1
+ # list of cutting planes
+ self.cplanes = list()
# list of query points
self.qpoints = list()
+ # list of past views
+ self.viewhistory = []
+ self.saveHistory = False
+ # offset for dialog (e.g. DisplayAttributesDialog)
+ self.dialogOffset = 5
+ # overlays
+ self.overlays = {}
+ self.imagelist = []
+ self.overlay = wx.Overlay()
+ #self.pdc = wx.PseudoDC()
+ self.textdict = {}
+ self.dragid = -1
+ self.hitradius = 5
+ # layer manager toolwindow
+ self.toolWin = None
- #
- # use display region instead of computational
- #
- os.environ['GRASS_REGION'] = self.Map.SetRegion()
-
- #
- # create nviz instance
- #
if self.lmgr:
self.log = self.lmgr.goutput
logerr = self.lmgr.goutput.GetLog(err = True)
@@ -104,6 +131,9 @@
self.log = logmsg = sys.stdout
logerr = sys.stderr
+ # create nviz instance - use display region instead of computational
+ os.environ['GRASS_REGION'] = self.Map.SetRegion(windres = True)
+
self.nvizThread = NvizThread(logerr,
self.parent.statusbarWin['progress'],
logmsg)
@@ -117,33 +147,171 @@
self.img = wx.Image(self.Map.mapfile, wx.BITMAP_TYPE_ANY)
# size of MapWindow, to avoid resizing if size is the same
- self.size = (0,0)
+ self.size = (0, 0)
- #
# default values
- #
+ self.nvizDefault = NvizDefault()
self.view = copy.deepcopy(UserSettings.Get(group = 'nviz', key = 'view')) # copy
self.iview = UserSettings.Get(group = 'nviz', key = 'view', internal = True)
-
- self.nvizDefault = NvizDefault()
self.light = copy.deepcopy(UserSettings.Get(group = 'nviz', key = 'light')) # copy
+ self.decoration = self.nvizDefault.SetDecorDefaultProp(type = 'arrow')
+ self.decoration['scalebar'] = []
+ self.decoration['arrow']['size'] = self._getDecorationSize()
+ self.fly = self.InitFly()
+ # timer for flythrough
+ self.timerFly = wx.Timer(self, id = wx.NewId())
+ # timer for animations
+ self.timerAnim = wx.Timer(self, id = wx.NewId())
+ self.animation = Animation(mapWindow = self, timer = self.timerAnim)
+
self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
self.Bind(wx.EVT_SIZE, self.OnSize)
self.Bind(wx.EVT_PAINT, self.OnPaint)
- self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
+ self._bindMouseEvents()
+
+ self.Bind(EVT_UPDATE_PROP, self.UpdateMapObjProperties)
+ self.Bind(EVT_UPDATE_VIEW, self.OnUpdateView)
+ self.Bind(EVT_UPDATE_LIGHT, self.UpdateLight)
+ self.Bind(EVT_UPDATE_CPLANE, self.UpdateCPlane)
+
+ self.Bind(wx.EVT_TIMER, self.OnTimerAnim, self.timerAnim)
+ self.Bind(wx.EVT_TIMER, self.OnTimerFly, self.timerFly)
+ self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
+ self.Bind(wx.EVT_KEY_UP, self.OnKeyUp)
+
+ self.Bind(wx.EVT_CLOSE, self.OnClose)
+
+ # cplanes cannot be initialized now
+ wx.CallAfter(self.InitCPlanes)
+
+ def InitFly(self):
+ """!Initialize fly through dictionary"""
+ fly = {'interval' : 10, # interval for timerFly
+ 'value': [0, 0, 0], # calculated values for navigation
+ 'mode' : 0, # fly through mode (0, 1)
+ 'exag' : { # sensitivity
+ 'move' : UserSettings.Get(group = 'nviz', key = 'fly', subkey = ['exag', 'move']),
+ 'turn' : UserSettings.Get(group = 'nviz', key = 'fly', subkey = ['exag', 'turn'])},
+ 'exagMultiplier' : 3, # speed up by Shift
+ 'flySpeed' : 4, # speed of flying
+ 'mouseControl' : None, # if mouse or keys are used
+ 'pos' : {'x' : 0, 'y' : 0}, # virtual mouse position when using arrows
+ 'arrowStep' : 50, # step in pixels (when using arrows)
+ 'flySpeedStep' : 2,
+ }
+
+ return fly
+
+ def OnTimerFly(self, event):
+ """!Fly event was emitted, move the scene"""
+ if self.mouse['use'] != 'fly':
+ return
+
+ if self.fly['mouseControl']:
+ mx, my = self.ComputeMxMy(*self.mouse['tmp'])
+ else:
+ mx, my = self.ComputeMxMy(self.fly['pos']['x'], self.fly['pos']['y'])
+
+ self.ComputeFlyValues(mx = mx, my = my)
+ self._display.FlyThrough(flyInfo = self.fly['value'], mode = self.fly['mode'],
+ exagInfo = self.fly['exag'])
+ self.ChangeInnerView()
+ self.render['quick'] = True
+ self.Refresh(False)
+
+ def ComputeMxMy(self, x, y):
+ """!Compute values for flythrough navigation
+ (ComputeFlyValues should follow).
+
+ Based on visualization/nviz/src/togl_flythrough.c.
+ @param x,y screen coordinates
+ """
+ sx, sy = self.GetClientSizeTuple()
+ dx = dy = 0.01
+
+ mx = 2 * (float(x) / sx) - 1
+ my = 2 * (float(y) / sy) - 1
+
+ if mx < - dx:
+ mx += dx
+ elif mx > dx:
+ mx -= dx
+ else:
+ mx = 0.0 # ?
+ if my < - dy:
+ my += dy
+ elif my > dy:
+ my -= dy
+ else:
+ my = 0.0
+
+ mx = mx / (1.0 - dx)
+ my = my / (1.0 - dy)
+
+ # Quadratic seems smoother
+ mx *= abs(mx)
+ my *= abs(my)
+
+ return mx, my
+
+ def ComputeFlyValues(self, mx, my):
+ """!Compute parameters for fly-through navigation
+
+ @params mx,my results from ComputeMxMy method
+ """
+ self.fly['value'] = [0, 0, 0]
+
+ if self.fly['mode'] == 0:
+ self.fly['value'][0] = self.fly['flySpeed'] * self.fly['interval'] / 1000. # forward */
+ self.fly['value'][1] = mx * 0.1 * self.fly['interval'] / 1000. # heading
+ self.fly['value'][2] = my * 0.1 * self.fly['interval'] / 1000. # pitch
+ else:
+ self.fly['value'][0] = mx * 100.0 * self.fly['interval'] /1000.
+ self.fly['value'][2] = - my * 100.0 * self.fly['interval'] /1000.
+
+ def ChangeFlySpeed(self, increase):
+ """!Increase/decrease flight spped"""
+ if increase:
+ self.fly['flySpeed'] += self.fly['flySpeedStep']
+ else:
+ self.fly['flySpeed'] -= self.fly['flySpeedStep']
+
+ def __del__(self):
+ """!Stop timers if running, unload data"""
+ self.StopTimer(self.timerAnim)
+ self.StopTimer(self.timerFly)
+ self.UnloadDataLayers(force = True)
+
+ def StopTimer(self, timer):
+ """!Stop timer if running"""
+ if timer.IsRunning():
+ timer.Stop()
+
+ def _bindMouseEvents(self):
self.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouseAction)
self.Bind(wx.EVT_MOTION, self.OnMotion)
- self.Bind(EVT_UPDATE_PROP, self.UpdateMapObjProperties)
- self.Bind(EVT_UPDATE_VIEW, self.UpdateView)
- self.Bind(EVT_UPDATE_LIGHT, self.UpdateLight)
+ def InitCPlanes(self):
+ """!Initialize cutting planes list"""
+ for i in range(self._display.GetCPlanesCount()):
+ cplane = copy.deepcopy(UserSettings.Get(group = 'nviz', key = 'cplane'))
+ cplane['on'] = False
+ self.cplanes.append(cplane)
- self.Bind(wx.EVT_CLOSE, self.OnClose)
+ def SetToolWin(self, toolWin):
+ """!Sets reference to nviz toolwindow in layer manager"""
+ self.toolWin = toolWin
+ def GetToolWin(self):
+ """!Returns reference to nviz toolwindow in layer manager"""
+ return self.toolWin
+
def OnClose(self, event):
+ self.StopTimer(self.timerAnim)
+ self.StopTimer(self.timerFly)
# cleanup when window actually closes (on quit) and not just is hidden
- self.Reset()
+ self.UnloadDataLayers(force = True)
def OnEraseBackground(self, event):
pass # do nothing, to avoid flashing on MSW
@@ -157,13 +325,26 @@
self.SetCurrent()
self._display.ResizeWindow(size.width,
size.height)
+
+ # reposition checkbox in statusbar
+ self.parent.StatusbarReposition()
+
+ # update statusbar
+ self.parent.StatusbarUpdate()
+
self.size = size
+
event.Skip()
-
+
def OnPaint(self, event):
Debug.msg(1, "GLCanvas.OnPaint()")
+ self.render['overlays'] = True
dc = wx.PaintDC(self)
+ self.DoPaint()
+
+
+ def DoPaint(self):
self.SetCurrent()
if not self.initView:
@@ -179,6 +360,9 @@
if hasattr(self.lmgr, "nviz"):
self.lmgr.nviz.UpdatePage('view')
self.lmgr.nviz.UpdatePage('light')
+ self.lmgr.nviz.UpdatePage('cplane')
+ self.lmgr.nviz.UpdatePage('decoration')
+ self.lmgr.nviz.UpdatePage('animation')
layer = self.GetSelectedLayer()
if layer:
if layer.type == 'raster':
@@ -187,7 +371,7 @@
elif layer.type == 'vector':
self.lmgr.nviz.UpdatePage('vector')
- ### self.lmgr.nviz.UpdateSettings()
+ self.lmgr.nviz.UpdateSettings()
# update widgets
win = self.lmgr.nviz.FindWindowById( \
@@ -197,42 +381,328 @@
self.init = True
self.UpdateMap()
+
+ def DrawImages(self):
+ """!Draw overlay image"""
+ for texture in self.imagelist:
+ if texture.IsActive():
+ texture.Draw()
+
+ def GetLegendRect(self):
+ """!Estimates legend size for dragging"""
+ size = None
+ if 1 in self.overlays:
+ for param in self.overlays[1]['cmd'][1:]:
+ if param.startswith("at="):
+ size = map(int, param.split("=")[-1].split(','))
+ break
+ if size:
+ wSize = self.GetClientSizeTuple()
+ x, y = size[2]/100. * wSize[0], wSize[1] - (size[1]/100. * wSize[1])
+ x += self.overlays[1]['coords'][0]
+ y += self.overlays[1]['coords'][1]
+ w = (size[3] - size[2])/100. * wSize[0]
+ h = (size[1] - size[0])/100. * wSize[1]
+
+ rect = wx.Rect(x, y, w, h)
+ return rect
+
+ return wx.Rect()
+
+ def DrawTextImage(self, textDict, relCoords):
+ """!Draw overlay text"""
+ bmp = wx.EmptyBitmap(textDict['bbox'][2], textDict['bbox'][3])
+ memDC = wx.MemoryDC()
+ memDC.SelectObject(bmp)
+
+ mask = self.view['background']['color']
+ if mask == textDict['color']:
+ mask = wx.WHITE
+ memDC.SetBackground(wx.Brush(mask))
+ memDC.Clear()
+ memDC.SetFont(textDict['font'])
+ memDC.SetTextForeground(textDict['color'])
+ if textDict['rotation'] == 0:
+ memDC.DrawText(textDict['text'], 0, 0)
+ else:
+ memDC.DrawRotatedText(textDict['text'], relCoords[0], relCoords[1],
+ textDict['rotation'])
+ bmp.SetMaskColour(mask)
+ memDC.DrawBitmap(bmp, 0, 0, 1)
+
+ filename = tempfile.mktemp() + '.png'
+ bmp.SaveFile(filename, wx.BITMAP_TYPE_PNG)
+ memDC.SelectObject(wx.NullBitmap)
+
+ return filename
+
+ def UpdateOverlays(self):
+ """!Converts rendered overlay files and text labels to wx.Image
+ and then to textures so that they can be rendered by OpenGL.
+ Updates self.imagelist"""
+ self.Map.ChangeMapSize(self.GetClientSize())
+ self.Map.RenderOverlays(force = True)
+
+ # delete textures
+ for texture in self.imagelist:
+ # inactive overlays, remove text labels
+ if texture.GetId() < 100:
+ if not self.overlays[texture.GetId()]['layer'].IsActive():
+ texture.SetActive(False)
+ else:
+ texture.SetActive(True)
+ else: # text label
+ if texture.GetId() not in self.textdict:
+ self.imagelist.remove(texture)
+
+ # update images (only legend so far)
+ for oid, overlay in self.overlays.iteritems():
+ layer = overlay['layer']
+ if not layer.IsActive() or oid == 0: # 0 for barscale
+ continue
+ if oid not in [t.GetId() for t in self.imagelist]: # new
+ self.CreateTexture(overlay = layer)
+ else:
+ for t in self.imagelist:
+ if t.GetId() == oid: # check if it is the same
+ if not t.Corresponds(layer):
+ self.imagelist.remove(t)
+ t = self.CreateTexture(overlay = layer)
+ # always set coordinates, needed for synchr. 2D and 3D modes
+ t.SetCoords(overlay['coords'])
+
+
+ # update text labels
+ for textId in self.textdict.keys():
+ if textId not in [t.GetId() for t in self.imagelist]:# new
+ self.CreateTexture(textId = textId)
+ else:
+ for t in self.imagelist:
+ if t.GetId() == textId: # check if it is the same
+ self.textdict[textId]['bbox'] = t.textDict['bbox']
+ if not t.Corresponds(self.textdict[textId]):
+ self.imagelist.remove(t)
+ t = self.CreateTexture(textId = textId)
+ # always set coordinates, needed for synchr. 2D and 3D modes
+ t.SetCoords(self.textdict[textId]['coords'])
+
+ def CreateTexture(self, overlay = None, textId = None):
+ """!Create texture from overlay image or from textdict"""
+ if overlay: # legend
+ texture = wxnviz.ImageTexture(filepath = overlay.mapfile, overlayId = overlay.id,
+ coords = list(self.overlays[overlay.id]['coords']),
+ cmd = overlay.GetCmd())
+ if overlay.id == 1: # legend
+ texture.SetBounds(self.GetLegendRect())
+ else: # text
+ coords, bbox, relCoords = self.TextBounds(self.textdict[textId])
+ self.textdict[textId]['coords'] = coords
+ self.textdict[textId]['bbox'] = bbox
+ file = self.DrawTextImage(self.textdict[textId], relCoords)
+ texture = wxnviz.TextTexture(filepath = file, overlayId = textId,
+ coords = coords, textDict = self.textdict[textId])
+ bbox.OffsetXY(*relCoords)
+ texture.SetBounds(bbox)
+
+ if not texture.textureId: # texture too big
+ gcmd.GMessage(parent = self, message =
+ _("Image is too large, your OpenGL implementation "
+ "supports maximum texture size %d px.") % texture.maxSize)
+ return texture
+
+ self.imagelist.append(texture)
+
+ return texture
+
+ def FindObjects(self, mouseX, mouseY, radius):
+ """Find object which was clicked on"""
+ for texture in self.imagelist:
+ if texture.HitTest(mouseX, mouseY, radius):
+ return texture.id
+ return -1
+
+ def OnTimerAnim(self, event):
+ self.animation.Update()
+
+ def GetAnimation(self):
+ return self.animation
+
+ def OnKeyDown(self, event):
+ """!Key was pressed.
+
+ Used for fly-through mode.
+ """
+ if not self.mouse['use'] == 'fly':
+ return
+
+ key = event.GetKeyCode()
+ if key == wx.WXK_CONTROL: # Mac ?
+ self.fly['mode'] = 1
+
+ elif key == wx.WXK_SHIFT:
+ self.fly['exag']['move'] *= self.fly['exagMultiplier']
+ self.fly['exag']['turn'] *= self.fly['exagMultiplier']
+
+ elif key == wx.WXK_ESCAPE and self.timerFly.IsRunning() and not self.fly['mouseControl']:
+ self.StopTimer(self.timerFly)
+ self.fly['mouseControl'] = None
+ self.render['quick'] = False
+ self.Refresh(False)
+
+ elif key in (wx.WXK_UP, wx.WXK_DOWN, wx.WXK_LEFT, wx.WXK_RIGHT):
+ if not self.fly['mouseControl']:
+ if not self.timerFly.IsRunning():
+ sx, sy = self.GetClientSizeTuple()
+ self.fly['pos']['x'] = sx / 2
+ self.fly['pos']['y'] = sy / 2
+ self.fly['mouseControl'] = False # controlled by keyboard
+ self.timerFly.Start(self.fly['interval'])
+
+ self.ProcessFlyByArrows(keyCode = key)
+ # change speed of flight when using mouse
+ else:
+ if key == wx.WXK_UP:
+ self.ChangeFlySpeed(increase = True)
+ elif key == wx.WXK_DOWN:
+ self.ChangeFlySpeed(increase = False)
+
+ elif key in (wx.WXK_HOME, wx.WXK_PAGEUP) and self.timerFly.IsRunning():
+ self.ChangeFlySpeed(increase = True)
+ elif key in (wx.WXK_END, wx.WXK_PAGEDOWN) and self.timerFly.IsRunning():
+ self.ChangeFlySpeed(increase = False)
+
+ event.Skip()
+
+ def ProcessFlyByArrows(self, keyCode):
+ """!Process arrow key during fly-through"""
+ step = self.fly['arrowStep']
+ if keyCode == wx.WXK_UP:
+ self.fly['pos']['y'] -= step
+ elif keyCode == wx.WXK_DOWN:
+ self.fly['pos']['y'] += step
+ elif keyCode == wx.WXK_LEFT:
+ self.fly['pos']['x'] -= step
+ elif keyCode == wx.WXK_RIGHT:
+ self.fly['pos']['x'] += step
+
+ def OnKeyUp(self, event):
+ """!Key was released.
+
+ Used for fly-through mode.
+ """
+ if not self.mouse['use'] == 'fly':
+ return
+
+ key = event.GetKeyCode()
+ if key == wx.WXK_CONTROL: # Mac ?
+ self.fly['mode'] = 0
+ elif key == wx.WXK_SHIFT:
+ self.fly['exag']['move'] = math.floor(self.fly['exag']['move'] / self.fly['exagMultiplier'])
+ self.fly['exag']['turn'] = math.floor(self.fly['exag']['turn'] / self.fly['exagMultiplier'])
+
+ event.Skip()
+
def OnMouseAction(self, event):
- # change perspective with mouse wheel
+ """!Handle mouse events"""
+ # zoom with mouse wheel
+ if event.GetWheelRotation() != 0:
+ self.OnMouseWheel(event)
+
+ # left mouse button pressed
+ elif event.LeftDown():
+ self.OnLeftDown(event)
+
+ # left mouse button released
+ elif event.LeftUp():
+ self.OnLeftUp(event)
+
+ # dragging
+ elif event.Dragging():
+ self.OnDragging(event)
+
+ # double click
+ elif event.ButtonDClick():
+ self.OnDClick(event)
+
+ event.Skip()
+
+ def OnMouseWheel(self, event):
+ """!Change perspective"""
wheel = event.GetWheelRotation()
-
- if wheel != 0:
- current = event.GetPositionTuple()[:]
- Debug.msg (5, "GLWindow.OnMouseMotion(): wheel = %d" % wheel)
- prev_value = self.view['persp']['value']
+ Debug.msg (5, "GLWindow.OnMouseMotion(): wheel = %d" % wheel)
+ if self.timerFly.IsRunning() and self.fly['mouseControl']:
if wheel > 0:
- value = -1 * self.view['persp']['step']
+ self.ChangeFlySpeed(increase = True)
else:
- value = self.view['persp']['step']
- self.view['persp']['value'] += value
- if self.view['persp']['value'] < 1:
- self.view['persp']['value'] = 1
- elif self.view['persp']['value'] > 100:
- self.view['persp']['value'] = 100
+ self.ChangeFlySpeed(increase = False)
+ else:
+ self.DoZoom(zoomtype = wheel, pos = event.GetPositionTuple())
- if prev_value != self.view['persp']['value']:
- if hasattr(self.lmgr, "nviz"):
- self.lmgr.nviz.UpdateSettings()
-
- self._display.SetView(self.view['position']['x'], self.view['position']['y'],
- self.iview['height']['value'],
- self.view['persp']['value'],
- self.view['twist']['value'])
+ # update statusbar
+ ### self.parent.StatusbarUpdate()
+
+ def OnLeftDown(self, event):
+ """!On left mouse down"""
+ self.mouse['begin'] = event.GetPositionTuple()
+ self.mouse['tmp'] = event.GetPositionTuple()
+ if self.mouse['use'] == "lookHere":
+ size = self.GetClientSize()
+ self._display.LookHere(self.mouse['begin'][0], size[1] - self.mouse['begin'][1])
+ focus = self._display.GetFocus()
+ for i, coord in enumerate(('x', 'y', 'z')):
+ self.iview['focus'][coord] = focus[i]
+ self.saveHistory = True
+ self.Refresh(False)
+ toggle = self.lmgr.nviz.FindWindowByName('here')
+ toggle.SetValue(False)
+ self.mouse['use'] = 'pointer'
+ self.SetCursor(self.cursors['default'])
- # redraw map
- self.OnPaint(None)
+ if self.mouse['use'] == 'arrow':
+ pos = event.GetPosition()
+ size = self.GetClientSize()
+ self.SetDrawArrow((pos[0], size[1] - pos[1]))
- # update statusbar
- ### self.parent.StatusbarUpdate()
+ if self.mouse['use'] == 'scalebar':
+ pos = event.GetPosition()
+ size = self.GetClientSize()
+ self.SetDrawScalebar((pos[0], size[1] - pos[1]))
+ if self.mouse['use'] == 'pointer':
+ # get decoration or text id
+ self.dragid = self.FindObjects(self.mouse['tmp'][0], self.mouse['tmp'][1],
+ self.hitradius)
+
+ if self.mouse['use'] == 'fly':
+ if not self.timerFly.IsRunning():
+ self.timerFly.Start(self.fly['interval'])
+ self.fly['mouseControl'] = True
+
+ event.Skip()
+
+ def OnDragging(self, event):
+ if self.mouse['use'] == 'pointer':
+ if self.dragid > 0:
+
+ self.DragItem(self.dragid, event)
+
+ if self.mouse['use'] == 'rotate':
+ dx, dy = event.GetX() - self.mouse['tmp'][0], event.GetY() - self.mouse['tmp'][1]
+
+ angle, x, y, z = self._display.GetRotationParameters(dx, dy)
+ self._display.Rotate(angle, x, y, z)
+
+ self.render['quick'] = True
+ self.Refresh(False)
+
+ if self.mouse['use'] == 'pan':
+ self.FocusPanning(event)
+
+ self.mouse['tmp'] = event.GetPositionTuple()
+
event.Skip()
-
+
def Pixel2Cell(self, (x, y)):
"""!Convert image coordinates to real word coordinates
@@ -243,28 +713,306 @@
"""
size = self.GetClientSize()
# UL -> LL
- sid, x, y, z = self._display.GetPointOnSurface(x, y)
+ sid, x, y, z = self._display.GetPointOnSurface(x, size[1] - y)
if not sid:
return None
return (x, y)
+ def DoZoom(self, zoomtype, pos):
+ """!Change perspective and focus"""
+
+ prev_value = self.view['persp']['value']
+ if zoomtype > 0:
+ value = -1 * self.view['persp']['step']
+ else:
+ value = self.view['persp']['step']
+ self.view['persp']['value'] += value
+ if self.view['persp']['value'] < 1:
+ self.view['persp']['value'] = 1
+ elif self.view['persp']['value'] > 180:
+ self.view['persp']['value'] = 180
+
+ if prev_value != self.view['persp']['value']:
+ if hasattr(self.lmgr, "nviz"):
+ self.lmgr.nviz.UpdateSettings()
+ x, y = pos[0], self.GetClientSize()[1] - pos[1]
+ result = self._display.GetPointOnSurface(x, y)
+ if result[0]:
+ self._display.LookHere(x, y)
+ focus = self._display.GetFocus()
+ for i, coord in enumerate(('x', 'y', 'z')):
+ self.iview['focus'][coord] = focus[i]
+ self._display.SetView(self.view['position']['x'], self.view['position']['y'],
+ self.iview['height']['value'],
+ self.view['persp']['value'],
+ self.view['twist']['value'])
+ self.saveHistory = True
+ # redraw map
+ self.DoPaint()
+
def OnLeftUp(self, event):
- self.ReleaseMouse()
- if self.mouse["use"] == "nvizQuerySurface":
- self.OnQuerySurface(event)
- elif self.mouse["use"] == "nvizQueryVector":
- self.OnQueryVector(event)
+ self.mouse['end'] = event.GetPositionTuple()
+ if self.mouse["use"] == "query":
+ # querying
+ layers = self.GetSelectedLayer(multi = True)
+ isRaster = False
+ nVectors = 0
+ for l in layers:
+ if l.GetType() == 'raster':
+ isRaster = True
+ break
+ if l.GetType() == 'vector':
+ nVectors += 1
+
+ if isRaster or nVectors > 1:
+ self.OnQueryMap(event)
+ else:
+ self.OnQueryVector(event)
+
+ elif self.mouse["use"] in ('arrow', 'scalebar'):
+ self.lmgr.nviz.FindWindowById(
+ self.lmgr.nviz.win['decoration'][self.mouse["use"]]['place']).SetValue(False)
+ self.mouse['use'] = 'pointer'
+ self.SetCursor(self.cursors['default'])
+ elif self.mouse['use'] == 'pointer':
+ if self.dragid > 0:
+ dx = self.mouse['end'][0] - self.mouse['begin'][0]
+ dy = self.mouse['end'][1] - self.mouse['begin'][1]
+ if self.dragid < 99:
+ coords = self.overlays[self.dragid]['coords']
+ self.overlays[self.dragid]['coords'] = [coords[0] + dx, coords[1] + dy]
+ else: # text
+ coords = self.textdict[self.dragid]['coords']
+ self.textdict[self.dragid]['coords'] = [coords[0] + dx, coords[1] + dy]
+ self.dragid = -1
+ self.render['quick'] = False
+ self.Refresh(False)
+
+ elif self.mouse['use'] == 'rotate':
+ self._display.UnsetRotation()
+ self.iview['rotation'] = self._display.GetRotationMatrix()
+ self.saveHistory = True
+ self.render['quick'] = False
+ self.Refresh(False)
+
+ elif self.mouse['use'] == 'pan':
+ self.saveHistory = True
+ self.render['quick'] = False
+ self.Refresh(False)
+
+ elif self.mouse['use'] == 'fly':
+ if self.fly['mouseControl']:
+ self.StopTimer(self.timerFly)
+ self.fly['mouseControl'] = None
+ #for key in self.iview['dir'].keys():
+ #self.iview[''][key] = -1
+ # this causes sudden change, but it should be there
+ #if hasattr(self.lmgr, "nviz"):
+ #self.lmgr.nviz.UpdateSettings()
+
+ self.render['quick'] = False
+ self.Refresh(False)
+
+ elif self.mouse['use'] == 'zoom':
+ self.DoZoom(zoomtype = self.zoomtype, pos = self.mouse['end'])
+ event.Skip()
+
+ def OnDClick(self, event):
+ """!On mouse double click"""
+ if self.mouse['use'] != 'pointer': return
+ pos = event.GetPositionTuple()
+ self.dragid = self.FindObjects(pos[0], pos[1], self.hitradius)
+
+ if self.dragid == 1:
+ self.parent.OnAddLegend(None)
+ elif self.dragid > 100:
+ self.parent.OnAddText(None)
+ else:
+ return
+ def FocusPanning(self, event):
+ """!Simulation of panning using focus"""
+ size = self.GetClientSizeTuple()
+ id1, x1, y1, z1 = self._display.GetPointOnSurface(
+ self.mouse['tmp'][0], size[1] - self.mouse['tmp'][1])
+ id2, x2, y2, z2 = self._display.GetPointOnSurface(
+ event.GetX(), size[1] - event.GetY())
+ if id1 and id1 == id2:
+ dx, dy, dz = x2 - x1, y2 - y1, z2 - z1
+ focus = self.iview['focus']
+ focus['x'], focus['y'], focus['z'] = self._display.GetFocus()
+ focus['x'] -= dx
+ focus['y'] -= dy
+ focus['z'] -= dz
+
+ #update properties
+ self.PostViewEvent()
+
+ self.mouse['tmp'] = event.GetPositionTuple()
+ self.render['quick'] = True
+ self.Refresh(False)
+
+ def HorizontalPanning(self, event):
+ """!Move all layers in horizontal (x, y) direction.
+ Currently not used.
+ """
+ size = self.GetClientSizeTuple()
+ id1, x1, y1, z1 = self._display.GetPointOnSurface(
+ self.mouse['tmp'][0], size[1] - self.mouse['tmp'][1])
+ id2, x2, y2, z2 = self._display.GetPointOnSurface(
+ event.GetX(), size[1] - event.GetY())
+
+ if id1 and id1 == id2:
+ dx, dy = x2 - x1, y2 - y1
+ # find raster and volume
+ for item in self.layers:
+ mapLayer = self.tree.GetPyData(item)[0]['maplayer']
+
+ data = self.tree.GetPyData(item)[0]['nviz']
+ if mapLayer.GetType() == 'raster':
+ data['surface']['position']['x'] += dx
+ data['surface']['position']['y'] += dy
+ data['surface']['position']['update'] = None
+
+ #update properties
+ evt = wxUpdateProperties(data = data)
+ wx.PostEvent(self, evt)
+
+ if event.CmdDown() and id1 == data['surface']['object']['id']:
+ break
+
+ elif mapLayer.GetType() == '3d-raster':
+ if 'x' not in data['volume']['position']:
+ data['volume']['position']['x'] = 0
+ data['volume']['position']['y'] = 0
+ data['volume']['position']['z'] = 0
+ data['volume']['position']['x'] += dx
+ data['volume']['position']['y'] += dy
+ data['volume']['position']['update'] = None
+
+ #update properties
+ evt = wxUpdateProperties(data = data)
+ wx.PostEvent(self, evt)
+
+ self.mouse['tmp'] = event.GetPositionTuple()
+ self.render['quick'] = True
+ self.Refresh(False)
+
+ def DragItem(self, id, event):
+ """!Drag an overlay decoration item
+ """
+ if not id: return
+ Debug.msg (5, "GLWindow.DragItem(): id=%d" % id)
+ x, y = self.mouse['tmp']
+ dx = event.GetX() - x
+ dy = event.GetY() - y
+ for texture in self.imagelist:
+ if texture.id == id:
+ texture.MoveTexture(dx, dy)
+
+
+ self.render['quick'] = True
+ self.Refresh(False)
+
+ self.mouse['tmp'] = (event.GetX(), event.GetY())
+
+ def ZoomBack(self):
+ """!Set previous view in history list
+ """
+ view = {}
+ if len(self.viewhistory) > 1:
+ self.viewhistory.pop()
+ view = copy.deepcopy(self.viewhistory[-1])
+
+ # disable tool if stack is empty
+ if len(self.viewhistory) < 2: # disable tool
+ toolbar = self.parent.toolbars['map']
+ toolbar.Enable('zoomback', enable = False)
+
+ # set view and update nviz view page
+ self.lmgr.nviz.UpdateState(view = view[0], iview = view[1])
+ self.lmgr.nviz.UpdatePage('view')
+ # update map
+ self.Refresh(False)
+
+ def ViewHistory(self, view, iview):
+ """!Manages a list of last 10 views
+
+ @param view view dictionary
+ @param iview view dictionary (internal)
+
+ @return removed history item if exists (or None)
+ """
+ removed = None
+ hview = copy.deepcopy(view)
+ hiview = copy.deepcopy(iview)
+
+ if not (self.viewhistory and self.viewhistory[-1] == (hview, hiview)):
+ self.viewhistory.append((hview, hiview))
+
+ if len(self.viewhistory) > 10:
+ removed = self.viewhistory.pop(0)
+
+ if removed:
+ Debug.msg(4, "GLWindow.ViewHistory(): hist=%s, removed=%s" %
+ (self.viewhistory, removed))
+ else:
+ Debug.msg(4, "GLWindow.ViewHistory(): hist=%s" %
+ (self.viewhistory))
+
+ # update toolbar
+ if len(self.viewhistory) > 1:
+ enable = True
+ else:
+ enable = False
+
+ toolbar = self.parent.toolbars['map']
+ toolbar.Enable('zoomback', enable)
+
+ return removed
+
+ def ResetViewHistory(self):
+ """!Reset view history"""
+ self.viewhistory = list()
+
+ def GoTo(self, e, n):
+ """!Focus on given point"""
+ w = self.Map.region['w']
+ s = self.Map.region['s']
+ e -= w
+ n -= s
+ focus = self.iview['focus']
+ focus['x'], focus['y'] = e, n
+ self.saveHistory = True
+ #update properties
+ self.PostViewEvent()
+
+ self.render['quick'] = False
+ self.Refresh(False)
+
+ def OnQueryMap(self, event):
+ """!Query raster and vector maps"""
+ self.OnQuerySurface(event)
+ self.parent.QueryMap(event.GetX(), event.GetY())
+
def OnQuerySurface(self, event):
"""!Query surface on given position"""
- result = self._display.QueryMap(event.GetX(), event.GetY())
+ size = self.GetClientSizeTuple()
+ result = self._display.QueryMap(event.GetX(), size[1] - event.GetY())
if result:
self.qpoints.append((result['x'], result['y'], result['z']))
self.log.WriteLog("%-30s: %.3f" % (_("Easting"), result['x']))
self.log.WriteLog("%-30s: %.3f" % (_("Northing"), result['y']))
self.log.WriteLog("%-30s: %.3f" % (_("Elevation"), result['z']))
+ name = ''
+ for item in self.layers:
+ self.tree.GetPyData(item)[0]['nviz']
+ if self.tree.GetPyData(item)[0]['maplayer'].type == 'raster' and\
+ self.tree.GetPyData(item)[0]['nviz']['surface']['object']['id'] == result['id']:
+ name = self.tree.GetPyData(item)[0]['maplayer'].name
+ self.log.WriteLog("%-30s: %s" % (_("Surface map name"), name))
self.log.WriteLog("%-30s: %s" % (_("Surface map elevation"), result['elevation']))
self.log.WriteLog("%-30s: %s" % (_("Surface map color"), result['color']))
if len(self.qpoints) > 1:
@@ -292,25 +1040,62 @@
self.log.WriteLog(_("No point on surface"))
self.log.WriteCmdLog('-' * 80)
+ def PostViewEvent(self, zExag = False):
+ """!Change view settings"""
+ event = wxUpdateView(zExag = zExag)
+ wx.PostEvent(self, event)
+
def OnQueryVector(self, event):
"""!Query vector on given position"""
- self.log.WriteWarning(_("Function not implemented yet"))
- self.log.WriteCmdLog('-' * 80)
+ self.parent.QueryVector(*event.GetPosition())
+
+ def ChangeInnerView(self):
+ """!Get current viewdir and viewpoint and set view"""
+ view = self.view
+ iview = self.iview
+ (view['position']['x'], view['position']['y'],
+ iview['height']['value']) = self._display.GetViewpointPosition()
+ for key, val in zip(('x', 'y', 'z'), self._display.GetViewdir()):
+ iview['dir'][key] = val
- def UpdateView(self, event):
+ iview['dir']['use'] = True
+
+ def OnUpdateView(self, event):
"""!Change view settings"""
- data = self.view
- self._display.SetView(data['position']['x'], data['position']['y'],
- self.iview['height']['value'],
- data['persp']['value'],
- data['twist']['value'])
+ if event:
+ self.UpdateView(zexag = event.zExag)
+
+ self.saveHistory = True
+ if event:
+ event.Skip()
+
+
+ def UpdateView(self, zexag = False):
+ """!Change view settings"""
+ view = self.view
+ iview = self.iview
+ if zexag and 'value' in view['z-exag']:
+ self._display.SetZExag(self.iview['z-exag']['original'] * view['z-exag']['value'])
- if event and event.zExag and 'value' in data['z-exag']:
- self._display.SetZExag(data['z-exag']['value'])
- if event:
- event.Skip()
-
+ self._display.SetView(view['position']['x'], view['position']['y'],
+ iview['height']['value'],
+ view['persp']['value'],
+ view['twist']['value'])
+
+ if iview['dir']['use']:
+ self._display.SetViewdir(iview['dir']['x'], iview['dir']['y'], iview['dir']['z'])
+
+ elif iview['focus']['x'] != -1:
+ self._display.SetFocus(self.iview['focus']['x'], self.iview['focus']['y'],
+ self.iview['focus']['z'])
+
+ if 'rotation' in iview:
+ if iview['rotation']:
+ self._display.SetRotationMatrix(iview['rotation'])
+ else:
+ self._display.ResetRotation()
+
def UpdateLight(self, event):
"""!Change light settings"""
data = self.light
@@ -319,6 +1104,8 @@
bright = data['bright'] / 100.,
ambient = data['ambient'] / 100.)
self._display.DrawLightingModel()
+ if event.refresh:
+ self.Refresh(False)
def UpdateMap(self, render = True):
"""!Updates the canvas anytime there is a change to the
@@ -338,6 +1125,9 @@
if self.render['quick'] is False:
self.parent.statusbarWin['progress'].SetValue(1)
self._display.Draw(False, -1)
+ if self.saveHistory:
+ self.ViewHistory(view = self.view, iview = self.iview)
+ self.saveHistory = False
elif self.render['quick'] is True:
# quick
mode = wxnviz.DRAW_QUICK_SURFACE | wxnviz.DRAW_QUICK_VOLUME
@@ -348,9 +1138,24 @@
self._display.Draw(True, mode)
else: # None -> reuse last rendered image
pass # TODO
-
+
self.SwapBuffers()
-
+ # draw fringe after SwapBuffers, otherwise it don't have to be visible
+ # on some computers
+ if self.render['quick'] is False:
+ self._display.DrawFringe()
+ if self.decoration['arrow']['show']:
+ self._display.DrawArrow()
+ if self.decoration['scalebar']:
+ self._display.DrawScalebar()
+ if self.imagelist:
+ if ((self.render['quick'] and self.dragid > -1) or # during dragging
+ (not self.render['quick'] and self.dragid < 0)): # redraw
+ self._display.Start2D()
+ self.DrawImages()
+
+
+
stop = time.clock()
if self.render['quick'] is False:
@@ -366,7 +1171,47 @@
"""
self._display.EraseMap()
self.SwapBuffers()
+
+ def _getDecorationSize(self):
+ """!Get initial size of north arrow/scalebar"""
+ size = self._display.GetLongDim() / 8.
+ coef = 0.01
+ if size < 1:
+ coef = 100.
+ return int(size * coef)/coef
+
+ def SetDrawArrow(self, pos):
+ if self._display.SetArrow(pos[0], pos[1],
+ self.decoration['arrow']['size'],
+ self.decoration['arrow']['color']):
+ self._display.DrawArrow()
+ # update
+ self.decoration['arrow']['show'] = True
+ self.decoration['arrow']['position']['x'] = pos[0]
+ self.decoration['arrow']['position']['y'] = pos[1]
+ self.Refresh(False)
+
+ def SetDrawScalebar(self, pos):
+ """!Add scale bar, sets properties and draw"""
+ if len(self.decoration['scalebar']) == 0:
+ self.decoration['scalebar'].append(
+ self.nvizDefault.SetDecorDefaultProp(type = 'scalebar')['scalebar'])
+ self.decoration['scalebar'][0]['size'] = self._getDecorationSize()
+ else:
+ self.decoration['scalebar'].append(copy.deepcopy(self.decoration['scalebar'][-1]))
+ self.decoration['scalebar'][-1]['id'] += 1
+
+ ret = self._display.SetScalebar(self.decoration['scalebar'][-1]['id'], pos[0], pos[1],
+ self.decoration['scalebar'][-1]['size'],
+ self.decoration['scalebar'][-1]['color'])
+ if ret:
+ self._display.DrawScalebar()
+ # update
+ self.decoration['scalebar'][-1]['position']['x'] = pos[0]
+ self.decoration['scalebar'][-1]['position']['y'] = pos[1]
+ self.Refresh(False)
+
def IsLoaded(self, item):
"""!Check if layer (item) is already loaded
@@ -426,6 +1271,10 @@
type = self.tree.GetPyData(item)[0]['type']
if item in self.layers:
continue
+ # "raster (double click to set properties)" - tries to load this
+ # layer - no idea how to fix it
+ if ' ' in self.tree.GetPyData(item)[0]['maplayer'].name:
+ return
try:
if type == 'raster':
self.LoadRaster(item)
@@ -451,42 +1300,66 @@
stop = time.time()
- Debug.msg(3, "GLWindow.LoadDataLayers(): time = %f" % (stop-start))
+ Debug.msg(1, "GLWindow.LoadDataLayers(): time = %f" % (stop-start))
- def UnloadDataLayers(self):
- """!Unload any layers that have been deleted from layer tree"""
+ def UnloadDataLayers(self, force = False):
+ """!Unload any layers that have been deleted from layer tree
+
+ @param force True to unload all data layers
+ """
if not self.tree:
return
listOfItems = []
- item = self.tree.GetFirstChild(self.tree.root)[0]
- self._GetDataLayers(item, listOfItems)
+ if not force:
+ item = self.tree.GetFirstChild(self.tree.root)[0]
+ self._GetDataLayers(item, listOfItems)
start = time.time()
- for layer in self.layers:
- if layer not in listOfItems:
- ltype = self.tree.GetPyData(layer)[0]['type']
- try:
- if ltype == 'raster':
- self.UnloadRaster(layer)
- elif ltype == '3d-raster':
- self.UnloadRaster3d(layer)
- elif ltype == 'vector':
- self.UnloadVector(layer, True)
- self.UnloadVector(layer, False)
-
- self.UpdateView(None)
- except gcmd.GException, e:
- gcmd.GError(parent = self,
- message = e.value)
-
- self.lmgr.nviz.UpdateSettings()
+ update = False
+ layersTmp = self.layers[:]
+ for layer in layersTmp:
+ if layer in listOfItems:
+ continue
+ ltype = self.tree.GetPyData(layer)[0]['type']
+ try:
+ if ltype == 'raster':
+ self.UnloadRaster(layer)
+ elif ltype == '3d-raster':
+ self.UnloadRaster3d(layer)
+ elif ltype == 'vector':
+ maplayer = self.tree.GetPyData(layer)[0]['maplayer']
+ npoints, nlines, nfeatures, mapIs3D = self.lmgr.nviz.VectorInfo(maplayer)
+ if npoints > 0:
+ self.UnloadVector(layer, points = True)
+ if nlines > 0:
+ self.UnloadVector(layer, points = False)
+
+ except gcmd.GException, e:
+ gcmd.GError(parent = self,
+ message = e.value)
+ if force and self.baseId > 0: # unload base surface when quitting
+ ret = self._display.UnloadSurface(self.baseId)
+ self.baseId = -1
+ if update:
+ self.lmgr.nviz.UpdateSettings()
+ self.UpdateView(None)
+
stop = time.time()
- Debug.msg(3, "GLWindow.UnloadDataLayers(): time = %f" % (stop-start))
-
+ Debug.msg(1, "GLWindow.UnloadDataLayers(): time = %f" % (stop-start))
+
+ def SetVectorSurface(self, data):
+ """!Set reference surfaces of vector"""
+ data['mode']['surface'] = {}
+ data['mode']['surface']['value'] = list()
+ data['mode']['surface']['show'] = list()
+ for name in self.GetLayerNames('raster'):
+ data['mode']['surface']['value'].append(name)
+ data['mode']['surface']['show'].append(True)
+
def SetVectorFromCmd(self, item, data):
"""!Set 3D view properties from cmd (d.vect)
@@ -515,56 +1388,76 @@
@param id nviz layer id (or -1)
@param nvizType nviz data type (surface, points, vector)
"""
- type = self.tree.GetPyData(item)[0]['maplayer'].type
- # reference to original layer properties (can be None)
- data = self.tree.GetPyData(item)[0]['nviz']
+ if nvizType != 'constant':
+ mapType = self.tree.GetPyData(item)[0]['maplayer'].type
+ # reference to original layer properties (can be None)
+ data = self.tree.GetPyData(item)[0]['nviz']
+ else:
+ mapType = nvizType
+ data = self.constants[item]
if not data:
# init data structure
- self.tree.GetPyData(item)[0]['nviz'] = {}
- data = self.tree.GetPyData(item)[0]['nviz']
+ if nvizType != 'constant':
+ self.tree.GetPyData(item)[0]['nviz'] = {}
+ data = self.tree.GetPyData(item)[0]['nviz']
- if type == 'raster':
+ if mapType == 'raster':
# reset to default properties
data[nvizType] = self.nvizDefault.SetSurfaceDefaultProp()
- elif type == 'vector':
+ elif mapType == 'vector':
# reset to default properties (lines/points)
data['vector'] = self.nvizDefault.SetVectorDefaultProp()
self.SetVectorFromCmd(item, data['vector'])
+ self.SetVectorSurface(data['vector']['points'])
+ self.SetVectorSurface(data['vector']['lines'])
- elif type == '3d-raster':
+ elif mapType == '3d-raster':
# reset to default properties
data[nvizType] = self.nvizDefault.SetVolumeDefaultProp()
+
+ elif mapType == 'constant':
+ data['constant'] = self.nvizDefault.SetConstantDefaultProp()
else:
- # complete data (use default values)
- if type == 'raster':
- data['surface'] = self.nvizDefault.SetSurfaceDefaultProp()
- if type == 'vector':
+ # complete data (use default values), not sure if this is necessary
+ if mapType == 'raster':
+ if not data['surface']:
+ data['surface'] = self.nvizDefault.SetSurfaceDefaultProp()
+ if mapType == 'vector':
if not data['vector']['lines']:
self.nvizDefault.SetVectorLinesDefaultProp(data['vector']['lines'])
if not data['vector']['points']:
- self.nvizDefault.SetVectorPointsDefaultProp(data['vector']['points'])
-
+ self.nvizDefault.SetVectorPointsDefaultProp(data['vector']['points'])
# set updates
for sec in data.keys():
for sec1 in data[sec].keys():
- for sec2 in data[sec][sec1].keys():
- if sec2 != 'all':
- data[sec][sec1][sec2]['update'] = None
-
+ if sec1 == 'position':
+ data[sec][sec1]['update'] = None
+ continue
+ if type(data[sec][sec1]) == types.DictType:
+ for sec2 in data[sec][sec1].keys():
+ if sec2 not in ('all', 'init', 'id'):
+ data[sec][sec1][sec2]['update'] = None
+ elif type(data[sec][sec1]) == types.ListType:
+ for i in range(len(data[sec][sec1])):
+ for sec2 in data[sec][sec1][i].keys():
+ data[sec][sec1][i][sec2]['update'] = None
event = wxUpdateProperties(data = data)
wx.PostEvent(self, event)
# set id
if id > 0:
- if type in ('raster', '3d-raster'):
- data[nvizType]['object'] = { 'id' : id,
+ if mapType in ('raster', '3d-raster'):
+ data[nvizType]['object'] = { 'id' : id,
'init' : False }
- elif type == 'vector':
+ elif mapType == 'vector':
data['vector'][nvizType]['object'] = { 'id' : id,
'init' : False }
+ elif mapType == 'constant':
+ data[nvizType]['object'] = { 'id' : id,
+ 'init' : False }
return data
@@ -632,6 +1525,61 @@
return id
+ def NewConstant(self):
+ """!Create new constant"""
+ index = len(self.constants)
+ try:
+ name = self.constants[-1]['constant']['object']['name'] + 1
+ except IndexError:
+ name = 1
+ data = dict()
+ self.constants.append(data)
+ data = self.SetMapObjProperties(item = index, id = -1, nvizType = 'constant')
+ self.AddConstant(data, name)
+ return name
+
+ def AddConstant(self, data, name):
+ """!Add new constant"""
+ id = self._display.AddConstant(value = data['constant']['value'], color = data['constant']['color'])
+ self._display.SetSurfaceRes(id, data['constant']['resolution'], data['constant']['resolution'])
+ data['constant']['object'] = { 'id' : id,
+ 'name': name,
+ 'init' : False }
+
+ def DeleteConstant(self, index):
+ """!Delete constant layer"""
+ id = self.constants[index]['constant']['object']['id']
+ self._display.UnloadSurface(id)
+ del self.constants[index]
+
+ def SelectCPlane(self, index):
+ """!Select cutting plane"""
+ for plane in range (self._display.GetCPlanesCount()):
+ if plane == index:
+ self._display.SelectCPlane(plane)
+ self.cplanes[plane]['on'] = True
+ self._display.SetFenceColor(self.cplanes[plane]['shading'])
+ else:
+ self._display.UnselectCPlane(plane)
+ try:
+ self.cplanes[plane]['on'] = False
+ except IndexError:
+ pass
+
+ def UpdateCPlane(self, event):
+ """!Change cutting plane settings"""
+ current = event.current
+ for each in event.update:
+ if each == 'rotation':
+ self._display.SetCPlaneRotation(0, self.cplanes[current]['rotation']['tilt'],
+ self.cplanes[current]['rotation']['rot'])
+ if each == 'position':
+ self._display.SetCPlaneTranslation(self.cplanes[current]['position']['x'],
+ self.cplanes[current]['position']['y'],
+ self.cplanes[current]['position']['z'])
+ if each == 'shading':
+ self._display.SetFenceColor(self.cplanes[current]['shading'])
+
def UnloadRaster(self, item):
"""!Unload 2d raster map
@@ -669,7 +1617,10 @@
errorMsg = _("Unable to unload 3d raster map")
successMsg = _("3d raster map")
- id = data[nvizType]['object']['id']
+ try:
+ id = data[nvizType]['object']['id']
+ except KeyError:
+ return
if unloadFn(id) == 0:
self.log.WriteError("%s <%s>" % (errorMsg, layer.name))
@@ -681,19 +1632,27 @@
self.layers.remove(item)
# update tools window
- if hasattr(self.lmgr, "nviz") and \
- layer.type == 'raster':
+ if hasattr(self.lmgr, "nviz"):
toolWin = self.lmgr.nviz
- win = toolWin.FindWindowById( \
- toolWin.win['vector']['lines']['surface'])
- win.SetItems(self.GetLayerNames(layer.type))
-
- def LoadVector(self, item, points = None):
+ if layer.type == 'raster':
+ win = toolWin.FindWindowById(toolWin.win['vector']['lines']['surface'])
+ win.SetItems(self.GetLayerNames(layer.type))
+ win = toolWin.FindWindowById(toolWin.win['surface']['map'])
+ win.SetValue('')
+ if layer.type == '3d-raster':
+ win = toolWin.FindWindowById(toolWin.win['volume']['map'])
+ win.SetValue('')
+ if layer.type == 'vector':
+ win = toolWin.FindWindowById(toolWin.win['vector']['map'])
+ win.SetValue('')
+
+ def LoadVector(self, item, points = None, append = True):
"""!Load 2D or 3D vector map overlay
@param item layer item
@param points True to load points, False to load lines, None
to load both
+ @param append append vector to layer list
"""
layer = self.tree.GetPyData(item)[0]['maplayer']
if layer.type != 'vector':
@@ -714,17 +1673,19 @@
id = -1
for vecType in vecTypes:
if vecType == 'lines':
- id = self._display.LoadVector(str(layer.GetName()), False)
+ id, baseId = self._display.LoadVector(str(layer.GetName()), False)
else:
- id = self._display.LoadVector(str(layer.GetName()), True)
+ id, baseId = self._display.LoadVector(str(layer.GetName()), True)
if id < 0:
self.log.WriteError(_("Loading vector map <%(name)s> (%(type)s) failed") % \
{ 'name' : layer.name, 'type' : vecType })
# update layer properties
self.SetMapObjProperties(item, id, vecType)
+ if baseId > 0:
+ self.baseId = baseId # id of base surface (when no surface is loaded)
+ if append:
+ self.layers.append(item)
- self.layers.append(item)
-
# update properties
data = self.tree.GetPyData(item)[0]['nviz']
event = wxUpdateProperties(data = data)
@@ -740,11 +1701,12 @@
return id
- def UnloadVector(self, item, points = None):
+ def UnloadVector(self, item, points = None, remove = True):
"""!Unload vector map overlay
@param item layer item
@param points,lines True to unload given feature type
+ @param remove remove layer from list
"""
layer = self.tree.GetPyData(item)[0]['maplayer']
data = self.tree.GetPyData(item)[0]['nviz']['vector']
@@ -766,7 +1728,7 @@
for vecType in vecTypes:
if 'object' not in data[vecType]:
continue
-
+
id = data[vecType]['object']['id']
if vecType == 'lines':
@@ -782,46 +1744,23 @@
data[vecType].pop('object')
- ### self.layers.remove(id)
-
- def Reset(self):
- """!Reset (unload data)"""
- for item in self.layers:
- type = self.tree.GetPyData(item)[0]['maplayer'].type
- if type == 'raster':
- self.UnloadRaster(item)
- elif type == '3d-raster':
- self.UnloadRaster3d(item)
- elif type == 'vector':
- self.UnloadVector(item)
-
- self.init = False
+ if remove and item in self.layers:
+ self.layers.remove(item)
- def OnZoomToMap(self, event):
- """!Set display extents to match selected raster or vector
- map or volume.
-
- @todo vector, volume
- """
- layer = self.GetSelectedLayer()
-
- if layer is None:
- return
-
- Debug.msg (3, "GLWindow.OnZoomToMap(): layer = %s, type = %s" % \
- (layer.name, layer.type))
-
- self._display.SetViewportDefault()
-
def ResetView(self):
"""!Reset to default view"""
- self.view['z-exag']['value'], \
+ self.iview['z-exag']['original'], \
self.iview['height']['value'], \
self.iview['height']['min'], \
self.iview['height']['max'] = self._display.SetViewDefault()
+
+ ## set initial z-exag value at 1X
+ self.view['z-exag']['value'] = 1.0
- self.view['z-exag']['min'] = 0
- self.view['z-exag']['max'] = self.view['z-exag']['value'] * 10
+ self.view['z-exag']['min'] = UserSettings.Get(group = 'nviz', key = 'view',
+ subkey = ('z-exag', 'min'))
+ zexagMax = UserSettings.Get(group = 'nviz', key = 'view',
+ subkey = ('z-exag', 'max'))
self.view['position']['x'] = UserSettings.Get(group = 'nviz', key = 'view',
subkey = ('position', 'x'))
@@ -832,20 +1771,33 @@
self.view['twist']['value'] = UserSettings.Get(group = 'nviz', key = 'view',
subkey = ('twist', 'value'))
+ self._display.ResetRotation()
+ self.iview['rotation'] = None
+ self._display.LookAtCenter()
+ focus = self.iview['focus']
+ focus['x'], focus['y'], focus['z'] = self._display.GetFocus()
- event = wxUpdateView(zExag = False)
- wx.PostEvent(self, event)
+ self.PostViewEvent()
def UpdateMapObjProperties(self, event):
"""!Generic method to update data layer properties"""
data = event.data
if 'surface' in data:
- id = data['surface']['object']['id']
+ try:
+ id = data['surface']['object']['id']
+ except KeyError:
+ return
self.UpdateSurfaceProperties(id, data['surface'])
# -> initialized
data['surface']['object']['init'] = True
+ elif 'constant' in data:
+ id = data['constant']['object']['id']
+ self.UpdateConstantProperties(id, data['constant'])
+ # -> initialized
+ data['constant']['object']['init'] = True
+
elif 'volume' in data:
id = data['volume']['object']['id']
self.UpdateVolumeProperties(id, data['volume'])
@@ -859,12 +1811,22 @@
self.UpdateVectorProperties(id, data['vector'], type)
# -> initialized
data['vector'][type]['object']['init'] = True
-
+
+ def UpdateConstantProperties(self, id, data):
+ """!Update surface map object properties"""
+ self._display.SetSurfaceColor(id = id, map = False, value = data['color'])
+ self._display.SetSurfaceTopo(id = id, map = False, value = data['value'])
+ self._display.SetSurfaceRes(id, data['resolution'], data['resolution'])
+ if data['transp'] == 0:
+ self._display.UnsetSurfaceTransp(id)
+ else:
+ self._display.SetSurfaceTransp(id, map = False, value = data['transp'])
+
def UpdateSurfaceProperties(self, id, data):
"""!Update surface map object properties"""
# surface attributes
- for attrb in ('topo', 'color', 'mask',
- 'transp', 'shine', 'emit'):
+ for attrb in ('color', 'mask',
+ 'transp', 'shine'):
if attrb not in data['attribute'] or \
'update' not in data['attribute'][attrb]:
continue
@@ -879,16 +1841,12 @@
# TODO: broken in NVIZ
self._display.UnsetSurfaceMask(id)
elif attrb == 'transp':
- self._display.UnsetSurfaceTransp(id)
- elif attrb == 'emit':
- self._display.UnsetSurfaceEmit(id)
+ self._display.UnsetSurfaceTransp(id)
else:
- if type(value) == type('') and \
+ if type(value) == types.StringType and \
len(value) <= 0: # ignore empty values (TODO: warning)
continue
- if attrb == 'topo':
- self._display.SetSurfaceTopo(id, map, str(value))
- elif attrb == 'color':
+ if attrb == 'color':
self._display.SetSurfaceColor(id, map, str(value))
elif attrb == 'mask':
# TODO: invert mask
@@ -898,8 +1856,6 @@
self._display.SetSurfaceTransp(id, map, str(value))
elif attrb == 'shine':
self._display.SetSurfaceShine(id, map, str(value))
- elif attrb == 'emit':
- self._display.SetSurfaceEmit(id, map, str(value))
data['attribute'][attrb].pop('update')
# draw res
@@ -949,14 +1905,25 @@
def UpdateVolumeProperties(self, id, data, isosurfId = None):
"""!Update volume (isosurface/slice) map object properties"""
if 'update' in data['draw']['resolution']:
- self._display.SetIsosurfaceRes(id, data['draw']['resolution']['value'])
+ if data['draw']['mode']['value'] == 0:
+ self._display.SetIsosurfaceRes(id, data['draw']['resolution']['isosurface']['value'])
+ else:
+ self._display.SetSliceRes(id, data['draw']['resolution']['slice']['value'])
data['draw']['resolution'].pop('update')
if 'update' in data['draw']['shading']:
- if data['draw']['shading']['value'] < 0: # need to calculate
- data['draw']['shading']['value'] = \
- self.nvizDefault.GetDrawMode(shade = data['draw']['shading'],
- string = False)
+ if data['draw']['mode']['value'] == 0:
+ if data['draw']['shading']['isosurface']['value'] < 0: # need to calculate
+ mode = data['draw']['shading']['isosurface']['value'] = \
+ self.nvizDefault.GetDrawMode(shade = data['draw']['shading']['isosurface'],
+ string = False)
+ self._display.SetIsosurfaceMode(id, mode)
+ else:
+ if data['draw']['shading']['slice']['value'] < 0: # need to calculate
+ mode = data['draw']['shading']['slice']['value'] = \
+ self.nvizDefault.GetDrawMode(shade = data['draw']['shading']['slice'],
+ string = False)
+ self._display.SetSliceMode(id, mode)
data['draw']['shading'].pop('update')
#
@@ -964,8 +1931,9 @@
#
isosurfId = 0
for isosurf in data['isosurface']:
- for attrb in ('color', 'mask',
- 'transp', 'shine', 'emit'):
+ self._display.AddIsosurface(id, 0, isosurf_id = isosurfId)
+ for attrb in ('topo', 'color', 'mask',
+ 'transp', 'shine'):
if attrb not in isosurf or \
'update' not in isosurf[attrb]:
continue
@@ -974,16 +1942,16 @@
if map is None: # unset
# only optional attributes
- if attrb == 'mask':
+ if attrb == 'topo' :
+ self._display.SetIsosurfaceTopo(id, isosurfId, map, str(value))
+ elif attrb == 'mask':
# TODO: invert mask
# TODO: broken in NVIZ
self._display.UnsetIsosurfaceMask(id, isosurfId)
elif attrb == 'transp':
- self._display.UnsetIsosurfaceTransp(id, isosurfId)
- elif attrb == 'emit':
- self._display.UnsetIsosurfaceEmit(id, isosurfId)
+ self._display.UnsetIsosurfaceTransp(id, isosurfId)
else:
- if type(value) == type('') and \
+ if type(value) == types.StringType and \
len(value) <= 0: # ignore empty values (TODO: warning)
continue
elif attrb == 'color':
@@ -995,12 +1963,34 @@
elif attrb == 'transp':
self._display.SetIsosurfaceTransp(id, isosurfId, map, str(value))
elif attrb == 'shine':
- self._display.SetIsosurfaceShine(id, isosurfId, map, str(value))
- elif attrb == 'emit':
- self._display.SetIsosurfaceEmit(id, isosurfId, map, str(value))
+ self._display.SetIsosurfaceShine(id, isosurfId, map, str(value))
isosurf[attrb].pop('update')
isosurfId += 1
-
+ #
+ # slice attributes
+ #
+ sliceId = 0
+ for slice in data['slice']:
+ ret = self._display.AddSlice(id, slice_id = sliceId)
+ if 'update' in slice['position']:
+ pos = slice['position']
+ ret = self._display.SetSlicePosition(id, sliceId, pos['x1'], pos['x2'],
+ pos['y1'], pos['y2'], pos['z1'], pos['z2'], pos['axis'])
+
+ slice['position'].pop('update')
+ if 'update' in slice['transp']:
+ tr = slice['transp']['value']
+ self._display.SetSliceTransp(id, sliceId, tr)
+ sliceId += 1
+
+ # position
+ if 'update' in data['position']:
+ x = data['position']['x']
+ y = data['position']['y']
+ z = data['position']['z']
+ self._display.SetVolumePosition(id, x, y, z)
+ data['position'].pop('update')
+
def UpdateVectorProperties(self, id, data, type):
"""!Update vector layer properties
@@ -1023,8 +2013,8 @@
color = data['color']['value']
if data['mode']['type'] == 'flat':
flat = True
- if 'surface' in data:
- data.pop('surface')
+ if 'surface' in data['mode']:
+ data['mode'].pop('surface')
else:
flat = False
@@ -1035,22 +2025,28 @@
data['color'].pop('update')
if 'update' in data['width']:
data['width'].pop('update')
- if 'update' in data['mode']:
- data['mode'].pop('update')
# height
if 'update' in data['height']:
self._display.SetVectorLineHeight(id,
data['height']['value'])
data['height'].pop('update')
-
+
# surface
+ if 'surface' in data['mode'] and 'update' in data['mode']:
+ for item in range(len(data['mode']['surface']['value'])):
+ for type in ('raster', 'constant'):
+ sid = self.GetLayerId(type = type,
+ name = data['mode']['surface']['value'][item])
+ if sid > -1:
+ if data['mode']['surface']['show'][item]:
+ self._display.SetVectorLineSurface(id, sid)
+ else:
+ self._display.UnsetVectorLineSurface(id, sid)
+ break
+
if 'update' in data['mode']:
- sid = self.GetLayerId(type = 'raster', name = data['mode']['surface'])
- if sid > -1:
- self._display.SetVectorLineSurface(id, sid)
-
- data['mode'].pop('update')
+ data['mode'].pop('update')
def UpdateVectorPointsProperties(self, id, data):
"""!Update vector point map object properties"""
@@ -1058,6 +2054,7 @@
'update' in data['width'] or \
'update' in data['marker'] or \
'update' in data['color']:
+
ret = self._display.SetVectorPointMode(id, data['color']['value'],
data['width']['value'], float(data['size']['value']),
data['marker']['value'] + 1)
@@ -1080,33 +2077,49 @@
self._display.SetVectorPointHeight(id,
data['height']['value'])
data['height'].pop('update')
-
+
# surface
- if 'update' in data['mode']:
- sid = self.GetLayerId(type = 'raster', name = data['mode']['surface'])
- if sid > -1:
- self._display.SetVectorPointSurface(id, sid)
-
+ if 'update' in data['mode'] and 'surface' in data['mode']:
+ for item in range(len(data['mode']['surface']['value'])):
+ for type in ('raster', 'constant'):
+ sid = self.GetLayerId(type = type,
+ name = data['mode']['surface']['value'][item])
+ if sid > -1:
+ if data['mode']['surface']['show'][item]:
+ self._display.SetVectorPointSurface(id, sid)
+ else:
+ self._display.UnsetVectorPointSurface(id, sid)
+ break
data['mode'].pop('update')
def GetLayerNames(self, type):
"""!Return list of map layer names of given type"""
layerName = []
- for item in self.layers:
- mapLayer = self.tree.GetPyData(item)[0]['maplayer']
- if type != mapLayer.GetType():
- continue
-
- layerName.append(mapLayer.GetName())
+ if type == 'constant':
+ for item in self.constants:
+ layerName.append(_("constant#") + str(item['constant']['object']['name']))
+ else:
+ for item in self.layers:
+ mapLayer = self.tree.GetPyData(item)[0]['maplayer']
+ if type != mapLayer.GetType():
+ continue
+
+ layerName.append(mapLayer.GetName())
return layerName
- def GetLayerId(self, type, name):
+ def GetLayerId(self, type, name, vsubtyp = None):
"""!Get layer object id or -1"""
if len(name) < 1:
return -1
+ if type == 'constant':
+ for item in self.constants:
+ if _("constant#") + str(item['constant']['object']['name']) == name:
+ return item['constant']['object']['id']
+
+
for item in self.layers:
mapLayer = self.tree.GetPyData(item)[0]['maplayer']
if type != mapLayer.GetType() or \
@@ -1115,17 +2128,317 @@
data = self.tree.GetPyData(item)[0]['nviz']
- if type == 'raster':
- return data['surface']['object']['id']
- elif type == 'vpoint':
- return data['vector']['points']['object']['id']
- elif type == 'vline':
- return data['vector']['lines']['object']['id']
- elif type == '3d-raster':
- return data['volume']['object']['id']
-
+ try:
+ if type == 'raster':
+ return data['surface']['object']['id']
+ elif type == 'vector':
+ if vsubtyp == 'vpoint':
+ return data['vector']['points']['object']['id']
+ elif vsubtyp == 'vline':
+ return data['vector']['lines']['object']['id']
+ elif type == '3d-raster':
+ return data['volume']['object']['id']
+ except KeyError:
+ return -1
return -1
+ def ReloadLayersData(self):
+ """!Delete nviz data of all loaded layers and reload them from current settings"""
+ for item in self.layers:
+ type = self.tree.GetPyData(item)[0]['type']
+ layer = self.tree.GetPyData(item)[0]['maplayer']
+ data = self.tree.GetPyData(item)[0]['nviz']
+
+ if type == 'raster':
+ self.nvizDefault.SetSurfaceDefaultProp(data['surface'])
+ if type == 'vector':
+ npoints, nlines, nfeatures, mapIs3D = self.lmgr.nviz.VectorInfo(layer)
+ if npoints > 0:
+ self.nvizDefault.SetVectorPointsDefaultProp(data['vector']['points'])
+ if nlines > 0:
+ self.nvizDefault.SetVectorLinesDefaultProp(data['vector']['lines'])
+
+ def NvizCmdCommand(self):
+ """!Generate command for m.nviz.image according to current state"""
+ cmd = 'm.nviz.image '
+
+ rasters = []
+ vectors = []
+ volumes = []
+ for item in self.layers:
+ if self.tree.GetPyData(item)[0]['type'] == 'raster':
+ rasters.append(item)
+ elif self.tree.GetPyData(item)[0]['type'] == '3d-raster':
+ volumes.append(item)
+ elif self.tree.GetPyData(item)[0]['type'] == 'vector':
+ vectors.append(item)
+ if not rasters and not self.constants:
+ return _("At least one raster map required")
+ # elevation_map/elevation_value
+ if self.constants:
+ subcmd = "elevation_value="
+ for constant in self.constants:
+ subcmd += "%d," % constant['constant']['value']
+ subcmd = subcmd.strip(', ') + ' '
+ cmd += subcmd
+ if rasters:
+ subcmd = "elevation_map="
+ for item in rasters:
+ subcmd += "%s," % self.tree.GetPyData(item)[0]['maplayer'].GetName()
+ subcmd = subcmd.strip(', ') + ' '
+ cmd += subcmd
+ #
+ # draw mode
+ #
+ cmdMode = "mode="
+ cmdFine = "resolution_fine="
+ cmdCoarse = "resolution_coarse="
+ cmdShading = "shading="
+ cmdStyle = "style="
+ cmdWire = "wire_color="
+ # test -a flag
+ flag_a = "-a "
+ nvizDataFirst = self.tree.GetPyData(rasters[0])[0]['nviz']['surface']['draw']
+ for item in rasters:
+ nvizData = self.tree.GetPyData(item)[0]['nviz']['surface']['draw']
+ if nvizDataFirst != nvizData:
+ flag_a = ""
+ cmd += flag_a
+ for item in rasters:
+ nvizData = self.tree.GetPyData(item)[0]['nviz']['surface']['draw']
+
+ cmdMode += "%s," % nvizData['mode']['desc']['mode']
+ cmdFine += "%s," % nvizData['resolution']['fine']
+ cmdCoarse += "%s," % nvizData['resolution']['coarse']
+ cmdShading += "%s," % nvizData['mode']['desc']['shading']
+ cmdStyle += "%s," % nvizData['mode']['desc']['style']
+ cmdWire += "%s," % nvizData['wire-color']['value']
+ for item in self.constants:
+ cmdMode += "fine,"
+ cmdFine += "%s," % item['constant']['resolution']
+ cmdCoarse += "%s," % item['constant']['resolution']
+ cmdShading += "gouraud,"
+ cmdStyle += "surface,"
+ cmdWire += "0:0:0,"
+ mode = []
+ for subcmd in (cmdMode, cmdFine, cmdCoarse, cmdShading, cmdStyle, cmdWire):
+ if flag_a:
+ mode.append(subcmd.split(',')[0] + ' ')
+ else:
+ subcmd = subcmd.strip(', ') + ' '
+ cmd += subcmd
+ if flag_a:# write only meaningful possibilities
+ cmd += mode[0]
+ if 'fine' in mode[0]:
+ cmd += mode[1]
+ elif 'coarse' in mode[0]:
+ cmd += mode[2]
+ elif 'both' in mode[0]:
+ cmd += mode[2]
+ cmd += mode[1]
+ if 'flat' in mode[3]:
+ cmd += mode[3]
+ if 'wire' in mode[4]:
+ cmd += mode[4]
+ if 'coarse' in mode[0] or 'both' in mode[0] and 'wire' in mode[3]:
+ cmd += mode[5]
+ #
+ # attributes
+ #
+ cmdColorMap = "color_map="
+ cmdColorVal = "color="
+ for item in rasters:
+ nvizData = self.tree.GetPyData(item)[0]['nviz']['surface']['attribute']
+ if 'color' not in nvizData:
+ cmdColorMap += "%s," % self.tree.GetPyData(item)[0]['maplayer'].GetName()
+ else:
+ if nvizData['color']['map']:
+ cmdColorMap += "%s," % nvizData['color']['value']
+ else:
+ cmdColorVal += "%s," % nvizData['color']['value']
+ #TODO
+ # transparency, shine, mask
+ for item in self.constants:
+ cmdColorVal += "%s," % item['constant']['color']
+ if cmdColorMap.split("=")[1]:
+ cmd += cmdColorMap.strip(', ') + ' '
+ if cmdColorVal.split("=")[1]:
+ cmd += cmdColorVal.strip(', ') + ' '
+ cmd += "\\\n"
+ #
+ # vlines
+ #
+ if vectors:
+ cmdLines = cmdLWidth = cmdLHeight = cmdLColor = cmdLMode = cmdLPos = \
+ cmdPoints = cmdPWidth = cmdPSize = cmdPColor = cmdPMarker = cmdPPos = cmdPLayer = ""
+ markers = ['x', 'box', 'sphere', 'cube', 'diamond',
+ 'dec_tree', 'con_tree', 'aster', 'gyro', 'histogram']
+ for vector in vectors:
+ npoints, nlines, nfeatures, mapIs3D = self.lmgr.nviz.VectorInfo(
+ self.tree.GetPyData(vector)[0]['maplayer'])
+ nvizData = self.tree.GetPyData(vector)[0]['nviz']['vector']
+ if nlines > 0:
+ cmdLines += "%s," % self.tree.GetPyData(vector)[0]['maplayer'].GetName()
+ cmdLWidth += "%d," % nvizData['lines']['width']['value']
+ cmdLHeight += "%d," % nvizData['lines']['height']['value']
+ cmdLColor += "%s," % nvizData['lines']['color']['value']
+ cmdLMode += "%s," % nvizData['lines']['mode']['type']
+ cmdLPos += "0,0,%d," % nvizData['lines']['height']['value']
+ if npoints > 0:
+ cmdPoints += "%s," % self.tree.GetPyData(vector)[0]['maplayer'].GetName()
+ cmdPWidth += "%d," % nvizData['points']['width']['value']
+ cmdPSize += "%d," % nvizData['points']['size']['value']
+ cmdPColor += "%s," % nvizData['points']['color']['value']
+ cmdPMarker += "%s," % markers[nvizData['points']['marker']['value']]
+ cmdPPos += "0,0,%d," % nvizData['points']['height']['value']
+ cmdPLayer += "1,1,"
+ if cmdLines:
+ cmd += "vline=" + cmdLines.strip(',') + ' '
+ cmd += "vline_width=" + cmdLWidth.strip(',') + ' '
+ cmd += "vline_color=" + cmdLColor.strip(',') + ' '
+ cmd += "vline_height=" + cmdLHeight.strip(',') + ' '
+ cmd += "vline_mode=" + cmdLMode.strip(',') + ' '
+ cmd += "vline_position=" + cmdLPos.strip(',') + ' '
+ if cmdPoints:
+ cmd += "vpoint=" + cmdPoints.strip(',') + ' '
+ cmd += "vpoint_width=" + cmdPWidth.strip(',') + ' '
+ cmd += "vpoint_color=" + cmdPColor.strip(',') + ' '
+ cmd += "vpoint_size=" + cmdPSize.strip(',') + ' '
+ cmd += "vpoint_marker=" + cmdPMarker.strip(',') + ' '
+ cmd += "vpoint_position=" + cmdPPos.strip(',') + ' '
+ cmd += "\\\n"
+
+ #
+ # volumes
+ #
+ if volumes:
+ cmdName = cmdShade = cmdRes = cmdPos = cmdIso = ""
+ cmdIsoColorMap = cmdIsoColorVal = cmdIsoTrMap = cmdIsoTrVal = ""
+ cmdSlice = cmdSliceTransp = cmdSlicePos = ""
+ for i, volume in enumerate(volumes):
+ nvizData = self.tree.GetPyData(volume)[0]['nviz']['volume']
+ cmdName += "%s," % self.tree.GetPyData(volume)[0]['maplayer'].GetName()
+ cmdShade += "%s," % nvizData['draw']['shading']['isosurface']['desc']
+ cmdRes += "%d," % nvizData['draw']['resolution']['isosurface']['value']
+ if nvizData['position']:
+ cmdPos += "%d,%d,%d," % (nvizData['position']['x'], nvizData['position']['y'],
+ nvizData['position']['z'])
+ for iso in nvizData['isosurface']:
+ level = iso['topo']['value']
+ cmdIso += "%d:%s," % (i + 1, level)
+ if iso['color']['map']:
+ cmdIsoColorMap += "%s," % iso['color']['value']
+ else:
+ cmdIsoColorVal += "%s," % iso['color']['value']
+ if 'transp' in iso:
+ if iso['transp']['map']:
+ cmdIsoTrMap += "%s," % iso['transp']['value']
+ else:
+ cmdIsoTrVal += "%s," % iso['transp']['value']
+
+ for slice in nvizData['slice']:
+ axis = ('x','y','z')[slice['position']['axis']]
+ cmdSlice += "%d:%s," % (i + 1, axis)
+ for coord in ('x1', 'x2', 'y1', 'y2', 'z1', 'z2'):
+ cmdSlicePos += "%f," % slice['position'][coord]
+ cmdSliceTransp += "%s," % slice['transp']['value']
+
+ cmd += "volume=" + cmdName.strip(',') + ' '
+ cmd += "volume_shading=" + cmdShade.strip(',') + ' '
+ cmd += "volume_resolution=" + cmdRes.strip(',') + ' '
+ if nvizData['position']:
+ cmd += "volume_position=" + cmdPos.strip(',') + ' '
+ if cmdIso:
+ cmd += "isosurf_level=" + cmdIso.strip(',') + ' '
+ if cmdIsoColorMap:
+ cmd += "isosurf_color_map=" + cmdIsoColorMap.strip(',') + ' '
+ if cmdIsoColorVal:
+ cmd += "isosurf_color_value=" + cmdIsoColorVal.strip(',') + ' '
+ if cmdIsoTrMap:
+ cmd += "isosurf_transparency_map=" + cmdIsoTrMap.strip(',') + ' '
+ if cmdIsoTrVal:
+ cmd += "isosurf_transparency_value=" + cmdIsoTrVal.strip(',') + ' '
+ if cmdSlice:
+ cmd += "slice=" + cmdSlice.strip(',') + ' '
+ cmd += "slice_position=" + cmdSlicePos.strip(',') + ' '
+ cmd += "slice_transparency=" + cmdSliceTransp.strip(',') + ' '
+
+ #
+ # cutting planes
+ #
+ cplane = self.lmgr.nviz.FindWindowById(self.lmgr.nviz.win['cplane']['planes']).GetStringSelection()
+ try:
+ planeIndex = int(cplane.split()[-1]) - 1
+ except (IndexError, ValueError):
+ planeIndex = None
+ if planeIndex is not None:
+ shading = ['clear', 'top', 'bottom', 'blend', 'shaded']
+ cmd += "cplane=%d " % planeIndex
+ cmd += "cplane_rotation=%d " % self.cplanes[planeIndex]['rotation']['rot']
+ cmd += "cplane_tilt=%d " % self.cplanes[planeIndex]['rotation']['tilt']
+ cmd += "cplane_position=%d,%d,%d " % (self.cplanes[planeIndex]['position']['x'],
+ self.cplanes[planeIndex]['position']['y'],
+ self.cplanes[planeIndex]['position']['z'])
+ cmd += "cplane_shading=%s " % shading[self.cplanes[planeIndex]['shading']]
+ cmd += "\\\n"
+ #
+ # viewpoint
+ #
+ subcmd = "position=%.2f,%.2f " % (self.view['position']['x'], self.view['position']['y'])
+ subcmd += "height=%d " % (self.iview['height']['value'])
+ subcmd += "perspective=%d " % (self.view['persp']['value'])
+ subcmd += "twist=%d " % (self.view['twist']['value'])
+ subcmd += "zexag=%d " % (self.view['z-exag']['value'] * self.iview['z-exag']['original'])
+ subcmd += "focus=%d,%d,%d " % (self.iview['focus']['x'],self.iview['focus']['y'],self.iview['focus']['z'])
+ cmd += subcmd
+
+ # background
+ subcmd = "bgcolor=%d:%d:%d " % (self.view['background']['color'][:3])
+ if self.view['background']['color'] != (255, 255, 255):
+ cmd += subcmd
+ cmd += "\\\n"
+ # light
+ subcmd = "light_position=%.2f,%.2f,%.2f " % (self.light['position']['x'],
+ self.light['position']['y'],
+ self.light['position']['z']/100.)
+ subcmd += "light_brightness=%d " % (self.light['bright'])
+ subcmd += "light_ambient=%d " % (self.light['ambient'])
+ subcmd += "light_color=%d:%d:%d " % (self.light['color'][:3])
+ cmd += subcmd
+ cmd += "\\\n"
+ # fringe
+ toolWindow = self.lmgr.nviz
+ direction = ''
+ for dir in ('nw', 'ne', 'sw', 'se'):
+ if toolWindow.FindWindowById(toolWindow.win['fringe'][dir]).IsChecked():
+ direction += "%s," % dir
+ if direction:
+ subcmd = "fringe=%s " % (direction.strip(','))
+ color = toolWindow.FindWindowById(toolWindow.win['fringe']['color']).GetValue()
+ subcmd += "fringe_color=%d:%d:%d " % (color[0], color[1], color[2])
+ subcmd += "fringe_elevation=%d " % (toolWindow.FindWindowById(toolWindow.win['fringe']['elev']).GetValue())
+ cmd += subcmd
+ cmd += "\\\n"
+ # north arrow
+ if self.decoration['arrow']['show']:
+ subcmd = "arrow_position=%d,%d " % (self.decoration['arrow']['position']['x'],
+ self.decoration['arrow']['position']['y'])
+ subcmd += "arrow_color=%s " % self.decoration['arrow']['color']
+ subcmd += "arrow_size=%d " % self.decoration['arrow']['size']
+ cmd += subcmd
+
+ # output
+ subcmd = 'output=nviz_output '
+ subcmd += 'format=ppm '
+ subcmd += 'size=%d,%d ' % self.GetClientSizeTuple()
+ cmd += subcmd
+
+ return cmd
+
+ def OnNvizCmd(self):
+ """!Generate and write command to command output"""
+ self.log.WriteLog(self.NvizCmdCommand(), switchPage = True)
+
def SaveToFile(self, FileName, FileType, width, height):
"""!This draws the DC to a buffer that can be saved to a file.
@@ -1136,7 +2449,7 @@
@param width image width
@param height image height
"""
- self._display.SaveToFile(FileName, width, height)
+ self._display.SaveToFile(FileName, width, height, FileType)
# pbuffer = wx.EmptyBitmap(max(1, self.Map.width), max(1, self.Map.height))
# dc = wx.BufferedPaintDC(self, pbuffer)
@@ -1154,4 +2467,10 @@
"""!Reset view
"""
self.lmgr.nviz.OnResetView(None)
-
+
+ def TextBounds(self, textinfo):
+ """!Return text boundary data
+
+ @param textinfo text metadata (text, font, color, rotation)
+ """
+ return self.parent.MapWindow2D.TextBounds(textinfo, relcoords = True)
Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/nviz_preferences.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/nviz_preferences.py 2011-11-25 14:58:21 UTC (rev 49356)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/nviz_preferences.py 2011-11-25 15:10:47 UTC (rev 49357)
@@ -6,16 +6,18 @@
Classes:
- NvizPreferencesDialog
-(C) 2008-2010 by the GRASS Development Team
+(C) 2008-2011 by the GRASS Development Team
This program is free software under the GNU General Public License
(>=v2). Read the file COPYING that comes with GRASS for details.
@author Martin Landa <landa.martin gmail.com> (Google SoC 2008/2010)
- at author Enhancements by Michael Barton <michael.barton at asu.edu>
+ at author Enhancements by Michael Barton <michael.barton asu.edu>
+ at author Anna Kratochvilova <KratochAnna seznam.cz> (Google SoC 2011)
"""
import types
+import copy
import wx
import wx.lib.colourselect as csel
@@ -30,18 +32,21 @@
settings = UserSettings):
PreferencesBaseDialog.__init__(self, parent = parent, title = title,
settings = settings)
- self.toolWin = self.parent.GetLayerManager().nviz
- self.win = dict()
+ self.toolWin = self.parent.nviz
# create notebook pages
self._createViewPage(self.notebook)
+ self._createFlyPage(self.notebook)
+ self._createLightPage(self.notebook)
+ self._createSurfacePage(self.notebook)
self._createVectorPage(self.notebook)
self.SetMinSize(self.GetBestSize())
self.SetSize(self.size)
+ self.btnDefault.SetToolTipString(_("Revert settings to default, changes are not applied"))
def _createViewPage(self, notebook):
- """!Create notebook page for general settings"""
+ """!Create notebook page for view settings"""
panel = wx.Panel(parent = notebook, id = wx.ID_ANY)
notebook.AddPage(page = panel,
@@ -49,152 +54,111 @@
pageSizer = wx.BoxSizer(wx.VERTICAL)
- self.win['general'] = {}
- self.win['view'] = {}
box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
label = " %s " % (_("View")))
boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
gridSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
-
+ row = 0
# perspective
- self.win['view']['persp'] = {}
pvals = UserSettings.Get(group = 'nviz', key = 'view', subkey = 'persp')
ipvals = UserSettings.Get(group = 'nviz', key = 'view', subkey = 'persp', internal = True)
gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
label = _("Perspective:")),
- pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL)
+ pos = (row, 0), flag = wx.ALIGN_CENTER_VERTICAL)
gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = _("(value)")),
- pos = (0, 1), flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
+ label = _("value:")),
+ pos = (row, 1), flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
pval = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
initial = pvals['value'],
min = ipvals['min'],
max = ipvals['max'])
- self.win['view']['persp']['value'] = pval.GetId()
- gridSizer.Add(item = pval, pos = (0, 2),
+ self.winId['nviz:view:persp:value'] = pval.GetId()
+ gridSizer.Add(item = pval, pos = (row, 2),
flag = wx.ALIGN_CENTER_VERTICAL)
gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = _("(step)")),
- pos = (0, 3), flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
+ label = _("step:")),
+ pos = (row, 3), flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
pstep = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
initial = pvals['step'],
min = ipvals['min'],
max = ipvals['max']-1)
- self.win['view']['persp']['step'] = pstep.GetId()
- gridSizer.Add(item = pstep, pos = (0, 4),
+ self.winId['nviz:view:persp:step'] = pstep.GetId()
+ gridSizer.Add(item = pstep, pos = (row, 4),
flag = wx.ALIGN_CENTER_VERTICAL)
+ row += 1
# position
- self.win['view']['pos'] = {}
posvals = UserSettings.Get(group = 'nviz', key = 'view', subkey = 'position')
gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
label = _("Position:")),
- pos = (1, 0), flag = wx.ALIGN_CENTER_VERTICAL)
+ pos = (row, 0), flag = wx.ALIGN_CENTER_VERTICAL)
gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = _("(x)")),
- pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
+ label = _("x:")),
+ pos = (row, 1), flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
px = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
initial = posvals['x'] * 100,
min = 0,
max = 100)
- self.win['view']['pos']['x'] = px.GetId()
- gridSizer.Add(item = px, pos = (1, 2),
+ self.winId['nviz:view:position:x'] = px.GetId()
+ gridSizer.Add(item = px, pos = (row, 2),
flag = wx.ALIGN_CENTER_VERTICAL)
gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = "(y)"),
- pos = (1, 3), flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
+ label = "y:"),
+ pos = (row, 3), flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
py = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
initial = posvals['y'] * 100,
min = 0,
max = 100)
- self.win['view']['pos']['y'] = py.GetId()
- gridSizer.Add(item = py, pos = (1, 4),
+ self.winId['nviz:view:position:y'] = py.GetId()
+ gridSizer.Add(item = py, pos = (row, 4),
flag = wx.ALIGN_CENTER_VERTICAL)
+ row += 1
- # height
- self.win['view']['height'] = {}
- hvals = UserSettings.Get(group = 'nviz', key = 'view', subkey = 'height')
- gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = _("Height:")),
- pos = (2, 0), flag = wx.ALIGN_CENTER_VERTICAL)
- gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = _("(step)")),
- pos = (2, 1), flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
+ # height is computed dynamically
- hstep = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
- initial = hvals['step'],
- min = 1,
- max = 1e6)
- self.win['view']['height']['step'] = hstep.GetId()
- gridSizer.Add(item = hstep, pos = (2, 2),
- flag = wx.ALIGN_CENTER_VERTICAL)
-
# twist
- self.win['view']['twist'] = {}
tvals = UserSettings.Get(group = 'nviz', key = 'view', subkey = 'twist')
itvals = UserSettings.Get(group = 'nviz', key = 'view', subkey = 'twist', internal = True)
gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
label = _("Twist:")),
- pos = (3, 0), flag = wx.ALIGN_CENTER_VERTICAL)
+ pos = (row, 0), flag = wx.ALIGN_CENTER_VERTICAL)
gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = _("(value)")),
- pos = (3, 1), flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
+ label = _("value:")),
+ pos = (row, 1), flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
tval = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
initial = tvals['value'],
min = itvals['min'],
max = itvals['max'])
- self.win['view']['twist']['value'] = tval.GetId()
- gridSizer.Add(item = tval, pos = (3, 2),
+ self.winId['nviz:view:twist:value'] = tval.GetId()
+ gridSizer.Add(item = tval, pos = (row, 2),
flag = wx.ALIGN_CENTER_VERTICAL)
+ row += 1
- gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = _("(step)")),
- pos = (3, 3), flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
-
- tstep = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
- initial = tvals['step'],
- min = itvals['min'],
- max = itvals['max']-1)
- self.win['view']['twist']['step'] = tstep.GetId()
- gridSizer.Add(item = tstep, pos = (3, 4),
- flag = wx.ALIGN_CENTER_VERTICAL)
-
# z-exag
- self.win['view']['z-exag'] = {}
zvals = UserSettings.Get(group = 'nviz', key = 'view', subkey = 'z-exag')
gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
label = _("Z-exag:")),
- pos = (4, 0), flag = wx.ALIGN_CENTER_VERTICAL)
+ pos = (row, 0), flag = wx.ALIGN_CENTER_VERTICAL)
gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = _("(value)")),
- pos = (4, 1), flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
+ label = _("value:")),
+ pos = (row, 1), flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
zval = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
+ initial = zvals['value'],
min = -1e6,
max = 1e6)
- self.win['view']['z-exag']['value'] = zval.GetId()
- gridSizer.Add(item = zval, pos = (4, 2),
+ self.winId['nviz:view:z-exag:value'] = zval.GetId()
+ gridSizer.Add(item = zval, pos = (row, 2),
flag = wx.ALIGN_CENTER_VERTICAL)
- gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = _("(step)")),
- pos = (4, 3), flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
- zstep = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
- initial = zvals['step'],
- min = -1e6,
- max = 1e6)
- self.win['view']['z-exag']['step'] = zstep.GetId()
- gridSizer.Add(item = zstep, pos = (4, 4),
- flag = wx.ALIGN_CENTER_VERTICAL)
-
boxSizer.Add(item = gridSizer, proportion = 1,
flag = wx.ALL | wx.EXPAND, border = 3)
pageSizer.Add(item = boxSizer, proportion = 0,
@@ -213,24 +177,283 @@
pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL)
color = csel.ColourSelect(panel, id = wx.ID_ANY,
- colour = UserSettings.Get(group = 'nviz', key = 'settings',
- subkey = ['general', 'bgcolor']),
+ colour = UserSettings.Get(group = 'nviz', key = 'view',
+ subkey = ['background', 'color']),
size = globalvar.DIALOG_COLOR_SIZE)
- self.win['general']['bgcolor'] = color.GetId()
+ color.SetName('GetColour')
+ self.winId['nviz:view:background:color'] = color.GetId()
gridSizer.Add(item = color, pos = (0, 1))
boxSizer.Add(item = gridSizer, proportion = 1,
- flag = wx.ALL | wx.EXPAND, border = 3)
+ flag = wx.ALL | wx.EXPAND, border = 5)
pageSizer.Add(item = boxSizer, proportion = 0,
flag = wx.EXPAND | wx.ALL,
- border = 3)
+ border = 5)
panel.SetSizer(pageSizer)
return panel
+
+ def _createFlyPage(self, notebook):
+ """!Create notebook page for view settings"""
+ panel = wx.Panel(parent = notebook, id = wx.ID_ANY)
+
+ notebook.AddPage(page = panel,
+ text = " %s " % _("Fly-through"))
+ pageSizer = wx.BoxSizer(wx.VERTICAL)
+ # fly throuhg mode
+ box = wx.StaticBox(parent = panel, id = wx.ID_ANY,
+ label = " %s " % (_("Fly-through mode")))
+ boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+ gridSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
+ gridSizer.AddGrowableCol(0)
+
+ # move exag
+ gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
+ label = _("Move exag:")),
+ pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL)
+
+ moveExag = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 1, max = 20,
+ initial = UserSettings.Get(group = 'nviz', key = 'fly',
+ subkey = ['exag', 'move']),
+ size = (65, -1))
+ self.winId['nviz:fly:exag:move'] = moveExag.GetId()
+ gridSizer.Add(item = moveExag, pos = (0, 1))
+
+ # turn exag
+ gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
+ label = _("Turn exag:")),
+ pos = (1, 0), flag = wx.ALIGN_CENTER_VERTICAL)
+
+ turnExag = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 1, max = 20,
+ initial = UserSettings.Get(group = 'nviz', key = 'fly',
+ subkey = ['exag', 'turn']),
+ size = (65, -1))
+ self.winId['nviz:fly:exag:turn'] = turnExag.GetId()
+ gridSizer.Add(item = turnExag, pos = (1, 1))
+
+ boxSizer.Add(item = gridSizer, proportion = 1,
+ flag = wx.ALL | wx.EXPAND, border = 5)
+ pageSizer.Add(item = boxSizer, proportion = 0,
+ flag = wx.EXPAND | wx.ALL,
+ border = 5)
+
+ panel.SetSizer(pageSizer)
+
+ return panel
+
+ def _createLightPage(self, notebook):
+ """!Create notebook page for light settings"""
+ panel = wx.Panel(parent = notebook, id = wx.ID_ANY)
+
+ notebook.AddPage(page = panel,
+ text = " %s " % _("Lighting"))
+
+ pageSizer = wx.BoxSizer(wx.VERTICAL)
+
+ box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
+ label = " %s " % (_("Light")))
+ boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+ gridSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
+
+
+ # position
+ posvals = UserSettings.Get(group = 'nviz', key = 'light', subkey = 'position')
+ gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
+ label = _("Position:")),
+ pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL)
+ gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
+ label = _("x:")),
+ pos = (0, 1), flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
+
+ px = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
+ initial = posvals['x'] * 100,
+ min = -100,
+ max = 100)
+ self.winId['nviz:light:position:x'] = px.GetId()
+ gridSizer.Add(item = px, pos = (0, 2),
+ flag = wx.ALIGN_CENTER_VERTICAL)
+
+ gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
+ label = "y:"),
+ pos = (0, 3), flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
+
+ py = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
+ initial = posvals['y'] * 100,
+ min = -100,
+ max = 100)
+ self.winId['nviz:light:position:y'] = py.GetId()
+ gridSizer.Add(item = py, pos = (0, 4),
+ flag = wx.ALIGN_CENTER_VERTICAL)
+
+ gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
+ label = _("z:")),
+ pos = (0, 5), flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
+
+ pz = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
+ initial = posvals['z'],
+ min = 0,
+ max = 100)
+ self.winId['nviz:light:position:z'] = pz.GetId()
+ gridSizer.Add(item = pz, pos = (0, 6),
+ flag = wx.ALIGN_CENTER_VERTICAL)
+
+ # brightness
+ brightval = UserSettings.Get(group = 'nviz', key = 'light', subkey = 'bright')
+ gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
+ label = _("Brightness:")),
+ pos = (1, 0), flag = wx.ALIGN_CENTER_VERTICAL)
+
+ bright = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
+ initial = brightval,
+ min = 0,
+ max = 100)
+ self.winId['nviz:light:bright'] = bright.GetId()
+ gridSizer.Add(item = bright, pos = (1, 2),
+ flag = wx.ALIGN_CENTER_VERTICAL)
+
+ # ambient
+ ambval = UserSettings.Get(group = 'nviz', key = 'light', subkey = 'ambient')
+ gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
+ label = _("Ambient:")),
+ pos = (2, 0), flag = wx.ALIGN_CENTER_VERTICAL)
+
+ amb = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
+ initial = ambval,
+ min = 0,
+ max = 100)
+ self.winId['nviz:light:ambient'] = amb.GetId()
+ gridSizer.Add(item = amb, pos = (2, 2),
+ flag = wx.ALIGN_CENTER_VERTICAL)
+
+ # light color
+ gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
+ label = _("Color:")),
+ pos = (3, 0), flag = wx.ALIGN_CENTER_VERTICAL)
+
+ color = csel.ColourSelect(panel, id = wx.ID_ANY,
+ colour = UserSettings.Get(group = 'nviz', key = 'light',
+ subkey = 'color'),
+ size = globalvar.DIALOG_COLOR_SIZE)
+ color.SetName('GetColour')
+ self.winId['nviz:light:color'] = color.GetId()
+ gridSizer.Add(item = color, pos = (3, 2))
+
+
+ boxSizer.Add(item = gridSizer, proportion = 1,
+ flag = wx.ALL | wx.EXPAND, border = 5)
+ pageSizer.Add(item = boxSizer, proportion = 0,
+ flag = wx.EXPAND | wx.ALL,
+ border = 5)
+
+ panel.SetSizer(pageSizer)
+
+ return panel
+ def _createSurfacePage(self, notebook):
+ """!Create notebook page for surface settings"""
+ panel = wx.Panel(parent = notebook, id = wx.ID_ANY)
+
+ notebook.AddPage(page = panel,
+ text = " %s " % _("Surface"))
+
+ pageSizer = wx.BoxSizer(wx.VERTICAL)
+
+ # draw
+
+ box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
+ label = " %s " % (_("Draw")))
+ boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+ gridSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
+
+ # mode
+ gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
+ label = _("Mode:")), flag = wx.ALIGN_CENTER_VERTICAL,
+ pos = (0, 0))
+ mode = wx.Choice(parent = panel, id = wx.ID_ANY, size = (-1, -1),
+ choices = [_("coarse"),
+ _("fine"),
+ _("both")])
+ self.winId['nviz:surface:draw:mode'] = mode.GetId()
+ mode.SetName('GetSelection')
+ mode.SetSelection(UserSettings.Get(group = 'nviz', key = 'surface',
+ subkey = ['draw', 'mode']))
+ gridSizer.Add(item = mode, flag = wx.ALIGN_CENTER_VERTICAL,
+ pos = (0, 1))
+
+ # fine
+ gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
+ label = _("Fine mode:")), flag = wx.ALIGN_CENTER_VERTICAL,
+ pos = (1, 0))
+ res = UserSettings.Get(group = 'nviz', key = 'surface', subkey = ['draw','res-fine'])
+ gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
+ label = _("resolution:")), flag = wx.ALIGN_CENTER_VERTICAL,
+ pos = (1, 1))
+ fine = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
+ initial = res,
+ min = 1,
+ max = 100)
+ self.winId['nviz:surface:draw:res-fine'] = fine.GetId()
+
+ gridSizer.Add(item = fine, flag = wx.ALIGN_CENTER_VERTICAL,
+ pos = (1, 2))
+
+ # coarse
+ gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
+ label = _("Coarse mode:")), flag = wx.ALIGN_CENTER_VERTICAL,
+ pos = (2, 0))
+ res = UserSettings.Get(group = 'nviz', key = 'surface', subkey = ['draw','res-coarse'])
+ gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
+ label = _("resolution:")), flag = wx.ALIGN_CENTER_VERTICAL,
+ pos = (2, 1))
+ coarse = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
+ initial = res,
+ min = 1,
+ max = 100)
+ self.winId['nviz:surface:draw:res-coarse'] = coarse.GetId()
+
+ gridSizer.Add(item = coarse, flag = wx.ALIGN_CENTER_VERTICAL,
+ pos = (2, 2))
+ #style
+ gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
+ label = _("style:")), flag = wx.ALIGN_CENTER_VERTICAL,
+ pos = (3, 1))
+ style = wx.Choice(parent = panel, id = wx.ID_ANY, size = (-1, -1),
+ choices = [_("wire"),
+ _("surface")])
+ self.winId['nviz:surface:draw:style'] = style.GetId()
+ style.SetName('GetSelection')
+ style.SetSelection(UserSettings.Get(group = 'nviz', key = 'surface',
+ subkey = ['draw', 'style']))
+ self.winId['nviz:surface:draw:style'] = style.GetId()
+
+ gridSizer.Add(item = style, flag = wx.ALIGN_CENTER_VERTICAL,
+ pos = (3, 2))
+ #wire color
+ gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
+ label = _("wire color:")), flag = wx.ALIGN_CENTER_VERTICAL,
+ pos = (4, 1))
+ color = csel.ColourSelect(panel, id = wx.ID_ANY,
+ colour = UserSettings.Get(group = 'nviz', key = 'surface',
+ subkey = ['draw', 'wire-color']),
+ size = globalvar.DIALOG_COLOR_SIZE)
+ color.SetName('GetColour')
+ self.winId['nviz:surface:draw:wire-color'] = color.GetId()
+ gridSizer.Add(item = color, flag = wx.ALIGN_CENTER_VERTICAL,
+ pos = (4, 2))
+
+ boxSizer.Add(item = gridSizer, proportion = 1,
+ flag = wx.ALL | wx.EXPAND, border = 5)
+ pageSizer.Add(item = boxSizer, proportion = 0,
+ flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
+ border = 5)
+
+ panel.SetSizer(pageSizer)
+
+ return panel
+
def _createVectorPage(self, notebook):
- """!Create notebook page for general settings"""
+ """!Create notebook page for vector settings"""
panel = wx.Panel(parent = notebook, id = wx.ID_ANY)
notebook.AddPage(page = panel,
@@ -239,46 +462,53 @@
pageSizer = wx.BoxSizer(wx.VERTICAL)
# vector lines
- self.win['vector'] = {}
- self.win['vector']['lines'] = {}
box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
label = " %s " % (_("Vector lines")))
boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
gridSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
- # show
row = 0
- showLines = wx.CheckBox(parent = panel, id = wx.ID_ANY,
- label = _("Show lines"))
- self.win['vector']['lines']['show'] = showLines.GetId()
- showLines.SetValue(UserSettings.Get(group = 'nviz', key = 'vector',
- subkey = ['lines', 'show']))
- gridSizer.Add(item = showLines, pos = (row, 0))
+ # icon size
+ gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
+ label = _("Width:")),
+ pos = (row, 0), flag = wx.ALIGN_CENTER_VERTICAL)
+ iwidth = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
+ initial = 12,
+ min = 1,
+ max = 100)
+ self.winId['nviz:vector:lines:width'] = iwidth.GetId()
+ iwidth.SetValue(UserSettings.Get(group = 'nviz', key = 'vector',
+ subkey = ['lines', 'width']))
+ gridSizer.Add(item = iwidth, pos = (row, 1),
+ flag = wx.ALIGN_CENTER_VERTICAL)
+
+ # icon color
+ gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
+ label = _("Color:")),
+ pos = (row, 4), flag = wx.ALIGN_CENTER_VERTICAL)
+ icolor = csel.ColourSelect(panel, id = wx.ID_ANY,
+ size = globalvar.DIALOG_COLOR_SIZE)
+ icolor.SetName('GetColour')
+ self.winId['nviz:vector:lines:color'] = icolor.GetId()
+ icolor.SetColour(UserSettings.Get(group = 'nviz', key = 'vector',
+ subkey = ['lines', 'color']))
+ gridSizer.Add(item = icolor, flag = wx.ALIGN_CENTER_VERTICAL,
+ pos = (row, 5))
boxSizer.Add(item = gridSizer, proportion = 1,
- flag = wx.ALL | wx.EXPAND, border = 3)
+ flag = wx.ALL | wx.EXPAND, border = 5)
pageSizer.Add(item = boxSizer, proportion = 0,
flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
- border = 3)
+ border = 5)
# vector points
- self.win['vector']['points'] = {}
box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
label = " %s " % (_("Vector points")))
boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
gridSizer = wx.GridBagSizer(vgap = 3, hgap = 5)
- # show
row = 0
- showPoints = wx.CheckBox(parent = panel, id = wx.ID_ANY,
- label = _("Show points"))
- showPoints.SetValue(UserSettings.Get(group = 'nviz', key = 'vector',
- subkey = ['points', 'show']))
- self.win['vector']['points']['show'] = showPoints.GetId()
- gridSizer.Add(item = showPoints, pos = (row, 0), span = (1, 8))
-
# icon size
- row += 1
gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
label = _("Size:")),
pos = (row, 0), flag = wx.ALIGN_CENTER_VERTICAL)
@@ -287,189 +517,113 @@
initial = 100,
min = 1,
max = 1e6)
- self.win['vector']['points']['size'] = isize.GetId()
+ self.winId['nviz:vector:points:size'] = isize.GetId()
isize.SetValue(UserSettings.Get(group = 'nviz', key = 'vector',
subkey = ['points', 'size']))
gridSizer.Add(item = isize, pos = (row, 1),
flag = wx.ALIGN_CENTER_VERTICAL)
- # icon width
- gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = _("Width:")),
- pos = (row, 2), flag = wx.ALIGN_CENTER_VERTICAL)
-
- iwidth = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
- initial = 2,
- min = 1,
- max = 1e6)
- self.win['vector']['points']['width'] = isize.GetId()
- iwidth.SetValue(UserSettings.Get(group = 'nviz', key = 'vector',
- subkey = ['points', 'width']))
- gridSizer.Add(item = iwidth, pos = (row, 3),
- flag = wx.ALIGN_CENTER_VERTICAL)
-
# icon symbol
gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
label = _("Marker:")),
- pos = (row, 4), flag = wx.ALIGN_CENTER_VERTICAL)
+ pos = (row, 2), flag = wx.ALIGN_CENTER_VERTICAL)
isym = wx.Choice (parent = panel, id = wx.ID_ANY, size = (100, -1),
choices = UserSettings.Get(group = 'nviz', key = 'vector',
subkey = ['points', 'marker'], internal = True))
- isym.SetName("selection")
- self.win['vector']['points']['marker'] = isym.GetId()
+ isym.SetName("GetSelection")
+ self.winId['nviz:vector:points:marker'] = isym.GetId()
isym.SetSelection(UserSettings.Get(group = 'nviz', key = 'vector',
subkey = ['points', 'marker']))
gridSizer.Add(item = isym, flag = wx.ALIGN_CENTER_VERTICAL,
- pos = (row, 5))
+ pos = (row, 3))
# icon color
gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
label = _("Color:")),
- pos = (row, 6), flag = wx.ALIGN_CENTER_VERTICAL)
- icolor = csel.ColourSelect(panel, id = wx.ID_ANY)
- icolor.SetName("color")
- self.win['vector']['points']['color'] = icolor.GetId()
+ pos = (row, 4), flag = wx.ALIGN_CENTER_VERTICAL)
+ icolor = csel.ColourSelect(panel, id = wx.ID_ANY,
+ size = globalvar.DIALOG_COLOR_SIZE)
+ icolor.SetName('GetColour')
+ self.winId['nviz:vector:points:color'] = icolor.GetId()
icolor.SetColour(UserSettings.Get(group = 'nviz', key = 'vector',
subkey = ['points', 'color']))
gridSizer.Add(item = icolor, flag = wx.ALIGN_CENTER_VERTICAL,
- pos = (row, 7))
+ pos = (row, 5))
boxSizer.Add(item = gridSizer, proportion = 1,
- flag = wx.ALL | wx.EXPAND, border = 3)
+ flag = wx.ALL | wx.EXPAND, border = 5)
pageSizer.Add(item = boxSizer, proportion = 0,
flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
- border = 3)
+ border = 5)
panel.SetSizer(pageSizer)
return panel
-
+
def OnDefault(self, event):
- """Restore default settings"""
- settings = copy.deepcopy(UserSettings.GetDefaultSettings()['nviz'])
- UserSettings.Set(group = 'nviz',
- value = settings)
+ """!Button 'Set to default' pressed"""
+ self.settings.userSettings = copy.deepcopy(self.settings.defaultSettings)
- for subgroup, key in settings.iteritems(): # view, surface, vector...
- if subgroup != 'view':
- continue
- for subkey, value in key.iteritems():
- for subvalue in value.keys():
- win = self.FindWindowById(self.win[subgroup][subkey][subvalue])
- val = settings[subgroup][subkey][subvalue]
- if subkey == 'position':
- val = int(val * 100)
-
- win.SetValue(val)
+ # update widgets
+ for gks in self.winId.keys():
+ subkey1 = None
+ try:
+ group, key, subkey = gks.split(':')
+ value = self.settings.Get(group, key, subkey)
+ except ValueError:
+ group, key, subkey, subkey1 = gks.split(':')
+ value = self.settings.Get(group, key, [subkey, subkey1])
+ if subkey == 'position':
+ if subkey1 in ('x', 'y'):
+ value = float(value) * 100
+ win = self.FindWindowById(self.winId[gks])
+ if win.GetName() == 'GetSelection':
+ value = win.SetSelection(value)
+ else:
+ value = win.SetValue(value)
- event.Skip()
-
def OnApply(self, event):
"""Apply Nviz settings for current session"""
- settings = UserSettings.Get(group = 'nviz')
- for subgroup, key in settings.iteritems(): # view, surface, vector...
- for subkey, value in key.iteritems():
- if type(value) == types.DictType:
- for subvalue in value.keys():
- try: # TODO
- win = self.FindWindowById(self.win[subgroup][subkey][subvalue])
- except:
- # print 'e', subgroup, subkey, subvalue
- continue
-
- if win.GetName() == "selection":
- value = win.GetSelection()
- elif win.GetName() == "color":
- value = tuple(win.GetColour())
- else:
- value = win.GetValue()
- if subkey == 'pos':
- value = float(value) / 100
-
- settings[subgroup][subkey][subvalue] = value
+ for item in self.winId.keys():
+ try:
+ group, key, subkey = item.split(':')
+ subkey1 = None
+ except ValueError:
+ group, key, subkey, subkey1 = item.split(':')
+
+ id = self.winId[item]
+ win = self.FindWindowById(id)
+ if win.GetName() == 'GetSelection':
+ value = win.GetSelection()
+ elif win.GetName() == 'GetColour':
+ value = tuple(win.GetValue())
+ else:
+ value = win.GetValue()
+
+ if subkey == 'position':
+ if subkey1 in ('x', 'y'):
+ value = float(value) / 100
+ if subkey1:
+ self.settings.Set(group, value, key, [subkey, subkey1])
+ else:
+ self.settings.Set(group, value, key, subkey)
+
+ self.toolWin.LoadSettings()
- def OnSave(self, event):
- """!Apply changes, update map and save settings of selected
- layer
- """
- # apply changes
- self.OnApply(None)
- if self.GetSelection() == self.page['id']:
- fileSettings = {}
- UserSettings.ReadSettingsFile(settings = fileSettings)
- fileSettings['nviz'] = UserSettings.Get(group = 'nviz')
- file = UserSettings.SaveToFile(fileSettings)
- self.parent.goutput.WriteLog(_('Nviz settings saved to file <%s>.') % file)
-
- def OnLoad(self, event):
- """!Apply button pressed"""
- self.LoadSettings()
-
- if event:
- event.Skip()
-
- def LoadSettings(self):
- """!Load saved Nviz settings and apply to current session"""
- UserSettings.ReadSettingsFile()
- settings = copy.deepcopy(UserSettings.Get(group = 'nviz'))
-
- for subgroup, key in settings.iteritems(): # view, surface, vector...
- for subkey, value in key.iteritems():
- for subvalue in value.keys():
- if subvalue == 'step':
- continue
- else:
- insetting = value[subvalue]
- if subgroup == 'view':
- for viewkey, viewitem in self.mapWindow.view[subkey].iteritems():
- if viewkey == subvalue:
- self.mapWindow.view[subkey][viewkey] = insetting
- else:
- continue
- else:
- for otherkey, otheritem in self.win[subgroup][subkey].iteritems():
- if type(otheritem) == data:
- for endkey, enditem in otheritem.iteritems():
- if endkey == subvalue:
- paramwin = self.FindWindowById(enditem)
- else:
- continue
- else:
- if otherkey == subvalue:
- paramwin = self.FindWindowById(otheritem)
- else:
- continue
- if type(insetting) in [tuple, list] and len(insetting) > 2:
- insetting = tuple(insetting)
- paramwin.SetColour(insetting)
- else:
- try:
- paramwin.SetValue(insetting)
- except:
- try:
- paramwin.SetStringSelection(insetting)
- except:
- continue
-
- self.toolWin.UpdateSettings()
- self.FindWindowById(self.win['view']['pos']).Draw()
- self.FindWindowById(self.win['view']['pos']).Refresh(False)
-
- self.mapWindow.render['quick'] = False
- self.mapWindow.Refresh(False)
-
def OnSave(self, event):
"""!Save button pressed
- Save settings to configuration file
+ Apply changes and save settings to configuration file
"""
+ self.OnApply(None)
fileSettings = {}
UserSettings.ReadSettingsFile(settings = fileSettings)
fileSettings['nviz'] = UserSettings.Get(group = 'nviz')
- fileName = UserSettings.SaveToFile(fileSettings)
- self.parent.GetLayerManager().goutput.WriteLog(_('3D view settings saved to file <%s>.') % fileName)
+ UserSettings.SaveToFile(fileSettings)
+ self.parent.goutput.WriteLog(
+ _('3D view settings saved to file <%s>.') % UserSettings.filePath)
self.Destroy()
Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/nviz_tools.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/nviz_tools.py 2011-11-25 14:58:21 UTC (rev 49356)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/nviz_tools.py 2011-11-25 15:10:47 UTC (rev 49357)
@@ -4,58 +4,238 @@
@brief Nviz (3D view) tools window
Classes:
+ - ScrolledPanel
+ - NTCValidator
+ - NumTextCtrl
+ - FloatSlider
+ - SymbolButton
- NvizToolWindow
- PositionWindow
- ViewPositionWindow
- LightPositionWindow
-(C) 2008-2010 by the GRASS Development Team
+(C) 2008-2011 by the GRASS Development Team
This program is free software under the GNU General Public
License (>=v2). Read the file COPYING that comes with GRASS
for details.
@author Martin Landa <landa.martin gmail.com> (Google SoC 2008/2010)
- at author Enhancements by Michael Barton <michael.barton at asu.edu>
+ at author Enhancements by Michael Barton <michael.barton asu.edu>
+ at author Anna Kratochvilova <kratochanna gmail.com> (Google SoC 2011)
"""
import os
import sys
import copy
import types
+import string
import wx
-import wx.lib.colourselect as csel
+import wx.lib.colourselect as csel
import wx.lib.scrolledpanel as SP
+import wx.lib.filebrowsebutton as filebrowse
+
try:
+ from wx.lib.buttons import ThemedGenBitmapTextButton as BitmapTextButton
+except ImportError: # not sure about TGBTButton version
+ from wx.lib.buttons import GenBitmapTextButton as BitmapTextButton
+
+try:
import wx.lib.agw.flatnotebook as FN
except ImportError:
import wx.lib.flatnotebook as FN
-
+try:
+ from agw import foldpanelbar as fpb
+except ImportError: # if it's not there locally, try the wxPython lib.
+ try:
+ import wx.lib.agw.foldpanelbar as fpb
+ except ImportError:
+ import wx.lib.foldpanelbar as fpb # versions <=2.5.5.1
+
import grass.script as grass
import globalvar
import gselect
import gcmd
+import colorrules
from preferences import globalSettings as UserSettings
-from preferences import PreferencesBaseDialog
+from gselect import VectorDBInfo
+
+from nviz_animation import EVT_ANIM_FIN, EVT_ANIM_UPDATE_IDX
try:
- from nviz_mapdisp import wxUpdateView, wxUpdateLight, wxUpdateProperties
+ from nviz_mapdisp import wxUpdateView, wxUpdateLight, wxUpdateProperties,\
+ wxUpdateCPlane
import wxnviz
except ImportError:
pass
+
from debug import Debug
+
+class ScrolledPanel(SP.ScrolledPanel):
+ """!Custom ScrolledPanel to avoid strange behaviour concerning focus"""
+ def __init__(self, parent):
+ SP.ScrolledPanel.__init__(self, parent = parent, id = wx.ID_ANY)
+ def OnChildFocus(self, event):
+ pass
+
+
+class NTCValidator(wx.PyValidator):
+ """!validates input in textctrls, taken from wxpython demo"""
+ def __init__(self, flag = None):
+ wx.PyValidator.__init__(self)
+ self.flag = flag
+ self.Bind(wx.EVT_CHAR, self.OnChar)
+
+ def Clone(self):
+ return NTCValidator(self.flag)
+
+ def OnChar(self, event):
+ key = event.GetKeyCode()
+ if key < wx.WXK_SPACE or key == wx.WXK_DELETE or key > 255:
+ event.Skip()
+ return
+ if self.flag == 'DIGIT_ONLY' and chr(key) in string.digits + '.-':
+ event.Skip()
+ return
+ if not wx.Validator_IsSilent():
+ wx.Bell()
+ # Returning without calling even.Skip eats the event before it
+ # gets to the text control
+ return
+
+class NumTextCtrl(wx.TextCtrl):
+ """!Class derived from wx.TextCtrl for numerical values only"""
+ def __init__(self, parent, **kwargs):
+## self.precision = kwargs.pop('prec')
+ wx.TextCtrl.__init__(self, parent = parent,
+ validator = NTCValidator(flag = 'DIGIT_ONLY'), **kwargs)
+
+
+ def SetValue(self, value):
+ super(NumTextCtrl, self).SetValue( str(value))
+
+ def GetValue(self):
+ val = super(NumTextCtrl, self).GetValue()
+ if val == '':
+ val = '0'
+ try:
+ return float(val)
+ except ValueError:
+ val = ''.join(''.join(val.split('-')).split('.'))
+ return float(val)
+
+ def SetRange(self, min, max):
+ pass
+
+class FloatSlider(wx.Slider):
+ """!Class derived from wx.Slider for floats"""
+ def __init__(self, **kwargs):
+ Debug.msg(1, "FloatSlider.__init__()")
+ wx.Slider.__init__(self, **kwargs)
+ self.coef = 1.
+ #init range
+ self.minValueOrig = 0
+ self.maxValueOrig = 1
+
+ def SetValue(self, value):
+ value *= self.coef
+ if abs(value) < 1 and value != 0:
+ while abs(value) < 1:
+ value *= 100
+ self.coef *= 100
+ super(FloatSlider, self).SetRange(self.minValueOrig * self.coef, self.maxValueOrig * self.coef)
+ super(FloatSlider, self).SetValue(value)
+
+ Debug.msg(4, "FloatSlider.SetValue(): value = %f" % value)
+
+ def SetRange(self, minValue, maxValue):
+ self.coef = 1.
+ self.minValueOrig = minValue
+ self.maxValueOrig = maxValue
+ if abs(minValue) < 1 or abs(maxValue) < 1:
+ while (abs(minValue) < 1 and minValue != 0) or (abs(maxValue) < 1 and maxValue != 0):
+ minValue *= 100
+ maxValue *= 100
+ self.coef *= 100
+ super(FloatSlider, self).SetValue(super(FloatSlider, self).GetValue() * self.coef)
+ super(FloatSlider, self).SetRange(minValue, maxValue)
+ Debug.msg(4, "FloatSlider.SetRange(): minValue = %f, maxValue = %f" % (minValue, maxValue))
+
+ def GetValue(self):
+ val = super(FloatSlider, self).GetValue()
+ Debug.msg(4, "FloatSlider.GetValue(): value = %f" % (val/self.coef))
+ return val/self.coef
+
+
+class SymbolButton(BitmapTextButton):
+ """!Button with symbol and label."""
+ def __init__(self, parent, usage, label, **kwargs):
+ """!Constructor
+
+ @param parent parent (usually wx.Panel)
+ @param usage determines usage and picture
+ @param label displayed label
+ """
+ size = (15, 15)
+ buffer = wx.EmptyBitmap(*size)
+ BitmapTextButton.__init__(self, parent = parent, label = " " + label, bitmap = buffer, **kwargs)
+
+ dc = wx.MemoryDC()
+ dc.SelectObject(buffer)
+ maskColor = wx.Color(255, 255, 255)
+ dc.SetBrush(wx.Brush(maskColor))
+ dc.Clear()
+
+ if usage == 'record':
+ self.DrawRecord(dc, size)
+ elif usage == 'stop':
+ self.DrawStop(dc, size)
+ elif usage == 'play':
+ self.DrawPlay(dc, size)
+ elif usage == 'pause':
+ self.DrawPause(dc, size)
+
+ buffer.SetMaskColour(maskColor)
+ self.SetBitmapLabel(buffer)
+ dc.SelectObject(wx.NullBitmap)
+
+ def DrawRecord(self, dc, size):
+ """!Draw record symbol"""
+ dc.SetBrush(wx.Brush(wx.Color(255, 0, 0)))
+ dc.DrawCircle(size[0]/2, size[1] / 2, size[0] / 2)
+
+ def DrawStop(self, dc, size):
+ """!Draw stop symbol"""
+ dc.SetBrush(wx.Brush(wx.Color(50, 50, 50)))
+ dc.DrawRectangle(0, 0, size[0], size[1])
+
+ def DrawPlay(self, dc, size):
+ """!Draw play symbol"""
+ dc.SetBrush(wx.Brush(wx.Color(0, 255, 0)))
+ points = (wx.Point(0, 0), wx.Point(0, size[1]), wx.Point(size[0], size[1] / 2))
+ dc.DrawPolygon(points)
+
+ def DrawPause(self, dc, size):
+ """!Draw pause symbol"""
+ dc.SetBrush(wx.Brush(wx.Color(50, 50, 50)))
+ dc.DrawRectangle(0, 0, 2 * size[0] / 5, size[1])
+ dc.DrawRectangle(3 * size[0] / 5, 0, 2 * size[0] / 5, size[1])
+
+
class NvizToolWindow(FN.FlatNotebook):
"""!Nviz (3D view) tools panel
"""
def __init__(self, parent, display, id = wx.ID_ANY,
- style = globalvar.FNPageStyle, **kwargs):
+ style = globalvar.FNPageStyle|FN.FNB_NO_X_BUTTON,
+ **kwargs):
+ Debug.msg(5, "NvizToolWindow.__init__()")
self.parent = parent # GMFrame
self.mapDisplay = display
self.mapWindow = display.GetWindow()
self._display = self.mapWindow.GetDisplay()
-
+
if globalvar.hasAgw:
kwargs['agwStyle'] = style
else:
@@ -73,34 +253,127 @@
# data page
self.AddPage(page = self._createDataPage(),
text = " %s " % _("Data"))
-
+
# appearance page
self.AddPage(page = self._createAppearancePage(),
text = " %s " % _("Appearance"))
+
+ # analysis page
+ self.AddPage(page = self._createAnalysisPage(),
+ text = " %s " % _("Analysis"))
+ # view page
+ self.AddPage(page = self._createAnimationPage(),
+ text = " %s " % _("Animation"))
self.UpdateSettings()
+
+ self.mapWindow.SetToolWin(self)
+
self.pageChanging = False
+ self.vetoGSelectEvt = False #when setting map, event is invoked
self.mapWindow.render['quick'] = False
self.mapWindow.Refresh(False)
# bindings
- self.Bind(wx.EVT_CLOSE, self.OnClose)
self.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.OnPageChanged)
+ self.Bind(wx.EVT_SIZE, self.OnSize)
+ self.Bind(EVT_ANIM_FIN, self.OnAnimationFinished)
+ self.Bind(EVT_ANIM_UPDATE_IDX, self.OnAnimationUpdateIndex)
+
+ Debug.msg(3, "NvizToolWindow.__init__()")
+
self.Update()
wx.CallAfter(self.SetPage, 'view')
- wx.CallAfter(self.notebookData.SetSelection, 0)
- wx.CallAfter(self.notebookAppearance.SetSelection, 0)
+ wx.CallAfter(self.UpdateScrolling, (self.foldpanelData, self.foldpanelAppear,
+ self.foldpanelAnalysis))
+ wx.CallAfter(self.SetInitialMaps)
+ def SetInitialMaps(self):
+ """!Set initial raster and vector map"""
+ for l_type in ('raster', 'vector', '3d-raster'):
+ selectedLayer = self.mapWindow.GetSelectedLayer()
+ layers = self.mapWindow.Map.GetListOfLayers(l_type = l_type, l_active = True)
+ if selectedLayer in layers:
+ selection = selectedLayer.GetName()
+ else:
+ try:
+ selection = layers[0].GetName()
+ except:
+ continue
+ if l_type == 'raster':
+ self.FindWindowById(self.win['surface']['map']).SetValue(selection)
+ self.FindWindowById(self.win['fringe']['map']).SetValue(selection)
+ elif l_type == 'vector':
+ self.FindWindowById(self.win['vector']['map']).SetValue(selection)
+ elif l_type == '3d-raster':
+ self.FindWindowById(self.win['volume']['map']).SetValue(selection)
+
+ def UpdateState(self, **kwargs):
+ if 'view' in kwargs:
+ self.mapWindow.view = kwargs['view']
+ self.FindWindowById(self.win['view']['position']).data = kwargs['view']
+ self.FindWindowById(self.win['view']['position']).PostDraw()
+ if 'iview' in kwargs:
+ self.mapWindow.iview = kwargs['iview']
+ if 'light' in kwargs:
+ self.mapWindow.light = kwargs['light']
+ self.FindWindowById(self.win['light']['position']).data = kwargs['light']
+ self.FindWindowById(self.win['light']['position']).PostDraw()
+ if 'fly' in kwargs:
+ self.mapWindow.fly['exag'] = kwargs['fly']['exag']
+
+ def LoadSettings(self):
+ """!Load Nviz settings and apply to current session"""
+ view = copy.deepcopy(UserSettings.Get(group = 'nviz', key = 'view')) # copy
+ light = copy.deepcopy(UserSettings.Get(group = 'nviz', key = 'light')) # copy
+ fly = copy.deepcopy(UserSettings.Get(group = 'nviz', key = 'fly')) # copy
+ self.UpdateState(view = view, light = light, fly = fly)
+ self.PostViewEvent(zExag = True)
+ self.PostLightEvent()
+ self.UpdatePage('view')
+ self.UpdatePage('light')
+
+ self.mapWindow.ReloadLayersData()
+ self.UpdatePage('surface')
+ self.UpdatePage('vector')
+ self.UpdateSettings()
+
def OnPageChanged(self, event):
new = event.GetSelection()
# self.ChangeSelection(new)
-
+
def PostViewEvent(self, zExag = False):
"""!Change view settings"""
event = wxUpdateView(zExag = zExag)
wx.PostEvent(self.mapWindow, event)
-
+
+ def PostLightEvent(self, refresh = False):
+ """!Change light settings"""
+ event = wxUpdateLight(refresh = refresh)
+ wx.PostEvent(self.mapWindow, event)
+
+ def OnSize(self, event):
+ """!After window is resized, update scrolling"""
+ # workaround to resize captionbars of foldpanelbar
+ wx.CallAfter(self.UpdateScrolling, (self.foldpanelData, self.foldpanelAppear,
+ self.foldpanelAnalysis))
+ event.Skip()
+
+ def OnPressCaption(self, event):
+ """!When foldpanel item collapsed/expanded, update scrollbars"""
+ foldpanel = event.GetBar().GetGrandParent().GetParent()
+ wx.CallAfter(self.UpdateScrolling, (foldpanel,))
+ event.Skip()
+
+ def UpdateScrolling(self, foldpanels):
+ """!Update scrollbars in foldpanel"""
+ for foldpanel in foldpanels:
+ length = foldpanel.GetPanelsLength(collapsed = 0, expanded = 0)
+ # virtual width is set to fixed value to suppress GTK warning
+ foldpanel.GetParent().SetVirtualSize((100, length[2]))
+ foldpanel.GetParent().Layout()
+
def _createViewPage(self):
"""!Create view settings page"""
panel = SP.ScrolledPanel(parent = self, id = wx.ID_ANY)
@@ -112,115 +385,106 @@
box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
label = " %s " % (_("Control View")))
boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
- gridSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
+ gridSizer = wx.GridBagSizer(vgap = 5, hgap = 10)
self.win['view'] = {}
# position
posSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
- posSizer.Add(item = wx.StaticText(panel, id = wx.ID_ANY, label = _("W")),
- pos = (1, 0), flag = wx.ALIGN_CENTER)
- posSizer.Add(item = wx.StaticText(panel, id = wx.ID_ANY, label = _("N")),
- pos = (0, 1), flag = wx.ALIGN_CENTER | wx.ALIGN_BOTTOM)
+
+ self._createCompass(panel = panel, sizer = posSizer, type = 'view')
+
view = ViewPositionWindow(panel, size = (175, 175),
mapwindow = self.mapWindow)
self.win['view']['position'] = view.GetId()
posSizer.Add(item = view,
pos = (1, 1), flag = wx.ALIGN_CENTER | wx.ALIGN_CENTER_VERTICAL)
- posSizer.Add(item = wx.StaticText(panel, id = wx.ID_ANY, label = _("S")),
- pos = (2, 1), flag = wx.ALIGN_CENTER | wx.ALIGN_TOP)
- posSizer.Add(item = wx.StaticText(panel, id = wx.ID_ANY, label = _("E")),
- pos = (1, 2), flag = wx.ALIGN_CENTER)
gridSizer.Add(item = posSizer, pos = (0, 0))
# perspective
# set initial defaults here (or perhaps in a default values file), not in user settings
+ #todo: consider setting an absolute max at 360 instead of undefined. (leave the default max value at pi)
self._createControl(panel, data = self.win['view'], name = 'persp',
- range = (1,100),
- bind = (self.OnViewChange, self.OnViewChanged, self.OnViewChangedSpin))
+ range = (1,180),
+ bind = (self.OnViewChange, self.OnViewChanged, self.OnViewChangedText))
+
gridSizer.Add(item = wx.StaticText(panel, id = wx.ID_ANY, label = _("Perspective:")),
pos = (1, 0), flag = wx.ALIGN_CENTER)
- gridSizer.Add(item = self.FindWindowById(self.win['view']['persp']['slider']), pos = (2, 0))
- gridSizer.Add(item = self.FindWindowById(self.win['view']['persp']['spin']), pos = (3, 0),
+ gridSizer.Add(item = self.FindWindowById(self.win['view']['persp']['slider']), pos = (2, 0),
+ flag = wx.ALIGN_CENTER)
+ gridSizer.Add(item = self.FindWindowById(self.win['view']['persp']['text']), pos = (3, 0),
flag = wx.ALIGN_CENTER)
# twist
self._createControl(panel, data = self.win['view'], name = 'twist',
range = (-180,180),
- bind = (self.OnViewChange, self.OnViewChanged, self.OnViewChangedSpin))
+ bind = (self.OnViewChange, self.OnViewChanged, self.OnViewChangedText))
gridSizer.Add(item = wx.StaticText(panel, id = wx.ID_ANY, label = _("Twist:")),
pos = (1, 1), flag = wx.ALIGN_CENTER)
gridSizer.Add(item = self.FindWindowById(self.win['view']['twist']['slider']), pos = (2, 1))
- gridSizer.Add(item = self.FindWindowById(self.win['view']['twist']['spin']), pos = (3, 1),
+ gridSizer.Add(item = self.FindWindowById(self.win['view']['twist']['text']), pos = (3, 1),
flag = wx.ALIGN_CENTER)
# height + z-exag
self._createControl(panel, data = self.win['view'], name = 'height', sliderHor = False,
range = (0, 1),
- bind = (self.OnViewChange, self.OnViewChanged, self.OnViewChangedSpin))
-
+ bind = (self.OnViewChange, self.OnViewChanged, self.OnViewChangedText))
self._createControl(panel, data = self.win['view'], name = 'z-exag', sliderHor = False,
- range = (0, 5),
- bind = (self.OnViewChange, self.OnViewChanged, self.OnViewChangedSpin))
+ range = (0, 10), floatSlider = True,
+ bind = (self.OnViewChange, self.OnViewChanged, self.OnViewChangedText))
self.FindWindowById(self.win['view']['z-exag']['slider']).SetValue(1)
- self.FindWindowById(self.win['view']['z-exag']['spin']).SetValue(1)
+ self.FindWindowById(self.win['view']['z-exag']['text']).SetValue(1)
heightSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
heightSizer.Add(item = wx.StaticText(panel, id = wx.ID_ANY, label = _("Height:")),
- pos = (0, 0), flag = wx.ALIGN_LEFT, span = (1, 2))
+ pos = (0, 0), flag = wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL, span = (1, 2))
heightSizer.Add(item = self.FindWindowById(self.win['view']['height']['slider']),
flag = wx.ALIGN_RIGHT, pos = (1, 0))
- heightSizer.Add(item = self.FindWindowById(self.win['view']['height']['spin']),
- flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.TOP |
- wx.BOTTOM | wx.RIGHT, pos = (1, 1))
+ heightSizer.Add(item = self.FindWindowById(self.win['view']['height']['text']),
+ flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT, pos = (1, 1))
heightSizer.Add(item = wx.StaticText(panel, id = wx.ID_ANY, label = _("Z-exag:")),
- pos = (0, 2), flag = wx.ALIGN_LEFT, span = (1, 2))
+ pos = (0, 2), flag = wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL, span = (1, 2))
heightSizer.Add(item = self.FindWindowById(self.win['view']['z-exag']['slider']),
flag = wx.ALIGN_RIGHT, pos = (1, 2))
- heightSizer.Add(item = self.FindWindowById(self.win['view']['z-exag']['spin']),
+ heightSizer.Add(item = self.FindWindowById(self.win['view']['z-exag']['text']),
flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.TOP |
wx.BOTTOM | wx.RIGHT, pos = (1, 3))
- gridSizer.Add(item = heightSizer, pos = (0, 1), flag = wx.ALIGN_RIGHT)
+ gridSizer.Add(item = heightSizer, pos = (0, 1), flag = wx.ALIGN_CENTER)
# view setup + reset
viewSizer = wx.BoxSizer(wx.HORIZONTAL)
-
viewSizer.Add(item = wx.StaticText(panel, id = wx.ID_ANY,
- label = _("Look at:")),
+ label = _("Look:")),
flag = wx.ALL | wx.ALIGN_CENTER_VERTICAL,
border = 5)
-
- viewType = wx.Choice (parent = panel, id = wx.ID_ANY, size = (125, -1),
- choices = [_("top"),
- _("north"),
- _("south"),
- _("east"),
- _("west"),
- _("north-west"),
- _("north-east"),
- _("south-east"),
- _("south-west")])
- viewType.SetSelection(0)
- viewType.Bind(wx.EVT_CHOICE, self.OnLookAt)
- # self.win['lookAt'] = viewType.GetId()
- viewSizer.Add(item = viewType,
- flag = wx.ALL | wx.ALIGN_CENTER_VERTICAL,
+ here = wx.ToggleButton(panel, id = wx.ID_ANY, label = _("here"))
+ here.Bind(wx.EVT_TOGGLEBUTTON, self.OnLookAt)
+ here.SetName('here')
+ viewSizer.Add(item = here, flag = wx.TOP|wx.BOTTOM|wx.LEFT|wx.ALIGN_CENTER_VERTICAL,
border = 5)
-
- reset = wx.Button(panel, id = wx.ID_ANY, label = _("Reset"))
+
+ center = wx.Button(panel, id = wx.ID_ANY, label = _("center"))
+ center.Bind(wx.EVT_BUTTON, self.OnLookAt)
+ center.SetName('center')
+ viewSizer.Add(item = center, flag = wx.TOP|wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL,
+ border = 5)
+
+ top = wx.Button(panel, id = wx.ID_ANY, label = _("top"))
+ top.Bind(wx.EVT_BUTTON, self.OnLookAt)
+ top.SetName('top')
+ viewSizer.Add(item = top, flag = wx.TOP|wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL,
+ border = 5)
+
+ reset = wx.Button(panel, id = wx.ID_ANY, label = _("reset"))
reset.SetToolTipString(_("Reset to default view"))
- # self.win['reset'] = reset.GetId()
reset.Bind(wx.EVT_BUTTON, self.OnResetView)
-
- viewSizer.Add(item = wx.Size(-1, -1), proportion = 1,
- flag = wx.EXPAND)
viewSizer.Add(item = reset, proportion = 0,
- flag = wx.ALL | wx.ALIGN_RIGHT,
+ flag = wx.TOP|wx.BOTTOM|wx.RIGHT| wx.ALIGN_RIGHT,
border = 5)
gridSizer.AddGrowableCol(2)
- gridSizer.Add(item = viewSizer, pos = (4, 0), span = (1, 2),
+ gridSizer.Add(item = viewSizer, pos = (4, 0), span = (1, 3),
flag = wx.EXPAND)
# body
@@ -237,6 +501,7 @@
gridSizer.AddGrowableCol(0)
# background color
+ self.win['view']['background'] = {}
gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
label = _("Background color:")),
pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL)
@@ -245,7 +510,7 @@
colour = UserSettings.Get(group = 'nviz', key = 'view',
subkey = ['background', 'color']),
size = globalvar.DIALOG_COLOR_SIZE)
- self.win['view']['bgcolor'] = color.GetId()
+ self.win['view']['background']['color'] = color.GetId()
color.Bind(csel.EVT_COLOURSELECT, self.OnBgColor)
gridSizer.Add(item = color, pos = (0, 1))
@@ -258,60 +523,280 @@
panel.SetSizer(pageSizer)
return panel
-
+
+ def _createAnimationPage(self):
+ """!Create view settings page"""
+ panel = SP.ScrolledPanel(parent = self, id = wx.ID_ANY)
+ panel.SetupScrolling(scroll_x = False)
+ self.page['animation'] = { 'id' : 0,
+ 'notebook' : self.GetId()}
+
+ pageSizer = wx.BoxSizer(wx.VERTICAL)
+ box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
+ label = " %s " % (_("Animation")))
+ boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+ hSizer = wx.BoxSizer(wx.HORIZONTAL)
+
+ self.win['anim'] = {}
+ # animation help text
+ help = wx.StaticText(parent = panel, id = wx.ID_ANY,
+ label = _("Press 'Record' button and start changing the view. "
+ "It is recommended to use fly-through mode "
+ "(Map Display toolbar) to achieve smooth motion."))
+ self.win['anim']['help'] = help.GetId()
+ hSizer.Add(item = help, proportion = 0)
+ boxSizer.Add(item = hSizer, proportion = 1,
+ flag = wx.ALL | wx.EXPAND, border = 5)
+
+ # animation controls
+ hSizer = wx.BoxSizer(wx.HORIZONTAL)
+ record = SymbolButton(parent = panel, id = wx.ID_ANY,
+ usage = "record", label = _("Record"))
+ play = SymbolButton(parent = panel, id = wx.ID_ANY,
+ usage = "play", label = _("Play"))
+ pause = SymbolButton(parent = panel, id = wx.ID_ANY,
+ usage = "pause", label = _("Pause"))
+ stop = SymbolButton(parent = panel, id = wx.ID_ANY,
+ usage = "stop", label = _("Stop"))
+
+ self.win['anim']['record'] = record.GetId()
+ self.win['anim']['play'] = play.GetId()
+ self.win['anim']['pause'] = pause.GetId()
+ self.win['anim']['stop'] = stop.GetId()
+
+ self._createControl(panel, data = self.win['anim'], name = 'frameIndex',
+ range = (0, 1), floatSlider = False,
+ bind = (self.OnFrameIndex, None, self.OnFrameIndexText))
+ frameSlider = self.FindWindowById(self.win['anim']['frameIndex']['slider'])
+ frameText = self.FindWindowById(self.win['anim']['frameIndex']['text'])
+ infoLabel = wx.StaticText(parent = panel, id = wx.ID_ANY, label = _("Total number of frames :"))
+ info = wx.StaticText(parent = panel, id = wx.ID_ANY)
+ self.win['anim']['info'] = info.GetId()
+
+ fpsLabel = wx.StaticText(parent = panel, id = wx.ID_ANY, label = _("Frame rate (FPS):"))
+ fps = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
+ initial = UserSettings.Get(group = 'nviz', key = 'animation', subkey = 'fps'),
+ min = 1,
+ max = 50)
+ self.win['anim']['fps'] = fps.GetId()
+ fps.SetToolTipString(_("Frames are recorded with given frequency (FPS). "))
+
+ record.Bind(wx.EVT_BUTTON, self.OnRecord)
+ play.Bind(wx.EVT_BUTTON, self.OnPlay)
+ stop.Bind(wx.EVT_BUTTON, self.OnStop)
+ pause.Bind(wx.EVT_BUTTON, self.OnPause)
+ fps.Bind(wx.EVT_SPINCTRL, self.OnFPS)
+
+ hSizer.Add(item = record, proportion = 0)
+ hSizer.Add(item = play, proportion = 0)
+ hSizer.Add(item = pause, proportion = 0)
+ hSizer.Add(item = stop, proportion = 0)
+ boxSizer.Add(item = hSizer, proportion = 0,
+ flag = wx.ALL | wx.EXPAND, border = 3)
+
+ sliderBox = wx.BoxSizer(wx.HORIZONTAL)
+ sliderBox.Add(item = frameSlider, proportion = 1, border = 5, flag = wx.EXPAND | wx.RIGHT)
+ sliderBox.Add(item = frameText, proportion = 0, border = 5, flag = wx.EXPAND| wx.RIGHT | wx.LEFT)
+ boxSizer.Add(item = sliderBox, proportion = 0, flag = wx.EXPAND)
+
+ # total number of frames
+ hSizer = wx.BoxSizer(wx.HORIZONTAL)
+ hSizer.Add(item = infoLabel, proportion = 0, flag = wx.RIGHT, border = 5)
+ hSizer.Add(item = info, proportion = 0, flag = wx.LEFT, border = 5)
+
+ boxSizer.Add(item = hSizer, proportion = 0,
+ flag = wx.ALL | wx.EXPAND, border = 5)
+
+ # frames per second
+ hSizer = wx.BoxSizer(wx.HORIZONTAL)
+ hSizer.Add(item = fpsLabel, proportion = 0, flag = wx.RIGHT | wx.ALIGN_CENTER_VERTICAL, border = 5)
+ hSizer.Add(item = fps, proportion = 0, flag = wx.LEFT | wx.ALIGN_CENTER_VERTICAL, border = 5)
+
+ boxSizer.Add(item = hSizer, proportion = 0,
+ flag = wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border = 5)
+ pageSizer.Add(item = boxSizer, proportion = 0,
+ flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
+ border = 3)
+
+ # save animation
+ self.win['anim']['save'] = {}
+ self.win['anim']['save']['image'] = {}
+ box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
+ label = " %s " % (_("Save image sequence")))
+ boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+ vSizer = wx.BoxSizer(wx.VERTICAL)
+ gridSizer = wx.GridBagSizer(vgap = 5, hgap = 10)
+
+ pwd = os.getcwd()
+ dir = filebrowse.DirBrowseButton(parent = panel, id = wx.ID_ANY,
+ labelText = _("Choose a directory:"),
+ dialogTitle = _("Choose a directory for images"),
+ buttonText = _('Browse'),
+ startDirectory = pwd)
+ dir.SetValue(pwd)
+ prefixLabel = wx.StaticText(parent = panel, id = wx.ID_ANY, label = _("File prefix:"))
+ prefixCtrl = wx.TextCtrl(parent = panel, id = wx.ID_ANY, size = (100, -1),
+ value = UserSettings.Get(group = 'nviz',
+ key = 'animation', subkey = 'prefix'))
+ prefixCtrl.SetToolTipString(_("Generated files names will look like this: prefix_1.ppm, prefix_2.ppm, ..."))
+ fileTypeLabel = wx.StaticText(parent = panel, id = wx.ID_ANY, label = _("File format:"))
+ fileTypeCtrl = wx.Choice(parent = panel, id = wx.ID_ANY, choices = ["PPM", "TIF"])
+
+ save = wx.Button(parent = panel, id = wx.ID_ANY,
+ label = "Save")
+
+ self.win['anim']['save']['image']['dir'] = dir.GetId()
+ self.win['anim']['save']['image']['prefix'] = prefixCtrl.GetId()
+ self.win['anim']['save']['image']['format'] = fileTypeCtrl.GetId()
+ self.win['anim']['save']['image']['confirm'] = save.GetId()
+
+ boxSizer.Add(item = dir, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 3)
+
+ gridSizer.Add(item = prefixLabel, pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT)
+ gridSizer.Add(item = prefixCtrl, pos = (0, 1), flag = wx.EXPAND )
+ gridSizer.Add(item = fileTypeLabel, pos = (1, 0), flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT)
+ gridSizer.Add(item = fileTypeCtrl, pos = (1, 1), flag = wx.EXPAND )
+
+ boxSizer.Add(item = gridSizer, proportion = 1,
+ flag = wx.ALL | wx.EXPAND, border = 5)
+ boxSizer.Add(item = save, proportion = 0, flag = wx.ALL | wx.ALIGN_RIGHT, border = 5)
+
+ save.Bind(wx.EVT_BUTTON, self.OnSaveAnimation)
+
+ pageSizer.Add(item = boxSizer, proportion = 0,
+ flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
+ border = 3)
+
+ panel.SetSizer(pageSizer)
+
+ return panel
+
def _createDataPage(self):
"""!Create data (surface, vector, volume) settings page"""
- if globalvar.hasAgw:
- self.notebookData = FN.FlatNotebook(parent = self, id = wx.ID_ANY,
- agwStyle = globalvar.FNPageDStyle)
- else:
- self.notebookData = FN.FlatNotebook(parent = self, id = wx.ID_ANY,
- style = globalvar.FNPageDStyle)
+
+ self.mainPanelData = ScrolledPanel(parent = self)
+ self.mainPanelData.SetupScrolling(scroll_x = False)
+## style = fpb.CaptionBarStyle()
+## style.SetCaptionStyle(fpb.CAPTIONBAR_FILLED_RECTANGLE)
+## style.SetFirstColour(wx.Color(250,250,250))
+ try:# wxpython <= 2.8.10
+ self.foldpanelData = fpb.FoldPanelBar(parent = self.mainPanelData, id = wx.ID_ANY,
+ style = fpb.FPB_DEFAULT_STYLE,
+ extraStyle = fpb.FPB_SINGLE_FOLD)
+ except:
+ try:# wxpython >= 2.8.11
+ self.foldpanelData = fpb.FoldPanelBar(parent = self.mainPanelData, id = wx.ID_ANY,
+ agwStyle = fpb.FPB_SINGLE_FOLD)
+ except: # to be sure
+ self.foldpanelData = fpb.FoldPanelBar(parent = self.mainPanelData, id = wx.ID_ANY,
+ style = fpb.FPB_SINGLE_FOLD)
+
+
+ self.foldpanelData.Bind(fpb.EVT_CAPTIONBAR, self.OnPressCaption)
+
+
# surface page
- self.notebookData.AddPage(page = self._createSurfacePage(),
- text = " %s " % _("Surface"))
- self.EnablePage('surface', False)
+ self.surfacePanel = self.foldpanelData.AddFoldPanel(_("Surface"), collapsed = False)
+ self.foldpanelData.AddFoldPanelWindow(self.surfacePanel,
+ window = self._createSurfacePage(parent = self.surfacePanel), flags = fpb.FPB_ALIGN_WIDTH)
+ self.EnablePage("surface", enabled = False)
+ # constant page
+ constantPanel = self.foldpanelData.AddFoldPanel(_("Constant surface"), collapsed = True)
+ self.foldpanelData.AddFoldPanelWindow(constantPanel,
+ window = self._createConstantPage(parent = constantPanel), flags = fpb.FPB_ALIGN_WIDTH)
+ self.EnablePage("constant", enabled = False)
# vector page
- self.notebookData.AddPage(page = self._createVectorPage(),
- text = " %s " % _("Vector"))
- self.EnablePage('vector', False)
+ vectorPanel = self.foldpanelData.AddFoldPanel(_("Vector"), collapsed = True)
+ self.foldpanelData.AddFoldPanelWindow(vectorPanel,
+ window = self._createVectorPage(parent = vectorPanel), flags = fpb.FPB_ALIGN_WIDTH)
+ self.EnablePage("vector", enabled = False)
# volume page
- self.notebookData.AddPage(page = self._createVolumePage(),
- text = " %s " % _("Volume"))
- self.EnablePage('volume', False)
+ volumePanel = self.foldpanelData.AddFoldPanel(_("Volume"), collapsed = True)
+ self.foldpanelData.AddFoldPanelWindow(volumePanel,
+ window = self._createVolumePage(parent = volumePanel), flags = fpb.FPB_ALIGN_WIDTH)
+ self.EnablePage("volume", enabled = False)
- return self.notebookData
-
+## self.foldpanelData.ApplyCaptionStyleAll(style)
+
+ sizer = wx.BoxSizer(wx.VERTICAL)
+ sizer.Add(self.foldpanelData, proportion = 1, flag = wx.EXPAND)
+ self.mainPanelData.SetSizer(sizer)
+ self.mainPanelData.Layout()
+ self.mainPanelData.Fit()
+
+ return self.mainPanelData
+
+
def _createAppearancePage(self):
"""!Create data (surface, vector, volume) settings page"""
- if globalvar.hasAgw:
- self.notebookAppearance = FN.FlatNotebook(parent = self, id = wx.ID_ANY,
- agwStyle = globalvar.FNPageDStyle)
- else:
- self.notebookAppearance = FN.FlatNotebook(parent = self, id = wx.ID_ANY,
- style = globalvar.FNPageDStyle)
+ self.mainPanelAppear = ScrolledPanel(parent = self)
+ self.mainPanelAppear.SetupScrolling(scroll_x = False)
+ try:# wxpython <= 2.8.10
+ self.foldpanelAppear = fpb.FoldPanelBar(parent = self.mainPanelAppear, id = wx.ID_ANY,
+ style = fpb.FPB_DEFAULT_STYLE,
+ extraStyle = fpb.FPB_SINGLE_FOLD)
+ except:
+ try:# wxpython >= 2.8.11
+ self.foldpanelAppear = fpb.FoldPanelBar(parent = self.mainPanelAppear, id = wx.ID_ANY,
+ agwStyle = fpb.FPB_SINGLE_FOLD)
+ except: # to be sure
+ self.foldpanelAppear = fpb.FoldPanelBar(parent = self.mainPanelAppear, id = wx.ID_ANY,
+ style = fpb.FPB_SINGLE_FOLD)
+
+ self.foldpanelAppear.Bind(fpb.EVT_CAPTIONBAR, self.OnPressCaption)
# light page
- self.notebookAppearance.AddPage(page = self._createLightPage(),
- text = " %s " % _("Lighting"))
+ lightPanel = self.foldpanelAppear.AddFoldPanel(_("Lighting"), collapsed = False)
+ self.foldpanelAppear.AddFoldPanelWindow(lightPanel,
+ window = self._createLightPage(parent = lightPanel), flags = fpb.FPB_ALIGN_WIDTH)
# fringe page
- self.notebookAppearance.AddPage(page = self._createFringePage(),
- text = " %s " % _("Fringe"))
+ fringePanel = self.foldpanelAppear.AddFoldPanel(_("Fringe"), collapsed = True)
+ self.foldpanelAppear.AddFoldPanelWindow(fringePanel,
+ window = self._createFringePage(parent = fringePanel), flags = fpb.FPB_ALIGN_WIDTH)
+
self.EnablePage('fringe', False)
-
- return self.notebookAppearance
+
+ # decoration page
+ decorationPanel = self.foldpanelAppear.AddFoldPanel(_("Decorations"), collapsed = True)
+ self.foldpanelAppear.AddFoldPanelWindow(decorationPanel,
+ window = self._createDecorationPage(parent = decorationPanel), flags = fpb.FPB_ALIGN_WIDTH)
+
+
+ sizer = wx.BoxSizer(wx.VERTICAL)
+ sizer.Add(self.foldpanelAppear, proportion = 1, flag = wx.EXPAND)
+ self.mainPanelAppear.SetSizer(sizer)
+ self.mainPanelAppear.Layout()
+ self.mainPanelAppear.Fit()
+ return self.mainPanelAppear
- def _createSurfacePage(self):
+ def _createAnalysisPage(self):
+ """!Create data analysis (cutting planes, ...) page"""
+ self.mainPanelAnalysis = ScrolledPanel(parent = self)
+ self.mainPanelAnalysis.SetupScrolling(scroll_x = False)
+ self.foldpanelAnalysis = fpb.FoldPanelBar(parent = self.mainPanelAnalysis, id = wx.ID_ANY,
+ style = fpb.FPB_SINGLE_FOLD)
+ self.foldpanelAnalysis.Bind(fpb.EVT_CAPTIONBAR, self.OnPressCaption)
+ # cutting planes page
+ cplanePanel = self.foldpanelAnalysis.AddFoldPanel(_("Cutting planes"), collapsed = False)
+ self.foldpanelAnalysis.AddFoldPanelWindow(cplanePanel,
+ window = self._createCPlanePage(parent = cplanePanel), flags = fpb.FPB_ALIGN_WIDTH)
+
+ sizer = wx.BoxSizer(wx.VERTICAL)
+ sizer.Add(self.foldpanelAnalysis, proportion = 1, flag = wx.EXPAND)
+ self.mainPanelAnalysis.SetSizer(sizer)
+ self.mainPanelAnalysis.Layout()
+ self.mainPanelAnalysis.Fit()
+ return self.mainPanelAnalysis
+
+ def _createSurfacePage(self, parent):
"""!Create view settings page"""
- panel = SP.ScrolledPanel(parent = self, id = wx.ID_ANY)
- panel.SetupScrolling(scroll_x = False)
+ panel = wx.Panel(parent = parent, id = wx.ID_ANY)
self.page['surface'] = { 'id' : 0,
- 'panel' : panel.GetId(),
- 'notebook' : self.notebookData.GetId() }
+ 'notebook' : self.foldpanelData.GetId() }
pageSizer = wx.BoxSizer(wx.VERTICAL)
self.win['surface'] = {}
@@ -337,99 +822,14 @@
border = 3)
#
- # surface attributes
- #
- box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
- label = " %s " % (_("Surface attributes")))
- boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
- gridSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
-
- # type
- self.win['surface']['attr'] = {}
- row = 0
- for code, attrb in (('topo', _("Topography")),
- ('color', _("Color")),
- ('mask', _("Mask")),
- ('transp', _("Transparency")),
- ('shine', _("Shininess")),
- ('emit', _("Emission"))):
- self.win['surface'][code] = {}
- gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = attrb + ':'),
- pos = (row, 0), flag = wx.ALIGN_CENTER_VERTICAL)
- use = wx.Choice (parent = panel, id = wx.ID_ANY, size = (100, -1),
- choices = [_("map")])
-
- if code not in ('topo', 'color', 'shine'):
- use.Insert(item = _("unset"), pos = 0)
- self.win['surface'][code]['required'] = False
- else:
- self.win['surface'][code]['required'] = True
- if code != 'mask':
- use.Append(item = _('constant'))
- self.win['surface'][code]['use'] = use.GetId()
- use.Bind(wx.EVT_CHOICE, self.OnMapObjUse)
- gridSizer.Add(item = use, flag = wx.ALIGN_CENTER_VERTICAL,
- pos = (row, 1))
-
- map = gselect.Select(parent = panel, id = wx.ID_ANY,
- # size = globalvar.DIALOG_GSELECT_SIZE,
- size = (200, -1),
- type = "raster")
- self.win['surface'][code]['map'] = map.GetId() - 1 # FIXME
- map.Bind(wx.EVT_TEXT, self.OnSurfaceMap)
- # changing map topography not allowed
- if code == 'topo':
- map.Enable(False)
- gridSizer.Add(item = map, flag = wx.ALIGN_CENTER_VERTICAL,
- pos = (row, 2))
-
- if code == 'color':
- value = csel.ColourSelect(panel, id = wx.ID_ANY,
- colour = (0,0,0),
- size = globalvar.DIALOG_COLOR_SIZE)
- value.Bind(csel.EVT_COLOURSELECT, self.OnSurfaceMap)
- elif code == 'mask':
- value = None
- else:
- value = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
- initial = 0)
- if code == 'topo':
- value.SetRange(minVal = -1e9, maxVal = 1e9)
- elif code in ('shine', 'transp', 'emit'):
- value.SetRange(minVal = 0, maxVal = 255)
- else:
- value.SetRange(minVal = 0, maxVal = 100)
- value.Bind(wx.EVT_TEXT, self.OnSurfaceMap)
-
- if value:
- self.win['surface'][code]['const'] = value.GetId()
- value.Enable(False)
- gridSizer.Add(item = value, flag = wx.ALIGN_CENTER_VERTICAL,
- pos = (row, 3))
- else:
- self.win['surface'][code]['const'] = None
-
- self.SetMapObjUseMap(nvizType = 'surface',
- attrb = code) # -> enable map / disable constant
-
- row += 1
-
- boxSizer.Add(item = gridSizer, proportion = 1,
- flag = wx.ALL | wx.EXPAND, border = 3)
- pageSizer.Add(item = boxSizer, proportion = 0,
- flag = wx.EXPAND | wx.ALL,
- border = 3)
-
- #
# draw
#
self.win['surface']['draw'] = {}
box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
label = " %s " % (_("Draw")))
boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
- gridSizer = wx.GridBagSizer(vgap = 5, hgap = 5)
- gridSizer.AddGrowableCol(6)
+ gridSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
+ gridSizer.AddGrowableCol(3)
# mode
gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
@@ -439,103 +839,88 @@
choices = [_("coarse"),
_("fine"),
_("both")])
- mode.SetSelection(0)
mode.SetName("selection")
mode.Bind(wx.EVT_CHOICE, self.OnSurfaceMode)
self.win['surface']['draw']['mode'] = mode.GetId()
- gridSizer.Add(item = mode, flag = wx.ALIGN_CENTER_VERTICAL,
- pos = (0, 1))
+ gridSizer.Add(item = mode, flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND,
+ pos = (0, 1),span = (1, 2))
# shading
gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
label = _("Shading:")),
- pos = (0, 2), flag = wx.ALIGN_CENTER_VERTICAL)
- shade = wx.Choice (parent = panel, id = wx.ID_ANY, size = (100, -1),
+ pos = (0, 3), flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT)
+ shade = wx.Choice (parent = panel, id = wx.ID_ANY, size = (-1, -1),
choices = [_("flat"),
_("gouraud")])
shade.SetName("selection")
self.win['surface']['draw']['shading'] = shade.GetId()
shade.Bind(wx.EVT_CHOICE, self.OnSurfaceMode)
gridSizer.Add(item = shade, flag = wx.ALIGN_CENTER_VERTICAL,
- pos = (0, 3))
+ pos = (0, 4))
# set to all
all = wx.Button(panel, id = wx.ID_ANY, label = _("Set to all"))
all.SetToolTipString(_("Use draw settings for all loaded surfaces"))
all.Bind(wx.EVT_BUTTON, self.OnSurfaceModeAll)
gridSizer.Add(item = all, flag = wx.ALL | wx.ALIGN_CENTER_VERTICAL | wx.EXPAND,
- pos = (0, 4), span = (1,2), border = 3 )
+ pos = (3, 4))
+ self.win['surface']['all'] = all.GetId()
# resolution coarse
gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = _("Coarse:")),
- pos = (1, 0), flag = wx.ALIGN_CENTER_VERTICAL)
- resSizer = wx.BoxSizer(wx.HORIZONTAL)
- resSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = _("res.")),
- flag = wx.ALL | wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL,
- border = 3)
+ label = _("Coarse mode:")),
+ pos = (2, 0), flag = wx.ALIGN_CENTER_VERTICAL)
+ gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
+ label = _("resolution:")),
+ pos = (2, 1), flag = wx.ALIGN_CENTER_VERTICAL)
resC = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
initial = 6,
min = 1,
max = 100)
resC.SetName("value")
- resC.SetValue(6)
-
self.win['surface']['draw']['res-coarse'] = resC.GetId()
resC.Bind(wx.EVT_SPINCTRL, self.OnSurfaceResolution)
- resSizer.Add(item = resC, flag = wx.ALL | wx.ALIGN_LEFT |
- wx.ALIGN_CENTER_VERTICAL, border = 3)
- gridSizer.Add(item = resSizer, pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL)
+ gridSizer.Add(item = resC, pos = (2, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT)
# Coarse style
gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = _("style")),
- pos = (1, 2), flag = wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL)
+ label = _("style:")),
+ pos = (3, 1), flag = wx.ALIGN_CENTER_VERTICAL)
style = wx.Choice (parent = panel, id = wx.ID_ANY, size = (100, -1),
choices = [_("wire"),
_("surface")])
style.SetName("selection")
self.win['surface']['draw']['style'] = style.GetId()
style.Bind(wx.EVT_CHOICE, self.OnSurfaceMode)
- gridSizer.Add(item = style, flag = wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL,
- pos = (1, 3))
+ gridSizer.Add(item = style, flag = wx.ALIGN_CENTER_VERTICAL,
+ pos = (3, 2))
# color
- gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = _("wire color")),
- pos = (1, 4), flag = wx.ALIGN_CENTER_VERTICAL |
- wx.ALIGN_RIGHT | wx.LEFT, border = 3)
color = csel.ColourSelect(panel, id = wx.ID_ANY,
size = globalvar.DIALOG_COLOR_SIZE)
- color.SetColour((136,136,136))
color.SetName("colour")
color.Bind(csel.EVT_COLOURSELECT, self.OnSurfaceWireColor)
+ color.SetToolTipString(_("Change wire color"))
self.win['surface']['draw']['wire-color'] = color.GetId()
gridSizer.Add(item = color, flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT,
- pos = (1, 5))
+ pos = (3, 3))
# resolution fine
gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = _("Fine:")),
- pos = (2, 0), flag = wx.ALIGN_CENTER_VERTICAL)
+ label = _("Fine mode:")),
+ pos = (1, 0), flag = wx.ALIGN_CENTER_VERTICAL)
- resSizer = wx.BoxSizer(wx.HORIZONTAL)
- resSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = _("res.")),
- flag = wx.ALL | wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL,
- border = 3)
+ gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
+ label = _("resolution:")),
+ pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL)
resF = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
initial = 3,
min = 1,
max = 100)
resF.SetName("value")
- resF.SetValue(3)
self.win['surface']['draw']['res-fine'] = resF.GetId()
resF.Bind(wx.EVT_SPINCTRL, self.OnSurfaceResolution)
- resSizer.Add(item = resF, flag = wx.ALL | wx.ALIGN_LEFT |
- wx.ALIGN_CENTER_VERTICAL, border = 3)
- gridSizer.Add(item = resSizer, pos = (2, 1), flag = wx.ALIGN_CENTER_VERTICAL)
+ gridSizer.Add(item = resF, pos = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT)
boxSizer.Add(item = gridSizer, proportion = 1,
flag = wx.ALL | wx.EXPAND, border = 3)
@@ -544,33 +929,80 @@
border = 3)
#
- # mask
+ # surface attributes
#
box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
- label = " %s " % (_("Mask")))
+ label = " %s " % (_("Surface attributes")))
boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
- gridSizer = wx.GridBagSizer(vgap = 5, hgap = 5)
+ gridSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
+ gridSizer.AddGrowableCol(2)
- gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = _("Mask zeros:")),
- pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL)
-
- elev = wx.CheckBox(parent = panel, id = wx.ID_ANY,
- label = _("by elevation"))
- elev.Enable(False) # TODO: not implemented yet
- gridSizer.Add(item = elev, pos = (0, 1))
-
- color = wx.CheckBox(parent = panel, id = wx.ID_ANY,
- label = _("by color"))
- color.Enable(False) # TODO: not implemented yet
- gridSizer.Add(item = color, pos = (0, 2))
-
- boxSizer.Add(item = gridSizer, proportion = 1,
+ # type
+ self.win['surface']['attr'] = {}
+ row = 0
+ for code, attrb in (('color', _("Color")),
+ ('mask', _("Mask")),
+ ('transp', _("Transparency")),
+ ('shine', _("Shininess"))):
+ self.win['surface'][code] = {}
+ gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
+ label = attrb + ':'),
+ pos = (row, 0), flag = wx.ALIGN_CENTER_VERTICAL)
+ use = wx.Choice (parent = panel, id = wx.ID_ANY, size = (100, -1),
+ choices = [_("map")])
+
+ if code not in ('color', 'shine'):
+ use.Insert(item = _("unset"), pos = 0)
+ self.win['surface'][code]['required'] = False
+ else:
+ self.win['surface'][code]['required'] = True
+ if code != 'mask':
+ use.Append(item = _('constant'))
+ self.win['surface'][code]['use'] = use.GetId()
+ use.Bind(wx.EVT_CHOICE, self.OnMapObjUse)
+ gridSizer.Add(item = use, flag = wx.ALIGN_CENTER_VERTICAL,
+ pos = (row, 1))
+
+ map = gselect.Select(parent = panel, id = wx.ID_ANY,
+ # size = globalvar.DIALOG_GSELECT_SIZE,
+ size = (-1, -1),
+ type = "raster")
+ self.win['surface'][code]['map'] = map.GetId() - 1 # FIXME
+ map.Bind(wx.EVT_TEXT, self.OnSurfaceMap)
+ gridSizer.Add(item = map, flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND,
+ pos = (row, 2))
+
+ if code == 'color':
+ color = UserSettings.Get(group = 'nviz', key = 'surface', subkey = ['color', 'value'])
+ value = csel.ColourSelect(panel, id = wx.ID_ANY,
+ colour = color,
+ size = globalvar.DIALOG_COLOR_SIZE)
+ value.Bind(csel.EVT_COLOURSELECT, self.OnSurfaceMap)
+ elif code == 'mask':
+ value = None
+ else:
+ value = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
+ initial = 0)
+ value.SetRange(minVal = 0, maxVal = 100)
+ value.Bind(wx.EVT_TEXT, self.OnSurfaceMap)
+
+ if value:
+ self.win['surface'][code]['const'] = value.GetId()
+ value.Enable(False)
+ gridSizer.Add(item = value, flag = wx.ALIGN_CENTER_VERTICAL,
+ pos = (row, 3))
+ else:
+ self.win['surface'][code]['const'] = None
+
+ self.SetMapObjUseMap(nvizType = 'surface',
+ attrb = code) # -> enable map / disable constant
+
+ row += 1
+ boxSizer.Add(item = gridSizer, proportion = 0,
flag = wx.ALL | wx.EXPAND, border = 3)
pageSizer.Add(item = boxSizer, proportion = 0,
- flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
+ flag = wx.EXPAND | wx.ALL,
border = 3)
-
#
# position
#
@@ -578,49 +1010,314 @@
box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
label = " %s " % (_("Position")))
boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
- gridSizer = wx.GridBagSizer(vgap = 5, hgap = 5)
+ gridSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
+ gridSizer.AddGrowableCol(3)
# position
self._createControl(panel, data = self.win['surface'], name = 'position',
- range = (-10000, 10000),
- bind = (self.OnSurfacePosition, self.OnSurfacePosition, self.OnSurfacePosition))
+ range = (-10000, 10000), floatSlider = True,
+ bind = (self.OnSurfacePosition, self.OnSurfacePositionChanged, self.OnSurfacePositionText))
axis = wx.Choice (parent = panel, id = wx.ID_ANY, size = (75, -1),
choices = ["X",
"Y",
"Z"])
+
+ reset = wx.Button(panel, id = wx.ID_ANY, label = _("Reset"))
+ reset.SetToolTipString(_("Reset to default position"))
+ reset.Bind(wx.EVT_BUTTON, self.OnResetSurfacePosition)
+ self.win['surface']['position']['reset'] = reset.GetId()
self.win['surface']['position']['axis'] = axis.GetId()
axis.SetSelection(0)
axis.Bind(wx.EVT_CHOICE, self.OnSurfaceAxis)
pslide = self.FindWindowById(self.win['surface']['position']['slider'])
- pspin = self.FindWindowById(self.win['surface']['position']['spin'])
+ ptext = self.FindWindowById(self.win['surface']['position']['text'])
+ ptext.SetValue('0')
gridSizer.Add(item = axis, flag = wx.ALIGN_CENTER_VERTICAL, pos = (0, 0))
gridSizer.Add(item = pslide, flag = wx.ALIGN_CENTER_VERTICAL, pos = (0, 1))
- gridSizer.Add(item = pspin, flag = wx.ALIGN_CENTER_VERTICAL, pos = (0, 2))
+ gridSizer.Add(item = ptext, flag = wx.ALIGN_CENTER_VERTICAL, pos = (0, 2))
+ gridSizer.Add(item = reset, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT, pos = (0, 3))
boxSizer.Add(item = gridSizer, proportion = 1,
flag = wx.ALL | wx.EXPAND, border = 3)
box.SetSizer(boxSizer)
box.Layout()
- pageSizer.Add(item = boxSizer, proportion = 0,
+ pageSizer.Add(item = boxSizer, proportion = 1,
flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
border = 3)
+ #
+ # mask
+ #
+## box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
+## label = " %s " % (_("Mask")))
+## boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+## gridSizer = wx.GridBagSizer(vgap = 5, hgap = 5)
+##
+## gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
+## label = _("Mask zeros:")),
+## pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL)
+##
+## elev = wx.CheckBox(parent = panel, id = wx.ID_ANY,
+## label = _("by elevation"))
+## elev.Enable(False) # TODO: not implemented yet
+## gridSizer.Add(item = elev, pos = (0, 1))
+##
+## color = wx.CheckBox(parent = panel, id = wx.ID_ANY,
+## label = _("by color"))
+## color.Enable(False) # TODO: not implemented yet
+## gridSizer.Add(item = color, pos = (0, 2))
+##
+## boxSizer.Add(item = gridSizer, proportion = 1,
+## flag = wx.ALL | wx.EXPAND, border = 3)
+## pageSizer.Add(item = boxSizer, proportion = 0,
+## flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
+## border = 3)
+
panel.SetSizer(pageSizer)
+
+ panel.Layout()
+ panel.Fit()
return panel
+ def _createCPlanePage(self, parent):
+ """!Create cutting planes page"""
+ panel = wx.Panel(parent = parent, id = wx.ID_ANY)
+ self.page['cplane'] = { 'id' : 4,
+ 'notebook' : self.foldpanelData.GetId() }
+ self.win['cplane'] = {}
+
+ pageSizer = wx.BoxSizer(wx.VERTICAL)
+ box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
+ label = " %s " % (_("Cutting planes")))
+ boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+ horSizer = wx.BoxSizer(wx.HORIZONTAL)
+
+ # planes
+ horSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
+ label = _("Active cutting plane:")),
+ flag = wx.ALIGN_CENTER_VERTICAL|wx.ALL, border = 5)
+ choice = wx.Choice(parent = panel, id = wx.ID_ANY, choices = [])
+ self.win['cplane']['planes'] = choice.GetId()
+ choice.Bind(wx.EVT_CHOICE, self.OnCPlaneSelection)
+ horSizer.Add(item = choice, flag = wx.ALL, border = 5)
+
+ # shading
+ horSizer.Add(item = wx.Size(-1, -1), proportion = 1)
+ horSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
+ label = _("Shading:")),
+ flag = wx.ALIGN_CENTER_VERTICAL|wx.ALL, border = 5)
+ choices = [_("clear"),
+ _("top color"),
+ _("bottom color"),
+ _("blend"),
+ _("shaded")]
+ choice = wx.Choice(parent = panel, id = wx.ID_ANY, choices = choices)
+ self.win['cplane']['shading'] = choice.GetId()
+ choice.Bind(wx.EVT_CHOICE, self.OnCPlaneShading)
+ horSizer.Add(item = choice, flag = wx.ALL, border = 5)
+ boxSizer.Add(item = horSizer, flag = wx.EXPAND)
+
+ gridSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
+
+ # cutting plane horizontal x position
+ self.win['cplane']['position'] = {}
+ gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
+ label = _("Horizontal X:")),
+ pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL)
+ self._createControl(panel, data = self.win['cplane']['position'], name = 'x', size = 250,
+ range = (-1000, 1000), sliderHor = True, floatSlider = True,
+ bind = (self.OnCPlaneChanging, self.OnCPlaneChangeDone, self.OnCPlaneChangeText))
+ self.FindWindowById(self.win['cplane']['position']['x']['slider']).SetValue(0)
+ self.FindWindowById(self.win['cplane']['position']['x']['text']).SetValue(0)
+ gridSizer.Add(item = self.FindWindowById(self.win['cplane']['position']['x']['slider']),
+ pos = (0, 1), flag = wx.EXPAND|wx.ALIGN_RIGHT)
+ gridSizer.Add(item = self.FindWindowById(self.win['cplane']['position']['x']['text']),
+ pos = (0, 2),
+ flag = wx.ALIGN_CENTER)
+
+ # cutting plane horizontal y position
+ gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
+ label = _("Horizontal Y:")),
+ pos = (1, 0), flag = wx.ALIGN_CENTER_VERTICAL)
+ self._createControl(panel, data = self.win['cplane']['position'], name = 'y', size = 250,
+ range = (-1000, 1000), sliderHor = True, floatSlider = True,
+ bind = (self.OnCPlaneChanging, self.OnCPlaneChangeDone, self.OnCPlaneChangeText))
+ self.FindWindowById(self.win['cplane']['position']['y']['slider']).SetValue(0)
+ self.FindWindowById(self.win['cplane']['position']['y']['text']).SetValue(0)
+ gridSizer.Add(item = self.FindWindowById(self.win['cplane']['position']['y']['slider']),
+ pos = (1, 1), flag = wx.EXPAND|wx.ALIGN_RIGHT)
+ gridSizer.Add(item = self.FindWindowById(self.win['cplane']['position']['y']['text']),
+ pos = (1, 2),
+ flag = wx.ALIGN_CENTER)
+
+ # cutting plane rotation
+ self.win['cplane']['rotation'] = {}
+ gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
+ label = _("Rotation:")),
+ pos = (2, 0), flag = wx.ALIGN_CENTER_VERTICAL)
+ self._createControl(panel, data = self.win['cplane']['rotation'], name = 'rot', size = 250,
+ range = (0, 360), sliderHor = True,
+ bind = (self.OnCPlaneChanging, self.OnCPlaneChangeDone, self.OnCPlaneChangeText))
+ self.FindWindowById(self.win['cplane']['rotation']['rot']['slider']).SetValue(0)
+ self.FindWindowById(self.win['cplane']['rotation']['rot']['text']).SetValue(0)
+ gridSizer.Add(item = self.FindWindowById(self.win['cplane']['rotation']['rot']['slider']),
+ pos = (2, 1), flag = wx.EXPAND|wx.ALIGN_RIGHT)
+ gridSizer.Add(item = self.FindWindowById(self.win['cplane']['rotation']['rot']['text']),
+ pos = (2, 2),
+ flag = wx.ALIGN_CENTER)
- def _createVectorPage(self):
+ # cutting plane tilt
+ gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
+ label = _("Tilt:")),
+ pos = (3, 0), flag = wx.ALIGN_CENTER_VERTICAL)
+ self._createControl(panel, data = self.win['cplane']['rotation'], name = 'tilt', size = 250,
+ range = (0, 360), sliderHor = True,
+ bind = (self.OnCPlaneChanging, self.OnCPlaneChangeDone, self.OnCPlaneChangeText))
+ self.FindWindowById(self.win['cplane']['rotation']['tilt']['slider']).SetValue(0)
+ self.FindWindowById(self.win['cplane']['rotation']['tilt']['text']).SetValue(0)
+ gridSizer.Add(item = self.FindWindowById(self.win['cplane']['rotation']['tilt']['slider']),
+ pos = (3, 1), flag = wx.EXPAND|wx.ALIGN_RIGHT)
+ gridSizer.Add(item = self.FindWindowById(self.win['cplane']['rotation']['tilt']['text']),
+ pos = (3, 2),
+ flag = wx.ALIGN_CENTER)
+
+ # cutting pland height
+ gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
+ label = _("Height:")),
+ pos = (4, 0), flag = wx.ALIGN_CENTER_VERTICAL)
+ self._createControl(panel, data = self.win['cplane']['position'], name = 'z', size = 250,
+ range = (-1000, 1000), sliderHor = True,
+ bind = (self.OnCPlaneChanging, self.OnCPlaneChangeDone, self.OnCPlaneChangeText))
+ self.FindWindowById(self.win['cplane']['position']['z']['slider']).SetValue(0)
+ self.FindWindowById(self.win['cplane']['position']['z']['text']).SetValue(0)
+ gridSizer.Add(item = self.FindWindowById(self.win['cplane']['position']['z']['slider']),
+ pos = (4, 1), flag = wx.EXPAND|wx.ALIGN_RIGHT)
+ gridSizer.Add(item = self.FindWindowById(self.win['cplane']['position']['z']['text']),
+ pos = (4, 2),
+ flag = wx.ALIGN_CENTER)
+
+ boxSizer.Add(gridSizer, proportion = 0, flag = wx.EXPAND|wx.ALL, border = 5)
+
+ horSizer = wx.BoxSizer(wx.HORIZONTAL)
+ horSizer.Add(item = wx.Size(-1, -1), proportion = 1, flag = wx.ALL, border = 5)
+ # reset
+ reset = wx.Button(parent = panel, id = wx.ID_ANY, label = _("Reset"))
+ self.win['cplane']['reset'] = reset.GetId()
+ reset.Bind(wx.EVT_BUTTON, self.OnCPlaneReset)
+ horSizer.Add(item = reset, flag = wx.ALL, border = 5)
+ boxSizer.Add(horSizer, proportion = 0, flag = wx.EXPAND)
+
+
+ pageSizer.Add(boxSizer, proportion = 0, flag = wx.EXPAND)
+
+ panel.SetSizer(pageSizer)
+ panel.Fit()
+
+ return panel
+
+ def _createConstantPage(self, parent):
+ """!Create constant page"""
+ panel = wx.Panel(parent = parent, id = wx.ID_ANY)
+ self.page['constant'] = { 'id' : 1,
+ 'notebook' : self.foldpanelData.GetId() }
+ self.win['constant'] = {}
+
+ pageSizer = wx.BoxSizer(wx.VERTICAL)
+
+ box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
+ label = " %s " % (_("Constant surface")))
+ boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+ horsizer = wx.BoxSizer(wx.HORIZONTAL)
+
+ surface = wx.ComboBox(parent = panel, id = wx.ID_ANY,
+ style = wx.CB_SIMPLE | wx.CB_READONLY,
+ choices = [])
+ self.win['constant']['surface'] = surface.GetId()
+ surface.Bind(wx.EVT_COMBOBOX, self.OnConstantSelection)
+ horsizer.Add(surface, proportion = 1, flag = wx.EXPAND|wx.RIGHT, border = 20)
+
+ addNew = wx.Button(panel, id = wx.ID_ANY, label = _("New"))
+ addNew.Bind(wx.EVT_BUTTON, self.OnNewConstant)
+ self.win['constant']['new'] = addNew.GetId()
+
+ delete = wx.Button(panel, id = wx.ID_ANY, label = _("Delete"))
+ delete.Bind(wx.EVT_BUTTON, self.OnDeleteConstant)
+ self.win['constant']['delete'] = delete.GetId()
+
+ horsizer.Add(item = addNew, proportion = 0, flag = wx.RIGHT|wx.LEFT, border = 3)
+ horsizer.Add(item = delete, proportion = 0, flag = wx.RIGHT|wx.LEFT, border = 3)
+
+ boxSizer.Add(item = horsizer, proportion = 0, flag = wx.ALL|wx.EXPAND,
+ border = 5)
+
+ gridSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
+ # fine resolution
+ gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
+ label = _("Fine resolution:")),
+ pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL)
+ resF = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
+ initial = 3,
+ min = 1,
+ max = 100)
+ resF.SetName("value")
+ self.win['constant']['resolution'] = resF.GetId()
+ resF.Bind(wx.EVT_SPINCTRL, self.OnSetConstantProp)
+ gridSizer.Add(item = resF, pos = (0, 1), flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT)
+ # value
+ gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
+ label = _("Value:")), pos = (1, 0),
+ flag = wx.ALIGN_CENTER_VERTICAL)
+
+ value = wx.SpinCtrl(panel, id = wx.ID_ANY,
+ min = -1e9, max = 1e9,
+ size = (65, -1))
+ self.win['constant']['value'] = value.GetId()
+ value.Bind(wx.EVT_SPINCTRL, self.OnSetConstantProp)
+ gridSizer.Add(item = value, pos = (1, 1))
+
+ # transparency
+ gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
+ label = _("Transparency:")), pos = (2, 0),
+ flag = wx.ALIGN_CENTER_VERTICAL)
+
+ transp = wx.SpinCtrl(panel, id = wx.ID_ANY,
+ min = 0, max = 100,
+ size = (65, -1))
+ self.win['constant']['transp'] = transp.GetId()
+ transp.Bind(wx.EVT_SPINCTRL, self.OnSetConstantProp)
+ gridSizer.Add(item = transp, pos = (2, 1))
+
+ # color
+ gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
+ label = _("Color:")), pos = (3, 0),
+ flag = wx.ALIGN_CENTER_VERTICAL)
+ color = csel.ColourSelect(panel, id = wx.ID_ANY,
+ colour = (0,0,0),
+ size = globalvar.DIALOG_COLOR_SIZE)
+ self.win['constant']['color'] = color.GetId()
+ color.Bind(csel.EVT_COLOURSELECT, self.OnSetConstantProp)
+ gridSizer.Add(item = color, pos = (3, 1))
+ boxSizer.Add(item = gridSizer, proportion = 0, flag = wx.ALL,
+ border = 5)
+ pageSizer.Add(item = boxSizer, proportion = 0,
+ flag = wx.EXPAND | wx.ALL,
+ border = 3)
+
+ panel.SetSizer(pageSizer)
+ panel.Fit()
+
+ return panel
+
+ def _createVectorPage(self, parent):
"""!Create view settings page"""
- panel = SP.ScrolledPanel(parent = self, id = wx.ID_ANY)
- panel.SetupScrolling(scroll_x = False)
- self.page['vector'] = { 'id' : 1,
- 'panel' : panel.GetId(),
- 'notebook' : self.notebookData.GetId() }
+ panel = wx.Panel(parent = parent, id = wx.ID_ANY)
+ self.page['vector'] = { 'id' : 2,
+ 'notebook' : self.foldpanelData.GetId() }
pageSizer = wx.BoxSizer(wx.VERTICAL)
self.win['vector'] = {}
@@ -664,13 +1361,14 @@
label = " %s " % (_("Vector lines")))
boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
gridSizer = wx.GridBagSizer(vgap = 5, hgap = 5)
+ gridSizer.AddGrowableCol(5)
# width
gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
label = _("Line:")),
pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL)
gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = _("width")),
+ label = _("width:")),
pos = (0, 1), flag = wx.ALIGN_CENTER_VERTICAL |
wx.ALIGN_RIGHT)
@@ -686,7 +1384,7 @@
# color
gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = _("color")),
+ label = _("color:")),
pos = (0, 3), flag = wx.ALIGN_CENTER_VERTICAL |
wx.ALIGN_RIGHT)
@@ -701,43 +1399,42 @@
# display
gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = _("display")),
- pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL |
- wx.ALIGN_RIGHT)
+ label = _("Display")),
+ pos = (1, 0), flag = wx.ALIGN_CENTER_VERTICAL |
+ wx.ALIGN_LEFT)
- display = wx.Choice (parent = panel, id = wx.ID_ANY, size = (100, -1),
- choices = [_("on surface"),
+ display = wx.Choice (parent = panel, id = wx.ID_ANY, size = (-1, -1),
+ choices = [_("on surface(s):"),
_("flat")])
self.win['vector']['lines']['flat'] = display.GetId()
display.Bind(wx.EVT_CHOICE, self.OnVectorDisplay)
gridSizer.Add(item = display, flag = wx.ALIGN_CENTER_VERTICAL |
- wx.ALIGN_LEFT, pos = (1, 2), span = (1,2))
+ wx.ALIGN_LEFT|wx.EXPAND, pos = (1, 1), span = (1,4))
# height
gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
label = _("Height above surface:")),
- pos = (2, 0), flag = wx.ALIGN_CENTER_VERTICAL,
- span = (1, 3))
+ pos = (2, 5), flag = wx.ALIGN_BOTTOM|wx.EXPAND)
- surface = wx.ComboBox(parent = panel, id = wx.ID_ANY, size = (250, -1),
- style = wx.CB_SIMPLE | wx.CB_READONLY,
- choices = [])
- surface.Bind(wx.EVT_COMBOBOX, self.OnVectorSurface)
+ surface = wx.CheckListBox(parent = panel, id = wx.ID_ANY, size = (-1, 60),
+ choices = [], style = wx.LB_NEEDED_SB)
+ surface.Bind(wx.EVT_CHECKLISTBOX, self.OnVectorSurface)
+
self.win['vector']['lines']['surface'] = surface.GetId()
gridSizer.Add(item = surface,
- pos = (2, 3), span = (1, 6),
- flag = wx.ALIGN_CENTER_VERTICAL)
+ pos = (2, 0), span = (3, 5),
+ flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
- self._createControl(panel, data = self.win['vector']['lines'], name = 'height', size = 300,
- range = (0, 1000),
- bind = (self.OnVectorHeight, self.OnVectorHeightFull, self.OnVectorHeightSpin))
+ self._createControl(panel, data = self.win['vector']['lines'], name = 'height', size = -1,
+ range = (0, 500), sliderHor = True,
+ bind = (self.OnVectorHeight, self.OnVectorHeightFull, self.OnVectorHeightText))
self.FindWindowById(self.win['vector']['lines']['height']['slider']).SetValue(0)
- self.FindWindowById(self.win['vector']['lines']['height']['spin']).SetValue(0)
+ self.FindWindowById(self.win['vector']['lines']['height']['text']).SetValue(0)
gridSizer.Add(item = self.FindWindowById(self.win['vector']['lines']['height']['slider']),
- pos = (3, 0), span = (1, 7))
- gridSizer.Add(item = self.FindWindowById(self.win['vector']['lines']['height']['spin']),
- pos = (3, 7),
+ pos = (3, 5), flag = wx.EXPAND|wx.ALIGN_RIGHT)
+ gridSizer.Add(item = self.FindWindowById(self.win['vector']['lines']['height']['text']),
+ pos = (4, 5),
flag = wx.ALIGN_CENTER)
boxSizer.Add(item = gridSizer, proportion = 1,
@@ -763,14 +1460,19 @@
box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
label = " %s " % (_("Vector points")))
boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+ vertSizer = wx.BoxSizer(wx.VERTICAL)
gridSizer = wx.GridBagSizer(vgap = 5, hgap = 5)
+ gridSizer.AddGrowableCol(0)
+ gridSizer.AddGrowableCol(2)
+ gridSizer.AddGrowableCol(4)
+ gridSizer.AddGrowableCol(6)
# icon size
gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
label = _("Icon:")),
pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL)
gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = _("size")),
+ label = _("size:")),
pos = (0, 1), flag = wx.ALIGN_CENTER_VERTICAL |
wx.ALIGN_RIGHT)
@@ -788,7 +1490,7 @@
# icon color
gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = _("color")),
+ label = _("color:")),
pos = (0, 3), flag = wx.ALIGN_CENTER_VERTICAL |
wx.ALIGN_RIGHT)
icolor = csel.ColourSelect(panel, id = wx.ID_ANY,
@@ -801,89 +1503,92 @@
wx.ALIGN_LEFT,
pos = (0, 4))
- # icon width
- gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = _("width")),
- pos = (0, 5), flag = wx.ALIGN_CENTER_VERTICAL |
- wx.ALIGN_RIGHT)
-
- iwidth = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
- initial = 1,
- min = 1,
- max = 1e6)
- iwidth.SetName('value')
- iwidth.SetValue(100)
- self.win['vector']['points']['width'] = iwidth.GetId()
- iwidth.Bind(wx.EVT_SPINCTRL, self.OnVectorPoints)
- iwidth.Bind(wx.EVT_TEXT, self.OnVectorPoints)
- gridSizer.Add(item = iwidth, pos = (0, 6),
- flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT)
-
+ # icon width - seems to do nothing
+## gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
+## label = _("width")),
+## pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL |
+## wx.ALIGN_RIGHT)
+##
+## iwidth = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
+## initial = 1,
+## min = 1,
+## max = 1e6)
+## iwidth.SetName('value')
+## iwidth.SetValue(100)
+## self.win['vector']['points']['width'] = iwidth.GetId()
+## iwidth.Bind(wx.EVT_SPINCTRL, self.OnVectorPoints)
+## iwidth.Bind(wx.EVT_TEXT, self.OnVectorPoints)
+## gridSizer.Add(item = iwidth, pos = (1, 2),
+## flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT)
# icon symbol
gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = _("symbol")),
- pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL)
+ label = _("symbol:")),
+ pos = (0, 5), flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
isym = wx.Choice (parent = panel, id = wx.ID_ANY, size = (100, -1),
choices = UserSettings.Get(group = 'nviz', key = 'vector',
subkey = ['points', 'marker'], internal = True))
isym.SetName("selection")
self.win['vector']['points']['marker'] = isym.GetId()
isym.Bind(wx.EVT_CHOICE, self.OnVectorPoints)
- gridSizer.Add(item = isym, flag = wx.ALIGN_CENTER_VERTICAL,
- pos = (1, 2), span = (1,2))
+ gridSizer.Add(item = isym, flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT,
+ pos = (0, 6))
+ vertSizer.Add(gridSizer, proportion = 0, flag = wx.EXPAND, border = 0)
# high
+ gridSizer = wx.GridBagSizer(vgap = 5, hgap = 5)
+ gridSizer.AddGrowableCol(1)
gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
+ label = _("Display on surface(s):")),
+ pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL)
+ gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
label = _("Height above surface:")),
- pos = (2, 0), flag = wx.ALIGN_CENTER_VERTICAL,
- span = (1, 3))
+ pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL)
- surface = wx.ComboBox(parent = panel, id = wx.ID_ANY, size = (250, -1),
- style = wx.CB_SIMPLE | wx.CB_READONLY,
- choices = [])
- surface.Bind(wx.EVT_COMBOBOX, self.OnVectorSurface)
+ surface = wx.CheckListBox(parent = panel, id = wx.ID_ANY, size = (-1, 60),
+ choices = [], style = wx.LB_NEEDED_SB)
+ surface.Bind(wx.EVT_CHECKLISTBOX, self.OnVectorSurface)
self.win['vector']['points']['surface'] = surface.GetId()
gridSizer.Add(item = surface,
- pos = (2, 3), span = (1, 5),
- flag = wx.ALIGN_CENTER_VERTICAL)
+ pos = (1, 0), span = (3, 1),
+ flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
- self._createControl(panel, data = self.win['vector']['points'], name = 'height', size = 300,
- range = (0, 1000),
- bind = (self.OnVectorHeight, self.OnVectorHeightFull, self.OnVectorHeightSpin))
+ self._createControl(panel, data = self.win['vector']['points'], name = 'height', size = -1,
+ range = (0, 500),
+ bind = (self.OnVectorHeight, self.OnVectorHeightFull, self.OnVectorHeightText))
self.FindWindowById(self.win['vector']['points']['height']['slider']).SetValue(0)
- self.FindWindowById(self.win['vector']['points']['height']['spin']).SetValue(0)
+ self.FindWindowById(self.win['vector']['points']['height']['text']).SetValue(0)
gridSizer.Add(item = self.FindWindowById(self.win['vector']['points']['height']['slider']),
- pos = (3, 0), span = (1, 7))
- gridSizer.Add(item = self.FindWindowById(self.win['vector']['points']['height']['spin']),
- pos = (3, 7),
+ pos = (2, 1),flag = wx.EXPAND|wx.ALIGN_CENTER_VERTICAL)
+ gridSizer.Add(item = self.FindWindowById(self.win['vector']['points']['height']['text']),
+ pos = (3, 1),
flag = wx.ALIGN_CENTER)
-
- boxSizer.Add(item = gridSizer, proportion = 1,
+
+ vertSizer.Add(gridSizer, proportion = 0, flag = wx.EXPAND, border = 0)
+ boxSizer.Add(item = vertSizer, proportion = 1,
flag = wx.ALL | wx.EXPAND, border = 3)
pageSizer.Add(item = boxSizer, proportion = 0,
flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
border = 3)
panel.SetSizer(pageSizer)
+ panel.Fit()
return panel
def GselectOnPopup(self, ltype, exclude = False):
"""Update gselect.Select() items"""
maps = list()
- for layer in self.mapWindow.Map.GetListOfLayers(l_type = ltype):
+ for layer in self.mapWindow.Map.GetListOfLayers(l_type = ltype, l_active = True):
maps.append(layer.GetName())
return maps, exclude
- def _createVolumePage(self):
+ def _createVolumePage(self, parent):
"""!Create view settings page"""
- panel = SP.ScrolledPanel(parent = self, id = wx.ID_ANY)
- panel.SetupScrolling(scroll_x = False)
- self.page['volume'] = { 'id' : 2,
- 'panel' : panel.GetId(),
- 'notebook' : self.notebookData.GetId() }
+ panel = wx.Panel(parent = parent, id = wx.ID_ANY)
+ self.page['volume'] = { 'id' : 3,
+ 'notebook' : self.foldpanelData.GetId() }
pageSizer = wx.BoxSizer(wx.VERTICAL)
self.win['volume'] = {}
@@ -892,7 +1597,7 @@
box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
label = " %s " % (_("3D raster map")))
boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
- rmaps = gselect.Select(parent = panel, type = 'raster3D',
+ rmaps = gselect.Select(parent = panel, type = '3d-raster',
onPopup = self.GselectOnPopup)
rmaps.GetChildren()[0].Bind(wx.EVT_TEXT, self.OnSetRaster3D)
self.win['volume']['map'] = rmaps.GetId()
@@ -916,18 +1621,18 @@
label = " %s " % (_("Draw")))
boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
gridSizer = wx.GridBagSizer(vgap = 5, hgap = 5)
- gridSizer.AddGrowableCol(4)
+## gridSizer.AddGrowableCol(4)
# mode
gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
label = _("Mode:")),
pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL)
- mode = wx.Choice (parent = panel, id = wx.ID_ANY, size = (150, -1),
+ mode = wx.Choice (parent = panel, id = wx.ID_ANY, size = (-1, -1),
choices = [_("isosurfaces"),
- _("slides")])
+ _("slices")])
mode.SetSelection(0)
mode.SetName("selection")
- # mode.Bind(wx.EVT_CHOICE, self.OnSurfaceMode)
+ mode.Bind(wx.EVT_CHOICE, self.OnVolumeMode)
self.win['volume']['draw']['mode'] = mode.GetId()
gridSizer.Add(item = mode, flag = wx.ALIGN_CENTER_VERTICAL,
pos = (0, 1))
@@ -941,7 +1646,7 @@
_("gouraud")])
shade.SetName("selection")
self.win['volume']['draw']['shading'] = shade.GetId()
- shade.Bind(wx.EVT_CHOICE, self.OnVolumeIsosurfMode)
+ shade.Bind(wx.EVT_CHOICE, self.OnVolumeDrawMode)
gridSizer.Add(item = shade, flag = wx.ALIGN_CENTER_VERTICAL,
pos = (0, 3))
@@ -955,11 +1660,11 @@
max = 100)
resol.SetName("value")
self.win['volume']['draw']['resolution'] = resol.GetId()
- resol.Bind(wx.EVT_SPINCTRL, self.OnVolumeIsosurfResolution)
- resol.Bind(wx.EVT_TEXT, self.OnVolumeIsosurfResolution)
+ resol.Bind(wx.EVT_SPINCTRL, self.OnVolumeResolution)
+ resol.Bind(wx.EVT_TEXT, self.OnVolumeResolution)
gridSizer.Add(item = resol, pos = (0, 5))
- boxSizer.Add(item = gridSizer, proportion = 1,
+ boxSizer.Add(item = gridSizer, proportion = 0,
flag = wx.ALL | wx.EXPAND, border = 3)
pageSizer.Add(item = boxSizer, proportion = 0,
flag = wx.EXPAND | wx.ALL,
@@ -968,41 +1673,43 @@
#
# manage isosurfaces
#
- box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
- label = " %s " % (_("List of isosurfaces")))
+ box = wx.StaticBox(parent = panel, id = wx.ID_ANY,
+ label = " %s " % (_("List of isosurfaces")))
+ box.SetName('listStaticBox')
boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
gridSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
# list
isolevel = wx.CheckListBox(parent = panel, id = wx.ID_ANY,
size = (300, 150))
- self.Bind(wx.EVT_CHECKLISTBOX, self.OnVolumeIsosurfCheck, isolevel)
- self.Bind(wx.EVT_LISTBOX, self.OnVolumeIsosurfSelect, isolevel)
+ self.Bind(wx.EVT_CHECKLISTBOX, self.OnVolumeCheck, isolevel)
+ self.Bind(wx.EVT_LISTBOX, self.OnVolumeSelect, isolevel)
self.win['volume']['isosurfs'] = isolevel.GetId()
+ self.win['volume']['slices'] = isolevel.GetId()
gridSizer.Add(item = isolevel, pos = (0, 0), span = (4, 1))
# buttons (add, delete, move up, move down)
btnAdd = wx.Button(parent = panel, id = wx.ID_ADD)
- self.win['volume']['btnIsosurfAdd'] = btnAdd.GetId()
- btnAdd.Bind(wx.EVT_BUTTON, self.OnVolumeIsosurfAdd)
+ self.win['volume']['btnAdd'] = btnAdd.GetId()
+ btnAdd.Bind(wx.EVT_BUTTON, self.OnVolumeAdd)
gridSizer.Add(item = btnAdd,
pos = (0, 1))
btnDelete = wx.Button(parent = panel, id = wx.ID_DELETE)
- self.win['volume']['btnIsosurfDelete'] = btnDelete.GetId()
- btnDelete.Bind(wx.EVT_BUTTON, self.OnVolumeIsosurfDelete)
+ self.win['volume']['btnDelete'] = btnDelete.GetId()
+ btnDelete.Bind(wx.EVT_BUTTON, self.OnVolumeDelete)
btnDelete.Enable(False)
gridSizer.Add(item = btnDelete,
pos = (1, 1))
btnMoveUp = wx.Button(parent = panel, id = wx.ID_UP)
- self.win['volume']['btnIsosurfMoveUp'] = btnMoveUp.GetId()
- btnMoveUp.Bind(wx.EVT_BUTTON, self.OnVolumeIsosurfMoveUp)
+ self.win['volume']['btnMoveUp'] = btnMoveUp.GetId()
+ btnMoveUp.Bind(wx.EVT_BUTTON, self.OnVolumeMoveUp)
btnMoveUp.Enable(False)
gridSizer.Add(item = btnMoveUp,
pos = (2, 1))
btnMoveDown = wx.Button(parent = panel, id = wx.ID_DOWN)
- self.win['volume']['btnIsosurfMoveDown'] = btnMoveDown.GetId()
- btnMoveDown.Bind(wx.EVT_BUTTON, self.OnVolumeIsosurfMoveDown)
+ self.win['volume']['btnMoveDown'] = btnMoveDown.GetId()
+ btnMoveDown.Bind(wx.EVT_BUTTON, self.OnVolumeMoveDown)
btnMoveDown.Enable(False)
gridSizer.Add(item = btnMoveDown,
pos = (3, 1))
@@ -1012,117 +1719,72 @@
pageSizer.Add(item = boxSizer, proportion = 0,
flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
border = 3)
-
+ # isosurface/slice
+ sizer = wx.BoxSizer()
+ self.isoPanel = self._createIsosurfacePanel(panel)
+ self.slicePanel = self._createSlicePanel(panel)
+ sizer.Add(self.isoPanel, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 0)
+ sizer.Add(self.slicePanel, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 0)
+ sizer.Hide(self.slicePanel)
+ pageSizer.Add(item = sizer, proportion = 0,
+ flag = wx.EXPAND | wx.ALL,
+ border = 3)
#
- # isosurface attributes
+ # position
#
+ self.win['volume']['position'] = {}
box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
- label = " %s " % (_("Isosurface attributes")))
+ label = " %s " % (_("Position")))
boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
gridSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
+ gridSizer.AddGrowableCol(3)
- self.win['volume']['attr'] = {}
- row = 0
- for code, attrb in (('topo', _("Topography level")),
- ('color', _("Color")),
- ('mask', _("Mask")),
- ('transp', _("Transparency")),
- ('shine', _("Shininess")),
- ('emit', _("Emission"))):
- self.win['volume'][code] = {}
- # label
- gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = attrb + ':'),
- pos = (row, 0), flag = wx.ALIGN_CENTER_VERTICAL)
- if code != 'topo':
- use = wx.Choice (parent = panel, id = wx.ID_ANY, size = (100, -1),
- choices = [_("map")])
- else:
- use = None
- # check for required properties
- if code not in ('topo', 'color', 'shine'):
- use.Insert(item = _("unset"), pos = 0)
- self.win['volume'][code]['required'] = False
- else:
- self.win['volume'][code]['required'] = True
- if use and code != 'mask':
- use.Append(item = _('constant'))
- if use:
- self.win['volume'][code]['use'] = use.GetId()
- use.Bind(wx.EVT_CHOICE, self.OnMapObjUse)
- gridSizer.Add(item = use, flag = wx.ALIGN_CENTER_VERTICAL,
- pos = (row, 1))
-
- if code != 'topo':
- map = gselect.Select(parent = panel, id = wx.ID_ANY,
- # size = globalvar.DIALOG_GSELECT_SIZE,
- size = (200, -1),
- type = "grid3")
- self.win['volume'][code]['map'] = map.GetId() - 1 # FIXME
- map.Bind(wx.EVT_TEXT, self.OnVolumeIsosurfMap)
- gridSizer.Add(item = map, flag = wx.ALIGN_CENTER_VERTICAL,
- pos = (row, 2))
- else:
- map = None
-
- if code == 'color':
- value = csel.ColourSelect(panel, id = wx.ID_ANY,
- colour = (0,0,0),
- size = globalvar.DIALOG_COLOR_SIZE)
- value.Bind(csel.EVT_COLOURSELECT, self.OnVolumeIsosurfMap)
- elif code == 'mask':
- value = None
- else:
- if code == 'topo':
- size = (200, -1)
- else:
- size = (65, -1)
- value = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = size,
- initial = 0)
- if code == 'topo':
- value.SetRange(minVal = -1e9, maxVal = 1e9)
- elif code in ('shine', 'transp', 'emit'):
- value.SetRange(minVal = 0, maxVal = 255)
- else:
- value.SetRange(minVal = 0, maxVal = 100)
- value.Bind(wx.EVT_SPINCTRL, self.OnVolumeIsosurfMap)
- value.Bind(wx.EVT_TEXT, self.OnVolumeIsosurfMap)
-
- if value:
- self.win['volume'][code]['const'] = value.GetId()
- if code == 'topo':
- gridSizer.Add(item = value, flag = wx.ALIGN_CENTER_VERTICAL,
- pos = (row, 2))
- else:
- value.Enable(False)
- gridSizer.Add(item = value, flag = wx.ALIGN_CENTER_VERTICAL,
- pos = (row, 3))
- else:
- self.win['volume'][code]['const'] = None
-
- if code != 'topo':
- self.SetMapObjUseMap(nvizType = 'volume',
- attrb = code) # -> enable map / disable constant
-
- row += 1
+ # position
+ self._createControl(panel, data = self.win['volume'], name = 'position',
+ range = (-10000, 10000), floatSlider = True,
+ bind = (self.OnVolumePosition, self.OnVolumePositionChanged, self.OnVolumePositionText))
+ axis = wx.Choice (parent = panel, id = wx.ID_ANY, size = (75, -1),
+ choices = ["X",
+ "Y",
+ "Z"])
+
+ reset = wx.Button(panel, id = wx.ID_ANY, label = _("Reset"))
+ reset.SetToolTipString(_("Reset to default position"))
+ reset.Bind(wx.EVT_BUTTON, self.OnResetVolumePosition)
+ self.win['volume']['position']['reset'] = reset.GetId()
+
+ self.win['volume']['position']['axis'] = axis.GetId()
+ axis.SetSelection(0)
+ axis.Bind(wx.EVT_CHOICE, self.OnVolumeAxis)
+
+ pslide = self.FindWindowById(self.win['volume']['position']['slider'])
+ ptext = self.FindWindowById(self.win['volume']['position']['text'])
+ ptext.SetValue('0')
+
+ gridSizer.Add(item = axis, flag = wx.ALIGN_CENTER_VERTICAL, pos = (0, 0))
+ gridSizer.Add(item = pslide, flag = wx.ALIGN_CENTER_VERTICAL, pos = (0, 1))
+ gridSizer.Add(item = ptext, flag = wx.ALIGN_CENTER_VERTICAL, pos = (0, 2))
+ gridSizer.Add(item = reset, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT, pos = (0, 3))
+
boxSizer.Add(item = gridSizer, proportion = 1,
- flag = wx.ALL | wx.EXPAND, border = 3)
+ flag = wx.ALL | wx.EXPAND, border = 3)
+
pageSizer.Add(item = boxSizer, proportion = 0,
flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
border = 3)
-
panel.SetSizer(pageSizer)
+ panel.Fit()
return panel
-
- def _createLightPage(self):
+
+
+ def _createLightPage(self, parent):
"""!Create light page"""
- panel = SP.ScrolledPanel(parent = self, id = wx.ID_ANY)
- panel.SetupScrolling(scroll_x = False)
+ panel = wx.Panel(parent = parent, id = wx.ID_ANY)
self.page['light'] = { 'id' : 0,
- 'notebook' : self.notebookAppearance.GetId() }
+ 'notebook' : self.foldpanelAppear.GetId() }
self.win['light'] = {}
pageSizer = wx.BoxSizer(wx.VERTICAL)
@@ -1130,12 +1792,14 @@
show = wx.CheckBox(parent = panel, id = wx.ID_ANY,
label = _("Show light model"))
show.Bind(wx.EVT_CHECKBOX, self.OnShowLightModel)
+ show.SetValue(True)
+ self._display.showLight = True
pageSizer.Add(item = show, proportion = 0,
flag = wx.ALL, border = 3)
- surface = wx.CheckBox(parent = panel, id = wx.ID_ANY,
- label = _("Follow source viewpoint"))
- pageSizer.Add(item = surface, proportion = 0,
- flag = wx.ALL, border = 3)
+## surface = wx.CheckBox(parent = panel, id = wx.ID_ANY,
+## label = _("Follow source viewpoint"))
+## pageSizer.Add(item = surface, proportion = 0,
+## flag = wx.ALL, border = 3)
# position
box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
@@ -1144,36 +1808,31 @@
gridSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
posSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
- posSizer.Add(item = wx.StaticText(panel, id = wx.ID_ANY, label = _("W")),
- pos = (1, 0), flag = wx.ALIGN_CENTER)
- posSizer.Add(item = wx.StaticText(panel, id = wx.ID_ANY, label = _("N")),
- pos = (0, 1), flag = wx.ALIGN_CENTER | wx.ALIGN_BOTTOM)
+
+ self._createCompass(panel = panel, sizer = posSizer, type = 'light')
+
pos = LightPositionWindow(panel, id = wx.ID_ANY, size = (175, 175),
mapwindow = self.mapWindow)
self.win['light']['position'] = pos.GetId()
posSizer.Add(item = pos,
pos = (1, 1), flag = wx.ALIGN_CENTER | wx.ALIGN_CENTER_VERTICAL)
- posSizer.Add(item = wx.StaticText(panel, id = wx.ID_ANY, label = _("S")),
- pos = (2, 1), flag = wx.ALIGN_CENTER | wx.ALIGN_TOP)
- posSizer.Add(item = wx.StaticText(panel, id = wx.ID_ANY, label = _("E")),
- pos = (1, 2), flag = wx.ALIGN_CENTER)
gridSizer.Add(item = posSizer, pos = (0, 0))
# height
self._createControl(panel, data = self.win['light'], name = 'z', sliderHor = False,
range = (0, 100),
- bind = (self.OnLightChange, None, self.OnLightChange))
+ bind = (self.OnLightChange, self.OnLightChanged, self.OnLightChange))
heightSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
heightSizer.Add(item = wx.StaticText(panel, id = wx.ID_ANY, label = _("Height:")),
pos = (0, 0), flag = wx.ALIGN_LEFT, span = (1, 2))
heightSizer.Add(item = self.FindWindowById(self.win['light']['z']['slider']),
flag = wx.ALIGN_RIGHT, pos = (1, 0))
- heightSizer.Add(item = self.FindWindowById(self.win['light']['z']['spin']),
+ heightSizer.Add(item = self.FindWindowById(self.win['light']['z']['text']),
flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.TOP |
wx.BOTTOM | wx.RIGHT, pos = (1, 1))
- gridSizer.Add(item = heightSizer, pos = (0, 1), flag = wx.ALIGN_RIGHT)
+ gridSizer.Add(item = heightSizer, pos = (0, 2), flag = wx.ALIGN_RIGHT)
boxSizer.Add(item = gridSizer, proportion = 1,
flag = wx.ALL | wx.EXPAND, border = 2)
@@ -1201,20 +1860,20 @@
pos = (1, 0), flag = wx.ALIGN_CENTER_VERTICAL)
self._createControl(panel, data = self.win['light'], name = 'bright', size = 300,
range = (0, 100),
- bind = (self.OnLightValue, None, self.OnLightValue))
+ bind = (self.OnLightValue, self.OnLightChanged, self.OnLightValue))
gridSizer.Add(item = self.FindWindowById(self.win['light']['bright']['slider']),
pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL)
- gridSizer.Add(item = self.FindWindowById(self.win['light']['bright']['spin']),
+ gridSizer.Add(item = self.FindWindowById(self.win['light']['bright']['text']),
pos = (1, 2),
flag = wx.ALIGN_CENTER)
gridSizer.Add(item = wx.StaticText(panel, id = wx.ID_ANY, label = _("Ambient:")),
pos = (2, 0), flag = wx.ALIGN_CENTER_VERTICAL)
self._createControl(panel, data = self.win['light'], name = 'ambient', size = 300,
range = (0, 100),
- bind = (self.OnLightValue, None, self.OnLightValue))
+ bind = (self.OnLightValue, self.OnLightChanged, self.OnLightValue))
gridSizer.Add(item = self.FindWindowById(self.win['light']['ambient']['slider']),
pos = (2, 1), flag = wx.ALIGN_CENTER_VERTICAL)
- gridSizer.Add(item = self.FindWindowById(self.win['light']['ambient']['spin']),
+ gridSizer.Add(item = self.FindWindowById(self.win['light']['ambient']['text']),
pos = (2, 2),
flag = wx.ALIGN_CENTER)
@@ -1238,16 +1897,17 @@
# flag = wx.EXPAND)
panel.SetSizer(pageSizer)
+ panel.Layout()
+ panel.Fit()
return panel
- def _createFringePage(self):
+ def _createFringePage(self, parent):
"""!Create fringe page"""
- panel = SP.ScrolledPanel(parent = self, id = wx.ID_ANY)
- panel.SetupScrolling(scroll_x = False)
+ panel = wx.Panel(parent = parent, id = wx.ID_ANY)
self.page['fringe'] = { 'id' : 1,
- 'notebook' : self.notebookAppearance.GetId() }
+ 'notebook' : self.foldpanelAppear.GetId() }
self.win['fringe'] = {}
pageSizer = wx.BoxSizer(wx.VERTICAL)
@@ -1323,12 +1983,114 @@
border = 3)
panel.SetSizer(pageSizer)
+ panel.Layout()
+ panel.Fit()
return panel
+
+ def _createDecorationPage(self, parent):
+ """!Create decoration (north arrow, scalebar, legend) page"""
+ panel = wx.Panel(parent = parent, id = wx.ID_ANY)
+
+ self.page['decoration'] = { 'id' : 2,
+ 'notebook' : self.foldpanelAppear.GetId()}
+ self.win['decoration'] = {}
- def GetLayerData(self, nvizType):
+ pageSizer = wx.BoxSizer(wx.VERTICAL)
+
+ # north arrow
+ self.win['decoration']['arrow'] = {}
+ nabox = wx.StaticBox (parent = panel, id = wx.ID_ANY,
+ label = " %s " % (_("North Arrow")))
+ naboxSizer = wx.StaticBoxSizer(nabox, wx.VERTICAL)
+ gridSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
+ # size
+ gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
+ label = _("Arrow length (in map units):")),
+ pos = (0,0), span = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL)
+ sizeCtrl = NumTextCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1), style = wx.TE_PROCESS_ENTER)
+ gridSizer.Add(sizeCtrl, pos = (0, 2))
+ self.win['decoration']['arrow']['size'] = sizeCtrl.GetId()
+ sizeCtrl.Bind(wx.EVT_TEXT_ENTER, self.OnDecorationProp)
+ sizeCtrl.Bind(wx.EVT_KILL_FOCUS, self.OnDecorationProp)
+
+ # color
+ gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
+ label = _("Arrow color:")),
+ pos = (1,0), span = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL)
+ color = csel.ColourSelect(parent = panel, id = wx.ID_ANY,
+ size = globalvar.DIALOG_COLOR_SIZE)
+ gridSizer.Add(color, pos = (1, 2))
+ self.win['decoration']['arrow']['color'] = color.GetId()
+ color.Bind(csel.EVT_COLOURSELECT, self.OnDecorationProp)
+
+ # control
+ toggle = wx.ToggleButton(parent = panel, id = wx.ID_ANY, label = _("Place arrow"))
+ gridSizer.Add(item = toggle, pos = (2, 0))
+ toggle.Bind(wx.EVT_TOGGLEBUTTON, self.OnDecorationPlacement)
+ self.win['decoration']['arrow']['place'] = toggle.GetId()
+ toggle.SetName('placeArrow')
+
+ delete = wx.Button(parent = panel, id = wx.ID_ANY, label = _("Delete"))
+ gridSizer.Add(item = delete, pos = (2, 1))
+ delete.Bind(wx.EVT_BUTTON, self.OnArrowDelete)
+ naboxSizer.Add(item = gridSizer, proportion = 0, flag = wx.EXPAND, border = 3)
+ pageSizer.Add(item = naboxSizer, proportion = 0,
+ flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
+ border = 3)
+
+
+ # north arrow
+ self.win['decoration']['scalebar'] = {}
+ nabox = wx.StaticBox (parent = panel, id = wx.ID_ANY,
+ label = " %s " % (_("Scale bar")))
+ naboxSizer = wx.StaticBoxSizer(nabox, wx.VERTICAL)
+ gridSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
+ # size
+ gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
+ label = _("Scale bar length (in map units):")),
+ pos = (0,0), span = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL)
+ sizeCtrl = NumTextCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1), style = wx.TE_PROCESS_ENTER)
+ gridSizer.Add(sizeCtrl, pos = (0, 2))
+ self.win['decoration']['scalebar']['size'] = sizeCtrl.GetId()
+ sizeCtrl.Bind(wx.EVT_TEXT_ENTER, self.OnDecorationProp)
+ sizeCtrl.Bind(wx.EVT_KILL_FOCUS, self.OnDecorationProp)
+
+ # color
+ gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
+ label = _("Scale bar color:")),
+ pos = (1,0), span = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL)
+ color = csel.ColourSelect(parent = panel, id = wx.ID_ANY,
+ size = globalvar.DIALOG_COLOR_SIZE)
+ gridSizer.Add(color, pos = (1, 2))
+ self.win['decoration']['scalebar']['color'] = color.GetId()
+ color.Bind(csel.EVT_COLOURSELECT, self.OnDecorationProp)
+
+ # control
+ toggle = wx.ToggleButton(parent = panel, id = wx.ID_ANY, label = _("Place scalebar"))
+ gridSizer.Add(item = toggle, pos = (2, 0))
+ toggle.Bind(wx.EVT_TOGGLEBUTTON, self.OnDecorationPlacement)
+ self.win['decoration']['scalebar']['place'] = toggle.GetId()
+ toggle.SetName('placeScalebar')
+
+ delete = wx.Button(parent = panel, id = wx.ID_ANY, label = _("Delete last"))
+ gridSizer.Add(item = delete, pos = (2, 1))
+ delete.Bind(wx.EVT_BUTTON, self.OnScalebarDelete)
+ naboxSizer.Add(item = gridSizer, proportion = 0, flag = wx.EXPAND, border = 3)
+ pageSizer.Add(item = naboxSizer, proportion = 0,
+ flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
+ border = 3)
+ panel.SetSizer(pageSizer)
+ panel.Layout()
+ panel.Fit()
+
+ return panel
+
+ def GetLayerData(self, nvizType, nameOnly = False):
"""!Get nviz data"""
name = self.FindWindowById(self.win[nvizType]['map']).GetValue()
+ if nameOnly:
+ return name
if nvizType == 'surface' or nvizType == 'fringe':
return self.mapWindow.GetLayerByName(name, mapType = 'raster', dataType = 'nviz')
@@ -1338,12 +2100,276 @@
return self.mapWindow.GetLayerByName(name, mapType = '3d-raster', dataType = 'nviz')
return None
+
+ def OnRecord(self, event):
+ """!Animation: start recording"""
+ anim = self.mapWindow.GetAnimation()
+ if not anim.IsPaused():
+ if anim.Exists() and not anim.IsSaved():
+ msg = _("Do you want to record new animation without saving the previous one?")
+ dlg = wx.MessageDialog(parent = self,
+ message = msg,
+ caption =_("Animation already axists"),
+ style = wx.YES_NO | wx.CENTRE)
+ if dlg.ShowModal() == wx.ID_NO:
+ dlg.Destroy()
+ return
+
+
+ anim.Clear()
+ self.UpdateFrameIndex(0)
+ self.UpdateFrameCount()
+
+ anim.SetPause(False)
+ anim.SetMode(mode = 'record')
+ anim.Start()
+
+ self.FindWindowById(self.win['anim']['play']).Disable()
+ self.FindWindowById(self.win['anim']['record']).Disable()
+ self.FindWindowById(self.win['anim']['pause']).Enable()
+ self.FindWindowById(self.win['anim']['stop']).Enable()
+ self.FindWindowById(self.win['anim']['frameIndex']['slider']).Disable()
+ self.FindWindowById(self.win['anim']['frameIndex']['text']).Disable()
+
+ def OnPlay(self, event):
+ """!Animation: replay"""
+ anim = self.mapWindow.GetAnimation()
+ anim.SetPause(False)
+ anim.SetMode(mode = 'play')
+ anim.Start()
+
+ self.FindWindowById(self.win['anim']['play']).Disable()
+ self.FindWindowById(self.win['anim']['record']).Disable()
+ self.FindWindowById(self.win['anim']['pause']).Enable()
+ self.FindWindowById(self.win['anim']['stop']).Enable()
+ self.FindWindowById(self.win['anim']['frameIndex']['slider']).Enable()
+ self.FindWindowById(self.win['anim']['frameIndex']['text']).Enable()
+
+ def OnStop(self, event):
+ """!Animation: stop recording/replaying"""
+ anim = self.mapWindow.GetAnimation()
+ anim.SetPause(False)
+ if anim.GetMode() == 'save':
+ anim.StopSaving()
+ if anim.IsRunning():
+ anim.Stop()
+
+ self.UpdateFrameIndex(0)
+
+ self.FindWindowById(self.win['anim']['play']).Enable()
+ self.FindWindowById(self.win['anim']['record']).Enable()
+ self.FindWindowById(self.win['anim']['pause']).Disable()
+ self.FindWindowById(self.win['anim']['stop']).Disable()
+ self.FindWindowById(self.win['anim']['frameIndex']['slider']).Disable()
+ self.FindWindowById(self.win['anim']['frameIndex']['text']).Disable()
+
+ def OnPause(self, event):
+ """!Pause animation"""
+ anim = self.mapWindow.GetAnimation()
+
+ anim.SetPause(True)
+ mode = anim.GetMode()
+ if anim.IsRunning():
+ anim.Pause()
+
+ if mode == "record":
+ self.FindWindowById(self.win['anim']['play']).Disable()
+ self.FindWindowById(self.win['anim']['record']).Enable()
+ self.FindWindowById(self.win['anim']['frameIndex']['slider']).Disable()
+ self.FindWindowById(self.win['anim']['frameIndex']['text']).Disable()
+ elif mode == 'play':
+ self.FindWindowById(self.win['anim']['record']).Disable()
+ self.FindWindowById(self.win['anim']['play']).Enable()
+ self.FindWindowById(self.win['anim']['frameIndex']['slider']).Enable()
+ self.FindWindowById(self.win['anim']['frameIndex']['text']).Enable()
+
+ self.FindWindowById(self.win['anim']['pause']).Disable()
+ self.FindWindowById(self.win['anim']['stop']).Enable()
+
+
+ def OnFrameIndex(self, event):
+ """!Frame index changed (by slider)"""
+ index = event.GetInt()
+ self.UpdateFrameIndex(index = index, sliderWidget = False)
+
+ def OnFrameIndexText(self, event):
+ """!Frame index changed by (textCtrl)"""
+ index = event.GetValue()
+ self.UpdateFrameIndex(index = index, textWidget = False)
+
+ def OnFPS(self, event):
+ """!Frames per second changed"""
+ anim = self.mapWindow.GetAnimation()
+ anim.SetFPS(event.GetInt())
+
+ def UpdateFrameIndex(self, index, sliderWidget = True, textWidget = True, goToFrame = True):
+ """!Update frame index"""
+ anim = self.mapWindow.GetAnimation()
+
+ # check index
+ frameCount = anim.GetFrameCount()
+ if index >= frameCount:
+ index = frameCount - 1
+ if index < 0:
+ index = 0
+
+ if sliderWidget:
+ slider = self.FindWindowById(self.win['anim']['frameIndex']['slider'])
+ slider.SetValue(index)
+ if textWidget:
+ text = self.FindWindowById(self.win['anim']['frameIndex']['text'])
+ text.SetValue(int(index))
+
+ # if called from tool window, update frame
+ if goToFrame:
+ anim.GoToFrame(int(index))
+
+ def UpdateFrameCount(self):
+ """!Update frame count label"""
+ anim = self.mapWindow.GetAnimation()
+ count = anim.GetFrameCount()
+ self.FindWindowById(self.win['anim']['info']).SetLabel(str(count))
+
+ def OnAnimationFinished(self, event):
+ """!Animation finished"""
+ anim = self.mapWindow.GetAnimation()
+ self.UpdateFrameIndex(index = 0)
+
+ slider = self.FindWindowById(self.win['anim']['frameIndex']['slider'])
+ text = self.FindWindowById(self.win['anim']['frameIndex']['text'])
+
+ if event.mode == 'record':
+ count = anim.GetFrameCount()
+ slider.SetMax(count)
+ self.UpdateFrameCount()
+
+ self.FindWindowById(self.win['anim']['pause']).Disable()
+ self.FindWindowById(self.win['anim']['stop']).Disable()
+ self.FindWindowById(self.win['anim']['record']).Enable()
+ self.FindWindowById(self.win['anim']['play']).Enable()
+ self.FindWindowById(self.win['anim']['frameIndex']['slider']).Disable()
+ self.FindWindowById(self.win['anim']['frameIndex']['text']).Disable()
+ self.FindWindowById(self.win['anim']['save']['image']['confirm']).Enable()
+
+ self.mapWindow.render['quick'] = False
+ self.mapWindow.Refresh(False)
+
+ def OnAnimationUpdateIndex(self, event):
+ """!Animation: frame index changed"""
+ if event.mode == 'record':
+ self.UpdateFrameCount()
+ elif event.mode == 'play':
+ self.UpdateFrameIndex(index = event.index, goToFrame = False)
+
+ def OnSaveAnimation(self, event):
+ """!Save animation as a sequence of images"""
+ anim = self.mapWindow.GetAnimation()
+
+ prefix = self.FindWindowById(self.win['anim']['save']['image']['prefix']).GetValue()
+ format = self.FindWindowById(self.win['anim']['save']['image']['format']).GetSelection()
+ dir = self.FindWindowById(self.win['anim']['save']['image']['dir']).GetValue()
+
+ if not prefix:
+ gcmd.GMessage(parent = self,
+ message = _("No file prefix given."))
+ return
+ elif not os.path.exists(dir):
+ gcmd.GMessage(parent = self,
+ message = _("Directory %s does not exist.") % dir)
+ return
+
+ self.FindWindowById(self.win['anim']['pause']).Disable()
+ self.FindWindowById(self.win['anim']['stop']).Enable()
+ self.FindWindowById(self.win['anim']['record']).Disable()
+ self.FindWindowById(self.win['anim']['play']).Disable()
+ self.FindWindowById(self.win['anim']['frameIndex']['slider']).Disable()
+ self.FindWindowById(self.win['anim']['frameIndex']['text']).Disable()
+
+ self.FindWindowById(self.win['anim']['save']['image']['confirm']).Disable()
+
+ anim.SaveAnimationFile(path = dir, prefix = prefix, format = format)
+
+ def OnNewConstant(self, event):
+ """!Create new surface with constant value"""
+ #TODO settings
+ name = self.mapWindow.NewConstant()
+ win = self.FindWindowById(self.win['constant']['surface'])
+ name = _("constant#") + str(name)
+ win.Append(name)
+ win.SetStringSelection(name)
+ self.OnConstantSelection(None)
+ self.EnablePage(name = 'constant', enabled = True)
+
+ self.mapWindow.Refresh(eraseBackground = False)
+
+ # need to update list of surfaces in vector page
+ for vtype in ('points', 'lines'):
+ checklist = self.FindWindowById(self.win['vector'][vtype]['surface'])
+ checklist.Append(name)
+ win = self.FindWindowById(self.win['vector']['map'])
+ win.SetValue(win.GetValue())
+
+
+ def OnDeleteConstant(self, event):
+ """!Delete selected constant surface"""
+ layerIdx = self.FindWindowById(self.win['constant']['surface']).GetSelection()
+ if layerIdx == wx.NOT_FOUND:
+ return
+ name = self.FindWindowById(self.win['constant']['surface']).GetStringSelection()
+ self.mapWindow.DeleteConstant(layerIdx)
+ win = self.FindWindowById(self.win['constant']['surface'])
+ win.Delete(layerIdx)
+ if win.IsEmpty():
+ win.SetValue("")
+ self.EnablePage(name = 'constant', enabled = False)
+ else:
+ win.SetSelection(0)
+ self.OnConstantSelection(None)
+
+ # need to update list of surfaces in vector page
+ for vtype in ('points', 'lines'):
+ checklist = self.FindWindowById(self.win['vector'][vtype]['surface'])
+ checklist.Delete(checklist.FindString(name))
+
+ if self.mapDisplay.IsAutoRendered():
+ self.mapWindow.Refresh(False)
+ def OnConstantSelection(self, event):
+ """!Constant selected"""
+ layerIdx = self.FindWindowById(self.win['constant']['surface']).GetSelection()
+ if layerIdx == wx.NOT_FOUND:
+ return
+ name = _("constant#") + str(layerIdx + 1)
+ data = self.mapWindow.constants[layerIdx]
+ for attr, value in data['constant'].iteritems():
+ if attr == 'color':
+ value = self._getColorFromString(value)
+ if attr in ('color', 'value', 'resolution', 'transp'):
+ if attr == 'transp':
+ self.FindWindowById(self.win['constant'][attr]).SetValue(self._getPercent(value))
+ self.FindWindowById(self.win['constant'][attr]).SetValue(value)
+
+ def OnSetConstantProp(self, event):
+ """!Change properties (color, value, resolution)
+ of currently selected constant surface"""
+ layerIdx = self.FindWindowById(self.win['constant']['surface']).GetSelection()
+ if layerIdx == wx.NOT_FOUND:
+ return
+ data = self.mapWindow.constants[layerIdx]
+ for attr in ('resolution', 'value', 'transp'):
+ data['constant'][attr] = self.FindWindowById(self.win['constant'][attr]).GetValue()
+ data['constant']['color'] = self._getColorString(
+ self.FindWindowById(self.win['constant']['color']).GetValue())
+ data['constant']['transp'] = self._getPercent(data['constant']['transp'], toPercent = False)
+
+ # update properties
+ event = wxUpdateProperties(data = data)
+ wx.PostEvent(self.mapWindow, event)
+ if self.mapDisplay.IsAutoRendered():
+ self.mapWindow.Refresh(False)
+
def OnFringe(self, event):
"""!Show/hide fringe"""
- enabled = event.IsChecked()
- win = self.FindWindowById(event.GetId())
-
data = self.GetLayerData('fringe')['surface']
sid = data['object']['id']
@@ -1362,15 +2388,234 @@
winName = self.__GetWindowName(win, event.GetId())
if not winName:
return
- data[winName] = event.GetInt()
+ data[winName] = self.FindWindowById(event.GetId()).GetValue()
for w in win[winName].itervalues():
self.FindWindowById(w).SetValue(data[winName])
event.Skip()
+ def AdjustSliderRange(self, slider, value):
+ minim, maxim = slider.GetRange()
+ if not (minim <= value <= maxim):
+ slider.SetRange(min(minim, value), max(maxim, value))
+
+ def _createIsosurfacePanel(self, parent):
+ panel = wx.Panel(parent = parent, id = wx.ID_ANY)
+
+ vSizer = wx.BoxSizer(wx.HORIZONTAL)
+
+ box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
+ label = " %s " % (_("Isosurface attributes")))
+ boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+ gridSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
+
+ self.win['volume']['attr'] = {}
+ inout = wx.CheckBox(parent = panel, id = wx.ID_ANY,
+ label = _("toggle normal direction"))
+ gridSizer.Add(item = inout, pos = (0,0), span = (1,2), flag = wx.ALIGN_CENTER_VERTICAL)
+ inout.Bind(wx.EVT_CHECKBOX, self.OnInOutMode)
+ self.win['volume']['inout'] = inout.GetId()
+
+ row = 1
+ for code, attrb in (('topo', _("Isosurface value")),
+ ('color', _("Color")),
+ ('mask', _("Mask")),
+ ('transp', _("Transparency")),
+ ('shine', _("Shininess"))):
+ self.win['volume'][code] = {}
+ # label
+ colspan = 1
+ if code == 'topo':
+ colspan = 2
+ gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
+ label = attrb + ':'),
+ pos = (row, 0), span = (1, colspan),flag = wx.ALIGN_CENTER_VERTICAL)
+ if code != 'topo':
+ use = wx.Choice (parent = panel, id = wx.ID_ANY, size = (100, -1),
+ choices = [_("map")])
+ else:
+ use = None
+ # check for required properties
+ if code not in ('topo', 'color', 'shine'):
+ use.Insert(item = _("unset"), pos = 0)
+ self.win['volume'][code]['required'] = False
+ else:
+ self.win['volume'][code]['required'] = True
+ if use and code != 'mask':
+ use.Append(item = _('constant'))
+ if use:
+ self.win['volume'][code]['use'] = use.GetId()
+ use.Bind(wx.EVT_CHOICE, self.OnMapObjUse)
+ gridSizer.Add(item = use, flag = wx.ALIGN_CENTER_VERTICAL,
+ pos = (row, 1))
+
+ if code != 'topo':
+ map = gselect.Select(parent = panel, id = wx.ID_ANY,
+ # size = globalvar.DIALOG_GSELECT_SIZE,
+ size = (200, -1),
+ type = "grid3")
+ self.win['volume'][code]['map'] = map.GetId() - 1 # FIXME
+ map.Bind(wx.EVT_TEXT, self.OnVolumeIsosurfMap)
+ gridSizer.Add(item = map, flag = wx.ALIGN_CENTER_VERTICAL,
+ pos = (row, 2))
+ else:
+ map = None
+
+ if code == 'color':
+ color = UserSettings.Get(group = 'nviz', key = 'volume', subkey = ['color', 'value'])
+ value = csel.ColourSelect(panel, id = wx.ID_ANY,
+ colour = color,
+ size = globalvar.DIALOG_COLOR_SIZE)
+ value.Bind(csel.EVT_COLOURSELECT, self.OnVolumeIsosurfMap)
+ value.SetName('color')
+ elif code == 'mask':
+ value = None
+ elif code == 'topo':
+ value = NumTextCtrl(parent = panel, id = wx.ID_ANY, size = (200, -1),
+ style = wx.TE_PROCESS_ENTER)
+ value.Bind(wx.EVT_TEXT_ENTER, self.OnVolumeIsosurfMap)
+ value.Bind(wx.EVT_KILL_FOCUS, self.OnVolumeIsosurfMap)
+## value.Bind(wx.EVT_TEXT, self.OnVolumeIsosurfMap)
+ else:
+ size = (65, -1)
+ value = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = size,
+ initial = 0)
+ if code == 'topo':
+ value.SetRange(minVal = -1e9, maxVal = 1e9)
+ elif code in ('shine', 'transp'):
+ value.SetRange(minVal = 0, maxVal = 100)
+
+ value.Bind(wx.EVT_SPINCTRL, self.OnVolumeIsosurfMap)
+ value.Bind(wx.EVT_TEXT, self.OnVolumeIsosurfMap)
+
+ if value:
+ self.win['volume'][code]['const'] = value.GetId()
+ if code == 'topo':
+ gridSizer.Add(item = value, flag = wx.ALIGN_CENTER_VERTICAL,
+ pos = (row, 2))
+ else:
+ value.Enable(False)
+ gridSizer.Add(item = value, flag = wx.ALIGN_CENTER_VERTICAL,
+ pos = (row, 3))
+ else:
+ self.win['volume'][code]['const'] = None
+
+ if code != 'topo':
+ self.SetMapObjUseMap(nvizType = 'volume',
+ attrb = code) # -> enable map / disable constant
+
+ row += 1
+
+ boxSizer.Add(item = gridSizer, proportion = 1,
+ flag = wx.ALL | wx.EXPAND, border = 3)
+ vSizer.Add(item = boxSizer, proportion = 1,
+ flag = wx.EXPAND, border = 0)
+ panel.SetSizer(vSizer)
+
+ return panel
+
+ def _createSlicePanel(self, parent):
+ panel = wx.Panel(parent = parent, id = wx.ID_ANY)
+
+ vSizer = wx.BoxSizer(wx.HORIZONTAL)
+
+ box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
+ label = " %s " % (_("Slice attributes")))
+ boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+ hSizer = wx.BoxSizer()
+
+ self.win['volume']['slice'] = {}
+ hSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
+ label = _("Slice parallel to axis:")), proportion = 0,
+ flag = wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, border = 3)
+ axes = wx.Choice(parent = panel, id = wx.ID_ANY, size = (65, -1), choices = ("X", "Y", "Z"))
+ hSizer.Add(axes, proportion = 0, flag = wx.ALIGN_LEFT|wx.LEFT, border = 3)
+ self.win['volume']['slice']['axes'] = axes.GetId()
+ axes.Bind(wx.EVT_CHOICE, self.OnVolumeSliceAxes)
+ boxSizer.Add(hSizer, proportion = 0, flag = wx.ALL|wx.EXPAND, border = 3)
+
+ gridSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
+ gridSizer.AddGrowableCol(0,1)
+ gridSizer.AddGrowableCol(1,2)
+ gridSizer.AddGrowableCol(2,2)
+
+ # text labels
+ for i in range(2):
+ label = wx.StaticText(parent = panel, id = wx.ID_ANY)
+ label.SetName('label_edge_' + str(i))
+ gridSizer.Add(item = label, pos = (0, i + 1),
+ flag = wx.ALIGN_CENTER)
+ for i in range(2,4):
+ label = wx.StaticText(parent = panel, id = wx.ID_ANY)
+ label.SetName('label_edge_' + str(i))
+ gridSizer.Add(item = label, pos = (3, i -1),
+ flag = wx.ALIGN_CENTER)
+ for i in range(2):
+ label = wx.StaticText(parent = panel, id = wx.ID_ANY)
+ label.SetName('label_coord_' + str(i))
+ gridSizer.Add(item = label, pos = (i + 1, 0),
+ flag = wx.ALIGN_CENTER_VERTICAL)
+ label = wx.StaticText(parent = panel, id = wx.ID_ANY)
+ label.SetName('label_coord_2')
+ gridSizer.Add(item = label, pos = (4, 0),
+ flag = wx.ALIGN_CENTER_VERTICAL)
+ # sliders
+ for i, coord in enumerate(('x1', 'x2')):
+ slider = wx.Slider(parent = panel, id = wx.ID_ANY, minValue = 0, maxValue = 100, value = 0)
+ self.win['volume']['slice']['slider_' + coord] = slider.GetId()
+ slider.Bind(wx.EVT_SPIN, self.OnSlicePositionChange)
+ slider.Bind(wx.EVT_SCROLL_THUMBRELEASE, self.OnSlicePositionChanged)
+ gridSizer.Add(item = slider, pos = (1, i + 1),
+ flag = wx.ALIGN_CENTER|wx.EXPAND)
+
+ for i, coord in enumerate(('y1', 'y2')):
+ slider = wx.Slider(parent = panel, id = wx.ID_ANY, minValue = 0, maxValue = 100, value = 0)
+ self.win['volume']['slice']['slider_' + coord] = slider.GetId()
+ slider.Bind(wx.EVT_SPIN, self.OnSlicePositionChange)
+ slider.Bind(wx.EVT_SCROLL_THUMBRELEASE, self.OnSlicePositionChanged)
+ gridSizer.Add(item = slider, pos = (2, i + 1),
+ flag = wx.ALIGN_CENTER|wx.EXPAND)
+
+ for i, coord in enumerate(('z1', 'z2')):
+ slider = wx.Slider(parent = panel, id = wx.ID_ANY, minValue = 0, maxValue = 100, value = 0)
+ self.win['volume']['slice']['slider_' + coord] = slider.GetId()
+ slider.Bind(wx.EVT_SPIN, self.OnSlicePositionChange)
+ slider.Bind(wx.EVT_SCROLL_THUMBRELEASE, self.OnSlicePositionChanged)
+ gridSizer.Add(item = slider, pos = (4,i+1),
+ flag = wx.ALIGN_CENTER|wx.EXPAND)
+
+
+ boxSizer.Add(item = gridSizer, proportion = 1,
+ flag = wx.ALL | wx.EXPAND, border = 3)
+
+ # transparency, reset
+ hSizer = wx.BoxSizer()
+ hSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
+ label = _("Transparency:")), proportion = 0,
+ flag = wx.ALIGN_CENTER_VERTICAL|wx.RIGHT|wx.TOP, border = 7)
+ spin = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
+ min = 0, max = 100, initial = 0)
+ spin.Bind(wx.EVT_SPINCTRL, self.OnSliceTransparency)
+ self.win['volume']['slice']['transp'] = spin.GetId()
+ hSizer.Add(item = spin, proportion = 0,
+ flag = wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.TOP, border = 7)
+
+ hSizer.Add(item = wx.Size(-1, -1), proportion = 1,
+ flag = wx.EXPAND)
+ reset = wx.Button(parent = panel, id = wx.ID_ANY, label = _("Reset"))
+ reset.Bind(wx.EVT_BUTTON, self.OnSliceReset)
+ self.win['volume']['slice']['reset'] = reset.GetId()
+ hSizer.Add(item = reset, proportion = 0,
+ flag = wx.ALIGN_CENTER_VERTICAL|wx.TOP, border = 7)
+
+ boxSizer.Add(hSizer, proportion = 0, flag = wx.ALL|wx.EXPAND, border = 3)
+ panel.SetSizer(boxSizer)
+
+ return panel
+
def _createControl(self, parent, data, name, range, bind = (None, None, None),
- sliderHor = True, size = 200):
- """!Add control (Slider + SpinCtrl)"""
+ sliderHor = True, size = 200, floatSlider = False):
+ """!Add control (Slider + TextCtrl)"""
data[name] = dict()
if sliderHor:
style = wx.SL_HORIZONTAL | wx.SL_AUTOTICKS | \
@@ -1381,31 +2626,62 @@
wx.SL_INVERSE
sizeW = (-1, size)
- slider = wx.Slider(parent = parent, id = wx.ID_ANY,
+ kwargs = dict(parent = parent, id = wx.ID_ANY,
minValue = range[0],
maxValue = range[1],
style = style,
size = sizeW)
+ if floatSlider:
+ slider = FloatSlider(**kwargs)
+ else:
+ slider = wx.Slider(**kwargs)
+
slider.SetName('slider')
if bind[0]:
- slider.Bind(wx.EVT_SCROLL, bind[0])
+ #EVT_SCROLL emits event after slider is released, EVT_SPIN not
+ slider.Bind(wx.EVT_SPIN, bind[0])
- # slider.Bind(wx.EVT_SCROLL_THUMBRELEASE, bind[1])
if bind[1]:
- slider.Bind(wx.EVT_SCROLL_CHANGED, bind[1]) # this only works in MSW
+ slider.Bind(wx.EVT_SCROLL_THUMBRELEASE, bind[1])
data[name]['slider'] = slider.GetId()
- spin = wx.SpinCtrl(parent = parent, id = wx.ID_ANY, size = (65, -1),
- min = range[0],
- max = range[1])
+ text = NumTextCtrl(parent = parent, id = wx.ID_ANY, size = (65, -1),
+ style = wx.TE_PROCESS_ENTER)
- # no 'changed' event ... (FIXME)
- spin.SetName('spin')
+ text.SetName('text')
if bind[2]:
- spin.Bind(wx.EVT_SPINCTRL, bind[2])
+ text.Bind(wx.EVT_TEXT_ENTER, bind[2])
+ text.Bind(wx.EVT_KILL_FOCUS, bind[2])
- data[name]['spin'] = spin.GetId()
+ data[name]['text'] = text.GetId()
+ def _createCompass(self, panel, sizer, type):
+ """!Create 'compass' widget for light and view page"""
+ w = wx.Button(panel, id = wx.ID_ANY, label = _("W"))
+ n = wx.Button(panel, id = wx.ID_ANY, label = _("N"))
+ s = wx.Button(panel, id = wx.ID_ANY, label = _("S"))
+ e = wx.Button(panel, id = wx.ID_ANY, label = _("E"))
+ nw = wx.Button(panel, id = wx.ID_ANY, label = _("NW"))
+ ne = wx.Button(panel, id = wx.ID_ANY, label = _("NE"))
+ se = wx.Button(panel, id = wx.ID_ANY, label = _("SE"))
+ sw = wx.Button(panel, id = wx.ID_ANY, label = _("SW"))
+ minWidth = sw.GetTextExtent(sw.GetLabel())[0] + 15
+ for win, name in zip((w, n, s, e, nw, ne, se, sw),
+ ('w', 'n', 's', 'e', 'nw', 'ne', 'se', 'sw')):
+ win.SetMinSize((minWidth, -1))
+ win.Bind(wx.EVT_BUTTON, self.OnLookFrom)
+ win.SetName(type + '_' + name)
+ sizer.Add(item = nw, pos = (0, 0), flag = wx.ALIGN_CENTER)
+ sizer.Add(item = n, pos = (0, 1), flag = wx.ALIGN_CENTER)
+ sizer.Add(item = ne, pos = (0, 2), flag = wx.ALIGN_CENTER)
+ sizer.Add(item = e, pos = (1, 2), flag = wx.ALIGN_CENTER)
+ sizer.Add(item = se, pos = (2, 2), flag = wx.ALIGN_CENTER)
+ sizer.Add(item = s, pos = (2, 1), flag = wx.ALIGN_CENTER)
+ sizer.Add(item = sw, pos = (2, 0), flag = wx.ALIGN_CENTER)
+ sizer.Add(item = w, pos = (1, 0), flag = wx.ALIGN_CENTER)
+
+
+
def __GetWindowName(self, data, id):
for name in data.iterkeys():
if type(data[name]) is type({}):
@@ -1425,16 +2701,15 @@
'persp',
'twist',
'z-exag'):
- for win in self.win['view'][control].itervalues():
- if control == 'height':
- value = UserSettings.Get(group = 'nviz', key = 'view',
- subkey = ['height', 'value'], internal = True)
- else:
- try:
+ for win in self.win['view'][control].itervalues():
+ try:
+ if control == 'height':
+ value = int(self.mapWindow.iview[control]['value'])
+ else:
value = self.mapWindow.view[control]['value']
- except KeyError:
- value = -1
-
+ except KeyError:
+ value = -1
+
self.FindWindowById(win).SetValue(value)
viewWin = self.FindWindowById(self.win['view']['position'])
@@ -1443,13 +2718,14 @@
viewWin.Draw(pos = (x, y), scale = True)
viewWin.Refresh(False)
- # bgcolor = self.FindWindowById(self.win['settings']['general']['bgcolor']).GetColour()
- # self.OnBgColor(event = bgcolor)
+ color = self._getColorString(self.mapWindow.view['background']['color'])
+ self._display.SetBgColor(str(color))
+
self.Update()
self.mapWindow.Refresh(eraseBackground = False)
self.mapWindow.render['quick'] = False
- self.mapWindow.Refresh(False)
+ self.mapWindow.Refresh(True)
def OnShowLightModel(self, event):
"""!Show light model"""
@@ -1457,49 +2733,49 @@
self._display.DrawLightingModel()
def OnLightChange(self, event):
- """!Position of the light changed"""
+ """!Position of the light changing"""
winName = self.__GetWindowName(self.win['light'], event.GetId())
if not winName:
return
- val = event.GetInt()
- self.mapWindow.light['position']['z'] = val
+ value = self.FindWindowById(event.GetId()).GetValue()
+
+ self.mapWindow.light['position']['z'] = value
for win in self.win['light'][winName].itervalues():
- self.FindWindowById(win).SetValue(val)
+ self.FindWindowById(win).SetValue(value)
+
+ self.PostLightEvent()
- event = wxUpdateLight()
- wx.PostEvent(self.mapWindow, event)
+ event.Skip()
- event.Skip()
-
+ def OnLightChanged(self, event):
+ """!Light changed"""
+ self.PostLightEvent(refresh = True)
+
def OnLightColor(self, event):
"""!Color of the light changed"""
- self.mapWindow.light['color'] = event.GetValue()
+ self.mapWindow.light['color'] = tuple(event.GetValue())
- event = wxUpdateLight()
- wx.PostEvent(self.mapWindow, event)
+ self.PostLightEvent(refresh = True)
event.Skip()
def OnLightValue(self, event):
- """!Light brightness changed"""
+ """!Light brightness/ambient changing"""
data = self.mapWindow.light
self.OnScroll(event, self.win['light'], data)
- event = wxUpdateLight()
- wx.PostEvent(self.mapWindow, event)
-
+ self.PostLightEvent()
event.Skip()
def OnBgColor(self, event):
"""!Background color changed"""
color = event.GetValue()
- self.mapWindow.view['background']['color'] = event.GetValue()
+ self.mapWindow.view['background']['color'] = tuple(color)
color = str(color[0]) + ':' + str(color[1]) + ':' + str(color[2])
-
self._display.SetBgColor(str(color))
- if self.mapDisplay.statusbarWin['render'].IsChecked():
+ if self.mapDisplay.IsAutoRendered():
self.mapWindow.Refresh(False)
def OnSetSurface(self, event):
@@ -1522,7 +2798,7 @@
except:
self.EnablePage('surface', False)
return
-
+
layer = self.mapWindow.GetLayerByName(name, mapType = 'raster')
self.EnablePage('surface', True)
self.UpdateSurfacePage(layer, data, updateName = False)
@@ -1535,7 +2811,6 @@
except:
self.EnablePage('vector', False)
return
-
layer = self.mapWindow.GetLayerByName(name, mapType = 'vector')
self.EnablePage('vector', True)
self.UpdateVectorPage(layer, data, updateName = False)
@@ -1560,23 +2835,34 @@
if not winName:
return
+ value = self.FindWindowById(event.GetId()).GetValue()
+ slider = self.FindWindowById(self.win['view'][winName]['slider'])
+ self.AdjustSliderRange(slider = slider, value = value)
+
if winName == 'height':
view = self.mapWindow.iview # internal
else:
view = self.mapWindow.view
- if winName == 'z-exag' and event.GetInt() >= 0:
+ if winName == 'z-exag' and value >= 0:
self.PostViewEvent(zExag = True)
else:
self.PostViewEvent(zExag = False)
- view[winName]['value'] = event.GetInt()
+ if winName in ('persp', 'twist'):
+ convert = int
+ else:
+ convert = float
+ view[winName]['value'] = convert(value)
+
for win in self.win['view'][winName].itervalues():
- self.FindWindowById(win).SetValue(view[winName]['value'])
-
+ self.FindWindowById(win).SetValue(value)
+
+ self.mapWindow.iview['dir']['use'] = False
self.mapWindow.render['quick'] = True
- self.mapWindow.Refresh(False)
+ if self.mapDisplay.IsAutoRendered():
+ self.mapWindow.Refresh(False)
event.Skip()
@@ -1584,68 +2870,122 @@
"""!View changed, render in full resolution"""
self.mapWindow.render['quick'] = False
self.mapWindow.Refresh(False)
-
self.UpdateSettings()
-
- def OnViewChangedSpin(self, event):
- """!View changed, render in full resolution"""
+ try:# when calling event = None
+ event.Skip()
+ except AttributeError:
+ pass
+
+ def OnViewChangedText(self, event):
+ """!View changed, render in full resolution"""
self.mapWindow.render['quick'] = False
self.OnViewChange(event)
self.OnViewChanged(None)
self.Update()
event.Skip()
-
+
+ def OnLookAt(self, event):
+ """!Look here/center"""
+ name = self.FindWindowById(event.GetId()).GetName()
+ if name == 'center':
+ self._display.LookAtCenter()
+ focus = self.mapWindow.iview['focus']
+ focus['x'], focus['y'], focus['z'] = self._display.GetFocus()
+ self.mapWindow.saveHistory = True
+ self.mapWindow.Refresh(False)
+ elif name == 'top':
+ self.mapWindow.view['position']['x'] = 0.5
+ self.mapWindow.view['position']['y'] = 0.5
+ self.PostViewEvent(zExag = True)
+ self.UpdateSettings()
+ self.mapWindow.Refresh(False)
+ else: # here
+ if self.FindWindowById(event.GetId()).GetValue():
+ self.mapDisplay.Raise()
+ self.mapWindow.mouse['use'] = 'lookHere'
+ self.mapWindow.SetCursor(self.mapWindow.cursors["cross"])
+ else:
+ self.mapWindow.mouse['use'] = 'default'
+ self.mapWindow.SetCursor(self.mapWindow.cursors['default'])
+
def OnResetView(self, event):
"""!Reset to default view (view page)"""
self.mapWindow.ResetView()
self.UpdateSettings()
self.mapWindow.Refresh(False)
- def OnLookAt(self, event):
- """!Look at (view page)"""
- sel = event.GetSelection()
- if sel == 0: # top
- self.mapWindow.view['position']['x'] = 0.5
- self.mapWindow.view['position']['y'] = 0.5
- elif sel == 1: # north
- self.mapWindow.view['position']['x'] = 0.5
- self.mapWindow.view['position']['y'] = 0.0
- elif sel == 2: # south
- self.mapWindow.view['position']['x'] = 0.5
- self.mapWindow.view['position']['y'] = 1.0
- elif sel == 3: # east
- self.mapWindow.view['position']['x'] = 1.0
- self.mapWindow.view['position']['y'] = 0.5
- elif sel == 4: # west
- self.mapWindow.view['position']['x'] = 0.0
- self.mapWindow.view['position']['y'] = 0.5
- elif sel == 5: # north-west
- self.mapWindow.view['position']['x'] = 0.0
- self.mapWindow.view['position']['y'] = 0.0
- elif sel == 6: # north-east
- self.mapWindow.view['position']['x'] = 1.0
- self.mapWindow.view['position']['y'] = 0.0
- elif sel == 7: # south-east
- self.mapWindow.view['position']['x'] = 1.0
- self.mapWindow.view['position']['y'] = 1.0
- elif sel == 8: # south-west
- self.mapWindow.view['position']['x'] = 0.0
- self.mapWindow.view['position']['y'] = 1.0
+ def OnResetSurfacePosition(self, event):
+ """!Reset position of surface"""
- self.PostViewEvent(zExag = True)
+ for win in self.win['surface']['position'].itervalues():
+ if win == self.win['surface']['position']['axis']:
+ self.FindWindowById(win).SetSelection(0)
+ elif win == self.win['surface']['position']['reset']:
+ continue
+ else:
+ self.FindWindowById(win).SetValue(0)
+
+ data = self.GetLayerData('surface')
+ data['surface']['position']['x'] = 0
+ data['surface']['position']['y'] = 0
+ data['surface']['position']['z'] = 0
+ data['surface']['position']['update'] = None
+ # update properties
+ event = wxUpdateProperties(data = data)
+ wx.PostEvent(self.mapWindow, event)
- self.UpdateSettings()
+ if self.mapDisplay.IsAutoRendered():
+ self.mapWindow.Refresh(False)
+
+ def OnLookFrom(self, event):
+ """!Position of view/light changed by buttons"""
+ name = self.FindWindowById(event.GetId()).GetName()
+ buttonName = name.split('_')[1]
+ if name.split('_')[0] == 'view':
+ type = 'view'
+ data = self.mapWindow.view
+ else:
+ type = 'light'
+ data = self.mapWindow.light
+ if buttonName == 'n': # north
+ data['position']['x'] = 0.5
+ data['position']['y'] = 0.0
+ elif buttonName == 's': # south
+ data['position']['x'] = 0.5
+ data['position']['y'] = 1.0
+ elif buttonName == 'e': # east
+ data['position']['x'] = 1.0
+ data['position']['y'] = 0.5
+ elif buttonName =='w': # west
+ data['position']['x'] = 0.0
+ data['position']['y'] = 0.5
+ elif buttonName == 'nw': # north-west
+ data['position']['x'] = 0.0
+ data['position']['y'] = 0.0
+ elif buttonName == 'ne': # north-east
+ data['position']['x'] = 1.0
+ data['position']['y'] = 0.0
+ elif buttonName == 'se': # south-east
+ data['position']['x'] = 1.0
+ data['position']['y'] = 1.0
+ elif buttonName == 'sw': # south-west
+ data['position']['x'] = 0.0
+ data['position']['y'] = 1.0
+ if type == 'view':
+ self.PostViewEvent(zExag = True)
+
+ self.UpdateSettings()
+ else:
+ self.PostLightEvent()
+ lightWin = self.FindWindowById(self.win['light']['position'])
+ x, y = lightWin.UpdatePos(self.mapWindow.light['position']['x'],
+ self.mapWindow.light['position']['y'])
+ lightWin.Draw(pos = (x, y), scale = True)
+ lightWin.Refresh(False)
self.mapWindow.render['quick'] = False
self.mapWindow.Refresh(False)
- def OnClose(self, event):
- """!Close button pressed
-
- Close dialog
- """
- self.Hide()
-
def OnMapObjUse(self, event):
"""!Set surface attribute -- use -- map/constant"""
if not self.mapWindow.init:
@@ -1676,7 +3016,7 @@
value = self.FindWindowById(self.win[nvizType][attrb]['const']).GetColour()
value = self._getColorString(value)
else:
- value = self.FindWindowById(self.win[nvizType][attrb]['const']).GetValue()
+ value = self._getPercent(self.FindWindowById(self.win[nvizType][attrb]['const']).GetValue(), toPercent = False)
self.SetMapObjUseMap(nvizType = nvizType,
attrb = attrb, map = useMap)
@@ -1691,26 +3031,32 @@
data = self.mapWindow.GetLayerByName(name, mapType = '3d-raster', dataType = 'nviz')
list = self.FindWindowById(self.win['volume']['isosurfs'])
id = list.GetSelection()
- data[nvizType]['isosurface'][id][attrb] = { 'map' : useMap,
- 'value' : str(value),
- 'update' : None }
+ if id != -1:
+ data[nvizType]['isosurface'][id][attrb] = { 'map' : useMap,
+ 'value' : str(value),
+ 'update' : None }
# update properties
event = wxUpdateProperties(data = data)
wx.PostEvent(self.mapWindow, event)
- if self.mapDisplay.statusbarWin['render'].IsChecked():
+ if self.mapDisplay.IsAutoRendered():
self.mapWindow.Refresh(False)
-
+
def EnablePage(self, name, enabled = True):
"""!Enable/disable all widgets on page"""
for key, item in self.win[name].iteritems():
- if key == 'map' or key == 'surface':
+ if key in ('map', 'surface', 'new','planes'):
continue
if type(item) == types.DictType:
- for sitem in self.win[name][key].itervalues():
- if type(sitem) == types.IntType:
- self.FindWindowById(sitem).Enable(enabled)
+ for skey, sitem in self.win[name][key].iteritems():
+ if type(sitem) == types.DictType:
+ for ssitem in self.win[name][key][skey].itervalues():
+ if type(ssitem) == types.IntType:
+ self.FindWindowById(ssitem).Enable(enabled)
+ else:
+ if type(sitem) == types.IntType:
+ self.FindWindowById(sitem).Enable(enabled)
else:
if type(item) == types.IntType:
self.FindWindowById(item).Enable(enabled)
@@ -1721,7 +3067,8 @@
incSel = -1 # decrement selection (no 'unset')
else:
incSel = 0
-
+ if nvizType == 'volume' and attrb == 'topo':
+ return
if map is True: # map
if attrb != 'topo': # changing map topography not allowed
# not sure why, but here must be disabled both ids, should be fixed!
@@ -1735,13 +3082,17 @@
self.FindWindowById(self.win[nvizType][attrb]['const']).Enable(True)
self.FindWindowById(self.win[nvizType][attrb]['use']).SetSelection(2 + incSel)
else: # unset
+ self.FindWindowById(self.win[nvizType][attrb]['use']).SetSelection(0)
self.FindWindowById(self.win[nvizType][attrb]['map'] + 1).Enable(False)
if self.win[nvizType][attrb]['const']:
self.FindWindowById(self.win[nvizType][attrb]['const']).Enable(False)
- self.FindWindowById(self.win[nvizType][attrb]['use']).SetSelection(0)
+
def OnSurfaceMap(self, event):
"""!Set surface attribute"""
+ if self.vetoGSelectEvt:
+ self.vetoGSelectEvt = False
+ return
self.SetMapObjAttrb(nvizType = 'surface', winId = event.GetId())
def SetMapObjAttrb(self, nvizType, winId):
@@ -1749,32 +3100,34 @@
if not self.mapWindow.init:
return
- attrb = self.__GetWindowName(self.win[nvizType], winId)
+ attrb = self.__GetWindowName(self.win[nvizType], winId)
if not attrb:
return
- if nvizType == 'volume' and attrb == 'topo':
- return
-
- selection = self.FindWindowById(self.win[nvizType][attrb]['use']).GetSelection()
- if self.win[nvizType][attrb]['required']:
- selection += 1
-
- if selection == 0: # unset
+ if not (nvizType == 'volume' and attrb == 'topo'):
+ selection = self.FindWindowById(self.win[nvizType][attrb]['use']).GetSelection()
+ if self.win[nvizType][attrb]['required']:
+ selection += 1
+
+ if selection == 0: # unset
+ useMap = None
+ value = ''
+ elif selection == 1: # map
+ value = self.FindWindowById(self.win[nvizType][attrb]['map']).GetValue()
+ useMap = True
+ else: # constant
+ if attrb == 'color':
+ value = self.FindWindowById(self.win[nvizType][attrb]['const']).GetColour()
+ # tuple to string
+ value = self._getColorString(value)
+ else:
+ value = self._getPercent(
+ self.FindWindowById(self.win[nvizType][attrb]['const']).GetValue(), toPercent = False)
+
+ useMap = False
+ else:
useMap = None
- value = ''
- elif selection == 1: # map
- value = self.FindWindowById(self.win[nvizType][attrb]['map']).GetValue()
- useMap = True
- else: # constant
- if attrb == 'color':
- value = self.FindWindowById(self.win[nvizType][attrb]['const']).GetColour()
- # tuple to string
- value = self._getColorString(value)
- else:
- value = self.FindWindowById(self.win[nvizType][attrb]['const']).GetValue()
- useMap = False
-
+ value = self.FindWindowById(self.win[nvizType][attrb]['const']).GetValue()
if not self.pageChanging:
name = self.FindWindowById(self.win[nvizType]['map']).GetValue()
if nvizType == 'surface':
@@ -1790,21 +3143,27 @@
data[nvizType]['isosurface'][id][attrb] = { 'map' : useMap,
'value' : str(value),
'update' : None }
+ if attrb == 'topo':
+ list = self.FindWindowById(self.win['volume']['isosurfs'])
+ sel = list.GetSelection()
+ list.SetString(sel, "%s %s" % (_("Level"), str(value)))
+ list.Check(sel)
# update properties
event = wxUpdateProperties(data = data)
wx.PostEvent(self.mapWindow, event)
- if self.mapDisplay.statusbarWin['render'].IsChecked():
+ if self.mapDisplay.IsAutoRendered():
self.mapWindow.Refresh(False)
def OnSurfaceResolution(self, event):
"""!Draw resolution changed"""
self.SetSurfaceResolution()
- if self.mapDisplay.statusbarWin['render'].IsChecked():
+ if self.mapDisplay.IsAutoRendered():
self.mapWindow.Refresh(False)
-
+
+
def SetSurfaceResolution(self):
"""!Set draw resolution"""
coarse = self.FindWindowById(self.win['surface']['draw']['res-coarse']).GetValue()
@@ -1822,17 +3181,11 @@
def SetSurfaceMode(self):
"""!Set draw mode"""
mode = self.FindWindowById(self.win['surface']['draw']['mode']).GetSelection()
- if mode == 0: # coarse
- self.FindWindowById(self.win['surface']['draw']['res-coarse']).Enable(True)
- self.FindWindowById(self.win['surface']['draw']['res-fine']).Enable(False)
- elif mode == 1: # fine
- self.FindWindowById(self.win['surface']['draw']['res-coarse']).Enable(False)
- self.FindWindowById(self.win['surface']['draw']['res-fine']).Enable(True)
- else: # both
- self.FindWindowById(self.win['surface']['draw']['res-coarse']).Enable(True)
- self.FindWindowById(self.win['surface']['draw']['res-fine']).Enable(True)
-
style = self.FindWindowById(self.win['surface']['draw']['style']).GetSelection()
+ if style == 0: # wire
+ self.FindWindowById(self.win['surface']['draw']['wire-color']).Enable(True)
+ elif style == 1: # surface
+ self.FindWindowById(self.win['surface']['draw']['wire-color']).Enable(False)
shade = self.FindWindowById(self.win['surface']['draw']['shading']).GetSelection()
@@ -1853,7 +3206,7 @@
event = wxUpdateProperties(data = data)
wx.PostEvent(self.mapWindow, event)
- if self.mapDisplay.statusbarWin['render'].IsChecked():
+ if self.mapDisplay.IsAutoRendered():
self.mapWindow.Refresh(False)
def OnSurfaceModeAll(self, event):
@@ -1884,13 +3237,48 @@
event = wxUpdateProperties(data = data)
wx.PostEvent(self.mapWindow, event)
- if self.mapDisplay.statusbarWin['render'].IsChecked():
+ if self.mapDisplay.IsAutoRendered():
self.mapWindow.Refresh(False)
def _getColorString(self, color):
- """!Set wire color"""
+ """!Convert color tuple to R:G:B format
+
+ @param color tuple
+
+ @return string R:G:B
+ """
return str(color[0]) + ':' + str(color[1]) + ':' + str(color[2])
+ def _getColorFromString(self, color, delim = ':'):
+ """!Convert color string (R:G:B) to wx.Color
+
+ @param color string
+ @param delim delimiter
+
+ @return wx.Color instance
+ """
+ return wx.Color(*map(int, color.split(delim)))
+
+ def _get3dRange(self, name):
+ """!Gelper func for getting range of 3d map"""
+ ret = gcmd.RunCommand('r3.info', read = True, flags = 'r', map = name)
+ if ret:
+ range = []
+ for value in ret.strip('\n').split('\n'):
+ range.append(float(value.split('=')[1]))
+ return range
+
+ return -1e6, 1e6
+
+ def _getPercent(self, value, toPercent = True):
+ """!Convert values 0 - 255 to percents and vice versa"""
+ value = int(value)
+ if toPercent:
+ value = int(value/255. * 100)
+ else:
+ value = int(value/100. * 255)
+ return value
+
def OnSurfaceWireColor(self, event):
"""!Set wire color"""
data = self.GetLayerData('surface')
@@ -1902,7 +3290,7 @@
event = wxUpdateProperties(data = data)
wx.PostEvent(self.mapWindow, event)
- if self.mapDisplay.statusbarWin['render'].IsChecked():
+ if self.mapDisplay.IsAutoRendered():
self.mapWindow.Refresh(False)
def OnSurfaceAxis(self, event):
@@ -1912,19 +3300,25 @@
axis = self.FindWindowById(self.win['surface']['position']['axis']).GetSelection()
slider = self.FindWindowById(self.win['surface']['position']['slider'])
- spin = self.FindWindowById(self.win['surface']['position']['spin'])
+ text = self.FindWindowById(self.win['surface']['position']['text'])
+ xydim = self._display.GetLongDim()
+ zdim = self._display.GetZRange()
+ zdim = zdim[1] - zdim[0]
x, y, z = self._display.GetSurfacePosition(id)
if axis == 0: # x
+ slider.SetRange(-3 * xydim, 3 * xydim)
slider.SetValue(x)
- spin.SetValue(x)
+ text.SetValue(x)
elif axis == 1: # y
+ slider.SetRange(-3 * xydim, 3 * xydim)
slider.SetValue(y)
- spin.SetValue(y)
+ text.SetValue(y)
else: # z
+ slider.SetRange(-3 * zdim, 3 * zdim)
slider.SetValue(z)
- spin.SetValue(z)
+ text.SetValue(z)
def OnSurfacePosition(self, event):
"""!Surface position"""
@@ -1932,10 +3326,14 @@
if not winName:
return
axis = self.FindWindowById(self.win['surface']['position']['axis']).GetSelection()
- value = event.GetInt()
+ value = self.FindWindowById(event.GetId()).GetValue()
+ slider = self.FindWindowById(self.win['surface'][winName]['slider'])
+ self.AdjustSliderRange(slider = slider, value = value)
+
for win in self.win['surface']['position'].itervalues():
- if win == self.win['surface']['position']['axis']:
+ if win in (self.win['surface']['position']['axis'],
+ self.win['surface']['position']['reset']):
continue
else:
self.FindWindowById(win).SetValue(value)
@@ -1951,19 +3349,30 @@
else: # z
z = value
- data = self.GetLayerData('surface')
data['surface']['position']['x'] = x
data['surface']['position']['y'] = y
data['surface']['position']['z'] = z
data['surface']['position']['update'] = None
# update properties
+
event = wxUpdateProperties(data = data)
wx.PostEvent(self.mapWindow, event)
- if self.mapDisplay.statusbarWin['render'].IsChecked():
+ self.mapWindow.render['quick'] = True
+ if self.mapDisplay.IsAutoRendered():
self.mapWindow.Refresh(False)
# self.UpdatePage('surface')
+
+ def OnSurfacePositionChanged(self, event):
+ """!Surface position changed"""
+ self.mapWindow.render['quick'] = False
+ self.mapWindow.Refresh(False)
+ def OnSurfacePositionText(self, event):
+ """!Surface position changed by textctrl"""
+ self.OnSurfacePosition(event)
+ self.OnSurfacePositionChanged(None)
+
def UpdateVectorShow(self, vecType, enabled):
"""!Enable/disable lines/points widgets
@@ -2005,9 +3414,9 @@
data = self.GetLayerData('vector')['vector']
if checked:
- self.mapWindow.LoadVector(item, points = points)
+ self.mapWindow.LoadVector(item, points = points, append = False)
else:
- self.mapWindow.UnloadVector(item, points = points)
+ self.mapWindow.UnloadVector(item, points = points, remove = False)
self.UpdateVectorShow(vecType, checked)
@@ -2024,7 +3433,7 @@
event = wxUpdateProperties(data = data)
wx.PostEvent(self.mapWindow, event)
- if self.mapDisplay.statusbarWin['render'].IsChecked():
+ if self.mapDisplay.IsAutoRendered():
self.mapWindow.Refresh(False)
event.Skip()
@@ -2059,15 +3468,23 @@
mode = {}
if self.FindWindowById(self.win['vector']['lines']['flat']).GetSelection() == 0:
mode['type'] = 'surface'
- mode['surface'] = self.FindWindowById(self.win['vector']['lines']['surface']).GetValue()
- mode['update'] = None
+ mode['surface'] = {}
+ checklist = self.FindWindowById(self.win['vector']['lines']['surface'])
+ value = list()
+ checked = list()
+ for surface in range(checklist.GetCount()):
+ value.append(checklist.GetString(surface))
+ checked.append(checklist.IsChecked(surface))
+
+ mode['surface']['value'] = value
+ mode['surface']['show'] = checked
else:
mode['type'] = 'flat'
for attrb in ('width', 'mode'):
data['vector']['lines'][attrb]['update'] = None
data['vector']['lines']['width']['value'] = width
- data['vector']['lines']['mode']['value'] = mode
+ data['vector']['lines']['mode'] = mode
color = self.FindWindowById(self.win['vector']['lines']['color']).GetColour()
@@ -2082,31 +3499,29 @@
event = wxUpdateProperties(data = data)
wx.PostEvent(self.mapWindow, event)
- if self.mapDisplay.statusbarWin['render'].IsChecked():
+ if self.mapDisplay.IsAutoRendered():
self.mapWindow.Refresh(False)
def OnVectorHeight(self, event):
- value = event.GetInt()
id = event.GetId()
- if id == self.win['vector']['lines']['height']['spin'] or \
- id == self.win['vector']['lines']['height']['slider']:
+ if id in self.win['vector']['lines']['height'].values():
vtype = 'lines'
else:
vtype = 'points'
- if type(event) == type(wx.ScrollEvent()):
- # slider
- win = self.FindWindowById(self.win['vector'][vtype]['height']['spin'])
- else:
- # spin
- win = self.FindWindowById(self.win['vector'][vtype]['height']['slider'])
- win.SetValue(value)
-
- data = self.GetLayerData('vector')['vector'][vtype]
- data['height'] = { 'value' : value,
- 'update' : None }
+ value = self.FindWindowById(id).GetValue()
+ slider = self.FindWindowById(self.win['vector'][vtype]['height']['slider'])
+ self.AdjustSliderRange(slider = slider, value = value)
+ for win in self.win['vector'][vtype]['height'].itervalues():
+ self.FindWindowById(win).SetValue(value)
+
+ data = self.GetLayerData('vector')
+ data['vector'][vtype]['height'] = { 'value' : value,
+ 'update' : None }
+
# update properties
+
event = wxUpdateProperties(data = data)
wx.PostEvent(self.mapWindow, event)
@@ -2119,10 +3534,9 @@
def OnVectorHeightFull(self, event):
"""!Vector height changed, render in full resolution"""
self.OnVectorHeight(event)
- self.OnVectorSurface(event)
+## self.OnVectorSurface(event)
id = event.GetId()
- if id == self.win['vector']['lines']['height']['spin'] or \
- id == self.win['vector']['lines']['height']['slider']:
+ if id in self.win['vector']['lines']['height'].values():
vtype = 'lines'
else:
vtype = 'points'
@@ -2131,30 +3545,38 @@
self.mapWindow.render['v' + vtype] = False
self.mapWindow.Refresh(False)
- def OnVectorHeightSpin(self, event):
+ def OnVectorHeightText(self, event):
"""!Vector height changed, render in full resolution"""
- # TODO: use step value instead
# self.OnVectorHeight(event)
self.OnVectorHeightFull(event)
-
+
def OnVectorSurface(self, event):
- """!Reference surface for vector map (lines/points)"""
+ """!Reference surface for vector map (lines/points)"""
id = event.GetId()
if id == self.win['vector']['lines']['surface']:
vtype = 'lines'
else:
vtype = 'points'
+ checkList = self.FindWindowById(self.win['vector'][vtype]['surface'])
+ checked = []
+ surfaces = []
+ for items in range(checkList.GetCount()):
+ checked.append(checkList.IsChecked(items))
+ surfaces.append(checkList.GetString(items))
+
data = self.GetLayerData('vector')
- data['vector'][vtype]['mode']['surface'] = { 'value' : event.GetString(),
- 'update' : None }
+ data['vector'][vtype]['mode']['surface'] = { 'value' : surfaces,
+ 'show' : checked}
+ data['vector'][vtype]['mode']['update'] = None
# update properties
event = wxUpdateProperties(data = data)
wx.PostEvent(self.mapWindow, event)
- if self.mapDisplay.statusbarWin['render'].IsChecked():
+ if self.mapDisplay.IsAutoRendered():
self.mapWindow.Refresh(False)
+
def OnVectorPoints(self, event):
"""!Set vector points mode, apply changes if auto-rendering is enabled"""
@@ -2182,17 +3604,18 @@
event = wxUpdateProperties(data = data)
wx.PostEvent(self.mapWindow, event)
- if self.mapDisplay.statusbarWin['render'].IsChecked():
+ if self.mapDisplay.IsAutoRendered():
self.mapWindow.Refresh(False)
-
+
+
def UpdateIsosurfButtons(self, list):
"""!Enable/disable buttons 'add', 'delete',
'move up', 'move down'"""
nitems = list.GetCount()
- add = self.parent.FindWindowById(self.win['volume']['btnIsosurfAdd'])
- delete = self.parent.FindWindowById(self.win['volume']['btnIsosurfDelete'])
- moveDown = self.parent.FindWindowById(self.win['volume']['btnIsosurfMoveDown'])
- moveUp = self.parent.FindWindowById(self.win['volume']['btnIsosurfMoveUp'])
+ add = self.parent.FindWindowById(self.win['volume']['btnAdd'])
+ delete = self.parent.FindWindowById(self.win['volume']['btnDelete'])
+ moveDown = self.parent.FindWindowById(self.win['volume']['btnMoveDown'])
+ moveUp = self.parent.FindWindowById(self.win['volume']['btnMoveUp'])
if nitems >= wxnviz.MAX_ISOSURFS:
# disable add button on max
add.Enable(False)
@@ -2216,13 +3639,42 @@
moveUp.Enable(False)
else:
moveUp.Enable(True)
+
+ def OnVolumeMode(self, event):
+ """!Change mode isosurfaces/slices"""
+ mode = self.FindWindowById(self.win['volume']['draw']['mode']).GetSelection()
+ data = self.GetLayerData('volume')['volume']
- def OnVolumeIsosurfMode(self, event):
+ sizer = self.isoPanel.GetContainingSizer()
+ sizer = self.slicePanel.GetContainingSizer()
+ listBox = self.FindWindowByName('listStaticBox')
+ if mode == 0:
+ sizer.Show(self.isoPanel)
+ sizer.Hide(self.slicePanel)
+ listBox.SetLabel(" %s " % _("List of isosurfaces"))
+ data['draw']['mode']['value'] = 0
+ data['draw']['mode']['desc'] = 'isosurface'
+ else:
+ sizer.Hide(self.isoPanel)
+ sizer.Show(self.slicePanel)
+ listBox.SetLabel(" %s " % _("List of slices"))
+ data['draw']['mode']['value'] = 1
+ data['draw']['mode']['desc'] = 'slice'
+
+ if event:
+ name = self.FindWindowById(self.win['volume']['map']).GetValue()
+ layer = self.mapWindow.GetLayerByName(name, mapType = '3d-raster')
+ self.UpdateVolumePage(layer, data, updateName = False)
+
+ sizer.Layout()
+ listBox.GetParent().Fit()
+
+ def OnVolumeDrawMode(self, event):
+ """!Set isosurface/slice draw mode"""
+ self.SetVolumeDrawMode(event.GetSelection())
+
+ def SetVolumeDrawMode(self, selection):
"""!Set isosurface draw mode"""
- self.SetIsosurfaceMode(event.GetSelection())
-
- def SetIsosurfaceMode(self, selection):
- """!Set isosurface draw mode"""
data = self.GetLayerData('volume')['volume']
id = data['object']['id']
@@ -2231,55 +3683,113 @@
mode |= wxnviz.DM_FLAT
else:
mode |= wxnviz.DM_GOURAUD
+
+ if self.FindWindowById(self.win['volume']['draw']['mode']).GetSelection() == 0:
+ self._display.SetIsosurfaceMode(id, mode)
+ data['draw']['shading']['isosurface']['desc'] = 'gouraud'
+ data['draw']['shading']['isosurface']['value'] = mode
+ else:
+ self._display.SetSliceMode(id, mode)
+ data['draw']['shading']['slice']['desc'] = 'flat'
+ data['draw']['shading']['slice']['value'] = mode
- self._display.SetIsosurfaceMode(id, mode)
-
- if self.mapDisplay.statusbarWin['render'].IsChecked():
+ if self.mapDisplay.IsAutoRendered():
self.mapWindow.Refresh(False)
- def OnVolumeIsosurfResolution(self, event):
- """!Set isosurface draw resolution"""
- self.SetIsosurfaceResolution(event.GetInt())
+ def OnVolumeResolution(self, event):
+ """!Set isosurface/slice draw resolution"""
+ self.SetVolumeResolution(event.GetInt())
- def SetIsosurfaceResolution(self, res):
+ def SetVolumeResolution(self, res):
"""!Set isosurface draw resolution"""
data = self.GetLayerData('volume')['volume']
+ id = data['object']['id']
+ if self.FindWindowById(self.win['volume']['draw']['mode']).GetSelection() == 0:
+ self._display.SetIsosurfaceRes(id, res)
+ data['draw']['resolution']['isosurface']['value'] = res
+ else:
+ self._display.SetSliceRes(id, res)
+ data['draw']['resolution']['slice']['value'] = res
+
+ if self.mapDisplay.IsAutoRendered():
+ self.mapWindow.Refresh(False)
+
+ def OnInOutMode(self, event):
+ """!Change isosurfaces mode inout"""
+ data = self.GetLayerData('volume')['volume']
id = data['object']['id']
- self._display.SetIsosurfaceRes(id, res)
+ isosurfId = self.FindWindowById(self.win['volume']['isosurfs']).GetSelection()
- if self.mapDisplay.statusbarWin['render'].IsChecked():
+ ret = self._display.SetIsosurfaceInOut(id, isosurfId, event.GetInt())
+ if ret == 1:
+ data['isosurface'][isosurfId]['inout'] = event.GetInt()
+
+ if self.mapDisplay.IsAutoRendered():
self.mapWindow.Refresh(False)
+
def OnVolumeIsosurfMap(self, event):
"""!Set surface attribute"""
+ if self.vetoGSelectEvt:
+ self.vetoGSelectEvt = False
+ return
self.SetMapObjAttrb(nvizType = 'volume', winId = event.GetId())
- def OnVolumeIsosurfCheck(self, event):
- """!Isosurface checked (->load) or unchecked (->unload)"""
+ def OnVolumeCheck(self, event):
+ """!Isosurface/slice checked (->load) or unchecked (->unload)"""
+ if self.FindWindowById(self.win['volume']['draw']['mode']).GetSelection() == 0:
+ mode = 'isosurf'
+ else:
+ mode = 'slice'
index = event.GetSelection()
- list = self.FindWindowById(self.win['volume']['isosurfs'])
+ list = self.FindWindowById(self.win['volume'][mode + 's'])
data = self.GetLayerData('volume')['volume']
- id = data['object']['id']
+ vid = data['object']['id']
- isosurfId = event.GetSelection()
+ id = event.GetSelection()
- if list.IsChecked(index):
- self._display.SetIsosurfaceTransp(id, isosurfId, False, "0")
+ if mode == 'isosurf':
+ if list.IsChecked(index):
+ if 'transp' in data['isosurface'][id] and\
+ data['isosurface'][id]['transp']['map'] is not None:
+ if data['isosurface'][id]['transp']['map']:
+ map = True
+ value = data['isosurface'][id]['transp']['value']
+ elif data['isosurface'][id]['transp']['map'] is not None:
+ map = False
+ value = data['isosurface'][id]['transp']['value']
+ self._display.SetIsosurfaceTransp(vid, id, map, value)
+ else:
+ self._display.SetIsosurfaceTransp(vid, id, False, "0")
+ else:
+ # disable -> make transparent
+ self._display.SetIsosurfaceTransp(vid, id, False, "255")
else:
- # disable -> make transparent
- self._display.SetIsosurfaceTransp(id, isosurfId, False, "255")
-
- if self.mapDisplay.statusbarWin['render'].IsChecked():
+ if list.IsChecked(index):
+ value = data['slice'][id]['transp']['value']
+ self._display.SetSliceTransp(vid, id, value)
+ else:
+ # disable -> make transparent
+ self._display.SetSliceTransp(vid, id, 255)
+
+ if self.mapDisplay.IsAutoRendered():
self.mapWindow.Refresh(False)
- def OnVolumeIsosurfSelect(self, event):
- """!Isosurface item selected"""
- winUp = self.FindWindowById(self.win['volume']['btnIsosurfMoveUp'])
- winDown = self.FindWindowById(self.win['volume']['btnIsosurfMoveDown'])
+ def OnVolumeSelect(self, event):
+ """!Isosurface/Slice item selected"""
+ if self.FindWindowById(self.win['volume']['draw']['mode']).GetSelection() == 0:
+ mode = 'isosurf'
+ else:
+ mode = 'slice'
+
+ winUp = self.FindWindowById(self.win['volume']['btnMoveUp'])
+ winDown = self.FindWindowById(self.win['volume']['btnMoveDown'])
selection = event.GetSelection()
- if selection == 0:
+ if selection == -1:
+ return
+ elif selection == 0:
winUp.Enable(False)
if not winDown.IsEnabled():
winDown.Enable()
@@ -2296,83 +3806,95 @@
# update dialog
name = self.FindWindowById(self.win['volume']['map']).GetValue()
layer = self.mapWindow.GetLayerByName(name, mapType = '3d-raster')
- data = self.GetLayerData('volume')['volume']['isosurface'][selection]
- self.UpdateVolumeIsosurfPage(layer, data)
+ if mode == 'isosurf':
+ data = self.GetLayerData('volume')['volume']['isosurface'][selection]
+ self.UpdateVolumeIsosurfPage(data)
+ else:
+ data = self.GetLayerData('volume')['volume']['slice'][selection]
+ self.UpdateVolumeSlicePage(data)
- def OnVolumeIsosurfAdd(self, event):
- """!Add new isosurface to the list"""
- list = self.FindWindowById(self.win['volume']['isosurfs'])
- level = self.FindWindowById(self.win['volume']['topo']['const']).GetValue()
- sel = list.GetSelection()
- if sel < 0 or sel >= list.GetCount() - 1:
- item = list.Append(item = "%s %s" % (_("Level"), str(level)))
+
+ def OnVolumeAdd(self, event):
+ """!Add new isosurface/slice to the list"""
+ if self.FindWindowById(self.win['volume']['draw']['mode']).GetSelection() == 0:
+ mode = 'isosurf'
else:
- list.Insert(item = "%s %s" % (_("Level"), str(level)),
- pos = sel+1) # append
- item = sel + 1
+ mode = 'slice'
+ list = self.FindWindowById(self.win['volume'][mode + 's'])
- list.Check(item)
- list.SetSelection(item)
-
name = self.FindWindowById(self.win['volume']['map']).GetValue()
layer = self.mapWindow.GetLayerByName(name, mapType = '3d-raster')
data = self.GetLayerData('volume')['volume']
id = data['object']['id']
- # collect properties
- isosurfData = {}
- for attrb in ('topo', 'color', 'mask',
- 'transp', 'shine', 'emit'):
- if attrb == 'topo':
- isosurfData[attrb] = {}
- win = self.FindWindowById(self.win['volume'][attrb]['const'])
- isosurfData[attrb]['value'] = win.GetValue()
+ sel = list.GetSelection()
+ if mode == 'isosurf':
+ isosurfData = self.mapWindow.nvizDefault.SetIsosurfaceDefaultProp()
+ if isosurfData['color']['map']:
+ isosurfData['color']['value'] = layer.name
+
+ level = isosurfData['topo']['value'] = round(self._get3dRange(name = layer.name)[0], 2)
+
+ if sel < 0 or sel >= list.GetCount() - 1:
+ item = list.Append(item = "%s %s" % (_("Level"), str(level)))
else:
- uwin = self.FindWindowById(self.win['volume'][attrb]['use'])
- sel = uwin.GetSelection()
- if self.win['volume'][attrb]['required']:
- sel += 1
- if sel == 0: # unset
- continue
-
- isosurfData[attrb] = {}
- if sel == 1: # map
- isosurfData[attrb]['map'] = True
- vwin = self.FindWindowById(self.win['volume'][attrb]['map'])
- value = vwin.GetValue()
- else: # const
- isosurfData[attrb]['map'] = False
- vwin = self.FindWindowById(self.win['volume'][attrb]['const'])
- if vwin.GetName() == "color":
- value = self._getColorString(vwin.GetValue())
- else:
- value = vwin.GetValue()
- isosurfData[attrb]['value'] = value
+ list.Insert(item = "%s %s" % (_("Level"), str(level)),
+ pos = sel+1) # append
+ item = sel + 1
+ else:
+ sliceData = self.mapWindow.nvizDefault.SetSliceDefaultProp()
+ axis = ("X", "Y", "Z")[sliceData['position']['axis']]
+ if sel < 0 or sel >= list.GetCount() - 1:
+ item = list.Append(item = "%s %s" % (_("Slice parallel to"), axis))
+ else:
+ list.Insert(item = "%s" % (_("Slice parallel to"), axis),
+ pos = sel+1) # append
+ item = sel + 1
- data['isosurface'].insert(item, isosurfData)
+ list.Check(item)
+ list.SetSelection(item)
- # add isosurface
- self._display.AddIsosurface(id, level)
- # use by default 3d raster map for color
- self._display.SetIsosurfaceColor(id, item, True, str(layer.name))
+ if mode == 'isosurf':
+ data['isosurface'].insert(item, isosurfData)
+ # add isosurface
+ self._display.AddIsosurface(id, float(level))
+ else:
+ data['slice'].insert(item, sliceData)
+ # add isosurface
+ nslice = self._display.AddSlice(id)
+ self._display.SetSlicePosition(id, nslice -1, sliceData['position']['x1'], sliceData['position']['x2'],
+ sliceData['position']['y1'], sliceData['position']['y2'],
+ sliceData['position']['z1'], sliceData['position']['z2'],
+ sliceData['position']['axis'])
+ # update properties
+ event = wxUpdateProperties(data = data)
+ wx.PostEvent(self.mapWindow, event)
# update buttons
self.UpdateIsosurfButtons(list)
+ if mode == 'isosurf':
+ self.UpdateVolumeIsosurfPage(isosurfData)
+ else:
+ self.UpdateVolumeSlicePage(sliceData)
- if self.mapDisplay.statusbarWin['render'].IsChecked():
+ if self.mapDisplay.IsAutoRendered():
self.mapWindow.Refresh(False)
event.Skip()
- def OnVolumeIsosurfDelete(self, event):
- """!Remove isosurface from list"""
- list = self.FindWindowById(self.win['volume']['isosurfs'])
+ def OnVolumeDelete(self, event):
+ """!Remove isosurface/slice from list"""
+ if self.FindWindowById(self.win['volume']['draw']['mode']).GetSelection() == 0:
+ mode = 'isosurf'
+ else:
+ mode = 'slice'
+ list = self.FindWindowById(self.win['volume'][mode + 's'])
# remove item from list
- isosurfId = list.GetSelection()
- list.Delete(isosurfId)
+ id = list.GetSelection()
+ list.Delete(id)
# select last item
if list.GetCount() > 0:
list.SetSelection(list.GetCount()-1)
@@ -2381,24 +3903,41 @@
layer = self.mapWindow.GetLayerByName(name, mapType = '3d-raster')
data = self.GetLayerData('volume')['volume']
- id = data['object']['id']
+ vid = data['object']['id']
# delete isosurface
- del data['isosurface'][isosurfId]
+ if mode == 'isosurf':
+ del data['isosurface'][id]
+ self._display.DeleteIsosurface(vid, id)
+ else:
+ del data['slice'][id]
+ self._display.DeleteSlice(vid, id)
- self._display.DeleteIsosurface(id, isosurfId)
-
# update buttons
+ if list.GetCount() > 0:
+ if mode == 'isosurf':
+ self.UpdateVolumeIsosurfPage(data['isosurface'][list.GetSelection()])
+ else:
+ self.UpdateVolumeSlicePage(data['slice'][list.GetSelection()])
+ else:
+ if mode == 'isosurf':
+ self.UpdateVolumeIsosurfPage(data['attribute'])
+ else:
+ self.UpdateVolumeSlicePage(None)
self.UpdateIsosurfButtons(list)
- if self.mapDisplay.statusbarWin['render'].IsChecked():
+ if self.mapDisplay.IsAutoRendered():
self.mapWindow.Refresh(False)
event.Skip()
- def OnVolumeIsosurfMoveUp(self, event):
- """!Move isosurface up in the list"""
- list = self.FindWindowById(self.win['volume']['isosurfs'])
+ def OnVolumeMoveUp(self, event):
+ """!Move isosurface/slice up in the list"""
+ if self.FindWindowById(self.win['volume']['draw']['mode']).GetSelection() == 0:
+ mode = 'isosurf'
+ else:
+ mode = 'slice'
+ list = self.FindWindowById(self.win['volume'][mode + 's'])
sel = list.GetSelection()
if sel < 1:
@@ -2416,21 +3955,30 @@
list.Check(sel-1)
list.SetSelection(sel-1)
list.Delete(sel+1)
- data['isosurface'].insert(sel-1, data['isosurface'][sel])
- del data['isosurface'][sel+1]
- self._display.MoveIsosurface(id, sel, True)
+ if mode == 'isosurf':
+ data['isosurface'].insert(sel-1, data['isosurface'][sel])
+ del data['isosurface'][sel+1]
+ self._display.MoveIsosurface(id, sel, True)
+ else:
+ data['slice'].insert(sel-1, data['slice'][sel])
+ del data['slice'][sel+1]
+ self._display.MoveSlice(id, sel, True)
# update buttons
self.UpdateIsosurfButtons(list)
- if self.mapDisplay.statusbarWin['render'].IsChecked():
+ if self.mapDisplay.IsAutoRendered():
self.mapWindow.Refresh(False)
event.Skip()
- def OnVolumeIsosurfMoveDown(self, event):
- """!Move isosurface dowm in the list"""
- list = self.FindWindowById(self.win['volume']['isosurfs'])
+ def OnVolumeMoveDown(self, event):
+ """!Move isosurface/slice down in the list"""
+ if self.FindWindowById(self.win['volume']['draw']['mode']).GetSelection() == 0:
+ mode = 'isosurf'
+ else:
+ mode = 'slice'
+ list = self.FindWindowById(self.win['volume'][mode + 's'])
sel = list.GetSelection()
if sel >= list.GetCount() - 1:
@@ -2448,18 +3996,365 @@
list.Check(sel+2)
list.SetSelection(sel+2)
list.Delete(sel)
- data['isosurface'].insert(sel+2, data['isosurface'][sel])
- del data['isosurface'][sel]
- self._display.MoveIsosurface(id, sel, False)
+ if mode == 'isosurf':
+ data['isosurface'].insert(sel+2, data['isosurface'][sel])
+ del data['isosurface'][sel]
+ self._display.MoveIsosurface(id, sel, False)
+ else:
+ data['slice'].insert(sel+2, data['slice'][sel])
+ del data['slice'][sel]
+ self._display.MoveSlice(id, sel, False)
# update buttons
self.UpdateIsosurfButtons(list)
- if self.mapDisplay.statusbarWin['render'].IsChecked():
+ if self.mapDisplay.IsAutoRendered():
self.mapWindow.Refresh(False)
event.Skip()
+
+ def OnVolumePositionChanged(self, event):
+ """!Volume position changed"""
+ self.mapWindow.render['quick'] = False
+ self.mapWindow.Refresh(False)
+ def OnVolumePosition(self, event):
+ """!Volume position"""
+ winName = self.__GetWindowName(self.win['volume'], event.GetId())
+ if not winName:
+ return
+ axis = self.FindWindowById(self.win['volume']['position']['axis']).GetSelection()
+
+ value = self.FindWindowById(event.GetId()).GetValue()
+ slider = self.FindWindowById(self.win['volume'][winName]['slider'])
+ self.AdjustSliderRange(slider = slider, value = value)
+
+ for win in self.win['volume']['position'].itervalues():
+ if win in (self.win['volume']['position']['axis'],
+ self.win['volume']['position']['reset']):
+ continue
+ else:
+ self.FindWindowById(win).SetValue(value)
+
+ data = self.GetLayerData('volume')
+ id = data['volume']['object']['id']
+ x, y, z = self._display.GetVolumePosition(id)
+
+ if axis == 0: # x
+ x = value
+ elif axis == 1: # y
+ y = value
+ else: # z
+ z = value
+
+ data['volume']['position']['x'] = x
+ data['volume']['position']['y'] = y
+ data['volume']['position']['z'] = z
+ data['volume']['position']['update'] = None
+ # update properties
+
+ event = wxUpdateProperties(data = data)
+ wx.PostEvent(self.mapWindow, event)
+
+ self.mapWindow.render['quick'] = True
+ if self.mapDisplay.IsAutoRendered():
+ self.mapWindow.Refresh(False)
+
+ def OnVolumeAxis(self, event):
+ """!Volume position, axis changed"""
+ data = self.GetLayerData('volume')
+ id = data['volume']['object']['id']
+
+ axis = self.FindWindowById(self.win['volume']['position']['axis']).GetSelection()
+ slider = self.FindWindowById(self.win['volume']['position']['slider'])
+ text = self.FindWindowById(self.win['volume']['position']['text'])
+ xydim = self._display.GetLongDim()
+ zdim = self._display.GetZRange()
+ zdim = zdim[1] - zdim[0]
+ x, y, z = self._display.GetVolumePosition(id)
+
+ if axis == 0: # x
+ slider.SetRange(-3 * xydim, 3 * xydim)
+ slider.SetValue(x)
+ text.SetValue(x)
+ elif axis == 1: # y
+ slider.SetRange(-3 * xydim, 3 * xydim)
+ slider.SetValue(y)
+ text.SetValue(y)
+ else: # z
+ slider.SetRange(-3 * zdim, 3 * zdim)
+ slider.SetValue(z)
+ text.SetValue(z)
+
+ def OnVolumePositionText(self, event):
+ """!Volume position changed by textctrl"""
+ self.OnVolumePosition(event)
+ self.OnVolumePositionChanged(None)
+
+ def OnResetVolumePosition(self, event):
+ """!Reset position of volume"""
+ for win in self.win['volume']['position'].itervalues():
+ if win == self.win['volume']['position']['axis']:
+ self.FindWindowById(win).SetSelection(0)
+ elif win == self.win['volume']['position']['reset']:
+ continue
+ else:
+ self.FindWindowById(win).SetValue(0)
+
+ data = self.GetLayerData('volume')
+ data['volume']['position']['x'] = 0
+ data['volume']['position']['y'] = 0
+ data['volume']['position']['z'] = 0
+ data['volume']['position']['update'] = None
+ # update properties
+ event = wxUpdateProperties(data = data)
+ wx.PostEvent(self.mapWindow, event)
+
+ if self.mapDisplay.IsAutoRendered():
+ self.mapWindow.Refresh(False)
+
+ def OnVolumeSliceAxes(self, event):
+ """!Slice axis changed"""
+ self.UpdateSliceLabels()
+ data = self.GetLayerData('volume')
+ list = self.FindWindowById(self.win['volume']['slices'])
+ sel = list.GetSelection()
+ if sel < 0:
+ return
+ axis = self.FindWindowById(self.win['volume']['slice']['axes']).GetSelection()
+ data['volume']['slice'][sel]['position']['axis'] = axis
+ data['volume']['slice'][sel]['position']['update'] = None
+
+ axis = ("X", "Y", "Z")[axis]
+ list.SetString(sel, "%s %s" % (_("Slice parallel to"), axis))
+ list.Check(sel)
+
+ # update properties
+ event = wxUpdateProperties(data = data)
+ wx.PostEvent(self.mapWindow, event)
+
+ if self.mapDisplay.IsAutoRendered():
+ self.mapWindow.Refresh(False)
+
+ def OnSliceTransparency(self, event):
+ """!Slice transparency changed"""
+ data = self.GetLayerData('volume')
+
+ list = self.FindWindowById(self.win['volume']['slices'])
+ sel = list.GetSelection()
+ if sel < 0:
+ return
+
+ val = self.FindWindowById(self.win['volume']['slice']['transp']).GetValue()
+ data['volume']['slice'][sel]['transp']['value'] = self._getPercent(val, toPercent = False)
+ data['volume']['slice'][sel]['transp']['update'] = None
+
+ # update properties
+ event = wxUpdateProperties(data = data)
+ wx.PostEvent(self.mapWindow, event)
+
+ if self.mapDisplay.IsAutoRendered():
+ self.mapWindow.Refresh(False)
+
+ def OnSliceReset(self, event):
+ """!Slice position reset"""
+ data = self.GetLayerData('volume')
+
+ list = self.FindWindowById(self.win['volume']['slices'])
+ sel = list.GetSelection()
+ if sel < 0:
+ return
+
+ for coord, val in zip(('x1', 'x2', 'y1', 'y2', 'z1', 'z2'),(0, 1, 0, 1, 0, 1, 0)):
+ data['volume']['slice'][sel]['position'][coord] = val
+ data['volume']['slice'][sel]['position']['update'] = None
+
+ self.UpdateVolumeSlicePage(data['volume']['slice'][sel])
+ # update properties
+ event = wxUpdateProperties(data = data)
+ wx.PostEvent(self.mapWindow, event)
+
+ if self.mapDisplay.IsAutoRendered():
+ self.mapWindow.Refresh(False)
+
+ def OnSlicePositionChange(self, event):
+ """!Slice position is changing"""
+ data = self.GetLayerData('volume')
+ list = self.FindWindowById(self.win['volume']['slices'])
+ sel = list.GetSelection()
+ if sel < 0:
+ return
+ win = self.win['volume']['slice']
+ winId = event.GetId()
+ value = event.GetInt()/100.
+
+ for coord in ('x1', 'x2', 'y1', 'y2', 'z1', 'z2'):
+ if win['slider_' + coord] == winId:
+ data['volume']['slice'][sel]['position'][coord] = value
+ data['volume']['slice'][sel]['position']['update'] = None
+ break
+ self.mapWindow.render['quick'] = True
+ # update properties
+ event = wxUpdateProperties(data = data)
+ wx.PostEvent(self.mapWindow, event)
+
+ if self.mapDisplay.IsAutoRendered():
+ self.mapWindow.Refresh(False)
+
+ def OnSlicePositionChanged(self, event):
+ """!Slice position is changed"""
+ self.mapWindow.render['quick'] = False
+ if self.mapDisplay.IsAutoRendered():
+ self.mapWindow.Refresh(False)
+
+ def OnCPlaneSelection(self, event):
+ """!Cutting plane selected"""
+ plane = self.FindWindowById(self.win['cplane']['planes']).GetStringSelection()
+ try:
+ planeIndex = int(plane.split()[-1]) - 1
+ self.EnablePage("cplane", enabled = True)
+ except:
+ planeIndex = -1
+ self.EnablePage("cplane", enabled = False)
+ self.mapWindow.SelectCPlane(planeIndex)
+ if self.mapDisplay.IsAutoRendered():
+ self.mapWindow.Refresh(False)
+ self.UpdateCPlanePage(planeIndex)
+
+ def OnCPlaneChanging(self, event):
+ """!Cutting plane is changing"""
+ plane = self.FindWindowById(self.win['cplane']['planes']).GetStringSelection()
+ try:
+ planeIndex = int(plane.split()[-1]) - 1
+ except:#TODO disabled page
+ planeIndex = -1
+
+ if event.GetId() in (self.win['cplane']['rotation']['rot'].values() +
+ self.win['cplane']['rotation']['tilt'].values()):
+ action = 'rotation'
+ else:
+ action = 'position'
+ data = self.mapWindow.cplanes[planeIndex][action]
+ self.OnScroll(event, self.win['cplane'][action], data)
+
+ self.mapWindow.render['quick'] = True
+ event = wxUpdateCPlane(update = (action,), current = planeIndex)
+ wx.PostEvent(self.mapWindow, event)
+
+ if self.mapDisplay.IsAutoRendered():
+ self.mapWindow.Refresh(False)
+
+ def OnCPlaneChangeDone(self, event):
+ """!Cutting plane change done"""
+ self.mapWindow.render['quick'] = False
+ if self.mapDisplay.IsAutoRendered():
+ self.mapWindow.Refresh(False)
+
+ def OnCPlaneChangeText(self, event):
+ """!Cutting plane changed by textctrl"""
+ for axis in ('x', 'y', 'z'):
+ if event.GetId() == self.win['cplane']['position'][axis]['text']:
+ value = self.FindWindowById(event.GetId()).GetValue()
+ slider = self.FindWindowById(self.win['cplane']['position'][axis]['slider'])
+ self.AdjustSliderRange(slider = slider, value = value)
+ self.OnCPlaneChanging(event = event)
+ self.OnCPlaneChangeDone(None)
+
+ def OnCPlaneShading(self, event):
+ """!Cutting plane shading changed"""
+ shading = self.FindWindowById(self.win['cplane']['shading']).GetSelection()
+ plane = self.FindWindowById(self.win['cplane']['planes']).GetStringSelection()
+ try:
+ planeIndex = int(plane.split()[-1]) - 1
+ except:#TODO disabled page
+ planeIndex = -1
+
+ self.mapWindow.cplanes[planeIndex]['shading'] = shading
+
+ event = wxUpdateCPlane(update = ('shading',), current = planeIndex)
+ wx.PostEvent(self.mapWindow, event)
+
+ self.OnCPlaneChangeDone(None)
+
+ def OnCPlaneReset(self, event):
+ """!Reset current cutting plane"""
+ plane = self.FindWindowById(self.win['cplane']['planes']).GetStringSelection()
+ try:
+ planeIndex = int(plane.split()[-1]) - 1
+ except:#TODO disabled page
+ planeIndex = -1
+ self.mapWindow.cplanes[planeIndex] = copy.deepcopy(UserSettings.Get(group = 'nviz',
+ key = 'cplane'))
+ event = wxUpdateCPlane(update = ('position','rotation','shading'), current = planeIndex)
+ wx.PostEvent(self.mapWindow, event)
+ self.OnCPlaneChangeDone(None)
+ self.UpdateCPlanePage(planeIndex)
+
+ def OnDecorationPlacement(self, event):
+ """!Place an arrow/scalebar by clicking on display"""
+ if event.GetId() == self.win['decoration']['arrow']['place']:
+ type = 'arrow'
+ elif event.GetId() == self.win['decoration']['scalebar']['place']:
+ type = 'scalebar'
+ else: return
+
+ if event.GetInt():
+ self.mapDisplay.Raise()
+ self.mapWindow.mouse['use'] = type
+ self.mapWindow.SetCursor(self.mapWindow.cursors["cross"])
+ else:
+ self.mapWindow.mouse['use'] = 'default'
+ self.mapWindow.SetCursor(self.mapWindow.cursors["default"])
+
+ def OnArrowDelete(self, event):
+ """!Delete arrow"""
+ self._display.DeleteArrow()
+ self.mapWindow.decoration['arrow']['show'] = False
+ self.mapWindow.Refresh(False)
+
+ def OnScalebarDelete(self, event):
+ """!Delete scalebar"""
+ try:
+ id = self.mapWindow.decoration['scalebar'][-1]['id']
+ except IndexError:
+ return
+ self._display.DeleteScalebar(id = id)
+ del self.mapWindow.decoration['scalebar'][-1]
+
+ self.mapWindow.Refresh(False)
+
+ def OnDecorationProp(self, event):
+ """!Set arrow/scalebar properties"""
+ if event.GetId() in self.win['decoration']['arrow'].values():
+ type = 'arrow'
+ elif event.GetId() in self.win['decoration']['scalebar'].values():
+ type = 'scalebar'
+ else: return
+
+ color = self.FindWindowById(self.win['decoration'][type]['color']).GetValue()
+ size = self.FindWindowById(self.win['decoration'][type]['size']).GetValue()
+ if type == 'arrow':
+ self.mapWindow.decoration[type]['color'] = self._getColorString(color)
+ self.mapWindow.decoration[type]['size'] = size
+ elif type == 'scalebar'and self.mapWindow.decoration['scalebar']:
+ self.mapWindow.decoration[type][-1]['color'] = self._getColorString(color)
+ self.mapWindow.decoration[type][-1]['size'] = size
+
+ if type == 'arrow' and self.mapWindow.decoration['arrow']['show']:
+ self._display.SetArrow(self.mapWindow.decoration['arrow']['position']['x'],
+ self.mapWindow.decoration['arrow']['position']['y'],
+ self.mapWindow.decoration['arrow']['size'],
+ self.mapWindow.decoration['arrow']['color'])
+ self._display.DrawArrow()
+ elif type == 'scalebar' and self.mapWindow.decoration['scalebar']:
+ self._display.SetScalebar(self.mapWindow.decoration['scalebar'][-1]['id'],
+ self.mapWindow.decoration['scalebar'][-1]['position']['x'],
+ self.mapWindow.decoration['scalebar'][-1]['position']['y'],
+ self.mapWindow.decoration['scalebar'][-1]['size'],
+ self.mapWindow.decoration['scalebar'][-1]['color'])
+ self._display.DrawScalebar()
+ self.mapWindow.Refresh(False)
+
def UpdatePage(self, pageId):
"""!Update dialog (selected page)"""
self.pageChanging = True
@@ -2474,17 +4369,26 @@
zmax = self.mapWindow.view['z-exag']['max']
zval = self.mapWindow.view['z-exag']['value']
- for control in ('spin', 'slider'):
- self.FindWindowById(self.win['view']['height'][control]).SetRange(hmin,
- hmax)
+ for control in ('slider','text'):
+ self.FindWindowById(self.win['view']['height'][control]).SetRange(
+ hmin,hmax)
+ self.FindWindowById(self.win['view']['z-exag'][control]).SetRange(
+ zmin, zmax)
self.FindWindowById(self.win['view']['height'][control]).SetValue(hval)
- self.FindWindowById(self.win['view']['z-exag'][control]).SetRange(zmin,
- zmax)
+
self.FindWindowById(self.win['view']['z-exag'][control]).SetValue(zval)
- self.FindWindowById(self.win['view']['bgcolor']).SetColour(\
+ self.FindWindowById(self.win['view']['background']['color']).SetColour(\
self.mapWindow.view['background']['color'])
+
+ tval = self.mapWindow.view['twist']['value']
+ pval = self.mapWindow.view['persp']['value']
+ for control in ('slider','text'):
+ self.FindWindowById(self.win['view']['twist'][control]).SetValue(tval)
+
+ self.FindWindowById(self.win['view']['persp'][control]).SetValue(pval)
+
elif pageId in ('surface', 'vector', 'volume'):
name = self.FindWindowById(self.win[pageId]['map']).GetValue()
data = self.GetLayerData(pageId)
@@ -2497,96 +4401,172 @@
self.UpdateVectorPage(layer, data['vector'])
elif pageId == 'volume':
layer = self.mapWindow.GetLayerByName(name, mapType = '3d-raster')
- self.UpdateVectorPage(layer, data['vector'])
+ self.UpdateVolumePage(layer, data['volume'])
elif pageId == 'light':
zval = self.mapWindow.light['position']['z']
bval = self.mapWindow.light['bright']
aval = self.mapWindow.light['ambient']
- for control in ('spin', 'slider'):
+ for control in ('slider','text'):
self.FindWindowById(self.win['light']['z'][control]).SetValue(zval)
self.FindWindowById(self.win['light']['bright'][control]).SetValue(bval)
self.FindWindowById(self.win['light']['ambient'][control]).SetValue(aval)
self.FindWindowById(self.win['light']['color']).SetColour(self.mapWindow.light['color'])
+ self.FindWindowById(self.win['light']['position']).PostDraw()
elif pageId == 'fringe':
win = self.FindWindowById(self.win['fringe']['map'])
win.SetValue(self.FindWindowById(self.win['surface']['map']).GetValue())
-
+ elif pageId == 'decoration':
+ win = self.FindWindowById(self.win['decoration']['arrow']['size'])
+ win.SetValue(self.mapWindow.decoration['arrow']['size'])
+ win = self.FindWindowById(self.win['decoration']['scalebar']['size'])
+ win.SetValue(self.mapWindow._getDecorationSize())
+ elif pageId == 'constant':
+ if self.mapWindow.constants:
+ surface = self.FindWindowById(self.win['constant']['surface'])
+ for item in self.mapWindow.constants:
+ surface.Append(_("constant#") + str(item['constant']['object']['name']))
+ surface.SetSelection(0)
+ self.OnConstantSelection(None)
+ self.EnablePage('constant', True)
+ elif pageId == 'cplane':
+ count = self._display.GetCPlanesCount()
+ choices = [_("None"),]
+ for plane in range(count):
+ choices.append("%s %i" % (_("Plane"), plane+1))
+ self.FindWindowById(self.win['cplane']['planes']).SetItems(choices)
+ current = 0
+ for i, cplane in enumerate(self.mapWindow.cplanes):
+ if cplane['on']:
+ current = i + 1
+ self.FindWindowById(self.win['cplane']['planes']).SetSelection(current)
+
+ xyRange, zRange = self._display.GetXYRange(), self._display.GetZRange()
+ if xyRange > 0: # GTK warning
+ self.FindWindowById(self.win['cplane']['position']['x']['slider']).SetRange(
+ -xyRange/2., xyRange/2.)
+ self.FindWindowById(self.win['cplane']['position']['y']['slider']).SetRange(
+ -xyRange/2., xyRange/2.)
+ if zRange[0] - zRange[1] > 0:
+ self.FindWindowById(self.win['cplane']['position']['z']['slider']).SetRange(zRange[0], zRange[1])
+ self.FindWindowById(self.win['cplane']['position']['z']['slider']).SetValue(zRange[0])
+ self.FindWindowById(self.win['cplane']['position']['z']['text']).SetValue(zRange[0])
+ self.OnCPlaneSelection(None)
+
+ elif pageId == 'animation':
+ self.UpdateAnimationPage()
+
self.Update()
self.pageChanging = False
+ def UpdateAnimationPage(self):
+ """!Update animation page"""
+ # wrap help text according to tool window
+ help = self.FindWindowById(self.win['anim']['help'])
+ width = help.GetGrandParent().GetSizeTuple()[0]
+ help.Wrap(width - 15)
+ anim = self.mapWindow.GetAnimation()
+ if anim.Exists():
+ self.FindWindowById(self.win['anim']['play']).Enable()
+ else:
+ self.UpdateFrameIndex(index = 0)
+
+ self.UpdateFrameCount()
+
+ self.FindWindowById(self.win['anim']['play']).Disable()
+ self.FindWindowById(self.win['anim']['record']).Enable()
+ self.FindWindowById(self.win['anim']['pause']).Disable()
+ self.FindWindowById(self.win['anim']['stop']).Disable()
+ self.FindWindowById(self.win['anim']['frameIndex']['slider']).Disable()
+ self.FindWindowById(self.win['anim']['frameIndex']['text']).Disable()
+
+ def UpdateCPlanePage(self, index):
+ """!Update widgets according to selected clip plane"""
+ if index == -1:
+ return
+ data = self.mapWindow.cplanes[index]
+ for widget in ('text', 'slider'):
+ for axes in ('x', 'y', 'z'):
+ self.FindWindowById(self.win['cplane']['position'][axes][widget]).SetValue(data['position'][axes])
+ for each in ('tilt', 'rot'):
+ self.FindWindowById(self.win['cplane']['rotation'][each][widget]).SetValue(data['rotation'][each])
+ self.FindWindowById(self.win['cplane']['shading']).SetSelection(data['shading'])
+
def UpdateSurfacePage(self, layer, data, updateName = True):
"""!Update surface page"""
- ret = gcmd.RunCommand('r.info',
- read = True,
- flags = 'm',
- map = layer.name)
- if ret:
- desc = ret.split('=')[1].rstrip('\n')
- else:
- desc = None
+ desc = grass.raster_info(layer.name)['title']
if updateName:
self.FindWindowById(self.win['surface']['map']).SetValue(layer.name)
self.FindWindowById(self.win['surface']['desc']).SetLabel(desc)
# attributes
- for attr in ('topo', 'color'): # required
- if layer and layer.type == 'raster':
- self.FindWindowById(self.win['surface'][attr]['map']).SetValue(layer.name)
- else:
- self.FindWindowById(self.win['surface'][attr]['map']).SetValue('')
- self.SetMapObjUseMap(nvizType = 'surface',
- attrb = attr, map = True) # -> map
-
+ if layer and layer.type == 'raster':
+ self.vetoGSelectEvt = True
+ self.FindWindowById(self.win['surface']['color']['map']).SetValue(layer.name)
+ else:
+ self.FindWindowById(self.win['surface']['color']['map']).SetValue('')
+
+ self.SetMapObjUseMap(nvizType = 'surface',
+ attrb = 'color', map = True) # -> map
+
if 'color' in data['attribute']:
value = data['attribute']['color']['value']
+
if data['attribute']['color']['map']:
self.FindWindowById(self.win['surface']['color']['map']).SetValue(value)
else: # constant
color = map(int, value.split(':'))
self.FindWindowById(self.win['surface']['color']['const']).SetColour(color)
self.SetMapObjUseMap(nvizType = 'surface',
- attrb = attr, map = data['attribute']['color']['map'])
-
+ attrb = 'color', map = data['attribute']['color']['map'])
+
self.SetMapObjUseMap(nvizType = 'surface',
attrb = 'shine', map = data['attribute']['shine']['map'])
value = data['attribute']['shine']['value']
if data['attribute']['shine']['map']:
self.FindWindowById(self.win['surface']['shine']['map']).SetValue(value)
else:
- self.FindWindowById(self.win['surface']['shine']['const']).SetValue(value)
-
+ self.FindWindowById(self.win['surface']['shine']['const']).SetValue(self._getPercent(value))
+ if 'transp' in data['attribute']:
+ value = data['attribute']['transp']['value']
+ if data['attribute']['transp']['map']:
+ self.FindWindowById(self.win['surface']['color']['map']).SetValue(value)
+ else:
+ self.FindWindowById(self.win['surface']['transp']['const']).SetValue(self._getPercent(value))
+ self.SetMapObjUseMap(nvizType = 'surface', attrb = 'transp', map = data['attribute']['transp']['map'])
+ else:
+ self.SetMapObjUseMap(nvizType = 'surface', attrb = 'transp', map = None)
#
# draw
#
- for control, data in data['draw'].iteritems():
+ for control, drawData in data['draw'].iteritems():
if control == 'all': # skip 'all' property
continue
if control == 'resolution':
- self.FindWindowById(self.win['surface']['draw']['res-coarse']).SetValue(data['coarse'])
- self.FindWindowById(self.win['surface']['draw']['res-fine']).SetValue(data['fine'])
+ self.FindWindowById(self.win['surface']['draw']['res-coarse']).SetValue(drawData['coarse'])
+ self.FindWindowById(self.win['surface']['draw']['res-fine']).SetValue(drawData['fine'])
continue
if control == 'mode':
- if data['desc']['mode'] == 'coarse':
+ if drawData['desc']['mode'] == 'coarse':
self.FindWindowById(self.win['surface']['draw']['mode']).SetSelection(0)
- elif data['desc']['mode'] == 'fine':
+ elif drawData['desc']['mode'] == 'fine':
self.FindWindowById(self.win['surface']['draw']['mode']).SetSelection(1)
else: # both
self.FindWindowById(self.win['surface']['draw']['mode']).SetSelection(2)
- if data['desc']['style'] == 'wire':
+ if drawData['desc']['style'] == 'wire':
self.FindWindowById(self.win['surface']['draw']['style']).SetSelection(0)
else: # surface
self.FindWindowById(self.win['surface']['draw']['style']).SetSelection(1)
- if data['desc']['shading'] == 'flat':
+ if drawData['desc']['shading'] == 'flat':
self.FindWindowById(self.win['surface']['draw']['shading']).SetSelection(0)
else: # gouraud
self.FindWindowById(self.win['surface']['draw']['shading']).SetSelection(1)
continue
- value = data['value']
+ value = drawData['value']
win = self.FindWindowById(self.win['surface']['draw'][control])
name = win.GetName()
@@ -2598,6 +4578,16 @@
win.SetColour(color)
else:
win.SetValue(value)
+ #
+ # position
+ #
+ dim = self._display.GetLongDim()
+ self.FindWindowById(self.win['surface']['position']['slider']).SetRange(-2 * dim, 2 * dim)
+ if 'x' in data['position']:
+ xval = data['position']['x']
+ self.FindWindowById(self.win['surface']['position']['axis']).SetSelection(0)
+ for control in ('slider','text'):
+ self.FindWindowById(self.win['surface']['position'][control]).SetValue(xval)
# enable/disable res widget + set draw mode
self.OnSurfaceMode(event = None)
@@ -2646,7 +4636,7 @@
for v in ('lines', 'points'):
self.FindWindowById(self.win['vector'][v]['surface']).Enable(enable)
self.FindWindowById(self.win['vector'][v]['height']['slider']).Enable(enable)
- self.FindWindowById(self.win['vector'][v]['height']['spin']).Enable(enable)
+ self.FindWindowById(self.win['vector'][v]['height']['text']).Enable(enable)
#
# lines
@@ -2677,18 +4667,20 @@
display.SetSelection(1)
else:
display.SetSelection(0)
-
if data[vtype]['mode']['type'] == 'surface':
rasters = self.mapWindow.GetLayerNames('raster')
- surface = self.FindWindowById(self.win['vector'][vtype]['surface'])
- surface.SetItems(rasters)
- if len(rasters) > 0:
- try:
- surface.SetStringSelection(data[vtype]['mode']['surface'])
- except:
- pass
-
- for type in ('slider', 'spin'):
+ constants = self.mapWindow.GetLayerNames('constant')
+ surfaces = rasters + constants
+ surfaceWin = self.FindWindowById(self.win['vector'][vtype]['surface'])
+ surfaceWin.SetItems(surfaces)
+ for idx, surface in enumerate(surfaces):
+ try:# TODO fix this mess
+ selected = data[vtype]['mode']['surface']['show'][idx]
+ except (TypeError, IndexError, KeyError):
+ selected = False
+ surfaceWin.Check(idx, selected)
+
+ for type in ('slider', 'text'):
win = self.FindWindowById(self.win['vector']['lines']['height'][type])
win.SetValue(data['lines']['height']['value'])
@@ -2719,8 +4711,9 @@
win.SetValue(color)
else:
win.SetValue(data['points'][prop]['value'])
+
# height
- for type in ('slider', 'spin'):
+ for type in ('slider', 'text'):
win = self.FindWindowById(self.win['vector']['points']['height'][type])
win.SetValue(data['points']['height']['value'])
@@ -2728,56 +4721,86 @@
"""!Update volume page"""
if updateName:
self.FindWindowById(self.win['volume']['map']).SetValue(layer.name)
- list = self.FindWindowById(self.win['volume']['isosurfs'])
# draw
for control, idata in data['draw'].iteritems():
if control == 'all': # skip 'all' property
continue
-
+
win = self.FindWindowById(self.win['volume']['draw'][control])
-
+ if control == 'mode':
+ value = data['draw']['mode']['value']
if control == 'shading':
- if data['draw']['shading']['desc'] == 'flat':
+ if data['draw']['shading'][data['draw']['mode']['desc']]['desc'] == 'flat':
value = 0
else:
value = 1
- else:
- value = idata['value']
+ if control == 'resolution':
+ value = idata[data['draw']['mode']['desc']]['value']
if win.GetName() == "selection":
win.SetSelection(value)
else:
win.SetValue(value)
+
+ self.OnVolumeMode(None)
+ id = data['object']['id']
+ if data['draw']['mode']['desc'] == 'isosurface':
+ self._display.SetIsosurfaceMode(id, data['draw']['shading']['isosurface']['value'])
+ self._display.SetIsosurfaceRes(id, data['draw']['resolution']['isosurface']['value'])
+ else:
+ self._display.SetSliceMode(id, data['draw']['shading']['slice']['value'])
+ self._display.SetSliceRes(id, data['draw']['resolution']['slice']['value'])
+ box = self.FindWindowById(self.win['volume']['isosurfs'])
- self.SetIsosurfaceMode(data['draw']['shading']['value'])
- self.SetIsosurfaceResolution(data['draw']['resolution']['value'])
+ if data['draw']['mode']['desc'] == 'isosurface':
+ isosurfaces = []
+ for iso in data['isosurface']:
+ level = iso['topo']['value']
+ isosurfaces.append("%s %s" % (_("Level"), level))
+ box.Set(isosurfaces)
+ box.SetChecked(range(len(isosurfaces)))
+ if data['isosurface']:
+ box.SetSelection(0)
+ self.UpdateVolumeIsosurfPage(data['isosurface'][0])
+ else:
+ self.UpdateVolumeIsosurfPage(data['attribute'])
+ else:
+ slices = []
+ for slice in data['slice']:
+ axis = ("X", "Y", "Z")[slice['position']['axis']]
+ slices.append("%s %s" % (_("Slice parallel to"), axis))
+ box.Set(slices)
+ box.SetChecked(range(len(slices)))
+ if data['slice']:
+ box.SetSelection(0)
+ self.UpdateVolumeSlicePage(data['slice'][0])
+ else:
+ self.UpdateVolumeSlicePage(None)
+ #
+ # position
+ #
+ if 'x' in data['position']:
+ xval = data['position']['x']
+ self.FindWindowById(self.win['volume']['position']['axis']).SetSelection(0)
+ for control in ('slider','text'):
+ self.FindWindowById(self.win['volume']['position'][control]).SetValue(xval)
+ # set topo range
+ mapRange = self._get3dRange(name = layer.name)
+ desc = self.FindWindowById(self.win['volume']['desc'])
+ desc.SetLabel("%s %.2f - %.2f" % (_("range:"), mapRange[0], mapRange[1]))
- self.UpdateVolumeIsosurfPage(layer, data['attribute'])
-
- def UpdateVolumeIsosurfPage(self, layer, data):
+ def UpdateVolumeIsosurfPage(self, data):
"""!Update dialog -- isosurface attributes"""
#
# isosurface attributes
#
for attrb in ('topo', 'color', 'mask',
- 'transp', 'shine', 'emit'):
- # check required first
- if attrb == 'topo':
- self.FindWindowById(self.win['volume'][attrb]['const']).SetValue(0)
- continue
- if attrb == 'color':
- if layer and layer.type == '3d-raster':
- self.FindWindowById(self.win['volume'][attrb]['map']).SetValue(layer.name)
- else:
- self.FindWindowById(self.win['volume'][attrb]['map']).SetValue('')
- self.SetMapObjUseMap(nvizType = 'volume',
- attrb = attrb, map = True) # -> map
- continue
-
+ 'transp', 'shine'):
# skip empty attributes
if attrb not in data:
- continue
+ self.SetMapObjUseMap(nvizType = 'volume', attrb = attrb, map = None)
+ continue
value = data[attrb]['value']
if attrb == 'color':
@@ -2788,14 +4811,78 @@
self.FindWindowById(self.win['volume'][attrb]['const']).SetColour(color)
else:
if data[attrb]['map']:
+ self.vetoGSelectEvt = True
win = self.FindWindowById(self.win['volume'][attrb]['map'])
+ win.SetValue(value)
else:
- win = self.FindWindowById(self.win['volume'][attrb]['const'])
- win.SetValue(value)
-
+ if value:
+ win = self.FindWindowById(self.win['volume'][attrb]['const'])
+ if attrb == 'topo':
+ win.SetValue(float(value))
+ else:
+ win.SetValue(self._getPercent(value))
+
self.SetMapObjUseMap(nvizType = 'volume',
attrb = attrb, map = data[attrb]['map'])
+ # set inout
+ if 'inout' in data:
+ self.FindWindowById(self.win['volume']['inout']).SetValue(data['inout'])
+
+ def UpdateVolumeSlicePage(self, data):
+ """!Update dialog -- slice attributes"""
+ if data:
+ for coord in ('x1', 'x2', 'y1', 'y2', 'z1', 'z2'):
+ win = self.FindWindowById(self.win['volume']['slice']['slider_' + coord])
+ win.Enable()
+ win.SetValue(data['position'][coord] * 100)
+ win = self.FindWindowById(self.win['volume']['slice']['axes'])
+ win.SetSelection(data['position']['axis'])
+ win.Enable()
+
+ win = self.FindWindowById(self.win['volume']['slice']['transp'])
+ win.SetValue(self._getPercent(data['transp']['value']))
+ win.Enable()
+ self.FindWindowById(self.win['volume']['slice']['reset']).Enable()
+ else:
+ for coord in ('x1', 'x2', 'y1', 'y2', 'z1', 'z2'):
+ self.FindWindowById(self.win['volume']['slice']['slider_' + coord]).Disable()
+ self.FindWindowById(self.win['volume']['slice']['axes']).Disable()
+ self.FindWindowById(self.win['volume']['slice']['transp']).Disable()
+ self.FindWindowById(self.win['volume']['slice']['reset']).Disable()
+ self.UpdateSliceLabels()
+
+ def UpdateSliceLabels(self):
+ """!Update text labels of slice controls according to axis"""
+ sel = self.FindWindowById(self.win['volume']['slice']['axes']).GetSelection()
+ if sel == 0:
+ self.FindWindowByName('label_edge_0').SetLabel(_("North edge:"))
+ self.FindWindowByName('label_edge_1').SetLabel(_("South edge:"))
+ self.FindWindowByName('label_edge_2').SetLabel(_("West edge:"))
+ self.FindWindowByName('label_edge_3').SetLabel(_("East edge:"))
+
+ self.FindWindowByName('label_coord_0').SetLabel(_("Northing (Y):"))
+ self.FindWindowByName('label_coord_1').SetLabel(_("Height (Z):"))
+ self.FindWindowByName('label_coord_2').SetLabel(_("Easting (X):"))
+ elif sel == 1:
+ self.FindWindowByName('label_edge_0').SetLabel(_("West edge:"))
+ self.FindWindowByName('label_edge_1').SetLabel(_("East edge:"))
+ self.FindWindowByName('label_edge_2').SetLabel(_("North edge:"))
+ self.FindWindowByName('label_edge_3').SetLabel(_("South edge:"))
+
+ self.FindWindowByName('label_coord_0').SetLabel(_("Easting (X):"))
+ self.FindWindowByName('label_coord_1').SetLabel(_("Height (Z):"))
+ self.FindWindowByName('label_coord_2').SetLabel(_("Northing (Y):"))
+ else:
+ self.FindWindowByName('label_edge_0').SetLabel(_("West edge:"))
+ self.FindWindowByName('label_edge_1').SetLabel(_("East edge:"))
+ self.FindWindowByName('label_edge_2').SetLabel(_("Bottom edge:"))
+ self.FindWindowByName('label_edge_3').SetLabel(_("Top edge:"))
+
+ self.FindWindowByName('label_coord_0').SetLabel(_("Easting (X):"))
+ self.FindWindowByName('label_coord_1').SetLabel(_("Northing (Y):"))
+ self.FindWindowByName('label_coord_2').SetLabel(_("Height (Z):"))
+
def SetPage(self, name):
"""!Get named page"""
if name == 'view':
@@ -2804,9 +4891,13 @@
self.SetSelection(1)
else:
self.SetSelection(2)
+
win = self.FindWindowById(self.page[name]['notebook'])
-
- win.SetSelection(self.page[name]['id'])
+ try:
+ win.Expand(win.GetFoldPanel(self.page[name]['id']))
+ self.UpdateScrolling((win.GetFoldPanel(self.page[name]['id']).GetGrandParent(),))
+ except AttributeError:
+ win.SetSelection(self.page[name]['id'])
class PositionWindow(wx.Window):
"""!Abstract position control window, see subclasses
@@ -2860,10 +4951,11 @@
ycoord = 0.0
elif ycoord > 1.0:
ycoord = 1.0
-
- self.data['position']['x'] = xcoord
- self.data['position']['y'] = ycoord
+ x, y = self.TransformCoordinates(xcoord, ycoord)
+ self.data['position']['x'] = x
+ self.data['position']['y'] = y
+
return xcoord, ycoord
def OnMouse(self, event):
@@ -2881,7 +4973,8 @@
def PostDraw(self):
x, y = self.UpdatePos(self.data['position']['x'],
self.data['position']['y'])
- self.Draw(pos = (x, y), scale = True)
+
+ self.Draw(pos = (x,y), scale = True)
class ViewPositionWindow(PositionWindow):
"""!View position control widget"""
@@ -2899,8 +4992,12 @@
wx.PostEvent(self.mapWindow, event)
return x, y
-
+
+ def TransformCoordinates(self, x, y, toLight = True):
+ return x, y
+
def OnMouse(self, event):
+ self.mapWindow.iview['dir']['use'] = False # use focus instead of viewdir
PositionWindow.OnMouse(self, event)
if event.LeftIsDown():
self.mapWindow.render['quick'] = self.quick
@@ -2916,7 +5013,7 @@
def __init__(self, parent, mapwindow, id = wx.ID_ANY,
**kwargs):
PositionWindow.__init__(self, parent, mapwindow, id, **kwargs)
-
+
self.data = self.mapWindow.light
self.quick = False
self.PostDraw()
@@ -2924,522 +5021,30 @@
def UpdatePos(self, xcoord, ycoord):
x, y = PositionWindow.UpdatePos(self, xcoord, ycoord)
- event = wxUpdateLight()
+ event = wxUpdateLight(refresh = False)
wx.PostEvent(self.mapWindow, event)
+
+ return x, y
+ def TransformCoordinates(self, x, y, toLight = True):
+ if toLight:
+ x = 2 * x - 1
+ y = -2 * y + 1
+ else:
+ x = (x + 1)/2
+ y = (1 - y)/2
return x, y
-
+
+ def PostDraw(self):
+ event = wxUpdateLight(refresh = True)
+ wx.PostEvent(self.mapWindow, event)
+ x, y = self.data['position']['x'], self.data['position']['y']
+ x, y = self.TransformCoordinates(x, y, toLight = False)
+
+ self.Draw(pos = (x,y), scale = True)
+
def OnMouse(self, event):
PositionWindow.OnMouse(self, event)
if event.LeftUp():
self.mapWindow.render['quick'] = False
self.mapWindow.Refresh(eraseBackground = False)
-
-class NvizPreferencesDialog(PreferencesBaseDialog):
- """!Nviz preferences dialog"""
- def __init__(self, parent, title = _("3D view settings"),
- settings = UserSettings):
- PreferencesBaseDialog.__init__(self, parent = parent, title = title,
- settings = settings)
- self.toolWin = self.parent.GetLayerManager().nviz
- self.win = dict()
-
- # create notebook pages
- self._createViewPage(self.notebook)
- self._createVectorPage(self.notebook)
-
- self.SetMinSize(self.GetBestSize())
- self.SetSize(self.size)
-
- def _createViewPage(self, notebook):
- """!Create notebook page for general settings"""
- panel = wx.Panel(parent = notebook, id = wx.ID_ANY)
-
- notebook.AddPage(page = panel,
- text = " %s " % _("View"))
-
- pageSizer = wx.BoxSizer(wx.VERTICAL)
-
- self.win['general'] = {}
- self.win['view'] = {}
- box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
- label = " %s " % (_("View")))
- boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
- gridSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
-
- # perspective
- self.win['view']['persp'] = {}
- pvals = UserSettings.Get(group = 'nviz', key = 'view', subkey = 'persp')
- ipvals = UserSettings.Get(group = 'nviz', key = 'view', subkey = 'persp', internal = True)
- gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = _("Perspective:")),
- pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL)
- gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = _("(value)")),
- pos = (0, 1), flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
-
- pval = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
- initial = pvals['value'],
- min = ipvals['min'],
- max = ipvals['max'])
- self.win['view']['persp']['value'] = pval.GetId()
- gridSizer.Add(item = pval, pos = (0, 2),
- flag = wx.ALIGN_CENTER_VERTICAL)
-
- gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = _("(step)")),
- pos = (0, 3), flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
-
- pstep = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
- initial = pvals['step'],
- min = ipvals['min'],
- max = ipvals['max']-1)
- self.win['view']['persp']['step'] = pstep.GetId()
- gridSizer.Add(item = pstep, pos = (0, 4),
- flag = wx.ALIGN_CENTER_VERTICAL)
-
- # position
- self.win['view']['position'] = {}
- posvals = UserSettings.Get(group = 'nviz', key = 'view', subkey = 'position')
- gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = _("Position:")),
- pos = (1, 0), flag = wx.ALIGN_CENTER_VERTICAL)
- gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = _("(x)")),
- pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
-
- px = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
- initial = posvals['x'] * 100,
- min = 0,
- max = 100)
- self.win['view']['position']['x'] = px.GetId()
- gridSizer.Add(item = px, pos = (1, 2),
- flag = wx.ALIGN_CENTER_VERTICAL)
-
- gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = "(y)"),
- pos = (1, 3), flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
-
- py = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
- initial = posvals['y'] * 100,
- min = 0,
- max = 100)
- self.win['view']['position']['y'] = py.GetId()
- gridSizer.Add(item = py, pos = (1, 4),
- flag = wx.ALIGN_CENTER_VERTICAL)
-
- # height
- self.win['view']['height'] = {}
- hvals = UserSettings.Get(group = 'nviz', key = 'view', subkey = 'height')
- gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = _("Height:")),
- pos = (2, 0), flag = wx.ALIGN_CENTER_VERTICAL)
- gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = _("(step)")),
- pos = (2, 1), flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
-
- hstep = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
- initial = hvals['step'],
- min = 1,
- max = 1e6)
- self.win['view']['height']['step'] = hstep.GetId()
- gridSizer.Add(item = hstep, pos = (2, 2),
- flag = wx.ALIGN_CENTER_VERTICAL)
-
- # twist
- self.win['view']['twist'] = {}
- tvals = UserSettings.Get(group = 'nviz', key = 'view', subkey = 'twist')
- itvals = UserSettings.Get(group = 'nviz', key = 'view', subkey = 'twist', internal = True)
- gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = _("Twist:")),
- pos = (3, 0), flag = wx.ALIGN_CENTER_VERTICAL)
- gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = _("(value)")),
- pos = (3, 1), flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
-
- tval = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
- initial = tvals['value'],
- min = itvals['min'],
- max = itvals['max'])
- self.win['view']['twist']['value'] = tval.GetId()
- gridSizer.Add(item = tval, pos = (3, 2),
- flag = wx.ALIGN_CENTER_VERTICAL)
-
- gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = _("(step)")),
- pos = (3, 3), flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
-
- tstep = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
- initial = tvals['step'],
- min = itvals['min'],
- max = itvals['max']-1)
- self.win['view']['twist']['step'] = tstep.GetId()
- gridSizer.Add(item = tstep, pos = (3, 4),
- flag = wx.ALIGN_CENTER_VERTICAL)
-
- # z-exag
- self.win['view']['z-exag'] = {}
- zvals = UserSettings.Get(group = 'nviz', key = 'view', subkey = 'z-exag')
- gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = _("Z-exag:")),
- pos = (4, 0), flag = wx.ALIGN_CENTER_VERTICAL)
- gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = _("(value)")),
- pos = (4, 1), flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
-
- zval = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
- initial = zvals['value'],
- min = -1e6,
- max = 1e6)
- self.win['view']['z-exag']['value'] = zval.GetId()
- gridSizer.Add(item = zval, pos = (4, 2),
- flag = wx.ALIGN_CENTER_VERTICAL)
-
- gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = _("(step)")),
- pos = (4, 3), flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
-
- zstep = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
- initial = zvals['step'],
- min = -1e6,
- max = 1e6)
- self.win['view']['z-exag']['step'] = zstep.GetId()
- gridSizer.Add(item = zstep, pos = (4, 4),
- flag = wx.ALIGN_CENTER_VERTICAL)
-
- boxSizer.Add(item = gridSizer, proportion = 1,
- flag = wx.ALL | wx.EXPAND, border = 3)
- pageSizer.Add(item = boxSizer, proportion = 0,
- flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
- border = 3)
-
- box = wx.StaticBox(parent = panel, id = wx.ID_ANY,
- label = " %s " % (_("Image Appearance")))
- boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
- gridSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
- gridSizer.AddGrowableCol(0)
-
- # background color
- gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = _("Background color:")),
- pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL)
-
- color = csel.ColourSelect(panel, id = wx.ID_ANY,
- colour = UserSettings.Get(group = 'nviz', key = 'settings',
- subkey = ['general', 'bgcolor']),
- size = globalvar.DIALOG_COLOR_SIZE)
- self.win['general']['bgcolor'] = color.GetId()
- gridSizer.Add(item = color, pos = (0, 1))
-
- boxSizer.Add(item = gridSizer, proportion = 1,
- flag = wx.ALL | wx.EXPAND, border = 3)
- pageSizer.Add(item = boxSizer, proportion = 0,
- flag = wx.EXPAND | wx.ALL,
- border = 3)
-
- panel.SetSizer(pageSizer)
-
- return panel
-
- def _createVectorPage(self, notebook):
- """!Create notebook page for general settings"""
- panel = wx.Panel(parent = notebook, id = wx.ID_ANY)
-
- notebook.AddPage(page = panel,
- text = " %s " % _("Vector"))
-
- pageSizer = wx.BoxSizer(wx.VERTICAL)
-
- # vector lines
- self.win['vector'] = {}
- self.win['vector']['lines'] = {}
- box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
- label = " %s " % (_("Vector lines")))
- boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
- gridSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
-
- # show
- row = 0
- showLines = wx.CheckBox(parent = panel, id = wx.ID_ANY,
- label = _("Show lines"))
- self.win['vector']['lines']['show'] = showLines.GetId()
- showLines.SetValue(UserSettings.Get(group = 'nviz', key = 'vector',
- subkey = ['lines', 'show']))
- gridSizer.Add(item = showLines, pos = (row, 0))
-
- boxSizer.Add(item = gridSizer, proportion = 1,
- flag = wx.ALL | wx.EXPAND, border = 3)
- pageSizer.Add(item = boxSizer, proportion = 0,
- flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
- border = 3)
-
- # vector points
- self.win['vector']['points'] = {}
- box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
- label = " %s " % (_("Vector points")))
- boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
- gridSizer = wx.GridBagSizer(vgap = 3, hgap = 5)
-
- # show
- row = 0
- showPoints = wx.CheckBox(parent = panel, id = wx.ID_ANY,
- label = _("Show points"))
- showPoints.SetValue(UserSettings.Get(group = 'nviz', key = 'vector',
- subkey = ['points', 'show']))
- self.win['vector']['points']['show'] = showPoints.GetId()
- gridSizer.Add(item = showPoints, pos = (row, 0), span = (1, 8))
-
- # icon size
- row += 1
- gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = _("Size:")),
- pos = (row, 0), flag = wx.ALIGN_CENTER_VERTICAL)
-
- isize = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
- initial = 100,
- min = 1,
- max = 1e6)
- self.win['vector']['points']['size'] = isize.GetId()
- isize.SetValue(UserSettings.Get(group = 'nviz', key = 'vector',
- subkey = ['points', 'size']))
- gridSizer.Add(item = isize, pos = (row, 1),
- flag = wx.ALIGN_CENTER_VERTICAL)
-
- # icon width
- gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = _("Width:")),
- pos = (row, 2), flag = wx.ALIGN_CENTER_VERTICAL)
-
- iwidth = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
- initial = 2,
- min = 1,
- max = 1e6)
- self.win['vector']['points']['width'] = isize.GetId()
- iwidth.SetValue(UserSettings.Get(group = 'nviz', key = 'vector',
- subkey = ['points', 'width']))
- gridSizer.Add(item = iwidth, pos = (row, 3),
- flag = wx.ALIGN_CENTER_VERTICAL)
-
- # icon symbol
- gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = _("Marker:")),
- pos = (row, 4), flag = wx.ALIGN_CENTER_VERTICAL)
- isym = wx.Choice (parent = panel, id = wx.ID_ANY, size = (100, -1),
- choices = UserSettings.Get(group = 'nviz', key = 'vector',
- subkey = ['points', 'marker'], internal = True))
- isym.SetName("selection")
- self.win['vector']['points']['marker'] = isym.GetId()
- isym.SetSelection(UserSettings.Get(group = 'nviz', key = 'vector',
- subkey = ['points', 'marker']))
- gridSizer.Add(item = isym, flag = wx.ALIGN_CENTER_VERTICAL,
- pos = (row, 5))
-
- # icon color
- gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
- label = _("Color:")),
- pos = (row, 6), flag = wx.ALIGN_CENTER_VERTICAL)
- icolor = csel.ColourSelect(panel, id = wx.ID_ANY)
- icolor.SetName("color")
- self.win['vector']['points']['color'] = icolor.GetId()
- icolor.SetColour(UserSettings.Get(group = 'nviz', key = 'vector',
- subkey = ['points', 'color']))
- gridSizer.Add(item = icolor, flag = wx.ALIGN_CENTER_VERTICAL,
- pos = (row, 7))
-
- boxSizer.Add(item = gridSizer, proportion = 1,
- flag = wx.ALL | wx.EXPAND, border = 3)
- pageSizer.Add(item = boxSizer, proportion = 0,
- flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
- border = 3)
-
- panel.SetSizer(pageSizer)
-
- return panel
-
- def OnDefault(self, event):
- """Restore default settings"""
- settings = copy.deepcopy(UserSettings.GetDefaultSettings()['nviz'])
- UserSettings.Set(group = 'nviz',
- value = settings)
-
- for subgroup, key in settings.iteritems(): # view, surface, vector...
- if subgroup != 'view':
- continue
- for subkey, value in key.iteritems():
- for subvalue in value.keys():
- win = self.FindWindowById(self.win[subgroup][subkey][subvalue])
- val = settings[subgroup][subkey][subvalue]
- if subkey == 'position':
- val = int(val * 100)
-
- win.SetValue(val)
-
- event.Skip()
-
- def OnApply(self, event):
- """Apply Nviz settings for current session"""
- settings = UserSettings.Get(group = 'nviz')
- for subgroup, key in settings.iteritems(): # view, surface, vector...
- for subkey, value in key.iteritems():
- for subvalue in value.keys():
- try: # TODO
- win = self.FindWindowById(self.win[subgroup][subkey][subvalue])
- except:
- # print 'e', subgroup, subkey, subvalue
- continue
-
- if win.GetName() == "selection":
- value = win.GetSelection()
- elif win.GetName() == "color":
- value = tuple(win.GetColour())
- else:
- value = win.GetValue()
- if subkey == 'position':
- value = float(value) / 100
-
- settings[subgroup][subkey][subvalue] = value
-
- def OnSave(self, event):
- """!Apply changes, update map and save settings of selected
- layer
- """
- # apply changes
- self.OnApply(None)
-
- if self.GetSelection() == self.page['id']:
- fileSettings = {}
- UserSettings.ReadSettingsFile(settings = fileSettings)
- fileSettings['nviz'] = UserSettings.Get(group = 'nviz')
- file = UserSettings.SaveToFile(fileSettings)
- self.parent.goutput.WriteLog(_('Nviz settings saved to file <%s>.') % file)
-
- def OnLoad(self, event):
- """!Apply button pressed"""
- self.LoadSettings()
-
- if event:
- event.Skip()
-
- def LoadSettings(self):
- """!Load saved Nviz settings and apply to current session"""
- UserSettings.ReadSettingsFile()
- settings = copy.deepcopy(UserSettings.Get(group = 'nviz'))
-
- for subgroup, key in settings.iteritems(): # view, surface, vector...
- for subkey, value in key.iteritems():
- for subvalue in value.keys():
- if subvalue == 'step':
- continue
- else:
- insetting = value[subvalue]
- if subgroup == 'view':
- for viewkey, viewitem in self.mapWindow.view[subkey].iteritems():
- if viewkey == subvalue:
- self.mapWindow.view[subkey][viewkey] = insetting
- else:
- continue
- else:
- for otherkey, otheritem in self.win[subgroup][subkey].iteritems():
- if type(otheritem) == data:
- for endkey, enditem in otheritem.iteritems():
- if endkey == subvalue:
- paramwin = self.FindWindowById(enditem)
- else:
- continue
- else:
- if otherkey == subvalue:
- paramwin = self.FindWindowById(otheritem)
- else:
- continue
- if type(insetting) in [tuple, list] and len(insetting) > 2:
- insetting = tuple(insetting)
- paramwin.SetColour(insetting)
- else:
- try:
- paramwin.SetValue(insetting)
- except:
- try:
- paramwin.SetStringSelection(insetting)
- except:
- continue
-
- self.toolWin.UpdateSettings()
- self.FindWindowById(self.win['view']['position']).Draw()
- self.FindWindowById(self.win['view']['position']).Refresh(False)
-
- self.mapWindow.render['quick'] = False
- self.mapWindow.Refresh(False)
-
- def OnSave(self, event):
- """!Save button pressed
-
- Save settings to configuration file
- """
- fileSettings = {}
- UserSettings.ReadSettingsFile(settings = fileSettings)
-
- self.toolWin.UpdateSettings()
-
- nvsettings = UserSettings.Get(group = 'nviz')
- for subgroup, key in nvsettings.iteritems(): # view, surface, vector...
- for subkey, value in key.iteritems():
- if subkey == 'height': continue
- for subvalue in value.keys():
- if subvalue == 'step':
- #no way to change steps for sliders or spinctrls on non-MSW systems
- nvsettings[subgroup][subkey][subvalue] = 1
- else:
- if subgroup == 'view':
- nvsettings[subgroup][subkey][subvalue] = self.mapWindow.view[subkey][subvalue]
- elif subvalue == 'map':
- if subkey == 'shine':
- nvsettings[subgroup][subkey][subvalue] = False
- if subkey == 'color':
- nvsettings[subgroup][subkey][subvalue] = True
- else:
- for otherkey, otheritem in self.win[subgroup][subkey].iteritems():
- if type(otheritem) == data:
- for endkey, enditem in otheritem.iteritems():
- if endkey == subvalue:
- if self.FindWindowById(enditem).GetClassName() == 'wxChoice':
- outsetting = self.FindWindowById(enditem).GetSelection()
- else:
- try:
- outsetting = self.FindWindowById(enditem).GetColour()
- outsetting = str(outsetting.Red())+':'+str(outsetting.Green())+':'+str(outsetting.Blue())
- except:
- try:
- outsetting = self.FindWindowById(enditem).GetValue()
- except:
- try:
- outsetting = self.FindWindowById(enditem).GetString()
- except:
- outsetting = ''
- if (type(outsetting) == list or type(outsetting) == tuple) and len(outsetting) > 2:
- outsetting = str(outsetting[0])+':'+str(outsetting[1])+':'+str(outsetting[2])
-
- nvsettings[subgroup][subkey][subvalue][endkey] = outsetting
- else:
- if otherkey == subvalue:
- if self.FindWindowById(otheritem).GetClassName() == 'wxChoice':
- outsetting = self.FindWindowById(otheritem).GetSelection()
- else:
- try:
- outsetting = self.FindWindowById(otheritem).GetColour()
- outsetting = str(outsetting.Red())+':'+str(outsetting.Green())+':'+str(outsetting.Blue())
- except:
- try:
- outsetting = self.FindWindowById(otheritem).GetValue()
- except:
- try:
- outsetting = self.FindWindowById(enditem).GetString()
- except:
- outsetting = ''
- if (type(outsetting) == list or type(outsetting) == tuple) and len(outsetting) > 2:
- outsetting = str(outsetting[0])+':'+str(outsetting[1])+':'+str(outsetting[2])
-
- nvsettings[subgroup][subkey][subvalue] = outsetting
-
- UserSettings.Set(group = 'nviz', value = nvsettings)
- file = UserSettings.SaveToFile()
- self.parent.goutput.WriteLog(_('Nviz settings saved to file <%s>.') % file)
Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/preferences.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/preferences.py 2011-11-25 14:58:21 UTC (rev 49356)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/preferences.py 2011-11-25 15:10:47 UTC (rev 49357)
@@ -470,26 +470,34 @@
'view' : {
'persp' : {
'value' : 20,
- 'step' : 5,
+ 'step' : 2,
},
'position' : {
'x' : 0.84,
'y' : 0.16,
},
- 'height' : {
- 'step' : 100,
- },
'twist' : {
'value' : 0,
- 'step' : 5,
},
'z-exag' : {
- 'step' : 1,
+ 'min' : 0,
+ 'max' : 10,
+ 'value': 1,
},
'background' : {
'color' : (255, 255, 255, 255), # white
},
},
+ 'fly' : {
+ 'exag' : {
+ 'move' : 5,
+ 'turn' : 5,
+ }
+ },
+ 'animation' : {
+ 'fps' : 24,
+ 'prefix' : _("animation")
+ },
'surface' : {
'shine': {
'map' : False,
@@ -497,7 +505,7 @@
},
'color' : {
'map' : True,
- 'value' : (0, 0, 0, 255), # constant: black
+ 'value' : (100, 100, 100, 255), # constant: grey
},
'draw' : {
'wire-color' : (136, 136, 136, 255),
@@ -513,6 +521,12 @@
'z' : 0,
},
},
+ 'constant' : {
+ 'color' : (100, 100, 100, 255),
+ 'value' : 0.0,
+ 'transp' : 0,
+ 'resolution': 6
+ },
'vector' : {
'lines' : {
'show' : False,
@@ -533,7 +547,7 @@
'volume' : {
'color' : {
'map' : True,
- 'value' : (0, 0, 0, 255), # constant: black
+ 'value' : (100, 100, 100, 255), # constant: grey
},
'draw' : {
'mode' : 0, # isosurfaces
@@ -544,11 +558,44 @@
'map' : False,
'value' : 60,
},
+ 'topo': {
+ 'map' : None,
+ 'value' : 0.0
+ },
+ 'transp': {
+ 'map' : None,
+ 'value': 0
+ },
+ 'mask': {
+ 'map' : None,
+ 'value': ''
+ },
+ 'slice_position': {
+ 'x1' : 0,
+ 'x2' : 1,
+ 'y1' : 0,
+ 'y2' : 1,
+ 'z1' : 0,
+ 'z2' : 1,
+ 'axis' : 0,
+ }
},
+ 'cplane' : {
+ 'shading': 4,
+ 'rotation':{
+ 'rot': 0,
+ 'tilt': 0
+ },
+ 'position':{
+ 'x' : 0,
+ 'y' : 0,
+ 'z' : 0
+ }
+ },
'light' : {
'position' : {
'x' : 0.68,
- 'y' : 0.68,
+ 'y' : -0.68,
'z' : 80,
},
'bright' : 80,
@@ -559,6 +606,12 @@
'elev' : 55,
'color' : (128, 128, 128, 255), # grey
},
+ 'arrow': {
+ 'color': (0, 0, 0),
+ },
+ 'scalebar': {
+ 'color': (0, 0, 0),
+ }
},
'modeler' : {
'disabled': {
@@ -668,6 +721,25 @@
self.internalSettings['nviz']['view']['persp']['max'] = 100
self.internalSettings['nviz']['view']['height'] = {}
self.internalSettings['nviz']['view']['height']['value'] = -1
+ self.internalSettings['nviz']['view']['z-exag'] = {}
+ self.internalSettings['nviz']['view']['z-exag']['original'] = 1
+ self.internalSettings['nviz']['view']['rotation'] = None
+ self.internalSettings['nviz']['view']['focus'] = {}
+ self.internalSettings['nviz']['view']['focus']['x'] = -1
+ self.internalSettings['nviz']['view']['focus']['y'] = -1
+ self.internalSettings['nviz']['view']['focus']['z'] = -1
+ self.internalSettings['nviz']['view']['dir'] = {}
+ self.internalSettings['nviz']['view']['dir']['x'] = -1
+ self.internalSettings['nviz']['view']['dir']['y'] = -1
+ self.internalSettings['nviz']['view']['dir']['z'] = -1
+ self.internalSettings['nviz']['view']['dir']['use'] = False
+
+ for decor in ('arrow', 'scalebar'):
+ self.internalSettings['nviz'][decor] = {}
+ self.internalSettings['nviz'][decor]['position'] = {}
+ self.internalSettings['nviz'][decor]['position']['x'] = 0
+ self.internalSettings['nviz'][decor]['position']['y'] = 0
+ self.internalSettings['nviz'][decor]['size'] = 100
self.internalSettings['nviz']['vector'] = {}
self.internalSettings['nviz']['vector']['points'] = {}
self.internalSettings['nviz']['vector']['points']['marker'] = ("x",
@@ -933,6 +1005,16 @@
"""!Get default user settings"""
return self.defaultSettings
+ def Reset(self, key = None):
+ """!Reset to default settings
+
+ @key key in settings dict (None for all keys)
+ """
+ if not key:
+ self.userSettings = copy.deepcopy(self.defaultSettings)
+ else:
+ self.userSettings[key] = copy.deepcopy(self.defaultSettings[key])
+
globalSettings = Settings()
class PreferencesBaseDialog(wx.Dialog):
Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/render.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/render.py 2011-11-25 14:58:21 UTC (rev 49356)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/render.py 2011-11-25 15:10:47 UTC (rev 49357)
@@ -698,8 +698,7 @@
if windres:
compRegion = self.GetRegion()
region = copy.copy(self.region)
- for key in ('nsres', 'ewres',
- 'rows', 'cols', 'cells'):
+ for key in ('nsres', 'ewres', 'cells'):
region[key] = compRegion[key]
else:
# adjust region settings to match monitor
@@ -733,10 +732,14 @@
(region['nsres'])
continue
elif key == "cols":
+ if windres:
+ continue
grass_region += 'cols: %d; ' % \
region['cols']
continue
elif key == "rows":
+ if windres:
+ continue
grass_region += 'rows: %d; ' % \
region['rows']
continue
@@ -1241,7 +1244,7 @@
def DeleteOverlay(self, overlay):
"""!Delete overlay
- @param id overlay id
+ @param overlay overlay layer
@return removed overlay on success or None
"""
@@ -1288,6 +1291,12 @@
"""!Reverse list of layers"""
return self.layers.reverse()
+ def RenderOverlays(self, force):
+ """!Render overlays only (for nviz)"""
+ for layer in self.overlays:
+ if force or layer.force_render:
+ layer.Render()
+
if __name__ == "__main__":
import gettext
gettext.install('grasswxpy', os.path.join(os.getenv("GISBASE"), 'locale'), unicode = True)
Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/toolbars.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/toolbars.py 2011-11-25 14:58:21 UTC (rev 49356)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/toolbars.py 2011-11-25 15:10:47 UTC (rev 49357)
@@ -10,7 +10,7 @@
- GCPDisplayToolbar
- VDigitToolbar
- ProfileToolbar
- - NvizToolbar
+ - LMNvizToolbar
- ModelToolbar
- HistogramToolbar
- LMWorkspaceToolbar
@@ -27,7 +27,7 @@
@author Michael Barton
@author Jachym Cepicky
@author Martin Landa <landa.martin gmail.com>
- at author Anna Kratochvilova <anna.kratochvilova fsv.cvut.cz>
+ at author Anna Kratochvilova <kratochanna gmail.com>
"""
import os
@@ -75,9 +75,10 @@
return None
def CreateTool(self, label, bitmap, kind,
- shortHelp, longHelp, handler):
+ shortHelp, longHelp, handler, pos = -1):
"""!Add tool to the toolbar
+ @param pos if -1 add tool, if > 0 insert at given pos
@return id of tool
"""
bmpDisabled = wx.NullBitmap
@@ -86,10 +87,14 @@
tool = vars(self)[label] = wx.NewId()
Debug.msg(3, "CreateTool(): tool=%d, label=%s bitmap=%s" % \
(tool, label, bitmap))
-
- toolWin = self.AddLabelTool(tool, label, bitmap,
- bmpDisabled, kind,
- shortHelp, longHelp)
+ if pos < 0:
+ toolWin = self.AddLabelTool(tool, label, bitmap,
+ bmpDisabled, kind,
+ shortHelp, longHelp)
+ else:
+ toolWin = self.InsertLabelTool(pos, tool, label, bitmap,
+ bmpDisabled, kind,
+ shortHelp, longHelp)
self.Bind(wx.EVT_TOOL, handler, toolWin)
else: # separator
self.AddSeparator()
@@ -149,10 +154,10 @@
'desc' : self.defaultAction.get('desc', '') }
def FixSize(self, width):
- """!Fix toolbar width on Windows
-
- @todo Determine why combobox causes problems here
- """
+ """!Fix toolbar width on Windows
+
+ @todo Determine why combobox causes problems here
+ """
if platform.system() == 'Windows':
size = self.GetBestSize()
self.SetSize((size[0] + width, size[1]))
@@ -176,16 +181,15 @@
retData = list()
for args in data:
retData.append(self._defineTool(*args))
-
return retData
- def _defineTool(self, name = None, icon = None, handler = None, item = wx.ITEM_NORMAL):
+ def _defineTool(self, name = None, icon = None, handler = None, item = wx.ITEM_NORMAL, pos = -1):
"""!Define tool
"""
if name:
return (name, icon.GetBitmap(),
item, icon.GetLabel(), icon.GetDesc(),
- handler)
+ handler, pos)
return ("", "", "", "", "", "") # separator
class MapToolbar(AbstractToolbar):
@@ -308,7 +312,40 @@
self.parent.PrintMenu),
(None, ))
)
-
+ def InsertTool(self, data):
+ """!Insert tool to toolbar
+
+ @param data toolbar data"""
+ data = self._getToolbarData(data)
+ for tool in data:
+ self.CreateTool(*tool)
+ self.Realize()
+
+ self.parent._mgr.GetPane('mapToolbar').BestSize(self.GetBestSize())
+ self.parent._mgr.Update()
+
+ def RemoveTool(self, tool):
+ """!Remove tool from toolbar
+
+ @param tool tool id"""
+ self.DeleteTool(tool)
+
+ self.parent._mgr.GetPane('mapToolbar').BestSize(self.GetBestSize())
+ self.parent._mgr.Update()
+
+ def ChangeToolsDesc(self, mode2d):
+ """!Change description of zoom tools for 2D/3D view"""
+ if mode2d:
+ set = 'displayWindow'
+ else:
+ set = 'nviz'
+ for i, data in enumerate(self._data):
+ for tool, toolname in (('zoomin', 'zoomIn'),('zoomout', 'zoomOut')):
+ if data[0] == tool:
+ tmp = list(data)
+ tmp[4] = Icons[set][toolname].GetDesc()
+ self._data[i] = tuple(tmp)
+
def OnSelectTool(self, event):
"""!Select / enable tool available in tools list
"""
@@ -317,11 +354,12 @@
if tool == self.toolId['2d']:
self.ExitToolbars()
self.Enable2D(True)
+ self.ChangeToolsDesc(mode2d = True)
elif tool == self.toolId['3d'] and \
- not self.parent.toolbars['nviz']:
+ not (self.parent.MapWindow3D and self.parent.IsPaneShown('3d')):
self.ExitToolbars()
- self.parent.AddToolbar("nviz")
+ self.parent.AddNviz()
elif tool == self.toolId['vdigit'] and \
not self.parent.toolbars['vdigit']:
@@ -332,19 +370,13 @@
def ExitToolbars(self):
if self.parent.toolbars['vdigit']:
self.parent.toolbars['vdigit'].OnExit()
- if self.parent.toolbars['nviz']:
- self.parent.toolbars['nviz'].OnExit()
+ if self.parent.GetLayerManager().IsPaneShown('toolbarNviz'):
+ self.parent.RemoveNviz()
def Enable2D(self, enabled):
"""!Enable/Disable 2D display mode specific tools"""
- for tool in (self.pointer,
- self.pan,
- self.zoomin,
- self.zoomout,
- self.zoomback,
- self.zoommenu,
+ for tool in (self.zoommenu,
self.analyze,
- self.dec,
self.printmap):
self.EnableTool(tool, enabled)
@@ -1227,12 +1259,11 @@
self.parent.OnQuit),
))
-class NvizToolbar(AbstractToolbar):
+class LMNvizToolbar(AbstractToolbar):
"""!Nviz toolbar
"""
- def __init__(self, parent, mapcontent):
- self.mapcontent = mapcontent
- self.lmgr = parent.GetLayerManager()
+ def __init__(self, parent):
+ self.lmgr = parent
AbstractToolbar.__init__(self, parent)
@@ -1247,55 +1278,19 @@
def _toolbarData(self):
"""!Toolbar data"""
icons = Icons['nviz']
- return self._getToolbarData((("view", icons["view"],
- self.OnShowPage),
+ return self._getToolbarData((("nvizCmd", icons['nvizCmd'],
+ self.OnNvizCmd),
(None, ),
- ("surface", icons["surface"],
- self.OnShowPage),
- ("vector", icons["vector"],
- self.OnShowPage),
- ("volume", icons["volume"],
- self.OnShowPage),
- (None, ),
- ("light", icons["light"],
- self.OnShowPage),
- ("fringe", icons["fringe"],
- self.OnShowPage),
- (None, ),
("settings", icons["settings"],
self.OnSettings),
- ("help", Icons['misc']["help"],
- self.OnHelp),
- (None, ),
- ('quit', icons["quit"],
- self.OnExit))
+ ("help", icons["help"],
+ self.OnHelp))
)
-
- def OnShowPage(self, event):
- """!Go to the selected page"""
- if not self.lmgr or not hasattr(self.lmgr, "nviz"):
- event.Skip()
- return
- self.lmgr.notebook.SetSelectionByName('nviz')
- eId = event.GetId()
- if eId == self.view:
- self.lmgr.nviz.SetPage('view')
- elif eId == self.surface:
- self.lmgr.nviz.SetPage('surface')
- elif eId == self.surface:
- self.lmgr.nviz.SetPage('surface')
- elif eId == self.vector:
- self.lmgr.nviz.SetPage('vector')
- elif eId == self.volume:
- self.lmgr.nviz.SetPage('volume')
- elif eId == self.light:
- self.lmgr.nviz.SetPage('light')
- elif eId == self.fringe:
- self.lmgr.nviz.SetPage('fringe')
+ def OnNvizCmd(self, event):
+ """!Show m.nviz.image command"""
+ self.lmgr.GetLayerTree().GetMapDisplay().GetWindow().OnNvizCmd()
- self.lmgr.Raise()
-
def OnHelp(self, event):
"""!Show 3D view mode help"""
if not self.lmgr:
@@ -1311,20 +1306,7 @@
if not self.settingsDialog:
self.settingsDialog = NvizPreferencesDialog(parent = self.parent)
self.settingsDialog.Show()
-
- def OnExit (self, event = None):
- """!Quit nviz tool (swith to 2D mode)"""
- # set default mouse settings
- self.parent.MapWindow.mouse['use'] = "pointer"
- self.parent.MapWindow.mouse['box'] = "point"
- self.parent.MapWindow.polycoords = []
- # return to map layer page (gets rid of ugly exit bug)
- self.lmgr.notebook.SetSelectionByName('layers')
-
- # disable the toolbar
- self.parent.RemoveToolbar("nviz")
-
class ModelToolbar(AbstractToolbar):
"""!Graphical modeler toolbar (see gmodeler.py)
"""
Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/workspace.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/workspace.py 2011-11-25 14:58:21 UTC (rev 49356)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/workspace.py 2011-11-25 15:10:47 UTC (rev 49357)
@@ -9,16 +9,19 @@
- WriteWorkspaceFile
- ProcessGrcFile
-(C) 2007-2010 by the GRASS Development Team
+(C) 2007-2011 by the GRASS Development Team
This program is free software under the GNU General Public
License (>=v2). Read the file COPYING that comes with GRASS
for details.
@author Martin Landa <landa.martin gmail.com>
+ at author Anna Kratochvilova <kratochanna gmail.com> (wxNviz / Google SoC 2011)
"""
import os
import sys
+import copy
+import types
import wx
@@ -64,6 +67,10 @@
# list of map layers
#
self.layers = []
+ #
+ # nviz state
+ #
+ self.nviz_state = {}
self.displayIndex = -1 # first display has index '0'
@@ -150,10 +157,13 @@
"extent" : extent,
"alignExtent" : bool(int(display.get('alignExtent', "0"))),
"constrainRes" : bool(int(display.get('constrainRes', "0"))),
- "projection" : projection, } )
+ "projection" : projection,
+ "viewMode" : display.get('viewMode', '2d')} )
# process all layers/groups in the display
self.__processLayers(display)
+ # process nviz_state
+ self.__processNvizState(display)
def __processLayers(self, node, inGroup = -1):
"""!Process layers/groups of selected display
@@ -331,12 +341,12 @@
# position
node_pos = node_surface.find('position')
if node_pos is not None:
- dc = self.nviz['surface']['position'] = {}
+ dc = nviz['surface']['position'] = {}
for coor in ['x', 'y', 'z']:
node = node_pos.find(coor)
if node is None:
continue
- value = int(self.__getNodeText(node, 'value'))
+ value = int(self.__getNodeText(node_pos, coor))
dc[coor] = value
elif 'vector' in nviz:
@@ -351,9 +361,17 @@
node_mode = node_vpoints.find('mode')
if node_mode is not None:
nviz['vector']['points']['mode'] = {}
- nviz['vector']['points']['mode']['type'] = str(node_mode.get('type', ''))
- nviz['vector']['points']['mode']['surface'] = \
- self.__processLayerNvizNode(node_mode, 'map', str)
+ nviz['vector']['points']['mode']['type'] = str(node_mode.get('type', 'surface'))
+ nviz['vector']['points']['mode']['surface'] = {}
+ nviz['vector']['points']['mode']['surface']['value'] = []
+ nviz['vector']['points']['mode']['surface']['show'] = []
+
+ # map
+ for node_map in node_mode.findall('map'):
+ nviz['vector']['points']['mode']['surface']['value'].append(
+ self.__processLayerNvizNode(node_map, 'name', str))
+ nviz['vector']['points']['mode']['surface']['show'].append(bool(
+ self.__processLayerNvizNode(node_map, 'checked', int)))
# color
self.__processLayerNvizNode(node_vpoints, 'color', str,
@@ -370,7 +388,7 @@
# height
self.__processLayerNvizNode(node_vpoints, 'size', int,
nviz['vector']['points'])
-
+
# vlines
node_vlines = node_nviz.find('vlines')
if node_vlines is not None:
@@ -378,11 +396,16 @@
if node_mode is not None:
nviz['vector']['lines']['mode'] = {}
nviz['vector']['lines']['mode']['type'] = str(node_mode.get('type', ''))
- nviz['vector']['lines']['mode']['surface'] = ''
+ nviz['vector']['lines']['mode']['surface'] = {}
+ nviz['vector']['lines']['mode']['surface']['value'] = []
+ nviz['vector']['lines']['mode']['surface']['show'] = []
# map
- nviz['vector']['lines']['mode']['surface'] = \
- self.__processLayerNvizNode(node_mode, 'map', str)
+ for node_map in node_mode.findall('map'):
+ nviz['vector']['lines']['mode']['surface']['value'].append(
+ self.__processLayerNvizNode(node_map, 'name', str))
+ nviz['vector']['lines']['mode']['surface']['show'].append(bool(
+ self.__processLayerNvizNode(node_map, 'checked', int)))
# color
self.__processLayerNvizNode(node_vlines, 'color', str,
@@ -395,7 +418,7 @@
# height
self.__processLayerNvizNode(node_vlines, 'height', int,
nviz['vector']['lines'])
-
+
return nviz
def __processLayerNvizNode(self, node, tag, cast, dc = None):
@@ -418,14 +441,124 @@
else:
return value
+ def __processNvizState(self, node):
+ """!Process tag nviz_state"""
+ node_state = node.find('nviz_state')
+ if node_state is None:
+ return
+ self.nviz_state['display'] = self.displayIndex
+ #
+ # view
+ #
+ node_view = node_state.find('view')
+ view = {}
+ iview = {}
+
+ node_position = node_view.find('v_position')
+ view['position'] = {}
+ view['position']['x'] = self.__processLayerNvizNode(node_position, 'x', float)
+ view['position']['y'] = self.__processLayerNvizNode(node_position, 'y', float)
+ node_persp = node_view.find('persp')
+ view['persp'] = {}
+ iview['persp'] = {}
+ view['persp']['value'] = self.__processLayerNvizNode(node_persp, 'value', int)
+ view['persp']['step'] = self.__processLayerNvizNode(node_persp, 'step', int)
+ iview['persp']['min'] = self.__processLayerNvizNode(node_persp, 'min', int)
+ iview['persp']['max'] = self.__processLayerNvizNode(node_persp, 'max', int)
+ node_height = node_view.find('v_height')
+ iview['height'] = {}
+ iview['height']['value'] = self.__processLayerNvizNode(node_height, 'value', int)
+ iview['height']['min'] = self.__processLayerNvizNode(node_height, 'min', int)
+ iview['height']['max'] = self.__processLayerNvizNode(node_height, 'max', int)
+ node_twist = node_view.find('twist')
+ view['twist'] = {}
+ iview['twist'] = {}
+ view['twist']['value'] = self.__processLayerNvizNode(node_twist, 'value', int)
+ iview['twist']['min'] = self.__processLayerNvizNode(node_twist, 'min', int)
+ iview['twist']['max'] = self.__processLayerNvizNode(node_twist, 'max', int)
+ node_zexag = node_view.find('z-exag')
+ view['z-exag'] = {}
+ iview['z-exag'] = {}
+ view['z-exag']['value'] = self.__processLayerNvizNode(node_zexag, 'value', int)
+ view['z-exag']['min'] = self.__processLayerNvizNode(node_zexag, 'min', int)
+ view['z-exag']['max'] = self.__processLayerNvizNode(node_zexag, 'max', int)
+ iview['z-exag']['original'] = self.__processLayerNvizNode(node_zexag, 'original', float)
+ node_focus = node_view.find('focus')
+ iview['focus'] = {}
+ iview['focus']['x'] = self.__processLayerNvizNode(node_focus, 'x', int)
+ iview['focus']['y'] = self.__processLayerNvizNode(node_focus, 'y', int)
+ iview['focus']['z'] = self.__processLayerNvizNode(node_focus, 'z', int)
+ node_dir = node_view.find('dir')
+ if node_dir:
+ iview['dir'] = {}
+ iview['dir']['x'] = self.__processLayerNvizNode(node_dir, 'x', int)
+ iview['dir']['y'] = self.__processLayerNvizNode(node_dir, 'y', int)
+ iview['dir']['z'] = self.__processLayerNvizNode(node_dir, 'z', int)
+ iview['dir']['use'] = True
+ else:
+ iview['dir'] = {}
+ iview['dir']['x'] = -1
+ iview['dir']['y'] = -1
+ iview['dir']['z'] = -1
+ iview['dir']['use'] = False
+
+ view['background'] = {}
+ color = self.__processLayerNvizNode(node_view, 'background_color', str)
+ view['background']['color'] = tuple(map(int, color.split(':')))
+
+ self.nviz_state['view'] = view
+ self.nviz_state['iview'] = iview
+ #
+ # light
+ #
+ node_light = node_state.find('light')
+ light = {}
+
+ node_position = node_light.find('l_position')
+ light['position'] = {}
+ light['position']['x'] = self.__processLayerNvizNode(node_position, 'x', float)
+ light['position']['y'] = self.__processLayerNvizNode(node_position, 'y', float)
+ light['position']['z'] = self.__processLayerNvizNode(node_position, 'z', int)
+
+ light['bright'] = self.__processLayerNvizNode(node_light, 'bright', int)
+ light['ambient'] = self.__processLayerNvizNode(node_light, 'ambient', int)
+ color = self.__processLayerNvizNode(node_light, 'color', str)
+ light['color'] = tuple(map(int, color.split(':')))
+
+ self.nviz_state['light'] = light
+
+ node_constants = node_state.find('constant_planes')
+ constants = []
+ if node_constants:
+ for i, node_plane in enumerate(node_constants.findall('plane')):
+ plane = {}
+ plane['color'] = self.__processLayerNvizNode(node_plane, 'color', str)
+ plane['resolution'] = self.__processLayerNvizNode(node_plane, 'fine_resolution', int)
+ plane['value'] = self.__processLayerNvizNode(node_plane, 'height', int)
+ plane['object'] = {}
+ constants.append({'constant': plane})
+ self.nviz_state['constants'] = constants
+
class Nviz:
def __init__(self):
"""Default 3D settings"""
- pass
+ UserSettings.Reset('nviz')
+ UserSettings.ReadSettingsFile()
+
+ def SetConstantDefaultProp(self):
+ """Set default constant data properties"""
+ data = dict()
+ for key, value in UserSettings.Get(group='nviz', key='constant').iteritems():
+ data[key] = value
+ color = str(data['color'][0]) + ':' + str(data['color'][1]) + ':' + str(data['color'][2])
+ data['color'] = color
+
+ return data
- def SetSurfaceDefaultProp(self):
+ def SetSurfaceDefaultProp(self, data = None):
"""Set default surface data properties"""
- data = dict()
+ if not data:
+ data = dict()
for sec in ('attribute', 'draw', 'mask', 'position'):
data[sec] = {}
@@ -434,7 +567,7 @@
#
for attrb in ('shine', ):
data['attribute'][attrb] = {}
- for key, value in UserSettings.Get(group='nviz', key='volume',
+ for key, value in UserSettings.Get(group='nviz', key='surface',
subkey=attrb).iteritems():
data['attribute'][attrb][key] = value
data['attribute'][attrb]['update'] = None
@@ -469,7 +602,11 @@
data['draw']['mode'] = { 'value' : value,
'desc' : desc,
'update': None }
-
+ # position
+ for coord in ('x', 'y', 'z'):
+ data['position'][coord] = UserSettings.Get(group='nviz', key='surface', subkey=['position', coord])
+ data['position']['update'] = None
+
return data
def SetVolumeDefaultProp(self):
@@ -484,14 +621,15 @@
# draw
#
for control, value in UserSettings.Get(group='nviz', key='volume', subkey='draw').iteritems():
- if control == 'mode':
- continue
if control == 'shading':
- sel = UserSettings.Get(group='nviz', key='surface', subkey=['draw', 'shading'])
+ sel = UserSettings.Get(group='nviz', key='volume', subkey=['draw', 'shading'])
value, desc = self.GetDrawMode(shade=sel, string=False)
-
- data['draw']['shading'] = { 'value' : value,
- 'desc' : desc['shading'] }
+
+ data['draw']['shading'] = {}
+ data['draw']['shading']['isosurface'] = { 'value' : value,
+ 'desc' : desc['shading'] }
+ data['draw']['shading']['slice'] = { 'value' : value,
+ 'desc' : desc['shading'] }
elif control == 'mode':
sel = UserSettings.Get(group='nviz', key='volume', subkey=['draw', 'mode'])
if sel == 0:
@@ -501,7 +639,9 @@
data['draw']['mode'] = { 'value' : sel,
'desc' : desc, }
else:
- data['draw'][control] = { 'value' : value }
+ data['draw'][control] = {}
+ data['draw'][control]['isosurface'] = { 'value' : value }
+ data['draw'][control]['slice'] = { 'value' : value }
if 'update' not in data['draw'][control]:
data['draw'][control]['update'] = None
@@ -517,9 +657,32 @@
return data
- def SetVectorDefaultProp(self):
+ def SetIsosurfaceDefaultProp(self):
+ """!Set default isosurface properties"""
+ data = dict()
+ for attr in ('shine', 'topo', 'transp', 'color'):
+ data[attr] = {}
+ for key, value in UserSettings.Get(group = 'nviz', key = 'volume',
+ subkey = attr).iteritems():
+ data[attr][key] = value
+ data[attr]['update'] = None
+ return data
+
+ def SetSliceDefaultProp(self):
+ """!Set default slice properties"""
+ data = dict()
+ data['position'] = copy.deepcopy(UserSettings.Get(group = 'nviz', key = 'volume',
+ subkey = 'slice_position'))
+ data['position']['update'] = None
+
+ data['transp'] = copy.deepcopy(UserSettings.Get(group = 'nviz', key = 'volume',
+ subkey = 'transp'))
+ return data
+
+ def SetVectorDefaultProp(self, data = None):
"""Set default vector data properties"""
- data = dict()
+ if not data:
+ data = dict()
for sec in ('lines', 'points'):
data[sec] = {}
@@ -544,21 +707,17 @@
if UserSettings.Get(group='nviz', key='vector',
subkey=['lines', 'flat']):
type = 'flat'
- map = None
+
else:
- type = 'flat'
- map = None
-
+ type = 'surface'
+
data['mode'] = {}
data['mode']['type'] = type
data['mode']['update'] = None
- if map:
- data['mode']['surface'] = map
-
+
# height
data['height'] = { 'value' : UserSettings.Get(group='nviz', key='vector',
subkey=['lines', 'height']) }
-
if 'object' in data:
for attrb in ('color', 'width', 'mode', 'height'):
data[attrb]['update'] = None
@@ -584,16 +743,15 @@
data['color'] = { 'value' : color }
# mode
- data['mode'] = { 'type' : 'surface',
- 'surface' : '', }
+ data['mode'] = { 'type' : 'surface'}
+## 'surface' : '', }
# height
data['height'] = { 'value' : UserSettings.Get(group='nviz', key='vector',
subkey=['points', 'height']) }
-
+
if 'object' in data:
- for attrb in ('size', 'width', 'marker',
- 'color', 'surface', 'height'):
+ for attrb in ('size', 'width', 'marker', 'color', 'height'):
data[attrb]['update'] = None
def GetDrawMode(self, mode=None, style=None, shade=None, string=False):
@@ -662,6 +820,28 @@
return (value, desc)
+ def SetDecorDefaultProp(self, type):
+ """!Set default arrow properties
+ """
+ data = {}
+
+ # arrow
+ if type == 'arrow':
+ data['arrow'] = UserSettings.Get(group = 'nviz', key = 'arrow')
+ data['arrow']['color'] = "%d:%d:%d" % (
+ UserSettings.Get(group = 'nviz', key = 'arrow', subkey = 'color')[:3])
+ data['arrow'].update(UserSettings.Get(group = 'nviz', key = 'arrow', internal = True))
+ data['arrow']['show'] = False
+
+ # arrow
+ if type == 'scalebar':
+ data['scalebar'] = copy.deepcopy(UserSettings.Get(group = 'nviz', key = 'scalebar'))
+ data['scalebar']['color'] = "%d:%d:%d" % (
+ UserSettings.Get(group = 'nviz', key = 'scalebar', subkey = 'color')[:3])
+ data['scalebar'].update(copy.deepcopy(UserSettings.Get(group = 'nviz', key = 'scalebar', internal = True)))
+ data['scalebar']['id'] = 0
+ return data
+
class WriteWorkspaceFile(object):
"""!Generic class for writing workspace file"""
def __init__(self, lmgr, file):
@@ -695,13 +875,18 @@
displayPos = mapTree.mapdisplay.GetPosition()
displaySize = mapTree.mapdisplay.GetSize()
+ if mapTree.mapdisplay.toolbars['map'].combo.GetSelection() == 1:
+ viewmode = '3d'
+ else:
+ viewmode = '2d'
file.write('%s<display render="%d" '
'mode="%d" showCompExtent="%d" '
'alignExtent="%d" '
'constrainRes="%d" '
'dim="%d,%d,%d,%d" '
- 'extent="%f,%f,%f,%f">\n' % (' ' * self.indent,
+ 'extent="%f,%f,%f,%f" '
+ 'viewMode="%s" >\n' % (' ' * self.indent,
int(mapTree.mapdisplay.statusbarWin['render'].IsChecked()),
mapTree.mapdisplay.statusbarWin['toggle'].GetSelection(),
int(mapTree.mapdisplay.statusbarWin['region'].IsChecked()),
@@ -714,7 +899,8 @@
region['w'],
region['s'],
region['e'],
- region['n']
+ region['n'],
+ viewmode
))
# projection statusbar info
if mapTree.mapdisplay.statusbarWin['projection'].IsChecked() and \
@@ -735,6 +921,12 @@
# list of layers
item = mapTree.GetFirstChild(mapTree.root)[0]
self.__writeLayer(mapTree, item)
+
+ if mapTree.mapdisplay.MapWindow3D is not None:
+ nvizDisp = mapTree.mapdisplay.MapWindow3D
+ self.__writeNvizState(view = nvizDisp.view, iview = nvizDisp.iview,
+ light = nvizDisp.light, constants = nvizDisp.constants)
+
file.write('%s</display>\n' % (' ' * self.indent))
self.indent =- 4
@@ -843,7 +1035,6 @@
"""
if 'object' not in data: # skip disabled
return
-
self.indent += 4
self.file.write('%s<surface>\n' % (' ' * self.indent))
self.indent += 4
@@ -940,8 +1131,14 @@
data[attrb][name]['type']))
if data[attrb][name]['type'] == 'surface':
self.indent += 4
- self.file.write('%s<map>%s</map>\n' % (' ' * self.indent,
- data[attrb][name]['surface']))
+ for idx, surface in enumerate(data[attrb][name]['surface']['value']):
+ checked = data[attrb][name]['surface']['show'][idx]
+ self.file.write('%s<map>\n' % (' ' * self.indent))
+ self.indent += 4
+ self.file.write('%s<name>%s</name>\n' % (' ' * self.indent, surface))
+ self.file.write('%s<checked>%s</checked>\n' % (' ' * self.indent, int(checked)))
+ self.indent -= 4
+ self.file.write('%s</map>\n' % (' ' * self.indent))
self.indent -= 4
self.file.write('%s</%s>\n' % ((' ' * self.indent, name)))
else:
@@ -955,6 +1152,132 @@
self.indent -= 4
+ def __writeNvizState(self, view, iview, light, constants):
+ """"!Save Nviz properties (view, light) to workspace
+
+ @param view Nviz view properties
+ @param iview Nviz internal view properties
+ @param light Nviz light properties
+ """
+ self.indent += 4
+ self.file.write('%s<nviz_state>\n' % (' ' * self.indent))
+ #
+ # view
+ #
+ self.indent += 4
+ self.file.write('%s<view>\n' % (' ' * self.indent))
+ self.indent += 4
+ # position
+ self.file.write('%s<v_position>\n' % (' ' * self.indent))
+ self.indent += 4
+ self.file.write('%s<x>%.2f</x>\n' % (' ' * self.indent, view['position']['x']))
+ self.file.write('%s<y>%.2f</y>\n' % (' ' * self.indent, view['position']['y']))
+ self.indent -= 4
+ self.file.write('%s</v_position>\n' % (' ' * self.indent))
+ # perspective
+ self.file.write('%s<persp>\n' % (' ' * self.indent))
+ self.indent += 4
+ self.file.write('%s<value>%d</value>\n' % (' ' * self.indent, view['persp']['value']))
+ self.file.write('%s<step>%d</step>\n' % (' ' * self.indent, view['persp']['step']))
+ self.file.write('%s<min>%d</min>\n' % (' ' * self.indent, iview['persp']['min']))
+ self.file.write('%s<max>%d</max>\n' % (' ' * self.indent, iview['persp']['max']))
+ self.indent -= 4
+ self.file.write('%s</persp>\n' % (' ' * self.indent))
+ # height
+ self.file.write('%s<v_height>\n' % (' ' * self.indent))
+ self.indent += 4
+ self.file.write('%s<value>%d</value>\n' % (' ' * self.indent, iview['height']['value']))
+ self.file.write('%s<min>%d</min>\n' % (' ' * self.indent, iview['height']['min']))
+ self.file.write('%s<max>%d</max>\n' % (' ' * self.indent, iview['height']['max']))
+ self.indent -= 4
+ self.file.write('%s</v_height>\n' % (' ' * self.indent))
+ # twist
+ self.file.write('%s<twist>\n' % (' ' * self.indent))
+ self.indent += 4
+ self.file.write('%s<value>%d</value>\n' % (' ' * self.indent, view['twist']['value']))
+ self.file.write('%s<min>%d</min>\n' % (' ' * self.indent, iview['twist']['min']))
+ self.file.write('%s<max>%d</max>\n' % (' ' * self.indent, iview['twist']['max']))
+ self.indent -= 4
+ self.file.write('%s</twist>\n' % (' ' * self.indent))
+ # z-exag
+ self.file.write('%s<z-exag>\n' % (' ' * self.indent))
+ self.indent += 4
+ self.file.write('%s<value>%d</value>\n' % (' ' * self.indent, view['z-exag']['value']))
+ self.file.write('%s<min>%d</min>\n' % (' ' * self.indent, view['z-exag']['min']))
+ self.file.write('%s<max>%d</max>\n' % (' ' * self.indent, view['z-exag']['max']))
+ self.file.write('%s<original>%d</original>\n' % (' ' * self.indent, iview['z-exag']['original']))
+ self.indent -= 4
+ self.file.write('%s</z-exag>\n' % (' ' * self.indent))
+ # focus (look here)
+ self.file.write('%s<focus>\n' % (' ' * self.indent))
+ self.indent += 4
+ self.file.write('%s<x>%d</x>\n' % (' ' * self.indent, iview['focus']['x']))
+ self.file.write('%s<y>%d</y>\n' % (' ' * self.indent, iview['focus']['y']))
+ self.file.write('%s<z>%d</z>\n' % (' ' * self.indent, iview['focus']['z']))
+ self.indent -= 4
+ self.file.write('%s</focus>\n' % (' ' * self.indent))
+ # background
+ self.__writeTagWithValue('background_color', view['background']['color'][:3], format = 'd:%d:%d')
+
+ self.indent -= 4
+ self.file.write('%s</view>\n' % (' ' * self.indent))
+ #
+ # light
+ #
+ self.file.write('%s<light>\n' % (' ' * self.indent))
+ self.indent += 4
+ # position
+ self.file.write('%s<l_position>\n' % (' ' * self.indent))
+ self.indent += 4
+ self.file.write('%s<x>%.2f</x>\n' % (' ' * self.indent, light['position']['x']))
+ self.file.write('%s<y>%.2f</y>\n' % (' ' * self.indent, light['position']['y']))
+ self.file.write('%s<z>%d</z>\n' % (' ' * self.indent, light['position']['z']))
+ self.indent -= 4
+ self.file.write('%s</l_position>\n' % (' ' * self.indent))
+ # bright
+ self.__writeTagWithValue('bright', light['bright'])
+ # ambient
+ self.__writeTagWithValue('ambient', light['ambient'])
+ # color
+ self.__writeTagWithValue('color', light['color'][:3], format = 'd:%d:%d')
+
+ self.indent -= 4
+ self.file.write('%s</light>\n' % (' ' * self.indent))
+ #
+ # constant planes
+ #
+ if constants:
+ self.file.write('%s<constant_planes>\n' % (' ' * self.indent))
+ self.indent += 4
+ for idx, plane in enumerate(constants):
+ self.file.write('%s<plane>\n' % (' ' * self.indent))
+ self.indent += 4
+ self.__writeTagWithValue('height', constants[idx]['constant']['value'])
+ self.__writeTagWithValue('fine_resolution', constants[idx]['constant']['resolution'])
+ self.__writeTagWithValue('color', constants[idx]['constant']['color'], format = 's')
+ self.indent -= 4
+ self.file.write('%s</plane>\n' % (' ' * self.indent))
+ self.indent -= 4
+ self.file.write('%s</constant_planes>\n' % (' ' * self.indent))
+ self.indent -= 4
+
+ self.file.write('%s</nviz_state>\n' % (' ' * self.indent))
+ self.indent -= 4
+
+ def __writeTagWithValue(self, tag, data, format = 'd'):
+ """!Helper function for writing pair tag
+
+ @param tag written tag
+ @param data written data
+ @param format conversion type
+ """
+ self.file.write('%s<%s>\n' % (' ' * self.indent, tag))
+ self.indent += 4
+ self.file.write('%s' % (' ' * self.indent))
+ self.file.write(('<value>%' + format + '</value>\n') % data)
+ self.indent -= 4
+ self.file.write('%s</%s>\n' % (' ' * self.indent, tag))
+
class ProcessGrcFile(object):
def __init__(self, filename):
"""!Process GRC file"""
Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/wxnviz.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/wxnviz.py 2011-11-25 14:58:21 UTC (rev 49356)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/wxnviz.py 2011-11-25 15:10:47 UTC (rev 49357)
@@ -3,12 +3,14 @@
@brief wxGUI 3D view mode
-This module implements 3D visualization mode for map display.
+This module implements 3D visualization mode for map display (ctypes
+required).
List of classes:
- Nviz
+ - Texture
-(C) 2008-2010 by the GRASS Development Team
+(C) 2008-2011 by the GRASS Development Team
This program is free software under the GNU General Public
License (>=v2). Read the file COPYING that comes with GRASS
@@ -16,21 +18,29 @@
@author Martin Landa <landa.martin gmail.com> (Google SoC 2008/2010)
@author Pythonized by Glynn Clements
+ at author Anna Kratochvilova <KratochAnna seznam.cz> (Google SoC 2011)
"""
+import wx
import sys
+import locale
+import struct
from threading import Thread
+from math import sqrt
+from numpy import matrix
from ctypes import *
try:
- from grass.lib.gis import *
- from grass.lib.g3d import *
- from grass.lib.ogsf import *
- from grass.lib.nviz import *
+ from grass.lib.gis import *
+ from grass.lib.g3d import *
+ from grass.lib.vector import *
+ from grass.lib.ogsf import *
+ from grass.lib.nviz import *
except ImportError, e:
sys.stderr.write(_("3D view mode: %s\n") % e)
-
+
from debug import Debug
+import grass.script as grass
log = None
progress = None
@@ -65,20 +75,24 @@
"""!Initialize Nviz class instance
@param log logging area
+ @param gprogress progressbar
"""
global errfunc, perfunc, log, progress
log = glog
progress = gprogress
- G_gisinit("")
+ G_gisinit("wxnviz")
+ # gislib is already initialized (where?)
G_set_error_routine(errfunc)
G_set_percent_routine(perfunc)
- GS_libinit()
- GVL_libinit()
+ self.Init()
self.data_obj = nv_data()
self.data = pointer(self.data_obj)
+ self.color_obj = Colors()
+ self.color = pointer(self.color_obj)
+
self.width = self.height = -1
self.showLight = False
@@ -91,7 +105,16 @@
del self.data
del self.data_obj
self.log = None
-
+
+ def Init(self):
+ """!Initialize window"""
+ locale.setlocale(locale.LC_NUMERIC, 'C')
+ #G_unset_window()
+ #Rast_unset_window()
+ #Rast__init_window()
+ GS_libinit()
+ GVL_libinit()
+
def ResizeWindow(self, width, height):
"""!GL canvas resized
@@ -107,6 +130,10 @@
width, height)
return Nviz_resize_window(width, height)
+ def GetLongDim(self):
+ """!Get longest dimension, used for initial size of north arrow"""
+ return Nviz_get_longdim(self.data)
+
def SetViewDefault(self):
"""!Set default view (based on loaded data)
@@ -141,7 +168,62 @@
Debug.msg(3, "Nviz::SetView(): x=%f, y=%f, height=%f, persp=%f, twist=%f",
x, y, height, persp, twist)
+
+ def GetViewpointPosition(self):
+ x = c_double()
+ y = c_double()
+ h = c_double()
+ Nviz_get_viewpoint_height(byref(h))
+ Nviz_get_viewpoint_position(byref(x), byref(y))
+ return (x.value, y.value, h.value)
+
+ def LookHere(self, x, y):
+ """!Look here feature
+ @param x,y screen coordinates
+ """
+
+ Nviz_look_here(x, y)
+ Debug.msg(3, "Nviz::LookHere(): x=%f, y=%f", x, y)
+
+ def LookAtCenter(self):
+ """!Center view at center of displayed surface"""
+ Nviz_set_focus_map(MAP_OBJ_UNDEFINED, -1)
+ Debug.msg(3, "Nviz::LookAtCenter()")
+
+ def GetFocus(self):
+ """!Get focus"""
+ Debug.msg(3, "Nviz::GetFocus()")
+ if Nviz_has_focus(self.data):
+ x = c_float()
+ y = c_float()
+ z = c_float()
+ Nviz_get_focus(self.data, byref(x), byref(y), byref(z))
+ return x.value, y.value, z.value
+ else:
+ return -1, -1, -1
+
+ def SetFocus(self, x, y, z):
+ """!Set focus"""
+ Debug.msg(3, "Nviz::SetFocus()")
+ Nviz_set_focus(self.data, x, y, z)
+
+ def GetViewdir(self):
+ """!Get viewdir"""
+ Debug.msg(3, "Nviz::GetViewdir()")
+ dir = (c_float * 3)()
+ GS_get_viewdir(byref(dir))
+
+ return dir[0], dir[1], dir[2]
+
+ def SetViewdir(self, x, y, z):
+ """!Set viewdir"""
+ Debug.msg(3, "Nviz::SetViewdir(): x=%f, y=%f, z=%f" % (x, y, z))
+ dir = (c_float * 3)()
+ for i, coord in enumerate((x, y, z)):
+ dir[i] = coord
+ GS_set_viewdir(byref(dir))
+
def SetZExag(self, z_exag):
"""!Set z-exag value
@@ -189,7 +271,7 @@
# set background color
Nviz_set_bgcolor(self.data, Nviz_color_from_str("white"))
- GS_clear(Nviz_get_bgcolor(self.data))
+ GS_clear(Nviz_get_bgcolor(self.data))
# initialize view, lights
Nviz_init_view(self.data)
@@ -265,7 +347,19 @@
Debug.msg(1, "Nviz::LoadRaster(): name=%s -> id=%d", name, id)
return id
-
+
+ def AddConstant(self, value, color):
+ """!Add new constant surface"""
+ id = Nviz_new_map_obj(MAP_OBJ_SURF, None, value, self.data)
+
+ Nviz_set_attr(id, MAP_OBJ_SURF, ATT_COLOR, CONST_ATT,
+ None, Nviz_color_from_str(color),
+ self.data)
+ Nviz_set_focus_map(MAP_OBJ_UNDEFINED, -1)
+
+ Debug.msg(1, "Nviz::AddConstant(): id=%d", id)
+ return id
+
def UnloadSurface(self, id):
"""!Unload surface
@@ -290,16 +384,17 @@
@param name vector map name
@param points if true load 2d points rather then 2d lines
- @return object id
+ @return object id, id of base surface (or -1 if it is not loaded)
@return -1 on failure
"""
+ baseId = -1
if GS_num_surfs() == 0: # load base surface if no loaded
- Nviz_new_map_obj(MAP_OBJ_SURF, None, 0.0, self.data)
+ baseId = Nviz_new_map_obj(MAP_OBJ_SURF, None, 0.0, self.data)
nsurf = c_int()
surf_list = GS_get_surf_list(byref(nsurf))
GS_set_att_const(surf_list[0], ATT_TRANSP, 255)
-
+
mapset = G_find_vector2 (name, "")
if mapset is None:
G_warning(_("Vector map <%s> not found"),
@@ -316,7 +411,7 @@
Debug.msg(1, "Nviz::LoadVector(): name=%s -> id=%d", name, id)
- return id
+ return id, baseId
def UnloadVector(self, id, points):
"""!Unload vector set
@@ -342,6 +437,19 @@
return 1
+ def VectorSurfaceSelected(self, vid, sid):
+ """!Check if surface is selected (currently unused)
+
+ @param vid vector id
+ @param sid surface id
+
+ @return True if selected
+ @return False if not selected
+ """
+ selected = GV_surf_is_selected(vid, sid)
+ Debug.msg(1, "Nviz::VectorSurfaceSelected(): vid=%s, sid=%d -> selected=%d", vid, sid, selected)
+ return selected
+
def LoadVolume(self, name, color_name, color_value):
"""!Load 3d raster map (volume)
@@ -423,7 +531,7 @@
@param id surface id
@param map if true use map otherwise constant
- @param value map name of value
+ @param value map name or value
@return 1 on success
@return -1 surface not found
@@ -444,7 +552,7 @@
@return -1 surface not found
@return -2 setting attributes failed
"""
- return self.SetSurfaceAttr(id, ATT_MASK, true, value)
+ return self.SetSurfaceAttr(id, ATT_MASK, True, value)
def SetSurfaceTransp(self, id, map, value):
"""!Set surface mask
@@ -475,7 +583,7 @@
return self.SetSurfaceAttr(id, ATT_SHINE, map, value)
def SetSurfaceEmit(self, id, map, value):
- """!Set surface emission
+ """!Set surface emission (currently unused)
@param id surface id
@param map if true use map otherwise constant
@@ -546,7 +654,7 @@
return self.UnsetSurfaceAttr(id, ATT_TRANSP)
def UnsetSurfaceEmit(self, id):
- """!Unset surface emission
+ """!Unset surface emission (currently unused)
@param id surface id
@@ -784,6 +892,28 @@
return 1
+ def UnsetVectorLineSurface(self, id, surf_id):
+ """!Unset reference surface of vector set (lines)
+
+ @param id vector set id
+ @param surf_id surface id
+
+ @return 1 on success
+ @return -1 vector set not found
+ @return -2 surface not found
+ @return -3 on failure
+ """
+ if not GV_vect_exists(id):
+ return -1
+
+ if not GS_surf_exists(surf_id):
+ return -2
+
+ if GV_unselect_surf(id, surf_id) < 0:
+ return -3
+
+ return 1
+
def SetVectorPointMode(self, id, color_str, width, size, marker):
"""!Set mode of vector point overlay
@@ -803,9 +933,8 @@
color = Nviz_color_from_str(color_str)
- ### TODO
- # if GP_set_style(id, color, width, size, marker) < 0:
- # return -2
+ if GP_set_sitemode(id, ST_ATT_NONE, color, width, size, marker) < 0:
+ return -2
return 1
@@ -850,7 +979,64 @@
return 1
- def AddIsosurface(self, id, level):
+ def ReadVectorColors(self, name, mapset):
+ """!Read vector colors
+
+ @param name vector map name
+ @mapset mapset name ("" for search path)
+
+ @return -1 on error
+ @return 0 if color table missing
+ @return 1 on success (color table found)
+ """
+ return Vect_read_colors(name, mapset, self.color)
+
+ def CheckColorTable(self, id, type):
+ """!Check if color table exists.
+
+ @param id vector set id
+ @param type vector set type (lines/points)
+
+ @return 1 color table exists
+ @return 0 no color table found
+ @return -1 on error
+ @return -2 vector set not found
+ """
+ file = c_char_p()
+
+ if type == 'points':
+ ret = GP_get_sitename(id, byref(file))
+ elif type == 'lines':
+ ret = GV_get_vectname(id, byref(file))
+
+ if ret < 0:
+ return -2
+
+ return self.ReadVectorColors(file, "")
+
+ def UnsetVectorPointSurface(self, id, surf_id):
+ """!Unset reference surface of vector set (points)
+
+ @param id vector set id
+ @param surf_id surface id
+
+ @return 1 on success
+ @return -1 vector set not found
+ @return -2 surface not found
+ @return -3 on failure
+ """
+ if not GP_site_exists(id):
+ return -1
+
+ if not GS_surf_exists(surf_id):
+ return -2
+
+ if GP_unselect_surf(id, surf_id) < 0:
+ return -3
+
+ return 1
+
+ def AddIsosurface(self, id, level, isosurf_id = None):
"""!Add new isosurface
@param id volume id
@@ -862,6 +1048,11 @@
if not GVL_vol_exists(id):
return -1
+ if isosurf_id is not None:
+ num = GVL_isosurf_num_isosurfs(id)
+ if num < 0 or isosurf_id != num:
+ return -1
+
if GVL_isosurf_add(id) < 0:
return -1
@@ -870,6 +1061,27 @@
return GVL_isosurf_set_att_const(id, nisosurfs - 1, ATT_TOPO, level)
+ def AddSlice(self, id, slice_id = None):
+ """!Add new slice
+
+ @param id volume id
+
+ @return -1 on failure
+ @return number of slices
+ """
+ if not GVL_vol_exists(id):
+ return -1
+
+ if slice_id is not None:
+ num = GVL_slice_num_slices(id)
+ if num < 0 or slice_id != num:
+ return -1
+
+ if GVL_slice_add(id) < 0:
+ return -1
+
+ return GVL_slice_num_slices(id)
+
def DeleteIsosurface(self, id, isosurf_id):
"""!Delete isosurface
@@ -894,6 +1106,30 @@
return 1
+ def DeleteSlice(self, id, slice_id):
+ """!Delete slice
+
+ @param id volume id
+ @param slice_id slice id
+
+ @return 1 on success
+ @return -1 volume not found
+ @return -2 slice not found
+ @return -3 on failure
+ """
+ if not GVL_vol_exists(id):
+ return -1
+
+ if slice_id > GVL_slice_num_slices(id):
+ return -2
+
+ ret = GVL_slice_del(id, slice_id)
+
+ if ret < 0:
+ return -3
+
+ return 1
+
def MoveIsosurface(self, id, isosurf_id, up):
"""!Move isosurface up/down in the list
@@ -922,6 +1158,49 @@
return 1
+ def MoveSlice(self, id, slice_id, up):
+ """!Move slice up/down in the list
+
+ @param id volume id
+ @param slice_id slice id
+ @param up if true move up otherwise down
+
+ @return 1 on success
+ @return -1 volume not found
+ @return -2 slice not found
+ @return -3 on failure
+ """
+ if not GVL_vol_exists(id):
+ return -1
+
+ if slice_id > GVL_slice_num_slices(id):
+ return -2
+
+ if up:
+ ret = GVL_slice_move_up(id, slice_id)
+ else:
+ ret = GVL_slice_move_down(id, slice_id)
+
+ if ret < 0:
+ return -3
+
+ return 1
+
+ def SetIsosurfaceTopo(self, id, isosurf_id, map, value):
+ """!Set isosurface level
+
+ @param id volume id
+ @param isosurf_id isosurface id (0 - MAX_ISOSURFS)
+ @param map if true use map otherwise constant
+ @param value map name of value
+
+ @return 1 on success
+ @return -1 volume not found
+ @return -2 isosurface not found
+ @return -3 on failure
+ """
+ return self.SetIsosurfaceAttr(id, isosurf_id, ATT_TOPO, map, value)
+
def SetIsosurfaceColor(self, id, isosurf_id, map, value):
"""!Set isosurface color
@@ -952,7 +1231,7 @@
@return -2 isosurface not found
@return -3 on failure
"""
- return self.SetIsosurfaceAttr(id, isosurf_id, ATT_MASK, true, value)
+ return self.SetIsosurfaceAttr(id, isosurf_id, ATT_MASK, True, value)
def SetIsosurfaceTransp(self, id, isosurf_id, map, value):
"""!Set isosurface transparency
@@ -985,7 +1264,7 @@
return self.SetIsosurfaceAttr(id, isosurf_id, ATT_SHINE, map, value)
def SetIsosurfaceEmit(self, id, isosurf_id, map, value):
- """!Set isosurface emission
+ """!Set isosurface emission (currently unused)
@param id volume id
@param isosurf_id isosurface id (0 - MAX_ISOSURFS)
@@ -1030,7 +1309,7 @@
ret = GVL_isosurf_set_att_const(id, isosurf_id, attr, val)
Debug.msg(3, "Nviz::SetIsosurfaceAttr(): id=%d, isosurf=%d, "
- "attr=%d, map=%d, value=%s",
+ "attr=%d, map=%s, value=%s",
id, isosurf_id, attr, map, value)
if ret < 0:
@@ -1065,7 +1344,7 @@
return self.UnsetIsosurfaceAttr(id, isosurf_id, ATT_TRANSP)
def UnsetIsosurfaceEmit(self, id, isosurf_id):
- """!Unset isosurface emission
+ """!Unset isosurface emission (currently unused)
@param id volume id
@param isosurf_id isosurface id (0 - MAX_ISOSURFS)
@@ -1124,6 +1403,25 @@
return 1
+ def SetSliceMode(self, id, mode):
+ """!Set draw mode for slices
+
+ @param mode
+
+ @return 1 on success
+ @return -1 volume set not found
+ @return -2 on failure
+ """
+ if not GVL_vol_exists(id):
+ return -1
+
+ ret = GVL_slice_set_drawmode(id, mode)
+
+ if ret < 0:
+ return -2
+
+ return 1
+
def SetIsosurfaceRes(self, id, res):
"""!Set draw resolution for isosurfaces
@@ -1142,7 +1440,228 @@
return -2
return 1
-
+
+ def SetSliceRes(self, id, res):
+ """!Set draw resolution for slices
+
+ @param res resolution value
+
+ @return 1 on success
+ @return -1 volume set not found
+ @return -2 on failure
+ """
+ if not GVL_vol_exists(id):
+ return -1
+
+ ret = GVL_slice_set_drawres(id, res, res, res)
+
+ if ret < 0:
+ return -2
+
+ return 1
+
+ def SetSlicePosition(self, id, slice_id, x1, x2, y1, y2, z1, z2, dir):
+ """!Set slice position
+
+ @param id volume id
+ @param slice_id slice id
+ @param x1,x2,y1,y2,z1,z2 slice coordinates
+ @param dir axis
+
+ @return 1 on success
+ @return -1 volume not found
+ @return -2 slice not found
+ @return -3 on failure
+ """
+ if not GVL_vol_exists(id):
+ return -1
+
+ if slice_id > GVL_slice_num_slices(id):
+ return -2
+
+ ret = GVL_slice_set_pos(id, slice_id, x1, x2, y1, y2, z1, z2, dir)
+
+ if ret < 0:
+ return -2
+
+ return 1
+
+ def SetSliceTransp(self, id, slice_id, value):
+ """!Set slice transparency
+
+ @param id volume id
+ @param slice_id slice id
+ @param x1,x2,y1,y2,z1,z2 slice coordinates
+ @param value transparency value (0 - 255)
+
+ @return 1 on success
+ @return -1 volume not found
+ @return -2 slice not found
+ @return -3 on failure
+ """
+
+ if not GVL_vol_exists(id):
+ return -1
+
+ if slice_id > GVL_slice_num_slices(id):
+ return -2
+
+ ret = GVL_slice_set_transp(id, slice_id, value)
+
+ if ret < 0:
+ return -2
+
+ return 1
+
+ def SetIsosurfaceInOut(self, id, isosurf_id, inout):
+ """!Set inout mode
+
+ @param inout mode true/false
+
+ @return 1 on success
+ @return -1 volume set not found
+ @return -2 isosurface not found
+ @return -3 on failure
+ """
+ if not GVL_vol_exists(id):
+ return -1
+
+ if isosurf_id > GVL_isosurf_num_isosurfs(id) - 1:
+ return -2
+
+ ret = GVL_isosurf_set_flags(id, isosurf_id, inout)
+
+ if ret < 0:
+ return -3
+
+ return 1
+
+ def GetVolumePosition(self, id):
+ """!Get volume position
+
+ @param id volume id
+
+ @return x,y,z
+ @return zero-length vector on error
+ """
+ if not GVL_vol_exists(id):
+ return []
+
+ x, y, z = c_float(), c_float(), c_float()
+ GVL_get_trans(id, byref(x), byref(y), byref(z))
+
+ Debug.msg(3, "Nviz::GetVolumePosition(): id=%d, x=%f, y=%f, z=%f",
+ id, x.value, y.value, z.value)
+
+ return [x.value, y.value, z.value]
+
+ def SetVolumePosition(self, id, x, y, z):
+ """!Set volume position
+
+ @param id volume id
+ @param x,y,z translation values
+
+ @return 1 on success
+ @return -1 volume not found
+ @return -2 setting position failed
+ """
+ if not GVL_vol_exists(id):
+ return -1
+
+ Debug.msg(3, "Nviz::SetVolumePosition(): id=%d, x=%f, y=%f, z=%f",
+ id, x, y, z)
+
+ GVL_set_trans(id, x, y, z)
+
+ return 1
+
+ def GetCPlaneCurrent(self):
+ return Nviz_get_current_cplane(self.data)
+
+ def GetCPlanesCount(self):
+ """!Returns number of cutting planes"""
+ return Nviz_num_cplanes(self.data)
+
+ def GetCPlaneRotation(self):
+ """!Returns rotation parameters of current cutting plane"""
+ x, y, z = c_float(), c_float(), c_float()
+
+ current = Nviz_get_current_cplane(self.data)
+ Nviz_get_cplane_rotation(self.data, current, byref(x), byref(y), byref(z))
+
+ return x.value, y.value, z.value
+
+ def GetCPlaneTranslation(self):
+ """!Returns translation parameters of current cutting plane"""
+ x, y, z = c_float(), c_float(), c_float()
+
+ current = Nviz_get_current_cplane(self.data)
+ Nviz_get_cplane_translation(self.data, current, byref(x), byref(y), byref(z))
+
+ return x.value, y.value, z.value
+
+ def SetCPlaneRotation(self, x, y, z):
+ """!Set current clip plane rotation
+
+ @param x,y,z rotation parameters
+ """
+ current = Nviz_get_current_cplane(self.data)
+ Nviz_set_cplane_rotation(self.data, current, x, y, z)
+ Nviz_draw_cplane(self.data, -1, -1)
+
+ def SetCPlaneTranslation(self, x, y, z):
+ """!Set current clip plane translation
+
+ @param x,y,z translation parameters
+ """
+ current = Nviz_get_current_cplane(self.data)
+ Nviz_set_cplane_translation(self.data, current, x, y, z)
+ Nviz_draw_cplane(self.data, -1, -1)
+ Debug.msg(3, "Nviz::SetCPlaneTranslation(): id=%d, x=%f, y=%f, z=%f",
+ current, x, y, z)
+
+ def SetCPlaneInteractively(self, x, y):
+ current = Nviz_get_current_cplane(self.data)
+ ret = Nviz_set_cplane_here(self.data, current, x, y)
+ if ret:
+ Nviz_draw_cplane(self.data, -1, -1)
+ x, y, z = self.GetCPlaneTranslation()
+ return x, y, z
+ else:
+ return None, None, None
+
+
+ def SelectCPlane(self, index):
+ """!Select cutting plane
+
+ @param index index of cutting plane
+ """
+ Nviz_on_cplane(self.data, index)
+
+ def UnselectCPlane(self, index):
+ """!Unselect cutting plane
+
+ @param index index of cutting plane
+ """
+ Nviz_off_cplane(self.data, index)
+
+ def SetFenceColor(self, index):
+ """!Select current cutting plane
+
+ @param index type of fence - from 0 (off) to 4
+ """
+ Nviz_set_fence_color(self.data, index)
+
+ def GetXYRange(self):
+ """!Get xy range"""
+ return Nviz_get_xyrange(self.data)
+
+ def GetZRange(self):
+ """!Get z range"""
+ min, max = c_float(), c_float()
+ Nviz_get_zrange(self.data, byref(min), byref(max))
+ return min.value, max.value
+
def SaveToFile(self, filename, width = 20, height = 20, itype = 'ppm'):
"""!Save current GL screen to ppm/tif file
@@ -1167,8 +1686,12 @@
def DrawLightingModel(self):
"""!Draw lighting model"""
if self.showLight:
- GS_draw_lighting_model()
+ Nviz_draw_model(self.data)
+ def DrawFringe(self):
+ """!Draw fringe"""
+ Nviz_draw_fringe(self.data)
+
def SetFringe(self, sid, color, elev, nw = False, ne = False, sw = False, se = False):
"""!Set fringe
@@ -1178,11 +1701,49 @@
@param nw,ne,sw,se fringe edges (turn on/off)
"""
scolor = str(color[0]) + ':' + str(color[1]) + ':' + str(color[2])
-
Nviz_set_fringe(self.data,
sid, Nviz_color_from_str(scolor),
elev, int(nw), int(ne), int(sw), int(se))
+
+ def DrawArrow(self):
+ """!Draw north arrow
+ """
+ return Nviz_draw_arrow(self.data)
+ def SetArrow(self, sx, sy, size, color):
+ """!Set north arrow from canvas coordinates
+
+ @param sx,sy canvas coordinates
+ @param size arrow length
+ @param color arrow color
+ """
+ return Nviz_set_arrow(self.data, sx, sy, size, Nviz_color_from_str(color))
+
+ def DeleteArrow(self):
+ """!Delete north arrow
+ """
+ Nviz_delete_arrow(self.data)
+
+ def SetScalebar(self, id, sx, sy, size, color):
+ """!Set scale bar from canvas coordinates
+
+ @param sx,sy canvas coordinates
+ @param id scale bar id
+ @param size scale bar length
+ @param color scale bar color
+ """
+ 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 DeleteScalebar(self, id):
+ """!Delete scalebar
+ """
+ Nviz_delete_scalebar(self.data, id)
+
def GetPointOnSurface(self, sx, sy):
"""!Get point on surface
@@ -1192,7 +1753,7 @@
x = c_float()
y = c_float()
z = c_float()
- Debug.msg(5, "GLWindow.GetPointOnSurface(): sx=%d sy=%d" % (sx, sy))
+ Debug.msg(5, "Nviz::GetPointOnSurface(): sx=%d sy=%d" % (sx, sy))
num = GS_get_selected_point_on_surface(sx, sy, byref(sid), byref(x), byref(y), byref(z))
if num == 0:
return (None, None, None, None)
@@ -1228,3 +1789,246 @@
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()
+
+ def GetRotationMatrix(self):
+ """!Get rotation matrix"""
+ matrix = (c_double * 16)()
+ GS_get_rotation_matrix(byref(matrix))
+ returnMatrix = []
+ for item in matrix:
+ returnMatrix.append(item)
+ return returnMatrix
+
+ def SetRotationMatrix(self, matrix):
+ """!Set rotation matrix"""
+ mtrx = (c_double * 16)()
+ for i in range(len(matrix)):
+ mtrx[i] = matrix[i]
+ GS_set_rotation_matrix(byref(mtrx))
+
+ def Start2D(self):
+ Nviz_set_2D(self.width, self.height)
+
+ def FlyThrough(self, flyInfo, mode, exagInfo):
+ """!Fly through the scene
+
+ @param flyInfo fly parameters
+ @param mode 0 or 1 for different fly behaviour
+ @param exagInfo parameters changing fly speed
+ """
+ fly = (c_float * 3)()
+ for i, item in enumerate(flyInfo):
+ fly[i] = item
+ exag = (c_int * 2)()
+ exag[0] = int(exagInfo['move'])
+ exag[1] = int(exagInfo['turn'])
+ Nviz_flythrough(self.data, fly, exag, mode)
+
+class Texture(object):
+ """!Class representing OpenGL texture"""
+ def __init__(self, filepath, overlayId, coords):
+ """!Load image to texture
+
+ @param filepath path to image file
+ @param overlayId id of overlay (1 for legend, 101 and more for text)
+ @param coords image coordinates
+ """
+ self.path = filepath
+ self.image = wx.Image(filepath, wx.BITMAP_TYPE_ANY)
+ self.width = self.image.GetWidth()
+ self.height = self.image.GetHeight()
+ self.id = overlayId
+ self.coords = list(coords)
+ self.bounds = wx.Rect()
+ self.active = True
+
+ # alpha needs to be initialized
+ if not self.image.HasAlpha():
+ self.image.InitAlpha()
+
+ # resize image to match 2^n
+ self.Resize()
+
+ # check max texture size
+ maxSize = c_int()
+ Nviz_get_max_texture(byref(maxSize))
+ self.maxSize = maxSize.value
+ if self.maxSize < self.width or self.maxSize < self.height:
+ # TODO: split up image
+ self.textureId = None
+ else:
+ self.textureId = self.Load()
+
+ def __del__(self):
+ """!Delete texture"""
+ if self.textureId:
+ Nviz_del_texture(self.textureId)
+ grass.try_remove(self.path)
+
+ def Resize(self):
+ """!Resize image to match 2^n"""
+ n = m = 1
+ while self.width > pow(2,n):
+ n += 1
+ while self.height > pow(2,m):
+ m += 1
+ self.image.Resize(size = (pow(2,n), pow(2,m)), pos = (0, 0))
+ self.width = self.image.GetWidth()
+ self.height = self.image.GetHeight()
+
+ def Load(self):
+ """!Load image to texture"""
+ if self.image.HasAlpha():
+ bytesPerPixel = 4
+ else:
+ bytesPerPixel = 3
+ bytes = bytesPerPixel * self.width * self.height
+ rev_val = self.height - 1
+ im = (c_ubyte * bytes)()
+ bytes3 = 3 * self.width * self.height
+ bytes1 = self.width * self.height
+ imageData = struct.unpack(str(bytes3) + 'B', self.image.GetData())
+ if self.image.HasAlpha():
+ alphaData = struct.unpack(str(bytes1) + 'B', self.image.GetAlphaData())
+
+ # this takes too much time
+ wx.BeginBusyCursor()
+ for i in range(self.height):
+ for j in range(self.width):
+ im[(j + i * self.width) * bytesPerPixel + 0] = imageData[( j + (rev_val - i) * self.width) * 3 + 0]
+ im[(j + i * self.width) * bytesPerPixel + 1] = imageData[( j + (rev_val - i) * self.width) * 3 + 1]
+ im[(j + i * self.width) * bytesPerPixel + 2] = imageData[( j + (rev_val - i) * self.width) * 3 + 2]
+ if self.image.HasAlpha():
+ im[(j + i * self.width) * bytesPerPixel + 3] = alphaData[( j + (rev_val - i) * self.width)]
+ wx.EndBusyCursor()
+
+ id = Nviz_load_image(im, self.width, self.height, self.image.HasAlpha())
+
+ return id
+
+ def Draw(self):
+ """!Draw texture as an image"""
+ Nviz_draw_image(self.coords[0], self.coords[1], self.width, self.height, self.textureId)
+
+
+ def SetBounds(self, rect):
+ """!Set Bounding Rectangle"""
+ self.bounds = rect
+
+ def HitTest(self, x, y, radius):
+ copy = wx.Rect(*self.bounds)
+ copy.Inflate(radius, radius)
+ return copy.ContainsXY(x, y)
+
+ def MoveTexture(self, dx, dy):
+ """!Move texture on the screen"""
+ self.coords[0] += dx
+ self.coords[1] += dy
+ self.bounds.OffsetXY(dx, dy)
+
+ def SetCoords(self, coords):
+ """!Set coordinates"""
+ dx = coords[0] - self.coords[0]
+ dy = coords[1] - self.coords[1]
+ self.MoveTexture(dx, dy)
+
+ def GetId(self):
+ """!Returns image id."""
+ return self.id
+
+ def SetActive(self, active = True):
+ self.active = active
+
+ def IsActive(self):
+ return self.active
+
+class ImageTexture(Texture):
+ """!Class representing OpenGL texture as an overlay image"""
+ def __init__(self, filepath, overlayId, coords, cmd):
+ """!Load image to texture
+
+ @param filepath path to image file
+ @param overlayId id of overlay (1 for legend)
+ @param coords image coordinates
+ @param cmd d.legend command
+ """
+ Texture.__init__(self, filepath = filepath, overlayId = overlayId, coords = coords)
+
+ self.cmd = cmd
+
+ def GetCmd(self):
+ """!Returns overlay command."""
+ return self.cmd
+
+ def Corresponds(self, item):
+ return sorted(self.GetCmd()) == sorted(item.GetCmd())
+
+class TextTexture(Texture):
+ """!Class representing OpenGL texture as a text label"""
+ def __init__(self, filepath, overlayId, coords, textDict):
+ """!Load image to texture
+
+ @param filepath path to image file
+ @param overlayId id of overlay (101 and more for text)
+ @param coords text coordinates
+ @param textDict text properties
+ """
+ Texture.__init__(self, filepath = filepath, overlayId = overlayId, coords = coords)
+
+ self.textDict = textDict
+
+ def GetTextDict(self):
+ """!Returns text properties."""
+ return self.textDict
+
+
+ def Corresponds(self, item):
+ t = self.GetTextDict()
+ for prop in t.keys():
+ if prop in ('coords','bbox'): continue
+ if t[prop] != item[prop]:
+ return False
+
+ return True
+
Modified: grass/branches/develbranch_6/gui/wxpython/icons/icon.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/icons/icon.py 2011-11-25 14:58:21 UTC (rev 49356)
+++ grass/branches/develbranch_6/gui/wxpython/icons/icon.py 2011-11-25 15:10:47 UTC (rev 49357)
@@ -16,7 +16,7 @@
for details.
@author Martin Landa <landa.martin gmail.com>
- at author Anna Kratochvilova <anna.kratochvilova fsv.cvut.cz>
+ at author Anna Kratochvilova <kratochanna gmail.com>
"""
import os
@@ -364,30 +364,27 @@
desc = _('Settings dialog for georectification tool')),
},
'nviz' : {
- 'view' : MetaIcon(img = iconSet.get('3d-view', wx.ART_ERROR),
- label = _('Switch to view control page'),
- desc = _('Change view settings')),
- 'surface' : MetaIcon(img = iconSet.get('3d-raster', wx.ART_ERROR),
- label = _('Switch to surface (raster) control page'),
- desc = _('Change surface (loaded raster maps) settings')),
- 'vector' : MetaIcon(img = iconSet.get('3d-vector', wx.ART_ERROR),
- label = _('Switch to vector (2D/3D) control page'),
- desc = _('Change 2D/3D vector settings')),
- 'volume' : MetaIcon(img = iconSet.get('3d-volume', wx.ART_ERROR),
- label = _('Switch to volume (3D raster) control page'),
- desc = _('Change volume (loaded 3D raster maps) settings')),
- 'light' : MetaIcon(img = iconSet.get('3d-light', wx.ART_ERROR),
- label = _('Switch to lighting control page'),
- desc = _('Change lighting settings')),
- 'fringe' : MetaIcon(img = iconSet.get('3d-fringe', wx.ART_ERROR),
- label = _('Switch to fringe control page'),
- desc = _('Switch on/off fringes')),
- 'settings': MetaIcon(img = iconSet.get('settings', wx.ART_ERROR),
- label = _('3D view mode tools'),
- desc = _('Show/hide 3D view mode settings dialog')),
- 'quit' : MetaIcon(img = iconSet.get('quit', wx.ART_ERROR),
- label = _('Quit 3D view mode'),
- desc = _('Switch back to 2D view mode')),
+ 'rotate': MetaIcon(img = iconSet.get('3d-rotate', wx.ART_ERROR),
+ label = _('Rotate 3D scene'),
+ desc = _('Drag with mouse to rotate 3D scene')),
+ 'flyThrough': MetaIcon(img = iconSet.get('', wx.ART_MISSING_IMAGE),
+ label = _('Fly-through mode'),
+ desc = _('Drag with mouse, hold Ctrl down for different mode'
+ ' or Shift to accelerate')),
+ 'zoomIn': MetaIcon(img = iconSet.get('zoom-in', wx.ART_ERROR),
+ label = _('Zoom in'),
+ desc = _('Click mouse to zoom')),
+ 'zoomOut': MetaIcon(img = iconSet.get('zoom-out', wx.ART_ERROR),
+ label = _('Zoom out'),
+ desc = _('Click mouse to unzoom')),
+ 'nvizCmd': MetaIcon(img = iconSet.get('script-save', wx.ART_ERROR),
+ label = _('Generate command for m.nviz.image'),
+ desc = _('Generate command for m.nviz.image based on current state')),
+ 'settings': MetaIcon(img = iconSet.get('3d-settings', wx.ART_ERROR),
+ label = _('3D view mode settings'),
+ desc = _('Show 3D view mode settings dialog')),
+ 'help' : MetaIcon(img = iconSet.get('3d-help', wx.ART_ERROR),
+ label = _('Show 3D view mode manual')),
},
'modeler' : {
'new' : MetaIcon(img = iconSet.get('create', wx.ART_ERROR),
Modified: grass/branches/develbranch_6/gui/wxpython/wxgui.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/wxgui.py 2011-11-25 14:58:21 UTC (rev 49356)
+++ grass/branches/develbranch_6/gui/wxpython/wxgui.py 2011-11-25 15:10:47 UTC (rev 49357)
@@ -77,7 +77,8 @@
from gui_modules import nviz_tools
from gui_modules.debug import Debug
from gui_modules.ghelp import MenuTreeWindow, AboutWindow, InstallExtensionWindow
-from gui_modules.toolbars import LMWorkspaceToolbar, LMDataToolbar, LMToolsToolbar, LMMiscToolbar, LMVectorToolbar
+from gui_modules.toolbars import LMWorkspaceToolbar, LMDataToolbar, LMToolsToolbar,\
+ LMMiscToolbar, LMVectorToolbar, LMNvizToolbar
from gui_modules.gpyshell import PyShellWindow
from icons.icon import Icons
@@ -113,6 +114,7 @@
self.workspaceChanged = False # track changes in workspace
self.georectifying = None # reference to GCP class or None
self.gcpmanagement = None # reference to GCP class or None
+
# list of open dialogs
self.dialogs = dict()
self.dialogs['preferences'] = None
@@ -126,7 +128,8 @@
'data' : LMDataToolbar(parent = self),
'tools' : LMToolsToolbar(parent = self),
'misc' : LMMiscToolbar(parent = self),
- 'vector' : LMVectorToolbar(parent = self) }
+ 'vector' : LMVectorToolbar(parent = self),
+ 'nviz' : LMNvizToolbar(parent = self)}
self._toolbarsData = { 'workspace' : ("toolbarWorkspace", # name
_("Workspace Toolbar"), # caption
@@ -143,13 +146,16 @@
'vector' : ("toolbarVector",
_("Vector Toolbar"),
2),
+ 'nviz' : ("toolbarNviz",
+ _("3D view Toolbar"),
+ 2),
}
if sys.platform == 'win32':
self._toolbarsList = ('workspace', 'data',
- 'vector', 'tools', 'misc')
+ 'vector', 'tools', 'misc', 'nviz')
else:
self._toolbarsList = ('data', 'workspace',
- 'misc', 'tools', 'vector')
+ 'nviz', 'misc', 'tools', 'vector')
for toolbar in self._toolbarsList:
name, caption, row = self._toolbarsData[toolbar]
self._auimgr.AddPane(self.toolbars[toolbar],
@@ -161,6 +167,7 @@
CloseButton(False).Layer(2).
BestSize((self.toolbars[toolbar].GetBestSize())))
+ self._auimgr.GetPane('toolbarNviz').Hide()
# bindings
self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
@@ -231,7 +238,13 @@
def _setCopyingOfSelectedText(self):
copy = UserSettings.Get(group = 'manager', key = 'copySelectedTextToClipboard', subkey = 'enabled')
self.goutput.SetCopyingOfSelectedText(copy)
-
+
+ def IsPaneShown(self, name):
+ """!Check if pane (toolbar, ...) of given name is currently shown"""
+ if self._auimgr.GetPane(name).IsOk():
+ return self._auimgr.GetPane(name).IsShown()
+ return False
+
def _createNoteBook(self):
"""!Creates notebook widgets"""
self.notebook = menuform.GNotebook(parent = self, style = globalvar.FNPageDStyle)
@@ -270,20 +283,36 @@
return self.notebook
- def AddNviz(self):
+ def AddNvizTools(self):
"""!Add nviz notebook page"""
+ Debug.msg(5, "GMFrame.AddNvizTools()")
+ # show toolbar
+ self._auimgr.GetPane('toolbarNviz').Show()
+ # reorder other toolbars
+ for pos, toolbar in enumerate(('toolbarVector', 'toolbarTools', 'toolbarMisc','toolbarNviz')):
+ self._auimgr.GetPane(toolbar).Row(2).Position(pos)
+ self._auimgr.Update()
+
+ # create nviz tools tab
self.nviz = nviz_tools.NvizToolWindow(parent = self,
- display = self.curr_page.maptree.GetMapDisplay())
- self.notebook.AddPage(page = self.nviz, text = _("3D view"), name = 'nviz')
+ display = self.curr_page.maptree.GetMapDisplay())
+ idx = self.notebook.GetPageIndexByName('layers')
+ self.notebook.InsertPage(indx = idx + 1, page = self.nviz, text = _("3D view"), name = 'nviz')
self.notebook.SetSelectionByName('nviz')
- def RemoveNviz(self):
+
+ def RemoveNvizTools(self):
"""!Remove nviz notebook page"""
- # print self.notebook.GetPage(1)
+ # if more mapwindow3D were possible, check here if nb page should be removed
+ self.notebook.SetSelectionByName('layers')
self.notebook.RemovePage(self.notebook.GetPageIndexByName('nviz'))
del self.nviz
- self.notebook.SetSelectionByName('layers')
-
+ # hide toolbar
+ self._auimgr.GetPane('toolbarNviz').Hide()
+ for pos, toolbar in enumerate(('toolbarVector', 'toolbarTools', 'toolbarMisc')):
+ self._auimgr.GetPane(toolbar).Row(2).Position(pos)
+ self._auimgr.Update()
+
def WorkspaceChanged(self):
"""!Update window title"""
if not self.workspaceChanged:
@@ -745,7 +774,7 @@
return
Debug.msg(4, "GMFrame.OnWorkspaceOpen(): filename=%s" % filename)
-
+
# delete current layer tree content
self.OnWorkspaceClose()
@@ -869,9 +898,23 @@
# reverse list of map layers
maptree.Map.ReverseListOfLayers()
- for mdisp in mapdisplay:
+ for idx, mdisp in enumerate(mapdisplay):
mdisp.MapWindow2D.UpdateMap()
+ #nviz
+ if gxwXml.displays[idx]['viewMode'] == '3d':
+ mdisp.AddNviz()
+ self.nviz.UpdateState(view = gxwXml.nviz_state['view'],
+ iview = gxwXml.nviz_state['iview'],
+ light = gxwXml.nviz_state['light'])
+ mdisp.MapWindow3D.constants = gxwXml.nviz_state['constants']
+ for idx, constant in enumerate(mdisp.MapWindow3D.constants):
+ mdisp.MapWindow3D.AddConstant(constant, idx + 1)
+ for page in ('view', 'light', 'fringe', 'constant', 'cplane'):
+ self.nviz.UpdatePage(page)
+ self.nviz.UpdateSettings()
+ mapdisp.toolbars['map'].combo.SetSelection(1)
+
return True
def OnWorkspaceLoadGrcFile(self, event):
@@ -1277,6 +1320,23 @@
# show ATM window
dbmanager.Show()
+ def OnNewDisplayWMS(self, event = None):
+ """!Create new layer tree and map display instance"""
+ self.NewDisplayWMS()
+
+ def NewDisplayWMS(self, show = True):
+ Debug.msg(1, "GMFrame.NewDisplay(): idx=%d" % self.disp_idx)
+ try:
+ from gui_modules.wms.wmsmenu import DisplayWMSMenu
+ except:
+ gcmd.GError(parent = self.parent,
+ message = _("Experimental WMS support for wxGUI not available. "
+ "You can install it by '%s'") % \
+ "g.extension -s extension=wx.wms")
+ return
+
+ DisplayWMSMenu()
+
def OnNewDisplay(self, event = None):
"""!Create new layer tree and map display instance"""
self.NewDisplay()
Modified: grass/branches/develbranch_6/include/gstypes.h
===================================================================
--- grass/branches/develbranch_6/include/gstypes.h 2011-11-25 14:58:21 UTC (rev 49356)
+++ grass/branches/develbranch_6/include/gstypes.h 2011-11-25 15:10:47 UTC (rev 49357)
@@ -326,12 +326,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/branches/develbranch_6/include/nviz.h
===================================================================
--- grass/branches/develbranch_6/include/nviz.h 2011-11-25 14:58:21 UTC (rev 49356)
+++ grass/branches/develbranch_6/include/nviz.h 2011-11-25 15:10:47 UTC (rev 49357)
@@ -84,6 +84,21 @@
int where[4];
};
+struct arrow_data
+{
+ unsigned long color;
+ float size;
+ float where[3];
+};
+
+struct scalebar_data
+{
+ int id;
+ unsigned long color;
+ float size;
+ float where[3];
+};
+
typedef struct
{
/* ranges */
@@ -101,7 +116,15 @@
/* fringe */
int num_fringes;
struct fringe_data **fringe;
+
+ /* north arrow */
+ int draw_arrow;
+ struct arrow_data *arrow;
+ /* scalebar */
+ int num_scalebars;
+ struct scalebar_data **scalebar;
+
/* background color */
int bgcolor;
@@ -129,16 +152,34 @@
int Nviz_resize_window(int, int);
int Nviz_update_ranges(nv_data *);
int Nviz_set_viewpoint_position(double, double);
+void Nviz_get_viewpoint_position(double *, double *);
int Nviz_set_viewpoint_height(double);
+void Nviz_get_viewpoint_height(double *);
int Nviz_set_viewpoint_persp(int);
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);
+void Nviz_flythrough(nv_data *, float *, int *, int);
/* cplanes_obj.c */
int Nviz_new_cplane(nv_data *, int);
+int Nviz_on_cplane(nv_data *, int);
int Nviz_off_cplane(nv_data *, int);
int Nviz_draw_cplane(nv_data *, int, int);
+int Nviz_num_cplanes(nv_data *);
+int Nviz_get_current_cplane(nv_data *);
+int Nviz_set_cplane_rotation(nv_data *, int, float, float, float);
+int Nviz_get_cplane_rotation(nv_data *, int, float *, float *, float *);
+int Nviz_set_cplane_translation(nv_data *, int, float, float, float);
+int Nviz_get_cplane_translation(nv_data *, int, float *, float *, float *);
+int Nviz_set_fence_color(nv_data *, int);
+int Nviz_set_cplane_here(nv_data *, int, float, float);
+
/* draw.c */
int Nviz_draw_all_surf(nv_data *);
int Nviz_draw_all_vect();
@@ -146,6 +187,11 @@
int Nviz_draw_all_vol();
int Nviz_draw_all(nv_data *);
int Nviz_draw_quick(nv_data *, int);
+int Nviz_load_image(GLubyte *, int, int, int);
+void Nviz_draw_image(int, int, int, int, int);
+void Nviz_set_2D(int, int);
+void Nviz_del_texture(int);
+void Nviz_get_max_texture(int *);
/* exag.c */
int Nviz_get_exag_height(double *, double *, double *);
@@ -158,6 +204,7 @@
int Nviz_set_light_ambient(nv_data *, int, double);
int Nviz_init_light(nv_data *, int);
int Nviz_new_light(nv_data *);
+void Nviz_draw_model(nv_data *);
/* map_obj.c */
int Nviz_new_map_obj(int, const char *, double, nv_data *);
@@ -177,11 +224,25 @@
double, int, int, int, int);
struct fringe_data *Nviz_set_fringe(nv_data *, int, unsigned long,
double, int, int, int, int);
+void Nviz_draw_fringe(nv_data *data);
+int Nviz_draw_arrow(nv_data *);
+int Nviz_set_arrow(nv_data *, int, int, float, unsigned int);
+void Nviz_delete_arrow(nv_data *);
+struct scalebar_data * Nviz_new_scalebar(nv_data *, int, float *, float, unsigned int);
+struct scalebar_data * Nviz_set_scalebar(nv_data *, int , int, int, float, unsigned int);
+void Nviz_draw_scalebar(nv_data *);
+void Nviz_delete_scalebar(nv_data *, int);
/* position.c */
void Nviz_init_view(nv_data *);
int Nviz_set_focus_state(int);
int Nviz_set_focus_map(int, int);
+int Nviz_has_focus(nv_data *);
+int Nviz_set_focus(nv_data *, float, float, float);
+int Nviz_get_focus(nv_data *, float *, float *, float *);
+float Nviz_get_xyrange(nv_data *);
+int Nviz_get_zrange(nv_data *, float *, float *);
+float Nviz_get_longdim(nv_data *);
/* render.c */
struct render_window *Nviz_new_render_window();
Modified: grass/branches/develbranch_6/include/ogsf_proto.h
===================================================================
--- grass/branches/develbranch_6/include/ogsf_proto.h 2011-11-25 14:58:21 UTC (rev 49356)
+++ grass/branches/develbranch_6/include/ogsf_proto.h 2011-11-25 15:10:47 UTC (rev 49357)
@@ -86,6 +86,8 @@
int GS_surf_exists(int);
int GS_new_surface(void);
int GS_new_light(void);
+void GS_set_light_reset(int);
+int GS_get_light_reset(void);
void GS_setlight_position(int, float, float, float, int);
void GS_setlight_color(int, float, float, float);
void GS_setlight_ambient(int, float, float, float);
@@ -166,6 +168,11 @@
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_get_rotation_matrix(double *);
+void GS_set_rotation_matrix(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);
@@ -583,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/branches/develbranch_6/lib/nviz/change_view.c
===================================================================
--- grass/branches/develbranch_6/lib/nviz/change_view.c 2011-11-25 14:58:21 UTC (rev 49356)
+++ grass/branches/develbranch_6/lib/nviz/change_view.c 2011-11-25 15:10:47 UTC (rev 49357)
@@ -12,6 +12,8 @@
\author Updated/modified by Martin Landa <landa.martin gmail.com> (Google SoC 2008/2010)
*/
+#include <math.h>
+
#include <grass/glocale.h>
#include <grass/nviz.h>
@@ -125,6 +127,25 @@
return 1;
}
+void Nviz_get_viewpoint_position(double *x_pos, double *y_pos)
+{
+ float from[3];
+ double xpos, ypos;
+
+ GS_get_from(from);
+ xpos = (from[X] + RANGE_OFFSET) / RANGE;
+ ypos = (from[Y] + RANGE_OFFSET) / RANGE;
+ *x_pos = xpos;
+ *x_pos = (*x_pos < 0) ? 0 : (*x_pos > 1.0) ? 1.0 : *x_pos;
+ *y_pos = 1.0 - ypos;
+ *y_pos = (*y_pos < 0) ? 0 : (*y_pos > 1.0) ? 1.0 : *y_pos;
+
+ if (xpos < 0.0 || xpos > 1.0 || ypos < 0.0 || ypos > 1.0) {
+ G_debug(3, "Invalid view position coordinates, using %f,%f",
+ *x_pos, 1.0 - *y_pos);
+ }
+}
+
/*!
\brief Change viewpoint height
@@ -157,6 +178,16 @@
return 1;
}
+void Nviz_get_viewpoint_height(double *height)
+{
+ float from[3];
+
+ G_debug(1, "Nviz_get_viewpoint_height():");
+
+ GS_get_from_real(from);
+
+ *height = from[Z];
+}
/*!
\brief Change viewpoint perspective (field of view)
@@ -221,3 +252,127 @@
return 1;
}
+/*!
+ \brief Change focused point
+
+ \param sx,sy screen coordinates
+
+ \return 1
+*/
+int Nviz_look_here(double sx, double sy)
+{
+ G_debug(1, "Nviz_look_here(): screen coordinates = %f %f", sx, sy);
+ GS_look_here(sx, sy);
+ 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();
+}
+
+/*!
+ \brief Fly through the scene
+
+ Computes parameters needed for moving scene.
+ Changes viewpoint and viewdir.
+ Based on visualization/nviz/src/togl_flythrough.c and simplified.
+
+ \param fly_info values computed from mouse movement
+ \param scale rate of movement
+ \param lateral type of movement
+
+*/
+void Nviz_flythrough(nv_data *data, float *fly_info, int *scale, int lateral)
+{
+ float dir[3], from[4], cur_from[4], cur_dir[4];
+ float speed, h, p, sh, ch, sp, cp;
+ float diff_x, diff_y, diff_z;
+ float quasi_zero;
+
+ quasi_zero = 0.0001;
+
+ GS_get_from(cur_from);
+ GS_get_viewdir(cur_dir);
+
+ p = asin(cur_dir[Z]);
+ h = atan2(- cur_dir[X], - cur_dir[Y]);
+
+ speed = scale[0] * fly_info[0];
+
+ h += scale[1] * fly_info[1]; /* change heading */
+ if (!lateral) /* in case of "lateral" doesn't change pitch */
+ p -= scale[1] * fly_info[2];
+
+ h = fmod(h + M_PI, 2 * M_PI) - M_PI;
+
+ sh = sin(h);
+ ch = cos(h);
+ sp = sin(p);
+ cp = cos(p);
+
+ dir[X] = -sh * cp;
+ dir[Y] = -ch * cp;
+ dir[Z] = sp;
+
+ if (lateral) {
+ from[X] = cur_from[X] + speed * dir[Y];
+ from[Y] = cur_from[Y] - speed * dir[X];
+ from[Z] = cur_from[Z] + scale[0] * fly_info[2];
+ }
+ else {
+ from[X] = cur_from[X] + speed * dir[X];
+ from[Y] = cur_from[Y] + speed * dir[Y];
+ /* not sure how this should behave (change Z coord or not ?)*/
+ from[Z] = cur_from[Z]; /* + speed * dir[Z]*/
+ }
+
+ diff_x = fabs(cur_dir[X] - dir[X]);
+ diff_y = fabs(cur_dir[Y] - dir[Y]);
+ diff_z = fabs(cur_dir[Z] - dir[Z]);
+
+ if ( /* something has changed */
+ (diff_x > quasi_zero) || (diff_y > quasi_zero) ||
+ (diff_z > quasi_zero) || (cur_from[X] != from[X]) ||
+ (cur_from[Y] != from[Y]) || (cur_from[Z] != from[Z])
+ ) {
+ GS_moveto(from);
+ GS_set_viewdir(dir); /* calls gsd_set_view */
+ }
+}
Modified: grass/branches/develbranch_6/lib/nviz/cplanes_obj.c
===================================================================
--- grass/branches/develbranch_6/lib/nviz/cplanes_obj.c 2011-11-25 14:58:21 UTC (rev 49356)
+++ grass/branches/develbranch_6/lib/nviz/cplanes_obj.c 2011-11-25 15:10:47 UTC (rev 49357)
@@ -15,6 +15,7 @@
#include <grass/nviz.h>
static void cp_draw(nv_data *, int, int, int);
+static geoview Gv;
/*!
\brief Creates a clip plane object
@@ -36,6 +37,21 @@
}
/*!
+ \brief Turn on (make current) the given clip plane.
+
+ \param data nviz data
+ \param cplane id
+ */
+int Nviz_on_cplane(nv_data * data, int id)
+{
+ data->cur_cplane = id;
+ data->cp_on[id] = 1;
+ GS_set_cplane(id);
+
+ return 1;
+}
+
+/*!
\brief Turn off (make inactive) the given clip plane
\param data nviz data
@@ -118,3 +134,153 @@
return;
}
+/*!
+ \brief Return the number of clip planes objects currently allocated.
+
+ \param data nviz data
+ */
+int Nviz_num_cplanes(nv_data * data)
+{
+ return data->num_cplanes;
+}
+
+/*!
+ \brief Get the current active cutplane.
+
+ \param data nviz data
+ */
+int Nviz_get_current_cplane(nv_data * data)
+{
+ return data->cur_cplane;
+}
+
+/*!
+ \brief Set the rotation for the current clip plane.
+
+ \param data nviz data
+ \param id id of current clip plane
+ \param dx,dy,dz rotation parameters
+
+ \return 1
+
+ */
+int Nviz_set_cplane_rotation(nv_data * data, int id, float dx, float dy, float dz)
+{
+ data->cp_rot[id][X] = dx;
+ data->cp_rot[id][Y] = dy;
+ data->cp_rot[id][Z] = dz;
+ GS_set_cplane_rot(id, data->cp_rot[id][X], data->cp_rot[id][Y],
+ data->cp_rot[id][Z]);
+
+ cp_draw(data, data->cur_cplane, -1, -1);
+
+ return 1;
+}
+/*!
+ \brief Get the rotation values for the current clip plane.
+
+ \param data nviz data
+ \param id id of current clip plane
+ \param dx,dy,dz rotation parameters
+
+ \return 1
+
+ */
+int Nviz_get_cplane_rotation(nv_data * data, int id, float *dx, float *dy, float *dz)
+{
+ *dx = data->cp_rot[id][X];
+ *dy = data->cp_rot[id][Y];
+ *dz = data->cp_rot[id][Z];
+
+ return 1;
+}
+
+/*!
+ \brief Set the translation for the current clip plane.
+
+ \param data nviz data
+ \param id id of current clip plane
+ \param dx,dy,dz values for setting translation
+
+ \return 1
+ */
+int Nviz_set_cplane_translation(nv_data * data, int id, float dx, float dy, float dz)
+{
+ data->cp_trans[id][X] = dx;
+ data->cp_trans[id][Y] = dy;
+ data->cp_trans[id][Z] = dz;
+ GS_set_cplane_trans(id, data->cp_trans[id][X], data->cp_trans[id][Y],
+ data->cp_trans[id][Z]);
+
+ cp_draw(data, data->cur_cplane, -1, -1);
+
+ return 1;
+}
+/*!
+ \brief Get the translation values for the current clip plane.
+
+ \param data nviz data
+ \param id id of current clip plane
+ \param dx,dy,dz translation parameters
+ */
+int Nviz_get_cplane_translation(nv_data * data, int id, float *dx, float *dy, float *dz)
+{
+ *dx = data->cp_trans[id][X];
+ *dy = data->cp_trans[id][Y];
+ *dz = data->cp_trans[id][Z];
+
+ return 1;
+}
+/*!
+ \brief Set appropriate fence color
+
+ \param type type of fence (FC_ABOVE, FC_BELOW, FC_BLEND, FC_GREY, FC_OFF)
+ */
+int Nviz_set_fence_color(nv_data * data, int type)
+{
+ GS_set_fencecolor(type);
+
+ return 1;
+
+}
+int Nviz_set_cplane_here(nv_data *data, int cplane, float sx, float sy)
+{
+ float x, y, z, len, los[2][3];
+ float dx, dy, dz;
+ float n, s, w, e;
+ Point3 realto, dir;
+ int id;
+ geosurf *gs;
+
+ if (GS_get_selected_point_on_surface(sx, sy, &id, &x, &y, &z)) {
+ gs = gs_get_surf(id);
+ if (gs) {
+ realto[X] = x - gs->ox + gs->x_trans;
+ realto[Y] = y - gs->oy + gs->y_trans;
+ realto[Z] = z + gs->z_trans;
+ }
+ else
+ return 0;
+ }
+ else {
+ if (gsd_get_los(los, (short)sx, (short)sy)) {
+ len = GS_distance(Gv.from_to[FROM], Gv.real_to);
+ GS_v3dir(los[FROM], los[TO], dir);
+ GS_v3mult(dir, len);
+ realto[X] = Gv.from_to[FROM][X] + dir[X];
+ realto[Y] = Gv.from_to[FROM][Y] + dir[Y];
+ realto[Z] = Gv.from_to[FROM][Z] + dir[Z];
+ }
+ else
+ return 0;
+ }
+ Nviz_get_cplane_translation(data, cplane, &dx, &dy, &dz);
+
+ GS_get_region(&n, &s, &w, &e);
+ dx = realto[X] - (e - w) / 2.;
+ dy = realto[Y] - (n - s) / 2.;
+
+ Nviz_set_cplane_translation(data, cplane, dx, dy, dz);
+
+ return 1;
+}
Modified: grass/branches/develbranch_6/lib/nviz/draw.c
===================================================================
--- grass/branches/develbranch_6/lib/nviz/draw.c 2011-11-25 14:58:21 UTC (rev 49356)
+++ grass/branches/develbranch_6/lib/nviz/draw.c 2011-11-25 15:10:47 UTC (rev 49357)
@@ -6,15 +6,20 @@
Based on visualization/nviz/src/draw.c and
visualization/nviz/src/togl_flythrough.c
- (C) 2008, 2010 by the GRASS Development Team
+ (C) 2008, 2010-2011 by the GRASS Development Team
This program is free software under the GNU General Public License
(>=v2). Read the file COPYING that comes with GRASS for details.
\author Updated/modified by Martin Landa <landa.martin gmail.com> (Google SoC 2008/2010)
+ \author Textures by Anna Kratochvilova
*/
#include <grass/nviz.h>
+#ifndef GL_CLAMP_TO_EDGE
+#define GL_CLAMP_TO_EDGE 0x812F
+#endif
+
static int sort_surfs_max(int *, int *, int *, int);
/*!
@@ -232,11 +237,23 @@
if (draw_vol)
Nviz_draw_all_vol(data);
-
+
for(i = 0; i < data->num_fringes; i++) {
struct fringe_data * f = data->fringe[i];
GS_draw_fringe(f->id, f->color, f->elev, f->where);
}
+
+ /* North Arrow */
+ if (data->draw_arrow) {
+ gsd_north_arrow(data->arrow->where, data->arrow->size,
+ (GLuint)NULL, data->arrow->color, data->arrow->color);
+ }
+
+ /* scale bar */
+ for (i = 0; i < data->num_scalebars; i++) {
+ struct scalebar_data *s = data->scalebar[i];
+ gsd_scalebar_v2(s->where, s->size, 0, s->color, s->color);
+ }
GS_done_draw();
GS_set_draw(GSD_BACK);
@@ -287,3 +304,119 @@
return 1;
}
+
+/*!
+ \brief Load image into texture
+
+ \param image_data image data
+ \param width, height image screen size
+ \param alpha has alpha channel
+*/
+int Nviz_load_image(GLubyte *image_data, int width, int height, int alpha)
+{
+ unsigned int texture_id;
+ int in_format;
+ GLenum format;
+
+ if (alpha)
+ {
+ in_format = 4;
+ format = GL_RGBA;
+ }
+ else
+ {
+ in_format = 3;
+ format = GL_RGB;
+ }
+ glGenTextures( 1, &texture_id);
+ glBindTexture(GL_TEXTURE_2D, texture_id);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+ glTexImage2D(GL_TEXTURE_2D, 0, in_format, width, height, 0,format,
+ GL_UNSIGNED_BYTE, image_data);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+
+ return texture_id;
+}
+
+/*!
+ \brief Set ortho view for drawing images
+
+ \param width, height image screen size
+*/
+void Nviz_set_2D(int width, int height)
+{
+ glEnable(GL_BLEND); // images are transparent
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0, width, 0, height, -1, 1);
+
+ // set coordinate system from upper left corner
+ glScalef(1, -1, 1);
+ glTranslatef(0, -height, 0);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+}
+
+/*!
+ \brief Draw image as texture
+
+ \param x, y image coordinates
+ \param width, height image size
+ \param texture_id texture id
+*/
+void Nviz_draw_image(int x, int y, int width, int height, int texture_id)
+{
+ glBindTexture(GL_TEXTURE_2D, texture_id);
+ GS_set_draw(GSD_FRONT);
+
+ glEnable(GL_TEXTURE_2D);
+
+ glBegin(GL_QUADS);
+
+ glTexCoord2d(0.0,1.0);
+ glVertex2d(x, y);
+ glTexCoord2d(0.0,0.0);
+ glVertex2d(x, y + height);
+ glTexCoord2d(1.0,0.0);
+ glVertex2d(x + width, y + height);
+ glTexCoord2d(1.0,1.0);
+ glVertex2d(x + width, y);
+
+ glEnd();
+
+ GS_done_draw();
+ glDisable(GL_TEXTURE_2D);
+}
+
+/*!
+ \brief Delete texture
+
+ \param texture_id texture id
+*/
+void Nviz_del_texture(int texture_id)
+{
+ GLuint t[1];
+
+ t[0] = texture_id;
+ glDeleteTextures(1, t);
+}
+
+/*!
+ \brief Get maximum texture size
+
+*/
+void Nviz_get_max_texture(int *size)
+{
+ glGetIntegerv(GL_MAX_TEXTURE_SIZE, size);
+}
Modified: grass/branches/develbranch_6/lib/nviz/lights.c
===================================================================
--- grass/branches/develbranch_6/lib/nviz/lights.c 2011-11-25 14:58:21 UTC (rev 49356)
+++ grass/branches/develbranch_6/lib/nviz/lights.c 2011-11-25 15:10:47 UTC (rev 49357)
@@ -39,16 +39,16 @@
x, y, xpos, 1.0 - ypos);
}
*/
- num--;
- data->light[num].id = num + 1;
+
+ data->light[num].id = num;
data->light[num].x = x;
data->light[num].y = y;
data->light[num].z = z;
data->light[num].w = w;
G_debug(1, "Nviz_set_light_position(): num = %d x = %f y = %f z = %f w = %f",
- num + 1, x, y, z, w);
- GS_setlight_position(num + 1, x, y, z, w);
+ num, x, y, z, w);
+ GS_setlight_position(num, x, y, z, w);
return 1;
}
@@ -64,7 +64,6 @@
{
double r, g, b;
- num--;
data->light[num].brt = value;
r = data->light[num].r * data->light[num].brt;
@@ -72,8 +71,8 @@
b = data->light[num].b * data->light[num].brt;
G_debug(1, "Nviz_set_light_bright(): num = %d value = %f r = %f g = %f b = %f",
- num + 1, value, r, g, b);
- GS_setlight_color(num + 1, r, g, b);
+ num, value, r, g, b);
+ GS_setlight_color(num, r, g, b);
return 1;
}
@@ -90,7 +89,6 @@
{
double r, g, b;
- num--;
data->light[num].r = red / 255.;
data->light[num].g = green / 255.;
data->light[num].b = blue / 255.;
@@ -100,8 +98,8 @@
b = data->light[num].b * data->light[num].brt;
G_debug(1, "Nviz_set_light_color(): num = %d r = %d/%f g = %d/%f b = %d/%f",
- num + 1, red, r, green, g, blue, b);
- GS_setlight_color(num + 1, r, g, b);
+ num, red, r, green, g, blue, b);
+ GS_setlight_color(num, r, g, b);
return 1;
}
@@ -115,14 +113,13 @@
*/
int Nviz_set_light_ambient(nv_data * data, int num, double value)
{
- num--;
data->light[num].ar = value;
data->light[num].ag = value;
data->light[num].ab = value;
G_debug(1, "Nviz_set_light_ambient(): num = %d value = %f",
- num + 1, value);
- GS_setlight_ambient(num + 1, value, value, value);
+ num, value);
+ GS_setlight_ambient(num, value, value, value);
return 1;
}
@@ -135,8 +132,8 @@
*/
int Nviz_init_light(nv_data * data, int num)
{
- num--;
- if (num >= MAX_LIGHTS) {
+ G_debug(1, "Nviz_init_light(): num = %d", num);
+ if (num > MAX_LIGHTS) {
return 0;
}
@@ -180,3 +177,16 @@
return 1;
}
+/*!
+ \brief Draw lighting model
+
+ \param data nviz data
+*/
+void Nviz_draw_model(nv_data * data)
+{
+ GS_set_draw(GSD_FRONT);
+ GS_ready_draw();
+ GS_draw_lighting_model();
+ GS_done_draw();
+ GS_set_draw(GSD_BACK);
+}
Modified: grass/branches/develbranch_6/lib/nviz/nviz.c
===================================================================
--- grass/branches/develbranch_6/lib/nviz/nviz.c 2011-11-25 14:58:21 UTC (rev 49356)
+++ grass/branches/develbranch_6/lib/nviz/nviz.c 2011-11-25 15:10:47 UTC (rev 49357)
@@ -37,14 +37,24 @@
}
/* lights */
- for (i = 0; i < MAX_LIGHTS; i++) {
+ GS_set_light_reset(1);
+
+ for (i = 0; i < MAX_LIGHTS - 1; i++) {
Nviz_new_light(data);
}
/* fringe */
data->num_fringes = 0;
data->fringe = NULL;
-
+
+ /* north arrow */
+ data->draw_arrow = 0;
+ data->arrow = NULL;
+
+ /* scale bar*/
+ data->num_scalebars = 0;
+ data->scalebar = NULL;
+
return;
}
@@ -61,6 +71,19 @@
}
data->num_fringes = 0;
data->fringe = NULL;
+
+ if (data->arrow) {
+ G_free(data->arrow);
+ data->arrow = NULL;
+ data->draw_arrow = 0;
+ }
+
+ for (i = 0; data->num_scalebars; i++) {
+ G_free(data->scalebar[i]);
+ data->scalebar[i] = NULL;
+ }
+ data->num_scalebars = 0;
+ data->scalebar = NULL;
}
/*!
@@ -134,6 +157,7 @@
if (num < 1)
return NULL;
id = surf[0];
+ G_free(surf);
}
@@ -177,6 +201,7 @@
if (num < 1)
return NULL;
id = surf[0];
+ G_free(surf);
}
for (i = 0; i < data->num_fringes; i++) {
@@ -199,3 +224,211 @@
return f;
}
+/*! Draw fringe
+
+ \param data nviz data
+ */
+void Nviz_draw_fringe(nv_data *data)
+{
+ int i;
+
+ for (i = 0; i < data->num_fringes; i++) {
+ struct fringe_data *f = data->fringe[i];
+
+ GS_draw_fringe(f->id, f->color, f->elev, f->where);
+ }
+}
+/*!
+ \brief Sets the North Arrow position and return world coords
+
+ \param data nviz data
+ \param sx,sy screen coordinates
+ \param size arrow length
+ \param color arrow/text color
+ */
+int Nviz_set_arrow(nv_data *data,
+ int sx, int sy, float size,
+ unsigned int color)
+{
+ int id, pt[2];
+ int *surf_list, num_surfs;
+ float coords[3];
+ struct arrow_data *arw;
+
+ if (GS_num_surfs() > 0) {
+ surf_list = GS_get_surf_list(&num_surfs);
+ id = surf_list[0];
+ G_free(surf_list);
+
+ pt[0] = sx;
+ pt[1] = sy;
+
+ GS_set_Narrow(pt, id, coords);
+
+ if (data->arrow) {
+ data->arrow->color = color;
+ data->arrow->size = size;
+ data->arrow->where[0] = coords[0];
+ data->arrow->where[1] = coords[1];
+ data->arrow->where[2] = coords[2];
+ }
+ else {
+ arw = (struct arrow_data *) G_malloc(sizeof(struct arrow_data));
+ arw->color = color;
+ arw->size = size;
+ arw->where[0] = coords[0];
+ arw->where[1] = coords[1];
+ arw->where[2] = coords[2];
+
+ data->arrow = arw;
+ }
+ return 1;
+ }
+ return 0;
+}
+
+
+/*!
+ \brief Draws the North Arrow
+
+ \param data nviz data
+ */
+int Nviz_draw_arrow(nv_data *data)
+{
+
+ struct arrow_data *arw = data->arrow;
+ GLuint FontBase = 0; /* don't know how to get fontbase*/
+
+ data->draw_arrow = 1;
+ gsd_north_arrow(arw->where, arw->size, FontBase, arw->color, arw->color);
+
+ return 1;
+}
+
+/*!
+ \brief Deletes the North Arrow
+
+ \param data nviz data
+ */
+void Nviz_delete_arrow(nv_data *data)
+{
+ data->draw_arrow = 0;
+
+ return;
+}
+
+/*! Add new scalebar
+
+ \param data nviz data
+ \param bar_id scale bar id
+ \param coords real(?) coordinates
+ \param size scale bar length
+ \param color scalebar/text color
+
+ \return pointer to allocated scalebar_data structure
+ \return NULL on error
+*/
+
+struct scalebar_data *Nviz_new_scalebar(nv_data *data,
+ int bar_id, float *coords, float size,
+ unsigned int color)
+{
+ struct scalebar_data *s;
+
+
+ s = (struct scalebar_data *) G_malloc(sizeof(struct scalebar_data));
+ s->id = bar_id;
+ s->color = color;
+ s->size = size;
+ s->where[0] = coords[0];
+ s->where[1] = coords[1];
+ s->where[2] = coords[2];
+
+ data->scalebar = (struct scalebar_data **) G_realloc(data->scalebar,
+ data->num_scalebars + 1 * sizeof(struct scalebar_data *));
+ data->scalebar[data->num_scalebars++] = s;
+
+ return s;
+
+}
+/*!
+ \brief Sets the scale bar position and return world coords
+
+ \param data nviz data
+ \param bar_id scale bar id
+ \param sx,sy screen coordinates
+ \param size scale bar length
+ \param color scalebar/text color
+
+ \return pointer to allocated scalebar_data structure
+ \return NULL when there's no surface
+ */
+struct scalebar_data *Nviz_set_scalebar(nv_data *data, int bar_id,
+ int sx, int sy, float size,
+ unsigned int color)
+{
+ int i, id, pt[2];
+ int *surf_list, num_surfs;
+ float coords[3];
+ struct scalebar_data *s;
+
+ if (GS_num_surfs() > 0) {
+ surf_list = GS_get_surf_list(&num_surfs);
+ id = surf_list[0];
+ G_free(surf_list);
+
+ pt[0] = sx;
+ pt[1] = sy;
+
+ GS_set_Narrow(pt, id, coords); /* the same like arrow */
+
+ for (i = 0; i < data->num_scalebars; i++) {
+ s = data->scalebar[i];
+ if (s->id == bar_id) {
+ s->color = color;
+ s->size = size;
+ s->where[0] = coords[0];
+ s->where[1] = coords[1];
+ s->where[2] = coords[2];
+
+ return s;
+ }
+ }
+
+ s = Nviz_new_scalebar(data, bar_id, coords, size, color);
+
+ return s;
+ }
+ return NULL;
+}
+/*!
+ \brief Draws the Scale bar
+
+ \param data nviz data
+ */
+void Nviz_draw_scalebar(nv_data *data)
+{
+ int i;
+
+ GLuint FontBase = 0; /* don't know how to get fontbase*/
+
+ for (i = 0; i < data->num_scalebars; i++) {
+ struct scalebar_data *s = data->scalebar[i];
+
+ gsd_scalebar_v2(s->where, s->size, FontBase, s->color, s->color);
+ }
+}
+
+/*!
+ \brief Deletes scale bar
+
+ \param data nviz data
+ */
+void Nviz_delete_scalebar(nv_data *data, int bar_id)
+{
+ if (bar_id < data->num_scalebars) {
+ G_free(data->scalebar[bar_id]);
+ data->scalebar[bar_id] = NULL;
+ data->num_scalebars--;
+ }
+}
Modified: grass/branches/develbranch_6/lib/nviz/position.c
===================================================================
--- grass/branches/develbranch_6/lib/nviz/position.c 2011-11-25 14:58:21 UTC (rev 49356)
+++ grass/branches/develbranch_6/lib/nviz/position.c 2011-11-25 15:10:47 UTC (rev 49357)
@@ -1,10 +1,10 @@
/*!
\file lib/nviz/position.c
-
+
\brief Nviz library -- Position, focus settings
-
+
Based on visualization/nviz/src/position.c
-
+
(C) 2008, 2010 by the GRASS Development Team
This program is free software under the GNU General Public License
(>=v2). Read the file COPYING that comes with GRASS for details.
@@ -20,21 +20,21 @@
Set position to center of view
*/
-void Nviz_init_view(nv_data *data)
+void Nviz_init_view(nv_data * data)
{
GS_init_view();
Nviz_set_focus_state(1); /* center of view */
-
+
/* set default lights (1 & 2) */
Nviz_set_light_position(data, 1, 0.68, -0.68, 0.80, 0.0);
- Nviz_set_light_bright(data, 1, 0.8);
- Nviz_set_light_color(data, 1, 255, 255, 255);
- Nviz_set_light_ambient(data, 1, 0.2);
+ Nviz_set_light_bright(data, 1, 0.8);
+ Nviz_set_light_color(data, 1, 255, 255, 255);
+ Nviz_set_light_ambient(data, 1, 0.2);
Nviz_set_light_position(data, 2, 0.0, 0.0, 1.0, 0.0);
- Nviz_set_light_bright(data, 2, 0.5);
- Nviz_set_light_color(data, 2, 255, 255, 255);
- Nviz_set_light_ambient(data, 2, 0.3);
-
+ Nviz_set_light_bright(data, 2, 0.5);
+ Nviz_set_light_color(data, 2, 255, 255, 255);
+ Nviz_set_light_ambient(data, 2, 0.3);
+
return;
}
@@ -109,3 +109,97 @@
return id;
}
+
+/*!
+ \brief Get focus
+
+ \param data nviz data
+ \param x,y,z focus coordinates
+ */
+int Nviz_get_focus(nv_data * data, float *x, float *y, float *z)
+{
+ float realto[3];
+
+ /* Get current center */
+ GS_get_focus(realto);
+ *x = realto[0];
+ *y = realto[1];
+ *z = realto[2];
+ // old nviz code is more complicated and it doesn't work properly,
+ // no idea why
+
+ return 1;
+
+}
+
+/*!
+ \brief Set focus
+
+ \param data nviz data
+ \param x, y, z focus coordinates
+ */
+int Nviz_set_focus(nv_data * data, float x, float y, float z)
+{
+ float realto[3];
+
+ realto[0] = x;
+ realto[1] = y;
+ realto[2] = z;
+ GS_set_focus(realto);
+ // old nviz code is more complicated and it doesn't work properly,
+ // no idea why
+
+ return 1;
+
+}
+
+/*!
+ \brief Test focus
+
+ \param data nviz data
+ */
+int Nviz_has_focus(nv_data * data)
+{
+ float realto[3];
+
+ if (GS_get_focus(realto))
+ return 1;
+ else
+ return 0;
+}
+
+/*!
+ \brief Get xy range
+
+ \param data nviz data
+ */
+float Nviz_get_xyrange(nv_data * data)
+{
+ return data->xyrange;
+}
+
+/*!
+ \brief Get z range
+
+ \param data nviz data
+ \param min,max z range
+ */
+int Nviz_get_zrange(nv_data * data, float *min, float *max)
+{
+ GS_get_zrange_nz(min, max);
+ return 1;
+}
+
+/*!
+ \brief Get largest dimension
+
+ \param data nviz data
+ */
+float Nviz_get_longdim(nv_data * data)
+{
+ float dim;
+
+ GS_get_longdim(&dim);
+
+ return dim;
+}
Modified: grass/branches/develbranch_6/lib/ogsf/GS2.c
===================================================================
--- grass/branches/develbranch_6/lib/ogsf/GS2.c 2011-11-25 14:58:21 UTC (rev 49356)
+++ grass/branches/develbranch_6/lib/ogsf/GS2.c 2011-11-25 15:10:47 UTC (rev 49357)
@@ -78,6 +78,7 @@
static struct Cell_head wind;
static int Buffermode;
static int Numlights = 0;
+static int Resetlight = 1;
static int Modelshowing = 0;
void void_func(void)
@@ -113,9 +114,13 @@
Gv.scale = GS_UNIT_SIZE / Longdim;
+ G_debug(1, "GS_libinit(): n=%f s=%f w=%f e=%f scale=%f first=%d",
+ Region[0], Region[1], Region[2], Region[3], Gv.scale, first);
+
Cxl_func = void_func;
Swap_func = void_func;
+
if (first) {
gs_init();
}
@@ -244,7 +249,16 @@
return (-1);
}
-
+void GS_set_light_reset(int i)
+{
+ Resetlight = i;
+ if (i)
+ Numlights = 0;
+}
+int GS_get_light_reset(void)
+{
+ return Resetlight;
+}
/*!
\brief Add new model light
@@ -253,12 +267,12 @@
*/
int GS_new_light(void)
{
- static int first = 1;
int i;
- if (first) {
- first = 0;
+ if (GS_get_light_reset()) {
+ GS_set_light_reset(0);
+
for (i = 0; i < MAX_LIGHTS; i++) {
Gv.lights[i].position[X] = Gv.lights[i].position[Y] = 0.0;
Gv.lights[i].position[Z] = 1.0;
@@ -277,10 +291,10 @@
gsd_deflight(Numlights + 1, &(Gv.lights[Numlights]));
gsd_switchlight(Numlights + 1, 1);
- return (++Numlights);
+ return ++Numlights;
}
- return (-1);
+ return -1;
}
/*!
@@ -1548,32 +1562,33 @@
*/
int GS_delete_surface(int id)
{
- int i, j, found = 0;
-
- G_debug(3, "GS_delete_surface");
-
+ int i, j, found;
+
+ found = FALSE;
+
+ G_debug(1, "GS_delete_surface(): id=%d", id);
+
if (GS_surf_exists(id)) {
gs_delete_surf(id);
-
for (i = 0; i < Next_surf && !found; i++) {
if (Surf_ID[i] == id) {
- found = 1;
+ found = TRUE;
for (j = i; j < Next_surf; j++) {
Surf_ID[j] = Surf_ID[j + 1];
}
}
}
-
+
gv_update_drapesurfs();
if (found) {
--Next_surf;
- return (1);
+ return 1;
}
}
- return (-1);
+ return -1;
}
@@ -2864,6 +2879,72 @@
}
/*!
+ \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 Get rotation matrix
+ */
+void GS_get_rotation_matrix(double *matrix)
+{
+ int i;
+
+ for (i = 0; i < 16; i++) {
+ matrix[i] = Gv.rotate.rotMatrix[i];
+ }
+}
+
+/*!
+ * \brief Set rotation matrix
+ */
+void GS_set_rotation_matrix(double *matrix)
+{
+ int i;
+
+ for (i = 0; i < 16; i++) {
+ Gv.rotate.rotMatrix[i] = matrix[i];
+ }
+}
+
+/*!
\brief Unset focus
*/
void GS_set_nofocus(void)
@@ -3262,6 +3343,7 @@
*/
void GS_init_view(void)
{
+ int i;
static int first = 1;
G_debug(3, "GS_init_view");
@@ -3295,6 +3377,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/branches/develbranch_6/lib/ogsf/Gp3.c
===================================================================
--- grass/branches/develbranch_6/lib/ogsf/Gp3.c 2011-11-25 14:58:21 UTC (rev 49356)
+++ grass/branches/develbranch_6/lib/ogsf/Gp3.c 2011-11-25 15:10:47 UTC (rev 49357)
@@ -125,6 +125,8 @@
}
G_get_set_window(&wind);
+ Vect_set_constraint_region(&map, wind.north, wind.south, wind.east,
+ wind.west, PORT_DOUBLE_MAX, -PORT_DOUBLE_MAX);
/* get ndim */
ndim = 2;
Modified: grass/branches/develbranch_6/lib/ogsf/gs.c
===================================================================
--- grass/branches/develbranch_6/lib/ogsf/gs.c 2011-11-25 14:58:21 UTC (rev 49356)
+++ grass/branches/develbranch_6/lib/ogsf/gs.c 2011-11-25 15:10:47 UTC (rev 49357)
@@ -572,7 +572,7 @@
/* for ea att of all other surfs */
for (gs = Surf_top; gs; gs = gs->next) {
for (j = 0; j < MAX_ATTS; j++) {
- if (old_datah == gs->att[j].hdata) {
+ if ((old_datah == gs->att[j].hdata) && (fs != gs)) {
same = 1;
}
}
Modified: grass/branches/develbranch_6/lib/ogsf/gsd_objs.c
===================================================================
--- grass/branches/develbranch_6/lib/ogsf/gsd_objs.c 2011-11-25 14:58:21 UTC (rev 49356)
+++ grass/branches/develbranch_6/lib/ogsf/gsd_objs.c 2011-11-25 15:10:47 UTC (rev 49357)
@@ -1234,6 +1234,74 @@
}
/*!
+ \brief Draw Scalebar (as lines)
+
+ Adapted from gsd_scalebar A.Kratochvilova 2011
+
+ \param pos2 scalebar position
+ \param fontbase font-base (unused)
+ \param bar_clr barscale color
+ \param text_clr text color (unused)
+
+ \return 1
+ */
+int gsd_scalebar_v2(float *pos, float len, GLuint fontbase,
+ unsigned long bar_clr, unsigned long text_clr)
+{
+ float base[6][3];
+ float Ntop[] = { 0.0, 0.0, 1.0 };
+
+ base[0][Z] = base[1][Z] = base[2][Z] = pos[Z];
+ base[3][Z] = base[4][Z] = base[5][Z] = pos[Z];
+
+ /* simple scalebar: |------| */
+ base[0][X] = base[2][X] = base[3][X] = pos[X] - len / 2.;
+ base[1][X] = base[4][X] = base[5][X] = pos[X] + len / 2.;
+ base[0][Y] = base[1][Y] = pos[Y];
+ base[2][Y] = base[4][Y] = pos[Y] - len / 12;
+ base[3][Y] = base[5][Y] = pos[Y] + len / 12;
+
+ /* make sure we are drawing in front buffer */
+ GS_set_draw(GSD_FRONT);
+
+ gsd_pushmatrix();
+ gsd_do_scale(1); /* get map scale factor */
+
+ glNormal3fv(Ntop);
+
+ gsd_color_func(bar_clr);
+
+ gsd_linewidth(3); /* could be optional */
+
+ /* ------- */
+ gsd_bgnline();
+ gsd_vert_func(base[0]);
+ gsd_vert_func(base[1]);
+ gsd_endline();
+
+ /* |------- */
+ gsd_bgnline();
+ gsd_vert_func(base[2]);
+ gsd_vert_func(base[3]);
+ gsd_endline();
+
+ /* |-------| */
+ gsd_bgnline();
+ gsd_vert_func(base[4]);
+ gsd_vert_func(base[5]);
+ gsd_endline();
+
+ /* TODO -- draw units */
+
+ GS_done_draw();
+
+ gsd_popmatrix();
+ gsd_flush();
+
+ return 1;
+}
+
+/*!
\brief Primitives only called after transforms
Center is actually center at base of 8 sided cone
Modified: grass/branches/develbranch_6/lib/ogsf/gsd_views.c
===================================================================
--- grass/branches/develbranch_6/lib/ogsf/gsd_views.c 2011-11-25 14:58:21 UTC (rev 49356)
+++ grass/branches/develbranch_6/lib/ogsf/gsd_views.c 2011-11-25 15:10:47 UTC (rev 49357)
@@ -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
Modified: grass/branches/develbranch_6/misc/m.nviz.image/args.c
===================================================================
--- grass/branches/develbranch_6/misc/m.nviz.image/args.c 2011-11-25 14:58:21 UTC (rev 49356)
+++ grass/branches/develbranch_6/misc/m.nviz.image/args.c 2011-11-25 15:10:47 UTC (rev 49357)
@@ -31,6 +31,8 @@
static void args_volume(struct GParams *);
static void args_lighting(struct GParams *);
static void args_fringe(struct GParams *);
+static void args_cplane(struct GParams *);
+static void args_arrow(struct GParams *);
/*!
\brief Parse command
@@ -73,7 +75,13 @@
/*** fringe ***/
args_fringe(params);
-
+
+ /*** cutting plane ***/
+ args_cplane(params);
+
+ /*** north arrow ***/
+ args_arrow(params);
+
/*** output image ***/
/* output */
params->output = G_define_standard_option(G_OPT_F_OUTPUT);
@@ -377,7 +385,7 @@
params->vpoint_size->multiple = YES;
params->vpoint_size->description = _("Icon size");
params->vpoint_size->guisection = _("Vector points");
- params->vpoint_size->options = "1-1000";
+ params->vpoint_size->options = "1-10000";
params->vpoint_size->answer = "100";
/* point width */
@@ -485,6 +493,16 @@
params->exag->multiple = NO;
params->exag->description = _("Vertical exaggeration");
+ /* focus */
+ params->focus = G_define_option();
+ params->focus->key = "focus";
+ params->focus->key_desc = "x,y,z";
+ params->focus->type = TYPE_DOUBLE;
+ params->focus->required = NO;
+ params->focus->multiple = NO;
+ params->focus->description = _("Focus to point on surface (from SW corner in map units)");
+ params->focus->guisection = _("Viewpoint");
+
return;
}
@@ -551,9 +569,152 @@
params->isosurf_level->description = _("Isosurface level");
params->isosurf_level->guisection = _("Volumes");
+ /* isosurface color map */
+ params->isosurf_color_map = G_define_standard_option(G_OPT_R3_MAPS);
+ params->isosurf_color_map->key = "isosurf_color_map";
+ params->isosurf_color_map->required = NO;
+ params->isosurf_color_map->multiple = YES;
+ params->isosurf_color_map->description = _("Name of volume for isosurface color");
+ params->isosurf_color_map->guisection = _("Volumes");
+
+ /* isosurface color value */
+ params->isosurf_color_const = G_define_standard_option(G_OPT_C_FG);
+ params->isosurf_color_const->key = "isosurf_color_value";
+ params->isosurf_color_const->required = NO;
+ params->isosurf_color_const->multiple = YES;
+ params->isosurf_color_const->label = _("Isosurface color");
+ params->isosurf_color_const->guisection = _("Volumes");
+ params->isosurf_color_const->answer = NULL;
+
+ /* isosurface transparency */
+ params->isosurf_transp_map = G_define_standard_option(G_OPT_R3_MAP);
+ params->isosurf_transp_map->multiple = YES;
+ params->isosurf_transp_map->required = NO;
+ params->isosurf_transp_map->description =
+ _("Name of 3D raster map(s) for isosurface transparency");
+ params->isosurf_transp_map->guisection = _("Volumes");
+ params->isosurf_transp_map->key = "isosurf_transparency_map";
+
+ params->isosurf_transp_const = G_define_option();
+ params->isosurf_transp_const->key = "isosurf_transparency_value";
+ params->isosurf_transp_const->key_desc = "value";
+ params->isosurf_transp_const->type = TYPE_INTEGER;
+ params->isosurf_transp_const->required = NO;
+ params->isosurf_transp_const->multiple = YES;
+ params->isosurf_transp_const->description = _("Transparency value(s)for isosurfaces");
+ params->isosurf_transp_const->guisection = _("Volumes");
+ params->isosurf_transp_const->options = "0-255";
+
+ /* isosurface shininess */
+ params->isosurf_shine_map = G_define_standard_option(G_OPT_R3_MAP);
+ params->isosurf_shine_map->multiple = YES;
+ params->isosurf_shine_map->required = NO;
+ params->isosurf_shine_map->description = _("Name of 3D raster map(s) for shininess");
+ params->isosurf_shine_map->guisection = _("Volumes");
+ params->isosurf_shine_map->key = "isosurf_shininess_map";
+
+ params->isosurf_shine_const = G_define_option();
+ params->isosurf_shine_const->key = "isosurf_shininess_value";
+ params->isosurf_shine_const->key_desc = "value";
+ params->isosurf_shine_const->type = TYPE_INTEGER;
+ params->isosurf_shine_const->required = NO;
+ params->isosurf_shine_const->multiple = YES;
+ params->isosurf_shine_const->description = _("Shininess value(s) for isosurfaces");
+ params->isosurf_shine_const->guisection = _("Volumes");
+ params->isosurf_shine_const->options = "0-255";
+
+ /* slices */
+ /* slice axis */
+ params->slice = G_define_option();
+ params->slice->key = "slice";
+ params->slice->key_desc = "volume:axis";
+ params->slice->type = TYPE_STRING;
+ params->slice->required = NO;
+ params->slice->multiple = YES;
+ params->slice->description = _("Volume slice parallel to given axis (x, y, z)");
+ params->slice->guisection = _("Volumes");
+
+ /* slice position */
+ params->slice_pos = G_define_option();
+ params->slice_pos->key = "slice_position";
+ params->slice_pos->key_desc = "x1,x2,y1,y2,z1,z2";
+ params->slice_pos->type = TYPE_DOUBLE;
+ params->slice_pos->required = NO;
+ params->slice_pos->multiple = YES;
+ params->slice_pos->description = _("Volume slice position");
+ params->slice_pos->guisection = _("Volumes");
+ params->slice_pos->answer = "0,1,0,1,0,1";
+
+ /* slice transparency */
+ params->slice_transp = G_define_option();
+ params->slice_transp->key = "slice_transparency";
+ params->slice_transp->key_desc = "value";
+ params->slice_transp->type = TYPE_INTEGER;
+ params->slice_transp->required = NO;
+ params->slice_transp->multiple = YES;
+ params->slice_transp->description = _("Volume slice transparency");
+ params->slice_transp->guisection = _("Volumes");
+ params->slice_transp->answer = "0";
+ params->slice_transp->options = "0-255";
+
return;
}
+void args_cplane(struct GParams *params)
+{
+ params->cplane = G_define_option();
+ params->cplane->key = "cplane";
+ params->cplane->key_desc = "value";
+ params->cplane->type = TYPE_INTEGER;
+ params->cplane->required = NO;
+ params->cplane->multiple = YES;
+ params->cplane->description = _("Cutting plane index (0-5)");
+ params->cplane->guisection = _("Cutting planes");
+
+ params->cplane_pos = G_define_option();
+ params->cplane_pos->key = "cplane_position";
+ params->cplane_pos->key_desc = "x,y,z";
+ params->cplane_pos->type = TYPE_DOUBLE;
+ params->cplane_pos->required = NO;
+ params->cplane_pos->multiple = YES;
+ params->cplane_pos->description = _("Cutting plane x,y,z coordinates");
+ params->cplane_pos->guisection = _("Cutting planes");
+ params->cplane_pos->answer = "0,0,0";
+
+ params->cplane_rot = G_define_option();
+ params->cplane_rot->key = "cplane_rotation";
+ params->cplane_rot->key_desc = "value";
+ params->cplane_rot->type = TYPE_DOUBLE;
+ params->cplane_rot->multiple = YES;
+ params->cplane_rot->required = NO;
+ params->cplane_rot->guisection = _("Cutting planes");
+ params->cplane_rot->description = _("Cutting plane rotation along the vertical axis");
+ params->cplane_rot->answer = "0";
+ params->cplane_rot->options="0-360";
+
+ params->cplane_tilt = G_define_option();
+ params->cplane_tilt->key = "cplane_tilt";
+ params->cplane_tilt->key_desc = "value";
+ params->cplane_tilt->type = TYPE_DOUBLE;
+ params->cplane_tilt->multiple = YES;
+ params->cplane_tilt->required = NO;
+ params->cplane_tilt->guisection = _("Cutting planes");
+ params->cplane_tilt->description = _("Cutting plane tilt");
+ params->cplane_tilt->answer = "0";
+ params->cplane_tilt->options="0-360";
+
+ params->cplane_shading = G_define_option();
+ params->cplane_shading->key = "cplane_shading";
+ params->cplane_shading->key_desc = "string";
+ params->cplane_shading->type = TYPE_STRING;
+ params->cplane_shading->multiple = NO;
+ params->cplane_shading->required = NO;
+ params->cplane_shading->guisection = _("Cutting planes");
+ params->cplane_shading->description = _("Cutting plane color (between two surfaces)");
+ params->cplane_shading->answer = "clear";
+ params->cplane_shading->options= "clear,top,bottom,blend,shaded";
+}
+
void args_lighting(struct GParams *params)
{
params->light_pos = G_define_option();
@@ -624,6 +785,36 @@
params->fringe_elev->answer = "55";
}
+void args_arrow(struct GParams *params)
+{
+ params->north_arrow = G_define_option();
+ params->north_arrow->key = "arrow_position";
+ params->north_arrow->key_desc = "x,y";
+ params->north_arrow->type = TYPE_INTEGER;
+ params->north_arrow->required = NO;
+ params->north_arrow->multiple = NO;
+ params->north_arrow->description = _("Place north arrow at given position \
+ (in screen coordinates from bottom left corner)");
+ params->north_arrow->guisection = _("Decoration");
+
+ params->north_arrow_size = G_define_option();
+ params->north_arrow_size->key = "arrow_size";
+ params->north_arrow_size->key_desc = "value";
+ params->north_arrow_size->type = TYPE_DOUBLE;
+ params->north_arrow_size->required = NO;
+ params->north_arrow_size->multiple = NO;
+ params->north_arrow_size->description = _("North arrow size (in map units)");
+ params->north_arrow_size->guisection = _("Decoration");
+
+ params->north_arrow_color = G_define_standard_option(G_OPT_C_FG);
+ params->north_arrow_color->key = "arrow_color";
+ params->north_arrow_color->required = NO;
+ params->north_arrow_color->multiple = NO;
+ params->north_arrow_color->label = _("North arrow color");
+ params->north_arrow_color->guisection = _("Decoration");
+ params->north_arrow_color->answer = "black";
+}
+
/*!
\brief Get number of answers of given option
@@ -642,6 +833,8 @@
i++;
}
}
+
+ G_debug(3, "opt_get_num_answers(): opt=%s num=%d", opt->key, i);
return i;
}
@@ -654,10 +847,12 @@
void check_parameters(const struct GParams *params)
{
int nelev_map, nelev_const, nelevs;
- int nmaps, nconsts;
+ int nmaps, nconsts, ncoords, ncplanes;
int nvects;
+ int nvolumes, nisosurf, nslices;
+
/* topography */
nelev_map = opt_get_num_answers(params->elev_map);
nelev_const = opt_get_num_answers(params->elev_const);
@@ -742,6 +937,25 @@
params->elev_map->key, params->elev_const->key,
nelevs, params->wire_color->key, nconsts);
}
+
+ /*
+ * Cutting planes
+ */
+ ncplanes = opt_get_num_answers(params->cplane);
+ ncoords = opt_get_num_answers(params->cplane_pos);
+ if (ncplanes > 0 && ncplanes * 3 != ncoords)
+ G_fatal_error(_("Inconsistent number of attributes (<%s> %d: <%s> %d x 3)"),
+ params->cplane->key, ncplanes, params->cplane_pos->key, ncoords/3);
+
+ nconsts = opt_get_num_answers(params->cplane_rot);
+ if (ncplanes > 0 && ncplanes != nconsts)
+ G_fatal_error(_("Inconsistent number of attributes (<%s> %d: <%s> %d)"),
+ params->cplane->key, ncplanes, params->cplane_rot->key, nconsts);
+
+ nconsts = opt_get_num_answers(params->cplane_tilt);
+ if (ncplanes > 0 && ncplanes != nconsts)
+ G_fatal_error(_("Inconsistent number of attributes (<%s> %d: <%s> %d)"),
+ params->cplane->key, ncplanes, params->cplane_tilt->key, nconsts);
/*
* vector
@@ -776,6 +990,50 @@
params->vlines->key, nvects, params->vline_height->key,
nconsts);
+ /* position */
+ nconsts = opt_get_num_answers(params->vline_pos);
+ if (nvects > 0 && nconsts != 3 * nvects)
+ G_fatal_error(_("Inconsistent number of attributes (<%s> %d: <%s> %d)"),
+ params->vlines->key, nvects, params->vline_pos->key,
+ nconsts);
+
+ /*
+ * volumes
+ */
+ nvolumes = opt_get_num_answers(params->volume);
+ nisosurf = opt_get_num_answers(params->isosurf_level);
+ nslices = opt_get_num_answers(params->slice);
+
+ /* isosurface transparency */
+ nmaps = opt_get_num_answers(params->isosurf_transp_map);
+ nconsts = opt_get_num_answers(params->isosurf_transp_const);
+
+ if ((nmaps + nconsts > 0) && (nisosurf != nmaps + nconsts))
+ G_fatal_error(_("Inconsistent number of attributes (<%s> %d: <%s> %d, <%s> %d"),
+ params->isosurf_level->key, nisosurf, params->isosurf_transp_map->key, nmaps,
+ params->isosurf_transp_const->key, nconsts);
+
+ /* isosurface shininess */
+ nmaps = opt_get_num_answers(params->isosurf_shine_map);
+ nconsts = opt_get_num_answers(params->isosurf_shine_const);
+
+ if ((nmaps + nconsts > 0) && (nisosurf != nmaps + nconsts))
+ G_fatal_error(_("Inconsistent number of attributes (<%s> %d: <%s> %d, <%s> %d"),
+ params->isosurf_level->key, nisosurf, params->isosurf_shine_map->key, nmaps,
+ params->isosurf_shine_const->key, nconsts);
+
+ /* slice transparency */
+ nconsts = opt_get_num_answers(params->slice_transp);
+ if (nslices > 0 && nslices != nconsts)
+ G_fatal_error(_("Inconsistent number of attributes (<%s> %d: <%s> %d)"),
+ params->slice->key, nslices, params->slice_transp->key, nconsts);
+
+ /* slice position */
+ ncoords = opt_get_num_answers(params->slice_pos);
+ if (nslices > 0 && ncoords != 6 * nslices)
+ G_fatal_error(_("Inconsistent number of attributes (<%s> %d: <%s> %d x 6)"),
+ params->slice->key, nslices, params->slice_pos->key, ncoords/6);
+
return;
}
@@ -783,7 +1041,7 @@
const char *elev_map, const char *elev_const,
const char *map_name, const char *const_name)
{
- if ((nmaps > 0 && nelevs != nmaps) || (nconsts > 0 && nelevs != nconsts))
+ if ((nmaps + nconsts > 0) && (nelevs != nmaps + nconsts))
G_fatal_error(_("Inconsistent number of attributes (<%s/%s> %d: <%s> %d, <%s> %d"),
elev_map, elev_const, nelevs, map_name, nmaps,
const_name, nconsts);
Added: grass/branches/develbranch_6/misc/m.nviz.image/cplane.c
===================================================================
--- grass/branches/develbranch_6/misc/m.nviz.image/cplane.c (rev 0)
+++ grass/branches/develbranch_6/misc/m.nviz.image/cplane.c 2011-11-25 15:10:47 UTC (rev 49357)
@@ -0,0 +1,72 @@
+/*!
+ \file cplane.c
+
+ \brief Cutting plane subroutine
+
+ (C) 2011 by the GRASS Development Team
+
+ This program is free software under the GNU General Public
+ License (>=v2). Read the file COPYING that comes with GRASS
+ for details.
+
+ \author Anna Kratochvilova <kratochanna gmail.com> (Google SoC 2010/2011)
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <grass/glocale.h>
+
+#include "local_proto.h"
+
+/*!
+ \brief Draw cutting planes and set their attributes
+
+ \param params module parameters
+ \param data nviz data
+ */
+void draw_cplane(const struct GParams *params, nv_data * data)
+{
+ int i, id, ncplanes;
+ float trans_x, trans_y, trans_z;
+ float rot_x, rot_y, rot_z;
+ int fence;
+
+ ncplanes = opt_get_num_answers(params->cplane);
+ for (i = 0; i < ncplanes; i++) {
+ id = atoi(params->cplane->answers[i]);
+
+ if (id < 0 || id > Nviz_num_cplanes(data))
+ G_fatal_error(_("Cutting plane number <%d> not found"), id);
+
+ Nviz_on_cplane(data, id);
+
+ trans_x = atof(params->cplane_pos->answers[i * 3 + 0]);
+ trans_y = atof(params->cplane_pos->answers[i * 3 + 1]);
+ trans_z = atof(params->cplane_pos->answers[i * 3 + 2]);
+ Nviz_set_cplane_translation(data, id, trans_x, trans_y, trans_z);
+
+ rot_x = 0;
+ rot_y = atof(params->cplane_tilt->answers[i]);
+ rot_z = atof(params->cplane_rot->answers[i]);
+ Nviz_set_cplane_rotation(data, id, rot_x, rot_y, rot_z);
+ }
+
+ const char *shading = params->cplane_shading->answers[0];
+
+ if (strcmp(shading, "clear") == 0)
+ fence = 0;
+ else if (strcmp(shading, "top") == 0)
+ fence = 1;
+ else if (strcmp(shading, "bottom") == 0)
+ fence = 2;
+ else if (strcmp(shading, "blend") == 0)
+ fence = 3;
+ else if (strcmp(shading, "shaded") == 0)
+ fence = 4;
+ else
+ fence = 0;
+ Nviz_set_fence_color(data, fence);
+
+ return;
+}
Modified: grass/branches/develbranch_6/misc/m.nviz.image/description.html
===================================================================
--- grass/branches/develbranch_6/misc/m.nviz.image/description.html 2011-11-25 14:58:21 UTC (rev 49356)
+++ grass/branches/develbranch_6/misc/m.nviz.image/description.html 2011-11-25 15:10:47 UTC (rev 49357)
@@ -23,7 +23,13 @@
<h2>AUTHOR</h2>
-Martin Landa (Google Summer of Code 2008/2010)
+<a href="http://geo.fsv.cvut.cz/gwiki/Landa">Martin
+Landa</a>, <a href="http://grass.osgeo.org/wiki/WxNviz_GSoC_2008">Google
+Summer of Code 2008</a> (mentor: Michael Barton)
+and <a href="http://grass.osgeo.org/wiki/WxNviz_GSoC_2010">Google
+Summer of Code 2010</a> (mentor: Helena Mitasova)<br>
+Anna Kratochvilova, <a href="http://grass.osgeo.org/wiki/WxNviz_GSoC_2011">Google
+Summer of Code 2011</a> (mentor: Martin Landa)
<p>
<i>Last changed: $Date$</i>
Modified: grass/branches/develbranch_6/misc/m.nviz.image/local_proto.h
===================================================================
--- grass/branches/develbranch_6/misc/m.nviz.image/local_proto.h 2011-11-25 14:58:21 UTC (rev 49356)
+++ grass/branches/develbranch_6/misc/m.nviz.image/local_proto.h 2011-11-25 15:10:47 UTC (rev 49357)
@@ -21,16 +21,22 @@
*vpoints, *vpoint_size, *vpoint_marker, *vpoint_color, *vpoint_width, *vpoint_pos,
/* volumes */
*volume, *volume_mode, *volume_shade, *volume_pos, *volume_res, *isosurf_level,
+ *isosurf_color_map, *isosurf_color_const, *isosurf_transp_map, *isosurf_transp_const,
+ *isosurf_shine_map, *isosurf_shine_const, *slice_pos, *slice, *slice_transp,
/* misc */
*exag, *bgcolor,
+ /* cutting planes */
+ *cplane, *cplane_pos, *cplane_rot, *cplane_tilt, *cplane_shading,
/* viewpoint */
- *pos, *height, *persp, *twist,
+ *pos, *height, *persp, *twist, *focus,
/* output */
*output, *format, *size,
/* lighting */
*light_pos, *light_color, *light_bright, *light_ambient,
/* fringe */
- *fringe, *fringe_color, *fringe_elev;
+ *fringe, *fringe_color, *fringe_elev,
+ /* north arrow */
+ *north_arrow, *north_arrow_size, *north_arrow_color;
};
/* args.c */
@@ -52,7 +58,11 @@
/* volume.c */
int load_rasters3d(const struct GParams *, nv_data *);
int add_isosurfs(const struct GParams *, nv_data *);
+int add_slices(const struct GParams *, nv_data *);
+/* cutting planes */
+void draw_cplane(const struct GParams *, nv_data *);
+
/* write_img.c */
int write_img(const char *, int);
Modified: grass/branches/develbranch_6/misc/m.nviz.image/main.c
===================================================================
--- grass/branches/develbranch_6/misc/m.nviz.image/main.c 2011-11-25 14:58:21 UTC (rev 49356)
+++ grass/branches/develbranch_6/misc/m.nviz.image/main.c 2011-11-25 15:10:47 UTC (rev 49357)
@@ -34,6 +34,7 @@
int i, ret;
int red, grn, blu;
+ float size;
double vp_height, z_exag; /* calculated viewpoint height, z-exag */
int width, height; /* output image size */
char *output_name;
@@ -116,6 +117,11 @@
add_isosurfs(params, &data);
}
+ /* define slices for displaying volumes */
+ if (params->slice->answer) {
+ add_slices(params, &data);
+ }
+
/* focus on loaded data */
Nviz_set_focus_map(MAP_OBJ_UNDEFINED, -1);
@@ -147,6 +153,11 @@
atof(params->pos->answers[1]));
Nviz_set_viewpoint_twist(atoi(params->twist->answer));
Nviz_set_viewpoint_persp(atoi(params->persp->answer));
+ if (params->focus->answer) {
+ Nviz_set_focus(&data, atof(params->focus->answers[0]),
+ atof(params->focus->answers[1]),
+ atof(params->focus->answers[2]));
+ }
/* set lights */
Nviz_set_light_position(&data, 1,
@@ -183,11 +194,28 @@
Nviz_new_fringe(&data, -1, Nviz_color_from_str(params->fringe_color->answer),
atof(params->fringe_elev->answer), nw, ne, sw, se);
}
-
+
+/* draw north arrow */
+ if (params->north_arrow->answer) {
+
+ if (!params->north_arrow_size->answer)
+ size = Nviz_get_longdim(&data) / 8.;
+ else
+ size = atof(params->north_arrow_size->answer);
+
+ Nviz_set_arrow(&data, atoi(params->north_arrow->answers[0]),
+ atoi(params->north_arrow->answers[1]),
+ size, Nviz_color_from_str(params->north_arrow_color->answer));
+ Nviz_draw_arrow(&data);
+ }
+
GS_clear(data.bgcolor);
+ /* cutting planes */
+ if(params->cplane->answer)
+ draw_cplane(params, &data);
+
/* draw */
- Nviz_draw_cplane(&data, -1, -1);
Nviz_draw_all(&data);
/* write to image */
Modified: grass/branches/develbranch_6/misc/m.nviz.image/surface.c
===================================================================
--- grass/branches/develbranch_6/misc/m.nviz.image/surface.c 2011-11-25 14:58:21 UTC (rev 49356)
+++ grass/branches/develbranch_6/misc/m.nviz.image/surface.c 2011-11-25 15:10:47 UTC (rev 49357)
@@ -40,10 +40,7 @@
nelev_map = opt_get_num_answers(params->elev_map);
nelev_const = opt_get_num_answers(params->elev_const);
- if (nelev_map > 0)
- nelevs = nelev_map;
- else
- nelevs = nelev_const;
+ nelevs = nelev_const + nelev_map;
/* topography (required) */
for (i = 0; i < nelevs; i++) {
@@ -61,10 +58,10 @@
0.0, data);
}
else {
- if (i < nelev_const && strcmp(params->elev_const->answers[i], "")) {
+ if (i-nelev_map < nelev_const && strcmp(params->elev_const->answers[i-nelev_map], "")) {
id = Nviz_new_map_obj(MAP_OBJ_SURF,
NULL,
- atof(params->elev_const->answers[i]),
+ atof(params->elev_const->answers[i-nelev_map]),
data);
}
else {
@@ -74,9 +71,16 @@
}
/* set position */
- x = atof(params->surface_pos->answers[i]);
- y = atof(params->surface_pos->answers[i+1]);
- z = atof(params->surface_pos->answers[i+2]);
+ if (opt_get_num_answers(params->surface_pos) != 3 * nelevs){
+ x = atof(params->surface_pos->answers[0]);
+ y = atof(params->surface_pos->answers[1]);
+ z = atof(params->surface_pos->answers[2]);
+ }
+ else {
+ x = atof(params->surface_pos->answers[i*3+0]);
+ y = atof(params->surface_pos->answers[i*3+1]);
+ z = atof(params->surface_pos->answers[i*3+2]);
+ }
GS_set_trans(id, x, y, z);
}
@@ -111,19 +115,25 @@
data);
}
/* check for color value */
- else if (i < ncolor_const &&
- strcmp(params->color_const->answers[i], "")) {
+ else if (i-ncolor_map < ncolor_const &&
+ strcmp(params->color_const->answers[i-ncolor_map], "")) {
Nviz_set_attr(id, MAP_OBJ_SURF, ATT_COLOR, CONST_ATT, NULL,
Nviz_color_from_str(params->color_const->
- answers[i]), data);
+ answers[i-ncolor_map]), data);
}
else { /* use by default elevation map for coloring */
- Nviz_set_attr(id, MAP_OBJ_SURF, ATT_COLOR, MAP_ATT,
- G_fully_qualified_name(params->elev_map->answers[i],
- mapset), -1.0, data);
- G_verbose_message(_("Color attribute not defined, using default <%s>"),
- G_fully_qualified_name(params->elev_map->
- answers[i], mapset));
+ if (nelev_map > 0){
+ Nviz_set_attr(id, MAP_OBJ_SURF, ATT_COLOR, MAP_ATT,
+ G_fully_qualified_name(params->elev_map->answers[i],
+ mapset), -1.0, data);
+ G_verbose_message(_("Color attribute not defined, using default <%s>"),
+ G_fully_qualified_name(params->elev_map->
+ answers[i], mapset));
+ }
+ else{
+ G_fatal_error(_("Missing color attribute for surface %d"),
+ i + 1);
+ }
}
/* mask */
if (i < nmask_map && strcmp(params->mask_map->answers[i], "")) {
@@ -139,10 +149,10 @@
answers[i], mapset), -1.0,
data);
}
- else if (i < ntransp_const &&
- strcmp(params->transp_const->answers[i], "")) {
+ else if (i-ntransp_map < ntransp_const &&
+ strcmp(params->transp_const->answers[i-ntransp_map], "")) {
Nviz_set_attr(id, MAP_OBJ_SURF, ATT_TRANSP, CONST_ATT, NULL,
- atof(params->transp_const->answers[i]), data);
+ atof(params->transp_const->answers[i-ntransp_map]), data);
}
/* shininess */
@@ -152,10 +162,10 @@
answers[i], mapset), -1.0,
data);
}
- else if (i < nshine_const &&
- strcmp(params->shine_const->answers[i], "")) {
+ else if (i-nshine_map < nshine_const &&
+ strcmp(params->shine_const->answers[i-nshine_map], "")) {
Nviz_set_attr(id, MAP_OBJ_SURF, ATT_SHINE, CONST_ATT, NULL,
- atof(params->shine_const->answers[i]), data);
+ atof(params->shine_const->answers[i-nshine_map]), data);
}
/* emission */
@@ -164,10 +174,10 @@
G_fully_qualified_name(params->emit_map->answers[i],
mapset), -1.0, data);
}
- else if (i < nemit_const &&
- strcmp(params->emit_const->answers[i], "")) {
+ else if (i-nemit_map < nemit_const &&
+ strcmp(params->emit_const->answers[i-nemit_map], "")) {
Nviz_set_attr(id, MAP_OBJ_SURF, ATT_EMIT, CONST_ATT, NULL,
- atof(params->emit_const->answers[i]), data);
+ atof(params->emit_const->answers[i-nemit_map]), data);
}
/*
@@ -229,7 +239,7 @@
}
/* style */
- if (strcmp(params->style->answers[i], "wire") == 0) {
+ if (strcmp(style, "wire") == 0) {
draw_mode |= DM_GRID_WIRE;
}
else { /* surface */
@@ -237,7 +247,7 @@
}
/* shading */
- if (strcmp(params->shade->answers[i], "flat") == 0) {
+ if (strcmp(shade, "flat") == 0) {
draw_mode |= DM_FLAT;
}
else { /* gouraud */
Modified: grass/branches/develbranch_6/misc/m.nviz.image/vector.c
===================================================================
--- grass/branches/develbranch_6/misc/m.nviz.image/vector.c 2011-11-25 14:58:21 UTC (rev 49356)
+++ grass/branches/develbranch_6/misc/m.nviz.image/vector.c 2011-11-25 15:10:47 UTC (rev 49357)
@@ -85,9 +85,9 @@
0.0, data);
/* set position */
- x = atof(position->answers[i]);
- y = atof(position->answers[i+1]);
- z = atof(position->answers[i+2]);
+ x = atof(position->answers[i*3+0]);
+ y = atof(position->answers[i*3+1]);
+ z = atof(position->answers[i*3+2]);
if (map_obj_type == MAP_OBJ_VECT)
GV_set_trans(id, x, y, z);
Modified: grass/branches/develbranch_6/misc/m.nviz.image/volume.c
===================================================================
--- grass/branches/develbranch_6/misc/m.nviz.image/volume.c 2011-11-25 14:58:21 UTC (rev 49356)
+++ grass/branches/develbranch_6/misc/m.nviz.image/volume.c 2011-11-25 15:10:47 UTC (rev 49357)
@@ -13,6 +13,7 @@
*/
#include <stdlib.h>
+#include <string.h>
#include <grass/G3d.h>
#include <grass/glocale.h>
@@ -29,7 +30,8 @@
*/
int load_rasters3d(const struct GParams *params, nv_data *data)
{
- int i, nvol, id;
+ int i, nvol, id;
+ float x, y, z;
char *mapset;
nvol = opt_get_num_answers(params->volume);
@@ -45,6 +47,20 @@
G_fully_qualified_name(params->volume->answers[i],
mapset),
0.0, data);
+
+ /* set position */
+ if (opt_get_num_answers(params->volume_pos) != 3 * nvol) {
+ x = atof(params->volume_pos->answers[0]);
+ y = atof(params->volume_pos->answers[1]);
+ z = atof(params->volume_pos->answers[2]);
+ }
+ else {
+ x = atof(params->volume_pos->answers[i*3+0]);
+ y = atof(params->volume_pos->answers[i*3+1]);
+ z = atof(params->volume_pos->answers[i*3+2]);
+ }
+
+ GVL_set_trans(id, x, y, z);
}
return 1;
@@ -61,8 +77,12 @@
int add_isosurfs(const struct GParams *params, nv_data *data)
{
int i;
- int num, level, nvols, *vol_list, id, nisosurfs;
+ float level;
+ int num, nvols, *vol_list, id, nisosurfs;
+ int ncolor_map, ncolor_const, ntransp_map, ntransp_const, nshine_map, nshine_const;
+ int res, draw_mode;
char **tokens;
+ const char *mapset, *style;
vol_list = GVL_get_vol_list(&nvols);
@@ -72,7 +92,7 @@
G_fatal_error(_("Error tokenize '%s'"),
params->isosurf_level->answers[i]);
num = atoi(tokens[0]);
- level = atoi(tokens[1]);
+ level = atof(tokens[1]);
G_free_tokens(tokens);
if (num > nvols) {
@@ -95,11 +115,192 @@
}
/* color */
- if (GVL_isosurf_set_att_map(id, nisosurfs-1, ATT_COLOR, params->volume->answers[0]) < 0) {
- G_fatal_error(_("Unable to set isosurface (%d) attribute (%d) of volume %d"),
- nisosurfs-1, ATT_COLOR, id);
+ ncolor_map = opt_get_num_answers(params->isosurf_color_map);
+ ncolor_const = opt_get_num_answers(params->isosurf_color_const);
+
+ if (i < ncolor_map && strcmp(params->isosurf_color_map->answers[i], "")) {
+ mapset = G_find_grid3(params->isosurf_color_map->answers[i], "");
+
+ if (mapset == NULL) {
+ G_fatal_error(_("3d raster map <%s> not found"),
+ params->isosurf_color_map->answers[i]);
+ }
+
+ if (GVL_isosurf_set_att_map(id, nisosurfs-1, ATT_COLOR,
+ params->isosurf_color_map->answers[i]) < 0)
+ G_fatal_error(_("Unable to set isosurface (%d) attribute (%d) of volume %d"),
+ nisosurfs-1, ATT_COLOR, id);
}
+ else if (i-ncolor_map < ncolor_const &&
+ strcmp(params->isosurf_color_const->answers[i-ncolor_map], "")) {
+
+ if (GVL_isosurf_set_att_const(id, nisosurfs-1, ATT_COLOR,
+ Nviz_color_from_str(params->isosurf_color_const->answers[i-ncolor_map])) < 0)
+ G_fatal_error(_("Unable to set isosurface (%d) attribute (%d) of volume %d"),
+ nisosurfs-1, ATT_COLOR, id);
+ }
+ else { /* use by default 3d raster map for coloring */
+ GVL_isosurf_set_att_map(id, nisosurfs-1, ATT_COLOR, params->volume->answers[num-1]);
+ G_verbose_message(_("Color attribute not defined, using default <%s>"),
+ params->volume->answers[num-1]);
+ }
+
+ /* transparency */
+ ntransp_map = opt_get_num_answers(params->isosurf_transp_map);
+ ntransp_const = opt_get_num_answers(params->isosurf_transp_const);
+
+ if (i < ntransp_map && strcmp(params->isosurf_transp_map->answers[i], "")) {
+ if (GVL_isosurf_set_att_map(id, nisosurfs-1, ATT_TRANSP,
+ params->isosurf_transp_map->answers[i]) < 0)
+ G_fatal_error(_("Unable to set isosurface (%d) attribute (%d) of volume %d"),
+ nisosurfs-1, ATT_TRANSP, id);
+ }
+ else if (i-ntransp_map < ntransp_const &&
+ strcmp(params->isosurf_transp_const->answers[i-ntransp_map], "")) {
+ if (GVL_isosurf_set_att_const(id, nisosurfs-1, ATT_TRANSP,
+ atof(params->isosurf_transp_const->answers[i-ntransp_map])) < 0)
+ G_fatal_error(_("Unable to set isosurface (%d) attribute (%d) of volume %d"),
+ nisosurfs-1, ATT_TRANSP, id);
+ }
+
+ /* shine */
+ nshine_map = opt_get_num_answers(params->isosurf_shine_map);
+ nshine_const = opt_get_num_answers(params->isosurf_shine_const);
+
+ if (i < nshine_map && strcmp(params->isosurf_shine_map->answers[i], "")) {
+ if (GVL_isosurf_set_att_map(id, nisosurfs-1, ATT_SHINE,
+ params->isosurf_shine_map->answers[i]) < 0)
+ G_fatal_error(_("Unable to set isosurface (%d) attribute (%d) of volume %d"),
+ nisosurfs-1, ATT_SHINE, id);
+ }
+ else if (i-nshine_map < nshine_const &&
+ strcmp(params->isosurf_shine_const->answers[i-nshine_map], "")) {
+ if (GVL_isosurf_set_att_const(id, nisosurfs-1, ATT_SHINE,
+ atof(params->isosurf_shine_const->answers[i-nshine_map])) < 0)
+ G_fatal_error(_("Unable to set isosurface (%d) attribute (%d) of volume %d"),
+ nisosurfs-1, ATT_SHINE, id);
+ }
}
-
+
+ /* set draw resolution and shading after isosurfaces are added*/
+ for (i = 0; i < nvols; i++) {
+
+ id = vol_list[i];
+ /* set resolution */
+ if (opt_get_num_answers(params->volume_res) != nvols)
+ res = atof(params->volume_res->answers[0]);
+ else
+ res = atof(params->volume_res->answers[i]);
+
+ GVL_isosurf_set_drawres(id, res, res, res);
+
+ /* set shading */
+ if (opt_get_num_answers(params->volume_shade) != nvols)
+ style = params->volume_shade->answers[0];
+ else
+ style = params->volume_shade->answers[i];
+
+ draw_mode = 0;
+
+ if (strcmp(style, "flat") == 0) {
+ draw_mode |= DM_FLAT;
+ }
+ else {
+ draw_mode |= DM_GOURAUD;
+ }
+
+ GVL_isosurf_set_drawmode(id, draw_mode);
+ }
+
return 1;
}
+
+int add_slices(const struct GParams *params, nv_data *data)
+{
+ int i;
+ int num, nvols, *vol_list, id, nslices, axis;
+ int res, draw_mode;
+ char **tokens;
+ const char* style;
+
+ vol_list = GVL_get_vol_list(&nvols);
+
+ for (i = 0; params->slice->answers[i]; i++) {
+ tokens = G_tokenize(params->slice->answers[i], ":");
+ if (G_number_of_tokens(tokens) != 2)
+ G_fatal_error(_("Error tokenize '%s'"),
+ params->slice->answers[i]);
+ num = atoi(tokens[0]);
+
+ if (!strcmp(tokens[1],"x") || !strcmp(tokens[1],"X"))
+ axis = 0;
+ else if (!strcmp(tokens[1],"y") || !strcmp(tokens[1],"Y"))
+ axis = 1;
+ else if (!strcmp(tokens[1],"z") || !strcmp(tokens[1],"Z"))
+ axis = 2;
+ else
+ G_fatal_error(_("Wrong name for axis: %s"),
+ tokens[1]);
+ G_free_tokens(tokens);
+
+ if (num > nvols) {
+ G_fatal_error(_("Volume set number %d is not available"),
+ num);
+ }
+
+ id = vol_list[num-1];
+ if (GVL_slice_add(id) < 0) {
+ G_fatal_error(_("Unable to add slice (volume set %d)"),
+ id);
+ }
+
+ nslices = GVL_slice_num_slices(id);
+
+ if (GVL_slice_set_pos(id, nslices-1, atof(params->slice_pos->answers[i*6+0]),
+ atof(params->slice_pos->answers[i*6+1]),
+ atof(params->slice_pos->answers[i*6+2]),
+ atof(params->slice_pos->answers[i*6+3]),
+ atof(params->slice_pos->answers[i*6+4]),
+ atof(params->slice_pos->answers[i*6+5]),
+ axis) < 0)
+ G_fatal_error(_("Unable to set slice (%d) position of volume %d"),
+ nslices-1, id);
+
+ /* set transparency */
+ if (GVL_slice_set_transp(id, nslices-1, atoi(params->slice_transp->answers[i])) < 0)
+ G_fatal_error(_("Unable to set slice (%d) transparency of volume %d"),
+ nslices-1, id);
+ }
+
+ /* set draw resolution and shading after slices are added*/
+ for (i = 0; i < nvols; i++) {
+
+ id = vol_list[i];
+ /* set resolution */
+ if (opt_get_num_answers(params->volume_res) != nvols)
+ res = atof(params->volume_res->answers[0]);
+ else
+ res = atof(params->volume_res->answers[i]);
+
+ GVL_slice_set_drawres(id, res, res, res);
+
+ /* set shading */
+ if (opt_get_num_answers(params->volume_shade) != nvols)
+ style = params->volume_shade->answers[0];
+ else
+ style = params->volume_shade->answers[i];
+
+ draw_mode = 0;
+
+ if (strcmp(style, "flat") == 0) {
+ draw_mode |= DM_FLAT;
+ }
+ else {
+ draw_mode |= DM_GOURAUD;
+ }
+
+ GVL_slice_set_drawmode(id, draw_mode);
+ }
+
+ return 1;
+}
More information about the grass-commit
mailing list