diff --git a/manim/file_writer/file_writer.py b/manim/file_writer/file_writer.py index 660b795436..6183a8548a 100644 --- a/manim/file_writer/file_writer.py +++ b/manim/file_writer/file_writer.py @@ -36,7 +36,7 @@ from manim.utils.sounds import get_full_sound_file_path if TYPE_CHECKING: - from manim.typing import PixelArray, StrOrBytesPath + from manim.typing import PixelArray, StrOrBytesPath, StrPath def to_av_frame_rate(fps: float) -> Fraction: @@ -76,8 +76,7 @@ def convert_audio( class FileWriter(FileWriterProtocol): - """ - FileWriter is the object that actually writes the animations + """FileWriter is the object that actually writes the animations played, into video files, using FFMPEG. This is mostly for Manim's internal use. You will rarely, if ever, have to use the methods for this class, unless tinkering with the very @@ -272,9 +271,11 @@ def get_resolution_directory(self) -> str: |--Tex |--texts |--videos - |-- - |--p - |--.mp4 + |-- + |--p + |--partial_movie_files + |--.mp4 + |--.srt Returns ------- @@ -300,8 +301,7 @@ def add_audio_segment( time: float | None = None, gain_to_background: float | None = None, ) -> None: - """ - This method adds an audio segment from an + """This method adds an audio segment from an AudioSegment type object and suitable parameters. Parameters @@ -310,8 +310,7 @@ def add_audio_segment( The audio segment to add time - the timestamp at which the - sound should be added. + the timestamp at which the sound should be added. gain_to_background The gain of the segment from the background. @@ -346,8 +345,7 @@ def add_sound( gain: float | None = None, **kwargs: Any, ) -> None: - """ - This method adds an audio segment from a sound file. + """This method adds an audio segment from a sound file. Parameters ---------- @@ -385,10 +383,9 @@ def add_sound( # Writers def begin_animation( - self, allow_write: bool = False, file_path: str | None = None + self, allow_write: bool = False, file_path: StrPath | None = None ) -> None: - """ - Used internally by manim to stream the animation to FFMPEG for + """Used internally by manim to stream the animation to FFMPEG for displaying or writing to a file. Parameters @@ -400,8 +397,7 @@ def begin_animation( self.open_partial_movie_stream(file_path=file_path) def end_animation(self, allow_write: bool = False) -> None: - """ - Internally used by Manim to stop streaming to + """Internally used by Manim to stop streaming to FFMPEG gracefully. Parameters @@ -423,8 +419,7 @@ def listen_and_write(self) -> None: self.encode_and_write_frame(frame_data, num_frames) def encode_and_write_frame(self, frame: PixelArray, num_frames: int) -> None: - """ - For internal use only: takes a given frame in ``np.ndarray`` format and + """For internal use only: takes a given frame in ``np.ndarray`` format and write it to the stream """ for _ in range(num_frames): @@ -439,9 +434,7 @@ def encode_and_write_frame(self, frame: PixelArray, num_frames: int) -> None: self.video_container.mux(packet) def write_frame(self, frame: PixelArray, num_frames: int = 1) -> None: - """ - Used internally by Manim to write a frame to - the FFMPEG input buffer. + """Used internally by Manim to write a frame to the FFMPEG input buffer. Parameters ---------- @@ -466,7 +459,7 @@ def write_frame(self, frame: PixelArray, num_frames: int = 1) -> None: ) def output_image( - self, image: Image.Image, target_dir: str | Path, ext: str, zero_pad: int + self, image: Image.Image, target_dir: StrPath, ext: str, zero_pad: int ) -> None: if zero_pad: image.save(f"{target_dir}{str(self.frame_count).zfill(zero_pad)}{ext}") @@ -475,8 +468,7 @@ def output_image( self.frame_count += 1 def save_image(self, image: PixelArray) -> None: - """ - Saves an image in the default image directory. + """Saves an image in the default image directory. Parameters ---------- @@ -491,13 +483,9 @@ def save_image(self, image: PixelArray) -> None: self.print_file_ready_message(self.image_file_path) def finish(self) -> None: - """ - Finishes writing to the FFMPEG buffer or writing images - to output directory. - Combines the partial movie files into the - whole scene. - If save_last_frame is True, saves the last - frame in the default image directory. + """Finishes writing to the FFMPEG buffer or writing images to output directory. + Combines the partial movie files into the whole scene. + If save_last_frame is True, saves the last frame in the default image directory. """ if write_to_movie(): self.combine_to_movie() @@ -513,7 +501,7 @@ def finish(self) -> None: if self.subcaptions: self.write_subcaption_file() - def open_partial_movie_stream(self, file_path: str | None = None) -> None: + def open_partial_movie_stream(self, file_path: StrPath | None = None) -> None: """Open a container holding a video stream. This is used internally by Manim initialize the container holding @@ -640,8 +628,7 @@ def combine_files( if config.transparent and config.movie_file_extension == ".webm": output_stream.pix_fmt = "yuva420p" if create_gif: - """ - The following solution was largely inspired from this comment + """The following solution was largely inspired from this comment https://github.com/imageio/imageio/issues/995#issuecomment-1580533018, and the following code https://github.com/imageio/imageio/blob/65d79140018bb7c64c0692ea72cb4093e8d632a0/imageio/plugins/pyav.py#L927-L996. @@ -869,7 +856,7 @@ def write_subcaption_file(self) -> None: subcaption_file.write_text(srt.compose(self.subcaptions), encoding="utf-8") logger.info(f"Subcaption file has been written as {subcaption_file}") - def print_file_ready_message(self, file_path: str | Path) -> None: + def print_file_ready_message(self, file_path: StrPath) -> None: """Prints the "File Ready" message to STDOUT.""" config.output_file = str(file_path) logger.info(f"\nFile ready at {str(file_path)!r}\n") diff --git a/manim/manager.py b/manim/manager.py index 2f9cef06ce..f83d47da10 100644 --- a/manim/manager.py +++ b/manim/manager.py @@ -6,8 +6,8 @@ import platform import time import warnings -from collections.abc import Iterable, Iterator, Sequence -from typing import TYPE_CHECKING, Callable, Generic, TypeVar +from collections.abc import Callable, Iterable, Iterator, Sequence +from typing import TYPE_CHECKING, Generic, TypeVar import numpy as np @@ -108,10 +108,10 @@ def create_window(self) -> WindowProtocol | None: ------- A window if previewing, else None """ - return Window() if config.preview else None # type: ignore[abstract] + return Window() if config.preview else None def create_file_writer(self) -> FileWriterProtocol: - """Create and returna file writer instance. + """Create and return a file writer instance. This can be overridden in subclasses (plugins), if more processing is needed. diff --git a/manim/mobject/geometry/shape_matchers.py b/manim/mobject/geometry/shape_matchers.py index 86afb58db5..9a4d930ba6 100644 --- a/manim/mobject/geometry/shape_matchers.py +++ b/manim/mobject/geometry/shape_matchers.py @@ -20,6 +20,7 @@ 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.utils.color import BLACK, RED, YELLOW, ManimColor, ParsableManimColor @@ -50,7 +51,7 @@ def construct(self): def __init__( self, - *mobjects: Mobject, + *mobjects: Mobject | OpenGLMobject, color: ParsableManimColor = YELLOW, buff: float = SMALL_BUFF, corner_radius: float = 0.0, @@ -58,9 +59,9 @@ def __init__( ) -> None: from manim.mobject.mobject import Group - if not all(isinstance(mob, Mobject) for mob in mobjects): + if not all(isinstance(mob, (Mobject, OpenGLMobject)) for mob in mobjects): raise TypeError( - "Expected all inputs for parameter mobjects to be a Mobjects" + "Expected all inputs for parameter mobjects to be of type Mobject or OpenGLMobject" ) group = Group(*mobjects) @@ -122,7 +123,7 @@ def __init__( buff=buff, **kwargs, ) - self.original_fill_opacity: float = self.fill_opacity + self.original_fill_opacity: float = self.get_fill_opacity() def pointwise_become_partial(self, mobject: Mobject, a: Any, b: float) -> Self: self.set_fill(opacity=b * self.original_fill_opacity) diff --git a/manim/mobject/opengl/shader.py b/manim/mobject/opengl/shader.py index a098ed30ca..5732b141ad 100644 --- a/manim/mobject/opengl/shader.py +++ b/manim/mobject/opengl/shader.py @@ -9,8 +9,8 @@ import moderngl import numpy as np -from .. import config -from ..utils import opengl +from ... import config +from ...utils import opengl SHADER_FOLDER = Path(__file__).parent / "shaders" shader_program_cache: dict = {} diff --git a/manim/utils/ipython_magic.py b/manim/utils/ipython_magic.py index a3967012b0..10caf9667b 100644 --- a/manim/utils/ipython_magic.py +++ b/manim/utils/ipython_magic.py @@ -11,7 +11,7 @@ from manim import config, logger, tempconfig from manim.__main__ import main from manim.manager import Manager -from manim.renderer.shader import shader_program_cache +from manim.mobject.opengl.shader import shader_program_cache __all__ = ["ManimMagic"] diff --git a/manim/utils/space_ops.py b/manim/utils/space_ops.py index 31a4e9d581..f7a198f1b6 100644 --- a/manim/utils/space_ops.py +++ b/manim/utils/space_ops.py @@ -598,8 +598,7 @@ def find_intersection( v1s: Sequence[np.ndarray] | Point3D_Array, threshold: float = 1e-5, ) -> Sequence[np.ndarray]: - """ - Return the intersection of a line passing through p0 in direction v0 + """Return the intersection of a line passing through p0 in direction v0 with one passing through p1 in direction v1 (or array of intersections from arrays of such points/directions). For 3d values, it returns the point on the ray p0 + v0 * t closest to the @@ -660,8 +659,7 @@ def shoelace(x_y: np.ndarray) -> float: def shoelace_direction(x_y: np.ndarray) -> str: - """ - Uses the area determined by the shoelace method to determine whether + """Uses the area determined by the shoelace method to determine whether the input set of points is directed clockwise or counterclockwise. Returns diff --git a/mypy.ini b/mypy.ini index 160daf488b..7c0d8ad52f 100644 --- a/mypy.ini +++ b/mypy.ini @@ -59,7 +59,7 @@ ignore_errors = True ignore_errors = True [mypy-manim.cli.*] -ignore_errors = False +ignore_errors = True [mypy-manim.cli.cfg.*] ignore_errors = False @@ -71,7 +71,7 @@ ignore_errors = True ignore_errors = True [mypy-manim.mobject.geometry.*] -ignore_errors = False +ignore_errors = True [mypy-manim.renderer.*] ignore_errors = True diff --git a/tests/test_scene_rendering/test_file_writer.py b/tests/test_scene_rendering/test_file_writer.py index ea9dacb02c..a5aef8ed7d 100644 --- a/tests/test_scene_rendering/test_file_writer.py +++ b/tests/test_scene_rendering/test_file_writer.py @@ -7,7 +7,7 @@ import pytest from manim import DR, Circle, Create, Manager, Scene, Star -from manim.scene.scene_file_writer import to_av_frame_rate +from manim.file_writer.file_writer import to_av_frame_rate from manim.utils.commands import capture, get_video_metadata