int main(int argc, const char **argv) { const char *me; char *err; hestOpt *hopt=NULL; hestParm *hparm; airArray *mop; /* variables learned via hest */ Nrrd *nin; float camfr[3], camat[3], camup[3], camnc, camfc, camFOV; int camortho, hitandquit; unsigned int camsize[2]; double isovalue, sliso, isomin, isomax; /* boilerplate hest code */ me = argv[0]; mop = airMopNew(); hparm = hestParmNew(); hparm->respFileEnable = AIR_TRUE; airMopAdd(mop, hparm, (airMopper)hestParmFree, airMopAlways); /* setting up the command-line options */ hparm->respFileEnable = AIR_TRUE; hestOptAdd(&hopt, "i", "volume", airTypeOther, 1, 1, &nin, NULL, "input volume to isosurface", NULL, NULL, nrrdHestNrrd); hestOptAdd(&hopt, "v", "isovalue", airTypeDouble, 1, 1, &isovalue, "nan", "isovalue at which to run Marching Cubes"); hestOptAdd(&hopt, "fr", "x y z", airTypeFloat, 3, 3, camfr, "3 4 5", "look-from point"); hestOptAdd(&hopt, "at", "x y z", airTypeFloat, 3, 3, camat, "0 0 0", "look-at point"); hestOptAdd(&hopt, "up", "x y z", airTypeFloat, 3, 3, camup, "0 0 1", "up direction"); hestOptAdd(&hopt, "nc", "dist", airTypeFloat, 1, 1, &(camnc), "-2", "at-relative near clipping distance"); hestOptAdd(&hopt, "fc", "dist", airTypeFloat, 1, 1, &(camfc), "2", "at-relative far clipping distance"); hestOptAdd(&hopt, "fov", "angle", airTypeFloat, 1, 1, &(camFOV), "20", "vertical field-of-view, in degrees. Full vertical " "extent of image plane subtends this angle."); hestOptAdd(&hopt, "sz", "s0 s1", airTypeUInt, 2, 2, &(camsize), "640 480", "# samples (horz vert) of image plane. "); hestOptAdd(&hopt, "ortho", NULL, airTypeInt, 0, 0, &(camortho), NULL, "use orthographic instead of (the default) " "perspective projection "); hestOptAdd(&hopt, "haq", NULL, airTypeBool, 0, 0, &(hitandquit), NULL, "save a screenshot rather than display the viewer"); hestParseOrDie(hopt, argc-1, argv+1, hparm, me, "demo program", AIR_TRUE, AIR_TRUE, AIR_TRUE); airMopAdd(mop, hopt, (airMopper)hestOptFree, airMopAlways); airMopAdd(mop, hopt, (airMopper)hestParseFree, airMopAlways); /* learn value range, and set initial isovalue if needed */ NrrdRange *range = nrrdRangeNewSet(nin, AIR_FALSE); airMopAdd(mop, range, (airMopper)nrrdRangeNix, airMopAlways); isomin = range->min; isomax = range->max; if (!AIR_EXISTS(isovalue)) { isovalue = (isomin + isomax)/2; } /* first, make sure we can isosurface ok */ limnPolyData *lpld = limnPolyDataNew(); seekContext *sctx = seekContextNew(); airMopAdd(mop, sctx, (airMopper)seekContextNix, airMopAlways); sctx->pldArrIncr = nrrdElementNumber(nin); seekVerboseSet(sctx, 0); seekNormalsFindSet(sctx, AIR_TRUE); if (seekDataSet(sctx, nin, NULL, 0) || seekTypeSet(sctx, seekTypeIsocontour) || seekIsovalueSet(sctx, isovalue) || seekUpdate(sctx) || seekExtract(sctx, lpld)) { airMopAdd(mop, err=biffGetDone(SEEK), airFree, airMopAlways); fprintf(stderr, "trouble with isosurfacing:\n%s", err); airMopError(mop); return 1; } if (!lpld->xyzwNum) { fprintf(stderr, "%s: warning: No isocontour generated at isovalue %g\n", me, isovalue); } /* then create empty scene */ Hale::init(); Hale::Scene scene; /* then create viewer (in order to create the OpenGL context) */ Hale::Viewer viewer(camsize[0], camsize[1], "Iso", &scene); viewer.lightDir(glm::vec3(-1.0f, 1.0f, 3.0f)); viewer.camera.init(glm::vec3(camfr[0], camfr[1], camfr[2]), glm::vec3(camat[0], camat[1], camat[2]), glm::vec3(camup[0], camup[1], camup[2]), camFOV, (float)camsize[0]/camsize[1], camnc, camfc, camortho); viewer.refreshCB((Hale::ViewerRefresher)render); viewer.refreshData(&viewer); sliso = isovalue; viewer.slider(&sliso, isomin, isomax); viewer.current(); /* then create geometry, and add it to scene */ Hale::Polydata hply(lpld, true, // hply now owns lpld Hale::ProgramLib(Hale::preprogramAmbDiff2SideSolid)); scene.add(&hply); scene.drawInit(); render(&viewer); if (hitandquit) { seekIsovalueSet(sctx, isovalue); seekUpdate(sctx); seekExtract(sctx, lpld); hply.rebuffer(); render(&viewer); glfwWaitEvents(); render(&viewer); viewer.snap(); Hale::done(); airMopOkay(mop); return 0; } while(!Hale::finishing){ glfwWaitEvents(); if (viewer.sliding() && sliso != isovalue) { isovalue = sliso; printf("%s: isosurfacing at %g\n", me, isovalue); seekIsovalueSet(sctx, isovalue); seekUpdate(sctx); seekExtract(sctx, lpld); hply.rebuffer(); } render(&viewer); } /* clean exit; all okay */ Hale::done(); airMopOkay(mop); return 0; }
int main(int argc, const char *argv[]) { const char *me; char *err, *outS; hestOpt *hopt=NULL; airArray *mop; limnPolyData *pld, *pldSub; gageContext *gctx=NULL; gagePerVolume *pvl; Nrrd *nin, *nmeas; double kparm[3], strength, scaling[3]; seekContext *sctx; FILE *file; unsigned int ncc; size_t samples[3]; gageKind *kind; char *itemGradS; /* , *itemEvalS[2], *itemEvecS[2]; */ int itemGrad; /* , itemEval[2], itemEvec[2]; */ int E; me = argv[0]; hestOptAdd(&hopt, "i", "nin", airTypeOther, 1, 1, &nin, NULL, "input volume to analyze", NULL, NULL, nrrdHestNrrd); hestOptAdd(&hopt, "k", "kind", airTypeOther, 1, 1, &kind, NULL, "\"kind\" of volume (\"scalar\", \"vector\", \"tensor\")", NULL, NULL, &probeKindHestCB); hestOptAdd(&hopt, "s", "strength", airTypeDouble, 1, 1, &strength, "0.01", "strength"); hestOptAdd(&hopt, "gi", "grad item", airTypeString, 1, 1, &itemGradS, NULL, "item for gradient vector"); hestOptAdd(&hopt, "c", "scaling", airTypeDouble, 3, 3, scaling, "1 1 1", "amount by which to up/down-sample on each spatial axis"); hestOptAdd(&hopt, "n", "# CC", airTypeUInt, 1, 1, &ncc, "0", "if non-zero, number of CC to save"); hestOptAdd(&hopt, "o", "output LMPD", airTypeString, 1, 1, &outS, "out.lmpd", "output file to save LMPD 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); itemGrad = airEnumVal(kind->enm, itemGradS); pld = limnPolyDataNew(); airMopAdd(mop, pld, (airMopper)limnPolyDataNix, airMopAlways); pldSub = limnPolyDataNew(); airMopAdd(mop, pldSub, (airMopper)limnPolyDataNix, airMopAlways); file = airFopen(outS, stdout, "w"); airMopAdd(mop, file, (airMopper)airFclose, airMopAlways); sctx = seekContextNew(); airMopAdd(mop, sctx, (airMopper)seekContextNix, airMopAlways); gctx = gageContextNew(); airMopAdd(mop, gctx, (airMopper)gageContextNix, airMopAlways); ELL_3V_SET(kparm, 1, 1.0, 0.0); if (!(pvl = gagePerVolumeNew(gctx, nin, kind)) || gagePerVolumeAttach(gctx, pvl) || gageKernelSet(gctx, gageKernel00, nrrdKernelBCCubic, kparm) || gageKernelSet(gctx, gageKernel11, nrrdKernelBCCubicD, kparm) || gageKernelSet(gctx, gageKernel22, nrrdKernelBCCubicDD, kparm) || gageQueryItemOn(gctx, pvl, itemGrad) || gageQueryItemOn(gctx, pvl, gageSclHessEval) || gageQueryItemOn(gctx, pvl, gageSclHessEval2) || gageQueryItemOn(gctx, pvl, gageSclHessEvec) || gageQueryItemOn(gctx, pvl, gageSclHessEvec2) || gageUpdate(gctx)) { airMopAdd(mop, err = biffGetDone(GAGE), airFree, airMopAlways); fprintf(stderr, "%s: trouble:\n%s\n", me, err); airMopError(mop); return 1; } seekVerboseSet(sctx, 10); E = 0; if (!E) E |= seekDataSet(sctx, NULL, gctx, 0); ELL_3V_SET(samples, scaling[0]*nin->axis[kind->baseDim + 0].size, scaling[1]*nin->axis[kind->baseDim + 1].size, scaling[2]*nin->axis[kind->baseDim + 2].size); if (!E) E |= seekSamplesSet(sctx, samples); if (!E) E |= seekItemGradientSet(sctx, itemGrad); if (!E) E |= seekItemEigensystemSet(sctx, gageSclHessEval, gageSclHessEvec); if (!E) E |= seekItemNormalSet(sctx, gageSclHessEvec2); if (!E) E |= seekStrengthUseSet(sctx, AIR_TRUE); if (!E) E |= seekStrengthSet(sctx, -1, strength); if (!E) E |= seekItemStrengthSet(sctx, gageSclHessEval2); if (!E) E |= seekNormalsFindSet(sctx, AIR_TRUE); if (!E) E |= seekTypeSet(sctx, seekTypeRidgeSurface); if (!E) E |= seekUpdate(sctx); if (!E) E |= seekExtract(sctx, pld); if (E) { airMopAdd(mop, err = biffGetDone(SEEK), airFree, airMopAlways); fprintf(stderr, "%s: trouble:\n%s\n", me, err); airMopError(mop); return 1; } fprintf(stderr, "%s: extraction time = %g\n", me, sctx->time); nmeas = nrrdNew(); airMopAdd(mop, nmeas, (airMopper)nrrdNuke, airMopAlways); if (limnPolyDataVertexWindingFix(pld, AIR_TRUE) || limnPolyDataVertexWindingFlip(pld) || limnPolyDataVertexNormals(pld) || limnPolyDataCCFind(pld) || limnPolyDataPrimitiveArea(nmeas, pld) || limnPolyDataPrimitiveSort(pld, nmeas)) { err = biffGetDone(LIMN); fprintf(stderr, "%s: trouble sorting:\n%s", me, err); free(err); } if (ncc > 1) { double *meas; unsigned int ccIdx; nrrdSave("meas.nrrd", nmeas, NULL); ncc = AIR_MIN(ncc, nmeas->axis[0].size); meas = AIR_CAST(double *, nmeas->data); for (ccIdx=ncc; ccIdx<nmeas->axis[0].size; ccIdx++) { meas[ccIdx] = 0.0; } if (!E) E |= limnPolyDataPrimitiveSelect(pldSub, pld, nmeas); if (!E) E |= limnPolyDataWriteLMPD(file, pldSub); } else {