diff --git a/camera.py b/camera.py index dca4a501..8737a54b 100644 --- a/camera.py +++ b/camera.py @@ -84,15 +84,38 @@ class Camera(object): def reset(self): 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): 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: - mobjects = it.chain(*[ - mob.family_members_with_points() - for mob in mobjects - ]) + mobjects = self.extract_mobject_family_members( + mobjects, only_those_with_points = True + ) + if excluded_mobjects: + all_excluded = self.extract_mobject_family_members( + excluded_mobjects + ) + mobjects = list_difference_update(mobjects, all_excluded) vmobjects = [] for mobject in mobjects: if isinstance(mobject, VMobject): diff --git a/constants.py b/constants.py index 78a2bad9..6efe1a1d 100644 --- a/constants.py +++ b/constants.py @@ -43,7 +43,7 @@ DEFAULT_MOBJECT_TO_MOBJECT_BUFFER = MED_SMALL_BUFF #All in seconds DEFAULT_ANIMATION_RUN_TIME = 1.0 DEFAULT_POINTWISE_FUNCTION_RUN_TIME = 3.0 -DEFAULT_wait_TIME = 1.0 +DEFAULT_WAIT_TIME = 1.0 ORIGIN = np.array(( 0., 0., 0.)) diff --git a/scene/scene.py b/scene/scene.py index 823b642d..d2fb81e1 100644 --- a/scene/scene.py +++ b/scene/scene.py @@ -123,19 +123,23 @@ class Scene(object): def capture_mobjects_in_camera(self, mobjects, **kwargs): self.camera.capture_mobjects(mobjects, **kwargs) - def update_frame(self, mobjects = None, background = None, **kwargs): - if "include_submobjects" not in kwargs: - kwargs["include_submobjects"] = False + def update_frame( + self, + mobjects = None, + background = None, + include_submobjects = True, + **kwargs): if mobjects is None: mobjects = list_update( - self.foreground_mobjects, self.mobjects, + self.foreground_mobjects, ) if background is not None: self.set_camera_pixel_array(background) else: self.reset_camera() + kwargs["include_submobjects"] = include_submobjects self.capture_mobjects_in_camera(mobjects, **kwargs) 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): # Return only those which are not in the family # of another mobject from the scene @@ -209,14 +204,10 @@ class Scene(object): """ Mobjects will be displayed, from background to foreground, 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_or_continual_animations ) - mobjects = self.extract_mobject_family_members(*mobjects) self.mobjects = list_update(self.mobjects, mobjects) self.continual_animations = list_update( self.continual_animations, continual_animations @@ -236,23 +227,29 @@ class Scene(object): mobjects, continual_animations = self.separate_mobjects_and_continual_animations( mobjects_or_continual_animations ) - mobjects = self.extract_mobject_family_members(*mobjects) - self.mobjects = filter( - lambda m : m not in mobjects, - self.mobjects + to_remove = self.camera.extract_mobject_family_members(mobjects) + + self.mobjects = list_difference_update(self.mobjects, to_remove) + self.restructure_how_mobjects_containing_to_remove_are_stored( + self.mobjects, to_remove ) - self.remove_mobjects_not_completely_on_screen() - self.remove_foreground_mobjects(*mobjects) + self.remove_foreground_mobjects(*to_remove) self.continual_animations = filter( lambda ca : ca not in continual_animations and \ - ca.mobject not in mobjects, + ca.mobject not in to_remove, self.continual_animations ) 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): return all([ submob in self.mobjects @@ -274,9 +271,9 @@ class Scene(object): return self.add_foreground_mobjects(mobject) def remove_foreground_mobjects(self, *mobjects): - self.foreground_mobjects = filter( - lambda m : m not in mobjects, - self.foreground_mobjects + self.foreground_mobjects = list_difference_update( + self.foreground_mobjects, + self.camera.extract_mobject_family_members(mobjects) ) return self @@ -289,7 +286,7 @@ class Scene(object): def bring_to_back(self, *mobjects): self.remove(*mobjects) - self.mobjects = mobjects + self.mobjects + self.mobjects = list(mobjects) + self.mobjects return self def clear(self): @@ -304,17 +301,13 @@ class Scene(object): def get_mobject_copies(self): return [m.copy() for m in self.mobjects] - def separate_moving_and_static_mobjects(self, *animations): - moving_mobjects = self.extract_mobject_family_members(*it.chain( + def get_moving_mobjects(self, *animations): + moving_mobjects = list(it.chain( [anim.mobject for anim in animations], [ca.mobject for ca in self.continual_animations], self.foreground_mobjects, )) - static_mobjects = filter( - lambda m : m not in moving_mobjects, - self.mobjects - ) - return moving_mobjects, static_mobjects + return moving_mobjects def get_time_progression(self, run_time): times = np.arange(0, run_time, self.frame_duration) @@ -395,9 +388,8 @@ class Scene(object): self.num_plays += 1 sync_animation_run_times_and_rate_funcs(*animations, **kwargs) - moving_mobjects, static_mobjects = \ - self.separate_moving_and_static_mobjects(*animations) - self.update_frame(static_mobjects) + moving_mobjects = self.get_moving_mobjects(*animations) + self.update_frame(excluded_mobjects = moving_mobjects) static_image = self.get_frame() for t in self.get_animation_time_progression(animations): for animation in animations: @@ -422,7 +414,7 @@ class Scene(object): return self.mobjects_from_last_animation return [] - def wait(self, duration = DEFAULT_wait_TIME): + def wait(self, duration = DEFAULT_WAIT_TIME): if self.skip_animations: return self @@ -527,3 +519,7 @@ class Scene(object): shutil.move(*self.args_to_rename_file) else: os.rename(*self.args_to_rename_file) + + + +