home *** CD-ROM | disk | FTP | other *** search
/ Hackers Magazine 57 / CdHackersMagazineNr57.iso / Software / Multimedia / k3d-setup-0.7.11.0.exe / lib / site-packages / cgkit / ri.py < prev    next >
Encoding:
Python Source  |  2008-02-10  |  69.1 KB  |  2,290 lines

  1. # ***** BEGIN LICENSE BLOCK *****
  2. # Version: MPL 1.1/GPL 2.0/LGPL 2.1
  3. #
  4. # The contents of this file are subject to the Mozilla Public License Version
  5. # 1.1 (the "License"); you may not use this file except in compliance with
  6. # the License. You may obtain a copy of the License at
  7. # http://www.mozilla.org/MPL/
  8. #
  9. # Software distributed under the License is distributed on an "AS IS" basis,
  10. # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11. # for the specific language governing rights and limitations under the
  12. # License.
  13. #
  14. # The Original Code is the Python Computer Graphics Kit.
  15. #
  16. # The Initial Developer of the Original Code is Matthias Baas.
  17. # Portions created by the Initial Developer are Copyright (C) 2004
  18. # the Initial Developer. All Rights Reserved.
  19. #
  20. # Contributor(s):
  21. #
  22. # Alternatively, the contents of this file may be used under the terms of
  23. # either the GNU General Public License Version 2 or later (the "GPL"), or
  24. # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  25. # in which case the provisions of the GPL or the LGPL are applicable instead
  26. # of those above. If you wish to allow use of your version of this file only
  27. # under the terms of either the GPL or the LGPL, and not to allow others to
  28. # use your version of this file under the terms of the MPL, indicate your
  29. # decision by deleting the provisions above and replace them with the notice
  30. # and other provisions required by the GPL or the LGPL. If you do not delete
  31. # the provisions above, a recipient may use your version of this file under
  32. # the terms of any one of the MPL, the GPL or the LGPL.
  33. #
  34. # ***** END LICENSE BLOCK *****
  35. # -------------------------------------------------------------
  36. # The RenderMan (R) Interface Procedures and Protocol are:
  37. # Copyright 1988, 1989, 2000, Pixar
  38. # All Rights Reserved
  39. #
  40. # RenderMan (R) is a registered trademark of Pixar
  41. # -------------------------------------------------------------
  42. # $Id: ri.py,v 1.4 2006/02/14 19:29:39 mbaas Exp $
  43.  
  44. """A RenderMan(R) binding for Python.
  45.  
  46. This module contains a complete binding of Pixar's RenderMan API. The
  47. binding was written to be compliant to v3.2 of Pixar's RenderMan
  48. Interface specification. However, it also supports some newer features
  49. such as string handles for light sources or object instances.
  50.  
  51. It is safe to import the module using 
  52.  
  53.   from cgkit.ri import *
  54.  
  55. All the functions that get imported start with the prefix Ri, all
  56. constants start with RI_ or RIE_, so you probably won't get into a
  57. naming conflict.
  58.  
  59. After importing the module this way you can use the functions just as
  60. you are used to from the C API (well, almost).
  61.  
  62.   from cgkit.ri import *
  63.  
  64.   RiBegin(RI_NULL)
  65.   RiWorldBegin()
  66.   RiSurface("plastic")
  67.   RiSphere(1,-1,1,360)
  68.   RiWorldEnd()
  69.   RiEnd()
  70.  
  71. For more details on using the module see the cgkit manual at
  72. http://cgkit.sourceforge.net/
  73. """
  74.  
  75. import sys, types, time, os, os.path, string, getpass, inspect, gzip
  76. try:
  77.     from _core import vec3 as _vec3
  78. except:
  79.     from cgtypes import vec3 as _vec3
  80.  
  81. ########################### Constants #############################
  82.  
  83. RI_NULL         = None
  84.  
  85. RI_TRUE         = 1
  86. RI_FALSE        = 0
  87.  
  88. RI_HIDDEN       = "hidden"
  89. RI_PAINT        = "paint"
  90.  
  91. RI_EPSILON      = 1.0e-10
  92. RI_INFINITY     = 1.0e38
  93.  
  94. RI_FILE         = "file"
  95. RI_FRAMEBUFFER  = "framebuffer"
  96. RI_RGB          = "rgb"
  97. RI_RGBA         = "rgba"
  98. RI_RGBZ         = "rgbZ"
  99. RI_RGBAZ        = "rgbaz"
  100. RI_A            = "a"
  101. RI_Z            = "z"
  102. RI_AZ           = "az"
  103.  
  104. RI_ORIGIN       = "origin"
  105.  
  106. RI_PERSPECTIVE  = "perspective"
  107. RI_ORTHOGRAPHIC = "orthographic"
  108. RI_FOV          = "fov"
  109.  
  110. RI_LH           = "lh"
  111. RI_RH           = "rh"
  112. RI_INSIDE       = "inside"
  113. RI_OUTSIDE      = "outside"
  114.  
  115. RI_BILINEAR     = "bilinear"
  116. RI_BICUBIC      = "bicubic"
  117.  
  118. RI_LINEAR       = "linear"
  119. RI_CUBIC        = "cubic"
  120.  
  121. RI_CONSTANT     = "constant"
  122. RI_SMOOTH       = "smooth"
  123.  
  124. RI_P            = "P"
  125. RI_PW           = "Pw"
  126. RI_PZ           = "Pz"
  127. RI_N            = "N"
  128. RI_NP           = "Np"
  129. RI_NG           = "Ng"
  130. RI_CI           = "Ci"
  131. RI_OI           = "Oi"
  132. RI_CS           = "Cs"
  133. RI_OS           = "Os"
  134. RI_S            = "s"
  135. RI_T            = "t"
  136. RI_ST           = "st"
  137.  
  138. RI_COMMENT      = "comment"
  139. RI_STRUCTURE    = "structure"
  140. RI_VERBATIM     = "verbatim"
  141.  
  142. RI_HERMITESTEP    = 2
  143. RI_CATMULLROMSTEP = 1
  144. RI_BEZIERSTEP     = 3
  145. RI_BSPLINESTEP    = 1
  146. RI_POWERSTEP      = 4
  147.  
  148. RI_PERIODIC     = "periodic"
  149. RI_NONPERIODIC  = "nonperiodic"
  150. RI_CLAMP        = "clamp"
  151. RI_BLACK        = "black"
  152.  
  153. RI_FLATNESS     = "flatness"
  154.  
  155. RI_PRIMITIVE    = "primitive"
  156. RI_UNION        = "union"
  157. RI_DIFFERENCE   = "difference"
  158. RI_INTERSECTION = "intersection"
  159.  
  160. RI_WIDTH        = "width"
  161. RI_CONSTANTWIDTH = "constantwidth"
  162.  
  163. RI_HOLE         = "hole"
  164. RI_CREASE       = "crease"
  165. RI_CORNER       = "corner"
  166. RI_INTERPOLATEBOUNDARY = "interpolateboundary"
  167.  
  168. RI_AMBIENTLIGHT = "ambientlight"
  169. RI_POINTLIGHT   = "pointlight"
  170. RI_DISTANTLIGHT = "distantlight"
  171. RI_SPOTLIGHT    = "spotlight"
  172.  
  173. RI_INTENSITY    = "intensity"
  174. RI_LIGHTCOLOR   = "lightcolor"
  175. RI_FROM         = "from"
  176. RI_TO           = "to"
  177. RI_CONEANGLE    = "coneangle"
  178. RI_CONEDELTAANGLE = "conedeltaangle"
  179. RI_BEAMDISTRIBUTION = "beamdistribution"
  180.  
  181. RI_MATTE        = "matte"
  182. RI_METAL        = "metal"
  183. RI_SHINYMETAL   = "shinymetal"
  184. RI_PLASTIC      = "plastic"
  185. RI_PAINTEDPLASTIC = "paintedplastic"
  186.  
  187. RI_KA           = "Ka"
  188. RI_KD           = "Kd"
  189. RI_KS           = "Ks"
  190. RI_ROUGHNESS    = "roughness"
  191. RI_KR           = "Kr"
  192. RI_TEXTURENAME  = "texturename"
  193. RI_SPECULARCOLOR = "specularcolor"
  194.  
  195. RI_DEPTHCUE     = "depthcue"
  196. RI_FOG          = "fog"
  197. RI_BUMPY        = "bumpy"
  198.  
  199. RI_MINDISTANCE  = "mindistance"
  200. RI_MAXDISTANCE  = "maxdistance"
  201. RI_BACKGROUND   = "background"
  202. RI_DISTANCE     = "distance"
  203. RI_AMPLITUDE    = "amplitude"
  204.  
  205. RI_RASTER       = "raster"
  206. RI_SCREEN       = "screen"
  207. RI_CAMERA       = "camera"
  208. RI_WORLD        = "world"
  209. RI_OBJECT       = "object"
  210.  
  211. RI_IDENTIFIER   = "identifier"
  212. RI_NAME         = "name"
  213. RI_SHADINGGROUP = "shadinggroup"
  214.  
  215. RI_IGNORE       = "ignore"
  216. RI_PRINT        = "print"
  217. RI_ABORT        = "abort"
  218. RI_HANDLER      = "handler"
  219.  
  220. RI_HANDLEID     = "__handleid"
  221.  
  222. # Tokens specific to the cgkit binding...
  223. RI_RIBOUTPUT    = "_riboutput"
  224. RI_VERSION      = "_version"
  225.  
  226. # Error handling: severity levels
  227. RIE_INFO        = 0
  228. RIE_WARNING     = 1
  229. RIE_ERROR       = 2
  230. RIE_SEVERE      = 3
  231.  
  232. RIE_INCAPABLE   = 11
  233.  
  234. RIE_NOTOPTIONS  = 25       # Invalid state for options
  235. RIE_NOTATTRIBS  = 26       # Invalid state for attributes
  236. RIE_NOTPRIMS    = 27       # Invalid state for primitives
  237. RIE_ILLSTATE    = 28       # Other invalid state 
  238. RIE_RANGE       = 42       # Parameter out of range 
  239. RIE_CONSISTENCY = 43       # Parameters inconsistent
  240.  
  241. RIE_INVALIDSEQLEN = 80     # A sequence hasn't had the required length
  242. RIE_UNDECLARED    = 81     # An undeclared parameter is used
  243.  
  244. RiLastError     = 0
  245.  
  246. ############################ Types ###################################
  247.  
  248. RtBoolean = bool
  249. RtInt = int
  250. RtFloat = float
  251. RtString = str
  252. RtToken = str
  253. RtVoid = None
  254. RtPointer = lambda x: x
  255.  
  256. RtColor = tuple
  257. RtPoint = tuple
  258. RtVector = tuple
  259. RtNormal = tuple
  260. RtHpoint = tuple
  261. RtMatrix = tuple
  262. RtBasis = tuple
  263. RtBound = tuple
  264.  
  265. RtObjectHandle = lambda x: x
  266. RtLightHandle = lambda x: x
  267. RtContextHandle = lambda x: x
  268.  
  269. RtFilterFunc = lambda x: x
  270. RtErrorHandler = lambda x: x
  271. RtProcSubdivFunc = lambda x: x
  272. RtProcFreeFunc = lambda x: x
  273. RtArchiveCallback = lambda x: x
  274.  
  275.  
  276. ######################################################################
  277.  
  278. class RIBStream:
  279.     """This class encapsulates the output stream.
  280.  
  281.     The version number is automatically placed into the stream before
  282.     any "real" Ri calls are made. Output from RiArchiveRecord() will
  283.     be placed before the version number.
  284.     """
  285.     
  286.     def __init__(self, outstream):
  287.         self.out = outstream
  288.         self.output_version = 1
  289.  
  290.     def close(self):
  291.         """Close the stream, unless it's stdout."""
  292.         if self.out!=sys.stdout:
  293.             self.out.close()
  294.  
  295.     def flush(self):
  296.         """Flush the internal buffer."""
  297.         self.out.flush()
  298.  
  299.     def write(self, data):
  300.         """Write data into the stream."""
  301.         if self.output_version:
  302.             self.out.write('version 3.03\n')
  303.             self.output_version = 0
  304.         self.out.write(data)
  305.  
  306.     def writeArchiveRecord(self, data):
  307.         """Same as write() but suppresses the version number.
  308.  
  309.         This method is used by RiArchiveRecord(), everyone else uses
  310.         write().
  311.         """
  312.         self.out.write(data)
  313.         
  314.  
  315. ###################### Standard error handlers #######################
  316.  
  317. def RiErrorIgnore(code, severity, message):
  318.     """Standard error handler.
  319.  
  320.     Ignores error messages."""
  321.     
  322.     pass
  323.  
  324. def RiErrorPrint(code, severity, message):
  325.     """Standard error handler.
  326.  
  327.     Prints the message to stderr."""
  328.  
  329.     if severity==RIE_WARNING:
  330.         print >> sys.stderr, "WARNING:",
  331.     elif severity==RIE_ERROR or severity==RIE_SEVERE:
  332.         print >> sys.stderr, "ERROR (%d):"%(code),        
  333.     print >> sys.stderr, message
  334.  
  335. def RiErrorAbort(code, severity, message):
  336.     """Standard error handler.
  337.  
  338.     Prints the message to stderr and aborts if it was an error."""
  339.  
  340.     RiErrorPrint(code, severity, message)
  341.     if severity>=RIE_ERROR:
  342.         sys.exit(1)
  343.  
  344.  
  345. class RIException(Exception):
  346.     """RenderMan Interface exception
  347.  
  348.     This exception is thrown by the error handler RiErrorException()."""
  349.     pass
  350.  
  351. def RiErrorException(code, severity, message):
  352.     """This error handler raises an exception when an error occurs.
  353.  
  354.     If the "error" is only an info or warning message the message is
  355.     printed to stderr, otherwise the exception RIException is thrown.
  356.     The actual error message is given as an argument to the constructor of
  357.     RIException (the line with the file name, line number and offending
  358.     Ri call is removed. You will have that information in the Traceback).
  359.     """
  360.     if severity<RIE_ERROR:
  361.         RiErrorPrint(code, severity, message)
  362.     else:
  363.         if message[:7]=="In file":
  364.             n=message.find("\n")
  365.             message=message[n+1:]
  366.         raise RIException(message)
  367.  
  368. ########################### Functions ################################
  369.  
  370. # RiErrorHandler
  371. def RiErrorHandler(handler):
  372.     """Install a new error handler.
  373.  
  374.     The handler takes three arguments: code, severity, message.
  375.     Besides the three standard error handler RiErrorIgnore, RiErrorPrint
  376.     and RiErrorAbort there's an additional error handler available called
  377.     RiErrorException. Whenever an error occurs RiErrorException raises
  378.     the exception RIException.
  379.  
  380.     If you use one of the standard error handlers the corresponding RIB
  381.     request is written to the output. If you supply RiErrorException or
  382.     your own handler then the handler is installed but no output is
  383.     written to the output stream.
  384.  
  385.     The last error code is always stored in the variable RiLastError.
  386.     Note: If you import the module with "from ri import *" you have to
  387.     import it with "import ri" as well and you must access RiLastError
  388.     via "ri.RiLastError" otherwise the variable will always be 0.
  389.  
  390.     Example: RiErrorHandler(RiErrorAbort)
  391.     """
  392.  
  393.     global _errorhandler
  394.  
  395.     _errorhandler = handler
  396.  
  397.     if handler==RiErrorIgnore:
  398.         _ribout.write('ErrorHandler "ignore"\n')
  399.     elif handler==RiErrorPrint:
  400.         _ribout.write('ErrorHandler "print"\n')
  401.     elif handler==RiErrorAbort:
  402.         _ribout.write('ErrorHandler "abort"\n')
  403.  
  404.  
  405. # RiBegin
  406. def RiBegin(name):
  407.     """Starts the main block using a particular rendering method.
  408.     
  409.     The default renderer is selected by passing RI_NULL as name.
  410.     Here this means the output is written to stdout.
  411.     If the name has the extension ".rib" then the output is written into
  412.     a file with that name. Otherwise the name is supposed to be an
  413.     external renderer (e.g. "rendrib" (BMRT), "rgl" (BMRT), "aqsis" (Aqsis),
  414.     "renderdl" (3Delight),...) which is started and fed with the data.
  415.  
  416.     Example: RiBegin(RI_NULL)
  417.              ...
  418.              RiEnd()
  419.     """
  420.     global _ribout, _colorsamples, _lighthandle, _errorhandler
  421.     global _insideframe, _insideworld, _insideobject, _insidesolid
  422.     global _insidemotion, _declarations
  423.  
  424.     _create_new_context()
  425.  
  426.     # Determine where the output should be directed to...
  427.     if name==RI_NULL or name=="":
  428.         # -> stdout
  429.         outstream = sys.stdout
  430.     else:
  431.         root, ext = os.path.splitext(name)
  432.         ext=ext.lower()
  433.         if ext==".rib":
  434.             # -> file (rib)
  435.             outstream = open(name,"w")
  436.         elif ext==".gz":
  437.             outstream = gzip.open(name,"wb")
  438.         else:
  439.             # -> pipe
  440.             outstream = os.popen(name,"w")
  441.  
  442.     _ribout = RIBStream(outstream)
  443.  
  444.     # Initialize internal variables
  445.     _colorsamples = 3
  446.     _lighthandle  = 0
  447.     _errorhandler = RiErrorPrint
  448.     _insideframe  = 0
  449.     _insideworld  = 0
  450.     _insideobject = 0
  451.     _insidesolid  = 0
  452.     _insidemotion = 0
  453.     _init_declarations()
  454.  
  455.  
  456. # RiEnd
  457. def RiEnd():
  458.     """Terminates the main block.
  459.     """
  460.     global _ribout
  461.  
  462.     _ribout.flush()
  463.     
  464.     if _ribout != sys.stdout:
  465.         _ribout.close()
  466.         _ribout = sys.stdout
  467.  
  468.     _destroy_context()
  469.  
  470. # RiWorldBegin
  471. def RiWorldBegin():
  472.     """Start the world block.
  473.  
  474.     Example: RiWorldBegin()
  475.              ...
  476.              RiWorldEnd()
  477.     """
  478.  
  479.     global _insideworld
  480.  
  481.     if _insideworld:
  482.         _error(RIE_ILLSTATE, RIE_ERROR, "World blocks cannot be nested.")
  483.     
  484.     _ribout.write("WorldBegin\n")
  485.     _insideworld = 1
  486.  
  487. # RiWorldEnd
  488. def RiWorldEnd():
  489.     """Terminates the world block."""
  490.  
  491.     global _insideworld
  492.     
  493.     _ribout.write("WorldEnd\n")
  494.     _insideworld = 0
  495.  
  496. # RiOption
  497. def RiOption(name, *paramlist, **keyparams):
  498.     """Set an implementation-specific option.
  499.  
  500.     Example: RiOption("searchpath", "shader","~/shaders:&")
  501.     """
  502.     global _ribout
  503.  
  504.     # cgkit specific options?
  505.     if name==RI_RIBOUTPUT:
  506.         keyparams = _paramlist2lut(paramlist, keyparams)
  507.         if keyparams.get(RI_VERSION, None)==0:
  508.             # Disable the "version" call in the RIB stream...
  509.             if hasattr(_ribout, "output_version"):
  510.                 _ribout.output_version = 0
  511.         return
  512.             
  513.     _ribout.write('Option "'+name+'"'+_paramlist2string(paramlist, keyparams)+"\n")
  514.  
  515. # RiAttribute
  516. def RiAttribute(name, *paramlist, **keyparams):
  517.     """Set an implementation-specific attribute.
  518.  
  519.     Example: RiAttribute("displacementbound", "sphere", 0.5)
  520.     """
  521.     
  522.     _ribout.write('Attribute "'+name+'"'+_paramlist2string(paramlist, keyparams)+"\n")
  523.  
  524. # RiAttributeBegin
  525. def RiAttributeBegin():
  526.     """Push the current set of attributes onto the attribute stack.
  527.  
  528.     Example: RiAttributeBegin()
  529.              ...
  530.              RiAttributeEnd()
  531.     """
  532.     
  533.     _ribout.write("AttributeBegin\n")
  534.  
  535. # RiAttributeEnd
  536. def RiAttributeEnd():
  537.     """Pops the current set of attributes from the attribute stack."""
  538.  
  539.     _ribout.write("AttributeEnd\n")
  540.  
  541. # RiTransformBegin
  542. def RiTransformBegin():
  543.     """Push the current transformation on the transformation stack.
  544.  
  545.     Example: RiTransformBegin()
  546.              ...
  547.              RiTransformEnd()
  548.     """
  549.     
  550.     _ribout.write("TransformBegin\n")
  551.  
  552. # RiTransformEnd
  553. def RiTransformEnd():
  554.     """Pop the current transformation from the stack."""
  555.  
  556.     _ribout.write("TransformEnd\n")
  557.  
  558. # RiFrameBegin
  559. def RiFrameBegin(number):
  560.     """Start a new frame.
  561.  
  562.     Example: RiFrameBegin(1)
  563.              ...
  564.              RiFrameEnd()
  565.     """
  566.  
  567.     global _insideframe
  568.  
  569.     if _insideframe:
  570.         _error(RIE_ILLSTATE, RIE_ERROR, "Frame blocks cannot be nested.")
  571.             
  572.     _ribout.write("FrameBegin %d\n"%number)
  573.     _insideframe = 1
  574.     
  575.  
  576. # RiFrameEnd
  577. def RiFrameEnd():
  578.     """Terminates a frame."""
  579.     
  580.     global _insideframe
  581.     
  582.     _ribout.write("FrameEnd\n")
  583.     _insideframe = 0
  584.  
  585. # RiHider
  586. def RiHider(type, *paramlist, **keyparams):
  587.     """Choose a hidden-surface elimination technique.
  588.  
  589.     Example: RiHider(RI_HIDDEN)  (default)
  590.     """
  591.     
  592.     if type==RI_NULL: type="null"
  593.     _ribout.write('Hider "'+type+'"'+_paramlist2string(paramlist, keyparams)+"\n")
  594.  
  595. # RiSphere
  596. def RiSphere(radius,zmin,zmax,thetamax,*paramlist, **keyparams):
  597.     """Create a sphere.
  598.  
  599.     Number of array elements for primitive variables:
  600.     -------------------------------------------------
  601.     constant: 1              varying: 4
  602.     uniform:  1              vertex:  4
  603.  
  604.     Example: RiSphere(1.0, -1.0, 1.0, 360)
  605.     """
  606.  
  607.     _ribout.write('Sphere %s %s %s %s'%(radius, zmin, zmax, thetamax)+ \
  608.                  _paramlist2string(paramlist, keyparams)+"\n")
  609.  
  610. # RiCone
  611. def RiCone(height, radius, thetamax, *paramlist, **keyparams):
  612.     """Create a cone (along the z axis).
  613.  
  614.     Number of array elements for primitive variables:
  615.     -------------------------------------------------
  616.     constant: 1              varying: 4
  617.     uniform:  1              vertex:  4
  618.  
  619.     Example: RiCone(1.5, 0.7, 360)
  620.     """
  621.  
  622.     _ribout.write('Cone %s %s %s'%(height, radius, thetamax)+ \
  623.                  _paramlist2string(paramlist, keyparams)+"\n")
  624.  
  625. # RiDisk
  626. def RiDisk(height, radius, thetamax, *paramlist, **keyparams):
  627.     """Create a disk (parallel to the XY plane).
  628.  
  629.     Number of array elements for primitive variables:
  630.     -------------------------------------------------
  631.     constant: 1              varying: 4
  632.     uniform:  1              vertex:  4
  633.  
  634.     Example: RiDisk(0.0, 1.0, 360)"""
  635.  
  636.     _ribout.write('Disk %s %s %s'%(height, radius, thetamax)+ \
  637.                  _paramlist2string(paramlist, keyparams)+"\n")
  638.  
  639. # RiCylinder
  640. def RiCylinder(radius,zmin,zmax,thetamax,*paramlist, **keyparams):
  641.     """Create a cylinder (along the z axis).
  642.  
  643.     Number of array elements for primitive variables:
  644.     -------------------------------------------------
  645.     constant: 1              varying: 4
  646.     uniform:  1              vertex:  4
  647.  
  648.     Example: RiCylinder(1.5, 0.0, 1.0, 360)
  649.     """
  650.  
  651.     _ribout.write('Cylinder %s %s %s %s'%(radius, zmin, zmax, thetamax)+ \
  652.                  _paramlist2string(paramlist, keyparams)+"\n")
  653.  
  654. # RiTorus
  655. def RiTorus(major, minor, phimin, phimax, thetamax, *paramlist, **keyparams):
  656.     """Create a torus (with the z axis as symmetry axis).
  657.  
  658.     Number of array elements for primitive variables:
  659.     -------------------------------------------------
  660.     constant: 1              varying: 4
  661.     uniform:  1              vertex:  4
  662.  
  663.     Example: RiTorus(1.5, 0.1, 0, 360, 360)
  664.     """
  665.  
  666.     _ribout.write('Torus %s %s %s %s %s'%(major, minor, phimin, phimax, thetamax)+ \
  667.                  _paramlist2string(paramlist, keyparams)+"\n")
  668.  
  669. # RiHyperboloid
  670. def RiHyperboloid(point1, point2, thetamax, *paramlist, **keyparams):
  671.     """Create a hyperboloid (with the z axis as symmetry axis).
  672.  
  673.     Example: RiHyperboloid([1,0,0],[1,1,1],360)
  674.     """
  675.  
  676.     p1 = _seq2list(point1, 3)
  677.     p2 = _seq2list(point2, 3)
  678.     _ribout.write('Hyperboloid '+p1[1:-1]+' '+p2[1:-1]+' '+`thetamax`+ \
  679.                  _paramlist2string(paramlist, keyparams)+"\n")
  680.  
  681. # RiParaboloid
  682. def RiParaboloid(rmax, zmin, zmax, thetamax, *paramlist, **keyparams):
  683.     """Create a paraboloid (with the z axis as symmetry axis).
  684.  
  685.     Number of array elements for primitive variables:
  686.     -------------------------------------------------
  687.     constant: 1              varying: 4
  688.     uniform:  1              vertex:  4
  689.  
  690.     Example: RiParaboloid(1.0, 0.0, 1.0, 360)
  691.     """
  692.  
  693.     _ribout.write('Paraboloid %s %s %s %s'%(rmax, zmin, zmax, thetamax)+ \
  694.                  _paramlist2string(paramlist, keyparams)+"\n")
  695.  
  696. # RiPolygon
  697. def RiPolygon(*paramlist, **keyparams):
  698.     """Create a planar and convex polygon.
  699.  
  700.     The parameter list must include at least position ("P") information.
  701.  
  702.     Number of array elements for primitive variables:
  703.     -------------------------------------------------
  704.     constant: 1              varying: #vertices
  705.     uniform:  1              vertex:  #vertices
  706.  
  707.     Example: RiPolygon(P=[0,1,0, 0,1,1, 0,0,1, 0,0,0])
  708.     """
  709.  
  710.     _ribout.write('Polygon'+_paramlist2string(paramlist, keyparams)+"\n")
  711.  
  712. # RiGeneralPolygon
  713. def RiGeneralPolygon(nverts, *paramlist, **keyparams):
  714.     """Create a general planar concave polygon with holes.
  715.  
  716.     Number of array elements for primitive variables:
  717.     -------------------------------------------------
  718.     constant: 1              varying: #total vertices
  719.     uniform:  1              vertex:  #total vertices
  720.  
  721.     Example: RiGeneralPolygon([4,3], P=[0,0,0, 0,1,0, 0,1,1, 0,0,1, \\
  722.                                         0,0.25,0.5, 0,0.75,0.75, 0,0.75,0.25])
  723.     """
  724.  
  725.     _ribout.write('GeneralPolygon '+_seq2list(nverts)+ \
  726.                  _paramlist2string(paramlist, keyparams)+"\n")
  727.  
  728. # RiPointsPolygons
  729. def RiPointsPolygons(nverts, vertids, *paramlist, **keyparams):
  730.     """Create a polyhedron made of planar convex polygons that share vertices.
  731.  
  732.     nverts:  An array with the number of vertices in each polygon
  733.     vertids: The vertex indices of the polygon vertices (0-based)
  734.     The vertices themselves are stored in the parameter list (parameter "P").
  735.  
  736.     Number of array elements for primitive variables:
  737.     -------------------------------------------------
  738.     constant: 1              varying: #vertices (*)
  739.     uniform:  #polygons      vertex:  #vertices (*)
  740.  
  741.     (*) max(vertids)+1
  742.     """
  743.  
  744.     _ribout.write('PointsPolygons '+_seq2list(nverts)+' '+ \
  745.                  _seq2list(vertids)+ \
  746.                  _paramlist2string(paramlist, keyparams)+"\n")
  747.  
  748. # RiPointsGeneralPolygons
  749. def RiPointsGeneralPolygons(nloops, nverts, vertids, *paramlist, **keyparams):
  750.     """Create a polyhedron made of general planar concave polygons.
  751.  
  752.     nloops:  The number of loops for each polygon
  753.     nverts:  The number of vertices in each loop
  754.     vertids: The vertex indices of the loop vertices (0-based)
  755.     The vertices themselves are stored in the parameter list (parameter "P").
  756.  
  757.     Number of array elements for primitive variables:
  758.     -------------------------------------------------
  759.     constant: 1              varying: #vertices (*)
  760.     uniform:  #polygons      vertex:  #vertices (*)
  761.  
  762.     (*) max(vertids)+1
  763.     """
  764.  
  765.     _ribout.write('PointsGeneralPolygons '+_seq2list(nloops)+' '+ \
  766.                  _seq2list(nverts)+' '+_seq2list(vertids)+ \
  767.                  _paramlist2string(paramlist, keyparams)+"\n")
  768.  
  769.  
  770. # Predefined basis matrices
  771. RiHermiteBasis = "hermite"
  772. RiCatmullRomBasis = "catmull-rom"
  773. RiBezierBasis = "bezier"
  774. RiBSplineBasis = "b-spline"
  775. RiPowerBasis = "power"
  776.  
  777. # RiBasis
  778. def RiBasis(ubasis, ustep, vbasis, vstep):
  779.     """Set the current basis for the u and v direction.
  780.  
  781.     ubasis/vbasis can either be one of the predefined basis matrices
  782.     RiHermiteBasis, RiCatmullRomBasis, RiBezierBasis, RiBSplineBasis,
  783.     RiPowerBasis or it can be a user defined matrix.
  784.  
  785.     For the predefined matrices there are also predefined variables
  786.     which can be used for the step parameters:
  787.     RI_HERMITESTEP, RI_CATMULLROMSTEP, RI_BEZIERSTEP, RI_BSPLINESTEP,
  788.     RI_POWERSTEP.
  789.  
  790.     Example: RiBasis(RiBezierBasis, RI_BEZIERSTEP,
  791.                      RiHermiteBasis, RI_HERMITESTEP)
  792.     """
  793.  
  794.     if type(ubasis)==types.StringType:
  795.         ubasis = '"'+ubasis+'"'
  796.     else:
  797.         ubasis = _seq2list(ubasis, 16)
  798.         
  799.     if type(vbasis)==types.StringType:
  800.         vbasis = '"'+vbasis+'"'
  801.     else:
  802.         vbasis = _seq2list(vbasis, 16)
  803.         
  804.     _ribout.write('Basis '+ubasis+' '+str(ustep)+' '+vbasis+' '+str(vstep)+"\n")
  805.  
  806. # RiPatch
  807. def RiPatch(type, *paramlist, **keyparams):
  808.     """RiPatch(type, paramlist)
  809.  
  810.     type is one of RI_BILINEAR (4 vertices) or RI_BICUBIC (16 vertices).
  811.  
  812.     Number of array elements for primitive variables:
  813.     -------------------------------------------------
  814.     constant: 1              varying: 4
  815.     uniform:  1              vertex:  4/16 (depends on type)
  816.  
  817.     Example: RiPatch(RI_BILINEAR, P=[0,0,0, 1,0,0, 0,1,0, 1,1,0])
  818.     """
  819.  
  820.     _ribout.write('Patch "'+type+'"'+_paramlist2string(paramlist, keyparams)+"\n")
  821.  
  822. # RiPatchMesh
  823. def RiPatchMesh(type, nu, uwrap, nv, vwrap, *paramlist, **keyparams):
  824.     """Create a mesh made of patches.
  825.  
  826.     type is one of RI_BILINEAR or RI_BICUBIC.
  827.     uwrap/vwrap can be RI_PERIODIC or RI_NONPERIODIC.
  828.     The number of control points is nu*nv.
  829.  
  830.     Number of array elements for primitive variables:
  831.     -------------------------------------------------
  832.     constant: 1              varying: #patch corners (depends on uwrap/vwrap)
  833.     uniform:  #patches       vertex:  nu*nv (same as "P")
  834.  
  835.     """
  836.  
  837.     _ribout.write('PatchMesh "'+type+'" '+str(nu)+' "'+uwrap+'" '+\
  838.                  str(nv)+' "'+vwrap+'"'+\
  839.                  _paramlist2string(paramlist, keyparams)+"\n")
  840.     
  841.  
  842. # RiNuPatch
  843. def RiNuPatch(nu, uorder, uknot, umin, umax, nv, vorder, vknot, vmin, vmax, *paramlist, **keyparams):
  844.     """Create a NURBS patch.
  845.  
  846.     Number of array elements for primitive variables:
  847.     -------------------------------------------------
  848.     constant: 1              varying: #segment corners
  849.     uniform:  #segments      vertex:  nu*nv
  850.     """
  851.  
  852.     _ribout.write('NuPatch '+str(nu)+" "+str(uorder)+' '+_seq2list(uknot)+" "+ \
  853.                  str(umin)+" "+str(umax)+" "+ \
  854.                 str(nv)+" "+str(vorder)+' '+_seq2list(vknot)+" "+ \
  855.                  str(vmin)+" "+str(vmax)+_paramlist2string(paramlist, keyparams)+"\n")
  856.  
  857. # RiTrimCurve
  858. def RiTrimCurve(ncurves, order, knot, min, max, n, u, v, w):
  859.     """Set the current trim curve.
  860.     """
  861.  
  862.     _ribout.write('TrimCurve '+_seq2list(ncurves)+' '+\
  863.                  _seq2list(order)+' '+_seq2list(knot)+' '+\
  864.                  _seq2list(min)+' '+_seq2list(max)+' '+_seq2list(n)+' '+ \
  865.                  _seq2list(u)+' '+ \
  866.                  _seq2list(v)+' '+ \
  867.                  _seq2list(w)+'\n')
  868.  
  869. # RiPoints
  870. def RiPoints(*paramlist, **keyparams):
  871.     """Create individual points.
  872.  
  873.     The size of the points can be either set with the primitive variable
  874.     RI_WIDTH (one float per point) or RI_CONSTANTWIDTH (one float for all
  875.     points).
  876.  
  877.     Number of array elements for primitive variables:
  878.     -------------------------------------------------
  879.     constant: 1              varying: #points
  880.     uniform:  1              vertex:  #points    
  881.     """
  882.  
  883.     _ribout.write('Points'+_paramlist2string(paramlist, keyparams)+"\n")
  884.  
  885. # RiCurves
  886. def RiCurves(type, nvertices, wrap, *paramlist, **keyparams):
  887.     """Create a number of curve primitives.
  888.  
  889.     type is either RI_LINEAR or RI_CUBIC.
  890.     nvertices is an array with the number of vertices in each curve.
  891.     wrap is either RI_PERIODIC or RI_NONPERIODIC.
  892.     The width of the curves can be specified with the parameter
  893.     RI_WIDTH (varying float) or RI_CONSTANTWIDTH (constant float).
  894.  
  895.     Number of array elements for primitive variables:
  896.     -------------------------------------------------
  897.     constant: 1              varying: #segments (depends on type and wrap)
  898.     uniform:  #curves        vertex:  #points
  899.  
  900.     Example: RiCurves(RI_CUBIC, [4], RI_NONPERIODIC,
  901.                       P=[0,0,0, -1,-0.5,1, 2,0.5,1, 1,0,-1],
  902.                       width=[0.1, 0.04])
  903.     """
  904.  
  905.     _ribout.write('Curves "'+type+'" '+_seq2list(nvertices)+' "'+wrap+'"'+
  906.                   _paramlist2string(paramlist, keyparams)+'\n')
  907.  
  908. # RiSubdivisionMesh
  909. def RiSubdivisionMesh(scheme, nverts, vertids, tags, nargs, intargs, floatargs, *paramlist, **keyparams):
  910.     """Create a subdivision surface.
  911.  
  912.     The only standard scheme is currently "catmull-clark".
  913.     nverts:  The number of vertices in each face
  914.     vertids: The vertex indices of the face vertices (0-based)
  915.     tags: A string array of tag names.
  916.     nargs: The number of int and float args for each tag.
  917.     intargs: The integer arguments.
  918.     floatargs: The float arguments.
  919.     The vertices themselves are stored in the parameter list (parameter "P").
  920.     
  921.  
  922.     Number of array elements for primitive variables:
  923.     -------------------------------------------------
  924.     constant: 1              varying: #vertices (*)
  925.     uniform:  #faces         vertex:  #vertices (*)
  926.  
  927.     (*) max(vertids)+1
  928.     """
  929.  
  930.     if len(tags)==0:
  931.         _ribout.write('SubdivisionMesh "'+scheme+'" '+_seq2list(nverts)+' '+ \
  932.                  _seq2list(vertids)+' '+ \
  933.                  _paramlist2string(paramlist, keyparams)+"\n")
  934.     else:
  935.         _ribout.write('SubdivisionMesh "'+scheme+'" '+_seq2list(nverts)+' '+ \
  936.                  _seq2list(vertids)+' '+_seq2list(tags)+' '+ \
  937.                  _seq2list(nargs)+' '+_seq2list(intargs)+' '+ \
  938.                  _seq2list(floatargs)+' '+ \
  939.                  _paramlist2string(paramlist, keyparams)+"\n")
  940.  
  941. # RiBlobby
  942. def RiBlobby(nleaf, code, floats, strings, *paramlist, **keyparams):
  943.     """Create a blobby surface.
  944.  
  945.     Number of array elements for primitive variables:
  946.     -------------------------------------------------
  947.     constant: 1              varying: nleaf
  948.     uniform:  1              vertex:  nleaf
  949.  
  950.     Example: RiBlobby(2, [1001,0, 1003,0,16, 0,2,0,1],
  951.                       [1.5,0,0,0, 0,1.5,0,0, 0,0,1.5,0, 0,0,-.1,1,
  952.                       0.4, 0.01,0.3, 0.08], ["flat.zfile"])
  953.     """
  954.  
  955.     _ribout.write('Blobby '+str(nleaf)+' '+_seq2list(code)+' '+_seq2list(floats)+
  956.                   ' '+_seq2list(strings)+
  957.                   _paramlist2string(paramlist, keyparams)+'\n')
  958.  
  959. # RiColorSamples
  960. def RiColorSamples(nRGB, RGBn):
  961.     """Redefine the number of color components to be used for specifying colors.
  962.  
  963.     nRGB is a n x 3 matrix that can be used to transform the n component color
  964.     to a RGB color (n -> RGB).
  965.     RGBn is just the opposite, its a 3 x n matrix that's used to transform
  966.     a RGB color to a n component color (RGB -> n).
  967.     Thus, the new number of color components is len(matrix)/3 (matrix is
  968.     either nRGB or RGBn).
  969.  
  970.     Example: RiColorSamples([0.3,0.3,0.3], [1,1,1])
  971.     """
  972.     global _colorsamples
  973.  
  974.     if len(nRGB)!=len(RGBn):
  975.         _error(RIE_CONSISTENCY, RIE_ERROR,
  976.                "The color transformation matrices must have the same number of values.")
  977.  
  978.     if len(nRGB)%3!=0 or len(nRGB)==0:
  979.         _error(RIE_CONSISTENCY, RIE_ERROR,
  980.                "The number of values in the transformation matrices must be a multiple of 3.")
  981.         
  982.     _colorsamples = len(_flatten(nRGB))/3
  983.     _ribout.write('ColorSamples '+_seq2list(nRGB)+' '+_seq2list(RGBn)+'\n')
  984.  
  985. # RiColor
  986. def RiColor(Cs):
  987.     """Set the current color.
  988.  
  989.     Cs must be a sequence of at least N values where N is the number of
  990.     color samples (set by RiColorSamples(), default is 3).
  991.  
  992.     Example: RiColor([0.2,0.5,0.2])
  993.     """
  994.  
  995.     col=_seq2col(Cs)
  996.     _ribout.write("Color "+col+"\n")
  997.  
  998. # RiOpacity
  999. def RiOpacity(Os):
  1000.     """Set the current opacity.
  1001.  
  1002.     Os must be a sequence of at least N values where N is the number
  1003.     of color samples (set by RiColorSamples(), default is 3). The
  1004.     opacity values must lie in the range from 0 to 1 (where 0 means
  1005.     completely transparent and 1 means completely opaque).
  1006.  
  1007.     Example: RiOpacity([0,0,1])
  1008.     """
  1009.  
  1010.     col=_seq2col(Os)
  1011.     _ribout.write("Opacity "+col+"\n")
  1012.  
  1013. # RiShadingRate
  1014. def RiShadingRate(size):
  1015.     """Set the current shading rate to an area of size pixels.
  1016.  
  1017.     Example: RiShadingRate(1.0)
  1018.     """
  1019.  
  1020.     _ribout.write("ShadingRate %s\n"%size)
  1021.  
  1022. # RiShadingInterpolation
  1023. def RiShadingInterpolation(type):
  1024.     """Specify how shading samples are interpolated.
  1025.  
  1026.     type can be RI_CONSTANT or RI_SMOOTH.
  1027.  
  1028.     Example: RiShadingInterpolation(RI_SMOOTH)"""
  1029.  
  1030.     _ribout.write('ShadingInterpolation "'+type+'"\n')
  1031.  
  1032. # RiSurface
  1033. def RiSurface(name, *paramlist, **keyparams):
  1034.     """Set the current surface shader.
  1035.  
  1036.     Example: RiSurface("plastic", Kd=0.7, Ks=0.3)"""
  1037.  
  1038.     _ribout.write('Surface "'+name+'"'+ \
  1039.                  _paramlist2string(paramlist, keyparams)+"\n")
  1040.  
  1041. # RiInterior
  1042. def RiInterior(name, *paramlist, **keyparams):
  1043.     """Set the current interior volume shader.
  1044.  
  1045.     Example: RiInterior("water")
  1046.     """
  1047.  
  1048.     _ribout.write('Interior "'+name+'"'+_paramlist2string(paramlist, keyparams)+"\n")
  1049.  
  1050. # RiExterior
  1051. def RiExterior(name, *paramlist, **keyparams):
  1052.     """Set the current exterior volume shader.
  1053.  
  1054.     Example: RiExterior("fog")
  1055.     """
  1056.  
  1057.     _ribout.write('Exterior "'+name+'"'+_paramlist2string(paramlist, keyparams)+"\n")
  1058.  
  1059. # RiAtmosphere
  1060. def RiAtmosphere(name, *paramlist, **keyparams):
  1061.     """Set the current atmosphere shader.
  1062.  
  1063.     If name is RI_NULL then no atmosphere shader is used.
  1064.  
  1065.     Example: RiAtmosphere("fog")
  1066.     """
  1067.  
  1068.     if name==RI_NULL:
  1069.         _ribout.write('Atmosphere\n')
  1070.     else:
  1071.         _ribout.write('Atmosphere "'+name+'"'+ \
  1072.                       _paramlist2string(paramlist, keyparams)+"\n")
  1073.  
  1074. # RiDisplacement
  1075. def RiDisplacement(name, *paramlist, **keyparams):
  1076.     """Set the current displacement shader.
  1077.  
  1078.     Example: RiDisplacement("dented", km=1.5)
  1079.     """
  1080.  
  1081.     _ribout.write('Displacement "'+name+'"'+_paramlist2string(paramlist, keyparams)+"\n")
  1082.  
  1083. # RiImager
  1084. def RiImager(name, *paramlist, **keyparams):
  1085.     """Set an imager shader.
  1086.  
  1087.     if name is RI_NULL, no imager shader is used.
  1088.  
  1089.     Example: RiImager("background", "color bgcolor", [0.3,0.3,0.9])
  1090.     """
  1091.  
  1092.     if name==RI_NULL:
  1093.         _ribout.write('Imager\n')
  1094.     else:
  1095.         _ribout.write('Imager "'+name+'"'+_paramlist2string(paramlist, keyparams)+"\n")
  1096.  
  1097. # RiClipping
  1098. def RiClipping(near, far):
  1099.     """Sets the near and the far clipping plane along the direction of view.
  1100.  
  1101.     near and far must be positive values in the range from RI_EPSILON to
  1102.     RI_INFINITY.
  1103.  
  1104.     Example: RiClipping(0.1, 100)
  1105.     """
  1106.  
  1107.     _ribout.write("Clipping %s %s\n"%(near,far))
  1108.  
  1109. # RiClippingPlane
  1110. def RiClippingPlane(x, y, z, nx, ny, nz):
  1111.     """Adds a new clipping plane, defined by a surface point and its normal.
  1112.  
  1113.     All the geometry in positive normal direction is clipped.
  1114.  
  1115.     Example: RiClippingPlane(0,0,0, 0,0,-1) clips everything below the XY plane
  1116.     """
  1117.  
  1118.     _ribout.write('ClippingPlane %s %s %s %s %s %s\n'%(x,y,z,nx,ny,nz))
  1119.  
  1120. # RiDisplay
  1121. def RiDisplay(name,type,mode, *paramlist, **keyparams):
  1122.     """Specify the destination and type of the output.
  1123.  
  1124.     Example: RiDisplay("frame0001.tif", RI_FILE, RI_RGB)
  1125.              RiDisplay("myimage.tif", RI_FRAMEBUFFER, RI_RGB)
  1126.     """
  1127.  
  1128.     _ribout.write('Display "'+name+'" "'+type+'" "'+mode+'"'+ \
  1129.                  _paramlist2string(paramlist, keyparams)+"\n")
  1130.  
  1131. # RiFormat
  1132. def RiFormat(xres, yres, aspect):
  1133.     """Set the resolution of the output image and the aspect ratio of a pixel.
  1134.  
  1135.     Example: RiFormat(720,576,1)"""
  1136.  
  1137.     _ribout.write('Format %s %s %s\n'%(xres, yres, aspect))
  1138.  
  1139. # RiFrameAspectRatio
  1140. def RiFrameAspectRatio(frameratio):
  1141.     """Set the ratio between width and height of the image.
  1142.  
  1143.     Example: RiFrameAspectRatio(4.0/3)
  1144.     """
  1145.  
  1146.     _ribout.write('FrameAspectRatio %s\n'%frameratio)
  1147.  
  1148. # RiGeometricApproximation
  1149. def RiGeometricApproximation(type, value):
  1150.     """Sets parameters for approximating surfaces.
  1151.  
  1152.     Example: RiGeometricApproximation(RI_FLATNESS, 0.5)  (default value)
  1153.     """
  1154.  
  1155.     _ribout.write('GeometricApproximation "'+type+'" '+str(value)+"\n")
  1156.  
  1157.  
  1158. # RiProjection
  1159. def RiProjection(name, *paramlist, **keyparams):
  1160.     """Specify a projection method.
  1161.  
  1162.     The standard projections are RI_PERSPECTIVE and RI_ORTHOGRAPHIC.
  1163.     The perspective projection takes one optional parameter, RI_FOV.
  1164.  
  1165.     Example: RiProjection(RI_PERSPECTIVE, fov=45)
  1166.     """
  1167.  
  1168.     if name==RI_NULL:
  1169.         _ribout.write('Projection\n')
  1170.     else:
  1171.         _ribout.write('Projection "'+name+'"'+ \
  1172.                       _paramlist2string(paramlist, keyparams)+"\n")
  1173.  
  1174. # RiScreenWindow
  1175. def RiScreenWindow(left, right, bottom, top):
  1176.     """Specify the extents of the output image on the image plane.
  1177.  
  1178.     Example: RiScreenWindow(-1,1,-1,1)
  1179.     """
  1180.  
  1181.     _ribout.write('ScreenWindow %s %s %s %s\n'%(left, right, bottom, top))
  1182.  
  1183. # RiCropWindow
  1184. def RiCropWindow(left, right, bottom, top):
  1185.     """Specify a subwindow to render.
  1186.  
  1187.     The values each lie between 0 and 1.
  1188.  
  1189.     Example: RiCropWindow(0.0, 1.0 , 0.0, 1.0)  (renders the entire frame)
  1190.              RiCropWindow(0.5, 1.0 , 0.0, 0.5)  (renders the top right quarter)
  1191.     """
  1192.  
  1193.     _ribout.write('CropWindow %s %s %s %s\n'%(left, right, bottom, top))
  1194.  
  1195. # RiPixelSamples
  1196. def RiPixelSamples(xsamples, ysamples):
  1197.     """Set the sampling rate in horizontal and vertical direction.
  1198.  
  1199.     Example: RiPixelSamples(2,2)"""
  1200.  
  1201.     _ribout.write("PixelSamples %s %s\n"%(max(1,xsamples), max(1,ysamples)))
  1202.  
  1203. # RiPixelVariance
  1204. def RiPixelVariance(variance):
  1205.     """Limit the acceptable variance in the output value of pixels.
  1206.  
  1207.     Example: RiPixelVariance(0.01)"""
  1208.  
  1209.     _ribout.write('PixelVariance %s\n'%variance)
  1210.  
  1211. # Predefined filter functions:
  1212. RiGaussianFilter   = "gaussian"
  1213. RiBoxFilter        = "box"
  1214. RiTriangleFilter   = "triangle"
  1215. RiSincFilter       = "sinc"
  1216. RiCatmullRomFilter = "catmull-rom"
  1217.  
  1218. # RiPixelFilter
  1219. def RiPixelFilter(function, xwidth, ywidth):
  1220.     """Set a pixel filter function and its width in pixels.
  1221.  
  1222.     Note: Here you can only use one of the predefined filter functions:
  1223.     RiGaussianFilter, RiBoxFilter, RiTriangleFilter, RiSincFilter and
  1224.     RiCatmullRomFilter.
  1225.     Passing a callable as filter function will issue a warning and ignore
  1226.     the call.
  1227.  
  1228.     Example: RiPixelFilter(RiGaussianFilter, 2.0, 1.0)"""
  1229.     
  1230.     if callable(function):
  1231.         _error(RIE_INCAPABLE, RIE_WARNING, "Only the standard filters can be stored in a RIB stream.")
  1232.         return
  1233.  
  1234.     _ribout.write('PixelFilter "'+function+'" '+str(xwidth)+' '+str(ywidth)+'\n')
  1235.  
  1236. # RiExposure
  1237. def RiExposure(gain, gamma):
  1238.     """Sets the parameters for the output color transformation.
  1239.  
  1240.     The transformation is color_out = (color_in*gain)^(1/gamma)
  1241.  
  1242.     Example: RiExposure(1.3, 2.2)
  1243.     """
  1244.  
  1245.     _ribout.write("Exposure %s %s\n"%(gain, gamma))
  1246.  
  1247. # RiQuantize
  1248. def RiQuantize(type, one, min, max, ditheramplitude):
  1249.     """Set the quantization parameters for colors and depth.
  1250.  
  1251.     Example: RiQuantize(RI_RGBA, 2048, -1024, 3071, 1.0)
  1252.     """
  1253.  
  1254.     _ribout.write('Quantize "%s" %s %s %s %s\n'%(type, one, min, max, ditheramplitude))
  1255.     
  1256.  
  1257. # RiDepthOfField
  1258. def RiDepthOfField(fstop, focallength, focaldistance):
  1259.     """Set depth of field parameters.
  1260.  
  1261.     If fstop is RI_INFINITY depth of field is turned off.
  1262.  
  1263.     Example: RiDepthOfField(22,45,1200)
  1264.     """
  1265.  
  1266.     if fstop==RI_INFINITY:
  1267.         _ribout.write('DepthOfField\n')
  1268.     else:
  1269.         _ribout.write('DepthOfField %s %s %s\n'%(fstop, focallength, focaldistance))
  1270.  
  1271. # RiMotionBegin
  1272. def RiMotionBegin(*times):
  1273.     """Start the definition of a moving primitive.
  1274.  
  1275.     You can specify the time values directly or inside a sequence,
  1276.     for example, RiMotionBegin(0,1) or RiMotionBegin([0,1]).
  1277.  
  1278.     Example: RiMotionBegin(0.0, 1.0)
  1279.              RiTranslate(1.0, 0.0, 0.0)
  1280.              RiTranslate(1.0, 2.0, 0.0)
  1281.              RiMotionEnd()
  1282.     """
  1283.  
  1284.     global _insidemotion
  1285.  
  1286.     if _insidemotion:
  1287.         _error(RIE_ILLSTATE, RIE_ERROR, "Motion blocks cannot be nested.")
  1288.  
  1289.     _ribout.write('MotionBegin '+_seq2list(times)+'\n')
  1290.     _insidemotion = 1
  1291.  
  1292. # RiMotionEnd
  1293. def RiMotionEnd():
  1294.     "Terminates the definition of a moving primitive."
  1295.  
  1296.     global _insidemotion
  1297.  
  1298.     _ribout.write('MotionEnd\n')
  1299.     _insidemotion = 0
  1300.  
  1301. # RiShutter
  1302. def RiShutter(opentime, closetime):
  1303.     """Set the times at which the shutter opens and closes.
  1304.  
  1305.     Example: RiShutter(0.1, 0.9)
  1306.     """
  1307.  
  1308.     _ribout.write('Shutter %s %s\n'%(opentime, closetime))
  1309.  
  1310. # RiTranslate
  1311. def RiTranslate(*translation):
  1312.     """Concatenate a translation onto the current transformation.
  1313.  
  1314.     The translation is either given as 3 scalars or a sequence of
  1315.     3 scalars.
  1316.  
  1317.     Example: RiTranslate(1.2, 4.3, -0.5)
  1318.              or
  1319.              RiTranslate( (1.2, 4.3, -0.5) )
  1320.     """
  1321.  
  1322.     # Argument = sequence?
  1323.     if len(translation)==1:
  1324.         s=_seq2list(translation,3)
  1325.         _ribout.write('Translate '+s[1:-1]+"\n")
  1326.     # Argument = 3 scalars?
  1327.     elif len(translation)==3:
  1328.         dx,dy,dz=translation
  1329.         _ribout.write('Translate %s %s %s\n'%(dx,dy,dz))
  1330.     # Invalid argument size
  1331.     else:
  1332.         raise TypeError, "RiTranslate() only takes a sequence or three scalars as arguments"
  1333.  
  1334. # RiRotate
  1335. def RiRotate(angle, *axis):
  1336.     """Rotate about angle degrees about the given axis.
  1337.  
  1338.     The axis is either given as 3 scalars or a sequence of 3 scalars.
  1339.  
  1340.     Example: RiRotate(90, 1,0,0)
  1341.     """
  1342.  
  1343.     # Argument = sequence?
  1344.     if len(axis)==1:
  1345.         s=_seq2list(axis,3)
  1346.         _ribout.write('Rotate %s %s\n'%(angle, s[1:-1]))
  1347.     # Argument = 3 scalars?
  1348.     elif len(axis)==3:
  1349.         ax,ay,az=axis
  1350.         _ribout.write('Rotate %s %s %s %s\n'%(angle, ax, ay, az))
  1351.     # Invalid argument size
  1352.     else:
  1353.         raise TypeError, "RiRotate() only takes 2 or 4 arguments ("+`len(axis)+1`+" given)"
  1354.  
  1355.  
  1356. # RiScale
  1357. def RiScale(*scaling):
  1358.     """Concatenate a scaling onto the current transformation.
  1359.  
  1360.     The scaling is either given as 3 scalars or a sequence of 3 scalars.
  1361.  
  1362.     Example: RiScale(2,2,2)"""
  1363.  
  1364.     # Argument = sequence?
  1365.     if len(scaling)==1:
  1366.         s=_seq2list(scaling,3)
  1367.         _ribout.write('Scale '+s[1:-1]+"\n")
  1368.     # Argument = 3 scalars?
  1369.     elif len(scaling)==3:
  1370.         sx,sy,sz=scaling
  1371.         _ribout.write('Scale %s %s %s\n'%(sx, sy, sz))
  1372.     # Invalid argument size
  1373.     else:
  1374.         raise TypeError, "RiScale() only takes a sequence or three scalars as arguments"
  1375.  
  1376.  
  1377. # RiSkew
  1378. def RiSkew(angle, *vecs):
  1379.     """Concatenate a skew onto the current transformation.
  1380.  
  1381.     angle is given in degrees.
  1382.     The two vectors are each given as 3 scalars or a sequence
  1383.     of 3 scalars.
  1384.  
  1385.     Example: RiSkew(45, 0,1,0, 1,0,0)
  1386.     """
  1387.  
  1388.     # Argument = two sequences?
  1389.     if len(vecs)==2:
  1390.         s1=_seq2list(vecs[0],3)
  1391.         s2=_seq2list(vecs[1],3)
  1392.         _ribout.write('Skew '+str(angle)+" "+s1[1:-1]+" "+s2[1:-1]+"\n")
  1393.     # Argument = 6 scalars?
  1394.     elif len(vecs)==6:
  1395.         dx1,dy1,dz1,dx2,dy2,dz2=vecs
  1396.         _ribout.write('Skew %s %s %s %s %s %s %s\n'%(angle, dx1, dy1, dz1, dx2, dy2, dz2))
  1397.     # Invalid argument size
  1398.     else:
  1399.         raise TypeError, "RiSkew() only takes 3 or 7 arguments ("+`len(vecs)+1`+" given)"
  1400.  
  1401.  
  1402. # RiPerspective
  1403. def RiPerspective(fov):
  1404.     """Concatenate a perspective transformation onto the current transformation.
  1405.     
  1406.     Example: RiPerspective(45)"""
  1407.  
  1408.     _ribout.write('Perspective %s\n'%fov)
  1409.  
  1410. # RiIdentity
  1411. def RiIdentity():
  1412.     """Set the current transformation to the identity.
  1413.  
  1414.     Example: RiIdentity()
  1415.     """
  1416.  
  1417.     _ribout.write('Identity\n')
  1418.  
  1419. # RiConcatTransform
  1420. def RiConcatTransform(transform):
  1421.     """Concatenate a transformation onto the current transformation.
  1422.  
  1423.     transform must be a sequence that evaluates to 16 floating point
  1424.     values (4x4 matrix).
  1425.  
  1426.     Example: RiConcatTransform([2,0,0,0, 0,2,0,0, 0,0,2,0, 0,0,0,1])
  1427.              RiConcatTransform([[2,0,0,0], [0,2,0,0], [0,0,2,0], [0,0,0,1]])
  1428.     """
  1429.  
  1430.     _ribout.write('ConcatTransform '+_seq2list(transform,16)+"\n")
  1431.  
  1432. # RiTransform
  1433. def RiTransform(transform):
  1434.     """Set the current transformation.
  1435.  
  1436.     transform must be a sequence that evaluates to 16 floating point
  1437.     values (4x4 matrix).
  1438.  
  1439.     Example: RiTransform([2,0,0,0, 0,2,0,0, 0,0,2,0, 0,0,0,1])
  1440.              RiTransform([[2,0,0,0], [0,2,0,0], [0,0,2,0], [0,0,0,1]])
  1441.     """
  1442.  
  1443.     _ribout.write('Transform '+_seq2list(transform,16)+"\n")
  1444.  
  1445. # RiSides
  1446. def RiSides(nsides):
  1447.     """Specify the number of visible sides of subsequent surfaces.
  1448.  
  1449.     Example: RiSides(1)"""
  1450.  
  1451.     if nsides!=1 and nsides!=2:
  1452.         _error(RIE_RANGE, RIE_ERROR, "The number of sides (nsides) must be either 1 or 2.")
  1453.  
  1454.     _ribout.write('Sides %s\n'%nsides)
  1455.  
  1456. # RiOrientation
  1457. def RiOrientation(orientation):
  1458.     """Set the orientation of subsequent surfaces.
  1459.  
  1460.     orientation is either RI_OUTSIDE, RI_INSIDE, RI_LH (left handed)
  1461.     or RI_RH (right handed).
  1462.     """
  1463.  
  1464.     _ribout.write('Orientation "'+orientation+'"\n')
  1465.  
  1466. # RiReverseOrientation
  1467. def RiReverseOrientation():
  1468.     """Causes the current orientation to be toggled.
  1469.  
  1470.     Example: RiReverseOrientation()
  1471.     """
  1472.  
  1473.     _ribout.write('ReverseOrientation\n')
  1474.  
  1475. # RiMatte
  1476. def RiMatte(onoff):
  1477.     """Indicates whether subsequent primitives are matte objects.
  1478.  
  1479.     Example: RiMatte(RI_TRUE)
  1480.     """
  1481.     if onoff:
  1482.         _ribout.write('Matte 1\n')
  1483.     else:
  1484.         _ribout.write('Matte 0\n')
  1485.  
  1486. # RiLightSource
  1487. def RiLightSource(name, *paramlist, **keyparams):
  1488.     """Add another light source and return its light handle.
  1489.  
  1490.     name is the name of the light source shader. You can set a user defined
  1491.     string handle via the RI_HANDLEID parameter.
  1492.  
  1493.     Example: light1 = RiLightSource("distantlight", intensity=1.5)
  1494.     """
  1495.     global _lighthandle
  1496.  
  1497.     paramlist = _merge_paramlist(paramlist, keyparams)
  1498.     lshandle = None
  1499.     for i in range(0, len(paramlist), 2):
  1500.         token = paramlist[i]
  1501.         if token==RI_HANDLEID:
  1502.             lshandle = str(paramlist[i+1])
  1503.             paramlist = paramlist[:i]+paramlist[i+2:]
  1504.             break
  1505.  
  1506.     # Check if the user provided a handle id...
  1507.     if lshandle is None:
  1508.         _lighthandle += 1
  1509.         lshandle = _lighthandle
  1510.         _ribout.write('LightSource "%s" %d%s\n'%(name, lshandle, _paramlist2string(paramlist, {})))
  1511.     else:
  1512.         _ribout.write('LightSource "%s" "%s"%s\n'%(name, lshandle, _paramlist2string(paramlist, {})))
  1513.         
  1514.     return lshandle
  1515.  
  1516. # RiIlluminate
  1517. def RiIlluminate(light, onoff):
  1518.     """Activate or deactive a light source.
  1519.  
  1520.     Example: RiIlluminate(lgt, RI_TRUE)
  1521.     """
  1522.  
  1523.     if type(light)==str or type(light)==unicode:
  1524.         _ribout.write('Illuminate "%s" %d\n'%(light, onoff))
  1525.     else:
  1526.         _ribout.write('Illuminate %d %d\n'%(light, onoff))
  1527.         
  1528.  
  1529. # RiAreaLightSource
  1530. def RiAreaLightSource(name, *paramlist, **keyparams):
  1531.     """Start the definition of an area light and return the light handle.
  1532.  
  1533.     You can set a user defined string handle via the RI_HANDLEID parameter.
  1534.     
  1535.     Example: RiAttributeBegin()
  1536.              area1 = RiAreaLightSource("arealight", intensity=0.75)
  1537.              ....
  1538.              RiAttributeEnd()
  1539.              RiIlluminate(area1, RI_TRUE)
  1540.     """
  1541.     global _lighthandle
  1542.  
  1543.     # Check if the user provided a handle id...
  1544.     if RI_HANDLEID in keyparams:
  1545.         lshandle = str(keyparams[RI_HANDLEID])
  1546.         del keyparams[RI_HANDLEID]
  1547.         _ribout.write('AreaLightSource "%s" "%s"%s\n'%(name, lshandle, _paramlist2string((), keyparams)))
  1548.     else:
  1549.         _lighthandle+=1
  1550.         lshandle = _lighthandle
  1551.         _ribout.write('AreaLightSource "%s" %d%s\n'%(name, lshandle, _paramlist2string((), keyparams)))
  1552.  
  1553.     return lshandle
  1554.  
  1555. # RiDeclare
  1556. def RiDeclare(name, declaration):
  1557.     """Declare the name and type of a variable.
  1558.  
  1559.     The syntax of the declaration is:  [class] [type] ['['n']']
  1560.  
  1561.     class ::= constant | uniform | varying | vertex
  1562.     type  ::= float | integer | string | color | point | vector | normal |
  1563.               matrix | hpoint
  1564.     
  1565.     Example: RiDeclare("foo","uniform float")
  1566.              RiDeclare("bar","constant integer [4]")
  1567.              RiDeclare("mycolor", "varying color")
  1568.     """
  1569.  
  1570.     global _declarations
  1571.  
  1572.     if declaration==RI_NULL:
  1573.         declaration=""
  1574.         
  1575.     _ribout.write('Declare "'+name+'" "'+declaration+'"\n')
  1576.     _declarations[name]=declaration
  1577.     return name
  1578.  
  1579. # RiArchiveRecord
  1580. def RiArchiveRecord(type, format, *args):
  1581.     """Output a user data record.
  1582.  
  1583.     type is one of RI_COMMENT, RI_STRUCTURE or RI_VERBATIM.
  1584.  
  1585.     For comments and structural hints you can use the special variables
  1586.     $CREATOR, $DATE and $USER which will be replaced by their appropriate
  1587.     value (program name, date string, user name).
  1588.  
  1589.     Example: RiArchiveRecord(RI_COMMENT, "Frame %d", 2)
  1590.              RiArchiveRecord(RI_STRUCTURE, "CreationDate $DATE")
  1591.     """
  1592.  
  1593.     if type!=RI_VERBATIM and format.find("$")!=-1:
  1594.         format = format.replace("$DATE", time.ctime())
  1595.         format = format.replace("$CREATOR", sys.argv[0])
  1596.         try:
  1597.             user = getpass.getuser()
  1598.         except:
  1599.             user = "<unknown>"
  1600.         format = format.replace("$USER", user)
  1601.  
  1602.     if type==RI_COMMENT:
  1603.         outstr = "# "+format%args+"\n"
  1604.     elif type==RI_STRUCTURE:
  1605.         outstr = "##"+format%args+"\n"
  1606.     elif type==RI_VERBATIM:
  1607.         outstr = format%args
  1608.     else:
  1609.         return
  1610.  
  1611.     # Use the writeArchiveRecord() if there is any, otherwise use write()
  1612.     # (the latter case happens when RiBegin() wasn't called. _ribout is
  1613.     # then set to stdout)
  1614.     if hasattr(_ribout, "writeArchiveRecord"):
  1615.         _ribout.writeArchiveRecord(outstr)
  1616.     else:
  1617.         _ribout.write(outstr)
  1618.     
  1619.     
  1620. # RiReadArchive
  1621. def RiReadArchive(filename, callback=None, *ignore):
  1622.     """Include an archive file.
  1623.  
  1624.     In this implementation the callback function is not used and can
  1625.     be left out.
  1626.  
  1627.     RiExample: RiReadArchive("teapot.rib")"""
  1628.  
  1629.     _ribout.write('ReadArchive "'+filename+'"\n')
  1630.  
  1631.  
  1632. def RiProcDelayedReadArchive(): return "DelayedReadArchive"
  1633. def RiProcRunProgram(): return "RunProgram"
  1634. def RiProcDynamicLoad(): return "DynamicLoad"
  1635. def RiProcFree(data): pass
  1636.  
  1637. # RiProcedural
  1638. def RiProcedural(data, bound, subdividefunc, freefunc=None):
  1639.     """Declare a procedural model.
  1640.  
  1641.     subdividefunc and freefunc may either be the standard RenderMan
  1642.     procedurals (RiProcDelayedReadArchive, RiProcRunProgram,
  1643.     RiProcDynamicLoad and RiProcFree) or Python callables.
  1644.     In the former case, data must be a sequence of strings or a single
  1645.     string containing the data for the functions. In the latter case,
  1646.     data may be any Python object which is just passed on to the
  1647.     functions. 
  1648.     freefunc is optional and defaults to None.
  1649.  
  1650.     Because this module can only produce RIB, a custom subdivide function is
  1651.     simply called with a detail value of RI_INFINITY to generate all the
  1652.     data at once.
  1653.     
  1654.     Example: RiProcedural("mymodel.rib", [-1,1,-1,1,-1,1], \\
  1655.                           RiProcDelayedReadArchive, RI_NULL)
  1656.                           
  1657.              RiProcedural(["python teapot.py",""],[0,1,0,1,0,1], \\
  1658.                           RiProcRunProgram, RI_NULL)
  1659.                           
  1660.              RiProcedural(["teapot.so",""],[0,1,0,1,0,1], \\
  1661.                           RiProcDynamicLoad, RI_NULL)
  1662.     """
  1663.     if subdividefunc in [RiProcDelayedReadArchive, RiProcRunProgram, RiProcDynamicLoad]:
  1664.         if type(data)==types.StringType:
  1665.             data=[data]
  1666.         _ribout.write('Procedural "'+subdividefunc()+'" '+_seq2list(data)+ \
  1667.                      ' '+_seq2list(bound,6)+"\n")
  1668.     else:
  1669.         # Call the custom procedure to generate all the data...
  1670.         subdividefunc(data, RI_INFINITY)
  1671.         if freefunc is not None:
  1672.             freefunc(data)
  1673.  
  1674. # RiGeometry
  1675. def RiGeometry(type, *paramlist, **keyparams):
  1676.     """Create an implementation-specific geometric primitive.
  1677.  
  1678.     Example: RiGeometry("teapot")
  1679.     """
  1680.  
  1681.     _ribout.write('Geometry "'+type+'"'+_paramlist2string(paramlist, keyparams)+"\n")
  1682.  
  1683. # RiBound
  1684. def RiBound(bound):
  1685.     """Set the bounding box for subsequent primitives.
  1686.  
  1687.     bound must be a sequence of six floating point values specifying
  1688.     the extent of the box along each coordinate direction:
  1689.     bound = [xmin, xmax, ymin, ymax, zmin, zmax]
  1690.  
  1691.     Example: RiBound([-1,1, 0,1, 0.5,0.75])
  1692.     """
  1693.  
  1694.     _ribout.write('Bound '+_seq2list(bound,6)+'\n')
  1695.     
  1696. # RiSolidBegin
  1697. def RiSolidBegin(type):
  1698.     """Start the definition of a solid object.
  1699.  
  1700.     type is one of RI_PRIMITIVE, RI_UNION, RI_DIFFERENCE and RI_INTERSECTION.
  1701.  
  1702.     Example: RiSolidBegin(RI_INTERSECTION)
  1703.              RiSolidBegin(RI_PRIMITIVE)
  1704.              ...
  1705.              RiSolidEnd()
  1706.              RiSolidBegin(RI_PRIMITIVE)
  1707.              ...
  1708.              RiSolidEnd()
  1709.              RiSolidEnd()
  1710.     """
  1711.  
  1712.     _ribout.write('SolidBegin "'+type+'"\n')
  1713.  
  1714. # RiSolidEnd
  1715. def RiSolidEnd():
  1716.     """Terminate the definition of a solid object."""
  1717.  
  1718.     _ribout.write('SolidEnd\n')
  1719.  
  1720. # RiObjectBegin
  1721. def RiObjectBegin(*paramlist, **keyparams):
  1722.     """Start the definition of a retained model and return the object handle.
  1723.  
  1724.     You can pass a user defined string handle via the RI_HANDLEID parameter.
  1725.  
  1726.     Example: obj1 = RiObjectBegin()
  1727.              ...
  1728.              RiObjectEnd()
  1729.     """
  1730.     global _objecthandle, _insideobject
  1731.  
  1732.     if _insideobject:
  1733.         _error(RIE_ILLSTATE, RIE_ERROR, "Object blocks cannot be nested.")
  1734.  
  1735.     keyparams = _paramlist2dict(paramlist, keyparams)
  1736.  
  1737.     # Check if the user provided a handle id...
  1738.     if RI_HANDLEID in keyparams:
  1739.         objhandle = str(keyparams[RI_HANDLEID])
  1740.         del keyparams[RI_HANDLEID]
  1741.         _ribout.write('ObjectBegin "%s"\n'%objhandle)
  1742.     else:
  1743.         _objecthandle+=1
  1744.         objhandle = _objecthandle
  1745.         _ribout.write('ObjectBegin %d\n'%objhandle)
  1746.     
  1747.     _insideobject=1
  1748.  
  1749.     return objhandle
  1750.  
  1751. # RiObjectEct
  1752. def RiObjectEnd():
  1753.     """Terminate the definition of a retained model."""
  1754.  
  1755.     global _insideobject
  1756.     
  1757.     _ribout.write('ObjectEnd\n')
  1758.     _insideobject=0
  1759.  
  1760. # RiObjectInstance
  1761. def RiObjectInstance(handle):
  1762.     """Create an instance of a previously defined model.
  1763.  
  1764.     Example: RiObjectInstance(obj1)
  1765.     """
  1766.  
  1767.     if type(handle)==str or type(handle)==unicode:
  1768.         _ribout.write('ObjectInstance "%s"\n'%handle)
  1769.     else:
  1770.         _ribout.write('ObjectInstance %d\n'%handle)
  1771.  
  1772. # RiTextureCoordinates
  1773. def RiTextureCoordinates(s1, t1, s2, t2, s3, t3, s4, t4):
  1774.     """Set the current set of texture coordinates.
  1775.  
  1776.     Declares a projection from the unit square [(0,0), (1,0), (0,1), (1,1)]
  1777.     in parameter space to quadrilateral [(s1,t1), (s2,t2), (s3,t3), (s4,t4)]
  1778.     in texture space.
  1779.  
  1780.     Example: RiTextureCoordinates(0.0, 0.0, 2.0, -0.5, -0.5, 1.75, 3.0, 3.0)"""
  1781.  
  1782.     _ribout.write('TextureCoordinates %s %s %s %s %s %s %s %s\n'%(s1,t1,s2,t2,s3,t3,s4,t4))
  1783.  
  1784. # RiMakeTexture
  1785. def RiMakeTexture(picname, texname, swrap, twrap, filterfunc, swidth, twidth, *paramlist, **keyparams):
  1786.     """Convert an image file into a texture file.
  1787.  
  1788.     swrap and twrap are one of RI_PERIODIC, RI_CLAMP or RI_BLACK.
  1789.     filterfunc has to be one of the predefined filter functions:
  1790.     RiGaussianFilter, RiBoxFilter, RiTriangleFilter, RiSincFilter or
  1791.     RiCatmullRomFilter (otherwise a warning is issued and the call is ignored).
  1792.     swidth and twidth define the support of the filter.
  1793.  
  1794.     Example: RiMakeTexture("img.tif", "tex.tif", RI_PERIODIC, RI_CLAMP, \\
  1795.                            RiGaussianFilter, 2,2)
  1796.     """
  1797.     
  1798.     if callable(filterfunc):
  1799.         _error(RIE_INCAPABLE, RIE_WARNING, "Only the standard filters can be stored in a RIB stream.")
  1800.         return
  1801.  
  1802.     _ribout.write('MakeTexture "'+picname+'" "'+texname+'" "'+swrap+'" "'+
  1803.                   twrap+'" "'+filterfunc+'" '+str(swidth)+' '+str(twidth)+
  1804.                   _paramlist2string(paramlist, keyparams)+'\n')
  1805.  
  1806. # RiMakeLatLongEnvironment
  1807. def RiMakeLatLongEnvironment(picname, texname, filterfunc, swidth, twidth, *paramlist, **keyparams):
  1808.     """Convert an image file into an environment map.
  1809.  
  1810.     filterfunc has to be one of the predefined filter functions:
  1811.     RiGaussianFilter, RiBoxFilter, RiTriangleFilter, RiSincFilter or
  1812.     RiCatmullRomFilter (otherwise a warning is issued and the call is ignored).
  1813.     swidth and twidth define the support of the filter.
  1814.  
  1815.     Example: RiMakeLatLongEnvironment("img.tif", "tex.tif",
  1816.                                       RiGaussianFilter, 2,2)
  1817.     """
  1818.     
  1819.     if callable(filterfunc):
  1820.         _error(RIE_INCAPABLE, RIE_WARNING, "Only the standard filters can be stored in a RIB stream.")
  1821.         return
  1822.  
  1823.     _ribout.write('MakeLatLongEnvironment "'+picname+'" "'+texname+'" "'+
  1824.                   filterfunc+'" '+str(swidth)+' '+str(twidth)+
  1825.                   _paramlist2string(paramlist, keyparams)+'\n')
  1826.  
  1827. # RiMakeCubeFaceEnvironment
  1828. def RiMakeCubeFaceEnvironment(px,nx,py,ny,pz,nz, texname, fov, filterfunc, swidth, twidth, *paramlist, **keyparams):
  1829.     """Convert six image files into an environment map.
  1830.  
  1831.     The px/nx images are the views in positive/negative x direction.
  1832.     fov is the field of view that was used to generate the individual images.
  1833.     filterfunc has to be one of the predefined filter functions:
  1834.     RiGaussianFilter, RiBoxFilter, RiTriangleFilter, RiSincFilter or
  1835.     RiCatmullRomFilter (otherwise a warning is issued and the call is ignored).
  1836.     swidth and twidth define the support of the filter.
  1837.  
  1838.     Example: RiMakeCubeFaceEnvironment("px.tif","nx.tif","py.tif","ny.tif",
  1839.                                        "pz.tif","nz.tif", "tex.tif", 92.0,
  1840.                                         RiGaussianFilter, 2,2)
  1841.     """
  1842.     
  1843.     if callable(filterfunc):
  1844.         _error(RIE_INCAPABLE, RIE_WARNING, "Only the standard filters can be stored in a RIB stream.")
  1845.         return
  1846.  
  1847.     _ribout.write('MakeCubeFaceEnvironment "'+px+'" "'+nx+'" "'+
  1848.                   py+'" "'+ny+'" "'+pz+'" "'+nz+'" "'+ texname+'" '+
  1849.                   str(fov)+' "'+filterfunc+'" '+str(swidth)+' '+str(twidth)+
  1850.                   _paramlist2string(paramlist, keyparams)+'\n')
  1851.  
  1852. # RiMakeShadow
  1853. def RiMakeShadow(picname, shadowname, *paramlist, **keyparams):
  1854.     """Transform a depth image into a shadow map.
  1855.  
  1856.     Example: RiMakeShadow("depthimg.tif", "shadow.tif")
  1857.     """
  1858.     
  1859.     _ribout.write('MakeShadow "'+picname+'" "'+shadowname+'"'+_paramlist2string(paramlist, keyparams)+'\n')
  1860.  
  1861. # RiDetail
  1862. def RiDetail(bound):
  1863.     """Set the current bounding box.
  1864.  
  1865.     bound must be a sequence of six floating point values specifying
  1866.     the extent of the box along each coordinate direction:
  1867.     bound = [xmin, xmax, ymin, ymax, zmin, zmax]
  1868.  
  1869.     Example: RiDetail([10,20,40,70,0,1])
  1870.     """
  1871.  
  1872.     _ribout.write('Detail '+_seq2list(bound,6)+'\n')
  1873.  
  1874. # RiRelativeDetail
  1875. def RiRelativeDetail(relativedetail):
  1876.     """Set the factor for all level of detail calculations.
  1877.  
  1878.     Example: RiRelativeDetail(0.7)"""
  1879.  
  1880.     _ribout.write('RelativeDetail %s\n'%relativedetail)
  1881.  
  1882. # RiDetailRange
  1883. def RiDetailRange(minvisible, lowertransition, uppertransition, maxvisible):
  1884.     """Set the current detail range.
  1885.  
  1886.     The values of the parameters must satisfy the following ordering:
  1887.     minvisible <= lowertransition <= uppertransition <= maxvisible
  1888.  
  1889.                 lowertransition  uppertransition
  1890.  visibility         |____________________|       
  1891.     ^               /                    \\
  1892.     |              /                      \\
  1893.     |_____________/                        \\_____________\\ Level of detail
  1894.                  |                          |            /
  1895.              minvisible                      maxvisible
  1896.  
  1897.     Example: RiDetailRange(0,0,10,20)
  1898.     """
  1899.  
  1900.     _ribout.write('DetailRange %s %s %s %s\n'%(minvisible, lowertransition, uppertransition, maxvisible))
  1901.  
  1902. # RiCoordinateSystem
  1903. def RiCoordinateSystem(spacename):
  1904.     """Mark the current coordinate system with a name.
  1905.  
  1906.     Example: RiCoordinateSystem("lamptop")
  1907.     """
  1908.  
  1909.     _ribout.write('CoordinateSystem "'+spacename+'"\n')
  1910.  
  1911. # RiTransformPoints
  1912. def RiTransformPoints(fromspace, tospace, points):
  1913.     """Transform a set of points from one space to another.
  1914.  
  1915.     This function is not implemented and always returns None.
  1916.     """
  1917.  
  1918.     return None
  1919.  
  1920. # RiCoordSysTransform
  1921. def RiCoordSysTransform(spacename):
  1922.     """Replace the current transformation matrix with spacename.
  1923.  
  1924.     Example: RiCoordSysTransform("lamptop")
  1925.     """
  1926.  
  1927.     _ribout.write('CoordSysTransform "'+spacename+'"\n')
  1928.  
  1929. # RiContext
  1930. def RiContext(handle):
  1931.     """Set the current active rendering context.
  1932.  
  1933.     Example: ctx1 = RiGetContext()
  1934.              ...
  1935.              RiContext(ctx1)
  1936.     """
  1937.  
  1938.     _switch_context(handle)
  1939.  
  1940. # RiGetContext
  1941. def RiGetContext():
  1942.     """Get a handle for the current active rendering context.
  1943.  
  1944.     Example: ctx1 = RiGetContext()
  1945.              ...
  1946.              RiContext(ctx1)"""
  1947.  
  1948.     global _current_context
  1949.  
  1950.     return _current_context
  1951.  
  1952. ##################### Global variabels (internal) ####################
  1953.  
  1954. _contexts     = {}
  1955. _current_context = None
  1956.  
  1957. ####
  1958.  
  1959. # Initially the output stream is stdout (and not an instance of RIBStream)
  1960. # In interactive sessions this prevents the version number to be written.
  1961. _ribout       = sys.stdout
  1962. _colorsamples = 3
  1963. _lighthandle  = 0
  1964. _objecthandle = 0
  1965. _errorhandler = RiErrorPrint
  1966. _declarations = {}
  1967.  
  1968. _insideframe  = 0
  1969. _insideworld  = 0
  1970. _insideobject = 0
  1971. _insidesolid  = 0
  1972. _insidemotion = 0
  1973.  
  1974. # If you're adding new global variables then make sure that they're
  1975. # saved and loaded from the context handling functions and initialized
  1976. # in RiBegin() and during the module initialization.
  1977.  
  1978. ##################### Internal helper functions #######################
  1979.  
  1980. def _save_context(handle):
  1981.     "Save a context."
  1982.     ctx = (_ribout, _colorsamples, _lighthandle, _objecthandle,
  1983.            _errorhandler, _declarations,
  1984.            _insideframe, _insideworld, _insideobject, _insidesolid,
  1985.            _insidemotion)
  1986.     _contexts[handle]=ctx
  1987.  
  1988. def _load_context(handle):
  1989.     "Load a context."
  1990.     global _ribout, _colorsamples, _lighthandle, _objecthandle
  1991.     global _errorhandler, _declarations, _insideframe, _insideworld
  1992.     global _insideobject, _insidesolid, _insidemotion
  1993.  
  1994.     _ribout, _colorsamples, _lighthandle, _objecthandle, \
  1995.     _errorhandler, _declarations, \
  1996.     _insideframe, _insideworld, _insideobject, _insidesolid, \
  1997.     _insidemotion = _contexts[handle]
  1998.  
  1999. def _create_new_context():
  2000.     "Create a new context and make it the active one."
  2001.     global _current_context
  2002.  
  2003.     keys = _contexts.keys()
  2004.     if len(keys)>0:
  2005.         handle = max(keys)+1
  2006.     else:
  2007.         handle = 1
  2008.     _contexts[handle]=()
  2009.     
  2010.     if _current_context!=None:
  2011.         _save_context(_current_context)
  2012.  
  2013.     _current_context = handle
  2014.  
  2015. def _switch_context(handle):
  2016.     "Save the current context and make another context the active one."
  2017.     global _current_context
  2018.     
  2019.     if _current_context!=None:
  2020.         _save_context(_current_context)
  2021.     _current_context = handle
  2022.     _load_context(handle)
  2023.  
  2024. def _destroy_context():
  2025.     "Destroy the current active context"
  2026.     global _contexts, _current_context
  2027.  
  2028.     handle = _current_context
  2029.     del _contexts[handle]
  2030.     _current_context = None
  2031.  
  2032. def _init_declarations():
  2033.     global _declarations
  2034.     _declarations = {RI_P:"vertex point", RI_PZ:"vertex point",
  2035.                      RI_PW:"vertex hpoint",
  2036.                      RI_N:"varying normal", RI_NP:"uniform normal",
  2037.                      RI_CS:"varying color", RI_OS:"varying color",
  2038.                      RI_S:"varying float", RI_T:"varying float",
  2039.                      RI_ST:"varying float[2]",
  2040.                      RI_ORIGIN:"integer[2]",
  2041.                      RI_KA:"uniform float",
  2042.                      RI_KD:"uniform float",
  2043.                      RI_KS:"uniform float",
  2044.                      RI_ROUGHNESS:"uniform float",
  2045.                      RI_KR:"uniform float",
  2046.                      RI_TEXTURENAME:"string",
  2047.                      RI_SPECULARCOLOR:"uniform color",
  2048.                      RI_INTENSITY:"float",
  2049.                      RI_LIGHTCOLOR:"color",
  2050.                      RI_FROM:"point",
  2051.                      RI_TO:"point",
  2052.                      RI_CONEANGLE:"float",
  2053.                      RI_CONEDELTAANGLE:"float",
  2054.                      RI_BEAMDISTRIBUTION:"float",
  2055.                      RI_AMPLITUDE:"uniform float",
  2056.                      RI_MINDISTANCE:"float",
  2057.                      RI_MAXDISTANCE:"float",
  2058.                      RI_BACKGROUND:"color",
  2059.                      RI_DISTANCE:"float",
  2060.                      RI_FOV:"float",
  2061.                      RI_WIDTH:"varying float",
  2062.                      RI_CONSTANTWIDTH:"constant float",
  2063.                      "shader":"string",
  2064.                      "archive":"string",
  2065.                      "texture":"string",
  2066.                      "procedural":"string",
  2067.                      "endofframe":"integer",
  2068.                      "sphere":"float",
  2069.                      "coordinatesystem":"string",
  2070.                      "name":"string",
  2071.                      "sense":"string"
  2072.                     }
  2073.  
  2074. def _error(code, severity, message):
  2075.     global _errorhandler, RiLastError
  2076.  
  2077.     RiLastError = code
  2078.  
  2079.     st = inspect.stack(1)
  2080.     # Search the offending Ri function in the stack...
  2081.     j=None
  2082.     for i in range(len(st)):
  2083.         if st[i][3][:2]=="Ri":
  2084.             j=i
  2085.     # No function beginning with "Ri" found? That's weird. Maybe someone
  2086.     # messed with the function names.
  2087.     if j==None:
  2088.         where=""
  2089.     else:
  2090.         # name of the Ri function
  2091.         call   = inspect.stack(0)[j][3]
  2092.         # filename and line number where the offending Ri call occured
  2093.         file   = inspect.stack(1)[j+1][1]
  2094.         line   = inspect.stack(1)[j+1][2]
  2095.         if file==None: file="?"
  2096.         where = 'In file "'+file+'", line '+`line`+' - '+call+"():\n"
  2097.  
  2098.     _errorhandler(code,severity,where+message)
  2099.  
  2100. def _seq2col(seq):
  2101.     """Convert a sequence containing a color into a string."""
  2102.     if len(seq)<_colorsamples:
  2103.         _error(RIE_INVALIDSEQLEN, RIE_ERROR, "Invalid sequence length ("+\
  2104.                `len(seq)`+" instead of "+`_colorsamples`+")")
  2105.     colseq = tuple(seq)
  2106.     return '['+string.join( map(lambda x: str(x), colseq[:_colorsamples]) )+']'
  2107.  
  2108. def _flatten(seq):
  2109.     """Return a list of the individual items in a (possibly nested) sequence.
  2110.  
  2111.     Returns a list with all items as strings.
  2112.     If an item was already a string it's enclosed in apostrophes.
  2113.     
  2114.     Example: _flatten( [(1,2,3), (4,5,6)] ) -> ["1","2","3","4","5","6"]
  2115.              _flatten( ("str1","str2") )    -> ['"str1"','"str2"']
  2116.     """
  2117.     res = []
  2118.     ScalarTypes = [types.IntType, types.LongType, types.FloatType]
  2119.     StringType = types.StringType
  2120.     for v in seq:
  2121.         vtype = type(v)
  2122.         # v=scalar?
  2123.         if vtype in ScalarTypes:
  2124.             res.append(str(v))
  2125.         # vec3?
  2126.         elif isinstance(v, _vec3):
  2127.             res.extend([str(v.x), str(v.y), str(v.z)])
  2128.         # v=string?
  2129.         elif vtype==StringType:
  2130.             res.append('"%s"'%v)
  2131.         # no scalar or string. Then it might be a sequence...
  2132.         else:
  2133.             # Check if it is really a sequence...
  2134.             try:
  2135.                 n = len(v)
  2136.             except:
  2137.                 res.append(str(v))
  2138.                 continue
  2139.             res += _flatten(v)
  2140.     return res
  2141.  
  2142. def _seq2list(seq, count=None):
  2143.     """Convert a sequence into a string.
  2144.  
  2145.     The function checks if the sequence contains count elements (unless
  2146.     count is None). If it doesn't an error is generated.
  2147.     The return value is a string containing the sequence. The string can
  2148.     be used as parameter value to RIB commands.
  2149.     """
  2150.  
  2151.     f = _flatten(seq)
  2152.     # Has the sequence an incorrect length? then generate an error
  2153.     if count!=None and len(f)!=count:
  2154.         _error(RIE_INVALIDSEQLEN, RIE_ERROR, "Invalid sequence length ("+\
  2155.                `len(f)`+" instead of "+`count`+")")
  2156.         
  2157.     return '[%s]'%" ".join(f)
  2158.  
  2159. def _paramlist2dict(paramlist, keyparams):
  2160.     """Combine the paramlists (tuple & dict) into one dict.
  2161.     
  2162.     paramlist is a tuple with function arguments (token/value pairs or
  2163.     a dictionary). keyparams is a dictionary with keyword arguments.
  2164.     The dictionary keyparams will be modified and returned.
  2165.     """
  2166.  
  2167.     if len(paramlist)==1 and type(paramlist[0])==types.DictType:
  2168.         keyparams = paramlist[0]
  2169.         paramlist = ()
  2170.     
  2171.     # Add the paramlist tuple to the keyword argument dict
  2172.     for i in range(len(paramlist)/2):
  2173.         token = paramlist[i*2]
  2174.         value = paramlist[i*2+1]
  2175.         keyparams[token]=value
  2176.  
  2177.     return keyparams
  2178.  
  2179. def _paramlist2lut(paramlist, keyparams):
  2180.     """Combine the paramlists into one dict without inline declarations.
  2181.  
  2182.     paramlist is a tuple with function arguments. keyparams is a
  2183.     dictionary with keyword arguments. The dictionary keyparams will
  2184.     be modified and returned.
  2185.  
  2186.     The resulting dictionary can be used to look up the value of tokens.
  2187.     """
  2188.     # Add the paramlist tuple to the keyword argument dict
  2189.     for i in range(len(paramlist)/2):
  2190.         token = paramlist[i*2]
  2191.         value = paramlist[i*2+1]
  2192.         # Extract the name of the token (without inline declaration
  2193.         # if there is one)
  2194.         f = token.split(" ")
  2195.         tokname = f[-1]
  2196.         keyparams[tokname]=value
  2197.  
  2198.     return keyparams
  2199.     
  2200. def _merge_paramlist(paramlist, keyparams):
  2201.     """Merge a paramlist tuple and keyparams dict into one single list.
  2202.     """
  2203.     if len(paramlist)==1 and type(paramlist[0])==types.DictType:
  2204.         keyparams = paramlist[0]
  2205.         paramlist = ()
  2206.  
  2207.     res = list(paramlist)
  2208.     # Check if the number of values is uneven (this is only allowed when
  2209.     # the last value is None (RI_NULL) in which case this last value is ignored)
  2210.     if (len(res)%2==1):
  2211.        if res[-1] is None:
  2212.            res = res[:-1]
  2213.        else:
  2214.            raise ValueError, "The parameter list must contain an even number of values" 
  2215.  
  2216.     # Append the params from the keyparams dict to the parameter list
  2217.     map(lambda param: res.extend(param), keyparams.iteritems())
  2218.     return res
  2219.     
  2220.  
  2221. def _paramlist2string(paramlist, keyparams={}):
  2222.     """Convert the paramlist into a string representation.
  2223.  
  2224.     paramlist is a tuple with function arguments (token/value pairs or
  2225.     a dictionary). keyparams is a dictionary with keyword arguments.
  2226.     Each token has to be a string, the value can be of any type. If the
  2227.     value is a string, it's enclosed in apostrophes. A trailing token
  2228.     without a value is ignored, which also means that a trailing RI_NULL
  2229.     can be passed.
  2230.     The resulting string contains a leading space, unless there are no
  2231.     token/value pairs.
  2232.     """
  2233.  
  2234.     global _declarations
  2235.  
  2236.     paramlist = _merge_paramlist(paramlist, keyparams)
  2237.  
  2238.     res=""
  2239.     for i in range(0, len(paramlist), 2):
  2240.         token = paramlist[i].strip()
  2241.         value = paramlist[i+1]
  2242.         # Extract the name of the token (without inline declaration
  2243.         # if there is one)
  2244.         f = token.split(" ")
  2245.         tokname = f[-1:][0]
  2246.         inline  = f[:-1]
  2247.  
  2248.         if not (_declarations.has_key(tokname) or inline!=[]):
  2249.             _error(RIE_UNDECLARED,RIE_ERROR,'Parameter "'+tokname+
  2250.                    '" is not declared.')
  2251.         
  2252.         # Check if the value is a sequence (if it returns an iterator)
  2253.         isseq=0
  2254.         try:
  2255.             isseq = (iter(value)!=None)
  2256.         except:
  2257.             pass
  2258.         # Convert value into the appropriate string representation
  2259.         if type(value)==types.StringType:
  2260.             value='["'+value+'"]'
  2261. #        elif type(value)==types.ListType or type(value)==types.TupleType:
  2262.         elif isseq:
  2263.             value = _seq2list(value)
  2264.         else:
  2265.             value='[%s]'%value
  2266.         res+=' "'+token+'" '+value
  2267.  
  2268.     if (res==" "): res=""
  2269.     return res
  2270.  
  2271.  
  2272. ############################################################
  2273.  
  2274. _init_declarations()
  2275.  
  2276. if __name__=='__main__':
  2277.  
  2278.     RiBegin(RI_NULL)
  2279.     RiErrorHandler(RiErrorAbort)
  2280.  
  2281.     RiWorldBegin();
  2282.  
  2283.     RiWorldEnd()
  2284.  
  2285.     RiSkew(45,0,1,0,1,0,0)
  2286.     RiSkew(45,[0,1,0],[1,0,0])
  2287.     
  2288.     RiEnd()
  2289.     
  2290.