Skip to content

Commit 299e756

Browse files
authored
Merge branch 'master' into issue-511
2 parents 24045f7 + fa0a82c commit 299e756

File tree

9 files changed

+191
-105
lines changed

9 files changed

+191
-105
lines changed

docs/source/changelog.rst

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ New Features
1919
Command line
2020
^^^^^^^^^^^^
2121

22-
#. Add 4k rendering option with the :code:`-k` option
23-
#. High quality rendering has gotten its own short argument (:code:`-e`)
2422
#. Output of 'manim --help' has been improved
2523
#. Implement logging with the :code:`rich` library and a :code:`logger` object instead of plain ol` prints
2624
#. Added a flag :code:`--dry_run`, which doesn’t write any media
@@ -33,6 +31,7 @@ Command line
3331
#. Added a :code:`--verbose` flag
3432
#. You can save the logs to a file by using :code:`--log_to_file`
3533
#. Add experimental javascript rendering with :code:`--use_js_renderer`
34+
#. Add :code:`-q/--quality [k|h|m|l]` flag and removed :code:`-m/-l` flags.
3635
#. Removed :code:`--sound` flag
3736

3837

docs/source/tutorials/configuration.rst

Lines changed: 67 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Usually, manim is ran from the command line by executing
1717
1818
This asks manim to search for a Scene class called :code:`SceneName` inside the
1919
file <file.py> and render it. One can also specify the render quality by using
20-
the flags :code:`-l`, :code:`-m`, :code:`-e`, or :code:`-k`, for low, medium,
20+
the flags :code:`-ql`, :code:`-qm`, :code:`-qh`, or :code:`-qk`, for low, medium,
2121
high, and 4k quality, respectively.
2222

2323
.. code-block:: bash
@@ -46,88 +46,78 @@ The output looks as follows.
4646
.. testoutput::
4747
:options: -ELLIPSIS, +NORMALIZE_WHITESPACE
4848

