ManimCommunity / ManimCommunity/manim

Bug: AttributeError when using ReplacementTransform and opengl

Open
#3,938 1 comment 1 reaction 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
If we use ReplacementTransform with opengl rendering, it will raise `AttributeError`

## Expected behavior
Render seccessfully

## How to reproduce the issue

```
self.play(ReplacementTransform(tex19, tex20), run_time = 3)
renderer = cairo
```
Code for reproducing the problem

## Additional media files

Images/GIFs

## Logs
Terminal output

```
│ J:\Videos\manim\main.py:68 in construct │
│ │
│ 65 │ │ self.play(FadeIn(tex8)) │
│ 66 │ │ self.wait(3) │
│ 67 │ │ tex13 = MathTex(r"f(\lambda) = \sum (a_i+\lambda b_i)^2 ", font_size=48, tex_tem │
│ > 68 │ │ self.play(ReplacementTransform(tex8, tex13)) │
│ 69 │ │ self.wait(3) │
│ 70 │ │ self.remove(tex13) │
│ 71 │ │ tex14 = MathTex(r"f(\lambda) = \sum (a_i^2 + 2\lambda a_i b_i + \lambda^2 b_i^2) │
│ │
│ C:\Python310\lib\site-packages\manim\scene\scene.py:1092 in play │
│ │
│ 1089 │ │ │ return │
│ 1090 │ │ │
│ 1091 │ │ start_time = self.renderer.time │
│ > 1092 │ │ self.renderer.play(self, *args, **kwargs) │
│ 1093 │ │ run_time = self.renderer.time - start_time │
│ 1094 │ │ if subcaption: │
│ 1095 │ │ │ if subcaption_duration is None: │
│ │
│ C:\Python310\lib\site-packages\manim\utils\caching.py:67 in wrapper │
│ │
│ 64 │ │ │ "List of the first few animation hashes of the scene: %(h)s", │
│ 65 │ │ │ {"h": str(self.animations_hashes[:5])}, │
│ 66 │ │ ) │
│ > 67 │ │ func(self, scene, *args, **kwargs) │
│ 68 │ │
│ 69 │ return wrapper │
│ 70 │
│ │
│ C:\Python310\lib\site-packages\manim\renderer\opengl_renderer.py:423 in play │
│ │
│ 420 │ │ self.file_writer.begin_animation(not self.skip_animations) │
│ 421 │ │ │
│ 422 │ │ scene.compile_animation_data(*args, **kwargs) │
│ > 423 │ │ scene.begin_animations() │
│ 424 │ │ if scene.is_current_animation_frozen_frame(): │
│ 425 │ │ │ self.update_frame(scene) │
│ 426 │
│ │
│ C:\Python310\lib\site-packages\manim\scene\scene.py:1224 in begin_animations │
│ │
│ 1221 │ │ """Start the animations of the scene.""" │
│ 1222 │ │ for animation in self.animations: │
│ 1223 │ │ │ animation._setup_scene(self) │
│ > 1224 │ │ │ animation.begin() │
│ 1225 │ │ │
│ 1226 │ │ if config.renderer == RendererType.CAIRO: │
│ 1227 │ │ │ # Paint all non-moving objects onto the screen, so they don't │
│ │
│ C:\Python310\lib\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() │
│ │
│ C:\Python310\lib\site-packages\manim\mobject\opengl\opengl_mobject.py:2315 in │
│ align_data_and_family │
│ │
│ 2312 │ │
│ 2313 │ def align_data_and_family(self, mobject): │
│ 2314 │ │ self.align_family(mobject) │
│ > 2315 │ │ self.align_data(mobject) │
│ 2316 │ │
│ 2317 │ def align_data(self, mobject): │
│ 2318 │ │ # In case any data arrays get resized when aligned to shader data │
│ │
│ C:\Python310\lib\site-packages\manim\mobject\opengl\opengl_mobject.py:2323 in align_data │
│ │
│ 2320 │ │ for mob1, mob2 in zip(self.get_family(), mobject.get_family()): │
│ 2321 │ │ │ # Separate out how points are treated so that subclasses │
│ 2322 │ │ │ # can handle that case differently if they choose │
│ > 2323 │ │ │ mob1.align_points(mob2) │
│ 2324 │ │ │ for key in mob1.data.keys() & mob2.data.keys(): │
│ 2325 │ │ │ │ if key == "points": │
│ 2326 │ │ │ │ │ continue │
│ │
│ C:\Python310\lib\site-packages\manim\mobject\opengl\opengl_vectorized_mobject.py:1227 in │
│ align_points │
│ │
│ 1224 │ │ │ diff1 = max(0, (len(sp2) - len(sp1)) // nppc) │
│ 1225 │ │ │ diff2 = max(0, (len(sp1) - len(sp2)) // nppc) │
│ 1226 │ │ │ sp1 = self.insert_n_curves_to_point_list(diff1, sp1) │
│ > 1227 │ │ │ sp2 = self.insert_n_curves_to_point_list(diff2, sp2) │
│ 1228 │ │ │ new_subpaths1.append(sp1) │
│ 1229 │ │ │ new_subpaths2.append(sp2) │
│ 1230 │ │ self.set_points(np.vstack(new_subpaths1)) │
│ │
│ C:\Python310\lib\site-packages\manim\mobject\opengl\opengl_vectorized_mobject.py:1277 in │
│ insert_n_curves_to_point_list │
│ │
│ 1274 │ │ if len(points) == 1: │
│ 1275 │ │ │ return np.repeat(points, nppc * n, 0) │
│ 1276 │ │ │
│ > 1277 │ │ bezier_groups = self.get_bezier_tuples_from_points(points) │
│ 1278 │ │ norms = np.array([np.linalg.norm(bg[nppc - 1] - bg[0]) for bg in bezier_groups]) │
│ 1279 │ │ total_norm = sum(norms) │
│ 1280 │ │ # Calculate insertions per curve (ipc) │
│ │
│ C:\Python310\lib\site-packages\manim\mobject\opengl\opengl_vectorized_mobject.py:727 in │
│ get_bezier_tuples_from_points │
│ │
│ 724 │ │ nppc = self.n_points_per_curve │
│ 725 │ │ remainder = len(points) % nppc │
│ 726 │ │ points = points[: len(points) - remainder] │
│ > 727 │ │ return points.reshape((-1, nppc, 3)) │
│ 728 │ │
│ 729 │ def get_bezier_tuples(self): │
│ 730 │ │ return self.get_bezier_tuples_from_points(self.points) │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘
AttributeError: 'list' object has no attribute 'reshape'
```

## System specifications

System Details

- OS (with version, e.g., Windows 11): Windows 11
- RAM: 16GB(2GB available)
- Python version (`python/py/python3 --version`): Python 3.10
- Installed modules (provide output from `pip list`):
```
PASTE HERE
```

LaTeX details

+ LaTeX distribution (e.g. TeX Live 2020): MikTeX
+ Installed LaTeX packages:

## Additional comments
It's works with cairo

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

Start at animation/transform.py in ReplacementTransform.begin, then follow the OpenGL alignment path in mobject/opengl/opengl_mobject.py and mobject/opengl/opengl_vectorized_mobject.py, especially align_points and get_bezier_tuples_from_points. Reproduce the reported ReplacementTransform with OpenGL and verify that it renders successfully without the AttributeError.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
computer-graphics
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.