Skip to content
Snippets Groups Projects
Commit 01eed576 authored by Max Gaukler's avatar Max Gaukler
Browse files

dummy driver: add SVG output

parent 0d41e0f8
No related branches found
No related tags found
No related merge requests found
......@@ -21,6 +21,12 @@ package com.t_oster.liblasercut.drivers;
import com.t_oster.liblasercut.*;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.*;
/**
......@@ -33,26 +39,204 @@ public class Dummy extends LaserCutter {
private static final String SETTING_BEDWIDTH = "Laserbed width";
private static final String SETTING_BEDHEIGHT = "Laserbed height";
private static final String SETTING_RUNTIME = "Fake estimated run-time in seconds (-1 to disable)";
private static final String SETTING_SVG_OUTDIR = "SVG Debug output directory (set empty to disable)";
/**
* SVG output creator, mostly for testing vector-sorting
*/
class SVGWriter {
private double xPrev,xNow,yPrev,yNow;
private StringBuilder svg = new StringBuilder();
private boolean vectorPathActive=false;
private boolean partActive=false;
private int idCounter=0;
private int partCounter=0;
private LaserCutter cutter;
private double dpi;
public SVGWriter(LaserCutter cutter) {
this.cutter = cutter;
}
/**
* start a new JobPart
* @param title some string that will be included in the group ID
* @param dpi
*/
public void startPart(String title, double dpi) {
endPart();
partCounter += 1;
this.dpi=dpi;
this.partActive=true;
svg.append("<g style=\"fill:none;stroke:#000000;stroke-width:0.1mm;\" id=\"");
svg.append("visicut-part").append(partCounter).append("-");
svg.append(title.replaceAll("[^a-zA-Z0-9]","_"));
svg.append("\">\n");
}
/**
* end a JobPart
*/
public void endPart() {
moveTo(0,0); // end path
if (partActive) {
partActive=false;
svg.append("</g>\n");
}
}
private void setLocation(int x, int y) {
xPrev=xNow;
yPrev=yNow;
double factor = 25.4/dpi; // convert units to millimeters
xNow=x*factor;
yNow=y*factor;
}
/**
* move to somewhere with laser off
* @param x
* @param y
*/
void moveTo(int x, int y) {
setLocation(x,y);
if (vectorPathActive) {
// end the previous path
svg.append("\"/>\n");
vectorPathActive=false;
}
}
/**
* move to somewhere with laser on
* @param x
* @param y
*/
void lineTo(int x, int y) {
setLocation(x,y);
if (!partActive) {
throw new RuntimeException("lineTo called outside of a part!");
}
if (!vectorPathActive) {
// start a new path
vectorPathActive=true;
svg.append("<path id=\"visicut-").append(idCounter).append("\" d=\"M ");
idCounter += 1;
svg.append(xPrev).append(",").append(yPrev).append(" ");
}
svg.append(xNow).append(",").append(yNow).append(" ");
}
/**
* generate SVG output string and reset everything (delete all path data)
* @return
*/
private String getSVG() {
endPart();
svg.insert(0,"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?> \n"
+ "<!-- Created by VisiCut Debug output -->\n"
+ "<svg xmlns:svg=\"http://www.w3.org/2000/svg\" "
+ "xmlns=\"http://www.w3.org/2000/svg\" "
+ "width=\"" + cutter.getBedWidth() + "mm\" "
+ "height=\"" + cutter.getBedHeight() + "mm\" "
+ "viewBox=\"0 0 " + cutter.getBedWidth() + " " + cutter.getBedHeight() + "\" "
+ "version=\"1.1\" id=\"svg\"> \n");
svg.append("</svg>\n");
String result=svg.toString();
svg = new StringBuilder();
idCounter=0;
return result;
}
/**
* store a String into a file
* @param path the filename
* @param str the content to be stored
*/
private void storeString(String path, String str) {
try {
FileWriter f = new FileWriter(path);
BufferedWriter b = new BufferedWriter(f);
b.write(str);
b.close();
} catch (Exception e) {
System.out.println("Could not write debug SVG: Exception: " + e);
}
}
/**
* store XHTML viewer to file
* @param path
* @param svgString
*/
void storeXHTML(String path, String svgString) {
BufferedReader br = null;
StringBuilder xhtml = new StringBuilder();
try {
InputStream stream = new Dummy().getClass().getResourceAsStream("resources/visicut-svg-output-viewer.xhtml");
StringBuilder s = new StringBuilder();
br = new BufferedReader(new InputStreamReader(stream, "UTF-8"));
String line="";
while ((line=br.readLine()) != null) {
if (line.contains("<!-- REPLACE THIS WITH SVG -->")) {
// insert svg, but skip first line with <?xml...
line=svgString.substring(svgString.indexOf("\n"));
}
xhtml.append(line).append("\n");
}
storeString(path, xhtml.toString());
} catch (Exception e) {
System.out.println("could not store debug XHTML: " + e);
} finally {
try {
br.close();
} catch (IOException ex) {
System.out.println("could not close bufferedWriter when storing debug XHTML");
}
}
}
void store(String directory) {
if (directory == null || directory.isEmpty()) {
System.out.println("Not writing debug SVG - no output directory set (edit lasercutter settings to change)");
} else {
String pathSVG=directory + "/visicut-debug.svg";
System.out.println("storing SVG debug output to "+pathSVG);
String svgString=getSVG();
storeString(pathSVG,svgString);
String pathXHTML=directory + "/visicut-svg-output-viewer.xhtml";
System.out.println("storing SVG debug output (XHTML viewer) to "+pathXHTML);
storeXHTML(pathXHTML, svgString);
}
}
}
@Override
public String getModelName() {
return "Dummy";
}
@Override
public void sendJob(LaserJob job, ProgressListener pl) throws IllegalJobException, Exception {
pl.progressChanged(this, 0);
BufferedOutputStream out;
pl.taskChanged(this, "checking job");
checkJob(job);
job.applyStartPoint();
pl.taskChanged(this, "sending");
pl.taskChanged(this, "sent.");
SVGWriter svg = new SVGWriter(this); // SVG debug output
System.out.println("dummy-driver got LaserJob: ");
// TODO don't just print the parts and settins, but also the commands
// TODO if you have too much time, also implement some preview output (svg animation???) - would be nice for testing optimisations
for (JobPart p : job.getParts())
{
svg.startPart(p.getClass().getSimpleName(), p.getDPI());
if (p instanceof VectorPart)
{
System.out.println("VectorPart");
......@@ -60,16 +244,25 @@ public class Dummy extends LaserCutter {
{
if (cmd.getType() == VectorCommand.CmdType.SETPROPERTY)
{
if (!(cmd.getProperty() instanceof PowerSpeedFocusFrequencyProperty))
{
throw new IllegalJobException("This driver expects Power,Speed,Frequency and Focus as settings");
}
System.out.println(((PowerSpeedFocusFrequencyProperty) cmd.getProperty()).toString());
} else if (cmd.getType() == VectorCommand.CmdType.LINETO) {
System.out.println("LINETO \t" + cmd.getX() + ", \t" + cmd.getY());
svg.lineTo(cmd.getX(),cmd.getY());
} else if (cmd.getType() == VectorCommand.CmdType.MOVETO) {
System.out.println("MOVETO \t" + cmd.getX() + ", \t" + cmd.getY());
svg.moveTo(cmd.getX(),cmd.getY());
}
}
}
if (p instanceof RasterPart)
{
// TODO add raster output for SVG debug output
RasterPart rp = ((RasterPart) p);
if (rp.getLaserProperty() != null && !(rp.getLaserProperty() instanceof PowerSpeedFocusProperty))
{
......@@ -89,6 +282,7 @@ public class Dummy extends LaserCutter {
}
}
System.out.println("end of job.");
svg.store(svgOutdir);
pl.progressChanged(this, 100);
}
......@@ -161,10 +355,14 @@ public class Dummy extends LaserCutter {
public void setBedHeight(double bedHeight) {
this.bedHeight = bedHeight;
}
public String svgOutdir="";
private static String[] settingAttributes = new String[]{
SETTING_BEDWIDTH,
SETTING_BEDHEIGHT,
SETTING_RUNTIME
SETTING_RUNTIME,
SETTING_SVG_OUTDIR
};
@Override
......@@ -180,6 +378,8 @@ public class Dummy extends LaserCutter {
return this.getBedHeight();
} else if (SETTING_RUNTIME.equals(attribute)) {
return this.fakeRunTime;
} else if (SETTING_SVG_OUTDIR.equals(attribute)) {
return this.svgOutdir;
}
return null;
}
......@@ -192,6 +392,8 @@ public class Dummy extends LaserCutter {
this.setBedHeight((Double) value);
} else if (SETTING_RUNTIME.equals(attribute)) {
this.fakeRunTime=Integer.parseInt(value.toString());
} else if (SETTING_SVG_OUTDIR.equals(attribute)) {
this.svgOutdir=value.toString();
}
}
......
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<head>
<title>VisiCut SVG debug view</title>
</head>
<style>
.done{stroke:black;}
.todo{stroke:grey; fill:none;}
</style>
<script>
<![CDATA[
var maximum=0;
function load(n) {
// get maximum
var i=0;
while (true) {
var obj=document.getElementById('visicut-'+i);
if (obj==null) {
// end of elements reached
break;
}
i++;
maximum=i;
}
document.getElementById('slider').max=maximum;
}
function showUntil(n) {
for (var i=0; i<n; i++) {
document.getElementById('visicut-'+i).setAttribute('class','done');
}
var i=n;
while (true) {
var obj=document.getElementById('visicut-'+i);
if (obj==null) {
// end of elements reached
break;
}
obj.setAttribute('class','todo');
i++;
}
}
]]>
</script>
<body onload="load()">
<h1>VisiCut debug output</h1>
<div style="display:block; width:100%;">
Slide to see individual steps. Please use this with Chrome or another browser that supports &lt;input type=&quot;range&quot;&gt; (not Firefox).<br/>
Start <input id="slider" type="range" value="0" min="0" max="0" onchange="showUntil(this.value)" style="width:60%"/> End
</div>
<!-- REPLACE THIS WITH SVG -->
</body>
</html>
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment