Example #1
0
int
main(int argc, char *argv[]) {
  char *me;
  hestOpt *hopt=NULL;
  airArray *mop;
  
  pushEnergySpec *ensp;
  unsigned int pi, xi, nn;
  double xx, supp, del;

  mop = airMopNew();
  me = argv[0];
  hestOptAdd(&hopt, "energy", "spec", airTypeOther, 1, 1, &ensp, NULL,
             "specification of force function to use",
             NULL, NULL, pushHestEnergySpec);
  hestParseOrDie(hopt, argc-1, argv+1, NULL,
                 me, info, AIR_TRUE, AIR_TRUE, AIR_TRUE);
  airMopAdd(mop, hopt, (airMopper)hestOptFree, airMopAlways);
  airMopAdd(mop, hopt, (airMopper)hestParseFree, airMopAlways);

  fprintf(stderr, "%s: parsed energy \"%s\", with %u parms.\n", me,
          ensp->energy->name, ensp->energy->parmNum);
  for (pi=0; pi<ensp->energy->parmNum; pi++) {
    fprintf(stderr, "%u: %g\n", pi, ensp->parm[pi]);
  }
  fprintf(stderr, "\n");

  nn = 600;
  supp = ensp->energy->support(ensp->parm);
  del = AIR_DELTA(0, 2, nn, 0, supp);
  for (xi=1; xi<nn; xi++) {
    double x0, x1, ee, ff, e0, e1, dummy;
    xx = AIR_AFFINE(0, xi,   nn, 0, supp);
    x1 = AIR_AFFINE(0, xi+1, nn, 0, supp);
    x0 = AIR_AFFINE(0, xi-1, nn, 0, supp);
    ensp->energy->eval(&e1, &dummy, x1, ensp->parm);
    ensp->energy->eval(&e0, &dummy, x0, ensp->parm);
    ensp->energy->eval(&ee, &ff, xx, ensp->parm);
    printf("%g %g %g %g\n", xx, ee, ff, (e1 - e0)/del);
  }

  airMopOkay(mop);
  return 0;
}
Example #2
0
void *
_hooverThreadBody(void *_arg) {
  _hooverThreadArg *arg;
  void *thread;
  int ret,               /* to catch return values from callbacks */
    sampleI,             /* which sample we're on */
    inside,              /* we're inside the volume */
    vI, uI;              /* integral coords in image */
  double tmp,
    mm,                  /* lowest position in index space, for all axes */
    Mx, My, Mz,          /* highest position in index space on each axis */
    u, v,                /* floating-point coords in image */
    uvScale,             /* how to scale (u,v) to go from image to 
                            near plane, according to ortho or perspective */
    lx, ly, lz,          /* half edge-lengths of volume */
    rayLen=0,            /* length of segment formed by ray line intersecting
                            the near and far clipping planes */
    rayT,                /* current position along ray (world-space) */
    rayDirW[3],          /* unit-length ray direction (world-space) */
    rayDirI[3],          /* rayDirW transformed into index space;
                            not unit length, but a unit change in
                            world space along rayDirW translates to
                            this change in index space along rayDirI */
    rayPosW[3],          /* current ray location (world-space) */
    rayPosI[3],          /* current ray location (index-space) */
    rayStartW[3],        /* ray start on near plane (world-space) */
    rayStartI[3],        /* ray start on near plane (index-space) */
    rayStep,             /* distance between samples (world-space) */
    vOff[3], uOff[3];    /* offsets in arg->ec->wU and arg->ec->wV
                            directions towards start of ray */

  arg = (_hooverThreadArg *)_arg;
  if ( (ret = (arg->ctx->threadBegin)(&thread, 
                                      arg->render, 
                                      arg->ctx->user,
                                      arg->whichThread)) ) {
    arg->errCode = ret;
    arg->whichErr = hooverErrThreadBegin;
    return arg;
  }
  lx = arg->ec->volHLen[0];
  ly = arg->ec->volHLen[1];
  lz = arg->ec->volHLen[2];
  if (nrrdCenterNode == arg->ctx->volCentering) {
    mm = 0;
    Mx = arg->ctx->volSize[0]-1;
    My = arg->ctx->volSize[1]-1;
    Mz = arg->ctx->volSize[2]-1;
  } else {
    mm = -0.5;
    Mx = arg->ctx->volSize[0]-0.5;
    My = arg->ctx->volSize[1]-0.5;
    Mz = arg->ctx->volSize[2]-0.5;
  }
  
  if (arg->ctx->cam->orthographic) {
    ELL_3V_COPY(rayDirW, arg->ctx->cam->N);
    rayDirI[0] = AIR_DELTA(-lx, rayDirW[0], lx, mm, Mx);
    rayDirI[1] = AIR_DELTA(-ly, rayDirW[1], ly, mm, My);
    rayDirI[2] = AIR_DELTA(-lz, rayDirW[2], lz, mm, Mz);
    rayLen = arg->ctx->cam->vspFaar - arg->ctx->cam->vspNeer;
    uvScale = 1.0;
  } else {
    uvScale = arg->ctx->cam->vspNeer/arg->ctx->cam->vspDist;
  }

  while (1) {
    /* the work assignment is simply the next scanline to be rendered:
       the result of all this is setting vI */
    if (arg->ctx->workMutex) {
      airThreadMutexLock(arg->ctx->workMutex);
    }
    vI = arg->ctx->workIdx;
    if (arg->ctx->workIdx < arg->ctx->imgSize[1]) {
      arg->ctx->workIdx += 1;
    }
    if (arg->ctx->workMutex) {
      airThreadMutexUnlock(arg->ctx->workMutex);
    }
    if (vI == arg->ctx->imgSize[1]) {
      /* we're done! */
      break;
    }

    if (nrrdCenterCell == arg->ctx->imgCentering) {
      v = uvScale*AIR_AFFINE(-0.5, vI, arg->ctx->imgSize[1]-0.5,
                             arg->ctx->cam->vRange[0],
                             arg->ctx->cam->vRange[1]);
    } else {
      v = uvScale*AIR_AFFINE(0.0, vI, arg->ctx->imgSize[1]-1.0,
                             arg->ctx->cam->vRange[0],
                             arg->ctx->cam->vRange[1]);
    }
    ELL_3V_SCALE(vOff, v, arg->ctx->cam->V);
    for (uI=0; uI<arg->ctx->imgSize[0]; uI++) {
      if (nrrdCenterCell == arg->ctx->imgCentering) {
        u = uvScale*AIR_AFFINE(-0.5, uI, arg->ctx->imgSize[0]-0.5,
                               arg->ctx->cam->uRange[0],
                               arg->ctx->cam->uRange[1]);
      } else {
        u = uvScale*AIR_AFFINE(0.0, uI, arg->ctx->imgSize[0]-1.0,
                               arg->ctx->cam->uRange[0],
                               arg->ctx->cam->uRange[1]);
      }
      ELL_3V_SCALE(uOff, u, arg->ctx->cam->U);
      ELL_3V_ADD3(rayStartW, uOff, vOff, arg->ec->rayZero);
      rayStartI[0] = AIR_AFFINE(-lx, rayStartW[0], lx, mm, Mx);
      rayStartI[1] = AIR_AFFINE(-ly, rayStartW[1], ly, mm, My);
      rayStartI[2] = AIR_AFFINE(-lz, rayStartW[2], lz, mm, Mz);
      if (!arg->ctx->cam->orthographic) {
        ELL_3V_SUB(rayDirW, rayStartW, arg->ctx->cam->from);
        ELL_3V_NORM(rayDirW, rayDirW, tmp);
        rayDirI[0] = AIR_DELTA(-lx, rayDirW[0], lx, mm, Mx);
        rayDirI[1] = AIR_DELTA(-ly, rayDirW[1], ly, mm, My);
        rayDirI[2] = AIR_DELTA(-lz, rayDirW[2], lz, mm, Mz);
        rayLen = ((arg->ctx->cam->vspFaar - arg->ctx->cam->vspNeer)/
                  ELL_3V_DOT(rayDirW, arg->ctx->cam->N));
      }
      if ( (ret = (arg->ctx->rayBegin)(thread,
                                       arg->render,
                                       arg->ctx->user,
                                       uI, vI, rayLen,
                                       rayStartW, rayStartI,
                                       rayDirW, rayDirI)) ) {
        arg->errCode = ret;
        arg->whichErr = hooverErrRayBegin;
        return arg;
      }
      
      sampleI = 0;
      rayT = 0;
      while (1) {
        ELL_3V_SCALE_ADD2(rayPosW, 1.0, rayStartW, rayT, rayDirW);
        ELL_3V_SCALE_ADD2(rayPosI, 1.0, rayStartI, rayT, rayDirI);
        inside = (AIR_IN_CL(mm, rayPosI[0], Mx) &&
                  AIR_IN_CL(mm, rayPosI[1], My) &&
                  AIR_IN_CL(mm, rayPosI[2], Mz));
        rayStep = (arg->ctx->sample)(thread,
                                     arg->render,
                                     arg->ctx->user,
                                     sampleI, rayT,
                                     inside,
                                     rayPosW, rayPosI);
        if (!AIR_EXISTS(rayStep)) {
          /* sampling failed */
          arg->errCode = 0;
          arg->whichErr = hooverErrSample;
          return arg;
        }
        if (!rayStep) {
          /* ray decided to finish itself */
          break;
        } 
        /* else we moved to a new location along the ray */
        rayT += rayStep;
        if (!AIR_IN_CL(0, rayT, rayLen)) {
          /* ray stepped outside near-far clipping region, its done. */
          break;
        }
        sampleI++;
      }
      
      if ( (ret = (arg->ctx->rayEnd)(thread,
                                     arg->render,
                                     arg->ctx->user)) ) {
        arg->errCode = ret;
        arg->whichErr = hooverErrRayEnd;
        return arg;
      }
    }  /* end this scanline */
  } /* end while(1) assignment of scanlines */

  if ( (ret = (arg->ctx->threadEnd)(thread,
                                    arg->render,
                                    arg->ctx->user)) ) {
    arg->errCode = ret;
    arg->whichErr = hooverErrThreadEnd;
    return arg;
  }
  
  /* returning NULL actually indicates that there was NOT an error */
  return NULL;
}