示例#1
0
echoObject *
echoRoughSphereNew(echoScene *scene, int theRes, int phiRes, echoPos_t *matx) {
  echoObject *trim;
  echoPos_t *_pos, *pos, tmp[3];
  int *_vert, *vert, thidx, phidx, n;
  echoPos_t th, ph;

  trim = echoObjectNew(scene, echoTypeTriMesh);
  TRIMESH(trim)->numV = 2 + (phiRes-1)*theRes;
  TRIMESH(trim)->numF = (2 + 2*(phiRes-2))*theRes;

  _pos = pos = (echoPos_t *)calloc(3*TRIMESH(trim)->numV, sizeof(echoPos_t));
  _vert = vert = (int *)calloc(3*TRIMESH(trim)->numF, sizeof(int));

  ELL_3V_SET(tmp, 0, 0, 1); _echoPosSet(pos, matx, tmp); pos += 3;
  for (phidx=1; phidx<phiRes; phidx++) {
    ph = AIR_AFFINE(0, phidx, phiRes, 0.0, AIR_PI);
    for (thidx=0; thidx<theRes; thidx++) {
      th = AIR_AFFINE(0, thidx, theRes, 0.0, 2*AIR_PI);
      ELL_3V_SET(tmp, cos(th)*sin(ph), sin(th)*sin(ph), cos(ph));
      _echoPosSet(pos, matx, tmp); pos += 3;
    }
  }
  ELL_3V_SET(tmp, 0, 0, -1); _echoPosSet(pos, matx, tmp);

  for (thidx=0; thidx<theRes; thidx++) {
    n = AIR_MOD(thidx+1, theRes);
    ELL_3V_SET(vert, 0, 1+thidx, 1+n); vert += 3;
  }
  for (phidx=0; phidx<phiRes-2; phidx++) {
    for (thidx=0; thidx<theRes; thidx++) {
      n = AIR_MOD(thidx+1, theRes);
      ELL_3V_SET(vert, 1+phidx*theRes+thidx, 1+(1+phidx)*theRes+thidx,
                 1+phidx*theRes+n); vert += 3;
      ELL_3V_SET(vert, 1+(1+phidx)*theRes+thidx, 1+(1+phidx)*theRes+n, 
                 1+phidx*theRes+n); vert += 3;
    }
  }
  for (thidx=0; thidx<theRes; thidx++) {
    n = AIR_MOD(thidx+1, theRes);
    ELL_3V_SET(vert, 1+(phiRes-2)*theRes+thidx, TRIMESH(trim)->numV-1,
               1+(phiRes-2)*theRes+n); 
    vert += 3;
  }

  echoTriMeshSet(trim, TRIMESH(trim)->numV, _pos, TRIMESH(trim)->numF, _vert);
  return(trim);
}
示例#2
0
void
_limnSplineIndexFind(int *idx, limnSpline *spline, int ii) {
  int N, ti[4];

  N = spline->ncpt->axis[2].size;
  if (limnSplineTypeHasImplicitTangents[spline->type]) {
    if (spline->loop) {
      ELL_4V_SET(ti,
                 AIR_MOD(ii-1, N),
                 AIR_MOD(ii+0, N),
                 AIR_MOD(ii+1, N),
                 AIR_MOD(ii+2, N));
    } else {
      ELL_4V_SET(ti,
                 AIR_CLAMP(0, ii-1, N-1),
                 AIR_CLAMP(0, ii+0, N-1),
                 AIR_CLAMP(0, ii+1, N-1),
                 AIR_CLAMP(0, ii+2, N-1));
    }
    ELL_4V_SET(idx, 1 + 3*ti[0], 1 + 3*ti[1], 1 + 3*ti[2], 1 + 3*ti[3]);
  } else {
    if (spline->loop) {
      ELL_4V_SET(ti,
                 AIR_MOD(ii+0, N),
                 AIR_MOD(ii+0, N),
                 AIR_MOD(ii+1, N),
                 AIR_MOD(ii+1, N));
    } else {
      ELL_4V_SET(ti,
                 AIR_CLAMP(0, ii+0, N-1),
                 AIR_CLAMP(0, ii+0, N-1),
                 AIR_CLAMP(0, ii+1, N-1),
                 AIR_CLAMP(0, ii+1, N-1));
    }
    ELL_4V_SET(idx, 1 + 3*ti[0], 2 + 3*ti[1], 0 + 3*ti[2], 1 + 3*ti[3]);
  }
}
示例#3
0
/*
** _nrrdResampleMakeWeightIndex()
**
** _allocate_ and fill the arrays of indices and weights that are
** needed to process all the scanlines along a given axis; also
** be so kind as to set the sampling ratio (<1: downsampling,
** new sample spacing larger, >1: upsampling, new sample spacing smaller)
**
** returns "dotLen", the number of input samples which are required
** for resampling this axis, or 0 if there was an error.  Uses biff.
*/
int
_nrrdResampleMakeWeightIndex(nrrdResample_t **weightP,
                             int **indexP, double *ratioP,
                             const Nrrd *nin, const NrrdResampleInfo *info,
                             unsigned int ai) {
  char me[]="_nrrdResampleMakeWeightIndex", err[BIFF_STRLEN];
  int sizeIn, sizeOut, center, dotLen, halfLen, *index, base, idx;
  nrrdResample_t minIn, maxIn, minOut, maxOut, spcIn, spcOut,
    ratio, support, integral, pos, idxD, wght;
  nrrdResample_t *weight;
  double parm[NRRD_KERNEL_PARMS_NUM];

  int e, i;

  if (!(info->kernel[ai])) {
    sprintf(err, "%s: don't see a kernel for dimension %d", me, ai);
    biffAdd(NRRD, err); *weightP = NULL; *indexP = NULL; return 0;
  }

  center = _nrrdCenter(nin->axis[ai].center);
  sizeIn = nin->axis[ai].size;
  sizeOut = info->samples[ai];
  minIn = AIR_CAST(nrrdResample_t, nin->axis[ai].min);
  maxIn = AIR_CAST(nrrdResample_t, nin->axis[ai].max);
  minOut = AIR_CAST(nrrdResample_t, info->min[ai]);
  maxOut = AIR_CAST(nrrdResample_t, info->max[ai]);
  spcIn = NRRD_SPACING(center, minIn, maxIn, sizeIn);
  spcOut = NRRD_SPACING(center, minOut, maxOut, sizeOut);
  *ratioP = ratio = spcIn/spcOut;
  support = AIR_CAST(nrrdResample_t,
                     info->kernel[ai]->support(info->parm[ai]));
  integral = AIR_CAST(nrrdResample_t,
                      info->kernel[ai]->integral(info->parm[ai]));
  /*
  fprintf(stderr, 
          "!%s(%d): size{In,Out} = %d, %d, support = %f; ratio = %f\n", 
          me, d, sizeIn, sizeOut, support, ratio);
  */
  if (ratio > 1) {
    /* if upsampling, we need only as many samples as needed for
       interpolation with the given kernel */
    dotLen = (int)(2*ceil(support));
  } else {
    /* if downsampling, we need to use all the samples covered by
       the stretched out version of the kernel */
    if (info->cheap) {
      dotLen = (int)(2*ceil(support));
    } else {
      dotLen = (int)(2*ceil(support/ratio));
    }
  }
  /*
  fprintf(stderr, "!%s(%d): dotLen = %d\n", me, d, dotLen);
  */

  weight = (nrrdResample_t*)calloc(sizeOut*dotLen, sizeof(nrrdResample_t));
  index = (int*)calloc(sizeOut*dotLen, sizeof(int));
  if (!(weight && index)) {
    sprintf(err, "%s: can't allocate weight and index arrays", me);
    biffAdd(NRRD, err); *weightP = NULL; *indexP = NULL; return 0;
  }

  /* calculate sample locations and do first pass on indices */
  halfLen = dotLen/2;
  for (i=0; i<sizeOut; i++) {
    pos = AIR_CAST(nrrdResample_t,
                   NRRD_POS(center, minOut, maxOut, sizeOut, i));
    idxD = AIR_CAST(nrrdResample_t,
                    NRRD_IDX(center, minIn, maxIn, sizeIn, pos));
    base = (int)floor(idxD) - halfLen + 1;
    for (e=0; e<dotLen; e++) {
      index[e + dotLen*i] = base + e;
      weight[e + dotLen*i] = idxD - index[e + dotLen*i];
    }
    /* ********
    if (!i) {
      fprintf(stderr, "%s: sample locations:\n", me);
    }
    fprintf(stderr, "%s: %d (sample locations)\n        ", me, i);
    for (e=0; e<dotLen; e++) {
      fprintf(stderr, "%d/%g ", index[e + dotLen*i], weight[e + dotLen*i]);
    }
    fprintf(stderr, "\n");
    ******** */
  }

  /*
  nrrdBoundaryPad,      1: fill with some user-specified value
  nrrdBoundaryBleed,    2: copy the last/first value out as needed
  nrrdBoundaryWrap,     3: wrap-around
  nrrdBoundaryWeight,   4: normalize the weighting on the existing samples;
                        ONLY sensible for a strictly positive kernel
                        which integrates to unity (as in blurring)
  */

  /* figure out what to do with the out-of-range indices */
  for (i=0; i<dotLen*sizeOut; i++) {
    idx = index[i];
    if (!AIR_IN_CL(0, idx, sizeIn-1)) {
      switch(info->boundary) {
      case nrrdBoundaryPad:
      case nrrdBoundaryWeight:  /* this will be further handled later */
        idx = sizeIn;
        break;
      case nrrdBoundaryBleed:
        idx = AIR_CLAMP(0, idx, sizeIn-1);
        break;
      case nrrdBoundaryWrap:
        idx = AIR_MOD(idx, sizeIn);
        break;
      default:
        sprintf(err, "%s: boundary behavior %d unknown/unimplemented", 
                me, info->boundary);
        biffAdd(NRRD, err); *weightP = NULL; *indexP = NULL; return 0;
      }
      index[i] = idx;
    }
  }

  /* run the sample locations through the chosen kernel.  We play a 
     sneaky trick on the kernel parameter 0 in case of downsampling
     to create the blurring of the old index space, but only if !cheap */
  memcpy(parm, info->parm[ai], NRRD_KERNEL_PARMS_NUM*sizeof(double));
  if (ratio < 1 && !(info->cheap)) {
    parm[0] /= ratio;
  }
  info->kernel[ai]->EVALN(weight, weight, dotLen*sizeOut, parm);

  /* ********
  for (i=0; i<sizeOut; i++) {
    fprintf(stderr, "%s: %d (sample weights)\n        ", me, i);
    for (e=0; e<dotLen; e++) {
      fprintf(stderr, "%d/%g ", index[e + dotLen*i], weight[e + dotLen*i]);
    }
    fprintf(stderr, "\n");
  }
  ******** */

  if (nrrdBoundaryWeight == info->boundary) {
    if (integral) {
      /* above, we set to sizeIn all the indices that were out of 
         range.  We now use that to determine the sum of the weights
         for the indices that were in-range */
      for (i=0; i<sizeOut; i++) {
        wght = 0;
        for (e=0; e<dotLen; e++) {
          if (sizeIn != index[e + dotLen*i]) {
            wght += weight[e + dotLen*i];
          }
        }
        for (e=0; e<dotLen; e++) {
          idx = index[e + dotLen*i];
          if (sizeIn != idx) {
            weight[e + dotLen*i] *= integral/wght;
          } else {
            weight[e + dotLen*i] = 0;
          }
        }
      }
    }
  } else {
    /* try to remove ripple/grating on downsampling */
    /* if (ratio < 1 && info->renormalize && integral) { */
    if (info->renormalize && integral) {
      for (i=0; i<sizeOut; i++) {
        wght = 0;
        for (e=0; e<dotLen; e++) {
          wght += weight[e + dotLen*i];
        }
        if (wght) {
          for (e=0; e<dotLen; e++) {
            /* this used to normalize the weights so that they summed
               to integral ("*= integral/wght"), which meant that if
               you use a very truncated Gaussian, then your over-all
               image brightness goes down.  This seems very contrary
               to the whole point of renormalization. */
            weight[e + dotLen*i] *= AIR_CAST(nrrdResample_t, 1.0/wght);
          }
        }
      }
    }
  }
  /* ********
  fprintf(stderr, "%s: sample weights:\n", me);
  for (i=0; i<sizeOut; i++) {
    fprintf(stderr, "%s: %d\n        ", me, i);
    wght = 0;
    for (e=0; e<dotLen; e++) {
      fprintf(stderr, "%d/%g ", index[e + dotLen*i], weight[e + dotLen*i]);
      wght += weight[e + dotLen*i];
    }
    fprintf(stderr, " (sum = %g)\n", wght);
  }
  ******** */

  *weightP = weight;
  *indexP = index;
  /*
  fprintf(stderr, "!%s: dotLen = %d\n", me, dotLen);
  */
  return dotLen;
}
示例#4
0
/*
** _nrrdResampleComputePermute()
**
** figures out information related to how the axes in a nrrd are
** permuted during resampling: permute, topRax, botRax, passes, ax[][], sz[][]
*/
void
_nrrdResampleComputePermute(unsigned int permute[], 
                            unsigned int ax[NRRD_DIM_MAX][NRRD_DIM_MAX], 
                            size_t sz[NRRD_DIM_MAX][NRRD_DIM_MAX], 
                            int *topRax,
                            int *botRax,
                            unsigned int *passes,
                            const Nrrd *nin,
                            const NrrdResampleInfo *info) {
  /* char me[]="_nrrdResampleComputePermute"; */
  unsigned int bi, ai, pi;
  
  /* what are the first (top) and last (bottom) axes being resampled? */
  *topRax = *botRax = -1;
  for (ai=0; ai<nin->dim; ai++) {
    if (info->kernel[ai]) {
      if (*topRax < 0) {
        *topRax = ai;
      }
      *botRax = ai;
    }
  }

  /* figure out total number of passes needed, and construct the
     permute[] array.  permute[i] = j means that the axis in position
     i of the old array will be in position j of the new one
     (permute[] answers "where do I put this", not "what do I put here").
  */
  *passes = bi = 0;
  for (ai=0; ai<nin->dim; ai++) {
    if (info->kernel[ai]) {
      do {
        bi = AIR_MOD((int)bi+1, (int)nin->dim); /* HEY scrutinize casts */
      } while (!info->kernel[bi]);
      permute[bi] = ai;
      *passes += 1;
    } else {
      permute[ai] = ai;
      bi += bi == ai;
    }
  }
  permute[nin->dim] = nin->dim;
  if (!*passes) {
    /* none of the kernels was non-NULL */
    return;
  }
  
  /*
  fprintf(stderr, "%s: permute:\n", me);
  for (d=0; d<nin->dim; d++) {
    fprintf(stderr, "   permute[%d] = %d\n", d, permute[ai]);
  }
  */

  /* create array of how the axes will be arranged in each pass ("ax"), 
     and create array of how big each axes is in each pass ("sz").
     The input to pass i will have axis layout described in ax[i] and
     axis sizes described in sz[i] */
  for (ai=0; ai<nin->dim; ai++) {
    ax[0][ai] = ai;
    sz[0][ai] = nin->axis[ai].size;
  }
  for (pi=0; pi<*passes; pi++) {
    for (ai=0; ai<nin->dim; ai++) {
      ax[pi+1][permute[ai]] = ax[pi][ai];
      if (ai == (unsigned int)*topRax) {  /* HEY scrutinize casts */
        /* this is the axis which is getting resampled, 
           so the number of samples is potentially changing */
        sz[pi+1][permute[ai]] = (info->kernel[ax[pi][ai]]
                                 ? info->samples[ax[pi][ai]]
                                 : sz[pi][ai]);
      } else {
        /* this axis is just a shuffled version of the
           previous axis; no resampling this pass.
           Note: this case also includes axes which aren't 
           getting resampled whatsoever */
        sz[pi+1][permute[ai]] = sz[pi][ai];
      }
    }
  }

  return;
}
示例#5
0
void *
_alanTuringWorker(void *_task) {
  alan_t *tendata, *ten, react,
    conf, Dxx, Dxy, Dyy, /* Dxz, Dyz, */
    *tpx, *tmx, *tpy, *tmy, /* *tpz, *tmz, */
    *lev0, *lev1, *parm, deltaT, alpha, beta, A, B,
    *v[27], lapA, lapB, corrA, corrB, 
    deltaA, deltaB, diffA, diffB, change;
  int dim, iter, stop, startW, endW, idx,
    px, mx, py, my, pz, mz,
    startY, endY, startZ, endZ, sx, sy, sz, x, y, z;
  alanTask *task;

  task = (alanTask *)_task;
  dim = task->actx->dim;
  sx = task->actx->size[0];
  sy = task->actx->size[1];
  sz = (2 == dim ? 1 : task->actx->size[2]);
  parm = (alan_t*)(task->actx->nparm->data);
  diffA = AIR_CAST(alan_t, task->actx->diffA/pow(task->actx->deltaX, dim));
  diffB = AIR_CAST(alan_t, task->actx->diffB/pow(task->actx->deltaX, dim));
  startW = task->idx*sy/task->actx->numThreads;
  endW = (task->idx+1)*sy/task->actx->numThreads;
  tendata = task->actx->nten ? (alan_t *)task->actx->nten->data : NULL;
  react = task->actx->react;

  if (2 == dim) {
    startZ = 0;
    endZ = 1;
    startY = startW;
    endY = endW;
  } else {
    startZ = startW;
    endZ = endW;
    startY = 0;
    endY = sy;
  }

  for (iter = 0; 
       (alanStopNot == task->actx->stop 
        && (0 == task->actx->maxIteration
            || iter < task->actx->maxIteration)); 
       iter++) {

    if (0 == task->idx) {
      task->actx->iter = iter;
      task->actx->nlev = task->actx->_nlev[(iter+1) % 2];
    }
    lev0 = (alan_t*)(task->actx->_nlev[iter % 2]->data);
    lev1 = (alan_t*)(task->actx->_nlev[(iter+1) % 2]->data);
    stop = alanStopNot;
    change = 0;
    conf = 1;  /* if you have no data; this will stay 1 */
    for (z = startZ; z < endZ; z++) {
      if (task->actx->wrap) {
        pz = AIR_MOD(z+1, sz);
        mz = AIR_MOD(z-1, sz);
      } else {
        pz = AIR_MIN(z+1, sz-1);
        mz = AIR_MAX(z-1, 0);
      }
      for (y = startY; y < endY; y++) {
        if (task->actx->wrap) {
          py = AIR_MOD(y+1, sy);
          my = AIR_MOD(y-1, sy);
        } else {
          py = AIR_MIN(y+1, sy-1);
          my = AIR_MAX(y-1, 0);
        }
        for (x = 0; x < sx; x++) {
          if (task->actx->wrap) {
            px = AIR_MOD(x+1, sx);
            mx = AIR_MOD(x-1, sx);
          } else {
            px = AIR_MIN(x+1, sx-1);
            mx = AIR_MAX(x-1, 0);
          }
          idx = x + sx*(y + sy*z);
          A = lev0[0 + 2*idx];
          B = lev0[1 + 2*idx];
          deltaT = parm[0 + 3*idx];
          alpha = parm[1 + 3*idx];
          beta = parm[2 + 3*idx];
          lapA = lapB = corrA = corrB = 0;
          if (2 == dim) {
            /*
            **  0 1 2 ----> X
            **  3 4 5
            **  6 7 8
            **  |
            **  v Y
            */
            v[1] = lev0 + 2*( x + sx*(my));
            v[3] = lev0 + 2*(mx + sx*( y));
            v[5] = lev0 + 2*(px + sx*( y));
            v[7] = lev0 + 2*( x + sx*(py));
            if (tendata) {
              /*
              **  0 1 2    Dxy/2          Dyy        -Dxy/2
              **  3 4 5     Dxx     -2*(Dxx + Dyy)     Dxx
              **  6 7 8   -Dxy/2          Dyy         Dxy/2
              */
              v[0] = lev0 + 2*(mx + sx*(my));
              v[2] = lev0 + 2*(px + sx*(my));
              v[6] = lev0 + 2*(mx + sx*(py));
              v[8] = lev0 + 2*(px + sx*(py));
              ten = tendata + 4*idx;
              conf = AIR_CAST(alan_t, (AIR_CLAMP(0.3, ten[0], 1) - 0.3)/0.7);
              if (conf) {
                Dxx = ten[1];
                Dxy = ten[2];
                Dyy = ten[3];
                lapA = (Dxy*(v[0][0] + v[8][0] - v[2][0] - v[6][0])/2
                        + Dxx*(v[3][0] + v[5][0]) + Dyy*(v[1][0] + v[7][0])
                        - 2*(Dxx + Dyy)*A);
                lapB = (Dxy*(v[0][1] + v[8][1] - v[2][1] - v[6][1])/2
                        + Dxx*(v[3][1] + v[5][1]) + Dyy*(v[1][1] + v[7][1])
                        - 2*(Dxx + Dyy)*B);
                if (!(task->actx->homogAniso)) {
                  tpx = tendata + 4*(px + sx*( y + sy*( z)));
                  tmx = tendata + 4*(mx + sx*( y + sy*( z)));
                  tpy = tendata + 4*( x + sx*(py + sy*( z)));
                  tmy = tendata + 4*( x + sx*(my + sy*( z)));
                  corrA = ((tpx[1]-tmx[1])*(v[5][0]-v[3][0])/4+ /* Dxx,x*A,x */
                           (tpx[2]-tmx[2])*(v[7][0]-v[1][0])/4+ /* Dxy,x*A,y */
                           (tpy[2]-tmy[2])*(v[5][0]-v[3][0])/4+ /* Dxy,y*A,x */
                           (tpy[3]-tmy[3])*(v[7][0]-v[1][0]));  /* Dyy,y*A,y */
                  corrB = ((tpx[1]-tmx[1])*(v[5][1]-v[3][1])/4+ /* Dxx,x*B,x */
                           (tpx[2]-tmx[2])*(v[7][1]-v[1][1])/4+ /* Dxy,x*B,y */
                           (tpy[2]-tmy[2])*(v[5][1]-v[3][1])/4+ /* Dxy,y*B,x */
                           (tpy[3]-tmy[3])*(v[7][1]-v[1][1]));  /* Dyy,y*B,y */
                }
              } else {
                /* no confidence; you diffuse */
                lapA = v[1][0] + v[3][0] + v[5][0] + v[7][0] - 4*A;
                lapB = v[1][1] + v[3][1] + v[5][1] + v[7][1] - 4*B;
              }
            } else {
              /* no data; you diffuse */
              lapA = v[1][0] + v[3][0] + v[5][0] + v[7][0] - 4*A;
              lapB = v[1][1] + v[3][1] + v[5][1] + v[7][1] - 4*B;
            }
          } else {
            /* 3 == dim */
            /*
            **          0   1   2   ---- X
            **        3   4   5
            **      6   7   8
            **    /
            **  /       9  10  11
            ** Y     12  13  14
            **     15  16  17
            **
            **         18  19  20
            **       21  22  23
            **     24  25  26
            **         |
            **         |
            **         Z
            */
            v[ 4] = lev0 + 2*( x + sx*( y + sy*(mz)));
            v[10] = lev0 + 2*( x + sx*(my + sy*( z)));
            v[12] = lev0 + 2*(mx + sx*( y + sy*( z)));
            v[14] = lev0 + 2*(px + sx*( y + sy*( z)));
            v[16] = lev0 + 2*( x + sx*(py + sy*( z)));
            v[22] = lev0 + 2*( x + sx*( y + sy*(pz)));
            if (tendata) {

              if (!(task->actx->homogAniso)) {
                
              }
            } else {
              lapA = (v[ 4][0] + v[10][0] + v[12][0]
                      + v[14][0] + v[16][0] + v[22][0] - 6*A);
              lapB = (v[ 4][1] + v[10][1] + v[12][1]
                      + v[14][1] + v[16][1] + v[22][1] - 6*B);
            }
          }
          
          deltaA = deltaT*(react*conf*task->actx->K*(alpha - A*B) 
                           + diffA*(lapA + corrA));
          if (AIR_ABS(deltaA) > task->actx->maxPixelChange) {
            stop = alanStopDiverged;
          }
          change += AIR_ABS(deltaA);
          deltaB = deltaT*(react*conf*task->actx->K*(A*B - B - beta)
                           + diffB*(lapB + corrB));
          if (!( AIR_EXISTS(deltaA) && AIR_EXISTS(deltaB) )) {
            stop = alanStopNonExist;
          }
          
          A += deltaA;
          B = AIR_MAX(0, B + deltaB);
          lev1[0 + 2*idx] = A;
          lev1[1 + 2*idx] = B; 
        }
      }
    }
    
    /* add change to global sum in a threadsafe way */
    airThreadMutexLock(task->actx->changeMutex);
    task->actx->averageChange += change/(sx*sy*sz);
    task->actx->changeCount += 1;
    if (task->actx->changeCount == task->actx->numThreads) {
      /* I must be the last thread to reach this point; all 
         others must have passed the mutex unlock, and are
         sitting at the barrier */
      if (alanStopNot != stop) {
        /* there was some problem in going from lev0 to lev1, which
           we deal with now by setting actx->stop */
        task->actx->stop = stop;
      } else if (task->actx->averageChange < task->actx->minAverageChange) {
        /* we converged */
        task->actx->stop = alanStopConverged;
      } else {
        /* we keep going */
        _alanPerIteration(task->actx, iter);
        if (task->actx->perIteration) {
          task->actx->perIteration(task->actx, iter);
        }
      }
      task->actx->averageChange = 0;
      task->actx->changeCount = 0;
    }
    airThreadMutexUnlock(task->actx->changeMutex);

    /* force all threads to line up here, once per iteration */
    airThreadBarrierWait(task->actx->iterBarrier);
  }
  
  if (iter == task->actx->maxIteration) {
    /* HEY: all threads will agree on this, right? */
    task->actx->stop = alanStopMaxIteration;
  }
  /* else: the non-alanStopNot value of task->actx->stop made us stop */
  return _task;
}
示例#6
0
文件: arith.c 项目: BRAINSia/teem
static double _nrrdBinaryOpMod(double a, double b) {
  return AIR_MOD((int)a,(int)b);}
