10.2 3Delight APIs
10.2.1 The Rx API | ||
10.2.2 The Gx API | ||
10.2.3 The Sx API | ||
10.2.4 The Point Cloud API | ||
10.2.5 The Slo API | ||
10.2.6 The Rix Interface API | ||
10.2.7 The VolumeTracer API | ||
10.2.8 The interactive edit API |
10.2.1 The Rx API
The Rx library provides access to some useful internal functions to SL DSOs writers. Also, it allows RiProcedural
writers to query internal state of the renderer.
10.2.1.1 Noise functions | ||
10.2.1.2 Texture lookup functions | ||
10.2.1.3 Transformation functions | ||
10.2.1.4 Message passing and info functions | ||
10.2.1.5 File functions | ||
10.2.1.6 Example |
10.2.1.1 Noise functions
There are three noise functions. They access respectively the internal implementations of noise
, pnoise
and cellnoise
in the shading language (see section Noise and Random). They are accessible to both DSO shadeops and RiProcedural
code.
- RtInt RxNoise ( RtInt i_inDimension, RtFloat *i_in, RtInt i_outDimension, RtFloat *o_out )
- RtInt RxPNoise ( RtInt i_inDimension, RtFloat *i_in, RtFloat *i_period, RtInt i_outDimension, RtFloat *o_out )
- RtInt RxCellNoise ( RtInt i_inDimension, RtFloat *i_in, RtInt i_outDimension, RtFloat *o_out )
As input, these functions take one to four floats. The number of floats is passed by i_inDimension and the values by i_in. The expected number of dimensions as a result should be passed by i_outDimension (only one and three are accepted). It is important to provide a big enough o_out buffer to contain the output. The i_period parameter for
RxPNoise
should contain as many periods as there are input dimensions. A return value of `0' indicates a sucess.
10.2.1.2 Texture lookup functions
There are three texture lookup functions with several variants for each. They call respectively the implementations of environment
, shadow
and texture
in the shading language (see section Texture Mapping).
- RtInt RxEnvironmentPoints1 ( RtString i_fileName, RtInt i_nPoints, RtInt i_firstChannel, RtInt i_nChannels, const RtPoint *i_dir, RtFloat *o_result, ... )
- RtInt RxShadowPoints1 ( RtString i_fileName, RtInt i_nPoints, RtInt i_firstChannel, const RtPoint *i_P, RtFloat *o_result, ... )
- RtInt RxTexturePoints1 ( RtString i_fileName, RtInt i_nPoints, RtInt i_firstChannel, RtInt i_nChannels, const RtFloat *i_s, const RtFloat *i_t, RtFloat *o_result, ... )
Each function takes a texture name and an input point specifying the texture location to be sampled. When these are called over all the points being shaded at once, proper derivatives are automatically computed for smooth filtering. Otherwise, the corresponding function below is called with the same point duplicated four times (ie. no filtering). i_nChannels channels is retrieved starting at channel i_firstChannel in the texture i_fileName. Optional parameters (described in Table 6.16) provided as name-value pairs as accepted. Named parameters which are varying must be explicitely declared as such inline (eg. "varying float blur") or they will be read as uniform. All read channels are stored in o_result. These three functions also have their vector versions (
RxEnvironmentPoints1V
,RxShadowPoints1V
andRxTexturePoints1V
) which take a vector of tokens and a vector of values, similar to Ri calls. A return value of `0' indicates a sucess.
- RtInt RxEnvironmentPoints4 ( RtString i_fileName, RtInt i_nPoints, RtInt i_firstChannel, RtInt i_nChannels, const RtPoint *i_dir0, const RtPoint *i_dir1, const RtPoint *i_dir2, const RtPoint *i_dir3, RtFloat *o_result, ... )
- RtInt RxShadowPoints4 ( RtString i_fileName, RtInt i_nPoints, RtInt i_firstChannel, const RtPoint *i_P0, const RtPoint *i_P1, const RtPoint *i_P2, const RtPoint *i_P3, RtFloat *o_result, ... )
- RtInt RxTexturePoints4 ( RtString i_fileName, RtInt i_nPoints, RtInt i_firstChannel, RtInt i_nChannels, const RtFloat *i_s0, const RtFloat *i_t0, const RtFloat *i_s1, const RtFloat *i_t1, const RtFloat *i_s2, const RtFloat *i_t2, const RtFloat *i_s3, const RtFloat *i_t3, RtFloat *o_result, ... )
These functions are the same as the previous three except that they take four points to explicitely specify the filtering area.
- RtInt RxEnvironment ( RtString i_fileName, RtInt i_firstChannel, RtInt i_nChannels, RtPoint i_dir0, RtPoint i_dir1, RtPoint i_dir2, RtPoint i_dir3, RtFloat *o_result, ... )
- RtInt RxShadow ( RtString i_fileName, RtInt i_firstChannel, RtPoint i_P0, RtPoint i_P1, RtPoint i_P2, RtPoint i_P3, RtFloat *o_result, ... )
- RtInt RxTexture (RtString i_fileName, RtInt i_firstChannel, RtInt i_nChannels, RtFloat i_s0, RtFloat i_t0, RtFloat i_s1, RtFloat i_t1, RtFloat i_s2, RtFloat i_t2, RtFloat i_s3, RtFloat i_t3, RtFloat *o_result, ... )
These functions perform a single lookup at a time and do not provide automatic derivatives. They are present for compatibility and should not be used in new code when there are several lookups to perform. Using the Points version instead.
10.2.1.3 Transformation functions
There is a single space transformation function: RxTransformPoints
. It looks a lot like the transform
shadeop in the shading language (Geometry, Matrices and Colors), except that it passes an array of points to transform and accepts a time parameter (useful with motion blurred geometry). There is also RxTransform
which allows a transformation matrix to be retrieved without actually transforming anything.
- RtInt RxTransformPoints ( RtToken i_fromspace, RtToken i_tospace, RtInt i_n, RtPoint io_p[], RtFloat i_time )
The points in io_p are transformed from i_fromspace to i_tospace, at time i_time. If there is some motion blur and i_time is somewhere inside the shutter time interval, the transformation interpolates points between the two enclosing time steps. A return value of `0' means success.
- RtInt RxTransform ( RtToken i_fromspace, RtToken i_tospace, RtFloat i_time, RtMatrix o_matrix )
Computes, in o_matrix, the matrix to transform points from i_fromspace to i_tospace at time i_time. A return value of `0' means success.
10.2.1.4 Message passing and info functions
These functions access state and general information. They are respectively the equivalent of attribute()
, option()
, rendererinfo()
and textureinfo()
shadeops in the shading language (see section Message Passing and Information).
- RtInt RxAttribute ( RtString i_name, RtPointer o_result, RtInt i_resultLen, RxInfoType_t *o_resulttype, RtInt *o_resultcount )
- RtInt RxOption ( RtString i_name, RtPointer o_result, RtInt i_resultLen, RxInfoType_t *o_resulttype, RtInt *o_resultcount)
- RtInt RxRendererInfo ( RtString i_name, RtPointer o_result, RtInt i_resultLen, RxInfoType_t *o_resulttype, RtInt *o_resultcount)
- RtInt RxTextureInfo ( RtString i_texture, RtString i_name, RtPointer o_result, RtInt i_resultLen, RxInfoType_t *o_resulttype, RtInt *o_resultcount)
The information i_name is retrieved and stored into o_result, which has a size of at least i_resultLen in bytes. The type is returned in o_resulttype and the number of base elements (of type RtString or RtFloat) contained in o_result is stored in o_resultcount. These two values may be useful for user defined attributes or options. For
RxAttribute
andRxOption
, a return value N > 0 indicates that the call failed due to a too small buffer (N indicating the number of missing bytes). In this case, take a look at o_resulttype and o_resultcount for more explanations. A return value of 0 indicates a success. A negative return value indicates an error.
10.2.1.5 File functions
- RtString RxCacheFile ( RtString i_filename )
This function allows access to 3Delight's network cache (see section Network Cache). When the network cache is enabled, the given file is cached and a path to the cached file is returned. If caching fails, is disabled or is not required, i_filename is returned. This function is useful when the caching of extra resources is necessary due to excessive network loads. Example resources that could benefit from caching:
- Scene data. Such as Maya scene files or specific custom DSO data.
- Executables. Executing files through the network is a non negligible part of the total network traffic.
Note that 3DELIGHT already caches RIB archives so caching them using this call is not a good idea.
- RtString RxFindFile ( RtString i_category, RtString i_filename )
This function allows access to 3Delight's searchpath system. It will look for the requested file in the searchpaths of the given category (as given by the "searchpath" option). It will also apply any required directory mapping (see section Search Paths Options).
10.2.1.6 Example
Here is a simple example of a DSO using the RxTexture
function. Note that the `rx.h' file is included instead of the `ri.h' file.
#include "shadeop.h" #include "rx.h" /* A simple DSO shadeop using the Rx Library Notes that 'extern "C"' is not necessary for '.c' files. Only c++ files need that. */ extern "C" { SHADEOP_TABLE(rxTexture) = { {"color rxTexture(string, float, float, float, float, float, " "float, float, float, float)", "rx_init", "rx_cleanup"}, {""} }; } extern "C" SHADEOP_INIT(rx_init) { return 0x0; /* No init data */ } extern "C" SHADEOP_CLEANUP(rx_cleanup) { /* Nothing to do */ } /* Given a texture file, texture coordinates and a width, return texture color using a gaussian filter. Note that the filename in argv[1] is a pointer of a string. */ extern "C" SHADEOP(rxTexture) { RtString filter = "gaussian"; return RxTexture( *((RtString *)argv[1]), 0, 3, *((RtFloat *) argv[2]), *((RtFloat *) argv[3]), *((RtFloat *) argv[4]), *((RtFloat *) argv[5]), *((RtFloat *) argv[6]), *((RtFloat *) argv[7]), *((RtFloat *) argv[8]), *((RtFloat *) argv[9]), (RtFloat *) argv[0], "width", (RtFloat*)argv[10], "filter", &filter, 0); }
The DSO has to be compiled with the `-shared' flag activated, as shown below for each platform:
- Linux
g++ -shared -o rxexample.so -I$DELIGHT/include rxexample.cpp
- MacOS X
g++ -dynamiclib -o rxexample.dylib -I$DELIGHT/include rxexample.cpp
- Windows
cl -I"%DELIGHT%/include" "%DELIGHT%/lib/3delight.lib" -LD rxexample.cpp
10.2.2 The Gx API
This API allows the evaluation of RenderMan geometry. The design principal is to provide the user with an interface that is easy to use and coherent with the rest of the RenderMan protocol. All geometry types that are supported by 3Delight can be evaluated using this API, this includes: subdivision surfaces (including hierarchical subdivision surfaces), polygons, NURBS, conics, ... Etc. To use the interface one must include the `gx.h' header file.
10.2.2.1 Entry Points | ||
10.2.2.2 Example Usage |
10.2.2.1 Entry Points
- GxGeometryHandle GxGetGeometry ( RtObjectHandle i_object, ... )
- GxGeometryHandle GxGetGeometryV ( RtObjectHandle i_object,
RtInt i_n, RtToken i_tokens[], RtPointer i_params[] );
Prepares a stored object for processing with this API. The object must be declared using a
RiObjectBegin
/RiObjectEnd
block. The i_object parameter is the one returned byRiObjectBegin
.
- void GxFreeGeometry ( GxGeometryHandle i_geo )
Release memory and resources that have been allocated by
GxGetGeometry
. This should be done when the object and all the other resources derived from it will no longer be used.
- unsigned GxGetFaceCount ( GxGeometryHandle i_geo )
Returns the number of faces for a given piece of geometry. This can be different from what is specified through the RI interface as 3Delight may transform some types of geometry into a different internal representation.
- int GxCreateSurfacePoint ( GxGeometryHandle i_geo, unsigned i_face, float i_u, float i_v, float i_time, GxSurfacePoint *o_point )
Initializes a surface point handle directly with a face number of parametric coordinates on the face. Parameters are:
- i_geo
- The geometry to evaluate.
- i_face
- The face number. Must be in the [0 .. GxGetFaceCount(i_geo)[ range.
- u
- v
- The parametric coordinates on the face (local to the face).
- i_time
- Time. Currently unimplemented(71).
- o_point
- A pointer to the handle to be initialized. The initialized handle must be cleaned up with
FreeSurfacePoint
or resources will leak.
Possible return values all:
RIE_NOERROR
- Everything went well.
RIE_RANGE
- Invalid face id.
RIE_BADHANDLE
- Invalid i_geo.
- void GxFreeSurfacePoint ( GxSurfacePoint i_point )
Releases the memory associated with a surface point handle that was previously allocated by
GxCreateSurfacePoint
.
- int GxEvaluateSurface ( unsigned i_npoints, GxSurfacePoint *i_points, RtToken i_variable, unsigned i_width, float *o_values )
Evaluates a primitive variable at the given surface points.
- i_npoints
- Length of the i_points array.
- i_points
- A pre-allocated array of
GxSurfacePoint
s. - i_variable
- The name of the primitive variable to evaluate (eg. "P"). Any primitive variable that is attached to the geometry can be evaluated using this function. Note that "dPdu", "dPdv", "N" and "Ng" can always be passed to this function (these variables are inherent to the geometry and don't have to be passed as a primitive variable).
- i_width
- The number of components of i_variable (eg. 3 for "P").
- o_values
- A buffer to receive the results. This should be i_npoints * i_width long.
Possible return values are:
RIE_NOERROR
- Everything went well.
RIE_BADHANDLE
- At least one the the evaluation points is invalid.
RIE_MISSINGDATA
- The provided token (i_varibale) cannot be found in the geometry.
RIE_CONSISTENCY
- i_width is not equal to the with of the primitive variable declared in the geometry.
RIE_BADTOKEN
- i_variable is of type
RtString
so it cannot be evaluated.
10.2.2.2 Example Usage
A complete example can be found in `$DELIGHT/examples/gx'. The directory contains code for a procedural that transforms RenderMan geometry into particles. To run the example of a Linux or Mac OS X system, open a shell and execute the following commands:
cd $DELIGHT/examples/gx make
A framebuffer should popup and some primtives will be rendered as points. The primitives are all described in `points.rib'.
10.2.3 The Sx API
This API allows the evaluation of RenderMan shaders on arbitrary user data. The API doesn't expect any scene description so its usable from a variety of contexts. Usage examples include:
- Evaluation of displacement shaders in animation packages to correctly place fur and hair on a displaced surface.
- Evaluation of RenderMan shaders on object vertices for a rough preview of RenderMan shaders in an animation package.
- Using the library to access the high quality and efficient texturing mapping shadeops.
- Using the library to design other libraries which take RenderMan shaders as inputs. This is well illustrated by the "VolumeTracer" API (see section The VolumeTracer API).
The library operates in SIMD so many points can be evaluated at once.
10.2.3.1 Entry Points | ||
10.2.3.2 Example Usage |
10.2.3.1 Entry Points
- SxContext SxCreateContext ( SxContext i_parent = 0 )
Creates a shader evaluation context.
- i_parent
- Specifies the parent context.
- void SxSetOption ( SxContext i_context, const char* i_optionName, SxType i_optionType, SxData i_values, unsigned i_arraySize )
- void SxSetAttribute ( SxContext i_context, const char* i_optionName, SxType i_optionType, SxData i_values, unsigned i_arraySize )
Sets a rendering option or attribute in the given context. All options are accessible from inside the shader through the
option()
andattribute()
shadeops (see section Message Passing and Information). This is similar in spirit to theRiOption
andRiAttribute
RenderMan commands.- i_context
- The
SxContext
as returned bySxCreateContext()
. - i_optionType
- Type of the option.
- i_values
- Pointer to the actual values.
- i_arraySize
- Total number of elements in the array (0 if the variable is not an array).
Note that all options are uniform.
- void SxDefineSpace ( SxContext i_context, const char* i_spaceName, float *i_matrix )
Binds a matrix to the specified space in the specified context. Any name can be specify except `current' which is reserved by this library. This function must be called before
SxCreateShader
for each space of interest for the new shader.
- SxParameterList SxCreateParameterList ( SxContext i_context, unsigned i_numPoints, const char* i_spaceName )
Creates a parameter list for use in either intializing a shader instance or running a shader on a set of points. i_numPoints specifies the number of values for varying parameters when evaluating the shader. If the list is used to create a shader then this should be 1 as only the first value is use to set the shader's intance parameters. The optional i_spaceName indicates the space in which the parameters are declared (this matters in case of points, vectors, normals and matrices). It defaults to "shader" if the list is used to create a new shader and "current" if it is used to evaluate a shader. The parameter list will be automatically freed when the context specified by i_context is destroyed. However,
SxDestroyParameterList()
may also be used to destroy the parameter list earlier. This is mostly useful for the list passed toSxCallShader()
.
- void SxSetParameterListGridTopology ( SxParameterList i_paramList, unsigned i_numGrids, const unsigned *i_uRes, const unsigned *i_vRes )
Sets a parameter list to be interpreted as grids instead of independent points. i_uRes and i_vRes are two arrays of i_numGrids values which specify the number of points of each grid in both axis. Using this function affects the behavior of area and filtered functions in the shader.
- void SxSetPredefinedParameter ( SxParameterList i_paramList, const char* i_predefParamName, SxData i_values, bool i_varying = true )
Sets (or adds) a predefined variable to the specified parameter list. Predefined parameters are P, u, v, etc ...
- i_paramList
- Specified parameter list
- i_predefParamName
- Predefined variable's name
- i_values
- Predefined variable's values
- i_varying
- Predefined variable's class (optional). True for varying, false for uniform.
- void SxDestroyParameterList ( SxParameterList i_parameterList )
Destroys a previous constructed parameter lists.
- SxShader SxCreateShader ( SxContext i_context, SxParameterList i_paramList, const char *i_shaderName, const char *i_shaderHandle )
Creates a shader in the specified context.
- i_context
- The context where the shader is created and to which it will belong.
- i_paramList
- The parameter list which contains the shader instance parameter values. These are the values which will not change for different calls to the shader. This parameter may be null if no list is needed.
- i_shaderName
- The name of the shader file to load (without the .sdl part).
- i_shaderHandle
- The name by which the shader will be referenced. This should be null for shaders which you do not intend to use as co-shaders.
- unsigned SxGetNumParameters ( SxShader i_shader )
Returns the number of parameters declared for the specified shader.
- unsigned SxGetPredefinedParameters ( SxShader i_shader, const char* o_names[], unsigned i_maxNames )
Returns the number of predefined parameters needed by i_shader and fills o_names with pointers to their names.
- i_shader
- The shader of interest.
- o_names
- An array that will be filled with the parameters' names. May be
null
when i_maxNames is set to0
. - i_maxNames
- The maximum number of strings that can be written to o_names. It can be useful to set this parameter to
0
when only the number of predefined parameters (and not their names) is needed.
- const char* SxGetParameterInfo ( SxShader i_shader, unsigned i_index, SxType* o_type, bool* o_varying, SxData* o_defValues, unsigned * o_arraySize, const char** o_spaceName = 0, bool* o_output = 0 )
Returns parameter's name and all information about the parameter which matches the specified index for the specified shader.
- i_shader
- The shader of interest.
- i_index
- Specified index
- o_type
- Parameter's type (would be one of SxFloat, SxPoint, SxColor, SxString, SxMatrix, SxVector or SxNormal).
- o_varying
- Parameter's class (would be true for varying, false for uniform).
- o_defValues
- Parameter's default values.
- o_arraySize
- Parameter's array size. Would be 0 if not an array.
- o_spaceName
- Parameter's space for the default value (optional).
- o_output
- Parameter's output state (optional). Would be true for output, false otherwise.
- unsigned SxGetParameter ( SxParameterList i_paramList, const char* i_paramName, SxData* o_values )
Returns the number of values associated with the specified output variable.
- i_paramList
- The parameter list from which to retrieve values. Normally this will be a list which was passed to SxCallShader.
- i_paramName
- Variable's name.
- o_values
- Values of the predefined or output variable.
- bool SxCallShader ( SxShader i_shader, SxParameterList i_paramList )
Calls (executes) a shader.
- i_shader
- Shader to evaluate.
- i_paramList
- Parameter list to use (created by
SxcreateParameterList
).
Result of the evaluation can be queried using the
SxGetParameter()
function on i_paramList. The shader is run with the lights and co-shaders which were created in the same Sx context. Any light shader created is added to the active light list and any shader created with a non null handle name is added to the co-shaders list.
10.2.3.2 Example Usage
10.2.4 The Point Cloud API
10.2.4.1 Point Cloud API Data Types | ||
10.2.4.2 Point Cloud Reading | ||
10.2.4.3 Point Cloud Writing | ||
10.2.4.4 API Example |
An easy to use C++
API is provided with 3Delight to read and write point cloud files as those generated by the bake3d()
shadeop.
To use the API, one has to include the `pointcloud.h' header file that is distributed in the package and link the application with the 3Delight library (see section Linking with 3Delight).
10.2.4.1 Point Cloud API Data Types
Only one type is defined in `pointcloud.h'
typedef void * PtcPointCloud
This typedef
is used as a handle to a point cloud file on disk.
10.2.4.2 Point Cloud Reading
- PtcPointCloud PtcSafeOpenPointCloudFile ( const char *filename )
This function opens a given file for reading and returns a file handle than shall be used in other reading calls.
- PtcPointCloud PtcOpenPointCloudFile ( const char *filename, int *nvars, const char **vartypes, const char **varnames )
This function opens a given file for reading and returns a file handle than shall be used in other reading calls.
- filename
- The complete path to the point cloud file
- nvars
- A pointer to an
int
that will be filled with the total number of channels in the point cloud file. - varnames
- A pointer to an array of
const char *
that will hold the name of each variable. - vartypes
- A pointer to an array of
const char *
that will hold the type of each variable. Types are string representing the type of the variable as declared in the shading language (color, point, float, normal, … etc).
This function could fail if the file is not accessible or is not a valid point cloud file, in which case
null
is returned. Data allocated by this function is managed by the library and not user intervention is necessary to deallocate it.NOTE
This API call is badly designed since the caller cannot know the size of vartypes and varnames in advance. But for compatibly reasons with other software we decided to provide this API entry. A safe way to open a point-cloud file is to call
PtcSafeOpenPointCloudFile()
and then callPtcGetPointCloudInfo()
to get nvars, varnames and vartypes.
- int PtcGetPointCloudInfo ( PtcPointCloud pointcloud, const char *request, void *result )
This function returns informations about a point cloud file. Accepted requests are:
- pointcloud
- A handle to the point cloud file as returned by
PtcOpenPointCloudFile
- request
- The name of the information needed. The following requests are accepted:
- ` npoints'
- Number of points in the point cloud file. C++ data type is
int
- ` bbox'
- The bounding box of the point cloud. Will return an array of six floats: min x, min y, min z, max x, max y and max z.
- ` datasize'
- ` pointdatasize'
- The number of
float
s needed to store each data point. C++ data type isint
. - ` world2eye'
- The world to eye (world to camera) transformation matrix. Will return an array of 16
float
s. - ` world2ndc'
- The world to NDC transformation matrix. Will return an array of 16
float
s. - ` format'
- The resolution of the render that generated the point cloud file. Three
float
s will be returned: x resolution, y resolution and aspect ratio. - ` nvars'
- Total number of variables attached to each point. In this case, result is considered to be of type
int *
. - ` varnames'
- ` pointvarnames'
- The name of each variable. In this case, result is considered to be of type
char **
. - ` vartypes'
- ` pointvartypes'
- The type of each variable. In this case, result is considered to be of type
char **
.
- result
- A pointer to an array large enough to hold the returned informations.
Returns 1 if the request is successful, 0 otherwise.
NOTE
Some point cloud files generated with older 3Delight versions may not contain the `format' information.
- int PtcReadDataPoint ( PtcPointCloud pointcloud, float *point, float *normal, float *radius, float *user_data )
Reads next point from the point cloud file. The parameters are:
- pointcloud
- The handle to the point cloud file as returned by
PtcOpenPointCloudFile
. - point
- A pointer to a point (three floats) that will be filled with current point's position.
- normal
- A pointer to a point (three floats) that will be filled with current point's normal.
- radius
- A pointer to float that will be filled with point's radius. The area of the micro-polygon that generated this sample is radius * radius * PI.
- user_data
- A pointer to a user buffer of a size big enough to hold all the variables attached to a point. The size of the buffer, in
float
s, can be obtained by callingPtcGetPointCloudInfo
with request set to `datasize'.
Returns 1 if the operation is successful, 0 otherwise.
NOTE
point, normal, radius and user_data can be null if their value is not neede.
- void PtcClosePointCloudFile ( PtcPointCloud pointcloud )
Closes a file opened with
PtcOpenPointCloudFile
. This function releases all memory allocated byPtcOpenPointCloudFile
.
10.2.4.3 Point Cloud Writing
- PtcPointCloud PtcCreatePointCloudFile ( const char *filename, int nvars, const char **vartypes, const char **varnames, float *world2eye, float *world2ndc, float *format)
Creates the specified point cloud file. If the point cloud file already exists, it will be overwritten.
- filename
- Complete path to point cloud file.
- nvars
- Number of variables to save in the point cloud.
- vartype
- A type for each variable. Types are the same as in the shading language: point, normal, color, float, matrix ... Etc.
- varname
- A name for each variable.
- world2eye
- A world to camera transformation matrix.
- world2ndc
- A world to NDC transformation matrix.
- format
- The X resolution, Y resolution and aspect ratio of the image.
- int PtcWriteDataPoint ( PtcPointCloud pointcloud, float *point, float *normal, float radius, float *data)
Adds a point, along with its data, to a point cloud file.
- pointcloud
- A handle to a point cloud file as returned by
PtcCreatePointCloudFile
. - point
- normal
- radius
- Position, orientation and radius of the point and data. point and normal cannot be null.
- data
- Array of floats containing data for all variables, continuously in memory. The data must be of the same size as the sum of sizes of the variables passed to
PtcCreatePointCloudFile
.
Returns 1 if the operation is successful, 0 otherwise.
- void PtcFinishPointCloudFile ( PtcPointCloud pointcloud)
Writes out all data to disk and closes the file.
10.2.4.4 API Example
An example is available in `$DELIGHT/examples/ptc2rib' directory. This simple application transforms a point cloud file into a RIB that is renderable using renderdl
. An example usage is:
ptc2rib cloud.ptc | renderdl -d
10.2.5 The Slo API
Shader interrogation is possible by using the shaderinfo
command line tool (see section Using shaderinfo
to Interrogate Shaders). It is also possible to "manually" interrogate shaders by using a number of calls implemented in `lib3delight'. The interrogating application should include `slo.h' (found in `$DELIGHT/include') and link with `lib3delight' (see section Linking with 3Delight).
Here is the complete list for shader interrogation calls:
- void Slo_SetPath ( char* i_path )
Set the paths where the library looks for shaders. It accepts a colon separated list of paths. Refer to Search Paths Options for more information on search paths which also applies to this function.
- int Slo_SetShader ( char* i_name )
Find and open the shader named i_name. Close any shader that was previously opened by
Slo_SetShader
. Returns 0 when the shader was successfully loaded.
- SLO_TYPE Slo_GetType ( void )
Return the type of the currently opened shader. See the file `slo.h' for details about
SLO_TYPE
.
- SLO_VISSYMDEF* Slo_GetArgById ( int i )
Return information about the i-th parameter of the shader. The first parameter has an id of 1. See `slo.h' for details about
SLO_VISSYMDEF
structure.
- SLO_VISSYMDEF* Slo_GetArgByName ( char *i_name )
Return information about the parameter named i_name. See the file `slo.h' for details about
SLO_VISSYMDEF
.
- SLO_VISSYMDEF* Slo_GetArrayArgElement ( SLO_VISSYMDEF *i_array, int i_index )
If a parameter is an array (as specified by
Slo_GetArgById()
orSlo_GetArgByName
), each of its element should be accessed using this function.
- int Slo_GetNAnnotations ( void )
Return the number of annotations contained in this shader. Annotations are further discussed in Attaching annotations to shaders.
- char* Slo_GetAnnotationKeyById ( int i_id )
Returns an annotation key by it's index i_id. Acceptable indexes range from 1 to n, where n is the number of annotations available. Any index outside this range returns 0x0 (null pointer).
- char* Slo_GetAnnotationByKey ( const char *i_key )
Returns an annotation specified by it's key. If i_key doesn't refer to any annotation, 0 (null pointer) is returned. It is possible to retrieve the different possible keys with
Slo_GetAnnotationKeyById
.
- char* Slo_StortoStr ( SLO_STORAGE i_storage )
Get a string representation of storage class i_storage.
- char* Slo_DetailtoStr ( SLO_DETAIL i_detail )
Get a string representation of variable detail i_detail.
- const char*const* Slo_GetMethodNames ( )
Returns a null terminated array of strings containing the names of the methods in the current shader.
Next is the complete source code of the shaderinfo
utility, it is compilable on all supported platforms, see Linking with 3Delight.
/******************************************************************************/ /* */ /* Copyright (c)The 3Delight Team. */ /* All Rights Reserved. */ /* */ /******************************************************************************/ // =========================================================================== // = VERSION // $Revision$ // = DATE RELEASED // $Date$ // = RCSID // $Id$ // =========================================================================== #include "slo.h" #include "dlMsgShaderInfo.h" #include "dlVersion.h" #include <string.h> #include <stdlib.h> #include <stdio.h> #include <assert.h> typedef enum { e_prman = 1, e_ribout, e_table, e_source, e_annotations, e_methods } Format; void PrintDefaultValue( const SLO_VISSYMDEF* arg ) { switch(arg->svd_type) { case SLO_TYPE_SCALAR: printf( "%g", *arg->svd_default.scalarval ); break; case SLO_TYPE_STRING: printf( "%s", arg->svd_default.stringval ); break; case SLO_TYPE_POINT: case SLO_TYPE_COLOR: case SLO_TYPE_VECTOR: case SLO_TYPE_NORMAL: printf( "%g %g %g", arg->svd_default.pointval->xval, arg->svd_default.pointval->yval, arg->svd_default.pointval->zval ); break; case SLO_TYPE_MATRIX: { unsigned i=0; for( ; i < 15; ++i ) printf( "%g ", arg->svd_default.matrixval[i] ); printf( "%g", arg->svd_default.matrixval[i] ); break; } case SLO_TYPE_SHADER: printf( "nil" ); break; default: ; } } /* Function to print one parameter. */ void PrintOneParameter( const SLO_VISSYMDEF *parameter, const Format i_format ) { const char *storage = Slo_StortoStr( parameter->svd_storage ); const char *name = parameter->svd_name; const char *detail = Slo_DetailtoStr( parameter->svd_detail ); const char *type = Slo_TypetoStr( parameter->svd_type ); unsigned arraylen = parameter->svd_arraylen; bool is_array = parameter->svd_isarray; if( i_format == e_ribout ) { /* Output a string suitable for RIB syntax */ if( !is_array ) printf( "Declare \"%s\" \"%s %s\"\n", name, detail, type ); else printf( "Declare \"%s\" \"%s %s[%d]\"\n", name, detail, type, arraylen ); return; } else if( i_format == e_table ) { printf( "%s,%s,%s,%s,%s,%d,", name, storage, detail, type, parameter->svd_spacename[0] ? parameter->svd_spacename : "<none>", arraylen ); /* Print all default values */ if( !is_array ) { PrintDefaultValue( parameter ); } else { for( int i = 0; i < parameter->svd_arraylen; i++ ) { if( i != 0 ) { printf( " " ); } PrintDefaultValue( Slo_GetArrayArgElement((SLO_VISSYMDEF *)parameter, i) ); } } printf( "\n" ); return; } assert( i_format == e_prman ); printf( " \"%s\" \"%s %s %s", name, storage, detail, type ); if( is_array ) { if( arraylen == 0 ) printf( "[]" ); else printf( "[%d]", arraylen ); } printf( "\"\n" ); printf( "\t\t%s", DlGetText(DlText_1725_default) ); switch( parameter->svd_type ) { case SLO_TYPE_COLOR: // Even if color has a different spacename, // it has been converted by evaluation. printf( "\"rgb\" "); break; case SLO_TYPE_POINT: case SLO_TYPE_VECTOR: case SLO_TYPE_NORMAL: case SLO_TYPE_MATRIX: if( parameter->svd_spacename[0] != (char)0 ) printf( "\"%s\" ", parameter->svd_spacename ); break; default: break; } if( is_array ) { printf( "{" ); } int num_elements = is_array ? arraylen : 1; for( int k=0; k<num_elements; k++ ) { const SLO_VISSYMDEF *elem = Slo_GetArrayArgElement( (SLO_VISSYMDEF *)parameter, k ); if( !elem ) { printf( "<error>" ); continue; } switch( parameter->svd_type ) { case SLO_TYPE_SCALAR: printf( "%g", *elem->svd_default.scalarval ); break; case SLO_TYPE_POINT: case SLO_TYPE_VECTOR: case SLO_TYPE_NORMAL: case SLO_TYPE_COLOR: printf( "[%g %g %g]", elem->svd_default.pointval->xval, elem->svd_default.pointval->yval, elem->svd_default.pointval->zval ); break; case SLO_TYPE_MATRIX: printf( "[%g ", elem->svd_default.matrixval[0] ); for( int kk = 1; kk < 15; kk++ ) printf( "%g ", elem->svd_default.matrixval[kk] ); printf( "%g]", elem->svd_default.matrixval[15] ); break; case SLO_TYPE_STRING: printf( "\"%s\"", elem->svd_default.stringval ); break; case SLO_TYPE_SHADER: printf( "null" ); break; default: break; } if( k != (num_elements-1) ) { printf( ", " ); } } if( is_array ) printf( "}" ); printf( "\n" ); } void printArgs( const Format i_format ) { if( i_format == e_table ) { printf( "%d\n", Slo_GetNArgs() ); } for( int j = 0; j < Slo_GetNArgs(); j++ ) { SLO_VISSYMDEF *parameter = Slo_GetArgById( j+1 ); if( !parameter ) { fprintf( stderr, DlGetText(DlText_2259_param), j ); continue; } PrintOneParameter( parameter, i_format ); } if( i_format == e_prman ) { printf( "\n" ); } } int main( int argc, char ** argv ) { int i; int exitCode = 0; Format format = e_prman; int start = 1; /* DlDebug::InitErrorSignalsHandling(); */ if ( argc <= 1 || !strcmp(argv[1], "-h") || !strcmp(argv[1], "--help") ) { printf( "Usage: shaderinfo [<option>] [file1 ... fileN]\n" "Options\n" " -d : Outputs declarations in RIB format\n" " -t : Outputs declarations in parsable table format\n" " -a : Outputs available annotation keys\n" " --source : Outputs shader's source (if embedded)\n" " --methods : Outputs shader's methods\n" " -v : Shows version to console\n" " --version : Same as -v\n" " -h : Shows this help\n\n" "Notes:\n" "- No arguments is the equivalent of passing -h\n" "- All options are exclusive. Use no more than one\n" "- The options -h, -v, and --version should not be used with shader names\n" ); return 0; } if( argc == 2 && (!strcmp(argv[1], "-v") || !strcmp(argv[1], "--version")) ) { const char* v = DlGetVersionString(); const char* copyright = DlGetCopyrightString(); fprintf(stderr, "shaderinfo version %s.\n%s\n", v, copyright); return 0; } if ( argc == 1 ) { start++; } else if (!strcmp(argv[1], "-d")) { format = e_ribout; start++; } else if( !strcmp(argv[1], "-t") ) { format = e_table; start++; } else if (!strcmp(argv[1], "-a")) { format = e_annotations; start++; } else if (!strcmp(argv[1], "-source") || !strcmp(argv[1], "--source") ) { format = e_source; start ++; } else if (!strcmp(argv[1], "--methods") ) { format = e_methods; start ++; } /* Add '.' to the default path so shaders are still found in the current directory even if the default path is modified not to include '.' */ Slo_SetPath( ".:@" ); for( i = start; i < argc; i++ ) { int err = Slo_SetShader( argv[i] ); if( err != 0 ) { fprintf( stderr, DlGetText(DlText_2260_open), argv[i], err ); exitCode = 1; continue; } /* Print a header indicating which shader this is */ if( format == e_table ) { printf( "%s\n%s\n", Slo_GetName(), Slo_TypetoStr(Slo_GetType()) ); } else if( format == e_prman ) { printf( "\n%s \"%s\"\n", Slo_TypetoStr(Slo_GetType()), Slo_GetName() ); } else if( format == e_methods ) { /* PrMan doesn't seem to print a header in --methods mode. */ } else if( format == e_source ) { /* We want the source that is output directly compilable. So we don't want the name the shader in the listing. */ } else { printf( "%s %s\n", Slo_TypetoStr(Slo_GetType()), Slo_GetName() ); } if( format == e_annotations ) { if( Slo_GetNAnnotations() == 0 ) { fprintf( stderr, DlGetText(DlText_2261_nokey), argv[i] ); continue; } printf( "%d\n", Slo_GetNAnnotations() ); for( int id=0; id<Slo_GetNAnnotations(); id++ ) { const char *key = Slo_GetAnnotationKeyById( id+1 ); if( !key ) { assert( false ); fprintf(stderr, DlGetText(DlText_1727_nokey), id, argv[i]); return 1; } const char *annotation = Slo_GetAnnotationByKey(key); printf( "\"%s\" \"%s\"\n", key, annotation ); } } else if ( format == e_source ) { const char *value = Slo_GetAnnotationByKey( "source" ); if( value ) { printf( "%s\n", value ); } else { fprintf( stderr, DlGetText(DlText_1796_no_source) ); } } else if ( format == e_methods ) { const char *const *method_names = Slo_GetMethodNames(); while( *method_names ) { printf( "%s\n", *method_names ); method_names ++; } } else { printArgs( format ); } Slo_EndShader(); } return exitCode; }
10.2.6 The Rix Interface API
The "Rix" API is a collection of classes giving access to useful methods. These classes and methods can be used from inside RSL plug-ins for example (see section RSL Plug-ins). All classes are declared in file `$DELIGHT/include/RixInterface.h' and are further described in the following sections.
The RixContext
class
All Rix Interface class live in a Rix Context. The only useful method in this class is GetRixInterface
.
- RixInterface* RixContext::GetRixInterface ( RixInterfaceID i_id )
This method constructs and returns the Rix Interface specified by i_id. The i_id variable can take one of the following values:
k_RixThreadUtils
k_RixMessages
k_RixStats
k_RixThreadData
k_RixLocalData
k_RixGlobalTokenData
- Returns an instance of the corresponding class (
RixThreadutils
,RixMessages
,RixThreadData
, etc...).
This method returns a pointer to
RxInterface
that needs to be cast into the appropriate class. For example:/* Get a context */ RixContext *context = RxGetRixContext(); RixMessage *error_handler = (RixMessages*) context->GetRixInterface( k_RixMessages ); error_handler->Info( "This is an example" );
The RixInterface
class
This is the base class for all other Rix
classes. There is no particular functionality provided by this class apart from returning the version of the API and being the base type returned by GetRixInterface
.
The RixStorage
class
This class provides data storage and retrieval methods. Data is associated with a key and is accessible across plug-in boundaries when retrieved with the same key. Such a class is created through a RixContext
object and can return local, global or thread-local data. For example:
RixContext *context = RxGetRixContext( ); RixStorate *thread_storage = (RixStorage *)context->GetRixInterface( k_RixThreadData ); thread->storage->Set( "example", somedata );
- void* RixStorage::Get ( const char *i_key )
Returns the data associated with the give key.
NULL
is returned if there is no data attached to the given key.
- void* RixStorage::Set ( const char *i_key, void *i_data, RixCleanupFunction i_clean = NULL )
Sets the data associated with the given key. If the key has associated data, it will be cleared and it associated cleanup function will be called (if provided with the previous
Set
function).
- void RixStorage::Lock ( )
- void RixStorage::Unlock ( )
Lock or unlocks this object. Only necessary when accessing global storage.
The RixThreadUtils
class
This class provides access to thread related methods. As of now, only one method is accessible to provide a mutex object.
- RiMutex RixThreadUtils::NewMutex ( ) const
Returns a RiMutex object. Mutexes are necessary to serialize concurrent access to globally memory. Please refer to The RiMutex class for more information. All mutex objects allocated using this method must be de-allocated using the
delete
operator.
The RixMessage
class
Provides functions to print messages using 3Delight's error handler.
The RiMutex
class
A cross-platform locking mechanism is provided through this class.
10.2.7 The VolumeTracer API
This API provides functions to trace rays in a voxel grid as suitable for volume rendering. It is available through a RSL plug-in so it is callable from inside regular RenderMan shaders. In summary, the VolumeTracer API allows a shader to:
- Manage a voxel grid. The voxel grid contains a certain number of attributes at each grid vertex. Those attributes are grouped into categories, each categories being computed by a RSL shader.
- Trace a bundle of rays in the voxel grid, in SIMD, and retrieve the values of all defined attributes at current ray position, computed using the indicated interpolation mode.
These provided functionalities make it easy to write efficient volume shaders without hassle.
10.2.7.1 Working Principles | ||
10.2.7.2 Entry Points | ||
10.2.7.3 Usage Example |
10.2.7.1 Working Principles
To use the library one has to write at least two RenderMan shaders:
- A classical ray-marching volume shader that uses the provided calls to trace rays, in SIMD, through 3D space.
- A small shader that returns the volume attributes (there can be many) at any position in the volume. In practice, this shader will be called to query volume quantities at each grid vertex. Most commonly, this shader would return the density of the volume but other usages are of course possible. The name of this shader is provided to the initialization function of API (see section Entry Points) and is handled by the plug-in(72). It must have a single output parameter : an array of floats. Any number of input parameters are allowed and can be initialized when creating the grid (usually to provide the name of a point cloud file).
The RSL plug-in library is located in `$DELIGHT/shaders/'.
10.2.7.2 Entry Points
- float VolumeTracer_InitGrid ( uniform string gridName; ... )
Creates and initializes a 3D grid to be used by the other API functions. Parameters are:
- gridName
- Name of the grid. Might be used later by
VolumeTracer_NbAttributes
orVolumeTracer_InitRay_Function
.
The other parameters of the grid are specified through name/value pairs :
- uniform string paramName
- Name of the grid parameter.
- uniform <type> paramValue
- Value of the parameter.
Supported grid parameters are :
- `grid:center' (point)
- Center position of the grid in 3D space.
- `grid:size' (vector)
- Size of the grid in each dimension, in the same 3D space as the position.
- `grid:nbcells' (vector)
- Number of cells in the grid in each dimension.
- `grid:shader' (string)
- Name of a surface shader that will be used to compute the attributes of the volume at selected sample points in the grid. The shader must have a single output parameter of type "float[]" (the array can be of any constant size), plus any number of input parameters. This defines an attribute category for the grid. The size of the output array determines the number of attributes in the category. This parameter can be specified up to 3 times with different shader names in order to create multiple attribute categories.
In addition to this, parameters that need to be passed to the grid's shaders can also be specified through additional name/value pairs :
- uniform string paramName
- Name of the shader parameter, prefixed with the shader name (as specified for the `grid:shader' grid parameter) and the ":" parameter. For example to specifiy the parameter "pointCloudFile" of a shader named "density", paramName would be "density:pointCloudFile".
- uniform <type> paramValue
- Value of the shader parameter.
This function returns a uniform float which indicates the total number of attributes the grid will handle.
- float VolumeTracer_GetParameters ( uniform string gridName; ... )
Retrieves some parameters of a previously created grid. The first parameter of this function, gridName, is the name of a grid previously created with
VolumeTracer_InitGrid
. The following parameters are an optional list of name/value pairs : each pair is composed of the name of a grid parameter to be retrieved, followed by a uniform variable of the appropriate type where the grid parameter's value is to be stored. The following grid parameters are supported:- ` nbattributes'
- A float indicating the number of volume attributes managed by the grid (defined by the number of attributes returned by the grid's shaders). This is the number of attributes that will be returned by the
VolumeTracer_StepRay
function. - ` cellsize'
- A vector indicating the size of the cells in each dimension.
- ` nbcells'
- A vector indicating the number of cells in each dimension of the grid.
This function returns the number of grid parameters successfully retrieved (might be 0 if none were requested(73)), or a negative value if the grid was not found or the function was called with invalid arguments.
- float VolumeTracer_InitRay ( uniform string gridName; varying point start, end; varying float stepLength; uniform string interpolation )
Initializes a ray to be traced across the grid. Note that this function is SIMD so it will initialize many rays in practice. Parameters are:
- gridName
- Name of the grid in which ray-tracing takes place.
- start
- Starting position of the ray.
- end
- Ending position of the ray.
- stepLength
- Approximative length of steps to be made along the ray.
- interpolation
- Type of interpolation to be used when computing the volume's attributes along the ray. The following values are accepted :
- ` trunc'
- No interpolation - sample position is truncated to a grid vertex position
- ` nearest'
- No interpolation - nearest grid vertex is used
- ` linear'
- Linear interpolation between surrounding grid vertices
- ` cubic'
- Cubic interpolation between surrounding grid vertices
- ` exact'
- No interpolation - the grid is ignored and the exact value is computed directly by the grid's shaders (very expensive; meant for low resolution testing only)
VolumeTracer_StepRay_Function
.
- float VolumeTracer_StepRay ( varying float rayID; output varying float length; output varying float[] attributes )
Advances one step along a ray (in SIMD) and returns the volume's attribute midway along the step. All rays must belong to the same grid. Parameters are:
- rayID
- Identifier of a ray previously created with
VolumeTracer_InitRay
. - length
- The length of this step.
- attributes (optional)
- The volume's attributes computed near midpoint along the current step, using the shaders specified to
VolumeTracer_InitGrid
and the interpolation mode specified toVolumeTracer_InitRay
.
This function returns a varying float which indicates the fraction of the distance between the ray's start and end points that was covered until now. When 1.0 is returned, the end point has been reached and the ray cannot be advanced anymore.
- float VolumeTracer_EvaluateStep ( varying float rayID; output varying float[] attributes ; uniform string[] shaders )
Evaluates the volume's attribute midway along the previous step (in SIMD). All rays must belong to the same grid. Parameters are:
- rayID
- Identifier of a ray previously created with
VolumeTracer_InitRay
. - attributes
- The volume's attributes computed near midpoint along the current step, using the density shader specified to
VolumeTracer_InitGrid
and the interpolation mode specified toVolumeTracer_InitRay
. - shaders (optional)
- The list of attribute categories that should be evaluated, those categories are identified by the name of the shader that computes them, as provided in the `grid:shader' parameter of
VolumeTracer_InitGrid
. By default, all attributes will be evaluated, but disabling a few of them can improve performance.
This function returns a varying float success (1.0) or failure (1.0).
10.2.7.3 Usage Example
Follows a code snippet showing how to use the API:
uniform string objectName = ... ; uniform vector bboxCenter = ... ; uniform vector bboxSize = ... ; uniform vector nbCells = ... ; uniform float nbAttributes; /* Test grid existence */ if(VolumeTracer_GetParameters(objectName, "nbattributes", nbAttributes) < 0) { /* Create grid */ nbAttributes = VolumeTracer_InitGrid( objectName, "grid:center", bboxCenter, "grid:size", bboxSize, "grid:nbcells", nbCells, "grid:shader", "noisy", "noisy:intensity", 0.7); } /* Create ray */ float stepLength = ... ; uniform string interpolation = "linear"; float rayID = VolumeTracer_InitRay(objectName, transform("object", P-I), transform("object", P), stepLength, interpolation); float progress = 0.0; float attributes[]; resize(attributes, nbAttributes); while(progress < 1.0) { float step; progress = VolumeTracer_StepRay(rayID, step, attributes); /* Use attributes ... */ }
The `noisy.sl' shader has to define a varying output array of floats, as in:
surface noisy( uniform float intensity; output varying float density[3]; ) { color D = noise( P ) * intensity; density[0] = D[0]; density[1] = D[1]; density[2] = D[2]; }
10.2.8 The interactive edit API
This API allows some changes to be applied to the scene being rendered with quick feedback of their effect on the image. Some limits are placed on the allowed changes so that they can be rendered immediately, without any startup delay. Although this API can be accessed through RIB, it makes more sense when used with the C binding within an application with a user interface.
Using the API requires few changes from a regular render. The first one is that the editable and progressive hider options must be enabled. Also note that the raytrace hider must be used.
RtInt on = 1; RiHider( RI_RAYTRACE, "int editable", &on, "int progressive", &on, RI_NULL );
The scene is then output as usual. The next notable difference is that RiWorldEnd
will begin rendering in a background thread instead of blocking until the render is finished. Edits to the scene can now be applied with RiEditBegin
/ RiEditEnd
blocks. Rendering stops on the next RiFrameEnd
or RiEnd
call.
- RtVoid RiEditBegin ( RtToken name, ... )
- RtVoid RiEditBeginV ( RtToken name, RtInt n, RtToken tokens[], RtPointer params[] )
- RtVoid RiEditEnd ()
These functions are used to specify changes to the scene. The possible edit types specified by the
name
parameter along with their optional parameters are:- "attribute"
- This is a generic method of changing attributes on objects. The objects to edit are selected by these optional parameters:
- "string exactscopename"
- The provided value must exactly match an object's "identifier" "string name" attribute for it to be edited.
- "string scopename"
- The provided value is a regular expression which is matched against the object's "identifier" "string name" attribute to decide if it must be edited.
- "string scopetype"
- This can be either
"all"
or"geometry"
. If"geometry"
is given, the scope parameters above will match only on geometry. If"all"
is given, they will also match parent attribute scopes of the geometry. The default behavior is"all"
when a scope name is specified and"geometry"
when none is given (all geometry will match).
- "shader"
- This allows replacing a shader by handle for the entire scene. It can be much simpler and more efficient than performing several
"attribute"
edits. The shader is identified by adding a special"string __edithandleid"
parameter to its parameter list. When an edit is done, all shaders of the same type with a matching handle are replaced. - "light"
- This allows replacing a light shader by a new instance. It can be the same shader with different parameters or shader space or an entirely different shader. The shader replaces the previous shader with the same handle everywhere.
- "option"
- This allows editing options or other global objects such as the imager shader, the camera or named coordinate systems. Note that updating the camera requires a
RiCamera( "world", RI_NULL )
call once the new camera has been set up. - "texture"
- This specifies that a texture file was updated and should be reloaded by the renderer. The file is identified by the
"string filename"
named parameter. No other calls should be made betweenRiEditBegin
andRiEditEnd
. - "suspendrendering"
- This is not a real edit type but will simply suspend rendering until
RiEditEnd
is called. It is possible to specify edits withRiEditBegin
/RiEditEnd
pairs before resuming rendering with a finalRiEditEnd
.
Edit blocks begin in world space except for "option"
edits which begin with no transform in place. A complete example follows which demonstrates most types of edits.
/* 3Delight editable render API example. This is not meant to do anything useful besides demonstrating how the API works. */ #include <ri.h> #include <stdio.h> #include <stdlib.h> #include <time.h> #ifdef __linux__ # include <unistd.h> #endif #ifdef _WIN32 # include <windows.h> #endif void milisleep( unsigned ms ) { #ifdef _WIN32 Sleep( ms ); #else timespec delay; delay.tv_sec = ms / 1000u; delay.tv_nsec = (ms % 1000u) * 1000000u; nanosleep( &delay, 0x0 ); #endif } void OutputCamera( float fov ) { RiProjection( RI_PERSPECTIVE, RI_FOV, &fov, RI_NULL ); RiTranslate( 0.0f, 0.0f, 5.0f ); RiRotate( 40.0f, 1.0f, 0.0f, 0.0f ); } void OutputSpotlight( RtFloat aimangle, RtFloat coneangle, RtString handle ) { RiTranslate( 0.0f, 0.0f, -7.0f ); RiRotate( aimangle, 0.0f, 1.0f, 0.0f ); RtFloat conedeltaangle = 0.01f; RtFloat intensity = 25.0f; RiLightSource( "spotlight", RI___HANDLEID, &handle, "float coneangle", &coneangle, "float conedeltaangle", &conedeltaangle, "float intensity", &intensity, RI_NULL ); } void Identify( const char *i_name ) { RiAttribute( "identifier", "name", &i_name, RI_NULL ); } int main( int argc, char *argv[] ) { RiBegin( RI_NULL ); RiDisplay( "edit example", "idisplay", RI_RGBA, RI_NULL ); RiFormat( 1280, 720, 1.0f ); RiPixelFilter( RiBoxFilter, 1.0f, 1.0f ); RiPixelSamples( 4.0f, 4.0f ); RtInt on = 1; RiHider( RI_RAYTRACE, "int editable", &on, "int progressive", &on, RI_NULL ); OutputCamera( 25.0f ); RtString edithandle1 = "shadinggroup1"; RiWorldBegin(); RiTransformBegin(); OutputSpotlight( 0.0f, 0.10f, "light1" ); RiTransformEnd(); RiTransformBegin(); OutputSpotlight( -4.0f, 0.15f, "light2" ); RiTransformEnd(); RiIlluminate( (RtLightHandle)"light2", RI_FALSE ); RiAttributeBegin(); RtPoint patchPl[4] = { {-2, 1.1, 0}, {2, 1.1, 0}, {-2, -1.1, 0}, {2, -1.1, 0} }; Identify( "plane" ); RiSurface( "plastic", "string __edithandleid", &edithandle1, RI_NULL ); RiPatch( RI_BILINEAR, RI_P, patchPl, RI_NULL ); RiAttributeEnd(); RiAttributeBegin(); Identify( "sphere_left" ); RiSurface( "plastic", RI_NULL ); RiTranslate( -1.0f, 0.0f, -0.3f ); RiSphere( 0.3f, -0.3f, 0.0f, 360.0f, RI_NULL ); RiAttributeEnd(); RiAttributeBegin(); Identify( "sphere_right" ); RiSurface( "plastic", RI_NULL ); RiTranslate( 1.0f, 0.0f, -0.3f ); RiSphere( 0.3f, -0.3f, 0.0f, 360.0f, RI_NULL ); RiAttributeEnd(); RiAttributeBegin(); Identify( "cube" ); RiSurface( "plastic", "string __edithandleid", &edithandle1, RI_NULL ); RiTranslate( 0.0f, 0.0f, -0.5f ); RiRotate( 55.0f, 0.0f, 0.0f, 1.0f ); RiRotate( 45.0f, 1.0f, 0.0f, 0.0f ); RiRotate( 45.0f, 0.0f, 1.0f, 0.0f ); RiScale( 0.5f, 0.5f, 0.5f ); RiGeometry( "cube", RI_NULL ); RiAttributeEnd(); RiWorldEnd(); milisleep( 3000 ); /* Aim light1 a bit more to the right. Changes the light shader's space. */ RiEditBegin( "light", RI_NULL ); OutputSpotlight( 4.0f, 0.10f, "light1" ); RiEditEnd(); milisleep( 1000 ); /* Increase light's cone angle. Changes the light shader. */ RiEditBegin( "light", RI_NULL ); OutputSpotlight( 4.0f, 0.15f, "light1" ); RiEditEnd(); milisleep( 2000 ); /* Turn on the second spotlight. */ RiEditBegin( "attribute", RI_NULL ); RiIlluminate( (RtLightHandle)"light2", RI_TRUE ); RiEditEnd(); milisleep( 2000 ); /* Add a third spotlight. */ RiEditBegin( "attribute", RI_NULL ); OutputSpotlight( 0.0f, 0.05f, "light3" ); RiEditEnd(); milisleep( 2000 ); /* Turn it off for the plane. */ RtString plane = "plane"; RiEditBegin( "attribute", "string exactscopename", &plane, RI_NULL ); RiIlluminate( (RtLightHandle)"light3", RI_FALSE ); RiEditEnd(); milisleep( 2000 ); /* Change an attribute (color) on the left sphere. */ RtString leftsphere = "sphere_left"; RiEditBegin( "attribute", "string exactscopename", &leftsphere, RI_NULL ); RtColor newcolor = { 0.7f, 0.5f, 0.9f }; RiColor( newcolor ); RiEditEnd(); milisleep( 2000 ); /* Change (in this case add) the imager shader. */ RiEditBegin( "option", RI_NULL ); RtColor red = { 1.0f, 0.0f, 0.0f }; RiImager( "background", "color bgcolor", red, RI_NULL ); RiEditEnd(); milisleep( 2000 ); /* Give both spheres a matte shader, using a regular expression. */ RtString spheres = "^sphere.*"; RiEditBegin( "attribute", "string scopename", &spheres, RI_NULL ); RiSurface( "matte", RI_NULL ); RiEditEnd(); milisleep( 2000 ); /* Change the camera. */ RiEditBegin( "option", RI_NULL ); OutputCamera( 20.0f ); RiCamera( RI_WORLD, RI_NULL ); RiEditEnd(); milisleep( 2000 ); /* Edit shaders by handle. We only change Kd here but could also use a different shader. */ RiEditBegin( "shader", RI_NULL ); float Kd = 0.2; RiSurface( "plastic", "string __edithandleid", &edithandle1, "float Kd", &Kd, RI_NULL ); RiEditEnd(); milisleep( 250 ); /* Pause rendering for a short time. */ RiEditBegin( "suspendrendering", RI_NULL ); milisleep( 1500 ); RiEditEnd(); milisleep( 5000 ); /* Stop rendering. */ RiEnd(); }
3Delight 10.0. Copyright 2000-2011 The 3Delight Team. All Rights Reserved.