Hey,
I’m working on a slicer for a CNC-Project.
The aim is to convert selected 3D-Surefaces to G-Code to milling 2D contours with my CNC-Robot.
Till yet I started with the Slicer, and made the 3D Viewer and Editor.
The contour is built up by 2 ArrayList’s and an one Vector2f.
(ArrayList<ArrayList>)
The Vector2f is used for Points.
The ArrayList above is for single contours (connected lines).
The ArrayList above this ArrayList is to store a lot of single contours.
Now I have 3 classes:
ContourSlicer3DViewer (3D Viewer to convert 3D surfaces to 2D Contours; return contour)
ContourEditor (Editor to edit contours (move, scale, rotate, mirror); return contour)
ContourSlicer (The Slicer to convert contours to G-Code; return G-Code)
I tested it, and my 3D Viewer and the Editor works, if I directly handover the Contour List from 3D Viewer to Editor.
But if I first handover the contour to ContourSlicer, and then to Editor, it won’t work with a lot of errors.
“Exception in thread “main” java.lang.NullPointerException
at contourSlicer.Window.createContour(Window.java:79)
at contourSlicer.Window.(Window.java:67)
at contourSlicer.ContourSlicer.main(ContourSlicer.java:15)”
Or
“Uncaught exception thrown in Thread[jME3 Main,5,main]
IllegalStateException: Scene graph is not properly updated for rendering.
State was changed after rootNode.updateGeometricState() call.
Make sure you do not modify the scene from another thread!
Problem spatial name: Gui Node”
I tried a lot of things, but nothing works…
Here is the code:
ContourEditor:
public boolean isRunning() {
return isRunning;
}
public ContourEditor() {
super("Contour Editor");
}
public void start(ArrayList<ArrayList<Vector2f>> v) {
isRunning = true;
this.setLayout(new BorderLayout());
this.setLocation(0,0);
this.getContentPane().setPreferredSize(new Dimension(640,480));
this.add(canvas,BorderLayout.CENTER);
this.add(bar,BorderLayout.SOUTH);
3DViewer:
public ArrayList<ArrayList<Vector2f>> getPoints() {
if (convertedPoints.size() <= 0) {
return null;
} else {
return convertedPoints;
}
}
ContourSlicer: (Window.java)
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package contourSlicer;
import ContourEditor.ContourEditor;
import ContourFunctions.ContourFunctions;
import com.jme3.math.Vector2f;
import contourslicer3dviewer.ContourSlicer3DViewer;
import contourslicer3dviewer.FileChooser;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Polygon;
import java.io.File;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
*
* @author Admin
*/
public class Window extends JFrame {
private ContourFunctions contourFunctions;
private Window window = this;
private ContourSlicer3DViewer viewer = new ContourSlicer3DViewer();
private ContourEditor editor = new ContourEditor();
private Canvas canvas = new Canvas();
private ArrayList<ArrayList<ArrayList<Vector2f>>> contours = new ArrayList<>();
private ArrayList<ArrayList<Vector2f>> editableContour;
private Thread viewerThread = new Thread(){
public void run(){
System.out.println("Start viewer");
viewer.start();
}
};
private Thread editorThread = new Thread(){
public void run(){
System.out.println("Start editor");
editor.start(editableContour);
}
};
public Window() {
super("Contour Slicer");
this.setLocation(0,0);
this.getContentPane().setPreferredSize(new Dimension(640,480));
this.add(canvas);
canvas.setVisible(true);
this.pack();
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
createContour();
}
private void createContour(){
this.setVisible(false);
viewerThread.start();
while(viewer.isRunning()) try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger(ContourSlicer.class.getName()).log(Level.SEVERE, null, ex);
}
ArrayList<ArrayList<Vector2f>> contour = contourFunctions.copyContourListWithoutArray(viewer.getPoints());
if (viewer.getPoints().size() <= 0) {
viewer.destroy();
} else {
editContour(contour);
viewerThread.interrupt();
viewer.stop();
viewer.destroy();
}
}
private void editContour(ArrayList<ArrayList<Vector2f>> contour){
this.setVisible(false);
editableContour = contour;
editorThread.start();
while(editor.isRunning()) try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger(ContourSlicer.class.getName()).log(Level.SEVERE, null, ex);
}
editorThread.interrupt();
if (editor.getContour() == null);
else {
contours.add((ArrayList<ArrayList<Vector2f>>) editor.getContour().clone());
}
editableContour = new ArrayList<>();
editor.dispose();
this.setVisible(true);
}
private class Canvas extends JPanel {
private Paint paint;
private static final int TOTAL_RECTANGLES = 5;
private static final int WIDTH = 400;
private static final int HEIGHT = 300;
private static final int RADIUS = 50;
private static final int X = 50;
private static final int Y = 50;
private int counter;
private int moveXBy;
private boolean isActive;
private int count;
public Canvas () {
setOpaque (true);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(window.getPreferredSize().width, window.getPreferredSize().height);
}
@Override
protected void paintComponent(Graphics g2) {
Graphics2D g = (Graphics2D) g2;
super.paintComponent(g);
g.setPaint(paint);
g.setColor(Color.black);
g.setStroke(new BasicStroke(1));
Polygon p = new Polygon();
for (int i = 0; i < contours.size();i++) {
for (int i2 = 0; i2 < contours.get(i).size();i2++) {
for (int i3 = 0; i3 < contours.get(i).get(i2).size();i3++) {
p.addPoint((int) Math.round(contours.get(i).get(i2).get(i3).x), (int) Math.round(contours.get(i).get(i2).get(i3).y));
}
}
}
g.drawPolygon(p);
}
}
}
ContourFunctions:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package ContourFunctions;
import com.jme3.math.Vector2f;
import java.util.ArrayList;
/**
*
* @author Admin
*/
public class ContourFunctions {
/*
Copy some contour
*/
public ArrayList<ArrayList<Vector2f[]>> copyContourListWithArray(ArrayList<ArrayList<Vector2f[]>> listToCopy) {
ArrayList<ArrayList<Vector2f[]>> newList = new ArrayList<>();
for (int i = 0; i < listToCopy.size();i++) {
ArrayList<Vector2f[]> list = new ArrayList<>();
for (int i2 = 0; i2 < listToCopy.get(i).size();i2++) {
Vector2f vArray[] = new Vector2f[2];
vArray[0] = listToCopy.get(i).get(i2)[0].clone();
vArray[1] = listToCopy.get(i).get(i2)[1].clone();
list.add(vArray);
}
newList.add(list);
}
return newList;
}
public ArrayList<ArrayList<Vector2f>> copyContourListWithoutArray(ArrayList<ArrayList<Vector2f>> listToCopy) {
ArrayList<ArrayList<Vector2f>> newList = new ArrayList<>();
for (int i = 0; i < listToCopy.size();i++) {
ArrayList<Vector2f> list = new ArrayList<>();
for (int i2 = 0; i2 < listToCopy.get(i).size();i2++) {
list.add(listToCopy.get(i).get(i2).clone());
}
newList.add(list);
}
return newList;
}
/*
Copy some line
*/
public ArrayList<Vector2f[]> copyLineListWithArray(ArrayList<Vector2f[]> listToCopy) {
ArrayList<Vector2f[]> list = new ArrayList<>();
for (int i = 0; i < listToCopy.size();i++) {
Vector2f vArray[] = new Vector2f[2];
vArray[0] = listToCopy.get(i)[0].clone();
vArray[1] = listToCopy.get(i)[1].clone();
list.add(vArray);
}
return list;
}
public ArrayList<Vector2f> copyLineListWithoutArray(ArrayList<Vector2f> listToCopy) {
ArrayList<Vector2f> list = new ArrayList<>();
for (int i = 0; i < listToCopy.size();i++) {
Vector2f v = listToCopy.get(i).clone();
list.add(v);
}
return list;
}
/*
Convert contour to string
*/
public String contourToStringWithArray(ArrayList<ArrayList<Vector2f[]>> contour) {
String s = "";
for (int i = 0; i < contour.size();i++) {
if (i > 0)
s += ";";
ArrayList<Vector2f[]> lines = contour.get(i);
for (int i2 = 0; i2 < lines.size();i2++) {
if (i2 > 0)
s += ":";
s += Float.toString(lines.get(i2)[0].x);
s += ",";
s += Float.toString(lines.get(i2)[0].y);
}
}
return s;
}
public String contourToStringWithoutArray(ArrayList<ArrayList<Vector2f>> contour) {
String s = "";
for (int i = 0; i < contour.size();i++) {
if (i > 0)
s += ";";
ArrayList<Vector2f> lines = contour.get(i);
for (int i2 = 0; i2 < lines.size();i2++) {
if (i2 > 0)
s += ":";
s += Float.toString(lines.get(i2).x);
s += ",";
s += Float.toString(lines.get(i2).y);
}
}
return s;
}
/*
Convert string to contour
*/
public ArrayList<ArrayList<Vector2f[]>> stringToContourWithArray(String s) {
ArrayList<ArrayList<Vector2f[]>> contourReturn = new ArrayList<>();
String contours[] = s.split(";");
for (int i = 0; i < contours.length;i++) {
ArrayList<Vector2f[]> lineList = new ArrayList<>();
String contour = contours[i];
String[] points = contour.split(":");
for (int i2 = 0; i2 < points.length;i2++) {
String[] point1;
String[] point2;
if (i2 < points.length-1) {
point1 = points[i2].split(",");
point2 = points[i2+1].split(",");
} else {
point1 = points[i2].split(",");
point2 = points[0].split(",");
}
Vector2f[] v = {new Vector2f(Float.parseFloat(point1[0]),Float.parseFloat(point1[1])),new Vector2f(Float.parseFloat(point2[0]),Float.parseFloat(point2[1]))};
lineList.add(v);
}
contourReturn.add(lineList);
}
return contourReturn;
}
public ArrayList<ArrayList<Vector2f>> stringToContourWithoutArray(String s) {
ArrayList<ArrayList<Vector2f>> contourReturn = new ArrayList<>();
String contours[] = s.split(";");
for (int i = 0; i < contours.length;i++) {
ArrayList<Vector2f> lineList = new ArrayList<>();
String contour = contours[i];
String[] points = contour.split(":");
for (int i2 = 0; i2 < points.length;i2++) {
String[] point1;
point1 = points[i2].split(",");
Vector2f v = new Vector2f(Float.parseFloat(point1[0]),Float.parseFloat(point1[1]));
lineList.add(v);
}
contourReturn.add(lineList);
}
return contourReturn;
}
}
Sorry, if it’s complicated, but I don’t know, how to make it easier.
Thanks a lot for all help!