#! /usr/bin/python
from vtk import *
from Numeric import * #arrays
from math import sin
# create a rendering window and renderer
ren = vtkRenderer()
renWin = vtkRenderWindow()
renWin.AddRenderer(ren)
renWin.SetSize(800,600)
renWin.StereoCapableWindowOn()
iren = vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)
trackcam = vtkInteractorStyleTrackballCamera()
iren.SetInteractorStyle(trackcam)
class matchstick:
"""an element in a height map"""
def __init__(self, x, y, z):
self.source = vtkCubeSource() #looks like a cube
#now do a bunch of vtk crap to render the matchstick
#google for vtk-intro.py if you dont understand what's going on
#self.source.SetCenter(1,0,(self.height/2))
#self.source.SetZLength(self.height)
self.mapper = vtkPolyDataMapper()
self.actor = vtkActor()
self.actor.SetMapper(self.mapper)
self.mapper.SetInput(self.source.GetOutput())
ren.AddActor(self.actor)
def SetOffset(self, Xoffset, Yoffset, height):
"""move and stretch the cubes to the right place"""
self.source.SetCenter((Xoffset, Yoffset, height/2))
self.source.SetZLength(height)
class heightmap:
def __init__(self, sizeX, sizeY, defaultZ, resolution):
self.rows = sizeX*resolution
self.columns = sizeY*resolution
self.array = empty((self.rows, self.columns)) #the data
self.array[:] = defaultZ
# self.surface = empty((self.rows, self.columns)) #the display surface
self.surface = [] #the display surface, a list of cubes, actually a 2d list
#initialize/display the array
self.show()
"""def showElement(self, x, y):
#create a new map element
#self.surface[x][y] = matchstick()
self.surface.append( matchstick())
#move the element to its proper place
self.surface[x*self.columns+y].SetOffset(x, y, self.array[x][y])
"""
def show(self):
"""display a cube for each element in the array"""
#currently only works for a regular grid
#self.surface = [ [matchstick(x, y, self.array[x][y]) for x in range(self.rows)] for y in range(self.columns)]
self.surface = [[ matchstick(x,y, self.array[x][y])
for y in range(self.columns)]
for x in range(self.rows)]
self.redrawSurface()
#for i in range(self.rows):
# for j in range(self.columns):
# self.showElement(i, j)
def redrawElement(self, x, y):
#move the element to its proper place
self.surface[x][y].SetOffset(x, y, self.array[x][y])
#fix all this crap to use apply(array, show/redraw) instead
def redrawSurface(self):
"""rearrange the cubes to show a new surface"""
#currently only works for a regular grid
for x in range(self.rows):
for y in range(self.columns):
#self.surface[x][y].SetOffset(x, y, (self.array[x][y]*1.0))
self.redrawElement(x, y)
myHeightmap = heightmap(2,3,5.0,10) # Height in mm, Width in mm, default Z, resolution per mm
#demo surface
for i in range(myHeightmap.rows):
for j in range(myHeightmap.columns):
myHeightmap.array[i][j] = sin(0.3*i)*4.0 + sin(0.1*j)*4.0 + 8.0
myHeightmap.redrawSurface()
# enable user interface interactor
iren.Initialize()
iren.Start()