/* 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.fx.contour; import javafx.beans.property.SimpleBooleanProperty; import javafx.collections.FXCollections; import javafx.scene.layout.GridPane; import org.cirqwizard.fx.Context; import org.cirqwizard.fx.PCBPane; import org.cirqwizard.fx.SettingsDependentScreenController; import org.cirqwizard.fx.machining.Machining; import org.cirqwizard.fx.settings.SettingsEditor; import org.cirqwizard.generation.MillingToolpathGenerator; import org.cirqwizard.generation.gcode.MillingGCodeGenerator; import org.cirqwizard.generation.optimizer.Chain; import org.cirqwizard.generation.optimizer.ChainDetector; import org.cirqwizard.generation.optimizer.Optimizer; import org.cirqwizard.generation.optimizer.TimeEstimator; import org.cirqwizard.generation.toolpath.Toolpath; import org.cirqwizard.gerber.GerberPrimitive; import org.cirqwizard.layers.Board; import org.cirqwizard.post.RTPostprocessor; import org.cirqwizard.settings.ApplicationConstants; import org.cirqwizard.settings.ContourMillingSettings; import org.cirqwizard.settings.SettingsFactory; import java.util.Collection; import java.util.List; import java.util.stream.Collectors; public class ContourMilling extends Machining { @Override protected String getName() { return "Milling"; } @Override public void refresh() { pcbPane.setGerberColor(PCBPane.CONTOUR_COLOR); pcbPane.setToolpathColor(PCBPane.CONTOUR_COLOR); Context context = getMainApplication().getContext(); ContourMillingSettings settings = SettingsFactory.getContourMillingSettings(); context.setG54Z(settings.getZOffset().getValue()); super.refresh(); } @Override public void populateSettingsGroup(GridPane pane, SettingsDependentScreenController listener) { SettingsEditor.renderSettings(pane, SettingsFactory.getContourMillingSettings(), getMainApplication(), listener); } @Override protected Board.LayerType getCurrentLayer() { return Board.LayerType.MILLING; } @Override protected void generateToolpaths() { ContourMillingSettings settings = SettingsFactory.getContourMillingSettings(); double feed = convertToDouble(settings.getFeedXY().getValue()) / 60; double zFeed = convertToDouble(settings.getFeedZ().getValue()) / 60; double arcFeed = convertToDouble(settings.getFeedXY().getDefaultValue()) / 60 * settings.getFeedArcs().getValue() / 100; double clearance = convertToDouble(settings.getClearance().getValue()); double safetyHeight = convertToDouble(settings.getSafetyHeight().getValue()); List<Toolpath> toolpaths = new MillingToolpathGenerator( (List<GerberPrimitive>) getMainApplication().getContext().getPanel().getCombinedElements(Board.LayerType.MILLING)). generate(); double originalDuration = TimeEstimator.calculateTotalDuration(toolpaths, feed, zFeed, arcFeed, clearance, safetyHeight, false, ApplicationConstants.ROUNDING); List<Chain> chains = new ChainDetector(toolpaths).detect(); chains = new Optimizer(chains, feed, zFeed, arcFeed, clearance, safetyHeight, 100, new SimpleBooleanProperty()).optimize(); List<Toolpath> optimizedToolpaths = chains.stream().map(Chain::getSegments).flatMap(Collection::stream).collect(Collectors.toList()); double optimizedDuration = TimeEstimator.calculateTotalDuration(optimizedToolpaths, feed, zFeed, arcFeed, clearance, safetyHeight, false, ApplicationConstants.ROUNDING); if (optimizedDuration < originalDuration) toolpaths = optimizedToolpaths; getMainApplication().getContext().getPanel().setToolpaths(Board.LayerType.MILLING, toolpaths); pcbPane.toolpathsProperty().setValue(FXCollections.observableArrayList(toolpaths)); } private double convertToDouble(Integer i) { return i.doubleValue() / ApplicationConstants.RESOLUTION; } @Override protected String generateGCode() { ContourMillingSettings settings = SettingsFactory.getContourMillingSettings(); int arcFeed = (settings.getFeedXY().getValue() * settings.getFeedArcs().getValue() / 100); MillingGCodeGenerator generator = new MillingGCodeGenerator(getMainApplication().getContext()); return generator.generate(new RTPostprocessor(), settings.getFeedXY().getValue(), settings.getFeedZ().getValue(), arcFeed, settings.getClearance().getValue(), settings.getSafetyHeight().getValue(), settings.getWorkingHeight().getValue(), settings.getSpeed().getValue()); } }