wxnviz.py 61 KB

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