wxnviz.py 60 KB

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