```
# link ONFRAMECHANGE
# put 'Wave' grid mesh object on a hidden layer
# put 'Boat' mesh object on visible layer
from Blender import Get, NMesh, Object, Material
from math import sqrt, sin, pow, pi
dpi = 2*pi
veloc = 0.8 # velocity
interv = 20 # num. frames to consider in calculus
ampl = 0.3 # amplitude
Lon = 2 # wavelenght
visco = 0.01 # viscosity
Rmin = 0.1 # min. radius
Hmin = 1 # max.Z over Zplane
frame = Get('curframe')
me = NMesh.GetRawFromObject('Wave')
vs = me.verts
obj = Object.Get()
mat = Material.Get()
wmat = []
[wmat.append(m) for m in mat if (m.name[:5] == 'Waves')]
if wmat == []: wave = Material.New('Waves')
else: wave = Material.Get('Waves')
for o in obj:
if (o.name[:4] == 'Boat'):
curves = o.getIpo()
for v in vs:
sum = 0
for a in range(frame)[-interv:]:
z = curves.EvaluateCurveOn(2, a)
if abs(z) < Hmin:
x = curves.EvaluateCurveOn(0, a)
y = curves.EvaluateCurveOn(1, a)
vx = (curves.EvaluateCurveOn(0, a+0.01)-curves.EvaluateCurveOn(0, a-0.01))*50
vy = (curves.EvaluateCurveOn(1, a+0.01)-curves.EvaluateCurveOn(1, a-0.01))*50
vz = (curves.EvaluateCurveOn(2, a+0.01)-curves.EvaluateCurveOn(2, a-0.01))*50
VB = sqrt(vx*vx+vy*vy+vz*vz)
D = sqrt((v.co[0]-x)*(v.co[0]-x)+(v.co[1]-y)*(v.co[1]-y))
if(frame-a > D/veloc):
D = max(D, Rmin)
sum = sum+5*o.SizeX*VB*sin(D*dpi/Lon-(frame-a)*veloc)
v.co[2] = v.co[2] - sum*ampl/interv/pow(D, visco)
for f in me.faces: f.smooth = 1
me.setMode('SubSurf')
me.setSubDivLevels([1, 3])
if not me.materials: me.addMaterial(wave)
NMesh.PutRaw(me, me.name + '.Fx')
for o in obj: o.makeDisplayList()
```

this one sort of automatically adds materials

adopted from an older script, I forgot who the original author was