source: inundation/ga/storm_surge/pyvolution-parallel/faces_heightfield.py @ 1452

Last change on this file since 1452 was 1231, checked in by steve, 20 years ago

Added advection example for parallel testing

File size: 3.3 KB
Line 
1## Demonstrates some techniques for working with "faces", and
2## shows how to build a height field (a common feature request)
3## with it.
4## David Scherer July 2001
5
6from visual import *
7
8class Model:
9    def __init__(self):
10        self.frame = frame()
11        self.model = faces(frame=self.frame)
12        self.twoSided = true  # add every face twice with opposite normals
13
14    def FacetedTriangle(self, v1, v2, v3, color=None):
15        """Add a triangle to the model, apply faceted shading automatically"""
16        try:
17            normal = norm( cross(v2-v1, v3-v1) )
18        except:
19            normal = vector(0,0,0)
20        for v in (v1,v2,v3):
21            self.model.append( pos=v, color=color, normal=normal )
22        if self.twoSided:
23            for v in (v1,v3,v2):
24                self.model.append( pos=v, color=color, normal=-normal )
25
26    def FacetedPolygon(self, *v):
27        """Appends a planar polygon of any number of vertices to the model,
28           applying faceted shading automatically."""
29        for t in range(len(v)-2):
30            self.FacetedTriangle( v[0], v[t+1], v[t+2] )
31
32    def DoSmoothShading(self):
33        """Change a faceted model to smooth shaded, by averaging normals at
34        coinciding vertices.
35       
36        This is a very slow and simple smooth shading
37        implementation which has to figure out the connectivity of the
38        model and does not attempt to detect sharp edges.
39
40        It attempts to work even in two-sided mode where there are two
41        opposite normals at each vertex.  It may fail somehow in pathological
42        cases. """
43
44        pos = self.model.pos
45        normal = self.model.normal
46
47        vertex_map = {}  # vertex position -> vertex normal
48        vertex_map_backface = {}
49        for i in range( len(pos) ):
50            tp = tuple(pos[i])
51            old_normal = vertex_map.get( tp, (0,0,0) )
52            if dot(old_normal, normal[i]) >= 0:
53                vertex_map[tp] = normal[i] + old_normal
54            else:
55                vertex_map_backface[tp] = normal[i] + vertex_map_backface.get(tp, (0,0,0))
56
57        for i in range( len(pos) ):
58            tp = tuple(pos[i])
59            if dot(vertex_map[tp], normal[i]) >= 0:
60                normal[i] = vertex_map[tp] and norm( vertex_map[ tp ] )
61            else:
62                normal[i] = vertex_map_backface[tp] and norm(vertex_map_backface[tp] )
63
64    def DrawNormal(self, scale):
65        pos = self.model.pos
66        normal = self.model.normal
67        for i in range(len(pos)):
68            arrow(pos=pos[i], axis=normal[i]*scale)
69
70class Mesh (Model):
71    def __init__(self, xvalues, yvalues, zvalues):
72        Model.__init__(self)
73
74        points = zeros( xvalues.shape + (3,), Float )
75        points[...,0] = xvalues
76        points[...,1] = yvalues
77        points[...,2] = zvalues
78
79        for i in range(zvalues.shape[0]-1):
80            for j in range(zvalues.shape[1]-1):
81                self.FacetedPolygon( points[i,j], points[i,j+1],
82                                     points[i+1,j+1], points[i+1,j] )
83
84## Graph a function of two variables (a height field)
85x = arange(-1,1,2./60)
86y = arange(-1,1,2./60)
87
88z = zeros( (len(x),len(y)), Float )
89x,y = x[:,NewAxis]+z, y+z
90
91m = Mesh( x, (sin(x*pi)+sin(y*pi))*0.2, y )
92m.DoSmoothShading()
93#m.DrawNormal(0.05)
Note: See TracBrowser for help on using the repository browser.