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 : ribOut.cpp
27 // Classes : CRibOut
28 // Description :
29 //
30 ////////////////////////////////////////////////////////////////////////
31 #include <string.h>
32 #include <time.h>
33 #include <math.h>
34
35 #include "ribOut.h"
36 #include "common/os.h"
37 #include "ri.h"
38 #include "error.h"
39 #include "variable.h"
40
41 // This is the size of the temporary buffer we use before going to the file
42 const int ribOutScratchSize = 1000;
43
44 // Options for rib
45 int preferCompressedRibOut = FALSE;
46
47
getFilter(float (* function)(float,float,float,float))48 static const char *getFilter(float (*function)(float,float,float,float)) {
49 if (function == RiGaussianFilter) {
50 return RI_GAUSSIANFILTER;
51 } else if (function == RiBoxFilter) {
52 return RI_BOXFILTER;
53 } else if (function == RiTriangleFilter) {
54 return RI_TRIANGLEFILTER;
55 } else if (function == RiCatmullRomFilter) {
56 return RI_CATMULLROMFILTER;
57 } else if (function == RiBlackmanHarrisFilter) {
58 return RI_BLACKMANHARRISFILTER;
59 } else if (function == RiMitchellFilter) {
60 return RI_MITCHELLFILTER;
61 } else if (function == RiSincFilter) {
62 return RI_SINCFILTER;
63 } else if (function == RiBesselFilter) {
64 return RI_BESSELFILTER;
65 } else if (function == RiDiskFilter) {
66 return RI_DISKFILTER;
67 } else {
68 return RI_GAUSSIANFILTER;
69 }
70 }
71
CRibAttributes()72 CRibOut::CRibAttributes::CRibAttributes() {
73 uStep = 3;
74 vStep = 3;
75 next = NULL;
76 }
77
CRibAttributes(CRibAttributes * a)78 CRibOut::CRibAttributes::CRibAttributes(CRibAttributes *a) {
79 this[0] = a[0];
80 this->next = a;
81 }
82
~CRibAttributes()83 CRibOut::CRibAttributes::~CRibAttributes() {
84 }
85
CRibOut(const char * n)86 CRibOut::CRibOut(const char *n) : CRiInterface() {
87 struct tm *newtime;
88 time_t aclock;
89
90 time( &aclock );
91 newtime = localtime( &aclock );
92
93 outName = strdup(n);
94 if (*outName == '|') {
95 outFile = popen(outName+1,"w");
96 outputCompressed = FALSE;
97 outputIsPipe = TRUE;
98 } else {
99
100 #ifdef HAVE_ZLIB
101
102 if ( (strstr(outName,".Z") != NULL) ||
103 (strstr(outName,".zip") != NULL) ||
104 (strstr(outName,".z") != NULL) ||
105 (preferCompressedRibOut == TRUE) ) {
106 outFile = (FILE *) gzopen(outName,"wb");
107 outputCompressed = TRUE;
108 } else {
109 outFile = fopen(outName,"w");
110 outputCompressed = FALSE;
111 }
112 #else
113 outFile = fopen(outName,"w");
114 outputCompressed = FALSE;
115 #endif
116
117 outputIsPipe = FALSE;
118 }
119 declaredVariables = new CTrie<CVariable *>;
120 numLightSources = 1;
121 numObjects = 1;
122 attributes = new CRibAttributes;
123 scratch = new char[ribOutScratchSize];
124
125 // Write a header
126 out("## Pixie %d.%d.%d\n",VERSION_RELEASE,VERSION_BETA,VERSION_ALPHA);
127 out("## Generated %s\n",asctime(newtime));
128
129 declareDefaultVariables();
130 }
131
CRibOut(FILE * o)132 CRibOut::CRibOut(FILE *o) : CRiInterface() {
133 struct tm *newtime;
134 time_t aclock;
135
136 time( &aclock );
137 newtime = localtime( &aclock );
138
139 outName = NULL;
140 outFile = o;
141 outputCompressed = FALSE;
142 outputIsPipe = FALSE;
143 declaredVariables = new CTrie<CVariable *>;
144 numLightSources = 1;
145 numObjects = 1;
146 attributes = new CRibAttributes;
147 scratch = new char[ribOutScratchSize];
148
149 // Write a header
150 out("## Pixie %d.%d.%d\n",VERSION_RELEASE,VERSION_BETA,VERSION_ALPHA);
151 out("## Generated %s\n",asctime(newtime));
152
153 declareDefaultVariables();
154 }
155
~CRibOut()156 CRibOut::~CRibOut() {
157
158 if (outName != NULL) {
159 if (outputIsPipe) {
160 pclose(outFile);
161 } else {
162
163 #ifdef HAVE_ZLIB
164 if (outputCompressed) {
165 gzclose((gzFile)outFile);
166 } else {
167 fclose(outFile);
168 }
169 #else
170 fclose(outFile);
171 #endif
172 }
173
174 free((void *) outName);
175 }
176
177 assert(attributes->next == NULL);
178
179 delete attributes;
180 declaredVariables->destroy();
181
182 delete [] scratch;
183 }
184
RiDeclare(const char * name,const char * type)185 void CRibOut::RiDeclare(const char *name,const char *type) {
186 out("Declare \"%s\" \"%s\"\n",name,type);
187 declareVariable(name,type);
188 }
189
RiFrameBegin(int number)190 void CRibOut::RiFrameBegin(int number) {
191 out("FrameBegin %d\n",number);
192 }
193
RiFrameEnd(void)194 void CRibOut::RiFrameEnd(void) {
195 out("FrameEnd\n");
196 }
197
RiWorldBegin(void)198 void CRibOut::RiWorldBegin(void) {
199 out("WorldBegin\n");
200 }
201
RiWorldEnd(void)202 void CRibOut::RiWorldEnd(void) {
203 out("WorldEnd\n");
204 }
205
RiFormat(int xres,int yres,float aspect)206 void CRibOut::RiFormat(int xres,int yres,float aspect) {
207 out("Format %d %d %g\n",xres,yres,aspect);
208 }
209
RiFrameAspectRatio(float aspect)210 void CRibOut::RiFrameAspectRatio(float aspect) {
211 out("FrameAspectRatio %g\n",aspect);
212 }
213
RiScreenWindow(float left,float right,float bot,float top)214 void CRibOut::RiScreenWindow(float left,float right,float bot,float top) {
215 out("ScreenWindow %g %g %g %g\n",left,right,bot,top);
216 }
217
RiCropWindow(float xmin,float xmax,float ymin,float ymax)218 void CRibOut::RiCropWindow(float xmin,float xmax,float ymin,float ymax) {
219 out("CropWindow %g %g %g %g\n",xmin,xmax,ymin,ymax);
220 }
221
RiProjectionV(const char * name,int n,const char * tokens[],const void * params[])222 void CRibOut::RiProjectionV(const char *name,int n,const char *tokens[],const void *params[]) {
223 out("Projection \"%s\" ",name);
224 writePL(n,tokens,params);
225 }
226
RiClipping(float hither,float yon)227 void CRibOut::RiClipping(float hither,float yon) {
228 out("Clipping %g %g\n",hither,yon);
229 }
230
RiClippingPlane(float x,float y,float z,float nx,float ny,float nz)231 void CRibOut::RiClippingPlane(float x,float y,float z,float nx,float ny,float nz) {
232 out("ClippingPlane %g %g %g %g %g %g\n",x,y,z,nx,ny,nz);
233 }
234
RiDepthOfField(float fstop,float focallength,float focaldistance)235 void CRibOut::RiDepthOfField(float fstop,float focallength,float focaldistance) {
236 out("DepthOfField %g %g %g\n",fstop,focallength,focaldistance);
237 }
238
RiShutter(float smin,float smax)239 void CRibOut::RiShutter(float smin,float smax) {
240 out("Shutter %g %g\n",smin,smax);
241 }
242
RiPixelVariance(float variance)243 void CRibOut::RiPixelVariance(float variance) {
244 out("PixelVariance %g\n",variance);
245 }
246
RiPixelSamples(float xsamples,float ysamples)247 void CRibOut::RiPixelSamples(float xsamples,float ysamples) {
248 out("PixelSamples %g %g\n",xsamples,ysamples);
249 }
250
RiPixelFilter(float (* function)(float,float,float,float),float xwidth,float ywidth)251 void CRibOut::RiPixelFilter(float (*function)(float,float,float,float),float xwidth,float ywidth) {
252 if (function == RiGaussianFilter) {
253 out("PixelFilter \"%s\" %g %g\n",RI_GAUSSIANFILTER,xwidth,ywidth);
254 } else if (function == RiBoxFilter) {
255 out("PixelFilter \"%s\" %g %g\n",RI_BOXFILTER,xwidth,ywidth);
256 } else if (function == RiTriangleFilter) {
257 out("PixelFilter \"%s\" %g %g\n",RI_TRIANGLEFILTER,xwidth,ywidth);
258 } else if (function == RiCatmullRomFilter) {
259 out("PixelFilter \"%s\" %g %g\n",RI_CATMULLROMFILTER,xwidth,ywidth);
260 } else if (function == RiBlackmanHarrisFilter) {
261 out("PixelFilter \"%s\" %g %g\n",RI_BLACKMANHARRISFILTER,xwidth,ywidth);
262 } else if (function == RiMitchellFilter) {
263 out("PixelFilter \"%s\" %g %g\n",RI_MITCHELLFILTER,xwidth,ywidth);
264 } else if (function == RiSincFilter) {
265 out("PixelFilter \"%s\" %g %g\n",RI_SINCFILTER,xwidth,ywidth);
266 } else if (function == RiBesselFilter) {
267 out("PixelFilter \"%s\" %g %g\n",RI_BESSELFILTER,xwidth,ywidth);
268 } else if (function == RiDiskFilter) {
269 out("PixelFilter \"%s\" %g %g\n",RI_DISKFILTER,xwidth,ywidth);
270 } else {
271 errorHandler(RIE_BADHANDLE,RIE_ERROR,"Failed to write custom filter function\n");
272 }
273 }
274
RiExposure(float gain,float gamma)275 void CRibOut::RiExposure(float gain,float gamma) {
276 out("Exposure %g %g\n",gain,gamma);
277 }
278
RiImagerV(const char * name,int n,const char * tokens[],const void * params[])279 void CRibOut::RiImagerV(const char *name,int n,const char *tokens[],const void *params[]) {
280 out("Imager \"%s\" ",name);
281 writePL(n,tokens,params);
282 }
283
RiQuantize(const char * type,int one,int qmin,int qmax,float ampl)284 void CRibOut::RiQuantize(const char * type,int one,int qmin,int qmax,float ampl) {
285 out("Quantize \"%s\" %d %d %d %g\n",type,one,qmin,qmax,ampl);
286 }
287
RiDisplayV(const char * name,const char * type,const char * mode,int n,const char * tokens[],const void * params[])288 void CRibOut::RiDisplayV(const char *name,const char * type,const char * mode,int n,const char *tokens[],const void *params[]) {
289 out("Display \"%s\" \"%s\" \"%s\" ",name,type,mode);
290 writePL(n,tokens,params);
291 }
292
RiCustomDisplayV(const char * name,RtToken mode,RtDisplayStartFunction,RtDisplayDataFunction,RtDisplayFinishFunction,RtInt n,RtToken tokens[],RtPointer params[])293 void CRibOut::RiCustomDisplayV(const char *name, RtToken mode, RtDisplayStartFunction, RtDisplayDataFunction, RtDisplayFinishFunction, RtInt n, RtToken tokens[], RtPointer params[]) {
294 error(CODE_INCAPABLE,"Can not serialize custom displays.\n");
295 }
296
RiDisplayChannelV(const char * channel,int n,const char * tokens[],const void * params[])297 void CRibOut::RiDisplayChannelV(const char *channel,int n,const char *tokens[],const void *params[]) {
298 out("Display \"%s\" ",channel);
299 writePL(n,tokens,params);
300 }
301
RiHiderV(const char * type,int n,const char * tokens[],const void * params[])302 void CRibOut::RiHiderV(const char * type,int n,const char *tokens[],const void *params[]) {
303 out("Hider \"%s\" ",type);
304 writePL(n,tokens,params);
305 }
306
RiColorSamples(int N,float * nRGB,float * RGBn)307 void CRibOut::RiColorSamples(int N,float *nRGB,float *RGBn) {
308 int i;
309
310 out("ColorSamples [ ");
311
312 for (i=0;i<N*3;i++) {
313 out("%g ",nRGB[i]);
314 }
315
316 out("] [ ");
317
318 for (i=0;i<N*3;i++) {
319 out("%g ",RGBn[i]);
320 }
321
322 out("]\n");
323 }
324
RiRelativeDetail(float relativedetail)325 void CRibOut::RiRelativeDetail(float relativedetail) {
326 out("RelativeDetail %g\n",relativedetail);
327 }
328
329
330
331 #define optionCheckInt(__name,__num) \
332 } else if (strcmp(tokens[i],__name) == 0) { \
333 const int *val = (const int *) params[i]; \
334 int k; \
335 out("Option \"%s\" \"%s\" [%i",name,tokens[i],val[0]); \
336 for (k=1;k<__num;k++) { \
337 out(" %i",val[k]); \
338 } \
339 out("]\n");
340
341
342 #define optionCheckFloat(__name,__num) \
343 } else if (strcmp(tokens[i],__name) == 0) { \
344 const float *val = (const float *) params[i]; \
345 int k; \
346 out("Option \"%s\" \"%s\" [%g",name,tokens[i],val[0]); \
347 for (k=1;k<__num;k++) { \
348 out(" %g",val[k]); \
349 } \
350 out("]\n");
351
352
353 #define optionCheckString(__name) \
354 } else if (strcmp(tokens[i],__name) == 0) { \
355 const char *val = ((const char **) params[i])[0]; \
356 out("Option \"%s\" \"%s\" \"%s\"\n",name,tokens[i],val);
357
358 #define optionEndCheck \
359 } else { \
360 CVariable var; \
361 if (parseVariable(&var,NULL,tokens[i]) == TRUE) { \
362 RiOption(name,var.name,params[i],RI_NULL); \
363 } else { \
364 error(CODE_BADTOKEN,"Unknown %s option: \"%s\"\n",name,tokens[i]); \
365 } \
366 }
367
368
369
370
371
RiOptionV(const char * name,int n,const char * tokens[],const void * params[])372 void CRibOut::RiOptionV(const char *name,int n,const char *tokens[],const void *params[]) {
373 int i;
374
375 // Check the searchpath options
376 if (strcmp(name,RI_SEARCHPATH) == 0) {
377 for (i=0;i<n;i++) {
378 if (FALSE) {
379 optionCheckString(RI_ARCHIVE)
380 optionCheckString(RI_PROCEDURAL)
381 optionCheckString(RI_TEXTURE)
382 optionCheckString(RI_SHADER)
383 optionCheckString(RI_DISPLAY)
384 optionCheckString(RI_RESOURCE)
385 optionEndCheck
386 }
387
388 // Check the limit options
389 } else if (strcmp(name,RI_LIMITS) == 0) {
390 for (i=0;i<n;i++) {
391 if (FALSE) {
392 optionCheckInt(RI_BUCKETSIZE,2)
393 optionCheckInt(RI_METABUCKETS,2)
394 optionCheckInt(RI_INHERITATTRIBUTES,1)
395 optionCheckInt(RI_GRIDSIZE,1)
396 optionCheckInt(RI_EYESPLITS,1)
397 optionCheckInt(RI_TEXTUREMEMORY,1)
398 optionCheckInt(RI_BRICKMEMORY,1)
399 optionEndCheck
400 }
401 // Check the hider options
402 } else if (strcmp(name,RI_HIDER) == 0) {
403 for (i=0;i<n;i++) {
404 if (FALSE) {
405 optionCheckFloat(RI_JITTER,1) //GSHTODO: should be INT
406 optionCheckInt(RI_FALSECOLOR,1)
407 optionCheckInt(RI_EMIT,1)
408 optionCheckString(RI_DEPTHFILTER)
409 optionEndCheck
410 }
411
412 // Check the trace options
413 } else if (strcmp(name,RI_TRACE) == 0) {
414 for (i=0;i<n;i++) {
415 if (FALSE) {
416 optionCheckInt(RI_MAXDEPTH,1)
417 optionEndCheck
418 }
419
420 // Check the io options
421 } else if (strcmp(name,RI_STATISTICS) == 0) {
422 for (i=0;i<n;i++) {
423 if (FALSE) {
424 optionCheckInt(RI_ENDOFFRAME,1)
425 optionCheckString(RI_FILELOG)
426 optionCheckInt(RI_PROGRESS,1)
427 optionEndCheck
428 }
429 // Check for rib compression / output options
430 } else if (strcmp(name,RI_RIB) == 0) {
431 for (i=0;i<n;i++) {
432 if (FALSE) {
433 } else if (strcmp(tokens[i],RI_COMPRESSION) == 0) {
434 const char *val = ((const char **) params[i])[0];
435 if (strcmp(val,"gzip") == 0) {
436 preferCompressedRibOut = TRUE;
437 } else if (strcmp(val,"none") == 0) {
438 preferCompressedRibOut = FALSE;
439 } else {
440 error(CODE_BADTOKEN,"Unknown compression type \"%s\"\n",val);
441 }
442 optionEndCheck
443 }
444 } else {
445 error(CODE_BADTOKEN,"Unknown option: \"%s\"\n",name);
446 }
447 }
448
449 #undef optionCheckInt
450 #undef optionCheckFloat
451 #undef optionCheckString
452 #undef optionEnd
453
454
455 void CRibOut::RiAttributeBegin(void) {
456 out("AttributeBegin\n");
457
458 attributes = new CRibAttributes(attributes);
459 }
460
461 void CRibOut::RiAttributeEnd(void) {
462 CRibAttributes *old = attributes;
463
464 out("AttributeEnd\n");
465
466 attributes = attributes->next;
467 delete old;
468 }
469
470 void CRibOut::RiColor(float *Cs) {
471 out("Color [%g %g %g]\n",Cs[0],Cs[1],Cs[2]);
472 }
473
474 void CRibOut::RiOpacity(float *Cs) {
475 out("Opacity [%g %g %g]\n",Cs[0],Cs[1],Cs[2]);
476 }
477
478 void CRibOut::RiTextureCoordinates(float s1,float t1,float s2,float t2,float s3,float t3,float s4,float t4) {
479 out("TextureCoordinates [%g %g %g %g %g %g %g %g]\n",s1,t1,s2,t2,s3,t3,s4,t4);
480 }
481
482 void *CRibOut::RiLightSourceV(const char *name,int n,const char *tokens[],const void *params[]) {
483 out("LightSource \"%s\" %d ",name,numLightSources);
484 writePL(n,tokens,params);
485
486 return (void *) (uintptr_t) numLightSources++;
487 }
488
489 void *CRibOut::RiAreaLightSourceV(const char *name,int n,const char *tokens[],const void *params[]) {
490 out("AreaLightSource \"%s\" %d ",name,numLightSources);
491 writePL(n,tokens,params);
492
493 return (void *) (uintptr_t) numLightSources++;
494 }
495
496 void CRibOut::RiIlluminate(const void *light,int onoff) {
497 out("Illuminate %d %d\n",light,onoff);
498 }
499
500 void CRibOut::RiSurfaceV(const char *name,int n,const char *tokens[],const void *params[]) {
501 out("Surface \"%s\" ",name);
502 writePL(n,tokens,params);
503 }
504
505 void CRibOut::RiAtmosphereV(const char *name,int n,const char *tokens[],const void *params[]) {
506 out("Atmosphere \"%s\" ",name);
507 writePL(n,tokens,params);
508 }
509
510 void CRibOut::RiInteriorV(const char *name,int n,const char *tokens[],const void *params[]) {
511 out("Interior \"%s\" ",name);
512 writePL(n,tokens,params);
513 }
514
515 void CRibOut::RiExteriorV(const char *name,int n,const char *tokens[],const void *params[]) {
516 out("Exterior \"%s\" ",name);
517 writePL(n,tokens,params);
518 }
519
520 void CRibOut::RiShadingRate(float size) {
521 out("ShadingRate %g\n",size);
522 }
523
524 void CRibOut::RiShadingInterpolation(const char * type) {
525 out("ShadingInterpolation \"%s\"\n",type);
526 }
527
528 void CRibOut::RiMatte(int onoff) {
529 out("Matte %d\n",onoff);
530 }
531
532 void CRibOut::RiBound(float *bound) {
533 out("Bound [%g %g %g %g %g %g]\n",bound[0],bound[1],bound[2],bound[3],bound[4],bound[5]);
534 }
535
536 void CRibOut::RiDetail(float *bound) {
537 out("Detail [%g %g %g %g %g %g]\n",bound[0],bound[1],bound[2],bound[3],bound[4],bound[5]);
538 }
539
540 void CRibOut::RiDetailRange(float minvis,float lowtran,float uptran,float maxvis) {
541 out("DetailRange %g %g %g %g\n",minvis,lowtran,uptran,maxvis);
542 }
543
544 void CRibOut::RiGeometricApproximation(const char * type,float value) {
545 out("GeometricApproximation \"%s\" %g\n",type,value);
546 }
547
548 void CRibOut::RiGeometricRepresentation(const char * type) {
549 out("GeometricRepresentation \"%s\"\n",type);
550 }
551
552 void CRibOut::RiOrientation(const char * orientation) {
553 out("Orientation \"%s\"\n",orientation);
554 }
555
556 void CRibOut::RiReverseOrientation(void) {
557 out("ReverseOrientation\n");
558 }
559
560 void CRibOut::RiSides(int nsides) {
561 out("Sides %d\n",nsides);
562 }
563
564 void CRibOut::RiIdentity(void) {
565 out("Identity\n");
566 }
567
568 void CRibOut::RiTransform(float transform[][4]) {
569 out("Transform [%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g]\n",transform[0][0],transform[0][1],transform[0][2],transform[0][3]
570 ,transform[1][0],transform[1][1],transform[1][2],transform[1][3]
571 ,transform[2][0],transform[2][1],transform[2][2],transform[2][3]
572 ,transform[3][0],transform[3][1],transform[3][2],transform[3][3]);
573 }
574
575 void CRibOut::RiConcatTransform(float transform[][4]) {
576 out("ConcatTransform [%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g]\n",transform[0][0],transform[0][1],transform[0][2],transform[0][3]
577 ,transform[1][0],transform[1][1],transform[1][2],transform[1][3]
578 ,transform[2][0],transform[2][1],transform[2][2],transform[2][3]
579 ,transform[3][0],transform[3][1],transform[3][2],transform[3][3]);
580 }
581
582 void CRibOut::RiPerspective(float fov) {
583 out("Perspective %g\n",fov);
584 }
585
586 void CRibOut::RiTranslate(float dx,float dy,float dz) {
587 out("Translate %g %g %g\n",dx,dy,dz);
588 }
589
590 void CRibOut::RiRotate(float angle,float dx,float dy,float dz) {
591 out("Rotate %g %g %g %g\n",angle,dx,dy,dz);
592 }
593
594 void CRibOut::RiScale(float dx,float dy,float dz) {
595 out("Scale %g %g %g\n",dx,dy,dz);
596 }
597
598 void CRibOut::RiSkew(float angle,float dx1,float dy1,float dz1,float dx2,float dy2,float dz2) {
599 out("Skew %g %g %g %g %g %g %g\n",angle,dx1,dy1,dz1,dx2,dy2,dz2);
600 }
601
602 void CRibOut::RiDeformationV(const char *name,int n,const char *tokens[],const void *params[]) {
603 out("Deformation \"%s\" ",name);
604 writePL(n,tokens,params);
605 }
606
607 void CRibOut::RiDisplacementV(const char *name,int n,const char *tokens[],const void *params[]) {
608 out("Displacement \"%s\" ",name);
609 writePL(n,tokens,params);
610 }
611
612 void CRibOut::RiCoordinateSystem(const char * space) {
613 out("CoordinateSystem \"%s\"\n",space);
614 }
615
616 void CRibOut::RiCoordSysTransform(const char * space) {
617 out("CoordSysTransform \"%s\"\n",space);
618 }
619
620 RtPoint * CRibOut::RiTransformPoints(const char * fromspace,const char * tospace,int npoints,RtPoint *points) {
621 errorHandler(RIE_SYSTEM,RIE_ERROR,"Failed to output TransformPoints\n");
622 return NULL;
623 }
624
625 void CRibOut::RiTransformBegin(void) {
626 out("TransformBegin\n");
627 }
628
629 void CRibOut::RiTransformEnd(void) {
630 out("TransformEnd\n");
631 }
632
633
634 #define attributeCheckInt(__name,__num) \
635 } else if (strcmp(tokens[i],__name) == 0) { \
636 const int *val = (const int *) params[i]; \
637 int k; \
638 out("Attribute \"%s\" \"%s\" [%i",name,tokens[i],val[0]); \
639 for (k=1;k<__num;k++) { \
640 out(" %i",val[k]); \
641 } \
642 out("]\n");
643
644
645 #define attributeCheckFloat(__name,__num) \
646 } else if (strcmp(tokens[i],__name) == 0) { \
647 const float *val = (const float *) params[i]; \
648 int k; \
649 out("Attribute \"%s\" \"%s\" [%g",name,tokens[i],val[0]); \
650 for (k=1;k<__num;k++) { \
651 out(" %g",val[k]); \
652 } \
653 out("]\n");
654
655
656 #define attributeCheckString(__name) \
657 } else if (strcmp(tokens[i],__name) == 0) { \
658 const char *val = ((const char **) params[i])[0]; \
659 out("Attribute \"%s\" \"%s\" \"%s\"\n",name,tokens[i],val);
660
661 #define attributeEndCheck \
662 } else { \
663 CVariable var; \
664 if (parseVariable(&var,NULL,tokens[i]) == TRUE) { \
665 RiAttribute(name,var.name,params[i],RI_NULL); \
666 } else { \
667 error(CODE_BADTOKEN,"Unknown %s option: \"%s\"\n",name,tokens[i]); \
668 } \
669 }
670
671
672
673 void CRibOut::RiAttributeV(const char *name,int n,const char *tokens[],const void *params[]) {
674 int i;
675
676 if (strcmp(name,RI_DICE) == 0) {
677 for (i=0;i<n;i++) {
678 if (FALSE) {
679 attributeCheckInt(RI_NUMPROBES,2)
680 attributeCheckInt(RI_MINSUBDIVISION,1)
681 attributeCheckInt(RI_MAXSUBDIVISION,1)
682 attributeCheckInt(RI_MINSPLITS,1)
683 attributeCheckFloat(RI_BOUNDEXPAND,1)
684 attributeCheckInt(RI_BINARY,1)
685 attributeCheckInt(RI_RASTERORIENT,1)
686 attributeEndCheck
687 }
688 } else if (strcmp(name,RI_DISPLACEMENTBOUND) == 0) {
689 for (i=0;i<n;i++) {
690 if (FALSE) {
691 attributeCheckFloat(RI_SPHERE,1)
692 attributeCheckString(RI_COORDINATESYSYTEM)
693 attributeEndCheck
694 }
695 } else if (strcmp(name,RI_TRACE) == 0) {
696 for (i=0;i<n;i++) {
697 if (FALSE) {
698 attributeCheckInt(RI_DISPLACEMENTS,1)
699 attributeCheckFloat(RI_BIAS,1)
700 attributeCheckInt(RI_MAXDIFFUSEDEPTH,1)
701 attributeCheckInt(RI_MAXSPECULARDEPTH,1)
702 attributeEndCheck
703 }
704 // Check the irradiance cache options
705 } else if (strcmp(name,RI_IRRADIANCE) == 0) {
706 for (i=0;i<n;i++) {
707 if (FALSE) {
708 attributeCheckString(RI_HANDLE)
709 attributeCheckString(RI_FILEMODE)
710 attributeCheckFloat(RI_MAXERROR,1)
711 attributeEndCheck
712 }
713 } else if (strcmp(name,RI_PHOTON) == 0) {
714 for (i=0;i<n;i++) {
715 if (FALSE) {
716 attributeCheckString(RI_GLOBALMAP)
717 attributeCheckString(RI_CAUSTICMAP)
718 attributeCheckString(RI_SHADINGMODEL)
719 attributeCheckFloat(RI_IOR,1)
720 attributeCheckInt(RI_ESTIMATOR,1)
721 attributeCheckInt(RI_ILLUMINATEFRONT,1)
722 attributeEndCheck
723 }
724 } else if (strcmp(name,RI_VISIBILITY) == 0) {
725 for (i=0;i<n;i++) {
726 if (FALSE) {
727 attributeCheckInt(RI_TRANSMISSION,1)
728 attributeCheckInt(RI_DIFFUSE,1)
729 attributeCheckInt(RI_SPECULAR,1)
730 attributeCheckInt(RI_CAMERA,1)
731 attributeCheckInt(RI_TRACE,1)
732 attributeCheckInt(RI_PHOTON,1)
733 attributeEndCheck
734 }
735 } else if (strcmp(name,RI_SHADE) == 0) {
736 for (i=0;i<n;i++) {
737 if (FALSE) {
738 attributeCheckString(RI_TRANSMISSIONHITMODE)
739 attributeCheckString(RI_DIFFUSEHITMODE)
740 attributeCheckString(RI_SPECULARHITMODE)
741 attributeEndCheck
742 }
743 } else if (strcmp(name,RI_IDENTIFIER) == 0) {
744 for (i=0;i<n;i++) {
745 if (FALSE) {
746 attributeCheckString(RI_NAME)
747 attributeEndCheck
748 }
749 } else if (strcmp(name,RI_CULL) == 0) {
750 for (i=0;i<n;i++) {
751 if (FALSE) {
752 attributeCheckInt(RI_HIDDEN,1)
753 attributeCheckInt(RI_BACKFACING,1)
754 attributeEndCheck
755 }
756 }
757 }
758
759
760 #undef attributeCheckInt
761 #undef attributeCheckFloat
762 #undef attributeCheckString
763 #undef attributeEndCheck
764
765
766 void CRibOut::RiPolygonV(int nvertices,int n,const char *tokens[],const void *params[]) {
767 out("Polygon ");
768 writePL(nvertices,nvertices,nvertices,1,n,tokens,params);
769 }
770
771 void CRibOut::RiGeneralPolygonV(int nloops,int *nverts,int n,const char *tokens[],const void *params[]) {
772 int i;
773 int nvertices=0;
774
775 out("GeneralPolygon [");
776 for (i=0;i<nloops;i++) {
777 nvertices += nverts[i];
778 out("%d ",nverts[i]);
779 }
780 out("] ");
781
782 writePL(nvertices,nvertices,nvertices,1,n,tokens,params);
783 }
784
785 void CRibOut::RiPointsPolygonsV(int npolys,int *nverts,int *verts,int n,const char *tokens[],const void *params[]) {
786 int i;
787 int nvertices = 0;
788 int mvertex = 0;
789
790 out("PointsPolygons [");
791
792 for (i=0;i<npolys;i++) {
793 nvertices += nverts[i];
794 out("%d ",nverts[i]);
795 }
796 out("] ");
797
798 out("[");
799 for (i=0;i<nvertices;i++) {
800 mvertex = max(mvertex,verts[i]);
801 out("%d ",verts[i]);
802 }
803 out("] ");
804 mvertex++;
805
806 writePL(mvertex,mvertex,nvertices,npolys,n,tokens,params);
807 }
808
809 void CRibOut::RiPointsGeneralPolygonsV(int npolys,int *nloops,int *nverts,int *verts,int n,const char *tokens[],const void *params[]) {
810 int i,j;
811 int snverts = 0;
812 int sverts = 0;
813 int nvertices = 0;
814 int k = 0;
815
816 out("PointsGeneralPolygons [");
817 for (i=0;i<npolys;i++) {
818 snverts += nloops[i];
819 out("%d ",nloops[i]);
820 for (j=0;j<nloops[i];j++,k++) {
821 sverts += nverts[k];
822 }
823 }
824 out("] ");
825
826 out("[");
827 for (k=0,i=0;i<npolys;i++) {
828 for (j=0;j<nloops[i];j++,k++) {
829 out("%d ",nverts[k]);
830 }
831 }
832 out("] ");
833
834 out("[");
835 for (i=0;i<sverts;i++) {
836 nvertices = max(nvertices,verts[i]+1);
837 out("%d ",verts[i]);
838 }
839 out("] ");
840
841 writePL(nvertices,nvertices,sverts,npolys,n,tokens,params);
842 }
843
844 void CRibOut::RiBasis(float ubasis[][4],int ustep,float vbasis[][4],int vstep) {
845 if ((ubasis == RiBezierBasis || ubasis == RiBSplineBasis || ubasis == RiCatmullRomBasis || ubasis == RiHermiteBasis || ubasis == RiPowerBasis) &&
846 (vbasis == RiBezierBasis || vbasis == RiBSplineBasis || vbasis == RiCatmullRomBasis || vbasis == RiHermiteBasis || vbasis == RiPowerBasis)) {
847
848 const char *ubasis_str;
849 if (ubasis == RiBezierBasis)
850 ubasis_str = "bezier";
851 else if (ubasis == RiBSplineBasis)
852 ubasis_str = "b-spline";
853 else if (ubasis == RiCatmullRomBasis)
854 ubasis_str = "catmull-rom";
855 else if (ubasis == RiHermiteBasis)
856 ubasis_str = "hermite";
857 else if (ubasis == RiPowerBasis)
858 ubasis_str = "power";
859
860 const char *vbasis_str;
861 if (vbasis == RiBezierBasis)
862 vbasis_str = "bezier";
863 else if (vbasis == RiBSplineBasis)
864 vbasis_str = "b-spline";
865 else if (vbasis == RiCatmullRomBasis)
866 vbasis_str = "catmull-rom";
867 else if (vbasis == RiHermiteBasis)
868 vbasis_str = "hermite";
869 else if (vbasis == RiPowerBasis)
870 vbasis_str = "power";
871
872 out("Basis \"%s\" %d \"%s\" %d\n",
873 ubasis_str,ustep,
874 vbasis_str,vstep);
875 attributes->uStep = ustep;
876 attributes->vStep = vstep;
877 return;
878 }
879 out("Basis [%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g] %d [%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g] %d\n"
880 ,ubasis[0][0],ubasis[0][1],ubasis[0][2],ubasis[0][3]
881 ,ubasis[1][0],ubasis[1][1],ubasis[1][2],ubasis[1][3]
882 ,ubasis[2][0],ubasis[2][1],ubasis[2][2],ubasis[2][3]
883 ,ubasis[3][0],ubasis[3][1],ubasis[3][2],ubasis[3][3],ustep
884 ,vbasis[0][0],vbasis[0][1],vbasis[0][2],vbasis[0][3]
885 ,vbasis[1][0],vbasis[1][1],vbasis[1][2],vbasis[1][3]
886 ,vbasis[2][0],vbasis[2][1],vbasis[2][2],vbasis[2][3]
887 ,vbasis[3][0],vbasis[3][1],vbasis[3][2],vbasis[3][3],vstep);
888 attributes->uStep = ustep;
889 attributes->vStep = vstep;
890 }
891
892 void CRibOut::RiPatchV(const char * type,int n,const char *tokens[],const void *params[]) {
893 int uver,vver;
894
895 if (strcmp(type,RI_BILINEAR) == 0) { uver = 2; vver = 2; }
896 else if (strcmp(type,RI_BICUBIC) == 0) { uver = 4; vver = 4; }
897 else {
898 char tmp[512];
899
900 sprintf(tmp,"Unknown patch type: \"%s\"\n",type);
901 errorHandler(RIE_BADTOKEN,RIE_ERROR,tmp);
902 return;
903 }
904
905 out("Patch \"%s\" ",type);
906 writePL(uver*vver,4,4,1,n,tokens,params);
907 }
908
909 void CRibOut::RiPatchMeshV(const char *type,int nu,const char * uwrap,int nv,const char * vwrap,int n,const char *tokens[],const void *params[]) {
910 int uw,vw;
911 int uver,vver;
912 int upatches,vpatches;
913
914 if (strcmp(uwrap,RI_PERIODIC) == 0) {
915 uw = TRUE;
916 } else if ((strcmp(uwrap,RI_NONPERIODIC) == 0) || (strcmp(uwrap,RI_NOWRAP) == 0)) {
917 uw = FALSE;
918 } else {
919 errorHandler(RIE_BADTOKEN,RIE_ERROR,"Wrapping mode unrecognized\n");
920 return;
921 }
922
923 if (strcmp(vwrap,RI_PERIODIC) == 0) {
924 vw = TRUE;
925 } else if ((strcmp(vwrap,RI_NONPERIODIC) == 0) || (strcmp(vwrap,RI_NOWRAP) == 0)) {
926 vw = FALSE;
927 } else {
928 errorHandler(RIE_BADTOKEN,RIE_ERROR,"Wrapping mode unrecognized\n");
929 return;
930 }
931
932 uver = nu;
933 vver = nv;
934
935 if (strcmp(type,RI_BICUBIC) == 0) {
936 if (uw) {
937 if ((uver % attributes->uStep) != 0) {
938 errorHandler(RIE_CONSISTENCY,RIE_ERROR,"Unexpected number of u vertices\n");
939 return;
940 }
941
942 upatches = (uver ) / attributes->uStep;
943 } else {
944 if (((uver - 4) % attributes->uStep) != 0) {
945 errorHandler(RIE_CONSISTENCY,RIE_ERROR,"Unexpected number of u vertices\n");
946 return;
947 }
948
949 upatches = ((uver - 4) / attributes->uStep)+1;
950 }
951
952 if (vw) {
953 if ((vver % attributes->vStep) != 0) {
954 errorHandler(RIE_CONSISTENCY,RIE_ERROR,"Unexpected number of v vertices\n");
955 return;
956 }
957
958 vpatches = (vver) / attributes->vStep;
959 } else {
960 if (((vver - 4) % attributes->vStep) != 0) {
961 errorHandler(RIE_CONSISTENCY,RIE_ERROR,"Unexpected number of v vertices\n");
962 return;
963 }
964
965 vpatches = ((vver - 4) / attributes->vStep)+1;
966 }
967 } else {
968 if (uw)
969 upatches = uver;
970 else
971 upatches = uver-1;
972
973 if (vw)
974 vpatches = vver;
975 else
976 vpatches = vver-1;
977 }
978
979 out("PatchMesh \"%s\" %i \"%s\" %i \"%s\" ",type,nu,uwrap,nv,vwrap);
980 writePL(uver*vver,uver*vver,uver*vver,upatches*vpatches,n,tokens,params);
981 }
982
983 void CRibOut::RiNuPatchV(int nu,int uorder,float *uknot,float umin,float umax,int nv,int vorder,float *vknot,float vmin,float vmax,int n,const char *tokens[],const void *params[]) {
984 int upatches = nu - uorder + 1;
985 int vpatches = nv - vorder + 1;
986 int i,uk,vk;
987
988 out("NuPatch ");
989
990 // Print the knot sequence
991 uk = nu + uorder;
992 vk = nv + vorder;
993 out("%i %i [%g",nu,uorder,uknot[0]);
994 for (i=1;i<uk;i++) out(" %g",uknot[i]);
995 out("] %g %g ",umin,umax);
996
997 out("%i %i [%g",nv,vorder,vknot[0]);
998 for (i=1;i<vk;i++) out(" %g",vknot[i]);
999 out("] %g %g ",vmin,vmax);
1000
1001 writePL(nu*nv,(nu-uorder+2)*(nv-vorder+2),(nu-uorder+2)*(nv-vorder+2),upatches*vpatches,n,tokens,params);
1002 }
1003
1004 void CRibOut::RiTrimCurve(int nloops,int *ncurves,int *order,float *knot,float *amin,float *amax,int *n,float *u,float *v,float *w) {
1005 int i,j,k,numCurves;
1006
1007 // Write the ncurves
1008 out("TrimCurve [%d",ncurves[0]);
1009 numCurves = ncurves[0];
1010 for (i=1;i<nloops;i++) {
1011 out(" %d",ncurves[i]);
1012 numCurves += ncurves[i];
1013 }
1014
1015 // Print the order for each curve
1016 out("] [%d",order[0]);
1017 for (i=1;i<numCurves;i++) out(" %d",order[i]);
1018
1019 // Print the knot vector for each curve
1020 out("] [");
1021 for (k=0,i=0;i<numCurves;i++) {
1022
1023 for (j=n[i]+order[i];j>0;j--,k++) {
1024 if (k == 0) {
1025 out("%g",knot[k]);
1026 } else {
1027 out(" %g",knot[k]);
1028 }
1029 }
1030 }
1031
1032 // Print the parametric range for each curve
1033 out("] [%g",amin[0]);
1034 for (i=1;i<numCurves;i++) {
1035 out(" %g",amin[i]);
1036 }
1037
1038 out("] [%g",amax[0]);
1039 for (i=1;i<numCurves;i++) {
1040 out(" %g",amax[i]);
1041 }
1042
1043 // Print the number of vertices for each curve
1044 out("] [%d",n[0]);
1045 for (i=1;i<numCurves;i++) {
1046 out(" %d",n[i]);
1047 }
1048
1049 // Print the vertices for each curve
1050 out("] [");
1051 for (k=0,i=0;i<numCurves;i++) {
1052
1053 for (j=n[i];j>0;j--,k++) {
1054 if (k == 0) {
1055 out("%g",u[k]);
1056 } else {
1057 out(" %g",u[k]);
1058 }
1059 }
1060 }
1061
1062 out("] [");
1063 for (k=0,i=0;i<numCurves;i++) {
1064
1065 for (j=n[i];j>0;j--,k++) {
1066 if (k == 0) {
1067 out("%g",v[k]);
1068 } else {
1069 out(" %g",v[k]);
1070 }
1071 }
1072 }
1073
1074 out("] [");
1075 for (k=0,i=0;i<numCurves;i++) {
1076
1077 for (j=n[i];j>0;j--,k++) {
1078 if (k == 0) {
1079 out("%g",w[k]);
1080 } else {
1081 out(" %g",w[k]);
1082 }
1083 }
1084 }
1085
1086 out("]\n");
1087 }
1088
1089 void CRibOut::RiSphereV(float radius,float zmin,float zmax,float thetamax,int n,const char *tokens[],const void *params[]) {
1090 out("Sphere %g %g %g %g ",radius,zmin,zmax,thetamax);
1091 writePL(4,4,4,1,n,tokens,params);
1092 }
1093
1094 void CRibOut::RiConeV(float height,float radius,float thetamax,int n,const char *tokens[],const void *params[]) {
1095 out("Cone %g %g %g ",height,radius,thetamax);
1096 writePL(4,4,4,1,n,tokens,params);
1097 }
1098
1099 void CRibOut::RiCylinderV(float radius,float zmin,float zmax,float thetamax,int n,const char *tokens[],const void *params[]) {
1100 out("Cylinder %g %g %g %g ",radius,zmin,zmax,thetamax);
1101 writePL(4,4,4,1,n,tokens,params);
1102 }
1103
1104 void CRibOut::RiHyperboloidV(float *point1,float *point2,float thetamax,int n,const char *tokens[],const void *params[]) {
1105 out("Hyperboloid %g %g %g %g %g %g %g ",point1[0],point1[1],point1[2],point2[0],point2[1],point2[2],thetamax);
1106 writePL(4,4,4,1,n,tokens,params);
1107 }
1108
1109 void CRibOut::RiParaboloidV(float rmax,float zmin,float zmax,float thetamax,int n,const char *tokens[],const void *params[]) {
1110 out("Paraboloid %g %g %g %g ",rmax,zmin,zmax,thetamax);
1111 writePL(4,4,4,1,n,tokens,params);
1112 }
1113
1114 void CRibOut::RiDiskV(float height,float radius,float thetamax,int n,const char *tokens[],const void *params[]) {
1115 out("Disk %g %g %g ",height,radius,thetamax);
1116 writePL(4,4,4,1,n,tokens,params);
1117 }
1118
1119 void CRibOut::RiTorusV(float majorrad,float minorrad,float phimin,float phimax,float thetamax,int n,const char *tokens[],const void *params[]) {
1120 out("Torus %g %g %g %g %g",majorrad,minorrad,phimin,phimax,thetamax);
1121 writePL(4,4,4,1,n,tokens,params);
1122 }
1123
1124 void CRibOut::RiProcedural(void * data,float *bound,void (*subdivfunc)(void *,float),void (*freefunc)(void *)) {
1125 errorHandler(RIE_UNIMPLEMENT,RIE_ERROR,"Failed to output procedural geometry\n");
1126 }
1127
1128 void CRibOut::RiGeometryV(const char * type,int n,const char *tokens[],const void *params[]) {
1129 errorHandler(RIE_UNIMPLEMENT,RIE_ERROR,"Failed to output optional geometry\n");
1130 }
1131
1132 void CRibOut::RiCurvesV(const char * degree,int ncurves,int nverts[],const char * wrap,int n,const char *tokens[],const void *params[]) {
1133 int i;
1134 int nvertices = 0;
1135 int nvaryings = 0;
1136 int wrapadd;
1137
1138 if (strcmp(wrap,RI_PERIODIC) == 0) {
1139 wrapadd = 0;
1140 } else {
1141 wrapadd = 1;
1142 }
1143
1144 out("Curves \"%s\" [",degree);
1145
1146 if (strcmp(degree,RI_LINEAR) == 0) {
1147 for (i=0;i<ncurves;i++) {
1148 nvertices += nverts[i];
1149 out("%d ",nverts[i]);
1150 }
1151
1152 nvaryings = nvertices;
1153 } else if (strcmp(degree,RI_CUBIC) == 0) {
1154 for (i=0;i<ncurves;i++) {
1155 int j = (nverts[i] - 4) / attributes->vStep + 1;
1156 nvertices += nverts[i];
1157 nvaryings += j + wrapadd;
1158 out("%d ",nverts[i]);
1159 }
1160 }
1161
1162 out("] \"%s\" ",wrap);
1163
1164 writePL(nvertices,nvaryings,nvaryings,ncurves,n,tokens,params);
1165 }
1166
1167 void CRibOut::RiPointsV(int npts,int n,const char *tokens[],const void *params[]) {
1168 out("Points ");
1169 writePL(npts,npts,npts,1,n,tokens,params);
1170 }
1171
1172 void CRibOut::RiSubdivisionMeshV(const char * scheme,int nfaces,int nvertices[],int vertices[],int ntags,const char * tags[],int nargs[],int intargs[],float floatargs[],int n,const char *tokens[],const void *params[]) {
1173 int numVertices;
1174 int i,j;
1175 int numInt,numFloat;
1176 int numFacevaryings;
1177
1178 for (i=0,j=0;i<nfaces;j+=nvertices[i],i++);
1179 numFacevaryings = j;
1180
1181 for (numVertices=-1,i=0;i<j;i++) {
1182 if (vertices[i] > numVertices) numVertices = vertices[i];
1183 }
1184 numVertices++;
1185
1186 out("SubdivisionMesh \"%s\" [ ",scheme);
1187 for (i=0;i<nfaces;i++) {
1188 out("%d ",nvertices[i]);
1189 }
1190
1191 out("] [ ");
1192 for (i=0;i<j;i++) {
1193 out("%d ",vertices[i]);
1194 }
1195
1196 out("] [");
1197 for (i=0;i<ntags;i++) {
1198 out(" \"%s\" ",tags[i]);
1199 }
1200
1201 out("] [");
1202 numInt = 0;
1203 numFloat = 0;
1204 for (i=0;i<ntags;i++) {
1205 out(" %d %d ",nargs[0],nargs[1]);
1206 numInt += nargs[0];
1207 numFloat += nargs[1];
1208 nargs += 2;
1209 }
1210
1211 out("] [ ");
1212 for (i=0;i<numInt;i++) {
1213 out("%d ",intargs[i]);
1214 }
1215
1216 out("] [ ");
1217 for (i=0;i<numFloat;i++) {
1218 out("%g ",floatargs[i]);
1219 }
1220 out("] ");
1221
1222 writePL(numVertices,numVertices,numFacevaryings,nfaces,n,tokens,params);
1223 }
1224
1225 void CRibOut::RiBlobbyV(int nleaf,int ncode,int code[],int nflt,float flt[],int nstr,const char *str[],int n,const char *tokens[],const void *params[]) {
1226 errorHandler(RIE_UNIMPLEMENT,RIE_ERROR,"Blobby primitive is not implemented\n");
1227 }
1228
1229 void CRibOut::RiProcDelayedReadArchive(const char * data,float detail) {
1230 }
1231
1232 void CRibOut::RiProcRunProgram(const char * data,float detail) {
1233 }
1234
1235 void CRibOut::RiProcDynamicLoad(const char * data,float detail) {
1236 }
1237
1238 void CRibOut::RiProcFree(const char *) {
1239 }
1240
1241 void CRibOut::RiSolidBegin(const char * type) {
1242 out("SolidBegin \"%s\"\n",type);
1243 }
1244
1245 void CRibOut::RiSolidEnd(void) {
1246 out("SolidEnd\n");
1247 }
1248
1249 void *CRibOut::RiObjectBegin(void) {
1250 out("ObjectBegin %d\n",numObjects);
1251
1252 return (void *) (uintptr_t) numObjects++;
1253 }
1254
1255 void CRibOut::RiObjectEnd(void) {
1256 out("ObjectEnd\n");
1257 }
1258
1259 void CRibOut::RiObjectInstance(const void *handle) {
1260 out("ObjectInstance %d\n",handle);
1261 }
1262
1263 void CRibOut::RiMotionBeginV(int N,float times[]) {
1264 int i;
1265
1266 out("MotionBegin [ ");
1267 for (i=0;i<N;i++) {
1268 out(" %g ",times[i]);
1269 }
1270 out("]\n");
1271 }
1272
1273 void CRibOut::RiMotionEnd(void) {
1274 out("MotionEnd\n");
1275 }
1276
1277 void CRibOut::RiMakeTextureV(const char *pic,const char *tex,const char * swrap,const char * twrap,float (*filterfunc)(float,float,float,float),float swidth,float twidth,int n,const char *tokens[],const void *params[]) {
1278 out("MakeTexture \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" %g %g ",pic,tex,swrap,twrap,getFilter(filterfunc),swidth,twidth);
1279 writePL(n,tokens,params);
1280 }
1281
1282 void CRibOut::RiMakeBumpV(const char *pic,const char *tex,const char * swrap,const char * twrap,float (*filterfunc)(float,float,float,float),float swidth,float twidth,int n,const char *tokens[],const void *params[]) {
1283 out("MakeBump \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" %g %g ",pic,tex,swrap,twrap,getFilter(filterfunc),swidth,twidth);
1284 writePL(n,tokens,params);
1285 }
1286
1287 void CRibOut::RiMakeLatLongEnvironmentV(const char *pic,const char *tex,float (*filterfunc)(float,float,float,float),float swidth,float twidth,int n,const char *tokens[],const void *params[]) {
1288 out("MakeBump \"%s\" \"%s\" \"%s\" %g %g",pic,tex,getFilter(filterfunc),swidth,twidth);
1289 writePL(n,tokens,params);
1290 }
1291
1292 void CRibOut::RiMakeCubeFaceEnvironmentV(const char *px,const char *nx,const char *py,const char *ny,const char *pz,const char *nz,const char *tex,float fov,float (*filterfunc)(float,float,float,float),float swidth,float twidth,int n,const char *tokens[],const void *params[]) {
1293 out("MakeCubeFaceEnvironment \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" %g \"%s\" %g %g ",px,nx,py,ny,pz,nz,tex,fov,getFilter(filterfunc),swidth,twidth);
1294 writePL(n,tokens,params);
1295 }
1296
1297 void CRibOut::RiMakeShadowV(const char *pic,const char *tex,int n,const char *tokens[],const void *params[]) {
1298 out("MakeShadow \"%s\" \"%s\" ",pic,tex);
1299 writePL(n,tokens,params);
1300 }
1301
1302 void CRibOut::RiMakeBrickMapV(int n,const char **src,const char *dest,int numTokens,const char *tokens[],const void *params[]) {
1303 out("MakeBrickMap [");
1304 for(int i=0;i<n;i++) out("\"%s\" ",src[i]);
1305 out("] \"%s\" ",dest);
1306 writePL(numTokens,tokens,params);
1307 }
1308
1309 void CRibOut::RiErrorHandler(void (*handler)(int,int,const char *)) {
1310 errorHandler = handler;
1311 }
1312
1313 void CRibOut::RiArchiveRecord(const char * type,const char *format,va_list args) {
1314 if (strcmp(type,RI_COMMENT) == 0) {
1315 out("#");
1316 vout(format,args);
1317 out("\n");
1318 } else if (strcmp(type,RI_STRUCTURE) == 0) {
1319 out("##");
1320 vout(format,args);
1321 out("\n");
1322 } else if (strcmp(type,RI_VERBATIM) == 0) {
1323 vout(format,args);
1324 out("\n");
1325 } else {
1326 error(CODE_BADTOKEN,"Unknown record type: \"%s\"\n",type);
1327 }
1328 }
1329
1330 void CRibOut::RiReadArchiveV(const char *filename,void (*callback)(const char *,...),int n,const char *tokens[],const void *params[]) {
1331 out("ReadArchive \"%s\"\n",filename);
1332 }
1333
1334 void *CRibOut::RiArchiveBeginV(const char *name,int n,const char *tokens[],const void *parms[]) {
1335 out("ArchiveBegin \"%s\" ",name);
1336 writePL(n,tokens,parms);
1337 return NULL;
1338 }
1339
1340 void CRibOut::RiArchiveEnd(void) {
1341 out("ArchiveEnd\n");
1342 }
1343
1344 void CRibOut::RiResourceV(const char *handle,const char *type,int n,const char *tokens[],const void *parms[]) {
1345 out("Resource \"%s\" \"%s\" ",handle,type);
1346 writePL(n,tokens,parms);
1347 }
1348
1349 void CRibOut::RiResourceBegin(void) {
1350 out("ResourceBegin\n");
1351 }
1352
1353 void CRibOut::RiResourceEnd(void) {
1354 out("ResourceEnd\n");
1355 }
1356
1357 void CRibOut::RiIfBeginV(const char *expr,int n,const char *tokens[],const void *parms[]) {
1358 out("IfBegin \"%s\" ",expr);
1359 writePL(n,tokens,parms);
1360 }
1361
1362 void CRibOut::RiElseIfV(const char *expr,int n,const char *tokens[],const void *parms[]) {
1363 out("ElseIf \"%s\" ",expr);
1364 writePL(n,tokens,parms);
1365 }
1366
1367 void CRibOut::RiElse(void) {
1368 out("Else\n");
1369 }
1370
1371 void CRibOut::RiIfEnd(void) {
1372 out("IfEnd\n");
1373 }
1374
1375
1376 void CRibOut::writePL(int numParameters,const char *tokens[],const void *vals[]) {
1377 int i,j;
1378 const float *f;
1379 const int *iv;
1380 const char **s;
1381
1382 for (i=0;i<numParameters;i++) {
1383 CVariable tmpVar;
1384 CVariable *variable;
1385
1386 if (declaredVariables->find(tokens[i],variable) == TRUE) {
1387 retry:;
1388
1389 out(" \"%s\" [",tokens[i]);
1390
1391 switch(variable->type) {
1392 case TYPE_FLOAT:
1393
1394 f = (float *) vals[i];
1395 for (j=variable->numItems;j>0;j--,f++) {
1396 out("%g ",f[0]);
1397 }
1398 break;
1399 case TYPE_COLOR:
1400 case TYPE_VECTOR:
1401 case TYPE_NORMAL:
1402 case TYPE_POINT:
1403
1404 f = (float *) vals[i];
1405 for (j=variable->numItems;j>0;j--,f+=3) {
1406 out("%g %g %g ",f[0],f[1],f[2]);
1407 }
1408 break;
1409 case TYPE_MATRIX:
1410
1411 f = (float *) vals[i];
1412 for (j=variable->numItems;j>0;j--,f+=16) {
1413 out("%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g ",f[0],f[1],f[2],f[3],f[4],f[5],f[6],f[7],f[8],f[9],f[10],f[11],f[12],f[13],f[14],f[15]);
1414 }
1415 break;
1416 case TYPE_QUAD:
1417
1418 f = (float *) vals[i];
1419 for (j=variable->numItems;j>0;j--,f+=4) {
1420 out("%g %g %g %g ",f[0],f[1],f[2],f[3]);
1421 }
1422 break;
1423 case TYPE_DOUBLE:
1424
1425 f = (float *) vals[i];
1426 for (j=variable->numItems;j>0;j--,f+=2) {
1427 out("%g %g ",f[0],f[1]);
1428 }
1429 break;
1430 case TYPE_STRING:
1431
1432 s = (const char **) vals[i];
1433 for (j=variable->numItems;j>0;j--,s++) {
1434 out("\"%s\" ",s[0]);
1435 }
1436
1437 break;
1438 case TYPE_INTEGER:
1439 iv = (int *) vals[i];
1440 for (j=variable->numItems;j>0;j--,iv++) {
1441 out("%d ",iv[0]);
1442 }
1443 break;
1444 default:
1445 break;
1446 }
1447
1448 out("] ");
1449 } else {
1450 if (parseVariable(&tmpVar,NULL,tokens[i])) {
1451 variable = &tmpVar;
1452 goto retry;
1453 } else {
1454 char tmp[512];
1455
1456 sprintf(tmp,"Parameter \"%s\" not found\n",tokens[i]);
1457 errorHandler(RIE_BADTOKEN,RIE_ERROR,tmp);
1458 }
1459 }
1460 }
1461
1462 // Print the final newline
1463 out("\n");
1464 }
1465
1466 void CRibOut::writePL(int numVertex,int numVarying,int numFaceVarying,int numUniform,int numParameters,const char *tokens[],const void *vals[]) {
1467 int i,j;
1468 const float *f;
1469 const char **s;
1470
1471 #define numItems(__dest,__var) \
1472 switch(variable->container) { \
1473 case CONTAINER_UNIFORM: \
1474 __dest = __var->numItems*numUniform; \
1475 break; \
1476 case CONTAINER_VERTEX: \
1477 __dest = __var->numItems*numVertex; \
1478 break; \
1479 case CONTAINER_VARYING: \
1480 __dest = __var->numItems*numVarying; \
1481 break; \
1482 case CONTAINER_FACEVARYING: \
1483 __dest = __var->numItems*numFaceVarying; \
1484 break; \
1485 case CONTAINER_CONSTANT: \
1486 __dest = __var->numItems; \
1487 break; \
1488 default: \
1489 error(CODE_BUG,"Unknown container in writePL\n"); \
1490 __dest = 1; \
1491 }
1492
1493
1494
1495 for (i=0;i<numParameters;i++) {
1496 CVariable tmpVar;
1497 CVariable *variable;
1498
1499 if (declaredVariables->find(tokens[i],variable) == TRUE) {
1500 retry:;
1501 out(" \"%s\" [",tokens[i]);
1502
1503 switch(variable->type) {
1504 case TYPE_FLOAT:
1505
1506 f = (float *) vals[i];
1507 numItems(j,variable);
1508 for (;j>0;j--,f++) {
1509 out("%g ",f[0]);
1510 }
1511 break;
1512 case TYPE_COLOR:
1513 case TYPE_VECTOR:
1514 case TYPE_NORMAL:
1515 case TYPE_POINT:
1516
1517 f = (float *) vals[i];
1518 numItems(j,variable);
1519 for (;j>0;j--,f+=3) {
1520 out("%g %g %g ",f[0],f[1],f[2]);
1521 }
1522 break;
1523 case TYPE_MATRIX:
1524
1525 f = (float *) vals[i];
1526 numItems(j,variable);
1527 for (;j>0;j--,f+=16) {
1528 out("%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g ",f[0],f[1],f[2],f[3],f[4],f[5],f[6],f[7],f[8],f[9],f[10],f[11],f[12],f[13],f[14],f[15]);
1529 }
1530 break;
1531 case TYPE_QUAD:
1532
1533 f = (float *) vals[i];
1534 numItems(j,variable);
1535 for (;j>0;j--,f+=4) {
1536 out("%g %g %g %g ",f[0],f[1],f[2],f[3]);
1537 }
1538 break;
1539 case TYPE_DOUBLE:
1540
1541 f = (float *) vals[i];
1542 numItems(j,variable);
1543 for (;j>0;j--,f+=2) {
1544 out("%g %g ",f[0],f[1]);
1545 }
1546 break;
1547 case TYPE_STRING:
1548
1549 s = (const char **) vals[i];
1550 for (j=variable->numItems;j>0;j--,s++) {
1551 out("\"%s\" ",s[0]);
1552 }
1553 break;
1554 case TYPE_INTEGER:
1555 break;
1556 default:
1557 break;
1558 }
1559
1560 out("] ");
1561 } else {
1562 if (parseVariable(&tmpVar,NULL,tokens[i])) {
1563 variable = &tmpVar;
1564 goto retry;
1565 } else {
1566 char tmp[512];
1567
1568 sprintf(tmp,"Parameter \"%s\" not found\n",tokens[i]);
1569 errorHandler(RIE_BADTOKEN,RIE_ERROR,tmp);
1570 }
1571 }
1572 }
1573
1574 // Print the final newline
1575 out("\n");
1576
1577 #undef numItems
1578 }
1579
1580 void CRibOut::declareVariable(const char *name,const char *decl) {
1581 CVariable cVariable,*nVariable;
1582
1583 assert(declaredVariables != NULL);
1584
1585 if (parseVariable(&cVariable,name,decl) == TRUE) {
1586 // Parse successful, insert the variable into the dictionary
1587 CVariable *oVariable;
1588
1589 if (declaredVariables->erase(cVariable.name,oVariable)) {
1590 delete oVariable;
1591 };
1592
1593 // Add the new variable into the variables list
1594 nVariable = new CVariable;
1595 nVariable[0] = cVariable;
1596
1597 // Insert the variable into the variables trie
1598 declaredVariables->insert(nVariable->name,nVariable);
1599 }
1600 }
1601
1602
1603 void CRibOut::declareDefaultVariables() {
1604 // Define the options
1605 declareVariable(RI_ARCHIVE, "string");
1606 declareVariable(RI_PROCEDURAL, "string");
1607 declareVariable(RI_TEXTURE, "string");
1608 declareVariable(RI_SHADER, "string");
1609 declareVariable(RI_DISPLAY, "string");
1610 declareVariable(RI_RESOURCE, "string");
1611
1612 declareVariable(RI_BUCKETSIZE, "int[2]");
1613 declareVariable(RI_METABUCKETS, "int[2]");
1614 declareVariable(RI_INHERITATTRIBUTES, "int");
1615 declareVariable(RI_GRIDSIZE, "int");
1616 declareVariable(RI_EYESPLITS, "int");
1617 declareVariable(RI_TEXTUREMEMORY, "int");
1618 declareVariable(RI_BRICKMEMORY, "int");
1619
1620 declareVariable(RI_RADIANCECACHE, "int");
1621 declareVariable(RI_JITTER, "float");
1622 declareVariable(RI_FALSECOLOR, "int");
1623 declareVariable(RI_EMIT, "int");
1624 declareVariable(RI_DEPTHFILTER, "string");
1625
1626 declareVariable(RI_MAXDEPTH, "int");
1627
1628 declareVariable(RI_ENDOFFRAME, "int");
1629 declareVariable(RI_FILELOG, "string");
1630 declareVariable(RI_PROGRESS, "int");
1631
1632
1633 // Define the attributes
1634 declareVariable(RI_NUMPROBES, "int[2]");
1635 declareVariable(RI_MINSUBDIVISION, "int");
1636 declareVariable(RI_MAXSUBDIVISION, "int");
1637 declareVariable(RI_MINSPLITS, "int");
1638 declareVariable(RI_BOUNDEXPAND, "float");
1639 declareVariable(RI_BINARY, "int");
1640 declareVariable(RI_RASTERORIENT, "int");
1641
1642 declareVariable(RI_SPHERE, "float");
1643 declareVariable(RI_COORDINATESYSYTEM, "string");
1644
1645 declareVariable(RI_DISPLACEMENTS, "int");
1646 declareVariable(RI_BIAS, "float");
1647 declareVariable(RI_MAXDIFFUSEDEPTH, "int");
1648 declareVariable(RI_MAXSPECULARDEPTH, "int");
1649 declareVariable(RI_SAMPLEMOTION, "int");
1650
1651 declareVariable(RI_HANDLE, "string");
1652 declareVariable(RI_FILEMODE, "string");
1653 declareVariable(RI_MAXERROR, "float");
1654
1655 declareVariable(RI_GLOBALMAP, "string");
1656 declareVariable(RI_CAUSTICMAP, "string");
1657 declareVariable(RI_SHADINGMODEL, "string");
1658 declareVariable(RI_ESTIMATOR, "int");
1659 declareVariable(RI_ILLUMINATEFRONT, "int");
1660
1661 declareVariable(RI_TRANSMISSION, "int");
1662 declareVariable(RI_CAMERA, "int");
1663 declareVariable(RI_SPECULAR, "int");
1664 declareVariable(RI_DIFFUSE, "int");
1665 declareVariable(RI_PHOTON, "int");
1666
1667 declareVariable(RI_DIFFUSEHITMODE, "string");
1668 declareVariable(RI_SPECULARHITMODE, "string");
1669 declareVariable(RI_TRANSMISSIONHITMODE, "string");
1670 declareVariable(RI_CAMERAHITMODE, "string");
1671
1672 declareVariable(RI_NAME, "string");
1673
1674 declareVariable(RI_HIDDEN, "int");
1675 declareVariable(RI_BACKFACING, "backfacing");
1676
1677
1678 // File display variables
1679 declareVariable("quantize", "float[4]");
1680 declareVariable("dither", "float");
1681 declareVariable("gamma", "float");
1682 declareVariable("gain", "float");
1683 declareVariable("near", "float");
1684 declareVariable("far", "float");
1685 declareVariable("Software", "string");
1686 declareVariable("compression", "string");
1687 declareVariable("NP", "float[16]");
1688 declareVariable("Nl", "float[16]");
1689
1690 // Declare the rest
1691 declareVariable("P", "global vertex point");
1692 declareVariable("Ps", "global vertex point");
1693 declareVariable("N", "global varying normal");
1694 declareVariable("Ng", "global varying normal");
1695 declareVariable("dPdu", "global vertex vector");
1696 declareVariable("dPdv", "global vertex vector");
1697 declareVariable("L", "global varying vector");
1698 declareVariable("Cs", "global varying color");
1699 declareVariable("Os", "global varying color");
1700 declareVariable("Cl", "global varying color");
1701 declareVariable("Ol", "global varying color");
1702 declareVariable("Ci", "global varying color");
1703 declareVariable("Oi", "global varying color");
1704 declareVariable("s", "global varying float");
1705 declareVariable("t", "global varying float");
1706 declareVariable("st", "varying float[2]");
1707 declareVariable("du", "global varying float");
1708 declareVariable("dv", "global varying float");
1709 declareVariable("u", "global varying float");
1710 declareVariable("v", "global varying float");
1711 declareVariable("I", "global varying vector");
1712 declareVariable("E", "global varying point");
1713 declareVariable("alpha","global varying float");
1714 declareVariable("time", "global varying float");
1715 declareVariable("Pw", "global vertex htpoint");
1716 declareVariable("Pz", "vertex float");
1717 declareVariable("width","vertex float");
1718 declareVariable("constantwidth","constant float");
1719
1720 // Define uniform variables
1721 declareVariable("ncomps","global uniform float");
1722 declareVariable("dtime","global uniform float");
1723 declareVariable("Np","uniform normal");
1724
1725 // Misc. variables
1726 declareVariable("fov", "float");
1727
1728 // Standard RI variables
1729 declareVariable("Ka", "float");
1730 declareVariable("Kd", "float");
1731 declareVariable("Kr", "float");
1732 declareVariable("Ks", "float");
1733 declareVariable("amplitude", "float");
1734 declareVariable("background", "color");
1735 declareVariable("beamdistribution", "float");
1736 declareVariable("coneangle", "float");
1737 declareVariable("conedeltangle", "float");
1738 declareVariable("distance", "float");
1739 declareVariable("from", "point");
1740 declareVariable("intensity", "float");
1741 declareVariable("lightcolor", "color");
1742 declareVariable("maxdistance", "float");
1743 declareVariable("mindistance", "float");
1744 declareVariable("roughness", "float");
1745 declareVariable("specularcolor", "color");
1746 declareVariable("texturename", "string");
1747 declareVariable("to", "point");
1748 }
1749
1750