Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
869ac6fd1f | ||
|
|
cb168d64ab | ||
|
|
a89e9e01a6 | ||
|
|
e70b4df9b5 | ||
|
|
af1ef7e441 | ||
|
|
d8738eee2f | ||
|
|
c397c68ca3 | ||
|
|
0e0722ec08 |
@@ -1,35 +0,0 @@
|
||||
import { ComfyApp, app } from "../../scripts/app.js";
|
||||
|
||||
let conflict_check = undefined;
|
||||
|
||||
app.registerExtension({
|
||||
name: "Comfy.impact.comboBoolMigration",
|
||||
|
||||
nodeCreated(node, app) {
|
||||
for(let i in node.widgets) {
|
||||
let widget = node.widgets[i];
|
||||
|
||||
if(conflict_check == undefined) {
|
||||
conflict_check = !!app.extensions.find((ext) => ext.name === "Comfy.comboBoolMigration");
|
||||
}
|
||||
|
||||
if(conflict_check)
|
||||
return;
|
||||
|
||||
if(widget.type == "toggle") {
|
||||
let value = widget.value;
|
||||
|
||||
var v = Object.getOwnPropertyDescriptor(widget, 'value');
|
||||
if(!v) {
|
||||
Object.defineProperty(widget, "value", {
|
||||
set: (value) => {
|
||||
delete widget.value;
|
||||
widget.value = value == true || value == widget.options.on;
|
||||
},
|
||||
get: () => { return value; }
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
+16
-6
@@ -93,7 +93,7 @@ const input_dirty = {};
|
||||
const output_tracking = {};
|
||||
|
||||
function progressExecuteHandler(event) {
|
||||
if(event.detail.output.aux){
|
||||
if(event.detail?.output?.aux){
|
||||
const id = event.detail.node;
|
||||
if(input_tracking.hasOwnProperty(id)) {
|
||||
if(input_tracking.hasOwnProperty(id) && input_tracking[id][0] != event.detail.output.aux[0]) {
|
||||
@@ -273,7 +273,7 @@ app.registerExtension({
|
||||
}
|
||||
else {
|
||||
const node = app.graph.getNodeById(link_info.origin_id);
|
||||
slot_type = node.outputs[link_info.origin_slot].type;
|
||||
slot_type = node.outputs[link_info.origin_slot]?.type;
|
||||
}
|
||||
|
||||
this.inputs[0].type = slot_type;
|
||||
@@ -365,7 +365,11 @@ app.registerExtension({
|
||||
// connect input
|
||||
if(this.inputs[0].type == '*'){
|
||||
const node = app.graph.getNodeById(link_info.origin_id);
|
||||
let origin_type = node.outputs[link_info.origin_slot].type;
|
||||
let origin_type = node.outputs[link_info.origin_slot]?.type;
|
||||
|
||||
if(origin_type==undefined) {
|
||||
return; // fallback
|
||||
}
|
||||
|
||||
if(origin_type == '*') {
|
||||
this.disconnectInput(link_info.target_slot);
|
||||
@@ -755,14 +759,20 @@ app.registerExtension({
|
||||
// mode combo
|
||||
Object.defineProperty(mode_widget, "value", {
|
||||
set: (value) => {
|
||||
node._mode_value = value == true || value == "Populate";
|
||||
populated_text_widget.inputEl.disabled = value == true || value == "Populate";
|
||||
if(value == true)
|
||||
node._mode_value = "populate";
|
||||
else if(value == false)
|
||||
node._mode_value = "fixed";
|
||||
else
|
||||
node._mode_value = value; // combo value
|
||||
|
||||
populated_text_widget.inputEl.disabled = node._mode_value != 'populate';
|
||||
},
|
||||
get: () => {
|
||||
if(node._mode_value != undefined)
|
||||
return node._mode_value;
|
||||
else
|
||||
return true;
|
||||
return 'populate';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import configparser
|
||||
import os
|
||||
|
||||
version_code = [8, 3, 1]
|
||||
version_code = [8, 6]
|
||||
version = f"V{version_code[0]}.{version_code[1]}" + (f'.{version_code[2]}' if len(version_code) > 2 else '')
|
||||
|
||||
dependency_version = 24
|
||||
|
||||
+15
-8
@@ -244,7 +244,8 @@ def enhance_detail(image, model, clip, vae, guide_size, guide_size_for_bbox, max
|
||||
detailer_hook=None,
|
||||
refiner_ratio=None, refiner_model=None, refiner_clip=None, refiner_positive=None,
|
||||
refiner_negative=None, control_net_wrapper=None, cycle=1,
|
||||
inpaint_model=False, noise_mask_feather=0, scheduler_func=None):
|
||||
inpaint_model=False, noise_mask_feather=0, scheduler_func=None,
|
||||
vae_tiled_encode=False, vae_tiled_decode=False):
|
||||
|
||||
if noise_mask is not None:
|
||||
noise_mask = utils.tensor_gaussian_blur_mask(noise_mask, noise_mask_feather)
|
||||
@@ -334,7 +335,7 @@ def enhance_detail(image, model, clip, vae, guide_size, guide_size_for_bbox, max
|
||||
print(f"[Impact Pack] ComfyUI is an outdated version.")
|
||||
positive, negative, latent_image = imc_encode(positive, negative, upscaled_image, vae, noise_mask)
|
||||
else:
|
||||
latent_image = to_latent_image(upscaled_image, vae)
|
||||
latent_image = to_latent_image(upscaled_image, vae, vae_tiled_encode=vae_tiled_encode)
|
||||
if noise_mask is not None:
|
||||
latent_image['noise_mask'] = noise_mask
|
||||
|
||||
@@ -369,12 +370,18 @@ def enhance_detail(image, model, clip, vae, guide_size, guide_size_for_bbox, max
|
||||
refined_latent = detailer_hook.pre_decode(refined_latent)
|
||||
|
||||
# non-latent downscale - latent downscale cause bad quality
|
||||
try:
|
||||
# try to decode image normally
|
||||
refined_image = vae.decode(refined_latent['samples'])
|
||||
except Exception as e:
|
||||
#usually an out-of-memory exception from the decode, so try a tiled approach
|
||||
refined_image = vae.decode_tiled(refined_latent["samples"], tile_x=64, tile_y=64, )
|
||||
start = time.time()
|
||||
if vae_tiled_decode:
|
||||
(refined_image,) = nodes.VAEDecodeTiled().decode(vae, refined_latent, 512) # using default settings
|
||||
print(f"[Impact Pack] vae decoded (tiled) in {time.time() - start:.1f}s")
|
||||
else:
|
||||
try:
|
||||
refined_image = vae.decode(refined_latent['samples'])
|
||||
except Exception as e:
|
||||
# usually an out-of-memory exception from the decode, so try a tiled approach
|
||||
print(f"[Impact Pack] failed after {time.time() - start:.1f}s, doing vae.decode_tiled 64...")
|
||||
refined_image = vae.decode_tiled(refined_latent["samples"], tile_x=64, tile_y=64, )
|
||||
print(f"[Impact Pack] vae decoded in {time.time() - start:.1f}s")
|
||||
|
||||
if detailer_hook is not None:
|
||||
refined_image = detailer_hook.post_decode(refined_image)
|
||||
|
||||
@@ -218,6 +218,8 @@ class DetailerForEach:
|
||||
"inpaint_model": ("BOOLEAN", {"default": False, "label_on": "enabled", "label_off": "disabled"}),
|
||||
"noise_mask_feather": ("INT", {"default": 20, "min": 0, "max": 100, "step": 1}),
|
||||
"scheduler_func_opt": ("SCHEDULER_FUNC",),
|
||||
"tiled_encode": ("BOOLEAN", {"default": False, "label_on": "enabled", "label_off": "disabled"}),
|
||||
"tiled_decode": ("BOOLEAN", {"default": False, "label_on": "enabled", "label_off": "disabled"}),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -234,7 +236,7 @@ class DetailerForEach:
|
||||
def do_detail(image, segs, model, clip, vae, guide_size, guide_size_for_bbox, max_size, seed, steps, cfg, sampler_name, scheduler,
|
||||
positive, negative, denoise, feather, noise_mask, force_inpaint, wildcard_opt=None, detailer_hook=None,
|
||||
refiner_ratio=None, refiner_model=None, refiner_clip=None, refiner_positive=None, refiner_negative=None,
|
||||
cycle=1, inpaint_model=False, noise_mask_feather=0, scheduler_func_opt=None):
|
||||
cycle=1, inpaint_model=False, noise_mask_feather=0, scheduler_func_opt=None, tiled_encode=False, tiled_decode=False):
|
||||
|
||||
if len(image) > 1:
|
||||
raise Exception('[Impact Pack] ERROR: DetailerForEach does not allow image batches.\nPlease refer to https://github.com/ltdrdata/ComfyUI-extension-tutorials/blob/Main/ComfyUI-Impact-Pack/tutorial/batching-detailer.md for more information.')
|
||||
@@ -338,7 +340,8 @@ class DetailerForEach:
|
||||
refiner_clip=refiner_clip, refiner_positive=refiner_positive,
|
||||
refiner_negative=refiner_negative, control_net_wrapper=seg.control_net_wrapper,
|
||||
cycle=cycle, inpaint_model=inpaint_model, noise_mask_feather=noise_mask_feather,
|
||||
scheduler_func=scheduler_func_opt)
|
||||
scheduler_func=scheduler_func_opt, vae_tiled_encode=tiled_encode,
|
||||
vae_tiled_decode=tiled_decode)
|
||||
else:
|
||||
enhanced_image = cropped_image
|
||||
cnet_pils = None
|
||||
@@ -384,13 +387,15 @@ class DetailerForEach:
|
||||
|
||||
def doit(self, image, segs, model, clip, vae, guide_size, guide_size_for, max_size, seed, steps, cfg, sampler_name,
|
||||
scheduler, positive, negative, denoise, feather, noise_mask, force_inpaint, wildcard, cycle=1,
|
||||
detailer_hook=None, inpaint_model=False, noise_mask_feather=0, scheduler_func_opt=None):
|
||||
detailer_hook=None, inpaint_model=False, noise_mask_feather=0, scheduler_func_opt=None,
|
||||
tiled_encode=False, tiled_decode=False):
|
||||
|
||||
enhanced_img, *_ = \
|
||||
DetailerForEach.do_detail(image, segs, model, clip, vae, guide_size, guide_size_for, max_size, seed, steps,
|
||||
cfg, sampler_name, scheduler, positive, negative, denoise, feather, noise_mask,
|
||||
force_inpaint, wildcard, detailer_hook,
|
||||
cycle=cycle, inpaint_model=inpaint_model, noise_mask_feather=noise_mask_feather, scheduler_func_opt=scheduler_func_opt)
|
||||
cycle=cycle, inpaint_model=inpaint_model, noise_mask_feather=noise_mask_feather,
|
||||
scheduler_func_opt=scheduler_func_opt, tiled_encode=tiled_encode, tiled_decode=tiled_decode)
|
||||
|
||||
return (enhanced_img, )
|
||||
|
||||
@@ -425,6 +430,8 @@ class DetailerForEachPipe:
|
||||
"inpaint_model": ("BOOLEAN", {"default": False, "label_on": "enabled", "label_off": "disabled"}),
|
||||
"noise_mask_feather": ("INT", {"default": 20, "min": 0, "max": 100, "step": 1}),
|
||||
"scheduler_func_opt": ("SCHEDULER_FUNC",),
|
||||
"tiled_encode": ("BOOLEAN", {"default": False, "label_on": "enabled", "label_off": "disabled"}),
|
||||
"tiled_decode": ("BOOLEAN", {"default": False, "label_on": "enabled", "label_off": "disabled"}),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -438,7 +445,8 @@ class DetailerForEachPipe:
|
||||
def doit(self, image, segs, guide_size, guide_size_for, max_size, seed, steps, cfg, sampler_name, scheduler,
|
||||
denoise, feather, noise_mask, force_inpaint, basic_pipe, wildcard,
|
||||
refiner_ratio=None, detailer_hook=None, refiner_basic_pipe_opt=None,
|
||||
cycle=1, inpaint_model=False, noise_mask_feather=0, scheduler_func_opt=None):
|
||||
cycle=1, inpaint_model=False, noise_mask_feather=0, scheduler_func_opt=None,
|
||||
tiled_encode=False, tiled_decode=False):
|
||||
|
||||
if len(image) > 1:
|
||||
raise Exception('[Impact Pack] ERROR: DetailerForEach does not allow image batches.\nPlease refer to https://github.com/ltdrdata/ComfyUI-extension-tutorials/blob/Main/ComfyUI-Impact-Pack/tutorial/batching-detailer.md for more information.')
|
||||
@@ -456,7 +464,8 @@ class DetailerForEachPipe:
|
||||
force_inpaint, wildcard, detailer_hook,
|
||||
refiner_ratio=refiner_ratio, refiner_model=refiner_model,
|
||||
refiner_clip=refiner_clip, refiner_positive=refiner_positive, refiner_negative=refiner_negative,
|
||||
cycle=cycle, inpaint_model=inpaint_model, noise_mask_feather=noise_mask_feather, scheduler_func_opt=scheduler_func_opt)
|
||||
cycle=cycle, inpaint_model=inpaint_model, noise_mask_feather=noise_mask_feather, scheduler_func_opt=scheduler_func_opt,
|
||||
tiled_encode=tiled_encode, tiled_decode=tiled_decode)
|
||||
|
||||
# set fallback image
|
||||
if len(cnet_pil_list) == 0:
|
||||
@@ -513,6 +522,8 @@ class FaceDetailer:
|
||||
"inpaint_model": ("BOOLEAN", {"default": False, "label_on": "enabled", "label_off": "disabled"}),
|
||||
"noise_mask_feather": ("INT", {"default": 20, "min": 0, "max": 100, "step": 1}),
|
||||
"scheduler_func_opt": ("SCHEDULER_FUNC",),
|
||||
"tiled_encode": ("BOOLEAN", {"default": False, "label_on": "enabled", "label_off": "disabled"}),
|
||||
"tiled_decode": ("BOOLEAN", {"default": False, "label_on": "enabled", "label_off": "disabled"}),
|
||||
}}
|
||||
|
||||
RETURN_TYPES = ("IMAGE", "IMAGE", "IMAGE", "MASK", "DETAILER_PIPE", "IMAGE")
|
||||
@@ -530,7 +541,7 @@ class FaceDetailer:
|
||||
sam_mask_hint_use_negative, drop_size,
|
||||
bbox_detector, segm_detector=None, sam_model_opt=None, wildcard_opt=None, detailer_hook=None,
|
||||
refiner_ratio=None, refiner_model=None, refiner_clip=None, refiner_positive=None, refiner_negative=None, cycle=1,
|
||||
inpaint_model=False, noise_mask_feather=0, scheduler_func_opt=None):
|
||||
inpaint_model=False, noise_mask_feather=0, scheduler_func_opt=None, tiled_encode=False, tiled_decode=False):
|
||||
|
||||
# make default prompt as 'face' if empty prompt for CLIPSeg
|
||||
bbox_detector.setAux('face')
|
||||
@@ -562,7 +573,8 @@ class FaceDetailer:
|
||||
refiner_ratio=refiner_ratio, refiner_model=refiner_model,
|
||||
refiner_clip=refiner_clip, refiner_positive=refiner_positive,
|
||||
refiner_negative=refiner_negative,
|
||||
cycle=cycle, inpaint_model=inpaint_model, noise_mask_feather=noise_mask_feather, scheduler_func_opt=scheduler_func_opt)
|
||||
cycle=cycle, inpaint_model=inpaint_model, noise_mask_feather=noise_mask_feather,
|
||||
scheduler_func_opt=scheduler_func_opt, tiled_encode=tiled_encode, tiled_decode=tiled_decode)
|
||||
else:
|
||||
enhanced_img = image
|
||||
cropped_enhanced = []
|
||||
@@ -588,7 +600,8 @@ class FaceDetailer:
|
||||
bbox_threshold, bbox_dilation, bbox_crop_factor,
|
||||
sam_detection_hint, sam_dilation, sam_threshold, sam_bbox_expansion, sam_mask_hint_threshold,
|
||||
sam_mask_hint_use_negative, drop_size, bbox_detector, wildcard, cycle=1,
|
||||
sam_model_opt=None, segm_detector_opt=None, detailer_hook=None, inpaint_model=False, noise_mask_feather=0, scheduler_func_opt=None):
|
||||
sam_model_opt=None, segm_detector_opt=None, detailer_hook=None, inpaint_model=False, noise_mask_feather=0,
|
||||
scheduler_func_opt=None, tiled_encode=False, tiled_decode=False):
|
||||
|
||||
result_img = None
|
||||
result_mask = None
|
||||
@@ -606,7 +619,8 @@ class FaceDetailer:
|
||||
bbox_threshold, bbox_dilation, bbox_crop_factor,
|
||||
sam_detection_hint, sam_dilation, sam_threshold, sam_bbox_expansion, sam_mask_hint_threshold,
|
||||
sam_mask_hint_use_negative, drop_size, bbox_detector, segm_detector_opt, sam_model_opt, wildcard, detailer_hook,
|
||||
cycle=cycle, inpaint_model=inpaint_model, noise_mask_feather=noise_mask_feather, scheduler_func_opt=scheduler_func_opt)
|
||||
cycle=cycle, inpaint_model=inpaint_model, noise_mask_feather=noise_mask_feather, scheduler_func_opt=scheduler_func_opt,
|
||||
tiled_encode=tiled_encode, tiled_decode=tiled_decode)
|
||||
|
||||
result_img = torch.cat((result_img, enhanced_img), dim=0) if result_img is not None else enhanced_img
|
||||
result_mask = torch.cat((result_mask, mask), dim=0) if result_mask is not None else mask
|
||||
@@ -1381,6 +1395,8 @@ class FaceDetailerPipe:
|
||||
"inpaint_model": ("BOOLEAN", {"default": False, "label_on": "enabled", "label_off": "disabled"}),
|
||||
"noise_mask_feather": ("INT", {"default": 20, "min": 0, "max": 100, "step": 1}),
|
||||
"scheduler_func_opt": ("SCHEDULER_FUNC",),
|
||||
"tiled_encode": ("BOOLEAN", {"default": False, "label_on": "enabled", "label_off": "disabled"}),
|
||||
"tiled_decode": ("BOOLEAN", {"default": False, "label_on": "enabled", "label_off": "disabled"}),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1395,7 +1411,8 @@ class FaceDetailerPipe:
|
||||
denoise, feather, noise_mask, force_inpaint, bbox_threshold, bbox_dilation, bbox_crop_factor,
|
||||
sam_detection_hint, sam_dilation, sam_threshold, sam_bbox_expansion,
|
||||
sam_mask_hint_threshold, sam_mask_hint_use_negative, drop_size, refiner_ratio=None,
|
||||
cycle=1, inpaint_model=False, noise_mask_feather=0, scheduler_func_opt=None):
|
||||
cycle=1, inpaint_model=False, noise_mask_feather=0, scheduler_func_opt=None,
|
||||
tiled_encode=False, tiled_decode=False):
|
||||
|
||||
result_img = None
|
||||
result_mask = None
|
||||
@@ -1418,7 +1435,8 @@ class FaceDetailerPipe:
|
||||
sam_mask_hint_use_negative, drop_size, bbox_detector, segm_detector, sam_model_opt, wildcard, detailer_hook,
|
||||
refiner_ratio=refiner_ratio, refiner_model=refiner_model,
|
||||
refiner_clip=refiner_clip, refiner_positive=refiner_positive, refiner_negative=refiner_negative,
|
||||
cycle=cycle, inpaint_model=inpaint_model, noise_mask_feather=noise_mask_feather, scheduler_func_opt=scheduler_func_opt)
|
||||
cycle=cycle, inpaint_model=inpaint_model, noise_mask_feather=noise_mask_feather, scheduler_func_opt=scheduler_func_opt,
|
||||
tiled_encode=tiled_encode, tiled_decode=tiled_decode)
|
||||
|
||||
result_img = torch.cat((result_img, enhanced_img), dim=0) if result_img is not None else enhanced_img
|
||||
result_mask = torch.cat((result_mask, mask), dim=0) if result_mask is not None else mask
|
||||
@@ -1552,7 +1570,7 @@ class DetailerForEachTest(DetailerForEach):
|
||||
|
||||
def doit(self, image, segs, model, clip, vae, guide_size, guide_size_for, max_size, seed, steps, cfg, sampler_name,
|
||||
scheduler, positive, negative, denoise, feather, noise_mask, force_inpaint, wildcard, detailer_hook=None,
|
||||
cycle=1, inpaint_model=False, noise_mask_feather=0, scheduler_func_opt=None):
|
||||
cycle=1, inpaint_model=False, noise_mask_feather=0, scheduler_func_opt=None, tiled_encode=False, tiled_decode=False):
|
||||
|
||||
if len(image) > 1:
|
||||
raise Exception('[Impact Pack] ERROR: DetailerForEach does not allow image batches.\nPlease refer to https://github.com/ltdrdata/ComfyUI-extension-tutorials/blob/Main/ComfyUI-Impact-Pack/tutorial/batching-detailer.md for more information.')
|
||||
@@ -1561,7 +1579,8 @@ class DetailerForEachTest(DetailerForEach):
|
||||
DetailerForEach.do_detail(image, segs, model, clip, vae, guide_size, guide_size_for, max_size, seed, steps,
|
||||
cfg, sampler_name, scheduler, positive, negative, denoise, feather, noise_mask,
|
||||
force_inpaint, wildcard, detailer_hook,
|
||||
cycle=cycle, inpaint_model=inpaint_model, noise_mask_feather=noise_mask_feather, scheduler_func_opt=scheduler_func_opt)
|
||||
cycle=cycle, inpaint_model=inpaint_model, noise_mask_feather=noise_mask_feather,
|
||||
scheduler_func_opt=scheduler_func_opt, tiled_encode=tiled_encode, tiled_decode=tiled_decode)
|
||||
|
||||
# set fallback image
|
||||
if len(cropped) == 0:
|
||||
@@ -1590,7 +1609,8 @@ class DetailerForEachTestPipe(DetailerForEachPipe):
|
||||
|
||||
def doit(self, image, segs, guide_size, guide_size_for, max_size, seed, steps, cfg, sampler_name, scheduler,
|
||||
denoise, feather, noise_mask, force_inpaint, basic_pipe, wildcard, cycle=1,
|
||||
refiner_ratio=None, detailer_hook=None, refiner_basic_pipe_opt=None, inpaint_model=False, noise_mask_feather=0, scheduler_func_opt=None):
|
||||
refiner_ratio=None, detailer_hook=None, refiner_basic_pipe_opt=None, inpaint_model=False, noise_mask_feather=0,
|
||||
scheduler_func_opt=None, tiled_encode=False, tiled_decode=False):
|
||||
|
||||
if len(image) > 1:
|
||||
raise Exception('[Impact Pack] ERROR: DetailerForEach does not allow image batches.\nPlease refer to https://github.com/ltdrdata/ComfyUI-extension-tutorials/blob/Main/ComfyUI-Impact-Pack/tutorial/batching-detailer.md for more information.')
|
||||
@@ -1609,7 +1629,8 @@ class DetailerForEachTestPipe(DetailerForEachPipe):
|
||||
refiner_ratio=refiner_ratio, refiner_model=refiner_model,
|
||||
refiner_clip=refiner_clip, refiner_positive=refiner_positive,
|
||||
refiner_negative=refiner_negative,
|
||||
cycle=cycle, inpaint_model=inpaint_model, noise_mask_feather=noise_mask_feather, scheduler_func_opt=scheduler_func_opt)
|
||||
cycle=cycle, inpaint_model=inpaint_model, noise_mask_feather=noise_mask_feather,
|
||||
scheduler_func_opt=scheduler_func_opt, tiled_encode=tiled_encode, tiled_decode=tiled_decode)
|
||||
|
||||
# set fallback image
|
||||
if len(cropped) == 0:
|
||||
@@ -2322,7 +2343,11 @@ class ImpactWildcardProcessor:
|
||||
return {"required": {
|
||||
"wildcard_text": ("STRING", {"multiline": True, "dynamicPrompts": False, "tooltip": "Enter a prompt using wildcard syntax."}),
|
||||
"populated_text": ("STRING", {"multiline": True, "dynamicPrompts": False, "tooltip": "The actual value passed during the execution of 'ImpactWildcardProcessor' is what is shown here. The behavior varies slightly depending on the mode. Wildcard syntax can also be used in 'populated_text'."}),
|
||||
"mode": ("BOOLEAN", {"default": True, "label_on": "Populate", "label_off": "Fixed", "tooltip": "Populate: Before running the workflow, it overwrites the existing value of 'populated_text' with the prompt processed from 'wildcard_text'. In this mode, 'populated_text' cannot be edited.\nFixed: Ignores wildcard_text and keeps 'populated_text' as is. You can edit 'populated_text' in this mode."}),
|
||||
"mode": (["populate", "fixed", "reproduce"], {"default": "populate", "tooltip":
|
||||
"populate: Before running the workflow, it overwrites the existing value of 'populated_text' with the prompt processed from 'wildcard_text'. In this mode, 'populated_text' cannot be edited.\n"
|
||||
"fixed: Ignores wildcard_text and keeps 'populated_text' as is. You can edit 'populated_text' in this mode.\n"
|
||||
"reproduce: This mode operates as 'fixed' mode only once for reproduction, and then it switches to 'populate' mode."
|
||||
}),
|
||||
"seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff, "tooltip": "Determines the random seed to be used for wildcard processing."}),
|
||||
"Select to add Wildcard": (["Select the Wildcard to add to the text"],),
|
||||
},
|
||||
@@ -2331,7 +2356,7 @@ class ImpactWildcardProcessor:
|
||||
CATEGORY = "ImpactPack/Prompt"
|
||||
|
||||
DESCRIPTION = ("The 'ImpactWildcardProcessor' processes text prompts written in wildcard syntax and outputs the processed text prompt.\n\n"
|
||||
"TIP: Before the workflow is executed, the processing result of 'wildcard_text' is displayed in 'populated_text', and the populated text is saved along with the workflow. If you want to use a seed converted as input, write the prompt directly in 'populated_text' instead of 'wildcard_text', and set the mode to 'Fixed'.")
|
||||
"TIP: Before the workflow is executed, the processing result of 'wildcard_text' is displayed in 'populated_text', and the populated text is saved along with the workflow. If you want to use a seed converted as input, write the prompt directly in 'populated_text' instead of 'wildcard_text', and set the mode to 'fixed'.")
|
||||
|
||||
RETURN_TYPES = ("STRING", )
|
||||
FUNCTION = "doit"
|
||||
@@ -2353,8 +2378,10 @@ class ImpactWildcardEncode:
|
||||
"clip": ("CLIP",),
|
||||
"wildcard_text": ("STRING", {"multiline": True, "dynamicPrompts": False, "tooltip": "Enter a prompt using wildcard syntax."}),
|
||||
"populated_text": ("STRING", {"multiline": True, "dynamicPrompts": False, "tooltip": "The actual value passed during the execution of 'ImpactWildcardEncode' is what is shown here. The behavior varies slightly depending on the mode. Wildcard syntax can also be used in 'populated_text'."}),
|
||||
"mode": ("BOOLEAN", {"default": True, "label_on": "Populate", "label_off": "Fixed", "tooltip": "Populate: Before running the workflow, it overwrites the existing value of 'populated_text' with the prompt processed from 'wildcard_text'. In this mode, 'populated_text' cannot be edited.\n"
|
||||
"Fixed: Ignores wildcard_text and keeps 'populated_text' as is. You can edit 'populated_text' in this mode."}),
|
||||
"mode": (["populate", "fixed", "reproduce"], {"tooltip":
|
||||
"populate: Before running the workflow, it overwrites the existing value of 'populated_text' with the prompt processed from 'wildcard_text'. In this mode, 'populated_text' cannot be edited.\n"
|
||||
"fixed: Ignores wildcard_text and keeps 'populated_text' as is. You can edit 'populated_text' in this mode\n."
|
||||
"reproduce: This mode operates as 'fixed' mode only once for reproduction, and then it switches to 'populate' mode."}),
|
||||
"Select to add LoRA": (["Select the LoRA to add to the text"] + folder_paths.get_filename_list("loras"), ),
|
||||
"Select to add Wildcard": (["Select the Wildcard to add to the text"], ),
|
||||
"seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff, "tooltip": "Determines the random seed to be used for wildcard processing."}),
|
||||
@@ -2364,7 +2391,7 @@ class ImpactWildcardEncode:
|
||||
CATEGORY = "ImpactPack/Prompt"
|
||||
|
||||
DESCRIPTION = ("The 'ImpactWildcardEncode' node processes text prompts written in wildcard syntax and outputs them as conditioning. It also supports LoRA syntax, with the applied LoRA reflected in the model's output.\n\n"
|
||||
"TIP1: Before the workflow is executed, the processing result of 'wildcard_text' is displayed in 'populated_text', and the populated text is saved along with the workflow. If you want to use a seed converted as input, write the prompt directly in 'populated_text' instead of 'wildcard_text', and set the mode to 'Fixed'.\n"
|
||||
"TIP1: Before the workflow is executed, the processing result of 'wildcard_text' is displayed in 'populated_text', and the populated text is saved along with the workflow. If you want to use a seed converted as input, write the prompt directly in 'populated_text' instead of 'wildcard_text', and set the mode to 'fixed'.\n"
|
||||
"TIP2: If the 'Inspire Pack' is installed, LBW(LoRA Block Weight) syntax can also be applied.")
|
||||
|
||||
RETURN_TYPES = ("MODEL", "CLIP", "CONDITIONING", "STRING")
|
||||
|
||||
@@ -78,9 +78,13 @@ async def sam_prepare(request):
|
||||
if data['sam_model_name'] == 'auto':
|
||||
model_name = impact.config.get_config()['sam_editor_model']
|
||||
|
||||
model_name = os.path.join(impact_pack.model_path, "sams", model_name)
|
||||
model_path = folder_paths.get_full_path("sams", model_name)
|
||||
|
||||
logging.info(f"[Impact Pack] Loading SAM model '{impact_pack.model_path}'")
|
||||
if model_path is None:
|
||||
logging.error(f"[Impact Pack] The '{model_name}' model file cannot be found in any sams model path.")
|
||||
return web.Response(status=400)
|
||||
|
||||
logging.info(f"[Impact Pack] Loading SAM model '{model_path}'")
|
||||
|
||||
filename, image_dir = folder_paths.annotated_filepath(data["filename"])
|
||||
|
||||
@@ -93,7 +97,7 @@ async def sam_prepare(request):
|
||||
if image_dir is None:
|
||||
return web.Response(status=400)
|
||||
|
||||
thread = threading.Thread(target=async_prepare_sam, args=(image_dir, model_name, filename,))
|
||||
thread = threading.Thread(target=async_prepare_sam, args=(image_dir, model_path, filename,))
|
||||
thread.start()
|
||||
|
||||
logging.info("[Impact Pack] SAM model loaded. ")
|
||||
@@ -478,7 +482,17 @@ def onprompt_populate_wildcards(json_data):
|
||||
for k, v in prompt.items():
|
||||
if 'class_type' in v and (v['class_type'] == 'ImpactWildcardEncode' or v['class_type'] == 'ImpactWildcardProcessor'):
|
||||
inputs = v['inputs']
|
||||
if inputs['mode'] and isinstance(inputs['populated_text'], str):
|
||||
|
||||
# legacy adapter
|
||||
if isinstance(inputs['mode'], bool):
|
||||
if inputs['mode']:
|
||||
new_mode = 'populate'
|
||||
else:
|
||||
new_mode = 'fixed'
|
||||
|
||||
inputs['mode'] = new_mode
|
||||
|
||||
if inputs['mode'] == 'populate' and isinstance(inputs['populated_text'], str):
|
||||
if isinstance(inputs['seed'], list):
|
||||
try:
|
||||
input_node = prompt[inputs['seed'][0]]
|
||||
@@ -499,17 +513,22 @@ def onprompt_populate_wildcards(json_data):
|
||||
input_seed = int(inputs['seed'])
|
||||
|
||||
inputs['populated_text'] = wildcards.process(inputs['wildcard_text'], input_seed)
|
||||
inputs['mode'] = False
|
||||
inputs['mode'] = 'reproduce'
|
||||
|
||||
PromptServer.instance.send_sync("impact-node-feedback", {"node_id": k, "widget_name": "populated_text", "type": "STRING", "value": inputs['populated_text']})
|
||||
updated_widget_values[k] = inputs['populated_text']
|
||||
|
||||
if inputs['mode'] == 'reproduce':
|
||||
PromptServer.instance.send_sync("impact-node-feedback", {"node_id": k, "widget_name": "mode", "type": "STRING", "value": 'populate'})
|
||||
|
||||
|
||||
|
||||
if 'extra_data' in json_data and 'extra_pnginfo' in json_data['extra_data']:
|
||||
for node in json_data['extra_data']['extra_pnginfo']['workflow']['nodes']:
|
||||
key = str(node['id'])
|
||||
if key in updated_widget_values:
|
||||
node['widgets_values'][1] = updated_widget_values[key]
|
||||
node['widgets_values'][2] = False
|
||||
node['widgets_values'][2] = 'reproduce'
|
||||
|
||||
|
||||
def onprompt_for_remote(json_data):
|
||||
|
||||
+10
-3
@@ -7,6 +7,7 @@ import nodes
|
||||
from . import config
|
||||
from PIL import Image
|
||||
import comfy
|
||||
import time
|
||||
|
||||
|
||||
class TensorBatchBuilder:
|
||||
@@ -501,15 +502,21 @@ def crop_image(image, crop_region):
|
||||
return crop_tensor4(image, crop_region)
|
||||
|
||||
|
||||
def to_latent_image(pixels, vae):
|
||||
def to_latent_image(pixels, vae, vae_tiled_encode=False):
|
||||
x = pixels.shape[1]
|
||||
y = pixels.shape[2]
|
||||
if pixels.shape[1] != x or pixels.shape[2] != y:
|
||||
pixels = pixels[:, :x, :y, :]
|
||||
|
||||
vae_encode = nodes.VAEEncode()
|
||||
start = time.time()
|
||||
if vae_tiled_encode:
|
||||
encoded = nodes.VAEEncodeTiled().encode(vae, pixels, 512, overlap=64)[0] # using default settings
|
||||
print(f"[Impact Pack] vae encoded (tiled) in {time.time() - start:.1f}s")
|
||||
else:
|
||||
encoded = nodes.VAEEncode().encode(vae, pixels)[0]
|
||||
print(f"[Impact Pack] vae encoded in {time.time() - start:.1f}s")
|
||||
|
||||
return vae_encode.encode(vae, pixels)[0]
|
||||
return encoded
|
||||
|
||||
|
||||
def empty_pil_tensor(w=64, h=64):
|
||||
|
||||
@@ -237,7 +237,23 @@ def process(text, seed=None):
|
||||
keyword = match.lower()
|
||||
keyword = wildcard_normalize(keyword)
|
||||
if keyword in local_wildcard_dict:
|
||||
replacement = random_gen.choice(local_wildcard_dict[keyword])
|
||||
# look for adjusted probability
|
||||
adjusted_probabilities = []
|
||||
total_prob = 0
|
||||
options=local_wildcard_dict[keyword]
|
||||
for option in options:
|
||||
parts = option.split('::', 1)
|
||||
if len(parts) == 2 and is_numeric_string(parts[0].strip()):
|
||||
config_value = float(parts[0].strip())
|
||||
else:
|
||||
config_value = 1 # Default value if no configuration is provided
|
||||
|
||||
adjusted_probabilities.append(config_value)
|
||||
total_prob += config_value
|
||||
|
||||
normalized_probabilities = [prob / total_prob for prob in adjusted_probabilities]
|
||||
selected_item = random_gen.choice(options, p=normalized_probabilities, replace=False)
|
||||
replacement = re.sub(r'^\s*[0-9.]+::', '', selected_item, 1)
|
||||
replacements_found = True
|
||||
string = string.replace(f"__{match}__", replacement, 1)
|
||||
elif '*' in keyword:
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
[project]
|
||||
name = "comfyui-impact-pack"
|
||||
description = "This node pack offers various detector nodes and detailer nodes that allow you to configure a workflow that automatically enhances facial details. And provide iterative upscaler."
|
||||
version = "8.3.1"
|
||||
version = "8.6"
|
||||
license = { file = "LICENSE.txt" }
|
||||
dependencies = ["segment-anything", "scikit-image", "piexif", "transformers", "opencv-python-headless", "GitPython", "scipy>=1.11.4"]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user