ManimCommunity / ManimCommunity/manim
next_section(skip_animation = True) doesn't work with opengl renderer
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 40.9k
- Forks
- 3.1k
- Avg merge
- 3d 12h
- Merged PRs (30d)
- 25
Description
## Description of bug / unexpected behavior
When attempted to use self.next_section(skip_animation = True) with opengl renderer the opengl window just froze up. At this point the code was quite large, so I reduced it to a basic test with two shapes each animated in. (see attached code). After doing that I ran the program with cairo renderer - perfect result, first animation skipped, second is being played. When switching to opengl renderer, the program broke down.
## Expected behavior
First animation skipped, second played.
## How to reproduce the issue
Code for reproducing the problem
from manim import *
class MyScene(Scene):
def construct(self):
self.next_section(skip_animations = True)
c = Circle(color = RED, fill_opacity = 1)
self.play(Write(c))
self.wait(2)
self.next_section()
s = Square(color = GREEN_B)
self.play(Create(s))
self.wait(1)
## Additional media files
Images/GIFs
## Logs
Terminal output
```
[5/7/2025 7:08:44 PM] DEBUG Skipping animation 0 caching.py:43
╭──────────────────────────── Traceback (most recent call last) ─────────────────────────────╮
│ C:\Users\mined\.virtualenvs\manim-WDlXdsyV\Lib\site-packages\manim\cli\render\commands.py: │
│ 107 in render │
│ │
│ 104 │ │ │ │ for SceneClass in scene_classes_from_file(file): │
│ 105 │ │ │ │ │ with tempconfig({}): │
│ 106 │ │ │ │ │ │ scene = SceneClass(renderer) │
│ ❱ 107 │ │ │ │ │ │ rerun = scene.render() │
│ 108 │ │ │ │ │ if rerun or config["write_all"]: │
│ 109 │ │ │ │ │ │ renderer.num_plays = 0 │
│ 110 │ │ │ │ │ │ continue │
│ │
│ C:\Users\mined\.virtualenvs\manim-WDlXdsyV\Lib\site-packages\manim\scene\scene.py:237 in │
│ render │
│ │
│ 234 │ │ """ │
│ 235 │ │ self.setup() │
│ 236 │ │ try: │
│ ❱ 237 │ │ │ self.construct() │
│ 238 │ │ except EndSceneEarlyException: │
│ 239 │ │ │ pass │
│ 240 │ │ except RerunSceneException: │
│ │
│ C:\Users\mined\Documents\manim\testing\section_test.py:8 in construct │
│ │
│ 5 │ def construct(self): │
│ 6 │ │ self.next_section(skip_animations = True) │
│ 7 │ │ c = Circle(color = RED, fill_opacity = 1) │
│ ❱ 8 │ │ self.play(Write(c)) │
│ 9 │ │ self.wait(2) │
│ 10 │ │ self.next_section() │
│ 11 │ │ s = Square(color = GREEN_B) │
│ │
│ C:\Users\mined\.virtualenvs\manim-WDlXdsyV\Lib\site-packages\manim\scene\scene.py:1125 in │
│ play │
│ │
│ 1122 │ │ │ return │
│ 1123 │ │ │
│ 1124 │ │ start_time = self.time │
│ ❱ 1125 │ │ self.renderer.play(self, *args, **kwargs) │
│ 1126 │ │ run_time = self.time - start_time │
│ 1127 │ │ if subcaption: │
│ 1128 │ │ │ if subcaption_duration is None: │
│ │
│ C:\Users\mined\.virtualenvs\manim-WDlXdsyV\Lib\site-packages\manim\utils\caching.py:44 in │
│ wrapper │
│ │
│ 41 │ │ scene.add_mobjects_from_animations(animations) │
│ 42 │ │ if self.skip_animations: │
│ 43 │ │ │ logger.debug(f"Skipping animation {self.num_plays}") │
│ ❱ 44 │ │ │ func(self, scene, *args, **kwargs) │
│ 45 │ │ │ # If the animation is skipped, we mark its hash as None. │
│ 46 │ │ │ # When sceneFileWriter will start combining partial movie files, it won't │
│ 47 │ │ │ self.animations_hashes.append(None) │
│ │
│ C:\Users\mined\.virtualenvs\manim-WDlXdsyV\Lib\site-packages\manim\renderer\opengl_rendere │
│ r.py:437 in play │
│ │
│ 434 │ │ │ self.animation_elapsed_time = scene.duration │
│ 435 │ │ │
│ 436 │ │ else: │
│ ❱ 437 │ │ │ scene.play_internal() │
│ 438 │ │ │
│ 439 │ │ self.file_writer.end_animation(not self.skip_animations) │
│ 440 │ │ self.time += scene.duration │
│ │
│ C:\Users\mined\.virtualenvs\manim-WDlXdsyV\Lib\site-packages\manim\scene\scene.py:1295 in │
│ play_internal │
│ │
│ 1292 │ │ │ self.duration, │
│ 1293 │ │ ) │
│ 1294 │ │ for t in self.time_progression: │
│ ❱ 1295 │ │ │ self.update_to_time(t) │
│ 1296 │ │ │ if not skip_rendering and not self.skip_animation_preview: │
│ 1297 │ │ │ │ self.renderer.render(self, t, self.moving_mobjects) │
│ 1298 │ │ │ if self.stop_condition is not None and self.stop_condition(): │
│ │
│ C:\Users\mined\.virtualenvs\manim-WDlXdsyV\Lib\site-packages\manim\scene\scene.py:1534 in │
│ update_to_time │
│ │
│ 1531 │ │ for animation in self.animations: │
│ 1532 │ │ │ animation.update_mobjects(dt) │
│ 1533 │ │ │ alpha = t / animation.run_time │
│ ❱ 1534 │ │ │ animation.interpolate(alpha) │
│ 1535 │ │ self.update_mobjects(dt) │
│ 1536 │ │ self.update_meshes(dt) │
│ 1537 │ │ self.update_self(dt) │
│ │
│ C:\Users\mined\.virtualenvs\manim-WDlXdsyV\Lib\site-packages\manim\animation\animation.py: │
│ 339 in interpolate │
│ │
│ 336 │ │ │ The relative time to set the animation to, 0 meaning the start, 1 meanin │
│ 337 │ │ │ the end. │
│ 338 │ │ """ │
│ ❱ 339 │ │ self.interpolate_mobject(alpha) │
│ 340 │ │
│ 341 │ def interpolate_mobject(self, alpha: float) -> None: │
│ 342 │ │ """Interpolates the mobject of the :class:`Animation` based on alpha value. │
│ │
│ C:\Users\mined\.virtualenvs\manim-WDlXdsyV\Lib\site-packages\manim\animation\animation.py: │
│ 354 in interpolate_mobject │
│ │
│ 351 │ │ families = list(self.get_all_families_zipped()) │
│ 352 │ │ for i, mobs in enumerate(families): │
│ 353 │ │ │ sub_alpha = self.get_sub_alpha(alpha, i, len(families)) │
│ ❱ 354 │ │ │ self.interpolate_submobject(*mobs, sub_alpha) │
│ 355 │ │
│ 356 │ def interpolate_submobject( │
│ 357 │ │ self, │
│ │
│ C:\Users\mined\.virtualenvs\manim-WDlXdsyV\Lib\site-packages\manim\animation\creation.py:2 │
│ 92 in interpolate_submobject │
│ │
│ 289 │ │ │ submobject.pointwise_become_partial(outline, 0, subalpha) │
│ 290 │ │ │ submobject.match_style(outline) │
│ 291 │ │ else: │
│ ❱ 292 │ │ │ submobject.interpolate(outline, starting_submobject, subalpha) │
│ 293 │
│ 294 │
│ 295 class Write(DrawBorderThenFill): │
│ │
│ C:\Users\mined\.virtualenvs\manim-WDlXdsyV\Lib\site-packages\manim\mobject\opengl\opengl_v │
│ ectorized_mobject.py:1282 in interpolate │
│ │
│ 1279 │ │ return new_points │
│ 1280 │ │
│ 1281 │ def interpolate(self, mobject1, mobject2, alpha, *args, **kwargs): │
│ ❱ 1282 │ │ super().interpolate(mobject1, mobject2, alpha, *args, **kwargs) │
│ 1283 │ │ if config["use_projection_fill_shaders"]: │
│ 1284 │ │ │ self.refresh_triangulation() │
│ 1285 │ │ else: │
│ │
│ C:\Users\mined\.virtualenvs\manim-WDlXdsyV\Lib\site-packages\manim\mobject\opengl\opengl_m │
│ object.py:2582 in interpolate │
│ │
│ 2579 │ │ │ │
│ 2580 │ │ │ func = path_func if key in ("points", "bounding_box") else interpolate │
│ 2581 │ │ │ │
│ ❱ 2582 │ │ │ self.data[key][:] = func(mobject1.data[key], mobject2.data[key], alpha) │
│ 2583 │ │ │
│ 2584 │ │ for key in self.uniforms: │
│ 2585 │ │ │ if key != "fixed_orientation_center": │
╰────────────────────────────────────────────────────────────────────────────────────────────╯
ValueError: could not broadcast input array from shape (27,3) into shape (3,3)
```
## System specifications
System Details
- OS Windows 10 v2009
- RAM: 16
- Python version 3.12.9:
- Installed modules (provide output from `pip list`):
```
asttokens 3.0.0
av 13.1.0
beautifulsoup4 4.13.4
click 8.1.8
cloup 3.0.7
colorama 0.4.6
decorator 5.2.1
executing 2.2.0
glcontext 3.0.0
ipython 9.2.0
ipython_pygments_lexers 1.1.1
isosurfaces 0.1.2
jedi 0.19.2
manim 0.19.0
ManimPango 0.6.0
mapbox_earcut 1.0.3
markdown-it-py 3.0.0
matplotlib-inline 0.1.7
mdurl 0.1.2
moderngl 5.12.0
moderngl-window 3.1.1
networkx 3.4.2
noise 1.2.2
numpy 2.2.5
parso 0.8.4
pillow 11.2.1
pip 25.0.1
prompt_toolkit 3.0.51
pure_eval 0.2.3
pycairo 1.28.0
pydub 0.25.1
pyglet 2.1.6
pyglm 2.8.2
Pygments 2.19.1
PyOpenGL 3.1.9
rich 14.0.0
scipy 1.15.2
screeninfo 0.8.1
skia-pathops 0.8.0.post2
soupsieve 2.7
srt 3.5.3
stack-data 0.6.3
svgelements 1.9.6
tqdm 4.67.1
traitlets 5.14.3
typing_extensions 4.13.2
watchdog 6.0.0
wcwidth 0.2.13
```
## Additional comments
Terminal commands used
manim -pqm 'path_to_file' MyScene
manim -p --renderer=opengl 'path_to_file' MyScene
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the case from testing/section_test.py with the OpenGL renderer and compare it with Cairo. Inspect renderer/opengl_renderer.py around play, along with the skip path in caching.py and scene.py's play_internal. Done means the first animation is skipped, the second plays, and the OpenGL window does not freeze.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- computer-graphics
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100