[GRASS-SVN] r32560 - in grass/branches/develbranch_6: gui/icons gui/icons/silk gui/wxpython gui/wxpython/docs gui/wxpython/gui_modules gui/wxpython/icons gui/wxpython/icons/silk gui/wxpython/nviz gui/wxpython/scripts gui/wxpython/vdigit gui/wxpython/xml include include/Make lib visualization

svn_grass at osgeo.org svn_grass at osgeo.org
Wed Aug 6 05:21:47 EDT 2008


Author: martinl
Date: 2008-08-06 05:21:46 -0400 (Wed, 06 Aug 2008)
New Revision: 32560

Added:
   grass/branches/develbranch_6/gui/icons/gui-layeroptions.gif
   grass/branches/develbranch_6/gui/icons/silk/bricks.png
   grass/branches/develbranch_6/gui/wxpython/docs/wxGUI.Nviz.html
   grass/branches/develbranch_6/gui/wxpython/gui_modules/nviz.py
   grass/branches/develbranch_6/gui/wxpython/nviz/
   grass/branches/develbranch_6/gui/wxpython/nviz/Makefile
   grass/branches/develbranch_6/gui/wxpython/nviz/change_view.cpp
   grass/branches/develbranch_6/gui/wxpython/nviz/draw.cpp
   grass/branches/develbranch_6/gui/wxpython/nviz/init.cpp
   grass/branches/develbranch_6/gui/wxpython/nviz/lights.cpp
   grass/branches/develbranch_6/gui/wxpython/nviz/load.cpp
   grass/branches/develbranch_6/gui/wxpython/nviz/nviz.h
   grass/branches/develbranch_6/gui/wxpython/nviz/nviz.i
   grass/branches/develbranch_6/gui/wxpython/nviz/nviz_types.i
   grass/branches/develbranch_6/gui/wxpython/nviz/surface.cpp
   grass/branches/develbranch_6/gui/wxpython/nviz/vector.cpp
   grass/branches/develbranch_6/gui/wxpython/scripts/Makefile
   grass/branches/develbranch_6/gui/wxpython/scripts/d.rast3d
   grass/branches/develbranch_6/include/nviz.h
   grass/branches/develbranch_6/lib/nviz/
   grass/branches/develbranch_6/visualization/nviz2/
Removed:
   grass/branches/develbranch_6/gui/wxpython/nviz/Makefile
   grass/branches/develbranch_6/gui/wxpython/nviz/change_view.cpp
   grass/branches/develbranch_6/gui/wxpython/nviz/draw.cpp
   grass/branches/develbranch_6/gui/wxpython/nviz/init.cpp
   grass/branches/develbranch_6/gui/wxpython/nviz/lights.cpp
   grass/branches/develbranch_6/gui/wxpython/nviz/load.cpp
   grass/branches/develbranch_6/gui/wxpython/nviz/nviz.h
   grass/branches/develbranch_6/gui/wxpython/nviz/nviz.i
   grass/branches/develbranch_6/gui/wxpython/nviz/nviz_types.i
   grass/branches/develbranch_6/gui/wxpython/nviz/surface.cpp
   grass/branches/develbranch_6/gui/wxpython/nviz/vector.cpp
Modified:
   grass/branches/develbranch_6/gui/wxpython/Makefile
   grass/branches/develbranch_6/gui/wxpython/README
   grass/branches/develbranch_6/gui/wxpython/docs/Makefile
   grass/branches/develbranch_6/gui/wxpython/docs/wxGUI.html
   grass/branches/develbranch_6/gui/wxpython/gis_set.py
   grass/branches/develbranch_6/gui/wxpython/gui_modules/__init__.py
   grass/branches/develbranch_6/gui/wxpython/gui_modules/gdialogs.py
   grass/branches/develbranch_6/gui/wxpython/gui_modules/georect.py
   grass/branches/develbranch_6/gui/wxpython/gui_modules/gselect.py
   grass/branches/develbranch_6/gui/wxpython/gui_modules/mapdisp.py
   grass/branches/develbranch_6/gui/wxpython/gui_modules/menudata.py
   grass/branches/develbranch_6/gui/wxpython/gui_modules/preferences.py
   grass/branches/develbranch_6/gui/wxpython/gui_modules/profile.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/utils.py
   grass/branches/develbranch_6/gui/wxpython/gui_modules/workspace.py
   grass/branches/develbranch_6/gui/wxpython/gui_modules/wxgui_utils.py
   grass/branches/develbranch_6/gui/wxpython/icons/icon.py
   grass/branches/develbranch_6/gui/wxpython/icons/silk/__init__.py
   grass/branches/develbranch_6/gui/wxpython/vdigit/Makefile
   grass/branches/develbranch_6/gui/wxpython/wxgui.py
   grass/branches/develbranch_6/gui/wxpython/xml/grass-gxw.dtd
   grass/branches/develbranch_6/include/Make/Grass.make.in
   grass/branches/develbranch_6/lib/Makefile
   grass/branches/develbranch_6/lib/grasslib.dox
   grass/branches/develbranch_6/visualization/Makefile
Log:
nviz2 backported from trunk (CLI module and wxGUI extension)
wxGUI code synchronized with trunk
also the last changes in drag-and-drop LayerTree backported (cmbarton)


Copied: grass/branches/develbranch_6/gui/icons/gui-layeroptions.gif (from rev 32556, grass/trunk/gui/icons/gui-layeroptions.gif)
===================================================================
(Binary files differ)

Copied: grass/branches/develbranch_6/gui/icons/silk/bricks.png (from rev 32559, grass/trunk/gui/icons/silk/bricks.png)
===================================================================
(Binary files differ)

Modified: grass/branches/develbranch_6/gui/wxpython/Makefile
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/Makefile	2008-08-06 09:11:06 UTC (rev 32559)
+++ grass/branches/develbranch_6/gui/wxpython/Makefile	2008-08-06 09:21:46 UTC (rev 32560)
@@ -4,10 +4,15 @@
 
 include $(MODULE_TOPDIR)/include/Make/Platform.make
 
+#compile if wxWidgets, Python, CXX present
 ifneq ($(USE_WXWIDGETS),)
   ifneq ($(USE_PYTHON),)
     ifneq ($(strip $(CXX)),)
        SUBDIRS += vdigit
+         #compile if OpenGL present
+         ifneq ($(strip $(OPENGLLIB)),)
+           SUBDIRS += nviz
+         endif
     endif
   endif
 endif
@@ -20,7 +25,7 @@
 	$(MAKE) parsubdirs
 
 install_scripts:
