Skip to content

Commit

Permalink
Added toolpath generator for lasers (#2525)
Browse files Browse the repository at this point in the history
* Added new toolpath generator for lasers
* Fixed selection bug overwriting settigns
  • Loading branch information
breiler authored May 24, 2024
1 parent e4461f2 commit f30af36
Show file tree
Hide file tree
Showing 43 changed files with 1,265 additions and 559 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -94,27 +94,27 @@ public static PartialPosition fromXY(Position position) {


public boolean hasX() {
return x != null;
return x != null && !x.isNaN();
}

public boolean hasY() {
return y != null;
return y != null && !y.isNaN();
}

public boolean hasZ() {
return z != null;
return z != null && !z.isNaN();
}

public boolean hasA() {
return a != null;
return a != null && !a.isNaN();
}

public boolean hasB() {
return b != null;
return b != null && !b.isNaN();
}

public boolean hasC() {
return c != null;
return c != null && !c.isNaN();
}

public Double getX() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ public enum TextFieldUnit {
INCHES_PER_MINUTE("inch/min"),
ROTATIONS_PER_MINUTE("rpm"),
PERCENT("%"),
DEGREE("°");
DEGREE("°"),
TIMES("times");

private final String abbreviation;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ public UnitSpinner(double value, TextFieldUnit units, Double minimum, Double max
}

public void setUnits(TextFieldUnit units) {
if(units == TextFieldUnit.MM) {
if (units == TextFieldUnit.MM) {
spinnerNumberModel.setStepSize(0.01);
} else {
} else if (units == TextFieldUnit.INCH) {
spinnerNumberModel.setStepSize(0.001);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package com.willwinder.universalgcodesender.model;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import org.junit.Test;

import static org.junit.Assert.*;

public class PartialPositionTest {

@Test
Expand All @@ -12,6 +13,10 @@ public void testFormatted() {
assertEquals("X0Z0", new PartialPosition(0.0, null, 0.0, UnitUtils.Units.MM).getFormattedGCode());
assertEquals("X0Y0", new PartialPosition(0.0, 0.0, UnitUtils.Units.MM).getFormattedGCode());

assertEquals("Y0Z0", new PartialPosition(Double.NaN, 0.0, 0.0, UnitUtils.Units.MM).getFormattedGCode());
assertEquals("X0Z0", new PartialPosition(0.0, Double.NaN, 0.0, UnitUtils.Units.MM).getFormattedGCode());
assertEquals("X0Y0", new PartialPosition(0.0, 0.0, Double.NaN, UnitUtils.Units.MM).getFormattedGCode());

assertEquals("Y10Z0", new PartialPosition(null, 10.0, 0.0, UnitUtils.Units.MM).getFormattedGCode());
assertEquals("X10Z0", new PartialPosition(10.0, null, 0.0, UnitUtils.Units.MM).getFormattedGCode());
assertEquals("X0Y10", new PartialPosition(0.0, 10.0, UnitUtils.Units.MM).getFormattedGCode());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,38 +18,31 @@ This file is part of Universal Gcode Sender (UGS).
*/
package com.willwinder.ugs.nbp.designer.actions;

import com.willwinder.ugs.nbp.designer.entities.cuttable.CutType;
import com.willwinder.ugs.nbp.designer.entities.EntitySetting;
import com.willwinder.ugs.nbp.designer.entities.cuttable.Cuttable;
import com.willwinder.ugs.nbp.designer.logic.Controller;

import javax.swing.*;
import javax.swing.AbstractAction;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
* @author Joacim Breiler
*/
public class ChangeCutSettingsAction extends AbstractAction implements UndoableAction {

private final transient Controller controller;
private final List<Double> previousStartDepth;
private final List<Double> previousCutDepth;
private final List<CutType> previousCutType;
private final double newStartDepth;
private final double newCutDepth;
private final CutType newCutType;
private final transient List<Cuttable> cuttableList;
private final Object newValue;
private final List<Object> previousValue;
private final EntitySetting entitySetting;

public ChangeCutSettingsAction(Controller controller, List<Cuttable> cuttableList, double startDepth, double targetDepth, CutType cutType) {
public ChangeCutSettingsAction(Controller controller, List<Cuttable> cuttableList, EntitySetting entitySetting, Object value) {
this.cuttableList = new ArrayList<>(cuttableList);
previousStartDepth = cuttableList.stream().map(Cuttable::getStartDepth).collect(Collectors.toList());
previousCutDepth = cuttableList.stream().map(Cuttable::getTargetDepth).collect(Collectors.toList());
previousCutType = cuttableList.stream().map(Cuttable::getCutType).collect(Collectors.toList());
newStartDepth = startDepth;
newCutDepth = targetDepth;
newCutType = cutType;
this.entitySetting = entitySetting;
previousValue = cuttableList.stream().map(c -> c.getEntitySetting(entitySetting).orElse(null)).toList();
newValue = value;

this.controller = controller;
putValue("menuText", "Change stock settings");
Expand All @@ -64,18 +57,14 @@ public void redo() {
@Override
public void undo() {
for (int i = 0; i < cuttableList.size(); i++) {
cuttableList.get(i).setStartDepth(previousStartDepth.get(i));
cuttableList.get(i).setTargetDepth(previousCutDepth.get(i));
cuttableList.get(i).setCutType(previousCutType.get(i));
cuttableList.get(i).setEntitySetting(entitySetting, previousValue.get(i));
}
}

@Override
public void actionPerformed(ActionEvent e) {
for (Cuttable cuttable : cuttableList) {
cuttable.setStartDepth(newStartDepth);
cuttable.setTargetDepth(newCutDepth);
cuttable.setCutType(newCutType);
cuttable.setEntitySetting(entitySetting, newValue);
}
this.controller.getDrawing().repaint();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@
import com.willwinder.ugs.nbp.designer.logic.Controller;
import org.openide.DialogDescriptor;
import org.openide.DialogDisplayer;
import static org.openide.NotifyDescriptor.OK_OPTION;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import static org.openide.NotifyDescriptor.OK_OPTION;

public class OpenToolSettingsAction implements ActionListener {
private final Controller controller;

Expand All @@ -22,9 +21,9 @@ public void actionPerformed(ActionEvent e) {
ToolSettingsPanel toolSettingsPanel = new ToolSettingsPanel(controller);
DialogDescriptor dialogDescriptor = new DialogDescriptor(toolSettingsPanel, "Tool settings", true, null);
if (DialogDisplayer.getDefault().notify(dialogDescriptor) == OK_OPTION) {
ChangeToolSettingsAction changeStockSettings = new ChangeToolSettingsAction(controller, toolSettingsPanel.getSettings());
changeStockSettings.actionPerformed(null);
controller.getUndoManager().addAction(changeStockSettings);
ChangeToolSettingsAction changeToolSettingsAction = new ChangeToolSettingsAction(controller, toolSettingsPanel.getSettings());
changeToolSettingsAction.actionPerformed(null);
controller.getUndoManager().addAction(changeToolSettingsAction);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ This file is part of Universal Gcode Sender (UGS).

package com.willwinder.ugs.nbp.designer.entities;

import java.util.List;

/**
* What settings that is possible to set on an entity.
*
Expand All @@ -36,7 +38,37 @@ public enum EntitySetting {
TARGET_DEPTH("Target depth"),
ANCHOR("Anchor"),
FONT_FAMILY("Font"),
LOCK_RATIO("Lock ratio");
LOCK_RATIO("Lock ratio"),
SPINDLE_SPEED("Spindle speed"),
PASSES("Passes"),
FEED_RATE("Feed rate");

public static final List<EntitySetting> DEFAULT_ENDMILL_SETTINGS = List.of(
EntitySetting.CUT_TYPE,
EntitySetting.ANCHOR,
EntitySetting.HEIGHT,
EntitySetting.WIDTH,
EntitySetting.FONT_FAMILY,
EntitySetting.LOCK_RATIO,
EntitySetting.POSITION_X,
EntitySetting.POSITION_Y,
EntitySetting.ROTATION,
EntitySetting.START_DEPTH,
EntitySetting.TARGET_DEPTH);

public static final List<EntitySetting> DEFAULT_LASER_SETTINGS = List.of(
EntitySetting.CUT_TYPE,
EntitySetting.ANCHOR,
EntitySetting.HEIGHT,
EntitySetting.WIDTH,
EntitySetting.FONT_FAMILY,
EntitySetting.LOCK_RATIO,
EntitySetting.POSITION_X,
EntitySetting.POSITION_Y,
EntitySetting.ROTATION,
EntitySetting.SPINDLE_SPEED,
EntitySetting.PASSES,
EntitySetting.FEED_RATE);

private final String label;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ This file is part of Universal Gcode Sender (UGS).

import com.willwinder.ugs.nbp.designer.entities.AbstractEntity;
import com.willwinder.ugs.nbp.designer.entities.EntityEvent;
import com.willwinder.ugs.nbp.designer.entities.EventType;
import com.willwinder.ugs.nbp.designer.entities.EntitySetting;
import com.willwinder.ugs.nbp.designer.entities.EventType;
import com.willwinder.ugs.nbp.designer.gui.Colors;
import com.willwinder.ugs.nbp.designer.gui.Drawing;
import com.willwinder.ugs.nbp.designer.logic.Controller;
Expand All @@ -35,14 +35,19 @@ This file is part of Universal Gcode Sender (UGS).
import java.awt.geom.Rectangle2D;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

/**
* @author Joacim Breiler
*/
public abstract class AbstractCuttable extends AbstractEntity implements Cuttable {
private final CuttableEntitySettings entitySettings;
private CutType cutType = CutType.NONE;
private double targetDepth;
private double startDepth;
private int spindleSpeed;
private int passes;
private int feedRate;
private boolean isHidden = false;

protected AbstractCuttable() {
Expand All @@ -51,6 +56,7 @@ protected AbstractCuttable() {

protected AbstractCuttable(double relativeX, double relativeY) {
super(relativeX, relativeY);
entitySettings = new CuttableEntitySettings(this);
}

@Override
Expand Down Expand Up @@ -86,6 +92,39 @@ public void setTargetDepth(double targetDepth) {
notifyEvent(new EntityEvent(this, EventType.SETTINGS_CHANGED));
}

@Override
public int getSpindleSpeed() {
return spindleSpeed;
}

@Override
public void setSpindleSpeed(int Speed) {
this.spindleSpeed = Math.abs(Speed);
notifyEvent(new EntityEvent(this, EventType.SETTINGS_CHANGED));
}

@Override
public int getPasses() {
return passes;
}

@Override
public void setPasses(int passes) {
this.passes = Math.abs(passes);
notifyEvent(new EntityEvent(this, EventType.SETTINGS_CHANGED));
}

@Override
public int getFeedRate() {
return feedRate;
}

@Override
public void setFeedRate(int feedRate) {
this.feedRate = Math.abs(feedRate);
notifyEvent(new EntityEvent(this, EventType.SETTINGS_CHANGED));
}

@Override
public void render(Graphics2D graphics, Drawing drawing) {
if (isHidden) {
Expand All @@ -106,6 +145,13 @@ public void render(Graphics2D graphics, Drawing drawing) {
graphics.draw(shape);
} else if (getCutType() == CutType.INSIDE_PATH || getCutType() == CutType.ON_PATH || getCutType() == CutType.OUTSIDE_PATH) {
drawShape(graphics, new BasicStroke(strokeWidth), getCutColor(), shape);
} else if (getCutType() == CutType.LASER_ON_PATH) {
drawShape(graphics, new BasicStroke(strokeWidth), getLaserCutColor(), shape);
} else if (getCutType() == CutType.LASER_FILL) {
graphics.setStroke(new BasicStroke(strokeWidth));
graphics.setColor(getLaserCutColor());
graphics.fill(shape);
graphics.draw(shape);
} else if (getCutType() == CutType.CENTER_DRILL) {
drawShape(graphics, new BasicStroke(strokeWidth), Colors.SHAPE_HINT, shape);
double centerX = shape.getBounds2D().getCenterX();
Expand Down Expand Up @@ -152,10 +198,24 @@ public List<EntitySetting> getSettings() {
EntitySetting.HEIGHT,
EntitySetting.CUT_TYPE,
EntitySetting.START_DEPTH,
EntitySetting.TARGET_DEPTH
EntitySetting.TARGET_DEPTH,
EntitySetting.SPINDLE_SPEED,
EntitySetting.PASSES,
EntitySetting.FEED_RATE
);
}

private Color getLaserCutColor() {
int color = Math.max(0, Math.min(255, (int) Math.round(255d * getLaserCutAlpha()) - 50));
return new Color(color, color, color);
}

private double getLaserCutAlpha() {
return 1d - Math.max(Float.MIN_VALUE, getEntitySetting(EntitySetting.SPINDLE_SPEED)
.map(v -> (Integer) v / 100d).orElse(0d));
}


private Color getCutColor() {
int color = Math.max(0, Math.min(255, (int) Math.round(255d * getCutAlpha()) - 50));
return new Color(color, color, color);
Expand All @@ -174,6 +234,18 @@ protected void copyPropertiesTo(Cuttable copy) {
copy.setStartDepth(getStartDepth());
copy.setTargetDepth(getTargetDepth());
copy.setCutType(getCutType());
copy.setSpindleSpeed(getSpindleSpeed());
copy.setPasses(getPasses());
copy.setHidden(isHidden());
}

@Override
public Optional<Object> getEntitySetting(EntitySetting entitySetting) {
return entitySettings.getEntitySetting(entitySetting);
}

@Override
public void setEntitySetting(EntitySetting entitySetting, Object value) {
entitySettings.setEntitySetting(entitySetting, value);
}
}
Loading

0 comments on commit f30af36

Please sign in to comment.