示例#7
0
int
main(int argc, char *argv[]) {
  char *me, *err;
  limnSpline *spline, *warp;
  hestOpt *hopt=NULL;
  airArray *mop;
  int i, M, ret, pause, loop;
  Nrrd *nout, *ntmp;
  double *out, minT, maxT, scale, tran[2];

  mop = airMopNew();
  
  me = argv[0];
  hestOptAdd(&hopt, "i", "spline", airTypeOther, 1, 1, &spline, NULL,
             "the spline that we want to sample", NULL, NULL, limnHestSpline);
  hestOptAdd(&hopt, "w", "timewarp", airTypeOther, 1, 1, &warp, "",
             "how to (optionally) warp the spline domain",
             NULL, NULL, limnHestSpline);
  hestOptAdd(&hopt, "loop", NULL, airTypeInt, 0, 0, &loop, NULL,
             "the last control point is in fact the first");
  hestOptAdd(&hopt, "m", "M", airTypeInt, 1, 1, &M, "512",
             "the number of sample points at which to evalute the spline");
  hestOptAdd(&hopt, "t", "tx ty", airTypeDouble, 2, 2, tran, "0.0 0.0",
             "translation for drawing");
  hestOptAdd(&hopt, "s", "scale", airTypeDouble, 1, 1, &scale, "1.0",
             "scaling for drawing");
  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);

  spline->loop = loop;
  if (!( limnSplineInfo2Vector == spline->info )) {
    fprintf(stderr, "%s: sorry, can only have %s info for PostScript\n",
            me, airEnumStr(limnSplineInfo, limnSplineInfo2Vector));
    airMopError(mop);
    return 1;
  }
  if (warp) {
    warp->loop = loop;
    if (!( limnSplineTypeTimeWarp == warp->type )) {
      fprintf(stderr, "%s: %s spline isn't; its %s\n", me,
              airEnumStr(limnSplineType, limnSplineTypeTimeWarp),
              airEnumStr(limnSplineType, warp->type));
      airMopError(mop);
      return 1;
    }
    if (loop) {
      if (!( limnSplineNumPoints(warp) == 1 + limnSplineNumPoints(spline) )) {
        fprintf(stderr, "%s: # warp points (%d) needs to be 1 more than "
                "# spline points (%d) for looping\n", me, 
                limnSplineNumPoints(warp), limnSplineNumPoints(spline));
        airMopError(mop);
        return 1;
      }
    } else {
      if (!( limnSplineNumPoints(warp) ==  limnSplineNumPoints(spline) )) {
        fprintf(stderr, "%s: # warp points (%d) != # spline points (%d)\n", me,
                limnSplineNumPoints(warp), limnSplineNumPoints(spline));
                
        airMopError(mop);
        return 1;
      }
    }
  }
  
  airMopAdd(mop, nout=nrrdNew(), (airMopper)nrrdNuke, airMopAlways);
  airMopAdd(mop, ntmp=nrrdNew(), (airMopper)nrrdNuke, airMopAlways);
  if (warp) {
    minT = limnSplineMinT(warp);
    maxT = limnSplineMaxT(warp);
    ret = (limnSplineSample(ntmp, warp, minT, M, maxT)
           || limnSplineNrrdEvaluate(nout, spline, ntmp));
  } else {
    minT = limnSplineMinT(spline);
    maxT = limnSplineMaxT(spline);
    ret = limnSplineSample(nout, spline, minT, M, maxT);
  }
  if (ret) {
    airMopAdd(mop, err=biffGetDone(LIMN), airFree, airMopAlways);
    fprintf(stderr, "%s: trouble:\n%s\n", me, err);
    airMopError(mop);
    return 1;
  }

  out = (double*)(nout->data);
  pause = M/150;
  printf("%%!\n");
  printf("1 setlinewidth\n");
  printf("%g %g moveto\n",
         scale*out[0 + 2*0] + tran[0], scale*out[1 + 2*0] + tran[1]);
  printf("gsave\n");
  printf("0.2 setlinewidth\n");
  printf("currentpoint newpath 3 0 360 arc stroke\n");
  printf("grestore\n");
  for (i=1; i<M; i++) {
    printf("%g %g lineto\n",
           scale*out[0 + 2*i] + tran[0], scale*out[1 + 2*i] + tran[1]);
    if (0 == AIR_MOD(i, pause)) {
      printf("gsave\n");
      printf("0.2 setlinewidth\n");
      printf("currentpoint newpath 3 0 360 arc stroke\n");
      printf("grestore\n");
    }
  }
  printf("stroke\n");
  printf("showpage\n");
  
  airMopOkay(mop);
  return 0;
}