home *** CD-ROM | disk | FTP | other *** search
- # ***** BEGIN LICENSE BLOCK *****
- # Version: MPL 1.1/GPL 2.0/LGPL 2.1
- #
- # The contents of this file are subject to the Mozilla Public License Version
- # 1.1 (the "License"); you may not use this file except in compliance with
- # the License. You may obtain a copy of the License at
- # http://www.mozilla.org/MPL/
- #
- # Software distributed under the License is distributed on an "AS IS" basis,
- # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- # for the specific language governing rights and limitations under the
- # License.
- #
- # The Original Code is the Python Computer Graphics Kit.
- #
- # The Initial Developer of the Original Code is Matthias Baas.
- # Portions created by the Initial Developer are Copyright (C) 2008
- # the Initial Developer. All Rights Reserved.
- #
- # Contributor(s):
- #
- # Alternatively, the contents of this file may be used under the terms of
- # either the GNU General Public License Version 2 or later (the "GPL"), or
- # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- # in which case the provisions of the GPL or the LGPL are applicable instead
- # of those above. If you wish to allow use of your version of this file only
- # under the terms of either the GPL or the LGPL, and not to allow others to
- # use your version of this file under the terms of the MPL, indicate your
- # decision by deleting the provisions above and replace them with the notice
- # and other provisions required by the GPL or the LGPL. If you do not delete
- # the provisions above, a recipient may use your version of this file under
- # the terms of any one of the MPL, the GPL or the LGPL.
- #
- # ***** END LICENSE BLOCK *****
- # -------------------------------------------------------------
- # The RenderMan (R) Interface Procedures and Protocol are:
- # Copyright 1988, 1989, 2000, Pixar
- # All Rights Reserved
- #
- # RenderMan (R) is a registered trademark of Pixar
- # -------------------------------------------------------------
- # $Id: ri.py,v 1.4 2006/02/14 19:29:39 mbaas Exp $
-
- import types, re
- import ri
- from cgtypes import vec3
- try:
- import ctypes
- _has_ctypes = True
- except ImportError:
- # If importing ctypes fails (which should only happen on older Python versions)
- # the loadRI() function can still be used to load the standard ri module
- # (and get the shortened function names without the "Ri" prefix).
- _has_ctypes = False
-
- if _has_ctypes:
- import _cri
- from _cri import importRINames
-
- try:
- import numpy
- from numpy.ctypeslib import ndpointer
- _has_numpy = True
- except ImportError:
- _has_numpy = False
-
-
- def loadRI(libName):
- """Load a RenderMan library and return a module-like handle to it.
-
- libName is the name of a shared library that implements the RenderMan
- interface. The name can either be an absolute file name or just the
- name of the library (without suffix or "lib" prefix) in which case
- the function tries to find the library file itself.
- The return value is the library handle as returned by the ctypes
- LoadLibrary() function. This handle has already been prepared so that
- it can be used like a module that contains the RenderMan interface.
-
- It is also possible to pass in None or an empty string in which case
- the built-in ri module will be returned.
- """
- if libName is None or libName=="":
- _ri = ri
- else:
- if not _has_ctypes:
- raise ImportError("The ctypes module is not available. Please upgrade to a newer Python version (2.5 or newer) or install ctypes separately.")
- _ri = _cri.loadRI(libName)
- _ri = _RenderManAPI(_ri)
-
- # Create an alias for every Ri function and RI_ constant that has the prefix removed...
- for name in dir(_ri):
- if name.startswith("Ri"):
- setattr(_ri, name[2:], getattr(_ri, name))
- elif name.startswith("RI_"):
- setattr(_ri, name[3:], getattr(_ri, name))
-
- return _ri
-
- class _ProceduralWrapper:
- """Helper class for RiProcedural.
-
- The main purpose of this class is to ensure that all relevant Python
- objects (the ctypes functions) are kept alive for as long as the
- procedural is active. And while we have an instance of this class
- around, it also stores the data value which is passed on the user
- functions. This means, the C data value is not used at all (as every
- procedural will have its own _ProceduralWrapper instance).
-
- The subdiv() and free() methods of this class are the actual functions
- that get passed to the C RiProcedural function.
- """
- def __init__(self, RMAPI, data, subdivFunc, freeFunc):
- # A reference to the "ri" object that has spawned this wrapper instance
- self.RMAPI = RMAPI
- # The wrapped up data value
- self.data = data
- # The user subdiv function
- self.subdivFunc = subdivFunc
- # The user free function (may be None)
- self.freeFunc = freeFunc
-
- # The ctypes function wrappers that get passed to the C function
- self.cSubdivideFunc = RMAPI.RtProcSubdivFunc(self.subdivide)
- self.cFreeFunc = RMAPI.RtProcFreeFunc(self.free)
-
- def subdivide(self, dataPtr, detail):
- """Subdivide function wrapper.
-
- Unwraps the data value and calls the user subdiv function.
- """
- self.subdivFunc(self.data, detail)
-
- def free(self, dataPtr):
- """Free function wrapper.
-
- Unwraps the data value, calls the user free function and
- removes this wrapper instance from the ri object (because
- the associated Python objects need no longer be kept alive).
- """
- if self.freeFunc is not None:
- self.freeFunc(self.data)
- try:
- del self.RMAPI._procWrappers[self]
- except KeyError:
- pass
-
-
- class _RenderManAPI:
- """RenderMan interface.
-
- An instance of this class can be used in a "module-like" fashion,
- i.e. it defines all the functions and constants from the RenderMan
- standard and behaves much like the "ri" module.
- """
-
- def __init__(self, rimod):
- """Constructor.
-
- rimod is the unterlying ctypes library handle as returned by _cri.loadRI().
- """
- self._ri = rimod
-
- # Regular expression to parse declarations
- self._declRe = re.compile(r"^\s*(?:(constant|uniform|varying|vertex) )?\s*"
- "(float|integer|string|color|point|vector|normal|matrix|hpoint)\s*"
- "(?:\[\s*([0-9]+)\s*\])?\s*(\w+)$")
-
- # Copy the RI_ and Rt attributes...
- for name in dir(rimod):
- if name[:2] in ["Rt", "RI"]:
- setattr(self, name, getattr(rimod, name))
-
- # "Import" the error handlers, filters and basis functions...
- for name in ["RiErrorAbort", "RiErrorIgnore", "RiErrorPrint",
- "RiBoxFilter", "RiTriangleFilter", "RiCatmullRomFilter",
- "RiGaussianFilter", "RiSincFilter",
- "RiBezierBasis", "RiBSplineBasis", "RiCatmullRomBasis",
- "RiHermiteBasis", "RiPowerBasis",
- "RiProcDelayedReadArchive", "RiProcRunProgram",
- "RiProcDynamicLoad", "RiProcFree"]:
- if hasattr(rimod, name):
- setattr(self, name, getattr(rimod, name))
-
- # Variable declarations.
- # Key: Variable name - Value: (class, type, n)
- self._declarations = {}
- self._standardDeclarations(self._ri)
-
- # Stores the _ProceduralWrapper objects
- self._procWrappers = {}
-
- # Lookup table ctypes type -> numpy type
- self._numpyTypes = {}
- if _has_numpy:
- # Fill the _numpyTypes dict
- RtFloat = self._ri.RtFloat
- if RtFloat==ctypes.c_float:
- self._numpyTypes[RtFloat] = numpy.float32
- elif RtFloat==ctypes.c_double:
- self._numpyTypes[RtFloat] = numpy.float64
- else:
- raise TypeError("RtFloat is of an unknown type")
-
- self._numpyTypes[self._ri.RtInt] = numpy.int_
-
-
- def _getRiLastError(self):
- return self._ri.RiLastError
-
- def _setRiLastError(self, val):
- self._ri.RiLastError = val
-
- RiLastError = property(_getRiLastError, _setRiLastError)
- LastError = property(_getRiLastError, _setRiLastError)
-
- def RiArchiveRecord(self, type, format, *args):
- """Output a user data record.
-
- type is one of RI_COMMENT, RI_STRUCTURE or RI_VERBATIM.
-
- Example: RiArchiveRecord(RI_COMMENT, "Frame %d", 2)
- """
- self._ri.RiArchiveRecord(type, format, *args)
-
- def RiAreaLightSource(self, name, *paramlist, **keyparams):
- """Start the definition of an area light and return the light handle.
-
- Example: RiAttributeBegin()
- area1 = RiAreaLightSource("arealight", intensity=0.75)
- ....
- RiAttributeEnd()
- RiIlluminate(area1, RI_TRUE)
- """
- self._ri.RiAreaLightSource(name, *self._createCParamList(paramlist, keyparams))
-
- def RiAtmosphere(self, name, *paramlist, **keyparams):
- """Set the current atmosphere shader.
-
- If name is RI_NULL then no atmosphere shader is used.
-
- Example: RiAtmosphere("fog")
- """
- self._ri.RiAtmosphere(name, *self._createCParamList(paramlist, keyparams))
-
- def RiAttribute(self, name, *paramlist, **keyparams):
- """Set an implementation-specific attribute.
-
- Example: RiAttribute("displacementbound", "sphere", 0.5)
- """
- a = self._createCParamList(paramlist, keyparams)
- self._ri.RiAttribute(name, *self._createCParamList(paramlist, keyparams))
-
- def RiAttributeBegin(self):
- """Push the current set of attributes onto the attribute stack.
-
- Example: RiAttributeBegin()
- ...
- RiAttributeEnd()
- """
- self._ri.RiAttributeBegin()
-
- def RiAttributeEnd(self):
- """Pops the current set of attributes from the attribute stack."""
- self._ri.RiAttributeEnd()
-
- def RiBasis(self, ubasis, ustep, vbasis, vstep):
- """Set the current basis for the u and v direction.
-
- ubasis/vbasis can either be one of the predefined basis matrices
- RiHermiteBasis, RiCatmullRomBasis, RiBezierBasis, RiBSplineBasis,
- RiPowerBasis or it can be a user defined matrix.
-
- For the predefined matrices there are also predefined variables
- which can be used for the step parameters:
- RI_HERMITESTEP, RI_CATMULLROMSTEP, RI_BEZIERSTEP, RI_BSPLINESTEP,
- RI_POWERSTEP.
-
- Example: RiBasis(RiBezierBasis, RI_BEZIERSTEP,
- RiHermiteBasis, RI_HERMITESTEP)
- """
- ubasis = self._toCArray(self._ri.RtFloat, ubasis)
- vbasis = self._toCArray(self._ri.RtFloat, vbasis)
- self._ri.RiBasis(ubasis, ustep, vbasis, vstep)
-
- def RiBegin(self, name):
- """Starts the main block using a particular rendering method.
-
- The default renderer is selected by passing RI_NULL as name.
-
- Example: RiBegin(RI_NULL)
- ...
- RiEnd()
- """
- self._ri.RiBegin(name)
-
- def RiBlobby(self, nleaf, code, floats, strings, *paramlist, **keyparams):
- """Create a blobby surface.
-
- Number of array elements for primitive variables:
- -------------------------------------------------
- constant: 1 varying: nleaf
- uniform: 1 vertex: nleaf
-
- Example: RiBlobby(2, [1001,0, 1003,0,16, 0,2,0,1],
- [1.5,0,0,0, 0,1.5,0,0, 0,0,1.5,0, 0,0,-.1,1,
- 0.4, 0.01,0.3, 0.08], ["flat.zfile"])
- """
- code = self._toCArray(self._ri.RtInt, code)
- floats = self._toCArray(self._ri.RtFloat, floats)
- strings = self._toCArray(self._ri.RtString, strings)
- self._ri.RiBlobby(nleaf, len(code), code, len(floats), floats, len(strings), strings, *self._createCParamList(paramlist, keyparams))
-
- def RiBound(self, bound):
- """Set the bounding box for subsequent primitives.
-
- bound must be a sequence of six floating point values specifying
- the extent of the box along each coordinate direction:
- bound = [xmin, xmax, ymin, ymax, zmin, zmax]
-
- Example: RiBound([-1,1, 0,1, 0.5,0.75])
- """
- bound = self._toCArray(self._ri.RtFloat, bound)
- self._ri.RiBound(bound)
-
- def RiClipping(self, near, far):
- """Sets the near and the far clipping plane along the direction of view.
-
- near and far must be positive values in the range from RI_EPSILON to
- RI_INFINITY.
-
- Example: RiClipping(0.1, 100)
- """
- self._ri.RiClipping(near, far)
-
- def RiClippingPlane(self, x, y, z, nx, ny, nz):
- """Adds a new clipping plane, defined by a surface point and its normal.
-
- All the geometry in positive normal direction is clipped.
-
- Example: RiClippingPlane(0,0,0, 0,0,-1) clips everything below the XY plane
- """
- self._ri.RiClippingPlane(x, y, z, nx, ny, nz)
-
- def RiColor(self, Cs):
- """Set the current color.
-
- Cs must be a sequence of at least N values where N is the number of
- color samples (set by RiColorSamples(), default is 3).
-
- Example: RiColor([0.2,0.5,0.2])
- """
- Cs = self._toCArray(self._ri.RtFloat, Cs)
- self._ri.RiColor(Cs)
-
- def RiColorSamples(self, nRGB, RGBn):
- """Redefine the number of color components to be used for specifying colors.
-
- nRGB is a n x 3 matrix that can be used to transform the n component color
- to a RGB color (n -> RGB).
- RGBn is just the opposite, its a 3 x n matrix that's used to transform
- a RGB color to a n component color (RGB -> n).
- Thus, the new number of color components is len(matrix)/3 (matrix is
- either nRGB or RGBn).
-
- Example: RiColorSamples([0.3,0.3,0.3], [1,1,1])
- """
- nRGB = self._toCArray(self._ri.RtFloat, nRGB)
- RGBn = self._toCArray(self._ri.RtFloat, RGBn)
- if len(nRGB)!=len(RGBn):
- raise ValueError, "The conversion matrices must have the same number of elements."
- if len(nRGB)%3!=0:
- raise ValueError, "Invalid number of elements in the conversion matrices."
- n = len(nRGB)/3
- self._ri.RiColorSamples(n, nRGB, RGBn)
-
- def RiConcatTransform(self, transform):
- """Concatenate a transformation onto the current transformation.
-
- transform must be a sequence that evaluates to 16 floating point
- values (4x4 matrix).
-
- Example: RiConcatTransform([2,0,0,0, 0,2,0,0, 0,0,2,0, 0,0,0,1])
- RiConcatTransform([[2,0,0,0], [0,2,0,0], [0,0,2,0], [0,0,0,1]])
- """
- transform = self._toCArray(self._ri.RtFloat, transform)
- self._ri.RiConcatTransform(transform)
-
- def RiCone(self, height, radius, thetamax, *paramlist, **keyparams):
- """Create a cone (along the z axis).
-
- Number of array elements for primitive variables:
- -------------------------------------------------
- constant: 1 varying: 4
- uniform: 1 vertex: 4
-
- Example: RiCone(1.5, 0.7, 360)
- """
- self._ri.RiCone(height, radius, thetamax, *self._createCParamList(paramlist, keyparams))
-
- def RiContext(self, handle):
- """Set the current active rendering context.
-
- Example: ctx1 = RiGetContext()
- ...
- RiContext(ctx1)
- """
- self._ri.RiContext(handle)
-
- def RiCoordinateSystem(self, spacename):
- """Mark the current coordinate system with a name.
-
- Example: RiCoordinateSystem("lamptop")
- """
- self._ri.RiCoordinateSystem(spacename)
-
- def RiCoordSysTransform(self, spacename):
- """Replace the current transformation matrix with spacename.
-
- Example: RiCoordSysTransform("lamptop")
- """
- self._ri.RiCoordSysTransform(spacename)
-
- def RiCropWindow(self, left, right, bottom, top):
- """Specify a subwindow to render.
-
- The values each lie between 0 and 1.
-
- Example: RiCropWindow(0.0, 1.0 , 0.0, 1.0) (renders the entire frame)
- RiCropWindow(0.5, 1.0 , 0.0, 0.5) (renders the top right quarter)
- """
- self._ri.RiCropWindow(left, right, bottom, top)
-
- def RiCurves(self, type, nvertices, wrap, *paramlist, **keyparams):
- """Create a number of curve primitives.
-
- type is either RI_LINEAR or RI_CUBIC.
- nvertices is an array with the number of vertices in each curve.
- wrap is either RI_PERIODIC or RI_NONPERIODIC.
- The width of the curves can be specified with the parameter
- RI_WIDTH (varying float) or RI_CONSTANTWIDTH (constant float).
-
- Number of array elements for primitive variables:
- -------------------------------------------------
- constant: 1 varying: #segments (depends on type and wrap)
- uniform: #curves vertex: #points
-
- Example: RiCurves(RI_CUBIC, [4], RI_NONPERIODIC,
- P=[0,0,0, -1,-0.5,1, 2,0.5,1, 1,0,-1],
- width=[0.1, 0.04])
- """
- nvertices = self._toCArray(self._ri.RtInt, nvertices)
- self._ri.RiCurves(type, len(nvertices), nvertices, wrap, *self._createCParamList(paramlist, keyparams))
-
- def RiCylinder(self, radius,zmin,zmax,thetamax,*paramlist, **keyparams):
- """Create a cylinder (along the z axis).
-
- Number of array elements for primitive variables:
- -------------------------------------------------
- constant: 1 varying: 4
- uniform: 1 vertex: 4
-
- Example: RiCylinder(1.5, 0.0, 1.0, 360)
- """
- self._ri.RiCylinder(radius, zmin, zmax, thetamax, *self._createCParamList(paramlist, keyparams))
-
- def RiDeclare(self, name, declaration):
- """Declare the name and type of a variable.
-
- The syntax of the declaration is: [class] [type] ['['n']']
-
- class ::= constant | uniform | varying | vertex
- type ::= float | integer | string | color | point | vector | normal |
- matrix | hpoint
-
- Example: RiDeclare("foo","uniform float")
- RiDeclare("bar","constant integer [4]")
- RiDeclare("mycolor", "varying color")
- """
- # Process the declaration internally so that parameter lists can be
- # constructed properly...
- decl = "%s %s"%(declaration, name)
- m = self._declRe.match(decl)
- if m is None:
- raise ValueError, "Invalid declaration: %s"%decl
- # Groups is a 4-tuple (class, type, n, name)
- grps = m.groups()
- self._declarations[grps[3]] = grps[:3]
-
- # Forward the call...
- return self._ri.RiDeclare(name, declaration)
-
- def RiDepthOfField(self, fstop, focallength, focaldistance):
- """Set depth of field parameters.
-
- If fstop is RI_INFINITY depth of field is turned off.
-
- Example: RiDepthOfField(22,45,1200)
- """
- self._ri.RiDepthOfField(fstop, focallength, focaldistance)
-
- def RiDetail(self, bound):
- """Set the current bounding box.
-
- bound must be a sequence of six floating point values specifying
- the extent of the box along each coordinate direction:
- bound = [xmin, xmax, ymin, ymax, zmin, zmax]
-
- Example: RiDetail([10,20,40,70,0,1])
- """
- bound = self._toCArray(self._ri.RtFloat, bound)
- self._ri.RiDetail(bound)
-
- def RiDetailRange(self, minvisible, lowertransition, uppertransition, maxvisible):
- """Set the current detail range.
-
- The values of the parameters must satisfy the following ordering:
- minvisible <= lowertransition <= uppertransition <= maxvisible
-
- lowertransition uppertransition
- visibility |____________________|
- ^ / \\
- | / \\
- |_____________/ \\_____________\\ Level of detail
- | | /
- minvisible maxvisible
-
- Example: RiDetailRange(0,0,10,20)
- """
- self._ri.RiDetailRange(minvisible, lowertransition, uppertransition, maxvisible)
-
- def RiDisk(self, height, radius, thetamax, *paramlist, **keyparams):
- """Create a disk (parallel to the XY plane).
-
- Number of array elements for primitive variables:
- -------------------------------------------------
- constant: 1 varying: 4
- uniform: 1 vertex: 4
-
- Example: RiDisk(0.0, 1.0, 360)"""
- self._ri.RiDisk(height, radius, thetamax, *self._createCParamList(paramlist, keyparams))
-
- def RiDisplacement(self, name, *paramlist, **keyparams):
- """Set the current displacement shader.
-
- Example: RiDisplacement("dented", km=1.5)
- """
- self._ri.RiDisplacement(name, *self._createCParamList(paramlist, keyparams))
-
- def RiDisplay(self, name, type, mode, *paramlist, **keyparams):
- """Specify the destination and type of the output.
-
- Example: RiDisplay("frame0001.tif", RI_FILE, RI_RGB)
- RiDisplay("myimage.tif", RI_FRAMEBUFFER, RI_RGB)
- """
- self._ri.RiDisplay(name, type, mode, *self._createCParamList(paramlist, keyparams))
-
- def RiEnd(self):
- """Terminates the main block.
- """
- self._ri.RiEnd()
-
- def RiErrorHandler(self, handler):
- try:
- self._ri.RiErrorHandler(handler)
- except ctypes.ArgumentError:
- self._ri.RiErrorHandler(self._ri.RtErrorHandler(handler))
-
- def RiExposure(self, gain, gamma):
- """Sets the parameters for the output color transformation.
-
- The transformation is color_out = (color_in*gain)^(1/gamma)
-
- Example: RiExposure(1.3, 2.2)
- """
- self._ri.RiExposure(gain, gamma)
-
- def RiExterior(self, name, *paramlist, **keyparams):
- """Set the current exterior volume shader.
-
- Example: RiExterior("fog")
- """
- self._ri.RiExterior(name, *self._createCParamList(paramlist, keyparams))
-
- def RiFormat(self, xres, yres, aspect):
- """Set the resolution of the output image and the aspect ratio of a pixel.
-
- Example: RiFormat(720,576,1)"""
- self._ri.RiFormat(xres, yres, aspect)
-
- def RiFrameAspectRatio(self, frameratio):
- """Set the ratio between width and height of the image.
-
- Example: RiFrameAspectRatio(4.0/3)
- """
- self._ri.RiFrameAspectRatio(frameratio)
-
- def RiFrameBegin(self, number):
- """Start a new frame.
-
- Example: RiFrameBegin(1)
- ...
- RiFrameEnd()
- """
- self._ri.RiFrameBegin(number)
-
- def RiFrameEnd(self):
- """Terminates a frame."""
- self._ri.RiFrameEnd()
-
- def RiGeneralPolygon(self, nverts, *paramlist, **keyparams):
- """Create a general planar concave polygon with holes.
-
- Number of array elements for primitive variables:
- -------------------------------------------------
- constant: 1 varying: #total vertices
- uniform: 1 vertex: #total vertices
-
- Example: RiGeneralPolygon([4,3], P=[0,0,0, 0,1,0, 0,1,1, 0,0,1, \\
- 0,0.25,0.5, 0,0.75,0.75, 0,0.75,0.25])
- """
- nverts = self._toCArray(self._ri.RtInt, nverts)
- self._ri.RiGeneralPolygon(len(nverts), nverts, *self._createCParamList(paramlist, keyparams))
-
- def RiGeometricApproximation(self, type, value):
- """Sets parameters for approximating surfaces.
-
- Example: RiGeometricApproximation(RI_FLATNESS, 0.5)
- """
- self._ri.RiGeometricApproximation(type, value)
-
- def RiGeometry(self, type, *paramlist, **keyparams):
- """Create an implementation-specific geometric primitive.
-
- Example: RiGeometry("teapot")
- """
- self._ri.RiGeometry(type, *self._createCParamList(paramlist, keyparams))
-
- def RiGetContext(self):
- """Set the current active rendering context.
-
- Example: ctx1 = RiGetContext()
- ...
- RiContext(ctx1)
- """
- return self._ri.RiGetContext()
-
- def RiHider(self, type, *paramlist, **keyparams):
- """Choose a hidden-surface elimination technique.
-
- Example: RiHider(RI_HIDDEN) (default)
- """
- self._ri.RiHider(type, *self._createCParamList(paramlist, keyparams))
-
- def RiHyperboloid(self, point1, point2, thetamax, *paramlist, **keyparams):
- """Create a hyperboloid (with the z axis as symmetry axis).
-
- Example: RiHyperboloid([1,0,0],[1,1,1],360)
- """
- point1 =self._toCArray(self._ri.RtFloat, point1)
- point2 =self._toCArray(self._ri.RtFloat, point2)
- self._ri.RiHyperboloid(point1, point2, thetamax, *self._createCParamList(paramlist, keyparams))
-
- def RiIdentity(self):
- """Set the current transformation to the identity.
-
- Example: RiIdentity()
- """
- self._ri.RiIdentity()
-
- def RiIlluminate(self, light, onoff):
- """Activate or deactive a light source.
-
- Example: RiIlluminate(lgt, RI_TRUE)
- """
- self._ri.RiIlluminate(light, onoff)
-
- def RiImager(self, name, *paramlist, **keyparams):
- """Set an imager shader.
-
- if name is RI_NULL, no imager shader is used.
-
- Example: RiImager("background", "color bgcolor", [0.3,0.3,0.9])
- """
- self._ri.RiImager(name, *self._createCParamList(paramlist, keyparams))
-
- def RiInterior(self, name, *paramlist, **keyparams):
- """Set the current interior volume shader.
-
- Example: RiInterior("water")
- """
- self._ri.RiInterior(name, *self._createCParamList(paramlist, keyparams))
-
- def RiLightSource(self, name, *paramlist, **keyparams):
- """Add another light source and return its light handle.
-
- name is the name of the light source shader.
-
- Example: light1 = RiLightSource("distantlight", intensity=1.5)
- """
- return self._ri.RiLightSource(name, *self._createCParamList(paramlist, keyparams))
-
- def RiMakeCubeFaceEnvironment(self, px,nx,py,ny,pz,nz, texname, fov, filterfunc, swidth, twidth, *paramlist, **keyparams):
- """Convert six image files into an environment map.
-
- The px/nx images are the views in positive/negative x direction.
- fov is the field of view that was used to generate the individual images.
- filterfunc is either one of the predefined filter (RiGaussianFilter,
- RiBoxFilter, RiTriangleFilter, RiSincFilter, RiCatmullRomFilter) or
- a callable that takes four float arguments x, y, width, height.
- swidth and twidth define the support of the filter.
-
- Example: RiMakeCubeFaceEnvironment("px.tif","nx.tif","py.tif","ny.tif",
- "pz.tif","nz.tif", "tex.tif", 92.0,
- RiGaussianFilter, 2,2)
- """
- swidth = self._ri.RtFloat(swidth)
- twidth = self._ri.RtFloat(twidth)
- # Try passing the function in directly first (in case it's a standard
- # filter). If this fails, function must be a custom filter.
- try:
- self._ri.RiMakeCubeFaceEnvironment(px, nx, py, ny, pz, nz, texname, fov, filterfunc, swidth, twidth, *self._createCParamList(paramlist, keyparams))
- except ctypes.ArgumentError:
- filterfunc = self._ri.RtFilterFunc(filterfunc)
- self._ri.RiMakeCubeFaceEnvironment(px, nx, py, ny, pz, nz, texname, fov, filterfunc, swidth, twidth, *self._createCParamList(paramlist, keyparams))
-
- def RiMakeLatLongEnvironment(self, picname, texname, filterfunc, swidth, twidth, *paramlist, **keyparams):
- """Convert an image file into an environment map.
-
- filterfunc is either one of the predefined filter (RiGaussianFilter,
- RiBoxFilter, RiTriangleFilter, RiSincFilter, RiCatmullRomFilter) or
- a callable that takes four float arguments x, y, width, height.
- swidth and twidth define the support of the filter.
-
- Example: RiMakeLatLongEnvironment("img.tif", "tex.tif",
- RiGaussianFilter, 2,2)
- """
- swidth = self._ri.RtFloat(swidth)
- twidth = self._ri.RtFloat(twidth)
- # Try passing the function in directly first (in case it's a standard
- # filter). If this fails, function must be a custom filter.
- try:
- self._ri.RiMakeLatLongEnvironment(picname, texname, filterfunc, swidth, twidth, *self._createCParamList(paramlist, keyparams))
- except ctypes.ArgumentError:
- filterfunc = self._ri.RtFilterFunc(filterfunc)
- self._ri.RiMakeLatLongEnvironment(picname, texname, filterfunc, swidth, twidth, *self._createCParamList(paramlist, keyparams))
-
- def RiMakeShadow(self, picname, shadowname, *paramlist, **keyparams):
- """Transform a depth image into a shadow map.
-
- Example: RiMakeShadow("depthimg.tif", "shadow.tif")
- """
- self._ri.RiMakeShadow(picname, shadowname, *self._createCParamList(paramlist, keyparams))
-
- def RiMakeTexture(self, picname, texname, swrap, twrap, filterfunc, swidth, twidth, *paramlist, **keyparams):
- """Convert an image file into a texture file.
-
- swrap and twrap are one of RI_PERIODIC, RI_CLAMP or RI_BLACK.
- filterfunc is either one of the predefined filter (RiGaussianFilter,
- RiBoxFilter, RiTriangleFilter, RiSincFilter, RiCatmullRomFilter) or
- a callable that takes four float arguments x, y, width, height.
- swidth and twidth define the support of the filter.
-
- Example: RiMakeTexture("img.tif", "tex.tif", RI_PERIODIC, RI_CLAMP, \\
- RiGaussianFilter, 2,2)
- """
- swidth = self._ri.RtFloat(swidth)
- twidth = self._ri.RtFloat(twidth)
- # Try passing the function in directly first (in case it's a standard
- # filter). If this fails, function must be a custom filter.
- try:
- self._ri.RiMakeTexture(picname, texname, swrap, twrap, filterfunc, swidth, twidth, *self._createCParamList(paramlist, keyparams))
- except ctypes.ArgumentError:
- filterfunc = self._ri.RtFilterFunc(filterfunc)
- self._ri.RiMakeTexture(picname, texname, swrap, twrap, filterfunc, swidth, twidth, *self._createCParamList(paramlist, keyparams))
-
- def RiMatte(self, onoff):
- """Indicates whether subsequent primitives are matte objects.
-
- Example: RiMatte(RI_TRUE)
- """
- self._ri.RiMatte(onoff)
-
- def RiMotionBegin(self, *times):
- """Start the definition of a moving primitive.
-
- You can specify the time values directly or inside a sequence,
- for example, RiMotionBegin(0,1) or RiMotionBegin([0,1]).
-
- Example: RiMotionBegin(0.0, 1.0)
- RiTranslate(1.0, 0.0, 0.0)
- RiTranslate(1.0, 2.0, 0.0)
- RiMotionEnd()
- """
- # For some reason the time values must be doubles...
- times = tuple(map(lambda v: ctypes.c_double(v), self._flatten(times)))
- self._ri.RiMotionBegin(len(times), *times)
-
- def RiMotionEnd(self):
- "Terminates the definition of a moving primitive."
- self._ri.RiMotionEnd()
-
- def RiNuPatch(self, nu, uorder, uknot, umin, umax, nv, vorder, vknot, vmin, vmax, *paramlist, **keyparams):
- """Create a NURBS patch.
-
- Number of array elements for primitive variables:
- -------------------------------------------------
- constant: 1 varying: #segment corners
- uniform: #segments vertex: nu*nv
- """
- uknot = self._toCArray(self._ri.RtFloat, uknot)
- vknot = self._toCArray(self._ri.RtFloat, vknot)
- self._ri.RiNuPatch(nu, uorder, uknot, umin, umax, nv, vorder, vknot, vmin, vmax, *self._createCParamList(paramlist, keyparams))
-
- def RiObjectBegin(self, *paramlist, **keyparams):
- """Start the definition of a retained model and return the object handle.
-
- Example: obj1 = RiObjectBegin()
- ...
- RiObjectEnd()
- """
- return self._ri.RiObjectBegin(*self._createCParamList(paramlist, keyparams))
-
- def RiObjectEnd(self):
- """Terminate the definition of a retained model."""
- self._ri.RiObjectEnd()
-
- def RiObjectInstance(self, handle):
- """Create an instance of a previously defined model.
-
- Example: RiObjectInstance(obj1)
- """
- self._ri.RiObjectInstance(handle)
-
- def RiOpacity(self, Os):
- """Set the current opacity.
-
- Os must be a sequence of at least N values where N is the number
- of color samples (set by RiColorSamples(), default is 3). The
- opacity values must lie in the range from 0 to 1 (where 0 means
- completely transparent and 1 means completely opaque).
-
- Example: RiOpacity([0,0,1])
- """
- Os = self._toCArray(self._ri.RtFloat, Os)
- self._ri.RiOpacity(Os)
-
- def RiOption(self, name, *paramlist, **keyparams):
- """Set an implementation-specific option.
-
- Example: RiOption("searchpath", "shader","~/shaders:&")
- """
- self._ri.RiOption(name, *self._createCParamList(paramlist, keyparams))
-
- def RiOrientation(self, orientation):
- """Set the orientation of subsequent surfaces.
-
- orientation is either RI_OUTSIDE, RI_INSIDE, RI_LH (left handed)
- or RI_RH (right handed).
- """
- self._ri.RiOrientation(orientation)
-
- def RiParaboloid(self, rmax, zmin, zmax, thetamax, *paramlist, **keyparams):
- """Create a paraboloid (with the z axis as symmetry axis).
-
- Number of array elements for primitive variables:
- -------------------------------------------------
- constant: 1 varying: 4
- uniform: 1 vertex: 4
-
- Example: RiParaboloid(1.0, 0.0, 1.0, 360)
- """
- self._ri.RiParaboloid(rmax, zmin, zmax, thetamax, *self._createCParamList(paramlist, keyparams))
-
- def RiPatch(self, type, *paramlist, **keyparams):
- """RiPatch(type, paramlist)
-
- type is one of RI_BILINEAR (4 vertices) or RI_BICUBIC (16 vertices).
-
- Number of array elements for primitive variables:
- -------------------------------------------------
- constant: 1 varying: 4
- uniform: 1 vertex: 4/16 (depends on type)
-
- Example: RiPatch(RI_BILINEAR, P=[0,0,0, 1,0,0, 0,1,0, 1,1,0])
- """
- self._ri.RiPatch(type, *self._createCParamList(paramlist, keyparams))
-
- def RiPatchMesh(self, type, nu, uwrap, nv, vwrap, *paramlist, **keyparams):
- """Create a mesh made of patches.
-
- type is one of RI_BILINEAR or RI_BICUBIC.
- uwrap/vwrap can be RI_PERIODIC or RI_NONPERIODIC.
- The number of control points is nu*nv.
-
- Number of array elements for primitive variables:
- -------------------------------------------------
- constant: 1 varying: #patch corners (depends on uwrap/vwrap)
- uniform: #patches vertex: nu*nv (same as "P")
-
- """
- self._ri.RiPatchMesh(type, nu, uwrap, nv, vwrap, *self._createCParamList(paramlist, keyparams))
-
- def RiPerspective(self, fov):
- """Concatenate a perspective transformation onto the current transformation.
-
- Example: RiPerspective(45)"""
- self._ri.RiPerspective(fov)
-
- def RiPixelFilter(self, function, xwidth, ywidth):
- """Set a pixel filter function and its width in pixels.
-
- function is either one of the predefined filter (RiGaussianFilter,
- RiBoxFilter, RiTriangleFilter, RiSincFilter, RiCatmullRomFilter) or
- a callable that takes four float arguments x, y, width, height.
- xwidth and ywidth define the support of the filter.
-
- Example: RiPixelFilter(RiGaussianFilter, 2.0, 1.0)
- """
- xwidth = self._ri.RtFloat(xwidth)
- ywidth = self._ri.RtFloat(ywidth)
- # Try passing the function in directly first (in case it's a standard
- # filter). If this fails, function must be a custom filter.
- try:
- self._ri.RiPixelFilter(function, xwidth, ywidth)
- except ctypes.ArgumentError:
- self._ri.RiPixelFilter(self._ri.RtFilterFunc(function), xwidth, ywidth)
-
- def RiPixelSamples(self, xsamples, ysamples):
- """Set the sampling rate in horizontal and vertical direction.
-
- Example: RiPixelSamples(2,2)"""
- self._ri.RiPixelSamples(xsamples, ysamples)
-
- def RiPixelVariance(self, variance):
- """Limit the acceptable variance in the output value of pixels.
-
- Example: RiPixelVariance(0.01)"""
- self._ri.RiPixelVariance(variance)
-
- def RiPoints(self, *paramlist, **keyparams):
- """Create individual points.
-
- The size of the points can be either set with the primitive variable
- RI_WIDTH (one float per point) or RI_CONSTANTWIDTH (one float for all
- points).
-
- Number of array elements for primitive variables:
- -------------------------------------------------
- constant: 1 varying: #points
- uniform: 1 vertex: #points
- """
- params = self._createCParamList(paramlist, keyparams)
- for i in range(0, len(params), 2):
- if params[i]=="P":
- n = len(params[i+1])
- if n%3!=0:
- raise ValueError, 'Invalid number of floats in the "P" parameter.'
- n /= 3
- break
- else:
- raise ValueError, 'Parameter "P" is missing.'
- self._ri.RiPoints(n, *params)
-
- def RiPointsGeneralPolygons(self, nloops, nverts, vertids, *paramlist, **keyparams):
- """Create a polyhedron made of general planar concave polygons.
-
- nloops: The number of loops for each polygon
- nverts: The number of vertices in each loop
- vertids: The vertex indices of the loop vertices (0-based)
- The vertices themselves are stored in the parameter list (parameter "P").
-
- Number of array elements for primitive variables:
- -------------------------------------------------
- constant: 1 varying: #vertices (*)
- uniform: #polygons vertex: #vertices (*)
-
- (*) max(vertids)+1
- """
- nloops = self._toCArray(self._ri.RtInt, nloops)
- nverts = self._toCArray(self._ri.RtInt, nverts)
- vertids = self._toCArray(self._ri.RtInt, vertids)
- self._ri.RiPointsGeneralPolygons(len(nloops), nloops, nverts, vertids, *self._createCParamList(paramlist, keyparams))
-
- def RiPointsPolygons(self, nverts, vertids, *paramlist, **keyparams):
- """Create a polyhedron made of planar convex polygons that share vertices.
-
- nverts: An array with the number of vertices in each polygon
- vertids: The vertex indices of the polygon vertices (0-based)
- The vertices themselves are stored in the parameter list (parameter "P").
-
- Number of array elements for primitive variables:
- -------------------------------------------------
- constant: 1 varying: #vertices (*)
- uniform: #polygons vertex: #vertices (*)
-
- (*) max(vertids)+1
- """
- nverts = self._toCArray(self._ri.RtInt, nverts)
- vertids = self._toCArray(self._ri.RtInt, vertids)
- self._ri.RiPointsPolygons(len(nverts), nverts, vertids, *self._createCParamList(paramlist, keyparams))
-
- def RiPolygon(self, *paramlist, **keyparams):
- """Create a planar and convex polygon.
-
- The parameter list must include at least position ("P") information.
-
- Number of array elements for primitive variables:
- -------------------------------------------------
- constant: 1 varying: #vertices
- uniform: 1 vertex: #vertices
-
- Example: RiPolygon(P=[0,1,0, 0,1,1, 0,0,1, 0,0,0])
- """
- params = self._createCParamList(paramlist, keyparams)
- for i in range(0, len(params), 2):
- if params[i]=="P":
- n = len(params[i+1])
- if n%3!=0:
- raise ValueError, 'Invalid number of floats in the "P" parameter.'
- n /= 3
- break
- else:
- raise ValueError, 'Parameter "P" is missing.'
- self._ri.RiPolygon(n, *params)
-
- def RiProcedural(self, data, bound, subdividefunc, freefunc=None):
- """Declare a procedural model.
-
- subdividefunc and freefunc may either be the standard RenderMan
- procedurals (RiProcDelayedReadArchive, RiProcRunProgram,
- RiProcDynamicLoad and RiProcFree) or Python callables.
- In the former case, data must be a sequence of strings or a single
- string containing the data for the functions. In the latter case,
- data may be any Python object which is just passed on to the
- functions.
- freefunc is optional and defaults to None.
-
- Example: RiProcedural("mymodel.rib", [-1,1,-1,1,-1,1], \\
- RiProcDelayedReadArchive, RI_NULL)
-
- RiProcedural(["python teapot.py",""],[0,1,0,1,0,1], \\
- RiProcRunProgram, RI_NULL)
-
- RiProcedural(["teapot.so",""],[0,1,0,1,0,1], \\
- RiProcDynamicLoad, RI_NULL)
- """
- bound = self._toCArray(self._ri.RtFloat, bound)
-
- callMode = 0
- # Try to convert the data into a string array. If this fails,
- # don't even try to do a call without function wrapper...
- try:
- if data is None:
- data2 = ""
- else:
- data2 = data
- # Put everything into a list and append an empty string. This is
- # done so that you can also just pass one single string in all cases.
- data2 = [data2]+[""]
- stringArray = self._toCArray(self._ri.RtString, data2)
- except:
- callMode = 1
-
- # Try to use the functions directly (this will only work for builtin functions)...
- if callMode==0:
- try:
- self._ri.RiProcedural(ctypes.byref(stringArray), bound, subdividefunc, freefunc)
- callMode = 2
- except ctypes.ArgumentError:
- callMode = 1
-
- # Use a wrapper function (this must be used for Python callables)...
- if callMode==1:
- procWrapper = _ProceduralWrapper(RMAPI=self, data=data, subdivFunc=subdividefunc, freeFunc=freefunc)
- # Keep a reference to the instance so that it is kept alive...
- self._procWrappers[procWrapper] = 1
- # Call the procedural function (the data value is now the wrapped
- # one from within the wrapper object)...
- self._ri.RiProcedural(0, bound, procWrapper.cSubdivideFunc, procWrapper.cFreeFunc)
-
-
- def RiProjection(self, name, *paramlist, **keyparams):
- """Specify a projection method.
-
- The standard projections are RI_PERSPECTIVE and RI_ORTHOGRAPHIC.
- The perspective projection takes one optional parameter, RI_FOV.
-
- Example: RiProjection(RI_PERSPECTIVE, fov=45)
- """
- self._ri.RiProjection(name, *self._createCParamList(paramlist, keyparams))
-
- def RiQuantize(self, type, one, min, max, ditheramplitude):
- """Set the quantization parameters for colors and depth.
-
- Example: RiQuantize(RI_RGBA, 2048, -1024, 3071, 1.0)
- """
- self._ri.RiQuantize(type, one, min, max, ditheramplitude)
-
- def RiReadArchive(self, filename, callback=None, *paramlist, **keyparams):
- """Include an archive file.
-
- RiExample: RiReadArchive("teapot.rib")
- """
- if callable(callback):
- callback = self._ri.RtArchiveCallback(callback)
- self._ri.RiReadArchive(filename, callback, *self._createCParamList(paramlist, keyparams))
-
- def RiRelativeDetail(self, relativedetail):
- """Set the factor for all level of detail calculations.
-
- Example: RiRelativeDetail(0.7)"""
- self._ri.RiRelativeDetail(relativedetail)
-
- def RiReverseOrientation(self):
- """Causes the current orientation to be toggled.
-
- Example: RiReverseOrientation()
- """
- self._ri.RiReverseOrientation()
-
- def RiRotate(self, angle, *axis):
- """Rotate about angle degrees about the given axis.
-
- The axis is either given as 3 scalars or a sequence of 3 scalars.
-
- Example: RiRotate(90, 1,0,0)
- """
- axis = self._toCArray(self._ri.RtFloat, axis)
- self._ri.RiRotate(angle, *tuple(axis))
-
- def RiScale(self, *scale):
- """Concatenate a scaling onto the current transformation.
-
- The scaling is either given as 3 scalars or a sequence of 3 scalars.
-
- Example: RiScale(2,2,2)"""
- scale = self._toCArray(self._ri.RtFloat, scale)
- self._ri.RiScale(*tuple(scale))
-
- def RiScreenWindow(self, left, right, bottom, top):
- """Specify the extents of the output image on the image plane.
-
- Example: RiScreenWindow(-1,1,-1,1)
- """
- self._ri.RiScreenWindow(left, right, bottom, top)
-
- def RiShadingInterpolation(self, type):
- """Specify how shading samples are interpolated.
-
- type can be RI_CONSTANT or RI_SMOOTH.
-
- Example: RiShadingInterpolation(RI_SMOOTH)"""
- self._ri.RiShadingInterpolation(type)
-
- def RiShadingRate(self, size):
- """Set the current shading rate to an area of size pixels.
-
- Example: RiShadingRate(1.0)
- """
- self._ri.RiShadingRate(size)
-
- def RiShutter(self, opentime, closetime):
- """Set the times at which the shutter opens and closes.
-
- Example: RiShutter(0.1, 0.9)
- """
- self._ri.RiShutter(opentime, closetime)
-
- def RiSides(self, nsides):
- """Specify the number of visible sides of subsequent surfaces.
-
- Example: RiSides(1)"""
- self._ri.RiSides(nsides)
-
- def RiSkew(self, angle, *vecs):
- """Concatenate a skew onto the current transformation.
-
- angle is given in degrees.
- The two vectors are each given as 3 scalars or a sequence
- of 3 scalars.
-
- Example: RiSkew(45, 0,1,0, 1,0,0)
- """
- vecs = self._flatten(vecs)
- self._ri.RiSkew(angle, *vecs)
-
- def RiSolidBegin(self, type):
- """Start the definition of a solid object.
-
- type is one of RI_PRIMITIVE, RI_UNION, RI_DIFFERENCE and RI_INTERSECTION.
-
- Example: RiSolidBegin(RI_INTERSECTION)
- RiSolidBegin(RI_PRIMITIVE)
- ...
- RiSolidEnd()
- RiSolidBegin(RI_PRIMITIVE)
- ...
- RiSolidEnd()
- RiSolidEnd()
- """
- self._ri.RiSolidBegin(type)
-
- def RiSolidEnd(self):
- """Terminate the definition of a solid object."""
- self._ri.RiSolidEnd()
-
- def RiSphere(self, radius,zmin,zmax,thetamax,*paramlist, **keyparams):
- """Create a sphere.
-
- Number of array elements for primitive variables:
- -------------------------------------------------
- constant: 1 varying: 4
- uniform: 1 vertex: 4
-
- Example: RiSphere(1.0, -1.0, 1.0, 360)
- """
- self._ri.RiSphere(radius, zmin, zmax, thetamax, *self._createCParamList(paramlist, keyparams))
-
- def RiSubdivisionMesh(self, scheme, nverts, vertids, tags, nargs, intargs, floatargs, *paramlist, **keyparams):
- """Create a subdivision surface.
-
- The only standard scheme is currently "catmull-clark".
- nverts: The number of vertices in each face
- vertids: The vertex indices of the face vertices (0-based)
- tags: A string array of tag names.
- nargs: The number of int and float args for each tag.
- intargs: The integer arguments.
- floatargs: The float arguments.
- The vertices themselves are stored in the parameter list (parameter "P").
-
-
- Number of array elements for primitive variables:
- -------------------------------------------------
- constant: 1 varying: #vertices (*)
- uniform: #faces vertex: #vertices (*)
-
- (*) max(vertids)+1
- """
- nverts = self._toCArray(self._ri.RtInt, nverts)
- vertids = self._toCArray(self._ri.RtInt, vertids)
- tags = self._toCArray(self._ri.RtToken, tags)
- nargs = self._toCArray(self._ri.RtInt, nargs)
- intargs = self._toCArray(self._ri.RtInt, intargs)
- floatargs = self._toCArray(self._ri.RtFloat, floatargs)
- self._ri.RiSubdivisionMesh(scheme, len(nverts), nverts, vertids, len(tags), tags, nargs, intargs, floatargs, *self._createCParamList(paramlist, keyparams))
-
- def RiSurface(self, name, *paramlist, **keyparams):
- """Set the current surface shader.
-
- Example: RiSurface("plastic", Kd=0.7, Ks=0.3)"""
- self._ri.RiSurface(name, *self._createCParamList(paramlist, keyparams))
-
- def RiTextureCoordinates(self, s1, t1, s2, t2, s3, t3, s4, t4):
- """Set the current set of texture coordinates.
-
- Declares a projection from the unit square [(0,0), (1,0), (0,1), (1,1)]
- in parameter space to quadrilateral [(s1,t1), (s2,t2), (s3,t3), (s4,t4)]
- in texture space.
-
- Example: RiTextureCoordinates(0.0, 0.0, 2.0, -0.5, -0.5, 1.75, 3.0, 3.0)"""
- self._ri.RiTextureCoordinates(s1, t1, s2, t2, s3, t3, s4, t4)
-
- def RiTorus(self, major, minor, phimin, phimax, thetamax, *paramlist, **keyparams):
- """Create a torus (with the z axis as symmetry axis).
-
- Number of array elements for primitive variables:
- -------------------------------------------------
- constant: 1 varying: 4
- uniform: 1 vertex: 4
-
- Example: RiTorus(1.5, 0.1, 0, 360, 360)
- """
- self._ri.RiTorus(major, minor, phimin, phimax, thetamax, *self._createCParamList(paramlist, keyparams))
-
- def RiTransform(self, transform):
- """Set the current transformation.
-
- transform must be a sequence that evaluates to 16 floating point
- values (4x4 matrix).
-
- Example: RiTransform([2,0,0,0, 0,2,0,0, 0,0,2,0, 0,0,0,1])
- RiTransform([[2,0,0,0], [0,2,0,0], [0,0,2,0], [0,0,0,1]])
- """
- transform = self._toCArray(self._ri.RtFloat, transform)
- self._ri.RiTransform(transform)
-
- def RiTransformBegin(self):
- """Push the current transformation on the transformation stack.
-
- Example: RiTransformBegin()
- ...
- RiTransformEnd()
- """
- self._ri.RiTransformBegin()
-
- def RiTransformEnd(self):
- """Pop the current transformation from the stack."""
- self._ri.RiTransformEnd()
-
- def RiTransformPoints(self, fromspace, tospace, points):
- """Transform a set of points from one space to another.
-
- points must be a sequence of points where each point is another
- sequence with 3 floats.
- The return value is a sequence of vec3 objects containing the
- transformed points. None is returned in case of an error.
- """
- points = (len(points)*self._ri.RtPoint)(*map(lambda p: tuple(p), points))
- n = len(points)
- res = self._ri.RiTransformPoints(fromspace, tospace, n, points)
- if res==0:
- return None
-
- return map(lambda p: vec3(p), points)
-
- def RiTranslate(self, *translate):
- """Concatenate a translation onto the current transformation.
-
- The translation is either given as 3 scalars or a sequence of
- 3 scalars.
-
- Example: RiTranslate(1.2, 4.3, -0.5)
- or
- RiTranslate( (1.2, 4.3, -0.5) )
- """
- translate = self._toCArray(self._ri.RtFloat, translate)
- self._ri.RiTranslate(*tuple(translate))
-
- def RiTrimCurve(self, ncurves, order, knot, min, max, n, u, v, w):
- """Set the current trim curve.
- """
- ncurves = self._toCArray(self._ri.RtInt, ncurves)
- order = self._toCArray(self._ri.RtInt, order)
- knot = self._toCArray(self._ri.RtFloat, knot)
- min = self._toCArray(self._ri.RtFloat, min)
- max = self._toCArray(self._ri.RtFloat, max)
- n = self._toCArray(self._ri.RtInt, n)
- u = self._toCArray(self._ri.RtFloat, u)
- v = self._toCArray(self._ri.RtFloat, v)
- w = self._toCArray(self._ri.RtFloat, w)
- self._ri.RiTrimCurve(len(ncurves), ncurves, order, knot, min, max, n, u, v, w)
-
- def RiWorldBegin(self):
- """Start the world block.
-
- Example: RiWorldBegin()
- ...
- RiWorldEnd()
- """
- self._ri.RiWorldBegin()
-
- def RiWorldEnd(self):
- """Terminates the world block."""
- self._ri.RiWorldEnd()
-
-
- def _toCArray(self, ctype, seq):
- """Convert and flatten a sequence into a ctypes array.
-
- ctype is the base type of the array and seq is the sequence that is
- to be flattened and converted. The return value is a ctypes
- array type with ctype as element type.
- If seq is already a ctypes sequence or a numpy array then no
- data conversion is done and the input is used directly.
- """
- # Is the value already a ctypes array? Then there's nothing to do
- if isinstance(seq, ctypes.Array):
- if seq._type_!=ctype:
- raise TypeError, "ctypes array should be of type %s instead of %s"%(getattr(ctype, "__name__", "?"), getattr(seq._type_, "__name__", "?"))
- return seq
-
- # Is the sequence a numpy array?
- if hasattr(seq, "ctypes"):
- try:
- self._assertNumPyArrayType(seq, ctype)
- except TypeError, e:
- raise TypeError("numpy error: %s"%e)
- n = seq.size
- Cls = (n*ctype)
- seq = Cls.from_address(seq.ctypes.data)
- return seq
-
- # Convert the sequence into a ctypes array...
- seq = self._flatten(seq)
- return (len(seq)*ctype)(*seq)
-
- def _assertNumPyArrayType(self, seq, ctype):
- """Make sure a numpy array contains elements of the correct type.
-
- seq must be a numpy array and ctype is the ctypes type that the
- array elements must match.
- Raises a TypeError exception when seq is of the wrong type.
- """
- dtype = self._numpyTypes.get(ctype, None)
- if dtype is None:
- raise TypeError, "numpy arrays cannot be used for this parameter type (%s)"%getattr(ctype, "__name__", "?")
- np = ndpointer(dtype=dtype, flags='CONTIGUOUS')
- # Just call from_param() to test the type. The actual return value is not needed.
- np.from_param(seq)
-
- def _flatten(self, seq):
- """Return a list of the individual items in a (possibly nested) sequence.
- """
- res = []
- ScalarTypes = [types.IntType, types.LongType, types.FloatType, types.StringType]
- for v in seq:
- vtype = type(v)
- # v=scalar?
- if vtype in ScalarTypes:
- res.append(v)
- # no stadard scalar or string. Then it might be a sequence..
- else:
- # Check if it is really a sequence...
- try:
- n = len(v)
- except:
- res.append(v)
- continue
- res += self._flatten(v)
- return res
-
- def _createCParamList(self, paramlist, keyparams):
- """
- Combine the keyparams with the paramlist into one paramlist
- and convert sequence values.
- Appends None (RI_NULL) to the parameter list.
- """
- # Combine the paramlist and keyparams values...
- res = ri._merge_paramlist(paramlist, keyparams)
-
- # Check if the values need conversion...
- for i in range(0, len(res), 2):
- token = res[i].strip()
-
- ##### Determine the type of the variable #####
-
- # Try to process any inline declaration...
- m = self._declRe.match(token)
- # No inline declaration or invalid declaration...
- if m is None:
- # If the token doesn't contain a space then it must have been
- # just a name without inline declaration. In this case, try
- # to get the declaration from the previously declared tokens...
- if token.find(" ")==-1:
- decl = self._declarations.get(token, None)
- if decl is None:
- raise ValueError, 'Token "%s" is not declared.'%token
- else:
- raise ValueError, 'Invalid inline declaration: %s'%token
- else:
- decl = m.groups()[:3]
-
- cls,type,n = decl
-
- # The actual size is not checked here, so we only determine
- # the "base" type...
- if type=="integer":
- ctype = self._ri.RtInt
- elif type=="string":
- ctype = self._ri.RtString
- else:
- ctype = self._ri.RtFloat
-
- # Check if the value is a sequence. If not, turn it into a list...
- if isinstance(res[i+1], basestring):
- res[i+1] = [res[i+1]]
- try:
- n = len(res[i+1])
- except:
- res[i+1] = [res[i+1]]
-
- # Convert the value(s) into a ctypes array (even single values
- # must be converted)...
- try:
- res[i+1] = self._toCArray(ctype, res[i+1])
- except TypeError, e:
- raise TypeError('Parameter "%s": %s'%(res[i], e))
-
- res.append(None)
- return res
-
- def _standardDeclarations(self, ri):
- """Predeclare standard parameters.
- """
- decls = {ri.RI_AMPLITUDE:"uniform float",
- ri.RI_BACKGROUND:"color",
- ri.RI_BEAMDISTRIBUTION:"float",
- ri.RI_CONEANGLE:"float",
- ri.RI_CONEDELTAANGLE:"float",
- ri.RI_CONSTANTWIDTH:"constant float",
- ri.RI_CS:"varying color",
- ri.RI_DISTANCE:"float",
- ri.RI_FOV:"float",
- ri.RI_FROM:"point",
- ri.RI_HANDLEID:"string",
- ri.RI_INTENSITY:"float",
- ri.RI_KA:"uniform float",
- ri.RI_KD:"uniform float",
- ri.RI_KR:"uniform float",
- ri.RI_KS:"uniform float",
- ri.RI_LIGHTCOLOR:"color",
- ri.RI_MAXDISTANCE:"float",
- ri.RI_MINDISTANCE:"float",
- ri.RI_N:"varying normal",
- ri.RI_NP:"uniform normal",
- ri.RI_ORIGIN:"integer[2]",
- ri.RI_OS:"varying color",
- ri.RI_P:"vertex point",
- ri.RI_PW:"vertex hpoint",
- ri.RI_PZ:"vertex point",
- ri.RI_ROUGHNESS:"uniform float",
- ri.RI_S:"varying float",
- ri.RI_SPECULARCOLOR:"uniform color",
- ri.RI_ST:"varying float[2]",
- ri.RI_T:"varying float",
- ri.RI_TEXTURENAME:"string",
- ri.RI_TO:"point",
- ri.RI_WIDTH:"varying float",
- "shader":"string",
- "archive":"string",
- "texture":"string",
- "procedural":"string",
- "endofframe":"integer",
- "sphere":"float",
- "coordinatesystem":"string",
- "name":"string",
- "sense":"string"
- }
-
- # Fill the declarations dict...
- for name,decl in decls.iteritems():
- m = self._declRe.match("%s %s"%(decl, name))
- grps = m.groups()
- self._declarations[grps[3]] = grps[:3]
-