manim 0.17.0__py3-none-any.whl → 0.19.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.
- manim/__init__.py +11 -6
- manim/__main__.py +62 -19
- manim/_config/__init__.py +10 -9
- manim/_config/cli_colors.py +26 -9
- manim/_config/default.cfg +1 -3
- manim/_config/logger_utils.py +23 -13
- manim/_config/utils.py +662 -468
- manim/animation/animation.py +164 -18
- manim/animation/changing.py +34 -23
- manim/animation/composition.py +265 -67
- manim/animation/creation.py +208 -26
- manim/animation/fading.py +16 -18
- manim/animation/growing.py +35 -15
- manim/animation/indication.py +150 -76
- manim/animation/movement.py +56 -22
- manim/animation/numbers.py +64 -6
- manim/animation/rotation.py +78 -7
- manim/animation/specialized.py +6 -7
- manim/animation/speedmodifier.py +13 -10
- manim/animation/transform.py +14 -11
- manim/animation/transform_matching_parts.py +3 -4
- manim/animation/updaters/mobject_update_utils.py +152 -30
- manim/animation/updaters/update.py +10 -7
- manim/camera/camera.py +182 -118
- manim/camera/mapping_camera.py +34 -3
- manim/camera/moving_camera.py +95 -74
- manim/camera/multi_camera.py +23 -15
- manim/camera/three_d_camera.py +70 -52
- manim/cli/__init__.py +17 -0
- manim/cli/cfg/group.py +76 -44
- manim/cli/checkhealth/checks.py +192 -0
- manim/cli/checkhealth/commands.py +90 -0
- manim/cli/default_group.py +158 -25
- manim/cli/init/commands.py +33 -25
- manim/cli/plugins/commands.py +16 -3
- manim/cli/render/commands.py +72 -60
- manim/cli/render/ease_of_access_options.py +4 -3
- manim/cli/render/global_options.py +59 -17
- manim/cli/render/output_options.py +6 -5
- manim/cli/render/render_options.py +98 -33
- manim/constants.py +109 -59
- manim/data_structures.py +31 -0
- manim/mobject/frame.py +8 -5
- manim/mobject/geometry/__init__.py +1 -0
- manim/mobject/geometry/arc.py +277 -135
- manim/mobject/geometry/boolean_ops.py +32 -31
- manim/mobject/geometry/labeled.py +376 -0
- manim/mobject/geometry/line.py +192 -87
- manim/mobject/geometry/polygram.py +224 -58
- manim/mobject/geometry/shape_matchers.py +61 -25
- manim/mobject/geometry/tips.py +122 -48
- manim/mobject/graph.py +1027 -419
- manim/mobject/graphing/coordinate_systems.py +533 -278
- manim/mobject/graphing/functions.py +53 -32
- manim/mobject/graphing/number_line.py +123 -65
- manim/mobject/graphing/probability.py +88 -62
- manim/mobject/graphing/scale.py +33 -19
- manim/mobject/logo.py +118 -28
- manim/mobject/matrix.py +87 -83
- manim/mobject/mobject.py +912 -442
- manim/mobject/opengl/dot_cloud.py +16 -5
- manim/mobject/opengl/opengl_compatibility.py +4 -2
- manim/mobject/opengl/opengl_geometry.py +254 -153
- manim/mobject/opengl/opengl_image_mobject.py +3 -1
- manim/mobject/opengl/opengl_mobject.py +779 -482
- manim/mobject/opengl/opengl_point_cloud_mobject.py +41 -14
- manim/mobject/opengl/opengl_surface.py +14 -92
- manim/mobject/opengl/opengl_three_dimensions.py +12 -8
- manim/mobject/opengl/opengl_vectorized_mobject.py +98 -100
- manim/mobject/svg/brace.py +173 -41
- manim/mobject/svg/svg_mobject.py +139 -53
- manim/mobject/table.py +61 -68
- manim/mobject/text/code_mobject.py +193 -539
- manim/mobject/text/numbers.py +81 -34
- manim/mobject/text/tex_mobject.py +130 -78
- manim/mobject/text/text_mobject.py +288 -164
- manim/mobject/three_d/polyhedra.py +111 -13
- manim/mobject/three_d/three_d_utils.py +17 -8
- manim/mobject/three_d/three_dimensions.py +239 -106
- manim/mobject/types/image_mobject.py +50 -30
- manim/mobject/types/point_cloud_mobject.py +120 -75
- manim/mobject/types/vectorized_mobject.py +841 -408
- manim/mobject/value_tracker.py +105 -38
- manim/mobject/vector_field.py +50 -31
- manim/opengl/__init__.py +3 -3
- manim/plugins/__init__.py +14 -1
- manim/plugins/plugins_flags.py +10 -14
- manim/renderer/cairo_renderer.py +65 -50
- manim/renderer/opengl_renderer.py +89 -69
- manim/renderer/opengl_renderer_window.py +39 -18
- manim/renderer/shader.py +123 -87
- manim/renderer/shader_wrapper.py +44 -28
- manim/renderer/vectorized_mobject_rendering.py +38 -10
- manim/scene/moving_camera_scene.py +32 -3
- manim/scene/scene.py +507 -242
- manim/scene/scene_file_writer.py +371 -220
- manim/scene/section.py +20 -16
- manim/scene/three_d_scene.py +14 -22
- manim/scene/vector_space_scene.py +223 -129
- manim/scene/zoomed_scene.py +46 -41
- manim/typing.py +990 -0
- manim/utils/bezier.py +1823 -371
- manim/utils/caching.py +12 -5
- manim/utils/color/AS2700.py +236 -0
- manim/utils/color/BS381.py +318 -0
- manim/utils/color/DVIPSNAMES.py +96 -0
- manim/utils/color/SVGNAMES.py +179 -0
- manim/utils/color/X11.py +533 -0
- manim/utils/color/XKCD.py +952 -0
- manim/utils/color/__init__.py +61 -0
- manim/utils/color/core.py +1667 -0
- manim/utils/color/manim_colors.py +218 -0
- manim/utils/commands.py +48 -20
- manim/utils/config_ops.py +39 -19
- manim/utils/debug.py +8 -7
- manim/utils/deprecation.py +86 -39
- manim/utils/docbuild/__init__.py +17 -0
- manim/utils/docbuild/autoaliasattr_directive.py +236 -0
- manim/utils/docbuild/autocolor_directive.py +99 -0
- manim/utils/docbuild/manim_directive.py +94 -41
- manim/utils/docbuild/module_parsing.py +245 -0
- manim/utils/exceptions.py +6 -0
- manim/utils/family.py +5 -3
- manim/utils/family_ops.py +17 -4
- manim/utils/file_ops.py +27 -17
- manim/utils/hashing.py +55 -45
- manim/utils/images.py +13 -7
- manim/utils/ipython_magic.py +13 -7
- manim/utils/iterables.py +163 -120
- manim/utils/module_ops.py +66 -24
- manim/utils/opengl.py +77 -24
- manim/utils/parameter_parsing.py +32 -0
- manim/utils/paths.py +30 -33
- manim/utils/polylabel.py +235 -0
- manim/utils/qhull.py +218 -0
- manim/utils/rate_functions.py +98 -32
- manim/utils/simple_functions.py +25 -33
- manim/utils/sounds.py +7 -1
- manim/utils/space_ops.py +188 -115
- manim/utils/testing/__init__.py +17 -0
- manim/utils/testing/_frames_testers.py +13 -8
- manim/utils/testing/_show_diff.py +5 -3
- manim/utils/testing/_test_class_makers.py +34 -18
- manim/utils/testing/frames_comparison.py +37 -19
- manim/utils/tex.py +130 -198
- manim/utils/tex_file_writing.py +77 -47
- manim/utils/tex_templates.py +2 -1
- manim/utils/unit.py +6 -5
- {manim-0.17.0.dist-info → manim-0.19.1.dist-info}/METADATA +64 -65
- manim-0.19.1.dist-info/RECORD +220 -0
- {manim-0.17.0.dist-info → manim-0.19.1.dist-info}/WHEEL +1 -1
- manim-0.19.1.dist-info/entry_points.txt +3 -0
- {manim-0.17.0.dist-info → manim-0.19.1.dist-info/licenses}/LICENSE.community +1 -1
- manim/cli/new/group.py +0 -189
- manim/communitycolors.py +0 -9
- manim/gui/__init__.py +0 -0
- manim/gui/gui.py +0 -82
- manim/plugins/import_plugins.py +0 -43
- manim/utils/color.py +0 -552
- manim-0.17.0.dist-info/RECORD +0 -206
- manim-0.17.0.dist-info/entry_points.txt +0 -4
- /manim/cli/{new → checkhealth}/__init__.py +0 -0
- {manim-0.17.0.dist-info → manim-0.19.1.dist-info/licenses}/LICENSE +0 -0
|
@@ -2,30 +2,32 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import itertools as it
|
|
4
4
|
import operator as op
|
|
5
|
+
from collections.abc import Callable, Iterable, Sequence
|
|
5
6
|
from functools import reduce, wraps
|
|
6
|
-
from typing import
|
|
7
|
+
from typing import Any
|
|
7
8
|
|
|
8
9
|
import moderngl
|
|
9
10
|
import numpy as np
|
|
10
|
-
from
|
|
11
|
+
from typing_extensions import Self
|
|
11
12
|
|
|
12
13
|
from manim import config
|
|
13
14
|
from manim.constants import *
|
|
14
15
|
from manim.mobject.opengl.opengl_mobject import OpenGLMobject, OpenGLPoint
|
|
15
16
|
from manim.renderer.shader_wrapper import ShaderWrapper
|
|
17
|
+
from manim.typing import Point3D, Point3DLike, Point3DLike_Array
|
|
16
18
|
from manim.utils.bezier import (
|
|
17
19
|
bezier,
|
|
20
|
+
bezier_remap,
|
|
18
21
|
get_quadratic_approximation_of_cubic,
|
|
19
22
|
get_smooth_cubic_bezier_handle_points,
|
|
20
23
|
integer_interpolate,
|
|
21
24
|
interpolate,
|
|
22
|
-
|
|
25
|
+
partial_bezier_points,
|
|
23
26
|
proportions_along_bezier_curve_for_point,
|
|
24
|
-
quadratic_bezier_remap,
|
|
25
27
|
)
|
|
26
|
-
from manim.utils.color import
|
|
28
|
+
from manim.utils.color import BLACK, WHITE, ManimColor, ParsableManimColor
|
|
27
29
|
from manim.utils.config_ops import _Data
|
|
28
|
-
from manim.utils.iterables import
|
|
30
|
+
from manim.utils.iterables import make_even, resize_with_interpolation, tuplify
|
|
29
31
|
from manim.utils.space_ops import (
|
|
30
32
|
angle_between_vectors,
|
|
31
33
|
cross2d,
|
|
@@ -35,6 +37,15 @@ from manim.utils.space_ops import (
|
|
|
35
37
|
z_to_vector,
|
|
36
38
|
)
|
|
37
39
|
|
|
40
|
+
__all__ = [
|
|
41
|
+
"triggers_refreshed_triangulation",
|
|
42
|
+
"OpenGLVMobject",
|
|
43
|
+
"OpenGLVGroup",
|
|
44
|
+
"OpenGLVectorizedPoint",
|
|
45
|
+
"OpenGLCurvesAsSubmobjects",
|
|
46
|
+
"OpenGLDashedVMobject",
|
|
47
|
+
]
|
|
48
|
+
|
|
38
49
|
|
|
39
50
|
def triggers_refreshed_triangulation(func):
|
|
40
51
|
@wraps(func)
|
|
@@ -74,6 +85,9 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
74
85
|
stroke_shader_folder = "quadratic_bezier_stroke"
|
|
75
86
|
fill_shader_folder = "quadratic_bezier_fill"
|
|
76
87
|
|
|
88
|
+
# TODO: although these are called "rgba" in singular, they are used as
|
|
89
|
+
# FloatRGBA_Arrays and should be called instead "rgbas" in plural for consistency.
|
|
90
|
+
# The same should probably apply for "stroke_width" and "unit_normal".
|
|
77
91
|
fill_rgba = _Data()
|
|
78
92
|
stroke_rgba = _Data()
|
|
79
93
|
stroke_width = _Data()
|
|
@@ -81,9 +95,9 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
81
95
|
|
|
82
96
|
def __init__(
|
|
83
97
|
self,
|
|
84
|
-
fill_color:
|
|
98
|
+
fill_color: ParsableManimColor | None = None,
|
|
85
99
|
fill_opacity: float = 0.0,
|
|
86
|
-
stroke_color:
|
|
100
|
+
stroke_color: ParsableManimColor | None = None,
|
|
87
101
|
stroke_opacity: float = 1.0,
|
|
88
102
|
stroke_width: float = DEFAULT_STROKE_WIDTH,
|
|
89
103
|
draw_stroke_behind_fill: bool = False,
|
|
@@ -137,13 +151,6 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
137
151
|
self.needs_new_triangulation = True
|
|
138
152
|
self.triangulation = np.zeros(0, dtype="i4")
|
|
139
153
|
self.orientation = 1
|
|
140
|
-
super().__init__(**kwargs)
|
|
141
|
-
self.refresh_unit_normal()
|
|
142
|
-
|
|
143
|
-
if fill_color:
|
|
144
|
-
self.fill_color = Color(fill_color)
|
|
145
|
-
if stroke_color:
|
|
146
|
-
self.stroke_color = Color(stroke_color)
|
|
147
154
|
|
|
148
155
|
self.fill_data = None
|
|
149
156
|
self.stroke_data = None
|
|
@@ -151,6 +158,17 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
151
158
|
self.stroke_shader_wrapper = None
|
|
152
159
|
self.init_shader_data()
|
|
153
160
|
|
|
161
|
+
super().__init__(**kwargs)
|
|
162
|
+
self.refresh_unit_normal()
|
|
163
|
+
|
|
164
|
+
if fill_color is not None:
|
|
165
|
+
self.fill_color = ManimColor.parse(fill_color)
|
|
166
|
+
if stroke_color is not None:
|
|
167
|
+
self.stroke_color = ManimColor.parse(stroke_color)
|
|
168
|
+
|
|
169
|
+
def _assert_valid_submobjects(self, submobjects: Iterable[OpenGLVMobject]) -> Self:
|
|
170
|
+
return self._assert_valid_submobjects_internal(submobjects, OpenGLVMobject)
|
|
171
|
+
|
|
154
172
|
def get_group_class(self):
|
|
155
173
|
return OpenGLVGroup
|
|
156
174
|
|
|
@@ -158,6 +176,15 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
158
176
|
def get_mobject_type_class():
|
|
159
177
|
return OpenGLVMobject
|
|
160
178
|
|
|
179
|
+
@property
|
|
180
|
+
def submobjects(self) -> Sequence[OpenGLVMobject]:
|
|
181
|
+
return self._submobjects if hasattr(self, "_submobjects") else []
|
|
182
|
+
|
|
183
|
+
@submobjects.setter
|
|
184
|
+
def submobjects(self, submobject_list: Iterable[OpenGLVMobject]) -> None:
|
|
185
|
+
self.remove(*self.submobjects)
|
|
186
|
+
self.add(*submobject_list)
|
|
187
|
+
|
|
161
188
|
def init_data(self):
|
|
162
189
|
super().init_data()
|
|
163
190
|
self.data.pop("rgbas")
|
|
@@ -184,7 +211,7 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
184
211
|
|
|
185
212
|
def set_fill(
|
|
186
213
|
self,
|
|
187
|
-
color:
|
|
214
|
+
color: ParsableManimColor | None = None,
|
|
188
215
|
opacity: float | None = None,
|
|
189
216
|
recurse: bool = True,
|
|
190
217
|
) -> OpenGLVMobject:
|
|
@@ -256,7 +283,10 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
256
283
|
|
|
257
284
|
if width is not None:
|
|
258
285
|
for mob in self.get_family(recurse):
|
|
259
|
-
|
|
286
|
+
if isinstance(width, np.ndarray):
|
|
287
|
+
mob.stroke_width = width
|
|
288
|
+
else:
|
|
289
|
+
mob.stroke_width = np.array([[width] for width in tuplify(width)])
|
|
260
290
|
|
|
261
291
|
if background is not None:
|
|
262
292
|
for mob in self.get_family(recurse):
|
|
@@ -311,6 +341,7 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
311
341
|
vmobject_style = vmobject.get_style()
|
|
312
342
|
if config.renderer == RendererType.OPENGL:
|
|
313
343
|
vmobject_style["stroke_width"] = vmobject_style["stroke_width"][0][0]
|
|
344
|
+
vmobject_style["fill_opacity"] = self.get_fill_opacity()
|
|
314
345
|
self.set_style(**vmobject_style, recurse=False)
|
|
315
346
|
if recurse:
|
|
316
347
|
# Does its best to match up submobject lists, and
|
|
@@ -350,14 +381,15 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
350
381
|
super().fade(darkness, recurse)
|
|
351
382
|
return self
|
|
352
383
|
|
|
384
|
+
# Todo im not quite sure why we are doing this
|
|
353
385
|
def get_fill_colors(self):
|
|
354
|
-
return [
|
|
386
|
+
return [ManimColor.from_rgb(rgba[:3]) for rgba in self.fill_rgba]
|
|
355
387
|
|
|
356
388
|
def get_fill_opacities(self):
|
|
357
389
|
return self.fill_rgba[:, 3]
|
|
358
390
|
|
|
359
391
|
def get_stroke_colors(self):
|
|
360
|
-
return [
|
|
392
|
+
return [ManimColor.from_rgb(rgba[:3]) for rgba in self.stroke_rgba]
|
|
361
393
|
|
|
362
394
|
def get_stroke_opacities(self):
|
|
363
395
|
return self.stroke_rgba[:, 3]
|
|
@@ -391,7 +423,7 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
391
423
|
return self.get_stroke_opacities()[0]
|
|
392
424
|
|
|
393
425
|
def get_color(self):
|
|
394
|
-
if self.
|
|
426
|
+
if not self.has_fill():
|
|
395
427
|
return self.get_stroke_color()
|
|
396
428
|
return self.get_fill_color()
|
|
397
429
|
|
|
@@ -447,7 +479,13 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
447
479
|
self.append_points([point])
|
|
448
480
|
return self
|
|
449
481
|
|
|
450
|
-
def add_cubic_bezier_curve(
|
|
482
|
+
def add_cubic_bezier_curve(
|
|
483
|
+
self,
|
|
484
|
+
anchor1: Point3DLike,
|
|
485
|
+
handle1: Point3DLike,
|
|
486
|
+
handle2: Point3DLike,
|
|
487
|
+
anchor2: Point3DLike,
|
|
488
|
+
):
|
|
451
489
|
new_points = get_quadratic_approximation_of_cubic(
|
|
452
490
|
anchor1,
|
|
453
491
|
handle1,
|
|
@@ -457,9 +495,7 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
457
495
|
self.append_points(new_points)
|
|
458
496
|
|
|
459
497
|
def add_cubic_bezier_curve_to(self, handle1, handle2, anchor):
|
|
460
|
-
"""
|
|
461
|
-
Add cubic bezier curve to the path.
|
|
462
|
-
"""
|
|
498
|
+
"""Add cubic bezier curve to the path."""
|
|
463
499
|
self.throw_error_if_no_points()
|
|
464
500
|
quadratic_approx = get_quadratic_approximation_of_cubic(
|
|
465
501
|
self.get_last_point(),
|
|
@@ -544,7 +580,7 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
544
580
|
alphas = np.linspace(0, 1, n + 1)
|
|
545
581
|
new_points.extend(
|
|
546
582
|
[
|
|
547
|
-
|
|
583
|
+
partial_bezier_points(tup, a1, a2)
|
|
548
584
|
for a1, a2 in zip(alphas, alphas[1:])
|
|
549
585
|
],
|
|
550
586
|
)
|
|
@@ -558,7 +594,7 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
558
594
|
self.add_line_to(point)
|
|
559
595
|
return points
|
|
560
596
|
|
|
561
|
-
def set_points_as_corners(self, points:
|
|
597
|
+
def set_points_as_corners(self, points: Point3DLike_Array) -> OpenGLVMobject:
|
|
562
598
|
"""Given an array of points, set them as corner of the vmobject.
|
|
563
599
|
|
|
564
600
|
To achieve that, this algorithm sets handles aligned with the anchors such that the resultant bezier curve will be the segment
|
|
@@ -581,7 +617,9 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
581
617
|
)
|
|
582
618
|
return self
|
|
583
619
|
|
|
584
|
-
def set_points_smoothly(
|
|
620
|
+
def set_points_smoothly(
|
|
621
|
+
self, points: Point3DLike_Array, true_smooth: bool = False
|
|
622
|
+
) -> Self:
|
|
585
623
|
self.set_points_as_corners(points)
|
|
586
624
|
self.make_smooth()
|
|
587
625
|
return self
|
|
@@ -802,7 +840,6 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
802
840
|
length : :class:`float`
|
|
803
841
|
The length of the nth curve.
|
|
804
842
|
"""
|
|
805
|
-
|
|
806
843
|
if sample_points is None:
|
|
807
844
|
sample_points = 10
|
|
808
845
|
|
|
@@ -842,7 +879,6 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
842
879
|
length : :class:`float`
|
|
843
880
|
The length of the nth curve.
|
|
844
881
|
"""
|
|
845
|
-
|
|
846
882
|
_, length = self.get_nth_curve_function_with_length(n, sample_points)
|
|
847
883
|
|
|
848
884
|
return length
|
|
@@ -857,7 +893,6 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
857
893
|
Iterable[Callable[[float], np.ndarray]]
|
|
858
894
|
The functions for the curves.
|
|
859
895
|
"""
|
|
860
|
-
|
|
861
896
|
num_curves = self.get_num_curves()
|
|
862
897
|
|
|
863
898
|
for n in range(num_curves):
|
|
@@ -907,13 +942,12 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
907
942
|
Iterable[Tuple[Callable[[float], np.ndarray], float]]
|
|
908
943
|
The functions and lengths of the curves.
|
|
909
944
|
"""
|
|
910
|
-
|
|
911
945
|
num_curves = self.get_num_curves()
|
|
912
946
|
|
|
913
947
|
for n in range(num_curves):
|
|
914
948
|
yield self.get_nth_curve_function_with_length(n, **kwargs)
|
|
915
949
|
|
|
916
|
-
def point_from_proportion(self, alpha: float) ->
|
|
950
|
+
def point_from_proportion(self, alpha: float) -> Point3D:
|
|
917
951
|
"""Gets the point at a proportion along the path of the :class:`OpenGLVMobject`.
|
|
918
952
|
|
|
919
953
|
Parameters
|
|
@@ -923,7 +957,7 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
923
957
|
|
|
924
958
|
Returns
|
|
925
959
|
-------
|
|
926
|
-
:class:`
|
|
960
|
+
:class:`Point3D`
|
|
927
961
|
The point on the :class:`OpenGLVMobject`.
|
|
928
962
|
|
|
929
963
|
Raises
|
|
@@ -933,7 +967,6 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
933
967
|
:exc:`Exception`
|
|
934
968
|
If the :class:`OpenGLVMobject` has no points.
|
|
935
969
|
"""
|
|
936
|
-
|
|
937
970
|
if alpha < 0 or alpha > 1:
|
|
938
971
|
raise ValueError(f"Alpha {alpha} not between 0 and 1.")
|
|
939
972
|
|
|
@@ -943,7 +976,9 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
943
976
|
|
|
944
977
|
curves_and_lengths = tuple(self.get_curve_functions_with_lengths())
|
|
945
978
|
|
|
946
|
-
target_length = alpha * np.sum(
|
|
979
|
+
target_length = alpha * np.sum(
|
|
980
|
+
np.fromiter((length for _, length in curves_and_lengths), dtype=np.float64)
|
|
981
|
+
)
|
|
947
982
|
current_length = 0
|
|
948
983
|
|
|
949
984
|
for curve, length in curves_and_lengths:
|
|
@@ -959,7 +994,7 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
959
994
|
|
|
960
995
|
def proportion_from_point(
|
|
961
996
|
self,
|
|
962
|
-
point:
|
|
997
|
+
point: Point3DLike,
|
|
963
998
|
) -> float:
|
|
964
999
|
"""Returns the proportion along the path of the :class:`OpenGLVMobject`
|
|
965
1000
|
a particular given point is at.
|
|
@@ -1013,7 +1048,7 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
1013
1048
|
|
|
1014
1049
|
return alpha
|
|
1015
1050
|
|
|
1016
|
-
def get_anchors_and_handles(self):
|
|
1051
|
+
def get_anchors_and_handles(self) -> Iterable[np.ndarray]:
|
|
1017
1052
|
"""
|
|
1018
1053
|
Returns anchors1, handles, anchors2,
|
|
1019
1054
|
where (anchors1[i], handles[i], anchors2[i])
|
|
@@ -1045,27 +1080,21 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
1045
1080
|
nppc = self.n_points_per_curve
|
|
1046
1081
|
return self.points[nppc - 1 :: nppc]
|
|
1047
1082
|
|
|
1048
|
-
def get_anchors(self) -> np.ndarray:
|
|
1083
|
+
def get_anchors(self) -> Iterable[np.ndarray]:
|
|
1049
1084
|
"""Returns the anchors of the curves forming the OpenGLVMobject.
|
|
1050
1085
|
|
|
1051
1086
|
Returns
|
|
1052
1087
|
-------
|
|
1053
|
-
np.ndarray
|
|
1088
|
+
Iterable[np.ndarray]
|
|
1054
1089
|
The anchors.
|
|
1055
1090
|
"""
|
|
1056
1091
|
points = self.points
|
|
1057
1092
|
if len(points) == 1:
|
|
1058
1093
|
return points
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
self.get_start_anchors(),
|
|
1064
|
-
self.get_end_anchors(),
|
|
1065
|
-
)
|
|
1066
|
-
),
|
|
1067
|
-
),
|
|
1068
|
-
)
|
|
1094
|
+
|
|
1095
|
+
s = self.get_start_anchors()
|
|
1096
|
+
e = self.get_end_anchors()
|
|
1097
|
+
return list(it.chain.from_iterable(zip(s, e)))
|
|
1069
1098
|
|
|
1070
1099
|
def get_points_without_null_curves(self, atol=1e-9):
|
|
1071
1100
|
nppc = self.n_points_per_curve
|
|
@@ -1092,7 +1121,6 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
1092
1121
|
float
|
|
1093
1122
|
The length of the :class:`OpenGLVMobject`.
|
|
1094
1123
|
"""
|
|
1095
|
-
|
|
1096
1124
|
return np.sum(
|
|
1097
1125
|
length
|
|
1098
1126
|
for _, length in self.get_curve_functions_with_lengths(
|
|
@@ -1213,8 +1241,8 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
1213
1241
|
return path
|
|
1214
1242
|
|
|
1215
1243
|
for n in range(n_subpaths):
|
|
1216
|
-
sp1 = get_nth_subpath(subpaths1, n)
|
|
1217
|
-
sp2 = get_nth_subpath(subpaths2, n)
|
|
1244
|
+
sp1 = np.asarray(get_nth_subpath(subpaths1, n))
|
|
1245
|
+
sp2 = np.asarray(get_nth_subpath(subpaths2, n))
|
|
1218
1246
|
diff1 = max(0, (len(sp2) - len(sp1)) // nppc)
|
|
1219
1247
|
diff2 = max(0, (len(sp1) - len(sp2)) // nppc)
|
|
1220
1248
|
sp1 = self.insert_n_curves_to_point_list(diff1, sp1)
|
|
@@ -1268,30 +1296,12 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
1268
1296
|
if len(points) == 1:
|
|
1269
1297
|
return np.repeat(points, nppc * n, 0)
|
|
1270
1298
|
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
else:
|
|
1278
|
-
ipc = np.round(n * norms / sum(norms)).astype(int)
|
|
1279
|
-
|
|
1280
|
-
diff = n - sum(ipc)
|
|
1281
|
-
for _ in range(diff):
|
|
1282
|
-
ipc[np.argmin(ipc)] += 1
|
|
1283
|
-
for _ in range(-diff):
|
|
1284
|
-
ipc[np.argmax(ipc)] -= 1
|
|
1285
|
-
|
|
1286
|
-
new_points = []
|
|
1287
|
-
for group, n_inserts in zip(bezier_groups, ipc):
|
|
1288
|
-
# What was once a single quadratic curve defined
|
|
1289
|
-
# by "group" will now be broken into n_inserts + 1
|
|
1290
|
-
# smaller quadratic curves
|
|
1291
|
-
alphas = np.linspace(0, 1, n_inserts + 2)
|
|
1292
|
-
for a1, a2 in zip(alphas, alphas[1:]):
|
|
1293
|
-
new_points += partial_quadratic_bezier_points(group, a1, a2)
|
|
1294
|
-
return np.vstack(new_points)
|
|
1299
|
+
bezier_tuples = self.get_bezier_tuples_from_points(points)
|
|
1300
|
+
current_number_of_curves = len(bezier_tuples)
|
|
1301
|
+
new_number_of_curves = current_number_of_curves + n
|
|
1302
|
+
new_bezier_tuples = bezier_remap(bezier_tuples, new_number_of_curves)
|
|
1303
|
+
new_points = new_bezier_tuples.reshape(-1, 3)
|
|
1304
|
+
return new_points
|
|
1295
1305
|
|
|
1296
1306
|
def interpolate(self, mobject1, mobject2, alpha, *args, **kwargs):
|
|
1297
1307
|
super().interpolate(mobject1, mobject2, alpha, *args, **kwargs)
|
|
@@ -1301,7 +1311,7 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
1301
1311
|
if self.has_fill():
|
|
1302
1312
|
tri1 = mobject1.get_triangulation()
|
|
1303
1313
|
tri2 = mobject2.get_triangulation()
|
|
1304
|
-
if len(tri1) != len(
|
|
1314
|
+
if len(tri1) != len(tri2) or not np.all(tri1 == tri2):
|
|
1305
1315
|
self.refresh_triangulation()
|
|
1306
1316
|
return self
|
|
1307
1317
|
|
|
@@ -1344,7 +1354,7 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
1344
1354
|
return self
|
|
1345
1355
|
if lower_index == upper_index:
|
|
1346
1356
|
self.append_points(
|
|
1347
|
-
|
|
1357
|
+
partial_bezier_points(
|
|
1348
1358
|
bezier_triplets[lower_index],
|
|
1349
1359
|
lower_residue,
|
|
1350
1360
|
upper_residue,
|
|
@@ -1352,24 +1362,18 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
1352
1362
|
)
|
|
1353
1363
|
else:
|
|
1354
1364
|
self.append_points(
|
|
1355
|
-
|
|
1356
|
-
bezier_triplets[lower_index], lower_residue, 1
|
|
1357
|
-
),
|
|
1365
|
+
partial_bezier_points(bezier_triplets[lower_index], lower_residue, 1),
|
|
1358
1366
|
)
|
|
1359
1367
|
inner_points = bezier_triplets[lower_index + 1 : upper_index]
|
|
1360
1368
|
if len(inner_points) > 0:
|
|
1361
1369
|
if remap:
|
|
1362
|
-
new_triplets =
|
|
1363
|
-
inner_points, num_quadratics - 2
|
|
1364
|
-
)
|
|
1370
|
+
new_triplets = bezier_remap(inner_points, num_quadratics - 2)
|
|
1365
1371
|
else:
|
|
1366
1372
|
new_triplets = bezier_triplets
|
|
1367
1373
|
|
|
1368
1374
|
self.append_points(np.asarray(new_triplets).reshape(-1, 3))
|
|
1369
1375
|
self.append_points(
|
|
1370
|
-
|
|
1371
|
-
bezier_triplets[upper_index], 0, upper_residue
|
|
1372
|
-
),
|
|
1376
|
+
partial_bezier_points(bezier_triplets[upper_index], 0, upper_residue),
|
|
1373
1377
|
)
|
|
1374
1378
|
return self
|
|
1375
1379
|
|
|
@@ -1396,7 +1400,7 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
1396
1400
|
|
|
1397
1401
|
# Related to triangulation
|
|
1398
1402
|
|
|
1399
|
-
def refresh_triangulation(self):
|
|
1403
|
+
def refresh_triangulation(self) -> Self:
|
|
1400
1404
|
for mob in self.get_family():
|
|
1401
1405
|
mob.needs_new_triangulation = True
|
|
1402
1406
|
return self
|
|
@@ -1518,6 +1522,7 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
1518
1522
|
self.fill_shader_wrapper.vert_data = self.get_fill_shader_data()
|
|
1519
1523
|
self.fill_shader_wrapper.vert_indices = self.get_triangulation()
|
|
1520
1524
|
self.fill_shader_wrapper.uniforms = self.get_fill_uniforms()
|
|
1525
|
+
self.fill_shader_wrapper.depth_test = self.depth_test
|
|
1521
1526
|
|
|
1522
1527
|
def get_stroke_shader_wrapper(self):
|
|
1523
1528
|
self.update_stroke_shader_wrapper()
|
|
@@ -1526,6 +1531,7 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
1526
1531
|
def update_stroke_shader_wrapper(self):
|
|
1527
1532
|
self.stroke_shader_wrapper.vert_data = self.get_stroke_shader_data()
|
|
1528
1533
|
self.stroke_shader_wrapper.uniforms = self.get_stroke_uniforms()
|
|
1534
|
+
self.stroke_shader_wrapper.depth_test = self.depth_test
|
|
1529
1535
|
|
|
1530
1536
|
def get_shader_wrapper_list(self):
|
|
1531
1537
|
# Build up data lists
|
|
@@ -1673,9 +1679,7 @@ class OpenGLVGroup(OpenGLVMobject):
|
|
|
1673
1679
|
self.add(circles_group)
|
|
1674
1680
|
"""
|
|
1675
1681
|
|
|
1676
|
-
def __init__(self, *vmobjects, **kwargs):
|
|
1677
|
-
if not all([isinstance(m, OpenGLVMobject) for m in vmobjects]):
|
|
1678
|
-
raise Exception("All submobjects must be of type OpenGLVMobject")
|
|
1682
|
+
def __init__(self, *vmobjects: OpenGLVMobject, **kwargs: Any):
|
|
1679
1683
|
super().__init__(**kwargs)
|
|
1680
1684
|
self.add(*vmobjects)
|
|
1681
1685
|
|
|
@@ -1741,8 +1745,6 @@ class OpenGLVGroup(OpenGLVMobject):
|
|
|
1741
1745
|
(gr-circle_red).animate.shift(RIGHT)
|
|
1742
1746
|
)
|
|
1743
1747
|
"""
|
|
1744
|
-
if not all(isinstance(m, OpenGLVMobject) for m in vmobjects):
|
|
1745
|
-
raise TypeError("All submobjects must be of type OpenGLVMobject")
|
|
1746
1748
|
return super().add(*vmobjects)
|
|
1747
1749
|
|
|
1748
1750
|
def __add__(self, vmobject):
|
|
@@ -1788,8 +1790,7 @@ class OpenGLVGroup(OpenGLVMobject):
|
|
|
1788
1790
|
|
|
1789
1791
|
>>> config.renderer = original_renderer
|
|
1790
1792
|
"""
|
|
1791
|
-
|
|
1792
|
-
raise TypeError("All submobjects must be of type OpenGLVMobject")
|
|
1793
|
+
self._assert_valid_submobjects(tuplify(value))
|
|
1793
1794
|
self.submobjects[key] = value
|
|
1794
1795
|
|
|
1795
1796
|
|
|
@@ -1879,7 +1880,7 @@ class OpenGLDashedVMobject(OpenGLVMobject):
|
|
|
1879
1880
|
vmobject: OpenGLVMobject,
|
|
1880
1881
|
num_dashes: int = 15,
|
|
1881
1882
|
dashed_ratio: float = 0.5,
|
|
1882
|
-
color:
|
|
1883
|
+
color: ParsableManimColor = WHITE,
|
|
1883
1884
|
**kwargs,
|
|
1884
1885
|
):
|
|
1885
1886
|
self.dashed_ratio = dashed_ratio
|
|
@@ -1890,10 +1891,7 @@ class OpenGLDashedVMobject(OpenGLVMobject):
|
|
|
1890
1891
|
if num_dashes > 0:
|
|
1891
1892
|
# Assuming total length is 1
|
|
1892
1893
|
dash_len = r / n
|
|
1893
|
-
if vmobject.is_closed()
|
|
1894
|
-
void_len = (1 - r) / n
|
|
1895
|
-
else:
|
|
1896
|
-
void_len = (1 - r) / (n - 1)
|
|
1894
|
+
void_len = (1 - r) / n if vmobject.is_closed() else (1 - r) / (n - 1)
|
|
1897
1895
|
|
|
1898
1896
|
self.add(
|
|
1899
1897
|
*(
|