[Back]


cellbasis.c

/* * Copyright (c) 1999-2001 Thomas E. Burge. All rights reserved. * * Affine (R) is a registered trademark of Thomas E. Burge * * THIS SOFTWARE IS DISTRIBUTED "AS-IS" WITHOUT WARRANTY OF ANY KIND * AND WITHOUT ANY GUARANTEE OF MERCHANTABILITY OR FITNESS FOR A * PARTICULAR PURPOSE. * * In no event shall Thomas E. Burge be liable for any indirect or * consequential damages or loss of data resulting from use or performance * of this software. * * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that the following copyright notices and this permission notice appear in * all copies of the software and related documentation: * * The Affine (R) Libraries and Tools are * Copyright (c) 1995-2001 Thomas E. Burge. * All rights reserved. * Affine (R) is a registered trademark of Thomas E. Burge. * * Also refer to any additional requirements presently set by Pixar * in regards to the RenderMan (R) Interface Procedures and Protocol. * * * Affine Toolkit * * FILE: cellbasis.c * * DESCRIPTION: Example shadeop DSO for PRMan 3.8. * * Contains: * * History: * * References: * [PIXA98] Pixar, rnotes-3.8.html#shadedsos, Version 3.8, * Richmond, CA, 1998. * [WORL96] Worley, Steven, A Cellular Texture Basis Function, * SIGGRAPH 96 Conference Proceedings, Addison Wesley, * 1996, pp. 291-294. * * * The RenderMan (R) Interface Procedures and Protocol are: * Copyright 1988, 1989, Pixar * All Rights Reserved * * Renderman (R) is a registered trademark of Pixar */ #include <stdio.h> #include <string.h> #include <math.h> /*Uncomment this to build BMRT 2.6*/ /*#define BMRT2_6*/ #ifndef BMRT2_6 #include <shadeop.h> #else typedef struct _SHADEOP_SPEC { char *declaration; /* if zero length string, end of table signaled. */ char *initfunctionname; /* optional */ char *cleanupfunctionname;/* optional */ } SHADEOP_SPEC; #endif typedef struct _point { float x; float y; float z; } point; #if defined(__cplusplus) || defined(c_plusplus) extern "C" { #endif #ifdef _WIN32 #define EXTERN extern _declspec(dllexport) #else #define EXTERN extern #endif EXTERN SHADEOP_SPEC cellbasis_shadeops[]; /* For BMRT 2.6 intelnt the following export for functions * named in the shadeops[] table is needed. Otherwise you get * the behavior with BMRT 2.6.0.-18 intelnt of slc working * fine and even the RIB rendering without any messages, but * yet the code in the shaderop that should be called * is never run during the rendering. */ EXTERN int cellbasis( void *initdata, int argc, void *argv[] ); #if defined(__cplusplus) || defined(c_plusplus) } #endif #ifndef BMRT2_6 /*SHADEOP_TABLE(cellbasis) = {*/ SHADEOP_SPEC cellbasis_shadeops[] = { /* Do not use "output" in "float cellbasis(point, output float,...)" * because "output" never allows a shader to match types and the * argv[] pointers allow changes to the data anyway. * * Using arrays on the parameter list is not liked by the compiler: * * ...,{ "void cellbasis(point, float, point[], float[])", "", "", }, * or * ...,{ "void cellbasis(point, float, point[9], float[9])", "", "", }, * * Using a return type of "void" compiles but causes the following error * when prman is used: * S05001 Shadeop error: argument types clash in op calldso at pc 6 * in "callCellBasis". (WARNING) * So use a return type of "float" and just ignore argv[0]. */ { "float cellbasis(point, "\ "point, float)", "", "", }, { "float cellbasis(point, "\ "point, float, point, float)", "", "", }, { "float cellbasis(point, "\ "point, float, point, float, point, float)", "", "", }, { "float cellbasis(point, "\ "point, float, point, float, point, float, point, float)", "", "", }, { "", "", "", } }; #else /* The following was tested on 2.6.0.-18 intelnt */ /* I haven't yet checked the limitations mentioned above against this * version of BMRT. */ SHADEOP_SPEC cellbasis_shadeops[] = { { "float cellbasis(point, point, float)", "", "", }, { "float cellbasis(point, "\ "point, float, point, float)", "", "", }, { "float cellbasis(point, "\ "point, float, point, float, point, float)", "", "", }, { "float cellbasis(point, "\ "point, float, point, float, point, float, point, float)", "", "", }, { "", "", "", } }; #endif #define xcomp(/* point* */ p) ((p)->x) #define ycomp(/* point* */ p) ((p)->y) #define zcomp(/* point* */ p) ((p)->z) float distance( point *p1, point *p2 ) { point v; v.x = p1->x - p2->x; v.y = p1->y - p2->y; v.z = p1->z - p2->z; return (float)sqrt( v.x*v.x + v.y*v.y + v.z*v.z ); } static unsigned int idum=1; void scellnoise(unsigned int seed) { idum = seed; } int intcellnoise( int max ) { /* Numerical Recipes in C, Second Edition, page 284. */ idum = 1664525*idum + 1013904223; max++; return idum % max; } float cellnoise() { float f; /* Numerical Recipes in C, Second Edition, page 284. */ idum = 1664525*idum + 1013904223; f = (float)idum / (float)0xffffffff; return f; } #define Swap( p1, p2, f1, f2 ) \ { \ point SwapP; \ float SwapF; \ \ SwapP = p1; \ SwapF = f1; \ p1 = p2; \ f1 = f2; \ p2 = SwapP; \ f2 = SwapF; \ } void FindFeaturePoints( int n, point *P, int i, int j, int k, point featurepoints[], float distances[] ) { int s = 0; int npoints; float dist; point p; int a,b; /* Set seed for random numbers. */ scellnoise(541*i + 79*j + (31*k)%999983); npoints = intcellnoise(5) + 4; /* npoints is a member of {4..9}. */ for ( s=0; s < npoints; s++ ) { p.x = i+cellnoise(); p.y = j+cellnoise(); p.z = k+cellnoise(); dist = distance( &p, P ); for ( a=0; a < n; a+=1 ) { if ( dist < distances[a] ) break; } for ( b=a; b < n; b+=1 ) { Swap( p, featurepoints[b], dist, distances[b] ); } } } /* Checking bounds gives a huge performance boost, but if nF gets * greater than 4 when there are 9 points per cell the DIST bounds * needs to be lowered. * Note that a fancy mechanism based on the density of feature points * in a cell could be used to automate the calculation of a good * bounding scheme. */ #define DIST 0.5 int cellbasis( void *initdata, int argc, void *argv[] ) { int nF; int i,j,k; float x,y,z; float xn,yn,zn; float largedistances[9] = {1e5,1e5,1e5,1e5,1e5,1e5,1e5,1e5,1e5}; float distances[9] = {1e5,1e5,1e5,1e5,1e5,1e5,1e5,1e5,1e5}; point featurepoints[9]; point *P; switch (argc) { case 4: nF = 1; break; case 6: nF = 2; break; case 8: nF = 3; break; case 10: nF = 4; break; default: return 1; } P = argv[1]; x = xcomp(P); y = ycomp(P); z = zcomp(P); i = (int)floor(x); j = (int)floor(y); k = (int)floor(z); xn = x - i; yn = y - j; zn = z - k; memcpy( distances, largedistances, nF * sizeof(float ) ); FindFeaturePoints( nF, P, i, j, k, featurepoints,distances ); #if 1 /* Cheap bounding scheme used here. */ if ( zn <= DIST ) { FindFeaturePoints( nF, P, i, j, k-1, featurepoints,distances ); if ( yn <= DIST ) { FindFeaturePoints( nF, P, i, j-1, k-1, featurepoints,distances ); FindFeaturePoints( nF, P, i, j-1, k, featurepoints,distances ); } else { FindFeaturePoints( nF, P, i, j+1, k-1, featurepoints,distances ); FindFeaturePoints( nF, P, i, j+1, k, featurepoints,distances ); } if ( xn <= DIST ) { FindFeaturePoints( nF, P, i-1, j, k-1, featurepoints,distances ); FindFeaturePoints( nF, P, i-1, j, k, featurepoints,distances ); if ( yn <= DIST ) { FindFeaturePoints( nF, P, i-1, j-1, k-1, featurepoints,distances ); FindFeaturePoints( nF, P, i-1, j-1, k, featurepoints,distances ); } else { FindFeaturePoints( nF, P, i-1, j+1, k-1, featurepoints,distances ); FindFeaturePoints( nF, P, i-1, j+1, k, featurepoints,distances ); } } else { FindFeaturePoints( nF, P, i+1, j, k-1, featurepoints,distances ); FindFeaturePoints( nF, P, i+1, j, k, featurepoints,distances ); if ( yn <= DIST ) { FindFeaturePoints( nF, P, i+1, j-1, k-1, featurepoints,distances ); FindFeaturePoints( nF, P, i+1, j-1, k, featurepoints,distances ); } else { FindFeaturePoints( nF, P, i+1, j+1, k-1, featurepoints,distances ); FindFeaturePoints( nF, P, i+1, j+1, k, featurepoints,distances ); } } } else { FindFeaturePoints( nF, P, i, j, k+1, featurepoints,distances ); if ( yn <= DIST ) { FindFeaturePoints( nF, P, i, j-1, k+1, featurepoints,distances ); FindFeaturePoints( nF, P, i, j-1, k, featurepoints,distances ); } else { FindFeaturePoints( nF, P, i, j+1, k+1, featurepoints,distances ); FindFeaturePoints( nF, P, i, j+1, k, featurepoints,distances ); } if ( xn <= DIST ) { FindFeaturePoints( nF, P, i-1, j, k+1, featurepoints,distances ); FindFeaturePoints( nF, P, i-1, j, k, featurepoints,distances ); if ( yn <= DIST ) { FindFeaturePoints( nF, P, i-1, j-1, k+1, featurepoints,distances ); FindFeaturePoints( nF, P, i-1, j-1, k, featurepoints,distances ); } else { FindFeaturePoints( nF, P, i-1, j+1, k+1, featurepoints,distances ); FindFeaturePoints( nF, P, i-1, j+1, k, featurepoints,distances ); } } else { FindFeaturePoints( nF, P, i+1, j, k+1, featurepoints,distances ); FindFeaturePoints( nF, P, i+1, j, k, featurepoints,distances ); if ( yn <= DIST ) { FindFeaturePoints( nF, P, i+1, j-1, k+1, featurepoints,distances ); FindFeaturePoints( nF, P, i+1, j-1, k, featurepoints,distances ); } else { FindFeaturePoints( nF, P, i+1, j+1, k+1, featurepoints,distances ); FindFeaturePoints( nF, P, i+1, j+1, k, featurepoints,distances ); } } } #else FindFeaturePoints( nF, P, i, j-1, k-1, featurepoints, distances ); FindFeaturePoints( nF, P, i, j, k-1, featurepoints, distances ); FindFeaturePoints( nF, P, i, j+1, k-1, featurepoints, distances ); FindFeaturePoints( nF, P, i-1, j-1, k-1, featurepoints, distances ); FindFeaturePoints( nF, P, i-1, j, k-1, featurepoints, distances ); FindFeaturePoints( nF, P, i-1, j+1, k-1, featurepoints, distances ); FindFeaturePoints( nF, P, i+1, j-1, k-1, featurepoints, distances ); FindFeaturePoints( nF, P, i+1, j, k-1, featurepoints, distances ); FindFeaturePoints( nF, P, i+1, j+1, k-1, featurepoints, distances ); FindFeaturePoints( nF, P, i, j-1, k, featurepoints, distances ); FindFeaturePoints( nF, P, i, j+1, k, featurepoints, distances ); FindFeaturePoints( nF, P, i-1, j-1, k, featurepoints, distances ); FindFeaturePoints( nF, P, i-1, j, k, featurepoints, distances ); FindFeaturePoints( nF, P, i-1, j+1, k, featurepoints, distances ); FindFeaturePoints( nF, P, i+1, j-1, k, featurepoints, distances ); FindFeaturePoints( nF, P, i+1, j, k, featurepoints, distances ); FindFeaturePoints( nF, P, i+1, j+1, k, featurepoints, distances ); FindFeaturePoints( nF, P, i, j-1, k+1, featurepoints, distances ); FindFeaturePoints( nF, P, i, j, k+1, featurepoints, distances ); FindFeaturePoints( nF, P, i, j+1, k+1, featurepoints, distances ); FindFeaturePoints( nF, P, i-1, j-1, k+1, featurepoints, distances ); FindFeaturePoints( nF, P, i-1, j, k+1, featurepoints, distances ); FindFeaturePoints( nF, P, i-1, j+1, k+1, featurepoints, distances ); FindFeaturePoints( nF, P, i+1, j-1, k+1, featurepoints, distances ); FindFeaturePoints( nF, P, i+1, j, k+1, featurepoints, distances ); FindFeaturePoints( nF, P, i+1, j+1, k+1, featurepoints, distances ); #endif switch (nF) { case 4: *((float*)argv[9]) = distances[3]; *((point*)argv[8]) = featurepoints[3]; /* fall through */ case 3: *((float*)argv[7]) = distances[2]; *((point*)argv[6]) = featurepoints[2]; /* fall through */ case 2: *((float*)argv[5]) = distances[1]; *((point*)argv[4]) = featurepoints[1]; /* fall through */ case 1: *((float*)argv[3]) = distances[0]; *((point*)argv[2]) = featurepoints[0]; } #ifdef DEBUG for (i=0;i < 9;i++) printf("d:%g (%f,%f,%f)\n",distances[i],featurepoints[i].x, featurepoints[i].y,featurepoints[i].z); #endif return 0; }

