From 8b86f64908169d63a9b1c9ee0d6e4c99742e405b Mon Sep 17 00:00:00 2001 From: Austin Mroz Date: Wed, 10 Jul 2024 13:46:20 -0500 Subject: [PATCH 1/8] Add js to auto-size nodes --- web/js/autosize.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 web/js/autosize.js diff --git a/web/js/autosize.js b/web/js/autosize.js new file mode 100644 index 0000000..4961ddc --- /dev/null +++ b/web/js/autosize.js @@ -0,0 +1,15 @@ +import { app } from '../../../scripts/app.js' +app.registerExtension({ + name: "AnimateDiffEvolved.autosize", + async beforeRegisterNodeDef(nodeType, nodeData, app) { + if(nodeData?.name?.startsWith("ADE_") || + nodeData?.name?.startsWith("ACN_")) { + let origOnCreated = nodeType.prototype.onNodeCreated + nodeType.prototype.onNodeCreated = function() { + const r = origOnCreated ? origOnCreated.apply(this) : undefined; + this.setSize(this.computeSize(0)); + return r + } + } + } +}); From 7a8415b560a2ece5ee02e00b52fc4ccf01bff7ef Mon Sep 17 00:00:00 2001 From: Austin Mroz Date: Wed, 10 Jul 2024 22:05:50 -0500 Subject: [PATCH 2/8] Enable autosize by widget instead of namespace. Also adds a padding option which, if supplied is summed with the calculated width when auto-sizing is applied. --- animatediff/nodes_sample.py | 1 + web/js/autosize.js | 33 +++++++++++++++++++++++++-------- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/animatediff/nodes_sample.py b/animatediff/nodes_sample.py index 1c5a143..a4041f2 100644 --- a/animatediff/nodes_sample.py +++ b/animatediff/nodes_sample.py @@ -298,6 +298,7 @@ def INPUT_TYPES(s): "optional": { "prev_custom_cfg": ("CUSTOM_CFG",), "cfg_extras": ("CFG_EXTRAS",), + "autosize": ("ADEAUTOSIZE", {"padding": 10}), } } diff --git a/web/js/autosize.js b/web/js/autosize.js index 4961ddc..ccf1cfd 100644 --- a/web/js/autosize.js +++ b/web/js/autosize.js @@ -1,14 +1,31 @@ import { app } from '../../../scripts/app.js' app.registerExtension({ name: "AnimateDiffEvolved.autosize", - async beforeRegisterNodeDef(nodeType, nodeData, app) { - if(nodeData?.name?.startsWith("ADE_") || - nodeData?.name?.startsWith("ACN_")) { - let origOnCreated = nodeType.prototype.onNodeCreated - nodeType.prototype.onNodeCreated = function() { - const r = origOnCreated ? origOnCreated.apply(this) : undefined; - this.setSize(this.computeSize(0)); - return r + async nodeCreated(node) { + if(node.adeAutosize) { + let size = node.computeSize(0); + size[0] += node.adeAutosize?.padding || 0; + node.setSize(size); + } + }, + async getCustomWidgets() { + return { + ADEAUTOSIZE(node, inputName, inputData) { + let w = { + name : inputName, + type : "ADE.AUTOSIZE", + value : "", + options : {"serialize": false}, + computeSize : function(width) { + return [0, -4]; + } + } + node.adeAutosize = inputData[1]; + if (!node.widgets) { + node.widgets = [] + } + node.widgets.push(w) + return w; } } } From b6a1a84df3b8f959f7d0318ed6d93957312d94ac Mon Sep 17 00:00:00 2001 From: Jedrzej Kosinski Date: Fri, 12 Jul 2024 18:01:11 -0500 Subject: [PATCH 3/8] Added autosize to a lot of nodes, still more to setup --- animatediff/nodes_animatelcmi2v.py | 1 + animatediff/nodes_cameractrl.py | 2 ++ animatediff/nodes_gen2.py | 3 +++ animatediff/nodes_multival.py | 15 ++++++++++++--- animatediff/nodes_pia.py | 3 +++ animatediff/nodes_sample.py | 3 +++ 6 files changed, 24 insertions(+), 3 deletions(-) diff --git a/animatediff/nodes_animatelcmi2v.py b/animatediff/nodes_animatelcmi2v.py index be33d11..370f5f0 100644 --- a/animatediff/nodes_animatelcmi2v.py +++ b/animatediff/nodes_animatelcmi2v.py @@ -34,6 +34,7 @@ def INPUT_TYPES(s): "effect_multival": ("MULTIVAL",), "ad_keyframes": ("AD_KEYFRAMES",), "prev_m_models": ("M_MODELS",), + "autosize": ("ADEAUTOSIZE", {"padding": 70}), } } diff --git a/animatediff/nodes_cameractrl.py b/animatediff/nodes_cameractrl.py index aaaaee6..4c84ca4 100644 --- a/animatediff/nodes_cameractrl.py +++ b/animatediff/nodes_cameractrl.py @@ -271,6 +271,7 @@ def INPUT_TYPES(s): "cameractrl_multival": ("MULTIVAL",), "inherit_missing": ("BOOLEAN", {"default": True}, ), "guarantee_steps": ("INT", {"default": 1, "min": 0, "max": BIGMAX}), + "autosize": ("ADEAUTOSIZE", {"padding": 30}), } } @@ -330,6 +331,7 @@ def INPUT_TYPES(cls): }, "optional": { "prev_poses": ("CAMERACTRL_POSES",), + "autosize": ("ADEAUTOSIZE", {"padding": 30}), } } diff --git a/animatediff/nodes_gen2.py b/animatediff/nodes_gen2.py index f06e819..8302df2 100644 --- a/animatediff/nodes_gen2.py +++ b/animatediff/nodes_gen2.py @@ -94,6 +94,7 @@ def INPUT_TYPES(s): "effect_multival": ("MULTIVAL",), "ad_keyframes": ("AD_KEYFRAMES",), "prev_m_models": ("M_MODELS",), + "autosize": ("ADEAUTOSIZE", {"padding": 80}), } } @@ -140,6 +141,7 @@ def INPUT_TYPES(s): "scale_multival": ("MULTIVAL",), "effect_multival": ("MULTIVAL",), "ad_keyframes": ("AD_KEYFRAMES",), + "autosize": ("ADEAUTOSIZE", {"padding": 40}), } } @@ -192,6 +194,7 @@ def INPUT_TYPES(s): "effect_multival": ("MULTIVAL",), "inherit_missing": ("BOOLEAN", {"default": True}, ), "guarantee_steps": ("INT", {"default": 1, "min": 0, "max": BIGMAX}), + "autosize": ("ADEAUTOSIZE", {"padding": 0}), } } diff --git a/animatediff/nodes_multival.py b/animatediff/nodes_multival.py index 25d1098..1149104 100644 --- a/animatediff/nodes_multival.py +++ b/animatediff/nodes_multival.py @@ -21,7 +21,8 @@ def INPUT_TYPES(s): "float_val": ("FLOAT", {"default": 1.0, "min": 0.0, "step": 0.001},), }, "optional": { - "mask_optional": ("MASK",) + "mask_optional": ("MASK",), + "autosize": ("ADEAUTOSIZE", {"padding": 10}), } } @@ -76,6 +77,7 @@ def INPUT_TYPES(s): }, "optional": { "scaling": (ScaleType.LIST,), + "autosize": ("ADEAUTOSIZE", {"padding": 10}), } } @@ -120,7 +122,8 @@ def INPUT_TYPES(s): "float_val": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001, "forceInput": True},), }, "optional": { - "mask_optional": ("MASK",) + "mask_optional": ("MASK",), + "autosize": ("ADEAUTOSIZE", {"padding": 10}), } } @@ -139,6 +142,9 @@ def INPUT_TYPES(s): "required": { "float_val": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001},), }, + "optional": { + "autosize": ("ADEAUTOSIZE", {"padding": 10}), + } } RETURN_TYPES = ("MULTIVAL",) @@ -154,7 +160,10 @@ class MultivalConvertToMaskNode: def INPUT_TYPES(s): return { "required": { - "multival": ("MULTIVAL",) + "multival": ("MULTIVAL",), + }, + "optional": { + "autosize": ("ADEAUTOSIZE", {"padding": 10}), } } diff --git a/animatediff/nodes_pia.py b/animatediff/nodes_pia.py index c966a38..e65386a 100644 --- a/animatediff/nodes_pia.py +++ b/animatediff/nodes_pia.py @@ -125,6 +125,7 @@ def INPUT_TYPES(s): "effect_multival": ("MULTIVAL",), "ad_keyframes": ("AD_KEYFRAMES",), "prev_m_models": ("M_MODELS",), + "autosize": ("ADEAUTOSIZE", {"padding": 70}), } } @@ -198,6 +199,7 @@ def INPUT_TYPES(s): "pia_input": ("PIA_INPUT",), "inherit_missing": ("BOOLEAN", {"default": True}, ), "guarantee_steps": ("INT", {"default": 1, "min": 0, "max": BIGMAX}), + "autosize": ("ADEAUTOSIZE", {"padding": 5}), } } @@ -249,6 +251,7 @@ def INPUT_TYPES(s): "optional": { "mult_multival": ("MULTIVAL",), "print_values": ("BOOLEAN", {"default": False},), + "autosize": ("ADEAUTOSIZE", {"padding": 60}), #"effect_multival": ("MULTIVAL",), } } diff --git a/animatediff/nodes_sample.py b/animatediff/nodes_sample.py index a4041f2..a5e147c 100644 --- a/animatediff/nodes_sample.py +++ b/animatediff/nodes_sample.py @@ -223,6 +223,7 @@ def INPUT_TYPES(s): }, "optional": { "cfg_extras": ("CFG_EXTRAS",), + "autosize": ("ADEAUTOSIZE", {"padding": 20}), } } @@ -246,6 +247,7 @@ def INPUT_TYPES(s): }, "optional": { "cfg_extras": ("CFG_EXTRAS",), + "autosize": ("ADEAUTOSIZE", {"padding": 10}), } } @@ -269,6 +271,7 @@ def INPUT_TYPES(s): "optional": { "prev_custom_cfg": ("CUSTOM_CFG",), "cfg_extras": ("CFG_EXTRAS",), + "autosize": ("ADEAUTOSIZE", {"padding": 80}), } } From 3acf95e7a492db5d9ae048deebe1d3a8a669ac1a Mon Sep 17 00:00:00 2001 From: Jedrzej Kosinski Date: Mon, 15 Jul 2024 16:12:56 -0500 Subject: [PATCH 4/8] Added autosize on a bunch more nodes, added Sigma Schedule to Sigmas node --- animatediff/nodes.py | 6 +++-- animatediff/nodes_ad_settings.py | 11 ++++++++ animatediff/nodes_conditioning.py | 30 +++++++++++++++++++--- animatediff/nodes_lora.py | 13 ++++++---- animatediff/nodes_sample.py | 10 ++++++++ animatediff/nodes_sigma_schedule.py | 40 +++++++++++++++++++++++++++++ 6 files changed, 99 insertions(+), 11 deletions(-) diff --git a/animatediff/nodes.py b/animatediff/nodes.py index 5597df2..62af7ff 100644 --- a/animatediff/nodes.py +++ b/animatediff/nodes.py @@ -23,7 +23,7 @@ CustomCFGNode, CustomCFGSimpleNode, CustomCFGKeyframeNode, CustomCFGKeyframeSimpleNode, CFGExtrasPAGNode, CFGExtrasPAGSimpleNode, CFGExtrasRescaleCFGNode, CFGExtrasRescaleCFGSimpleNode, NoisedImageInjectionNode, NoisedImageInjectOptionsNode) -from .nodes_sigma_schedule import (SigmaScheduleNode, RawSigmaScheduleNode, WeightedAverageSigmaScheduleNode, InterpolatedWeightedAverageSigmaScheduleNode, SplitAndCombineSigmaScheduleNode) +from .nodes_sigma_schedule import (SigmaScheduleNode, RawSigmaScheduleNode, WeightedAverageSigmaScheduleNode, InterpolatedWeightedAverageSigmaScheduleNode, SplitAndCombineSigmaScheduleNode, SigmaScheduleToSigmasNode) from .nodes_context import (LegacyLoopedUniformContextOptionsNode, LoopedUniformContextOptionsNode, LoopedUniformViewOptionsNode, StandardUniformContextOptionsNode, StandardStaticContextOptionsNode, BatchedContextOptionsNode, StandardStaticViewOptionsNode, StandardUniformViewOptionsNode, ViewAsContextOptionsNode, VisualizeContextOptionsK, VisualizeContextOptionsKAdv, VisualizeContextOptionsSCustom) @@ -115,6 +115,7 @@ "ADE_SigmaScheduleWeightedAverage": WeightedAverageSigmaScheduleNode, "ADE_SigmaScheduleWeightedAverageInterp": InterpolatedWeightedAverageSigmaScheduleNode, "ADE_SigmaScheduleSplitAndCombine": SplitAndCombineSigmaScheduleNode, + "ADE_SigmaScheduleToSigmas": SigmaScheduleToSigmasNode, "ADE_NoisedImageInjection": NoisedImageInjectionNode, "ADE_NoisedImageInjectOptions": NoisedImageInjectOptionsNode, "ADE_CFGExtrasPAGSimple": CFGExtrasPAGSimpleNode, @@ -220,7 +221,7 @@ "ADE_NoiseLayerReplace": "Noise Layer [Replace] πŸŽ­πŸ…πŸ…“", # AnimateDiff Settings "ADE_AnimateDiffSettings": "AnimateDiff Settings πŸŽ­πŸ…πŸ…“", - "ADE_AdjustPESweetspotStretch": "Adjust PE [Sweetspot Stretch] πŸŽ­πŸ…πŸ…“", + "ADE_AdjustPESweetspotStretch": "Adjust PE [Sweetspot] πŸŽ­πŸ…πŸ…“", "ADE_AdjustPEFullStretch": "Adjust PE [Full Stretch] πŸŽ­πŸ…πŸ…“", "ADE_AdjustPEManual": "Adjust PE [Manual] πŸŽ­πŸ…πŸ…“", "ADE_AdjustWeightAllAdd": "Adjust Weight [Allβ—†Add] πŸŽ­πŸ…πŸ…“", @@ -239,6 +240,7 @@ "ADE_SigmaScheduleWeightedAverage": "Sigma Schedule Weighted Mean πŸŽ­πŸ…πŸ…“", "ADE_SigmaScheduleWeightedAverageInterp": "Sigma Schedule Interpolated Mean πŸŽ­πŸ…πŸ…“", "ADE_SigmaScheduleSplitAndCombine": "Sigma Schedule Split Combine πŸŽ­πŸ…πŸ…“", + "ADE_SigmaScheduleToSigmas": "Sigma Schedule To Sigmas πŸŽ­πŸ…πŸ…“", "ADE_NoisedImageInjection": "Image Injection πŸŽ­πŸ…πŸ…“", "ADE_NoisedImageInjectOptions": "Image Injection Options πŸŽ­πŸ…πŸ…“", "ADE_CFGExtrasPAGSimple": "CFG Extrasβ—†PAG πŸŽ­πŸ…πŸ…“", diff --git a/animatediff/nodes_ad_settings.py b/animatediff/nodes_ad_settings.py index fbe8dd2..e99364b 100644 --- a/animatediff/nodes_ad_settings.py +++ b/animatediff/nodes_ad_settings.py @@ -9,6 +9,7 @@ def INPUT_TYPES(s): "optional": { "pe_adjust": ("PE_ADJUST",), "weight_adjust": ("WEIGHT_ADJUST",), + "autosize": ("ADEAUTOSIZE", {"padding": 0}), } } @@ -30,9 +31,11 @@ def INPUT_TYPES(s): "initial_pe_idx_offset": ("INT", {"default": 0, "min": 0, "step": 1}), "final_pe_idx_offset": ("INT", {"default": 0, "min": 0, "step": 1}), "print_adjustment": ("BOOLEAN", {"default": False}), + }, "optional": { "prev_pe_adjust": ("PE_ADJUST",), + "autosize": ("ADEAUTOSIZE", {"padding": 30}), } } @@ -64,6 +67,7 @@ def INPUT_TYPES(s): }, "optional": { "prev_pe_adjust": ("PE_ADJUST",), + "autosize": ("ADEAUTOSIZE", {"padding": 20}), } } @@ -91,6 +95,7 @@ def INPUT_TYPES(s): }, "optional": { "prev_pe_adjust": ("PE_ADJUST",), + "autosize": ("ADEAUTOSIZE", {"padding": 30}), } } @@ -118,6 +123,7 @@ def INPUT_TYPES(s): }, "optional": { "prev_weight_adjust": ("WEIGHT_ADJUST",), + "autosize": ("ADEAUTOSIZE", {"padding": 0}), } } @@ -147,6 +153,7 @@ def INPUT_TYPES(s): }, "optional": { "prev_weight_adjust": ("WEIGHT_ADJUST",), + "autosize": ("ADEAUTOSIZE", {"padding": 0}), } } @@ -178,6 +185,7 @@ def INPUT_TYPES(s): }, "optional": { "prev_weight_adjust": ("WEIGHT_ADJUST",), + "autosize": ("ADEAUTOSIZE", {"padding": 0}), } } @@ -211,6 +219,7 @@ def INPUT_TYPES(s): }, "optional": { "prev_weight_adjust": ("WEIGHT_ADJUST",), + "autosize": ("ADEAUTOSIZE", {"padding": 0}), } } @@ -249,6 +258,7 @@ def INPUT_TYPES(s): }, "optional": { "prev_weight_adjust": ("WEIGHT_ADJUST",), + "autosize": ("ADEAUTOSIZE", {"padding": 20}), } } @@ -295,6 +305,7 @@ def INPUT_TYPES(s): }, "optional": { "prev_weight_adjust": ("WEIGHT_ADJUST",), + "autosize": ("ADEAUTOSIZE", {"padding": 20}), } } diff --git a/animatediff/nodes_conditioning.py b/animatediff/nodes_conditioning.py index 87121e9..6a95465 100644 --- a/animatediff/nodes_conditioning.py +++ b/animatediff/nodes_conditioning.py @@ -32,7 +32,8 @@ def INPUT_TYPES(s): "optional": { "opt_mask": ("MASK", ), "opt_lora_hook": ("LORA_HOOK",), - "opt_timesteps": ("TIMESTEPS_COND",) + "opt_timesteps": ("TIMESTEPS_COND",), + "autosize": ("ADEAUTOSIZE", {"padding": 0}), } } @@ -62,7 +63,8 @@ def INPUT_TYPES(s): "optional": { "opt_mask": ("MASK", ), "opt_lora_hook": ("LORA_HOOK",), - "opt_timesteps": ("TIMESTEPS_COND",) + "opt_timesteps": ("TIMESTEPS_COND",), + "autosize": ("ADEAUTOSIZE", {"padding": 0}), } } @@ -94,7 +96,8 @@ def INPUT_TYPES(s): "optional": { "opt_mask": ("MASK", ), "opt_lora_hook": ("LORA_HOOK",), - "opt_timesteps": ("TIMESTEPS_COND",) + "opt_timesteps": ("TIMESTEPS_COND",), + "autosize": ("ADEAUTOSIZE", {"padding": 70}), } } @@ -125,7 +128,8 @@ def INPUT_TYPES(s): "optional": { "opt_mask": ("MASK", ), "opt_lora_hook": ("LORA_HOOK",), - "opt_timesteps": ("TIMESTEPS_COND",) + "opt_timesteps": ("TIMESTEPS_COND",), + "autosize": ("ADEAUTOSIZE", {"padding": 55}), } } @@ -154,6 +158,7 @@ def INPUT_TYPES(s): }, "optional": { "opt_lora_hook": ("LORA_HOOK",), + "autosize": ("ADEAUTOSIZE", {"padding": 10}), } } @@ -179,6 +184,7 @@ def INPUT_TYPES(s): }, "optional": { "opt_lora_hook": ("LORA_HOOK",), + "autosize": ("ADEAUTOSIZE", {"padding": 0}), } } @@ -207,6 +213,9 @@ def INPUT_TYPES(s): "required": { "start_percent": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001}), "end_percent": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.001}) + }, + "optional": { + "autosize": ("ADEAUTOSIZE", {"padding": 25}), } } @@ -225,6 +234,9 @@ def INPUT_TYPES(s): "required": { "lora_hook": ("LORA_HOOK",), "hook_kf": ("LORA_HOOK_KEYFRAMES",), + }, + "optional": { + "autosize": ("ADEAUTOSIZE", {"padding": 40}), } } @@ -249,6 +261,7 @@ def INPUT_TYPES(s): }, "optional": { "prev_hook_kf": ("LORA_HOOK_KEYFRAMES",), + "autosize": ("ADEAUTOSIZE", {"padding": 5}), } } @@ -503,6 +516,9 @@ def INPUT_TYPES(s): "required": { "conditioning": ("CONDITIONING",), "lora_hook": ("LORA_HOOK",), + }, + "optional": { + "autosize": ("ADEAUTOSIZE", {"padding": 5}), } } @@ -526,6 +542,9 @@ def INPUT_TYPES(s): "required": { "clip": ("CLIP",), "lora_hook": ("LORA_HOOK",), + }, + "optional": { + "autosize": ("ADEAUTOSIZE", {"padding": 0}), } } @@ -549,6 +568,7 @@ def INPUT_TYPES(s): "optional": { "lora_hook_A": ("LORA_HOOK",), "lora_hook_B": ("LORA_HOOK",), + "autosize": ("ADEAUTOSIZE", {"padding": 30}), } } @@ -572,6 +592,7 @@ def INPUT_TYPES(s): "lora_hook_B": ("LORA_HOOK",), "lora_hook_C": ("LORA_HOOK",), "lora_hook_D": ("LORA_HOOK",), + "autosize": ("ADEAUTOSIZE", {"padding": 30}), } } @@ -601,6 +622,7 @@ def INPUT_TYPES(s): "lora_hook_F": ("LORA_HOOK",), "lora_hook_G": ("LORA_HOOK",), "lora_hook_H": ("LORA_HOOK",), + "autosize": ("ADEAUTOSIZE", {"padding": 30}), } } diff --git a/animatediff/nodes_lora.py b/animatediff/nodes_lora.py index 3286962..1f1524c 100644 --- a/animatediff/nodes_lora.py +++ b/animatediff/nodes_lora.py @@ -14,11 +14,12 @@ class AnimateDiffLoraLoader: def INPUT_TYPES(s): return { "required": { - "lora_name": (get_available_motion_loras(),), + "name": (get_available_motion_loras(),), "strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}), }, "optional": { "prev_motion_lora": ("MOTION_LORA",), + "autosize": ("ADEAUTOSIZE", {"padding": 30}), } } @@ -26,17 +27,19 @@ def INPUT_TYPES(s): CATEGORY = "Animate Diff πŸŽ­πŸ…πŸ…“" FUNCTION = "load_motion_lora" - def load_motion_lora(self, lora_name: str, strength: float, prev_motion_lora: MotionLoraList=None): + def load_motion_lora(self, name: str, strength: float, prev_motion_lora: MotionLoraList=None, lora_name: str=None): if prev_motion_lora is None: prev_motion_lora = MotionLoraList() else: prev_motion_lora = prev_motion_lora.clone() + if lora_name is not None: # backwards compatibility + name = lora_name # check if motion lora with name exists - lora_path = get_motion_lora_path(lora_name) + lora_path = get_motion_lora_path(name) if not Path(lora_path).is_file(): - raise FileNotFoundError(f"Motion lora with name '{lora_name}' not found.") + raise FileNotFoundError(f"Motion lora with name '{name}' not found.") # create motion lora info to be loaded in AnimateDiff Loader - lora_info = MotionLoraInfo(name=lora_name, strength=strength) + lora_info = MotionLoraInfo(name=name, strength=strength) prev_motion_lora.add_lora(lora_info) return (prev_motion_lora,) diff --git a/animatediff/nodes_sample.py b/animatediff/nodes_sample.py index a5e147c..5d8b772 100644 --- a/animatediff/nodes_sample.py +++ b/animatediff/nodes_sample.py @@ -32,6 +32,7 @@ def INPUT_TYPES(s): "custom_cfg": ("CUSTOM_CFG",), "sigma_schedule": ("SIGMA_SCHEDULE",), "image_inject": ("IMAGE_INJECT",), + "autosize": ("ADEAUTOSIZE", {"padding": 10}), } } @@ -63,6 +64,7 @@ def INPUT_TYPES(s): "prev_noise_layers": ("NOISE_LAYERS",), "mask_optional": ("MASK",), "seed_override": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff, "forceInput": True}), + "autosize": ("ADEAUTOSIZE", {"padding": 20}), } } @@ -98,6 +100,7 @@ def INPUT_TYPES(s): "prev_noise_layers": ("NOISE_LAYERS",), "mask_optional": ("MASK",), "seed_override": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff, "forceInput": True}), + "autosize": ("ADEAUTOSIZE", {"padding": 20}), } } @@ -136,6 +139,7 @@ def INPUT_TYPES(s): "prev_noise_layers": ("NOISE_LAYERS",), "mask_optional": ("MASK",), "seed_override": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff, "forceInput": True}), + "autosize": ("ADEAUTOSIZE", {"padding": 10}), } } @@ -197,6 +201,7 @@ def INPUT_TYPES(s): "optional": { "iter_batch_offset": ("INT", {"default": 0, "min": 0, "max": BIGMAX}), "iter_seed_offset": ("INT", {"default": 1, "min": BIGMIN, "max": BIGMAX}), + "autosize": ("ADEAUTOSIZE", {"padding": 55}), } } @@ -324,6 +329,7 @@ def INPUT_TYPES(s): }, "optional": { "prev_extras": ("CFG_EXTRAS",), + "autosize": ("ADEAUTOSIZE", {"padding": 45}), } } @@ -355,6 +361,7 @@ def INPUT_TYPES(s): }, "optional": { "prev_extras": ("CFG_EXTRAS",), + "autosize": ("ADEAUTOSIZE", {"padding": 0}), } } @@ -407,6 +414,7 @@ def INPUT_TYPES(s): }, "optional": { "prev_extras": ("CFG_EXTRAS",), + "autosize": ("ADEAUTOSIZE", {"padding": 45}), } } @@ -436,6 +444,7 @@ def INPUT_TYPES(s): "img_inject_opts": ("IMAGE_INJECT_OPTIONS", ), "strength_multival": ("MULTIVAL", ), "prev_image_inject": ("IMAGE_INJECT", ), + "autosize": ("ADEAUTOSIZE", {"padding": 0}), } } @@ -465,6 +474,7 @@ def INPUT_TYPES(s): "optional": { "composite_x": ("INT", {"default": 0, "min": 0, "max": MAX_RESOLUTION, "step": 1}), "composite_y": ("INT", {"default": 0, "min": 0, "max": MAX_RESOLUTION, "step": 1}), + "autosize": ("ADEAUTOSIZE", {"padding": 30}), } } diff --git a/animatediff/nodes_sigma_schedule.py b/animatediff/nodes_sigma_schedule.py index 4431c7a..20580a2 100644 --- a/animatediff/nodes_sigma_schedule.py +++ b/animatediff/nodes_sigma_schedule.py @@ -1,5 +1,7 @@ import torch +import comfy.samplers + from .utils_model import BetaSchedules, SigmaSchedule, ModelSamplingType, ModelSamplingConfig, InterpolationMethod @@ -71,6 +73,9 @@ def INPUT_TYPES(s): "schedule_A": ("SIGMA_SCHEDULE",), "schedule_B": ("SIGMA_SCHEDULE",), "weight_A": ("FLOAT", {"default": 0.5, "min": 0.0, "max": 1.0, "step": 0.001}), + }, + "optional": { + "autosize": ("ADEAUTOSIZE", {"padding": 80}), } } @@ -124,6 +129,9 @@ def INPUT_TYPES(s): "schedule_Start": ("SIGMA_SCHEDULE",), "schedule_End": ("SIGMA_SCHEDULE",), "idx_split_percent": ("FLOAT", {"default": 0.5, "min": 0.0, "max": 1.0, "step": 0.001}) + }, + "optional": { + "autosize": ("ADEAUTOSIZE", {"padding": 40}), } } @@ -139,3 +147,35 @@ def get_sigma_schedule(self, schedule_Start: SigmaSchedule, schedule_End: SigmaS new_schedule = schedule_Start.clone() new_schedule.model_sampling.set_sigmas(new_sigmas) return (new_schedule,) + + +class SigmaScheduleToSigmasNode: + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "sigma_schedule": ("SIGMA_SCHEDULE",), + "scheduler": (comfy.samplers.SCHEDULER_NAMES, ), + "steps": ("INT", {"default": 20, "min": 1, "max": 10000}), + "denoise": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01}), + }, + "optional": { + "autosize": ("ADEAUTOSIZE", {"padding": 50}), + } + } + + RETURN_TYPES = ("SIGMAS",) + CATEGORY = "Animate Diff πŸŽ­πŸ…πŸ…“/sample settings/sigma schedule" + FUNCTION = "get_sigmas" + + def get_sigmas(self, sigma_schedule: SigmaSchedule, scheduler: str, steps: int, denoise: float): + total_steps = steps + if denoise < 1.0: + if denoise <= 0.0: + return (torch.FloatTensor([]),) + total_steps = int(steps/denoise) + + sigmas = comfy.samplers.calculate_sigmas(sigma_schedule, scheduler, total_steps).cpu() + sigmas = sigmas[-(steps + 1):] + return (sigmas, ) + \ No newline at end of file From 0899b1620a4b36c3ddf5656bb34233d81f2e8bcc Mon Sep 17 00:00:00 2001 From: Jedrzej Kosinski Date: Mon, 15 Jul 2024 16:24:53 -0500 Subject: [PATCH 5/8] Added Manual Combine Cond/s nodes --- animatediff/conditioning.py | 2 +- animatediff/nodes.py | 5 ++++ animatediff/nodes_conditioning.py | 41 +++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/animatediff/conditioning.py b/animatediff/conditioning.py index f626efb..455257a 100644 --- a/animatediff/conditioning.py +++ b/animatediff/conditioning.py @@ -274,7 +274,7 @@ def set_mask_conds(conds: list, strength: float, set_cond_area: str, masked_conds.append(c) return masked_conds -def set_mask_and_combine_conds(conds: list, new_conds: list, strength: float, set_cond_area: str, +def set_mask_and_combine_conds(conds: list, new_conds: list, strength: float=1.0, set_cond_area: str="default", opt_mask: Tensor=None, opt_lora_hook: LoraHookGroup=None, opt_timesteps: TimestepsCond=None): combined_conds = [] for c, masked_c in zip(conds, new_conds): diff --git a/animatediff/nodes.py b/animatediff/nodes.py index 62af7ff..b9c2a56 100644 --- a/animatediff/nodes.py +++ b/animatediff/nodes.py @@ -17,6 +17,7 @@ PairedConditioningSetMaskHooked, ConditioningSetMaskHooked, PairedConditioningSetMaskAndCombineHooked, ConditioningSetMaskAndCombineHooked, PairedConditioningSetUnmaskedAndCombineHooked, ConditioningSetUnmaskedAndCombineHooked, + PairedConditioningCombine, ConditioningCombine, ConditioningTimestepsNode, SetLoraHookKeyframes, CreateLoraHookKeyframe, CreateLoraHookKeyframeInterpolation, CreateLoraHookKeyframeFromStrengthList) from .nodes_sample import (FreeInitOptionsNode, NoiseLayerAddWeightedNode, SampleSettingsNode, NoiseLayerAddNode, NoiseLayerReplaceNode, IterationOptionsNode, @@ -89,6 +90,8 @@ "ADE_ConditioningSetMaskAndCombine": ConditioningSetMaskAndCombineHooked, "ADE_PairedConditioningSetUnmaskedAndCombine": PairedConditioningSetUnmaskedAndCombineHooked, "ADE_ConditioningSetUnmaskedAndCombine": ConditioningSetUnmaskedAndCombineHooked, + "ADE_PairedConditioningCombine": PairedConditioningCombine, + "ADE_ConditioningCombine": ConditioningCombine, "ADE_TimestepsConditioning": ConditioningTimestepsNode, # Noise Layer Nodes "ADE_NoiseLayerAdd": NoiseLayerAddNode, @@ -214,6 +217,8 @@ "ADE_ConditioningSetMaskAndCombine": "Set Props and Combine Cond πŸŽ­πŸ…πŸ…“", "ADE_PairedConditioningSetUnmaskedAndCombine": "Set Unmasked Conds πŸŽ­πŸ…πŸ…“", "ADE_ConditioningSetUnmaskedAndCombine": "Set Unmasked Cond πŸŽ­πŸ…πŸ…“", + "ADE_PairedConditioningCombine": "Manual Combine Conds πŸŽ­πŸ…πŸ…“", + "ADE_ConditioningCombine": "Manual Combine Cond πŸŽ­πŸ…πŸ…“", "ADE_TimestepsConditioning": "Timesteps Conditioning πŸŽ­πŸ…πŸ…“", # Noise Layer Nodes "ADE_NoiseLayerAdd": "Noise Layer [Add] πŸŽ­πŸ…πŸ…“", diff --git a/animatediff/nodes_conditioning.py b/animatediff/nodes_conditioning.py index 6a95465..1bb77c0 100644 --- a/animatediff/nodes_conditioning.py +++ b/animatediff/nodes_conditioning.py @@ -197,6 +197,47 @@ def append_and_combine(self, cond, cond_DEFAULT, (final_conditioning,) = set_unmasked_and_combine_conds(conds=[cond], new_conds=[cond_DEFAULT], opt_lora_hook=opt_lora_hook) return (final_conditioning,) + + +class PairedConditioningCombine: + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "positive_A": ("CONDITIONING",), + "negative_A": ("CONDITIONING",), + "positive_B": ("CONDITIONING",), + "negative_B": ("CONDITIONING",), + }, + } + + RETURN_TYPES = ("CONDITIONING", "CONDITIONING") + RETURN_NAMES = ("positive", "negative") + CATEGORY = "Animate Diff πŸŽ­πŸ…πŸ…“/conditioning" + FUNCTION = "combine" + + def combine(self, positive_A, negative_A, positive_B, negative_B): + final_positive, final_negative = set_mask_and_combine_conds(conds=[positive_A, negative_A], new_conds=[positive_B, negative_B],) + return (final_positive, final_negative,) + + +class ConditioningCombine: + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "cond_A": ("CONDITIONING",), + "cond_B": ("CONDITIONING",), + }, + } + + RETURN_TYPES = ("CONDITIONING",) + CATEGORY = "Animate Diff πŸŽ­πŸ…πŸ…“/conditioning/single cond ops" + FUNCTION = "combine" + + def combine(self, cond_A, cond_B): + (final_conditioning,) = set_mask_and_combine_conds(conds=[cond_A], new_conds=[cond_B],) + return (final_conditioning,) ############################################### ############################################### ############################################### From 1fc556900dda3b0ae84b138ab95398264ad36dee Mon Sep 17 00:00:00 2001 From: Jedrzej Kosinski Date: Mon, 15 Jul 2024 17:01:50 -0500 Subject: [PATCH 6/8] Added Load Camera Poses (Path) node --- animatediff/nodes.py | 7 +++-- animatediff/nodes_cameractrl.py | 45 +++++++++++++++++++++++++++++++-- animatediff/utils_model.py | 10 ++++++++ 3 files changed, 58 insertions(+), 4 deletions(-) diff --git a/animatediff/nodes.py b/animatediff/nodes.py index b9c2a56..f143f84 100644 --- a/animatediff/nodes.py +++ b/animatediff/nodes.py @@ -6,7 +6,8 @@ from .nodes_gen2 import (UseEvolvedSamplingNode, ApplyAnimateDiffModelNode, ApplyAnimateDiffModelBasicNode, ADKeyframeNode, LoadAnimateDiffModelNode) from .nodes_animatelcmi2v import (ApplyAnimateLCMI2VModel, LoadAnimateLCMI2VModelNode, LoadAnimateDiffAndInjectI2VNode, UpscaleAndVaeEncode) -from .nodes_cameractrl import (LoadAnimateDiffModelWithCameraCtrl, ApplyAnimateDiffWithCameraCtrl, CameraCtrlADKeyframeNode, LoadCameraPoses, +from .nodes_cameractrl import (LoadAnimateDiffModelWithCameraCtrl, ApplyAnimateDiffWithCameraCtrl, CameraCtrlADKeyframeNode, + LoadCameraPosesFromFile, LoadCameraPosesFromPath, CameraCtrlPoseBasic, CameraCtrlPoseCombo, CameraCtrlPoseAdvanced, CameraCtrlManualAppendPose, CameraCtrlReplaceCameraParameters, CameraCtrlSetOriginalAspectRatio) from .nodes_pia import (ApplyAnimateDiffPIAModel, LoadAnimateDiffAndInjectPIANode, InputPIA_MultivalNode, InputPIA_PaperPresetsNode, PIA_ADKeyframeNode) @@ -148,7 +149,8 @@ "ADE_ApplyAnimateDiffModelWithCameraCtrl": ApplyAnimateDiffWithCameraCtrl, "ADE_LoadAnimateDiffModelWithCameraCtrl": LoadAnimateDiffModelWithCameraCtrl, "ADE_CameraCtrlAnimateDiffKeyframe": CameraCtrlADKeyframeNode, - "ADE_LoadCameraPoses": LoadCameraPoses, + "ADE_LoadCameraPoses": LoadCameraPosesFromFile, + "ADE_LoadCameraPosesFromPath": LoadCameraPosesFromPath, "ADE_CameraPoseBasic": CameraCtrlPoseBasic, "ADE_CameraPoseCombo": CameraCtrlPoseCombo, "ADE_CameraPoseAdvanced": CameraCtrlPoseAdvanced, @@ -276,6 +278,7 @@ "ADE_LoadAnimateDiffModelWithCameraCtrl": "Load AnimateDiff+CameraCtrl Model πŸŽ­πŸ…πŸ…“β‘‘", "ADE_CameraCtrlAnimateDiffKeyframe": "AnimateDiff+CameraCtrl Keyframe πŸŽ­πŸ…πŸ…“", "ADE_LoadCameraPoses": "Load CameraCtrl Poses (File) πŸŽ­πŸ…πŸ…“β‘‘", + "ADE_LoadCameraPosesFromPath": "Load CameraCtrl Poses (Path) πŸŽ­πŸ…πŸ…“β‘‘", "ADE_CameraPoseBasic": "Create CameraCtrl Poses πŸŽ­πŸ…πŸ…“β‘‘", "ADE_CameraPoseCombo": "Create CameraCtrl Poses (Combo) πŸŽ­πŸ…πŸ…“β‘‘", "ADE_CameraPoseAdvanced": "Create CameraCtrl Poses (Adv.) πŸŽ­πŸ…πŸ…“β‘‘", diff --git a/animatediff/nodes_cameractrl.py b/animatediff/nodes_cameractrl.py index 4c84ca4..9352bae 100644 --- a/animatediff/nodes_cameractrl.py +++ b/animatediff/nodes_cameractrl.py @@ -7,12 +7,13 @@ import copy import json import numpy as np +from pathlib import Path from collections import OrderedDict from .ad_settings import AnimateDiffSettings from .adapter_cameractrl import CameraEntry from .logger import logger -from .utils_model import get_available_motion_models, BIGMAX +from .utils_model import get_available_motion_models, calculate_file_hash, strip_path, BIGMAX from .utils_motion import ADKeyframeGroup from .motion_lora import MotionLoraList from .model_injection import (MotionModelGroup, MotionModelPatcher, load_motion_module_gen2, inject_camera_encoder_into_model) @@ -292,7 +293,7 @@ def load_keyframe(self, ) -class LoadCameraPoses: +class LoadCameraPosesFromFile: @classmethod def INPUT_TYPES(s): input_dir = folder_paths.get_input_directory() @@ -318,6 +319,46 @@ def load_camera_poses(self, pose_filename: str): poses = [[float(x) for x in pose] for pose in poses] poses = set_original_pose_dims(poses, pose_width=CAM.DEFAULT_POSE_WIDTH, pose_height=CAM.DEFAULT_POSE_HEIGHT) return (poses,) + + +class LoadCameraPosesFromPath: + @classmethod + def INPUT_TYPES(s): + return { + "optional": { + "file_path": ("STRING", {"default": "X://path/to/pose_file.txt"}), + } + } + + @classmethod + def IS_CHANGED(s, file_path, **kwargs): + if Path(file_path).is_file(): + return calculate_file_hash(strip_path(file_path)) + return False + + @classmethod + def VALIDATE_INPUTS(s, file_path, **kwargs): + # This function never gets ran for some reason, I don't care enough to figure out why right now. + if not Path(strip_path(file_path)).is_file(): + return f"Pose file not found: {file_path}" + return True + + RETURN_TYPES = ("CAMERACTRL_POSES",) + CATEGORY = "Animate Diff πŸŽ­πŸ…πŸ…“/β‘‘ Gen2 nodes β‘‘/CameraCtrl/poses" + FUNCTION = "load_camera_poses" + + def load_camera_poses(self, file_path: str): + file_path = strip_path(file_path) + if not Path(file_path).is_file(): + raise Exception(f"Pose file not found: {file_path}") + with open(file_path, 'r') as f: + poses = f.readlines() + # first line of file is the link to source, so can be skipped, + # and the rest is a header-less CSV file separated by single spaces + poses = [pose.strip().split(' ') for pose in poses[1:]] + poses = [[float(x) for x in pose] for pose in poses] + poses = set_original_pose_dims(poses, pose_width=CAM.DEFAULT_POSE_WIDTH, pose_height=CAM.DEFAULT_POSE_HEIGHT) + return (poses,) class CameraCtrlPoseBasic: diff --git a/animatediff/utils_model.py b/animatediff/utils_model.py index c59af31..0e62d00 100644 --- a/animatediff/utils_model.py +++ b/animatediff/utils_model.py @@ -378,6 +378,16 @@ def calculate_model_hash(model: ModelPatcher): return m.hexdigest() +def strip_path(path): + # removes whitespace and single quotes from either end of string, if present + path = path.strip() + if path.startswith("\""): + path = path[1:] + if path.endswith("\""): + path = path[:-1] + return path + + class ModelTypeSD: SD1_5 = "SD1.5" SD2_1 = "SD2.1" From 6cd7747da845b9e57b39f628211d086e4c8639ba Mon Sep 17 00:00:00 2001 From: Jedrzej Kosinski Date: Mon, 15 Jul 2024 19:05:12 -0500 Subject: [PATCH 7/8] Added Custom CFG Keyframes Interpolation and From List nodes, copied over set_model_options_post_cfg_function function into cfg_extras.py to slightly extend ComfyUI version compatibility --- animatediff/cfg_extras.py | 6 ++ animatediff/nodes.py | 22 +++--- animatediff/nodes_conditioning.py | 2 +- animatediff/nodes_sample.py | 108 ++++++++++++++++++++++++++++-- 4 files changed, 121 insertions(+), 17 deletions(-) diff --git a/animatediff/cfg_extras.py b/animatediff/cfg_extras.py index f2b3d47..4b0d6a5 100644 --- a/animatediff/cfg_extras.py +++ b/animatediff/cfg_extras.py @@ -21,6 +21,12 @@ def set_model_options_sampler_cfg_function(model_options: dict[str], sampler_cfg if disable_cfg1_optimization: model_options["disable_cfg1_optimization"] = True return model_options + +def set_model_options_post_cfg_function(model_options, post_cfg_function, disable_cfg1_optimization=False): + model_options["sampler_post_cfg_function"] = model_options.get("sampler_post_cfg_function", []) + [post_cfg_function] + if disable_cfg1_optimization: + model_options["disable_cfg1_optimization"] = True + return model_options #------------------------------------------------------------------------------- diff --git a/animatediff/nodes.py b/animatediff/nodes.py index f143f84..07ba149 100644 --- a/animatediff/nodes.py +++ b/animatediff/nodes.py @@ -22,7 +22,7 @@ ConditioningTimestepsNode, SetLoraHookKeyframes, CreateLoraHookKeyframe, CreateLoraHookKeyframeInterpolation, CreateLoraHookKeyframeFromStrengthList) from .nodes_sample import (FreeInitOptionsNode, NoiseLayerAddWeightedNode, SampleSettingsNode, NoiseLayerAddNode, NoiseLayerReplaceNode, IterationOptionsNode, - CustomCFGNode, CustomCFGSimpleNode, CustomCFGKeyframeNode, CustomCFGKeyframeSimpleNode, + CustomCFGNode, CustomCFGSimpleNode, CustomCFGKeyframeNode, CustomCFGKeyframeSimpleNode, CustomCFGKeyframeInterpolationNode, CustomCFGKeyframeFromListNode, CFGExtrasPAGNode, CFGExtrasPAGSimpleNode, CFGExtrasRescaleCFGNode, CFGExtrasRescaleCFGSimpleNode, NoisedImageInjectionNode, NoisedImageInjectOptionsNode) from .nodes_sigma_schedule import (SigmaScheduleNode, RawSigmaScheduleNode, WeightedAverageSigmaScheduleNode, InterpolatedWeightedAverageSigmaScheduleNode, SplitAndCombineSigmaScheduleNode, SigmaScheduleToSigmasNode) @@ -114,6 +114,12 @@ "ADE_CustomCFG": CustomCFGNode, "ADE_CustomCFGKeyframeSimple": CustomCFGKeyframeSimpleNode, "ADE_CustomCFGKeyframe": CustomCFGKeyframeNode, + "ADE_CustomCFGKeyframeInterpolation": CustomCFGKeyframeInterpolationNode, + "ADE_CustomCFGKeyframeFromList": CustomCFGKeyframeFromListNode, + "ADE_CFGExtrasPAGSimple": CFGExtrasPAGSimpleNode, + "ADE_CFGExtrasPAG": CFGExtrasPAGNode, + "ADE_CFGExtrasRescaleCFGSimple": CFGExtrasRescaleCFGSimpleNode, + "ADE_CFGExtrasRescaleCFG": CFGExtrasRescaleCFGNode, "ADE_SigmaSchedule": SigmaScheduleNode, "ADE_RawSigmaSchedule": RawSigmaScheduleNode, "ADE_SigmaScheduleWeightedAverage": WeightedAverageSigmaScheduleNode, @@ -122,10 +128,6 @@ "ADE_SigmaScheduleToSigmas": SigmaScheduleToSigmasNode, "ADE_NoisedImageInjection": NoisedImageInjectionNode, "ADE_NoisedImageInjectOptions": NoisedImageInjectOptionsNode, - "ADE_CFGExtrasPAGSimple": CFGExtrasPAGSimpleNode, - "ADE_CFGExtrasPAG": CFGExtrasPAGNode, - "ADE_CFGExtrasRescaleCFGSimple": CFGExtrasRescaleCFGSimpleNode, - "ADE_CFGExtrasRescaleCFG": CFGExtrasRescaleCFGNode, # Extras Nodes "ADE_AnimateDiffUnload": AnimateDiffUnload, "ADE_EmptyLatentImageLarge": EmptyLatentImageLarge, @@ -242,6 +244,12 @@ "ADE_CustomCFG": "Custom CFG [Multival] πŸŽ­πŸ…πŸ…“", "ADE_CustomCFGKeyframeSimple": "Custom CFG Keyframe πŸŽ­πŸ…πŸ…“", "ADE_CustomCFGKeyframe": "Custom CFG Keyframe [Multival] πŸŽ­πŸ…πŸ…“", + "ADE_CustomCFGKeyframeInterpolation": "Custom CFG Keyframes Interpolation πŸŽ­πŸ…πŸ…“", + "ADE_CustomCFGKeyframeFromList": "Custom CFG Keyframes From List πŸŽ­πŸ…πŸ…“", + "ADE_CFGExtrasPAGSimple": "CFG Extrasβ—†PAG πŸŽ­πŸ…πŸ…“", + "ADE_CFGExtrasPAG": "CFG Extrasβ—†PAG [Multival] πŸŽ­πŸ…πŸ…“", + "ADE_CFGExtrasRescaleCFGSimple": "CFG Extrasβ—†RescaleCFG πŸŽ­πŸ…πŸ…“", + "ADE_CFGExtrasRescaleCFG": "CFG Extrasβ—†RescaleCFG [Multival] πŸŽ­πŸ…πŸ…“", "ADE_SigmaSchedule": "Create Sigma Schedule πŸŽ­πŸ…πŸ…“", "ADE_RawSigmaSchedule": "Create Raw Sigma Schedule πŸŽ­πŸ…πŸ…“", "ADE_SigmaScheduleWeightedAverage": "Sigma Schedule Weighted Mean πŸŽ­πŸ…πŸ…“", @@ -250,10 +258,6 @@ "ADE_SigmaScheduleToSigmas": "Sigma Schedule To Sigmas πŸŽ­πŸ…πŸ…“", "ADE_NoisedImageInjection": "Image Injection πŸŽ­πŸ…πŸ…“", "ADE_NoisedImageInjectOptions": "Image Injection Options πŸŽ­πŸ…πŸ…“", - "ADE_CFGExtrasPAGSimple": "CFG Extrasβ—†PAG πŸŽ­πŸ…πŸ…“", - "ADE_CFGExtrasPAG": "CFG Extrasβ—†PAG [Multival] πŸŽ­πŸ…πŸ…“", - "ADE_CFGExtrasRescaleCFGSimple": "CFG Extrasβ—†RescaleCFG πŸŽ­πŸ…πŸ…“", - "ADE_CFGExtrasRescaleCFG": "CFG Extrasβ—†RescaleCFG [Multival] πŸŽ­πŸ…πŸ…“", # Extras Nodes "ADE_AnimateDiffUnload": "AnimateDiff Unload πŸŽ­πŸ…πŸ…“", "ADE_EmptyLatentImageLarge": "Empty Latent Image (Big Batch) πŸŽ­πŸ…πŸ…“", diff --git a/animatediff/nodes_conditioning.py b/animatediff/nodes_conditioning.py index 1bb77c0..9c694b2 100644 --- a/animatediff/nodes_conditioning.py +++ b/animatediff/nodes_conditioning.py @@ -400,7 +400,7 @@ def create_hook_keyframes(self, strengths_float: Union[float, list[float]], elif isinstance(strengths_float, Iterable): pass else: - raise Exception(f"strengths_floast must be either an interable input or a float, but was {type(strengths_float).__repr__}.") + raise Exception(f"strengths_float must be either an interable input or a float, but was {type(strengths_float).__repr__}.") percents = InterpolationMethod.get_weights(num_from=start_percent, num_to=end_percent, length=len(strengths_float), method=InterpolationMethod.LINEAR) is_first = True diff --git a/animatediff/nodes_sample.py b/animatediff/nodes_sample.py index 5d8b772..d988a62 100644 --- a/animatediff/nodes_sample.py +++ b/animatediff/nodes_sample.py @@ -1,8 +1,8 @@ from typing import Union from torch import Tensor +from collections.abc import Iterable from comfy.sd import VAE -from comfy.model_patcher import set_model_options_post_cfg_function from .freeinit import FreeInitFilter from .sample_settings import (FreeInitOptions, IterationOptions, @@ -10,8 +10,9 @@ SeedNoiseGeneration, SampleSettings, CustomCFGKeyframeGroup, CustomCFGKeyframe, CFGExtrasGroup, CFGExtras, NoisedImageToInjectGroup, NoisedImageToInject, NoisedImageInjectOptions) -from .utils_model import BIGMIN, BIGMAX, MAX_RESOLUTION, SigmaSchedule -from .cfg_extras import perturbed_attention_guidance_patch, rescale_cfg_patch, set_model_options_sampler_cfg_function +from .utils_model import BIGMIN, BIGMAX, MAX_RESOLUTION, SigmaSchedule, InterpolationMethod +from .cfg_extras import perturbed_attention_guidance_patch, rescale_cfg_patch, set_model_options_sampler_cfg_function, set_model_options_post_cfg_function +from .logger import logger class SampleSettingsNode: @@ -233,7 +234,7 @@ def INPUT_TYPES(s): } RETURN_TYPES = ("CUSTOM_CFG",) - CATEGORY = "Animate Diff πŸŽ­πŸ…πŸ…“/sample settings" + CATEGORY = "Animate Diff πŸŽ­πŸ…πŸ…“/sample settings/custom cfg" FUNCTION = "create_custom_cfg" def create_custom_cfg(self, cfg_multival: Union[float, Tensor], cfg_extras: CFGExtrasGroup=None): @@ -257,7 +258,7 @@ def INPUT_TYPES(s): } RETURN_TYPES = ("CUSTOM_CFG",) - CATEGORY = "Animate Diff πŸŽ­πŸ…πŸ…“/sample settings" + CATEGORY = "Animate Diff πŸŽ­πŸ…πŸ…“/sample settings/custom cfg" FUNCTION = "create_custom_cfg" def create_custom_cfg(self, cfg: float, cfg_extras: CFGExtrasGroup=None): @@ -281,7 +282,7 @@ def INPUT_TYPES(s): } RETURN_TYPES = ("CUSTOM_CFG",) - CATEGORY = "Animate Diff πŸŽ­πŸ…πŸ…“/sample settings" + CATEGORY = "Animate Diff πŸŽ­πŸ…πŸ…“/sample settings/custom cfg" FUNCTION = "create_custom_cfg" def create_custom_cfg(self, cfg_multival: Union[float, Tensor], start_percent: float=0.0, guarantee_steps: int=1, @@ -311,7 +312,7 @@ def INPUT_TYPES(s): } RETURN_TYPES = ("CUSTOM_CFG",) - CATEGORY = "Animate Diff πŸŽ­πŸ…πŸ…“/sample settings" + CATEGORY = "Animate Diff πŸŽ­πŸ…πŸ…“/sample settings/custom cfg" FUNCTION = "create_custom_cfg" def create_custom_cfg(self, cfg: float, start_percent: float=0.0, guarantee_steps: int=1, @@ -320,6 +321,99 @@ def create_custom_cfg(self, cfg: float, start_percent: float=0.0, guarantee_step guarantee_steps=guarantee_steps, prev_custom_cfg=prev_custom_cfg, cfg_extras=cfg_extras) +class CustomCFGKeyframeInterpolationNode: + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "start_percent": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001}), + "end_percent": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.001}), + "cfg_start": ("FLOAT", {"default": 8.0, "min": 0.0, "max": 100.0, "step": 0.1}), + "cfg_end": ("FLOAT", {"default": 8.0, "min": 0.0, "max": 100.0, "step": 0.1}), + "interpolation": (InterpolationMethod._LIST, ), + "intervals": ("INT", {"default": 50, "min": 2, "max": 100, "step": 1}), + "print_keyframes": ("BOOLEAN", {"default": False}), + }, + "optional": { + "prev_custom_cfg": ("CUSTOM_CFG",), + "cfg_extras": ("CFG_EXTRAS",), + } + } + + RETURN_TYPES = ("CUSTOM_CFG",) + CATEGORY = "Animate Diff πŸŽ­πŸ…πŸ…“/sample settings/custom cfg" + FUNCTION = "create_custom_cfg" + + def create_custom_cfg(self, + start_percent: float, end_percent: float, + cfg_start: float, cfg_end: float, interpolation: str, intervals: int, + prev_custom_cfg: CustomCFGKeyframeGroup=None, cfg_extras: CFGExtrasGroup=None, + print_keyframes=False): + if not prev_custom_cfg: + prev_custom_cfg = CustomCFGKeyframeGroup() + prev_custom_cfg = prev_custom_cfg.clone() + percents = InterpolationMethod.get_weights(num_from=start_percent, num_to=end_percent, length=intervals, method=InterpolationMethod.LINEAR) + cfgs = InterpolationMethod.get_weights(num_from=cfg_start, num_to=cfg_end, length=intervals, method=interpolation) + + is_first = True + for percent, cfg in zip(percents, cfgs): + guarantee_steps = 0 + if is_first: + guarantee_steps = 1 + is_first = False + prev_custom_cfg.add(CustomCFGKeyframe(cfg_multival=float(cfg), start_percent=percent, guarantee_steps=guarantee_steps, cfg_extras=cfg_extras)) + if print_keyframes: + logger.info(f"CustomCFGKeyframe - start_percent:{percent} = {cfg}") + return (prev_custom_cfg,) + + +class CustomCFGKeyframeFromListNode: + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "cfgs_float": ("FLOAT", {"default": -1, "min": -1, "step": 0.001, "forceInput": True}), + "start_percent": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001}), + "end_percent": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.001}), + "print_keyframes": ("BOOLEAN", {"default": False}), + }, + "optional": { + "prev_custom_cfg": ("CUSTOM_CFG",), + "cfg_extras": ("CFG_EXTRAS",), + } + } + + RETURN_TYPES = ("CUSTOM_CFG",) + CATEGORY = "Animate Diff πŸŽ­πŸ…πŸ…“/sample settings/custom cfg" + FUNCTION = "create_custom_cfg" + + def create_custom_cfg(self, cfgs_float: Union[float, list[float]], + start_percent: float, end_percent: float, + prev_custom_cfg: CustomCFGKeyframeGroup=None, cfg_extras: CFGExtrasGroup=None, + print_keyframes=False): + if not prev_custom_cfg: + prev_custom_cfg = CustomCFGKeyframeGroup() + prev_custom_cfg = prev_custom_cfg.clone() + if type(cfgs_float) in (float, int): + cfgs_float = [float(cfgs_float)] + elif isinstance(cfgs_float, Iterable): + pass + else: + raise Exception(f"strengths_float must be either an interable input or a float, but was {type(cfgs_float).__repr__}.") + percents = InterpolationMethod.get_weights(num_from=start_percent, num_to=end_percent, length=len(cfgs_float), method=InterpolationMethod.LINEAR) + + is_first = True + for percent, cfg in zip(percents, cfgs_float): + guarantee_steps = 0 + if is_first: + guarantee_steps = 1 + is_first = False + prev_custom_cfg.add(CustomCFGKeyframe(cfg_multival=float(cfg), start_percent=percent, guarantee_steps=guarantee_steps, cfg_extras=cfg_extras)) + if print_keyframes: + logger.info(f"CustomCFGKeyframe - start_percent:{percent} = {cfg}") + return (prev_custom_cfg,) + + class CFGExtrasPAGNode: @classmethod def INPUT_TYPES(s): From b10c6fd2117cedda113cac022a881d7a0aa34a99 Mon Sep 17 00:00:00 2001 From: Jedrzej Kosinski Date: Mon, 15 Jul 2024 19:06:26 -0500 Subject: [PATCH 8/8] version bump --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 30a7309..da50a53 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "comfyui-animatediff-evolved" description = "Improved AnimateDiff integration for ComfyUI." -version = "1.0.10" +version = "1.0.11" license = "LICENSE" dependencies = []