[cgkit-commits] SF.net SVN: cgkit: [221] cgkit/trunk/cgkit
Brought to you by:
mbaas
From: <mb...@us...> - 2008-01-27 20:30:37
|
Revision: 221 http://cgkit.svn.sourceforge.net/cgkit/?rev=221&view=rev Author: mbaas Date: 2008-01-27 12:30:33 -0800 (Sun, 27 Jan 2008) Log Message: ----------- Added a wrapper to the cri (now _cri) module. The interface is now compatible to the old ri module. Modified Paths: -------------- cgkit/trunk/cgkit/cri.py Added Paths: ----------- cgkit/trunk/cgkit/_cri.py Added: cgkit/trunk/cgkit/_cri.py =================================================================== --- cgkit/trunk/cgkit/_cri.py (rev 0) +++ cgkit/trunk/cgkit/_cri.py 2008-01-27 20:30:33 UTC (rev 221) @@ -0,0 +1,435 @@ +# ***** 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) 2004 +# 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 os.path +from ctypes import * +import ctypes.util + +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. + """ + + # Try to figure out the location of the lib if the name is not an absolute path... + if not os.path.isabs(libName): + p = ctypes.util.find_library(libName) + if p is not None: + libName = p + + # Load the library... + ri = cdll.LoadLibrary(libName) + + _createRiTypes(ri) + _createRiTokens(ri) + _createRiConstants(ri) + _createRiFunctions(ri) + + # Create an alias for every Ri function that has the prefix removed... + for name in dir(ri): + if name.startswith("Ri"): + setattr(ri, name[2:], getattr(ri, name)) + + ri.__class__.RiLastError = property(_getLastError, _setLastError) + ri.__class__.LastError = property(_getLastError, _setLastError) + + return ri + +def importRINames(ri, ns): + """Import the RenderMan names into the given namespace. + """ + for name in dir(ri): + if name.startswith("Ri"): + localName = name + ns[localName] = getattr(ri, name) + + if name[:2] in ["Rt", "RI"]: + ns[name] = getattr(ri, name) + + +def _createRiTypes(ri): + """Create the RenderMan types. + + The types are added as attributes to the ri object. All names + begin with "Rt" (RtInt, RtFloat, ...). + """ + + # Base types that are not composed of other RenderMan types... + baseTypes = dict(RtBoolean = c_short, + RtInt = c_int, + RtFloat = c_float, + RtString = c_char_p, + RtToken = c_char_p, + RtVoid = None, + RtPointer = c_void_p) + + for name,ctype in baseTypes.iteritems(): + setattr(ri, name, ctype) + + ri.RtColor = 3*ri.RtFloat + ri.RtPoint = 3*ri.RtFloat + ri.RtVector = 3*ri.RtFloat + ri.RtNormal = 3*ri.RtFloat + ri.RtHpoint = 4*ri.RtFloat + ri.RtMatrix = 16*ri.RtFloat + ri.RtBasis = 16*ri.RtFloat + ri.RtBound = 6*ri.RtFloat + + ri.RtObjectHandle = ri.RtPointer + ri.RtLightHandle = ri.RtPointer + ri.RtContextHandle = ri.RtPointer + + ri.RtFilterFunc = CFUNCTYPE(ri.RtFloat, ri.RtFloat, ri.RtFloat, ri.RtFloat, ri.RtFloat) + ri.RtErrorHandler = CFUNCTYPE(ri.RtVoid, ri.RtInt, ri.RtInt, c_char_p) + ri.RtProcSubdivFunc = CFUNCTYPE(ri.RtVoid, ri.RtPointer, ri.RtFloat) + ri.RtProcFreeFunc = CFUNCTYPE(ri.RtVoid, ri.RtPointer) + ri.RtArchiveCallback = CFUNCTYPE(ri.RtVoid, ri.RtToken, c_char_p) # var args are missing + +def _createRiConstants(ri): + """Create the RenderMan constants. + + The types must already be available on ri. + """ + + ri.RI_NULL = None + ri.RI_TRUE = 1 + ri.RI_FALSE = 0 + ri.RI_EPSILON = 1.0e-10 + ri.RI_INFINITY = ri.RtFloat(1.0e38).value + + ri.RI_HERMITESTEP = 2 + ri.RI_CATMULLROMSTEP = 1 + ri.RI_BEZIERSTEP = 3 + ri.RI_BSPLINESTEP = 1 + ri.RI_POWERSTEP = 4 + + bases = ["RiBezierBasis", "RiBSplineBasis", "RiCatmullRomBasis", + "RiHermiteBasis", "RiPowerBasis"] + + for basis in bases: + try: + value = ri.RtBasis.in_dll(ri, basis) + except ValueError: + raise ValueError, 'The RenderMan implementation "%s" does not define the standard basis "%s"'%(getattr(ri, "_name", "?"), basis) + setattr(ri, basis, value) + +def _createRiTokens(ri): + """Create the RenderMan tokens. + + The constants are added as attributes to the ri object. All names + begin with "RI_". + """ + + tokens = [("RI_A", "a"), + ("RI_ABORT", "abort"), + ("RI_AMBIENTLIGHT", "ambientlight"), + ("RI_AMPLITUDE", "amplitude"), + ("RI_AZ", "az"), + ("RI_BACKGROUND", "background"), + ("RI_BEAMDISTRIBUTION", "beamdistribution"), + ("RI_BICUBIC", "bicubic"), + ("RI_BILINEAR", "bilinear"), + ("RI_BLACK", "black"), + ("RI_BUMPY", "bumpy"), + ("RI_CAMERA", "camera"), + ("RI_CI", "Ci"), + ("RI_CLAMP", "clamp"), + ("RI_COMMENT", "comment"), + ("RI_CONEANGLE", "coneangle"), + ("RI_CONEDELTAANGLE", "conedeltaangle"), + ("RI_CONSTANT", "constant"), + ("RI_CONSTANTWIDTH", "constantwidth"), + ("RI_CS", "Cs"), + ("RI_CUBIC", "cubic"), + ("RI_DEPTHCUE", "depthcue"), + ("RI_DIFFERENCE", "difference"), + ("RI_DISTANCE", "distance"), + ("RI_DISTANTLIGHT", "distantlight"), + ("RI_FILE", "file"), + ("RI_FLATNESS", "flatness"), + ("RI_FOG", "fog"), + ("RI_FOV", "fov"), + ("RI_FRAMEBUFFER", "framebuffer"), + ("RI_FROM", "from"), + ("RI_HANDLER", "handler"), + ("RI_HIDDEN", "hidden"), + ("RI_IDENTIFIER", "identifier"), + ("RI_IGNORE", "ignore"), + ("RI_INSIDE", "inside"), + ("RI_INTENSITY", "intensity"), + ("RI_INTERSECTION", "intersection"), + ("RI_KA", "Ka"), + ("RI_KD", "Kd"), + ("RI_KR", "Kr"), + ("RI_KS", "Ks"), + ("RI_LH", "lh"), + ("RI_LIGHTCOLOR", "lightcolor"), + ("RI_LINEAR", "linear"), + ("RI_MATTE", "matte"), + ("RI_MAXDISTANCE", "maxdistance"), + ("RI_METAL", "metal"), + ("RI_MINDISTANCE", "mindistance"), + ("RI_N", "N"), + ("RI_NAME", "name"), + ("RI_NG", "Ng"), + ("RI_NONPERIODIC", "nonperiodic"), + ("RI_NP", "Np"), + ("RI_OBJECT", "object"), + ("RI_OI", "Oi"), + ("RI_ORIGIN", "origin"), + ("RI_ORTHOGRAPHIC", "orthographic"), + ("RI_OS", "Os"), + ("RI_OUTSIDE", "outside"), + ("RI_P", "P"), + ("RI_PAINT", "paint"), + ("RI_PAINTEDPLASTIC", "paintedplastic"), + ("RI_PERIODIC", "periodic"), + ("RI_PERSPECTIVE", "perspective"), + ("RI_PLASTIC", "plastic"), + ("RI_POINTLIGHT", "pointlight"), + ("RI_PRIMITIVE", "primitive"), + ("RI_PRINT", "print"), + ("RI_PW", "Pw"), + ("RI_PZ", "Pz"), + ("RI_RASTER", "raster"), + ("RI_RGB", "rgb"), + ("RI_RGBA", "rgba"), + ("RI_RGBAZ", "rgbaz"), + ("RI_RGBZ", "rgbz"), + ("RI_RH", "rh"), + ("RI_ROUGHNESS", "roughness"), + ("RI_S", "s"), + ("RI_SCREEN", "screen"), + ("RI_SHADINGGROUP", "shadinggroup"), + ("RI_SHINYMETAL", "shinymetal"), + ("RI_SMOOTH", "smooth"), + ("RI_SPECULARCOLOR", "specularcolor"), + ("RI_SPOTLIGHT", "spotlight"), + ("RI_ST", "st"), + ("RI_STRUCTURE", "structure"), + ("RI_T", "t"), + ("RI_TEXTURENAME", "texturename"), + ("RI_TO", "to"), + ("RI_UNION", "union"), + ("RI_VERBATIM", "verbatim"), + ("RI_WIDTH", "width"), + ("RI_WORLD", "world"), + ("RI_Z", "z"), + ] + + for tokSpec in tokens: + if isinstance(tokSpec, basestring): + name = tokSpec + default = None + else: + try: + name,default = tokSpec + if not isinstance(name, basestring): + raise ValueError() + except: + raise ValueError("Invalid token spec: %s"%(tokSpec,)) + + try: + value = c_char_p.in_dll(ri, name).value + except ValueError: + value = default + + setattr(ri, name, value) + + +def _createRiFunctions(ri): + # "Import" the types (so that we can write RtInt instead of ri.RtInt)... + for name in dir(ri): + if name.startswith("Rt"): + exec "%s = ri.%s"%(name, name) + + ri.RiArchiveRecord.argtypes = [RtToken, c_char_p] + ri.RiAreaLightSource.argtypes = [RtToken] + ri.RiAreaLightSource.restype = RtLightHandle + ri.RiAtmosphere.argtypes = [RtToken] + ri.RiAttribute.argtypes = [RtToken] + ri.RiAttributeBegin.argtypes = [] + ri.RiAttributeEnd.argtypes = [] + ri.RiBasis.argtypes = [RtBasis, RtInt, RtBasis, RtInt] + ri.RiBegin.argtypes = [RtToken] + ri.RiBlobby.argtypes = [RtInt, RtInt, POINTER(RtInt), RtInt, POINTER(RtFloat), RtInt, POINTER(RtString)] + ri.RiBound.argtypes = [RtBound] + ri.RiClipping.argtypes = [RtFloat, RtFloat] + ri.RiClippingPlane.argtypes = [RtFloat, RtFloat, RtFloat, RtFloat, RtFloat, RtFloat] + ri.RiColor.argtypes = [RtColor] + ri.RiColorSamples.argtypes = [RtInt, POINTER(RtFloat), POINTER(RtFloat)] + ri.RiConcatTransform.argtypes = [RtMatrix] + ri.RiCone.argtypes = [RtFloat, RtFloat, RtFloat] + ri.RiContext.argtypes = [RtContextHandle] + ri.RiCoordinateSystem.argtypes = [RtToken] + ri.RiCoordSysTransform.argtypes = [RtToken] + ri.RiCropWindow.argtypes = [RtFloat, RtFloat, RtFloat, RtFloat] + ri.RiCurves.argtypes = [RtToken, RtInt] + ri.RiCylinder.argtypes = [RtFloat, RtFloat, RtFloat, RtFloat] + ri.RiDeclare.argtypes = [c_char_p, c_char_p] + ri.RiDeclare.restype = RtToken + ri.RiDepthOfField.argtypes = [RtFloat, RtFloat, RtFloat] + ri.RiDetail.argtypes = [RtBound] + ri.RiDetailRange.argtypes = [RtFloat, RtFloat, RtFloat, RtFloat] + ri.RiDisk.argtypes = [RtFloat, RtFloat, RtFloat] + ri.RiDisplacement.argtypes = [RtToken] + ri.RiDisplay.argtypes = [RtToken, RtToken, RtToken] + ri.RiEnd.argtypes = [] + # See RiPixelFilter for an explanation why RiErrorHandler is commented out +# ri.RiErrorHandler.argtypes = [RtErrorHandler] + ri.RiExposure.argtypes = [RtFloat, RtFloat] + ri.RiExterior.argtypes = [RtToken] + ri.RiFormat.argtypes = [RtInt, RtInt, RtFloat] + ri.RiFrameAspectRatio.argtypes = [RtFloat] + ri.RiFrameBegin.argtypes = [RtInt] + ri.RiFrameEnd.argtypes = [] + ri.RiGeneralPolygon.argtypes = [RtInt, POINTER(RtInt)] + ri.RiGeometricApproximation.argtypes = [RtToken, RtFloat] + ri.RiGeometry.argtypes = [RtToken] + ri.RiGetContext.argtypes = [] + ri.RiGetContext.restype = RtContextHandle + ri.RiHider.argtypes = [RtToken] + ri.RiHyperboloid.argtypes = [RtPoint, RtPoint, RtFloat] + ri.RiIdentity.argtypes = [] + ri.RiIlluminate.argtypes = [RtLightHandle, RtBoolean] + ri.RiImager.argtypes = [RtToken] + ri.RiInterior.argtypes = [RtToken] + ri.RiLightSource.argtypes = [RtToken] + ri.RiLightSource.restype = RtLightHandle + ri.RiMakeCubeFaceEnvironment.argtypes = [c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, RtFloat, RtFilterFunc, RtFloat, RtFloat] + ri.RiMakeLatLongEnvironment.argtypes = [c_char_p, c_char_p, RtFilterFunc, RtFloat, RtFloat] + ri.RiMakeShadow.argtypes = [c_char_p, c_char_p] + ri.RiMakeTexture.argtypes = [c_char_p, c_char_p, RtToken, RtToken, RtFilterFunc, RtFloat, RtFloat] + ri.RiMatte.argtypes = [RtBoolean] + ri.RiMotionBegin.argtypes = [RtInt] + ri.RiMotionEnd.argtypes = [] + ri.RiNuPatch.argtypes = [RtInt, RtInt, POINTER(RtFloat), RtFloat, RtFloat, RtInt, RtInt, POINTER(RtFloat), RtFloat, RtFloat] + ri.RiObjectBegin.argtypes = [] + ri.RiObjectBegin.restype = RtObjectHandle + ri.RiObjectEnd.argtypes = [] + ri.RiObjectInstance.argtypes = [RtObjectHandle] + ri.RiOpacity.argtypes = [RtColor] + ri.RiOption.argtypes = [RtToken] + ri.RiOrientation.argtypes = [RtToken] + ri.RiParaboloid.argtypes = [RtFloat, RtFloat, RtFloat, RtFloat] + ri.RiPatch.argtypes = [RtToken] + ri.RiPatchMesh.argtypes = [RtToken, RtInt, RtToken, RtInt, RtToken] + ri.RiPerspective.argtypes = [RtFloat] + # The following line is commented out because declaring the first argument + # as RtFilterFunc will prevent the standard filters from being passed in directly + # so that the renderer recognizes them as standard filters (which is necessary + # during RIB generation so that the renderer can generate the appropriate + # filter name). +# ri.RiPixelFilter.argtypes = [RtFilterFunc, RtFloat, RtFloat] + ri.RiPixelSamples.argtypes = [RtFloat, RtFloat] + ri.RiPixelVariance.argtypes = [RtFloat] + ri.RiPoints.argtypes = [RtInt] + ri.RiPointsGeneralPolygons.argtypes = [RtInt, POINTER(RtInt), POINTER(RtInt), POINTER(RtInt)] + ri.RiPointsPolygons.argtypes = [RtInt, POINTER(RtInt), POINTER(RtInt)] + ri.RiPolygon.argtypes = [RtInt] + ri.RiProcedural.argtypes = [RtPointer, RtBound, RtProcSubdivFunc, RtProcFreeFunc] + ri.RiProjection.argtypes = [RtToken] + ri.RiQuantize.argtypes = [RtToken, RtInt, RtInt, RtInt, RtFloat] + ri.RiReadArchive.argtypes = [RtToken, RtArchiveCallback] + ri.RiRelativeDetail.argtypes = [RtFloat] + ri.RiReverseOrientation.argtypes = [] + ri.RiRotate.argtypes = [RtFloat, RtFloat, RtFloat, RtFloat] + ri.RiScale.argtypes = [RtFloat, RtFloat, RtFloat] + ri.RiScreenWindow.argtypes = [RtFloat, RtFloat, RtFloat, RtFloat] + ri.RiShadingInterpolation.argtypes = [RtToken] + ri.RiShadingRate.argtypes = [RtFloat] + ri.RiShutter.argtypes = [RtFloat, RtFloat] + ri.RiSides.argtypes = [RtInt] + ri.RiSkew.argtypes = [RtFloat, RtFloat, RtFloat, RtFloat, RtFloat, RtFloat, RtFloat] + ri.RiSolidBegin.argtypes = [RtToken] + ri.RiSolidEnd.argtypes = [] + ri.RiSphere.argtypes = [RtFloat, RtFloat, RtFloat, RtFloat] + ri.RiSubdivisionMesh.argtypes = [RtToken, RtInt, POINTER(RtInt), POINTER(RtInt), RtInt, POINTER(RtToken), POINTER(RtInt), POINTER(RtInt), POINTER(RtFloat)] + ri.RiSurface.argtypes = [RtToken] + ri.RiTextureCoordinates.argtypes = [RtFloat, RtFloat, RtFloat, RtFloat, RtFloat, RtFloat, RtFloat, RtFloat] + ri.RiTorus.argtypes = [RtFloat, RtFloat, RtFloat, RtFloat, RtFloat] + ri.RiTransform.argtypes = [RtMatrix] + ri.RiTransformBegin.argtypes = [] + ri.RiTransformEnd.argtypes = [] + ri.RiTransformPoints.argtypes = [RtToken, RtToken, RtInt, POINTER(RtPoint)] + ri.RiTransformPoints.restype = POINTER(RtPoint) + ri.RiTranslate.argtypes = [RtFloat, RtFloat, RtFloat] + ri.RiTrimCurve.argtypes = [RtInt, POINTER(RtInt), POINTER(RtInt), POINTER(RtFloat), POINTER(RtFloat), POINTER(RtFloat), POINTER(RtInt), POINTER(RtFloat), POINTER(RtFloat), POINTER(RtFloat)] + ri.RiWorldBegin.argtypes = [] + ri.RiWorldEnd.argtypes = [] + + ri.RiBoxFilter.argtypes = [c_float, c_float, c_float, c_float] + ri.RiBoxFilter.restype = c_float + ri.RiTriangleFilter.argtypes = [c_float, c_float, c_float, c_float] + ri.RiTriangleFilter.restype = c_float + ri.RiCatmullRomFilter.argtypes = [c_float, c_float, c_float, c_float] + ri.RiCatmullRomFilter.restype = c_float + ri.RiGaussianFilter.argtypes = [c_float, c_float, c_float, c_float] + ri.RiGaussianFilter.restype = c_float + ri.RiSincFilter.argtypes = [c_float, c_float, c_float, c_float] + ri.RiSincFilter.restype = c_float + + +def _getLastError(ri): + """Getter function for the RiLastError variable. + """ + try: + return c_int.in_dll(ri, "RiLastError").value + except ValueError: + return None + +def _setLastError(ri, value): + """Setter function for the RiLastError variable. + """ + try: + c_int.in_dll(ri, "RiLastError").value = value + except ValueError: + pass + + Modified: cgkit/trunk/cgkit/cri.py =================================================================== --- cgkit/trunk/cgkit/cri.py 2008-01-17 22:45:39 UTC (rev 220) +++ cgkit/trunk/cgkit/cri.py 2008-01-27 20:30:33 UTC (rev 221) @@ -41,9 +41,10 @@ # ------------------------------------------------------------- # $Id: ri.py,v 1.4 2006/02/14 19:29:39 mbaas Exp $ -import os.path -from ctypes import * -import ctypes.util +import ctypes, types, re +import _cri +from _cri import importRINames +import ri def loadRI(libName): """Load a RenderMan library and return a module-like handle to it. @@ -56,347 +57,598 @@ LoadLibrary() function. This handle has already been prepared so that it can be used like a module that contains the RenderMan interface. """ + + _ri = _cri.loadRI(libName) - # Try to figure out the location of the lib if the name is not an absolute path... - if not os.path.isabs(libName): - p = ctypes.util.find_library(libName) - if p is not None: - libName = p + return _RenderManAPI(_ri) + +class _RenderManAPI: + + def __init__(self, rimod): + self._ri = rimod - # Load the library... - ri = cdll.LoadLibrary(libName) + # 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)) + + for name in ["RiErrorAbort", "RiErrorIgnore", "RiErrorPrint", + "RiBoxFilter", "RiTriangleFilter", "RiCatmullRomFilter", + "RiGaussianFilter", "RiSincFilter", + "RiBezierBasis", "RiBSplineBasis", "RiCatmullRomBasis", + "RiHermiteBasis", "RiPowerBasis"]: + if hasattr(rimod, name): + setattr(self, name, getattr(rimod, name)) + + # Copy the doc strings from the ri module into the Ri methods... +# for name in dir(self): +# method = getattr(self.__class__, name) +# if not callable(method): +# continue +# func = getattr(ri, name, None) +# if func is not None and hasattr(func, "__doc__"): +# method.__doc__ = func.__doc__ + + # Key: Variable name - Value: (class, type, n) + self._declarations = {} + self._standardDeclarations(self._ri) + + def _getRiLastError(self): + return self._ri.RiLastError - _createRiTypes(ri) - _createRiConstants(ri) - _createRiFunctions(ri) + def _setRiLastError(self, val): + self._ri.RiLastError = val + + RiLastError = property(_getRiLastError, _setRiLastError) + LastError = property(_getRiLastError, _setRiLastError) + + def RiArchiveRecord(self, type, format, *args): + self._ri.RiArchiveRecord(type, format, *args) - # Create an alias for every Ri function that has the prefix removed... - for name in dir(ri): - if name.startswith("Ri"): - setattr(ri, name[2:], getattr(ri, name)) + def RiAreaLightSource(self, name, *paramlist, **keyparams): + self._ri.RiAreaLightSource(name, *self._createCParamList(paramlist, keyparams)) - ri.__class__.RiLastError = property(_getLastError, _setLastError) - ri.__class__.LastError = property(_getLastError, _setLastError) + def RiAtmosphere(self, name, *paramlist, **keyparams): + self._ri.RiAtmosphere(name, *self._createCParamList(paramlist, keyparams)) - return ri + def RiAttribute(self, name, *paramlist, **keyparams): + self._ri.RiAttribute(name, *self._createCParamList(paramlist, keyparams)) + + def RiAttributeBegin(self): + self._ri.RiAttributeBegin() -def importRINames(ri, ns): - """Import the RenderMan names into the given namespace. - """ - for name in dir(ri): - if name.startswith("Ri"): - localName = name - ns[localName] = getattr(ri, name) - - if name[:2] in ["Rt", "RI"]: - ns[name] = getattr(ri, name) + def RiAttributeEnd(self): + self._ri.RiAttributeEnd() + def RiBasis(self, ubasis, ustep, vbasis, vstep): + ubasis = self._toCArray(self._ri.RtFloat, ubasis) + vbasis = self._toCArray(self._ri.RtFloat, vbasis) + self._ri.RiBasis(ubasis, ustep, vbasis, vstep) -def _createRiTypes(ri): - """Create the RenderMan types. + def RiBegin(self, name): + self._ri.RiBegin(name) + + def RiBlobby(self, nleaf, code, floats, strings, *paramlist, **keyparams): + 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): + bound = self._toCArray(self._ri.RtFloat, bound) + self._ri.RiBound(bound) + + def RiClipping(self, near, far): + self._ri.RiClipping(near, far) + + def RiClippingPlane(self, x, y, z, nx, ny, nz): + self._ri.RiClippingPlane(x, y, z, nx, ny, nz) - The types are added as attributes to the ri object. All names - begin with "Rt" (RtInt, RtFloat, ...). - """ + def RiColor(self, Cs): + Cs = self._toCArray(self._ri.RtFloat, Cs) + self._ri.RiColor(Cs) + + def RiColorSamples(self, nRGB, RGBn): + 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): + transform = self._toCArray(self._ri.RtFloat, transform) + self._ri.RiConcatTransform(transform) + + def RiCone(self, height, radius, thetamax, *paramlist, **keyparams): + self._ri.RiCone(height, radius, thetamax, *self._createCParamList(paramlist, keyparams)) + + def RiContext(self, handle): + self._ri.RiContext(handle) - # Base types that are not composed of other RenderMan types... - baseTypes = dict(RtBoolean = c_short, - RtInt = c_int, - RtFloat = c_float, - RtString = c_char_p, - RtToken = c_char_p, - RtVoid = None, - RtPointer = c_void_p) + def RiCoordinateSystem(self, spacename): + self._ri.RiCoordinateSystem(spacename) + + def RiCoordSysTransform(self, spacename): + self._ri.RiCoordSysTransform(spacename) - for name,ctype in baseTypes.iteritems(): - setattr(ri, name, ctype) + def RiCropWindow(self, left, right, bottom, top): + self._ri.RiCropWindow(left, right, bottom, top) - ri.RtColor = 3*ri.RtFloat - ri.RtPoint = 3*ri.RtFloat - ri.RtVector = 3*ri.RtFloat - ri.RtNormal = 3*ri.RtFloat - ri.RtHpoint = 4*ri.RtFloat - ri.RtMatrix = 16*ri.RtFloat - ri.RtBasis = 16*ri.RtFloat - ri.RtBound = 6*ri.RtFloat + def RiCurves(self, type, nvertices, wrap, *paramlist, **keyparams): + 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): + self._ri.RiCylinder(radius, zmin, zmax, thetamax, *self._createCParamList(paramlist, keyparams)) + + def RiDeclare(self, name, declaration): + + # 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): + self._ri.RiDepthOfField(fstop, focallength, focaldistance) + + def RiDetail(self, bound): + bound = self._toCArray(self._ri.RtFloat, bound) + self._ri.RiDetail(bound) - ri.RtObjectHandle = ri.RtPointer - ri.RtLightHandle = ri.RtPointer - ri.RtContextHandle = ri.RtPointer + def RiDetailRange(self, minvisible, lowertransition, uppertransition, maxvisible): + self._ri.RiDetailRange(minvisible, lowertransition, uppertransition, maxvisible) + + def RiDisk(self, height, radius, thetamax, *paramlist, **keyparams): + self._ri.RiDisk(height, radius, thetamax, *self._createCParamList(paramlist, keyparams)) + + def RiDisplacement(self, name, *paramlist, **keyparams): + self._ri.RiDisplacement(name, *self._createCParamList(paramlist, keyparams)) + + def RiDisplay(self, name, type, mode, *paramlist, **keyparams): + self._ri.RiDisplay(name, type, mode, *self._createCParamList(paramlist, keyparams)) + + def RiEnd(self): + 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): + self._ri.RiExposure(gain, gamma) + + def RiExterior(self, name, *paramlist, **keyparams): + self._ri.RiExterior(name, *self._createCParamList(paramlist, keyparams)) - ri.RtFilterFunc = CFUNCTYPE(ri.RtFloat, ri.RtFloat, ri.RtFloat, ri.RtFloat, ri.RtFloat) - ri.RtErrorHandler = CFUNCTYPE(ri.RtVoid, ri.RtInt, ri.RtInt, c_char_p) - ri.RtProcSubdivFunc = CFUNCTYPE(ri.RtVoid, ri.RtPointer, ri.RtFloat) - ri.RtProcFreeFunc = CFUNCTYPE(ri.RtVoid, ri.RtPointer) - ri.RtArchiveCallback = CFUNCTYPE(ri.RtVoid, ri.RtToken, c_char_p) # var args are missing + def RiFormat(self, xres, yres, aspect): + self._ri.RiFormat(xres, yres, aspect) + + def RiFrameAspectRatio(self, frameratio): + self._ri.RiFrameAspectRatio(frameratio) + + def RiFrameBegin(self, number): + self._ri.RiFrameBegin(number) + + def RiFrameEnd(self): + self._ri.RiFrameEnd() + + def RiGeneralPolygon(self, nverts, *paramlist, **keyparams): + nverts = self._toCArray(self._ri.RtInt, nverts) + self._ri.RiGeneralPolygon(len(nverts), nverts, *self._createCParamList(paramlist, keyparams)) + + def RiGeometricApproximation(self, type, value): + self._ri.RiGeometricApproximation(type, value) + + def RiGeometry(self, type, *paramlist, **keyparams): + self._ri.RiGeometry(type, *self._createCParamList(paramlist, keyparams)) + + def RiGetContext(self): + return self._ri.RiGetContext() -def _createRiConstants(ri): - """Create the RenderMan constants. + def RiHider(self, type, *paramlist, **keyparams): + self._ri.RiHider(type, *self._createCParamList(paramlist, keyparams)) + + def RiHyperboloid(self, point1, point2, thetamax, *paramlist, **keyparams): + 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): + self._ri.RiIdentity() + + def RiIlluminate(self, light, onoff): + self._ri.RiIlluminate(light, onoff) + + def RiImager(self, name, *paramlist, **keyparams): + self._ri.RiImager(name, *self._createCParamList(paramlist, keyparams)) + + def RiInterior(self, name, *paramlist, **keyparams): + self._ri.RiInterior(name, *self._createCParamList(paramlist, keyparams)) + + def RiLightSource(self, name, *paramlist, **keyparams): + 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): + self._ri.RiMakeCubeFaceEnvironment(px, nx, py, ny, pz, nz, texname, fov, self._ri.RtFilterFunc(filterfunc), swith, twidth, *self._createCParamList(paramlist, keyparams)) + + def RiMakeLatLongEnvironment(self, picname, texname, filterfunc, swidth, twidth, *paramlist, **keyparams): + self._ri.RiMakeLatLongEnvironment(picname, texname, self._ri.RtFilterFunc(filterfunc), swith, twidth, *self._createCParamList(paramlist, keyparams)) + + def RiMakeShadow(self, picname, shadowname, *paramlist, **keyparams): + self._ri.RiMakeShadow(picname, texname, *self._createCParamList(paramlist, keyparams)) + + def RiMakeTexture(self, picname, texname, swrap, twrap, filterfunc, swidth, twidth, *paramlist, **keyparams): + self._ri.RiMakeTexture(picname, texname, swrap, twrap, self._ri.RtFilterFunc(filterfunc), swith, twidth, *self._createCParamList(paramlist, keyparams)) + + def RiMatte(self, onoff): + self._ri.RiMatte(onoff) + + def RiMotionBegin(self, *times): + # 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): + self._ri.RiMotionEnd() + + def RiNuPatch(self, nu, uorder, uknot, umin, umax, nv, vorder, vknot, vmin, vmax, *paramlist, **keyparams): + 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): + return self._ri.RiObjectBegin(*self._createCParamList(paramlist, keyparams)) + + def RiObjectEnd(self): + self._ri.RiObjectEnd() - The constants are added as attributes to the ri object. All names - begin with "RI_". - """ - ri.RI_NULL = None - ri.RI_TRUE = 1 - ri.RI_FALSE = 0 - ri.RI_EPSILON = 1.0e-10 - ri.RI_INFINITY = 1.0e38 + def RiObjectInstance(self, handle): + self._ri.RiObjectInstance(handle) - ri.RI_HERMITESTEP = 2 - ri.RI_CATMULLROMSTEP = 1 - ri.RI_BEZIERSTEP = 3 - ri.RI_BSPLINESTEP = 1 - ri.RI_POWERSTEP = 4 + def RiOpacity(self, Os): + Os = self._toCArray(self._ri.RtFloat, Os) + self._ri.RiOpacity(Os) - tokens = [("RI_FRAMEBUFFER", "framebuffer"), - ("RI_FILE", "file"), - ("RI_RGB", "rgb"), - ("RI_RGBA", "rgba"), - ("RI_RGBZ", "rgbz"), - ("RI_RGBAZ", "rgbaz"), - ("RI_A", "a"), - ("RI_Z", "z"), - ("RI_AZ", "az"), - ("RI_PERSPECTIVE", "perspective"), - ("RI_ORTHOGRAPHIC", "orthographic"), - ("RI_HIDDEN", "hidden"), - ("RI_PAINT", "paint"), - ("RI_CONSTANT", "constant"), - ("RI_SMOOTH", "smooth"), - ("RI_FLATNESS", "flatness"), - ("RI_FOV", "fov"), - ("RI_AMBIENTLIGHT", "ambientlight"), - ("RI_POINTLIGHT", "pointlight"), - ("RI_DISTANTLIGHT", "distantlight"), - ("RI_SPOTLIGHT", "spotlight"), - ("RI_INTENSITY", "intensity"), - ("RI_LIGHTCOLOR", "lightcolor"), - ("RI_FROM", "from"), - ("RI_TO", "to"), - ("RI_CONEANGLE", "coneangle"), - ("RI_CONEDELTAANGLE", "conedeltaangle"), - ("RI_BEAMDISTRIBUTION", "beamdistribution"), - ("RI_MATTE", "matte"), - ("RI_METAL", "metal"), - ("RI_SHINYMETAL", "shinymetal"), - ("RI_PLASTIC", "plastic"), - ("RI_PAINTEDPLASTIC", "paintedplastic"), - ("RI_KA", "ka"), - ("RI_KD", "kd"), - ("RI_KS", "ks"), - ("RI_ROUGHNESS", "roughness"), - ("RI_KR", "kr"), - ("RI_TEXTURENAME", "texturename"), - ("RI_SPECULARCOLOR", "specularcolor"), - ("RI_DEPTHCUE", "depthcue"), - ("RI_FOG", "fog"), - ("RI_BUMPY", "bumpy"), - ("RI_MINDISTANCE", "mindistance"), - ("RI_MAXDISTANCE", "maxdistance"), - ("RI_BACKGROUND", "background"), - ("RI_DISTANCE", "distance"), - ("RI_AMPLITUDE", "amplitude"), - ("RI_RASTER", "raster"), - ("RI_SCREEN", "screen"), - ("RI_CAMERA", "camera"), - ("RI_WORLD", "world"), - ("RI_OBJECT", "object"), - ("RI_LH", "lh"), - ("RI_RH", "rh"), - ("RI_INSIDE", "inside"), - ("RI_OUTSIDE", "outside"), - ("RI_P", "P"), - ("RI_PW", "Pw"), - ("RI_PZ", "Pz"), - ("RI_N", "N"), - ("RI_NP", "Np"), - ("RI_NG", "Ng"), - ("RI_CI", "Ci"), - ("RI_OI", "Oi"), - ("RI_CS", "Cs"), - ("RI_OS", "Os"), - ("RI_S", "s"), - ("RI_T", "t"), - ("RI_ST", "st"), - ("RI_BILINEAR", "bilinear"), - ("RI_BICUBIC", "bicubic"), - ("RI_LINEAR", "linear"), - ("RI_CUBIC", "cubic"), - ("RI_PRIMITIVE", "primitive"), - ("RI_UNION", "union"), - ("RI_DIFFERENCE", "difference"), - ("RI_INTERSECTION", "intersection"), - ("RI_PERIODIC", "periodic"), - ("RI_NONPERIODIC", "nonperiodic"), - ("RI_CLAMP", "clamp"), - ("RI_BLACK", "black"), - ("RI_COMMENT", "comment"), - ("RI_STRUCTURE", "structure"), - ("RI_VERBATIM", "verbatim"), - ("RI_IDENTIFIER", "identifier"), - ("RI_NAME", "name"), - ("RI_SHADINGGROUP", "shadinggroup"), - ("RI_IGNORE", "ignore"), - ("RI_PRINT", "print"), - ("RI_ABORT", "abort"), - ("RI_HANDLER", "handler"), - ("RI_WIDTH", "width"), - ("RI_CONSTANTWIDTH", "constantwidth") - ] + def RiOption(self, name, *paramlist, **keyparams): + self._ri.RiOption(name, *self._createCParamList(paramlist, keyparams)) + + def RiOrientation(self, orientation): + self._ri.RiOrientation(orientation) + + def RiParaboloid(self, rmax, zmin, zmax, thetamax, *paramlist, **keyparams): + self._ri.RiParaboloid(rmax, zmin, zmax, thetamax, *self._createCParamList(paramlist, keyparams)) + + def RiPatch(self, type, *paramlist, **keyparams): + self._ri.RiPatch(type, *self._createCParamList(paramlist, keyparams)) + + def RiPatchMesh(self, type, nu, uwrap, nv, vwrap, *paramlist, **keyparams): + self._ri.RiPatchMesh(type, nu, uwrap, nv, vwrap, *self._createCParamList(paramlist, keyparams)) + + def RiPerspective(self, fov): + self._ri.RiPerspective(fov) + + def RiPixelFilter(self, function, xwidth, ywidth): + xwidth = self._ri.RtFloat(xwidth) + ywidth = self._ri.RtFloat(ywidth) + # Try passing the function in directlry 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) - for tokSpec in tokens: - if isinstance(tokSpec, basestring): - name = tokSpec - default = None + def RiPixelSamples(self, xsamples, ysamples): + self._ri.RiPixelSamples(xsamples, ysamples) + + def RiPixelVariance(self, variance): + self._ri.RiPixelVariance(variance) + + def RiPoints(self, *paramlist, **keyparams): + 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: - try: - name,default = tokSpec - if not isinstance(name, basestring): - raise ValueError() - except: - raise ValueError("Invalid token spec: %s"%(tokSpec,)) - - try: - value = c_char_p.in_dll(ri, name).value - except ValueError: - value = default - - setattr(ri, name, value) + raise ValueError, 'Parameter "P" is missing.' + self._ri.RiPoints(n, *params) + def RiPointsGeneralPolygons(self, nloops, nverts, vertids, *paramlist, **keyparams): + 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): + 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): + 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): + raise RuntimeError, "Not yet supported" + + def RiProjection(self, name, *paramlist, **keyparams): + self._ri.RiProjection(name, *self._createCParamList(paramlist, keyparams)) + + def RiQuantize(self, type, one, min, max, ditheramplitude): + self._ri.RiQuantize(type, one, min, max, ditheramplitude) + + def RiReadArchive(self, filename, callback=None, *ignore): + raise RuntimeError, "Not yet supported" + + def RiRelativeDetail(self, relativedetail): + self._ri.RiRelativeDetail(relativedetail) + + def RiReverseOrientation(self): + self._ri.RiReverseOrientation() + + def RiRotate(self, angle, *axis): + axis = self._toCArray(self._ri.RtFloat, axis) + self._ri.RiRotate(angle, *tuple(axis)) + + def RiScale(self, *scale): + scale = self._toCArray(self._ri.RtFloat, scale) + self._ri.RiScale(*tuple(scale)) + + def RiScreenWindow(self, left, right, bottom, top): + self._ri.RiScreenWindow(left, right, bottom, top) + + def RiShadingInterpolation(self, type): + self._ri.RiShadingInterpolation(type) + + def RiShadingRate(self, size): + self._ri.RiShadingRate(size) + + def RiShutter(self, opentime, closetime): + self._ri.RiShutter(opentime, closetime) + + def RiSides(self, nsides): + self._ri.RiSides(nsides) + + def RiSkew(self, angle, *vecs): + vecs = self._flatten(vecs) + self._ri.RiSkew(angle, *vecs) -def _createRiFunctions(ri): - # "Import" the types (so that we can write RtInt instead of ri.RtInt)... - for name in dir(ri): - if name.startswith("Rt"): - exec "%s = ri.%s"%(name, name) + def RiSolidBegin(self, type): + self._ri.RiSolidBegin(type) + + def RiSolidEnd(self): + self._ri.RiSolidEnd() + + def RiSphere(self, radius,zmin,zmax,thetamax,*paramlist, **keyparams): + self._ri.RiSphere(radius, zmin, zmax, thetamax, *self._createCParamList(paramlist, keyparams)) + + def RiSubdivisionMesh(self, scheme, nverts, vertids, tags, nargs, intargs, floatargs, *paramlist, **keyparams): + 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): + self._ri.RiSurface(name, *self._createCParamList(paramlist, keyparams)) + + def RiTextureCoordinates(self, s1, t1, s2, t2, s3, t3, s4, t4): + self._ri.RiTextureCoordinates(s1, t1, s2, t2, s3, t3, s4, t4) + + def RiTorus(self, major, minor, phimin, phimax, thetamax, *paramlist, **keyparams): + self._ri.RiTorus(major, minor, phimin, phimax, thetamax, *self._createCParamList(paramlist, keyparams)) + + def RiTransform(self, transform): + transform = self._toCArray(self._ri.RtFloat, transform) + self._ri.RiTransform(transform) + + def RiTransformBegin(self): + self._ri.RiTransformBegin() + + def RiTransformEnd(self): + self._ri.RiTransformEnd() + + def RiTransformPoints(self, fromspace, tospace, points): + raise RuntimeError, "not yet implemented (interface?)" + points = self._toCArray(self._ri.RtFloat, points) + n = len(points)/3 + res = self._ri.RiTransformPoints(fromspace, tospace, n, points) + return res - ri.RiArchiveRecord.argtypes = [RtToken, c_char_p] - ri.RiAreaLightSource.argtypes = [RtToken] - ri.RiAreaLightSource.restype = RtLightHandle - ri.RiAtmosphere.argtypes = [RtToken] - ri.RiAttribute.argtypes = [RtToken] - ri.RiAttributeBegin.argtypes = [] - ri.RiAttributeEnd.argtypes = [] - ri.RiBasis.argtypes = [RtBasis, RtInt, RtBasis, RtInt] - ri.RiBegin.argtypes = [RtToken] - ri.RiBlobby.argtypes = [RtInt, RtInt] - ri.RiBound.argtypes = [RtBound] - ri.RiClipping.argtypes = [RtFloat, RtFloat] - ri.RiClippingPlane.argtypes = [RtFloat, RtFloat, RtFloat, RtFloat, RtFloat, RtFloat] - ri.RiColor.argtypes = [RtColor] - ri.RiColorSamples.argtypes = [RtInt, POINTER(RtFloat), POINTER(RtFloat)] - ri.RiConcatTransform.argtypes = [RtMatrix] - ri.RiCone.argtypes = [RtFloat, RtFloat, RtFloat] - ri.RiContext.argtypes = [RtContextHandle] - ri.RiCoordinateSystem.argtypes = [RtToken] - ri.RiCoordSysTransform.argtypes = [RtToken] - ri.RiCropWindow.argtypes = [RtFloat, RtFloat, RtFloat, RtFloat] - ri.RiCurves.argtypes = [RtToken, RtInt] - ri.RiCylinder.argtypes = [RtFloat, RtFloat, RtFloat, RtFloat] - ri.RiDeclare.argtypes = [c_char_p, c_char_p] - ri.RiDeclare.restype = RtToken - ri.RiDepthOfField.argtypes = [RtFloat, RtFloat, RtFloat] - ri.RiDetail.argtypes = [RtBound] - ri.RiDetailRange.argtypes = [RtFloat, RtFloat, RtFloat, RtFloat] - ri.RiDisk.argtypes = [RtFloat, RtFloat, RtFloat] - ri.RiDisplacement.argtypes = [RtToken] - ri.RiDisplay.argtypes = [RtToken, RtToken, RtToken] - ri.RiEnd.argtypes = [] - ri.RiErrorHandler.argtypes = [RtErrorHandler] - ri.RiExposure.argtypes = [RtFloat, RtFloat] - ri.RiExterior.argtypes = [RtToken] - ri.RiFormat.argtypes = [RtInt, RtInt, RtFloat] - ri.RiFrameAspectRatio.argtypes = [RtFloat] - ri.RiFrameBegin.argtypes = [RtInt] - ri.RiFrameEnd.argtypes = [] - ri.RiGeneralPolygon.argtypes = [RtInt, POINTER(RtInt)] - ri.RiGeometricApproximation.argtypes = [RtToken, RtFloat] - ri.RiGeometry.argtypes = [RtToken] - ri.RiGetContext.argtypes = [] - ri.RiGetContext.restype = RtContextHandle - ri.RiHider.argtypes = [RtToken] - ri.RiHyperboloid.argtypes = [RtPoint, RtPoint, RtFloat] - ri.RiIdentity.argtypes = [] - ri.RiIlluminate.argtypes = [RtLightHandle, RtBoolean] - ri.RiImager.argtypes = [RtToken] - ri.RiInterior.argtypes = [RtToken] - ri.RiLightSource.argtypes = [RtToken] - ri.RiLightSource.restype = RtLightHandle - ri.RiMakeCubeFaceEnvironment.argtypes = [c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, RtFloat, RtFilterFunc, RtFloat, RtFloat] - ri.RiMakeLatLongEnvironment.argtypes = [c_char_p, c_char_p, RtFilterFunc, RtFloat, RtFloat] - ri.RiMakeShadow.argtypes = [c_char_p, c_char_p] - ri.RiMakeTexture.argtypes = [c_char_p, c_char_p, RtToken, RtToken, RtFilterFunc, RtFloat, RtFloat] - ri.RiMatte.argtypes = [RtBoolean] - ri.RiMotionBegin.argtypes = [RtInt] - ri.RiMotionEnd.argtypes = [] - ri.RiNuPatch.argtypes = [RtInt, RtInt, POINTER(RtFloat), RtFloat, RtFloat, RtInt, RtInt, POINTER(RtFloat), RtFloat, RtFloat] - ri.RiObjectBegin.argtypes = [] - ri.RiObjectBegin.restype = RtObjectHandle - ri.RiObjectEnd.argtypes = [] - ri.RiObjectInstance.argtypes = [RtObjectHandle] - ri.RiOpacity.argtypes = [RtColor] - ri.RiOption.argtypes = [RtToken] - ri.RiOrientation.argtypes = [RtToken] - ri.RiParaboloid.argtypes = [RtFloat, RtFloat, RtFloat, RtFloat] - ri.RiPatch.argtypes = [RtToken] - ri.RiPatchMesh.argtypes = [RtToken, RtInt, RtToken, RtInt, RtInt] - ri.RiPerspective.argtypes = [RtFloat] - ri.RiPixelFilter.argtypes = [RtFilterFunc, RtFloat, RtFloat] - ri.RiPixelSamples.argtypes = [RtFloat, RtFloat] - ri.RiPixelVariance.argtypes = [RtFloat] - ri.RiPoints.argtypes = [RtInt] - ri.RiPointsGeneralPolygons.argtypes = [RtInt, POINTER(RtInt), POINTER(RtInt), POINTER(RtInt)] - ri.RiPointsPolygons.argtypes = [RtInt, POINTER(RtInt), POINTER(RtInt)] - ri.RiPolygon.argtypes = [RtInt] - ri.RiProcedural.argtypes = [RtPointer, RtBound, RtProcSubdivFunc, RtProcFreeFunc] - ri.RiProjection.argtypes = [RtToken] - ri.RiQuantize.argtypes = [RtToken, RtInt, RtInt, RtInt, RtFloat] - ri.RiReadArchive.argtypes = [RtToken, RtArchiveCallback] - ri.RiRelativeDetail.argtypes = [RtFloat] - ri.RiReverseOrientation.argtypes = [] - ri.RiRotate.argtypes = [RtFloat, RtFloat, RtFloat, RtFloat] - ri.RiScale.argtypes = [RtFloat, RtFloat, RtFloat] - ri.RiScreenWindow.argtypes = [RtFloat, RtFloat, RtFloat, RtFloat] - ri.RiShadingInterpolation.argtypes = [RtToken] - ri.RiShadingRate.argtypes = [RtFloat] - ri.RiShutter.argtypes = [RtFloat, RtFloat] - ri.RiSides.argtypes = [RtInt] - ri.RiSkew.argtypes = [RtFloat, RtFloat, RtFloat, RtFloat, RtFloat, RtFloat, RtFloat] - ri.RiSolidBegin.argtypes = [RtToken] - ri.RiSolidEnd.argtypes = [] - ri.RiSphere.argtypes = [RtFloat, RtFloat, RtFloat, RtFloat] - ri.RiSubdivisionMesh.argtypes = [RtToken, RtInt, POINTER(RtInt), POINTER(RtInt), RtInt, POINTER(RtToken), POINTER(RtInt), POINTER(RtInt), POINTER(RtFloat)] - ri.RiSurface.argtypes = [RtToken] - ri.RiTextureCoordinates.argtypes = [RtFloat, RtFloat, RtFloat, RtFloat, RtFloat, RtFloat, RtFloat, RtFloat] - ri.RiTorus.argtypes = [RtFloat, RtFloat, RtFloat, RtFloat, RtFloat] - ri.RiTransform.argtypes = [RtMatrix] - ri.RiTransformBegin.argtypes = [] - ri.RiTransformEnd.argtypes = [] - ri.RiTransformPoints.argtypes = [RtToken, RtToken, RtInt, POINTER(RtPoint)] - ri.RiTransformPoints.restype = POINTER(RtPoint) - ri.RiTranslate.argtypes = [RtFloat, RtFloat, RtFloat] - ri.RiTrimCurve.argtypes = [RtInt, POINTER(RtInt), POINTER(RtInt), POINTER(RtFloat), RtFloat, RtFloat, POINTER(RtInt), POINTER(RtFloat), POINTER(RtFloat), POINTER(RtFloat)] - ri.RiWorldBegin.argtypes = [] - ri.RiWorldEnd.argtypes = [] + def RiTranslate(self, *translate): + translate = self._toCArray(self._ri.RtFloat, translate) + self._ri.RiTranslate(*tuple(translate)) - ri.RiErrorIgnore = ri.RtErrorHandler(ri.RiErrorIgnore) - ri.RiErrorPrint = ri.RtErrorHandler(ri.RiErrorPrint) - ri.RiErrorAbort = ri.RtErrorHandler(ri.RiErrorAbort) + def RiTrimCurve(self, ncurves, order, knot, min, max, n, u, v, w): + 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): + self._ri.RiWorldBegin() + + def RiWorldEnd(self): + 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. + """ + # Check if seq is already a ctypes sequence + seq = self._flatten(seq) + return (len(seq)*ctype)(*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 scalar or string. Then it's supposed to be a sequence + else: + 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. + """ + res = list(paramlist) + # Check if the number of values is uneven (this is only allowed when + # the last value is None (RI_NULL) in which case this last value is ignored) + if (len(res)%2==1): + if res[-1] is None: + res = res[:-1] + else: + raise ValueError, "The parameter list must contain an even number of values" + + # Append the params from the keyparams dict to the parameter list + map(lambda param: res.extend(param), keyparams.iteritems()) -def _getLastError(ri): - """Getter function for the RiLastError variable. - """ - try: - return c_int.in_dll(ri, "RiLastError").value - except ValueError: - return None + # 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 + + # Is the value already a ctypes array? Then there's nothing to do + # TODO: Check if the array is of the correct type (_type_ is type) + if isinstance(res[i+1], ctypes.Array): + continue + # Convert the value(s) into a ctypes array (even single values + # must be converted)... + values = self._flatten([res[i+1]]) + # Convert the sequence into a ctypes array... + res[i+1] = (len(values)*ctype)(*values) -def _setLastError(ri, value): - """Setter function for the RiLastError variable. - """ - try: - c_int.in_dll(ri, "RiLastError").value = value - except ValueError: - pass - - + 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_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] This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |