Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions src/main/java/com/marginallyclever/makelangelo/LayerViewPanel.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.marginallyclever.makelangelo;

import com.marginallyclever.makelangelo.turtle.StrokeLayer;
import com.marginallyclever.makelangelo.turtle.Turtle;

import javax.swing.*;
import java.awt.*;

public class LayerViewPanel extends JPanel {
private final MainFrame mainFrame;

public LayerViewPanel(MainFrame mainFrame) {
super(new GridBagLayout());
this.mainFrame = mainFrame;
setName("LayerViewPanel");
}

public void setTurtle(Turtle turtle) {
removeAll();
if(turtle!=null) fillPanel(turtle);

revalidate();
repaint();
}

private void fillPanel(Turtle turtle) {
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx=0;
c.gridy=0;
c.weightx=1;

for(var layer : turtle.getLayers()) {
JPanel layerView = createOneLayerView(turtle,layer);
add(layerView,c);
c.gridy++;
}
JPanel spacer = new JPanel();
c.weighty=1;
add(spacer,c);
}

private JPanel createOneLayerView(Turtle turtle,StrokeLayer layer) {
JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEADING));
// add a visibility checkbox
JCheckBox visibilityCheckBox = new JCheckBox();
visibilityCheckBox.setSelected(layer.isVisible());
visibilityCheckBox.addActionListener(e -> {
layer.setVisible(visibilityCheckBox.isSelected());
if(mainFrame!=null) {
mainFrame.setTurtle(turtle);
}
});
panel.add(visibilityCheckBox);
JLabel nameLabel = new JLabel(layer.getName() +" "+ layer.getAllLines().size() + " lines");
panel.add(nameLabel);

