#ifndef SPECKS_H #define SPECKS_H /* * Brains of partiview: core functions and data. * Stuart Levy, slevy@ncsa.uiuc.edu * National Center for Supercomputing Applications, * University of Illinois 2001. * This file is part of partiview, released under the * Illinois Open Source License; see the file LICENSE.partiview for details. */ #ifdef __cplusplus extern "C" { #endif #ifdef __APPLE__ #include <OpenGL/gl.h> #else #include <GL/gl.h> /* for GLuint */ #endif #ifndef CONST # ifdef __cplusplus # define CONST const # else # define CONST # endif #endif #include "geometry.h" #include "textures.h" #include "sclock.h" #include <stdio.h> #define MAXVAL 29 #define CONSTVAL MAXVAL struct stuff; struct speck { Point p; int rgba; float size; float val[MAXVAL]; /* other data values, from which we determine size/threshold/etc. */ char title[28]; }; #define SMALLSPECKSIZE(maxval) ( (char *)&(((struct speck *)0)->val[maxval]) - (char *)0 ) #define SPECKMAXVAL(sl) ( (float *)(((char *)0) + sl->bytesperspeck) - (float *)0 ) #define NewNSpeck(sl, nspecks) ( (struct speck *)NewN( char, (sl)->bytesperspeck*nspecks ) ) #define NextSpeck(sp, sl, skip) ( (struct speck *) (((char *)sp) + (skip)*(sl)->bytesperspeck ) ) enum Lop { L_LIN, L_ABS, L_LOG, L_EXP, L_POW }; struct valdesc { float min, mean, max, sum; int nsamples; /* over which mean is computed */ float cmin, cmax; /* range actually used for coloring (may differ from min..max) */ float lmin, lmax; /* range actually used for sizing (lum) */ int cexact; /* "use exact (unscaled) value as colortable index" */ int call; /* "use entire color range for color" */ int lall; /* "use entire data range for lum" */ float lum; /* luminosity scale factor */ enum Lop lop; /* L_LIN, L_ABS, L_LOG, L_EXP, L_POW */ float lbase, lexp; /* L_ABS: |v|+lbase; L_LOG: log(v/lbase + lexp); */ /* L_EXP: pow(lexp, v/lbase); L_POW: pow(v/lbase, lexp) */ char name[20]; struct cment *vcmap; /* per-data-variable colormap (may be NULL); rgba format */ int vncmap; /* number of entries in cmap */ }; struct cment { int raw; int cooked; }; struct AMRbox { Point p0, p1; /* opposite corners of box */ int level; int boxno; }; enum SurfStyle { S_SOLID, S_LINE, S_PLANE, S_POINT, S_HALO, S_OFF }; enum MeshType { QUADMESH, POLYMESH, MODEL }; struct mesh { struct mesh *next; enum MeshType type; enum SurfStyle style; void *wavobj; /* class WavObj, used iff type == MODEL */ void (*objrender)(struct stuff *,struct mesh *); /* draw func, if not built-in */ int cindex; /* colormap index, or -1 for white */ int txno; /* texture index, or -1 if none */ int levelno; /* level number, for show/hide selection */ int nu, nv; /* for QUADMESH type */ int nfaces; /* face count */ int nfv; /* number of face-vertices (sum of abs(fvn[i])) */ int nverts; /* size of pts array, = nu*nv for QUADMESHes */ int ntx; /* size of tx array */ int nvnorms; /* size of vnorms array */ int *fvn; /* fvn[nfaces] verts on this face (neg for tstrips) */ int *fv0; /* fv0[nfaces] starting index in fvs[] */ int *fvs; /* fvs[nfv] face vertex indices, each 0..nverts-1 */ #define FVSTEP 3 #define FVS_VERT 0 #define FVS_TX 1 #define FVS_VNORM 2 Point *pts; /* pts[nverts] vertex coords */ Point *tx; /* tx[ntx] texture coords, or NULL if absent */ Point *vnorms; /* vnorms[nvnorms] vertex normals, or NULL */ Point *fnorms; /* fnorms[nfnorms] facet normals, or NULL if absent */ Point *fcolors; /* fcolors[nfaces] RGB colors stored in Point's, or NULL if absent */ float haloth; /* halo threshold */ }; struct ellipsoid { struct ellipsoid *next; int nu, nv; enum SurfStyle style; int cindex; int level; Point pos; Point size; int hasori; Matrix ori; char *title; }; enum SpecialSpeck { SPECKS=0, POLYLINES, TMESHES, MARKERS, ELLIPSOIDS }; #define MAXSELNAME 16 struct selitem { char name[MAXSELNAME]; }; typedef unsigned int SelMask; enum SelUse { SEL_NONE, /* disabled */ SEL_USE, /* evaluate given function */ SEL_DEST }; typedef struct _selfunc { SelMask wanted; /* mask of interesting bits, either on or off */ SelMask wanton; /* mask of bits which are interesting if on */ enum SelUse use; } SelOp; /* * Selection scheme is: * User specifies a set of bit-numbers, like * 3 -5 7 -10 * which refers to all specks with attributes 3 or 7 on, AND attributes 5 and 10 off. * To compute this, consider two masks: * wanton = (1<<3) | (1<<7) * wantoff = (1<<5) | (1<<10) * Then construct * wanted = (wanton | wantoff) * Now the speck with attribute-mask "attributes" is selected iff * (attributes ^ wanton) & (wanton | wantoff) == 0 */ #define SELECTED(attrs, selp) (0==( ((attrs)^(selp)->wanton) & (selp)->wanted)) #define SELBYDEST(attrs, selp) (0==( ((attrs)^(selp)->wanton) & ~(selp)->wanted)) #define SELSET(attrs, selp) ((attrs) = ((attrs)&(selp)->wanted) ^ (selp)->wanton) #define SELUNSET(attrs, selp) ((attrs) = ((attrs)|~(selp)->wanted) ^ (selp)->wanton) /* SET: want=1 => attrs' = attrs ^ wanton * want=0 => attrs' = wanton * UNSET: want=1 => attrs' = attrs ^ wanton * want=0 => attrs' = ~wanton */ #define SELMASK(bitno) (((SelMask)1) << ((bitno)-1)) struct specklist { struct specklist *next; int nspecks; int bytesperspeck; /* allow for shortened specks */ struct speck *specks; float scaledby; int coloredby; /* val[] index used for colormapping */ int sizedby; /* val[] index used for sizing */ int colorseq, sizeseq, threshseq; Point center, radius; /* of bounding box, after scaling to world space */ Point interest; /* point-of-interest, if any */ char *text; int subsampled; /* subsampling ("every") factor applied already */ int used; /* "used" clock, for mem purges */ int speckseq; /* sequence number, for tracking derived specklists */ int nsel; unsigned int *sel; /* selection bitmasks per particle */ int selseq; enum SpecialSpeck special; struct specklist *freelink; /* link on free/scrap list */ }; struct specktree { /* Not used yet, if ever */ struct specklist self; struct specklist *kid[8]; }; struct coordsys { char name[16]; Matrix w2coord; }; struct wfframe { float tx, ty, tz; float rx, ry, rz; float fovy; }; struct wfpath { struct wfpath *next; int nframes, frame0; int curframe; float fps; /* frames per second */ struct wfframe *frames; float *focallens; }; enum FadeType { F_SPHERICAL, F_PLANAR, F_CONSTANT, F_LINEAR, F_LREGION, F_KNEE2, F_KNEE12 }; typedef struct dyndata { int enabled; int slvalid; void *data; int (*ctlcmd)( struct dyndata *, struct stuff *, int argc, char **argv ); int (*trange)( struct dyndata *, struct stuff *, double *tminp, double *tmaxp ); struct specklist *(*getspecks)( struct dyndata *, struct stuff *, double realtimestep ); int (*draw)( struct dyndata *, struct stuff *, struct specklist *head, Matrix *Tc2w, float radperpix ); int (*help)( struct dyndata *, struct stuff *, int verbose ); void (*free)( struct dyndata *, struct stuff * ); } DynData; typedef int (*SpecksPickFunc)( struct stuff *, GLuint *hit, struct specklist *, int speckno ); #define MAXFILES 8 struct stuff { struct specklist *sl; /* Current display = anima[curdata][curtime] */ struct specklist **anima[MAXFILES]; /* anima[ndata][ntimes]: All data */ char dataname[MAXFILES][12]; int ntimes, ndata; int timeroom; /* number of slots allocated for: * anima[0..ndata-1][0..timeroom-1] * datafile[0..ndata-1][0..timeroom-1] */ int curtime, curdata; double currealtime; SClock *clk; /* provider of time */ int datatime; /* timestep at which to add newly-read specks */ int datasync; /* read .raw data synchronously? */ /* Clones of sl, curtime, curdata, snapped once per frame for consistency */ /* If st->dyndata, * then specks_set_timestep(st, time) * calls (*st->dyndatafunc)(st, time) to find new st->sl. * st->dyndatadata can hold an opaque pointer used by dyndatafunc. */ DynData dyn; #ifdef USE_CONSTE /* modified by T.Takahei */ int conste; void *constedata; #endif struct specklist *frame_sl; int frame_time, frame_data; struct specklist **annot[MAXFILES]; /* annotation strings */ void **datafile[MAXFILES]; /* datafile[ndata][ntimes] -- open-file handles for each dataset */ int datatimes[MAXFILES]; /* number of timesteps for each dataset */ char **fname[MAXFILES]; #define CURDATATIME(field) (((unsigned int)st->curtime < st->ntimes) ? st->field[st->curdata][st->curtime] : NULL) struct valdesc vdesc[MAXFILES][MAXVAL+1]; char *annotation; /* annotation string */ char *frame_annotation; /* ... snapped for current frame */ char *alias; /* alt name for this object besides g<N> */ int ntextures; /* extensible array of Textures */ Texture **textures; Matrix objTo2w; /* object-to-world transform, used in cave only so far */ float spacescale; int sizedby, coloredby; int sizeseq, colorseq; int usesee; SelOp seesel; /* bitmask of desired features in sl->sel[] */ int selseq; /* sel[] change sequence number */ SpecksPickFunc picked; void *pickinfo; int trueradius; char *sdbvars; int maxcomment; struct coordsys altcoord[1]; float speed; /* time steps per CAT_time second */ float fspeed; /* time steps per CAVETime second */ int skipblanktimes; /* skip time-slots with nothing in them */ double time0; /* base timestep, added to time*speed */ int timeplay; int timefwd; int timestepping; double timedelta; /* default delta timestep amount */ float playnext; /* time at which we take our next step. * (= CAVETime of last step plus 1/fspeed, * if in timeplay mode). */ int hidemenu; float menudemandfps; /* If frame rate < demanded then hide scene */ float alpha; float gamma; /* to compensate for display gamma */ int fast; int fog; /* unused */ float pfaint, plarge; /* min/max point brightness */ float polymin; /* min size (pixels) to render polygons */ float polymax; /* max size (pixels) to render polygons */ float polyfademax; /* if polymin < size < polyfademax, then fade */ float psize; float polysize; float textmin; /* min height (pixels) to render labels */ float textsize; int useme; /* global enable/disable display flag */ int usepoly; int polysizevar; int polyarea; /* scale polygon area with data? else radius */ int polyorivar0; int usepoint; int usetext; int usetextaxes; int usetextures; int useblobs; float txscale; int texturevar; float fogscale; int npolygon; enum FadeType fade; float fadeknee1, fadeknee2; /* near and far distance knees in fade curve */ float knee2steep; /* steepness of far knee */ Point fadecen; #define P_THRESHMIN 0x1 #define P_THRESHMAX 0x2 #define P_USETHRESH 0x4 /* supplanted by "see thresh" */ SelOp threshsel; int usethresh; /* bit-encoded */ int threshvar; /* datavar index to threshold on */ float thresh[2]; /* data range */ int threshseq; #define SEL_OFF 34 #define SEL_ALL 33 #define SEL_THRESH 32 #define SEL_PICK 31 /*XXX shouldn't be hard-wired!*/ int useemph; SelOp emphsel; float emphfactor; /* increase lum by this factor */ #define MAXSEL 30 struct selitem selitems[MAXSEL]; int inpick; float gscale; Point gtrans; int useboxes; int boxtimes; int boxlevels; int boxlevelmask; int boxlabels; int boxaxes; float boxlabelscale; float boxlinewidth; float goboxscale; #define MAXBOXLEV 28 float boxscale[MAXBOXLEV]; struct AMRbox **boxes; /* An array per time step */ int staticboxroom; struct AMRbox *staticboxes; /* another array of permanent boxes */ int usemeshes; struct mesh *staticmeshes; struct mesh **meshes[MAXFILES]; /* meshes[curdata][curtime] list of meshes */ float mullions; int useellipsoids; struct ellipsoid *staticellipsoids; char vdcmd[128]; int subsample; /* show every Nth data point */ int everycomp; /* compensate for subsampling by brightening? */ struct cment *cmap; /* rgba format */ int ncmap; /* number of entries in cmap, 1..256 (> 0) */ struct cment *boxcmap; int boxncmap; struct cment *textcmap; int textncmap; struct AMRbox clipbox; /* clipping region. clipbox.level > 0 if active. */ int depthsort; /* sort particles by camera distance? */ int fetchpid; volatile int fetching; /* busy fetching data in subprocess (don't start another fetch) */ volatile int fetchdata, fetchtime; /* data and timestep being fetched */ int used; /* global "used" clock, for LRU purging */ struct specklist *scrap; /* stuff to be deleted when it's safe */ int nghosts; /* keep recent ghost snapshots of dynamic data */ int usertrange; double utmin, utmax, utwrap; /* user-supplied time range */ int speckseq; /* sequence-number seed */ /* rgb565 colormaps & parameters */ float rgbright[3], rgbgamma[3]; unsigned char rgbmap[3][256]; /* chromadepth stuff */ int use_chromadepth; float chromaslidestart, chromaslidelength; int nchromacm; struct cment *chromacm; }; /* * some globals for collaborating with Matt's AMR code. * We need to publicize where our menu lies. */ extern int parti_menuwall; extern int parti_menubox[4]; /* xmin,ymin, xmax,ymax (pixels) * with 0,0 at LOWER LEFT */ extern int parti_datastep; extern int vtkamr_datastep, vtkamr_datastep_ready; extern void specks_display( struct stuff *st ); extern struct stuff *specks_init( int argc, char *argv[] ); extern void specks_read( struct stuff **stp, char *fname ); extern struct specklist *specks_ieee_read_timestep( struct stuff *st, int subsample, int dataset, int timestep ); extern void specks_ieee_open( struct stuff *st, char *fname, int dataset, int starttime ); extern void drawspecks( struct stuff *st ); int specks_partial_pick_decode( struct stuff *st, int id, int nhits, int nents, GLuint *hitbuf, unsigned int *bestzp, struct specklist **slp, int *speckno, Point *pos ); extern int specks_parse_args( struct stuff **, int cat_argc, char *cat_argv[] ); extern void specks_set_time( struct stuff *, double newtime ); extern void specks_set_timestep( struct stuff * ); /*...from current time*/ extern int specks_get_datastep( struct stuff * ); extern void specks_set_speed( struct stuff *, double newspeed ); extern void specks_set_timebase( struct stuff *, double newbase ); extern void specks_discard( struct stuff *, struct specklist **slist ); /* Free later */ extern int specks_check_async( struct stuff ** ); extern int specks_add_async( struct stuff *st, char *cmdstr, int replytoo ); extern void specks_set_annotation( struct stuff *, CONST char *str ); extern void specks_current_frame( struct stuff *, struct specklist *sl ); extern void specks_reupdate( struct stuff *, struct specklist *sl ); extern void specks_datawait( struct stuff * ); extern struct specklist * specks_timespecks( struct stuff *, int dataset, int timestep ); extern struct specklist **specks_timespecksptr( struct stuff *, int dataset, int timestep ); extern float display_time(void); extern char *rejoinargs( int arg0, int argc, char **argv ); extern double getfloat( char *str, double defval ); extern int getbool( char *str, int what ); extern int specks_set_byvariable( struct stuff *st, char *str, int *val ); extern int parse_selexpr( struct stuff *, char *str, SelOp *dest, SelOp *src, char *plaint ); extern char *show_selexpr( struct stuff *, SelOp *dest, SelOp *src ); extern void selinit( SelOp * ); extern void selsrc2dest( struct stuff *, CONST SelOp *src, SelOp *dest ); extern void seldest2src( struct stuff *, CONST SelOp *dest, SelOp *src ); CONST char *selcounts( struct stuff *st, struct specklist *sl, SelOp *selp ); extern SpecksPickFunc specks_all_picks( struct stuff *, SpecksPickFunc func, void *arg ); #ifdef __cplusplus } #endif #endif /*SPECKS_H*/