Index: /anuga_core/source/anuga/examples/sww_file_visualiser_example.py
===================================================================
--- /anuga_core/source/anuga/examples/sww_file_visualiser_example.py	(revision 3669)
+++ /anuga_core/source/anuga/examples/sww_file_visualiser_example.py	(revision 3670)
@@ -27,4 +27,7 @@
 #                                                 (q['ymomentum'] ** 2)), 0, 10))
 
+# Draw some axes on the visualiser so we can see how big the wave is
+o.render_axes()
+
 # Precaching the height-based quantities reduces the time taken to draw each
 # frame, but increases the time taken when the visualiser starts.
Index: /anuga_core/source/anuga/visualiser/offline.py
===================================================================
--- /anuga_core/source/anuga/visualiser/offline.py	(revision 3669)
+++ /anuga_core/source/anuga/visualiser/offline.py	(revision 3670)
@@ -22,4 +22,11 @@
         self.maxFrameNumber = fin.variables['time'].shape[0] - 1
         fin.close()
+
+        self.xmin = None
+        self.xmax = None
+        self.ymin = None
+        self.ymax = None
+        self.zmin = None
+        self.zmax = None
 
         self.vtk_heightQuantityCache = []
@@ -49,4 +56,7 @@
             polydata.SetPoints(self.read_height_quantity(quantityName, False))
         polydata.SetPolys(self.vtk_cells)
+
+    def get_3d_bounds(self):
+        return [self.xmin, self.xmax, self.ymin, self.ymax, self.zmin, self.zmax]
             
     def read_height_quantity(self, quantityName, dynamic=True, frameNumber=0):
@@ -72,4 +82,16 @@
         for v in range(N_vert):
             points.InsertNextPoint(x[v], y[v], q[v])
+            if self.xmin == None or self.xmin > x[v]:
+                self.xmin = x[v]
+            if self.xmax == None or self.xmax < x[v]:
+                self.xmax = x[v]
+            if self.ymin == None or self.ymin > y[v]:
+                self.ymin = y[v]
+            if self.ymax == None or self.ymax < y[v]:
+                self.ymax = y[v]
+            if self.zmin == None or self.zmin > q[v]:
+                self.zmin = q[v]
+            if self.zmax == None or self.zmax < q[v]:
+                self.zmax = q[v]
         fin.close()
         return points
Index: /anuga_core/source/anuga/visualiser/visualiser.py
===================================================================
--- /anuga_core/source/anuga/visualiser/visualiser.py	(revision 3669)
+++ /anuga_core/source/anuga/visualiser/visualiser.py	(revision 3670)
@@ -2,5 +2,5 @@
 from Tkinter import Tk, Button, Frame, N, E, S, W
 from types import FunctionType, TupleType
-from vtk import vtkActor, vtkFloatArray, vtkPolyDataMapper, vtkRenderer
+from vtk import vtkActor, vtkCubeAxesActor2D, vtkFloatArray, vtkPolyDataMapper, vtkRenderer
 from vtk.tk.vtkTkRenderWidget import vtkTkRenderWidget
 
@@ -24,6 +24,9 @@
         # Structures used for VTK
         self.vtk_actors = {}
+        self.vtk_axesSet = False
+        self.vtk_drawAxes = False
         self.vtk_mappers = {}
         self.vtk_polyData = {}
+        self.vtk_renderer = vtkRenderer()
 
         self.setup_gui()
@@ -45,6 +48,25 @@
                 self.update_height_quantity(q, self.height_dynamic[q])
                 self.draw_height_quantity(q)
-
+        if self.vtk_drawAxes is True:
+            self.vtk_axes.SetBounds(self.get_3d_bounds())
+            if not self.vtk_axesSet:
+                self.vtk_axesSet = True
+                self.vtk_axes.SetCamera(self.vtk_renderer.GetActiveCamera())
+                self.vtk_renderer.AddActor(self.vtk_axes)
+        
     # --- Height Based Rendering --- #
+
+    def render_axes(self):
+        """Intstruct the visualiser to render cube axes around the render.
+        """
+        self.vtk_drawAxes = True
+        self.vtk_axes = vtkCubeAxesActor2D()
+        
+    def get_axes(self):
+        """Return the vtkCubeAxesActor2D object used to render the axes.
+        This is to allow simple manipulation of the axes such as
+        get_axes().SetNumberOfLabels(5) or similar.
+        """
+        return self.vtk_axes
 
     def setup_grid(self):
@@ -75,4 +97,11 @@
         pass
 
+    def get_3d_bounds(self):
+        """Get the minimum and maximum bounds for the x, y and z directions.
+        Return as a list of double in the order (xmin, xmax, ymin, ymax, zmin, zmax),
+        suitable for passing to vtkCubeAxesActor2D::SetRanges(). Subclasses are expected
+        to override this function.
+        """
+        pass
 
     def draw_height_quantity(self, quantityName):
@@ -155,5 +184,4 @@
         self.tk_quit = Button(self.tk_controlFrame, text="Quit", command=self.shutdown)
         self.tk_quit.grid(row=0, column=0, sticky=E+W)
-        self.vtk_renderer = vtkRenderer()
         self.tk_renderWidget.GetRenderWindow().AddRenderer(self.vtk_renderer)
 
