The goal of this assignment was to use Python classes to write scripts to generate a Hilbert curve that can be implemented
into Maya.
# This is the formula that generates the CVs for the Hilbert pattern. # Code from Malcolm Kesson - www.fundza.com import sys, math def hilbert(x0, y0, xi, xj, yi, yj, n): if n <= 0: X = x0 + (xi + yi)/2 Y = y0 + (xj + yj)/2 # Output the coordinates the cv print '%s %s 0' % (X, Y) else: hilbert(x0, y0, yi/2, yj/2, xi/2, xj/2, n - 1) hilbert(x0 + xi/2, y0 + xj/2, xi/2, xj/2, yi/2, yj/2, n - 1) hilbert(x0 + xi/2 + yi/2, y0 + xj/2 + yj/2, xi/2, xj/2, yi/2, yj/2, n - 1) hilbert(x0 + xi/2 + yi, y0 + xj/2 + yj, -yi/2,-yj/2,-xi/2,-xj/2, n - 1) |
Next, we created a Python class for the Hilbert function, to which we could then add sub-classes for more functionality.
The first sub-class simply took the X and Y outputs and held them, so they could be used by the next sub-class to pass the information to a RIB file.
def data(self, x, y): pass |
With the class implementation, we can now create "instances" of the hilbert function, passing different arguments to each, generating multiple files.
if __name__ == '__main__': hilbert1 = Hilbert(0.0, 0.0, 5.0, 0.0, 0.0, 5.0, 5) |
We then made a new file, HilbertRib, that served as another sub-class of Hilbert. This file calls to the base class to generate the data, then processes it into a RIB file.
from HilbertClass import Hilbert class HilbertRib(Hilbert): # This is a class (global) variable rootpath = '/home/cfetze20/mount/stuhome/tech312/Hilbert/renderman/ribarchives/hilbert_' def __init__(self, x0, y0, xi, xj, yi, yj, n, degree, width): # Open a file for writing self.fullpath = HilbertRib.rootpath + str(Hilbert.counter) + '.rib' # Temporary storage for coordinates self.temppath = '/temp/temp.rib' self.temp = open(self.temppath, 'w') self.line_counter = 0 #Opening and setting up the final RIB file self.rib =open(self.fullpath, 'w') self.rib.write('Basis "catmull-rom" 1 "catmull-rom" 1\n') # Give the input data to the base class. This will fill up the temp file with xyz data. Hilbert.__init__(self, x0, y0, xi, xj, yi, yj, n) self.temp.close() # Writing initial lines to final RIB self.rib.write('Curves "cubic" [%d] "nonperiodic" "P" [' % (self.line_counter + 2)) # Open temp file again, for reading data self.temp = open(self.temppath, 'r') lines = self.temp.readlines() self.temp.close() # Transfer the temp data into final RIB for n in range (len(lines)): self.rib.write(lines[n]) if n == 0: self.rib.write(lines[n]) if n == len(lines) - 1: self.rib.write(lines[n]) # Close the file - we're done self.rib.write(']\n "constantwidth" [%1.3f]' % width) self.rib.close() # We override the implementation of the proc in the base class def data(self, x, y): self.temp.write('%s %s 0\n' % (x,y)) self.line_counter += 1 |
After we loaded the RIB into Maya, Malcolm gave us the "sparky" script, which traces a curve from keyframes 0 to 1, across it's UV's.
Rendering a sequence with this shader gave me the video at the top of the page.
Although I still find classes confusing, this exercise was a good introduction to the concept. I can see how using classes could be beneficial while writing scripts that handle multiple jobs and heavy workloads. Also, the Hilbert pattern was very interesting, and I had fun creating renders with it. I'm enjoying becoming reacquainted with Renderman's power and quality.