49-
usage: manim [-h] [-o OUTPUT_FILE] [-p] [-f] [--leave_progress_bars]
50-
[-a] [-w] [-s] [-g] [-i] [--disable_caching] [--flush_cache]
51-
[--log_to_file] [-c BACKGROUND_COLOR]
52-
[--background_opacity BACKGROUND_OPACITY] [--media_dir MEDIA_DIR]
53-
[--log_dir LOG_DIR] [--tex_template TEX_TEMPLATE] [--dry_run]
54-
[-t] [-l] [-m] [-e] [-k] [-r RESOLUTION]
55-
[-n FROM_ANIMATION_NUMBER] [--config_file CONFIG_FILE]
56-
[--custom_folders] [-v {DEBUG,INFO,WARNING,ERROR,CRITICAL}]
57-
[--progress_bar True/False]
58-
{cfg} ... file [scene_names [scene_names ...]]
59-
60-
Animation engine for explanatory math videos
61-
62-
positional arguments:
63-
{cfg}
64-
file path to file holding the python code for the scene
65-
scene_names Name of the Scene class you want to see
66-
67-
optional arguments:
68-
-h, --help show this help message and exit
69-
-o OUTPUT_FILE, --output_file OUTPUT_FILE
70-
Specify the name of the output file, if it should be
71-
different from the scene class name
72-
-p, --preview Automatically open the saved file once its done
73-
-f, --show_in_file_browser
74-
Show the output file in the File Browser
75-
--leave_progress_bars
76-
Leave progress bars displayed in terminal
77-
-a, --write_all Write all the scenes from a file
78-
-w, --write_to_movie Render the scene as a movie file (this is on by
79-
default)
80-
-s, --save_last_frame
81-
Save the last frame only (no movie file is generated)
82-
-g, --save_pngs Save each frame as a png
83-
-i, --save_as_gif Save the video as gif
84-
--disable_caching Disable caching (will generate partial-movie-files
85-
anyway)
86-
--flush_cache Remove all cached partial-movie-files
87-
--log_to_file Log terminal output to file
88-
-c BACKGROUND_COLOR, --background_color BACKGROUND_COLOR
89-
Specify background color
90-
--background_opacity BACKGROUND_OPACITY
91-
Specify background opacity
92-
--media_dir MEDIA_DIR
93-
Directory to store media (including video files)
94-
--log_dir LOG_DIR Directory to store log files
95-
--tex_template TEX_TEMPLATE
96-
Specify a custom TeX template file
97-
--dry_run Do a dry run (render scenes but generate no output
98-
files)
99-
-t, --transparent Render a scene with an alpha channel
100-
-l, --low_quality Render at low quality
101-
-m, --medium_quality Render at medium quality
102-
-e, --high_quality Render at high quality
103-
-k, --fourk_quality Render at 4K quality
104-
-r RESOLUTION, --resolution RESOLUTION
105-
Resolution, passed as "height,width". Overrides the
106-
-l, -m, -e, and -k flags, if present
107-
-n FROM_ANIMATION_NUMBER, --from_animation_number FROM_ANIMATION_NUMBER
108-
Start rendering at the specified animation index,
109-
instead of the first animation. If you pass in two
110-
comma separated values, e.g. '3,6', it will end the
111-
rendering at the second value
112-
--config_file CONFIG_FILE
113-
Specify the configuration file
114-
--custom_folders Use the folders defined in the [custom_folders]
115-
section of the config file to define the output folder
116-
structure
117-
-v {DEBUG,INFO,WARNING,ERROR,CRITICAL}, --verbosity {DEBUG,INFO,WARNING,ERROR,CRITICAL}
118-
Verbosity level. Also changes the ffmpeg log level
119-
unless the latter is specified in the config
120-
--progress_bar True/False
121-
Display the progress bar
122-
123-
Made with <3 by the manim community devs
49+
usage: manim [-h] [-o OUTPUT_FILE] [-p] [-f] [--leave_progress_bars] [-a] [-w] [-s] [-g] [-i] [--disable_caching] [--flush_cache] [--log_to_file] [-c BACKGROUND_COLOR]
50+
[--background_opacity BACKGROUND_OPACITY] [--media_dir MEDIA_DIR] [--log_dir LOG_DIR] [--tex_template TEX_TEMPLATE] [--dry_run] [-t] [-q {k,h,m,l}] [--low_quality] [--medium_quality]
51+
[--high_quality] [--fourk_quality] [-r RESOLUTION] [-n FROM_ANIMATION_NUMBER] [--use_js_renderer] [--js_renderer_path JS_RENDERER_PATH] [--config_file CONFIG_FILE] [--custom_folders]
52+
[-v {DEBUG,INFO,WARNING,ERROR,CRITICAL}] [--progress_bar True/False]
53+
{cfg} ... file [scene_names [scene_names ...]]
54+
55+
Animation engine for explanatory math videos
56+
57+
positional arguments:
58+
{cfg}
59+
file path to file holding the python code for the scene
60+
scene_names Name of the Scene class you want to see
61+
62+
optional arguments:
63+
-h, --help show this help message and exit
64+
-o OUTPUT_FILE, --output_file OUTPUT_FILE
65+
Specify the name of the output file, if it should be different from the scene class name
66+
-p, --preview Automatically open the saved file once its done
67+
-f, --show_in_file_browser
68+
Show the output file in the File Browser
69+
--leave_progress_bars
70+
Leave progress bars displayed in terminal
71+
-a, --write_all Write all the scenes from a file
72+
-w, --write_to_movie Render the scene as a movie file (this is on by default)
73+
-s, --save_last_frame
74+
Save the last frame only (no movie file is generated)
75+
-g, --save_pngs Save each frame as a png
76+
-i, --save_as_gif Save the video as gif
77+
--disable_caching Disable caching (will generate partial-movie-files anyway)
78+
--flush_cache Remove all cached partial-movie-files
79+
--log_to_file Log terminal output to file
80+
-c BACKGROUND_COLOR, --background_color BACKGROUND_COLOR
81+
Specify background color
82+
--background_opacity BACKGROUND_OPACITY
83+
Specify background opacity
84+
--media_dir MEDIA_DIR
85+
Directory to store media (including video files)
86+
--log_dir LOG_DIR Directory to store log files
87+
--tex_template TEX_TEMPLATE
88+
Specify a custom TeX template file
89+
--dry_run Do a dry run (render scenes but generate no output files)
90+
-t, --transparent Render a scene with an alpha channel
91+
-q {k,h,m,l}, --quality {k,h,m,l}
92+
Render at specific quality, short form of the --*_quality flags
93+
--low_quality Render at low quality
94+
--medium_quality Render at medium quality
95+
--high_quality Render at high quality
96+
--fourk_quality Render at 4K quality
97+
-r RESOLUTION, --resolution RESOLUTION
98+
Resolution, passed as "height,width". Overrides any quality flags, if present
99+
-n FROM_ANIMATION_NUMBER, --from_animation_number FROM_ANIMATION_NUMBER
100+
Start rendering at the specified animation index, instead of the first animation. If you pass in two comma separated values, e.g. '3,6', it will end the rendering at the second
101+
value
102+
--use_js_renderer Render animations using the javascript frontend
103+
--js_renderer_path JS_RENDERER_PATH
104+
Path to the javascript frontend
105+
--config_file CONFIG_FILE
106+
Specify the configuration file
107+
--custom_folders Use the folders defined in the [custom_folders] section of the config file to define the output folder structure
108+
-v {DEBUG,INFO,WARNING,ERROR,CRITICAL}, --verbosity {DEBUG,INFO,WARNING,ERROR,CRITICAL}
109+
Verbosity level. Also changes the ffmpeg log level unless the latter is specified in the config
110+
--progress_bar True/False
111+
Display the progress bar
112+
113+
Made with <3 by the manim community devs
124114

