mirror of
https://github.com/ManimCommunity/manim.git
synced 2026-06-22 10:01:47 +00:00
[Experimental] Fix errors in the table tests (#4549)
* Rename parameter n_rows and n_cols of OpenGLMobject::arrange_in_grid to rows and cols This is to match the Mobject::arrange_in_grid method signature * Make OpenGLMobject::arrange_in_grid handle buff values similar to Mobject::arrange_in_grid * Use Mobject::arrange_in_grid from the main branch Also removed some type ignore statements * Use the same default opacities as VMobject in the main branch Also removed some type ignore statements and added strict=False to two zip statements. * Deal with opacities later.
This commit is contained in:
parent
a2c04954b8
commit
d1b7d20c65
2 changed files with 61 additions and 120 deletions
|
|
@ -4,6 +4,7 @@ import copy
|
|||
import inspect
|
||||
import itertools as it
|
||||
import logging
|
||||
import math
|
||||
import numbers
|
||||
import os
|
||||
import pickle
|
||||
|
|
@ -12,7 +13,6 @@ import sys
|
|||
from collections.abc import Callable, Iterable, Sequence
|
||||
from dataclasses import dataclass
|
||||
from functools import partialmethod, wraps
|
||||
from math import ceil
|
||||
from typing import (
|
||||
TYPE_CHECKING,
|
||||
Any,
|
||||
|
|
@ -23,7 +23,6 @@ from typing import (
|
|||
TypeAlias,
|
||||
TypeVar,
|
||||
cast,
|
||||
overload,
|
||||
override,
|
||||
)
|
||||
|
||||
|
|
@ -32,7 +31,6 @@ import numpy.typing as npt
|
|||
from typing_extensions import (
|
||||
ParamSpec,
|
||||
TypedDict,
|
||||
TypeVar,
|
||||
)
|
||||
|
||||
from manim import config
|
||||
|
|
@ -62,6 +60,7 @@ from manim.utils.space_ops import (
|
|||
|
||||
__all__ = ["InvisibleMobject", "OpenGLMobject", "MobjectKwargs"]
|
||||
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from manim.animation.animation import Animation
|
||||
from manim.renderer.renderer import RendererData
|
||||
|
|
@ -75,7 +74,6 @@ if TYPE_CHECKING:
|
|||
Point3D_Array,
|
||||
Point3DLike,
|
||||
Point3DLike_Array,
|
||||
Vector3D,
|
||||
Vector3DLike,
|
||||
)
|
||||
|
||||
|
|
@ -1047,7 +1045,7 @@ class OpenGLMobject:
|
|||
return self
|
||||
|
||||
# !TODO this differs a lot from 3b1b/manim
|
||||
def arrange_in_grid_legacy(
|
||||
def arrange_in_grid(
|
||||
self,
|
||||
rows: int | None = None,
|
||||
cols: int | None = None,
|
||||
|
|
@ -1092,19 +1090,8 @@ class OpenGLMobject:
|
|||
|
||||
Returns
|
||||
-------
|
||||
OpenGLMobject
|
||||
The mobject.
|
||||
|
||||
NOTES
|
||||
-----
|
||||
|
||||
If only one of ``cols`` and ``rows`` is set implicitly, the other one will be chosen big
|
||||
enough to fit all submobjects. If neither is set, they will be chosen to be about the same,
|
||||
tending towards ``cols`` > ``rows`` (simply because videos are wider than they are high).
|
||||
|
||||
If both ``cell_alignment`` and ``row_alignments`` / ``col_alignments`` are
|
||||
defined, the latter has higher priority.
|
||||
|
||||
:class:`OpenGLMobject`
|
||||
``self``
|
||||
|
||||
Raises
|
||||
------
|
||||
|
|
@ -1114,6 +1101,15 @@ class OpenGLMobject:
|
|||
If :code:`cols`, :code:`col_alignments` and :code:`col_widths` or :code:`rows`,
|
||||
:code:`row_alignments` and :code:`row_heights` have mismatching sizes.
|
||||
|
||||
Notes
|
||||
-----
|
||||
If only one of ``cols`` and ``rows`` is set implicitly, the other one will be chosen big
|
||||
enough to fit all submobjects. If neither is set, they will be chosen to be about the same,
|
||||
tending towards ``cols`` > ``rows`` (simply because videos are wider than they are high).
|
||||
|
||||
If both ``cell_alignment`` and ``row_alignments`` / ``col_alignments`` are
|
||||
defined, the latter has higher priority.
|
||||
|
||||
Examples
|
||||
--------
|
||||
.. manim:: ExampleBoxes
|
||||
|
|
@ -1131,11 +1127,9 @@ class OpenGLMobject:
|
|||
|
||||
class ArrangeInGrid(Scene):
|
||||
def construct(self):
|
||||
#Add some numbered boxes:
|
||||
np.random.seed(3)
|
||||
boxes = VGroup(*[
|
||||
Rectangle(WHITE, np.random.random()+.5, np.random.random()+.5).add(Text(str(i+1)).scale(0.5))
|
||||
for i in range(22)
|
||||
Rectangle(WHITE, 0.5, 0.5).add(Text(str(i+1)).scale(0.5))
|
||||
for i in range(24)
|
||||
])
|
||||
self.add(boxes)
|
||||
|
||||
|
|
@ -1143,7 +1137,8 @@ class OpenGLMobject:
|
|||
buff=(0.25,0.5),
|
||||
col_alignments="lccccr",
|
||||
row_alignments="uccd",
|
||||
col_widths=[2, *[None]*4, 2],
|
||||
col_widths=[1, *[None]*4, 1],
|
||||
row_heights=[1, None, None, 1],
|
||||
flow_order="dr"
|
||||
)
|
||||
|
||||
|
|
@ -1168,15 +1163,15 @@ class OpenGLMobject:
|
|||
|
||||
# calculate rows cols
|
||||
if rows is None and cols is None:
|
||||
cols = ceil(np.sqrt(len(mobs)))
|
||||
cols = math.ceil(math.sqrt(len(mobs)))
|
||||
# make the grid as close to quadratic as possible.
|
||||
# choosing cols first can results in cols>rows.
|
||||
# This is favored over rows>cols since in general
|
||||
# the sceene is wider than high.
|
||||
if rows is None:
|
||||
rows = ceil(len(mobs) / cols) # type: ignore
|
||||
rows = math.ceil(len(mobs) / cols)
|
||||
if cols is None:
|
||||
cols = ceil(len(mobs) / rows)
|
||||
cols = math.ceil(len(mobs) / rows)
|
||||
if rows * cols < len(mobs):
|
||||
raise ValueError("Too few rows and columns to fit all submobjetcs.")
|
||||
# rows and cols are now finally valid.
|
||||
|
|
@ -1191,31 +1186,31 @@ class OpenGLMobject:
|
|||
def init_alignments(alignments, num, mapping, name, dir_):
|
||||
if alignments is None:
|
||||
# Use cell_alignment as fallback
|
||||
return [cast(Vector3D, cell_alignment * direction)] * num
|
||||
if len(str_alignments) != num:
|
||||
return [cell_alignment * dir_] * num
|
||||
if len(alignments) != num:
|
||||
raise ValueError(f"{name}_alignments has a mismatching size.")
|
||||
alignments = list(alignments)
|
||||
for i in range(num):
|
||||
alignments[i] = mapping[alignments[i]]
|
||||
return alignments
|
||||
|
||||
row_alignments_seq: Sequence[Vector3D] = init_alignments(
|
||||
row_alignments = init_alignments(
|
||||
row_alignments,
|
||||
rows,
|
||||
{"u": UP, "c": ORIGIN, "d": DOWN},
|
||||
"row",
|
||||
RIGHT,
|
||||
)
|
||||
col_alignments_seq: Sequence[Vector3D] = init_alignments(
|
||||
col_alignments = init_alignments(
|
||||
col_alignments,
|
||||
cols,
|
||||
{"l": LEFT, "c": ORIGIN, "r": RIGHT},
|
||||
"col",
|
||||
UP,
|
||||
)
|
||||
# Now row_alignments_seq[r] + col_alignment_seq[c] is the alignment in cell [r][c]
|
||||
# Now row_alignment[r] + col_alignment[c] is the alignment in cell [r][c]
|
||||
|
||||
mapper: dict[str, Callable[[int, int], int]] = {
|
||||
mapper = {
|
||||
"dr": lambda r, c: (rows - r - 1) + c * rows,
|
||||
"dl": lambda r, c: (rows - r - 1) + (cols - c - 1) * rows,
|
||||
"ur": lambda r, c: r + c * rows,
|
||||
|
|
@ -1226,30 +1221,20 @@ class OpenGLMobject:
|
|||
"lu": lambda r, c: r * cols + (cols - c - 1),
|
||||
}
|
||||
if flow_order not in mapper:
|
||||
valid_flow_orders = ",".join([f'"{key}"' for key in mapper])
|
||||
raise ValueError(
|
||||
f"flow_order must be one of the following values: {valid_flow_orders}.",
|
||||
'flow_order must be one of the following values: "dr", "rd", "ld" "dl", "ru", "ur", "lu", "ul".',
|
||||
)
|
||||
flow_order_func = mapper[flow_order]
|
||||
flow_order = mapper[flow_order]
|
||||
|
||||
# Reverse row_alignments and row_heights. Necessary since the
|
||||
# grid filling is handled bottom up for simplicity reasons.
|
||||
if TYPE_CHECKING:
|
||||
|
||||
@overload
|
||||
def reverse(maybe_list: None) -> None: ...
|
||||
@overload
|
||||
def reverse(maybe_list: Sequence[_T]) -> list[_T]: ...
|
||||
@overload
|
||||
def reverse(maybe_list: Sequence[_T] | None) -> list[_T] | None: ...
|
||||
|
||||
def reverse(maybe_list: Sequence[_T] | None) -> list[_T] | None:
|
||||
def reverse(maybe_list):
|
||||
if maybe_list is not None:
|
||||
maybe_list = list(maybe_list)
|
||||
maybe_list.reverse()
|
||||
return maybe_list
|
||||
|
||||
row_alignments_seq = reverse(row_alignments_seq)
|
||||
row_alignments = reverse(row_alignments)
|
||||
row_heights = reverse(row_heights)
|
||||
|
||||
placeholder = OpenGLMobject()
|
||||
|
|
@ -1258,7 +1243,7 @@ class OpenGLMobject:
|
|||
# properties of 0.
|
||||
|
||||
mobs.extend([placeholder] * (rows * cols - len(mobs)))
|
||||
grid = [[mobs[flow_order_func(r, c)] for c in range(cols)] for r in range(rows)]
|
||||
grid = [[mobs[flow_order(r, c)] for c in range(cols)] for r in range(rows)]
|
||||
|
||||
measured_heigths = [
|
||||
max(grid[r][c].height for c in range(cols)) for r in range(rows)
|
||||
|
|
@ -1274,19 +1259,18 @@ class OpenGLMobject:
|
|||
if len(sizes) != num:
|
||||
raise ValueError(f"{name} has a mismatching size.")
|
||||
return [
|
||||
size if (size := sizes[i]) is not None else measures[i]
|
||||
for i in range(num)
|
||||
sizes[i] if sizes[i] is not None else measures[i] for i in range(num)
|
||||
]
|
||||
|
||||
heights = init_sizes(row_heights, rows, measured_heigths, "row_heights")
|
||||
widths = init_sizes(col_widths, cols, measured_widths, "col_widths")
|
||||
|
||||
x, y = 0.0, 0.0
|
||||
x, y = 0, 0
|
||||
for r in range(rows):
|
||||
x = 0.0
|
||||
x = 0
|
||||
for c in range(cols):
|
||||
if grid[r][c] is not placeholder:
|
||||
alignment = row_alignments_seq[r] + col_alignments_seq[c]
|
||||
alignment = row_alignments[r] + col_alignments[c]
|
||||
line = Line(
|
||||
x * RIGHT + y * UP,
|
||||
(x + widths[c]) * RIGHT + (y + heights[r]) * UP,
|
||||
|
|
@ -1302,52 +1286,6 @@ class OpenGLMobject:
|
|||
self.move_to(start_pos)
|
||||
return self
|
||||
|
||||
def arrange_in_grid(
|
||||
self,
|
||||
n_rows: int | None = None,
|
||||
n_cols: int | None = None,
|
||||
buff: float | None = None,
|
||||
h_buff: float | None = None,
|
||||
v_buff: float | None = None,
|
||||
buff_ratio: float | None = None,
|
||||
h_buff_ratio: float = 0.5,
|
||||
v_buff_ratio: float = 0.5,
|
||||
aligned_edge: Vector3DLike = ORIGIN,
|
||||
fill_rows_first: bool = True,
|
||||
) -> Self:
|
||||
submobs = self.submobjects
|
||||
if n_rows is None and n_cols is None:
|
||||
n_rows = int(np.sqrt(len(submobs)))
|
||||
if n_rows is None and n_cols is not None:
|
||||
n_rows = len(submobs) // n_cols
|
||||
if n_cols is None and n_rows is not None:
|
||||
n_cols = len(submobs) // n_rows
|
||||
|
||||
if buff is not None:
|
||||
h_buff = buff
|
||||
v_buff = buff
|
||||
else:
|
||||
if buff_ratio is not None:
|
||||
v_buff_ratio = buff_ratio
|
||||
h_buff_ratio = buff_ratio
|
||||
if h_buff is None:
|
||||
h_buff = h_buff_ratio * self[0].get_width()
|
||||
if v_buff is None:
|
||||
v_buff = v_buff_ratio * self[0].get_height()
|
||||
|
||||
x_unit = h_buff + max(sm.get_width() for sm in submobs)
|
||||
y_unit = v_buff + max(sm.get_height() for sm in submobs)
|
||||
|
||||
for index, sm in enumerate(submobs):
|
||||
if fill_rows_first:
|
||||
x, y = index % n_cols, index // n_cols # type: ignore
|
||||
else:
|
||||
x, y = index // n_rows, index % n_rows # type: ignore
|
||||
sm.move_to(ORIGIN, aligned_edge)
|
||||
sm.shift(x * x_unit * RIGHT + y * y_unit * DOWN)
|
||||
self.center()
|
||||
return self
|
||||
|
||||
def arrange_to_fit_dim(
|
||||
self, length: float, dim: int, about_edge: Vector3DLike = ORIGIN
|
||||
) -> Self:
|
||||
|
|
@ -1649,9 +1587,9 @@ class OpenGLMobject:
|
|||
) -> Self:
|
||||
updater_list: list[_TimeBasedUpdater] | list[_NonTimeBasedUpdater]
|
||||
if "dt" in inspect.signature(update_function).parameters:
|
||||
updater_list: list[Updater] = self.time_based_updaters # type: ignore
|
||||
updater_list: list[Updater] = self.time_based_updaters
|
||||
else:
|
||||
updater_list: list[Updater] = self.non_time_updaters # type: ignore
|
||||
updater_list: list[Updater] = self.non_time_updaters
|
||||
|
||||
if index is None:
|
||||
cast("list[_Updater]", updater_list).append(update_function)
|
||||
|
|
@ -1665,8 +1603,8 @@ class OpenGLMobject:
|
|||
|
||||
def remove_updater(self, update_function: Updater) -> Self:
|
||||
updater_lists: list[list[Updater]] = [
|
||||
self.time_based_updaters, # type: ignore
|
||||
self.non_time_updaters, # type: ignore
|
||||
self.time_based_updaters,
|
||||
self.non_time_updaters,
|
||||
]
|
||||
for updater_list in updater_lists:
|
||||
while update_function in updater_list:
|
||||
|
|
@ -1792,7 +1730,7 @@ class OpenGLMobject:
|
|||
if isinstance(scale_factor, numbers.Number):
|
||||
scale_factor = max(scale_factor, min_scale_factor)
|
||||
else:
|
||||
scale_factor = np.array(scale_factor).clip(min=min_scale_factor) # type: ignore
|
||||
scale_factor = np.array(scale_factor).clip(min=min_scale_factor)
|
||||
self.apply_points_function(
|
||||
lambda points: scale_factor * points,
|
||||
about_point=about_point,
|
||||
|
|
@ -2690,7 +2628,7 @@ class OpenGLMobject:
|
|||
def is_aligned_with(self, mobject: OpenGLMobject) -> bool:
|
||||
return len(self.submobjects) == len(mobject.submobjects) and all(
|
||||
sm1.is_aligned_with(sm2)
|
||||
for sm1, sm2 in zip(self.submobjects, mobject.submobjects)
|
||||
for sm1, sm2 in zip(self.submobjects, mobject.submobjects, strict=False)
|
||||
)
|
||||
|
||||
def align_data_and_family(self, mobject):
|
||||
|
|
@ -2875,7 +2813,7 @@ class OpenGLMobject:
|
|||
self.align_family(mobject)
|
||||
family1 = self.get_family()
|
||||
family2 = mobject.get_family()
|
||||
for sm1, sm2 in zip(family1, family2):
|
||||
for sm1, sm2 in zip(family1, family2, strict=False):
|
||||
sm1.depth_test = sm2.depth_test
|
||||
sm1.points = (
|
||||
sm2.points
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ class OpenGLVMobject(OpenGLMobject):
|
|||
def _assert_valid_submobjects(self, submobjects: Iterable[OpenGLVMobject]) -> Self:
|
||||
return self._assert_valid_submobjects_internal(submobjects, OpenGLVMobject)
|
||||
|
||||
def get_group_class(self) -> type[OpenGLVGroup]: # type: ignore
|
||||
def get_group_class(self) -> type[OpenGLVGroup]:
|
||||
return OpenGLVGroup
|
||||
|
||||
@staticmethod
|
||||
|
|
@ -135,21 +135,21 @@ class OpenGLVMobject(OpenGLMobject):
|
|||
|
||||
# These are here just to make type checkers happy
|
||||
def get_family(self, recurse: bool = True) -> Sequence[OpenGLVMobject]:
|
||||
return super().get_family(recurse) # type: ignore
|
||||
return super().get_family(recurse)
|
||||
|
||||
def family_members_with_points(self) -> Sequence[OpenGLVMobject]: # type: ignore
|
||||
return super().family_members_with_points() # type: ignore
|
||||
def family_members_with_points(self) -> Sequence[OpenGLVMobject]:
|
||||
return super().family_members_with_points()
|
||||
|
||||
def replicate(self, n: int) -> OpenGLVGroup: # type: ignore
|
||||
return super().replicate(n) # type: ignore
|
||||
def replicate(self, n: int) -> OpenGLVGroup:
|
||||
return super().replicate(n)
|
||||
|
||||
def get_grid(self, *args, **kwargs) -> OpenGLVGroup: # type: ignore
|
||||
return super().get_grid(*args, **kwargs) # type: ignore
|
||||
def get_grid(self, *args, **kwargs) -> OpenGLVGroup:
|
||||
return super().get_grid(*args, **kwargs)
|
||||
|
||||
def __getitem__(self, value: int | slice) -> Self: # type: ignore
|
||||
return super().__getitem__(value) # type: ignore
|
||||
def __getitem__(self, value: int | slice) -> Self:
|
||||
return super().__getitem__(value)
|
||||
|
||||
def add(self, *vmobjects: OpenGLVMobject) -> Self: # type: ignore
|
||||
def add(self, *vmobjects: OpenGLVMobject) -> Self:
|
||||
return super().add(*vmobjects)
|
||||
|
||||
# Colors
|
||||
|
|
@ -868,7 +868,7 @@ class OpenGLVMobject(OpenGLMobject):
|
|||
curve = self.get_nth_curve_function(n)
|
||||
points = np.array([curve(a) for a in np.linspace(0, 1, sample_points)])
|
||||
diffs = points[1:] - points[:-1]
|
||||
norms = np.apply_along_axis(np.linalg.norm, 1, diffs) # type: ignore
|
||||
norms = np.apply_along_axis(np.linalg.norm, 1, diffs)
|
||||
|
||||
return norms
|
||||
|
||||
|
|
@ -1279,7 +1279,8 @@ class OpenGLVMobject(OpenGLMobject):
|
|||
attr2 = getattr(mobject2, attr)
|
||||
if isinstance(attr1, list) or isinstance(attr2, list):
|
||||
result = [
|
||||
interp(elem1, elem2, alpha) for elem1, elem2 in zip(attr1, attr2)
|
||||
interp(elem1, elem2, alpha)
|
||||
for elem1, elem2 in zip(attr1, attr2, strict=False)
|
||||
]
|
||||
else:
|
||||
result = interp(attr1, attr2, alpha)
|
||||
|
|
@ -1573,7 +1574,7 @@ class OpenGLVGroup(OpenGLVMobject):
|
|||
>>> config.renderer = original_renderer
|
||||
"""
|
||||
self._assert_valid_submobjects(tuplify(value))
|
||||
self.submobjects[key] = value # type: ignore
|
||||
self.submobjects[key] = value
|
||||
self.note_changed_family()
|
||||
|
||||
|
||||
|
|
@ -1704,7 +1705,9 @@ class VHighlight(OpenGLVGroup):
|
|||
outline.set_fill(opacity=0)
|
||||
added_widths = np.linspace(0, max_stroke_addition, n_layers + 1)[1:]
|
||||
colors = color_gradient(color_bounds, n_layers)
|
||||
for part, added_width, color in zip(reversed(outline), added_widths, colors):
|
||||
for part, added_width, color in zip(
|
||||
reversed(outline), added_widths, colors, strict=False
|
||||
):
|
||||
for sm in part.family_members_with_points():
|
||||
sm.set_stroke(
|
||||
width=sm.get_stroke_width() + added_width,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue