{-# LANGUAGE RecordWildCards #-}
module Data.GCode.Utils where
import Data.Maybe
import Data.GCode.Types
import Data.GCode.RS274 (isMove, isRapid)
import qualified Data.Map.Strict as M
isG :: Code -> Bool
isG Code{codeCls=(Just G)} = True
isG _ = False
isM :: Code -> Bool
isM Code{codeCls=(Just M)} = True
isM _ = False
isGN :: Int -> Code -> Bool
isGN n Code{codeCls=(Just G), codeNum=(Just x)} = x == n
isGN _ _ = False
hasAxis :: AxisDesignator -> Code -> Bool
hasAxis a Code{..} = M.member a codeAxes
hasAxis _ _ = False
getAxis :: AxisDesignator -> Code -> Maybe Double
getAxis a Code{..} = M.lookup a codeAxes
getAxis _ _ = Nothing
getAxes :: [AxisDesignator] -> Code -> [Maybe Double]
getAxes as c = map (\a-> getAxis a c) as
getAxesToList :: Code -> [(AxisDesignator, Double)]
getAxesToList Code{..} = M.toList codeAxes
getAxesToList _ = []
hasX :: Code -> Bool
hasX = hasAxis X
hasY :: Code -> Bool
hasY = hasAxis Y
hasZ :: Code -> Bool
hasZ = hasAxis Z
hasE :: Code -> Bool
hasE = hasAxis E
hasParam :: ParamDesignator -> Code -> Bool
hasParam p Code{..} = M.member p codeParams
hasParam _ _ = False
getParam :: ParamDesignator -> Code -> Maybe Double
getParam p Code{..} = M.lookup p codeParams
getParam _ _ = Nothing
hasFeedrate :: Code -> Bool
hasFeedrate = hasParam F
gcodes :: [Code] -> [Code]
gcodes = filter isG
mcodes :: [Code] -> [Code]
mcodes = filter isM
rapids :: [Code] -> [Code]
rapids = filter isRapid
moves :: [Code] -> [Code]
moves = filter isMove
replaceClass :: Class -> Code -> Code
replaceClass newclass c = cls newclass c
replaceCode :: Int -> Code -> Code
replaceCode newcode c = num newcode c
replaceAxis :: AxisDesignator -> Double -> Code -> Code
replaceAxis de val c | hasAxis de c = addReplaceAxis de val c
replaceAxis _ _ c = c
modifyAxis :: AxisDesignator -> (Double -> Double) -> Code -> Code
modifyAxis de f c | hasAxis de c = addReplaceAxis de (f $ fromJust $ getAxis de c) c
modifyAxis _ _ c = c
modifyAxes :: [AxisDesignator] -> (Double -> Double) -> Code -> Code
modifyAxes axes' f c = foldl (\c1 ax -> modifyAxis ax f c1) c axes'
hasXY :: Code -> Bool
hasXY c = hasAxis X c && hasAxis Y c
modifyXY :: (Double -> Double -> (Double, Double)) -> Code -> Code
modifyXY f c | hasXY c =
let x = fromJust $ getAxis X c
y = fromJust $ getAxis Y c
(nx, ny) = f x y
in c & axis X nx & axis Y ny
modifyXY _ c = c
addReplaceAxis :: AxisDesignator -> Double -> Code -> Code
addReplaceAxis de val c@Code{..} = c & (axes $ newaxes $ codeAxes)
where
newaxes = M.insert de val
addReplaceAxis _ _ x = x
replaceX :: Double -> Code -> Code
replaceX = replaceAxis X
replaceY :: Double -> Code -> Code
replaceY = replaceAxis Y
replaceZ :: Double -> Code -> Code
replaceZ = replaceAxis Z
replaceE :: Double -> Code -> Code
replaceE = replaceAxis E
addReplaceX :: Double -> Code -> Code
addReplaceX = addReplaceAxis X
addReplaceY :: Double -> Code -> Code
addReplaceY = addReplaceAxis Y
addReplaceZ :: Double -> Code -> Code
addReplaceZ = addReplaceAxis Z
addReplaceE :: Double -> Code -> Code
addReplaceE = addReplaceAxis E
replaceParam :: ParamDesignator -> Double -> Code -> Code
replaceParam de val c | hasParam de c = addReplaceParam de val c
replaceParam _ _ c = c
modifyParam :: ParamDesignator -> (Double -> Double) -> Code -> Code
modifyParam de f c | hasParam de c = addReplaceParam de (f $ fromJust $ getParam de c) c
modifyParam _ _ c = c
modifyParams :: [ParamDesignator] -> (Double -> Double) -> Code -> Code
modifyParams params' f c = foldl (\c1 ax -> modifyParam ax f c1) c params'
modifyParamsWithKey :: [ParamDesignator] -> (ParamDesignator -> Double -> Double) -> Code -> Code
modifyParamsWithKey params' f c = foldl (\c1 ax -> modifyParam ax (f ax) c1) c params'
addReplaceParam :: ParamDesignator -> Double -> Code -> Code
addReplaceParam de val c@Code{..} = c & (params $ newparams $ codeParams)
where
newparams = M.insert de val
addReplaceParam _ _ x = x
replaceFeedrate :: Double -> Code -> Code
replaceFeedrate = replaceParam F
modifyFeedrate :: (Double -> Double) -> Code -> Code
modifyFeedrate = modifyParam F
travelDistance :: Code -> Double
travelDistance Code{codeCls=(Just G), ..} = M.foldl (+) 0 codeAxes
travelDistance _ = 0
roundprec :: (Integral a, RealFrac b, Fractional c) => a -> b -> c
roundprec n x = (fromInteger $ round $ x * (10^n)) / (10.0^^n)