source: trunk/anuga_core/source/anuga/visualiser/realtime.py @ 8466

Last change on this file since 8466 was 8167, checked in by steve, 14 years ago

Found an error in vtk visualiser

File size: 6.0 KB
Line 
1#from  import Float, zeros, shape
2import numpy as num
3from Tkinter import Button, E, Tk, W
4from threading import Event
5from visualiser import Visualiser
6from vtk import vtkCellArray, vtkPoints, vtkPolyData
7
8class RealtimeVisualiser(Visualiser):
9    """A VTK-powered realtime visualiser which runs in its own thread.
10    In addition to the functions provided by the standard visualiser,
11    the following additional functions are provided:
12
13    update() - Sync the visualiser to the current state of the model.
14    Should be called inside the evolve loop.
15
16    evolveFinished() - Clean up synchronisation constructs that tie the
17    visualiser to the evolve loop. Call this after the evolve loop finishes
18    to ensure a clean shutdown.
19    """
20    def __init__(self, source):
21        """The source parameter is assumed to be a Domain.
22        """
23        Visualiser.__init__(self, source)
24
25        self.running = True
26
27        self.xmin = None
28        self.xmax = None
29        self.ymin = None
30        self.ymax = None
31        self.zmin = None
32        self.zmax = None
33
34        # Synchronisation Constructs
35        self.sync_idle = Event()
36        self.sync_idle.clear()
37        self.sync_unpaused = Event()
38        self.sync_unpaused.set()
39        self.sync_redrawReady = Event()
40        self.sync_redrawReady.clear()
41       
42    def setup_grid(self):
43        self.vtk_cells = vtkCellArray()
44        triangles = self.source.get_triangles()
45        N_tri = len(self.source)
46        verticies = self.source.get_vertex_coordinates()
47        N_vert = len(verticies)
48
49        # Also build vert_index - a list of the x & y values of each vertex
50        self.vert_index = num.zeros((N_vert,2), num.float)
51        for n in range(N_tri):
52            self.vtk_cells.InsertNextCell(3)
53            for v in range(3):
54                self.vert_index[n * 3 + v] = verticies[n * 3 + v]
55                self.vtk_cells.InsertCellPoint(n * 3 + v)
56
57    def update_height_quantity(self, quantityName, dynamic=True):
58        N_vert = len(self.source.get_vertex_coordinates())
59        qty_index = num.zeros(N_vert, num.float)
60        triangles = self.source.get_triangles()
61        vertex_values, _ = self.source.get_quantity(quantityName).get_vertex_values(xy=False, smooth=False)
62
63       
64        for n in range(N_vert):
65            qty_index[n] = vertex_values[n]
66
67        points = vtkPoints()
68        for v in range(N_vert):
69            points.InsertNextPoint(self.vert_index[v][0],
70                                   self.vert_index[v][1],
71                                   qty_index[v] * self.height_zScales[quantityName]
72                                   + self.height_offset[quantityName])
73            if self.xmin == None or self.xmin > self.vert_index[v][0]:
74                self.xmin = self.vert_index[v][0]
75            if self.xmax == None or self.xmax < self.vert_index[v][0]:
76                self.xmax = self.vert_index[v][0]
77            if self.ymin == None or self.ymin > self.vert_index[v][1]:
78                self.ymin = self.vert_index[v][1]
79            if self.ymax == None or self.ymax < self.vert_index[v][1]:
80                self.ymax = self.vert_index[v][1]
81            if self.zmin == None or self.zmin > qty_index[v] * self.height_zScales[quantityName] + self.height_offset[quantityName]:
82                self.zmin = qty_index[v] * self.height_zScales[quantityName] + self.height_offset[quantityName]
83            if self.zmax == None or self.zmax < qty_index[v] * self.height_zScales[quantityName] + self.height_offset[quantityName]:
84                self.zmax = qty_index[v] * self.height_zScales[quantityName] + self.height_offset[quantityName]
85
86        polydata = self.vtk_polyData[quantityName] = vtkPolyData()
87        polydata.SetPoints(points)
88        polydata.SetPolys(self.vtk_cells)
89
90    def get_3d_bounds(self):
91        return [self.xmin, self.xmax, self.ymin, self.ymax, self.zmin, self.zmax]
92       
93    def build_quantity_dict(self):
94        triangles = self.source.get_triangles()
95        quantities = {}
96        for q in self.source.get_quantity_names():
97            #quantities[q], _ = self.source.get_quantity(q).get_vertex_values(xy=False)
98            quantities[q]  = self.source.get_quantity(q).vertex_values.flatten()
99        return quantities
100
101    def setup_gui(self):
102        Visualiser.setup_gui(self)
103        self.tk_pauseResume = Button(self.tk_controlFrame, text="Pause", command=self.pauseResume)
104        self.tk_pauseResume.grid(row=1, column=0, sticky=E+W)
105
106    def pauseResume(self):
107        if self.sync_unpaused.isSet():
108            self.sync_unpaused.clear()
109            self.tk_pauseResume.config(text="Resume")
110        else:
111            self.sync_unpaused.set()
112            self.tk_pauseResume.config(text="Pause")
113
114    def shutdown(self):
115        Visualiser.shutdown(self)
116        self.running = False
117        self.sync_idle.set()
118        self.sync_unpaused.set()
119
120    def redraw(self):
121        if self.running and self.sync_unpaused.isSet():
122            self.sync_redrawReady.wait()
123            self.sync_redrawReady.clear()
124            self.redraw_quantities()
125            self.sync_idle.set()
126        Visualiser.redraw(self)
127
128    def update(self,pause=False):
129        """Sync the visualiser to the domain. Call this in the evolve loop."""
130           
131        if self.running:
132            self.sync_redrawReady.set()
133            self.sync_idle.wait()
134            self.sync_idle.clear()
135            self.sync_unpaused.wait()
136
137        if pause and self.running:
138            if self.sync_unpaused.isSet():
139                self.sync_unpaused.clear()
140                self.tk_pauseResume.config(text="Resume")
141               
142                self.sync_redrawReady.set()
143                self.sync_idle.wait()
144                self.sync_idle.clear()
145                self.sync_unpaused.wait()
146           
147        return self.running
148
149    def evolveFinished(self):
150        """Stop the visualiser from waiting on signals from the evolve loop.
151        Call this just after the evolve loop to ensure a clean shutdown."""
152        self.running = False
153        self.sync_redrawReady.set()
Note: See TracBrowser for help on using the repository browser.