return panel;
}
}
7 changes: 7 additions & 0 deletions src/main/java/com/marginallyclever/makelangelo/MainFrame.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public class MainFrame extends JFrame {
private final AboutPanel aboutPanel = new AboutPanel(MakelangeloVersion.VERSION, MakelangeloVersion.DETAILED_VERSION);
private final NodeFactoryPanel nodeFactoryPanel = new NodeFactoryPanel();
private final DockableEditNodePanel editNodePanel = new DockableEditNodePanel();
private final LayerViewPanel layerViewPanel = new LayerViewPanel(this);

private Turtle myTurtle = new Turtle();

Expand Down Expand Up @@ -256,8 +257,12 @@ public void setMainTitle(String title) {
}

public void setTurtle(Turtle turtle) {
// trim empty layers
turtle.trimEmptyLayers();

myTurtle = turtle;
previewPanel.setTurtle(turtle);
layerViewPanel.setTurtle(turtle);
}

public Turtle getTurtle() {
Expand Down Expand Up @@ -292,6 +297,7 @@ public void createDefaultLayout() {
addDockingPanel("AddNode","Add Node", nodeFactoryPanel);
addDockingPanel("About","About",aboutPanel);
addDockingPanel("EditNode","Edit Node",editNodePanel);
addDockingPanel("Layers","Layers",layerViewPanel);
}

private void setupDropTarget() {
Expand Down Expand Up @@ -355,6 +361,7 @@ public TurtleRenderer getTurtleRenderer() {

public void setTurtleRenderer(TurtleRenderer turtleRenderer) {
previewPanel.setTurtleRenderer(turtleRenderer);
previewPanel.onPlotterSettingsUpdate(getPlotterSettingsManager().getLastSelectedProfile());
}

public PlotterSettingsManager getPlotterSettingsManager() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public void update() {
} else if( allLayers.size() > 1 ) {
// many layers merge into one, provided they are the same diameter
// TODO check for diameter changes
StrokeLayer newLayer = new StrokeLayer(c, allLayers.getFirst().getDiameter());
StrokeLayer newLayer = new StrokeLayer("0",c, allLayers.getFirst().getDiameter());
for( var layer : allLayers ) {
newLayer.addAll(layer.getAllLines());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,33 +1,19 @@
package com.marginallyclever.makelangelo.donatelloimpl.nodes.turtle;

import com.marginallyclever.donatello.Donatello;
import com.marginallyclever.donatello.ports.InputBoolean;
import com.marginallyclever.donatello.ports.InputColor;
import com.marginallyclever.donatello.ports.InputInt;
import com.marginallyclever.donatello.ports.InputOneOfMany;
import com.marginallyclever.makelangelo.MainFrame;
import com.marginallyclever.makelangelo.donatelloimpl.ports.InputTurtle;
import com.marginallyclever.makelangelo.makeart.turtlegenerator.Generator_AnalogClock;
import com.marginallyclever.makelangelo.makeart.turtlegenerator.TurtleGeneratorFactory;
import com.marginallyclever.makelangelo.makeart.turtlegenerator.lineweight.GenerateClockHands;
import com.marginallyclever.makelangelo.preview.PreviewPanel;
import com.marginallyclever.makelangelo.turtle.PolylineBuilder;
import com.marginallyclever.makelangelo.turtle.Turtle;
import com.marginallyclever.makelangelo.turtle.TurtleToBufferedImageHelper;
import com.marginallyclever.makelangelo.turtle.turtlerenderer.TurtleRenderFacade;
import com.marginallyclever.makelangelo.turtle.turtlerenderer.TurtleRenderFactory;
import com.marginallyclever.makelangelo.turtle.turtlerenderer.TurtleRenderer;
import com.marginallyclever.nodegraphcore.Node;
import com.marginallyclever.nodegraphcore.PrintWithGraphics;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Nonnull;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
* <p>Print the {@link Turtle}'s path behind the {@link Node}s.</p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public double getTransformedY(double y) {
return ((y / scaleY) - translateY);
}

class Box {
class Box {
public double left, top, right, bottom;

public Box(double left, double top, double right, double bottom) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,15 +103,16 @@ protected void convertOneLayer(TransformedImage img) {
double height = yTop-yBottom;
double width = xRight-xLeft;
double r = Math.sqrt(Math.pow(width/2,2) + Math.pow(height/2,2));

boolean isFirst=true;
double i=-r;
for(double j =-r; j <= r; j+= blockScale) {
i = -i;
a.scale(j,majorAxis);
b.scale(j,majorAxis);
a.scaleAdd(-i,minorAxis,a);
b.scaleAdd(i,minorAxis,b);
turtle.add(wave.lineToWave(a,b));
wave.lineToWave(turtle,a,b,isFirst);
isFirst=false;
}

CropTurtle.run(turtle, myPaper.getMarginRectangle());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,15 +77,15 @@ public void start(Paper paper, TransformedImage image) {
turtle = new Turtle();
turtle.setStroke(Color.BLACK,settings.getDouble(PlotterSettings.DIAMETER));

outputChannel(cmyk.getY(),Color.YELLOW);
outputChannel(cmyk.getC(),Color.CYAN);
outputChannel(cmyk.getM(),Color.MAGENTA);
outputChannel(cmyk.getK(),Color.BLACK);
outputChannel(0,cmyk.getY(),Color.YELLOW);
outputChannel(1,cmyk.getC(),Color.CYAN);
outputChannel(2,cmyk.getM(),Color.MAGENTA);
outputChannel(3,cmyk.getK(),Color.BLACK);

fireConversionFinished();
}

protected void outputChannel(TransformedImage img,Color channel) {
protected void outputChannel(int phaseOffset,TransformedImage img,Color channel) {
Rectangle2D.Double rect = myPaper.getMarginRectangle();
double xLeft = rect.getMinX();
double yBottom = rect.getMinY();
Expand All @@ -99,6 +99,7 @@ protected void outputChannel(TransformedImage img,Color channel) {
newTurtle.setStroke(Color.BLACK,settings.getDouble(PlotterSettings.DIAMETER));

var wave = new WaveByIntensity(img,blockScale/2,sampleRate,zigDensity);
wave.setPhase(phaseOffset*15);

Vector2d majorAxis = new Vector2d(
Math.cos(Math.toRadians(angle)),
Expand All @@ -108,6 +109,7 @@ protected void outputChannel(TransformedImage img,Color channel) {
double height = yTop-yBottom;
double width = xRight-xLeft;
double r = Math.sqrt(Math.pow(width/2,2) + Math.pow(height/2,2));
boolean isFirst=true;

double i=-r;
for(double j =-r; j <= r; j+= blockScale) {
Expand All @@ -116,11 +118,13 @@ protected void outputChannel(TransformedImage img,Color channel) {
b.scale(j,majorAxis);
a.scaleAdd(-i,minorAxis,a);
b.scaleAdd(i,minorAxis,b);
newTurtle.add(wave.lineToWave(a,b));
wave.lineToWave(newTurtle,a,b,isFirst);
isFirst=false;
}

for(var layer : newTurtle.getLayers()) {
layer.setColor(channel);
layer.setName("0x"+Integer.toHexString(channel.getRGB()).substring(2).toUpperCase());
}

CropTurtle.run(newTurtle, myPaper.getMarginRectangle());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,22 +108,24 @@ public void start(Paper paper, TransformedImage image) {

Point2d a = new Point2d();
Point2d b = new Point2d();

boolean isFirst=true;
a.set(Math.cos(0) * r, Math.sin(0) * r);

while (r > toolDiameter*2.0) {
// find circumference of current circle
double circumference = Math.floor((2.0f * r - toolDiameter) * Math.PI)*toolDiameter;
//if (circumference > 360.0f) circumference = 360.0f;
if (circumference < 360.0f) circumference = 360.0f;

for (int i = 0; i <= circumference; ++i) {
// tweak the diameter to make it look like a spiral
double r2 = r - ringSize * i / circumference;
double f = Math.PI * 2.0f * i / circumference;
b.set(Math.cos(f) * r2, Math.sin(f) * r2);

turtle.add(wave.lineToWave(a,b));
a.set(b);
if(a.distanceSquared(b)>=toolDiameter) {
wave.lineToWave(turtle, a, b, isFirst);
isFirst = false;
a.set(b);
}
}
r -= ringSize;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,15 +81,15 @@ public void start(Paper paper, TransformedImage image) {
turtle = new Turtle();
turtle.setStroke(Color.BLACK, settings.getDouble(PlotterSettings.DIAMETER));

outputChannel(cmyk.getY(), Color.YELLOW);
outputChannel(cmyk.getC(), Color.CYAN);
outputChannel(cmyk.getM(), Color.MAGENTA);
outputChannel(cmyk.getK(), Color.BLACK);
outputChannel(0,cmyk.getY(), Color.YELLOW);
outputChannel(1,cmyk.getC(), Color.CYAN);
outputChannel(2,cmyk.getM(), Color.MAGENTA);
outputChannel(3,cmyk.getK(), Color.BLACK);

fireConversionFinished();
}

private void outputChannel(TransformedImage img,Color channel) {
private void outputChannel(int phaseOffset,TransformedImage img,Color channel) {
Turtle newTurtle = new Turtle();
newTurtle.setStroke(Color.BLACK,settings.getDouble(PlotterSettings.DIAMETER));

Expand All @@ -116,10 +116,11 @@ private void outputChannel(TransformedImage img,Color channel) {
double ringSize = spacing;

var wave = new WaveByIntensity(img,halfWaveHeight,sampleRate,zigDensity);
wave.setPhase(phaseOffset*15);

Point2d a = new Point2d();
Point2d b = new Point2d();

boolean isFirst=true;
a.set(Math.cos(0) * r, Math.sin(0) * r);

while (r > toolDiameter*2) {
Expand All @@ -132,15 +133,18 @@ private void outputChannel(TransformedImage img,Color channel) {
double r2 = r - ringSize * (float)i / circumference;
double f = Math.PI * 2.0f * (float)i / circumference;
b.set(Math.cos(f) * r2, Math.sin(f) * r2);

newTurtle.add(wave.lineToWave(a,b));
a.set(b);
if(a.distanceSquared(b)>=toolDiameter) {
wave.lineToWave(newTurtle, a, b, isFirst);
isFirst = false;
a.set(b);
}
}
r -= ringSize;
}

for(var layer : newTurtle.getLayers()) {
layer.setColor(channel);
layer.setName("0x"+Integer.toHexString(channel.getRGB()).substring(2).toUpperCase());
}

CropTurtle.run(newTurtle, myPaper.getMarginRectangle());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package com.marginallyclever.makelangelo.makeart.imagefilter;

import com.marginallyclever.makelangelo.makeart.TransformedImage;

import javax.vecmath.Vector2d;
import java.awt.image.BufferedImage;

/**
* Applies a Sobel filter to an image to detect edges.
* See <a href="https://en.wikipedia.org/wiki/Sobel_operator">Sobel Operator</a>
* @author Dan Royer
*/
public class FilterSobel extends ImageFilter {
private final TransformedImage img;

public FilterSobel(TransformedImage img) {
super();
this.img = img;
}

@Override
public TransformedImage filter() {
double [][] Gy = {
{-1, -2, -1},
{ 0, 0, 0},
{ 1, 2, 1}
};
double [][] Gx = {
{-1, 0, 1},
{-2, 0, 2},
{-1, 0, 1}
};

TransformedImage result = new TransformedImage(img);
BufferedImage before = img.getSourceImage();
BufferedImage after = result.getSourceImage();
Vector2d sumR = new Vector2d();
Vector2d sumG = new Vector2d();
Vector2d sumB = new Vector2d();

// convolve before into result using the Gy matrix
for(int y=0;y<before.getHeight();y++) {
for(int x=0;x<before.getWidth();x++) {
sumR.set(0,0);
sumG.set(0,0);
sumB.set(0,0);

for(int j=-1;j<=1;j++) {
for(int i=-1;i<=1;i++) {
int sampleX = Math.min(Math.max(x+i,0), before.getWidth()-1);
int sampleY = Math.min(Math.max(y+j,0), before.getHeight()-1);
int rgb = before.getRGB(sampleX, sampleY);
int red = ((rgb >> 16) & 0xff);
int green = ((rgb >> 8) & 0xff);
int blue = ((rgb ) & 0xff);
sumR.x += red * Gx[j+1][i+1];
sumR.y += red * Gy[j+1][i+1];
sumG.x += green * Gx[j+1][i+1];
sumG.y += green * Gy[j+1][i+1];
sumB.x += blue * Gx[j+1][i+1];
sumB.y += blue * Gy[j+1][i+1];
}
}

int magR = (int)Math.clamp(sumR.length(), 0, 255);
int magG = (int)Math.clamp(sumG.length(), 0, 255);
int magB = (int)Math.clamp(sumB.length(), 0, 255);
int edgeColor = (0xff << 24) | (magR << 16) | (magG << 8) | magB;
after.setRGB(x, y, edgeColor);
}
}

return result;
}
}
Loading