/*
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License version 3 as published by
the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.cirqwizard.generation;
import org.cirqwizard.geom.Point;
import org.cirqwizard.generation.toolpath.LinearToolpath;
import org.cirqwizard.generation.toolpath.Toolpath;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
public class RubOutGenerator
{
private byte[] sourceData;
private int width;
private int height;
private int diameter;
private int overlap;
/**
*
* @param image Source raster window
* @param diameter Tool diameter
* @param overlap Tool paths overlap in mm/RESOLUTION units
*/
public RubOutGenerator(BufferedImage image, int diameter, int overlap)
{
sourceData = (byte[]) image.getData().getDataElements(0, 0, image.getWidth(), image.getHeight(), null);
this.width = image.getWidth();
this.height = image.getHeight();
this.diameter = diameter;
this.overlap = overlap;
}
private byte getPoint(int x, int y)
{
return sourceData[y * width + x];
}
private boolean checkVertical(int x, int y)
{
for (int yy = y - diameter / 2; yy < y + diameter / 2; yy++)
{
if (getPoint(x, yy) != 0)
return false;
}
return true;
}
private Toolpath generateToolpath(int start, int end, int y)
{
for (int yy = y - diameter / 2; yy < y + diameter / 2 - overlap; yy++)
{
int endIndex = yy * width + end;
for (int index = yy * width + start; index < endIndex; index++)
sourceData[index] = 1;
}
return new LinearToolpath(diameter, new Point(start, y), new Point(end, y));
}
public List<Toolpath> process()
{
List<Toolpath> result = new ArrayList<>();
int radius = diameter / 2;
for (int y = radius; y < height - radius; y++)
{
Integer start = null;
for (int x = 0; x < width - 1; x++)
{
if (start == null && getPoint(x, y) == 0 && checkVertical(x, y))
start = x;
else if (start != null && !checkVertical(x, y))
{
if (x - start > diameter / 2)
result.add(generateToolpath(start, x, y));
start = null;
}
}
if (start != null)
result.add(generateToolpath(start, width - 1, y));
}
return result;
}
}