Repository: ManimCommunity/manim

Issue:
Transform into a complex transformed vmobject errors in OpenGL
## Description of bug / unexpected behavior
<!-- Add a clear and concise description of the problem you encountered. -->
My code doesn't work in opengl, but works fine with cairo.
Code:
```py
from manim import *


def func(x):
    return np.sin(x) + np.sin(5 * x)


class Test(Scene):
    def construct(self):
        plane = NumberPlane()
        graph = plane.get_graph(func, [-PI, PI, 0.01], color=YELLOW)
        graph2 = graph.copy().apply_complex_function(np.exp)
        self.add(plane, graph)
        self.play(Transform(graph, graph2))
        self.wait()
```
Error (full log below): `AttributeError: Mobject object has no attribute 'start_new_path'`

## Expected behavior
<!-- Add a clear and concise description of what you expected to happen. -->
Cairo:
![GerakKerja_ManimCE_v0 10 0](https://user-images.githubusercontent.com/83535735/132718814-e1b7fad7-4472-42ce-a04e-ee753b018396.png)


## How to reproduce the issue
<!-- Provide a piece of code illustrating the undesired behavior. -->

<details><summary>Code for reproducing the problem</summary>

```py
Paste your code here.
```

</details>


## Additional media files
<!-- Paste in the files manim produced on rendering the code above. -->

<details><summary>Images/GIFs</summary>

<!-- PASTE MEDIA HERE -->

</details>


## Logs
<details><summary>Terminal output</summary>
<!-- Add "-v DEBUG" when calling manim to generate more detailed logs -->

```
Manim Community v0.9.0

╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮
│ C:\Users\myname\GitHub\manim\manim\cli\render\commands.py:108 in render                         │
│                                                                                                  │
│   105 │   │   │   while keep_running:                                                            │
│   106 │   │   │   │   for SceneClass in scene_classes_from_file(file):                           │
│   107 │   │   │   │   │   scene = SceneClass(renderer)                                           │
│ ❱ 108 │   │   │   │   │   status = scene.render()                                                │
│   109 │   │   │   │   │   if status:                                                             │
│   110 │   │   │   │   │   │   continue                                                           │
│   111 │   │   │   │   │   else:                                                                  │
│                                                                                                  │
│ C:\Users\myname\GitHub\manim\manim\scene\scene.py:215 in render                                 │
│                                                                                                  │
│    212 │   │   """                                                                               │
│    213 │   │   self.setup()                                                                      │
│    214 │   │   try:                                                                              │
│ ❱  215 │   │   │   self.construct()                                                              │
│    216 │   │   except EndSceneEarlyException:                                                    │
│    217 │   │   │   pass                                                                          │
│    218 │   │   except RerunSceneException as e:                                                  │
│                                                                                                  │
│ C:\Users\myname\siri_fourier.py:14 in construct                         │
│                                                                                                  │
│   11 │   │   graph = plane.get_graph(func, [-PI, PI, 0.01], color=YELLOW)                        │
│   12 │   │   graph2 = graph.copy().apply_complex_function(np.exp)                                │
│   13 │   │   self.add(plane, graph)                                                              │
│ ❱ 14 │   │   self.play(Transform(graph, graph2))                                                 │
│   15 │   │   self.wait()                                                                         │
│   16                                                                                             │
│                                                                                                  │
│ C:\Users\myname\GitHub\manim\manim\scene\scene.py:890 in play                                   │
│                                                                                                  │
│    887 │   │   │   return np.max([animation.run_time for animation in animations])               │
│    888 │                                                                                         │
│    889 │   def play(self, *args, **kwargs):                                                      │
│ ❱  890 │   │   self.renderer.play(self, *args, **kwargs)                                         │
│    891 │                                                                                         │
│    892 │   def wait(self, duration=DEFAULT_WAIT_TIME, stop_condition=None):                      │
│    893 │   │   self.play(Wait(run_time=duration, stop_condition=stop_condition))                 │
│                                                                                                  │
│ C:\Users\myname\GitHub\manim\manim\utils\caching.py:61 in wrapper                               │
│                                                                                                  │
│   58 │   │   │   "List of the first few animation hashes of the scene: %(h)s",                   │
│   59 │   │   │   {"h": str(self.animations_hashes[:5])},                                         │
│   60 │   │   )                                                                                   │
│ ❱ 61 │   │   func(self, scene, *args, **kwargs)                                                  │
│   62 │                                                                                           │
│   63 │   return wrapper                                                                          │
│   64                                                                                             │
│                                                                                                  │
│ C:\Users\myname\GitHub\manim\manim\renderer\cairo_renderer.py:46 in wrapper                     │
│                                                                                                  │
│    43 │   def wrapper(self, scene, *args, **kwargs):                                             │
│    44 │   │   self.animation_start_time = time.time()                                            │
│    45 │   │   self.file_writer.begin_animation(not self.skip_animations)                         │
│ ❱  46 │   │   func(self, scene, *args, **kwargs)                                                 │
│    47 │   │   self.file_writer.end_animation(not self.skip_animations)                           │
│    48 │   │   self.num_plays += 1                                                                │
│    49                                                                                            │
│                                                                                                  │
│ C:\Users\myname\GitHub\manim\manim\renderer\opengl_renderer.py:389 in play                      │
│                                                                                                  │
│   386 │   def play(self, scene, *args, **kwargs):                                                │
│   387 │   │   # TODO: Handle data locking / unlocking.                                           │
│   388 │   │   if scene.compile_animation_data(*args, **kwargs):                                  │
│ ❱ 389 │   │   │   scene.begin_animations()                                                       │
│   390 │   │   │   scene.play_internal()                                                          │
│   391 │                                                                                          │
│   392 │   def clear_screen(self):                                                                │
│                                                                                                  │
│ C:\Users\myname\GitHub\manim\manim\scene\scene.py:963 in begin_animations                       │
│                                                                                                  │
│    960 │   def begin_animations(self) -> None:                                                   │
│    961 │   │   """Start the animations of the scene."""                                          │
│    962 │   │   for animation in self.animations:                                                 │
│ ❱  963 │   │   │   animation.begin()                                                             │
│    964 │                                                                                         │
│    965 │   def is_current_animation_frozen_frame(self) -> bool:                                  │
│    966 │   │   """Returns whether the current animation produces a static frame (generally a Wa  │
│                                                                                                  │
│ C:\Users\myname\GitHub\manim\manim\animation\transform.py:111 in begin                          │
│                                                                                                  │
│   108 │   │   # Note, this potentially changes the structure                                     │
│   109 │   │   # of both mobject and target_mobject                                               │
│   110 │   │   if config["renderer"] == "opengl":                                                 │
│ ❱ 111 │   │   │   self.mobject.align_data_and_family(self.target_copy)                           │
│   112 │   │   else:                                                                              │
│   113 │   │   │   self.mobject.align_data(self.target_copy)                                      │
│   114 │   │   super().begin()                                                                    │
│                                                                                                  │
│ C:\Users\myname\GitHub\manim\manim\mobject\opengl_mobject.py:1576 in align_data_and_family      │
│                                                                                                  │
│   1573 │                                                                                         │
│   1574 │   def align_data_and_family(self, mobject):                                             │
│   1575 │   │   self.align_family(mobject)                                                        │
│ ❱ 1576 │   │   self.align_data(mobject)                                                          │
│   1577 │                                                                                         │
│   1578 │   def align_data(self, mobject):                                                        │
│   1579 │   │   # In case any data arrays get resized when aligned to shader data                 │
│                                                                                                  │
│ C:\Users\myname\GitHub\manim\manim\mobject\opengl_mobject.py:1584 in align_data                 │
│                                                                                                  │
│   1581 │   │   for mob1, mob2 in zip(self.get_family(), mobject.get_family()):                   │
│   1582 │   │   │   # Separate out how points are treated so that subclasses                      │
│   1583 │   │   │   # can handle that case differently if they choose                             │
│ ❱ 1584 │   │   │   mob1.align_points(mob2)                                                       │
│   1585 │   │   │   for key in mob1.data.keys() & mob2.data.keys():                               │
│   1586 │   │   │   │   if key == "points":                                                       │
│   1587 │   │   │   │   │   continue                                                              │
│                                                                                                  │
│ C:\Users\myname\GitHub\manim\manim\mobject\types\opengl_vectorized_mobject.py:827 in            │
│ align_points                                                                                     │
│                                                                                                  │
│    824 │   │   │   # If there are no points, add one to                                          │
│    825 │   │   │   # where the "center" is                                                       │
│    826 │   │   │   if not mob.has_points():                                                      │
│ ❱  827 │   │   │   │   mob.start_new_path(mob.get_center())                                      │
│    828 │   │   │   # If there's only one point, turn it into                                     │
│    829 │   │   │   # a null curve                                                                │
│    830 │   │   │   if mob.has_new_path_started():                                                │
│                                                                                                  │
│ C:\Users\myname\GitHub\manim\manim\mobject\mobject.py:568 in __getattr__                        │
│                                                                                                  │
│    565 │   │   │   return types.MethodType(setter, self)                                         │
│    566 │   │                                                                                     │
│    567 │   │   # Unhandled attribute, therefore error                                            │
│ ❱  568 │   │   raise AttributeError(f"{type(self).__name__} object has no attribute '{attr}'")   │
│    569 │                                                                                         │
│    570 │   @property                                                                             │
│    571 │   def width(self):                                                                      │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
AttributeError: Mobject object has no attribute 'start_new_path'
```

<!-- Insert screenshots here (only when absolutely necessary, we prefer copy/pasted output!) -->

</details>


## System specifications

<details><summary>System Details</summary>

- OS (with version, e.g Windows 10 v2004 or macOS 10.15 (Catalina)):
- Python version (`python/py/python3 --version`):
- Installed modules (provide output from `pip list`):
```
PASTE HERE
```
</details>

<details><summary>LaTeX details</summary>

+ LaTeX distribution (e.g. TeX Live 2020):
+ Installed LaTeX packages:
<!-- output of `tlmgr list --only-installed` for TeX Live or a screenshot of the Packages page for MikTeX -->
</details>

<details><summary>FFMPEG</summary>

Output of `ffmpeg -version`:

```
PASTE HERE
```
</details>

## Additional comments
<!-- Add further context that you think might be relevant for this issue here. -->



Discussion:

Resolving patch:
diff --git a/manim/mobject/types/opengl_vectorized_mobject.py b/manim/mobject/types/opengl_vectorized_mobject.py
--- a/manim/mobject/types/opengl_vectorized_mobject.py
+++ b/manim/mobject/types/opengl_vectorized_mobject.py
@@ -1050,6 +1050,7 @@ def wrapper(self, *args, **kwargs):
             if not np.array_equal(new_points, old_points):
                 self.refresh_triangulation()
                 self.refresh_unit_normal()
+            return self
 
         return wrapper
 


Test patch: