manim 0.18.0.post0__py3-none-any.whl → 0.18.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of manim might be problematic. Click here for more details.

Files changed (116) hide show
  1. manim/__init__.py +3 -6
  2. manim/__main__.py +18 -10
  3. manim/_config/__init__.py +5 -2
  4. manim/_config/cli_colors.py +12 -8
  5. manim/_config/default.cfg +1 -1
  6. manim/_config/logger_utils.py +9 -8
  7. manim/_config/utils.py +637 -449
  8. manim/animation/animation.py +9 -2
  9. manim/animation/composition.py +78 -40
  10. manim/animation/creation.py +12 -6
  11. manim/animation/fading.py +0 -1
  12. manim/animation/indication.py +10 -21
  13. manim/animation/movement.py +1 -2
  14. manim/animation/rotation.py +1 -1
  15. manim/animation/specialized.py +1 -1
  16. manim/animation/speedmodifier.py +7 -2
  17. manim/animation/transform_matching_parts.py +1 -1
  18. manim/camera/camera.py +13 -4
  19. manim/cli/cfg/group.py +18 -8
  20. manim/cli/checkhealth/checks.py +2 -0
  21. manim/cli/checkhealth/commands.py +2 -0
  22. manim/cli/default_group.py +13 -5
  23. manim/cli/init/commands.py +4 -1
  24. manim/cli/plugins/commands.py +3 -0
  25. manim/cli/render/commands.py +27 -20
  26. manim/cli/render/ease_of_access_options.py +4 -3
  27. manim/cli/render/global_options.py +9 -7
  28. manim/cli/render/output_options.py +6 -5
  29. manim/cli/render/render_options.py +13 -13
  30. manim/constants.py +54 -15
  31. manim/gui/gui.py +2 -0
  32. manim/mobject/geometry/arc.py +4 -4
  33. manim/mobject/geometry/boolean_ops.py +13 -9
  34. manim/mobject/geometry/line.py +16 -8
  35. manim/mobject/geometry/polygram.py +17 -5
  36. manim/mobject/geometry/tips.py +2 -2
  37. manim/mobject/graph.py +379 -106
  38. manim/mobject/graphing/coordinate_systems.py +17 -20
  39. manim/mobject/graphing/functions.py +14 -10
  40. manim/mobject/graphing/number_line.py +1 -1
  41. manim/mobject/mobject.py +175 -72
  42. manim/mobject/opengl/opengl_compatibility.py +2 -0
  43. manim/mobject/opengl/opengl_geometry.py +26 -1
  44. manim/mobject/opengl/opengl_image_mobject.py +2 -0
  45. manim/mobject/opengl/opengl_mobject.py +3 -0
  46. manim/mobject/opengl/opengl_point_cloud_mobject.py +2 -0
  47. manim/mobject/opengl/opengl_surface.py +2 -0
  48. manim/mobject/opengl/opengl_three_dimensions.py +2 -0
  49. manim/mobject/opengl/opengl_vectorized_mobject.py +19 -14
  50. manim/mobject/svg/brace.py +2 -0
  51. manim/mobject/svg/svg_mobject.py +2 -2
  52. manim/mobject/table.py +0 -1
  53. manim/mobject/text/code_mobject.py +2 -0
  54. manim/mobject/text/numbers.py +2 -0
  55. manim/mobject/text/tex_mobject.py +1 -1
  56. manim/mobject/text/text_mobject.py +43 -6
  57. manim/mobject/three_d/three_d_utils.py +4 -4
  58. manim/mobject/three_d/three_dimensions.py +4 -4
  59. manim/mobject/types/image_mobject.py +5 -1
  60. manim/mobject/types/point_cloud_mobject.py +2 -0
  61. manim/mobject/types/vectorized_mobject.py +124 -29
  62. manim/mobject/value_tracker.py +3 -3
  63. manim/mobject/vector_field.py +3 -1
  64. manim/plugins/__init__.py +15 -1
  65. manim/plugins/plugins_flags.py +11 -5
  66. manim/renderer/cairo_renderer.py +12 -2
  67. manim/renderer/opengl_renderer.py +2 -3
  68. manim/renderer/opengl_renderer_window.py +2 -0
  69. manim/renderer/shader_wrapper.py +2 -0
  70. manim/renderer/vectorized_mobject_rendering.py +5 -0
  71. manim/scene/scene.py +22 -6
  72. manim/scene/scene_file_writer.py +3 -1
  73. manim/scene/section.py +2 -0
  74. manim/scene/three_d_scene.py +5 -6
  75. manim/scene/vector_space_scene.py +21 -5
  76. manim/typing.py +567 -67
  77. manim/utils/bezier.py +9 -18
  78. manim/utils/caching.py +2 -0
  79. manim/utils/color/BS381.py +1 -0
  80. manim/utils/color/XKCD.py +1 -0
  81. manim/utils/color/core.py +31 -13
  82. manim/utils/commands.py +8 -1
  83. manim/utils/debug.py +0 -1
  84. manim/utils/deprecation.py +3 -2
  85. manim/utils/docbuild/__init__.py +17 -0
  86. manim/utils/docbuild/autoaliasattr_directive.py +197 -0
  87. manim/utils/docbuild/autocolor_directive.py +9 -4
  88. manim/utils/docbuild/manim_directive.py +18 -9
  89. manim/utils/docbuild/module_parsing.py +198 -0
  90. manim/utils/exceptions.py +6 -0
  91. manim/utils/family.py +2 -0
  92. manim/utils/family_ops.py +5 -0
  93. manim/utils/file_ops.py +6 -2
  94. manim/utils/hashing.py +2 -0
  95. manim/utils/ipython_magic.py +2 -0
  96. manim/utils/module_ops.py +2 -0
  97. manim/utils/opengl.py +14 -0
  98. manim/utils/parameter_parsing.py +31 -0
  99. manim/utils/paths.py +12 -20
  100. manim/utils/rate_functions.py +6 -8
  101. manim/utils/space_ops.py +81 -36
  102. manim/utils/testing/__init__.py +17 -0
  103. manim/utils/testing/frames_comparison.py +7 -5
  104. manim/utils/tex.py +124 -196
  105. manim/utils/tex_file_writing.py +2 -0
  106. manim/utils/tex_templates.py +1 -0
  107. {manim-0.18.0.post0.dist-info → manim-0.18.1.dist-info}/LICENSE.community +1 -1
  108. {manim-0.18.0.post0.dist-info → manim-0.18.1.dist-info}/METADATA +29 -35
  109. manim-0.18.1.dist-info/RECORD +217 -0
  110. manim/cli/new/__init__.py +0 -0
  111. manim/cli/new/group.py +0 -189
  112. manim/plugins/import_plugins.py +0 -43
  113. manim-0.18.0.post0.dist-info/RECORD +0 -217
  114. {manim-0.18.0.post0.dist-info → manim-0.18.1.dist-info}/LICENSE +0 -0
  115. {manim-0.18.0.post0.dist-info → manim-0.18.1.dist-info}/WHEEL +0 -0
  116. {manim-0.18.0.post0.dist-info → manim-0.18.1.dist-info}/entry_points.txt +0 -0
