/** * Creates a reoriented copy of this VoxelSelection and add a border of blank voxels on all faces. * * @param borderWidth the number of voxels in the border added to all faces * @param orientation the new orientation (flip, rotate) * @param wxzOrigin takes the current [wxMin, wzMin] and returns the new [wxMin, wzMin] - if the * selection is rotated this may change * @return the new VoxelSelection */ public VoxelSelection makeReorientedCopyWithBorder( QuadOrientation orientation, int borderWidth, Pair<Integer, Integer> wxzOrigin) { int wxMin = wxzOrigin.getFirst(); int wzMin = wxzOrigin.getSecond(); Pair<Integer, Integer> xrange = new Pair<Integer, Integer>(wxMin, wxMin + xSize - 1); Pair<Integer, Integer> zrange = new Pair<Integer, Integer>(wzMin, wzMin + zSize - 1); orientation.getWXZranges(xrange, zrange); int wxNewMin = xrange.getFirst(); int wzNewMin = zrange.getFirst(); wxzOrigin.setFirst(wxNewMin); wxzOrigin.setSecond(wzNewMin); int newXsize = (xrange.getSecond() - xrange.getFirst() + 1) + 2 * borderWidth; int newYsize = ySize + 2 * borderWidth; int newZsize = (zrange.getSecond() - zrange.getFirst() + 1) + 2 * borderWidth; VoxelSelection copy = new VoxelSelection(newXsize, newYsize, newZsize); for (int x = 0; x < xSize; ++x) { for (int y = 0; y < ySize; ++y) { for (int z = 0; z < zSize; ++z) { if (getVoxel(x, y, z)) { copy.setVoxel( orientation.calcWXfromXZ(x, z) + borderWidth - wxNewMin, y + borderWidth, orientation.calcWZfromXZ(x, z) + borderWidth - wzNewMin); } } } } return copy; }
/** * Creates a copy of this VoxelSelection, adding a border of blank voxels on all faces. For * example - if the VoxelSelection has size 5x6x7, and borderWidth is 2, the resulting * VoxelSelection is 9x10x11 in size And (eg) if the initial VoxelSelection is all set, the new * selection will be all clear except from the box from [2,2,2] to [6,7,8] inclusive which will be * all set * * @param borderWidth the number of voxels in the border added to all faces * @return the new VoxelSelection */ public VoxelSelection makeCopyWithEmptyBorder(int borderWidth) { VoxelSelection copy = new VoxelSelection( xSize + 2 * borderWidth, ySize + 2 * borderWidth, zSize + 2 * borderWidth); for (int x = 0; x < xSize; ++x) { for (int y = 0; y < ySize; ++y) { for (int z = 0; z < zSize; ++z) { if (getVoxel(x, y, z)) { copy.setVoxel(x + borderWidth, y + borderWidth, z + borderWidth); } } } } return copy; }
/** * For the given VoxelSelection, make a "BorderMask" copy where all the empty voxels adjacent to a * set voxel are marked as set. i.e. for a given [x,y,z]: 1) if the voxel is set, the BorderMask * voxel is clear 2) if all of the six adjacent voxels are clear, the BorderMask voxel is clear 3) * otherwise, the BorderMask voxel is set. * * @return */ public VoxelSelection generateBorderMask() { VoxelSelection copy = new VoxelSelection(xSize, ySize, zSize); for (int x = 0; x < xSize; ++x) { for (int y = 0; y < ySize; ++y) { for (int z = 0; z < zSize; ++z) { if (!getVoxel(x, y, z)) { if (getVoxel(x - 1, y, z) || getVoxel(x + 1, y, z) || getVoxel(x, y - 1, z) || getVoxel(x, y + 1, z) || getVoxel(x, y, z - 1) || getVoxel(x, y, z + 1)) { copy.setVoxel(x, y, z); } } } } } return copy; }
/** * splits this VoxelSelection into two, in accordance with the supplied mask: For each set voxel * in this: 1) if the mask is clear, the voxel is removed from this and added to the return value * 2) if the mask is set, the voxel remains in this * * @param mask * @param xOffsetOfMask the origin of the mask relative to the origin of this fragment * @param yOffsetOfMask * @param zOffsetOfMask * @return a new VoxelSelection containing those voxels that aren't also present in the mask. */ public VoxelSelection splitByMask( VoxelSelection mask, int xOffsetOfMask, int yOffsetOfMask, int zOffsetOfMask) { VoxelSelection notOverlapped = new VoxelSelection(this); notOverlapped.clearAll(); int xSize = mask.getxSize(); int ySize = mask.getySize(); int zSize = mask.getzSize(); for (int x = 0; x < xSize; ++x) { for (int z = 0; z < zSize; ++z) { for (int y = 0; y < ySize; ++y) { if (getVoxel(x - xOffsetOfMask, y - yOffsetOfMask, z - zOffsetOfMask)) { if (!mask.getVoxel(x, y, z)) { notOverlapped.setVoxel(x - xOffsetOfMask, y - yOffsetOfMask, z - zOffsetOfMask); this.clearVoxel(x - xOffsetOfMask, y - yOffsetOfMask, z - zOffsetOfMask); } } } } } return notOverlapped; }