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