Skip to content

Commit dba6fa8

Browse files
Add type annotations to three_d_camera.py (#4356)
* Adding type annotations to three_d_camera.py * Suggestions from Chopan50 * Removed a comment. --------- Co-authored-by: Francisco Manríquez Novoa <[email protected]>
1 parent df36f4f commit dba6fa8

File tree

3 files changed

+71
-58
lines changed

3 files changed

+71
-58
lines changed

manim/camera/camera.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
import numpy as np
1717
from PIL import Image
1818
from scipy.spatial.distance import pdist
19+
from typing_extensions import Self
20+
21+
from manim.typing import Point3D_Array
1922

2023
from .. import config, logger
2124
from ..constants import *
@@ -386,7 +389,7 @@ def make_background_from_func(
386389

387390
def set_background_from_func(
388391
self, coords_to_colors_func: Callable[[np.ndarray], np.ndarray]
389-
):
392+
) -> None:
390393
"""
391394
Sets the background to a pixel array using coords_to_colors_func to determine each pixel's color. Each input
392395
pixel's color. Each input to coords_to_colors_func is an (x, y) pair in space (in ordinary space coordinates; not
@@ -400,7 +403,7 @@ def set_background_from_func(
400403
"""
401404
self.set_background(self.make_background_from_func(coords_to_colors_func))
402405

403-
def reset(self):
406+
def reset(self) -> Self:
404407
"""Resets the camera's pixel array
405408
to that of the background
406409
@@ -1078,8 +1081,8 @@ def adjust_out_of_range_points(self, points: np.ndarray):
10781081

10791082
def transform_points_pre_display(
10801083
self,
1081-
mobject,
1082-
points,
1084+
mobject: Mobject,
1085+
points: Point3D_Array,
10831086
): # TODO: Write more detailed docstrings for this method.
10841087
# NOTE: There seems to be an unused argument `mobject`.
10851088

manim/camera/three_d_camera.py

Lines changed: 64 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
__all__ = ["ThreeDCamera"]
66

77

8-
from typing import Callable
8+
from collections.abc import Callable, Iterable
9+
from typing import Any
910

1011
import numpy as np
1112

@@ -16,7 +17,14 @@
1617
get_3d_vmob_start_corner,
1718
get_3d_vmob_start_corner_unit_normal,
1819
)
20+
from manim.mobject.types.vectorized_mobject import VMobject
1921
from manim.mobject.value_tracker import ValueTracker
22+
from manim.typing import (
23+
MatrixMN,
24+
Point3D,
25+
Point3D_Array,
26+
Point3DLike,
27+
)
2028

2129
from .. import config
2230
from ..camera.camera import Camera
@@ -30,17 +38,17 @@
3038
class ThreeDCamera(Camera):
3139
def __init__(
3240
self,
33-
focal_distance=20.0,
34-
shading_factor=0.2,
35-
default_distance=5.0,
36-
light_source_start_point=9 * DOWN + 7 * LEFT + 10 * OUT,
37-
should_apply_shading=True,
38-
exponential_projection=False,
39-
phi=0,
40-
theta=-90 * DEGREES,
41-
gamma=0,
42-
zoom=1,
43-
**kwargs,
41+
focal_distance: float = 20.0,
42+
shading_factor: float = 0.2,
43+
default_distance: float = 5.0,
44+
light_source_start_point: Point3DLike = 9 * DOWN + 7 * LEFT + 10 * OUT,
45+
should_apply_shading: bool = True,
46+
exponential_projection: bool = False,
47+
phi: float = 0,
48+
theta: float = -90 * DEGREES,
49+
gamma: float = 0,
50+
zoom: float = 1,
51+
**kwargs: Any,
4452
):
4553
"""Initializes the ThreeDCamera
4654
@@ -68,23 +76,23 @@ def __init__(
6876
self.focal_distance_tracker = ValueTracker(self.focal_distance)
6977
self.gamma_tracker = ValueTracker(self.gamma)
7078
self.zoom_tracker = ValueTracker(self.zoom)
71-
self.fixed_orientation_mobjects = {}
72-
self.fixed_in_frame_mobjects = set()
79+
self.fixed_orientation_mobjects: dict[Mobject, Callable[[], Point3D]] = {}
80+
self.fixed_in_frame_mobjects: set[Mobject] = set()
7381
self.reset_rotation_matrix()
7482

7583
@property
76-
def frame_center(self):
84+
def frame_center(self) -> Point3D:
7785
return self._frame_center.points[0]
7886

7987
@frame_center.setter
80-
def frame_center(self, point):
88+
def frame_center(self, point: Point3DLike) -> None:
8189
self._frame_center.move_to(point)
8290

83-
def capture_mobjects(self, mobjects, **kwargs):
91+
def capture_mobjects(self, mobjects: Iterable[Mobject], **kwargs: Any) -> None:
8492
self.reset_rotation_matrix()
8593
super().capture_mobjects(mobjects, **kwargs)
8694

87-
def get_value_trackers(self):
95+
def get_value_trackers(self) -> list[ValueTracker]:
8896
"""A list of :class:`ValueTrackers <.ValueTracker>` of phi, theta, focal_distance,
8997
gamma and zoom.
9098
@@ -101,7 +109,7 @@ def get_value_trackers(self):
101109
self.zoom_tracker,
102110
]
103111

104-
def modified_rgbas(self, vmobject, rgbas):
112+
def modified_rgbas(self, vmobject: VMobject, rgbas: MatrixMN) -> MatrixMN:
105113
if not self.should_apply_shading:
106114
return rgbas
107115
if vmobject.shade_in_3d and (vmobject.get_num_points() > 0):
@@ -127,28 +135,33 @@ def modified_rgbas(self, vmobject, rgbas):
127135

128136
def get_stroke_rgbas(
129137
self,
130-
vmobject,
131-
background=False,
132-
): # NOTE : DocStrings From parent
138+
vmobject: VMobject,
139+
background: bool = False,
140+
) -> MatrixMN: # NOTE : DocStrings From parent
133141
return self.modified_rgbas(vmobject, vmobject.get_stroke_rgbas(background))
134142

135-
def get_fill_rgbas(self, vmobject): # NOTE : DocStrings From parent
143+
def get_fill_rgbas(
144+
self, vmobject: VMobject
145+
) -> MatrixMN: # NOTE : DocStrings From parent
136146
return self.modified_rgbas(vmobject, vmobject.get_fill_rgbas())
137147

138-
def get_mobjects_to_display(self, *args, **kwargs): # NOTE : DocStrings From parent
148+
def get_mobjects_to_display(
149+
self, *args: Any, **kwargs: Any
150+
) -> list[Mobject]: # NOTE : DocStrings From parent
139151
mobjects = super().get_mobjects_to_display(*args, **kwargs)
140152
rot_matrix = self.get_rotation_matrix()
141153

142-
def z_key(mob):
154+
def z_key(mob: Mobject) -> float:
143155
if not (hasattr(mob, "shade_in_3d") and mob.shade_in_3d):
144-
return np.inf
156+
return np.inf # type: ignore[no-any-return]
145157
# Assign a number to a three dimensional mobjects
146158
# based on how close it is to the camera
147-
return np.dot(mob.get_z_index_reference_point(), rot_matrix.T)[2]
159+
distance: float = np.dot(mob.get_z_index_reference_point(), rot_matrix.T)[2]
160+
return distance
148161

149162
return sorted(mobjects, key=z_key)
150163

151-
def get_phi(self):
164+
def get_phi(self) -> float:
152165
"""Returns the Polar angle (the angle off Z_AXIS) phi.
153166
154167
Returns
@@ -158,7 +171,7 @@ def get_phi(self):
158171
"""
159172
return self.phi_tracker.get_value()
160173

161-
def get_theta(self):
174+
def get_theta(self) -> float:
162175
"""Returns the Azimuthal i.e the angle that spins the camera around the Z_AXIS.
163176
164177
Returns
@@ -168,7 +181,7 @@ def get_theta(self):
168181
"""
169182
return self.theta_tracker.get_value()
170183

171-
def get_focal_distance(self):
184+
def get_focal_distance(self) -> float:
172185
"""Returns focal_distance of the Camera.
173186
174187
Returns
@@ -178,7 +191,7 @@ def get_focal_distance(self):
178191
"""
179192
return self.focal_distance_tracker.get_value()
180193

181-
def get_gamma(self):
194+
def get_gamma(self) -> float:
182195
"""Returns the rotation of the camera about the vector from the ORIGIN to the Camera.
183196
184197
Returns
@@ -189,7 +202,7 @@ def get_gamma(self):
189202
"""
190203
return self.gamma_tracker.get_value()
191204

192-
def get_zoom(self):
205+
def get_zoom(self) -> float:
193206
"""Returns the zoom amount of the camera.
194207
195208
Returns
@@ -199,7 +212,7 @@ def get_zoom(self):
199212
"""
200213
return self.zoom_tracker.get_value()
201214

202-
def set_phi(self, value: float):
215+
def set_phi(self, value: float) -> None:
203216
"""Sets the polar angle i.e the angle between Z_AXIS and Camera through ORIGIN in radians.
204217
205218
Parameters
@@ -209,7 +222,7 @@ def set_phi(self, value: float):
209222
"""
210223
self.phi_tracker.set_value(value)
211224

212-
def set_theta(self, value: float):
225+
def set_theta(self, value: float) -> None:
213226
"""Sets the azimuthal angle i.e the angle that spins the camera around Z_AXIS in radians.
214227
215228
Parameters
@@ -219,7 +232,7 @@ def set_theta(self, value: float):
219232
"""
220233
self.theta_tracker.set_value(value)
221234

222-
def set_focal_distance(self, value: float):
235+
def set_focal_distance(self, value: float) -> None:
223236
"""Sets the focal_distance of the Camera.
224237
225238
Parameters
@@ -229,7 +242,7 @@ def set_focal_distance(self, value: float):
229242
"""
230243
self.focal_distance_tracker.set_value(value)
231244

232-
def set_gamma(self, value: float):
245+
def set_gamma(self, value: float) -> None:
233246
"""Sets the angle of rotation of the camera about the vector from the ORIGIN to the Camera.
234247
235248
Parameters
@@ -239,7 +252,7 @@ def set_gamma(self, value: float):
239252
"""
240253
self.gamma_tracker.set_value(value)
241254

242-
def set_zoom(self, value: float):
255+
def set_zoom(self, value: float) -> None:
243256
"""Sets the zoom amount of the camera.
244257
245258
Parameters
@@ -249,13 +262,13 @@ def set_zoom(self, value: float):
249262
"""
250263
self.zoom_tracker.set_value(value)
251264

252-
def reset_rotation_matrix(self):
265+
def reset_rotation_matrix(self) -> None:
253266
"""Sets the value of self.rotation_matrix to
254267
the matrix corresponding to the current position of the camera
255268
"""
256269
self.rotation_matrix = self.generate_rotation_matrix()
257270

258-
def get_rotation_matrix(self):
271+
def get_rotation_matrix(self) -> MatrixMN:
259272
"""Returns the matrix corresponding to the current position of the camera.
260273
261274
Returns
@@ -265,7 +278,7 @@ def get_rotation_matrix(self):
265278
"""
266279
return self.rotation_matrix
267280

268-
def generate_rotation_matrix(self):
281+
def generate_rotation_matrix(self) -> MatrixMN:
269282
"""Generates a rotation matrix based off the current position of the camera.
270283
271284
Returns
@@ -286,7 +299,7 @@ def generate_rotation_matrix(self):
286299
result = np.dot(matrix, result)
287300
return result
288301

289-
def project_points(self, points: np.ndarray | list):
302+
def project_points(self, points: Point3D_Array) -> Point3D_Array:
290303
"""Applies the current rotation_matrix as a projection
291304
matrix to the passed array of points.
292305
@@ -323,7 +336,7 @@ def project_points(self, points: np.ndarray | list):
323336
points[:, i] *= factor * zoom
324337
return points
325338

326-
def project_point(self, point: list | np.ndarray):
339+
def project_point(self, point: Point3D) -> Point3D:
327340
"""Applies the current rotation_matrix as a projection
328341
matrix to the passed point.
329342
@@ -341,9 +354,9 @@ def project_point(self, point: list | np.ndarray):
341354

342355
def transform_points_pre_display(
343356
self,
344-
mobject,
345-
points,
346-
): # TODO: Write Docstrings for this Method.
357+
mobject: Mobject,
358+
points: Point3D_Array,
359+
) -> Point3D_Array: # TODO: Write Docstrings for this Method.
347360
points = super().transform_points_pre_display(mobject, points)
348361
fixed_orientation = mobject in self.fixed_orientation_mobjects
349362
fixed_in_frame = mobject in self.fixed_in_frame_mobjects
@@ -362,8 +375,8 @@ def add_fixed_orientation_mobjects(
362375
self,
363376
*mobjects: Mobject,
364377
use_static_center_func: bool = False,
365-
center_func: Callable[[], np.ndarray] | None = None,
366-
):
378+
center_func: Callable[[], Point3D] | None = None,
379+
) -> None:
367380
"""This method allows the mobject to have a fixed orientation,
368381
even when the camera moves around.
369382
E.G If it was passed through this method, facing the camera, it
@@ -384,7 +397,7 @@ def add_fixed_orientation_mobjects(
384397

385398
# This prevents the computation of mobject.get_center
386399
# every single time a projection happens
387-
def get_static_center_func(mobject):
400+
def get_static_center_func(mobject: Mobject) -> Callable[[], Point3D]:
388401
point = mobject.get_center()
389402
return lambda: point
390403

@@ -398,7 +411,7 @@ def get_static_center_func(mobject):
398411
for submob in mobject.get_family():
399412
self.fixed_orientation_mobjects[submob] = func
400413

401-
def add_fixed_in_frame_mobjects(self, *mobjects: Mobject):
414+
def add_fixed_in_frame_mobjects(self, *mobjects: Mobject) -> None:
402415
"""This method allows the mobject to have a fixed position,
403416
even when the camera moves around.
404417
E.G If it was passed through this method, at the top of the frame, it
@@ -414,7 +427,7 @@ def add_fixed_in_frame_mobjects(self, *mobjects: Mobject):
414427
for mobject in extract_mobject_family_members(mobjects):
415428
self.fixed_in_frame_mobjects.add(mobject)
416429