-	$(MKDIR) $(ETCDIR) $(ETCDIR)/compat $(ETCDIR)/gui_modules $(ETCDIR)/icons $(ETCDIR)/icons/silk $(ETCDIR)/images $(ETCDIR)/scripts $(ETCDIR)/vdigit $(ETCDIR)/xml
+	$(MKDIR) $(ETCDIR) $(ETCDIR)/compat $(ETCDIR)/gui_modules $(ETCDIR)/icons $(ETCDIR)/icons/silk $(ETCDIR)/images $(ETCDIR)/scripts $(ETCDIR)/vdigit $(ETCDIR)/xml $(ETCDIR)/nviz
 	$(INSTALL_DATA) compat/* $(ETCDIR)/compat/
 	$(INSTALL_DATA) gui_modules/* $(ETCDIR)/gui_modules/
 	$(INSTALL_DATA) icons/*.* $(ETCDIR)/icons/

Modified: grass/branches/develbranch_6/gui/wxpython/README
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/README	2008-08-06 09:11:06 UTC (rev 32559)
+++ grass/branches/develbranch_6/gui/wxpython/README	2008-08-06 09:21:46 UTC (rev 32560)
@@ -47,6 +47,13 @@
  Get Python Extensions for MS-Windows from: http://sourceforge.net/project/platformdownload.php?group_id=78018 
  Get NumPy from: http://sourceforge.net/project/showfiles.php?group_id=1369&package_id=175103  
 
+ NVIZ EXTENSION REQUIREMENTS
+
+ PyOpenGL: http://pyopengl.sourceforge.net
+ 
+ On Debian GNU/Linux install package:
+ apt-get install python-opengl
+
 2 - STARTUP WITH GRASS INITIALIZATION
 
 If you want to launch wxPython GUI automatically when you start

Modified: grass/branches/develbranch_6/gui/wxpython/docs/Makefile
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/docs/Makefile	2008-08-06 09:11:06 UTC (rev 32559)
+++ grass/branches/develbranch_6/gui/wxpython/docs/Makefile	2008-08-06 09:21:46 UTC (rev 32560)
@@ -1,6 +1,9 @@
 MODULE_TOPDIR = ../../..
 
-FILES = wxGUI wxGUI.Vector_Digitizing_Tool wxGUI.Attribute_Table_Manager
+FILES = wxGUI \
+	wxGUI.Vector_Digitizing_Tool \
+	wxGUI.Attribute_Table_Manager \
+	wxGUI.Nviz
 
 include $(MODULE_TOPDIR)/include/Make/Platform.make
 include $(MODULE_TOPDIR)/include/Make/Grass.make

Copied: grass/branches/develbranch_6/gui/wxpython/docs/wxGUI.Nviz.html (from rev 32556, grass/trunk/gui/wxpython/docs/wxGUI.Nviz.html)
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/docs/wxGUI.Nviz.html	                        (rev 0)
+++ grass/branches/develbranch_6/gui/wxpython/docs/wxGUI.Nviz.html	2008-08-06 09:21:46 UTC (rev 32560)
@@ -0,0 +1,14 @@
+<h2>DESCRIPTION</h2>
+
+TODO
+
+<h2>SEE ALSO</h2>
+
+See also <a href="http://grass.osgeo.org/wiki/WxNVIZ">Wiki</a> page.
+
+<h2>AUTHORS</h2>
+
+Martin Landa, Google Summer of Code 2008 (Mentor: Michael Barton)
+
+<p>
+<i>$Date$</i>

Modified: grass/branches/develbranch_6/gui/wxpython/docs/wxGUI.html
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/docs/wxGUI.html	2008-08-06 09:11:06 UTC (rev 32559)
+++ grass/branches/develbranch_6/gui/wxpython/docs/wxGUI.html	2008-08-06 09:21:46 UTC (rev 32560)
@@ -7,7 +7,7 @@
     grass -wxpython
 </pre></div>
 
-or define in your <tt>.grassrc6</tt> file 'GRASS_GUI' variable
+or define in your <tt>.grassrc7</tt> file 'GRASS_GUI' variable
 
 <div class="code"><pre>
     GRASS_GUI: wxpython
@@ -174,7 +174,7 @@
 Note that when an option of the command contains spaces, you need to
 escape them with the backslash ('\') character, for example:
 <div class="code"><pre>
-d.text.freetype text=Population\ density</tt>
+d.text text=Population\ density</tt>
 </pre></div>
 </dd>
 
@@ -399,7 +399,8 @@
 
 <em>
 <a href="wxGUI.Vector_Digitizing_Tool.html">Vector digitizing tool</a>,
-<a href="wxGUI.Attribute_Table_Manager.html">Attribute Table Manager</a>
+<a href="wxGUI.Attribute_Table_Manager.html">Attribute Table Manager</a>,
+<a href="wxGUI.Nviz.html">Nviz extension</a>
 </em>
 
 <p>

Modified: grass/branches/develbranch_6/gui/wxpython/gis_set.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gis_set.py	2008-08-06 09:11:06 UTC (rev 32559)
+++ grass/branches/develbranch_6/gui/wxpython/gis_set.py	2008-08-06 09:21:46 UTC (rev 32560)
@@ -57,7 +57,7 @@
         
         wx.Frame.__init__(self, parent=parent, id=id, style=style)
 
-	self.panel = wx.Panel(parent=self, id=wx.ID_ANY)
+        self.panel = wx.Panel(parent=self, id=wx.ID_ANY)
 
         #
         # graphical elements
@@ -127,7 +127,7 @@
         self.manageloc = wx.Choice(parent=self.panel, id=wx.ID_ANY,
                                    choices=[_('Rename mapset'), _('Rename location'),
                                             _('Delete mapset'), _('Delete location')])
-	self.manageloc.SetSelection(0)
+        self.manageloc.SetSelection(0)
 
         # textinputs
         self.tgisdbase = wx.TextCtrl(parent=self.panel, id=wx.ID_ANY, value="", size=(300, -1),
@@ -200,6 +200,7 @@
             self.UpdateLocations(self.gisdbase)
             try:
                 self.lblocations.SetSelection(self.listOfLocations.index(location))
+                self.lblocations.EnsureVisible(self.listOfLocations.index(location))
             except ValueError:
                 print >> sys.stderr, _("ERROR: Location <%s> not found") % \
                     (location)
@@ -210,6 +211,7 @@
             if mapset:
                 try:
                     self.lbmapsets.SetSelection(self.listOfMapsets.index(mapset))
+                    self.lbmapsets.EnsureVisible(self.listOfMapsets.index(mapset))
                 except ValueError:
                     self.lbmapsets.Clear()
                     print >> sys.stderr, _("ERROR: Mapset <%s> not found") % \

Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/__init__.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/__init__.py	2008-08-06 09:11:06 UTC (rev 32559)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/__init__.py	2008-08-06 09:21:46 UTC (rev 32560)
@@ -12,8 +12,10 @@
         "mapdisp",
         "menudata",
         "menuform",
+        "nviz",
         "preferences",
         "profile",
+        "psmap",
         "render",
         "rules",
         "sqlbuilder",

Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/gdialogs.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/gdialogs.py	2008-08-06 09:11:06 UTC (rev 32559)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/gdialogs.py	2008-08-06 09:21:46 UTC (rev 32560)
@@ -1057,5 +1057,72 @@
 
         return data
 
+class SetOpacityDialog(wx.Dialog):
+    """Set opacity of map layers"""
+    def __init__(self, parent, id=wx.ID_ANY, title=_("Set Map Layer Opacity"),
+                 size=wx.DefaultSize, pos=wx.DefaultPosition,
+                 style=wx.DEFAULT_DIALOG_STYLE, opacity=100):
 
+        self.parent = parent    # GMFrame
+        self.opacity = opacity  # current opacity
 
+        super(SetOpacityDialog, self).__init__(parent, id=id, pos=pos,
+                                               size=size, style=style, title=title)
+
+        panel = wx.Panel(parent=self, id=wx.ID_ANY)
+        
+        sizer = wx.BoxSizer(wx.VERTICAL)
+
+        box = wx.GridBagSizer(vgap=5, hgap=5)
+        self.value = wx.Slider(panel, id=wx.ID_ANY, value=self.opacity,
+                               style=wx.SL_HORIZONTAL | wx.SL_AUTOTICKS | \
+                                   wx.SL_TOP | wx.SL_LABELS,
+                               minValue=0, maxValue=100,
+                               size=(350, -1))
+
+        box.Add(item=self.value,
+                flag=wx.ALIGN_CENTRE, pos=(0, 0), span=(1, 2))
+        box.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
+                                   label=_("transparent")),
+                pos=(1, 0))
+        box.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
+                                   label=_("opaque")),
+                flag=wx.ALIGN_RIGHT,
+                pos=(1, 1))
+
+        sizer.Add(item=box, proportion=0,
+                  flag=wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.ALL, border=5)
+
+        line = wx.StaticLine(parent=panel, id=wx.ID_ANY,
+                             style=wx.LI_HORIZONTAL)
+        sizer.Add(item=line, proportion=0,
+                  flag=wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.ALL, border=5)
+
+        # buttons
+        btnsizer = wx.StdDialogButtonSizer()
+
+        btnOK = wx.Button(parent=panel, id=wx.ID_OK)
+        btnOK.SetDefault()
+        btnsizer.AddButton(btnOK)
+
+        btnCancel = wx.Button(parent=panel, id=wx.ID_CANCEL)
+        btnsizer.AddButton(btnCancel)
+        btnsizer.Realize()
+
+        sizer.Add(item=btnsizer, proportion=0,
+                  flag=wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.ALL, border=5)
+
+        panel.SetSizer(sizer)
+        sizer.Fit(panel)
+
+        self.SetSize(self.GetBestSize())
+
+        self.Layout()
+
+    def GetOpacity(self):
+        """Button 'OK' pressed"""
+        # return opacity value
+        opacity = float(self.value.GetValue()) / 100
+        return opacity
+
+

Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/georect.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/georect.py	2008-08-06 09:11:06 UTC (rev 32559)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/georect.py	2008-08-06 09:21:46 UTC (rev 32560)
@@ -672,8 +672,11 @@
         self.SetTarget(self.xygroup, self.currentlocation, self.currentmapset)
 
         #
-        # toolbar
+        # toolbar and display for xy map
         #
+        self.toolbar = toolbars.GCPToolbar(parent=self, tbframe=self).GetToolbar()
+        self.SetToolBar(self.toolbar)
+        
         self.SetMapDisplay(self.mapdisp)
 
         #
@@ -698,6 +701,11 @@
                                        majorDimension=wx.RA_SPECIFY_COLS)
         sizer.Add(item=self.rb_grmethod, proportion=0,
                        flag=wx.EXPAND | wx.ALL, border=5)
+        
+        self.clip_to_region = wx.CheckBox(parent=panel, id=wx.ID_ANY,
+                                label=_("clip to computational region in target location"))
+        sizer.Add(item=self.clip_to_region, proportion=0,
+                       flag=wx.EXPAND | wx.ALL, border=5)
 
         box = wx.StaticBox (parent=panel, id=wx.ID_ANY,
                             label=" %s " % _("Ground Control Points"))
@@ -729,13 +737,8 @@
     def SetMapDisplay(self, win):
         self.mapdisp = win
         if self.mapdisp:
-            self.toolbar = toolbars.GCPToolbar(parent=self, mapdisplay=self.mapdisp, map=self.mapdisp.Map).GetToolbar()
-            self.SetToolBar(self.toolbar)
+             self.list.LoadData()
 
-            self.list.LoadData()
-        else:
-            self.toolbar = None
-
     def SetTarget(self, tgroup, tlocation, tmapset):
         """
         Sets rectification target to current location and mapset
@@ -931,8 +934,9 @@
         #
         # calculate RMS
         #
-        if self.CheckGCPcount():
-            self.RMSError(self.xygroup, self.gr_order)
+        # FIXME auto calculation on load is not working
+        #if self.CheckGCPcount():
+        #    self.RMSError(self.xygroup, self.gr_order)
 
     def ReloadGCPs(self, event):
         """Reload data from file"""
@@ -954,7 +958,7 @@
         are active for the selected transformation order
         """
         if (self.GCPcount < 3 and self.gr_order == 1) or \
-            (self.GCPcount < 6 and self.gr_order == 2) or \
+            (self.GCPcount < 7 and self.gr_order == 2) or \
             (self.GCPcount < 10 and self.gr_order == 3):
             if msg:
                 wx.MessageBox(parent=self,
@@ -962,7 +966,7 @@
                               message=_('Insufficient points defined and active (checked) '
                                         'for selected rectification method.\n'
                                         '3+ points needed for 1st order,\n'
-                                        '6+ points for 2nd order, and\n'
+                                        '7+ points for 2nd order, and\n'
                                         '10+ points for 3rd order.'),
                               style=wx.ICON_INFORMATION | wx.ID_OK | wx.CENTRE)
                 return False
@@ -981,13 +985,13 @@
                 
         if maptype == 'cell':
             self.grwiz.SwitchEnv('new')
+            cmdlist = ['i.rectify','-a','group=%s' % self.xygroup,
+                       'extension=%s' % self.extension,'order=%s' % self.gr_order]
+            if self.clip_to_region:
+                cmdlist.append('-c')
+            
+            self.parent.goutput.RunCmd(cmdlist)
 
-            self.parent.goutput.RunCmd(['i.rectify',
-                                        '-ca',
-                                        'group=%s' % self.xygroup,
-                                        'extension=%s' % self.extension,
-                                        'order=%s' % self.gr_order])
-
             self.grwiz.SwitchEnv('original')
 
         elif maptype == 'vector':

Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/gselect.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/gselect.py	2008-08-06 09:11:06 UTC (rev 32559)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/gselect.py	2008-08-06 09:21:46 UTC (rev 32560)
@@ -21,6 +21,7 @@
 import wx
 import wx.combo
 
+import grass
 import globalvar
 import gcmd
 import utils
@@ -131,8 +132,7 @@
         with all relevant elements displayed beneath each mapset branch
         """
         # get current mapset
-        cmdlist = ['g.gisenv', 'get=MAPSET']
-        curr_mapset = gcmd.Command(cmdlist).ReadStdOutput()[0]
+        curr_mapset = grass.gisenv()['MAPSET']
         
         # list of mapsets in current location
         if mapsets is None:
@@ -195,12 +195,13 @@
                 mapsets[i] = mapsets[0]
                 mapsets[0] = curr_mapset
 
+        filesdict = grass.list_grouped(elementdict[element])
+        
         for dir in mapsets:
             dir_node = self.AddItem('Mapset: '+dir)
             self.seltree.SetItemTextColour(dir_node,wx.Colour(50,50,200))
             try:
-                cmdlist = ['g.mlist', 'type=%s' % elementdict[element], 'mapset=%s' % dir]
-                elem_list = gcmd.Command(cmdlist).ReadStdOutput()
+                elem_list = filesdict[dir]
                 elem_list.sort()
                 for elem in elem_list:
                     if elem != '':

Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/mapdisp.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/mapdisp.py	2008-08-06 09:11:06 UTC (rev 32559)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/mapdisp.py	2008-08-06 09:21:46 UTC (rev 32560)
@@ -3,6 +3,7 @@
 
 CLASSES:
  - Command
+ - MapWindow
  - BufferedWindow
  - MapFrame
  - MapApp
@@ -121,8 +122,78 @@
 
         sys.exit()
 
-class BufferedWindow(wx.Window):
+class MapWindow(object):
+    """Abstract map window class
+
+    Parent for BufferedWindow class (2D display mode) and
+    GLWindow (3D display mode)
     """
+    def __init__(self, parent, id,
+                 pos=wx.DefaultPosition,
+                 size=wx.DefaultSize,
+                 style=wx.NO_FULL_REPAINT_ON_RESIZE,
+                 Map=None, tree=None, gismgr=None):
+        pass
+
+    def EraseMap(self):
+        """
+        Erase the canvas (virtual method)
+        """
+        pass
+
+    def UpdateMap(self):
+        """
+        Updates the canvas anytime there is a change to the
+        underlaying images or to the geometry of the canvas.
+        """
+        pass
+
+    def OnLeftDown(self, event):
+        pass
+
+    def OnLeftUp(self, event):
+        pass
+
+    def OnMouseMotion(self, event):
+        pass
+
+    def OnZoomToMap(self, event):
+        pass
+
+    def OnZoomToRaster(self, event):
+        pass
+
+    def GetSelectedLayer(self, type='layer'):
+        """Get selected layer from layer tree
+
+        @param type 'item' / 'layer' / 'nviz'
+
+        @return layer / map layer properties / nviz properties
+        @return None on failure
+        """
+        # get currently selected map layer
+        if not self.tree or not self.tree.GetSelection():
+            return None
+        
+        item = self.tree.GetSelection()
+        if not item.IsChecked():
+            return None
+
+        if type == 'item':
+            return item
+        
+        try:
+            if type == 'nviz':
+                layer = self.tree.GetPyData(item)[0]['nviz']
+            else:
+                layer = self.tree.GetPyData(item)[0]['maplayer']
+        except:
+            layer = None
+            
+        return layer
+
+class BufferedWindow(MapWindow, wx.Window):
+    """
     A Buffered window class.
 
     When the drawing needs to change, you app needs to call the
@@ -137,7 +208,10 @@
                  style=wx.NO_FULL_REPAINT_ON_RESIZE,
                  Map=None, tree=None, gismgr=None):
 
+        MapWindow.__init__(self, parent, id, pos, size, style,
+                           Map, tree, gismgr)
         wx.Window.__init__(self, parent, id, pos, size, style)
+
         self.parent = parent
         self.Map = Map
         self.tree = tree
@@ -540,13 +614,12 @@
 
     def UpdateMap(self, render=True, renderVector=True):
         """
-        Updates the canvas anytime there is a change to the underlaying images
-        or to the geometry of the canvas.
+        Updates the canvas anytime there is a change to the
+        underlaying images or to the geometry of the canvas.
 
         @param render re-render map composition
         @param renderVector re-render vector map layer enabled for editing (used for digitizer)
         """
-
         start = time.clock()
 
         self.resize = False
@@ -713,7 +786,7 @@
 
     def EraseMap(self):
         """
-        Erase the map display
+        Erase the canvas
         """
         self.Draw(self.pdc, pdctype='clear')
 
@@ -2088,16 +2161,8 @@
         """
         zoomreg = {}
 
-        # find selected map
-        if not self.tree or not self.tree.GetSelection():
-            return
-
-        item  = self.tree.GetSelection()
-        try:
-            layer = self.tree.GetPyData(item)[0]['maplayer']
-        except:
-            layer = None
-
+        layer = self.GetSelectedLayer()
+        
         if layer is None:
             return
 
@@ -2362,7 +2427,8 @@
         #
         self.toolbars = { 'map' : None,
                           'vdigit' : None,
-                          'georect' : None }
+                          'georect' : None, 
+                          'nviz' : None }
         for toolb in toolbars:
             self.AddToolbar(toolb)
 
@@ -2422,9 +2488,14 @@
         #
         # Init map display (buffered DC & set default cursor)
         #
-        self.MapWindow = BufferedWindow(self, id=wx.ID_ANY, Map=self.Map, tree=self.tree, gismgr=self.gismanager)
+        self.MapWindow2D = BufferedWindow(self, id=wx.ID_ANY,
+                                          Map=self.Map, tree=self.tree, gismgr=self.gismanager)
+        # default is 2D display mode
+        self.MapWindow = self.MapWindow2D
         self.MapWindow.Bind(wx.EVT_MOTION, self.OnMotion)
         self.MapWindow.SetCursor(self.cursors["default"])
+        # used by Nviz (3D display mode)
+        self.MapWindow3D = None 
 
         #
         # initialize region values
@@ -2488,7 +2559,8 @@
          - map basic map toolbar
          - digit vector digitizer
          - georect georectifier
-         """
+        """
+        # default toolbar
         if name == "map":
             self.toolbars['map'] = toolbars.MapToolbar(self, self.Map)
 
@@ -2499,8 +2571,8 @@
                               LeftDockable(False).RightDockable(False).
                               BottomDockable(False).TopDockable(True).
                               CloseButton(False).Layer(2))
-
-        if name == "vdigit":
+        # vector digitizer
+        elif name == "vdigit":
             self.toolbars['vdigit'] = toolbars.VDigitToolbar(self, self.Map, self.tree)
 
             for toolRow in range(0, self.toolbars['vdigit'].numOfRows):
@@ -2517,18 +2589,98 @@
             self.MapWindow.zoomtype = 0
             self.MapWindow.pen     = wx.Pen(colour='red',   width=2, style=wx.SOLID)
             self.MapWindow.polypen = wx.Pen(colour='green', width=2, style=wx.SOLID)
-
-        if name == "georect":
+        # georectifier
+        elif name == "georect":
             self.toolbars['georect'] = toolbars.GRToolbar(self, self.Map)
 
             self._mgr.AddPane(self.toolbars['georect'].toolbar,
                               wx.aui.AuiPaneInfo().
-                              Name("georecttoolbar").Caption(_("Georectification Toolbar")).
+                              Name("georecttoolbar").Caption(_("Georectification toolbar")).
                               ToolbarPane().Top().
                               LeftDockable(False).RightDockable(False).
                               BottomDockable(False).TopDockable(True).
                               CloseButton(False).Layer(2))
+        # nviz
+        elif name == "nviz":
+            import nviz
 
+            # check for GLCanvas and OpenGL
+            msg = None
+            if not nviz.haveGLCanvas:
+                msg = _("Unable to start Nviz. The GLCanvas class has not been "
+                        "included with this build "
+                        "of wxPython! Switching back to "
+                        "2D display mode.\n\nDetails: %s" % nviz.errorMsg)
+            if not nviz.haveOpenGL:
+                msg = _("Unable to start Nviz. The OpenGL package "
+                        "was not found. You can get it "
+                        "at http://PyOpenGL.sourceforge.net. "
+                        "Switching back to 2D display mode.\n\nDetails: %s" % nviz.errorMsg)
+            if not nviz.haveNviz:
+                msg = _("Unable to start Nviz. Python extension "
+                        "for Nviz was not found. "
+                        "Switching back to 2D display mode.\n\nDetails: %s" % nviz.errorMsg)
+
+            if msg:
+                wx.MessageBox(parent=self,
+                              message=msg,
+                              caption=_("Error"))
+                return
+
+            #
+            # add Nviz toolbar and disable 2D display mode tools
+            #
+            self.toolbars['nviz'] = toolbars.NvizToolbar(self, self.Map)
+            self.toolbars['map'].Enable2D(False)
+
+            #
+            # update status bar
+            #
+            self.toggleStatus.Enable(False)
+
+            #
+            # erase map window
+            #
+            self.MapWindow.EraseMap()
+
+            busy = wx.BusyInfo(message=_("Please wait, loading data..."),
+                               parent=self)
+            wx.Yield()
+        
+            #
+            # create GL window & NVIZ toolbar
+            #
+            if not self.MapWindow3D:
+                self.MapWindow3D = nviz.GLWindow(self, id=wx.ID_ANY,
+                                                 Map=self.Map, tree=self.tree, gismgr=self.gismanager)
+                self.nvizToolWin = nviz.NvizToolWindow(self, id=wx.ID_ANY,
+                                                       mapWindow=self.MapWindow3D)
+                self.MapWindow3D.OnPaint(None) # -> LoadData
+
+            busy.Destroy()
+
+            self.nvizToolWin.Show()
+
+            #
+            # 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'].toolbar,
+                              wx.aui.AuiPaneInfo().
+                              Name("nviztoolbar").Caption(_("Nviz toolbar")).
+                              ToolbarPane().Top().Row(1).
+                              LeftDockable(False).RightDockable(False).
+                              BottomDockable(False).TopDockable(True).
+                              CloseButton(False).Layer(2))
+            self.MapWindow = self.MapWindow3D
+            self.SetStatusText("", 0)
+            
         self._mgr.Update()
 
     def RemoveToolbar (self, name):
@@ -2546,9 +2698,31 @@
             for toolRow in range(0, self.toolbars['vdigit'].numOfRows):
                 self._mgr.DetachPane (self.toolbars['vdigit'].toolbar[toolRow])
                 self.toolbars['vdigit'].toolbar[toolRow].Destroy()
-            self.toolbars['vdigit'] = None
+        else:
+            self._mgr.DetachPane (self.toolbars[name].toolbar)
+            self.toolbars[name].toolbar.Destroy()
 
-        self.toolbars['map'].combo.SetValue ("Tools");
+        self.toolbars[name] = None
+
+        if name == 'nviz':
+            # hide nviz tools
+            self.nvizToolWin.Hide()
+            # 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
+        
+        self.toolbars['map'].combo.SetValue ("Tools")
+        self.toolbars['map'].Enable2D(True)
+        self.toggleStatus.Enable(True)
+
         self._mgr.Update()
 
     def __InitDisplay(self):

Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/menudata.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/menudata.py	2008-08-06 09:11:06 UTC (rev 32559)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/menudata.py	2008-08-06 09:21:46 UTC (rev 32560)
@@ -70,7 +70,7 @@
                                  "self.OnMenuCmd",
                                  "r.in.gdal"),
                                 (_("Multiple raster data import using GDAL"),
-                                 _("Import selected GDAL layers tpo GRASS raster maps using r.in.gdal."),
+                                 _("Converts selected GDAL layers to GRASS raster maps using r.in.gdal."),
                                  "self.OnImportGdalLayers",
                                  ""),
 
@@ -168,7 +168,7 @@
                                  "self.OnImportDxfFile",
                                  ""),
                                 ("","","", ""),
-
+                                
                                 (_("ESRI e00 import"),
                                  _("Import E00 file into a vector map."),
                                  "self.OnMenuCmd",

Copied: grass/branches/develbranch_6/gui/wxpython/gui_modules/nviz.py (from rev 32556, grass/trunk/gui/wxpython/gui_modules/nviz.py)
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/nviz.py	                        (rev 0)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/nviz.py	2008-08-06 09:21:46 UTC (rev 32560)
@@ -0,0 +1,3038 @@
+"""
+ at package nviz.py
+
+ at brief 2.5/3D visialization mode for Map Display Window
+
+List of classes:
+ - GLWindow
+ - NvizToolWindow
+ - ViewPositionWindow
+
+(C) 2008 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)
+"""
+
+import os
+import sys
+import time
+import copy
+
+from threading import Thread
+
+import wx
+import wx.lib.colourselect as csel
+import wx.lib.scrolledpanel as scrolled
+errorMsg = ''
+try:
+    from wx import glcanvas
+    haveGLCanvas = True
+except ImportError, e:
+    haveGLCanvas = False
+    errorMsg = e
+try:
+    from OpenGL.GL import *
+    from OpenGL.GLUT import *
+    haveOpenGL = True
+except ImportError, e:
+    haveOpenGL = False
+    errorMsg = e
+
+import globalvar
+import gcmd
+import gselect
+from debug import Debug as Debug
+from mapdisp import MapWindow as MapWindow
+from preferences import globalSettings as UserSettings
+try:
+    nvizPath = os.path.join(globalvar.ETCWXDIR, "nviz")
+    sys.path.append(nvizPath)
+    import grass6_wxnviz as wxnviz
+    haveNviz = True
+except ImportError, e:
+    haveNviz = False
+    errorMsg = e
+
+class GLWindow(MapWindow, glcanvas.GLCanvas):
+    """OpenGL canvas for Map Display Window"""
+    def __init__(self, parent, id,
+                 pos=wx.DefaultPosition,
+                 size=wx.DefaultSize,
+                 style=wx.NO_FULL_REPAINT_ON_RESIZE,
+                 Map=None, tree=None, gismgr=None):
+
+        self.parent = parent # MapFrame
+        self.Map = Map
+        self.tree = tree
+        self.gismgr = gismgr
+        
+        glcanvas.GLCanvas.__init__(self, parent, id)
+        MapWindow.__init__(self, parent, id, pos, size, style,
+                           Map, tree, gismgr)
+
+
+        self.parent = parent # MapFrame
+
+        self.init = False
+        # render mode 
+        self.render = { 'quick' : False,
+                        # do not render vector lines in quick mode
+                        'vlines' : False,
+                        'vpoints' : False }
+
+        # list of loaded map layers
+        self.layers = {}
+        for type in ('raster', 'vlines', 'vpoints'):
+            self.layers[type] = {}
+            self.layers[type]['name'] = []
+            self.layers[type]['id'] = []
+
+        #
+        # create nviz instance
+        #
+        self.nvizClass = wxnviz.Nviz(sys.stderr)
+
+        #
+        # set current display
+        #
+        self.nvizClass.SetDisplay(self)
+
+        #
+        # initialize mouse position
+        #
+        self.lastX = self.x = 30
+        self.lastY = self.y = 30
+
+        #
+        # default values
+        #
+        self.view = copy.deepcopy(UserSettings.Get(group='nviz', key='view')) # copy
+        self.iview = UserSettings.Get(group='nviz', key='view', internal=True)
+        self.update = [] # list of properties to be updated
+
+        self.size = None
+        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_DOWN, self.OnLeftDown)
+        self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
+        self.Bind(wx.EVT_MOTION, self.OnMouseAction)
+        self.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouseAction)
+
+    def OnEraseBackground(self, event):
+        pass # do nothing, to avoid flashing on MSW
+
+    def OnSize(self, event):
+        self.size = self.parent.GetClientSize()
+        if self.GetContext():
+            Debug.msg(3, "GLCanvas.OnPaint(): w=%d, h=%d" % \
+                      (self.size.width, self.size.height))
+            self.SetCurrent()
+            self.nvizClass.ResizeWindow(self.size.width,
+                                        self.size.height)
+        
+        event.Skip()
+
+    def OnPaint(self, event):
+        Debug.msg(3, "GLCanvas.OnPaint()")
+
+        dc = wx.PaintDC(self)
+        self.SetCurrent()
+        
+        if not self.init:
+            self.nvizClass.InitView()
+
+            self.LoadDataLayers()
+
+            self.ResetView()
+            
+            if hasattr(self.parent, "nvizToolWin"):
+                self.parent.nvizToolWin.UpdatePage('view')
+                layer = self.GetSelectedLayer()
+                if layer:
+                    if layer.type == 'raster':
+                        self.parent.nvizToolWin.UpdatePage('surface')
+                    elif layer.type == 'vector':
+                        self.parent.nvizToolWin.UpdatePage('vector')
+
+                self.parent.nvizToolWin.UpdateSettings()
+
+                # update widgets
+                win = self.parent.nvizToolWin.FindWindowById( \
+                    self.parent.nvizToolWin.win['vector']['lines']['surface'])
+                win.SetItems(self.layers['raster']['name'])
+
+            self.init = True
+
+        self.UpdateMap()
+
+    def OnMouseAction(self, event):
+        # change position
+        if event.Dragging() and event.LeftIsDown():
+            self.lastX = self.lastY = self.x = self.y
+            self.x, self.y = event.GetPosition()
+            self.Refresh(False)
+
+        # change perspective with mouse wheel
+        wheel = event.GetWheelRotation()
+
+        if wheel != 0:
+            current  = event.GetPositionTuple()[:]
+            Debug.msg (5, "GLWindow.OnMouseMotion(): wheel=%d" % wheel)
+            prev_value = self.view['persp']['value']
+            if wheel > 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'] > 100:
+                self.view['persp']['value'] = 100
+
+            if prev_value != self.view['persp']['value']:
+                if hasattr(self.parent, "nvizToolWin"):
+                    self.parent.nvizToolWin.UpdateSettings()
+
+                    self.nvizClass.SetView(self.view['pos']['x'], self.view['pos']['y'],
+                                           self.iview['height']['value'],
+                                           self.view['persp']['value'],
+                                           self.view['twist']['value'])
+
+                # redraw map
+                self.OnPaint(None)
+
+                # update statusbar
+                ### self.parent.StatusbarUpdate()
+
+    def OnLeftDown(self, event):
+        self.CaptureMouse()
+        self.x, self.y = self.lastX, self.lastY = event.GetPosition()
+        
+    def OnLeftUp(self, event):
+        self.ReleaseMouse()
+
+    def UpdateMap(self, render=True):
+        """
+        Updates the canvas anytime there is a change to the
+        underlaying images or to the geometry of the canvas.
+
+        @param render re-render map composition
+        """
+        start = time.clock()
+
+        self.resize = False
+
+        # if self.size is None:
+        #    self.size = self.GetClientSize()
+        
+        #         w, h = self.size
+        #         w = float(max(w, 1.0))
+        #         h = float(max(h, 1.0))
+        #         d = float(min(w, h))
+        #         xScale = d / w
+        #         yScale = d / h
+        # print w, h, d, xScale, yScale
+        # print self.y, self.lastY, self.x, self.lastX
+        # print (self.y - self.lastY) * yScale, (self.x - self.lastX) * xScale 
+        # print self.x * xScale
+        
+        #glRotatef((self.y - self.lastY) * yScale, 1.0, 0.0, 0.0);
+        #glRotatef((self.x - self.lastX) * xScale, 0.0, 1.0, 0.0);
+
+        if self.render['quick'] is False:
+            self.parent.onRenderGauge.Show()
+            self.parent.onRenderGauge.SetRange(2)
+            self.parent.onRenderGauge.SetValue(0)
+
+        if 'view' in self.update:
+            if 'z-exag' in self.update:
+                self.nvizClass.SetZExag(self.view['z-exag']['value'])
+                self.update.remove('z-exag')
+            
+            self.nvizClass.SetView(self.view['pos']['x'], self.view['pos']['y'],
+                                   self.iview['height']['value'],
+                                   self.view['persp']['value'],
+                                   self.view['twist']['value'])
+
+            self.update.remove('view')
+
+        if self.render['quick'] is False:
+            self.parent.onRenderGauge.SetValue(1)
+            wx.Yield()
+            self.nvizClass.Draw(False, False, False)
+        elif self.render['quick'] is True:
+            # quick
+            self.nvizClass.Draw(True,
+                                self.render['vlines'],
+                                self.render['vpoints'])
+        else: # None -> reuse last rendered image
+            pass # TODO
+
+        self.SwapBuffers()
+
+        stop = time.clock()
+
+        if self.render['quick'] is False:
+            self.parent.onRenderGauge.SetValue(2)
+            # hide process bar
+            self.parent.onRenderGauge.Hide()
+
+        #
+        # update statusbar
+        #
+        # self.parent.StatusbarUpdate()
+
+        Debug.msg(3, "GLWindow.UpdateMap(): quick=%d, -> time=%g" % \
+                      (self.render['quick'], (stop-start)))
+
+        # print stop-start
+
+    def EraseMap(self):
+        """
+        Erase the canvas
+        """
+        self.nvizClass.EraseMap()
+        self.SwapBuffers()
+
+    def IsLoaded(self, item):
+        """Check if layer (item) is already loaded
+
+        @param item layer item
+        """
+        layer = self.tree.GetPyData(item)[0]['maplayer']
+        data = self.tree.GetPyData(item)[0]['nviz']
+
+        if not data:
+            return 0
+
+        if layer.type == 'raster':
+            if not data['surface'].has_key('object'):
+                return 0
+        elif layer.type == 'vector':
+            if not data['vlines'].has_key('object') and \
+                    not data['points'].has_key('object'):
+                return 0
+
+        return 1
+
+    def LoadDataLayers(self):
+        """Load raster/vector from current layer tree
+
+        @todo volumes
+        """
+        listOfItems = []
+        # load raster & vector maps
+        item = self.tree.GetFirstChild(self.tree.root)[0]
+        while item and item.IsOk():
+            type = self.tree.GetPyData(item)[0]['type']
+            if not item.IsChecked() or \
+                    type not in ('raster', 'vector'):
+                item = self.tree.GetNextSibling(item)
+                continue
+
+            listOfItems.append(item)
+
+            item = self.tree.GetNextSibling(item)
+
+        start = time.time()
+
+        while(len(listOfItems) > 0):
+            item = listOfItems.pop()
+            type = self.tree.GetPyData(item)[0]['type']
+            
+            try:
+                if type == 'raster':
+                    self.LoadRaster(item)
+            except gcmd.NvizError, e:
+                print >> sys.stderr, "Nviz:" + e.message
+
+            try:
+                if type == 'vector':
+                    data = self.tree.GetPyData(item)[0]['nviz']
+                    vecType = []
+                    if data and data.has_key('vector'):
+                        for v in ('lines', 'points'):
+                            if data['vector'][v]:
+                                vecType.append(v)
+                    self.LoadVector(item, vecType)
+            except gcmd.NvizError, e:
+                print >> sys.stderr, "Nviz:" + e.message
+            
+        stop = time.time()
+        
+        Debug.msg(3, "GLWindow.LoadDataLayers(): time=%f" % (stop-start))
+
+        # print stop - start
+
+    def SetLayerData(self, item, id, nvizType):
+        """Set map object properties
+
+        @param item layer item
+        @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 data is None:
+            # init data structure
+            self.tree.GetPyData(item)[0]['nviz'] = {}
+            data = self.tree.GetPyData(item)[0]['nviz']
+
+            if type == 'raster':
+                data[nvizType] = {}
+                for sec in ('attribute', 'draw', 'mask', 'position'):
+                    data[nvizType][sec] = {}
+
+                # reset to default properties
+                self.SetSurfaceDefaultProp(data[nvizType])
+                        
+            elif type == 'vector':
+                data['vector'] = {}
+                for sec in ('lines', 'points'):
+                    data['vector'][sec] = {}
+
+                # reset to default properties (lines/points)
+                self.SetVectorDefaultProp(data['vector'])
+        
+        else:
+            # check data
+            if type == 'vector':
+                if not data['vector']['lines']:
+                    self.SetVectorLinesDefaultProp(data['vector']['lines'])
+                if not data['vector']['points']:
+                    self.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 not in ('object'):
+                            self.update.append('%s:%s:%s' % (sec, sec1, sec2))
+
+        # set id
+        if id > 0:
+            if type == 'raster':
+               data[nvizType]['object'] = { 'id' : id,
+                                            'init' : False }
+            elif type == 'vector':
+                data['vector'][nvizType]['object'] = { 'id' : id,
+                                                       'init' : False }
+        
+        return data
+
+    def LoadRaster(self, item):
+        """Load raster map and set surface attributes
+
+        @param layer item
+        """
+        layer = self.tree.GetPyData(item)[0]['maplayer']
+
+        if layer.type != 'raster':
+            return
+
+        id = self.nvizClass.LoadSurface(str(layer.name), None, None)
+        if id < 0:
+            print >> sys.stderr, "Nviz:" + _("Loading raster map <%s> failed") % layer.name
+        
+        self.layers['raster']['name'].append(layer.name)
+        self.layers['raster']['id'].append(id)
+
+        # set default/workspace layer properties
+        data = self.SetLayerData(item, id, 'surface')
+
+        # update properties
+        self.UpdateLayerProperties(item)
+
+        # update tools window
+        if hasattr(self.parent, "nvizToolWin") and \
+                item == self.GetSelectedLayer(type='item'):
+            toolWin = self.parent.nvizToolWin
+            win = toolWin.FindWindowById( \
+                toolWin.win['vector']['lines']['surface'])
+            win.SetItems(self.layers['raster']['name'])
+
+            toolWin.UpdatePage('surface')
+            toolWin.SetPage('surface')
+            
+        return id
+
+    def UnloadRaster(self, item):
+        """Unload raster map
+
+        @param item layer item
+        """
+        layer = self.tree.GetPyData(item)[0]['maplayer']
+        data = self.tree.GetPyData(item)[0]['nviz']
+
+        id = data['surface']['object']['id']
+
+        if self.nvizClass.UnloadSurface(id) == 0:
+            print >> sys.stderr, "Nviz:" + _("Unable to unload raster map <%s>") % layer.name
+        else:
+            print "Nviz:" + _("Raster map <%s> unloaded successfully") % layer.name
+
+        data['surface'].pop('object')
+
+        idx = self.layers['raster']['id'].index(id)
+        del self.layers['raster']['name'][idx]
+        del self.layers['raster']['id'][idx]
+
+        # update tools window
+        if hasattr(self.parent, "nvizToolWin"):
+            toolWin = self.parent.nvizToolWin
+            win = toolWin.FindWindowById( \
+                toolWin.win['vector']['lines']['surface'])
+            win.SetItems(self.layers['raster']['name'])
+
+            # remove surface page
+            if toolWin.notebook.GetSelection() == toolWin.page['surface']['id']:
+                toolWin.notebook.RemovePage(toolWin.page['surface']['id'])
+                toolWin.page['surface']['id'] = -1
+                toolWin.page['settings']['id'] = 1
+        
+    def GetSurfaceMode(self, mode, style, shade, string=False):
+        """Determine surface draw mode"""
+        value = 0
+        desc = {}
+
+        if string:
+            if mode == 'coarse':
+                value |= wxnviz.DM_WIRE
+            elif mode == 'fine':
+                value |= wxnviz.DM_POLY
+            else: # both
+                value |= wxnviz.DM_WIRE_POLY
+
+            if style == 'wire':
+                value |= wxnviz.DM_GRID_WIRE
+            else: # surface
+                value |= wxnviz.DM_GRID_SURF
+
+            if shade == 'flat':
+                value |= wxnviz.DM_FLAT
+            else: # surface
+                value |= wxnviz.DM_GOURAUD
+
+            return value
+
+        # -> string is False
+        if mode == 0: # coarse
+            value |= wxnviz.DM_WIRE
+            desc['mode'] = 'coarse'
+        elif mode == 1: # fine
+            value |= wxnviz.DM_POLY
+            desc['mode'] = 'fine'
+        else: # both
+            value |= wxnviz.DM_WIRE_POLY
+            desc['mode'] = 'both'
+
+        if style == 0: # wire
+            value |= wxnviz.DM_GRID_WIRE
+            desc['style'] = 'wire'
+        else: # surface
+            value |= wxnviz.DM_GRID_SURF
+            desc['style'] = 'surface'
+
+        if shade == 0:
+            value |= wxnviz.DM_FLAT
+            desc['shading'] = 'flat'
+        else: # surface
+            value |= wxnviz.DM_GOURAUD
+            desc['shading'] = 'gouraud'
+
+        return (value, desc)
+    
+    def SetSurfaceDefaultProp(self, data):
+        """Set default surface properties"""
+        #
+        # attributes
+        #
+        data['attribute']['shine'] = {}
+        data['attribute']['shine']['map'] = \
+            UserSettings.Get(group='nviz', key='surface', subkey=['shine', 'map'])
+
+        data['attribute']['shine']['value'] = \
+            UserSettings.Get(group='nviz', key='surface', subkey=['shine', 'value'])
+
+        self.update.append('surface:attribute:shine')
+
+        #
+        # draw
+        #
+        for control, value in UserSettings.Get(group='nviz', key='surface', subkey='draw').iteritems():
+            if control[:3] == 'res':
+                if not data['draw'].has_key('resolution'):
+                    data['draw']['resolution'] = { 'all' : False }
+                if 'surface:draw:%s' % 'resolution' not in self.update:
+                    self.update.append('surface:draw:%s' % 'resolution')
+                    data['draw']['resolution'] = { 'all' : False,
+                                                   control[4:] : value }
+                else:
+                    data['draw']['resolution'][control[4:]] = value
+                continue
+            elif control not in ('style', 'shading'):
+                self.update.append('surface:draw:%s' % control)
+
+            if control == 'wire-color':
+                value = str(value[0]) + ':' + str(value[1]) + ':' + str(value[2])
+            elif control in ('mode', 'style', 'shading'):
+                if not data['draw'].has_key('mode'):
+                    data['draw']['mode'] = {}
+                continue
+
+            data['draw'][control] = { 'value' : value,
+                                      'all' : False }
+        
+        value, desc = self.GetSurfaceMode(UserSettings.Get(group='nviz', key='surface', subkey=['draw', 'mode']),
+                                          UserSettings.Get(group='nviz', key='surface', subkey=['draw', 'style']),
+                                          UserSettings.Get(group='nviz', key='surface', subkey=['draw', 'shading']))
+
+        data['draw']['mode'] = { 'value' : value,
+                                 'desc' : desc,
+                                 'all' : False }
+
+    def LoadVector(self, item, vecType=None):
+        """Load 2D or 3D vector map overlay
+
+        @param item layer item
+        @param vecType vector type (lines / points)
+        """
+        layer = self.tree.GetPyData(item)[0]['maplayer']
+
+        if layer.type != 'vector':
+            return
+
+        if vecType is None:
+            # load data type by default
+            vecType = []
+            for v in ('lines', 'points'):
+                if UserSettings.Get(group='nviz', key='vector',
+                                    subkey=[v, 'show']):
+                    vecType.append(v)
+
+        # set default properties
+        self.SetLayerData(item, -1, 'lines')
+        self.SetLayerData(item, -1, 'points')
+
+        id = -1
+        for type in vecType:
+            if type == 'lines':
+                id = self.nvizClass.LoadVector(str(layer.name), False)
+            else:
+                id = self.nvizClass.LoadVector(str(layer.name), True)
+
+            if id < 0:
+                print >> sys.stderr, "Nviz:" + _("Loading vector map <%(name)s> (%(type)s) failed") % \
+                    { 'name' : layer.name, 'type' : type }
+                continue
+
+            # update layer properties
+            self.SetLayerData(item, id, type)
+        
+            self.layers['v' + type]['name'].append(layer.name)
+            self.layers['v'  + type]['id'].append(id)
+        
+        # update properties
+        self.UpdateLayerProperties(item)
+        
+        # update tools window
+        if hasattr(self.parent, "nvizToolWin") and \
+                item == self.GetSelectedLayer(type='item'):
+            toolWin = self.parent.nvizToolWin
+
+            toolWin.UpdatePage('vector')
+            toolWin.SetPage('vector')
+        
+        return id
+
+    def UnloadVector(self, item, vecType=None):
+        """Unload vector map overlay
+
+        @param item layer item
+        @param vecType vector type (lines, points)
+        """
+        layer = self.tree.GetPyData(item)[0]['maplayer']
+        data = self.tree.GetPyData(item)[0]['nviz']['vector']
+
+        if vecType is None:
+            vecType = []
+            for v in ('lines', 'points'):
+                if UserSettings.Get(group='nviz', key='vector',
+                                    subkey=[v, 'show']):
+                    vecType.append(v)
+
+        for vtype in vecType:
+            if not data[vtype].has_key('object'):
+                continue
+
+            id = data[vtype]['object']['id']
+
+            if vtype == 'lines':
+                ret = self.nvizClass.UnloadVector(id, False)
+            else:
+                ret = self.nvizClass.UnloadVector(id, True)
+            if ret == 0:
+                print >> sys.stderr, "Nviz:" + _("Unable to unload vector map <%(name)s> (%(type)s)") % \
+                    { 'name': layer.name, 'type' : vtype }
+            else:
+                print "Nviz:" + _("Vector map <%(name)s> (%(type)s) unloaded successfully") % \
+                    { 'name' : layer.name, 'type' : vtype }
+
+            
+            data[vtype].pop('object')
+
+            idx = self.layers['v' + vtype]['id'].index(id)
+            del self.layers['v' + vtype]['name'][idx]
+            del self.layers['v' + vtype]['id'][idx]
+
+        # update tools window
+        if hasattr(self.parent, "nvizToolWin") and \
+                vecType is None:
+            toolWin = self.parent.nvizToolWin
+            # remove surface page
+            if toolWin.notebook.GetSelection() == toolWin.page['surface']['id']:
+                toolWin.notebook.RemovePage(toolWin.page['surface']['id'])
+                toolWin.page['surface']['id'] = -1
+                toolWin.page['settings']['id'] = 1
+
+
+    def SetVectorDefaultProp(self, data):
+        """Set default vector properties"""
+        self.SetVectorLinesDefaultProp(data['lines'])
+        self.SetVectorPointsDefaultProp(data['points'])
+
+    def SetVectorLinesDefaultProp(self, data):
+        """Set default vector properties -- lines"""
+        # width
+        data['width'] = UserSettings.Get(group='nviz', key='vector',
+                                                  subkey=['lines', 'width'])
+        
+        # color
+        value = UserSettings.Get(group='nviz', key='vector',
+                                 subkey=['lines', 'color'])
+        color = str(value[0]) + ':' + str(value[1]) + ':' + str(value[2])
+        data['color'] = color
+
+        # mode
+        if UserSettings.Get(group='nviz', key='vector',
+                            subkey=['lines', 'flat']):
+            type = 'flat'
+            map  = None
+        else:
+            if len(self.layers['raster']['name']) > 0:
+                type = 'surface'
+                map  = self.layers['raster']['name'][0]
+            else:
+                type = 'flat'
+                map = None
+
+        data['mode'] = {}
+        data['mode']['type'] = type
+        if map:
+            data['mode']['surface'] = map
+
+        # height
+        data['height'] = UserSettings.Get(group='nviz', key='vector',
+                                                   subkey=['lines', 'height'])
+
+        if data.has_key('object'):
+            self.update.append('vector:lines:color')
+            self.update.append('vector:lines:width')
+            self.update.append('vector:lines:mode')
+            self.update.append('vector:lines:height')
+
+    def SetVectorPointsDefaultProp(self, data):
+        """Set default vector properties -- points"""
+        # size
+        data['size'] = UserSettings.Get(group='nviz', key='vector',
+                                        subkey=['points', 'size'])
+
+        # width
+        data['width'] = UserSettings.Get(group='nviz', key='vector',
+                                         subkey=['points', 'width'])
+
+        # marker
+        data['marker'] = UserSettings.Get(group='nviz', key='vector',
+                                          subkey=['points', 'marker'])
+
+        # color
+        value = UserSettings.Get(group='nviz', key='vector',
+                                 subkey=['points', 'color'])
+        color = str(value[0]) + ':' + str(value[1]) + ':' + str(value[2])
+        data['color'] = color
+
+        # mode
+        data['mode'] = { 'type' : 'surface',
+                         'surface' : '' }
+        if len(self.layers['raster']['name']) > 0:
+            data['mode']['surface'] = self.layers['raster']['name'][0]
+        
+        # height
+        data['height'] = UserSettings.Get(group='nviz', key='vector',
+                                          subkey=['points', 'height'])
+
+        if data.has_key('object'):
+            self.update.append('vector:points:size')
+            self.update.append('vector:points:width')
+            self.update.append('vector:points:marker')
+            self.update.append('vector:points:color')
+            self.update.append('vector:points:surface')
+            self.update.append('vector:points:height')
+        
+    def Reset(self):
+        """Reset (unload data)"""
+        self.nvizClass.Reset()
+        self.init = False
+
+    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.nvizClass.SetViewportDefault()
+
+    def ResetView(self):
+        """Reset to default view"""
+        self.view['z-exag']['value'], \
+            self.iview['height']['value'], \
+            self.iview['height']['min'], \
+            self.iview['height']['max'] = self.nvizClass.SetViewDefault()
+        
+        self.view['pos']['x'] = UserSettings.Get(group='nviz', key='view',
+                                                 subkey=('pos', 'x'))
+        self.view['pos']['y'] = UserSettings.Get(group='nviz', key='view',
+                                                 subkey=('pos', 'x'))
+        self.view['persp']['value'] = UserSettings.Get(group='nviz', key='view',
+                                                       subkey=('persp', 'value'))
+
+        self.view['twist']['value'] = UserSettings.Get(group='nviz', key='view',
+                                                       subkey=('twist', 'value'))
+
+        self.update.append('view')
+
+    def UpdateLayerProperties(self, layer=None):
+        """Update data layer properties
+
+        @param layer layer item or None (for selected item)
+        """
+        if not layer:
+            mapLayer = self.GetSelectedLayer()
+            data = self.GetSelectedLayer(type='nviz')
+        else:
+            mapLayer = self.tree.GetPyData(layer)[0]['maplayer']
+            data = self.tree.GetPyData(layer)[0]['nviz']
+
+        if mapLayer.type == 'raster':
+            id = data['surface']['object']['id']
+            self.UpdateRasterProperties(id, data['surface'])
+            # -> initialized
+            data['surface']['object']['init'] = True
+
+        elif mapLayer.type == 'vector':
+            for type in ('lines', 'points'):
+                if data['vector'][type].has_key('object'):
+                    id = data['vector'][type]['object']['id']
+                    self.UpdateVectorProperties(id, data['vector'], type)
+                    # -> initialized
+                    data['vector'][type]['object']['init'] = True
+
+    def UpdateRasterProperties(self, id, data):
+        """Apply changes for surfaces"""
+
+        # surface attributes
+        for attrb in ('topo', 'color', 'mask',
+                     'transp', 'shine', 'emit'):
+            if 'surface:attribute:%s' % attrb in self.update:
+                map = data['attribute'][attrb]['map']
+                value = data['attribute'][attrb]['value']
+
+                if map is None: # unset
+                    # only optional attributes
+                    if attrb == 'mask':
+                        # TODO: invert mask
+                        # TODO: broken in NVIZ
+                        self.nvizClass.UnsetSurfaceMask(id)
+                    elif attrb == 'transp':
+                        self.nvizClass.UnsetSurfaceTransp(id)
+                    elif attrb == 'emit':
+                        self.nvizClass.UnsetSurfaceEmit(id) 
+                else:
+                    if type(value) == type('') and \
+                            len(value) <= 0: # ignore empty values (TODO: warning)
+                        continue
+                    if attrb == 'topo':
+                        self.nvizClass.SetSurfaceTopo(id, map, str(value)) 
+                    elif attrb == 'color':
+                        self.nvizClass.SetSurfaceColor(id, map, str(value))
+                    elif attrb == 'mask':
+                        # TODO: invert mask
+                        # TODO: broken in NVIZ
+                        self.nvizClass.SetSurfaceMask(id, False, str(value))
+                    elif attrb == 'transp':
+                        self.nvizClass.SetSurfaceTransp(id, map, str(value)) 
+                    elif attrb == 'shine':
+                        self.nvizClass.SetSurfaceShine(id, map, str(value)) 
+                    elif attrb == 'emit':
+                        self.nvizClass.SetSurfaceEmit(id, map, str(value)) 
+                self.update.remove('surface:attribute:%s' % attrb)
+
+        # draw res
+        if 'surface:draw:resolution' in self.update:
+            coarse = data['draw']['resolution']['coarse']
+            fine   = data['draw']['resolution']['fine']
+
+            if data['draw']['resolution']['all']:
+                self.nvizClass.SetSurfaceRes(-1, fine, coarse)
+            else:
+                self.nvizClass.SetSurfaceRes(id, fine, coarse)
+            self.update.remove('surface:draw:resolution')
+
+        # draw style
+        if 'surface:draw:mode' in self.update:
+            if data['draw']['mode']['value'] < 0: # need to calculate
+                data['draw']['mode']['value'] = \
+                    self.GetSurfaceMode(mode=data['draw']['mode']['desc']['mode'],
+                                        style=data['draw']['mode']['desc']['style'],
+                                        shade=data['draw']['mode']['desc']['shading'],
+                                        string=True)
+            style = data['draw']['mode']['value']
+            if data['draw']['mode']['all']:
+                self.nvizClass.SetSurfaceStyle(-1, style)
+            else:
+                self.nvizClass.SetSurfaceStyle(id, style)
+            self.update.remove('surface:draw:mode')
+
+        # wire color
+        if 'surface:draw:wire-color' in self.update:
+            color = data['draw']['wire-color']['value']
+            if data['draw']['wire-color']['all']:
+                self.nvizClass.SetWireColor(-1, str(color))
+            else:
+                self.nvizClass.SetWireColor(id, str(color))
+                self.update.remove('surface:draw:wire-color')
+        
+        # position
+        if 'surface:position' in self.update:
+            x = data['position']['x']
+            y = data['position']['y']
+            z = data['position']['z']
+            self.nvizClass.SetSurfacePosition(id, x, y, z)
+            self.update.remove('surface:position')
+
+    def UpdateVectorProperties(self, id, data, type):
+        """Update vector layer properties
+
+        @param id layer id
+        @param data properties
+        @param type lines/points
+        """
+        if type == 'points':
+            self.UpdateVectorPointsProperties(id, data[type])
+        else:
+            self.UpdateVectorLinesProperties(id, data[type])
+    
+    def UpdateVectorLinesProperties(self, id, data):
+        """Apply changes for vector line layer"""
+        # mode
+        if 'vector:lines:color' in self.update or \
+                'vector:lines:width' in self.update or \
+                'vector:lines:mode' in self.update:
+            width = data['width']
+            color = data['color']
+            if data['mode']['type'] == 'flat':
+                flat = True
+                if data.has_key('surface'):
+                    data.pop('surface')
+            else:
+                flat = False
+                if not 'vector:lines:surface' in self.update:
+                    self.update.append('vector:lines:surface')
+
+            self.nvizClass.SetVectorLineMode(id, color,
+                                             width, flat)
+            if 'vector:lines:color' in self.update:
+                self.update.remove('vector:lines:color')
+            if 'vector:lines:width' in self.update:
+                self.update.remove('vector:lines:width')
+            if 'vector:lines:mode' in self.update:
+                self.update.remove('vector:lines:mode')
+        # height
+        if 'vector:lines:height' in self.update:
+            self.nvizClass.SetVectorLineHeight(id,
+                                               data['height'])
+            self.update.remove('vector:lines:height')
+
+        # surface
+        if 'vector:lines:surface' in self.update:
+            idx = self.layers['raster']['name'].index(data['mode']['surface'])
+            if idx > -1:
+                self.nvizClass.SetVectorLineSurface(id,
+                                                    self.layers['raster']['id'][idx])
+            self.update.remove('vector:lines:surface')
+
+    def UpdateVectorPointsProperties(self, id, data):
+        """Apply changes for vector point layer"""
+        if 'vector:points:size' in self.update or \
+                'vector:points:width' in self.update or \
+                'vector:points:marker' in self.update or \
+                'vector:points:color' in self.update:
+            ret = self.nvizClass.SetVectorPointMode(id, data['color'],
+                                                    data['width'], float(data['size']),
+                                                    data['marker'] + 1)
+
+            error = None
+            if ret == -1:
+                error = _("Vector point layer not found (id=%d)") % id
+            elif ret == -2:
+                error = _("Unable to set data layer properties (id=%d)") % id
+
+            if error:
+                raise gcmd.NvizError(parent=self.parent,
+                                     message=_("Setting data layer properties failed.\n\n%s") % error)
+
+            for prop in ('size', 'width', 'marker', 'color'):
+                if 'vector:points:%s' % prop in self.update:
+                    self.update.remove('vector:points:%s' % prop)
+        
+        # height
+        if 'vector:points:height' in self.update:
+            self.nvizClass.SetVectorPointHeight(id,
+                                                data['height'])
+            self.update.remove('vector:points:height')
+
+        # surface
+        if 'vector:points:surface' in self.update:
+            idx = self.layers['raster']['name'].index(data['mode']['surface'])
+            if idx > -1:
+                self.nvizClass.SetVectorPointSurface(id,
+                                                     self.layers['raster']['id'][idx])
+            self.update.remove('vector:points:surface')
+
+class NvizToolWindow(wx.Frame):
+    """Experimental window for Nviz tools
+
+    @todo integrate with Map display
+    """
+    def __init__(self, parent=None, id=wx.ID_ANY, title=_("Nviz tools"),
+                 pos=wx.DefaultPosition, size=wx.DefaultSize,
+                 style=wx.DEFAULT_FRAME_STYLE, mapWindow=None):
+        
+        self.parent = parent # MapFrame
+        self.lmgr = self.parent.gismanager # GMFrame
+        self.mapWindow = mapWindow
+
+        wx.Frame.__init__(self, parent, id, title, pos, size, style)
+
+        #
+        # icon
+        #
+        self.SetIcon(wx.Icon(os.path.join(globalvar.ETCDIR, 'grass_nviz.ico'), wx.BITMAP_TYPE_ICO))
+
+        #
+        # dialog body
+        #
+        mainSizer = wx.BoxSizer(wx.VERTICAL)
+
+        self.win = {} # window ids
+
+        #
+        # notebook
+        #
+        self.notebook = wx.Notebook(parent=self, id=wx.ID_ANY, style=wx.BK_DEFAULT)
+
+        self.page = {}
+        # view page
+        self.__createViewPage()
+        self.page['view'] = { 'id' : 0 }
+        # surface page
+        size = self.__createSurfacePage()
+        size = (size[0] + 25, size[0] + 20)
+        # vector page
+        self.__createVectorPage()
+        # settings page
+        self.__createSettingsPage()
+        self.page['settings'] = { 'id' : 1 }
+        self.UpdatePage('settings')
+        self.pageChanging = False
+
+        mainSizer.Add(item=self.notebook, proportion=1,
+                      flag=wx.EXPAND | wx.ALL, border=5)
+
+        #
+        # bindings
+        #
+        self.Bind(wx.EVT_CLOSE, self.OnClose)
+
+        #
+        # layout
+        #
+        self.SetSizer(mainSizer)
+        mainSizer.Fit(self)
+
+        self.SetSize(size)
+
+    def __createViewPage(self):
+        """Create view settings page"""
+        panel = wx.Panel(parent=self.notebook, id=wx.ID_ANY)
+        self.notebook.AddPage(page=panel,
+                              text=" %s " % _("View"))
+        
+        pageSizer = wx.BoxSizer(wx.VERTICAL)
+        gridSizer = wx.GridBagSizer(vgap=3, hgap=3)
+
+        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)
+        viewPos = ViewPositionWindow(panel, id=wx.ID_ANY, size=(175, 175),
+                                     mapwindow=self.mapWindow)
+        self.win['view']['pos'] = viewPos.GetId()
+        posSizer.Add(item=viewPos,
+                     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
+        range = UserSettings.Get(group='nviz', key='view', subkey='persp', internal=True)
+        self.CreateControl(panel, dict=self.win['view'], name='persp',
+                           range=(range['min'], range['max']),
+                           bind=(self.OnViewChange, self.OnViewChanged, self.OnViewChangedSpin))
+        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),
+                      flag=wx.ALIGN_CENTER)        
+
+        # twist
+        range = UserSettings.Get(group='nviz', key='view', subkey='twist', internal=True)
+        self.CreateControl(panel, dict=self.win['view'], name='twist',
+                           range=(range['min'], range['max']),
+                           bind=(self.OnViewChange, self.OnViewChanged, self.OnViewChangedSpin))
+        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),
+                      flag=wx.ALIGN_CENTER)        
+
+        # height + z-exag
+        self.CreateControl(panel, dict=self.win['view'], name='height', sliderHor=False,
+                           range=(0, 1),
+                           bind=(self.OnViewChange, self.OnViewChanged, self.OnViewChangedSpin))
+        self.CreateControl(panel, dict=self.win['view'], name='z-exag', sliderHor=False,
+                           range=(0, 1),
+                           bind=(self.OnViewChange, self.OnViewChanged, self.OnViewChangedSpin))
+        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['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=wx.StaticText(panel, id=wx.ID_ANY, label=_("Z-exag:")),
+                      pos=(0, 2), flag=wx.ALIGN_LEFT, 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']),
+                        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)
+
+        # view setup + reset
+        viewSizer = wx.BoxSizer(wx.HORIZONTAL)
+
+        viewSizer.Add(item=wx.StaticText(panel, id=wx.ID_ANY,
+                                         label=_("Look at:")),
+                      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,
+                      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=reset, proportion=1,
+                      flag=wx.EXPAND | wx.ALL | wx.ALIGN_RIGHT,
+                      border=5)
+
+        gridSizer.AddGrowableCol(3)
+        gridSizer.Add(item=viewSizer, pos=(4, 0), span=(1, 2),
+                      flag=wx.EXPAND)
+
+        # body
+        pageSizer.Add(item=gridSizer, proportion=1,
+                      flag=wx.EXPAND | wx.ALL,
+                      border=5)
+
+        panel.SetSizer(pageSizer)
+
+        return panel.GetBestSize()
+
+    def __createSurfacePage(self):
+        """Create view settings page"""
+        panel = wx.Panel(parent=self.notebook, id=wx.ID_ANY)
+        self.page['surface'] = {}
+        self.page['surface']['id'] = -1
+        self.page['surface']['panel'] = panel.GetId()
+
+        # panel = scrolled.ScrolledPanel(parent=self.notebook, id=wx.ID_ANY)
+        # panel.SetupScrolling(scroll_x=True, scroll_y=True)
+
+        pageSizer = wx.BoxSizer(wx.VERTICAL)
+
+        self.win['surface'] = {}
+        #
+        # 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)
+
+        # labels
+        # col = 0
+        #         for type in (_("Attribute"),
+        #                      _("Use"),
+        #                      _("Map"),
+        #                      _("Constant")):
+        #             gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
+        #                                              label=type),
+        #                           pos=(0, col))
+        #             col += 1
+
+        # 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.OnSurfaceUse)
+            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=UserSettings.Get(group='nviz', key='surface',
+                                                                  subkey=['color', 'value']))
+                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.SetSurfaceUseMap(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=5)
+
+        #
+        # 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(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=(100, -1),
+                          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))
+
+        # resolution (mode)
+        gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
+                                         label=_("Resolution:")),
+                      pos=(0, 2), flag=wx.ALIGN_CENTER_VERTICAL)
+        resSizer = wx.BoxSizer(wx.HORIZONTAL)
+        resSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
+                                        label=_("coarse:")),
+                     flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=3)
+        resC = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
+                           initial=1,
+                           min=1,
+                           max=100)
+        resC.SetName("value")
+        self.win['surface']['draw']['res-coarse'] = resC.GetId()
+        resC.Bind(wx.EVT_SPINCTRL, self.OnSurfaceResolution)
+        resSizer.Add(item=resC, flag=wx.ALL, border=3)
+        
+        resSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
+                                        label=_("fine:")),
+                     flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=3)
+        resF = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
+                           initial=1,
+                           min=1,
+                           max=100)
+        resF.SetName("value")
+        self.win['surface']['draw']['res-fine'] = resF.GetId()
+        resF.Bind(wx.EVT_SPINCTRL, self.OnSurfaceResolution)
+        resSizer.Add(item=resF, flag=wx.ALL, border=3)
+
+        gridSizer.Add(item=resSizer, pos=(0, 3), span=(1, 2))
+
+        # style
+        gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
+                                         label=_("Coarse style:")),
+                      pos=(1, 0), 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_CENTER_VERTICAL,
+                      pos=(1, 1))
+
+        # shading
+        gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
+                                         label=_("Shading:")),
+                      pos=(1, 2), flag=wx.ALIGN_CENTER_VERTICAL)
+        shade = wx.Choice (parent=panel, id=wx.ID_ANY, size=(100, -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=(1, 3))
+
+        # color
+        gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
+                                         label=_("Wire color:")),
+                      pos=(2, 0), flag=wx.ALIGN_CENTER_VERTICAL)
+        color = csel.ColourSelect(panel, id=wx.ID_ANY)
+        color.SetName("colour")
+        color.Bind(csel.EVT_COLOURSELECT, self.OnSurfaceWireColor)
+        self.win['surface']['draw']['wire-color'] = color.GetId()
+        gridSizer.Add(item=color, flag=wx.ALIGN_CENTER_VERTICAL,
+                      pos=(2, 1))
+
+        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=5)
+
+        all = wx.Button(panel, id=wx.ID_ANY, label=_("All"))
+        all.SetToolTipString(_("Use for all loaded surfaces"))
+        # self.win['reset'] = reset.GetId()
+        all.Bind(wx.EVT_BUTTON, self.OnSurfaceModeAll)
+        gridSizer.Add(item=all, flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND,
+                      pos=(2, 4))
+
+        #
+        # 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=5)
+
+        #
+        # position
+        #
+        self.win['surface']['position'] = {}
+        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)
+
+        # position
+        axis = wx.Choice (parent=panel, id=wx.ID_ANY, size=(75, -1),
+                          choices = ["X",
+                                     "Y",
+                                     "Z"])
+        axis.SetSelection(0)
+        self.win['surface']['position']['axis'] = axis.GetId()
+        axis.Bind(wx.EVT_CHOICE, self.OnSurfaceAxis)
+        gridSizer.Add(item=axis, flag=wx.ALIGN_CENTER_VERTICAL,
+                      pos=(0, 0))
+        value = wx.Slider(parent=panel, id=wx.ID_ANY,
+                          value=0,
+                          minValue=-1e4,
+                          maxValue=1e4,
+                          style=wx.SL_HORIZONTAL | wx.SL_AUTOTICKS | \
+                              wx.SL_TOP | wx.SL_LABELS,
+                          size=(350, -1))
+        self.win['surface']['position']['pos'] = value.GetId()
+        value.Bind(wx.EVT_SCROLL, self.OnSurfacePosition)
+        gridSizer.Add(item=value, flag=wx.ALIGN_CENTER_VERTICAL,
+                      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.LEFT | wx.RIGHT | wx.BOTTOM,
+                      border=5)
+        
+        panel.SetSizer(pageSizer)
+        
+        return panel.GetBestSize()
+
+    def __createVectorPage(self):
+        """Create view settings page"""
+        panel = wx.Panel(parent=self.notebook, id=wx.ID_ANY)
+        self.page['vector'] = {}
+        self.page['vector']['id'] = -1
+        self.page['vector']['panel'] = panel.GetId()
+
+        pageSizer = wx.BoxSizer(wx.VERTICAL)
+
+        self.win['vector'] = {}
+
+        #
+        # desc
+        #
+        desc = wx.StaticText(parent=panel, id=wx.ID_ANY,
+                             label="")
+        self.win['vector']['desc'] = desc.GetId()
+        pageSizer.Add(item=desc, proportion=0,
+                      flag=wx.EXPAND | wx.ALL,
+                      border=10)
+
+        #
+        # vector lines
+        #
+        self.win['vector']['lines'] = {}
+
+        showLines = wx.CheckBox(parent=panel, id=wx.ID_ANY,
+                                label=_("Show vector lines"))
+        self.win['vector']['lines']['show'] = showLines.GetId()
+        showLines.Bind(wx.EVT_CHECKBOX, self.OnVectorShow)
+
+        pageSizer.Add(item=showLines, proportion=0,
+                      flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border=5)
+
+        box = wx.StaticBox (parent=panel, id=wx.ID_ANY,
+                            label=" %s " % (_("Vector lines")))
+        boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+        gridSizer = wx.GridBagSizer(vgap=5, hgap=5)
+
+        # width
+        gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
+                                         label=_("Width:")),
+                      pos=(0, 0), flag=wx.ALIGN_CENTER_VERTICAL)
+
+        width = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
+                            initial=1,
+                            min=1,
+                            max=100)
+        self.win['vector']['lines']['width'] = width.GetId()
+        width.Bind(wx.EVT_SPINCTRL, self.OnVectorLines)
+        gridSizer.Add(item=width, pos=(0, 1),
+                      flag=wx.ALIGN_CENTER_VERTICAL)
+
+        gridSizer.AddGrowableCol(2)
+
+        # color
+        gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
+                                         label=_("Color:")),
+                      pos=(0, 3), flag=wx.ALIGN_CENTER_VERTICAL)
+
+        color = csel.ColourSelect(panel, id=wx.ID_ANY,
+                                  colour=UserSettings.Get(group='nviz', key='vector',
+                                                          subkey=['lines', 'color']))
+        self.win['vector']['lines']['color'] = color.GetId()
+        color.Bind(csel.EVT_COLOURSELECT, self.OnVectorLines)
+
+        gridSizer.Add(item=color, pos=(0, 4))
+
+        gridSizer.AddGrowableCol(5)
+
+        # display
+        gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
+                                         label=_("Display:")),
+                      pos=(0, 6), flag=wx.ALIGN_CENTER_VERTICAL)
+
+        display = wx.Choice (parent=panel, id=wx.ID_ANY, size=(100, -1),
+                             choices = [_("on surface"),
+                                        _("flat")])
+        self.win['vector']['lines']['flat'] = display.GetId()
+        display.Bind(wx.EVT_CHOICE, self.OnVectorDisplay)
+
+        gridSizer.Add(item=display, flag=wx.ALIGN_CENTER_VERTICAL,
+                      pos=(0, 7))
+
+        # hight
+        gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
+                                         label=_("Hight above surface:")),
+                      pos=(1, 0), flag=wx.ALIGN_CENTER_VERTICAL,
+                      span=(1, 2))
+        
+        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)
+        self.win['vector']['lines']['surface'] = surface.GetId()
+        gridSizer.Add(item=surface, 
+                      pos=(1, 2), span=(1, 6),
+                      flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
+
+
+        self.CreateControl(panel, dict=self.win['vector']['lines'], name='height', size=300,
+                           range=(0, 1000),
+                           bind=(self.OnVectorHeight, self.OnVectorHeightFull, self.OnVectorHeightSpin))
+        gridSizer.Add(item=self.FindWindowById(self.win['vector']['lines']['height']['slider']),
+                      pos=(2, 2), span=(1, 6))
+        gridSizer.Add(item=self.FindWindowById(self.win['vector']['lines']['height']['spin']),
+                      pos=(3, 4),
+                      flag=wx.ALIGN_CENTER)
+
+        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=5)
+
+        #
+        # vector points
+        #
+        self.win['vector']['points'] = {}
+
+        showPoints = wx.CheckBox(parent=panel, id=wx.ID_ANY,
+                                 label=_("Show vector points"))
+        self.win['vector']['points']['show'] = showPoints.GetId()
+        showPoints.Bind(wx.EVT_CHECKBOX, self.OnVectorShow)
+
+        pageSizer.Add(item=showPoints, proportion=0,
+                      flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border=5)
+
+        box = wx.StaticBox (parent=panel, id=wx.ID_ANY,
+                            label=" %s " % (_("Vector points")))
+        boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+        gridSizer = wx.GridBagSizer(vgap=5, hgap=5)
+
+        # icon size
+        gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
+                                         label=_("Icon size:")),
+                      pos=(0, 0), flag=wx.ALIGN_CENTER_VERTICAL)
+
+        isize = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
+                            initial=1,
+                            min=1,
+                            max=1e6)
+        isize.SetName('value')
+        self.win['vector']['points']['size'] = isize.GetId()
+        isize.Bind(wx.EVT_SPINCTRL, self.OnVectorPoints)
+        gridSizer.Add(item=isize, pos=(0, 1),
+                      flag=wx.ALIGN_CENTER_VERTICAL)
+
+        # icon width
+        gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
+                                         label=_("width:")),
+                      pos=(0, 2), flag=wx.ALIGN_CENTER_VERTICAL)
+
+        iwidth = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
+                             initial=1,
+                             min=1,
+                             max=1e6)
+        iwidth.SetName('value')
+        self.win['vector']['points']['width'] = iwidth.GetId()
+        iwidth.Bind(wx.EVT_SPINCTRL, self.OnVectorPoints)
+        gridSizer.Add(item=iwidth, pos=(0, 3),
+                      flag=wx.ALIGN_CENTER_VERTICAL)
+
+        # icon symbol
+        gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
+                                         label=_("symbol:")),
+                      pos=(0, 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.Bind(wx.EVT_CHOICE, self.OnVectorPoints)
+        gridSizer.Add(item=isym, flag=wx.ALIGN_CENTER_VERTICAL,
+                      pos=(0, 5))
+
+        # icon color
+        gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
+                                         label=_("color:")),
+                      pos=(0, 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.Bind(csel.EVT_COLOURSELECT, self.OnVectorPoints)
+        gridSizer.Add(item=icolor, flag=wx.ALIGN_CENTER_VERTICAL,
+                      pos=(0, 7))
+
+        # high
+        gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
+                                         label=_("Hight above surface:")),
+                      pos=(1, 0), flag=wx.ALIGN_CENTER_VERTICAL,
+                      span=(1, 2))
+        
+        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)
+        self.win['vector']['points']['surface'] = surface.GetId()
+        gridSizer.Add(item=surface, 
+                      pos=(1, 2), span=(1, 6),
+                      flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
+
+        self.CreateControl(panel, dict=self.win['vector']['points'], name='height', size=300,
+                           range=(0, 1000),
+                           bind=(self.OnVectorHeight, self.OnVectorHeightFull, self.OnVectorHeightSpin))
+        gridSizer.Add(item=self.FindWindowById(self.win['vector']['points']['height']['slider']),
+                      pos=(2, 2), span=(1, 6))
+        gridSizer.Add(item=self.FindWindowById(self.win['vector']['points']['height']['spin']),
+                      pos=(3, 4),
+                      flag=wx.ALIGN_CENTER)
+
+        
+        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=5)
+
+
+        panel.SetSizer(pageSizer)
+
+        return panel.GetBestSize()
+
+    def __createSettingsPage(self):
+        """Create settings page"""
+        panel = wx.Panel(parent=self.notebook, id=wx.ID_ANY)
+        self.notebook.AddPage(page=panel,
+                              text=" %s " % _("Settings"))
+        
+        pageSizer = wx.BoxSizer(wx.VERTICAL)
+
+        self.win['settings'] = {}
+
+        #
+        # general
+        #
+        self.win['settings']['general'] = {}
+        box = wx.StaticBox (parent=panel, id=wx.ID_ANY,
+                            label=" %s " % (_("General")))
+        boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+        gridSizer = wx.GridBagSizer(vgap=3, hgap=3)
+
+        # 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']))
+        self.win['settings']['general']['bgcolor'] = color.GetId()
+        color.Bind(csel.EVT_COLOURSELECT, self.OnBgColor)
+        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=5)
+
+        #
+        # view
+        #
+        self.win['settings']['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['settings']['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['settings']['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['settings']['view']['persp']['step'] = pstep.GetId()
+        gridSizer.Add(item=pstep, pos=(0, 4),
+                      flag=wx.ALIGN_CENTER_VERTICAL)
+
+        # position
+        self.win['settings']['view']['pos'] = {}
+        posvals = UserSettings.Get(group='nviz', key='view', subkey='pos')
+        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['settings']['view']['pos']['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['settings']['view']['pos']['y'] = py.GetId()
+        gridSizer.Add(item=py, pos=(1, 4),
+                      flag=wx.ALIGN_CENTER_VERTICAL)
+
+        # height
+        self.win['settings']['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=hvals['max']-1)
+        self.win['settings']['view']['height']['step'] = hstep.GetId()
+        gridSizer.Add(item=hstep, pos=(2, 2),
+                      flag=wx.ALIGN_CENTER_VERTICAL)
+
+        # twist
+        self.win['settings']['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['settings']['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['settings']['view']['twist']['step'] = tstep.GetId()
+        gridSizer.Add(item=tstep, pos=(3, 4),
+                      flag=wx.ALIGN_CENTER_VERTICAL)
+
+        # z-exag
+        self.win['settings']['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['settings']['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['settings']['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=5)
+
+        #
+        # surface
+        #
+        self.win['settings']['surface'] = {}
+        box = wx.StaticBox (parent=panel, id=wx.ID_ANY,
+                            label=" %s " % (_("Surface")))
+        boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+        gridSizer = wx.GridBagSizer(vgap=3, hgap=3)
+
+
+        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=5)
+
+        #
+        # vector lines
+        #
+        self.win['settings']['vector'] = {}
+        self.win['settings']['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['settings']['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=5)
+
+        #
+        # vector points
+        #
+        self.win['settings']['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['settings']['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['settings']['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=_("Witdh:")),
+                      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['settings']['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['settings']['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['settings']['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=5)
+
+        #
+        # buttons
+        #
+        btnDefault = wx.Button(panel, wx.ID_CANCEL, label=_("Default"))
+        btnSave = wx.Button(panel, wx.ID_SAVE)
+        btnApply = wx.Button(panel, wx.ID_APPLY)
+
+        btnDefault.Bind(wx.EVT_BUTTON, self.OnDefault)
+        btnDefault.SetToolTipString(_("Restore default settings"))
+        btnApply.Bind(wx.EVT_BUTTON, self.OnApply)
+        btnApply.SetToolTipString(_("Apply changes for the current session"))
+        btnSave.Bind(wx.EVT_BUTTON, self.OnSave)
+        btnSave.SetToolTipString(_("Apply and save changes to user settings file (default for next sessions)"))
+        btnSave.SetDefault()
+
+        btnSizer = wx.StdDialogButtonSizer()
+        btnSizer.AddButton(btnDefault)
+        btnSizer.AddButton(btnApply)
+        btnSizer.AddButton(btnSave)
+        btnSizer.Realize()
+
+        pageSizer.Add(item=btnSizer, proportion=1,
+                      flag=wx.EXPAND | wx.ALL | wx.ALIGN_RIGHT | wx.ALIGN_BOTTOM,
+                      border=5)
+
+        panel.SetSizer(pageSizer)
+
+        return panel.GetBestSize()
+
+    def CreateControl(self, parent, dict, name, range, bind, sliderHor=True, size=200):
+        """Add control (Slider + SpinCtrl)"""
+        dict[name] = {}
+        if sliderHor:
+            style = wx.SL_HORIZONTAL | wx.SL_AUTOTICKS | \
+                wx.SL_BOTTOM
+            sizeW = (size, -1)
+        else:
+            style = wx.SL_VERTICAL | wx.SL_AUTOTICKS | \
+                wx.SL_BOTTOM | wx.SL_INVERSE
+            sizeW = (-1, size)
+        try:
+            val = self.mapWindow.view[name]['value']
+        except KeyError:
+            val=-1
+        slider = wx.Slider(parent=parent, id=wx.ID_ANY,
+                           value=val,
+                           minValue=range[0],
+                           maxValue=range[1],
+                           style=style,
+                           size=sizeW)
+        slider.SetName('slider')
+        slider.Bind(wx.EVT_SCROLL, bind[0])
+        slider.Bind(wx.EVT_SCROLL_CHANGED, bind[1])
+        dict[name]['slider'] = slider.GetId()
+
+        spin = wx.SpinCtrl(parent=parent, id=wx.ID_ANY, size=(65, -1),
+                           initial=val,
+                           min=range[0],
+                           max=range[1])
+        #         spin = wx.SpinButton(parent=parent, id=wx.ID_ANY)
+        #         spin.SetValue (self.mapWindow.view[name]['value'])
+        #         spin.SetRange(self.mapWindow.view[name]['min'],
+        #                      self.mapWindow.view[name]['max'])
+
+        # no 'changed' event ... (FIXME)
+        spin.SetName('spin')
+        spin.Bind(wx.EVT_SPINCTRL, bind[2])
+        dict[name]['spin'] = spin.GetId()
+
+    def UpdateSettings(self):
+        """Update dialog settings"""
+        for control in ('height',
+                        '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:
+                    value = self.mapWindow.view[control]['value']
+                self.FindWindowById(win).SetValue(value)
+
+        self.FindWindowById(self.win['view']['pos']).Draw()
+        self.FindWindowById(self.win['view']['pos']).Refresh(False)
+        
+        self.Refresh(False)
+
+    def __GetWindowName(self, dict, id):
+        for name in dict.iterkeys():
+            if type(dict[name]) is type({}):
+                for win in dict[name].itervalues():
+                    if win == id:
+                        return name
+            else:
+                if dict[name] == id:
+                    return name
+
+        return None
+
+    def OnViewChange(self, event):
+        """Change view, render in quick mode"""
+        # find control
+        winName = self.__GetWindowName(self.win['view'], event.GetId())
+        if not winName:
+            return
+
+        if winName == 'height':
+            view = self.mapWindow.iview # internal
+        else:
+            view = self.mapWindow.view
+
+        view[winName]['value'] = event.GetInt()
+
+        for win in self.win['view'][winName].itervalues():
+            self.FindWindowById(win).SetValue(view[winName]['value'])
+
+        self.mapWindow.update.append('view')
+        if winName == 'z-exag':
+            self.mapWindow.update.append('z-exag')
+        
+        self.mapWindow.render['quick'] = True
+        self.mapWindow.Refresh(False)
+
+    def OnViewChanged(self, event):
+        """View changed, render in full resolution"""
+        self.mapWindow.render['quick'] = False
+        self.mapWindow.Refresh(False)
+
+    def OnViewChangedSpin(self, event):
+        """View changed, render in full resolution"""
+        # TODO: use step value instead
+
+        self.OnViewChange(event)
+        self.OnViewChanged(None)
+
+    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['pos']['x'] = 0.5
+            self.mapWindow.view['pos']['y'] = 0.5
+        elif sel == 1: # north
+            self.mapWindow.view['pos']['x'] = 0.5
+            self.mapWindow.view['pos']['y'] = 0.0
+        elif sel == 2: # south
+            self.mapWindow.view['pos']['x'] = 0.5
+            self.mapWindow.view['pos']['y'] = 1.0
+        elif sel == 3: # east
+            self.mapWindow.view['pos']['x'] = 1.0
+            self.mapWindow.view['pos']['y'] = 0.5
+        elif sel == 4: # west
+            self.mapWindow.view['pos']['x'] = 0.0
+            self.mapWindow.view['pos']['y'] = 0.5
+        elif sel == 5: # north-west
+            self.mapWindow.view['pos']['x'] = 0.0
+            self.mapWindow.view['pos']['y'] = 0.0
+        elif sel == 6: # north-east
+            self.mapWindow.view['pos']['x'] = 1.0
+            self.mapWindow.view['pos']['y'] = 0.0
+        elif sel == 7: # south-east
+            self.mapWindow.view['pos']['x'] = 1.0
+            self.mapWindow.view['pos']['y'] = 1.0
+        elif sel == 8: # south-west
+            self.mapWindow.view['pos']['x'] = 0.0
+            self.mapWindow.view['pos']['y'] = 1.0
+
+        self.mapWindow.update.append('view')
+
+        self.UpdateSettings()
+
+        self.mapWindow.Refresh(False)
+
+    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['settings'][subgroup][subkey][subvalue])
+                    val = settings[subgroup][subkey][subvalue]
+                    if subkey == 'pos':
+                        val = int(val * 100)
+
+                    win.SetValue(val)
+        
+        event.Skip()
+
+    def OnApply(self, event):
+        """Apply button pressed"""
+        if self.notebook.GetSelection() == self.page['settings']['id']:
+            self.ApplySettings()
+        
+        if event:
+            event.Skip()
+
+    def ApplySettings(self):
+        """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['settings'][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
+                    
+    def OnSave(self, event):
+        """OK button pressed
+        
+        Apply changes, update map and save settings of selected layer
+        """
+        #
+        # apply changes
+        #
+        self.OnApply(None)
+
+        if self.notebook.GetSelection() == self.page['settings']['id']:
+            fileSettings = {}
+            UserSettings.ReadSettingsFile(settings=fileSettings)
+            fileSettings['nviz'] = UserSettings.Get(group='nviz')
+            file = UserSettings.SaveToFile(fileSettings)
+            self.lmgr.goutput.WriteLog(_('Nviz settings saved to file <%s>.') % file)
+
+    def OnBgColor(self, event):
+        """Background color changed"""
+        color = event.GetValue()
+        color = str(color[0]) + ':' + str(color[1]) + ':' + str(color[2])
+
+        self.mapWindow.nvizClass.SetBgColor(str(color))
+
+        if self.parent.autoRender.IsChecked():
+            self.mapWindow.Refresh(False)
+        
+    def OnClose(self, event):
+        """Close button pressed
+        
+        Close dialog
+        """
+        self.Hide()
+
+    def OnSurfaceUse(self, event):
+        """Surface attribute -- use -- map/constant"""
+        if not self.mapWindow.init:
+            return
+
+        wx.Yield()
+
+        # find attribute row
+        attrb = self.__GetWindowName(self.win['surface'], event.GetId())
+        if not attrb:
+            return
+
+        selection = event.GetSelection()
+        if self.win['surface'][attrb]['required']: # no 'unset'
+            selection += 1
+        if selection == 0: # unset
+            useMap = None
+            value = ''
+        elif selection == 1: # map
+            useMap = True
+            value = self.FindWindowById(self.win['surface'][attrb]['map']).GetValue()
+        elif selection == 2: # constant
+            useMap = False
+            if attrb == 'color':
+                value = self.FindWindowById(self.win['surface'][attrb]['const']).GetColour()
+                value = str(value[0]) + ':' + str(value[1]) + ':' + str(value[2])
+            else:
+                value = self.FindWindowById(self.win['surface'][attrb]['const']).GetValue()
+
+        self.SetSurfaceUseMap(attrb, useMap)
+        
+        self.mapWindow.update.append('surface:attribute:%s' % attrb)
+        data = self.mapWindow.GetSelectedLayer(type='nviz')
+        data['surface']['attribute'][attrb] = { 'map' : useMap,
+                                                'value' : str(value),
+                                                }
+        self.mapWindow.UpdateLayerProperties()
+
+        if self.parent.autoRender.IsChecked():
+            self.mapWindow.Refresh(False)
+
+    def SetSurfaceUseMap(self, attrb, map=None):
+        if attrb in ('topo', 'color', 'shine'):
+            incSel = -1 # decrement selection (no 'unset')
+        else:
+            incSel = 0
+
+        if map is True: # map
+            if attrb != 'topo': # changing map topography not allowed
+                self.FindWindowById(self.win['surface'][attrb]['map'] + 1).Enable(True) # FIXME
+            if self.win['surface'][attrb]['const']:
+                self.FindWindowById(self.win['surface'][attrb]['const']).Enable(False)
+            self.FindWindowById(self.win['surface'][attrb]['use']).SetSelection(1 + incSel)
+        elif map is False: # const
+            self.FindWindowById(self.win['surface'][attrb]['map'] + 1).Enable(False)
+            if self.win['surface'][attrb]['const']:
+                self.FindWindowById(self.win['surface'][attrb]['const']).Enable(True)
+            self.FindWindowById(self.win['surface'][attrb]['use']).SetSelection(2 + incSel)
+        else: # unset
+            self.FindWindowById(self.win['surface'][attrb]['map'] + 1).Enable(False)
+            if self.win['surface'][attrb]['const']:
+                self.FindWindowById(self.win['surface'][attrb]['const']).Enable(False)
+            self.FindWindowById(self.win['surface'][attrb]['use']).SetSelection(0)
+
+    def OnSurfaceMap(self, event):
+        """Set surface attribute"""
+        if not self.mapWindow.init:
+            return
+
+        attrb = self.__GetWindowName(self.win['surface'], event.GetId()) 
+        if not attrb:
+            return
+
+        selection = self.FindWindowById(self.win['surface'][attrb]['use']).GetSelection()
+        if self.win['surface'][attrb]['required']:
+            selection += 1
+
+        if selection == 0: # unset
+            map = None
+            value = ''
+        elif selection == 1: # map
+            value = self.FindWindowById(self.win['surface'][attrb]['map']).GetValue()
+            map = True
+        else: # constant
+            if attrb == 'color':
+                value = self.FindWindowById(self.win['surface'][attrb]['const']).GetColour()
+                # tuple to string
+                value = str(value[0]) + ':' + str(value[1]) + ':' + str(value[2])
+            else:
+                value = self.FindWindowById(self.win['surface'][attrb]['const']).GetValue()
+            map = False
+        
+        if not self.pageChanging:
+            self.mapWindow.update.append('surface:attribute:%s' % attrb)
+            data = self.mapWindow.GetSelectedLayer(type='nviz')
+            data['surface']['attribute'][attrb] = { 'map' : map,
+                                                    'value' : str(value),
+                                                    }
+            self.mapWindow.UpdateLayerProperties()
+
+            if self.parent.autoRender.IsChecked():
+                self.mapWindow.Refresh(False)
+
+    def OnSurfaceResolution(self, event):
+        """Draw resolution changed"""
+        self.SetSurfaceResolution()
+
+        if apply and self.parent.autoRender.IsChecked():
+            self.mapWindow.Refresh(False)
+
+    def SetSurfaceResolution(self, all=False):
+        """Set draw resolution"""
+        coarse = self.FindWindowById(self.win['surface']['draw']['res-coarse']).GetValue()
+        fine = self.FindWindowById(self.win['surface']['draw']['res-fine']).GetValue()
+            
+        self.mapWindow.update.append('surface:draw:resolution')
+        data = self.mapWindow.GetSelectedLayer(type='nviz')
+        data['surface']['draw']['resolution'] = { 'coarse' : coarse,
+                                                  'fine' : fine,
+                                                  'all' : all } 
+
+        self.mapWindow.UpdateLayerProperties()
+
+    def SetSurfaceMode(self, all=False):
+        """Set draw mode
+
+        @param apply allow auto-rendering
+        """
+        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()
+
+        shade = self.FindWindowById(self.win['surface']['draw']['shading']).GetSelection()
+
+        value, desc = self.mapWindow.GetSurfaceMode(mode, style, shade)
+
+        return value, desc
+
+    def OnSurfaceMode(self, event):
+        """Set draw mode"""
+        value, desc = self.SetSurfaceMode()
+
+        self.mapWindow.update.append('surface:draw:mode')
+        data = self.mapWindow.GetSelectedLayer(type='nviz')
+        data['surface']['draw']['mode'] = { 'value' : value,
+                                            'all' : False,
+                                            'desc' : desc }
+
+        self.mapWindow.UpdateLayerProperties()
+
+        if apply and self.parent.autoRender.IsChecked():
+            self.mapWindow.Refresh(False)
+
+    def OnSurfaceModeAll(self, event):
+        """Set draw mode (including wire color) for all loaded surfaces"""
+        self.SetSurfaceMode(all=True)
+        self.SetSurfaceResolution(all=True)
+        color = self.FindWindowById(self.win['surface']['draw']['wire-color']).GetColour()
+        self.SetSurfaceWireColor(color, all=True)
+
+        if apply and self.parent.autoRender.IsChecked():
+            self.mapWindow.Refresh(False)
+
+    def SetSurfaceWireColor(self, color, all=False, apply=True):
+        """Set wire color"""
+        value = str(color[0]) + ':' + str(color[1]) + ':' + str(color[2])
+
+    def OnSurfaceWireColor(self, event):
+        """Set wire color"""
+        self.SetSurfaceWireColor(event.GetValue())
+
+        self.mapWindow.update.append('surface:draw:wire-color')
+        data = self.mapWindow.GetSelectedLayer(type='nviz')
+        data['surface']['draw']['wire-color'] = { 'value' : value,
+                                                  'all' : all }
+        self.mapWindow.UpdateLayerProperties()
+
+        if self.parent.autoRender.IsChecked():
+            self.mapWindow.Refresh(False)
+
+    def OnSurfaceAxis(self, event):
+        """Surface position, axis changed"""
+        mapLayer = self.mapWindow.GetSelectedLayer()
+        data = self.mapWindow.GetSelectedLayer(type='nviz')
+        id = data['object']['id']
+
+        axis = self.FindWindowById(self.win['surface']['position']['axis']).GetSelection()
+        win = self.FindWindowById(self.win['surface']['position']['pos'])
+
+        x, y, z = self.mapWindow.nvizClass.GetSurfacePosition(id)
+
+        if axis == 0: # x
+            win.SetRange(-1e4, 1e4)
+            win.SetValue(x)
+        elif axis == 1: # y
+            win.SetRange(-1e4, 1e4)
+            win.SetValue(y)
+        else: # z
+            win.SetRange(-1e3, 1e3)
+            win.SetValue(z)
+
+    def OnSurfacePosition(self, event):
+        """Surface position"""
+        axis = self.FindWindowById(self.win['surface']['position']['axis']).GetSelection()
+        value = event.GetInt()
+
+        mapLayer = self.mapWindow.GetSelectedLayer()
+        data = self.mapWindow.GetSelectedLayer(type='nviz')
+        id = data['object']['id']
+        x, y, z = self.mapWindow.nvizClass.GetSurfacePosition(id)
+
+        if axis == 0: # x
+            x = value
+        elif axis == 1: # y
+            y = value
+        else: # z
+            z = value
+        
+        self.mapWindow.update.append('surface:position')
+        data = self.mapWindow.GetSelectedLayer(type='nviz')
+        data['surface']['position']['x'] = x
+        data['surface']['position']['y'] = y
+        data['surface']['position']['z'] = z
+        
+        self.mapWindow.UpdateLayerProperties()
+
+        if self.parent.autoRender.IsChecked():
+            self.mapWindow.Refresh(False)
+
+    def UpdateVectorShow(self, vecType, enabled):
+        """Enable/disable lines/points widgets
+
+        @param vecType vector type (lines, points)
+        """
+        if vecType != 'lines' and vecType != 'points':
+            return False
+
+        for win in self.win['vector'][vecType].keys():
+            if win == 'show':
+                continue
+            if type(self.win['vector'][vecType][win]) == type({}):
+                for swin in self.win['vector'][vecType][win].keys():
+                    if enabled:
+                        self.FindWindowById(self.win['vector'][vecType][win][swin]).Enable(True)
+                    else:
+                        self.FindWindowById(self.win['vector'][vecType][win][swin]).Enable(False)
+            else:
+                if enabled:
+                    self.FindWindowById(self.win['vector'][vecType][win]).Enable(True)
+                else:
+                    self.FindWindowById(self.win['vector'][vecType][win]).Enable(False)
+
+        return True
+    
+    def OnVectorShow(self, event):
+        """Show vector lines/points"""
+        winId = event.GetId()
+        if winId == self.win['vector']['lines']['show']:
+            vecType = 'lines'
+        else: # points
+            vecType = 'points'
+
+        checked = event.IsChecked()
+        item = self.mapWindow.GetSelectedLayer(type='item')
+        data = self.mapWindow.GetSelectedLayer(type='nviz')['vector']
+        
+        if checked:
+            self.mapWindow.LoadVector(item, (vecType,))
+        else:
+            self.mapWindow.UnloadVector(item, (vecType,))
+        
+        self.UpdateVectorShow(vecType, checked)
+        
+        if checked:
+            try:
+                id = data[vecType]['object']['id']
+            except KeyError:
+                id = -1
+
+            if id > 0:
+                self.mapWindow.SetLayerData(item, id, vecType)
+        
+                # update properties
+                self.mapWindow.UpdateLayerProperties(item)
+
+        if self.parent.autoRender.IsChecked():
+            self.mapWindow.Refresh(False)
+        
+        event.Skip()
+    
+    def OnVectorDisplay(self, event):
+        """Display vector lines on surface/flat"""
+        if event.GetSelection() == 0: # surface
+            if len(self.mapWindow.layers['raster']['name']) < 1:
+                event.Veto()
+                return
+
+            self.FindWindowById(self.win['vector']['lines']['surface']).Enable(True)
+            # set first found surface
+            data = self.mapWindow.GetSelectedLayer(type='nviz')
+            data['vector']['lines']['mode']['surface'] = self.mapWindow.layers['raster']['name'][0]
+            self.FindWindowById(self.win['vector']['lines']['surface']).SetStringSelection( \
+                self.mapWindow.layers['raster']['name'][0])
+        else: # flat
+            self.FindWindowById(self.win['vector']['lines']['surface']).Enable(False)
+
+        self.OnVectorLines(event)
+
+        event.Skip()
+
+    def OnVectorLines(self, event):
+        """Set vector lines mode, apply changes if auto-rendering is enabled"""
+        width = self.FindWindowById(self.win['vector']['lines']['width']).GetValue()
+
+        color = self.FindWindowById(self.win['vector']['lines']['color']).GetColour()
+        color = str(color[0]) + ':' + str(color[1]) + ':' + str(color[2])
+
+        mode = {}
+        if self.FindWindowById(self.win['vector']['lines']['flat']).GetSelection() == 0:
+            mode['type'] = 'surface'
+            mode['surface'] = self.FindWindowById(self.win['vector']['lines']['surface']).GetValue()
+            self.mapWindow.update.append('vector:lines:surface')
+        else:
+            mode['type'] = 'flat'
+
+        self.mapWindow.update.append('vector:lines:width')
+        self.mapWindow.update.append('vector:lines:color')
+        self.mapWindow.update.append('vector:lines:mode')
+        data = self.mapWindow.GetSelectedLayer(type='nviz')
+        data['vector']['lines']['width'] = width
+        data['vector']['lines']['color'] = color
+        data['vector']['lines']['mode'] = mode
+
+        self.mapWindow.UpdateLayerProperties()
+                
+        if self.parent.autoRender.IsChecked():
+            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']:
+            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)
+
+        self.mapWindow.update.append('vector:%s:height' % vtype)
+        data = self.mapWindow.GetSelectedLayer(type='nviz')
+        
+        data['vector'][vtype]['height'] = value
+
+        self.mapWindow.UpdateLayerProperties()
+
+        self.mapWindow.render['quick'] = True
+        self.mapWindow.render['v' + vtype] = True
+        self.mapWindow.Refresh(False)
+    
+    def OnVectorHeightFull(self, event):
+        """Vector height changed, render in full resolution"""
+        id = event.GetId()
+        if id == self.win['vector']['lines']['height']['spin'] or \
+                id == self.win['vector']['lines']['height']['slider']:
+            vtype = 'lines'
+        else:
+            vtype = 'points'
+
+        self.mapWindow.render['quick'] = False
+        self.mapWindow.render['v' + vtype] = False
+        self.mapWindow.Refresh(False)
+
+    def OnVectorHeightSpin(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)"""
+        id = event.GetId()
+        if id == self.win['vector']['lines']['surface']:
+            vtype = 'lines'
+        else:
+            vtype = 'points'
+
+        self.mapWindow.update.append('vector:%s:surface' % vtype)
+        
+        data['vector'][vtype]['mode']['surface'] = event.GetValue()
+
+        self.mapWindow.UpdateLayerProperties()
+
+        if self.parent.autoRender.IsChecked():
+            self.mapWindow.Refresh(False)
+        
+    def OnVectorPoints(self, event):
+        """Set vector points mode, apply changes if auto-rendering is enabled"""
+        size  = self.FindWindowById(self.win['vector']['points']['size']).GetValue()
+        width = self.FindWindowById(self.win['vector']['points']['width']).GetValue()
+
+        color = self.FindWindowById(self.win['vector']['points']['color']).GetColour()
+        color = str(color[0]) + ':' + str(color[1]) + ':' + str(color[2])
+
+        marker = self.FindWindowById(self.win['vector']['points']['marker']).GetSelection()
+
+        self.mapWindow.update.append('vector:points:size')
+        self.mapWindow.update.append('vector:points:width')
+        self.mapWindow.update.append('vector:points:color')
+        self.mapWindow.update.append('vector:points:marker')
+        data = self.mapWindow.GetSelectedLayer(type='nviz')['vector']['points']
+        data['size'] = size
+        data['width'] = width
+        data['color'] = color
+        data['marker'] = marker
+
+        self.mapWindow.UpdateLayerProperties()
+                
+        if self.parent.autoRender.IsChecked():
+            self.mapWindow.Refresh(False)
+        
+    def UpdatePage(self, pageId):
+        """Update dialog (selected page)"""
+        self.pageChanging = True
+        layer = self.mapWindow.GetSelectedLayer()
+        data = self.mapWindow.GetSelectedLayer(type='nviz')
+        
+        if pageId == 'view':
+            max = self.mapWindow.view['z-exag']['value'] * 10
+            hmin = self.mapWindow.iview['height']['min']
+            hmax = self.mapWindow.iview['height']['max']
+            for control in ('spin', 'slider'):
+                self.FindWindowById(self.win['view']['z-exag'][control]).SetRange(0,
+                                                                                  max)
+                self.FindWindowById(self.win['view']['height'][control]).SetRange(hmin,
+                                                                                  hmax)
+        elif pageId == 'surface':
+            if self.notebook.GetSelection() != self.page['surface']['id']:
+                if self.page['vector']['id'] > -1:
+                    self.notebook.RemovePage(self.page['vector']['id'])
+                    self.page['vector']['id'] = -1
+
+                self.page['surface']['id'] = 1
+                self.page['settings']['id'] = 2
+
+                panel = wx.FindWindowById(self.page['surface']['panel'])
+                self.notebook.InsertPage(n=self.page['surface']['id'],
+                                         page=panel,
+                                         text=" %s " % _("Layer properties"),
+                                         select=True)
+
+            self.UpdateSurfacePage(layer, data['surface'])
+
+        elif pageId == 'vector':
+            if self.notebook.GetSelection() != self.page['vector']['id']:
+                if self.page['surface']['id'] > -1:
+                    self.notebook.RemovePage(self.page['surface']['id'])
+                    self.page['surface']['id'] = -1
+
+                self.page['vector']['id'] = 1
+                self.page['settings']['id'] = 2
+
+                panel = wx.FindWindowById(self.page['vector']['panel'])
+                self.notebook.InsertPage(n=self.page['vector']['id'],
+                                         page=panel,
+                                         text=" %s " % _("Layer properties"),
+                                         select=True)
+
+            self.UpdateVectorPage(layer, data['vector'])
+        
+        self.pageChanging = False
+        
+    def UpdateSurfacePage(self, layer, data):
+        #
+        # 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.SetSurfaceUseMap(attr, True) # -> map
+
+        if data['attribute'].has_key('color'):
+            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.SetSurfaceUseMap(attr, data['attribute']['color']['map'])
+
+        self.SetSurfaceUseMap('shine', 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)
+
+        #
+        # draw
+        #
+        for control, dict in data['draw'].iteritems():
+            if control == 'resolution':
+                self.FindWindowById(self.win['surface']['draw']['res-coarse']).SetValue(dict['coarse'])
+                self.FindWindowById(self.win['surface']['draw']['res-fine']).SetValue(dict['fine'])
+                continue
+
+            if control == 'mode':
+                if dict['desc']['mode'] == 'coarse':
+                    self.FindWindowById(self.win['surface']['draw']['mode']).SetSelection(0)
+                elif dict['desc']['mode'] == 'fine':
+                    self.FindWindowById(self.win['surface']['draw']['mode']).SetSelection(1)
+                else: # both
+                    self.FindWindowById(self.win['surface']['draw']['mode']).SetSelection(2)
+                    
+                if dict['desc']['style'] == 'wire':
+                    self.FindWindowById(self.win['surface']['draw']['style']).SetSelection(0)
+                else: # surface
+                    self.FindWindowById(self.win['surface']['draw']['style']).SetSelection(1)
+
+                if dict['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 = dict['value']
+            win = self.FindWindowById(self.win['surface']['draw'][control])
+            
+            name = win.GetName()
+
+            if name == "selection":
+                win.SetSelection(value)
+            elif name == "colour":
+                color = map(int, value.split(':'))
+                win.SetColour(color)
+            else:
+                win.SetValue(value)
+        # enable/disable res widget + set draw mode
+        self.SetSurfaceMode()
+        color = self.FindWindowById(self.win['surface']['draw']['wire-color'])
+        self.SetSurfaceWireColor(color.GetColour())
+
+    def UpdateVectorPage(self, layer, data):
+        vInfo = gcmd.Command(['v.info',
+                              'map=%s' % layer.name])
+        npoints = nprimitives = 0
+        for line in vInfo.ReadStdOutput():
+            if 'Map is 3D' in line:
+                mapIs3D = int(line.replace('|', '').split(':')[1].strip())
+            elif 'Number of points' in line:
+                npoints = int(line.replace('|', '').split(':')[1].strip().split(' ')[0])
+                nprimitives = npoints
+            elif 'Number of lines' in line:
+                nprimitives += int(line.replace('|', '').split(':')[1].strip().split(' ')[0])
+            elif 'Number of boundaries' in line:
+                nprimitives += int(line.replace('|', '').split(':')[1].strip().split(' ')[0]) # boundaries
+                nprimitives += int(line.replace('|', '').split(':')[2].strip()) # faces
+            elif 'Number of centroids' in line:
+                nprimitives += int(line.replace('|', '').split(':')[1].strip().split(' ')[0]) # centroids
+                nprimitives += int(line.replace('|', '').split(':')[2].strip()) # kernels
+
+        if mapIs3D:
+            desc = _("Vector map <%s> is 3D") % layer.name
+            enable = False
+        else:
+            desc = _("Vector map <%s> is 2D") % layer.name
+            enable = True
+        desc += " - " + _("%d primitives (%d points)") % (nprimitives, npoints)
+
+        self.FindWindowById(self.win['vector']['lines']['flat']).Enable(enable)
+        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']['desc']).SetLabel(desc)
+        #
+        # lines
+        #
+        showLines = self.FindWindowById(self.win['vector']['lines']['show'])
+        if data['lines'].has_key('object'):
+            showLines.SetValue(True)
+        else:
+            showLines.SetValue(False)
+            if nprimitives - npoints > 0:
+                showLines.Enable(True)
+            else:
+                showLines.Enable(False)
+
+        self.UpdateVectorShow('lines',
+                              showLines.IsChecked())
+
+        width = self.FindWindowById(self.win['vector']['lines']['width'])
+        width.SetValue(data['lines']['width'])
+
+        color = self.FindWindowById(self.win['vector']['lines']['color'])
+        color.SetValue(map(int, data['lines']['color'].split(':')))
+
+        for vtype in ('lines', 'points'):
+            if vtype == 'lines':
+                display = self.FindWindowById(self.win['vector']['lines']['flat'])
+                if data[vtype]['mode']['type'] == 'flat':
+                    display.SetSelection(1)
+                else:
+                    display.SetSelection(0)
+
+            if data[vtype]['mode']['type'] == 'surface' and \
+                    len(self.mapWindow.layers['raster']['name']) > 0:
+                surface = self.FindWindowById(self.win['vector'][vtype]['surface'])
+                surface.SetItems(self.mapWindow.layers['raster']['name'])
+                surface.SetStringSelection(data[vtype]['mode']['surface'])
+                
+        for type in ('slider', 'spin'):
+            win = self.FindWindowById(self.win['vector']['lines']['height'][type])
+            win.SetValue(data['lines']['height'])
+
+        #
+        # points
+        #
+        showPoints = self.FindWindowById(self.win['vector']['points']['show'])
+        
+        if data['points'].has_key('object'):
+            showPoints.SetValue(True)
+        else:
+            showPoints.SetValue(False)
+            if npoints > 0:
+                showPoints.Enable(True)
+            else:
+                showPoints.Enable(False)
+        
+        self.UpdateVectorShow('points',
+                              showPoints.IsChecked())
+        # size, width, marker, color
+        for prop in ('size', 'width', 'marker', 'color'):
+            win = self.FindWindowById(self.win['vector']['points'][prop])
+            name = win.GetName()
+            if name == 'selection':
+                win.SetSelection(data['points'][prop])
+            elif name == 'color':
+                color = map(int, data['points'][prop].split(':'))
+                win.SetValue(color)
+            else:
+                win.SetValue(data['points'][prop])
+        # height
+        for type in ('slider', 'spin'):
+            win = self.FindWindowById(self.win['vector']['points']['height'][type])
+            win.SetValue(data['points']['height'])
+
+    def SetPage(self, name):
+        """Get named page"""
+        self.notebook.SetSelection(self.page[name]['id'])
+
+class ViewPositionWindow(wx.Window):
+    """Position control window (for NvizToolWindow)"""
+    def __init__(self, parent, id, mapwindow,
+                 pos=wx.DefaultPosition,
+                 size=wx.DefaultSize):
+        self.mapWindow = mapwindow
+
+        wx.Window.__init__(self, parent, id, pos, size)
+
+        self.SetBackgroundColour("WHITE")
+
+        self.pdc = wx.PseudoDC()
+
+        self.pdc.SetBrush(wx.Brush(colour='dark green', style=wx.SOLID))
+        self.pdc.SetPen(wx.Pen(colour='dark green', width=2, style=wx.SOLID))
+
+        self.Draw()
+
+        self.Bind(wx.EVT_ERASE_BACKGROUND, lambda x: None)
+        self.Bind(wx.EVT_PAINT, self.OnPaint)
+        # self.Bind(wx.EVT_MOTION,       self.OnMouse)
+        self.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouse)
+
+    def Draw(self, pos=None):
+        w, h = self.GetClientSize()
+
+        if pos is None:
+            x = self.mapWindow.view['pos']['x']
+            y = self.mapWindow.view['pos']['y']
+            x = x * w
+            y = y * h
+        else:
+            x, y = pos
+
+        self.pdc.Clear()
+        self.pdc.BeginDrawing()
+        self.pdc.DrawLine(w / 2, h / 2, x, y)
+        self.pdc.DrawCircle(x, y, 5)
+        self.pdc.EndDrawing()
+
+    def OnPaint(self, event):
+        dc = wx.BufferedPaintDC(self)
+        dc.SetBackground(wx.Brush("White"))
+        dc.Clear()
+
+        self.PrepareDC(dc)
+        self.pdc.DrawToDC(dc)
+
+    def OnMouse(self, event):
+        if event.LeftIsDown():
+            x, y = event.GetPosition()
+            self.Draw(pos=(x, y))
+            self.Refresh(False)
+            w, h = self.GetClientSize()
+            x = float(x) / w
+            y = float(y) / h
+            if x >= 0 and x <= 1.0:
+                self.mapWindow.view['pos']['x'] = x
+            if y >= 0 and y <= 1.0:
+                self.mapWindow.view['pos']['y'] = y
+            self.mapWindow.update.append('view')
+
+            self.mapWindow.render['quick'] = True
+            self.mapWindow.Refresh(eraseBackground=False)
+
+        elif event.LeftUp():
+            self.mapWindow.render['quick'] = False
+            self.mapWindow.Refresh(eraseBackground=False)
+        
+        event.Skip()

Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/preferences.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/preferences.py	2008-08-06 09:11:06 UTC (rev 32559)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/preferences.py	2008-08-06 09:21:46 UTC (rev 32560)
@@ -111,7 +111,7 @@
                     'type' : 'vdigit'
                     }, # vedit, vdigit
                 'iconTheme' : {
-                    'type' : 'silk'
+                    'type' : 'grass'
                     }, # grass, silk
                 },
             #
@@ -354,6 +354,74 @@
                     'width' : 2,
                     },
                 },
+            'nviz' : {
+                'view' : {
+                    'persp' : {
+                        'value' : 40,
+                        'step' : 5,
+                        },
+                    'pos' : {
+                        'x' : 0.85,
+                        'y' : 0.85,
+                        },
+                    'height' : {
+                        'step' : 100,
+                        },
+                    'twist' : {
+                        'value' : 0,
+                        'step' : 5,
+                        },
+                    'z-exag' : {
+                        'value': 1,
+                        'step' : 1,
+                        },
+                    },
+                'surface' : {
+                    'shine': {
+                        'map' : False,
+                        'value' : 60.0,
+                        },
+                    'color' : {
+                        'map' : True,
+                        'value' : (0, 0, 0, 255), # constant: black
+                        },
+                    'draw' : {
+                        'wire-color' : (136, 136, 136, 255),
+                        'mode' : 1, # fine
+                        'style' : 1, # surface
+                        'shading' : 1, # gouraud
+                        'res-fine' : 6,
+                        'res-coarse' : 9,
+                        },
+                    'position' : {
+                        'x' : 0,
+                        'y' : 0,
+                        'z' : 0,
+                        },
+                    },
+                'vector' : {
+                    'lines' : {
+                        'show' : False,
+                        'width' : 2,
+                        'color' : (0, 0, 255, 255), # blue
+                        'flat' : False,
+                        'height' : 0,
+                        },
+                    'points' : {
+                        'show' : False,
+                        'size' : 100,
+                        'width' : 2,
+                        'marker' : 2,
+                        'color' : (0, 0, 255, 255), # blue
+                        'height' : 0,
+                        }
+                    },
+                'settings': {
+                    'general' : {
+                        'bgcolor' : (255, 255, 255, 255), # white
+                        },
+                    },
+                },
             }
         
         #
@@ -396,6 +464,28 @@
                                                                 'quiet')
         self.internalSettings['display']['driver']['choices'] = ['default']
         self.internalSettings['display']['statusbarMode']['choices'] = globalvar.MAP_DISPLAY_STATUSBAR_MODE
+
+        self.internalSettings['nviz']['view'] = {}
+        self.internalSettings['nviz']['view']['twist'] = {}
+        self.internalSettings['nviz']['view']['twist']['min'] = -180
+        self.internalSettings['nviz']['view']['twist']['max'] = 180
+        self.internalSettings['nviz']['view']['persp'] = {}
+        self.internalSettings['nviz']['view']['persp']['min'] = 1
+        self.internalSettings['nviz']['view']['persp']['max'] = 100
+        self.internalSettings['nviz']['view']['height'] = {}
+        self.internalSettings['nviz']['view']['height']['value'] = -1
+        self.internalSettings['nviz']['vector'] = {}
+        self.internalSettings['nviz']['vector']['points'] = {}
+        self.internalSettings['nviz']['vector']['points']['marker'] = ("x",
+                                                                       _("box"),
+                                                                       _("sphere"),
+                                                                       _("cube"),
+                                                                       _("diamond"),
+                                                                       _("dtree"),
+                                                                       _("ctree"),
+                                                                       _("aster"),
+                                                                       _("gyro"),
+                                                                       _("histogram"))
         
     def ReadSettingsFile(self, settings=None):
         """Reads settings file (mapset, location, gisdbase)"""
@@ -774,23 +864,11 @@
         gridSizer = wx.GridBagSizer (hgap=3, vgap=3)
         gridSizer.AddGrowableCol(0)
 
-        #
-        # show opacily level
-        #
-        row = 0
-        changeOpacityLevel = wx.CheckBox(parent=panel, id=wx.ID_ANY,
-                                       label=_("Opacity level editable"),
-                                       name='IsChecked')
-        changeOpacityLevel.SetValue(self.settings.Get(group='manager', key='changeOpacityLevel', subkey='enabled'))
-        self.winId['manager:changeOpacityLevel:enabled'] = changeOpacityLevel.GetId()
 
-        gridSizer.Add(item=changeOpacityLevel,
-                      pos=(row, 0), span=(1, 2))
-
         #
         # ask when removing map layer from layer tree
         #
-        row += 1
+        row = 0
         askOnRemoveLayer = wx.CheckBox(parent=panel, id=wx.ID_ANY,
                                        label=_("Ask when removing map layer from layer tree"),
                                        name='IsChecked')

Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/profile.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/profile.py	2008-08-06 09:11:06 UTC (rev 32559)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/profile.py	2008-08-06 09:21:46 UTC (rev 32560)
@@ -164,17 +164,19 @@
         self.properties['font']['wxfont'] = wx.Font(11, wx.FONTFAMILY_SWISS,
                                                     wx.FONTSTYLE_NORMAL,
                                                     wx.FONTWEIGHT_NORMAL)
+        
         self.properties['marker'] = UserSettings.Get(group='profile', key='marker')
 
         self.properties['grid'] = UserSettings.Get(group='profile', key='grid')
+        self.properties['x-axis'] = {}
         
-        self.properties['x-axis'] = {}
         self.properties['x-axis']['prop'] = UserSettings.Get(group='profile', key='x-axis')
         self.properties['x-axis']['axis'] = None
 
         self.properties['y-axis'] = {}
         self.properties['y-axis']['prop'] = UserSettings.Get(group='profile', key='y-axis')
         self.properties['y-axis']['axis'] = None
+        
         self.properties['legend'] = UserSettings.Get(group='profile', key='legend')
         
         # zooming disabled
@@ -186,14 +188,23 @@
         self.client.SetShowScrollbars(True)
 
         # x and y axis set to normal (non-log)
-        self.client.setLogScale((False, False)) 
-        self.client.SetXSpec(self.properties['x-axis']['prop']['type'])
-        self.client.SetYSpec(self.properties['y-axis']['prop']['type'])
+        self.client.setLogScale((False, False))
+        if self.properties['x-axis']['prop']['type']:
+            self.client.SetXSpec(self.properties['x-axis']['prop']['type'])
+        else:
+            self.client.SetXSpec('auto')
+        
+        if self.properties['y-axis']['prop']['type']:
+            self.client.SetYSpec(self.properties['y-axis']['prop']['type'])
+        else:
+            self.client.SetYSpec('auto')
 
         #
         # Bind various events
         #
         self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
+        
+        self.CentreOnScreen()
 
     def OnDrawTransect(self, event):
         """
@@ -217,6 +228,7 @@
         """
         Select raster map(s) to profile
         """
+        
         dlg = SetRasterDialog(parent=self)
 
         if dlg.ShowModal() == wx.ID_OK:
@@ -362,6 +374,7 @@
             self.properties['y-axis']['axis'] = None
 
         self.client.SetEnableGrid(self.properties['grid']['enabled'])
+        
         self.client.SetGridColour(wx.Color(self.properties['grid']['color'][0],
                                            self.properties['grid']['color'][1],
                                            self.properties['grid']['color'][2],
@@ -411,6 +424,7 @@
         segments, these are drawn as points. Profile transect is drawn, using
         methods in mapdisp.py
         """
+        
         if len(self.mapwin.polycoords) == 0 or self.raster[0]['name'] == '':
             dlg = wx.MessageDialog(parent=self,
                                    message=_('You must draw a transect to profile in the map display window.'),

Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/render.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/render.py	2008-08-06 09:11:06 UTC (rev 32559)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/render.py	2008-08-06 09:21:46 UTC (rev 32560)
@@ -189,13 +189,17 @@
         
         return int (self.opacity * 100)
 
+    def GetName(self):
+        """Get map layer name"""
+        return self.name
+    
     def IsActive(self):
         """Check if layer is activated for rendering"""
         return self.active
 
     def SetType(self, type):
         """Set layer type"""
-        if type not in ('raster', 'vector', 'overlay', 'command'):
+        if type not in ('raster', '3d-raster', 'vector', 'overlay', 'command'):
             raise gcmd.GStdError(_("Unsupported map layer type '%s'") % str(type))
         
         self.type = type

Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/toolbars.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/toolbars.py	2008-08-06 09:11:06 UTC (rev 32559)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/toolbars.py	2008-08-06 09:21:46 UTC (rev 32560)
@@ -8,6 +8,7 @@
     * GCPToolbar
     * VDigitToolbar
     * ProfileToolbar
+    * NvizToolbar
 
 PURPOSE: Toolbars for Map Display window
 
@@ -111,7 +112,7 @@
         
         # optional tools
         self.combo = wx.ComboBox(parent=self.toolbar, id=wx.ID_ANY, value='Tools',
-                                 choices=['Digitize'], style=wx.CB_READONLY, size=(90, -1))
+                                 choices=['Digitize', 'Nviz'], style=wx.CB_READONLY, size=(90, -1))
 
         self.comboid = self.toolbar.AddControl(self.combo)
         self.mapdisplay.Bind(wx.EVT_COMBOBOX, self.OnSelectTool, self.comboid)
@@ -201,9 +202,27 @@
         if tool == "Digitize" and not self.mapdisplay.toolbars['vdigit']:
             self.mapdisplay.AddToolbar("vdigit")
 
+        elif tool == "Nviz" and not self.mapdisplay.toolbars['nviz']:
+            self.mapdisplay.AddToolbar("nviz")
+
+    def Enable2D(self, enabled):
+        """Enable/Disable 2D display mode specific tools"""
+        for tool in (self.pointer,
+                     self.query,
+                     self.pan,
+                     self.zoomin,
+                     self.zoomout,
+                     self.zoomback,
+                     self.zoommenu,
+                     self.analyze,
+                     self.dec,
+                     self.savefile,
+                     self.printmap):
+            self.toolbar.EnableTool(tool, enabled)
+
 class GRToolbar(AbstractToolbar):
     """
-    Georectify Display toolbar
+    Georectification Display toolbar
     """
 
     def __init__(self, mapdisplay, map):
@@ -263,23 +282,23 @@
             (self.zoommenu, "zoommenu", Icons["zoommenu"].GetBitmap(),
              wx.ITEM_NORMAL, Icons["zoommenu"].GetLabel(), Icons["zoommenu"].GetDesc(),
              self.mapdisplay.OnZoomMenu),
+            ("", "", "", "", "", "", ""),
             )
 
 class GCPToolbar(AbstractToolbar):
     """
-    Toolbar for digitization
+    Toolbar for managing ground control points during georectification
     """
-    def __init__(self, parent, mapdisplay, map):
-        self.parent     = parent # GCP
-        self.mapcontent = map
-        self.mapdisplay = mapdisplay
+    def __init__(self, parent, tbframe):
+        self.parent  = parent # GCP
+        self.tbframe = tbframe
 
-        self.toolbar = wx.ToolBar(parent=self.mapdisplay, id=wx.ID_ANY)
+        self.toolbar = wx.ToolBar(parent=self.tbframe, id=wx.ID_ANY)
 
         # self.SetToolBar(self.toolbar)
         self.toolbar.SetToolBitmapSize(globalvar.toolbarSize)
 
-        self.InitToolbar(self.mapdisplay, self.toolbar, self.ToolbarData())
+        self.InitToolbar(self.tbframe, self.toolbar, self.ToolbarData())
 
         # realize the toolbar
         self.toolbar.Realize()
@@ -358,7 +377,7 @@
         self.numOfRows = 1 # number of rows for toolbar
         for row in range(0, self.numOfRows):
             self.toolbar.append(wx.ToolBar(parent=self.parent, id=wx.ID_ANY))
-	    self.toolbar[row].SetToolBitmapSize(globalvar.toolbarSize)
+            self.toolbar[row].SetToolBitmapSize(globalvar.toolbarSize)
             self.toolbar[row].Bind(wx.EVT_TOOL, self.OnTool)
             
             # create toolbar
@@ -999,3 +1018,51 @@
              wx.ITEM_NORMAL, Icons["quit"].GetLabel(), Icons["quit"].GetDesc(),
              self.parent.OnQuit),
             )
+
+class NvizToolbar(AbstractToolbar):
+    """
+    Nviz toolbar
+    """
+    def __init__(self, parent, map):
+        self.parent     = parent
+        self.mapcontent = map
+
+        self.toolbar = wx.ToolBar(parent=self.parent, id=wx.ID_ANY)
+
+        # self.SetToolBar(self.toolbar)
+        self.toolbar.SetToolBitmapSize(globalvar.toolbarSize)
+
+        self.InitToolbar(self.parent, self.toolbar, self.ToolbarData())
+
+        # realize the toolbar
+        self.toolbar.Realize()
+
+    def ToolbarData(self):
+        """Toolbar data"""
+
+        self.settings = wx.NewId()
+        self.quit = wx.NewId()
+                
+        # tool, label, bitmap, kind, shortHelp, longHelp, handler
+        return   (
+            (self.settings, "settings", Icons["nvizSettings"].GetBitmap(),
+             wx.ITEM_NORMAL, Icons["nvizSettings"].GetLabel(), Icons["nvizSettings"].GetDesc(),
+             self.OnSettings),
+            (self.quit, 'quit', Icons["quit"].GetBitmap(),
+             wx.ITEM_NORMAL, Icons["quit"].GetLabel(), Icons["quit"].GetDesc(),
+             self.OnExit),
+            )
+
+    def OnSettings(self, event):
+        win = self.parent.nvizToolWin
+        if not win.IsShown():
+            self.parent.nvizToolWin.Show()
+        else:
+            self.parent.nvizToolWin.Hide()
+
+    def OnExit (self, event=None):
+        """Quit nviz tool (swith to 2D mode)"""
+
+        # disable the toolbar
+        self.parent.RemoveToolbar ("nviz")
+

Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/utils.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/utils.py	2008-08-06 09:11:06 UTC (rev 32559)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/utils.py	2008-08-06 09:21:46 UTC (rev 32560)
@@ -68,6 +68,9 @@
     """
     mapname = ''
 
+    if len(dcmd) < 1:
+        return mapname
+    
     if 'd.grid' == dcmd[0]:
         mapname = 'grid'
     elif 'd.geodesic' in dcmd[0]:

Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/workspace.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/workspace.py	2008-08-06 09:11:06 UTC (rev 32559)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/workspace.py	2008-08-06 09:21:46 UTC (rev 32560)
@@ -32,6 +32,8 @@
 HandlerBase=xml.sax.handler.ContentHandler
 from xml.sax import make_parser
 
+from preferences import globalSettings as UserSettings
+
 class ProcessWorkspaceFile(HandlerBase):
     """
     A SAX handler for the GXW XML file, as
@@ -41,7 +43,16 @@
         self.inTag = {}
         for tag in ('gxw', 'layer', 'task', 'parameter',
                     'flag', 'value', 'group', 'display',
-                    'layer_manager'):
+                    'layer_manager',
+                    'nviz',
+                    # surface
+                    'surface', 'attribute', 'draw', 'resolution',
+                    'wire_color', 'position', 'x', 'y', 'z',
+                    # vector lines
+                    'vlines', 'color', 'width', 'mode',
+                    'map', 'height',
+                    # vector points
+                    'vpoints', 'size'):
             self.inTag[tag] = False
 
         #
@@ -102,7 +113,8 @@
                 "opacity" : None,
                 "cmd"     : None,
                 "group"   : self.inTag['group'],
-                "display" : self.displayIndex })
+                "display" : self.displayIndex,
+                "nviz"    : None})
 
         elif name == 'layer':
             self.layerType     = attrs.get('type', None)
@@ -110,6 +122,7 @@
             self.layerChecked  = attrs.get('checked', None)
             self.layerOpacity  = attrs.get('opacity', None)
             self.layerSelected = False
+            self.layerNviz     = None
             self.cmd = []
 
         elif name == 'task':
@@ -119,7 +132,7 @@
         elif name == 'parameter':
             self.parameterName = attrs.get('name', None)
 
-        elif name in ('value', 'x', 'y', 'z'):
+        elif name in ('value', 'x', 'y', 'z', 'map'):
             self.value = ''
 
         elif name == 'flag':
@@ -142,6 +155,75 @@
             else:
                 pass
 
+        #
+        # Nviz section
+        #
+        elif name == 'nviz':
+            # init nviz layer properties
+            self.layerNviz = {}
+            if self.layerType == 'raster':
+                self.layerNviz['surface'] = {}
+                for sec in ('attribute', 'draw', 'mask', 'position'):
+                    self.layerNviz['surface'][sec] = {}
+            elif self.layerType == 'vector':
+                self.layerNviz['vector'] = {}
+                for sec in ('lines', 'points'):
+                    self.layerNviz['vector'][sec] = {}
+
+        elif name == 'attribute':
+            if self.inTag['nviz'] and self.inTag['surface']:
+                tagName = str(name)
+                attrbName = str(attrs.get('name', ''))
+                self.layerNviz['surface'][tagName][attrbName] = {}
+                if attrs.get('map', '0') == '0':
+                    self.layerNviz['surface'][tagName][attrbName]['map'] = False
+                else:
+                    self.layerNviz['surface'][tagName][attrbName]['map'] = True
+
+                self.refAttribute = self.layerNviz['surface'][tagName][attrbName]
+        
+        elif name == 'draw':
+            if self.inTag['nviz'] and self.inTag['surface']:
+                tagName = str(name)
+                self.layerNviz['surface'][tagName]['mode'] = {}
+                self.layerNviz['surface'][tagName]['mode']['all'] = False
+                self.layerNviz['surface'][tagName]['mode']['value'] = -1 # to be calculated
+                self.layerNviz['surface'][tagName]['mode']['desc'] = {}
+                self.layerNviz['surface'][tagName]['mode']['desc']['shading'] = \
+                    str(attrs.get('shading', ''))
+                self.layerNviz['surface'][tagName]['mode']['desc']['style'] = \
+                    str(attrs.get('style', ''))
+                self.layerNviz['surface'][tagName]['mode']['desc']['mode'] = \
+                    str(attrs.get('mode', ''))
+
+        elif name == 'resolution':
+            if self.inTag['nviz'] and self.inTag['surface']:
+                self.resolutionType = str(attrs.get('type', ''))
+                if not self.layerNviz['surface']['draw'].has_key(str(name)):
+                    self.layerNviz['surface']['draw'][str(name)] = {}
+
+        elif name == 'position':
+            if self.inTag['nviz'] and inTag['surface']:
+                self.layerNviz['surface']['position'] = {}
+        
+        elif name == 'mode':
+            if self.inTag['nviz']:
+                if self.inTag['vlines']:
+                    self.layerNviz['vector']['lines']['mode'] = {}
+                    self.layerNviz['vector']['lines']['mode']['type'] = str(attrs.get('type', ''))
+                    self.layerNviz['vector']['lines']['mode']['surface'] = ''
+                elif self.inTag['vpoints']:
+                    self.layerNviz['vector']['points']['mode'] = {}
+                    self.layerNviz['vector']['points']['mode']['type'] = str(attrs.get('type', ''))
+                    self.layerNviz['vector']['points']['mode']['surface'] = ''
+
+        elif name == 'vpoints':
+            if self.inTag['nviz']:
+                marker = str(attrs.get('marker', ''))
+                markerId = list(UserSettings.Get(group='nviz', key='vector',
+                                                 subkey=['points', 'marker'], internal=True)).index(marker)
+                self.layerNviz['vector']['points']['marker'] = markerId
+        
         self.inTag[name] = True
         
     def endElement(self, name):
@@ -157,8 +239,9 @@
                     "cmd"      : None,
                     "group"    : self.inTag['group'],
                     "display"  : self.displayIndex,
-                    "selected" : self.layerSelected })
-
+                    "selected" : self.layerSelected,
+                    "nviz"     : self.layerNviz})
+            
             if self.layerOpacity:
                 self.layers[-1]["opacity"] = float(self.layerOpacity)
             if self.cmd:
@@ -171,13 +254,86 @@
             self.cmd.append('%s=%s' % (self.parameterName, self.value))
             self.parameterName = self.value = None
 
+        #
+        # Nviz section
+        #
+        elif name == 'attribute':
+            if self.inTag['nviz'] and self.inTag['surface']:
+                try:
+                    self.refAttribute['value'] = int(self.value)
+                except ValueError:
+                    try:
+                        self.refAttribute['value'] = float(self.value)
+                    except ValueError:
+                        self.refAttribute['value'] = str(self.value)
+
+        elif name == 'resolution':
+            if self.inTag['nviz'] and self.inTag['surface']:
+                self.layerNviz['surface']['draw']['resolution']['all'] = False
+                self.layerNviz['surface']['draw']['resolution'][self.resolutionType] = int(self.value)
+                del self.resolutionType
+
+        elif name == 'wire_color':
+            if self.inTag['nviz'] and self.inTag['surface']:
+                self.layerNviz['surface']['draw']['wire-color'] = {}
+                self.layerNviz['surface']['draw']['wire-color']['all'] = False
+                self.layerNviz['surface']['draw']['wire-color']['value'] = str(self.value)
+
+        elif name == 'x':
+            if self.inTag['nviz'] and self.inTag['surface']:
+                self.layerNviz['surface']['position']['x'] = int(self.value)
+
+        elif name == 'y':
+            if self.inTag['nviz'] and self.inTag['surface']:
+                self.layerNviz['surface']['position']['y'] = int(self.value)
+
+        elif name == 'z':
+            if self.inTag['nviz'] and self.inTag['surface']:
+                self.layerNviz['surface']['position']['z'] = int(self.value)
+        
+        elif name == 'color':
+            if self.inTag['nviz']:
+                if self.inTag['vlines']:
+                    self.layerNviz['vector']['lines']['color'] = str(self.value)
+                elif self.inTag['vpoints']:
+                    self.layerNviz['vector']['points']['color'] = str(self.value)
+                    
+        elif name == 'width':
+            if self.inTag['nviz']:
+                if self.inTag['vlines']:
+                    self.layerNviz['vector']['lines']['width'] = int(self.value)
+                elif self.inTag['vpoints']:
+                    self.layerNviz['vector']['points']['width'] = int(self.value)
+
+        elif name == 'height':
+            if self.inTag['nviz']:
+                if self.inTag['vlines']:
+                    self.layerNviz['vector']['lines']['height'] = int(self.value)
+                elif self.inTag['vpoints']:
+                    self.layerNviz['vector']['points']['height'] = int(self.value)
+        
+        elif name == 'size':
+            if self.inTag['nviz'] and self.inTag['vpoints']:
+                self.layerNviz['vector']['points']['size'] = int(self.value)
+
+        elif name == 'map':
+            if self.inTag['nviz']:
+                if self.inTag['vlines']:
+                    self.layerNviz['vector']['lines']['mode']['surface'] = str(self.value)
+                elif self.inTag['vpoints']:
+                    self.layerNviz['vector']['points']['mode']['surface'] = str(self.value)
+
         self.inTag[name] = False
 
     def characters(self, ch):
         self.my_characters(ch)
 
     def my_characters(self, ch):
-        if self.inTag['value']:
+        if self.inTag['value'] or \
+                self.inTag['x'] or \
+                self.inTag['y'] or \
+                self.inTag['z'] or \
+                self.inTag['map']:
             self.value += ch
 
 class WriteWorkspaceFile(object):
@@ -266,6 +422,9 @@
                 self.file.write('%s</group>\n' % (' ' * self.indent));
             else:
                 name = mapTree.GetItemText(item)
+                # remove 'opacity' part
+                if '(opacity' in name:
+                    name = name.split('(', -1)[0].strip()
                 opacity = maplayer.GetOpacity(float=True)
                 self.file.write('%s<layer type="%s" name="%s" checked="%d" opacity="%f">\n' % \
                                (' ' * self.indent, type, name, checked, opacity));
@@ -292,12 +451,138 @@
                         self.file.write('%s</parameter>\n' % (' ' * self.indent));
                 self.indent -= 4
                 self.file.write('%s</task>\n' % (' ' * self.indent));
-
+                nviz = mapTree.GetPyData(item)[0]['nviz']
+                if nviz:
+                    self.file.write('%s<nviz>\n' % (' ' * self.indent));
+                    if maplayer.type == 'raster':
+                        self.__writeNvizSurface(nviz['surface'])
+                    elif maplayer.type == 'vector':
+                        self.__writeNvizVector(nviz['vector'])
+                    self.file.write('%s</nviz>\n' % (' ' * self.indent));
                 self.indent -= 4
                 self.file.write('%s</layer>\n' % (' ' * self.indent));
             item = mapTree.GetNextSibling(item)
         self.indent -= 4
 
+    def __writeNvizSurface(self, data):
+        """Save Nviz raster layer properties to workspace
+
+        @param data Nviz layer properties
+        """
+        if not data.has_key('object'): # skip disabled
+            return
+
+        self.indent += 4
+        self.file.write('%s<surface>\n' % (' ' * self.indent))
+        self.indent += 4
+        for attrb in data.iterkeys():
+            if len(data[attrb]) < 1: # skip empty attributes
+                continue
+            if attrb == 'object':
+                continue
+            
+            for name in data[attrb].iterkeys():
+                # surface attribute
+                if attrb == 'attribute':
+                    self.file.write('%s<%s name="%s" map="%d">\n' % \
+                                   (' ' * self.indent, attrb, name, data[attrb][name]['map']))
+                    self.indent += 4
+                    self.file.write('%s<value>%s</value>\n' % (' ' * self.indent, data[attrb][name]['value']))
+                    self.indent -= 4
+                    # end tag
+                    self.file.write('%s</%s>\n' % (' ' * self.indent, attrb))
+
+            # draw mode
+            if attrb == 'draw':
+                self.file.write('%s<%s' %(' ' * self.indent, attrb))
+                if data[attrb].has_key('mode'):
+                    for tag, value in data[attrb]['mode']['desc'].iteritems():
+                        self.file.write(' %s="%s"' % (tag, value))
+                self.file.write('>\n') # <draw ...>
+
+                if data[attrb].has_key('resolution'):
+                    self.indent += 4
+                    for type in ('coarse', 'fine'):
+                        self.file.write('%s<resolution type="%s">\n' % (' ' * self.indent, type))
+                        self.indent += 4
+                        self.file.write('%s<value>%d</value>\n' % (' ' * self.indent,
+                                                                   data[attrb]['resolution'][type]))
+                        self.indent -= 4
+                        self.file.write('%s</resolution>\n' % (' ' * self.indent))
+
+                if data[attrb].has_key('wire-color'):
+                    self.file.write('%s<wire_color>\n' % (' ' * self.indent))
+                    self.indent += 4
+                    self.file.write('%s<value>%s</value>\n' % (' ' * self.indent,
+                                                               data[attrb]['wire-color']['value']))
+                    self.indent -= 4
+                    self.file.write('%s</wire_color>\n' % (' ' * self.indent))
+                self.indent -= 4
+            
+            # position
+            elif attrb == 'position':
+                self.file.write('%s<%s>\n' %(' ' * self.indent, attrb))
+                i = 0
+                for tag in ('x', 'y', 'z'):
+                    self.indent += 4
+                    self.file.write('%s<%s>%d</%s>\n' % (' ' * self.indent, tag,
+                                                        data[attrb][tag], tag))
+                    i += 1
+                    self.indent -= 4
+
+            if attrb != 'attribute':
+                # end tag
+                self.file.write('%s</%s>\n' % (' ' * self.indent, attrb))
+
+        self.indent -= 4
+        self.file.write('%s</surface>\n' % (' ' * self.indent))
+        self.indent -= 4
+
+    def __writeNvizVector(self, data):
+        """Save Nviz vector layer properties (lines/points) to workspace
+
+        @param data Nviz layer properties
+        """
+        self.indent += 4
+        for attrb in data.iterkeys():
+            if len(data[attrb]) < 1: # skip empty attributes
+                continue
+
+            if not data[attrb].has_key('object'): # skip disabled
+                continue
+            if attrb == 'lines':
+                self.file.write('%s<v%s>\n' % (' ' * self.indent, attrb))
+            elif attrb == 'points':
+                markerId = data[attrb]['marker']
+                marker = UserSettings.Get(group='nviz', key='vector',
+                                          subkey=['points', 'marker'], internal=True)[markerId]
+                self.file.write('%s<v%s marker="%s">\n' % (' ' * self.indent,
+                                                           attrb,
+                                                           marker))
+            self.indent += 4
+            for name in data[attrb].iterkeys():
+                if name in ('object', 'marker'):
+                    continue
+                if name == 'mode':
+                    self.file.write('%s<%s type="%s">\n' % (' ' * self.indent, name,
+                                                          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']))
+                        self.indent -= 4
+                    self.file.write('%s</%s>\n' % ((' ' * self.indent, name)))
+                else:
+                    self.file.write('%s<%s>\n' % (' ' * self.indent, name))
+                    self.indent += 4
+                    self.file.write('%s<value>%s</value>\n' % (' ' * self.indent, data[attrb][name]))
+                    self.indent -= 4
+                    self.file.write('%s</%s>\n' % (' ' * self.indent, name))
+            self.indent -= 4
+            self.file.write('%s</v%s>\n' % (' ' * self.indent, attrb))
+
+        self.indent -= 4
+
 class ProcessGrcFile(object):
     def __init__(self, filename):
         """Process GRC file"""

Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/wxgui_utils.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/wxgui_utils.py	2008-08-06 09:11:06 UTC (rev 32559)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/wxgui_utils.py	2008-08-06 09:21:46 UTC (rev 32560)
@@ -28,7 +28,9 @@
 import wx.lib.customtreectrl as CT
 import wx.combo
 import wx.lib.newevent
+import wx.lib.buttons  as  buttons
 
+import gdialogs
 import globalvar
 import menuform
 import mapdisp
@@ -45,22 +47,28 @@
     import subprocess
 except:
     from compat import subprocess
+    
+try:
+    import treemixin 
+except ImportError:
+    from wx.lib.mixins import treemixin
 
+
 TREE_ITEM_HEIGHT = 25
 
-class LayerTree(CT.CustomTreeCtrl):
+class LayerTree(treemixin.DragAndDrop, CT.CustomTreeCtrl):
     """
     Creates layer tree structure
     """
-    #	def __init__(self, parent, id, pos, size, style):
     def __init__(self, parent,
                  id=wx.ID_ANY, pos=wx.DefaultPosition,
                  size=wx.DefaultSize, style=wx.SUNKEN_BORDER,
                  ctstyle=CT.TR_HAS_BUTTONS | CT.TR_HAS_VARIABLE_ROW_HEIGHT |
                  CT.TR_HIDE_ROOT | CT.TR_ROW_LINES | CT.TR_FULL_ROW_HIGHLIGHT |
-                 CT.TR_EDIT_LABELS | CT.TR_MULTIPLE,
-                 **kargs):
-        CT.CustomTreeCtrl.__init__(self, parent, id, pos, size, style, ctstyle)
+                 CT.TR_MULTIPLE,**kargs):
+        self.items = []
+        self.itemCounter = 0
+        super(LayerTree, self).__init__(parent, id, pos, size, style=style, ctstyle=ctstyle)
 
         ### SetAutoLayout() causes that no vertical scrollbar is displayed
         ### when some layers are not visible in layer tree
@@ -77,12 +85,12 @@
         self.layer_selected = None # ID of currently selected layer
         self.saveitem = {}         # dictionary to preserve layer attributes for drag and drop
         self.first = True          # indicates if a layer is just added or not
-        self.drag = False          # flag to indicate a drag event is in process
+        self.flag = ''             # flag for drag and drop hittest
         self.disp_idx = kargs['idx']
         self.gismgr = kargs['gismgr']
-        self.notebook = kargs['notebook'] # Layer Manager notebook for layer tree
-        self.treepg = parent              # notebook page holding layer tree
-        self.auimgr = kargs['auimgr']     # aui manager
+        self.notebook = kargs['notebook']   # GIS Manager notebook for layer tree
+        self.treepg = parent        # notebook page holding layer tree
+        self.auimgr = kargs['auimgr']       # aui manager
 
         # init associated map display
         self.mapdisplay = mapdisp.MapFrame(self,
@@ -106,6 +114,7 @@
 
         self.root = self.AddRoot(_("Map Layers"))
         self.SetPyData(self.root, (None,None))
+        self.items = []
 
         #create image list to use with layer tree
         il = wx.ImageList(16, 16, mask=False)
@@ -119,6 +128,10 @@
         trgif = Icons["addrast"].GetBitmap(bmpsize)
         self.rast_icon = il.Add(trgif)
 
+        trgif = Icons["addrast3d"].GetBitmap(bmpsize)
+        print Icons["addrast3d"]
+        self.rast3d_icon = il.Add(trgif)
+
         trgif = Icons["addrgb"].GetBitmap(bmpsize)
         self.rgb_icon = il.Add(trgif)
 
@@ -170,13 +183,13 @@
         self.Bind(wx.EVT_TREE_SEL_CHANGED,      self.OnChangeSel)
         self.Bind(CT.EVT_TREE_ITEM_CHECKED,     self.OnLayerChecked)
         self.Bind(wx.EVT_TREE_DELETE_ITEM,      self.OnDeleteLayer)
-        self.Bind(wx.EVT_TREE_BEGIN_DRAG,       self.OnBeginDrag)
+        self.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK, self.OnLayerContextMenu)
+        #self.Bind(wx.EVT_TREE_BEGIN_DRAG,       self.OnDrag)
         self.Bind(wx.EVT_TREE_END_DRAG,         self.OnEndDrag)
-        self.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK, self.OnLayerContextMenu)
-        self.Bind(wx.EVT_TREE_END_LABEL_EDIT,   self.OnChangeLayerName)
+        #self.Bind(wx.EVT_TREE_END_LABEL_EDIT,   self.OnChangeLayerName)
         self.Bind(wx.EVT_KEY_UP,                self.OnKeyUp)
         # self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
-
+                
     def OnKeyUp(self, event):
         """Key pressed"""
         key = event.GetKeyCode()
@@ -185,9 +198,9 @@
 
         event.Skip()
 
-    def OnChangeLayerName (self, event):
-        """Change layer name"""
-        Debug.msg (3, "LayerTree.OnChangeLayerName: name=%s" % event.GetLabel())
+    #def OnChangeLayerName (self, event):
+    #    """Change layer name"""
+    #    Debug.msg (3, "LayerTree.OnChangeLayerName: name=%s" % event.GetLabel())
 
     def OnLayerContextMenu (self, event):
         """Contextual menu for item/layer"""
@@ -214,6 +227,7 @@
             self.popupID8 = wx.NewId()
             self.popupID9 = wx.NewId()
             self.popupID10 = wx.NewId()
+            self.popupID11 = wx.NewId() # nviz
             self.popupID12 = wx.NewId()
             self.popupID13 = wx.NewId()
             
@@ -231,11 +245,6 @@
                 ltype != "command": # properties
             self.popupMenu.AppendSeparator()
             self.popupMenu.Append(self.popupID8, text=_("Change opacity level"))
-            if self.FindWindowById(self.GetPyData(self.layer_selected)[0]['ctrl']).GetName() == 'spinCtrl':
-                checked = True
-            else:
-                checked = False
-            self.popupMenu.Check(self.popupID8, checked)
             self.Bind(wx.EVT_MENU, self.OnPopupOpacityLevel, id=self.popupID8)
             self.popupMenu.Append(self.popupID3, text=_("Properties"))
             self.Bind(wx.EVT_MENU, self.OnPopupProperties, id=self.popupID3)
@@ -249,7 +258,9 @@
             mltype = self.GetPyData(self.layer_selected)[0]['type']
         except:
             mltype = None
-        # vector specific items
+        #
+        # vector layers (specific items)
+        #
         if mltype and mltype == "vector":
             self.popupMenu.AppendSeparator()
             self.popupMenu.Append(self.popupID4, text=_("Show attribute data"))
@@ -280,8 +291,9 @@
             self.popupMenu.Append(self.popupID7, _("Metadata"))
             self.Bind (wx.EVT_MENU, self.OnMetadata, id=self.popupID7)
 
-
-        # raster
+        #
+        # raster layers (specific items)
+        #
         elif mltype and mltype == "raster":
             self.popupMenu.Append(self.popupID12, text=_("Zoom to selected map (ignore NULLs)"))
             self.Bind(wx.EVT_MENU, self.mapdisplay.MapWindow.OnZoomToRaster, id=self.popupID12)
@@ -294,6 +306,9 @@
             self.Bind (wx.EVT_MENU, self.OnProfile, id=self.popupID5)
             self.popupMenu.Append(self.popupID6, _("Metadata"))
             self.Bind (wx.EVT_MENU, self.OnMetadata, id=self.popupID6)
+            if self.mapdisplay.toolbars['nviz']:
+                self.popupMenu.Append(self.popupID11, _("Nviz properties"))
+                self.Bind (wx.EVT_MENU, self.OnNvizProperties, id=self.popupID11)
 
         ## self.PopupMenu(self.popupMenu, pos)
         self.PopupMenu(self.popupMenu)
@@ -318,7 +333,7 @@
     def OnSetCompRegFromRaster(self, event):
         """Set computational region from selected raster map (ignore NULLs)"""
         mapLayer = self.GetPyData(self.layer_selected)[0]['maplayer']
-
+        
         cmd = ['g.region',
                '-p',
                'zoom=%s' % mapLayer.name]
@@ -439,41 +454,58 @@
         if not self.GetPyData(self.layer_selected)[0]['ctrl']:
             return
 
-        win = self.FindWindowById(self.GetPyData(self.layer_selected)[0]['ctrl'])
-        type = win.GetName()
+        #win = self.FindWindowById(self.GetPyData(self.layer_selected)[0]['ctrl'])
+        #type = win.GetName()
+        #
+        #self.layer_selected.DeleteWindow()
 
-        self.layer_selected.DeleteWindow()
+        maplayer = self.GetPyData(self.layer_selected)[0]['maplayer']
+        current_opacity = maplayer.GetOpacity()
+        
+        dlg = gdialogs.SetOpacityDialog(self, opacity=current_opacity,
+                                        title=_("Set opacity <%s>") % maplayer.GetName())
         dlg.CentreOnParent()
 
-        opacity = self.GetPyData(self.layer_selected)[0]['maplayer'].GetOpacity()
-        if type == 'staticText':
-            ctrl = wx.SpinCtrl(self, id=wx.ID_ANY, value="",
-                               style=wx.SP_ARROW_KEYS, initial=100, min=0, max=100,
-                               name='spinCtrl')
-            ctrl.SetValue(opacity)
-            self.Bind(wx.EVT_SPINCTRL, self.OnOpacity, ctrl)
-        else:
-            ctrl = wx.StaticText(self, id=wx.ID_ANY,
-                                 name='staticText')
-            if opacity < 100:
-                ctrl.SetLabel('   (' + str(opacity) + '%)')
-                
-        self.GetPyData(self.layer_selected)[0]['ctrl'] = ctrl.GetId()
-        self.layer_selected.SetWindow(ctrl)
+        if dlg.ShowModal() == wx.ID_OK:
+            new_opacity = dlg.GetOpacity() # string            
+            self.Map.ChangeOpacity(maplayer, new_opacity)
+            maplayer.SetOpacity(new_opacity)
+            opacity_pct = int(new_opacity * 100)
+            layername = self.GetItemText(self.layer_selected)
+            layerbase = layername.split('(')[0].strip()
+            self.SetItemText(self.layer_selected,
+                             layerbase + ' (opacity: ' + str(opacity_pct) + '%)')
+            
+            # redraw map if auto-rendering is enabled
+            if self.mapdisplay.autoRender.GetValue(): 
+                self.mapdisplay.OnRender(None)
 
-        self.RefreshSelected()
-        self.Refresh()
-        
+    def OnNvizProperties(self, event):
+        """Nviz-related properties (raster/vector/volume)
+
+        @todo vector/volume
+        """
+        if not self.mapdisplay.nvizToolWin.IsShown():
+            self.mapdisplay.nvizToolWin.Show()
+
+        self.mapdisplay.nvizToolWin.SetPage('surface')
+
     def RenameLayer (self, event):
         """Rename layer"""
         self.EditLabel(self.layer_selected)
 
-    def AddLayer(self, ltype, lname=None, lchecked=None,
-                 lopacity=None, lcmd=None, lgroup=None):
+    def AddLayer(self, ltype, lname=None, lchecked=None, \
+                 lopacity=None, lcmd=None, lgroup=None, lnviz=None):
         """Add new item to the layer tree, create corresponding MapLayer instance.
         Launch property dialog if needed (raster, vector, etc.)
 
-        Note: lcmd is given as a list
+        @param ltype layer type (raster, vector, 3d-raster, ...)
+        @param lname layer name
+        @param lchecked if True layer is checked
+        @param lopacity layer opacity level
+        @param lcmd command (given as a list)
+        @param lgroup group name or None
+        @param lnviz layer Nviz properties
         """
 
         self.first = True
@@ -498,19 +530,20 @@
             grouptext = _('Layer group:') + str(self.groupnode)
             self.groupnode += 1
         else:
-            # all other items (raster, vector, ...)
-            if UserSettings.Get(group='manager', key='changeOpacityLevel', subkey='enabled'):
-                ctrl = wx.SpinCtrl(self, id=wx.ID_ANY, value="",
-                                   style=wx.SP_ARROW_KEYS, initial=100, min=0, max=100,
-                                   name='spinCtrl')
-                
-                self.Bind(wx.EVT_SPINCTRL, self.OnOpacity, ctrl)
-            else:
-                ctrl = wx.StaticText(self, id=wx.ID_ANY,
-                                     name='staticText')
+            btnbmp = Icons["layeropts"].GetBitmap((16,16))
+            ctrl = buttons.GenBitmapButton(self, id=wx.ID_ANY, bitmap=btnbmp, size=(24,24))
+            ctrl.SetToolTipString(_("Click to edit layer settings"))
+            self.Bind(wx.EVT_BUTTON, self.OnLayerContextMenu, ctrl)
         # add layer to the layer tree
         if self.layer_selected and self.layer_selected != self.GetRootItem():
-            if self.GetPyData(self.layer_selected)[0]['type'] != 'group':
+            
+            if self.GetPyData(self.layer_selected)[0]['type'] == 'group' \
+                and self.IsExpanded(self.layer_selected):
+                # add to group (first child of self.layer_selected) if group expanded
+                layer = self.PrependItem(parent=self.layer_selected,
+                                         text='', ct_type=1, wnd=ctrl)
+            else:
+                # prepend to individual layer or non-expanded group
                 if lgroup is False:
                     # -> last child of root (loading from workspace)
                     layer = self.AppendItem(parentId=self.root,
@@ -526,15 +559,9 @@
                     layer = self.InsertItem(parentId=parent,
                                             input=self.GetPrevSibling(self.layer_selected),
                                             text='', ct_type=1, wnd=ctrl)
+        else: # add first layer to the layer tree (first child of root)
+            layer = self.PrependItem(parent=self.root, text='', ct_type=1, wnd=ctrl)
 
-            else: # group -> first child of selected layer
-                layer = self.PrependItem(parent=self.layer_selected,
-                                         text='', ct_type=1, wnd=ctrl)
-                self.Expand(self.layer_selected)
-        else: # add first layer to the layer tree (i.e. first child of root)
-            layer = self.PrependItem(parent=self.root,
-                                     text='', ct_type=1, wnd=ctrl)
-
         # layer is initially unchecked as inactive (beside 'command')
         # use predefined value if given
         if lchecked is not None:
@@ -544,10 +571,17 @@
 
         self.CheckItem(layer, checked=checked)
 
+        # select new item
+        self.SelectItem(layer, select=True)
+        self.layer_selected = layer
+
         # add text and icons for each layer ltype
         if ltype == 'raster':
             self.SetItemImage(layer, self.rast_icon)
             self.SetItemText(layer, '%s %s' % (_('raster'), _('(double click to set properties)')))
+        elif ltype == '3d-raster':
+            self.SetItemImage(layer, self.rast3d_icon)
+            self.SetItemText(layer, '%s %s' % (_('3d raster'), _('(double click to set properties)')))
         elif ltype == 'rgb':
             self.SetItemImage(layer, self.rgb_icon)
             self.SetItemText(layer, '%s %s' % (_('RGB'), _('(double click to set properties)')))
@@ -594,14 +628,10 @@
 
         if ltype != 'group':
             if lopacity:
-                opacity = lopacity
-                if UserSettings.Get(group='manager', key='changeOpacityLevel', subkey='enabled'):
-                    ctrl.SetValue(int(lopacity * 100))
-                else:
-                    if opacity < 1.0:
-                        ctrl.SetLabel('   (' + str(int(opacity * 100)) + '%)')
+                opacity = int(lopacity * 100)
             else:
-                opacity = 1.0
+                opacity = 100
+            
             if lcmd and len(lcmd) > 1:
                 cmd = lcmd
                 render = False
@@ -621,26 +651,11 @@
                                     'type' : ltype,
                                     'ctrl' : ctrlId,
                                     'maplayer' : None,
+                                    'nviz' : lnviz,
                                     'prowin' : None}, 
                                    None))
 
-            # find previous map layer instance
-            prevItem = self.GetLastChild(self.root)
-            prevMapLayer = None
-            while prevItem and prevItem.IsOk() and \
-                    prevItem != layer:
-                if self.GetPyData(prevItem)[0]['maplayer']:
-                    prevMapLayer = self.GetPyData(prevItem)[0]['maplayer']
-                
-                prevItem = self.GetPrevSibling(prevItem)
-            
-            if prevMapLayer:
-                pos = self.Map.GetLayerIndex(prevMapLayer) + 1
-            else:
-                pos = -1
-
-            maplayer = self.Map.AddLayer(pos=pos,
-                                         type=ltype, command=self.GetPyData(layer)[0]['cmd'], name=name,
+            maplayer = self.Map.AddLayer(type=ltype, command=self.GetPyData(layer)[0]['cmd'], name=name,
                                          l_active=checked, l_hidden=False,
                                          l_opacity=opacity, l_render=render)
             self.GetPyData(layer)[0]['maplayer'] = maplayer
@@ -660,7 +675,9 @@
         # use predefined layer name if given
         if lname:
             if ltype != 'command':
-                self.SetItemText(layer, lname)
+                if opacity:
+                    name = lname + ' (opacity: ' + str(opacity) + '%)'
+                self.SetItemText(layer, name )
             else:
                 ctrl.SetValue(lname)
 
@@ -668,10 +685,6 @@
         if checked is True:
             self.mapdisplay.onRenderGauge.SetRange(len(self.Map.GetListOfLayers(l_active=True)))
 
-        # select new item
-        self.SelectItem(layer, select=True)
-        self.layer_selected = layer
-        
         # layer.SetHeight(TREE_ITEM_HEIGHT)
 
         return layer
@@ -702,10 +715,15 @@
             self.GetPyData(layer)[0]['cmd'] = cmdValidated
         elif ltype == 'raster':
             cmd = ['d.rast']
+            
             if UserSettings.Get(group='cmd', key='rasterOverlay', subkey='enabled'):
                 cmd.append('-o')
             menuform.GUI().ParseCommand(cmd, completed=(self.GetOptData,layer,params),
                                         parentframe=self)
+        elif ltype == '3d-raster':
+            cmd = ['d.rast3d']
+            menuform.GUI().ParseCommand(cmd, completed=(self.GetOptData,layer,params),
+                                        parentframe=self)
         elif ltype == 'rgb':
             menuform.GUI().ParseCommand(['d.rgb'], completed=(self.GetOptData,layer,params),
                                         parentframe=self)
@@ -752,7 +770,7 @@
             pass
         
     def OnActivateLayer(self, event):
-        """Click on the layer item.
+        """Double click on the layer item.
         Launch property dialog, or expand/collapse group of items, etc."""
         
         layer = event.GetItem()
@@ -805,11 +823,11 @@
         event.Skip()
 
     def OnLayerChecked(self, event):
-        """Enable/disable given layer item"""
+        """Enable/disable data layer"""
         item    = event.GetItem()
         checked = item.IsChecked()
         
-        if self.drag == False and self.first == False:
+        if self.first == False:
             # change active parameter for item in layers list in render.Map
             if self.GetPyData(item)[0]['type'] == 'group':
                 child, cookie = self.GetFirstChild(item)
@@ -823,6 +841,37 @@
         # update progress bar range (mapwindow statusbar)
         self.mapdisplay.onRenderGauge.SetRange(len(self.Map.GetListOfLayers(l_active=True)))
 
+        if self.mapdisplay.toolbars['nviz'] 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 checked: # enable
+                if mapLayer.type == 'raster':
+                    self.mapdisplay.MapWindow.LoadRaster(item)
+                elif mapLayer.type == 'vector':
+                    self.mapdisplay.MapWindow.LoadVector(item)
+
+            else: # disable
+                data = self.GetPyData(item)[0]['nviz']
+
+                if mapLayer.type == 'raster':
+                    self.mapdisplay.MapWindow.UnloadRaster(item)
+                elif mapLayer.type == 'vector':
+                    self.mapdisplay.MapWindow.UnloadVector(item)
+                    
+                    if hasattr(self.mapdisplay, "nvizToolWin"):
+                        toolWin = self.mapdisplay.nvizToolWin
+                        # remove vector page
+                        if toolWin.notebook.GetSelection() == toolWin.page['vector']['id']:
+                            toolWin.notebook.RemovePage(toolWin.page['vector']['id'])
+                            toolWin.page['vector']['id'] = -1
+                            toolWin.page['settings']['id'] = 1
+
+            self.mapdisplay.SetStatusText("", 0)
+
         # redraw map if auto-rendering is enabled
         if self.mapdisplay.autoRender.GetValue(): 
             self.mapdisplay.OnRender(None)
@@ -842,7 +891,7 @@
             layer = self.GetNextVisible(layer)
 
         # change parameters for item in layers list in render.Map
-        if layer and self.drag == False:
+        if layer == False:
             self.ChangeLayer(layer)
             self.GetPyData(layer)[0]['cmd'] = cmd.split(' ')
             maplayer = self.GetPyData(layer)[0]['maplayer']
@@ -853,39 +902,6 @@
 
         event.Skip()
 
-    def OnOpacity(self, event):
-        """
-        Set opacity level for map layer
-        """
-        Debug.msg (3, "LayerTree.OnOpacity(): %s" % event.GetInt())
-
-        ctrl = event.GetEventObject().GetId()
-        maplayer = None
-
-        vislayer = self.GetFirstVisibleItem()
-
-        layer = None
-        for item in range(0, self.GetCount()):
-            if self.GetPyData(vislayer)[0]['ctrl'] == ctrl:
-                layer = vislayer
-
-            if not self.GetNextVisible(vislayer):
-                break
-            else:
-                vislayer = self.GetNextVisible(vislayer)
-
-        if layer:
-            maplayer = self.GetPyData(layer)[0]['maplayer']
-
-        opacity = event.GetInt() / 100.
-        # change opacity parameter for item in layers list in render.Map
-        if maplayer and self.drag == False:
-            self.Map.ChangeOpacity(maplayer, opacity)
-
-        # redraw map if auto-rendering is enabled
-        if self.mapdisplay.autoRender.GetValue(): 
-            self.mapdisplay.OnRender(None)
-
     def OnChangeSel(self, event):
         """Selection changed"""
         oldlayer = event.GetOldItem()
@@ -903,7 +919,29 @@
             cmd = self.GetPyData(layer)[0]['maplayer'].GetCmd(string=True)
             if len(cmd) > 0:
                 self.gismgr.SetStatusText(cmd)
+        
+        # update nviz tools
+        if self.mapdisplay.toolbars['nviz'] and \
+                self.GetPyData(self.layer_selected) is not None:
 
+            if self.layer_selected.IsChecked():
+                # update Nviz tool window
+                type = self.GetPyData(self.layer_selected)[0]['maplayer'].type
+
+                if type == 'raster':
+                    self.mapdisplay.nvizToolWin.UpdatePage('surface')
+                    self.mapdisplay.nvizToolWin.SetPage('surface')
+                elif type == 'vector':
+                    self.mapdisplay.nvizToolWin.UpdatePage('vector')
+                    self.mapdisplay.nvizToolWin.SetPage('vector')
+            else:
+                for page in ('surface', 'vector'):
+                    pageId = self.mapdisplay.nvizToolWin.page[page]['id']
+                    if pageId > -1:
+                        self.mapdisplay.nvizToolWin.notebook.RemovePage(pageId)
+                        self.mapdisplay.nvizToolWin.page[page]['id'] = -1
+                        self.mapdisplay.nvizToolWin.page['settings']['id'] = 1 
+
     def OnCollapseNode(self, event):
         """
         Collapse node
@@ -918,109 +956,136 @@
         self.layer_selected = event.GetItem()
         if self.GetPyData(self.layer_selected)[0]['type'] == 'group':
             self.SetItemImage(self.layer_selected, self.folder_open)
+    
+    def OnEndDrag(self, event):
+        self.StopDragging()
+        dropTarget = event.GetItem()
+        self.flag = self.HitTest(event.GetPoint())[1]
+        if self.IsValidDropTarget(dropTarget):
+            self.UnselectAll()
+            if dropTarget != None:
+                self.SelectItem(dropTarget)
+            self.OnDrop(dropTarget, self._dragItem)
+        elif dropTarget == None:
+            self.OnDrop(dropTarget, self._dragItem)
 
-    def OnBeginDrag(self, event):
-        """
-        Drag and drop of tree nodes
-        """
+    def OnDrop(self, dropTarget, dragItem):
+        # save everthing associated with item to drag
+        try:
+            old = dragItem  # make sure this member exists
+        except:
+            return
 
-        item  = event.GetItem()
-        Debug.msg (3, "LayerTree.OnBeginDrag(): layer=%s" % \
-                   (self.GetItemText(item)))
+        Debug.msg (4, "LayerTree.OnDrop(): layer=%s" % \
+                   (self.GetItemText(dragItem)))
+        
+        # recreate data layer, insert copy of layer in new position, and delete original at old position
+        newItem  = self.RecreateItem (dragItem, dropTarget)
 
-        event.Allow()
-        self.drag = True
-        self.DoSelectItem(item, unselect_others=True)
+        # if recreated layer is a group, also recreate its children
+        if  self.GetPyData(newItem)[0]['type'] == 'group':
+            (child, cookie) = self.GetFirstChild(dragItem)
+            if child:
+                while child:
+                    self.RecreateItem(child, dropTarget, parent=newItem)
+                    self.Delete(child)
+                    child = self.GetNextChild(old, cookie)[0]
+            #self.Expand(newItem)
 
-        # save everthing associated with item to drag
-        self.dragItem = item
+        # delete layer at original position
+        try:
+            self.Delete(old) # entry in render.Map layers list automatically deleted by OnDeleteLayer handler
+        except AttributeError:
+            # FIXME being ugly (item.SetWindow(None))
+            pass
 
-    def RecreateItem (self, event, oldItem, parent=None):
+        # reorder layers in render.Map to match new order after drag and drop
+        self.ReorderLayers()
+
+        # redraw map if auto-rendering is enabled
+        if self.mapdisplay.autoRender.GetValue(): 
+            self.mapdisplay.OnRender(None)
+
+        # select new item
+        self.SelectItem(newItem)
+        
+    def RecreateItem (self, dragItem, dropTarget, parent=None):
         """
         Recreate item (needed for OnEndDrag())
         """
         Debug.msg (4, "LayerTree.RecreateItem(): layer=%s" % \
-                   self.GetItemText(oldItem))
+                   self.GetItemText(dragItem))
 
-        # fetch data (olditem)
-        text    = self.GetItemText(oldItem)
-        image   = self.GetItemImage(oldItem, 0)
-        if self.GetPyData(oldItem)[0]['ctrl']:
-            oldctrl = self.FindWindowById(self.GetPyData(oldItem)[0]['ctrl'])
-        else:
+        # fetch data (dragItem)
+        checked = self.IsItemChecked(dragItem)
+        image   = self.GetItemImage(dragItem, 0)
+        text    = self.GetItemText(dragItem)
+        if self.GetPyData(dragItem)[0]['ctrl']:
+            # recreate spin/text control for layer
+            btnbmp = Icons["layeropts"].GetBitmap((16,16))
+            newctrl = buttons.GenBitmapButton(self, id=wx.ID_ANY, bitmap=btnbmp)
+            newctrl.SetToolTipString(_("Click to edit layer settings"))
+            self.Bind(wx.EVT_BUTTON, self.OnLayerContextMenu, newctrl)
+            opacity = self.GetPyData(dragItem)[0]['maplayer'].GetOpacity()
+            windval = self.GetPyData(dragItem)[0]['maplayer'].GetOpacity()
+            data    = self.GetPyData(dragItem)
+        
+        elif self.GetPyData(dragItem)[0]['type'] == 'command':
+            # recreate command layer
             oldctrl = None
-        checked = self.IsItemChecked(oldItem)
-        
-        # recreate spin/text control for layer
-        if self.GetPyData(oldItem)[0]['type'] == 'command':
             newctrl = wx.TextCtrl(self, id=wx.ID_ANY, value='',
                                   pos=wx.DefaultPosition, size=(250,25),
                                   style=wx.TE_MULTILINE|wx.TE_WORDWRAP)
             try:
-                newctrl.SetValue(self.GetPyData(oldItem)[0]['maplayer'].GetCmd(string=True))
+                newctrl.SetValue(self.GetPyData(dragItem)[0]['maplayer'].GetCmd(string=True))
             except:
                 pass
             newctrl.Bind(wx.EVT_TEXT_ENTER, self.OnCmdChanged)
             newctrl.Bind(wx.EVT_TEXT,       self.OnCmdChanged)
-        elif self.GetPyData(oldItem)[0]['type'] == 'group' or oldctrl is None:
+            windval = self.GetPyData(dragItem)[0]['maplayer'].GetOpacity()
+            data    = self.GetPyData(dragItem)
+
+        elif self.GetPyData(dragItem)[0]['type'] == 'group':
+            #recreate group
             newctrl = None
-        else:
-            opacity = self.GetPyData(oldItem)[0]['maplayer'].GetOpacity()
-            if oldctrl.GetName() == 'staticText':
-                newctrl = wx.StaticText(self, id=wx.ID_ANY,
-                                        name='staticText')
-                if opacity < 100:
-                    newctrl.SetLabel('   (' + str(opacity) + '%)')
-            else:
-                newctrl = wx.SpinCtrl(self, id=wx.ID_ANY, value="",
-                                      style=wx.SP_ARROW_KEYS, min=0, max=100,
-                                      name='spinCtrl')
-                newctrl.SetValue(opacity)
-                self.Bind(wx.EVT_SPINCTRL, self.OnOpacity, newctrl)
-
-        # decide where to put new layer and put it there
-        if not parent:
-            flag = self.HitTest(event.GetPoint())[1]
-        else:
-            flag = 0
-
-        if self.GetPyData(oldItem)[0]['type'] == 'group':
             windval = None
             data    = None
-        else:
-            windval = self.GetPyData(self.layer_selected)[0]['maplayer'].GetOpacity()
-            data    = self.GetPyData(oldItem)
-
-        # create GenericTreeItem instance
-        if flag & wx.TREE_HITTEST_ABOVE:
-            newItem = self.PrependItem(self.root, text=text, \
-                                   ct_type=1, wnd=newctrl, image=image, \
-                                   data=data)
-        elif (flag &  wx.TREE_HITTEST_BELOW) or (flag & wx.TREE_HITTEST_NOWHERE) \
-                 or (flag & wx.TREE_HITTEST_TOLEFT) or (flag & wx.TREE_HITTEST_TORIGHT):
-            newItem = self.AppendItem(self.root, text=text, \
-                                  ct_type=1, wnd=newctrl, image=image, \
-                                  data=data)
-        else:
+            
+        # decide where to put recreated item
+        if dropTarget != None and dropTarget != self.GetRootItem():
             if parent:
+                # new item is a group
                 afteritem = parent
             else:
-                afteritem = event.GetItem()
+                # new item is a single layer
+                afteritem = dropTarget
 
+            # dragItem dropped on group
             if  self.GetPyData(afteritem)[0]['type'] == 'group':
-                parent = afteritem
-                newItem = self.AppendItem(parent, text=text, \
+                newItem = self.PrependItem(afteritem, text=text, \
                                       ct_type=1, wnd=newctrl, image=image, \
                                       data=data)
                 self.Expand(afteritem)
             else:
-                parent = self.GetItemParent(afteritem)
-                newItem = self.InsertItem(parent, afteritem, text=text, \
+                #dragItem dropped on single layer
+                newparent = self.GetItemParent(afteritem)
+                newItem = self.InsertItem(newparent, self.GetPrevSibling(afteritem), \
+                                       text=text, ct_type=1, wnd=newctrl, \
+                                       image=image, data=data)
+        else:
+            # if dragItem not dropped on a layer or group, append or prepend it to the layer tree
+            if self.flag & wx.TREE_HITTEST_ABOVE:
+                newItem = self.PrependItem(self.root, text=text, \
                                       ct_type=1, wnd=newctrl, image=image, \
                                       data=data)
+            elif (self.flag &  wx.TREE_HITTEST_BELOW) or (self.flag & wx.TREE_HITTEST_NOWHERE) \
+                     or (self.flag & wx.TREE_HITTEST_TOLEFT) or (self.flag & wx.TREE_HITTEST_TORIGHT):
+                newItem = self.AppendItem(self.root, text=text, \
+                                      ct_type=1, wnd=newctrl, image=image, \
+                                      data=data)
 
-        # add layer at new position
-        self.SetPyData(newItem, self.GetPyData(oldItem))
+        #update new layer 
+        self.SetPyData(newItem, self.GetPyData(dragItem))
         if newctrl:
             self.GetPyData(newItem)[0]['ctrl'] = newctrl.GetId()
         else:
@@ -1032,56 +1097,14 @@
 
         return newItem
 
-    def OnEndDrag(self, event):
-        """
-        Insert copy of layer in new
-        position and delete original at old position
-        """
-
-        self.drag = True
-        try:
-            old = self.dragItem  # make sure this member exists
-        except:
-            return
-
-        Debug.msg (4, "LayerTree.OnEndDrag(): layer=%s" % \
-                   (self.GetItemText(self.dragItem)))
-
-        newItem  = self.RecreateItem (event, self.dragItem)
-
-        if  self.GetPyData(newItem)[0]['type'] == 'group':
-            (child, cookie) = self.GetFirstChild(self.dragItem)
-            if child:
-                while child:
-                    self.RecreateItem(event, child, parent=newItem)
-                    self.Delete(child)
-                    child = self.GetNextChild(old, cookie)[0]
-
-            self.Expand(newItem)
-
-        # delete layer at original position
-        try:
-            self.Delete(old) # entry in render.Map layers list automatically deleted by OnDeleteLayer handler
-        except AttributeError:
-            # FIXME being ugly (item.SetWindow(None))
-            pass
-
-        # reorder layers in render.Map to match new order after drag and drop
-        self.ReorderLayers()
-
-        # select new item
-        self.SelectItem(newItem)
-
-        # completed drag and drop
-        self.drag = False
-
     def GetOptData(self, dcmd, layer, params, propwin):
         """Process layer data"""
 
         # set layer text to map name
         if dcmd:
+            opacity = int(self.GetPyData(layer)[0]['maplayer'].GetOpacity(float=True) * 100)
             mapname = utils.GetLayerNameFromCmd(dcmd, fullyQualified=True)
-            self.SetItemText(layer, mapname)
+            self.SetItemText(layer, mapname + ' (opacity: ' + str(opacity) + '%)')
 
         # update layer data
         if params:
@@ -1096,6 +1119,29 @@
         # change parameters for item in layers list in render.Map
         self.ChangeLayer(layer)
 
+        if self.mapdisplay.toolbars['nviz'] and dcmd:
+            # update nviz session
+            mapLayer = self.GetPyData(layer)[0]['maplayer']
+            mapWin = self.mapdisplay.MapWindow
+            if len(mapLayer.GetCmd()) > 0:
+                id = -1
+                if mapLayer.type == 'raster':
+                    if mapWin.IsLoaded(layer):
+                        mapWin.UnloadRaster(layer)
+                    
+                    mapWin.LoadRaster(layer)
+                elif mapLayer.type == 'vector':
+                    if mapWin.IsLoaded(layer):
+                        mapWin.UnloadVector(layer)
+                    
+                    mapWin.LoadVector(mapLayer)
+
+                # reset view when first layer loaded
+                nlayers = len(mapWin.Map.GetListOfLayers(l_type=('raster', 'vector'),
+                                                         l_active=True))
+                if nlayers < 2:
+                    mapWin.ResetView()
+        
     def ReorderLayers(self):
         """Add commands from data associated with
         any valid layers (checked or not) to layer list in order to
@@ -1111,7 +1157,7 @@
 
         itemList = ""
 
-        for item in range(0, self.GetCount()):
+        for item in range(self.GetCount()):
             itemList += self.GetItemText(vislayer) + ','
             if self.GetPyData(vislayer)[0]['type'] != 'group':
                 treelayers.append(self.GetPyData(vislayer)[0]['maplayer'])
@@ -1146,11 +1192,16 @@
                 opac = self.GetPyData(item)[0]['maplayer'].GetOpacity(float=True)
                 chk = self.IsItemChecked(item)
                 hidden = not self.IsVisible(item)
+        # determine layer name
+        layerName = utils.GetLayerNameFromCmd(cmdlist, fullyQualified=True)
+        if not layerName:
+            layerName = self.GetItemText(item)
+        maplayer = self.Map.ChangeLayer(layer=self.GetPyData(item)[0]['maplayer'], type=type,
+                                        command=cmdlist, name=layerName,
+                                        l_active=chk, l_hidden=hidden, l_opacity=opac, l_render=False)
 
-        self.Map.ChangeLayer(layer=self.GetPyData(item)[0]['maplayer'],
-                             command=cmdlist, name=self.GetItemText(item),
-                             active=chk, l_hidden=hidden, l_opacity=opac)
-        
+        self.GetPyData(item)[0]['maplayer'] = maplayer
+
         # if digitization tool enabled -> update list of available vector map layers
         if self.mapdisplay.toolbars['vdigit']:
             self.mapdisplay.toolbars['vdigit'].UpdateListOfLayers(updateTool=True)
@@ -1184,3 +1235,4 @@
             item = self.GetNextSibling(item)
 
         return None
+    

Modified: grass/branches/develbranch_6/gui/wxpython/icons/icon.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/icons/icon.py	2008-08-06 09:11:06 UTC (rev 32559)
+++ grass/branches/develbranch_6/gui/wxpython/icons/icon.py	2008-08-06 09:21:46 UTC (rev 32560)
@@ -80,13 +80,14 @@
     "digUndo" : wx.ART_ERROR, # FIXME
     "digSettings" : 'settings.gif',
     "digAdditionalTools" : wx.ART_ERROR, # FIXME
-    # gis manager
+    # layer manager
     "newdisplay" : 'gui-startmon.gif',
     "workspaceNew" : 'file-new.gif',
     "workspaceLoad" : 'file-new.gif', # change the icon if possible
     "workspaceOpen" : 'file-open.gif',
     "workspaceSave" : 'file-save.gif',
     "addrast"    : 'element-cell.gif',
+    "addrast3d"  : 'element-grid3.gif',
     "addvect"    : 'element-vector.gif',
     "addcmd"     : 'gui-cmd.gif',
     "addgrp"     : 'gui-group.gif',
@@ -114,7 +115,7 @@
     "font"       : 'gui-font.gif',
     "histogram"  : 'module-d.histogram.gif',
     "color"      : 'edit-color.gif',
-    "options"    :  wx.ART_ERROR, # FIXME
+    "layeropts"  : 'gui-layeroptions.gif',
     # profile 
     "profile"    : 'gui-profile.gif',
     "transect"   : 'gui-profiledefine.gif',
@@ -128,10 +129,12 @@
     'grGcpRms'     : 'gui-rms.gif',
     'grGcpRefresh' : 'gui-display.gif',
     "grGcpSave"    : 'file-save.gif', 
-    "grGcpAdd"     : wx.ART_ERROR, # FIXME
-    "grGcpDelete"  : wx.ART_ERROR, # FIXME
+    "grGcpAdd"     : wx.ART_NEW, # FIXME
+    "grGcpDelete"  : wx.ART_DELETE, # FIXME
     "grGcpReload"  : 'gui-redraw.gif',
     "grSettings"   : 'edit-color.gif', 
+    # nviz 
+    "nvizSettings" : 'settings.gif',   
     }
 
 # merge icons dictionaries, join paths
@@ -312,6 +315,8 @@
                              label=_("Add labels")),
     "addtext"    : MetaIcon (img=icons_img["addtext"],
                              label=_("Add text layer")),
+    "addrast3d"  : MetaIcon (img=icons_img["addrast3d"],
+                             label=_("Add 3D raster map")),
     # digit
     "digAddPoint": MetaIcon (img=icons_img["digAddPoint"],
                              label=_("Digitize new point"),
@@ -386,8 +391,8 @@
                              label=_("Select font")),
     "color"      : MetaIcon (img=icons_img["color"],
                              label=_("Select color")),
-    "options"    : MetaIcon (img=icons_img["options"],
-                             label=_("Set histogram options")),
+    "layeropts"  : MetaIcon (img=icons_img["layeropts"],
+                             label=_("Set options")),
     "analyze"    : MetaIcon (img=icons_img["analyze"],
                              label=_("Analyze")),
     # georectify
@@ -415,6 +420,10 @@
     "grSettings": MetaIcon (img=icons_img["grSettings"],
                             label=_("Settings"),
                             desc=_("Settings dialog for georectification tool")),
+    # nviz
+    "nvizSettings": MetaIcon (img=icons_img["nvizSettings"],
+                              label=_("Settings"),
+                              desc=_("Show Nviz settings dialog")),
     }
 
 # testing ...

Modified: grass/branches/develbranch_6/gui/wxpython/icons/silk/__init__.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/icons/silk/__init__.py	2008-08-06 09:11:06 UTC (rev 32559)
+++ grass/branches/develbranch_6/gui/wxpython/icons/silk/__init__.py	2008-08-06 09:21:46 UTC (rev 32560)
@@ -57,13 +57,14 @@
     "digUndo" : 'arrow_undo.png',
     "digSettings" : 'color_swatch.png',
     "digAdditionalTools" : 'plugin.png',
-    # gis manager
+    # layer manager
     "newdisplay" : 'application_add.png',
     "workspaceNew" : 'page_white.png',
     "workspaceLoad" : 'page_white_get.png',
     "workspaceOpen" : 'folder.png',
     "workspaceSave" : 'page_save.png',
     "addrast"    : 'image_add.png',
+    "addrast3d"  : 'bricks.png',
     "addshaded"  : 'picture_empty.png',
     "addrarrow"  : 'arrow_inout.png',
     "addvect"    : 'map_add.png',
@@ -78,6 +79,7 @@
     "addhis"     : 'his.png',
     "addthematic": 'thematic.png',
     "addchart"   : 'chart_bar.png',
+    "layeropts"  : 'map_edit.png',
     # profile analysis
     "transect"   : 'image_edit.png',
     "profiledraw"  : 'arrow_refresh.png',
@@ -93,4 +95,6 @@
     "grGcpDelete"  : 'bullet_delete.png',
     "grGcpReload"  : 'arrow_refresh.png',
     "grSettings"   : 'color_swatch.png',
+    # nviz
+    "nvizSettings"   : 'color_swatch.png',
     }

Copied: grass/branches/develbranch_6/gui/wxpython/nviz (from rev 32555, grass/trunk/gui/wxpython/nviz)

Deleted: grass/branches/develbranch_6/gui/wxpython/nviz/Makefile
===================================================================
--- grass/trunk/gui/wxpython/nviz/Makefile	2008-08-06 07:27:17 UTC (rev 32555)
+++ grass/branches/develbranch_6/gui/wxpython/nviz/Makefile	2008-08-06 09:21:46 UTC (rev 32560)
@@ -1,39 +0,0 @@
-MODULE_TOPDIR = ../../..
-
-include $(MODULE_TOPDIR)/include/Make/Lib.make
-
-LIB_NAME = grass7_wxnviz
-SOURCES := $(wildcard *.cpp) $(LIB_NAME)_wrap.cpp
-SHLIB_OBJS := $(patsubst %.cpp, $(OBJDIR)/%.o, $(SOURCES))
-
-EXTRA_CFLAGS = $(SHLIB_CFLAGS) $(GDALCFLAGS) $(PYTHONCFLAGS) $(WXWIDGETSCXXFLAGS) $(XCFLAGS) $(XMINC)
-EXTRA_LIBS = $(GISLIB) $(WXWIDGETSLIB) $(PYTHONLDFLAGS) $(XLIBPATH) $(XMLIB) $(XTLIB) $(XLIB) $(XEXTRALIBS) $(OGSFLIB) $(NVIZLIB)
-
-LOCAL_HEADERS = nviz.h
-
-ETCDIR = $(ETC)/wxpython
-
-SHLIB = $(OBJDIR)/_$(LIB_NAME).so
-
-EXTRA_CLEAN_FILES = $(SHLIB) $(LIB_NAME).i $(LIB_NAME).py $(LIB_NAME)_wrap.cpp
-
-default: install_nviz
-
-$(LIB_NAME).i: nviz.i nviz_types.i nviz.h
-	cat nviz.i nviz_types.i > $(LIB_NAME).i
-	echo "/* auto-generated swig typedef file */" >> $(LIB_NAME).i
-	cat nviz.h >> $(LIB_NAME).i
-
-$(LIB_NAME).py $(LIB_NAME)_wrap.cpp: $(LIB_NAME).i
-	$(SWIG) -c++ -python -shadow -o $(LIB_NAME)_wrap.cpp $<
-
-$(SHLIB): $(SHLIB_OBJS)
-ifeq ($(findstring darwin,$(ARCH)),darwin)
-	$(CXX) -o $@ $(LDFLAGS) $^ $(EXTRA_LIBS)
-else
-	$(SHLIB_LD) -o $@ $(LDFLAGS) $^ $(EXTRA_LIBS)
-endif
-
-install_nviz: $(SHLIB) $(LIB_NAME).py
-	$(INSTALL) $(SHLIB) $(ETCDIR)/nviz
-	$(INSTALL_DATA) $(LIB_NAME).py $(ETCDIR)/nviz

