nviztask.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. """
  2. @package animation.nviztask
  3. @brief Conversion from workspace file to m.nviz.image command
  4. Classes:
  5. - nviztask::NvizTask
  6. (C) 2013 by the GRASS Development Team
  7. This program is free software under the GNU General Public License
  8. (>=v2). Read the file COPYING that comes with GRASS for details.
  9. @author Anna Petrasova <kratochanna gmail.com>
  10. """
  11. import os
  12. try:
  13. import xml.etree.ElementTree as etree
  14. except ImportError:
  15. import elementtree.ElementTree as etree # Python <= 2.4
  16. from core.workspace import ProcessWorkspaceFile
  17. from core.gcmd import RunCommand, GException
  18. from core.utils import GetLayerNameFromCmd, _
  19. from grass.script import task as gtask
  20. from core.settings import UserSettings
  21. class NvizTask:
  22. def __init__(self):
  23. self.task = None
  24. self.filename = None
  25. self.region = {}
  26. def Load(self, filename):
  27. self.task = gtask.grassTask("m.nviz.image")
  28. self.filename = filename
  29. try:
  30. gxwXml = ProcessWorkspaceFile(etree.parse(self.filename))
  31. except Exception:
  32. raise GException(_("Reading workspace file <%s> failed.\n"
  33. "Invalid file, unable to parse XML document.") % filename)
  34. # for display in gxwXml.displays:
  35. # pprint(display)
  36. # for layer in gxwXml.layers:
  37. # pprint(layer)
  38. # pprint(gxwXml.nviz_state)
  39. if not gxwXml.nviz_state:
  40. raise GException(
  41. _("No 3d view information in workspace file <%s>.") %
  42. self.filename)
  43. self._getExtent(gxwXml)
  44. self._processState(gxwXml.nviz_state)
  45. self._processLayers(gxwXml.layers)
  46. def _getExtent(self, root):
  47. for display in root.displays:
  48. if display['viewMode'] == '3d':
  49. self.region['w'], self.region['s'],\
  50. self.region['e'], self.region['n'],\
  51. self.region['b'], self.region['t'] = display['extent']
  52. self.region['tbres'] = display['tbres']
  53. def _processLayers(self, layers):
  54. for layer in layers:
  55. if not layer['checked']:
  56. continue
  57. if not layer['nviz']:
  58. continue
  59. layerName, found = GetLayerNameFromCmd(
  60. layer['cmd'], fullyQualified=False, param='map')
  61. if not found:
  62. continue
  63. if 'surface' in layer['nviz']:
  64. self._processSurface(
  65. layer['nviz']['surface'],
  66. mapName=layerName)
  67. if 'volume' in layer['nviz']:
  68. self._processVolume(layer['nviz']['volume'], mapName=layerName)
  69. if 'vector' in layer['nviz']:
  70. if 'points' in layer['nviz']['vector']:
  71. self._processPoints(
  72. layer['nviz']['vector']['points'],
  73. mapName=layerName)
  74. def _processSurface(self, surface, mapName):
  75. self._setMultiTaskParam('elevation_map', mapName)
  76. # attributes like color, shine, transparency
  77. attributes = ('color', 'shine', 'transp') # mask missing
  78. parameters = (('color_map', 'color'),
  79. ('shininess_map', 'shininess_value'),
  80. ('transparency_map', 'transparency_value'))
  81. for attr, params in zip(attributes, parameters):
  82. mapname = None
  83. const = None
  84. if attr in surface['attribute']:
  85. if surface['attribute'][attr]['map']:
  86. mapname = surface['attribute'][attr]['value']
  87. else:
  88. const = surface['attribute'][attr]['value']
  89. else:
  90. if attr == 'transp':
  91. const = 0
  92. elif attr == 'color':
  93. mapname = mapName
  94. if mapname:
  95. self._setMultiTaskParam(params[0], mapname)
  96. else:
  97. self._setMultiTaskParam(params[1], const)
  98. # draw mode
  99. for mode in ('mode', 'shading', 'style'):
  100. value = surface['draw']['mode']['desc'][mode]
  101. self._setMultiTaskParam(mode, value)
  102. # wire color
  103. value = surface['draw']['wire-color']['value']
  104. self._setMultiTaskParam('wire_color', value)
  105. # resolution
  106. for mode1, mode2 in zip(
  107. ('coarse', 'fine'),
  108. ('resolution_coarse', 'resolution_fine')):
  109. value = surface['draw']['resolution'][mode1]
  110. self._setMultiTaskParam(mode2, value)
  111. # position
  112. pos = []
  113. for coor in ('x', 'y', 'z'):
  114. pos.append(str(surface['position'][coor]))
  115. value = ','.join(pos)
  116. self._setMultiTaskParam('surface_position', value)
  117. def _processPoints(self, points, mapName):
  118. for attrib in ('color', 'size', 'width'):
  119. if attrib in points:
  120. val = points[attrib]['value']
  121. self._setMultiTaskParam('vpoint_' + attrib, str(val))
  122. if 'height' in points:
  123. height = points['height']['value']
  124. self._setMultiTaskParam(
  125. 'vpoint_position',
  126. '0,0,{h}'.format(
  127. h=height))
  128. if 'marker' in points:
  129. marker = list(
  130. UserSettings.Get(
  131. group='nviz', key='vector', subkey=[
  132. 'points', 'marker'], settings_type='internal'))[
  133. points['marker']['value']]
  134. self._setMultiTaskParam('vpoint_marker', marker)
  135. if 'mode' in points:
  136. if points['mode']['type'] == '3d':
  137. self._setMultiTaskParam('vpoint_mode', '3D')
  138. else:
  139. self._setMultiTaskParam('vpoint_mode', 'surface')
  140. def _processVolume(self, volume, mapName):
  141. self._setMultiTaskParam('volume', mapName)
  142. if volume['draw']['box']['enabled']:
  143. self.task.set_flag('b', True)
  144. # isosurfaces
  145. isosurfaces = volume['isosurface']
  146. if isosurfaces:
  147. res_value = volume['draw']['resolution']['isosurface']['value']
  148. self._setMultiTaskParam('volume_resolution', res_value)
  149. for isosurface in isosurfaces:
  150. attributes = ('topo', 'color', 'shine', 'transp')
  151. parameters = (
  152. (None, 'isosurf_level'),
  153. ('isosurf_color_map', 'isosurf_color_value'),
  154. ('isosurf_shininess_map', 'isosurf_shininess_value'),
  155. ('isosurf_transparency_map', 'isosurf_transparency_value'))
  156. for attr, params in zip(attributes, parameters):
  157. mapname = None
  158. const = None
  159. if attr in isosurface:
  160. if isosurface[attr]['map']:
  161. mapname = isosurface[attr]['value']
  162. else:
  163. const = float(isosurface[attr]['value'])
  164. else:
  165. if attr == 'transp':
  166. const = 0
  167. elif attr == 'color':
  168. mapname = mapName
  169. if mapname:
  170. self._setMultiTaskParam(params[0], mapname)
  171. else:
  172. if attr == 'topo':
  173. # TODO: we just assume it's the first volume, what
  174. # to do else?
  175. self._setMultiTaskParam(
  176. params[1], '1:' + str(const))
  177. else:
  178. self._setMultiTaskParam(params[1], const)
  179. if isosurface['inout']['value']:
  180. self.task.set_flag('n', True)
  181. # slices
  182. slices = volume['slice']
  183. if slices:
  184. res_value = volume['draw']['resolution']['slice']['value']
  185. self._setMultiTaskParam('volume_resolution', res_value)
  186. for slice_ in slices:
  187. self._setMultiTaskParam(
  188. 'slice_transparency', slice_['transp']['value'])
  189. axis = slice_['position']['axis']
  190. self._setMultiTaskParam('slice', '1:' + 'xyz'[axis])
  191. pos = slice_['position']
  192. coords = pos['x1'], pos['x2'], pos[
  193. 'y1'], pos['y2'], pos['z1'], pos['z2']
  194. self._setMultiTaskParam('slice_position', ','.join(
  195. [str(c) for c in coords]))
  196. # position
  197. pos = []
  198. for coor in ('x', 'y', 'z'):
  199. pos.append(str(volume['position'][coor]))
  200. value = ','.join(pos)
  201. self._setMultiTaskParam('volume_position', value)
  202. def _processState(self, state):
  203. color = state['view']['background']['color']
  204. self.task.set_param('bgcolor', self._join(color, delim=':'))
  205. self.task.set_param(
  206. 'position', self._join(
  207. (state['view']['position']['x'],
  208. state['view']['position']['y'])))
  209. self.task.set_param('height', state['iview']['height']['value'])
  210. self.task.set_param('perspective', state['view']['persp']['value'])
  211. self.task.set_param('twist', state['view']['twist']['value'])
  212. # TODO: fix zexag
  213. self.task.set_param('zexag', state['view']['z-exag']['value'])
  214. self.task.set_param(
  215. 'focus', self._join(
  216. (state['iview']['focus']['x'],
  217. state['iview']['focus']['y'],
  218. state['iview']['focus']['z'])))
  219. self.task.set_param(
  220. 'light_position', self._join(
  221. (state['light']['position']['x'],
  222. state['light']['position']['y'],
  223. state['light']['position']['z'] / 100.)))
  224. color = state['light']['color'][:3]
  225. self.task.set_param('light_color', self._join(color, delim=':'))
  226. self.task.set_param('light_brightness', int(state['light']['bright']))
  227. self.task.set_param('light_ambient', state['light']['ambient'])
  228. def _setMultiTaskParam(self, param, value):
  229. last = self.task.get_param(param)['value']
  230. self.task.set_param(param, self._join((last, value)))
  231. def _join(self, toJoin, delim=','):
  232. toJoin = filter(self._ignore, toJoin)
  233. return delim.join(map(str, toJoin))
  234. def _ignore(self, value):
  235. if value == '' or value is None:
  236. return False
  237. else:
  238. return True
  239. def ListMapParameters(self):
  240. # params = self.task.get_list_params()
  241. # parameter with 'map' name
  242. # params = filter(lambda x: 'map' in x, params)
  243. return ('elevation_map', 'color_map', 'vline', 'vpoint', 'volume')
  244. def GetCommandSeries(self, layerList, paramName):
  245. commands = []
  246. if not self.task:
  247. return commands
  248. if len(layerList) > 1:
  249. raise GException(_("Please add only one layer in the list."))
  250. return
  251. layer = layerList[0]
  252. if hasattr(layer, 'maps'):
  253. series = layer.maps
  254. else:
  255. raise GException(
  256. _("No map series nor space-time dataset is added."))
  257. for value in series:
  258. self.task.set_param(paramName, value)
  259. # FIXME: we assume we want always default color map
  260. if paramName == 'elevation_map':
  261. self.task.set_param('color_map', '')
  262. if paramName == 'volume':
  263. self.task.set_param('isosurf_color_map', '')
  264. self.task.set_flag('overwrite', True)
  265. self.task.set_param('output', 'tobechanged')
  266. cmd = self.task.get_cmd(
  267. ignoreErrors=False,
  268. ignoreRequired=False,
  269. ignoreDefault=True)
  270. commands.append(cmd)
  271. return commands
  272. def GetCommand(self):
  273. if not self.task:
  274. return None
  275. self.task.set_flag('overwrite', True)
  276. self.task.set_param('output', 'tobechanged')
  277. cmd = self.task.get_cmd(
  278. ignoreErrors=False,
  279. ignoreRequired=False,
  280. ignoreDefault=True)
  281. return gtask.cmdlist_to_tuple(cmd)
  282. def GetRegion(self):
  283. return self.region
  284. def test():
  285. nviz = NvizTask('/home/anna/testy/nviz/t12.gxw')
  286. # nviz = NvizState('/home/anna/testy/nviz/t3.gxw')
  287. # cmd = nviz.GetCommand()
  288. cmds = nviz.GetCommandSeries(['aspect', 'elevation'], 'color_map')
  289. for cmd in cmds:
  290. print cmd
  291. returncode, message = RunCommand(
  292. getErrorMsg=True, prog=cmd[0], **cmd[1])
  293. print returncode, message
  294. if __name__ == '__main__':
  295. test()