wxnviz.py 60 KB

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