Copied: grass/branches/develbranch_6/gui/wxpython/nviz/Makefile (from rev 32558, grass/trunk/gui/wxpython/nviz/Makefile)
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/nviz/Makefile	                        (rev 0)
+++ grass/branches/develbranch_6/gui/wxpython/nviz/Makefile	2008-08-06 09:21:46 UTC (rev 32560)
@@ -0,0 +1,39 @@
+MODULE_TOPDIR = ../../..
+
+include $(MODULE_TOPDIR)/include/Make/Lib.make
+
+LIB_NAME = grass6_wxnviz
+SOURCES := $(wildcard *.cpp) $(LIB_NAME)_wrap.cpp
+SHLIB_OBJS := $(patsubst %.cpp, $(OBJDIR)/%.o, $(SOURCES))
+
+EXTRA_CFLAGS = $(SHLIB_CFLAGS) $(GDALCFLAGS) $(PYTHONCFLAGS) $(WXWIDGETSCXXFLAGS) $(XCFLAGS) $(XMINC)
+EXTRA_LIBS = $(GISLIB) $(WXWIDGETSLIB) $(PYTHONLDFLAGS) $(XLIBPATH) $(XMLIB) $(XTLIB) $(XLIB) $(XEXTRALIBS) $(OGSFLIB) $(NVIZLIB)
+
+LOCAL_HEADERS = nviz.h
+
+ETCDIR = $(ETC)/wxpython
+
+SHLIB = $(OBJDIR)/_$(LIB_NAME).so
+
+EXTRA_CLEAN_FILES = $(SHLIB) $(LIB_NAME).i $(LIB_NAME).py $(LIB_NAME)_wrap.cpp
+
+default: install_nviz
+
+$(LIB_NAME).i: nviz.i nviz_types.i nviz.h
+	cat nviz.i nviz_types.i > $(LIB_NAME).i
+	echo "/* auto-generated swig typedef file */" >> $(LIB_NAME).i
+	cat nviz.h >> $(LIB_NAME).i
+
+$(LIB_NAME).py $(LIB_NAME)_wrap.cpp: $(LIB_NAME).i
+	$(SWIG) -c++ -python -shadow -o $(LIB_NAME)_wrap.cpp $<
+
+$(SHLIB): $(SHLIB_OBJS)
+ifeq ($(findstring darwin,$(ARCH)),darwin)
+	$(CXX) -o $@ $(LDFLAGS) $^ $(EXTRA_LIBS)
+else
+	$(SHLIB_LD) -o $@ $(LDFLAGS) $^ $(EXTRA_LIBS)
+endif
+
+install_nviz: $(SHLIB) $(LIB_NAME).py
+	$(INSTALL) $(SHLIB) $(ETCDIR)/nviz
+	$(INSTALL_DATA) $(LIB_NAME).py $(ETCDIR)/nviz

