source: anuga_core/source/anuga/visualiser/realtime.py @ 7248

Last change on this file since 7248 was 6113, checked in by steve, 16 years ago

Added wireframe visualisation

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