Merge branch 'TonyCrane-package-improve'

This commit is contained in:
Grant Sanderson
2021-02-11 10:54:30 -08:00
30 changed files with 399 additions and 360 deletions

3
.gitignore vendored
View File

@ -145,5 +145,6 @@ dmypy.json
# Custom exclusions: # Custom exclusions:
.DS_Store .DS_Store
# # For manim
/videos /videos
/custom_config.yml

View File

@ -16,7 +16,7 @@ Note, there are two versions of manim. This repository began as a personal proj
Since the fork, this version has evolved to work on top of OpenGL, and allows real-time rendering to an interactive window before scenes are finalized and written to a file. Since the fork, this version has evolved to work on top of OpenGL, and allows real-time rendering to an interactive window before scenes are finalized and written to a file.
## Installation ## Installation
Manim runs on Python 3.8. Manim runs on Python 3.6 or higher (Python 3.8 is recommended).
System requirements are [FFmpeg](https://ffmpeg.org/), [OpenGL](https://www.opengl.org//), [LaTeX](https://www.latex-project.org) (optional, if you want to use LaTeX) System requirements are [FFmpeg](https://ffmpeg.org/), [OpenGL](https://www.opengl.org//), [LaTeX](https://www.latex-project.org) (optional, if you want to use LaTeX)
and [cairo](https://www.cairographics.org/) (optional, if you want to use Text). and [cairo](https://www.cairographics.org/) (optional, if you want to use Text).
@ -28,11 +28,13 @@ For more options, take a look at the [Using manim](#using-manim) sections furthe
If you want to hack on manimlib itself, clone this repository and in that directory execute: If you want to hack on manimlib itself, clone this repository and in that directory execute:
```sh ```sh
# Install python requirements # Install manimgl
pip install -r requirements.txt pip install -e .
# Try it out # Try it out
python manim.py example_scenes.py OpeningManimExample manimgl example_scenes.py OpeningManimExample
# or
manim-render example_scenes.py OpeningManimExample
``` ```
### Mac OSX ### Mac OSX
1. Install FFmpeg, LaTeX, Cairo in terminal using homebrew. 1. Install FFmpeg, LaTeX, Cairo in terminal using homebrew.
@ -44,8 +46,8 @@ python manim.py example_scenes.py OpeningManimExample
```sh ```sh
git clone https://github.com/3b1b/manim.git git clone https://github.com/3b1b/manim.git
cd manim cd manim
pip install -r requirements.txt pip install -e .
python manim.py example_scenes.py OpeningManimExample manimgl example_scenes.py OpeningManimExample
``` ```
### Directly (Windows) ### Directly (Windows)
@ -55,30 +57,22 @@ python manim.py example_scenes.py OpeningManimExample
```sh ```sh
git clone https://github.com/3b1b/manim.git git clone https://github.com/3b1b/manim.git
cd manim cd manim
pip install -r requirements.txt pip install -e .
python manim.py example_scenes.py OpeningManimExample manimgl example_scenes.py OpeningManimExample
``` ```
## Anaconda Install ## Anaconda Install
* Install latex as above. * Install LaTeX as above.
* Create a conda environment using `conda env create -f environment.yml` * Create a conda environment using `conda create -n manim python=3.8`.
* Activate the environment using `conda activate manim`.
* Install manimgl using `pip install -e .`.
### Using `virtualenv` and `virtualenvwrapper`
After installing `virtualenv` and `virtualenvwrapper`
```sh
git clone https://github.com/3b1b/manim.git
mkvirtualenv -a manim -r requirements.txt manim
python -m manim example_scenes.py OpeningManimExample
```
## Using manim ## Using manim
Try running the following: Try running the following:
```sh ```sh
python -m manim example_scenes.py OpeningManimExample manimgl example_scenes.py OpeningManimExample
``` ```
This should pop up a window playing a simple scene. This should pop up a window playing a simple scene.
@ -90,7 +84,7 @@ Some useful flags include:
* `-n <number>` to skip ahead to the `n`'th animation of a scene. * `-n <number>` to skip ahead to the `n`'th animation of a scene.
* `-f` to make the playback window fullscreen * `-f` to make the playback window fullscreen
Take a look at custom_defaults.yml for further configuration. To add your customization, you can either edit this file, or add another file by the same name "custom_defaults.yml" to whatever directory you are running manim from. For example [this is the one](https://github.com/3b1b/videos/blob/master/custom_defaults.yml) for 3blue1brown videos. There you can specify where videos should be output to, where manim should look for image files and sounds you want to read in, and other defaults regarding style and video quality. Take a look at custom_config.yml for further configuration. To add your customization, you can either edit this file, or add another file by the same name "custom_config.yml" to whatever directory you are running manim from. For example [this is the one](https://github.com/3b1b/videos/blob/master/custom_config.yml) for 3blue1brown videos. There you can specify where videos should be output to, where manim should look for image files and sounds you want to read in, and other defaults regarding style and video quality.
Look through the [example scenes](https://3b1b.github.io/manim/getting_started/example_scenes.html) to get a sense of how it is used, and feel free to look through the code behind [3blue1brown videos](https://github.com/3b1b/videos) for a much larger set of example. Note, however, that developments are often made to the library without considering backwards compatibility with those old videos. To run an old project with a guarantee that it will work, you will have to go back to the commit which completed that project. Look through the [example scenes](https://3b1b.github.io/manim/getting_started/example_scenes.html) to get a sense of how it is used, and feel free to look through the code behind [3blue1brown videos](https://github.com/3b1b/videos) for a much larger set of example. Note, however, that developments are often made to the library without considering backwards compatibility with those old videos. To run an old project with a guarantee that it will work, you will have to go back to the commit which completed that project.

View File

@ -1,4 +1,4 @@
custom_default custom_config
============== ==============
``directories`` ``directories``
@ -18,12 +18,13 @@ custom_default
file and saved the last frame, then the final directory structure will be like: file and saved the last frame, then the final directory structure will be like:
.. code-block:: text .. code-block:: text
:emphasize-lines: 8, 10 :emphasize-lines: 9, 11
manim/ manim/
├── manimlib/ ├── manimlib/
│ ├── animation/ │ ├── animation/
│ ├── ... │ ├── ...
│ ├── default_config.yml
│ └── window.py │ └── window.py
├── output/ ├── output/
│ ├── images │ ├── images
@ -31,18 +32,18 @@ custom_default
│ └── videos │ └── videos
│ └── Scene1.mp4 │ └── Scene1.mp4
├── code.py ├── code.py
── custom_default.yml ── custom_config.yml
└── manim.py
But if you set ``mirror_module_path`` to ``True``, the directory structure will be: But if you set ``mirror_module_path`` to ``True``, the directory structure will be:
.. code-block:: text .. code-block:: text
:emphasize-lines: 7 :emphasize-lines: 8
manim/ manim/
├── manimlib/ ├── manimlib/
│ ├── animation/ │ ├── animation/
│ ├── ... │ ├── ...
│ ├── default_config.yml
│ └── window.py │ └── window.py
├── output/ ├── output/
│ └── code/ │ └── code/
@ -51,8 +52,7 @@ custom_default
│ └── videos │ └── videos
│ └── Scene1.mp4 │ └── Scene1.mp4
├── code.py ├── code.py
── custom_default.yml ── custom_config.yml
└── manim.py
- ``raster_images`` - ``raster_images``
The directory for storing raster images to be used in the code (including The directory for storing raster images to be used in the code (including

View File

@ -4,14 +4,16 @@ CLI flags and configuration
Command Line Interface Command Line Interface
---------------------- ----------------------
To run manim, you need to enter the directory at the same level as ``manim.py`` To run manim, you need to enter the directory at the same level as ``manimlib/``
and enter the command in the following format into terminal: and enter the command in the following format into terminal:
.. code-block:: sh .. code-block:: sh
python manim.py <code>.py <Scene> <flags> manimgl <code>.py <Scene> <flags>
# or
manim-render <code>.py <Scene> <flags>
- ``<code>.py`` : The python file you wrote. Needs to be at the same level as ``manim.py``, otherwise you need to use an absolute path or a relative path. - ``<code>.py`` : The python file you wrote. Needs to be at the same level as ``manimlib/``, otherwise you need to use an absolute path or a relative path.
- ``<Scene>`` : The scene you want to render here. If it is not written or written incorrectly, it will list all for you to choose. And if there is only one ``Scene`` in the file, this class will be rendered directly. - ``<Scene>`` : The scene you want to render here. If it is not written or written incorrectly, it will list all for you to choose. And if there is only one ``Scene`` in the file, this class will be rendered directly.
- ``<flags>`` : CLI flags. - ``<flags>`` : CLI flags.
@ -48,6 +50,7 @@ flag abbr function
``--write_all`` ``-a`` Write all the scenes from a file ``--write_all`` ``-a`` Write all the scenes from a file
``--open`` ``-o`` Automatically open the saved file once its done ``--open`` ``-o`` Automatically open the saved file once its done
``--finder`` Show the output file in finder ``--finder`` Show the output file in finder
``--config`` Guide for automatic configuration
``--file_name FILE_NAME`` Name for the movie or image file ``--file_name FILE_NAME`` Name for the movie or image file
``--start_at_animation_number START_AT_ANIMATION_NUMBER`` ``-n`` Start rendering not from the first animation, but from another, specified by its index. If you passin two comma separated values, e.g. "3,6", it will end the rendering at the second value. ``--start_at_animation_number START_AT_ANIMATION_NUMBER`` ``-n`` Start rendering not from the first animation, but from another, specified by its index. If you passin two comma separated values, e.g. "3,6", it will end the rendering at the second value.
``--resolution RESOLUTION`` ``-r`` Resolution, passed as "WxH", e.g. "1920x1080" ``--resolution RESOLUTION`` ``-r`` Resolution, passed as "WxH", e.g. "1920x1080"
@ -57,15 +60,15 @@ flag abbr function
``--video_dir VIDEO_DIR`` directory to write video ``--video_dir VIDEO_DIR`` directory to write video
========================================================== ====== ================================================================================================================================================================================================= ========================================================== ====== =================================================================================================================================================================================================
custom_default custom_config
-------------- --------------
In order to perform more configuration (about directories, etc.) and permanently In order to perform more configuration (about directories, etc.) and permanently
change the default value (you don't have to add flags to the command every time), change the default value (you don't have to add flags to the command every time),
you can modify ``custom_default.yml``. The meaning of each option is in you can modify ``custom_config.yml``. The meaning of each option is in
page :doc:`../documentation/custom_default`. page :doc:`../documentation/custom_config`.
You can also use different ``custom_default.yml`` for different directories, such as You can also use different ``custom_config.yml`` for different directories, such as
following the directory structure: following the directory structure:
.. code-block:: text .. code-block:: text
@ -74,13 +77,13 @@ following the directory structure:
├── manimlib/ ├── manimlib/
│ ├── animation/ │ ├── animation/
│ ├── ... │ ├── ...
│ ├── default_config.yml
│ └── window.py │ └── window.py
├── project/ ├── project/
│ ├── code.py │ ├── code.py
│ └── custom_default.yml │ └── custom_config.yml
── custom_default.yml ── custom_config.yml
└── manim.py
When you enter the ``project/`` folder and run ``python ../manim.py code.py <Scene>``, When you enter the ``project/`` folder and run ``manimgl code.py <Scene>``,
it will overwrite ``manim/custom_default.yml`` with ``custom_default.yml`` it will overwrite ``manim/custom_config.yml`` with ``custom_config.yml``
in the ``project`` folder. in the ``project`` folder.

View File

@ -11,7 +11,7 @@ InteractiveDevlopment
.. manim-example:: InteractiveDevlopment .. manim-example:: InteractiveDevlopment
:media: ../_static/example_scenes/InteractiveDevlopment.mp4 :media: ../_static/example_scenes/InteractiveDevlopment.mp4
from manimlib.imports import * from manimlib import *
class InteractiveDevlopment(Scene): class InteractiveDevlopment(Scene):
def construct(self): def construct(self):
@ -572,7 +572,7 @@ SurfaceExample
# be interpreted as the side towards the light, and away from # be interpreted as the side towards the light, and away from
# the light. These can be either urls, or paths to a local file # the light. These can be either urls, or paths to a local file
# in whatever you've set as the image directory in # in whatever you've set as the image directory in
# the custom_defaults.yml file # the custom_config.yml file
# day_texture = "EarthTextureMap" # day_texture = "EarthTextureMap"
# night_texture = "NightEarthTextureMap" # night_texture = "NightEarthTextureMap"

View File

@ -19,10 +19,12 @@ that directory execute:
.. code-block:: sh .. code-block:: sh
# Install python requirements # Install python requirements
pip install -r requirements.txt pip install -e .
# Try it out # Try it out
python -m manim example_scenes.py OpeningManimExample manimgl example_scenes.py OpeningManimExample
# or
manim-render example_scenes.py OpeningManimExample
If you run the above command and no error message appears, If you run the above command and no error message appears,
then you have successfully installed all the environments required by manim. then you have successfully installed all the environments required by manim.
@ -40,8 +42,8 @@ Directly (Windows)
git clone https://github.com/3b1b/manim.git git clone https://github.com/3b1b/manim.git
cd manim cd manim
pip install -r requirements.txt pip install -e .
python manim.py example_scenes.py OpeningManimExample manimgl example_scenes.py OpeningManimExample
For Anaconda For Anaconda
------------ ------------
@ -53,15 +55,6 @@ For Anaconda
git clone https://github.com/3b1b/manim.git git clone https://github.com/3b1b/manim.git
cd manim cd manim
conda env create -f environment.yml conda create -n manim python=3.8
conda activate manim
Using virtualenv and virtualenvwrapper pip install -e .
--------------------------------------
After installing ``virtualenv`` and ``virtualenvwrapper``
.. code-block:: sh
git clone https://github.com/3b1b/manim.git
mkvirtualenv -a manim -r requirements.txt manim
python -m manim example_scenes.py OpeningManimExample

View File

@ -14,9 +14,9 @@ directory structure:
├── manimlib/ ├── manimlib/
│ ├── animation/ │ ├── animation/
│ ├── ... │ ├── ...
│ ├── default_config.yml
│ └── window.py │ └── window.py
├── custom_default.yml ├── custom_config.yml
├── manim.py
└── start.py └── start.py
And paste the following code (I will explain the function of each line in detail later): And paste the following code (I will explain the function of each line in detail later):
@ -24,7 +24,7 @@ And paste the following code (I will explain the function of each line in detail
.. code-block:: python .. code-block:: python
:linenos: :linenos:
from manimlib.imports import * from manimlib import *
class SquareToCircle(Scene): class SquareToCircle(Scene):
def construct(self): def construct(self):
@ -38,7 +38,7 @@ And run this command:
.. code-block:: sh .. code-block:: sh
python manim.py start.py SquareToCircle manimgl start.py SquareToCircle
A window will pop up on the screen. And then you can : A window will pop up on the screen. And then you can :
@ -53,7 +53,7 @@ Run this command again:
.. code-block:: sh .. code-block:: sh
python manim.py start.py SquareToCircle -os manimgl start.py SquareToCircle -os
At this time, no window will pop up. When the program is finished, this rendered At this time, no window will pop up. When the program is finished, this rendered
image will be automatically opened (saved in the subdirectory ``images/`` of the same image will be automatically opened (saved in the subdirectory ``images/`` of the same
@ -70,9 +70,15 @@ Next, let's take a detailed look at what each row does.
**Line 1**: **Line 1**:
.. code-block:: python .. code-block:: python
<<<<<<< HEAD
from manimlib.imports import * from manimlib.imports import *
=======
from manimlib import *
>>>>>>> TonyCrane-package-improve
This will import all the classes that may be used when using manim. This will import all the classes that may be used when using manim.
**Line 3**: **Line 3**:
@ -129,7 +135,7 @@ Let's change some codes and add some animations to make videos instead of just p
.. code-block:: python .. code-block:: python
:linenos: :linenos:
from manimlib.imports import * from manimlib import *
class SquareToCircle(Scene): class SquareToCircle(Scene):
def construct(self): def construct(self):
@ -147,14 +153,14 @@ Run this command this time:
.. code-block:: sh .. code-block:: sh
python manim.py start.py SquareToCircle manimgl start.py SquareToCircle
The pop-up window will play animations of drawing a square and transforming The pop-up window will play animations of drawing a square and transforming
it into a circle. If you want to save this video, run: it into a circle. If you want to save this video, run:
.. code-block:: sh .. code-block:: sh
python manim.py start.py SquareToCircle -ow manimgl start.py SquareToCircle -o
This time there will be no pop-up window, but the video file (saved in the subdirectory This time there will be no pop-up window, but the video file (saved in the subdirectory
``videos/`` of the same level directory of ``start.py`` by default) will be automatically ``videos/`` of the same level directory of ``start.py`` by default) will be automatically
@ -209,7 +215,11 @@ at the end of the code to enable interaction:
self.embed() self.embed()
<<<<<<< HEAD
Then run ``python manim.py start.py SquareToCircle``. Then run ``python manim.py start.py SquareToCircle``.
=======
Then run ``manimgl start.py SquareToCircle``.
>>>>>>> TonyCrane-package-improve
After the previous animation is executed, the ipython terminal will be opened on After the previous animation is executed, the ipython terminal will be opened on
the command line. After that, you can continue to write code in it, and the statement the command line. After that, you can continue to write code in it, and the statement
@ -245,7 +255,7 @@ empty scene containing only ``self.embed()``, you can directly run the following
.. code-block:: sh .. code-block:: sh
python manim.py manimgl
You succeeded! You succeeded!
-------------- --------------

View File

@ -12,14 +12,13 @@ Below is the directory structure of manim:
.. code-block:: text .. code-block:: text
├── manim.py # Manim command entry manimlib/ # manim library
├── custom_default.yml # Default configuration ├── __init__.py
── manimlib/ # manim library ── __main__.py
├── __init__.py # run from here ├── default_config.yml # Default configuration file
├── config.py # Process CLI flags ├── config.py # Process CLI flags
├── constants.py # Defined some constants ├── constants.py # Defined some constants
├── extract_scene.py # Extract and run the scene ├── extract_scene.py # Extract and run the scene
├── imports.py # Import all required files in manimlib
├── shader_wrapper.py # Shaders' Wrapper for convenient control ├── shader_wrapper.py # Shaders' Wrapper for convenient control
├── window.py # Playback window ├── window.py # Playback window
├── tex_templates/ # Templates preset for LaTeX ├── tex_templates/ # Templates preset for LaTeX
@ -31,8 +30,6 @@ Below is the directory structure of manim:
│ ├── scene_file_writer.py # Used to write scene to video file │ ├── scene_file_writer.py # Used to write scene to video file
│ ├── scene.py # The basic Scene class │ ├── scene.py # The basic Scene class
│ ├── three_d_scene.py # Three-dimensional scene │ ├── three_d_scene.py # Three-dimensional scene
│ ├── graph_scene.py # GraphScene (with coordinate axis)
│ ├── reconfigurable_scene.py
│ ├── sample_space_scene.py # Probability related sample space scene │ ├── sample_space_scene.py # Probability related sample space scene
│ └── vector_space_scene.py # Vector field scene │ └── vector_space_scene.py # Vector field scene
├── animation/ ├── animation/
@ -100,11 +97,12 @@ Below is the directory structure of manim:
├── bezier.py # For bezier curve ├── bezier.py # For bezier curve
├── color.py # For color ├── color.py # For color
├── config_ops.py # Process CONFIG ├── config_ops.py # Process CONFIG
├── customization.py # Read from custom_default.yml ├── customization.py # Read from custom_config.yml
├── debug.py # Utilities for debugging in program ├── debug.py # Utilities for debugging in program
├── family_ops.py # Process family members ├── family_ops.py # Process family members
├── file_ops.py # Process files and directories ├── file_ops.py # Process files and directories
├── images.py # Read image ├── images.py # Read image
├── init_config.py # Configuration guide
├── iterables.py # Functions related to list/dictionary processing ├── iterables.py # Functions related to list/dictionary processing
├── paths.py # Curve path ├── paths.py # Curve path
├── rate_functions.py # Some defined rate_functions ├── rate_functions.py # Some defined rate_functions

View File

@ -25,7 +25,7 @@ And here is a Chinese version of this documentation: https://manim.ml/shaders
:caption: Documentation :caption: Documentation
documentation/constants documentation/constants
documentation/custom_default documentation/custom_config
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 2

View File

@ -1,29 +0,0 @@
name: manim_shaders
channels:
- defaults
- conda-forge
dependencies:
- python=3.7
- pip
- pip:
- pyreadline
- matplotlib
- mapbox-earcut
- moderngl_window
- screeninfo
- argparse
- colour
- numpy
- Pillow
- progressbar
- scipy
- sympy
- tqdm
- moderngl
- pydub
- pyyaml
- validators
- ipython
- PyOpenGL
- pycairo

View File

@ -1,4 +1,5 @@
from manimlib.imports import * from manimlib import *
import numpy as np
# To watch one of these scenes, run the following: # To watch one of these scenes, run the following:
# python -m manim example_scenes.py SquareToCircle # python -m manim example_scenes.py SquareToCircle
@ -510,7 +511,7 @@ class SurfaceExample(Scene):
# be interpreted as the side towards the light, and away from # be interpreted as the side towards the light, and away from
# the light. These can be either urls, or paths to a local file # the light. These can be either urls, or paths to a local file
# in whatever you've set as the image directory in # in whatever you've set as the image directory in
# the custom_defaults.yml file # the custom_config.yml file
# day_texture = "EarthTextureMap" # day_texture = "EarthTextureMap"
# night_texture = "NightEarthTextureMap" # night_texture = "NightEarthTextureMap"

View File

@ -1,5 +0,0 @@
#!/usr/bin/env python
import manimlib
if __name__ == "__main__":
manimlib.main()

View File

@ -1,12 +1,72 @@
#!/usr/bin/env python from manimlib.constants import *
import manimlib.config
import manimlib.extract_scene
from manimlib.animation.animation import *
from manimlib.animation.composition import *
from manimlib.animation.creation import *
from manimlib.animation.fading import *
from manimlib.animation.growing import *
from manimlib.animation.indication import *
from manimlib.animation.movement import *
from manimlib.animation.numbers import *
from manimlib.animation.rotation import *
from manimlib.animation.specialized import *
from manimlib.animation.transform import *
from manimlib.animation.transform_matching_parts import *
from manimlib.animation.update import *
def main(): from manimlib.camera.camera import *
args = manimlib.config.parse_cli()
config = manimlib.config.get_configuration(args)
scenes = manimlib.extract_scene.main(config)
for scene in scenes: from manimlib.mobject.coordinate_systems import *
scene.run() from manimlib.mobject.changing import *
from manimlib.mobject.frame import *
from manimlib.mobject.functions import *
from manimlib.mobject.geometry import *
from manimlib.mobject.matrix import *
from manimlib.mobject.mobject import *
from manimlib.mobject.number_line import *
from manimlib.mobject.numbers import *
from manimlib.mobject.probability import *
from manimlib.mobject.shape_matchers import *
from manimlib.mobject.svg.brace import *
from manimlib.mobject.svg.drawings import *
from manimlib.mobject.svg.svg_mobject import *
from manimlib.mobject.svg.tex_mobject import *
from manimlib.mobject.svg.text_mobject import *
from manimlib.mobject.three_dimensions import *
from manimlib.mobject.types.image_mobject import *
from manimlib.mobject.types.point_cloud_mobject import *
from manimlib.mobject.types.surface import *
from manimlib.mobject.types.vectorized_mobject import *
from manimlib.mobject.types.dot_cloud import *
from manimlib.mobject.mobject_update_utils import *
from manimlib.mobject.value_tracker import *
from manimlib.mobject.vector_field import *
from manimlib.once_useful_constructs.arithmetic import *
from manimlib.once_useful_constructs.combinatorics import *
from manimlib.once_useful_constructs.complex_transformation_scene import *
from manimlib.once_useful_constructs.counting import *
from manimlib.once_useful_constructs.fractals import *
from manimlib.once_useful_constructs.graph_theory import *
from manimlib.once_useful_constructs.light import *
from manimlib.scene.scene import *
from manimlib.scene.sample_space_scene import *
from manimlib.scene.three_d_scene import *
from manimlib.scene.vector_space_scene import *
from manimlib.utils.bezier import *
from manimlib.utils.color import *
from manimlib.utils.config_ops import *
from manimlib.utils.customization import *
from manimlib.utils.debug import *
from manimlib.utils.directories import *
from manimlib.utils.images import *
from manimlib.utils.iterables import *
from manimlib.utils.file_ops import *
from manimlib.utils.paths import *
from manimlib.utils.rate_functions import *
from manimlib.utils.simple_functions import *
from manimlib.utils.sounds import *
from manimlib.utils.space_ops import *
from manimlib.utils.strings import *

17
manimlib/__main__.py Normal file
View File

@ -0,0 +1,17 @@
#!/usr/bin/env python
import manimlib.config
import manimlib.extract_scene
import manimlib.utils.init_config
def main():
args = manimlib.config.parse_cli()
if args.config:
manimlib.utils.init_config.init_customization()
else:
config = manimlib.config.get_configuration(args)
scenes = manimlib.extract_scene.main(config)
for scene in scenes:
scene.run()

View File

View File

View File

@ -8,6 +8,7 @@ import yaml
from screeninfo import get_monitors from screeninfo import get_monitors
from manimlib.utils.config_ops import merge_dicts_recursively from manimlib.utils.config_ops import merge_dicts_recursively
from manimlib.utils.init_config import init_customization
def parse_cli(): def parse_cli():
@ -94,6 +95,11 @@ def parse_cli():
action="store_true", action="store_true",
help="Show the output file in finder", help="Show the output file in finder",
) )
parser.add_argument(
"--config",
action="store_true",
help="Guide for automatic configuration",
)
parser.add_argument( parser.add_argument(
"--file_name", "--file_name",
help="Name for the movie or image file", help="Name for the movie or image file",
@ -150,28 +156,40 @@ def get_module(file_name):
return module return module
def get_custom_defaults(): def get_custom_config():
manim_defaults_file = os.path.join(get_manim_dir(), "manimlib", "defaults.yml") filename = "custom_config.yml"
with open(manim_defaults_file, "r") as file: global_defaults_file = os.path.join(get_manim_dir(), "manimlib", "default_config.yml")
custom_defaults = yaml.safe_load(file)
if os.path.exists(global_defaults_file):
with open(global_defaults_file, "r") as file:
config = yaml.safe_load(file)
# See if there's a custom_defaults file in current directory,
# and if so, it further updates the defaults based on it.
filename = "custom_defaults.yml"
if os.path.exists(filename): if os.path.exists(filename):
with open(filename, "r") as file: with open(filename, "r") as file:
local_defaults = yaml.safe_load(file) local_defaults = yaml.safe_load(file)
if local_defaults: if local_defaults:
custom_defaults = merge_dicts_recursively( config = merge_dicts_recursively(
custom_defaults, config,
local_defaults, local_defaults,
) )
else:
with open(filename, "r") as file:
config = yaml.safe_load(file)
return custom_defaults return config
def get_configuration(args): def get_configuration(args):
custom_defaults = get_custom_defaults() local_config_file = "custom_config.yml"
global_defaults_file = os.path.join(get_manim_dir(), "manimlib", "default_config.yml")
if not (os.path.exists(global_defaults_file) or os.path.exists(local_config_file)):
print("There is no configuration file detected. Initial configuration:\n")
init_customization()
elif not os.path.exists(local_config_file):
print(f"""Warning: Using the default configuration file, which you can modify in {global_defaults_file}
If you want to create a local configuration file, you can create a file named {local_config_file}, or run manimgl --config
""")
custom_config = get_custom_config()
write_file = any([args.write_file, args.open, args.finder]) write_file = any([args.write_file, args.open, args.finder])
if args.transparent: if args.transparent:
@ -183,14 +201,14 @@ def get_configuration(args):
file_writer_config = { file_writer_config = {
"write_to_movie": not args.skip_animations and write_file, "write_to_movie": not args.skip_animations and write_file,
"break_into_partial_movies": custom_defaults["break_into_partial_movies"], "break_into_partial_movies": custom_config["break_into_partial_movies"],
"save_last_frame": args.skip_animations and write_file, "save_last_frame": args.skip_animations and write_file,
"save_pngs": args.save_pngs, "save_pngs": args.save_pngs,
# If -t is passed in (for transparent), this will be RGBA # If -t is passed in (for transparent), this will be RGBA
"png_mode": "RGBA" if args.transparent else "RGB", "png_mode": "RGBA" if args.transparent else "RGB",
"movie_file_extension": file_ext, "movie_file_extension": file_ext,
"mirror_module_path": custom_defaults["directories"]["mirror_module_path"], "mirror_module_path": custom_config["directories"]["mirror_module_path"],
"output_directory": args.video_dir or custom_defaults["directories"]["output"], "output_directory": args.video_dir or custom_config["directories"]["output"],
"file_name": args.file_name, "file_name": args.file_name,
"input_file_path": args.file or "", "input_file_path": args.file or "",
"open_file_upon_completion": args.open, "open_file_upon_completion": args.open,
@ -212,11 +230,11 @@ def get_configuration(args):
} }
# Camera configuration # Camera configuration
config["camera_config"] = get_camera_configuration(args, custom_defaults) config["camera_config"] = get_camera_configuration(args, custom_config)
# Default to making window half the screen size # Default to making window half the screen size
# but make it full screen if -f is passed in # but make it full screen if -f is passed in
monitor = get_monitors()[custom_defaults["window_monitor"]] monitor = get_monitors()[custom_config["window_monitor"]]
window_width = monitor.width window_width = monitor.width
if not args.full_screen: if not args.full_screen:
window_width //= 2 window_width //= 2
@ -242,9 +260,9 @@ def get_configuration(args):
return config return config
def get_camera_configuration(args, custom_defaults): def get_camera_configuration(args, custom_config):
camera_config = {} camera_config = {}
camera_qualities = get_custom_defaults()["camera_qualities"] camera_qualities = get_custom_config()["camera_qualities"]
if args.low_quality: if args.low_quality:
quality = camera_qualities["low"] quality = camera_qualities["low"]
elif args.medium_quality: elif args.medium_quality:
@ -272,7 +290,7 @@ def get_camera_configuration(args, custom_defaults):
}) })
try: try:
bg_color = args.color or custom_defaults["style"]["background_color"] bg_color = args.color or custom_config["style"]["background_color"]
camera_config["background_color"] = colour.Color(bg_color) camera_config["background_color"] = colour.Color(bg_color)
except AttributeError as err: except AttributeError as err:
print("Please use a valid color") print("Please use a valid color")

View File

@ -21,11 +21,11 @@ tex:
template_file: "tex_template.tex" template_file: "tex_template.tex"
intermediate_filetype: "dvi" intermediate_filetype: "dvi"
text_to_replace: "[tex_expression]" text_to_replace: "[tex_expression]"
# # For ctex, use the following configuration # For ctex, use the following configuration
# executable: "xelatex -no-pdf" # executable: "xelatex -no-pdf"
# template_file: "ctex_template.tex" # template_file: "ctex_template.tex"
# intermediate_filetype: "xdv" # intermediate_filetype: "xdv"
universal_import_line: "from manimlib.imports import *" universal_import_line: "from manimlib import *"
style: style:
font: "Consolas" font: "Consolas"
background_color: "#333333" background_color: "#333333"

View File

@ -3,12 +3,12 @@ import sys
import logging import logging
from manimlib.scene.scene import Scene from manimlib.scene.scene import Scene
from manimlib.config import get_custom_defaults from manimlib.config import get_custom_config
class BlankScene(Scene): class BlankScene(Scene):
def construct(self): def construct(self):
exec(get_custom_defaults()["universal_import_line"]) exec(get_custom_config()["universal_import_line"])
self.embed() self.embed()

View File

@ -1,106 +0,0 @@
"""
I won't pretend like this is best practice, but in creating animations for a video,
it can be very nice to simply have all of the Mobjects, Animations, Scenes, etc.
of manim available without having to worry about what namespace they come from.
Rather than having a large pile of "from <module> import *" at the top of every such
script, the intent of this file is to make it so that one can just include
"from manimlib.imports import *". The effects of adding more modules
or refactoring the library on current or older scene scripts should be entirely
addressible by changing this file.
Note: One should NOT import from this file for main library code, it is meant only
as a convenience for scripts creating scenes for videos.
"""
from manimlib.constants import *
from manimlib.animation.animation import *
from manimlib.animation.composition import *
from manimlib.animation.creation import *
from manimlib.animation.fading import *
from manimlib.animation.growing import *
from manimlib.animation.indication import *
from manimlib.animation.movement import *
from manimlib.animation.numbers import *
from manimlib.animation.rotation import *
from manimlib.animation.specialized import *
from manimlib.animation.transform import *
from manimlib.animation.transform_matching_parts import *
from manimlib.animation.update import *
from manimlib.camera.camera import *
from manimlib.mobject.coordinate_systems import *
from manimlib.mobject.changing import *
from manimlib.mobject.frame import *
from manimlib.mobject.functions import *
from manimlib.mobject.geometry import *
from manimlib.mobject.matrix import *
from manimlib.mobject.mobject import *
from manimlib.mobject.number_line import *
from manimlib.mobject.numbers import *
from manimlib.mobject.probability import *
from manimlib.mobject.shape_matchers import *
from manimlib.mobject.interactive import *
from manimlib.mobject.svg.brace import *
from manimlib.mobject.svg.drawings import *
from manimlib.mobject.svg.svg_mobject import *
from manimlib.mobject.svg.tex_mobject import *
from manimlib.mobject.svg.text_mobject import *
from manimlib.mobject.three_dimensions import *
from manimlib.mobject.types.image_mobject import *
from manimlib.mobject.types.point_cloud_mobject import *
from manimlib.mobject.types.surface import *
from manimlib.mobject.types.vectorized_mobject import *
from manimlib.mobject.types.dot_cloud import *
from manimlib.mobject.mobject_update_utils import *
from manimlib.mobject.value_tracker import *
from manimlib.mobject.vector_field import *
from manimlib.once_useful_constructs.arithmetic import *
from manimlib.once_useful_constructs.combinatorics import *
from manimlib.once_useful_constructs.complex_transformation_scene import *
from manimlib.once_useful_constructs.counting import *
from manimlib.once_useful_constructs.fractals import *
from manimlib.once_useful_constructs.graph_theory import *
from manimlib.once_useful_constructs.light import *
from manimlib.scene.scene import *
from manimlib.scene.sample_space_scene import *
from manimlib.scene.three_d_scene import *
from manimlib.scene.vector_space_scene import *
from manimlib.utils.bezier import *
from manimlib.utils.color import *
from manimlib.utils.config_ops import *
from manimlib.utils.customization import *
from manimlib.utils.debug import *
from manimlib.utils.directories import *
from manimlib.utils.images import *
from manimlib.utils.iterables import *
from manimlib.utils.file_ops import *
from manimlib.utils.paths import *
from manimlib.utils.rate_functions import *
from manimlib.utils.simple_functions import *
from manimlib.utils.sounds import *
from manimlib.utils.space_ops import *
from manimlib.utils.strings import *
# Non manim libraries that are also nice to have without thinking
import inspect
import itertools as it
import numpy as np
import operator as op
import os
import random
import re
import string
import sys
import math
import sympy
from PIL import Image
from colour import Color

View File

View File

View File

View File

View File

View File

@ -1,7 +1,7 @@
import os import os
import tempfile import tempfile
from manimlib.config import get_custom_defaults from manimlib.config import get_custom_config
from manimlib.config import get_manim_dir from manimlib.config import get_manim_dir
CUSTOMIZATION = {} CUSTOMIZATION = {}
@ -9,7 +9,7 @@ CUSTOMIZATION = {}
def get_customization(): def get_customization():
if not CUSTOMIZATION: if not CUSTOMIZATION:
CUSTOMIZATION.update(get_custom_defaults()) CUSTOMIZATION.update(get_custom_config())
directories = CUSTOMIZATION["directories"] directories = CUSTOMIZATION["directories"]
# Unless user has specified otherwise, use the system default temp # Unless user has specified otherwise, use the system default temp
# directory for storing tex files, mobject_data, etc. # directory for storing tex files, mobject_data, etc.

View File

@ -0,0 +1,84 @@
import yaml
import os
def init_customization():
configuration = {
"directories": {
"mirror_module_path": False,
"output": "",
"raster_images": "",
"vector_images": "",
"sounds": "",
"temporary_storage": "",
},
"tex": {
"executable": "",
"template_file": "",
"intermediate_filetype": "",
"text_to_replace": "[tex_expression]",
},
"universal_import_line": "from manimlib import *",
"style": {
"font": "Consolas",
"background_color": "",
},
"window_position": "UR",
"break_into_partial_movies": False,
"camera_qualities": {
"low": {
"resolution": "854x480",
"frame_rate": 15,
},
"medium": {
"resolution": "1280x720",
"frame_rate": 30,
},
"high": {
"resolution": "1920x1080",
"frame_rate": 60,
},
"ultra_high": {
"resolution": "3840x2160",
"frame_rate": 60,
},
"default_quality": "",
}
}
scope = input(" Please select the scope of the configuration [global/local]: ")
if scope == "global":
from manimlib.config import get_manim_dir
file_name = os.path.join(get_manim_dir(), "manimlib", "default_config.yml")
else:
file_name = os.path.join(os.getcwd(), "custom_config.yml")
print("\n directories:")
configuration["directories"]["output"] = input(" [1/8] Where should manim output video and image files place: ")
configuration["directories"]["raster_images"] = input(" [2/8] Which folder should manim find raster images (.jpg .png .gif) in (optional): ")
configuration["directories"]["vector_images"] = input(" [3/8] Which folder should manim find vector images (.svg .xdv) in (optional): ")
configuration["directories"]["sounds"] = input(" [4/8] Which folder should manim find sound files (.mp3 .wav) in (optional): ")
configuration["directories"]["temporary_storage"] = input(" [5/8] Which folder should manim storage temporary files: ")
print("\n tex:")
tex = input(" [6/8] Which executable file to use to compile [latex/xelatex]: ")
if tex == "latex":
configuration["tex"]["executable"] = "latex"
configuration["tex"]["template_file"] = "tex_template.tex"
configuration["tex"]["intermediate_filetype"] = "dvi"
else:
configuration["tex"]["executable"] = "xelatex -no-pdf"
configuration["tex"]["template_file"] = "ctex_template.tex"
configuration["tex"]["intermediate_filetype"] = "xdv"
print("\n style:")
configuration["style"]["background_color"] = input(" [7/8] Which background color do you want (hex code): ")
print("\n camera_qualities:")
print(" Four defined qualities: low: 480p15 medium: 720p30 high: 1080p60 ultra_high: 2160p60")
configuration["camera_qualities"]["default_quality"] = input(" [8/8] Which one to choose as the default rendering quality [low/medium/high/ultra_high]: ")
with open(file_name, 'w', encoding="utf_8") as file:
yaml.dump(configuration, file)
print(f"\nYou have set up a {scope} configuration file")
print(f"You can manually modify it again in: {file_name}\n")

View File

@ -6,7 +6,7 @@ from contextlib import contextmanager
from manimlib.utils.directories import get_tex_dir from manimlib.utils.directories import get_tex_dir
from manimlib.config import get_manim_dir from manimlib.config import get_manim_dir
from manimlib.config import get_custom_defaults from manimlib.config import get_custom_config
SAVED_TEX_CONFIG = {} SAVED_TEX_CONFIG = {}
@ -25,8 +25,8 @@ def get_tex_config():
""" """
# Only load once, then save thereafter # Only load once, then save thereafter
if not SAVED_TEX_CONFIG: if not SAVED_TEX_CONFIG:
custom_defaults = get_custom_defaults() custom_config = get_custom_config()
SAVED_TEX_CONFIG.update(custom_defaults["tex"]) SAVED_TEX_CONFIG.update(custom_config["tex"])
# Read in template file # Read in template file
template_filename = os.path.join( template_filename = os.path.join(
get_manim_dir(), "manimlib", "tex_templates", get_manim_dir(), "manimlib", "tex_templates",

View File

@ -19,5 +19,5 @@ extra_files = requirements.txt
[entry_points] [entry_points]
console_scripts = console_scripts =
manimgl = manimlib:main manimgl = manimlib.__main__:main
manim-render = manimlib:main manim-render = manimlib.__main__:main