@@ -1,7 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import typing
4
- from typing import Any
5
4
 
6
5
  import numpy as np
7
6
 
@@ -15,8 +14,14 @@ from ..utils.exceptions import EndSceneEarlyException
15
14
  from ..utils.iterables import list_update
16
15
 
17
16
  if typing.TYPE_CHECKING:
17
+ import types
18
+ from typing import Any, Iterable
19
+
20
+ from manim.animation.animation import Animation
18
21
  from manim.scene.scene import Scene
19
22
 
23
+ __all__ = ["CairoRenderer"]
24
+
20
25
 
21
26
  class CairoRenderer:
22
27
  """A renderer using Cairo.
@@ -51,7 +56,12 @@ class CairoRenderer:
51
56
  scene.__class__.__name__,
52
57
  )
53
58
 
54
- def play(self, scene, *args, **kwargs):
59
+ def play(
60
+ self,
61
+ scene: Scene,
62
+ *args: Animation | Iterable[Animation] | types.GeneratorType[Animation],
63
+ **kwargs,
64
+ ):
55
65
  # Reset skip_animations to the original state.
56
66
  # Needed when rendering only some animations, and skipping others.
57
67
  self.skip_animations = self._original_skipping_status
@@ -39,6 +39,8 @@ from .vectorized_mobject_rendering import (
39
39
  render_opengl_vectorized_mobject_stroke,
40
40
  )
41
41
 
42
+ __all__ = ["OpenGLCamera", "OpenGLRenderer"]
43
+
42
44
 
43
45
  class OpenGLCamera(OpenGLMobject):
44
46
  euler_angles = _Data()
@@ -217,9 +219,6 @@ class OpenGLCamera(OpenGLMobject):
217
219
  self.refresh_rotation_matrix()
218
220
 
219
221
 
220
- points_per_curve = 3
221
-
222
-
223
222
  class OpenGLRenderer:
224
223
  def __init__(self, file_writer_class=SceneFileWriter, skip_animations=False):
225
224
  # Measured in pixel widths, used for vector graphics
@@ -7,6 +7,8 @@ from screeninfo import get_monitors
7
7
 
8
8
  from .. import __version__, config
9
9
 
10
+ __all__ = ["Window"]
11
+
10
12
 
11
13
  class Window(PygletWindow):
12
14
  fullscreen = False
@@ -15,6 +15,8 @@ from .. import logger
15
15
  # of a dict holding all the relevant information
16
16
  # to that shader
17
17
 
18
+ __all__ = ["ShaderWrapper"]
19
+
18
20
 
19
21
  def get_shader_dir():
20
22
  return Path(__file__).parent / "shaders"
@@ -8,6 +8,11 @@ from ..utils import opengl
8
8
  from ..utils.space_ops import cross2d, earclip_triangulation
9
9
  from .shader import Shader
10
10
 
11
+ __all__ = [
12
+ "render_opengl_vectorized_mobject_fill",
13
+ "render_opengl_vectorized_mobject_stroke",
14
+ ]
15
+
11
16
 
12
17
  def build_matrix_lists(mob):
13
18
  root_hierarchical_matrix = mob.hierarchical_model_matrix()
manim/scene/scene.py CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ from manim.utils.parameter_parsing import flatten_iterable_parameters
6
+
5
7
  __all__ = ["Scene"]
6
8
 
7
9
  import copy
@@ -13,7 +15,6 @@ import threading
13
15
  import time
14
16
  import types
15
17
  from queue import Queue
16
- from typing import Callable
17
18
 
18
19
  import srt
19
20
 
@@ -25,6 +26,8 @@ try:
25
26
  dearpygui_imported = True
26
27
  except ImportError:
27
28
  dearpygui_imported = False
29
+ from typing import TYPE_CHECKING
30
+
28
31
  import numpy as np
29
32
  from tqdm import tqdm
30
33
  from watchdog.events import FileSystemEventHandler
@@ -48,6 +51,9 @@ from ..utils.family_ops import restructure_list_to_exclude_certain_family_member
48
51
  from ..utils.file_ops import open_media_file
49
52
  from ..utils.iterables import list_difference_update, list_update
50
53
 
54
+ if TYPE_CHECKING:
55
+ from typing import Callable, Iterable
56
+
51
57
 
52
58
  class RerunSceneHandler(FileSystemEventHandler):
53
59
  """A class to handle rerunning a Scene after the input file is modified."""
@@ -281,7 +287,7 @@ class Scene:
281
287
  Examples
282
288
  --------
283
289
  A typical manim script includes a class derived from :class:`Scene` with an
284
- overridden :meth:`Scene.contruct` method:
290
+ overridden :meth:`Scene.construct` method:
285
291
 
286
292
  .. code-block:: python
287
293
 
@@ -865,7 +871,11 @@ class Scene:
865
871
  )
866
872
  return all_moving_mobject_families, static_mobjects
867
873
 
868
- def compile_animations(self, *args: Animation, **kwargs):
874
+ def compile_animations(
875
+ self,
876
+ *args: Animation | Iterable[Animation] | types.GeneratorType[Animation],
877
+ **kwargs,
878
+ ):
869
879
  """
