double * _miteAnswerPointer(miteThread *mtt, gageItemSpec *isp) { static const char me[]="_miteAnswerPointer"; double *ret; if (!isp->kind) { /* we got a NULL kind (as happens with output of gageItemSpecNew(), or miteVariableParse of an empty string); only NULL return is sensible */ return NULL; } if (gageKindScl == isp->kind) { ret = mtt->ansScl; } else if (gageKindVec == isp->kind) { ret = mtt->ansVec; } else if (tenGageKind == isp->kind) { ret = mtt->ansTen; } else if (miteValGageKind == isp->kind) { ret = mtt->ansMiteVal; } else { fprintf(stderr, "\nPANIC: %s: unknown gageKind!\n", me); exit(1); } ret += gageKindAnswerOffset(isp->kind, isp->item); return ret; }
/* non-const version of the above */ double * _gageAnswerPointer(const gageContext *ctx, gagePerVolume *pvl, int item) { double *ret; AIR_UNUSED(ctx); if (pvl && !airEnumValCheck(pvl->kind->enm, item)) { ret = pvl->answer + gageKindAnswerOffset(pvl->kind, item); } else { ret = NULL; } return ret; }
miteThread * miteThreadNew() { char me[]="miteThreadNew", err[BIFF_STRLEN]; miteThread *mtt; int ii; mtt = (miteThread *)calloc(1, sizeof(miteThread)); if (!mtt) { sprintf(err, "%s: couldn't calloc miteThread", me); biffAdd(MITE, err); return NULL; } mtt->rmop = airMopNew(); if (!mtt->rmop) { sprintf(err, "%s: couldn't calloc thread's mop", me); biffAdd(MITE, err); airFree(mtt); return NULL; } mtt->gctx = NULL; mtt->ansScl = mtt->ansVec = mtt->ansTen = NULL; mtt->_normal = NULL; mtt->shadeVec0 = NULL; mtt->shadeVec1 = NULL; mtt->shadeScl0 = NULL; mtt->shadeScl1 = NULL; /* were miteVal a full-fledged gageKind, the following would be done by gagePerVolumeNew */ mtt->ansMiteVal = (double *)calloc(gageKindTotalAnswerLength(miteValGageKind), sizeof(double)); mtt->directAnsMiteVal = (double **)calloc(miteValGageKind->itemMax+1, sizeof(double*)); if (!(mtt->ansMiteVal && mtt->directAnsMiteVal)) { sprintf(err, "%s: couldn't calloc miteVal answer arrays", me); biffAdd(MITE, err); return NULL; } for (ii=0; ii<=miteValGageKind->itemMax; ii++) { mtt->directAnsMiteVal[ii] = mtt->ansMiteVal + gageKindAnswerOffset(miteValGageKind, ii); } mtt->verbose = 0; mtt->skip = 0; mtt->thrid = -1; mtt->ui = mtt->vi = -1; mtt->raySample = 0; mtt->samples = 0; mtt->stage = NULL; /* mtt->range[], rayStep, V, RR, GG, BB, TT initialized in miteRayBegin or in miteSample */ return mtt; }
/* ******** gagePerVolumeNew() ** ** creates a new pervolume of a known kind, but nothing besides the ** answer array is allocated ** ** uses biff primarily because of the error checking in gageVolumeCheck() */ gagePerVolume * gagePerVolumeNew(gageContext *ctx, const Nrrd *nin, const gageKind *kind) { char me[]="gagePerVolumeNew", err[BIFF_STRLEN]; gagePerVolume *pvl; int ii; if (!( nin && kind )) { sprintf(err, "%s: got NULL pointer", me); return NULL; } if (gageVolumeCheck(ctx, nin, kind)) { sprintf(err, "%s: problem with given volume", me); biffAdd(GAGE, err); return NULL; } pvl = (gagePerVolume *)calloc(1, sizeof(gagePerVolume)); if (!pvl) { sprintf(err, "%s: couldn't alloc gagePerVolume", me); biffAdd(GAGE, err); return NULL; } pvl->verbose = gageDefVerbose; pvl->kind = kind; GAGE_QUERY_RESET(pvl->query); pvl->needD[0] = pvl->needD[1] = pvl->needD[2] = AIR_FALSE; pvl->nin = nin; for (ii=gagePvlFlagUnknown+1; ii<gagePvlFlagLast; ii++) { pvl->flag[ii] = AIR_FALSE; } pvl->iv3 = pvl->iv2 = pvl->iv1 = NULL; pvl->lup = nrrdDLookup[nin->type]; pvl->answer = (double *)calloc(gageKindTotalAnswerLength(kind), sizeof(double)); pvl->directAnswer = (double **)calloc(kind->itemMax+1, sizeof(double*)); if (!(pvl->answer && pvl->directAnswer)) { sprintf(err, "%s: couldn't alloc answer and directAnswer arrays", me); biffAdd(GAGE, err); return NULL; } for (ii=1; ii<=kind->itemMax; ii++) { pvl->directAnswer[ii] = pvl->answer + gageKindAnswerOffset(kind, ii); } pvl->flag[gagePvlFlagVolume] = AIR_TRUE; if (kind->pvlDataNew) { if (!(pvl->data = kind->pvlDataNew(kind))) { sprintf(err, "%s: double creating gagePerVolume data", me); biffAdd(GAGE, err); return NULL; } } else { pvl->data = NULL; } return pvl; }
/* ** _gagePerVolumeCopy() ** ** copies a pervolume for use in a copied context, and probably ** should only be called by gageContextCopy() */ gagePerVolume * _gagePerVolumeCopy(gagePerVolume *pvl, unsigned int fd) { char me[]="gagePerVolumeCopy", err[BIFF_STRLEN]; gagePerVolume *nvl; int ii; nvl = (gagePerVolume *)calloc(1, sizeof(gagePerVolume)); if (!nvl) { sprintf(err, "%s: couldn't create new pervolume", me); biffAdd(GAGE, err); return NULL; } /* we should probably restrict ourselves to gage API calls, but given the constant state of gage construction, this seems much simpler. Pointers to per-pervolume-allocated arrays are fixed below */ memcpy(nvl, pvl, sizeof(gagePerVolume)); nvl->iv3 = (double *)calloc(fd*fd*fd*nvl->kind->valLen, sizeof(double)); nvl->iv2 = (double *)calloc(fd*fd*nvl->kind->valLen, sizeof(double)); nvl->iv1 = (double *)calloc(fd*nvl->kind->valLen, sizeof(double)); nvl->answer = (double *)calloc(gageKindTotalAnswerLength(nvl->kind), sizeof(double)); nvl->directAnswer = (double **)calloc(nvl->kind->itemMax+1, sizeof(double*)); if (!( nvl->iv3 && nvl->iv2 && nvl->iv1 && nvl->answer && nvl->directAnswer )) { sprintf(err, "%s: couldn't allocate all caches " "(fd=%u, valLen=%u, totAnsLen=%u, itemMax=%u)", me, fd, nvl->kind->valLen, gageKindTotalAnswerLength(nvl->kind), nvl->kind->itemMax); biffAdd(GAGE, err); return NULL; } for (ii=1; ii<=pvl->kind->itemMax; ii++) { nvl->directAnswer[ii] = nvl->answer + gageKindAnswerOffset(pvl->kind, ii); } if (pvl->kind->pvlDataCopy) { if (!(nvl->data = pvl->kind->pvlDataCopy(pvl->kind, pvl->data))) { sprintf(err, "%s: double copying gagePerVolume data", me); biffAdd(GAGE, err); return NULL; } } else { nvl->data = NULL; } return nvl; }
/* ******** miteThreadBegin() ** ** this has some of the body of what would be miteThreadInit */ int miteThreadBegin(miteThread **mttP, miteRender *mrr, miteUser *muu, int whichThread) { char me[]="miteThreadBegin", err[BIFF_STRLEN]; /* all the miteThreads have already been allocated */ (*mttP) = mrr->tt[whichThread]; if (!whichThread) { /* this is the first thread- it just points to the parent gageContext */ (*mttP)->gctx = muu->gctx0; } else { /* we have to generate a new gageContext */ (*mttP)->gctx = gageContextCopy(muu->gctx0); if (!(*mttP)->gctx) { sprintf(err, "%s: couldn't set up thread %d", me, whichThread); biffMove(MITE, err, GAGE); return 1; } } if (-1 != mrr->sclPvlIdx) { (*mttP)->ansScl = (*mttP)->gctx->pvl[mrr->sclPvlIdx]->answer; (*mttP)->nPerp = ((*mttP)->ansScl + gageKindAnswerOffset(gageKindScl, gageSclNPerp)); (*mttP)->geomTens = ((*mttP)->ansScl + gageKindAnswerOffset(gageKindScl, gageSclGeomTens)); } else { (*mttP)->ansScl = NULL; (*mttP)->nPerp = NULL; (*mttP)->geomTens = NULL; } (*mttP)->ansVec = (-1 != mrr->vecPvlIdx ? (*mttP)->gctx->pvl[mrr->vecPvlIdx]->answer : NULL); (*mttP)->ansTen = (-1 != mrr->tenPvlIdx ? (*mttP)->gctx->pvl[mrr->tenPvlIdx]->answer : NULL); (*mttP)->thrid = whichThread; (*mttP)->raySample = 0; (*mttP)->samples = 0; (*mttP)->verbose = 0; (*mttP)->skip = 0; (*mttP)->_normal = _miteAnswerPointer(*mttP, mrr->normalSpec); /* set up shading answers */ switch(mrr->shadeSpec->method) { case miteShadeMethodNone: /* nothing to do */ break; case miteShadeMethodPhong: (*mttP)->shadeVec0 = _miteAnswerPointer(*mttP, mrr->shadeSpec->vec0); break; case miteShadeMethodLitTen: (*mttP)->shadeVec0 = _miteAnswerPointer(*mttP, mrr->shadeSpec->vec0); (*mttP)->shadeVec1 = _miteAnswerPointer(*mttP, mrr->shadeSpec->vec1); (*mttP)->shadeScl0 = _miteAnswerPointer(*mttP, mrr->shadeSpec->scl0); (*mttP)->shadeScl1 = _miteAnswerPointer(*mttP, mrr->shadeSpec->scl1); break; default: sprintf(err, "%s: shade method %d not implemented!", me, mrr->shadeSpec->method); biffAdd(MITE, err); return 1; break; } if (_miteStageSet(*mttP, mrr)) { sprintf(err, "%s: trouble setting up stage array", me); biffAdd(MITE, err); return 1; } return 0; }