Deleted: grass/branches/develbranch_6/gui/wxpython/nviz/change_view.cpp
===================================================================
--- grass/trunk/gui/wxpython/nviz/change_view.cpp	2008-08-06 07:27:17 UTC (rev 32555)
+++ grass/branches/develbranch_6/gui/wxpython/nviz/change_view.cpp	2008-08-06 09:21:46 UTC (rev 32560)
@@ -1,115 +0,0 @@
-/**
-   \file change_view.cpp
-   
-   \brief Experimental C++ wxWidgets Nviz prototype -- Change viewport
-
-   Used by wxGUI Nviz extension.
-
-   Copyright: (C) 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)
-
-   \date 2008
-*/
-
-#include "nviz.h"
-
-/*!
-  \brief GL canvas resized
-
-  \param width window width
-  \param height window height
-
-  \return 1 on success
-  \return 0 on failure (window resized by dafault to 20x20 px)
- */
-int Nviz::ResizeWindow(int width, int height)
-{
-    int ret;
-
-    ret = Nviz_resize_window(width, height);
-
-    G_debug(1, "Nviz::ResizeWindow(): width=%d height=%d",
-	    width, height);
-
-    return ret;
-}
-
-/*!
-  \brief Set default view (based on loaded data)
-
-  \return z-exag value, default, min and max height
-*/
-std::vector<double> Nviz::SetViewDefault()
-{
-    std::vector<double> ret;
-
-    float hdef, hmin, hmax, z_exag;
-
-    /* determine z-exag */
-    z_exag = Nviz_get_exag();
-    ret.push_back(z_exag);
-    Nviz_change_exag(data,
-		     z_exag);
-
-    /* determine height */
-    Nviz_get_exag_height(&hdef, &hmin, &hmax);
-    ret.push_back(hdef);
-    ret.push_back(hmin);
-    ret.push_back(hmax);
-
-    G_debug(1, "Nviz::SetViewDefault(): hdef=%f, hmin=%f, hmax=%f",
-	    hdef, hmin, hmax);
-
-    return ret;
-}
-
-/*!
-  \brief Change view settings
-
-  \param x,y position
-  \param height
-  \param persp perpective
-  \param twist
-
-  \return 1 on success
-*/
-int Nviz::SetView(float x, float y,
-		  float height, float persp, float twist)
-{
-    Nviz_set_viewpoint_height(data,
-			      height);
-    Nviz_set_viewpoint_position(data,
-				x, y);
-    Nviz_set_viewpoint_twist(data,
-			     twist);
-    Nviz_set_viewpoint_persp(data,
-			     persp);
-
-    G_debug(1, "Nviz::SetView(): x=%f, y=%f, height=%f, persp=%f, twist=%f",
-	    x, y, height, persp, twist);
-	
-    return 1;
-}
-
-/*!
-  \brief Set z-exag value
-
-  \param z_exag value
-
-  \return 1
-*/
-int Nviz::SetZExag(float z_exag)
-{
-    int ret;
-    
-    ret = Nviz_change_exag(data, z_exag);
-
-    G_debug(1, "Nviz::SetZExag(): z_exag=%f", z_exag);
-
-    return ret;
-}

Copied: grass/branches/develbranch_6/gui/wxpython/nviz/change_view.cpp (from rev 32558, grass/trunk/gui/wxpython/nviz/change_view.cpp)
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/nviz/change_view.cpp	                        (rev 0)
+++ grass/branches/develbranch_6/gui/wxpython/nviz/change_view.cpp	2008-08-06 09:21:46 UTC (rev 32560)
@@ -0,0 +1,115 @@
+/**
+   \file change_view.cpp
+   
+   \brief Experimental C++ wxWidgets Nviz prototype -- Change viewport
+
+   Used by wxGUI Nviz extension.
+
+   Copyright: (C) 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)
+
+   \date 2008
+*/
+
+#include "nviz.h"
+
+/*!
+  \brief GL canvas resized
+
+  \param width window width
+  \param height window height
+
+  \return 1 on success
+  \return 0 on failure (window resized by dafault to 20x20 px)
+ */
+int Nviz::ResizeWindow(int width, int height)
+{
+    int ret;
+
+    ret = Nviz_resize_window(width, height);
+
+    G_debug(1, "Nviz::ResizeWindow(): width=%d height=%d",
+	    width, height);
+
+    return ret;
+}
+
+/*!
+  \brief Set default view (based on loaded data)
+
+  \return z-exag value, default, min and max height
+*/
+std::vector<double> Nviz::SetViewDefault()
+{
+    std::vector<double> ret;
+
+    float hdef, hmin, hmax, z_exag;
+
+    /* determine z-exag */
+    z_exag = Nviz_get_exag();
+    ret.push_back(z_exag);
+    Nviz_change_exag(data,
+		     z_exag);
+
+    /* determine height */
+    Nviz_get_exag_height(&hdef, &hmin, &hmax);
+    ret.push_back(hdef);
+    ret.push_back(hmin);
+    ret.push_back(hmax);
+
+    G_debug(1, "Nviz::SetViewDefault(): hdef=%f, hmin=%f, hmax=%f",
+	    hdef, hmin, hmax);
+
+    return ret;
+}
+
+/*!
+  \brief Change view settings
+
+  \param x,y position
+  \param height
+  \param persp perpective
+  \param twist
+
+  \return 1 on success
+*/
+int Nviz::SetView(float x, float y,
+		  float height, float persp, float twist)
+{
+    Nviz_set_viewpoint_height(data,
+			      height);
+    Nviz_set_viewpoint_position(data,
+				x, y);
+    Nviz_set_viewpoint_twist(data,
+			     twist);
+    Nviz_set_viewpoint_persp(data,
+			     persp);
+
+    G_debug(1, "Nviz::SetView(): x=%f, y=%f, height=%f, persp=%f, twist=%f",
+	    x, y, height, persp, twist);
+	
+    return 1;
+}
+
+/*!
+  \brief Set z-exag value
+
+  \param z_exag value
+
+  \return 1
+*/
+int Nviz::SetZExag(float z_exag)
+{
+    int ret;
+    
+    ret = Nviz_change_exag(data, z_exag);
+
+    G_debug(1, "Nviz::SetZExag(): z_exag=%f", z_exag);
+
+    return ret;
+}

