# ri_utils.py
# A collection of procs that generate strings containing the
# RenderMan description of a surface. For example,
#
# import ri_utils
# verts = [ [-1,0,1], [1,0,1], [1,0,-1] ]
# print ri_utils.Polygon(verts)
#
# will generate the following Rib statement:
# Polygon "P" [-1.0 0.0 1.0 1.0 0.0 1.0 1.0 0.0 -1.0]
#
# Malcolm Kesson Jan 20 2013
#_______________________________________________________
def Cube(bbox, index):
pnts = []
minX,minY,minZ,maxX,maxY,maxZ = bbox
rib = 'Attribute "identifier" "float id" [' + str(index) + ']\n'
rib += 'PointsGeneralPolygons [1 1 1 1 1 1] '
rib += '[4 4 4 4 4 4]\n'
rib += '\t\t[0 1 3 2 2 3 5 4 4 5 7 6 6 7 1 0 1 7 5 3 6 0 2 4]\n'
rib += '\t\t"P" ['
pnts.append('%1.3f %1.3f %1.3f' % (minX,minY,maxZ))
pnts.append(' %1.3f %1.3f %1.3f' % (maxX,minY,maxZ))
pnts.append(' %1.3f %1.3f %1.3f' % (minX,maxY,maxZ))
pnts.append(' %1.3f %1.3f %1.3f' % (maxX,maxY,maxZ))
pnts.append(' %1.3f %1.3f %1.3f' % (minX,maxY,minZ))
pnts.append(' %1.3f %1.3f %1.3f' % (maxX,maxY,minZ))
pnts.append(' %1.3f %1.3f %1.3f' % (minX,minY,minZ))
pnts.append(' %1.3f %1.3f %1.3f' % (maxX,minY,minZ))
rib += ''.join(pnts)
rib += ']\n'
return rib
#_______________________________________________________
def __cube_edges(bbox):
x0,y0,z0,x1,y1,z1 = bbox
edges = []
# lower edges
edges.append([ [x0,y0,z0], [x0,y0,z1] ]) # edge 0_1
edges.append([ [x0,y0,z1], [x1,y0,z1] ]) # edge 1_2
edges.append([ [x1,y0,z1], [x1,y0,z0] ]) # edge 2_3
edges.append([ [x1,y0,z0], [x0,y0,z0] ]) # edge 3_0
# upper edges
edges.append([ [x0,y1,z0], [x0,y1,z1] ]) # edge 4_5
edges.append([ [x0,y1,z1], [x1,y1,z1] ]) # edge 5_6
edges.append([ [x1,y1,z1], [x1,y1,z0] ]) # edge 6_7
edges.append([ [x1,y1,z0], [x0,y1,z0] ]) # edge 7_4
# vertical edges
edges.append([ [x0,y0,z0], [x0,y1,z0] ]) # edge 0_4
edges.append([ [x0,y0,z1], [x0,y1,z1] ]) # edge 1_5
edges.append([ [x1,y0,z1], [x1,y1,z1] ]) # edge 2_6
edges.append([ [x1,y0,z0], [x1,y1,z0] ]) # edge 3_7
return edges
def CubeEdges(bbox, width):
edges = __cube_edges(bbox)
rib = ''
for edge in edges:
pnts = []
begin,end = edge
x,y,z = begin
X,Y,Z = end
rib += '\tCurves "linear" [2] "nonperiodic" \n'
rib += '\t\t"P" ['
pnts.append('%1.3f %1.3f %1.3f' % (x,y,z))
pnts.append(' %1.3f %1.3f %1.3f' % (X,Y,Z))
rib += ''.join(pnts)
rib += '] "constantwidth" [%1.3f]\n' % width
return rib
#_______________________________________________________
def Polygon(verts, index):
pnts = []
rib = 'Attribute "identifier" "float id" [' + str(index) + ']\n'
rib += 'Polygon "P" ['
for vert in verts:
x,y,z = vert
pnts.append('%1.3f %1.3f %1.3f ' % (x,y,z))
rib += ''.join(pnts)
rib += ']\n'
return rib
#_______________________________________________________
def HierarchicalSubdivisionMesh(mesh, index):
loops = [] # a list of the number of vertices of each face
vertLUT = {} # a sequence of unique vertices
for poly in mesh:
loops.append(' %d' % len(poly))
for vert in poly:
vertLUT[vert] = vert
# Convert the LUT to a list so that indexing can be used
pnts = []
for item in vertLUT.keys():
pnts.append(item)
indices = []
for poly in mesh:
for vert in poly:
indices.append(' %d' % pnts.index(vert))
rib = 'Attribute "identifier" "float id" [' + str(index) + ']\n'
rib += 'HierarchicalSubdivisionMesh "catmull-clark" \n['
rib += ''.join(loops)
rib += ']\n['
rib += ''.join(indices)
rib += ']\n'
rib += '["creasemethod" "facevaryingpropagatecorners" "interpolateboundary"] [0 0 1 1 0 0 1 0 0] [1 1] [] ["chaikin"]\n'
rib += '"P" [\n'
pntstr = []
for pnt in pnts:
x,y,z = pnt
pntstr.append('%1.4f %1.4f %1.4f ' % (x,y,z))
rib += ''.join(pntstr)
rib += ']\n'
return rib
#_______________________________________________________
def PointsGeneralPolygons(mesh, index):
faces = []
loops = []
vertLUT = {}
for poly in mesh:
faces.append(' 1')
loops.append(' %d' % len(poly))
for vert in poly:
vertLUT[vert] = vert
pnts = []
for item in vertLUT.keys():
pnts.append(item)
pnts.sort()
indices = []
for poly in mesh:
for vert in poly:
indices.append(' %d' % pnts.index(vert))
rib = 'Attribute "identifier" "float id" [' + str(index) + ']\n'
rib += 'PointsGeneralPolygons ['
rib += ''.join(faces)
rib += ']\n['
rib += ''.join(loops)
rib += ']\n['
rib += ''.join(indices)
rib += '] \n"P" [\n'
pntstr = []
for pnt in pnts:
x,y,z = pnt
pntstr.append('%1.4f %1.4f %1.4f ' % (x,y,z))
rib += ''.join(pntstr)
rib += ']\n'
return rib
#_______________________________________________________
def Cylinder(bbox, index):
x,y,z,X,Y,Z = bbox
xrad = (X - x) / 2
zrad = (Z - z) / 2
rad = (xrad + zrad) / 2
height = Y - y
rib = 'TransformBegin\n'
rib += '\tTranslate %1.3f %1.3f %1.3f \n' % (x,y,z)
rib += '\tRotate 90 1 0 0\n'
rib += '\tAttribute "identifier" "float id" [' + str(index) + ']\n'
rib += '\tCylinder %1.3f 0 %1.3f 360\n' % (rad,height)
rib += 'TransformEnd\n'
return rib