""" @package nviz.py @brief 2.5/3D visialization mode for Map Display Window List of classes: - GLWindow - NvizToolWindow - ViewPositionWindow - IsoSurfList (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. @author Martin Landa (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 grass7_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', '3d-raster'): 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, -1) elif self.render['quick'] is True: # quick mode = wxnviz.DRAW_QUICK_SURFACE | wxnviz.DRAW_QUICK_VOLUME if self.render['vlines']: mode |= wxnviz.DRAW_QUICK_VLINES if self.render['vpoints']: mode |= wxnviz.DRAW_QUICK_VPOINTS self.nvizClass.Draw(True, mode) 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', '3d-raster'): 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) elif type == '3d-raster': self.LoadRaster3d(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']) elif type == '3d-raster': data[nvizType] = {} for sec in ('attribute', 'draw', 'position', 'isosurface', 'slice'): data[nvizType][sec] = {} # reset to default properties self.SetVolumeDefaultProp(data[nvizType]) 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 in ('raster', '3d-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 2d raster map and set surface attributes @param layer item """ return self._loadRaster(item) def LoadRaster3d(self, item): """Load 3d raster map and set surface attributes @param layer item """ return self._loadRaster(item) def _loadRaster(self, item): """Load 2d/3d raster map and set its attributes @param layer item """ layer = self.tree.GetPyData(item)[0]['maplayer'] if layer.type not in ('raster', '3d-raster'): return if layer.type == 'raster': id = self.nvizClass.LoadSurface(str(layer.name), None, None) nvizType = 'surface' errorMsg = _("Loading raster map") elif layer.type == '3d-raster': id = self.nvizClass.LoadVolume(str(layer.name), None, None) nvizType = 'volume' errorMsg = _("Loading 3d raster map") else: id = -1 if id < 0: if layer.type in ('raster', '3d-raster'): print >> sys.stderr, "Nviz:" + "%s <%s> %s" % (errorMsg, layer.name, _("failed")) else: print >> sys.stderr, "Nviz:" + _("Unsupported layer type '%s'") % layer.type self.layers[layer.type]['name'].append(layer.name) self.layers[layer.type]['id'].append(id) # set default/workspace layer properties data = self.SetLayerData(item, id, nvizType) print data # update properties self.UpdateLayerProperties(item) # update tools window if hasattr(self.parent, "nvizToolWin") and \ item == self.GetSelectedLayer(type='item'): toolWin = self.parent.nvizToolWin if layer.type == 'raster': win = toolWin.FindWindowById( \ toolWin.win['vector']['lines']['surface']) win.SetItems(self.layers[layer.type]['name']) toolWin.UpdatePage(nvizType) toolWin.SetPage(nvizType) return id def UnloadRaster(self, item): """Unload 2d raster map @param layer item """ return self._unloadRaster(item) def UnloadRaster3d(self, item): """Unload 3d raster map @param layer item """ return self._unloadRaster(item) def _unloadRaster(self, item): """Unload 2d/3d raster map @param item layer item """ layer = self.tree.GetPyData(item)[0]['maplayer'] if layer.type not in ('raster', '3d-raster'): return data = self.tree.GetPyData(item)[0]['nviz'] if layer.type == 'raster': nvizType = 'surface' unloadFn = self.nvizClass.UnloadSurface errorMsg = _("Unable to unload raster map") successMsg = _("Raster map") else: nvizType = 'volume' unloadFn = self.nvizClass.UnloadVolume errorMsg = _("Unable to unload 3d raster map") successMsg = _("3d raster map") id = data[nvizType]['object']['id'] if unloadFn(id) == 0: print >> sys.stderr, "Nviz:" + "%s <%s>" % (errorMsg, layer.name) else: print "Nviz:" + "%s <%s> %s" % (successMsg, layer.name, _("unloaded successfully")) data[nvizType].pop('object') idx = self.layers[layer.type]['id'].index(id) del self.layers[layer.type]['name'][idx] del self.layers[layer.type]['id'][idx] # update tools window if hasattr(self.parent, "nvizToolWin") and \ layer.type == 'raster': toolWin = self.parent.nvizToolWin win = toolWin.FindWindowById( \ toolWin.win['vector']['lines']['surface']) win.SetItems(self.layers[layer.type]['name']) # remove surface page if toolWin.notebook.GetSelection() == toolWin.page[nvizType]['id']: toolWin.notebook.RemovePage(toolWin.page[nvizType]['id']) toolWin.page[nvizType]['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 # for attrb in ('shine', ): data['attribute'][attrb] = {} for key, value in UserSettings.Get(group='nviz', key='volume', subkey=attrb).iteritems(): data['attribute'][attrb][key] = value self.update.append('surface:attribute:%s' % value)# # # draw # data['draw']['all'] = False # apply only for current surface for control, value in UserSettings.Get(group='nviz', key='surface', subkey='draw').iteritems(): if control[:3] == 'res': if 'surface:draw:%s' % 'resolution' not in self.update: self.update.append('surface:draw:%s' % 'resolution') 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 } 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, } 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 SetVolumeDefaultProp(self, data): """Set default volume properties""" # # draw # data['draw']['all'] = False # apply only for current volume set for control, value in UserSettings.Get(group='nviz', key='volume', subkey='draw').iteritems(): if 'volume:draw:%s' % control not in self.update: self.update.append('volume:draw:%s' % control) data['draw'][control] = { 'value' : value } # # isosurface attributes # for attrb in ('shine', ): data['attribute'][attrb] = {} for key, value in UserSettings.Get(group='nviz', key='volume', subkey=attrb).iteritems(): data['attribute'][attrb][key] = value ### self.update.append('volume:attribute:%s' % value) 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']['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']['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']['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() # volume page self.__createVolumePage() # 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) # type self.win['surface']['attr'] = {} row = 0 for code, attrb in (('topo', _("Topography")), ('color', _("Color")), ('mask', _("Mask")), ('transp', _("Transparency")), ('shine', _("Shininess")), ('emit', _("Emission"))): self.win['surface'][code] = {} gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY, label=attrb + ':'), pos=(row, 0), flag=wx.ALIGN_CENTER_VERTICAL) use = wx.Choice (parent=panel, id=wx.ID_ANY, size=(100, -1), choices = [_("map")]) if code not in ('topo', 'color', 'shine'): use.Insert(item=_("unset"), pos=0) self.win['surface'][code]['required'] = False else: self.win['surface'][code]['required'] = True if code != 'mask': use.Append(item=_('constant')) self.win['surface'][code]['use'] = use.GetId() use.Bind(wx.EVT_CHOICE, self.OnMapObjUse) gridSizer.Add(item=use, flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 1)) map = gselect.Select(parent=panel, id=wx.ID_ANY, # size=globalvar.DIALOG_GSELECT_SIZE, size=(200, -1), type="raster") self.win['surface'][code]['map'] = map.GetId() - 1 # FIXME map.Bind(wx.EVT_TEXT, self.OnSurfaceMap) # changing map topography not allowed if code == 'topo': map.Enable(False) gridSizer.Add(item=map, flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 2)) if code == 'color': value = csel.ColourSelect(panel, id=wx.ID_ANY, colour=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.SetMapObjUseMap(nvizType='surface', attrb=code) # -> enable map / disable constant row += 1 boxSizer.Add(item=gridSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=3) pageSizer.Add(item=boxSizer, proportion=0, flag=wx.EXPAND | wx.ALL, border=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 __createVolumePage(self): """Create view settings page""" panel = wx.Panel(parent=self.notebook, id=wx.ID_ANY) self.page['volume'] = {} self.page['volume']['id'] = -1 self.page['volume']['panel'] = panel.GetId() pageSizer = wx.BoxSizer(wx.VERTICAL) self.win['volume'] = {} # # draw # self.win['volume']['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=(150, -1), choices = [_("isosurfaces"), _("slides")]) mode.SetSelection(0) mode.SetName("selection") # mode.Bind(wx.EVT_CHOICE, self.OnSurfaceMode) self.win['volume']['draw']['mode'] = mode.GetId() gridSizer.Add(item=mode, flag=wx.ALIGN_CENTER_VERTICAL, pos=(0, 1)) # shading gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("Shading:")), pos=(0, 2), flag=wx.ALIGN_CENTER_VERTICAL) shade = wx.Choice (parent=panel, id=wx.ID_ANY, size=(100, -1), choices = [_("flat"), _("gouraud")]) shade.SetName("selection") self.win['volume']['draw']['shading'] = shade.GetId() # shade.Bind(wx.EVT_CHOICE, self.OnSurfaceMode) gridSizer.Add(item=shade, flag=wx.ALIGN_CENTER_VERTICAL, pos=(0, 3)) # resolution (mode) gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("Resolution:")), pos=(0, 4), flag=wx.ALIGN_CENTER_VERTICAL) resol = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1), initial=1, min=1, max=100) resol.SetName("value") self.win['volume']['draw']['resolution'] = resol.GetId() # resC.Bind(wx.EVT_SPINCTRL, self.OnSurfaceResolution) gridSizer.Add(item=resol, pos=(0, 5)) 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) # # manage isosurfaces # box = wx.StaticBox (parent=panel, id=wx.ID_ANY, label=" %s " % (_("List of isosurfaces"))) boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL) gridSizer = wx.GridBagSizer(vgap=3, hgap=3) # list isolevel = IsoSurfList(parent=panel, win=self.win['volume'], size=(300, 150)) self.win['volume']['isosurfs'] = isolevel.GetId() gridSizer.Add(item=isolevel, pos=(0, 0), span=(4, 1)) # buttons (add, delete, move up, move down) btnAdd = wx.Button(parent=panel, id=wx.ID_ADD) self.win['volume']['btnIsoSurfAdd'] = btnAdd.GetId() btnAdd.Bind(wx.EVT_BUTTON, self.OnVolumeIsosurfAdd) gridSizer.Add(item=btnAdd, pos=(0, 1)) btnDelete = wx.Button(parent=panel, id=wx.ID_DELETE) self.win['volume']['btnIsosurfDelete'] = btnDelete.GetId() btnDelete.Bind(wx.EVT_BUTTON, self.OnVolumeIsosurfDelete) btnDelete.Enable(False) gridSizer.Add(item=btnDelete, pos=(1, 1)) btnMoveUp = wx.Button(parent=panel, id=wx.ID_UP) self.win['volume']['btnIsosurfMoveUp'] = btnMoveUp.GetId() btnMoveUp.Bind(wx.EVT_BUTTON, self.OnVolumeIsosurfMoveUp) btnMoveUp.Enable(False) gridSizer.Add(item=btnMoveUp, pos=(2, 1)) btnMoveDown = wx.Button(parent=panel, id=wx.ID_DOWN) self.win['volume']['btnIsosurfMoveDown'] = btnMoveDown.GetId() btnMoveDown.Bind(wx.EVT_BUTTON, self.OnVolumeIsosurfMoveDown) btnMoveDown.Enable(False) gridSizer.Add(item=btnMoveDown, pos=(3, 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) # # isosurface attributes # box = wx.StaticBox (parent=panel, id=wx.ID_ANY, label=" %s " % (_("Isosurface attributes"))) boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL) gridSizer = wx.GridBagSizer(vgap=3, hgap=3) self.win['volume']['attr'] = {} row = 0 for code, attrb in (('topo', _("Topography level")), ('color', _("Color")), ('mask', _("Mask")), ('transp', _("Transparency")), ('shine', _("Shininess")), ('emit', _("Emission"))): self.win['volume'][code] = {} # label gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY, label=attrb + ':'), pos=(row, 0), flag=wx.ALIGN_CENTER_VERTICAL) if code != 'topo': use = wx.Choice (parent=panel, id=wx.ID_ANY, size=(100, -1), choices = [_("map")]) else: use = None # check for required properties if code not in ('topo', 'color'): use.Insert(item=_("unset"), pos=0) self.win['volume'][code]['required'] = False else: self.win['volume'][code]['required'] = True if use and code != 'mask': use.Append(item=_('constant')) if use: self.win['volume'][code]['use'] = use.GetId() use.Bind(wx.EVT_CHOICE, self.OnMapObjUse) gridSizer.Add(item=use, flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 1)) if code != 'topo': map = gselect.Select(parent=panel, id=wx.ID_ANY, # size=globalvar.DIALOG_GSELECT_SIZE, size=(200, -1), type="grid3") self.win['volume'][code]['map'] = map.GetId() - 1 # FIXME map.Bind(wx.EVT_TEXT, self.OnSurfaceMap) gridSizer.Add(item=map, flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 2)) else: map = None if code == 'color': value = csel.ColourSelect(panel, id=wx.ID_ANY, colour=UserSettings.Get(group='nviz', key='volume', subkey=['color', 'value'])) value.Bind(csel.EVT_COLOURSELECT, self.OnSurfaceMap) elif code == 'mask': value = None else: if code == 'topo': size = (200, -1) else: size = (65, -1) value = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=size, initial=0) if code == 'topo': value.SetRange(minVal=-1e9, maxVal=1e9) elif code in ('shine', 'transp', 'emit'): value.SetRange(minVal=0, maxVal=255) else: value.SetRange(minVal=0, maxVal=100) value.Bind(wx.EVT_TEXT, self.OnSurfaceMap) if value: self.win['volume'][code]['const'] = value.GetId() if code == 'topo': gridSizer.Add(item=value, flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 2)) else: value.Enable(False) gridSizer.Add(item=value, flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 3)) else: self.win['volume'][code]['const'] = None if code != 'topo': self.SetMapObjUseMap(nvizType='volume', attrb=code) # -> enable map / disable constant row += 1 boxSizer.Add(item=gridSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=3) 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=1e6) 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 OnMapObjUse(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: attrb = self.__GetWindowName(self.win['volume'], event.GetId()) nvizType = 'volume' else: nvizType = 'surface' selection = event.GetSelection() if self.win[nvizType][attrb]['required']: # no 'unset' selection += 1 if selection == 0: # unset useMap = None value = '' elif selection == 1: # map useMap = True value = self.FindWindowById(self.win[nvizType][attrb]['map']).GetValue() elif selection == 2: # constant useMap = False if attrb == 'color': value = self.FindWindowById(self.win[nvizType][attrb]['const']).GetColour() value = str(value[0]) + ':' + str(value[1]) + ':' + str(value[2]) else: value = self.FindWindowById(self.win[nvizType][attrb]['const']).GetValue() self.SetMapObjUseMap(nvizType=nvizType, attrb=attrb, map=useMap) self.mapWindow.update.append('surface:attribute:%s' % attrb) data = self.mapWindow.GetSelectedLayer(type='nviz') data[nvizType]['attribute'][attrb] = { 'map' : useMap, 'value' : str(value), } self.mapWindow.UpdateLayerProperties() if self.parent.autoRender.IsChecked(): self.mapWindow.Refresh(False) def SetMapObjUseMap(self, nvizType, 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 # not sure why, but here must be disabled both ids, should be fixed! self.FindWindowById(self.win[nvizType][attrb]['map'] + 1).Enable(True) if self.win[nvizType][attrb]['const']: self.FindWindowById(self.win[nvizType][attrb]['const']).Enable(False) self.FindWindowById(self.win[nvizType][attrb]['use']).SetSelection(1 + incSel) elif map is False: # const self.FindWindowById(self.win[nvizType][attrb]['map'] + 1).Enable(False) if self.win[nvizType][attrb]['const']: self.FindWindowById(self.win[nvizType][attrb]['const']).Enable(True) self.FindWindowById(self.win[nvizType][attrb]['use']).SetSelection(2 + incSel) else: # unset self.FindWindowById(self.win[nvizType][attrb]['map'] + 1).Enable(False) if self.win[nvizType][attrb]['const']: self.FindWindowById(self.win[nvizType][attrb]['const']).Enable(False) self.FindWindowById(self.win[nvizType][attrb]['use']).SetSelection(0) def OnSurfaceMap(self, event): """Set surface attribute""" if 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): """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 } self.mapWindow.UpdateLayerProperties() def SetSurfaceMode(self): """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, '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 } 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 OnVolumeIsosurfAdd(self, event): """Add new isosurface to the list""" list = self.FindWindowById(self.win['volume']['isosurfs']) level = self.FindWindowById(self.win['volume']['topo']['const']).GetValue() list.Append("%s %s" % (_("Level"), str(level))) list.Check(list.GetCount()-1) list.SetSelection(list.GetCount()-1) # add isosurface layer = self.mapWindow.GetSelectedLayer() data = self.mapWindow.GetSelectedLayer(type='nviz')['volume'] id = data['object']['id'] self.mapWindow.nvizClass.AddIsosurface(id, level) self.mapWindow.nvizClass.SetIsosurfaceColor(id, 0, True, str(layer.name)) # disable add button on max if list.GetCount() >= wxnviz.MAX_ISOSURFS: self.FindWindowById(event.GetId()).Enable(False) # disable 'move-down' moveDown = self.parent.FindWindowById(self.win['volume']['btnIsosurfMoveDown']) if not moveDown.IsEnabled(): moveDown.Enable(False) # enable delete & move buttons btnDelete = self.FindWindowById(self.win['volume']['btnIsosurfDelete']) if not btnDelete.IsEnabled(): btnDelete.Enable(True) if list.GetCount() > 1: btnMoveUp = self.FindWindowById(self.win['volume']['btnIsosurfMoveUp']) if not btnMoveUp.IsEnabled(): btnMoveUp.Enable(True) if self.parent.autoRender.IsChecked(): self.mapWindow.Refresh(False) event.Skip() def OnVolumeIsosurfDelete(self, event): """Remove isosurface from list""" list = self.FindWindowById(self.win['volume']['isosurfs']) btn = self.FindWindowById(event.GetId()) # remove item from list isosurfId = list.GetSelection() list.Delete(isosurfId) # select last item if list.GetCount() > 0: list.SetSelection(list.GetCount()-1) # delete isosurface layer = self.mapWindow.GetSelectedLayer() data = self.mapWindow.GetSelectedLayer(type='nviz')['volume'] id = data['object']['id'] self.mapWindow.nvizClass.DeleteIsosurface(id, isosurfId) # update buttons if list.GetCount() < 1: btn.Enable(False) elif list.GetCount() < 2: self.FindWindowById(self.win['volume']['btnIsosurfMoveUp']).Enable(False) self.FindWindowById(self.win['volume']['btnIsosurfMoveDown']).Enable(False) if self.parent.autoRender.IsChecked(): self.mapWindow.Refresh(False) event.Skip() def OnVolumeIsosurfMoveUp(self, event): """Move isosurface up in the list""" pass def OnVolumeIsosurfMoveDown(self, event): """Move isosurface dowm in the list""" pass 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(1, max) self.FindWindowById(self.win['view']['height'][control]).SetRange(hmin, hmax) elif pageId == 'surface': if self.notebook.GetSelection() != self.page['surface']['id']: for page in ('vector', 'volume'): if self.page[page]['id'] > -1: self.notebook.RemovePage(self.page[page]['id']) self.page[page]['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']: for page in ('surface', 'volume'): if self.page[page]['id'] > -1: self.notebook.RemovePage(self.page[page]['id']) self.page[page]['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']) elif pageId == 'volume': if self.notebook.GetSelection() != self.page['volume']['id']: for page in ('surface', 'vector'): if self.page[page]['id'] > -1: self.notebook.RemovePage(self.page[page]['id']) self.page[page]['id'] = -1 self.page['volume']['id'] = 1 self.page['settings']['id'] = 2 panel = wx.FindWindowById(self.page['volume']['panel']) self.notebook.InsertPage(n=self.page['volume']['id'], page=panel, text=" %s " % _("Layer properties"), select=True) self.UpdateVolumePage(layer, data['volume']) 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.SetMapObjUseMap(nvizType='surface', attrb=attr, map=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.SetMapObjUseMap(nvizType='surface', attrb=attr, map=data['attribute']['color']['map']) self.SetMapObjUseMap(nvizType='surface', attrb='shine', map=data['attribute']['shine']['map']) value = data['attribute']['shine']['value'] if data['attribute']['shine']['map']: self.FindWindowById(self.win['surface']['shine']['map']).SetValue(value) else: self.FindWindowById(self.win['surface']['shine']['const']).SetValue(value) # # draw # for control, dict in data['draw'].iteritems(): if control == 'all': # skip 'all' property continue 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 UpdateVolumePage(self, layer, data): """Update volume layer properties page""" # # draw # for control, dict in data['draw'].iteritems(): if control == 'all': # skip 'all' property continue win = self.FindWindowById(self.win['volume']['draw'][control]) if win.GetName() == "selection": win.SetSelection(dict['value']) else: win.SetValue(dict['value']) # # isosurface attributes # for attr in ('color', ): # required if layer and layer.type == '3d-raster': self.FindWindowById(self.win['volume'][attr]['map']).SetValue(layer.name) else: self.FindWindowById(self.win['volume'][attr]['map']).SetValue('') self.SetMapObjUseMap(nvizType='volume', attrb=attr, map=True) # -> map if data['attribute'].has_key('color'): value = data['attribute']['color']['value'] if data['attribute']['color']['map']: self.FindWindowById(self.win['volume']['color']['map']).SetValue(value) else: # constant color = map(int, value.split(':')) self.FindWindowById(self.win['volume']['color']['const']).SetColour(color) self.SetMapObjUseMap(nvizType='volume', attrb=attr, map=data['attribute']['color']['map']) self.SetMapObjUseMap(nvizType='volume', attrb='shine', map=data['attribute']['shine']['map']) value = data['attribute']['shine']['value'] if data['attribute']['shine']['map']: self.FindWindowById(self.win['volume']['shine']['map']).SetValue(value) else: self.FindWindowById(self.win['volume']['shine']['const']).SetValue(value) 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() class IsoSurfList(wx.CheckListBox): """List of loaded volume isosurfaces (volume properties page)""" def __init__(self, parent, win, id=wx.ID_ANY, size=wx.DefaultSize): self.parent = parent self.win = win wx.CheckListBox.__init__(self, parent, id, size=size) self.Bind(wx.EVT_CHECKLISTBOX, self.OnCheck) self.Bind(wx.EVT_LISTBOX, self.OnSelect) def OnCheck(self, event): """Item checked/unchecked -> load/delete surface""" print event.IsChecked() def OnSelect(self, event): """Item selected""" winUp = self.parent.FindWindowById(self.win['btnIsosurfMoveUp']) winDown = self.parent.FindWindowById(self.win['btnIsosurfMoveDown']) selection = event.GetSelection() if selection == 0: winUp.Enable(False) if not winDown.IsEnabled(): winDown.Enable() elif selection == self.GetCount() - 1: winDown.Enable(False) if not winUp.IsEnabled(): winUp.Enable() else: if not winDown.IsEnabled(): winDown.Enable() if not winUp.IsEnabled(): winUp.Enable()