Deleted: grass/branches/develbranch_6/gui/wxpython/nviz/draw.cpp
===================================================================
--- grass/trunk/gui/wxpython/nviz/draw.cpp	2008-08-06 07:27:17 UTC (rev 32555)
+++ grass/branches/develbranch_6/gui/wxpython/nviz/draw.cpp	2008-08-06 09:21:46 UTC (rev 32560)
@@ -1,54 +0,0 @@
-/*!
-  \file draw.cpp
- 
-  \brief Experimental C++ wxWidgets Nviz prototype -- Draw map objects to GLX context
-  
-  COPYRIGHT: (C) 2008 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.
-
-  Based on visualization/nviz/src/draw.c and
-  visualization/nviz/src/togl_flythrough.c
-
-  \author Updated/modified by Martin Landa <landa.martin gmail.com> (Google SoC 2008)
-
-  \date 2008
-*/
-
-#include "nviz.h"
-
-/*!
-  \brief Draw map
-
-  \param quick true for forcing coarse draw mode 
-*/
-void Nviz::Draw(bool quick, bool quick_vlines, bool quick_vpoints)
-{
-    Nviz_draw_cplane(data, -1, -1); // ?
-
-    if (quick) {
-	Nviz_draw_quick(data, quick_vlines, quick_vpoints); 
-    }
-    else {
-	Nviz_draw_all (data); 
-    }
-
-    G_debug(1, "Nviz::Draw(): quick=%d",
-	    quick);
-    
-    return;
-}
-
-/*!
-  \brief Erase map display (with background color)
-*/
-void Nviz::EraseMap()
-{
-    GS_clear(data->bgcolor);
-
-    G_debug(1, "Nviz::EraseMap()");
-
-    return;
-}

Copied: grass/branches/develbranch_6/gui/wxpython/nviz/draw.cpp (from rev 32558, grass/trunk/gui/wxpython/nviz/draw.cpp)
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/nviz/draw.cpp	                        (rev 0)
+++ grass/branches/develbranch_6/gui/wxpython/nviz/draw.cpp	2008-08-06 09:21:46 UTC (rev 32560)
@@ -0,0 +1,54 @@
+/*!
+  \file draw.cpp
+ 
+  \brief Experimental C++ wxWidgets Nviz prototype -- Draw map objects to GLX context
+  
+  COPYRIGHT: (C) 2008 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.
+
+  Based on visualization/nviz/src/draw.c and
+  visualization/nviz/src/togl_flythrough.c
+
+  \author Updated/modified by Martin Landa <landa.martin gmail.com> (Google SoC 2008)
+
+  \date 2008
+*/
+
+#include "nviz.h"
+
+/*!
+  \brief Draw map
+
+  \param quick true for forcing coarse draw mode 
+*/
+void Nviz::Draw(bool quick, bool quick_vlines, bool quick_vpoints)
+{
+    Nviz_draw_cplane(data, -1, -1); // ?
+
+    if (quick) {
+	Nviz_draw_quick(data, quick_vlines, quick_vpoints); 
+    }
+    else {
+	Nviz_draw_all (data); 
+    }
+
+    G_debug(1, "Nviz::Draw(): quick=%d",
+	    quick);
+    
+    return;
+}
+
+/*!
+  \brief Erase map display (with background color)
+*/
+void Nviz::EraseMap()
+{
+    GS_clear(data->bgcolor);
+
+    G_debug(1, "Nviz::EraseMap()");
+
+    return;
+}

Deleted: grass/branches/develbranch_6/gui/wxpython/nviz/init.cpp
===================================================================
--- grass/trunk/gui/wxpython/nviz/init.cpp	2008-08-06 07:27:17 UTC (rev 32555)
+++ grass/branches/develbranch_6/gui/wxpython/nviz/init.cpp	2008-08-06 09:21:46 UTC (rev 32560)
@@ -1,229 +0,0 @@
-/**
-   \file init.cpp
-   
-   \brief Experimental C++ wxWidgets Nviz prototype -- initialization
-
-   Used by wxGUI Nviz extension.
-
-   Copyright: (C) 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)
-
-   \date 2008
-*/
-
-#include "nviz.h"
-
-#define MSG  0
-#define WARN 1
-#define ERR  2
-
-static void swap_gl();
-static int print_error(const char *, const int);
-static int print_percent(int);
-static void print_sentence (PyObject*, const int, const char *);
-static PyObject *logStream;
-static int message_id = 1;
-
-/*!
-  \brief Initialize Nviz class instance
-*/
-Nviz::Nviz(PyObject *log)
-{
-    G_gisinit(""); /* GRASS functions */
-
-    logStream = log;
-
-    G_set_error_routine(&print_error);
-    // TODO
-    // G_set_percent_routine(&print_percent);
-
-    GS_libinit();
-    /* GVL_libinit(); TODO */
-
-    GS_set_swap_func(swap_gl);
-
-    data = (nv_data*) G_malloc(sizeof (nv_data));
-
-    /* GLCanvas */
-    glCanvas = NULL;
-
-    G_debug(1, "Nviz::Nviz()");
-}
-
-/*!
-  \brief Destroy Nviz class instance
-*/
-Nviz::~Nviz()
-{
-    G_unset_error_routine();
-    // TODO
-    // G_unset_percent_routine();
-
-    G_free((void *) data);
-
-    data = NULL;
-    glCanvas = NULL;
-
-    logStream = NULL;
-}
-
-/*!
-  \brief Associate display with render window
-
-  \return 1 on success
-  \return 0 on failure
-*/
-int Nviz::SetDisplay(void *display)
-{
-    glCanvas = (wxGLCanvas *) display;
-    // glCanvas->SetCurrent();
-
-    G_debug(1, "Nviz::SetDisplay()");
-
-    return 1;
-}
-
-void Nviz::InitView()
-{
-    /* initialize nviz data */
-    Nviz_init_data(data);
-
-    /* define default attributes for map objects */
-    Nviz_set_surface_attr_default();
-    /* set background color */
-    Nviz_set_bgcolor(data, Nviz_color_from_str("white")); /* TODO */
-
-    /* initialize view */
-    Nviz_init_view();
-
-    /* set default lighting model */
-    SetLightsDefault();
-
-    /* clear window */
-    GS_clear(data->bgcolor);
-
-    G_debug(1, "Nviz::InitView()");
-
-    return;
-}
-
-/*!
-  \brief Reset session
-
-  Unload all data layers
-
-  @todo vector, volume
-*/
-void Nviz::Reset()
-{
-    int i;
-    int *surf_list, nsurfs;
-
-    surf_list = GS_get_surf_list(&nsurfs);
-    for (i = 0; i < nsurfs; i++) {
-	GS_delete_surface(surf_list[i]);
-    }
-}
-
-void swap_gl()
-{
-    return;
-}
-
-/*!
-  \brief Set background color
-
-  \param color_str color string
-*/
-void Nviz::SetBgColor(const char *color_str)
-{
-    data->bgcolor = Nviz_color_from_str(color_str);
-
-    return;
-}
-
-int print_error(const char *msg, const int type)
-{
-    if (logStream) {
-	print_sentence(logStream, type, msg);
-    }
-    else {
-	fprintf(stderr, "Nviz: %s\n", msg);
-    }
-
-    return 0;
-}
-
-/*
-  \brief Print one message, prefix inserted before each new line
-
-  From lib/gis/error.c
-*/
-void print_sentence (PyObject *pyFd, const int type, const char *msg)
-{
-    char prefix[256];
-    const char *start;
-    char* sentence;
-
-    switch ( type ) {
-	case MSG: 
-    	    sprintf (prefix, "GRASS_INFO_MESSAGE(%d,%d): Nviz: ", getpid(), message_id);
-	    break;
-	case WARN:
-    	    sprintf (prefix, "GRASS_INFO_WARNING(%d,%d): Nviz: ", getpid(), message_id);
-	    break;
-	case ERR:
-    	    sprintf (prefix, "GRASS_INFO_ERROR(%d,%d): Nviz: ", getpid(), message_id);
-	    break;
-    }
-
-    start = msg;
-
-    PyFile_WriteString("\n", pyFd);
-
-    while ( *start != '\0' ) {
-	const char *next = start;
-
-	PyFile_WriteString(prefix, pyFd);
-
-	while ( *next != '\0' ) {
-	    next++;
-		
-	    if ( *next == '\n' ) {
-	        next++;
-		break;
-	    }
-	}
-
-	sentence = (char *) G_malloc ((next - start + 1) * sizeof (char));
-	strncpy(sentence, start, next - start + 1);
-	sentence[next-start] = '\0';
-
-	PyFile_WriteString(sentence, pyFd);
-	G_free((void *)sentence);
-
-	PyFile_WriteString("\n", pyFd);
-	start = next;
-    }
-
-    PyFile_WriteString("\n", pyFd);
-    sprintf(prefix, "GRASS_INFO_END(%d,%d)\n", getpid(), message_id);
-    PyFile_WriteString(prefix, pyFd);
-
-    message_id++;
-}
-
-int print_percent(int x)
-{
-    char msg[256];
-
-    sprintf(msg, "GRASS_INFO_PERCENT: %d\n", x);
-    PyFile_WriteString(msg, logStream);
-
-    return 0;
-}

Copied: grass/branches/develbranch_6/gui/wxpython/nviz/init.cpp (from rev 32558, grass/trunk/gui/wxpython/nviz/init.cpp)
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/nviz/init.cpp	                        (rev 0)
+++ grass/branches/develbranch_6/gui/wxpython/nviz/init.cpp	2008-08-06 09:21:46 UTC (rev 32560)
@@ -0,0 +1,229 @@
+/**
+   \file init.cpp
+   
+   \brief Experimental C++ wxWidgets Nviz prototype -- initialization
+
+   Used by wxGUI Nviz extension.
+
+   Copyright: (C) 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)
+
+   \date 2008
+*/
+
+#include "nviz.h"
+
+#define MSG  0
+#define WARN 1
+#define ERR  2
+
+static void swap_gl();
+static int print_error(const char *, const int);
+static int print_percent(int);
+static void print_sentence (PyObject*, const int, const char *);
+static PyObject *logStream;
+static int message_id = 1;
+
+/*!
+  \brief Initialize Nviz class instance
+*/
+Nviz::Nviz(PyObject *log)
+{
+    G_gisinit(""); /* GRASS functions */
+
+    logStream = log;
+
+    G_set_error_routine(&print_error);
+    // TODO
+    // G_set_percent_routine(&print_percent);
+
+    GS_libinit();
+    /* GVL_libinit(); TODO */
+
+    GS_set_swap_func(swap_gl);
+
+    data = (nv_data*) G_malloc(sizeof (nv_data));
+
+    /* GLCanvas */
+    glCanvas = NULL;
+
+    G_debug(1, "Nviz::Nviz()");
+}
+
+/*!
+  \brief Destroy Nviz class instance
+*/
+Nviz::~Nviz()
+{
+    G_unset_error_routine();
+    // TODO
+    // G_unset_percent_routine();
+
+    G_free((void *) data);
+
+    data = NULL;
+    glCanvas = NULL;
+
+    logStream = NULL;
+}
+
+/*!
+  \brief Associate display with render window
+
+  \return 1 on success
+  \return 0 on failure
+*/
+int Nviz::SetDisplay(void *display)
+{
+    glCanvas = (wxGLCanvas *) display;
+    // glCanvas->SetCurrent();
+
+    G_debug(1, "Nviz::SetDisplay()");
+
+    return 1;
+}
+
+void Nviz::InitView()
+{
+    /* initialize nviz data */
+    Nviz_init_data(data);
+
+    /* define default attributes for map objects */
+    Nviz_set_surface_attr_default();
+    /* set background color */
+    Nviz_set_bgcolor(data, Nviz_color_from_str("white")); /* TODO */
+
+    /* initialize view */
+    Nviz_init_view();
+
+    /* set default lighting model */
+    SetLightsDefault();
+
+    /* clear window */
+    GS_clear(data->bgcolor);
+
+    G_debug(1, "Nviz::InitView()");
+
+    return;
+}
+
+/*!
+  \brief Reset session
+
+  Unload all data layers
+
+  @todo vector, volume
+*/
+void Nviz::Reset()
+{
+    int i;
+    int *surf_list, nsurfs;
+
+    surf_list = GS_get_surf_list(&nsurfs);
+    for (i = 0; i < nsurfs; i++) {
+	GS_delete_surface(surf_list[i]);
+    }
+}
+
+void swap_gl()
+{
+    return;
+}
+
+/*!
+  \brief Set background color
+
+  \param color_str color string
+*/
+void Nviz::SetBgColor(const char *color_str)
+{
+    data->bgcolor = Nviz_color_from_str(color_str);
+
+    return;
+}
+
+int print_error(const char *msg, const int type)
+{
+    if (logStream) {
+	print_sentence(logStream, type, msg);
+    }
+    else {
+	fprintf(stderr, "Nviz: %s\n", msg);
+    }
+
+    return 0;
+}
+
+/*
+  \brief Print one message, prefix inserted before each new line
+
+  From lib/gis/error.c
+*/
+void print_sentence (PyObject *pyFd, const int type, const char *msg)
+{
+    char prefix[256];
+    const char *start;
+    char* sentence;
+
+    switch ( type ) {
+	case MSG: 
+    	    sprintf (prefix, "GRASS_INFO_MESSAGE(%d,%d): Nviz: ", getpid(), message_id);
+	    break;
+	case WARN:
+    	    sprintf (prefix, "GRASS_INFO_WARNING(%d,%d): Nviz: ", getpid(), message_id);
+	    break;
+	case ERR:
+    	    sprintf (prefix, "GRASS_INFO_ERROR(%d,%d): Nviz: ", getpid(), message_id);
+	    break;
+    }
+
+    start = msg;
+
+    PyFile_WriteString("\n", pyFd);
+
+    while ( *start != '\0' ) {
+	const char *next = start;
+
+	PyFile_WriteString(prefix, pyFd);
+
+	while ( *next != '\0' ) {
+	    next++;
+		
+	    if ( *next == '\n' ) {
+	        next++;
+		break;
+	    }
+	}
+
+	sentence = (char *) G_malloc ((next - start + 1) * sizeof (char));
+	strncpy(sentence, start, next - start + 1);
+	sentence[next-start] = '\0';
+
+	PyFile_WriteString(sentence, pyFd);
+	G_free((void *)sentence);
+
+	PyFile_WriteString("\n", pyFd);
+	start = next;
+    }
+
+    PyFile_WriteString("\n", pyFd);
+    sprintf(prefix, "GRASS_INFO_END(%d,%d)\n", getpid(), message_id);
+    PyFile_WriteString(prefix, pyFd);
+
+    message_id++;
+}
+
+int print_percent(int x)
+{
+    char msg[256];
+
+    sprintf(msg, "GRASS_INFO_PERCENT: %d\n", x);
+    PyFile_WriteString(msg, logStream);
+
+    return 0;
+}

