packages feed

juicy-gcode 0.1.0.10 → 0.2.0.1

raw patch · 6 files changed

+99/−85 lines, 6 filesdep +gitrevdep ~optparse-applicative

Dependencies added: gitrev

Dependency ranges changed: optparse-applicative

Files

ChangeLog.md view
@@ -1,5 +1,11 @@ # Revision history for juicy-gcode
 
+## 0.2.0.1 -- 2020-08-24
+
+- Breaking change: change default DPI to 96 instead of 72
+- Breaking change: the option to mirror the Y axis is removed (it is always mirrored now for correct result)
+- Add --version flag
+
 ## 0.1.0.10 -- 2020-08-19
 
 - Improve algorithmic stability at small details
README.md view
@@ -6,11 +6,9 @@ 
 ## Overview
 
-Haskell SVG to G-code converter that aims to support most SVG features. The flavor of the generated G-Code can be influenced providing a configuration file.
-Juicy-gcode, in contrast to most SVG to G-Code converters, approximates bezier curves with [biarcs](http://dlacko.org/blog/2016/10/19/approximating-bezier-curves-by-biarcs/) instead of line segments
-that results in much better curve fit.
+Juicy-gcode is a configurable SVG to G-code converter that approximates bezier curves with [biarcs](http://dlacko.org/blog/2016/10/19/approximating-bezier-curves-by-biarcs/) for maximal curve fitting.
 
-## Installation and usage
+## Installation
 
 The easiest way is to download one of the pre-built binaries from the [releases page](https://github.com/domoszlai/juicy-gcode/releases).
 Alternatively, you can build from source code as follows:
@@ -21,83 +19,89 @@ - `$ stack install`
 - `$ juicy-gcode --help`
 
-```
-juicy-gcode - The SVG to G-Code converter
+## Usage
 
-Usage: juicy-gcode SVGFILE [-f|--flavor CONFIGFILE] [-o|--output OUTPUTFILE]
-                   [-d|--dpi DPI] [-r|--resolution RESOLUTION]
-                   [-m|--mirror-y-axis] [-b|--generate-bezier]
-  Convert SVGFILE to G-Code
+> :warning: **Breaking change**: Since version 0.2.0.1, default DPI is changed to 96 and the option to mirror the Y axis is removed (it is always mirrored now for correct result)
 
-Available options:
-  -h,--help                   Show this help text
-  SVGFILE                     The SVG file to be converted
-  -f,--flavor CONFIGFILE      Configuration of G-Code flavor
-  -o,--output OUTPUTFILE      The output G-Code file (default is standard output)
-  -d,--dpi DPI                Used to determine the size of the SVG when it does
-                              not contain any units; dot per inch (default is 72)
-  -r,--resolution RESOLUTION  Shorter paths are replaced by line segments; mm
-                              (default is 0.1)
-  -m,--mirror-y-axis          Mirror Y axis to have the result in G-Code coordinate
-                              system
-  -b,--generate-bezier        Generate bezier curves (G5) instead of arcs (G2,G3)
+The easier way to use juicy-gcode is to simply provide an SVG file name. The generated GCode will be written to standard output.
+
 ```
+$ juicy-gcode SVGFILE
+```
 
-## Configuration
+Alternativly, you can provide an output file name as well.
 
-The default G-Code flavor configuration file is the following:
+```
+$ juicy-gcode SVGFILE -o OUTPUT
+```
 
+Sometimes you want to overwrite some default settings. These are the 
+
+* *--dpi* (default 96 DPI) [the resolution of the SVG file](https://developer.mozilla.org/en-US/docs/Web/CSS/resolution) that is used to determine the size of the SVG when it does not contain explicit units
+* *--resolution* (default is 0.1 mm) the resolution of the generated GCode. Paths smaller than this are replaced by line segments instead of further approximated by biarcs
+ 
 ```
-gcode
-{
-   begin = "G17;G90;G0 Z10;G0 X0 Y0;M3;G4 P2000.000000"
-   end = "G0 Z10;M5;M2"
-   toolon =  "G00 Z10"
-   tooloff = "G01 Z0 F10.00"
-}
+$ juicy-gcode SVGFILE --dpi 72 --resolution 0.01 
 ```
 
-A new configuration file can be set by the `--flavor` or `-f` command line option.
+Some firmwares (e.g. [Marlin](https://marlinfw.org/docs/gcode/G005.html)) can handle bezier curves directly. In this case
+you can command juicy-gcode not to approximate bezier-curves but emit them unchanged. 
 
-Another configurable property is the resolution of the SVG image in DPI (dot per inch). It can be given by the `--dpi` or `-d` command line option. Default value is 72 DPI.
+```
+$ juicy-gcode SVGFILE --generate-bezier
+```
 
-## Limitations
+## Configuration
 
-Missing features:
+The generated GCode is highly dependent on the actual device it will be executed by. In juicy-gcode these settings are called
+GCode *flavor* and consists of the following:
 
-- text (easy with e.g. [FontyFruity](https://hackage.haskell.org/package/FontyFruity), maybe once, you can convert text to curves easily anyway)
-- filling (moderately difficult)
-- clipping (probably not easy, maybe once)
-- images (not planned)
+- Begin GCode routine (commands that are executed *before* the actual print job)
+- End GCode routine (commands that are executed *after* the actual print job)
+- Tool on (commands to switch the tool on, e.g. lower pen)
+- Tool off (commands to switch the tool off e.g. lift pen)
 
-## Testing and bugs
+These settings can be provided by a configuration file. The default settings
+are made for being able to test the generated GCode in an emulator e.g. with [LaserWeb](https://laserweb.yurl.ch/)
+or [my hanging plotter simulator](https://github.com/domoszlai/hanging-plotter-simulator). 
 
-There is a JavaScript [hanging plotter simulator](https://github.com/domoszlai/hanging-plotter-simulator) mainly developed to test the generated gcode.
-Please file an issue if you run into a problem (or drop me an email to dlacko @ gmail.com).
+```
+gcode
+{
+   begin = "G17;G90;G0 Z1;G0 X0 Y0"
+   end = "G0 Z1"
+   toolon =  "G00 Z1"
+   tooloff = "G01 Z0 F10.00"
+}
+```
 
-## Implementation
+In the case you want to overwrite it, copy this favor to a text file and modify it according to your need. Then use juicy-gcode as follows:
 
-SVG images are built using the following shapes (all of these are subject of an arbitrary affine transformation):
+```
+$ juicy-gcode SVGFILE -f FLAVORFILE
+```
 
-- lines
-- circles
-- ellipses
-- elliptic arcs with optional x axis rotation
-- quadratic and cubic bezier curves
+## Future development
 
-In contrast G-Code implements only
+Juicy-gcode was originally developed as a testbed for my hanging plotter project, but over the years
+it reached maturity and became a really usuable tool. My main idea for further development is to turn it
+into a tool that can drive CNCs in 2.5 dimensions (e.g. carving, engraving) with just one colored SVG file.
 
-- lines
-- non-elliptical arcs
+To be able to test and enjoy that software, I need a proper CNC. Please consider donating a small amount for that purpose,
+or donate an actual CNC if you have a spare one for whatever reason.
 
-That means that only lines, circles and some arcs (non-elliptic ones without rotation) can be translated to G-Code directly. If transformations are also counted, then
-only lines can be translated to G-Code directly as circles are not invariant under affine transformations. Because of this, the converter is implemented in two stages.
+**[Donate for a CNC](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=UGFZYDQSTF58L&source=https://github.com/domoszlai/juicy-gcode/)**
 
-### Stage 1
+Collected so far: 102.47€
+Target: >= 209€
 
-All the SVG drawing operations are translated to a list of MoveTo, LineTo and CubicBezierTo operations as these are invariant under affine transformations.
-Arcs, circles and ellipses can be easily approximated with bezier curves with a small error.
+Thank you so much for all people supporting the development!
 
-### Stage 2
+## Limitations
 
-Cubic bezier curves are approximated with [Biarcs](https://en.wikipedia.org/wiki/Biarc) using the algorithm described in [[1](http://www.itc.ktu.lt/index.php/ITC/article/view/11812)] and explained [here](http://dlacko.org/blog/2016/10/19/approximating-bezier-curves-by-biarcs/).
+SVG features that are not supported:
+
+- texts
+- filling
+- clipping
+- images
juicy-gcode.cabal view
@@ -1,5 +1,5 @@ name:                juicy-gcode
-version:             0.1.0.10
+version:             0.2.0.1
 license:             BSD3
 license-file:        LICENSE
 author:              dlacko
@@ -19,17 +19,18 @@   hs-source-dirs:           src
   main-is:                  Main.hs
 
-  other-modules:            Approx BiArc CircularArc CubicBezier GCode Line Render SvgArcSegment Transformation Types SVGExt
+  other-modules:            Approx BiArc CircularArc CubicBezier GCode Line Render SvgArcSegment Transformation Types SVGExt Paths_juicy_gcode
 
   build-depends:
     base                    >=4.8    && <5,
     lens                    >=4.15.4 && <4.20,
     linear                  >=1.20   && <1.22,
-    optparse-applicative    >=0.13   && <0.16,
+    optparse-applicative    >=0.13   && <0.20,
     configurator            >=0.3    && <0.4,
     text                    >=1.2.2  && <1.3,
     matrix                  >=0.3.5  && <0.4,
-    svg-tree                >=0.6    && <0.7
+    svg-tree                >=0.6    && <0.7,
+    gitrev                  >=1.3.0  && <1.4
 
   GHC-Options:              -Wall
   default-language:         Haskell2010
src/GCode.hs view
@@ -15,7 +15,7 @@                                }
 
 defaultFlavor :: GCodeFlavor
-defaultFlavor =  GCodeFlavor "G17\nG90\nG0 Z10\nG0 X0 Y0\nM3\nG4 P2000.000000" "G0 Z10\nM5\nM2" "G01 Z0 F10.00" "G00 Z10"
+defaultFlavor =  GCodeFlavor "G17\nG90\nG0 Z1\nG0 X0 Y0\n" "G0 Z1" "G01 Z0 F10.00" "G00 Z1"
 
 toString :: GCodeFlavor -> Int -> [GCodeOp] -> String
 toString (GCodeFlavor begin end on off) dpi gops = begin ++ "\n" ++ intercalate "\n" (toString' gops (0,0) True) ++ "\n" ++ end
src/Main.hs view
@@ -1,12 +1,17 @@+{-# LANGUAGE TemplateHaskell #-}
+
 import qualified Graphics.Svg as SVG
 
-import Data.Text
+import Options.Applicative
+import Paths_juicy_gcode (version)
+import Data.Version (showVersion)
+import Development.GitRev (gitHash)
+
+import Data.Text (Text, pack, unpack, replace)
 import qualified Data.Configurator as C
 
 import Data.Monoid
 
-import Options.Applicative
-
 import Render
 import GCode
 
@@ -15,7 +20,6 @@                        , _outfile        :: Maybe String
                        , _dpi            :: Int
                        , _resolution     :: Double
-                       , _mirrorYAxis    :: Bool
                        , _generateBezier :: Bool
                        }
 
@@ -36,10 +40,10 @@      <> help "The output G-Code file (default is standard output)" ))
   <*> (option auto
       ( long "dpi"
-     <> value 72
+     <> value 96
      <> short 'd'
      <> metavar "DPI"
-     <> help "Used to determine the size of the SVG when it does not contain any units; dot per inch (default is 72)" ))
+     <> help "Used to determine the size of the SVG when it does not contain any units; dot per inch (default is 96)" ))
  <*> (option auto
       ( long "resolution"
      <> value 0.1
@@ -47,21 +51,17 @@      <> metavar "RESOLUTION"
      <> help "Shorter paths are replaced by line segments; mm (default is 0.1)" ))
   <*> (switch
-      ( long "mirror-y-axis"
-     <> short 'm'
-     <> help "Mirror Y axis to have the result in G-Code coordinate system" ))
-  <*> (switch
       ( long "generate-bezier"
       <> short 'b'
       <> help "Generate bezier curves (G5) instead of arcs (G2,G3)" ))
 
 runWithOptions :: Options -> IO ()
-runWithOptions (Options svgFile mbCfg mbOut dpi resolution mirrorYAxis generateBezier) =
+runWithOptions (Options svgFile mbCfg mbOut dpi resolution generateBezier) =
     do
         mbDoc <- SVG.loadSvgFile svgFile
         flavor <- maybe (return defaultFlavor) readFlavor mbCfg
         case mbDoc of
-            (Just doc) -> writer (toString flavor dpi $ renderDoc mirrorYAxis generateBezier dpi resolution doc)
+            (Just doc) -> writer (toString flavor dpi $ renderDoc generateBezier dpi resolution doc)
             Nothing    -> putStrLn "juicy-gcode: error during opening the SVG file"
     where
         writer = maybe putStrLn (\fn -> writeFile fn) mbOut
@@ -78,10 +78,15 @@   tooloff      <- C.require cfg (pack "gcode.tooloff")
   return $ GCodeFlavor (toLines begin) (toLines end) (toLines toolon) (toLines tooloff)
 
+versionOption :: Parser (a -> a)
+versionOption = infoOption 
+                    (concat ["juicy-gcode ", showVersion version, ", git revision ", $(gitHash)])
+                    (long "version" <> short 'v' <> help "Show version")
+
 main :: IO ()
 main = execParser opts >>= runWithOptions
   where
-    opts = info (helper <*> options)
+    opts = info (helper <*> versionOption <*> options)
       ( fullDesc
      <> progDesc "Convert SVGFILE to G-Code"
      <> header "juicy-gcode - The SVG to G-Code converter" )
src/Render.hs view
@@ -52,23 +52,21 @@ toAbsolute _ SVG.OriginAbsolute p = p
 toAbsolute (cx,cy) SVG.OriginRelative (dx,dy) = (cx+dx, cy+dy)
 
-docTransform :: Bool -> Int -> SVG.Document -> TransformationMatrix
-docTransform mirrorYAxis dpi doc = multiply mirrorTransform (viewBoxTransform $ SVG._viewBox doc)
+docTransform :: Int -> SVG.Document -> TransformationMatrix
+docTransform dpi doc = multiply mirrorTransform (viewBoxTransform $ SVG._viewBox doc)
     where
         viewBoxTransform (Just (vbx,vby,vbw,vbh))
             = multiply (scaleTransform (w/vbw) (h/vbh)) (translateTransform (-vbx) (-vby))
         viewBoxTransform Nothing
             = identityTransform
 
-        mirrorTransform
-            | mirrorYAxis = mirrorYTransform w h
-            | otherwise   = identityTransform
+        mirrorTransform = mirrorYTransform w h
 
         (w, h) = (documentSize dpi doc)
 
-renderDoc :: Bool -> Bool -> Int -> Double -> SVG.Document -> [GCodeOp]
-renderDoc mirrorYAxis generateBezier dpi resolution doc
-    = stage2 $ renderTrees (docTransform mirrorYAxis dpi doc) (SVG._elements doc)
+renderDoc :: Bool -> Int -> Double -> SVG.Document -> [GCodeOp]
+renderDoc generateBezier dpi resolution doc
+    = stage2 $ renderTrees (docTransform dpi doc) (SVG._elements doc)
     where
         pxresolution = (fromIntegral dpi) / 2.45 / 10 * resolution