Skip to content
Snippets Groups Projects
Dummy.java 13 KiB
Newer Older
  • Learn to ignore specific revisions
  •  * This file is part of LibLaserCut.
     * Copyright (C) 2011 - 2013 Thomas Oster <thomas.oster@rwth-aachen.de>
     * RWTH Aachen University - 52062 Aachen, Germany
    
     *     LibLaserCut is free software: you can redistribute it and/or modify
     *     it under the terms of the GNU Lesser General Public License as published by
     *     the Free Software Foundation, either version 3 of the License, or
     *     (at your option) any later version.
    
     *     LibLaserCut 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 Lesser General Public License for more details.
    
     *     You should have received a copy of the GNU Lesser General Public License
     *     along with LibLaserCut.  If not, see <http://www.gnu.org/licenses/>.
     **/
    
    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.*;
    
    /**
    
     * This class implements a dummy driver that accepts laserjobs and prints debug information about them.
     * You can use it to test the VisiCut GUI without having a real lasercutter.
    
     * @author Max Gaukler <development@maxgaukler.de>, based on the LAOS driver by Thomas Oster <thomas.oster@rwth-aachen.de>
    
     */
    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";
      }
    
      public void sendJob(LaserJob job, ProgressListener pl, List<String> warnings) throws IllegalJobException, Exception {
    
        pl.progressChanged(this, 0);
    
        BufferedOutputStream out;
        pl.taskChanged(this, "checking job");
        checkJob(job);
    
        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 improve SVG-debug output: support bitmaps, add animation
    
         for (JobPart p : job.getParts())
            {
    
              svg.startPart(p.getClass().getSimpleName(), p.getDPI());
    
              if (p instanceof VectorPart)
              {
                System.out.println("VectorPart");
                for (VectorCommand cmd : ((VectorPart) p).getCommandList())
                {
                  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)
              {
    
                System.out.println("RasterPart");
    
                // TODO add raster output for SVG debug output
    
                RasterPart rp = ((RasterPart) p);
                if (rp.getLaserProperty() != null && !(rp.getLaserProperty() instanceof PowerSpeedFocusProperty))
                {
                  throw new IllegalJobException("This driver expects Power,Speed and Focus as settings");
                }
                System.out.println(((PowerSpeedFocusProperty) rp.getLaserProperty()).toString());
    
              }
              if (p instanceof Raster3dPart)
              {
    
                System.out.println("Raster3dPart");
    
                Raster3dPart rp = (Raster3dPart) p;
                if (rp.getLaserProperty() != null && !(rp.getLaserProperty() instanceof PowerSpeedFocusProperty))
                {
                  throw new IllegalJobException("This driver expects Power,Speed and Focus as settings");
                }
                System.out.println(((PowerSpeedFocusProperty) rp.getLaserProperty()).toString());
              }
          }
    
          System.out.println("end of job.");
    
          svg.store(svgOutdir);
    
          pl.progressChanged(this, 100);
    
      @Override
      public int estimateJobDuration(LaserJob job)
      {
    
          // instead of really calculating some duration, just print the number configured from the settings
          // if <0, act as if the driver can not calculate a job duration
          if (!canEstimateJobDuration()) {
              throw new RuntimeException("cannot estimate job duration (dummy driver: fake runtime is set to negative value)");
          }
    
          // return bogus value to test codepaths of GUI
    
      private List<Double> resolutions;
    
      @Override
      public boolean canEstimateJobDuration() {
    
        }
    
      @Override
      public List<Double> getResolutions() {
        if (resolutions == null) {
          resolutions = Arrays.asList(new Double[]{
                    500d
                  });
        }
        return resolutions;
      }
      protected double bedWidth = 250;
    
      /**
       * Get the value of bedWidth
       *
       * @return the value of bedWidth
       */
      @Override
      public double getBedWidth() {
        return bedWidth;
      }
    
      /**
       * Set the value of bedWidth
       *
       * @param bedWidth new value of bedWidth
       */
      public void setBedWidth(double bedWidth) {
        this.bedWidth = bedWidth;
      }
      protected double bedHeight = 280;
    
      /**
       * Get the value of bedHeight
       *
       * @return the value of bedHeight
       */
      @Override
      public double getBedHeight() {
        return bedHeight;
      }
    
      /**
       * Set the value of bedHeight
       *
       * @param bedHeight new value of bedHeight
       */
      public void setBedHeight(double bedHeight) {
        this.bedHeight = bedHeight;
      }
    
      
      public String svgOutdir="";
      
    
      private static String[] settingAttributes = new String[]{
        SETTING_BEDWIDTH,
    
        SETTING_RUNTIME,
        SETTING_SVG_OUTDIR
    
      };
    
      @Override
      public String[] getPropertyKeys() {
        return settingAttributes;
      }
    
      @Override
      public Object getProperty(String attribute) {
        if (SETTING_BEDWIDTH.equals(attribute)) {
          return this.getBedWidth();
        } else if (SETTING_BEDHEIGHT.equals(attribute)) {
          return this.getBedHeight();
    
        } else if (SETTING_RUNTIME.equals(attribute)) {
          return this.fakeRunTime;
    
        } else if (SETTING_SVG_OUTDIR.equals(attribute)) {
          return this.svgOutdir;
    
        }
        return null;
      }
    
      @Override
      public void setProperty(String attribute, Object value) {
        if (SETTING_BEDWIDTH.equals(attribute)) {
          this.setBedWidth((Double) value);
        } else if (SETTING_BEDHEIGHT.equals(attribute)) {
          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();
    
      }
    
      @Override
      public LaserCutter clone() {
        Dummy clone = new Dummy();
        clone.bedHeight = bedHeight;
        clone.bedWidth = bedWidth;