manim icon indicating copy to clipboard operation
manim copied to clipboard

TransformMatchingTex fails if fade_transform_mismatches set but there are no mismatches

Open kjlubick opened this issue 3 years ago • 0 comments

Description of bug / unexpected behavior

When rearranging the terms in a Latex equation, I ran into a confounding error that ended up being because I set fade_transform_matches when it wasn't strictly necessary. That is, all strings in the first equation exist in the second equation, so there is nothing to fade out or in.

Expected behavior

Setting face_transform_matches should not cause a crash, but just be a no-op if there are no arriving or exiting Latex parts

How to reproduce the issue

Code for reproducing the problem
class ReproBug(Scene):
  def construct(self):
    start = MathTex("A", "->", "B")
    end = MathTex("B", "->", "A")

    self.add(start)
    self.play(TransformMatchingTex(start, end, fade_transform_mismatches=True))

Logs

Terminal output
│   815 │   end = MathTex("B", "->", "A")                                                          │
│   816 │                                                                                          │
│   817 │   self.add(start)                                                                        │
│ ❱ 818 │   self.play(TransformMatchingTex(start, end, fade_transform_mismatches=True))            │
│   819                                                                                            │
│   820                                                                                            │
│                                                                                                  │
│ /usr/local/lib/python3.9/site-packages/manim/scene/scene.py:1012 in play                         │
│                                                                                                  │
│   1009 │   │                                                                                     │
│   1010 │   │   """                                                                               │
│   1011 │   │   start_time = self.renderer.time                                                   │
│ ❱ 1012 │   │   self.renderer.play(self, *args, **kwargs)                                         │
│   1013 │   │   run_time = self.renderer.time - start_time                                        │
│   1014 │   │   if subcaption:                                                                    │
│   1015 │   │   │   if subcaption_duration is None:                                               │
│                                                                                                  │
│ /usr/local/lib/python3.9/site-packages/manim/renderer/cairo_renderer.py:90 in play               │
│                                                                                                  │
│    87 │   │   )                                                                                  │
│    88 │   │                                                                                      │
│    89 │   │   self.file_writer.begin_animation(not self.skip_animations)                         │
│ ❱  90 │   │   scene.begin_animations()                                                           │
│    91 │   │                                                                                      │
│    92 │   │   # Save a static image, to avoid rendering non moving objects.                      │
│    93 │   │   self.static_image = self.save_static_frame_data(scene, scene.static_mobjects)      │
│                                                                                                  │
│ /usr/local/lib/python3.9/site-packages/manim/scene/scene.py:1139 in begin_animations             │
│                                                                                                  │
│   1136 │   │   """Start the animations of the scene."""                                          │
│   1137 │   │   for animation in self.animations:                                                 │
│   1138 │   │   │   animation._setup_scene(self)                                                  │
│ ❱ 1139 │   │   │   animation.begin()                                                             │
│   1140 │   │                                                                                     │
│   1141 │   │   if config.renderer != "opengl":                                                   │
│   1142 │   │   │   # Paint all non-moving objects onto the screen, so they don't                 │
│                                                                                                  │
│ /usr/local/lib/python3.9/site-packages/manim/animation/composition.py:60 in begin                │
│                                                                                                  │
│    57 │   │   if self.suspend_mobject_updating:                                                  │
│    58 │   │   │   self.group.suspend_updating()                                                  │
│    59 │   │   for anim in self.animations:                                                       │
│ ❱  60 │   │   │   anim.begin()                                                                   │
│    61 │                                                                                          │
│    62 │   def _setup_scene(self, scene) -> None:                                                 │
│    63 │   │   for anim in self.animations:                                                       │
│                                                                                                  │
│ /usr/local/lib/python3.9/site-packages/manim/animation/transform.py:805 in begin                 │
│                                                                                                  │
│   802 │                                                                                          │
│   803 │   def begin(self):                                                                       │
│   804 │   │   self.mobject[0].align_submobjects(self.mobject[1])                                 │
│ ❱ 805 │   │   super().begin()                                                                    │
│   806 │                                                                                          │
│   807 │   def ghost_to(self, source, target):                                                    │
│   808 │   │   """Replaces the source submobjects by the target submobjects and sets              │
│                                                                                                  │
│ /usr/local/lib/python3.9/site-packages/manim/animation/transform.py:749 in begin                 │
│                                                                                                  │
│   746 │   │   # and at the end it should be the other way around.                                │
│   747 │   │   start, end = self.starting_mobject, self.ending_mobject                            │
│   748 │   │   for m0, m1 in ((start[1], start[0]), (end[0], end[1])):                            │
│ ❱ 749 │   │   │   self.ghost_to(m0, m1)                                                          │
│   750 │                                                                                          │
│   751 │   def ghost_to(self, source, target):                                                    │
│   752 │   │   """Replaces the source by the target and sets the opacity to 0."""                 │
│                                                                                                  │
│ /usr/local/lib/python3.9/site-packages/manim/animation/transform.py:812 in ghost_to              │
│                                                                                                  │
│   809 │   │   the opacity to 0.                                                                  │
│   810 │   │   """                                                                                │
│   811 │   │   for sm0, sm1 in zip(source.get_family(), target.get_family()):                     │
│ ❱ 812 │   │   │   super().ghost_to(sm0, sm1)                                                     │
│   813                                                                                            │
│                                                                                                  │
│ /usr/local/lib/python3.9/site-packages/manim/animation/transform.py:753 in ghost_to              │
│                                                                                                  │
│   750 │                                                                                          │
│   751 │   def ghost_to(self, source, target):                                                    │
│   752 │   │   """Replaces the source by the target and sets the opacity to 0."""                 │
│ ❱ 753 │   │   source.replace(target, stretch=self.stretch, dim_to_match=self.dim_to_match)       │
│   754 │   │   source.set_opacity(0)                                                              │
│   755 │                                                                                          │
│   756 │   def get_all_mobjects(self) -> Sequence[Mobject]:                                       │
│                                                                                                  │
│ /usr/local/lib/python3.9/site-packages/manim/mobject/mobject.py:1599 in replace                  │
│                                                                                                  │
│   1596 │                                                                                         │
│   1597 │   def replace(self, mobject, dim_to_match=0, stretch=False):                            │
│   1598 │   │   if not mobject.get_num_points() and not mobject.submobjects:                      │
│ ❱ 1599 │   │   │   raise Warning("Attempting to replace mobject with no points")                 │
│   1600 │   │   if stretch:                                                                       │
│   1601 │   │   │   self.stretch_to_fit_width(mobject.width)                                      │
│   1602 │   │   │   self.stretch_to_fit_height(mobject.height)                                    │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
Warning: Attempting to replace mobject with no points

System specifications

System Details
  • OS (with version, e.g., Windows 10 v2004 or macOS 10.15 (Catalina)): MacOS 12.4
  • RAM: 8 GB
  • Python version (python/py/python3 --version): 3.9.13
  • Installed modules (provide output from pip list): Manim community 0.15.2 is installed. Others available upon request.
LaTeX details
  • LaTeX distribution (e.g. TeX Live 2020): MacTeX
  • Installed LaTeX packages: Available upon request
FFMPEG

Output of ffmpeg -version:

ffmpeg version 5.0.1 Copyright (c) 2000-2022 the FFmpeg developers
built with Apple clang version 13.1.6 (clang-1316.0.21.2.5)
configuration: --prefix=/usr/local/Cellar/ffmpeg/5.0.1_2 --enable-shared --enable-pthreads --enable-version3 --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librist --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libspeex --enable-libsoxr --enable-libzmq --enable-libzimg --disable-libjack --disable-indev=jack --enable-videotoolbox
libavutil      57. 17.100 / 57. 17.100
libavcodec     59. 18.100 / 59. 18.100
libavformat    59. 16.100 / 59. 16.100
libavdevice    59.  4.100 / 59.  4.100
libavfilter     8. 24.100 /  8. 24.100
libswscale      6.  4.100 /  6.  4.100
libswresample   4.  3.100 /  4.  3.100
libpostproc    56.  3.100 / 56.  3.100

Additional comments

This could probably be fixed by making FadeTransformPieces be a no-op if the input and output are empty or skip adding fades in TransformMatchingAbstractBase

kjlubick avatar Jun 23 '22 22:06 kjlubick