packages feed

reanimate-0.2.0.0: examples/blender_sphere.hs

#!/usr/bin/env stack
-- stack runghc --package reanimate
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes       #-}
module Main (main) where

import           Data.String.Here
import qualified Data.Text         as T
import           Reanimate

main :: IO ()
main = reanimate $ mkAnimation 5 $ \t ->
    let s = t * pi * 2 in
    mkGroup
    [ mkBackground "black"
    , blender (script s)
    ]

texture :: FilePath
texture = svgAsPngFile (mkGroup
  [ checker 10 10
  , withFillColor "red" $
    scale 2 $ center $
    latexAlign "\\sum_{k=1}^\\infty {1 \\over k^2} = {\\pi^2 \\over 6}"])

script :: Double -> T.Text
script s = [iTrim|
import os

import bpy

origin = bpy.data.objects['Cube']

bpy.ops.object.select_all(action='DESELECT')
origin.select_set(True)
bpy.ops.object.delete()

bpy.ops.mesh.primitive_uv_sphere_add(segments=100,ring_count=100)
sphere = bpy.context.object
sphere.rotation_euler = (0,0,${s})
bpy.ops.object.shade_smooth()

# bpy.data.materials.new('Prog mat')
bpy.context.object.active_material = bpy.data.materials['Material']
mat = bpy.context.object.active_material
image_node = mat.node_tree.nodes.new('ShaderNodeTexImage')
texture = mat.node_tree.nodes['Principled BSDF']
texture.inputs['Roughness'].default_value = 1
mat.node_tree.links.new(image_node.outputs['Color'], texture.inputs['Base Color'])

image_node.image = bpy.data.images.load('${T.pack texture}')

scn = bpy.context.scene
#scn.render.engine = 'CYCLES'
scn.render.film_transparent = True

bpy.ops.render.render( write_still=True )

|]


checker :: Int -> Int -> SVG
checker w h =
  withFillColor "white" $
  withStrokeColor "white" $
  withStrokeWidth 0.1 $
  mkGroup
  [ withStrokeWidth 0 $
    withFillOpacity 0.8 $ mkBackground "blue"
  , mkGroup
    [ translate (stepX*x-offsetX + stepX/2) 0 $
      mkLine (0, -screenHeight/2*0.9) (0, screenHeight/2*0.9)
    | x <- map fromIntegral [0..w-1]
    ]
  ,
    mkGroup
    [ translate 0 (stepY*y-offsetY) $
      mkLine (-screenWidth/2, 0) (screenWidth/2, 0)
    | y <- map fromIntegral [0..h]
    ]
  ]
  where
    stepX = screenWidth/fromIntegral w
    stepY = screenHeight/fromIntegral h
    offsetX = screenWidth/2
    offsetY = screenHeight/2