Esempio n. 1
0
int
miteRenderBegin(miteRender **mrrP, miteUser *muu) {
  static const char me[]="miteRenderBegin";
  gagePerVolume *pvl;
  int E, T, pvlIdx;
  gageQuery queryScl, queryVec, queryTen;
  gageItemSpec isp;
  unsigned int axi, thr;

  if (!(mrrP && muu)) {
    biffAddf(MITE, "%s: got NULL pointer", me);
    return 1;
  }
  if (_miteUserCheck(muu)) {
    biffAddf(MITE, "%s: problem with user-set parameters", me);
    return 1;
  }
  if (!( *mrrP = _miteRenderNew() )) {
    biffAddf(MITE, "%s: couldn't alloc miteRender", me);
    return 1;
  }
  if (_miteNtxfAlphaAdjust(*mrrP, muu)) {
    biffAddf(MITE, "%s: trouble copying and alpha-adjusting txfs", me);
    return 1;
  }

  GAGE_QUERY_RESET(queryScl);
  GAGE_QUERY_RESET(queryVec);
  GAGE_QUERY_RESET(queryTen);
  GAGE_QUERY_RESET((*mrrP)->queryMite);
  for (T=0; T<muu->ntxfNum; T++) {
    for (axi=1; axi<muu->ntxf[T]->dim; axi++) {
      miteVariableParse(&isp, muu->ntxf[T]->axis[axi].label);
      miteQueryAdd(queryScl, queryVec, queryTen, (*mrrP)->queryMite, &isp);
    }
  }
  miteVariableParse((*mrrP)->normalSpec, muu->normalStr);
  miteQueryAdd(queryScl, queryVec, queryTen, (*mrrP)->queryMite,
               (*mrrP)->normalSpec);
  miteShadeSpecParse((*mrrP)->shadeSpec, muu->shadeStr);
  miteShadeSpecQueryAdd(queryScl, queryVec, queryTen, (*mrrP)->queryMite,
                        (*mrrP)->shadeSpec);
  (*mrrP)->queryMiteNonzero = GAGE_QUERY_NONZERO((*mrrP)->queryMite);

  E = 0;
  pvlIdx = 0;
  if (muu->nsin) {
    if (!E) E |= !(pvl = gagePerVolumeNew(muu->gctx0, muu->nsin, gageKindScl));
    if (!E) E |= gageQuerySet(muu->gctx0, pvl, queryScl);
    if (!E) E |= gagePerVolumeAttach(muu->gctx0, pvl);
    if (!E) (*mrrP)->sclPvlIdx = pvlIdx++;
  }
  if (muu->nvin) {
    if (!E) E |= !(pvl = gagePerVolumeNew(muu->gctx0, muu->nvin, gageKindVec));
    if (!E) E |= gageQuerySet(muu->gctx0, pvl, queryVec);
    if (!E) E |= gagePerVolumeAttach(muu->gctx0, pvl);
    if (!E) (*mrrP)->vecPvlIdx = pvlIdx++;
  }
  if (muu->ntin) {
    if (!E) E |= !(pvl = gagePerVolumeNew(muu->gctx0, muu->ntin, tenGageKind));
    if (!E) E |= gageQuerySet(muu->gctx0, pvl, queryTen);
    if (!E) E |= gagePerVolumeAttach(muu->gctx0, pvl);
    if (!E) (*mrrP)->tenPvlIdx = pvlIdx++;
  }
  if (!E) E |= gageKernelSet(muu->gctx0, gageKernel00,
                             muu->ksp[gageKernel00]->kernel,
                             muu->ksp[gageKernel00]->parm);
  if (!E) E |= gageKernelSet(muu->gctx0, gageKernel11,
                             muu->ksp[gageKernel11]->kernel,
                             muu->ksp[gageKernel11]->parm);
  if (!E) E |= gageKernelSet(muu->gctx0, gageKernel22,
                             muu->ksp[gageKernel22]->kernel,
                             muu->ksp[gageKernel22]->parm);
  if (!E) E |= gageUpdate(muu->gctx0);
  if (E) {
    biffMovef(MITE, GAGE, "%s: gage trouble", me);
    return 1;
  }
  fprintf(stderr, "!%s: kernel support = %d^3 samples\n",
          me, 2*muu->gctx0->radius);

  if (nrrdMaybeAlloc_va(muu->nout, mite_nt, 3,
                        AIR_CAST(size_t, 5) /* RGBAZ */ ,
                        AIR_CAST(size_t, muu->hctx->imgSize[0]),
                        AIR_CAST(size_t, muu->hctx->imgSize[1]))) {
    biffMovef(MITE, NRRD, "%s: nrrd trouble", me);
    return 1;
  }
  muu->nout->axis[1].center = nrrdCenterCell;
  muu->nout->axis[1].min = muu->hctx->cam->uRange[0];
  muu->nout->axis[1].max = muu->hctx->cam->uRange[1];
  muu->nout->axis[2].center = nrrdCenterCell;
  muu->nout->axis[2].min = muu->hctx->cam->vRange[0];
  muu->nout->axis[2].max = muu->hctx->cam->vRange[1];

  for (thr=0; thr<muu->hctx->numThreads; thr++) {
    (*mrrP)->tt[thr] = miteThreadNew();
    if (!((*mrrP)->tt[thr])) {
      biffAddf(MITE, "%s: couldn't allocate thread[%d]", me, thr);
      return 1;
    }
    airMopAdd((*mrrP)->rmop, (*mrrP)->tt[thr],
              (airMopper)miteThreadNix, airMopAlways);
  }

  (*mrrP)->time0 = airTime();
  return 0;
}
Esempio n. 2
0
/*
** _miteStageSet
**
** ALLOCATES and initializes stage array in a miteThread
*/
int
_miteStageSet(miteThread *mtt, miteRender *mrr) {
  static const char me[]="_miteStageSet";
  char *value;
  int ni, di, stageIdx, rii, stageNum, ilog2;
  Nrrd *ntxf;
  miteStage *stage;
  gageItemSpec isp;
  char rc;

  stageNum = _miteStageNum(mrr);
  /* fprintf(stderr, "!%s: stageNum = %d\n", me, stageNum); */
  mtt->stage = AIR_CALLOC(stageNum, miteStage);
  if (!mtt->stage) {
    biffAddf(MITE, "%s: couldn't alloc array of %d stages", me, stageNum);
    return 1;
  }
  airMopAdd(mtt->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(&isp, ntxf->axis[di].label);
      stage->val = _miteAnswerPointer(mtt, &isp);
      stage->label = ntxf->axis[di].label;
      /*
      fprintf(stderr, "!%s: ans=%p + offset[%d]=%d == %p\n", me,
              mtt->ans, dom, kind->ansOffset[dom], stage->val);
      */
      stage->size = ntxf->axis[di].size;
      stage->min =  ntxf->axis[di].min;
      stage->max =  ntxf->axis[di].max;
      if (di > 1) {
        stage->data = NULL;
      } else {
        stage->data = (mite_t *)ntxf->data;
        value = nrrdKeyValueGet(ntxf, "miteStageOp");
        if (value) {
          stage->op = airEnumVal(miteStageOp, value);
          if (miteStageOpUnknown == stage->op) {
            stage->op = miteStageOpMultiply;
          }
        } else {
          stage->op = miteStageOpMultiply;
        }
        if (1 == isp.kind->table[isp.item].answerLength) {
          stage->qn = NULL;
        } else if (3 == isp.kind->table[isp.item].answerLength) {
          char stmp[AIR_STRLEN_SMALL];
          ilog2 = airLog2(ntxf->axis[di].size);
          switch(ilog2) {
          case 8:  stage->qn = limnVtoQN_d[ limnQN8octa]; break;
          case 9:  stage->qn = limnVtoQN_d[ limnQN9octa]; break;
          case 10: stage->qn = limnVtoQN_d[limnQN10octa]; break;
          case 11: stage->qn = limnVtoQN_d[limnQN11octa]; break;
          case 12: stage->qn = limnVtoQN_d[limnQN12octa]; break;
          case 13: stage->qn = limnVtoQN_d[limnQN13octa]; break;
          case 14: stage->qn = limnVtoQN_d[limnQN14octa]; break;
          case 15: stage->qn = limnVtoQN_d[limnQN15octa]; break;
          case 16: stage->qn = limnVtoQN_d[limnQN16octa]; break;
          default:
            biffAddf(MITE, "%s: txf axis %d size %s not usable for "
                     "vector txf domain variable %s", me, di,
                     airSprintSize_t(stmp, ntxf->axis[di].size),
                     ntxf->axis[di].label);
            return 1;
            break;
          }
        } else {
          biffAddf(MITE, "%s: %s not scalar or vector (len = %d): can't be "
                   "a txf domain variable", me,
                   ntxf->axis[di].label,
                   isp.kind->table[isp.item].answerLength);
          return 1;
        }
        stage->rangeNum = ntxf->axis[0].size;
        for (rii=0; rii<stage->rangeNum; rii++) {
          rc = ntxf->axis[0].label[rii];
          stage->rangeIdx[rii] = strchr(miteRangeChar, rc) - miteRangeChar;
          /*
          fprintf(stderr, "!%s: range: %c -> %d\n", "_miteStageSet",
                  ntxf->axis[0].label[rii], stage->rangeIdx[rii]);
          */
        }
      }
      stageIdx++;
    }
  }
  return 0;
}
Esempio n. 3
0
/*
******** miteShadeSpecParse
**
** set up a miteShadeSpec based on a string.  Valid forms are:
**
**   none
**   phong:<vector>
**   litten:<vector>,<vector>,<scalar>,<scalar>
**
** where <vector> and <scalar> are specifications of 3-vector and scalar
** parsable by miteVariableParse
*/
int
miteShadeSpecParse(miteShadeSpec *shpec, char *shadeStr) {
  static const char me[]="miteShadeSpecParse";
  char *buff, *qstr, *tok, *state;
  airArray *mop;
  int ansLength;

  mop = airMopNew();
  if (!( shpec && airStrlen(shadeStr) )) {
    biffAddf(MITE, "%s: got NULL pointer and/or empty string", me);
    airMopError(mop); return 1;
  }
  buff = airToLower(airStrdup(shadeStr));
  if (!buff) {
    biffAddf(MITE, "%s: couldn't strdup shading spec", me);
    airMopError(mop); return 1;
  }
  airMopAdd(mop, buff, airFree, airMopAlways);
  shpec->method = miteShadeMethodUnknown;
  if (!strcmp("none", buff)) {
    shpec->method = miteShadeMethodNone;
  } else if (buff == strstr(buff, "phong:")) {
    shpec->method = miteShadeMethodPhong;
    qstr = buff + strlen("phong:");
    if (miteVariableParse(shpec->vec0, qstr)) {
      biffAddf(MITE, "%s: couldn't parse \"%s\" as shading vector", me, qstr);
      airMopError(mop); return 1;
    }
    ansLength = shpec->vec0->kind->table[shpec->vec0->item].answerLength;
    if (3 != ansLength) {
      biffAddf(MITE, "%s: \"%s\" isn't a vector (answer length is %d, not 3)",
               me, qstr, ansLength);
      airMopError(mop); return 1;
    }
    shpec->method = miteShadeMethodPhong;
  } else if (buff == strstr(buff, "litten:")) {
    qstr = buff + strlen("litten:");
    /* ---- first vector */
    tok = airStrtok(qstr, ",", &state);
    if (miteVariableParse(shpec->vec0, tok)) {
      biffAddf(MITE, "%s: couldn't parse \"%s\" as first lit-tensor vector",
               me, tok);
      airMopError(mop); return 1;
    }
    ansLength = shpec->vec0->kind->table[shpec->vec0->item].answerLength;
    if (3 != ansLength) {
      biffAddf(MITE, "%s: \"%s\" isn't a vector (answer length is %d, not 3)",
               me, qstr, ansLength);
      airMopError(mop); return 1;
    }
    /* ---- second vector */
    tok = airStrtok(qstr, ",", &state);
    if (miteVariableParse(shpec->vec1, tok)) {
      biffAddf(MITE, "%s: couldn't parse \"%s\" as second lit-tensor vector",
               me, tok);
      airMopError(mop); return 1;
    }
    ansLength = shpec->vec1->kind->table[shpec->vec1->item].answerLength;
    if (3 != ansLength) {
      biffAddf(MITE, "%s: \"%s\" isn't a vector (answer length is %d, not 3)",
               me, qstr, ansLength);
      airMopError(mop); return 1;
    }
    /* ---- first scalar */
    tok = airStrtok(qstr, ",", &state);
    if (miteVariableParse(shpec->scl0, tok)) {
      biffAddf(MITE, "%s: couldn't parse \"%s\" as first lit-tensor scalar",
               me, tok);
      airMopError(mop); return 1;
    }
    ansLength = shpec->scl0->kind->table[shpec->scl0->item].answerLength;
    if (1 != ansLength) {
      biffAddf(MITE, "%s: \"%s\" isn't a scalar (answer length is %d, not 1)",
               me, qstr, ansLength);
      airMopError(mop); return 1;
    }
    /* ---- second scalar */
    tok = airStrtok(qstr, ",", &state);
    if (miteVariableParse(shpec->scl1, tok)) {
      biffAddf(MITE, "%s: couldn't parse \"%s\" as second lit-tensor scalar",
               me, tok);
      airMopError(mop); return 1;
    }
    ansLength = shpec->scl1->kind->table[shpec->scl1->item].answerLength;
    if (1 != ansLength) {
      biffAddf(MITE, "%s: \"%s\" isn't a scalar (answer length is %d, not 1)",
               me, qstr, ansLength);
      airMopError(mop); return 1;
    }
    shpec->method = miteShadeMethodLitTen;
  } else {
    biffAddf(MITE, "%s: shading specification \"%s\" not understood",
             me, shadeStr);
    airMopError(mop); return 1;
  }
  airMopOkay(mop);
  return 0;
}
Esempio n. 4
0
int
miteNtxfCheck(const Nrrd *ntxf) {
  static const char me[]="miteNtxfCheck";
  char *rangeStr, *domStr;
  gageItemSpec isp;
  unsigned int rii, axi;
  int ilog2;

  if (nrrdCheck(ntxf)) {
    biffMovef(MITE, NRRD, "%s: basic nrrd validity check failed", me);
    return 1;
  }
  if (!( nrrdTypeFloat == ntxf->type ||
         nrrdTypeDouble == ntxf->type ||
         nrrdTypeUChar == ntxf->type )) {
    biffAddf(MITE, "%s: need a type %s, %s or %s nrrd (not %s)", me,
             airEnumStr(nrrdType, nrrdTypeFloat),
             airEnumStr(nrrdType, nrrdTypeDouble),
             airEnumStr(nrrdType, nrrdTypeUChar),
             airEnumStr(nrrdType, ntxf->type));
    return 1;
  }
  if (!( 2 <= ntxf->dim )) {
    biffAddf(MITE, "%s: nrrd dim (%d) isn't at least 2 (for a 1-D txf)",
             me, ntxf->dim);
    return 1;
  }
  rangeStr = ntxf->axis[0].label;
  if (0 == airStrlen(rangeStr)) {
    biffAddf(MITE, "%s: axis[0]'s label doesn't specify txf range", me);
    return 1;
  }
  if (airStrlen(rangeStr) != ntxf->axis[0].size) {
    char stmp1[AIR_STRLEN_SMALL], stmp2[AIR_STRLEN_SMALL];
    biffAddf(MITE, "%s: axis[0]'s size %s, but label specifies %s values", me,
             airSprintSize_t(stmp1, ntxf->axis[0].size),
             airSprintSize_t(stmp2, airStrlen(rangeStr)));
    return 1;
  }
  for (rii=0; rii<airStrlen(rangeStr); rii++) {
    if (!strchr(miteRangeChar, rangeStr[rii])) {
      biffAddf(MITE, "%s: char %d of axis[0]'s label (\"%c\") isn't a valid "
               "transfer function range specifier (not in \"%s\")",
               me, rii, rangeStr[rii], miteRangeChar);
      return 1;
    }
  }
  for (axi=1; axi<ntxf->dim; axi++) {
    if (1 == ntxf->axis[axi].size) {
      biffAddf(MITE, "%s: # samples on axis %d must be > 1", me, axi);
      return 1;
    }
    domStr = ntxf->axis[axi].label;
    if (0 == airStrlen(domStr)) {
      biffAddf(MITE, "%s: axis[%d] of txf didn't specify a domain variable",
               me, axi);
      return 1;
    }
    if (miteVariableParse(&isp, domStr)) {
      biffAddf(MITE, "%s: couldn't parse txf domain \"%s\" for axis %d\n",
               me, domStr, axi);
      return 1;
    }
    if (!( 1 == isp.kind->table[isp.item].answerLength ||
           3 == isp.kind->table[isp.item].answerLength )) {
      biffAddf(MITE, "%s: %s (item %d) not a scalar or vector "
               "(answerLength = %d): "
               "can't be a txf domain variable", me, domStr, isp.item,
               isp.kind->table[isp.item].answerLength);
      return 1;
    }
    if (3 == isp.kind->table[isp.item].answerLength) {
      /* has to be right length for one of the quantization schemes */
      ilog2 = airLog2(ntxf->axis[axi].size);
      if (-1 == ilog2) {
        char stmp[AIR_STRLEN_SMALL];
        biffAddf(MITE, "%s: txf axis size for %s must be power of 2 (not %s)",
                 me, domStr, airSprintSize_t(stmp, ntxf->axis[axi].size));
        return 1;
      } else {
        if (!( AIR_IN_CL(8, ilog2, 16) )) {
          biffAddf(MITE, "%s: log_2 of txf axis size for %s should be in "
                   "range [8,16] (not %d)", me, domStr, ilog2);
          return 1;
        }
      }
    } else {
      if (!( AIR_EXISTS(ntxf->axis[axi].min) &&
             AIR_EXISTS(ntxf->axis[axi].max) )) {
        biffAddf(MITE, "%s: min and max of axis %d aren't both set", me, axi);
        return 1;
      }
      if (!( ntxf->axis[axi].min < ntxf->axis[axi].max )) {
        biffAddf(MITE, "%s: min (%g) not less than max (%g) on axis %d",
                 me, ntxf->axis[axi].min, ntxf->axis[axi].max, axi);
        return 1;
      }
    }
  }

  return 0;
}
Esempio n. 5
0
int
_miteUserCheck(miteUser *muu) {
  char me[]="miteUserCheck", err[BIFF_STRLEN];
  int T, gotOpac;
  gageItemSpec isp;
  gageQuery queryScl, queryVec, queryTen, queryMite;
  miteShadeSpec *shpec;
  airArray *mop;
  unsigned int axi;
  
  if (!muu) {
    sprintf(err, "%s: got NULL pointer", me);
    biffAdd(MITE, err); return 1;
  }
  mop = airMopNew();
  if (!( muu->ntxfNum >= 1 )) {
    sprintf(err, "%s: need at least one transfer function", me);
    biffAdd(MITE, err); airMopError(mop); return 1;
  }
  gotOpac = AIR_FALSE;
  GAGE_QUERY_RESET(queryScl);
  GAGE_QUERY_RESET(queryVec);
  GAGE_QUERY_RESET(queryTen);
  GAGE_QUERY_RESET(queryMite);  /* not actually used here */

  /* add on all queries associated with transfer functions */
  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);
      biffAdd(MITE, err); airMopError(mop); return 1;
    }
    /* NOTE: no error checking because miteNtxfCheck succeeded */
    for (axi=1; axi<muu->ntxf[T]->dim; axi++) {
      miteVariableParse(&isp, muu->ntxf[T]->axis[axi].label);
      miteQueryAdd(queryScl, queryVec, queryTen, queryMite, &isp);
    }
    gotOpac |= !!strchr(muu->ntxf[T]->axis[0].label, 'A');
  }
  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);
  }

  /* add on "normal"-based queries */
  if (airStrlen(muu->normalStr)) {
    miteVariableParse(&isp, muu->normalStr);
    if (miteValGageKind == isp.kind) {
      sprintf(err, "%s: normalStr \"%s\" refers to a miteVal "
              "(normal must be data-intrinsic)", me, muu->normalStr);
      biffAdd(MITE, err); airMopError(mop); return 1;
    }
    if (3 != isp.kind->table[isp.item].answerLength) {
      sprintf(err, "%s: %s not a vector: can't be used as normal",
              me, muu->normalStr);
      biffAdd(MITE, err); return 1;
    }
    miteQueryAdd(queryScl, queryVec, queryTen, queryMite, &isp);
  }

  /* add on shading-based queries */
  shpec = miteShadeSpecNew();
  airMopAdd(mop, shpec, (airMopper)miteShadeSpecNix, airMopAlways);
  if (miteShadeSpecParse(shpec, muu->shadeStr)) {
    sprintf(err, "%s: couldn't parse shading spec \"%s\"", 
            me, muu->shadeStr);
    biffAdd(MITE, err); airMopError(mop); return 1;
  }
  miteShadeSpecQueryAdd(queryScl, queryVec, queryTen, queryMite, shpec);

  /* see if anyone asked for an unspecified normal */
  if ((GAGE_QUERY_ITEM_TEST(queryMite, miteValNdotV)
       || GAGE_QUERY_ITEM_TEST(queryMite, miteValNdotL)
       || GAGE_QUERY_ITEM_TEST(queryMite, miteValVrefN))
      && !airStrlen(muu->normalStr)) {
    sprintf(err, "%s: txf or shading requested a miteVal's use of the "
            "\"normal\", but one has not been specified in muu->normalStr",
            me);
    biffAdd(MITE, err); airMopError(mop); return 1;
  }

  /* see if we have volumes for requested queries */
  if (GAGE_QUERY_NONZERO(queryScl) && !(muu->nsin)) {
    sprintf(err, "%s: txf or shading require %s volume, but don't have one",
            me, gageKindScl->name);
    biffAdd(MITE, err); airMopError(mop); return 1;
  }
  if (GAGE_QUERY_NONZERO(queryVec) && !(muu->nvin)) {
    sprintf(err, "%s: txf or shading require %s volume, but don't have one",
            me, gageKindVec->name);
    biffAdd(MITE, err); airMopError(mop); return 1;
  }
  if (GAGE_QUERY_NONZERO(queryTen) && !(muu->ntin)) {
    sprintf(err, "%s: txf or shading require %s volume, but don't have one",
            me, tenGageKind->name);
    biffAdd(MITE, err); airMopError(mop); return 1;
  }

  /* check appropriateness of given volumes */
  if (muu->nsin) {
    if (gageVolumeCheck(muu->gctx0, muu->nsin, gageKindScl)) {
      sprintf(err, "%s: trouble with input %s volume",
              me, gageKindScl->name);
      biffMove(MITE, err, GAGE); airMopError(mop); return 1;
    }
  }
  if (muu->nvin) {
    if (gageVolumeCheck(muu->gctx0, muu->nvin, gageKindVec)) {
      sprintf(err, "%s: trouble with input %s volume", 
              me, gageKindVec->name);
      biffMove(MITE, err, GAGE); airMopError(mop); return 1;
    }
  }
  if (muu->ntin) {
    if (gageVolumeCheck(muu->gctx0, muu->ntin, tenGageKind)) {
      sprintf(err, "%s: trouble with input %s volume", 
              me, tenGageKind->name);
      biffMove(MITE, err, GAGE); airMopError(mop); return 1;
    }
  }

  if (!muu->nout) {
    sprintf(err, "%s: rendered image nrrd is NULL", me);
    biffAdd(MITE, err); airMopError(mop); return 1;
  }
  airMopOkay(mop); 
  return 0;
}