New manim releases break My 3D Dot Groups when using OpenGL (from 0.16 to 0.17)
OpenGL renderer gives me a TypeError: object of type 'float' has no len() when I try to render 3D Dots
When trying to generate a group of 3D Dots in OpenGL in the new manim releases, I ended up getting a TypeError. I have no idea about the backend of manim, so I apologize that I can't give a more detailed explanation of the error, so I'll just try to give as much context.
Specifically, this worked when I used manim 0.16, but when I upgraded to 0.17, I got this error. I haven't experimented enough to pinpoint the exact release where this issue starts, but it's surely between 0.16 and 0.17.
Here is the specific piece of code that generates the 3D Dots.
...
dots_all = Group()
for ax in ax_grid:
dots1 = Group(
*[
Dot3D(ax.c2p(*point, 0), radius=0.04, color=colors.PURPLE)
for point in array1
]
)
dots2 = Group(
*[
Dot3D([ax.c2p(*point, 0)], radius=0.04, color=colors.RED)
for point in array2
]
)
dots_all.add(Group(dots1, dots2))
...
self.play(FadeIn(dots_all))
...
Note: this could be an issue of just 3D Dots or Groups of 3D Dots. I haven't experimented enough to pin point the exact issue.
Logs
Terminal output
/Users/great/opt/miniconda3/envs/manim/lib/python3.9/site-packages/m │
│ anim/cli/render/commands.py:97 in render │
│ │
│ 94 │ │ │ │ for SceneClass in scene_classes_from_file(file): │
│ 95 │ │ │ │ │ with tempconfig({}): │
│ 96 │ │ │ │ │ │ scene = SceneClass(renderer) │
│ ❱ 97 │ │ │ │ │ │ rerun = scene.render() │
│ 98 │ │ │ │ │ if rerun or config["write_all"]: │
│ 99 │ │ │ │ │ │ renderer.num_plays = 0 │
│ 100 │ │ │ │ │ │ continue │
│ │
│ /Users/great/opt/miniconda3/envs/manim/lib/python3.9/site-packages/m │
│ anim/scene/scene.py:223 in render │
│ │
│ 220 │ │ """ │
│ 221 │ │ self.setup() │
│ 222 │ │ try: │
│ ❱ 223 │ │ │ self.construct() │
│ 224 │ │ except EndSceneEarlyException: │
│ 225 │ │ │ pass │
│ 226 │ │ except RerunSceneException as e: │
│ │
│ /Users/great/Documents/manim │
│ animations/manifold-hypothesis/separating_spirals3d_training.py:98 in │
│ construct │
│ │
│ 95 │ │ │ │ │ else: │
│ 96 │ │ │ │ │ │ dots[1][int(i.item())].move_to(ax.c2p(*h_out)) │
│ 97 │ │ │
│ ❱ 98 │ │ self.play(FadeIn(dots_all)) │
│ 99 │ │ │
│ 100 │ │ # self.begin_ambient_camera_rotation(-0.1) │
│ 101 │
│ │
│ /Users/great/opt/miniconda3/envs/manim/lib/python3.9/site-packages/m │
│ anim/scene/scene.py:1033 in play │
│ │
│ 1030 │ │ │ return │
│ 1031 │ │ │
│ 1032 │ │ start_time = self.renderer.time │
│ ❱ 1033 │ │ self.renderer.play(self, *args, **kwargs) │
│ 1034 │ │ run_time = self.renderer.time - start_time │
│ 1035 │ │ if subcaption: │
│ 1036 │ │ │ if subcaption_duration is None: │
│ │
│ /Users/great/opt/miniconda3/envs/manim/lib/python3.9/site-packages/m │
│ anim/utils/caching.py:65 in wrapper │
│ │
│ 62 │ │ │ "List of the first few animation hashes of the scene: %(h)s │
│ 63 │ │ │ {"h": str(self.animations_hashes[:5])}, │
│ 64 │ │ ) │
│ ❱ 65 │ │ func(self, scene, *args, **kwargs) │
│ 66 │ │
│ 67 │ return wrapper │
│ 68 │
│ │
│ /Users/great/opt/miniconda3/envs/manim/lib/python3.9/site-packages/m │
│ anim/renderer/opengl_renderer.py:424 in play │
│ │
│ 421 │ │ self.file_writer.begin_animation(not self.skip_animations) │
│ 422 │ │ │
│ 423 │ │ scene.compile_animation_data(*args, **kwargs) │
│ ❱ 424 │ │ scene.begin_animations() │
│ 425 │ │ if scene.is_current_animation_frozen_frame(): │
│ 426 │ │ │ self.update_frame(scene) │
│ 427 │
│ │
│ /Users/great/opt/miniconda3/envs/manim/lib/python3.9/site-packages/m │
│ anim/scene/scene.py:1163 in begin_animations │
│ │
│ 1160 │ │ """Start the animations of the scene.""" │
│ 1161 │ │ for animation in self.animations: │
│ 1162 │ │ │ animation._setup_scene(self) │
│ ❱ 1163 │ │ │ animation.begin() │
│ 1164 │ │ │
│ 1165 │ │ if config.renderer == RendererType.CAIRO: │
│ 1166 │ │ │ # Paint all non-moving objects onto the screen, so they d │
│ │
│ /Users/great/opt/miniconda3/envs/manim/lib/python3.9/site-packages/m │
│ anim/animation/transform.py:201 in begin │
│ │
│ 198 │ │ # Note, this potentially changes the structure │
│ 199 │ │ # of both mobject and target_mobject │
│ 200 │ │ if config.renderer == RendererType.OPENGL: │
│ ❱ 201 │ │ │ self.mobject.align_data_and_family(self.target_copy) │
│ 202 │ │ else: │
│ 203 │ │ │ self.mobject.align_data(self.target_copy) │
│ 204 │ │ super().begin() │
│ │
│ /Users/great/opt/miniconda3/envs/manim/lib/python3.9/site-packages/m │
│ anim/mobject/opengl/opengl_mobject.py:2306 in align_data_and_family │
│ │
│ 2303 │ │
│ 2304 │ def align_data_and_family(self, mobject): │
│ 2305 │ │ self.align_family(mobject) │
│ ❱ 2306 │ │ self.align_data(mobject) │
│ 2307 │ │
│ 2308 │ def align_data(self, mobject): │
│ 2309 │ │ # In case any data arrays get resized when aligned to shader │
│ │
│ /Users/great/opt/miniconda3/envs/manim/lib/python3.9/site-packages/m │
│ anim/mobject/opengl/opengl_mobject.py:2320 in align_data │
│ │
│ 2317 │ │ │ │ │ continue │
│ 2318 │ │ │ │ arr1 = mob1.data[key] │
│ 2319 │ │ │ │ arr2 = mob2.data[key] │
│ ❱ 2320 │ │ │ │ if len(arr2) > len(arr1): │
│ 2321 │ │ │ │ │ mob1.data[key] = resize_preserving_order(arr1, le │
│ 2322 │ │ │ │ elif len(arr1) > len(arr2): │
│ 2323 │ │ │ │ │ mob2.data[key] = resize_preserving_order(arr2, le │
╰──────────────────────────────────────────────────────────────────────────────╯
TypeError: object of type 'float' has no len()
Just wanted to add to this thread: I am having the same issue but using a 3D sphere:
class MyScene(ThreeDScene):
def construct(self):
sph = Sphere(
center=(3, 0, 0),
radius=1,
resolution=(20, 20),
u_range=[0.001, PI - 0.001],
v_range=[0, TAU]
)
self.add(sph)
self.play(Create(sph))
self.play(Rotate(sph, 2 * PI)) # fails here
This produces essentially the same error as above.
This also fails with Manim Community v0.18.0.post0 when animating a Surface mobject:
from manim import *
from manim.mobject.opengl.opengl_three_dimensions import OpenGLSurface
config.renderer = RendererType.OPENGL
config.quality = "low_quality"
class Draw3DEllipsoid(ThreeDScene):
def construct(self):
# Axes setup
axes = ThreeDAxes()
self.set_camera_orientation(phi=75 * DEGREES, theta=45 * DEGREES)
# Parametric equation of the ellipsoid
def ellipsoid(u, v):
# Ellipsoid parameters
a, b, c = 2, 1, 1.5 # Semi-principal axes lengths
x = a * np.cos(u) * np.sin(v)
y = b * np.sin(u) * np.sin(v)
z = c * np.cos(v)
return np.array([x, y, z])
# Create the ellipsoid surface
ellipsoid_surface = Surface(
func=ellipsoid,
u_range=[0, 2 * PI], # Full rotation
v_range=[0, PI], # From top to bottom
resolution=(20, 20),
)
ellipsoid_surface.shift(UR) # <--- This works
# Add elements to the scene
self.add(axes, ellipsoid_surface)
self.begin_ambient_camera_rotation(rate=0.2)
self.play(ellipsoid_surface.animate.shift(DOWN)) # <--- This fails
self.wait(5)
if __name__ == "__main__":
scene = Draw3DEllipsoid()
scene.render(preview=True)
Generated error
Manim Community v0.18.0.post0
Traceback (most recent call last):
File "/home/waelti/tmp/manim/ellispoid.py", line 42, in <module>
scene.render(preview=True)
File "/home/waelti/.local/lib/python3.8/site-packages/manim/scene/scene.py", line 223, in render
self.construct()
File "/home/waelti/tmp/manim/ellispoid.py", line 37, in construct
self.play(ellipsoid_surface.animate.shift(DOWN)) # <--- This fails
File "/home/waelti/.local/lib/python3.8/site-packages/manim/scene/scene.py", line 1080, in play
self.renderer.play(self, *args, **kwargs)
File "/home/waelti/.local/lib/python3.8/site-packages/manim/utils/caching.py", line 65, in wrapper
func(self, scene, *args, **kwargs)
File "/home/waelti/.local/lib/python3.8/site-packages/manim/renderer/opengl_renderer.py", line 424, in play
scene.begin_animations()
File "/home/waelti/.local/lib/python3.8/site-packages/manim/scene/scene.py", line 1208, in begin_animations
animation.begin()
File "/home/waelti/.local/lib/python3.8/site-packages/manim/animation/transform.py", line 201, in begin
self.mobject.align_data_and_family(self.target_copy)
File "/home/waelti/.local/lib/python3.8/site-packages/manim/mobject/opengl/opengl_mobject.py", line 2312, in align_data_and_family
self.align_data(mobject)
File "/home/waelti/.local/lib/python3.8/site-packages/manim/mobject/opengl/opengl_mobject.py", line 2326, in align_data
if len(arr2) > len(arr1):
TypeError: object of type 'float' has no len()