Python Binding

Python Binding

The prman Layer

prman.py represents the highest level layer of the bridge to prman. prman.py is a Python module that exports a combination of procedures, constants, and class definitions. You must first import the module to gain access to prman. Python offers a number of methods to ensure a module import succeeds. Assuming you can successfully import prman, you can cause your Python application to mimic the behavior of the classic prman executable.

Here are the exports of the prman layer:

prman.Init(arglist)         # optional initialization
prman.Cleanup()             # optional cleanup
prman.RifInit(riflist)      # reset the current Rif state
prman.ParseFile(filename, layer=FirstLayer) # parse a RIB file in a Rif layer
prman.Ri()                  # class definition, create an Ri instance
prman.Rif()                 # class definition, create a Rif instance
prman.ThisLayer             # (plus NextLayer, FirstLayer, used by prman.ParseFile)
prman.Version               # (plus a few other useful constants)
prman.RicFlush(marker, synchronous, flushmode) # Synchronize with a detached prman
prman.RicGetProgress()      # returns percentage of a render completed
prman.RicProcessCallbacks() # delivers queued error messages and pixels for display

The Ri Layer

The Ri layer is at the heart of prman and embodies the RenderMan Interface. All standard Ri procedure calls are provided. Rather than require complex custom data structure support, we've opted for the simple, generic approach, wherein standard Python entities are preferred. To represent an array of three rgb colors, we require/support any of these representations:

[1, 0, 0, 0, 1, 0,  0, 0, 1]    # list
(1, 0, 0, 0, 1, 0,  0, 0, 1)    # tuple
array.array('f',  [1, 0, 0, 0, 1, 0,  0, 0, 1] )  # array

RenderMan's variable-length parameter list is represented in prman_for_python as a standard Python dictionary whose keys are the parameter declaration and whose values are scalars or sequences whose length is governed by the declaration and standard binding semantics (see the Primitive Variable Application Note for more details).

The Ri layer also provides standard variables and tokens like these:

Ri.RGBA             # (plus all standard Ri tokens)]
Ri.BEZIERSTEP           # (and all basis steps)
Ri.BezierBasis          # (and all standard bases)
Ri.BoxFilter            # (all standard filters)
Ri.ErrorPrintOnce       # (and all standard error handlers)
Ri.ProcDelayedReadArchive   # (all standard procprims)

Unlike the C binding, prman_for_python is able to infer the size of varying length arrays directly, and does not require passing in the size as a separate parameter. For example, the Python bindings for the Polygon creation routines do not require passing in the numbers of vertices, loops, or polygons. Similarly, the binding for subdivision meshes does not require specifying the number of faces or tags:

ri.Polygon({ri.P:pointData, ri.CS:colorData})
ri.GeneralPolygon (nvertices, {ri.P:genPolyPointData})
ri.PointsPolygons(pointsPolyNvertices, pointsPolyVertices,
                  {ri.P:pointsPolyPointData})
ri.PointsGeneralPolygons(nloops, pointsPolyNvertices, pointsPolyVertices,
                         {ri.P:pointsPolyPointData})
ri.SubdivisionMesh("loop", [3, 3, 3, 3], verts, [ri.CREASE],
                   [2, 1], [3, 0], [20], {ri.P:pointData})

Finally, prman_for_python supports RenderMan plugins expressed in Python. With respect to the Ri layer, this amounts to support for Python-based procedural primitives. An example is provided in the Application Note: PRMan for Python.


The Rif Layer

Ri Filter plugins can also be expressed with Python. This makes it trivial to manipulate the Ri stream at the mouth of the renderer or simply to filter RIB files. To define a new Rif, simply subclass the provided Rif base class then create Rif instances and register them with the prman layer.


The Ric Layer

As noted above, the Ric API is provided by the prman layer. For more information on Ric please refer to Ri Control API documentation.