示例#1
0
/*
** creaseProj
**
** eigenvectors (with non-zero eigenvalues) of output posproj are
** tangents to the directions along which particle is allowed to move
** *downward* (in height) for constraint satisfaction (according to
** tangent 1 or tangents 1&2)
**
** negproj is the same, but for points moving upwards (according to
** negativetangent1 or negativetangent 1&2)
*/
static void
creaseProj(pullTask *task, pullPoint *point,
           int tang1Use, int tang2Use,
           int negtang1Use, int negtang2Use,
           /* output */
           double posproj[9], double negproj[9]) {
#if PRAYING
  static const char me[]="creaseProj";
#endif
  double pp[9];
  double *tng;

  ELL_3M_ZERO_SET(posproj);
  if (tang1Use) {
    tng = point->info + task->pctx->infoIdx[pullInfoTangent1];
#if PRAYING
    fprintf(stderr, "!%s: tng1 = %g %g %g\n", me, tng[0], tng[1], tng[2]);
#endif
    ELL_3MV_OUTER(pp, tng, tng);
    ELL_3M_ADD2(posproj, posproj, pp);
  }
  if (tang2Use) {
    tng = point->info + task->pctx->infoIdx[pullInfoTangent2];
    ELL_3MV_OUTER(pp, tng, tng);
    ELL_3M_ADD2(posproj, posproj, pp);
  }

  ELL_3M_ZERO_SET(negproj);
  if (negtang1Use) {
    tng = point->info + task->pctx->infoIdx[pullInfoNegativeTangent1];
    ELL_3MV_OUTER(pp, tng, tng);
    ELL_3M_ADD2(negproj, negproj, pp);
  }
  if (negtang2Use) {
    tng = point->info + task->pctx->infoIdx[pullInfoNegativeTangent2];
    ELL_3MV_OUTER(pp, tng, tng);
    ELL_3M_ADD2(negproj, negproj, pp);
  }

  if (!tang1Use && !tang2Use && !negtang1Use && !negtang2Use) {
    /* we must be after points, and so need freedom to go after them */
    /* for now we do this via posproj not negproj; see haveNada below */
    ELL_3M_IDENTITY_SET(posproj);
  }

  return;
}
示例#2
0
文件: tsoid.c 项目: BRAINSia/teem
static void
scalingMatrix(double mat[9], double vec[3], double scl) {
  double dir[3], tmp[9], len;

  ELL_3V_NORM(dir, vec, len);
  ELL_3MV_OUTER(tmp, dir, dir);
  ELL_3M_SCALE(tmp, scl-1, tmp);
  ELL_3M_IDENTITY_SET(mat);
  ELL_3M_ADD2(mat, mat, tmp);
  return;
}
void
_gageVecAnswer(gageContext *ctx, gagePerVolume *pvl) {
  char me[]="_gageVecAnswer";
  double cmag, tmpMat[9], mgevec[9], mgeval[3];
  double symm[9], asym[9], tran[9], eval[3], tmpVec[3], norm;
  gage_t *vecAns, *normAns, *jacAns, *curlAns, *hesAns, *curlGradAns, 
         *helGradAns, *dirHelDirAns, *curlnormgradAns;
  /* int asw; */

  vecAns          = pvl->directAnswer[gageVecVector];
  normAns         = pvl->directAnswer[gageVecNormalized];
  jacAns          = pvl->directAnswer[gageVecJacobian];
  curlAns         = pvl->directAnswer[gageVecCurl];
  hesAns          = pvl->directAnswer[gageVecHessian];
  curlGradAns     = pvl->directAnswer[gageVecCurlGradient];
  curlnormgradAns = pvl->directAnswer[gageVecCurlNormGrad];
  helGradAns      = pvl->directAnswer[gageVecHelGradient];
  dirHelDirAns    = pvl->directAnswer[gageVecDirHelDeriv];

  if (GAGE_QUERY_ITEM_TEST(pvl->query, gageVecVector)) {
    /* done if doV */
    if (ctx->verbose) {
      fprintf(stderr, "vec = ");
      ell_3v_PRINT(stderr, vecAns);
    }
  }
  /* done if doV 
  if (GAGE_QUERY_ITEM_TEST(pvl->query, gageVecVector{0,1,2})) {
  }
  */
  if (GAGE_QUERY_ITEM_TEST(pvl->query, gageVecLength)) {
    pvl->directAnswer[gageVecLength][0] = AIR_CAST(gage_t, ELL_3V_LEN(vecAns));
  }
  if (GAGE_QUERY_ITEM_TEST(pvl->query, gageVecNormalized)) {
    if (pvl->directAnswer[gageVecLength][0]) {
      ELL_3V_SCALE_TT(normAns, gage_t,
                      1.0/pvl->directAnswer[gageVecLength][0], vecAns);
    } else {
      ELL_3V_COPY(normAns, gageZeroNormal);
    }
  }
  if (GAGE_QUERY_ITEM_TEST(pvl->query, gageVecJacobian)) {
    /* done if doD1 */
    /*
      0:dv_x/dx  1:dv_x/dy  2:dv_x/dz
      3:dv_y/dx  4:dv_y/dy  5:dv_y/dz
      6:dv_z/dx  7:dv_z/dy  8:dv_z/dz
    */
    if (ctx->verbose) {
      fprintf(stderr, "%s: jac = \n", me);
      ell_3m_PRINT(stderr, jacAns);
    }
  }
  if (GAGE_QUERY_ITEM_TEST(pvl->query, gageVecDivergence)) {
    pvl->directAnswer[gageVecDivergence][0] = jacAns[0] + jacAns[4] + jacAns[8];
    if (ctx->verbose) {
      fprintf(stderr, "%s: div = %g + %g + %g  = %g\n", me,
              jacAns[0], jacAns[4], jacAns[8],
              pvl->directAnswer[gageVecDivergence][0]);
    }
  }
  if (GAGE_QUERY_ITEM_TEST(pvl->query, gageVecCurl)) {
    ELL_3V_SET(curlAns,
               jacAns[7] - jacAns[5],
               jacAns[2] - jacAns[6],
               jacAns[3] - jacAns[1]);
  }
  if (GAGE_QUERY_ITEM_TEST(pvl->query, gageVecCurlNorm)) {
    pvl->directAnswer[gageVecCurlNorm][0] =
      AIR_CAST(gage_t, ELL_3V_LEN(curlAns));  
  }
  if (GAGE_QUERY_ITEM_TEST(pvl->query, gageVecHelicity)) {
    pvl->directAnswer[gageVecHelicity][0] = 
      ELL_3V_DOT(vecAns, curlAns);
  }
  if (GAGE_QUERY_ITEM_TEST(pvl->query, gageVecNormHelicity)) {
    cmag = ELL_3V_LEN(curlAns);
    pvl->directAnswer[gageVecNormHelicity][0] = 
      AIR_CAST(gage_t, cmag ? ELL_3V_DOT(normAns, curlAns)/cmag : 0);
  }
  if (GAGE_QUERY_ITEM_TEST(pvl->query, gageVecLambda2)) {
      ELL_3M_TRANSPOSE(tran, jacAns);
      /* symmetric part */
      ELL_3M_SCALE_ADD2(symm, 0.5, jacAns,  0.5, tran);
      /* antisymmetric part */
      ELL_3M_SCALE_ADD2(asym, 0.5, jacAns, -0.5, tran);
      /* square symmetric part */
      ELL_3M_MUL(tmpMat, symm, symm);
      ELL_3M_COPY(symm, tmpMat);
      /* square antisymmetric part */
      ELL_3M_MUL(tmpMat, asym, asym);
      /* sum of both */
      ELL_3M_ADD2(symm, symm, tmpMat);
      /* get eigenvalues in sorted order */
      /* asw = */ ell_3m_eigenvalues_d(eval, symm, AIR_TRUE);
      pvl->directAnswer[gageVecLambda2][0] = AIR_CAST(gage_t, eval[1]);
  }
  if (GAGE_QUERY_ITEM_TEST(pvl->query, gageVecImaginaryPart)) {
      pvl->directAnswer[gageVecImaginaryPart][0] =
        AIR_CAST(gage_t, gage_imaginary_part_eigenvalues(jacAns)); 
  }
  /* 2nd order vector derivative continued */ 
  if (GAGE_QUERY_ITEM_TEST(pvl->query, gageVecHessian)) {
      /* done if doD2 */
      /* the ordering is induced by the scalar hessian computation :
         0:d2v_x/dxdx   1:d2v_x/dxdy   2:d2v_x/dxdz
         3:d2v_x/dydx   4:d2v_x/dydy   5:d2v_x/dydz
         6:d2v_x/dzdx   7:d2v_x/dzdy   8:d2v_x/dzdz
         9:d2v_y/dxdx       [...]
             [...]
        24:dv2_z/dzdx  25:d2v_z/dzdy  26:d2v_z/dzdz
      */
    if (ctx->verbose) {
      fprintf(stderr, "%s: hes = \n", me);
      ell_3m_PRINT(stderr, hesAns); /* ?? */
    }
  }
  if (GAGE_QUERY_ITEM_TEST(pvl->query, gageVecDivGradient)) {
      pvl->directAnswer[gageVecDivGradient][0] = hesAns[0] + hesAns[12] + hesAns[24];
      pvl->directAnswer[gageVecDivGradient][1] = hesAns[1] + hesAns[13] + hesAns[25];
      pvl->directAnswer[gageVecDivGradient][2] = hesAns[2] + hesAns[14] + hesAns[26];
  }
  if (GAGE_QUERY_ITEM_TEST(pvl->query, gageVecCurlGradient)) {
      pvl->directAnswer[gageVecCurlGradient][0] = hesAns[21]-hesAns[15];
      pvl->directAnswer[gageVecCurlGradient][1] = hesAns[22]-hesAns[16];
      pvl->directAnswer[gageVecCurlGradient][2] = hesAns[23]-hesAns[17];
      pvl->directAnswer[gageVecCurlGradient][3] = hesAns[ 6]-hesAns[18];
      pvl->directAnswer[gageVecCurlGradient][4] = hesAns[ 7]-hesAns[19];
      pvl->directAnswer[gageVecCurlGradient][5] = hesAns[ 8]-hesAns[20];
      pvl->directAnswer[gageVecCurlGradient][6] = hesAns[ 9]-hesAns[ 1];
      pvl->directAnswer[gageVecCurlGradient][7] = hesAns[10]-hesAns[ 2];
      pvl->directAnswer[gageVecCurlGradient][8] = hesAns[11]-hesAns[ 3];
  }
  if (GAGE_QUERY_ITEM_TEST(pvl->query, gageVecCurlNormGrad)) {
      norm = 1./ELL_3V_LEN(curlAns);

      tmpVec[0] = hesAns[21] - hesAns[15];
      tmpVec[1] = hesAns[ 6] - hesAns[18];
      tmpVec[2] = hesAns[ 9] - hesAns[ 3];      
      pvl->directAnswer[gageVecCurlNormGrad][0]=
        AIR_CAST(gage_t, norm*ELL_3V_DOT(tmpVec, curlAns));

      tmpVec[0] = hesAns[22] - hesAns[16];
      tmpVec[1] = hesAns[ 7] - hesAns[19];
      tmpVec[2] = hesAns[10] - hesAns[ 4];      
      pvl->directAnswer[gageVecCurlNormGrad][1]=
        AIR_CAST(gage_t, norm*ELL_3V_DOT(tmpVec, curlAns));

      tmpVec[0] = hesAns[23] - hesAns[17];
      tmpVec[1] = hesAns[ 8] - hesAns[20];
      tmpVec[2] = hesAns[11] - hesAns[ 5];      
      pvl->directAnswer[gageVecCurlNormGrad][2]=
        AIR_CAST(gage_t,  norm*ELL_3V_DOT(tmpVec, curlAns));
  }
  if (GAGE_QUERY_ITEM_TEST(pvl->query, gageVecNCurlNormGrad)) {
      norm = 1./ELL_3V_LEN(curlnormgradAns);
      ELL_3V_SCALE_TT(pvl->directAnswer[gageVecNCurlNormGrad], gage_t,
                      norm, pvl->directAnswer[gageVecCurlNormGrad]);
  }
  if (GAGE_QUERY_ITEM_TEST(pvl->query, gageVecHelGradient)) {
      pvl->directAnswer[gageVecHelGradient][0] = 
          jacAns[0]*curlAns[0]+
          jacAns[3]*curlAns[1]+
          jacAns[6]*curlAns[2]+
          curlGradAns[0]*vecAns[0]+
          curlGradAns[3]*vecAns[1]+
          curlGradAns[6]*vecAns[2];
      pvl->directAnswer[gageVecHelGradient][1] = 
          jacAns[1]*curlAns[0]+
          jacAns[4]*curlAns[1]+
          jacAns[7]*curlAns[2]+
          curlGradAns[1]*vecAns[0]+
          curlGradAns[4]*vecAns[1]+
          curlGradAns[7]*vecAns[2];
      pvl->directAnswer[gageVecHelGradient][0] = 
          jacAns[2]*curlAns[0]+
          jacAns[5]*curlAns[1]+
          jacAns[8]*curlAns[2]+
          curlGradAns[2]*vecAns[0]+
          curlGradAns[5]*vecAns[1]+
          curlGradAns[8]*vecAns[2];
  }
  if (GAGE_QUERY_ITEM_TEST(pvl->query, gageVecDirHelDeriv)) {
      pvl->directAnswer[gageVecDirHelDeriv][0] = 
        ELL_3V_DOT(normAns, helGradAns);          
  }
  if (GAGE_QUERY_ITEM_TEST(pvl->query, gageVecProjHelGradient)) {
      pvl->directAnswer[gageVecDirHelDeriv][0] = 
          helGradAns[0]-dirHelDirAns[0]*normAns[0];
      pvl->directAnswer[gageVecDirHelDeriv][1] = 
          helGradAns[1]-dirHelDirAns[0]*normAns[1];
      pvl->directAnswer[gageVecDirHelDeriv][2] = 
          helGradAns[2]-dirHelDirAns[0]*normAns[2];
  }
  if (GAGE_QUERY_ITEM_TEST(pvl->query, gageVecGradient0)) {
    ELL_3V_SET(pvl->directAnswer[gageVecGradient0],
               jacAns[0],
               jacAns[1],
               jacAns[2]);
  }
  if (GAGE_QUERY_ITEM_TEST(pvl->query, gageVecGradient1)) {
    ELL_3V_SET(pvl->directAnswer[gageVecGradient1],
               jacAns[3],
               jacAns[4],
               jacAns[5]);
  }
  if (GAGE_QUERY_ITEM_TEST(pvl->query, gageVecGradient2)) {
    ELL_3V_SET(pvl->directAnswer[gageVecGradient2],
               jacAns[6],
               jacAns[7],
               jacAns[8]);
  }
  if (GAGE_QUERY_ITEM_TEST(pvl->query, gageVecMultiGrad)) {
    ELL_3M_IDENTITY_SET(pvl->directAnswer[gageVecMultiGrad]);
    ELL_3MV_OUTER_ADD(pvl->directAnswer[gageVecMultiGrad],
                      pvl->directAnswer[gageVecGradient0],
                      pvl->directAnswer[gageVecGradient0]);
    ELL_3MV_OUTER_ADD(pvl->directAnswer[gageVecMultiGrad],
                      pvl->directAnswer[gageVecGradient1],
                      pvl->directAnswer[gageVecGradient1]);
    ELL_3MV_OUTER_ADD(pvl->directAnswer[gageVecMultiGrad],
                      pvl->directAnswer[gageVecGradient2],
                      pvl->directAnswer[gageVecGradient2]);
  }
  if (GAGE_QUERY_ITEM_TEST(pvl->query, gageVecMGFrob)) {
    pvl->directAnswer[gageVecMGFrob][0] 
      = AIR_CAST(gage_t, ELL_3M_FROB(pvl->directAnswer[gageVecMultiGrad]));
  }
  if (GAGE_QUERY_ITEM_TEST(pvl->query, gageVecMGEval)) {
    ELL_3M_COPY(tmpMat, pvl->directAnswer[gageVecMultiGrad]);
    /* HEY: look at the return value for root multiplicity? */
    ell_3m_eigensolve_d(mgeval, mgevec, tmpMat, AIR_TRUE);
    ELL_3V_COPY_TT(pvl->directAnswer[gageVecMGEval], gage_t, mgeval);
  }
  if (GAGE_QUERY_ITEM_TEST(pvl->query, gageVecMGEvec)) {
    ELL_3M_COPY_TT(pvl->directAnswer[gageVecMGEvec], gage_t, mgevec);
  }

  return;
}
示例#4
0
int
main(int argc, const char *argv[]) {
  const char *me;
  char *err, *outS;
  double scale[3], matA[9], matB[9], matC[9], sval[3], uu[9], vv[9];
  float matAf[9], matBf[16];
  float p[3], q[4], mR[9], len, gamma;
  float os, vs, rad, AB[2], ten[7], view[3];
  hestOpt *hopt=NULL;
  airArray *mop;
  limnObject *obj;
  limnLook *look; int lookRod, lookSoid;
  int partIdx=-1; /* sssh */
  int res, sphere;
  FILE *file;

  me = argv[0];
  hestOptAdd(&hopt, "sc", "scalings", airTypeDouble, 3, 3, scale, "1 1 1",
             "axis-aligned scaling to do on ellipsoid");
  hestOptAdd(&hopt, "AB", "A, B exponents", airTypeFloat, 2, 2, AB, "nan nan",
             "Directly set the A, B parameters to the superquadric surface, "
             "over-riding the default behavior of determining them from the "
             "scalings \"-sc\" as superquadric tensor glyphs");
  hestOptAdd(&hopt, "os", "over-all scaling", airTypeFloat, 1, 1, &os, "1",
             "over-all scaling (multiplied by scalings)");
  hestOptAdd(&hopt, "vs", "over-all scaling", airTypeFloat, 1, 1, &vs, "1",
             "scaling along view-direction (to show off bas-relief "
             "ambibuity of ellipsoids versus superquads)");
  hestOptAdd(&hopt, "fr", "from (eye) point", airTypeFloat, 3, 3, &view,
             "4 4 4", "eye point, needed for non-unity \"-vs\"");
  hestOptAdd(&hopt, "gamma", "superquad sharpness", airTypeFloat, 1, 1,
             &gamma, "0",
             "how much to sharpen edges as a "
             "function of differences between eigenvalues");
  hestOptAdd(&hopt, "sphere", NULL, airTypeInt, 0, 0, &sphere, NULL,
             "use a sphere instead of a superquadric");
  hestOptAdd(&hopt, "p", "x y z", airTypeFloat, 3, 3, p, "0 0 0",
             "location in quaternion quotient space");
  hestOptAdd(&hopt, "r", "radius", airTypeFloat, 1, 1, &rad, "0.015",
             "black axis cylinder radius (or 0.0 to not drawn these)");
  hestOptAdd(&hopt, "res", "resolution", airTypeInt, 1, 1, &res, "25",
             "tesselation resolution for both glyph and axis cylinders");
  hestOptAdd(&hopt, "o", "output OFF", airTypeString, 1, 1, &outS, "out.off",
             "output file to save OFF into");
  hestParseOrDie(hopt, argc-1, argv+1, NULL,
                 me, info, AIR_TRUE, AIR_TRUE, AIR_TRUE);
  mop = airMopNew();
  airMopAdd(mop, hopt, (airMopper)hestOptFree, airMopAlways);
  airMopAdd(mop, hopt, (airMopper)hestParseFree, airMopAlways);

  obj = limnObjectNew(1000, AIR_TRUE);
  airMopAdd(mop, obj, (airMopper)limnObjectNix, airMopAlways);

  /* create limnLooks for ellipsoid and for rods */
  lookSoid = limnObjectLookAdd(obj);
  look = obj->look + lookSoid;
  ELL_4V_SET(look->rgba, 1, 1, 1, 1);
  ELL_3V_SET(look->kads, 0.2, 0.8, 0);
  look->spow = 0;
  lookRod = limnObjectLookAdd(obj);
  look = obj->look + lookRod;
  ELL_4V_SET(look->rgba, 0, 0, 0, 1);
  ELL_3V_SET(look->kads, 1, 0, 0);
  look->spow = 0;

  ELL_3M_IDENTITY_SET(matA);
  ELL_3V_SCALE(scale, os, scale);
  ELL_3M_SCALE_SET(matB, scale[0], scale[1], scale[2]);
  ell_3m_post_mul_d(matA, matB);
  if (1 != vs) {
    ELL_3V_NORM(view, view, len);
    if (!len) {
      /* HEY: perhaps do more diplomatic error message here */
      fprintf(stderr, "%s: stupido!\n", me);
      exit(1);
    }
    ELL_3MV_OUTER(matB, view, view);
    ELL_3M_SCALE(matB, vs-1, matB);
    ELL_3M_IDENTITY_SET(matC);
    ELL_3M_ADD2(matB, matC, matB);
    ell_3m_post_mul_d(matA, matB);
  }
  ell_3m_svd_d(uu, sval, vv, matA, AIR_TRUE);

  /*
  fprintf(stderr, "%s: ____________________________________\n", me);
  fprintf(stderr, "%s: mat = \n", me);
  ell_3m_print_d(stderr, matA);
  fprintf(stderr, "%s: uu = \n", me);
  ell_3m_print_d(stderr, uu);
  ELL_3M_TRANSPOSE(matC, uu);
  ELL_3M_MUL(matB, uu, matC);
  fprintf(stderr, "%s: uu * uu^T = \n", me);
  ell_3m_print_d(stderr, matB);
  fprintf(stderr, "%s: sval = %g %g %g\n", me, sval[0], sval[1], sval[2]);
  fprintf(stderr, "%s: vv = \n", me);
  ell_3m_print_d(stderr, vv);
  ELL_3M_MUL(matB, vv, vv);
  fprintf(stderr, "%s: vv * vv^T = \n", me);
  ELL_3M_TRANSPOSE(matC, vv);
  ELL_3M_MUL(matB, vv, matC);
  ell_3m_print_d(stderr, matB);
  ELL_3M_IDENTITY_SET(matA);
  ell_3m_pre_mul_d(matA, uu);
  ELL_3M_SCALE_SET(matB, sval[0], sval[1], sval[2]);
  ell_3m_pre_mul_d(matA, matB);
  ell_3m_pre_mul_d(matA, vv);
  fprintf(stderr, "%s: uu * diag(sval) * vv = \n", me);
  ell_3m_print_d(stderr, matA);
  fprintf(stderr, "%s: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", me);
  */

  ELL_3M_IDENTITY_SET(matA);
  ell_3m_pre_mul_d(matA, uu);
  ELL_3M_SCALE_SET(matB, sval[0], sval[1], sval[2]);
  ell_3m_pre_mul_d(matA, matB);
  ELL_3M_TRANSPOSE(matB, uu);
  ell_3m_pre_mul_d(matA, matB);
  TEN_M2T(ten, matA);

  partIdx = soidDoit(obj, lookSoid,
                     sphere, gamma, res,
                     (AIR_EXISTS(AB[0]) && AIR_EXISTS(AB[1])) ? AB : NULL,
                     ten);

  ELL_4V_SET(q, 1, p[0], p[1], p[2]);
  ELL_4V_NORM(q, q, len);
  ell_q_to_3m_f(mR, q);
  ELL_43M_INSET(matBf, mR);
  limnObjectPartTransform(obj, partIdx, matBf);

  if (rad) {
    partIdx = limnObjectCylinderAdd(obj, lookRod, 0, res);
    ELL_4M_IDENTITY_SET(matAf);
    ELL_4M_SCALE_SET(matBf, (1-scale[0])/2, rad, rad);
    ell_4m_post_mul_f(matAf, matBf);
    ELL_4M_TRANSLATE_SET(matBf, (1+scale[0])/2, 0.0, 0.0);
    ell_4m_post_mul_f(matAf, matBf);
    limnObjectPartTransform(obj, partIdx, matAf);

    partIdx = limnObjectCylinderAdd(obj, lookRod, 0, res);
    ELL_4M_IDENTITY_SET(matAf);
    ELL_4M_SCALE_SET(matBf, (1-scale[0])/2, rad, rad);
    ell_4m_post_mul_f(matAf, matBf);
    ELL_4M_TRANSLATE_SET(matBf, -(1+scale[0])/2, 0.0, 0.0);
    ell_4m_post_mul_f(matAf, matBf);
    limnObjectPartTransform(obj, partIdx, matAf);

    partIdx = limnObjectCylinderAdd(obj, lookRod, 1, res);
    ELL_4M_IDENTITY_SET(matAf);
    ELL_4M_SCALE_SET(matBf, rad, (1-scale[1])/2, rad);
    ell_4m_post_mul_f(matAf, matBf);
    ELL_4M_TRANSLATE_SET(matBf, 0.0, (1+scale[1])/2, 0.0);
    ell_4m_post_mul_f(matAf, matBf);
    limnObjectPartTransform(obj, partIdx, matAf);

    partIdx = limnObjectCylinderAdd(obj, lookRod, 1, res);
    ELL_4M_IDENTITY_SET(matAf);
    ELL_4M_SCALE_SET(matBf, rad, (1-scale[1])/2, rad);
    ell_4m_post_mul_f(matAf, matBf);
    ELL_4M_TRANSLATE_SET(matBf, 0.0, -(1+scale[1])/2, 0.0);
    ell_4m_post_mul_f(matAf, matBf);
    limnObjectPartTransform(obj, partIdx, matAf);

    partIdx = limnObjectCylinderAdd(obj, lookRod, 2, res);
    ELL_4M_IDENTITY_SET(matAf);
    ELL_4M_SCALE_SET(matBf, rad, rad, (1-scale[2])/2);
    ell_4m_post_mul_f(matAf, matBf);
    ELL_4M_TRANSLATE_SET(matBf, 0.0, 0.0, (1+scale[2])/2);
    ell_4m_post_mul_f(matAf, matBf);
    limnObjectPartTransform(obj, partIdx, matAf);

    partIdx = limnObjectCylinderAdd(obj, lookRod, 2, res);
    ELL_4M_IDENTITY_SET(matAf);
    ELL_4M_SCALE_SET(matBf, rad, rad, (1-scale[2])/2);
    ell_4m_post_mul_f(matAf, matBf);
    ELL_4M_TRANSLATE_SET(matBf, 0.0, 0.0, -(1+scale[2])/2);
    ell_4m_post_mul_f(matAf, matBf);
    limnObjectPartTransform(obj, partIdx, matAf);
  }

  file = airFopen(outS, stdout, "w");
  airMopAdd(mop, file, (airMopper)airFclose, airMopAlways);

  if (limnObjectWriteOFF(file, obj)) {
    airMopAdd(mop, err = biffGetDone(LIMN), airFree, airMopAlways);
    fprintf(stderr, "%s: trouble:\n%s\n", me, err);
    airMopError(mop); return 1;
  }

  airMopOkay(mop);
  return 0;
}
示例#5
0
文件: qseg.c 项目: CIBC-Internal/teem
/* Calculates 2 new centroids (and a new segmentation) from distances
   between Q-balls and centroids, returns true if segmentation changed
*/
int
_tenCalccent2(const int gradcount, const double qpoints[],
              const double dists[], double centroid[6], unsigned int seg[]) {
#if 0
  /* HEY: Attempt to implement better line-adding by adding
     outerproducts of points and estimating major eigenvector
     afterwards */
  int i,changed=AIR_FALSE;
  double sum0[9],sum1[9],mat[9], eval[3],evec[9];

  ELL_3M_ZERO_SET( sum0 );
  ELL_3M_ZERO_SET( sum1 );
  for( i = 0; i < gradcount; i++ ) {
    if( dists[i] < dists[gradcount+i] ) {
      ELL_3MV_OUTER( mat, qpoints +3*i, qpoints +3*i );
      ELL_3M_ADD2( sum0, sum0, mat );
      changed = changed || (seg[i] != 0);
      seg[i] = 0;
    } else {
      ELL_3MV_OUTER( mat, qpoints +3*i +gradcount, qpoints +3*i +gradcount );
      ELL_3M_ADD2( sum1, sum1, mat );
      changed = changed || (seg[i] != 1);
      seg[i] = 1;
    }
  }

  ell_3m_eigensolve_d( eval, evec, sum0, 0 );
  ELL_3V_COPY( centroid, evec + 3*ELL_MAX3_IDX( eval[0], eval[1], eval[2] ) );
  /* ELL_3V_SCALE( centroid, ELL_3V_LEN( centroid ), centroid ); */


  ell_3m_eigensolve_d( eval, evec, sum1, 0 );
  ELL_3V_COPY( centroid +3, evec + 3*ELL_MAX3_IDX( eval[0], eval[1], eval[2] ) );
  /* ELL_3V_SCALE( centroid +3, ELL_3V_LEN( centroid ), centroid +3); Normalize */

  return changed;
#endif

  int i, sign, seg0count=0, seg1count=0, changed=AIR_FALSE;
  double oldcentroid[6], diff[3], sum[3];

  memcpy( oldcentroid, centroid, 6 * sizeof( double ));

  for( i = 0; i < gradcount; i++ ) {
    if( dists[ 0*gradcount +i] < dists[1*gradcount +i] ) {
      /* Try to resolve sign so that centroid do not end up as all 0 */
      /* Choose signs so that the point lies "on the same side" as */
      /* the previous centroid. */
      diff[0] = oldcentroid[0] - qpoints[3*i +0];
      diff[1] = oldcentroid[1] - qpoints[3*i +1];
      diff[2] = oldcentroid[2] - qpoints[3*i +2];
      sum[0] = oldcentroid[0] + qpoints[3*i +0];
      sum[1] = oldcentroid[1] + qpoints[3*i +1];
      sum[2] = oldcentroid[2] + qpoints[3*i +2];
      sign = (diff[0]*diff[0] + diff[1]*diff[1] + diff[2]*diff[2]) <
        (sum[0]*sum[0] + sum[1]*sum[1] + sum[2]*sum[2]) ? -1 : +1;

      changed = changed || (seg[i] != 0);

      seg[i] = 0;
      centroid[0] += sign * qpoints[3*i +0];
      centroid[1] += sign * qpoints[3*i +1];
      centroid[2] += sign * qpoints[3*i +2];
      seg0count++;
    } else {
      diff[0] = oldcentroid[3+0] - qpoints[3*i +0];
      diff[1] = oldcentroid[3+1] - qpoints[3*i +1];
      diff[2] = oldcentroid[3+2] - qpoints[3*i +2];
      sum[0] = oldcentroid[3+0] + qpoints[3*i +0];
      sum[1] = oldcentroid[3+1] + qpoints[3*i +1];
      sum[2] = oldcentroid[3+2] + qpoints[3*i +2];
      sign = (diff[0]*diff[0] + diff[1]*diff[1] + diff[2]*diff[2]) <
        (sum[0]*sum[0] + sum[1]*sum[1] + sum[2]*sum[2]) ? -1 : +1;

      changed = changed || (seg[i] != 1);

      seg[i] = 1;
      centroid[3+0] += sign * qpoints[3*i +0];
      centroid[3+1] += sign * qpoints[3*i +1];
      centroid[3+2] += sign * qpoints[3*i +2];
      seg1count++;
    }
  }
  centroid[0] /= seg0count;
  centroid[1] /= seg0count;
  centroid[2] /= seg0count;
  centroid[3+0] /= seg1count;
  centroid[3+1] /= seg1count;
  centroid[3+2] /= seg1count;

  /* printf("cent = %f %f %f %f %f %f\n", centroid[0],centroid[1],centroid[2],centroid[3],centroid[4],centroid[5] ); */

  /*
    Should give error if any segment contains less than 6 elements,
    i.e. if( seg0count < 6 || seg1count < 6 ), since that would
    imply that a tensor cannot be computed for that segment.
  */

  return changed;
}