tebVoronoiDSO.sl

/* * Copyright (c) 1999 Thomas E. Burge. All rights reserved. * * * FILE: tebVoronoiDSO.sl * * * DESCRIPTION: * * Using the cellbasis DSO can double the speed over using the same code * in the SL version tebVoronoi.sl. * * References: * [WORL96] Worley, Steven, A Cellular Texture Basis Function, * SIGGRAPH 96 Conference Proceedings, Addison Wesley, * 1996, pp. 291-294. * */ surface tebVoronoiDSO( uniform float Ka = 1.0; uniform float Kd = .5; /* cellbasistype can be assigned one of the following: * "voronoi", "medialaxis", "F1", "F2", "F3", "F4", * or "edgedvoronoi". * voronoi == F1 * medialaxis == F2 -- has a medial-axis diagram "look" * edgedvoronoi == F2 - F1 */ uniform string cellbasistype = "voronoi"; ) { normal Nf; color Ct; point p1=0; point p2=0; point p3=0; point p4=0; float d1=0; float d2=0; float d3=0; float d4=0; if ( cellbasistype=="voronoi" || cellbasistype=="F1" ) { cellbasis( P, p1, d1 ); Ct = d1; } else if ( cellbasistype=="medialaxis" || cellbasistype=="F2" ) { cellbasis( P, p1, d1, p2, d2 ); Ct = d2; } else if ( cellbasistype=="F3" ) { cellbasis( P, p1, d1, p2, d2, p3, d3 ); Ct = d3; } else if ( cellbasistype=="F4" ) { cellbasis( P, p1, d1, p2, d2, p3, d3, p4, d4 ); Ct = d4; } else if ( cellbasistype=="edgedvoronoi" ) { cellbasis( P, p1, d1, p2, d2 ); Ct = d2 - d1; } else Ct = 0.0; Nf = faceforward( normalize(N), I ); Ci = Os * ( Cs * Ct * (Ka*ambient()+Kd*diffuse(Nf)) ); Oi = Os; }

Makefile

# # Use this only with PRMan 3.8. # .SUFFIXES: .sl .slo .rib .tif INCPATHS= -I. -I/usr/local/prman/include LIBPATHS= -L/usr/local/prman/lib # For SGI C compiler: CC=cc CFLAGS= -g -ansi -fullwarn ${INCPATHS} CFLAGS32= -n32 -mips4 LFLAGS32= -n32 -mips4 .c.o: ${CC} -n32 -mips3 -c $< ${INCPATHS} .sl.slo: shader $< .rib.tif: prman $< all: cellbasis.so tebVoronoiDSO.slo tebVoronoi.slo clean: -rm ./cellbasis.so cellbasis.o so_locations \ tebVoronoi.slo tebVoronoiDSO.slo cellbasis.so: cellbasis.o Makefile ld -n32 -mips3 -shared -o cellbasis.so cellbasis.o tebVoronoiDSO.slo: tebVoronoiDSO.sl Makefile cellbasis.so tebVoronoi.slo: tebVoronoi.sl Makefile

cellbasis.mak (Windows VC++6.0 nmake)

# # BMRT 2.6 seems to use the Unix .so naming convention. # cellbasis.so: cellbasis.obj link.exe rendrib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib \ advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib \ odbccp32.lib /nologo /dll /incremental:no /machine:I386 /out:"cellbasis.so" \ /implib:"cellbasis.lib" /libpath:"$(RMANTREE)/lib" cellbasis.obj cellbasis.obj: cellbasis.c .c.obj:: cl.exe /o cellbasis.so /nologo /MT /W3 /GX /O2 /I "$(RMANTREE)/include" /D "WIN32" /D "NDEBUG" \ /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /c $<


[Affine Toolkit]
[RIB Utilities] [Bitmap Utilities] [Handy Little Utilities]
[Libraries] [Using the Libraries]