Skip to content

Commit 3b30e01

Browse files
author
doctorpangloss
committed
Installable with links to the known models
1 parent 74d0c56 commit 3b30e01

10 files changed

+155
-117
lines changed

__init__.py

+1-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,2 @@
1-
from .adv_control.nodes import NODE_CLASS_MAPPINGS, NODE_DISPLAY_NAME_MAPPINGS
2-
from .adv_control import documentation
3-
41
WEB_DIRECTORY = "./web"
5-
__all__ = ['NODE_CLASS_MAPPINGS', 'NODE_DISPLAY_NAME_MAPPINGS', "WEB_DIRECTORY"]
6-
documentation.format_descriptions(NODE_CLASS_MAPPINGS)
2+

adv_control/__init__.py

Whitespace-only changes.

adv_control/control_reference.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ def __init__(self, condhint: Tensor):
141141
class ReferenceAdvanced(ControlBase, AdvancedControlBase):
142142
CHANNEL_TO_MULT = {320: 1, 640: 2, 1280: 4}
143143

144-
def __init__(self, ref_opts: ReferenceOptions, timestep_keyframes: TimestepKeyframeGroup, device=None):
144+
def __init__(self, ref_opts: ReferenceOptions, timestep_keyframes: TimestepKeyframeGroup | None, device=None):
145145
super().__init__(device)
146146
AdvancedControlBase.__init__(self, super(), timestep_keyframes=timestep_keyframes, weights_default=ControlWeights.controllllite(), allow_condhint_latents=True)
147147
# TODO: allow vae_optional to be used instead of preprocessor

adv_control/nodes.py

+77-66
Large diffs are not rendered by default.

adv_control/nodes_loosecontrol.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import folder_paths
1+
from comfy.model_downloader import get_or_download, get_filename_list_with_downloadable
22
import comfy.utils
33
import comfy.model_detection
44
import comfy.model_management
@@ -37,8 +37,8 @@ class ControlNetLoaderWithLoraAdvanced:
3737
def INPUT_TYPES(s):
3838
return {
3939
"required": {
40-
"control_net_name": (folder_paths.get_filename_list("controlnet"), ),
41-
"cn_lora_name": (folder_paths.get_filename_list("controlnet"), ),
40+
"control_net_name": (get_filename_list_with_downloadable("controlnet"), ),
41+
"cn_lora_name": (get_filename_list_with_downloadable("controlnet"), ),
4242
"cn_lora_strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.001}),
4343
},
4444
"optional": {
@@ -54,12 +54,12 @@ def INPUT_TYPES(s):
5454
def load_controlnet(self, control_net_name, cn_lora_name, cn_lora_strength: float,
5555
timestep_keyframe: TimestepKeyframeGroup=None
5656
):
57-
controlnet_path = folder_paths.get_full_path("controlnet", control_net_name)
57+
controlnet_path = get_or_download("controlnet", control_net_name)
5858
controlnet: ControlNetAdvanced = load_controlnet(controlnet_path, timestep_keyframe)
5959
if not isinstance(controlnet, ControlNetAdvanced):
6060
raise ValueError("Type {} is not compatible with CN LoRA features at this time.")
6161
# now, try to load CN LoRA
62-
lora_path = folder_paths.get_full_path("controlnet", cn_lora_name)
62+
lora_path = get_or_download("controlnet", cn_lora_name)
6363
lora_data = convert_cn_lora_from_diffusers(cn_model=controlnet.control_model_wrapped, lora_path=lora_path)
6464
# apply patches to wrapped control_model
6565
controlnet.control_model_wrapped.add_patches(lora_data, strength_patch=cn_lora_strength)

adv_control/nodes_plusplus.py

+5-6
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
from torch import Tensor
22
import math
33

4-
import folder_paths
5-
4+
from comfy.model_downloader import get_or_download, get_filename_list_with_downloadable
65
from .control_plusplus import load_controlnetplusplus, PlusPlusType, PlusPlusInput, PlusPlusInputGroup, PlusPlusImageWrapper
76
from .utils import BIGMAX
87

@@ -13,7 +12,7 @@ def INPUT_TYPES(s):
1312
return {
1413
"required": {
1514
"plus_input": ("PLUS_INPUT", ),
16-
"name": (folder_paths.get_filename_list("controlnet"), ),
15+
"name": (get_filename_list_with_downloadable("controlnet"), ),
1716
}
1817
}
1918

@@ -23,7 +22,7 @@ def INPUT_TYPES(s):
2322
CATEGORY = "Adv-ControlNet 🛂🅐🅒🅝/ControlNet++"
2423

2524
def load_controlnet_plusplus(self, plus_input: PlusPlusInputGroup, name: str):
26-
controlnet_path = folder_paths.get_full_path("controlnet", name)
25+
controlnet_path = get_or_download("controlnet", name)
2726
controlnet = load_controlnetplusplus(controlnet_path)
2827
controlnet.verify_control_type(name, plus_input)
2928
return (controlnet, PlusPlusImageWrapper(plus_input),)
@@ -34,7 +33,7 @@ class PlusPlusLoaderSingle:
3433
def INPUT_TYPES(s):
3534
return {
3635
"required": {
37-
"name": (folder_paths.get_filename_list("controlnet"), ),
36+
"name": (get_filename_list_with_downloadable("controlnet"), ),
3837
"control_type": (PlusPlusType._LIST_WITH_NONE, {"default": PlusPlusType.NONE}, ),
3938
}
4039
}
@@ -45,7 +44,7 @@ def INPUT_TYPES(s):
4544
CATEGORY = "Adv-ControlNet 🛂🅐🅒🅝/ControlNet++"
4645

4746
def load_controlnet_plusplus(self, name: str, control_type: str):
48-
controlnet_path = folder_paths.get_full_path("controlnet", name)
47+
controlnet_path = get_or_download("controlnet", name)
4948
controlnet = load_controlnetplusplus(controlnet_path)
5049
controlnet.single_control_type = control_type
5150
controlnet.verify_control_type(name)

adv_control/nodes_reference.py

+2-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from torch import Tensor
22

3-
from nodes import VAEEncode
3+
from comfy.nodes.base_nodes import VAEEncode
44
import comfy.utils
55
from comfy.sd import VAE
66

@@ -82,9 +82,6 @@ def preprocess_images(self, vae: VAE, image: Tensor, latent_size: Tensor):
8282
image = comfy.utils.common_upscale(image, latent_size["samples"].shape[3] * 8, latent_size["samples"].shape[2] * 8, 'nearest-exact', "center")
8383
image = image.movedim(1,-1)
8484
# then, vae encode
85-
try:
86-
image = vae.vae_encode_crop_pixels(image)
87-
except Exception:
88-
image = VAEEncode.vae_encode_crop_pixels(image)
85+
image = vae.vae_encode_crop_pixels(image)
8986
encoded = vae.encode(image[:,:,:,:3])
9087
return (ReferencePreprocWrapper(condhint=encoded),)

adv_control/nodes_sparsectrl.py

+16-18
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
from torch import Tensor
22

3-
import folder_paths
4-
from nodes import VAEEncode
3+
from comfy.model_downloader import get_or_download, get_filename_list_with_downloadable
54
import comfy.utils
65
from comfy.sd import VAE
76

@@ -16,7 +15,7 @@ class SparseCtrlLoaderAdvanced:
1615
def INPUT_TYPES(s):
1716
return {
1817
"required": {
19-
"sparsectrl_name": (folder_paths.get_filename_list("controlnet"), ),
18+
"sparsectrl_name": (get_filename_list_with_downloadable("controlnet"), ),
2019
"use_motion": ("BOOLEAN", {"default": True}, ),
2120
"motion_strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ),
2221
"motion_scale": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ),
@@ -30,15 +29,15 @@ def INPUT_TYPES(s):
3029
"sparse_mask_mult": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ),
3130
}
3231
}
33-
32+
3433
RETURN_TYPES = ("CONTROL_NET", )
3534
FUNCTION = "load_controlnet"
3635

3736
CATEGORY = "Adv-ControlNet 🛂🅐🅒🅝/SparseCtrl"
3837

3938
def load_controlnet(self, sparsectrl_name: str, use_motion: bool, motion_strength: float, motion_scale: float, sparse_method: SparseMethod=SparseSpreadMethod(), tk_optional: TimestepKeyframeGroup=None,
4039
context_aware=SparseContextAware.NEAREST_HINT, sparse_hint_mult=1.0, sparse_nonhint_mult=1.0, sparse_mask_mult=1.0):
41-
sparsectrl_path = folder_paths.get_full_path("controlnet", sparsectrl_name)
40+
sparsectrl_path = get_or_download("controlnet", sparsectrl_name)
4241
sparse_settings = SparseSettings(sparse_method=sparse_method, use_motion=use_motion, motion_strength=motion_strength, motion_scale=motion_scale,
4342
context_aware=context_aware,
4443
sparse_mask_mult=sparse_mask_mult, sparse_hint_mult=sparse_hint_mult, sparse_nonhint_mult=sparse_nonhint_mult)
@@ -51,8 +50,8 @@ class SparseCtrlMergedLoaderAdvanced:
5150
def INPUT_TYPES(s):
5251
return {
5352
"required": {
54-
"sparsectrl_name": (folder_paths.get_filename_list("controlnet"), ),
55-
"control_net_name": (folder_paths.get_filename_list("controlnet"), ),
53+
"sparsectrl_name": (get_filename_list_with_downloadable("controlnet"), ),
54+
"control_net_name": (get_filename_list_with_downloadable("controlnet"), ),
5655
"use_motion": ("BOOLEAN", {"default": True}, ),
5756
"motion_strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ),
5857
"motion_scale": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ),
@@ -62,15 +61,15 @@ def INPUT_TYPES(s):
6261
"tk_optional": ("TIMESTEP_KEYFRAME", ),
6362
}
6463
}
65-
64+
6665
RETURN_TYPES = ("CONTROL_NET", )
6766
FUNCTION = "load_controlnet"
6867

6968
CATEGORY = "Adv-ControlNet 🛂🅐🅒🅝/SparseCtrl/experimental"
7069

7170
def load_controlnet(self, sparsectrl_name: str, control_net_name: str, use_motion: bool, motion_strength: float, motion_scale: float, sparse_method: SparseMethod=SparseSpreadMethod(), tk_optional: TimestepKeyframeGroup=None):
72-
sparsectrl_path = folder_paths.get_full_path("controlnet", sparsectrl_name)
73-
controlnet_path = folder_paths.get_full_path("controlnet", control_net_name)
71+
sparsectrl_path = get_or_download("controlnet", sparsectrl_name)
72+
controlnet_path = get_or_download("controlnet", control_net_name)
7473
sparse_settings = SparseSettings(sparse_method=sparse_method, use_motion=use_motion, motion_strength=motion_strength, motion_scale=motion_scale, merged=True)
7574
# first, load normal controlnet
7675
controlnet = load_controlnet(controlnet_path, timestep_keyframe=tk_optional)
@@ -96,7 +95,7 @@ def INPUT_TYPES(s):
9695
"indexes": ("STRING", {"default": "0"}),
9796
}
9897
}
99-
98+
10099
RETURN_TYPES = ("SPARSE_METHOD",)
101100
FUNCTION = "get_method"
102101

@@ -115,7 +114,7 @@ def INPUT_TYPES(s):
115114
"spread": (SparseSpreadMethod.LIST,),
116115
}
117116
}
118-
117+
119118
RETURN_TYPES = ("SPARSE_METHOD",)
120119
FUNCTION = "get_method"
121120

@@ -151,10 +150,7 @@ def preprocess_images(self, vae: VAE, image: Tensor, latent_size: Tensor):
151150
image = comfy.utils.common_upscale(image, latent_size["samples"].shape[3] * 8, latent_size["samples"].shape[2] * 8, 'nearest-exact', "center")
152151
image = image.movedim(1,-1)
153152
# then, vae encode
154-
try:
155-
image = vae.vae_encode_crop_pixels(image)
156-
except Exception:
157-
image = VAEEncode.vae_encode_crop_pixels(image)
153+
image = vae.vae_encode_crop_pixels(image)
158154
encoded = vae.encode(image[:,:,:,:3])
159155
return (PreprocSparseRGBWrapper(condhint=encoded),)
160156