417-
def remove_fixed_orientation_mobjects(self, *mobjects: Mobject):
430+
def remove_fixed_orientation_mobjects(self, *mobjects: Mobject) -> None:
418431
"""If a mobject was fixed in its orientation by passing it through
419432
:meth:`.add_fixed_orientation_mobjects`, then this undoes that fixing.
420433
The Mobject will no longer have a fixed orientation.
@@ -428,7 +441,7 @@ def remove_fixed_orientation_mobjects(self, *mobjects: Mobject):
428441
if mobject in self.fixed_orientation_mobjects:
429442
del self.fixed_orientation_mobjects[mobject]
430443

431-
def remove_fixed_in_frame_mobjects(self, *mobjects: Mobject):
444+
def remove_fixed_in_frame_mobjects(self, *mobjects: Mobject) -> None:
432445
"""If a mobject was fixed in frame by passing it through
433446
:meth:`.add_fixed_in_frame_mobjects`, then this undoes that fixing.
434447
The Mobject will no longer be fixed in frame.

mypy.ini

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,6 @@ ignore_errors = True
9696
[mypy-manim.camera.multi_camera]
9797
ignore_errors = True
9898

99-
[mypy-manim.camera.three_d_camera]
100-
ignore_errors = True
101-
10299
[mypy-manim.mobject.graphing.coordinate_systems]
103100
ignore_errors = True
104101

0 commit comments

Comments
 (0)