mirror of
https://github.com/3b1b/manim.git
synced 2025-04-13 09:47:07 +00:00
Most of the restructuring for how scenes hold mobjects is done, just need to handle the trickiness of Scene.remove
This commit is contained in:
parent
dcb28791c4
commit
2ab57bda97
3 changed files with 65 additions and 46 deletions
33
camera.py
33
camera.py
|
@ -84,15 +84,38 @@ class Camera(object):
|
||||||
def reset(self):
|
def reset(self):
|
||||||
self.set_pixel_array(np.array(self.background))
|
self.set_pixel_array(np.array(self.background))
|
||||||
|
|
||||||
|
####
|
||||||
|
|
||||||
|
def extract_mobject_family_members(self, mobjects, only_those_with_points = False):
|
||||||
|
if only_those_with_points:
|
||||||
|
method = Mobject.family_members_with_points
|
||||||
|
else:
|
||||||
|
method = Mobject.submobject_family
|
||||||
|
return remove_list_redundancies(list(
|
||||||
|
it.chain(*[
|
||||||
|
method(m)
|
||||||
|
for m in mobjects
|
||||||
|
if not (isinstance(m, VMobject) and m.is_subpath)
|
||||||
|
])
|
||||||
|
))
|
||||||
|
|
||||||
def capture_mobject(self, mobject):
|
def capture_mobject(self, mobject):
|
||||||
return self.capture_mobjects([mobject])
|
return self.capture_mobjects([mobject])
|
||||||
|
|
||||||
def capture_mobjects(self, mobjects, include_submobjects = True):
|
def capture_mobjects(
|
||||||
|
self, mobjects,
|
||||||
|
include_submobjects = True,
|
||||||
|
excluded_mobjects = None,
|
||||||
|
):
|
||||||
if include_submobjects:
|
if include_submobjects:
|
||||||
mobjects = it.chain(*[
|
mobjects = self.extract_mobject_family_members(
|
||||||
mob.family_members_with_points()
|
mobjects, only_those_with_points = True
|
||||||
for mob in mobjects
|
)
|
||||||
])
|
if excluded_mobjects:
|
||||||
|
all_excluded = self.extract_mobject_family_members(
|
||||||
|
excluded_mobjects
|
||||||
|
)
|
||||||
|
mobjects = list_difference_update(mobjects, all_excluded)
|
||||||
vmobjects = []
|
vmobjects = []
|
||||||
for mobject in mobjects:
|
for mobject in mobjects:
|
||||||
if isinstance(mobject, VMobject):
|
if isinstance(mobject, VMobject):
|
||||||
|
|
|
@ -43,7 +43,7 @@ DEFAULT_MOBJECT_TO_MOBJECT_BUFFER = MED_SMALL_BUFF
|
||||||
#All in seconds
|
#All in seconds
|
||||||
DEFAULT_ANIMATION_RUN_TIME = 1.0
|
DEFAULT_ANIMATION_RUN_TIME = 1.0
|
||||||
DEFAULT_POINTWISE_FUNCTION_RUN_TIME = 3.0
|
DEFAULT_POINTWISE_FUNCTION_RUN_TIME = 3.0
|
||||||
DEFAULT_wait_TIME = 1.0
|
DEFAULT_WAIT_TIME = 1.0
|
||||||
|
|
||||||
|
|
||||||
ORIGIN = np.array(( 0., 0., 0.))
|
ORIGIN = np.array(( 0., 0., 0.))
|
||||||
|
|
|
@ -123,19 +123,23 @@ class Scene(object):
|
||||||
def capture_mobjects_in_camera(self, mobjects, **kwargs):
|
def capture_mobjects_in_camera(self, mobjects, **kwargs):
|
||||||
self.camera.capture_mobjects(mobjects, **kwargs)
|
self.camera.capture_mobjects(mobjects, **kwargs)
|
||||||
|
|
||||||
def update_frame(self, mobjects = None, background = None, **kwargs):
|
def update_frame(
|
||||||
if "include_submobjects" not in kwargs:
|
self,
|
||||||
kwargs["include_submobjects"] = False
|
mobjects = None,
|
||||||
|
background = None,
|
||||||
|
include_submobjects = True,
|
||||||
|
**kwargs):
|
||||||
if mobjects is None:
|
if mobjects is None:
|
||||||
mobjects = list_update(
|
mobjects = list_update(
|
||||||
self.foreground_mobjects,
|
|
||||||
self.mobjects,
|
self.mobjects,
|
||||||
|
self.foreground_mobjects,
|
||||||
)
|
)
|
||||||
if background is not None:
|
if background is not None:
|
||||||
self.set_camera_pixel_array(background)
|
self.set_camera_pixel_array(background)
|
||||||
else:
|
else:
|
||||||
self.reset_camera()
|
self.reset_camera()
|
||||||
|
|
||||||
|
kwargs["include_submobjects"] = include_submobjects
|
||||||
self.capture_mobjects_in_camera(mobjects, **kwargs)
|
self.capture_mobjects_in_camera(mobjects, **kwargs)
|
||||||
|
|
||||||
def freeze_background(self):
|
def freeze_background(self):
|
||||||
|
@ -167,15 +171,6 @@ class Scene(object):
|
||||||
|
|
||||||
###
|
###
|
||||||
|
|
||||||
def extract_mobject_family_members(self, *mobjects):
|
|
||||||
return remove_list_redundancies(list(
|
|
||||||
it.chain(*[
|
|
||||||
m.submobject_family()
|
|
||||||
for m in mobjects
|
|
||||||
if not (isinstance(m, VMobject) and m.is_subpath)
|
|
||||||
])
|
|
||||||
))
|
|
||||||
|
|
||||||
def get_top_level_mobjects(self):
|
def get_top_level_mobjects(self):
|
||||||
# Return only those which are not in the family
|
# Return only those which are not in the family
|
||||||
# of another mobject from the scene
|
# of another mobject from the scene
|
||||||
|
@ -209,14 +204,10 @@ class Scene(object):
|
||||||
"""
|
"""
|
||||||
Mobjects will be displayed, from background to foreground,
|
Mobjects will be displayed, from background to foreground,
|
||||||
in the order with which they are entered.
|
in the order with which they are entered.
|
||||||
|
|
||||||
Scene class keeps track not just of the mobject directly added,
|
|
||||||
but also of every family member therein.
|
|
||||||
"""
|
"""
|
||||||
mobjects, continual_animations = self.separate_mobjects_and_continual_animations(
|
mobjects, continual_animations = self.separate_mobjects_and_continual_animations(
|
||||||
mobjects_or_continual_animations
|
mobjects_or_continual_animations
|
||||||
)
|
)
|
||||||
mobjects = self.extract_mobject_family_members(*mobjects)
|
|
||||||
self.mobjects = list_update(self.mobjects, mobjects)
|
self.mobjects = list_update(self.mobjects, mobjects)
|
||||||
self.continual_animations = list_update(
|
self.continual_animations = list_update(
|
||||||
self.continual_animations, continual_animations
|
self.continual_animations, continual_animations
|
||||||
|
@ -236,23 +227,29 @@ class Scene(object):
|
||||||
mobjects, continual_animations = self.separate_mobjects_and_continual_animations(
|
mobjects, continual_animations = self.separate_mobjects_and_continual_animations(
|
||||||
mobjects_or_continual_animations
|
mobjects_or_continual_animations
|
||||||
)
|
)
|
||||||
mobjects = self.extract_mobject_family_members(*mobjects)
|
to_remove = self.camera.extract_mobject_family_members(mobjects)
|
||||||
self.mobjects = filter(
|
|
||||||
lambda m : m not in mobjects,
|
self.mobjects = list_difference_update(self.mobjects, to_remove)
|
||||||
self.mobjects
|
self.restructure_how_mobjects_containing_to_remove_are_stored(
|
||||||
|
self.mobjects, to_remove
|
||||||
)
|
)
|
||||||
self.remove_mobjects_not_completely_on_screen()
|
self.remove_foreground_mobjects(*to_remove)
|
||||||
self.remove_foreground_mobjects(*mobjects)
|
|
||||||
|
|
||||||
self.continual_animations = filter(
|
self.continual_animations = filter(
|
||||||
lambda ca : ca not in continual_animations and \
|
lambda ca : ca not in continual_animations and \
|
||||||
ca.mobject not in mobjects,
|
ca.mobject not in to_remove,
|
||||||
self.continual_animations
|
self.continual_animations
|
||||||
)
|
)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def remove_mobjects_not_completely_on_screen(self):
|
def restructure_how_mobjects_containing_to_remove_are_stored(self, mobjects, to_remove):
|
||||||
|
"""
|
||||||
|
In cases where the scene contains a group, e.g. Group(m1, m2, m3), but one
|
||||||
|
of its submobjects is removed, e.g. scene.remove(m1), the list of mobjects
|
||||||
|
will be editing to contain other submobjts, but not m1, e.g. it will now
|
||||||
|
insert m2 and m3 to where the group once was.
|
||||||
|
"""
|
||||||
def should_keep(mobject):
|
def should_keep(mobject):
|
||||||
return all([
|
return all([
|
||||||
submob in self.mobjects
|
submob in self.mobjects
|
||||||
|
@ -274,9 +271,9 @@ class Scene(object):
|
||||||
return self.add_foreground_mobjects(mobject)
|
return self.add_foreground_mobjects(mobject)
|
||||||
|
|
||||||
def remove_foreground_mobjects(self, *mobjects):
|
def remove_foreground_mobjects(self, *mobjects):
|
||||||
self.foreground_mobjects = filter(
|
self.foreground_mobjects = list_difference_update(
|
||||||
lambda m : m not in mobjects,
|
self.foreground_mobjects,
|
||||||
self.foreground_mobjects
|
self.camera.extract_mobject_family_members(mobjects)
|
||||||
)
|
)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
@ -289,7 +286,7 @@ class Scene(object):
|
||||||
|
|
||||||
def bring_to_back(self, *mobjects):
|
def bring_to_back(self, *mobjects):
|
||||||
self.remove(*mobjects)
|
self.remove(*mobjects)
|
||||||
self.mobjects = mobjects + self.mobjects
|
self.mobjects = list(mobjects) + self.mobjects
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def clear(self):
|
def clear(self):
|
||||||
|
@ -304,17 +301,13 @@ class Scene(object):
|
||||||
def get_mobject_copies(self):
|
def get_mobject_copies(self):
|
||||||
return [m.copy() for m in self.mobjects]
|
return [m.copy() for m in self.mobjects]
|
||||||
|
|
||||||
def separate_moving_and_static_mobjects(self, *animations):
|
def get_moving_mobjects(self, *animations):
|
||||||
moving_mobjects = self.extract_mobject_family_members(*it.chain(
|
moving_mobjects = list(it.chain(
|
||||||
[anim.mobject for anim in animations],
|
[anim.mobject for anim in animations],
|
||||||
[ca.mobject for ca in self.continual_animations],
|
[ca.mobject for ca in self.continual_animations],
|
||||||
self.foreground_mobjects,
|
self.foreground_mobjects,
|
||||||
))
|
))
|
||||||
static_mobjects = filter(
|
return moving_mobjects
|
||||||
lambda m : m not in moving_mobjects,
|
|
||||||
self.mobjects
|
|
||||||
)
|
|
||||||
return moving_mobjects, static_mobjects
|
|
||||||
|
|
||||||
def get_time_progression(self, run_time):
|
def get_time_progression(self, run_time):
|
||||||
times = np.arange(0, run_time, self.frame_duration)
|
times = np.arange(0, run_time, self.frame_duration)
|
||||||
|
@ -395,9 +388,8 @@ class Scene(object):
|
||||||
self.num_plays += 1
|
self.num_plays += 1
|
||||||
|
|
||||||
sync_animation_run_times_and_rate_funcs(*animations, **kwargs)
|
sync_animation_run_times_and_rate_funcs(*animations, **kwargs)
|
||||||
moving_mobjects, static_mobjects = \
|
moving_mobjects = self.get_moving_mobjects(*animations)
|
||||||
self.separate_moving_and_static_mobjects(*animations)
|
self.update_frame(excluded_mobjects = moving_mobjects)
|
||||||
self.update_frame(static_mobjects)
|
|
||||||
static_image = self.get_frame()
|
static_image = self.get_frame()
|
||||||
for t in self.get_animation_time_progression(animations):
|
for t in self.get_animation_time_progression(animations):
|
||||||
for animation in animations:
|
for animation in animations:
|
||||||
|
@ -422,7 +414,7 @@ class Scene(object):
|
||||||
return self.mobjects_from_last_animation
|
return self.mobjects_from_last_animation
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def wait(self, duration = DEFAULT_wait_TIME):
|
def wait(self, duration = DEFAULT_WAIT_TIME):
|
||||||
if self.skip_animations:
|
if self.skip_animations:
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
@ -527,3 +519,7 @@ class Scene(object):
|
||||||
shutil.move(*self.args_to_rename_file)
|
shutil.move(*self.args_to_rename_file)
|
||||||
else:
|
else:
|
||||||
os.rename(*self.args_to_rename_file)
|
os.rename(*self.args_to_rename_file)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue