Merge pull request #1941 from 3b1b/video-work

Small bug fixes and refactors
This commit is contained in:
Grant Sanderson 2022-12-19 21:20:01 -08:00 committed by GitHub
commit 67912e26d3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 60 additions and 56 deletions

View file

@ -184,7 +184,7 @@ def get_manim_dir():
return os.path.abspath(os.path.join(manimlib_dir, ".."))
def get_module(file_name):
def get_module(file_name: str | None):
if file_name is None:
return None
module_name = file_name.replace(os.sep, ".").replace(".py", "")
@ -198,8 +198,9 @@ def get_indent(line: str):
return len(line) - len(line.lstrip())
@contextmanager
def insert_embed_line(file_name: str, scene_name: str, line_marker: str):
def get_module_with_inserted_embed_line(
file_name: str, scene_name: str, line_marker: str
):
"""
This is hacky, but convenient. When user includes the argument "-e", it will try
to recreate a file that inserts the line `self.embed()` into the end of the scene's
@ -255,14 +256,19 @@ def insert_embed_line(file_name: str, scene_name: str, line_marker: str):
inserted_line = " " * n_spaces + "self.embed()\n"
new_lines = list(lines)
new_lines.insert(prev_line_num + 1, inserted_line)
new_file = file_name.replace(".py", "_insert_embed.py")
with open(file_name, 'w') as fp:
with open(new_file, 'w') as fp:
fp.writelines(new_lines)
try:
yield file_name
finally:
with open(file_name, 'w') as fp:
fp.writelines(lines)
module = get_module(new_file)
# This is to pretend the module imported from the edited lines
# of code actually comes from the original file.
module.__file__ = file_name
os.remove(new_file)
return module
def get_custom_config():
@ -326,7 +332,7 @@ def get_configuration(args):
elif not os.path.exists(__config_file__):
log.info(f"Using the default configuration file, which you can modify in `{global_defaults_file}`")
log.info(
"If you want to create a local configuration file, you can create a file named"
"If you want to create a local configuration file, you can create a file named" + \
f" `{__config_file__}`, or run `manimgl --config`"
)
@ -367,11 +373,12 @@ def get_configuration(args):
"quiet": args.quiet,
}
module = get_module(args.file)
if args.embed is not None:
with insert_embed_line(args.file, args.scene_names[0], args.embed) as alt_file:
module = get_module(alt_file)
module = get_module_with_inserted_embed_line(
args.file, args.scene_names[0], args.embed
)
else:
module = get_module(args.file)
config = {
"module": module,

View file

@ -410,13 +410,15 @@ class Axes(VGroup, CoordinateSystem):
axis_config: dict = dict(),
x_axis_config: dict = dict(),
y_axis_config: dict = dict(),
height: float = FRAME_HEIGHT - 2,
width: float = FRAME_WIDTH - 2,
height: float | None = None,
width: float | None = None,
unit_size: float = 1.0,
**kwargs
):
CoordinateSystem.__init__(self, x_range, y_range, **kwargs)
VGroup.__init__(self, **kwargs)
axis_config = dict(**axis_config, unit_size=unit_size)
self.x_axis = self.create_axis(
self.x_range,
axis_config=merge_dicts_recursively(
@ -435,7 +437,7 @@ class Axes(VGroup, CoordinateSystem):
axis_config,
y_axis_config
),
length=height
length=height,
)
self.y_axis.rotate(90 * DEGREES, about_point=ORIGIN)
# Add as a separate group in case various other
@ -449,7 +451,7 @@ class Axes(VGroup, CoordinateSystem):
self,
range_terms: RangeSpecifier,
axis_config: dict,
length: float
length: float | None
) -> NumberLine:
axis = NumberLine(range_terms, width=length, **axis_config)
axis.shift(-axis.n2p(0))
@ -576,8 +578,6 @@ class NumberPlane(Axes):
self,
x_range: RangeSpecifier = (-8.0, 8.0, 1.0),
y_range: RangeSpecifier = (-4.0, 4.0, 1.0),
height: float = 8.0,
width: float = 16.0,
background_line_style: dict = dict(
stroke_color=BLUE_D,
stroke_width=2,
@ -589,12 +589,7 @@ class NumberPlane(Axes):
make_smooth_after_applying_functions: bool = True,
**kwargs
):
super().__init__(
x_range, y_range,
height=height,
width=width,
**kwargs
)
super().__init__(x_range, y_range, **kwargs)
self.background_line_style = dict(background_line_style)
self.faded_line_style = dict(faded_line_style)
self.faded_line_ratio = faded_line_ratio

View file

@ -3,6 +3,8 @@ from __future__ import annotations
import re
from manimlib.mobject.svg.string_mobject import StringMobject
from manimlib.utils.color import color_to_hex
from manimlib.utils.color import hex_to_int
from manimlib.utils.tex_file_writing import tex_content_to_svg_file
from typing import TYPE_CHECKING
@ -159,7 +161,7 @@ class MTex(StringMobject):
@staticmethod
def get_color_command(rgb_hex: str) -> str:
rgb = MTex.hex_to_int(rgb_hex)
rgb = hex_to_int(rgb_hex)
rg, b = divmod(rgb, 256)
r, g = divmod(rg, 256)
return f"\\color[RGB]{{{r}, {g}, {b}}}"
@ -181,7 +183,7 @@ class MTex(StringMobject):
suffix_lines = []
if not is_labelled:
prefix_lines.append(self.get_color_command(
self.color_to_hex(self.base_color)
color_to_hex(self.base_color)
))
if self.alignment:
prefix_lines.append(self.alignment)

View file

@ -10,8 +10,9 @@ from manimlib.constants import WHITE
from manimlib.logger import log
from manimlib.mobject.svg.svg_mobject import SVGMobject
from manimlib.mobject.types.vectorized_mobject import VGroup
from manimlib.utils.color import color_to_rgb
from manimlib.utils.color import rgb_to_hex
from manimlib.utils.color import color_to_hex
from manimlib.utils.color import hex_to_int
from manimlib.utils.color import int_to_hex
from typing import TYPE_CHECKING
@ -117,7 +118,7 @@ class StringMobject(SVGMobject, ABC):
for submob, labelled_svg_submob in zip(
self.submobjects, labelled_svg.submobjects
):
label = self.hex_to_int(self.color_to_hex(
label = hex_to_int(color_to_hex(
labelled_svg_submob.get_fill_color()
))
if label >= labels_count:
@ -129,7 +130,7 @@ class StringMobject(SVGMobject, ABC):
"Unrecognizable color labels detected (%s). " + \
"The result could be unexpected.",
", ".join(
self.int_to_hex(color)
int_to_hex(color)
for color in unrecognizable_colors
)
)
@ -196,18 +197,6 @@ class StringMobject(SVGMobject, ABC):
def span_contains(span_0: Span, span_1: Span) -> bool:
return span_0[0] <= span_1[0] and span_0[1] >= span_1[1]
@staticmethod
def color_to_hex(color: ManimColor) -> str:
return rgb_to_hex(color_to_rgb(color))
@staticmethod
def hex_to_int(rgb_hex: str) -> int:
return int(rgb_hex[1:], 16)
@staticmethod
def int_to_hex(rgb_int: int) -> str:
return f"#{rgb_int:06x}".upper()
# Parsing
def parse(self) -> None:
@ -380,7 +369,7 @@ class StringMobject(SVGMobject, ABC):
lambda label, flag, attr_dict: self.get_command_string(
attr_dict,
is_end=flag < 0,
label_hex=self.int_to_hex(label) if is_labelled else None
label_hex=int_to_hex(label) if is_labelled else None
)
)
prefix, suffix = self.get_content_prefix_and_suffix(

View file

@ -15,6 +15,8 @@ from manimlib.constants import NORMAL
from manimlib.logger import log
from manimlib.mobject.svg.string_mobject import StringMobject
from manimlib.utils.customization import get_customization
from manimlib.utils.color import color_to_hex
from manimlib.utils.color import int_to_hex
from manimlib.utils.directories import get_downloads_dir
from manimlib.utils.directories import get_text_dir
from manimlib.utils.simple_functions import hash_string
@ -366,7 +368,7 @@ class MarkupText(StringMobject):
self, is_labelled: bool
) -> tuple[str, str]:
global_attr_dict = {
"foreground": self.color_to_hex(self.base_color),
"foreground": color_to_hex(self.base_color),
"font_family": self.font,
"font_style": self.slant,
"font_weight": self.weight,
@ -394,7 +396,7 @@ class MarkupText(StringMobject):
self.get_command_string(
global_attr_dict,
is_end=is_end,
label_hex=self.int_to_hex(0) if is_labelled else None
label_hex=int_to_hex(0) if is_labelled else None
)
for is_end in (False, True)
)

View file

@ -100,7 +100,6 @@ class VMobject(Mobject):
self.flat_stroke = flat_stroke
self.needs_new_triangulation = True
self.needs_new_unit_normal = True
self.triangulation = np.zeros(0, dtype='i4')
super().__init__(**kwargs)
@ -759,10 +758,9 @@ class VMobject(Mobject):
if not self.has_points():
return np.zeros(3)
nppc = self.n_points_per_curve
points = self.get_points()
p0 = points[0::nppc]
p1 = points[nppc - 1::nppc]
p0 = points[:-1]
p1 = points[1:]
# Each term goes through all edges [(x1, y1, z1), (x2, y2, z2)]
return 0.5 * np.array([
@ -772,7 +770,7 @@ class VMobject(Mobject):
])
def get_unit_normal(self, recompute: bool = False) -> Vect3:
if not self.needs_new_unit_normal and not recompute:
if not recompute:
return self.data["unit_normal"][0]
if self.get_num_points() < 3:
@ -789,12 +787,11 @@ class VMobject(Mobject):
points[2] - points[1],
)
self.data["unit_normal"][:] = normal
self.needs_new_unit_normal = False
return normal
def refresh_unit_normal(self):
for mob in self.get_family():
mob.needs_new_unit_normal = True
mob.get_unit_normal(recompute=True)
return self
# Alignment
@ -1026,9 +1023,10 @@ class VMobject(Mobject):
super().set_points(points)
return self
@triggers_refreshed_triangulation
def append_points(self, points: Vect3Array):
super().append_points(points)
self.refresh_unit_normal()
self.refresh_triangulation()
return self
@triggers_refreshed_triangulation

View file

@ -624,7 +624,6 @@ class Scene(object):
break
self.refresh_static_mobjects()
self.post_play()
return self
def hold_loop(self):
while self.hold_on_wait:

View file

@ -62,6 +62,18 @@ def color_to_int_rgba(color: ManimColor, opacity: float = 1.0) -> np.ndarray[int
return np.array([*color_to_int_rgb(color), alpha], dtype=np.uint8)
def color_to_hex(color: ManimColor) -> str:
return Color(color).hex.upper()
def hex_to_int(rgb_hex: str) -> int:
return int(rgb_hex[1:], 16)
def int_to_hex(rgb_int: int) -> str:
return f"#{rgb_int:06x}".upper()
def color_gradient(
reference_colors: Iterable[ManimColor],
length_of_output: int