125115
For example, to render a scene in high quality, but only output the last frame
126116
of the scene instead of the whole video, you can execute
127117

128118
.. code-block:: bash
129119
130-
$ manim <file.py> SceneName -es
120+
$ manim <file.py> SceneName -sqh
131121
132122
The following example specifies the output file name (with the :code:`-o`
133123
flag), renders only the first ten animations (:code:`-n` flag) with a white

manim/config/config.py

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,12 @@
1616
import colour
1717

1818
from .. import constants
19-
from .config_utils import _run_config, _init_dirs, _from_command_line
19+
from .config_utils import (
20+
_determine_quality,
21+
_run_config,
22+
_init_dirs,
23+
_from_command_line,
24+
)
2025

2126
from .logger import set_rich_logger, set_file_logger, logger
2227
from ..utils.tex import TexTemplate, TexTemplateFromFile
@@ -80,13 +85,11 @@ def _parse_config(config_parser, args):
8085
# Handle the *_quality flags. These determine the section to read
8186
# and are stored in 'camera_config'. Note the highest resolution
8287
# passed as argument will be used.
83-
for flag in ["fourk_quality", "high_quality", "medium_quality", "low_quality"]:
84-
if getattr(args, flag):
85-
section = config_parser[flag]
86-
break
87-
else:
88-
section = config_parser["CLI"]
89-
config = {opt: section.getint(opt) for opt in config_parser[flag]}
88+
quality = _determine_quality(args)
89+
section = config_parser[quality if quality != "production" else "CLI"]
90+
91+
# Loop over low quality for the keys, could be any quality really
92+
config = {opt: section.getint(opt) for opt in config_parser["low_quality"]}
9093

9194
config["default_pixel_height"] = default.getint("pixel_height")
9295
config["default_pixel_width"] = default.getint("pixel_width")
@@ -152,6 +155,8 @@ def _parse_config(config_parser, args):
152155

