nviztask.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  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, CmdToTuple, _
  19. from grass.script import task as gtask
  20. class NvizTask:
  21. def __init__(self):
  22. self.task = None
  23. self.filename = None
  24. self.region = {}
  25. def Load(self, filename):
  26. self.task = gtask.grassTask("m.nviz.image")
  27. self.filename = filename
  28. try:
  29. gxwXml = ProcessWorkspaceFile(etree.parse(self.filename))
  30. except Exception:
  31. raise GException(_("Reading workspace file <%s> failed.\n"
  32. "Invalid file, unable to parse XML document.") % filename)
  33. # for display in gxwXml.displays:
  34. # pprint(display)
  35. # for layer in gxwXml.layers:
  36. # pprint(layer)
  37. # pprint(gxwXml.nviz_state)
  38. if not gxwXml.nviz_state:
  39. raise GException(_("No 3d view information in workspace file <%s>.") % self.filename)
  40. self._getExtent(gxwXml)
  41. self._processState(gxwXml.nviz_state)
  42. self._processLayers(gxwXml.layers)
  43. def _getExtent(self, root):
  44. for display in root.displays:
  45. if display['viewMode'] == '3d':
  46. self.region['w'], self.region['s'],\
  47. self.region['e'], self.region['n'],\
  48. self.region['b'], self.region['t'] = display['extent']
  49. self.region['tbres'] = display['tbres']
  50. def _processLayers(self, layers):
  51. for layer in layers:
  52. if not layer['checked']:
  53. continue
  54. if not layer['nviz']:
  55. continue
  56. layerName, found = GetLayerNameFromCmd(layer['cmd'], fullyQualified=False,
  57. param='map')
  58. if not found:
  59. continue
  60. if 'surface' in layer['nviz']:
  61. self._processSurface(layer['nviz']['surface'], mapName=layerName)
  62. if 'volume' in layer['nviz']:
  63. self._processVolume(layer['nviz']['volume'], mapName=layerName)
  64. def _processSurface(self, surface, mapName):
  65. self._setMultiTaskParam('elevation_map', mapName)
  66. # attributes like color, shine, transparency
  67. attributes = ('color', 'shine', 'transp') # mask missing
  68. parameters = (('color_map', 'color'),
  69. ('shininess_map', 'shininess_value'),
  70. ('transparency_map', 'transparency_value'))
  71. for attr, params in zip(attributes, parameters):
  72. mapname = None
  73. const = None
  74. if attr in surface['attribute']:
  75. if surface['attribute'][attr]['map']:
  76. mapname = surface['attribute'][attr]['value']
  77. else:
  78. const = surface['attribute'][attr]['value']
  79. else:
  80. if attr == 'transp':
  81. const = 0
  82. elif attr == 'color':
  83. mapname = mapName
  84. if mapname:
  85. self._setMultiTaskParam(params[0], mapname)
  86. else:
  87. self._setMultiTaskParam(params[1], const)
  88. # draw mode
  89. for mode in ('mode', 'shading', 'style'):
  90. value = surface['draw']['mode']['desc'][mode]
  91. self._setMultiTaskParam(mode, value)
  92. # wire color
  93. value = surface['draw']['wire-color']['value']
  94. self._setMultiTaskParam('wire_color', value)
  95. # resolution
  96. for mode1, mode2 in zip(('coarse', 'fine'), ('resolution_coarse', 'resolution_fine')):
  97. value = surface['draw']['resolution'][mode1]
  98. self._setMultiTaskParam(mode2, value)
  99. # position
  100. pos = []
  101. for coor in ('x', 'y', 'z'):
  102. pos.append(str(surface['position'][coor]))
  103. value = ','.join(pos)
  104. self._setMultiTaskParam('surface_position', value)
  105. def _processVolume(self, volume, mapName):
  106. self._setMultiTaskParam('volume', mapName)
  107. if volume['draw']['box']['enabled']:
  108. self.task.set_flag('b', True)
  109. # isosurfaces
  110. isosurfaces = volume['isosurface']
  111. if isosurfaces:
  112. res_value = volume['draw']['resolution']['isosurface']['value']
  113. self._setMultiTaskParam('volume_resolution', res_value)
  114. for isosurface in isosurfaces:
  115. attributes = ('topo', 'color', 'shine', 'transp')
  116. parameters = ((None, 'isosurf_level'),
  117. ('isosurf_color_map', 'isosurf_color_value'),
  118. ('isosurf_shininess_map', 'isosurf_shininess_value'),
  119. ('isosurf_transparency_map', 'isosurf_transparency_value'))
  120. for attr, params in zip(attributes, parameters):
  121. mapname = None
  122. const = None
  123. if attr in isosurface:
  124. if isosurface[attr]['map']:
  125. mapname = isosurface[attr]['value']
  126. else:
  127. const = float(isosurface[attr]['value'])
  128. else:
  129. if attr == 'transp':
  130. const = 0
  131. elif attr == 'color':
  132. mapname = mapName
  133. if mapname:
  134. self._setMultiTaskParam(params[0], mapname)
  135. else:
  136. if attr == 'topo':
  137. # TODO: we just assume it's the first volume, what to do else?
  138. self._setMultiTaskParam(params[1], '1:' + str(const))
  139. else:
  140. self._setMultiTaskParam(params[1], const)
  141. if isosurface['inout']['value']:
  142. self.task.set_flag('n', True)
  143. # slices
  144. slices = volume['slice']
  145. if slices:
  146. res_value = volume['draw']['resolution']['slice']['value']
  147. self._setMultiTaskParam('volume_resolution', res_value)
  148. for slice_ in slices:
  149. self._setMultiTaskParam('slice_transparency', slice_['transp']['value'])
  150. axis = slice_['position']['axis']
  151. self._setMultiTaskParam('slice', '1:' + 'xyz'[axis])
  152. pos = slice_['position']
  153. coords = pos['x1'], pos['x2'], pos['y1'], pos['y2'], pos['z1'], pos['z2']
  154. self._setMultiTaskParam('slice_position', ','.join([str(c) for c in coords]))
  155. # position
  156. pos = []
  157. for coor in ('x', 'y', 'z'):
  158. pos.append(str(volume['position'][coor]))
  159. value = ','.join(pos)
  160. self._setMultiTaskParam('volume_position', value)
  161. def _processState(self, state):
  162. color = state['view']['background']['color']
  163. self.task.set_param('bgcolor', self._join(color, delim=':'))
  164. self.task.set_param('position', self._join((state['view']['position']['x'],
  165. state['view']['position']['y'])))
  166. self.task.set_param('height', state['iview']['height']['value'])
  167. self.task.set_param('perspective', state['view']['persp']['value'])
  168. self.task.set_param('twist', state['view']['twist']['value'])
  169. # TODO: fix zexag
  170. self.task.set_param('zexag', state['view']['z-exag']['value'])
  171. self.task.set_param('focus', self._join((state['iview']['focus']['x'],
  172. state['iview']['focus']['y'],
  173. state['iview']['focus']['z'])))
  174. self.task.set_param('light_position', self._join((state['light']['position']['x'],
  175. state['light']['position']['y'],
  176. state['light']['position']['z'] / 100.)))
  177. color = state['light']['color'][:3]
  178. self.task.set_param('light_color', self._join(color, delim=':'))
  179. self.task.set_param('light_brightness', int(state['light']['bright']))
  180. self.task.set_param('light_ambient', state['light']['ambient'])
  181. def _setMultiTaskParam(self, param, value):
  182. last = self.task.get_param(param)['value']
  183. self.task.set_param(param, self._join((last, value)))
  184. def _join(self, toJoin, delim=','):
  185. toJoin = filter(self._ignore, toJoin)
  186. return delim.join(map(str, toJoin))
  187. def _ignore(self, value):
  188. if value == '' or value is None:
  189. return False
  190. else:
  191. return True
  192. def ListMapParameters(self):
  193. # params = self.task.get_list_params()
  194. # parameter with 'map' name
  195. # params = filter(lambda x: 'map' in x, params)
  196. return ('elevation_map', 'color_map', 'vline', 'vpoint', 'volume')
  197. def GetCommandSeries(self, layerList, paramName):
  198. commands = []
  199. if not self.task:
  200. return commands
  201. if len(layerList) > 1:
  202. raise GException(_("Please add only one layer in the list."))
  203. return
  204. layer = layerList[0]
  205. if hasattr(layer, 'maps'):
  206. series = layer.maps
  207. else:
  208. raise GException(_("No map series nor space-time dataset is added."))
  209. for value in series:
  210. self.task.set_param(paramName, value)
  211. # FIXME: we assume we want always default color map
  212. if paramName == 'elevation_map':
  213. self.task.set_param('color_map', '')
  214. if paramName == 'volume':
  215. self.task.set_param('isosurf_color_map', '')
  216. self.task.set_flag('overwrite', True)
  217. self.task.set_param('output', 'tobechanged')
  218. cmd = self.task.get_cmd(ignoreErrors=False, ignoreRequired=False, ignoreDefault=True)
  219. commands.append(cmd)
  220. return commands
  221. def GetCommand(self):
  222. if not self.task:
  223. return None
  224. self.task.set_flag('overwrite', True)
  225. self.task.set_param('output', 'tobechanged')
  226. cmd = self.task.get_cmd(ignoreErrors=False, ignoreRequired=False, ignoreDefault=True)
  227. return CmdToTuple(cmd)
  228. def GetRegion(self):
  229. return self.region
  230. def test():
  231. nviz = NvizTask('/home/anna/testy/nviz/t12.gxw')
  232. # nviz = NvizState('/home/anna/testy/nviz/t3.gxw')
  233. # cmd = nviz.GetCommand()
  234. cmds = nviz.GetCommandSeries(['aspect', 'elevation'], 'color_map')
  235. for cmd in cmds:
  236. print cmd
  237. returncode, message = RunCommand(getErrorMsg=True, prog=cmd[0], **cmd[1])
  238. print returncode, message
  239. if __name__ == '__main__':
  240. test()