wxnviz.py 60 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031
  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 SetPointsStyleThematic(self, id, layer, color = None, colorTable = False,
  736. width = None, size = None, symbol = None):
  737. """!Set thematic style for vector points
  738. @param id vector set id
  739. @param layer layer number for thematic mapping
  740. @param colorTable use color table
  741. @param color color column name
  742. @param width width column name
  743. @param size size column name
  744. @param symbol symbol column name
  745. """
  746. file = c_char_p()
  747. ret = GP_get_sitename(id, byref(file))
  748. if ret < 0:
  749. return -1
  750. ret = self.ReadVectorColors(file, "")
  751. if ret < 0:
  752. return -1
  753. if colorTable:
  754. GP_set_style_thematic(id, layer, color, width, size, symbol, self.color)
  755. else:
  756. GP_set_style_thematic(id, layer, color, width, size, symbol, None)
  757. def SetLinesStyleThematic(self, id, layer, color = None, colorTable = False, width = None):
  758. """!Set thematic style for vector lines
  759. @param id vector set id
  760. @param layer layer number for thematic mapping
  761. @param color color column name
  762. @param colorTable use color table
  763. @param width width column name
  764. """
  765. file = c_char_p()
  766. ret = GV_get_vectname(id, byref(file))
  767. if ret < 0:
  768. return -1
  769. ret = self.ReadVectorColors(file, "")
  770. if ret < 0:
  771. return -1
  772. if colorTable:
  773. GV_set_style_thematic(id, layer, color, width, self.color)
  774. else:
  775. GV_set_style_thematic(id, layer, color, width, None)
  776. def UnsetLinesStyleThematic(self, id):
  777. """!Unset thematic style for vector points"""
  778. GV_unset_style_thematic(id)
  779. def UnsetPointsStyleThematic(self, id):
  780. """!Unset thematic style for vector lines"""
  781. GP_unset_style_thematic(id)
  782. def UnsetVectorPointSurface(self, id, surf_id):
  783. """!Unset reference surface of vector set (points)
  784. @param id vector set id
  785. @param surf_id surface id
  786. @return 1 on success
  787. @return -1 vector set not found
  788. @return -2 surface not found
  789. @return -3 on failure
  790. """
  791. if not GP_site_exists(id):
  792. return -1
  793. if not GS_surf_exists(surf_id):
  794. return -2
  795. if GP_unselect_surf(id, surf_id) < 0:
  796. return -3
  797. return 1
  798. def AddIsosurface(self, id, level, isosurf_id = None):
  799. """!Add new isosurface
  800. @param id volume id
  801. @param level isosurface level (topography)
  802. @return -1 on failure
  803. @return 1 on success
  804. """
  805. if not GVL_vol_exists(id):
  806. return -1
  807. if isosurf_id is not None:
  808. num = GVL_isosurf_num_isosurfs(id)
  809. if num < 0 or isosurf_id != num:
  810. return -1
  811. if GVL_isosurf_add(id) < 0:
  812. return -1
  813. # set topography level
  814. nisosurfs = GVL_isosurf_num_isosurfs(id)
  815. return GVL_isosurf_set_att_const(id, nisosurfs - 1, ATT_TOPO, level)
  816. def AddSlice(self, id, slice_id = None):
  817. """!Add new slice
  818. @param id volume id
  819. @return -1 on failure
  820. @return number of slices
  821. """
  822. if not GVL_vol_exists(id):
  823. return -1
  824. if slice_id is not None:
  825. num = GVL_slice_num_slices(id)
  826. if num < 0 or slice_id != num:
  827. return -1
  828. if GVL_slice_add(id) < 0:
  829. return -1
  830. return GVL_slice_num_slices(id)
  831. def DeleteIsosurface(self, id, isosurf_id):
  832. """!Delete isosurface
  833. @param id volume id
  834. @param isosurf_id isosurface id
  835. @return 1 on success
  836. @return -1 volume not found
  837. @return -2 isosurface not found
  838. @return -3 on failure
  839. """
  840. if not GVL_vol_exists(id):
  841. return -1
  842. if isosurf_id > GVL_isosurf_num_isosurfs(id):
  843. return -2
  844. ret = GVL_isosurf_del(id, isosurf_id)
  845. if ret < 0:
  846. return -3
  847. return 1
  848. def DeleteSlice(self, id, slice_id):
  849. """!Delete slice
  850. @param id volume id
  851. @param slice_id slice id
  852. @return 1 on success
  853. @return -1 volume not found
  854. @return -2 slice not found
  855. @return -3 on failure
  856. """
  857. if not GVL_vol_exists(id):
  858. return -1
  859. if slice_id > GVL_slice_num_slices(id):
  860. return -2
  861. ret = GVL_slice_del(id, slice_id)
  862. if ret < 0:
  863. return -3
  864. return 1
  865. def MoveIsosurface(self, id, isosurf_id, up):
  866. """!Move isosurface up/down in the list
  867. @param id volume id
  868. @param isosurf_id isosurface id
  869. @param up if true move up otherwise down
  870. @return 1 on success
  871. @return -1 volume not found
  872. @return -2 isosurface not found
  873. @return -3 on failure
  874. """
  875. if not GVL_vol_exists(id):
  876. return -1
  877. if isosurf_id > GVL_isosurf_num_isosurfs(id):
  878. return -2
  879. if up:
  880. ret = GVL_isosurf_move_up(id, isosurf_id)
  881. else:
  882. ret = GVL_isosurf_move_down(id, isosurf_id)
  883. if ret < 0:
  884. return -3
  885. return 1
  886. def MoveSlice(self, id, slice_id, up):
  887. """!Move slice up/down in the list
  888. @param id volume id
  889. @param slice_id slice id
  890. @param up if true move up otherwise down
  891. @return 1 on success
  892. @return -1 volume not found
  893. @return -2 slice not found
  894. @return -3 on failure
  895. """
  896. if not GVL_vol_exists(id):
  897. return -1
  898. if slice_id > GVL_slice_num_slices(id):
  899. return -2
  900. if up:
  901. ret = GVL_slice_move_up(id, slice_id)
  902. else:
  903. ret = GVL_slice_move_down(id, slice_id)
  904. if ret < 0:
  905. return -3
  906. return 1
  907. def SetIsosurfaceTopo(self, id, isosurf_id, map, value):
  908. """!Set isosurface level
  909. @param id volume id
  910. @param isosurf_id isosurface id (0 - MAX_ISOSURFS)
  911. @param map if true use map otherwise constant
  912. @param value map name of value
  913. @return 1 on success
  914. @return -1 volume not found
  915. @return -2 isosurface not found
  916. @return -3 on failure
  917. """
  918. return self.SetIsosurfaceAttr(id, isosurf_id, ATT_TOPO, map, value)
  919. def SetIsosurfaceColor(self, id, isosurf_id, map, value):
  920. """!Set isosurface color
  921. @param id volume id
  922. @param isosurf_id isosurface id (0 - MAX_ISOSURFS)
  923. @param map if true use map otherwise constant
  924. @param value map name of value
  925. @return 1 on success
  926. @return -1 volume not found
  927. @return -2 isosurface not found
  928. @return -3 on failure
  929. """
  930. return self.SetIsosurfaceAttr(id, isosurf_id, ATT_COLOR, map, value)
  931. def SetIsosurfaceMask(self, id, isosurf_id, invert, value):
  932. """!Set isosurface mask
  933. @todo invert
  934. @param id volume id
  935. @param isosurf_id isosurface id (0 - MAX_ISOSURFS)
  936. @param invert true for invert mask
  937. @param value map name to be used for mask
  938. @return 1 on success
  939. @return -1 volume not found
  940. @return -2 isosurface not found
  941. @return -3 on failure
  942. """
  943. return self.SetIsosurfaceAttr(id, isosurf_id, ATT_MASK, True, value)
  944. def SetIsosurfaceTransp(self, id, isosurf_id, map, value):
  945. """!Set isosurface transparency
  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_TRANSP, map, value)
  956. def SetIsosurfaceShine(self, id, isosurf_id, map, value):
  957. """!Set isosurface shininess
  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_SHINE, map, value)
  968. def SetIsosurfaceEmit(self, id, isosurf_id, map, value):
  969. """!Set isosurface emission (currently unused)
  970. @param id volume id
  971. @param isosurf_id isosurface id (0 - MAX_ISOSURFS)
  972. @param map if true use map otherwise constant
  973. @param value map name of value
  974. @return 1 on success
  975. @return -1 volume not found
  976. @return -2 isosurface not found
  977. @return -3 on failure
  978. """
  979. return self.SetIsosurfaceAttr(id, isosurf_id, ATT_EMIT, map, value)
  980. def SetIsosurfaceAttr(self, id, isosurf_id, attr, map, value):
  981. """!Set isosurface attribute
  982. @param id volume id
  983. @param isosurf_id isosurface id (0 - MAX_ISOSURFS)
  984. @param attr attribute desc
  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 setting attributes failed
  991. """
  992. if not GVL_vol_exists(id):
  993. return -1
  994. if isosurf_id > GVL_isosurf_num_isosurfs(id) - 1:
  995. return -2
  996. if map:
  997. ret = GVL_isosurf_set_att_map(id, isosurf_id, attr, value)
  998. else:
  999. if attr == ATT_COLOR:
  1000. val = Nviz_color_from_str(value)
  1001. else:
  1002. val = float(value)
  1003. ret = GVL_isosurf_set_att_const(id, isosurf_id, attr, val)
  1004. Debug.msg(3, "Nviz::SetIsosurfaceAttr(): id=%d, isosurf=%d, "
  1005. "attr=%d, map=%s, value=%s",
  1006. id, isosurf_id, attr, map, value)
  1007. if ret < 0:
  1008. return -2
  1009. return 1
  1010. def UnsetIsosurfaceMask(self, id, isosurf_id):
  1011. """!Unset isosurface mask
  1012. @param id volume id
  1013. @param isosurf_id isosurface id (0 - MAX_ISOSURFS)
  1014. @return 1 on success
  1015. @return -1 volume not found
  1016. @return -2 isosurface not found
  1017. @return -3 setting attributes failed
  1018. """
  1019. return self.UnsetIsosurfaceAttr(id, isosurf_id, ATT_MASK)
  1020. def UnsetIsosurfaceTransp(self, id, isosurf_id):
  1021. """!Unset isosurface transparency
  1022. @param id volume id
  1023. @param isosurf_id isosurface id (0 - MAX_ISOSURFS)
  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. return self.UnsetIsosurfaceAttr(id, isosurf_id, ATT_TRANSP)
  1030. def UnsetIsosurfaceEmit(self, id, isosurf_id):
  1031. """!Unset isosurface emission (currently unused)
  1032. @param id volume id
  1033. @param isosurf_id isosurface id (0 - MAX_ISOSURFS)
  1034. @return 1 on success
  1035. @return -1 volume not found
  1036. @return -2 isosurface not found
  1037. @return -3 setting attributes failed
  1038. """
  1039. return self.UnsetIsosurfaceAttr(id, isosurf_id, ATT_EMIT)
  1040. def UnsetIsosurfaceAttr(self, id, isosurf_id, attr):
  1041. """!Unset surface attribute
  1042. @param id surface id
  1043. @param isosurf_id isosurface id (0 - MAX_ISOSURFS)
  1044. @param attr attribute descriptor
  1045. @return 1 on success
  1046. @return -1 volume not found
  1047. @return -2 isosurface not found
  1048. @return -2 on failure
  1049. """
  1050. if not GVL_vol_exists(id):
  1051. return -1
  1052. if isosurf_id > GVL_isosurf_num_isosurfs(id) - 1:
  1053. return -2
  1054. Debug.msg(3, "Nviz::UnsetSurfaceAttr(): id=%d, isosurf_id=%d, attr=%d",
  1055. id, isosurf_id, attr)
  1056. ret = GVL_isosurf_unset_att(id, isosurf_id, attr)
  1057. if ret < 0:
  1058. return -2
  1059. return 1
  1060. def SetIsosurfaceMode(self, id, mode):
  1061. """!Set draw mode for isosurfaces
  1062. @param mode
  1063. @return 1 on success
  1064. @return -1 volume set not found
  1065. @return -2 on failure
  1066. """
  1067. if not GVL_vol_exists(id):
  1068. return -1
  1069. ret = GVL_isosurf_set_drawmode(id, mode)
  1070. if ret < 0:
  1071. return -2
  1072. return 1
  1073. def SetSliceMode(self, id, mode):
  1074. """!Set draw mode for slices
  1075. @param mode
  1076. @return 1 on success
  1077. @return -1 volume set not found
  1078. @return -2 on failure
  1079. """
  1080. if not GVL_vol_exists(id):
  1081. return -1
  1082. ret = GVL_slice_set_drawmode(id, mode)
  1083. if ret < 0:
  1084. return -2
  1085. return 1
  1086. def SetIsosurfaceRes(self, id, res):
  1087. """!Set draw resolution for isosurfaces
  1088. @param res resolution value
  1089. @return 1 on success
  1090. @return -1 volume set not found
  1091. @return -2 on failure
  1092. """
  1093. if not GVL_vol_exists(id):
  1094. return -1
  1095. ret = GVL_isosurf_set_drawres(id, res, res, res)
  1096. if ret < 0:
  1097. return -2
  1098. return 1
  1099. def SetSliceRes(self, id, res):
  1100. """!Set draw resolution for slices
  1101. @param res resolution value
  1102. @return 1 on success
  1103. @return -1 volume set not found
  1104. @return -2 on failure
  1105. """
  1106. if not GVL_vol_exists(id):
  1107. return -1
  1108. ret = GVL_slice_set_drawres(id, res, res, res)
  1109. if ret < 0:
  1110. return -2
  1111. return 1
  1112. def SetSlicePosition(self, id, slice_id, x1, x2, y1, y2, z1, z2, dir):
  1113. """!Set slice position
  1114. @param id volume id
  1115. @param slice_id slice id
  1116. @param x1,x2,y1,y2,z1,z2 slice coordinates
  1117. @param dir axis
  1118. @return 1 on success
  1119. @return -1 volume not found
  1120. @return -2 slice not found
  1121. @return -3 on failure
  1122. """
  1123. if not GVL_vol_exists(id):
  1124. return -1
  1125. if slice_id > GVL_slice_num_slices(id):
  1126. return -2
  1127. ret = GVL_slice_set_pos(id, slice_id, x1, x2, y1, y2, z1, z2, dir)
  1128. if ret < 0:
  1129. return -2
  1130. return 1
  1131. def SetSliceTransp(self, id, slice_id, value):
  1132. """!Set slice transparency
  1133. @param id volume id
  1134. @param slice_id slice id
  1135. @param x1,x2,y1,y2,z1,z2 slice coordinates
  1136. @param value transparency value (0 - 255)
  1137. @return 1 on success
  1138. @return -1 volume not found
  1139. @return -2 slice not found
  1140. @return -3 on failure
  1141. """
  1142. if not GVL_vol_exists(id):
  1143. return -1
  1144. if slice_id > GVL_slice_num_slices(id):
  1145. return -2
  1146. ret = GVL_slice_set_transp(id, slice_id, value)
  1147. if ret < 0:
  1148. return -2
  1149. return 1
  1150. def SetIsosurfaceInOut(self, id, isosurf_id, inout):
  1151. """!Set inout mode
  1152. @param inout mode true/false
  1153. @return 1 on success
  1154. @return -1 volume set not found
  1155. @return -2 isosurface not found
  1156. @return -3 on failure
  1157. """
  1158. if not GVL_vol_exists(id):
  1159. return -1
  1160. if isosurf_id > GVL_isosurf_num_isosurfs(id) - 1:
  1161. return -2
  1162. ret = GVL_isosurf_set_flags(id, isosurf_id, inout)
  1163. if ret < 0:
  1164. return -3
  1165. return 1
  1166. def GetVolumePosition(self, id):
  1167. """!Get volume position
  1168. @param id volume id
  1169. @return x,y,z
  1170. @return zero-length vector on error
  1171. """
  1172. if not GVL_vol_exists(id):
  1173. return []
  1174. x, y, z = c_float(), c_float(), c_float()
  1175. GVL_get_trans(id, byref(x), byref(y), byref(z))
  1176. Debug.msg(3, "Nviz::GetVolumePosition(): id=%d, x=%f, y=%f, z=%f",
  1177. id, x.value, y.value, z.value)
  1178. return [x.value, y.value, z.value]
  1179. def SetVolumePosition(self, id, x, y, z):
  1180. """!Set volume position
  1181. @param id volume id
  1182. @param x,y,z translation values
  1183. @return 1 on success
  1184. @return -1 volume not found
  1185. @return -2 setting position failed
  1186. """
  1187. if not GVL_vol_exists(id):
  1188. return -1
  1189. Debug.msg(3, "Nviz::SetVolumePosition(): id=%d, x=%f, y=%f, z=%f",
  1190. id, x, y, z)
  1191. GVL_set_trans(id, x, y, z)
  1192. return 1
  1193. def GetCPlaneCurrent(self):
  1194. return Nviz_get_current_cplane(self.data)
  1195. def GetCPlanesCount(self):
  1196. """!Returns number of cutting planes"""
  1197. return Nviz_num_cplanes(self.data)
  1198. def GetCPlaneRotation(self):
  1199. """!Returns rotation parameters of current cutting plane"""
  1200. x, y, z = c_float(), c_float(), c_float()
  1201. current = Nviz_get_current_cplane(self.data)
  1202. Nviz_get_cplane_rotation(self.data, current, byref(x), byref(y), byref(z))
  1203. return x.value, y.value, z.value
  1204. def GetCPlaneTranslation(self):
  1205. """!Returns translation parameters of current cutting plane"""
  1206. x, y, z = c_float(), c_float(), c_float()
  1207. current = Nviz_get_current_cplane(self.data)
  1208. Nviz_get_cplane_translation(self.data, current, byref(x), byref(y), byref(z))
  1209. return x.value, y.value, z.value
  1210. def SetCPlaneRotation(self, x, y, z):
  1211. """!Set current clip plane rotation
  1212. @param x,y,z rotation parameters
  1213. """
  1214. current = Nviz_get_current_cplane(self.data)
  1215. Nviz_set_cplane_rotation(self.data, current, x, y, z)
  1216. Nviz_draw_cplane(self.data, -1, -1)
  1217. def SetCPlaneTranslation(self, x, y, z):
  1218. """!Set current clip plane translation
  1219. @param x,y,z translation parameters
  1220. """
  1221. current = Nviz_get_current_cplane(self.data)
  1222. Nviz_set_cplane_translation(self.data, current, x, y, z)
  1223. Nviz_draw_cplane(self.data, -1, -1)
  1224. Debug.msg(3, "Nviz::SetCPlaneTranslation(): id=%d, x=%f, y=%f, z=%f",
  1225. current, x, y, z)
  1226. def SetCPlaneInteractively(self, x, y):
  1227. current = Nviz_get_current_cplane(self.data)
  1228. ret = Nviz_set_cplane_here(self.data, current, x, y)
  1229. if ret:
  1230. Nviz_draw_cplane(self.data, -1, -1)
  1231. x, y, z = self.GetCPlaneTranslation()
  1232. return x, y, z
  1233. else:
  1234. return None, None, None
  1235. def SelectCPlane(self, index):
  1236. """!Select cutting plane
  1237. @param index index of cutting plane
  1238. """
  1239. Nviz_on_cplane(self.data, index)
  1240. def UnselectCPlane(self, index):
  1241. """!Unselect cutting plane
  1242. @param index index of cutting plane
  1243. """
  1244. Nviz_off_cplane(self.data, index)
  1245. def SetFenceColor(self, index):
  1246. """!Select current cutting plane
  1247. @param index type of fence - from 0 (off) to 4
  1248. """
  1249. Nviz_set_fence_color(self.data, index)
  1250. def GetXYRange(self):
  1251. """!Get xy range"""
  1252. return Nviz_get_xyrange(self.data)
  1253. def GetZRange(self):
  1254. """!Get z range"""
  1255. min, max = c_float(), c_float()
  1256. Nviz_get_zrange(self.data, byref(min), byref(max))
  1257. return min.value, max.value
  1258. def SaveToFile(self, filename, width = 20, height = 20, itype = 'ppm'):
  1259. """!Save current GL screen to ppm/tif file
  1260. @param filename file name
  1261. @param width image width
  1262. @param height image height
  1263. @param itype image type ('ppm' or 'tif')
  1264. """
  1265. widthOrig = self.width
  1266. heightOrig = self.height
  1267. self.ResizeWindow(width, height)
  1268. GS_clear(Nviz_get_bgcolor(self.data))
  1269. self.Draw(False, -1)
  1270. if itype == 'ppm':
  1271. GS_write_ppm(filename)
  1272. else:
  1273. GS_write_tif(filename)
  1274. self.ResizeWindow(widthOrig, heightOrig)
  1275. def DrawLightingModel(self):
  1276. """!Draw lighting model"""
  1277. if self.showLight:
  1278. Nviz_draw_model(self.data)
  1279. def DrawFringe(self):
  1280. """!Draw fringe"""
  1281. Nviz_draw_fringe(self.data)
  1282. def SetFringe(self, sid, color, elev, nw = False, ne = False, sw = False, se = False):
  1283. """!Set fringe
  1284. @param sid surface id
  1285. @param color color
  1286. @param elev elevation (height)
  1287. @param nw,ne,sw,se fringe edges (turn on/off)
  1288. """
  1289. scolor = str(color[0]) + ':' + str(color[1]) + ':' + str(color[2])
  1290. Nviz_set_fringe(self.data,
  1291. sid, Nviz_color_from_str(scolor),
  1292. elev, int(nw), int(ne), int(sw), int(se))
  1293. def DrawArrow(self):
  1294. """!Draw north arrow
  1295. """
  1296. return Nviz_draw_arrow(self.data)
  1297. def SetArrow(self, sx, sy, size, color):
  1298. """!Set north arrow from canvas coordinates
  1299. @param sx,sy canvas coordinates
  1300. @param size arrow length
  1301. @param color arrow color
  1302. """
  1303. return Nviz_set_arrow(self.data, sx, sy, size, Nviz_color_from_str(color))
  1304. def DeleteArrow(self):
  1305. """!Delete north arrow
  1306. """
  1307. Nviz_delete_arrow(self.data)
  1308. def SetScalebar(self, id, sx, sy, size, color):
  1309. """!Set scale bar from canvas coordinates
  1310. @param sx,sy canvas coordinates
  1311. @param id scale bar id
  1312. @param size scale bar length
  1313. @param color scale bar color
  1314. """
  1315. return Nviz_set_scalebar(self.data, id, sx, sy, size, Nviz_color_from_str(color))
  1316. def DrawScalebar(self):
  1317. """!Draw scale bar
  1318. """
  1319. return Nviz_draw_scalebar(self.data)
  1320. def DeleteScalebar(self, id):
  1321. """!Delete scalebar
  1322. """
  1323. Nviz_delete_scalebar(self.data, id)
  1324. def GetPointOnSurface(self, sx, sy):
  1325. """!Get point on surface
  1326. @param sx,sy canvas coordinates (LL)
  1327. """
  1328. sid = c_int()
  1329. x = c_float()
  1330. y = c_float()
  1331. z = c_float()
  1332. Debug.msg(5, "Nviz::GetPointOnSurface(): sx=%d sy=%d" % (sx, sy))
  1333. num = GS_get_selected_point_on_surface(sx, sy, byref(sid), byref(x), byref(y), byref(z))
  1334. if num == 0:
  1335. return (None, None, None, None)
  1336. return (sid.value, x.value, y.value, z.value)
  1337. def QueryMap(self, sx, sy):
  1338. """!Query surface map
  1339. @param sx,sy canvas coordinates (LL)
  1340. """
  1341. sid, x, y, z = self.GetPointOnSurface(sx, sy)
  1342. if not sid:
  1343. return None
  1344. catstr = create_string_buffer(256)
  1345. valstr = create_string_buffer(256)
  1346. GS_get_cat_at_xy(sid, ATT_TOPO, catstr, x, y)
  1347. GS_get_val_at_xy(sid, ATT_COLOR, valstr, x, y)
  1348. return { 'id' : sid,
  1349. 'x' : x,
  1350. 'y' : y,
  1351. 'z' : z,
  1352. 'elevation' : catstr.value.replace('(', '').replace(')', ''),
  1353. 'color' : valstr.value }
  1354. def GetDistanceAlongSurface(self, sid, p1, p2, useExag = True):
  1355. """!Get distance measured along surface"""
  1356. d = c_float()
  1357. GS_get_distance_alongsurf(sid, p1[0], p1[1], p2[0], p2[1],
  1358. byref(d), int(useExag))
  1359. return d.value
  1360. def GetRotationParameters(self, dx, dy):
  1361. """!Get rotation parameters (angle, x, y, z axes)
  1362. @param dx,dy difference from previous mouse drag event
  1363. """
  1364. modelview = (c_double * 16)()
  1365. Nviz_get_modelview(byref(modelview))
  1366. angle = sqrt(dx*dx+dy*dy)/float(self.width+1)*180.0
  1367. m = []
  1368. row = []
  1369. for i, item in enumerate(modelview):
  1370. row.append(item)
  1371. if (i+1) % 4 == 0:
  1372. m.append(row)
  1373. row = []
  1374. inv = matrix(m).I
  1375. ax, ay, az = dy, dx, 0.
  1376. x = inv[0,0]*ax + inv[1,0]*ay + inv[2,0]*az
  1377. y = inv[0,1]*ax + inv[1,1]*ay + inv[2,1]*az
  1378. z = inv[0,2]*ax + inv[1,2]*ay + inv[2,2]*az
  1379. return angle, x, y, z
  1380. def Rotate(self, angle, x, y, z):
  1381. """!Set rotation parameters
  1382. Rotate scene (difference from current state).
  1383. @param angle angle
  1384. @param x,y,z axis coordinate
  1385. """
  1386. Nviz_set_rotation(angle, x, y, z)
  1387. def UnsetRotation(self):
  1388. """!Stop rotating the scene"""
  1389. Nviz_unset_rotation()
  1390. def ResetRotation(self):
  1391. """!Reset scene rotation"""
  1392. Nviz_init_rotation()
  1393. def GetRotationMatrix(self):
  1394. """!Get rotation matrix"""
  1395. matrix = (c_double * 16)()
  1396. GS_get_rotation_matrix(byref(matrix))
  1397. returnMatrix = []
  1398. for item in matrix:
  1399. returnMatrix.append(item)
  1400. return returnMatrix
  1401. def SetRotationMatrix(self, matrix):
  1402. """!Set rotation matrix"""
  1403. mtrx = (c_double * 16)()
  1404. for i in range(len(matrix)):
  1405. mtrx[i] = matrix[i]
  1406. GS_set_rotation_matrix(byref(mtrx))
  1407. def Start2D(self):
  1408. Nviz_set_2D(self.width, self.height)
  1409. class Texture(object):
  1410. """!Class representing OpenGL texture"""
  1411. def __init__(self, filepath, overlayId, coords):
  1412. """!Load image to texture
  1413. @param filepath path to image file
  1414. @param overlayId id of overlay (1 for legend, 101 and more for text)
  1415. @param coords image coordinates
  1416. """
  1417. self.path = filepath
  1418. self.image = wx.Image(filepath, wx.BITMAP_TYPE_ANY)
  1419. self.width = self.image.GetWidth()
  1420. self.height = self.image.GetHeight()
  1421. self.id = overlayId
  1422. self.coords = list(coords)
  1423. self.bounds = wx.Rect()
  1424. self.active = True
  1425. # alpha needs to be initialized
  1426. if not self.image.HasAlpha():
  1427. self.image.InitAlpha()
  1428. # resize image to match 2^n
  1429. self.Resize()
  1430. # check max texture size
  1431. maxSize = c_int()
  1432. Nviz_get_max_texture(byref(maxSize))
  1433. self.maxSize = maxSize.value
  1434. if self.maxSize < self.width or self.maxSize < self.height:
  1435. # TODO: split up image
  1436. self.textureId = None
  1437. else:
  1438. self.textureId = self.Load()
  1439. def __del__(self):
  1440. """!Delete texture"""
  1441. if self.textureId:
  1442. Nviz_del_texture(self.textureId)
  1443. grass.try_remove(self.path)
  1444. def Resize(self):
  1445. """!Resize image to match 2^n"""
  1446. n = m = 1
  1447. while self.width > pow(2,n):
  1448. n += 1
  1449. while self.height > pow(2,m):
  1450. m += 1
  1451. self.image.Resize(size = (pow(2,n), pow(2,m)), pos = (0, 0))
  1452. self.width = self.image.GetWidth()
  1453. self.height = self.image.GetHeight()
  1454. def Load(self):
  1455. """!Load image to texture"""
  1456. if self.image.HasAlpha():
  1457. bytesPerPixel = 4
  1458. else:
  1459. bytesPerPixel = 3
  1460. bytes = bytesPerPixel * self.width * self.height
  1461. rev_val = self.height - 1
  1462. im = (c_ubyte * bytes)()
  1463. bytes3 = 3 * self.width * self.height
  1464. bytes1 = self.width * self.height
  1465. imageData = struct.unpack(str(bytes3) + 'B', self.image.GetData())
  1466. if self.image.HasAlpha():
  1467. alphaData = struct.unpack(str(bytes1) + 'B', self.image.GetAlphaData())
  1468. # this takes too much time
  1469. wx.BeginBusyCursor()
  1470. for i in range(self.height):
  1471. for j in range(self.width):
  1472. im[(j + i * self.width) * bytesPerPixel + 0] = imageData[( j + (rev_val - i) * self.width) * 3 + 0]
  1473. im[(j + i * self.width) * bytesPerPixel + 1] = imageData[( j + (rev_val - i) * self.width) * 3 + 1]
  1474. im[(j + i * self.width) * bytesPerPixel + 2] = imageData[( j + (rev_val - i) * self.width) * 3 + 2]
  1475. if self.image.HasAlpha():
  1476. im[(j + i * self.width) * bytesPerPixel + 3] = alphaData[( j + (rev_val - i) * self.width)]
  1477. wx.EndBusyCursor()
  1478. id = Nviz_load_image(im, self.width, self.height, self.image.HasAlpha())
  1479. return id
  1480. def Draw(self):
  1481. """!Draw texture as an image"""
  1482. Nviz_draw_image(self.coords[0], self.coords[1], self.width, self.height, self.textureId)
  1483. def SetBounds(self, rect):
  1484. """!Set Bounding Rectangle"""
  1485. self.bounds = rect
  1486. def HitTest(self, x, y, radius):
  1487. copy = wx.Rect(*self.bounds)
  1488. copy.Inflate(radius, radius)
  1489. return copy.ContainsXY(x, y)
  1490. def MoveTexture(self, dx, dy):
  1491. """!Move texture on the screen"""
  1492. self.coords[0] += dx
  1493. self.coords[1] += dy
  1494. self.bounds.OffsetXY(dx, dy)
  1495. def SetCoords(self, coords):
  1496. """!Set coordinates"""
  1497. dx = coords[0] - self.coords[0]
  1498. dy = coords[1] - self.coords[1]
  1499. self.MoveTexture(dx, dy)
  1500. def GetId(self):
  1501. """!Returns image id."""
  1502. return self.id
  1503. def SetActive(self, active = True):
  1504. self.active = active
  1505. def IsActive(self):
  1506. return self.active
  1507. class ImageTexture(Texture):
  1508. """!Class representing OpenGL texture as an overlay image"""
  1509. def __init__(self, filepath, overlayId, coords, cmd):
  1510. """!Load image to texture
  1511. @param filepath path to image file
  1512. @param overlayId id of overlay (1 for legend)
  1513. @param coords image coordinates
  1514. @param cmd d.legend command
  1515. """
  1516. Texture.__init__(self, filepath = filepath, overlayId = overlayId, coords = coords)
  1517. self.cmd = cmd
  1518. def GetCmd(self):
  1519. """!Returns overlay command."""
  1520. return self.cmd
  1521. def Corresponds(self, item):
  1522. return sorted(self.GetCmd()) == sorted(item.GetCmd())
  1523. class TextTexture(Texture):
  1524. """!Class representing OpenGL texture as a text label"""
  1525. def __init__(self, filepath, overlayId, coords, textDict):
  1526. """!Load image to texture
  1527. @param filepath path to image file
  1528. @param overlayId id of overlay (101 and more for text)
  1529. @param coords text coordinates
  1530. @param textDict text properties
  1531. """
  1532. Texture.__init__(self, filepath = filepath, overlayId = overlayId, coords = coords)
  1533. self.textDict = textDict
  1534. def GetTextDict(self):
  1535. """!Returns text properties."""
  1536. return self.textDict
  1537. def Corresponds(self, item):
  1538. t = self.GetTextDict()
  1539. for prop in t.keys():
  1540. if prop in ('coords','bbox'): continue
  1541. if t[prop] != item[prop]:
  1542. return False
  1543. return True