ManimCommunity / ManimCommunity/manim
Bug: AttributeError when using ReplacementTransform and opengl
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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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