1 //////////////////////////////////////////////////////////////////////
2 //
3 //                             Pixie
4 //
5 // Copyright � 1999 - 2003, Okan Arikan
6 //
7 // Contact: okan@cs.utexas.edu
8 //
9 //	This library is free software; you can redistribute it and/or
10 //	modify it under the terms of the GNU Lesser General Public
11 //	License as published by the Free Software Foundation; either
12 //	version 2.1 of the License, or (at your option) any later version.
13 //
14 //	This library is distributed in the hope that it will be useful,
15 //	but WITHOUT ANY WARRANTY; without even the implied warranty of
16 //	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 //	Lesser General Public License for more details.
18 //
19 //	You should have received a copy of the GNU Lesser General Public
20 //	License along with this library; if not, write to the Free Software
21 //	Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22 //
23 ///////////////////////////////////////////////////////////////////////
24 ///////////////////////////////////////////////////////////////////////
25 //
26 //  File				:	ri.cpp
27 //  Classes				:	-
28 //  Description			:	RenderMan Interface Implementation
29 //
30 ////////////////////////////////////////////////////////////////////////
31 ////////////////////////////////////////////////////////////////////////
32 // The RI implementation
33 #include <math.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <stdarg.h>
37 #include <string.h>
38 
39 #include "common/global.h"
40 #include "common/os.h"
41 #include "error.h"
42 #include "ri.h"
43 #include "riInterface.h"
44 #include "ribOut.h"
45 #include "delayed.h"
46 #include "rendererContext.h"
47 
48 //////////////////////////////////////////////////////////////////
49 // Token definitions
50 RtToken		RI_FRAMEBUFFER		=	"framebuffer";
51 RtToken		RI_FILE				=	"file";
52 
53 RtToken		RI_RGB				=	"rgb";
54 RtToken		RI_RGBA				=	"rgba";
55 RtToken		RI_RGBZ				=	"rgbz";
56 RtToken		RI_RGBAZ			=	"rgbaz";
57 RtToken		RI_A				=	"a";
58 RtToken		RI_Z				=	"z";
59 RtToken		RI_AZ				=	"az";
60 
61 RtToken		RI_PERSPECTIVE		=	"perspective";
62 RtToken		RI_ORTHOGRAPHIC		=	"orthographic";
63 
64 RtToken		RI_HIDDEN			=	"hidden";
65 RtToken		RI_PAINT			=	"paint";
66 
67 RtToken		RI_CONSTANT			=	"constant";
68 RtToken		RI_SMOOTH			=	"smooth";
69 
70 RtToken		RI_FLATNESS			=	"flatness";
71 RtToken		RI_FOV				=	"fov";
72 
73 RtToken		RI_AMBIENTLIGHT		=	"ambientlight";
74 RtToken		RI_POINTLIGHT		=	"pointlight";
75 RtToken		RI_DISTANTLIGHT		=	"distantlight";
76 RtToken		RI_SPOTLIGHT		=	"spotlight";
77 
78 RtToken		RI_INTENSITY		=	"intensity";
79 RtToken		RI_LIGHTCOLOR		=	"lightcolor";
80 RtToken		RI_FROM				=	"from";
81 RtToken		RI_TO				=	"to";
82 RtToken		RI_CONEANGLE		=	"coneangle";
83 RtToken     RI_CONEDELTAANGLE	=	"conedeltaangle";
84 RtToken		RI_BEAMDISTRIBUTION	=	"beamdistribution";
85 
86 RtToken		RI_MATTE			=	"matte";
87 RtToken		RI_METAL			=	"metal";
88 RtToken		RI_SHINYMETAL		=	"shinymetal";
89 RtToken		RI_PLASTIC			=	"plastic";
90 RtToken		RI_PAINTEDPLASTIC	=	"paintedplastic";
91 
92 RtToken		RI_KA				=	"Ka";
93 RtToken		RI_KD				=	"Kd";
94 RtToken		RI_KS				=	"Ks";
95 RtToken		RI_ROUGHNESS		=	"roughness";
96 RtToken		RI_KR				=	"Kr";
97 RtToken		RI_TEXTURENAME		=	"texturename";
98 RtToken		RI_SPECULARCOLOR	=	"specularcolor";
99 
100 RtToken		RI_DEPTHCUE			=	"depthcue";
101 RtToken		RI_FOG				=	"fog";
102 RtToken		RI_BUMPY			=	"bumpy";
103 
104 RtToken		RI_MINDISTANCE		=	"mindistance";
105 RtToken		RI_BACKGROUND		=	"background";
106 RtToken		RI_DISTANCE			=	"distance";
107 RtToken		RI_AMPLITUDE		=	"amplitude";
108 
109 RtToken		RI_INSIDE			=	"inside";
110 RtToken		RI_OUTSIDE			=	"outside";
111 RtToken		RI_LH				=	"lh";
112 RtToken		RI_RH				=	"rh";
113 
114 RtToken		RI_P				=	"P";
115 RtToken		RI_PZ				=	"Pz";
116 RtToken		RI_PW				=	"Pw";
117 RtToken		RI_N				=	"N";
118 RtToken		RI_NP				=	"Np";
119 RtToken		RI_CS				=	"Cs";
120 RtToken		RI_OS				=	"Os";
121 RtToken		RI_S				=	"s";
122 RtToken		RI_T				=	"t";
123 RtToken		RI_ST				=	"st";
124 
125 RtToken		RI_BILINEAR			=	"bilinear";
126 RtToken		RI_BICUBIC			=	"bicubic";
127 
128 RtToken		RI_PRIMITIVE		=	"primitive";
129 RtToken		RI_INTERSECTION		=	"intersection";
130 RtToken		RI_UNION			=	"union";
131 RtToken		RI_DIFFERENCE		=	"difference";
132 
133 RtToken		RI_PERIODIC			=	"periodic";
134 RtToken		RI_NOWRAP			=	"nowrap";
135 RtToken		RI_NONPERIODIC		=	"nonperiodic";
136 RtToken		RI_CLAMP			=	"clamp";
137 RtToken		RI_BLACK			=	"black";
138 
139 RtToken		RI_IGNORE			=	"ignore";
140 RtToken		RI_PRINT			=	"print";
141 RtToken		RI_ABORT			=	"abort";
142 RtToken		RI_HANDLER			=	"handler";
143 
144 RtToken		RI_ORIGIN			=	"origin";
145 RtToken		RI_IDENTIFIER		=	"identifier";
146 RtToken		RI_NAME				=	"name";
147 
148 RtToken		RI_COMMENT			=	"comment";
149 RtToken		RI_STRUCTURE		=	"structure";
150 RtToken		RI_VERBATIM			=	"verbatim";
151 
152 RtToken		RI_LINEAR			=	"linear";
153 RtToken		RI_CUBIC			=	"cubic";
154 RtToken		RI_WIDTH			=	"width";
155 RtToken		RI_CONSTANTWIDTH	=	"constantwidth";
156 
157 RtToken		RI_CATMULLCLARK		=	"catmull-clark";
158 RtToken		RI_HOLE				=	"hole";
159 RtToken		RI_CREASE			=	"crease";
160 RtToken		RI_CORNER			=	"corner";
161 RtToken		RI_INTERPOLATEBOUNDARY	=	"interpolateboundary";
162 
163 RtToken		RI_CURRENT			=	"current";
164 RtToken		RI_WORLD			=	"world";
165 RtToken		RI_OBJECT			=	"object";
166 RtToken		RI_SHADER			=	"shader";
167 RtToken		RI_RASTER			=	"raster";
168 RtToken		RI_NDC				=	"ndc";
169 RtToken		RI_SCREEN			=	"screen";
170 RtToken		RI_CAMERA			=	"camera";
171 RtToken		RI_EYE				=	"eye";
172 
173 
174 
175 ////////////////////////////////////////////////////////////////////////
176 //
177 //	Filter types
178 //
179 ////////////////////////////////////////////////////////////////////////
180 RtToken		RI_BOXFILTER				=	"box";
181 RtToken		RI_TRIANGLEFILTER			=	"triangle";
182 RtToken		RI_GAUSSIANFILTER			=	"gaussian";
183 RtToken		RI_SINCFILTER				=	"sinc";
184 RtToken		RI_CATMULLROMFILTER			=	"catmull-rom";
185 RtToken		RI_BLACKMANHARRISFILTER		=	"blackman-harris";
186 RtToken		RI_MITCHELLFILTER			=	"mitchell";
187 RtToken		RI_BESSELFILTER				=   "bessel";
188 RtToken		RI_DISKFILTER				=   "disk";
189 RtToken		RI_CUSTOM					=	"custom";
190 
191 RtToken		RI_MIN						=	"min";
192 RtToken		RI_MAX						=	"max";
193 RtToken		RI_AVERAGE					=	"average";
194 RtToken		RI_ZMIN						=	"zmin";
195 RtToken		RI_ZMAX						=	"zmax";
196 
197 
198 ////////////////////////////////////////////////////////////////////////
199 //
200 //	Non-Standard options/attributes entry points
201 //
202 ////////////////////////////////////////////////////////////////////////
203 RtToken		RI_LIMITS				=	"limits";
204 RtToken		RI_SEARCHPATH			=	"searchpath";
205 RtToken		RI_SHADOW				=	"shadow";
206 RtToken		RI_RENDER				=	"render";
207 RtToken		RI_DICE					=	"dice";
208 RtToken		RI_HINT					=	"hint";
209 RtToken		RI_TEXTURE				=	"texture";
210 RtToken		RI_HIDER				=	"hider";
211 RtToken		RI_STATISTICS			=	"statistics";
212 RtToken		RI_VISIBILITY			=	"visibility";
213 RtToken		RI_SHADE				=	"shade";
214 RtToken		RI_DISPLACEMENTBOUND	=	"displacementbound";
215 RtToken		RI_IRRADIANCE			=	"irradiance";
216 RtToken		RI_CULL					=	"cull";
217 RtToken		RI_COMPRESSION			=	"compression";
218 RtToken		RI_RIB					=	"rib";
219 RtToken		RI_SHUTTER				=	"shutter";
220 RtToken		RI_USER					=	"user";
221 
222 ////////////////////////////////////////////////////////////////////////
223 //
224 //	Non-Standard attributes
225 //
226 ////////////////////////////////////////////////////////////////////////
227 
228 RtToken		RI_NORMALDEVIATION		=	"normaldeviation";
229 RtToken		RI_POINTDEVIATION		=	"pointdeviation";
230 
231 
232 // Dice attributes
233 RtToken		RI_MINSUBDIVISION		=	"minsubdivision";
234 RtToken		RI_MAXSUBDIVISION		=	"maxsubdivision";
235 RtToken		RI_NUMPROBES			=	"numprobes";
236 RtToken		RI_MINSPLITS			=	"minsplits";
237 RtToken		RI_BOUNDEXPAND			=	"boundexpand";
238 RtToken		RI_BINARY				=	"binary";
239 RtToken		RI_RASTERORIENT			=	"rasterorient";
240 
241 // Displacementbound attributes
242 RtToken		RI_SPHERE				=	"sphere";
243 RtToken		RI_COORDINATESYSYTEM	=	"coordinatesystem";
244 
245 // Visibility attributes
246 RtToken		RI_PHOTON				=	"photon";
247 RtToken		RI_ENVIRONMENT			=	"environment";
248 RtToken		RI_TRACE				=	"trace";
249 RtToken		RI_DIFFUSE				=	"diffuse";
250 RtToken		RI_SPECULAR				=	"specular";
251 RtToken		RI_TRANSMISSION			=	"transmission";
252 RtToken		RI_CAUSTICS				=	"caustics";
253 
254 RtToken		RI_DIFFUSEHITMODE		=	"diffusehitmode";
255 RtToken		RI_SPECULARHITMODE		=	"specularhitmode";
256 RtToken		RI_TRANSMISSIONHITMODE	=	"transmissionhitmode";
257 RtToken		RI_CAMERAHITMODE		=	"camerahitmode";
258 
259 // Trace attributes
260 RtToken		RI_BIAS					=	"bias";
261 RtToken		RI_DISPLACEMENTS		=	"displacements";
262 RtToken		RI_MAXDIFFUSEDEPTH		=	"maxdiffusedepth";
263 RtToken		RI_MAXSPECULARDEPTH		=	"maxspeculardepth";
264 RtToken		RI_SAMPLEMOTION			=	"samplemotion";
265 
266 // Photon attributes
267 RtToken		RI_GLOBALMAP			=	"globalmap";
268 RtToken		RI_CAUSTICMAP			=	"causticmap";
269 RtToken		RI_ESTIMATOR			=	"estimator";
270 RtToken		RI_MAXDISTANCE			=	"maxdistance";
271 RtToken		RI_SHADINGMODEL			=	"shadingmodel";
272 RtToken		RI_ILLUMINATEFRONT		=	"illuminatefront";
273 RtToken		RI_IOR					=	"ior";
274 RtToken		RI_IORRANGE				=	"iorrange";
275 
276 // Motionfactor attribute
277 RtToken		RI_MOTIONFACTOR			=	"motionfactor";
278 
279 // Cull attributes
280 //RtToken	RI_HIDDEN				=	"hidden";
281 RtToken		RI_BACKFACING			=	"backfacing";
282 
283 
284 ////////////////////////////////////////////////////////////////////////
285 //
286 //	Non-Standard options
287 //
288 ////////////////////////////////////////////////////////////////////////
289 
290 // Searchpath options
291 RtToken		RI_ARCHIVE				=	"archive";
292 RtToken		RI_PROCEDURAL			=	"procedural";
293 RtToken		RI_RESOURCE				=	"resource";
294 RtToken		RI_DISPLAY				=	"display";
295 
296 
297 // Limits options
298 RtToken		RI_BUCKETSIZE			=	"bucketsize";
299 RtToken		RI_METABUCKETS			=	"metabuckets";
300 RtToken		RI_GRIDSIZE				=	"gridsize";
301 RtToken		RI_MAXRECURSION			=	"raydepth";
302 RtToken		RI_TEXTUREMEMORY		=	"texturememory";
303 RtToken		RI_BRICKMEMORY			=	"brickmemory";
304 RtToken		RI_EYESPLITS			=	"eyesplits";
305 RtToken		RI_NUMTHREADS			=	"numthreads";
306 RtToken		RI_THREADSTRIDE			=	"threadstride";
307 RtToken		RI_GEOCACHEMEMORY		=	"geocachememory";
308 RtToken		RI_OTHRESHOLD			=	"othreshold";
309 RtToken		RI_ZTHRESHOLD			=	"zthreshold";
310 
311 // Trace options
312 RtToken		RI_MAXDEPTH				=	"maxdepth";
313 
314 // Statstics options
315 RtToken		RI_ENDOFFRAME			=	"endofframe";
316 RtToken		RI_FILELOG				=	"filelog";
317 RtToken		RI_PROGRESS				=	"progress";
318 
319 // Irradiance options
320 RtToken		RI_HANDLE				=	"handle";
321 RtToken		RI_FILEMODE				=	"filemode";
322 RtToken		RI_MAXERROR				=	"maxerror";
323 RtToken		RI_MAXPIXELDIST			=	"maxpixeldist";
324 RtToken		RI_MINSAMPLEDISTANCE	=	"minsampledistance";
325 RtToken		RI_MAXSAMPLEDISTANCE	=	"maxsampledistance";
326 
327 // Hider options
328 RtToken		RI_JITTER				=	"jitter";
329 RtToken		RI_FALSECOLOR			=	"falsecolor";
330 RtToken		RI_EMIT					=	"emit";
331 RtToken		RI_SAMPLESPECTRUM		=	"samplespectrum";
332 RtToken		RI_DEPTHFILTER			=	"depthfilter";
333 RtToken		RI_RADIANCECACHE		=	"radiancecache";
334 
335 // IO options
336 RtToken		RI_MASKRESOLUTION		=	"maskresolution";
337 RtToken		RI_MASKPRINTF			=	"maskprintf";
338 RtToken		RI_MASKLOG				=	"masklog";
339 RtToken		RI_MASKPROGRESS			=	"maskprogress";
340 RtToken		RI_MASKSTATS			=	"maskstats";
341 RtToken		RI_INHERITATTRIBUTES	=	"inheritattributes";
342 
343 // Shutter options
344 RtToken		RI_OFFSET				=	"offset";
345 
346 // Misc junk
347 RtToken		RI_DEFAULTSURFACE		=	"defaultsurface";
348 
349 // Error handling
350 RtInt		RiLastError				=	RIE_NOERROR;
351 
352 ////////////////////////////////////////////////////////////////////////
353 // The cubic spline basis definition
354 RtBasis		RiCatmullRomBasis	= {
355 	{(float)  (-1.0/2.0),	(float)  ( 3.0/2.0),	(float)  (-3.0/2.0),	(float)  ( 1.0/2.0)},
356 	{(float)  ( 2.0/2.0),	(float)  (-5.0/2.0),	(float)  ( 4.0/2.0),	(float)  (-1.0/2.0)},
357 	{(float)  (-1.0/2.0),	(float)  ( 0.0/2.0),	(float)  ( 1.0/2.0),	(float)  ( 0.0/2.0)},
358 	{(float)  ( 0.0/2.0),	(float)  ( 2.0/2.0),	(float)  ( 0.0/2.0),	(float)  ( 0.0/2.0)}};
359 
360 
361 RtBasis		RiBezierBasis		= {
362 	{(float) -1,	(float)	3,		(float)	-3,		(float)	1},
363 	{(float) 3,		(float)	-6,		(float)	3,		(float)	0},
364 	{(float) -3,	(float)	3,		(float)	0,		(float)	0},
365 	{(float) 1,		(float)	0,		(float)	0,		(float)	0 }};
366 
367 RtBasis		RiBSplineBasis		= {
368 	{(float) (-1.0/6.0),	(float) (3.0/6.0),	(float) (-3.0/6.0),	(float)  (1.0/6.0)},
369 	{(float) (3.0/6.0),		(float) -(6.0/6.0),	(float) (3.0/6.0),	(float)  (0.0/6.0)},
370 	{(float) (-3.0/6.0),	(float) (0.0/6.0),	(float) (3.0/6.0),	(float)  (0.0/6.0)},
371 	{(float) (1.0/6.0),		(float) (4.0/6.0),	(float) (1.0/6.0),	(float)  (0.0/6.0)}};
372 
373 RtBasis		RiHermiteBasis		= {
374 	{(float) 1 ,	(float) 1 ,		(float)	-3 ,	(float)	1},
375 	{(float) -1 ,	(float) -2 ,	(float)	4 ,		(float)	-1},
376 	{(float) -1,	(float) 1 ,		(float)	0 ,		(float)	0},
377 	{(float) 1 ,	(float) 0 ,		(float)	0 ,		(float)	0}};
378 
379 RtBasis		RiPowerBasis		= {
380 	{(float)  1,	(float)	0,		(float)	0,		(float)	0},
381 	{(float)  0,	(float)	1,		(float)	0,		(float)	0},
382 	{(float)  0,	(float)	0,		(float)	1,		(float)	0},
383 	{(float)  0,	(float)	0,		(float)	0,		(float)	1 }};
384 
385 RtBasis		RiLinearBasis		= {
386 	{(float)  0,	(float)	0,		(float)	0,		(float)	0},
387 	{(float)  0,	(float)	0,		(float)	0,		(float)	0},
388 	{(float)  0,	(float)	0,		(float)	1,		(float)	0},
389 	{(float)  0,	(float)	0,		(float)	0,		(float)	1 }};
390 
391 
392 ////////////////////////////////////////////////////////////////////////
393 //
394 // Action begins here
395 //
396 ////////////////////////////////////////////////////////////////////////
397 const	unsigned int		RENDERMAN_BLOCK						=	1;
398 const	unsigned int		RENDERMAN_XFORM_BLOCK				=	RENDERMAN_BLOCK << 1;
399 const	unsigned int		RENDERMAN_ATTRIBUTE_BLOCK			=	RENDERMAN_XFORM_BLOCK << 1;
400 const	unsigned int		RENDERMAN_WORLD_BLOCK				=	RENDERMAN_ATTRIBUTE_BLOCK << 1;
401 const	unsigned int		RENDERMAN_FRAME_BLOCK				=	RENDERMAN_WORLD_BLOCK << 1;
402 const	unsigned int		RENDERMAN_OBJECT_BLOCK				=	RENDERMAN_FRAME_BLOCK << 1;
403 const	unsigned int		RENDERMAN_MOTION_BLOCK				=	RENDERMAN_OBJECT_BLOCK << 1;
404 const	unsigned int		RENDERMAN_SOLID_PRIMITIVE_BLOCK		=	RENDERMAN_MOTION_BLOCK << 1;
405 const	unsigned int		RENDERMAN_SOLID_INTERSECTION_BLOCK	=	RENDERMAN_SOLID_PRIMITIVE_BLOCK << 1;
406 const	unsigned int		RENDERMAN_SOLID_DIFFERENCE_BLOCK	=	RENDERMAN_SOLID_INTERSECTION_BLOCK << 1;
407 const	unsigned int		RENDERMAN_SOLID_UNION_BLOCK			=	RENDERMAN_SOLID_DIFFERENCE_BLOCK << 1;
408 const	unsigned int		RENDERMAN_RESOURCE_BLOCK			=	RENDERMAN_SOLID_UNION_BLOCK << 1;
409 const	unsigned int		RENDERMAN_ARCHIVE_BLOCK				=	RENDERMAN_RESOURCE_BLOCK << 1;
410 
411 const	unsigned int		RENDERMAN_ALL_BLOCKS				=	RENDERMAN_BLOCK
412 																	| RENDERMAN_XFORM_BLOCK
413 																	| RENDERMAN_ATTRIBUTE_BLOCK
414 																	| RENDERMAN_WORLD_BLOCK
415 																	| RENDERMAN_FRAME_BLOCK
416 																	| RENDERMAN_OBJECT_BLOCK
417 																	| RENDERMAN_MOTION_BLOCK
418 																	| RENDERMAN_SOLID_PRIMITIVE_BLOCK
419 																	| RENDERMAN_SOLID_INTERSECTION_BLOCK
420 																	| RENDERMAN_SOLID_DIFFERENCE_BLOCK
421 																	| RENDERMAN_SOLID_UNION_BLOCK
422 																	| RENDERMAN_RESOURCE_BLOCK
423 																	| RENDERMAN_ARCHIVE_BLOCK;
424 
425 
426 // This is the blocks that options can be changed
427 const	unsigned int		VALID_OPTION_BLOCKS					=	RENDERMAN_BLOCK | RENDERMAN_FRAME_BLOCK | RENDERMAN_ARCHIVE_BLOCK;
428 
429 // This is the blocks that attributes can be changed
430 const	unsigned int		VALID_ATTRIBUTE_BLOCKS				=	RENDERMAN_BLOCK | RENDERMAN_FRAME_BLOCK | RENDERMAN_WORLD_BLOCK | RENDERMAN_ARCHIVE_BLOCK | RENDERMAN_ATTRIBUTE_BLOCK | RENDERMAN_XFORM_BLOCK | RENDERMAN_SOLID_PRIMITIVE_BLOCK | RENDERMAN_OBJECT_BLOCK | RENDERMAN_MOTION_BLOCK | RENDERMAN_RESOURCE_BLOCK;
431 
432 // This is the blocks that xforms can be changed
433 const	unsigned int		VALID_XFORM_BLOCKS					=	RENDERMAN_BLOCK | RENDERMAN_FRAME_BLOCK | RENDERMAN_WORLD_BLOCK | RENDERMAN_ARCHIVE_BLOCK | RENDERMAN_ATTRIBUTE_BLOCK | RENDERMAN_XFORM_BLOCK | RENDERMAN_SOLID_PRIMITIVE_BLOCK | RENDERMAN_OBJECT_BLOCK | RENDERMAN_MOTION_BLOCK | RENDERMAN_RESOURCE_BLOCK;
434 
435 // This is the blocks that primitives can be issued
436 const	unsigned int		VALID_PRIMITIVE_BLOCKS				=	RENDERMAN_WORLD_BLOCK | RENDERMAN_ARCHIVE_BLOCK | RENDERMAN_ATTRIBUTE_BLOCK | RENDERMAN_XFORM_BLOCK | RENDERMAN_SOLID_PRIMITIVE_BLOCK | RENDERMAN_OBJECT_BLOCK | RENDERMAN_MOTION_BLOCK | RENDERMAN_RESOURCE_BLOCK;
437 
438 // Global variables to convert calls to the vector form
439 static	int					initialized			=	FALSE;
440 static	int					nTokens,mTokens;							// Parameter list info
441 static	RtToken				*tokens				=	NULL;
442 static	RtPointer			*values				=	NULL;
443 static	CArray<int>			blocks;										// The block stack
444 static	int					framebufferOnly		=	FALSE;
445 static	int					frameRangeActive	=	FALSE;
446 static	int					frameBegin			=	0;
447 static	int					frameEnd			=	0;
448 static	int					frameStep			=	0;
449 static	int					ignoreFrame			=	FALSE;
450 static	int					currentBlock		=	0;
451 static	int					raytracingInited	=	FALSE;
452 static	int					allowedCommands		=	RENDERMAN_ALL_BLOCKS;
453 static	int					archiveNesting		=	0;
454 
455 		CRiInterface		*savedRenderMan		=	NULL;	// This variable contains the parent context for arhiving
456 		CRiInterface		*renderMan			=	NULL;	// This variable is exported for error reporting
457 		int					ignoreCommand		=	FALSE;	// This variable can be set to force ignore ri commands (used for conditional execution)
458 		int					insideRunProgram	=	FALSE;	// Are we running inside a runprogram context
459 
460 
461 ///////////////////////////////////////////////////////////////////////
462 // Function				:	check
463 // Description			:	Make sure the command is good for a given nesting
464 // Return Value			:	TRUE if the command should be ignored
465 // Comments				:
check(const char * fun,int scope)466 static	inline int		check(const char *fun,int scope) {
467 	if (ignoreFrame | ignoreCommand)	return TRUE;
468 
469 	if (scope & currentBlock & allowedCommands)	return FALSE;
470 
471 	if (allowedCommands != RENDERMAN_FRAME_BLOCK) {
472 		if (renderMan != NULL) {
473 			error(CODE_NESTING,"Bad scope for \"%s\"\n",fun);
474 		}
475 	}
476 
477 	return TRUE;
478 }
479 
480 ///////////////////////////////////////////////////////////////////////
481 // Function				:	extract
482 // Description			:	Extract a parameter from the command string
483 // Return Value			:
484 // Comments				:
extract(char * dest,const char * tag,const char * src)485 static	inline int		extract(char *dest,const char *tag,const char *src) {
486 	const char	*tmp,*tmpEnd;
487 	int			length;
488 
489 	if ((tmp = strstr(src,tag)) != NULL) {
490 		if ((tmpEnd	= strchr(tmp+1,' ')) == NULL)	tmpEnd	=	tmp + strlen(tmp);
491 
492 		length	=	(int) (tmpEnd - tmp - strlen(tag));
493 
494 		strncpy(dest,tmp+strlen(tag),length);
495 		dest[length]	=	'\0';
496 		return	TRUE;
497 	} else {
498 		return	FALSE;
499 	}
500 }
501 
502 ///////////////////////////////////////////////////////////////////////
503 // Function				:	getArgs
504 // Description			:	Read the parameter list and set nTokens,tokens,values
505 // Return Value			:
506 // Comments				:
getArgs(va_list args)507 static	inline	void	getArgs(va_list args) {
508 	RtToken		tmp;
509 	tmp			= va_arg(args,RtToken);
510     nTokens		= 0;
511     while (tmp != RI_NULL) {
512 		tokens[nTokens] = tmp;
513 		values[nTokens] = va_arg(args,RtPointer);
514 		nTokens++;
515 		if (nTokens == mTokens) {
516 			RtToken		*ttokens	=	new RtToken[mTokens + 50];
517 			RtPointer	*tvalues	=	new RtPointer[mTokens + 50];
518 			int			i;
519 
520 			for (i=0;i<nTokens;i++) {
521 				ttokens[i] = tokens[i];
522 				tvalues[i] = values[i];
523 			}
524 
525 			delete [] tokens;
526 			delete [] values;
527 
528 			tokens	=	ttokens;
529 			values	=	tvalues;
530 
531 			mTokens += 50;
532 		}
533 		tmp = va_arg(args,RtToken);
534     }
535 }
536 
537 ///////////////////////////////////////////////////////////////////////
538 // Function				:	RiInit
539 // Description			:	Init the static variables
540 // Return Value			:
541 // Comments				:
RiInit()542 static	void RiInit() {
543 	if (initialized)	return;
544 
545 	nTokens				=	0;
546 	mTokens				=	0;
547 	tokens				=	NULL;
548 	values				=	NULL;
549 	currentBlock		=	0;
550 
551 	nTokens				=	0;
552 	mTokens				=	50;
553 	tokens				=	new RtToken[mTokens];
554 	values				=	new RtPointer[mTokens];
555 	currentBlock		=	RENDERMAN_BLOCK;
556 	initialized			=	TRUE;
557 }
558 
559 ///////////////////////////////////////////////////////////////////////
560 // Function				:	RiTini
561 // Description			:	Ditch the allocated static variables
562 // Return Value			:
563 // Comments				:
RiTini()564 static	void RiTini() {
565 	if (tokens != NULL)				delete [] tokens;
566 	if (values != NULL)				delete [] values;
567 	initialized	= FALSE;
568 }
569 
570 
571 
572 
573 
574 ///////////////////////////////////////////////////////////////////////
575 //
576 // RenderMan Interface begins here
577 //
578 ///////////////////////////////////////////////////////////////////////
RiDeclare(const char * name,const char * declaration)579 EXTERN(RtToken) RiDeclare (const char *name,const char *declaration) {
580 	if (check("RiDeclare",RENDERMAN_ALL_BLOCKS)) return RI_NULL;
581 
582 	renderMan->RiDeclare(name,declaration);
583 
584 	return (RtToken) name;
585 }
586 
RiGetContext(void)587 EXTERN(RtContextHandle)	RiGetContext(void) {
588 	if (check("RiGetContext",RENDERMAN_BLOCK)) return RI_NULL;
589 
590 	return (RtContextHandle) renderMan;
591 }
592 
593 
594 EXTERN(RtVoid)
RiContext(RtContextHandle handle)595 RiContext(RtContextHandle handle) {
596 	if (check("RiContext",RENDERMAN_BLOCK)) return;
597 
598 	renderMan	=	(CRiInterface *) handle;
599 }
600 
601 
602 EXTERN(RtVoid)
RiBegin(RtToken name)603 RiBegin (RtToken name) {
604 	if (renderMan != NULL) {
605 		error(CODE_NESTING,"Already started\n");
606 		return;
607 	}
608 
609 	// Parse the net string
610 	if (name != NULL) {
611 		if (name[0] == '#') {
612 			char	riRibFile[OS_MAX_PATH_LENGTH];
613 			char	riNetString[OS_MAX_PATH_LENGTH];
614 			int		riRib,riNet;
615 
616 			if (extract(riRibFile,	"fbonly:"	,name))	framebufferOnly	=	TRUE;
617 
618 			if (extract(riRibFile,	"frames:"	,name))	{
619 				if		(sscanf(riRibFile,"%d:%d:%d",&frameBegin,&frameStep,&frameEnd) == 3) {
620 					frameRangeActive	=	TRUE;
621 				} else if (sscanf(riRibFile,"%d:%d",&frameBegin,&frameEnd) == 2){
622 					frameStep			=	0;
623 					frameRangeActive	=	TRUE;
624 				} else if (sscanf(riRibFile,"%d",&frameBegin) == 1) {
625 					frameEnd			=	frameBegin;
626 					frameStep			=	0;
627 					frameRangeActive	=	TRUE;
628 				}
629 			}
630 
631 			riRib	=	extract(riRibFile,		"rib:"		,name);
632 			riNet	=	extract(riNetString,	"net:"		,name);
633 
634 			if (riRib & riNet)	renderMan	=	new CRendererContext(riRibFile,riNetString);
635 			else				renderMan	=	new CRendererContext();
636 
637 		} else {
638 			renderMan	=	new CRibOut(name);
639 		}
640 	} else {
641 		char *runProgEnv = osEnvironment("PIXIE_RUNPROGRAM");
642 		if (runProgEnv != NULL) {
643 			// If we're a runprogram, we should be writing out to stdout
644 			renderMan	=	new CRibOut(stdout);
645 			insideRunProgram = TRUE;
646 		} else {
647 			renderMan	=	new CRendererContext();
648 		}
649 	}
650 
651 	// Init the renderer
652 	RiInit();
653 
654 	// Alter the state if we're inside a runprogram
655 	if (insideRunProgram) {
656 		// We're also inside the world block already
657 		currentBlock = RENDERMAN_WORLD_BLOCK;
658 	}
659 
660 
661 	if (framebufferOnly) {
662 		framebufferOnly	=	FALSE;
663 		RiDisplay("ri",RI_FRAMEBUFFER,RI_RGB,RI_NULL);
664 		framebufferOnly	=	TRUE;
665 	}
666 }
667 
668 EXTERN(RtVoid)
RiEnd(void)669 RiEnd (void) {
670 
671 	// Alter the state if we're inside a runprogram
672 	if (insideRunProgram) {
673 		RiArchiveRecord(RI_VERBATIM,"\n\377");
674 		fflush(stdout);
675 		// We're also inside the world block already
676 		currentBlock = RENDERMAN_BLOCK;
677 	}
678 
679 	if (check("RiEnd",RENDERMAN_BLOCK)) return;
680 
681 	if (currentBlock != RENDERMAN_BLOCK) {
682 		error(CODE_NESTING,"Matching RiBegin not found\n");
683 	}
684 
685 	currentBlock	=	blocks.pop();
686 
687 	// Ditch the statics
688 	RiTini();
689 
690 	delete renderMan;
691 	renderMan	=	NULL;
692 }
693 
694 // FrameBegin - End stuff
695 EXTERN(RtVoid)
RiFrameBegin(RtInt number)696 RiFrameBegin (RtInt number) {
697 	if (check("RiFrameBegin",RENDERMAN_BLOCK | RENDERMAN_ARCHIVE_BLOCK)) return;
698 
699 	if (frameRangeActive) {
700 		if ((number < frameBegin) || (number > frameEnd))	ignoreFrame	=	TRUE;
701 		else if (frameStep > 1) {
702 			if (((number - frameBegin) % frameStep) != 0)	ignoreFrame	=	TRUE;
703 		}
704 	}
705 
706 	renderMan->RiFrameBegin(number);
707 
708 	blocks.push(currentBlock);
709 	currentBlock	=	RENDERMAN_FRAME_BLOCK;
710 }
711 
712 EXTERN(RtVoid)
RiFrameEnd(void)713 RiFrameEnd (void) {
714 
715 	ignoreFrame	=	FALSE;
716 
717 	if (check("RiFrameEnd",RENDERMAN_FRAME_BLOCK)) return;
718 
719 	if (currentBlock != RENDERMAN_FRAME_BLOCK) {
720 		error(CODE_NESTING,"Matching RiFrameBegin not found\n");
721 		return;
722 	}
723 
724 	renderMan->RiFrameEnd();
725 
726 	currentBlock	=	blocks.pop();
727 
728 	if (allowedCommands == RENDERMAN_FRAME_BLOCK)	allowedCommands		=	RENDERMAN_ALL_BLOCKS;
729 }
730 
731 // WorldBegin - End stuff
732 EXTERN(RtVoid)
RiWorldBegin(void)733 RiWorldBegin (void) {
734 	if (check("RiWorldBegin",RENDERMAN_BLOCK | RENDERMAN_FRAME_BLOCK | RENDERMAN_ARCHIVE_BLOCK)) return;
735 
736 	renderMan->RiWorldBegin();
737 
738 	blocks.push(currentBlock);
739 	currentBlock	=	RENDERMAN_WORLD_BLOCK;
740 }
741 
742 EXTERN(RtVoid)
RiWorldEnd(void)743 RiWorldEnd (void) {
744 
745 	if (check("RiWorldEnd",RENDERMAN_WORLD_BLOCK)) return;
746 
747 	if (currentBlock != RENDERMAN_WORLD_BLOCK) {
748 		error(CODE_NESTING,"Matching RiWorldBegin not found\n");
749 		return;
750 	}
751 
752 	renderMan->RiWorldEnd();
753 
754 	currentBlock		=	blocks.pop();
755 }
756 
757 EXTERN(RtVoid)
RiFormat(RtInt xres,RtInt yres,RtFloat aspect)758 RiFormat (RtInt xres, RtInt yres, RtFloat aspect) {
759 	if (check("RiFormat",VALID_OPTION_BLOCKS)) return;
760 
761 	renderMan->RiFormat(xres,yres,aspect);
762 }
763 
764 EXTERN(RtVoid)
RiFrameAspectRatio(RtFloat aspect)765 RiFrameAspectRatio (RtFloat aspect) {
766 	if (check("RiFrameAspectRatio",VALID_OPTION_BLOCKS)) return;
767 
768 	renderMan->RiFrameAspectRatio(aspect);
769 }
770 
771 EXTERN(RtVoid)
RiScreenWindow(RtFloat left,RtFloat right,RtFloat bot,RtFloat top)772 RiScreenWindow (RtFloat left, RtFloat right, RtFloat bot, RtFloat top) {
773 	if (check("RiScreenWindow",VALID_OPTION_BLOCKS)) return;
774 
775 	renderMan->RiScreenWindow(left,right,bot,top);
776 }
777 
778 EXTERN(RtVoid)
RiCropWindow(RtFloat xmin,RtFloat xmax,RtFloat ymin,RtFloat ymax)779 RiCropWindow (RtFloat xmin, RtFloat xmax, RtFloat ymin, RtFloat ymax) {
780 	if (check("RiCropWindow",VALID_OPTION_BLOCKS)) return;
781 
782 	renderMan->RiCropWindow(xmin,xmax,ymin,ymax);
783 }
784 
785 EXTERN(RtVoid)
RiProjection(const char * name,...)786 RiProjection (const char *name, ...) {
787 	va_list	args;
788 	va_start(args,name);
789 	getArgs(args);
790 	RiProjectionV(name,nTokens,tokens,values);
791 	va_end(args);
792 
793 }
794 
795 EXTERN(RtVoid)
RiProjectionV(const char * name,RtInt n,RtToken tokens[],RtPointer params[])796 RiProjectionV (const char *name, RtInt n, RtToken tokens[], RtPointer params[]) {
797 	if (check("RiProjection",VALID_OPTION_BLOCKS)) return;
798 
799 	renderMan->RiProjectionV(name,n,tokens,params);
800 }
801 
802 EXTERN(RtVoid)
RiClipping(RtFloat hither,RtFloat yon)803 RiClipping (RtFloat hither, RtFloat yon) {
804 	if (check("RiClipping",VALID_OPTION_BLOCKS)) return;
805 
806 	renderMan->RiClipping(hither,yon);
807 }
808 
809 EXTERN(RtVoid)
RiClippingPlane(RtFloat x,RtFloat y,RtFloat z,RtFloat nx,RtFloat ny,RtFloat nz)810 RiClippingPlane(RtFloat x,RtFloat y,RtFloat z,RtFloat nx,RtFloat ny,RtFloat nz) {
811 	if (check("RiClippingPlane",VALID_OPTION_BLOCKS)) return;
812 
813 	renderMan->RiClippingPlane(x,y,z,nx,ny,nz);
814 }
815 
816 EXTERN(RtVoid)
RiDepthOfField(RtFloat fstop,RtFloat focallength,RtFloat focaldistance)817 RiDepthOfField (RtFloat fstop, RtFloat focallength, RtFloat focaldistance) {
818 	if (check("RiDepthOfField",VALID_OPTION_BLOCKS)) return;
819 
820 	renderMan->RiDepthOfField(fstop,focallength,focaldistance);
821 }
822 
823 EXTERN(RtVoid)
RiShutter(RtFloat smin,RtFloat smax)824 RiShutter (RtFloat smin, RtFloat smax) {
825 	if (check("RiShutter",VALID_OPTION_BLOCKS)) return;
826 
827 	renderMan->RiShutter(smin,smax);
828 }
829 
830 EXTERN(RtVoid)
RiPixelVariance(RtFloat variation)831 RiPixelVariance (RtFloat variation) {
832 	if (check("RiPixelVariance",VALID_OPTION_BLOCKS)) return;
833 
834 	renderMan->RiPixelVariance(variation);
835 }
836 
837 EXTERN(RtVoid)
RiPixelSamples(RtFloat xsamples,RtFloat ysamples)838 RiPixelSamples (RtFloat xsamples, RtFloat ysamples) {
839 	if (check("RiPixelSamples",VALID_OPTION_BLOCKS)) return;
840 
841 	renderMan->RiPixelSamples(xsamples,ysamples);
842 }
843 
844 EXTERN(RtVoid)
RiPixelFilter(RtFilterFunc function,RtFloat xwidth,RtFloat ywidth)845 RiPixelFilter (RtFilterFunc function, RtFloat xwidth, RtFloat ywidth) {
846 	if (check("RiPixelFilter",VALID_OPTION_BLOCKS)) return;
847 
848 	renderMan->RiPixelFilter(function,xwidth,ywidth);
849 }
850 
851 EXTERN(RtVoid)
RiExposure(RtFloat gain,RtFloat gamma)852 RiExposure (RtFloat gain, RtFloat gamma) {
853 	if (check("RiExposure",VALID_OPTION_BLOCKS)) return;
854 
855 	renderMan->RiExposure(gain,gamma);
856 }
857 
858 EXTERN(RtVoid)
RiImager(const char * name,...)859 RiImager (const char *name, ...) {
860 	va_list	args;
861 
862 	va_start(args,name);
863 	getArgs(args);
864 	RiImagerV(name,nTokens,tokens,values);
865 	va_end(args);
866 }
867 
868 EXTERN(RtVoid)
RiImagerV(const char * name,RtInt n,RtToken tokens[],RtPointer params[])869 RiImagerV (const char *name, RtInt n, RtToken tokens[], RtPointer params[]) {
870 	if (check("RiImager",VALID_OPTION_BLOCKS)) return;
871 
872 	renderMan->RiImagerV(name,n,tokens,params);
873 }
874 
875 EXTERN(RtVoid)
RiQuantize(RtToken type,RtInt one,RtInt qmin,RtInt qmax,RtFloat ampl)876 RiQuantize (RtToken type, RtInt one, RtInt qmin, RtInt qmax, RtFloat ampl) {
877 	if (check("RiQuantize",VALID_OPTION_BLOCKS)) return;
878 
879 	renderMan->RiQuantize(type,one,qmin,qmax,ampl);
880 }
881 
882 EXTERN(RtVoid)
RiDisplay(const char * name,RtToken type,RtToken mode,...)883 RiDisplay (const char *name, RtToken type, RtToken mode, ...) {
884 	va_list	args;
885 
886 	va_start(args,mode);
887 	getArgs(args);
888 	RiDisplayV(name,type,mode,nTokens,tokens,values);
889 	va_end(args);
890 }
891 
892 EXTERN(RtVoid)
RiDisplayV(const char * name,RtToken type,RtToken mode,RtInt n,RtToken tokens[],RtPointer params[])893 RiDisplayV (const char *name, RtToken type, RtToken mode,
894 			RtInt n, RtToken tokens[], RtPointer params[]) {
895 	if (check("RiDisplay",VALID_OPTION_BLOCKS)) return;
896 
897 	if (framebufferOnly) return;
898 
899 	renderMan->RiDisplayV(name,type,mode,n,tokens,params);
900 }
901 
902 EXTERN(RtVoid)
RiCustomDisplay(const char * name,RtToken mode,RtDisplayStartFunction startFunc,RtDisplayDataFunction dataFunc,RtDisplayFinishFunction endFunc,...)903 RiCustomDisplay (const char *name, RtToken mode, RtDisplayStartFunction startFunc, RtDisplayDataFunction dataFunc, RtDisplayFinishFunction endFunc, ...) {
904 	va_list	args;
905 
906 	va_start(args,endFunc);
907 	getArgs(args);
908 	RiCustomDisplayV(name,mode,startFunc,dataFunc,endFunc,nTokens,tokens,values);
909 	va_end(args);
910 }
911 
912 EXTERN(RtVoid)
RiCustomDisplayV(const char * name,RtToken mode,RtDisplayStartFunction startFunc,RtDisplayDataFunction dataFunc,RtDisplayFinishFunction endFunc,RtInt n,RtToken tokens[],RtPointer params[])913 RiCustomDisplayV (const char *name, RtToken mode, RtDisplayStartFunction startFunc, RtDisplayDataFunction dataFunc, RtDisplayFinishFunction endFunc, RtInt n, RtToken tokens[], RtPointer params[]) {
914 	if (check("RiCustomDisplay",VALID_OPTION_BLOCKS)) return;
915 
916 	if (framebufferOnly) return;
917 
918 	renderMan->RiCustomDisplayV(name,mode,startFunc,dataFunc,endFunc,n,tokens,params);
919 }
920 
921 EXTERN(RtVoid)
RiDisplayChannel(RtToken channel,...)922 RiDisplayChannel (RtToken channel, ...) {
923 	va_list	args;
924 
925 	va_start(args,channel);
926 	getArgs(args);
927 	RiDisplayChannelV(channel,nTokens,tokens,values);
928 	va_end(args);
929 }
930 
931 EXTERN(RtVoid)
RiDisplayChannelV(RtToken channel,RtInt n,RtToken tokens[],RtPointer params[])932 RiDisplayChannelV (RtToken channel,RtInt n, RtToken tokens[], RtPointer params[]) {
933 	if (check("RiDisplayChannel",VALID_OPTION_BLOCKS)) return;
934 
935 	renderMan->RiDisplayChannelV(channel,n,tokens,params);
936 }
937 
938 
939 // Various filters
940 
941 EXTERN(RtFloat)
RiGaussianFilter(RtFloat x,RtFloat y,RtFloat xwidth,RtFloat ywidth)942 RiGaussianFilter (RtFloat x, RtFloat y, RtFloat xwidth, RtFloat ywidth) {
943 	x		=	2*x / xwidth;
944 	y		=	2*y / ywidth;
945 
946 	return expf(-2 * (x*x + y*y));
947 }
948 
949 EXTERN(RtFloat)
RiBoxFilter(RtFloat x,RtFloat y,RtFloat xwidth,RtFloat ywidth)950 RiBoxFilter (RtFloat x, RtFloat y, RtFloat xwidth, RtFloat ywidth) {
951 	return 1;
952 }
953 
954 EXTERN(RtFloat)
RiTriangleFilter(RtFloat x,RtFloat y,RtFloat xwidth,RtFloat ywidth)955 RiTriangleFilter (RtFloat x, RtFloat y, RtFloat xwidth, RtFloat ywidth) {
956 	if (x<0.0) x = -x;
957     if (y<0.0) y = -y;
958 
959 	xwidth	*=	0.5f;
960 	ywidth	*=	0.5f;
961 
962 	if (x > y) {
963 		return (RtFloat) (xwidth-x) / xwidth;
964 	} else {
965 		return (RtFloat) (ywidth-y) / ywidth;
966 	}
967 
968 
969 }
970 
971 EXTERN(RtFloat)
RiCatmullRomFilter(RtFloat x,RtFloat y,RtFloat xwidth,RtFloat ywidth)972 RiCatmullRomFilter (RtFloat x, RtFloat y, RtFloat xwidth, RtFloat ywidth) {
973    float r2 = (x*x + y*y);
974    float r = sqrtf(r2);
975 
976    if (r < 1.0f) {
977 	   return	(float) (1.5f*r*r2 - 2.5f*r2 + 1.0f);
978    } else if (r < 2.0f) {
979 	   return	(float) (-0.5f*r*r2 + 2.5f*r2 - 4.0f*r + 2.0f);
980    } else {
981 	   return 0;
982    }
983 }
984 
985 EXTERN(RtFloat)
RiBlackmanHarrisFilter(RtFloat x,RtFloat y,RtFloat xwidth,RtFloat ywidth)986 RiBlackmanHarrisFilter (RtFloat x, RtFloat y, RtFloat xwidth, RtFloat ywidth) {
987    float xc = x/xwidth;
988    float yc = y/ywidth;
989    float r2 = (xc*xc + yc*yc);
990    float r = 0.5f-sqrtf(r2);
991 
992    const float N  = 1;
993    const float a0 = 0.35875f;
994    const float a1 = 0.48829f;
995    const float a2 = 0.14128f;
996    const float a3 = 0.01168f;
997 
998    if (r <= N*0.5f) {
999 	   return	(float) (a0 - a1*cosf(2*((float) C_PI)*r/N) + a2*cosf(4*((float) C_PI)*r/N) - a3*cosf(6*((float) C_PI)*r/N));
1000    } else {
1001        return	0;
1002    }
1003 }
1004 
1005 EXTERN(RtFloat)
RiMitchellFilter(RtFloat x,RtFloat y,RtFloat xwidth,RtFloat ywidth)1006 RiMitchellFilter( RtFloat x, RtFloat y, RtFloat xwidth, RtFloat ywidth ) {
1007 	x	/=	xwidth;
1008 	y	/=	ywidth;
1009 
1010 #define	B	1/3.0f
1011 #define	C	1/3.0f
1012 
1013 	x	=	fabsf(2.f * x);
1014 	if (x > 1.f)	x	= ((-B - 6*C) * x*x*x + (6*B + 30*C) * x*x + (-12*B - 48*C) * x + (8*B + 24*C)) * (1.f/6.f);
1015 	else			x	= ((12 - 9*B - 6*C) * x*x*x + (-18 + 12*B + 6*C) * x*x + (6 - 2*B)) * (1.f/6.f);
1016 
1017 	y	=	fabsf(2.f * y);
1018 	if (y > 1.f)	y	= ((-B - 6*C) * y*y*y + (6*B + 30*C) * y*y + (-12*B - 48*C) * y + (8*B + 24*C)) * (1.f/6.f);
1019 	else			y	= ((12 - 9*B - 6*C) * y*y*y + (-18 + 12*B + 6*C) * y*y + (6 - 2*B)) * (1.f/6.f);
1020 
1021 #undef B
1022 #undef C
1023 
1024 	return	x*y;
1025 }
1026 
1027 EXTERN(RtFloat)
RiSincFilter(RtFloat x,RtFloat y,RtFloat xwidth,RtFloat ywidth)1028 RiSincFilter (RtFloat x, RtFloat y, RtFloat xwidth, RtFloat ywidth) {
1029 
1030 	if ( x != 0.0 )	{
1031 		x *= (float) C_PI;
1032 		x = cosf( 0.5f * x / xwidth ) * sinf( x ) / x;
1033 	} else {
1034 		x = 1.0;
1035 	}
1036 
1037 	if ( y != 0.0 ) {
1038 		y *= (float) C_PI;
1039 		y = cosf( 0.5f * y / ywidth ) * sinf( y ) / y;
1040 	} else {
1041 		y = 1.0;
1042 	}
1043 
1044 	return x*y;
1045 }
1046 
1047 EXTERN(RtFloat)
RiBesselFilter(RtFloat x,RtFloat y,RtFloat xwidth,RtFloat ywidth)1048 RiBesselFilter (RtFloat x, RtFloat y, RtFloat xwidth, RtFloat ywidth) {
1049 	const float x2 = x * x;
1050 	const float y2 = y * y;
1051 
1052 	if ( x2+y2 < 0.0001f )
1053 		return 1.0f;
1054 
1055 	const float w = x2 / ( xwidth * xwidth ) + y2 / ( ywidth * ywidth );
1056 	const float d = sqrtf( x2 + y2 );
1057 	return (float) (j1( d*2 )/d);
1058 }
1059 
1060 
1061 EXTERN(RtFloat)
RiDiskFilter(RtFloat x,RtFloat y,RtFloat xwidth,RtFloat ywidth)1062 RiDiskFilter (RtFloat x, RtFloat y, RtFloat xwidth, RtFloat ywidth) {
1063 	const float xc = x / xwidth;
1064 	const float yc = y / ywidth;
1065 	const float d = xc * xc + yc * yc;
1066 
1067 	return ( d <= 0.25f )? 1.0f : 0.0f;
1068 }
1069 
1070 #ifdef _WINDOWS
1071 //
1072 // Computation of the complementary error function erfc(x).
1073 //
1074 // The algorithm is based on a Chebyshev fit as denoted in
1075 // Numerical Recipes 2nd ed. on p. 214 (W.H.Press et al.).
1076 //
1077 // The fractional error is always less than 1.2e-7.
1078 //
1079 //
1080 // The parameters of the Chebyshev fit
1081 //
erfc(double x)1082 inline double erfc(double x) {
1083 	const double a1 = -1.26551223, a2 = 1.00002368,
1084 	a3 = 0.37409196, a4 = 0.09678418,
1085 	a5 = -0.18628806, a6 = 0.27886807,
1086 	a7 = -1.13520398, a8 = 1.48851587,
1087 	a9 = -0.82215223, a10 = 0.17087277;
1088 	//
1089 	double v = 1; // The return value
1090 	double z = fabs(x);
1091 	//
1092 	if (z <= 0) return v; // erfc(0)=1
1093 	//
1094 	double t = 1/(1+0.5*z);
1095 	//
1096 	v = t*exp((-z*z) +a1+t*(a2+t*(a3+t*(a4+t*(a5+t*(a6+t*(a7+t*(a8+t*(a9+t*a10)))))))));
1097 	//
1098 	if (x < 0) v = 2-v; // erfc(-x)=2-erfc(x)
1099 	//
1100 	return v;
1101 }
1102 #endif
1103 
1104 
1105 EXTERN(RtFloat)
RiGaussianStepFilter(RtFloat _t,RtFloat _edge,RtFloat _w)1106 RiGaussianStepFilter(RtFloat _t,RtFloat _edge,RtFloat _w) {
1107 	const double t = _t,edge = _edge,w = _w;
1108 	double res = 0.0;
1109 
1110 	res = (1.0/2.0)*erfc( (2.0*sqrt(2.0)*(edge-t))/w );
1111 
1112 	return (RtFloat) res;
1113 }
1114 
1115 EXTERN(RtFloat)
RiCatmullRomStepFilter(RtFloat _t,RtFloat _edge,RtFloat _w)1116 RiCatmullRomStepFilter(RtFloat _t,RtFloat _edge,RtFloat _w) {
1117 	const double t = _t,edge = _edge,w = _w;
1118 	double res = 0.0;
1119 
1120 	if (edge==t && edge>=(t+w) && edge<(t+2.0*w)) {
1121 		res = -1.0/24.0;
1122 	} else if (edge<t && (edge+w)<=t && (edge+2.0*w)<=t) {
1123 		res = 1.0;
1124 	} else if ((edge+w)==t && (edge+2.0*w)>t && edge<t) {
1125 		res = 25.0/24.0;
1126 	} else if (edge>t && edge>(t+w) && edge<(t+2.0*w)) {
1127 		res = ((3.0*edge-3.0*t-2.0*w) * pow(edge-t-2.0*w,3.0)) / (24.0*pow(w,4.0));
1128 	} else if ((edge+2.0*w)>t && edge<t && (edge+w)<t) {
1129 		res = (-3.0*pow(edge-t,4.0) - 20.0*pow(edge-t,3.0)*w - 48.0*pow(edge-t,2.0)*w*w +
1130 				 48.0*(-edge+t)*pow(w,3.0) + 8.0*pow(w,4.0))/(24.0*pow(w,4.0));
1131 	} else if ((edge+w)>t && edge<t && (edge+2.0*w)<=t) {
1132 		res	= (-edge+t)/w		+ (3.0*pow(edge-t,4))/(8.0*pow(w,4.0))
1133 								+ (5.0*pow(edge-t,3))/(6.0*pow(w,3.0))
1134 								+ (11.0)/24.0;
1135 	} else if (edge<(t+w) && (edge>t || (edge>=t && edge<(t+2.0*w)))) {
1136 		res = (-edge+t)/w		- (3.0*pow(edge-t,4))/(8.0*pow(w,4.0))
1137 								+ (5.0*pow(edge-t,3))/(6.0*pow(w,3.0))
1138 								+ 1.0/2.0;
1139 	} else if ((edge+w)>t && (edge+2.0*w)>t && edge<t) {
1140 		res = (-edge+t)/w		+ (3.0*pow(edge-t,4))/(8.0*pow(w,4.0))
1141 								+ (5.0*pow(edge-t,3))/(6.0*pow(w,3.0))
1142 								+ 1.0/2.0;
1143 	} else if (edge==t && edge>=(t+2.0*w) && edge<(t+w)) {
1144 		res = 13.0/24.0;
1145 	}
1146 
1147 	return (RtFloat) res;
1148 }
1149 
1150 EXTERN(RtFloat)
RiMitchellStepFilter(RtFloat _t,RtFloat _edge,RtFloat _w)1151 RiMitchellStepFilter(RtFloat _t,RtFloat _edge,RtFloat _w) {
1152 	const double t = _t,edge = _edge,w = _w;
1153 	double res = 0.0;
1154 
1155 	if (edge==t && edge>=(t+w) && edge<(t+2.0*w)) {
1156 		res = -1.0/72.0;
1157 	} else if (edge<t && (edge+w)<=t && (edge+2.0*w)<=t) {
1158 		res = 1.0;
1159 	} else if ((edge+w)==t && (edge+2.0*w)>t && edge<t) {
1160 		res = 73.0/72.0;
1161 	} else if (edge>t && edge>(t+w) && edge<(t+2.0*w)) {
1162 		res = ((7.0*edge-7.0*t-6.0*w) * pow(edge-t-2.0*w,3.0)) / (72.0*pow(w,4.0));
1163 	} else if ((edge+2.0*w)>t && edge<t && (edge+w)<t) {
1164 		res = (-7.0*pow(edge-t,4.0) - 48.0*pow(edge-t,3.0)*w - 120.0*pow(edge-t,2.0)*w*w +
1165 				 128.0*(-edge+t)*pow(w,3.0) + 24.0*pow(w,4.0))/(72.0*pow(w,4.0));
1166 	} else if ((edge+w)>t && edge<t && (edge+2.0*w)<=t) {
1167 		res	= (64.0*(-edge+t)/(w*72.0)) + (35.0/72.0)
1168 								+ ( (21.0*pow(edge-t,4))
1169 								+   (48.0*w*pow(edge-t,3)) ) /(72.0*pow(w,4.0));
1170 	} else if (edge<(t+w) && (edge>t || (edge>=t && edge<(t+2.0*w)))) {
1171 		res	= (64.0*(-edge+t)/(w*72.0)) + (36.0/72.0)
1172 								+ ( (-21.0*pow(edge-t,4))
1173 								+   (48.0*w*pow(edge-t,3)) ) /(72.0*pow(w,4.0));
1174 	} else if ((edge+w)>t && (edge+2.0*w)>t && edge<t) {
1175 		res	= (64.0*(-edge+t)/(w*72.0)) + (36.0/72.0)
1176 								+ ( (21.0*pow(edge-t,4))
1177 								+   (48.0*w*pow(edge-t,3)) ) /(72.0*pow(w,4.0));
1178 	} else if (edge==t && edge>=(t+2.0*w) && edge<(t+w)) {
1179 		res = 37.0/72.0;
1180 	}
1181 
1182 	return (RtFloat) res;
1183 }
1184 
1185 
1186 EXTERN(RtFloat)
RiTriangleStepFilter(RtFloat _t,RtFloat _edge,RtFloat _w)1187 RiTriangleStepFilter(RtFloat _t,RtFloat _edge,RtFloat _w) {
1188 	const double t = _t,edge = _edge,w = _w;
1189 	double res = 0.0;
1190 
1191 	if ((edge-t+w)<= 0 && (edge-t) < 0) {
1192 		res = 1.0;
1193 	} else if ((edge-t)<0 && (edge-t+w) > 0) {
1194 		res = (-edge*edge + 2.0*edge*t - t*t - 2.0*edge*w + 2.0*t*w + w*w)/(2.0*w*w);
1195 	} else if ((edge-t)>=0 && (edge-t-w) < 0) {
1196 		res = ( edge*edge - 2.0*edge*t + t*t - 2.0*edge*w + 2.0*t*w + w*w)/(2.0*w*w);
1197 	}
1198 
1199 	return (RtFloat) res;
1200 }
1201 
1202 EXTERN(RtFloat)
RiBoxStepFilter(RtFloat _t,RtFloat _edge,RtFloat _w)1203 RiBoxStepFilter(RtFloat _t,RtFloat _edge,RtFloat _w) {
1204 	const double t = _t,edge = _edge,w = _w;
1205 	double res = 0.0;
1206 
1207 	if ((edge-t)<0 && (2.0*edge-2*t+w) <= 0) {
1208 		res = 1.0;
1209 	} else if (((2.0*edge-2.0*t+w)>0 && (edge-t)<0) || ((edge-t)>=0 && (2.0*edge-2.0*t-w)<0)) {
1210 		res = (-2.0*edge + 2.0*t + w)/(2.0*w);
1211 	}
1212 
1213 	return (RtFloat) res;
1214 }
1215 
1216 
1217 
1218 EXTERN(RtVoid)
RiHider(RtToken type,...)1219 RiHider (RtToken type, ...) {
1220 	va_list	args;
1221 
1222 	va_start(args,type);
1223 	getArgs(args);
1224 	RiHiderV(type,nTokens,tokens,values);
1225 	va_end(args);
1226 }
1227 
1228 EXTERN(RtVoid)
RiHiderV(RtToken type,RtInt n,RtToken tokens[],RtPointer params[])1229 RiHiderV (RtToken type, RtInt n, RtToken tokens[], RtPointer params[]) {
1230 	if (check("RiHider",VALID_OPTION_BLOCKS)) return;
1231 
1232 	renderMan->RiHiderV(type,n,tokens,params);
1233 }
1234 
1235 EXTERN(RtVoid)
RiColorSamples(RtInt N,RtFloat * nRGB,RtFloat * RGBn)1236 RiColorSamples (RtInt N, RtFloat *nRGB, RtFloat *RGBn) {
1237 	if (check("RiColorSamples",VALID_OPTION_BLOCKS)) return;
1238 
1239 	renderMan->RiColorSamples(N,nRGB,RGBn);
1240 }
1241 
1242 EXTERN(RtVoid)
RiRelativeDetail(RtFloat relativedetail)1243 RiRelativeDetail (RtFloat relativedetail) {
1244 	if (check("RiRelativeDetail",VALID_OPTION_BLOCKS)) return;
1245 
1246 	renderMan->RiRelativeDetail(relativedetail);
1247 }
1248 
1249 EXTERN(RtVoid)
RiOption(const char * name,...)1250 RiOption (const char *name, ...) {
1251 	va_list	args;
1252 
1253 	// init if necessary (for gz options)
1254 	if (!initialized) RiInit();
1255 
1256 	va_start(args,name);
1257 	getArgs(args);
1258 	RiOptionV(name,nTokens,tokens,values);
1259 	va_end(args);
1260 }
1261 
1262 
1263 EXTERN(RtVoid)
RiOptionV(const char * name,RtInt n,RtToken tokens[],RtPointer params[])1264 RiOptionV (const char *name, RtInt n, RtToken tokens[], RtPointer params[]) {
1265 
1266 	// This section allows us to parse RibOut options before RiBegin, to match the standard
1267 	if (renderMan == NULL) {
1268 		extern int preferCompressedRibOut;
1269 
1270 		// Check the rib format options
1271 		if (strcmp(name,RI_RIB) == 0) {
1272 			for (int i=0;i<n;i++) {
1273 				if (strcmp(tokens[i],RI_COMPRESSION) == 0) {
1274 					char	*val	=	((char **) params[i])[0];
1275 					if (strcmp(val,"gzip") == 0) {
1276 						preferCompressedRibOut	=	TRUE;
1277 					} else if (strcmp(val,"none") == 0) {
1278 						preferCompressedRibOut	=	FALSE;
1279 					} else {
1280 						error(CODE_BADTOKEN,"Unknown compression type \"%s\"\n",val);
1281 					}
1282 				}
1283 			}
1284 		}
1285 		return;
1286 	}
1287 
1288 	if (check("RiOption",VALID_OPTION_BLOCKS)) return;
1289 
1290 	renderMan->RiOptionV(name,n,tokens,params);
1291 }
1292 
1293 
1294 EXTERN(RtVoid)
RiAttributeBegin(void)1295 RiAttributeBegin (void) {
1296 	if (check("RiAttributeBegin",RENDERMAN_BLOCK | RENDERMAN_FRAME_BLOCK | RENDERMAN_WORLD_BLOCK | RENDERMAN_ATTRIBUTE_BLOCK | RENDERMAN_XFORM_BLOCK | RENDERMAN_SOLID_PRIMITIVE_BLOCK | RENDERMAN_RESOURCE_BLOCK | RENDERMAN_ARCHIVE_BLOCK)) return;
1297 
1298 	renderMan->RiAttributeBegin();
1299 
1300 	blocks.push(currentBlock);
1301 	currentBlock	=	RENDERMAN_ATTRIBUTE_BLOCK;
1302 }
1303 
1304 EXTERN(RtVoid)
RiAttributeEnd(void)1305 RiAttributeEnd (void) {
1306 	if (check("RiAttributeEnd",RENDERMAN_ATTRIBUTE_BLOCK)) return;
1307 
1308 	if (currentBlock != RENDERMAN_ATTRIBUTE_BLOCK) {
1309 		error(CODE_NESTING,"Matching RiAttributeBegin not found\n");
1310 		return;
1311 	}
1312 
1313 	renderMan->RiAttributeEnd();
1314 
1315 	currentBlock	=	blocks.pop();
1316 }
1317 
1318 EXTERN(RtVoid)
RiColor(RtColor Cs)1319 RiColor (RtColor Cs) {
1320 	if (check("RiColor",VALID_ATTRIBUTE_BLOCKS)) return;
1321 
1322 	renderMan->RiColor(Cs);
1323 }
1324 
1325 EXTERN(RtVoid)
RiOpacity(RtColor Cs)1326 RiOpacity (RtColor Cs) {
1327 	if (check("RiOpacity",VALID_ATTRIBUTE_BLOCKS)) return;
1328 
1329 	renderMan->RiOpacity(Cs);
1330 }
1331 
1332 EXTERN(RtVoid)
RiTextureCoordinates(RtFloat s1,RtFloat t1,RtFloat s2,RtFloat t2,RtFloat s3,RtFloat t3,RtFloat s4,RtFloat t4)1333 RiTextureCoordinates (RtFloat s1, RtFloat t1, RtFloat s2, RtFloat t2,
1334 					  RtFloat s3, RtFloat t3, RtFloat s4, RtFloat t4) {
1335 	if (check("RiTextureCoordinates",VALID_ATTRIBUTE_BLOCKS)) return;
1336 
1337 	renderMan->RiTextureCoordinates(s1,t1,s2,t2,s3,t3,s4,t4);
1338 }
1339 
1340 
1341 EXTERN(RtLightHandle)
RiLightSource(const char * name,...)1342 RiLightSource (const char *name, ...) {
1343 	RtLightHandle	handle;
1344 	va_list			args;
1345 
1346 	va_start(args,name);
1347 	getArgs(args);
1348 	handle	=	RiLightSourceV(name,nTokens,tokens,values);
1349 	va_end(args);
1350 
1351 	return handle;
1352 }
1353 
1354 EXTERN(RtLightHandle)
RiLightSourceV(const char * name,RtInt n,RtToken tokens[],RtPointer params[])1355 RiLightSourceV (const char *name, RtInt n, RtToken tokens[], RtPointer params[]) {
1356 	if (check("RiLightSource",VALID_ATTRIBUTE_BLOCKS)) return NULL;
1357 
1358 	return (RtLightHandle) renderMan->RiLightSourceV(name,n,tokens,params);
1359 }
1360 
1361 EXTERN(RtLightHandle)
RiAreaLightSource(const char * name,...)1362 RiAreaLightSource (const char *name, ...) {
1363 	RtLightHandle	handle;
1364 	va_list			args;
1365 
1366 	va_start(args,name);
1367 	getArgs(args);
1368 	handle	=	RiAreaLightSourceV(name,nTokens,tokens,values);
1369 	va_end(args);
1370 
1371 	return handle;
1372 }
1373 
1374 EXTERN(RtLightHandle)
RiAreaLightSourceV(const char * name,RtInt n,RtToken tokens[],RtPointer params[])1375 RiAreaLightSourceV (const char *name, RtInt n,
1376 					RtToken tokens[], RtPointer params[]) {
1377 	if (check("RiAreaLightSource",VALID_ATTRIBUTE_BLOCKS)) return NULL;
1378 
1379 	return (RtLightHandle) renderMan->RiAreaLightSourceV(name,n,tokens,params);
1380 }
1381 
1382 
1383 EXTERN(RtVoid)
RiIlluminate(RtLightHandle light,RtBoolean onoff)1384 RiIlluminate (RtLightHandle light, RtBoolean onoff) {
1385 	if (check("RiIlluminate",VALID_ATTRIBUTE_BLOCKS)) return;
1386 
1387 	renderMan->RiIlluminate(light,onoff);
1388 }
1389 
1390 EXTERN(RtVoid)
RiSurface(const char * name,...)1391 RiSurface (const char *name, ...) {
1392 	va_list			args;
1393 
1394 	va_start(args,name);
1395 	getArgs(args);
1396 	RiSurfaceV(name,nTokens,tokens,values);
1397 	va_end(args);
1398 }
1399 
1400 EXTERN(RtVoid)
RiSurfaceV(const char * name,RtInt n,RtToken tokens[],RtPointer params[])1401 RiSurfaceV (const char *name, RtInt n, RtToken tokens[], RtPointer params[]) {
1402 	if (check("RiSurface",VALID_ATTRIBUTE_BLOCKS)) return;
1403 
1404 	renderMan->RiSurfaceV(name,n,tokens,params);
1405 }
1406 
1407 EXTERN(RtVoid)
RiAtmosphere(const char * name,...)1408 RiAtmosphere (const char *name, ...) {
1409 	va_list			args;
1410 
1411 	va_start(args,name);
1412 	getArgs(args);
1413 	RiAtmosphereV(name,nTokens,tokens,values);
1414 	va_end(args);
1415 }
1416 
1417 EXTERN(RtVoid)
RiAtmosphereV(const char * name,RtInt n,RtToken tokens[],RtPointer params[])1418 RiAtmosphereV (const char *name, RtInt n, RtToken tokens[], RtPointer params[]) {
1419 	if (check("RiAtmosphere",VALID_ATTRIBUTE_BLOCKS)) return;
1420 
1421 	renderMan->RiAtmosphereV(name,n,tokens,params);
1422 }
1423 
1424 EXTERN(RtVoid)
RiInterior(const char * name,...)1425 RiInterior (const char *name, ...) {
1426 	va_list			args;
1427 
1428 	va_start(args,name);
1429 	getArgs(args);
1430 	RiInteriorV(name,nTokens,tokens,values);
1431 	va_end(args);
1432 }
1433 
1434 EXTERN(RtVoid)
RiInteriorV(const char * name,RtInt n,RtToken tokens[],RtPointer params[])1435 RiInteriorV (const char *name, RtInt n, RtToken tokens[], RtPointer params[]) {
1436 	if (check("RiInterior",VALID_ATTRIBUTE_BLOCKS)) return;
1437 
1438 	renderMan->RiInteriorV(name,n,tokens,params);
1439 }
1440 
1441 EXTERN(RtVoid)
RiExterior(const char * name,...)1442 RiExterior (const char *name, ...) {
1443 	va_list			args;
1444 
1445 	va_start(args,name);
1446 	getArgs(args);
1447 	RiExteriorV(name,nTokens,tokens,values);
1448 	va_end(args);
1449 }
1450 
1451 EXTERN(RtVoid)
RiExteriorV(const char * name,RtInt n,RtToken tokens[],RtPointer params[])1452 RiExteriorV (const char *name, RtInt n, RtToken tokens[], RtPointer params[]) {
1453 	if (check("RiExterior",VALID_ATTRIBUTE_BLOCKS)) return;
1454 
1455 	renderMan->RiExteriorV(name,n,tokens,params);
1456 }
1457 
1458 EXTERN(RtVoid)
RiShadingRate(RtFloat size)1459 RiShadingRate (RtFloat size) {
1460 	if (check("RiShadingRate",VALID_ATTRIBUTE_BLOCKS)) return;
1461 
1462 	renderMan->RiShadingRate(size);
1463 }
1464 
1465 EXTERN(RtVoid)
RiShadingInterpolation(RtToken type)1466 RiShadingInterpolation (RtToken type) {
1467 	if (check("RiShadingInterpolation",VALID_ATTRIBUTE_BLOCKS)) return;
1468 
1469 	renderMan->RiShadingInterpolation(type);
1470 }
1471 
1472 EXTERN(RtVoid)
RiMatte(RtBoolean onoff)1473 RiMatte (RtBoolean onoff) {
1474 	if (check("RiMatte",VALID_ATTRIBUTE_BLOCKS)) return;
1475 
1476 	renderMan->RiMatte(onoff);
1477 }
1478 
1479 
1480 EXTERN(RtVoid)
RiBound(RtBound bound)1481 RiBound (RtBound bound) {
1482 	if (check("RiBound",VALID_ATTRIBUTE_BLOCKS)) return;
1483 
1484 	renderMan->RiBound(bound);
1485 }
1486 
1487 EXTERN(RtVoid)
RiDetail(RtBound bound)1488 RiDetail (RtBound bound) {
1489 	if (check("RiDetail",VALID_ATTRIBUTE_BLOCKS)) return;
1490 
1491 	renderMan->RiDetail(bound);
1492 }
1493 
1494 EXTERN(RtVoid)
RiDetailRange(RtFloat minvis,RtFloat lowtran,RtFloat uptran,RtFloat maxvis)1495 RiDetailRange (RtFloat minvis, RtFloat lowtran,
1496 			   RtFloat uptran, RtFloat maxvis) {
1497 	if (check("RiDetailRange",VALID_ATTRIBUTE_BLOCKS)) return;
1498 
1499 	renderMan->RiDetailRange(minvis,lowtran,uptran,maxvis);
1500 }
1501 
1502 EXTERN(RtVoid)
RiGeometricApproximation(RtToken type,RtFloat value)1503 RiGeometricApproximation (RtToken type, RtFloat value) {
1504 	if (check("RiGeometricApproximation",VALID_ATTRIBUTE_BLOCKS)) return;
1505 
1506 	renderMan->RiGeometricApproximation(type,value);
1507 }
1508 
1509 EXTERN(RtVoid)
RiGeometricRepresentation(RtToken type)1510 RiGeometricRepresentation (RtToken type) {
1511 	if (check("RiGeometricRepresentation",VALID_ATTRIBUTE_BLOCKS)) return;
1512 
1513 	renderMan->RiGeometricRepresentation(type);
1514 }
1515 
1516 EXTERN(RtVoid)
RiOrientation(RtToken orientation)1517 RiOrientation (RtToken orientation) {
1518 	if (check("RiOrientation",VALID_ATTRIBUTE_BLOCKS)) return;
1519 
1520 	renderMan->RiOrientation(orientation);
1521 }
1522 
1523 EXTERN(RtVoid)
RiReverseOrientation(void)1524 RiReverseOrientation (void) {
1525 	if (check("RiReverseOrientation",VALID_ATTRIBUTE_BLOCKS)) return;
1526 
1527 	renderMan->RiReverseOrientation();
1528 }
1529 
1530 EXTERN(RtVoid)
RiSides(RtInt nsides)1531 RiSides (RtInt nsides) {
1532 	if (check("RiSides",VALID_ATTRIBUTE_BLOCKS)) return;
1533 
1534 	renderMan->RiSides(nsides);
1535 }
1536 
1537 
1538 EXTERN(RtVoid)
RiIdentity(void)1539 RiIdentity (void) {
1540 	if (check("RiIdentity",VALID_XFORM_BLOCKS)) return;
1541 
1542 	renderMan->RiIdentity();
1543 }
1544 
1545 EXTERN(RtVoid)
RiTransform(RtMatrix transform)1546 RiTransform (RtMatrix transform) {
1547 	if (check("RiTransform",VALID_XFORM_BLOCKS)) return;
1548 
1549 	renderMan->RiTransform(transform);
1550 }
1551 
1552 EXTERN(RtVoid)
RiConcatTransform(RtMatrix transform)1553 RiConcatTransform (RtMatrix transform) {
1554 	if (check("RiConcatTransform",VALID_XFORM_BLOCKS)) return;
1555 
1556 	renderMan->RiConcatTransform(transform);
1557 }
1558 
1559 EXTERN(RtVoid)
RiPerspective(RtFloat fov)1560 RiPerspective (RtFloat fov) {
1561 	if (check("RiPerspective",VALID_XFORM_BLOCKS)) return;
1562 
1563 	renderMan->RiPerspective(fov);
1564 }
1565 
1566 EXTERN(RtVoid)
RiTranslate(RtFloat dx,RtFloat dy,RtFloat dz)1567 RiTranslate (RtFloat dx, RtFloat dy, RtFloat dz) {
1568 	if (check("RiTranslate",VALID_XFORM_BLOCKS)) return;
1569 
1570 	renderMan->RiTranslate(dx,dy,dz);
1571 }
1572 
1573 EXTERN(RtVoid)
RiRotate(RtFloat angle,RtFloat dx,RtFloat dy,RtFloat dz)1574 RiRotate (RtFloat angle, RtFloat dx, RtFloat dy, RtFloat dz) {
1575 	if (check("RiRotate",VALID_XFORM_BLOCKS)) return;
1576 
1577 	renderMan->RiRotate(angle,dx,dy,dz);
1578 }
1579 
1580 EXTERN(RtVoid)
RiScale(RtFloat dx,RtFloat dy,RtFloat dz)1581 RiScale (RtFloat dx, RtFloat dy, RtFloat dz) {
1582 	if (check("RiScale",VALID_XFORM_BLOCKS)) return;
1583 
1584 	renderMan->RiScale(dx,dy,dz);
1585 }
1586 
1587 EXTERN(RtVoid)
RiSkew(RtFloat angle,RtFloat dx1,RtFloat dy1,RtFloat dz1,RtFloat dx2,RtFloat dy2,RtFloat dz2)1588 RiSkew (RtFloat angle, RtFloat dx1, RtFloat dy1, RtFloat dz1,
1589 		RtFloat dx2, RtFloat dy2, RtFloat dz2) {
1590 	if (check("RiSkew",VALID_XFORM_BLOCKS)) return;
1591 
1592 	renderMan->RiSkew(angle,dx1,dy1,dz1,dx2,dy2,dz2);
1593 }
1594 
1595 EXTERN(RtVoid)
RiDeformation(const char * name,...)1596 RiDeformation (const char *name, ...) {
1597 	va_list			args;
1598 
1599 	va_start(args,name);
1600 	getArgs(args);
1601 	RiDeformationV(name,nTokens,tokens,values);
1602 	va_end(args);
1603 }
1604 
1605 EXTERN(RtVoid)
RiDeformationV(const char * name,RtInt n,RtToken tokens[],RtPointer params[])1606 RiDeformationV (const char *name, RtInt n, RtToken tokens[], RtPointer params[]) {
1607 	if (check("RiDeformation",VALID_XFORM_BLOCKS)) return;
1608 
1609 	renderMan->RiDeformationV(name,n,tokens,params);
1610 }
1611 
1612 EXTERN(RtVoid)
RiDisplacement(const char * name,...)1613 RiDisplacement (const char *name, ...) {
1614 	va_list			args;
1615 
1616 	va_start(args,name);
1617 	getArgs(args);
1618 	RiDisplacementV(name,nTokens,tokens,values);
1619 	va_end(args);
1620 }
1621 
1622 EXTERN(RtVoid)
RiDisplacementV(const char * name,RtInt n,RtToken tokens[],RtPointer params[])1623 RiDisplacementV (const char *name, RtInt n, RtToken tokens[], RtPointer params[]) {
1624 
1625 	// We treat displacement as an attribute, not an xform
1626 	if (check("RiDisplacement",VALID_ATTRIBUTE_BLOCKS)) return;
1627 
1628 	renderMan->RiDisplacementV(name,n,tokens,params);
1629 }
1630 
1631 EXTERN(RtVoid)
RiCoordinateSystem(RtToken space)1632 RiCoordinateSystem (RtToken space) {
1633 	if (check("RiCoordinateSystem",VALID_XFORM_BLOCKS)) return;
1634 
1635 	renderMan->RiCoordinateSystem(space);
1636 }
1637 
1638 EXTERN(RtVoid)
RiCoordSysTransform(RtToken space)1639 RiCoordSysTransform (RtToken space) {
1640 	if (check("RiCoordSysTransform",VALID_XFORM_BLOCKS)) return;
1641 
1642 	renderMan->RiCoordSysTransform(space);
1643 }
1644 
1645 
1646 EXTERN(RtPoint *)
RiTransformPoints(RtToken fromspace,RtToken tospace,RtInt npoints,RtPoint * points)1647 RiTransformPoints (RtToken fromspace, RtToken tospace,
1648 							RtInt npoints, RtPoint *points) {
1649 	if (check("RiTransformPoints",RENDERMAN_ALL_BLOCKS)) return NULL;
1650 
1651 	return renderMan->RiTransformPoints(fromspace,tospace,npoints,points);
1652 }
1653 
1654 
1655 EXTERN(RtVoid)
RiTransformBegin(void)1656 RiTransformBegin (void) {
1657 	if (check("RiTransformBegin",VALID_XFORM_BLOCKS)) return;
1658 
1659 	renderMan->RiTransformBegin();
1660 
1661 	blocks.push(currentBlock);
1662 	currentBlock	=	RENDERMAN_XFORM_BLOCK;
1663 }
1664 
1665 EXTERN(RtVoid)
RiTransformEnd(void)1666 RiTransformEnd (void) {
1667 	if (check("RiTransformEnd",RENDERMAN_XFORM_BLOCK)) return;
1668 
1669 	if (currentBlock != RENDERMAN_XFORM_BLOCK) {
1670 		error(CODE_NESTING,"Matching RiTransformBegin not found\n");
1671 		return;
1672 	}
1673 
1674 	renderMan->RiTransformEnd();
1675 
1676 	currentBlock		=	blocks.pop();
1677 }
1678 
1679 
1680 EXTERN(RtVoid)
RiAttribute(const char * name,...)1681 RiAttribute (const char *name, ...) {
1682 	va_list			args;
1683 
1684 	va_start(args,name);
1685 	getArgs(args);
1686 	RiAttributeV(name,nTokens,tokens,values);
1687 	va_end(args);
1688 }
1689 
1690 EXTERN(RtVoid)
RiAttributeV(const char * name,RtInt n,RtToken tokens[],RtPointer params[])1691 RiAttributeV (const char *name, RtInt n, RtToken tokens[], RtPointer params[]) {
1692 	if (check("RiAttribute",VALID_ATTRIBUTE_BLOCKS)) return;
1693 
1694 	renderMan->RiAttributeV(name,n,tokens,params);
1695 }
1696 
1697 EXTERN(RtVoid)
RiPolygon(RtInt nvertices,...)1698 RiPolygon (RtInt nvertices, ...) {
1699 	va_list			args;
1700 
1701 	va_start(args,nvertices);
1702 	getArgs(args);
1703 	RiPolygonV(nvertices,nTokens,tokens,values);
1704 	va_end(args);
1705 }
1706 
1707 EXTERN(RtVoid)
RiPolygonV(RtInt nvertices,RtInt n,RtToken tokens[],RtPointer params[])1708 RiPolygonV (RtInt nvertices, RtInt n, RtToken tokens[], RtPointer params[]) {
1709 	if (check("RiPolygon",VALID_PRIMITIVE_BLOCKS)) return;
1710 
1711 	renderMan->RiPolygonV(nvertices,n,tokens,params);
1712 }
1713 
1714 EXTERN(RtVoid)
RiGeneralPolygon(RtInt nloops,RtInt * nverts,...)1715 RiGeneralPolygon (RtInt nloops, RtInt *nverts, ...) {
1716 	va_list			args;
1717 
1718 	va_start(args,nverts);
1719 	getArgs(args);
1720 	RiGeneralPolygonV(nloops,nverts,nTokens,tokens,values);
1721 	va_end(args);
1722 }
1723 
1724 EXTERN(RtVoid)
RiGeneralPolygonV(RtInt nloops,RtInt * nverts,RtInt n,RtToken tokens[],RtPointer params[])1725 RiGeneralPolygonV (RtInt nloops, RtInt *nverts,
1726 				   RtInt n, RtToken tokens[], RtPointer params[]) {
1727 	if (check("RiGeneralPolygon",VALID_PRIMITIVE_BLOCKS)) return;
1728 
1729 	renderMan->RiGeneralPolygonV(nloops,nverts,n,tokens,params);
1730 }
1731 
1732 EXTERN(RtVoid)
RiPointsPolygons(RtInt npolys,RtInt * nverts,RtInt * verts,...)1733 RiPointsPolygons (RtInt npolys, RtInt *nverts, RtInt *verts, ...) {
1734 	va_list			args;
1735 
1736 	va_start(args,verts);;
1737 	getArgs(args);
1738 	RiPointsPolygonsV(npolys,nverts,verts,nTokens,tokens,values);
1739 	va_end(args);
1740 }
1741 
1742 EXTERN(RtVoid)
RiPointsPolygonsV(RtInt npolys,RtInt * nverts,RtInt * verts,RtInt n,RtToken tokens[],RtPointer params[])1743 RiPointsPolygonsV (RtInt npolys, RtInt *nverts, RtInt *verts,
1744 				   RtInt n, RtToken tokens[], RtPointer params[]) {
1745 	if (check("RiPointsPolygons",VALID_PRIMITIVE_BLOCKS)) return;
1746 
1747 	renderMan->RiPointsPolygonsV(npolys,nverts,verts,n,tokens,params);
1748 }
1749 
1750 EXTERN(RtVoid)
RiPointsGeneralPolygons(RtInt npolys,RtInt * nloops,RtInt * nverts,RtInt * verts,...)1751 RiPointsGeneralPolygons (RtInt npolys, RtInt *nloops,
1752 						 RtInt *nverts, RtInt *verts, ...) {
1753 	va_list			args;
1754 
1755 	va_start(args,verts);
1756 	getArgs(args);
1757 	RiPointsGeneralPolygonsV(npolys,nloops,nverts,verts,nTokens,tokens,values);
1758 	va_end(args);
1759 }
1760 
1761 EXTERN(RtVoid)
RiPointsGeneralPolygonsV(RtInt npolys,RtInt * nloops,RtInt * nverts,RtInt * verts,RtInt n,RtToken tokens[],RtPointer params[])1762 RiPointsGeneralPolygonsV (RtInt npolys, RtInt *nloops,
1763 			     RtInt *nverts, RtInt *verts,
1764 				 RtInt n, RtToken tokens[], RtPointer params[]) {
1765 	if (check("RiPointsGeneralPolygons",VALID_PRIMITIVE_BLOCKS)) return;
1766 
1767 	renderMan->RiPointsGeneralPolygonsV(npolys,nloops,nverts,verts,n,tokens,params);
1768 }
1769 
1770 EXTERN(RtVoid)
RiBasis(RtBasis ubasis,RtInt ustep,RtBasis vbasis,RtInt vstep)1771 RiBasis (RtBasis ubasis, RtInt ustep, RtBasis vbasis, RtInt vstep) {
1772 	if (check("RiBasis",VALID_ATTRIBUTE_BLOCKS)) return;
1773 
1774 	renderMan->RiBasis(ubasis,ustep,vbasis,vstep);
1775 }
1776 
1777 EXTERN(RtVoid)
RiPatch(RtToken type,...)1778 RiPatch (RtToken type, ...) {
1779 	va_list	args;
1780 
1781 	va_start(args,type);
1782 	getArgs(args);
1783 	RiPatchV(type,nTokens,tokens,values);
1784 	va_end(args);
1785 }
1786 
1787 EXTERN(RtVoid)
RiPatchV(RtToken type,RtInt n,RtToken tokens[],RtPointer params[])1788 RiPatchV (RtToken type, RtInt n, RtToken tokens[], RtPointer params[]) {
1789 	if (check("RiPatch",VALID_PRIMITIVE_BLOCKS)) return;
1790 
1791 	renderMan->RiPatchV(type,n,tokens,params);
1792 }
1793 
1794 EXTERN(RtVoid)
RiPatchMesh(RtToken type,RtInt nu,RtToken uwrap,RtInt nv,RtToken vwrap,...)1795 RiPatchMesh (RtToken type, RtInt nu, RtToken uwrap,
1796 			 RtInt nv, RtToken vwrap, ...) {
1797 	va_list	args;
1798 
1799 	va_start(args,vwrap);
1800 	getArgs(args);
1801 	RiPatchMeshV(type,nu,uwrap,nv,vwrap,nTokens,tokens,values);
1802 	va_end(args);
1803 }
1804 
1805 EXTERN(RtVoid)
RiPatchMeshV(RtToken type,RtInt nu,RtToken uwrap,RtInt nv,RtToken vwrap,RtInt n,RtToken tokens[],RtPointer params[])1806     RiPatchMeshV (RtToken type, RtInt nu, RtToken uwrap, RtInt nv,
1807 		  RtToken vwrap, RtInt n, RtToken tokens[], RtPointer params[]) {
1808 	if (check("RiPatchMesh",VALID_PRIMITIVE_BLOCKS)) return;
1809 
1810 	renderMan->RiPatchMeshV(type,nu,uwrap,nv,vwrap,n,tokens,params);
1811 }
1812 
1813 EXTERN(RtVoid)
RiNuPatch(RtInt nu,RtInt uorder,RtFloat * uknot,RtFloat umin,RtFloat umax,RtInt nv,RtInt vorder,RtFloat * vknot,RtFloat vmin,RtFloat vmax,...)1814     RiNuPatch (RtInt nu, RtInt uorder, RtFloat *uknot,
1815 	       RtFloat umin, RtFloat umax, RtInt nv, RtInt vorder,
1816 		   RtFloat *vknot, RtFloat vmin, RtFloat vmax, ...) {
1817 	va_list	args;
1818 
1819 	va_start(args,vmax);
1820 	getArgs(args);
1821 	RiNuPatchV(nu,uorder,uknot,umin,umax,nv,vorder,vknot,vmin,vmax,nTokens,tokens,values);
1822 	va_end(args);
1823 
1824 }
1825 
1826 EXTERN(RtVoid)
RiNuPatchV(RtInt nu,RtInt uorder,RtFloat * uknot,RtFloat umin,RtFloat umax,RtInt nv,RtInt vorder,RtFloat * vknot,RtFloat vmin,RtFloat vmax,RtInt n,RtToken tokens[],RtPointer params[])1827     RiNuPatchV (RtInt nu, RtInt uorder, RtFloat *uknot,
1828 		RtFloat umin, RtFloat umax, RtInt nv, RtInt vorder,
1829 		RtFloat *vknot, RtFloat vmin, RtFloat vmax,
1830 		RtInt n, RtToken tokens[], RtPointer params[]) {
1831 	if (check("RiNuPatch",VALID_PRIMITIVE_BLOCKS)) return;
1832 
1833 	renderMan->RiNuPatchV(nu,uorder,uknot,umin,umax,nv,vorder,vknot,vmin,vmax,n,tokens,params);
1834 }
1835 
1836 EXTERN(RtVoid)
RiTrimCurve(RtInt nloops,RtInt * ncurves,RtInt * order,RtFloat * knot,RtFloat * amin,RtFloat * amax,RtInt * n,RtFloat * u,RtFloat * v,RtFloat * w)1837     RiTrimCurve (RtInt nloops, RtInt *ncurves, RtInt *order,
1838 		 RtFloat *knot, RtFloat *amin, RtFloat *amax,
1839 		 RtInt *n, RtFloat *u, RtFloat *v, RtFloat *w) {
1840 
1841 	// Trim curve is an attribute
1842 	if (check("RiTrimCurve",VALID_ATTRIBUTE_BLOCKS)) return;
1843 
1844 	renderMan->RiTrimCurve(nloops,ncurves,order,knot,amin,amax,n,u,v,w);
1845 }
1846 
1847 EXTERN(RtVoid)
RiSphere(RtFloat radius,RtFloat zmin,RtFloat zmax,RtFloat thetamax,...)1848     RiSphere (RtFloat radius, RtFloat zmin,
1849 	RtFloat zmax, RtFloat thetamax, ...) {
1850 	va_list	args;
1851 
1852 	va_start(args,thetamax);
1853 	getArgs(args);
1854 	RiSphereV(radius,zmin,zmax,thetamax,nTokens,tokens,values);
1855 	va_end(args);
1856 }
1857 
1858 EXTERN(RtVoid)
RiSphereV(RtFloat radius,RtFloat zmin,RtFloat zmax,RtFloat thetamax,RtInt n,RtToken tokens[],RtPointer params[])1859     RiSphereV (RtFloat radius, RtFloat zmin, RtFloat zmax, RtFloat thetamax,
1860 	RtInt n, RtToken tokens[], RtPointer params[]) {
1861 	if (check("RiSphere",VALID_PRIMITIVE_BLOCKS)) return;
1862 
1863 	renderMan->RiSphereV(radius,zmin,zmax,thetamax,n,tokens,params);
1864 }
1865 
1866 EXTERN(RtVoid)
RiCone(RtFloat height,RtFloat radius,RtFloat thetamax,...)1867 RiCone (RtFloat height, RtFloat radius, RtFloat thetamax, ...) {
1868 	va_list	args;
1869 
1870 	va_start(args,thetamax);
1871 	getArgs(args);
1872 	RiConeV(height,radius,thetamax,nTokens,tokens,values);
1873 	va_end(args);
1874 }
1875 
1876 EXTERN(RtVoid)
RiConeV(RtFloat height,RtFloat radius,RtFloat thetamax,RtInt n,RtToken tokens[],RtPointer params[])1877     RiConeV (RtFloat height, RtFloat radius, RtFloat thetamax,
1878 	RtInt n, RtToken tokens[], RtPointer params[]) {
1879 	if (check("RiCone",VALID_PRIMITIVE_BLOCKS)) return;
1880 
1881 	renderMan->RiConeV(height,radius,thetamax,n,tokens,params);
1882 }
1883 
1884 EXTERN(RtVoid)
RiCylinder(RtFloat radius,RtFloat zmin,RtFloat zmax,RtFloat thetamax,...)1885     RiCylinder (RtFloat radius, RtFloat zmin, RtFloat zmax,
1886 	RtFloat thetamax, ...) {
1887 	va_list	args;
1888 
1889 	va_start(args,thetamax);
1890 	getArgs(args);
1891 	RiCylinderV(radius,zmin,zmax,thetamax,nTokens,tokens,values);
1892 	va_end(args);
1893 }
1894 
1895 EXTERN(RtVoid)
RiCylinderV(RtFloat radius,RtFloat zmin,RtFloat zmax,RtFloat thetamax,RtInt n,RtToken tokens[],RtPointer params[])1896     RiCylinderV (RtFloat radius, RtFloat zmin, RtFloat zmax, RtFloat thetamax,
1897 	RtInt n, RtToken tokens[], RtPointer params[]) {
1898 	if (check("RiCylinder",VALID_PRIMITIVE_BLOCKS)) return;
1899 
1900 	renderMan->RiCylinderV(radius,zmin,zmax,thetamax,n,tokens,params);
1901 }
1902 
1903 EXTERN(RtVoid)
RiHyperboloid(RtPoint point1,RtPoint point2,RtFloat thetamax,...)1904 RiHyperboloid (RtPoint point1, RtPoint point2, RtFloat thetamax, ...) {
1905 	va_list	args;
1906 
1907 	va_start(args,thetamax);
1908 	getArgs(args);
1909 	RiHyperboloidV(point1,point2,thetamax,nTokens,tokens,values);
1910 	va_end(args);
1911 
1912 }
1913 
1914 EXTERN(RtVoid)
RiHyperboloidV(RtPoint point1,RtPoint point2,RtFloat thetamax,RtInt n,RtToken tokens[],RtPointer params[])1915     RiHyperboloidV (RtPoint point1, RtPoint point2, RtFloat thetamax,
1916 	RtInt n, RtToken tokens[], RtPointer params[]) {
1917 	if (check("RiHyperboloid",VALID_PRIMITIVE_BLOCKS)) return;
1918 
1919 	renderMan->RiHyperboloidV(point1,point2,thetamax,n,tokens,params);
1920 }
1921 
1922 EXTERN(RtVoid)
RiParaboloid(RtFloat rmax,RtFloat zmin,RtFloat zmax,RtFloat thetamax,...)1923     RiParaboloid (RtFloat rmax, RtFloat zmin,
1924 		  RtFloat zmax, RtFloat thetamax, ...) {
1925 	va_list	args;
1926 
1927 	va_start(args,thetamax);
1928 	getArgs(args);
1929 	RiParaboloidV(rmax,zmin,zmax,thetamax,nTokens,tokens,values);
1930 	va_end(args);
1931 
1932 }
1933 
1934 EXTERN(RtVoid)
RiParaboloidV(RtFloat radius,RtFloat zmin,RtFloat zmax,RtFloat thetamax,RtInt n,RtToken tokens[],RtPointer params[])1935     RiParaboloidV (RtFloat radius, RtFloat zmin, RtFloat zmax, RtFloat thetamax,
1936 	RtInt n, RtToken tokens[], RtPointer params[]) {
1937 	if (check("RiParaboloid",VALID_PRIMITIVE_BLOCKS)) return;
1938 
1939 	renderMan->RiParaboloidV(radius,zmin,zmax,thetamax,n,tokens,params);
1940 }
1941 
1942 EXTERN(RtVoid)
RiDisk(RtFloat height,RtFloat radius,RtFloat thetamax,...)1943 RiDisk (RtFloat height, RtFloat radius, RtFloat thetamax, ...) {
1944 	va_list	args;
1945 
1946 	va_start(args,thetamax);
1947 	getArgs(args);
1948 	RiDiskV(height,radius,thetamax,nTokens,tokens,values);
1949 	va_end(args);
1950 }
1951 
1952 EXTERN(RtVoid)
RiDiskV(RtFloat height,RtFloat radius,RtFloat thetamax,RtInt n,RtToken tokens[],RtPointer params[])1953     RiDiskV (RtFloat height, RtFloat radius, RtFloat thetamax,
1954 	RtInt n, RtToken tokens[], RtPointer params[]) {
1955 	if (check("RiDisk",VALID_PRIMITIVE_BLOCKS)) return;
1956 
1957 	renderMan->RiDiskV(height,radius,thetamax,n,tokens,params);
1958 }
1959 
1960 EXTERN(RtVoid)
RiTorus(RtFloat majorrad,RtFloat minorrad,RtFloat phimin,RtFloat phimax,RtFloat thetamax,...)1961     RiTorus (RtFloat majorrad, RtFloat minorrad, RtFloat phimin,
1962 	RtFloat phimax, RtFloat thetamax, ...) {
1963 	va_list	args;
1964 
1965 	va_start(args,thetamax);
1966 	getArgs(args);
1967 	RiTorusV(majorrad,minorrad,phimin,phimax,thetamax,nTokens,tokens,values);
1968 	va_end(args);
1969 }
1970 
1971 EXTERN(RtVoid)
RiTorusV(RtFloat majorrad,RtFloat minorrad,RtFloat phimin,RtFloat phimax,RtFloat thetamax,RtInt n,RtToken tokens[],RtPointer params[])1972     RiTorusV (RtFloat majorrad, RtFloat minorrad, RtFloat phimin,
1973 	     RtFloat phimax, RtFloat thetamax,
1974 		 RtInt n, RtToken tokens[], RtPointer params[]) {
1975 	if (check("RiTorus",VALID_PRIMITIVE_BLOCKS)) return;
1976 
1977 	renderMan->RiTorusV(majorrad,minorrad,phimin,phimax,thetamax,n,tokens,params);
1978 }
1979 
1980 EXTERN(RtVoid)
RiCurves(RtToken degree,RtInt ncurves,RtInt nverts[],RtToken wrap,...)1981 RiCurves (RtToken degree, RtInt ncurves, RtInt nverts[], RtToken wrap, ...) {
1982 	va_list	args;
1983 
1984 	va_start(args,wrap);
1985 	getArgs(args);
1986 	RiCurvesV(degree,ncurves,nverts,wrap,nTokens,tokens,values);
1987 	va_end(args);
1988 }
1989 
1990 
1991 EXTERN(RtVoid)
RiCurvesV(RtToken degree,RtInt ncurves,RtInt nverts[],RtToken wrap,RtInt n,RtToken tokens[],RtPointer params[])1992 RiCurvesV (RtToken degree, RtInt ncurves, RtInt nverts[], RtToken wrap,
1993 		   RtInt n, RtToken tokens[], RtPointer params[]) {
1994 	if (check("RiCurves",VALID_PRIMITIVE_BLOCKS)) return;
1995 
1996 	renderMan->RiCurvesV(degree,ncurves,nverts,wrap,n,tokens,params);
1997 }
1998 
1999 EXTERN(RtVoid)
RiProcedural(void * data,RtBound bound,RtVoid (* subdivfunc)(void *,RtFloat),RtVoid (* freefunc)(void *))2000     RiProcedural (void *data, RtBound bound,
2001 		  RtVoid (*subdivfunc) (void *, RtFloat),RtVoid (*freefunc) (void *)) {
2002 	if (check("RiProcedural",VALID_PRIMITIVE_BLOCKS)) return;
2003 
2004 	renderMan->RiProcedural(data,bound,subdivfunc,freefunc);
2005 }
2006 
2007 
2008 EXTERN(RtVoid)
RiGeometry(RtToken type,...)2009 RiGeometry (RtToken type, ...) {
2010 	va_list	args;
2011 
2012 	va_start(args,type);
2013 	getArgs(args);
2014 	RiGeometryV(type,nTokens,tokens,values);
2015 	va_end(args);
2016 }
2017 
2018 EXTERN(RtVoid)
RiGeometryV(RtToken type,RtInt n,RtToken tokens[],RtPointer params[])2019 RiGeometryV (RtToken type, RtInt n, RtToken tokens[], RtPointer params[]) {
2020 	if (check("RiGeometry",VALID_PRIMITIVE_BLOCKS)) return;
2021 
2022 	renderMan->RiGeometryV(type,n,tokens,params);
2023 }
2024 
2025 EXTERN(RtVoid)
RiPoints(RtInt npts,...)2026 RiPoints (RtInt npts,...) {
2027 	va_list	args;
2028 
2029 	va_start(args,npts);
2030 	getArgs(args);
2031 	RiPointsV(npts,nTokens,tokens,values);
2032 	va_end(args);
2033 }
2034 
2035 EXTERN(RtVoid)
RiPointsV(RtInt npts,RtInt n,RtToken tokens[],RtPointer params[])2036 RiPointsV (RtInt npts, RtInt n, RtToken tokens[], RtPointer params[]) {
2037 	if (check("RiPoints",VALID_PRIMITIVE_BLOCKS)) return;
2038 
2039 	renderMan->RiPointsV(npts,n,tokens,params);
2040 }
2041 
2042 EXTERN(RtVoid)
RiSubdivisionMesh(RtToken scheme,RtInt nfaces,RtInt nvertices[],RtInt vertices[],RtInt ntags,RtToken tags[],RtInt nargs[],RtInt intargs[],RtFloat floatargs[],...)2043     RiSubdivisionMesh (RtToken scheme, RtInt nfaces,
2044 		       RtInt nvertices[], RtInt vertices[],
2045 		       RtInt ntags, RtToken tags[], RtInt nargs[],
2046 			   RtInt intargs[], RtFloat floatargs[], ...) {
2047 	va_list	args;
2048 
2049 	va_start(args,floatargs);
2050 	getArgs(args);
2051 	RiSubdivisionMeshV(scheme,nfaces,nvertices,vertices,ntags,tags,nargs,intargs,floatargs,nTokens,tokens,values);
2052 	va_end(args);
2053 }
2054 
2055 EXTERN(RtVoid)
RiSubdivisionMeshV(RtToken scheme,RtInt nfaces,RtInt nvertices[],RtInt vertices[],RtInt ntags,RtToken tags[],RtInt nargs[],RtInt intargs[],RtFloat floatargs[],RtInt n,RtToken tokens[],RtPointer params[])2056     RiSubdivisionMeshV (RtToken scheme, RtInt nfaces,
2057 		       RtInt nvertices[], RtInt vertices[],
2058 		       RtInt ntags, RtToken tags[], RtInt nargs[],
2059 		       RtInt intargs[], RtFloat floatargs[],
2060 			   RtInt n, RtToken tokens[], RtPointer params[]) {
2061 	if (check("RiSubdivisionMesh",VALID_PRIMITIVE_BLOCKS)) return;
2062 
2063 	renderMan->RiSubdivisionMeshV(scheme,nfaces,nvertices,vertices,ntags,tags,nargs,intargs,floatargs,n,tokens,params);
2064 }
2065 
2066 EXTERN(RtVoid)
RiBlobby(RtInt nleaf,RtInt ncode,RtInt code[],RtInt nflt,RtFloat flt[],RtInt nstr,RtString str[],...)2067     RiBlobby (RtInt nleaf, RtInt ncode, RtInt code[],
2068 	RtInt nflt, RtFloat flt[], RtInt nstr, RtString str[], ...) {
2069 	va_list	args;
2070 
2071 	va_start(args,str);
2072 	getArgs(args);
2073 	RiBlobbyV(nleaf,ncode,code,nflt,flt,nstr,str,nTokens,tokens,values);
2074 	va_end(args);
2075 }
2076 
2077 EXTERN(RtVoid)
RiBlobbyV(RtInt nleaf,RtInt ncode,RtInt code[],RtInt nflt,RtFloat flt[],RtInt nstr,RtString str[],RtInt n,RtToken tokens[],RtPointer params[])2078     RiBlobbyV (RtInt nleaf, RtInt ncode, RtInt code[],
2079 	       RtInt nflt, RtFloat flt[], RtInt nstr, RtString str[],
2080 		   RtInt n, RtToken tokens[], RtPointer params[]) {
2081 
2082 	if (check("RiBlobby",VALID_PRIMITIVE_BLOCKS)) return;
2083 
2084 	renderMan->RiBlobbyV(nleaf,ncode,code,nflt,flt,nstr,str,n,tokens,params);
2085 }
2086 
2087 
2088 EXTERN(RtVoid)
RiProcDelayedReadArchive(void * data,RtFloat detail)2089 RiProcDelayedReadArchive (void *data, RtFloat detail) {
2090 	CDelayedData	*delayed	=	(CDelayedData *) data;
2091 
2092 	renderMan->RiReadArchiveV(delayed->generator,NULL,0,NULL,NULL);
2093 
2094 #if 0
2095 	int			cubePoints[]	=	{	0, 0, 0,
2096 										1, 0, 0,
2097 										1, 0, 1,
2098 										0, 0, 1,
2099 
2100 										0, 1, 0,
2101 										1, 1, 0,
2102 										1, 1, 1,
2103 										0, 1, 1,
2104 
2105 										0, 0, 0,
2106 										1, 0, 0,
2107 										1, 1, 0,
2108 										0, 1, 0,
2109 
2110 										0, 0, 1,
2111 										1, 0, 1,
2112 										1, 1, 1,
2113 										0, 1, 1,
2114 
2115 										0, 0, 0,
2116 										0, 1, 0,
2117 										0, 1, 1,
2118 										0, 0, 1,
2119 
2120 										1, 0, 0,
2121 										1, 1, 0,
2122 										1, 1, 1,
2123 										1, 0, 1
2124 										};
2125 
2126 	vector bmin,bmax;
2127 	interpolatev(bmin,delayed->bmin,delayed->bmax,0.05);
2128 	interpolatev(bmax,delayed->bmin,delayed->bmax,0.95);
2129 
2130 	float	*P = (float*) alloca(6*4*3*sizeof(float));
2131 	int 	*Ind = (int*) alloca(6*4*sizeof(int));
2132 	int 	*NV = (int*) alloca(6*sizeof(int));
2133 
2134 	int		*cInd = Ind;
2135 	float	*cP = P;
2136 
2137 	#define pt() 							\
2138 		*cP++ = cp[0] ? bmin[0] : bmax[0];	\
2139 		*cP++ = cp[1] ? bmin[1] : bmax[1];	\
2140 		*cP++ = cp[2] ? bmin[2] : bmax[2];	\
2141 		*cInd++ = i;						\
2142 		cp += 3;
2143 
2144 	int *cp = cubePoints;
2145 	for(int i=0;i<6*4;i++) {
2146 		pt();
2147 	}
2148 	for(int i=0;i<6;i++)
2149 		NV[i] = 4;
2150 
2151 	RiAttributeBegin();
2152 	vector Cs,Os;
2153 	initv(Cs,rand()/((float)RAND_MAX),rand()/((float)RAND_MAX),rand()/((float)RAND_MAX));
2154 	initv(Os,0.2);
2155 	RiOpacity(Os);
2156 	RiColor(Cs);
2157 	RiSides(2);
2158 	RiPointsPolygons( 6, NV, Ind, "P", P, NULL);
2159 	RiAttributeEnd();
2160 #endif
2161 }
2162 
2163 
2164 EXTERN(RtVoid)
RiProcRunProgram(void * data,RtFloat detail)2165 RiProcRunProgram (void *data, RtFloat detail) {
2166 	CDelayedData	*delayed	=	(CDelayedData *) data;
2167 
2168 	// GSHTODO: cache the open pipes and close on last RunProgram
2169 
2170 #ifdef _WINDOWS
2171 	char			progString[256];
2172 	char			tmpFile[512];
2173 
2174 	// GSHTODO: do proper redirection.  See
2175 	// http://support.microsoft.com/default.aspx?scid=kb;en-us;190351
2176 
2177 	tmpnam(tmpFile);
2178 	sprintf(progString,"echo %f [%s] | %s > %s",detail,delayed->helper,delayed->generator,tmpFile);
2179 	system(progString);
2180 	renderMan->RiReadArchiveV(tmpFile,NULL,0,NULL,NULL);
2181 	osDeleteFile(tmpFile);
2182 #else
2183 	int				fdin[2];
2184 	int				fdout[2];
2185 
2186 	if ((pipe(fdin) != -1) && (pipe(fdout) != -1)) {
2187 		int cpid;
2188 
2189 		if ( (cpid = fork()) >= 0) {
2190 
2191 			if (cpid != 0) {
2192 				char	tmp[128];
2193 
2194 				// we are the parent rndr
2195 
2196 				close(fdout[0]);			// close the ends the client uses
2197 				close(fdin[1]);
2198 
2199 				// repoen as files, close the fd versions
2200 				sprintf(tmp,"|%d",fdin[0]);
2201 				FILE	*out	= fdopen(fdout[1],"wb");
2202 
2203 				if (out != NULL) {
2204 					// This write may SIGPIPE out - so guard against it
2205 					void (*oldHandler)(int) = signal(SIGPIPE,SIG_IGN);
2206 
2207 					fprintf(out,"%f [%s]\n",detail,delayed->helper);
2208 					fflush(out);		// ensure the output is synchronized
2209 					fclose(out);		// send eof (remove this when we keep pipe open)
2210 					out = NULL;
2211 
2212 					signal(SIGPIPE,oldHandler);
2213 
2214 					renderMan->RiReadArchiveV(tmp,NULL,0,NULL,NULL);
2215 				} else {
2216 					error(CODE_SYSTEM,"Failed to redirect input or output for \"%s\"\n",delayed->generator);
2217 				}
2218 				// close the output handle (it may already be shut)
2219 				if (out	!= NULL) fclose(out);
2220 			} else {
2221 				// We are the child process
2222 
2223 				close(fdout[1]);		// we'll read from fdout[0], fdout[1] belongs to parent
2224 				close(fdin[0]);			// we'll write to fdin[1], fdin[0] belongs to parent
2225 
2226 				dup2(fdout[0],STDIN_FILENO);	close(fdout[0]);// remap stdin and stdout
2227 				dup2(fdin[1],STDOUT_FILENO);	close(fdin[1]);
2228 
2229 				putenv((char *) "PIXIE_RUNPROGRAM=1");
2230 
2231 				// launch the program (via shell to do cmdline parsing / breaking up!)
2232 				if (system(delayed->generator) != 0) {
2233 					error(CODE_SYSTEM,"Failed to execute \"%s\"\n",delayed->generator);
2234 				}
2235 
2236 				_exit(0);	// call _exit() NOT exit() to avoid flushing stdio twice
2237 			}
2238 		} else {
2239 			error(CODE_SYSTEM,"Failed to execute \"%s\"\n",delayed->generator);
2240 			close(fdin[0]);
2241 			close(fdin[1]);
2242 			close(fdout[0]);
2243 			close(fdout[1]);
2244 		}
2245 	} else {
2246 		error(CODE_SYSTEM,"Failed to open communication for \"%s\"\n",delayed->generator);
2247 		close(fdin[0]);
2248 		close(fdin[1]);
2249 		close(fdout[0]);
2250 		close(fdout[1]);
2251 	}
2252 #endif
2253 }
2254 
2255 EXTERN(RtVoid)
RiProcDynamicLoad(void * data,RtFloat detail)2256 RiProcDynamicLoad (void *data, RtFloat detail) {
2257 	CDelayedData	*delayed	=	(CDelayedData *) data;
2258 	void			*module;
2259 
2260 	module	=	osLoadModule(delayed->generator);
2261 
2262 	if (module != NULL) {
2263 		// Extract information
2264 		RtPointer			blindData;
2265 
2266 		typedef	RtPointer	(*FunConvertParameter)(char *);
2267 		typedef	void		(*FunSubdivide)(RtPointer,RtFloat);
2268 		typedef	void		(*FunFree)(RtPointer);
2269 
2270 		FunConvertParameter	ConvertParameter;
2271 		FunSubdivide		Subdivide;
2272 		FunFree				Free;
2273 
2274 		ConvertParameter	=	(FunConvertParameter)	osResolve(module,"ConvertParameters");
2275 		Subdivide			=	(FunSubdivide)			osResolve(module,"Subdivide");
2276 		Free				=	(FunFree)				osResolve(module,"Free");
2277 
2278 		blindData			=	NULL;
2279 		if (ConvertParameter	!= NULL)	blindData	=	ConvertParameter(delayed->helper);
2280 		if (Subdivide			!= NULL)	Subdivide(blindData,detail);
2281 		if (Free				!= NULL)	Free(blindData);
2282 
2283 		//osUnloadModule(module);
2284 	} else {
2285 		error(CODE_NOFILE,"The delayed module \"%s\" is not found: %s\n",delayed->generator,osModuleError());
2286 	}
2287 }
2288 
RiProcFree(void * data)2289 EXTERN(RtVoid)	RiProcFree(void *data) {
2290 	CDelayedData	*delayed	=	(CDelayedData *) data;
2291 
2292 	delete delayed;
2293 }
2294 
2295 EXTERN(RtVoid)
RiSolidBegin(RtToken type)2296 RiSolidBegin (RtToken type) {
2297 	if (check("RiSolidBegin",RENDERMAN_WORLD_BLOCK | RENDERMAN_ATTRIBUTE_BLOCK | RENDERMAN_XFORM_BLOCK | RENDERMAN_SOLID_PRIMITIVE_BLOCK | RENDERMAN_RESOURCE_BLOCK | RENDERMAN_ARCHIVE_BLOCK)) return;
2298 
2299 	renderMan->RiSolidBegin(type);
2300 }
2301 
2302 EXTERN(RtVoid)
RiSolidEnd(void)2303 RiSolidEnd(void) {
2304 	if (check("RiSolidEnd",RENDERMAN_WORLD_BLOCK | RENDERMAN_ATTRIBUTE_BLOCK | RENDERMAN_XFORM_BLOCK | RENDERMAN_SOLID_PRIMITIVE_BLOCK | RENDERMAN_RESOURCE_BLOCK | RENDERMAN_ARCHIVE_BLOCK)) return;
2305 
2306 	renderMan->RiSolidEnd();
2307 }
2308 
2309 EXTERN(RtObjectHandle)
RiObjectBegin(void)2310 RiObjectBegin (void) {
2311 	if (check("RiObjectBegin",RENDERMAN_BLOCK | RENDERMAN_FRAME_BLOCK | RENDERMAN_WORLD_BLOCK | RENDERMAN_ATTRIBUTE_BLOCK | RENDERMAN_XFORM_BLOCK | RENDERMAN_SOLID_PRIMITIVE_BLOCK | RENDERMAN_RESOURCE_BLOCK | RENDERMAN_ARCHIVE_BLOCK)) return NULL;
2312 
2313 	blocks.push(currentBlock);
2314 	currentBlock	=	RENDERMAN_OBJECT_BLOCK;
2315 
2316 	return (RtObjectHandle) renderMan->RiObjectBegin();
2317 }
2318 
2319 
2320 EXTERN(RtVoid)
RiObjectEnd(void)2321 RiObjectEnd (void) {
2322 	if (check("RiObjectBegin",RENDERMAN_OBJECT_BLOCK)) return;
2323 
2324 	if (currentBlock != RENDERMAN_OBJECT_BLOCK) {
2325 		error(CODE_NESTING,"Matching RiObjectBegin not found\n");
2326 		return;
2327 	}
2328 
2329 	renderMan->RiObjectEnd();
2330 
2331 	currentBlock	=	blocks.pop();
2332 }
2333 
2334 
2335 EXTERN(RtVoid)
RiObjectInstance(RtObjectHandle handle)2336 RiObjectInstance (RtObjectHandle handle) {
2337 	if (check("RiObjectInstance",VALID_PRIMITIVE_BLOCKS)) return;
2338 
2339 	renderMan->RiObjectInstance(handle);
2340 }
2341 
2342 EXTERN(RtVoid)
RiMotionBegin(RtInt N,...)2343 RiMotionBegin (RtInt N, ...) {
2344 	va_list	args;
2345 	float	*keys;
2346 	int		i;
2347 
2348 	keys	=	(float *) alloca(sizeof(float)*N);
2349 	va_start(args,N);
2350 
2351 	for (i=0;i<N;i++) {
2352 		keys[i]	=	(float) (va_arg(args,double));
2353 	}
2354 
2355 	va_end(args);
2356 
2357 	RiMotionBeginV(N,keys);
2358 }
2359 
2360 EXTERN(RtVoid)
RiMotionBeginV(RtInt N,RtFloat times[])2361 RiMotionBeginV (RtInt N, RtFloat times[]) {
2362 	if (check("RiMotionBegin",RENDERMAN_BLOCK | RENDERMAN_FRAME_BLOCK | RENDERMAN_WORLD_BLOCK | RENDERMAN_ATTRIBUTE_BLOCK | RENDERMAN_XFORM_BLOCK | RENDERMAN_SOLID_PRIMITIVE_BLOCK | RENDERMAN_RESOURCE_BLOCK | RENDERMAN_ARCHIVE_BLOCK)) return;
2363 
2364 	renderMan->RiMotionBeginV(N,times);
2365 
2366 	blocks.push(currentBlock);
2367 	currentBlock	=	RENDERMAN_MOTION_BLOCK;
2368 }
2369 
2370 EXTERN(RtVoid)
RiMotionEnd(void)2371 RiMotionEnd (void) {
2372 	if (check("RiMotionEnd",RENDERMAN_MOTION_BLOCK)) return;
2373 
2374 	if (currentBlock != RENDERMAN_MOTION_BLOCK) {
2375 		error(CODE_NESTING,"Expecting a motion block\n");
2376 		return;
2377 	}
2378 
2379 	renderMan->RiMotionEnd();
2380 
2381 	currentBlock	=	blocks.pop();
2382 }
2383 
2384 EXTERN(RtVoid)
RiMakeTexture(const char * pic,const char * tex,RtToken swrap,RtToken twrap,RtFilterFunc filterfunc,RtFloat swidth,RtFloat twidth,...)2385     RiMakeTexture (const char *pic, const char *tex, RtToken swrap, RtToken twrap,
2386 	RtFilterFunc filterfunc, RtFloat swidth, RtFloat twidth, ...) {
2387 
2388 	va_list	args;
2389 
2390 	va_start(args,twidth);
2391 	getArgs(args);
2392 	RiMakeTextureV(pic,tex,swrap,twrap,filterfunc,swidth,twidth,nTokens,tokens,values);
2393 	va_end(args);
2394 }
2395 
2396 EXTERN(RtVoid)
RiMakeTextureV(const char * pic,const char * tex,RtToken swrap,RtToken twrap,RtFilterFunc filterfunc,RtFloat swidth,RtFloat twidth,RtInt n,RtToken tokens[],RtPointer params[])2397     RiMakeTextureV (const char *pic, const char *tex, RtToken swrap, RtToken twrap,
2398 		    RtFilterFunc filterfunc, RtFloat swidth, RtFloat twidth,
2399 			RtInt n, RtToken tokens[], RtPointer params[]) {
2400 	if (check("RiMakeTexture",RENDERMAN_ALL_BLOCKS)) return;
2401 
2402 	renderMan->RiMakeTextureV(pic,tex,swrap,twrap,filterfunc,swidth,twidth,n,tokens,params);
2403 }
2404 
2405 EXTERN(RtVoid)
RiMakeBump(const char * pic,const char * tex,RtToken swrap,RtToken twrap,RtFilterFunc filterfunc,RtFloat swidth,RtFloat twidth,...)2406     RiMakeBump (const char *pic, const char *tex, RtToken swrap, RtToken twrap,
2407 	RtFilterFunc filterfunc, RtFloat swidth, RtFloat twidth, ...) {
2408 	va_list	args;
2409 
2410 	va_start(args,twidth);
2411 	getArgs(args);
2412 	RiMakeBumpV(pic,tex,swrap,twrap,filterfunc,swidth,twidth,nTokens,tokens,values);
2413 	va_end(args);
2414 }
2415 
2416 EXTERN(RtVoid)
RiMakeBumpV(const char * pic,const char * tex,RtToken swrap,RtToken twrap,RtFilterFunc filterfunc,RtFloat swidth,RtFloat twidth,RtInt n,RtToken tokens[],RtPointer params[])2417     RiMakeBumpV (const char *pic, const char *tex, RtToken swrap, RtToken twrap,
2418 		 RtFilterFunc filterfunc, RtFloat swidth, RtFloat twidth,
2419 		 RtInt n, RtToken tokens[], RtPointer params[]) {
2420 	if (check("RiMakeBump",RENDERMAN_ALL_BLOCKS)) return;
2421 
2422 	renderMan->RiMakeBumpV(pic,tex,swrap,twrap,filterfunc,swidth,twidth,n,tokens,params);
2423 }
2424 
2425 EXTERN(RtVoid)
RiMakeLatLongEnvironment(const char * pic,const char * tex,RtFilterFunc filterfunc,RtFloat swidth,RtFloat twidth,...)2426     RiMakeLatLongEnvironment (const char *pic, const char *tex, RtFilterFunc filterfunc,
2427 	RtFloat swidth, RtFloat twidth, ...) {
2428 	va_list	args;
2429 
2430 	va_start(args,twidth);
2431 	getArgs(args);
2432 	RiMakeLatLongEnvironmentV(pic,tex,filterfunc,swidth,twidth,nTokens,tokens,values);
2433 	va_end(args);
2434 }
2435 
2436 EXTERN(RtVoid)
RiMakeLatLongEnvironmentV(const char * pic,const char * tex,RtFilterFunc filterfunc,RtFloat swidth,RtFloat twidth,RtInt n,RtToken tokens[],RtPointer params[])2437     RiMakeLatLongEnvironmentV (const char *pic, const char *tex, RtFilterFunc filterfunc,
2438 			      RtFloat swidth, RtFloat twidth,
2439 				  RtInt n, RtToken tokens[], RtPointer params[]) {
2440 	if (check("RiMakeLatLongEnvironment",RENDERMAN_ALL_BLOCKS)) return;
2441 
2442 	renderMan->RiMakeLatLongEnvironmentV(pic,tex,filterfunc,swidth,twidth,n,tokens,params);
2443 }
2444 
2445 EXTERN(RtVoid)
RiMakeCubeFaceEnvironment(const char * px,const char * nx,const char * py,const char * ny,const char * pz,const char * nz,const char * tex,RtFloat fov,RtFilterFunc filterfunc,RtFloat swidth,RtFloat twidth,...)2446     RiMakeCubeFaceEnvironment (const char *px, const char *nx, const char *py,
2447 			       const char *ny, const char *pz, const char *nz,
2448 			       const char *tex, RtFloat fov, RtFilterFunc filterfunc,
2449 				   RtFloat swidth, RtFloat twidth, ...) {
2450 	va_list	args;
2451 
2452 	va_start(args,twidth);
2453 	getArgs(args);
2454 	RiMakeCubeFaceEnvironmentV(px,nx,py,ny,pz,nz,tex,fov,filterfunc,swidth,twidth,nTokens,tokens,values);
2455 	va_end(args);
2456 }
2457 
2458 EXTERN(RtVoid)
RiMakeCubeFaceEnvironmentV(const char * px,const char * nx,const char * py,const char * ny,const char * pz,const char * nz,const char * tex,RtFloat fov,RtFilterFunc filterfunc,RtFloat swidth,RtFloat twidth,RtInt n,RtToken tokens[],RtPointer params[])2459     RiMakeCubeFaceEnvironmentV (const char *px, const char *nx, const char *py,
2460 				const char *ny, const char *pz, const char *nz,
2461 				const char *tex, RtFloat fov, RtFilterFunc filterfunc,
2462 				RtFloat swidth, RtFloat twidth,
2463 				RtInt n, RtToken tokens[], RtPointer params[]) {
2464 
2465 	if (check("RiMakeCubeFaceEnvironmentV",RENDERMAN_ALL_BLOCKS)) return;
2466 
2467 	renderMan->RiMakeCubeFaceEnvironmentV(px,nx,py,ny,pz,nz,tex,fov,filterfunc,swidth,twidth,n,tokens,params);
2468 }
2469 
2470 EXTERN(RtVoid)
RiMakeShadow(const char * pic,const char * tex,...)2471 RiMakeShadow (const char *pic, const char *tex, ...) {
2472 	va_list	args;
2473 
2474 	va_start(args,tex);
2475 	getArgs(args);
2476 	RiMakeShadowV(pic,tex,nTokens,tokens,values);
2477 	va_end(args);
2478 }
2479 
2480 EXTERN(RtVoid)
RiMakeShadowV(const char * pic,const char * tex,RtInt n,RtToken tokens[],RtPointer params[])2481     RiMakeShadowV (const char *pic, const char *tex,
2482 	RtInt n, RtToken tokens[], RtPointer params[]) {
2483 
2484 	if (check("RiMakeShadow",RENDERMAN_ALL_BLOCKS)) return;
2485 
2486 	renderMan->RiMakeShadowV(pic,tex,n,tokens,params);
2487 }
2488 
2489 EXTERN(RtVoid)
RiMakeBrickMap(int n,const char ** src,const char * dest,...)2490 	RiMakeBrickMap (int n,const char **src, const char *dest, ...) {
2491 	va_list	args;
2492 
2493 	va_start(args,dest);
2494 	getArgs(args);
2495 	RiMakeBrickMapV(n,src,dest,nTokens,tokens,values);
2496 	va_end(args);
2497 }
2498 
2499 EXTERN(RtVoid)
RiMakeBrickMapV(int nb,const char ** src,const char * dest,RtInt n,RtToken tokens[],RtPointer params[])2500 	RiMakeBrickMapV(int nb,const char **src, const char *dest,RtInt n, RtToken tokens[], RtPointer params[]) {
2501 
2502 	if (check("RiMakeBrickMap",RENDERMAN_ALL_BLOCKS)) return;
2503 
2504 	renderMan->RiMakeBrickMapV(nb,src,dest,n,tokens,params);
2505 }
2506 
2507 EXTERN(RtVoid)
RiErrorHandler(const RtErrorHandler handler)2508 RiErrorHandler (const RtErrorHandler handler) {
2509 	renderMan->RiErrorHandler(handler);
2510 }
2511 
2512 EXTERN(RtVoid)
RiErrorIgnore(RtInt code,RtInt severity,const char * message)2513 RiErrorIgnore (RtInt code, RtInt severity, const char *message) {
2514 	if ((severity == RIE_ERROR) || (severity == RIE_SEVERE)) {
2515 		RiLastError = code;
2516 	}
2517 }
2518 
2519 EXTERN(RtVoid)
RiErrorPrint(RtInt code,RtInt severity,const char * message)2520 RiErrorPrint (RtInt code, RtInt severity, const char *message) {
2521 	if (severity == RIE_SEVERE) {
2522 		// Severe errors must still abort
2523 
2524 		fprintf(stderr,"%s",message);
2525 		fflush(stderr);
2526 
2527 		RiLastError = code;
2528 
2529 		exit(-1);
2530 	} else if (severity == RIE_ERROR) {
2531 		fprintf(stderr,"%s",message);
2532 		fflush(stderr);
2533 
2534 		RiLastError = code;
2535 	} else {
2536 		fprintf(stdout,"%s",message);
2537 		fflush(stdout);
2538 	}
2539 }
2540 
2541 EXTERN(RtVoid)
RiErrorAbort(RtInt code,RtInt severity,const char * message)2542 RiErrorAbort (RtInt code, RtInt severity, const char *message) {
2543 	if ((severity == RIE_ERROR) || (severity == RIE_SEVERE)) {
2544 		RiLastError = code;
2545 
2546 		exit(-1);
2547 	}
2548 }
2549 
2550 
2551 ///////////////////////////////////////////////////////////////////////////////////////
2552 //
2553 //  Resource related functions
2554 //
RiResource(RtToken handle,RtToken type,...)2555 EXTERN(RtVoid)	RiResource(RtToken handle, RtToken type,...) {
2556 	va_list	args;
2557 
2558 	va_start(args,type);
2559 	getArgs(args);
2560 	RiResourceV(handle,type,nTokens,tokens,values);
2561 	va_end(args);
2562 }
2563 
RiResourceV(RtToken handle,RtToken type,RtInt n,RtToken tokens[],RtPointer parms[])2564 EXTERN(RtVoid)	RiResourceV(RtToken handle, RtToken type,RtInt n, RtToken tokens[], RtPointer parms[]) {
2565 	if (check("RiResource",VALID_ATTRIBUTE_BLOCKS | VALID_XFORM_BLOCKS)) return;
2566 
2567 	renderMan->RiResourceV(handle,type,n,tokens,parms);
2568 }
2569 
RiResourceBegin(void)2570 EXTERN(RtVoid)	RiResourceBegin(void) {
2571 	if (check("RiResourceBegin",VALID_ATTRIBUTE_BLOCKS | VALID_XFORM_BLOCKS)) return;
2572 
2573 	blocks.push(currentBlock);
2574 	currentBlock	=	RENDERMAN_RESOURCE_BLOCK;
2575 
2576 	renderMan->RiResourceBegin();
2577 }
2578 
2579 
RiResourceEnd(void)2580 EXTERN(RtVoid)	RiResourceEnd(void) {
2581 	if (check("RiResourceEnd",RENDERMAN_RESOURCE_BLOCK)) return;
2582 
2583 	if (currentBlock != RENDERMAN_RESOURCE_BLOCK) {
2584 		error(CODE_NESTING,"Matching RiResourceBegin not found\n");
2585 		return;
2586 	}
2587 
2588 	renderMan->RiResourceEnd();
2589 
2590 	currentBlock	=	blocks.pop();
2591 }
2592 
2593 ///////////////////////////////////////////////////////////////////////////////////////
2594 //
2595 //  Archieving functions
2596 //
RiArchiveBegin(RtToken name,...)2597 EXTERN(RtArchiveHandle)	RiArchiveBegin(RtToken name, ...) {
2598 	RtArchiveHandle	handle;
2599 	va_list			args;
2600 
2601 	va_start(args,name);
2602 	getArgs(args);
2603 	handle	=	RiArchiveBeginV(name,nTokens,tokens,values);
2604 	va_end(args);
2605 
2606 	return handle;
2607 }
2608 
RiArchiveBeginV(RtToken name,RtInt n,RtToken tokens[],RtPointer parms[])2609 EXTERN(RtArchiveHandle)	RiArchiveBeginV(RtToken name, RtInt n, RtToken tokens[], RtPointer parms[]) {
2610 
2611 	//if (check("RiArchiveBegin",RENDERMAN_FRAME_BLOCK | RENDERMAN_WORLD_BLOCK | RENDERMAN_ATTRIBUTE_BLOCK | RENDERMAN_XFORM_BLOCK | RENDERMAN_SOLID_PRIMITIVE_BLOCK | RENDERMAN_RESOURCE_BLOCK | RENDERMAN_ARCHIVE_BLOCK)) return NULL;
2612 	// Archives should be allowed anywhere
2613 	if (check("RiArchiveBegin",RENDERMAN_ALL_BLOCKS)) return NULL;
2614 
2615 
2616 	blocks.push(currentBlock);
2617 	currentBlock	=	RENDERMAN_ARCHIVE_BLOCK;
2618 
2619 	// Keep track of the nesting count
2620 	archiveNesting++;
2621 
2622 	// Always call the current renderMan
2623 	return (RtArchiveHandle) renderMan->RiArchiveBeginV(name,n,tokens,parms);
2624 }
2625 
RiArchiveEnd(void)2626 EXTERN(RtVoid)			RiArchiveEnd(void) {
2627 
2628 	if (check("RiArchiveEnd",RENDERMAN_ARCHIVE_BLOCK)) return;
2629 
2630 	if (currentBlock != RENDERMAN_ARCHIVE_BLOCK) {
2631 		error(CODE_NESTING,"Matching RiResourceBegin not found\n");
2632 		return;
2633 	}
2634 
2635 	// Decrease the nesting and recover the original context
2636 	archiveNesting--;
2637 	if (archiveNesting == 0) {
2638 		if (savedRenderMan != NULL)	{
2639 			delete renderMan;
2640 			renderMan	=	savedRenderMan;
2641 		}
2642 	}
2643 
2644 	renderMan->RiArchiveEnd();
2645 
2646 	currentBlock	=	blocks.pop();
2647 }
2648 
2649 ///////////////////////////////////////////////////////////////////////////////////////
2650 //
2651 //  Conditional evaluation functions
2652 //
RiIfBegin(const char * expr,...)2653 EXTERN(RtVoid)			RiIfBegin(const char *expr, ...) {
2654 	va_list	args;
2655 
2656 	va_start(args,expr);
2657 	getArgs(args);
2658 	RiIfBeginV(expr,nTokens,tokens,values);
2659 	va_end(args);
2660 }
2661 
RiIfBeginV(const char * expr,RtInt n,RtToken tokens[],RtPointer parms[])2662 EXTERN(RtVoid)			RiIfBeginV(const char *expr, RtInt n, RtToken tokens[], RtPointer parms[]) {
2663 
2664 	// Do not check for scope
2665 	renderMan->RiIfBeginV(expr,n,tokens,parms);
2666 }
2667 
RiElseIf(const char * expr,...)2668 EXTERN(RtVoid)			RiElseIf(const char *expr, ...) {
2669 	va_list	args;
2670 
2671 	va_start(args,expr);
2672 	getArgs(args);
2673 	RiElseIfV(expr,nTokens,tokens,values);
2674 	va_end(args);
2675 }
2676 
RiElseIfV(const char * expr,RtInt n,RtToken tokens[],RtPointer parms[])2677 EXTERN(RtVoid)			RiElseIfV(const char *expr, RtInt n, RtToken tokens[], RtPointer parms[]) {
2678 
2679 	// Do not check for scope
2680 	renderMan->RiElseIfV(expr,n,tokens,parms);}
2681 
RiElse(void)2682 EXTERN(RtVoid)			RiElse(void) {
2683 
2684 	// Do not check for scope
2685 	renderMan->RiElse();
2686 }
2687 
RiIfEnd(void)2688 EXTERN(RtVoid)			RiIfEnd(void) {
2689 
2690 	// Do not check for scope
2691 	renderMan->RiIfEnd();
2692 }
2693 
2694 
2695 
2696 
2697 
2698 ///////////////////////////////////////////////////////////////////////////////////////
2699 //
2700 //  Archieve reading functions
2701 //
2702 EXTERN(RtVoid)
RiArchiveRecord(RtToken type,const char * format,...)2703 RiArchiveRecord (RtToken type, const char *format, ...) {
2704 	va_list	args;
2705 
2706 	va_start(args,format);
2707 
2708 	renderMan->RiArchiveRecord(type,format,args);
2709 
2710 	va_end(args);
2711 }
2712 
2713 EXTERN(RtVoid)
RiReadArchive(RtString filename,RtArchiveCallback callback,...)2714 RiReadArchive (RtString filename, RtArchiveCallback callback, ...) {
2715 	va_list	args;
2716 
2717 	va_start(args,callback);
2718 	getArgs(args);
2719 	RiReadArchiveV(filename,callback,nTokens,tokens,values);
2720 	va_end(args);
2721 
2722 }
2723 
2724 EXTERN(RtVoid)
RiReadArchiveV(RtString filename,RtArchiveCallback callback,int n,RtToken tokens[],RtPointer params[])2725     RiReadArchiveV (RtString filename, RtArchiveCallback callback,
2726 	int n, RtToken tokens[], RtPointer params[]) {
2727 
2728 	if (check("RiReadArchive",RENDERMAN_ALL_BLOCKS)) return;
2729 
2730 	renderMan->RiReadArchiveV(filename,callback,n,tokens,params);
2731 }
2732 
2733