Deleted: grass/branches/develbranch_6/gui/wxpython/nviz/lights.cpp
===================================================================
--- grass/trunk/gui/wxpython/nviz/lights.cpp	2008-08-06 07:27:17 UTC (rev 32555)
+++ grass/branches/develbranch_6/gui/wxpython/nviz/lights.cpp	2008-08-06 09:21:46 UTC (rev 32560)
@@ -1,49 +0,0 @@
-/**
-   \file load.cpp
-   
-   \brief Experimental C++ wxWidgets Nviz prototype -- light manipulation
-
-   Used by wxGUI Nviz extension.
-
-   Copyright: (C) 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)
-
-   \date 2008
-*/
-
-#include "nviz.h"
-
-/*!
-  \brief Set default lighting model
-*/
-void Nviz::SetLightsDefault()
-{
-    /* first */
-    Nviz_set_light_position(data, 0,
-			    0.68, -0.68, 0.80, 0.0);
-    Nviz_set_light_bright(data, 0,
-			  0.8);
-    Nviz_set_light_color(data, 0,
-			 1.0, 1.0, 1.0);
-    Nviz_set_light_ambient(data, 0,
-			   0.2, 0.2, 0.2);
-
-    /* second */
-    Nviz_set_light_position(data, 1,
-			    0.0, 0.0, 1.0, 0.0);
-    Nviz_set_light_bright(data, 1,
-			  0.5);
-    Nviz_set_light_color(data, 1,
-			 1.0, 1.0, 1.0);
-    Nviz_set_light_ambient(data, 1,
-			   0.3, 0.3, 0.3);
-
-    G_debug(1, "Nviz::SetLightsDefault()");
-
-    return;
-}

Copied: grass/branches/develbranch_6/gui/wxpython/nviz/lights.cpp (from rev 32558, grass/trunk/gui/wxpython/nviz/lights.cpp)
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/nviz/lights.cpp	                        (rev 0)
+++ grass/branches/develbranch_6/gui/wxpython/nviz/lights.cpp	2008-08-06 09:21:46 UTC (rev 32560)
@@ -0,0 +1,49 @@
+/**
+   \file load.cpp
+   
+   \brief Experimental C++ wxWidgets Nviz prototype -- light manipulation
+
+   Used by wxGUI Nviz extension.
+
+   Copyright: (C) 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)
+
+   \date 2008
+*/
+
+#include "nviz.h"
+
+/*!
+  \brief Set default lighting model
+*/
+void Nviz::SetLightsDefault()
+{
+    /* first */
+    Nviz_set_light_position(data, 0,
+			    0.68, -0.68, 0.80, 0.0);
+    Nviz_set_light_bright(data, 0,
+			  0.8);
+    Nviz_set_light_color(data, 0,
+			 1.0, 1.0, 1.0);
+    Nviz_set_light_ambient(data, 0,
+			   0.2, 0.2, 0.2);
+
+    /* second */
+    Nviz_set_light_position(data, 1,
+			    0.0, 0.0, 1.0, 0.0);
+    Nviz_set_light_bright(data, 1,
+			  0.5);
+    Nviz_set_light_color(data, 1,
+			 1.0, 1.0, 1.0);
+    Nviz_set_light_ambient(data, 1,
+			   0.3, 0.3, 0.3);
+
+    G_debug(1, "Nviz::SetLightsDefault()");
+
+    return;
+}

Deleted: grass/branches/develbranch_6/gui/wxpython/nviz/load.cpp
===================================================================
--- grass/trunk/gui/wxpython/nviz/load.cpp	2008-08-06 07:27:17 UTC (rev 32555)
+++ grass/branches/develbranch_6/gui/wxpython/nviz/load.cpp	2008-08-06 09:21:46 UTC (rev 32560)
@@ -1,187 +0,0 @@
-/**
-   \file load.cpp
-   
-   \brief Experimental C++ wxWidgets Nviz prototype -- load data layers
-
-   Used by wxGUI Nviz extension.
-
-   Copyright: (C) 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)
-
-   \date 2008
-*/
-
-#include "nviz.h"
-
-extern "C" {
-#include <grass/glocale.h>
-}
-
-/*!
-  \brief Load raster map (surface)
-
-  \param name raster map name
-  \param color_name raster map for color (NULL for color_value)
-  \param color_value color string (named color or RGB triptet)
-
-  \return object id
-  \return -1 on failure
-*/
-int Nviz::LoadSurface(const char* name, const char *color_name, const char *color_value)
-{
-    char *mapset;
-    int id;
-
-    mapset = G_find_cell2 (name, "");
-    if (mapset == NULL) {
-	G_warning(_("Raster map <%s> not found"),
-		  name);
-	return -1;
-    }
-	    
-    /* topography */
-    id = Nviz_new_map_obj(MAP_OBJ_SURF,
-			  G_fully_qualified_name(name, mapset), 0.0,
-			  data);
-
-    if (color_name) { /* check for color map */
-	mapset = G_find_cell2 (color_name, "");
-	if (mapset == NULL) {
-	    G_warning(_("Raster map <%s> not found"),
-		      color_name);
-	    GS_delete_surface(id);
-	    return -1;
-	}
-
-	Nviz_set_attr(id, MAP_OBJ_SURF, ATT_COLOR, MAP_ATT,
-		      G_fully_qualified_name(color_name, mapset), -1.0,
-		      data);
-    }
-    else if (color_value) { /* check for color value */
-	Nviz_set_attr(id, MAP_OBJ_SURF, ATT_COLOR, CONST_ATT,
-		      NULL, Nviz_color_from_str(color_value),
-		      data);
-    }
-    else { /* use by default elevation map for coloring */
-	Nviz_set_attr(id, MAP_OBJ_SURF, ATT_COLOR, MAP_ATT,
-		      G_fully_qualified_name(name, mapset), -1.0,
-		      data);
-    }
-	    
-    /*
-      if (i > 1)
-      set_default_wirecolors(data, i);
-    */
-
-    /* focus on loaded data */
-    Nviz_set_focus_map(MAP_OBJ_UNDEFINED, -1);
-
-    G_debug(1, "Nviz::LoadRaster(): name=%s -> id=%d", name, id);
-
-    return id;
-}
-
-/*!
-  \brief Unload surface
-
-  \param id surface id
-
-  \return 1 on success
-  \return 0 on failure
-*/
-int Nviz::UnloadSurface(int id)
-{
-    if (!GS_surf_exists(id)) {
-	return 0;
-    }
-
-    G_debug(1, "Nviz::UnloadSurface(): id=%d", id);
-
-    if (GS_delete_surface(id) < 0)
-      return 0;
-
-    return 1;
-}
-
-/*!
-  \brief Load vector map overlay
-
-  \param name vector map name
-  \param points if true load 2d points rather then 2d lines
-
-  \return object id
-  \return -1 on failure
-*/
-int Nviz::LoadVector(const char *name, bool points)
-{
-    int id;
-    char *mapset;
-
-    if (GS_num_surfs() == 0) { /* load base surface if no loaded */
-	int *surf_list, nsurf;
-	
-	Nviz_new_map_obj(MAP_OBJ_SURF, NULL, 0.0, data);
-
-	surf_list = GS_get_surf_list(&nsurf);
-	GS_set_att_const(surf_list[0], ATT_TRANSP, 255);
-    }
-
-    mapset = G_find_vector2 (name, "");
-    if (mapset == NULL) {
-	G_warning(_("Vector map <%s> not found"),
-		  name);
-    }
-
-    if (points) {
-      id = Nviz_new_map_obj(MAP_OBJ_SITE,
-			    G_fully_qualified_name(name, mapset), 0.0,
-			    data);
-    }
-    else {
-      id = Nviz_new_map_obj(MAP_OBJ_VECT,
-			    G_fully_qualified_name(name, mapset), 0.0,
-			    data);
-    }
-
-    G_debug(1, "Nviz::LoadVector(): name=%s -> id=%d", name, id);
-
-    return id;
-}
-  
-/*!
-  \brief Unload vector set
-
-  \param id vector set id
-  \param points vector points or lines set
-
-  \return 1 on success
-  \return 0 on failure
-*/
-int Nviz::UnloadVector(int id, bool points)
-{
-    G_debug(1, "Nviz::UnloadVector(): id=%d", id);
-
-    if (points) {
-	if (!GP_site_exists(id)) {
-	    return 0;
-	}
-	
-	if (GP_delete_site(id) < 0)
-	    return 0;
-    }
-    else {
-	if (!GV_vect_exists(id)) {
-	    return 0;
-	}
-	
-	if (GV_delete_vector(id) < 0)
-	    return 0;
-    }
-
-    return 1;
-}

Copied: grass/branches/develbranch_6/gui/wxpython/nviz/load.cpp (from rev 32558, grass/trunk/gui/wxpython/nviz/load.cpp)
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/nviz/load.cpp	                        (rev 0)
+++ grass/branches/develbranch_6/gui/wxpython/nviz/load.cpp	2008-08-06 09:21:46 UTC (rev 32560)
@@ -0,0 +1,187 @@
+/**
+   \file load.cpp
+   
+   \brief Experimental C++ wxWidgets Nviz prototype -- load data layers
+
+   Used by wxGUI Nviz extension.
+
+   Copyright: (C) 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)
+
+   \date 2008
+*/
+
+#include "nviz.h"
+
+extern "C" {
+#include <grass/glocale.h>
+}
+
+/*!
+  \brief Load raster map (surface)
+
+  \param name raster map name
+  \param color_name raster map for color (NULL for color_value)
+  \param color_value color string (named color or RGB triptet)
+
+  \return object id
+  \return -1 on failure
+*/
+int Nviz::LoadSurface(const char* name, const char *color_name, const char *color_value)
+{
+    char *mapset;
+    int id;
+
+    mapset = G_find_cell2 (name, "");
+    if (mapset == NULL) {
+	G_warning(_("Raster map <%s> not found"),
+		  name);
+	return -1;
+    }
+	    
+    /* topography */
+    id = Nviz_new_map_obj(MAP_OBJ_SURF,
+			  G_fully_qualified_name(name, mapset), 0.0,
+			  data);
+
+    if (color_name) { /* check for color map */
+	mapset = G_find_cell2 (color_name, "");
+	if (mapset == NULL) {
+	    G_warning(_("Raster map <%s> not found"),
+		      color_name);
+	    GS_delete_surface(id);
+	    return -1;
+	}
+
+	Nviz_set_attr(id, MAP_OBJ_SURF, ATT_COLOR, MAP_ATT,
+		      G_fully_qualified_name(color_name, mapset), -1.0,
+		      data);
+    }
+    else if (color_value) { /* check for color value */
+	Nviz_set_attr(id, MAP_OBJ_SURF, ATT_COLOR, CONST_ATT,
+		      NULL, Nviz_color_from_str(color_value),
+		      data);
+    }
+    else { /* use by default elevation map for coloring */
+	Nviz_set_attr(id, MAP_OBJ_SURF, ATT_COLOR, MAP_ATT,
+		      G_fully_qualified_name(name, mapset), -1.0,
+		      data);
+    }
+	    
+    /*
+      if (i > 1)
+      set_default_wirecolors(data, i);
+    */
+
+    /* focus on loaded data */
+    Nviz_set_focus_map(MAP_OBJ_UNDEFINED, -1);
+
+    G_debug(1, "Nviz::LoadRaster(): name=%s -> id=%d", name, id);
+
+    return id;
+}
+
+/*!
+  \brief Unload surface
+
+  \param id surface id
+
+  \return 1 on success
+  \return 0 on failure
+*/
+int Nviz::UnloadSurface(int id)
+{
+    if (!GS_surf_exists(id)) {
+	return 0;
+    }
+
+    G_debug(1, "Nviz::UnloadSurface(): id=%d", id);
+
+    if (GS_delete_surface(id) < 0)
+      return 0;
+
+    return 1;
+}
+
+/*!
+  \brief Load vector map overlay
+
+  \param name vector map name
+  \param points if true load 2d points rather then 2d lines
+
+  \return object id
+  \return -1 on failure
+*/
+int Nviz::LoadVector(const char *name, bool points)
+{
+    int id;
+    char *mapset;
+
+    if (GS_num_surfs() == 0) { /* load base surface if no loaded */
+	int *surf_list, nsurf;
+	
+	Nviz_new_map_obj(MAP_OBJ_SURF, NULL, 0.0, data);
+
+	surf_list = GS_get_surf_list(&nsurf);
+	GS_set_att_const(surf_list[0], ATT_TRANSP, 255);
+    }
+
+    mapset = G_find_vector2 (name, "");
+    if (mapset == NULL) {
+	G_warning(_("Vector map <%s> not found"),
+		  name);
+    }
+
+    if (points) {
+      id = Nviz_new_map_obj(MAP_OBJ_SITE,
+			    G_fully_qualified_name(name, mapset), 0.0,
+			    data);
+    }
+    else {
+      id = Nviz_new_map_obj(MAP_OBJ_VECT,
+			    G_fully_qualified_name(name, mapset), 0.0,
+			    data);
+    }
+
+    G_debug(1, "Nviz::LoadVector(): name=%s -> id=%d", name, id);
+
+    return id;
+}
+  
+/*!
+  \brief Unload vector set
+
+  \param id vector set id
+  \param points vector points or lines set
+
+  \return 1 on success
+  \return 0 on failure
+*/
+int Nviz::UnloadVector(int id, bool points)
+{
+    G_debug(1, "Nviz::UnloadVector(): id=%d", id);
+
+    if (points) {
+	if (!GP_site_exists(id)) {
+	    return 0;
+	}
+	
+	if (GP_delete_site(id) < 0)
+	    return 0;
+    }
+    else {
+	if (!GV_vect_exists(id)) {
+	    return 0;
+	}
+	
+	if (GV_delete_vector(id) < 0)
+	    return 0;
+    }
+
+    return 1;
+}

Deleted: grass/branches/develbranch_6/gui/wxpython/nviz/nviz.h
===================================================================
--- grass/trunk/gui/wxpython/nviz/nviz.h	2008-08-06 07:27:17 UTC (rev 32555)
+++ grass/branches/develbranch_6/gui/wxpython/nviz/nviz.h	2008-08-06 09:21:46 UTC (rev 32560)
@@ -1,97 +0,0 @@
-#ifndef WXNVIZ_H
-#define WXNVIZ_H
-
-#include <vector>
-
-extern "C" {
-#include <grass/gis.h>
-#include <grass/gsurf.h>
-#include <grass/gstypes.h>
-#include <grass/nviz.h>
-}
-
-// For compilers that support precompilation, includes "wx.h".
-#include <wx/wxprec.h>
-
-#ifdef __BORLANDC__
-#pragma hdrstop
-#endif
-
-#ifndef WX_PRECOMP
-// Include your minimal set of headers here, or wx.h
-#include <wx/wx.h>
-#endif
-
-#include <wx/glcanvas.h>
-
-#include <Python.h>
-
-class Nviz
-{
-private:
-    nv_data *data;
-    wxGLCanvas *glCanvas;
-
-    /* surface.cpp */
-    int SetSurfaceAttr(int, int, bool, const char *);
-    int UnsetSurfaceAttr(int, int);
-
-public:
-    /* constructor */
-    Nviz(PyObject *);
-
-    /* destructor */
-    ~Nviz();
-
-    /* change_view.cpp */
-    int ResizeWindow(int, int);
-    std::vector<double> SetViewDefault();
-    int SetView(float, float,
-		float, float, float);
-    int SetZExag(float);
-
-    /* init.cpp */
-    int SetDisplay(void *);
-    void InitView();
-    void Reset();
-    void SetBgColor(const char *);
-
-    /* lights.cpp */
-    void SetLightsDefault();
-
-    /* load.cpp */
-    int LoadSurface(const char*, const char *, const char *);
-    int UnloadSurface(int);
-    int LoadVector(const char *, bool);
-    int UnloadVector(int, bool);
-
-    /* draw.cpp */
-    void Draw(bool, bool, bool);
-    void EraseMap();
-
-    /* surface.cpp */
-    int SetSurfaceTopo(int, bool, const char *);
-    int SetSurfaceColor(int, bool, const char *);
-    int SetSurfaceMask(int, bool, const char *);
-    int SetSurfaceTransp(int, bool, const char *);
-    int SetSurfaceShine(int, bool, const char *);
-    int SetSurfaceEmit(int, bool, const char *);
-    int UnsetSurfaceMask(int);
-    int UnsetSurfaceTransp(int);
-    int UnsetSurfaceEmit(int);
-    int SetSurfaceRes(int, int, int);
-    int SetSurfaceStyle(int, int);
-    int SetWireColor(int, const char *);
-    std::vector<double> GetSurfacePosition(int);
-    int SetSurfacePosition(int, float, float, float);
-
-    /* vector */
-    int SetVectorLineMode(int, const char *, int, int);
-    int SetVectorLineHeight(int, float);
-    int SetVectorLineSurface(int, int);
-    int SetVectorPointMode(int, const char*, int, float, int);
-    int SetVectorPointHeight(int, float);
-    int SetVectorPointSurface(int, int);
-};
-
-#endif /* WXNVIZ_H */

Copied: grass/branches/develbranch_6/gui/wxpython/nviz/nviz.h (from rev 32558, grass/trunk/gui/wxpython/nviz/nviz.h)
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/nviz/nviz.h	                        (rev 0)
+++ grass/branches/develbranch_6/gui/wxpython/nviz/nviz.h	2008-08-06 09:21:46 UTC (rev 32560)
@@ -0,0 +1,97 @@
+#ifndef WXNVIZ_H
+#define WXNVIZ_H
+
+#include <vector>
+
+extern "C" {
+#include <grass/gis.h>
+#include <grass/gsurf.h>
+#include <grass/gstypes.h>
+#include <grass/nviz.h>
+}
+
+// For compilers that support precompilation, includes "wx.h".
+#include <wx/wxprec.h>
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+// Include your minimal set of headers here, or wx.h
+#include <wx/wx.h>
+#endif
+
+#include <wx/glcanvas.h>
+
+#include <Python.h>
+
+class Nviz
+{
+private:
+    nv_data *data;
+    wxGLCanvas *glCanvas;
+
+    /* surface.cpp */
+    int SetSurfaceAttr(int, int, bool, const char *);
+    int UnsetSurfaceAttr(int, int);
+
+public:
+    /* constructor */
+    Nviz(PyObject *);
+
+    /* destructor */
+    ~Nviz();
+
+    /* change_view.cpp */
+    int ResizeWindow(int, int);
+    std::vector<double> SetViewDefault();
+    int SetView(float, float,
+		float, float, float);
+    int SetZExag(float);
+
+    /* init.cpp */
+    int SetDisplay(void *);
+    void InitView();
+    void Reset();
+    void SetBgColor(const char *);
+
+    /* lights.cpp */
+    void SetLightsDefault();
+
+    /* load.cpp */
+    int LoadSurface(const char*, const char *, const char *);
+    int UnloadSurface(int);
+    int LoadVector(const char *, bool);
+    int UnloadVector(int, bool);
+
+    /* draw.cpp */
+    void Draw(bool, bool, bool);
+    void EraseMap();
+
+    /* surface.cpp */
+    int SetSurfaceTopo(int, bool, const char *);
+    int SetSurfaceColor(int, bool, const char *);
+    int SetSurfaceMask(int, bool, const char *);
+    int SetSurfaceTransp(int, bool, const char *);
+    int SetSurfaceShine(int, bool, const char *);
+    int SetSurfaceEmit(int, bool, const char *);
+    int UnsetSurfaceMask(int);
+    int UnsetSurfaceTransp(int);
+    int UnsetSurfaceEmit(int);
+    int SetSurfaceRes(int, int, int);
+    int SetSurfaceStyle(int, int);
+    int SetWireColor(int, const char *);
+    std::vector<double> GetSurfacePosition(int);
+    int SetSurfacePosition(int, float, float, float);
+
+    /* vector */
+    int SetVectorLineMode(int, const char *, int, int);
+    int SetVectorLineHeight(int, float);
+    int SetVectorLineSurface(int, int);
+    int SetVectorPointMode(int, const char*, int, float, int);
+    int SetVectorPointHeight(int, float);
+    int SetVectorPointSurface(int, int);
+};
+
+#endif /* WXNVIZ_H */

Deleted: grass/branches/develbranch_6/gui/wxpython/nviz/nviz.i
===================================================================
--- grass/trunk/gui/wxpython/nviz/nviz.i	2008-08-06 07:27:17 UTC (rev 32555)
+++ grass/branches/develbranch_6/gui/wxpython/nviz/nviz.i	2008-08-06 09:21:46 UTC (rev 32560)
@@ -1,20 +0,0 @@
-/* File: nviz.i */
-
-%module grass7_wxnviz
-%{
-#include <grass/gsurf.h>
-#include <grass/gstypes.h>
-#include "nviz.h"
-%}
-
-%include "std_vector.i"
-namespace std { 
-   %template(IntVector) vector<int>;
-   %template(DoubleVector) vector<double>;
-}
-%include "std_map.i"
-namespace std { 
-   %template(IntVecIntMap) map<int, vector<int> >;
-}
-
-%include "nviz.h"

Copied: grass/branches/develbranch_6/gui/wxpython/nviz/nviz.i (from rev 32558, grass/trunk/gui/wxpython/nviz/nviz.i)
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/nviz/nviz.i	                        (rev 0)
+++ grass/branches/develbranch_6/gui/wxpython/nviz/nviz.i	2008-08-06 09:21:46 UTC (rev 32560)
@@ -0,0 +1,20 @@
+/* File: nviz.i */
+
+%module grass6_wxnviz
+%{
+#include <grass/gsurf.h>
+#include <grass/gstypes.h>
+#include "nviz.h"
+%}
+
+%include "std_vector.i"
+namespace std { 
+   %template(IntVector) vector<int>;
+   %template(DoubleVector) vector<double>;
+}
+%include "std_map.i"
+namespace std { 
+   %template(IntVecIntMap) map<int, vector<int> >;
+}
+
+%include "nviz.h"

Deleted: grass/branches/develbranch_6/gui/wxpython/nviz/nviz_types.i
===================================================================
--- grass/trunk/gui/wxpython/nviz/nviz_types.i	2008-08-06 07:27:17 UTC (rev 32555)
+++ grass/branches/develbranch_6/gui/wxpython/nviz/nviz_types.i	2008-08-06 09:21:46 UTC (rev 32560)
@@ -1,49 +0,0 @@
-/* extracted from include/vect/dig_defines.h */
-
-#define GV_POINT      0x01
-#define GV_LINE       0x02
-#define GV_BOUNDARY   0x04
-#define GV_CENTROID   0x08
-#define GV_FACE       0x10
-#define GV_KERNEL     0x20
-#define GV_AREA       0x40
-#define GV_VOLUME     0x80
-
-#define GV_POINTS (GV_POINT | GV_CENTROID )
-#define GV_LINES (GV_LINE | GV_BOUNDARY )
-
-#define PORT_DOUBLE_MAX 1.7976931348623157e+308
-
-/* extracted from gui/wxpython/nviz/nviz.h */
-
-#define VIEW_DEFAULT_POS_X 0.85
-#define VIEW_DEFAULT_POS_Y 0.85
-#define VIEW_DEFAULT_PERSP 40.0
-#define VIEW_DEFAULT_TWIST 0.0
-#define VIEW_DEFAULT_ZEXAG 1.0
-
-/* extracted from include/gsurf.h */
-#define DM_GOURAUD   0x00000100
-#define DM_FLAT      0x00000200
-
-#define DM_FRINGE    0x00000010
-
-#define DM_WIRE      0x00000001
-#define DM_COL_WIRE  0x00000002
-#define DM_POLY      0x00000004
-#define DM_WIRE_POLY 0x00000008
-
-#define DM_GRID_WIRE 0x00000400
-#define DM_GRID_SURF 0x00000800
-
-/* site markers */
-#define ST_X          1
-#define ST_BOX        2
-#define ST_SPHERE     3
-#define ST_CUBE       4
-#define ST_DIAMOND    5
-#define ST_DEC_TREE   6
-#define ST_CON_TREE   7
-#define ST_ASTER      8
-#define ST_GYRO       9
-#define ST_HISTOGRAM  10

Copied: grass/branches/develbranch_6/gui/wxpython/nviz/nviz_types.i (from rev 32558, grass/trunk/gui/wxpython/nviz/nviz_types.i)
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/nviz/nviz_types.i	                        (rev 0)
+++ grass/branches/develbranch_6/gui/wxpython/nviz/nviz_types.i	2008-08-06 09:21:46 UTC (rev 32560)
@@ -0,0 +1,49 @@
+/* extracted from include/vect/dig_defines.h */
+
+#define GV_POINT      0x01
+#define GV_LINE       0x02
+#define GV_BOUNDARY   0x04
+#define GV_CENTROID   0x08
+#define GV_FACE       0x10
+#define GV_KERNEL     0x20
+#define GV_AREA       0x40
+#define GV_VOLUME     0x80
+
+#define GV_POINTS (GV_POINT | GV_CENTROID )
+#define GV_LINES (GV_LINE | GV_BOUNDARY )
+
+#define PORT_DOUBLE_MAX 1.7976931348623157e+308
+
+/* extracted from gui/wxpython/nviz/nviz.h */
+
+#define VIEW_DEFAULT_POS_X 0.85
+#define VIEW_DEFAULT_POS_Y 0.85
+#define VIEW_DEFAULT_PERSP 40.0
+#define VIEW_DEFAULT_TWIST 0.0
+#define VIEW_DEFAULT_ZEXAG 1.0
+
+/* extracted from include/gsurf.h */
+#define DM_GOURAUD   0x00000100
+#define DM_FLAT      0x00000200
+
+#define DM_FRINGE    0x00000010
+
+#define DM_WIRE      0x00000001
+#define DM_COL_WIRE  0x00000002
+#define DM_POLY      0x00000004
+#define DM_WIRE_POLY 0x00000008
+
+#define DM_GRID_WIRE 0x00000400
+#define DM_GRID_SURF 0x00000800
+
+/* site markers */
+#define ST_X          1
+#define ST_BOX        2
+#define ST_SPHERE     3
+#define ST_CUBE       4
+#define ST_DIAMOND    5
+#define ST_DEC_TREE   6
+#define ST_CON_TREE   7
+#define ST_ASTER      8
+#define ST_GYRO       9
+#define ST_HISTOGRAM  10

Deleted: grass/branches/develbranch_6/gui/wxpython/nviz/surface.cpp
===================================================================
--- grass/trunk/gui/wxpython/nviz/surface.cpp	2008-08-06 07:27:17 UTC (rev 32555)
+++ grass/branches/develbranch_6/gui/wxpython/nviz/surface.cpp	2008-08-06 09:21:46 UTC (rev 32560)
@@ -1,387 +0,0 @@
-/**
-   \file surface.cpp
-   
-   \brief Experimental C++ wxWidgets Nviz prototype -- surface attributes
-
-   Used by wxGUI Nviz extension.
-
-   Copyright: (C) 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)
-
-   \date 2008
-*/
-
-#include "nviz.h"
-
-/*!
-  \brief Set surface topography
-
-  \param id surface id
-  \param map if true use map otherwise constant
-  \param value map name of value
-
-  \return 1 on success
-  \return 0 on failure
-*/
-int Nviz::SetSurfaceTopo(int id, bool map, const char *value)
-{
-    return SetSurfaceAttr(id, ATT_TOPO, map, value);
-}
-
-/*!
-  \brief Set surface color
-
-  \param id surface id
-  \param map if true use map otherwise constant
-  \param value map name of value
-
-  \return 1 on success
-  \return 0 on failure
-*/
-int Nviz::SetSurfaceColor(int id, bool map, const char *value)
-{
-    return SetSurfaceAttr(id, ATT_COLOR, map, value);
-}
-
-/*!
-  \brief Set surface mask
-
-  @todo invert
-
-  \param id surface id
-  \param invert if true invert mask 
-  \param value map name of value
-
-  \return 1 on success
-  \return 0 on failure
-*/
-int Nviz::SetSurfaceMask(int id, bool invert, const char *value)
-{
-    return SetSurfaceAttr(id, ATT_MASK, true, value);
-}
-
-/*!
-  \brief Set surface mask
-
-  @todo invert
-
-  \param id surface id
-  \param map if true use map otherwise constant
-  \param value map name of value
-
-  \return 1 on success
-  \return 0 on failure
-*/
-int Nviz::SetSurfaceTransp(int id, bool map, const char *value)
-{
-    return SetSurfaceAttr(id, ATT_TRANSP, map, value);
-}
-
-/*!
-  \brief Set surface shininess
-
-  \param id surface id
-  \param map if true use map otherwise constant
-  \param value map name of value
-
-  \return 1 on success
-  \return 0 on failure
-*/
-int Nviz::SetSurfaceShine(int id, bool map, const char *value)
-{
-    return SetSurfaceAttr(id, ATT_SHINE, map, value);
-}
-
-/*!
-  \brief Set surface emission
-
-  \param id surface id
-  \param map if true use map otherwise constant
-  \param value map name of value
-
-  \return 1 on success
-  \return 0 on failure
-*/
-int Nviz::SetSurfaceEmit(int id, bool map, const char *value)
-{
-    return SetSurfaceAttr(id, ATT_EMIT, map, value);
-}
-
-/*!
-  \brief Set surface attribute
-
-  \param id surface id
-  \param attr attribute desc
-  \param map if true use map otherwise constant
-  \param value map name of value
-
-  \return 1 on success
-  \return 0 on failure
-*/
-int Nviz::SetSurfaceAttr(int id, int attr, bool map, const char *value)
-{
-    int ret;
-
-    if (!GS_surf_exists(id)) {
-	return 0;
-    }
-
-    if (map) {
-	ret = Nviz_set_attr(id, MAP_OBJ_SURF, attr, MAP_ATT,
-			    value, -1.0,
-			    data);
-    }
-    else {
-	float val;
-	if (attr == ATT_COLOR) {
-	    val = Nviz_color_from_str(value);
-	}
-	else {
-	    val = atof(value);
-	}
-	ret = Nviz_set_attr(id, MAP_OBJ_SURF, attr, CONST_ATT,
-			    NULL, val,
-			    data);
-    }
-	
-    G_debug(1, "Nviz::SetSurfaceAttr(): id=%d, attr=%d, map=%d, value=%s",
-	    id, attr, map, value);
-
-    return ret;
-}
-
-/*!
-  \brief Unset surface mask
-
-  \param id surface id
-
-  \return 1 on success
-  \return 0 on failure
-*/
-
-int Nviz::UnsetSurfaceMask(int id)
-{
-    return UnsetSurfaceAttr(id, ATT_MASK);
-}
-
-/*!
-  \brief Unset surface transparency
-
-  \param id surface id
-
-  \return 1 on success
-  \return 0 on failure
-*/
-
-int Nviz::UnsetSurfaceTransp(int id)
-{
-    return UnsetSurfaceAttr(id, ATT_TRANSP);
-}
-
-/*!
-  \brief Unset surface emission
-
-  \param id surface id
-
-  \return 1 on success
-  \return 0 on failure
-*/
-
-int Nviz::UnsetSurfaceEmit(int id)
-{
-    return UnsetSurfaceAttr(id, ATT_EMIT);
-}
-
-/*!
-  \brief Unset surface attribute
-
-  \param id surface id
-  \param attr attribute descriptor
-
-  \return 1 on success
-  \return 0 on failure
-*/
-int Nviz::UnsetSurfaceAttr(int id, int attr)
-{
-    if (!GS_surf_exists(id)) {
-	return 0;
-    }
-
-    G_debug(1, "Nviz::UnsetSurfaceAttr(): id=%d, attr=%d",
-	    id, attr);
-    
-    return Nviz_unset_attr(id, MAP_OBJ_SURF, attr);
-}
-
-/*!
-  \brief Set surface resolution
-
-  \param id surface id
-  \param fine x/y fine resolution
-  \param coarse x/y coarse resolution
-
-  \return 0 on error
-  \return 1 on success
-*/
-int Nviz::SetSurfaceRes(int id, int fine, int coarse)
-{
-    G_debug(1, "Nviz::SetSurfaceRes(): id=%d, fine=%d, coarse=%d",
-	    id, fine, coarse);
-
-
-    if (id > 0) {
-	if (!GS_surf_exists(id)) {
-	    return 0;
-	}
-
-	if (GS_set_drawres(id, fine, fine, coarse, coarse) < 0) {
-	    return 0;
-	}
-    }
-    else {
-	GS_setall_drawres(fine, fine, coarse, coarse);
-    }
-
-    return 1;
-}
-
-/*!
-  \brief Set draw style
-
-  Draw styles:
-   - DM_GOURAUD
-   - DM_FLAT
-   - DM_FRINGE
-   - DM_WIRE
-   - DM_COL_WIRE
-   - DM_POLY
-   - DM_WIRE_POLY
-   - DM_GRID_WIRE
-   - DM_GRID_SURF
-
-  \param id surface id (<= 0 for all)
-  \param style draw style
-
-  \return 1 on success
-  \return 0 on error
-*/
-int Nviz::SetSurfaceStyle(int id, int style)
-{
-    G_debug(1, "Nviz::SetSurfaceStyle(): id=%d, style=%d",
-	    id, style);
-
-    if (id > 0) {
-	if (!GS_surf_exists(id)) {
-	    return 0;
-	}
-	
-	if (GS_set_drawmode(id, style) < 0) {
-	    return 0;
-	}
-	return 1;
-    }
-
-    if (GS_setall_drawmode(style) < 0) {
-	return 0;
-    }
-
-    return 1;
-}
-
-/*!
-  \brief Set color of wire
-
-  \todo all
-
-  \param surface id (< 0 for all)
-  \param color color string (R:G:B)
-
-  \return 1 on success
-  \return 0 on failure
-*/
-int Nviz::SetWireColor(int id, const char* color_str)
-{
-    int color;
-
-    G_debug(1, "Nviz::SetWireColor(): id=%d, color=%s",
-	    id, color_str);
-
-    color = Nviz_color_from_str(color_str);
-
-    if (id > 0) {
-	if (!GS_surf_exists(id)) {
-	    return 0;
-	}
-	GS_set_wire_color(id, color);
-    }
-    else {
-	int *surf_list, nsurfs, id;
-
-	surf_list = GS_get_surf_list(&nsurfs);
-	for (int i = 0; i < nsurfs; i++) {
-	    id = surf_list[i];
-	    GS_set_wire_color(id, color);
-	}
-
-	G_free(surf_list);
-    }
-
-    return 1;
-}
-
-/*!
-  \brief Get surface position
-
-  \param id surface id
-
-  \return x,y,z
-  \return zero-length vector on error
-*/
-std::vector<double> Nviz::GetSurfacePosition(int id)
-{
-    std::vector<double> vals;
-    float x, y, z;
-    if (!GS_surf_exists(id)) {
-	return vals;
-    }
-    
-    GS_get_trans(id, &x, &y, &z);
-    
-    G_debug(1, "Nviz::GetSurfacePosition(): id=%d, x=%f, y=%f, z=%f",
-	    id, x, y, z);
-
-
-    vals.push_back(double (x));
-    vals.push_back(double (y));
-    vals.push_back(double (z));
-
-    return vals;
-}
-
-/*!
-  \brief Set surface position
-
-  \param id surface id
-  \param x,y,z translation values
-
-  \return 1 on success
-  \return 0 on failure
-*/
-int Nviz::SetSurfacePosition(int id, float x, float y, float z)
-{
-    if (!GS_surf_exists(id)) {
-	return 0;
-    }
-    
-    G_debug(1, "Nviz::SetSurfacePosition(): id=%d, x=%f, y=%f, z=%f",
-	    id, x, y, z);
-
-    GS_set_trans(id, x, y, z);
-
-    return 1;
-}

