diff --git a/manimlib/animation/transform.py b/manimlib/animation/transform.py index fdc262a9..1281ddc2 100644 --- a/manimlib/animation/transform.py +++ b/manimlib/animation/transform.py @@ -63,7 +63,7 @@ class Transform(Animation): # preserved, since calling align_data will potentially # change the structure of both arguments self.target_copy = self.target_mobject.copy() - self.mobject.align_data_and_family(self.target_copy) + self.mobject.align_data_and_family(self.target_copy) super().begin() if not self.mobject.has_updaters: self.mobject.lock_matching_data( diff --git a/manimlib/config.py b/manimlib/config.py index bb5e57ef..1de7bbd7 100644 --- a/manimlib/config.py +++ b/manimlib/config.py @@ -420,11 +420,12 @@ def get_file_writer_config(args: Namespace, custom_config: dict) -> dict: result["video_codec"] = args.vcodec elif args.transparent: result["video_codec"] = 'prores_ks' + result["pixel_format"] = '' elif args.gif: result["video_codec"] = '' if args.pix_fmt: - result["pix_fmt"] = args.pix_fmt + result["pixel_format"] = args.pix_fmt return result diff --git a/manimlib/mobject/coordinate_systems.py b/manimlib/mobject/coordinate_systems.py index e1f1d961..615eed7d 100644 --- a/manimlib/mobject/coordinate_systems.py +++ b/manimlib/mobject/coordinate_systems.py @@ -508,7 +508,7 @@ class ThreeDAxes(Axes): z_axis_config: dict = dict(), z_normal: Vect3 = DOWN, depth: float = 6.0, - num_axis_pieces: int = 20, + flat_stroke: bool = False, **kwargs ): Axes.__init__(self, x_range, y_range, **kwargs) @@ -533,8 +533,7 @@ class ThreeDAxes(Axes): self.axes.add(self.z_axis) self.add(self.z_axis) - for axis in self.axes: - axis.insert_n_curves(num_axis_pieces - 1) + self.set_flat_stroke(flat_stroke) def get_all_ranges(self) -> list[Sequence[float]]: return [self.x_range, self.y_range, self.z_range] diff --git a/manimlib/mobject/mobject.py b/manimlib/mobject/mobject.py index 2f974389..9f4f2a18 100644 --- a/manimlib/mobject/mobject.py +++ b/manimlib/mobject/mobject.py @@ -2178,7 +2178,7 @@ class _AnimationBuilder: if (self.is_chaining and has_overridden_animation) or self.overridden_animation: raise NotImplementedError( - "Method chaining is currently not supported for " + "Method chaining is currently not supported for " + \ "overridden animations" ) @@ -2213,7 +2213,7 @@ class _AnimationBuilder: if not self.can_pass_args: raise ValueError( - "Animation arguments can only be passed by calling ``animate`` " + "Animation arguments can only be passed by calling ``animate`` " + \ "or ``set_anim_args`` and can only be passed once", ) diff --git a/manimlib/mobject/mobject_update_utils.py b/manimlib/mobject/mobject_update_utils.py index 4fdcfecd..d47270ff 100644 --- a/manimlib/mobject/mobject_update_utils.py +++ b/manimlib/mobject/mobject_update_utils.py @@ -93,7 +93,7 @@ def turn_animation_into_updater( the updater will be popped uplon completion """ mobject = animation.mobject - animation.update_config(**kwargs) + animation.update_rate_info(**kwargs) animation.suspend_mobject_updating = False animation.begin() animation.total_time = 0 diff --git a/manimlib/mobject/types/vectorized_mobject.py b/manimlib/mobject/types/vectorized_mobject.py index 8d60f019..72b287af 100644 --- a/manimlib/mobject/types/vectorized_mobject.py +++ b/manimlib/mobject/types/vectorized_mobject.py @@ -541,6 +541,7 @@ class VMobject(Mobject): else: new_handle = self.get_reflection_of_last_handle() self.add_cubic_bezier_curve_to(new_handle, handle, point) + return self def has_new_path_started(self) -> bool: points = self.get_points() @@ -898,6 +899,8 @@ class VMobject(Mobject): self.has_same_shape_as(vmobject) if match_tris: vmobject.triangulation = self.triangulation + for mob in [self, vmobject]: + mob.get_joint_products() return self for mob in self, vmobject: diff --git a/manimlib/scene/scene_file_writer.py b/manimlib/scene/scene_file_writer.py index fdcabb8f..47698d0d 100644 --- a/manimlib/scene/scene_file_writer.py +++ b/manimlib/scene/scene_file_writer.py @@ -49,6 +49,8 @@ class SceneFileWriter(object): progress_description_len: int = 40, video_codec: str = "libx264", pixel_format: str = "yuv420p", + saturation: float = 1.7, + gamma: float = 1.2, ): self.scene: Scene = scene self.write_to_movie = write_to_movie @@ -67,6 +69,8 @@ class SceneFileWriter(object): self.progress_description_len = progress_description_len self.video_codec = video_codec self.pixel_format = pixel_format + self.saturation = saturation + self.gamma = gamma # State during file writing self.writing_process: sp.Popen | None = None @@ -254,6 +258,10 @@ class SceneFileWriter(object): fps = self.scene.camera.fps width, height = self.scene.camera.get_pixel_shape() + vf_arg = 'vflip' + if self.pixel_format.startswith("yuv"): + vf_arg += f',eq=saturation={self.saturation}:gamma={self.gamma}' + command = [ FFMPEG_BIN, '-y', # overwrite output file if it exists @@ -262,7 +270,7 @@ class SceneFileWriter(object): '-pix_fmt', 'rgba', '-r', str(fps), # frames per second '-i', '-', # The input comes from a pipe - '-vf', 'vflip', + '-vf', vf_arg, '-an', # Tells FFMPEG not to expect any audio '-loglevel', 'error', ]