GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
animation.py
Go to the documentation of this file.
1 """!
2 @package nviz.animation
3 
4 @brief Nviz (3D view) animation
5 
6 Classes:
7  - animation::Animation
8 
9 (C) 2011 by the GRASS Development Team
10 
11 This program is free software under the GNU General Public License
12 (>=v2). Read the file COPYING that comes with GRASS for details.
13 
14 @author Anna Kratochvilova <kratochanna gmail.com>
15 """
16 
17 import os
18 import copy
19 
20 import wx
21 from wx.lib.newevent import NewEvent
22 
23 wxAnimationFinished, EVT_ANIM_FIN = NewEvent()
24 wxAnimationUpdateIndex, EVT_ANIM_UPDATE_IDX = NewEvent()
25 
26 class Animation:
27  """!Class represents animation as a sequence of states (views).
28  It enables to record, replay the sequence and finally generate
29  all image files. Recording and replaying is based on timer events.
30  There is no frame interpolation like in the Tcl/Tk based Nviz.
31  """
32  def __init__(self, mapWindow, timer):
33  """!Animation constructor
34 
35  @param mapWindow glWindow where rendering takes place
36  @param timer timer for recording and replaying
37  """
38 
39  self.animationList = [] # view states
40  self.timer = timer
41  self.mapWindow = mapWindow
42  self.actions = {'record': self.Record,
43  'play': self.Play}
44  self.formats = ['ppm', 'tif'] # currently supported formats
45  self.mode = 'record' # current mode (record, play, save)
46  self.paused = False # recording/replaying paused
47  self.currentFrame = 0 # index of current frame
48  self.fps = 24 # user settings # Frames per second
49 
50  self.stopSaving = False # stop during saving images
51  self.animationSaved = False # current animation saved or not
52 
53  def Start(self):
54  """!Start recording/playing"""
55  self.timer.Start(self.GetInterval())
56 
57  def Pause(self):
58  """!Pause recording/playing"""
59  self.timer.Stop()
60 
61  def Stop(self):
62  """!Stop recording/playing"""
63  self.timer.Stop()
64  self.PostFinishedEvent()
65 
66  def Update(self):
67  """!Record/play next view state (on timer event)"""
68  self.actions[self.mode]()
69 
70  def Record(self):
71  """!Record new view state"""
72  self.animationList.append({'view' : copy.deepcopy(self.mapWindow.view),
73  'iview': copy.deepcopy(self.mapWindow.iview)})
74  self.currentFrame += 1
75  self.PostUpdateIndexEvent(index = self.currentFrame)
76  self.animationSaved = False
77 
78  def Play(self):
79  """!Render next frame"""
80  if not self.animationList:
81  self.Stop()
82  return
83  try:
84  self.IterAnimation()
85  except IndexError:
86  # no more frames
87  self.Stop()
88 
89  def IterAnimation(self):
90  params = self.animationList[self.currentFrame]
91  self.UpdateView(params)
92  self.currentFrame += 1
93 
94  self.PostUpdateIndexEvent(index = self.currentFrame)
95 
96  def UpdateView(self, params):
97  """!Update view data in map window and render"""
98  toolWin = self.mapWindow.GetToolWin()
99  toolWin.UpdateState(view = params['view'], iview = params['iview'])
100 
101  self.mapWindow.UpdateView()
102 
103  self.mapWindow.render['quick'] = True
104  self.mapWindow.Refresh(False)
105 
106  def IsRunning(self):
107  """!Test if timer is running"""
108  return self.timer.IsRunning()
109 
110  def SetMode(self, mode):
111  """!Start animation mode
112 
113  @param mode animation mode (record, play, save)
114  """
115  self.mode = mode
116 
117  def GetMode(self):
118  """!Get animation mode (record, play, save)"""
119  return self.mode
120 
121  def IsPaused(self):
122  """!Test if animation is paused"""
123  return self.paused
124 
125  def SetPause(self, pause):
126  self.paused = pause
127 
128  def Exists(self):
129  """!Returns if an animation has been recorded"""
130  return bool(self.animationList)
131 
132  def GetFrameCount(self):
133  """!Return number of recorded frames"""
134  return len(self.animationList)
135 
136  def Clear(self):
137  """!Clear all records"""
138  self.animationList = []
139  self.currentFrame = 0
140 
141  def GoToFrame(self, index):
142  """!Render frame of given index"""
143  if index >= len(self.animationList):
144  return
145 
146  self.currentFrame = index
147  params = self.animationList[self.currentFrame]
148  self.UpdateView(params)
149 
150  def PostFinishedEvent(self):
151  """!Animation ends"""
152  toolWin = self.mapWindow.GetToolWin()
153  event = wxAnimationFinished(mode = self.mode)
154  wx.PostEvent(toolWin, event)
155 
156  def PostUpdateIndexEvent(self, index):
157  """!Frame index changed, update tool window"""
158  toolWin = self.mapWindow.GetToolWin()
159  event = wxAnimationUpdateIndex(index = index, mode = self.mode)
160  wx.PostEvent(toolWin, event)
161 
162  def StopSaving(self):
163  """!Abort image files generation"""
164  self.stopSaving = True
165 
166  def IsSaved(self):
167  """"!Test if animation has been saved (to images)"""
168  return self.animationSaved
169 
170  def SaveAnimationFile(self, path, prefix, format):
171  """!Generate image files
172 
173  @param path path to direcory
174  @param prefix file prefix
175  @param format index of image file format
176  """
177  w, h = self.mapWindow.GetClientSizeTuple()
178  toolWin = self.mapWindow.GetToolWin()
179 
180  self.currentFrame = 0
181  self.mode = 'save'
182  for params in self.animationList:
183  if not self.stopSaving:
184  self.UpdateView(params)
185  filename = prefix + "_" + str(self.currentFrame) + '.' + self.formats[format]
186  filepath = os.path.join(path, filename)
187  self.mapWindow.SaveToFile(FileName = filepath, FileType = self.formats[format],
188  width = w, height = h)
189  self.currentFrame += 1
190 
191  wx.Yield()
192  toolWin.UpdateFrameIndex(index = self.currentFrame, goToFrame = False)
193  else:
194  self.stopSaving = False
195  break
196  self.animationSaved = True
197  self.PostFinishedEvent()
198 
199  def SetFPS(self, fps):
200  """!Set Frames Per Second value
201  @param fps frames per second
202  """
203  self.fps = fps
204 
205  def GetInterval(self):
206  """!Return timer interval in ms"""
207  return 1000. / self.fps
def PostFinishedEvent
Animation ends.
Definition: animation.py:150
def GetInterval
Return timer interval in ms.
Definition: animation.py:205
def StopSaving
Abort image files generation.
Definition: animation.py:162
def Start
Start recording/playing.
Definition: animation.py:53
def UpdateView
Update view data in map window and render.
Definition: animation.py:96
def Pause
Pause recording/playing.
Definition: animation.py:57
def Play
Render next frame.
Definition: animation.py:78
Class represents animation as a sequence of states (views).
Definition: animation.py:26
def PostUpdateIndexEvent
Frame index changed, update tool window.
Definition: animation.py:156
def IsRunning
Test if timer is running.
Definition: animation.py:106
def SetFPS
Set Frames Per Second value.
Definition: animation.py:199
def Clear
Clear all records.
Definition: animation.py:136
def GoToFrame
Render frame of given index.
Definition: animation.py:141
def Record
Record new view state.
Definition: animation.py:70
def SetMode
Start animation mode.
Definition: animation.py:110
def __init__
Animation constructor.
Definition: animation.py:32
def GetFrameCount
Return number of recorded frames.
Definition: animation.py:132
def Update
Record/play next view state (on timer event)
Definition: animation.py:66
def Exists
Returns if an animation has been recorded.
Definition: animation.py:128
def Stop
Stop recording/playing.
Definition: animation.py:61
def IsPaused
Test if animation is paused.
Definition: animation.py:121
def GetMode
Get animation mode (record, play, save)
Definition: animation.py:117
def SaveAnimationFile
Generate image files.
Definition: animation.py:170