wxnviz.py 61 KB

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