source: anuga_core/source/anuga/visualiser/offline.py @ 3536

Last change on this file since 3536 was 3536, checked in by jack, 18 years ago

Added caching to the offline visualiser.

File size: 4.7 KB
Line 
1from Numeric import array, Float, zeros
2from Scientific.IO.NetCDF import NetCDFFile
3from Tkinter import Button, E, W
4from visualiser import Visualiser
5from vtk import vtkCellArray, vtkPoints, vtkPolyData
6
7class OfflineVisualiser(Visualiser):
8    """A VTK-powered offline visualiser which runs in its own thread.
9    """
10    def __init__(self, source):
11        """The source parameter is assumed to be a NetCDF sww file.
12        """
13        Visualiser.__init__(self, source)
14
15        self.frameNumber = 0
16        fin = NetCDFFile(self.source, 'r')
17        self.maxFrameNumber = fin.variables['time'].shape[0] - 1
18        fin.close()
19
20        self.vtk_heightQuantityCache = []
21        for i in range(self.maxFrameNumber):
22            self.vtk_heightQuantityCache.append({})
23
24    def setup_grid(self):
25        fin = NetCDFFile(self.source, 'r')
26        self.vtk_cells = vtkCellArray()
27        N_tri = fin.variables['volumes'].shape[0]
28        for v in range(N_tri):
29            self.vtk_cells.InsertNextCell(3)
30            for i in range(3):
31                self.vtk_cells.InsertCellPoint(fin.variables['volumes'][v][i])
32        fin.close()
33
34    def update_height_quantity(self, quantityName, dynamic=True):
35        polydata = self.vtk_polyData[quantityName] = vtkPolyData()
36        if dynamic is True:
37            if not self.vtk_heightQuantityCache[self.frameNumber].has_key(quantityName):
38                self.vtk_heightQuantityCache[self.frameNumber][quantityName]\
39                    = self.read_height_quantity(quantityName, True, self.frameNumber);
40                print "Caching %s (frame %d)" % (quantityName, self.frameNumber)
41            else:
42                print "Using cache of %s (frame %d)" % (quantityName, self.frameNumber)
43            polydata.SetPoints(self.vtk_heightQuantityCache[self.frameNumber][quantityName])
44        else:
45            polydata.SetPoints(self.read_height_quantity(quantityName, False))
46        polydata.SetPolys(self.vtk_cells)
47           
48    def read_height_quantity(self, quantityName, dynamic=True, frameNumber=0):
49        """Read in a height based quantity from the NetCDF source file
50        and return a vtkPoints object. frameNumber is ignored if
51        dynamic is false."""
52        fin = NetCDFFile(self.source, 'r')
53        points = vtkPoints()
54        if dynamic is True:
55            N_vert = fin.variables[quantityName].shape[1]
56        else:
57            N_vert = len(fin.variables[quantityName])
58        x = array(fin.variables['x'], Float)
59        y = array(fin.variables['y'], Float)
60        if dynamic is True:
61            q = array(fin.variables[quantityName][self.frameNumber], Float)
62        else:
63            q = array(fin.variables[quantityName], Float)
64
65        q *= self.height_zScales[quantityName]
66        q += self.height_offset[quantityName]
67
68        for v in range(N_vert):
69            points.InsertNextPoint(x[v], y[v], q[v])
70        fin.close()
71        return points
72
73    def setup_gui(self):
74        Visualiser.setup_gui(self)
75        self.tk_renderWidget.grid(row=0, column=0, columnspan=6)
76        self.tk_quit.grid(row=2, column=0, columnspan=6, sticky=W+E)
77        self.tk_restart = Button(self.tk_root, text="<<<", command=self.restart)
78        self.tk_restart.grid(row=1, column=0, sticky=W+E)
79        self.tk_back10 = Button(self.tk_root, text="<<", command=self.back10)
80        self.tk_back10.grid(row=1, column=1, sticky=W+E)
81        self.tk_back = Button(self.tk_root, text="<", command=self.back)
82        self.tk_back.grid(row=1, column=2, sticky=W+E)
83        self.tk_pauseResume = Button(self.tk_root, text="Pause", command=self.pauseResume)
84        self.tk_pauseResume.grid(row=1, column=3, sticky=W+E)
85        self.tk_forward = Button(self.tk_root, text=">", command=self.forward)
86        self.tk_forward.grid(row=1, column=4, sticky=W+E)
87        self.tk_forward10 = Button(self.tk_root, text=">>", command=self.forward10)
88        self.tk_forward10.grid(row=1, column=5, sticky=W+E)
89
90    def restart(self):
91        self.frameNumber = 0
92        self.redraw_quantities(True)
93
94    def back10(self):
95        if self.frameNumber - 10 >= 0:
96            self.frameNumber -= 10
97        else:
98            self.frameNumber = 0
99        self.redraw_quantities(True)
100
101    def back(self):
102        if self.frameNumber > 0:
103            self.frameNumber -= 1
104            self.redraw_quantities(True)
105
106    def pauseResume(self):
107        print "Pause/Resume"
108
109    def forward(self):
110        if self.frameNumber < self.maxFrameNumber:
111            self.frameNumber += 1
112            self.redraw_quantities(True)
113
114    def forward10(self):
115        if self.frameNumber + 10 <= self.maxFrameNumber:
116            self.frameNumber += 10
117        else:
118            self.frameNumber = self.maxFrameNumber
119        self.redraw_quantities(True)
Note: See TracBrowser for help on using the repository browser.