Changeset 3873
- Timestamp:
- Oct 26, 2006, 1:02:41 PM (19 years ago)
- Location:
- anuga_core/source/anuga
- Files:
-
- 4 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
anuga_core/source/anuga/examples/sww_file_visualiser_example.py
r3813 r3873 1 #!/usr/bin/env python 1 2 ########## 2 3 # Demonstration of the VTK sww Visualiser … … 7 8 # Import the offline visualiser 8 9 from anuga.visualiser import OfflineVisualiser 10 from vtk import vtkCubeAxesActor2D 9 11 10 12 # The argument to OfflineVisualiser is the path to a sww file … … 31 33 o.render_axes() 32 34 33 # Draw a polygon (here, a triangle) at height 10 35 # Increase the number of labels on the axes 36 o.alter_axes(vtkCubeAxesActor2D.SetNumberOfLabels, (5,)) 37 38 # Draw a yellow polygon at height 10 34 39 o.overlay_polygon([(20, 50), (40, 40), (50, 10), (30, 20), (10, 30)], 10, colour=(1.0, 1.0, 0.0)) 35 40 … … 39 44 40 45 # Start the visualiser (in its own thread). 41 o.run() 46 o.start() 47 48 # Wait for the visualiser to terminate before shutting down. 49 o.join() -
anuga_core/source/anuga/examples/visualise_rectangle.py
r3870 r3873 1 1 #!/usr/bin/env python 2 """ 3 Example showing improved wet dry limiting. 4 This script runs the same simulation twice and stores the outputs in 5 old_limiter.sww and new_limiter.sww respectively. 6 7 Authors: Steve Roberts 8 October 9 """ 2 ########## 3 # Demonstration of the VTK realtime Visualiser. 4 # Based on run_sw_rectangle.py 5 # Jack Kelly and Stephen Roberts 6 # October 2006 7 ########## 10 8 11 #----------------------------------------------------------------- 12 # Common structures 13 #----------------------------------------------------------------- 9 # Import the offline visualiser 10 from anuga.visualiser import RealtimeVisualiser 11 from vtk import vtkCubeAxesActor2D 12 14 13 import time 15 14 from Numeric import array … … 17 16 from anuga.shallow_water import Reflective_boundary 18 17 from anuga.abstract_2d_finite_volumes.mesh_factory import rectangular 18 19 19 20 20 class Set_Stage: … … 37 37 38 38 yieldstep = 0.002 39 finaltime = 0.0639 finaltime = 1.0 40 40 rect = [0.0, 0.0, 1.0, 1.0] 41 41 42 domain = Domain(points, vertices, boundary) 42 43 43 #----------------------------------------------------------------- 44 # Create domain for "old limiter" scenario 45 #----------------------------------------------------------------- 46 domain = Domain(points, vertices, boundary) 47 domain.set_name('old_limiter_second_order') 48 print 'Number of triangles =', len(domain) 44 # Turn on the visualisation. The argument to the realtime visualier 45 # is a domain object. 46 v = RealtimeVisualiser(domain) 49 47 50 # Turn on the visualisation 51 try: 52 domain.initialise_visualiser() 53 except: 54 pass 48 # Specify the height-based-quantities to render. 49 # Remember to set dynamic=True for time-varying quantities 50 v.render_quantity_height("elevation", dynamic=False) 51 v.render_quantity_height("stage", dynamic=True) 55 52 53 # Colour the stage: 54 # Either with an RGB value as a 3-tuple of Floats, 55 #v.colour_height_quantity('stage', (0.0, 0.0, 0.8)) 56 # Or with a function of the quantities at that point, such as the stage height: 57 # 0 and 1 are the minimum and maximum values of the stage. 58 v.colour_height_quantity('stage', (lambda q:q['stage'], 0, 1)) 59 # Or with the magnitude of the momentum at that point: 60 # Needs the sqrt function from Numeric. Again, 0 and 10 define the colour range. 61 #v.colour_height_quantity('stage', (lambda q:sqrt((q['xmomentum'] ** 2) + 62 # (q['ymomentum'] ** 2)), 0, 10)) 63 64 # Draw some axes on the visualiser so we can see how big the wave is 65 v.render_axes() 66 67 # Increase the number of labels on the axes 68 v.alter_axes(vtkCubeAxesActor2D.SetNumberOfLabels, (5,)) 69 70 # Draw a yellow polygon at height 10 71 v.overlay_polygon([(20, 50), (40, 40), (50, 10), (30, 20), (10, 30)], 10, colour=(1.0, 1.0, 0.0)) 72 73 # Start the visualiser (in its own thread). 74 v.start() 56 75 57 76 #----------------------------------------------------------------- … … 63 82 64 83 #----------------------------------------------------------------- 65 # Values for old limiter66 #-----------------------------------------------------------------67 domain.default_order = 268 domain.beta_w = 0.969 domain.beta_w_dry = 0.970 domain.beta_uh = 0.971 domain.beta_uh_dry = 0.972 domain.beta_vh = 0.973 domain.beta_vh_dry = 0.974 75 #-----------------------------------------------------------------76 84 # Evolve 77 85 #----------------------------------------------------------------- 78 86 t0 = time.time() 79 87 for t in domain.evolve(yieldstep = yieldstep, finaltime = finaltime): 88 v.update() 80 89 domain.write_time() 81 82 print 'That took %.2f seconds' %(time.time()-t0) 83 print 'Note the small timesteps and the irregular flow' 84 #raw_input('press return to continue') 85 86 87 #----------------------------------------------------------------- 88 # Create domain for "new limiter" scenario (2 order) 89 #----------------------------------------------------------------- 90 domain = Domain(points, vertices, boundary) 91 domain.set_name('new_limiter_second_order') 92 print 'Number of triangles =', len(domain) 93 94 # Turn on the visualisation 95 try: 96 domain.initialise_visualiser() 97 except: 98 pass 99 100 #----------------------------------------------------------------- 101 # Boundaries and Initial conditions 102 #----------------------------------------------------------------- 103 R = Reflective_boundary(domain) 104 domain.set_boundary( {'left': R, 'right': R, 'bottom': R, 'top': R} ) 105 domain.set_quantity('stage', Set_Stage(0.2, 0.4, 0.25, 0.75, 1.0, 0.00)) 106 107 #----------------------------------------------------------------- 108 # Values for new limiter 109 #----------------------------------------------------------------- 110 domain.set_default_order(2) 111 domain.minimum_allowed_height = 0.001 112 domain.beta_w = 1.0 113 domain.beta_w_dry = 0.2 114 domain.beta_uh = 1.0 115 domain.beta_uh_dry = 0.2 116 domain.beta_vh = 1.0 117 domain.beta_vh_dry = 0.2 118 119 #----------------------------------------------------------------- 120 # Evolve 121 #----------------------------------------------------------------- 122 t0 = time.time() 123 for t in domain.evolve(yieldstep = yieldstep, finaltime = finaltime): 124 domain.write_time() 125 126 print 'That took %.2f seconds' %(time.time()-t0) 127 print 'Note more uniform and large timesteps' 128 #raw_input('press return to continue') 129 130 131 #----------------------------------------------------------------- 132 # Create domain for "new limiter" scenario (1 order) 133 #----------------------------------------------------------------- 134 domain = Domain(points, vertices, boundary) 135 domain.set_name('new_limiter_first_order') 136 print 'Number of triangles =', len(domain) 137 138 # Turn on the visualisation 139 try: 140 domain.initialise_visualiser() 141 except: 142 pass 143 144 #----------------------------------------------------------------- 145 # Boundaries and Initial conditions 146 #----------------------------------------------------------------- 147 R = Reflective_boundary(domain) 148 domain.set_boundary( {'left': R, 'right': R, 'bottom': R, 'top': R} ) 149 domain.set_quantity('stage', Set_Stage(0.2, 0.4, 0.25, 0.75, 1.0, 0.00)) 150 151 #----------------------------------------------------------------- 152 # Values for new limiter first order 153 #----------------------------------------------------------------- 154 domain.set_default_order(1) 155 domain.minimum_allowed_height = 0.001 156 domain.beta_w = 1.0 157 domain.beta_w_dry = 0.2 158 domain.beta_uh = 1.0 159 domain.beta_uh_dry = 0.2 160 domain.beta_vh = 1.0 161 domain.beta_vh_dry = 0.2 162 163 #----------------------------------------------------------------- 164 # Evolve 165 #----------------------------------------------------------------- 166 t0 = time.time() 167 for t in domain.evolve(yieldstep = yieldstep, finaltime = finaltime): 168 domain.write_time() 90 # Unhook the visualiser from the evolve loop. 91 # It won't shutdown cleanly unless you do this. 92 v.evolveFinished() 169 93 170 94 print 'That took %.2f seconds' %(time.time()-t0) 171 95 172 96 # Wait for the visualiser to be closed 97 v.join() -
anuga_core/source/anuga/visualiser/offline.py
r3670 r3873 1 1 from Numeric import array, Float, ravel, zeros 2 2 from Scientific.IO.NetCDF import NetCDFFile 3 from Tkinter import Button, E, W3 from Tkinter import Button, E, Tk, W 4 4 from visualiser import Visualiser 5 5 from vtk import vtkCellArray, vtkPoints, vtkPolyData … … 13 13 structures for any dynamic height based quantities to render. 14 14 """ 15 def __init__(self, source ):15 def __init__(self, source, frameDelay=100): 16 16 """The source parameter is assumed to be a NetCDF sww file. 17 The frameDelay parameter is the number of milliseconds waited between frames. 17 18 """ 18 19 Visualiser.__init__(self, source) … … 22 23 self.maxFrameNumber = fin.variables['time'].shape[0] - 1 23 24 fin.close() 25 26 self.frameDelay = frameDelay 24 27 25 28 self.xmin = None … … 140 143 141 144 def run(self): 142 self. tk_root.after(100, self.animateForward)145 self.alter_tkroot(Tk.after, (self.frameDelay, self.animateForward)) 143 146 Visualiser.run(self) 144 147 145 148 def restart(self): 146 149 self.frameNumber = 0 147 self.redraw_quantities( True)150 self.redraw_quantities() 148 151 self.pause() 149 152 … … 153 156 else: 154 157 self.frameNumber = 0 155 self.redraw_quantities( True)158 self.redraw_quantities() 156 159 self.pause() 157 160 … … 159 162 if self.frameNumber > 0: 160 163 self.frameNumber -= 1 161 self.redraw_quantities( True)164 self.redraw_quantities() 162 165 self.pause() 163 166 … … 175 178 self.paused = False 176 179 self.tk_pauseResume.config(text="Pause") 177 self.tk_root.after( 100, self.animateForward)180 self.tk_root.after(self.frameDelay, self.animateForward) 178 181 179 182 def forward(self): … … 184 187 if self.frameNumber < self.maxFrameNumber: 185 188 self.frameNumber += 1 186 self.redraw_quantities( True)189 self.redraw_quantities() 187 190 else: 188 191 self.pause() … … 193 196 else: 194 197 self.frameNumber = self.maxFrameNumber 195 self.redraw_quantities( True)198 self.redraw_quantities() 196 199 self.pause() 197 200 … … 199 202 if self.paused is not True: 200 203 self.forward_step() 201 self.tk_root.after( 100, self.animateForward)204 self.tk_root.after(self.frameDelay, self.animateForward) -
anuga_core/source/anuga/visualiser/realtime.py
r3625 r3873 1 1 from Numeric import Float, zeros 2 from Tkinter import Button, E, W2 from Tkinter import Button, E, Tk, W 3 3 from threading import Event 4 4 from visualiser import Visualiser … … 7 7 class RealtimeVisualiser(Visualiser): 8 8 """A VTK-powered realtime visualiser which runs in its own thread. 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. 9 18 """ 10 19 def __init__(self, source): … … 14 23 15 24 self.running = True 25 26 self.xmin = None 27 self.xmax = None 28 self.ymin = None 29 self.ymax = None 30 self.zmin = None 31 self.zmax = None 16 32 17 33 # Synchronisation Constructs … … 24 40 25 41 def run(self): 26 self. tk_root.after(100, self.sync_idle.set)42 self.alter_tkroot(Tk.after, (100, self.sync_idle.set)) 27 43 Visualiser.run(self) 28 44 … … 35 51 self.vtk_cells.InsertNextCell(3) 36 52 for v in range(3): 37 self.vert_index[self.source.triangles[n][v]] = self.source.vertex_coordinates[n][ i*2:i*2+2]53 self.vert_index[self.source.triangles[n][v]] = self.source.vertex_coordinates[n][v*2:v*2+2] 38 54 self.vtk_cells.InsertCellPoint(self.source.triangles[n][v]) 39 55 … … 52 68 qty_index[v] * self.height_zScales[quantityName] 53 69 + self.height_offset[quantityName]) 70 if self.xmin == None or self.xmin > self.vert_index[v][0]: 71 self.xmin = self.vert_index[v][0] 72 if self.xmax == None or self.xmax < self.vert_index[v][0]: 73 self.xmax = self.vert_index[v][0] 74 if self.ymin == None or self.ymin > self.vert_index[v][1]: 75 self.ymin = self.vert_index[v][1] 76 if self.ymax == None or self.ymax < self.vert_index[v][1]: 77 self.ymax = self.vert_index[v][1] 78 if self.zmin == None or self.zmin > qty_index[v] * self.height_zScales[quantityName] + self.height_offset[quantityName]: 79 self.zmin = qty_index[v] * self.height_zScales[quantityName] + self.height_offset[quantityName] 80 if self.zmax == None or self.zmax < qty_index[v] * self.height_zScales[quantityName] + self.height_offset[quantityName]: 81 self.zmax = qty_index[v] * self.height_zScales[quantityName] + self.height_offset[quantityName] 54 82 55 83 polydata = self.vtk_polyData[quantityName] = vtkPolyData() 56 84 polydata.SetPoints(points) 57 85 polydata.SetPolys(self.vtk_cells) 86 87 def get_3d_bounds(self): 88 return [self.xmin, self.xmax, self.ymin, self.ymax, self.zmin, self.zmax] 58 89 59 90 def build_quantity_dict(self): … … 86 117 self.sync_unpaused.set() 87 118 119 def redraw(self): 120 if self.running: 121 self.sync_redrawReady.wait() 122 self.sync_redrawReady.clear() 123 self.redraw_quantities() 124 self.sync_idle.set() 125 Visualiser.redraw(self) 126 127 def update(self): 128 """Sync the visualiser to the domain. Call this in the evolve loop.""" 129 if self.running: 130 self.sync_redrawReady.set() 131 self.sync_idle.wait() 132 self.sync_idle.clear() 133 self.sync_unpaused.wait() 134 135 def evolveFinished(self): 136 """Stop the visualiser from waiting on signals from the evolve loop. 137 Call this just after the evolve loop to ensure a clean shutdown.""" 138 self.running = False 139 self.sync_redrawReady.set() -
anuga_core/source/anuga/visualiser/visualiser.py
r3813 r3873 1 1 from threading import Thread 2 from Queue import Queue 2 3 from Tkinter import Tk, Button, Frame, N, E, S, W 3 4 from types import FunctionType, TupleType … … 28 29 self.vtk_mappers = {} 29 30 self.vtk_polyData = {} 31 32 # A function queue to ensure all the visualiser configuration is done in the visualiser thread. 33 # The queue will contain zero or more functions, with the arguments to that function immediately following 34 # as a tuple. 35 self.sync_configFuncs = Queue(-1) 36 37 def run(self): 30 38 self.vtk_renderer = vtkRenderer() 31 32 39 self.setup_gui() 33 34 def run(self):35 40 self.setup_grid() 41 42 # Normally, empty() is not reliable, however all configuration is done 43 # before the visualiser is started and nothing is added to the queue after that. 44 while not self.sync_configFuncs.empty(): 45 func = self.sync_configFuncs.get(True) 46 args = self.sync_configFuncs.get(True) 47 func(*args) 48 36 49 # Draw Height Quantities 37 50 for q in self.height_quantities: 38 51 self.update_height_quantity(q, self.height_dynamic[q]) 39 52 self.draw_height_quantity(q) 53 54 if self.vtk_drawAxes is True: 55 self.tk_root.after(1, self.draw_axes) 56 40 57 self.tk_root.mainloop() 41 58 42 59 def redraw_quantities(self, dynamic_only=False): 43 """Redraw all dynamic quantities , unless dynamic_only is True.60 """Redraw all dynamic quantities. 44 61 """ 45 62 # Height quantities 46 63 for q in self.height_quantities: 47 if ( dynamic_only is False) or (self.height_dynamic[q]):64 if (self.height_dynamic[q]): 48 65 self.update_height_quantity(q, self.height_dynamic[q]) 49 66 self.draw_height_quantity(q) 50 67 if self.vtk_drawAxes is True: 51 self.vtk_axes.SetBounds(self.get_3d_bounds()) 52 if not self.vtk_axesSet: 53 self.vtk_axesSet = True 54 self.vtk_axes.SetCamera(self.vtk_renderer.GetActiveCamera()) 55 self.vtk_renderer.AddActor(self.vtk_axes) 68 self.draw_axes() 69 70 # --- Axes --- # 56 71 57 # --- Height Based Rendering --- #58 59 72 def render_axes(self): 60 73 """Intstruct the visualiser to render cube axes around the render. 61 74 """ 75 self.sync_configFuncs.put(self._render_axes, True) 76 self.sync_configFuncs.put(()) 77 78 def _render_axes(self): 79 """Add the axes to the visualiser. 80 """ 62 81 self.vtk_drawAxes = True 63 82 self.vtk_axes = vtkCubeAxesActor2D() 83 84 def draw_axes(self): 85 """Update the 3D bounds on the axes and add them to the pipeline if not yet connected. 86 """ 87 self.vtk_axes.SetBounds(self.get_3d_bounds()) 88 if not self.vtk_axesSet: 89 self.vtk_axesSet = True 90 self.vtk_axes.SetCamera(self.vtk_renderer.GetActiveCamera()) 91 self.vtk_renderer.AddActor(self.vtk_axes) 64 92 65 def get_axes(self): 66 """Return the vtkCubeAxesActor2D object used to render the axes. 67 This is to allow simple manipulation of the axes such as 68 get_axes().SetNumberOfLabels(5) or similar. 69 """ 70 return self.vtk_axes 93 def alter_axes(self, func, args): 94 """Attempt to apply the function 'func' with args tuple 'args' to the 95 vtkCubeAxesActor2D instance set up by render_axes. This is done this way to ensure 96 the axes setup is handled in the visualiser thread. 97 98 Example call: 99 from vtk import vtkCubeAxesActor2D 100 alter_axes(vtkCubeAxesActor2D.SetNumberOfPoints, (5,)) 101 """ 102 self.sync_configFuncs.put(self._alter_axes, True) 103 self.sync_configFuncs.put((func,)+args, True) 104 105 def _alter_axes(self, func, *args): 106 """Apply func, with args *args to the axes actor. This function should be called from 107 within the visualiser thread after the axes have been initialised. 108 """ 109 func(*((self.vtk_axes,) + args)) 110 111 # --- Height Based Rendering --- # 71 112 72 113 def setup_grid(self): … … 120 161 actor.SetMapper(mapper) 121 162 self.vtk_renderer.AddActor(actor) 163 else: 164 actor = self.vtk_actors[quantityName] 122 165 123 166 if self.colours_height.has_key(quantityName): … … 175 218 colour is the colour of the polygon, as a 3-tuple representing 176 219 r, g, b values between 0 and 1.""" 220 self.sync_configFuncs.put(self._overlay_polygon, True) 221 self.sync_configFuncs.put((coords, height, colour), True) 222 223 def _overlay_polygon(self, coords, height, colour): 224 """Add a polygon to the output of the visualiser. 225 226 coords is a list of 2-tuples representing x and y coordinates. 227 These are triangulated by vtkDelaunay2D. 228 229 height is the z-value given to all points. 230 231 colour is the colour of the polygon, as a 3-tuple representing 232 r, g, b values between 0 and 1. 233 234 This function should not be called from outside the visualiser thread. 235 Use overlay_polygon instead. 236 237 """ 177 238 points = vtkPoints() 178 239 for coord in coords: … … 212 273 self.tk_renderWidget.GetRenderWindow().AddRenderer(self.vtk_renderer) 213 274 275 def alter_tkroot(self, func, args): 276 """Apply func, with arguments tuple args to the root tk window for this visualiser. 277 """ 278 self.sync_configFuncs.put(self._alter_tkroot, True) 279 self.sync_configFuncs.put((func,)+args, True) 280 281 def _alter_tkroot(self, func, *args): 282 """Apply func, with arguments tuple args to the root tk window for this visualiser. 283 This function should only be called from within the visualiser after the tk root window 284 has been created. 285 """ 286 func(*((self.tk_root,) + args)) 287 214 288 # --- GUI Events --- # 215 289
Note: See TracChangeset
for help on using the changeset viewer.