Source code for manim.scene.section

"""building blocks of segmented video API"""

from __future__ import annotations

from enum import Enum
from pathlib import Path
from typing import Any

from manim import get_video_metadata


[docs]class DefaultSectionType(str, Enum): """The type of a section can be used for third party applications. A presentation system could for example use the types to created loops. Examples -------- This class can be reimplemented for more types:: class PresentationSectionType(str, Enum): # start, end, wait for continuation by user NORMAL = "presentation.normal" # start, end, immediately continue to next section SKIP = "presentation.skip" # start, end, restart, immediately continue to next section when continued by user LOOP = "presentation.loop" # start, end, restart, finish animation first when user continues COMPLETE_LOOP = "presentation.complete_loop" """ NORMAL = "default.normal"
[docs]class Section: """A :class:`.Scene` can be segmented into multiple Sections. Refer to :doc:`the documentation</tutorials/output_and_config>` for more info. It consists of multiple animations. Attributes ---------- type Can be used by a third party applications to classify different types of sections. video Path to video file with animations belonging to section relative to sections directory. If ``None``, then the section will not be saved. name Human readable, non-unique name for this section. skip_animations Skip rendering the animations in this section when ``True``. partial_movie_files Animations belonging to this section. See Also -------- :class:`.DefaultSectionType` :meth:`.CairoRenderer.update_skipping_status` :meth:`.OpenGLRenderer.update_skipping_status` """ def __init__(self, type: str, video: str | None, name: str, skip_animations: bool): self.type = type # None when not to be saved -> still keeps section alive self.video: str | None = video self.name = name self.skip_animations = skip_animations self.partial_movie_files: list[str | None] = []
[docs] def is_empty(self) -> bool: """Check whether this section is empty. Note that animations represented by ``None`` are also counted. """ return len(self.partial_movie_files) == 0
[docs] def get_clean_partial_movie_files(self) -> list[str]: """Return all partial movie files that are not ``None``.""" return [el for el in self.partial_movie_files if el is not None]
[docs] def get_dict(self, sections_dir: Path) -> dict[str, Any]: """Get dictionary representation with metadata of output video. The output from this function is used from every section to build the sections index file. The output video must have been created in the ``sections_dir`` before executing this method. This is the main part of the Segmented Video API. """ if self.video is None: raise ValueError( f"Section '{self.name}' cannot be exported as dict, it does not have a video path assigned to it" ) video_metadata = get_video_metadata(sections_dir / self.video) return dict( { "name": self.name, "type": self.type, "video": self.video, }, **video_metadata, )
def __repr__(self): return f"<Section '{self.name}' stored in '{self.video}'>"