source: anuga_core/source/anuga/visualiser/visualiser.py @ 3512

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

Offline visualiser is working fairly well.

File size: 4.1 KB
Line 
1from threading import Event, Thread
2from Tkinter import Tk, Button, N, E, S, W
3from vtk import vtkActor, vtkPolyDataMapper, vtkRenderer
4from vtk.tk.vtkTkRenderWidget import vtkTkRenderWidget
5
6class Visualiser(Thread):
7    """Superclass of both the realtime and offline VTK visualisers
8    """
9    def __init__(self, source):
10        Thread.__init__(self)
11
12        self.source = source
13
14        # Structures for Height Based quantities
15        self.height_quantities = []
16        self.height_zScales = {}
17        self.height_dynamic = {}
18        self.height_offset = {}
19
20        # Structures used for VTK
21        self.vtk_actors = {}
22        self.vtk_mappers = {}
23        self.vtk_polyData = {}
24
25    def run(self):
26        self.setup_gui()
27        self.setup_grid()
28        # Draw Height Quantities
29        for q in self.height_quantities:
30            self.update_height_quantity(q, self.height_dynamic[q])
31            self.draw_height_quantity(q)
32        self.tk_root.mainloop()
33
34    def redraw_quantities(self, dynamic_only=False):
35        """Redraw all dynamic quantities, unless dynamic_only is True.
36        """
37        # Height quantities
38        for q in self.height_quantities:
39            if (dynamic_only is False) or (self.height_dynamic[q]):
40                self.update_height_quantity(q, self.height_dynamic[q])
41                self.draw_height_quantity(q)
42
43    # --- Height Based Rendering --- #
44
45    def setup_grid(self):
46        """Create the vtkCellArray instance that represents the
47        triangles. Subclasses are expected to override this function
48        to read from their source as appropriate.
49        """
50        pass
51
52    def render_quantity_height(self, quantityName, zScale=1.0, offset=0.0, dynamic=True):
53        """Instruct the visualiser to render a quantity using the
54        value at a point as its height.  The value at each point is
55        multiplied by z_scale and is added to offset, and if
56        dynamic=False, the quantity is not recalculated on each
57        update.
58        """
59        self.height_quantities.append(quantityName)
60        self.height_zScales[quantityName] = zScale
61        self.height_offset[quantityName] = offset
62        self.height_dynamic[quantityName] = dynamic
63
64    def update_height_quantity(self, quantityName, dynamic=True):
65        """Create a vtkPolyData object and store it in
66        self.vtk_polyData[q]. Subclasses are expected to override this
67        function.
68        """
69        pass
70
71
72    def draw_height_quantity(self, quantityName):
73        """Use the vtkPolyData and prepare/update the rest of the VTK
74        rendering pipeline.
75        """
76        if self.vtk_mappers.has_key(quantityName):
77            mapper = self.vtk_mappers[quantityName]
78        else:
79            mapper = self.vtk_mappers[quantityName] = vtkPolyDataMapper()
80        mapper.SetInput(self.vtk_polyData[quantityName])
81        mapper.Update()
82
83        if not self.vtk_actors.has_key(quantityName):
84            actor = self.vtk_actors[quantityName] = vtkActor()
85            actor.SetMapper(mapper)
86            actor.GetProperty().SetColor(0.5, 0.5, 0.5)
87            self.vtk_renderer.AddActor(actor)
88
89    # --- Colour Coding --- #
90
91    # --- Vector Fields --- #
92
93    # --- GUI Setup --- #
94
95    def setup_gui(self):
96        self.tk_root = Tk()
97        self.tk_root.title("Visualisation")
98        self.tk_root.after(100, self.redraw)
99        self.tk_root.bind("<Destroy>", self.destroyed)
100
101        self.tk_renderWidget = vtkTkRenderWidget(self.tk_root, width=400, height=400)
102        self.tk_renderWidget.grid(row=0, column=0, sticky=N+S+E+W)
103        self.tk_quit = Button(self.tk_root, text="Quit", command=self.shutdown)
104        self.tk_quit.grid(row=2, column=0, sticky=E+W)
105        self.vtk_renderer = vtkRenderer()
106        self.tk_renderWidget.GetRenderWindow().AddRenderer(self.vtk_renderer)
107
108    # --- GUI Events --- #
109
110    def destroyed(self, event):
111        if event.widget == self.tk_root:
112            self.shutdown()
113
114    def redraw(self):
115        self.tk_renderWidget.GetRenderWindow().Render()
116        self.tk_root.update_idletasks()
117        self.tk_root.after(100, self.redraw)
118
119    def shutdown(self):
120        self.tk_root.withdraw()
121        self.tk_root.quit()
Note: See TracBrowser for help on using the repository browser.