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 : options.cpp
27 // Classes : COptions
28 // Description : Implementation
29 //
30 ////////////////////////////////////////////////////////////////////////
31 #include <math.h>
32 #include <stdio.h>
33 #include <string.h>
34
35 #ifdef __APPLE__
36 #include <sys/stat.h>
37 #include <CoreServices/CoreServices.h>
38 #ifdef check // Apple's library defines "check"
39 #undef check
40 #endif
41 #endif
42
43 #include "options.h"
44 #include "texture.h"
45 #include "stats.h"
46 #include "ri_config.h"
47
48 ///////////////////////////////////////////////////////////////////////
49 // Class : COptions
50 // Method : optionsDeleteSearchPath
51 // Description : Delete the searchpath
52 // Return Value : -
53 // Comments :
optionsDeleteSearchPath(TSearchpath * cPath)54 static void optionsDeleteSearchPath(TSearchpath *cPath) {
55 TSearchpath *nPath;
56
57 for(;cPath!=NULL;) {
58 nPath = cPath->next;
59 free(cPath->directory);
60 delete cPath;
61 cPath = nPath;
62 }
63 }
64
65 ///////////////////////////////////////////////////////////////////////
66 // Class : COptions
67 // Method : optionsCloneSearchPath
68 // Description : Clone a search path
69 // Return Value : -
70 // Comments :
optionsCloneSearchPath(TSearchpath * cPath)71 static TSearchpath *optionsCloneSearchPath(TSearchpath *cPath) {
72 TSearchpath *nPath = NULL;
73 TSearchpath *lPath = NULL;
74
75 for(;cPath!=NULL;cPath=cPath->next) {
76 TSearchpath *ncPath = new TSearchpath;
77
78 ncPath->directory = strdup(cPath->directory);
79 ncPath->next = NULL;
80
81 if (lPath == NULL) {
82 lPath = ncPath;
83 nPath = ncPath;
84 } else {
85 lPath->next = ncPath;
86 lPath = ncPath;
87 }
88 }
89
90 return nPath;
91 }
92
93
94 ///////////////////////////////////////////////////////////////////////
95 // Class : COptions::CDisplay
96 // Method : CDisplay
97 // Description : Ctor
98 // Return Value : -
99 // Comments :
CDisplay()100 COptions::CDisplay::CDisplay() {
101 outDevice = NULL;
102 outName = NULL;
103 outSamples = NULL;
104 next = NULL;
105
106 startFunction = NULL;
107 dataFunction = NULL;
108 finishFunction = NULL;
109
110 quantizer[0] = -1; // Copy from the default
111
112 numParameters = 0;
113 parameters = NULL;
114 }
115
116 ///////////////////////////////////////////////////////////////////////
117 // Class : COptions::CDisplay
118 // Method : CDisplay
119 // Description : Ctor
120 // Return Value : -
121 // Comments :
CDisplay(const CDisplay * other)122 COptions::CDisplay::CDisplay(const CDisplay *other) {
123
124 outDevice = strdup(other->outDevice);
125 outName = strdup(other->outName);
126 outSamples = strdup(other->outSamples);
127 quantizer[0] = other->quantizer[0];
128 quantizer[1] = other->quantizer[1];
129 quantizer[2] = other->quantizer[2];
130 quantizer[3] = other->quantizer[3];
131 quantizer[4] = other->quantizer[4];
132
133 startFunction = other->startFunction;
134 dataFunction = other->dataFunction;
135 finishFunction = other->finishFunction;
136
137 if (other->numParameters > 0) {
138 int i;
139
140 numParameters = other->numParameters;
141 parameters = new TDisplayParameter[numParameters];
142
143 // Duplicate the parameters
144 for (i=0;i<numParameters;i++) {
145 parameters[i] = other->parameters[i];
146 parameters[i].name = strdup(other->parameters[i].name);
147 switch(parameters[i].type) {
148 case FLOAT_PARAMETER:
149 parameters[i].data = new float[parameters[i].numItems];
150 memcpy(parameters[i].data,other->parameters[i].data,parameters[i].numItems*sizeof(float));
151 break;
152 case VECTOR_PARAMETER:
153 parameters[i].data = new float[parameters[i].numItems*3];
154 memcpy(parameters[i].data,other->parameters[i].data,parameters[i].numItems*sizeof(float)*3);
155 break;
156 case MATRIX_PARAMETER:
157 parameters[i].data = new float[parameters[i].numItems*16];
158 memcpy(parameters[i].data,other->parameters[i].data,parameters[i].numItems*sizeof(float)*16);
159 break;
160 case STRING_PARAMETER:
161 char *str;
162
163 str = strdup((char *) other->parameters[i].data);
164 parameters[i].data = str;
165 break;
166 case INTEGER_PARAMETER:
167 parameters[i].data = new int[parameters[i].numItems];
168 memcpy(parameters[i].data,other->parameters[i].data,parameters[i].numItems*sizeof(int));
169 break;
170 default:
171 break;
172 }
173 }
174 } else {
175 numParameters = 0;
176 parameters = NULL;
177 }
178 }
179
180 ///////////////////////////////////////////////////////////////////////
181 // Class : COptions::CDisplay
182 // Method : ~CDisplay
183 // Description : Dtor
184 // Return Value : -
185 // Comments :
~CDisplay()186 COptions::CDisplay::~CDisplay() {
187 if (outDevice != NULL) free(outDevice);
188 if (outName != NULL) free(outName);
189 if (outSamples != NULL) free(outSamples);
190
191 if (parameters != NULL) {
192 int i;
193
194 for (i=0;i<numParameters;i++) {
195 switch(parameters[i].type) {
196 case FLOAT_PARAMETER:
197 case VECTOR_PARAMETER:
198 case MATRIX_PARAMETER:
199 delete [] (float *) parameters[i].data;
200 break;
201 case STRING_PARAMETER:
202 free((char *) parameters[i].data);
203 break;
204 }
205
206 free(parameters[i].name);
207 }
208
209 delete [] parameters;
210 }
211 }
212
213 ///////////////////////////////////////////////////////////////////////
214 // Class : COptions::CClipPlane
215 // Method : CCplitPlane
216 // Description : Ctor
217 // Return Value : -
218 // Comments :
CClipPlane()219 COptions::CClipPlane::CClipPlane() {
220 }
221
222
223 ///////////////////////////////////////////////////////////////////////
224 // Class : COptions::CClipPlane
225 // Method : CCplitPlane
226 // Description : Ctor
227 // Return Value : -
228 // Comments :
CClipPlane(const CClipPlane * other)229 COptions::CClipPlane::CClipPlane(const CClipPlane *other) {
230 movvv(normal,other->normal);
231 d = other->d;
232 }
233
234
235 ///////////////////////////////////////////////////////////////////////
236 // Class : COptions
237 // Method : COptions
238 // Description : All the default frame specific settings are defined here
239 // Return Value : -
240 // Comments :
COptions()241 COptions::COptions() {
242 atomicIncrement(&stats.numOptions);
243
244 xres = 640;
245 yres = 480;
246
247 frame = -1;
248
249 pixelAR = 1;
250 frameAR = 4.0f/3.0f;
251
252 cropLeft = 0;
253 cropRight = 1;
254 cropTop = 0;
255 cropBottom = 1;
256
257 screenLeft = -4.0f/3.0f;
258 screenRight = 4.0f/3.0f;
259 screenTop = 1;
260 screenBottom = -1;
261
262 clipMin = C_EPSILON;
263 clipMax = C_INFINITY;
264
265 pixelVariance = 0.05f;
266
267 jitter = 0.99f;
268
269 hider = strdup("stochastic");
270
271 #ifdef __APPLE__
272 // Support for finding resources in Mac OS X bundles and standard Mac OS X file system locations
273
274 // Find the application bundle's plug-in and Resources directory
275 char path[OS_MAX_PATH_LENGTH];
276 char pathtmp[OS_MAX_PATH_LENGTH];
277 CFBundleRef bundle = CFBundleGetMainBundle();
278 if (bundle) {
279 CFURLRef url = CFBundleCopyBuiltInPlugInsURL(bundle);
280 if (url) {
281 Boolean validpath = CFURLGetFileSystemRepresentation(url,true,(UInt8*)path,OS_MAX_PATH_LENGTH);
282 if (validpath)
283 setenv("PIXIEAPPPLUGINS", (const char*)path, 1);
284 CFRelease(url);
285 }
286 url = CFBundleCopyResourcesDirectoryURL(bundle);
287 if (url) {
288 Boolean validpath = CFURLGetFileSystemRepresentation(url,true,(UInt8*)path,OS_MAX_PATH_LENGTH);
289 if (validpath)
290 setenv("PIXIEAPPRESOURCES", (const char*)path, 1);
291 CFRelease(url);
292 }
293 CFRelease(bundle);
294 }
295
296 // Find the application support directory (~/Library/Application Support/Pixie/PlugIns), and set the
297 // PIXIEUSERDIR environment variable to that directory
298 FSRef appsupport;
299 if (FSFindFolder(kUserDomain, kApplicationSupportFolderType, kCreateFolder, &appsupport) == noErr) {
300 FSRefMakePath(&appsupport, (UInt8*)path, OS_MAX_PATH_LENGTH);
301 sprintf(pathtmp, "%s/" PACKAGE, path);
302 mkdir(pathtmp, 0755);
303 setenv("PIXIEUSERDIR", (const char*)pathtmp, 1);
304 }
305
306 // Find the application support directory (/Library/Application Support/Pixie/PlugIns), and set the
307 // PIXIELOCALDIR environment variable to that directory
308 if (FSFindFolder(kLocalDomain, kApplicationSupportFolderType, kCreateFolder, &appsupport) == noErr) {
309 FSRefMakePath(&appsupport, (UInt8*)path, OS_MAX_PATH_LENGTH);
310 snprintf(pathtmp, OS_MAX_PATH_LENGTH, "%s/" PACKAGE, path);
311 mkdir(pathtmp, 0755);
312 setenv("PIXIELOCALDIR", (const char*)pathtmp, 1);
313 }
314
315 // Default home, unless overridden with environment
316 setenv("PIXIEHOME","/Library/Pixie",0);
317
318 archivePath = optionsGetSearchPath(".:%RIBS%:%PIXIEHOME%/ribs" ,NULL);
319 proceduralPath = optionsGetSearchPath(".:%PROCEDURALS%:%PIXIEUSERDIR%/procedurals:%PIXIELOCALDIR%/procedurals:%PIXIEAPPPLUGINS%:%PIXIEHOME%/procedurals",NULL);
320 texturePath = optionsGetSearchPath(".:%TEXTURES%:%PIXIEUSERDIR%/textures:%PIXIELOCALDIR%/textures:%PIXIEAPPRESOURCES%/textures:%PIXIEHOME%/textures",NULL);
321 shaderPath = optionsGetSearchPath(".:%SHADERS%:%PIXIEUSERDIR%/shaders:%PIXIELOCALDIR%/shaders:%PIXIEAPPRESOURCES%/shaders:%PIXIEHOME%/shaders",NULL);
322 displayPath = optionsGetSearchPath("%DISPLAYS%:%PIXIEUSERDIR%/displays:%PIXIELOCALDIR%/displays:%PIXIEAPPPLUGINS%:%PIXIEHOME%/displays",NULL);
323 modulePath = optionsGetSearchPath("%MODULES%:%PIXIEUSERDIR%/modules:%PIXIELOCALDIR%/modules:%PIXIEAPPPLUGINS%:%PIXIEHOME%/modules",NULL);
324
325 #else
326 archivePath = optionsGetSearchPath(".:%RIBS%:" PIXIE_RIBS,NULL);
327 proceduralPath = optionsGetSearchPath(".:%PROCEDURALS%:" PIXIE_PROCEDURALS,NULL);
328 texturePath = optionsGetSearchPath(".:%TEXTURES%:" PIXIE_TEXTURES,NULL);
329 shaderPath = optionsGetSearchPath(".:%SHADERS%:" PIXIE_SHADERS,NULL);
330 displayPath = optionsGetSearchPath(".:%DISPLAYS%:" PIXIE_DISPLAYS,NULL);
331 modulePath = optionsGetSearchPath(".:%MODULES%:" PIXIE_MODULES,NULL);
332 #endif
333
334 pixelXsamples = 2;
335 pixelYsamples = 2;
336
337 gamma = 1;
338 gain = 1;
339
340 pixelFilterWidth = 2;
341 pixelFilterHeight = 2;
342 pixelFilter = RiCatmullRomFilter;
343
344 colorQuantizer[0] = 0; // Zero
345 colorQuantizer[1] = 255; // One
346 colorQuantizer[2] = 0; // Min
347 colorQuantizer[3] = 255; // Max
348 colorQuantizer[4] = 0.5;
349 depthQuantizer[0] = 0; // Zero
350 depthQuantizer[1] = 0; // One
351 depthQuantizer[2] = 0; // Min
352 depthQuantizer[3] = 0; // Max
353 depthQuantizer[4] = 0;
354
355 initv(opacityThreshold,0.996f);
356 initv(zvisibilityThreshold,0.996f);
357
358 // We default to sampling motion, but this can be turned off.
359 // Additionally, if there's no motionblur in the scene, it will be turned off
360 flags = OPTIONS_FLAGS_SAMPLEMOTION;
361
362 displays = NULL;
363
364 clipPlanes = NULL;
365
366 relativeDetail = 1;
367
368 projection = OPTIONS_PROJECTION_ORTHOGRAPHIC;
369 fov = 90;
370
371 nColorComps = 3;
372 fromRGB = NULL;
373 toRGB = NULL;
374
375 fstop = C_INFINITY;
376 focallength = 1;
377 focaldistance = 1;
378
379 shutterOpen = 0;
380 shutterClose = 0;
381 shutterOffset = 0;
382
383 endofframe = 0;
384 filelog = NULL;
385
386 numThreads = osAvailableCPUs();
387 if (numThreads < 1)
388 numThreads = DEFAULT_NUM_THREADS;
389
390 maxTextureSize = DEFAULT_MAX_TEXTURESIZE;
391 maxBrickSize = DEFAULT_MAX_BRICKSIZE;
392
393 maxGridSize = DEFAULT_MAX_GRIDSIZE;
394
395 maxRayDepth = 5;
396 maxPhotonDepth = 10;
397
398 bucketWidth = DEFAULT_TILE_WIDTH;
399 bucketHeight = DEFAULT_TILE_HEIGHT;
400
401 netXBuckets = DEFAULT_NET_XBUCKETS;
402 netYBuckets = DEFAULT_NET_YBUCKETS;
403
404 threadStride = DEFAULT_THREAD_STRIDE;
405
406 geoCacheMemory = DEFAULT_GEO_CACHE_SIZE;
407
408 maxEyeSplits = 10;
409
410 tsmThreshold = DEFAULT_TSM_THRESHOLD;
411
412 causticIn = NULL;
413 causticOut = NULL;
414
415 globalIn = NULL;
416 globalOut = NULL;
417
418 numEmitPhotons = 10000;
419
420 shootStep = 1000;
421
422 depthFilter = DEPTH_MIN;
423 }
424
425
426 ///////////////////////////////////////////////////////////////////////
427 // Class : COptions
428 // Method : COptions
429 // Description : Create an exact copy of another options block
430 // Return Value : -
431 // Comments :
COptions(const COptions * o)432 COptions::COptions(const COptions *o) {
433 atomicIncrement(&stats.numOptions);
434
435 this[0] = o[0];
436
437 // Note: The assignment here also invokes the assignment operator of userOptions
438 // so there's no need for a separate copy for that
439
440 hider = strdup(o->hider);
441
442 archivePath = optionsCloneSearchPath(o->archivePath);
443 proceduralPath = optionsCloneSearchPath(o->proceduralPath);
444 texturePath = optionsCloneSearchPath(o->texturePath);
445 shaderPath = optionsCloneSearchPath(o->shaderPath);
446 displayPath = optionsCloneSearchPath(o->displayPath);
447 modulePath = optionsCloneSearchPath(o->modulePath);
448
449 if (o->displays != NULL) {
450 CDisplay *cDisplay,*nDisplay;
451
452 displays = NULL;
453 for (cDisplay=o->displays;cDisplay!=NULL;cDisplay=cDisplay->next) {
454 nDisplay = new CDisplay(cDisplay);
455 nDisplay->next = displays;
456 displays = nDisplay;
457 }
458 } else {
459 displays = NULL;
460 }
461
462
463 if (o->clipPlanes != NULL) {
464 CClipPlane *cPlane,*nPlane;
465
466 clipPlanes = NULL;
467 for (cPlane=o->clipPlanes;cPlane!=NULL;cPlane=cPlane->next) {
468 nPlane = new CClipPlane;
469 *nPlane = *cPlane;
470 nPlane->next = clipPlanes;
471 clipPlanes = nPlane;
472 }
473 } else {
474 clipPlanes = NULL;
475 }
476
477
478 if (o->fromRGB != NULL) {
479 fromRGB = new float[3*nColorComps];
480 memcpy(fromRGB,o->fromRGB,3*nColorComps*sizeof(float));
481 } else {
482 fromRGB = NULL;
483 }
484
485 if (o->toRGB != NULL) {
486 toRGB = new float[3*nColorComps];
487 memcpy(toRGB,o->toRGB,3*nColorComps*sizeof(float));
488 } else {
489 toRGB = NULL;
490 }
491
492 causticIn = (o->causticIn != NULL ? strdup(o->causticIn) : NULL);
493 causticOut = (o->causticOut != NULL ? strdup(o->causticOut) : NULL);
494 globalIn = (o->globalIn != NULL ? strdup(o->globalIn) : NULL);
495 globalOut = (o->globalOut != NULL ? strdup(o->globalOut) : NULL);
496 filelog = (o->filelog != NULL ? strdup(o->filelog) : NULL);
497 }
498
499
500 ///////////////////////////////////////////////////////////////////////
501 // Class : COptions
502 // Method : ~COptions
503 // Description : Destructor
504 // Return Value : -
505 // Comments :
~COptions()506 COptions::~COptions(){
507 atomicDecrement(&stats.numOptions);
508
509 if (fromRGB != NULL)
510 delete [] fromRGB;
511
512 if (toRGB != NULL)
513 delete [] toRGB;
514
515 if (displays != NULL) {
516 CDisplay *cDisplay,*nDisplay;
517
518 for (cDisplay=displays;cDisplay!=NULL;) {
519 nDisplay = cDisplay->next;
520 delete cDisplay;
521 cDisplay = nDisplay;
522 }
523 }
524
525 if (clipPlanes != NULL) {
526 CClipPlane *cPlane,*nPlane;
527
528 for (cPlane=clipPlanes;cPlane!=NULL;) {
529 nPlane = cPlane->next;
530 delete cPlane;
531 cPlane = nPlane;
532 }
533 }
534
535 if (hider != NULL)
536 free(hider);
537
538
539 optionsDeleteSearchPath(archivePath);
540 optionsDeleteSearchPath(proceduralPath);
541 optionsDeleteSearchPath(texturePath);
542 optionsDeleteSearchPath(shaderPath);
543 optionsDeleteSearchPath(displayPath);
544 optionsDeleteSearchPath(modulePath);
545
546 if (causticIn != NULL) free(causticIn);
547 if (causticOut != NULL) free(causticOut);
548 if (globalIn != NULL) free(globalIn);
549 if (globalOut != NULL) free(globalOut);
550 if (filelog != NULL) free(filelog);
551 }
552
553 ///////////////////////////////////////////////////////////////////////
554 // Class : COptions
555 // Method : convertColor
556 // Description : Convert color to RGB space from whatever space entered
557 // Return Value : -
558 // Comments :
convertColor(vector & c,const float * f) const559 void COptions::convertColor(vector &c,const float *f) const {
560 int i,j;
561 if (toRGB == NULL) {
562 c[COMP_R] = f[0];
563 c[COMP_G] = f[1];
564 c[COMP_B] = f[2];
565 } else {
566 for (i=0;i<3;i++) {
567 c[i] = 0;
568 for (j=0;j<(int) nColorComps;j++)
569 c[i] += f[j]*toRGB[i*nColorComps+j];
570 }
571 }
572 }
573
574
575 ///////////////////////////////////////////////////////////////////////
576 // Class : COptions
577 // Method : pickSearchpath
578 // Description : Pick a searchpath from name
579 // Return Value : -
580 // Comments :
pickSearchpath(const char * name)581 TSearchpath *COptions::pickSearchpath(const char *name) {
582
583 if (strstr(name,"rib") != NULL) {
584 return archivePath;
585
586 } else if (strstr(name,"tif") != NULL) {
587 return texturePath;
588
589 } else if (strstr(name,"tiff") != NULL) {
590 return texturePath;
591
592 } else if (strstr(name,"tex") != NULL) {
593 return texturePath;
594
595 } else if (strstr(name,"tx") != NULL) {
596 return texturePath;
597
598 } else if (strstr(name,"ptc") != NULL) {
599 return texturePath;
600
601 } else if (strstr(name,"bm") != NULL) {
602 return texturePath;
603
604 } else if (strstr(name,"sdr") != NULL) {
605 return shaderPath;
606
607 } else if (strstr(name,osModuleExtension) != NULL) {
608 return proceduralPath;
609 }
610
611 return NULL;
612 }
613
614
615 ///////////////////////////////////////////////////////////////////////
616 // Function : optionsGetSearchPath
617 // Description : Get the searchpath
618 // Return Value : -
619 // Comments :
optionsGetSearchPath(const char * path,TSearchpath * oldPath)620 TSearchpath *optionsGetSearchPath(const char *path,TSearchpath *oldPath) {
621 TSearchpath *newPath = NULL;
622 TSearchpath *lastPath = NULL;
623 TSearchpath *cPath;
624 const char *currentPath;
625 char tmp[OS_MAX_PATH_LENGTH];
626 char *dest;
627
628 for (dest=tmp,currentPath=path;;) {
629 if ((*currentPath == '\0') || (*currentPath == ':')) { // End of the current path
630
631 #ifdef _WINDOWS
632 if ((dest - tmp) == 1) {
633 if ((currentPath[1] == '\\') || (currentPath[1] == '/')) {
634 *dest++ = *currentPath++;
635 continue;
636 }
637 }
638 #endif
639
640 if ((dest - tmp) > 0) { // Do we have anything to record ?
641 dest--;
642
643 if ((*dest == '/') || (*dest == '\\')) { // The last character has to be a slash
644 dest++;
645 } else {
646 dest++;
647 *dest++ = '/';
648 }
649
650 *dest++ = '\0';
651 osFixSlashes(tmp);
652
653 cPath = new TSearchpath;
654 if (strncmp(tmp,"\\\\",2) == 0) {
655 tmp[1] = tmp[2];
656 tmp[2] = ':';
657 tmp[3] = '\\';
658 cPath->directory = strdup(tmp+1);
659 } else {
660 cPath->directory = strdup(tmp);
661 }
662 cPath->next = NULL;
663
664 if (lastPath == NULL) {
665 lastPath = cPath;
666 newPath = cPath;
667 } else {
668 lastPath->next = cPath;
669 lastPath = cPath;
670 }
671 }
672
673 dest = tmp;
674
675 if (*currentPath == '\0') break;
676
677 currentPath++;
678 } else if (*currentPath == '%') {
679 const char *endOfCurrentPath = strchr(currentPath+1,'%');
680 char environmentVariable[OS_MAX_PATH_LENGTH];
681
682 if (endOfCurrentPath!=NULL) {
683 const int environmentLength = (int) (endOfCurrentPath - currentPath) - 1;
684 const char *value;
685
686 strncpy(environmentVariable,currentPath+1,environmentLength);
687 environmentVariable[environmentLength] = '\0';
688
689 value = osEnvironment(environmentVariable);
690 if (value != NULL) {
691 strcpy(dest,value);
692 dest += strlen(value);
693 currentPath = endOfCurrentPath+1;
694 } else {
695 // If this environment variable was not defined, scrap the entire
696 // path in progress b/c it will not be correct without this env variable
697 dest = tmp;
698 *dest = '\0'; // Truncate dest path
699 currentPath = strchr(endOfCurrentPath,':'); // Skip to next path
700 if (!currentPath)
701 currentPath = strchr(endOfCurrentPath,'\0'); // ...or end if last path
702 }
703
704 } else {
705 currentPath++;
706 }
707 } else if ((*currentPath == '@') || (*currentPath == '&')) {
708 for (cPath=oldPath;cPath!=NULL;cPath=cPath->next) {
709 TSearchpath *nPath = new TSearchpath;
710
711 nPath->directory = strdup(cPath->directory);
712 nPath->next = NULL;
713
714 if (lastPath == NULL) {
715 lastPath = nPath;
716 newPath = nPath;
717 } else {
718 lastPath->next = nPath;
719 lastPath = nPath;
720 }
721 }
722 currentPath++;
723 } else {
724 *dest++ = *currentPath++;
725 }
726 }
727
728 optionsDeleteSearchPath(oldPath);
729
730 return newPath;
731 }
732
733 ///////////////////////////////////////////////////////////////////////
734 // Class : COptions
735 // Method : find
736 // Description : Find the value of a particular option
737 // Return Value : -
738 // Comments :
find(const char * name,const char * category,EVariableType & type,const void * & value,int & intValue,float & floatValue) const739 int COptions::find(const char *name,const char *category,EVariableType &type,const void *&value,int &intValue,float &floatValue) const {
740
741 // Check the common case first
742 if ((category == NULL) || (strcmp(category,RI_USER) == 0)) {
743 CVariable *var;
744 if (userOptions.lookup(name,var) == TRUE) {
745 type = var->type;
746 value = var->defaultValue;
747 if (value != NULL) return TRUE;
748 }
749 }
750
751 if ((category == NULL) || (strcmp(category,RI_LIMITS) == 0)) {
752 if (strcmp(name,RI_BUCKETSIZE) == 0) { type = TYPE_INTEGER; value = &bucketWidth; return TRUE;}
753 else if (strcmp(name,RI_METABUCKETS) == 0) { type = TYPE_INTEGER; value = &netXBuckets; return TRUE;}
754 else if (strcmp(name,RI_GRIDSIZE) == 0) { type = TYPE_INTEGER; value = &maxGridSize; return TRUE;}
755 else if (strcmp(name,RI_EYESPLITS) == 0) { type = TYPE_INTEGER; value = &maxEyeSplits; return TRUE;}
756 else if (strcmp(name,RI_TEXTUREMEMORY) == 0) { type = TYPE_INTEGER; value = NULL; intValue = maxTextureSize / 1000; return TRUE;}
757 else if (strcmp(name,RI_BRICKMEMORY) == 0) { type = TYPE_INTEGER; value = NULL; intValue = maxBrickSize / 1000; return TRUE;}
758 else if (strcmp(name,RI_NUMTHREADS) == 0) { type = TYPE_INTEGER; value = &numThreads; return TRUE;}
759 else if (strcmp(name,RI_THREADSTRIDE) == 0) { type = TYPE_INTEGER; value = &threadStride; return TRUE;}
760 else if (strcmp(name,RI_GEOCACHEMEMORY) == 0) { type = TYPE_INTEGER; value = NULL; intValue = geoCacheMemory / 1000; return TRUE;}
761 else if (strcmp(name,RI_INHERITATTRIBUTES) == 0) { type = TYPE_INTEGER; value = NULL; intValue = (flags & OPTIONS_FLAGS_INHERIT_ATTRIBUTES) != 0; return TRUE;}
762 else if (strcmp(name,"frame") == 0) { type = TYPE_INTEGER; value = &frame; return TRUE;}
763 }
764
765 if ((category == NULL) || (strcmp(category,RI_HIDER) == 0)) {
766 if (strcmp(name,RI_JITTER) == 0) { type = TYPE_FLOAT; value = &jitter; return TRUE;}
767 else if (strcmp(name,RI_EMIT) == 0) { type = TYPE_INTEGER; value = &numEmitPhotons; return TRUE;}
768 else if (strcmp(name,RI_SAMPLESPECTRUM) == 0) { type = TYPE_INTEGER; value = NULL; intValue = (flags & OPTIONS_FLAGS_SAMPLESPECTRUM) != 0; return TRUE;}
769 else if (strcmp(name,RI_SAMPLEMOTION) == 0) { type = TYPE_INTEGER; value = NULL; intValue = (flags & OPTIONS_FLAGS_SAMPLEMOTION) != 0; return TRUE;}
770 }
771
772 if ((category == NULL) || (strcmp(category,RI_TRACE) == 0)) {
773 if (strcmp(name,RI_MAXDEPTH) == 0) { type = TYPE_INTEGER; value = &maxRayDepth; return TRUE;}
774 }
775
776 if ((category == NULL) || (strcmp(category,RI_STATISTICS) == 0)) {
777 if (strcmp(name,RI_ENDOFFRAME) == 0) { type = TYPE_INTEGER; value = &endofframe; return TRUE;}
778 else if (strcmp(name,RI_FILELOG) == 0) { type = TYPE_STRING; value = filelog; return TRUE;}
779 else if (strcmp(name,RI_PROGRESS) == 0) { type = TYPE_INTEGER; value = NULL; intValue = (flags & OPTIONS_FLAGS_PROGRESS) != 0; return TRUE;}
780
781 }
782
783 if ((category == NULL) || (strcmp(category,RI_SHUTTER) == 0)) {
784 if (strcmp(name,RI_OFFSET) == 0) { type = TYPE_FLOAT; value = &shutterOffset; return TRUE;}
785 }
786
787
788 return FALSE;
789 }
790