wxnviz.py 61 KB

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