module GCode ( GCodeFlavor(..) , defaultFlavor , toString ) where import Data.List import Text.Printf import Types data GCodeFlavor = GCodeFlavor { _begin :: String , _end :: String , _toolon :: String , _tooloff :: String } 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" toString :: GCodeFlavor -> Int -> [GCodeOp] -> String toString (GCodeFlavor begin end on off) dpi gops = begin ++ "\n" ++ intercalate "\n" (toString' gops (0,0) True) ++ "\n" ++ end where dd :: Double dd = fromIntegral dpi mm :: Double -> Double mm px = (px / dd) * 2.54 * 10 toString' (GMoveTo p@(x,y) : gs) _ False = printf "G00 X%.4f Y%.4f" (mm x) (mm y) : toString' gs p False toString' (GMoveTo p@(x,y) : gs) _ True = off : printf "G00 X%.4f Y%.4f" (mm x) (mm y) : toString' gs p False toString' gs cp False = on : toString' gs cp True toString' (GLineTo p@(x,y) : gs) _ True = printf "G01 X%.4f Y%.4f" (mm x) (mm y) : toString' gs p True toString' (GArcTo (ox,oy) p@(x,y) cw : gs) (cx,cy) True = arcStr : toString' gs p True where i = ox - cx j = oy - cy cmd = if' cw "G03" "G02" arcStr -- avoid tiny arcs | (mm $ abs i) < 1 && (mm $ abs j) < 1 = printf "G01 X%.4f Y%.4f" (mm x) (mm y) | otherwise = printf "%s X%.4f Y%.4f I%.4f J%.4f" cmd (mm x) (mm y) (mm i) (mm j) toString' [] _ _ = []