Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8a0e706567 | ||
|
|
13ed169c47 |
+6
-2
@@ -3,7 +3,7 @@ from .animatediff.logger import logger
|
|||||||
from .animatediff.utils_model import get_available_motion_models, Folders
|
from .animatediff.utils_model import get_available_motion_models, Folders
|
||||||
from .animatediff.model_injection import prepare_dinklink_register_definitions
|
from .animatediff.model_injection import prepare_dinklink_register_definitions
|
||||||
from .animatediff.motion_module_ad import prepare_dinklink_motion_module_ad
|
from .animatediff.motion_module_ad import prepare_dinklink_motion_module_ad
|
||||||
from .animatediff.nodes import NODE_CLASS_MAPPINGS, NODE_DISPLAY_NAME_MAPPINGS
|
from .animatediff.nodes import AnimateDiffExtension
|
||||||
from .animatediff.dinklink import init_dinklink
|
from .animatediff.dinklink import init_dinklink
|
||||||
|
|
||||||
if len(get_available_motion_models()) == 0:
|
if len(get_available_motion_models()) == 0:
|
||||||
@@ -11,8 +11,12 @@ if len(get_available_motion_models()) == 0:
|
|||||||
|
|
||||||
WEB_DIRECTORY = "./web"
|
WEB_DIRECTORY = "./web"
|
||||||
|
|
||||||
__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS", "WEB_DIRECTORY"]
|
__all__ = ["WEB_DIRECTORY"]
|
||||||
|
|
||||||
init_dinklink()
|
init_dinklink()
|
||||||
prepare_dinklink_register_definitions()
|
prepare_dinklink_register_definitions()
|
||||||
prepare_dinklink_motion_module_ad()
|
prepare_dinklink_motion_module_ad()
|
||||||
|
|
||||||
|
|
||||||
|
async def comfy_entrypoint() -> AnimateDiffExtension:
|
||||||
|
return AnimateDiffExtension()
|
||||||
|
|||||||
+324
-411
@@ -1,415 +1,328 @@
|
|||||||
import comfy.sample as comfy_sample
|
from comfy_api.latest import ComfyExtension, io
|
||||||
|
|
||||||
from .nodes_gen1 import (AnimateDiffLoaderGen1,)
|
from .nodes_ad_settings import (
|
||||||
from .nodes_gen2 import (UseEvolvedSamplingNode, ApplyAnimateDiffModelNode, ApplyAnimateDiffModelBasicNode, ADKeyframeNode,
|
AnimateDiffSettingsNode,
|
||||||
LoadAnimateDiffModelNode)
|
FullStretchPENode,
|
||||||
from .nodes_animatelcmi2v import (ApplyAnimateLCMI2VModel, LoadAnimateLCMI2VModelNode, LoadAnimateDiffAndInjectI2VNode, UpscaleAndVaeEncode)
|
ManualAdjustPENode,
|
||||||
from .nodes_cameractrl import (LoadAnimateDiffModelWithCameraCtrl, ApplyAnimateDiffWithCameraCtrl, CameraCtrlADKeyframeNode,
|
SweetspotStretchPENode,
|
||||||
LoadCameraPosesFromFile, LoadCameraPosesFromPath,
|
WeightAdjustAllAddNode,
|
||||||
CameraCtrlPoseBasic, CameraCtrlPoseCombo, CameraCtrlPoseAdvanced, CameraCtrlManualAppendPose,
|
WeightAdjustAllMultNode,
|
||||||
CameraCtrlReplaceCameraParameters, CameraCtrlSetOriginalAspectRatio)
|
WeightAdjustIndivAddNode,
|
||||||
from .nodes_motionctrl import (LoadMotionCtrlCMCM, LoadMotionCtrlOMCM, ApplyAnimateDiffMotionCtrlModel, LoadMotionCtrlCameraPosesFromFile)
|
WeightAdjustIndivAttnAddNode,
|
||||||
from .nodes_pia import (ApplyAnimateDiffPIAModel, LoadAnimateDiffAndInjectPIANode, InputPIA_MultivalNode, InputPIA_PaperPresetsNode, PIA_ADKeyframeNode)
|
WeightAdjustIndivAttnMultNode,
|
||||||
from .nodes_fancyvideo import (ApplyAnimateDiffFancyVideo,)
|
WeightAdjustIndivMultNode,
|
||||||
from .nodes_hellomeme import (TestHMRefNetInjection,)
|
)
|
||||||
from .nodes_multival import MultivalDynamicNode, MultivalScaledMaskNode, MultivalDynamicFloatInputNode, MultivalDynamicFloatsNode, MultivalConvertToMaskNode
|
from .nodes_animatelcmi2v import (
|
||||||
from .nodes_conditioning import (CreateLoraHookKeyframeInterpolationDEPR,
|
ApplyAnimateLCMI2VModel,
|
||||||
MaskableLoraLoaderDEPR, MaskableLoraLoaderModelOnlyDEPR, MaskableSDModelLoaderDEPR, MaskableSDModelLoaderModelOnlyDEPR,
|
LoadAnimateDiffAndInjectI2VNode,
|
||||||
SetModelLoraHookDEPR, SetClipLoraHookDEPR,
|
LoadAnimateLCMI2VModelNode,
|
||||||
CombineLoraHooksDEPR, CombineLoraHookFourOptionalDEPR, CombineLoraHookEightOptionalDEPR,
|
UpscaleAndVaeEncode,
|
||||||
PairedConditioningSetMaskHookedDEPR, ConditioningSetMaskHookedDEPR,
|
)
|
||||||
PairedConditioningSetMaskAndCombineHookedDEPR, ConditioningSetMaskAndCombineHookedDEPR,
|
from .nodes_cameractrl import (
|
||||||
PairedConditioningSetUnmaskedAndCombineHookedDEPR, ConditioningSetUnmaskedAndCombineHookedDEPR,
|
ApplyAnimateDiffWithCameraCtrl,
|
||||||
PairedConditioningCombineDEPR, ConditioningCombineDEPR,
|
CameraCtrlADKeyframeNode,
|
||||||
ConditioningTimestepsNodeDEPR, SetLoraHookKeyframesDEPR,
|
CameraCtrlManualAppendPose,
|
||||||
CreateLoraHookKeyframeDEPR, CreateLoraHookKeyframeFromStrengthListDEPR)
|
CameraCtrlPoseAdvanced,
|
||||||
from .nodes_sample import (FreeInitOptionsNode, NoiseLayerAddWeightedNode, NoiseLayerNormalizedSumNode, SampleSettingsNode, NoiseLayerAddNode, NoiseLayerReplaceNode, IterationOptionsNode,
|
CameraCtrlPoseBasic,
|
||||||
CustomCFGNode, CustomCFGSimpleNode, CustomCFGKeyframeNode, CustomCFGKeyframeSimpleNode, CustomCFGKeyframeInterpolationNode, CustomCFGKeyframeFromListNode,
|
CameraCtrlPoseCombo,
|
||||||
CFGExtrasPAGNode, CFGExtrasPAGSimpleNode, CFGExtrasRescaleCFGNode, CFGExtrasRescaleCFGSimpleNode,
|
CameraCtrlReplaceCameraParameters,
|
||||||
NoisedImageInjectionNode, NoisedImageInjectOptionsNode, NoiseCalibrationNode, AncestralOptionsNode)
|
CameraCtrlSetOriginalAspectRatio,
|
||||||
from .nodes_sigma_schedule import (SigmaScheduleNode, RawSigmaScheduleNode, WeightedAverageSigmaScheduleNode, InterpolatedWeightedAverageSigmaScheduleNode, SplitAndCombineSigmaScheduleNode, SigmaScheduleToSigmasNode)
|
LoadAnimateDiffModelWithCameraCtrl,
|
||||||
from .nodes_context import (LegacyLoopedUniformContextOptionsNode, LoopedUniformContextOptionsNode, LoopedUniformViewOptionsNode, StandardUniformContextOptionsNode, StandardStaticContextOptionsNode, BatchedContextOptionsNode,
|
LoadCameraPosesFromFile,
|
||||||
StandardStaticViewOptionsNode, StandardUniformViewOptionsNode, ViewAsContextOptionsNode,
|
LoadCameraPosesFromPath,
|
||||||
VisualizeContextOptionsK, VisualizeContextOptionsKAdv, VisualizeContextOptionsSCustom)
|
)
|
||||||
from .nodes_context_extras import (SetContextExtrasOnContextOptions, ContextExtras_NaiveReuse, ContextExtras_ContextRef,
|
from .nodes_conditioning import (
|
||||||
ContextRef_ModeFirst, ContextRef_ModeSliding, ContextRef_ModeIndexes,
|
CombineLoraHookEightOptionalDEPR,
|
||||||
ContextRef_TuneAttn, ContextRef_TuneAttnAdain,
|
CombineLoraHookFourOptionalDEPR,
|
||||||
ContextRef_KeyframeMultivalNode, ContextRef_KeyframeInterpolationNode, ContextRef_KeyframeFromListNode,
|
CombineLoraHooksDEPR,
|
||||||
NaiveReuse_KeyframeMultivalNode, NaiveReuse_KeyframeInterpolationNode, NaiveReuse_KeyframeFromListNode)
|
ConditioningCombineDEPR,
|
||||||
from .nodes_ad_settings import (AnimateDiffSettingsNode, ManualAdjustPENode, SweetspotStretchPENode, FullStretchPENode,
|
ConditioningSetMaskAndCombineHookedDEPR,
|
||||||
WeightAdjustAllAddNode, WeightAdjustAllMultNode, WeightAdjustIndivAddNode, WeightAdjustIndivMultNode,
|
ConditioningSetMaskHookedDEPR,
|
||||||
WeightAdjustIndivAttnAddNode, WeightAdjustIndivAttnMultNode)
|
ConditioningSetUnmaskedAndCombineHookedDEPR,
|
||||||
from .nodes_scheduling import (ConditionExtractionNode, PromptSchedulingNode, PromptSchedulingLatentsNode, ValueSchedulingNode, ValueSchedulingLatentsNode,
|
ConditioningTimestepsNodeDEPR,
|
||||||
AddValuesReplaceNode, FloatToFloatsNode)
|
CreateLoraHookKeyframeDEPR,
|
||||||
from .nodes_per_block import (ADBlockComboNode, ADBlockIndivNode, PerBlockHighLevelNode,
|
CreateLoraHookKeyframeFromStrengthListDEPR,
|
||||||
PerBlock_SD15_LowLevelNode, PerBlock_SD15_MidLevelNode, PerBlock_SD15_FromFloatsNode,
|
CreateLoraHookKeyframeInterpolationDEPR,
|
||||||
PerBlock_SDXL_LowLevelNode, PerBlock_SDXL_MidLevelNode, PerBlock_SDXL_FromFloatsNode)
|
MaskableLoraLoaderDEPR,
|
||||||
from .nodes_extras import AnimateDiffUnload, EmptyLatentImageLarge, CheckpointLoaderSimpleWithNoiseSelect, PerturbedAttentionGuidanceMultival, RescaleCFGMultival
|
MaskableLoraLoaderModelOnlyDEPR,
|
||||||
from .nodes_deprecated import (AnimateDiffLoaderDEPR, AnimateDiffLoaderAdvancedDEPR, LegacyAnimateDiffLoaderWithContextDEPR, AnimateDiffCombineDEPR,
|
MaskableSDModelLoaderDEPR,
|
||||||
AnimateDiffModelSettingsDEPR, AnimateDiffModelSettingsSimpleDEPR, AnimateDiffModelSettingsAdvancedDEPR, AnimateDiffModelSettingsAdvancedAttnStrengthsDEPR)
|
MaskableSDModelLoaderModelOnlyDEPR,
|
||||||
|
PairedConditioningCombineDEPR,
|
||||||
|
PairedConditioningSetMaskAndCombineHookedDEPR,
|
||||||
|
PairedConditioningSetMaskHookedDEPR,
|
||||||
|
PairedConditioningSetUnmaskedAndCombineHookedDEPR,
|
||||||
|
SetClipLoraHookDEPR,
|
||||||
|
SetLoraHookKeyframesDEPR,
|
||||||
|
SetModelLoraHookDEPR,
|
||||||
|
)
|
||||||
|
from .nodes_context import (
|
||||||
|
BatchedContextOptionsNode,
|
||||||
|
LegacyLoopedUniformContextOptionsNode,
|
||||||
|
LoopedUniformContextOptionsNode,
|
||||||
|
LoopedUniformViewOptionsNode,
|
||||||
|
StandardStaticContextOptionsNode,
|
||||||
|
StandardStaticViewOptionsNode,
|
||||||
|
StandardUniformContextOptionsNode,
|
||||||
|
StandardUniformViewOptionsNode,
|
||||||
|
ViewAsContextOptionsNode,
|
||||||
|
VisualizeContextOptionsK,
|
||||||
|
VisualizeContextOptionsKAdv,
|
||||||
|
VisualizeContextOptionsSCustom,
|
||||||
|
)
|
||||||
|
from .nodes_context_extras import (
|
||||||
|
ContextExtras_ContextRef,
|
||||||
|
ContextExtras_NaiveReuse,
|
||||||
|
ContextRef_KeyframeFromListNode,
|
||||||
|
ContextRef_KeyframeInterpolationNode,
|
||||||
|
ContextRef_KeyframeMultivalNode,
|
||||||
|
ContextRef_ModeFirst,
|
||||||
|
ContextRef_ModeIndexes,
|
||||||
|
ContextRef_ModeSliding,
|
||||||
|
ContextRef_TuneAttn,
|
||||||
|
ContextRef_TuneAttnAdain,
|
||||||
|
NaiveReuse_KeyframeFromListNode,
|
||||||
|
NaiveReuse_KeyframeInterpolationNode,
|
||||||
|
NaiveReuse_KeyframeMultivalNode,
|
||||||
|
SetContextExtrasOnContextOptions,
|
||||||
|
)
|
||||||
|
from .nodes_deprecated import (
|
||||||
|
AnimateDiffCombineDEPR,
|
||||||
|
AnimateDiffLoaderAdvancedDEPR,
|
||||||
|
AnimateDiffLoaderDEPR,
|
||||||
|
AnimateDiffModelSettingsAdvancedAttnStrengthsDEPR,
|
||||||
|
AnimateDiffModelSettingsAdvancedDEPR,
|
||||||
|
AnimateDiffModelSettingsDEPR,
|
||||||
|
AnimateDiffModelSettingsSimpleDEPR,
|
||||||
|
LegacyAnimateDiffLoaderWithContextDEPR,
|
||||||
|
)
|
||||||
|
from .nodes_extras import (
|
||||||
|
AnimateDiffUnload,
|
||||||
|
CheckpointLoaderSimpleWithNoiseSelect,
|
||||||
|
EmptyLatentImageLarge,
|
||||||
|
PerturbedAttentionGuidanceMultival,
|
||||||
|
RescaleCFGMultival,
|
||||||
|
)
|
||||||
|
from .nodes_gen1 import AnimateDiffLoaderGen1
|
||||||
|
from .nodes_gen2 import (
|
||||||
|
ADKeyframeNode,
|
||||||
|
ApplyAnimateDiffModelBasicNode,
|
||||||
|
ApplyAnimateDiffModelNode,
|
||||||
|
LoadAnimateDiffModelNode,
|
||||||
|
UseEvolvedSamplingNode,
|
||||||
|
)
|
||||||
from .nodes_lora import AnimateDiffLoraLoader
|
from .nodes_lora import AnimateDiffLoraLoader
|
||||||
|
from .nodes_multival import (
|
||||||
from .logger import logger
|
MultivalConvertToMaskNode,
|
||||||
|
MultivalDynamicFloatInputNode,
|
||||||
|
MultivalDynamicFloatsNode,
|
||||||
|
MultivalDynamicNode,
|
||||||
|
MultivalScaledMaskNode,
|
||||||
|
)
|
||||||
|
from .nodes_per_block import (
|
||||||
|
ADBlockComboNode,
|
||||||
|
ADBlockIndivNode,
|
||||||
|
PerBlockHighLevelNode,
|
||||||
|
PerBlock_SD15_FromFloatsNode,
|
||||||
|
PerBlock_SD15_LowLevelNode,
|
||||||
|
PerBlock_SD15_MidLevelNode,
|
||||||
|
PerBlock_SDXL_FromFloatsNode,
|
||||||
|
PerBlock_SDXL_LowLevelNode,
|
||||||
|
PerBlock_SDXL_MidLevelNode,
|
||||||
|
)
|
||||||
|
from .nodes_pia import (
|
||||||
|
ApplyAnimateDiffPIAModel,
|
||||||
|
InputPIA_MultivalNode,
|
||||||
|
InputPIA_PaperPresetsNode,
|
||||||
|
LoadAnimateDiffAndInjectPIANode,
|
||||||
|
PIA_ADKeyframeNode,
|
||||||
|
)
|
||||||
|
from .nodes_sample import (
|
||||||
|
AncestralOptionsNode,
|
||||||
|
CFGExtrasPAGNode,
|
||||||
|
CFGExtrasPAGSimpleNode,
|
||||||
|
CFGExtrasRescaleCFGNode,
|
||||||
|
CFGExtrasRescaleCFGSimpleNode,
|
||||||
|
CustomCFGKeyframeFromListNode,
|
||||||
|
CustomCFGKeyframeInterpolationNode,
|
||||||
|
CustomCFGKeyframeNode,
|
||||||
|
CustomCFGKeyframeSimpleNode,
|
||||||
|
CustomCFGNode,
|
||||||
|
CustomCFGSimpleNode,
|
||||||
|
FreeInitOptionsNode,
|
||||||
|
IterationOptionsNode,
|
||||||
|
NoisedImageInjectionNode,
|
||||||
|
NoisedImageInjectOptionsNode,
|
||||||
|
NoiseLayerAddNode,
|
||||||
|
NoiseLayerAddWeightedNode,
|
||||||
|
NoiseLayerNormalizedSumNode,
|
||||||
|
NoiseLayerReplaceNode,
|
||||||
|
SampleSettingsNode,
|
||||||
|
)
|
||||||
|
from .nodes_scheduling import (
|
||||||
|
AddValuesReplaceNode,
|
||||||
|
ConditionExtractionNode,
|
||||||
|
FloatToFloatsNode,
|
||||||
|
PromptSchedulingLatentsNode,
|
||||||
|
PromptSchedulingNode,
|
||||||
|
ValueSchedulingLatentsNode,
|
||||||
|
ValueSchedulingNode,
|
||||||
|
)
|
||||||
|
from .nodes_sigma_schedule import (
|
||||||
|
InterpolatedWeightedAverageSigmaScheduleNode,
|
||||||
|
RawSigmaScheduleNode,
|
||||||
|
SigmaScheduleNode,
|
||||||
|
SigmaScheduleToSigmasNode,
|
||||||
|
SplitAndCombineSigmaScheduleNode,
|
||||||
|
WeightedAverageSigmaScheduleNode,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
NODE_CLASS_MAPPINGS = {
|
class AnimateDiffExtension(ComfyExtension):
|
||||||
# Unencapsulated
|
async def get_node_list(self) -> list[type[io.ComfyNode]]:
|
||||||
"ADE_AnimateDiffLoRALoader": AnimateDiffLoraLoader,
|
return [
|
||||||
"ADE_AnimateDiffSamplingSettings": SampleSettingsNode,
|
AnimateDiffLoraLoader,
|
||||||
"ADE_AnimateDiffKeyframe": ADKeyframeNode,
|
SampleSettingsNode,
|
||||||
# Multival Nodes
|
ADKeyframeNode,
|
||||||
"ADE_MultivalDynamic": MultivalDynamicNode,
|
MultivalDynamicNode,
|
||||||
"ADE_MultivalDynamicFloatInput": MultivalDynamicFloatInputNode,
|
MultivalDynamicFloatInputNode,
|
||||||
"ADE_MultivalDynamicFloats": MultivalDynamicFloatsNode,
|
MultivalDynamicFloatsNode,
|
||||||
"ADE_MultivalScaledMask": MultivalScaledMaskNode,
|
MultivalScaledMaskNode,
|
||||||
"ADE_MultivalConvertToMask": MultivalConvertToMaskNode,
|
MultivalConvertToMaskNode,
|
||||||
###############################################################################
|
StandardStaticContextOptionsNode,
|
||||||
#------------------------------------------------------------------------------
|
StandardUniformContextOptionsNode,
|
||||||
# Context Opts
|
LoopedUniformContextOptionsNode,
|
||||||
"ADE_StandardStaticContextOptions": StandardStaticContextOptionsNode,
|
ViewAsContextOptionsNode,
|
||||||
"ADE_StandardUniformContextOptions": StandardUniformContextOptionsNode,
|
BatchedContextOptionsNode,
|
||||||
"ADE_LoopedUniformContextOptions": LoopedUniformContextOptionsNode,
|
LegacyLoopedUniformContextOptionsNode,
|
||||||
"ADE_ViewsOnlyContextOptions": ViewAsContextOptionsNode,
|
VisualizeContextOptionsK,
|
||||||
"ADE_BatchedContextOptions": BatchedContextOptionsNode,
|
VisualizeContextOptionsKAdv,
|
||||||
"ADE_AnimateDiffUniformContextOptions": LegacyLoopedUniformContextOptionsNode, # Legacy/Deprecated
|
VisualizeContextOptionsSCustom,
|
||||||
"ADE_VisualizeContextOptionsK": VisualizeContextOptionsK,
|
StandardStaticViewOptionsNode,
|
||||||
"ADE_VisualizeContextOptionsKAdv": VisualizeContextOptionsKAdv,
|
StandardUniformViewOptionsNode,
|
||||||
"ADE_VisualizeContextOptionsSCustom": VisualizeContextOptionsSCustom,
|
LoopedUniformViewOptionsNode,
|
||||||
# View Opts
|
SetContextExtrasOnContextOptions,
|
||||||
"ADE_StandardStaticViewOptions": StandardStaticViewOptionsNode,
|
ContextExtras_ContextRef,
|
||||||
"ADE_StandardUniformViewOptions": StandardUniformViewOptionsNode,
|
ContextRef_ModeFirst,
|
||||||
"ADE_LoopedUniformViewOptions": LoopedUniformViewOptionsNode,
|
ContextRef_ModeSliding,
|
||||||
# Context Extras
|
ContextRef_ModeIndexes,
|
||||||
"ADE_ContextExtras_Set": SetContextExtrasOnContextOptions,
|
ContextRef_TuneAttn,
|
||||||
"ADE_ContextExtras_ContextRef": ContextExtras_ContextRef,
|
ContextRef_TuneAttnAdain,
|
||||||
"ADE_ContextExtras_ContextRef_ModeFirst": ContextRef_ModeFirst,
|
ContextRef_KeyframeMultivalNode,
|
||||||
"ADE_ContextExtras_ContextRef_ModeSliding": ContextRef_ModeSliding,
|
ContextRef_KeyframeInterpolationNode,
|
||||||
"ADE_ContextExtras_ContextRef_ModeIndexes": ContextRef_ModeIndexes,
|
ContextRef_KeyframeFromListNode,
|
||||||
"ADE_ContextExtras_ContextRef_TuneAttn": ContextRef_TuneAttn,
|
ContextExtras_NaiveReuse,
|
||||||
"ADE_ContextExtras_ContextRef_TuneAttnAdain": ContextRef_TuneAttnAdain,
|
NaiveReuse_KeyframeMultivalNode,
|
||||||
"ADE_ContextExtras_ContextRef_Keyframe": ContextRef_KeyframeMultivalNode,
|
NaiveReuse_KeyframeInterpolationNode,
|
||||||
"ADE_ContextExtras_ContextRef_KeyframeInterpolation": ContextRef_KeyframeInterpolationNode,
|
NaiveReuse_KeyframeFromListNode,
|
||||||
"ADE_ContextExtras_ContextRef_KeyframeFromList": ContextRef_KeyframeFromListNode,
|
IterationOptionsNode,
|
||||||
"ADE_ContextExtras_NaiveReuse": ContextExtras_NaiveReuse,
|
FreeInitOptionsNode,
|
||||||
"ADE_ContextExtras_NaiveReuse_Keyframe": NaiveReuse_KeyframeMultivalNode,
|
MaskableLoraLoaderDEPR,
|
||||||
"ADE_ContextExtras_NaiveReuse_KeyframeInterpolation": NaiveReuse_KeyframeInterpolationNode,
|
MaskableLoraLoaderModelOnlyDEPR,
|
||||||
"ADE_ContextExtras_NaiveReuse_KeyframeFromList": NaiveReuse_KeyframeFromListNode,
|
MaskableSDModelLoaderDEPR,
|
||||||
#------------------------------------------------------------------------------
|
MaskableSDModelLoaderModelOnlyDEPR,
|
||||||
###############################################################################
|
CombineLoraHooksDEPR,
|
||||||
# Iteration Opts
|
CombineLoraHookFourOptionalDEPR,
|
||||||
"ADE_IterationOptsDefault": IterationOptionsNode,
|
CombineLoraHookEightOptionalDEPR,
|
||||||
"ADE_IterationOptsFreeInit": FreeInitOptionsNode,
|
SetLoraHookKeyframesDEPR,
|
||||||
# Conditioning
|
SetClipLoraHookDEPR,
|
||||||
# Conditioning (DEPRECATED)
|
CreateLoraHookKeyframeDEPR,
|
||||||
"ADE_RegisterLoraHook": MaskableLoraLoaderDEPR,
|
CreateLoraHookKeyframeInterpolationDEPR,
|
||||||
"ADE_RegisterLoraHookModelOnly": MaskableLoraLoaderModelOnlyDEPR,
|
CreateLoraHookKeyframeFromStrengthListDEPR,
|
||||||
"ADE_RegisterModelAsLoraHook": MaskableSDModelLoaderDEPR,
|
SetModelLoraHookDEPR,
|
||||||
"ADE_RegisterModelAsLoraHookModelOnly": MaskableSDModelLoaderModelOnlyDEPR,
|
PairedConditioningSetMaskHookedDEPR,
|
||||||
"ADE_CombineLoraHooks": CombineLoraHooksDEPR,
|
ConditioningSetMaskHookedDEPR,
|
||||||
"ADE_CombineLoraHooksFour": CombineLoraHookFourOptionalDEPR,
|
PairedConditioningSetMaskAndCombineHookedDEPR,
|
||||||
"ADE_CombineLoraHooksEight": CombineLoraHookEightOptionalDEPR,
|
ConditioningSetMaskAndCombineHookedDEPR,
|
||||||
"ADE_SetLoraHookKeyframe": SetLoraHookKeyframesDEPR,
|
PairedConditioningSetUnmaskedAndCombineHookedDEPR,
|
||||||
"ADE_AttachLoraHookToCLIP": SetClipLoraHookDEPR,
|
ConditioningSetUnmaskedAndCombineHookedDEPR,
|
||||||
"ADE_LoraHookKeyframe": CreateLoraHookKeyframeDEPR,
|
PairedConditioningCombineDEPR,
|
||||||
"ADE_LoraHookKeyframeInterpolation": CreateLoraHookKeyframeInterpolationDEPR,
|
ConditioningCombineDEPR,
|
||||||
"ADE_LoraHookKeyframeFromStrengthList": CreateLoraHookKeyframeFromStrengthListDEPR,
|
ConditioningTimestepsNodeDEPR,
|
||||||
"ADE_AttachLoraHookToConditioning": SetModelLoraHookDEPR,
|
NoiseLayerAddNode,
|
||||||
"ADE_PairedConditioningSetMask": PairedConditioningSetMaskHookedDEPR,
|
NoiseLayerAddWeightedNode,
|
||||||
"ADE_ConditioningSetMask": ConditioningSetMaskHookedDEPR,
|
NoiseLayerNormalizedSumNode,
|
||||||
"ADE_PairedConditioningSetMaskAndCombine": PairedConditioningSetMaskAndCombineHookedDEPR,
|
NoiseLayerReplaceNode,
|
||||||
"ADE_ConditioningSetMaskAndCombine": ConditioningSetMaskAndCombineHookedDEPR,
|
AnimateDiffSettingsNode,
|
||||||
"ADE_PairedConditioningSetUnmaskedAndCombine": PairedConditioningSetUnmaskedAndCombineHookedDEPR,
|
SweetspotStretchPENode,
|
||||||
"ADE_ConditioningSetUnmaskedAndCombine": ConditioningSetUnmaskedAndCombineHookedDEPR,
|
FullStretchPENode,
|
||||||
"ADE_PairedConditioningCombine": PairedConditioningCombineDEPR,
|
ManualAdjustPENode,
|
||||||
"ADE_ConditioningCombine": ConditioningCombineDEPR,
|
WeightAdjustAllAddNode,
|
||||||
"ADE_TimestepsConditioning": ConditioningTimestepsNodeDEPR,
|
WeightAdjustAllMultNode,
|
||||||
# Noise Layer Nodes
|
WeightAdjustIndivAddNode,
|
||||||
"ADE_NoiseLayerAdd": NoiseLayerAddNode,
|
WeightAdjustIndivMultNode,
|
||||||
"ADE_NoiseLayerAddWeighted": NoiseLayerAddWeightedNode,
|
WeightAdjustIndivAttnAddNode,
|
||||||
"ADE_NoiseLayerNormalizedSum": NoiseLayerNormalizedSumNode,
|
WeightAdjustIndivAttnMultNode,
|
||||||
"ADE_NoiseLayerReplace": NoiseLayerReplaceNode,
|
CustomCFGSimpleNode,
|
||||||
# AnimateDiff Settings
|
CustomCFGNode,
|
||||||
"ADE_AnimateDiffSettings": AnimateDiffSettingsNode,
|
CustomCFGKeyframeSimpleNode,
|
||||||
"ADE_AdjustPESweetspotStretch": SweetspotStretchPENode,
|
CustomCFGKeyframeNode,
|
||||||
"ADE_AdjustPEFullStretch": FullStretchPENode,
|
CustomCFGKeyframeInterpolationNode,
|
||||||
"ADE_AdjustPEManual": ManualAdjustPENode,
|
CustomCFGKeyframeFromListNode,
|
||||||
"ADE_AdjustWeightAllAdd": WeightAdjustAllAddNode,
|
CFGExtrasPAGSimpleNode,
|
||||||
"ADE_AdjustWeightAllMult": WeightAdjustAllMultNode,
|
CFGExtrasPAGNode,
|
||||||
"ADE_AdjustWeightIndivAdd": WeightAdjustIndivAddNode,
|
CFGExtrasRescaleCFGSimpleNode,
|
||||||
"ADE_AdjustWeightIndivMult": WeightAdjustIndivMultNode,
|
CFGExtrasRescaleCFGNode,
|
||||||
"ADE_AdjustWeightIndivAttnAdd": WeightAdjustIndivAttnAddNode,
|
SigmaScheduleNode,
|
||||||
"ADE_AdjustWeightIndivAttnMult": WeightAdjustIndivAttnMultNode,
|
RawSigmaScheduleNode,
|
||||||
# Sample Settings
|
WeightedAverageSigmaScheduleNode,
|
||||||
"ADE_CustomCFGSimple": CustomCFGSimpleNode,
|
InterpolatedWeightedAverageSigmaScheduleNode,
|
||||||
"ADE_CustomCFG": CustomCFGNode,
|
SplitAndCombineSigmaScheduleNode,
|
||||||
"ADE_CustomCFGKeyframeSimple": CustomCFGKeyframeSimpleNode,
|
SigmaScheduleToSigmasNode,
|
||||||
"ADE_CustomCFGKeyframe": CustomCFGKeyframeNode,
|
NoisedImageInjectionNode,
|
||||||
"ADE_CustomCFGKeyframeInterpolation": CustomCFGKeyframeInterpolationNode,
|
NoisedImageInjectOptionsNode,
|
||||||
"ADE_CustomCFGKeyframeFromList": CustomCFGKeyframeFromListNode,
|
AncestralOptionsNode,
|
||||||
"ADE_CFGExtrasPAGSimple": CFGExtrasPAGSimpleNode,
|
PromptSchedulingNode,
|
||||||
"ADE_CFGExtrasPAG": CFGExtrasPAGNode,
|
PromptSchedulingLatentsNode,
|
||||||
"ADE_CFGExtrasRescaleCFGSimple": CFGExtrasRescaleCFGSimpleNode,
|
ValueSchedulingNode,
|
||||||
"ADE_CFGExtrasRescaleCFG": CFGExtrasRescaleCFGNode,
|
ValueSchedulingLatentsNode,
|
||||||
"ADE_SigmaSchedule": SigmaScheduleNode,
|
ConditionExtractionNode,
|
||||||
"ADE_RawSigmaSchedule": RawSigmaScheduleNode,
|
AddValuesReplaceNode,
|
||||||
"ADE_SigmaScheduleWeightedAverage": WeightedAverageSigmaScheduleNode,
|
FloatToFloatsNode,
|
||||||
"ADE_SigmaScheduleWeightedAverageInterp": InterpolatedWeightedAverageSigmaScheduleNode,
|
ADBlockComboNode,
|
||||||
"ADE_SigmaScheduleSplitAndCombine": SplitAndCombineSigmaScheduleNode,
|
ADBlockIndivNode,
|
||||||
"ADE_SigmaScheduleToSigmas": SigmaScheduleToSigmasNode,
|
PerBlockHighLevelNode,
|
||||||
"ADE_NoisedImageInjection": NoisedImageInjectionNode,
|
PerBlock_SD15_MidLevelNode,
|
||||||
"ADE_NoisedImageInjectOptions": NoisedImageInjectOptionsNode,
|
PerBlock_SD15_LowLevelNode,
|
||||||
"ADE_AncestralOptions": AncestralOptionsNode,
|
PerBlock_SD15_FromFloatsNode,
|
||||||
#"ADE_NoiseCalibration": NoiseCalibrationNode,
|
PerBlock_SDXL_MidLevelNode,
|
||||||
# Scheduling
|
PerBlock_SDXL_LowLevelNode,
|
||||||
PromptSchedulingNode.NodeID: PromptSchedulingNode,
|
PerBlock_SDXL_FromFloatsNode,
|
||||||
PromptSchedulingLatentsNode.NodeID: PromptSchedulingLatentsNode,
|
AnimateDiffUnload,
|
||||||
ValueSchedulingNode.NodeID: ValueSchedulingNode,
|
EmptyLatentImageLarge,
|
||||||
ValueSchedulingLatentsNode.NodeID: ValueSchedulingLatentsNode,
|
CheckpointLoaderSimpleWithNoiseSelect,
|
||||||
ConditionExtractionNode.NodeID: ConditionExtractionNode,
|
PerturbedAttentionGuidanceMultival,
|
||||||
AddValuesReplaceNode.NodeID: AddValuesReplaceNode,
|
RescaleCFGMultival,
|
||||||
FloatToFloatsNode.NodeID: FloatToFloatsNode,
|
AnimateDiffLoaderGen1,
|
||||||
# Per-Block
|
UseEvolvedSamplingNode,
|
||||||
ADBlockComboNode.NodeID: ADBlockComboNode,
|
ApplyAnimateDiffModelBasicNode,
|
||||||
ADBlockIndivNode.NodeID: ADBlockIndivNode,
|
ApplyAnimateDiffModelNode,
|
||||||
PerBlockHighLevelNode.NodeID: PerBlockHighLevelNode,
|
LoadAnimateDiffModelNode,
|
||||||
PerBlock_SD15_MidLevelNode.NodeID: PerBlock_SD15_MidLevelNode,
|
ApplyAnimateLCMI2VModel,
|
||||||
PerBlock_SD15_LowLevelNode.NodeID: PerBlock_SD15_LowLevelNode,
|
LoadAnimateLCMI2VModelNode,
|
||||||
PerBlock_SD15_FromFloatsNode.NodeID: PerBlock_SD15_FromFloatsNode,
|
UpscaleAndVaeEncode,
|
||||||
PerBlock_SDXL_MidLevelNode.NodeID: PerBlock_SDXL_MidLevelNode,
|
LoadAnimateDiffAndInjectI2VNode,
|
||||||
PerBlock_SDXL_LowLevelNode.NodeID: PerBlock_SDXL_LowLevelNode,
|
ApplyAnimateDiffWithCameraCtrl,
|
||||||
PerBlock_SDXL_FromFloatsNode.NodeID: PerBlock_SDXL_FromFloatsNode,
|
LoadAnimateDiffModelWithCameraCtrl,
|
||||||
# Extras Nodes
|
CameraCtrlADKeyframeNode,
|
||||||
"ADE_AnimateDiffUnload": AnimateDiffUnload,
|
LoadCameraPosesFromFile,
|
||||||
"ADE_EmptyLatentImageLarge": EmptyLatentImageLarge,
|
LoadCameraPosesFromPath,
|
||||||
"CheckpointLoaderSimpleWithNoiseSelect": CheckpointLoaderSimpleWithNoiseSelect,
|
CameraCtrlPoseBasic,
|
||||||
"ADE_PerturbedAttentionGuidanceMultival": PerturbedAttentionGuidanceMultival,
|
CameraCtrlPoseCombo,
|
||||||
"ADE_RescaleCFGMultival": RescaleCFGMultival,
|
CameraCtrlPoseAdvanced,
|
||||||
# Gen1 Nodes
|
CameraCtrlManualAppendPose,
|
||||||
"ADE_AnimateDiffLoaderGen1": AnimateDiffLoaderGen1,
|
CameraCtrlReplaceCameraParameters,
|
||||||
# Gen2 Nodes
|
CameraCtrlSetOriginalAspectRatio,
|
||||||
"ADE_UseEvolvedSampling": UseEvolvedSamplingNode,
|
ApplyAnimateDiffPIAModel,
|
||||||
"ADE_ApplyAnimateDiffModelSimple": ApplyAnimateDiffModelBasicNode,
|
InputPIA_MultivalNode,
|
||||||
"ADE_ApplyAnimateDiffModel": ApplyAnimateDiffModelNode,
|
InputPIA_PaperPresetsNode,
|
||||||
"ADE_LoadAnimateDiffModel": LoadAnimateDiffModelNode,
|
PIA_ADKeyframeNode,
|
||||||
# AnimateLCM-I2V Nodes
|
LoadAnimateDiffAndInjectPIANode,
|
||||||
"ADE_ApplyAnimateLCMI2VModel": ApplyAnimateLCMI2VModel,
|
LegacyAnimateDiffLoaderWithContextDEPR,
|
||||||
"ADE_LoadAnimateLCMI2VModel": LoadAnimateLCMI2VModelNode,
|
AnimateDiffLoaderDEPR,
|
||||||
"ADE_UpscaleAndVAEEncode": UpscaleAndVaeEncode,
|
AnimateDiffLoaderAdvancedDEPR,
|
||||||
"ADE_InjectI2VIntoAnimateDiffModel": LoadAnimateDiffAndInjectI2VNode,
|
AnimateDiffCombineDEPR,
|
||||||
# MotionCtrl Nodes
|
AnimateDiffModelSettingsDEPR,
|
||||||
#LoadMotionCtrlCMCM.NodeID: LoadMotionCtrlCMCM,
|
AnimateDiffModelSettingsSimpleDEPR,
|
||||||
#LoadMotionCtrlOMCM.NodeID: LoadMotionCtrlOMCM,
|
AnimateDiffModelSettingsAdvancedDEPR,
|
||||||
#ApplyAnimateDiffMotionCtrlModel.NodeID: ApplyAnimateDiffMotionCtrlModel,
|
AnimateDiffModelSettingsAdvancedAttnStrengthsDEPR,
|
||||||
#LoadMotionCtrlCameraPosesFromFile.NodeID: LoadMotionCtrlCameraPosesFromFile,
|
]
|
||||||
# CameraCtrl Nodes
|
|
||||||
"ADE_ApplyAnimateDiffModelWithCameraCtrl": ApplyAnimateDiffWithCameraCtrl,
|
|
||||||
"ADE_LoadAnimateDiffModelWithCameraCtrl": LoadAnimateDiffModelWithCameraCtrl,
|
|
||||||
"ADE_CameraCtrlAnimateDiffKeyframe": CameraCtrlADKeyframeNode,
|
|
||||||
"ADE_LoadCameraPoses": LoadCameraPosesFromFile,
|
|
||||||
"ADE_LoadCameraPosesFromPath": LoadCameraPosesFromPath,
|
|
||||||
"ADE_CameraPoseBasic": CameraCtrlPoseBasic,
|
|
||||||
"ADE_CameraPoseCombo": CameraCtrlPoseCombo,
|
|
||||||
"ADE_CameraPoseAdvanced": CameraCtrlPoseAdvanced,
|
|
||||||
"ADE_CameraManualPoseAppend": CameraCtrlManualAppendPose,
|
|
||||||
"ADE_ReplaceCameraParameters": CameraCtrlReplaceCameraParameters,
|
|
||||||
"ADE_ReplaceOriginalPoseAspectRatio": CameraCtrlSetOriginalAspectRatio,
|
|
||||||
# PIA Nodes
|
|
||||||
"ADE_ApplyAnimateDiffModelWithPIA": ApplyAnimateDiffPIAModel,
|
|
||||||
"ADE_InputPIA_Multival": InputPIA_MultivalNode,
|
|
||||||
"ADE_InputPIA_PaperPresets": InputPIA_PaperPresetsNode,
|
|
||||||
"ADE_PIA_AnimateDiffKeyframe": PIA_ADKeyframeNode,
|
|
||||||
"ADE_InjectPIAIntoAnimateDiffModel": LoadAnimateDiffAndInjectPIANode,
|
|
||||||
# FancyVideo
|
|
||||||
#ApplyAnimateDiffFancyVideo.NodeID: ApplyAnimateDiffFancyVideo,
|
|
||||||
# HelloMeme
|
|
||||||
#TestHMRefNetInjection.NodeID: TestHMRefNetInjection,
|
|
||||||
# Deprecated Nodes
|
|
||||||
"ADE_AnimateDiffLoaderWithContext": LegacyAnimateDiffLoaderWithContextDEPR,
|
|
||||||
"AnimateDiffLoaderV1": AnimateDiffLoaderDEPR,
|
|
||||||
"ADE_AnimateDiffLoaderV1Advanced": AnimateDiffLoaderAdvancedDEPR,
|
|
||||||
"ADE_AnimateDiffCombine": AnimateDiffCombineDEPR,
|
|
||||||
"ADE_AnimateDiffModelSettings_Release": AnimateDiffModelSettingsDEPR,
|
|
||||||
"ADE_AnimateDiffModelSettingsSimple": AnimateDiffModelSettingsSimpleDEPR,
|
|
||||||
"ADE_AnimateDiffModelSettings": AnimateDiffModelSettingsAdvancedDEPR,
|
|
||||||
"ADE_AnimateDiffModelSettingsAdvancedAttnStrengths": AnimateDiffModelSettingsAdvancedAttnStrengthsDEPR,
|
|
||||||
}
|
|
||||||
NODE_DISPLAY_NAME_MAPPINGS = {
|
|
||||||
# Unencapsulated
|
|
||||||
"ADE_AnimateDiffLoRALoader": "Load AnimateDiff LoRA 🎭🅐🅓",
|
|
||||||
"ADE_AnimateDiffSamplingSettings": "Sample Settings 🎭🅐🅓",
|
|
||||||
"ADE_AnimateDiffKeyframe": "AnimateDiff Keyframe 🎭🅐🅓",
|
|
||||||
# Multival Nodes
|
|
||||||
"ADE_MultivalDynamic": "Multival 🎭🅐🅓",
|
|
||||||
"ADE_MultivalDynamicFloatInput": "Multival [Float List] 🎭🅐🅓",
|
|
||||||
"ADE_MultivalDynamicFloats": "Multival [Floats] 🎭🅐🅓",
|
|
||||||
"ADE_MultivalScaledMask": "Multival Scaled Mask 🎭🅐🅓",
|
|
||||||
"ADE_MultivalConvertToMask": "Multival to Mask 🎭🅐🅓",
|
|
||||||
###############################################################################
|
|
||||||
#------------------------------------------------------------------------------
|
|
||||||
# Context Opts
|
|
||||||
"ADE_StandardStaticContextOptions": "Context Options◆Standard Static 🎭🅐🅓",
|
|
||||||
"ADE_StandardUniformContextOptions": "Context Options◆Standard Uniform 🎭🅐🅓",
|
|
||||||
"ADE_LoopedUniformContextOptions": "Context Options◆Looped Uniform 🎭🅐🅓",
|
|
||||||
"ADE_ViewsOnlyContextOptions": "Context Options◆Views Only [VRAM⇈] 🎭🅐🅓",
|
|
||||||
"ADE_BatchedContextOptions": "Context Options◆Batched [Non-AD] 🎭🅐🅓",
|
|
||||||
"ADE_AnimateDiffUniformContextOptions": "Context Options◆Looped Uniform 🎭🅐🅓", # Legacy/Deprecated
|
|
||||||
"ADE_VisualizeContextOptionsK": "Visualize Context Options (K.) 🎭🅐🅓",
|
|
||||||
"ADE_VisualizeContextOptionsKAdv": "Visualize Context Options (K.Adv.) 🎭🅐🅓",
|
|
||||||
"ADE_VisualizeContextOptionsSCustom": "Visualize Context Options (S.Cus.) 🎭🅐🅓",
|
|
||||||
# View Opts
|
|
||||||
"ADE_StandardStaticViewOptions": "View Options◆Standard Static 🎭🅐🅓",
|
|
||||||
"ADE_StandardUniformViewOptions": "View Options◆Standard Uniform 🎭🅐🅓",
|
|
||||||
"ADE_LoopedUniformViewOptions": "View Options◆Looped Uniform 🎭🅐🅓",
|
|
||||||
# Context Extras
|
|
||||||
"ADE_ContextExtras_Set": "Set Context Extras 🎭🅐🅓",
|
|
||||||
"ADE_ContextExtras_ContextRef": "Context Extras◆ContextRef 🎭🅐🅓",
|
|
||||||
"ADE_ContextExtras_ContextRef_ModeFirst": "ContextRef Mode◆First 🎭🅐🅓",
|
|
||||||
"ADE_ContextExtras_ContextRef_ModeSliding": "ContextRef Mode◆Sliding 🎭🅐🅓",
|
|
||||||
"ADE_ContextExtras_ContextRef_ModeIndexes": "ContextRef Mode◆Indexes 🎭🅐🅓",
|
|
||||||
"ADE_ContextExtras_ContextRef_TuneAttn": "ContextRef Tune◆Attn 🎭🅐🅓",
|
|
||||||
"ADE_ContextExtras_ContextRef_TuneAttnAdain": "ContextRef Tune◆Attn+Adain 🎭🅐🅓",
|
|
||||||
"ADE_ContextExtras_ContextRef_Keyframe": "ContextRef Keyframe 🎭🅐🅓",
|
|
||||||
"ADE_ContextExtras_ContextRef_KeyframeInterpolation": "ContextRef Keyframes Interp. 🎭🅐🅓",
|
|
||||||
"ADE_ContextExtras_ContextRef_KeyframeFromList": "ContextRef Keyframes From List 🎭🅐🅓",
|
|
||||||
"ADE_ContextExtras_NaiveReuse": "Context Extras◆NaiveReuse 🎭🅐🅓",
|
|
||||||
"ADE_ContextExtras_NaiveReuse_Keyframe": "NaiveReuse Keyframe 🎭🅐🅓",
|
|
||||||
"ADE_ContextExtras_NaiveReuse_KeyframeInterpolation": "NaiveReuse Keyframes Interp. 🎭🅐🅓",
|
|
||||||
"ADE_ContextExtras_NaiveReuse_KeyframeFromList": "NaiveReuse Keyframes From List 🎭🅐🅓",
|
|
||||||
#------------------------------------------------------------------------------
|
|
||||||
###############################################################################
|
|
||||||
# Iteration Opts
|
|
||||||
"ADE_IterationOptsDefault": "Default Iteration Options 🎭🅐🅓",
|
|
||||||
"ADE_IterationOptsFreeInit": "FreeInit Iteration Options 🎭🅐🅓",
|
|
||||||
# Conditioning
|
|
||||||
# Conditioning (DEPRECATED)
|
|
||||||
"ADE_RegisterLoraHook": "Register LoRA Hook 🎭🅐🅓",
|
|
||||||
"ADE_RegisterLoraHookModelOnly": "Register LoRA Hook (Model Only) 🎭🅐🅓",
|
|
||||||
"ADE_RegisterModelAsLoraHook": "Register Model as LoRA Hook 🎭🅐🅓",
|
|
||||||
"ADE_RegisterModelAsLoraHookModelOnly": "Register Model as LoRA Hook (MO) 🎭🅐🅓",
|
|
||||||
"ADE_CombineLoraHooks": "Combine LoRA Hooks [2] 🎭🅐🅓",
|
|
||||||
"ADE_CombineLoraHooksFour": "Combine LoRA Hooks [4] 🎭🅐🅓",
|
|
||||||
"ADE_CombineLoraHooksEight": "Combine LoRA Hooks [8] 🎭🅐🅓",
|
|
||||||
"ADE_SetLoraHookKeyframe": "Set LoRA Hook Keyframes 🎭🅐🅓",
|
|
||||||
"ADE_AttachLoraHookToCLIP": "Set CLIP LoRA Hook 🎭🅐🅓",
|
|
||||||
"ADE_LoraHookKeyframe": "LoRA Hook Keyframe 🎭🅐🅓",
|
|
||||||
"ADE_LoraHookKeyframeInterpolation": "LoRA Hook Keyframes Interp. 🎭🅐🅓",
|
|
||||||
"ADE_LoraHookKeyframeFromStrengthList": "LoRA Hook Keyframes From List 🎭🅐🅓",
|
|
||||||
"ADE_AttachLoraHookToConditioning": "Set Model LoRA Hook 🎭🅐🅓",
|
|
||||||
"ADE_PairedConditioningSetMask": "Set Props on Conds 🎭🅐🅓",
|
|
||||||
"ADE_ConditioningSetMask": "Set Props on Cond 🎭🅐🅓",
|
|
||||||
"ADE_PairedConditioningSetMaskAndCombine": "Set Props and Combine Conds 🎭🅐🅓",
|
|
||||||
"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] 🎭🅐🅓",
|
|
||||||
"ADE_NoiseLayerAddWeighted": "Noise Layer [Add Weighted] 🎭🅐🅓",
|
|
||||||
"ADE_NoiseLayerNormalizedSum": "Noise Layer [Normalized Sum] 🎭🅐🅓",
|
|
||||||
"ADE_NoiseLayerReplace": "Noise Layer [Replace] 🎭🅐🅓",
|
|
||||||
# AnimateDiff Settings
|
|
||||||
"ADE_AnimateDiffSettings": "AnimateDiff Settings 🎭🅐🅓",
|
|
||||||
"ADE_AdjustPESweetspotStretch": "Adjust PE [Sweetspot] 🎭🅐🅓",
|
|
||||||
"ADE_AdjustPEFullStretch": "Adjust PE [Full Stretch] 🎭🅐🅓",
|
|
||||||
"ADE_AdjustPEManual": "Adjust PE [Manual] 🎭🅐🅓",
|
|
||||||
"ADE_AdjustWeightAllAdd": "Adjust Weight [All◆Add] 🎭🅐🅓",
|
|
||||||
"ADE_AdjustWeightAllMult": "Adjust Weight [All◆Mult] 🎭🅐🅓",
|
|
||||||
"ADE_AdjustWeightIndivAdd": "Adjust Weight [Indiv◆Add] 🎭🅐🅓",
|
|
||||||
"ADE_AdjustWeightIndivMult": "Adjust Weight [Indiv◆Mult] 🎭🅐🅓",
|
|
||||||
"ADE_AdjustWeightIndivAttnAdd": "Adjust Weight [Indiv-Attn◆Add] 🎭🅐🅓",
|
|
||||||
"ADE_AdjustWeightIndivAttnMult": "Adjust Weight [Indiv-Attn◆Mult] 🎭🅐🅓",
|
|
||||||
# Sample Settings
|
|
||||||
"ADE_CustomCFGSimple": "Custom CFG 🎭🅐🅓",
|
|
||||||
"ADE_CustomCFG": "Custom CFG [Multival] 🎭🅐🅓",
|
|
||||||
"ADE_CustomCFGKeyframeSimple": "Custom CFG Keyframe 🎭🅐🅓",
|
|
||||||
"ADE_CustomCFGKeyframe": "Custom CFG Keyframe [Multival] 🎭🅐🅓",
|
|
||||||
"ADE_CustomCFGKeyframeInterpolation": "Custom CFG Keyframes Interp. 🎭🅐🅓",
|
|
||||||
"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 🎭🅐🅓",
|
|
||||||
"ADE_SigmaScheduleWeightedAverageInterp": "Sigma Schedule Interp. Mean 🎭🅐🅓",
|
|
||||||
"ADE_SigmaScheduleSplitAndCombine": "Sigma Schedule Split Combine 🎭🅐🅓",
|
|
||||||
"ADE_SigmaScheduleToSigmas": "Sigma Schedule To Sigmas 🎭🅐🅓",
|
|
||||||
"ADE_NoisedImageInjection": "Image Injection 🎭🅐🅓",
|
|
||||||
"ADE_NoisedImageInjectOptions": "Image Injection Options 🎭🅐🅓",
|
|
||||||
"ADE_NoiseCalibration": "Noise Calibration 🎭🅐🅓",
|
|
||||||
"ADE_AncestralOptions": "Ancestral Options 🎭🅐🅓",
|
|
||||||
# Scheduling
|
|
||||||
PromptSchedulingNode.NodeID: PromptSchedulingNode.NodeName,
|
|
||||||
PromptSchedulingLatentsNode.NodeID: PromptSchedulingLatentsNode.NodeName,
|
|
||||||
ValueSchedulingNode.NodeID: ValueSchedulingNode.NodeName,
|
|
||||||
ValueSchedulingLatentsNode.NodeID: ValueSchedulingLatentsNode.NodeName,
|
|
||||||
ConditionExtractionNode.NodeID: ConditionExtractionNode.NodeName,
|
|
||||||
AddValuesReplaceNode.NodeID: AddValuesReplaceNode.NodeName,
|
|
||||||
FloatToFloatsNode.NodeID:FloatToFloatsNode.NodeName,
|
|
||||||
# Per-Block
|
|
||||||
ADBlockComboNode.NodeID: ADBlockComboNode.NodeName,
|
|
||||||
ADBlockIndivNode.NodeID: ADBlockIndivNode.NodeName,
|
|
||||||
PerBlockHighLevelNode.NodeID: PerBlockHighLevelNode.NodeName,
|
|
||||||
PerBlock_SD15_MidLevelNode.NodeID: PerBlock_SD15_MidLevelNode.NodeName,
|
|
||||||
PerBlock_SD15_LowLevelNode.NodeID: PerBlock_SD15_LowLevelNode.NodeName,
|
|
||||||
PerBlock_SD15_FromFloatsNode.NodeID: PerBlock_SD15_FromFloatsNode.NodeName,
|
|
||||||
PerBlock_SDXL_MidLevelNode.NodeID: PerBlock_SDXL_MidLevelNode.NodeName,
|
|
||||||
PerBlock_SDXL_LowLevelNode.NodeID: PerBlock_SDXL_LowLevelNode.NodeName,
|
|
||||||
PerBlock_SDXL_FromFloatsNode.NodeID: PerBlock_SDXL_FromFloatsNode.NodeName,
|
|
||||||
# Extras Nodes
|
|
||||||
"ADE_AnimateDiffUnload": "AnimateDiff Unload 🎭🅐🅓",
|
|
||||||
"ADE_EmptyLatentImageLarge": "Empty Latent Image (Big Batch) 🎭🅐🅓",
|
|
||||||
"CheckpointLoaderSimpleWithNoiseSelect": "Load Checkpoint w/ Noise Select 🎭🅐🅓",
|
|
||||||
"ADE_PerturbedAttentionGuidanceMultival": "PerturbedAttnGuide [Multival] 🎭🅐🅓",
|
|
||||||
"ADE_RescaleCFGMultival": "RescaleCFG [Multival] 🎭🅐🅓",
|
|
||||||
# Gen1 Nodes
|
|
||||||
"ADE_AnimateDiffLoaderGen1": "AnimateDiff Loader 🎭🅐🅓①",
|
|
||||||
# Gen2 Nodes
|
|
||||||
"ADE_UseEvolvedSampling": "Use Evolved Sampling 🎭🅐🅓②",
|
|
||||||
"ADE_ApplyAnimateDiffModelSimple": "Apply AnimateDiff Model 🎭🅐🅓②",
|
|
||||||
"ADE_ApplyAnimateDiffModel": "Apply AnimateDiff Model (Adv.) 🎭🅐🅓②",
|
|
||||||
"ADE_LoadAnimateDiffModel": "Load AnimateDiff Model 🎭🅐🅓②",
|
|
||||||
# AnimateLCM-I2V Nodes
|
|
||||||
"ADE_ApplyAnimateLCMI2VModel": "Apply AnimateLCM-I2V Model 🎭🅐🅓②",
|
|
||||||
"ADE_LoadAnimateLCMI2VModel": "Load AnimateLCM-I2V Model 🎭🅐🅓②",
|
|
||||||
"ADE_UpscaleAndVAEEncode": "Scale Ref Image and VAE Encode 🎭🅐🅓②",
|
|
||||||
"ADE_InjectI2VIntoAnimateDiffModel": "🧪Inject I2V into AnimateDiff Model 🎭🅐🅓②",
|
|
||||||
# MotionCtrl Nodes
|
|
||||||
LoadMotionCtrlCMCM.NodeID: LoadMotionCtrlCMCM.NodeName,
|
|
||||||
LoadMotionCtrlOMCM.NodeID: LoadMotionCtrlOMCM.NodeName,
|
|
||||||
ApplyAnimateDiffMotionCtrlModel.NodeID: ApplyAnimateDiffMotionCtrlModel.NodeName,
|
|
||||||
# CameraCtrl Nodes
|
|
||||||
"ADE_ApplyAnimateDiffModelWithCameraCtrl": "Apply AnimateDiff+CameraCtrl Model 🎭🅐🅓②",
|
|
||||||
"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.) 🎭🅐🅓②",
|
|
||||||
"ADE_CameraManualPoseAppend": "Manual Append CameraCtrl Poses 🎭🅐🅓②",
|
|
||||||
"ADE_ReplaceCameraParameters": "Replace Camera Parameters 🎭🅐🅓②",
|
|
||||||
"ADE_ReplaceOriginalPoseAspectRatio": "Replace Orig. Pose Aspect Ratio 🎭🅐🅓②",
|
|
||||||
# PIA Nodes
|
|
||||||
"ADE_ApplyAnimateDiffModelWithPIA": "Apply AnimateDiff-PIA Model 🎭🅐🅓②",
|
|
||||||
"ADE_InputPIA_Multival": "PIA Input [Multival] 🎭🅐🅓②",
|
|
||||||
"ADE_InputPIA_PaperPresets": "PIA Input [Paper Presets] 🎭🅐🅓②",
|
|
||||||
"ADE_PIA_AnimateDiffKeyframe": "AnimateDiff-PIA Keyframe 🎭🅐🅓",
|
|
||||||
"ADE_InjectPIAIntoAnimateDiffModel": "🧪Inject PIA into AnimateDiff Model 🎭🅐🅓②",
|
|
||||||
# FancyVideo
|
|
||||||
ApplyAnimateDiffFancyVideo.NodeID: ApplyAnimateDiffFancyVideo.NodeName,
|
|
||||||
# HelloMeme
|
|
||||||
TestHMRefNetInjection.NodeID: TestHMRefNetInjection.NodeName,
|
|
||||||
# Deprecated Nodes
|
|
||||||
"ADE_AnimateDiffLoaderWithContext": "AnimateDiff Loader [Legacy] 🎭🅐🅓①",
|
|
||||||
"AnimateDiffLoaderV1": "🚫AnimateDiff Loader [DEPRECATED] 🎭🅐🅓",
|
|
||||||
"ADE_AnimateDiffLoaderV1Advanced": "🚫AnimateDiff Loader (Advanced) [DEPRECATED] 🎭🅐🅓",
|
|
||||||
"ADE_AnimateDiffCombine": "🚫AnimateDiff Combine [DEPRECATED, Use Video Combine (VHS) Instead!] 🎭🅐🅓",
|
|
||||||
"ADE_AnimateDiffModelSettings_Release": "🚫[DEPR] Motion Model Settings 🎭🅐🅓①",
|
|
||||||
"ADE_AnimateDiffModelSettingsSimple": "🚫[DEPR] Motion Model Settings (Simple) 🎭🅐🅓①",
|
|
||||||
"ADE_AnimateDiffModelSettings": "🚫[DEPR] Motion Model Settings (Advanced) 🎭🅐🅓①",
|
|
||||||
"ADE_AnimateDiffModelSettingsAdvancedAttnStrengths": "🚫[DEPR] Motion Model Settings (Adv. Attn) 🎭🅐🅓①",
|
|
||||||
}
|
|
||||||
|
|||||||
+206
-184
@@ -1,49 +1,55 @@
|
|||||||
|
from comfy_api.latest import io
|
||||||
from .ad_settings import AdjustPE, AdjustWeight, AdjustGroup, AnimateDiffSettings
|
from .ad_settings import AdjustPE, AdjustWeight, AdjustGroup, AnimateDiffSettings
|
||||||
from .utils_model import BIGMAX
|
from .utils_model import BIGMAX
|
||||||
|
|
||||||
|
|
||||||
class AnimateDiffSettingsNode:
|
class AnimateDiffSettingsNode(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {
|
return io.Schema(
|
||||||
"optional": {
|
node_id='ADE_AnimateDiffSettings',
|
||||||
"pe_adjust": ("PE_ADJUST",),
|
display_name='AnimateDiff Settings 🎭🅐🅓',
|
||||||
"weight_adjust": ("WEIGHT_ADJUST",),
|
category='Animate Diff 🎭🅐🅓/ad settings',
|
||||||
},
|
inputs=[
|
||||||
}
|
io.Custom("PE_ADJUST").Input('pe_adjust', optional=True),
|
||||||
|
io.Custom("WEIGHT_ADJUST").Input('weight_adjust', optional=True),
|
||||||
RETURN_TYPES = ("AD_SETTINGS",)
|
],
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/ad settings"
|
outputs=[
|
||||||
FUNCTION = "get_ad_settings"
|
io.Custom("AD_SETTINGS").Output('AD_SETTINGS'),
|
||||||
|
],
|
||||||
def get_ad_settings(self, pe_adjust: AdjustGroup=None, weight_adjust: AdjustGroup=None):
|
)
|
||||||
return (AnimateDiffSettings(adjust_pe=pe_adjust, adjust_weight=weight_adjust),)
|
|
||||||
|
|
||||||
|
|
||||||
class ManualAdjustPENode:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def execute(cls, pe_adjust: AdjustGroup=None, weight_adjust: AdjustGroup=None) -> io.NodeOutput:
|
||||||
return {
|
return io.NodeOutput(AnimateDiffSettings(adjust_pe=pe_adjust, adjust_weight=weight_adjust))
|
||||||
"required": {
|
|
||||||
"cap_initial_pe_length": ("INT", {"default": 0, "min": 0, "step": 1}),
|
|
||||||
"interpolate_pe_to_length": ("INT", {"default": 0, "min": 0, "step": 1}),
|
|
||||||
"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",),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("PE_ADJUST",)
|
class ManualAdjustPENode(io.ComfyNode):
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/ad settings/pe adjust"
|
@classmethod
|
||||||
FUNCTION = "get_pe_adjust"
|
def define_schema(cls) -> io.Schema:
|
||||||
|
return io.Schema(
|
||||||
|
node_id='ADE_AdjustPEManual',
|
||||||
|
display_name='Adjust PE [Manual] 🎭🅐🅓',
|
||||||
|
category='Animate Diff 🎭🅐🅓/ad settings/pe adjust',
|
||||||
|
inputs=[
|
||||||
|
io.Int.Input('cap_initial_pe_length', default=0, min=0, step=1),
|
||||||
|
io.Int.Input('interpolate_pe_to_length', default=0, min=0, step=1),
|
||||||
|
io.Int.Input('initial_pe_idx_offset', default=0, min=0, step=1),
|
||||||
|
io.Int.Input('final_pe_idx_offset', default=0, min=0, step=1),
|
||||||
|
io.Boolean.Input('print_adjustment', default=False),
|
||||||
|
io.Custom("PE_ADJUST").Input('prev_pe_adjust', optional=True),
|
||||||
|
],
|
||||||
|
outputs=[
|
||||||
|
io.Custom("PE_ADJUST").Output('PE_ADJUST'),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
def get_pe_adjust(self, cap_initial_pe_length: int, interpolate_pe_to_length: int,
|
|
||||||
|
@classmethod
|
||||||
|
def execute(cls, cap_initial_pe_length: int, interpolate_pe_to_length: int,
|
||||||
initial_pe_idx_offset: int, final_pe_idx_offset: int, print_adjustment: bool,
|
initial_pe_idx_offset: int, final_pe_idx_offset: int, print_adjustment: bool,
|
||||||
prev_pe_adjust: AdjustGroup=None):
|
prev_pe_adjust: AdjustGroup=None) -> io.NodeOutput:
|
||||||
if prev_pe_adjust is None:
|
if prev_pe_adjust is None:
|
||||||
prev_pe_adjust = AdjustGroup()
|
prev_pe_adjust = AdjustGroup()
|
||||||
prev_pe_adjust = prev_pe_adjust.clone()
|
prev_pe_adjust = prev_pe_adjust.clone()
|
||||||
@@ -51,82 +57,88 @@ class ManualAdjustPENode:
|
|||||||
initial_pe_idx_offset=initial_pe_idx_offset, final_pe_idx_offset=final_pe_idx_offset,
|
initial_pe_idx_offset=initial_pe_idx_offset, final_pe_idx_offset=final_pe_idx_offset,
|
||||||
print_adjustment=print_adjustment)
|
print_adjustment=print_adjustment)
|
||||||
prev_pe_adjust.add(adjust)
|
prev_pe_adjust.add(adjust)
|
||||||
return (prev_pe_adjust,)
|
return io.NodeOutput(prev_pe_adjust)
|
||||||
|
|
||||||
|
|
||||||
class SweetspotStretchPENode:
|
class SweetspotStretchPENode(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {
|
return io.Schema(
|
||||||
"required": {
|
node_id='ADE_AdjustPESweetspotStretch',
|
||||||
"sweetspot": ("INT", {"default": 16, "min": 0, "max": BIGMAX},),
|
display_name='Adjust PE [Sweetspot] 🎭🅐🅓',
|
||||||
"new_sweetspot": ("INT", {"default": 16, "min": 0, "max": BIGMAX},),
|
category='Animate Diff 🎭🅐🅓/ad settings/pe adjust',
|
||||||
"print_adjustment": ("BOOLEAN", {"default": False}),
|
inputs=[
|
||||||
},
|
io.Int.Input('sweetspot', default=16, max=9007199254740991, min=0),
|
||||||
"optional": {
|
io.Int.Input('new_sweetspot', default=16, max=9007199254740991, min=0),
|
||||||
"prev_pe_adjust": ("PE_ADJUST",),
|
io.Boolean.Input('print_adjustment', default=False),
|
||||||
},
|
io.Custom("PE_ADJUST").Input('prev_pe_adjust', optional=True),
|
||||||
}
|
],
|
||||||
|
outputs=[
|
||||||
|
io.Custom("PE_ADJUST").Output('PE_ADJUST'),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
RETURN_TYPES = ("PE_ADJUST",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/ad settings/pe adjust"
|
|
||||||
FUNCTION = "get_pe_adjust"
|
|
||||||
|
|
||||||
def get_pe_adjust(self, sweetspot: int, new_sweetspot: int, print_adjustment: bool, prev_pe_adjust: AdjustGroup=None):
|
@classmethod
|
||||||
|
def execute(cls, sweetspot: int, new_sweetspot: int, print_adjustment: bool, prev_pe_adjust: AdjustGroup=None) -> io.NodeOutput:
|
||||||
if prev_pe_adjust is None:
|
if prev_pe_adjust is None:
|
||||||
prev_pe_adjust = AdjustGroup()
|
prev_pe_adjust = AdjustGroup()
|
||||||
prev_pe_adjust = prev_pe_adjust.clone()
|
prev_pe_adjust = prev_pe_adjust.clone()
|
||||||
adjust = AdjustPE(cap_initial_pe_length=sweetspot, interpolate_pe_to_length=new_sweetspot,
|
adjust = AdjustPE(cap_initial_pe_length=sweetspot, interpolate_pe_to_length=new_sweetspot,
|
||||||
print_adjustment=print_adjustment)
|
print_adjustment=print_adjustment)
|
||||||
prev_pe_adjust.add(adjust)
|
prev_pe_adjust.add(adjust)
|
||||||
return (prev_pe_adjust,)
|
return io.NodeOutput(prev_pe_adjust)
|
||||||
|
|
||||||
|
|
||||||
class FullStretchPENode:
|
class FullStretchPENode(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {
|
return io.Schema(
|
||||||
"required": {
|
node_id='ADE_AdjustPEFullStretch',
|
||||||
"pe_stretch": ("INT", {"default": 0, "min": 0, "max": BIGMAX},),
|
display_name='Adjust PE [Full Stretch] 🎭🅐🅓',
|
||||||
"print_adjustment": ("BOOLEAN", {"default": False}),
|
category='Animate Diff 🎭🅐🅓/ad settings/pe adjust',
|
||||||
},
|
inputs=[
|
||||||
"optional": {
|
io.Int.Input('pe_stretch', default=0, max=9007199254740991, min=0),
|
||||||
"prev_pe_adjust": ("PE_ADJUST",),
|
io.Boolean.Input('print_adjustment', default=False),
|
||||||
},
|
io.Custom("PE_ADJUST").Input('prev_pe_adjust', optional=True),
|
||||||
}
|
],
|
||||||
|
outputs=[
|
||||||
|
io.Custom("PE_ADJUST").Output('PE_ADJUST'),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
RETURN_TYPES = ("PE_ADJUST",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/ad settings/pe adjust"
|
|
||||||
FUNCTION = "get_pe_adjust"
|
|
||||||
|
|
||||||
def get_pe_adjust(self, pe_stretch: int, print_adjustment: bool, prev_pe_adjust: AdjustGroup=None):
|
@classmethod
|
||||||
|
def execute(cls, pe_stretch: int, print_adjustment: bool, prev_pe_adjust: AdjustGroup=None) -> io.NodeOutput:
|
||||||
if prev_pe_adjust is None:
|
if prev_pe_adjust is None:
|
||||||
prev_pe_adjust = AdjustGroup()
|
prev_pe_adjust = AdjustGroup()
|
||||||
prev_pe_adjust = prev_pe_adjust.clone()
|
prev_pe_adjust = prev_pe_adjust.clone()
|
||||||
adjust = AdjustPE(motion_pe_stretch=pe_stretch,
|
adjust = AdjustPE(motion_pe_stretch=pe_stretch,
|
||||||
print_adjustment=print_adjustment)
|
print_adjustment=print_adjustment)
|
||||||
prev_pe_adjust.add(adjust)
|
prev_pe_adjust.add(adjust)
|
||||||
return (prev_pe_adjust,)
|
return io.NodeOutput(prev_pe_adjust)
|
||||||
|
|
||||||
|
|
||||||
class WeightAdjustAllAddNode:
|
class WeightAdjustAllAddNode(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {
|
return io.Schema(
|
||||||
"required": {
|
node_id='ADE_AdjustWeightAllAdd',
|
||||||
"all_ADD": ("FLOAT", {"default": 0.0, "min": -2.0, "max": 2.0, "step": 0.000001}),
|
display_name='Adjust Weight [All◆Add] 🎭🅐🅓',
|
||||||
"print_adjustment": ("BOOLEAN", {"default": False}),
|
category='Animate Diff 🎭🅐🅓/ad settings/weight adjust',
|
||||||
},
|
inputs=[
|
||||||
"optional": {
|
io.Float.Input('all_ADD', default=0.0, max=2.0, min=-2.0, step=1e-06),
|
||||||
"prev_weight_adjust": ("WEIGHT_ADJUST",),
|
io.Boolean.Input('print_adjustment', default=False),
|
||||||
},
|
io.Custom("WEIGHT_ADJUST").Input('prev_weight_adjust', optional=True),
|
||||||
}
|
],
|
||||||
|
outputs=[
|
||||||
|
io.Custom("WEIGHT_ADJUST").Output('WEIGHT_ADJUST'),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
RETURN_TYPES = ("WEIGHT_ADJUST",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/ad settings/weight adjust"
|
|
||||||
FUNCTION = "get_weight_adjust"
|
|
||||||
|
|
||||||
def get_weight_adjust(self, all_ADD: float, print_adjustment: bool, prev_weight_adjust: AdjustGroup=None):
|
@classmethod
|
||||||
|
def execute(cls, all_ADD: float, print_adjustment: bool, prev_weight_adjust: AdjustGroup=None) -> io.NodeOutput:
|
||||||
if prev_weight_adjust is None:
|
if prev_weight_adjust is None:
|
||||||
prev_weight_adjust = AdjustGroup()
|
prev_weight_adjust = AdjustGroup()
|
||||||
prev_weight_adjust = prev_weight_adjust.clone()
|
prev_weight_adjust = prev_weight_adjust.clone()
|
||||||
@@ -135,27 +147,29 @@ class WeightAdjustAllAddNode:
|
|||||||
print_adjustment=print_adjustment
|
print_adjustment=print_adjustment
|
||||||
)
|
)
|
||||||
prev_weight_adjust.add(adjust)
|
prev_weight_adjust.add(adjust)
|
||||||
return (prev_weight_adjust,)
|
return io.NodeOutput(prev_weight_adjust)
|
||||||
|
|
||||||
|
|
||||||
class WeightAdjustAllMultNode:
|
class WeightAdjustAllMultNode(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {
|
return io.Schema(
|
||||||
"required": {
|
node_id='ADE_AdjustWeightAllMult',
|
||||||
"all_MULT": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 2.0, "step": 0.000001}),
|
display_name='Adjust Weight [All◆Mult] 🎭🅐🅓',
|
||||||
"print_adjustment": ("BOOLEAN", {"default": False}),
|
category='Animate Diff 🎭🅐🅓/ad settings/weight adjust',
|
||||||
},
|
inputs=[
|
||||||
"optional": {
|
io.Float.Input('all_MULT', default=1.0, max=2.0, min=0.0, step=1e-06),
|
||||||
"prev_weight_adjust": ("WEIGHT_ADJUST",),
|
io.Boolean.Input('print_adjustment', default=False),
|
||||||
},
|
io.Custom("WEIGHT_ADJUST").Input('prev_weight_adjust', optional=True),
|
||||||
}
|
],
|
||||||
|
outputs=[
|
||||||
|
io.Custom("WEIGHT_ADJUST").Output('WEIGHT_ADJUST'),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
RETURN_TYPES = ("WEIGHT_ADJUST",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/ad settings/weight adjust"
|
|
||||||
FUNCTION = "get_weight_adjust"
|
|
||||||
|
|
||||||
def get_weight_adjust(self, all_MULT: float, print_adjustment: bool, prev_weight_adjust: AdjustGroup=None):
|
@classmethod
|
||||||
|
def execute(cls, all_MULT: float, print_adjustment: bool, prev_weight_adjust: AdjustGroup=None) -> io.NodeOutput:
|
||||||
if prev_weight_adjust is None:
|
if prev_weight_adjust is None:
|
||||||
prev_weight_adjust = AdjustGroup()
|
prev_weight_adjust = AdjustGroup()
|
||||||
prev_weight_adjust = prev_weight_adjust.clone()
|
prev_weight_adjust = prev_weight_adjust.clone()
|
||||||
@@ -164,29 +178,31 @@ class WeightAdjustAllMultNode:
|
|||||||
print_adjustment=print_adjustment
|
print_adjustment=print_adjustment
|
||||||
)
|
)
|
||||||
prev_weight_adjust.add(adjust)
|
prev_weight_adjust.add(adjust)
|
||||||
return (prev_weight_adjust,)
|
return io.NodeOutput(prev_weight_adjust)
|
||||||
|
|
||||||
|
|
||||||
class WeightAdjustIndivAddNode:
|
class WeightAdjustIndivAddNode(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {
|
return io.Schema(
|
||||||
"required": {
|
node_id='ADE_AdjustWeightIndivAdd',
|
||||||
"pe_ADD": ("FLOAT", {"default": 0.0, "min": -2.0, "max": 2.0, "step": 0.000001}),
|
display_name='Adjust Weight [Indiv◆Add] 🎭🅐🅓',
|
||||||
"attn_ADD": ("FLOAT", {"default": 0.0, "min": -2.0, "max": 2.0, "step": 0.000001}),
|
category='Animate Diff 🎭🅐🅓/ad settings/weight adjust',
|
||||||
"other_ADD": ("FLOAT", {"default": 0.0, "min": -2.0, "max": 2.0, "step": 0.000001}),
|
inputs=[
|
||||||
"print_adjustment": ("BOOLEAN", {"default": False}),
|
io.Float.Input('pe_ADD', default=0.0, max=2.0, min=-2.0, step=1e-06),
|
||||||
},
|
io.Float.Input('attn_ADD', default=0.0, max=2.0, min=-2.0, step=1e-06),
|
||||||
"optional": {
|
io.Float.Input('other_ADD', default=0.0, max=2.0, min=-2.0, step=1e-06),
|
||||||
"prev_weight_adjust": ("WEIGHT_ADJUST",),
|
io.Boolean.Input('print_adjustment', default=False),
|
||||||
},
|
io.Custom("WEIGHT_ADJUST").Input('prev_weight_adjust', optional=True),
|
||||||
}
|
],
|
||||||
|
outputs=[
|
||||||
|
io.Custom("WEIGHT_ADJUST").Output('WEIGHT_ADJUST'),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
RETURN_TYPES = ("WEIGHT_ADJUST",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/ad settings/weight adjust"
|
|
||||||
FUNCTION = "get_weight_adjust"
|
|
||||||
|
|
||||||
def get_weight_adjust(self, pe_ADD: float, attn_ADD: float, other_ADD: float, print_adjustment: bool, prev_weight_adjust: AdjustGroup=None):
|
@classmethod
|
||||||
|
def execute(cls, pe_ADD: float, attn_ADD: float, other_ADD: float, print_adjustment: bool, prev_weight_adjust: AdjustGroup=None) -> io.NodeOutput:
|
||||||
if prev_weight_adjust is None:
|
if prev_weight_adjust is None:
|
||||||
prev_weight_adjust = AdjustGroup()
|
prev_weight_adjust = AdjustGroup()
|
||||||
prev_weight_adjust = prev_weight_adjust.clone()
|
prev_weight_adjust = prev_weight_adjust.clone()
|
||||||
@@ -197,29 +213,31 @@ class WeightAdjustIndivAddNode:
|
|||||||
print_adjustment=print_adjustment
|
print_adjustment=print_adjustment
|
||||||
)
|
)
|
||||||
prev_weight_adjust.add(adjust)
|
prev_weight_adjust.add(adjust)
|
||||||
return (prev_weight_adjust,)
|
return io.NodeOutput(prev_weight_adjust)
|
||||||
|
|
||||||
|
|
||||||
class WeightAdjustIndivMultNode:
|
class WeightAdjustIndivMultNode(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {
|
return io.Schema(
|
||||||
"required": {
|
node_id='ADE_AdjustWeightIndivMult',
|
||||||
"pe_MULT": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 2.0, "step": 0.000001}),
|
display_name='Adjust Weight [Indiv◆Mult] 🎭🅐🅓',
|
||||||
"attn_MULT": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 2.0, "step": 0.000001}),
|
category='Animate Diff 🎭🅐🅓/ad settings/weight adjust',
|
||||||
"other_MULT": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 2.0, "step": 0.000001}),
|
inputs=[
|
||||||
"print_adjustment": ("BOOLEAN", {"default": False}),
|
io.Float.Input('pe_MULT', default=1.0, max=2.0, min=0.0, step=1e-06),
|
||||||
},
|
io.Float.Input('attn_MULT', default=1.0, max=2.0, min=0.0, step=1e-06),
|
||||||
"optional": {
|
io.Float.Input('other_MULT', default=1.0, max=2.0, min=0.0, step=1e-06),
|
||||||
"prev_weight_adjust": ("WEIGHT_ADJUST",),
|
io.Boolean.Input('print_adjustment', default=False),
|
||||||
},
|
io.Custom("WEIGHT_ADJUST").Input('prev_weight_adjust', optional=True),
|
||||||
}
|
],
|
||||||
|
outputs=[
|
||||||
|
io.Custom("WEIGHT_ADJUST").Output('WEIGHT_ADJUST'),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
RETURN_TYPES = ("WEIGHT_ADJUST",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/ad settings/weight adjust"
|
|
||||||
FUNCTION = "get_weight_adjust"
|
|
||||||
|
|
||||||
def get_weight_adjust(self, pe_MULT: float, attn_MULT: float, other_MULT: float, print_adjustment: bool, prev_weight_adjust: AdjustGroup=None):
|
@classmethod
|
||||||
|
def execute(cls, pe_MULT: float, attn_MULT: float, other_MULT: float, print_adjustment: bool, prev_weight_adjust: AdjustGroup=None) -> io.NodeOutput:
|
||||||
if prev_weight_adjust is None:
|
if prev_weight_adjust is None:
|
||||||
prev_weight_adjust = AdjustGroup()
|
prev_weight_adjust = AdjustGroup()
|
||||||
prev_weight_adjust = prev_weight_adjust.clone()
|
prev_weight_adjust = prev_weight_adjust.clone()
|
||||||
@@ -230,37 +248,39 @@ class WeightAdjustIndivMultNode:
|
|||||||
print_adjustment=print_adjustment
|
print_adjustment=print_adjustment
|
||||||
)
|
)
|
||||||
prev_weight_adjust.add(adjust)
|
prev_weight_adjust.add(adjust)
|
||||||
return (prev_weight_adjust,)
|
return io.NodeOutput(prev_weight_adjust)
|
||||||
|
|
||||||
|
|
||||||
class WeightAdjustIndivAttnAddNode:
|
class WeightAdjustIndivAttnAddNode(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {
|
return io.Schema(
|
||||||
"required": {
|
node_id='ADE_AdjustWeightIndivAttnAdd',
|
||||||
"pe_ADD": ("FLOAT", {"default": 0.0, "min": -2.0, "max": 2.0, "step": 0.000001}),
|
display_name='Adjust Weight [Indiv-Attn◆Add] 🎭🅐🅓',
|
||||||
"attn_ADD": ("FLOAT", {"default": 0.0, "min": -2.0, "max": 2.0, "step": 0.000001}),
|
category='Animate Diff 🎭🅐🅓/ad settings/weight adjust',
|
||||||
"attn_q_ADD": ("FLOAT", {"default": 0.0, "min": -2.0, "max": 2.0, "step": 0.000001}),
|
inputs=[
|
||||||
"attn_k_ADD": ("FLOAT", {"default": 0.0, "min": -2.0, "max": 2.0, "step": 0.000001}),
|
io.Float.Input('pe_ADD', default=0.0, max=2.0, min=-2.0, step=1e-06),
|
||||||
"attn_v_ADD": ("FLOAT", {"default": 0.0, "min": -2.0, "max": 2.0, "step": 0.000001}),
|
io.Float.Input('attn_ADD', default=0.0, max=2.0, min=-2.0, step=1e-06),
|
||||||
"attn_out_weight_ADD": ("FLOAT", {"default": 0.0, "min": -2.0, "max": 2.0, "step": 0.000001}),
|
io.Float.Input('attn_q_ADD', default=0.0, max=2.0, min=-2.0, step=1e-06),
|
||||||
"attn_out_bias_ADD": ("FLOAT", {"default": 0.0, "min": -2.0, "max": 2.0, "step": 0.000001}),
|
io.Float.Input('attn_k_ADD', default=0.0, max=2.0, min=-2.0, step=1e-06),
|
||||||
"other_ADD": ("FLOAT", {"default": 0.0, "min": -2.0, "max": 2.0, "step": 0.000001}),
|
io.Float.Input('attn_v_ADD', default=0.0, max=2.0, min=-2.0, step=1e-06),
|
||||||
"print_adjustment": ("BOOLEAN", {"default": False}),
|
io.Float.Input('attn_out_weight_ADD', default=0.0, max=2.0, min=-2.0, step=1e-06),
|
||||||
},
|
io.Float.Input('attn_out_bias_ADD', default=0.0, max=2.0, min=-2.0, step=1e-06),
|
||||||
"optional": {
|
io.Float.Input('other_ADD', default=0.0, max=2.0, min=-2.0, step=1e-06),
|
||||||
"prev_weight_adjust": ("WEIGHT_ADJUST",),
|
io.Boolean.Input('print_adjustment', default=False),
|
||||||
},
|
io.Custom("WEIGHT_ADJUST").Input('prev_weight_adjust', optional=True),
|
||||||
}
|
],
|
||||||
|
outputs=[
|
||||||
|
io.Custom("WEIGHT_ADJUST").Output('WEIGHT_ADJUST'),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
RETURN_TYPES = ("WEIGHT_ADJUST",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/ad settings/weight adjust"
|
|
||||||
FUNCTION = "get_weight_adjust"
|
|
||||||
|
|
||||||
def get_weight_adjust(self, pe_ADD: float, attn_ADD: float,
|
@classmethod
|
||||||
|
def execute(cls, pe_ADD: float, attn_ADD: float,
|
||||||
attn_q_ADD: float, attn_k_ADD: float, attn_v_ADD: float,
|
attn_q_ADD: float, attn_k_ADD: float, attn_v_ADD: float,
|
||||||
attn_out_weight_ADD: float, attn_out_bias_ADD: float,
|
attn_out_weight_ADD: float, attn_out_bias_ADD: float,
|
||||||
other_ADD: float, print_adjustment: bool, prev_weight_adjust: AdjustGroup=None):
|
other_ADD: float, print_adjustment: bool, prev_weight_adjust: AdjustGroup=None) -> io.NodeOutput:
|
||||||
if prev_weight_adjust is None:
|
if prev_weight_adjust is None:
|
||||||
prev_weight_adjust = AdjustGroup()
|
prev_weight_adjust = AdjustGroup()
|
||||||
prev_weight_adjust = prev_weight_adjust.clone()
|
prev_weight_adjust = prev_weight_adjust.clone()
|
||||||
@@ -276,37 +296,39 @@ class WeightAdjustIndivAttnAddNode:
|
|||||||
print_adjustment=print_adjustment
|
print_adjustment=print_adjustment
|
||||||
)
|
)
|
||||||
prev_weight_adjust.add(adjust)
|
prev_weight_adjust.add(adjust)
|
||||||
return (prev_weight_adjust,)
|
return io.NodeOutput(prev_weight_adjust)
|
||||||
|
|
||||||
|
|
||||||
class WeightAdjustIndivAttnMultNode:
|
class WeightAdjustIndivAttnMultNode(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {
|
return io.Schema(
|
||||||
"required": {
|
node_id='ADE_AdjustWeightIndivAttnMult',
|
||||||
"pe_MULT": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 2.0, "step": 0.000001}),
|
display_name='Adjust Weight [Indiv-Attn◆Mult] 🎭🅐🅓',
|
||||||
"attn_MULT": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 2.0, "step": 0.000001}),
|
category='Animate Diff 🎭🅐🅓/ad settings/weight adjust',
|
||||||
"attn_q_MULT": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 2.0, "step": 0.000001}),
|
inputs=[
|
||||||
"attn_k_MULT": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 2.0, "step": 0.000001}),
|
io.Float.Input('pe_MULT', default=1.0, max=2.0, min=0.0, step=1e-06),
|
||||||
"attn_v_MULT": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 2.0, "step": 0.000001}),
|
io.Float.Input('attn_MULT', default=1.0, max=2.0, min=0.0, step=1e-06),
|
||||||
"attn_out_weight_MULT": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 2.0, "step": 0.000001}),
|
io.Float.Input('attn_q_MULT', default=1.0, max=2.0, min=0.0, step=1e-06),
|
||||||
"attn_out_bias_MULT": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 2.0, "step": 0.000001}),
|
io.Float.Input('attn_k_MULT', default=1.0, max=2.0, min=0.0, step=1e-06),
|
||||||
"other_MULT": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 2.0, "step": 0.000001}),
|
io.Float.Input('attn_v_MULT', default=1.0, max=2.0, min=0.0, step=1e-06),
|
||||||
"print_adjustment": ("BOOLEAN", {"default": False}),
|
io.Float.Input('attn_out_weight_MULT', default=1.0, max=2.0, min=0.0, step=1e-06),
|
||||||
},
|
io.Float.Input('attn_out_bias_MULT', default=1.0, max=2.0, min=0.0, step=1e-06),
|
||||||
"optional": {
|
io.Float.Input('other_MULT', default=1.0, max=2.0, min=0.0, step=1e-06),
|
||||||
"prev_weight_adjust": ("WEIGHT_ADJUST",),
|
io.Boolean.Input('print_adjustment', default=False),
|
||||||
},
|
io.Custom("WEIGHT_ADJUST").Input('prev_weight_adjust', optional=True),
|
||||||
}
|
],
|
||||||
|
outputs=[
|
||||||
|
io.Custom("WEIGHT_ADJUST").Output('WEIGHT_ADJUST'),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
RETURN_TYPES = ("WEIGHT_ADJUST",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/ad settings/weight adjust"
|
|
||||||
FUNCTION = "get_weight_adjust"
|
|
||||||
|
|
||||||
def get_weight_adjust(self, pe_MULT: float, attn_MULT: float,
|
@classmethod
|
||||||
|
def execute(cls, pe_MULT: float, attn_MULT: float,
|
||||||
attn_q_MULT: float, attn_k_MULT: float, attn_v_MULT: float,
|
attn_q_MULT: float, attn_k_MULT: float, attn_v_MULT: float,
|
||||||
attn_out_weight_MULT: float, attn_out_bias_MULT: float,
|
attn_out_weight_MULT: float, attn_out_bias_MULT: float,
|
||||||
other_MULT: float, print_adjustment: bool, prev_weight_adjust: AdjustGroup=None):
|
other_MULT: float, print_adjustment: bool, prev_weight_adjust: AdjustGroup=None) -> io.NodeOutput:
|
||||||
if prev_weight_adjust is None:
|
if prev_weight_adjust is None:
|
||||||
prev_weight_adjust = AdjustGroup()
|
prev_weight_adjust = AdjustGroup()
|
||||||
prev_weight_adjust = prev_weight_adjust.clone()
|
prev_weight_adjust = prev_weight_adjust.clone()
|
||||||
@@ -322,4 +344,4 @@ class WeightAdjustIndivAttnMultNode:
|
|||||||
print_adjustment=print_adjustment
|
print_adjustment=print_adjustment
|
||||||
)
|
)
|
||||||
prev_weight_adjust.add(adjust)
|
prev_weight_adjust.add(adjust)
|
||||||
return (prev_weight_adjust,)
|
return io.NodeOutput(prev_weight_adjust)
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
from comfy_api.latest import io
|
||||||
from typing import Union
|
from typing import Union
|
||||||
import torch
|
import torch
|
||||||
|
|
||||||
@@ -16,40 +17,42 @@ from .motion_module_ad import AnimateDiffFormat
|
|||||||
from .nodes_gen2 import ApplyAnimateDiffModelNode
|
from .nodes_gen2 import ApplyAnimateDiffModelNode
|
||||||
|
|
||||||
|
|
||||||
class ApplyAnimateLCMI2VModel:
|
class ApplyAnimateLCMI2VModel(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {
|
return io.Schema(
|
||||||
"required": {
|
node_id='ADE_ApplyAnimateLCMI2VModel',
|
||||||
"motion_model": ("MOTION_MODEL_ADE",),
|
display_name='Apply AnimateLCM-I2V Model 🎭🅐🅓②',
|
||||||
"ref_latent": ("LATENT",),
|
category='Animate Diff 🎭🅐🅓/② Gen2 nodes ②/AnimateLCM-I2V',
|
||||||
"ref_drift": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 10.0, "step": 0.001}),
|
inputs=[
|
||||||
"apply_ref_when_disabled": ("BOOLEAN", {"default": False}),
|
io.Custom("MOTION_MODEL_ADE").Input('motion_model'),
|
||||||
"start_percent": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001}),
|
io.Latent.Input('ref_latent'),
|
||||||
"end_percent": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.001}),
|
io.Float.Input('ref_drift', default=0.0, max=10.0, min=0.0, step=0.001),
|
||||||
},
|
io.Boolean.Input('apply_ref_when_disabled', default=False),
|
||||||
"optional": {
|
io.Float.Input('start_percent', default=0.0, max=1.0, min=0.0, step=0.001),
|
||||||
"motion_lora": ("MOTION_LORA",),
|
io.Float.Input('end_percent', default=1.0, max=1.0, min=0.0, step=0.001),
|
||||||
"scale_multival": ("MULTIVAL",),
|
io.Custom("MOTION_LORA").Input('motion_lora', optional=True),
|
||||||
"effect_multival": ("MULTIVAL",),
|
io.Custom("MULTIVAL").Input('scale_multival', optional=True),
|
||||||
"ad_keyframes": ("AD_KEYFRAMES",),
|
io.Custom("MULTIVAL").Input('effect_multival', optional=True),
|
||||||
"prev_m_models": ("M_MODELS",),
|
io.Custom("AD_KEYFRAMES").Input('ad_keyframes', optional=True),
|
||||||
"per_block": ("PER_BLOCK",),
|
io.Custom("M_MODELS").Input('prev_m_models', optional=True),
|
||||||
},
|
io.Custom("PER_BLOCK").Input('per_block', optional=True),
|
||||||
}
|
],
|
||||||
|
outputs=[
|
||||||
|
io.Custom("M_MODELS").Output('M_MODELS'),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
RETURN_TYPES = ("M_MODELS",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/② Gen2 nodes ②/AnimateLCM-I2V"
|
|
||||||
FUNCTION = "apply_motion_model"
|
|
||||||
|
|
||||||
def apply_motion_model(self, motion_model: MotionModelPatcher, ref_latent: dict, ref_drift: float=0.0, apply_ref_when_disabled=False, start_percent: float=0.0, end_percent: float=1.0,
|
@classmethod
|
||||||
|
def execute(cls, motion_model: MotionModelPatcher, ref_latent: dict, ref_drift: float=0.0, apply_ref_when_disabled=False, start_percent: float=0.0, end_percent: float=1.0,
|
||||||
motion_lora: MotionLoraList=None, ad_keyframes: ADKeyframeGroup=None,
|
motion_lora: MotionLoraList=None, ad_keyframes: ADKeyframeGroup=None,
|
||||||
scale_multival=None, effect_multival=None, per_block=None,
|
scale_multival=None, effect_multival=None, per_block=None,
|
||||||
prev_m_models: MotionModelGroup=None,):
|
prev_m_models: MotionModelGroup=None,):
|
||||||
new_m_models = ApplyAnimateDiffModelNode.apply_motion_model(self, motion_model, start_percent=start_percent, end_percent=end_percent,
|
new_m_models = ApplyAnimateDiffModelNode.execute( motion_model, start_percent=start_percent, end_percent=end_percent,
|
||||||
motion_lora=motion_lora, ad_keyframes=ad_keyframes,
|
motion_lora=motion_lora, ad_keyframes=ad_keyframes,
|
||||||
scale_multival=scale_multival, effect_multival=effect_multival, per_block=per_block,
|
scale_multival=scale_multival, effect_multival=effect_multival, per_block=per_block,
|
||||||
prev_m_models=prev_m_models)
|
prev_m_models=prev_m_models).args
|
||||||
# most recent added model will always be first in list;
|
# most recent added model will always be first in list;
|
||||||
curr_model = new_m_models[0].models[0]
|
curr_model = new_m_models[0].models[0]
|
||||||
# confirm that model contains img_encoder
|
# confirm that model contains img_encoder
|
||||||
@@ -59,27 +62,29 @@ class ApplyAnimateLCMI2VModel:
|
|||||||
attachment.orig_img_latents = ref_latent["samples"]
|
attachment.orig_img_latents = ref_latent["samples"]
|
||||||
attachment.orig_ref_drift = ref_drift
|
attachment.orig_ref_drift = ref_drift
|
||||||
attachment.orig_apply_ref_when_disabled = apply_ref_when_disabled
|
attachment.orig_apply_ref_when_disabled = apply_ref_when_disabled
|
||||||
return new_m_models
|
return io.NodeOutput(*new_m_models)
|
||||||
|
|
||||||
|
|
||||||
class LoadAnimateLCMI2VModelNode:
|
class LoadAnimateLCMI2VModelNode(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {
|
return io.Schema(
|
||||||
"required": {
|
node_id='ADE_LoadAnimateLCMI2VModel',
|
||||||
"model_name": (get_available_motion_models(),),
|
display_name='Load AnimateLCM-I2V Model 🎭🅐🅓②',
|
||||||
},
|
category='Animate Diff 🎭🅐🅓/② Gen2 nodes ②/AnimateLCM-I2V',
|
||||||
"optional": {
|
inputs=[
|
||||||
"ad_settings": ("AD_SETTINGS",),
|
io.Combo.Input('model_name', options=get_available_motion_models()),
|
||||||
}
|
io.Custom("AD_SETTINGS").Input('ad_settings', optional=True),
|
||||||
}
|
],
|
||||||
|
outputs=[
|
||||||
|
io.Custom("MOTION_MODEL_ADE").Output('MOTION_MODEL'),
|
||||||
|
io.Custom("MOTION_MODEL_ADE").Output('encoder_only'),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
RETURN_TYPES = ("MOTION_MODEL_ADE", "MOTION_MODEL_ADE")
|
|
||||||
RETURN_NAMES = ("MOTION_MODEL", "encoder_only")
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/② Gen2 nodes ②/AnimateLCM-I2V"
|
|
||||||
FUNCTION = "load_motion_model"
|
|
||||||
|
|
||||||
def load_motion_model(self, model_name: str, ad_settings: AnimateDiffSettings=None):
|
@classmethod
|
||||||
|
def execute(cls, model_name: str, ad_settings: AnimateDiffSettings=None):
|
||||||
# load motion module and motion settings, if included
|
# load motion module and motion settings, if included
|
||||||
motion_model = load_motion_module_gen2(model_name=model_name, motion_model_settings=ad_settings)
|
motion_model = load_motion_module_gen2(model_name=model_name, motion_model_settings=ad_settings)
|
||||||
# make sure model is an AnimateLCM-I2V model
|
# make sure model is an AnimateLCM-I2V model
|
||||||
@@ -89,61 +94,66 @@ class LoadAnimateLCMI2VModelNode:
|
|||||||
raise Exception(f"Motion model '{motion_model.model.mm_info.mm_name}' is not an AnimateLCM-I2V model; selected model IS AnimateLCM, but does NOT contain an img_encoder.")
|
raise Exception(f"Motion model '{motion_model.model.mm_info.mm_name}' is not an AnimateLCM-I2V model; selected model IS AnimateLCM, but does NOT contain an img_encoder.")
|
||||||
# create encoder-only motion model
|
# create encoder-only motion model
|
||||||
encoder_only_motion_model = create_fresh_encoder_only_model(motion_model=motion_model)
|
encoder_only_motion_model = create_fresh_encoder_only_model(motion_model=motion_model)
|
||||||
return (motion_model, encoder_only_motion_model)
|
return io.NodeOutput(motion_model, encoder_only_motion_model)
|
||||||
|
|
||||||
|
|
||||||
class LoadAnimateDiffAndInjectI2VNode:
|
class LoadAnimateDiffAndInjectI2VNode(io.ComfyNode):
|
||||||
EXPERIMENTAL = True
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {
|
return io.Schema(
|
||||||
"required": {
|
node_id='ADE_InjectI2VIntoAnimateDiffModel',
|
||||||
"model_name": (get_available_motion_models(),),
|
display_name='🧪Inject I2V into AnimateDiff Model 🎭🅐🅓②',
|
||||||
"motion_model": ("MOTION_MODEL_ADE",),
|
category='Animate Diff 🎭🅐🅓/② Gen2 nodes ②/AnimateLCM-I2V/🧪experimental',
|
||||||
},
|
inputs=[
|
||||||
"optional": {
|
io.Combo.Input('model_name', options=get_available_motion_models()),
|
||||||
"ad_settings": ("AD_SETTINGS",),
|
io.Custom("MOTION_MODEL_ADE").Input('motion_model'),
|
||||||
}
|
io.Custom("AD_SETTINGS").Input('ad_settings', optional=True),
|
||||||
}
|
],
|
||||||
|
outputs=[
|
||||||
|
io.Custom("MOTION_MODEL_ADE").Output('MOTION_MODEL'),
|
||||||
|
],
|
||||||
|
is_experimental=True,
|
||||||
|
)
|
||||||
|
|
||||||
RETURN_TYPES = ("MOTION_MODEL_ADE",)
|
|
||||||
RETURN_NAMES = ("MOTION_MODEL",)
|
|
||||||
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/② Gen2 nodes ②/AnimateLCM-I2V/🧪experimental"
|
|
||||||
FUNCTION = "load_motion_model"
|
|
||||||
|
|
||||||
def load_motion_model(self, model_name: str, motion_model: MotionModelPatcher, ad_settings: AnimateDiffSettings=None):
|
@classmethod
|
||||||
|
def execute(cls, model_name: str, motion_model: MotionModelPatcher, ad_settings: AnimateDiffSettings=None):
|
||||||
# make sure model w/ encoder actually has encoder
|
# make sure model w/ encoder actually has encoder
|
||||||
if motion_model.model.img_encoder is None:
|
if motion_model.model.img_encoder is None:
|
||||||
raise Exception("Passed-in motion model was expected to have an img_encoder, but did not.")
|
raise Exception("Passed-in motion model was expected to have an img_encoder, but did not.")
|
||||||
# load motion module and motion settings, if included
|
# load motion module and motion settings, if included
|
||||||
loaded_motion_model = load_motion_module_gen2(model_name=model_name, motion_model_settings=ad_settings)
|
loaded_motion_model = load_motion_module_gen2(model_name=model_name, motion_model_settings=ad_settings)
|
||||||
inject_img_encoder_into_model(motion_model=loaded_motion_model, w_encoder=motion_model)
|
inject_img_encoder_into_model(motion_model=loaded_motion_model, w_encoder=motion_model)
|
||||||
return (loaded_motion_model,)
|
return io.NodeOutput(loaded_motion_model,)
|
||||||
|
|
||||||
|
|
||||||
class UpscaleAndVaeEncode:
|
class UpscaleAndVaeEncode(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {
|
return io.Schema(
|
||||||
"required": {
|
node_id='ADE_UpscaleAndVAEEncode',
|
||||||
"image": ("IMAGE",),
|
display_name='Scale Ref Image and VAE Encode 🎭🅐🅓②',
|
||||||
"vae": ("VAE",),
|
category='Animate Diff 🎭🅐🅓/② Gen2 nodes ②/AnimateLCM-I2V',
|
||||||
"latent_size": ("LATENT",),
|
inputs=[
|
||||||
"scale_method": (ScaleMethods._LIST_IMAGE,),
|
io.Image.Input('image'),
|
||||||
"crop": (CropMethods._LIST, {"default": CropMethods.CENTER},),
|
io.Vae.Input('vae'),
|
||||||
}
|
io.Latent.Input('latent_size'),
|
||||||
}
|
io.Combo.Input('scale_method', options=['nearest-exact', 'bilinear', 'area', 'bicubic', 'lanczos']),
|
||||||
|
io.Combo.Input('crop', options=['disabled', 'center'], default='center'),
|
||||||
|
],
|
||||||
|
outputs=[
|
||||||
|
io.Latent.Output('LATENT'),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
RETURN_TYPES = ("LATENT",)
|
|
||||||
FUNCTION = "preprocess_images"
|
|
||||||
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/② Gen2 nodes ②/AnimateLCM-I2V"
|
|
||||||
|
|
||||||
def preprocess_images(self, image: torch.Tensor, vae: VAE, latent_size: torch.Tensor, scale_method: str, crop: str):
|
@classmethod
|
||||||
|
def execute(cls, image: torch.Tensor, vae: VAE, latent_size: torch.Tensor, scale_method: str, crop: str):
|
||||||
b, c, h, w = latent_size["samples"].size()
|
b, c, h, w = latent_size["samples"].size()
|
||||||
image = image.movedim(-1,1)
|
image = image.movedim(-1,1)
|
||||||
image = comfy.utils.common_upscale(samples=image, width=w*8, height=h*8, upscale_method=scale_method, crop=crop)
|
image = comfy.utils.common_upscale(samples=image, width=w*8, height=h*8, upscale_method=scale_method, crop=crop)
|
||||||
image = image.movedim(1,-1)
|
image = image.movedim(1,-1)
|
||||||
# now that images are the expected size, VAEEncode them
|
# now that images are the expected size, VAEEncode them
|
||||||
return ({"samples": vae_encode_raw_batched(vae, image)},)
|
return io.NodeOutput({"samples": vae_encode_raw_batched(vae, image)},)
|
||||||
|
|||||||
+236
-207
@@ -1,3 +1,4 @@
|
|||||||
|
from comfy_api.latest import io
|
||||||
from typing import Union
|
from typing import Union
|
||||||
import os
|
import os
|
||||||
import torch
|
import torch
|
||||||
@@ -218,38 +219,40 @@ def poses_to_ndarray(poses: list[list[float]]) -> np.ndarray:
|
|||||||
return RT
|
return RT
|
||||||
|
|
||||||
|
|
||||||
class ApplyAnimateDiffWithCameraCtrl:
|
class ApplyAnimateDiffWithCameraCtrl(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {
|
return io.Schema(
|
||||||
"required": {
|
node_id='ADE_ApplyAnimateDiffModelWithCameraCtrl',
|
||||||
"motion_model": ("MOTION_MODEL_ADE",),
|
display_name='Apply AnimateDiff+CameraCtrl Model 🎭🅐🅓②',
|
||||||
"cameractrl_poses": ("CAMERACTRL_POSES",),
|
category='Animate Diff 🎭🅐🅓/② Gen2 nodes ②/CameraCtrl',
|
||||||
"start_percent": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001}),
|
inputs=[
|
||||||
"end_percent": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.001}),
|
io.Custom("MOTION_MODEL_ADE").Input('motion_model'),
|
||||||
},
|
io.Custom("CAMERACTRL_POSES").Input('cameractrl_poses'),
|
||||||
"optional": {
|
io.Float.Input('start_percent', default=0.0, max=1.0, min=0.0, step=0.001),
|
||||||
"motion_lora": ("MOTION_LORA",),
|
io.Float.Input('end_percent', default=1.0, max=1.0, min=0.0, step=0.001),
|
||||||
"scale_multival": ("MULTIVAL",),
|
io.Custom("MOTION_LORA").Input('motion_lora', optional=True),
|
||||||
"effect_multival": ("MULTIVAL",),
|
io.Custom("MULTIVAL").Input('scale_multival', optional=True),
|
||||||
"cameractrl_multival": ("MULTIVAL",),
|
io.Custom("MULTIVAL").Input('effect_multival', optional=True),
|
||||||
"ad_keyframes": ("AD_KEYFRAMES",),
|
io.Custom("MULTIVAL").Input('cameractrl_multival', optional=True),
|
||||||
"prev_m_models": ("M_MODELS",),
|
io.Custom("AD_KEYFRAMES").Input('ad_keyframes', optional=True),
|
||||||
"per_block": ("PER_BLOCK",),
|
io.Custom("M_MODELS").Input('prev_m_models', optional=True),
|
||||||
}
|
io.Custom("PER_BLOCK").Input('per_block', optional=True),
|
||||||
}
|
],
|
||||||
|
outputs=[
|
||||||
|
io.Custom("M_MODELS").Output('M_MODELS'),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
RETURN_TYPES = ("M_MODELS",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/② Gen2 nodes ②/CameraCtrl"
|
|
||||||
FUNCTION = "apply_motion_model"
|
|
||||||
|
|
||||||
def apply_motion_model(self, motion_model: MotionModelPatcher, cameractrl_poses: list[list[float]], start_percent: float=0.0, end_percent: float=1.0,
|
@classmethod
|
||||||
|
def execute(cls, motion_model: MotionModelPatcher, cameractrl_poses: list[list[float]], start_percent: float=0.0, end_percent: float=1.0,
|
||||||
motion_lora: MotionLoraList=None, ad_keyframes: ADKeyframeGroup=None,
|
motion_lora: MotionLoraList=None, ad_keyframes: ADKeyframeGroup=None,
|
||||||
scale_multival=None, effect_multival=None, cameractrl_multival=None, per_block=None,
|
scale_multival=None, effect_multival=None, cameractrl_multival=None, per_block=None,
|
||||||
prev_m_models: MotionModelGroup=None,):
|
prev_m_models: MotionModelGroup=None,):
|
||||||
new_m_models = ApplyAnimateDiffModelNode.apply_motion_model(self, motion_model, start_percent=start_percent, end_percent=end_percent,
|
new_m_models = ApplyAnimateDiffModelNode.execute( motion_model, start_percent=start_percent, end_percent=end_percent,
|
||||||
motion_lora=motion_lora, ad_keyframes=ad_keyframes, per_block=per_block,
|
motion_lora=motion_lora, ad_keyframes=ad_keyframes, per_block=per_block,
|
||||||
scale_multival=scale_multival, effect_multival=effect_multival, prev_m_models=prev_m_models)
|
scale_multival=scale_multival, effect_multival=effect_multival, prev_m_models=prev_m_models).args
|
||||||
# most recent added model will always be first in list;
|
# most recent added model will always be first in list;
|
||||||
curr_model = new_m_models[0].models[0]
|
curr_model = new_m_models[0].models[0]
|
||||||
# confirm that model contains camera_encoder
|
# confirm that model contains camera_encoder
|
||||||
@@ -259,84 +262,88 @@ class ApplyAnimateDiffWithCameraCtrl:
|
|||||||
attachment = get_mm_attachment(curr_model)
|
attachment = get_mm_attachment(curr_model)
|
||||||
attachment.orig_camera_entries = camera_entries
|
attachment.orig_camera_entries = camera_entries
|
||||||
attachment.cameractrl_multival = cameractrl_multival
|
attachment.cameractrl_multival = cameractrl_multival
|
||||||
return new_m_models
|
return io.NodeOutput(*new_m_models)
|
||||||
|
|
||||||
|
|
||||||
class LoadAnimateDiffModelWithCameraCtrl:
|
class LoadAnimateDiffModelWithCameraCtrl(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {
|
return io.Schema(
|
||||||
"required": {
|
node_id='ADE_LoadAnimateDiffModelWithCameraCtrl',
|
||||||
"model_name": (get_available_motion_models(),),
|
display_name='Load AnimateDiff+CameraCtrl Model 🎭🅐🅓②',
|
||||||
"camera_ctrl": (get_available_motion_models(),),
|
category='Animate Diff 🎭🅐🅓/② Gen2 nodes ②/CameraCtrl',
|
||||||
},
|
inputs=[
|
||||||
"optional": {
|
io.Combo.Input('model_name', options=get_available_motion_models()),
|
||||||
"ad_settings": ("AD_SETTINGS",),
|
io.Combo.Input('camera_ctrl', options=get_available_motion_models()),
|
||||||
}
|
io.Custom("AD_SETTINGS").Input('ad_settings', optional=True),
|
||||||
}
|
],
|
||||||
|
outputs=[
|
||||||
|
io.Custom("MOTION_MODEL_ADE").Output('MOTION_MODEL'),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
RETURN_TYPES = ("MOTION_MODEL_ADE",)
|
|
||||||
RETURN_NAMES = ("MOTION_MODEL",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/② Gen2 nodes ②/CameraCtrl"
|
|
||||||
FUNCTION = "load_camera_ctrl"
|
|
||||||
|
|
||||||
def load_camera_ctrl(self, model_name: str, camera_ctrl: str, ad_settings: AnimateDiffSettings=None):
|
@classmethod
|
||||||
|
def execute(cls, model_name: str, camera_ctrl: str, ad_settings: AnimateDiffSettings=None):
|
||||||
loaded_motion_model = load_motion_module_gen2(model_name=model_name, motion_model_settings=ad_settings)
|
loaded_motion_model = load_motion_module_gen2(model_name=model_name, motion_model_settings=ad_settings)
|
||||||
inject_camera_encoder_into_model(motion_model=loaded_motion_model, camera_ctrl_name=camera_ctrl)
|
inject_camera_encoder_into_model(motion_model=loaded_motion_model, camera_ctrl_name=camera_ctrl)
|
||||||
return (loaded_motion_model,)
|
return io.NodeOutput(loaded_motion_model,)
|
||||||
|
|
||||||
|
|
||||||
class CameraCtrlADKeyframeNode:
|
class CameraCtrlADKeyframeNode(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {
|
return io.Schema(
|
||||||
"required": {
|
node_id='ADE_CameraCtrlAnimateDiffKeyframe',
|
||||||
"start_percent": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001}, ),
|
display_name='AnimateDiff+CameraCtrl Keyframe 🎭🅐🅓',
|
||||||
},
|
category='Animate Diff 🎭🅐🅓/② Gen2 nodes ②/CameraCtrl',
|
||||||
"optional": {
|
inputs=[
|
||||||
"prev_ad_keyframes": ("AD_KEYFRAMES", ),
|
io.Float.Input('start_percent', default=0.0, max=1.0, min=0.0, step=0.001),
|
||||||
"scale_multival": ("MULTIVAL",),
|
io.Custom("AD_KEYFRAMES").Input('prev_ad_keyframes', optional=True),
|
||||||
"effect_multival": ("MULTIVAL",),
|
io.Custom("MULTIVAL").Input('scale_multival', optional=True),
|
||||||
"cameractrl_multival": ("MULTIVAL",),
|
io.Custom("MULTIVAL").Input('effect_multival', optional=True),
|
||||||
"inherit_missing": ("BOOLEAN", {"default": True}, ),
|
io.Custom("MULTIVAL").Input('cameractrl_multival', optional=True),
|
||||||
"guarantee_steps": ("INT", {"default": 1, "min": 0, "max": BIGMAX}),
|
io.Boolean.Input('inherit_missing', optional=True, default=True),
|
||||||
},
|
io.Int.Input('guarantee_steps', optional=True, default=1, max=9007199254740991, min=0),
|
||||||
}
|
],
|
||||||
|
outputs=[
|
||||||
|
io.Custom("AD_KEYFRAMES").Output('AD_KEYFRAMES'),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
RETURN_TYPES = ("AD_KEYFRAMES", )
|
|
||||||
FUNCTION = "load_keyframe"
|
|
||||||
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/② Gen2 nodes ②/CameraCtrl"
|
|
||||||
|
|
||||||
def load_keyframe(self,
|
@classmethod
|
||||||
|
def execute(cls,
|
||||||
start_percent: float, prev_ad_keyframes=None,
|
start_percent: float, prev_ad_keyframes=None,
|
||||||
scale_multival: Union[float, torch.Tensor]=None, effect_multival: Union[float, torch.Tensor]=None,
|
scale_multival: Union[float, torch.Tensor]=None, effect_multival: Union[float, torch.Tensor]=None,
|
||||||
cameractrl_multival: Union[float, torch.Tensor]=None,
|
cameractrl_multival: Union[float, torch.Tensor]=None,
|
||||||
inherit_missing: bool=True, guarantee_steps: int=1):
|
inherit_missing: bool=True, guarantee_steps: int=1):
|
||||||
return ADKeyframeNode.load_keyframe(self,
|
return io.NodeOutput(*ADKeyframeNode.execute(
|
||||||
start_percent=start_percent, prev_ad_keyframes=prev_ad_keyframes,
|
start_percent=start_percent, prev_ad_keyframes=prev_ad_keyframes,
|
||||||
scale_multival=scale_multival, effect_multival=effect_multival, cameractrl_multival=cameractrl_multival,
|
scale_multival=scale_multival, effect_multival=effect_multival, cameractrl_multival=cameractrl_multival,
|
||||||
inherit_missing=inherit_missing, guarantee_steps=guarantee_steps
|
inherit_missing=inherit_missing, guarantee_steps=guarantee_steps
|
||||||
|
).args)
|
||||||
|
|
||||||
|
|
||||||
|
class LoadCameraPosesFromFile(io.ComfyNode):
|
||||||
|
@classmethod
|
||||||
|
def define_schema(cls) -> io.Schema:
|
||||||
|
return io.Schema(
|
||||||
|
node_id='ADE_LoadCameraPoses',
|
||||||
|
display_name='Load CameraCtrl Poses (File) 🎭🅐🅓②',
|
||||||
|
category='Animate Diff 🎭🅐🅓/② Gen2 nodes ②/CameraCtrl/poses',
|
||||||
|
inputs=[
|
||||||
|
io.Combo.Input('pose_filename', options=sorted(f for f in os.listdir(folder_paths.get_input_directory()) if os.path.isfile(os.path.join(folder_paths.get_input_directory(), f)) and f.endswith(".txt"))),
|
||||||
|
],
|
||||||
|
outputs=[
|
||||||
|
io.Custom("CAMERACTRL_POSES").Output('CAMERACTRL_POSES'),
|
||||||
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class LoadCameraPosesFromFile:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def execute(cls, pose_filename: str):
|
||||||
input_dir = folder_paths.get_input_directory()
|
|
||||||
files = [f for f in os.listdir(input_dir) if os.path.isfile(os.path.join(input_dir, f))]
|
|
||||||
files = [f for f in files if f.endswith(".txt")]
|
|
||||||
return {
|
|
||||||
"required": {
|
|
||||||
"pose_filename": (sorted(files),),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("CAMERACTRL_POSES",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/② Gen2 nodes ②/CameraCtrl/poses"
|
|
||||||
FUNCTION = "load_camera_poses"
|
|
||||||
|
|
||||||
def load_camera_poses(self, pose_filename: str):
|
|
||||||
file_path = folder_paths.get_annotated_filepath(pose_filename)
|
file_path = folder_paths.get_annotated_filepath(pose_filename)
|
||||||
with open(file_path, 'r') as f:
|
with open(file_path, 'r') as f:
|
||||||
poses = f.readlines()
|
poses = f.readlines()
|
||||||
@@ -345,36 +352,40 @@ class LoadCameraPosesFromFile:
|
|||||||
poses = [pose.strip().split(' ') for pose in poses[1:]]
|
poses = [pose.strip().split(' ') for pose in poses[1:]]
|
||||||
poses = [[float(x) for x in pose] for pose in poses]
|
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)
|
poses = set_original_pose_dims(poses, pose_width=CAM.DEFAULT_POSE_WIDTH, pose_height=CAM.DEFAULT_POSE_HEIGHT)
|
||||||
return (poses,)
|
return io.NodeOutput(poses,)
|
||||||
|
|
||||||
|
|
||||||
class LoadCameraPosesFromPath:
|
class LoadCameraPosesFromPath(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {
|
return io.Schema(
|
||||||
"optional": {
|
node_id='ADE_LoadCameraPosesFromPath',
|
||||||
"file_path": ("STRING", {"default": "X://path/to/pose_file.txt"}),
|
display_name='Load CameraCtrl Poses (Path) 🎭🅐🅓②',
|
||||||
}
|
category='Animate Diff 🎭🅐🅓/② Gen2 nodes ②/CameraCtrl/poses',
|
||||||
}
|
inputs=[
|
||||||
|
io.String.Input('file_path', optional=True, default='X://path/to/pose_file.txt'),
|
||||||
|
],
|
||||||
|
outputs=[
|
||||||
|
io.Custom("CAMERACTRL_POSES").Output('CAMERACTRL_POSES'),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def IS_CHANGED(s, file_path, **kwargs):
|
def fingerprint_inputs(cls, file_path, **kwargs):
|
||||||
if Path(file_path).is_file():
|
if Path(file_path).is_file():
|
||||||
return calculate_file_hash(strip_path(file_path))
|
return calculate_file_hash(strip_path(file_path))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def VALIDATE_INPUTS(s, file_path, **kwargs):
|
def validate_inputs(cls, file_path, **kwargs):
|
||||||
# This function never gets ran for some reason, I don't care enough to figure out why right now.
|
# 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():
|
if not Path(strip_path(file_path)).is_file():
|
||||||
return f"Pose file not found: {file_path}"
|
return f"Pose file not found: {file_path}"
|
||||||
return True
|
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):
|
@classmethod
|
||||||
|
def execute(cls, file_path: str):
|
||||||
file_path = strip_path(file_path)
|
file_path = strip_path(file_path)
|
||||||
if not Path(file_path).is_file():
|
if not Path(file_path).is_file():
|
||||||
raise Exception(f"Pose file not found: {file_path}")
|
raise Exception(f"Pose file not found: {file_path}")
|
||||||
@@ -385,60 +396,64 @@ class LoadCameraPosesFromPath:
|
|||||||
poses = [pose.strip().split(' ') for pose in poses[1:]]
|
poses = [pose.strip().split(' ') for pose in poses[1:]]
|
||||||
poses = [[float(x) for x in pose] for pose in poses]
|
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)
|
poses = set_original_pose_dims(poses, pose_width=CAM.DEFAULT_POSE_WIDTH, pose_height=CAM.DEFAULT_POSE_HEIGHT)
|
||||||
return (poses,)
|
return io.NodeOutput(poses,)
|
||||||
|
|
||||||
|
|
||||||
class CameraCtrlPoseBasic:
|
class CameraCtrlPoseBasic(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(cls):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {
|
return io.Schema(
|
||||||
"required": {
|
node_id='ADE_CameraPoseBasic',
|
||||||
"motion_type": (CAM._LIST,),
|
display_name='Create CameraCtrl Poses 🎭🅐🅓②',
|
||||||
"speed": ("FLOAT", {"default": 1.0, "min": -100.0, "max": 100.0, "step": 0.01}),
|
category='Animate Diff 🎭🅐🅓/② Gen2 nodes ②/CameraCtrl/poses',
|
||||||
"frame_length": ("INT", {"default": 16}),
|
inputs=[
|
||||||
},
|
io.Combo.Input('motion_type', options=['Static', 'Pan Up', 'Pan Down', 'Pan Left', 'Pan Right', 'Zoom In', 'Zoom Out', 'Roll Clockwise', 'Roll Anticlockwise', 'Tilt Down', 'Tilt Up', 'Tilt Left', 'Tilt Right']),
|
||||||
"optional": {
|
io.Float.Input('speed', default=1.0, max=100.0, min=-100.0, step=0.01),
|
||||||
"prev_poses": ("CAMERACTRL_POSES",),
|
io.Int.Input('frame_length', default=16),
|
||||||
},
|
io.Custom("CAMERACTRL_POSES").Input('prev_poses', optional=True),
|
||||||
}
|
],
|
||||||
|
outputs=[
|
||||||
|
io.Custom("CAMERACTRL_POSES").Output('CAMERACTRL_POSES'),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
RETURN_TYPES = ("CAMERACTRL_POSES",)
|
|
||||||
FUNCTION = "camera_pose_basic"
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/② Gen2 nodes ②/CameraCtrl/poses"
|
|
||||||
|
|
||||||
def camera_pose_basic(self, motion_type: str, speed: float, frame_length: int, prev_poses: list[list[float]]=None):
|
@classmethod
|
||||||
|
def execute(cls, motion_type: str, speed: float, frame_length: int, prev_poses: list[list[float]]=None):
|
||||||
motion = CAM.get(motion_type)
|
motion = CAM.get(motion_type)
|
||||||
RT = get_camera_motion(motion.rotate, motion.translate, speed, frame_length)
|
RT = get_camera_motion(motion.rotate, motion.translate, speed, frame_length)
|
||||||
new_motion = ndarray_to_poses(RT=RT)
|
new_motion = ndarray_to_poses(RT=RT)
|
||||||
if prev_poses is not None:
|
if prev_poses is not None:
|
||||||
new_motion = combine_poses(prev_poses, new_motion)
|
new_motion = combine_poses(prev_poses, new_motion)
|
||||||
return (new_motion,)
|
return io.NodeOutput(new_motion,)
|
||||||
|
|
||||||
|
|
||||||
class CameraCtrlPoseCombo:
|
class CameraCtrlPoseCombo(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(cls):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {
|
return io.Schema(
|
||||||
"required": {
|
node_id='ADE_CameraPoseCombo',
|
||||||
"motion_type1": (CAM._LIST,),
|
display_name='Create CameraCtrl Poses (Combo) 🎭🅐🅓②',
|
||||||
"motion_type2": (CAM._LIST,),
|
category='Animate Diff 🎭🅐🅓/② Gen2 nodes ②/CameraCtrl/poses',
|
||||||
"motion_type3": (CAM._LIST,),
|
inputs=[
|
||||||
"motion_type4": (CAM._LIST,),
|
io.Combo.Input('motion_type1', options=['Static', 'Pan Up', 'Pan Down', 'Pan Left', 'Pan Right', 'Zoom In', 'Zoom Out', 'Roll Clockwise', 'Roll Anticlockwise', 'Tilt Down', 'Tilt Up', 'Tilt Left', 'Tilt Right']),
|
||||||
"motion_type5": (CAM._LIST,),
|
io.Combo.Input('motion_type2', options=['Static', 'Pan Up', 'Pan Down', 'Pan Left', 'Pan Right', 'Zoom In', 'Zoom Out', 'Roll Clockwise', 'Roll Anticlockwise', 'Tilt Down', 'Tilt Up', 'Tilt Left', 'Tilt Right']),
|
||||||
"motion_type6": (CAM._LIST,),
|
io.Combo.Input('motion_type3', options=['Static', 'Pan Up', 'Pan Down', 'Pan Left', 'Pan Right', 'Zoom In', 'Zoom Out', 'Roll Clockwise', 'Roll Anticlockwise', 'Tilt Down', 'Tilt Up', 'Tilt Left', 'Tilt Right']),
|
||||||
"speed": ("FLOAT", {"default": 1.0, "min": -100.0, "max": 100.0, "step": 0.01}),
|
io.Combo.Input('motion_type4', options=['Static', 'Pan Up', 'Pan Down', 'Pan Left', 'Pan Right', 'Zoom In', 'Zoom Out', 'Roll Clockwise', 'Roll Anticlockwise', 'Tilt Down', 'Tilt Up', 'Tilt Left', 'Tilt Right']),
|
||||||
"frame_length": ("INT", {"default": 16}),
|
io.Combo.Input('motion_type5', options=['Static', 'Pan Up', 'Pan Down', 'Pan Left', 'Pan Right', 'Zoom In', 'Zoom Out', 'Roll Clockwise', 'Roll Anticlockwise', 'Tilt Down', 'Tilt Up', 'Tilt Left', 'Tilt Right']),
|
||||||
},
|
io.Combo.Input('motion_type6', options=['Static', 'Pan Up', 'Pan Down', 'Pan Left', 'Pan Right', 'Zoom In', 'Zoom Out', 'Roll Clockwise', 'Roll Anticlockwise', 'Tilt Down', 'Tilt Up', 'Tilt Left', 'Tilt Right']),
|
||||||
"optional": {
|
io.Float.Input('speed', default=1.0, max=100.0, min=-100.0, step=0.01),
|
||||||
"prev_poses": ("CAMERACTRL_POSES",),
|
io.Int.Input('frame_length', default=16),
|
||||||
}
|
io.Custom("CAMERACTRL_POSES").Input('prev_poses', optional=True),
|
||||||
}
|
],
|
||||||
|
outputs=[
|
||||||
|
io.Custom("CAMERACTRL_POSES").Output('CAMERACTRL_POSES'),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
RETURN_TYPES = ("CAMERACTRL_POSES",)
|
|
||||||
FUNCTION = "camera_pose_combo"
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/② Gen2 nodes ②/CameraCtrl/poses"
|
|
||||||
|
|
||||||
def camera_pose_combo(self,
|
@classmethod
|
||||||
|
def execute(cls,
|
||||||
motion_type1: str, motion_type2: str, motion_type3: str,
|
motion_type1: str, motion_type2: str, motion_type3: str,
|
||||||
motion_type4: str, motion_type5: str, motion_type6: str,
|
motion_type4: str, motion_type5: str, motion_type6: str,
|
||||||
speed: float, frame_length: int,
|
speed: float, frame_length: int,
|
||||||
@@ -452,88 +467,98 @@ class CameraCtrlPoseCombo:
|
|||||||
new_motion = ndarray_to_poses(RT=RT)
|
new_motion = ndarray_to_poses(RT=RT)
|
||||||
if prev_poses is not None:
|
if prev_poses is not None:
|
||||||
new_motion = combine_poses(prev_poses, new_motion)
|
new_motion = combine_poses(prev_poses, new_motion)
|
||||||
return (new_motion,)
|
return io.NodeOutput(new_motion,)
|
||||||
|
|
||||||
|
|
||||||
class CameraCtrlPoseAdvanced:
|
class CameraCtrlPoseAdvanced(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(cls):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {
|
return io.Schema(
|
||||||
"required": {
|
node_id='ADE_CameraPoseAdvanced',
|
||||||
"motion_type1": (CAM._LIST,),
|
display_name='Create CameraCtrl Poses (Adv.) 🎭🅐🅓②',
|
||||||
"strength1": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.01}),
|
category='Animate Diff 🎭🅐🅓/② Gen2 nodes ②/CameraCtrl/poses',
|
||||||
"motion_type2": (CAM._LIST,),
|
inputs=[
|
||||||
"strength2": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.01}),
|
io.Combo.Input('motion_type1', options=['Static', 'Pan Up', 'Pan Down', 'Pan Left', 'Pan Right', 'Zoom In', 'Zoom Out', 'Roll Clockwise', 'Roll Anticlockwise', 'Tilt Down', 'Tilt Up', 'Tilt Left', 'Tilt Right']),
|
||||||
"motion_type3": (CAM._LIST,),
|
io.Float.Input('strength1', default=1.0, max=10.0, min=0.0, step=0.01),
|
||||||
"strength3": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.01}),
|
io.Combo.Input('motion_type2', options=['Static', 'Pan Up', 'Pan Down', 'Pan Left', 'Pan Right', 'Zoom In', 'Zoom Out', 'Roll Clockwise', 'Roll Anticlockwise', 'Tilt Down', 'Tilt Up', 'Tilt Left', 'Tilt Right']),
|
||||||
"motion_type4": (CAM._LIST,),
|
io.Float.Input('strength2', default=1.0, max=10.0, min=0.0, step=0.01),
|
||||||
"strength4": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.01}),
|
io.Combo.Input('motion_type3', options=['Static', 'Pan Up', 'Pan Down', 'Pan Left', 'Pan Right', 'Zoom In', 'Zoom Out', 'Roll Clockwise', 'Roll Anticlockwise', 'Tilt Down', 'Tilt Up', 'Tilt Left', 'Tilt Right']),
|
||||||
"motion_type5": (CAM._LIST,),
|
io.Float.Input('strength3', default=1.0, max=10.0, min=0.0, step=0.01),
|
||||||
"strength5": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.01}),
|
io.Combo.Input('motion_type4', options=['Static', 'Pan Up', 'Pan Down', 'Pan Left', 'Pan Right', 'Zoom In', 'Zoom Out', 'Roll Clockwise', 'Roll Anticlockwise', 'Tilt Down', 'Tilt Up', 'Tilt Left', 'Tilt Right']),
|
||||||
"motion_type6": (CAM._LIST,),
|
io.Float.Input('strength4', default=1.0, max=10.0, min=0.0, step=0.01),
|
||||||
"strength6": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.01}),
|
io.Combo.Input('motion_type5', options=['Static', 'Pan Up', 'Pan Down', 'Pan Left', 'Pan Right', 'Zoom In', 'Zoom Out', 'Roll Clockwise', 'Roll Anticlockwise', 'Tilt Down', 'Tilt Up', 'Tilt Left', 'Tilt Right']),
|
||||||
"speed": ("FLOAT", {"default": 1.0, "min": -100.0, "max": 100.0, "step": 0.01}),
|
io.Float.Input('strength5', default=1.0, max=10.0, min=0.0, step=0.01),
|
||||||
"frame_length": ("INT", {"default": 16}),
|
io.Combo.Input('motion_type6', options=['Static', 'Pan Up', 'Pan Down', 'Pan Left', 'Pan Right', 'Zoom In', 'Zoom Out', 'Roll Clockwise', 'Roll Anticlockwise', 'Tilt Down', 'Tilt Up', 'Tilt Left', 'Tilt Right']),
|
||||||
},
|
io.Float.Input('strength6', default=1.0, max=10.0, min=0.0, step=0.01),
|
||||||
"optional": {
|
io.Float.Input('speed', default=1.0, max=100.0, min=-100.0, step=0.01),
|
||||||
"prev_poses": ("CAMERACTRL_POSES",),
|
io.Int.Input('frame_length', default=16),
|
||||||
}
|
io.Custom("CAMERACTRL_POSES").Input('prev_poses', optional=True),
|
||||||
}
|
],
|
||||||
|
outputs=[
|
||||||
|
io.Custom("CAMERACTRL_POSES").Output('CAMERACTRL_POSES'),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
RETURN_TYPES = ("CAMERACTRL_POSES",)
|
|
||||||
FUNCTION = "camera_pose_combo"
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/② Gen2 nodes ②/CameraCtrl/poses"
|
|
||||||
|
|
||||||
def camera_pose_combo(self,
|
@classmethod
|
||||||
|
def execute(cls,
|
||||||
motion_type1: str, motion_type2: str, motion_type3: str,
|
motion_type1: str, motion_type2: str, motion_type3: str,
|
||||||
motion_type4: str, motion_type5: str, motion_type6: str,
|
motion_type4: str, motion_type5: str, motion_type6: str,
|
||||||
speed: float, frame_length: int,
|
speed: float, frame_length: int,
|
||||||
prev_poses: list[list[float]]=None,
|
prev_poses: list[list[float]]=None,
|
||||||
strength1=1.0, strength2=1.0, strength3=1.0, strength4=1.0, strength5=1.0, strength6=1.0):
|
strength1=1.0, strength2=1.0, strength3=1.0, strength4=1.0, strength5=1.0, strength6=1.0):
|
||||||
return CameraCtrlPoseCombo.camera_pose_combo(self,
|
return io.NodeOutput(*CameraCtrlPoseCombo.execute(
|
||||||
motion_type1=motion_type1, motion_type2=motion_type2, motion_type3=motion_type3,
|
motion_type1=motion_type1, motion_type2=motion_type2, motion_type3=motion_type3,
|
||||||
motion_type4=motion_type4, motion_type5=motion_type5, motion_type6=motion_type6,
|
motion_type4=motion_type4, motion_type5=motion_type5, motion_type6=motion_type6,
|
||||||
speed=speed, frame_length=frame_length, prev_poses=prev_poses,
|
speed=speed, frame_length=frame_length, prev_poses=prev_poses,
|
||||||
strength1=strength1, strength2=strength2, strength3=strength3,
|
strength1=strength1, strength2=strength2, strength3=strength3,
|
||||||
strength4=strength4, strength5=strength5, strength6=strength6)
|
strength4=strength4, strength5=strength5, strength6=strength6).args)
|
||||||
|
|
||||||
|
|
||||||
class CameraCtrlManualAppendPose:
|
class CameraCtrlManualAppendPose(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(cls):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {
|
return io.Schema(
|
||||||
"required": {
|
node_id='ADE_CameraManualPoseAppend',
|
||||||
"poses_first": ("CAMERACTRL_POSES",),
|
display_name='Manual Append CameraCtrl Poses 🎭🅐🅓②',
|
||||||
"poses_last": ("CAMERACTRL_POSES",),
|
category='Animate Diff 🎭🅐🅓/② Gen2 nodes ②/CameraCtrl/poses',
|
||||||
}
|
inputs=[
|
||||||
}
|
io.Custom("CAMERACTRL_POSES").Input('poses_first'),
|
||||||
|
io.Custom("CAMERACTRL_POSES").Input('poses_last'),
|
||||||
RETURN_TYPES = ("CAMERACTRL_POSES",)
|
],
|
||||||
FUNCTION = "camera_manual_append"
|
outputs=[
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/② Gen2 nodes ②/CameraCtrl/poses"
|
io.Custom("CAMERACTRL_POSES").Output('CAMERACTRL_POSES'),
|
||||||
|
],
|
||||||
def camera_manual_append(self, poses_first: list[list[float]], poses_last: list[list[float]]):
|
)
|
||||||
return (combine_poses(poses0=poses_first, poses1=poses_last),)
|
|
||||||
|
|
||||||
|
|
||||||
class CameraCtrlReplaceCameraParameters:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(cls):
|
def execute(cls, poses_first: list[list[float]], poses_last: list[list[float]]):
|
||||||
return {
|
return io.NodeOutput(combine_poses(poses0=poses_first, poses1=poses_last),)
|
||||||
"required": {
|
|
||||||
"poses":("CAMERACTRL_POSES",),
|
|
||||||
"fx": ("FLOAT", {"default": CAM.DEFAULT_FX, "min": 0, "max": 1, "step": 0.000000001}),
|
|
||||||
"fy": ("FLOAT", {"default": CAM.DEFAULT_FY, "min": 0, "max": 1, "step": 0.000000001}),
|
|
||||||
"cx": ("FLOAT", {"default": CAM.DEFAULT_CX, "min": 0, "max": 1, "step": 0.01}),
|
|
||||||
"cy": ("FLOAT", {"default": CAM.DEFAULT_CY, "min": 0, "max": 1, "step": 0.01}),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("CAMERACTRL_POSES",)
|
|
||||||
FUNCTION = "set_camera_parameters"
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/② Gen2 nodes ②/CameraCtrl/poses"
|
|
||||||
|
|
||||||
def set_camera_parameters(self, poses: list[list[float]], fx: float, fy: float, cx: float, cy: float):
|
class CameraCtrlReplaceCameraParameters(io.ComfyNode):
|
||||||
|
@classmethod
|
||||||
|
def define_schema(cls) -> io.Schema:
|
||||||
|
return io.Schema(
|
||||||
|
node_id='ADE_ReplaceCameraParameters',
|
||||||
|
display_name='Replace Camera Parameters 🎭🅐🅓②',
|
||||||
|
category='Animate Diff 🎭🅐🅓/② Gen2 nodes ②/CameraCtrl/poses',
|
||||||
|
inputs=[
|
||||||
|
io.Custom("CAMERACTRL_POSES").Input('poses'),
|
||||||
|
io.Float.Input('fx', default=0.474812461, max=1, min=0, step=1e-09),
|
||||||
|
io.Float.Input('fy', default=0.844111024, max=1, min=0, step=1e-09),
|
||||||
|
io.Float.Input('cx', default=0.5, max=1, min=0, step=0.01),
|
||||||
|
io.Float.Input('cy', default=0.5, max=1, min=0, step=0.01),
|
||||||
|
],
|
||||||
|
outputs=[
|
||||||
|
io.Custom("CAMERACTRL_POSES").Output('CAMERACTRL_POSES'),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def execute(cls, poses: list[list[float]], fx: float, fy: float, cx: float, cy: float):
|
||||||
new_poses = copy.deepcopy(poses)
|
new_poses = copy.deepcopy(poses)
|
||||||
for pose in new_poses:
|
for pose in new_poses:
|
||||||
# fx,fy,cx,fy are in indexes 1-4 of the 19-long pose list
|
# fx,fy,cx,fy are in indexes 1-4 of the 19-long pose list
|
||||||
@@ -541,23 +566,27 @@ class CameraCtrlReplaceCameraParameters:
|
|||||||
pose[2] = fy
|
pose[2] = fy
|
||||||
pose[3] = cx
|
pose[3] = cx
|
||||||
pose[4] = cy
|
pose[4] = cy
|
||||||
return (new_poses,)
|
return io.NodeOutput(new_poses,)
|
||||||
|
|
||||||
|
|
||||||
class CameraCtrlSetOriginalAspectRatio:
|
class CameraCtrlSetOriginalAspectRatio(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(cls):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {
|
return io.Schema(
|
||||||
"required": {
|
node_id='ADE_ReplaceOriginalPoseAspectRatio',
|
||||||
"poses":("CAMERACTRL_POSES",),
|
display_name='Replace Orig. Pose Aspect Ratio 🎭🅐🅓②',
|
||||||
"orig_pose_width": ("INT", {"default": 1280, "min": 1, "max": BIGMAX}),
|
category='Animate Diff 🎭🅐🅓/② Gen2 nodes ②/CameraCtrl/poses',
|
||||||
"orig_pose_height": ("INT", {"default": 720, "min": 1, "max": BIGMAX}),
|
inputs=[
|
||||||
}
|
io.Custom("CAMERACTRL_POSES").Input('poses'),
|
||||||
}
|
io.Int.Input('orig_pose_width', default=1280, max=9007199254740991, min=1),
|
||||||
|
io.Int.Input('orig_pose_height', default=720, max=9007199254740991, min=1),
|
||||||
|
],
|
||||||
|
outputs=[
|
||||||
|
io.Custom("CAMERACTRL_POSES").Output('CAMERACTRL_POSES'),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
RETURN_TYPES = ("CAMERACTRL_POSES",)
|
|
||||||
FUNCTION = "set_aspect_ratio"
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/② Gen2 nodes ②/CameraCtrl/poses"
|
|
||||||
|
|
||||||
def set_aspect_ratio(self, poses: list[list[float]], orig_pose_width: int, orig_pose_height: int):
|
@classmethod
|
||||||
return (set_original_pose_dims(poses, pose_width=orig_pose_width, pose_height=orig_pose_height),)
|
def execute(cls, poses: list[list[float]], orig_pose_width: int, orig_pose_height: int):
|
||||||
|
return io.NodeOutput(set_original_pose_dims(poses, pose_width=orig_pose_width, pose_height=orig_pose_height),)
|
||||||
|
|||||||
+183
-546
@@ -1,9 +1,9 @@
|
|||||||
|
from comfy_api.latest import io
|
||||||
import uuid
|
import uuid
|
||||||
import folder_paths
|
import folder_paths
|
||||||
from typing import Union
|
from typing import Union
|
||||||
from torch import Tensor
|
from torch import Tensor
|
||||||
from collections.abc import Iterable
|
from collections.abc import Iterable
|
||||||
|
|
||||||
from comfy.model_patcher import ModelPatcher
|
from comfy.model_patcher import ModelPatcher
|
||||||
from comfy.sd import CLIP
|
from comfy.sd import CLIP
|
||||||
import comfy.sd
|
import comfy.sd
|
||||||
@@ -11,60 +11,28 @@ from comfy.hooks import HookGroup, HookKeyframeGroup, HookKeyframe
|
|||||||
import comfy_extras.nodes_hooks
|
import comfy_extras.nodes_hooks
|
||||||
import comfy.hooks
|
import comfy.hooks
|
||||||
import comfy.utils
|
import comfy.utils
|
||||||
|
|
||||||
from .utils_model import BIGMAX, InterpolationMethod
|
from .utils_model import BIGMAX, InterpolationMethod
|
||||||
from .logger import logger
|
from .logger import logger
|
||||||
|
|
||||||
|
|
||||||
###################################################################
|
|
||||||
# EVERYTHING BELOW HERE IS DEPRECATED;
|
|
||||||
# Can be replaced with vanilla ComfyUI nodes
|
|
||||||
#------------------------------------------------------------------
|
|
||||||
#------------------------------------------------------------------
|
|
||||||
#------------------------------------------------------------------
|
|
||||||
#------------------------------------------------------------------
|
|
||||||
#------------------------------------------------------------------
|
|
||||||
class COND_CONST:
|
class COND_CONST:
|
||||||
COND_AREA_DEFAULT = "default"
|
COND_AREA_DEFAULT = 'default'
|
||||||
COND_AREA_MASK_BOUNDS = "mask bounds"
|
COND_AREA_MASK_BOUNDS = 'mask bounds'
|
||||||
_LIST_COND_AREA = [COND_AREA_DEFAULT, COND_AREA_MASK_BOUNDS]
|
_LIST_COND_AREA = [COND_AREA_DEFAULT, COND_AREA_MASK_BOUNDS]
|
||||||
|
|
||||||
|
class CreateLoraHookKeyframeInterpolationDEPR(io.ComfyNode):
|
||||||
|
|
||||||
class CreateLoraHookKeyframeInterpolationDEPR:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls):
|
||||||
return {
|
return io.Schema(node_id='ADE_LoraHookKeyframeInterpolation', display_name='LoRA Hook Keyframes Interp. 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/conditioning/schedule lora hooks', inputs=[io.Float.Input('start_percent', default=0.0, max=1.0, min=0.0, step=0.001), io.Float.Input('end_percent', default=1.0, max=1.0, min=0.0, step=0.001), io.Float.Input('strength_start', default=1.0, max=10.0, min=0.0, step=0.001), io.Float.Input('strength_end', default=1.0, max=10.0, min=0.0, step=0.001), io.Combo.Input('interpolation', options=['linear', 'ease_in', 'ease_out', 'ease_in_out']), io.Int.Input('intervals', default=5, max=100, min=2, step=1), io.Boolean.Input('print_keyframes', default=False), io.Custom('HOOK_KEYFRAMES').Input('prev_hook_kf', optional=True)], outputs=[io.Custom('HOOK_KEYFRAMES').Output('HOOK_KF')], is_deprecated=True)
|
||||||
"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}),
|
|
||||||
"strength_start": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ),
|
|
||||||
"strength_end": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ),
|
|
||||||
"interpolation": (InterpolationMethod._LIST, ),
|
|
||||||
"intervals": ("INT", {"default": 5, "min": 2, "max": 100, "step": 1}),
|
|
||||||
"print_keyframes": ("BOOLEAN", {"default": False}),
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"prev_hook_kf": ("HOOK_KEYFRAMES",),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
DEPRECATED = True
|
@classmethod
|
||||||
RETURN_TYPES = ("HOOK_KEYFRAMES",)
|
def execute(cls, start_percent: float, end_percent: float, strength_start: float, strength_end: float, interpolation: str, intervals: int, prev_hook_kf: HookKeyframeGroup=None, print_keyframes=False):
|
||||||
RETURN_NAMES = ("HOOK_KF",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/conditioning/schedule lora hooks"
|
|
||||||
FUNCTION = "create_hook_keyframes"
|
|
||||||
|
|
||||||
def create_hook_keyframes(self,
|
|
||||||
start_percent: float, end_percent: float,
|
|
||||||
strength_start: float, strength_end: float, interpolation: str, intervals: int,
|
|
||||||
prev_hook_kf: HookKeyframeGroup=None, print_keyframes=False):
|
|
||||||
if prev_hook_kf:
|
if prev_hook_kf:
|
||||||
prev_hook_kf = prev_hook_kf.clone()
|
prev_hook_kf = prev_hook_kf.clone()
|
||||||
else:
|
else:
|
||||||
prev_hook_kf = HookKeyframeGroup()
|
prev_hook_kf = HookKeyframeGroup()
|
||||||
percents = InterpolationMethod.get_weights(num_from=start_percent, num_to=end_percent, length=intervals, method=InterpolationMethod.LINEAR)
|
percents = InterpolationMethod.get_weights(num_from=start_percent, num_to=end_percent, length=intervals, method=InterpolationMethod.LINEAR)
|
||||||
strengths = InterpolationMethod.get_weights(num_from=strength_start, num_to=strength_end, length=intervals, method=interpolation)
|
strengths = InterpolationMethod.get_weights(num_from=strength_start, num_to=strength_end, length=intervals, method=interpolation)
|
||||||
|
|
||||||
is_first = True
|
is_first = True
|
||||||
for percent, strength in zip(percents, strengths):
|
for percent, strength in zip(percents, strengths):
|
||||||
guarantee_steps = 0
|
guarantee_steps = 0
|
||||||
@@ -73,338 +41,143 @@ class CreateLoraHookKeyframeInterpolationDEPR:
|
|||||||
is_first = False
|
is_first = False
|
||||||
prev_hook_kf.add(HookKeyframe(strength=strength, start_percent=percent, guarantee_steps=guarantee_steps))
|
prev_hook_kf.add(HookKeyframe(strength=strength, start_percent=percent, guarantee_steps=guarantee_steps))
|
||||||
if print_keyframes:
|
if print_keyframes:
|
||||||
logger.info(f"HookKeyframe - start_percent:{percent} = {strength}")
|
logger.info(f'HookKeyframe - start_percent:{percent} = {strength}')
|
||||||
return (prev_hook_kf,)
|
return io.NodeOutput(prev_hook_kf)
|
||||||
|
|
||||||
|
class PairedConditioningSetMaskHookedDEPR(io.ComfyNode):
|
||||||
|
|
||||||
###############################################
|
|
||||||
### Mask, Combine, and Hook Conditioning
|
|
||||||
###############################################
|
|
||||||
class PairedConditioningSetMaskHookedDEPR:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls):
|
||||||
return {
|
return io.Schema(node_id='ADE_PairedConditioningSetMask', display_name='Set Props on Conds 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/conditioning', inputs=[io.Conditioning.Input('positive_ADD'), io.Conditioning.Input('negative_ADD'), io.Float.Input('strength', default=1.0, max=10.0, min=0.0, step=0.01), io.Combo.Input('set_cond_area', options=['default', 'mask bounds']), io.Mask.Input('opt_mask', optional=True), io.Custom('HOOKS').Input('opt_lora_hook', optional=True), io.Custom('TIMESTEPS_RANGE').Input('opt_timesteps', optional=True)], outputs=[io.Conditioning.Output('positive'), io.Conditioning.Output('negative')], is_deprecated=True)
|
||||||
"required": {
|
|
||||||
"positive_ADD": ("CONDITIONING", ),
|
|
||||||
"negative_ADD": ("CONDITIONING", ),
|
|
||||||
"strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.01}),
|
|
||||||
"set_cond_area": (COND_CONST._LIST_COND_AREA,),
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"opt_mask": ("MASK", ),
|
|
||||||
"opt_lora_hook": ("HOOKS",),
|
|
||||||
"opt_timesteps": ("TIMESTEPS_RANGE",),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("CONDITIONING", "CONDITIONING")
|
|
||||||
RETURN_NAMES = ("positive", "negative")
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/conditioning"
|
|
||||||
FUNCTION = "append_and_hook"
|
|
||||||
DEPRECATED = True
|
|
||||||
|
|
||||||
def append_and_hook(self, positive_ADD, negative_ADD,
|
|
||||||
strength: float, set_cond_area: str,
|
|
||||||
opt_mask: Tensor=None, opt_lora_hook: HookGroup=None, opt_timesteps: tuple=None):
|
|
||||||
final_positive, final_negative = comfy.hooks.set_conds_props(conds=[positive_ADD, negative_ADD],
|
|
||||||
strength=strength, set_cond_area=set_cond_area,
|
|
||||||
mask=opt_mask, hooks=opt_lora_hook, timesteps_range=opt_timesteps)
|
|
||||||
return (final_positive, final_negative)
|
|
||||||
|
|
||||||
|
|
||||||
class ConditioningSetMaskHookedDEPR:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def execute(cls, positive_ADD, negative_ADD, strength: float, set_cond_area: str, opt_mask: Tensor=None, opt_lora_hook: HookGroup=None, opt_timesteps: tuple=None):
|
||||||
return {
|
final_positive, final_negative = comfy.hooks.set_conds_props(conds=[positive_ADD, negative_ADD], strength=strength, set_cond_area=set_cond_area, mask=opt_mask, hooks=opt_lora_hook, timesteps_range=opt_timesteps)
|
||||||
"required": {
|
return io.NodeOutput(final_positive, final_negative)
|
||||||
"cond_ADD": ("CONDITIONING",),
|
|
||||||
"strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.01}),
|
|
||||||
"set_cond_area": (COND_CONST._LIST_COND_AREA,),
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"opt_mask": ("MASK", ),
|
|
||||||
"opt_lora_hook": ("HOOKS",),
|
|
||||||
"opt_timesteps": ("TIMESTEPS_RANGE",),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("CONDITIONING",)
|
class ConditioningSetMaskHookedDEPR(io.ComfyNode):
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/conditioning/single cond ops"
|
|
||||||
FUNCTION = "append_and_hook"
|
|
||||||
DEPRECATED = True
|
|
||||||
|
|
||||||
def append_and_hook(self, cond_ADD,
|
|
||||||
strength: float, set_cond_area: str,
|
|
||||||
opt_mask: Tensor=None, opt_lora_hook: HookGroup=None, opt_timesteps: tuple=None):
|
|
||||||
(final_conditioning,) = comfy.hooks.set_conds_props(conds=[cond_ADD],
|
|
||||||
strength=strength, set_cond_area=set_cond_area,
|
|
||||||
mask=opt_mask, hooks=opt_lora_hook, timesteps_range=opt_timesteps)
|
|
||||||
return (final_conditioning,)
|
|
||||||
|
|
||||||
|
|
||||||
class PairedConditioningSetMaskAndCombineHookedDEPR:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls):
|
||||||
return {
|
return io.Schema(node_id='ADE_ConditioningSetMask', display_name='Set Props on Cond 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/conditioning/single cond ops', inputs=[io.Conditioning.Input('cond_ADD'), io.Float.Input('strength', default=1.0, max=10.0, min=0.0, step=0.01), io.Combo.Input('set_cond_area', options=['default', 'mask bounds']), io.Mask.Input('opt_mask', optional=True), io.Custom('HOOKS').Input('opt_lora_hook', optional=True), io.Custom('TIMESTEPS_RANGE').Input('opt_timesteps', optional=True)], outputs=[io.Conditioning.Output('CONDITIONING')], is_deprecated=True)
|
||||||
"required": {
|
|
||||||
"positive": ("CONDITIONING",),
|
|
||||||
"negative": ("CONDITIONING",),
|
|
||||||
"positive_ADD": ("CONDITIONING",),
|
|
||||||
"negative_ADD": ("CONDITIONING",),
|
|
||||||
"strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.01}),
|
|
||||||
"set_cond_area": (COND_CONST._LIST_COND_AREA,),
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"opt_mask": ("MASK", ),
|
|
||||||
"opt_lora_hook": ("HOOKS",),
|
|
||||||
"opt_timesteps": ("TIMESTEPS_RANGE",),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("CONDITIONING", "CONDITIONING")
|
|
||||||
RETURN_NAMES = ("positive", "negative")
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/conditioning"
|
|
||||||
FUNCTION = "append_and_combine"
|
|
||||||
DEPRECATED = True
|
|
||||||
|
|
||||||
def append_and_combine(self, positive, negative, positive_ADD, negative_ADD,
|
|
||||||
strength: float, set_cond_area: str,
|
|
||||||
opt_mask: Tensor=None, opt_lora_hook: HookGroup=None, opt_timesteps: tuple=None):
|
|
||||||
final_positive, final_negative = comfy.hooks.set_conds_props_and_combine(conds=[positive, negative], new_conds=[positive_ADD, negative_ADD],
|
|
||||||
strength=strength, set_cond_area=set_cond_area,
|
|
||||||
mask=opt_mask, hooks=opt_lora_hook, timesteps_range=opt_timesteps)
|
|
||||||
return (final_positive, final_negative,)
|
|
||||||
|
|
||||||
|
|
||||||
class ConditioningSetMaskAndCombineHookedDEPR:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def execute(cls, cond_ADD, strength: float, set_cond_area: str, opt_mask: Tensor=None, opt_lora_hook: HookGroup=None, opt_timesteps: tuple=None):
|
||||||
return {
|
final_conditioning, = comfy.hooks.set_conds_props(conds=[cond_ADD], strength=strength, set_cond_area=set_cond_area, mask=opt_mask, hooks=opt_lora_hook, timesteps_range=opt_timesteps)
|
||||||
"required": {
|
return io.NodeOutput(final_conditioning)
|
||||||
"cond": ("CONDITIONING",),
|
|
||||||
"cond_ADD": ("CONDITIONING",),
|
|
||||||
"strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.01}),
|
|
||||||
"set_cond_area": (COND_CONST._LIST_COND_AREA,),
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"opt_mask": ("MASK", ),
|
|
||||||
"opt_lora_hook": ("HOOKS",),
|
|
||||||
"opt_timesteps": ("TIMESTEPS_RANGE",),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("CONDITIONING",)
|
class PairedConditioningSetMaskAndCombineHookedDEPR(io.ComfyNode):
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/conditioning/single cond ops"
|
|
||||||
FUNCTION = "append_and_combine"
|
|
||||||
DEPRECATED = True
|
|
||||||
|
|
||||||
def append_and_combine(self, cond, cond_ADD,
|
|
||||||
strength: float, set_cond_area: str,
|
|
||||||
opt_mask: Tensor=None, opt_lora_hook: HookGroup=None, opt_timesteps: tuple=None):
|
|
||||||
(final_conditioning,) = comfy.hooks.set_conds_props_and_combine(conds=[cond], new_conds=[cond_ADD],
|
|
||||||
strength=strength, set_cond_area=set_cond_area,
|
|
||||||
mask=opt_mask, hooks=opt_lora_hook, timesteps_range=opt_timesteps)
|
|
||||||
return (final_conditioning,)
|
|
||||||
|
|
||||||
|
|
||||||
class PairedConditioningSetUnmaskedAndCombineHookedDEPR:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls):
|
||||||
return {
|
return io.Schema(node_id='ADE_PairedConditioningSetMaskAndCombine', display_name='Set Props and Combine Conds 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/conditioning', inputs=[io.Conditioning.Input('positive'), io.Conditioning.Input('negative'), io.Conditioning.Input('positive_ADD'), io.Conditioning.Input('negative_ADD'), io.Float.Input('strength', default=1.0, max=10.0, min=0.0, step=0.01), io.Combo.Input('set_cond_area', options=['default', 'mask bounds']), io.Mask.Input('opt_mask', optional=True), io.Custom('HOOKS').Input('opt_lora_hook', optional=True), io.Custom('TIMESTEPS_RANGE').Input('opt_timesteps', optional=True)], outputs=[io.Conditioning.Output('positive'), io.Conditioning.Output('negative')], is_deprecated=True)
|
||||||
"required": {
|
|
||||||
"positive": ("CONDITIONING",),
|
|
||||||
"negative": ("CONDITIONING",),
|
|
||||||
"positive_DEFAULT": ("CONDITIONING",),
|
|
||||||
"negative_DEFAULT": ("CONDITIONING",),
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"opt_lora_hook": ("HOOKS",),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("CONDITIONING", "CONDITIONING")
|
|
||||||
RETURN_NAMES = ("positive", "negative")
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/conditioning"
|
|
||||||
FUNCTION = "append_and_combine"
|
|
||||||
DEPRECATED = True
|
|
||||||
|
|
||||||
def append_and_combine(self, positive, negative, positive_DEFAULT, negative_DEFAULT,
|
|
||||||
opt_lora_hook: HookGroup=None):
|
|
||||||
final_positive, final_negative = comfy.hooks.set_default_conds_and_combine(conds=[positive, negative], new_conds=[positive_DEFAULT, negative_DEFAULT],
|
|
||||||
hooks=opt_lora_hook)
|
|
||||||
return (final_positive, final_negative,)
|
|
||||||
|
|
||||||
|
|
||||||
class ConditioningSetUnmaskedAndCombineHookedDEPR:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def execute(cls, positive, negative, positive_ADD, negative_ADD, strength: float, set_cond_area: str, opt_mask: Tensor=None, opt_lora_hook: HookGroup=None, opt_timesteps: tuple=None):
|
||||||
return {
|
final_positive, final_negative = comfy.hooks.set_conds_props_and_combine(conds=[positive, negative], new_conds=[positive_ADD, negative_ADD], strength=strength, set_cond_area=set_cond_area, mask=opt_mask, hooks=opt_lora_hook, timesteps_range=opt_timesteps)
|
||||||
"required": {
|
return io.NodeOutput(final_positive, final_negative)
|
||||||
"cond": ("CONDITIONING",),
|
|
||||||
"cond_DEFAULT": ("CONDITIONING",),
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"opt_lora_hook": ("HOOKS",),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("CONDITIONING",)
|
class ConditioningSetMaskAndCombineHookedDEPR(io.ComfyNode):
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/conditioning/single cond ops"
|
|
||||||
FUNCTION = "append_and_combine"
|
|
||||||
DEPRECATED = True
|
|
||||||
|
|
||||||
def append_and_combine(self, cond, cond_DEFAULT,
|
|
||||||
opt_lora_hook: HookGroup=None):
|
|
||||||
(final_conditioning,) = comfy.hooks.set_default_conds_and_combine(conds=[cond], new_conds=[cond_DEFAULT],
|
|
||||||
hooks=opt_lora_hook)
|
|
||||||
return (final_conditioning,)
|
|
||||||
|
|
||||||
|
|
||||||
class PairedConditioningCombineDEPR:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls):
|
||||||
return {
|
return io.Schema(node_id='ADE_ConditioningSetMaskAndCombine', display_name='Set Props and Combine Cond 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/conditioning/single cond ops', inputs=[io.Conditioning.Input('cond'), io.Conditioning.Input('cond_ADD'), io.Float.Input('strength', default=1.0, max=10.0, min=0.0, step=0.01), io.Combo.Input('set_cond_area', options=['default', 'mask bounds']), io.Mask.Input('opt_mask', optional=True), io.Custom('HOOKS').Input('opt_lora_hook', optional=True), io.Custom('TIMESTEPS_RANGE').Input('opt_timesteps', optional=True)], outputs=[io.Conditioning.Output('CONDITIONING')], is_deprecated=True)
|
||||||
"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"
|
|
||||||
DEPRECATED = True
|
|
||||||
|
|
||||||
def combine(self, positive_A, negative_A, positive_B, negative_B):
|
|
||||||
final_positive, final_negative = comfy.hooks.set_conds_props_and_combine(conds=[positive_A, negative_A], new_conds=[positive_B, negative_B],)
|
|
||||||
return (final_positive, final_negative,)
|
|
||||||
|
|
||||||
|
|
||||||
class ConditioningCombineDEPR:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def execute(cls, cond, cond_ADD, strength: float, set_cond_area: str, opt_mask: Tensor=None, opt_lora_hook: HookGroup=None, opt_timesteps: tuple=None):
|
||||||
return {
|
final_conditioning, = comfy.hooks.set_conds_props_and_combine(conds=[cond], new_conds=[cond_ADD], strength=strength, set_cond_area=set_cond_area, mask=opt_mask, hooks=opt_lora_hook, timesteps_range=opt_timesteps)
|
||||||
"required": {
|
return io.NodeOutput(final_conditioning)
|
||||||
"cond_A": ("CONDITIONING",),
|
|
||||||
"cond_B": ("CONDITIONING",),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("CONDITIONING",)
|
class PairedConditioningSetUnmaskedAndCombineHookedDEPR(io.ComfyNode):
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/conditioning/single cond ops"
|
|
||||||
FUNCTION = "combine"
|
|
||||||
DEPRECATED = True
|
|
||||||
|
|
||||||
def combine(self, cond_A, cond_B):
|
|
||||||
(final_conditioning,) = comfy.hooks.set_conds_props_and_combine(conds=[cond_A], new_conds=[cond_B],)
|
|
||||||
return (final_conditioning,)
|
|
||||||
###############################################
|
|
||||||
###############################################
|
|
||||||
###############################################
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
###############################################
|
|
||||||
### Scheduling
|
|
||||||
###############################################
|
|
||||||
class ConditioningTimestepsNodeDEPR:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls):
|
||||||
return {
|
return io.Schema(node_id='ADE_PairedConditioningSetUnmaskedAndCombine', display_name='Set Unmasked Conds 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/conditioning', inputs=[io.Conditioning.Input('positive'), io.Conditioning.Input('negative'), io.Conditioning.Input('positive_DEFAULT'), io.Conditioning.Input('negative_DEFAULT'), io.Custom('HOOKS').Input('opt_lora_hook', optional=True)], outputs=[io.Conditioning.Output('positive'), io.Conditioning.Output('negative')], is_deprecated=True)
|
||||||
"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})
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("TIMESTEPS_RANGE",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/conditioning"
|
|
||||||
FUNCTION = "create_schedule"
|
|
||||||
DEPRECATED = True
|
|
||||||
|
|
||||||
def create_schedule(self, start_percent: float, end_percent: float):
|
|
||||||
return ((start_percent, end_percent),)
|
|
||||||
|
|
||||||
|
|
||||||
class SetLoraHookKeyframesDEPR:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def execute(cls, positive, negative, positive_DEFAULT, negative_DEFAULT, opt_lora_hook: HookGroup=None):
|
||||||
return {
|
final_positive, final_negative = comfy.hooks.set_default_conds_and_combine(conds=[positive, negative], new_conds=[positive_DEFAULT, negative_DEFAULT], hooks=opt_lora_hook)
|
||||||
"required": {
|
return io.NodeOutput(final_positive, final_negative)
|
||||||
"lora_hook": ("HOOKS",),
|
|
||||||
"hook_kf": ("HOOK_KEYFRAMES",),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("HOOKS",)
|
class ConditioningSetUnmaskedAndCombineHookedDEPR(io.ComfyNode):
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/conditioning"
|
|
||||||
FUNCTION = "set_hook_keyframes"
|
|
||||||
DEPRECATED = True
|
|
||||||
|
|
||||||
def set_hook_keyframes(self, lora_hook: HookGroup, hook_kf: HookKeyframeGroup):
|
@classmethod
|
||||||
|
def define_schema(cls):
|
||||||
|
return io.Schema(node_id='ADE_ConditioningSetUnmaskedAndCombine', display_name='Set Unmasked Cond 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/conditioning/single cond ops', inputs=[io.Conditioning.Input('cond'), io.Conditioning.Input('cond_DEFAULT'), io.Custom('HOOKS').Input('opt_lora_hook', optional=True)], outputs=[io.Conditioning.Output('CONDITIONING')], is_deprecated=True)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def execute(cls, cond, cond_DEFAULT, opt_lora_hook: HookGroup=None):
|
||||||
|
final_conditioning, = comfy.hooks.set_default_conds_and_combine(conds=[cond], new_conds=[cond_DEFAULT], hooks=opt_lora_hook)
|
||||||
|
return io.NodeOutput(final_conditioning)
|
||||||
|
|
||||||
|
class PairedConditioningCombineDEPR(io.ComfyNode):
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def define_schema(cls):
|
||||||
|
return io.Schema(node_id='ADE_PairedConditioningCombine', display_name='Manual Combine Conds 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/conditioning', inputs=[io.Conditioning.Input('positive_A'), io.Conditioning.Input('negative_A'), io.Conditioning.Input('positive_B'), io.Conditioning.Input('negative_B')], outputs=[io.Conditioning.Output('positive'), io.Conditioning.Output('negative')], is_deprecated=True)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def execute(cls, positive_A, negative_A, positive_B, negative_B):
|
||||||
|
final_positive, final_negative = comfy.hooks.set_conds_props_and_combine(conds=[positive_A, negative_A], new_conds=[positive_B, negative_B])
|
||||||
|
return io.NodeOutput(final_positive, final_negative)
|
||||||
|
|
||||||
|
class ConditioningCombineDEPR(io.ComfyNode):
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def define_schema(cls):
|
||||||
|
return io.Schema(node_id='ADE_ConditioningCombine', display_name='Manual Combine Cond 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/conditioning/single cond ops', inputs=[io.Conditioning.Input('cond_A'), io.Conditioning.Input('cond_B')], outputs=[io.Conditioning.Output('CONDITIONING')], is_deprecated=True)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def execute(cls, cond_A, cond_B):
|
||||||
|
final_conditioning, = comfy.hooks.set_conds_props_and_combine(conds=[cond_A], new_conds=[cond_B])
|
||||||
|
return io.NodeOutput(final_conditioning)
|
||||||
|
|
||||||
|
class ConditioningTimestepsNodeDEPR(io.ComfyNode):
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def define_schema(cls):
|
||||||
|
return io.Schema(node_id='ADE_TimestepsConditioning', display_name='Timesteps Conditioning 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/conditioning', inputs=[io.Float.Input('start_percent', default=0.0, max=1.0, min=0.0, step=0.001), io.Float.Input('end_percent', default=1.0, max=1.0, min=0.0, step=0.001)], outputs=[io.Custom('TIMESTEPS_RANGE').Output('TIMESTEPS_RANGE')], is_deprecated=True)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def execute(cls, start_percent: float, end_percent: float):
|
||||||
|
return io.NodeOutput((start_percent, end_percent))
|
||||||
|
|
||||||
|
class SetLoraHookKeyframesDEPR(io.ComfyNode):
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def define_schema(cls):
|
||||||
|
return io.Schema(node_id='ADE_SetLoraHookKeyframe', display_name='Set LoRA Hook Keyframes 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/conditioning', inputs=[io.Custom('HOOKS').Input('lora_hook'), io.Custom('HOOK_KEYFRAMES').Input('hook_kf')], outputs=[io.Custom('HOOKS').Output('HOOKS')], is_deprecated=True)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def execute(cls, lora_hook: HookGroup, hook_kf: HookKeyframeGroup):
|
||||||
new_lora_hook = lora_hook.clone()
|
new_lora_hook = lora_hook.clone()
|
||||||
new_lora_hook.set_keyframes_on_hooks(hook_kf=hook_kf)
|
new_lora_hook.set_keyframes_on_hooks(hook_kf=hook_kf)
|
||||||
return (new_lora_hook,)
|
return io.NodeOutput(new_lora_hook)
|
||||||
|
|
||||||
|
class CreateLoraHookKeyframeDEPR(io.ComfyNode):
|
||||||
|
|
||||||
class CreateLoraHookKeyframeDEPR:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls):
|
||||||
return {
|
return io.Schema(node_id='ADE_LoraHookKeyframe', display_name='LoRA Hook Keyframe 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/conditioning/schedule lora hooks', inputs=[io.Float.Input('strength_model', default=1.0, max=20.0, min=-20.0, step=0.01), io.Float.Input('start_percent', default=0.0, max=1.0, min=0.0, step=0.001), io.Int.Input('guarantee_steps', default=1, max=9007199254740991, min=0), io.Custom('HOOK_KEYFRAMES').Input('prev_hook_kf', optional=True)], outputs=[io.Custom('HOOK_KEYFRAMES').Output('HOOK_KF')], is_deprecated=True)
|
||||||
"required": {
|
|
||||||
"strength_model": ("FLOAT", {"default": 1.0, "min": -20.0, "max": 20.0, "step": 0.01}),
|
|
||||||
"start_percent": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001}),
|
|
||||||
"guarantee_steps": ("INT", {"default": 1, "min": 0, "max": BIGMAX}),
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"prev_hook_kf": ("HOOK_KEYFRAMES",),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("HOOK_KEYFRAMES",)
|
@classmethod
|
||||||
RETURN_NAMES = ("HOOK_KF",)
|
def execute(cls, strength_model: float, start_percent: float, guarantee_steps: float, prev_hook_kf: HookKeyframeGroup=None):
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/conditioning/schedule lora hooks"
|
|
||||||
FUNCTION = "create_hook_keyframe"
|
|
||||||
DEPRECATED = True
|
|
||||||
|
|
||||||
def create_hook_keyframe(self, strength_model: float, start_percent: float, guarantee_steps: float,
|
|
||||||
prev_hook_kf: HookKeyframeGroup=None):
|
|
||||||
if prev_hook_kf:
|
if prev_hook_kf:
|
||||||
prev_hook_kf = prev_hook_kf.clone()
|
prev_hook_kf = prev_hook_kf.clone()
|
||||||
else:
|
else:
|
||||||
prev_hook_kf = HookKeyframeGroup()
|
prev_hook_kf = HookKeyframeGroup()
|
||||||
keyframe = HookKeyframe(strength=strength_model, start_percent=start_percent, guarantee_steps=guarantee_steps)
|
keyframe = HookKeyframe(strength=strength_model, start_percent=start_percent, guarantee_steps=guarantee_steps)
|
||||||
prev_hook_kf.add(keyframe)
|
prev_hook_kf.add(keyframe)
|
||||||
return (prev_hook_kf,)
|
return io.NodeOutput(prev_hook_kf)
|
||||||
|
|
||||||
|
class CreateLoraHookKeyframeFromStrengthListDEPR(io.ComfyNode):
|
||||||
|
|
||||||
class CreateLoraHookKeyframeFromStrengthListDEPR:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls):
|
||||||
return {
|
return io.Schema(node_id='ADE_LoraHookKeyframeFromStrengthList', display_name='LoRA Hook Keyframes From List 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/conditioning/schedule lora hooks', inputs=[io.Float.Input('strengths_float', default=-1, force_input=True, min=-1, step=0.001), io.Float.Input('start_percent', default=0.0, max=1.0, min=0.0, step=0.001), io.Float.Input('end_percent', default=1.0, max=1.0, min=0.0, step=0.001), io.Boolean.Input('print_keyframes', default=False), io.Custom('HOOK_KEYFRAMES').Input('prev_hook_kf', optional=True)], outputs=[io.Custom('HOOK_KEYFRAMES').Output('HOOK_KF')], is_deprecated=True)
|
||||||
"required": {
|
|
||||||
"strengths_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_hook_kf": ("HOOK_KEYFRAMES",),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("HOOK_KEYFRAMES",)
|
@classmethod
|
||||||
RETURN_NAMES = ("HOOK_KF",)
|
def execute(cls, strengths_float: Union[float, list[float]], start_percent: float, end_percent: float, prev_hook_kf: HookKeyframeGroup=None, print_keyframes=False):
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/conditioning/schedule lora hooks"
|
|
||||||
FUNCTION = "create_hook_keyframes"
|
|
||||||
DEPRECATED = True
|
|
||||||
|
|
||||||
def create_hook_keyframes(self, strengths_float: Union[float, list[float]],
|
|
||||||
start_percent: float, end_percent: float,
|
|
||||||
prev_hook_kf: HookKeyframeGroup=None, print_keyframes=False):
|
|
||||||
if prev_hook_kf:
|
if prev_hook_kf:
|
||||||
prev_hook_kf = prev_hook_kf.clone()
|
prev_hook_kf = prev_hook_kf.clone()
|
||||||
else:
|
else:
|
||||||
@@ -414,9 +187,8 @@ class CreateLoraHookKeyframeFromStrengthListDEPR:
|
|||||||
elif isinstance(strengths_float, Iterable):
|
elif isinstance(strengths_float, Iterable):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
raise Exception(f"strengths_float 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)
|
percents = InterpolationMethod.get_weights(num_from=start_percent, num_to=end_percent, length=len(strengths_float), method=InterpolationMethod.LINEAR)
|
||||||
|
|
||||||
is_first = True
|
is_first = True
|
||||||
for percent, strength in zip(percents, strengths_float):
|
for percent, strength in zip(percents, strengths_float):
|
||||||
guarantee_steps = 0
|
guarantee_steps = 0
|
||||||
@@ -425,256 +197,121 @@ class CreateLoraHookKeyframeFromStrengthListDEPR:
|
|||||||
is_first = False
|
is_first = False
|
||||||
prev_hook_kf.add(HookKeyframe(strength=strength, start_percent=percent, guarantee_steps=guarantee_steps))
|
prev_hook_kf.add(HookKeyframe(strength=strength, start_percent=percent, guarantee_steps=guarantee_steps))
|
||||||
if print_keyframes:
|
if print_keyframes:
|
||||||
logger.info(f"HookKeyframe - start_percent:{percent} = {strength}")
|
logger.info(f'HookKeyframe - start_percent:{percent} = {strength}')
|
||||||
return (prev_hook_kf,)
|
return io.NodeOutput(prev_hook_kf)
|
||||||
###############################################
|
|
||||||
###############################################
|
|
||||||
###############################################
|
|
||||||
|
|
||||||
|
class MaskableLoraLoaderDEPR(io.ComfyNode):
|
||||||
###############################################
|
loaded_lora = None
|
||||||
### Register LoRA Hooks
|
|
||||||
###############################################
|
|
||||||
# based on ComfyUI's nodes.py LoraLoader
|
|
||||||
class MaskableLoraLoaderDEPR:
|
|
||||||
def __init__(self):
|
|
||||||
self.loaded_lora = None
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls):
|
||||||
return {
|
return io.Schema(node_id='ADE_RegisterLoraHook', display_name='Register LoRA Hook 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/conditioning/register lora hooks', inputs=[io.Model.Input('model'), io.Clip.Input('clip'), io.Combo.Input('lora_name', options=folder_paths.get_filename_list('loras')), io.Float.Input('strength_model', default=1.0, max=20.0, min=-20.0, step=0.01), io.Float.Input('strength_clip', default=1.0, max=20.0, min=-20.0, step=0.01)], outputs=[io.Model.Output('MODEL'), io.Clip.Output('CLIP'), io.Custom('HOOKS').Output('HOOKS')], is_deprecated=True)
|
||||||
"required": {
|
|
||||||
"model": ("MODEL",),
|
|
||||||
"clip": ("CLIP",),
|
|
||||||
"lora_name": (folder_paths.get_filename_list("loras"), ),
|
|
||||||
"strength_model": ("FLOAT", {"default": 1.0, "min": -20.0, "max": 20.0, "step": 0.01}),
|
|
||||||
"strength_clip": ("FLOAT", {"default": 1.0, "min": -20.0, "max": 20.0, "step": 0.01}),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("MODEL", "CLIP", "HOOKS")
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/conditioning/register lora hooks"
|
|
||||||
FUNCTION = "load_lora"
|
|
||||||
DEPRECATED = True
|
|
||||||
|
|
||||||
def load_lora(self, model: Union[ModelPatcher], clip: CLIP, lora_name: str, strength_model: float, strength_clip: float):
|
@classmethod
|
||||||
|
def execute(cls, model: Union[ModelPatcher], clip: CLIP, lora_name: str, strength_model: float, strength_clip: float):
|
||||||
if strength_model == 0 and strength_clip == 0:
|
if strength_model == 0 and strength_clip == 0:
|
||||||
return (model, clip, None)
|
return io.NodeOutput(model, clip, None)
|
||||||
|
lora_path = folder_paths.get_full_path('loras', lora_name)
|
||||||
lora_path = folder_paths.get_full_path("loras", lora_name)
|
|
||||||
lora = None
|
lora = None
|
||||||
if self.loaded_lora is not None:
|
if cls.loaded_lora is not None:
|
||||||
if self.loaded_lora[0] == lora_path:
|
if cls.loaded_lora[0] == lora_path:
|
||||||
lora = self.loaded_lora[1]
|
lora = cls.loaded_lora[1]
|
||||||
else:
|
else:
|
||||||
temp = self.loaded_lora
|
temp = cls.loaded_lora
|
||||||
self.loaded_lora = None
|
cls.loaded_lora = None
|
||||||
del temp
|
del temp
|
||||||
|
|
||||||
if lora is None:
|
if lora is None:
|
||||||
lora = comfy.utils.load_torch_file(lora_path, safe_load=True)
|
lora = comfy.utils.load_torch_file(lora_path, safe_load=True)
|
||||||
self.loaded_lora = (lora_path, lora)
|
cls.loaded_lora = (lora_path, lora)
|
||||||
|
model_lora, clip_lora, hooks = comfy.hooks.load_hook_lora_for_models(model=model, clip=clip, lora=lora, strength_model=strength_model, strength_clip=strength_clip)
|
||||||
|
return io.NodeOutput(model_lora, clip_lora, hooks)
|
||||||
|
|
||||||
model_lora, clip_lora, hooks = comfy.hooks.load_hook_lora_for_models(model=model, clip=clip, lora=lora,
|
class MaskableLoraLoaderModelOnlyDEPR(io.ComfyNode):
|
||||||
strength_model=strength_model, strength_clip=strength_clip)
|
|
||||||
return (model_lora, clip_lora, hooks)
|
|
||||||
|
|
||||||
|
|
||||||
class MaskableLoraLoaderModelOnlyDEPR(MaskableLoraLoaderDEPR):
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls):
|
||||||
return {
|
return io.Schema(node_id='ADE_RegisterLoraHookModelOnly', display_name='Register LoRA Hook (Model Only) 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/conditioning/register lora hooks', inputs=[io.Model.Input('model'), io.Combo.Input('lora_name', options=folder_paths.get_filename_list('loras')), io.Float.Input('strength_model', default=1.0, max=20.0, min=-20.0, step=0.01)], outputs=[io.Model.Output('MODEL'), io.Custom('HOOKS').Output('HOOKS')], is_deprecated=True)
|
||||||
"required": {
|
|
||||||
"model": ("MODEL",),
|
|
||||||
"lora_name": (folder_paths.get_filename_list("loras"), ),
|
|
||||||
"strength_model": ("FLOAT", {"default": 1.0, "min": -20.0, "max": 20.0, "step": 0.01}),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("MODEL", "HOOKS")
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/conditioning/register lora hooks"
|
|
||||||
FUNCTION = "load_lora_model_only"
|
|
||||||
DEPRECATED = True
|
|
||||||
|
|
||||||
def load_lora_model_only(self, model: ModelPatcher, lora_name: str, strength_model: float):
|
|
||||||
model_lora, _, hooks = self.load_lora(model=model, clip=None, lora_name=lora_name,
|
|
||||||
strength_model=strength_model, strength_clip=0)
|
|
||||||
return (model_lora, hooks)
|
|
||||||
|
|
||||||
|
|
||||||
class MaskableSDModelLoaderDEPR(comfy_extras.nodes_hooks.CreateHookModelAsLora):
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def execute(cls, model: ModelPatcher, lora_name: str, strength_model: float):
|
||||||
return {
|
model_lora, _, hooks = MaskableLoraLoaderDEPR.execute(model=model, clip=None, lora_name=lora_name, strength_model=strength_model, strength_clip=0).args
|
||||||
"required": {
|
return io.NodeOutput(model_lora, hooks)
|
||||||
"model": ("MODEL",),
|
|
||||||
"clip": ("CLIP",),
|
|
||||||
"ckpt_name": (folder_paths.get_filename_list("checkpoints"), ),
|
|
||||||
"strength_model": ("FLOAT", {"default": 1.0, "min": -20.0, "max": 20.0, "step": 0.01}),
|
|
||||||
"strength_clip": ("FLOAT", {"default": 1.0, "min": -20.0, "max": 20.0, "step": 0.01}),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("MODEL", "CLIP", "HOOKS")
|
class MaskableSDModelLoaderDEPR(io.ComfyNode, comfy_extras.nodes_hooks.CreateHookModelAsLora):
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/conditioning/register lora hooks"
|
loaded_weights = None
|
||||||
FUNCTION = "load_model_as_lora"
|
|
||||||
DEPRECATED = True
|
|
||||||
|
|
||||||
def load_model_as_lora(self, model: ModelPatcher, clip: CLIP, ckpt_name: str, strength_model: float, strength_clip: float):
|
|
||||||
returned = self.create_hook(ckpt_name=ckpt_name, strength_model=strength_model, strength_clip=strength_clip)
|
|
||||||
return (model.clone(), clip.clone(), returned[0])
|
|
||||||
|
|
||||||
|
|
||||||
class MaskableSDModelLoaderModelOnlyDEPR(MaskableSDModelLoaderDEPR):
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls):
|
||||||
return {
|
return io.Schema(node_id='ADE_RegisterModelAsLoraHook', display_name='Register Model as LoRA Hook 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/conditioning/register lora hooks', inputs=[io.Model.Input('model'), io.Clip.Input('clip'), io.Combo.Input('ckpt_name', options=folder_paths.get_filename_list('checkpoints')), io.Float.Input('strength_model', default=1.0, max=20.0, min=-20.0, step=0.01), io.Float.Input('strength_clip', default=1.0, max=20.0, min=-20.0, step=0.01)], outputs=[io.Model.Output('MODEL'), io.Clip.Output('CLIP'), io.Custom('HOOKS').Output('HOOKS')], is_deprecated=True, is_experimental=True)
|
||||||
"required": {
|
|
||||||
"model": ("MODEL",),
|
|
||||||
"ckpt_name": (folder_paths.get_filename_list("checkpoints"), ),
|
|
||||||
"strength_model": ("FLOAT", {"default": 1.0, "min": -20.0, "max": 20.0, "step": 0.01}),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("MODEL", "HOOKS")
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/conditioning/register lora hooks"
|
|
||||||
FUNCTION = "load_model_as_lora_model_only"
|
|
||||||
DEPRECATED = True
|
|
||||||
|
|
||||||
def load_model_as_lora_model_only(self, model: ModelPatcher, ckpt_name: str, strength_model: float):
|
|
||||||
model_lora, _, hooks = self.load_model_as_lora(model=model, clip=None, ckpt_name=ckpt_name,
|
|
||||||
strength_model=strength_model, strength_clip=0)
|
|
||||||
return (model_lora, hooks)
|
|
||||||
###############################################
|
|
||||||
###############################################
|
|
||||||
###############################################
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
###############################################
|
|
||||||
### Set LoRA Hooks
|
|
||||||
###############################################
|
|
||||||
class SetModelLoraHookDEPR:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def execute(cls, model: ModelPatcher, clip: CLIP, ckpt_name: str, strength_model: float, strength_clip: float):
|
||||||
return {
|
returned = comfy_extras.nodes_hooks.CreateHookModelAsLora.create_hook(
|
||||||
"required": {
|
cls, ckpt_name=ckpt_name, strength_model=strength_model, strength_clip=strength_clip
|
||||||
"conditioning": ("CONDITIONING",),
|
)
|
||||||
"lora_hook": ("HOOKS",),
|
return io.NodeOutput(model.clone(), clip.clone(), returned[0])
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("CONDITIONING",)
|
class MaskableSDModelLoaderModelOnlyDEPR(io.ComfyNode):
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/conditioning/single cond ops"
|
|
||||||
FUNCTION = "attach_lora_hook"
|
|
||||||
DEPRECATED = True
|
|
||||||
|
|
||||||
def attach_lora_hook(self, conditioning, lora_hook: HookGroup):
|
|
||||||
return (comfy.hooks.set_hooks_for_conditioning(conditioning, lora_hook),)
|
|
||||||
|
|
||||||
|
|
||||||
class SetClipLoraHookDEPR:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls):
|
||||||
return {
|
return io.Schema(node_id='ADE_RegisterModelAsLoraHookModelOnly', display_name='Register Model as LoRA Hook (MO) 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/conditioning/register lora hooks', inputs=[io.Model.Input('model'), io.Combo.Input('ckpt_name', options=folder_paths.get_filename_list('checkpoints')), io.Float.Input('strength_model', default=1.0, max=20.0, min=-20.0, step=0.01)], outputs=[io.Model.Output('MODEL'), io.Custom('HOOKS').Output('HOOKS')], is_deprecated=True, is_experimental=True)
|
||||||
"required": {
|
|
||||||
"clip": ("CLIP",),
|
|
||||||
"lora_hook": ("HOOKS",),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("CLIP",)
|
|
||||||
RETURN_NAMES = ("hook_CLIP",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/conditioning"
|
|
||||||
FUNCTION = "apply_lora_hook"
|
|
||||||
DEPRECATED = True
|
|
||||||
|
|
||||||
def apply_lora_hook(self, clip: CLIP, lora_hook: HookGroup):
|
|
||||||
return comfy_extras.nodes_hooks.SetClipHooks.apply_hooks(self, clip, False, lora_hook)
|
|
||||||
|
|
||||||
|
|
||||||
class CombineLoraHooksDEPR:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def execute(cls, model: ModelPatcher, ckpt_name: str, strength_model: float):
|
||||||
return {
|
model_lora, _, hooks = MaskableSDModelLoaderDEPR.execute(model=model, clip=None, ckpt_name=ckpt_name, strength_model=strength_model, strength_clip=0).args
|
||||||
"required": {
|
return io.NodeOutput(model_lora, hooks)
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"lora_hook_A": ("HOOKS",),
|
|
||||||
"lora_hook_B": ("HOOKS",),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("HOOKS",)
|
class SetModelLoraHookDEPR(io.ComfyNode):
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/conditioning/combine lora hooks"
|
|
||||||
FUNCTION = "combine_lora_hooks"
|
|
||||||
DEPRECATED = True
|
|
||||||
|
|
||||||
def combine_lora_hooks(self, lora_hook_A: HookGroup=None, lora_hook_B: HookGroup=None):
|
@classmethod
|
||||||
|
def define_schema(cls):
|
||||||
|
return io.Schema(node_id='ADE_AttachLoraHookToConditioning', display_name='Set Model LoRA Hook 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/conditioning/single cond ops', inputs=[io.Conditioning.Input('conditioning'), io.Custom('HOOKS').Input('lora_hook')], outputs=[io.Conditioning.Output('CONDITIONING')], is_deprecated=True)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def execute(cls, conditioning, lora_hook: HookGroup):
|
||||||
|
return io.NodeOutput(comfy.hooks.set_hooks_for_conditioning(conditioning, lora_hook))
|
||||||
|
|
||||||
|
class SetClipLoraHookDEPR(io.ComfyNode):
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def define_schema(cls):
|
||||||
|
return io.Schema(node_id='ADE_AttachLoraHookToCLIP', display_name='Set CLIP LoRA Hook 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/conditioning', inputs=[io.Clip.Input('clip'), io.Custom('HOOKS').Input('lora_hook')], outputs=[io.Clip.Output('hook_CLIP')], is_deprecated=True)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def execute(cls, clip: CLIP, lora_hook: HookGroup):
|
||||||
|
return io.NodeOutput(*comfy_extras.nodes_hooks.SetClipHooks.apply_hooks(cls, clip, False, lora_hook))
|
||||||
|
|
||||||
|
class CombineLoraHooksDEPR(io.ComfyNode):
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def define_schema(cls):
|
||||||
|
return io.Schema(node_id='ADE_CombineLoraHooks', display_name='Combine LoRA Hooks [2] 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/conditioning/combine lora hooks', inputs=[io.Custom('HOOKS').Input('lora_hook_A', optional=True), io.Custom('HOOKS').Input('lora_hook_B', optional=True)], outputs=[io.Custom('HOOKS').Output('HOOKS')], is_deprecated=True)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def execute(cls, lora_hook_A: HookGroup=None, lora_hook_B: HookGroup=None):
|
||||||
candidates = [lora_hook_A, lora_hook_B]
|
candidates = [lora_hook_A, lora_hook_B]
|
||||||
return (HookGroup.combine_all_hooks(candidates),)
|
return io.NodeOutput(HookGroup.combine_all_hooks(candidates))
|
||||||
|
|
||||||
|
class CombineLoraHookFourOptionalDEPR(io.ComfyNode):
|
||||||
|
|
||||||
class CombineLoraHookFourOptionalDEPR:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls):
|
||||||
return {
|
return io.Schema(node_id='ADE_CombineLoraHooksFour', display_name='Combine LoRA Hooks [4] 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/conditioning/combine lora hooks', inputs=[io.Custom('HOOKS').Input('lora_hook_A', optional=True), io.Custom('HOOKS').Input('lora_hook_B', optional=True), io.Custom('HOOKS').Input('lora_hook_C', optional=True), io.Custom('HOOKS').Input('lora_hook_D', optional=True)], outputs=[io.Custom('HOOKS').Output('HOOKS')], is_deprecated=True)
|
||||||
"required": {
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"lora_hook_A": ("HOOKS",),
|
|
||||||
"lora_hook_B": ("HOOKS",),
|
|
||||||
"lora_hook_C": ("HOOKS",),
|
|
||||||
"lora_hook_D": ("HOOKS",),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("HOOKS",)
|
@classmethod
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/conditioning/combine lora hooks"
|
def execute(cls, lora_hook_A: HookGroup=None, lora_hook_B: HookGroup=None, lora_hook_C: HookGroup=None, lora_hook_D: HookGroup=None):
|
||||||
FUNCTION = "combine_lora_hooks"
|
|
||||||
DEPRECATED = True
|
|
||||||
|
|
||||||
def combine_lora_hooks(self,
|
|
||||||
lora_hook_A: HookGroup=None, lora_hook_B: HookGroup=None,
|
|
||||||
lora_hook_C: HookGroup=None, lora_hook_D: HookGroup=None,):
|
|
||||||
candidates = [lora_hook_A, lora_hook_B, lora_hook_C, lora_hook_D]
|
candidates = [lora_hook_A, lora_hook_B, lora_hook_C, lora_hook_D]
|
||||||
return (HookGroup.combine_all_hooks(candidates),)
|
return io.NodeOutput(HookGroup.combine_all_hooks(candidates))
|
||||||
|
|
||||||
|
class CombineLoraHookEightOptionalDEPR(io.ComfyNode):
|
||||||
|
|
||||||
class CombineLoraHookEightOptionalDEPR:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls):
|
||||||
return {
|
return io.Schema(node_id='ADE_CombineLoraHooksEight', display_name='Combine LoRA Hooks [8] 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/conditioning/combine lora hooks', inputs=[io.Custom('HOOKS').Input('lora_hook_A', optional=True), io.Custom('HOOKS').Input('lora_hook_B', optional=True), io.Custom('HOOKS').Input('lora_hook_C', optional=True), io.Custom('HOOKS').Input('lora_hook_D', optional=True), io.Custom('HOOKS').Input('lora_hook_E', optional=True), io.Custom('HOOKS').Input('lora_hook_F', optional=True), io.Custom('HOOKS').Input('lora_hook_G', optional=True), io.Custom('HOOKS').Input('lora_hook_H', optional=True)], outputs=[io.Custom('HOOKS').Output('HOOKS')], is_deprecated=True)
|
||||||
"required": {
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"lora_hook_A": ("HOOKS",),
|
|
||||||
"lora_hook_B": ("HOOKS",),
|
|
||||||
"lora_hook_C": ("HOOKS",),
|
|
||||||
"lora_hook_D": ("HOOKS",),
|
|
||||||
"lora_hook_E": ("HOOKS",),
|
|
||||||
"lora_hook_F": ("HOOKS",),
|
|
||||||
"lora_hook_G": ("HOOKS",),
|
|
||||||
"lora_hook_H": ("HOOKS",),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("HOOKS",)
|
@classmethod
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/conditioning/combine lora hooks"
|
def execute(cls, lora_hook_A: HookGroup=None, lora_hook_B: HookGroup=None, lora_hook_C: HookGroup=None, lora_hook_D: HookGroup=None, lora_hook_E: HookGroup=None, lora_hook_F: HookGroup=None, lora_hook_G: HookGroup=None, lora_hook_H: HookGroup=None):
|
||||||
FUNCTION = "combine_lora_hooks"
|
candidates = [lora_hook_A, lora_hook_B, lora_hook_C, lora_hook_D, lora_hook_E, lora_hook_F, lora_hook_G, lora_hook_H]
|
||||||
DEPRECATED = True
|
return io.NodeOutput(HookGroup.combine_all_hooks(candidates))
|
||||||
|
|
||||||
def combine_lora_hooks(self,
|
|
||||||
lora_hook_A: HookGroup=None, lora_hook_B: HookGroup=None,
|
|
||||||
lora_hook_C: HookGroup=None, lora_hook_D: HookGroup=None,
|
|
||||||
lora_hook_E: HookGroup=None, lora_hook_F: HookGroup=None,
|
|
||||||
lora_hook_G: HookGroup=None, lora_hook_H: HookGroup=None):
|
|
||||||
candidates = [lora_hook_A, lora_hook_B, lora_hook_C, lora_hook_D,
|
|
||||||
lora_hook_E, lora_hook_F, lora_hook_G, lora_hook_H]
|
|
||||||
return (HookGroup.combine_all_hooks(candidates),)
|
|
||||||
|
|
||||||
# NOTE: if at some point I add more Javascript stuff to this repo, there should be a combine node
|
|
||||||
# that dynamically increases the hooks available to plug in on the node
|
|
||||||
###############################################
|
|
||||||
###############################################
|
|
||||||
###############################################
|
|
||||||
|
|||||||
+96
-377
@@ -1,442 +1,161 @@
|
|||||||
|
from comfy_api.latest import io
|
||||||
from torch import Tensor
|
from torch import Tensor
|
||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
||||||
import comfy.samplers
|
import comfy.samplers
|
||||||
from comfy.model_patcher import ModelPatcher
|
from comfy.model_patcher import ModelPatcher
|
||||||
|
from .context import ContextFuseMethod, ContextOptions, ContextOptionsGroup, ContextSchedules, generate_context_visualization
|
||||||
from .context import (ContextFuseMethod, ContextOptions, ContextOptionsGroup, ContextSchedules,
|
|
||||||
generate_context_visualization)
|
|
||||||
from .utils_model import BIGMAX, MAX_RESOLUTION
|
from .utils_model import BIGMAX, MAX_RESOLUTION
|
||||||
|
LENGTH_MAX = 128
|
||||||
|
STRIDE_MAX = 32
|
||||||
|
OVERLAP_MAX = 128
|
||||||
|
|
||||||
|
class LoopedUniformContextOptionsNode(io.ComfyNode):
|
||||||
|
|
||||||
LENGTH_MAX = 128 # keep an eye on these max values;
|
|
||||||
STRIDE_MAX = 32 # would need to be updated
|
|
||||||
OVERLAP_MAX = 128 # if new motion modules come out
|
|
||||||
|
|
||||||
|
|
||||||
class LoopedUniformContextOptionsNode:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls):
|
||||||
return {
|
return io.Schema(node_id='ADE_LoopedUniformContextOptions', display_name='Context Options◆Looped Uniform 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/context opts', inputs=[io.Int.Input('context_length', default=16, max=128, min=1), io.Int.Input('context_stride', default=1, max=32, min=1), io.Int.Input('context_overlap', default=4, max=128, min=0), io.Boolean.Input('closed_loop', default=False), io.Combo.Input('fuse_method', options=['pyramid', 'flat', 'overlap-linear', '🔬delayed reverse sawtooth', '🔬pyramid-sigma', '🔬pyramid-sigma inverse', '🔬gauss-sigma', '🔬gauss-sigma inverse', '🔬random'], optional=True), io.Boolean.Input('use_on_equal_length', optional=True, default=False), io.Float.Input('start_percent', optional=True, default=0.0, max=1.0, min=0.0, step=0.001), io.Int.Input('guarantee_steps', optional=True, default=1, max=9007199254740991, min=0), io.Custom('CONTEXT_OPTIONS').Input('prev_context', optional=True), io.Custom('VIEW_OPTS').Input('view_opts', optional=True)], outputs=[io.Custom('CONTEXT_OPTIONS').Output('CONTEXT_OPTS')])
|
||||||
"required": {
|
|
||||||
"context_length": ("INT", {"default": 16, "min": 1, "max": LENGTH_MAX}),
|
|
||||||
"context_stride": ("INT", {"default": 1, "min": 1, "max": STRIDE_MAX}),
|
|
||||||
"context_overlap": ("INT", {"default": 4, "min": 0, "max": OVERLAP_MAX}),
|
|
||||||
"closed_loop": ("BOOLEAN", {"default": False},),
|
|
||||||
#"sync_context_to_pe": ("BOOLEAN", {"default": False},),
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"fuse_method": (ContextFuseMethod.LIST,),
|
|
||||||
"use_on_equal_length": ("BOOLEAN", {"default": False},),
|
|
||||||
"start_percent": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001}),
|
|
||||||
"guarantee_steps": ("INT", {"default": 1, "min": 0, "max": BIGMAX}),
|
|
||||||
"prev_context": ("CONTEXT_OPTIONS",),
|
|
||||||
"view_opts": ("VIEW_OPTS",),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("CONTEXT_OPTIONS",)
|
@classmethod
|
||||||
RETURN_NAMES = ("CONTEXT_OPTS",)
|
def execute(cls, context_length: int, context_stride: int, context_overlap: int, closed_loop: bool, fuse_method: str=ContextFuseMethod.FLAT, use_on_equal_length=False, start_percent: float=0.0, guarantee_steps: int=1, view_opts: ContextOptions=None, prev_context: ContextOptionsGroup=None):
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/context opts"
|
|
||||||
FUNCTION = "create_options"
|
|
||||||
|
|
||||||
def create_options(self, context_length: int, context_stride: int, context_overlap: int, closed_loop: bool,
|
|
||||||
fuse_method: str=ContextFuseMethod.FLAT, use_on_equal_length=False, start_percent: float=0.0, guarantee_steps: int=1,
|
|
||||||
view_opts: ContextOptions=None, prev_context: ContextOptionsGroup=None):
|
|
||||||
if prev_context is None:
|
if prev_context is None:
|
||||||
prev_context = ContextOptionsGroup()
|
prev_context = ContextOptionsGroup()
|
||||||
prev_context = prev_context.clone()
|
prev_context = prev_context.clone()
|
||||||
|
context_options = ContextOptions(context_length=context_length, context_stride=context_stride, context_overlap=context_overlap, context_schedule=ContextSchedules.UNIFORM_LOOPED, closed_loop=closed_loop, fuse_method=fuse_method, use_on_equal_length=use_on_equal_length, start_percent=start_percent, guarantee_steps=guarantee_steps, view_options=view_opts)
|
||||||
context_options = ContextOptions(
|
|
||||||
context_length=context_length,
|
|
||||||
context_stride=context_stride,
|
|
||||||
context_overlap=context_overlap,
|
|
||||||
context_schedule=ContextSchedules.UNIFORM_LOOPED,
|
|
||||||
closed_loop=closed_loop,
|
|
||||||
fuse_method=fuse_method,
|
|
||||||
use_on_equal_length=use_on_equal_length,
|
|
||||||
start_percent=start_percent,
|
|
||||||
guarantee_steps=guarantee_steps,
|
|
||||||
view_options=view_opts,
|
|
||||||
)
|
|
||||||
#context_options.set_sync_context_to_pe(sync_context_to_pe)
|
|
||||||
prev_context.add(context_options)
|
prev_context.add(context_options)
|
||||||
return (prev_context,)
|
return io.NodeOutput(prev_context)
|
||||||
|
|
||||||
|
class LegacyLoopedUniformContextOptionsNode(io.ComfyNode):
|
||||||
|
|
||||||
# This Legacy version exists to maintain compatiblity with old workflows
|
|
||||||
class LegacyLoopedUniformContextOptionsNode:
|
|
||||||
DEPRECATED = True
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls):
|
||||||
return {
|
return io.Schema(node_id='ADE_AnimateDiffUniformContextOptions', display_name='Context Options◆Looped Uniform 🎭🅐🅓', category='', inputs=[io.Int.Input('context_length', default=16, max=128, min=1), io.Int.Input('context_stride', default=1, max=32, min=1), io.Int.Input('context_overlap', default=4, max=128, min=0), io.Combo.Input('context_schedule', options=['uniform']), io.Boolean.Input('closed_loop', default=False), io.Combo.Input('fuse_method', options=['pyramid', 'flat', 'overlap-linear', '🔬delayed reverse sawtooth', '🔬pyramid-sigma', '🔬pyramid-sigma inverse', '🔬gauss-sigma', '🔬gauss-sigma inverse', '🔬random'], optional=True, default='flat'), io.Boolean.Input('use_on_equal_length', optional=True, default=False), io.Float.Input('start_percent', optional=True, default=0.0, max=1.0, min=0.0, step=0.001), io.Int.Input('guarantee_steps', optional=True, default=1, max=9007199254740991, min=0), io.Custom('CONTEXT_OPTIONS').Input('prev_context', optional=True), io.Custom('VIEW_OPTS').Input('view_opts', optional=True)], outputs=[io.Custom('CONTEXT_OPTIONS').Output('CONTEXT_OPTS')], is_deprecated=True)
|
||||||
"required": {
|
|
||||||
"context_length": ("INT", {"default": 16, "min": 1, "max": LENGTH_MAX}),
|
|
||||||
"context_stride": ("INT", {"default": 1, "min": 1, "max": STRIDE_MAX}),
|
|
||||||
"context_overlap": ("INT", {"default": 4, "min": 0, "max": OVERLAP_MAX}),
|
|
||||||
"context_schedule": (ContextSchedules.LEGACY_UNIFORM_SCHEDULE_LIST,),
|
|
||||||
"closed_loop": ("BOOLEAN", {"default": False},),
|
|
||||||
#"sync_context_to_pe": ("BOOLEAN", {"default": False},),
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"fuse_method": (ContextFuseMethod.LIST, {"default": ContextFuseMethod.FLAT}),
|
|
||||||
"use_on_equal_length": ("BOOLEAN", {"default": False},),
|
|
||||||
"start_percent": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001}),
|
|
||||||
"guarantee_steps": ("INT", {"default": 1, "min": 0, "max": BIGMAX}),
|
|
||||||
"prev_context": ("CONTEXT_OPTIONS",),
|
|
||||||
"view_opts": ("VIEW_OPTS",),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("CONTEXT_OPTIONS",)
|
|
||||||
RETURN_NAMES = ("CONTEXT_OPTS",)
|
|
||||||
CATEGORY = "" # No Category, so will not appear in menu
|
|
||||||
FUNCTION = "create_options"
|
|
||||||
|
|
||||||
def create_options(self, fuse_method: str=ContextFuseMethod.FLAT, context_schedule: str=None, **kwargs):
|
|
||||||
return LoopedUniformContextOptionsNode.create_options(self, fuse_method=fuse_method, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
class StandardUniformContextOptionsNode:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def execute(cls, fuse_method: str=ContextFuseMethod.FLAT, context_schedule: str=None, **kwargs):
|
||||||
return {
|
return LoopedUniformContextOptionsNode.execute(fuse_method=fuse_method, **kwargs)
|
||||||
"required": {
|
|
||||||
"context_length": ("INT", {"default": 16, "min": 1, "max": LENGTH_MAX}),
|
|
||||||
"context_stride": ("INT", {"default": 1, "min": 1, "max": STRIDE_MAX}),
|
|
||||||
"context_overlap": ("INT", {"default": 4, "min": 0, "max": OVERLAP_MAX}),
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"fuse_method": (ContextFuseMethod.LIST,),
|
|
||||||
"use_on_equal_length": ("BOOLEAN", {"default": False},),
|
|
||||||
"start_percent": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001}),
|
|
||||||
"guarantee_steps": ("INT", {"default": 1, "min": 0, "max": BIGMAX}),
|
|
||||||
"prev_context": ("CONTEXT_OPTIONS",),
|
|
||||||
"view_opts": ("VIEW_OPTS",),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("CONTEXT_OPTIONS",)
|
class StandardUniformContextOptionsNode(io.ComfyNode):
|
||||||
RETURN_NAMES = ("CONTEXT_OPTS",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/context opts"
|
|
||||||
FUNCTION = "create_options"
|
|
||||||
|
|
||||||
def create_options(self, context_length: int, context_stride: int, context_overlap: int,
|
@classmethod
|
||||||
fuse_method: str=ContextFuseMethod.PYRAMID, use_on_equal_length=False, start_percent: float=0.0, guarantee_steps: int=1,
|
def define_schema(cls):
|
||||||
view_opts: ContextOptions=None, prev_context: ContextOptionsGroup=None):
|
return io.Schema(node_id='ADE_StandardUniformContextOptions', display_name='Context Options◆Standard Uniform 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/context opts', inputs=[io.Int.Input('context_length', default=16, max=128, min=1), io.Int.Input('context_stride', default=1, max=32, min=1), io.Int.Input('context_overlap', default=4, max=128, min=0), io.Combo.Input('fuse_method', options=['pyramid', 'flat', 'overlap-linear', '🔬delayed reverse sawtooth', '🔬pyramid-sigma', '🔬pyramid-sigma inverse', '🔬gauss-sigma', '🔬gauss-sigma inverse', '🔬random'], optional=True), io.Boolean.Input('use_on_equal_length', optional=True, default=False), io.Float.Input('start_percent', optional=True, default=0.0, max=1.0, min=0.0, step=0.001), io.Int.Input('guarantee_steps', optional=True, default=1, max=9007199254740991, min=0), io.Custom('CONTEXT_OPTIONS').Input('prev_context', optional=True), io.Custom('VIEW_OPTS').Input('view_opts', optional=True)], outputs=[io.Custom('CONTEXT_OPTIONS').Output('CONTEXT_OPTS')])
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def execute(cls, context_length: int, context_stride: int, context_overlap: int, fuse_method: str=ContextFuseMethod.PYRAMID, use_on_equal_length=False, start_percent: float=0.0, guarantee_steps: int=1, view_opts: ContextOptions=None, prev_context: ContextOptionsGroup=None):
|
||||||
if prev_context is None:
|
if prev_context is None:
|
||||||
prev_context = ContextOptionsGroup()
|
prev_context = ContextOptionsGroup()
|
||||||
prev_context = prev_context.clone()
|
prev_context = prev_context.clone()
|
||||||
|
context_options = ContextOptions(context_length=context_length, context_stride=context_stride, context_overlap=context_overlap, context_schedule=ContextSchedules.UNIFORM_STANDARD, closed_loop=False, fuse_method=fuse_method, use_on_equal_length=use_on_equal_length, start_percent=start_percent, guarantee_steps=guarantee_steps, view_options=view_opts)
|
||||||
context_options = ContextOptions(
|
|
||||||
context_length=context_length,
|
|
||||||
context_stride=context_stride,
|
|
||||||
context_overlap=context_overlap,
|
|
||||||
context_schedule=ContextSchedules.UNIFORM_STANDARD,
|
|
||||||
closed_loop=False,
|
|
||||||
fuse_method=fuse_method,
|
|
||||||
use_on_equal_length=use_on_equal_length,
|
|
||||||
start_percent=start_percent,
|
|
||||||
guarantee_steps=guarantee_steps,
|
|
||||||
view_options=view_opts,
|
|
||||||
)
|
|
||||||
prev_context.add(context_options)
|
prev_context.add(context_options)
|
||||||
return (prev_context,)
|
return io.NodeOutput(prev_context)
|
||||||
|
|
||||||
|
class StandardStaticContextOptionsNode(io.ComfyNode):
|
||||||
|
|
||||||
class StandardStaticContextOptionsNode:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls):
|
||||||
return {
|
return io.Schema(node_id='ADE_StandardStaticContextOptions', display_name='Context Options◆Standard Static 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/context opts', inputs=[io.Int.Input('context_length', default=16, max=128, min=1), io.Int.Input('context_overlap', default=4, max=128, min=0), io.Combo.Input('fuse_method', options=['pyramid', 'relative', 'flat', 'overlap-linear', '🔬delayed reverse sawtooth', '🔬pyramid-sigma', '🔬pyramid-sigma inverse', '🔬gauss-sigma', '🔬gauss-sigma inverse', '🔬random'], optional=True), io.Boolean.Input('use_on_equal_length', optional=True, default=False), io.Float.Input('start_percent', optional=True, default=0.0, max=1.0, min=0.0, step=0.001), io.Int.Input('guarantee_steps', optional=True, default=1, max=9007199254740991, min=0), io.Custom('CONTEXT_OPTIONS').Input('prev_context', optional=True), io.Custom('VIEW_OPTS').Input('view_opts', optional=True)], outputs=[io.Custom('CONTEXT_OPTIONS').Output('CONTEXT_OPTS')])
|
||||||
"required": {
|
|
||||||
"context_length": ("INT", {"default": 16, "min": 1, "max": LENGTH_MAX}),
|
|
||||||
"context_overlap": ("INT", {"default": 4, "min": 0, "max": OVERLAP_MAX}),
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"fuse_method": (ContextFuseMethod.LIST_STATIC,),
|
|
||||||
"use_on_equal_length": ("BOOLEAN", {"default": False},),
|
|
||||||
"start_percent": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001}),
|
|
||||||
"guarantee_steps": ("INT", {"default": 1, "min": 0, "max": BIGMAX}),
|
|
||||||
"prev_context": ("CONTEXT_OPTIONS",),
|
|
||||||
"view_opts": ("VIEW_OPTS",),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("CONTEXT_OPTIONS",)
|
@classmethod
|
||||||
RETURN_NAMES = ("CONTEXT_OPTS",)
|
def execute(cls, context_length: int, context_overlap: int, fuse_method: str=ContextFuseMethod.PYRAMID, use_on_equal_length=False, start_percent: float=0.0, guarantee_steps: int=1, view_opts: ContextOptions=None, prev_context: ContextOptionsGroup=None):
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/context opts"
|
|
||||||
FUNCTION = "create_options"
|
|
||||||
|
|
||||||
def create_options(self, context_length: int, context_overlap: int,
|
|
||||||
fuse_method: str=ContextFuseMethod.PYRAMID, use_on_equal_length=False, start_percent: float=0.0, guarantee_steps: int=1,
|
|
||||||
view_opts: ContextOptions=None, prev_context: ContextOptionsGroup=None):
|
|
||||||
if prev_context is None:
|
if prev_context is None:
|
||||||
prev_context = ContextOptionsGroup()
|
prev_context = ContextOptionsGroup()
|
||||||
prev_context = prev_context.clone()
|
prev_context = prev_context.clone()
|
||||||
|
context_options = ContextOptions(context_length=context_length, context_stride=None, context_overlap=context_overlap, context_schedule=ContextSchedules.STATIC_STANDARD, fuse_method=fuse_method, use_on_equal_length=use_on_equal_length, start_percent=start_percent, guarantee_steps=guarantee_steps, view_options=view_opts)
|
||||||
context_options = ContextOptions(
|
|
||||||
context_length=context_length,
|
|
||||||
context_stride=None,
|
|
||||||
context_overlap=context_overlap,
|
|
||||||
context_schedule=ContextSchedules.STATIC_STANDARD,
|
|
||||||
fuse_method=fuse_method,
|
|
||||||
use_on_equal_length=use_on_equal_length,
|
|
||||||
start_percent=start_percent,
|
|
||||||
guarantee_steps=guarantee_steps,
|
|
||||||
view_options=view_opts,
|
|
||||||
)
|
|
||||||
prev_context.add(context_options)
|
prev_context.add(context_options)
|
||||||
return (prev_context,)
|
return io.NodeOutput(prev_context)
|
||||||
|
|
||||||
|
class BatchedContextOptionsNode(io.ComfyNode):
|
||||||
|
|
||||||
class BatchedContextOptionsNode:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls):
|
||||||
return {
|
return io.Schema(node_id='ADE_BatchedContextOptions', display_name='Context Options◆Batched [Non-AD] 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/context opts', inputs=[io.Int.Input('context_length', default=16, max=128, min=1), io.Float.Input('start_percent', optional=True, default=0.0, max=1.0, min=0.0, step=0.001), io.Int.Input('guarantee_steps', optional=True, default=1, max=9007199254740991, min=0), io.Custom('CONTEXT_OPTIONS').Input('prev_context', optional=True)], outputs=[io.Custom('CONTEXT_OPTIONS').Output('CONTEXT_OPTS')])
|
||||||
"required": {
|
|
||||||
"context_length": ("INT", {"default": 16, "min": 1, "max": LENGTH_MAX}),
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"start_percent": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001}),
|
|
||||||
"guarantee_steps": ("INT", {"default": 1, "min": 0, "max": BIGMAX}),
|
|
||||||
"prev_context": ("CONTEXT_OPTIONS",),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("CONTEXT_OPTIONS",)
|
@classmethod
|
||||||
RETURN_NAMES = ("CONTEXT_OPTS",)
|
def execute(cls, context_length: int, start_percent: float=0.0, guarantee_steps: int=1, prev_context: ContextOptionsGroup=None):
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/context opts"
|
|
||||||
FUNCTION = "create_options"
|
|
||||||
|
|
||||||
def create_options(self, context_length: int, start_percent: float=0.0, guarantee_steps: int=1,
|
|
||||||
prev_context: ContextOptionsGroup=None):
|
|
||||||
if prev_context is None:
|
if prev_context is None:
|
||||||
prev_context = ContextOptionsGroup()
|
prev_context = ContextOptionsGroup()
|
||||||
prev_context = prev_context.clone()
|
prev_context = prev_context.clone()
|
||||||
|
context_options = ContextOptions(context_length=context_length, context_overlap=0, context_schedule=ContextSchedules.BATCHED, start_percent=start_percent, guarantee_steps=guarantee_steps)
|
||||||
context_options = ContextOptions(
|
|
||||||
context_length=context_length,
|
|
||||||
context_overlap=0,
|
|
||||||
context_schedule=ContextSchedules.BATCHED,
|
|
||||||
start_percent=start_percent,
|
|
||||||
guarantee_steps=guarantee_steps,
|
|
||||||
)
|
|
||||||
prev_context.add(context_options)
|
prev_context.add(context_options)
|
||||||
return (prev_context,)
|
return io.NodeOutput(prev_context)
|
||||||
|
|
||||||
|
class ViewAsContextOptionsNode(io.ComfyNode):
|
||||||
|
|
||||||
class ViewAsContextOptionsNode:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls):
|
||||||
return {
|
return io.Schema(node_id='ADE_ViewsOnlyContextOptions', display_name='Context Options◆Views Only [VRAM⇈] 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/context opts', inputs=[io.Custom('VIEW_OPTS').Input('view_opts_req'), io.Float.Input('start_percent', optional=True, default=0.0, max=1.0, min=0.0, step=0.001), io.Int.Input('guarantee_steps', optional=True, default=1, max=9007199254740991, min=0), io.Custom('CONTEXT_OPTIONS').Input('prev_context', optional=True)], outputs=[io.Custom('CONTEXT_OPTIONS').Output('CONTEXT_OPTS')])
|
||||||
"required": {
|
|
||||||
"view_opts_req": ("VIEW_OPTS",),
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"start_percent": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001}),
|
|
||||||
"guarantee_steps": ("INT", {"default": 1, "min": 0, "max": BIGMAX}),
|
|
||||||
"prev_context": ("CONTEXT_OPTIONS",),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("CONTEXT_OPTIONS",)
|
@classmethod
|
||||||
RETURN_NAMES = ("CONTEXT_OPTS",)
|
def execute(cls, view_opts_req: ContextOptions, start_percent: float=0.0, guarantee_steps: int=1, prev_context: ContextOptionsGroup=None):
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/context opts"
|
|
||||||
FUNCTION = "create_options"
|
|
||||||
|
|
||||||
def create_options(self, view_opts_req: ContextOptions, start_percent: float=0.0, guarantee_steps: int=1,
|
|
||||||
prev_context: ContextOptionsGroup=None):
|
|
||||||
if prev_context is None:
|
if prev_context is None:
|
||||||
prev_context = ContextOptionsGroup()
|
prev_context = ContextOptionsGroup()
|
||||||
prev_context = prev_context.clone()
|
prev_context = prev_context.clone()
|
||||||
context_options = ContextOptions(
|
context_options = ContextOptions(context_schedule=ContextSchedules.VIEW_AS_CONTEXT, start_percent=start_percent, guarantee_steps=guarantee_steps, view_options=view_opts_req, use_on_equal_length=True)
|
||||||
context_schedule=ContextSchedules.VIEW_AS_CONTEXT,
|
|
||||||
start_percent=start_percent,
|
|
||||||
guarantee_steps=guarantee_steps,
|
|
||||||
view_options=view_opts_req,
|
|
||||||
use_on_equal_length=True
|
|
||||||
)
|
|
||||||
prev_context.add(context_options)
|
prev_context.add(context_options)
|
||||||
return (prev_context,)
|
return io.NodeOutput(prev_context)
|
||||||
|
|
||||||
|
class StandardStaticViewOptionsNode(io.ComfyNode):
|
||||||
|
|
||||||
#########################
|
|
||||||
# View Options
|
|
||||||
class StandardStaticViewOptionsNode:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls):
|
||||||
return {
|
return io.Schema(node_id='ADE_StandardStaticViewOptions', display_name='View Options◆Standard Static 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/context opts/view opts', inputs=[io.Int.Input('view_length', default=16, max=128, min=1), io.Int.Input('view_overlap', default=4, max=128, min=0), io.Combo.Input('fuse_method', options=['pyramid', 'flat', 'overlap-linear', '🔬delayed reverse sawtooth', '🔬pyramid-sigma', '🔬pyramid-sigma inverse', '🔬gauss-sigma', '🔬gauss-sigma inverse', '🔬random'], optional=True)], outputs=[io.Custom('VIEW_OPTS').Output('VIEW_OPTS')])
|
||||||
"required": {
|
|
||||||
"view_length": ("INT", {"default": 16, "min": 1, "max": LENGTH_MAX}),
|
|
||||||
"view_overlap": ("INT", {"default": 4, "min": 0, "max": OVERLAP_MAX}),
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"fuse_method": (ContextFuseMethod.LIST,),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("VIEW_OPTS",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/context opts/view opts"
|
|
||||||
FUNCTION = "create_options"
|
|
||||||
|
|
||||||
def create_options(self, view_length: int, view_overlap: int,
|
|
||||||
fuse_method: str=ContextFuseMethod.FLAT,):
|
|
||||||
view_options = ContextOptions(
|
|
||||||
context_length=view_length,
|
|
||||||
context_stride=None,
|
|
||||||
context_overlap=view_overlap,
|
|
||||||
context_schedule=ContextSchedules.STATIC_STANDARD,
|
|
||||||
fuse_method=fuse_method,
|
|
||||||
)
|
|
||||||
return (view_options,)
|
|
||||||
|
|
||||||
|
|
||||||
class StandardUniformViewOptionsNode:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def execute(cls, view_length: int, view_overlap: int, fuse_method: str=ContextFuseMethod.FLAT):
|
||||||
return {
|
view_options = ContextOptions(context_length=view_length, context_stride=None, context_overlap=view_overlap, context_schedule=ContextSchedules.STATIC_STANDARD, fuse_method=fuse_method)
|
||||||
"required": {
|
return io.NodeOutput(view_options)
|
||||||
"view_length": ("INT", {"default": 16, "min": 1, "max": LENGTH_MAX}),
|
|
||||||
"view_stride": ("INT", {"default": 1, "min": 1, "max": STRIDE_MAX}),
|
|
||||||
"view_overlap": ("INT", {"default": 4, "min": 0, "max": OVERLAP_MAX}),
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"fuse_method": (ContextFuseMethod.LIST,),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("VIEW_OPTS",)
|
class StandardUniformViewOptionsNode(io.ComfyNode):
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/context opts/view opts"
|
|
||||||
FUNCTION = "create_options"
|
|
||||||
|
|
||||||
def create_options(self, view_length: int, view_overlap: int, view_stride: int,
|
|
||||||
fuse_method: str=ContextFuseMethod.PYRAMID,):
|
|
||||||
view_options = ContextOptions(
|
|
||||||
context_length=view_length,
|
|
||||||
context_stride=view_stride,
|
|
||||||
context_overlap=view_overlap,
|
|
||||||
context_schedule=ContextSchedules.UNIFORM_STANDARD,
|
|
||||||
fuse_method=fuse_method,
|
|
||||||
)
|
|
||||||
return (view_options,)
|
|
||||||
|
|
||||||
|
|
||||||
class LoopedUniformViewOptionsNode:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls):
|
||||||
return {
|
return io.Schema(node_id='ADE_StandardUniformViewOptions', display_name='View Options◆Standard Uniform 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/context opts/view opts', inputs=[io.Int.Input('view_length', default=16, max=128, min=1), io.Int.Input('view_stride', default=1, max=32, min=1), io.Int.Input('view_overlap', default=4, max=128, min=0), io.Combo.Input('fuse_method', options=['pyramid', 'flat', 'overlap-linear', '🔬delayed reverse sawtooth', '🔬pyramid-sigma', '🔬pyramid-sigma inverse', '🔬gauss-sigma', '🔬gauss-sigma inverse', '🔬random'], optional=True)], outputs=[io.Custom('VIEW_OPTS').Output('VIEW_OPTS')])
|
||||||
"required": {
|
|
||||||
"view_length": ("INT", {"default": 16, "min": 1, "max": LENGTH_MAX}),
|
|
||||||
"view_stride": ("INT", {"default": 1, "min": 1, "max": STRIDE_MAX}),
|
|
||||||
"view_overlap": ("INT", {"default": 4, "min": 0, "max": OVERLAP_MAX}),
|
|
||||||
"closed_loop": ("BOOLEAN", {"default": False},),
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"fuse_method": (ContextFuseMethod.LIST,),
|
|
||||||
"use_on_equal_length": ("BOOLEAN", {"default": False},),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("VIEW_OPTS",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/context opts/view opts"
|
|
||||||
FUNCTION = "create_options"
|
|
||||||
|
|
||||||
def create_options(self, view_length: int, view_overlap: int, view_stride: int, closed_loop: bool,
|
|
||||||
fuse_method: str=ContextFuseMethod.PYRAMID, use_on_equal_length=False):
|
|
||||||
view_options = ContextOptions(
|
|
||||||
context_length=view_length,
|
|
||||||
context_stride=view_stride,
|
|
||||||
context_overlap=view_overlap,
|
|
||||||
context_schedule=ContextSchedules.UNIFORM_LOOPED,
|
|
||||||
closed_loop=closed_loop,
|
|
||||||
fuse_method=fuse_method,
|
|
||||||
use_on_equal_length=use_on_equal_length,
|
|
||||||
)
|
|
||||||
return (view_options,)
|
|
||||||
|
|
||||||
|
|
||||||
class VisualizeContextOptionsKAdv:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def execute(cls, view_length: int, view_overlap: int, view_stride: int, fuse_method: str=ContextFuseMethod.PYRAMID):
|
||||||
return {
|
view_options = ContextOptions(context_length=view_length, context_stride=view_stride, context_overlap=view_overlap, context_schedule=ContextSchedules.UNIFORM_STANDARD, fuse_method=fuse_method)
|
||||||
"required": {
|
return io.NodeOutput(view_options)
|
||||||
"model": ("MODEL",),
|
|
||||||
"sampler_name": (comfy.samplers.KSampler.SAMPLERS, ),
|
|
||||||
"scheduler": (comfy.samplers.KSampler.SCHEDULERS, ),
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"context_opts": ("CONTEXT_OPTIONS",),
|
|
||||||
"visual_width": ("INT", {"min": 32, "max": MAX_RESOLUTION, "default": 1440}),
|
|
||||||
"latents_length": ("INT", {"min": 1, "max": BIGMAX, "default": 32}),
|
|
||||||
"steps": ("INT", {"min": 0, "max": BIGMAX, "default": 20}),
|
|
||||||
"start_step": ("INT", {"min": 0, "max": BIGMAX, "default": 0}),
|
|
||||||
"end_step": ("INT", {"min": 1, "max": BIGMAX, "default": 20}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("IMAGE",)
|
class LoopedUniformViewOptionsNode(io.ComfyNode):
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/context opts/visualize"
|
|
||||||
FUNCTION = "visualize"
|
|
||||||
|
|
||||||
def visualize(self, model: ModelPatcher, sampler_name: str, scheduler: str, context_opts: ContextOptionsGroup=None,
|
|
||||||
visual_width=1440, latents_length=32, steps=20, start_step=0, end_step=20):
|
|
||||||
images = generate_context_visualization(model=model, context_opts=context_opts, width=visual_width, video_length=latents_length,
|
|
||||||
sampler_name=sampler_name, scheduler=scheduler,
|
|
||||||
steps=steps, start_step=start_step, end_step=end_step)
|
|
||||||
return (images,)
|
|
||||||
|
|
||||||
|
|
||||||
class VisualizeContextOptionsK:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls):
|
||||||
return {
|
return io.Schema(node_id='ADE_LoopedUniformViewOptions', display_name='View Options◆Looped Uniform 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/context opts/view opts', inputs=[io.Int.Input('view_length', default=16, max=128, min=1), io.Int.Input('view_stride', default=1, max=32, min=1), io.Int.Input('view_overlap', default=4, max=128, min=0), io.Boolean.Input('closed_loop', default=False), io.Combo.Input('fuse_method', options=['pyramid', 'flat', 'overlap-linear', '🔬delayed reverse sawtooth', '🔬pyramid-sigma', '🔬pyramid-sigma inverse', '🔬gauss-sigma', '🔬gauss-sigma inverse', '🔬random'], optional=True), io.Boolean.Input('use_on_equal_length', optional=True, default=False)], outputs=[io.Custom('VIEW_OPTS').Output('VIEW_OPTS')])
|
||||||
"required": {
|
|
||||||
"model": ("MODEL",),
|
|
||||||
"sampler_name": (comfy.samplers.KSampler.SAMPLERS, ),
|
|
||||||
"scheduler": (comfy.samplers.KSampler.SCHEDULERS, ),
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"context_opts": ("CONTEXT_OPTIONS",),
|
|
||||||
"visual_width": ("INT", {"min": 32, "max": MAX_RESOLUTION, "default": 1440}),
|
|
||||||
"latents_length": ("INT", {"min": 1, "max": BIGMAX, "default": 32}),
|
|
||||||
"steps": ("INT", {"min": 0, "max": BIGMAX, "default": 20}),
|
|
||||||
"denoise": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("IMAGE",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/context opts/visualize"
|
|
||||||
FUNCTION = "visualize"
|
|
||||||
|
|
||||||
def visualize(self, model: ModelPatcher, sampler_name: str, scheduler: str, context_opts: ContextOptionsGroup=None,
|
|
||||||
visual_width=1440, latents_length=32, steps=20, denoise=1.0):
|
|
||||||
images = generate_context_visualization(model=model, context_opts=context_opts, width=visual_width, video_length=latents_length,
|
|
||||||
sampler_name=sampler_name, scheduler=scheduler,
|
|
||||||
steps=steps, denoise=denoise)
|
|
||||||
return (images,)
|
|
||||||
|
|
||||||
|
|
||||||
class VisualizeContextOptionsSCustom:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def execute(cls, view_length: int, view_overlap: int, view_stride: int, closed_loop: bool, fuse_method: str=ContextFuseMethod.PYRAMID, use_on_equal_length=False):
|
||||||
return {
|
view_options = ContextOptions(context_length=view_length, context_stride=view_stride, context_overlap=view_overlap, context_schedule=ContextSchedules.UNIFORM_LOOPED, closed_loop=closed_loop, fuse_method=fuse_method, use_on_equal_length=use_on_equal_length)
|
||||||
"required": {
|
return io.NodeOutput(view_options)
|
||||||
"model": ("MODEL",),
|
|
||||||
"sigmas": ("SIGMAS", ),
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"context_opts": ("CONTEXT_OPTIONS",),
|
|
||||||
"visual_width": ("INT", {"min": 32, "max": MAX_RESOLUTION, "default": 1440}),
|
|
||||||
"latents_length": ("INT", {"min": 1, "max": BIGMAX, "default": 32}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("IMAGE",)
|
class VisualizeContextOptionsKAdv(io.ComfyNode):
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/context opts/visualize"
|
|
||||||
FUNCTION = "visualize"
|
|
||||||
|
|
||||||
def visualize(self, model: ModelPatcher, sigmas, context_opts: ContextOptionsGroup=None,
|
@classmethod
|
||||||
visual_width=1440, latents_length=32):
|
def define_schema(cls):
|
||||||
images = generate_context_visualization(model=model, context_opts=context_opts, width=visual_width, video_length=latents_length,
|
return io.Schema(node_id='ADE_VisualizeContextOptionsKAdv', display_name='Visualize Context Options (K.Adv.) 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/context opts/visualize', inputs=[io.Model.Input('model'), io.Combo.Input('sampler_name', options=comfy.samplers.KSampler.SAMPLERS), io.Combo.Input('scheduler', options=comfy.samplers.KSampler.SCHEDULERS), io.Custom('CONTEXT_OPTIONS').Input('context_opts', optional=True), io.Int.Input('visual_width', optional=True, default=1440, max=16384, min=32), io.Int.Input('latents_length', optional=True, default=32, max=9007199254740991, min=1), io.Int.Input('steps', optional=True, default=20, max=9007199254740991, min=0), io.Int.Input('start_step', optional=True, default=0, max=9007199254740991, min=0), io.Int.Input('end_step', optional=True, default=20, max=9007199254740991, min=1)], outputs=[io.Image.Output('IMAGE')])
|
||||||
sigmas=sigmas)
|
|
||||||
return (images,)
|
@classmethod
|
||||||
|
def execute(cls, model: ModelPatcher, sampler_name: str, scheduler: str, context_opts: ContextOptionsGroup=None, visual_width=1440, latents_length=32, steps=20, start_step=0, end_step=20):
|
||||||
|
images = generate_context_visualization(model=model, context_opts=context_opts, width=visual_width, video_length=latents_length, sampler_name=sampler_name, scheduler=scheduler, steps=steps, start_step=start_step, end_step=end_step)
|
||||||
|
return io.NodeOutput(images)
|
||||||
|
|
||||||
|
class VisualizeContextOptionsK(io.ComfyNode):
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def define_schema(cls):
|
||||||
|
return io.Schema(node_id='ADE_VisualizeContextOptionsK', display_name='Visualize Context Options (K.) 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/context opts/visualize', inputs=[io.Model.Input('model'), io.Combo.Input('sampler_name', options=comfy.samplers.KSampler.SAMPLERS), io.Combo.Input('scheduler', options=comfy.samplers.KSampler.SCHEDULERS), io.Custom('CONTEXT_OPTIONS').Input('context_opts', optional=True), io.Int.Input('visual_width', optional=True, default=1440, max=16384, min=32), io.Int.Input('latents_length', optional=True, default=32, max=9007199254740991, min=1), io.Int.Input('steps', optional=True, default=20, max=9007199254740991, min=0), io.Float.Input('denoise', optional=True, default=1.0, max=1.0, min=0.0, step=0.01)], outputs=[io.Image.Output('IMAGE')])
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def execute(cls, model: ModelPatcher, sampler_name: str, scheduler: str, context_opts: ContextOptionsGroup=None, visual_width=1440, latents_length=32, steps=20, denoise=1.0):
|
||||||
|
images = generate_context_visualization(model=model, context_opts=context_opts, width=visual_width, video_length=latents_length, sampler_name=sampler_name, scheduler=scheduler, steps=steps, denoise=denoise)
|
||||||
|
return io.NodeOutput(images)
|
||||||
|
|
||||||
|
class VisualizeContextOptionsSCustom(io.ComfyNode):
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def define_schema(cls):
|
||||||
|
return io.Schema(node_id='ADE_VisualizeContextOptionsSCustom', display_name='Visualize Context Options (S.Cus.) 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/context opts/visualize', inputs=[io.Model.Input('model'), io.Sigmas.Input('sigmas'), io.Custom('CONTEXT_OPTIONS').Input('context_opts', optional=True), io.Int.Input('visual_width', optional=True, default=1440, max=16384, min=32), io.Int.Input('latents_length', optional=True, default=32, max=9007199254740991, min=1)], outputs=[io.Image.Output('IMAGE')])
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def execute(cls, model: ModelPatcher, sigmas, context_opts: ContextOptionsGroup=None, visual_width=1440, latents_length=32):
|
||||||
|
images = generate_context_visualization(model=model, context_opts=context_opts, width=visual_width, video_length=latents_length, sigmas=sigmas)
|
||||||
|
return io.NodeOutput(images)
|
||||||
|
|||||||
+104
-350
@@ -1,182 +1,89 @@
|
|||||||
|
from comfy_api.latest import io
|
||||||
from torch import Tensor
|
from torch import Tensor
|
||||||
from typing import Union
|
from typing import Union
|
||||||
from collections.abc import Iterable
|
from collections.abc import Iterable
|
||||||
|
from .context import ContextOptionsGroup
|
||||||
from .context import (ContextOptionsGroup)
|
from .context_extras import ContextExtrasGroup, ContextRef, ContextRefTune, ContextRefMode, ContextRefKeyframeGroup, ContextRefKeyframe, NaiveReuse, NaiveReuseKeyframe, NaiveReuseKeyframeGroup
|
||||||
from .context_extras import (ContextExtrasGroup,
|
|
||||||
ContextRef, ContextRefTune, ContextRefMode, ContextRefKeyframeGroup, ContextRefKeyframe,
|
|
||||||
NaiveReuse, NaiveReuseKeyframe, NaiveReuseKeyframeGroup)
|
|
||||||
from .utils_model import BIGMAX, InterpolationMethod
|
from .utils_model import BIGMAX, InterpolationMethod
|
||||||
from .utils_scheduling import convert_str_to_indexes
|
from .utils_scheduling import convert_str_to_indexes
|
||||||
from .logger import logger
|
from .logger import logger
|
||||||
|
|
||||||
|
class SetContextExtrasOnContextOptions(io.ComfyNode):
|
||||||
|
|
||||||
class SetContextExtrasOnContextOptions:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls):
|
||||||
return {
|
return io.Schema(node_id='ADE_ContextExtras_Set', display_name='Set Context Extras 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/context opts/context extras', inputs=[io.Custom('CONTEXT_OPTIONS').Input('context_opts'), io.Custom('CONTEXT_EXTRAS').Input('context_extras', optional=True)], outputs=[io.Custom('CONTEXT_OPTIONS').Output('CONTEXT_OPTS')])
|
||||||
"required": {
|
|
||||||
"context_opts": ("CONTEXT_OPTIONS",),
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"context_extras": ("CONTEXT_EXTRAS",),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("CONTEXT_OPTIONS",)
|
@classmethod
|
||||||
RETURN_NAMES = ("CONTEXT_OPTS",)
|
def execute(cls, context_opts: ContextOptionsGroup, context_extras: ContextExtrasGroup=None):
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/context opts/context extras"
|
|
||||||
FUNCTION = "set_context_extras"
|
|
||||||
|
|
||||||
def set_context_extras(self, context_opts: ContextOptionsGroup, context_extras: ContextExtrasGroup=None):
|
|
||||||
context_opts = context_opts.clone()
|
context_opts = context_opts.clone()
|
||||||
if context_extras is not None:
|
if context_extras is not None:
|
||||||
context_opts.extras = context_extras.clone()
|
context_opts.extras = context_extras.clone()
|
||||||
return (context_opts,)
|
return io.NodeOutput(context_opts)
|
||||||
|
|
||||||
|
class ContextExtras_NaiveReuse(io.ComfyNode):
|
||||||
|
|
||||||
#########################################
|
|
||||||
# NaiveReuse
|
|
||||||
class ContextExtras_NaiveReuse:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls):
|
||||||
return {
|
return io.Schema(node_id='ADE_ContextExtras_NaiveReuse', display_name='Context Extras◆NaiveReuse 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/context opts/context extras', inputs=[io.Custom('CONTEXT_EXTRAS').Input('prev_extras', optional=True), io.Custom('MULTIVAL').Input('strength_multival', optional=True), io.Custom('NAIVEREUSE_KEYFRAME').Input('naivereuse_kf', optional=True), io.Float.Input('start_percent', optional=True, default=0.0, max=1.0, min=0.0, step=0.001), io.Float.Input('end_percent', optional=True, default=0.15, max=1.0, min=0.0, step=0.001), io.Float.Input('weighted_mean', optional=True, default=0.95, max=1.0, min=0.0, step=0.001)], outputs=[io.Custom('CONTEXT_EXTRAS').Output('CONTEXT_EXTRAS')])
|
||||||
"required": {
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"prev_extras": ("CONTEXT_EXTRAS",),
|
|
||||||
"strength_multival": ("MULTIVAL",),
|
|
||||||
"naivereuse_kf": ("NAIVEREUSE_KEYFRAME",),
|
|
||||||
"start_percent": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001}),
|
|
||||||
"end_percent": ("FLOAT", {"default": 0.15, "min": 0.0, "max": 1.0, "step": 0.001}),
|
|
||||||
"weighted_mean": ("FLOAT", {"default": 0.95, "min": 0.0, "max": 1.0, "step": 0.001}),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("CONTEXT_EXTRAS",)
|
@classmethod
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/context opts/context extras"
|
def execute(cls, start_percent=0.0, end_percent=0.1, weighted_mean=0.95, strength_multival: Union[float, Tensor]=None, naivereuse_kf: NaiveReuseKeyframeGroup=None, prev_extras: ContextExtrasGroup=None):
|
||||||
FUNCTION = "create_context_extra"
|
|
||||||
|
|
||||||
def create_context_extra(self, start_percent=0.0, end_percent=0.1, weighted_mean=0.95, strength_multival: Union[float, Tensor]=None,
|
|
||||||
naivereuse_kf: NaiveReuseKeyframeGroup=None, prev_extras: ContextExtrasGroup=None):
|
|
||||||
if prev_extras is None:
|
if prev_extras is None:
|
||||||
prev_extras = prev_extras = ContextExtrasGroup()
|
prev_extras = prev_extras = ContextExtrasGroup()
|
||||||
prev_extras = prev_extras.clone()
|
prev_extras = prev_extras.clone()
|
||||||
# create extra
|
naive_reuse = NaiveReuse(start_percent=start_percent, end_percent=end_percent, weighted_mean=weighted_mean, multival_opt=strength_multival, naivereuse_kf=naivereuse_kf)
|
||||||
naive_reuse = NaiveReuse(start_percent=start_percent, end_percent=end_percent, weighted_mean=weighted_mean, multival_opt=strength_multival,
|
|
||||||
naivereuse_kf=naivereuse_kf)
|
|
||||||
prev_extras.add(naive_reuse)
|
prev_extras.add(naive_reuse)
|
||||||
return (prev_extras,)
|
return io.NodeOutput(prev_extras)
|
||||||
|
|
||||||
|
class NaiveReuse_KeyframeMultivalNode(io.ComfyNode):
|
||||||
|
|
||||||
class NaiveReuse_KeyframeMultivalNode:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls):
|
||||||
return {
|
return io.Schema(node_id='ADE_ContextExtras_NaiveReuse_Keyframe', display_name='NaiveReuse Keyframe 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/context opts/context extras/naivereuse', inputs=[io.Custom('NAIVEREUSE_KEYFRAME').Input('prev_kf', optional=True), io.Custom('MULTIVAL').Input('mult_multival', optional=True), io.Float.Input('mult', optional=True, default=1.0, max=1.0, min=0.0, step=0.001), io.Float.Input('start_percent', optional=True, default=0.0, max=1.0, min=0.0, step=0.001), io.Int.Input('guarantee_steps', optional=True, default=1, max=9007199254740991, min=0), io.Boolean.Input('inherit_missing', optional=True, default=True)], outputs=[io.Custom('NAIVEREUSE_KEYFRAME').Output('NAIVEREUSE_KF')])
|
||||||
"required": {
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"prev_kf": ("NAIVEREUSE_KEYFRAME",),
|
|
||||||
"mult_multival": ("MULTIVAL",),
|
|
||||||
"mult": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.001}),
|
|
||||||
"start_percent": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001}),
|
|
||||||
"guarantee_steps": ("INT", {"default": 1, "min": 0, "max": BIGMAX}),
|
|
||||||
"inherit_missing": ("BOOLEAN", {"default": True}, ),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("NAIVEREUSE_KEYFRAME",)
|
@classmethod
|
||||||
RETURN_NAMES = ("NAIVEREUSE_KF",)
|
def execute(cls, prev_kf=None, mult=1.0, mult_multival=None, start_percent=0.0, guarantee_steps=1, inherit_missing=True):
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/context opts/context extras/naivereuse"
|
|
||||||
FUNCTION = "create_keyframe"
|
|
||||||
|
|
||||||
def create_keyframe(self, prev_kf=None, mult=1.0, mult_multival=None,
|
|
||||||
start_percent=0.0, guarantee_steps=1, inherit_missing=True):
|
|
||||||
if prev_kf is None:
|
if prev_kf is None:
|
||||||
prev_kf = NaiveReuseKeyframeGroup()
|
prev_kf = NaiveReuseKeyframeGroup()
|
||||||
prev_kf = prev_kf.clone()
|
prev_kf = prev_kf.clone()
|
||||||
kf = NaiveReuseKeyframe(mult=mult, mult_multival=mult_multival,
|
kf = NaiveReuseKeyframe(mult=mult, mult_multival=mult_multival, start_percent=start_percent, guarantee_steps=guarantee_steps, inherit_missing=inherit_missing)
|
||||||
start_percent=start_percent, guarantee_steps=guarantee_steps, inherit_missing=inherit_missing)
|
|
||||||
prev_kf.add(kf)
|
prev_kf.add(kf)
|
||||||
return (prev_kf,)
|
return io.NodeOutput(prev_kf)
|
||||||
|
|
||||||
|
class NaiveReuse_KeyframeInterpolationNode(io.ComfyNode):
|
||||||
|
|
||||||
class NaiveReuse_KeyframeInterpolationNode:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls):
|
||||||
return {
|
return io.Schema(node_id='ADE_ContextExtras_NaiveReuse_KeyframeInterpolation', display_name='NaiveReuse Keyframes Interp. 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/context opts/context extras/naivereuse', inputs=[io.Float.Input('start_percent', default=0.0, max=1.0, min=0.0, step=0.001), io.Float.Input('end_percent', default=1.0, max=1.0, min=0.0, step=0.001), io.Float.Input('mult_start', default=1.0, max=1.0, min=0.0, step=0.001), io.Float.Input('mult_end', default=1.0, max=1.0, min=0.0, step=0.001), io.Combo.Input('interpolation', options=['linear', 'ease_in', 'ease_out', 'ease_in_out']), io.Int.Input('intervals', default=50, max=100, min=2, step=1), io.Boolean.Input('inherit_missing', default=True), io.Boolean.Input('print_keyframes', default=False), io.Custom('NAIVEREUSE_KEYFRAME').Input('prev_kf', optional=True), io.Custom('MULTIVAL').Input('mult_multival', optional=True)], outputs=[io.Custom('NAIVEREUSE_KEYFRAME').Output('NAIVEREUSE_KF')])
|
||||||
"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}),
|
|
||||||
"mult_start": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.001}),
|
|
||||||
"mult_end": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.001}),
|
|
||||||
"interpolation": (InterpolationMethod._LIST, ),
|
|
||||||
"intervals": ("INT", {"default": 50, "min": 2, "max": 100, "step": 1}),
|
|
||||||
"inherit_missing": ("BOOLEAN", {"default": True}),
|
|
||||||
"print_keyframes": ("BOOLEAN", {"default": False}),
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"prev_kf": ("NAIVEREUSE_KEYFRAME",),
|
|
||||||
"mult_multival": ("MULTIVAL",),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("NAIVEREUSE_KEYFRAME",)
|
@classmethod
|
||||||
RETURN_NAMES = ("NAIVEREUSE_KF",)
|
def execute(cls, start_percent: float, end_percent: float, mult_start: float, mult_end: float, interpolation: str, intervals: int, inherit_missing=True, prev_kf: NaiveReuseKeyframeGroup=None, mult_multival=None, print_keyframes=False):
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/context opts/context extras/naivereuse"
|
|
||||||
FUNCTION = "create_keyframe"
|
|
||||||
|
|
||||||
def create_keyframe(self,
|
|
||||||
start_percent: float, end_percent: float,
|
|
||||||
mult_start: float, mult_end: float, interpolation: str, intervals: int,
|
|
||||||
inherit_missing=True, prev_kf: NaiveReuseKeyframeGroup=None,
|
|
||||||
mult_multival=None, print_keyframes=False):
|
|
||||||
if prev_kf is None:
|
if prev_kf is None:
|
||||||
prev_kf = NaiveReuseKeyframeGroup()
|
prev_kf = NaiveReuseKeyframeGroup()
|
||||||
prev_kf = prev_kf.clone()
|
prev_kf = prev_kf.clone()
|
||||||
prev_kf = prev_kf.clone()
|
prev_kf = prev_kf.clone()
|
||||||
percents = InterpolationMethod.get_weights(num_from=start_percent, num_to=end_percent, length=intervals, method=InterpolationMethod.LINEAR)
|
percents = InterpolationMethod.get_weights(num_from=start_percent, num_to=end_percent, length=intervals, method=InterpolationMethod.LINEAR)
|
||||||
mults = InterpolationMethod.get_weights(num_from=mult_start, num_to=mult_end, length=intervals, method=interpolation)
|
mults = InterpolationMethod.get_weights(num_from=mult_start, num_to=mult_end, length=intervals, method=interpolation)
|
||||||
|
|
||||||
is_first = True
|
is_first = True
|
||||||
for percent, mult in zip(percents, mults):
|
for percent, mult in zip(percents, mults):
|
||||||
guarantee_steps = 0
|
guarantee_steps = 0
|
||||||
if is_first:
|
if is_first:
|
||||||
guarantee_steps = 1
|
guarantee_steps = 1
|
||||||
is_first = False
|
is_first = False
|
||||||
prev_kf.add(NaiveReuseKeyframe(mult=mult, mult_multival=mult_multival,
|
prev_kf.add(NaiveReuseKeyframe(mult=mult, mult_multival=mult_multival, start_percent=percent, guarantee_steps=guarantee_steps, inherit_missing=inherit_missing))
|
||||||
start_percent=percent, guarantee_steps=guarantee_steps, inherit_missing=inherit_missing))
|
|
||||||
if print_keyframes:
|
if print_keyframes:
|
||||||
logger.info(f"NaiveReuseKeyframe - start_percent:{percent} = {mult}")
|
logger.info(f'NaiveReuseKeyframe - start_percent:{percent} = {mult}')
|
||||||
return (prev_kf,)
|
return io.NodeOutput(prev_kf)
|
||||||
|
|
||||||
|
class NaiveReuse_KeyframeFromListNode(io.ComfyNode):
|
||||||
|
|
||||||
class NaiveReuse_KeyframeFromListNode:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls):
|
||||||
return {
|
return io.Schema(node_id='ADE_ContextExtras_NaiveReuse_KeyframeFromList', display_name='NaiveReuse Keyframes From List 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/context opts/context extras/naivereuse', inputs=[io.Float.Input('mults_float', default=-1, force_input=True, min=-1, step=0.001), io.Float.Input('start_percent', default=0.0, max=1.0, min=0.0, step=0.001), io.Float.Input('end_percent', default=1.0, max=1.0, min=0.0, step=0.001), io.Boolean.Input('inherit_missing', default=True), io.Boolean.Input('print_keyframes', default=False), io.Custom('NAIVEREUSE_KEYFRAME').Input('prev_kf', optional=True), io.Custom('MULTIVAL').Input('mult_multival', optional=True)], outputs=[io.Custom('NAIVEREUSE_KEYFRAME').Output('NAIVEREUSE_KF')])
|
||||||
"required": {
|
|
||||||
"mults_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}),
|
|
||||||
"inherit_missing": ("BOOLEAN", {"default": True}),
|
|
||||||
"print_keyframes": ("BOOLEAN", {"default": False}),
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"prev_kf": ("NAIVEREUSE_KEYFRAME",),
|
|
||||||
"mult_multival": ("MULTIVAL",),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("NAIVEREUSE_KEYFRAME",)
|
@classmethod
|
||||||
RETURN_NAMES = ("NAIVEREUSE_KF",)
|
def execute(cls, mults_float: Union[float, list[float]], start_percent: float, end_percent: float, inherit_missing=True, prev_kf: NaiveReuseKeyframeGroup=None, mult_multival=None, print_keyframes=False):
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/context opts/context extras/naivereuse"
|
|
||||||
FUNCTION = "create_keyframe"
|
|
||||||
|
|
||||||
def create_keyframe(self, mults_float: Union[float, list[float]],
|
|
||||||
start_percent: float, end_percent: float,
|
|
||||||
inherit_missing=True, prev_kf: NaiveReuseKeyframeGroup=None,
|
|
||||||
mult_multival=None, print_keyframes=False):
|
|
||||||
if prev_kf is None:
|
if prev_kf is None:
|
||||||
prev_kf = NaiveReuseKeyframeGroup()
|
prev_kf = NaiveReuseKeyframeGroup()
|
||||||
prev_kf = prev_kf.clone()
|
prev_kf = prev_kf.clone()
|
||||||
@@ -185,180 +92,85 @@ class NaiveReuse_KeyframeFromListNode:
|
|||||||
elif isinstance(mults_float, Iterable):
|
elif isinstance(mults_float, Iterable):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
raise Exception(f"strengths_float must be either an interable input or a float, but was {type(mults_float).__repr__}.")
|
raise Exception(f'strengths_float must be either an interable input or a float, but was {type(mults_float).__repr__}.')
|
||||||
percents = InterpolationMethod.get_weights(num_from=start_percent, num_to=end_percent, length=len(mults_float), method=InterpolationMethod.LINEAR)
|
percents = InterpolationMethod.get_weights(num_from=start_percent, num_to=end_percent, length=len(mults_float), method=InterpolationMethod.LINEAR)
|
||||||
|
|
||||||
is_first = True
|
is_first = True
|
||||||
for percent, mult in zip(percents, mults_float):
|
for percent, mult in zip(percents, mults_float):
|
||||||
guarantee_steps = 0
|
guarantee_steps = 0
|
||||||
if is_first:
|
if is_first:
|
||||||
guarantee_steps = 1
|
guarantee_steps = 1
|
||||||
is_first = False
|
is_first = False
|
||||||
prev_kf.add(NaiveReuseKeyframe(mult=mult, mult_multival=mult_multival,
|
prev_kf.add(NaiveReuseKeyframe(mult=mult, mult_multival=mult_multival, start_percent=percent, guarantee_steps=guarantee_steps, inherit_missing=inherit_missing))
|
||||||
start_percent=percent, guarantee_steps=guarantee_steps, inherit_missing=inherit_missing))
|
|
||||||
if print_keyframes:
|
if print_keyframes:
|
||||||
logger.info(f"NaiveReuseKeyframe - start_percent:{percent} = {mult}")
|
logger.info(f'NaiveReuseKeyframe - start_percent:{percent} = {mult}')
|
||||||
return (prev_kf,)
|
return io.NodeOutput(prev_kf)
|
||||||
#----------------------------------------
|
|
||||||
#########################################
|
|
||||||
|
|
||||||
|
class ContextExtras_ContextRef(io.ComfyNode):
|
||||||
|
|
||||||
#########################################
|
|
||||||
# ContextRef
|
|
||||||
class ContextExtras_ContextRef:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls):
|
||||||
return {
|
return io.Schema(node_id='ADE_ContextExtras_ContextRef', display_name='Context Extras◆ContextRef 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/context opts/context extras', inputs=[io.Custom('CONTEXT_EXTRAS').Input('prev_extras', optional=True), io.Custom('MULTIVAL').Input('strength_multival', optional=True), io.Custom('CONTEXTREF_MODE').Input('contextref_mode', optional=True), io.Custom('CONTEXTREF_TUNE').Input('contextref_tune', optional=True), io.Custom('CONTEXTREF_KEYFRAME').Input('contextref_kf', optional=True), io.Float.Input('start_percent', optional=True, default=0.0, max=1.0, min=0.0, step=0.001), io.Float.Input('end_percent', optional=True, default=0.25, max=1.0, min=0.0, step=0.001)], outputs=[io.Custom('CONTEXT_EXTRAS').Output('CONTEXT_EXTRAS')])
|
||||||
"required": {
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"prev_extras": ("CONTEXT_EXTRAS",),
|
|
||||||
"strength_multival": ("MULTIVAL",),
|
|
||||||
"contextref_mode": ("CONTEXTREF_MODE",),
|
|
||||||
"contextref_tune": ("CONTEXTREF_TUNE",),
|
|
||||||
"contextref_kf": ("CONTEXTREF_KEYFRAME",),
|
|
||||||
"start_percent": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001}),
|
|
||||||
"end_percent": ("FLOAT", {"default": 0.25, "min": 0.0, "max": 1.0, "step": 0.001}),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("CONTEXT_EXTRAS",)
|
@classmethod
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/context opts/context extras"
|
def execute(cls, start_percent=0.0, end_percent=0.1, strength_multival: Union[float, Tensor]=None, contextref_mode: ContextRefMode=None, contextref_tune: ContextRefTune=None, contextref_kf: ContextRefKeyframeGroup=None, prev_extras: ContextExtrasGroup=None):
|
||||||
FUNCTION = "create_context_extra"
|
|
||||||
|
|
||||||
def create_context_extra(self, start_percent=0.0, end_percent=0.1, strength_multival: Union[float, Tensor]=None,
|
|
||||||
contextref_mode: ContextRefMode=None, contextref_tune: ContextRefTune=None,
|
|
||||||
contextref_kf: ContextRefKeyframeGroup=None, prev_extras: ContextExtrasGroup=None):
|
|
||||||
if prev_extras is None:
|
if prev_extras is None:
|
||||||
prev_extras = prev_extras = ContextExtrasGroup()
|
prev_extras = prev_extras = ContextExtrasGroup()
|
||||||
prev_extras = prev_extras.clone()
|
prev_extras = prev_extras.clone()
|
||||||
# create extra
|
|
||||||
# TODO: make customizable, and allow mask input
|
|
||||||
if contextref_tune is None:
|
if contextref_tune is None:
|
||||||
contextref_tune = ContextRefTune(attn_style_fidelity=1.0, attn_ref_weight=1.0, attn_strength=1.0)
|
contextref_tune = ContextRefTune(attn_style_fidelity=1.0, attn_ref_weight=1.0, attn_strength=1.0)
|
||||||
if contextref_mode is None:
|
if contextref_mode is None:
|
||||||
contextref_mode = ContextRefMode.init_first()
|
contextref_mode = ContextRefMode.init_first()
|
||||||
context_ref = ContextRef(start_percent=start_percent, end_percent=end_percent,
|
context_ref = ContextRef(start_percent=start_percent, end_percent=end_percent, strength_multival=strength_multival, tune=contextref_tune, mode=contextref_mode, keyframe=contextref_kf)
|
||||||
strength_multival=strength_multival, tune=contextref_tune, mode=contextref_mode,
|
|
||||||
keyframe=contextref_kf)
|
|
||||||
prev_extras.add(context_ref)
|
prev_extras.add(context_ref)
|
||||||
return (prev_extras,)
|
return io.NodeOutput(prev_extras)
|
||||||
|
|
||||||
|
class ContextRef_KeyframeMultivalNode(io.ComfyNode):
|
||||||
|
|
||||||
class ContextRef_KeyframeMultivalNode:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls):
|
||||||
return {
|
return io.Schema(node_id='ADE_ContextExtras_ContextRef_Keyframe', display_name='ContextRef Keyframe 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/context opts/context extras/contextref', inputs=[io.Custom('CONTEXTREF_KEYFRAME').Input('prev_kf', optional=True), io.Custom('MULTIVAL').Input('mult_multival', optional=True), io.Custom('CONTEXTREF_MODE').Input('mode_replace', optional=True), io.Custom('CONTEXTREF_TUNE').Input('tune_replace', optional=True), io.Float.Input('mult', optional=True, default=1.0, max=1.0, min=0.0, step=0.001), io.Float.Input('start_percent', optional=True, default=0.0, max=1.0, min=0.0, step=0.001), io.Int.Input('guarantee_steps', optional=True, default=1, max=9007199254740991, min=0), io.Boolean.Input('inherit_missing', optional=True, default=True)], outputs=[io.Custom('CONTEXTREF_KEYFRAME').Output('CONTEXTREF_KF')])
|
||||||
"required": {
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"prev_kf": ("CONTEXTREF_KEYFRAME",),
|
|
||||||
"mult_multival": ("MULTIVAL",),
|
|
||||||
"mode_replace": ("CONTEXTREF_MODE",),
|
|
||||||
"tune_replace": ("CONTEXTREF_TUNE",),
|
|
||||||
"mult": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.001}),
|
|
||||||
"start_percent": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001}),
|
|
||||||
"guarantee_steps": ("INT", {"default": 1, "min": 0, "max": BIGMAX}),
|
|
||||||
"inherit_missing": ("BOOLEAN", {"default": True}, ),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("CONTEXTREF_KEYFRAME",)
|
@classmethod
|
||||||
RETURN_NAMES = ("CONTEXTREF_KF",)
|
def execute(cls, prev_kf: ContextRefKeyframeGroup=None, mult=1.0, mult_multival=None, mode_replace=None, tune_replace=None, start_percent=1.0, guarantee_steps=1, inherit_missing=True):
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/context opts/context extras/contextref"
|
|
||||||
FUNCTION = "create_keyframe"
|
|
||||||
|
|
||||||
def create_keyframe(self, prev_kf: ContextRefKeyframeGroup=None,
|
|
||||||
mult=1.0, mult_multival=None, mode_replace=None, tune_replace=None,
|
|
||||||
start_percent=1.0, guarantee_steps=1, inherit_missing=True):
|
|
||||||
if prev_kf is None:
|
if prev_kf is None:
|
||||||
prev_kf = ContextRefKeyframeGroup()
|
prev_kf = ContextRefKeyframeGroup()
|
||||||
prev_kf = prev_kf.clone()
|
prev_kf = prev_kf.clone()
|
||||||
kf = ContextRefKeyframe(mult=mult, mult_multival=mult_multival, tune_replace=tune_replace, mode_replace=mode_replace,
|
kf = ContextRefKeyframe(mult=mult, mult_multival=mult_multival, tune_replace=tune_replace, mode_replace=mode_replace, start_percent=start_percent, guarantee_steps=guarantee_steps, inherit_missing=inherit_missing)
|
||||||
start_percent=start_percent, guarantee_steps=guarantee_steps, inherit_missing=inherit_missing)
|
|
||||||
prev_kf.add(kf)
|
prev_kf.add(kf)
|
||||||
return (prev_kf,)
|
return io.NodeOutput(prev_kf)
|
||||||
|
|
||||||
|
class ContextRef_KeyframeInterpolationNode(io.ComfyNode):
|
||||||
|
|
||||||
class ContextRef_KeyframeInterpolationNode:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls):
|
||||||
return {
|
return io.Schema(node_id='ADE_ContextExtras_ContextRef_KeyframeInterpolation', display_name='ContextRef Keyframes Interp. 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/context opts/context extras/contextref', inputs=[io.Float.Input('start_percent', default=0.0, max=1.0, min=0.0, step=0.001), io.Float.Input('end_percent', default=1.0, max=1.0, min=0.0, step=0.001), io.Float.Input('mult_start', default=1.0, max=1.0, min=0.0, step=0.001), io.Float.Input('mult_end', default=1.0, max=1.0, min=0.0, step=0.001), io.Combo.Input('interpolation', options=['linear', 'ease_in', 'ease_out', 'ease_in_out']), io.Int.Input('intervals', default=50, max=100, min=2, step=1), io.Boolean.Input('inherit_missing', default=True), io.Boolean.Input('print_keyframes', default=False), io.Custom('CONTEXTREF_KEYFRAME').Input('prev_kf', optional=True), io.Custom('MULTIVAL').Input('mult_multival', optional=True), io.Custom('CONTEXTREF_MODE').Input('mode_replace', optional=True), io.Custom('CONTEXTREF_TUNE').Input('tune_replace', optional=True)], outputs=[io.Custom('CONTEXTREF_KEYFRAME').Output('CONTEXTREF_KF')])
|
||||||
"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}),
|
|
||||||
"mult_start": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.001}),
|
|
||||||
"mult_end": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.001}),
|
|
||||||
"interpolation": (InterpolationMethod._LIST, ),
|
|
||||||
"intervals": ("INT", {"default": 50, "min": 2, "max": 100, "step": 1}),
|
|
||||||
"inherit_missing": ("BOOLEAN", {"default": True}),
|
|
||||||
"print_keyframes": ("BOOLEAN", {"default": False}),
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"prev_kf": ("CONTEXTREF_KEYFRAME",),
|
|
||||||
"mult_multival": ("MULTIVAL",),
|
|
||||||
"mode_replace": ("CONTEXTREF_MODE",),
|
|
||||||
"tune_replace": ("CONTEXTREF_TUNE",),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("CONTEXTREF_KEYFRAME",)
|
@classmethod
|
||||||
RETURN_NAMES = ("CONTEXTREF_KF",)
|
def execute(cls, start_percent: float, end_percent: float, mult_start: float, mult_end: float, interpolation: str, intervals: int, inherit_missing=True, prev_kf: ContextRefKeyframeGroup=None, mult_multival=None, mode_replace=None, tune_replace=None, print_keyframes=False):
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/context opts/context extras/contextref"
|
|
||||||
FUNCTION = "create_keyframe"
|
|
||||||
|
|
||||||
def create_keyframe(self,
|
|
||||||
start_percent: float, end_percent: float,
|
|
||||||
mult_start: float, mult_end: float, interpolation: str, intervals: int,
|
|
||||||
inherit_missing=True, prev_kf: ContextRefKeyframeGroup=None,
|
|
||||||
mult_multival=None, mode_replace=None, tune_replace=None, print_keyframes=False):
|
|
||||||
if prev_kf is None:
|
if prev_kf is None:
|
||||||
prev_kf = ContextRefKeyframeGroup()
|
prev_kf = ContextRefKeyframeGroup()
|
||||||
prev_kf = prev_kf.clone()
|
prev_kf = prev_kf.clone()
|
||||||
percents = InterpolationMethod.get_weights(num_from=start_percent, num_to=end_percent, length=intervals, method=InterpolationMethod.LINEAR)
|
percents = InterpolationMethod.get_weights(num_from=start_percent, num_to=end_percent, length=intervals, method=InterpolationMethod.LINEAR)
|
||||||
mults = InterpolationMethod.get_weights(num_from=mult_start, num_to=mult_end, length=intervals, method=interpolation)
|
mults = InterpolationMethod.get_weights(num_from=mult_start, num_to=mult_end, length=intervals, method=interpolation)
|
||||||
|
|
||||||
is_first = True
|
is_first = True
|
||||||
for percent, mult in zip(percents, mults):
|
for percent, mult in zip(percents, mults):
|
||||||
guarantee_steps = 0
|
guarantee_steps = 0
|
||||||
if is_first:
|
if is_first:
|
||||||
guarantee_steps = 1
|
guarantee_steps = 1
|
||||||
is_first = False
|
is_first = False
|
||||||
prev_kf.add(ContextRefKeyframe(mult=mult, mult_multival=mult_multival, tune_replace=tune_replace, mode_replace=mode_replace,
|
prev_kf.add(ContextRefKeyframe(mult=mult, mult_multival=mult_multival, tune_replace=tune_replace, mode_replace=mode_replace, start_percent=percent, guarantee_steps=guarantee_steps, inherit_missing=inherit_missing))
|
||||||
start_percent=percent, guarantee_steps=guarantee_steps, inherit_missing=inherit_missing))
|
|
||||||
if print_keyframes:
|
if print_keyframes:
|
||||||
logger.info(f"ContextRefKeyframe - start_percent:{percent} = {mult}")
|
logger.info(f'ContextRefKeyframe - start_percent:{percent} = {mult}')
|
||||||
return (prev_kf,)
|
return io.NodeOutput(prev_kf)
|
||||||
|
|
||||||
|
class ContextRef_KeyframeFromListNode(io.ComfyNode):
|
||||||
|
|
||||||
class ContextRef_KeyframeFromListNode:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls):
|
||||||
return {
|
return io.Schema(node_id='ADE_ContextExtras_ContextRef_KeyframeFromList', display_name='ContextRef Keyframes From List 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/context opts/context extras/contextref', inputs=[io.Float.Input('mults_float', default=-1, force_input=True, min=-1, step=0.001), io.Float.Input('start_percent', default=0.0, max=1.0, min=0.0, step=0.001), io.Float.Input('end_percent', default=1.0, max=1.0, min=0.0, step=0.001), io.Boolean.Input('inherit_missing', default=True), io.Boolean.Input('print_keyframes', default=False), io.Custom('CONTEXTREF_KEYFRAME').Input('prev_kf', optional=True), io.Custom('MULTIVAL').Input('mult_multival', optional=True), io.Custom('CONTEXTREF_MODE').Input('mode_replace', optional=True), io.Custom('CONTEXTREF_TUNE').Input('tune_replace', optional=True)], outputs=[io.Custom('CONTEXTREF_KEYFRAME').Output('CONTEXTREF_KF')])
|
||||||
"required": {
|
|
||||||
"mults_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}),
|
|
||||||
"inherit_missing": ("BOOLEAN", {"default": True}),
|
|
||||||
"print_keyframes": ("BOOLEAN", {"default": False}),
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"prev_kf": ("CONTEXTREF_KEYFRAME",),
|
|
||||||
"mult_multival": ("MULTIVAL",),
|
|
||||||
"mode_replace": ("CONTEXTREF_MODE",),
|
|
||||||
"tune_replace": ("CONTEXTREF_TUNE",),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("CONTEXTREF_KEYFRAME",)
|
@classmethod
|
||||||
RETURN_NAMES = ("CONTEXTREF_KF",)
|
def execute(cls, mults_float: Union[float, list[float]], start_percent: float, end_percent: float, inherit_missing=True, prev_kf: ContextRefKeyframeGroup=None, mult_multival=None, mode_replace=None, tune_replace=None, print_keyframes=False):
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/context opts/context extras/contextref"
|
|
||||||
FUNCTION = "create_keyframe"
|
|
||||||
|
|
||||||
def create_keyframe(self, mults_float: Union[float, list[float]],
|
|
||||||
start_percent: float, end_percent: float,
|
|
||||||
inherit_missing=True, prev_kf: ContextRefKeyframeGroup=None,
|
|
||||||
mult_multival=None, mode_replace=None, tune_replace=None, print_keyframes=False):
|
|
||||||
if prev_kf is None:
|
if prev_kf is None:
|
||||||
prev_kf = ContextRefKeyframeGroup()
|
prev_kf = ContextRefKeyframeGroup()
|
||||||
prev_kf = prev_kf.clone()
|
prev_kf = prev_kf.clone()
|
||||||
@@ -367,131 +179,73 @@ class ContextRef_KeyframeFromListNode:
|
|||||||
elif isinstance(mults_float, Iterable):
|
elif isinstance(mults_float, Iterable):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
raise Exception(f"strengths_float must be either an interable input or a float, but was {type(mults_float).__repr__}.")
|
raise Exception(f'strengths_float must be either an interable input or a float, but was {type(mults_float).__repr__}.')
|
||||||
percents = InterpolationMethod.get_weights(num_from=start_percent, num_to=end_percent, length=len(mults_float), method=InterpolationMethod.LINEAR)
|
percents = InterpolationMethod.get_weights(num_from=start_percent, num_to=end_percent, length=len(mults_float), method=InterpolationMethod.LINEAR)
|
||||||
|
|
||||||
is_first = True
|
is_first = True
|
||||||
for percent, mult in zip(percents, mults_float):
|
for percent, mult in zip(percents, mults_float):
|
||||||
guarantee_steps = 0
|
guarantee_steps = 0
|
||||||
if is_first:
|
if is_first:
|
||||||
guarantee_steps = 1
|
guarantee_steps = 1
|
||||||
is_first = False
|
is_first = False
|
||||||
prev_kf.add(ContextRefKeyframe(mult=mult, mult_multival=mult_multival, tune_replace=tune_replace, mode_replace=mode_replace,
|
prev_kf.add(ContextRefKeyframe(mult=mult, mult_multival=mult_multival, tune_replace=tune_replace, mode_replace=mode_replace, start_percent=percent, guarantee_steps=guarantee_steps, inherit_missing=inherit_missing))
|
||||||
start_percent=percent, guarantee_steps=guarantee_steps, inherit_missing=inherit_missing))
|
|
||||||
if print_keyframes:
|
if print_keyframes:
|
||||||
logger.info(f"ContextRefKeyframe - start_percent:{percent} = {mult}")
|
logger.info(f'ContextRefKeyframe - start_percent:{percent} = {mult}')
|
||||||
return (prev_kf,)
|
return io.NodeOutput(prev_kf)
|
||||||
|
|
||||||
|
class ContextRef_ModeFirst(io.ComfyNode):
|
||||||
|
|
||||||
class ContextRef_ModeFirst:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls):
|
||||||
return {
|
return io.Schema(node_id='ADE_ContextExtras_ContextRef_ModeFirst', display_name='ContextRef Mode◆First 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/context opts/context extras/contextref', inputs=[], outputs=[io.Custom('CONTEXTREF_MODE').Output('CONTEXTREF_MODE')])
|
||||||
"required": {
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("CONTEXTREF_MODE",)
|
@classmethod
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/context opts/context extras/contextref"
|
def execute(cls):
|
||||||
FUNCTION = "create_contextref_mode"
|
|
||||||
|
|
||||||
def create_contextref_mode(self):
|
|
||||||
mode = ContextRefMode.init_first()
|
mode = ContextRefMode.init_first()
|
||||||
return (mode,)
|
return io.NodeOutput(mode)
|
||||||
|
|
||||||
|
class ContextRef_ModeSliding(io.ComfyNode):
|
||||||
|
|
||||||
class ContextRef_ModeSliding:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls):
|
||||||
return {
|
return io.Schema(node_id='ADE_ContextExtras_ContextRef_ModeSliding', display_name='ContextRef Mode◆Sliding 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/context opts/context extras/contextref', inputs=[io.Int.Input('sliding_width', optional=True, default=2, max=9007199254740991, min=2, step=1)], outputs=[io.Custom('CONTEXTREF_MODE').Output('CONTEXTREF_MODE')])
|
||||||
"required": {
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"sliding_width": ("INT", {"default": 2, "min": 2, "max": BIGMAX, "step": 1}),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("CONTEXTREF_MODE",)
|
@classmethod
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/context opts/context extras/contextref"
|
def execute(cls, sliding_width):
|
||||||
FUNCTION = "create_contextref_mode"
|
|
||||||
|
|
||||||
def create_contextref_mode(self, sliding_width):
|
|
||||||
mode = ContextRefMode.init_sliding(sliding_width=sliding_width)
|
mode = ContextRefMode.init_sliding(sliding_width=sliding_width)
|
||||||
return (mode,)
|
return io.NodeOutput(mode)
|
||||||
|
|
||||||
|
class ContextRef_ModeIndexes(io.ComfyNode):
|
||||||
|
|
||||||
class ContextRef_ModeIndexes:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls):
|
||||||
return {
|
return io.Schema(node_id='ADE_ContextExtras_ContextRef_ModeIndexes', display_name='ContextRef Mode◆Indexes 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/context opts/context extras/contextref', inputs=[io.String.Input('switch_on_idxs', optional=True, default=''), io.Boolean.Input('always_include_0', optional=True, default=True)], outputs=[io.Custom('CONTEXTREF_MODE').Output('CONTEXTREF_MODE')])
|
||||||
"required": {
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"switch_on_idxs": ("STRING", {"default": ""}),
|
|
||||||
"always_include_0": ("BOOLEAN", {"default": True},),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("CONTEXTREF_MODE",)
|
@classmethod
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/context opts/context extras/contextref"
|
def execute(cls, switch_on_idxs: str, always_include_0: bool):
|
||||||
FUNCTION = "create_contextref_mode"
|
|
||||||
|
|
||||||
def create_contextref_mode(self, switch_on_idxs: str, always_include_0: bool):
|
|
||||||
idxs = set(convert_str_to_indexes(indexes_str=switch_on_idxs, length=0, allow_range=False))
|
idxs = set(convert_str_to_indexes(indexes_str=switch_on_idxs, length=0, allow_range=False))
|
||||||
if always_include_0 and 0 not in idxs:
|
if always_include_0 and 0 not in idxs:
|
||||||
idxs.add(0)
|
idxs.add(0)
|
||||||
mode = ContextRefMode.init_indexes(indexes=idxs)
|
mode = ContextRefMode.init_indexes(indexes=idxs)
|
||||||
return (mode,)
|
return io.NodeOutput(mode)
|
||||||
|
|
||||||
|
class ContextRef_TuneAttnAdain(io.ComfyNode):
|
||||||
|
|
||||||
class ContextRef_TuneAttnAdain:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls):
|
||||||
return {
|
return io.Schema(node_id='ADE_ContextExtras_ContextRef_TuneAttnAdain', display_name='ContextRef Tune◆Attn+Adain 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/context opts/context extras/contextref', inputs=[io.Float.Input('attn_style_fidelity', optional=True, default=1.0, max=1.0, min=0.0, step=0.01), io.Float.Input('attn_ref_weight', optional=True, default=1.0, max=1.0, min=0.0, step=0.01), io.Float.Input('attn_strength', optional=True, default=1.0, max=1.0, min=0.0, step=0.01), io.Float.Input('adain_style_fidelity', optional=True, default=1.0, max=1.0, min=0.0, step=0.01), io.Float.Input('adain_ref_weight', optional=True, default=1.0, max=1.0, min=0.0, step=0.01), io.Float.Input('adain_strength', optional=True, default=1.0, max=1.0, min=0.0, step=0.01)], outputs=[io.Custom('CONTEXTREF_TUNE').Output('CONTEXTREF_TUNE')])
|
||||||
"required": {
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"attn_style_fidelity": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01}),
|
|
||||||
"attn_ref_weight": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01}),
|
|
||||||
"attn_strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01}),
|
|
||||||
"adain_style_fidelity": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01}),
|
|
||||||
"adain_ref_weight": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01}),
|
|
||||||
"adain_strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01}),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("CONTEXTREF_TUNE",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/context opts/context extras/contextref"
|
|
||||||
FUNCTION = "create_contextref_tune"
|
|
||||||
|
|
||||||
def create_contextref_tune(self, attn_style_fidelity=1.0, attn_ref_weight=1.0, attn_strength=1.0,
|
|
||||||
adain_style_fidelity=1.0, adain_ref_weight=1.0, adain_strength=1.0):
|
|
||||||
params = ContextRefTune(attn_style_fidelity=attn_style_fidelity, adain_style_fidelity=adain_style_fidelity,
|
|
||||||
attn_ref_weight=attn_ref_weight, adain_ref_weight=adain_ref_weight,
|
|
||||||
attn_strength=attn_strength, adain_strength=adain_strength)
|
|
||||||
return (params,)
|
|
||||||
|
|
||||||
|
|
||||||
class ContextRef_TuneAttn:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def execute(cls, attn_style_fidelity=1.0, attn_ref_weight=1.0, attn_strength=1.0, adain_style_fidelity=1.0, adain_ref_weight=1.0, adain_strength=1.0):
|
||||||
return {
|
params = ContextRefTune(attn_style_fidelity=attn_style_fidelity, adain_style_fidelity=adain_style_fidelity, attn_ref_weight=attn_ref_weight, adain_ref_weight=adain_ref_weight, attn_strength=attn_strength, adain_strength=adain_strength)
|
||||||
"required": {
|
return io.NodeOutput(params)
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"attn_style_fidelity": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01}),
|
|
||||||
"attn_ref_weight": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01}),
|
|
||||||
"attn_strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01}),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("CONTEXTREF_TUNE",)
|
class ContextRef_TuneAttn(io.ComfyNode):
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/context opts/context extras/contextref"
|
|
||||||
FUNCTION = "create_contextref_tune"
|
|
||||||
|
|
||||||
def create_contextref_tune(self, attn_style_fidelity=1.0, attn_ref_weight=1.0, attn_strength=1.0):
|
@classmethod
|
||||||
return ContextRef_TuneAttnAdain.create_contextref_tune(self,
|
def define_schema(cls):
|
||||||
attn_style_fidelity=attn_style_fidelity, attn_ref_weight=attn_ref_weight, attn_strength=attn_strength,
|
return io.Schema(node_id='ADE_ContextExtras_ContextRef_TuneAttn', display_name='ContextRef Tune◆Attn 🎭🅐🅓', category='Animate Diff 🎭🅐🅓/context opts/context extras/contextref', inputs=[io.Float.Input('attn_style_fidelity', optional=True, default=1.0, max=1.0, min=0.0, step=0.01), io.Float.Input('attn_ref_weight', optional=True, default=1.0, max=1.0, min=0.0, step=0.01), io.Float.Input('attn_strength', optional=True, default=1.0, max=1.0, min=0.0, step=0.01)], outputs=[io.Custom('CONTEXTREF_TUNE').Output('CONTEXTREF_TUNE')])
|
||||||
adain_ref_weight=0.0, adain_style_fidelity=0.0, adain_strength=0.0)
|
|
||||||
#----------------------------------------
|
@classmethod
|
||||||
#########################################
|
def execute(cls, attn_style_fidelity=1.0, attn_ref_weight=1.0, attn_strength=1.0):
|
||||||
|
output = ContextRef_TuneAttnAdain.execute(attn_style_fidelity=attn_style_fidelity, attn_ref_weight=attn_ref_weight, attn_strength=attn_strength, adain_ref_weight=0.0, adain_style_fidelity=0.0, adain_strength=0.0)
|
||||||
|
return io.NodeOutput(*output.args)
|
||||||
|
|||||||
+103
-438
@@ -1,557 +1,222 @@
|
|||||||
|
from comfy_api.latest import io
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
from typing import Dict, List
|
from typing import Dict, List
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import torch
|
import torch
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
from PIL.PngImagePlugin import PngInfo
|
from PIL.PngImagePlugin import PngInfo
|
||||||
|
|
||||||
import folder_paths
|
import folder_paths
|
||||||
from comfy.model_patcher import ModelPatcher
|
from comfy.model_patcher import ModelPatcher
|
||||||
|
|
||||||
from .ad_settings import AnimateDiffSettings, AdjustGroup, AdjustPE, AdjustWeight
|
from .ad_settings import AnimateDiffSettings, AdjustGroup, AdjustPE, AdjustWeight
|
||||||
from .context import ContextOptionsGroup, ContextOptions, ContextSchedules
|
from .context import ContextOptionsGroup, ContextOptions, ContextSchedules
|
||||||
from .logger import logger
|
from .logger import logger
|
||||||
from .utils_model import Folders, BetaSchedules, get_available_motion_models
|
from .utils_model import Folders, BetaSchedules, get_available_motion_models
|
||||||
from .utils_motion import ADKeyframeGroup
|
from .utils_motion import ADKeyframeGroup
|
||||||
from .motion_lora import MotionLoraList
|
from .motion_lora import MotionLoraList
|
||||||
from .model_injection import (ModelPatcherHelper, InjectionParams, MotionModelGroup, get_mm_attachment, load_motion_module_gen1)
|
from .model_injection import ModelPatcherHelper, InjectionParams, MotionModelGroup, get_mm_attachment, load_motion_module_gen1
|
||||||
from .sampling import outer_sample_wrapper, sliding_calc_cond_batch
|
from .sampling import outer_sample_wrapper, sliding_calc_cond_batch
|
||||||
from .sample_settings import SampleSettings
|
from .sample_settings import SampleSettings
|
||||||
|
|
||||||
|
class AnimateDiffLoaderDEPR(io.ComfyNode):
|
||||||
|
|
||||||
class AnimateDiffLoaderDEPR:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls):
|
||||||
return {
|
return io.Schema(node_id='AnimateDiffLoaderV1', display_name='🚫AnimateDiff Loader [DEPRECATED] 🎭🅐🅓', category='', inputs=[io.Model.Input('model'), io.Custom('LATENT').Input('latents'), io.Combo.Input('model_name', options=get_available_motion_models()), io.Boolean.Input('unlimited_area_hack', default=False), io.Combo.Input('beta_schedule', options=['sqrt_linear (AnimateDiff)', 'use existing', 'autoselect', 'linear (AnimateDiff-SDXL)', 'linear (HotshotXL/default)', 'avg(sqrt_linear,linear)', 'lcm avg(sqrt_linear,linear)', 'lcm', 'lcm[100_ots]', 'lcm >> sqrt_linear', 'sqrt', 'cosine', 'squaredcos_cap_v2'])], outputs=[io.Model.Output('MODEL'), io.Custom('LATENT').Output('LATENT')], is_deprecated=True)
|
||||||
"required": {
|
|
||||||
"model": ("MODEL",),
|
|
||||||
"latents": ("LATENT",),
|
|
||||||
"model_name": (get_available_motion_models(),),
|
|
||||||
"unlimited_area_hack": ("BOOLEAN", {"default": False},),
|
|
||||||
"beta_schedule": (BetaSchedules.get_alias_list_with_first_element(BetaSchedules.SQRT_LINEAR),),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("MODEL", "LATENT")
|
@classmethod
|
||||||
CATEGORY = ""
|
def execute(cls, model: ModelPatcher, latents: Dict[str, torch.Tensor], model_name: str, unlimited_area_hack: bool, beta_schedule: str):
|
||||||
FUNCTION = "load_mm_and_inject_params"
|
|
||||||
DEPRECATED = True
|
|
||||||
|
|
||||||
def load_mm_and_inject_params(
|
|
||||||
self,
|
|
||||||
model: ModelPatcher,
|
|
||||||
latents: Dict[str, torch.Tensor],
|
|
||||||
model_name: str, unlimited_area_hack: bool, beta_schedule: str,
|
|
||||||
):
|
|
||||||
# load motion module
|
|
||||||
motion_model = load_motion_module_gen1(model_name, model)
|
motion_model = load_motion_module_gen1(model_name, model)
|
||||||
# get total frames
|
init_frames_len = len(latents['samples'])
|
||||||
init_frames_len = len(latents["samples"]) # deprecated - no longer used for anything lol
|
params = InjectionParams(unlimited_area_hack=unlimited_area_hack, apply_v2_properly=False)
|
||||||
# set injection params
|
|
||||||
params = InjectionParams(
|
|
||||||
unlimited_area_hack=unlimited_area_hack,
|
|
||||||
apply_v2_properly=False,
|
|
||||||
)
|
|
||||||
# inject for use in sampling code
|
|
||||||
model = model.clone()
|
model = model.clone()
|
||||||
helper = ModelPatcherHelper(model)
|
helper = ModelPatcherHelper(model)
|
||||||
helper.set_all_properties(
|
helper.set_all_properties(outer_sampler_wrapper=outer_sample_wrapper, calc_cond_batch_wrapper=sliding_calc_cond_batch, params=params, motion_models=MotionModelGroup(motion_model))
|
||||||
outer_sampler_wrapper=outer_sample_wrapper,
|
if beta_schedule == BetaSchedules.AUTOSELECT and (not model.motion_models.is_empty()):
|
||||||
calc_cond_batch_wrapper=sliding_calc_cond_batch,
|
|
||||||
params=params,
|
|
||||||
motion_models=MotionModelGroup(motion_model),
|
|
||||||
)
|
|
||||||
|
|
||||||
# save model sampling from BetaSchedule as object patch
|
|
||||||
# if autoselect, get suggested beta_schedule from motion model
|
|
||||||
if beta_schedule == BetaSchedules.AUTOSELECT and not model.motion_models.is_empty():
|
|
||||||
beta_schedule = model.motion_models[0].model.get_best_beta_schedule(log=True)
|
beta_schedule = model.motion_models[0].model.get_best_beta_schedule(log=True)
|
||||||
new_model_sampling = BetaSchedules.to_model_sampling(beta_schedule, model)
|
new_model_sampling = BetaSchedules.to_model_sampling(beta_schedule, model)
|
||||||
if new_model_sampling is not None:
|
if new_model_sampling is not None:
|
||||||
model.add_object_patch("model_sampling", new_model_sampling)
|
model.add_object_patch('model_sampling', new_model_sampling)
|
||||||
|
|
||||||
del motion_model
|
del motion_model
|
||||||
return (model, latents)
|
return io.NodeOutput(model, latents)
|
||||||
|
|
||||||
|
class AnimateDiffLoaderAdvancedDEPR(io.ComfyNode):
|
||||||
|
|
||||||
class AnimateDiffLoaderAdvancedDEPR:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls):
|
||||||
return {
|
return io.Schema(node_id='ADE_AnimateDiffLoaderV1Advanced', display_name='🚫AnimateDiff Loader (Advanced) [DEPRECATED] 🎭🅐🅓', category='', inputs=[io.Model.Input('model'), io.Custom('LATENT').Input('latents'), io.Combo.Input('model_name', options=get_available_motion_models()), io.Boolean.Input('unlimited_area_hack', default=False), io.Int.Input('context_length', default=16, max=1000, min=0), io.Int.Input('context_stride', default=1, max=1000, min=1), io.Int.Input('context_overlap', default=4, max=1000, min=0), io.Combo.Input('context_schedule', options=['uniform']), io.Boolean.Input('closed_loop', default=False), io.Combo.Input('beta_schedule', options=['sqrt_linear (AnimateDiff)', 'use existing', 'autoselect', 'linear (AnimateDiff-SDXL)', 'linear (HotshotXL/default)', 'avg(sqrt_linear,linear)', 'lcm avg(sqrt_linear,linear)', 'lcm', 'lcm[100_ots]', 'lcm >> sqrt_linear', 'sqrt', 'cosine', 'squaredcos_cap_v2'])], outputs=[io.Model.Output('MODEL'), io.Custom('LATENT').Output('LATENT')], is_deprecated=True)
|
||||||
"required": {
|
|
||||||
"model": ("MODEL",),
|
|
||||||
"latents": ("LATENT",),
|
|
||||||
"model_name": (get_available_motion_models(),),
|
|
||||||
"unlimited_area_hack": ("BOOLEAN", {"default": False},),
|
|
||||||
"context_length": ("INT", {"default": 16, "min": 0, "max": 1000}),
|
|
||||||
"context_stride": ("INT", {"default": 1, "min": 1, "max": 1000}),
|
|
||||||
"context_overlap": ("INT", {"default": 4, "min": 0, "max": 1000}),
|
|
||||||
"context_schedule": (ContextSchedules.LEGACY_UNIFORM_SCHEDULE_LIST,),
|
|
||||||
"closed_loop": ("BOOLEAN", {"default": False},),
|
|
||||||
"beta_schedule": (BetaSchedules.get_alias_list_with_first_element(BetaSchedules.SQRT_LINEAR),),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("MODEL", "LATENT")
|
@classmethod
|
||||||
CATEGORY = ""
|
def execute(cls, model: ModelPatcher, latents: Dict[str, torch.Tensor], model_name: str, unlimited_area_hack: bool, context_length: int, context_stride: int, context_overlap: int, context_schedule: str, closed_loop: bool, beta_schedule: str):
|
||||||
FUNCTION = "load_mm_and_inject_params"
|
|
||||||
DEPRECATED = True
|
|
||||||
|
|
||||||
def load_mm_and_inject_params(self,
|
|
||||||
model: ModelPatcher,
|
|
||||||
latents: Dict[str, torch.Tensor],
|
|
||||||
model_name: str, unlimited_area_hack: bool,
|
|
||||||
context_length: int, context_stride: int, context_overlap: int, context_schedule: str, closed_loop: bool,
|
|
||||||
beta_schedule: str,
|
|
||||||
):
|
|
||||||
# load motion module
|
|
||||||
motion_model = load_motion_module_gen1(model_name, model)
|
motion_model = load_motion_module_gen1(model_name, model)
|
||||||
# get total frames
|
init_frames_len = len(latents['samples'])
|
||||||
init_frames_len = len(latents["samples"]) # deprecated - no longer used for anything lol
|
params = InjectionParams(unlimited_area_hack=unlimited_area_hack, apply_v2_properly=False)
|
||||||
# set injection params
|
|
||||||
params = InjectionParams(
|
|
||||||
unlimited_area_hack=unlimited_area_hack,
|
|
||||||
apply_v2_properly=False,
|
|
||||||
)
|
|
||||||
context_group = ContextOptionsGroup()
|
context_group = ContextOptionsGroup()
|
||||||
context_group.add(
|
context_group.add(ContextOptions(context_length=context_length, context_stride=context_stride, context_overlap=context_overlap, context_schedule=context_schedule, closed_loop=closed_loop))
|
||||||
ContextOptions(
|
|
||||||
context_length=context_length,
|
|
||||||
context_stride=context_stride,
|
|
||||||
context_overlap=context_overlap,
|
|
||||||
context_schedule=context_schedule,
|
|
||||||
closed_loop=closed_loop,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
# set context settings
|
|
||||||
params.set_context(context_options=context_group)
|
params.set_context(context_options=context_group)
|
||||||
# inject for use in sampling code
|
|
||||||
model = model.clone()
|
model = model.clone()
|
||||||
helper = ModelPatcherHelper(model)
|
helper = ModelPatcherHelper(model)
|
||||||
helper.set_all_properties(
|
helper.set_all_properties(outer_sampler_wrapper=outer_sample_wrapper, calc_cond_batch_wrapper=sliding_calc_cond_batch, params=params, motion_models=MotionModelGroup(motion_model))
|
||||||
outer_sampler_wrapper=outer_sample_wrapper,
|
if beta_schedule == BetaSchedules.AUTOSELECT and (not model.motion_models.is_empty()):
|
||||||
calc_cond_batch_wrapper=sliding_calc_cond_batch,
|
|
||||||
params=params,
|
|
||||||
motion_models=MotionModelGroup(motion_model),
|
|
||||||
)
|
|
||||||
|
|
||||||
# save model sampling from BetaSchedule as object patch
|
|
||||||
# if autoselect, get suggested beta_schedule from motion model
|
|
||||||
if beta_schedule == BetaSchedules.AUTOSELECT and not model.motion_models.is_empty():
|
|
||||||
beta_schedule = model.motion_models[0].model.get_best_beta_schedule(log=True)
|
beta_schedule = model.motion_models[0].model.get_best_beta_schedule(log=True)
|
||||||
new_model_sampling = BetaSchedules.to_model_sampling(beta_schedule, model)
|
new_model_sampling = BetaSchedules.to_model_sampling(beta_schedule, model)
|
||||||
if new_model_sampling is not None:
|
if new_model_sampling is not None:
|
||||||
model.add_object_patch("model_sampling", new_model_sampling)
|
model.add_object_patch('model_sampling', new_model_sampling)
|
||||||
|
|
||||||
del motion_model
|
del motion_model
|
||||||
return (model, latents)
|
return io.NodeOutput(model, latents)
|
||||||
|
|
||||||
|
class LegacyAnimateDiffLoaderWithContextDEPR(io.ComfyNode):
|
||||||
|
|
||||||
class LegacyAnimateDiffLoaderWithContextDEPR:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls):
|
||||||
return {
|
return io.Schema(node_id='ADE_AnimateDiffLoaderWithContext', display_name='AnimateDiff Loader [Legacy] 🎭🅐🅓①', category='Animate Diff 🎭🅐🅓/① Gen1 nodes ①', inputs=[io.Model.Input('model'), io.Combo.Input('model_name', options=get_available_motion_models()), io.Combo.Input('beta_schedule', options=['autoselect', 'use existing', 'sqrt_linear (AnimateDiff)', 'linear (AnimateDiff-SDXL)', 'linear (HotshotXL/default)', 'avg(sqrt_linear,linear)', 'lcm avg(sqrt_linear,linear)', 'lcm', 'lcm[100_ots]', 'lcm >> sqrt_linear', 'sqrt', 'cosine', 'squaredcos_cap_v2'], default='autoselect'), io.Custom('CONTEXT_OPTIONS').Input('context_options', optional=True), io.Custom('MOTION_LORA').Input('motion_lora', optional=True), io.Custom('AD_SETTINGS').Input('ad_settings', optional=True), io.Custom('SAMPLE_SETTINGS').Input('sample_settings', optional=True), io.Float.Input('motion_scale', optional=True, default=1.0, min=0.0, step=0.001), io.Boolean.Input('apply_v2_models_properly', optional=True, default=True), io.Custom('AD_KEYFRAMES').Input('ad_keyframes', optional=True)], outputs=[io.Model.Output('MODEL')], is_deprecated=True)
|
||||||
"required": {
|
|
||||||
"model": ("MODEL",),
|
|
||||||
"model_name": (get_available_motion_models(),),
|
|
||||||
"beta_schedule": (BetaSchedules.ALIAS_LIST, {"default": BetaSchedules.AUTOSELECT}),
|
|
||||||
#"apply_mm_groupnorm_hack": ("BOOLEAN", {"default": True}),
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"context_options": ("CONTEXT_OPTIONS",),
|
|
||||||
"motion_lora": ("MOTION_LORA",),
|
|
||||||
"ad_settings": ("AD_SETTINGS",),
|
|
||||||
"sample_settings": ("SAMPLE_SETTINGS",),
|
|
||||||
"motion_scale": ("FLOAT", {"default": 1.0, "min": 0.0, "step": 0.001}),
|
|
||||||
"apply_v2_models_properly": ("BOOLEAN", {"default": True}),
|
|
||||||
"ad_keyframes": ("AD_KEYFRAMES",),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DEPRECATED = True
|
@classmethod
|
||||||
RETURN_TYPES = ("MODEL",)
|
def execute(cls, model: ModelPatcher, model_name: str, beta_schedule: str, context_options: ContextOptionsGroup=None, motion_lora: MotionLoraList=None, ad_settings: AnimateDiffSettings=None, motion_model_settings: AnimateDiffSettings=None, sample_settings: SampleSettings=None, motion_scale: float=1.0, apply_v2_models_properly: bool=False, ad_keyframes: ADKeyframeGroup=None):
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/① Gen1 nodes ①"
|
|
||||||
FUNCTION = "load_mm_and_inject_params"
|
|
||||||
|
|
||||||
def load_mm_and_inject_params(self,
|
|
||||||
model: ModelPatcher,
|
|
||||||
model_name: str, beta_schedule: str,# apply_mm_groupnorm_hack: bool,
|
|
||||||
context_options: ContextOptionsGroup=None, motion_lora: MotionLoraList=None, ad_settings: AnimateDiffSettings=None, motion_model_settings: AnimateDiffSettings=None,
|
|
||||||
sample_settings: SampleSettings=None, motion_scale: float=1.0, apply_v2_models_properly: bool=False, ad_keyframes: ADKeyframeGroup=None,
|
|
||||||
):
|
|
||||||
if ad_settings is not None:
|
if ad_settings is not None:
|
||||||
motion_model_settings = ad_settings
|
motion_model_settings = ad_settings
|
||||||
# load motion module
|
|
||||||
motion_model = load_motion_module_gen1(model_name, model, motion_lora=motion_lora, motion_model_settings=motion_model_settings)
|
motion_model = load_motion_module_gen1(model_name, model, motion_lora=motion_lora, motion_model_settings=motion_model_settings)
|
||||||
# set injection params
|
params = InjectionParams(unlimited_area_hack=False, apply_v2_properly=apply_v2_models_properly)
|
||||||
params = InjectionParams(
|
|
||||||
unlimited_area_hack=False,
|
|
||||||
apply_v2_properly=apply_v2_models_properly,
|
|
||||||
)
|
|
||||||
if context_options:
|
if context_options:
|
||||||
params.set_context(context_options)
|
params.set_context(context_options)
|
||||||
# set motion_scale and motion_model_settings
|
|
||||||
if not motion_model_settings:
|
if not motion_model_settings:
|
||||||
motion_model_settings = AnimateDiffSettings()
|
motion_model_settings = AnimateDiffSettings()
|
||||||
motion_model_settings.attn_scale = motion_scale
|
motion_model_settings.attn_scale = motion_scale
|
||||||
params.set_motion_model_settings(motion_model_settings)
|
params.set_motion_model_settings(motion_model_settings)
|
||||||
|
|
||||||
attachment = get_mm_attachment(motion_model)
|
attachment = get_mm_attachment(motion_model)
|
||||||
if params.motion_model_settings.mask_attn_scale is not None:
|
if params.motion_model_settings.mask_attn_scale is not None:
|
||||||
attachment.scale_multival = params.motion_model_settings.mask_attn_scale * params.motion_model_settings.attn_scale
|
attachment.scale_multival = params.motion_model_settings.mask_attn_scale * params.motion_model_settings.attn_scale
|
||||||
else:
|
else:
|
||||||
attachment.scale_multival = params.motion_model_settings.attn_scale
|
attachment.scale_multival = params.motion_model_settings.attn_scale
|
||||||
|
|
||||||
attachment.keyframes = ad_keyframes.clone() if ad_keyframes else ADKeyframeGroup()
|
attachment.keyframes = ad_keyframes.clone() if ad_keyframes else ADKeyframeGroup()
|
||||||
|
|
||||||
# need to use a ModelPatcher that supports injection of motion modules into unet
|
|
||||||
model = model.clone()
|
model = model.clone()
|
||||||
helper = ModelPatcherHelper(model)
|
helper = ModelPatcherHelper(model)
|
||||||
helper.set_all_properties(
|
helper.set_all_properties(outer_sampler_wrapper=outer_sample_wrapper, calc_cond_batch_wrapper=sliding_calc_cond_batch, params=params, sample_settings=sample_settings, motion_models=MotionModelGroup(motion_model))
|
||||||
outer_sampler_wrapper=outer_sample_wrapper,
|
|
||||||
calc_cond_batch_wrapper=sliding_calc_cond_batch,
|
|
||||||
params=params,
|
|
||||||
sample_settings=sample_settings,
|
|
||||||
motion_models=MotionModelGroup(motion_model),
|
|
||||||
)
|
|
||||||
|
|
||||||
sample_settings = helper.get_sample_settings()
|
sample_settings = helper.get_sample_settings()
|
||||||
if sample_settings.custom_cfg is not None:
|
if sample_settings.custom_cfg is not None:
|
||||||
logger.info("[Sample Settings] custom_cfg is set; will override any KSampler cfg values or patches.")
|
logger.info('[Sample Settings] custom_cfg is set; will override any KSampler cfg values or patches.')
|
||||||
|
|
||||||
if sample_settings.sigma_schedule is not None:
|
if sample_settings.sigma_schedule is not None:
|
||||||
logger.info("[Sample Settings] sigma_schedule is set; will override beta_schedule.")
|
logger.info('[Sample Settings] sigma_schedule is set; will override beta_schedule.')
|
||||||
model.add_object_patch("model_sampling", sample_settings.sigma_schedule.clone().model_sampling)
|
model.add_object_patch('model_sampling', sample_settings.sigma_schedule.clone().model_sampling)
|
||||||
else:
|
else:
|
||||||
# save model sampling from BetaSchedule as object patch
|
|
||||||
# if autoselect, get suggested beta_schedule from motion model
|
|
||||||
if beta_schedule == BetaSchedules.AUTOSELECT and helper.get_motion_models():
|
if beta_schedule == BetaSchedules.AUTOSELECT and helper.get_motion_models():
|
||||||
beta_schedule = helper.get_motion_models()[0].model.get_best_beta_schedule(log=True)
|
beta_schedule = helper.get_motion_models()[0].model.get_best_beta_schedule(log=True)
|
||||||
new_model_sampling = BetaSchedules.to_model_sampling(beta_schedule, model)
|
new_model_sampling = BetaSchedules.to_model_sampling(beta_schedule, model)
|
||||||
if new_model_sampling is not None:
|
if new_model_sampling is not None:
|
||||||
model.add_object_patch("model_sampling", new_model_sampling)
|
model.add_object_patch('model_sampling', new_model_sampling)
|
||||||
|
|
||||||
del motion_model
|
del motion_model
|
||||||
return (model,)
|
return io.NodeOutput(model)
|
||||||
|
|
||||||
|
class AnimateDiffCombineDEPR(io.ComfyNode):
|
||||||
|
|
||||||
class AnimateDiffCombineDEPR:
|
|
||||||
ffmpeg_warning_already_shown = False
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def get_formats(cls):
|
||||||
ffmpeg_path = shutil.which("ffmpeg")
|
ffmpeg_path = shutil.which('ffmpeg')
|
||||||
#Hide ffmpeg formats if ffmpeg isn't available
|
|
||||||
if ffmpeg_path is not None:
|
if ffmpeg_path is not None:
|
||||||
ffmpeg_formats = ["video/"+x[:-5] for x in folder_paths.get_filename_list(Folders.VIDEO_FORMATS)]
|
return ['image/gif', 'image/webp'] + ['video/' + x[:-5] for x in folder_paths.get_filename_list(Folders.VIDEO_FORMATS)]
|
||||||
else:
|
cls.ffmpeg_warning_already_shown = True
|
||||||
ffmpeg_formats = []
|
return ['image/gif', 'image/webp']
|
||||||
if not s.ffmpeg_warning_already_shown:
|
|
||||||
# Deprecated node are now hidden, so no need to show warning unless node is used.
|
|
||||||
# logger.warning("This warning can be ignored, you should not be using the deprecated AnimateDiff Combine node anyway. If you are, use Video Combine from ComfyUI-VideoHelperSuite instead. ffmpeg could not be found. Outputs that require it have been disabled")
|
|
||||||
s.ffmpeg_warning_already_shown = True
|
|
||||||
return {
|
|
||||||
"required": {
|
|
||||||
"images": ("IMAGE",),
|
|
||||||
"frame_rate": (
|
|
||||||
"INT",
|
|
||||||
{"default": 8, "min": 1, "max": 24, "step": 1},
|
|
||||||
),
|
|
||||||
"loop_count": ("INT", {"default": 0, "min": 0, "max": 100, "step": 1}),
|
|
||||||
"filename_prefix": ("STRING", {"default": "AnimateDiff"}),
|
|
||||||
"format": (["image/gif", "image/webp"] + ffmpeg_formats,),
|
|
||||||
"pingpong": ("BOOLEAN", {"default": False}),
|
|
||||||
"save_image": ("BOOLEAN", {"default": True}),
|
|
||||||
},
|
|
||||||
"hidden": {
|
|
||||||
"prompt": "PROMPT",
|
|
||||||
"extra_pnginfo": "EXTRA_PNGINFO",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("GIF",)
|
@classmethod
|
||||||
OUTPUT_NODE = True
|
def define_schema(cls):
|
||||||
CATEGORY = ""
|
return io.Schema(node_id='ADE_AnimateDiffCombine', display_name='🚫AnimateDiff Combine [DEPRECATED, Use Video Combine (VHS) Instead!] 🎭🅐🅓', category='', inputs=[io.Image.Input('images'), io.Int.Input('frame_rate', default=8, max=24, min=1, step=1), io.Int.Input('loop_count', default=0, max=100, min=0, step=1), io.String.Input('filename_prefix', default='AnimateDiff'), io.Combo.Input('format', options=cls.get_formats()), io.Boolean.Input('pingpong', default=False), io.Boolean.Input('save_image', default=True)], outputs=[io.Custom('GIF').Output('GIF')], is_deprecated=True, is_output_node=True, hidden=[io.Hidden.prompt, io.Hidden.extra_pnginfo])
|
||||||
FUNCTION = "generate_gif"
|
ffmpeg_warning_already_shown = False
|
||||||
DEPRECATED = True
|
|
||||||
|
|
||||||
def generate_gif(
|
@classmethod
|
||||||
self,
|
def execute(cls, images, frame_rate: int, loop_count: int, filename_prefix='AnimateDiff', format='image/gif', pingpong=False, save_image=True, prompt=None, extra_pnginfo=None):
|
||||||
images,
|
prompt = cls.hidden.prompt
|
||||||
frame_rate: int,
|
extra_pnginfo = cls.hidden.extra_pnginfo
|
||||||
loop_count: int,
|
logger.warning('Do not use AnimateDiff Combine node, it is deprecated. Use Video Combine node from ComfyUI-VideoHelperSuite instead. Video nodes from VideoHelperSuite are actively maintained, more feature-rich, and also automatically attempts to get ffmpeg.')
|
||||||
filename_prefix="AnimateDiff",
|
|
||||||
format="image/gif",
|
|
||||||
pingpong=False,
|
|
||||||
save_image=True,
|
|
||||||
prompt=None,
|
|
||||||
extra_pnginfo=None,
|
|
||||||
):
|
|
||||||
logger.warning("Do not use AnimateDiff Combine node, it is deprecated. Use Video Combine node from ComfyUI-VideoHelperSuite instead. Video nodes from VideoHelperSuite are actively maintained, more feature-rich, and also automatically attempts to get ffmpeg.")
|
|
||||||
# convert images to numpy
|
|
||||||
frames: List[Image.Image] = []
|
frames: List[Image.Image] = []
|
||||||
for image in images:
|
for image in images:
|
||||||
img = 255.0 * image.cpu().numpy()
|
img = 255.0 * image.cpu().numpy()
|
||||||
img = Image.fromarray(np.clip(img, 0, 255).astype(np.uint8))
|
img = Image.fromarray(np.clip(img, 0, 255).astype(np.uint8))
|
||||||
frames.append(img)
|
frames.append(img)
|
||||||
|
output_dir = folder_paths.get_output_directory() if save_image else folder_paths.get_temp_directory()
|
||||||
# get output information
|
full_output_folder, filename, counter, subfolder, _ = folder_paths.get_save_image_path(filename_prefix, output_dir)
|
||||||
output_dir = (
|
|
||||||
folder_paths.get_output_directory()
|
|
||||||
if save_image
|
|
||||||
else folder_paths.get_temp_directory()
|
|
||||||
)
|
|
||||||
(
|
|
||||||
full_output_folder,
|
|
||||||
filename,
|
|
||||||
counter,
|
|
||||||
subfolder,
|
|
||||||
_,
|
|
||||||
) = folder_paths.get_save_image_path(filename_prefix, output_dir)
|
|
||||||
|
|
||||||
metadata = PngInfo()
|
metadata = PngInfo()
|
||||||
if prompt is not None:
|
if prompt is not None:
|
||||||
metadata.add_text("prompt", json.dumps(prompt))
|
metadata.add_text('prompt', json.dumps(prompt))
|
||||||
if extra_pnginfo is not None:
|
if extra_pnginfo is not None:
|
||||||
for x in extra_pnginfo:
|
for x in extra_pnginfo:
|
||||||
metadata.add_text(x, json.dumps(extra_pnginfo[x]))
|
metadata.add_text(x, json.dumps(extra_pnginfo[x]))
|
||||||
|
file = f'{filename}_{counter:05}_.png'
|
||||||
# save first frame as png to keep metadata
|
|
||||||
file = f"{filename}_{counter:05}_.png"
|
|
||||||
file_path = os.path.join(full_output_folder, file)
|
file_path = os.path.join(full_output_folder, file)
|
||||||
frames[0].save(
|
frames[0].save(file_path, pnginfo=metadata, compress_level=4)
|
||||||
file_path,
|
|
||||||
pnginfo=metadata,
|
|
||||||
compress_level=4,
|
|
||||||
)
|
|
||||||
if pingpong:
|
if pingpong:
|
||||||
frames = frames + frames[-2:0:-1]
|
frames = frames + frames[-2:0:-1]
|
||||||
|
format_type, format_ext = format.split('/')
|
||||||
format_type, format_ext = format.split("/")
|
file = f'{filename}_{counter:05}_.{format_ext}'
|
||||||
file = f"{filename}_{counter:05}_.{format_ext}"
|
|
||||||
file_path = os.path.join(full_output_folder, file)
|
file_path = os.path.join(full_output_folder, file)
|
||||||
if format_type == "image":
|
if format_type == 'image':
|
||||||
# Use pillow directly to save an animated image
|
frames[0].save(file_path, format=format_ext.upper(), save_all=True, append_images=frames[1:], duration=round(1000 / frame_rate), loop=loop_count, compress_level=4)
|
||||||
frames[0].save(
|
|
||||||
file_path,
|
|
||||||
format=format_ext.upper(),
|
|
||||||
save_all=True,
|
|
||||||
append_images=frames[1:],
|
|
||||||
duration=round(1000 / frame_rate),
|
|
||||||
loop=loop_count,
|
|
||||||
compress_level=4,
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
# Use ffmpeg to save a video
|
ffmpeg_path = shutil.which('ffmpeg')
|
||||||
ffmpeg_path = shutil.which("ffmpeg")
|
|
||||||
if ffmpeg_path is None:
|
if ffmpeg_path is None:
|
||||||
#Should never be reachable
|
raise ProcessLookupError('Could not find ffmpeg')
|
||||||
raise ProcessLookupError("Could not find ffmpeg")
|
video_format_path = folder_paths.get_full_path('video_formats', format_ext + '.json')
|
||||||
|
|
||||||
video_format_path = folder_paths.get_full_path("video_formats", format_ext + ".json")
|
|
||||||
with open(video_format_path, 'r') as stream:
|
with open(video_format_path, 'r') as stream:
|
||||||
video_format = json.load(stream)
|
video_format = json.load(stream)
|
||||||
file = f"{filename}_{counter:05}_.{video_format['extension']}"
|
file = f"{filename}_{counter:05}_.{video_format['extension']}"
|
||||||
file_path = os.path.join(full_output_folder, file)
|
file_path = os.path.join(full_output_folder, file)
|
||||||
dimensions = f"{frames[0].width}x{frames[0].height}"
|
dimensions = f'{frames[0].width}x{frames[0].height}'
|
||||||
args = [ffmpeg_path, "-v", "error", "-f", "rawvideo", "-pix_fmt", "rgb24",
|
args = [ffmpeg_path, '-v', 'error', '-f', 'rawvideo', '-pix_fmt', 'rgb24', '-s', dimensions, '-r', str(frame_rate), '-i', '-'] + video_format['main_pass'] + [file_path]
|
||||||
"-s", dimensions, "-r", str(frame_rate), "-i", "-"] \
|
|
||||||
+ video_format['main_pass'] + [file_path]
|
|
||||||
|
|
||||||
env = os.environ.copy()
|
env = os.environ.copy()
|
||||||
if "environment" in video_format:
|
if 'environment' in video_format:
|
||||||
env.update(video_format["environment"])
|
env.update(video_format['environment'])
|
||||||
with subprocess.Popen(args, stdin=subprocess.PIPE, env=env) as proc:
|
with subprocess.Popen(args, stdin=subprocess.PIPE, env=env) as proc:
|
||||||
for frame in frames:
|
for frame in frames:
|
||||||
proc.stdin.write(frame.tobytes())
|
proc.stdin.write(frame.tobytes())
|
||||||
|
previews = [{'filename': file, 'subfolder': subfolder, 'type': 'output' if save_image else 'temp', 'format': format}]
|
||||||
|
return io.NodeOutput.from_dict({'ui': {'images': previews, 'animated': (True,)}})
|
||||||
|
|
||||||
previews = [
|
class AnimateDiffModelSettingsDEPR(io.ComfyNode):
|
||||||
{
|
|
||||||
"filename": file,
|
|
||||||
"subfolder": subfolder,
|
|
||||||
"type": "output" if save_image else "temp",
|
|
||||||
"format": format,
|
|
||||||
}
|
|
||||||
]
|
|
||||||
return {"ui": {"images": previews, "animated": (True,)}}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class AnimateDiffModelSettingsDEPR:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls):
|
||||||
return {
|
return io.Schema(node_id='ADE_AnimateDiffModelSettings_Release', display_name='🚫[DEPR] Motion Model Settings 🎭🅐🅓①', category='', inputs=[io.Float.Input('min_motion_scale', default=1.0, min=0.0, step=0.001), io.Float.Input('max_motion_scale', default=1.0, min=0.0, step=0.001), io.Mask.Input('mask_motion_scale', optional=True)], outputs=[io.Custom('AD_SETTINGS').Output('AD_SETTINGS')], is_deprecated=True)
|
||||||
"required": {
|
|
||||||
"min_motion_scale": ("FLOAT", {"default": 1.0, "min": 0.0, "step": 0.001}),
|
|
||||||
"max_motion_scale": ("FLOAT", {"default": 1.0, "min": 0.0, "step": 0.001}),
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"mask_motion_scale": ("MASK",),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("AD_SETTINGS",)
|
|
||||||
CATEGORY = "" #"Animate Diff 🎭🅐🅓/① Gen1 nodes ①/motion settings"
|
|
||||||
FUNCTION = "get_motion_model_settings"
|
|
||||||
DEPRECATED = True
|
|
||||||
|
|
||||||
def get_motion_model_settings(self, mask_motion_scale: torch.Tensor=None, min_motion_scale: float=1.0, max_motion_scale: float=1.0):
|
|
||||||
motion_model_settings = AnimateDiffSettings(
|
|
||||||
mask_attn_scale=mask_motion_scale,
|
|
||||||
mask_attn_scale_min=min_motion_scale,
|
|
||||||
mask_attn_scale_max=max_motion_scale,
|
|
||||||
)
|
|
||||||
|
|
||||||
return (motion_model_settings,)
|
|
||||||
|
|
||||||
|
|
||||||
class AnimateDiffModelSettingsSimpleDEPR:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def execute(cls, mask_motion_scale: torch.Tensor=None, min_motion_scale: float=1.0, max_motion_scale: float=1.0):
|
||||||
return {
|
motion_model_settings = AnimateDiffSettings(mask_attn_scale=mask_motion_scale, mask_attn_scale_min=min_motion_scale, mask_attn_scale_max=max_motion_scale)
|
||||||
"required": {
|
return io.NodeOutput(motion_model_settings)
|
||||||
"motion_pe_stretch": ("INT", {"default": 0, "min": 0, "step": 1}),
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"mask_motion_scale": ("MASK",),
|
|
||||||
"min_motion_scale": ("FLOAT", {"default": 1.0, "min": 0.0, "step": 0.001}),
|
|
||||||
"max_motion_scale": ("FLOAT", {"default": 1.0, "min": 0.0, "step": 0.001}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("AD_SETTINGS",)
|
class AnimateDiffModelSettingsSimpleDEPR(io.ComfyNode):
|
||||||
CATEGORY = "" #"Animate Diff 🎭🅐🅓/① Gen1 nodes ①/motion settings/experimental"
|
|
||||||
FUNCTION = "get_motion_model_settings"
|
|
||||||
DEPRECATED = True
|
|
||||||
|
|
||||||
def get_motion_model_settings(self, motion_pe_stretch: int,
|
@classmethod
|
||||||
mask_motion_scale: torch.Tensor=None, min_motion_scale: float=1.0, max_motion_scale: float=1.0):
|
def define_schema(cls):
|
||||||
|
return io.Schema(node_id='ADE_AnimateDiffModelSettingsSimple', display_name='🚫[DEPR] Motion Model Settings (Simple) 🎭🅐🅓①', category='', inputs=[io.Int.Input('motion_pe_stretch', default=0, min=0, step=1), io.Mask.Input('mask_motion_scale', optional=True), io.Float.Input('min_motion_scale', optional=True, default=1.0, min=0.0, step=0.001), io.Float.Input('max_motion_scale', optional=True, default=1.0, min=0.0, step=0.001)], outputs=[io.Custom('AD_SETTINGS').Output('AD_SETTINGS')], is_deprecated=True)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def execute(cls, motion_pe_stretch: int, mask_motion_scale: torch.Tensor=None, min_motion_scale: float=1.0, max_motion_scale: float=1.0):
|
||||||
adjust_pe = AdjustGroup(AdjustPE(motion_pe_stretch=motion_pe_stretch))
|
adjust_pe = AdjustGroup(AdjustPE(motion_pe_stretch=motion_pe_stretch))
|
||||||
motion_model_settings = AnimateDiffSettings(
|
motion_model_settings = AnimateDiffSettings(adjust_pe=adjust_pe, mask_attn_scale=mask_motion_scale, mask_attn_scale_min=min_motion_scale, mask_attn_scale_max=max_motion_scale)
|
||||||
adjust_pe=adjust_pe,
|
return io.NodeOutput(motion_model_settings)
|
||||||
mask_attn_scale=mask_motion_scale,
|
|
||||||
mask_attn_scale_min=min_motion_scale,
|
|
||||||
mask_attn_scale_max=max_motion_scale,
|
|
||||||
)
|
|
||||||
|
|
||||||
return (motion_model_settings,)
|
class AnimateDiffModelSettingsAdvancedDEPR(io.ComfyNode):
|
||||||
|
|
||||||
|
|
||||||
class AnimateDiffModelSettingsAdvancedDEPR:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls):
|
||||||
return {
|
return io.Schema(node_id='ADE_AnimateDiffModelSettings', display_name='🚫[DEPR] Motion Model Settings (Advanced) 🎭🅐🅓①', category='', inputs=[io.Float.Input('pe_strength', default=1.0, max=10.0, min=0.0, step=0.0001), io.Float.Input('attn_strength', default=1.0, max=10.0, min=0.0, step=0.0001), io.Float.Input('other_strength', default=1.0, max=10.0, min=0.0, step=0.0001), io.Int.Input('motion_pe_stretch', default=0, min=0, step=1), io.Int.Input('cap_initial_pe_length', default=0, min=0, step=1), io.Int.Input('interpolate_pe_to_length', default=0, min=0, step=1), io.Int.Input('initial_pe_idx_offset', default=0, min=0, step=1), io.Int.Input('final_pe_idx_offset', default=0, min=0, step=1), io.Mask.Input('mask_motion_scale', optional=True), io.Float.Input('min_motion_scale', optional=True, default=1.0, min=0.0, step=0.001), io.Float.Input('max_motion_scale', optional=True, default=1.0, min=0.0, step=0.001)], outputs=[io.Custom('AD_SETTINGS').Output('AD_SETTINGS')], is_deprecated=True)
|
||||||
"required": {
|
|
||||||
"pe_strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.0001}),
|
|
||||||
"attn_strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.0001}),
|
|
||||||
"other_strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.0001}),
|
|
||||||
"motion_pe_stretch": ("INT", {"default": 0, "min": 0, "step": 1}),
|
|
||||||
"cap_initial_pe_length": ("INT", {"default": 0, "min": 0, "step": 1}),
|
|
||||||
"interpolate_pe_to_length": ("INT", {"default": 0, "min": 0, "step": 1}),
|
|
||||||
"initial_pe_idx_offset": ("INT", {"default": 0, "min": 0, "step": 1}),
|
|
||||||
"final_pe_idx_offset": ("INT", {"default": 0, "min": 0, "step": 1}),
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"mask_motion_scale": ("MASK",),
|
|
||||||
"min_motion_scale": ("FLOAT", {"default": 1.0, "min": 0.0, "step": 0.001}),
|
|
||||||
"max_motion_scale": ("FLOAT", {"default": 1.0, "min": 0.0, "step": 0.001}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("AD_SETTINGS",)
|
|
||||||
CATEGORY = "" #"Animate Diff 🎭🅐🅓/① Gen1 nodes ①/motion settings/experimental"
|
|
||||||
FUNCTION = "get_motion_model_settings"
|
|
||||||
DEPRECATED = True
|
|
||||||
|
|
||||||
def get_motion_model_settings(self, pe_strength: float, attn_strength: float, other_strength: float,
|
|
||||||
motion_pe_stretch: int,
|
|
||||||
cap_initial_pe_length: int, interpolate_pe_to_length: int,
|
|
||||||
initial_pe_idx_offset: int, final_pe_idx_offset: int,
|
|
||||||
mask_motion_scale: torch.Tensor=None, min_motion_scale: float=1.0, max_motion_scale: float=1.0):
|
|
||||||
adjust_pe = AdjustGroup(AdjustPE(motion_pe_stretch=motion_pe_stretch,
|
|
||||||
cap_initial_pe_length=cap_initial_pe_length, interpolate_pe_to_length=interpolate_pe_to_length,
|
|
||||||
initial_pe_idx_offset=initial_pe_idx_offset, final_pe_idx_offset=final_pe_idx_offset))
|
|
||||||
adjust_weight = AdjustGroup(AdjustWeight(
|
|
||||||
pe_MULT=pe_strength,
|
|
||||||
attn_MULT=attn_strength,
|
|
||||||
other_MULT=other_strength,
|
|
||||||
))
|
|
||||||
motion_model_settings = AnimateDiffSettings(
|
|
||||||
adjust_pe=adjust_pe,
|
|
||||||
adjust_weight=adjust_weight,
|
|
||||||
mask_attn_scale=mask_motion_scale,
|
|
||||||
mask_attn_scale_min=min_motion_scale,
|
|
||||||
mask_attn_scale_max=max_motion_scale,
|
|
||||||
)
|
|
||||||
|
|
||||||
return (motion_model_settings,)
|
|
||||||
|
|
||||||
|
|
||||||
class AnimateDiffModelSettingsAdvancedAttnStrengthsDEPR:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def execute(cls, pe_strength: float, attn_strength: float, other_strength: float, motion_pe_stretch: int, cap_initial_pe_length: int, interpolate_pe_to_length: int, initial_pe_idx_offset: int, final_pe_idx_offset: int, mask_motion_scale: torch.Tensor=None, min_motion_scale: float=1.0, max_motion_scale: float=1.0):
|
||||||
return {
|
adjust_pe = AdjustGroup(AdjustPE(motion_pe_stretch=motion_pe_stretch, cap_initial_pe_length=cap_initial_pe_length, interpolate_pe_to_length=interpolate_pe_to_length, initial_pe_idx_offset=initial_pe_idx_offset, final_pe_idx_offset=final_pe_idx_offset))
|
||||||
"required": {
|
adjust_weight = AdjustGroup(AdjustWeight(pe_MULT=pe_strength, attn_MULT=attn_strength, other_MULT=other_strength))
|
||||||
"pe_strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.0001}),
|
motion_model_settings = AnimateDiffSettings(adjust_pe=adjust_pe, adjust_weight=adjust_weight, mask_attn_scale=mask_motion_scale, mask_attn_scale_min=min_motion_scale, mask_attn_scale_max=max_motion_scale)
|
||||||
"attn_strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.0001}),
|
return io.NodeOutput(motion_model_settings)
|
||||||
"attn_q_strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.0001}),
|
|
||||||
"attn_k_strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.0001}),
|
|
||||||
"attn_v_strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.0001}),
|
|
||||||
"attn_out_weight_strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.0001}),
|
|
||||||
"attn_out_bias_strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.0001}),
|
|
||||||
"other_strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.0001}),
|
|
||||||
"motion_pe_stretch": ("INT", {"default": 0, "min": 0, "step": 1}),
|
|
||||||
"cap_initial_pe_length": ("INT", {"default": 0, "min": 0, "step": 1}),
|
|
||||||
"interpolate_pe_to_length": ("INT", {"default": 0, "min": 0, "step": 1}),
|
|
||||||
"initial_pe_idx_offset": ("INT", {"default": 0, "min": 0, "step": 1}),
|
|
||||||
"final_pe_idx_offset": ("INT", {"default": 0, "min": 0, "step": 1}),
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"mask_motion_scale": ("MASK",),
|
|
||||||
"min_motion_scale": ("FLOAT", {"default": 1.0, "min": 0.0, "step": 0.001}),
|
|
||||||
"max_motion_scale": ("FLOAT", {"default": 1.0, "min": 0.0, "step": 0.001}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("AD_SETTINGS",)
|
class AnimateDiffModelSettingsAdvancedAttnStrengthsDEPR(io.ComfyNode):
|
||||||
CATEGORY = "" #"Animate Diff 🎭🅐🅓/① Gen1 nodes ①/motion settings/experimental"
|
|
||||||
FUNCTION = "get_motion_model_settings"
|
|
||||||
DEPRECATED = True
|
|
||||||
|
|
||||||
def get_motion_model_settings(self, pe_strength: float, attn_strength: float,
|
@classmethod
|
||||||
attn_q_strength: float,
|
def define_schema(cls):
|
||||||
attn_k_strength: float,
|
return io.Schema(node_id='ADE_AnimateDiffModelSettingsAdvancedAttnStrengths', display_name='🚫[DEPR] Motion Model Settings (Adv. Attn) 🎭🅐🅓①', category='', inputs=[io.Float.Input('pe_strength', default=1.0, max=10.0, min=0.0, step=0.0001), io.Float.Input('attn_strength', default=1.0, max=10.0, min=0.0, step=0.0001), io.Float.Input('attn_q_strength', default=1.0, max=10.0, min=0.0, step=0.0001), io.Float.Input('attn_k_strength', default=1.0, max=10.0, min=0.0, step=0.0001), io.Float.Input('attn_v_strength', default=1.0, max=10.0, min=0.0, step=0.0001), io.Float.Input('attn_out_weight_strength', default=1.0, max=10.0, min=0.0, step=0.0001), io.Float.Input('attn_out_bias_strength', default=1.0, max=10.0, min=0.0, step=0.0001), io.Float.Input('other_strength', default=1.0, max=10.0, min=0.0, step=0.0001), io.Int.Input('motion_pe_stretch', default=0, min=0, step=1), io.Int.Input('cap_initial_pe_length', default=0, min=0, step=1), io.Int.Input('interpolate_pe_to_length', default=0, min=0, step=1), io.Int.Input('initial_pe_idx_offset', default=0, min=0, step=1), io.Int.Input('final_pe_idx_offset', default=0, min=0, step=1), io.Mask.Input('mask_motion_scale', optional=True), io.Float.Input('min_motion_scale', optional=True, default=1.0, min=0.0, step=0.001), io.Float.Input('max_motion_scale', optional=True, default=1.0, min=0.0, step=0.001)], outputs=[io.Custom('AD_SETTINGS').Output('AD_SETTINGS')], is_deprecated=True)
|
||||||
attn_v_strength: float,
|
|
||||||
attn_out_weight_strength: float,
|
|
||||||
attn_out_bias_strength: float,
|
|
||||||
other_strength: float,
|
|
||||||
motion_pe_stretch: int,
|
|
||||||
cap_initial_pe_length: int, interpolate_pe_to_length: int,
|
|
||||||
initial_pe_idx_offset: int, final_pe_idx_offset: int,
|
|
||||||
mask_motion_scale: torch.Tensor=None, min_motion_scale: float=1.0, max_motion_scale: float=1.0):
|
|
||||||
adjust_pe = AdjustGroup(AdjustPE(motion_pe_stretch=motion_pe_stretch,
|
|
||||||
cap_initial_pe_length=cap_initial_pe_length, interpolate_pe_to_length=interpolate_pe_to_length,
|
|
||||||
initial_pe_idx_offset=initial_pe_idx_offset, final_pe_idx_offset=final_pe_idx_offset))
|
|
||||||
adjust_weight = AdjustGroup(AdjustWeight(
|
|
||||||
pe_MULT=pe_strength,
|
|
||||||
attn_MULT=attn_strength,
|
|
||||||
attn_q_MULT=attn_q_strength,
|
|
||||||
attn_k_MULT=attn_k_strength,
|
|
||||||
attn_v_MULT=attn_v_strength,
|
|
||||||
attn_out_weight_MULT=attn_out_weight_strength,
|
|
||||||
attn_out_bias_MULT=attn_out_bias_strength,
|
|
||||||
other_MULT=other_strength,
|
|
||||||
))
|
|
||||||
motion_model_settings = AnimateDiffSettings(
|
|
||||||
adjust_pe=adjust_pe,
|
|
||||||
adjust_weight=adjust_weight,
|
|
||||||
mask_attn_scale=mask_motion_scale,
|
|
||||||
mask_attn_scale_min=min_motion_scale,
|
|
||||||
mask_attn_scale_max=max_motion_scale,
|
|
||||||
)
|
|
||||||
|
|
||||||
return (motion_model_settings,)
|
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def execute(cls, pe_strength: float, attn_strength: float, attn_q_strength: float, attn_k_strength: float, attn_v_strength: float, attn_out_weight_strength: float, attn_out_bias_strength: float, other_strength: float, motion_pe_stretch: int, cap_initial_pe_length: int, interpolate_pe_to_length: int, initial_pe_idx_offset: int, final_pe_idx_offset: int, mask_motion_scale: torch.Tensor=None, min_motion_scale: float=1.0, max_motion_scale: float=1.0):
|
||||||
|
adjust_pe = AdjustGroup(AdjustPE(motion_pe_stretch=motion_pe_stretch, cap_initial_pe_length=cap_initial_pe_length, interpolate_pe_to_length=interpolate_pe_to_length, initial_pe_idx_offset=initial_pe_idx_offset, final_pe_idx_offset=final_pe_idx_offset))
|
||||||
|
adjust_weight = AdjustGroup(AdjustWeight(pe_MULT=pe_strength, attn_MULT=attn_strength, attn_q_MULT=attn_q_strength, attn_k_MULT=attn_k_strength, attn_v_MULT=attn_v_strength, attn_out_weight_MULT=attn_out_weight_strength, attn_out_bias_MULT=attn_out_bias_strength, other_MULT=other_strength))
|
||||||
|
motion_model_settings = AnimateDiffSettings(adjust_pe=adjust_pe, adjust_weight=adjust_weight, mask_attn_scale=mask_motion_scale, mask_attn_scale_min=min_motion_scale, mask_attn_scale_max=max_motion_scale)
|
||||||
|
return io.NodeOutput(motion_model_settings)
|
||||||
|
|||||||
+62
-79
@@ -3,6 +3,8 @@ from typing import Union
|
|||||||
import torch
|
import torch
|
||||||
from torch import Tensor
|
from torch import Tensor
|
||||||
|
|
||||||
|
from comfy_api.latest import io
|
||||||
|
|
||||||
import folder_paths
|
import folder_paths
|
||||||
import nodes as comfy_nodes
|
import nodes as comfy_nodes
|
||||||
from comfy.model_patcher import ModelPatcher
|
from comfy.model_patcher import ModelPatcher
|
||||||
@@ -17,44 +19,36 @@ from .model_injection import get_vanilla_model_patcher
|
|||||||
from .cfg_extras import perturbed_attention_guidance_patch, rescale_cfg_patch
|
from .cfg_extras import perturbed_attention_guidance_patch, rescale_cfg_patch
|
||||||
|
|
||||||
|
|
||||||
class AnimateDiffUnload:
|
class AnimateDiffUnload(io.ComfyNode):
|
||||||
def __init__(self) -> None:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {"required": {"model": ("MODEL",)}}
|
return io.Schema(
|
||||||
|
node_id='ADE_AnimateDiffUnload',
|
||||||
RETURN_TYPES = ("MODEL",)
|
display_name='AnimateDiff Unload 🎭🅐🅓',
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/extras"
|
category='Animate Diff 🎭🅐🅓/extras',
|
||||||
FUNCTION = "unload_motion_modules"
|
inputs=[io.Model.Input('model')],
|
||||||
|
outputs=[io.Model.Output('MODEL')]
|
||||||
def unload_motion_modules(self, model: ModelPatcher):
|
)
|
||||||
|
@classmethod
|
||||||
|
def execute(cls, model: ModelPatcher):
|
||||||
# return model clone with ejected params
|
# return model clone with ejected params
|
||||||
#model = eject_params_from_model(model)
|
#model = eject_params_from_model(model)
|
||||||
model = get_vanilla_model_patcher(model)
|
model = get_vanilla_model_patcher(model)
|
||||||
return (model.clone(),)
|
return io.NodeOutput(model.clone())
|
||||||
|
|
||||||
|
|
||||||
class CheckpointLoaderSimpleWithNoiseSelect:
|
class CheckpointLoaderSimpleWithNoiseSelect(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {
|
return io.Schema(
|
||||||
"required": {
|
node_id='CheckpointLoaderSimpleWithNoiseSelect',
|
||||||
"ckpt_name": (folder_paths.get_filename_list("checkpoints"), ),
|
display_name='Load Checkpoint w/ Noise Select 🎭🅐🅓',
|
||||||
"beta_schedule": (BetaSchedules.ALIAS_LIST, {"default": BetaSchedules.USE_EXISTING}, )
|
category='Animate Diff 🎭🅐🅓/extras',
|
||||||
},
|
inputs=[io.Combo.Input('ckpt_name', options=folder_paths.get_filename_list("checkpoints")), io.Combo.Input('beta_schedule', options=['autoselect', 'use existing', 'sqrt_linear (AnimateDiff)', 'linear (AnimateDiff-SDXL)', 'linear (HotshotXL/default)', 'avg(sqrt_linear,linear)', 'lcm avg(sqrt_linear,linear)', 'lcm', 'lcm[100_ots]', 'lcm >> sqrt_linear', 'sqrt', 'cosine', 'squaredcos_cap_v2'] , default='use existing'), io.Boolean.Input('use_custom_scale_factor', default=False, optional=True), io.Float.Input('scale_factor', default=0.18215, max=1.0, min=0.0, step=1e-05, optional=True)],
|
||||||
"optional": {
|
outputs=[io.Model.Output('MODEL'), io.Clip.Output('CLIP'), io.Vae.Output('VAE')]
|
||||||
"use_custom_scale_factor": ("BOOLEAN", {"default": False}),
|
)
|
||||||
"scale_factor": ("FLOAT", {"default": 0.18215, "min": 0.0, "max": 1.0, "step": 0.00001})
|
@classmethod
|
||||||
}
|
def execute(cls, ckpt_name, beta_schedule, output_vae=True, output_clip=True, use_custom_scale_factor=False, scale_factor=0.18215):
|
||||||
}
|
|
||||||
RETURN_TYPES = ("MODEL", "CLIP", "VAE")
|
|
||||||
FUNCTION = "load_checkpoint"
|
|
||||||
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/extras"
|
|
||||||
|
|
||||||
def load_checkpoint(self, ckpt_name, beta_schedule, output_vae=True, output_clip=True, use_custom_scale_factor=False, scale_factor=0.18215):
|
|
||||||
ckpt_path = folder_paths.get_full_path("checkpoints", ckpt_name)
|
ckpt_path = folder_paths.get_full_path("checkpoints", ckpt_name)
|
||||||
out = load_checkpoint_guess_config(ckpt_path, output_vae=True, output_clip=True, embedding_directory=folder_paths.get_folder_paths("embeddings"))
|
out = load_checkpoint_guess_config(ckpt_path, output_vae=True, output_clip=True, embedding_directory=folder_paths.get_folder_paths("embeddings"))
|
||||||
# register chosen beta schedule on model - convert to beta_schedule name recognized by ComfyUI
|
# register chosen beta schedule on model - convert to beta_schedule name recognized by ComfyUI
|
||||||
@@ -63,66 +57,55 @@ class CheckpointLoaderSimpleWithNoiseSelect:
|
|||||||
out[0].model.model_sampling = new_model_sampling
|
out[0].model.model_sampling = new_model_sampling
|
||||||
if use_custom_scale_factor:
|
if use_custom_scale_factor:
|
||||||
out[0].model.latent_format.scale_factor = scale_factor
|
out[0].model.latent_format.scale_factor = scale_factor
|
||||||
return out
|
return io.NodeOutput(*out)
|
||||||
|
|
||||||
|
|
||||||
class EmptyLatentImageLarge:
|
class EmptyLatentImageLarge(io.ComfyNode):
|
||||||
def __init__(self, device="cpu"):
|
|
||||||
self.device = device
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {"required": { "width": ("INT", {"default": 512, "min": 64, "max": comfy_nodes.MAX_RESOLUTION, "step": 8}),
|
return io.Schema(
|
||||||
"height": ("INT", {"default": 512, "min": 64, "max": comfy_nodes.MAX_RESOLUTION, "step": 8}),
|
node_id='ADE_EmptyLatentImageLarge',
|
||||||
"batch_size": ("INT", {"default": 1, "min": 1, "max": 262144})}}
|
display_name='Empty Latent Image (Big Batch) 🎭🅐🅓',
|
||||||
RETURN_TYPES = ("LATENT",)
|
category='Animate Diff 🎭🅐🅓/extras',
|
||||||
FUNCTION = "generate"
|
inputs=[io.Int.Input('width', default=512, max=16384, min=64, step=8), io.Int.Input('height', default=512, max=16384, min=64, step=8), io.Int.Input('batch_size', default=1, max=262144, min=1)],
|
||||||
|
outputs=[io.Latent.Output('LATENT')]
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/extras"
|
)
|
||||||
|
@classmethod
|
||||||
def generate(self, width, height, batch_size=1):
|
def execute(cls, width, height, batch_size=1):
|
||||||
latent = torch.zeros([batch_size, 4, height // 8, width // 8])
|
latent = torch.zeros([batch_size, 4, height // 8, width // 8])
|
||||||
return ({"samples":latent}, )
|
return io.NodeOutput({"samples":latent})
|
||||||
|
|
||||||
|
|
||||||
class PerturbedAttentionGuidanceMultival:
|
class PerturbedAttentionGuidanceMultival(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {
|
return io.Schema(
|
||||||
"required": {
|
node_id='ADE_PerturbedAttentionGuidanceMultival',
|
||||||
"model": ("MODEL",),
|
display_name='PerturbedAttnGuide [Multival] 🎭🅐🅓',
|
||||||
"scale_multival": ("MULTIVAL",),
|
category='Animate Diff 🎭🅐🅓/extras',
|
||||||
}
|
inputs=[io.Model.Input('model'), io.Custom('MULTIVAL').Input('scale_multival')],
|
||||||
}
|
outputs=[io.Model.Output('MODEL')]
|
||||||
|
)
|
||||||
RETURN_TYPES = ("MODEL",)
|
@classmethod
|
||||||
FUNCTION = "patch"
|
def execute(cls, model: ModelPatcher, scale_multival: Union[float, Tensor]):
|
||||||
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/extras"
|
|
||||||
|
|
||||||
def patch(self, model: ModelPatcher, scale_multival: Union[float, Tensor]):
|
|
||||||
m = model.clone()
|
m = model.clone()
|
||||||
m.set_model_sampler_post_cfg_function(perturbed_attention_guidance_patch(scale_multival))
|
m.set_model_sampler_post_cfg_function(perturbed_attention_guidance_patch(scale_multival))
|
||||||
|
|
||||||
return (m,)
|
return io.NodeOutput(m)
|
||||||
|
|
||||||
|
|
||||||
class RescaleCFGMultival:
|
class RescaleCFGMultival(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {
|
return io.Schema(
|
||||||
"required": {
|
node_id='ADE_RescaleCFGMultival',
|
||||||
"model": ("MODEL",),
|
display_name='RescaleCFG [Multival] 🎭🅐🅓',
|
||||||
"mult_multival": ("MULTIVAL",),
|
category='Animate Diff 🎭🅐🅓/extras',
|
||||||
}
|
inputs=[io.Model.Input('model'), io.Custom('MULTIVAL').Input('mult_multival')],
|
||||||
}
|
outputs=[io.Model.Output('MODEL')]
|
||||||
|
)
|
||||||
RETURN_TYPES = ("MODEL",)
|
@classmethod
|
||||||
FUNCTION = "patch"
|
def execute(cls, model: ModelPatcher, mult_multival: Union[float, Tensor]):
|
||||||
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/extras"
|
|
||||||
|
|
||||||
def patch(self, model: ModelPatcher, mult_multival: Union[float, Tensor]):
|
|
||||||
m = model.clone()
|
m = model.clone()
|
||||||
m.set_model_sampler_cfg_function(rescale_cfg_patch(mult_multival))
|
m.set_model_sampler_cfg_function(rescale_cfg_patch(mult_multival))
|
||||||
return (m, )
|
return io.NodeOutput(m)
|
||||||
|
|||||||
+27
-25
@@ -1,3 +1,4 @@
|
|||||||
|
from comfy_api.latest import io
|
||||||
from comfy.model_patcher import ModelPatcher
|
from comfy.model_patcher import ModelPatcher
|
||||||
|
|
||||||
from .ad_settings import AnimateDiffSettings
|
from .ad_settings import AnimateDiffSettings
|
||||||
@@ -13,33 +14,34 @@ from .sample_settings import SampleSettings
|
|||||||
from .sampling import outer_sample_wrapper, sliding_calc_cond_batch
|
from .sampling import outer_sample_wrapper, sliding_calc_cond_batch
|
||||||
|
|
||||||
|
|
||||||
class AnimateDiffLoaderGen1:
|
class AnimateDiffLoaderGen1(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {
|
return io.Schema(
|
||||||
"required": {
|
node_id='ADE_AnimateDiffLoaderGen1',
|
||||||
"model": ("MODEL",),
|
display_name='AnimateDiff Loader 🎭🅐🅓①',
|
||||||
"model_name": (get_available_motion_models(),),
|
category='Animate Diff 🎭🅐🅓/① Gen1 nodes ①',
|
||||||
"beta_schedule": (BetaSchedules.ALIAS_LIST, {"default": BetaSchedules.AUTOSELECT}),
|
inputs=[
|
||||||
#"apply_mm_groupnorm_hack": ("BOOLEAN", {"default": True}),
|
io.Model.Input('model'),
|
||||||
},
|
io.Combo.Input('model_name', options=get_available_motion_models()),
|
||||||
"optional": {
|
io.Combo.Input('beta_schedule', options=['autoselect', 'use existing', 'sqrt_linear (AnimateDiff)', 'linear (AnimateDiff-SDXL)', 'linear (HotshotXL/default)', 'avg(sqrt_linear,linear)', 'lcm avg(sqrt_linear,linear)', 'lcm', 'lcm[100_ots]', 'lcm >> sqrt_linear', 'sqrt', 'cosine', 'squaredcos_cap_v2'], default='autoselect'),
|
||||||
"context_options": ("CONTEXT_OPTIONS",),
|
io.Custom("CONTEXT_OPTIONS").Input('context_options', optional=True),
|
||||||
"motion_lora": ("MOTION_LORA",),
|
io.Custom("MOTION_LORA").Input('motion_lora', optional=True),
|
||||||
"ad_settings": ("AD_SETTINGS",),
|
io.Custom("AD_SETTINGS").Input('ad_settings', optional=True),
|
||||||
"ad_keyframes": ("AD_KEYFRAMES",),
|
io.Custom("AD_KEYFRAMES").Input('ad_keyframes', optional=True),
|
||||||
"sample_settings": ("SAMPLE_SETTINGS",),
|
io.Custom("SAMPLE_SETTINGS").Input('sample_settings', optional=True),
|
||||||
"scale_multival": ("MULTIVAL",),
|
io.Custom("MULTIVAL").Input('scale_multival', optional=True),
|
||||||
"effect_multival": ("MULTIVAL",),
|
io.Custom("MULTIVAL").Input('effect_multival', optional=True),
|
||||||
"per_block": ("PER_BLOCK",),
|
io.Custom("PER_BLOCK").Input('per_block', optional=True),
|
||||||
}
|
],
|
||||||
}
|
outputs=[
|
||||||
|
io.Model.Output('MODEL'),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
RETURN_TYPES = ("MODEL",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/① Gen1 nodes ①"
|
|
||||||
FUNCTION = "load_mm_and_inject_params"
|
|
||||||
|
|
||||||
def load_mm_and_inject_params(self,
|
@classmethod
|
||||||
|
def execute(cls,
|
||||||
model: ModelPatcher,
|
model: ModelPatcher,
|
||||||
model_name: str, beta_schedule: str,# apply_mm_groupnorm_hack: bool,
|
model_name: str, beta_schedule: str,# apply_mm_groupnorm_hack: bool,
|
||||||
context_options: ContextOptionsGroup=None, motion_lora: MotionLoraList=None, ad_settings: AnimateDiffSettings=None,
|
context_options: ContextOptionsGroup=None, motion_lora: MotionLoraList=None, ad_settings: AnimateDiffSettings=None,
|
||||||
@@ -107,4 +109,4 @@ class AnimateDiffLoaderGen1:
|
|||||||
model.add_object_patch("model_sampling", new_model_sampling)
|
model.add_object_patch("model_sampling", new_model_sampling)
|
||||||
|
|
||||||
del motion_model
|
del motion_model
|
||||||
return (model,)
|
return io.NodeOutput(model,)
|
||||||
|
|||||||
+106
-96
@@ -1,3 +1,4 @@
|
|||||||
|
from comfy_api.latest import io
|
||||||
from typing import Union
|
from typing import Union
|
||||||
import torch
|
import torch
|
||||||
|
|
||||||
@@ -17,26 +18,28 @@ from .sample_settings import SampleSettings
|
|||||||
from .sampling import outer_sample_wrapper, sliding_calc_cond_batch
|
from .sampling import outer_sample_wrapper, sliding_calc_cond_batch
|
||||||
|
|
||||||
|
|
||||||
class UseEvolvedSamplingNode:
|
class UseEvolvedSamplingNode(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {
|
return io.Schema(
|
||||||
"required": {
|
node_id='ADE_UseEvolvedSampling',
|
||||||
"model": ("MODEL",),
|
display_name='Use Evolved Sampling 🎭🅐🅓②',
|
||||||
"beta_schedule": (BetaSchedules.ALIAS_LIST, {"default": BetaSchedules.AUTOSELECT}),
|
category='Animate Diff 🎭🅐🅓/② Gen2 nodes ②',
|
||||||
},
|
inputs=[
|
||||||
"optional": {
|
io.Model.Input('model'),
|
||||||
"m_models": ("M_MODELS",),
|
io.Combo.Input('beta_schedule', options=['autoselect', 'use existing', 'sqrt_linear (AnimateDiff)', 'linear (AnimateDiff-SDXL)', 'linear (HotshotXL/default)', 'avg(sqrt_linear,linear)', 'lcm avg(sqrt_linear,linear)', 'lcm', 'lcm[100_ots]', 'lcm >> sqrt_linear', 'sqrt', 'cosine', 'squaredcos_cap_v2'], default='autoselect'),
|
||||||
"context_options": ("CONTEXT_OPTIONS",),
|
io.Custom("M_MODELS").Input('m_models', optional=True),
|
||||||
"sample_settings": ("SAMPLE_SETTINGS",),
|
io.Custom("CONTEXT_OPTIONS").Input('context_options', optional=True),
|
||||||
}
|
io.Custom("SAMPLE_SETTINGS").Input('sample_settings', optional=True),
|
||||||
}
|
],
|
||||||
|
outputs=[
|
||||||
|
io.Model.Output('MODEL'),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
RETURN_TYPES = ("MODEL",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/② Gen2 nodes ②"
|
|
||||||
FUNCTION = "use_evolved_sampling"
|
|
||||||
|
|
||||||
def use_evolved_sampling(self, model: ModelPatcher, beta_schedule: str, m_models: MotionModelGroup=None, context_options: ContextOptionsGroup=None,
|
@classmethod
|
||||||
|
def execute(cls, model: ModelPatcher, beta_schedule: str, m_models: MotionModelGroup=None, context_options: ContextOptionsGroup=None,
|
||||||
sample_settings: SampleSettings=None):
|
sample_settings: SampleSettings=None):
|
||||||
model = model.clone()
|
model = model.clone()
|
||||||
helper = ModelPatcherHelper(model)
|
helper = ModelPatcherHelper(model)
|
||||||
@@ -81,33 +84,35 @@ class UseEvolvedSamplingNode:
|
|||||||
model.add_object_patch("model_sampling", new_model_sampling)
|
model.add_object_patch("model_sampling", new_model_sampling)
|
||||||
|
|
||||||
del m_models
|
del m_models
|
||||||
return (model,)
|
return io.NodeOutput(model,)
|
||||||
|
|
||||||
|
|
||||||
class ApplyAnimateDiffModelNode:
|
class ApplyAnimateDiffModelNode(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {
|
return io.Schema(
|
||||||
"required": {
|
node_id='ADE_ApplyAnimateDiffModel',
|
||||||
"motion_model": ("MOTION_MODEL_ADE",),
|
display_name='Apply AnimateDiff Model (Adv.) 🎭🅐🅓②',
|
||||||
"start_percent": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001}),
|
category='Animate Diff 🎭🅐🅓/② Gen2 nodes ②',
|
||||||
"end_percent": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.001}),
|
inputs=[
|
||||||
},
|
io.Custom("MOTION_MODEL_ADE").Input('motion_model'),
|
||||||
"optional": {
|
io.Float.Input('start_percent', default=0.0, max=1.0, min=0.0, step=0.001),
|
||||||
"motion_lora": ("MOTION_LORA",),
|
io.Float.Input('end_percent', default=1.0, max=1.0, min=0.0, step=0.001),
|
||||||
"scale_multival": ("MULTIVAL",),
|
io.Custom("MOTION_LORA").Input('motion_lora', optional=True),
|
||||||
"effect_multival": ("MULTIVAL",),
|
io.Custom("MULTIVAL").Input('scale_multival', optional=True),
|
||||||
"ad_keyframes": ("AD_KEYFRAMES",),
|
io.Custom("MULTIVAL").Input('effect_multival', optional=True),
|
||||||
"prev_m_models": ("M_MODELS",),
|
io.Custom("AD_KEYFRAMES").Input('ad_keyframes', optional=True),
|
||||||
"per_block": ("PER_BLOCK",),
|
io.Custom("M_MODELS").Input('prev_m_models', optional=True),
|
||||||
},
|
io.Custom("PER_BLOCK").Input('per_block', optional=True),
|
||||||
}
|
],
|
||||||
|
outputs=[
|
||||||
|
io.Custom("M_MODELS").Output('M_MODELS'),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
RETURN_TYPES = ("M_MODELS",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/② Gen2 nodes ②"
|
|
||||||
FUNCTION = "apply_motion_model"
|
|
||||||
|
|
||||||
def apply_motion_model(self, motion_model: MotionModelPatcher, start_percent: float=0.0, end_percent: float=1.0,
|
@classmethod
|
||||||
|
def execute(cls, motion_model: MotionModelPatcher, start_percent: float=0.0, end_percent: float=1.0,
|
||||||
motion_lora: MotionLoraList=None, ad_keyframes: ADKeyframeGroup=None,
|
motion_lora: MotionLoraList=None, ad_keyframes: ADKeyframeGroup=None,
|
||||||
scale_multival=None, effect_multival=None, per_block: AllPerBlocks=None,
|
scale_multival=None, effect_multival=None, per_block: AllPerBlocks=None,
|
||||||
prev_m_models: MotionModelGroup=None,):
|
prev_m_models: MotionModelGroup=None,):
|
||||||
@@ -136,85 +141,90 @@ class ApplyAnimateDiffModelNode:
|
|||||||
attachment.timestep_percent_range = (start_percent, end_percent)
|
attachment.timestep_percent_range = (start_percent, end_percent)
|
||||||
# add to beginning, so that after injection, it will be the earliest of prev_m_models to be run
|
# add to beginning, so that after injection, it will be the earliest of prev_m_models to be run
|
||||||
prev_m_models.add_to_start(mm=motion_model)
|
prev_m_models.add_to_start(mm=motion_model)
|
||||||
return (prev_m_models,)
|
return io.NodeOutput(prev_m_models,)
|
||||||
|
|
||||||
|
|
||||||
class ApplyAnimateDiffModelBasicNode:
|
class ApplyAnimateDiffModelBasicNode(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {
|
return io.Schema(
|
||||||
"required": {
|
node_id='ADE_ApplyAnimateDiffModelSimple',
|
||||||
"motion_model": ("MOTION_MODEL_ADE",),
|
display_name='Apply AnimateDiff Model 🎭🅐🅓②',
|
||||||
},
|
category='Animate Diff 🎭🅐🅓/② Gen2 nodes ②',
|
||||||
"optional": {
|
inputs=[
|
||||||
"motion_lora": ("MOTION_LORA",),
|
io.Custom("MOTION_MODEL_ADE").Input('motion_model'),
|
||||||
"scale_multival": ("MULTIVAL",),
|
io.Custom("MOTION_LORA").Input('motion_lora', optional=True),
|
||||||
"effect_multival": ("MULTIVAL",),
|
io.Custom("MULTIVAL").Input('scale_multival', optional=True),
|
||||||
"ad_keyframes": ("AD_KEYFRAMES",),
|
io.Custom("MULTIVAL").Input('effect_multival', optional=True),
|
||||||
"per_block": ("PER_BLOCK",),
|
io.Custom("AD_KEYFRAMES").Input('ad_keyframes', optional=True),
|
||||||
},
|
io.Custom("PER_BLOCK").Input('per_block', optional=True),
|
||||||
}
|
],
|
||||||
|
outputs=[
|
||||||
|
io.Custom("M_MODELS").Output('M_MODELS'),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
RETURN_TYPES = ("M_MODELS",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/② Gen2 nodes ②"
|
|
||||||
FUNCTION = "apply_motion_model"
|
|
||||||
|
|
||||||
def apply_motion_model(self,
|
@classmethod
|
||||||
|
def execute(cls,
|
||||||
motion_model: MotionModelPatcher, motion_lora: MotionLoraList=None,
|
motion_model: MotionModelPatcher, motion_lora: MotionLoraList=None,
|
||||||
scale_multival=None, effect_multival=None, ad_keyframes=None,
|
scale_multival=None, effect_multival=None, ad_keyframes=None,
|
||||||
per_block: AllPerBlocks=None):
|
per_block: AllPerBlocks=None):
|
||||||
# just a subset of normal ApplyAnimateDiffModelNode inputs
|
# just a subset of normal ApplyAnimateDiffModelNode inputs
|
||||||
return ApplyAnimateDiffModelNode.apply_motion_model(self, motion_model, motion_lora=motion_lora,
|
return io.NodeOutput(*ApplyAnimateDiffModelNode.execute( motion_model, motion_lora=motion_lora,
|
||||||
scale_multival=scale_multival, effect_multival=effect_multival,
|
scale_multival=scale_multival, effect_multival=effect_multival,
|
||||||
ad_keyframes=ad_keyframes, per_block=per_block)
|
ad_keyframes=ad_keyframes, per_block=per_block).args)
|
||||||
|
|
||||||
|
|
||||||
class LoadAnimateDiffModelNode:
|
class LoadAnimateDiffModelNode(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {
|
return io.Schema(
|
||||||
"required": {
|
node_id='ADE_LoadAnimateDiffModel',
|
||||||
"model_name": (get_available_motion_models(),),
|
display_name='Load AnimateDiff Model 🎭🅐🅓②',
|
||||||
},
|
category='Animate Diff 🎭🅐🅓/② Gen2 nodes ②',
|
||||||
"optional": {
|
inputs=[
|
||||||
"ad_settings": ("AD_SETTINGS",),
|
io.Combo.Input('model_name', options=get_available_motion_models()),
|
||||||
},
|
io.Custom("AD_SETTINGS").Input('ad_settings', optional=True),
|
||||||
}
|
],
|
||||||
|
outputs=[
|
||||||
|
io.Custom("MOTION_MODEL_ADE").Output('MOTION_MODEL'),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
RETURN_TYPES = ("MOTION_MODEL_ADE",)
|
|
||||||
RETURN_NAMES = ("MOTION_MODEL",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/② Gen2 nodes ②"
|
|
||||||
FUNCTION = "load_motion_model"
|
|
||||||
|
|
||||||
def load_motion_model(self, model_name: str, ad_settings: AnimateDiffSettings=None):
|
@classmethod
|
||||||
|
def execute(cls, model_name: str, ad_settings: AnimateDiffSettings=None):
|
||||||
# load motion module and motion settings, if included
|
# load motion module and motion settings, if included
|
||||||
motion_model = load_motion_module_gen2(model_name=model_name, motion_model_settings=ad_settings)
|
motion_model = load_motion_module_gen2(model_name=model_name, motion_model_settings=ad_settings)
|
||||||
return (motion_model,)
|
return io.NodeOutput(motion_model,)
|
||||||
|
|
||||||
|
|
||||||
class ADKeyframeNode:
|
class ADKeyframeNode(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {
|
return io.Schema(
|
||||||
"required": {
|
node_id='ADE_AnimateDiffKeyframe',
|
||||||
"start_percent": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001}, ),
|
display_name='AnimateDiff Keyframe 🎭🅐🅓',
|
||||||
},
|
category='Animate Diff 🎭🅐🅓',
|
||||||
"optional": {
|
inputs=[
|
||||||
"prev_ad_keyframes": ("AD_KEYFRAMES", ),
|
io.Float.Input('start_percent', default=0.0, max=1.0, min=0.0, step=0.001),
|
||||||
"scale_multival": ("MULTIVAL",),
|
io.Custom("AD_KEYFRAMES").Input('prev_ad_keyframes', optional=True),
|
||||||
"effect_multival": ("MULTIVAL",),
|
io.Custom("MULTIVAL").Input('scale_multival', optional=True),
|
||||||
"per_block_replace": ("PER_BLOCK",),
|
io.Custom("MULTIVAL").Input('effect_multival', optional=True),
|
||||||
"inherit_missing": ("BOOLEAN", {"default": True}, ),
|
io.Custom("PER_BLOCK").Input('per_block_replace', optional=True),
|
||||||
"guarantee_steps": ("INT", {"default": 1, "min": 0, "max": BIGMAX}),
|
io.Boolean.Input('inherit_missing', optional=True, default=True),
|
||||||
},
|
io.Int.Input('guarantee_steps', optional=True, default=1, max=9007199254740991, min=0),
|
||||||
}
|
],
|
||||||
|
outputs=[
|
||||||
|
io.Custom("AD_KEYFRAMES").Output('AD_KEYFRAMES'),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
RETURN_TYPES = ("AD_KEYFRAMES", )
|
|
||||||
FUNCTION = "load_keyframe"
|
|
||||||
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓"
|
|
||||||
|
|
||||||
def load_keyframe(self,
|
@classmethod
|
||||||
|
def execute(cls,
|
||||||
start_percent: float, prev_ad_keyframes=None,
|
start_percent: float, prev_ad_keyframes=None,
|
||||||
scale_multival: Union[float, torch.Tensor]=None, effect_multival: Union[float, torch.Tensor]=None,
|
scale_multival: Union[float, torch.Tensor]=None, effect_multival: Union[float, torch.Tensor]=None,
|
||||||
per_block_replace: AllPerBlocks=None,
|
per_block_replace: AllPerBlocks=None,
|
||||||
@@ -229,4 +239,4 @@ class ADKeyframeNode:
|
|||||||
cameractrl_multival=cameractrl_multival, pia_input=pia_input,
|
cameractrl_multival=cameractrl_multival, pia_input=pia_input,
|
||||||
inherit_missing=inherit_missing, guarantee_steps=guarantee_steps)
|
inherit_missing=inherit_missing, guarantee_steps=guarantee_steps)
|
||||||
prev_ad_keyframes.add(keyframe)
|
prev_ad_keyframes.add(keyframe)
|
||||||
return (prev_ad_keyframes,)
|
return io.NodeOutput(prev_ad_keyframes,)
|
||||||
|
|||||||
+19
-16
@@ -1,3 +1,4 @@
|
|||||||
|
from comfy_api.latest import io
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
import folder_paths
|
import folder_paths
|
||||||
@@ -9,24 +10,26 @@ from .utils_model import get_available_motion_loras, get_motion_lora_path
|
|||||||
from .motion_lora import MotionLoraInfo, MotionLoraList
|
from .motion_lora import MotionLoraInfo, MotionLoraList
|
||||||
|
|
||||||
|
|
||||||
class AnimateDiffLoraLoader:
|
class AnimateDiffLoraLoader(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {
|
return io.Schema(
|
||||||
"required": {
|
node_id='ADE_AnimateDiffLoRALoader',
|
||||||
"name": (get_available_motion_loras(),),
|
display_name='Load AnimateDiff LoRA 🎭🅐🅓',
|
||||||
"strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}),
|
category='Animate Diff 🎭🅐🅓',
|
||||||
},
|
inputs=[
|
||||||
"optional": {
|
io.Combo.Input('name', options=get_available_motion_loras()),
|
||||||
"prev_motion_lora": ("MOTION_LORA",),
|
io.Float.Input('strength', default=1.0, max=10.0, min=0.0, step=0.001),
|
||||||
},
|
io.Custom("MOTION_LORA").Input('prev_motion_lora', optional=True),
|
||||||
}
|
],
|
||||||
|
outputs=[
|
||||||
|
io.Custom("MOTION_LORA").Output('MOTION_LORA'),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
RETURN_TYPES = ("MOTION_LORA",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓"
|
|
||||||
FUNCTION = "load_motion_lora"
|
|
||||||
|
|
||||||
def load_motion_lora(self, name: str, strength: float, prev_motion_lora: MotionLoraList=None, lora_name: str=None):
|
@classmethod
|
||||||
|
def execute(cls, name: str, strength: float, prev_motion_lora: MotionLoraList=None, lora_name: str=None):
|
||||||
if prev_motion_lora is None:
|
if prev_motion_lora is None:
|
||||||
prev_motion_lora = MotionLoraList()
|
prev_motion_lora = MotionLoraList()
|
||||||
else:
|
else:
|
||||||
@@ -41,4 +44,4 @@ class AnimateDiffLoraLoader:
|
|||||||
lora_info = MotionLoraInfo(name=name, strength=strength)
|
lora_info = MotionLoraInfo(name=name, strength=strength)
|
||||||
prev_motion_lora.add_lora(lora_info)
|
prev_motion_lora.add_lora(lora_info)
|
||||||
|
|
||||||
return (prev_motion_lora,)
|
return io.NodeOutput(prev_motion_lora,)
|
||||||
|
|||||||
+62
-101
@@ -4,6 +4,8 @@ from typing import Union
|
|||||||
import torch
|
import torch
|
||||||
from torch import Tensor
|
from torch import Tensor
|
||||||
|
|
||||||
|
from comfy_api.latest import io
|
||||||
|
|
||||||
from .utils_motion import create_multival_combo, linear_conversion, normalize_min_max, extend_to_batch_size, extend_list_to_batch_size
|
from .utils_motion import create_multival_combo, linear_conversion, normalize_min_max, extend_to_batch_size, extend_list_to_batch_size
|
||||||
|
|
||||||
|
|
||||||
@@ -13,45 +15,33 @@ class ScaleType:
|
|||||||
LIST = [ABSOLUTE, RELATIVE]
|
LIST = [ABSOLUTE, RELATIVE]
|
||||||
|
|
||||||
|
|
||||||
class MultivalDynamicNode:
|
class MultivalDynamicNode(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {
|
return io.Schema(
|
||||||
"required": {
|
node_id='ADE_MultivalDynamic',
|
||||||
"float_val": ("FLOAT", {"default": 1.0, "min": 0.0, "step": 0.001},),
|
display_name='Multival 🎭🅐🅓',
|
||||||
},
|
category='Animate Diff 🎭🅐🅓/multival',
|
||||||
"optional": {
|
inputs=[io.Float.Input('float_val', default=1.0, min=0.0, step=0.001), io.Mask.Input('mask_optional', optional=True)],
|
||||||
"mask_optional": ("MASK",),
|
outputs=[io.Custom('MULTIVAL').Output('MULTIVAL')]
|
||||||
},
|
)
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("MULTIVAL",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/multival"
|
|
||||||
FUNCTION = "create_multival"
|
|
||||||
|
|
||||||
def create_multival(self, float_val: Union[float, list[float]]=1.0, mask_optional: Tensor=None):
|
|
||||||
return (create_multival_combo(float_val=float_val, mask_optional=mask_optional),)
|
|
||||||
|
|
||||||
|
|
||||||
class MultivalScaledMaskNode:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def execute(cls, float_val: Union[float, list[float]]=1.0, mask_optional: Tensor=None):
|
||||||
return {
|
return io.NodeOutput(create_multival_combo(float_val=float_val, mask_optional=mask_optional))
|
||||||
"required": {
|
|
||||||
"min_float_val": ("FLOAT", {"default": 0.0, "min": 0.0, "step": 0.001}),
|
|
||||||
"max_float_val": ("FLOAT", {"default": 1.0, "min": 0.0, "step": 0.001}),
|
|
||||||
"mask": ("MASK",),
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"scaling": (ScaleType.LIST,),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("MULTIVAL",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/multival"
|
|
||||||
FUNCTION = "create_multival"
|
|
||||||
|
|
||||||
def create_multival(self, min_float_val: float, max_float_val: float, mask: Tensor, scaling: str=ScaleType.ABSOLUTE):
|
class MultivalScaledMaskNode(io.ComfyNode):
|
||||||
|
@classmethod
|
||||||
|
def define_schema(cls) -> io.Schema:
|
||||||
|
return io.Schema(
|
||||||
|
node_id='ADE_MultivalScaledMask',
|
||||||
|
display_name='Multival Scaled Mask 🎭🅐🅓',
|
||||||
|
category='Animate Diff 🎭🅐🅓/multival',
|
||||||
|
inputs=[io.Float.Input('min_float_val', default=0.0, min=0.0, step=0.001), io.Float.Input('max_float_val', default=1.0, min=0.0, step=0.001), io.Mask.Input('mask'), io.Combo.Input('scaling', options=['absolute', 'relative'] , optional=True)],
|
||||||
|
outputs=[io.Custom('MULTIVAL').Output('MULTIVAL')]
|
||||||
|
)
|
||||||
|
@classmethod
|
||||||
|
def execute(cls, min_float_val: float, max_float_val: float, mask: Tensor, scaling: str=ScaleType.ABSOLUTE):
|
||||||
lengths = [mask.shape[0]]
|
lengths = [mask.shape[0]]
|
||||||
iterable_inputs = [False, False]
|
iterable_inputs = [False, False]
|
||||||
val_inputs = [min_float_val, max_float_val]
|
val_inputs = [min_float_val, max_float_val]
|
||||||
@@ -77,84 +67,55 @@ class MultivalScaledMaskNode:
|
|||||||
mask = normalize_min_max(mask.clone(), new_min=min_float_val, new_max=max_float_val)
|
mask = normalize_min_max(mask.clone(), new_min=min_float_val, new_max=max_float_val)
|
||||||
else:
|
else:
|
||||||
raise ValueError(f"scaling '{scaling}' not recognized.")
|
raise ValueError(f"scaling '{scaling}' not recognized.")
|
||||||
return MultivalDynamicNode.create_multival(self, mask_optional=mask)
|
return io.NodeOutput(*MultivalDynamicNode.execute(mask_optional=mask).args)
|
||||||
|
|
||||||
|
|
||||||
class MultivalDynamicFloatInputNode:
|
class MultivalDynamicFloatInputNode(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {
|
return io.Schema(
|
||||||
"required": {
|
node_id='ADE_MultivalDynamicFloatInput',
|
||||||
"float_val": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001, "forceInput": True},),
|
display_name='Multival [Float List] 🎭🅐🅓',
|
||||||
},
|
category='Animate Diff 🎭🅐🅓/multival',
|
||||||
"optional": {
|
inputs=[io.Float.Input('float_val', default=1.0, force_input=True, max=10.0, min=0.0, step=0.001), io.Mask.Input('mask_optional', optional=True)],
|
||||||
"mask_optional": ("MASK",),
|
outputs=[io.Custom('MULTIVAL').Output('MULTIVAL')]
|
||||||
},
|
)
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("MULTIVAL",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/multival"
|
|
||||||
FUNCTION = "create_multival"
|
|
||||||
|
|
||||||
def create_multival(self, float_val: Union[float, list[float]]=None, mask_optional: Tensor=None):
|
|
||||||
return MultivalDynamicNode.create_multival(self, float_val=float_val, mask_optional=mask_optional)
|
|
||||||
|
|
||||||
|
|
||||||
class MultivalDynamicFloatsNode:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def execute(cls, float_val: Union[float, list[float]]=None, mask_optional: Tensor=None):
|
||||||
return {
|
return io.NodeOutput(*MultivalDynamicNode.execute(float_val=float_val, mask_optional=mask_optional).args)
|
||||||
"required": {
|
|
||||||
"floats": ("FLOATS", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001},),
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"mask_optional": ("MASK",),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("MULTIVAL",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/multival"
|
|
||||||
FUNCTION = "create_multival"
|
|
||||||
|
|
||||||
def create_multival(self, floats: Union[float, list[float]]=None, mask_optional: Tensor=None):
|
|
||||||
return MultivalDynamicNode.create_multival(self, float_val=floats, mask_optional=mask_optional)
|
|
||||||
|
|
||||||
|
|
||||||
class MultivalFloatNode:
|
class MultivalDynamicFloatsNode(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {
|
return io.Schema(
|
||||||
"required": {
|
node_id='ADE_MultivalDynamicFloats',
|
||||||
"float_val": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001},),
|
display_name='Multival [Floats] 🎭🅐🅓',
|
||||||
},
|
category='Animate Diff 🎭🅐🅓/multival',
|
||||||
}
|
inputs=[io.Custom('FLOATS').Input('floats', extra_dict={'default': 1.0, 'min': 0.0, 'max': 10.0, 'step': 0.001}), io.Mask.Input('mask_optional', optional=True)],
|
||||||
|
outputs=[io.Custom('MULTIVAL').Output('MULTIVAL')]
|
||||||
RETURN_TYPES = ("MULTIVAL",)
|
)
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/multival"
|
|
||||||
FUNCTION = "create_multival"
|
|
||||||
|
|
||||||
def create_multival(self, float_val: Union[float, list[float]]=None):
|
|
||||||
return MultivalDynamicNode.create_multival(self, float_val=float_val)
|
|
||||||
|
|
||||||
|
|
||||||
class MultivalConvertToMaskNode:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def execute(cls, floats: Union[float, list[float]]=None, mask_optional: Tensor=None):
|
||||||
return {
|
return io.NodeOutput(*MultivalDynamicNode.execute(float_val=floats, mask_optional=mask_optional).args)
|
||||||
"required": {
|
|
||||||
"multival": ("MULTIVAL",),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("MASK",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/multival"
|
|
||||||
FUNCTION = "convert_multival_to_mask"
|
|
||||||
|
|
||||||
def convert_multival_to_mask(self, multival: Union[float, Tensor]):
|
class MultivalConvertToMaskNode(io.ComfyNode):
|
||||||
|
@classmethod
|
||||||
|
def define_schema(cls) -> io.Schema:
|
||||||
|
return io.Schema(
|
||||||
|
node_id='ADE_MultivalConvertToMask',
|
||||||
|
display_name='Multival to Mask 🎭🅐🅓',
|
||||||
|
category='Animate Diff 🎭🅐🅓/multival',
|
||||||
|
inputs=[io.Custom('MULTIVAL').Input('multival')],
|
||||||
|
outputs=[io.Mask.Output('MASK')]
|
||||||
|
)
|
||||||
|
@classmethod
|
||||||
|
def execute(cls, multival: Union[float, Tensor]):
|
||||||
# if already tensor, assume is a valid mask
|
# if already tensor, assume is a valid mask
|
||||||
if type(multival) == Tensor:
|
if type(multival) == Tensor:
|
||||||
return (multival,)
|
return io.NodeOutput(multival)
|
||||||
# otherwise, make a single 1x1 mask with the proper value
|
# otherwise, make a single 1x1 mask with the proper value
|
||||||
shape = (1,1,1)
|
shape = (1,1,1)
|
||||||
converted_multival = torch.ones(shape) * multival
|
converted_multival = torch.ones(shape) * multival
|
||||||
return (converted_multival,)
|
return io.NodeOutput(converted_multival)
|
||||||
|
|||||||
+114
-204
@@ -1,6 +1,8 @@
|
|||||||
from typing import Union
|
from typing import Union
|
||||||
from torch import Tensor
|
from torch import Tensor
|
||||||
|
|
||||||
|
from comfy_api.latest import io
|
||||||
|
|
||||||
from .motion_module_ad import BlockType
|
from .motion_module_ad import BlockType
|
||||||
from .utils_model import ModelTypeSD
|
from .utils_model import ModelTypeSD
|
||||||
from .utils_motion import AllPerBlocks, PerBlock, PerBlockId, extend_list_to_batch_size
|
from .utils_motion import AllPerBlocks, PerBlock, PerBlockId, extend_list_to_batch_size
|
||||||
@@ -26,80 +28,63 @@ class ADBlockHolder:
|
|||||||
return not has_anything
|
return not has_anything
|
||||||
|
|
||||||
|
|
||||||
class ADBlockComboNode:
|
class ADBlockComboNode(io.ComfyNode):
|
||||||
|
@classmethod
|
||||||
|
def define_schema(cls) -> io.Schema:
|
||||||
|
return io.Schema(
|
||||||
|
node_id='ADE_ADBlockCombo',
|
||||||
|
display_name='AD Block 🎭🅐🅓',
|
||||||
|
category='Animate Diff 🎭🅐🅓/per block',
|
||||||
|
inputs=[io.Custom('MULTIVAL').Input('effect', optional=True), io.Custom('MULTIVAL').Input('scale', optional=True)],
|
||||||
|
outputs=[io.Custom('AD_BLOCK').Output('AD_BLOCK')]
|
||||||
|
)
|
||||||
NodeID = 'ADE_ADBlockCombo'
|
NodeID = 'ADE_ADBlockCombo'
|
||||||
NodeName = 'AD Block 🎭🅐🅓'
|
NodeName = 'AD Block 🎭🅐🅓'
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def execute(cls, effect: Union[float, Tensor, None]=None, scale: Union[float, Tensor, None]=None):
|
||||||
return {
|
|
||||||
"required": {
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"effect": ("MULTIVAL",),
|
|
||||||
"scale": ("MULTIVAL",),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("AD_BLOCK",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/per block"
|
|
||||||
FUNCTION = "block_control"
|
|
||||||
|
|
||||||
def block_control(self, effect: Union[float, Tensor, None]=None, scale: Union[float, Tensor, None]=None):
|
|
||||||
scales = [scale, scale]
|
scales = [scale, scale]
|
||||||
block = ADBlockHolder(effect=effect, scales=scales)
|
block = ADBlockHolder(effect=effect, scales=scales)
|
||||||
if block.is_empty():
|
if block.is_empty():
|
||||||
block = None
|
block = None
|
||||||
return (block,)
|
return io.NodeOutput(block)
|
||||||
|
|
||||||
|
|
||||||
class ADBlockIndivNode:
|
class ADBlockIndivNode(io.ComfyNode):
|
||||||
|
@classmethod
|
||||||
|
def define_schema(cls) -> io.Schema:
|
||||||
|
return io.Schema(
|
||||||
|
node_id='ADE_ADBlockIndiv',
|
||||||
|
display_name='AD Block+ 🎭🅐🅓',
|
||||||
|
category='Animate Diff 🎭🅐🅓/per block',
|
||||||
|
inputs=[io.Custom('MULTIVAL').Input('effect', optional=True), io.Custom('MULTIVAL').Input('scale_0', optional=True), io.Custom('MULTIVAL').Input('scale_1', optional=True)],
|
||||||
|
outputs=[io.Custom('AD_BLOCK').Output('AD_BLOCK')]
|
||||||
|
)
|
||||||
NodeID = 'ADE_ADBlockIndiv'
|
NodeID = 'ADE_ADBlockIndiv'
|
||||||
NodeName = 'AD Block+ 🎭🅐🅓'
|
NodeName = 'AD Block+ 🎭🅐🅓'
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def execute(cls, effect: Union[float, Tensor, None]=None,
|
||||||
return {
|
|
||||||
"required": {
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"effect": ("MULTIVAL",),
|
|
||||||
"scale_0": ("MULTIVAL",),
|
|
||||||
"scale_1": ("MULTIVAL",),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("AD_BLOCK",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/per block"
|
|
||||||
FUNCTION = "block_control"
|
|
||||||
|
|
||||||
def block_control(self, effect: Union[float, Tensor, None]=None,
|
|
||||||
scale_0: Union[float, Tensor, None]=None, scale_1: Union[float, Tensor, None]=None):
|
scale_0: Union[float, Tensor, None]=None, scale_1: Union[float, Tensor, None]=None):
|
||||||
scales = [scale_0, scale_1]
|
scales = [scale_0, scale_1]
|
||||||
block = ADBlockHolder(effect=effect, scales=scales)
|
block = ADBlockHolder(effect=effect, scales=scales)
|
||||||
if block.is_empty():
|
if block.is_empty():
|
||||||
block = None
|
block = None
|
||||||
return (block,)
|
return io.NodeOutput(block)
|
||||||
|
|
||||||
|
|
||||||
class PerBlockHighLevelNode:
|
class PerBlockHighLevelNode(io.ComfyNode):
|
||||||
|
@classmethod
|
||||||
|
def define_schema(cls) -> io.Schema:
|
||||||
|
return io.Schema(
|
||||||
|
node_id='ADE_PerBlockHighLevel',
|
||||||
|
display_name='AD Per Block 🎭🅐🅓',
|
||||||
|
category='Animate Diff 🎭🅐🅓/per block',
|
||||||
|
inputs=[io.Custom('AD_BLOCK').Input('down', optional=True), io.Custom('AD_BLOCK').Input('mid', optional=True), io.Custom('AD_BLOCK').Input('up', optional=True)],
|
||||||
|
outputs=[io.Custom('PER_BLOCK').Output('PER_BLOCK')]
|
||||||
|
)
|
||||||
NodeID = 'ADE_PerBlockHighLevel'
|
NodeID = 'ADE_PerBlockHighLevel'
|
||||||
NodeName = 'AD Per Block 🎭🅐🅓'
|
NodeName = 'AD Per Block 🎭🅐🅓'
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def execute(cls,
|
||||||
return {
|
|
||||||
"required": {
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"down": ("AD_BLOCK",),
|
|
||||||
"mid": ("AD_BLOCK",),
|
|
||||||
"up": ("AD_BLOCK",),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("PER_BLOCK",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/per block"
|
|
||||||
FUNCTION = "create_per_block"
|
|
||||||
|
|
||||||
def create_per_block(self,
|
|
||||||
down: Union[ADBlockHolder, None]=None,
|
down: Union[ADBlockHolder, None]=None,
|
||||||
mid: Union[ADBlockHolder, None]=None,
|
mid: Union[ADBlockHolder, None]=None,
|
||||||
up: Union[ADBlockHolder, None]=None):
|
up: Union[ADBlockHolder, None]=None):
|
||||||
@@ -114,35 +99,23 @@ class PerBlockHighLevelNode:
|
|||||||
blocks.append(PerBlock(id=id, effect=block.effect, scales=block.scales))
|
blocks.append(PerBlock(id=id, effect=block.effect, scales=block.scales))
|
||||||
if len(blocks) == 0:
|
if len(blocks) == 0:
|
||||||
blocks = None
|
blocks = None
|
||||||
return (AllPerBlocks(blocks),)
|
return io.NodeOutput(AllPerBlocks(blocks))
|
||||||
|
|
||||||
|
|
||||||
class PerBlock_SD15_MidLevelNode:
|
class PerBlock_SD15_MidLevelNode(io.ComfyNode):
|
||||||
|
@classmethod
|
||||||
|
def define_schema(cls) -> io.Schema:
|
||||||
|
return io.Schema(
|
||||||
|
node_id='ADE_PerBlock_SD15_MidLevel',
|
||||||
|
display_name='AD Per Block+ (SD1.5) 🎭🅐🅓',
|
||||||
|
category='Animate Diff 🎭🅐🅓/per block',
|
||||||
|
inputs=[io.Custom('AD_BLOCK').Input('down_0', optional=True), io.Custom('AD_BLOCK').Input('down_1', optional=True), io.Custom('AD_BLOCK').Input('down_2', optional=True), io.Custom('AD_BLOCK').Input('down_3', optional=True), io.Custom('AD_BLOCK').Input('mid', optional=True), io.Custom('AD_BLOCK').Input('up_0', optional=True), io.Custom('AD_BLOCK').Input('up_1', optional=True), io.Custom('AD_BLOCK').Input('up_2', optional=True), io.Custom('AD_BLOCK').Input('up_3', optional=True)],
|
||||||
|
outputs=[io.Custom('PER_BLOCK').Output('PER_BLOCK')]
|
||||||
|
)
|
||||||
NodeID = 'ADE_PerBlock_SD15_MidLevel'
|
NodeID = 'ADE_PerBlock_SD15_MidLevel'
|
||||||
NodeName = 'AD Per Block+ (SD1.5) 🎭🅐🅓'
|
NodeName = 'AD Per Block+ (SD1.5) 🎭🅐🅓'
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def execute(cls,
|
||||||
return {
|
|
||||||
"required": {
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"down_0": ("AD_BLOCK",),
|
|
||||||
"down_1": ("AD_BLOCK",),
|
|
||||||
"down_2": ("AD_BLOCK",),
|
|
||||||
"down_3": ("AD_BLOCK",),
|
|
||||||
"mid": ("AD_BLOCK",),
|
|
||||||
"up_0": ("AD_BLOCK",),
|
|
||||||
"up_1": ("AD_BLOCK",),
|
|
||||||
"up_2": ("AD_BLOCK",),
|
|
||||||
"up_3": ("AD_BLOCK",),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("PER_BLOCK",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/per block"
|
|
||||||
FUNCTION = "create_per_block"
|
|
||||||
|
|
||||||
def create_per_block(self,
|
|
||||||
down_0: Union[ADBlockHolder, None]=None,
|
down_0: Union[ADBlockHolder, None]=None,
|
||||||
down_1: Union[ADBlockHolder, None]=None,
|
down_1: Union[ADBlockHolder, None]=None,
|
||||||
down_2: Union[ADBlockHolder, None]=None,
|
down_2: Union[ADBlockHolder, None]=None,
|
||||||
@@ -169,47 +142,23 @@ class PerBlock_SD15_MidLevelNode:
|
|||||||
blocks.append(PerBlock(id=id, effect=block.effect, scales=block.scales))
|
blocks.append(PerBlock(id=id, effect=block.effect, scales=block.scales))
|
||||||
if len(blocks) == 0:
|
if len(blocks) == 0:
|
||||||
blocks = None
|
blocks = None
|
||||||
return (AllPerBlocks(blocks, ModelTypeSD.SD1_5),)
|
return io.NodeOutput(AllPerBlocks(blocks, ModelTypeSD.SD1_5))
|
||||||
|
|
||||||
|
|
||||||
class PerBlock_SD15_LowLevelNode:
|
class PerBlock_SD15_LowLevelNode(io.ComfyNode):
|
||||||
|
@classmethod
|
||||||
|
def define_schema(cls) -> io.Schema:
|
||||||
|
return io.Schema(
|
||||||
|
node_id='ADE_PerBlock_SD15_LowLevel',
|
||||||
|
display_name='AD Per Block++ (SD1.5) 🎭🅐🅓',
|
||||||
|
category='Animate Diff 🎭🅐🅓/per block',
|
||||||
|
inputs=[io.Custom('AD_BLOCK').Input('down_0__0', optional=True), io.Custom('AD_BLOCK').Input('down_0__1', optional=True), io.Custom('AD_BLOCK').Input('down_1__0', optional=True), io.Custom('AD_BLOCK').Input('down_1__1', optional=True), io.Custom('AD_BLOCK').Input('down_2__0', optional=True), io.Custom('AD_BLOCK').Input('down_2__1', optional=True), io.Custom('AD_BLOCK').Input('down_3__0', optional=True), io.Custom('AD_BLOCK').Input('down_3__1', optional=True), io.Custom('AD_BLOCK').Input('mid', optional=True), io.Custom('AD_BLOCK').Input('up_0__0', optional=True), io.Custom('AD_BLOCK').Input('up_0__1', optional=True), io.Custom('AD_BLOCK').Input('up_0__2', optional=True), io.Custom('AD_BLOCK').Input('up_1__0', optional=True), io.Custom('AD_BLOCK').Input('up_1__1', optional=True), io.Custom('AD_BLOCK').Input('up_1__2', optional=True), io.Custom('AD_BLOCK').Input('up_2__0', optional=True), io.Custom('AD_BLOCK').Input('up_2__1', optional=True), io.Custom('AD_BLOCK').Input('up_2__2', optional=True), io.Custom('AD_BLOCK').Input('up_3__0', optional=True), io.Custom('AD_BLOCK').Input('up_3__1', optional=True), io.Custom('AD_BLOCK').Input('up_3__2', optional=True)],
|
||||||
|
outputs=[io.Custom('PER_BLOCK').Output('PER_BLOCK')]
|
||||||
|
)
|
||||||
NodeID = 'ADE_PerBlock_SD15_LowLevel'
|
NodeID = 'ADE_PerBlock_SD15_LowLevel'
|
||||||
NodeName = 'AD Per Block++ (SD1.5) 🎭🅐🅓'
|
NodeName = 'AD Per Block++ (SD1.5) 🎭🅐🅓'
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def execute(cls,
|
||||||
return {
|
|
||||||
"required": {
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"down_0__0": ("AD_BLOCK",),
|
|
||||||
"down_0__1": ("AD_BLOCK",),
|
|
||||||
"down_1__0": ("AD_BLOCK",),
|
|
||||||
"down_1__1": ("AD_BLOCK",),
|
|
||||||
"down_2__0": ("AD_BLOCK",),
|
|
||||||
"down_2__1": ("AD_BLOCK",),
|
|
||||||
"down_3__0": ("AD_BLOCK",),
|
|
||||||
"down_3__1": ("AD_BLOCK",),
|
|
||||||
"mid": ("AD_BLOCK",),
|
|
||||||
"up_0__0": ("AD_BLOCK",),
|
|
||||||
"up_0__1": ("AD_BLOCK",),
|
|
||||||
"up_0__2": ("AD_BLOCK",),
|
|
||||||
"up_1__0": ("AD_BLOCK",),
|
|
||||||
"up_1__1": ("AD_BLOCK",),
|
|
||||||
"up_1__2": ("AD_BLOCK",),
|
|
||||||
"up_2__0": ("AD_BLOCK",),
|
|
||||||
"up_2__1": ("AD_BLOCK",),
|
|
||||||
"up_2__2": ("AD_BLOCK",),
|
|
||||||
"up_3__0": ("AD_BLOCK",),
|
|
||||||
"up_3__1": ("AD_BLOCK",),
|
|
||||||
"up_3__2": ("AD_BLOCK",),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("PER_BLOCK",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/per block"
|
|
||||||
FUNCTION = "create_per_block"
|
|
||||||
|
|
||||||
def create_per_block(self,
|
|
||||||
down_0__0: Union[ADBlockHolder, None]=None,
|
down_0__0: Union[ADBlockHolder, None]=None,
|
||||||
down_0__1: Union[ADBlockHolder, None]=None,
|
down_0__1: Union[ADBlockHolder, None]=None,
|
||||||
down_1__0: Union[ADBlockHolder, None]=None,
|
down_1__0: Union[ADBlockHolder, None]=None,
|
||||||
@@ -260,33 +209,28 @@ class PerBlock_SD15_LowLevelNode:
|
|||||||
blocks.append(PerBlock(id=id, effect=block.effect, scales=block.scales))
|
blocks.append(PerBlock(id=id, effect=block.effect, scales=block.scales))
|
||||||
if len(blocks) == 0:
|
if len(blocks) == 0:
|
||||||
blocks = None
|
blocks = None
|
||||||
return (AllPerBlocks(blocks, ModelTypeSD.SD1_5),)
|
return io.NodeOutput(AllPerBlocks(blocks, ModelTypeSD.SD1_5))
|
||||||
|
|
||||||
|
|
||||||
class PerBlock_SD15_FromFloatsNode:
|
class PerBlock_SD15_FromFloatsNode(io.ComfyNode):
|
||||||
|
@classmethod
|
||||||
|
def define_schema(cls) -> io.Schema:
|
||||||
|
return io.Schema(
|
||||||
|
node_id='ADE_PerBlock_SD15_FromFloats',
|
||||||
|
display_name='AD Per Block Floats (SD1.5) 🎭🅐🅓',
|
||||||
|
category='Animate Diff 🎭🅐🅓/per block',
|
||||||
|
inputs=[io.Custom('FLOATS').Input('effect_21_floats', optional=True), io.Custom('FLOATS').Input('scale_21_floats', optional=True)],
|
||||||
|
outputs=[io.Custom('PER_BLOCK').Output('PER_BLOCK')],
|
||||||
|
description='Use Floats from Value Schedules to select SD1.5 effect/scale values for blocks.'
|
||||||
|
)
|
||||||
NodeID = 'ADE_PerBlock_SD15_FromFloats'
|
NodeID = 'ADE_PerBlock_SD15_FromFloats'
|
||||||
NodeName = 'AD Per Block Floats (SD1.5) 🎭🅐🅓'
|
NodeName = 'AD Per Block Floats (SD1.5) 🎭🅐🅓'
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def execute(cls,
|
||||||
return {
|
|
||||||
"required": {
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"effect_21_floats": ("FLOATS",),
|
|
||||||
"scale_21_floats": ("FLOATS",),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("PER_BLOCK",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/per block"
|
|
||||||
FUNCTION = "create_per_block"
|
|
||||||
DESCRIPTION = 'Use Floats from Value Schedules to select SD1.5 effect/scale values for blocks.'
|
|
||||||
|
|
||||||
def create_per_block(self,
|
|
||||||
effect_21_floats: Union[list[float], None]=None,
|
effect_21_floats: Union[list[float], None]=None,
|
||||||
scale_21_floats: Union[list[float], None]=None):
|
scale_21_floats: Union[list[float], None]=None):
|
||||||
if effect_21_floats is None and scale_21_floats is None:
|
if effect_21_floats is None and scale_21_floats is None:
|
||||||
return (AllPerBlocks(None, ModelTypeSD.SD1_5),)
|
return io.NodeOutput(AllPerBlocks(None, ModelTypeSD.SD1_5))
|
||||||
# SD1.5 has 21 blocks
|
# SD1.5 has 21 blocks
|
||||||
block_total = 21
|
block_total = 21
|
||||||
holders = [ADBlockHolder() for _ in range(block_total)]
|
holders = [ADBlockHolder() for _ in range(block_total)]
|
||||||
@@ -298,33 +242,23 @@ class PerBlock_SD15_FromFloatsNode:
|
|||||||
scale_21_floats = extend_list_to_batch_size(scale_21_floats, block_total)
|
scale_21_floats = extend_list_to_batch_size(scale_21_floats, block_total)
|
||||||
for scale, holder in zip(scale_21_floats, holders):
|
for scale, holder in zip(scale_21_floats, holders):
|
||||||
holder.scales = [scale, scale]
|
holder.scales = [scale, scale]
|
||||||
return PerBlock_SD15_LowLevelNode.create_per_block(self, *holders)
|
return PerBlock_SD15_LowLevelNode.execute(*holders)
|
||||||
|
|
||||||
|
|
||||||
class PerBlock_SDXL_MidLevelNode:
|
class PerBlock_SDXL_MidLevelNode(io.ComfyNode):
|
||||||
|
@classmethod
|
||||||
|
def define_schema(cls) -> io.Schema:
|
||||||
|
return io.Schema(
|
||||||
|
node_id='ADE_PerBlock_SDXL_MidLevel',
|
||||||
|
display_name='AD Per Block+ (SDXL) 🎭🅐🅓',
|
||||||
|
category='Animate Diff 🎭🅐🅓/per block',
|
||||||
|
inputs=[io.Custom('AD_BLOCK').Input('down_0', optional=True), io.Custom('AD_BLOCK').Input('down_1', optional=True), io.Custom('AD_BLOCK').Input('down_2', optional=True), io.Custom('AD_BLOCK').Input('mid', optional=True), io.Custom('AD_BLOCK').Input('up_0', optional=True), io.Custom('AD_BLOCK').Input('up_1', optional=True), io.Custom('AD_BLOCK').Input('up_2', optional=True)],
|
||||||
|
outputs=[io.Custom('PER_BLOCK').Output('PER_BLOCK')]
|
||||||
|
)
|
||||||
NodeID = 'ADE_PerBlock_SDXL_MidLevel'
|
NodeID = 'ADE_PerBlock_SDXL_MidLevel'
|
||||||
NodeName = 'AD Per Block+ (SDXL) 🎭🅐🅓'
|
NodeName = 'AD Per Block+ (SDXL) 🎭🅐🅓'
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def execute(cls,
|
||||||
return {
|
|
||||||
"required": {
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"down_0": ("AD_BLOCK",),
|
|
||||||
"down_1": ("AD_BLOCK",),
|
|
||||||
"down_2": ("AD_BLOCK",),
|
|
||||||
"mid": ("AD_BLOCK",),
|
|
||||||
"up_0": ("AD_BLOCK",),
|
|
||||||
"up_1": ("AD_BLOCK",),
|
|
||||||
"up_2": ("AD_BLOCK",),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("PER_BLOCK",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/per block"
|
|
||||||
FUNCTION = "create_per_block"
|
|
||||||
|
|
||||||
def create_per_block(self,
|
|
||||||
down_0: Union[ADBlockHolder, None]=None,
|
down_0: Union[ADBlockHolder, None]=None,
|
||||||
down_1: Union[ADBlockHolder, None]=None,
|
down_1: Union[ADBlockHolder, None]=None,
|
||||||
down_2: Union[ADBlockHolder, None]=None,
|
down_2: Union[ADBlockHolder, None]=None,
|
||||||
@@ -347,42 +281,23 @@ class PerBlock_SDXL_MidLevelNode:
|
|||||||
blocks.append(PerBlock(id=id, effect=block.effect, scales=block.scales))
|
blocks.append(PerBlock(id=id, effect=block.effect, scales=block.scales))
|
||||||
if len(blocks) == 0:
|
if len(blocks) == 0:
|
||||||
blocks = None
|
blocks = None
|
||||||
return (AllPerBlocks(blocks, ModelTypeSD.SDXL),)
|
return io.NodeOutput(AllPerBlocks(blocks, ModelTypeSD.SDXL))
|
||||||
|
|
||||||
|
|
||||||
class PerBlock_SDXL_LowLevelNode:
|
class PerBlock_SDXL_LowLevelNode(io.ComfyNode):
|
||||||
|
@classmethod
|
||||||
|
def define_schema(cls) -> io.Schema:
|
||||||
|
return io.Schema(
|
||||||
|
node_id='ADE_PerBlock_SDXL_LowLevel',
|
||||||
|
display_name='AD Per Block++ (SDXL) 🎭🅐🅓',
|
||||||
|
category='Animate Diff 🎭🅐🅓/per block',
|
||||||
|
inputs=[io.Custom('AD_BLOCK').Input('down_0__0', optional=True), io.Custom('AD_BLOCK').Input('down_0__1', optional=True), io.Custom('AD_BLOCK').Input('down_1__0', optional=True), io.Custom('AD_BLOCK').Input('down_1__1', optional=True), io.Custom('AD_BLOCK').Input('down_2__0', optional=True), io.Custom('AD_BLOCK').Input('down_2__1', optional=True), io.Custom('AD_BLOCK').Input('mid', optional=True), io.Custom('AD_BLOCK').Input('up_0__0', optional=True), io.Custom('AD_BLOCK').Input('up_0__1', optional=True), io.Custom('AD_BLOCK').Input('up_0__2', optional=True), io.Custom('AD_BLOCK').Input('up_1__0', optional=True), io.Custom('AD_BLOCK').Input('up_1__1', optional=True), io.Custom('AD_BLOCK').Input('up_1__2', optional=True), io.Custom('AD_BLOCK').Input('up_2__0', optional=True), io.Custom('AD_BLOCK').Input('up_2__1', optional=True), io.Custom('AD_BLOCK').Input('up_2__2', optional=True)],
|
||||||
|
outputs=[io.Custom('PER_BLOCK').Output('PER_BLOCK')]
|
||||||
|
)
|
||||||
NodeID = 'ADE_PerBlock_SDXL_LowLevel'
|
NodeID = 'ADE_PerBlock_SDXL_LowLevel'
|
||||||
NodeName = 'AD Per Block++ (SDXL) 🎭🅐🅓'
|
NodeName = 'AD Per Block++ (SDXL) 🎭🅐🅓'
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def execute(cls,
|
||||||
return {
|
|
||||||
"required": {
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"down_0__0": ("AD_BLOCK",),
|
|
||||||
"down_0__1": ("AD_BLOCK",),
|
|
||||||
"down_1__0": ("AD_BLOCK",),
|
|
||||||
"down_1__1": ("AD_BLOCK",),
|
|
||||||
"down_2__0": ("AD_BLOCK",),
|
|
||||||
"down_2__1": ("AD_BLOCK",),
|
|
||||||
"mid": ("AD_BLOCK",),
|
|
||||||
"up_0__0": ("AD_BLOCK",),
|
|
||||||
"up_0__1": ("AD_BLOCK",),
|
|
||||||
"up_0__2": ("AD_BLOCK",),
|
|
||||||
"up_1__0": ("AD_BLOCK",),
|
|
||||||
"up_1__1": ("AD_BLOCK",),
|
|
||||||
"up_1__2": ("AD_BLOCK",),
|
|
||||||
"up_2__0": ("AD_BLOCK",),
|
|
||||||
"up_2__1": ("AD_BLOCK",),
|
|
||||||
"up_2__2": ("AD_BLOCK",),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("PER_BLOCK",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/per block"
|
|
||||||
FUNCTION = "create_per_block"
|
|
||||||
|
|
||||||
def create_per_block(self,
|
|
||||||
down_0__0: Union[ADBlockHolder, None]=None,
|
down_0__0: Union[ADBlockHolder, None]=None,
|
||||||
down_0__1: Union[ADBlockHolder, None]=None,
|
down_0__1: Union[ADBlockHolder, None]=None,
|
||||||
down_1__0: Union[ADBlockHolder, None]=None,
|
down_1__0: Union[ADBlockHolder, None]=None,
|
||||||
@@ -423,33 +338,28 @@ class PerBlock_SDXL_LowLevelNode:
|
|||||||
blocks.append(PerBlock(id=id, effect=block.effect, scales=block.scales))
|
blocks.append(PerBlock(id=id, effect=block.effect, scales=block.scales))
|
||||||
if len(blocks) == 0:
|
if len(blocks) == 0:
|
||||||
blocks = None
|
blocks = None
|
||||||
return (AllPerBlocks(blocks, ModelTypeSD.SDXL),)
|
return io.NodeOutput(AllPerBlocks(blocks, ModelTypeSD.SDXL))
|
||||||
|
|
||||||
|
|
||||||
class PerBlock_SDXL_FromFloatsNode:
|
class PerBlock_SDXL_FromFloatsNode(io.ComfyNode):
|
||||||
|
@classmethod
|
||||||
|
def define_schema(cls) -> io.Schema:
|
||||||
|
return io.Schema(
|
||||||
|
node_id='ADE_PerBlock_SDXL_FromFloats',
|
||||||
|
display_name='AD Per Block Floats (SDXL) 🎭🅐🅓',
|
||||||
|
category='Animate Diff 🎭🅐🅓/per block',
|
||||||
|
inputs=[io.Custom('FLOATS').Input('effect_16_floats', optional=True), io.Custom('FLOATS').Input('scale_16_floats', optional=True)],
|
||||||
|
outputs=[io.Custom('PER_BLOCK').Output('PER_BLOCK')],
|
||||||
|
description='Use Floats from Value Schedules to select SDXL effect/scale values for blocks.'
|
||||||
|
)
|
||||||
NodeID = 'ADE_PerBlock_SDXL_FromFloats'
|
NodeID = 'ADE_PerBlock_SDXL_FromFloats'
|
||||||
NodeName = 'AD Per Block Floats (SDXL) 🎭🅐🅓'
|
NodeName = 'AD Per Block Floats (SDXL) 🎭🅐🅓'
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def execute(cls,
|
||||||
return {
|
|
||||||
"required": {
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"effect_16_floats": ("FLOATS",),
|
|
||||||
"scale_16_floats": ("FLOATS",),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("PER_BLOCK",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/per block"
|
|
||||||
FUNCTION = "create_per_block"
|
|
||||||
DESCRIPTION = 'Use Floats from Value Schedules to select SDXL effect/scale values for blocks.'
|
|
||||||
|
|
||||||
def create_per_block(self,
|
|
||||||
effect_16_floats: Union[list[float], None]=None,
|
effect_16_floats: Union[list[float], None]=None,
|
||||||
scale_16_floats: Union[list[float], None]=None):
|
scale_16_floats: Union[list[float], None]=None):
|
||||||
if effect_16_floats is None and scale_16_floats is None:
|
if effect_16_floats is None and scale_16_floats is None:
|
||||||
return (AllPerBlocks(None, ModelTypeSD.SDXL),)
|
return io.NodeOutput(AllPerBlocks(None, ModelTypeSD.SDXL))
|
||||||
# SDXL has 16 blocks
|
# SDXL has 16 blocks
|
||||||
block_total = 16
|
block_total = 16
|
||||||
holders = [ADBlockHolder() for _ in range(block_total)]
|
holders = [ADBlockHolder() for _ in range(block_total)]
|
||||||
@@ -461,4 +371,4 @@ class PerBlock_SDXL_FromFloatsNode:
|
|||||||
scale_16_floats = extend_list_to_batch_size(scale_16_floats, block_total)
|
scale_16_floats = extend_list_to_batch_size(scale_16_floats, block_total)
|
||||||
for scale, holder in zip(scale_16_floats, holders):
|
for scale, holder in zip(scale_16_floats, holders):
|
||||||
holder.scales = [scale, scale]
|
holder.scales = [scale, scale]
|
||||||
return PerBlock_SDXL_LowLevelNode.create_per_block(self, *holders)
|
return PerBlock_SDXL_LowLevelNode.execute(*holders)
|
||||||
|
|||||||
+108
-100
@@ -1,3 +1,4 @@
|
|||||||
|
from comfy_api.latest import io
|
||||||
from typing import Union
|
from typing import Union
|
||||||
import torch
|
import torch
|
||||||
from torch import Tensor
|
from torch import Tensor
|
||||||
@@ -107,41 +108,43 @@ class InputPIA_PaperPresets(InputPIA):
|
|||||||
return mask
|
return mask
|
||||||
|
|
||||||
|
|
||||||
class ApplyAnimateDiffPIAModel:
|
class ApplyAnimateDiffPIAModel(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {
|
return io.Schema(
|
||||||
"required": {
|
node_id='ADE_ApplyAnimateDiffModelWithPIA',
|
||||||
"motion_model": ("MOTION_MODEL_ADE",),
|
display_name='Apply AnimateDiff-PIA Model 🎭🅐🅓②',
|
||||||
"image": ("IMAGE",),
|
category='Animate Diff 🎭🅐🅓/② Gen2 nodes ②/PIA',
|
||||||
"vae": ("VAE",),
|
inputs=[
|
||||||
"start_percent": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001}),
|
io.Custom("MOTION_MODEL_ADE").Input('motion_model'),
|
||||||
"end_percent": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.001}),
|
io.Image.Input('image'),
|
||||||
},
|
io.Vae.Input('vae'),
|
||||||
"optional": {
|
io.Float.Input('start_percent', default=0.0, max=1.0, min=0.0, step=0.001),
|
||||||
"pia_input": ("PIA_INPUT",),
|
io.Float.Input('end_percent', default=1.0, max=1.0, min=0.0, step=0.001),
|
||||||
"motion_lora": ("MOTION_LORA",),
|
io.Custom("PIA_INPUT").Input('pia_input', optional=True),
|
||||||
"scale_multival": ("MULTIVAL",),
|
io.Custom("MOTION_LORA").Input('motion_lora', optional=True),
|
||||||
"effect_multival": ("MULTIVAL",),
|
io.Custom("MULTIVAL").Input('scale_multival', optional=True),
|
||||||
"ad_keyframes": ("AD_KEYFRAMES",),
|
io.Custom("MULTIVAL").Input('effect_multival', optional=True),
|
||||||
"prev_m_models": ("M_MODELS",),
|
io.Custom("AD_KEYFRAMES").Input('ad_keyframes', optional=True),
|
||||||
"per_block": ("PER_BLOCK",),
|
io.Custom("M_MODELS").Input('prev_m_models', optional=True),
|
||||||
},
|
io.Custom("PER_BLOCK").Input('per_block', optional=True),
|
||||||
}
|
],
|
||||||
|
outputs=[
|
||||||
|
io.Custom("M_MODELS").Output('M_MODELS'),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
RETURN_TYPES = ("M_MODELS",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/② Gen2 nodes ②/PIA"
|
|
||||||
FUNCTION = "apply_motion_model"
|
|
||||||
|
|
||||||
def apply_motion_model(self, motion_model: MotionModelPatcher, image: Tensor, vae: VAE,
|
@classmethod
|
||||||
|
def execute(cls, motion_model: MotionModelPatcher, image: Tensor, vae: VAE,
|
||||||
start_percent: float=0.0, end_percent: float=1.0, pia_input: InputPIA=None,
|
start_percent: float=0.0, end_percent: float=1.0, pia_input: InputPIA=None,
|
||||||
motion_lora: MotionLoraList=None, ad_keyframes: ADKeyframeGroup=None,
|
motion_lora: MotionLoraList=None, ad_keyframes: ADKeyframeGroup=None,
|
||||||
scale_multival=None, effect_multival=None, ref_multival=None, per_block=None,
|
scale_multival=None, effect_multival=None, ref_multival=None, per_block=None,
|
||||||
prev_m_models: MotionModelGroup=None,):
|
prev_m_models: MotionModelGroup=None,):
|
||||||
new_m_models = ApplyAnimateDiffModelNode.apply_motion_model(self, motion_model, start_percent=start_percent, end_percent=end_percent,
|
new_m_models = ApplyAnimateDiffModelNode.execute( motion_model, start_percent=start_percent, end_percent=end_percent,
|
||||||
motion_lora=motion_lora, ad_keyframes=ad_keyframes,
|
motion_lora=motion_lora, ad_keyframes=ad_keyframes,
|
||||||
scale_multival=scale_multival, effect_multival=effect_multival, per_block=per_block,
|
scale_multival=scale_multival, effect_multival=effect_multival, per_block=per_block,
|
||||||
prev_m_models=prev_m_models)
|
prev_m_models=prev_m_models).args
|
||||||
# most recent added model will always be first in list;
|
# most recent added model will always be first in list;
|
||||||
curr_model = new_m_models[0].models[0]
|
curr_model = new_m_models[0].models[0]
|
||||||
# confirm that model is PIA
|
# confirm that model is PIA
|
||||||
@@ -154,115 +157,120 @@ class ApplyAnimateDiffPIAModel:
|
|||||||
pia_input = InputPIA_Multival(1.0)
|
pia_input = InputPIA_Multival(1.0)
|
||||||
attachment.pia_input = pia_input
|
attachment.pia_input = pia_input
|
||||||
#curr_model.pia_multival = ref_multival
|
#curr_model.pia_multival = ref_multival
|
||||||
return new_m_models
|
return io.NodeOutput(*new_m_models)
|
||||||
|
|
||||||
|
|
||||||
class LoadAnimateDiffAndInjectPIANode:
|
class LoadAnimateDiffAndInjectPIANode(io.ComfyNode):
|
||||||
EXPERIMENTAL = True
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {
|
return io.Schema(
|
||||||
"required": {
|
node_id='ADE_InjectPIAIntoAnimateDiffModel',
|
||||||
"model_name": (get_available_motion_models(),),
|
display_name='🧪Inject PIA into AnimateDiff Model 🎭🅐🅓②',
|
||||||
"motion_model": ("MOTION_MODEL_ADE",),
|
category='Animate Diff 🎭🅐🅓/② Gen2 nodes ②/PIA/🧪experimental',
|
||||||
},
|
inputs=[
|
||||||
"optional": {
|
io.Combo.Input('model_name', options=get_available_motion_models()),
|
||||||
"ad_settings": ("AD_SETTINGS",),
|
io.Custom("MOTION_MODEL_ADE").Input('motion_model'),
|
||||||
}
|
io.Custom("AD_SETTINGS").Input('ad_settings', optional=True),
|
||||||
}
|
],
|
||||||
|
outputs=[
|
||||||
|
io.Custom("MOTION_MODEL_ADE").Output('MOTION_MODEL'),
|
||||||
|
],
|
||||||
|
is_experimental=True,
|
||||||
|
)
|
||||||
|
|
||||||
RETURN_TYPES = ("MOTION_MODEL_ADE",)
|
|
||||||
RETURN_NAMES = ("MOTION_MODEL",)
|
|
||||||
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/② Gen2 nodes ②/PIA/🧪experimental"
|
|
||||||
FUNCTION = "load_motion_model"
|
|
||||||
|
|
||||||
def load_motion_model(self, model_name: str, motion_model: MotionModelPatcher, ad_settings: AnimateDiffSettings=None):
|
@classmethod
|
||||||
|
def execute(cls, model_name: str, motion_model: MotionModelPatcher, ad_settings: AnimateDiffSettings=None):
|
||||||
# make sure model actually has PIA conv_in
|
# make sure model actually has PIA conv_in
|
||||||
if motion_model.model.conv_in is None:
|
if motion_model.model.conv_in is None:
|
||||||
raise Exception("Passed-in motion model was expected to be PIA (contain conv_in), but did not.")
|
raise Exception("Passed-in motion model was expected to be PIA (contain conv_in), but did not.")
|
||||||
# load motion module and motion settings, if included
|
# load motion module and motion settings, if included
|
||||||
loaded_motion_model = load_motion_module_gen2(model_name=model_name, motion_model_settings=ad_settings)
|
loaded_motion_model = load_motion_module_gen2(model_name=model_name, motion_model_settings=ad_settings)
|
||||||
inject_pia_conv_in_into_model(motion_model=loaded_motion_model, w_pia=motion_model)
|
inject_pia_conv_in_into_model(motion_model=loaded_motion_model, w_pia=motion_model)
|
||||||
return (loaded_motion_model,)
|
return io.NodeOutput(loaded_motion_model,)
|
||||||
|
|
||||||
|
|
||||||
class PIA_ADKeyframeNode:
|
class PIA_ADKeyframeNode(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {
|
return io.Schema(
|
||||||
"required": {
|
node_id='ADE_PIA_AnimateDiffKeyframe',
|
||||||
"start_percent": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001}, ),
|
display_name='AnimateDiff-PIA Keyframe 🎭🅐🅓',
|
||||||
},
|
category='Animate Diff 🎭🅐🅓/② Gen2 nodes ②/PIA',
|
||||||
"optional": {
|
inputs=[
|
||||||
"prev_ad_keyframes": ("AD_KEYFRAMES", ),
|
io.Float.Input('start_percent', default=0.0, max=1.0, min=0.0, step=0.001),
|
||||||
"scale_multival": ("MULTIVAL",),
|
io.Custom("AD_KEYFRAMES").Input('prev_ad_keyframes', optional=True),
|
||||||
"effect_multival": ("MULTIVAL",),
|
io.Custom("MULTIVAL").Input('scale_multival', optional=True),
|
||||||
"pia_input": ("PIA_INPUT",),
|
io.Custom("MULTIVAL").Input('effect_multival', optional=True),
|
||||||
"inherit_missing": ("BOOLEAN", {"default": True}, ),
|
io.Custom("PIA_INPUT").Input('pia_input', optional=True),
|
||||||
"guarantee_steps": ("INT", {"default": 1, "min": 0, "max": BIGMAX}),
|
io.Boolean.Input('inherit_missing', optional=True, default=True),
|
||||||
},
|
io.Int.Input('guarantee_steps', optional=True, default=1, max=9007199254740991, min=0),
|
||||||
}
|
],
|
||||||
|
outputs=[
|
||||||
|
io.Custom("AD_KEYFRAMES").Output('AD_KEYFRAMES'),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
RETURN_TYPES = ("AD_KEYFRAMES", )
|
|
||||||
FUNCTION = "load_keyframe"
|
|
||||||
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/② Gen2 nodes ②/PIA"
|
|
||||||
|
|
||||||
def load_keyframe(self,
|
@classmethod
|
||||||
|
def execute(cls,
|
||||||
start_percent: float, prev_ad_keyframes=None,
|
start_percent: float, prev_ad_keyframes=None,
|
||||||
scale_multival: Union[float, torch.Tensor]=None, effect_multival: Union[float, torch.Tensor]=None,
|
scale_multival: Union[float, torch.Tensor]=None, effect_multival: Union[float, torch.Tensor]=None,
|
||||||
pia_input: InputPIA=None,
|
pia_input: InputPIA=None,
|
||||||
inherit_missing: bool=True, guarantee_steps: int=1):
|
inherit_missing: bool=True, guarantee_steps: int=1):
|
||||||
return ADKeyframeNode.load_keyframe(self,
|
return io.NodeOutput(*ADKeyframeNode.execute(
|
||||||
start_percent=start_percent, prev_ad_keyframes=prev_ad_keyframes,
|
start_percent=start_percent, prev_ad_keyframes=prev_ad_keyframes,
|
||||||
scale_multival=scale_multival, effect_multival=effect_multival, pia_input=pia_input,
|
scale_multival=scale_multival, effect_multival=effect_multival, pia_input=pia_input,
|
||||||
inherit_missing=inherit_missing, guarantee_steps=guarantee_steps
|
inherit_missing=inherit_missing, guarantee_steps=guarantee_steps
|
||||||
|
).args)
|
||||||
|
|
||||||
|
|
||||||
|
class InputPIA_MultivalNode(io.ComfyNode):
|
||||||
|
@classmethod
|
||||||
|
def define_schema(cls) -> io.Schema:
|
||||||
|
return io.Schema(
|
||||||
|
node_id='ADE_InputPIA_Multival',
|
||||||
|
display_name='PIA Input [Multival] 🎭🅐🅓②',
|
||||||
|
category='Animate Diff 🎭🅐🅓/② Gen2 nodes ②/PIA',
|
||||||
|
inputs=[
|
||||||
|
io.Custom("MULTIVAL").Input('multival'),
|
||||||
|
],
|
||||||
|
outputs=[
|
||||||
|
io.Custom("PIA_INPUT").Output('PIA_INPUT'),
|
||||||
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class InputPIA_MultivalNode:
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def execute(cls, multival: Union[float, Tensor], effect_multival: Union[float, Tensor]=None):
|
||||||
return {
|
return io.NodeOutput(InputPIA_Multival(multival, effect_multival),)
|
||||||
"required": {
|
|
||||||
"multival": ("MULTIVAL",),
|
|
||||||
},
|
|
||||||
# "optional": {
|
|
||||||
# "effect_multival": ("MULTIVAL",),
|
|
||||||
# }
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("PIA_INPUT",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/② Gen2 nodes ②/PIA"
|
|
||||||
FUNCTION = "create_pia_input"
|
|
||||||
|
|
||||||
def create_pia_input(self, multival: Union[float, Tensor], effect_multival: Union[float, Tensor]=None):
|
|
||||||
return (InputPIA_Multival(multival, effect_multival),)
|
|
||||||
|
|
||||||
|
|
||||||
class InputPIA_PaperPresetsNode:
|
class InputPIA_PaperPresetsNode(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {
|
return io.Schema(
|
||||||
"required": {
|
node_id='ADE_InputPIA_PaperPresets',
|
||||||
"preset": (PIA_RANGES._LIST_ALL,),
|
display_name='PIA Input [Paper Presets] 🎭🅐🅓②',
|
||||||
"batch_index": ("INT", {"default": 0, "min": BIGMIN, "max": BIGMAX, "step": 1}),
|
category='Animate Diff 🎭🅐🅓/② Gen2 nodes ②/PIA',
|
||||||
},
|
inputs=[
|
||||||
"optional": {
|
io.Combo.Input('preset', options=['Animation (Small Motion)', 'Animation (Medium Motion)', 'Animation (Large Motion)', 'Loop (Small Motion)', 'Loop (Medium Motion)', 'Loop (Large Motion)', 'Style Transfer (Small Motion)', 'Style Transfer (Medium Motion)', 'Style Transfer (Large Motion)']),
|
||||||
"mult_multival": ("MULTIVAL",),
|
io.Int.Input('batch_index', default=0, max=9007199254740991, min=-9007199254740991, step=1),
|
||||||
"print_values": ("BOOLEAN", {"default": False},),
|
io.Custom("MULTIVAL").Input('mult_multival', optional=True),
|
||||||
#"effect_multival": ("MULTIVAL",),
|
io.Boolean.Input('print_values', optional=True, default=False),
|
||||||
},
|
],
|
||||||
}
|
outputs=[
|
||||||
|
io.Custom("PIA_INPUT").Output('PIA_INPUT'),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
RETURN_TYPES = ("PIA_INPUT",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/② Gen2 nodes ②/PIA"
|
|
||||||
FUNCTION = "create_pia_input"
|
|
||||||
|
|
||||||
def create_pia_input(self, preset: str, batch_index: int, mult_multival: Union[float, Tensor]=None, print_values: bool=False, effect_multival: Union[float, Tensor]=None):
|
@classmethod
|
||||||
|
def execute(cls, preset: str, batch_index: int, mult_multival: Union[float, Tensor]=None, print_values: bool=False, effect_multival: Union[float, Tensor]=None):
|
||||||
# verify preset exists - function will throw error if does not
|
# verify preset exists - function will throw error if does not
|
||||||
values = PIA_RANGES.get_preset(preset)
|
values = PIA_RANGES.get_preset(preset)
|
||||||
if print_values:
|
if print_values:
|
||||||
logger.info(f"PIA Preset '{preset}': {values}")
|
logger.info(f"PIA Preset '{preset}': {values}")
|
||||||
return (InputPIA_PaperPresets(preset=preset, index=batch_index, mult_multival=mult_multival, effect_multival=effect_multival),)
|
return io.NodeOutput(InputPIA_PaperPresets(preset=preset, index=batch_index, mult_multival=mult_multival, effect_multival=effect_multival),)
|
||||||
|
|||||||
+427
-392
File diff suppressed because it is too large
Load Diff
+92
-135
@@ -1,157 +1,119 @@
|
|||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
||||||
|
from comfy_api.latest import io
|
||||||
|
|
||||||
from .scheduling import (evaluate_prompt_schedule, evaluate_value_schedule, extract_cond_from_schedule, TensorInterp, PromptOptions,
|
from .scheduling import (evaluate_prompt_schedule, evaluate_value_schedule, extract_cond_from_schedule, TensorInterp, PromptOptions,
|
||||||
verify_key_value)
|
verify_key_value)
|
||||||
from .utils_model import BIGMAX
|
from .utils_model import BIGMAX
|
||||||
from .logger import logger
|
from .logger import logger
|
||||||
|
|
||||||
class PromptSchedulingLatentsNode:
|
class PromptSchedulingLatentsNode(io.ComfyNode):
|
||||||
|
@classmethod
|
||||||
|
def define_schema(cls) -> io.Schema:
|
||||||
|
return io.Schema(
|
||||||
|
node_id='ADE_PromptSchedulingLatents',
|
||||||
|
display_name='Prompt Scheduling [Latents] 🎭🅐🅓',
|
||||||
|
category='Animate Diff 🎭🅐🅓/scheduling',
|
||||||
|
inputs=[io.String.Input('prompts', default='', multiline=True), io.Clip.Input('clip'), io.Latent.Input('latent'), io.String.Input('prepend_text', default='', force_input=True, multiline=True, optional=True), io.String.Input('append_text', default='', force_input=True, multiline=True, optional=True), io.Custom('VALUES_REPLACE').Input('values_replace', optional=True), io.Boolean.Input('print_schedule', default=False, optional=True), io.Combo.Input('tensor_interp', options=['lerp', 'slerp'] , optional=True)],
|
||||||
|
outputs=[io.Conditioning.Output('CONDITIONING'), io.Latent.Output('LATENT')],
|
||||||
|
description='Encode a schedule of prompts with automatic interpolation, its length matching passed-in latent count.'
|
||||||
|
)
|
||||||
NodeID = 'ADE_PromptSchedulingLatents'
|
NodeID = 'ADE_PromptSchedulingLatents'
|
||||||
NodeName = 'Prompt Scheduling [Latents] 🎭🅐🅓'
|
NodeName = 'Prompt Scheduling [Latents] 🎭🅐🅓'
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def execute(cls, prompts: str, clip, latent: dict, print_schedule=False, tensor_interp=TensorInterp.LERP,
|
||||||
return {
|
|
||||||
"required": {
|
|
||||||
"prompts": ("STRING", {"multiline": True, "default": ''}),
|
|
||||||
"clip": ("CLIP",),
|
|
||||||
"latent": ("LATENT",),
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"prepend_text": ("STRING", {"multiline": True, "default": '', "forceInput": True}),
|
|
||||||
"append_text": ("STRING", {"multiline": True, "default": '', "forceInput": True}),
|
|
||||||
"values_replace": ("VALUES_REPLACE",),
|
|
||||||
"print_schedule": ("BOOLEAN", {"default": False}),
|
|
||||||
"tensor_interp": (TensorInterp._LIST,)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("CONDITIONING", "LATENT",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/scheduling"
|
|
||||||
FUNCTION = "create_schedule"
|
|
||||||
DESCRIPTION = 'Encode a schedule of prompts with automatic interpolation, its length matching passed-in latent count.'
|
|
||||||
|
|
||||||
def create_schedule(self, prompts: str, clip, latent: dict, print_schedule=False, tensor_interp=TensorInterp.LERP,
|
|
||||||
prepend_text='', append_text='', values_replace=None):
|
prepend_text='', append_text='', values_replace=None):
|
||||||
options = PromptOptions(interp=tensor_interp, prepend_text=prepend_text, append_text=append_text,
|
options = PromptOptions(interp=tensor_interp, prepend_text=prepend_text, append_text=append_text,
|
||||||
values_replace=values_replace, print_schedule=print_schedule)
|
values_replace=values_replace, print_schedule=print_schedule)
|
||||||
conditioning = evaluate_prompt_schedule(prompts, latent["samples"].size(0), clip, options)
|
conditioning = evaluate_prompt_schedule(prompts, latent["samples"].size(0), clip, options)
|
||||||
return (conditioning, latent)
|
return io.NodeOutput(conditioning, latent)
|
||||||
|
|
||||||
|
|
||||||
class PromptSchedulingNode:
|
class PromptSchedulingNode(io.ComfyNode):
|
||||||
|
@classmethod
|
||||||
|
def define_schema(cls) -> io.Schema:
|
||||||
|
return io.Schema(
|
||||||
|
node_id='ADE_PromptScheduling',
|
||||||
|
display_name='Prompt Scheduling 🎭🅐🅓',
|
||||||
|
category='Animate Diff 🎭🅐🅓/scheduling',
|
||||||
|
inputs=[io.String.Input('prompts', default='', multiline=True), io.Clip.Input('clip'), io.String.Input('prepend_text', default='', force_input=True, multiline=True, optional=True), io.String.Input('append_text', default='', force_input=True, multiline=True, optional=True), io.Custom('VALUES_REPLACE').Input('values_replace', optional=True), io.Boolean.Input('print_schedule', default=False, optional=True), io.Int.Input('max_length', default=0, max=9007199254740991, min=0, step=1, optional=True), io.Combo.Input('tensor_interp', options=['lerp', 'slerp'] , optional=True)],
|
||||||
|
outputs=[io.Conditioning.Output('CONDITIONING')],
|
||||||
|
description='Encode a schedule of prompts with automatic interpolation.'
|
||||||
|
)
|
||||||
NodeID = 'ADE_PromptScheduling'
|
NodeID = 'ADE_PromptScheduling'
|
||||||
NodeName = 'Prompt Scheduling 🎭🅐🅓'
|
NodeName = 'Prompt Scheduling 🎭🅐🅓'
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def execute(cls, prompts: str, clip, print_schedule=False, max_length: int=0, tensor_interp=TensorInterp.LERP,
|
||||||
return {
|
|
||||||
"required": {
|
|
||||||
"prompts": ("STRING", {"multiline": True, "default": ''}),
|
|
||||||
"clip": ("CLIP",),
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"prepend_text": ("STRING", {"multiline": True, "default": '', "forceInput": True}),
|
|
||||||
"append_text": ("STRING", {"multiline": True, "default": '', "forceInput": True}),
|
|
||||||
"values_replace": ("VALUES_REPLACE",),
|
|
||||||
"print_schedule": ("BOOLEAN", {"default": False}),
|
|
||||||
"max_length": ("INT", {"default": 0, "min": 0, "max": BIGMAX, "step": 1}),
|
|
||||||
"tensor_interp": (TensorInterp._LIST,)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("CONDITIONING",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/scheduling"
|
|
||||||
FUNCTION = "create_schedule"
|
|
||||||
DESCRIPTION = 'Encode a schedule of prompts with automatic interpolation.'
|
|
||||||
|
|
||||||
def create_schedule(self, prompts: str, clip, print_schedule=False, max_length: int=0, tensor_interp=TensorInterp.LERP,
|
|
||||||
prepend_text='', append_text='', values_replace=None):
|
prepend_text='', append_text='', values_replace=None):
|
||||||
options = PromptOptions(interp=tensor_interp, prepend_text=prepend_text, append_text=append_text,
|
options = PromptOptions(interp=tensor_interp, prepend_text=prepend_text, append_text=append_text,
|
||||||
values_replace=values_replace, print_schedule=print_schedule)
|
values_replace=values_replace, print_schedule=print_schedule)
|
||||||
conditioning = evaluate_prompt_schedule(prompts, max_length, clip, options)
|
conditioning = evaluate_prompt_schedule(prompts, max_length, clip, options)
|
||||||
return (conditioning,)
|
return io.NodeOutput(conditioning)
|
||||||
|
|
||||||
|
|
||||||
class ValueSchedulingLatentsNode:
|
class ValueSchedulingLatentsNode(io.ComfyNode):
|
||||||
|
@classmethod
|
||||||
|
def define_schema(cls) -> io.Schema:
|
||||||
|
return io.Schema(
|
||||||
|
node_id='ADE_ValueSchedulingLatents',
|
||||||
|
display_name='Value Scheduling [Latents] 🎭🅐🅓',
|
||||||
|
category='Animate Diff 🎭🅐🅓/scheduling',
|
||||||
|
inputs=[io.String.Input('values', default='', multiline=True), io.Latent.Input('latent'), io.Boolean.Input('print_schedule', default=False, optional=True)],
|
||||||
|
outputs=[io.Float.Output('FLOAT'), io.Custom('FLOATS').Output('FLOATS'), io.Int.Output('INT'), io.Custom('INTS').Output('INTS')],
|
||||||
|
description='Create a list of values with automatic interpolation, its length matching passed-in latent count.'
|
||||||
|
)
|
||||||
NodeID = 'ADE_ValueSchedulingLatents'
|
NodeID = 'ADE_ValueSchedulingLatents'
|
||||||
NodeName = 'Value Scheduling [Latents] 🎭🅐🅓'
|
NodeName = 'Value Scheduling [Latents] 🎭🅐🅓'
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def execute(cls, values: str, latent: dict, print_schedule=False):
|
||||||
return {
|
|
||||||
"required": {
|
|
||||||
"values": ("STRING", {"multiline": True, "default": ""}),
|
|
||||||
"latent": ("LATENT",),
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"print_schedule": ("BOOLEAN", {"default": False}),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("FLOAT", "FLOATS", "INT", "INTS")
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/scheduling"
|
|
||||||
FUNCTION = "create_schedule"
|
|
||||||
DESCRIPTION = 'Create a list of values with automatic interpolation, its length matching passed-in latent count.'
|
|
||||||
|
|
||||||
def create_schedule(self, values: str, latent: dict, print_schedule=False):
|
|
||||||
float_vals = evaluate_value_schedule(values, latent["samples"].size(0))
|
float_vals = evaluate_value_schedule(values, latent["samples"].size(0))
|
||||||
int_vals = [round(x) for x in float_vals]
|
int_vals = [round(x) for x in float_vals]
|
||||||
if print_schedule:
|
if print_schedule:
|
||||||
logger.info(f"ValueScheduling ({len(float_vals)} values):")
|
logger.info(f"ValueScheduling ({len(float_vals)} values):")
|
||||||
for i, val in enumerate(float_vals):
|
for i, val in enumerate(float_vals):
|
||||||
logger.info(f"{i} = {val}")
|
logger.info(f"{i} = {val}")
|
||||||
return (float_vals, float_vals, int_vals, int_vals)
|
return io.NodeOutput(float_vals, float_vals, int_vals, int_vals)
|
||||||
|
|
||||||
|
|
||||||
class ValueSchedulingNode:
|
class ValueSchedulingNode(io.ComfyNode):
|
||||||
|
@classmethod
|
||||||
|
def define_schema(cls) -> io.Schema:
|
||||||
|
return io.Schema(
|
||||||
|
node_id='ADE_ValueScheduling',
|
||||||
|
display_name='Value Scheduling 🎭🅐🅓',
|
||||||
|
category='Animate Diff 🎭🅐🅓/scheduling',
|
||||||
|
inputs=[io.String.Input('values', default='', multiline=True), io.Boolean.Input('print_schedule', default=False, optional=True), io.Int.Input('max_length', default=0, max=9007199254740991, min=0, step=1, optional=True)],
|
||||||
|
outputs=[io.Float.Output('FLOAT'), io.Custom('FLOATS').Output('FLOATS'), io.Int.Output('INT'), io.Custom('INTS').Output('INTS')],
|
||||||
|
description='Create a list of values with automatic interpolation.'
|
||||||
|
)
|
||||||
NodeID = 'ADE_ValueScheduling'
|
NodeID = 'ADE_ValueScheduling'
|
||||||
NodeName = 'Value Scheduling 🎭🅐🅓'
|
NodeName = 'Value Scheduling 🎭🅐🅓'
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def execute(cls, values: str, max_length: int, print_schedule=False):
|
||||||
return {
|
|
||||||
"required": {
|
|
||||||
"values": ("STRING", {"multiline": True, "default": ""}),
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"print_schedule": ("BOOLEAN", {"default": False}),
|
|
||||||
"max_length": ("INT", {"default": 0, "min": 0, "max": BIGMAX, "step": 1}),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("FLOAT", "FLOATS", "INT", "INTS")
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/scheduling"
|
|
||||||
FUNCTION = "create_schedule"
|
|
||||||
DESCRIPTION = 'Create a list of values with automatic interpolation.'
|
|
||||||
|
|
||||||
def create_schedule(self, values: str, max_length: int, print_schedule=False):
|
|
||||||
float_vals = evaluate_value_schedule(values, max_length)
|
float_vals = evaluate_value_schedule(values, max_length)
|
||||||
int_vals = [round(x) for x in float_vals]
|
int_vals = [round(x) for x in float_vals]
|
||||||
if print_schedule:
|
if print_schedule:
|
||||||
logger.info(f"ValueScheduling ({len(float_vals)} values):")
|
logger.info(f"ValueScheduling ({len(float_vals)} values):")
|
||||||
for i, val in enumerate(float_vals):
|
for i, val in enumerate(float_vals):
|
||||||
logger.info(f"{i} = {val}")
|
logger.info(f"{i} = {val}")
|
||||||
return (float_vals, float_vals, int_vals, int_vals)
|
return io.NodeOutput(float_vals, float_vals, int_vals, int_vals)
|
||||||
|
|
||||||
|
|
||||||
class AddValuesReplaceNode:
|
class AddValuesReplaceNode(io.ComfyNode):
|
||||||
|
@classmethod
|
||||||
|
def define_schema(cls) -> io.Schema:
|
||||||
|
return io.Schema(
|
||||||
|
node_id='ADE_ValuesReplace',
|
||||||
|
display_name='Add Values Replace 🎭🅐🅓',
|
||||||
|
category='Animate Diff 🎭🅐🅓/scheduling',
|
||||||
|
inputs=[io.String.Input('value_key', default=''), io.Custom('FLOATS').Input('floats'), io.Custom('VALUES_REPLACE').Input('prev_replace', optional=True)],
|
||||||
|
outputs=[io.Custom('VALUES_REPLACE').Output('VALUES_REPLACE')],
|
||||||
|
description='Add a values schedule bound to a key to be used in Prompt Scheduling node.'
|
||||||
|
)
|
||||||
NodeID = 'ADE_ValuesReplace'
|
NodeID = 'ADE_ValuesReplace'
|
||||||
NodeName = 'Add Values Replace 🎭🅐🅓'
|
NodeName = 'Add Values Replace 🎭🅐🅓'
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def execute(cls, value_key: str, floats: Union[list[float]], prev_replace: dict=None):
|
||||||
return {
|
|
||||||
"required": {
|
|
||||||
"value_key": ("STRING", {"default": ""}),
|
|
||||||
"floats": ("FLOATS",)
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"prev_replace": ("VALUES_REPLACE",),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("VALUES_REPLACE",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/scheduling"
|
|
||||||
FUNCTION = "add_values_replace"
|
|
||||||
DESCRIPTION = 'Add a values schedule bound to a key to be used in Prompt Scheduling node.'
|
|
||||||
|
|
||||||
def add_values_replace(self, value_key: str, floats: Union[list[float]], prev_replace: dict=None):
|
|
||||||
# key can only have a-z, A-Z, 0-9, and _ characters
|
# key can only have a-z, A-Z, 0-9, and _ characters
|
||||||
verify_key_value(key=value_key)
|
verify_key_value(key=value_key)
|
||||||
# add/replace value floats
|
# add/replace value floats
|
||||||
@@ -161,49 +123,44 @@ class AddValuesReplaceNode:
|
|||||||
if value_key in prev_replace:
|
if value_key in prev_replace:
|
||||||
logger.warn(f"Value key '{value_key}' is already present - corresponding floats value will be overriden.")
|
logger.warn(f"Value key '{value_key}' is already present - corresponding floats value will be overriden.")
|
||||||
prev_replace[value_key] = floats
|
prev_replace[value_key] = floats
|
||||||
return (prev_replace,)
|
return io.NodeOutput(prev_replace)
|
||||||
|
|
||||||
|
|
||||||
class FloatToFloatsNode:
|
class FloatToFloatsNode(io.ComfyNode):
|
||||||
|
@classmethod
|
||||||
|
def define_schema(cls) -> io.Schema:
|
||||||
|
return io.Schema(
|
||||||
|
node_id='ADE_FloatToFloats',
|
||||||
|
display_name='Float to Floats 🎭🅐🅓',
|
||||||
|
category='Animate Diff 🎭🅐🅓/scheduling',
|
||||||
|
inputs=[io.Float.Input('FLOAT', default=39, force_input=True)],
|
||||||
|
outputs=[io.Custom('FLOATS').Output('FLOATS')]
|
||||||
|
)
|
||||||
NodeID = 'ADE_FloatToFloats'
|
NodeID = 'ADE_FloatToFloats'
|
||||||
NodeName = 'Float to Floats 🎭🅐🅓'
|
NodeName = 'Float to Floats 🎭🅐🅓'
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def execute(cls, FLOAT: Union[float, list[float]]):
|
||||||
return {
|
|
||||||
"required": {
|
|
||||||
"FLOAT": ("FLOAT", {"default": 39, "forceInput": True}),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("FLOATS",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/scheduling"
|
|
||||||
FUNCTION = "convert_to_floats"
|
|
||||||
|
|
||||||
def convert_to_floats(self, FLOAT: Union[float, list[float]]):
|
|
||||||
floats = None
|
floats = None
|
||||||
if isinstance(FLOAT, float):
|
if isinstance(FLOAT, float):
|
||||||
floats = [float(FLOAT)]
|
floats = [float(FLOAT)]
|
||||||
else:
|
else:
|
||||||
floats = list(FLOAT)
|
floats = list(FLOAT)
|
||||||
return (floats,)
|
return io.NodeOutput(floats)
|
||||||
|
|
||||||
class ConditionExtractionNode:
|
class ConditionExtractionNode(io.ComfyNode):
|
||||||
|
@classmethod
|
||||||
|
def define_schema(cls) -> io.Schema:
|
||||||
|
return io.Schema(
|
||||||
|
node_id='ADE_ConditionExtraction',
|
||||||
|
display_name='Condition Step Extraction 🎭🅐🅓',
|
||||||
|
category='Animate Diff 🎭🅐🅓/scheduling',
|
||||||
|
inputs=[io.Conditioning.Input('conditioning'), io.Int.Input('index', default=0, min=0, step=1)],
|
||||||
|
outputs=[io.Conditioning.Output('CONDITIONING')],
|
||||||
|
description='Extract a single conditioning step from a schedule of prompts.'
|
||||||
|
)
|
||||||
NodeID = 'ADE_ConditionExtraction'
|
NodeID = 'ADE_ConditionExtraction'
|
||||||
NodeName = 'Condition Step Extraction 🎭🅐🅓'
|
NodeName = 'Condition Step Extraction 🎭🅐🅓'
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def execute(cls, conditioning, index: int=0):
|
||||||
return {
|
|
||||||
"required": {
|
|
||||||
"conditioning": ("CONDITIONING",),
|
|
||||||
"index": ("INT", {"default": 0, "min": 0, "step": 1})
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("CONDITIONING",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/scheduling"
|
|
||||||
FUNCTION = "extract_conditioning"
|
|
||||||
DESCRIPTION = 'Extract a single conditioning step from a schedule of prompts.'
|
|
||||||
|
|
||||||
def extract_conditioning(self, conditioning, index: int=0):
|
|
||||||
conditioning_step = extract_cond_from_schedule(conditioning, index)
|
conditioning_step = extract_cond_from_schedule(conditioning, index)
|
||||||
return (conditioning_step,)
|
return io.NodeOutput(conditioning_step)
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
from comfy_api.latest import io
|
||||||
import torch
|
import torch
|
||||||
|
|
||||||
import comfy.samplers
|
import comfy.samplers
|
||||||
@@ -13,47 +14,54 @@ def validate_sigma_schedule_compatibility(schedule_A: SigmaSchedule, schedule_B:
|
|||||||
f"{name_b} has {schedule_B.total_sigmas()} sigmas (lcm={schedule_B.is_lcm()}).")
|
f"{name_b} has {schedule_B.total_sigmas()} sigmas (lcm={schedule_B.is_lcm()}).")
|
||||||
|
|
||||||
|
|
||||||
class SigmaScheduleNode:
|
class SigmaScheduleNode(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {
|
return io.Schema(
|
||||||
"required": {
|
node_id='ADE_SigmaSchedule',
|
||||||
"beta_schedule": (BetaSchedules.ALIAS_ACTIVE_LIST,),
|
display_name='Create Sigma Schedule 🎭🅐🅓',
|
||||||
}
|
category='Animate Diff 🎭🅐🅓/sample settings/sigma schedule',
|
||||||
}
|
inputs=[
|
||||||
|
io.Combo.Input('beta_schedule', options=BetaSchedules.ALIAS_ACTIVE_LIST),
|
||||||
|
],
|
||||||
|
outputs=[
|
||||||
|
io.Custom("SIGMA_SCHEDULE").Output('SIGMA_SCHEDULE'),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
RETURN_TYPES = ("SIGMA_SCHEDULE",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/sample settings/sigma schedule"
|
|
||||||
FUNCTION = "get_sigma_schedule"
|
|
||||||
|
|
||||||
def get_sigma_schedule(self, beta_schedule: str):
|
@classmethod
|
||||||
|
def execute(cls, beta_schedule: str) -> io.NodeOutput:
|
||||||
model_type = ModelSamplingType.from_alias(ModelSamplingType.EPS)
|
model_type = ModelSamplingType.from_alias(ModelSamplingType.EPS)
|
||||||
new_model_sampling = BetaSchedules._to_model_sampling(alias=beta_schedule,
|
new_model_sampling = BetaSchedules._to_model_sampling(alias=beta_schedule,
|
||||||
model_type=model_type)
|
model_type=model_type)
|
||||||
return (SigmaSchedule(model_sampling=new_model_sampling, model_type=model_type),)
|
return io.NodeOutput(SigmaSchedule(model_sampling=new_model_sampling, model_type=model_type))
|
||||||
|
|
||||||
|
|
||||||
class RawSigmaScheduleNode:
|
class RawSigmaScheduleNode(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {
|
return io.Schema(
|
||||||
"required": {
|
node_id='ADE_RawSigmaSchedule',
|
||||||
"raw_beta_schedule": (BetaSchedules.RAW_BETA_SCHEDULE_LIST,),
|
display_name='Create Raw Sigma Schedule 🎭🅐🅓',
|
||||||
"linear_start": ("FLOAT", {"default": 0.00085, "min": 0.0, "max": 1.0, "step": 0.000001}),
|
category='Animate Diff 🎭🅐🅓/sample settings/sigma schedule',
|
||||||
"linear_end": ("FLOAT", {"default": 0.012, "min": 0.0, "max": 1.0, "step": 0.000001}),
|
inputs=[
|
||||||
#"cosine_s": ("FLOAT", {"default": 8e-3, "min": 0.0, "max": 1.0, "step": 0.000001}),
|
io.Combo.Input('raw_beta_schedule', options=BetaSchedules.RAW_BETA_SCHEDULE_LIST),
|
||||||
"sampling": (ModelSamplingType._FULL_LIST,),
|
io.Float.Input('linear_start', default=0.00085, max=1.0, min=0.0, step=1e-06),
|
||||||
"lcm_original_timesteps": ("INT", {"default": 50, "min": 1, "max": 1000}),
|
io.Float.Input('linear_end', default=0.012, max=1.0, min=0.0, step=1e-06),
|
||||||
"zsnr": ("BOOLEAN", {"default": False}),
|
io.Combo.Input('sampling', options=ModelSamplingType._FULL_LIST),
|
||||||
},
|
io.Int.Input('lcm_original_timesteps', default=50, max=1000, min=1),
|
||||||
}
|
io.Boolean.Input('zsnr', default=False),
|
||||||
|
],
|
||||||
|
outputs=[
|
||||||
|
io.Custom("SIGMA_SCHEDULE").Output('SIGMA_SCHEDULE'),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
RETURN_TYPES = ("SIGMA_SCHEDULE",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/sample settings/sigma schedule"
|
|
||||||
FUNCTION = "get_sigma_schedule"
|
|
||||||
|
|
||||||
def get_sigma_schedule(self, raw_beta_schedule: str, linear_start: float, linear_end: float,# cosine_s: float,
|
@classmethod
|
||||||
sampling: str, lcm_original_timesteps: int, zsnr: bool, lcm_zsnr: bool=None):
|
def execute(cls, raw_beta_schedule: str, linear_start: float, linear_end: float,# cosine_s: float,
|
||||||
|
sampling: str, lcm_original_timesteps: int, zsnr: bool, lcm_zsnr: bool=None) -> io.NodeOutput:
|
||||||
if lcm_zsnr is not None:
|
if lcm_zsnr is not None:
|
||||||
zsnr = lcm_zsnr
|
zsnr = lcm_zsnr
|
||||||
# from pathlib import Path
|
# from pathlib import Path
|
||||||
@@ -68,51 +76,59 @@ class RawSigmaScheduleNode:
|
|||||||
new_model_sampling = BetaSchedules._to_model_sampling(alias=BetaSchedules.AUTOSELECT, model_type=model_type, config_override=new_config, original_timesteps=lcm_original_timesteps)
|
new_model_sampling = BetaSchedules._to_model_sampling(alias=BetaSchedules.AUTOSELECT, model_type=model_type, config_override=new_config, original_timesteps=lcm_original_timesteps)
|
||||||
if zsnr:
|
if zsnr:
|
||||||
SigmaSchedule.apply_zsnr(new_model_sampling=new_model_sampling)
|
SigmaSchedule.apply_zsnr(new_model_sampling=new_model_sampling)
|
||||||
return (SigmaSchedule(model_sampling=new_model_sampling, model_type=model_type),)
|
return io.NodeOutput(SigmaSchedule(model_sampling=new_model_sampling, model_type=model_type))
|
||||||
|
|
||||||
|
|
||||||
class WeightedAverageSigmaScheduleNode:
|
class WeightedAverageSigmaScheduleNode(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {
|
return io.Schema(
|
||||||
"required": {
|
node_id='ADE_SigmaScheduleWeightedAverage',
|
||||||
"schedule_A": ("SIGMA_SCHEDULE",),
|
display_name='Sigma Schedule Weighted Mean 🎭🅐🅓',
|
||||||
"schedule_B": ("SIGMA_SCHEDULE",),
|
category='Animate Diff 🎭🅐🅓/sample settings/sigma schedule',
|
||||||
"weight_A": ("FLOAT", {"default": 0.5, "min": 0.0, "max": 1.0, "step": 0.001}),
|
inputs=[
|
||||||
},
|
io.Custom("SIGMA_SCHEDULE").Input('schedule_A'),
|
||||||
}
|
io.Custom("SIGMA_SCHEDULE").Input('schedule_B'),
|
||||||
|
io.Float.Input('weight_A', default=0.5, max=1.0, min=0.0, step=0.001),
|
||||||
|
],
|
||||||
|
outputs=[
|
||||||
|
io.Custom("SIGMA_SCHEDULE").Output('SIGMA_SCHEDULE'),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
RETURN_TYPES = ("SIGMA_SCHEDULE",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/sample settings/sigma schedule"
|
|
||||||
FUNCTION = "get_sigma_schedule"
|
|
||||||
|
|
||||||
def get_sigma_schedule(self, schedule_A: SigmaSchedule, schedule_B: SigmaSchedule, weight_A: float):
|
@classmethod
|
||||||
|
def execute(cls, schedule_A: SigmaSchedule, schedule_B: SigmaSchedule, weight_A: float) -> io.NodeOutput:
|
||||||
validate_sigma_schedule_compatibility(schedule_A, schedule_B)
|
validate_sigma_schedule_compatibility(schedule_A, schedule_B)
|
||||||
new_sigmas = schedule_A.model_sampling.sigmas * weight_A + schedule_B.model_sampling.sigmas * (1-weight_A)
|
new_sigmas = schedule_A.model_sampling.sigmas * weight_A + schedule_B.model_sampling.sigmas * (1-weight_A)
|
||||||
combo_schedule = schedule_A.clone()
|
combo_schedule = schedule_A.clone()
|
||||||
combo_schedule.model_sampling.set_sigmas(new_sigmas)
|
combo_schedule.model_sampling.set_sigmas(new_sigmas)
|
||||||
return (combo_schedule,)
|
return io.NodeOutput(combo_schedule)
|
||||||
|
|
||||||
|
|
||||||
class InterpolatedWeightedAverageSigmaScheduleNode:
|
class InterpolatedWeightedAverageSigmaScheduleNode(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {
|
return io.Schema(
|
||||||
"required": {
|
node_id='ADE_SigmaScheduleWeightedAverageInterp',
|
||||||
"schedule_A": ("SIGMA_SCHEDULE",),
|
display_name='Sigma Schedule Interp. Mean 🎭🅐🅓',
|
||||||
"schedule_B": ("SIGMA_SCHEDULE",),
|
category='Animate Diff 🎭🅐🅓/sample settings/sigma schedule',
|
||||||
"weight_A_Start": ("FLOAT", {"default": 0.5, "min": 0.0, "max": 1.0, "step": 0.001}),
|
inputs=[
|
||||||
"weight_A_End": ("FLOAT", {"default": 0.5, "min": 0.0, "max": 1.0, "step": 0.001}),
|
io.Custom("SIGMA_SCHEDULE").Input('schedule_A'),
|
||||||
"interpolation": (InterpolationMethod._LIST,),
|
io.Custom("SIGMA_SCHEDULE").Input('schedule_B'),
|
||||||
},
|
io.Float.Input('weight_A_Start', default=0.5, max=1.0, min=0.0, step=0.001),
|
||||||
}
|
io.Float.Input('weight_A_End', default=0.5, max=1.0, min=0.0, step=0.001),
|
||||||
|
io.Combo.Input('interpolation', options=InterpolationMethod._LIST),
|
||||||
|
],
|
||||||
|
outputs=[
|
||||||
|
io.Custom("SIGMA_SCHEDULE").Output('SIGMA_SCHEDULE'),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
RETURN_TYPES = ("SIGMA_SCHEDULE",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/sample settings/sigma schedule"
|
|
||||||
FUNCTION = "get_sigma_schedule"
|
|
||||||
|
|
||||||
def get_sigma_schedule(self, schedule_A: SigmaSchedule, schedule_B: SigmaSchedule,
|
@classmethod
|
||||||
weight_A_Start: float, weight_A_End: float, interpolation: str):
|
def execute(cls, schedule_A: SigmaSchedule, schedule_B: SigmaSchedule,
|
||||||
|
weight_A_Start: float, weight_A_End: float, interpolation: str) -> io.NodeOutput:
|
||||||
validate_sigma_schedule_compatibility(schedule_A, schedule_B)
|
validate_sigma_schedule_compatibility(schedule_A, schedule_B)
|
||||||
# get reverse weights, since sigmas are currently reversed
|
# get reverse weights, since sigmas are currently reversed
|
||||||
weights = InterpolationMethod.get_weights(num_from=weight_A_Start, num_to=weight_A_End,
|
weights = InterpolationMethod.get_weights(num_from=weight_A_Start, num_to=weight_A_End,
|
||||||
@@ -121,58 +137,65 @@ class InterpolatedWeightedAverageSigmaScheduleNode:
|
|||||||
new_sigmas = schedule_A.model_sampling.sigmas * weights + schedule_B.model_sampling.sigmas * (1.0-weights)
|
new_sigmas = schedule_A.model_sampling.sigmas * weights + schedule_B.model_sampling.sigmas * (1.0-weights)
|
||||||
combo_schedule = schedule_A.clone()
|
combo_schedule = schedule_A.clone()
|
||||||
combo_schedule.model_sampling.set_sigmas(new_sigmas)
|
combo_schedule.model_sampling.set_sigmas(new_sigmas)
|
||||||
return (combo_schedule,)
|
return io.NodeOutput(combo_schedule)
|
||||||
|
|
||||||
|
|
||||||
class SplitAndCombineSigmaScheduleNode:
|
class SplitAndCombineSigmaScheduleNode(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {
|
return io.Schema(
|
||||||
"required": {
|
node_id='ADE_SigmaScheduleSplitAndCombine',
|
||||||
"schedule_Start": ("SIGMA_SCHEDULE",),
|
display_name='Sigma Schedule Split Combine 🎭🅐🅓',
|
||||||
"schedule_End": ("SIGMA_SCHEDULE",),
|
category='Animate Diff 🎭🅐🅓/sample settings/sigma schedule',
|
||||||
"idx_split_percent": ("FLOAT", {"default": 0.5, "min": 0.0, "max": 1.0, "step": 0.001})
|
inputs=[
|
||||||
},
|
io.Custom("SIGMA_SCHEDULE").Input('schedule_Start'),
|
||||||
}
|
io.Custom("SIGMA_SCHEDULE").Input('schedule_End'),
|
||||||
|
io.Float.Input('idx_split_percent', default=0.5, max=1.0, min=0.0, step=0.001),
|
||||||
|
],
|
||||||
|
outputs=[
|
||||||
|
io.Custom("SIGMA_SCHEDULE").Output('SIGMA_SCHEDULE'),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
RETURN_TYPES = ("SIGMA_SCHEDULE",)
|
|
||||||
CATEGORY = "Animate Diff 🎭🅐🅓/sample settings/sigma schedule"
|
|
||||||
FUNCTION = "get_sigma_schedule"
|
|
||||||
|
|
||||||
def get_sigma_schedule(self, schedule_Start: SigmaSchedule, schedule_End: SigmaSchedule, idx_split_percent: float):
|
@classmethod
|
||||||
|
def execute(cls, schedule_Start: SigmaSchedule, schedule_End: SigmaSchedule, idx_split_percent: float) -> io.NodeOutput:
|
||||||
validate_sigma_schedule_compatibility(schedule_Start, schedule_End)
|
validate_sigma_schedule_compatibility(schedule_Start, schedule_End)
|
||||||
# first, calculate index to act as split; get diff from 1.0 since sigmas are flipped at this stage
|
# first, calculate index to act as split; get diff from 1.0 since sigmas are flipped at this stage
|
||||||
idx = int((1.0-idx_split_percent) * schedule_Start.total_sigmas())
|
idx = int((1.0-idx_split_percent) * schedule_Start.total_sigmas())
|
||||||
new_sigmas = torch.cat([schedule_End.model_sampling.sigmas[:idx], schedule_Start.model_sampling.sigmas[idx:]], dim=0)
|
new_sigmas = torch.cat([schedule_End.model_sampling.sigmas[:idx], schedule_Start.model_sampling.sigmas[idx:]], dim=0)
|
||||||
new_schedule = schedule_Start.clone()
|
new_schedule = schedule_Start.clone()
|
||||||
new_schedule.model_sampling.set_sigmas(new_sigmas)
|
new_schedule.model_sampling.set_sigmas(new_sigmas)
|
||||||
return (new_schedule,)
|
return io.NodeOutput(new_schedule)
|
||||||
|
|
||||||
|
|
||||||
class SigmaScheduleToSigmasNode:
|
class SigmaScheduleToSigmasNode(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def define_schema(cls) -> io.Schema:
|
||||||
return {
|
return io.Schema(
|
||||||
"required": {
|
node_id='ADE_SigmaScheduleToSigmas',
|
||||||
"sigma_schedule": ("SIGMA_SCHEDULE",),
|
display_name='Sigma Schedule To Sigmas 🎭🅐🅓',
|
||||||
"scheduler": (comfy.samplers.SCHEDULER_NAMES, ),
|
category='Animate Diff 🎭🅐🅓/sample settings/sigma schedule',
|
||||||
"steps": ("INT", {"default": 20, "min": 1, "max": 10000}),
|
inputs=[
|
||||||
"denoise": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01}),
|
io.Custom("SIGMA_SCHEDULE").Input('sigma_schedule'),
|
||||||
},
|
io.Combo.Input('scheduler', options=comfy.samplers.SCHEDULER_NAMES),
|
||||||
}
|
io.Int.Input('steps', default=20, max=10000, min=1),
|
||||||
|
io.Float.Input('denoise', default=1.0, max=1.0, min=0.0, step=0.01),
|
||||||
|
],
|
||||||
|
outputs=[
|
||||||
|
io.Sigmas.Output('SIGMAS'),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
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):
|
@classmethod
|
||||||
|
def execute(cls, sigma_schedule: SigmaSchedule, scheduler: str, steps: int, denoise: float) -> io.NodeOutput:
|
||||||
total_steps = steps
|
total_steps = steps
|
||||||
if denoise < 1.0:
|
if denoise < 1.0:
|
||||||
if denoise <= 0.0:
|
if denoise <= 0.0:
|
||||||
return (torch.FloatTensor([]),)
|
return io.NodeOutput(torch.FloatTensor([]))
|
||||||
total_steps = int(steps/denoise)
|
total_steps = int(steps/denoise)
|
||||||
|
|
||||||
sigmas = comfy.samplers.calculate_sigmas(sigma_schedule, scheduler, total_steps).cpu()
|
sigmas = comfy.samplers.calculate_sigmas(sigma_schedule, scheduler, total_steps).cpu()
|
||||||
sigmas = sigmas[-(steps + 1):]
|
sigmas = sigmas[-(steps + 1):]
|
||||||
return (sigmas, )
|
return io.NodeOutput(sigmas)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user