mirror of
https://github.com/3b1b/manim.git
synced 2025-11-14 08:47:44 +00:00
Merge branch 'master' of github.com:3b1b/manim into diffyq
This commit is contained in:
commit
92f4c0c001
8 changed files with 67 additions and 32 deletions
|
|
@ -1,5 +1,4 @@
|
|||
language: python
|
||||
sudo: required # required for Python 3.7 (travis-ci/travis-ci#9069)
|
||||
dist: xenial # required for Python 3.7 (travis-ci/travis-ci#9069)
|
||||
python: "3.7"
|
||||
cache: pip
|
||||
|
|
|
|||
20
README.md
20
README.md
|
|
@ -74,19 +74,29 @@ python3 -m manim example_scenes.py SquareToCircle -pl
|
|||
### Using Docker
|
||||
Since it's a bit tricky to get all the dependencies set up just right, there is a Dockerfile and Compose file provided in this repo as well as [a premade image on Docker Hub](https://hub.docker.com/r/eulertour/manim/tags/). The Dockerfile contains instructions on how to build a manim image, while the Compose file contains instructions on how to run the image.
|
||||
|
||||
In order to do this with the Compose file, you must set the `INPUT_PATH`
|
||||
environment variable to the directory containing your source code and the
|
||||
`OUTPUT_DIRECTORY` environment variable to the directory where you want media
|
||||
to be written.
|
||||
The prebuilt container image has manin repository included.
|
||||
`INPUT_PATH` is where the container looks for scene files. You must set the `INPUT_PATH`
|
||||
environment variable to the absolute path containing your scene file and the
|
||||
`OUTPUT_PATH` environment variable to the directory where you want media to be written.
|
||||
|
||||
1. [Install Docker](https://docs.docker.com)
|
||||
2. [Install Docker Compose](https://docs.docker.com/compose/install/)
|
||||
3. Render an animation
|
||||
```sh
|
||||
INPUT_PATH=/path/to/dir/containing/source/code \
|
||||
OUTPUT_PATH=/path/to/dir/for/media \
|
||||
OUTPUT_PATH=/path/to/output/ \
|
||||
docker-compose run manim example_scenes.py SquareToCircle -l
|
||||
```
|
||||
The command needs to be run as root if your username is not in the docker group.
|
||||
|
||||
You can replace `example.scenes.py` with any relative path from your `INPUT_PATH`.
|
||||
|
||||
<img src=./manim_docker_diagram.png/>
|
||||
|
||||
After running the output will say files ready at `/tmp/output/`, which refers to path inside the container. Your OUTPUT_PATH is bind mounted to this `/tmp/output` so any changes made by the container to `/tmp/output` will be mirrored on your OUTPUT_PATH. `/media/` will be created in `OUTPUT_PATH`.
|
||||
|
||||
`-p` won't work as manim would look for video player in the container system, which it does not have.
|
||||
|
||||
The first time you execute the above command, Docker will pull the image from Docker Hub and cache it. Any subsequent runs until the image is evicted will use the cached image.
|
||||
Note that the image doesn't have any development tools installed and can't preview animations. Its purpose is building and testing only.
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ services:
|
|||
- manim
|
||||
- --media_dir=/tmp/output
|
||||
volumes:
|
||||
- ${INPUT_DIR:?INPUT_DIR environment variable isn't set}:/tmp/input
|
||||
- ${OUTPUT_DIR:?OUTPUT_DIR environment variable isn't set}:/tmp/output
|
||||
- ${INPUT_PATH:?INPUT_PATH environment variable isn't set}:/tmp/input
|
||||
- ${OUTPUT_PATH:?OUTPUT_PATH environment variable isn't set}:/tmp/output
|
||||
working_dir: /tmp/input
|
||||
network_mode: "none"
|
||||
|
|
|
|||
BIN
manim_docker_diagram.png
Normal file
BIN
manim_docker_diagram.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
|
|
@ -116,8 +116,13 @@ def parse_cli():
|
|||
"--media_dir",
|
||||
help="directory to write media",
|
||||
)
|
||||
parser.add_argument(
|
||||
video_group = parser.add_mutually_exclusive_group()
|
||||
video_group.add_argument(
|
||||
"--video_dir",
|
||||
help="directory to write file tree for video",
|
||||
)
|
||||
video_group.add_argument(
|
||||
"--video_output_dir",
|
||||
help="directory to write video",
|
||||
)
|
||||
parser.add_argument(
|
||||
|
|
@ -207,6 +212,7 @@ def get_configuration(args):
|
|||
"leave_progress_bars": args.leave_progress_bars,
|
||||
"media_dir": args.media_dir,
|
||||
"video_dir": args.video_dir,
|
||||
"video_output_dir": args.video_output_dir,
|
||||
"tex_dir": args.tex_dir,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,13 +3,26 @@ import os
|
|||
|
||||
MEDIA_DIR = ""
|
||||
VIDEO_DIR = ""
|
||||
VIDEO_OUTPUT_DIR = ""
|
||||
TEX_DIR = ""
|
||||
|
||||
def initialize_directories(config):
|
||||
global MEDIA_DIR
|
||||
global VIDEO_DIR
|
||||
global VIDEO_OUTPUT_DIR
|
||||
global TEX_DIR
|
||||
if not (config["video_dir"] and config["tex_dir"]):
|
||||
|
||||
video_path_specified = config["video_dir"] or config["video_output_dir"]
|
||||
if not video_path_specified:
|
||||
VIDEO_DIR = os.path.join(MEDIA_DIR, "videos")
|
||||
elif config["video_output_dir"]:
|
||||
VIDEO_OUTPUT_DIR = config["video_output_dir"]
|
||||
else:
|
||||
VIDEO_DIR = config["video_dir"]
|
||||
|
||||
TEX_DIR = config["tex_dir"] or os.path.join(MEDIA_DIR, "Tex")
|
||||
|
||||
if not (video_path_specified and config["tex_dir"]):
|
||||
if config["media_dir"]:
|
||||
MEDIA_DIR = config["media_dir"]
|
||||
else:
|
||||
|
|
@ -26,14 +39,12 @@ def initialize_directories(config):
|
|||
else:
|
||||
if config["media_dir"]:
|
||||
print(
|
||||
"Ignoring --media_dir, since --video_dir and --tex_dir were "
|
||||
"both passed"
|
||||
"Ignoring --media_dir, since both --tex_dir and a video "
|
||||
"directory were both passed"
|
||||
)
|
||||
VIDEO_DIR = config["video_dir"] or os.path.join(MEDIA_DIR, "videos")
|
||||
TEX_DIR = config["tex_dir"] or os.path.join(MEDIA_DIR, "Tex")
|
||||
|
||||
for folder in [VIDEO_DIR, TEX_DIR]:
|
||||
if not os.path.exists(folder):
|
||||
for folder in [VIDEO_DIR, VIDEO_OUTPUT_DIR, TEX_DIR]:
|
||||
if folder != "" and not os.path.exists(folder):
|
||||
os.makedirs(folder)
|
||||
|
||||
TEX_USE_CTEX = False
|
||||
|
|
|
|||
|
|
@ -49,21 +49,30 @@ class SceneFileWriter(object):
|
|||
module_directory = self.output_directory or self.get_default_module_directory()
|
||||
scene_name = self.file_name or self.get_default_scene_name()
|
||||
if self.save_last_frame:
|
||||
if consts.VIDEO_DIR != "":
|
||||
image_dir = guarantee_existence(os.path.join(
|
||||
consts.VIDEO_DIR,
|
||||
module_directory,
|
||||
"images",
|
||||
))
|
||||
else:
|
||||
image_dir = guarantee_existence(os.path.join(
|
||||
consts.VIDEO_OUTPUT_DIR,
|
||||
"images",
|
||||
))
|
||||
self.image_file_path = os.path.join(
|
||||
image_dir,
|
||||
add_extension_if_not_present(scene_name, ".png")
|
||||
)
|
||||
if self.write_to_movie:
|
||||
if consts.VIDEO_DIR != "":
|
||||
movie_dir = guarantee_existence(os.path.join(
|
||||
consts.VIDEO_DIR,
|
||||
module_directory,
|
||||
self.get_resolution_directory(),
|
||||
))
|
||||
else:
|
||||
movie_dir = guarantee_existence(consts.VIDEO_OUTPUT_DIR)
|
||||
self.movie_file_path = os.path.join(
|
||||
movie_dir,
|
||||
add_extension_if_not_present(
|
||||
|
|
|
|||
|
|
@ -44,8 +44,8 @@ def tex_to_dvi(tex_file):
|
|||
"latex",
|
||||
"-interaction=batchmode",
|
||||
"-halt-on-error",
|
||||
"-output-directory=\'{}\'".format(consts.TEX_DIR),
|
||||
"\'{}\'".format(tex_file),
|
||||
"-output-directory=\"{}\"".format(consts.TEX_DIR),
|
||||
"\"{}\"".format(tex_file),
|
||||
">",
|
||||
os.devnull
|
||||
] if not TEX_USE_CTEX else [
|
||||
|
|
@ -53,8 +53,8 @@ def tex_to_dvi(tex_file):
|
|||
"-no-pdf",
|
||||
"-interaction=batchmode",
|
||||
"-halt-on-error",
|
||||
"-output-directory=\'{}\'".format(consts.TEX_DIR),
|
||||
"\'{}\'".format(tex_file),
|
||||
"-output-directory=\"{}\"".format(consts.TEX_DIR),
|
||||
"\"{}\"".format(tex_file),
|
||||
">",
|
||||
os.devnull
|
||||
]
|
||||
|
|
@ -79,12 +79,12 @@ def dvi_to_svg(dvi_file, regen_if_exists=False):
|
|||
if not os.path.exists(result):
|
||||
commands = [
|
||||
"dvisvgm",
|
||||
"\'{}\'".format(dvi_file),
|
||||
"\"{}\"".format(dvi_file),
|
||||
"-n",
|
||||
"-v",
|
||||
"0",
|
||||
"-o",
|
||||
"\'{}\'".format(result),
|
||||
"\"{}\"".format(result),
|
||||
">",
|
||||
os.devnull
|
||||
]
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue