Update of /cvsroot/teem/teem/src/mite In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29720 Modified Files: GNUmakefile defaultsMite.c mite.h privateMite.h ray.c renderMite.c thread.c txf.c user.c Log Message: in the midst of massive re-organizaztion; ignore Index: GNUmakefile =================================================================== RCS file: /cvsroot/teem/teem/src/mite/GNUmakefile,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** GNUmakefile 7 Jan 2004 15:34:30 -0000 1.14 --- GNUmakefile 13 Feb 2004 22:58:40 -0000 1.15 *************** *** 44,51 **** #### (ell for macros) #### ! $(L).NEED = hoover limn gage ell nrrd biff air $(L).PUBLIC_HEADERS = mite.h $(L).PRIVATE_HEADERS = privateMite.h ! $(L).OBJS = defaultsMite.o user.o txf.o renderMite.o thread.o ray.o #### #### --- 44,51 ---- #### (ell for macros) #### ! $(L).NEED = ten hoover limn gage ell nrrd biff air $(L).PUBLIC_HEADERS = mite.h $(L).PRIVATE_HEADERS = privateMite.h ! $(L).OBJS = defaultsMite.o kindnot.o renderMite.o thread.o ray.o txf.o user.o #### #### Index: defaultsMite.c =================================================================== RCS file: /cvsroot/teem/teem/src/mite/defaultsMite.c,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** defaultsMite.c 7 Jan 2004 15:34:30 -0000 1.6 --- defaultsMite.c 13 Feb 2004 22:58:40 -0000 1.7 *************** *** 34,36 **** double ! miteDefNear1 = 0.99; --- 34,39 ---- double ! miteDefOpacNear1 = 0.98; ! ! double ! miteDefOpacMatters = 0.05; Index: mite.h =================================================================== RCS file: /cvsroot/teem/teem/src/mite/mite.h,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -d -r1.24 -r1.25 *** mite.h 7 Jan 2004 15:34:30 -0000 1.24 --- mite.h 13 Feb 2004 22:58:40 -0000 1.25 *************** *** 28,31 **** --- 28,32 ---- #include <teem/limn.h> #include <teem/hoover.h> + #include <teem/ten.h> #if defined(_WIN32) && !defined(TEEM_STATIC) && !defined(__CYGWIN__) *************** *** 43,60 **** /* ******** mite_t ! ** */ ! ! /* typedef float mite_t; #define mite_nt nrrdTypeFloat #define mite_at airTypeFloat ! */ ! typedef double mite_t; #define mite_nt nrrdTypeDouble #define mite_at airTypeDouble ! enum { --- 44,67 ---- /* ******** mite_t ! ** ! ** the type used for representing and storing transfer function *range* ! ** (color, opacity, etc) information is: ! ** 1: float ! ** 0: double */ ! #if 0 typedef float mite_t; #define mite_nt nrrdTypeFloat #define mite_at airTypeFloat ! #define limnVTOQN limnVtoQN_f ! #define MITE_T_DOUBLE 0 ! #else typedef double mite_t; #define mite_nt nrrdTypeDouble #define mite_at airTypeDouble ! #define limnVTOQN limnVtoQN_d ! #define MITE_T_DOUBLE 1 ! #endif enum { *************** *** 98,112 **** ** unlike gage, there is no API for setting these- you go in the ** struct and set them yourself. */ typedef struct { ! Nrrd *nin, /* volume being rendered */ **ntxf, /* array of nrrds containing transfer functions, these are never altered (in contrast to ntxf in miteRender) */ ! *nout; /* output image container: we'll nrrdMaybeAlloc all ! the image data and put it in here, but we won't ! nrrdNuke(nout), just like we won't nrrdNuke ! nin or any of the ntxf[i] */ int ntxfNum; /* allocated and valid length of ntxf[] */ /* for each possible element of the txf range, what value should it start at prior to multiplying by the values (if any) learned from --- 105,129 ---- ** unlike gage, there is no API for setting these- you go in the ** struct and set them yourself. + ** + ** Mite can currently handle scalar, 3-vector, and (symmetric) tensor + ** volumes, one (at most) of each. All these volumes must have the + ** same 3-D size, because we're only using one gageContext per thread, + ** and the gageContext is what stores the convolution kernel weights + ** evaluated per sample. */ typedef struct { ! Nrrd *nsin, /* scalar volume being rendered */ ! *nvin, /* 3-vector volume being rendered */ ! *ntin, /* tensor volume being rendered */ **ntxf, /* array of nrrds containing transfer functions, these are never altered (in contrast to ntxf in miteRender) */ ! *nout; /* output image container, for five-channel output ! RGBAZ. We'll nrrdMaybeAlloc all the image data ! and put it in here, but we won't nrrdNuke(nout), ! just like we won't nrrdNuke nsin, ntin, or any of ! the ntxf[i] */ int ntxfNum; /* allocated and valid length of ntxf[] */ + char shadeStr[AIR_STRLEN_MED]; /* how to do shading */ /* for each possible element of the txf range, what value should it start at prior to multiplying by the values (if any) learned from *************** *** 116,121 **** double refStep, /* length of "unity" for doing opacity correction */ rayStep, /* distance between sampling planes */ ! near1; /* close enough to unity for the sake of doing early ! ray termination when opacity gets high */ hooverContext *hctx; /* context and input for all hoover-related things, including camera and image parameters */ --- 133,141 ---- double refStep, /* length of "unity" for doing opacity correction */ rayStep, /* distance between sampling planes */ ! opacMatters, /* minimal significant opacity, currently used to ! assign a Z depth (really "Tw") for each rendered ! ray */ ! opacNear1; /* opacity close enough to unity for the sake of ! doing early ray termination */ hooverContext *hctx; /* context and input for all hoover-related things, including camera and image parameters */ *************** *** 125,129 **** including all kernels. This is gageContextCopy'd for multi-threaded use (hence the 0) */ ! limnLight *lit; /* a struct for all lighting info */ int normalSide, /* determines direction of gradient that is used as normal for shading: --- 145,151 ---- including all kernels. This is gageContextCopy'd for multi-threaded use (hence the 0) */ ! limnLight *lit; /* a struct for all lighting info, although ! currently only the ambient and *first* directional ! light are used */ int normalSide, /* determines direction of gradient that is used as normal for shading: *************** *** 133,139 **** -1: normal points to higher values (lower values more "inside") */ ! justSum, /* don't use opacity: just sum colors */ ! noDirLight; /* forget directional phong lighting, using only ! the ambient component */ airArray *umop; /* for things allocated which are used across multiple renderings */ --- 155,159 ---- -1: normal points to higher values (lower values more "inside") */ ! verbUi, verbVi; /* pixel coordinate for which to turn on verbosity */ airArray *umop; /* for things allocated which are used across multiple renderings */ *************** *** 146,160 **** /* ******** miteRender ** ! ** rendering-parameter-set-specific, but non-thread-specific, ! ** state relevant for mite's internal use */ typedef struct { ! Nrrd **ntxf; /* array of transfer function nrrds. The only difference from those in miteUser is that ! opacity correction has been applied to ! these */ int ntxfNum; /* allocated and valid length of ntxf[] */ double time0; /* rendering start time */ --- 166,217 ---- /* + ******** miteShadeMethod* enum + ** + ** the different ways that shading can be done + */ + enum { + miteShadeMethodUnknown, + miteShadeMethodNone, /* 1: no direction shading based on anything + in the miteShadeSpec: just ambient + (though still using over operator) */ + miteShadeMethodPhong, /* 2: what mite has been doing all along */ + miteShadeMethodLitTen, /* 3: (tensor-based) lit-tensors */ + miteShadeMethodLast + }; + + /* + ******** miteShadeSpec struct + ** + ** describes how to do shading. With more and more generality in the + ** expressions that are evaluated for transfer function application, + ** there is less need for this "shading" per se (phong shading can be + ** expressed with multiplicative and additive transfer functions). + ** But its here for the time being... + */ + typedef struct { + int shadeMethod; /* from miteShadeMethod* enum */ + gageQuerySpec *vec0, *vec1, + *scl0, *scl1; /* things to use for shading. How these are + interpreted is determined by shadeMethod: + phong: vec0 is used as normal + litten: lit-tensors based on vec0 and vec1, + as weighted by scl0, scl1 */ + } miteShadeSpec; + + /* ******** miteRender ** ! ** rendering-parameter-set-specific (but non-thread-specific) state, ! ** used internally by mite */ typedef struct { ! Nrrd **ntxf; /* array of transfer function nrrds. The difference from those in miteUser is that ! opacity correction (based on rayStep and ! refStep) has been applied to these, and ! these have been converted/unquantized to ! type mite_t */ int ntxfNum; /* allocated and valid length of ntxf[] */ + miteShadeSpec *shpec; /* information based on muu->shadeStr */ double time0; /* rendering start time */ *************** *** 168,174 **** } miteRender; typedef struct { ! gage_t *val; /* the gage-measured txf axis variable */ ! int size; /* number of entries */ double min, max; /* min, max (copied from nrrd axis) */ mite_t *data; /* pointer to txf data. If non-NULL, the --- 225,256 ---- } miteRender; + /* + ******** miteStageOp* enum + ** + ** the kinds of things we can do per txf to modify the range variables. + ** previously mite only supported seperable transfer functions (i.e., + ** multiplication only) + */ + enum { + miteStageOpUnknown, + miteStageOpAdd, + miteStageOpMax, + miteStageOpMultiply, + miteStageOpLast + }; + typedef struct { ! gage_t *val; /* the txf axis variable, computed either by ! gage or by mite. This points into the ! answer vector in one of the thread's ! pervolumes */ ! int size, /* number of entries along this txf axis */ ! op, /* from miteStageOp* enum. Note that this ! operation applies to ALL the range variables ! adjusted by this txf (can't add color while ! multiplying opacity) */ ! (*qn)(gage_t *); /* callback for doing vector quantization of ! vector-valued txf domain variables, or ! NULL if this is a scalar variable */ double min, max; /* min, max (copied from nrrd axis) */ mite_t *data; /* pointer to txf data. If non-NULL, the *************** *** 180,208 **** /* ! ******** miteScl* enum ** ! ** the quantities not measured by gage which can appear in the ! ** transfer function domain. All of these are cheap to compute, ! ** so all of them are saved/computed per sample, and stored in ! ** the miteThread */ enum { ! miteSclUnknown=-1, /* -1: nobody knows */ ! miteSclXw, /* 0: "Xw", X position, world space */ ! miteSclXi, /* 1: "Xi", X " , index " */ ! miteSclYw, /* 2: "Yw", Y " , world " */ ! miteSclYi, /* 3: "Yi", Y " , index " */ ! miteSclZw, /* 4: "Zw", Z " , world " */ ! miteSclZi, /* 5: "Zi", Z " , index " */ ! miteSclTw, /* 6: "Tw", ray position */ ! miteSclTi, /* 7: "Ti", ray index (ray sample #) */ ! miteSclNdotV, /* 8: "NdotV", surface normal dotted w/ view vector ! (towards eye) */ ! miteSclNdotL, /* 9: "NdotL", surface normal dotted w/ light vector ! (towards the light source) */ ! miteSclGTdotV, /* 10: "GTdotV", normal curvature in view direction */ ! miteSclLast }; ! #define MITE_SCL_MAX 10 /* --- 262,301 ---- /* ! ******** miteVal* enum ** ! ** the quantities not measured by gage (but often reliant on gage-based ! ** measurements) which can appear in the transfer function domain. ! ** In many respects, these behave like gage queries, and these are ! ** associated with a gageKind (miteValGageKind), but it is hardly a ! ** real, bona fide, gageKind. The answers for these are stored in ! ** the miteThread, in lieu of a gagePerVolume */ enum { ! miteValUnknown=-1, /* -1: nobody knows */ ! miteValXw, /* 0: "Xw", X position, world space (*gage_t) */ ! miteValXi, /* 1: "Xi", X " , index " (*gage_t) */ ! miteValYw, /* 2: "Yw", Y " , world " (*gage_t) */ ! miteValYi, /* 3: "Yi", Y " , index " (*gage_t) */ ! miteValZw, /* 4: "Zw", Z " , world " (*gage_t) */ ! miteValZi, /* 5: "Zi", Z " , index " (*gage_t) */ ! miteValTw, /* 6: "Tw", ray position (*gage_t) */ ! miteValTi, /* 7: "Ti", ray index (ray sample #) (*gage_t) */ ! miteValNdotV, /* 8: "NdotV", surface normal dotted w/ view vector ! (towards eye) (*gage_t) */ ! miteValNdotL, /* 9: "NdotL", surface normal dotted w/ light vector ! (towards the light source) (*gage_t) */ ! miteValGTdotV, /* 10: "GTdotV", normal curvature in view direction ! (*gage_t) */ ! miteValVrefN, /* 11: "VrefN", view vector (towards eye) reflected ! across surface normal (gage_t[3]) */ ! miteValVdefT, /* 12: "VdefT", view direction, deflected by tensor, ! then normalized (gage_t[3]) */ ! miteValVdefTdotV, /* 13: "VdefTdotV", VdefT dotted back with V, not the ! same as the tensor contraction along V, ! (*gage_t) */ ! miteValLast }; ! #define MITE_VAL_MAX 13 ! #define MITE_VAL_TOTAL_ANS_LENGTH 18 /* *************** *** 213,226 **** typedef struct miteThread_t { gageContext *gctx; /* per-thread context */ ! gage_t *ans, /* shortcut to gctx->pvl[0]->ans */ ! *norm, /* shortcut to ans[gageSclNormal] */ ! *nPerp, /* shortcut to ans[gageSclNPerp] */ ! *gten, /* shortcut to ans[gageSclGeomTens] */ ! mscl[MITE_SCL_MAX+1]; /* all the miteScl */ int verbose, /* blah blah blah */ thrid, /* thread ID */ ui, vi, /* image coords */ ! samples; /* number of samples handled so far ! by this thread */ miteStage *stage; /* array of stages for txf computation */ int stageNum; /* number of stages == length of stage[] */ --- 306,320 ---- typedef struct miteThread_t { gageContext *gctx; /* per-thread context */ ! gage_t *ansScl, /* shortcut to scalar answer vector */ ! *ansVec, /* shortcut to vector answer vector */ ! *ansTen, /* shortcut to tensor answer vector */ ! *vec0, *vec1, *scl0, *scl1, /* shortcuts vectors/scalars used for ! shading; explained with miteShadeSpec */ ! ansMiteVal[MITE_VAL_TOTAL_ANS_LENGTH]; /* room for all the miteVal */ int verbose, /* blah blah blah */ thrid, /* thread ID */ ui, vi, /* image coords */ ! samples; /* number of samples handled so far by ! this thread */ miteStage *stage; /* array of stages for txf computation */ int stageNum; /* number of stages == length of stage[] */ *************** *** 228,233 **** copied from miteUser's rangeInit[], or over-written by txf evaluation */ ! rayStep, /* per-ray step, to implement sampling ! on planes */ V[3], /* per-ray view direction */ RR, GG, BB, TT; /* per-ray composited values */ --- 322,327 ---- copied from miteUser's rangeInit[], or over-written by txf evaluation */ ! rayStep, /* per-ray step (may need to be different for ! each ray to enable sampling on planes) */ V[3], /* per-ray view direction */ RR, GG, BB, TT; /* per-ray composited values */ *************** *** 239,248 **** extern mite_export int miteDefRenorm; extern mite_export int miteDefNormalSide; ! extern mite_export double miteDefNear1; /* txf.c */ - extern mite_export airEnum *miteScl; extern mite_export char miteRangeChar[MITE_RANGE_NUM]; ! extern int miteNtxfCheck(Nrrd *ntxf, gageKind *kind); /* user.c */ --- 333,348 ---- extern mite_export int miteDefRenorm; extern mite_export int miteDefNormalSide; ! extern mite_export double miteDefOpacNear1; ! extern mite_export double miteDefOpacMatters; ! ! /* kindnot.c */ ! extern mite_export airEnum *miteVal; ! extern mite_export gageKind *miteValGageKind; /* txf.c */ extern mite_export char miteRangeChar[MITE_RANGE_NUM]; ! extern void miteVariablePrint(char *buff, const gageQuerySpec *qsp); ! extern int miteVariableParse(gageQuerySpec *qsp, const char *label); ! extern int miteNtxfCheck(const Nrrd *ntxf); /* user.c */ *************** *** 251,254 **** --- 351,357 ---- /* renderMite.c */ + extern miteShadeSpec *miteShadeSpecNew(); + extern miteShadeSpec *miteShadeSpecNix(miteShadeSpec *); + extern int miteShadeParse(miteShadeSpec *shpec, char *shadeStr); extern int miteRenderBegin(miteRender **mrrP, miteUser *muu); extern int miteRenderEnd(miteRender *mrr, miteUser *muu); Index: privateMite.h =================================================================== RCS file: /cvsroot/teem/teem/src/mite/privateMite.h,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** privateMite.h 7 Jan 2004 15:34:30 -0000 1.3 --- privateMite.h 13 Feb 2004 22:58:40 -0000 1.4 *************** *** 25,33 **** #endif /* txf.c */ ! extern int _miteDomainParse(char *label, gageKind *kind); ! extern unsigned int _miteNtxfQuery(Nrrd *ntxf, gageKind *kind); extern int _miteNtxfAlphaAdjust(miteRender *mrr, miteUser *muu); ! extern int _miteStageSet(miteThread *mtt, miteRender *mrr, gageKind *kind); extern void _miteStageRun(miteThread *mtt); --- 25,40 ---- #endif + #if GAGE_TYPE_FLOAT + #define limnVtoQN_GT limnVtoQN_f + #else + #define limnVtoQN_GT limnVtoQN_d + #endif + /* txf.c */ ! extern void _miteQuery(unsigned int *queryScl, ! unsigned int *queryVec, ! unsigned int *queryTen, gageQuerySpec *qsp); extern int _miteNtxfAlphaAdjust(miteRender *mrr, miteUser *muu); ! extern int _miteStageSet(miteThread *mtt, miteRender *mrr); extern void _miteStageRun(miteThread *mtt); Index: ray.c =================================================================== RCS file: /cvsroot/teem/teem/src/mite/ray.c,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** ray.c 7 Jan 2004 15:34:30 -0000 1.16 --- ray.c 13 Feb 2004 22:58:40 -0000 1.17 *************** *** 36,40 **** fflush(stderr); } ! mtt->verbose = 0*(uIndex == 35 && vIndex == 42); mtt->RR = mtt->GG = mtt->BB = 0.0; mtt->TT = 1.0; --- 36,40 ---- fflush(stderr); } ! mtt->verbose = (uIndex == muu->verbUi && vIndex == muu->verbVi); mtt->RR = mtt->GG = mtt->BB = 0.0; mtt->TT = 1.0; *************** *** 62,93 **** ks = mtt->range[miteRangeKs]; ELL_3V_SCALE(ad, ka, muu->lit->amb); ! if (!muu->noDirLight && (kd || ks)) { ! if (muu->normalSide) { ! ELL_3V_SCALE(N, -muu->normalSide, mtt->norm); ! } else { ! ELL_3V_COPY(N, mtt->norm); ! } ! if (kd) { ! LdotN = ELL_3V_DOT(muu->lit->dir[0], N); ! if (!muu->normalSide) { ! LdotN = AIR_ABS(LdotN); ! } ! if (LdotN > 0) { ! ELL_3V_SCALE_ADD2(ad, 1.0, ad, LdotN*kd, muu->lit->col[0]); } ! } ! if (ks) { ! sp = mtt->range[miteRangeSP]; ! ELL_3V_ADD2(H, muu->lit->dir[0], mtt->V); ! ELL_3V_NORM(H, H, tmp); ! HdotN = ELL_3V_DOT(H, N); ! if (!muu->normalSide) { ! HdotN = AIR_ABS(HdotN); } ! if (HdotN > 0) { ! HdotN = pow(HdotN, sp); ! ELL_3V_SCALE(s, HdotN*ks, muu->lit->col[0]); } } } *R = (E - 1 + ad[0])*col[0] + s[0]; --- 62,101 ---- ks = mtt->range[miteRangeKs]; ELL_3V_SCALE(ad, ka, muu->lit->amb); ! if (miteShadeMethodPhong == mrr->shpec->shadeMethod) { ! if (kd || ks) { ! if (muu->normalSide) { ! ELL_3V_SCALE(N, -muu->normalSide, mtt->vec0); ! } else { ! ELL_3V_COPY(N, mtt->vec0); } ! if (kd) { ! LdotN = ELL_3V_DOT(muu->lit->dir[0], N); ! if (!muu->normalSide) { ! LdotN = AIR_ABS(LdotN); ! } ! if (LdotN > 0) { ! ELL_3V_SCALE_ADD2(ad, 1.0, ad, LdotN*kd, muu->lit->col[0]); ! } } ! if (ks) { ! sp = mtt->range[miteRangeSP]; ! ELL_3V_ADD2(H, muu->lit->dir[0], mtt->V); ! ELL_3V_NORM(H, H, tmp); ! HdotN = ELL_3V_DOT(H, N); ! if (!muu->normalSide) { ! HdotN = AIR_ABS(HdotN); ! } ! if (HdotN > 0) { ! HdotN = pow(HdotN, sp); ! ELL_3V_SCALE(s, HdotN*ks, muu->lit->col[0]); ! } } } + } else if (miteShadeMethodLitTen == mrr->shpec->shadeMethod) { + + } else { + fprintf(stderr, "!%s: PANIC, shadeMethod %d unimplemented\n", + me, mrr->shpec->shadeMethod); + exit(1); } *R = (E - 1 + ad[0])*col[0] + s[0]; *************** *** 121,125 **** } ! if (1-mtt->TT >= muu->near1 && !muu->justSum) { /* early ray termination */ mtt->TT = 0.0; --- 129,133 ---- } ! if (1-mtt->TT >= muu->opacNear1) { /* early ray termination */ mtt->TT = 0.0; *************** *** 132,155 **** biffAdd(MITE, err); return AIR_NAN; } ! /* HEY: NONE of this should be done if the txfs don't need any miteScl */ ! mtt->mscl[miteSclXw] = samplePosWorld[0]; ! mtt->mscl[miteSclXi] = samplePosIndex[0]; ! mtt->mscl[miteSclYw] = samplePosWorld[1]; ! mtt->mscl[miteSclYi] = samplePosIndex[1]; ! mtt->mscl[miteSclZw] = samplePosWorld[2]; ! mtt->mscl[miteSclZi] = samplePosIndex[2]; ! mtt->mscl[miteSclTw] = rayT; ! mtt->mscl[miteSclTi] = num; ! mtt->mscl[miteSclNdotV] = -muu->normalSide*ELL_3V_DOT(mtt->V, mtt->norm); ! mtt->mscl[miteSclNdotL] = -muu->normalSide*ELL_3V_DOT(mtt->norm, ! muu->lit->dir[0]); if (!muu->normalSide) { ! mtt->mscl[miteSclNdotV] = AIR_ABS(mtt->mscl[miteSclNdotV]); ! mtt->mscl[miteSclNdotL] = AIR_ABS(mtt->mscl[miteSclNdotL]); } ELL_3MV_MUL(kn, mtt->nPerp, mtt->V); ELL_3V_NORM(kn, kn, len); ELL_3MV_MUL(knd, mtt->gten, kn); ! mtt->mscl[miteSclGTdotV] = ELL_3V_DOT(knd, kn); memcpy(mtt->range, muu->rangeInit, MITE_RANGE_NUM*sizeof(mite_t)); --- 140,163 ---- biffAdd(MITE, err); return AIR_NAN; } ! /* HEY: NONE of this should be done if the txfs don't need any miteVal */ ! mtt->ansMiteVal[miteValXw] = samplePosWorld[0]; ! mtt->ansMiteVal[miteValXi] = samplePosIndex[0]; ! mtt->ansMiteVal[miteValYw] = samplePosWorld[1]; ! mtt->ansMiteVal[miteValYi] = samplePosIndex[1]; ! mtt->ansMiteVal[miteValZw] = samplePosWorld[2]; ! mtt->ansMiteVal[miteValZi] = samplePosIndex[2]; ! mtt->ansMiteVal[miteValTw] = rayT; ! mtt->ansMiteVal[miteValTi] = num; ! mtt->ansMiteVal[miteValNdotV] = -muu->normalSide*ELL_3V_DOT(mtt->V, mtt->vec0); ! mtt->ansMiteVal[miteValNdotL] = -muu->normalSide*ELL_3V_DOT(mtt->vec0, ! muu->lit->dir[0]); if (!muu->normalSide) { ! mtt->ansMiteVal[miteValNdotV] = AIR_ABS(mtt->ansMiteVal[miteValNdotV]); ! mtt->ansMiteVal[miteValNdotL] = AIR_ABS(mtt->ansMiteVal[miteValNdotL]); } ELL_3MV_MUL(kn, mtt->nPerp, mtt->V); ELL_3V_NORM(kn, kn, len); ELL_3MV_MUL(knd, mtt->gten, kn); ! mtt->ansMiteVal[miteValGTdotV] = ELL_3V_DOT(knd, kn); memcpy(mtt->range, muu->rangeInit, MITE_RANGE_NUM*sizeof(mite_t)); *************** *** 162,176 **** } _miteRGBACalc(&R, &G, &B, &A, mtt, mrr, muu); ! if (muu->justSum) { ! mtt->RR += A*R; ! mtt->GG += A*G; ! mtt->BB += A*B; ! mtt->TT += A; ! } else { ! mtt->RR += mtt->TT*A*R; ! mtt->GG += mtt->TT*A*G; ! mtt->BB += mtt->TT*A*B; ! mtt->TT *= 1-A; ! } if (mtt->verbose) { fprintf(stderr, "%s: after compositing: RGBT = %g,%g,%g,%g\n", --- 170,177 ---- } _miteRGBACalc(&R, &G, &B, &A, mtt, mrr, muu); ! mtt->RR += mtt->TT*A*R; ! mtt->GG += mtt->TT*A*G; ! mtt->BB += mtt->TT*A*B; ! mtt->TT *= 1-A; if (mtt->verbose) { fprintf(stderr, "%s: after compositing: RGBT = %g,%g,%g,%g\n", Index: renderMite.c =================================================================== RCS file: /cvsroot/teem/teem/src/mite/renderMite.c,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** renderMite.c 7 Jan 2004 15:34:30 -0000 1.9 --- renderMite.c 13 Feb 2004 22:58:40 -0000 1.10 *************** *** 21,24 **** --- 21,56 ---- #include "privateMite.h" + miteShadeSpec * + miteShadeSpecNew(void) { + miteShadeSpec *shpec; + + shpec = (miteShadeSpec *)calloc(1, sizeof(miteShadeSpec)); + if (shpec) { + shpec->shadeMethod = miteShadeMethodUnknown; + shpec->vec0 = gageQuerySpecNew(); + shpec->vec1 = gageQuerySpecNew(); + shpec->scl0 = gageQuerySpecNew(); + shpec->scl1 = gageQuerySpecNew(); + if (!( shpec->vec0 && shpec->vec1 && + shpec->scl0 && shpec->scl1 )) { + return NULL; + } + } + return shpec; + } + + miteShadeSpec * + miteShadeSpecNix(miteShadeSpec *shpec) { + + if (shpec) { + shpec->vec0 = gageQuerySpecNix(shpec->vec0); + shpec->vec1 = gageQuerySpecNix(shpec->vec1); + shpec->scl0 = gageQuerySpecNix(shpec->scl0); + shpec->scl1 = gageQuerySpecNix(shpec->scl1); + AIR_FREE(shpec); + } + return NULL; + } + miteRender * _miteRenderNew(void) { *************** *** 30,34 **** --- 62,70 ---- if (!mrr->rmop) { AIR_FREE(mrr); + return mrr; } + mrr->shpec = miteShadeSpecNew(); + airMopAdd(mrr->rmop, mrr->shpec, + (airMopper)miteShadeSpecNix, airMopAlways); } return mrr; *************** *** 45,54 **** } int miteRenderBegin(miteRender **mrrP, miteUser *muu) { char me[]="miteRenderBegin", err[AIR_STRLEN_MED]; gagePerVolume *pvl; ! int E, T, thr; ! unsigned int query; if (!(mrrP && muu)) { --- 81,186 ---- } + int + miteShadeParse(miteShadeSpec *shpec, char *shadeStr) { + char me[]="miteShadeParse", err[AIR_STRLEN_MED], *buff, *qstr, *tok, *state; + airArray *mop; + int ansLength; + + mop = airMopNew(); + if (!( shpec && airStrlen(shadeStr) )) { + sprintf(err, "%s: got NULL pointer and/or empty string", me); + biffAdd(MITE, err); airMopError(mop); return 1; + } + buff = airToLower(airStrdup(shadeStr)); + if (!buff) { + sprintf(err, "%s: couldn't strdup shading spec", me); + biffAdd(MITE, err); airMopError(mop); return 1; + } + airMopAdd(mop, buff, airFree, airMopAlways); + if (!strcmp("none", buff)) { + shpec->shadeMethod = miteShadeMethodNone; + } else if (buff == strstr("phong:", buff)) { + qstr = buff + strlen("phong:"); + if (miteVariableParse(shpec->vec0, qstr)) { + sprintf(err, "%s: couldn't parse \"%s\" as shading vector", me, qstr); + biffAdd(MITE, err); airMopError(mop); return 1; + } + ansLength = shpec->vec0->kind->ansLength[shpec->vec0->query]; + if (3 != ansLength) { + sprintf(err, "%s: \"%s\" isn't a vector (answer length is %d, not 3)", + me, qstr, ansLength); + biffAdd(MITE, err); airMopError(mop); return 1; + } + fprintf(stderr, "!%s: got phong:%s(%s)\n", me, + shpec->vec0->kind->name, + airEnumStr(shpec->vec0->kind->enm, shpec->vec0->query)); + } else if (buff == strstr("litten:", buff)) { + qstr = buff + strlen("litten:"); + /* ---- first vector */ + tok = airStrtok(qstr, ",", &state); + if (miteVariableParse(shpec->vec0, tok)) { + sprintf(err, "%s: couldn't parse \"%s\" as lit-tensor vector", me, tok); + biffAdd(MITE, err); airMopError(mop); return 1; + } + ansLength = shpec->vec0->kind->ansLength[shpec->vec0->query]; + if (3 != ansLength) { + sprintf(err, "%s: \"%s\" isn't a vector (answer length is %d, not 3)", + me, qstr, ansLength); + biffAdd(MITE, err); airMopError(mop); return 1; + } + /* ---- second vector */ + tok = airStrtok(qstr, ",", &state); + if (miteVariableParse(shpec->vec1, tok)) { + sprintf(err, "%s: couldn't parse \"%s\" as lit-tensor vector", me, tok); + biffAdd(MITE, err); airMopError(mop); return 1; + } + ansLength = shpec->vec1->kind->ansLength[shpec->vec1->query]; + if (3 != ansLength) { + sprintf(err, "%s: \"%s\" isn't a vector (answer length is %d, not 3)", + me, qstr, ansLength); + biffAdd(MITE, err); airMopError(mop); return 1; + } + /* ---- first scalar */ + tok = airStrtok(qstr, ",", &state); + if (miteVariableParse(shpec->scl0, tok)) { + sprintf(err, "%s: couldn't parse \"%s\" as lit-tensor scalar", me, tok); + biffAdd(MITE, err); airMopError(mop); return 1; + } + ansLength = shpec->scl0->kind->ansLength[shpec->scl0->query]; + if (1 != ansLength) { + sprintf(err, "%s: \"%s\" isn't a scalar (answer length is %d, not 1)", + me, qstr, ansLength); + biffAdd(MITE, err); airMopError(mop); return 1; + } + /* ---- second scalar */ + tok = airStrtok(qstr, ",", &state); + if (miteVariableParse(shpec->scl1, tok)) { + sprintf(err, "%s: couldn't parse \"%s\" as lit-tensor scalar", me, tok); + biffAdd(MITE, err); airMopError(mop); return 1; + } + ansLength = shpec->scl1->kind->ansLength[shpec->scl1->query]; + if (1 != ansLength) { + sprintf(err, "%s: \"%s\" isn't a scalar (answer length is %d, not 1)", + me, qstr, ansLength); + biffAdd(MITE, err); airMopError(mop); return 1; + } + fprintf(stderr, "!%s: got litten:%s(%s),\n", me, + shpec->vec0->kind->name, + airEnumStr(shpec->vec0->kind->enm, shpec->vec0->query)); + } else { + sprintf(err, "%s: shading specification \"%s\" not understood", + me, shadeStr); + biffAdd(MITE, err); airMopError(mop); return 1; + } + airMopOkay(mop); + return 0; + } + int miteRenderBegin(miteRender **mrrP, miteUser *muu) { char me[]="miteRenderBegin", err[AIR_STRLEN_MED]; gagePerVolume *pvl; ! int E, T, thr, axi; ! unsigned int queryScl, queryVec, queryTen; if (!(mrrP && muu)) { *************** *** 69,84 **** } ! query = 0; for (T=0; T<muu->ntxfNum; T++) { ! query |= _miteNtxfQuery(muu->ntxf[T], gageKindScl); } if (!muu->noDirLight) { query |= 1<<gageSclNormal; } fprintf(stderr, "!%s: gageScl query: \n", me); gageQueryPrint(stderr, gageKindScl, query); E = 0; ! if (!E) E |= !(pvl = gagePerVolumeNew(muu->gctx0, muu->nin, gageKindScl)); if (!E) E |= gagePerVolumeAttach(muu->gctx0, pvl); if (!E) E |= gageKernelSet(muu->gctx0, gageKernel00, --- 201,225 ---- } ! queryScl = 0; ! queryTen = 0; for (T=0; T<muu->ntxfNum; T++) { ! for (axi=1; axi<=muu->ntxf[T]->dim-1; axi++) { ! _miteNtxfQuery(&queryScl, &queryVec, &queryTen, ! muu->ntxf[T]->axis[axi]->label); } if (!muu->noDirLight) { query |= 1<<gageSclNormal; } + /* fprintf(stderr, "!%s: gageScl query: \n", me); gageQueryPrint(stderr, gageKindScl, query); + */ E = 0; ! if (!muu->nsin) { ! sprintf(err, "%s: sorry- can't proceed without scalar volume", me); ! biffAdd(MITE, err); return 1; ! } ! if (!E) E |= !(pvl = gagePerVolumeNew(muu->gctx0, muu->nsin, gageKindScl)); if (!E) E |= gagePerVolumeAttach(muu->gctx0, pvl); if (!E) E |= gageKernelSet(muu->gctx0, gageKernel00, Index: thread.c =================================================================== RCS file: /cvsroot/teem/teem/src/mite/thread.c,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** thread.c 7 Jan 2004 15:34:30 -0000 1.8 --- thread.c 13 Feb 2004 22:58:40 -0000 1.9 *************** *** 44,48 **** } } ! (*mttP)->ans = (*mttP)->gctx->pvl[0]->ans; (*mttP)->norm = (*mttP)->ans + gageKindScl->ansOffset[gageSclNormal]; (*mttP)->nPerp = (*mttP)->ans + gageKindScl->ansOffset[gageSclNPerp]; --- 44,48 ---- } } ! (*mttP)->ansScl = (*mttP)->gctx->pvl[0]->ans; (*mttP)->norm = (*mttP)->ans + gageKindScl->ansOffset[gageSclNormal]; (*mttP)->nPerp = (*mttP)->ans + gageKindScl->ansOffset[gageSclNPerp]; Index: txf.c =================================================================== RCS file: /cvsroot/teem/teem/src/mite/txf.c,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** txf.c 7 Jan 2004 15:34:30 -0000 1.12 --- txf.c 13 Feb 2004 22:58:41 -0000 1.13 *************** *** 29,163 **** miteRangeChar[MITE_RANGE_NUM] = "ARGBEadsp"; ! char ! _miteSclStr[][AIR_STRLEN_SMALL] = { ! "(unknown miteScl)", ! "Xw", ! "Xi", ! "Yw", ! "Yi", ! "Zw", ! "Zi", ! "Tw", ! "Ti", ! "NdotV", ! "NdotL", ! "GTdotV" ! }; ! ! int ! _miteSclVal[] = { ! miteSclUnknown, ! miteSclXw, ! miteSclXi, ! miteSclYw, ! miteSclYi, ! miteSclZw, ! miteSclZi, ! miteSclTw, ! miteSclTi, ! miteSclNdotV, ! miteSclNdotL, ! miteSclGTdotV, ! }; ! ! char ! _miteSclStrEqv[][AIR_STRLEN_SMALL] = { ! "x", "xw", ! "xi", ! "y", "yw", ! "yi", ! "z", "zw", ! "zi", ! "t", "tw", ! "ti", ! "ndotv", ! "ndotl", ! "gtdotv", ! "" ! }; ! ! int ! _miteSclValEqv[] = { ! miteSclXw, miteSclXw, ! miteSclXi, ! miteSclYw, miteSclYw, ! miteSclYi, ! miteSclZw, miteSclZw, ! miteSclZi, ! miteSclTw, miteSclTw, ! miteSclTi, ! miteSclNdotV, ! miteSclNdotL, ! miteSclGTdotV ! }; - airEnum - _miteScl = { - "miteScl", - MITE_SCL_MAX+1, - _miteSclStr, _miteSclVal, - NULL, - _miteSclStrEqv, _miteSclValEqv, - AIR_FALSE - }; - airEnum * - miteScl = &_miteScl; int ! _miteDomainParse(char *label, gageKind *kind) { ! char me[]="_miteDomainParse", err[AIR_STRLEN_MED], *buff, *paren, *qstr; ! int domI; ! ! if (!label) { sprintf(err, "%s: got NULL pointer", me); ! biffAdd(MITE, err); return -1; } ! if (label == strstr(label, "gage(")) { /* txf domain variable is to be measured directly by gage */ ! buff = airStrdup(label); ! if (!buff) { ! sprintf(err, "%s: this is so annoying", me); ! biffAdd(MITE, err); return -1; ! } ! if (!(paren = strstr(buff, ")"))) { sprintf(err, "%s: didn't see close paren after \"gage(\"", me); ! biffAdd(MITE, err); return -1; } ! *paren = 0; ! qstr = buff + strlen("gage("); ! domI = airEnumVal(gageScl, qstr); ! if (gageSclUnknown == domI) { ! sprintf(err, "%s: couldn't parse \"%s\" as a gageScl varable", me, qstr); ! biffAdd(MITE, err); free(buff); return -1; } ! if (1 != kind->ansLength[domI]) { ! sprintf(err, "%s: %s isn't a scalar, so it can't a txf domain variable", ! me, airEnumStr(gageScl, domI)); ! biffAdd(MITE, err); free(buff); return -1; } ! free(buff); } else { ! /* txf domain variable is not directly measured by gage */ ! domI = airEnumVal(miteScl, label); ! if (miteSclUnknown == domI) { ! sprintf(err, "%s: couldn't parse \"%s\" as a miteScl variable", ! me, label); ! biffAdd(MITE, err); return -1; } - /* this signifies that its a miteScl, not a gageScl */ - domI += GAGE_SCL_MAX+1; } ! return domI; } int ! miteNtxfCheck(Nrrd *ntxf, gageKind *kind) { char me[]="miteNtxfCheck", err[AIR_STRLEN_MED], *range, *domS; ! int i; - if (!( ntxf && kind )) { - sprintf(err, "%s: got NULL pointer", me); - biffAdd(MITE, err); return 1; - } if (nrrdCheck(ntxf)) { sprintf(err, "%s: basic nrrd validity check failed", me); --- 29,169 ---- miteRangeChar[MITE_RANGE_NUM] = "ARGBEadsp"; ! void ! miteVariablePrint(char *buff, const gageQuerySpec *qsp) { ! char me[]="miteVariablePrint"; ! ! if (gageKindScl == qsp->kind ! || gageKindVec == qsp->kind ! || tenGageKind == qsp->kind) { ! sprintf(buff, "gage(%s:%s)", qsp->kind->name, ! airEnumStr(qsp->kind->enm, qsp->query)); ! } else if (miteValGageKind == qsp->kind) { ! sprintf(buff, "%s(%s)", qsp->kind->name, ! airEnumStr(qsp->kind->enm, qsp->query)); ! } else { ! sprintf(buff, "(%s: unknown variable!)", me); ! } ! return; ! } + /* + ******** miteVariableParse() + ** + ** takes a string (usually the label from a nrrd axis) and parses it + ** to determine the gageQuerySpec from it (which means finding the + ** kind and query). The valid formats are (currently): + ** + ** <query> : miteValGageKind (DEPRECATED) + ** gage(<query>) : gageKindScl (DEPRECATED) + ** gage(scalar:<query>) : gageKindScl (preferred) + ** gage(vector:<query>) : gageKindVec + ** gage(tensor:<query>) : tenGageKind + ** mite(<query>) : miteValGageKind + ** + ** Notice that "scalar", "vector", and "tensor" to NOT refer to the type + ** of the quantity being measured, but rather to the type of volume in + ** which quantity is measured (i.e., the gageKind used) + */ int ! miteVariableParse(gageQuerySpec *qsp, const char *label) { ! char me[]="miteVariableParse", err[AIR_STRLEN_MED], *buff, *endparen, ! *kqstr, *col, *kstr, *qstr; ! airArray *mop; ! ! if (!( qsp && label )) { sprintf(err, "%s: got NULL pointer", me); ! biffAdd(MITE, err); return 1; } ! mop = airMopNew(); ! buff = airStrdup(label); ! if (!buff) { ! sprintf(err, "%s: couldn't strdup label!", me); ! biffAdd(MITE, err); airMopError(mop); return 1; ! } ! airMopAdd(mop, buff, airFree, airMopAlways); ! if (strstr(buff, "gage(") == buff) { /* txf domain variable is to be measured directly by gage */ ! if (!(endparen = strstr(buff, ")"))) { sprintf(err, "%s: didn't see close paren after \"gage(\"", me); ! biffAdd(MITE, err); airMopError(mop); return 1; } ! *endparen = 0; ! kqstr = buff + strlen("gage("); ! /* first see if its a gageKindScl specification */ ! qsp->query = airEnumVal(gageScl, kqstr); ! if (-1 != qsp->query) { ! qsp->kind = gageKindScl; ! fprintf(stderr, "\n%s: WARNING: deprecated use of txf domain " ! "\"gage(%s)\" without explicit gage kind specification; " ! "should use \"gage(%s:%s)\" instead\n\n", ! me, kqstr, gageKindScl->name, kqstr); ! } else { ! /* should be of form "<kind>:<query>" */ ! col = strstr(kqstr, ":"); ! if (!col) { ! sprintf(err, "%s: didn't see \":\" seperator between gage " ! "kind and query", me); ! biffAdd(MITE, err); airMopError(mop); return 1; ! } ! *col = 0; ! kstr = kqstr; ! qstr = col+1; ! if (!strcmp(gageKindScl->name, kstr)) { ! qsp->kind = gageKindScl; ! } else if (!strcmp(gageKindVec->name, kstr)) { ! qsp->kind = gageKindVec; ! } else if (!strcmp(tenGageKind->name, kstr)) { ! qsp->kind = tenGageKind; ! } else { ! sprintf(err, "%s: don't recognized \"%s\" gage kind", me, kstr); ! biffAdd(MITE, err); airMopError(mop); return 1; ! } ! qsp->query = airEnumVal(qsp->kind->enm, qstr); ! if (-1 == qsp->query) { ! sprintf(err, "%s: couldn't parse \"%s\" as a %s varable", ! me, qstr, qsp->kind->name); ! biffAdd(MITE, err); airMopError(mop); return 1; ! } } ! } else if (strstr(buff, "mite(") == buff) { ! /* txf domain variable is *not* directly measured by gage */ ! if (!(endparen = strstr(buff, ")"))) { ! sprintf(err, "%s: didn't see close paren after \"mite(\"", me); ! biffAdd(MITE, err); airMopError(mop); return 1; } ! *endparen = 0; ! kqstr = buff + strlen("mite("); ! qsp->query = airEnumVal(miteVal, kqstr); ! if (-1 == qsp->query) { ! sprintf(err, "%s: couldn't parse \"%s\" as a miteVal variable", ! me, kqstr); ! biffAdd(MITE, err); airMopError(mop); return 1; ! } ! qsp->kind = miteValGageKind; } else { ! /* didn't start with "gage(" or "mite(" */ ! qsp->query = airEnumVal(miteVal, label); ! if (-1 != qsp->query) { ! /* its measured by mite */ ! qsp->kind = miteValGageKind; ! fprintf(stderr, "\n%s: WARNING: deprecated use of txf domain " ! "\"%s\"; should use \"mite(%s)\" instead\n\n", ! me, label, label); ! } else { ! sprintf(err, "%s: \"%s\" not a recognized variable", me, label); ! biffAdd(MITE, err); airMopError(mop); return 1; } } ! airMopOkay(mop); ! return 0; } int ! miteNtxfCheck(const Nrrd *ntxf) { char me[]="miteNtxfCheck", err[AIR_STRLEN_MED], *range, *domS; ! gageQuerySpec qsp; ! int rii, axi; if (nrrdCheck(ntxf)) { sprintf(err, "%s: basic nrrd validity check failed", me); *************** *** 179,186 **** biffAdd(MITE, err); return 1; } - if (1 == ntxf->dim) { - sprintf(err, "%s: dimension is 1, must be 2 or greater", me); - biffAdd(MITE, err); return 1; - } range = ntxf->axis[0].label; if (0 == airStrlen(range)) { --- 185,188 ---- *************** *** 193,229 **** biffAdd(MITE, err); return 1; } ! for (i=0; i<airStrlen(range); i++) { ! if (!strchr(miteRangeChar, range[i])) { sprintf(err, "%s: char %d of axis[0]'s label (\"%c\") isn't a valid " "transfer function range specifier (not in \"%s\")", ! me, i, range[i], miteRangeChar); biffAdd(MITE, err); return 1; } } ! for (i=1; i<ntxf->dim; i++) { ! if (!( AIR_EXISTS(ntxf->axis[i].min) && AIR_EXISTS(ntxf->axis[i].max) )) { ! sprintf(err, "%s: min and max of axis %d aren't both set", me, i); biffAdd(MITE, err); return 1; } ! if (!( ntxf->axis[i].min < ntxf->axis[i].max )) { sprintf(err, "%s: min (%g) not less than max (%g) on axis %d", ! me, ntxf->axis[i].min, ntxf->axis[i].max, i); biffAdd(MITE, err); return 1; } ! if (1 == ntxf->axis[i].size) { ! sprintf(err, "%s: # samples on axis %d must be > 1", me, i); biffAdd(MITE, err); return 1; } ! domS = ntxf->axis[i].label; if (0 == airStrlen(domS)) { sprintf(err, "%s: axis[%d] of txf didn't specify a domain variable", ! me, i); biffAdd(MITE, err); return 1; } ! if (-1 == _miteDomainParse(domS, kind)) { ! sprintf(err, "%s: problem with txf domain \"%s\" for axis %d\n", ! me, domS, i); biffAdd(MITE, err); return 1; } } --- 195,250 ---- biffAdd(MITE, err); return 1; } ! for (rii=0; rii<airStrlen(range); rii++) { ! if (!strchr(miteRangeChar, range[rii])) { sprintf(err, "%s: char %d of axis[0]'s label (\"%c\") isn't a valid " "transfer function range specifier (not in \"%s\")", ! me, rii, range[rii], miteRangeChar); biffAdd(MITE, err); return 1; } } ! for (axi=1; axi<ntxf->dim; axi++) { ! if (!( AIR_EXISTS(ntxf->axis[axi].min) && ! AIR_EXISTS(ntxf->axis[axi].max) )) { ! sprintf(err, "%s: min and max of axis %d aren't both set", me, axi); biffAdd(MITE, err); return 1; } ! if (!( ntxf->axis[axi].min < ntxf->axis[axi].max )) { sprintf(err, "%s: min (%g) not less than max (%g) on axis %d", ! me, ntxf->axis[axi].min, ntxf->axis[axi].max, axi); biffAdd(MITE, err); return 1; } ! if (1 == ntxf->axis[axi].size) { ! sprintf(err, "%s: # samples on axis %d must be > 1", me, axi); biffAdd(MITE, err); return 1; } ! domS = ntxf->axis[axi].label; if (0 == airStrlen(domS)) { sprintf(err, "%s: axis[%d] of txf didn't specify a domain variable", ! me, axi); biffAdd(MITE, err); return 1; } ! if (miteVariableParse(&qsp, domS)) { ! sprintf(err, "%s: couldn't parse txf domain \"%s\" for axis %d\n", ! me, domS, axi); biffAdd(MITE, err); return 1; } + if (!( 1 == qsp.kind->ansLength[qsp.query] || + 3 == qsp.kind->ansLength[qsp.query] )) { + sprintf(err, "%s: %s not a scalar or vector: can't be a txf " + "domain variable", me, domS); + biffAdd(MITE, err); return 1; + } + if (3 == qsp.kind->ansLength[qsp.query]) { + /* has to be right length for one of the quantization schemes */ + if (!( limnQNBins[limnQN16checker] == ntxf->axis[axi].size || + limnQNBins[limnQN14checker] == ntxf->axis[axi].size || + limnQNBins[limnQN12checker] == ntxf->axis[axi].size )) { + sprintf(err, "%s: vector %s can be quantized into %d, %d, or %d bins " + "but not %d", me, domS, limnQNBins[limnQN16checker], + limnQNBins[limnQN14checker], limnQNBins[limnQN12checker], + ntxf->axis[axi].size); + biffAdd(MITE, err); return 1; + } + } } *************** *** 231,256 **** } ! unsigned int ! _miteNtxfQuery(Nrrd *ntxf, gageKind *kind) { ! int i, dom; ! unsigned int query; ! ! query = 0; for (i=1; i<ntxf->dim; i++) { ! dom = _miteDomainParse(ntxf->axis[i].label, kind); ! if (AIR_IN_OP(gageSclUnknown, dom, gageSclLast)) { ! query |= 1 << dom; ! } else { ! /* of all places, this is where we set gage queries that ! are required for miteScl txf domain variables */ ! dom -= GAGE_SCL_MAX+1; ! switch(dom) { ! case miteSclNdotV: query |= 1 << gageSclNormal; break; ! case miteSclNdotL: query |= 1 << gageSclNormal; break; ! case miteSclGTdotV: query |= 1 << gageSclGeomTens; break; ! } } } ! return query; } --- 252,313 ---- } ! /* ! ** _miteQuery() ! ** ! ** This looks a given gageQuerySpec and sets the bits in the ! ** gageKindScl and tenGageKind queries that are required to calculate ! ** the quantity ! ** ! ** NOTE: This does NOT initialize the *query{Scl,Vec,Ten}: it ! ** just bit-wise or's on new stuff ! ** ! ** HEY: this is really unfortunate: each new gage type use for ! ** volume rendering in mite will have to explicitly added as ! ** arguments here, which is part of the reason that mite may end ! ** up explicitly depending on the libraries supplying those gageKinds ! ** (like how new mite depends on ten) ! */ ! void ! _miteQuery(unsigned int *queryScl, ! unsigned int *queryVec, ! unsigned int *queryTen, gageQuerySpec *qsp) { ! char me[]="_miteQuery"; ! ! /* for (i=1; i<ntxf->dim; i++) { ! miteVariableParse(qsp, ntxf->axis[i].label); ! */ ! if (gageKindScl == qsp->kind) { ! *queryScl |= 1 << qsp->query; ! } else if (gageKindVec == qsp->kind) { ! *queryVec |= 1 << qsp->query; ! } else if (tenGageKind == qsp->kind) { ! *queryTen |= 1 << qsp->query; ! } else if (miteValGageKind == qsp->kind) { ! /* HEY: the first of these two have useful analogs for tensor ! data, but I won't be able to express them ... */ ! switch(qsp->query) { ! case miteValNdotV: ! *queryScl |= 1 << gageSclNormal; ! break; ! case miteValNdotL: ! *queryScl |= 1 << gageSclNormal; ! break; ! case miteValGTdotV: ! *queryScl |= 1 << gageSclGeomTens; ! break; ! case miteValVrefN: ! *queryScl |= 1 << gageSclNormal; ! break; ! case miteValVdefT: ! case miteValVdefTdotV: ! *queryTen |= 1 << tenGageTensor; ! break; } + } else { + fprintf(stderr, "%s: PANIC: unrecognized non-null gageKind\n", me); + exit(1); } ! return; } *************** *** 272,276 **** if (!E) airMopAdd(mrr->rmop, mrr->ntxf[ni], (airMopper)nrrdNuke, airMopAlways); ! /* this assumes that ntxf type is float, double, or uchar */ switch(muu->ntxf[ni]->type) { case nrrdTypeUChar: --- 329,342 ---- if (!E) airMopAdd(mrr->rmop, mrr->ntxf[ni], (airMopper)nrrdNuke, airMopAlways); ! if (!( nrrdTypeUChar == muu->ntxf[ni]->type ! || nrrdTypeFloat == muu->ntxf[ni]->type ! || nrrdTypeDouble == muu->ntxf[ni]->type )) { ! sprintf(err, "%s: sorry, can't handle txf of type %s (only %s, %s, %s)", ! me, airEnumStr(nrrdType, muu->ntxf[ni]->type), ! airEnumStr(nrrdType, nrrdTypeUChar), ! airEnumStr(nrrdType, nrrdTypeFloat), ! airEnumStr(nrrdType, nrrdTypeDouble)); ! biffAdd(MITE, err); return 1; ! } switch(muu->ntxf[ni]->type) { case nrrdTypeUChar: *************** *** 280,284 **** if (!E) E |= nrrdCopy(mrr->ntxf[ni], muu->ntxf[ni]); break; ! default: if (!E) E |= nrrdConvert(mrr->ntxf[ni], muu->ntxf[ni], mite_nt); break; --- 346,350 ---- if (!E) E |= nrrdCopy(mrr->ntxf[ni], muu->ntxf[ni]); break; ! default: /* will be either float or double (whatever mite_nt isn't) */ if (!E) E |= nrrdConvert(mrr->ntxf[ni], muu->ntxf[ni], mite_nt); break; *************** *** 335,344 **** } int ! _miteStageSet(miteThread *mtt, miteRender *mrr, gageKind *kind) { char me[]="_miteStageSet", err[AIR_STRLEN_MED]; ! int ni, di, si, rii, dom, stageNum; Nrrd *ntxf; miteStage *stage; char rc; --- 401,428 ---- } + void + _miteStageInit(miteStage *stage) { + int rii; + + stage->val = NULL; + stage->size = -1; + stage->op = miteStageOpUnknown; + stage->qn = NULL; + stage->min = stage->max = AIR_NAN; + stage->data = NULL; + for (rii=0; rii<=MITE_RANGE_NUM-1; rii++) { + stage->rangeIdx[rii] = -1; + } + stage->rangeNum = -1; + return; + } + int ! _miteStageSet(miteThread *mtt, miteRender *mrr) { char me[]="_miteStageSet", err[AIR_STRLEN_MED]; ! int ni, di, stageIdx, rii, stageNum; Nrrd *ntxf; miteStage *stage; + gageQuerySpec qsp; char rc; *************** *** 352,367 **** airMopAdd(mrr->rmop, mtt->stage, airFree, airMopAlways); mtt->stageNum = stageNum; ! si = 0; for (ni=0; ni<mrr->ntxfNum; ni++) { ntxf = mrr->ntxf[ni]; for (di=ntxf->dim-1; di>=1; di--) { ! stage = mtt->stage + si; ! dom = _miteDomainParse(ntxf->axis[di].label, kind); ! if (AIR_IN_OP(gageSclUnknown, dom, gageSclLast)) { ! stage->val = mtt->ans + kind->ansOffset[dom]; } else { ! dom -= GAGE_SCL_MAX+1; ! stage->val = mtt->mscl + dom; } /* fprintf(stderr, "!%s: ans=%p + offset[%d]=%d == %p\n", me, --- 436,460 ---- airMopAdd(mrr->rmop, mtt->stage, airFree, airMopAlways); mtt->stageNum = stageNum; ! stageIdx = 0; for (ni=0; ni<mrr->ntxfNum; ni++) { ntxf = mrr->ntxf[ni]; for (di=ntxf->dim-1; di>=1; di--) { ! stage = mtt->stage + stageIdx; ! _miteStageInit(stage); ! miteVariableParse(&qsp, ntxf->axis[di].label); ! if (gageKindScl == qsp.kind) { ! stage->val = mtt->ansScl; ! } else if (gageKindVec == qsp.kind) { ! stage->val = mtt->ansVec; ! } else if (tenGageKind == qsp.kind) { ! stage->val = mtt->ansTen; ! } else if (miteValGageKind == qsp.kind) { ! stage->val = mtt->ansMiteVal; } else { ! sprintf(err, "%s: don't handle gageKind for \"%s\"", ! me, ntxf->axis[di].label); ! biffAdd(MITE, err); return 1; } + stage->val += qsp.kind->ansOffset[qsp.query]; /* fprintf(stderr, "!%s: ans=%p + offset[%d]=%d == %p\n", me, *************** *** 375,378 **** --- 468,493 ---- } else { stage->data = ntxf->data; + stage->op = miteStageOpMultiply; + if (1 == qsp.kind->ansLength[qsp.query]) { + stage->qn = NULL; + } else if (3 == 1 == qsp.kind->ansLength[qsp.query]) { + if (limnQNBins[limnQN16checker] == ntxf->axis[di].size) { + stage->qn = limnVtoQN_GT[limnQN16checker]; + } else if (limnQNBins[limnQN14checker] == ntxf->axis[di].size) { + stage->qn = limnVtoQN_GT[limnQN14checker]; + } else if (limnQNBins[limnQN12checker] == ntxf->axis[di].size) { + stage->qn = limnVtoQN_GT[limnQN12checker]; + } else { + sprintf(err, "%s: txf axis %d size %d not usable for vector " + "txf domain variable %s", me, + di, ntxf->axis[di].size, ntxf->axis[di].label); + biffAdd(MITE, err); return 1; + } + } else { + sprintf(err, "%s: %s not scalar or vector (len = %d): can't be " + "a txf domain variable", me, + ntxf->axis[di].label, qsp.kind->ansLength[qsp.query]); + biffAdd(MITE, err); return 1; + } stage->rangeNum = ntxf->axis[0].size; for (rii=0; rii<stage->rangeNum; rii++) { *************** *** 385,389 **** } } ! si++; } } --- 500,504 ---- } } ! stageIdx++; } } *************** *** 393,413 **** void _miteStageRun(miteThread *mtt) { ! int si, ri, rii, idx, index; miteStage *stage; mite_t *rangeData; ! index = 0; ! for (si=0; si<mtt->stageNum; si++) { ! stage = &(mtt->stage[si]); ! AIR_INDEX(stage->min, *(stage->val), stage->max, stage->size, idx); ! idx = AIR_CLAMP(0, idx, stage->size-1); ! index = stage->size*index + idx; if (stage->data) { ! rangeData = stage->data + stage->rangeNum*index; for (rii=0; rii<stage->rangeNum; rii++) { ri = stage->rangeIdx[rii]; mtt->range[ri] *= rangeData[rii]; } ! index = 0; } } --- 508,534 ---- void _miteStageRun(miteThread *mtt) { ! int stageIdx, ri, rii, txfIdx, finalIdx; miteStage *stage; mite_t *rangeData; ! finalIdx = 0; ! for (stageIdx=0; stageIdx<mtt->stageNum; stageIdx++) { ! stage = &(mtt->stage[stageIdx]); ! if (stage->qn) { ! /* its a vector-valued txf domain variable */ ! txfIdx = stage->qn(stage->val); ! } else { ! /* its a scalar txf domain variable */ ! AIR_INDEX(stage->min, *(stage->val), stage->max, stage->size, txfIdx); ! } ! txfIdx = AIR_CLAMP(0, txfIdx, stage->size-1); ! finalIdx = stage->size*finalIdx + txfIdx; if (stage->data) { ! rangeData = stage->data + stage->rangeNum*finalIdx; for (rii=0; rii<stage->rangeNum; rii++) { ri = stage->rangeIdx[rii]; mtt->range[ri] *= rangeData[rii]; } ! finalIdx = 0; } } Index: user.c =================================================================== RCS file: /cvsroot/teem/teem/src/mite/user.c,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** user.c 7 Jan 2004 15:34:30 -0000 1.13 --- user.c 13 Feb 2004 22:58:41 -0000 1.14 *************** *** 31,38 **** muu->umop = airMopNew(); ! muu->nin = NULL; muu->ntxf = NULL; /* managed by user (with miter: hest) */ muu->nout = NULL; /* managed by user (with miter: hest) */ muu->ntxfNum = 0; for (i=0; i<MITE_RANGE_NUM; i++) { muu->rangeInit[i] = 1.0; --- 31,41 ---- muu->umop = airMopNew(); ! muu->nsin = NULL; ! muu->nvin = NULL; ! muu->ntin = NULL; muu->ntxf = NULL; /* managed by user (with miter: hest) */ muu->nout = NULL; /* managed by user (with miter: hest) */ muu->ntxfNum = 0; + muu->shadeStr[0] = 0; for (i=0; i<MITE_RANGE_NUM; i++) { muu->rangeInit[i] = 1.0; *************** *** 52,57 **** muu->lit = limnLightNew(); airMopAdd(muu->umop, muu->lit, (airMopper)limnLightNix, airMopAlways); ! muu->justSum = AIR_FALSE; ! muu->noDirLight = AIR_FALSE; muu->rendTime = 0; muu->sampRate = 0; --- 55,60 ---- muu->lit = limnLightNew(); airMopAdd(muu->umop, muu->lit, (airMopper)limnLightNix, airMopAlways); ! muu->normalSide = miteDefNormalSide; ! muu->verbUi = muu->verbVi = -1; muu->rendTime = 0; muu->sampRate = 0; *************** *** 84,88 **** gotOpac = AIR_FALSE; for (T=0; T<muu->ntxfNum; T++) { ! if (miteNtxfCheck(muu->ntxf[T], gageKindScl)) { sprintf(err, "%s: ntxf[%d] (%d of %d) can't be used as a txf", me, T, T+1, muu->ntxfNum); --- 87,91 ---- gotOpac = AIR_FALSE; for (T=0; T<muu->ntxfNum; T++) { ! if (miteNtxfCheck(muu->ntxf[T])) { sprintf(err, "%s: ntxf[%d] (%d of %d) can't be used as a txf", me, T, T+1, muu->ntxfNum); *************** *** 92,97 **** } if (!gotOpac) { ! fprintf(stderr, "\n\n%s: !!! WARNING !!! opacity (\"A\") not set " ! "by any transfer function\n\n", me); } if (!muu->nout) { --- 95,104 ---- } if (!gotOpac) { ! fprintf(stderr, "\n\n%s: ****************************************" ! "************************\n", me); ! fprintf(stderr, "%s: !!! WARNING !!! opacity (\"A\") not set " ! "by any transfer function\n", me); ! fprintf(stderr, "%s: ****************************************" ! "************************\n\n\n", me); } if (!muu->nout) { *************** *** 99,105 **** biffAdd(MITE, err); return 1; } ! if (gageVolumeCheck(muu->gctx0, muu->nin, gageKindScl)) { ! sprintf(err, "%s: trouble with input volume", me); ! biffMove(MITE, err, GAGE); return 1; } --- 106,123 ---- biffAdd(MITE, err); return 1; } ! if (!(muu->nsin || muu->ntin)) { ! sprintf(err, "%s: got neither scalar nor tensor volume", me); ! biffAdd(MITE, err); return 1; ! } ! if (muu->nsin) { ! if (gageVolumeCheck(muu->gctx0, muu->nsin, gageKindScl)) { ! sprintf(err, "%s: trouble with input scalar volume", me); ! biffMove(MITE, err, GAGE); return 1; ! } ! } else { ! if (gageVolumeCheck(muu->gctx0, muu->ntin, tenGageKind)) { ! sprintf(err, "%s: trouble with input tensor volume", me); ! biffMove(MITE, err, GAGE); return 1; ! } } |