Copied: grass/branches/develbranch_6/gui/wxpython/nviz/surface.cpp (from rev 32558, grass/trunk/gui/wxpython/nviz/surface.cpp)
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/nviz/surface.cpp	                        (rev 0)
+++ grass/branches/develbranch_6/gui/wxpython/nviz/surface.cpp	2008-08-06 09:21:46 UTC (rev 32560)
@@ -0,0 +1,387 @@
+/**
+   \file surface.cpp
+   
+   \brief Experimental C++ wxWidgets Nviz prototype -- surface attributes
+
+   Used by wxGUI Nviz extension.
+
+   Copyright: (C) 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)
+
+   \date 2008
+*/
+
+#include "nviz.h"
+
+/*!
+  \brief Set surface topography
+
+  \param id surface id
+  \param map if true use map otherwise constant
+  \param value map name of value
+
+  \return 1 on success
+  \return 0 on failure
+*/
+int Nviz::SetSurfaceTopo(int id, bool map, const char *value)
+{
+    return SetSurfaceAttr(id, ATT_TOPO, map, value);
+}
+
+/*!
+  \brief Set surface color
+
+  \param id surface id
+  \param map if true use map otherwise constant
+  \param value map name of value
+
+  \return 1 on success
+  \return 0 on failure
+*/
+int Nviz::SetSurfaceColor(int id, bool map, const char *value)
+{
+    return SetSurfaceAttr(id, ATT_COLOR, map, value);
+}
+
+/*!
+  \brief Set surface mask
+
+  @todo invert
+
+  \param id surface id
+  \param invert if true invert mask 
+  \param value map name of value
+
+  \return 1 on success
+  \return 0 on failure
+*/
+int Nviz::SetSurfaceMask(int id, bool invert, const char *value)
+{
+    return SetSurfaceAttr(id, ATT_MASK, true, value);
+}
+
+/*!
+  \brief Set surface mask
+
+  @todo invert
+
+  \param id surface id
+  \param map if true use map otherwise constant
+  \param value map name of value
+
+  \return 1 on success
+  \return 0 on failure
+*/
+int Nviz::SetSurfaceTransp(int id, bool map, const char *value)
+{
+    return SetSurfaceAttr(id, ATT_TRANSP, map, value);
+}
+
+/*!
+  \brief Set surface shininess
+
+  \param id surface id
+  \param map if true use map otherwise constant
+  \param value map name of value
+
+  \return 1 on success
+  \return 0 on failure
+*/
+int Nviz::SetSurfaceShine(int id, bool map, const char *value)
+{
+    return SetSurfaceAttr(id, ATT_SHINE, map, value);
+}
+
+/*!
+  \brief Set surface emission
+
+  \param id surface id
+  \param map if true use map otherwise constant
+  \param value map name of value
+
+  \return 1 on success
+  \return 0 on failure
+*/
+int Nviz::SetSurfaceEmit(int id, bool map, const char *value)
+{
+    return SetSurfaceAttr(id, ATT_EMIT, map, value);
+}
+
+/*!
+  \brief Set surface attribute
+
+  \param id surface id
+  \param attr attribute desc
+  \param map if true use map otherwise constant
+  \param value map name of value
+
+  \return 1 on success
+  \return 0 on failure
+*/
+int Nviz::SetSurfaceAttr(int id, int attr, bool map, const char *value)
+{
+    int ret;
+
+    if (!GS_surf_exists(id)) {
+	return 0;
+    }
+
+    if (map) {
+	ret = Nviz_set_attr(id, MAP_OBJ_SURF, attr, MAP_ATT,
+			    value, -1.0,
+			    data);
+    }
+    else {
+	float val;
+	if (attr == ATT_COLOR) {
+	    val = Nviz_color_from_str(value);
+	}
+	else {
+	    val = atof(value);
+	}
+	ret = Nviz_set_attr(id, MAP_OBJ_SURF, attr, CONST_ATT,
+			    NULL, val,
+			    data);
+    }
+	
+    G_debug(1, "Nviz::SetSurfaceAttr(): id=%d, attr=%d, map=%d, value=%s",
+	    id, attr, map, value);
+
+    return ret;
+}
+
+/*!
+  \brief Unset surface mask
+
+  \param id surface id
+
+  \return 1 on success
+  \return 0 on failure
+*/
+
+int Nviz::UnsetSurfaceMask(int id)
+{
+    return UnsetSurfaceAttr(id, ATT_MASK);
+}
+
+/*!
+  \brief Unset surface transparency
+
+  \param id surface id
+
+  \return 1 on success
+  \return 0 on failure
+*/
+
+int Nviz::UnsetSurfaceTransp(int id)
+{
+    return UnsetSurfaceAttr(id, ATT_TRANSP);
+}
+
+/*!
+  \brief Unset surface emission
+
+  \param id surface id
+
+  \return 1 on success
+  \return 0 on failure
+*/
+
+int Nviz::UnsetSurfaceEmit(int id)
+{
+    return UnsetSurfaceAttr(id, ATT_EMIT);
+}
+
+/*!
+  \brief Unset surface attribute
+
+  \param id surface id
+  \param attr attribute descriptor
+
+  \return 1 on success
+  \return 0 on failure
+*/
+int Nviz::UnsetSurfaceAttr(int id, int attr)
+{
+    if (!GS_surf_exists(id)) {
+	return 0;
+    }
+
+    G_debug(1, "Nviz::UnsetSurfaceAttr(): id=%d, attr=%d",
+	    id, attr);
+    
+    return Nviz_unset_attr(id, MAP_OBJ_SURF, attr);
+}
+
+/*!
+  \brief Set surface resolution
+
+  \param id surface id
+  \param fine x/y fine resolution
+  \param coarse x/y coarse resolution
+
+  \return 0 on error
+  \return 1 on success
+*/
+int Nviz::SetSurfaceRes(int id, int fine, int coarse)
+{
+    G_debug(1, "Nviz::SetSurfaceRes(): id=%d, fine=%d, coarse=%d",
+	    id, fine, coarse);
+
+
+    if (id > 0) {
+	if (!GS_surf_exists(id)) {
+	    return 0;
+	}
+
+	if (GS_set_drawres(id, fine, fine, coarse, coarse) < 0) {
+	    return 0;
+	}
+    }
+    else {
+	GS_setall_drawres(fine, fine, coarse, coarse);
+    }
+
+    return 1;
+}
+
+/*!
+  \brief Set draw style
+
+  Draw styles:
+   - DM_GOURAUD
+   - DM_FLAT
+   - DM_FRINGE
+   - DM_WIRE
+   - DM_COL_WIRE
+   - DM_POLY
+   - DM_WIRE_POLY
+   - DM_GRID_WIRE
+   - DM_GRID_SURF
+
+  \param id surface id (<= 0 for all)
+  \param style draw style
+
+  \return 1 on success
+  \return 0 on error
+*/
+int Nviz::SetSurfaceStyle(int id, int style)
+{
+    G_debug(1, "Nviz::SetSurfaceStyle(): id=%d, style=%d",
+	    id, style);
+
+    if (id > 0) {
+	if (!GS_surf_exists(id)) {
+	    return 0;
+	}
+	
+	if (GS_set_drawmode(id, style) < 0) {
+	    return 0;
+	}
+	return 1;
+    }
+
+    if (GS_setall_drawmode(style) < 0) {
+	return 0;
+    }
+
+    return 1;
+}
+
+/*!
+  \brief Set color of wire
+
+  \todo all
+
+  \param surface id (< 0 for all)
+  \param color color string (R:G:B)
+
+  \return 1 on success
+  \return 0 on failure
+*/
+int Nviz::SetWireColor(int id, const char* color_str)
+{
+    int color;
+
+    G_debug(1, "Nviz::SetWireColor(): id=%d, color=%s",
+	    id, color_str);
+
+    color = Nviz_color_from_str(color_str);
+
+    if (id > 0) {
+	if (!GS_surf_exists(id)) {
+	    return 0;
+	}
+	GS_set_wire_color(id, color);
+    }
+    else {
+	int *surf_list, nsurfs, id;
+
+	surf_list = GS_get_surf_list(&nsurfs);
+	for (int i = 0; i < nsurfs; i++) {
+	    id = surf_list[i];
+	    GS_set_wire_color(id, color);
+	}
+
+	G_free(surf_list);
+    }
+
+    return 1;
+}
+
+/*!
+  \brief Get surface position
+
+  \param id surface id
+
+  \return x,y,z
+  \return zero-length vector on error
+*/
+std::vector<double> Nviz::GetSurfacePosition(int id)
+{
+    std::vector<double> vals;
+    float x, y, z;
+    if (!GS_surf_exists(id)) {
+	return vals;
+    }
+    
+    GS_get_trans(id, &x, &y, &z);
+    
+    G_debug(1, "Nviz::GetSurfacePosition(): id=%d, x=%f, y=%f, z=%f",
+	    id, x, y, z);
+
+
+    vals.push_back(double (x));
+    vals.push_back(double (y));
+    vals.push_back(double (z));
+
+    return vals;
+}
+
+/*!
+  \brief Set surface position
+
+  \param id surface id
+  \param x,y,z translation values
+
+  \return 1 on success
+  \return 0 on failure
+*/
+int Nviz::SetSurfacePosition(int id, float x, float y, float z)
+{
+    if (!GS_surf_exists(id)) {
+	return 0;
+    }
+    
+    G_debug(1, "Nviz::SetSurfacePosition(): id=%d, x=%f, y=%f, z=%f",
+	    id, x, y, z);
+
+    GS_set_trans(id, x, y, z);
+
+    return 1;
+}

Deleted: grass/branches/develbranch_6/gui/wxpython/nviz/vector.cpp
===================================================================
--- grass/trunk/gui/wxpython/nviz/vector.cpp	2008-08-06 07:27:17 UTC (rev 32555)
+++ grass/branches/develbranch_6/gui/wxpython/nviz/vector.cpp	2008-08-06 09:21:46 UTC (rev 32560)
@@ -1,178 +0,0 @@
-/**
-   \file vector.cpp
-   
-   \brief Experimental C++ wxWidgets Nviz prototype -- vector mode and attributes
-
-   Used by wxGUI Nviz extension.
-
-   Copyright: (C) 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)
-
-   \date 2008
-*/
-
-#include "nviz.h"
-
-/**
-   \brief Set mode of vector line overlay
-
-   \param id vector id
-   \param color_str color string
-   \param width line width
-   \param flat display flat or on surface
-
-   \return -1 vector set not found
-   \return -2 on failure
-   \return 1 on success
-*/
-int Nviz::SetVectorLineMode(int id, const char *color_str,
-			    int width, int flat)
-{
-    int color;
-
-    if(!GV_vect_exists(id))
-	return -1;
-
-    G_debug(1, "Nviz::SetVectorMode(): id=%d, color=%s, width=%d, flat=%d",
-	    id, color_str, width, flat);
-
-
-    color = Nviz_color_from_str(color_str);
-
-    /* use memory by default */
-    if (GV_set_vectmode(id, 1, color, width, flat) < 0)
-	return -2;
-    
-    return 1;
-}
-
-/**
-  \brief Set vector height above surface (lines)
-
-  \param id vector set id
-  \param height
-
-  \return -1 vector set not found
-  \return 1 on success
-*/
-int Nviz::SetVectorLineHeight(int id, float height)
-{
-    if(!GV_vect_exists(id))
-	return -1;
-
-    G_debug(1, "Nviz::SetVectorLineHeight(): id=%d, height=%f",
-	    id, height);
-
-    GV_set_trans(id, 0.0, 0.0, height);
-
-    return 1;
-}
-
-/**
-   \brief Set 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
-*/
-int Nviz::SetVectorLineSurface(int id, int surf_id)
-{
-    if (!GV_vect_exists(id))
-	return -1;
-    
-    if (!GS_surf_exists(surf_id))
-	return -2;
-
-    if (GV_select_surf(id, surf_id) < 0)
-	return -3;
-
-    return 1;
-}
-
-/**
-   \brief Set mode of vector point overlay
-
-   \param id vector id
-   \param color_str color string
-   \param width line width
-   \param flat
-
-   \return -1 vector set not found
-*/
-int Nviz::SetVectorPointMode(int id, const char *color_str,
-			     int width, float size, int marker)
-{
-    int color;
-
-    if(!GP_site_exists(id))
-	return -1;
-
-    G_debug(1, "Nviz::SetVectorPointMode(): id=%d, color=%s, "
-	    "width=%d, size=%f, marker=%d",
-	    id, color_str, width, size, marker);
-
-
-    color = Nviz_color_from_str(color_str);
-
-    if (GP_set_sitemode(id, ST_ATT_NONE,
-			color, width, size, marker) < 0)
-	return -2;
-    
-    return 1;
-}
-
-/**
-  \brief Set vector height above surface (points)
-
-  \param id vector set id
-  \param height
-
-  \return -1 vector set not found
-  \return 1 on success
-*/
-int Nviz::SetVectorPointHeight(int id, float height)
-{
-    if(!GP_site_exists(id))
-	return -1;
-
-    G_debug(1, "Nviz::SetVectorPointHeight(): id=%d, height=%f",
-	    id, height);
-
-    GP_set_trans(id, 0.0, 0.0, height);
-
-    return 1;
-}
-
-/**
-   \brief Set 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
-*/
-int Nviz::SetVectorPointSurface(int id, int surf_id)
-{
-    if (!GP_site_exists(id))
-	return -1;
-    
-    if (!GS_surf_exists(surf_id))
-	return -2;
-
-    if (GP_select_surf(id, surf_id) < 0)
-	return -3;
-
-    return 1;
-}

Copied: grass/branches/develbranch_6/gui/wxpython/nviz/vector.cpp (from rev 32558, grass/trunk/gui/wxpython/nviz/vector.cpp)
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/nviz/vector.cpp	                        (rev 0)
+++ grass/branches/develbranch_6/gui/wxpython/nviz/vector.cpp	2008-08-06 09:21:46 UTC (rev 32560)
@@ -0,0 +1,178 @@
+/**
+   \file vector.cpp
+   
+   \brief Experimental C++ wxWidgets Nviz prototype -- vector mode and attributes
+
+   Used by wxGUI Nviz extension.
+
+   Copyright: (C) 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)
+
+   \date 2008
+*/
+
+#include "nviz.h"
+
+/**
+   \brief Set mode of vector line overlay
+
+   \param id vector id
+   \param color_str color string
+   \param width line width
+   \param flat display flat or on surface
+
+   \return -1 vector set not found
+   \return -2 on failure
+   \return 1 on success
+*/
+int Nviz::SetVectorLineMode(int id, const char *color_str,
+			    int width, int flat)
+{
+    int color;
+
+    if(!GV_vect_exists(id))
+	return -1;
+
+    G_debug(1, "Nviz::SetVectorMode(): id=%d, color=%s, width=%d, flat=%d",
+	    id, color_str, width, flat);
+
+
+    color = Nviz_color_from_str(color_str);
+
+    /* use memory by default */
+    if (GV_set_vectmode(id, 1, color, width, flat) < 0)
+	return -2;
+    
+    return 1;
+}
+
+/**
+  \brief Set vector height above surface (lines)
+
+  \param id vector set id
+  \param height
+
+  \return -1 vector set not found
+  \return 1 on success
+*/
+int Nviz::SetVectorLineHeight(int id, float height)
+{
+    if(!GV_vect_exists(id))
+	return -1;
+
+    G_debug(1, "Nviz::SetVectorLineHeight(): id=%d, height=%f",
+	    id, height);
+
+    GV_set_trans(id, 0.0, 0.0, height);
+
+    return 1;
+}
+
+/**
+   \brief Set 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
+*/
+int Nviz::SetVectorLineSurface(int id, int surf_id)
+{
+    if (!GV_vect_exists(id))
+	return -1;
+    
+    if (!GS_surf_exists(surf_id))
+	return -2;
+
+    if (GV_select_surf(id, surf_id) < 0)
+	return -3;
+
+    return 1;
+}
+
+/**
+   \brief Set mode of vector point overlay
+
+   \param id vector id
+   \param color_str color string
+   \param width line width
+   \param flat
+
+   \return -1 vector set not found
+*/
+int Nviz::SetVectorPointMode(int id, const char *color_str,
+			     int width, float size, int marker)
+{
+    int color;
+
+    if(!GP_site_exists(id))
+	return -1;
+
+    G_debug(1, "Nviz::SetVectorPointMode(): id=%d, color=%s, "
+	    "width=%d, size=%f, marker=%d",
+	    id, color_str, width, size, marker);
+
+
+    color = Nviz_color_from_str(color_str);
+
+    if (GP_set_sitemode(id, ST_ATT_NONE,
+			color, width, size, marker) < 0)
+	return -2;
+    
+    return 1;
+}
+
+/**
+  \brief Set vector height above surface (points)
+
+  \param id vector set id
+  \param height
+
+  \return -1 vector set not found
+  \return 1 on success
+*/
+int Nviz::SetVectorPointHeight(int id, float height)
+{
+    if(!GP_site_exists(id))
+	return -1;
+
+    G_debug(1, "Nviz::SetVectorPointHeight(): id=%d, height=%f",
+	    id, height);
+
+    GP_set_trans(id, 0.0, 0.0, height);
+
+    return 1;
+}
+
+/**
+   \brief Set 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
+*/
+int Nviz::SetVectorPointSurface(int id, int surf_id)
+{
+    if (!GP_site_exists(id))
+	return -1;
+    
+    if (!GS_surf_exists(surf_id))
+	return -2;
+
+    if (GP_select_surf(id, surf_id) < 0)
+	return -3;
+
+    return 1;
+}

Copied: grass/branches/develbranch_6/gui/wxpython/scripts/Makefile (from rev 32556, grass/trunk/gui/wxpython/scripts/Makefile)
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/scripts/Makefile	                        (rev 0)
+++ grass/branches/develbranch_6/gui/wxpython/scripts/Makefile	2008-08-06 09:21:46 UTC (rev 32560)
@@ -0,0 +1,14 @@
+MODULE_TOPDIR = ../../..
+
+include $(MODULE_TOPDIR)/include/Make/Platform.make
+include $(MODULE_TOPDIR)/include/Make/Dir.make
+
+ETCDIR = $(ETC)/gui/scripts
+
+default: install_scripts
+
+install_scripts:
+	$(MKDIR) $(ETCDIR)
+	$(INSTALL) d.rast3d $(ETCDIR)/
+
+clean: cleansubdirs

Copied: grass/branches/develbranch_6/gui/wxpython/scripts/d.rast3d (from rev 32556, grass/trunk/gui/wxpython/scripts/d.rast3d)
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/scripts/d.rast3d	                        (rev 0)
+++ grass/branches/develbranch_6/gui/wxpython/scripts/d.rast3d	2008-08-06 09:21:46 UTC (rev 32560)
@@ -0,0 +1,40 @@
+#!/bin/sh
+#
+############################################################################
+#
+# MODULE:       d.rast3d
+#
+# AUTHOR(S):    Martin Landa <landa.martin gmail.com>
+#
+# PURPOSE:	Wrapper for wxGUI -- add 3d raster map layer into layer tree
+#
+# COPYRIGHT:	(C) 2008 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.
+#
+#############################################################################
+
+#%Module
+#%  description: Displays 3d raster data in the active frame on the graphics monitor.
+#%  keywords: display, raster3d, voxel
+#%End
+#%option
+#% key: input
+#% type: string
+#% gisprompt: old,grid3,3d-raster
+#% description: 3D raster map to be displayed
+#% required : yes
+#%END
+
+if  [ -z "$GISBASE" ] ; then
+ echo "You must be in GRASS GIS to run this program." >&2
+ exit 1
+fi
+
+if [ "$1" != "@ARGS_PARSED@" ] ; then
+  exec g.parser "$0" "$@"
+fi
+
+exit 0

Modified: grass/branches/develbranch_6/gui/wxpython/vdigit/Makefile
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/vdigit/Makefile	2008-08-06 09:11:06 UTC (rev 32559)
+++ grass/branches/develbranch_6/gui/wxpython/vdigit/Makefile	2008-08-06 09:21:46 UTC (rev 32560)
@@ -32,6 +32,8 @@
 $(LIB_NAME).py $(LIB_NAME)_wrap.cpp: $(LIB_NAME).i
 	$(SWIG) -c++ -python -shadow -o $(LIB_NAME)_wrap.cpp $<
 
+.NOTPARALLEL: $(LIB_NAME).py $(LIB_NAME)_wrap.cpp
+
 $(SHLIB): $(SHLIB_OBJS)
 ifeq ($(findstring darwin,$(ARCH)),darwin)
 	$(CXX) -o $@ $(LDFLAGS) $^ $(EXTRA_LIBS)

Modified: grass/branches/develbranch_6/gui/wxpython/wxgui.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/wxgui.py	2008-08-06 09:11:06 UTC (rev 32559)
+++ grass/branches/develbranch_6/gui/wxpython/wxgui.py	2008-08-06 09:21:46 UTC (rev 32560)
@@ -672,7 +672,8 @@
                                            lchecked=layer['checked'],
                                            lopacity=layer['opacity'],
                                            lcmd=layer['cmd'],
-                                           lgroup=layer['group'])
+                                           lgroup=layer['group'],
+                                           lnviz=layer['nviz'])
                 
                 # tag 'selected' added 2008/04
                 if layer.has_key('selected'):
@@ -693,7 +694,7 @@
                 maptree.Map.ReverseListOfLayers()
 
             for mdisp in mapdisplay:
-                mdisp.MapWindow.UpdateMap()
+                mdisp.MapWindow2D.UpdateMap()
 
             file.close()
         except IOError, err:
@@ -1128,7 +1129,7 @@
         # create layer tree (tree control for managing GIS layers)  and put on new notebook page
         self.curr_page.maptree = wxgui_utils.LayerTree(self.curr_page, id=wx.ID_ANY, pos=wx.DefaultPosition,
                                                        size=wx.DefaultSize, style=wx.TR_HAS_BUTTONS
-                                                       |wx.TR_LINES_AT_ROOT|wx.TR_EDIT_LABELS|wx.TR_HIDE_ROOT
+                                                       |wx.TR_LINES_AT_ROOT|wx.TR_HIDE_ROOT
                                                        |wx.TR_DEFAULT_STYLE|wx.NO_BORDER|wx.FULL_REPAINT_ON_RESIZE,
                                                        idx=self.disp_idx, gismgr=self, notebook=self.gm_cb,
                                                        auimgr=self._auimgr, showMapDisplay=show)
@@ -1183,6 +1184,12 @@
         rastmenu.AppendItem(addrast)
         self.Bind(wx.EVT_MENU, self.AddRaster, addrast)
 
+        if self.curr_page.maptree.mapdisplay.toolbars['nviz']:
+            addrast3d = wx.MenuItem(rastmenu, -1, Icons ["addrast3d"].GetLabel())
+            addrast3d.SetBitmap(Icons["addrast3d"].GetBitmap (self.iconsize))
+            rastmenu.AppendItem(addrast3d)
+            self.Bind(wx.EVT_MENU, self.AddRaster3d, addrast3d)
+
         addshaded = wx.MenuItem(rastmenu, -1, Icons ["addshaded"].GetLabel())
         addshaded.SetBitmap(Icons["addshaded"].GetBitmap (self.iconsize))
         rastmenu.AppendItem(addshaded)
@@ -1228,17 +1235,17 @@
         addvect = wx.MenuItem(vectmenu, -1, Icons["addvect"].GetLabel())
         addvect.SetBitmap(Icons["addvect"].GetBitmap(self.iconsize))
         vectmenu.AppendItem(addvect)
-        self.Bind(wx.EVT_MENU, self.addVector, addvect)
+        self.Bind(wx.EVT_MENU, self.AddVector, addvect)
 
         addtheme = wx.MenuItem(vectmenu, -1, Icons["addthematic"].GetLabel())
         addtheme.SetBitmap(Icons["addthematic"].GetBitmap(self.iconsize))
         vectmenu.AppendItem(addtheme)
-        self.Bind(wx.EVT_MENU, self.addThemeMap, addtheme)
+        self.Bind(wx.EVT_MENU, self.AddThemeMap, addtheme)
 
         addchart = wx.MenuItem(vectmenu, -1, Icons["addchart"].GetLabel())
         addchart.SetBitmap(Icons["addchart"].GetBitmap(self.iconsize))
         vectmenu.AppendItem(addchart)
-        self.Bind(wx.EVT_MENU, self.addThemeChart, addchart)
+        self.Bind(wx.EVT_MENU, self.AddThemeChart, addchart)
 
         # Popup the menu.  If an item is selected then its handler
         # will be called before PopupMenu returns.
@@ -1284,6 +1291,10 @@
         self.notebook.SetSelection(0)
         self.curr_page.maptree.AddLayer('raster')
 
+    def AddRaster3d(self, event):
+        self.notebook.SetSelection(0)
+        self.curr_page.maptree.AddLayer('3d-raster')
+
     def AddRGB(self, event):
         """Add RGB layer"""
         self.notebook.SetSelection(0)
@@ -1309,17 +1320,17 @@
         self.notebook.SetSelection(0)
         self.curr_page.maptree.AddLayer('rastnum')
 
-    def addVector(self, event):
+    def AddVector(self, event):
         """Add vector layer"""
         self.notebook.SetSelection(0)
         self.curr_page.maptree.AddLayer('vector')
 
-    def addThemeMap(self, event):
+    def AddThemeMap(self, event):
         """Add thematic map layer"""
         self.notebook.SetSelection(0)
         self.curr_page.maptree.AddLayer('thememap')
 
-    def addThemeChart(self, event):
+    def AddThemeChart(self, event):
         """Add thematic chart layer"""
         self.notebook.SetSelection(0)
         self.curr_page.maptree.AddLayer('themechart')

Modified: grass/branches/develbranch_6/gui/wxpython/xml/grass-gxw.dtd
===================================================================
(Binary files differ)

Modified: grass/branches/develbranch_6/include/Make/Grass.make.in
===================================================================
--- grass/branches/develbranch_6/include/Make/Grass.make.in	2008-08-06 09:11:06 UTC (rev 32559)
+++ grass/branches/develbranch_6/include/Make/Grass.make.in	2008-08-06 09:21:46 UTC (rev 32560)
@@ -144,6 +144,7 @@
 
 # NVIZ related
 OGSF_LIBNAME          = grass_ogsf
+NVIZ_LIBNAME          = grass_nviz
 
 # triangulation libraries
 SOS_LIBNAME           = grass_sos
@@ -247,6 +248,7 @@
 
 # NVIZ related
 OGSFLIB       = -l$(OGSF_LIBNAME) $(BITMAPLIB) $(G3DLIB) $(GISLIB) $(SITESLIB) $(VECTRLIB) 
+NVIZLIB       = -l$(NVIZ_LIBNAME) $(BITMAPLIB) $(G3DLIB) $(GISLIB) $(VECTRLIB) 
 
 # triangulation libraries
 SOSLIB        = -l$(SOS_LIBNAME)
@@ -342,6 +344,7 @@
 
 # NVIZ related
 OGSFDEP      = $(ARCH_LIBDIR)/$(LIB_PREFIX)$(OGSF_LIBNAME)$(LIB_SUFFIX)
+NVIZDEP      = $(ARCH_LIBDIR)/$(LIB_PREFIX)$(NVIZ_LIBNAME)$(LIB_SUFFIX)
 
 # triangulation libraries
 SOSDEP      = $(ARCH_LIBDIR)/$(LIB_PREFIX)$(SOS_LIBNAME)$(LIB_SUFFIX)

Copied: grass/branches/develbranch_6/include/nviz.h (from rev 32556, grass/trunk/include/nviz.h)
===================================================================
--- grass/branches/develbranch_6/include/nviz.h	                        (rev 0)
+++ grass/branches/develbranch_6/include/nviz.h	2008-08-06 09:21:46 UTC (rev 32560)
@@ -0,0 +1,194 @@
+#ifndef GRASS_NVIZ_H
+#define GRASS_NVIZ_H
+
+#include <grass/config.h>
+
+/*** Windows headers ***/
+#if defined(OPENGL_WINDOWS)
+#  define WIN32_LEAN_AND_MEAN
+#  include <windows.h>
+#  undef WIN32_LEAN_AND_MEAN
+#  include <winnt.h>
+
+/*** X Window System headers ***/
+#elif defined(OPENGL_X11)
+#  include <X11/Xlib.h>
+#  include <X11/Xutil.h>
+#  include <X11/Xatom.h>	/* for XA_RGB_DEFAULT_MAP atom */
+#  if defined(__vms)
+#    include <X11/StdCmap.h>	/* for XmuLookupStandardColormap */
+#  else
+#    include <X11/Xmu/StdCmap.h>	/* for XmuLookupStandardColormap */
+#  endif
+#  include <GL/glx.h>
+
+/*** Mac headers ***/
+#elif defined(OPENGL_AQUA)
+#  define Cursor QDCursor
+#  include <AGL/agl.h>
+#  undef Cursor
+#  include <ApplicationServices/ApplicationServices.h>
+
+#else /* make sure only one platform defined */
+#  error Unsupported platform, or confused platform defines...
+#endif
+
+#include <grass/gsurf.h>
+#include <grass/gstypes.h>
+
+#define MAP_OBJ_UNDEFINED 0
+#define MAP_OBJ_SURF 1
+#define MAP_OBJ_VOL 2
+#define MAP_OBJ_VECT 3
+#define MAP_OBJ_SITE 4
+
+#define DRAW_COARSE 0
+#define DRAW_FINE 1
+#define DRAW_BOTH 2
+
+#define RANGE (5 * GS_UNIT_SIZE)
+#define RANGE_OFFSET (2 * GS_UNIT_SIZE)
+#define ZRANGE (3 * GS_UNIT_SIZE)
+#define ZRANGE_OFFSET (1 * GS_UNIT_SIZE)
+
+#define DEFAULT_SURF_COLOR 0x33BBFF
+
+#define RED_MASK 0x000000FF
+#define GRN_MASK 0x0000FF00
+#define BLU_MASK 0x00FF0000
+
+#define FORMAT_PPM 1
+#define FORMAT_TIF 2
+
+/* data structures */
+typedef struct
+{
+    int id;
+    float brt;
+    float r, g, b;
+    float ar, ag, ab;		/* ambient rgb */
+    float x, y, z, w;		/* position */
+} light_data;
+
+typedef struct
+{
+    /* ranges */
+    float zrange, xyrange;
+
+    /* cplanes */
+    int num_cplanes;
+    int cur_cplane, cp_on[MAX_CPLANES];
+    float cp_trans[MAX_CPLANES][3];
+    float cp_rot[MAX_CPLANES][3];
+
+    /* light */
+    light_data light[MAX_LIGHTS];
+
+    /* background color */
+    int bgcolor;
+
+} nv_data;
+
+/* The following structure is used to associate client data with surfaces.
+ * We do this so that we don't have to rely on the surface ID (which is libal to change
+ * between subsequent executions of nviz) when saving set-up info to files.
+ */
+
+typedef struct
+{
+    /* We use logical names to assign textual names to map objects.
+       When Nviz needs to refer to a map object it uses the logical name
+       rather than the map ID.  By setting appropriate logical names, we
+       can reuse names inbetween executions of Nviz.  The Nviz library
+       also provides a mechanism for aliasing between logical names.
+       Thus several logical names may refer to the same map object.
+       Aliases are meant to support the case in which two logical names
+       happen to be the same.  The Nviz library automatically assigns
+       logical names uniquely if they are not specified in the creation
+       of a map object.  When loading a saved file containing several map
+       objects, it is expected that the map 0bjects will be aliased to
+       their previous names.  This ensures that old scripts will work.
+     */
+
+    char *logical_name;
+
+} nv_clientdata;
+
+struct render_window
+{
+#if defined(OPENGL_X11)
+    Display *displayId;		/* display connection */
+    GLXContext contextId;	/* GLX rendering context */
+    GLXPixmap windowId;
+    Pixmap pixmap;
+#elif defined(OPENGL_AQUA)
+    AGLPixelFmtID pixelFmtId;
+    AGLContext contextId;
+    AGLPixmap windowId;
+    GWorldPtr pixmap;
+#elif defined(OPENGL_WINDOWS)
+    HDC displayId;		/* display context */
+    HGLRC contextId;		/* rendering context */
+    HBITMAP bitmapId;
+#endif
+};
+
+/* change_view.c */
+int Nviz_resize_window(int, int);
+int Nviz_update_ranges(nv_data *);
+int Nviz_set_viewpoint_position(nv_data *, float, float);
+int Nviz_set_viewpoint_height(nv_data *, float);
+int Nviz_set_viewpoint_persp(nv_data *, int);
+int Nviz_set_viewpoint_twist(nv_data *, int);
+int Nviz_change_exag(nv_data *, float);
+
+/* cplanes_obj.c */
+int Nviz_new_cplane(nv_data *, int);
+int Nviz_off_cplane(nv_data *, int);
+int Nviz_draw_cplane(nv_data *, int, int);
+
+/* draw.c */
+int Nviz_draw_all_surf(nv_data *);
+int Nviz_draw_all_vect(nv_data *);
+int Nviz_draw_all_site(nv_data *);
+int Nviz_draw_all_vol(nv_data *);
+int Nviz_draw_all(nv_data *);
+int Nviz_draw_quick(nv_data *, int, int);
+
+/* exag.c */
+int Nviz_get_exag_height(float *, float *, float *);
+float Nviz_get_exag();
+
+/* lights.c */
+int Nviz_set_light_position(nv_data *, int, float, float, float, float);
+int Nviz_set_light_bright(nv_data *, int, float);
+int Nviz_set_light_color(nv_data *, int, float, float, float);
+int Nviz_set_light_ambient(nv_data *, int, float, float, float);
+int Nviz_init_light(nv_data *, int);
+int Nviz_new_light(nv_data *);
+
+/* map_obj.c */
+int Nviz_new_map_obj(int, const char *, float, nv_data *);
+int Nviz_set_attr(int, int, int, int, const char *, float, nv_data *);
+void Nviz_set_surface_attr_default();
+int Nviz_set_vpoint_attr_default();
+int Nviz_unset_attr(int, int, int);
+
+/* nviz.c */
+void Nviz_init_data(nv_data *);
+void Nviz_set_bgcolor(nv_data *, int);
+int Nviz_color_from_str(const char *);
+
+/* position.c */
+void Nviz_init_view();
+int Nviz_set_focus_state(int);
+int Nviz_set_focus_map(int, int);
+
+/* render.c */
+struct render_window *Nviz_new_render_window();
+void Nviz_init_render_window(struct render_window *);
+void Nviz_destroy_render_window(struct render_window *);
+int Nviz_create_render_window(struct render_window *, void *, int, int);
+int Nviz_make_current_render_window(const struct render_window *);
+
+#endif /* GRASS_NVIZ_H */

Modified: grass/branches/develbranch_6/lib/Makefile
===================================================================
--- grass/branches/develbranch_6/lib/Makefile	2008-08-06 09:11:06 UTC (rev 32559)
+++ grass/branches/develbranch_6/lib/Makefile	2008-08-06 09:21:46 UTC (rev 32560)
@@ -39,7 +39,9 @@
 
 include $(MODULE_TOPDIR)/include/Make/Platform.make
 
-OPENGLBASED = ogsf
+OPENGLBASED = \
+	ogsf \
+	nviz
 
 #compile if OPENGLBASED present:
 ifneq ($(strip $(OPENGLLIB)),)

Modified: grass/branches/develbranch_6/lib/grasslib.dox
===================================================================
--- grass/branches/develbranch_6/lib/grasslib.dox	2008-08-06 09:11:06 UTC (rev 32559)
+++ grass/branches/develbranch_6/lib/grasslib.dox	2008-08-06 09:21:46 UTC (rev 32560)
@@ -95,6 +95,7 @@
 <ul>
 <li>vedit: \ref Vedit_Library - %vector editing
 </ul>
+<li>nviz:       \ref nvizlib (used by wxGUI Nviz extension and CLI-based Nviz module)
 </ul>
 <!--<li>image3:	extra imagery library (mainly still unused) - \ref image3lib-->
 <!--<li>D:		display library - \ref d_displaylib-->

Copied: grass/branches/develbranch_6/lib/nviz (from rev 32555, grass/trunk/lib/nviz)

Modified: grass/branches/develbranch_6/visualization/Makefile
===================================================================
--- grass/branches/develbranch_6/visualization/Makefile	2008-08-06 09:11:06 UTC (rev 32559)
+++ grass/branches/develbranch_6/visualization/Makefile	2008-08-06 09:21:46 UTC (rev 32560)
@@ -11,6 +11,11 @@
 endif
 endif
 
+#compile if OpenGL present
+ifneq ($(strip $(OPENGLLIB)),)
+    SUBDIRS += nviz2
+endif
+
 #compile if Motif present:
 ifneq ($(strip $(XMLIB)),)
     SUBDIRS += xganim

Copied: grass/branches/develbranch_6/visualization/nviz2 (from rev 32555, grass/trunk/visualization/nviz2)



More information about the grass-commit mailing list