mirror of
https://github.com/3b1b/manim.git
synced 2025-04-13 09:47:07 +00:00
Video work (#2284)
* Comment tweak * Directly print traceback Since the shell.showtraceback is giving some issues * Make InteracrtiveSceneEmbed into a class This way it can keep track of it's internal shell; use of get_ipython has a finicky relationship with reloading. * Move remaining checkpoint_paste logic into scene_embed.py This involved making a few context managers for Scene: temp_record, temp_skip, temp_progress_bar, which seem useful in and of themselves. * Change null key to be the empty string * Ensure temporary svg paths for Text are deleted * Remove unused dict_ops.py functions * Remove break_into_partial_movies from file_writer configuration * Rewrite guarantee_existence using Path * Clean up SceneFileWriter It had a number of vestigial functions no longer used, and some setup that could be made more organized. * Remove --save_pngs CLI arg (which did nothing) * Add --subdivide CLI arg * Remove add_extension_if_not_present * Remove get_sorted_integer_files * Have find_file return Path * Minor clean up * Clean up num_tex_symbols * Fix find_file * Minor cleanup for extract_scene.py * Add preview_frame_while_skipping option to scene config * Use shell.showtraceback function * Move keybindings to config, instead of in-place constants * Replace DEGREES -> DEG * Add arg to clear the cache * Separate out full_tex_to_svg from tex_to_svg And only cache to disk the results of full_tex_to_svg. Otherwise, making edits to the tex_templates would not show up without clearing the cache. * Bug fix in handling BlankScene * Make checkpoint_states an instance variable of CheckpointManager As per https://github.com/3b1b/manim/issues/2272 * Move resizing out of Window.focus, and into Window.init_for_scene * Make default output directory "." instead of "" To address https://github.com/3b1b/manim/issues/2261 * Remove input_file_path arg from SceneFileWriter * Use Dict syntax in place of dict for config more consistently across config.py * Simplify get_output_directory * Swap order of preamble and additional preamble * Minor stylistic tweak * Have UnitInterval pass on kwargs to NumberLine * Add simple get_dist function * Have TracedPath always update to the stroke configuration passed in * Have Mobject.match_points apply to all parts of data in pointlike_data_key * Always call Mobject.update upon adding an updater * Add Surface.uv_to_point * Make sure Surface.set_opacity takes in a recurse option * Update num_tex_symbols to account for \{ and \}
This commit is contained in:
parent
39fbb677dc
commit
96d44bd560
7 changed files with 49 additions and 11 deletions
|
@ -112,7 +112,7 @@ class TracedPath(VMobject):
|
||||||
self.time: float = 0
|
self.time: float = 0
|
||||||
self.traced_points: list[np.ndarray] = []
|
self.traced_points: list[np.ndarray] = []
|
||||||
self.add_updater(lambda m, dt: m.update_path(dt))
|
self.add_updater(lambda m, dt: m.update_path(dt))
|
||||||
self.set_stroke(stroke_color, stroke_width)
|
self.always.set_stroke(stroke_color, stroke_width)
|
||||||
|
|
||||||
def update_path(self, dt: float) -> Self:
|
def update_path(self, dt: float) -> Self:
|
||||||
if dt == 0:
|
if dt == 0:
|
||||||
|
|
|
@ -307,12 +307,15 @@ class Mobject(object):
|
||||||
parent.refresh_bounding_box()
|
parent.refresh_bounding_box()
|
||||||
return self
|
return self
|
||||||
|
|
||||||
# Others related to points
|
@affects_data
|
||||||
|
|
||||||
def match_points(self, mobject: Mobject) -> Self:
|
def match_points(self, mobject: Mobject) -> Self:
|
||||||
self.set_points(mobject.get_points())
|
self.resize_points(len(mobject.data), resize_func=resize_preserving_order)
|
||||||
|
for key in self.pointlike_data_keys:
|
||||||
|
self.data[key][:] = mobject.data[key]
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
# Others related to points
|
||||||
|
|
||||||
def get_points(self) -> Vect3Array:
|
def get_points(self) -> Vect3Array:
|
||||||
return self.data["point"]
|
return self.data["point"]
|
||||||
|
|
||||||
|
@ -842,6 +845,7 @@ class Mobject(object):
|
||||||
if call:
|
if call:
|
||||||
self.update(dt=0)
|
self.update(dt=0)
|
||||||
self.refresh_has_updater_status()
|
self.refresh_has_updater_status()
|
||||||
|
self.update()
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def insert_updater(self, update_func: Updater, index=0):
|
def insert_updater(self, update_func: Updater, index=0):
|
||||||
|
|
|
@ -221,11 +221,13 @@ class UnitInterval(NumberLine):
|
||||||
big_tick_numbers: list[float] = [0, 1],
|
big_tick_numbers: list[float] = [0, 1],
|
||||||
decimal_number_config: dict = dict(
|
decimal_number_config: dict = dict(
|
||||||
num_decimal_places=1,
|
num_decimal_places=1,
|
||||||
)
|
),
|
||||||
|
**kwargs
|
||||||
):
|
):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
x_range=x_range,
|
x_range=x_range,
|
||||||
unit_size=unit_size,
|
unit_size=unit_size,
|
||||||
big_tick_numbers=big_tick_numbers,
|
big_tick_numbers=big_tick_numbers,
|
||||||
decimal_number_config=decimal_number_config,
|
decimal_number_config=decimal_number_config,
|
||||||
|
**kwargs
|
||||||
)
|
)
|
||||||
|
|
|
@ -8,9 +8,11 @@ from manimlib.constants import OUT
|
||||||
from manimlib.mobject.mobject import Mobject
|
from manimlib.mobject.mobject import Mobject
|
||||||
from manimlib.utils.bezier import integer_interpolate
|
from manimlib.utils.bezier import integer_interpolate
|
||||||
from manimlib.utils.bezier import interpolate
|
from manimlib.utils.bezier import interpolate
|
||||||
|
from manimlib.utils.bezier import inverse_interpolate
|
||||||
from manimlib.utils.images import get_full_raster_image_path
|
from manimlib.utils.images import get_full_raster_image_path
|
||||||
from manimlib.utils.iterables import listify
|
from manimlib.utils.iterables import listify
|
||||||
from manimlib.utils.iterables import resize_with_interpolation
|
from manimlib.utils.iterables import resize_with_interpolation
|
||||||
|
from manimlib.utils.simple_functions import clip
|
||||||
from manimlib.utils.space_ops import normalize_along_axis
|
from manimlib.utils.space_ops import normalize_along_axis
|
||||||
from manimlib.utils.space_ops import cross
|
from manimlib.utils.space_ops import cross
|
||||||
|
|
||||||
|
@ -96,6 +98,32 @@ class Surface(Mobject):
|
||||||
self.data['du_point'][:] = du_points
|
self.data['du_point'][:] = du_points
|
||||||
self.data['dv_point'][:] = dv_points
|
self.data['dv_point'][:] = dv_points
|
||||||
|
|
||||||
|
def uv_to_point(self, u, v):
|
||||||
|
nu, nv = self.resolution
|
||||||
|
uv_grid = np.reshape(self.get_points(), (nu, nv, self.dim))
|
||||||
|
|
||||||
|
alpha1 = clip(inverse_interpolate(*self.u_range[:2], u), 0, 1)
|
||||||
|
alpha2 = clip(inverse_interpolate(*self.v_range[:2], v), 0, 1)
|
||||||
|
scaled_u = alpha1 * (nu - 1)
|
||||||
|
scaled_v = alpha2 * (nv - 1)
|
||||||
|
u_int = int(scaled_u)
|
||||||
|
v_int = int(scaled_v)
|
||||||
|
u_int_plus = min(u_int + 1, nu - 1)
|
||||||
|
v_int_plus = min(v_int + 1, nv - 1)
|
||||||
|
|
||||||
|
a = uv_grid[u_int, v_int, :]
|
||||||
|
b = uv_grid[u_int, v_int_plus, :]
|
||||||
|
c = uv_grid[u_int_plus, v_int, :]
|
||||||
|
d = uv_grid[u_int_plus, v_int_plus, :]
|
||||||
|
|
||||||
|
u_res = scaled_u % 1
|
||||||
|
v_res = scaled_v % 1
|
||||||
|
return interpolate(
|
||||||
|
interpolate(a, b, v_res),
|
||||||
|
interpolate(c, d, v_res),
|
||||||
|
u_res
|
||||||
|
)
|
||||||
|
|
||||||
def apply_points_function(self, *args, **kwargs) -> Self:
|
def apply_points_function(self, *args, **kwargs) -> Self:
|
||||||
super().apply_points_function(*args, **kwargs)
|
super().apply_points_function(*args, **kwargs)
|
||||||
self.get_unit_normals()
|
self.get_unit_normals()
|
||||||
|
@ -307,7 +335,7 @@ class TexturedSurface(Surface):
|
||||||
self.uniforms["num_textures"] = self.num_textures
|
self.uniforms["num_textures"] = self.num_textures
|
||||||
|
|
||||||
@Mobject.affects_data
|
@Mobject.affects_data
|
||||||
def set_opacity(self, opacity: float | Iterable[float]) -> Self:
|
def set_opacity(self, opacity: float | Iterable[float], recurse=True) -> Self:
|
||||||
op_arr = np.array(listify(opacity))
|
op_arr = np.array(listify(opacity))
|
||||||
self.data["opacity"][:, 0] = resize_with_interpolation(op_arr, len(self.data))
|
self.data["opacity"][:, 0] = resize_with_interpolation(op_arr, len(self.data))
|
||||||
return self
|
return self
|
||||||
|
|
|
@ -48,6 +48,10 @@ def get_norm(vect: VectN | List[float]) -> float:
|
||||||
return sum((x**2 for x in vect))**0.5
|
return sum((x**2 for x in vect))**0.5
|
||||||
|
|
||||||
|
|
||||||
|
def get_dist(vect1: VectN, vect2: VectN):
|
||||||
|
return get_norm(vect2 - vect1)
|
||||||
|
|
||||||
|
|
||||||
def normalize(
|
def normalize(
|
||||||
vect: VectN | List[float],
|
vect: VectN | List[float],
|
||||||
fall_back: VectN | List[float] | None = None
|
fall_back: VectN | List[float] | None = None
|
||||||
|
|
|
@ -11,7 +11,8 @@ def num_tex_symbols(tex: str) -> int:
|
||||||
tex = remove_tex_environments(tex)
|
tex = remove_tex_environments(tex)
|
||||||
commands_pattern = r"""
|
commands_pattern = r"""
|
||||||
(?P<sqrt>\\sqrt\[[0-9]+\])| # Special sqrt with number
|
(?P<sqrt>\\sqrt\[[0-9]+\])| # Special sqrt with number
|
||||||
(?P<cmd>\\[a-zA-Z!,-/:;<>]+) # Regular commands
|
(?P<escaped_brace>\\[{}])| # Escaped braces
|
||||||
|
(?P<cmd>\\[a-zA-Z!,-/:;<>]+) # Regular commands
|
||||||
"""
|
"""
|
||||||
total = 0
|
total = 0
|
||||||
pos = 0
|
pos = 0
|
||||||
|
@ -21,6 +22,8 @@ def num_tex_symbols(tex: str) -> int:
|
||||||
|
|
||||||
if match.group("sqrt"):
|
if match.group("sqrt"):
|
||||||
total += len(match.group()) - 5
|
total += len(match.group()) - 5
|
||||||
|
elif match.group("escaped_brace"):
|
||||||
|
total += 1 # Count escaped brace as one symbol
|
||||||
else:
|
else:
|
||||||
total += TEX_TO_SYMBOL_COUNT.get(match.group(), 1)
|
total += TEX_TO_SYMBOL_COUNT.get(match.group(), 1)
|
||||||
pos = match.end()
|
pos = match.end()
|
||||||
|
|
|
@ -22,10 +22,7 @@ def get_tex_template_config(template_name: str) -> dict[str, str]:
|
||||||
with open(template_path, encoding="utf-8") as tex_templates_file:
|
with open(template_path, encoding="utf-8") as tex_templates_file:
|
||||||
templates_dict = yaml.safe_load(tex_templates_file)
|
templates_dict = yaml.safe_load(tex_templates_file)
|
||||||
if name not in templates_dict:
|
if name not in templates_dict:
|
||||||
log.warning(
|
log.warning(f"Cannot recognize template {name}, falling back to 'default'.")
|
||||||
"Cannot recognize template '%s', falling back to 'default'.",
|
|
||||||
name
|
|
||||||
)
|
|
||||||
name = "default"
|
name = "default"
|
||||||
return templates_dict[name]
|
return templates_dict[name]
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue