ManimCommunity / ManimCommunity/manim

next_section(skip_animation = True) doesn't work with opengl renderer

Open
#4,240 1 comment 0 reactions 0 assignees View on GitHub

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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.