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   Copyright (C) 2012, 2011, 2010  Thomas Schultz
7 
8   This library is free software; you can redistribute it and/or
9   modify it under the terms of the GNU Lesser General Public License
10   (LGPL) as published by the Free Software Foundation; either
11   version 2.1 of the License, or (at your option) any later version.
12   The terms of redistributing and/or modifying this software also
13   include exceptions to the LGPL that facilitate static linking.
14 
15   This library is distributed in the hope that it will be useful,
16   but WITHOUT ANY WARRANTY; without even the implied warranty of
17   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18   Lesser General Public License for more details.
19 
20   You should have received a copy of the GNU Lesser General Public License
21   along with this library; if not, write to Free Software Foundation, Inc.,
22   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
23 */
24 
25 #ifndef LIMN_HAS_BEEN_INCLUDED
26 #define LIMN_HAS_BEEN_INCLUDED
27 
28 #include <stdlib.h>
29 
30 #include <math.h>
31 
32 #include <teem/air.h>
33 #include <teem/biff.h>
34 #include <teem/hest.h>
35 #include <teem/ell.h>
36 #include <teem/nrrd.h>
37 #include <teem/gage.h>
38 #include <teem/unrrdu.h>
39 
40 #if defined(_WIN32) && !defined(__CYGWIN__) && !defined(TEEM_STATIC)
41 #  if defined(TEEM_BUILD) || defined(limn_EXPORTS) || defined(teem_EXPORTS)
42 #    define LIMN_EXPORT extern __declspec(dllexport)
43 #  else
44 #    define LIMN_EXPORT extern __declspec(dllimport)
45 #  endif
46 #else /* TEEM_STATIC || UNIX */
47 #  define LIMN_EXPORT extern
48 #endif
49 
50 #ifdef __cplusplus
51 extern "C" {
52 #endif
53 
54 #define LIMN limnBiffKey
55 #define LIMN_LIGHT_NUM 8
56 
57 /*
58 ******** #define LIMN_SPLINE_Q_AVG_EPS
59 **
60 ** The convergence tolerance used for Buss/Fillmore quaternion
61 ** averaging
62 */
63 #define LIMN_SPLINE_Q_AVG_EPS 0.00001
64 
65 /*
66 ****** limnCamera struct
67 **
68 ** for all standard graphics camera parameters.  Image plane is
69 ** spanned by U and V; N always points away from the viewer, U
70 ** always points to the right, V can point up or down, if the
71 ** camera is left- or right-handed, respectively.
72 **
73 ** Has no dynamically allocated information or pointers.
74 */
75 typedef struct limnCamera_t {
76   double from[3],     /* location of eyepoint */
77     at[3],            /* what eye is looking at */
78     up[3],            /* what is up direction for eye (this is not updated
79                          to the "true" up) */
80     uRange[2],        /* range of U values to put on horiz. image axis */
81     vRange[2],        /* range of V values to put on vert. image axis */
82     fov,              /* if non-NaN, and aspect is non-NaN, then {u,v}Range
83                          will be set accordingly by limnCameraUpdate().
84                          "fov" is the angle, in degrees, vertically subtended
85                          by the view window */
86     aspect,           /* the ratio of horizontal to vertical size of the
87                          view window */
88     neer, faar,       /* near and far clipping plane distances
89                          (misspelled for the sake of a McRosopht compiler) */
90     dist;             /* distance to image plane */
91   int atRelative,     /* if non-zero: given neer, faar, and dist
92                          quantities indicate distance relative to the
93                          _at_ point, instead of the usual (in computer
94                          graphics) sense if being relative to the
95                          eye point */
96     orthographic,     /* no perspective projection: just orthographic */
97     rightHanded;      /* if rightHanded, V = NxU (V points "downwards"),
98                          otherwise, V = UxN (V points "upwards") */
99   /* --------------------------------------------------------------------
100      End of user-set parameters.  Things below are set by limnCameraUpdate
101      -------------------------------------------------------------------- */
102   double W2V[16],     /* World to view transform. The _rows_ of this
103                          matrix (its 3x3 submatrix) are the U, V, N
104                          vectors which form the view-space coordinate frame.
105                          The column-major ordering of elements in the
106                          matrix is from ell:
107                          0   4   8  12
108                          1   5   9  13
109                          2   6  10  14
110                          3   7  11  15 */
111     V2W[16],          /* View to world transform */
112     U[4], V[4], N[4], /* View space basis vectors (in world coords)
113                          last element always zero */
114     vspNeer, vspFaar, /* not usually user-set: near, far, and image plane
115                          distances, in view space */
116     vspDist;
117 } limnCamera;
118 
119 /*
120 ******** struct limnLight
121 **
122 ** information for directional lighting and the ambient light.  All
123 ** the vectors are length 4 (instead of 3) for the sake of passing them
124 ** directly to OpenGL. For colors, the last coefficient (alpha) is
125 ** always 1.0, and for directions it is 0.0 (w, homog coord).
126 **
127 **
128 ** Has no dynamically allocated information or pointers
129 */
130 typedef struct {
131   float amb[4],              /* RGBA ambient light color */
132     _dir[LIMN_LIGHT_NUM][4], /* direction of light[i] (view or world space).
133                                 This is what the user sets via limnLightSet */
134     dir[LIMN_LIGHT_NUM][4],  /* direction of light[i] (ONLY world space)
135                                 Not user-set: calculated/copied from _dir[] */
136     col[LIMN_LIGHT_NUM][4];  /* RGBA color of light[i] */
137   int on[LIMN_LIGHT_NUM],    /* light[i] is on */
138     vsp[LIMN_LIGHT_NUM];     /* light[i] lives in view space */
139 } limnLight;
140 
141 enum {
142   limnDeviceUnknown,
143   limnDevicePS,
144   limnDeviceGL,
145   limnDeviceLast
146 };
147 
148 enum {
149   limnEdgeTypeUnknown,     /* 0 */
150   limnEdgeTypeBackFacet,   /* 1: back-facing non-crease */
151   limnEdgeTypeBackCrease,  /* 2: back-facing crease */
152   limnEdgeTypeContour,     /* 3: silhoette edge */
153   limnEdgeTypeFrontCrease, /* 4: front-facing crease */
154   limnEdgeTypeFrontFacet,  /* 5: front-facing non-crease */
155   limnEdgeTypeBorder,      /* 6: attached to only one face */
156   limnEdgeTypeLone,        /* 7: attached to no faces */
157   limnEdgeTypeLast
158 };
159 #define LIMN_EDGE_TYPE_MAX    7
160 
161 typedef struct {
162   float lineWidth[LIMN_EDGE_TYPE_MAX+1],
163     creaseAngle,      /* difference between crease and facet, in *degrees* */
164     bg[3],            /* background color */
165     edgeColor[3];     /* edge color */
166   int showpage,       /* finish with "showpage" */
167     wireFrame,        /* just render wire-frame */
168     noBackground;     /* refrain from initially filling with bg[] color */
169 } limnOptsPS;
170 
171 typedef struct {
172   limnOptsPS ps;
173   int device;
174   float scale,
175     bbox[4];          /* minX minY maxX maxY */
176   int yFlip;
177   FILE *file;
178 } limnWindow;
179 
180 enum {
181   limnSpaceUnknown,  /* 0 */
182   limnSpaceWorld,    /* 1 */
183   limnSpaceView,     /* 2 */
184   limnSpaceScreen,   /* 3 */
185   limnSpaceDevice,   /* 4 */
186   limnSpaceLast
187 };
188 #define LIMN_SPACE_MAX  4
189 
190 /*
191 ******** limnPrimitive* enum
192 **
193 ** primitive types in the limnPolyData (should probably called
194 ** limnPolyDataPrimitiveType).
195 **
196 ** keep in sync: Deft/src/PolyData.cxx/PolyData::drawImmediate()
197 */
198 enum {
199   limnPrimitiveUnknown,       /* 0 */
200   limnPrimitiveNoop,          /* 1: no-op primitive, nothing drawn */
201   limnPrimitiveTriangles,     /* 2: triangle soup (for GL_TRIANGLES) */
202   limnPrimitiveTriangleStrip, /* 3: triangle strip (for GL_TRIANGLE_STRIP) */
203   limnPrimitiveTriangleFan,   /* 4: triangle fan (for GL_TRIANGLE_FAN) */
204   limnPrimitiveQuads,         /* 5: quad soup (for GL_QUADS) */
205   limnPrimitiveLineStrip,     /* 6: line strip (for GL_LINE_STRIP) */
206   limnPrimitiveLines,         /* 7: line soup (for GL_LINES) */
207   limnPrimitiveLast
208 };
209 #define LIMN_PRIMITIVE_MAX       7
210 
211 /*
212 ******** struct limnLook
213 **
214 ** surface properties: pretty much anything having to do with
215 ** appearance, for points, edges, faces, etc.
216 */
217 typedef struct {
218   float rgba[4];
219   float kads[3],              /* phong: ka, kd, ks */
220     spow;                     /* specular power */
221 } limnLook;
222 
223 /*
224 ******** struct limnVertex
225 **
226 ** all the information you might want for a point.
227 **
228 ** This used to have separate coordinate arrays for view, screen, and
229 ** device space, but these have been collapsed (in the interest of space)
230 ** into coord, with obj->vertSpace indicating which space these are in.
231 ** This also used to have a lookIdx (now just rgba[4]), and a partIdx
232 ** (which was never actually used).
233 **
234 ** Has no dynamically allocated information or pointers
235 */
236 typedef struct {
237   float world[4],             /* world coordinates (homogeneous) */
238     rgba[4],                  /* RGBA color */
239     coord[4],                 /* coordinates in some space */
240     worldNormal[3];           /* vertex normal (world coords only) */
241 } limnVertex;
242 
243 /*
244 ******** struct limnEdge
245 **
246 ** all the information about an edge
247 **
248 ** Has no dynamically allocated information or pointers
249 */
250 typedef struct limnEdge_t {
251   unsigned int vertIdx[2], /* indices into object's master vert array */
252     lookIdx,               /* index into parent's look array */
253     partIdx;               /* which part do we belong to */
254   int type,                /* from the limnEdgeType enum */
255     faceIdx[2],            /* indices into object's master face array */
256     once;                  /* flag used for certain kinds of rendering */
257 } limnEdge;
258 
259 /*
260 ******** struct limnFace
261 **
262 ** all the information about a face
263 */
264 typedef struct limnFace_t {
265   float worldNormal[3],
266     screenNormal[3];
267   unsigned int *vertIdx,      /* regular array (*not* airArray) of vertex
268                                  indices in object's master vert array */
269     *edgeIdx,                 /* likewise for edges */
270     sideNum,                  /* number of sides (allocated length of
271                                  {vert,edge}Idx arrays */
272     lookIdx,
273     partIdx;
274   int visible;                /* non-zero if face currently visible */
275   float depth;
276 } limnFace;
277 
278 /*
279 ******** struct limnPart
280 **
281 ** one connected part of an object
282 */
283 typedef struct limnPart_t {
284   /* (air)arrays of indices in object's vert array */
285   unsigned int *vertIdx, vertIdxNum;
286   airArray *vertIdxArr;
287 
288   /* (air)arrays of indices in object's edge array */
289   unsigned int *edgeIdx, edgeIdxNum;
290   airArray *edgeIdxArr;
291 
292   /* (air)arrays of indices in object's face array */
293   unsigned int *faceIdx, faceIdxNum;
294   airArray *faceIdxArr;
295   int lookIdx;
296   float depth;
297 } limnPart;
298 
299 /*
300 ******** struct limnObject
301 **
302 ** the beast used to represent polygonal objects
303 **
304 ** Relies on many dynamically allocated arrays
305 **
306 ** learned: I used to have an array of limnParts inside here, and that
307 ** array was managed by an airArray.  Inside the limnPart, are more
308 ** airArrays, for example the faceIdxArr which internally stores the
309 ** *address* of faceIdx.  When the array of limnParts is resized, the
310 ** limnPart's faceIdx pointer is still valid, and faceIdxArr is still
311 ** valid, but the faceIdxArr's internal pointer to the faceIdx pointer
312 ** is now bogus.  Thus: the weakness of airArrays (as long as they
313 ** aren't giving the data pointer anew for EACH ACCESS), is that you
314 ** must not confuse the airArrays by changing the address of its user
315 ** data pointer.  Putting user data pointers inside of a bigger
316 ** airArray is a fine way to create such confusion.
317 */
318 typedef struct {
319   limnVertex *vert; unsigned int vertNum;
320   airArray *vertArr;
321 
322   limnEdge *edge; unsigned int edgeNum;
323   airArray *edgeArr;
324 
325   limnFace *face; unsigned int faceNum;
326   airArray *faceArr;
327   limnFace **faceSort;    /* pointers into "face", sorted by depth */
328 
329   limnPart **part; unsigned int partNum;  /* double indirection, see above */
330   airArray *partArr;
331 
332   limnPart **partPool; unsigned int partPoolNum;
333   airArray *partPoolArr;
334 
335   limnLook *look; unsigned int lookNum;
336   airArray *lookArr;
337 
338   int vertSpace,           /* which space limnVertex->coord is in */
339     setVertexRGBAFromLook, /* when possible, copy vertex RGB values
340                               from limnLook of part (not face) */
341     doEdges;               /* if non-zero, build edges as faces are added */
342   unsigned incr;           /* increment to use with airArrays */
343 } limnObject;
344 
345 /*
346 ******** struct limnVrt
347 **
348 ** a very abbreviated limnVertex
349 **
350 ** this was killed Sun Feb  5 16:50:23 EST 2006 with the re-organization of
351 ** limnPolyData to have per-attribute arrays
352 **
353 typedef struct {
354   float xyzw[4],              / * homogeneous coordinates * /
355     norm[3];                  / * normal * /
356   unsigned char rgba[4];      / * RGBA color * /
357 } limnVrt;
358 */
359 
360 /*
361 ******** limnPolyDataInfo* enum
362 **
363 ** information that may be known per-vertex in limnPolyData
364 **
365 ** NOTE: The xyzw position data is always required, and that is always
366 ** allocated and present.  This is the optional extra per-vertex information.
367 */
368 enum {
369   limnPolyDataInfoUnknown,    /* 0: nobody knows */
370   limnPolyDataInfoRGBA,       /* 1: RGBA 4-tuple */
371   limnPolyDataInfoNorm,       /* 2: (x,y,z) unit-length 3-vector */
372   limnPolyDataInfoTex2,       /* 3: (s,t) 2D texture coordinates */
373   limnPolyDataInfoTang,       /* 4: unit-length surface tangent 3-vector */
374   limnPolyDataInfoLast
375 };
376 #define LIMN_POLY_DATA_INFO_MAX  4
377 
378 /*
379 ******** limnPolyData
380 **
381 ** A simpler beast for representing polygonal surfaces and other things
382 **
383 ** There is no notion of "part" here; there may be multiple
384 ** disconnected pieces inside the surface, but there is no way of
385 ** accessing just one such piece (because this is organized in terms
386 ** of primitives, and each piece may be made of multiple primitives).
387 ** Having separate parts is important for PostScript rendering, but
388 ** the limnPolyData is more OpenGL oriented.
389 **
390 ** Experimenting with *not* having airArrays here . . .
391 **
392 ** There need to be per-attribute "xxxNum" variables because otherwise
393 ** it is impossible to unambiguously manage both changes in the number
394 ** of vertices, and changes in the set of attributes required.
395 **
396 ** The idea is that at some point general gage info could be stored
397 ** per-vertex here, until that happens there is probably not going
398 ** to be explicit dependence of limn on gage (now that limnFeature
399 ** stuff moved to the "seek" library)
400 */
401 typedef struct {
402   float *xyzw;           /* (always allocated) xyzwNum position 4-tuples */
403   unsigned int xyzwNum;  /* logical size of xyzw */
404   unsigned char *rgba;   /* if non-NULL, rgbaNum RGBA color 4-tuples */
405   unsigned int rgbaNum;  /* logical size of rgba */
406   float *norm;           /* if non-NULL, normNum (x,y,z) unit normals */
407   unsigned int normNum;  /* logical size of norm */
408   float *tex2;           /* if non-NULL, tex2Num (s,t) 2D texture coords */
409   unsigned int tex2Num;  /* logical size of tex2 */
410   float *tang;           /* if non-NULL, tangNum unit surface tangents */
411   unsigned int tangNum;  /* logical size of tang */
412 
413   unsigned int indxNum;  /* there are indxNum vertex indices in indx[] */
414   unsigned int *indx;    /* all indices (into above arrays) for all primitives,
415                             concatenated together into one array */
416 
417   unsigned int primNum;  /* there are primNum primitives (e.g. tristrips) */
418   unsigned char *type;   /* prim ii is a type[ii] (limnPrimitive* enum) */
419   unsigned int *icnt;    /* prim ii has icnt[ii] vertex indices */
420 } limnPolyData;
421 
422 /*
423 ******** limnQN enum
424 **
425 ** the different quantized normal schemes currently supported
426 */
427 enum {
428   limnQNUnknown,     /*  0 */
429   limnQN16simple,    /*  1 */
430   limnQN16border1,   /*  2 */
431   limnQN16checker,   /*  3 */
432   limnQN16octa,      /*  4 */
433   limnQN15octa,      /*  5 */
434   limnQN14checker,   /*  6 */
435   limnQN14octa,      /*  7 */
436   limnQN13octa,      /*  8 */
437   limnQN12checker,   /*  9 */
438   limnQN12octa,      /* 10 */
439   limnQN11octa,      /* 11 */
440   limnQN10checker,   /* 12 */
441   limnQN10octa,      /* 13 */
442   limnQN9octa,       /* 14 */
443   limnQN8checker,    /* 15 */
444   limnQN8octa,       /* 16 */
445   limnQNLast
446 };
447 #define LIMN_QN_MAX     16
448 
449 enum {
450   limnSplineTypeUnknown,     /* 0 */
451   limnSplineTypeLinear,      /* 1 */
452   limnSplineTypeTimeWarp,    /* 2 */
453   limnSplineTypeHermite,     /* 3 */
454   limnSplineTypeCubicBezier, /* 4 */
455   limnSplineTypeBC,          /* 5 */
456   limnSplineTypeLast
457 };
458 #define LIMN_SPLINE_TYPE_MAX    5
459 
460 enum {
461   limnSplineInfoUnknown,    /* 0 */
462   limnSplineInfoScalar,     /* 1 */
463   limnSplineInfo2Vector,    /* 2 */
464   limnSplineInfo3Vector,    /* 3 */
465   limnSplineInfoNormal,     /* 4 */
466   limnSplineInfo4Vector,    /* 5 */
467   limnSplineInfoQuaternion, /* 6 */
468   limnSplineInfoLast
469 };
470 #define LIMN_SPLINE_INFO_MAX   6
471 
472 enum {
473   limnCameraPathTrackUnknown, /* 0 */
474   limnCameraPathTrackFrom,    /* 1: 3-D spline for *from* points, quaternion
475                                  spline for camera directions towards at */
476   limnCameraPathTrackAt,      /* 2: 3-D spline for *at* points, quaternion
477                                  spline for directions back to camera */
478   limnCameraPathTrackBoth,    /* 3: three 3-D splines: for from point, at
479                                  point, and the up vector */
480   limnCameraPathTrackLast
481 };
482 #define LIMN_CAMERA_PATH_TRACK_MAX 3
483 
484 /*
485 ******** limnSpline
486 **
487 ** the ncpt nrrd stores control point information in a 3-D nrrd, with
488 ** sizes C by 3 by N, where C is the number of values needed for each
489 ** point (3 for 3Vecs, 1 for scalars), and N is the number of control
490 ** points.  The 3 things per control point are 0) the pre-point info
491 ** (either inward tangent or an internal control point), 1) the control
492 ** point itself, 2) the post-point info (e.g., outward tangent).
493 **
494 ** NOTE: for the sake of simplicity, the ncpt nrrd is always "owned"
495 ** by the limnSpline, that is, it is COPIED from the one given in
496 ** limnSplineNew() (and is converted to type double along the way),
497 ** and it will is deleted with limnSplineNix.
498 */
499 typedef struct limnSpline_t {
500   int type,          /* from limnSplineType* enum */
501     info,            /* from limnSplineInfo* enum */
502     loop;            /* the last (implicit) control point is the first */
503   double B, C;       /* B,C values for BC-splines */
504   Nrrd *ncpt;        /* the control point info, ALWAYS a 3-D nrrd */
505   double *time;      /* ascending times for non-uniform control points.
506                         Currently, only used for limnSplineTypeTimeWarp */
507 } limnSpline;
508 
509 typedef struct limnSplineTypeSpec_t {
510   int type;          /* from limnSplineType* enum */
511   double B, C;       /* B,C values for BC-splines */
512 } limnSplineTypeSpec;
513 
514 /* defaultsLimn.c */
515 LIMN_EXPORT const int limnPresent;
516 LIMN_EXPORT const char *limnBiffKey;
517 LIMN_EXPORT int limnDefCameraAtRelative;
518 LIMN_EXPORT int limnDefCameraOrthographic;
519 LIMN_EXPORT int limnDefCameraRightHanded;
520 
521 /* enumsLimn.c */
522 LIMN_EXPORT const airEnum *const limnSpace;
523 LIMN_EXPORT const airEnum *const limnPolyDataInfo;
524 LIMN_EXPORT const airEnum *const limnCameraPathTrack;
525 LIMN_EXPORT const airEnum *const limnPrimitive;
526 
527 /* qn.c */
528 LIMN_EXPORT unsigned int limnQNBins[LIMN_QN_MAX+1];
529 LIMN_EXPORT void (*limnQNtoV_f[LIMN_QN_MAX+1])(float *vec, unsigned int qn);
530 LIMN_EXPORT void (*limnQNtoV_d[LIMN_QN_MAX+1])(double *vec, unsigned int qn);
531 LIMN_EXPORT unsigned int (*limnVtoQN_f[LIMN_QN_MAX+1])(const float *vec);
532 LIMN_EXPORT unsigned int (*limnVtoQN_d[LIMN_QN_MAX+1])(const double *vec);
533 LIMN_EXPORT int limnQNDemo(Nrrd *nqn, unsigned int reso, int qni);
534 
535 /* light.c */
536 LIMN_EXPORT void limnLightSet(limnLight *lit, int which, int vsp,
537                               float r, float g, float b,
538                               float x, float y, float z);
539 LIMN_EXPORT void limnLightAmbientSet(limnLight *lit,
540                                      float r, float g, float b);
541 LIMN_EXPORT void limnLightSwitch(limnLight *lit, int which, int on);
542 LIMN_EXPORT void limnLightReset(limnLight *lit);
543 LIMN_EXPORT int limnLightUpdate(limnLight *lit, limnCamera *cam);
544 
545 /* envmap.c */
546 typedef void (*limnEnvMapCB)(float rgb[3], float vec[3], void *data);
547 LIMN_EXPORT int limnEnvMapFill(Nrrd *envMap, limnEnvMapCB cb,
548                                int qnMethod, void *data);
549 LIMN_EXPORT void limnLightDiffuseCB(float rgb[3], float vec[3], void *_lit);
550 LIMN_EXPORT int limnEnvMapCheck(Nrrd *envMap);
551 
552 /* methodsLimn.c */
553 LIMN_EXPORT limnLight *limnLightNew(void);
554 LIMN_EXPORT void limnCameraInit(limnCamera *cam);
555 LIMN_EXPORT limnLight *limnLightNix(limnLight *);
556 LIMN_EXPORT limnCamera *limnCameraNew(void);
557 LIMN_EXPORT limnCamera *limnCameraNix(limnCamera *cam);
558 LIMN_EXPORT limnWindow *limnWindowNew(int device);
559 LIMN_EXPORT limnWindow *limnWindowNix(limnWindow *win);
560 
561 /* hestLimn.c */
562 LIMN_EXPORT void limnHestCameraOptAdd(hestOpt **hoptP, limnCamera *cam,
563                                       const char *frDef, const char *atDef,
564                                       const char *upDef, const char *dnDef,
565                                       const char *diDef, const char *dfDef,
566                                       const char *urDef, const char *vrDef,
567                                       const char *fvDef);
568 
569 /* cam.c */
570 LIMN_EXPORT int limnCameraAspectSet(limnCamera *cam,
571                                     unsigned int horz, unsigned int vert,
572                                     int centering);
573 LIMN_EXPORT int limnCameraUpdate(limnCamera *cam);
574 LIMN_EXPORT int limnCameraPathMake(limnCamera *cam, int numFrames,
575                                    limnCamera *keycam, double *time,
576                                    int numKeys, int trackFrom,
577                                    limnSplineTypeSpec *quatType,
578                                    limnSplineTypeSpec *posType,
579                                    limnSplineTypeSpec *distType,
580                                    limnSplineTypeSpec *viewType);
581 
582 /* obj.c */
583 LIMN_EXPORT int limnObjectLookAdd(limnObject *obj);
584 LIMN_EXPORT limnObject *limnObjectNew(int incr, int doEdges);
585 LIMN_EXPORT limnObject *limnObjectNix(limnObject *obj);
586 LIMN_EXPORT void limnObjectEmpty(limnObject *obj);
587 LIMN_EXPORT int limnObjectPreSet(limnObject *obj,
588                                  unsigned int partNum,
589                                  unsigned int lookNum,
590                                  unsigned int vertPerPart,
591                                  unsigned int edgePerPart,
592                                  unsigned int facePerPart);
593 LIMN_EXPORT int limnObjectPartAdd(limnObject *obj);
594 LIMN_EXPORT int limnObjectVertexNumPreSet(limnObject *obj,
595                                           unsigned int partIdx,
596                                           unsigned int vertNum);
597 LIMN_EXPORT int limnObjectVertexAdd(limnObject *obj,
598                                     unsigned int partIdx,
599                                     float x, float y, float z);
600 LIMN_EXPORT int limnObjectEdgeAdd(limnObject *obj,
601                                   unsigned int partIdx,
602                                   unsigned int lookIdx,
603                                   unsigned int faceIdx,
604                                   unsigned int vertIdx0,
605                                   unsigned int vertIdx1);
606 LIMN_EXPORT int limnObjectFaceNumPreSet(limnObject *obj,
607                                         unsigned int partIdx,
608                                         unsigned int faceNum);
609 LIMN_EXPORT int limnObjectFaceAdd(limnObject *obj,
610                                   unsigned int partIdx,
611                                   unsigned int lookIdx,
612                                   unsigned int sideNum,
613                                   unsigned int *vertIdx);
614 
615 /* polydata.c */
616 LIMN_EXPORT limnPolyData *limnPolyDataNew(void);
617 LIMN_EXPORT limnPolyData *limnPolyDataNix(limnPolyData *pld);
618 LIMN_EXPORT unsigned int limnPolyDataInfoBitFlag(const limnPolyData *pld);
619 LIMN_EXPORT int limnPolyDataAlloc(limnPolyData *pld,
620                                   unsigned int infoBitFlag,
621                                   unsigned int vertNum,
622                                   unsigned int indxNum,
623                                   unsigned int primNum);
624 LIMN_EXPORT size_t limnPolyDataSize(const limnPolyData *pld);
625 LIMN_EXPORT int limnPolyDataCopy(limnPolyData *pldB, const limnPolyData *pldA);
626 LIMN_EXPORT int limnPolyDataCopyN(limnPolyData *pldB, const limnPolyData *pldA,
627                                   unsigned int num);
628 LIMN_EXPORT void limnPolyDataTransform_f(limnPolyData *pld,
629                                          const float homat[16]);
630 LIMN_EXPORT void limnPolyDataTransform_d(limnPolyData *pld,
631                                          const double homat[16]);
632 LIMN_EXPORT unsigned int limnPolyDataPolygonNumber(const limnPolyData *pld);
633 LIMN_EXPORT int limnPolyDataVertexNormals(limnPolyData *pld);
634 LIMN_EXPORT int limnPolyDataVertexNormalsNO(limnPolyData *pld);
635 LIMN_EXPORT unsigned int limnPolyDataPrimitiveTypes(const limnPolyData *pld);
636 LIMN_EXPORT int limnPolyDataPrimitiveVertexNumber(Nrrd *nout,
637                                                   limnPolyData *pld);
638 LIMN_EXPORT int limnPolyDataPrimitiveArea(Nrrd *nout, limnPolyData *pld);
639 LIMN_EXPORT int limnPolyDataRasterize(Nrrd *nout, limnPolyData *pld,
640                                       double min[3], double max[3],
641                                       size_t size[3], int type);
642 LIMN_EXPORT void limnPolyDataColorSet(limnPolyData *pld,
643                                       unsigned char RR, unsigned char GG,
644                                       unsigned char BB, unsigned char AA);
645 
646 /* polyshapes.c */
647 LIMN_EXPORT int limnPolyDataCube(limnPolyData *pld,
648                                  unsigned int infoBitFlag,
649                                  int sharpEdge);
650 LIMN_EXPORT int limnPolyDataCubeTriangles(limnPolyData *pld,
651                                           unsigned int infoBitFlag,
652                                           int sharpEdge);
653 LIMN_EXPORT int limnPolyDataOctahedron(limnPolyData *pld,
654                                        unsigned int infoBitFlag,
655                                        int sharpEdge);
656 LIMN_EXPORT int limnPolyDataCone(limnPolyData *pld,
657                                  unsigned int infoBitFlag,
658                                  unsigned int res, int sharpEdge);
659 LIMN_EXPORT int limnPolyDataCylinder(limnPolyData *pld,
660                                      unsigned int infoBitFlag,
661                                      unsigned int res, int sharpEdge);
662 LIMN_EXPORT int limnPolyDataSuperquadric(limnPolyData *pld,
663                                          unsigned int infoBitFlag,
664                                          float A, float B,
665                                          unsigned int thetaRes,
666                                          unsigned int phiRes);
667 LIMN_EXPORT int limnPolyDataSpiralBetterquadric(limnPolyData *pld,
668                                                 unsigned int infoBitFlag,
669                                                 float alpha, float beta,
670                                                 float cee, float minRad,
671                                                 unsigned int thetaRes,
672                                                 unsigned int phiRes);
673 LIMN_EXPORT int limnPolyDataSpiralSuperquadric(limnPolyData *pld,
674                                                unsigned int infoBitFlag,
675                                                float A, float B,
676                                                unsigned int thetaRes,
677                                                unsigned int phiRes);
678 LIMN_EXPORT int limnPolyDataPolarSphere(limnPolyData *pld,
679                                         unsigned int infoBitFlag,
680                                         unsigned int thetaRes,
681                                         unsigned int phiRes);
682 LIMN_EXPORT int limnPolyDataSpiralSphere(limnPolyData *pld,
683                                          unsigned int infoBitFlag,
684                                          unsigned int thetaRes,
685                                          unsigned int phiRes);
686 LIMN_EXPORT int limnPolyDataIcoSphere(limnPolyData *pld,
687                                       unsigned int infoBitFlag,
688                                       unsigned int level);
689 LIMN_EXPORT int limnPolyDataPlane(limnPolyData *pld,
690                                   unsigned int infoBitFlag,
691                                   unsigned int uRes, unsigned int vRes);
692 LIMN_EXPORT int limnPolyDataSquare(limnPolyData *pld,
693                                    unsigned int infoBitFlag);
694 
695 /* polymod.c */
696 LIMN_EXPORT int limnPolyDataEdgeHalve(limnPolyData *pldOut,
697                                       const limnPolyData *pldIn);
698 LIMN_EXPORT int limnPolyDataVertexWindingFix(limnPolyData *pld,
699                                              int allowSplitting);
700 LIMN_EXPORT int limnPolyDataClip(limnPolyData *pld, Nrrd *nval, double thresh);
701 LIMN_EXPORT int limnPolyDataClipMulti(limnPolyData *pld, Nrrd *nval,
702                                       double *thresh);
703 LIMN_EXPORT limnPolyData *limnPolyDataCompress(const limnPolyData *pld);
704 LIMN_EXPORT limnPolyData *limnPolyDataJoin(const limnPolyData **plds,
705                                            unsigned int num);
706 LIMN_EXPORT int limnPolyDataVertexWindingFlip(limnPolyData *pld);
707 LIMN_EXPORT int limnPolyDataCCFind(limnPolyData *pld);
708 LIMN_EXPORT int limnPolyDataPrimitiveSort(limnPolyData *pld, const Nrrd *nval);
709 LIMN_EXPORT int limnPolyDataPrimitiveSelect(limnPolyData *pldOut,
710                                             const limnPolyData *pldIn,
711                                             const Nrrd *nmask);
712 LIMN_EXPORT int limnPolyDataNeighborList(unsigned int **nblist, size_t *len,
713                                          unsigned int *maxnb,
714                                          const limnPolyData *pld);
715 LIMN_EXPORT int limnPolyDataNeighborArray(int **neighbors, unsigned int *maxnb,
716                                           const limnPolyData *pld);
717 LIMN_EXPORT int limnPolyDataNeighborArrayComp(int **neighbors, int **idx,
718                                               const limnPolyData *pld);
719 
720 /* polyfilter.c */
721 LIMN_EXPORT int limnPolyDataSpiralTubeWrap(limnPolyData *pldOut,
722                                            const limnPolyData *pldIn,
723                                            unsigned int infoBitFlag,
724                                            Nrrd *nvertMap,
725                                            unsigned int tubeFacet,
726                                            unsigned int endFacet,
727                                            double radius);
728 LIMN_EXPORT int limnPolyDataSmoothHC(limnPolyData *pld, int *neighbors,
729                                      int *idx, double alpha, double beta,
730                                      int iter);
731 /* io.c */
732 LIMN_EXPORT int limnObjectDescribe(FILE *file, const limnObject *obj);
733 LIMN_EXPORT int limnObjectReadOFF(limnObject *obj, FILE *file);
734 LIMN_EXPORT int limnObjectWriteOFF(FILE *file, const limnObject *obj);
735 LIMN_EXPORT int limnPolyDataWriteIV(FILE *file, const limnPolyData *pld);
736 LIMN_EXPORT int limnPolyDataWriteLMPD(FILE *file, const limnPolyData *pld);
737 LIMN_EXPORT int limnPolyDataReadLMPD(limnPolyData *pld, FILE *file);
738 LIMN_EXPORT int limnPolyDataWriteVTK(FILE *file, const limnPolyData *pld);
739 LIMN_EXPORT int limnPolyDataReadOFF(limnPolyData *pld, FILE *file);
740 LIMN_EXPORT int limnPolyDataSave(const char *fname, const limnPolyData *lpld);
741 LIMN_EXPORT hestCB *limnHestPolyDataLMPD;
742 LIMN_EXPORT hestCB *limnHestPolyDataOFF;
743 
744 /* shapes.c */
745 LIMN_EXPORT int limnObjectCubeAdd(limnObject *obj, unsigned int lookIdx);
746 LIMN_EXPORT int limnObjectSquareAdd(limnObject *obj, unsigned int lookIdx);
747 LIMN_EXPORT int limnObjectCylinderAdd(limnObject *obj, unsigned int lookIdx,
748                                       unsigned int axis, unsigned int res);
749 LIMN_EXPORT int limnObjectPolarSphereAdd(limnObject *obj, unsigned int lookIdx,
750                                          unsigned int axis,
751                                          unsigned int thetaRes,
752                                          unsigned int phiRes);
753 LIMN_EXPORT int limnObjectConeAdd(limnObject *obj, unsigned int lookIdx,
754                                   unsigned int axis, unsigned int res);
755 LIMN_EXPORT int limnObjectPolarSuperquadAdd(limnObject *obj,
756                                             unsigned int lookIdx,
757                                             unsigned int axis,
758                                             float A, float B,
759                                             unsigned int thetaRes,
760                                             unsigned int phiRes);
761 LIMN_EXPORT int limnObjectPolarSuperquadFancyAdd(limnObject *obj,
762                                                  unsigned int lookIdx,
763                                                  unsigned int axis,
764                                                  float A, float B,
765                                                  float C, float R,
766                                                  unsigned int thetaRes,
767                                                  unsigned int phiRes);
768 
769 /* transform.c */
770 LIMN_EXPORT int limnObjectWorldHomog(limnObject *obj);
771 LIMN_EXPORT int limnObjectFaceNormals(limnObject *obj, int space);
772 LIMN_EXPORT int limnObjectVertexNormals(limnObject *obj);
773 LIMN_EXPORT int limnObjectSpaceTransform(limnObject *obj, limnCamera *cam,
774                                          limnWindow *win, int space);
775 LIMN_EXPORT int limnObjectPartTransform(limnObject *obj, unsigned int partIdx,
776                                         float tx[16]);
777 LIMN_EXPORT int limnObjectDepthSortParts(limnObject *obj);
778 LIMN_EXPORT int limnObjectDepthSortFaces(limnObject *obj);
779 LIMN_EXPORT int limnObjectFaceReverse(limnObject *obj);
780 
781 /* renderLimn.c */
782 LIMN_EXPORT int limnObjectRender(limnObject *obj, limnCamera *cam,
783                                  limnWindow *win);
784 LIMN_EXPORT int limnObjectPSDraw(limnObject *obj, limnCamera *cam,
785                                  Nrrd *envMap, limnWindow *win);
786 LIMN_EXPORT int limnObjectPSDrawConcave(limnObject *obj, limnCamera *cam,
787                                         Nrrd *envMap, limnWindow *win);
788 
789 /* splineMethods.c */
790 LIMN_EXPORT limnSplineTypeSpec *limnSplineTypeSpecNew(int type, ...);
791 LIMN_EXPORT limnSplineTypeSpec *
792   limnSplineTypeSpecNix(limnSplineTypeSpec *spec);
793 LIMN_EXPORT limnSpline *limnSplineNew(Nrrd *ncpt, int info,
794                                       limnSplineTypeSpec *spec);
795 LIMN_EXPORT limnSpline *limnSplineNix(limnSpline *spline);
796 LIMN_EXPORT int limnSplineNrrdCleverFix(Nrrd *nout, Nrrd *nin,
797                                         int info, int type);
798 LIMN_EXPORT limnSpline *limnSplineCleverNew(Nrrd *ncpt, int info,
799                                             limnSplineTypeSpec *spec);
800 LIMN_EXPORT int limnSplineUpdate(limnSpline *spline, Nrrd *ncpt);
801 
802 /* splineMisc.c */
803 LIMN_EXPORT const airEnum *const limnSplineType;
804 LIMN_EXPORT const airEnum *const limnSplineInfo;
805 LIMN_EXPORT limnSpline *limnSplineParse(char *str);
806 LIMN_EXPORT limnSplineTypeSpec *limnSplineTypeSpecParse(char *str);
807 LIMN_EXPORT hestCB *limnHestSpline;
808 LIMN_EXPORT hestCB *limnHestSplineTypeSpec;
809 LIMN_EXPORT unsigned int limnSplineInfoSize[LIMN_SPLINE_INFO_MAX+1];
810 LIMN_EXPORT int limnSplineTypeHasImplicitTangents[LIMN_SPLINE_TYPE_MAX+1];
811 LIMN_EXPORT int limnSplineNumPoints(limnSpline *spline);
812 LIMN_EXPORT double limnSplineMinT(limnSpline *spline);
813 LIMN_EXPORT double limnSplineMaxT(limnSpline *spline);
814 LIMN_EXPORT void limnSplineBCSet(limnSpline *spline, double B, double C);
815 
816 /* splineEval.c */
817 LIMN_EXPORT void limnSplineEvaluate(double *out,
818                                     limnSpline *spline, double time);
819 LIMN_EXPORT int limnSplineNrrdEvaluate(Nrrd *nout,
820                                        limnSpline *spline, Nrrd *nin);
821 LIMN_EXPORT int limnSplineSample(Nrrd *nout, limnSpline *spline,
822                                  double minT, size_t M, double maxT);
823 
824 /* lpu{Flotsam,. . .}.c */
825 #define LIMN_DECLARE(C) LIMN_EXPORT unrrduCmd limnpu_##C##Cmd;
826 #define LIMN_LIST(C) &limnpu_##C##Cmd,
827 /* F(clip) \ */
828 /* F(vwflip) \ */
829 /* F(vwfix) */
830 #define LIMN_MAP(F) \
831 F(about) \
832 F(ccfind) \
833 F(psel) \
834 F(rast) \
835 F(verts) \
836 F(meas) \
837 F(sort)
838 LIMN_MAP(LIMN_DECLARE)
839 LIMN_EXPORT unrrduCmd *limnpuCmdList[];
840 LIMN_EXPORT void limnpuUsage(char *me, hestParm *hparm);
841 
842 #ifdef __cplusplus
843 }
844 #endif
845 
846 #endif /* LIMN_HAS_BEEN_INCLUDED */
847