1 /* 2 Teem: Tools to process and visualize scientific data and images . 3 Copyright (C) 2012, 2011, 2010, 2009 University of Chicago 4 Copyright (C) 2008, 2007, 2006, 2005 Gordon Kindlmann 5 Copyright (C) 2004, 2003, 2002, 2001, 2000, 1999, 1998 University of Utah 6 7 This library is free software; you can redistribute it and/or 8 modify it under the terms of the GNU Lesser General Public License 9 (LGPL) as published by the Free Software Foundation; either 10 version 2.1 of the License, or (at your option) any later version. 11 The terms of redistributing and/or modifying this software also 12 include exceptions to the LGPL that facilitate static linking. 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 License 20 along with this library; if not, write to Free Software Foundation, Inc., 21 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 */ 23 24 #ifndef ECHO_HAS_BEEN_INCLUDED 25 #define ECHO_HAS_BEEN_INCLUDED 26 27 /* NOTE: this library has not undergone the changes as other Teem 28 libraries in order to make sure that array lengths and indices 29 are stored in unsigned types */ 30 31 #include <stdio.h> 32 #include <math.h> 33 34 #include <teem/air.h> 35 #include <teem/biff.h> 36 #include <teem/ell.h> 37 #include <teem/nrrd.h> 38 #include <teem/limn.h> 39 40 #if defined(_WIN32) && !defined(__CYGWIN__) && !defined(TEEM_STATIC) 41 # if defined(TEEM_BUILD) || defined(echo_EXPORTS) || defined(teem_EXPORTS) 42 # define ECHO_EXPORT extern __declspec(dllexport) 43 # else 44 # define ECHO_EXPORT extern __declspec(dllimport) 45 # endif 46 #else /* TEEM_STATIC || UNIX */ 47 # define ECHO_EXPORT extern 48 #endif 49 50 #ifdef __cplusplus 51 extern "C" { 52 #endif 53 54 #define ECHO echoBiffKey 55 56 /* all position and transform information is kept as: 57 ** 1: float 58 ** 0: double 59 */ 60 #if 0 61 typedef float echoPos_t; 62 # define ECHO_POS_FLOAT 1 63 #else 64 typedef double echoPos_t; 65 # define ECHO_POS_FLOAT 0 66 #endif 67 68 69 /* all color information is kept as 70 ** 1: float 71 ** 0: double 72 */ 73 #if 1 74 typedef float echoCol_t; 75 # define echoCol_nt nrrdTypeFloat 76 #else 77 typedef double echoCol_t; 78 # define echoCol_nt nrrdTypeDouble 79 #endif 80 81 #define ECHO_LIST_OBJECT_INCR 32 82 #define ECHO_IMG_CHANNELS 5 83 #define ECHO_EPSILON 0.00005 /* used for adjusting ray positions */ 84 #define ECHO_NEAR0 0.004 /* used for comparing transparency to zero */ 85 #define ECHO_LEN_SMALL_ENOUGH 5 /* to control splitting for split objects */ 86 87 #define ECHO_THREAD_MAX 512 /* max number of threads */ 88 89 typedef struct { 90 int jitterType, /* from echoJitter* enum below */ 91 reuseJitter, /* don't recompute jitter offsets per pixel */ 92 permuteJitter, /* properly permute the various jitter arrays */ 93 textureNN, /* use nearest-neighbor for texture lookups 94 (rather than bilinear interpolation) */ 95 numSamples, /* rays per pixel */ 96 imgResU, imgResV, /* horz. and vert. image resolution */ 97 maxRecDepth, /* max recursion depth */ 98 renderLights, /* render the area lights */ 99 renderBoxes, /* faintly render bounding boxes */ 100 seedRand, /* call airSrandMT() (don't if repeatability wanted) */ 101 sqNRI, /* how many iterations of newton-raphson we allow for 102 finding superquadric root (within tolorance sqTol) */ 103 numThreads; /* number of threads to spawn per rendering */ 104 echoPos_t 105 sqTol; /* how close newtwon-raphson must get to zero */ 106 echoCol_t 107 shadow, /* the extent to which shadows are seen: 108 0: no shadow rays cast 109 >0: shadow rays cast, results weighed by shadow 110 1: full shadowing */ 111 glassC; /* should really be an additional material parameter: 112 Beer's law attenuation in glass */ 113 float aperture, /* shallowness of field */ 114 timeGamma, /* gamma for values in time image */ 115 boxOpac; /* opacity of bounding boxes with renderBoxes */ 116 echoCol_t 117 maxRecCol[3]; /* color of max recursion depth being hit */ 118 } echoRTParm; 119 120 struct echoScene_t; 121 122 typedef struct { 123 int verbose; 124 double time; /* time it took to render image */ 125 Nrrd *nraw; /* copies of arguments to echoRTRender */ 126 limnCamera *cam; 127 struct echoScene_t *scene; 128 echoRTParm *parm; 129 int workIdx; /* next work assignment (such as a scanline) */ 130 airThreadMutex *workMutex; /* mutex around work assignment */ 131 } echoGlobalState; 132 133 typedef struct { 134 airThread *thread; /* my thread */ 135 echoGlobalState *gstate; 136 int verbose, /* blah blah blah */ 137 threadIdx, /* my thread index */ 138 depth; /* how many recursion levels are we at */ 139 Nrrd *nperm, /* ECHO_JITTABLE_NUM x parm->numSamples array 140 of ints, each column is a (different) random 141 permutation of [0 .. parm->numSamples-1], each 142 row corresponds to the different jittables for 143 a single sample */ 144 *njitt; /* 2 x ECHO_JITTABLE_NUM x parm->numSamples array 145 of echoPos_t's in domain [-1/2,1/2]; like the nperm 146 array, each row is comprised of the jitter vectors 147 (for all possible jittables) to use for 1 sample */ 148 unsigned int *permBuff; /* temp array for creating permutations */ 149 echoPos_t *jitt; /* pointer into njitt, good for current sample */ 150 echoCol_t *chanBuff; /* for storing ray color and other parameters for each 151 of the parm->numSamples rays in current pixel */ 152 airRandMTState *rst; /* random number state */ 153 void *returnPtr; /* for airThreadJoin */ 154 } echoThreadState; 155 156 /* 157 ******** echoJitter* enum 158 ** 159 ** the different jitter patterns that are supported. This setting is 160 ** global- you can't have different jitter patterns on the lights versus 161 ** the pixels. 162 */ 163 enum { 164 echoJitterUnknown=-1, 165 echoJitterNone, /* 0: N samples all at the square center */ 166 echoJitterGrid, /* 1: N samples exactly on a sqrt(N) x sqrt(N) grid */ 167 echoJitterJitter, /* 2: N jittered samples on a sqrt(N) x sqrt(N) grid */ 168 echoJitterRandom, /* 3: N samples randomly placed in square */ 169 echoJitterLast 170 }; 171 #define ECHO_JITTER_NUM 4 172 173 /* 174 ******** echoJittable* enum 175 ** 176 ** the different quantities to which the jitter two-vector may be 177 ** applied. 178 */ 179 enum { 180 echoJittableUnknown=-1, 181 echoJittablePixel, /* 0 */ 182 echoJittableLight, /* 1 */ 183 echoJittableLens, /* 2 */ 184 echoJittableNormalA, /* 3 */ 185 echoJittableNormalB, /* 4 */ 186 echoJittableMotionA, /* 5 */ 187 echoJittableMotionB, /* 6 */ 188 echoJittableLast 189 }; 190 #define ECHO_JITTABLE_NUM 7 191 192 /* 193 ******** echoMatter* enum 194 ** 195 ** the different materials that are supported. This setting determines 196 ** the interpretation of the vector of floats/doubles ("mat[]") that 197 ** constitutes material information. All objects have an rgba[] array 198 ** separate from material information. The Light material is currently only 199 ** supported on rectangles. 200 */ 201 enum { 202 echoMatterUnknown=0, 203 echoMatterPhong, /* 1 */ 204 echoMatterGlass, /* 2 */ 205 echoMatterMetal, /* 3 */ 206 echoMatterLight, /* 4 */ 207 echoMatterLast 208 }; 209 #define ECHO_MATTER_MAX 4 210 211 enum { 212 echoMatterPhongKa, /* 0 */ 213 echoMatterPhongKd, /* 1 */ 214 echoMatterPhongKs, /* 2 */ 215 echoMatterPhongSp /* 3 */ 216 }; 217 enum { 218 echoMatterGlassIndex, /* 0 */ 219 echoMatterGlassKa, /* 1 */ 220 echoMatterGlassKd, /* 2 */ 221 echoMatterGlassFuzzy /* 3 */ 222 }; 223 enum { 224 echoMatterMetalR0, /* 0 */ 225 echoMatterMetalKa, /* 1 */ 226 echoMatterMetalKd, /* 2 */ 227 echoMatterMetalFuzzy /* 3 */ 228 }; 229 enum { 230 echoMatterLightPower, /* 0 */ 231 echoMatterLightUnit /* 1 : (takes over role of old parm->refDistance) 232 distance to be considered unity when calculating 233 inverse square fall-off of light intensity, or, 234 use 0.0 to mean "this is a directional light" 235 (with no fall-off at all) */ 236 }; 237 238 #define ECHO_MATTER_PARM_NUM 4 239 240 /* 241 ******** echoType* enum 242 ** 243 ** the types of objects that echo supports 244 */ 245 enum { 246 echoTypeUnknown=-1, 247 echoTypeSphere, /* 0 */ 248 echoTypeCylinder, /* 1 */ 249 echoTypeSuperquad, /* 2 */ 250 echoTypeCube, /* 3 */ 251 echoTypeTriangle, /* 4 */ 252 echoTypeRectangle, /* 5 */ 253 echoTypeTriMesh, /* 6: only triangles in the mesh */ 254 echoTypeIsosurface, /* 7 */ 255 echoTypeAABBox, /* 8 */ 256 echoTypeSplit, /* 9 */ 257 echoTypeList, /* 10 */ 258 echoTypeInstance, /* 11 */ 259 echoTypeLast 260 }; 261 262 #define ECHO_TYPE_NUM 12 263 264 /* 265 ******** echoObject (generic) and all other object structs 266 ** 267 ** every starts with ECHO_OBJECT_COMMON, and all the "real" objects 268 ** have a ECHO_OBJECT_MATTER following that 269 */ 270 271 #define ECHO_OBJECT_COMMON \ 272 signed char type 273 274 #define ECHO_OBJECT_MATTER \ 275 unsigned char matter; \ 276 echoCol_t rgba[4]; \ 277 echoCol_t mat[ECHO_MATTER_PARM_NUM]; \ 278 Nrrd *ntext 279 280 typedef struct { 281 ECHO_OBJECT_COMMON; 282 ECHO_OBJECT_MATTER; /* ha! its not actually in every object, but in 283 those cases were we want to access it without 284 knowing object type, then it will be there. */ 285 } echoObject; 286 287 typedef struct { 288 ECHO_OBJECT_COMMON; 289 ECHO_OBJECT_MATTER; 290 echoPos_t pos[3], rad; 291 } echoSphere; 292 293 typedef struct { 294 ECHO_OBJECT_COMMON; 295 ECHO_OBJECT_MATTER; 296 int axis; 297 } echoCylinder; 298 299 typedef struct { 300 ECHO_OBJECT_COMMON; 301 ECHO_OBJECT_MATTER; 302 int axis; 303 echoPos_t A, B; 304 } echoSuperquad; 305 306 /* edges are unit length, [-0.5, 0.5] on every edge */ 307 typedef struct { 308 ECHO_OBJECT_COMMON; 309 ECHO_OBJECT_MATTER; 310 } echoCube; 311 312 typedef struct { 313 ECHO_OBJECT_COMMON; 314 ECHO_OBJECT_MATTER; 315 echoPos_t vert[3][3]; /* e0 = vert[1]-vert[0], 316 e1 = vert[2]-vert[0], 317 normal = e0 x e1 */ 318 } echoTriangle; 319 320 typedef struct { 321 ECHO_OBJECT_COMMON; 322 ECHO_OBJECT_MATTER; 323 echoPos_t origin[3], edge0[3], edge1[3]; 324 } echoRectangle; 325 326 typedef struct { 327 ECHO_OBJECT_COMMON; 328 ECHO_OBJECT_MATTER; 329 echoPos_t meanvert[3], min[3], max[3]; 330 int numV, numF; 331 echoPos_t *pos; 332 int *vert; 333 } echoTriMesh; 334 335 typedef struct { 336 ECHO_OBJECT_COMMON; 337 ECHO_OBJECT_MATTER; 338 /* this needs more stuff, perhaps a gageContext */ 339 Nrrd *volume; 340 float value; 341 } echoIsosurface; 342 343 typedef struct { 344 ECHO_OBJECT_COMMON; 345 echoObject *obj; 346 echoPos_t min[3], max[3]; 347 } echoAABBox; 348 349 typedef struct { 350 ECHO_OBJECT_COMMON; 351 int axis; /* which axis was split: 0:X, 1:Y, 2:Z */ 352 echoPos_t min0[3], max0[3], 353 min1[3], max1[3]; /* bboxes of two children */ 354 echoObject *obj0, *obj1; /* two splits, or ??? */ 355 } echoSplit; 356 357 typedef struct { 358 ECHO_OBJECT_COMMON; 359 echoObject **obj; 360 airArray *objArr; 361 } echoList; 362 363 typedef struct { 364 ECHO_OBJECT_COMMON; 365 echoPos_t Mi[16], M[16]; 366 echoObject *obj; 367 } echoInstance; 368 369 /* 370 ******** echoScene 371 ** 372 ** this is the central list of all objects in a scene, and all nrrds 373 ** used for textures and isosurface volumes. The scene "owns" all 374 ** the objects it points to, so that nixing it will cause all objects 375 ** and nrrds to be nixed and nuked, respectively. 376 */ 377 typedef struct echoScene_t { 378 echoObject **cat; /* array of ALL objects and all lights */ 379 airArray *catArr; 380 echoObject **rend; /* array of top-level objects to be rendered */ 381 airArray *rendArr; 382 echoObject **light; /* convenience pointers to lights within cat[] */ 383 airArray *lightArr; 384 Nrrd **nrrd; /* nrrds for textures and isosurfaces */ 385 airArray *nrrdArr; 386 Nrrd *envmap; /* 16checker-based diffuse environment map, 387 not touched by echoSceneNix() */ 388 echoCol_t ambi[3], /* color of ambient light */ 389 bkgr[3]; /* color of background */ 390 } echoScene; 391 392 /* 393 ******** echoRay 394 ** 395 ** all info associated with a ray being intersected against a scene 396 */ 397 typedef struct { 398 echoPos_t from[3], /* ray comes from this point */ 399 dir[3], /* ray goes in this (not normalized) direction */ 400 neer, faar; /* look for intx in this interval */ 401 int shadow; /* this is a shadow ray */ 402 echoCol_t transp; /* for shadow rays, the transparency so far; starts 403 at 1.0, goes down to 0.0 */ 404 } echoRay; 405 406 /* 407 ******** echoIntx 408 ** 409 ** all info about nature and location of an intersection 410 */ 411 typedef struct { 412 echoObject *obj; /* computed with every intersection */ 413 echoPos_t t, /* computed with every intersection */ 414 u, v; /* sometimes needed for texturing */ 415 echoPos_t norm[3], /* computed with every intersection */ 416 view[3], /* always used with coloring */ 417 refl[3], /* reflection of view across line spanned by normal */ 418 pos[3]; /* always used with coloring (and perhaps texturing) */ 419 int face, /* in intx with cube, which face was hit 420 (used for textures) */ 421 boxhits; /* how many bounding boxes we hit */ 422 } echoIntx; 423 424 typedef union { 425 echoObject ***obj; 426 Nrrd ***nrd; 427 void **v; 428 } echoPtrPtrUnion; 429 430 /* enumsEcho.c ------------------------------------------ */ 431 ECHO_EXPORT const airEnum *const echoJitter; 432 ECHO_EXPORT const airEnum *const echoType; 433 ECHO_EXPORT const airEnum *const echoMatter; 434 435 /* methodsEcho.c --------------------------------------- */ 436 ECHO_EXPORT const int echoPresent; 437 ECHO_EXPORT const char *echoBiffKey; 438 ECHO_EXPORT echoRTParm *echoRTParmNew(void); 439 ECHO_EXPORT echoRTParm *echoRTParmNix(echoRTParm *parm); 440 ECHO_EXPORT echoGlobalState *echoGlobalStateNew(void); 441 ECHO_EXPORT echoGlobalState *echoGlobalStateNix(echoGlobalState *state); 442 ECHO_EXPORT echoThreadState *echoThreadStateNew(void); 443 ECHO_EXPORT echoThreadState *echoThreadStateNix(echoThreadState *state); 444 ECHO_EXPORT echoScene *echoSceneNew(void); 445 ECHO_EXPORT echoScene *echoSceneNix(echoScene *scene); 446 447 /* objmethods.c --------------------------------------- */ 448 ECHO_EXPORT echoObject *echoObjectNew(echoScene *scene, signed char type); 449 ECHO_EXPORT int echoObjectAdd(echoScene *scene, echoObject *obj); 450 ECHO_EXPORT echoObject *echoObjectNix(echoObject *obj); 451 452 /* model.c ---------------------------------------- */ 453 ECHO_EXPORT echoObject *echoRoughSphereNew(echoScene *scene, 454 int theRes, int phiRes, 455 echoPos_t *matx); 456 457 /* bounds.c --------------------------------------- */ 458 ECHO_EXPORT void echoBoundsGet(echoPos_t *lo, echoPos_t *hi, echoObject *obj); 459 460 /* list.c --------------------------------------- */ 461 ECHO_EXPORT void echoListAdd(echoObject *parent, echoObject *child); 462 ECHO_EXPORT echoObject *echoListSplit(echoScene *scene, 463 echoObject *list, int axis); 464 ECHO_EXPORT echoObject *echoListSplit3(echoScene *scene, 465 echoObject *list, int depth); 466 467 /* set.c --------------------------------------- */ 468 ECHO_EXPORT void echoSphereSet(echoObject *sphere, 469 echoPos_t x, echoPos_t y, 470 echoPos_t z, echoPos_t rad); 471 ECHO_EXPORT void echoCylinderSet(echoObject *cylind, 472 int axis); 473 ECHO_EXPORT void echoSuperquadSet(echoObject *squad, 474 int axis, echoPos_t A, echoPos_t B); 475 ECHO_EXPORT void echoRectangleSet(echoObject *rect, 476 echoPos_t ogx, echoPos_t ogy, echoPos_t ogz, 477 echoPos_t x0, echoPos_t y0, echoPos_t z0, 478 echoPos_t x1, echoPos_t y1, echoPos_t z1); 479 ECHO_EXPORT void echoTriangleSet(echoObject *tri, 480 echoPos_t x0, echoPos_t y0, echoPos_t z0, 481 echoPos_t x1, echoPos_t y1, echoPos_t z1, 482 echoPos_t x2, echoPos_t y2, echoPos_t z2); 483 ECHO_EXPORT void echoTriMeshSet(echoObject *trim, 484 int numV, echoPos_t *pos, 485 int numF, int *vert); 486 ECHO_EXPORT void echoInstanceSet(echoObject *inst, 487 echoPos_t *M, echoObject *obj); 488 489 /* matter.c ------------------------------------------ */ 490 ECHO_EXPORT int echoObjectHasMatter[ECHO_TYPE_NUM]; 491 ECHO_EXPORT void echoColorSet(echoObject *obj, 492 echoCol_t R, echoCol_t G, 493 echoCol_t B, echoCol_t A); 494 ECHO_EXPORT void echoMatterPhongSet(echoScene *scene, echoObject *obj, 495 echoCol_t ka, echoCol_t kd, 496 echoCol_t ks, echoCol_t sp); 497 ECHO_EXPORT void echoMatterGlassSet(echoScene *scene, echoObject *obj, 498 echoCol_t index, echoCol_t ka, 499 echoCol_t kd, echoCol_t fuzzy); 500 ECHO_EXPORT void echoMatterMetalSet(echoScene *scene, echoObject *obj, 501 echoCol_t R0, echoCol_t ka, 502 echoCol_t kd, echoCol_t fuzzy); 503 ECHO_EXPORT void echoMatterLightSet(echoScene *scene, echoObject *obj, 504 echoCol_t power, echoCol_t unit); 505 ECHO_EXPORT void echoMatterTextureSet(echoScene *scene, echoObject *obj, 506 Nrrd *ntext); 507 508 /* lightEcho.c ------------------------------------------- */ 509 ECHO_EXPORT void echoLightPosition(echoPos_t pos[3], echoObject *light, 510 echoThreadState *tstate); 511 ECHO_EXPORT void echoLightColor(echoCol_t rgb[3], echoPos_t Ldist, 512 echoObject *light, echoRTParm *parm, 513 echoThreadState *tstate); 514 ECHO_EXPORT void echoEnvmapLookup(echoCol_t rgb[3], echoPos_t norm[3], 515 Nrrd *envmap); 516 517 /* color.c ------------------------------------------- */ 518 ECHO_EXPORT void echoTextureLookup(echoCol_t rgba[4], Nrrd *ntext, 519 echoPos_t u, echoPos_t v, echoRTParm *parm); 520 ECHO_EXPORT void echoIntxMaterialColor(echoCol_t rgba[4], echoIntx *intx, 521 echoRTParm *parm); 522 ECHO_EXPORT void echoIntxLightColor(echoCol_t ambi[3], echoCol_t diff[3], 523 echoCol_t spec[3], echoCol_t sp, 524 echoIntx *intx, echoScene *scene, 525 echoRTParm *parm, echoThreadState *tstate); 526 ECHO_EXPORT void echoIntxFuzzify(echoIntx *intx, echoCol_t fuzz, 527 echoThreadState *tstate); 528 529 /* intx.c ------------------------------------------- */ 530 ECHO_EXPORT int echoRayIntx(echoIntx *intx, echoRay *ray, echoScene *scene, 531 echoRTParm *parm, echoThreadState *tstate); 532 ECHO_EXPORT void echoIntxColor(echoCol_t rgba[4], echoIntx *intx, 533 echoScene *scene, echoRTParm *parm, 534 echoThreadState *tstate); 535 536 /* renderEcho.c ---------------------------------------- */ 537 ECHO_EXPORT int echoThreadStateInit(int threadIdx, echoThreadState *tstate, 538 echoRTParm *parm, echoGlobalState *gstate); 539 ECHO_EXPORT void echoJitterCompute(echoRTParm *parm, echoThreadState *state); 540 ECHO_EXPORT void echoRayColor(echoCol_t rgba[4], echoRay *ray, 541 echoScene *scene, echoRTParm *parm, 542 echoThreadState *tstate); 543 ECHO_EXPORT void echoChannelAverage(echoCol_t *img, 544 echoRTParm *parm, echoThreadState *tstate); 545 ECHO_EXPORT int echoRTRenderCheck(Nrrd *nraw, limnCamera *cam, 546 echoScene *scene, echoRTParm *parm, 547 echoGlobalState *gstate); 548 ECHO_EXPORT int echoRTRender(Nrrd *nraw, limnCamera *cam, echoScene *scene, 549 echoRTParm *parm, echoGlobalState *gstate); 550 551 #ifdef __cplusplus 552 } 553 #endif 554 555 #endif /* ECHO_HAS_BEEN_INCLUDED */ 556 557