/*! * Extracts a square matrix of size [dim] from the slice [sin], centered * around position [x], [y] and places the result into the array [mat]. */ void mrc_slice_mat_getimat(Islice *sin, int x, int y, int dim, float *mat) { int xs, ys, xe, ye; int i, j, ic, jc; xs = x - (dim / 2); xe = xs + dim; ys = y - (dim / 2); ye = ys + dim; if (xs >= 0 && xe < sin->xsize && ys >= 0 && ye < sin->ysize) { for(j = ys; j < ye; j++) for(i = xs; i < xe; i++) mat[(i-xs )+ dim * (j-ys)] = sliceGetPixelMagnitude(sin, i, j); } else { /* If any pixels are out of bounds, replicate from inside pixels */ for(j = ys; j < ye; j++) for(i = xs; i < xe; i++) { ic = B3DMAX(0, B3DMIN(sin->xsize - 1, i)); jc = B3DMAX(0, B3DMIN(sin->ysize - 1, j)); mat[(i-xs )+ dim * (j-ys)] = sliceGetPixelMagnitude(sin, ic, jc); } } }
/* * Compute the limits of usable data in one dimension for calling from the interp function */ static void interpLimits(int na, int nb, float cen, float trans, double scale, float *aOff, int *bSize, int *bOff) { float bcStart, bcEnd; int bdStart, bdEnd; /* Get starting and ending continuous coordinates in b from corners of a and limit them to edges of first and last pixel */ bcStart = -cen / scale + nb / 2. + trans; bcEnd = (na - cen) / scale + nb / 2. + trans; bcStart = B3DMAX(0., bcStart); bcEnd = B3DMIN(nb, bcEnd); /* Get discrete coordinates of the nearest whole pixel by rounding up on the start and down on the end, then get the offset and size from them */ bdStart = (int)ceil(bcStart - 0.001); bdEnd = (int)floor(bcEnd + 0.001) - 1; *bOff = bdStart; *aOff = scale * (bdStart - nb / 2. - trans) + cen; /* Make sure this is not negative; roundoff errors can give negative values */ *aOff = B3DMAX(0., *aOff); *bSize = bdEnd + 1 - bdStart; /* Make sure the output size will pass the test below too */ if (*bSize * scale + *aOff > na) (*bSize)--; }
// Compute starting and ending draw coordinates from center coordinate, desired // size and maximum size, shifting center if necessary static void setCoordLimits(int cur, int maxSize, int drawSize, int &str, int &end) { str = cur - drawSize / 2; str = B3DMAX(1, str); end = B3DMIN(str + drawSize, maxSize - 1); str = B3DMAX(1, end - drawSize); }
/*! * Sets pixel size in X, Y, Z in Angstroms to the values in [delta] for unit [iunit] by * changing the cell sizes. Fortran wrappers iiuAltDelta and ialdel. */ void iiuAltDelta(int iunit, float *delta) { MrcHeader *hdr = iiuMrcHeader(iunit, "iiuAltDelta", 1, 0); hdr->mx = B3DMAX(1, hdr->mx); hdr->xlen = delta[0] * hdr->mx; hdr->my = B3DMAX(1, hdr->my); hdr->ylen = delta[0] * hdr->my; hdr->mz = B3DMAX(1, hdr->mz); hdr->zlen = delta[0] * hdr->mz; }
void ContourCopy::update() { int minVal, maxVal, curVal; ImodView *vw = sData.vw; // For each operation that uses spin box, set up min and max value // and adjust the current value if necessary switch(sData.copyOperation){ case COPY_TO_OBJECT: minVal = 1; maxVal = vw->imod->objsize; sData.objectNumber = B3DMAX(1, B3DMIN(maxVal, sData.objectNumber)); curVal = sData.objectNumber; break; case COPY_TO_SECTION: minVal = 1; maxVal = vw->zsize; sData.sectionNumber = B3DMAX(1, B3DMIN(maxVal, sData.sectionNumber)); curVal = sData.sectionNumber; break; case COPY_TO_TIME: minVal = 1; maxVal = vw->numTimes; sData.timeIndex = B3DMAX(1, B3DMIN(maxVal, sData.timeIndex)); curVal = sData.timeIndex; break; case COPY_TO_NEXT_SECTION: case COPY_TO_PREV_SECTION: case COPY_TO_CURRENT: default: minVal = 0; maxVal = 0; curVal = 0; break; } // Set up spin box limits and value and enable it if meaningful diaSetSpinMMVal(mToSpinBox, minVal, maxVal, curVal); mToSpinBox->setSpecialValueText(minVal ? "" : " "); mToSpinBox->setEnabled(minVal > 0); mEllipseBox->setEnabled(sData.copyOperation == COPY_TO_OBJECT); // Enable the time radio button if appropriate if (vw->numTimes) mTimeRadio->setEnabled(sData.copyOperation == COPY_TO_TIME); }
/*! * Does a linear regression fit of the [n] values in the array [y] to * the values in the arrays [x1], [x2], and [x3], namely, to the equation * ^ y = a1 * x1 + a2 * x2 + a3 * x3 + c ^ * It returns the coefficients [a1], [a2], [a3] and the intercept [c]. */ void lsFit3(float *x1, float *x2, float *x3, float *y, int n, float *a1, float *a2, float *a3, float *c) { float x1s, x2s, x3s, ys, x1m, x2m, x3m, ym, x1sqs, x2sqs, x3sqs, x1x2s; float x1x3s, x2x3s, x1ys, x2ys, x3ys, x1p, x2p, x3p, yp; int i; double den, num1, num2, num3, maxnum; x1s = x2s = x3s = ys = 0.; for (i = 0; i < n; i++) { x1s = x1s + x1[i]; x2s = x2s + x2[i]; x3s = x3s + x3[i]; ys = ys + y[i]; } x1m = x1s / n; x2m = x2s / n; x3m = x3s / n; ym = ys / n; x1sqs = x2sqs = x3sqs = x1x2s = x1x3s = x2x3s = x1ys = x2ys = x3ys = 0.; for (i = 0; i < n; i++) { x1p = x1[i] - x1m; x2p = x2[i] - x2m; x3p = x3[i] - x3m; yp = y[i] - ym; x1sqs = x1sqs + x1p * x1p; x2sqs = x2sqs + x2p * x2p; x3sqs = x3sqs + x3p * x3p; x1ys = x1ys + x1p * yp; x2ys = x2ys + x2p * yp; x3ys = x3ys + x3p * yp; x1x2s = x1x2s + x1p * x2p; x1x3s = x1x3s + x1p * x3p; x2x3s = x2x3s + x2p * x3p; } *a1 = *a2 = *a3 = *c = 0.; den = determ3(x1sqs, x1x2s, x1x3s, x1x2s, x2sqs, x2x3s, x1x3s, x2x3s, x3sqs); num1 = determ3(x1ys, x1x2s, x1x3s, x2ys, x2sqs, x2x3s, x3ys, x2x3s, x3sqs); num2 = determ3(x1sqs, x1ys, x1x3s, x1x2s, x2ys, x2x3s, x1x3s, x3ys, x3sqs); num3 = determ3(x1sqs, x1x2s, x1ys, x1x2s, x2sqs, x2ys, x1x3s, x2x3s, x3ys); maxnum = B3DMAX(fabs(num1), fabs(num2)); maxnum = B3DMAX(maxnum, fabs(num3)); if (fabs(den) < 1.e-30 * maxnum) return; *a1 = (float)(num1 / den); *a2 = (float)(num2 / den); *a3 = (float)(num3 / den); *c = ym - *a1 * x1m - *a2 * x2m - *a3 * x3m; }
/* * Show or hide the tile parameters and resize the window */ void AngleDialog::tileParamsClicked() { int curWidth = width(); mParamsOpen = !mParamsOpen; mTileParamButton->setText(mParamsOpen ? "-" : "+"); mTileParamButton->setToolTip (QString(mParamsOpen ? "Hide" : "Show") + QString(" tile size, tolerance, and tilt axis angle entries")); mApp->showHideWidget(mDefTolLabel, mParamsOpen); mApp->showHideWidget(mLeftTolLabel, mParamsOpen); mApp->showHideWidget(mRightTolLabel, mParamsOpen); mApp->showHideWidget(mTileSizeLabel, mParamsOpen); mApp->showHideWidget(mAxisAngleLabel, mParamsOpen); mApp->showHideWidget(mDefTolEdit, mParamsOpen); mApp->showHideWidget(mLeftTolEdit, mParamsOpen); mApp->showHideWidget(mRightTolEdit, mParamsOpen); mApp->showHideWidget(mTileSizeEdit, mParamsOpen); mApp->showHideWidget(mAxisAngleEdit, mParamsOpen); QApplication::processEvents(); QSize hint = sizeHint(); QSize tabhint = mTable->sizeHint(); int height = tabhint.height() - 6.5 * mTable->fontMetrics().height(); height = hint.height() - B3DMAX(0, height); resize(mParamsOpen ? curWidth : (int)(0.85 * hint.width()), height); }
/* * Ruueads a file of tilt angles whose name is in angleFile, and which must * have at least nzz lines. angleSign should be 1., or -1. to invert the * sign of the angles. Minimum and maximum angles are returned in minAngle * and maxAngle. The return value is the array of tilt angles. */ float *readTiltAngles(const char *angleFile, int nzz, float angleSign, float &minAngle, float &maxAngle) { char angleStr[MAX_LINE]; FILE *fpAngle; int k, err; float currAngle; float *tiltAngles = (float *)malloc(nzz * sizeof(float)); minAngle = 10000.; maxAngle = -10000.; if (!tiltAngles) exitError("Allocating array for tilt angles"); if ((fpAngle = fopen(angleFile, "r")) == 0) exitError("Opening tilt angle file %s", angleFile); for (k = 0; k < nzz; k++) { do { err = fgetline(fpAngle, angleStr, MAX_LINE); } while (err == 0); if (err == -1 || err == -2) exitError("%seading tilt angle file %s\n", err == -1 ? "R" : "End of file while r", angleFile); sscanf(angleStr, "%f", &currAngle); currAngle *= angleSign; minAngle = B3DMIN(minAngle, currAngle); maxAngle = B3DMAX(maxAngle, currAngle); tiltAngles[k] = currAngle; } fclose(fpAngle); return tiltAngles; }
/*! * Computes the minimum [DMIN], maximum [dmax], mean [avg], and standard deviation [SD] * from data in [array], dimensioned [nx] by [ny], for X indices from [ix0] to [ix1] and * Y indices from [iy0] to [iy1], inclusive (numbered from 0 when calling from C). It * also returns the sum in [sumDbl] and sum of squares in [sumSqDl]. */ void arrayMinMaxMeanSd(float *array, int nx, int ny, int ix0, int ix1, int iy0, int iy1, float *dmin, float *dmax, double *sumDbl, double *sumSqDbl, float *avg, float *SD) { float den; float *arrTmp; double sumTmp, sumTmpSq; int ix, iy; *sumDbl = 0.; *sumSqDbl = 0.; *dmin = 1.e37; *dmax = -1.e37; for (iy = iy0; iy <= iy1; iy++) { sumTmp = 0.;; sumTmpSq = 0.; arrTmp = array + (size_t)iy * nx + ix0; for (ix = ix0; ix <= ix1; ix++) { den = *arrTmp++; sumTmp = sumTmp + den; sumTmpSq = sumTmpSq + den * den; *dmin = B3DMIN(*dmin, den); *dmax = B3DMAX(*dmax, den); } *sumDbl += sumTmp; *sumSqDbl += sumTmpSq; } sumsToAvgSDdbl(*sumDbl, *sumSqDbl, ix1 + 1 - ix0, iy1 + 1 - iy0, avg, SD); }
/* * Add after current item */ void MovieSequenceForm::addAfterClicked() { int index = B3DMAX(0, table->currentRow() + 1); if (!index && mSegments->size()) return; addAtIndex(index); }
// If a new surface is required, get one; in any case assign newSurf to cont void utilAssignSurfToCont(ImodView *vi, Iobj *obj, Icont *cont, int newSurf) { if (newSurf != cont->surf) { if (newSurf < 0) { vi->undo->objectPropChg(); newSurf = imodel_unused_surface(obj); obj->surfsize = B3DMAX(newSurf, obj->surfsize); if (newSurf) wprint("Started new surface # %d for modeling in this plane\n", newSurf); } vi->undo->contourPropChg(); cont->surf = newSurf; } }
void ImodvOlist::setFontDependentWidths() { int i, width, minWidth; bool rounded = ImodPrefs->getRoundedStyle(); minWidth = diaGetButtonWidth(this, rounded, 1.3, mButtons[0]->text()); for (i = 0; i < OBJLIST_NUMBUTTONS; i++) { width = diaGetButtonWidth(this, rounded, 1.3, mButtons[i]->text()); width = B3DMAX(minWidth, width); mButtons[i]->setFixedWidth(width); } width = diaGetButtonWidth(this, rounded, 1.8, "Help"); mHelpButton->setFixedWidth(width); mDoneButton->setFixedWidth(width); }
/* * Does common initial tasks for a montage snapshot: allocates the arrays, * (returns true for an error), and saves and adjusts the scale bar data */ bool utilStartMontSnap(int winx, int winy, int xFullSize, int yFullSize, float factor, ScaleBar &barSaved, int &numChunks, unsigned char **framePix, unsigned char ***fullPix, unsigned char ***linePtrs) { int iy, maxLines, line, ch, ndo; int chunkMax = 10000000; // This was needed to get to 2.9 GB on WinXP ScaleBar *barReal = scaleBarGetParams(); maxLines = B3DMAX(1, chunkMax / (4 * xFullSize)); numChunks = (yFullSize + maxLines - 1) / maxLines; *fullPix = (unsigned char **)malloc(numChunks * sizeof (unsigned char *)); if (!*fullPix) return true; for (ch = 0; ch < numChunks; ch++) (*fullPix)[ch] = NULL; *linePtrs = NULL; *framePix = NULL; *framePix = (unsigned char *)malloc(4 * winx * winy); *linePtrs = (unsigned char **)malloc(yFullSize * sizeof(unsigned char *)); if (!*framePix || !*linePtrs) { utilFreeMontSnapArrays(*fullPix, numChunks, *framePix, *linePtrs); return true; } line = 0; for (ch = 0; ch < numChunks; ch++) { ndo = B3DMIN(yFullSize - line, maxLines); (*fullPix)[ch] = (unsigned char *)malloc(ndo * 4 * xFullSize); if (!(*fullPix)[ch]) { imodPrintStderr("Failed on chunk %d, after %u\n", ch, (unsigned int)ch * ndo * 4 * xFullSize); utilFreeMontSnapArrays(*fullPix, numChunks, *framePix, *linePtrs); return true; } for (iy = 0; iy < ndo; iy++) (*linePtrs)[iy+line] = (*fullPix)[ch] + 4 * xFullSize * iy; line += ndo; } // Save and modify scale bar directives barSaved = *barReal; barReal->minLength = B3DNINT(factor * barReal->minLength); barReal->thickness = B3DNINT(factor * barReal->thickness); barReal->indentX = B3DNINT(factor * barReal->indentX); barReal->indentY = B3DNINT(factor * barReal->indentY); return false; }
static int copyAsEllipse(Icont *cont) { Ipoint center; float aa, bb, angle, cosang, sinang, xx, yy; Icont *ellco; double theta; Iobj *toObj; int ind, numNew; ImodView *vw = sData.vw; int obnum = vw->imod->cindex.object; if (cont->psize < 3) return 0; aa = imodContourLength(cont, 1); numNew = B3DMAX(12., aa / 3.); if (imodContourEquivEllipse(cont, ¢er, &aa, &bb, &angle)) return 1; ellco = imodContourNew(); if (!ellco) return 1; cosang = (float)cos((double)angle * RADIANS_PER_DEGREE); sinang = (float)sin((double)angle * RADIANS_PER_DEGREE); ellco->pts = B3DMALLOC(Ipoint, numNew); if (!ellco->pts) return 1; ellco->psize = numNew; for (ind = 0; ind < numNew; ind++) { theta = (ind * 360. * RADIANS_PER_DEGREE) / numNew; xx = aa * cos(theta); yy = bb * sin(theta); ellco->pts[ind].x = cosang * xx - sinang * yy + center.x; ellco->pts[ind].y = sinang * xx + cosang * yy + center.y; ellco->pts[ind].z = cont->pts->z; } obnum = sData.objectNumber - 1; toObj = &vw->imod->obj[obnum]; vbCleanupVBD(toObj); vw->undo->contourAddition(obnum, toObj->contsize); ind = imodObjectAddContour(toObj, ellco); imodContourDefault(ellco); if (ind < 0) return 1; return 0; }
/* * Finds the next section in the current object with a contour, given curz is * the current Z and dir is 1 to go forward or -1 to go back */ int utilNextSecWithCont(ImodView *vi, Iobj *obj, int curz, int dir) { int diff, co, contz; int newz = curz; Icont *cont; if (!obj) return newz; newz = -1; for (co = 0; co < obj->contsize; co++) { cont = &obj->cont[co]; if (!cont->psize) continue; contz = B3DNINT(cont->pts[0].z); contz = B3DMAX(0, B3DMIN(contz, vi->zsize - 1)); diff = dir * (contz - curz); if (diff > 0 && (newz < 0 || diff < dir * (newz - curz))) newz = contz; } return newz >= 0 ? newz : curz; }
// Changes the size of the current point given the zoom and scroll wheel delta value void utilWheelChangePointSize(ImodView *vi, float zoom, int delta) { int ix, iy, pt; Iobj *obj; Icont *cont; float size; imodGetIndex(vi->imod, &ix, &iy, &pt); obj = imodObjectGet(vi->imod); cont = imodContourGet(vi->imod); if (!cont || pt < 0) return; size = imodPointGetSize(obj, cont, pt); if (!size && (!cont->sizes || (cont->sizes && cont->sizes[pt] < 0))) return; size += delta * utilWheelToPointSizeScaling(zoom); size = B3DMAX(0., size); vi->undo->contourDataChg(); imodPointSetSize(cont, pt, size); vi->undo->finishUnit(); imodDraw(vi, IMOD_DRAW_MOD); }
/*! * Computes the minimum [DMIN], maximum [dmax], and mean [dmean] from data in [array], * dimensioned [nx] by [ny], for X indices from [ix0] to [ix1] and Y indices from [iy0] * to [iy1], inclusive (numbered from 0 when calling from C). */ void arrayMinMaxMean(float *array, int nx, int ny, int ix0, int ix1, int iy0, int iy1, float *dmin, float *dmax, float *dmean) { float den, sumTmp; float *arrTmp; double sumDbl; int ix, iy; sumDbl = 0.; *dmin = 1.e37; *dmax = -1.e37; for (iy = iy0; iy <= iy1; iy++) { sumTmp = 0.;; arrTmp = array + (size_t)iy * nx + ix0; for (ix = ix0; ix <= ix1; ix++) { den = *arrTmp++; sumTmp = sumTmp + den; *dmin = B3DMIN(*dmin, den); *dmax = B3DMAX(*dmax, den); } sumDbl += sumTmp; } *dmean = sumDbl / ((double)(ix1 + 1 - ix0) * (iy1 + 1 - iy0)); }
/* * Sets up variables for defining the input size and center, and section lists * for the 2D processing case, and also sets ox, oy,oz and output mode. */ void set_input_options(ClipOptions *opt, MrcHeader *hin) { int i, zst, znd, ozst; if (opt->nofsecs == IP_DEFAULT){ opt->nofsecs = hin->nz; opt->secs = (int *)malloc(sizeof(int) * hin->nz); for (i = 0; i < hin->nz; i++) opt->secs[i] = i; } if (opt->dim == 3){ if (opt->iz == IP_DEFAULT){ opt->iz = hin->nz; } if (opt->cz == IP_DEFAULT){ opt->cz = hin->nz * 0.5f; } /* If there is no output entry, make it be same as input; but if there is, and it is smaller output, trim input to that size */ if (opt->oz == IP_DEFAULT) opt->oz = opt->iz; else if (opt->iz > opt->oz) opt->iz = opt->oz; /* Set up a section list for the case where something is treated as 2d without -2d being given */ if (opt->nofsecs != IP_DEFAULT) free(opt->secs); zst = (int)floor(opt->cz - opt->iz / 2.); znd = B3DMAX(B3DMIN(zst + opt->iz - 1, hin->nz - 1), 0); zst = B3DMAX(B3DMIN(zst, hin->nz - 1), 0); opt->nofsecs = znd + 1 - zst; opt->secs = (int *)malloc(sizeof(int) * opt->nofsecs); for (i = zst; i <= znd; i++) opt->secs[i - zst] = i; /* If requested output is larger than this output set, keep track of blank slices to put out before and after */ if (opt->oz != IP_DEFAULT && opt->oz > opt->nofsecs) { ozst = (int)floor(opt->cz - opt->oz / 2.); opt->outBefore = B3DMAX(0, zst - ozst); opt->outAfter = opt->oz - opt->nofsecs - opt->outBefore; if (opt->outAfter < 0) { opt->outBefore += opt->outAfter; opt->outAfter = 0; } } } else { /* 2D case: use section list size for default output size */ if (opt->oz == IP_DEFAULT) opt->oz = opt->nofsecs; } /* Convert starting, ending X or Y to ix/cx entries - main routine already checked for conflict */ if (opt->x != IP_DEFAULT) { opt->x2 = B3DMAX(opt->x, opt->x2); opt->cx = (opt->x + opt->x2 + 1) / 2.; opt->ix = opt->x2 + 1 - opt->x; } if (opt->ix == IP_DEFAULT) opt->ix = hin->nx; if ((int)opt->cx == IP_DEFAULT) opt->cx = hin->nx * 0.5f; if (opt->ox == IP_DEFAULT) { opt->ox = opt->ix; if (opt->process == IP_UNPACK) opt->ox *= 2; } else { if (!opt->ocanresize){ show_warning("clip - Process can't change output size."); opt->ox = opt->ix; } } if (opt->y != IP_DEFAULT) { opt->y2 = B3DMAX(opt->y, opt->y2); opt->cy = (opt->y + opt->y2 + 1) / 2.; opt->iy = opt->y2 + 1 - opt->y; } if (opt->iy == IP_DEFAULT) opt->iy = hin->ny; if ((int)opt->cy == IP_DEFAULT) opt->cy = hin->ny * 0.5f; if (opt->oy == IP_DEFAULT) opt->oy = opt->iy; else{ if (!opt->ocanresize){ show_warning("clip - Process can't change output size."); opt->oy = opt->iy; } } if (opt->pad == IP_DEFAULT) opt->pad = hin->amean; if (opt->mode == IP_DEFAULT) opt->mode = hin->mode; }
/* Write the data volume with potential padding */ int grap_volume_write(Istack *v, MrcHeader *hout, ClipOptions *opt) { FILE *fp = hout->fp; int zs, ks, z; int k; float min, max, mean, zscale; Islice *s, *ps = NULL; int labels; if (opt->mode == IP_DEFAULT) opt->mode = v->vol[0]->mode; if (opt->ox == IP_DEFAULT) opt->ox = v->vol[0]->xsize; if (opt->oy == IP_DEFAULT) opt->oy = v->vol[0]->ysize; if (opt->oz == IP_DEFAULT) opt->oz = v->zsize; if (v->vol[0]->mode != opt->mode) for(k = 0; k < v->zsize; k++){ sliceNewMode(v->vol[k], opt->mode); } /* calculate min, max, mean of volume. */ sliceMMM(v->vol[0]); min = v->vol[0]->min; max = v->vol[0]->max; mean = v->vol[0]->mean; for(k = 1; k < v->zsize; k++){ sliceMMM(v->vol[k]); min = B3DMIN(min, v->vol[k]->min); max = B3DMAX(max, v->vol[k]->max); mean += v->vol[k]->mean; } mean /= (float)v->zsize; /* DNM 6/26/02: do not make a new header if appending or overwriting! */ switch(opt->add2file){ case IP_APPEND_OVERWRITE: ks = opt->isec; hout->nz = ks + opt->oz; opt->ox = hout->nx; opt->oy = hout->ny; if (hout->mode != v->vol[0]->mode){ fprintf(stderr, "overwriting requires data modes to be the same.\n"); return(-1); } /* DNM 6/26/02: fix min and max, also fix mz and zlen */ /* DNM 9/13/02: oops, had xlen instead of zlen */ /* todo: recalc mmm. This is a start but not much */ hout->amin = B3DMIN(min, hout->amin); hout->amax = B3DMAX(max, hout->amax); zscale = hout->zlen / hout->mz; hout->mz = hout->nz; hout->zlen = hout->mz * zscale; break; case IP_APPEND_ADD: ks = hout->nz; hout->nz = hout->nz + opt->oz; opt->ox = hout->nx; opt->oy = hout->ny; if (hout->mode != v->vol[0]->mode){ fprintf(stderr, "inserting requires data modes to be the same.\n"); return(-1); } hout->amin = B3DMIN(min, hout->amin); hout->amax = B3DMAX(max, hout->amax); hout->amean = ((hout->amean * ks) + (mean * opt->oz)) / hout->nz; zscale = hout->zlen / hout->mz; hout->mz = hout->nz; hout->zlen = hout->mz * zscale; break; case IP_APPEND_FALSE: /* New file: reinitialize header but preserve the labels, set min/max/mean */ labels = hout->nlabl; mrc_head_new(hout, opt->ox, opt->oy, opt->oz, v->vol[0]->mode); hout->nlabl = labels; hout->amin = min; hout->amax = max; hout->amean = mean; ks = 0; } if (opt->pad == IP_DEFAULT) opt->pad = hout->amean; if (mrc_head_write(fp, hout)) return -1; zs = (v->zsize - opt->oz) / 2; for (k = ks, z = zs; k < hout->nz; k++, z++) { /* printf("%d %d\n", k, z);*/ /* Write blank slice outside z range */ if ((z < 0) || (z >= v->zsize)) { if (!ps) { ps = clipBlankSlice(hout, opt); if (!ps) return -1; } if (mrc_write_slice((void *)ps->data.b, fp, hout, k, 'z')) return (-1); } else { /* Resize slice only if necessary */ s = v->vol[z]; if (opt->ox != v->vol[0]->xsize || opt->oy != v->vol[0]->ysize) { v->vol[z]->mean = opt->pad; s = mrc_slice_resize(v->vol[z], opt->ox, opt->oy); if (!s){ fprintf(stderr, "volume_write: error resizing slice.\n"); return(-1); } } if (mrc_write_slice((void *)s->data.b, fp, hout, k, 'z')) return (-1); if (opt->ox != v->vol[0]->xsize || opt->oy != v->vol[0]->ysize) sliceFree(s); } } if (ps) sliceFree(ps); return(0); }
/* * Write one slice to output file * kSec is the index of the sections being processed, * zWrite is address of z value at which to write, maintained here * freeSlice 1 indicates to free the slice when done */ int clipWriteSlice(Islice *slice, MrcHeader *hout, ClipOptions *opt, int kSec, int *zWrite, int freeSlice) { Islice *ps = NULL; Islice *s; int z; int blankBefore = 0; int blankAfter = 0; /* Ignore if output size is smaller than # being processed */ if (kSec < (opt->nofsecs - opt->oz) / 2 || kSec >= (opt->nofsecs - opt->oz) / 2 + opt->oz) { if (freeSlice) sliceFree(slice); return 0; } /* determine if blank slices need to be written before or after this slice */ if (opt->oz > opt->nofsecs) { if (!kSec) { if (opt->outBefore == IP_DEFAULT) blankBefore = (opt->oz - opt->nofsecs) / 2; else blankBefore = opt->outBefore; } if (kSec == opt->nofsecs - 1) { if (opt->outAfter == IP_DEFAULT) blankAfter = opt->oz - opt->nofsecs - (opt->oz - opt->nofsecs) / 2; else blankAfter = opt->outAfter; } if (blankBefore || blankAfter) { ps = clipBlankSlice(hout, opt); if (!ps) return -1; } } /* Write blank slices before */ for (z = 0; z < blankBefore; z++) if (mrc_write_slice((void *)ps->data.b, hout->fp, hout, (*zWrite)++, 'z')) return -1; /* convert slice to output mode if needed */ if (slice->mode != opt->mode && sliceNewMode(slice, opt->mode) < 0) return -1; /* Resize slice if necessary */ s = slice; if (opt->ox != slice->xsize || opt->oy != slice->ysize) { slice->mean = opt->pad; s = mrc_slice_resize(slice, opt->ox, opt->oy); if (!s) { fprintf(stderr, "clipWriteSlice: error resizing slice.\n"); return(-1); } } /* maintain min & max, add to mean unless overwriting */ sliceMMM(s); hout->amin = B3DMIN(hout->amin, s->min); hout->amax = B3DMAX(hout->amax, s->max); if (opt->add2file != IP_APPEND_OVERWRITE) hout->amean += (s->mean + (blankBefore + blankAfter) * opt->pad) / hout->nz; /* Write slice, free slices as needed */ if (mrc_write_slice((void *)s->data.b, hout->fp, hout, (*zWrite)++, 'z')) return -1; if (opt->ox != slice->xsize || opt->oy != slice->ysize) sliceFree(s); if (freeSlice) sliceFree(slice); /* Write blank slices after */ for (z = 0; z < blankAfter; z++) if (mrc_write_slice((void *)ps->data.b, hout->fp, hout, (*zWrite)++, 'z')) return -1; if (ps) sliceFree(ps); return 0; }
static void fillPatchFromTiles(std::vector<FastSegment> &segments, std::vector<int> &startInds, int ushort, unsigned char *bmap, int fillXsize, int istart, int iend, int jstart, int jend) { int u, v, j, i, iseg, numSeg, segEnd, nextToFill, uvind, segStart; FastSegment *segp; unsigned char *imdata; unsigned short *usimdata; unsigned char pix; for (j = jstart; j < jend; j++) { v = j - jstart; numSeg = startInds[j + 1] - startInds[j]; nextToFill = istart; for (iseg = startInds[j]; iseg < startInds[j + 1]; iseg++) { segp = &(segments[iseg]); // If segment starts past the end, done with segments if (segp->XorY >= iend) break; // If segment ends before the start, skip it if (segp->XorY + segp->length <= istart) continue; // If segment starts past next place to fill, need to fill with 0's if (segp->XorY > nextToFill) { for (i = nextToFill; i < segp->XorY; i++) { u = i - istart; FILLDATA(0); } } // Fill with segment data segEnd = B3DMIN(segp->XorY + segp->length, iend); segStart = B3DMAX(segp->XorY, istart); imdata = segp->line + segp->stride * (segStart - segp->XorY); if (ushort) { usimdata = (unsigned short *)imdata; for (i = segStart; i < segEnd; i++) { u = i - istart; pix = bmap[*usimdata]; usimdata += segp->stride; FILLDATA(pix); } } else { for (i = segStart; i < segEnd; i++) { u = i - istart; pix = *imdata; imdata += segp->stride; FILLDATA(pix); } } nextToFill = segEnd; } // Fill past end for (i = nextToFill; i < iend; i++) { u = i - istart; FILLDATA(0); } } }
/* * Determines whether the mouse has moved enough from the mouse press point to commit * the rubber band to a certain direction. If so it assigns the corners in the correct * order and sets dragging flags. */ int utilIsBandCommitted(int x, int y, int winX, int winY, int bandmin, int &rbMouseX0, int &rbMouseX1, int &rbMouseY0, int &rbMouseY1, int *dragging) { int bandCrit1 = 3 * bandmin; int bandCrit2 = 6 * bandmin; int bandMin2 = B3DMAX(1, bandmin / 2); int diffX, diffY, absDiffX, absDiffY, i, longc = 0; // get differences and absolute differences diffX = x - rbMouseX0; diffY = y - rbMouseY0; absDiffX = diffX < 0 ? -diffX : diffX; absDiffY = diffY < 0 ? -diffY : diffY; // If one axis change is still zero but the other is big enough, commit to the // direction toward middle of window; revise differences if (!diffY && absDiffX >= bandCrit2) { if (y < winY / 2) y = rbMouseY0 + bandmin; else y = rbMouseY0 - bandmin; absDiffY = bandmin; longc = 1; } else if (!diffX && absDiffY >= bandCrit2) { if (x < winX / 2) x = rbMouseX0 + bandmin; else x = rbMouseX0 - bandmin; absDiffX = bandmin; longc = 2; } // Ready to start if both directions are bigger than the minimum, or one is // bigger than a criterion and the other is big enough if (!((absDiffX >= bandmin && absDiffY >= bandmin) || (absDiffX >= bandCrit1 && absDiffY >= bandMin2 ) || (absDiffY >= bandCrit1 && absDiffX >= bandMin2))) return 0; //imodPrintStderr("COMMIT rb0 %d %d x,y %d %d diffX %d diffY %d longc %d\n", // rbMouseX0,rbMouseY0 , x, y, absDiffX, absDiffY , longc); for (i = 0; i < 4; i++) dragging[i] = 0; // Put the two coords in order on each axis and set the dragging flags if (x > rbMouseX0) { dragging[1] = 1; rbMouseX1 = x; } else { dragging[0] = 1; rbMouseX1 = rbMouseX0; rbMouseX0 = x; } if (y > rbMouseY0) { dragging[3] = 1; rbMouseY1 = y; } else { dragging[2] = 1; rbMouseY1 = rbMouseY0; rbMouseY0 = y; } return 1; }
/* * Main entry */ int main( int argc, char *argv[]) { Imod *imod; Iobj *obj; Ipoint point; Istore store; FILE *infp; char line[1024]; int open = 0, zsort = 0, scat = 0, numPerCont = 0, fromZero = 0, zFromZero = 0; int err, nvals, nread, ob, co, lineNum, after, needcont, i, numOffset, linelen; int numPts = 0, numConts = 0, numObjs = 0; int sphere = 0, circle = 0; float tst1, tst2, xx, yy, zz, value; float zOffset = 0.; int numColors = 0; int numNames = 0; int hasValues = 0; int contValues = 0; int *red, *green, *blue; int directScale = 0; float xscale = 1., yscale = 1., zscale = 1., xtrans = 0., ytrans = 0., ztrans = 0.; char **names = NULL; char *progname = imodProgName(argv[0]); char *filename, *imagename; MrcHeader hdata; IrefImage *ref; FILE *fpimage = NULL; char *errString; int numOptArgs, numNonOptArgs; /* Fallbacks from ../manpages/autodoc2man 2 1 point2model */ int numOptions = 16; const char *options[] = { "input:InputFile:FN:", "output:OutputFile:FN:", "open:OpenContours:B:", "scat:ScatteredPoints:B:", "number:PointsPerContour:I:", "planar:PlanarContours:B:", "zero:NumberedFromZero:B:", "zcoord:ZCoordinatesFromZero:B:", "values:ValuesInLastColumn:I:", "circle:CircleSize:I:", "sphere:SphereRadius:I:", "color:ColorOfObject:ITM:", "name:NameOfObject:CHM:", "image:ImageForCoordinates:FN:", "pixel:PixelSpacingOfImage:FT:", "origin:OriginOfImage:FT:" }; /* Startup with fallback */ PipReadOrParseOptions(argc, argv, options, numOptions, progname, 2, 1, 1, &numOptArgs, &numNonOptArgs, imodUsageHeader); /* Get input and output files */ if (PipGetInOutFile("InputFile", 0, &filename)) exitError("No input file specified"); infp = fopen(filename, "r"); if (!infp) exitError("Error opening input file %s", filename); free(filename); if (PipGetInOutFile("OutputFile", 1, &filename)) exitError("No output file specified"); if (!PipGetString("ImageForCoordinates", &imagename)) { fpimage = fopen(imagename, "rb"); if (!fpimage) exitError("Could not open image file for coordinates: %s", imagename); if (mrc_head_read(fpimage, &hdata)) exitError("Reading header from %s", imagename); free(imagename); } directScale = 2 - PipGetThreeFloats("PixelSpacingOfImage", &xscale, &yscale, &zscale) - PipGetThreeFloats("OriginOfImage", &xtrans, &ytrans, &ztrans); if (directScale && fpimage) exitError("You cannot use -image together with -pixel or -origin"); err = PipGetInteger("PointsPerContour", &numPerCont); err = PipGetInteger("SphereRadius", &sphere); err = PipGetInteger("CircleSize", &circle); err = PipGetBoolean("OpenContours", &open); err = PipGetBoolean("ScatteredPoints", &scat); err = PipGetBoolean("PlanarContours", &zsort); err = PipGetInteger("ValuesInLastColumn", &hasValues); err = PipGetBoolean("ZCoordinatesFromZero", &zFromZero); if (zFromZero) zOffset = 0.5; B3DCLAMP(hasValues, -1, 1); if (hasValues < 0) { hasValues = 1; contValues = 1; } err = PipGetBoolean("NumberedFromZero", &fromZero); numOffset = 1 - fromZero; if (numPerCont < 0) exitError("Number of points per contour must be positive or zero"); if (open + scat > 1) exitError("Only one of -open or -scat may be entered"); // Get colors err = PipNumberOfEntries("ColorOfObject", &numColors); if (numColors) { red = (int *)malloc(numColors * sizeof(int)); green = (int *)malloc(numColors * sizeof(int)); blue = (int *)malloc(numColors * sizeof(int)); if (!red || !green || !blue) exitError("Allocating memory for colors"); for (co = 0; co < numColors; co++) err = PipGetThreeIntegers("ColorOfObject", &red[co], &green[co], &blue[co]); } // Get names err = PipNumberOfEntries("NameOfObject", &numNames); if (numNames) { names = (char **)malloc(numNames * sizeof(char *)); if (!names) exitError("Allocating memory for names"); for (co = 0; co < numNames; co++) err = PipGetString("NameOfObject", &names[co]); } PipDone(); // Read first line of file, figure out how many values if (fgetline(infp, line, 1024) <= 0) exitError("Reading beginning of file"); nvals = sscanf(line, "%f %f %f %f %f %f", &tst1, &tst2, &xx, &yy, &zz, &value); nvals -= hasValues; if (nvals < 3) exitError("There must be at least %d values per line", 3 + hasValues); nvals = B3DMIN(nvals, 5); if (numPerCont && nvals > 3) { exitError("The point file has contour numbers and the -number option " "cannot be used"); } if (zsort && nvals > 3) exitError("The point file has contour numbers and the -planar option " "cannot be used"); rewind(infp); imod = imodNew(); if (!imod) exitError("Failed to get model structure"); // Set the image reference scaling if (fpimage) { imodSetRefImage(imod, &hdata); fclose(fpimage); } else if (directScale) { imod->refImage = (IrefImage *)malloc(sizeof(IrefImage)); if (!imod->refImage) exitError("Allocating IrefImage structure"); ref = imod->refImage; ref->ctrans.x = xtrans; ref->ctrans.y = ytrans; ref->ctrans.z = ztrans; ref->cscale.x = xscale; ref->cscale.y = yscale; ref->cscale.z = zscale; ref->oscale.x = ref->oscale.y = ref->oscale.z = 1.; ref->orot.x = ref->orot.y = ref->orot.z = 0.; ref->crot.x = ref->crot.y = ref->crot.z = 0.; ref->otrans.x = ref->otrans.y = ref->otrans.z = 0.; } ob = 0; co = 0; lineNum = 0; imod->xmax = 0.; imod->ymax = 0.; imod->zmax = 0.; store.type = GEN_STORE_VALUE1; store.flags = GEN_STORE_FLOAT << 2; // To do: error check contour and object #'s, and they are numbered from 1. while (1) { // get line, done on EOF, skip blank line linelen = fgetline(infp, line, 1024); if (linelen < 0) break; if (linelen == 0) continue; if (nvals == 3) { nread = sscanf(line, "%f %f %f %f", &xx, &yy, &zz, &value); } else if (nvals == 4) { nread = sscanf(line, "%d %f %f %f %f", &co, &xx, &yy, &zz, &value); co -= numOffset; } else { nread = sscanf(line, "%d %d %f %f %f %f", &ob, &co, &xx, &yy, &zz, &value); co -= numOffset; ob -= numOffset; } zz -= zOffset; lineNum++; // Skip line with no values if (nread <= 0) continue; if (B3DMIN(5 + hasValues, nread) != nvals + hasValues && !(contValues && nread == nvals)) exitError("Every line should have %d entries; line %d has %d", nvals + hasValues, lineNum, nread); if (ob < 0 || co < 0) exitError("Illegal object or contour number (object %d, contour %d at line %d", ob + numOffset, co + numOffset, lineNum); // Add objects if needed to get to the current object if (ob >= imod->objsize) { for (i = imod->objsize; i <= ob; i++) { if (imodNewObject(imod)) exitError("Failed to add object to model"); if (open) imod->obj[i].flags |= IMOD_OBJFLAG_OPEN; if (scat) imod->obj[i].flags |= IMOD_OBJFLAG_SCAT | IMOD_OBJFLAG_OPEN; numObjs++; imod->obj[i].pdrawsize = B3DMAX(0, sphere); if (circle > 0) { imod->obj[i].symsize = circle; imod->obj[i].symbol = IOBJ_SYM_CIRCLE; } if (i < numColors) { imod->obj[i].red = red[i] / 255.; imod->obj[i].green = green[i] / 255.; imod->obj[i].blue = blue[i] / 255.; } if (i < numNames) { strncpy(imod->obj[i].name, names[i], IOBJ_STRSIZE - 1); imod->obj[i].name[IOBJ_STRSIZE - 1] = 0x00; } } } // Determine if a contour is needed: either the contour number is too high // or the number limit is reached or there is a change in Z needcont = 0; obj = &imod->obj[ob]; if (co >= obj->contsize) needcont = 1; else if ((numPerCont && obj->cont[co].psize >= numPerCont) || (zsort && B3DNINT(obj->cont[co].pts[0].z) != B3DNINT(zz))) { co++; needcont = 1; } if (needcont) { imodSetIndex(imod, ob, -1, -1); for (i = obj->contsize; i<= co; i++) { if (imodNewContour(imod)) exitError("Failed to add contour to model"); numConts++; } } point.x = xx; point.y = yy; point.z = zz; imod->xmax = B3DMAX(imod->xmax, B3DNINT(xx + 10.)); imod->ymax = B3DMAX(imod->ymax, B3DNINT(yy + 10.)); imod->zmax = B3DMAX(imod->zmax, B3DNINT(zz + 1.)); if (!imodPointAppend(&obj->cont[co], &point)) exitError("Failed to add point to contour"); numPts++; // take care of value for contour or point, only add one per contour if (hasValues) { store.value.f = value; err = 0; if (contValues && istoreLookup(obj->store, co, &after) < 0) { if (nread < nvals + 1) exitError("The first point for a contour must have a value entry; line %d " "has only %d entries", lineNum, nread); store.index.i = co; err = istoreInsert(&obj->store, &store); } else { store.index.i = obj->cont[co].psize - 1; err = istoreInsert(&obj->cont[co].store, &store); } if (err) exitError("Failed to add general value"); } } // Get the object min/max values set up if (hasValues) { for (ob = 0; ob < imod->objsize; ob++) { if (imod->obj[ob].contsize && istoreFindAddMinMax1(&imod->obj[ob])) exitError("Adding min/max values to object"); } } // Attach image file's size as the max values if (fpimage) { imod->xmax = hdata.nx; imod->ymax = hdata.ny; imod->zmax = hdata.nz; } fclose(infp); if (imodBackupFile(filename)) printf("Warning: %s - Failed to make old version of %s be a backup file\n", progname, filename); imod->file = fopen(filename, "wb"); if (!imod->file) exitError("Opening new model file %s", filename); if (imodWriteFile(imod)) exitError("Writing model file %s", filename); free(filename); printf("Model created with %d objects, %d contours, %d points\n", numObjs, numConts, numPts); exit(0); }
/* Draw one of the image arrays in a subarea of the window */ void TumblerWindow::drawSubArea(TumblerStruct *xtum, unsigned short *sdata, int llx, int urx) { float scale, offset; unsigned int i, xysize; unsigned char *data; b3dUInt16 *usdata; float tf, tmax, tmin; int xo, yo; int zoom = xtum->zoom; xysize = xtum->slice->xsize * xtum->slice->ysize; data = xtum->bwslice->data.b; usdata = xtum->bwslice->data.us; scaleData(xtum, sdata); tmax = 255.0f; tmin = 0.0f; scale = xtum->scale; offset = xtum->offset; /* DNM: scale for depth 8 only if not rgba */ if (App->depth == 8 && !App->rgba){ scale *= xtum->vi->rampsize/256.0f; tmax = xtum->vi->rampbase + xtum->vi->rampsize; tmin = xtum->vi->rampbase; for(i = 0; i < xysize; i++){ tf = ((sdata[i] + offset) * scale) + xtum->vi->rampbase; if (tf < tmin) tf = tmin; if (tf > tmax) tf = tmax; data[i] = (unsigned char)tf; } } else if (xtum->vi->ushortStore) { tmax = 65535.; scale *= 256.; for (i = 0; i < xysize; i++) { tf = (sdata[i] + offset) * scale; usdata[i] = (b3dUInt16)B3DMAX(tmin, B3DMIN(tmax, tf)); } } else { for(i = 0; i < xysize; i++){ tf = (sdata[i] + offset) * scale; data[i] = (unsigned char)B3DMAX(tmin, B3DMIN(tmax, tf)); } } if (xtum->highres) zoom = 1; /* DNM 1/20/02: add slice argument to graphics calls; make it -1 to prevent image re-use */ b3dDrawGreyScalePixelsSubArea (xtum->image, ivwMakeLinePointers(xtum->vi, data, xtum->slice->xsize, xtum->slice->ysize, xtum->vi->rawImageStore), xtum->slice->xsize, xtum->slice->ysize, 0, 0, llx, 0, urx, xtum->height, xtum->vi->rampbase, zoom, &xo, &yo, -1); }
/* Really fill the slice data for one slice */ void TumblerWindow::fillASlice(TumblerStruct *xtum) { unsigned short *sdata; short *ndata = xtum->count->data.s; int xysize = xtum->slice->xsize * xtum->slice->ysize; int n; float xs, ys, zs, xt, yt, zt; float x, y, z; float xsx, xsy, xsz; float ysx, ysy, ysz; float zsx, zsy, zsz; float xtz, ytz, ztz; int isize, jsize; int ksize, xsize, ysize, zsize; int xi, yi, zi; int i, j, k; float zoomfac; int xmin,ymin,zmin,xmax,ymax,zmax; int val; float dx, dy, dz; float x1, x2, y1, y2, z1, z2; float a, b, c, d, e, f; int pxi, nxi, pyi, nyi, pzi, nzi, cindex; int maxval = xtum->maxval; int minval = xtum->minval; float dsum; int nsum, shortcut, izoom, ilimshort, jlimshort, ishort, fillval, nmax; float zoom = xtum->zoom; unsigned char *bmap = NULL; sdata = (unsigned short *)xtum->slice->data.s; if (xtum->slice->xsize <= 0) return; if (xtum->slice->ysize <= 0) return; if (xtum->vi->ushortStore) { bmap = ivwUShortInRangeToByteMap(xtum->vi); if (!bmap) return; } zoomfac = xtum->highres ? zoom : 1.0; xmin = xtum->cx - xtum->nx/2; if (xmin < 0) xmin = 0; ymin = xtum->cy - xtum->ny/2; if (ymin < 0) ymin = 0; zmin = xtum->cz - xtum->nz/2; if (zmin < 0) zmin = 0; xmax = xtum->cx + xtum->nx/2; if (xmax >= xtum->vi->xsize) xmax = xtum->vi->xsize - 1; ymax = xtum->cy + xtum->ny/2; if (ymax >= xtum->vi->ysize) ymax = xtum->vi->ysize - 1; zmax = xtum->cz + xtum->nz/2; if (zmax >= xtum->vi->zsize) zmax = xtum->vi->zsize - 1; isize = xtum->slice->xsize; jsize = xtum->slice->ysize; ksize = xtum->ms; xsize = xtum->vi->xsize; ysize = xtum->vi->ysize; zsize = xtum->vi->zsize; xsx = xtum->xstep.x/zoomfac; xsy = xtum->xstep.y/zoomfac; xsz = xtum->xstep.z/zoomfac; ysx = xtum->ystep.x/zoomfac; ysy = xtum->ystep.y/zoomfac; ysz = xtum->ystep.z/zoomfac; /* Steps in Z are independent of highres */ zsx = xtum->zstep.x; zsy = xtum->zstep.y; zsz = xtum->zstep.z; /* DNM 4/29/04: rewrote for compactness and clarity */ xs = xtum->cx - 0.5f * (xsx * isize + ysx * jsize + zsx * xtum->ms); ys = xtum->cy - 0.5f * (xsy * isize + ysy * jsize + zsy * xtum->ms); zs = xtum->cz - 0.5f * (xsz * isize + ysz * jsize + zsz * xtum->ms); /* imodPrintStderr("xyzs %f %f %f\n", xs, ys, zs); */ x = xs; y = ys; z = zs; shortcut = 0; izoom = (int)zoom; if (xtum->highres && (zoom == izoom) && (zoom > 1.0)) { shortcut = 1; ilimshort = izoom * ((isize - 1) / izoom - 1); jlimshort = izoom * ((jsize - 1) / izoom - 1); } else izoom = 1; for(n = 0; n < xysize; n++) { sdata[n] = 0; ndata[n] = 0; } for(k = 0; k < ksize; k++){ xtz = x; ytz = y; ztz = z; for(j = 0, n = 0; j < jsize; j++){ xt = x; yt = y; zt = z; cindex = j * isize; for(i = 0; i < isize; i++){ /* DNM 2/25/03: eliminate floor as in slicer */ xi = (int)x; yi = (int)y; zi = (int)(z + 0.5); if ((xi >= xmin) && (xi <= xmax) && (yi >= ymin) && (yi <= ymax) && (zi >= zmin) && (zi <= zmax) ){ val = (*ivwFastGetValue)(xi, yi, zi); if (xtum->highres) { dx = x - xi - 0.5; dy = y - yi - 0.5; dz = z - zi; pxi = xi - 1; nxi = xi + 1; pyi = yi - 1; nyi = yi + 1; pzi = zi - 1; nzi = zi + 1; if (pxi < 0) pxi = 0; if (nxi >= xsize) nxi = xi; if (pyi < 0) pyi = 0; if (nyi >= ysize) nyi = yi; if (pzi < 0) pzi = 0; if (nzi >= zsize) nzi = zi; x1 = (*ivwFastGetValue)(pxi, yi, zi); x2 = (*ivwFastGetValue)(nxi, yi, zi); y1 = (*ivwFastGetValue)( xi, pyi, zi); y2 = (*ivwFastGetValue)( xi, nyi, zi); z1 = (*ivwFastGetValue)( xi, yi, pzi); z2 = (*ivwFastGetValue)( xi, yi, nzi); a = (x1 + x2) * 0.5f - (float)val; b = (y1 + y2) * 0.5f - (float)val; c = (z1 + z2) * 0.5f - (float)val; d = (x2 - x1) * 0.5f; e = (y2 - y1) * 0.5f; f = (z2 - z1) * 0.5f; val = (int) ((a * dx * dx) + (b * dy * dy) + (c * dz * dz) + (d * dx) + (e * dy) + (f * dz) + (float)val + 0.5); } if (bmap) val = bmap[B3DMAX(0, B3DMIN(65535, val))]; if (val > maxval) val = maxval; if (val < minval) val = minval; sdata[cindex + i] += (unsigned short)val; ndata[cindex + i]++; } x += xsx; y += xsy; z += xsz; /* If taking short cut, advance the source position to get to next unzoomed pixel position */ if (shortcut != 0 && ((i >= izoom && j % izoom == 0) || (i >= izoom - 1 && j % izoom != 0)) && i < ilimshort && j >= izoom && j < jlimshort) { ishort = izoom - 1; if (j % izoom) ishort = ilimshort - izoom; x += xsx * ishort; y += xsy * ishort; z += xsz * ishort; i += ishort; } } x = xt + ysx; y = yt + ysy; z = zt + ysz; } x = xtz + zsx; y = ytz + zsy; z = ztz + zsz; } nmax = 0; nsum = 0; dsum = 0.; for (n = 0; n < xysize; n++) { if (nmax < ndata[n]) nmax = ndata[n]; nsum += ndata[n]; dsum += sdata[n]; } fillval = (int)(dsum / nsum + 0.5); for(n = 0; n < xysize; n++) sdata[n] += (nmax - ndata[n]) * fillval; xtum->fillval = fillval * nmax; if (shortcut) slicerCubicFillin(sdata, isize, jsize, izoom, ilimshort, jlimshort, 0, 65535, 0); B3DFREE(bmap); }
int main( int argc, char *argv[] ) { int i = 0; FILE *fin, *fout; struct MRCheader hdata, hout; struct MRCheader *hptr; unsigned char *buf; int bsize, csize, dsize; int inside = 0; int ntaper = DEFAULT_TAPER; int taperEntered = 0; Islice slice; int zmin = -1, zmax = -1; int secofs; char *progname = imodProgName(argv[0]); setStandardExitPrefix(progname); if (argc < 2){ fprintf(stderr, "%s version %s\n", progname, VERSION_NAME); imodCopyright(); mrctaper_help(progname); exit(3); } for (i = 1; i < argc; i++) { if (argv[i][0] == '-') { switch (argv[i][1]) { case 'i': inside = 1; break; case 't': taperEntered = 1; if (argv[i][2] != 0x00) sscanf(argv[i], "-t%d", &ntaper); else sscanf(argv[++i], "%d", &ntaper); break; case 'z': if (argv[i][2] != 0x00) sscanf(argv[i], "-z%d%*c%d", &zmin, &zmax); else sscanf(argv[++i], "%d%*c%d", &zmin, &zmax); break; default: printf("ERROR: %s - illegal option\n", progname); mrctaper_help(progname); exit(1); break; } } else break; } if (i < (argc - 2) || i == argc){ mrctaper_help(progname); exit(3); } if (ntaper < 1 || ntaper > 127) exitError("Taper must be between 1 and 127."); if (i < argc - 1) fin = iiFOpen(argv[i++], "rb"); else fin = iiFOpen(argv[i++], "rb+"); if (fin == NULL) exitError("Opening %s.", argv[i - 1]); if (mrc_head_read(fin, &hdata)) exitError("Can't Read Input File Header."); if (sliceModeIfReal(hdata.mode) < 0) exitError("Can operate only on byte, integer and real data."); if (!taperEntered) { ntaper = (hdata.nx + hdata.ny) / 200; ntaper = B3DMIN(127, B3DMAX(DEFAULT_TAPER, ntaper)); printf("Tapering over %d pixels\n", ntaper); } if (zmin == -1 && zmax == -1) { zmin = 0; zmax = hdata.nz - 1; } else { if (zmin < 0) zmin = 0; if (zmax >= hdata.nz) zmax = hdata.nz - 1; } if (i < argc) { fout = iiFOpen(argv[i], "wb"); if (fout == NULL) exitError("Opening %s.", argv[i]); hout = hdata; hout.fp = fout; /* DNM: eliminate extra header info in the output, and mark it as not swapped */ mrcInitOutputHeader(&hout); hptr = &hout; hout.nz = zmax + 1 - zmin; hout.mz = hout.nz; hout.zlen = hout.nz; secofs = zmin; } else { if (b3dOutputFileType() == IIFILE_TIFF) exitError("Cannot write to an existing TIFF file."); hptr = &hdata; fout = fin; secofs = 0; } mrc_getdcsize(hdata.mode, &dsize, &csize); bsize = hdata.nx * hdata.ny; buf = (unsigned char *)malloc(dsize * csize * bsize); if (!buf) exitError("Couldn't get memory for slice."); sliceInit(&slice, hdata.nx, hdata.ny, hdata.mode, buf); for (i = zmin; i <= zmax; i++) { printf("\rDoing section #%4d", i); fflush(stdout); if (mrc_read_slice(buf, fin, &hdata, i, 'Z')) exitError("Reading section %d.", i); if (sliceTaperAtFill(&slice, ntaper, inside)) exitError("Can't get memory for taper operation."); if (mrc_write_slice(buf, fout, hptr, i - secofs, 'Z')) exitError("Writing section %d.", i); } puts("\nDone!"); mrc_head_label(hptr, "mrctaper: Image tapered down to fill value at edges"); mrc_head_write(fout, hptr); iiFClose(fout); return(0); }
int main( int argc, char *argv[]) { int i, ind, col, maxValType; FILE *fout; Imod *mod; int npatch = 0; int numValues[MAX_VALUE_COLS], valueIDs[MAX_VALUE_COLS]; int ix, iy, iz; int colForVal1 = 1; float dx, dy, dz; float value, maxVal[MAX_VALUE_COLS]; int ob, co, listInd, listStart, numCols; Ipoint *pts; char format[MAX_VALUE_COLS][10]; int colToTypeMap[MAX_VALUE_COLS]; setExitPrefix("ERROR: imod2patch - "); if (argc < 3){ if (argc != 1) printf("ERROR: imod2patch - wrong # of arguments\n"); printf("imod2patch usage:\n"); printf("imod2patch [-v col] imod_model patch_file\n"); exit(1); } for (ind = 0; ind < MAX_VALUE_COLS; ind++) { numValues[ind] = 0; valueIDs[ind] = 0; colToTypeMap[ind] = -1; maxVal[ind] = -1.e37; } i = 1; if (!strcmp(argv[i], "-v")) { i++; colForVal1 = atoi(argv[i++]); } mod = imodRead(argv[i]); if (!mod) exitError("Reading model %s\n", argv[i]); if (imodBackupFile(argv[++i])) exitError("Renaming existing output file to %s\n", argv[i]); fout = fopen(argv[i], "w"); if (!fout) exitError("Could not open %s\n", argv[i]); /* Count up patches and values and find max of values */ for (ob = 0; ob < mod->objsize; ob++) { listInd = 0; for (co = 0; co < mod->obj[ob].contsize; co++) { listStart = listInd; if (mod->obj[ob].cont[co].psize >= 2) { npatch++; for (ind = 0; ind < MAX_VALUE_COLS; ind++) { listInd = listStart; if (istoreFindValue(mod->obj[ob].store, co, GEN_STORE_VALUE1 + 2 * ind, &value, &listInd)) { maxVal[ind] = B3DMAX(maxVal[ind], value); numValues[ind]++; } } } } } /* printf("numval %d %d %d %f %f %f\n", numValues[0], numValues[1], numValues[2], maxVal[0], maxVal[1], maxVal[2]); */ /* Get the value ID's if any and convert an entered ID to a type #. Also set format for output based on maximum value */ maxValType = -1; numCols = 0; for (ind = 0; ind < MAX_VALUE_COLS; ind++) { strcpy(format[ind], "%10.4f"); if (numValues[ind]) { numCols++; maxValType = ind; if (maxVal[ind] > 10.1) strcpy(format[ind], "%10.2f"); else if (maxVal[ind] > 1.01) strcpy(format[ind], "%10.3f"); } } for (ind = 0; ind < B3DMIN(maxValType + 1, mod->obj[0].extra[IOBJ_EXSIZE - 1]); ind++) valueIDs[ind] = mod->obj[0].extra[IOBJ_EXSIZE - 2 - ind]; /*printf("# vla ID %d %d %d %d\n", maxValType, valueIDs[0],valueIDs[1],valueIDs[2]);*/ /* Error checks on the column for value 1 */ if (colForVal1 < 1 || colForVal1 > numCols) { if (numCols) exitError("The column for general value type must be between 1 and %d", numCols); exitError("There are no general values stored in the model"); } colForVal1--; /* Set up map from column to value type index */ if (numValues[0]) colToTypeMap[colForVal1] = 0; col = 0; for (ind = 1; ind <= maxValType; ind++) { if (numValues[ind]) { if (!colToTypeMap[col]) col++; colToTypeMap[col++] = ind; } } /*printf("%d %d %d %d\n", numCols, colToTypeMap[0], colToTypeMap[1], colToTypeMap[2]);*/ /* Output the header line */ fprintf(fout, "%d edited positions", npatch); if (mod->obj[0].extra[IOBJ_EXSIZE - 1] > 0) for (col = 0; col < numCols; col++) fprintf(fout, " %d", valueIDs[colToTypeMap[col]]); fprintf(fout, "\n"); for (ob = 0; ob < mod->objsize; ob++) { listInd = 0; for (co = 0; co < mod->obj[ob].contsize; co++) { listStart = listInd; if (mod->obj[ob].cont[co].psize >= 2) { pts = mod->obj[ob].cont[co].pts; ix = pts[0].x + 0.5; iy = pts[0].y + 0.5; iz = pts[0].z + 0.5; dx = (pts[1].x - pts[0].x) / mod->pixsize; dy = (pts[1].y - pts[0].y) / mod->pixsize; dz = (pts[1].z - pts[0].z) / mod->pixsize; if (mod->flags & IMODF_FLIPYZ) fprintf(fout, "%6d %5d %5d %8.2f %8.2f %8.2f", ix, iz, iy, dx, dz, dy); else fprintf(fout, "%6d %5d %5d %8.2f %8.2f %8.2f", ix, iy, iz, dx, dy, dz); for (col = 0; col < numCols; col++) { ind = colToTypeMap[col]; if (numValues[ind]) { listInd = listStart; value = 0.; istoreFindValue(mod->obj[ob].store, co, GEN_STORE_VALUE1 + 2 * ind, &value, &listInd); fprintf(fout, format[ind], value); } } fprintf(fout, "\n"); } } } fclose(fout); exit(0); }
/*! * Converts the data in slice [s] from its current mode to [mode], allocating * a new data array as needed. Complex values are converted to others by * taking the magnitude. Values are converted to complex modes by setting the * real component to the value, and the imaginary component to 0. RGB values * are converted by taking a weighted sum of components. When converting to a * mode with integer or byte values, the data are truncated to fit within the * range of the new mode. Returns the new mode or -1 for error. */ int sliceNewMode(Islice *s, int mode) { Islice *ns; Ival val; int i, j; int default_copy = 0; int limit_val = 0; float minval, maxval; if (!s) return(-1); if (s->mode == mode) return(mode); ns = sliceCreate(s->xsize, s->ysize, mode); /* Set up limiting values */ if (mode == MRC_MODE_BYTE || mode == MRC_MODE_RGB) { limit_val = 1; minval = 0.; maxval = 255; } else if (mode == MRC_MODE_SHORT) { limit_val = 1; minval = -32768.; maxval = 32767.; } else if (mode == MRC_MODE_USHORT) { limit_val = 1; minval = 0.; maxval = 65535.; } if (!ns) return(-1); switch(s->mode){ case MRC_MODE_BYTE: case MRC_MODE_SHORT: case MRC_MODE_USHORT: case MRC_MODE_FLOAT: switch(mode){ case MRC_MODE_BYTE: case MRC_MODE_SHORT: case MRC_MODE_USHORT: case MRC_MODE_FLOAT: default_copy = 1; break; case MRC_MODE_COMPLEX_FLOAT: case MRC_MODE_COMPLEX_SHORT: val[1] = 0; default_copy = 1; break; case MRC_MODE_RGB: for(j = 0; j < s->ysize; j++) for(i = 0; i < s->xsize; i++){ sliceGetVal(s, i, j, val); if (limit_val) val[0] = B3DMIN(maxval, B3DMAX(minval, val[0])); val[2] = val[1] = val[0]; slicePutVal(ns, i, j, val); } break; default: default_copy = 1; break; } break; case MRC_MODE_COMPLEX_FLOAT: case MRC_MODE_COMPLEX_SHORT: switch(mode){ case MRC_MODE_BYTE: case MRC_MODE_SHORT: case MRC_MODE_USHORT: case MRC_MODE_FLOAT: for(j = 0; j < s->ysize; j++) for(i = 0; i < s->xsize; i++){ sliceGetVal(s, i, j, val); val[0] = (float)sqrt(val[0] * val[0] + val[1] * val[1]); if (limit_val) val[0] = B3DMIN(maxval, B3DMAX(minval, val[0])); slicePutVal(ns, i, j, val); } break; case MRC_MODE_COMPLEX_FLOAT: case MRC_MODE_COMPLEX_SHORT: default_copy = 1; break; case MRC_MODE_RGB: for(j = 0; j < s->ysize; j++) for(i = 0; i < s->xsize; i++){ sliceGetVal(s, i, j, val); val[0] = (float)sqrt(val[0] * val[0] + val[1] * val[1]); if (limit_val) val[0] = B3DMIN(maxval, B3DMAX(minval, val[0])); val[2] = val[1] = val[0]; slicePutVal(ns, i, j, val); } break; } break; case MRC_MODE_RGB: switch(mode){ case MRC_MODE_BYTE: case MRC_MODE_SHORT: case MRC_MODE_USHORT: case MRC_MODE_FLOAT: for(j = 0; j < s->ysize; j++) for(i = 0; i < s->xsize; i++){ sliceGetVal(s, i, j, val); val[0] = (val[0] * 0.3f) + (val[1] * 0.59f) + (val[2] * 0.11f); if (limit_val) val[0] = B3DMIN(maxval, B3DMAX(minval, val[0])); slicePutVal(ns, i, j, val); } break; case MRC_MODE_COMPLEX_FLOAT: case MRC_MODE_COMPLEX_SHORT: for(j = 0; j < s->ysize; j++) for(i = 0; i < s->xsize; i++){ sliceGetVal(s, i, j, val); val[0] = (val[0] * 0.3f) + (val[1] * 0.59f) + (val[2] * 0.11f); val[1] = 0; slicePutVal(ns, i, j, val); } break; default: default_copy = 1; break; } break; default: default_copy = 1; break; } if (default_copy){ for(j = 0; j < s->ysize; j++) for(i = 0; i < s->xsize; i++){ sliceGetVal(s, i, j, val); if (limit_val) val[0] = B3DMIN(maxval, B3DMAX(minval, val[0])); slicePutVal(ns, i, j, val); } } free(s->data.b); /* 2/3/07: switch from copying ns to s to just setting data and mode */ s->data.b = ns->data.b; s->mode = mode; free(ns); return(mode); }
/* * Analyze a mesh and pack it into VBOs if it qualifies */ int VertBufManager::analyzeMesh(Imesh *mesh, float zscale, int fillType, int useFillColor, DrawProps *defProps) { bool valid = true; RGBTmap colors; pair<RGBTmap::iterator,bool> mapret; RGBTmap::iterator mapit; VertBufData *vbd = mesh->vertBuf; RGBTindices rInd; Istore *stp; Istore store; int *mlist = mesh->list; DrawProps curProps; int i, j, cumInd, defInd, nextItemIndex, stateFlags, vertDflt, changeFlags, firstDflt; b3dUInt32 vertRGBT, firstRGBT; int remInd, curSave, curNext; int numDefaultTri = 0, numMixedTri = 0; int handleFlags, nonVboFlags = 0; if (fillType) handleFlags = (useFillColor ? CHANGED_FCOLOR : CHANGED_COLOR) | CHANGED_TRANS; else { handleFlags = CHANGED_COLOR | CHANGED_TRANS; nonVboFlags = CHANGED_3DWIDTH; } rInd.numFanInds = 0; // Check if there is a current VBO and it is all still valid packRGBT(defProps, useFillColor, firstRGBT); if (vbd && vbd->vbObj && fillType == vbd->fillType && (!ilistSize(mesh->store) || (vbd->useFillColor == useFillColor && vbd->defaultRGBT == firstRGBT)) && vbd->checksum == istoreChecksum(mesh->store)) { // If Z-scale still valid, return a -1; if have to fix the Z-scale, do it, return -2 if (fabs((double)(zscale - vbd->zscale)) < 1.e-4) return -1; b3dBindBuffer(GL_ARRAY_BUFFER, vbd->vbObj); if (loadVertexNormalArray(mesh, zscale, fillType)) { vbCleanupVBD(mesh); return 1; } vbd->zscale = zscale; return -2; } // Now proceed to full analysis nextItemIndex = istoreFirstChangeIndex(mesh->store); for (i = 0; i < mesh->lsize && valid; i++) { switch (mlist[i]) { case IMOD_MESH_BGNTRI: case IMOD_MESH_ENDTRI: case IMOD_MESH_BGNPOLY: case IMOD_MESH_NORMAL: case IMOD_MESH_BGNBIGPOLY: case IMOD_MESH_SWAP: valid = false; break; case IMOD_MESH_BGNPOLYNORM: i++; while (mlist[i] != IMOD_MESH_ENDPOLY && valid) { valid = (mlist[i] == mlist[i+1] + 1) && (mlist[i+2] == mlist[i+3] + 1) && (mlist[i+4] == mlist[i+5] + 1); i += 6; numDefaultTri++; } break; case IMOD_MESH_BGNPOLYNORM2: i++; while (mlist[i] != IMOD_MESH_ENDPOLY) { if (nextItemIndex < i || nextItemIndex > i + 2) { // Count a default triangle if no changes in this range numDefaultTri++; i += 3; } else { // Otherwise look at each vertex and get its properties if it is changed for (j = 0; j < 3; j++) { vertDflt = 1; if (i == nextItemIndex) { curProps = *defProps; stateFlags = 0; nextItemIndex = istoreNextChange(mesh->store, defProps, &curProps, &stateFlags, &changeFlags); if (stateFlags & handleFlags) { vertDflt = 0; packRGBT(&curProps, useFillColor, vertRGBT); } // Take triangle as mixed if it has unhandleable flags if (stateFlags & nonVboFlags) { firstDflt = -1; i++; continue; } } // For first vertex record the triangle properties, for later one record if // there is a mismatch from the first if (!j) { firstDflt = vertDflt; firstRGBT = vertRGBT; } else if (vertDflt != firstDflt || (!vertDflt && vertRGBT != firstRGBT)) { firstDflt = -1; } i++; } // Count whether it is a default or mixed triangle if (firstDflt < 0) { numMixedTri++; } else if (firstDflt > 0) { numDefaultTri++; } else { // For a special triangle, add to list of RGBT values with a count of 1 if it // is not on the list; if it is already on the list increment its count; rInd.firstElement = i; rInd.numInds = 1; mapret = colors.insert(pair<b3dUInt32,RGBTindices>(firstRGBT, rInd)); if (mapret.second == false) mapret.first->second.numInds++; } } } break; case IMOD_MESH_END: break; } } if (!valid) { vbCleanupVBD(mesh); return 3; } if (!colors.size() && !numDefaultTri) { vbCleanupVBD(mesh); return 2; } vbd = allocateVBDIfNeeded(&mesh->vertBuf); if (!vbd) return 1; // Now allocate whatever pieces are needed in there. Set remnant value in vbd first // Add up the special set sizes and re-initialize the counts to be starting indexes cumInd = numDefaultTri * 3; vbd->numRemnant = 0; if (numMixedTri) vbd->numRemnant = numMixedTri * 3 + 3; i = -1; if (allocateSpecialSets(vbd, colors.size(), cumInd, 0) || processMap(vbd, &colors, cumInd, 3, i)) { vbCleanupVBD(mesh); return 1; } imodTrace('b',"dfltInd %d spec sets %d cumind %d remnant %d", vbd->numIndDefault, vbd->numSpecialSets, cumInd, numMixedTri); // Create the store for remnants if (numMixedTri) { ilistDelete(vbd->remnantStore); vbd->remnantStore = ilistNew(sizeof(Istore), vbd->numRemnant / 8); if (!vbd->remnantStore) { vbCleanupVBD(mesh); return 1; } vbd->remnantStore->quantum = B3DMAX(vbd->remnantStore->quantum, vbd->numRemnant / 8); vbd->remnantIndList[0] = IMOD_MESH_BGNPOLYNORM2; } // Now get the vertex buffers themselves if (genAndBindBuffers(vbd, mesh->vsize, cumInd)) { vbCleanupVBD(mesh); return 1; } imodTrace('b',"vbObj %d ebObj %d", vbd->vbObj, vbd->ebObj); // Load the vertices and finish with buffer for now if (loadVertexNormalArray(mesh, zscale, fillType)) { vbCleanupVBD(mesh); return 1; } b3dBindBuffer(GL_ARRAY_BUFFER, 0); // Set the identifiers of this vb data vbd->zscale = zscale; vbd->fillType = fillType; vbd->useFillColor = useFillColor; packRGBT(defProps, useFillColor, vbd->defaultRGBT); vbd->checksum = istoreChecksum(mesh->store); // Get or use temporary array for indexes if (allocateTempInds(cumInd)) { vbCleanupVBD(mesh); return 1; } // No fine grain: copy all the indices into index array defInd = 0; if (!mesh->store) { i = 0; while (mlist[i] != IMOD_MESH_END) { if (mlist[i] == IMOD_MESH_BGNPOLYNORM) { i++; while (mlist[i] != IMOD_MESH_ENDPOLY) { i++; mInds[defInd++] = mlist[i++] / 2; } } else if (mlist[i] == IMOD_MESH_BGNPOLYNORM2) { i++; while (mlist[i] != IMOD_MESH_ENDPOLY) { mInds[defInd++] = mlist[i++] / 2; } } i++; } } else { // Otherwise process all triangles into index array or remnant arrays nextItemIndex = istoreFirstChangeIndex(mesh->store); remInd = 1; for (i = 0; i < mesh->lsize; i++) { switch (mlist[i]) { case IMOD_MESH_BGNPOLYNORM2: i++; while (mlist[i] != IMOD_MESH_ENDPOLY) { // Repeat the analysis to determine default, special, or mixed triangle curSave = mesh->store->current; if (nextItemIndex < i || nextItemIndex > i + 2) { firstDflt = 1; } else { // Otherwise look at each vertex and get its properties if it is changed for (j = 0; j < 3; j++) { vertDflt = 1; if (i + j == nextItemIndex) { curProps = *defProps; stateFlags = 0; nextItemIndex = istoreNextChange(mesh->store, defProps, &curProps, &stateFlags, &changeFlags); if (stateFlags & handleFlags) { vertDflt = 0; packRGBT(&curProps, useFillColor, vertRGBT); } if (stateFlags & nonVboFlags) { firstDflt = -1; continue; } } // For first vertex record the triangle properties, for later one stop if // there is a mismatch from the first if (!j) { firstDflt = vertDflt; firstRGBT = vertRGBT; } else if (vertDflt != firstDflt || (!vertDflt && vertRGBT != firstRGBT)) { firstDflt = -1; } } } // Save indexes for default or special triangles if (firstDflt > 0) { mInds[defInd++] = mlist[i++] / 2; mInds[defInd++] = mlist[i++] / 2; mInds[defInd++] = mlist[i++] / 2; } else if (firstDflt == 0) { mapit = colors.find(firstRGBT); mInds[mapit->second.numInds++] = mlist[i++] / 2; mInds[mapit->second.numInds++] = mlist[i++] / 2; mInds[mapit->second.numInds++] = mlist[i++] / 2; } else { // For mixed triangle, save the current pointer, copy the index for each // vertex to the remnant index array, and copy all stores for that vertex // to the remnant store, changing the index to the new value curNext = mesh->store->current; for (j = 0; j < 3; j++) { vbd->remnantIndList[remInd] = mlist[i]; while (curSave < curNext) { stp = istoreItem(mesh->store, curSave); if (stp->index.i == i) { store = *stp; store.index.i = remInd; if (istoreInsert(&vbd->remnantStore, &store)) { vbCleanupVBD(mesh); return 1; } curSave++; } else break; } i++; remInd++; } mesh->store->current = curNext; } } break; case IMOD_MESH_END: break; } } } if (vbd->numRemnant) { vbd->remnantIndList[remInd++] = IMOD_MESH_ENDPOLY; vbd->remnantIndList[remInd++] = IMOD_MESH_END; } b3dBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, cumInd * sizeof(GLuint), mInds); b3dBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); return 0; }
int main( int argc, char *argv[]) { int i; FILE *fin, *fout; struct Mod_Model *mod; int npatch = 0; int nvalue = 0, nvalue2 = 0; int ix, iy, iz; float dx, dy, dz; float value, maxval = -1.e30; float value2, maxval2 = -1.e30; int ob, co, listInd, listStart; Ipoint *pts; char format[10] = "%10.4f"; char format2[10] = "%10.4f"; setExitPrefix("ERROR: imod2patch - "); if (argc != 3){ if (argc != 1) printf("ERROR: imod2patch - wrong # of arguments\n"); printf("imod2patch usage:\n"); printf("imod2patch imod_model patch_file\n"); exit(1); } i = 1; mod = imodRead(argv[i]); if (!mod) exitError("Reading model %s\n", argv[i]); if (imodBackupFile(argv[++i])) exitError("Renaming existing output file to %s\n", argv[i]); fout = fopen(argv[i], "w"); if (!fout) exitError("Could not open %s\n", argv[i]); /* Count up patches and values and find max of values */ for (ob = 0; ob < mod->objsize; ob++) { listInd = 0; for (co = 0; co < mod->obj[ob].contsize; co++) { listStart = listInd; if (mod->obj[ob].cont[co].psize >= 2) { npatch++; if (istoreFindValue(mod->obj[ob].store, co, GEN_STORE_VALUE1, &value, &listInd)) { maxval = B3DMAX(maxval, value); nvalue++; } listInd = listStart; if (istoreFindValue(mod->obj[ob].store, co, GEN_STORE_VALUE2, &value2, &listInd)) { maxval2 = B3DMAX(maxval2, value2); nvalue2++; } } } } /* If values are greater than one they are probably residuals and only need 2 decimal places */ if (nvalue && maxval > 1.01) strcpy(format, "%10.2f"); if (nvalue2 && maxval2 > 1.01) strcpy(format, "%10.2f"); fprintf(fout, "%d edited positions\n", npatch); for (ob = 0; ob < mod->objsize; ob++) { listInd = 0; for (co = 0; co < mod->obj[ob].contsize; co++) { listStart = listInd; if (mod->obj[ob].cont[co].psize >= 2) { pts = mod->obj[ob].cont[co].pts; ix = pts[0].x + 0.5; iy = pts[0].y + 0.5; iz = pts[0].z + 0.5; dx = (pts[1].x - pts[0].x) / mod->pixsize; dy = (pts[1].y - pts[0].y) / mod->pixsize; dz = (pts[1].z - pts[0].z) / mod->pixsize; if (mod->flags & IMODF_FLIPYZ) fprintf(fout, "%6d %5d %5d %8.2f %8.2f %8.2f", ix, iz, iy, dx, dz, dy); else fprintf(fout, "%6d %5d %5d %8.2f %8.2f %8.2f", ix, iy, iz, dx, dy, dz); if (nvalue) { value = 0.; istoreFindValue(mod->obj[ob].store, co, GEN_STORE_VALUE1, &value, &listInd); fprintf(fout, format, value); } if (nvalue2) { listInd = listStart; value2 = 0.; istoreFindValue(mod->obj[ob].store, co, GEN_STORE_VALUE2, &value2, &listInd); fprintf(fout, format2, value2); } fprintf(fout, "\n"); } } } fclose(fout); exit(0); }