/** creates grid of half size */ static AttributeGrid makeGridHalfSize(AttributeGrid inGrid, int nx, int ny, int nz, int type) { int nx1 = (nx + 1) / 2; int ny1 = (ny + 1) / 2; int nz1 = (nz + 1) / 2; AttributeGrid grid = (AttributeGrid) inGrid.createEmpty( nx1, ny1, nz1, 2 * inGrid.getVoxelSize(), 2 * inGrid.getSliceHeight()); long att[] = new long[8]; for (int y = 0; y < ny1; y++) { int yy = 2 * y; int yy1 = (yy + 1); if (yy1 >= ny) yy1 = yy; for (int x = 0; x < nx1; x++) { int xx = 2 * x; int xx1 = (xx + 1); if (xx1 >= nx) xx1 = xx; for (int z = 0; z < nz1; z++) { int zz = 2 * z; int zz1 = (zz + 1) % nz; if (zz1 >= nz) zz1 = zz; int c = 0; att[c++] = inGrid.getAttribute(xx, yy, zz); att[c++] = inGrid.getAttribute(xx, yy, zz1); att[c++] = inGrid.getAttribute(xx1, yy, zz); att[c++] = inGrid.getAttribute(xx1, yy, zz1); att[c++] = inGrid.getAttribute(xx1, yy1, zz); att[c++] = inGrid.getAttribute(xx1, yy1, zz1); att[c++] = inGrid.getAttribute(xx, yy1, zz); att[c++] = inGrid.getAttribute(xx, yy1, zz1); switch (type) { default: case SCALING_AVERAGE: grid.setAttribute(x, y, z, average(att)); break; case SCALING_MAX: grid.setAttribute(x, y, z, max(att)); break; } } } } return grid; }
@Override public AttributeGrid execute(AttributeGrid dest) { if (dest.getWidth() != distanceGrid.getWidth() || dest.getHeight() != distanceGrid.getHeight() || dest.getDepth() != distanceGrid.getDepth()) { printf( "Distance grid: %d %d %d\n", distanceGrid.getWidth(), distanceGrid.getHeight(), distanceGrid.getDepth()); printf("Dest grid: %d %d %d\n", dest.getWidth(), dest.getHeight(), dest.getDepth()); throw new IllegalArgumentException( "DistanceGrid and DensityGrid must be the same dimensions"); } double vs = distanceGrid.getVoxelSize(); int nx = distanceGrid.getWidth(); int ny = distanceGrid.getHeight(); int nz = distanceGrid.getDepth(); // 5 intervals for distance values // -INF, inDistanceMinus, inDistancePlus, outDistanceMinus, outDistancePlus, +INF int inDistanceMinus = (int) ((inDistanceValue / vs - 0.5) * subvoxelResolution); int inDistancePlus = (int) ((inDistanceValue / vs + 0.5) * subvoxelResolution); int outDistanceMinus = (int) ((outDistanceValue / vs - 0.5) * subvoxelResolution); int outDistancePlus = (int) ((outDistanceValue / vs + 0.5) * subvoxelResolution); if (inDistanceValue < maxInDistanceValue) { // no interior shell will be generated inDistanceMinus = inDistancePlus = DEFAULT_IN_VALUE; } if (outDistanceValue > maxOutDistanceValue) { // no exterior shell will be generated outDistanceMinus = outDistancePlus = DEFAULT_OUT_VALUE; } // // TODO make it MT // for (int y = 0; y < ny; y++) { for (int x = 0; x < nx; x++) { for (int z = 0; z < nz; z++) { long att = (long) (short) distanceGrid.getAttribute(x, y, z); short dest_att; if (att < inDistanceMinus) { dest.setAttribute(x, y, z, 0); } else if (att >= inDistanceMinus && att < inDistancePlus) { dest_att = (short) (att - inDistanceMinus); dest.setAttribute(x, y, z, dest_att); } else if (att >= inDistancePlus && att < outDistanceMinus || att == DEFAULT_IN_VALUE) { dest_att = (short) subvoxelResolution; dest.setAttribute(x, y, z, dest_att); } else if (att >= outDistanceMinus && att <= outDistancePlus) { dest_att = (short) (outDistancePlus - att); dest.setAttribute(x, y, z, dest_att); } else { dest.setAttribute(x, y, z, 0); } } } } return dest; }