/** * An iso level can be made of multiple regions with holes in them. This builds one path (into * the passed GeneralPath) that represents one connected contour. * * @param isoData Marching-cubes classification at each cell * @param isoDivided The boolean above/below classification for each cell (to disambiguate * saddles) * @param iso The path to build into */ public static void stichContour( Aggregates<MC_TYPE> isoData, Aggregates<Boolean> isoDivided, GeneralPath iso, int startX, int startY) { int x = startX, y = startY; SIDE prevSide = SIDE.NONE; // Found an unambiguous iso line at [r][c], so start there. MC_TYPE startCell = isoData.get(x, y); Point2D nextPoint = startCell.firstSide(prevSide).nextPoint(x, y); iso.moveTo(nextPoint.getX(), nextPoint.getY()); prevSide = isoData.get(x, y).secondSide(prevSide, isoDivided.get(x, y)); // System.out.printf("-------------------\n); do { // Process current cell MC_TYPE curCell = isoData.get(x, y); nextPoint = curCell.secondSide(prevSide, isoDivided.get(x, y)).nextPoint(x, y); // System.out.printf("%d,%d: %s\n",x,y,curCell.secondSide(prevSide, isoDivided.get(x,y))); iso.lineTo(nextPoint.getX(), nextPoint.getY()); SIDE nextSide = curCell.secondSide(prevSide, isoDivided.get(x, y)); isoData.set(x, y, curCell.clearWith()); // Erase this marching cube line entry // Advance for next cell prevSide = nextSide; switch (nextSide) { case LEFT: x -= 1; break; case RIGHT: x += 1; break; case BOTTOM: y += 1; break; case TOP: y -= 1; break; case NONE: throw new IllegalArgumentException( "Encountered side NONE after starting contour line."); } } while (x != startX || y != startY); iso.closePath(); }
@Override public void set(int x, int y, A val) { base.set(x, y, val); }