spuder
spuder

Reputation: 18467

How to convert STL to rotating GIF using OpenSCAD?

Given an STL file, how can you convert it to an animated gif using the command line (bash)?

I've discovered a few articles that vaguely describe how to do this through the GUI. I've been able to generate the following, however the animation is very rough and the shadows jump around.

for ((angle=0; angle <=360; angle+=5)); do
    openscad /dev/null -o dump$angle.png  -D "cube([2,3,4]);" --imgsize=250,250 --camera=0,0,0,45,0,$angle,25
done

# https://unix.stackexchange.com/a/489210/39263
ffmpeg \
  -framerate 24 \
  -pattern_type glob \
  -i 'dump*.png' \
  -r 8 \
  -vf scale=512:-1 \
  out.gif \
;

enter image description here

OpenScad has a built in --animation X parameter, however using that likely won't work when passing in the camera angle as a parameter.

Resources

https://github.com/openscad/openscad/issues/1632#issuecomment-219203658
https://blog.prusaprinters.org/how-to-animate-models-in-openscad_29523/ https://github.com/openscad/openscad/issues/1573
https://github.com/openscad/openscad/pull/1808
https://forum.openscad.org/Product-Video-produced-with-OpenSCAD-td15783.html

Upvotes: 3

Views: 957

Answers (1)

spuder
spuder

Reputation: 18467

Bash + Docker

Converting an STL to a GIF requires several steps

  1. Center the STL at the origin
  2. Convert the STL into a collection of .PNG files from different angles
  3. Combine those PNG files into a .gif file

Assuming you have docker installed you can run the the following to convert an STL into an animated GIF

(Note: A more up to date version of this script is available at spuder/CAD-scripts/stl2gif

This depends on 3 docker containers

# 1. Use spuder/stl2origin:latest docker container to center the file at origin
# A file with the offsets will be saved to `${MYTMPDIR}/foo.sh`
file=/tmp/foo.stl
MYTMPDIR="$(mktemp -d)"
trap 'rm -rf -- "$MYTMPDIR"' EXIT
docker run \
    -e OUTPUT_BASH_FILE=/output/foo.sh \
    -v $(dirname "$file"):/input \
    -v $MYTMPDIR:/output \
    --rm spuder/stl2origin:latest \
    "/input/$(basename "$file")"
    cp "${file}" "$MYTMPDIR/foo.stl"
    
# 2. Read ${MYTMPDIR}/foo.sh and load the offset variables ($XTRANS, $XMID,$YTRANS,$YMID,$ZTRANS,$ZMID) 
# Save the new centered STL to `$MYTMPDIR/foo-centered.stl`
source $MYTMPDIR/foo.sh
docker run \
    -v "$MYTMPDIR:/input" \
    -v "$MYTMPDIR:/output" \
    openscad/openscad:2021.01 openscad /dev/null -D "translate([$XTRANS-$XMID,$YTRANS-$YMID,$ZTRANS-$ZMID])import(\"/input/foo.stl\");" -o "/output/foo-centered.stl"

# 3. Convert the STL into 60 .PNG images with the camera rotating around the object. Note `$t` is a built in openscad variable that is automatically set based on time when --animate option is used
# OSX users will need to replace `openscad` with `/Applications/OpenSCAD.app/Contents/MacOS/OpenSCAD`
# Save all images to $MYTMPDIR/foo{0..60}.png
# This is not yet running in a docker container due to a bug: https://github.com/openscad/openscad/issues/4028

openscad /dev/null \
    -D '$vpr = [60, 0, 360 * $t];' \
    -o "${MYTMPDIR}/foo.png"  \
    -D "import(\"${MYTMPDIR}/foo-centered.stl\");" \
    --imgsize=600,600 \
    --animate 60 \
    --colorscheme "Tomorrow Night" \
    --viewall --autocenter

# 4. Use ffmpeg to combine all images into a .GIF file
# Tune framerate (15) and -r (60) to produce a faster/slower/smoother image
    yes | ffmpeg \
        -framerate 15 \
        -pattern_type glob \
        -i "$MYTMPDIR/*.png" \
        -r 60 \
        -vf scale=512:-1 \
        "${file}.gif" \
        ;
    rm -rf -- "$MYTMPDIR"

STL File
Static PNG

Gif without centering
Before GIF

Gif with centering
After GIF

Upvotes: 2

Related Questions