1
//------------------------------------------------------------------------------
3
//------------------------------------------------------------------------------
12
#include "CCSubdivision.h"
17
#include "ribInterface.h"
18
// for ReadArchive handling...
19
#include "RIB_parser.h"
27
#define WIN32_LEAN_AND_MEAN
32
#define snprintf _snprintf
35
// for error/warning debug output, just use C funcs
39
using namespace QDRender;
42
RtToken RI_FRAMEBUFFER = "framebuffer";
43
RtToken RI_FILE = "file";
44
RtToken RI_RGB = "rgb";
45
RtToken RI_RGBA = "rgba";
46
RtToken RI_RGBZ = "rgbz";
47
RtToken RI_RGBAZ = "rgbaz";
51
RtToken RI_PERSPECTIVE = "perspective";
52
RtToken RI_ORTHOGRAPHIC = "orthographic";
53
RtToken RI_HIDDEN = "hidden";
54
RtToken RI_PAINT = "paint";
55
RtToken RI_CONSTANT = "constant";
56
RtToken RI_SMOOTH = "smooth";
57
RtToken RI_FLATNESS = "flatness";
58
RtToken RI_FOV = "fov";
59
RtToken RI_AMBIENTLIGHT = "ambientlight";
60
RtToken RI_POINTLIGHT = "pointlight";
61
RtToken RI_DISTANTLIGHT = "distantlight";
62
RtToken RI_SPOTLIGHT = "spotlight";
63
RtToken RI_INTENSITY = "intensity";
64
RtToken RI_LIGHTCOLOR = "lightcolor";
65
RtToken RI_FROM = "from";
67
RtToken RI_CONEANGLE = "coneangle";
68
RtToken RI_CONEDELTAANGLE = "conedeltaangle";
69
RtToken RI_BEAMDISTRIBUTION = "beamdistribution";
70
RtToken RI_MATTE = "matte";
71
RtToken RI_METAL = "metal";
72
RtToken RI_SHINYMETAL = "shinymetal";
73
RtToken RI_PLASTIC = "plastic";
74
RtToken RI_PAINTEDPLASTIC = "paintedplastic";
78
RtToken RI_ROUGHNESS = "roughness";
80
RtToken RI_TEXTURENAME = "texturename";
81
RtToken RI_SPECULARCOLOR = "specularcolor";
82
RtToken RI_DEPTHCUE = "depthcue";
83
RtToken RI_FOG = "fog";
84
RtToken RI_BUMPY = "bumpy";
85
RtToken RI_MINDISTANCE = "mindistance";
86
RtToken RI_MAXDISTANCE = "maxdistance";
87
RtToken RI_BACKGROUND = "background";
88
RtToken RI_DISTANCE = "distance";
89
RtToken RI_AMPLITUDE = "amplitude";
90
RtToken RI_RASTER = "raster";
91
RtToken RI_SCREEN = "screen";
92
RtToken RI_CAMERA = "camera";
93
RtToken RI_WORLD = "world";
94
RtToken RI_OBJECT = "object";
95
RtToken RI_INSIDE = "inside";
96
RtToken RI_OUTSIDE = "outside";
100
RtToken RI_PZ = "Pz";
101
RtToken RI_PW = "Pw";
103
RtToken RI_NP = "Np";
104
RtToken RI_CS = "Cs";
105
RtToken RI_OS = "Os";
108
RtToken RI_ST = "st";
109
RtToken RI_BILINEAR = "bilinear";
110
RtToken RI_BICUBIC = "bicubic";
111
RtToken RI_LINEAR = "linear";
112
RtToken RI_CUBIC = "cubic";
113
RtToken RI_PRIMITIVE = "primitive";
114
RtToken RI_INTERSECTION = "intersection";
115
RtToken RI_UNION = "union";
116
RtToken RI_DIFFERENCE = "difference";
117
RtToken RI_PERIODIC = "periodic";
118
RtToken RI_NONPERIODIC = "nonperiodic";
119
RtToken RI_CLAMP = "clamp";
120
RtToken RI_BLACK = "black";
121
RtToken RI_IGNORE = "ignore";
122
RtToken RI_PRINT = "print";
123
RtToken RI_ABORT = "abort";
124
RtToken RI_HANDLER = "handler";
125
RtToken RI_COMMENT = "comment";
126
RtToken RI_STRUCTURE = "structure";
127
RtToken RI_VERBATIM = "verbatim";
128
RtToken RI_IDENTIFIER = "identifier";
129
RtToken RI_NAME = "name";
130
RtToken RI_SHADINGGROUP = "shadinggroup";
131
RtToken RI_WIDTH = "width";
132
RtToken RI_CONSTANTWIDTH = "constantwidth";
134
RtToken RI_JITTER = "jitter";
135
RtToken RI_ZFILE = "zfile";
136
RtToken RI_SPHERE = "sphere";
137
RtToken RI_RAYTRACE = "raytrace";
138
RtToken RI_HYBRID = "hybrid";
139
RtToken RI_BUCKETSIZE = "bucketsize";
140
RtToken RI_TEXTUREMEMORY = "texturememory";
141
RtToken RI_GRIDSIZE = "gridsize";
142
RtToken RI_BINARY = "binary";
143
RtToken RI_EYESPLITS = "eyesplits";
145
//------------------------------------------------------------------------------
148
RtBasis RiBezierBasis = {{-1, 3, -3, 1},
153
RtBasis RiBSplineBasis = {{(RtFloat)-1/6, 0.5, -0.5, (RtFloat)1/6},
156
{(RtFloat)1/6, (RtFloat)4/6, (RtFloat)1/6, 0}};
158
RtBasis RiCatmullRomBasis = {{-0.5, 1.5, -1.5, 0.5},
163
RtBasis RiHermiteBasis = {{ 2, 1, -2, 1},
168
RtBasis RiPowerBasis = {{1, 0, 0, 0},
173
//------------------------------------------------------------------------------
174
// helper functions for building parameter lists from var args
176
static RtToken* _tokens = NULL;
177
static RtPointer* _parms = NULL;
179
static void getArgs(va_list args, unsigned int n)
181
for (unsigned int i=0; i<n; i++) {
182
_tokens[i] = va_arg(args, const char*);
183
_parms[i] = va_arg(args, void*);
187
static int cntArgs(va_list args)
192
t = va_arg(args, const char*);
195
p = va_arg(args, void*);
196
// p should never be NULL, this would indicate an error in the parameter list
198
t = va_arg(args, const char*);
203
// note: on linux got crashes here,
204
// obviously have to restart the list after first pass in CountArgs()
205
// why it doesn't happen on win32 I do not know...
206
#define BUILD_TOKENPARAM_LIST(start_arg)\
208
va_start(args, start_arg);\
209
unsigned int n = cntArgs(args);\
214
_tokens = new RtToken[n];\
215
_parms = new RtPointer[n];\
216
va_start(args, start_arg);\
221
//------------------------------------------------------------------------------
222
// helper functions to test for presence of 'P' array in parameter list (or Pz/Pw)
224
bool haveP(const char* funcname, RtInt n, RtToken tokens[], RtPointer parms[])
226
for (int i=0; i<n; ++i)
227
if (!strcmp(tokens[i], RI_P)) return true;
228
fprintf(ERROUT, "[ERROR]: %s() -> required 'P' array is missing\n", funcname);
233
bool haveP_Pz(const char* funcname, RtInt n, RtToken tokens[], RtPointer parms[])
235
for (int i=0; i<n; ++i)
236
if ((!strcmp(tokens[i], RI_P)) || (!strcmp(tokens[i], RI_PZ))) return true;
237
fprintf(ERROUT, "[ERROR]: %s() -> required 'P' or 'Pz' array is missing\n", funcname);
242
bool haveP_Pw(const char* funcname, RtInt n, RtToken tokens[], RtPointer parms[])
244
for (int i=0; i<n; ++i)
245
if ((!strcmp(tokens[i], RI_P)) || (!strcmp(tokens[i], RI_PW))) return true;
246
fprintf(ERROUT, "[ERROR]: %s() -> required 'P' or 'Pw' array is missing\n", funcname);
251
bool haveP_any(const char* funcname, RtInt n, RtToken tokens[], RtPointer parms[])
253
for (int i=0; i<n; ++i)
254
if ((!strcmp(tokens[i], RI_P)) || (!strcmp(tokens[i], RI_PZ)) || (!strcmp(tokens[i], RI_PW))) return true;
255
fprintf(ERROUT, "[ERROR]: %s() -> required 'P', 'Pz' or 'Pw' array is missing\n", funcname);
259
//------------------------------------------------------------------------------
260
// motion block error checking
262
static int motion_pos = -1;
263
enum mbCmdType {MB_NONE,
265
MB_TRANSFORM, MB_CONCATTRANSFORM, MB_PERSPECTIVE, MB_TRANSLATE, MB_ROTATE, MB_SCALE, MB_SKEW,
266
MB_PROJECTION, MB_DISPLACEMENT, MB_DEFORMATION,
268
MB_BOUND, MB_DETAIL, MB_POLYGON, MB_GENERALPOLYGON, MB_POINTSPOLYGONS, MB_POINTSGENERALPOLYGONS, MB_PATCH,
269
MB_PATCHMESH, MB_NUPATCH, MB_SPHERE, MB_CONE, MB_CYLINDER, MB_HYPERBOLOID, MB_PARABOLOID, MB_DISK, MB_TORUS, MB_POINTS, MB_CURVES,
270
MB_SUBDIVISIONMESH, MB_BLOBBY,
271
// not in list of valid commands, but this must be valid too
274
MB_COLOR, MB_OPACITY, MB_LIGHTSOURCE, MB_AREALIGHTSOURCE, MB_SURFACE, MB_INTERIOR, MB_EXTERIOR, MB_ATMOSPHERE
276
static mbCmdType prev_motion_cmd = MB_NONE;
277
// commands in readarchive include files are not tested yet.
278
// for now temporary solution is to only check commands in main file
279
static bool in_readarchive = false;
281
static bool mbCheck(bool valid=false, mbCmdType cur_cmd=MB_NONE)
283
if (cur_cmd == MB_READARCHIVE)
284
in_readarchive = true;
285
else if (in_readarchive) // skip if reading archive files, see comment above
288
if (motion_pos >= 0) {
289
fprintf(ERROUT, "[ERROR]: illegal command inside motion block\n");
290
State::Instance()->cancelMotion();
295
if ((motion_pos >= 1) && (prev_motion_cmd != cur_cmd)) {
296
fprintf(ERROUT, "[ERROR]: command inside current motion block is different from previous\n");
297
State::Instance()->cancelMotion();
300
if (motion_pos >= 0) {
302
prev_motion_cmd = cur_cmd;
307
//------------------------------------------------------------------------------
310
RtFloat RiGaussianFilter(RtFloat x, RtFloat y, RtFloat xwidth, RtFloat ywidth)
312
x *= (RtFloat)2 / xwidth;
313
y *= (RtFloat)2 / ywidth;
314
return expf((RtFloat)-2 * (x*x + y*y));
317
RtFloat RiBoxFilter(RtFloat x, RtFloat y, RtFloat xwidth, RtFloat ywidth)
322
RtFloat RiTriangleFilter(RtFloat x, RtFloat y, RtFloat xwidth, RtFloat ywidth)
324
RtFloat hfx = xwidth * (RtFloat)0.5;
325
RtFloat hfy = ywidth * (RtFloat)0.5;
326
RtFloat ax = fabs(x), ay = fabs(y);
327
return MIN2((hfx-ax)/hfx, (hfy-ay)/hfy);
330
RtFloat RiCatmullRomFilter(RtFloat x, RtFloat y, RtFloat xwidth, RtFloat ywidth)
332
RtFloat r2 = (x*x + y*y);
333
RtFloat r = sqrt(r2);
334
return (r>=(RtFloat)2) ? (RtFloat)0 :
335
(r<(RtFloat)1) ? ((RtFloat)3*r*r2 - (RtFloat)5*r2 + (RtFloat)2) :
336
(-r*r2 + (RtFloat)5*r2 - (RtFloat)8*r + (RtFloat)4);
339
RtFloat RiSincFilter(RtFloat x, RtFloat y,
340
RtFloat xwidth, RtFloat ywidth)
345
if ((x>-RI_EPSILON) && (x<RI_EPSILON))
349
if ((y>-RI_EPSILON) && (y<RI_EPSILON))
356
//------------------------------------------------------------------------------
357
// separable versions of all of the above (though not necessarly exactly the same...)
358
RtFloat RiSepGaussianFilter(RtFloat v, RtFloat width)
360
v *= (RtFloat)2 / width;
361
return (RtFloat)expf((RtFloat)-2*v*v);
364
RtFloat RiSepBoxFilter(RtFloat v, RtFloat width)
369
RtFloat RiSepTriangleFilter(RtFloat v, RtFloat width)
371
RtFloat hf = width * (RtFloat)0.5;
372
return (hf - ABS(v)) / hf;
375
RtFloat RiSepCatmullRomFilter(RtFloat v, RtFloat width)
377
if (v < (RtFloat)-2) return (RtFloat)0;
378
if (v < (RtFloat)-1) return (RtFloat)0.5*((RtFloat)4 + v*((RtFloat) 8 + v*((RtFloat) 5 + v)));
379
if (v < (RtFloat) 0) return (RtFloat)0.5*((RtFloat)2 + v*v*((RtFloat)-5 + v* (RtFloat)-3));
380
if (v < (RtFloat) 1) return (RtFloat)0.5*((RtFloat)2 + v*v*((RtFloat)-5 + v* (RtFloat) 3));
381
if (v < (RtFloat) 2) return (RtFloat)0.5*((RtFloat)4 + v*((RtFloat)-8 + v*((RtFloat) 5 - v)));
385
RtFloat RiSepSincFilter(RtFloat v, RtFloat width)
388
if ((v > -RI_EPSILON) && (v < RI_EPSILON)) return (RtFloat)1;
389
return (sinf(v) / v);
392
//------------------------------------------------------------------------------
394
RtToken RiDeclare(const char* name, const char* declaration)
396
if (!mbCheck()) return NULL;
397
decParam_t dp = {0, 0, 0};
398
if (!parseDeclaration(declaration, &dp, NULL)) {
399
fprintf(ERROUT, "[ERROR]: RiDeclare() -> parameter declaration error\n");
402
State::Instance()->addDeclared(name, dp);
407
RtVoid RiBegin(RtToken name)
409
//if (name) newfile?;
410
State::Instance()->begin(name);
415
// free last token/parm array allocs
416
if (_tokens) delete[] _tokens;
417
if (_parms) delete[] _parms;
419
State::Instance()->end();
422
RtContextHandle RiGetContext()
427
RtVoid RiContext(RtContextHandle)
431
RtVoid RiFrameBegin(RtInt frame)
433
if (!mbCheck()) return;
434
State::Instance()->frameBegin(frame);
439
if (!mbCheck()) return;
440
State::Instance()->frameEnd();
443
RtVoid RiWorldBegin()
445
if (!mbCheck()) return;
446
State::Instance()->worldBegin();
451
if (!mbCheck()) return;
452
State::Instance()->worldEnd();
456
RtVoid RiFormat(RtInt xres, RtInt yres, RtFloat aspect)
458
if (!mbCheck()) return;
459
Options& options = State::Instance()->topOptions();
460
// if negative: use defaults
461
if (xres>=0) options.xRes = xres;
462
if (yres>=0) options.yRes = yres;
463
if (aspect>=0) options.pixelAspectRatio = aspect;
464
// also affects other related options
465
options.frameAspectRatio = options.pixelAspectRatio * (xres / (float)yres);
467
options.left = -options.frameAspectRatio;
468
options.right = options.frameAspectRatio;
469
options.bottom = -1.f;
475
options.bottom = -1.f/options.frameAspectRatio;
476
options.top = 1.f/options.frameAspectRatio;
480
RtVoid RiFrameAspectRatio(RtFloat aspect)
482
if (!mbCheck()) return;
483
Options& options = State::Instance()->topOptions();
484
options.frameAspectRatio = aspect;
485
State::Instance()->resetFrameAspect = true;
488
RtVoid RiScreenWindow(RtFloat left, RtFloat right, RtFloat bot, RtFloat top)
490
if (!mbCheck()) return;
491
Options& options = State::Instance()->topOptions();
493
options.right = right;
494
options.bottom = bot;
496
State::Instance()->resetScrWin = true;
499
RtVoid RiCropWindow(RtFloat xmin, RtFloat xmax, RtFloat ymin, RtFloat ymax)
501
if (!mbCheck()) return;
502
Options& options = State::Instance()->topOptions();
509
RtVoid RiProjection(RtToken name, ...)
511
BUILD_TOKENPARAM_LIST(name)
512
RiProjectionV(name, n, _tokens, _parms);
515
RtVoid RiProjectionV(RtToken name, RtInt n, RtToken tokens[], RtPointer parms[])
517
if (!mbCheck(true, MB_PROJECTION)) return;
518
Options& options = State::Instance()->topOptions();
519
if (!strcmp(name, RI_PERSPECTIVE)) {
520
options.projection = Options::PROJ_PERSPECTIVE;
521
// optional param 'fov'
522
for (int i=0; i<n; i++) {
523
if (!strcmp(tokens[i], RI_FOV)) {
524
options.fov = *((RtFloat*)parms[i]);
530
else if (!strcmp(name, RI_ORTHOGRAPHIC))
531
options.projection = Options::PROJ_ORTHOGRAPHIC;
533
fprintf(ERROUT, "[WARNING]: RiProjection() -> unknown projection type '%s'\n", name);
536
RtVoid RiClipping(RtFloat hither, RtFloat yon)
538
if (!mbCheck()) return;
539
Options& options = State::Instance()->topOptions();
540
options.nearClip = hither;
541
options.farClip = yon;
544
RtVoid RiClippingPlane(RtFloat x, RtFloat y, RtFloat z, RtFloat nx, RtFloat ny, RtFloat nz)
546
if (!mbCheck()) return;
548
fprintf(ERROUT, "'ClippingPlane' not implemented (yet)\n");
551
RtVoid RiDepthOfField(RtFloat fstop, RtFloat focallength, RtFloat focaldistance)
553
if (!mbCheck()) return;
554
Options& options = State::Instance()->topOptions();
555
options.fStop = fstop;
556
options.focalLength = focallength;
557
options.focalDistance = focaldistance;
560
RtVoid RiShutter(RtFloat min, RtFloat max)
562
if (!mbCheck()) return;
563
Options& options = State::Instance()->topOptions();
564
options.closeShutter = min;
565
options.closeShutter = max;
569
RtVoid RiPixelVariance(RtFloat variation)
571
if (!mbCheck()) return;
572
Options& options = State::Instance()->topOptions();
573
options.pixelVariance = variation;
576
RtVoid RiPixelSamples(RtFloat xsamples, RtFloat ysamples)
578
if (!mbCheck()) return;
579
Options& options = State::Instance()->topOptions();
580
options.xSamples = xsamples;
581
options.ySamples = ysamples;
584
RtVoid RiPixelFilter(RtFilterFunc filterfunc, RtFloat xwidth, RtFloat ywidth)
586
if (!mbCheck()) return;
587
Options& options = State::Instance()->topOptions();
588
options.pixelFilter = filterfunc;
589
options.xWidth = xwidth;
590
options.yWidth = ywidth;
593
RtVoid RiExposure(RtFloat gain, RtFloat gamma)
595
if (!mbCheck()) return;
596
Options& options = State::Instance()->topOptions();
598
options.gamma = gamma;
601
RtVoid RiImager(RtToken name, ...)
603
BUILD_TOKENPARAM_LIST(name)
604
RiImagerV(name, n, _tokens, _parms);
607
RtVoid RiImagerV(RtToken name, RtInt n, RtToken tokens[], RtPointer parms[])
609
if (!mbCheck()) return;
611
fprintf(ERROUT, "'Imager' not implemented (yet)\n");
614
RtVoid RiQuantize(RtToken type, RtInt one, RtInt min, RtInt max, RtFloat ampl)
616
if (!mbCheck()) return;
617
Options& options = State::Instance()->topOptions();
618
if (!strcmp(type, RI_RGBA)) {
622
options.cqDitherAmplitude = ampl;
624
else if (!strcmp(type, RI_Z)) {
628
options.zqDitherAmplitude = ampl;
631
fprintf(ERROUT, "Unknown quantizer: '%s'\n", type);
634
RtVoid RiDisplay(const char* name, RtToken type, RtToken mode, ...)
636
BUILD_TOKENPARAM_LIST(mode)
637
RiDisplayV(name, type, mode, n, _tokens, _parms);
640
RtVoid RiDisplayV(const char* name, RtToken type, RtToken mode,
641
RtInt n, RtToken tokens[], RtPointer parms[])
643
if (!mbCheck()) return;
644
Options& options = State::Instance()->topOptions();
646
strncpy(options.displayName, name, 80);
648
if (!strcmp(type, RI_FRAMEBUFFER))
649
options.displayType = Options::DT_FRAMEBUFFER;
650
else if (!strcmp(type, RI_FILE))
651
options.displayType = Options::DT_FILE;
652
else if (!strcmp(type, RI_ZFILE))
653
options.displayType = Options::DT_ZFILE;
655
fprintf(ERROUT, "Display type unknown: '%s'\n", type);
657
if (!strcmp(mode, RI_RGB))
658
options.displayMode = Options::DM_RGB;
659
else if (!strcmp(mode, RI_RGBA))
660
options.displayMode = Options::DM_RGBA;
661
else if (!strcmp(mode, RI_RGBZ))
662
options.displayMode = Options::DM_RGBZ;
663
else if (!strcmp(mode, RI_RGBAZ))
664
options.displayMode = Options::DM_RGBAZ;
665
else if (!strcmp(mode, RI_A))
666
options.displayMode = Options::DM_A;
667
else if (!strcmp(mode, RI_Z))
668
options.displayMode = Options::DM_Z;
669
else if (!strcmp(mode, RI_AZ))
670
options.displayMode = Options::DM_AZ;
672
fprintf(ERROUT, "[WARNING]: Display mode unknown: '%s'\n", mode);
673
// no other parameters used yet
676
// Additional Options
677
RtVoid RiHider(RtToken type, ...)
679
BUILD_TOKENPARAM_LIST(type)
680
RiHiderV(type, n, _tokens, _parms);
683
RtVoid RiHiderV(RtToken type, RtInt n, RtToken tokens[], RtPointer parms[])
685
if (!mbCheck()) return;
686
State* state = State::Instance();
687
state->verifyMode(MODE_BASE, RIE_NOTSTARTED, "RiHiderV()");
688
Options& options = state->topOptions();
689
if (!strcmp(type, RI_HIDDEN))
690
options.hider = Options::HD_HIDDEN;
691
else if (!strcmp(type, RI_RAYTRACE))
692
options.hider = Options::HD_RAYTRACE;
693
else if (!strcmp(type, RI_HYBRID))
694
options.hider = Options::HD_HYBRID;
696
fprintf(ERROUT, "[WARNING] -> State::worldBegin(): Unknown hider '%s', will use 'hidden' instead\n", type);
697
options.hider = Options::HD_HIDDEN;
699
// optional jitter param
700
for (int i=0; i<n; i++) {
701
if (!strcmp(tokens[i], RI_JITTER)) {
702
options.jitter = MAX2(0.f, MIN2(1.f, *((RtFloat*)parms[i])));
708
RtVoid RiColorSamples(RtInt n, RtFloat nRGB[], RtFloat RGBn[])
710
if (!mbCheck()) return;
711
// TODO (possibly), for now fixed at 3 (RGB)
712
fprintf(ERROUT, "'ColorSamples' not implemented (yet)\n");
715
RtVoid RiRelativeDetail(RtFloat relativedetail)
717
if (!mbCheck()) return;
718
Options& options = State::Instance()->topOptions();
719
options.relativeDetail = relativedetail;
722
// Implementation-specific Options
723
RtVoid RiOption(RtToken name, ...)
725
if (!mbCheck()) return;
726
BUILD_TOKENPARAM_LIST(name)
727
RiOptionV(name, n, _tokens, _parms);
730
RtVoid RiOptionV(RtToken name, RtInt n, RtToken tokens[], RtPointer parms[])
732
if (!mbCheck()) return;
733
Options& options = State::Instance()->topOptions();
734
if (!strcmp(name, "hider")) {
735
for (int i=0; i<n; ++i) {
736
if (!strcmp(tokens[i], RI_JITTER))
737
options.jitter = MAX2(0.f, MIN2(1.f, *((RtFloat*)parms[i])));
739
fprintf(ERROUT, "Unknown hider option '%s'\n", tokens[i]);
742
else if (!strcmp(name, "limits")) {
743
for (int i=0; i<n; ++i) {
744
if (!strcmp(tokens[i], RI_BUCKETSIZE))
745
options.bucketsize = ABS(*((RtInt*)parms[i]));
746
else if (!strcmp(tokens[i], RI_TEXTUREMEMORY))
747
options.texturememory = ABS(*((RtInt*)parms[i]))*1024;
748
else if (!strcmp(tokens[i], RI_GRIDSIZE))
749
options.gridsize = ABS(*((RtInt*)parms[i]));
750
else if (!strcmp(tokens[i], RI_EYESPLITS))
751
options.eyesplits = ABS(*((RtInt*)parms[i]));
753
fprintf(ERROUT, "Unknown limits option '%s'\n", tokens[i]);
757
fprintf(ERROUT, "Unknown option '%s'\n", name);
760
//------------------------------------------------------------------------------
761
// helper function to get declared parameter values for shaders
762
bool getShaderParams(SlShaderInstance* SI, RtInt n, RtToken tokens[], RtPointer parms[])
764
// get declared params
765
for (int i=0; i<n; i++) {
766
// skip special case 'code' if found
767
if (!strcmp(tokens[i], "code")) continue;
769
decParam_t dp = {0, 0, 0};
770
char inline_name[256] = {0};
771
const char* varname = tokens[i];
772
if (!State::Instance()->parameterFromName(varname, dp, inline_name)) continue;
773
if (inline_name[0] != 0) varname = inline_name; // was inline declared
775
if (dp.ct_flags & DT_FLOAT)
776
SI->setParameter(varname, SL_FLOAT, ((dp.ct_flags & SC_VARYING)!=0), dp.arlen, parms[i]);
777
else if (dp.ct_flags & DT_STRING)
778
SI->setParameter(varname, SL_STRING, ((dp.ct_flags & SC_VARYING)!=0), dp.arlen, parms[i]);
779
else if (dp.ct_flags & DT_FLOAT3MASK) {
780
// to simplify, point/vector/normal/color all accessed as vector,
781
// all are float[3] typedefs anyway
782
RtVector *parm = (RtVector*)parms[i];
783
RtVector* tv = new RtVector[dp.arlen];
784
// current space transform
785
const Transform* xf = SI->xform;
786
if (dp.ct_flags & DT_POINT) {
787
for (int j=0; j<dp.arlen; j++) {
788
Point3 t = *xf * Point3(parm[j][0], parm[j][1], parm[j][2]);
789
tv[j][0] = t.x, tv[j][1] = t.y, tv[j][2] = t.z;
791
SI->setParameter(varname, SL_POINT, ((dp.ct_flags & SC_VARYING)!=0), dp.arlen, tv);
793
else if (dp.ct_flags & DT_VECTOR) {
794
for (int j=0; j<dp.arlen; j++) {
795
Vector t = *xf * Vector(parm[j][0], parm[j][1], parm[j][2]);
796
tv[j][0] = t.x, tv[j][1] = t.y, tv[j][2] = t.z;
798
SI->setParameter(varname, SL_VECTOR, ((dp.ct_flags & SC_VARYING)!=0), dp.arlen, tv);
800
else if (dp.ct_flags & DT_NORMAL) {
804
for (int j=0; j<dp.arlen; j++) {
805
Vector t = nxf * Vector(parm[j][0], parm[j][1], parm[j][2]);
806
tv[j][0] = t.x, tv[j][1] = t.y, tv[j][2] = t.z;
808
SI->setParameter(varname, SL_NORMAL, ((dp.ct_flags & SC_VARYING)!=0), dp.arlen, tv);
810
else if (dp.ct_flags & DT_COLOR) // no xform
811
SI->setParameter(varname, SL_COLOR, ((dp.ct_flags & SC_VARYING)!=0), dp.arlen, parms[i]);
814
else if (dp.ct_flags & DT_MATRIX)
815
SI->setParameter(varname, SL_MATRIX, ((dp.ct_flags & SC_VARYING)!=0), dp.arlen, parms[i]);
817
// RSL does not have hpoint type, needs conversion to point. TODO
818
else if (ct_flags & DT_HPOINT)
819
SI->setParameter(varname, SL_HPOINT, ((dp.ct_flags & SC_VARYING)!=0), dp.arlen, parms[i]);
820
// integer type also not supported, should generate error?
821
else if (ct_flags & DT_INT)
822
SI->setParameter(varname, SL_INTEGER, ((dp.ct_flags & SC_VARYING)!=0), dp.arlen, parms[i]);
825
fprintf(ERROUT, "[ERROR]: getShaderParams() -> unexpected unknown type '%s'\n", tokens[i]);
831
//------------------------------------------------------------------------------
833
RtVoid RiAttributeBegin()
835
State::Instance()->attributeBegin();
838
RtVoid RiAttributeEnd()
840
State::Instance()->attributeEnd();
844
RtVoid RiColor(RtColor color)
846
if (!mbCheck(true, MB_COLOR)) return;
847
Attributes& attr = State::Instance()->topAttributes();
848
attr.color[0] = color[0];
849
attr.color[1] = color[1];
850
attr.color[2] = color[2];
853
RtVoid RiOpacity(RtColor color)
855
if (!mbCheck(true, MB_OPACITY)) return;
856
Attributes& attr = State::Instance()->topAttributes();
857
attr.opacity[0] = color[0];
858
attr.opacity[1] = color[1];
859
attr.opacity[2] = color[2];
862
// Texture Coordinates
863
RtVoid RiTextureCoordinates(RtFloat s1, RtFloat t1, RtFloat s2, RtFloat t2,
864
RtFloat s3, RtFloat t3, RtFloat s4, RtFloat t4)
866
if (!mbCheck()) return;
867
Attributes& attr = State::Instance()->topAttributes();
868
attr.texCoords[0] = s1;
869
attr.texCoords[1] = t1;
870
attr.texCoords[2] = s2;
871
attr.texCoords[3] = t2;
872
attr.texCoords[4] = s3;
873
attr.texCoords[5] = t3;
874
attr.texCoords[6] = s4;
875
attr.texCoords[7] = t4;
879
RtLightHandle RiLightSource(RtToken name, ...)
881
BUILD_TOKENPARAM_LIST(name)
882
return RiLightSourceV(name, n, _tokens, _parms);
885
RtLightHandle RiLightSourceV(RtToken name, RtInt n, RtToken tokens[], RtPointer parms[])
887
if (!mbCheck(true, MB_LIGHTSOURCE)) return NULL;
889
State* state = State::Instance();
891
SlShaderInstance* SI;
892
SI = state->loadShader(name, SL_LIGHT); // on success will also add lightshader to current lightsource list
893
if (SI == NULL) return NULL; // load failed
895
// run default initialization code
897
// then set userdefined params, possibly overriding defaults
898
getShaderParams(SI, n, tokens, parms);
903
RtLightHandle RiAreaLightSource(RtToken name, ...)
905
BUILD_TOKENPARAM_LIST(name)
906
RtLightHandle LH = RiAreaLightSourceV(name, n, _tokens, _parms);
910
RtLightHandle RiAreaLightSourceV(RtToken name, RtInt n, RtToken tokens[], RtPointer parms[])
912
if (!mbCheck(true, MB_AREALIGHTSOURCE)) return NULL;
914
fprintf(ERROUT, "'AreaLightSource' not implemented (yet)\n");
918
RtVoid RiIlluminate(RtLightHandle light, RtBoolean onoff)
920
if (!mbCheck()) return;
921
State::Instance()->setLight(light, onoff);
925
RtVoid RiSurface(RtToken name, ...)
927
BUILD_TOKENPARAM_LIST(name)
928
RiSurfaceV(name, n, _tokens, _parms);
931
RtVoid RiSurfaceV(RtToken name, RtInt n, RtToken tokens[], RtPointer parms[])
933
if (!mbCheck(true, MB_SURFACE)) return;
935
State* state = State::Instance();
937
SlShaderInstance* SI;
938
SI = state->loadShader(name, SL_SURFACE);
939
if (SI == NULL) return; // load failed
941
// run default initialization code
943
// then set userdefined params, possibly overriding defaults
944
getShaderParams(SI, n, tokens, parms);
947
// Displacement Shading
948
RtVoid RiDisplacement(RtToken name, ...)
950
BUILD_TOKENPARAM_LIST(name)
951
RiDisplacementV(name, n, _tokens, _parms);
954
RtVoid RiDisplacementV(RtToken name, RtInt n, RtToken tokens[], RtPointer parms[])
956
if (!mbCheck(true, MB_DISPLACEMENT)) return;
958
State* state = State::Instance();
960
SlShaderInstance* SI;
961
SI = state->loadShader(name, SL_DISPLACEMENT);
962
if (SI == NULL) return; // load failed
964
// run default initialization code
966
// then set userdefined params, possibly overriding defaults
967
getShaderParams(SI, n, tokens, parms);
971
RtVoid RiAtmosphere(RtToken name, ...)
973
BUILD_TOKENPARAM_LIST(name)
974
RiAtmosphereV(name, n, _tokens, _parms);
977
RtVoid RiAtmosphereV(RtToken name,RtInt n, RtToken tokens[], RtPointer parms[])
979
if (!mbCheck(true, MB_ATMOSPHERE)) return;
981
State* state = State::Instance();
983
SlShaderInstance* SI;
984
SI = state->loadShader(name, SL_VOLUME);
985
if (SI == NULL) return; // load failed
987
// run default initialization code
989
// then set userdefined params, possibly overriding defaults
990
getShaderParams(SI, n, tokens, parms);
993
RtVoid RiInterior(RtToken name, ...)
995
BUILD_TOKENPARAM_LIST(name)
996
RiInteriorV(name, n, _tokens, _parms);
999
RtVoid RiInteriorV(RtToken name, RtInt n, RtToken tokens[], RtPointer parms[])
1001
if (!mbCheck(true, MB_INTERIOR)) return;
1003
fprintf(ERROUT, "'Interior' not implemented (yet)\n");
1006
RtVoid RiExterior(RtToken name, ...)
1008
BUILD_TOKENPARAM_LIST(name)
1009
RiExteriorV(name, n, _tokens, _parms);
1012
RtVoid RiExteriorV(RtToken name, RtInt n, RtToken tokens[], RtPointer parms[])
1014
if (!mbCheck(true, MB_EXTERIOR)) return;
1016
fprintf(ERROUT, "'Exterior' not implemented (yet)\n");
1020
RtVoid RiShadingRate(RtFloat size)
1022
if (!mbCheck()) return;
1023
Attributes& attr = State::Instance()->topAttributes();
1024
// since the diceable test works with edgelengths and not area's,
1025
// set effectiveShadingRate to some approximate edgelength assuming a square area
1026
attr.effectiveShadingRate = sqrtf(size);
1029
// ShadingInterpolation
1030
RtVoid RiShadingInterpolation(RtToken type)
1032
if (!mbCheck()) return;
1033
Attributes& attr = State::Instance()->topAttributes();
1034
if (!strcmp(type, RI_CONSTANT))
1035
attr.flags &= ~AF_SMOOTH;
1036
else if (!strcmp(type, RI_SMOOTH))
1037
attr.flags |= AF_SMOOTH;
1039
fprintf(ERROUT, "[WARNING]: ShadingInterpolation type unknown: '%s'\n", type);
1043
RtVoid RiMatte(RtBoolean onoff)
1045
if (!mbCheck()) return;
1046
Attributes& attr = State::Instance()->topAttributes();
1047
if (onoff == (RtBoolean)RI_TRUE)
1048
attr.flags |= AF_MATTE;
1050
attr.flags &= ~AF_MATTE;
1054
RtVoid RiBound(RtBound bound)
1056
if (!mbCheck(true, MB_BOUND)) return;
1057
// currently not used
1059
Attributes& attr = State::Instance()->topAttributes();
1060
attr.bound[0] = bound[0];
1061
attr.bound[1] = bound[1];
1062
attr.bound[2] = bound[2];
1063
attr.bound[3] = bound[3];
1064
attr.bound[4] = bound[4];
1065
attr.bound[5] = bound[5];
1070
RtVoid RiDetail(RtBound bound)
1072
if (!mbCheck(true, MB_DETAIL)) return;
1073
// currently not used
1075
Attributes& attr = State::Instance()->topAttributes();
1076
attr.detail[0] = bound[0];
1077
attr.detail[1] = bound[1];
1078
attr.detail[2] = bound[2];
1079
attr.detail[3] = bound[3];
1080
attr.detail[4] = bound[4];
1081
attr.detail[5] = bound[5];
1085
RtVoid RiDetailRange(RtFloat minvis, RtFloat lowtran, RtFloat uptran, RtFloat maxvis)
1087
// currently not used
1089
Attributes& attr = State::Instance()->topAttributes();
1090
attr.minVisible = minvis;
1091
attr.lowerTransition = lowtran;
1092
attr.upperTransition = uptran;
1093
attr.maxVisible = maxvis;
1097
// Geometric Approximation
1098
RtVoid RiGeometricApproximation(RtToken type, RtFloat value)
1100
if (!mbCheck()) return;
1101
// currently not used
1103
Attributes& attr = State::Instance()->topAttributes();
1104
if (!strcmp(type, RI_FLATNESS))
1105
attr.valueApproximation = value;
1107
fprintf(ERROUT, "[WARNING]: GeometricApproximation type unknown: '%s'\n", type);
1111
// Orientation and Sides
1112
RtVoid RiOrientation(RtToken orientation)
1114
if (!mbCheck()) return;
1115
Attributes& attr = State::Instance()->topAttributes();
1116
bool isrh = State::Instance()->currentTransform().handedness();
1117
if (!strcmp(orientation, RI_OUTSIDE))
1118
attr.flags &= ~AF_ORIENTATION;
1119
else if (!strcmp(orientation, RI_INSIDE))
1120
attr.flags |= AF_ORIENTATION;
1121
else if (!strcmp(orientation, RI_LH)) {
1122
if (isrh) attr.flags |= AF_ORIENTATION; else attr.flags &= ~AF_ORIENTATION;
1124
else if (!strcmp(orientation, RI_RH)) {
1125
if (isrh) attr.flags &= ~AF_ORIENTATION; else attr.flags |= AF_ORIENTATION;
1128
fprintf(ERROUT, "[WARNING]: Orientation unknown: '%s'\n", orientation);
1131
RtVoid RiReverseOrientation()
1133
if (!mbCheck()) return;
1134
Attributes& attr = State::Instance()->topAttributes();
1135
attr.flags ^= AF_ORIENTATION;
1138
RtVoid RiSides(RtInt sides)
1140
if (!mbCheck()) return;
1141
Attributes& attr = State::Instance()->topAttributes();
1143
attr.flags |= AF_SIDES1;
1145
attr.flags &= ~AF_SIDES1;
1151
if (!mbCheck()) return;
1152
State* state = State::Instance();
1153
const Transform idt = state->transformIdentity();
1154
Transform& curT = state->currentTransform();
1155
for (int i=0; i<4; ++i)
1156
for (int j=0; j<4; ++j)
1157
curT[i][j] = idt[i][j];
1160
RtVoid RiTransform(RtMatrix transform)
1162
if (!mbCheck(true, MB_TRANSFORM)) return;
1163
State* state = State::Instance();
1164
const Transform idt = state->transformIdentity();
1166
mulMMM(nm, *idt.getRtMatrixPtr(), transform);
1167
// NOTE motion_pos is already incremented at this point, so have to subtract 1,
1168
// is ok, since currentTransform only checks for negative val. anyway
1169
Transform& curT = state->currentTransform(motion_pos - 1);
1170
for (int i=0; i<4; ++i)
1171
for (int j=0; j<4; ++j)
1172
curT[i][j] = nm[i][j];
1175
RtVoid RiConcatTransform(RtMatrix transform)
1177
if (!mbCheck(true, MB_CONCATTRANSFORM)) return;
1178
Transform& curT = State::Instance()->currentTransform(motion_pos - 1);
1179
curT *= Transform(transform);
1182
RtVoid RiPerspective(RtFloat fov)
1184
if (!mbCheck(true, MB_PERSPECTIVE)) return;
1185
State* state = State::Instance();
1186
Transform& curT = state->currentTransform(motion_pos - 1);
1187
Options &options = state->topOptions();
1188
curT.perspective(fov, options.nearClip, options.farClip);
1191
RtVoid RiTranslate(RtFloat dx, RtFloat dy, RtFloat dz)
1193
if (!mbCheck(true, MB_TRANSLATE)) return;
1194
Transform& curT = State::Instance()->currentTransform(motion_pos - 1);
1195
curT.translate(dx, dy, dz);
1198
RtVoid RiRotate(RtFloat angle, RtFloat dx, RtFloat dy, RtFloat dz)
1200
if (!mbCheck(true, MB_ROTATE)) return;
1201
Transform& curT = State::Instance()->currentTransform(motion_pos - 1);
1202
curT.rotate(angle, dx, dy, dz);
1205
RtVoid RiScale(RtFloat sx, RtFloat sy, RtFloat sz)
1207
if (!mbCheck(true, MB_SCALE)) return;
1208
Transform& curT = State::Instance()->currentTransform(motion_pos - 1);
1209
curT.scale(sx, sy, sz);
1212
RtVoid RiSkew(RtFloat angle, RtFloat dx1, RtFloat dy1, RtFloat dz1,
1213
RtFloat dx2, RtFloat dy2, RtFloat dz2)
1215
if (!mbCheck(true, MB_SKEW)) return;
1216
Transform& curT = State::Instance()->currentTransform(motion_pos - 1);
1217
curT.skew(angle, dx1, dy1, dz1, dx2, dy2, dz2);
1220
RtVoid RiDeformation(RtToken name, ...)
1222
BUILD_TOKENPARAM_LIST(name)
1223
RiDeformationV(name, n, _tokens, _parms);
1226
RtVoid RiDeformationV(RtToken name, RtInt n, RtToken tokens[], RtPointer parms[])
1228
if (!mbCheck(true, MB_DEFORMATION)) return;
1230
fprintf(ERROUT, "'Deformation' not implemented (yet)\n");
1233
// Named Coordinate Systems
1234
RtVoid RiCoordinateSystem(RtToken space)
1236
if (!mbCheck()) return;
1237
State::Instance()->addNamedCoordSys(space);
1240
RtVoid RiCoordSysTransform(RtToken space)
1242
if (!mbCheck()) return;
1243
State::Instance()->activateNamedCoordSys(space);
1246
RtPoint* RiTransformPoints(RtToken fromspace, RtToken tospace, RtInt n, RtPoint points[])
1248
if (!mbCheck()) return NULL;
1250
fprintf(ERROUT, "RiTransformPoints() not implemented (yet)\n");
1254
// Transformation Stack
1255
RtVoid RiTransformBegin()
1257
State::Instance()->transformBegin();
1260
RtVoid RiTransformEnd()
1262
State::Instance()->transformEnd();
1265
// Implementation-specific Attributes
1266
RtVoid RiAttribute(RtToken name, ...)
1268
BUILD_TOKENPARAM_LIST(name)
1269
RiAttributeV(name, n, _tokens, _parms);
1272
RtVoid RiAttributeV(RtToken name, RtInt n, RtToken tokens[], RtPointer parms[])
1274
if (!mbCheck()) return;
1275
Attributes& attr = State::Instance()->topAttributes();
1276
if (!strcmp(name, "displacementbound")) {
1277
for (int i=0; i<n; ++i) {
1278
if (!strcmp(tokens[i], RI_SPHERE))
1279
attr.displacementbound_sphere = *((RtFloat*)parms[i]);
1280
// TODO coordinatesystem
1282
fprintf(ERROUT, "Unknown displacementbound attribute: '%s'\n", tokens[i]);
1285
else if (!strcmp(name, "dice")) {
1286
for (int i=0; i<n; ++i) {
1287
if (!strcmp(tokens[i], RI_BINARY))
1288
attr.flags |= (*((int*)parms[i]) != 0) ? AF_DICE_BINARY : 0;
1290
fprintf(ERROUT, "Unknown dice attribute: '%s'\n", tokens[i]);
1293
else fprintf(ERROUT, "Unknown attribute: '%s'\n", name);
1296
//------------------------------------------------------------------------------
1300
RtVoid RiPolygon(RtInt nverts, ...)
1302
BUILD_TOKENPARAM_LIST(nverts)
1303
RiPolygonV(nverts, n, _tokens, _parms);
1306
RtVoid RiPolygonV(RtInt nverts, RtInt n, RtToken tokens[], RtPointer parms[])
1308
if (!mbCheck(true, MB_POLYGON)) return;
1309
// three verts at least
1311
fprintf(ERROUT, "[ERROR]: RiPolygonV() -> must have at least three vertices\n");
1314
if (!haveP("RiPolygonV", n, tokens, parms)) return;
1315
State::Instance()->insert(new Polygon(nverts, n, tokens, parms), motion_pos);
1318
RtVoid RiGeneralPolygon(RtInt nloops, RtInt nverts[], ...)
1320
BUILD_TOKENPARAM_LIST(nverts)
1321
RiGeneralPolygonV(nloops, nverts, n, _tokens, _parms);
1324
RtVoid RiGeneralPolygonV(RtInt nloops, RtInt nverts[],
1325
RtInt n, RtToken tokens[], RtPointer parms[])
1328
fprintf(ERROUT, "'GeneralPolygon' not implemented (yet)\n");
1329
// not implemented, so no motion block update
1332
RtVoid RiPointsPolygons(RtInt npolys, RtInt nverts[], RtInt verts[], ...)
1334
BUILD_TOKENPARAM_LIST(verts)
1335
RiPointsPolygonsV(npolys, nverts, verts, n, _tokens, _parms);
1338
RtVoid RiPointsPolygonsV(RtInt npolys, RtInt nverts[], RtInt verts[],
1339
RtInt n, RtToken tokens[], RtPointer parms[])
1341
if (!mbCheck(true, MB_POINTSPOLYGONS)) return;
1342
if (!haveP("RiPointsPolygons", n, tokens, parms)) return;
1343
State::Instance()->insert(new PointsPolygons(npolys, nverts, verts, n, tokens, parms), motion_pos);
1346
RtVoid RiPointsGeneralPolygons(RtInt npolys, RtInt nloops[], RtInt nverts[], RtInt verts[], ...)
1348
BUILD_TOKENPARAM_LIST(verts)
1349
RiPointsGeneralPolygonsV(npolys, nloops, nverts, verts, n, _tokens, _parms);
1352
RtVoid RiPointsGeneralPolygonsV(RtInt npolys, RtInt nloops[], RtInt nverts[],
1353
RtInt verts[], RtInt n, RtToken tokens[], RtPointer parms[])
1356
fprintf(ERROUT, "'PointsGeneralPolygons' not implemented (yet)\n");
1357
// not implemented, so no motion block update
1361
RtVoid RiBasis(RtBasis ubasis, RtInt ustep, RtBasis vbasis, RtInt vstep)
1363
if (!mbCheck()) return;
1364
State* state = State::Instance();
1365
// basis allocation is handled by state
1366
state->newCubicBasis(ubasis, vbasis);
1367
Attributes& attr = state->topAttributes();
1368
attr.cubicBasisStep[0] = ustep;
1369
attr.cubicBasisStep[1] = vstep;
1372
RtVoid RiPatch(RtToken type, ...)
1374
BUILD_TOKENPARAM_LIST(type)
1375
RiPatchV(type, n, _tokens, _parms);
1378
RtVoid RiPatchV(RtToken type, RtInt n, RtToken tokens[], RtPointer parms[])
1380
if (!mbCheck(true, MB_PATCH)) return;
1381
if (!haveP_any("RiPatchV", n, tokens, parms)) return;
1382
State* state = State::Instance();
1383
if (!strcmp(type, RI_BILINEAR))
1384
state->insert(new BilinearPatch(n, tokens, parms), motion_pos);
1385
else if (!strcmp(type, RI_BICUBIC))
1386
state->insert(new BicubicPatch(n, tokens, parms), motion_pos);
1388
fprintf(ERROUT, "RiPatchV(): Unknown type '%s'\n", type);
1391
RtVoid RiPatchMesh(RtToken type, RtInt nu, RtToken uwrap,
1392
RtInt nv, RtToken vwrap, ...)
1394
BUILD_TOKENPARAM_LIST(vwrap)
1395
RiPatchMeshV(type, nu, uwrap, nv, vwrap, n, _tokens, _parms);
1398
RtVoid RiPatchMeshV(RtToken type, RtInt nu, RtToken uwrap,
1399
RtInt nv, RtToken vwrap,
1400
RtInt n, RtToken tokens[], RtPointer parms[])
1402
if (!mbCheck(true, MB_PATCHMESH)) return;
1403
if (!haveP_any("RiPatchMeshV", n, tokens, parms)) return;
1404
bool bilinear = true; // BILINEAR default
1405
if (!strcmp(type, RI_BICUBIC))
1407
else if (strcmp(type, RI_BILINEAR)) {
1409
fprintf(ERROUT, "RiPatchV(): Unknown type '%s'", type);
1413
bool uperiodic = false, vperiodic = false;
1414
if (!strcmp(uwrap, RI_PERIODIC))
1416
else if (strcmp(uwrap, RI_NONPERIODIC)) // unknown, assume uperiodic == false
1417
fprintf(ERROUT, "RiPatchMeshV(): unknown uwrap mode '%s'\n", uwrap);
1418
if (!strcmp(vwrap, RI_PERIODIC))
1420
else if (strcmp(vwrap, RI_NONPERIODIC)) // unknown, assume vperiodic == false
1421
fprintf(ERROUT, "RiPatchMeshV(): unknown vwrap mode '%s'\n", vwrap);
1423
State::Instance()->insert(new BilinearPatchMesh(nu, uperiodic, nv, vperiodic, n, tokens, parms), motion_pos);
1425
State::Instance()->insert(new BicubicPatchMesh(nu, uperiodic, nv, vperiodic, n, tokens, parms), motion_pos);
1428
RtVoid RiNuPatch(RtInt nu, RtInt uorder, RtFloat uknot[], RtFloat umin,
1429
RtFloat umax, RtInt nv, RtInt vorder, RtFloat vknot[],
1430
RtFloat vmin, RtFloat vmax, ...)
1432
BUILD_TOKENPARAM_LIST(vmax)
1433
RiNuPatchV(nu, uorder, uknot, umin, umax, nv, vorder, vknot, vmin, vmax, n, _tokens, _parms);
1436
RtVoid RiNuPatchV(RtInt nu, RtInt uorder, RtFloat uknot[], RtFloat umin,
1437
RtFloat umax, RtInt nv, RtInt vorder, RtFloat vknot[],
1438
RtFloat vmin, RtFloat vmax,
1439
RtInt n, RtToken tokens[], RtPointer parms[])
1441
if (!mbCheck(true, MB_NUPATCH)) return;
1442
if (!haveP_Pw("RiNuPatchV", n, tokens, parms)) return;
1443
// check that knots arrays are in increasing order
1444
for (int i=0; i<(nu + uorder - 1); ++i)
1445
if (uknot[i] > uknot[i+1]) {
1446
fprintf(ERROUT, "RiNuPatchV(): invalid decreasing knot value in uknot array\n");
1449
for (int i=0; i<(nv + vorder - 1); ++i)
1450
if (vknot[i] > vknot[i+1]) {
1451
fprintf(ERROUT, "RiNuPatchV(): invalid decreasing knot value in vknot array\n");
1454
// check that u/v min/max range is in valid range from the given knot arrays
1455
if (umin < uknot[uorder-1]) {
1456
fprintf(ERROUT, "RiNuPatchV(): umin value out of valid range [%f %f]\n", uknot[uorder-1], uknot[nu]);
1459
if (umax > uknot[nu]) {
1460
fprintf(ERROUT, "RiNuPatchV(): umax value out of valid range [%f %f]\n", uknot[uorder-1], uknot[nu]);
1463
if (vmin < vknot[vorder-1]) {
1464
fprintf(ERROUT, "RiNuPatchV(): vmin value out of valid range [%f %f]\n", vknot[vorder-1], vknot[nv]);
1467
if (vmax > vknot[nv]) {
1468
fprintf(ERROUT, "RiNuPatchV(): vmax value out of valid range [%f %f]\n", vknot[vorder-1], vknot[nv]);
1471
State::Instance()->insert(new NuPatch(nu, uorder, uknot, umin, umax,
1472
nv, vorder, vknot, vmin, vmax,
1473
n, tokens, parms), motion_pos);
1476
RtVoid RiTrimCurve(RtInt nloops, RtInt ncurves[], RtInt order[],
1477
RtFloat knot[], RtFloat min[], RtFloat max[], RtInt n[],
1478
RtFloat u[], RtFloat v[], RtFloat w[])
1480
if (!mbCheck()) return;
1482
fprintf(ERROUT, "'TrimCurve' not implemented (yet)\n");
1485
// Subdivision Meshes
1486
RtVoid RiSubdivisionMesh(RtToken mask, RtInt nf, RtInt nverts[],
1488
RtInt ntags, RtToken tags[], RtInt numargs[],
1489
RtInt intargs[], RtFloat floatargs[], ...)
1491
BUILD_TOKENPARAM_LIST(floatargs)
1492
RiSubdivisionMeshV(mask, nf, nverts, verts, ntags, tags, numargs, intargs, floatargs, n, _tokens, _parms);
1495
RtVoid RiSubdivisionMeshV(RtToken mask, RtInt nf, RtInt nverts[],
1496
RtInt verts[], RtInt ntags, RtToken tags[],
1497
RtInt nargs[], RtInt intargs[],
1498
RtFloat floatargs[], RtInt n,
1499
RtToken tokens[], RtPointer *parms)
1501
if (!mbCheck(true, MB_SUBDIVISIONMESH)) return;
1502
if (strcmp(mask, "catmull-clark")) {
1503
fprintf(ERROUT, "Unknown subdivision scheme '%s'\n", mask);
1506
State::Instance()->insert(new CCSubdivisionMesh(nf, nverts, verts, ntags, tags,
1507
nargs, intargs, floatargs, n, tokens, parms), motion_pos);
1512
RtVoid RiSphere(RtFloat radius, RtFloat zmin, RtFloat zmax, RtFloat tmax, ...)
1514
BUILD_TOKENPARAM_LIST(tmax)
1515
RiSphereV(radius, zmin, zmax, tmax, n, _tokens, _parms);
1518
RtVoid RiSphereV(RtFloat radius, RtFloat zmin, RtFloat zmax, RtFloat tmax,
1519
RtInt n, RtToken tokens[], RtPointer parms[])
1521
if (!mbCheck(true, MB_SPHERE)) return;
1522
State::Instance()->insert(new Sphere(radius, zmin, zmax, tmax, n, tokens, parms), motion_pos);
1525
RtVoid RiCone(RtFloat height, RtFloat radius, RtFloat tmax, ...)
1527
BUILD_TOKENPARAM_LIST(tmax)
1528
RiConeV(height, radius, tmax, n, _tokens, _parms);
1531
RtVoid RiConeV(RtFloat height, RtFloat radius, RtFloat tmax,
1532
RtInt n, RtToken tokens[], RtPointer parms[])
1534
if (!mbCheck(true, MB_CONE)) return;
1535
State::Instance()->insert(new Cone(height, radius, tmax, n, tokens, parms), motion_pos);
1538
RtVoid RiCylinder(RtFloat radius, RtFloat zmin, RtFloat zmax, RtFloat tmax, ...)
1540
BUILD_TOKENPARAM_LIST(tmax)
1541
RiCylinderV(radius, zmin, zmax, tmax, n, _tokens, _parms);
1544
RtVoid RiCylinderV(RtFloat radius, RtFloat zmin, RtFloat zmax, RtFloat tmax,
1545
RtInt n, RtToken tokens[], RtPointer parms[])
1547
if (!mbCheck(true, MB_CYLINDER)) return;
1548
State::Instance()->insert(new Cylinder(radius, zmin, zmax, tmax, n, tokens, parms), motion_pos);
1551
RtVoid RiHyperboloid(RtPoint point1, RtPoint point2, RtFloat tmax, ...)
1553
BUILD_TOKENPARAM_LIST(tmax)
1554
RiHyperboloidV(point1, point2, tmax, n, _tokens, _parms);
1557
RtVoid RiHyperboloidV(RtPoint point1, RtPoint point2, RtFloat tmax,
1558
RtInt n, RtToken tokens[], RtPointer parms[])
1560
if (!mbCheck(true, MB_HYPERBOLOID)) return;
1561
Point3 pt1(point1[0], point1[1], point1[2]);
1562
Point3 pt2(point2[0], point2[1], point2[2]);
1563
State::Instance()->insert(new Hyperboloid(pt1, pt2, tmax, n, tokens, parms), motion_pos);
1566
RtVoid RiParaboloid(RtFloat rmax, RtFloat zmin, RtFloat zmax, RtFloat tmax, ...)
1568
BUILD_TOKENPARAM_LIST(tmax)
1569
RiParaboloidV(rmax, zmin, zmax, tmax, n, _tokens, _parms);
1572
RtVoid RiParaboloidV(RtFloat rmax, RtFloat zmin, RtFloat zmax, RtFloat tmax,
1573
RtInt n, RtToken tokens[], RtPointer parms[])
1575
if (!mbCheck(true, MB_PARABOLOID)) return;
1576
State::Instance()->insert(new Paraboloid(rmax, zmin, zmax, tmax, n, tokens, parms), motion_pos);
1579
RtVoid RiDisk(RtFloat height, RtFloat radius, RtFloat tmax, ...)
1581
BUILD_TOKENPARAM_LIST(tmax)
1582
RiDiskV(height, radius, tmax, n, _tokens, _parms);
1585
RtVoid RiDiskV(RtFloat height, RtFloat radius, RtFloat tmax,
1586
RtInt n, RtToken tokens[], RtPointer parms[])
1588
if (!mbCheck(true, MB_DISK)) return;
1589
State::Instance()->insert(new Disk(height, radius, tmax, n, tokens, parms), motion_pos);
1592
RtVoid RiTorus(RtFloat majrad, RtFloat minrad, RtFloat phimin,
1593
RtFloat phimax, RtFloat tmax, ...)
1595
BUILD_TOKENPARAM_LIST(tmax)
1596
RiTorusV(majrad, minrad, phimin, phimax, tmax, n, _tokens, _parms);
1599
RtVoid RiTorusV(RtFloat majrad, RtFloat minrad,
1600
RtFloat phimin, RtFloat phimax, RtFloat tmax,
1601
RtInt n, RtToken tokens[], RtPointer parms[])
1603
if (!mbCheck(true, MB_TORUS)) return;
1604
State::Instance()->insert(new Torus(majrad, minrad, phimin, phimax, tmax, n, tokens, parms), motion_pos);
1607
// Point & Curve Primitives
1608
RtVoid RiPoints(RtInt nverts,...)
1610
BUILD_TOKENPARAM_LIST(nverts)
1611
RiPointsV(nverts, n, _tokens, _parms);
1614
RtVoid RiPointsV(RtInt nverts, RtInt n, RtToken tokens[], RtPointer parms[])
1616
if (!mbCheck(true, MB_POINTS)) return;
1617
if (!haveP("RiPointsV", n, tokens, parms)) return;
1618
State::Instance()->insert(new PointSet(nverts, n, tokens, parms), motion_pos);
1621
RtVoid RiCurves(RtToken type, RtInt ncurves,
1622
RtInt nvertices[], RtToken wrap, ...)
1624
BUILD_TOKENPARAM_LIST(wrap)
1625
RiCurvesV(type, ncurves, nvertices, wrap, n, _tokens, _parms);
1628
RtVoid RiCurvesV(RtToken type, RtInt ncurves, RtInt nvertices[], RtToken wrap,
1629
RtInt n, RtToken tokens[], RtPointer parms[])
1631
if (!mbCheck(true, MB_CURVES)) return;
1632
if (!haveP("RiCurvesV", n, tokens, parms)) return;
1634
if (!strcmp(type, RI_LINEAR))
1636
else if (!strcmp(type, RI_CUBIC))
1639
fprintf(ERROUT, "RiCurvesV(): unknown type '%s'\n", type);
1643
if (!strcmp(wrap, RI_PERIODIC))
1645
else if (!strcmp(wrap, RI_NONPERIODIC))
1648
fprintf(ERROUT, "RiCurvesV(): unknown wrap type '%s'\n", wrap);
1651
State::Instance()->insert(new CurveSet(islinear, ncurves, nvertices, _wrap, n, tokens, parms), motion_pos);
1655
// 'Blobby' Implicit Surfaces
1656
RtVoid RiBlobby(RtInt nleaf, RtInt ncode, RtInt code[],
1657
RtInt nflt, RtFloat flt[],
1658
RtInt nstr, RtToken str[], ...)
1660
BUILD_TOKENPARAM_LIST(str)
1661
RiBlobbyV(nleaf, ncode, code, nflt, flt, nstr, str, n, _tokens, _parms);
1664
RtVoid RiBlobbyV(RtInt nleaf, RtInt ncode, RtInt code[],
1665
RtInt nflt, RtFloat flt[],
1666
RtInt nstr, RtToken str[],
1667
RtInt n, RtToken tokens[], RtPointer parms[])
1669
if (!mbCheck(true, MB_BLOBBY)) return;
1671
fprintf(ERROUT, "'Blobby' not implemented (yet)\n");
1675
// Procedural Primitives
1676
RtVoid RiProcedural(RtPointer data, RtBound bound,
1677
RtVoid (*subdivfunc)(RtPointer, RtFloat),
1678
RtVoid (*freefunc)(RtPointer))
1680
if (!mbCheck()) return;
1682
fprintf(ERROUT, "'Procedural' not implemented (yet)\n");
1686
RtVoid RiProcDelayedReadArchive(RtPointer data, RtFloat detail)
1688
if (!mbCheck()) return;
1690
fprintf(ERROUT, "'ProcDelayedReadArchive' not implemented (yet)\n");
1693
RtVoid RiProcRunProgram(RtPointer data, RtFloat detail)
1695
if (!mbCheck()) return;
1697
fprintf(ERROUT, "'ProcRunProgram' not implemented (yet)\n");
1700
RtVoid RiProcDynamicLoad(RtPointer data, RtFloat detail)
1702
if (!mbCheck()) return;
1704
fprintf(ERROUT, "'ProcDynamicLoad' not implemented (yet)\n");
1707
// Implementation-specific Geometric Primitives
1708
RtVoid RiGeometry(RtToken type, ...)
1710
BUILD_TOKENPARAM_LIST(type)
1711
RiSurfaceV(type, n, _tokens, _parms);
1714
RtVoid RiGeometryV(RtToken type, RtInt n, RtToken tokens[], RtPointer parms[])
1716
if (!mbCheck()) return;
1718
fprintf(ERROUT, "'Geometry' not implemented (yet)\n");
1721
//------------------------------------------------------------------------------
1722
// Solids & Spatial Set operations
1724
RtVoid RiSolidBegin(RtToken operation)
1727
fprintf(ERROUT, "'SolidBegin' not implemented (yet)\n");
1733
fprintf(ERROUT, "'SolidEnd' not implemented (yet)\n");
1736
// Retained Geometry
1737
RtObjectHandle RiObjectBegin()
1740
fprintf(ERROUT, "'ObjectBegin' not implemented (yet)\n");
1744
RtVoid RiObjectEnd()
1747
fprintf(ERROUT, "'ObjectEnd' not implemented (yet)\n");
1750
RtVoid RiObjectInstance(RtObjectHandle handle)
1753
fprintf(ERROUT, "'ObjectInstance' not implemented (yet)\n");
1756
//------------------------------------------------------------------------------
1759
RtVoid RiMotionBegin(RtInt n2, ...)
1763
float* times = new float [n2];
1766
for (int i=0; i<n2; ++i)
1767
times[i] = (float)(va_arg(args, double));
1770
RiMotionBeginV(n2, times);
1774
RtVoid RiMotionBeginV(RtInt n, RtFloat times[])
1776
State::Instance()->motionBegin(n, times);
1777
prev_motion_cmd = MB_NONE;
1781
RtVoid RiMotionEnd()
1783
State::Instance()->motionEnd();
1784
prev_motion_cmd = MB_NONE;
1788
//------------------------------------------------------------------------------
1789
// External Resources
1792
RtVoid RiMakeTexture(const char* pic, const char* tex, RtToken swrap, RtToken twrap,
1793
RtFilterFunc filterfunc, RtFloat swidth, RtFloat twidth, ...)
1795
BUILD_TOKENPARAM_LIST(twidth)
1796
RiMakeTextureV(pic, tex, swrap, twrap, filterfunc, swidth, twidth, n, _tokens, _parms);
1799
RtVoid RiMakeTextureV(const char* pic, const char* tex, RtToken swrap, RtToken twrap,
1800
RtFilterFunc filterfunc, RtFloat swidth, RtFloat twidth,
1801
RtInt n, RtToken tokens[], RtPointer parms[])
1803
if (!mbCheck()) return;
1805
fprintf(ERROUT, "'MakeTexture' not implemented (yet)\n");
1809
RtVoid RiMakeLatLongEnvironment(const char* pic, const char* tex,
1810
RtFilterFunc filterfunc,
1811
RtFloat swidth, RtFloat twidth, ...)
1813
BUILD_TOKENPARAM_LIST(twidth)
1814
RiMakeLatLongEnvironmentV(pic, tex, filterfunc, swidth, twidth, n, _tokens, _parms);
1817
RtVoid RiMakeLatLongEnvironmentV(const char* pic, const char* tex,
1818
RtFilterFunc filterfunc,
1819
RtFloat swidth, RtFloat twidth,
1820
RtInt n, RtToken tokens[], RtPointer parms[])
1822
if (!mbCheck()) return;
1824
fprintf(ERROUT, "'MakeLatLongEnvironment' not implemented (yet)\n");
1827
RtVoid RiMakeCubeFaceEnvironment(const char* px, const char* nx, const char* py, const char* ny,
1828
const char* pz, const char* nz, const char* tex, RtFloat fov,
1829
RtFilterFunc filterfunc, RtFloat swidth, RtFloat ywidth, ...)
1831
BUILD_TOKENPARAM_LIST(ywidth)
1832
RiMakeCubeFaceEnvironmentV(px, nx, py, ny, pz, nz, tex, fov, filterfunc, swidth, ywidth, n, _tokens, _parms);
1835
RtVoid RiMakeCubeFaceEnvironmentV(const char* px, const char* nx, const char* py, const char* ny,
1836
const char* pz, const char* nz, const char* tex, RtFloat fov,
1837
RtFilterFunc filterfunc, RtFloat swidth, RtFloat ywidth,
1838
RtInt n, RtToken tokens[], RtPointer parms[])
1840
if (!mbCheck()) return;
1842
fprintf(ERROUT, "'MakeCubeFaceEnvironment' not implemented (yet)\n");
1846
RtVoid RiMakeShadow(const char* pic, const char* tex, ...)
1848
BUILD_TOKENPARAM_LIST(tex)
1849
RiMakeShadowV(pic, tex, n, _tokens, _parms);
1852
RtVoid RiMakeShadowV(const char* pic, const char* tex, RtInt n, RtToken tokens[], RtPointer parms[])
1854
if (!mbCheck()) return;
1856
fprintf(ERROUT, "'MakeShadow' not implemented (yet)\n");
1859
// Bump maps (not really supported anymore? 3.2 removed, use displacement instead
1860
RtVoid RiMakeBump(const char* pic, const char* tex, RtToken swrap, RtToken twrap,
1861
RtFilterFunc filterfunc, RtFloat swidth, RtFloat twidth, ...)
1863
BUILD_TOKENPARAM_LIST(twidth)
1864
RiMakeBumpV(pic, tex, swrap, twrap, filterfunc, swidth, twidth, n, _tokens, _parms);
1867
RtVoid RiMakeBumpV(const char* pic, const char* tex, RtToken swrap, RtToken twrap,
1868
RtFilterFunc filterfunc, RtFloat swidth, RtFloat twidth,
1869
RtInt n, RtToken tokens[], RtPointer parms[])
1871
if (!mbCheck()) return;
1873
fprintf(ERROUT, "'MakeBump' not implemented (yet)\n");
1876
//------------------------------------------------------------------------------
1877
// all below TODO or ignore...
1880
RtVoid RiErrorHandler(RtErrorHandler handler)
1884
RtVoid RiErrorIgnore(RtInt code, RtInt severity, const char* msg)
1888
RtVoid RiErrorPrint(RtInt code, RtInt severity, const char* msg)
1892
RtVoid RiErrorAbort(RtInt code, RtInt severity, const char* msg)
1896
//------------------------------------------------------------------------------
1899
RtVoid RiArchiveRecord(RtToken type, const char* format, ...)
1903
RtVoid RiReadArchive(RtToken name, RtArchiveCallback callback, ...)
1905
BUILD_TOKENPARAM_LIST(callback)
1906
RiReadArchiveV(name, callback, n, _tokens, _parms);
1909
RtVoid RiReadArchiveV(RtToken name, RtArchiveCallback callback,
1910
RtInt n, RtToken tokens[], RtPointer parms[])
1912
if (!mbCheck(true, MB_READARCHIVE)) return;
1913
Options& options = State::Instance()->topOptions();
1915
char fname[512] = {0};
1916
snprintf(fname, 512, "%s%s", options.basepath, name);
1917
RtInt err = rp.parse(fname, false);
1918
if (err!=RIE_NOERROR) {
1921
fprintf(ERROUT, "No file: '%s'\n", name);
1924
fprintf(ERROUT, "File read error\n");
1927
fprintf(ERROUT, "Unknown error: %d\n", err);
1930
in_readarchive = false;
1933
//------------------------------------------------------------------------------