Closed
Description
Description of bug / unexpected behavior
My manim version is 0.18.0. I got AttributeError: 'list' object has no attribute 'reshape'
when I ran the code with manim -pqm --renderer=opengl foo.py BugScene
in the How to reproduce the issue
section below.
I also have a solution in the Additional comments
section.
Expected behavior
It should render correctly.
How to reproduce the issue
Code for reproducing the problem
class BugScene(Scene):
def construct(self):
sin_text = Tex(r"$y = \sin(x)$").set_color(BLUE).to_corner(UL)
self.add(sin_text)
sin_text_2 = Tex(r"$y = \sin(x + \frac{\pi}{3})$").set_color(BLUE).to_corner(UL)
self.play(Transform(sin_text, sin_text_2))
self.wait()
Additional media files
Images/GIFs
Logs
Terminal output
The traceback was:╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮
│ /Users/wu/miniconda3/lib/python3.11/site-packages/manim/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/wu/miniconda3/lib/python3.11/site-packages/manim/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/wu/Documents/Code/Python/pylearn/manim_demo/sin_f.py:94 in construct │
│ │
│ 91 │ │ sin_text = Tex("$y = \sin(x)$").set_color(BLUE).to_corner(UL) │
│ 92 │ │ self.add(sin_text) │
│ 93 │ │ sin_text_2 = Tex(r"$y = \sin(x + \frac{\pi}{3})$").set_color(BLUE).to_corner(UL) │
│ ❱ 94 │ │ self.play( Transform(sin_text, sin_text_2)) │
│ 95 │ │ self.wait() │
│ 96 │
│ 97 │
│ │
│ /Users/wu/miniconda3/lib/python3.11/site-packages/manim/scene/scene.py:1080 in play │
│ │
│ 1077 │ │ │ return │
│ 1078 │ │ │
│ 1079 │ │ start_time = self.renderer.time │
│ ❱ 1080 │ │ self.renderer.play(self, *args, **kwargs) │
│ 1081 │ │ run_time = self.renderer.time - start_time │
│ 1082 │ │ if subcaption: │
│ 1083 │ │ │ if subcaption_duration is None: │
│ │
│ /Users/wu/miniconda3/lib/python3.11/site-packages/manim/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/wu/miniconda3/lib/python3.11/site-packages/manim/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/wu/miniconda3/lib/python3.11/site-packages/manim/scene/scene.py:1208 in begin_animations │
│ │
│ 1205 │ │ """Start the animations of the scene.""" │
│ 1206 │ │ for animation in self.animations: │
│ 1207 │ │ │ animation._setup_scene(self) │
│ ❱ 1208 │ │ │ animation.begin() │
│ 1209 │ │ │
│ 1210 │ │ if config.renderer == RendererType.CAIRO: │
│ 1211 │ │ │ # Paint all non-moving objects onto the screen, so they don't │
│ │
│ /Users/wu/miniconda3/lib/python3.11/site-packages/manim/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/wu/miniconda3/lib/python3.11/site-packages/manim/mobject/opengl/opengl_mobject.py:2312 in │
│ align_data_and_family │
│ │
│ 2309 │ │
│ 2310 │ def align_data_and_family(self, mobject): │
│ 2311 │ │ self.align_family(mobject) │
│ ❱ 2312 │ │ self.align_data(mobject) │
│ 2313 │ │
│ 2314 │ def align_data(self, mobject): │
│ 2315 │ │ # In case any data arrays get resized when aligned to shader data │
│ │
│ /Users/wu/miniconda3/lib/python3.11/site-packages/manim/mobject/opengl/opengl_mobject.py:2320 in │
│ align_data │
│ │
│ 2317 │ │ for mob1, mob2 in zip(self.get_family(), mobject.get_family()): │
│ 2318 │ │ │ # Separate out how points are treated so that subclasses │
│ 2319 │ │ │ # can handle that case differently if they choose │
│ ❱ 2320 │ │ │ mob1.align_points(mob2) │
│ 2321 │ │ │ for key in mob1.data.keys() & mob2.data.keys(): │
│ 2322 │ │ │ │ if key == "points": │
│ 2323 │ │ │ │ │ continue │
│ │
│ /Users/wu/miniconda3/lib/python3.11/site-packages/manim/mobject/opengl/opengl_vectorized_mobject │
│ .py:1225 in align_points │
│ │
│ 1222 │ │ │ diff2 = max(0, (len(sp1) - len(sp2)) // nppc) │
│ 1223 │ │ │ if isinstance(sp1, list): │
│ 1224 │ │ │ │ print('align_points sp1', type(sp1)) │
│ ❱ 1225 │ │ │ sp1 = self.insert_n_curves_to_point_list(diff1, sp1) │
│ 1226 │ │ │ if isinstance(sp2, list): │
│ 1227 │ │ │ │ print('align_points sp2', type(sp1)) │
│ 1228 │ │ │ sp2 = self.insert_n_curves_to_point_list(diff2, sp2) │
│ │
│ /Users/wu/miniconda3/lib/python3.11/site-packages/manim/mobject/opengl/opengl_vectorized_mobject │
│ .py:1280 in insert_n_curves_to_point_list │
│ │
│ 1277 │ │ │
│ 1278 │ │ if isinstance(points, list): │
│ 1279 │ │ │ print('insert_n_curves_to_point_list', type(points)) │
│ ❱ 1280 │ │ bezier_groups = self.get_bezier_tuples_from_points(points) │
│ 1281 │ │ norms = np.array([np.linalg.norm(bg[nppc - 1] - bg[0]) for bg in bezier_groups]) │
│ 1282 │ │ total_norm = sum(norms) │
│ 1283 │ │ # Calculate insertions per curve (ipc) │
│ │
│ /Users/wu/miniconda3/lib/python3.11/site-packages/manim/mobject/opengl/opengl_vectorized_mobject │
│ .py:720 in get_bezier_tuples_from_points │
│ │
│ 717 │ │ nppc = self.n_points_per_curve │
│ 718 │ │ remainder = len(points) % nppc │
│ 719 │ │ points = points[: len(points) - remainder] │
│ ❱ 720 │ │ return points.reshape((-1, nppc, 3)) │
│ 721 │ │
│ 722 │ def get_bezier_tuples(self): │
│ 723 │ │ return self.get_bezier_tuples_from_points(self.points) │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
AttributeError: 'list' object has no attribute 'reshape'
System specifications
System Details
- OS: macOS 14.3.1 (Sonoma)
- RAM: 64GB
- Python version: 3.11.5
- Installed modules (provide output from
pip list
):
PASTE HERE
LaTeX details
- LaTeX distribution (e.g. TeX Live 2020): TeX Live 2023
- Installed LaTeX packages:
FFMPEG
Output of ffmpeg -version
:
ffmpeg version 4.2.2 Copyright (c) 2000-2019 the FFmpeg developers
built with clang version 12.0.0
configuration: --prefix=/Users/ktietz/demo/mc3/conda-bld/ffmpeg_1628925491858/_h_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_plac --cc=arm64-apple-darwin20.0.0-clang --disable-doc --enable-avresample --enable-gmp --enable-hardcoded-tables --enable-libfreetype --enable-libvpx --enable-pthreads --enable-libopus --enable-postproc --enable-pic --enable-pthreads --enable-shared --enable-static --enable-version3 --enable-zlib --enable-libmp3lame --disable-nonfree --enable-gpl --enable-gnutls --disable-openssl --enable-libopenh264 --enable-libx264
libavutil 56. 31.100 / 56. 31.100
libavcodec 58. 54.100 / 58. 54.100
libavformat 58. 29.100 / 58. 29.100
libavdevice 58. 8.100 / 58. 8.100
libavfilter 7. 57.100 / 7. 57.100
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 5.100 / 5. 5.100
libswresample 3. 5.100 / 3. 5.100
libpostproc 55. 5.100 / 55. 5.100
Additional comments
I think the code below causes the issue:
https://github.com/ManimCommunity/manim/blob/011c36a6343baacefc092170a664624e3c4a737c/manim/mobject/opengl/opengl_vectorized_mobject.py#L1212C1-L1215C50
Because when I change the code return [path_list[-1][-1]] * nppc
to return np.array([path_list[-1][-1]] * nppc)
, it works correctly.
Metadata
Metadata
Assignees
Labels
No labels
Type
Projects
Status
🆕 New