manim
manim copied to clipboard
Issue with OpenGL rendering for Transform of SVGMobjects
Description of bug / unexpected behavior
For two SVGMobjects svg1 and svg2, self.play(Transform(svg1, svg2)) will give TypeError: object of type 'NoneType' has no len()
Expected behavior
How to reproduce the issue
Code for reproducing the problem
svg1 = SVGMObject('test1.svg')
svg2 = SVGMObject('test2.svg')
self.play(Create(svg1), Create(svg2))
self.play(Transform(svg1, svg2))
Additional media files
Images/GIFs
Logs
Terminal output
PASTE HERE OR PROVIDE LINK TO https://pastebin.com/ OR SIMILAR
transform.p │ │ y:202 in begin │ │ │ │ 199 │ │ # Note, this potentially changes the structure │ │ 200 │ │ # of both mobject and target_mobject │ │ 201 │ │ if config.renderer == RendererType.OPENGL: │ │ ❱ 202 │ │ │ self.mobject.align_data_and_family(self.target_copy) │ │ 203 │ │ else: │ │ 204 │ │ │ self.mobject.align_data(self.target_copy) │ │ 205 │ │ super().begin() │ │ │ site-packages/manim/mobject/opengl/opengl │ │ _mobject.py:2469 in align_data_and_family │ │ │ │ 2466 │ │ │ 2467 │ def align_data_and_family(self, mobject: OpenGLMobject) -> Self: │ │ 2468 │ │ self.align_family(mobject) │ │ ❱ 2469 │ │ self.align_data(mobject) │ │ 2470 │ │ return self │ │ 2471 │ │ │ 2472 │ def align_data(self, mobject: OpenGLMobject) -> Self: │ │ │ │/site-packages/manim/mobject/opengl/opengl │ │ _mobject.py:2484 in align_data │ │ │ │ 2481 │ │ │ │ │ continue │ │ 2482 │ │ │ │ arr1 = mob1.data[key] │ │ 2483 │ │ │ │ arr2 = mob2.data[key] │ │ ❱ 2484 │ │ │ │ if len(arr2) > len(arr1): │ │ 2485 │ │ │ │ │ mob1.data[key] = resize_preserving_order(arr1, len(arr2)) │ │ 2486 │ │ │ │ elif len(arr1) > len(arr2): │ │ 2487 │ │ │ │ │ mob2.data[key] = resize_preserving_order(arr2, len(arr1)) │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ TypeError: object of type 'NoneType' has no len()
System specifications
System Details
- OS (with version, e.g., Windows 10 v2004 or macOS 10.15 (Catalina)):
- RAM:
- Python version (
python/py/python3 --version): - Installed modules (provide output from
pip list):
PASTE HERE
LaTeX details
- LaTeX distribution (e.g. TeX Live 2020):
- Installed LaTeX packages:
Additional comments
manim -pql main.py Main --renderer=opengl will cause the problem, while manim -pql main.py Main works well.
I can recreate the issue with the following code and the attached svg file.
from manim import *
class Test(Scene):
def construct(self):
svg1 = SVGMobject('pic/svg_file.svg')
svg2 = SVGMobject('pic/svg_file.svg')
self.play(Create(svg1), Create(svg2))
self.play(Transform(svg1, svg2))
Command line output
$ uv run manim issue4182.py --renderer=opengl -p
Manim Community v0.19.0
╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮
│ /home/hemi/localbuild/manim/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 │
│ │
│ /home/hemi/localbuild/manim/manim/scene/scene.py:260 in render │
│ │
│ 257 │ │ """ │
│ 258 │ │ self.setup() │
│ 259 │ │ try: │
│ ❱ 260 │ │ │ self.construct() │
│ 261 │ │ except EndSceneEarlyException: │
│ 262 │ │ │ pass │
│ 263 │ │ except RerunSceneException: │
│ │
│ /home/hemi/localbuild/manim/issue/issue4182.py:8 in construct │
│ │
│ 5 │ │ svg1 = SVGMobject('pic/svg_file.svg') │
│ 6 │ │ svg2 = SVGMobject('pic/svg_file.svg') │
│ 7 │ │ self.play(Create(svg1), Create(svg2)) │
│ ❱ 8 │ │ self.play(Transform(svg1, svg2)) │
│ 9 │
│ │
│ /home/hemi/localbuild/manim/manim/scene/scene.py:1178 in play │
│ │
│ 1175 │ │ │ return │
│ 1176 │ │ │
│ 1177 │ │ start_time = self.time │
│ ❱ 1178 │ │ self.renderer.play(self, *args, **kwargs) │
│ 1179 │ │ run_time = self.time - start_time │
│ 1180 │ │ if subcaption: │
│ 1181 │ │ │ if subcaption_duration is None: │
│ │
│ /home/hemi/localbuild/manim/manim/utils/caching.py:73 in wrapper │
│ │
│ 70 │ │ │ "List of the first few animation hashes of the scene: %(h)s", │
│ 71 │ │ │ {"h": str(self.animations_hashes[:5])}, │
│ 72 │ │ ) │
│ ❱ 73 │ │ func(self, scene, *args, **kwargs) │
│ 74 │ │
│ 75 │ return wrapper │
│ 76 │
│ │
│ /home/hemi/localbuild/manim/manim/renderer/opengl_renderer.py:438 in play │
│ │
│ 435 │ │ self.file_writer.begin_animation(not self.skip_animations) │
│ 436 │ │ │
│ 437 │ │ scene.compile_animation_data(*args, **kwargs) │
│ ❱ 438 │ │ scene.begin_animations() │
│ 439 │ │ if scene.is_current_animation_frozen_frame(): │
│ 440 │ │ │ self.update_frame(scene) │
│ 441 │
│ │
│ /home/hemi/localbuild/manim/manim/scene/scene.py:1316 in begin_animations │
│ │
│ 1313 │ │ assert self.animations is not None │
│ 1314 │ │ for animation in self.animations: │
│ 1315 │ │ │ animation._setup_scene(self) │
│ ❱ 1316 │ │ │ animation.begin() │
│ 1317 │ │ │
│ 1318 │ │ if config.renderer == RendererType.CAIRO: │
│ 1319 │ │ │ # Paint all non-moving objects onto the screen, so they don't │
│ │
│ /home/hemi/localbuild/manim/manim/animation/transform.py:207 in begin │
│ │
│ 204 │ │ # Note, this potentially changes the structure │
│ 205 │ │ # of both mobject and target_mobject │
│ 206 │ │ if config.renderer == RendererType.OPENGL: │
│ ❱ 207 │ │ │ self.mobject.align_data_and_family(self.target_copy) │
│ 208 │ │ else: │
│ 209 │ │ │ self.mobject.align_data(self.target_copy) │
│ 210 │ │ super().begin() │
│ │
│ /home/hemi/localbuild/manim/manim/mobject/opengl/opengl_mobject.py:2479 in align_data_and_family │
│ │
│ 2476 │ │
│ 2477 │ def align_data_and_family(self, mobject: OpenGLMobject) -> Self: │
│ 2478 │ │ self.align_family(mobject) │
│ ❱ 2479 │ │ self.align_data(mobject) │
│ 2480 │ │ return self │
│ 2481 │ │
│ 2482 │ def align_data(self, mobject: OpenGLMobject) -> Self: │
│ │
│ /home/hemi/localbuild/manim/manim/mobject/opengl/opengl_mobject.py:2494 in align_data │
│ │
│ 2491 │ │ │ │ │ continue │
│ 2492 │ │ │ │ arr1 = mob1.data[key] │
│ 2493 │ │ │ │ arr2 = mob2.data[key] │
│ ❱ 2494 │ │ │ │ if len(arr2) > len(arr1): │
│ 2495 │ │ │ │ │ mob1.data[key] = resize_preserving_order(arr1, len(arr2)) │
│ 2496 │ │ │ │ elif len(arr1) > len(arr2): │
│ 2497 │ │ │ │ │ mob2.data[key] = resize_preserving_order(arr2, len(arr1)) │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
TypeError: object of type 'int' has no len()
SVG file content
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="210mm"
height="297mm"
viewBox="0 0 210 297"
version="1.1"
id="svg1"
inkscape:version="1.3 (0e150ed, 2023-07-21)"
sodipodi:docname="something.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#999999"
borderopacity="1"
inkscape:showpageshadow="2"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
inkscape:zoom="0.85548611"
inkscape:cx="396.85039"
inkscape:cy="561.66897"
inkscape:window-width="1392"
inkscape:window-height="1212"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="0"
inkscape:current-layer="layer1" />
<defs
id="defs1" />
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="opacity:1;fill:#646464;stroke:#73ffff;stroke-width:0;fill-opacity:1"
id="rect1"
width="115.97938"
height="102.06186"
x="32.474228"
y="56.597939" />
</g>
</svg>