@@ -171,14 +167,16 @@ def INPUT_TYPES(s):
171167
"autosize": ("ACNAUTOSIZE", {"padding": 50}),
172168
}
173169
}
174-
170+
175171
RETURN_TYPES = ("CN_WEIGHTS_EXTRAS", )
176172
RETURN_NAMES = ("cn_extras", )
177173
FUNCTION = "create_weight_extras"
178174

179175
CATEGORY = "Adv-ControlNet 🛂🅐🅒🅝/SparseCtrl/extras"
180176

181-
def create_weight_extras(self, cn_extras: dict[str]={}, sparse_hint_mult=1.0, sparse_nonhint_mult=1.0, sparse_mask_mult=1.0):
177+
def create_weight_extras(self, cn_extras=None, sparse_hint_mult=1.0, sparse_nonhint_mult=1.0, sparse_mask_mult=1.0):
178+
if cn_extras is None:
179+
cn_extras = {}
182180
cn_extras = cn_extras.copy()
183181
cn_extras[SparseConst.HINT_MULT] = sparse_hint_mult
184182
cn_extras[SparseConst.NONHINT_MULT] = sparse_nonhint_mult

adv_control/nodes_weight.py

+27-11
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ def INPUT_TYPES(s):
2323

2424
CATEGORY = "Adv-ControlNet 🛂🅐🅒🅝/weights"
2525

26-
def load_weights(self, cn_extras: dict[str]={}):
26+
def load_weights(self, cn_extras=None):
27+
if cn_extras is None:
28+
cn_extras = {}
2729
weights = ControlWeights.default(extras=cn_extras)
2830
return (weights, TimestepKeyframeGroup.default(TimestepKeyframe(control_weights=weights)))
2931

@@ -53,8 +55,10 @@ def INPUT_TYPES(s):
5355
CATEGORY = "Adv-ControlNet 🛂🅐🅒🅝/weights"
5456

5557
def load_weights(self, mask: Tensor, min_base_multiplier: float, max_base_multiplier: float, lock_min=False, lock_max=False,
56-
uncond_multiplier: float=1.0, cn_extras: dict[str]={}):
58+
uncond_multiplier: float=1.0, cn_extras=None):
5759
# normalize mask
60+
if cn_extras is None:
61+
cn_extras = {}
5862
mask = mask.clone()
5963
x_min = 0.0 if lock_min else mask.min()
6064
x_max = 1.0 if lock_max else mask.max()
@@ -86,7 +90,9 @@ def INPUT_TYPES(s):
8690

8791
CATEGORY = "Adv-ControlNet 🛂🅐🅒🅝/weights"
8892

89-
def load_weights(self, base_multiplier, uncond_multiplier: float=1.0, cn_extras: dict[str]={}):
93+
def load_weights(self, base_multiplier, uncond_multiplier: float=1.0, cn_extras=None):
94+
if cn_extras is None:
95+
cn_extras = {}
9096
weights = ControlWeights.universal(base_multiplier=base_multiplier, uncond_multiplier=uncond_multiplier, extras=cn_extras)
9197
return (weights, TimestepKeyframeGroup.default(TimestepKeyframe(control_weights=weights)))
9298

@@ -123,9 +129,11 @@ def INPUT_TYPES(s):
123129

124130
CATEGORY = "Adv-ControlNet 🛂🅐🅒🅝/weights/ControlNet"
125131

