GRASS Programmer's Manual  6.4.3(2013)-r
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Pages
wxnviz.py
Go to the documentation of this file.
1 """!
2 @package nviz.wxnviz
3 
4 @brief wxGUI 3D view mode (ctypes-based classes)
5 
6 This module implements 3D visualization mode for map display (ctypes
7 required).
8 
9 List of classes:
10  - wxnviz::Nviz
11  - wxnviz::Texture
12  - wxnviz::ImageTexture
13  - wxnviz::TextTexture
14 
15 (C) 2008-2011 by the GRASS Development Team
16 
17 This program is free software under the GNU General Public License
18 (>=v2). Read the file COPYING that comes with GRASS for details.
19 
20 @author Martin Landa <landa.martin gmail.com> (Google SoC 2008/2010)
21 @author Pythonized by Glynn Clements
22 @author Anna Kratochvilova <KratochAnna seznam.cz> (Google SoC 2011)
23 """
24 
25 import sys
26 import locale
27 import struct
28 from math import sqrt
29 try:
30  from numpy import matrix
31 except ImportError:
32  msg = _("This module requires the NumPy module, which could not be "
33  "imported. It probably is not installed (it's not part of the "
34  "standard Python distribution). See the Numeric Python site "
35  "(http://numpy.scipy.org) for information on downloading source or "
36  "binaries.")
37  print >> sys.stderr, "wxnviz.py: " + msg
38 
39 import wx
40 
41 from ctypes import *
42 try:
43  from grass.lib.gis import *
44  from grass.lib.g3d import *
45  from grass.lib.vector import *
46  from grass.lib.ogsf import *
47  from grass.lib.nviz import *
48 except ImportError, e:
49  sys.stderr.write(_("3D view mode: %s\n") % e)
50 
51 from core.debug import Debug
52 import grass.script as grass
53 
54 log = None
55 progress = None
56 
57 def print_error(msg, type):
58  """!Redirect stderr"""
59  global log
60  if log:
61  log.write(msg)
62  else:
63  print msg
64 
65  return 0
66 
67 def print_progress(value):
68  """!Redirect progress info"""
69  global progress
70  if progress:
71  progress.SetValue(value)
72  else:
73  print value
74 
75  return 0
76 
77 errtype = CFUNCTYPE(UNCHECKED(c_int), String, c_int)
78 errfunc = errtype(print_error)
79 pertype = CFUNCTYPE(UNCHECKED(c_int), c_int)
80 perfunc = pertype(print_progress)
81 
82 class Nviz(object):
83  def __init__(self, glog, gprogress):
84  """!Initialize Nviz class instance
85 
86  @param log logging area
87  @param gprogress progressbar
88  """
89  global errfunc, perfunc, log, progress
90  log = glog
91  progress = gprogress
92 
93  G_gisinit("wxnviz")
94  # gislib is already initialized (where?)
95  G_set_error_routine(errfunc)
96  G_set_percent_routine(perfunc)
97 
98  self.Init()
99 
100  self.data_obj = nv_data()
101  self.data = pointer(self.data_obj)
102  self.color_obj = Colors()
103  self.color = pointer(self.color_obj)
104 
105  self.width = self.height = -1
106  self.showLight = False
107 
108  Debug.msg(1, "Nviz::Nviz()")
109 
110  def __del__(self):
111  """!Destroy Nviz class instance"""
114  del self.data
115  del self.data_obj
116  self.log = None
117 
118  def Init(self):
119  """!Initialize window"""
120  locale.setlocale(locale.LC_NUMERIC, 'C')
121  #G_unset_window()
122  #Rast_unset_window()
123  #Rast__init_window()
124  GS_libinit()
125  GVL_libinit()
126 
127  def ResizeWindow(self, width, height):
128  """!GL canvas resized
129 
130  @param width window width
131  @param height window height
132 
133  @return 1 on success
134  @return 0 on failure (window resized by default to 20x20 px)
135  """
136  self.width = width
137  self.height = height
138  Debug.msg(3, "Nviz::ResizeWindow(): width=%d height=%d",
139  width, height)
140  return Nviz_resize_window(width, height)
141 
142  def GetLongDim(self):
143  """!Get longest dimension, used for initial size of north arrow"""
144  return Nviz_get_longdim(self.data)
145 
146  def SetViewDefault(self):
147  """!Set default view (based on loaded data)
148 
149  @return z-exag value, default, min and max height
150  """
151  # determine z-exag
152  z_exag = Nviz_get_exag()
153  Nviz_change_exag(self.data, z_exag)
154 
155  # determine height
156  hdef = c_double()
157  hmin = c_double()
158  hmax = c_double()
159  Nviz_get_exag_height(byref(hdef), byref(hmin), byref(hmax))
160 
161  Debug.msg(1, "Nviz::SetViewDefault(): hdef=%f, hmin=%f, hmax=%f",
162  hdef.value, hmin.value, hmax.value)
163 
164  return (z_exag, hdef.value, hmin.value, hmax.value)
165 
166  def SetView(self, x, y, height, persp, twist):
167  """!Change view settings
168  @param x,y position
169  @param height
170  @param persp perpective
171  @param twist
172  """
177 
178  Debug.msg(3, "Nviz::SetView(): x=%f, y=%f, height=%f, persp=%f, twist=%f",
179  x, y, height, persp, twist)
180 
182  x = c_double()
183  y = c_double()
184  h = c_double()
185  Nviz_get_viewpoint_height(byref(h))
186  Nviz_get_viewpoint_position(byref(x), byref(y))
187 
188  return (x.value, y.value, h.value)
189 
190  def LookHere(self, x, y):
191  """!Look here feature
192  @param x,y screen coordinates
193  """
194 
195  Nviz_look_here(x, y)
196  Debug.msg(3, "Nviz::LookHere(): x=%f, y=%f", x, y)
197 
198  def LookAtCenter(self):
199  """!Center view at center of displayed surface"""
200  Nviz_set_focus_map(MAP_OBJ_UNDEFINED, -1)
201  Debug.msg(3, "Nviz::LookAtCenter()")
202 
203  def GetFocus(self):
204  """!Get focus"""
205  Debug.msg(3, "Nviz::GetFocus()")
206  if Nviz_has_focus(self.data):
207  x = c_float()
208  y = c_float()
209  z = c_float()
210  Nviz_get_focus(self.data, byref(x), byref(y), byref(z))
211  return x.value, y.value, z.value
212  else:
213  return -1, -1, -1
214 
215  def SetFocus(self, x, y, z):
216  """!Set focus"""
217  Debug.msg(3, "Nviz::SetFocus()")
218  Nviz_set_focus(self.data, x, y, z)
219 
220  def GetViewdir(self):
221  """!Get viewdir"""
222  Debug.msg(3, "Nviz::GetViewdir()")
223  dir = (c_float * 3)()
224  GS_get_viewdir(byref(dir))
225 
226  return dir[0], dir[1], dir[2]
227 
228  def SetViewdir(self, x, y, z):
229  """!Set viewdir"""
230  Debug.msg(3, "Nviz::SetViewdir(): x=%f, y=%f, z=%f" % (x, y, z))
231  dir = (c_float * 3)()
232  for i, coord in enumerate((x, y, z)):
233  dir[i] = coord
234  GS_set_viewdir(byref(dir))
235 
236  def SetZExag(self, z_exag):
237  """!Set z-exag value
238 
239  @param z_exag value
240 
241  @return 1
242  """
243  Debug.msg(3, "Nviz::SetZExag(): z_exag=%f", z_exag)
244  return Nviz_change_exag(self.data, z_exag)
245 
246  def Draw(self, quick, quick_mode):
247  """!Draw canvas
248 
249  Draw quick mode:
250  - DRAW_QUICK_SURFACE
251  - DRAW_QUICK_VLINES
252  - DRAW_QUICK_VPOINTS
253  - DRAW_QUICK_VOLUME
254 
255  @param quick if true draw in wiremode
256  @param quick_mode quick mode
257  """
258  Debug.msg(3, "Nviz::Draw(): quick=%d", quick)
259 
260  Nviz_draw_cplane(self.data, -1, -1) # ?
261 
262  if quick:
263  Nviz_draw_quick(self.data, quick_mode)
264  else:
265  Nviz_draw_all(self.data)
266 
267  def EraseMap(self):
268  """!Erase map display (with background color)
269  """
270  Debug.msg(1, "Nviz::EraseMap()")
272 
273  def InitView(self):
274  """!Initialize view"""
275  # initialize nviz data
276  Nviz_init_data(self.data)
277 
278  # define default attributes for map objects
280  # set background color
282 
284  # initialize view, lights
285  Nviz_init_view(self.data)
286 
287  Debug.msg(1, "Nviz::InitView()")
288 
289  def SetBgColor(self, color_str):
290  """!Set background color
291 
292  @param color_str color string
293  """
294  Nviz_set_bgcolor(self.data, Nviz_color_from_str(color_str))
295 
296  def SetLight(self, x, y, z, color, bright, ambient, w = 0, lid = 1):
297  """!Change lighting settings
298  @param x,y,z position
299  @param color light color (as string)
300  @param bright light brightness
301  @param ambient light ambient
302  @param w local coordinate (default to 0)
303  """
304  Nviz_set_light_position(self.data, lid, x, y, z, w)
305  Nviz_set_light_bright(self.data, lid, bright)
306  Nviz_set_light_color(self.data, lid, int(color[0]), int(color[1]), int(color[2]))
307  Nviz_set_light_ambient(self.data, lid, ambient)
308 
309  def LoadSurface(self, name, color_name, color_value):
310  """!Load raster map (surface)
311 
312  @param name raster map name
313  @param color_name raster map for color (None for color_value)
314  @param color_value color string (named color or RGB triptet)
315 
316  @return object id
317  @return -1 on failure
318  """
319  mapset = G_find_cell2(name, "")
320  if mapset is None:
321  G_warning(_("Raster map <%s> not found"), name)
322  return -1
323 
324  # topography
325  id = Nviz_new_map_obj(MAP_OBJ_SURF,
326  G_fully_qualified_name(name, mapset), 0.0,
327  self.data)
328 
329  if color_name: # check for color map
330  mapset = G_find_cell2(color_name, "")
331  if mapset is None:
332  G_warning(_("Raster map <%s> not found"), color_name)
334  return -1
335 
336  Nviz_set_attr(id, MAP_OBJ_SURF, ATT_COLOR, MAP_ATT,
337  G_fully_qualified_name(color_name, mapset), -1.0,
338  self.data)
339 
340  elif color_value: # check for color value
341  Nviz_set_attr(id, MAP_OBJ_SURF, ATT_COLOR, CONST_ATT,
342  None, Nviz_color_from_str(color_value),
343  self.data)
344 
345  else: # use by default elevation map for coloring
346  Nviz_set_attr(id, MAP_OBJ_SURF, ATT_COLOR, MAP_ATT,
347  G_fully_qualified_name(name, mapset), -1.0,
348  self.data)
349 
350  # if (i > 1)
351  # set_default_wirecolors(self.data, i)
352 
353  # focus on loaded self.data
354  Nviz_set_focus_map(MAP_OBJ_UNDEFINED, -1)
355 
356  Debug.msg(1, "Nviz::LoadRaster(): name=%s -> id=%d", name, id)
357 
358  return id
359 
360  def AddConstant(self, value, color):
361  """!Add new constant surface"""
362  id = Nviz_new_map_obj(MAP_OBJ_SURF, None, value, self.data)
363 
364  Nviz_set_attr(id, MAP_OBJ_SURF, ATT_COLOR, CONST_ATT,
365  None, Nviz_color_from_str(color),
366  self.data)
367  Nviz_set_focus_map(MAP_OBJ_UNDEFINED, -1)
368 
369  Debug.msg(1, "Nviz::AddConstant(): id=%d", id)
370  return id
371 
372  def UnloadSurface(self, id):
373  """!Unload surface
374 
375  @param id surface id
376 
377  @return 1 on success
378  @return 0 on failure
379  """
380  if not GS_surf_exists(id):
381  return 0
382 
383  Debug.msg(1, "Nviz::UnloadSurface(): id=%d", id)
384 
385  if GS_delete_surface(id) < 0:
386  return 0
387 
388  return 1
389 
390  def LoadVector(self, name, points):
391  """!Load vector map overlay
392 
393  @param name vector map name
394  @param points if true load 2d points rather then 2d lines
395 
396  @return object id, id of base surface (or -1 if it is not loaded)
397  @return -1 on failure
398  """
399  baseId = -1
400  if GS_num_surfs() == 0: # load base surface if no loaded
401  baseId = Nviz_new_map_obj(MAP_OBJ_SURF, None, 0.0, self.data)
402 
403  nsurf = c_int()
404  surf_list = GS_get_surf_list(byref(nsurf))
405  GS_set_att_const(surf_list[0], ATT_TRANSP, 255)
406 
407  mapset = G_find_vector2 (name, "")
408  if mapset is None:
409  G_warning(_("Vector map <%s> not found"),
410  name)
411 
412  if points:
413  id = Nviz_new_map_obj(MAP_OBJ_SITE,
414  G_fully_qualified_name(name, mapset), 0.0,
415  self.data)
416  else:
417  id = Nviz_new_map_obj(MAP_OBJ_VECT,
418  G_fully_qualified_name(name, mapset), 0.0,
419  self.data)
420 
421  Debug.msg(1, "Nviz::LoadVector(): name=%s -> id=%d", name, id)
422 
423  return id, baseId
424 
425  def UnloadVector(self, id, points):
426  """!Unload vector set
427 
428  @param id vector set id
429  @param points vector points or lines set
430 
431  @return 1 on success
432  @return 0 on failure
433  """
434  Debug.msg(1, "Nviz::UnloadVector(): id=%d", id)
435 
436  if points:
437  if not GP_site_exists(id):
438  return 0
439  if GP_delete_site(id) < 0:
440  return 0
441  else:
442  if not GV_vect_exists(id):
443  return 0
444  if GV_delete_vector(id) < 0:
445  return 0
446 
447  return 1
448 
449  def VectorSurfaceSelected(self, vid, sid):
450  """!Check if surface is selected (currently unused)
451 
452  @param vid vector id
453  @param sid surface id
454 
455  @return True if selected
456  @return False if not selected
457  """
458  selected = GV_surf_is_selected(vid, sid)
459  Debug.msg(1, "Nviz::VectorSurfaceSelected(): vid=%s, sid=%d -> selected=%d", vid, sid, selected)
460  return selected
461 
462  def LoadVolume(self, name, color_name, color_value):
463  """!Load 3d raster map (volume)
464 
465  @param name 3d raster map name
466  @param color_name 3d raster map for color (None for color_value)
467  @param color_value color string (named color or RGB triptet)
468 
469  @return object id
470  @return -1 on failure
471  """
472  mapset = G_find_grid3(name, "")
473  if mapset is None:
474  G_warning(_("3d raster map <%s> not found"),
475  name)
476  return -1
477 
478  # topography
479  id = Nviz_new_map_obj(MAP_OBJ_VOL,
480  G_fully_qualified_name(name, mapset), 0.0,
481  self.data)
482 
483  if color_name: # check for color map
484  mapset = G_find_grid3(color_name, "")
485  if mapset is None:
486  G_warning(_("3d raster map <%s> not found"),
487  color_name)
488  GVL_delete_vol(id)
489  return -1
490 
491  Nviz_set_attr(id, MAP_OBJ_VOL, ATT_COLOR, MAP_ATT,
492  G_fully_qualified_name(color_name, mapset), -1.0,
493  self.data)
494  elif color_value: # check for color value
495  Nviz_set_attr(id, MAP_OBJ_VOL, ATT_COLOR, CONST_ATT,
496  None, Nviz_color_from_str(color_value),
497  self.data)
498  else: # use by default elevation map for coloring
499  Nviz_set_attr(id, MAP_OBJ_VOL, ATT_COLOR, MAP_ATT,
500  G_fully_qualified_name(name, mapset), -1.0,
501  self.data)
502 
503  Debug.msg(1, "Nviz::LoadVolume(): name=%s -> id=%d", name, id)
504 
505  return id
506 
507  def UnloadVolume(self, id):
508  """!Unload volume
509 
510  @param id volume id
511 
512  @return 1 on success
513  @return 0 on failure
514  """
515  if not GVL_vol_exists(id):
516  return 0
517 
518  Debug.msg(1, "Nviz::UnloadVolume(): id=%d", id)
519 
520  if GVL_delete_vol(id) < 0:
521  return 0
522 
523  return 1
524 
525  def SetSurfaceTopo(self, id, map, value):
526  """!Set surface topography
527 
528  @param id surface id
529  @param map if true use map otherwise constant
530  @param value map name of value
531 
532  @return 1 on success
533  @return -1 surface not found
534  @return -2 setting attributes failed
535  """
536  return self.SetSurfaceAttr(id, ATT_TOPO, map, value)
537 
538  def SetSurfaceColor(self, id, map, value):
539  """!Set surface color
540 
541  @param id surface id
542  @param map if true use map otherwise constant
543  @param value map name or value
544 
545  @return 1 on success
546  @return -1 surface not found
547  @return -2 setting attributes failed
548  """
549  return self.SetSurfaceAttr(id, ATT_COLOR, map, value)
550 
551  def SetSurfaceMask(self, id, invert, value):
552  """!Set surface mask
553 
554  @todo invert
555 
556  @param id surface id
557  @param invert if true invert mask
558  @param value map name of value
559 
560  @return 1 on success
561  @return -1 surface not found
562  @return -2 setting attributes failed
563  """
564  return self.SetSurfaceAttr(id, ATT_MASK, True, value)
565 
566  def SetSurfaceTransp(self, id, map, value):
567  """!Set surface mask
568 
569  @todo invert
570 
571  @param id surface id
572  @param map if true use map otherwise constant
573  @param value map name of value
574 
575  @return 1 on success
576  @return -1 surface not found
577  @return -2 setting attributes failed
578  """
579  return self.SetSurfaceAttr(id, ATT_TRANSP, map, value)
580 
581  def SetSurfaceShine(self, id, map, value):
582  """!Set surface shininess
583 
584  @param id surface id
585  @param map if true use map otherwise constant
586  @param value map name of value
587 
588  @return 1 on success
589  @return -1 surface not found
590  @return -2 setting attributes failed
591  """
592  return self.SetSurfaceAttr(id, ATT_SHINE, map, value)
593 
594  def SetSurfaceEmit(self, id, map, value):
595  """!Set surface emission (currently unused)
596 
597  @param id surface id
598  @param map if true use map otherwise constant
599  @param value map name of value
600 
601  @return 1 on success
602  @return -1 surface not found
603  @return -2 setting attributes failed
604  """
605  return self.SetSurfaceAttr(id, ATT_EMIT, map, value)
606 
607  def SetSurfaceAttr(self, id, attr, map, value):
608  """!Set surface attribute
609 
610  @param id surface id
611  @param attr attribute desc
612  @param map if true use map otherwise constant
613  @param value map name of value
614 
615  @return 1 on success
616  @return -1 surface not found
617  @return -2 setting attributes failed
618  """
619  if not GS_surf_exists(id):
620  return -1
621 
622  if map:
623  ret = Nviz_set_attr(id, MAP_OBJ_SURF, attr, MAP_ATT,
624  value, -1.0, self.data)
625  else:
626  if attr == ATT_COLOR:
627  val = Nviz_color_from_str(value)
628  else:
629  val = float(value)
630 
631  ret = Nviz_set_attr(id, MAP_OBJ_SURF, attr, CONST_ATT,
632  None, val, self.data)
633 
634  Debug.msg(3, "Nviz::SetSurfaceAttr(): id=%d, attr=%d, map=%d, value=%s",
635  id, attr, map, value)
636 
637  if ret < 0:
638  return -2
639 
640  return 1
641 
642  def UnsetSurfaceMask(self, id):
643  """!Unset surface mask
644 
645  @param id surface id
646 
647  @return 1 on success
648  @return -1 surface not found
649  @return -2 setting attributes failed
650  @return -1 on failure
651  """
652  return self.UnsetSurfaceAttr(id, ATT_MASK)
653 
654  def UnsetSurfaceTransp(self, id):
655  """!Unset surface transparency
656 
657  @param id surface id
658 
659  @return 1 on success
660  @return -1 surface not found
661  @return -2 setting attributes failed
662  """
663  return self.UnsetSurfaceAttr(id, ATT_TRANSP)
664 
665  def UnsetSurfaceEmit(self, id):
666  """!Unset surface emission (currently unused)
667 
668  @param id surface id
669 
670  @return 1 on success
671  @return -1 surface not found
672  @return -2 setting attributes failed
673  """
674  return self.UnsetSurfaceAttr(id, ATT_EMIT)
675 
676  def UnsetSurfaceAttr(self, id, attr):
677  """!Unset surface attribute
678 
679  @param id surface id
680  @param attr attribute descriptor
681 
682  @return 1 on success
683  @return -1 surface not found
684  @return -2 setting attributes failed
685  """
686  if not GS_surf_exists(id):
687  return -1
688 
689  Debug.msg(3, "Nviz::UnsetSurfaceAttr(): id=%d, attr=%d",
690  id, attr)
691 
692  ret = Nviz_unset_attr(id, MAP_OBJ_SURF, attr)
693 
694  if ret < 0:
695  return -2
696 
697  return 1
698 
699  def SetSurfaceRes(self, id, fine, coarse):
700  """!Set surface resolution
701 
702  @param id surface id
703  @param fine x/y fine resolution
704  @param coarse x/y coarse resolution
705 
706  @return 1 on success
707  @return -1 surface not found
708  @return -2 setting attributes failed
709  """
710  Debug.msg(3, "Nviz::SetSurfaceRes(): id=%d, fine=%d, coarse=%d",
711  id, fine, coarse)
712 
713  if id > 0:
714  if not GS_surf_exists(id):
715  return -1
716 
717  if GS_set_drawres(id, fine, fine, coarse, coarse) < 0:
718  return -2
719  else:
720  GS_setall_drawres(fine, fine, coarse, coarse)
721 
722  return 1
723 
724  def SetSurfaceStyle(self, id, style):
725  """!Set draw style
726 
727  Draw styles:
728  - DM_GOURAUD
729  - DM_FLAT
730  - DM_FRINGE
731  - DM_WIRE
732  - DM_COL_WIRE
733  - DM_POLY
734  - DM_WIRE_POLY
735  - DM_GRID_WIRE
736  - DM_GRID_SURF
737 
738  @param id surface id (<= 0 for all)
739  @param style draw style
740 
741  @return 1 on success
742  @return -1 surface not found
743  @return -2 setting attributes failed
744  """
745  Debug.msg(3, "Nviz::SetSurfaceStyle(): id=%d, style=%d",
746  id, style)
747 
748  if id > 0:
749  if not GS_surf_exists(id):
750  return -1
751 
752  if GS_set_drawmode(id, style) < 0:
753  return -2
754 
755  return 1
756 
757  if GS_setall_drawmode(style) < 0:
758  return -2
759 
760  return 1
761 
762  def SetWireColor(self, id, color_str):
763  """!Set color of wire
764 
765  @todo all
766 
767  @param surface id (< 0 for all)
768  @param color color string (R:G:B)
769 
770  @return 1 on success
771  @return -1 surface not found
772  @return -2 setting attributes failed
773  @return 1 on success
774  @return 0 on failure
775  """
776  Debug.msg(3, "Nviz::SetWireColor(): id=%d, color=%s",
777  id, color_str)
778 
779  color = Nviz_color_from_str(color_str)
780 
781  if id > 0:
782  if not GS_surf_exists(id):
783  return -1
784 
785  GS_set_wire_color(id, color)
786  else:
787  nsurfs = c_int()
788  surf_list = GS_get_surf_list(byref(nsurfs))
789  for i in xrange(nsurfs.value):
790  id = surf_list[i]
791  GS_set_wire_color(id, color)
792 
793  G_free(surf_list)
794  surf_list = None
795 
796  return 1
797 
798  def GetSurfacePosition(self, id):
799  """!Get surface position
800 
801  @param id surface id
802 
803  @return x,y,z
804  @return zero-length vector on error
805  """
806  if not GS_surf_exists(id):
807  return []
808 
809  x, y, z = c_float(), c_float(), c_float()
810  GS_get_trans(id, byref(x), byref(y), byref(z))
811 
812  Debug.msg(3, "Nviz::GetSurfacePosition(): id=%d, x=%f, y=%f, z=%f",
813  id, x.value, y.value, z.value)
814 
815  return [x.value, y.value, z.value]
816 
817  def SetSurfacePosition(self, id, x, y, z):
818  """!Set surface position
819 
820  @param id surface id
821  @param x,y,z translation values
822 
823  @return 1 on success
824  @return -1 surface not found
825  @return -2 setting position failed
826  """
827  if not GS_surf_exists(id):
828  return -1
829 
830  Debug.msg(3, "Nviz::SetSurfacePosition(): id=%d, x=%f, y=%f, z=%f",
831  id, x, y, z)
832 
833  GS_set_trans(id, x, y, z)
834 
835  return 1
836 
837  def SetVectorLineMode(self, id, color_str, width, flat):
838  """!Set mode of vector line overlay
839 
840  @param id vector id
841  @param color_str color string
842  @param width line width
843  @param flat display flat or on surface
844 
845  @return -1 vector set not found
846  @return -2 on failure
847  @return 1 on success
848  """
849  if not GV_vect_exists(id):
850  return -1
851 
852  Debug.msg(3, "Nviz::SetVectorMode(): id=%d, color=%s, width=%d, flat=%d",
853  id, color_str, width, flat)
854 
855  color = Nviz_color_from_str(color_str)
856 
857  # use memory by default
858  if GV_set_vectmode(id, 1, color, width, flat) < 0:
859  return -2
860 
861  return 1
862 
863  def SetVectorLineHeight(self, id, height):
864  """!Set vector height above surface (lines)
865 
866  @param id vector set id
867  @param height
868 
869  @return -1 vector set not found
870  @return 1 on success
871  """
872  if not GV_vect_exists(id):
873  return -1
874 
875  Debug.msg(3, "Nviz::SetVectorLineHeight(): id=%d, height=%f",
876  id, height)
877 
878  GV_set_trans(id, 0.0, 0.0, height)
879 
880  return 1
881 
882  def SetVectorLineSurface(self, id, surf_id):
883  """!Set reference surface of vector set (lines)
884 
885  @param id vector set id
886  @param surf_id surface id
887 
888  @return 1 on success
889  @return -1 vector set not found
890  @return -2 surface not found
891  @return -3 on failure
892  """
893  if not GV_vect_exists(id):
894  return -1
895 
896  if not GS_surf_exists(surf_id):
897  return -2
898 
899  if GV_select_surf(id, surf_id) < 0:
900  return -3
901 
902  return 1
903 
904  def UnsetVectorLineSurface(self, id, surf_id):
905  """!Unset reference surface of vector set (lines)
906 
907  @param id vector set id
908  @param surf_id surface id
909 
910  @return 1 on success
911  @return -1 vector set not found
912  @return -2 surface not found
913  @return -3 on failure
914  """
915  if not GV_vect_exists(id):
916  return -1
917 
918  if not GS_surf_exists(surf_id):
919  return -2
920 
921  if GV_unselect_surf(id, surf_id) < 0:
922  return -3
923 
924  return 1
925 
926  def SetVectorPointMode(self, id, color_str, width, size, marker):
927  """!Set mode of vector point overlay
928 
929  @param id vector id
930  @param color_str color string
931  @param width line width
932  @param flat
933 
934  @return -1 vector set not found
935  """
936  if not GP_site_exists(id):
937  return -1
938 
939  # dtree and ctree defined but not used
940  if marker > 5:
941  marker += 2
942 
943  Debug.msg(3, "Nviz::SetVectorPointMode(): id=%d, color=%s, "
944  "width=%d, size=%f, marker=%d",
945  id, color_str, width, size, marker)
946 
947  color = Nviz_color_from_str(color_str)
948 
949  if GP_set_sitemode(id, ST_ATT_NONE, color, width, size, marker) < 0:
950  return -2
951 
952  return 1
953 
954  def SetVectorPointHeight(self, id, height):
955  """!Set vector height above surface (points)
956 
957  @param id vector set id
958  @param height
959 
960  @return -1 vector set not found
961  @return 1 on success
962  """
963  if not GP_site_exists(id):
964  return -1
965 
966  Debug.msg(3, "Nviz::SetVectorPointHeight(): id=%d, height=%f",
967  id, height)
968 
969  GP_set_trans(id, 0.0, 0.0, height)
970 
971  return 1
972 
973  def SetVectorPointSurface(self, id, surf_id):
974  """!Set reference surface of vector set (points)
975 
976  @param id vector set id
977  @param surf_id surface id
978 
979  @return 1 on success
980  @return -1 vector set not found
981  @return -2 surface not found
982  @return -3 on failure
983  """
984  if not GP_site_exists(id):
985  return -1
986 
987  if not GS_surf_exists(surf_id):
988  return -2
989 
990  if GP_select_surf(id, surf_id) < 0:
991  return -3
992 
993  return 1
994 
995  def ReadVectorColors(self, name, mapset):
996  """!Read vector colors
997 
998  @param name vector map name
999  @mapset mapset name ("" for search path)
1000 
1001  @return -1 on error
1002  @return 0 if color table missing
1003  @return 1 on success (color table found)
1004  """
1005  return Vect_read_colors(name, mapset, self.color)
1006 
1007  def CheckColorTable(self, id, type):
1008  """!Check if color table exists.
1009 
1010  @param id vector set id
1011  @param type vector set type (lines/points)
1012 
1013  @return 1 color table exists
1014  @return 0 no color table found
1015  @return -1 on error
1016  @return -2 vector set not found
1017  """
1018  file = c_char_p()
1019 
1020  if type == 'points':
1021  ret = GP_get_sitename(id, byref(file))
1022  elif type == 'lines':
1023  ret = GV_get_vectname(id, byref(file))
1024 
1025  if ret < 0:
1026  return -2
1027 
1028  return self.ReadVectorColors(file, "")
1029 
1030  def UnsetVectorPointSurface(self, id, surf_id):
1031  """!Unset reference surface of vector set (points)
1032 
1033  @param id vector set id
1034  @param surf_id surface id
1035 
1036  @return 1 on success
1037  @return -1 vector set not found
1038  @return -2 surface not found
1039  @return -3 on failure
1040  """
1041  if not GP_site_exists(id):
1042  return -1
1043 
1044  if not GS_surf_exists(surf_id):
1045  return -2
1046 
1047  if GP_unselect_surf(id, surf_id) < 0:
1048  return -3
1049 
1050  return 1
1051 
1052  def AddIsosurface(self, id, level, isosurf_id = None):
1053  """!Add new isosurface
1054 
1055  @param id volume id
1056  @param level isosurface level (topography)
1057 
1058  @return -1 on failure
1059  @return 1 on success
1060  """
1061  if not GVL_vol_exists(id):
1062  return -1
1063 
1064  if isosurf_id is not None:
1065  num = GVL_isosurf_num_isosurfs(id)
1066  if num < 0 or isosurf_id != num:
1067  return -1
1068 
1069  if GVL_isosurf_add(id) < 0:
1070  return -1
1071 
1072  # set topography level
1073  nisosurfs = GVL_isosurf_num_isosurfs(id)
1074 
1075  return GVL_isosurf_set_att_const(id, nisosurfs - 1, ATT_TOPO, level)
1076 
1077  def AddSlice(self, id, slice_id = None):
1078  """!Add new slice
1079 
1080  @param id volume id
1081 
1082  @return -1 on failure
1083  @return number of slices
1084  """
1085  if not GVL_vol_exists(id):
1086  return -1
1087 
1088  if slice_id is not None:
1089  num = GVL_slice_num_slices(id)
1090  if num < 0 or slice_id != num:
1091  return -1
1092 
1093  if GVL_slice_add(id) < 0:
1094  return -1
1095 
1096  return GVL_slice_num_slices(id)
1097 
1098  def DeleteIsosurface(self, id, isosurf_id):
1099  """!Delete isosurface
1100 
1101  @param id volume id
1102  @param isosurf_id isosurface id
1103 
1104  @return 1 on success
1105  @return -1 volume not found
1106  @return -2 isosurface not found
1107  @return -3 on failure
1108  """
1109  if not GVL_vol_exists(id):
1110  return -1
1111 
1112  if isosurf_id > GVL_isosurf_num_isosurfs(id):
1113  return -2
1114 
1115  ret = GVL_isosurf_del(id, isosurf_id)
1116 
1117  if ret < 0:
1118  return -3
1119 
1120  return 1
1121 
1122  def DeleteSlice(self, id, slice_id):
1123  """!Delete slice
1124 
1125  @param id volume id
1126  @param slice_id slice id
1127 
1128  @return 1 on success
1129  @return -1 volume not found
1130  @return -2 slice not found
1131  @return -3 on failure
1132  """
1133  if not GVL_vol_exists(id):
1134  return -1
1135 
1136  if slice_id > GVL_slice_num_slices(id):
1137  return -2
1138 
1139  ret = GVL_slice_del(id, slice_id)
1140 
1141  if ret < 0:
1142  return -3
1143 
1144  return 1
1145 
1146  def MoveIsosurface(self, id, isosurf_id, up):
1147  """!Move isosurface up/down in the list
1148 
1149  @param id volume id
1150  @param isosurf_id isosurface id
1151  @param up if true move up otherwise down
1152 
1153  @return 1 on success
1154  @return -1 volume not found
1155  @return -2 isosurface not found
1156  @return -3 on failure
1157  """
1158  if not GVL_vol_exists(id):
1159  return -1
1160 
1161  if isosurf_id > GVL_isosurf_num_isosurfs(id):
1162  return -2
1163 
1164  if up:
1165  ret = GVL_isosurf_move_up(id, isosurf_id)
1166  else:
1167  ret = GVL_isosurf_move_down(id, isosurf_id)
1168 
1169  if ret < 0:
1170  return -3
1171 
1172  return 1
1173 
1174  def MoveSlice(self, id, slice_id, up):
1175  """!Move slice up/down in the list
1176 
1177  @param id volume id
1178  @param slice_id slice id
1179  @param up if true move up otherwise down
1180 
1181  @return 1 on success
1182  @return -1 volume not found
1183  @return -2 slice not found
1184  @return -3 on failure
1185  """
1186  if not GVL_vol_exists(id):
1187  return -1
1188 
1189  if slice_id > GVL_slice_num_slices(id):
1190  return -2
1191 
1192  if up:
1193  ret = GVL_slice_move_up(id, slice_id)
1194  else:
1195  ret = GVL_slice_move_down(id, slice_id)
1196 
1197  if ret < 0:
1198  return -3
1199 
1200  return 1
1201 
1202  def SetIsosurfaceTopo(self, id, isosurf_id, map, value):
1203  """!Set isosurface level
1204 
1205  @param id volume id
1206  @param isosurf_id isosurface id (0 - MAX_ISOSURFS)
1207  @param map if true use map otherwise constant
1208  @param value map name of value
1209 
1210  @return 1 on success
1211  @return -1 volume not found
1212  @return -2 isosurface not found
1213  @return -3 on failure
1214  """
1215  return self.SetIsosurfaceAttr(id, isosurf_id, ATT_TOPO, map, value)
1216 
1217  def SetIsosurfaceColor(self, id, isosurf_id, map, value):
1218  """!Set isosurface color
1219 
1220  @param id volume id
1221  @param isosurf_id isosurface id (0 - MAX_ISOSURFS)
1222  @param map if true use map otherwise constant
1223  @param value map name of value
1224 
1225  @return 1 on success
1226  @return -1 volume not found
1227  @return -2 isosurface not found
1228  @return -3 on failure
1229  """
1230  return self.SetIsosurfaceAttr(id, isosurf_id, ATT_COLOR, map, value)
1231 
1232  def SetIsosurfaceMask(self, id, isosurf_id, invert, value):
1233  """!Set isosurface mask
1234 
1235  @todo invert
1236 
1237  @param id volume id
1238  @param isosurf_id isosurface id (0 - MAX_ISOSURFS)
1239  @param invert true for invert mask
1240  @param value map name to be used for mask
1241 
1242  @return 1 on success
1243  @return -1 volume not found
1244  @return -2 isosurface not found
1245  @return -3 on failure
1246  """
1247  return self.SetIsosurfaceAttr(id, isosurf_id, ATT_MASK, True, value)
1248 
1249  def SetIsosurfaceTransp(self, id, isosurf_id, map, value):
1250  """!Set isosurface transparency
1251 
1252  @param id volume id
1253  @param isosurf_id isosurface id (0 - MAX_ISOSURFS)
1254  @param map if true use map otherwise constant
1255  @param value map name of value
1256 
1257  @return 1 on success
1258  @return -1 volume not found
1259  @return -2 isosurface not found
1260  @return -3 on failure
1261  """
1262  return self.SetIsosurfaceAttr(id, isosurf_id, ATT_TRANSP, map, value)
1263 
1264  def SetIsosurfaceShine(self, id, isosurf_id, map, value):
1265  """!Set isosurface shininess
1266 
1267  @param id volume id
1268  @param isosurf_id isosurface id (0 - MAX_ISOSURFS)
1269  @param map if true use map otherwise constant
1270  @param value map name of value
1271 
1272  @return 1 on success
1273  @return -1 volume not found
1274  @return -2 isosurface not found
1275  @return -3 on failure
1276  """
1277  return self.SetIsosurfaceAttr(id, isosurf_id, ATT_SHINE, map, value)
1278 
1279  def SetIsosurfaceEmit(self, id, isosurf_id, map, value):
1280  """!Set isosurface emission (currently unused)
1281 
1282  @param id volume id
1283  @param isosurf_id isosurface id (0 - MAX_ISOSURFS)
1284  @param map if true use map otherwise constant
1285  @param value map name of value
1286 
1287  @return 1 on success
1288  @return -1 volume not found
1289  @return -2 isosurface not found
1290  @return -3 on failure
1291  """
1292  return self.SetIsosurfaceAttr(id, isosurf_id, ATT_EMIT, map, value)
1293 
1294  def SetIsosurfaceAttr(self, id, isosurf_id, attr, map, value):
1295  """!Set isosurface attribute
1296 
1297  @param id volume id
1298  @param isosurf_id isosurface id (0 - MAX_ISOSURFS)
1299  @param attr attribute desc
1300  @param map if true use map otherwise constant
1301  @param value map name of value
1302 
1303  @return 1 on success
1304  @return -1 volume not found
1305  @return -2 isosurface not found
1306  @return -3 setting attributes failed
1307  """
1308  if not GVL_vol_exists(id):
1309  return -1
1310 
1311  if isosurf_id > GVL_isosurf_num_isosurfs(id) - 1:
1312  return -2
1313 
1314  if map:
1315  ret = GVL_isosurf_set_att_map(id, isosurf_id, attr, value)
1316  else:
1317  if attr == ATT_COLOR:
1318  val = Nviz_color_from_str(value)
1319  else:
1320  val = float(value)
1321 
1322  ret = GVL_isosurf_set_att_const(id, isosurf_id, attr, val)
1323 
1324  Debug.msg(3, "Nviz::SetIsosurfaceAttr(): id=%d, isosurf=%d, "
1325  "attr=%d, map=%s, value=%s",
1326  id, isosurf_id, attr, map, value)
1327 
1328  if ret < 0:
1329  return -2
1330 
1331  return 1
1332 
1333  def UnsetIsosurfaceMask(self, id, isosurf_id):
1334  """!Unset isosurface mask
1335 
1336  @param id volume id
1337  @param isosurf_id isosurface id (0 - MAX_ISOSURFS)
1338 
1339  @return 1 on success
1340  @return -1 volume not found
1341  @return -2 isosurface not found
1342  @return -3 setting attributes failed
1343  """
1344  return self.UnsetIsosurfaceAttr(id, isosurf_id, ATT_MASK)
1345 
1346  def UnsetIsosurfaceTransp(self, id, isosurf_id):
1347  """!Unset isosurface transparency
1348 
1349  @param id volume id
1350  @param isosurf_id isosurface id (0 - MAX_ISOSURFS)
1351 
1352  @return 1 on success
1353  @return -1 volume not found
1354  @return -2 isosurface not found
1355  @return -3 setting attributes failed
1356  """
1357  return self.UnsetIsosurfaceAttr(id, isosurf_id, ATT_TRANSP)
1358 
1359  def UnsetIsosurfaceEmit(self, id, isosurf_id):
1360  """!Unset isosurface emission (currently unused)
1361 
1362  @param id volume id
1363  @param isosurf_id isosurface id (0 - MAX_ISOSURFS)
1364 
1365  @return 1 on success
1366  @return -1 volume not found
1367  @return -2 isosurface not found
1368  @return -3 setting attributes failed
1369  """
1370  return self.UnsetIsosurfaceAttr(id, isosurf_id, ATT_EMIT)
1371 
1372  def UnsetIsosurfaceAttr(self, id, isosurf_id, attr):
1373  """!Unset surface attribute
1374 
1375  @param id surface id
1376  @param isosurf_id isosurface id (0 - MAX_ISOSURFS)
1377  @param attr attribute descriptor
1378 
1379  @return 1 on success
1380  @return -1 volume not found
1381  @return -2 isosurface not found
1382  @return -2 on failure
1383  """
1384  if not GVL_vol_exists(id):
1385  return -1
1386 
1387  if isosurf_id > GVL_isosurf_num_isosurfs(id) - 1:
1388  return -2
1389 
1390  Debug.msg(3, "Nviz::UnsetSurfaceAttr(): id=%d, isosurf_id=%d, attr=%d",
1391  id, isosurf_id, attr)
1392 
1393  ret = GVL_isosurf_unset_att(id, isosurf_id, attr)
1394 
1395  if ret < 0:
1396  return -2
1397 
1398  return 1
1399 
1400  def SetIsosurfaceMode(self, id, mode):
1401  """!Set draw mode for isosurfaces
1402 
1403  @param mode
1404 
1405  @return 1 on success
1406  @return -1 volume set not found
1407  @return -2 on failure
1408  """
1409  if not GVL_vol_exists(id):
1410  return -1
1411 
1412  ret = GVL_isosurf_set_drawmode(id, mode)
1413 
1414  if ret < 0:
1415  return -2
1416 
1417  return 1
1418 
1419  def SetSliceMode(self, id, mode):
1420  """!Set draw mode for slices
1421 
1422  @param mode
1423 
1424  @return 1 on success
1425  @return -1 volume set not found
1426  @return -2 on failure
1427  """
1428  if not GVL_vol_exists(id):
1429  return -1
1430 
1431  ret = GVL_slice_set_drawmode(id, mode)
1432 
1433  if ret < 0:
1434  return -2
1435 
1436  return 1
1437 
1438  def SetIsosurfaceRes(self, id, res):
1439  """!Set draw resolution for isosurfaces
1440 
1441  @param res resolution value
1442 
1443  @return 1 on success
1444  @return -1 volume set not found
1445  @return -2 on failure
1446  """
1447  if not GVL_vol_exists(id):
1448  return -1
1449 
1450  ret = GVL_isosurf_set_drawres(id, res, res, res)
1451 
1452  if ret < 0:
1453  return -2
1454 
1455  return 1
1456 
1457  def SetSliceRes(self, id, res):
1458  """!Set draw resolution for slices
1459 
1460  @param res resolution value
1461 
1462  @return 1 on success
1463  @return -1 volume set not found
1464  @return -2 on failure
1465  """
1466  if not GVL_vol_exists(id):
1467  return -1
1468 
1469  ret = GVL_slice_set_drawres(id, res, res, res)
1470 
1471  if ret < 0:
1472  return -2
1473 
1474  return 1
1475 
1476  def SetSlicePosition(self, id, slice_id, x1, x2, y1, y2, z1, z2, dir):
1477  """!Set slice position
1478 
1479  @param id volume id
1480  @param slice_id slice id
1481  @param x1,x2,y1,y2,z1,z2 slice coordinates
1482  @param dir axis
1483 
1484  @return 1 on success
1485  @return -1 volume not found
1486  @return -2 slice not found
1487  @return -3 on failure
1488  """
1489  if not GVL_vol_exists(id):
1490  return -1
1491 
1492  if slice_id > GVL_slice_num_slices(id):
1493  return -2
1494 
1495  ret = GVL_slice_set_pos(id, slice_id, x1, x2, y1, y2, z1, z2, dir)
1496 
1497  if ret < 0:
1498  return -2
1499 
1500  return 1
1501 
1502  def SetSliceTransp(self, id, slice_id, value):
1503  """!Set slice transparency
1504 
1505  @param id volume id
1506  @param slice_id slice id
1507  @param x1,x2,y1,y2,z1,z2 slice coordinates
1508  @param value transparency value (0 - 255)
1509 
1510  @return 1 on success
1511  @return -1 volume not found
1512  @return -2 slice not found
1513  @return -3 on failure
1514  """
1515 
1516  if not GVL_vol_exists(id):
1517  return -1
1518 
1519  if slice_id > GVL_slice_num_slices(id):
1520  return -2
1521 
1522  ret = GVL_slice_set_transp(id, slice_id, value)
1523 
1524  if ret < 0:
1525  return -2
1526 
1527  return 1
1528 
1529  def SetIsosurfaceInOut(self, id, isosurf_id, inout):
1530  """!Set inout mode
1531 
1532  @param inout mode true/false
1533 
1534  @return 1 on success
1535  @return -1 volume set not found
1536  @return -2 isosurface not found
1537  @return -3 on failure
1538  """
1539  if not GVL_vol_exists(id):
1540  return -1
1541 
1542  if isosurf_id > GVL_isosurf_num_isosurfs(id) - 1:
1543  return -2
1544 
1545  ret = GVL_isosurf_set_flags(id, isosurf_id, inout)
1546 
1547  if ret < 0:
1548  return -3
1549 
1550  return 1
1551 
1552  def GetVolumePosition(self, id):
1553  """!Get volume position
1554 
1555  @param id volume id
1556 
1557  @return x,y,z
1558  @return zero-length vector on error
1559  """
1560  if not GVL_vol_exists(id):
1561  return []
1562 
1563  x, y, z = c_float(), c_float(), c_float()
1564  GVL_get_trans(id, byref(x), byref(y), byref(z))
1565 
1566  Debug.msg(3, "Nviz::GetVolumePosition(): id=%d, x=%f, y=%f, z=%f",
1567  id, x.value, y.value, z.value)
1568 
1569  return [x.value, y.value, z.value]
1570 
1571  def SetVolumePosition(self, id, x, y, z):
1572  """!Set volume position
1573 
1574  @param id volume id
1575  @param x,y,z translation values
1576 
1577  @return 1 on success
1578  @return -1 volume not found
1579  @return -2 setting position failed
1580  """
1581  if not GVL_vol_exists(id):
1582  return -1
1583 
1584  Debug.msg(3, "Nviz::SetVolumePosition(): id=%d, x=%f, y=%f, z=%f",
1585  id, x, y, z)
1586 
1587  GVL_set_trans(id, x, y, z)
1588 
1589  return 1
1590 
1591  def GetCPlaneCurrent(self):
1592  return Nviz_get_current_cplane(self.data)
1593 
1594  def GetCPlanesCount(self):
1595  """!Returns number of cutting planes"""
1596  return Nviz_num_cplanes(self.data)
1597 
1599  """!Returns rotation parameters of current cutting plane"""
1600  x, y, z = c_float(), c_float(), c_float()
1601 
1602  current = Nviz_get_current_cplane(self.data)
1603  Nviz_get_cplane_rotation(self.data, current, byref(x), byref(y), byref(z))
1604 
1605  return x.value, y.value, z.value
1606 
1608  """!Returns translation parameters of current cutting plane"""
1609  x, y, z = c_float(), c_float(), c_float()
1610 
1611  current = Nviz_get_current_cplane(self.data)
1612  Nviz_get_cplane_translation(self.data, current, byref(x), byref(y), byref(z))
1613 
1614  return x.value, y.value, z.value
1615 
1616  def SetCPlaneRotation(self, x, y, z):
1617  """!Set current clip plane rotation
1618 
1619  @param x,y,z rotation parameters
1620  """
1621  current = Nviz_get_current_cplane(self.data)
1622  Nviz_set_cplane_rotation(self.data, current, x, y, z)
1623  Nviz_draw_cplane(self.data, -1, -1)
1624 
1625  def SetCPlaneTranslation(self, x, y, z):
1626  """!Set current clip plane translation
1627 
1628  @param x,y,z translation parameters
1629  """
1630  current = Nviz_get_current_cplane(self.data)
1631  Nviz_set_cplane_translation(self.data, current, x, y, z)
1632  Nviz_draw_cplane(self.data, -1, -1)
1633  Debug.msg(3, "Nviz::SetCPlaneTranslation(): id=%d, x=%f, y=%f, z=%f",
1634  current, x, y, z)
1635 
1636  def SetCPlaneInteractively(self, x, y):
1637  current = Nviz_get_current_cplane(self.data)
1638  ret = Nviz_set_cplane_here(self.data, current, x, y)
1639  if ret:
1640  Nviz_draw_cplane(self.data, -1, -1)
1641  x, y, z = self.GetCPlaneTranslation()
1642  return x, y, z
1643  else:
1644  return None, None, None
1645 
1646 
1647  def SelectCPlane(self, index):
1648  """!Select cutting plane
1649 
1650  @param index index of cutting plane
1651  """
1652  Nviz_on_cplane(self.data, index)
1653 
1654  def UnselectCPlane(self, index):
1655  """!Unselect cutting plane
1656 
1657  @param index index of cutting plane
1658  """
1659  Nviz_off_cplane(self.data, index)
1660 
1661  def SetFenceColor(self, index):
1662  """!Select current cutting plane
1663 
1664  @param index type of fence - from 0 (off) to 4
1665  """
1666  Nviz_set_fence_color(self.data, index)
1667 
1668  def GetXYRange(self):
1669  """!Get xy range"""
1670  return Nviz_get_xyrange(self.data)
1671 
1672  def GetZRange(self):
1673  """!Get z range"""
1674  min, max = c_float(), c_float()
1675  Nviz_get_zrange(self.data, byref(min), byref(max))
1676  return min.value, max.value
1677 
1678  def SaveToFile(self, filename, width = 20, height = 20, itype = 'ppm'):
1679  """!Save current GL screen to ppm/tif file
1680 
1681  @param filename file name
1682  @param width image width
1683  @param height image height
1684  @param itype image type ('ppm' or 'tif')
1685  """
1686  widthOrig = self.width
1687  heightOrig = self.height
1688 
1689  self.ResizeWindow(width, height)
1691  self.Draw(False, -1)
1692  if itype == 'ppm':
1693  GS_write_ppm(filename)
1694  else:
1695  GS_write_tif(filename)
1696 
1697  self.ResizeWindow(widthOrig, heightOrig)
1698 
1700  """!Draw lighting model"""
1701  if self.showLight:
1702  Nviz_draw_model(self.data)
1703 
1704  def DrawFringe(self):
1705  """!Draw fringe"""
1706  Nviz_draw_fringe(self.data)
1707 
1708  def SetFringe(self, sid, color, elev, nw = False, ne = False, sw = False, se = False):
1709  """!Set fringe
1710 
1711  @param sid surface id
1712  @param color color
1713  @param elev elevation (height)
1714  @param nw,ne,sw,se fringe edges (turn on/off)
1715  """
1716  scolor = str(color[0]) + ':' + str(color[1]) + ':' + str(color[2])
1717  Nviz_set_fringe(self.data,
1718  sid, Nviz_color_from_str(scolor),
1719  elev, int(nw), int(ne), int(sw), int(se))
1720 
1721  def DrawArrow(self):
1722  """!Draw north arrow
1723  """
1724  return Nviz_draw_arrow(self.data)
1725 
1726  def SetArrow(self, sx, sy, size, color):
1727  """!Set north arrow from canvas coordinates
1728 
1729  @param sx,sy canvas coordinates
1730  @param size arrow length
1731  @param color arrow color
1732  """
1733  return Nviz_set_arrow(self.data, sx, sy, size, Nviz_color_from_str(color))
1734 
1735  def DeleteArrow(self):
1736  """!Delete north arrow
1737  """
1738  Nviz_delete_arrow(self.data)
1739 
1740  def SetScalebar(self, id, sx, sy, size, color):
1741  """!Set scale bar from canvas coordinates
1742 
1743  @param sx,sy canvas coordinates
1744  @param id scale bar id
1745  @param size scale bar length
1746  @param color scale bar color
1747  """
1748  return Nviz_set_scalebar(self.data, id, sx, sy, size, Nviz_color_from_str(color))
1749 
1750  def DrawScalebar(self):
1751  """!Draw scale bar
1752  """
1753  return Nviz_draw_scalebar(self.data)
1754 
1755  def DeleteScalebar(self, id):
1756  """!Delete scalebar
1757  """
1758  Nviz_delete_scalebar(self.data, id)
1759 
1760  def GetPointOnSurface(self, sx, sy):
1761  """!Get point on surface
1762 
1763  @param sx,sy canvas coordinates (LL)
1764  """
1765  sid = c_int()
1766  x = c_float()
1767  y = c_float()
1768  z = c_float()
1769  Debug.msg(5, "Nviz::GetPointOnSurface(): sx=%d sy=%d" % (sx, sy))
1770  num = GS_get_selected_point_on_surface(sx, sy, byref(sid), byref(x), byref(y), byref(z))
1771  if num == 0:
1772  return (None, None, None, None)
1773 
1774  return (sid.value, x.value, y.value, z.value)
1775 
1776  def QueryMap(self, sx, sy):
1777  """!Query surface map
1778 
1779  @param sx,sy canvas coordinates (LL)
1780  """
1781  sid, x, y, z = self.GetPointOnSurface(sx, sy)
1782  if not sid:
1783  return None
1784 
1785  catstr = create_string_buffer(256)
1786  valstr = create_string_buffer(256)
1787  GS_get_cat_at_xy(sid, ATT_TOPO, catstr, x, y)
1788  GS_get_val_at_xy(sid, ATT_COLOR, valstr, x, y)
1789 
1790  return { 'id' : sid,
1791  'x' : x,
1792  'y' : y,
1793  'z' : z,
1794  'elevation' : catstr.value.replace('(', '').replace(')', ''),
1795  'color' : valstr.value }
1796 
1797  def GetDistanceAlongSurface(self, sid, p1, p2, useExag = True):
1798  """!Get distance measured along surface"""
1799  d = c_float()
1800 
1801  GS_get_distance_alongsurf(sid, p1[0], p1[1], p2[0], p2[1],
1802  byref(d), int(useExag))
1803 
1804  return d.value
1805 
1806  def GetRotationParameters(self, dx, dy):
1807  """!Get rotation parameters (angle, x, y, z axes)
1808 
1809  @param dx,dy difference from previous mouse drag event
1810  """
1811  modelview = (c_double * 16)()
1812  Nviz_get_modelview(byref(modelview))
1813 
1814  angle = sqrt(dx*dx+dy*dy)/float(self.width+1)*180.0
1815  m = []
1816  row = []
1817  for i, item in enumerate(modelview):
1818  row.append(item)
1819  if (i+1) % 4 == 0:
1820  m.append(row)
1821  row = []
1822  inv = matrix(m).I
1823  ax, ay, az = dy, dx, 0.
1824  x = inv[0,0]*ax + inv[1,0]*ay + inv[2,0]*az
1825  y = inv[0,1]*ax + inv[1,1]*ay + inv[2,1]*az
1826  z = inv[0,2]*ax + inv[1,2]*ay + inv[2,2]*az
1827 
1828  return angle, x, y, z
1829 
1830  def Rotate(self, angle, x, y, z):
1831  """!Set rotation parameters
1832  Rotate scene (difference from current state).
1833 
1834  @param angle angle
1835  @param x,y,z axis coordinate
1836  """
1837  Nviz_set_rotation(angle, x, y, z)
1838 
1839  def UnsetRotation(self):
1840  """!Stop rotating the scene"""
1842 
1843  def ResetRotation(self):
1844  """!Reset scene rotation"""
1846 
1848  """!Get rotation matrix"""
1849  matrix = (c_double * 16)()
1850  GS_get_rotation_matrix(byref(matrix))
1851  returnMatrix = []
1852  for item in matrix:
1853  returnMatrix.append(item)
1854  return returnMatrix
1855 
1856  def SetRotationMatrix(self, matrix):
1857  """!Set rotation matrix"""
1858  mtrx = (c_double * 16)()
1859  for i in range(len(matrix)):
1860  mtrx[i] = matrix[i]
1861  GS_set_rotation_matrix(byref(mtrx))
1862 
1863  def Start2D(self):
1864  Nviz_set_2D(self.width, self.height)
1865 
1866  def FlyThrough(self, flyInfo, mode, exagInfo):
1867  """!Fly through the scene
1868 
1869  @param flyInfo fly parameters
1870  @param mode 0 or 1 for different fly behaviour
1871  @param exagInfo parameters changing fly speed
1872  """
1873  fly = (c_float * 3)()
1874  for i, item in enumerate(flyInfo):
1875  fly[i] = item
1876  exag = (c_int * 2)()
1877  exag[0] = int(exagInfo['move'])
1878  exag[1] = int(exagInfo['turn'])
1879  Nviz_flythrough(self.data, fly, exag, mode)
1880 
1881 class Texture(object):
1882  """!Class representing OpenGL texture"""
1883  def __init__(self, filepath, overlayId, coords):
1884  """!Load image to texture
1885 
1886  @param filepath path to image file
1887  @param overlayId id of overlay (1 for legend, 101 and more for text)
1888  @param coords image coordinates
1889  """
1890  self.path = filepath
1891  self.image = wx.Image(filepath, wx.BITMAP_TYPE_ANY)
1892  self.width = self.image.GetWidth()
1893  self.height = self.image.GetHeight()
1894  self.id = overlayId
1895  self.coords = list(coords)
1896  self.bounds = wx.Rect()
1897  self.active = True
1898 
1899  # alpha needs to be initialized
1900  if not self.image.HasAlpha():
1901  self.image.InitAlpha()
1902 
1903  # resize image to match 2^n
1904  self.Resize()
1905 
1906  # check max texture size
1907  maxSize = c_int()
1908  Nviz_get_max_texture(byref(maxSize))
1909  self.maxSize = maxSize.value
1910  if self.maxSize < self.width or self.maxSize < self.height:
1911  # TODO: split up image
1912  self.textureId = None
1913  else:
1914  self.textureId = self.Load()
1915 
1916  def __del__(self):
1917  """!Delete texture"""
1918  if self.textureId:
1920  grass.try_remove(self.path)
1921 
1922  def Resize(self):
1923  """!Resize image to match 2^n"""
1924  n = m = 1
1925  while self.width > pow(2,n):
1926  n += 1
1927  while self.height > pow(2,m):
1928  m += 1
1929  self.image.Resize(size = (pow(2,n), pow(2,m)), pos = (0, 0))
1930  self.width = self.image.GetWidth()
1931  self.height = self.image.GetHeight()
1932 
1933  def Load(self):
1934  """!Load image to texture"""
1935  if self.image.HasAlpha():
1936  bytesPerPixel = 4
1937  else:
1938  bytesPerPixel = 3
1939  bytes = bytesPerPixel * self.width * self.height
1940  rev_val = self.height - 1
1941  im = (c_ubyte * bytes)()
1942  bytes3 = 3 * self.width * self.height
1943  bytes1 = self.width * self.height
1944  imageData = struct.unpack(str(bytes3) + 'B', self.image.GetData())
1945  if self.image.HasAlpha():
1946  alphaData = struct.unpack(str(bytes1) + 'B', self.image.GetAlphaData())
1947 
1948  # this takes too much time
1949  wx.BeginBusyCursor()
1950  for i in range(self.height):
1951  for j in range(self.width):
1952  im[(j + i * self.width) * bytesPerPixel + 0] = imageData[( j + (rev_val - i) * self.width) * 3 + 0]
1953  im[(j + i * self.width) * bytesPerPixel + 1] = imageData[( j + (rev_val - i) * self.width) * 3 + 1]
1954  im[(j + i * self.width) * bytesPerPixel + 2] = imageData[( j + (rev_val - i) * self.width) * 3 + 2]
1955  if self.image.HasAlpha():
1956  im[(j + i * self.width) * bytesPerPixel + 3] = alphaData[( j + (rev_val - i) * self.width)]
1957  wx.EndBusyCursor()
1958 
1959  id = Nviz_load_image(im, self.width, self.height, self.image.HasAlpha())
1960 
1961  return id
1962 
1963  def Draw(self):
1964  """!Draw texture as an image"""
1965  Nviz_draw_image(self.coords[0], self.coords[1], self.width, self.height, self.textureId)
1966 
1967 
1968  def SetBounds(self, rect):
1969  """!Set Bounding Rectangle"""
1970  self.bounds = rect
1971 
1972  def HitTest(self, x, y, radius):
1973  copy = wx.Rect(*self.bounds)
1974  copy.Inflate(radius, radius)
1975  return copy.ContainsXY(x, y)
1976 
1977  def MoveTexture(self, dx, dy):
1978  """!Move texture on the screen"""
1979  self.coords[0] += dx
1980  self.coords[1] += dy
1981  self.bounds.OffsetXY(dx, dy)
1982 
1983  def SetCoords(self, coords):
1984  """!Set coordinates"""
1985  dx = coords[0] - self.coords[0]
1986  dy = coords[1] - self.coords[1]
1987  self.MoveTexture(dx, dy)
1988 
1989  def GetId(self):
1990  """!Returns image id."""
1991  return self.id
1992 
1993  def SetActive(self, active = True):
1994  self.active = active
1995 
1996  def IsActive(self):
1997  return self.active
1998 
2000  """!Class representing OpenGL texture as an overlay image"""
2001  def __init__(self, filepath, overlayId, coords, cmd):
2002  """!Load image to texture
2003 
2004  @param filepath path to image file
2005  @param overlayId id of overlay (1 for legend)
2006  @param coords image coordinates
2007  @param cmd d.legend command
2008  """
2009  Texture.__init__(self, filepath = filepath, overlayId = overlayId, coords = coords)
2010 
2011  self.cmd = cmd
2012 
2013  def GetCmd(self):
2014  """!Returns overlay command."""
2015  return self.cmd
2016 
2017  def Corresponds(self, item):
2018  return sorted(self.GetCmd()) == sorted(item.GetCmd())
2019 
2021  """!Class representing OpenGL texture as a text label"""
2022  def __init__(self, filepath, overlayId, coords, textDict):
2023  """!Load image to texture
2024 
2025  @param filepath path to image file
2026  @param overlayId id of overlay (101 and more for text)
2027  @param coords text coordinates
2028  @param textDict text properties
2029  """
2030  Texture.__init__(self, filepath = filepath, overlayId = overlayId, coords = coords)
2031 
2032  self.textDict = textDict
2033 
2034  def GetTextDict(self):
2035  """!Returns text properties."""
2036  return self.textDict
2037 
2038 
2039  def Corresponds(self, item):
2040  t = self.GetTextDict()
2041  for prop in t.keys():
2042  if prop in ('coords','bbox'): continue
2043  if t[prop] != item[prop]:
2044  return False
2045 
2046  return True