wxnviz.py 60 KB

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