{-# LANGUAGE OverloadedStrings #-}
module Reanimate.Blender
( blender
, blender'
) where
import Codec.Picture.Png
import qualified Data.ByteString as B
import Data.Text (Text)
import qualified Data.Text.IO as T
import Graphics.SvgTree (Tree (..))
import Reanimate.Cache
import Reanimate.Misc
import Reanimate.Raster
import Reanimate.Parameters
import Reanimate.Animation
import Reanimate.Svg.Constructors
import System.FilePath (replaceExtension, (<.>))
import System.IO.Unsafe (unsafePerformIO)
import Data.Hashable
blender :: Text -> SVG
blender script =
unsafePerformIO $ mkBlenderImage script
blender' :: Text -> FilePath
blender' script =
unsafePerformIO $ mkBlenderImage' script
mkBlenderImage :: Text -> IO Tree
mkBlenderImage script | pNoExternals = pure $ mkText script
mkBlenderImage script = do
png <- B.readFile =<< mkBlenderImage' script
case decodePng png of
Left{} -> error "bad image"
Right img -> return $ center $ scaleToSize 16 9 $ embedDynamicImage img
mkBlenderImage' :: Text -> IO FilePath
mkBlenderImage' _ | pNoExternals = pure "/blender/has/been/disabled"
mkBlenderImage' script = cacheFile template $ \target -> do
exec <- requireExecutable "blender"
let py_file = replaceExtension target "py"
T.writeFile py_file script
runCmd exec [ "--background","--render-format", "PNG"
, "--python-exit-code", "1"
, "--render-output", target, "--python", py_file]
where
template = show (hash script) <.> "png"