Updated Aoply Advanced ControlNet nodes to remove long unnecessaru model_optional fields, shifted some of the nodes.py code around to separate files to make deprecation cleaner

This commit is contained in:
Jedrzej Kosinski
2024-11-14 04:04:21 -06:00
parent 3120c14e0a
commit 1d14382944
3 changed files with 311 additions and 212 deletions
+13 -212
View File
@@ -7,6 +7,9 @@ from comfy.model_patcher import ModelPatcher
from .control import load_controlnet, convert_to_advanced, is_advanced_controlnet, is_sd3_advanced_controlnet
from .utils import ControlWeights, LatentKeyframeGroup, TimestepKeyframeGroup, AbstractPreprocWrapper, BIGMAX
from .nodes_main import (ControlNetLoaderAdvanced, DiffControlNetLoaderAdvanced,
AdvancedControlNetApply, AdvancedControlNetApplySingle)
from .nodes_weight import (DefaultWeights, ScaledSoftMaskedUniversalWeights, ScaledSoftUniversalWeights,
SoftControlNetWeightsSD15, CustomControlNetWeightsSD15, CustomControlNetWeightsFlux,
SoftT2IAdapterWeights, CustomT2IAdapterWeights)
@@ -18,7 +21,8 @@ from .nodes_plusplus import PlusPlusLoaderAdvanced, PlusPlusLoaderSingle, PlusPl
from .nodes_loosecontrol import ControlNetLoaderWithLoraAdvanced
from .nodes_deprecated import (LoadImagesFromDirectory, ScaledSoftUniversalWeightsDeprecated,
SoftControlNetWeightsDeprecated, CustomControlNetWeightsDeprecated,
SoftT2IAdapterWeightsDeprecated, CustomT2IAdapterWeightsDeprecated)
SoftT2IAdapterWeightsDeprecated, CustomT2IAdapterWeightsDeprecated,
AdvancedControlNetApplyDEPR, AdvancedControlNetApplySingleDEPR)
from .logger import logger
from .sampling import acn_sample_factory
@@ -27,213 +31,6 @@ comfy.sample.sample = acn_sample_factory(comfy.sample.sample)
comfy.sample.sample_custom = acn_sample_factory(comfy.sample.sample_custom, is_custom=True)
class ControlNetLoaderAdvanced:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"control_net_name": (folder_paths.get_filename_list("controlnet"), ),
},
"optional": {
"tk_optional": ("TIMESTEP_KEYFRAME", ),
}
}
RETURN_TYPES = ("CONTROL_NET", )
FUNCTION = "load_controlnet"
CATEGORY = "Adv-ControlNet 🛂🅐🅒🅝"
def load_controlnet(self, control_net_name,
tk_optional: TimestepKeyframeGroup=None,
timestep_keyframe: TimestepKeyframeGroup=None,
):
if timestep_keyframe is not None: # backwards compatibility
tk_optional = timestep_keyframe
controlnet_path = folder_paths.get_full_path("controlnet", control_net_name)
controlnet = load_controlnet(controlnet_path, tk_optional)
return (controlnet,)
class DiffControlNetLoaderAdvanced:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"model": ("MODEL",),
"control_net_name": (folder_paths.get_filename_list("controlnet"), )
},
"optional": {
"tk_optional": ("TIMESTEP_KEYFRAME", ),
"autosize": ("ACNAUTOSIZE", {"padding": 160}),
}
}
RETURN_TYPES = ("CONTROL_NET", )
FUNCTION = "load_controlnet"
CATEGORY = "Adv-ControlNet 🛂🅐🅒🅝"
def load_controlnet(self, control_net_name, model,
tk_optional: TimestepKeyframeGroup=None,
timestep_keyframe: TimestepKeyframeGroup=None
):
if timestep_keyframe is not None: # backwards compatibility
tk_optional = timestep_keyframe
controlnet_path = folder_paths.get_full_path("controlnet", control_net_name)
controlnet = load_controlnet(controlnet_path, tk_optional, model)
if is_advanced_controlnet(controlnet):
controlnet.verify_all_weights()
return (controlnet,)
class AdvancedControlNetApply:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"positive": ("CONDITIONING", ),
"negative": ("CONDITIONING", ),
"control_net": ("CONTROL_NET", ),
"image": ("IMAGE", ),
"strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.01}),
"start_percent": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001}),
"end_percent": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.001})
},
"optional": {
"mask_optional": ("MASK", ),
"timestep_kf": ("TIMESTEP_KEYFRAME", ),
"latent_kf_override": ("LATENT_KEYFRAME", ),
"weights_override": ("CONTROL_NET_WEIGHTS", ),
"model_optional": ("MODEL",),
"vae_optional": ("VAE",),
"autosize": ("ACNAUTOSIZE", {"padding": 0}),
}
}
RETURN_TYPES = ("CONDITIONING","CONDITIONING","MODEL",)
RETURN_NAMES = ("positive", "negative", "model_opt")
FUNCTION = "apply_controlnet"
CATEGORY = "Adv-ControlNet 🛂🅐🅒🅝"
def apply_controlnet(self, positive, negative, control_net, image, strength, start_percent, end_percent,
mask_optional: Tensor=None, model_optional: ModelPatcher=None, vae_optional=None,
timestep_kf: TimestepKeyframeGroup=None, latent_kf_override: LatentKeyframeGroup=None,
weights_override: ControlWeights=None, control_apply_to_uncond=False):
if strength == 0:
return (positive, negative, model_optional)
if model_optional:
model_optional = model_optional.clone()
control_hint = image.movedim(-1,1)
cnets = {}
out = []
for conditioning in [positive, negative]:
c = []
if conditioning is not None:
for t in conditioning:
d = t[1].copy()
prev_cnet = d.get('control', None)
if prev_cnet in cnets:
c_net = cnets[prev_cnet]
else:
# make sure control_net is not None to avoid confusing error messages
if control_net is None:
raise Exception("Passed in control_net is None; something must have went wrong when loading it from a Load ControlNet node.")
# copy, convert to advanced if needed, and set cond
c_net = convert_to_advanced(control_net.copy()).set_cond_hint(control_hint, strength, (start_percent, end_percent), vae_optional)
if is_advanced_controlnet(c_net):
# disarm node check
c_net.disarm()
# check for allow_condhint_latents where vae_optional can't handle it itself
if c_net.allow_condhint_latents and not c_net.require_vae:
if not isinstance(control_hint, AbstractPreprocWrapper):
raise Exception(f"Type '{type(c_net).__name__}' requires proc_IMAGE input via a corresponding preprocessor, but received a normal Image instead.")
else:
if isinstance(control_hint, AbstractPreprocWrapper) and not c_net.postpone_condhint_latents_check:
raise Exception(f"Type '{type(c_net).__name__}' requires a normal Image input, but received a proc_IMAGE input instead.")
# if vae required, verify vae is passed in
if c_net.require_vae:
# if controlnet can accept preprocced condhint latents and is the case, ignore vae requirement
if c_net.allow_condhint_latents and isinstance(control_hint, AbstractPreprocWrapper):
pass
elif not vae_optional:
# make sure SD3 ControlNet will get a special message instead of generic type mention
if is_sd3_advanced_controlnet:
raise Exception(f"SD3 ControlNet requires vae_optional input, but got None.")
else:
raise Exception(f"Type '{type(c_net).__name__}' requires vae_optional input, but got None.")
# apply optional parameters and overrides, if provided
if timestep_kf is not None:
c_net.set_timestep_keyframes(timestep_kf)
if latent_kf_override is not None:
c_net.latent_keyframe_override = latent_kf_override
if weights_override is not None:
c_net.weights_override = weights_override
# verify weights are compatible
c_net.verify_all_weights()
# set cond hint mask
if mask_optional is not None:
mask_optional = mask_optional.clone()
# if not in the form of a batch, make it so
if len(mask_optional.shape) < 3:
mask_optional = mask_optional.unsqueeze(0)
c_net.set_cond_hint_mask(mask_optional)
c_net.set_previous_controlnet(prev_cnet)
cnets[prev_cnet] = c_net
d['control'] = c_net
d['control_apply_to_uncond'] = control_apply_to_uncond
n = [t[0], d]
c.append(n)
out.append(c)
return (out[0], out[1], model_optional)
class AdvancedControlNetApplySingle:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"conditioning": ("CONDITIONING", ),
"control_net": ("CONTROL_NET", ),
"image": ("IMAGE", ),
"strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.01}),
"start_percent": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001}),
"end_percent": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.001})
},
"optional": {
"mask_optional": ("MASK", ),
"timestep_kf": ("TIMESTEP_KEYFRAME", ),
"latent_kf_override": ("LATENT_KEYFRAME", ),
"weights_override": ("CONTROL_NET_WEIGHTS", ),
"model_optional": ("MODEL",),
"vae_optional": ("VAE",),
"autosize": ("ACNAUTOSIZE", {"padding": 0}),
}
}
RETURN_TYPES = ("CONDITIONING","MODEL",)
RETURN_NAMES = ("CONDITIONING", "model_opt")
FUNCTION = "apply_controlnet"
CATEGORY = "Adv-ControlNet 🛂🅐🅒🅝"
def apply_controlnet(self, conditioning, control_net, image, strength, start_percent, end_percent,
mask_optional: Tensor=None, model_optional: ModelPatcher=None, vae_optional=None,
timestep_kf: TimestepKeyframeGroup=None, latent_kf_override: LatentKeyframeGroup=None,
weights_override: ControlWeights=None):
values = AdvancedControlNetApply.apply_controlnet(self, positive=conditioning, negative=None, control_net=control_net, image=image,
strength=strength, start_percent=start_percent, end_percent=end_percent,
mask_optional=mask_optional, model_optional=model_optional, vae_optional=vae_optional,
timestep_kf=timestep_kf, latent_kf_override=latent_kf_override, weights_override=weights_override,
control_apply_to_uncond=True)
return (values[0], values[2])
# NODE MAPPING
NODE_CLASS_MAPPINGS = {
# Keyframes
@@ -245,8 +42,8 @@ NODE_CLASS_MAPPINGS = {
"LatentKeyframeBatchedGroup": LatentKeyframeBatchedGroupNode,
"LatentKeyframeGroup": LatentKeyframeGroupNode,
# Conditioning
"ACN_AdvancedControlNetApply": AdvancedControlNetApply,
"ACN_AdvancedControlNetApplySingle": AdvancedControlNetApplySingle,
"ACN_AdvancedControlNetApply_v2": AdvancedControlNetApply,
"ACN_AdvancedControlNetApplySingle_v2": AdvancedControlNetApplySingle,
# Loaders
"ControlNetLoaderAdvanced": ControlNetLoaderAdvanced,
"DiffControlNetLoaderAdvanced": DiffControlNetLoaderAdvanced,
@@ -283,6 +80,8 @@ NODE_CLASS_MAPPINGS = {
"CustomControlNetWeights": CustomControlNetWeightsDeprecated,
"SoftT2IAdapterWeights": SoftT2IAdapterWeightsDeprecated,
"CustomT2IAdapterWeights": CustomT2IAdapterWeightsDeprecated,
"ACN_AdvancedControlNetApply": AdvancedControlNetApplyDEPR,
"ACN_AdvancedControlNetApplySingle": AdvancedControlNetApplySingleDEPR,
}
NODE_DISPLAY_NAME_MAPPINGS = {
@@ -295,8 +94,8 @@ NODE_DISPLAY_NAME_MAPPINGS = {
"LatentKeyframeBatchedGroup": "Latent Keyframe From List 🛂🅐🅒🅝",
"LatentKeyframeGroup": "Latent Keyframe Group 🛂🅐🅒🅝",
# Conditioning
"ACN_AdvancedControlNetApply": "Apply Advanced ControlNet 🛂🅐🅒🅝",
"ACN_AdvancedControlNetApplySingle": "Apply Advanced ControlNet(1) 🛂🅐🅒🅝",
"ACN_AdvancedControlNetApply_v2": "Apply Advanced ControlNet 🛂🅐🅒🅝",
"ACN_AdvancedControlNetApplySingle_v2": "Apply Advanced ControlNet(1) 🛂🅐🅒🅝",
# Loaders
"ControlNetLoaderAdvanced": "Load Advanced ControlNet Model 🛂🅐🅒🅝",
"DiffControlNetLoaderAdvanced": "Load Advanced ControlNet Model (diff) 🛂🅐🅒🅝",
@@ -333,4 +132,6 @@ NODE_DISPLAY_NAME_MAPPINGS = {
"CustomControlNetWeights": "ControlNet Custom Weights 🛂🅐🅒🅝",
"SoftT2IAdapterWeights": "T2IAdapter Soft Weights 🛂🅐🅒🅝",
"CustomT2IAdapterWeights": "T2IAdapter Custom Weights 🛂🅐🅒🅝",
"ACN_AdvancedControlNetApply": "Apply Advanced ControlNet 🛂🅐🅒🅝",
"ACN_AdvancedControlNetApplySingle": "Apply Advanced ControlNet(1) 🛂🅐🅒🅝",
}
+85
View File
@@ -4,6 +4,7 @@ import torch
import numpy as np
from PIL import Image, ImageOps
from .nodes_main import AdvancedControlNetApply
from .utils import BIGMAX, ControlWeights, TimestepKeyframeGroup, TimestepKeyframe, get_properly_arranged_t2i_weights
from .logger import logger
@@ -249,3 +250,87 @@ class CustomT2IAdapterWeightsDeprecated:
weights = get_properly_arranged_t2i_weights(weights)
weights = ControlWeights.t2iadapter(weights_input=weights, uncond_multiplier=uncond_multiplier, extras=cn_extras)
return (weights, TimestepKeyframeGroup.default(TimestepKeyframe(control_weights=weights)))
class AdvancedControlNetApplyDEPR:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"positive": ("CONDITIONING", ),
"negative": ("CONDITIONING", ),
"control_net": ("CONTROL_NET", ),
"image": ("IMAGE", ),
"strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.01}),
"start_percent": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001}),
"end_percent": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.001})
},
"optional": {
"mask_optional": ("MASK", ),
"timestep_kf": ("TIMESTEP_KEYFRAME", ),
"latent_kf_override": ("LATENT_KEYFRAME", ),
"weights_override": ("CONTROL_NET_WEIGHTS", ),
"model_optional": ("MODEL",),
"vae_optional": ("VAE",),
"autosize": ("ACNAUTOSIZE", {"padding": 0}),
}
}
DEPRECATED = True
RETURN_TYPES = ("CONDITIONING","CONDITIONING","MODEL",)
RETURN_NAMES = ("positive", "negative", "model_opt")
FUNCTION = "apply_controlnet"
CATEGORY = ""
def apply_controlnet(self, positive, negative, control_net, image, strength, start_percent, end_percent,
mask_optional=None, model_optional=None, vae_optional=None,
timestep_kf: TimestepKeyframeGroup=None, latent_kf_override=None,
weights_override: ControlWeights=None, control_apply_to_uncond=False):
new_positive, new_negative = AdvancedControlNetApply.apply_controlnet(self, positive=positive, negative=negative, control_net=control_net, image=image,
strength=strength, start_percent=start_percent, end_percent=end_percent,
mask_optional=mask_optional, vae_optional=vae_optional,
timestep_kf=timestep_kf, latent_kf_override=latent_kf_override, weights_override=weights_override,)
return (new_positive, new_negative, model_optional)
class AdvancedControlNetApplySingleDEPR:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"conditioning": ("CONDITIONING", ),
"control_net": ("CONTROL_NET", ),
"image": ("IMAGE", ),
"strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.01}),
"start_percent": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001}),
"end_percent": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.001})
},
"optional": {
"mask_optional": ("MASK", ),
"timestep_kf": ("TIMESTEP_KEYFRAME", ),
"latent_kf_override": ("LATENT_KEYFRAME", ),
"weights_override": ("CONTROL_NET_WEIGHTS", ),
"model_optional": ("MODEL",),
"vae_optional": ("VAE",),
"autosize": ("ACNAUTOSIZE", {"padding": 0}),
}
}
DEPRECATED = True
RETURN_TYPES = ("CONDITIONING","MODEL",)
RETURN_NAMES = ("CONDITIONING", "model_opt")
FUNCTION = "apply_controlnet"
CATEGORY = ""
def apply_controlnet(self, conditioning, control_net, image, strength, start_percent, end_percent,
mask_optional=None, model_optional=None, vae_optional=None,
timestep_kf: TimestepKeyframeGroup=None, latent_kf_override=None,
weights_override: ControlWeights=None):
values = AdvancedControlNetApply.apply_controlnet(self, positive=conditioning, negative=None, control_net=control_net, image=image,
strength=strength, start_percent=start_percent, end_percent=end_percent,
mask_optional=mask_optional, vae_optional=vae_optional,
timestep_kf=timestep_kf, latent_kf_override=latent_kf_override, weights_override=weights_override,
control_apply_to_uncond=True)
return (values[0], model_optional)
+213
View File
@@ -0,0 +1,213 @@
from torch import Tensor
import folder_paths
from comfy.model_patcher import ModelPatcher
from .control import load_controlnet, convert_to_advanced, is_advanced_controlnet, is_sd3_advanced_controlnet
from .utils import ControlWeights, LatentKeyframeGroup, TimestepKeyframeGroup, AbstractPreprocWrapper, BIGMAX
from .logger import logger
class ControlNetLoaderAdvanced:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"control_net_name": (folder_paths.get_filename_list("controlnet"), ),
},
"optional": {
"tk_optional": ("TIMESTEP_KEYFRAME", ),
}
}
RETURN_TYPES = ("CONTROL_NET", )
FUNCTION = "load_controlnet"
CATEGORY = "Adv-ControlNet 🛂🅐🅒🅝"
def load_controlnet(self, control_net_name,
tk_optional: TimestepKeyframeGroup=None,
timestep_keyframe: TimestepKeyframeGroup=None,
):
if timestep_keyframe is not None: # backwards compatibility
tk_optional = timestep_keyframe
controlnet_path = folder_paths.get_full_path("controlnet", control_net_name)
controlnet = load_controlnet(controlnet_path, tk_optional)
return (controlnet,)
class DiffControlNetLoaderAdvanced:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"model": ("MODEL",),
"control_net_name": (folder_paths.get_filename_list("controlnet"), )
},
"optional": {
"tk_optional": ("TIMESTEP_KEYFRAME", ),
"autosize": ("ACNAUTOSIZE", {"padding": 160}),
}
}
RETURN_TYPES = ("CONTROL_NET", )
FUNCTION = "load_controlnet"
CATEGORY = "Adv-ControlNet 🛂🅐🅒🅝"
def load_controlnet(self, control_net_name, model,
tk_optional: TimestepKeyframeGroup=None,
timestep_keyframe: TimestepKeyframeGroup=None
):
if timestep_keyframe is not None: # backwards compatibility
tk_optional = timestep_keyframe
controlnet_path = folder_paths.get_full_path("controlnet", control_net_name)
controlnet = load_controlnet(controlnet_path, tk_optional, model)
if is_advanced_controlnet(controlnet):
controlnet.verify_all_weights()
return (controlnet,)
class AdvancedControlNetApply:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"positive": ("CONDITIONING", ),
"negative": ("CONDITIONING", ),
"control_net": ("CONTROL_NET", ),
"image": ("IMAGE", ),
"strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.01}),
"start_percent": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001}),
"end_percent": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.001})
},
"optional": {
"mask_optional": ("MASK", ),
"timestep_kf": ("TIMESTEP_KEYFRAME", ),
"latent_kf_override": ("LATENT_KEYFRAME", ),
"weights_override": ("CONTROL_NET_WEIGHTS", ),
"vae_optional": ("VAE",),
"autosize": ("ACNAUTOSIZE", {"padding": 0}),
}
}
RETURN_TYPES = ("CONDITIONING","CONDITIONING",)
RETURN_NAMES = ("positive", "negative")
FUNCTION = "apply_controlnet"
CATEGORY = "Adv-ControlNet 🛂🅐🅒🅝"
def apply_controlnet(self, positive, negative, control_net, image, strength, start_percent, end_percent,
mask_optional: Tensor=None, vae_optional=None,
timestep_kf: TimestepKeyframeGroup=None, latent_kf_override: LatentKeyframeGroup=None,
weights_override: ControlWeights=None, control_apply_to_uncond=False):
if strength == 0:
return (positive, negative)
control_hint = image.movedim(-1,1)
cnets = {}
out = []
for conditioning in [positive, negative]:
c = []
if conditioning is not None:
for t in conditioning:
d = t[1].copy()
prev_cnet = d.get('control', None)
if prev_cnet in cnets:
c_net = cnets[prev_cnet]
else:
# make sure control_net is not None to avoid confusing error messages
if control_net is None:
raise Exception("Passed in control_net is None; something must have went wrong when loading it from a Load ControlNet node.")
# copy, convert to advanced if needed, and set cond
c_net = convert_to_advanced(control_net.copy()).set_cond_hint(control_hint, strength, (start_percent, end_percent), vae_optional)
if is_advanced_controlnet(c_net):
# disarm node check
c_net.disarm()
# check for allow_condhint_latents where vae_optional can't handle it itself
if c_net.allow_condhint_latents and not c_net.require_vae:
if not isinstance(control_hint, AbstractPreprocWrapper):
raise Exception(f"Type '{type(c_net).__name__}' requires proc_IMAGE input via a corresponding preprocessor, but received a normal Image instead.")
else:
if isinstance(control_hint, AbstractPreprocWrapper) and not c_net.postpone_condhint_latents_check:
raise Exception(f"Type '{type(c_net).__name__}' requires a normal Image input, but received a proc_IMAGE input instead.")
# if vae required, verify vae is passed in
if c_net.require_vae:
# if controlnet can accept preprocced condhint latents and is the case, ignore vae requirement
if c_net.allow_condhint_latents and isinstance(control_hint, AbstractPreprocWrapper):
pass
elif not vae_optional:
# make sure SD3 ControlNet will get a special message instead of generic type mention
if is_sd3_advanced_controlnet:
raise Exception(f"SD3 ControlNet requires vae_optional input, but got None.")
else:
raise Exception(f"Type '{type(c_net).__name__}' requires vae_optional input, but got None.")
# apply optional parameters and overrides, if provided
if timestep_kf is not None:
c_net.set_timestep_keyframes(timestep_kf)
if latent_kf_override is not None:
c_net.latent_keyframe_override = latent_kf_override
if weights_override is not None:
c_net.weights_override = weights_override
# verify weights are compatible
c_net.verify_all_weights()
# set cond hint mask
if mask_optional is not None:
mask_optional = mask_optional.clone()
# if not in the form of a batch, make it so
if len(mask_optional.shape) < 3:
mask_optional = mask_optional.unsqueeze(0)
c_net.set_cond_hint_mask(mask_optional)
c_net.set_previous_controlnet(prev_cnet)
cnets[prev_cnet] = c_net
d['control'] = c_net
d['control_apply_to_uncond'] = control_apply_to_uncond
n = [t[0], d]
c.append(n)
out.append(c)
return (out[0], out[1])
class AdvancedControlNetApplySingle:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"conditioning": ("CONDITIONING", ),
"control_net": ("CONTROL_NET", ),
"image": ("IMAGE", ),
"strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.01}),
"start_percent": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001}),
"end_percent": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.001})
},
"optional": {
"mask_optional": ("MASK", ),
"timestep_kf": ("TIMESTEP_KEYFRAME", ),
"latent_kf_override": ("LATENT_KEYFRAME", ),
"weights_override": ("CONTROL_NET_WEIGHTS", ),
"model_optional": ("MODEL",),
"vae_optional": ("VAE",),
"autosize": ("ACNAUTOSIZE", {"padding": 0}),
}
}
RETURN_TYPES = ("CONDITIONING","MODEL",)
RETURN_NAMES = ("CONDITIONING", "model_opt")
FUNCTION = "apply_controlnet"
CATEGORY = "Adv-ControlNet 🛂🅐🅒🅝"
def apply_controlnet(self, conditioning, control_net, image, strength, start_percent, end_percent,
mask_optional: Tensor=None, model_optional: ModelPatcher=None, vae_optional=None,
timestep_kf: TimestepKeyframeGroup=None, latent_kf_override: LatentKeyframeGroup=None,
weights_override: ControlWeights=None):
values = AdvancedControlNetApply.apply_controlnet(self, positive=conditioning, negative=None, control_net=control_net, image=image,
strength=strength, start_percent=start_percent, end_percent=end_percent,
mask_optional=mask_optional, model_optional=model_optional, vae_optional=vae_optional,
timestep_kf=timestep_kf, latent_kf_override=latent_kf_override, weights_override=weights_override,
control_apply_to_uncond=True)
return (values[0],)