126-
def load_weights(self, output_0, output_1, output_2, output_3, output_4, output_5, output_6,
132+
def load_weights(self, output_0, output_1, output_2, output_3, output_4, output_5, output_6,
127133
output_7, output_8, output_9, output_10, output_11, middle_0,
128-
uncond_multiplier: float=1.0, cn_extras: dict[str]={}):
134+
uncond_multiplier: float=1.0, cn_extras=None):
135+
if cn_extras is None:
136+
cn_extras = {}
129137
return CustomControlNetWeightsSD15.load_weights(self,
130138
output_0=output_0, output_1=output_1, output_2=output_2, output_3=output_3,
131139
output_4=output_4, output_5=output_5, output_6=output_6, output_7=output_7,
@@ -166,9 +174,11 @@ def INPUT_TYPES(s):
166174

167175
CATEGORY = "Adv-ControlNet 🛂🅐🅒🅝/weights/ControlNet"
168176

169-
def load_weights(self, output_0, output_1, output_2, output_3, output_4, output_5, output_6,
177+
def load_weights(self, output_0, output_1, output_2, output_3, output_4, output_5, output_6,
170178
output_7, output_8, output_9, output_10, output_11, middle_0,
171-
uncond_multiplier: float=1.0, cn_extras: dict[str]={}):
179+
uncond_multiplier: float=1.0, cn_extras=None):
180+
if cn_extras is None:
181+
cn_extras = {}
172182
weights_output = [output_0, output_1, output_2, output_3, output_4, output_5, output_6,
173183
output_7, output_8, output_9, output_10, output_11]
174184
weights_middle = [middle_0]
@@ -214,10 +224,12 @@ def INPUT_TYPES(s):
214224

215225
CATEGORY = "Adv-ControlNet 🛂🅐🅒🅝/weights/ControlNet"
216226

217-
def load_weights(self, input_0, input_1, input_2, input_3, input_4, input_5, input_6,
227+
def load_weights(self, input_0, input_1, input_2, input_3, input_4, input_5, input_6,
218228
input_7, input_8, input_9, input_10, input_11, input_12, input_13,
219229
input_14, input_15, input_16, input_17, input_18,
220-
uncond_multiplier: float=1.0, cn_extras: dict[str]={}):
230+
uncond_multiplier: float=1.0, cn_extras=None):
231+
if cn_extras is None:
232+
cn_extras = {}
221233
weights_input = [input_0, input_1, input_2, input_3, input_4, input_5,
222234
input_6, input_7, input_8, input_9, input_10, input_11,
223235
input_12, input_13, input_14, input_15, input_16, input_17, input_18]
@@ -249,7 +261,9 @@ def INPUT_TYPES(s):
249261
CATEGORY = "Adv-ControlNet 🛂🅐🅒🅝/weights/T2IAdapter"
250262

251263
def load_weights(self, input_0, input_1, input_2, input_3,
252-
uncond_multiplier: float=1.0, cn_extras: dict[str]={}):
264+
uncond_multiplier: float=1.0, cn_extras=None):
265+
if cn_extras is None:
266+
cn_extras = {}
253267
return CustomT2IAdapterWeights.load_weights(self, input_0=input_0, input_1=input_1, input_2=input_2, input_3=input_3,
254268
uncond_multiplier=uncond_multiplier, cn_extras=cn_extras)
255269

@@ -278,7 +292,9 @@ def INPUT_TYPES(s):
278292
CATEGORY = "Adv-ControlNet 🛂🅐🅒🅝/weights/T2IAdapter"
279293

280294
def load_weights(self, input_0, input_1, input_2, input_3,
281-
uncond_multiplier: float=1.0, cn_extras: dict[str]={}):
295+
uncond_multiplier: float=1.0, cn_extras=None):
296+
if cn_extras is None:
297+
cn_extras = {}
282298
weights = [input_0, input_1, input_2, input_3]
283299
weights = get_properly_arranged_t2i_weights(weights)
284300
weights = ControlWeights.t2iadapter(weights_input=weights, uncond_multiplier=uncond_multiplier, extras=cn_extras)

pyproject.toml

+21
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,24 @@ Repository = "https://github.com/Kosinkadink/ComfyUI-Advanced-ControlNet"
1313
PublisherId = "kosinkadink"
1414
DisplayName = "ComfyUI-Advanced-ControlNet"
1515
Icon = ""
16+
17+
[build-system]
18+
requires = ["setuptools", "wheel"]
19+
build-backend = "setuptools.build_meta"
20+
21+
[tool.setuptools]
22+
packages = [
23+
"comfyui_advanced_controlnet",
24+
"comfyui_advanced_controlnet.adv_control",
25+
]
26+
27+
[tool.setuptools.package-dir]
28+
"comfyui_advanced_controlnet" = "."
29+
"comfyui_advanced_controlnet.adv_control" = "adv_control"
30+
31+
[project.entry-points."comfyui.custom_nodes"]
32+
comfyui_advanced_controlnet = "comfyui_advanced_controlnet.adv_control.nodes"
33+
comfyui_advanced_controlnet_web_directory = "comfyui_advanced_controlnet"
34+
35+
[tool.setuptools.package-data]
36+
"*" = ["**/*.js", "**/*.json"]

0 commit comments

Comments
 (0)