[Experimental] Use OpenGLMobject as Mobject and similar imports everywhere (#4578)

* Use 'OpenGLMobject as Mobject' and similar imports everywhere

* Remove commented Mobject imports

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Revert accidental renaming of OpenGLMobject to Mobject and duplicated .set_default() - now the example scene works again

* Fix CurvesAsSubmobjects and DashedVMobject imports

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Temporarily solve issue in _add_intrinsic_animation_overrides()

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
Francisco Manríquez Novoa 2026-02-12 19:59:50 -03:00 committed by GitHub
commit 186ad964bb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
56 changed files with 939 additions and 439 deletions

View file

@ -10,12 +10,17 @@ from typing import TYPE_CHECKING, Any, Self, assert_never, cast, overload
import numpy as np
from typing_extensions import TypeVar
from manim.mobject.opengl.opengl_mobject import OpenGLMobject
from manim.mobject.opengl.opengl_mobject import (
OpenGLGroup as Group,
)
from manim.mobject.opengl.opengl_mobject import (
OpenGLMobject as Mobject,
)
from manim.mobject.opengl.opengl_mobject import (
_AnimationBuilder,
)
from .. import logger
from ..mobject import mobject
from ..mobject.mobject import Group, Mobject
from ..mobject.opengl import opengl_mobject
from ..utils.rate_functions import linear, smooth
from .protocol import AnimationProtocol, MobjectAnimation
from .scene_buffer import SceneBuffer, SceneOperation
@ -25,7 +30,7 @@ if TYPE_CHECKING:
from manim.scene.scene import Scene
M = TypeVar("M", bound=OpenGLMobject)
M = TypeVar("M", bound=Mobject)
__all__ = ["Animation", "Wait", "override_animation"]
@ -135,7 +140,7 @@ class Animation(AnimationProtocol):
def __init__(
self,
mobject: OpenGLMobject | None,
mobject: Mobject | None,
lag_ratio: float = DEFAULT_ANIMATION_LAG_RATIO,
run_time: float = DEFAULT_ANIMATION_RUN_TIME,
rate_func: Callable[[float], float] = smooth,
@ -162,10 +167,8 @@ class Animation(AnimationProtocol):
self.buffer = SceneBuffer()
self.apply_buffer = False # ask scene to apply buffer
self.starting_mobject: OpenGLMobject = OpenGLMobject()
self.mobject: OpenGLMobject = (
mobject if mobject is not None else OpenGLMobject()
)
self.starting_mobject: Mobject = Mobject()
self.mobject: Mobject = mobject if mobject is not None else Mobject()
if hasattr(self, "CONFIG"):
logger.error(
@ -191,7 +194,7 @@ class Animation(AnimationProtocol):
def _typecheck_input(self, mobject: Mobject | None) -> None:
if mobject is None:
logger.debug("Animation with empty mobject")
elif not isinstance(mobject, (Mobject, OpenGLMobject)):
elif not isinstance(mobject, Mobject):
raise TypeError("Animation only works on Mobjects")
def __str__(self) -> str:
@ -252,11 +255,11 @@ class Animation(AnimationProtocol):
if self.remover:
self.buffer.remove(self.mobject)
def create_starting_mobject(self) -> OpenGLMobject:
def create_starting_mobject(self) -> Mobject:
# Keep track of where the mobject starts
return self.mobject.copy()
def get_all_mobjects(self) -> Sequence[OpenGLMobject]:
def get_all_mobjects(self) -> Sequence[Mobject]:
"""Get all mobjects involved in the animation.
Ordering must match the ordering of arguments to interpolate_submobject
@ -299,7 +302,7 @@ class Animation(AnimationProtocol):
assert_never(op)
buffer.clear()
def get_all_mobjects_to_update(self) -> Sequence[OpenGLMobject]:
def get_all_mobjects_to_update(self) -> Sequence[Mobject]:
"""Get all mobjects to be updated during the animation.
Returns
@ -342,8 +345,8 @@ class Animation(AnimationProtocol):
def interpolate_submobject(
self,
submobject: OpenGLMobject,
starting_submobject: OpenGLMobject,
submobject: Mobject,
starting_submobject: Mobject,
# target_copy: Mobject, #Todo: fix - signature of interpolate_submobject differs in Transform().
alpha: float,
) -> Animation:
@ -515,16 +518,12 @@ def prepare_animation(anim: MobjectAnimation[M]) -> MobjectAnimation[M]: ...
@overload
def prepare_animation(
anim: AnimationProtocol
| opengl_mobject._AnimationBuilder
| opengl_mobject.OpenGLMobject,
anim: AnimationProtocol | _AnimationBuilder | Mobject,
) -> AnimationProtocol: ...
def prepare_animation(
anim: AnimationProtocol
| opengl_mobject._AnimationBuilder
| opengl_mobject.OpenGLMobject,
anim: AnimationProtocol | _AnimationBuilder | Mobject,
) -> AnimationProtocol:
r"""Returns either an unchanged animation, or the animation built
from a passed animation factory.
@ -552,7 +551,7 @@ def prepare_animation(
TypeError: Object 42 cannot be converted to an animation
"""
if isinstance(anim, (mobject._AnimationBuilder, opengl_mobject._AnimationBuilder)):
if isinstance(anim, _AnimationBuilder):
return anim.build()
# if it has these three methods it probably is an AnimationProtocol

View file

@ -9,7 +9,6 @@ from typing import TYPE_CHECKING, Any, Self
import numpy as np
from manim.mobject.mobject import Mobject
from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL
from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVGroup as VGroup
from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVMobject as VMobject
from manim.utils.color import (
@ -109,7 +108,7 @@ class AnimatedBoundary(VGroup):
return self
class TracedPath(VMobject, metaclass=ConvertToOpenGL):
class TracedPath(VMobject):
"""Traces the path of a point returned by a function call.
Parameters

View file

@ -7,18 +7,19 @@ from typing import TYPE_CHECKING, Any
import numpy as np
from manim._config import config
from manim.animation.animation import Animation, prepare_animation
from manim.constants import RendererType
from manim.mobject.mobject import Group, Mobject
from manim.mobject.opengl.opengl_mobject import OpenGLGroup, OpenGLMobject
from manim.mobject.opengl.opengl_mobject import (
OpenGLGroup as Group,
)
from manim.mobject.opengl.opengl_mobject import (
OpenGLMobject as Mobject,
)
from manim.utils.iterables import remove_list_redundancies
from manim.utils.parameter_parsing import flatten_iterable_parameters
from manim.utils.rate_functions import linear
if TYPE_CHECKING:
from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVGroup
from manim.mobject.types.vectorized_mobject import VGroup
from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVGroup as VGroup
__all__ = ["AnimationGroup", "Succession", "LaggedStart", "LaggedStartMap"]
@ -53,7 +54,7 @@ class AnimationGroup(Animation):
def __init__(
self,
*animations: Animation | Iterable[Animation],
group: Group | VGroup | OpenGLGroup | OpenGLVGroup | None = None,
group: Group | VGroup | None = None,
run_time: float | None = None,
rate_func: Callable[[float], float] = linear,
lag_ratio: float = 0,
@ -67,12 +68,7 @@ class AnimationGroup(Animation):
mobjects = remove_list_redundancies(
[anim.mobject for anim in self.animations if not anim.introducer],
)
if config["renderer"] == RendererType.OPENGL:
self.group: Group | VGroup | OpenGLGroup | OpenGLVGroup = OpenGLGroup(
*mobjects
)
else:
self.group = Group(*mobjects)
self.group = Group(*mobjects)
else:
self.group = group
super().__init__(
@ -80,7 +76,7 @@ class AnimationGroup(Animation):
)
self.run_time: float = self.init_run_time(run_time)
def get_all_mobjects(self) -> Sequence[Mobject | OpenGLMobject]:
def get_all_mobjects(self) -> Sequence[Mobject]:
return list(self.group)
def begin(self) -> None:

View file

@ -89,7 +89,6 @@ if TYPE_CHECKING:
from manim.constants import RIGHT, TAU
from manim.mobject.opengl.opengl_surface import OpenGLSurface
from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVMobject
from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVMobject as VMobject
from manim.utils.color import ManimColor
from manim.utils.space_ops import rotate_vector
@ -97,8 +96,12 @@ from manim.utils.space_ops import rotate_vector
from .. import config
from ..animation.animation import Animation
from ..animation.composition import Succession
from ..mobject.mobject import Group
from ..mobject.opengl.opengl_mobject import OpenGLMobject
from ..mobject.opengl.opengl_mobject import (
OpenGLGroup as Group,
)
from ..mobject.opengl.opengl_mobject import (
OpenGLMobject as Mobject,
)
from ..utils.bezier import integer_interpolate
from ..utils.rate_functions import double_smooth, linear
@ -117,11 +120,7 @@ class ShowPartial(Animation):
"""
def __init__(
self,
mobject: VMobject | OpenGLVMobject | OpenGLSurface | None,
**kwargs,
):
def __init__(self, mobject: VMobject | OpenGLSurface | None, **kwargs: Any):
pointwise = getattr(mobject, "pointwise_become_partial", None)
if not callable(pointwise):
raise TypeError(f"{self.__class__.__name__} only works for VMobjects.")
@ -129,8 +128,8 @@ class ShowPartial(Animation):
def interpolate_submobject(
self,
submobject: OpenGLMobject,
starting_submobject: OpenGLMobject,
submobject: Mobject,
starting_submobject: Mobject,
alpha: float,
) -> Self:
submobject.pointwise_become_partial(
@ -171,7 +170,7 @@ class Create(ShowPartial):
def __init__(
self,
mobject: VMobject | OpenGLVMobject | OpenGLSurface,
mobject: VMobject | OpenGLSurface,
lag_ratio: float = 1.0,
introducer: bool = True,
**kwargs,
@ -201,7 +200,7 @@ class Uncreate(Create):
def __init__(
self,
mobject: VMobject | OpenGLVMobject,
mobject: VMobject,
reverse_rate_function: bool = True,
remover: bool = True,
**kwargs,
@ -229,7 +228,7 @@ class DrawBorderThenFill(Animation):
def __init__(
self,
vmobject: VMobject | OpenGLVMobject,
vmobject: VMobject,
run_time: float = 2,
rate_func: Callable[[float], float] = double_smooth,
stroke_width: float = 2,
@ -251,8 +250,8 @@ class DrawBorderThenFill(Animation):
self.stroke_color = stroke_color
self.outline = self.get_outline()
def _typecheck_input(self, vmobject: OpenGLVMobject) -> None:
if not isinstance(vmobject, OpenGLVMobject):
def _typecheck_input(self, vmobject: VMobject) -> None:
if not isinstance(vmobject, VMobject):
raise TypeError(
f"{self.__class__.__name__} only works for vectorized Mobjects"
)
@ -263,28 +262,28 @@ class DrawBorderThenFill(Animation):
self.outline = self.get_outline()
super().begin()
def get_outline(self) -> OpenGLMobject:
def get_outline(self) -> Mobject:
outline = self.mobject.copy()
outline.set_fill(opacity=0)
for sm in outline.family_members_with_points():
sm.set_stroke(color=self.get_stroke_color(sm), width=self.stroke_width)
return outline
def get_stroke_color(self, vmobject: VMobject | OpenGLVMobject) -> ManimColor:
def get_stroke_color(self, vmobject: VMobject) -> ManimColor:
if self.stroke_color:
return self.stroke_color
elif vmobject.get_stroke_width() > 0:
return vmobject.get_stroke_color()
return vmobject.get_color()
def get_all_mobjects(self) -> Sequence[OpenGLMobject]:
def get_all_mobjects(self) -> Sequence[Mobject]:
return [*super().get_all_mobjects(), self.outline]
def interpolate_submobject(
self,
submobject: OpenGLMobject,
starting_submobject: OpenGLMobject,
outline: OpenGLMobject,
submobject: Mobject,
starting_submobject: Mobject,
outline: Mobject,
alpha: float,
) -> None:
index: int
@ -326,7 +325,7 @@ class Write(DrawBorderThenFill):
def __init__(
self,
vmobject: VMobject | OpenGLVMobject,
vmobject: VMobject,
rate_func: Callable[[float], float] = linear,
reverse: bool = False,
run_time: float | None = None,
@ -352,7 +351,7 @@ class Write(DrawBorderThenFill):
def _set_default_config_from_length(
self,
vmobject: VMobject | OpenGLVMobject,
vmobject: VMobject,
run_time: float | None,
lag_ratio: float | None,
) -> tuple[float, float]:
@ -456,7 +455,7 @@ class SpiralIn(Animation):
def __init__(
self,
shapes: OpenGLMobject,
shapes: Mobject,
scale_factor: float = 8,
fade_in_fraction: float = 0.3,
**kwargs: Any,
@ -515,7 +514,7 @@ class ShowIncreasingSubsets(Animation):
def __init__(
self,
group: OpenGLMobject,
group: Mobject,
suspend_mobject_updating: bool = False,
int_func: Callable[[np.ndarray], np.ndarray] = np.floor,
reverse_rate_function=False,
@ -643,7 +642,7 @@ class ShowSubmobjectsOneByOne(ShowIncreasingSubsets):
def __init__(
self,
group: Iterable[OpenGLMobject],
group: Iterable[Mobject],
int_func: Callable[[np.ndarray], np.ndarray] = np.ceil,
**kwargs,
) -> None:
@ -728,7 +727,7 @@ class TypeWithCursor(AddTextLetterByLetter):
def __init__(
self,
text: Text,
cursor: OpenGLMobject,
cursor: Mobject,
buff: float = 0.1,
keep_cursor_y: bool = True,
leave_cursor_on: bool = True,

View file

@ -23,15 +23,19 @@ from typing import Any
import numpy as np
from manim.mobject.opengl.opengl_mobject import OpenGLMobject
from manim.mobject.opengl.opengl_mobject import (
OpenGLGroup as Group,
)
from manim.mobject.opengl.opengl_mobject import (
OpenGLMobject as Mobject,
)
from ..animation.transform import Transform
from ..constants import ORIGIN
from ..mobject.mobject import Group
class _Fade(Transform):
"""Fade :class:`~.OpenGLMobject` s in or out.
"""Fade :class:`~.Mobject` s in or out.
Parameters
----------
@ -50,9 +54,9 @@ class _Fade(Transform):
def __init__(
self,
*mobjects: OpenGLMobject,
*mobjects: Mobject,
shift: np.ndarray | None = None,
target_position: np.ndarray | OpenGLMobject | None = None,
target_position: np.ndarray | Mobject | None = None,
scale: float = 1,
**kwargs: Any,
) -> None:
@ -63,7 +67,7 @@ class _Fade(Transform):
self.point_target = False
if shift is None:
if target_position is not None:
if isinstance(target_position, OpenGLMobject):
if isinstance(target_position, Mobject):
target_position = target_position.get_center()
shift = target_position - mobject.get_center()
self.point_target = True
@ -73,7 +77,7 @@ class _Fade(Transform):
self.scale_factor = scale
super().__init__(mobject, **kwargs)
def _create_faded_mobject(self, fade_in: bool) -> OpenGLMobject:
def _create_faded_mobject(self, fade_in: bool) -> Mobject:
"""Create a faded, shifted and scaled copy of the mobject.
Parameters
@ -83,7 +87,7 @@ class _Fade(Transform):
Returns
-------
OpenGLMobject
Mobject
The faded, shifted and scaled copy of the mobject.
"""
faded_mobject: Mobject = self.mobject.copy() # type: ignore[assignment]
@ -95,7 +99,7 @@ class _Fade(Transform):
class FadeIn(_Fade):
r"""Fade in :class:`~.OpenGLMobject` s.
r"""Fade in :class:`~.Mobject` s.
Parameters
----------
@ -132,18 +136,18 @@ class FadeIn(_Fade):
"""
def __init__(self, *mobjects: OpenGLMobject, **kwargs: Any) -> None:
def __init__(self, *mobjects: Mobject, **kwargs: Any) -> None:
super().__init__(*mobjects, introducer=True, **kwargs)
def create_target(self) -> OpenGLMobject:
def create_target(self) -> Mobject:
return self.mobject
def create_starting_mobject(self) -> OpenGLMobject:
def create_starting_mobject(self) -> Mobject:
return self._create_faded_mobject(fade_in=True)
class FadeOut(_Fade):
r"""Fade out :class:`~.OpenGLMobject` s.
r"""Fade out :class:`~.Mobject` s.
Parameters
----------
@ -180,10 +184,10 @@ class FadeOut(_Fade):
"""
def __init__(self, *mobjects: OpenGLMobject, **kwargs: Any) -> None:
def __init__(self, *mobjects: Mobject, **kwargs: Any) -> None:
super().__init__(*mobjects, remover=True, **kwargs)
def create_target(self) -> OpenGLMobject:
def create_target(self) -> Mobject:
return self._create_faded_mobject(fade_in=False)
def begin(self) -> None:

View file

@ -39,7 +39,7 @@ from ..utils.paths import spiral_path
if TYPE_CHECKING:
from manim.mobject.geometry.line import Arrow
from manim.mobject.opengl.opengl_mobject import OpenGLMobject
from manim.mobject.opengl.opengl_mobject import OpenGLMobject as Mobject
from manim.typing import Point3DLike, Vector3DLike
from manim.utils.color import ParsableManimColor
@ -87,10 +87,10 @@ class GrowFromPoint(Transform):
self.point_color = point_color
super().__init__(mobject, introducer=True, **kwargs)
def create_target(self) -> Mobject | OpenGLMobject:
def create_target(self) -> Mobject:
return self.mobject
def create_starting_mobject(self) -> Mobject | OpenGLMobject:
def create_starting_mobject(self) -> Mobject:
start = super().create_starting_mobject()
start.scale(0)
start.move_to(self.point)
@ -203,7 +203,7 @@ class GrowArrow(GrowFromPoint):
point = arrow.get_start()
super().__init__(arrow, point, point_color=point_color, **kwargs)
def create_starting_mobject(self) -> Mobject | OpenGLMobject:
def create_starting_mobject(self) -> Mobject:
start_arrow = self.mobject.copy()
start_arrow.scale(0, scale_tips=True, about_point=self.point)
if self.point_color:

View file

@ -48,7 +48,7 @@ from manim.mobject.geometry.arc import Circle, Dot
from manim.mobject.geometry.line import Line
from manim.mobject.geometry.polygram import Rectangle
from manim.mobject.geometry.shape_matchers import SurroundingRectangle
from manim.mobject.opengl.opengl_mobject import OpenGLMobject
from manim.mobject.opengl.opengl_mobject import OpenGLMobject as Mobject
from .. import config
from ..animation.animation import Animation
@ -59,8 +59,12 @@ from ..animation.movement import Homotopy
from ..animation.transform import Transform
from ..animation.updaters.update import UpdateFromFunc
from ..constants import *
from ..mobject.mobject import Mobject
from ..mobject.types.vectorized_mobject import VGroup, VMobject
from ..mobject.opengl.opengl_vectorized_mobject import (
OpenGLVGroup as VGroup,
)
from ..mobject.opengl.opengl_vectorized_mobject import (
OpenGLVMobject as VMobject,
)
from ..typing import Point3D, Point3DLike, Vector3DLike
from ..utils.bezier import interpolate, inverse_interpolate
from ..utils.color import GREY, YELLOW, ParsableManimColor
@ -150,7 +154,7 @@ class Indicate(Transform):
def __init__(
self,
mobject: OpenGLMobject,
mobject: Mobject,
scale_factor: float = 1.2,
color: ParsableManimColor = YELLOW,
rate_func: RateFunction = there_and_back,
@ -160,7 +164,7 @@ class Indicate(Transform):
self.scale_factor = scale_factor
super().__init__(mobject, rate_func=rate_func, **kwargs)
def create_target(self) -> OpenGLMobject:
def create_target(self) -> Mobject:
target = self.mobject.copy()
target.scale(self.scale_factor)
target.set_color(self.color)

View file

@ -5,12 +5,12 @@ from typing import TYPE_CHECKING, Protocol
from typing_extensions import TypeVar
if TYPE_CHECKING:
from manim.mobject.opengl.opengl_mobject import OpenGLMobject
from manim.mobject.opengl.opengl_mobject import OpenGLMobject as Mobject
from manim.utils.rate_functions import RateFunction
from .scene_buffer import SceneBuffer
M = TypeVar("M", bound="OpenGLMobject", default="OpenGLMobject")
M = TypeVar("M", bound="Mobject", default="Mobject")
__all__ = ("AnimationProtocol",)

View file

@ -11,7 +11,7 @@ from manim.constants import ORIGIN, OUT, PI, TAU
from manim.utils.rate_functions import RateFunction, linear
if TYPE_CHECKING:
from manim.mobject.opengl.opengl_mobject import OpenGLMobject
from manim.mobject.opengl.opengl_mobject import OpenGLMobject as Mobject
from manim.typing import Point3DLike, Vector3DLike
from manim.utils.rate_functions import RateFunction
@ -85,7 +85,7 @@ class Rotating(Animation):
def __init__(
self,
mobject: OpenGLMobject,
mobject: Mobject,
angle: float = TAU,
axis: Vector3DLike = OUT,
about_point: Point3DLike | None = None,
@ -163,7 +163,7 @@ class Rotate(Rotating):
def __init__(
self,
mobject: OpenGLMobject,
mobject: Mobject,
angle: float = PI,
axis: Vector3DLike = OUT,
run_time: float = 1,

View file

@ -5,7 +5,7 @@ from enum import Enum
from typing import TYPE_CHECKING, Any
if TYPE_CHECKING:
from manim.mobject.opengl.opengl_mobject import OpenGLMobject
from manim.mobject.opengl.opengl_mobject import OpenGLMobject as Mobject
__all__ = ["SceneBuffer", "SceneOperation"]
@ -48,20 +48,18 @@ class SceneBuffer:
def __init__(self) -> None:
self.operations: list[
tuple[SceneOperation, Sequence[OpenGLMobject], dict[str, Any]]
tuple[SceneOperation, Sequence[Mobject], dict[str, Any]]
] = []
def add(self, *mobs: OpenGLMobject, **kwargs: Any) -> None:
def add(self, *mobs: Mobject, **kwargs: Any) -> None:
"""Add mobjects to the scene."""
self.operations.append((SceneOperation.ADD, mobs, kwargs))
def remove(self, *mobs: OpenGLMobject, **kwargs: Any) -> None:
def remove(self, *mobs: Mobject, **kwargs: Any) -> None:
"""Remove mobjects from the scene."""
self.operations.append((SceneOperation.REMOVE, mobs, kwargs))
def replace(
self, mob: OpenGLMobject, *replacements: OpenGLMobject, **kwargs: Any
) -> None:
def replace(self, mob: Mobject, *replacements: Mobject, **kwargs: Any) -> None:
"""Replace a ``mob`` with ``replacements`` on the scene."""
self.operations.append((SceneOperation.REPLACE, (mob, *replacements), kwargs))
@ -77,5 +75,5 @@ class SceneBuffer:
def __iter__(
self,
) -> Iterator[tuple[SceneOperation, Sequence[OpenGLMobject], dict[str, Any]]]:
) -> Iterator[tuple[SceneOperation, Sequence[Mobject], dict[str, Any]]]:
return iter(self.operations)

View file

@ -36,7 +36,12 @@ from typing import TYPE_CHECKING, Any
import numpy as np
from manim.data_structures import MethodWithArgs
from manim.mobject.opengl.opengl_mobject import OpenGLMobject
from manim.mobject.opengl.opengl_mobject import (
OpenGLGroup as Group,
)
from manim.mobject.opengl.opengl_mobject import (
OpenGLMobject as Mobject,
)
from ..animation.animation import Animation
from ..constants import (
@ -45,7 +50,6 @@ from ..constants import (
ORIGIN,
OUT,
)
from ..mobject.mobject import Group, Mobject
from ..utils.paths import path_along_arc, path_along_circles
from ..utils.rate_functions import smooth, squish_rate_func
@ -132,8 +136,8 @@ class Transform(Animation):
def __init__(
self,
mobject: OpenGLMobject | None,
target_mobject: OpenGLMobject | None = None,
mobject: Mobject | None,
target_mobject: Mobject | None = None,
path_func: Callable | None = None,
path_arc: float = 0,
path_arc_axis: np.ndarray = OUT,
@ -158,8 +162,8 @@ class Transform(Animation):
self.replace_mobject_with_target_in_scene: bool = (
replace_mobject_with_target_in_scene
)
self.target_mobject: OpenGLMobject = (
target_mobject if target_mobject is not None else OpenGLMobject()
self.target_mobject: Mobject = (
target_mobject if target_mobject is not None else Mobject()
)
super().__init__(mobject, **kwargs)
@ -196,7 +200,7 @@ class Transform(Animation):
super().begin()
def create_target(self) -> OpenGLMobject:
def create_target(self) -> Mobject:
# Has no meaningful effect here, but may be useful
# in subclasses
return self.target_mobject
@ -206,7 +210,7 @@ class Transform(Animation):
if self.replace_mobject_with_target_in_scene:
self.buffer.replace(self.mobject, self.target_mobject)
def get_all_mobjects(self) -> Sequence[OpenGLMobject]:
def get_all_mobjects(self) -> Sequence[Mobject]:
return [
self.mobject,
self.starting_mobject,
@ -214,9 +218,7 @@ class Transform(Animation):
self.target_copy,
]
def get_all_families_zipped(
self,
) -> zip[tuple[OpenGLMobject, OpenGLMobject, OpenGLMobject]]:
def get_all_families_zipped(self) -> zip[tuple[Mobject, Mobject, Mobject]]:
mobs = [
self.mobject,
self.starting_mobject,
@ -226,9 +228,9 @@ class Transform(Animation):
def interpolate_submobject(
self,
submobject: OpenGLMobject,
starting_submobject: OpenGLMobject,
target_copy: OpenGLMobject,
submobject: Mobject,
starting_submobject: Mobject,
target_copy: Mobject,
alpha: float,
) -> Transform:
submobject.interpolate(starting_submobject, target_copy, alpha, self.path_func)
@ -283,9 +285,7 @@ class ReplacementTransform(Transform):
"""
def __init__(
self, mobject: OpenGLMobject, target_mobject: OpenGLMobject, **kwargs
) -> None:
def __init__(self, mobject: Mobject, target_mobject: Mobject, **kwargs) -> None:
super().__init__(
mobject, target_mobject, replace_mobject_with_target_in_scene=True, **kwargs
)
@ -294,9 +294,7 @@ class ReplacementTransform(Transform):
class TransformFromCopy(Transform):
"""Performs a reversed Transform"""
def __init__(
self, mobject: OpenGLMobject, target_mobject: OpenGLMobject, **kwargs
) -> None:
def __init__(self, mobject: Mobject, target_mobject: Mobject, **kwargs) -> None:
super().__init__(target_mobject, mobject, **kwargs)
def interpolate(self, alpha: float) -> None:
@ -335,8 +333,8 @@ class ClockwiseTransform(Transform):
def __init__(
self,
mobject: OpenGLMobject,
target_mobject: OpenGLMobject,
mobject: Mobject,
target_mobject: Mobject,
path_arc: float = -np.pi,
**kwargs,
) -> None:
@ -384,8 +382,8 @@ class CounterclockwiseTransform(Transform):
def __init__(
self,
mobject: OpenGLMobject,
target_mobject: OpenGLMobject,
mobject: Mobject,
target_mobject: Mobject,
path_arc: float = np.pi,
**kwargs,
) -> None:
@ -418,11 +416,11 @@ class MoveToTarget(Transform):
"""
def __init__(self, mobject: OpenGLMobject, **kwargs) -> None:
def __init__(self, mobject: Mobject, **kwargs) -> None:
self.check_validity_of_input(mobject)
super().__init__(mobject, mobject.target, **kwargs)
def check_validity_of_input(self, mobject: OpenGLMobject) -> None:
def check_validity_of_input(self, mobject: Mobject) -> None:
if not hasattr(mobject, "target"):
raise ValueError(
"MoveToTarget called on mobjectwithout attribute 'target'",
@ -473,9 +471,9 @@ class ApplyMethod(Transform):
"Whoops, looks like you accidentally invoked "
"the method you want to animate",
)
assert isinstance(method.__self__, (Mobject, OpenGLMobject))
assert isinstance(method.__self__, Mobject)
def create_target(self) -> OpenGLMobject:
def create_target(self) -> Mobject:
method = self.method
# Make sure it's a list so that args.pop() works
args = list(self.method_args)
@ -521,9 +519,7 @@ class ApplyPointwiseFunction(ApplyMethod):
class ApplyPointwiseFunctionToCenter(ApplyPointwiseFunction):
def __init__(
self, function: types.MethodType, mobject: OpenGLMobject, **kwargs
) -> None:
def __init__(self, function: types.MethodType, mobject: Mobject, **kwargs) -> None:
self.function = function
super().__init__(mobject.move_to, **kwargs)
@ -613,15 +609,13 @@ class Restore(ApplyMethod):
class ApplyFunction(Transform):
def __init__(
self, function: types.MethodType, mobject: OpenGLMobject, **kwargs
) -> None:
def __init__(self, function: types.MethodType, mobject: Mobject, **kwargs) -> None:
self.function = function
super().__init__(mobject, **kwargs)
def create_target(self) -> Any:
target = self.function(self.mobject.copy())
if not isinstance(target, (Mobject, OpenGLMobject)):
if not isinstance(target, Mobject):
raise TypeError(
"Functions passed to ApplyFunction must return object of type Mobject",
)

View file

@ -7,13 +7,21 @@ __all__ = ["TransformMatchingShapes", "TransformMatchingTex"]
import numpy as np
from manim.mobject.opengl.opengl_mobject import OpenGLGroup, OpenGLMobject
from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVGroup, OpenGLVMobject
from manim.mobject.opengl.opengl_mobject import (
OpenGLGroup as Group,
)
from manim.mobject.opengl.opengl_mobject import (
OpenGLMobject as Mobject,
)
from manim.mobject.opengl.opengl_vectorized_mobject import (
OpenGLVGroup as VGroup,
)
from manim.mobject.opengl.opengl_vectorized_mobject import (
OpenGLVMobject as VMobject,
)
from .._config import config
from ..constants import RendererType
from ..mobject.mobject import Group, Mobject
from ..mobject.types.vectorized_mobject import VGroup, VMobject
from .composition import AnimationGroup
from .fading import FadeIn, FadeOut
from .transform import FadeTransformPieces, Transform
@ -72,11 +80,7 @@ class TransformMatchingAbstractBase(AnimationGroup):
key_map: dict | None = None,
**kwargs,
):
if isinstance(mobject, OpenGLVMobject):
group_type = OpenGLVGroup
elif isinstance(mobject, OpenGLMobject):
group_type = OpenGLGroup
elif isinstance(mobject, VMobject):
if isinstance(mobject, VMobject):
group_type = VGroup
else:
group_type = Group
@ -279,7 +283,7 @@ class TransformMatchingTex(TransformMatchingAbstractBase):
@staticmethod
def get_mobject_parts(mobject: Mobject) -> list[Mobject]:
if isinstance(mobject, (Group, VGroup, OpenGLGroup, OpenGLVGroup)):
if isinstance(mobject, (Group, VGroup)):
return [
p
for s in mobject.submobjects

View file

@ -17,7 +17,7 @@ from typing import TYPE_CHECKING, Any, TypeVar, cast
import numpy as np
from manim.mobject.opengl.opengl_mobject import OpenGLMobject
from manim.mobject.opengl.opengl_mobject import OpenGLMobject as Mobject
if TYPE_CHECKING:
import types
@ -30,13 +30,13 @@ if TYPE_CHECKING:
P = ParamSpec("P")
M = TypeVar("M", bound=OpenGLMobject)
M = TypeVar("M", bound=Mobject)
# TODO: figure out how to typehint as MethodType[OpenGLMobject] to avoid the cast
# TODO: figure out how to typehint as MethodType[Mobject] to avoid the cast
# madness in always/f_always
def is_mobject_method(method: Callable[..., Any]) -> TypeIs[types.MethodType]:
return inspect.ismethod(method) and isinstance(method.__self__, OpenGLMobject)
return inspect.ismethod(method) and isinstance(method.__self__, Mobject)
def always(

View file

@ -12,7 +12,7 @@ from typing import TYPE_CHECKING, Any
from manim.animation.animation import Animation
if TYPE_CHECKING:
from manim.mobject.opengl.opengl_mobject import OpenGLMobject
from manim.mobject.opengl.opengl_mobject import OpenGLMobject as Mobject
class UpdateFromFunc(Animation):
@ -24,8 +24,8 @@ class UpdateFromFunc(Animation):
def __init__(
self,
mobject: OpenGLMobject,
update_function: Callable[[OpenGLMobject], object],
mobject: Mobject,
update_function: Callable[[Mobject], object],
suspend_mobject_updating: bool = False,
**kwargs: Any,
) -> None:
@ -45,7 +45,7 @@ class UpdateFromAlphaFunc(UpdateFromFunc):
class MaintainPositionRelativeTo(Animation):
def __init__(
self, mobject: OpenGLMobject, tracked_mobject: OpenGLMobject, **kwargs: Any
self, mobject: Mobject, tracked_mobject: Mobject, **kwargs: Any
) -> None:
self.tracked_mobject = tracked_mobject
self.diff = op.sub(

View file

@ -10,7 +10,8 @@ import numpy.typing as npt
from manim._config import config, logger
from manim.constants import *
from manim.mobject.opengl.opengl_mobject import InvisibleMobject, OpenGLMobject
from manim.mobject.opengl.opengl_mobject import InvisibleMobject
from manim.mobject.opengl.opengl_mobject import OpenGLMobject as Mobject
from manim.utils.paths import straight_path
from manim.utils.space_ops import rotation_matrix
@ -26,10 +27,10 @@ class CameraOrientationConfig(TypedDict, total=False):
gamma: float | None
zoom: float | None
focal_distance: float | None
frame_center: OpenGLMobject | Sequence[float] | None
frame_center: Mobject | Sequence[float] | None
class Camera(OpenGLMobject, InvisibleMobject):
class Camera(Mobject, InvisibleMobject):
def __init__(
self,
frame_shape: tuple[float, float] = (config.frame_width, config.frame_height),
@ -57,8 +58,8 @@ class Camera(OpenGLMobject, InvisibleMobject):
def interpolate(
self,
mobject1: OpenGLMobject,
mobject2: OpenGLMobject,
mobject1: Mobject,
mobject2: Mobject,
alpha: float,
path_func: PathFuncType = straight_path(),
) -> Self:
@ -91,7 +92,7 @@ class Camera(OpenGLMobject, InvisibleMobject):
gamma: float | None = None,
zoom: float | None = None,
focal_distance: float | None = None,
frame_center: OpenGLMobject | Point3D | None = None, # TODO: use Point3DLike
frame_center: Mobject | Point3D | None = None, # TODO: use Point3DLike
) -> Self:
"""This method sets the orientation of the camera in the scene.
@ -408,7 +409,7 @@ class Camera(OpenGLMobject, InvisibleMobject):
This method is still unreliable. The Euler angles are automatically
standardized to (-TAU/2, TAU/2), leading to potentially unwanted behavior
when using :attr:`OpenGLMobject.animate`. Plus, if the camera is on
when using :attr:`Mobject.animate`. Plus, if the camera is on
the Z axis, which occurs when phi is a multiple of TAU/2, the current
implementation can only determine theta +- gamma, but not exactly
theta or gamma yet.
@ -421,7 +422,7 @@ class Camera(OpenGLMobject, InvisibleMobject):
Axis of rotation.
**kwargs
Additional parameters which are required by
:meth:`OpenGLMobject.rotate`.
:meth:`Mobject.rotate`.
Returns
-------

View file

@ -8,15 +8,15 @@ if TYPE_CHECKING:
from typing import Any
from manim.event_handler.event_type import EventType
from manim.mobject.opengl.opengl_mobject import OpenGLMobject
from manim.mobject.opengl.opengl_mobject import OpenGLMobject as Mobject
class EventListener:
def __init__(
self,
mobject: OpenGLMobject,
mobject: Mobject,
event_type: EventType,
event_callback: Callable[[OpenGLMobject, dict[str, str]], None],
event_callback: Callable[[Mobject, dict[str, str]], None],
) -> None:
self.mobject = mobject
self.event_type = event_type

View file

@ -50,7 +50,6 @@ from typing import TYPE_CHECKING, Any, Self, cast
import numpy as np
from manim.constants import *
from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL
from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVGroup as VGroup
from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVMobject as VMobject
from manim.utils.color import BLACK, BLUE, RED, WHITE, ParsableManimColor
@ -69,7 +68,7 @@ if TYPE_CHECKING:
import manim.mobject.geometry.tips as tips
from manim.mobject.geometry.line import Line
from manim.mobject.mobject import Mobject
from manim.mobject.opengl.opengl_mobject import OpenGLMobject as Mobject
from manim.mobject.text.tex_mobject import SingleStringMathTex, Tex
from manim.mobject.text.text_mobject import Text
from manim.typing import (
@ -80,7 +79,7 @@ if TYPE_CHECKING:
)
class TipableVMobject(VMobject, metaclass=ConvertToOpenGL):
class TipableVMobject(VMobject):
"""Meant for shared functionality between Arc and Line.
Functionality can be classified broadly into these groups:
@ -1092,7 +1091,7 @@ class Annulus(Circle):
self.generate_points()
class CubicBezier(VMobject, metaclass=ConvertToOpenGL):
class CubicBezier(VMobject):
"""A cubic Bézier curve.
Example
@ -1127,7 +1126,7 @@ class CubicBezier(VMobject, metaclass=ConvertToOpenGL):
self.add_cubic_bezier_curve(start_anchor, start_handle, end_handle, end_anchor)
class ArcPolygon(VMobject, metaclass=ConvertToOpenGL):
class ArcPolygon(VMobject):
"""A generalized polygon allowing for points to be connected with arcs.
This version tries to stick close to the way :class:`Polygon` is used. Points
@ -1248,7 +1247,7 @@ class ArcPolygon(VMobject, metaclass=ConvertToOpenGL):
self.arcs = arcs
class ArcPolygonFromArcs(VMobject, metaclass=ConvertToOpenGL):
class ArcPolygonFromArcs(VMobject):
"""A generalized polygon allowing for points to be connected with arcs.
This version takes in pre-defined arcs to generate the arcpolygon and introduces

View file

@ -8,8 +8,7 @@ import numpy as np
from pathops import Path as SkiaPath
from pathops import PathVerb, difference, intersection, union, xor
from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL
from manim.mobject.types.vectorized_mobject import VMobject
from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVMobject as VMobject
if TYPE_CHECKING:
from manim.typing import Point2DLike_Array, Point3D_Array, Point3DLike_Array
@ -18,7 +17,7 @@ if TYPE_CHECKING:
__all__ = ["Union", "Intersection", "Difference", "Exclusion"]
class _BooleanOps(VMobject, metaclass=ConvertToOpenGL):
class _BooleanOps(VMobject):
"""This class contains some helper functions which
helps to convert to and from skia objects and manim
objects (:class:`~.VMobject`).

View file

@ -15,9 +15,9 @@ from manim.mobject.geometry.shape_matchers import (
BackgroundRectangle,
SurroundingRectangle,
)
from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVGroup as VGroup
from manim.mobject.text.tex_mobject import MathTex, Tex
from manim.mobject.text.text_mobject import Text
from manim.mobject.types.vectorized_mobject import VGroup
from manim.utils.color import WHITE
from manim.utils.polylabel import polylabel

View file

@ -21,12 +21,12 @@ import numpy as np
from manim.constants import *
from manim.mobject.geometry.arc import Arc, ArcBetweenPoints, Dot, TipableVMobject
from manim.mobject.geometry.tips import ArrowTriangleFilledTip
from manim.mobject.mobject import Mobject
from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL
from manim.mobject.opengl.opengl_mobject import OpenGLMobject
from manim.mobject.opengl.opengl_mobject import OpenGLMobject as Mobject
from manim.mobject.opengl.opengl_vectorized_mobject import (
OpenGLDashedVMobject as DashedVMobject,
)
from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVGroup as VGroup
from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVMobject as VMobject
from manim.mobject.types.vectorized_mobject import DashedVMobject
from manim.utils.color import WHITE
from manim.utils.space_ops import angle_of_vector, line_intersection, normalize
@ -188,7 +188,7 @@ class Line(TipableVMobject):
direction
The direction.
"""
if isinstance(mob_or_point, (Mobject, OpenGLMobject)):
if isinstance(mob_or_point, Mobject):
mob = mob_or_point
if direction is None:
return mob.get_center()
@ -459,7 +459,7 @@ class TangentLine(Line):
self.scale(self.length / self.get_length())
class Elbow(VMobject, metaclass=ConvertToOpenGL):
class Elbow(VMobject):
"""Two lines that create a right angle about each other: L-shape.
Parameters
@ -857,7 +857,7 @@ class DoubleArrow(Arrow):
self.add_tip(at_start=True, tip_shape=tip_shape_start)
class Angle(VMobject, metaclass=ConvertToOpenGL):
class Angle(VMobject):
"""A circular arc or elbow-type mobject representing an angle of two lines.
Parameters

View file

@ -24,8 +24,12 @@ import numpy as np
from manim.constants import *
from manim.mobject.geometry.arc import ArcBetweenPoints
from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVMobject
from manim.mobject.types.vectorized_mobject import VGroup
from manim.mobject.opengl.opengl_vectorized_mobject import (
OpenGLVGroup as VGroup,
)
from manim.mobject.opengl.opengl_vectorized_mobject import (
OpenGLVMobject as VMobject,
)
from manim.utils.color import BLUE, WHITE, ParsableManimColor
from manim.utils.iterables import adjacent_n_tuples, adjacent_pairs
from manim.utils.qhull import QuickHull
@ -45,7 +49,7 @@ if TYPE_CHECKING:
from manim.utils.color import ParsableManimColor
class Polygram(OpenGLVMobject):
class Polygram(VMobject):
"""A generalized :class:`Polygon`, allowing for disconnected sets of edges.
Parameters
@ -743,7 +747,7 @@ class RoundedRectangle(Rectangle):
self.round_corners(self.corner_radius)
class Cutout(OpenGLVMobject):
class Cutout(VMobject):
"""A shape with smaller cutouts.
Parameters

View file

@ -17,9 +17,8 @@ from manim.constants import (
)
from manim.mobject.geometry.line import Line
from manim.mobject.geometry.polygram import RoundedRectangle
from manim.mobject.mobject import Mobject
from manim.mobject.opengl.opengl_mobject import OpenGLMobject
from manim.mobject.types.vectorized_mobject import VGroup
from manim.mobject.opengl.opengl_mobject import OpenGLMobject as Mobject
from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVGroup as VGroup
from manim.utils.color import BLACK, RED, YELLOW, ParsableManimColor
@ -49,18 +48,16 @@ class SurroundingRectangle(RoundedRectangle):
def __init__(
self,
*mobjects: Mobject | OpenGLMobject,
*mobjects: Mobject,
color: ParsableManimColor = YELLOW,
buff: float | tuple[float, float] = SMALL_BUFF,
corner_radius: float = 0.0,
**kwargs: Any,
) -> None:
from manim.mobject.mobject import Group
from manim.mobject.opengl.opengl_mobject import OpenGLGroup as Group
if not all(isinstance(mob, (Mobject, OpenGLMobject)) for mob in mobjects):
raise TypeError(
"Expected all inputs for parameter mobjects to be of type Mobject or OpenGLMobject"
)
if not all(isinstance(mob, Mobject) for mob in mobjects):
raise TypeError("Expected all inputs for parameter mobjects to be Mobjects")
if isinstance(buff, tuple):
buff_x = buff[0]

View file

@ -20,7 +20,6 @@ import numpy as np
from manim.constants import *
from manim.mobject.geometry.arc import Circle
from manim.mobject.geometry.polygram import Square, Triangle
from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL
from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVMobject as VMobject
from manim.utils.space_ops import angle_of_vector
@ -28,7 +27,7 @@ if TYPE_CHECKING:
from manim.typing import Point3D, Vector3D
class ArrowTip(VMobject, metaclass=ConvertToOpenGL):
class ArrowTip(VMobject):
r"""Base class for arrow tips.
.. seealso::

View file

@ -27,11 +27,14 @@ from manim.animation.composition import AnimationGroup
from manim.animation.creation import Create, Uncreate
from manim.mobject.geometry.arc import Dot, LabeledDot
from manim.mobject.geometry.line import Line
from manim.mobject.mobject import Mobject, override_animate
from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL
from manim.mobject.opengl.opengl_mobject import OpenGLMobject
from manim.mobject.opengl.opengl_mobject import (
OpenGLMobject as Mobject,
)
from manim.mobject.opengl.opengl_mobject import (
override_animate,
)
from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVMobject as VMobject
from manim.mobject.text.tex_mobject import MathTex
from manim.mobject.types.vectorized_mobject import VMobject
from manim.utils.color import BLACK
@ -476,7 +479,7 @@ def _determine_graph_layout(
) from e
class GenericGraph(VMobject, metaclass=ConvertToOpenGL):
class GenericGraph(VMobject):
"""Abstract base class for graphs (that is, a collection of vertices
connected with edges).
@ -698,7 +701,7 @@ class GenericGraph(VMobject, metaclass=ConvertToOpenGL):
label = MathTex(vertex, color=label_fill_color)
elif vertex in self._labels:
label = self._labels[vertex]
elif not isinstance(label, (Mobject, OpenGLMobject)):
elif not isinstance(label, Mobject):
label = None
base_vertex_config = copy(self.default_vertex_config)

View file

@ -26,17 +26,22 @@ from manim.mobject.geometry.polygram import Polygon, Rectangle, RegularPolygon
from manim.mobject.graphing.functions import ImplicitFunction, ParametricFunction
from manim.mobject.graphing.number_line import NumberLine
from manim.mobject.graphing.scale import LinearBase
from manim.mobject.mobject import Mobject
from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL
from manim.mobject.opengl.opengl_mobject import OpenGLMobject as Mobject
from manim.mobject.opengl.opengl_surface import OpenGLSurface
from manim.mobject.opengl.opengl_vectorized_mobject import (
OpenGLVDict as VDict,
)
from manim.mobject.opengl.opengl_vectorized_mobject import (
OpenGLVectorizedPoint as VectorizedPoint,
)
from manim.mobject.opengl.opengl_vectorized_mobject import (
OpenGLVGroup as VGroup,
)
from manim.mobject.opengl.opengl_vectorized_mobject import (
OpenGLVMobject as VMobject,
)
from manim.mobject.text.tex_mobject import MathTex
from manim.mobject.three_d.three_dimensions import Surface
from manim.mobject.types.vectorized_mobject import (
VDict,
VectorizedPoint,
VGroup,
VMobject,
)
from manim.utils.color import (
BLACK,
BLUE,
@ -55,7 +60,6 @@ from manim.utils.simple_functions import binary_search
from manim.utils.space_ops import angle_of_vector
if TYPE_CHECKING:
from manim.mobject.mobject import Mobject
from manim.typing import (
ManimFloat,
Point2D,
@ -1863,7 +1867,7 @@ class CoordinateSystem:
def _origin_shift(axis_range: Sequence[float]) -> float: ...
class Axes(VGroup, CoordinateSystem, metaclass=ConvertToOpenGL):
class Axes(VGroup, CoordinateSystem):
"""Creates a set of axes.
Parameters

View file

@ -13,8 +13,7 @@ from isosurfaces import plot_isoline
from manim import config
from manim.mobject.graphing.scale import LinearBase, _ScaleBase
from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL
from manim.mobject.types.vectorized_mobject import VMobject
from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVMobject as VMobject
if TYPE_CHECKING:
from typing import Any, Self
@ -25,7 +24,7 @@ if TYPE_CHECKING:
from manim.utils.color import YELLOW
class ParametricFunction(VMobject, metaclass=ConvertToOpenGL):
class ParametricFunction(VMobject):
"""A parametric curve.
Parameters
@ -237,7 +236,7 @@ class FunctionGraph(ParametricFunction):
return self.parametric_function(x)
class ImplicitFunction(VMobject, metaclass=ConvertToOpenGL):
class ImplicitFunction(VMobject):
def __init__(
self,
func: Callable[[float, float], float],

View file

@ -2,9 +2,6 @@
from __future__ import annotations
from manim.mobject.mobject import Mobject
from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVMobject
__all__ = ["NumberLine", "UnitInterval"]
@ -23,10 +20,16 @@ from manim import config
from manim.constants import *
from manim.mobject.geometry.line import Line
from manim.mobject.graphing.scale import LinearBase, _ScaleBase
from manim.mobject.opengl.opengl_mobject import OpenGLMobject as Mobject
from manim.mobject.opengl.opengl_vectorized_mobject import (
OpenGLVGroup as VGroup,
)
from manim.mobject.opengl.opengl_vectorized_mobject import (
OpenGLVMobject as VMobject,
)
from manim.mobject.text.numbers import DecimalNumber, Integer
from manim.mobject.text.tex_mobject import MathTex, Tex
from manim.mobject.text.text_mobject import Text
from manim.mobject.types.vectorized_mobject import VGroup, VMobject
from manim.utils.bezier import interpolate
from manim.utils.config_ops import merge_dicts_recursively
from manim.utils.space_ops import normalize
@ -651,7 +654,7 @@ class NumberLine(Line):
:class:`~.VMobject`
The label.
"""
if isinstance(label_tex, (VMobject, OpenGLVMobject)):
if isinstance(label_tex, VMobject):
return label_tex
if label_constructor is None:
label_constructor = self.label_constructor

View file

@ -14,10 +14,14 @@ from manim import config, logger
from manim.constants import *
from manim.mobject.geometry.polygram import Rectangle
from manim.mobject.graphing.coordinate_systems import Axes
from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVMobject
from manim.mobject.opengl.opengl_vectorized_mobject import (
OpenGLVGroup as VGroup,
)
from manim.mobject.opengl.opengl_vectorized_mobject import (
OpenGLVMobject as VMobject,
)
from manim.mobject.svg.brace import Brace
from manim.mobject.text.tex_mobject import MathTex, Tex
from manim.mobject.types.vectorized_mobject import VGroup, VMobject
from manim.typing import Vector3D
from manim.utils.color import (
BLUE_E,
@ -144,7 +148,7 @@ class SampleSpace(Rectangle):
def get_subdivision_braces_and_labels(
self,
parts: VGroup,
labels: list[str | VMobject | OpenGLVMobject],
labels: list[str | VMobject],
direction: Vector3D,
buff: float = SMALL_BUFF,
min_num_quads: int = 1,
@ -153,7 +157,7 @@ class SampleSpace(Rectangle):
braces = VGroup()
for label, part in zip(labels, parts, strict=False):
brace = Brace(part, direction, min_num_quads=min_num_quads, buff=buff)
if isinstance(label, (VMobject, OpenGLVMobject)):
if isinstance(label, VMobject):
label_mob = label
else:
label_mob = MathTex(label)
@ -174,7 +178,7 @@ class SampleSpace(Rectangle):
def get_side_braces_and_labels(
self,
labels: list[str | VMobject | OpenGLVMobject],
labels: list[str | VMobject],
direction: Vector3D = LEFT,
**kwargs: Any,
) -> VGroup:
@ -185,14 +189,14 @@ class SampleSpace(Rectangle):
)
def get_top_braces_and_labels(
self, labels: list[str | VMobject | OpenGLVMobject], **kwargs: Any
self, labels: list[str | VMobject], **kwargs: Any
) -> VGroup:
assert hasattr(self, "vertical_parts")
parts = self.vertical_parts
return self.get_subdivision_braces_and_labels(parts, labels, UP, **kwargs)
def get_bottom_braces_and_labels(
self, labels: list[str | VMobject | OpenGLVMobject], **kwargs: Any
self, labels: list[str | VMobject], **kwargs: Any
) -> VGroup:
assert hasattr(self, "vertical_parts")
parts = self.vertical_parts

View file

@ -13,7 +13,9 @@ from manim.mobject.text.numbers import Integer
if TYPE_CHECKING:
from collections.abc import Callable
from manim.mobject.types.vectorized_mobject import VMobject
from manim.mobject.opengl.opengl_vectorized_mobject import (
OpenGLVMobject as VMobject,
)
class _ScaleBase:

View file

@ -11,7 +11,12 @@ import svgelements as se
from manim.animation.updaters.update import UpdateFromAlphaFunc
from manim.mobject.geometry.arc import Circle
from manim.mobject.geometry.polygram import Square, Triangle
from manim.mobject.mobject import Mobject
from manim.mobject.opengl.opengl_vectorized_mobject import (
OpenGLVGroup as VGroup,
)
from manim.mobject.opengl.opengl_vectorized_mobject import (
OpenGLVMobject as VMobject,
)
from manim.typing import Vector3D
from .. import constants as cst
@ -20,7 +25,6 @@ from ..animation.composition import AnimationGroup, Succession
from ..animation.creation import Create, SpiralIn
from ..animation.fading import FadeIn
from ..mobject.svg.svg_mobject import VMobjectFromSVGPath
from ..mobject.types.vectorized_mobject import VGroup
from ..utils.rate_functions import ease_in_out_cubic, smooth
MANIM_SVG_PATHS: list[se.Path] = [
@ -292,7 +296,7 @@ class ManimBanner(VGroup):
elif direction == "left":
left_group.shift(-vector)
def slide_and_uncover(mob: Mobject, alpha: float) -> None:
def slide_and_uncover(mob: VMobject, alpha: float) -> None:
shift(alpha * (m_shape_offset + shape_sliding_overshoot) * cst.RIGHT)
# Add letters when they are covered
@ -309,7 +313,7 @@ class ManimBanner(VGroup):
mob.shapes.save_state()
mob.M.save_state()
def slide_back(mob: Mobject, alpha: float) -> None:
def slide_back(mob: VMobject, alpha: float) -> None:
if alpha == 0:
m_clone.set_opacity(1)
m_clone.move_to(mob.anim[-1])

View file

@ -45,13 +45,17 @@ from typing import Any, Self
import numpy as np
from manim.mobject.mobject import Mobject
from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL
from manim.mobject.opengl.opengl_mobject import OpenGLMobject as Mobject
from manim.mobject.opengl.opengl_vectorized_mobject import (
OpenGLVGroup as VGroup,
)
from manim.mobject.opengl.opengl_vectorized_mobject import (
OpenGLVMobject as VMobject,
)
from manim.mobject.text.numbers import DecimalNumber, Integer
from manim.mobject.text.tex_mobject import MathTex, Tex
from ..constants import *
from ..mobject.types.vectorized_mobject import VGroup, VMobject
# TO DO : The following two functions are not used in this file.
# Not sure if we should keep it or not.
@ -72,7 +76,7 @@ def matrix_to_mobject(matrix: np.ndarray) -> MathTex:
return MathTex(matrix_to_tex_string(matrix))
class Matrix(VMobject, metaclass=ConvertToOpenGL):
class Matrix(VMobject):
r"""A mobject that displays a matrix on the screen.
Parameters

View file

@ -171,6 +171,7 @@ class OpenGLMobject:
"""
dim: int = 3
animation_overrides: dict[type[Animation], FunctionOverride] = {}
# WARNING: when changing a parameter here, be sure to update the
# TypedDict above so that autocomplete works for users
@ -224,6 +225,9 @@ class OpenGLMobject:
@classmethod
def __init_subclass__(cls, **kwargs: Any) -> None:
super().__init_subclass__(**kwargs)
cls.animation_overrides = {}
cls._add_intrinsic_animation_overrides()
cls._original__init__ = cls.__init__
def __str__(self) -> str:
@ -328,6 +332,79 @@ class OpenGLMobject:
self.uniforms[key] = uniforms[key] # Copy?
return self
@classmethod
def animation_override_for(
cls,
animation_class: type[Animation],
) -> FunctionOverride | None:
"""Returns the function defining a specific animation override for this class.
Parameters
----------
animation_class
The animation class for which the override function should be returned.
Returns
-------
Optional[Callable[[Mobject, ...], Animation]]
The function returning the override animation or ``None`` if no such animation
override is defined.
"""
if animation_class in cls.animation_overrides:
return cls.animation_overrides[animation_class]
return None
@classmethod
def _add_intrinsic_animation_overrides(cls) -> None:
"""Initializes animation overrides marked with the :func:`~.override_animation`
decorator.
"""
for method_name in dir(cls):
# Ignore dunder methods
if method_name.startswith("__"):
continue
# TODO: remove broken references to the _Uniforms() and _Data() descriptors.
# Otherwise, getattr crashes unless we pass None as the default value.
method = getattr(cls, method_name, None)
if hasattr(method, "_override_animation"):
animation_class = method._override_animation
cls.add_animation_override(animation_class, method)
@classmethod
def add_animation_override(
cls,
animation_class: type[Animation],
override_func: FunctionOverride,
) -> None:
"""Add an animation override.
This does not apply to subclasses.
Parameters
----------
animation_class
The animation type to be overridden
override_func
The function returning an animation replacing the default animation. It gets
passed the parameters given to the animation constructor.
Raises
------
MultiAnimationOverrideException
If the overridden animation was already overridden.
"""
if animation_class not in cls.animation_overrides:
cls.animation_overrides[animation_class] = override_func
else:
raise MultiAnimationOverrideException(
f"The animation {animation_class.__name__} for "
f"{cls.__name__} is overridden by more than one method: "
f"{cls.animation_overrides[animation_class].__qualname__} and "
f"{override_func.__qualname__}.",
)
# https://github.com/python/typing/issues/802
# so we hack around it by doing | Self
# but this causes issues in Scene.play which only

View file

@ -50,6 +50,7 @@ if TYPE_CHECKING:
__all__ = [
"OpenGLVMobject",
"OpenGLVGroup",
"OpenGLVDict",
"OpenGLVectorizedPoint",
"OpenGLCurvesAsSubmobjects",
"OpenGLDashedVMobject",
@ -1578,6 +1579,343 @@ class OpenGLVGroup(OpenGLVMobject):
self.note_changed_family()
class OpenGLVDict(OpenGLVMobject):
"""A VGroup-like class, also offering submobject access by
key, like a python dict
Parameters
----------
mapping_or_iterable
The parameter specifying the key-value mapping of keys and mobjects.
show_keys
Whether to also display the key associated with
the mobject. This might be useful when debugging,
especially when there are a lot of mobjects in the
:class:`VDict`. Defaults to False.
kwargs
Other arguments to be passed to `Mobject`.
Attributes
----------
show_keys : :class:`bool`
Whether to also display the key associated with
the mobject. This might be useful when debugging,
especially when there are a lot of mobjects in the
:class:`VDict`. When displayed, the key is towards
the left of the mobject.
Defaults to False.
submob_dict : :class:`dict`
Is the actual python dictionary that is used to bind
the keys to the mobjects.
Examples
--------
.. manim:: ShapesWithVDict
class ShapesWithVDict(Scene):
def construct(self):
square = Square().set_color(RED)
circle = Circle().set_color(YELLOW).next_to(square, UP)
# create dict from list of tuples each having key-mobject pair
pairs = [("s", square), ("c", circle)]
my_dict = VDict(pairs, show_keys=True)
# display it just like a VGroup
self.play(Create(my_dict))
self.wait()
text = Tex("Some text").set_color(GREEN).next_to(square, DOWN)
# add a key-value pair by wrapping it in a single-element list of tuple
# after attrs branch is merged, it will be easier like `.add(t=text)`
my_dict.add([("t", text)])
self.wait()
rect = Rectangle().next_to(text, DOWN)
# can also do key assignment like a python dict
my_dict["r"] = rect
# access submobjects like a python dict
my_dict["t"].set_color(PURPLE)
self.play(my_dict["t"].animate.scale(3))
self.wait()
# also supports python dict styled reassignment
my_dict["t"] = Tex("Some other text").set_color(BLUE)
self.wait()
# remove submobject by key
my_dict.remove("t")
self.wait()
self.play(Uncreate(my_dict["s"]))
self.wait()
self.play(FadeOut(my_dict["c"]))
self.wait()
self.play(FadeOut(my_dict["r"], shift=DOWN))
self.wait()
# you can also make a VDict from an existing dict of mobjects
plain_dict = {
1: Integer(1).shift(DOWN),
2: Integer(2).shift(2 * DOWN),
3: Integer(3).shift(3 * DOWN),
}
vdict_from_plain_dict = VDict(plain_dict)
vdict_from_plain_dict.shift(1.5 * (UP + LEFT))
self.play(Create(vdict_from_plain_dict))
# you can even use zip
vdict_using_zip = VDict(zip(["s", "c", "r"], [Square(), Circle(), Rectangle()]))
vdict_using_zip.shift(1.5 * RIGHT)
self.play(Create(vdict_using_zip))
self.wait()
"""
def __init__(
self,
mapping_or_iterable: (
Mapping[Hashable, VMobject] | Iterable[tuple[Hashable, VMobject]]
) = {},
show_keys: bool = False,
**kwargs,
) -> None:
super().__init__(**kwargs)
self.show_keys = show_keys
self.submob_dict = {}
self.add(mapping_or_iterable)
def __repr__(self) -> str:
return f"{self.__class__.__name__}({repr(self.submob_dict)})"
def add(
self,
mapping_or_iterable: (
Mapping[Hashable, VMobject] | Iterable[tuple[Hashable, VMobject]]
),
) -> Self:
"""Adds the key-value pairs to the :class:`VDict` object.
Also, it internally adds the value to the `submobjects` :class:`list`
of :class:`~.Mobject`, which is responsible for actual on-screen display.
Parameters
---------
mapping_or_iterable
The parameter specifying the key-value mapping of keys and mobjects.
Returns
-------
:class:`VDict`
Returns the :class:`VDict` object on which this method was called.
Examples
--------
Normal usage::
square_obj = Square()
my_dict.add([("s", square_obj)])
"""
for key, value in dict(mapping_or_iterable).items():
self.add_key_value_pair(key, value)
return self
def remove(self, key: Hashable) -> Self:
"""Removes the mobject from the :class:`VDict` object having the key `key`
Also, it internally removes the mobject from the `submobjects` :class:`list`
of :class:`~.Mobject`, (which is responsible for removing it from the screen)
Parameters
----------
key
The key of the submoject to be removed.
Returns
-------
:class:`VDict`
Returns the :class:`VDict` object on which this method was called.
Examples
--------
Normal usage::
my_dict.remove("square")
"""
if key not in self.submob_dict:
raise KeyError(f"The given key {key!r} is not present in the VDict")
super().remove(self.submob_dict[key])
del self.submob_dict[key]
return self
def __getitem__(self, key: Hashable):
"""Override the [] operator for item retrieval.
Parameters
----------
key
The key of the submoject to be accessed
Returns
-------
:class:`VMobject`
The submobject corresponding to the key `key`
Examples
--------
Normal usage::
self.play(Create(my_dict["s"]))
"""
submob = self.submob_dict[key]
return submob
def __setitem__(self, key: Hashable, value: VMobject) -> None:
"""Override the [] operator for item assignment.
Parameters
----------
key
The key of the submoject to be assigned
value
The submobject to bind the key to
Returns
-------
None
Examples
--------
Normal usage::
square_obj = Square()
my_dict["sq"] = square_obj
"""
if key in self.submob_dict:
self.remove(key)
self.add([(key, value)])
def __delitem__(self, key: Hashable):
"""Override the del operator for deleting an item.
Parameters
----------
key
The key of the submoject to be deleted
Returns
-------
None
Examples
--------
::
>>> from manim import *
>>> my_dict = VDict({'sq': Square()})
>>> 'sq' in my_dict
True
>>> del my_dict['sq']
>>> 'sq' in my_dict
False
Notes
-----
Removing an item from a VDict does not remove that item from any Scene
that the VDict is part of.
"""
del self.submob_dict[key]
def __contains__(self, key: Hashable):
"""Override the in operator.
Parameters
----------
key
The key to check membership of.
Returns
-------
:class:`bool`
Examples
--------
::
>>> from manim import *
>>> my_dict = VDict({'sq': Square()})
>>> 'sq' in my_dict
True
"""
return key in self.submob_dict
def get_all_submobjects(self) -> list[list]:
"""To get all the submobjects associated with a particular :class:`VDict` object
Returns
-------
:class:`dict_values`
All the submobjects associated with the :class:`VDict` object
Examples
--------
Normal usage::
for submob in my_dict.get_all_submobjects():
self.play(Create(submob))
"""
submobjects = self.submob_dict.values()
return submobjects
def add_key_value_pair(self, key: Hashable, value: VMobject) -> None:
"""A utility function used by :meth:`add` to add the key-value pair
to :attr:`submob_dict`. Not really meant to be used externally.
Parameters
----------
key
The key of the submobject to be added.
value
The mobject associated with the key
Returns
-------
None
Raises
------
TypeError
If the value is not an instance of VMobject
Examples
--------
Normal usage::
square_obj = Square()
self.add_key_value_pair("s", square_obj)
"""
self._assert_valid_submobjects([value])
mob = value
if self.show_keys:
# This import is here and not at the top to avoid circular import
from manim.mobject.text.tex_mobject import Tex
key_text = Tex(str(key)).next_to(value, LEFT)
mob.add(key_text)
self.submob_dict[key] = mob
super().add(value)
class OpenGLVectorizedPoint(OpenGLPoint, OpenGLVMobject):
def __init__(
self,

View file

@ -12,8 +12,8 @@ import svgelements as se
from manim._config import config
from manim.mobject.geometry.arc import Arc
from manim.mobject.geometry.line import Line
from manim.mobject.mobject import Mobject
from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL
from manim.mobject.opengl.opengl_mobject import OpenGLMobject as Mobject
from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVMobject as VMobject
from manim.mobject.text.tex_mobject import MathTex, SingleStringMathTex, Tex
from manim.mobject.text.text_mobject import Text
@ -22,7 +22,6 @@ from ...animation.composition import AnimationGroup
from ...animation.fading import FadeIn
from ...animation.growing import GrowFromCenter
from ...constants import *
from ...mobject.types.vectorized_mobject import VMobject
from ...utils.color import BLACK
from ..svg.svg_mobject import VMobjectFromSVGPath
@ -204,7 +203,7 @@ class Brace(VMobjectFromSVGPath):
return vect / np.linalg.norm(vect)
class BraceLabel(VMobject, metaclass=ConvertToOpenGL):
class BraceLabel(VMobject):
"""Create a brace with a label attached.
Parameters

View file

@ -11,6 +11,7 @@ import numpy as np
import svgelements as se
from manim import config, logger
from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVMobject as VMobject
from ...constants import RIGHT
from ...utils.bezier import get_quadratic_approximation_of_cubic
@ -19,8 +20,6 @@ from ...utils.iterables import hash_obj
from ..geometry.arc import Circle
from ..geometry.line import Line
from ..geometry.polygram import Polygon, Rectangle, RoundedRectangle
from ..opengl.opengl_compatibility import ConvertToOpenGL
from ..types.vectorized_mobject import VMobject
__all__ = ["SVGMobject", "VMobjectFromSVGPath"]
@ -32,7 +31,7 @@ def _convert_point_to_3d(x: float, y: float) -> np.ndarray:
return np.array([x, y, 0.0])
class SVGMobject(VMobject, metaclass=ConvertToOpenGL):
class SVGMobject(VMobject):
"""A vectorized mobject created from importing an SVG file.
Parameters
@ -431,7 +430,7 @@ class SVGMobject(VMobject, metaclass=ConvertToOpenGL):
self.set(width=self.svg_width)
class VMobjectFromSVGPath(VMobject, metaclass=ConvertToOpenGL):
class VMobjectFromSVGPath(VMobject):
"""A vectorized mobject representing an SVG path.
.. note::

View file

@ -70,6 +70,12 @@ from collections.abc import Callable, Iterable, Sequence
from manim.mobject.geometry.line import Line
from manim.mobject.geometry.polygram import Polygon
from manim.mobject.geometry.shape_matchers import BackgroundRectangle
from manim.mobject.opengl.opengl_vectorized_mobject import (
OpenGLVGroup as VGroup,
)
from manim.mobject.opengl.opengl_vectorized_mobject import (
OpenGLVMobject as VMobject,
)
from manim.mobject.text.numbers import DecimalNumber, Integer
from manim.mobject.text.tex_mobject import MathTex
from manim.mobject.text.text_mobject import Paragraph
@ -78,7 +84,6 @@ from ..animation.animation import Animation
from ..animation.composition import AnimationGroup
from ..animation.creation import Create, Write
from ..animation.fading import FadeIn
from ..mobject.types.vectorized_mobject import VGroup, VMobject
from ..utils.color import BLACK, YELLOW, ManimColor, ParsableManimColor
@ -322,7 +327,6 @@ class Table(VGroup):
mob_table.insert(0, col_labels)
else:
# Placeholder to use arrange_in_grid if top_left_entry is not set.
# Import OpenGLVMobject to work with --renderer=opengl
dummy_mobject = VMobject()
col_labels = [dummy_mobject] + self.col_labels
mob_table.insert(0, col_labels)

View file

@ -19,13 +19,17 @@ from pygments.styles import get_all_styles
from manim.constants import *
from manim.mobject.geometry.arc import Dot
from manim.mobject.geometry.shape_matchers import SurroundingRectangle
from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL
from manim.mobject.types.vectorized_mobject import VGroup, VMobject
from manim.mobject.opengl.opengl_vectorized_mobject import (
OpenGLVGroup as VGroup,
)
from manim.mobject.opengl.opengl_vectorized_mobject import (
OpenGLVMobject as VMobject,
)
from manim.typing import StrPath
from manim.utils.color import WHITE, ManimColor
class Code(VMobject, metaclass=ConvertToOpenGL):
class Code(VMobject):
"""A highlighted source code listing.
Examples

View file

@ -10,17 +10,16 @@ import numpy as np
from manim import config
from manim.constants import *
from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL
from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVMobject as VMobject
from manim.mobject.text.tex_mobject import MathTex, SingleStringMathTex, Tex
from manim.mobject.text.text_mobject import Text
from manim.mobject.types.vectorized_mobject import VMobject
from manim.mobject.value_tracker import ValueTracker
from manim.typing import Vector3DLike
string_to_mob_map: dict[str, SingleStringMathTex] = {}
class DecimalNumber(VMobject, metaclass=ConvertToOpenGL):
class DecimalNumber(VMobject):
r"""An mobject representing a decimal number.
Parameters
@ -343,7 +342,7 @@ class Integer(DecimalNumber):
return int(np.round(super().get_value()))
class Variable(VMobject, metaclass=ConvertToOpenGL):
class Variable(VMobject):
"""A class for displaying text that shows "label = value" with
the value continuously updated from a :class:`~.ValueTracker`.

View file

@ -34,8 +34,8 @@ from typing import Any, Self
from manim import config, logger
from manim.constants import *
from manim.mobject.geometry.line import Line
from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVGroup as VGroup
from manim.mobject.svg.svg_mobject import SVGMobject
from manim.mobject.types.vectorized_mobject import VGroup
from manim.utils.tex import TexTemplate
from manim.utils.tex_file_writing import tex_to_svg_file

View file

@ -70,10 +70,13 @@ from manimpango import MarkupUtils, PangoUtils, TextSetting
from manim import config, logger
from manim.constants import *
from manim.mobject.geometry.arc import Dot
from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVMobject
from manim.mobject.opengl.opengl_vectorized_mobject import (
OpenGLVGroup as VGroup,
)
from manim.mobject.opengl.opengl_vectorized_mobject import (
OpenGLVMobject as VMobject,
)
from manim.mobject.svg.svg_mobject import SVGMobject
from manim.mobject.types.vectorized_mobject import VGroup, VMobject
from manim.typing import Point3D
from manim.utils.color import ManimColor, ParsableManimColor, color_gradient
if TYPE_CHECKING:
@ -509,9 +512,7 @@ class Text(SVGMobject):
else:
self.line_spacing = self._font_size + self._font_size * self.line_spacing
parsed_color: ManimColor = (
ManimColor(color) if color else OpenGLVMobject().color
)
parsed_color = ManimColor(color)
file_name = self._text2svg(parsed_color.to_hex())
PangoUtils.remove_last_M(file_name)
super().__init__(
@ -1209,9 +1210,7 @@ class MarkupText(SVGMobject):
else:
self.line_spacing = self._font_size + self._font_size * self.line_spacing
parsed_color: ManimColor = (
ManimColor(color) if color else OpenGLVMobject().color
)
parsed_color = ManimColor(color)
file_name = self._text2svg(parsed_color)
PangoUtils.remove_last_M(file_name)

View file

@ -9,12 +9,12 @@ import numpy as np
from manim.mobject.geometry.polygram import Polygon
from manim.mobject.graph import Graph
from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVGroup as VGroup
from manim.mobject.three_d.three_dimensions import Dot3D
from manim.mobject.types.vectorized_mobject import VGroup
from manim.utils.qhull import QuickHull
if TYPE_CHECKING:
from manim.mobject.mobject import Mobject
from manim.mobject.opengl.opengl_mobject import OpenGLMobject as Mobject
from manim.typing import Point3D, Point3DLike_Array
__all__ = [

View file

@ -22,10 +22,11 @@ from manim.constants import ORIGIN, UP
from manim.utils.space_ops import get_unit_normal
if TYPE_CHECKING:
from manim.mobject.opengl.opengl_vectorized_mobject import (
OpenGLVMobject as VMobject,
)
from manim.typing import Point3D, Vector3D
from ..types.vectorized_mobject import VMobject
def get_3d_vmob_gradient_start_and_end_points(
vmob: VMobject,

View file

@ -25,12 +25,16 @@ from manim import config, logger
from manim.constants import *
from manim.mobject.geometry.arc import Circle
from manim.mobject.geometry.polygram import Square
from manim.mobject.opengl.opengl_mobject import OpenGLMobject
from manim.mobject.opengl.opengl_mobject import OpenGLMobject as Mobject
from manim.mobject.opengl.opengl_vectorized_mobject import (
OpenGLVectorizedPoint as VectorizedPoint,
)
from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVGroup as VGroup
from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVMobject
from manim.mobject.opengl.opengl_vectorized_mobject import (
OpenGLVGroup as VGroup,
)
from manim.mobject.opengl.opengl_vectorized_mobject import (
OpenGLVMobject as VMobject,
)
from manim.utils.color import (
BLUE,
BLUE_D,
@ -48,7 +52,7 @@ if TYPE_CHECKING:
from manim.typing import Point3D, Point3DLike, Vector3D, Vector3DLike
class ThreeDVMobject(OpenGLVMobject):
class ThreeDVMobject(VMobject):
u_index: int
v_index: int
u1: float
@ -997,7 +1001,7 @@ class Line3D(Cylinder):
def pointify(
self,
mob_or_point: OpenGLMobject | Point3DLike,
mob_or_point: Mobject | Point3DLike,
direction: Vector3DLike | None = None,
) -> Point3D:
"""Gets a point representing the center of the :class:`Mobjects <.Mobject>`.
@ -1014,7 +1018,7 @@ class Line3D(Cylinder):
:class:`numpy.array`
Center of the :class:`Mobjects <.Mobject>` or point, or edge if direction is given.
"""
if isinstance(mob_or_point, OpenGLMobject):
if isinstance(mob_or_point, Mobject):
mob = mob_or_point
if direction is None:
return mob.get_center()

View file

@ -12,10 +12,10 @@ from PIL import Image
from PIL.Image import Resampling
from manim.mobject.geometry.shape_matchers import SurroundingRectangle
from manim.mobject.opengl.opengl_mobject import OpenGLMobject as Mobject
from ... import config
from ...constants import *
from ...mobject.mobject import Mobject
from ...utils.bezier import interpolate
from ...utils.color import WHITE, ManimColor, color_to_int_rgb
from ...utils.images import change_to_rgba_array, get_full_raster_image_path

View file

@ -9,11 +9,10 @@ from typing import TYPE_CHECKING, Any
import numpy as np
from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL
from manim.mobject.opengl.opengl_point_cloud_mobject import OpenGLPMobject
from ...constants import *
from ...mobject.mobject import Mobject
from ...mobject.opengl.opengl_mobject import OpenGLMobject as Mobject
from ...utils.bezier import interpolate
from ...utils.color import (
BLACK,
@ -44,7 +43,7 @@ if TYPE_CHECKING:
)
class PMobject(Mobject, metaclass=ConvertToOpenGL):
class PMobject(Mobject):
"""A disc made of a cloud of Dots
Examples
@ -250,7 +249,7 @@ class PMobject(Mobject, metaclass=ConvertToOpenGL):
# TODO, Make the two implementations below non-redundant
class Mobject1D(PMobject, metaclass=ConvertToOpenGL):
class Mobject1D(PMobject):
def __init__(self, density: int = DEFAULT_POINT_DENSITY_1D, **kwargs: Any) -> None:
self.density = density
self.epsilon = 1.0 / self.density
@ -274,7 +273,7 @@ class Mobject1D(PMobject, metaclass=ConvertToOpenGL):
self.add_points(points, color=color)
class Mobject2D(PMobject, metaclass=ConvertToOpenGL):
class Mobject2D(PMobject):
def __init__(self, density: int = DEFAULT_POINT_DENSITY_2D, **kwargs: Any) -> None:
self.density = density
self.epsilon = 1.0 / self.density

View file

@ -8,8 +8,7 @@ from typing import TYPE_CHECKING, Any
import numpy as np
from manim.mobject.mobject import Mobject
from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL
from manim.mobject.opengl.opengl_mobject import OpenGLMobject as Mobject
from manim.utils.paths import straight_path
if TYPE_CHECKING:
@ -18,7 +17,7 @@ if TYPE_CHECKING:
from manim.typing import PathFuncType
class ValueTracker(Mobject, metaclass=ConvertToOpenGL):
class ValueTracker(Mobject):
"""A mobject that can be used for tracking (real-valued) parameters.
Useful for animating parameter changes.

View file

@ -20,14 +20,19 @@ from PIL import Image
from manim.animation.updaters.update import UpdateFromAlphaFunc
from manim.mobject.geometry.line import Vector
from manim.mobject.graphing.coordinate_systems import CoordinateSystem
from manim.mobject.opengl.opengl_mobject import OpenGLMobject as Mobject
from manim.mobject.opengl.opengl_vectorized_mobject import (
OpenGLVGroup as VGroup,
)
from manim.mobject.opengl.opengl_vectorized_mobject import (
OpenGLVMobject as VMobject,
)
from .. import config
from ..animation.composition import AnimationGroup, Succession
from ..animation.creation import Create
from ..animation.indication import ShowPassingFlash
from ..constants import OUT, RIGHT, UP, RendererType
from ..mobject.mobject import Mobject
from ..mobject.types.vectorized_mobject import VGroup, VMobject
from ..utils.bezier import interpolate, inverse_interpolate
from ..utils.color import (
BLUE_E,

View file

@ -16,9 +16,24 @@ from manim.camera.camera import Camera
from manim.constants import DEFAULT_WAIT_TIME
from manim.event_handler import EVENT_DISPATCHER
from manim.event_handler.event_type import EventType
from manim.mobject.mobject import Group, Point
from manim.mobject.opengl.opengl_mobject import OpenGLMobject, _AnimationBuilder
from manim.mobject.types.vectorized_mobject import VGroup, VMobject
from manim.mobject.opengl.opengl_mobject import (
OpenGLGroup as Group,
)
from manim.mobject.opengl.opengl_mobject import (
OpenGLMobject as Mobject,
)
from manim.mobject.opengl.opengl_mobject import (
OpenGLPoint as Point,
)
from manim.mobject.opengl.opengl_mobject import (
_AnimationBuilder,
)
from manim.mobject.opengl.opengl_vectorized_mobject import (
OpenGLVGroup as VGroup,
)
from manim.mobject.opengl.opengl_vectorized_mobject import (
OpenGLVMobject as VMobject,
)
from manim.scene.sections import group as SceneGroup
from manim.utils.iterables import list_difference_update
@ -81,7 +96,7 @@ class Scene:
# Core state of the scene
self.camera: Camera = Camera()
self.manager = manager
self.mobjects: list[OpenGLMobject] = []
self.mobjects: list[Mobject] = []
self.num_plays: int = 0
# the time is updated by the manager
self.time: float = 0
@ -193,7 +208,7 @@ class Scene:
# Related to internal mobject organization
def add(self, *new_mobjects: OpenGLMobject) -> Self:
def add(self, *new_mobjects: Mobject) -> Self:
"""
Mobjects will be displayed, from background to
foreground in the order with which they are added.
@ -202,7 +217,7 @@ class Scene:
self.mobjects += new_mobjects
return self
def remove(self, *mobjects_to_remove: OpenGLMobject) -> Self:
def remove(self, *mobjects_to_remove: Mobject) -> Self:
"""
Removes anything in mobjects from scenes mobject list, but in the event that one
of the items to be removed is a member of the family of an item in mobject_list,
@ -219,11 +234,11 @@ class Scene:
self.mobjects = list_difference_update(self.mobjects, mob.get_family())
return self
def replace(self, mobject: OpenGLMobject, *replacements: OpenGLMobject):
def replace(self, mobject: Mobject, *replacements: Mobject):
"""Replace one Mobject in the scene with one or more other Mobjects,
preserving draw order.
If ``mobject`` is a submobject of some other :class:`OpenGLMobject`
If ``mobject`` is a submobject of some other :class:`Mobject`
(e.g. a :class:`.Group`), the ``replacements`` will replace it inside
the group, without otherwise changing the parent mobject.
@ -294,11 +309,11 @@ class Scene:
"""
self.updaters = [f for f in self.updaters if f is not func]
def bring_to_front(self, *mobjects: OpenGLMobject) -> Self:
def bring_to_front(self, *mobjects: Mobject) -> Self:
self.add(*mobjects)
return self
def bring_to_back(self, *mobjects: OpenGLMobject) -> Self:
def bring_to_back(self, *mobjects: Mobject) -> Self:
self.remove(*mobjects)
self.mobjects = [*mobjects, *self.mobjects]
return self
@ -307,18 +322,18 @@ class Scene:
self.mobjects.clear()
return self
def get_mobjects(self) -> Sequence[OpenGLMobject]:
def get_mobjects(self) -> Sequence[Mobject]:
return list(self.mobjects)
def get_mobject_copies(self) -> Sequence[OpenGLMobject]:
def get_mobject_copies(self) -> Sequence[Mobject]:
return [m.copy() for m in self.mobjects]
def point_to_mobject(
self,
point: Point3D,
search_set: Reversible[OpenGLMobject] | None = None,
search_set: Reversible[Mobject] | None = None,
buff: float = 0.0,
) -> OpenGLMobject | None:
) -> Mobject | None:
"""
E.g. if clicking on the scene, this returns the top layer mobject
under a given point
@ -397,11 +412,9 @@ class Scene:
def play(
self,
# the OpenGLMobject is a side-effect of the return type of animate, it will
# the Mobject is a side-effect of the return type of animate, it will
# raise a ValueError
*proto_animations: AnimationProtocol
| _AnimationBuilder[OpenGLMobject]
| OpenGLMobject,
*proto_animations: AnimationProtocol | _AnimationBuilder[Mobject] | Mobject,
run_time: float | None = None,
rate_func: Callable[[float], float] | None = None,
lag_ratio: float | None = None,
@ -621,9 +634,7 @@ class Scene:
class SceneState:
def __init__(
self, scene: Scene, ignore: Iterable[OpenGLMobject] | None = None
) -> None:
def __init__(self, scene: Scene, ignore: Iterable[Mobject] | None = None) -> None:
self.time = scene.time
self.num_plays = scene.num_plays
self.camera = scene.camera.copy()
@ -642,7 +653,7 @@ class SceneState:
self.mobjects_to_copies[mob] = mob.copy()
@property
def mobjects(self) -> Sequence[OpenGLMobject]:
def mobjects(self) -> Sequence[Mobject]:
return tuple(self.mobjects_to_copies.keys())
def __eq__(self, state: Any) -> bool:

View file

@ -9,14 +9,24 @@ from typing import TYPE_CHECKING, Any, cast
import numpy as np
from manim.animation.creation import DrawBorderThenFill, Group
from manim.animation.creation import DrawBorderThenFill
from manim.camera.camera import Camera
from manim.mobject.geometry.arc import Dot
from manim.mobject.geometry.line import Arrow, Line, Vector
from manim.mobject.geometry.polygram import Rectangle
from manim.mobject.graphing.coordinate_systems import Axes, NumberPlane
from manim.mobject.opengl.opengl_mobject import OpenGLMobject
from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVMobject
from manim.mobject.opengl.opengl_mobject import (
OpenGLGroup as Group,
)
from manim.mobject.opengl.opengl_mobject import (
OpenGLMobject as Mobject,
)
from manim.mobject.opengl.opengl_vectorized_mobject import (
OpenGLVGroup as VGroup,
)
from manim.mobject.opengl.opengl_vectorized_mobject import (
OpenGLVMobject as VMobject,
)
from manim.mobject.text.tex_mobject import MathTex, Tex
from manim.utils.config_ops import update_dict_recursively
@ -28,8 +38,6 @@ from ..animation.growing import GrowArrow
from ..animation.transform import ApplyFunction, ApplyPointwiseFunction, Transform
from ..constants import *
from ..mobject.matrix import Matrix
from ..mobject.mobject import Mobject
from ..mobject.types.vectorized_mobject import VGroup, VMobject
from ..scene.scene import Scene
from ..utils.color import (
BLACK,
@ -1006,7 +1014,7 @@ class LinearTransformationScene(VectorScene):
LinearTransformationScene
The scene with the title added to it.
"""
if not isinstance(title, (Mobject, OpenGLMobject)):
if not isinstance(title, Mobject):
title = Tex(title).scale(scale_factor)
title.to_edge(UP)
title.add_background_rectangle()
@ -1069,7 +1077,7 @@ class LinearTransformationScene(VectorScene):
Animation
The animation of the movement.
"""
v_pieces = [piece for piece in pieces if isinstance(piece, OpenGLVMobject)]
v_pieces = [piece for piece in pieces if isinstance(piece, VMobject)]
start = VGroup(*v_pieces)
target = VGroup(*(mob.target for mob in v_pieces))

View file

@ -18,7 +18,7 @@ from manim._config import config, logger
if TYPE_CHECKING:
from manim.animation.protocol import AnimationProtocol
from manim.camera.camera import Camera
from manim.mobject.opengl.opengl_mobject import OpenGLMobject
from manim.mobject.opengl.opengl_mobject import OpenGLMobject as Mobject
from manim.scene.scene import Scene
T = TypeVar("T")
@ -336,7 +336,7 @@ def get_hash_from_play_call(
scene_object: Scene,
camera_object: Camera,
animations_list: Iterable[AnimationProtocol],
current_mobjects_list: Iterable[OpenGLMobject],
current_mobjects_list: Iterable[Mobject],
) -> str:
"""Take the list of animations and a list of mobjects and output their hashes. This is meant to be used for `scene.play` function.

View file

@ -1,14 +1,14 @@
from manim import manim_colors as col
from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVMobject
from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVMobject as VMobject
def test_vmobject_init():
vm = OpenGLVMobject()
vm = VMobject()
assert vm.fill_color == [col.WHITE]
assert vm.stroke_color == [col.WHITE]
vm = OpenGLVMobject(color=col.RED)
vm = VMobject(color=col.RED)
assert vm.fill_color == [col.RED]
assert vm.stroke_color == [col.RED]
vm = OpenGLVMobject(fill_color=col.GREEN, stroke_color=col.YELLOW)
vm = VMobject(fill_color=col.GREEN, stroke_color=col.YELLOW)
assert vm.fill_color == [col.GREEN]
assert vm.stroke_color == [col.YELLOW]

View file

@ -1,20 +0,0 @@
from __future__ import annotations
from manim import Mobject
from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL
from manim.mobject.opengl.opengl_mobject import OpenGLMobject
def test_metaclass_registry(config):
class SomeTestMobject(Mobject, metaclass=ConvertToOpenGL):
pass
assert SomeTestMobject in ConvertToOpenGL._converted_classes
config.renderer = "opengl"
assert OpenGLMobject in SomeTestMobject.__bases__
assert Mobject not in SomeTestMobject.__bases__
config.renderer = "cairo"
assert Mobject in SomeTestMobject.__bases__
assert OpenGLMobject not in SomeTestMobject.__bases__

View file

@ -1,5 +1,12 @@
from manim import ORIGIN, UR, Arrow, DashedVMobject, VGroup
from manim.constants import ORIGIN, UR
from manim.mobject.geometry.line import Arrow
from manim.mobject.geometry.tips import ArrowTip, StealthTip
from manim.mobject.opengl.opengl_vectorized_mobject import (
OpenGLDashedVMobject as DashedVMobject,
)
from manim.mobject.opengl.opengl_vectorized_mobject import (
OpenGLVGroup as VGroup,
)
def _collect_tips(mobject):

View file

@ -3,38 +3,38 @@ from math import cos, sin
import numpy as np
import pytest
from manim import (
Circle,
CurvesAsSubmobjects,
Line,
Mobject,
OpenGLMobject,
Polygon,
RegularPolygon,
Square,
VDict,
VGroup,
VMobject,
)
from manim.constants import PI
from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVMobject
from manim.mobject.geometry.arc import Circle
from manim.mobject.geometry.line import Line
from manim.mobject.geometry.polygram import Polygon, RegularPolygon, Square
from manim.mobject.opengl.opengl_mobject import OpenGLMobject as Mobject
from manim.mobject.opengl.opengl_vectorized_mobject import (
OpenGLCurvesAsSubmobjects as CurvesAsSubmobjects,
)
from manim.mobject.opengl.opengl_vectorized_mobject import (
OpenGLVDict as VDict,
)
from manim.mobject.opengl.opengl_vectorized_mobject import (
OpenGLVGroup as VGroup,
)
from manim.mobject.opengl.opengl_vectorized_mobject import (
OpenGLVMobject as VMobject,
)
def test_vmobject_add():
def get_type_error_message(invalid_obj, invalid_indices):
return (
f"Only values of type OpenGLVMobject can be added "
"as submobjects of OpenGLVMobject, but the value "
f"{repr(invalid_obj)} (at index {invalid_indices[1]}) "
f"is of type "
f"Only values of type VMobject can be added as submobjects of VMobject, but "
f"the value {repr(invalid_obj)} (at index {invalid_indices[1]}) is of type "
f"{type(invalid_obj).__name__}."
)
"""Test the VMobject add method."""
obj = OpenGLVMobject()
obj = VMobject()
assert len(obj.submobjects) == 0
obj.add(OpenGLVMobject())
obj.add(VMobject())
assert len(obj.submobjects) == 1
# Can't add non-VMobject values to a VMobject.
@ -52,7 +52,7 @@ def test_vmobject_add():
with pytest.raises(TypeError) as add_vmob_and_mob_info:
# If only one of the added objects is not an instance of VMobject, none of them should be added
obj.add(OpenGLVMobject(), Mobject())
obj.add(VMobject(), Mobject())
assert str(add_vmob_and_mob_info.value) == (
get_type_error_message(Mobject(), [0, 1])
)
@ -62,7 +62,7 @@ def test_vmobject_add():
with pytest.raises(ValueError) as add_self_info:
obj.add(obj)
assert str(add_self_info.value) == (
"Cannot add OpenGLVMobject as a submobject of itself (at index 0)."
"Cannot add VMobject as a submobject of itself (at index 0)."
)
assert len(obj.submobjects) == 1
@ -99,7 +99,7 @@ def test_vmobject_add_points_as_corners():
def test_vmobject_point_from_proportion():
obj = OpenGLVMobject()
obj = VMobject()
# One long line, one short line
obj.set_points_as_corners(
@ -130,7 +130,7 @@ def test_curves_as_submobjects_point_from_proportion():
with pytest.raises(Exception, match="with no submobjects"):
obj.point_from_proportion(0)
obj.add(OpenGLVMobject())
obj.add(VMobject())
with pytest.raises(Exception, match="have no points"):
obj.point_from_proportion(0)
@ -141,7 +141,7 @@ def test_curves_as_submobjects_point_from_proportion():
np.array([4, 0, 0]),
],
)
obj.add(OpenGLVMobject())
obj.add(VMobject())
# submobject[1] is a line of length 2
obj.submobjects[1].set_points_as_corners(
[
@ -157,30 +157,30 @@ def test_curves_as_submobjects_point_from_proportion():
def test_vgroup_init():
"""Test the VGroup instantiation."""
VGroup()
VGroup(OpenGLVMobject())
VGroup(OpenGLVMobject(), OpenGLVMobject())
VGroup(VMobject())
VGroup(VMobject(), VMobject())
# A VGroup cannot contain non-VMobject values.
with pytest.raises(TypeError) as init_with_float_info:
VGroup(3.0)
assert str(init_with_float_info.value) == (
"Only values of type OpenGLVMobject can be added as submobjects of VGroup, "
"Only values of type VMobject can be added as submobjects of VGroup, "
"but the value 3.0 (at index 0 of parameter 0) is of type float."
)
with pytest.raises(TypeError) as init_with_mob_info:
VGroup(OpenGLMobject())
VGroup(Mobject())
assert str(init_with_mob_info.value) == (
"Only values of type OpenGLVMobject can be added as submobjects of VGroup, "
"but the value OpenGLMobject (at index 0 of parameter 0) is of type OpenGLMobject. You can try "
"Only values of type VMobject can be added as submobjects of VGroup, "
"but the value Mobject (at index 0 of parameter 0) is of type Mobject. You can try "
"adding this value into a Group instead."
)
with pytest.raises(TypeError) as init_with_vmob_and_mob_info:
VGroup(OpenGLVMobject(), OpenGLMobject())
VGroup(VMobject(), Mobject())
assert str(init_with_vmob_and_mob_info.value) == (
"Only values of type OpenGLVMobject can be added as submobjects of VGroup, "
"but the value OpenGLMobject (at index 0 of parameter 1) is of type OpenGLMobject. You can try "
"Only values of type VMobject can be added as submobjects of VGroup, "
"but the value Mobject (at index 0 of parameter 1) is of type Mobject. You can try "
"adding this value into a Group instead."
)
@ -197,40 +197,40 @@ def test_vgroup_init_with_iterable():
for i in range(n)
)
obj = VGroup(OpenGLVMobject())
obj = VGroup(VMobject())
assert len(obj.submobjects) == 1
obj = VGroup(type_generator(OpenGLVMobject, 38))
obj = VGroup(type_generator(VMobject, 38))
assert len(obj.submobjects) == 38
obj = VGroup(
OpenGLVMobject(),
[OpenGLVMobject(), OpenGLVMobject()],
type_generator(OpenGLVMobject, 38),
VMobject(),
[VMobject(), VMobject()],
type_generator(VMobject, 38),
)
assert len(obj.submobjects) == 41
# A VGroup cannot be initialised with an iterable containing a Mobject
with pytest.raises(TypeError) as init_with_mob_iterable:
VGroup(type_generator(OpenGLMobject, 5))
VGroup(type_generator(Mobject, 5))
assert str(init_with_mob_iterable.value) == (
"Only values of type OpenGLVMobject can be added as submobjects of VGroup, "
"but the value OpenGLMobject (at index 0 of parameter 0) is of type OpenGLMobject."
"Only values of type VMobject can be added as submobjects of VGroup, "
"but the value Mobject (at index 0 of parameter 0) is of type Mobject."
)
# A VGroup cannot be initialised with an iterable containing a Mobject in any position
with pytest.raises(TypeError) as init_with_mobs_and_vmobs_iterable:
VGroup(mixed_type_generator(OpenGLVMobject, OpenGLMobject, [3, 5], 7))
VGroup(mixed_type_generator(VMobject, Mobject, [3, 5], 7))
assert str(init_with_mobs_and_vmobs_iterable.value) == (
"Only values of type OpenGLVMobject can be added as submobjects of VGroup, "
"but the value OpenGLMobject (at index 3 of parameter 0) is of type OpenGLMobject."
"Only values of type VMobject can be added as submobjects of VGroup, "
"but the value Mobject (at index 3 of parameter 0) is of type Mobject."
)
# A VGroup cannot be initialised with an iterable containing non VMobject's in any position
with pytest.raises(TypeError) as init_with_float_and_vmobs_iterable:
VGroup(mixed_type_generator(OpenGLVMobject, float, [6, 7], 9))
VGroup(mixed_type_generator(VMobject, float, [6, 7], 9))
assert str(init_with_float_and_vmobs_iterable.value) == (
"Only values of type OpenGLVMobject can be added as submobjects of VGroup, "
"Only values of type VMobject can be added as submobjects of VGroup, "
"but the value 0.0 (at index 6 of parameter 0) is of type float."
)
@ -240,14 +240,14 @@ def test_vgroup_add():
obj = VGroup()
assert len(obj.submobjects) == 0
obj.add(OpenGLVMobject())
obj.add(VMobject())
assert len(obj.submobjects) == 1
# Can't add non-VMobject values to a VMobject or VGroup.
with pytest.raises(TypeError) as add_int_info:
obj.add(3)
assert str(add_int_info.value) == (
"Only values of type OpenGLVMobject can be added as submobjects of VGroup, "
"Only values of type VMobject can be added as submobjects of VGroup, "
"but the value 3 (at index 0 of parameter 0) is of type int."
)
assert len(obj.submobjects) == 1
@ -255,20 +255,20 @@ def test_vgroup_add():
# Plain Mobjects can't be added to a VMobject or VGroup if they're not
# VMobjects. Suggest adding them into a Group instead.
with pytest.raises(TypeError) as add_mob_info:
obj.add(OpenGLMobject())
obj.add(Mobject())
assert str(add_mob_info.value) == (
"Only values of type OpenGLVMobject can be added as submobjects of VGroup, "
"but the value OpenGLMobject (at index 0 of parameter 0) is of type OpenGLMobject. You can try "
"Only values of type VMobject can be added as submobjects of VGroup, "
"but the value Mobject (at index 0 of parameter 0) is of type Mobject. You can try "
"adding this value into a Group instead."
)
assert len(obj.submobjects) == 1
with pytest.raises(TypeError) as add_vmob_and_mob_info:
# If only one of the added objects is not an instance of VMobject, none of them should be added
obj.add(OpenGLVMobject(), OpenGLMobject())
obj.add(VMobject(), Mobject())
assert str(add_vmob_and_mob_info.value) == (
"Only values of type OpenGLVMobject can be added as submobjects of VGroup, "
"but the value OpenGLMobject (at index 0 of parameter 1) is of type OpenGLMobject. You can try "
"Only values of type VMobject can be added as submobjects of VGroup, "
"but the value Mobject (at index 0 of parameter 1) is of type Mobject. You can try "
"adding this value into a Group instead."
)
assert len(obj.submobjects) == 1
@ -286,16 +286,16 @@ def test_vgroup_add_dunder():
"""Test the VGroup __add__ magic method."""
obj = VGroup()
assert len(obj.submobjects) == 0
obj + OpenGLVMobject()
obj + VMobject()
assert len(obj.submobjects) == 0
obj += OpenGLVMobject()
obj += VMobject()
assert len(obj.submobjects) == 1
with pytest.raises(TypeError):
obj += Mobject()
assert len(obj.submobjects) == 1
with pytest.raises(TypeError):
# If only one of the added object is not an instance of VMobject, none of them should be added
obj += (OpenGLVMobject(), Mobject())
obj += (VMobject(), Mobject())
assert len(obj.submobjects) == 1
with pytest.raises(ValueError):
# a Mobject cannot contain itself
@ -304,8 +304,8 @@ def test_vgroup_add_dunder():
def test_vgroup_remove():
"""Test the VGroup remove method."""
a = OpenGLVMobject()
c = OpenGLVMobject()
a = VMobject()
c = VMobject()
b = VGroup(c)
obj = VGroup(a, b)
assert len(obj.submobjects) == 2
@ -320,8 +320,8 @@ def test_vgroup_remove():
def test_vgroup_remove_dunder():
"""Test the VGroup __sub__ magic method."""
a = OpenGLVMobject()
c = OpenGLVMobject()
a = VMobject()
c = VMobject()
b = VGroup(c)
obj = VGroup(a, b)
assert len(obj.submobjects) == 2
@ -338,7 +338,7 @@ def test_vgroup_remove_dunder():
def test_vmob_add_to_back():
"""Test the Mobject add_to_back method."""
a = OpenGLVMobject()
a = VMobject()
b = Line()
c = "text"
with pytest.raises(ValueError):
@ -371,14 +371,14 @@ def test_vdict_init():
# Test empty VDict
VDict()
# Test VDict made from list of pairs
VDict([("a", OpenGLVMobject()), ("b", OpenGLVMobject()), ("c", OpenGLVMobject())])
VDict([("a", VMobject()), ("b", VMobject()), ("c", VMobject())])
# Test VDict made from a python dict
VDict({"a": OpenGLVMobject(), "b": OpenGLVMobject(), "c": OpenGLVMobject()})
VDict({"a": VMobject(), "b": VMobject(), "c": VMobject()})
# Test VDict made using zip
VDict(
zip(
["a", "b", "c"],
[OpenGLVMobject(), OpenGLVMobject(), OpenGLVMobject()],
[VMobject(), VMobject(), VMobject()],
strict=False,
)
)
@ -391,7 +391,7 @@ def test_vdict_add():
"""Test the VDict add method."""
obj = VDict()
assert len(obj.submob_dict) == 0
obj.add([("a", OpenGLVMobject())])
obj.add([("a", VMobject())])
assert len(obj.submob_dict) == 1
with pytest.raises(TypeError):
obj.add([("b", Mobject())])
@ -399,7 +399,7 @@ def test_vdict_add():
def test_vdict_remove():
"""Test the VDict remove method."""
obj = VDict([("a", OpenGLVMobject())])
obj = VDict([("a", VMobject())])
assert len(obj.submob_dict) == 1
obj.remove("a")
assert len(obj.submob_dict) == 0
@ -409,8 +409,8 @@ def test_vdict_remove():
def test_vgroup_supports_item_assigment():
"""Test VGroup supports array-like assignment for VMObjects"""
a = OpenGLVMobject()
b = OpenGLVMobject()
a = VMobject()
b = VMobject()
vgroup = VGroup(a)
assert vgroup[0] == a
vgroup[0] = b
@ -423,8 +423,8 @@ def test_vgroup_item_assignment_at_correct_position():
n_items = 10
vgroup = VGroup()
for _i in range(n_items):
vgroup.add(OpenGLVMobject())
new_obj = OpenGLVMobject()
vgroup.add(VMobject())
new_obj = VMobject()
vgroup[6] = new_obj
assert vgroup[6] == new_obj
assert len(vgroup) == n_items
@ -432,17 +432,17 @@ def test_vgroup_item_assignment_at_correct_position():
def test_vgroup_item_assignment_only_allows_vmobjects():
"""Test VGroup item-assignment raises TypeError when invalid type is passed"""
vgroup = VGroup(OpenGLVMobject())
vgroup = VGroup(VMobject())
with pytest.raises(TypeError) as assign_str_info:
vgroup[0] = "invalid object"
assert str(assign_str_info.value) == (
"Only values of type OpenGLVMobject can be added as submobjects of VGroup, "
"Only values of type VMobject can be added as submobjects of VGroup, "
"but the value invalid object (at index 0) is of type str."
)
def test_trim_dummy():
o = OpenGLVMobject()
o = VMobject()
o.start_new_path(np.array([0, 0, 0]))
o.add_line_to(np.array([1, 0, 0]))
o.add_line_to(np.array([2, 0, 0]))
@ -450,7 +450,7 @@ def test_trim_dummy():
o.start_new_path(np.array([0, 1, 0]))
o.add_line_to(np.array([1, 2, 0]))
o2 = OpenGLVMobject()
o2 = VMobject()
o2.start_new_path(np.array([0, 0, 0]))
o2.add_line_to(np.array([0, 1, 0]))
o2.start_new_path(np.array([1, 0, 0]))
@ -473,9 +473,9 @@ def test_bounded_become():
"""Tests that align_points generates a bounded number of points.
https://github.com/ManimCommunity/manim/issues/1959
"""
o = OpenGLVMobject()
o = VMobject()
def draw_circle(m: OpenGLVMobject, n_points, x=0, y=0, r=1):
def draw_circle(m: VMobject, n_points, x=0, y=0, r=1):
center = np.array([x, y, 0])
m.start_new_path(center + [r, 0, 0])
for i in range(1, n_points + 1):
@ -487,10 +487,10 @@ def test_bounded_become():
for _ in range(20):
# Alternate between calls to become with different subpath sizes
a = OpenGLVMobject()
a = VMobject()
draw_circle(a, 20)
o.become(a)
b = OpenGLVMobject()
b = VMobject()
draw_circle(b, 15)
draw_circle(b, 15, x=3)
o.become(b)

View file

@ -4,34 +4,35 @@ import datetime
import pytest
from manim import Circle, Dot, FadeIn, Group, Manager, OpenGLMobject, Scene, Square
from manim import Circle, Dot, FadeIn, Group, Manager, Scene, Square
from manim.animation.animation import Wait
from manim.mobject.opengl.opengl_mobject import OpenGLMobject as Mobject
def test_scene_add_remove(dry_run):
manager = Manager(Scene)
scene = manager.scene
assert len(scene.mobjects) == 0
scene.add(OpenGLMobject())
scene.add(Mobject())
assert len(scene.mobjects) == 1
scene.add(*(OpenGLMobject() for _ in range(10)))
scene.add(*(Mobject() for _ in range(10)))
assert len(scene.mobjects) == 11
# Check that adding a mobject twice does not actually add it twice
repeated = OpenGLMobject()
repeated = Mobject()
scene.add(repeated)
assert len(scene.mobjects) == 12
scene.add(repeated)
assert len(scene.mobjects) == 12
# Check that Scene.add() returns the Scene (for chained calls)
assert scene.add(OpenGLMobject()) is scene
assert scene.add(Mobject()) is scene
manager = Manager(Scene)
scene = manager.scene
to_remove = OpenGLMobject()
to_remove = Mobject()
scene.add(to_remove)
scene.add(*(OpenGLMobject() for _ in range(10)))
scene.add(*(Mobject() for _ in range(10)))
assert len(scene.mobjects) == 11
scene.remove(to_remove)
assert len(scene.mobjects) == 10
@ -39,7 +40,7 @@ def test_scene_add_remove(dry_run):
assert len(scene.mobjects) == 10
# Check that Scene.remove() returns the instance (for chained calls)
assert scene.add(OpenGLMobject()) is scene
assert scene.add(Mobject()) is scene
def test_scene_time(dry_run):
@ -86,10 +87,10 @@ def test_replace(dry_run):
manager = Manager(Scene)
scene = manager.scene
first = OpenGLMobject(name="first")
second = OpenGLMobject(name="second")
third = OpenGLMobject(name="third")
fourth = OpenGLMobject(name="fourth")
first = Mobject(name="first")
second = Mobject(name="second")
third = Mobject(name="third")
fourth = Mobject(name="fourth")
scene.add(first)
scene.add(Group(second, third, name="group"))
@ -97,8 +98,8 @@ def test_replace(dry_run):
assert_names(scene.mobjects, ["first", "group", "fourth"])
assert_names(scene.mobjects[1], ["second", "third"])
alpha = OpenGLMobject(name="alpha")
beta = OpenGLMobject(name="beta")
alpha = Mobject(name="alpha")
beta = Mobject(name="beta")
scene.replace(first, alpha)
assert_names(scene.mobjects, ["alpha", "group", "fourth"])

View file

@ -1,6 +1,53 @@
from __future__ import annotations
from manim import *
import numpy as np
from manim.animation.fading import FadeIn
from manim.animation.transform import ApplyMethod
from manim.constants import DOWN, LEFT, ORIGIN, OUT, PI, RIGHT, UP
from manim.mobject.geometry.arc import (
AnnotationDot,
AnnularSector,
Annulus,
Arc,
ArcBetweenPoints,
Circle,
CurvedArrow,
CurvedDoubleArrow,
Dot,
Ellipse,
Sector,
)
from manim.mobject.geometry.labeled import LabeledArrow, LabeledLine, LabeledPolygram
from manim.mobject.geometry.line import (
Angle,
Arrow,
DashedLine,
DoubleArrow,
Elbow,
Line,
RightAngle,
Vector,
)
from manim.mobject.geometry.polygram import (
ConvexHull,
Polygon,
Polygram,
Rectangle,
RegularPolygram,
RoundedRectangle,
Square,
Star,
Triangle,
)
from manim.mobject.geometry.tips import ArrowCircleTip, ArrowSquareFilledTip
from manim.mobject.opengl.opengl_vectorized_mobject import (
OpenGLDashedVMobject as DashedVMobject,
)
from manim.mobject.opengl.opengl_vectorized_mobject import (
OpenGLVGroup as VGroup,
)
from manim.utils.color import BLUE, GREEN, RED
from manim.utils.testing.frames_comparison import frames_comparison
__module_test__ = "geometry"