870
880
  Creates _MethodAnimations from any _AnimationBuilders and updates animation
871
881
  kwargs with kwargs passed to play().
@@ -883,7 +893,9 @@ class Scene:
883
893
  Animations to be played.
884
894
  """
885
895
  animations = []
886
- for arg in args:
896
+ arg_anims = flatten_iterable_parameters(args)
897
+ # Allow passing a generator to self.play instead of comma separated arguments
898
+ for arg in arg_anims:
887
899
  try:
888
900
  animations.append(prepare_animation(arg))
889
901
  except TypeError:
@@ -1027,7 +1039,7 @@ class Scene:
1027
1039
 
1028
1040
  def play(
1029
1041
  self,
1030
- *args,
1042
+ *args: Animation | Iterable[Animation] | types.GeneratorType[Animation],
1031
1043
  subcaption=None,
1032
1044
  subcaption_duration=None,
1033
1045
  subcaption_offset=0,
@@ -1157,7 +1169,11 @@ class Scene:
1157
1169
  """
1158
1170
  self.wait(max_time, stop_condition=stop_condition)
1159
1171
 
1160
- def compile_animation_data(self, *animations: Animation, **play_kwargs):
1172
+ def compile_animation_data(
1173
+ self,
1174
+ *animations: Animation | Iterable[Animation] | types.GeneratorType[Animation],
1175
+ **play_kwargs,
1176
+ ):
1161
1177
  """Given a list of animations, compile the corresponding
1162
1178
  static and moving mobjects, and gather the animation durations.
1163
1179
 
@@ -191,7 +191,7 @@ class SceneFileWriter:
191
191
  and not skip_animations
192
192
  ):
193
193
  # relative to index file
194
- section_video = f"{self.output_name}_{len(self.sections):04}{config.movie_file_extension}"
194
+ section_video = f"{self.output_name}_{len(self.sections):04}_{name}{config.movie_file_extension}"
195
195
 
196
196
  self.sections.append(
197
197
  Section(
@@ -725,6 +725,8 @@ class SceneFileWriter:
725
725
 
726
726
  def write_subcaption_file(self):
727
727
  """Writes the subcaption file."""
728
+ if config.output_file is None:
729
+ return
728
730
  subcaption_file = Path(config.output_file).with_suffix(".srt")
729
731
  subcaption_file.write_text(srt.compose(self.subcaptions), encoding="utf-8")
730
732
  logger.info(f"Subcaption file has been written as {subcaption_file}")
manim/scene/section.py CHANGED
@@ -8,6 +8,8 @@ from typing import Any
8
8
 
9
9
  from manim import get_video_metadata
10
10
 
11
+ __all__ = ["Section", "DefaultSectionType"]
12
+
11
13
 
12
14
  class DefaultSectionType(str, Enum):
13
15
  """The type of a section can be used for third party applications.
@@ -283,16 +283,15 @@ class ThreeDScene(Scene):
283
283
  frame_center = frame_center.get_center()
284
284
  frame_center = list(frame_center)
285
285
 
286
+ zoom_value = None
287
+ if zoom is not None:
288
+ zoom_value = config.frame_height / (zoom * cam.height)
289
+
286
290
  for value, method in [
287
291
  [theta, "theta"],
288
292
  [phi, "phi"],
289
293
  [gamma, "gamma"],
290
- [
291
- config.frame_height / (zoom * cam.height)
292
- if zoom is not None
293
- else None,
294
- "zoom",
295
- ],
294
+ [zoom_value, "zoom"],
296
295
  [frame_center, "frame_center"],
297
296
  ]:
298
297
  if value is not None:
@@ -572,7 +572,7 @@ class LinearTransformationScene(VectorScene):
572
572
  self,
573
573
  show_coordinates=True,
574
574
  leave_ghost_vectors=True,
575
- *kwargs
575
+ **kwargs
576
576
  )
577
577
 
578
578
  def construct(self):
@@ -616,6 +616,8 @@ class LinearTransformationScene(VectorScene):
616
616
  },
617
617
  }
618
618
 
619
+ self.ghost_vectors = VGroup()
620
+
619
621
  self.foreground_plane_kwargs = {
620
622
  "x_range": np.array([-config["frame_width"], config["frame_width"], 1.0]),
621
623
  "y_range": np.array([-config["frame_width"], config["frame_width"], 1.0]),
@@ -741,6 +743,13 @@ class LinearTransformationScene(VectorScene):
741
743
  mobject.target = target_mobject
742
744
  self.add_special_mobjects(self.moving_mobjects, mobject)
743
745
 
746
+ def get_ghost_vectors(self) -> VGroup:
747
+ """
748
+ Returns all ghost vectors ever added to ``self``. Each element is a ``VGroup`` of
749
+ two ghost vectors.
750
+ """
751
+ return self.ghost_vectors
752
+
744
753
  def get_unit_square(
745
754
  self, color: str = YELLOW, opacity: float = 0.3, stroke_width: float = 3
746
755
  ):
@@ -994,10 +1003,16 @@ class LinearTransformationScene(VectorScene):
994
1003
  Animation
995
1004
  The animation of the movement.
996
1005
  """
997
- start = VGroup(*pieces)
998
- target = VGroup(*(mob.target for mob in pieces))
999
- if self.leave_ghost_vectors:
1000
- self.add(start.copy().fade(0.7))
1006
+
1007
+ v_pieces = [piece for piece in pieces if isinstance(piece, VMobject)]
1008
+ start = VGroup(*v_pieces)
1009
+ target = VGroup(*(mob.target for mob in v_pieces))
1010
+
1011
+ # don't add empty VGroups
1012
+ if self.leave_ghost_vectors and start.submobjects:
1013
+ # start.copy() gives a VGroup of Vectors
1014
+ self.ghost_vectors.add(start.copy().fade(0.7))
1015
+ self.add(self.ghost_vectors[-1])
1001
1016
  return Transform(start, target, lag_ratio=0)
1002
1017
 
1003
1018
  def get_moving_mobject_movement(self, func: Callable[[np.ndarray], np.ndarray]):
@@ -1079,6 +1094,7 @@ class LinearTransformationScene(VectorScene):
1079
1094
  **kwargs
1080
1095
  Any valid keyword argument of self.apply_transposed_matrix()
1081
1096
  """
1097
+
1082
1098
  self.apply_transposed_matrix(np.array(matrix).T, **kwargs)
1083
1099
 
1084
1100
  def apply_inverse(self, matrix: np.ndarray | list | tuple, **kwargs):