153156
args, config_parser, file_writer_config, successfully_read_files = _run_config()
154157
logger.setLevel(file_writer_config["verbosity"])
158+
set_rich_logger(config_parser["logger"], file_writer_config["verbosity"])
159+
155160
if _from_command_line():
156161
logger.debug(
157162
f"Read configuration files: {[os.path.abspath(cfgfile) for cfgfile in successfully_read_files]}"
@@ -163,8 +168,6 @@ def _parse_config(config_parser, args):
163168
file_writer_config["disable_caching"] = True
164169
camera_config = config
165170

166-
# Set the different loggers
167-
set_rich_logger(config_parser["logger"], file_writer_config["verbosity"])
168171
if file_writer_config["log_to_file"]:
169172
# IMPORTANT note about file name : The log file name will be the scene_name get from the args (contained in file_writer_config). So it can differ from the real name of the scene.
170173
log_file_path = os.path.join(

manim/config/config_utils.py

Lines changed: 54 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,11 @@
1717

1818
import argparse
1919
import configparser
20+
import logging
2021
import os
2122
import sys
2223

23-
import colour
24-
2524
from .. import constants
26-
from ..utils.tex import TexTemplate, TexTemplateFromFile
2725

2826

2927
def _parse_file_writer_config(config_parser, args):
@@ -342,36 +340,60 @@ def _parse_cli(arg_list, input=True):
342340
# The following are mutually exclusive and each overrides
343341
# FRAME_RATE, PIXEL_HEIGHT, and PIXEL_WIDTH,
344342
parser.add_argument(
345-
"-l",
343+
"-q",
344+
"--quality",
345+
choices=constants.QUALITIES.values(),
346+
help="Render at specific quality, short form of the --*_quality flags",
347+
)
348+
parser.add_argument(
346349
"--low_quality",
347350
action="store_true",
348351
help="Render at low quality",
349352
)
350353
parser.add_argument(
351-
"-m",
352354
"--medium_quality",
353355
action="store_true",
354356
help="Render at medium quality",
355357
)
356358
parser.add_argument(
357-
"-e",
358359
"--high_quality",
359360
action="store_true",
360361
help="Render at high quality",
361362
)
362363
parser.add_argument(
363-
"-k",
364364
"--fourk_quality",
365365
action="store_true",
366366
help="Render at 4K quality",
367367
)
368368

369+
# Deprecated quality flags
370+
parser.add_argument(
371+
"-l",
372+
action="store_true",
373+
help="DEPRECATED: USE -ql or --quality l",
374+
)
375+
parser.add_argument(
376+
"-m",
377+
action="store_true",
378+
help="DEPRECATED: USE -qm or --quality m",
379+
)
380+
parser.add_argument(
381+
"-e",
382+
action="store_true",
383+
help="DEPRECATED: USE -qh or --quality h",
384+
)
385+
parser.add_argument(
386+
"-k",
387+
action="store_true",
388+
help="DEPRECATED: USE -qk or --quality k",
389+
)
390+
369391
# This overrides any of the above
370392
parser.add_argument(
371393
"-r",
372394
"--resolution",
373395
help='Resolution, passed as "height,width". '
374-
"Overrides the -l, -m, -e, and -k flags, if present",
396+
"Overrides any quality flags, if present",
375397
)
376398

377399
# This sets FROM_ANIMATION_NUMBER and UPTO_ANIMATION_NUMBER
@@ -617,3 +639,27 @@ def _init_cfg_subcmd(subparsers):
617639
cfg_export_parser.add_argument("--dir", default=os.getcwd())
618640

619641
return cfg_related
642+
643+
644+
def _determine_quality(args):
645+
old_qualities = {
646+
"k": "fourk_quality",
647+
"e": "high_quality",
648+
"m": "medium_quality",
649+
"l": "low_quality",
650+
}
651+
652+
for quality in constants.QUALITIES.keys():
653+
if getattr(args, quality) or (
654+
hasattr(args, "quality") and args.quality == constants.QUALITIES[quality]
655+
):
656+
return quality
657+
658+
for quality in old_qualities.keys():
659+
if getattr(args, quality):
660+
logging.getLogger("manim").warning(
661+
f"Option -{quality} is deprecated please use the --quality/-q flag."
662+
)
663+
return old_qualities[quality]
664+
665+
return "production"

manim/constants.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,3 +126,11 @@ class MyText(Text):
126126
"you can either start it prior to running Manim or specify the path to the "
127127
"executable with the --js_renderer_path flag."
128128
)
129+
130+
# Video qualities
131+
QUALITIES = {
132+
"fourk_quality": "k",
133+
"high_quality": "h",
134+
"medium_quality": "m",
135+
"low_quality": "l",
136+
}

tests/test_cli_flags.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
from manim import constants
2+
from manim.config.config_utils import _determine_quality, _parse_cli
3+
4+
5+
def test_quality_flags():
6+
# Assert that quality is None when not specifying it
7+
parsed = _parse_cli([], False)
8+
9+
assert not parsed.quality
10+
11+
for quality in constants.QUALITIES.keys():
12+
# Assert that quality is properly set when using -q*
13+
arguments = f"-q{constants.QUALITIES[quality]}".split()
14+
parsed = _parse_cli(arguments, False)
15+
16+
assert parsed.quality == constants.QUALITIES[quality]
17+
assert quality == _determine_quality(parsed)
18+
19+
# Assert that quality is properly set when using -q *
20+
arguments = f"-q {constants.QUALITIES[quality]}".split()
21+
parsed = _parse_cli(arguments, False)
22+
23+
assert parsed.quality == constants.QUALITIES[quality]
24+
assert quality == _determine_quality(parsed)
25+
26+
# Assert that quality is properly set when using --quality *
27+
arguments = f"--quality {constants.QUALITIES[quality]}".split()
28+
parsed = _parse_cli(arguments, False)
29+
30+
assert parsed.quality == constants.QUALITIES[quality]
31+
assert quality == _determine_quality(parsed)
32+
33+
# Assert that quality is properly set when using -*_quality
34+
arguments = f"--{quality}".split()
35+
parsed = _parse_cli(arguments, False)
36+
37+
assert getattr(parsed, quality)
38+
assert quality == _determine_quality(parsed)
39+
40+
# Assert that *_quality is False when not specifying it
41+
parsed = _parse_cli([], False)
42+
43+
assert not getattr(parsed, quality)
44+
assert "production" == _determine_quality(parsed)

0 commit comments

Comments
 (0)