From 962eead137cfaf0a29d0050ec6eec08776fd15f9 Mon Sep 17 00:00:00 2001 From: "Dr.Lt.Data" Date: Wed, 2 Aug 2023 09:10:03 +0900 Subject: [PATCH] improve: ImpactWildcardProcessor supports PrimitiveNode add: SEGSConcat --- README.md | 2 + __init__.py | 5 ++ js/comboBoolMigration.js | 31 ++++++++ js/impact-pack.js | 28 +++++-- modules/impact/config.py | 2 +- modules/impact/core.py | 4 +- modules/impact/impact_pack.py | 134 ++++++++++++++++++++-------------- 7 files changed, 143 insertions(+), 63 deletions(-) create mode 100644 js/comboBoolMigration.js diff --git a/README.md b/README.md index 4147a59..9417261 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,8 @@ This custom node helps to conveniently enhance images through Detector, Detailer * This option is used to preview the improved image through `SEGSDetailer` before merging it into the original. Prior to going through ```SEGSDetailer```, SEGS only contains mask information without image information. If fallback_image_opt is connected to the original image, SEGS without image information will generate a preview using the original image. However, if SEGS already contains image information, fallback_image_opt will be ignored. * SEGSToImageList - Convert SEGS To Image List * SEGS Filter (label) - This node filters SEGS based on the label of the detected areas +* SEGSConcat - Concatenate segs1 and segs2. If source shape of segs1 and segs2 are different then segs2 will be ignored. +* * Pipe nodes * ToDetailerPipe, FromDetailerPipe - These nodes are used to bundle multiple inputs used in the detailer, such as models and vae, ..., into a single DETAILER_PIPE or extract the elements that are bundled in the DETAILER_PIPE. * ToBasicPipe, FromBasicPipe - These nodes are used to bundle model, clip, vae, positive conditioning, and negative conditioning into a single BASIC_PIPE, or extract each element from the BASIC_PIPE. diff --git a/__init__.py b/__init__.py index f6bcf14..bcc0ef8 100644 --- a/__init__.py +++ b/__init__.py @@ -73,6 +73,9 @@ def setup_js(): js_src_path = os.path.join(impact_path, "js", "impact-sam-editor.js") shutil.copy(js_src_path, js_dest_path) + + js_src_path = os.path.join(impact_path, "js", "comboBoolMigration.js") + shutil.copy(js_src_path, js_dest_path) setup_js() @@ -171,6 +174,7 @@ NODE_CLASS_MAPPINGS = { "SEGSPaste": SEGSPaste, "SEGSPreview": SEGSPreview, "SEGSToImageList": SEGSToImageList, + "ImpactSEGSConcat": SEGSConcat, # "SEGPick": SEGPick, # "SEGEdit": SEGEdit, @@ -229,6 +233,7 @@ NODE_DISPLAY_NAME_MAPPINGS = { "ImpactKSamplerBasicPipe": "KSampler (pipe)", "ImpactKSamplerAdvancedBasicPipe": "KSampler (Advanced/pipe)", "ImpactSEGSLabelFilter": "SEGS Filter (label)", + "ImpactSEGSConcat": "SEGS Concat", "PreviewBridge": "Preview Bridge", "ImageSender": "Image Sender", diff --git a/js/comboBoolMigration.js b/js/comboBoolMigration.js new file mode 100644 index 0000000..fe1ee2f --- /dev/null +++ b/js/comboBoolMigration.js @@ -0,0 +1,31 @@ +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; + Object.defineProperty(widget, "value", { + set: (value) => { + delete widget.value; + widget.value = value == true || value == widget.options.on; + }, + get: () => { return value; } + }); + } + } + } +}); diff --git a/js/impact-pack.js b/js/impact-pack.js index 65a8496..2915b20 100644 --- a/js/impact-pack.js +++ b/js/impact-pack.js @@ -223,14 +223,16 @@ app.registerExtension({ let force_serializeValue = async (n,i) => { - if(n.widgets_values[2] == "Fixed") { + if(node.widgets[2].value == "Fixed") { return node.widgets[1].value; } else { - let response = await fetch(`/impact/wildcards`, { + let wildcard_text = await node.widgets[0].serializeValue(); + + let response = await api.fetchApi(`/impact/wildcards`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({text: n.widgets_values[0]}) + body: JSON.stringify({text: wildcard_text}) }); let populated = await response.json(); @@ -246,12 +248,12 @@ app.registerExtension({ // mode combo Object.defineProperty(node.widgets[2], "value", { set: (value) => { - this._value = value; + node._mode_value = value; node.widgets[1].inputEl.disabled = value != "Fixed"; }, get: () => { - if(this._value) - return this._value; + if(node._mode_value) + return node._mode_value; else return "Populate"; } @@ -269,7 +271,19 @@ app.registerExtension({ } }); - node.widgets[0].serializeValue = (n,i) => { return n.widgets_values[i]; }; + node.widgets[0].serializeValue = (n,i) => { + let link_id = node.inputs.find(x => x.name=="wildcard_text")?.link; + if(link_id != undefined) { + let link = app.graph.links[link_id]; + let input_widget = app.graph._nodes_by_id[link.origin_id].widgets[link.origin_slot]; + if(input_widget.type == "customtext") { + return input_widget.value; + } + } + else { + return node.widgets[0].value; + } + }; node.widgets[1].serializeValue = force_serializeValue; } diff --git a/modules/impact/config.py b/modules/impact/config.py index 81710e0..4865bf8 100644 --- a/modules/impact/config.py +++ b/modules/impact/config.py @@ -2,7 +2,7 @@ import configparser import os -version = "V3.4.1" +version = "V3.6" dependency_version = 9 diff --git a/modules/impact/core.py b/modules/impact/core.py index 573e566..6350fe4 100644 --- a/modules/impact/core.py +++ b/modules/impact/core.py @@ -108,7 +108,7 @@ def gen_negative_hints(w, h, x1, y1, x2, y2): return npoints, nplabs -def enhance_detail(image, model, clip, vae, guide_size, guide_size_for, max_size, bbox, seed, steps, cfg, sampler_name, +def enhance_detail(image, model, clip, vae, guide_size, guide_size_for_bbox, max_size, bbox, seed, steps, cfg, sampler_name, scheduler, positive, negative, denoise, noise_mask, force_inpaint, wildcard_opt=None): if wildcard_opt is not None and wildcard_opt != "": model, positive = wildcards.process_with_loras(wildcard_opt, model, clip) @@ -124,7 +124,7 @@ def enhance_detail(image, model, clip, vae, guide_size, guide_size_for, max_size print(f"Detailer: segment skip (enough big)") return None - if guide_size_for == "bbox": + if guide_size_for_bbox: # == "bbox" # Scale up based on the smaller dimension between width and height. upscale = guide_size / min(bbox_w, bbox_h) else: diff --git a/modules/impact/impact_pack.py b/modules/impact/impact_pack.py index 4e72c43..a13f69b 100644 --- a/modules/impact/impact_pack.py +++ b/modules/impact/impact_pack.py @@ -151,7 +151,7 @@ class SEGSDetailer: "image": ("IMAGE", ), "segs": ("SEGS", ), "guide_size": ("FLOAT", {"default": 256, "min": 64, "max": nodes.MAX_RESOLUTION, "step": 8}), - "guide_size_for": (["bbox", "crop_region"],), + "guide_size_for": ("BOOLEAN", {"default": True, "label_on": "bbox", "label_off": "crop_region"}), "max_size": ("FLOAT", {"default": 768, "min": 64, "max": nodes.MAX_RESOLUTION, "step": 8}), "seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}), "steps": ("INT", {"default": 20, "min": 1, "max": 10000}), @@ -159,8 +159,8 @@ class SEGSDetailer: "sampler_name": (comfy.samplers.KSampler.SAMPLERS,), "scheduler": (comfy.samplers.KSampler.SCHEDULERS,), "denoise": ("FLOAT", {"default": 0.5, "min": 0.0001, "max": 1.0, "step": 0.01}), - "noise_mask": (["enabled", "disabled"], ), - "force_inpaint": (["disabled", "enabled"], ), + "noise_mask": ("BOOLEAN", {"default": True, "label_on": "enabled", "label_off": "disabled"}), + "force_inpaint": ("BOOLEAN", {"default": False, "label_on": "enabled", "label_off": "disabled"}), "basic_pipe": ("BASIC_PIPE",), }, } @@ -188,14 +188,14 @@ class SEGSDetailer: new_segs.append(seg) continue - if noise_mask == "enabled": + if noise_mask: cropped_mask = seg.cropped_mask else: cropped_mask = None enhanced_pil = core.enhance_detail(cropped_image, model, clip, vae, guide_size, guide_size_for, max_size, seg.bbox, seed, steps, cfg, sampler_name, scheduler, - positive, negative, denoise, cropped_mask, force_inpaint == "enabled") + positive, negative, denoise, cropped_mask, force_inpaint) new_seg = SEG(enhanced_pil, seg.cropped_mask, seg.confidence, seg.crop_region, seg.bbox, seg.label) new_segs.append(new_seg) @@ -305,8 +305,6 @@ class SEGSLabelFilter: CATEGORY = "ImpactPack/Util" - OUTPUT_NODE = True - def doit(self, segs, preset, labels): labels = labels.split(',') labels = set([label.strip() for label in labels]) @@ -339,8 +337,6 @@ class SEGSToImageList: CATEGORY = "ImpactPack/Util" - OUTPUT_NODE = True - def doit(self, segs, fallback_image_opt=None): results = list() @@ -361,6 +357,28 @@ class SEGSToImageList: return (results,) +class SEGSConcat: + @classmethod + def INPUT_TYPES(s): + return {"required": { + "segs1": ("SEGS", ), + "segs2": ("SEGS", ), + }, + } + + RETURN_TYPES = ("SEGS",) + FUNCTION = "doit" + + CATEGORY = "ImpactPack/Util" + + def doit(self, segs1, segs2): + if segs1[0] == segs2[0]: + return ((segs1[0], segs1[1] + segs2[1]), ) + else: + print(f"ERROR: source shape of 'segs1' and 'segs2' are different. 'segs2' will be ignored") + return (segs1, ) + + class DetailerForEach: @classmethod def INPUT_TYPES(s): @@ -371,7 +389,7 @@ class DetailerForEach: "clip": ("CLIP",), "vae": ("VAE",), "guide_size": ("FLOAT", {"default": 256, "min": 64, "max": nodes.MAX_RESOLUTION, "step": 8}), - "guide_size_for": (["bbox", "crop_region"],), + "guide_size_for": ("BOOLEAN", {"default": True, "label_on": "bbox", "label_off": "crop_region"}), "max_size": ("FLOAT", {"default": 768, "min": 64, "max": nodes.MAX_RESOLUTION, "step": 8}), "seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}), "steps": ("INT", {"default": 20, "min": 1, "max": 10000}), @@ -382,8 +400,8 @@ class DetailerForEach: "negative": ("CONDITIONING",), "denoise": ("FLOAT", {"default": 0.5, "min": 0.0001, "max": 1.0, "step": 0.01}), "feather": ("INT", {"default": 5, "min": 0, "max": 100, "step": 1}), - "noise_mask": (["enabled", "disabled"], ), - "force_inpaint": (["disabled", "enabled"], ), + "noise_mask": ("BOOLEAN", {"default": True, "label_on": "enabled", "label_off": "disabled"}), + "force_inpaint": ("BOOLEAN", {"default": True, "label_on": "enabled", "label_off": "disabled"}), }, } @@ -393,7 +411,7 @@ class DetailerForEach: CATEGORY = "ImpactPack/Detailer" @staticmethod - def do_detail(image, segs, model, clip, vae, guide_size, guide_size_for, max_size, seed, steps, cfg, sampler_name, scheduler, + 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): image_pil = tensor2pil(image).convert('RGBA') @@ -413,14 +431,14 @@ class DetailerForEach: print(f"Detailer: segment skip [empty mask]") continue - if noise_mask == "enabled": + if noise_mask: cropped_mask = seg.cropped_mask else: cropped_mask = None - enhanced_pil = core.enhance_detail(cropped_image, model, clip, vae, guide_size, guide_size_for, max_size, + enhanced_pil = core.enhance_detail(cropped_image, model, clip, vae, guide_size, guide_size_for_bbox, max_size, seg.bbox, seed, steps, cfg, sampler_name, scheduler, - positive, negative, denoise, cropped_mask, force_inpaint == "enabled", wildcard_opt) + positive, negative, denoise, cropped_mask, force_inpaint, wildcard_opt) if not (enhanced_pil is None): # don't latent composite-> converting to latent caused poor quality @@ -466,7 +484,7 @@ class DetailerForEachPipe: "image": ("IMAGE", ), "segs": ("SEGS", ), "guide_size": ("FLOAT", {"default": 256, "min": 64, "max": nodes.MAX_RESOLUTION, "step": 8}), - "guide_size_for": (["bbox", "crop_region"],), + "guide_size_for": ("BOOLEAN", {"default": True, "label_on": "bbox", "label_off": "crop_region"}), "max_size": ("FLOAT", {"default": 768, "min": 64, "max": nodes.MAX_RESOLUTION, "step": 8}), "seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}), "steps": ("INT", {"default": 20, "min": 1, "max": 10000}), @@ -475,8 +493,8 @@ class DetailerForEachPipe: "scheduler": (comfy.samplers.KSampler.SCHEDULERS,), "denoise": ("FLOAT", {"default": 0.5, "min": 0.0001, "max": 1.0, "step": 0.01}), "feather": ("INT", {"default": 5, "min": 0, "max": 100, "step": 1}), - "noise_mask": (["enabled", "disabled"], ), - "force_inpaint": (["disabled", "enabled"], ), + "noise_mask": ("BOOLEAN", {"default": True, "label_on": "enabled", "label_off": "disabled"}), + "force_inpaint": ("BOOLEAN", {"default": True, "label_on": "enabled", "label_off": "disabled"}), "basic_pipe": ("BASIC_PIPE", ) }, } @@ -752,7 +770,7 @@ class FaceDetailer: "clip": ("CLIP",), "vae": ("VAE",), "guide_size": ("FLOAT", {"default": 256, "min": 64, "max": nodes.MAX_RESOLUTION, "step": 8}), - "guide_size_for": (["bbox", "crop_region"],), + "guide_size_for": ("BOOLEAN", {"default": True, "label_on": "bbox", "label_off": "crop_region"}), "max_size": ("FLOAT", {"default": 768, "min": 64, "max": nodes.MAX_RESOLUTION, "step": 8}), "seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}), "steps": ("INT", {"default": 20, "min": 1, "max": 10000}), @@ -763,8 +781,8 @@ class FaceDetailer: "negative": ("CONDITIONING",), "denoise": ("FLOAT", {"default": 0.5, "min": 0.0001, "max": 1.0, "step": 0.01}), "feather": ("INT", {"default": 5, "min": 0, "max": 100, "step": 1}), - "noise_mask": (["enabled", "disabled"], ), - "force_inpaint": (["disabled", "enabled"], ), + "noise_mask": ("BOOLEAN", {"default": True, "label_on": "enabled", "label_off": "disabled"}), + "force_inpaint": ("BOOLEAN", {"default": True, "label_on": "enabled", "label_off": "disabled"}), "bbox_threshold": ("FLOAT", {"default": 0.5, "min": 0.0, "max": 1.0, "step": 0.01}), "bbox_dilation": ("INT", {"default": 10, "min": 0, "max": 255, "step": 1}), @@ -795,7 +813,7 @@ class FaceDetailer: CATEGORY = "ImpactPack/Simple" @staticmethod - def enhance_face(image, model, clip, vae, guide_size, guide_size_for, max_size, seed, steps, cfg, sampler_name, scheduler, + def enhance_face(image, 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, bbox_threshold, bbox_dilation, bbox_crop_factor, sam_detection_hint, sam_dilation, sam_threshold, sam_bbox_expansion, sam_mask_hint_threshold, @@ -819,7 +837,7 @@ class FaceDetailer: segs = core.segs_bitwise_and_mask(segs, segm_mask) enhanced_img, _, cropped_enhanced, cropped_enhanced_alpha = \ - DetailerForEach.do_detail(image, segs, model, clip, vae, guide_size, guide_size_for, max_size, seed, steps, cfg, + DetailerForEach.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) @@ -861,7 +879,7 @@ class LatentPixelScale: "scale_method": (s.upscale_methods,), "scale_factor": ("FLOAT", {"default": 1.5, "min": 0.1, "max": 10000, "step": 0.1}), "vae": ("VAE", ), - "use_tiled_vae": (["disabled", "enabled"],), + "use_tiled_vae": ("BOOLEAN", {"default": False, "label_on": "enabled", "label_off": "disabled"}), }, "optional": { "upscale_model_opt": ("UPSCALE_MODEL", ), @@ -874,11 +892,10 @@ class LatentPixelScale: CATEGORY = "ImpactPack/Upscale" def doit(self, samples, scale_method, scale_factor, vae, use_tiled_vae, upscale_model_opt=None): - use_tile = use_tiled_vae == "enabled" if upscale_model_opt is None: - latent = core.latent_upscale_on_pixel_space(samples, scale_method, scale_factor, vae, use_tile=use_tile) + latent = core.latent_upscale_on_pixel_space(samples, scale_method, scale_factor, vae, use_tile=use_tiled_vae) else: - latent = core.latent_upscale_on_pixel_space_with_model(samples, scale_method, upscale_model_opt, scale_factor, vae, use_tile=use_tile) + latent = core.latent_upscale_on_pixel_space_with_model(samples, scale_method, upscale_model_opt, scale_factor, vae, use_tile=use_tiled_vae) return (latent,) @@ -1079,7 +1096,7 @@ class PixelKSampleUpscalerProvider: "positive": ("CONDITIONING", ), "negative": ("CONDITIONING", ), "denoise": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01}), - "use_tiled_vae": (["disabled", "enabled"],), + "use_tiled_vae": ("BOOLEAN", {"default": False, "label_on": "enabled", "label_off": "disabled"}), }, "optional": { "upscale_model_opt": ("UPSCALE_MODEL", ), @@ -1095,7 +1112,7 @@ class PixelKSampleUpscalerProvider: def doit(self, scale_method, model, vae, seed, steps, cfg, sampler_name, scheduler, positive, negative, denoise, use_tiled_vae, upscale_model_opt=None, pk_hook_opt=None): upscaler = core.PixelKSampleUpscaler(scale_method, model, vae, seed, steps, cfg, sampler_name, scheduler, - positive, negative, denoise, use_tiled_vae == "enabled", upscale_model_opt, pk_hook_opt) + positive, negative, denoise, use_tiled_vae, upscale_model_opt, pk_hook_opt) return (upscaler, ) @@ -1112,7 +1129,7 @@ class PixelKSampleUpscalerProviderPipe(PixelKSampleUpscalerProvider): "sampler_name": (comfy.samplers.KSampler.SAMPLERS, ), "scheduler": (comfy.samplers.KSampler.SCHEDULERS, ), "denoise": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01}), - "use_tiled_vae": (["disabled", "enabled"],), + "use_tiled_vae": ("BOOLEAN", {"default": False, "label_on": "enabled", "label_off": "disabled"}), "basic_pipe": ("BASIC_PIPE",) }, "optional": { @@ -1130,7 +1147,7 @@ class PixelKSampleUpscalerProviderPipe(PixelKSampleUpscalerProvider): use_tiled_vae, basic_pipe, upscale_model_opt=None, pk_hook_opt=None): model, _, vae, positive, negative = basic_pipe upscaler = core.PixelKSampleUpscaler(scale_method, model, vae, seed, steps, cfg, sampler_name, scheduler, - positive, negative, denoise, use_tiled_vae == "enabled", upscale_model_opt, pk_hook_opt) + positive, negative, denoise, use_tiled_vae, upscale_model_opt, pk_hook_opt) return (upscaler, ) @@ -1146,7 +1163,7 @@ class TwoSamplersForMaskUpscalerProvider: "last1", "last2", "interleave1+last1", "interleave2+last1", "interleave3+last1", ],), - "use_tiled_vae": (["disabled", "enabled"],), + "use_tiled_vae": ("BOOLEAN", {"default": False, "label_on": "enabled", "label_off": "disabled"}), "base_sampler": ("KSAMPLER", ), "mask_sampler": ("KSAMPLER", ), "mask": ("MASK", ), @@ -1169,7 +1186,7 @@ class TwoSamplersForMaskUpscalerProvider: def doit(self, scale_method, full_sample_schedule, use_tiled_vae, base_sampler, mask_sampler, mask, vae, full_sampler_opt=None, upscale_model_opt=None, pk_hook_base_opt=None, pk_hook_mask_opt=None, pk_hook_full_opt=None): - upscaler = core.TwoSamplersForMaskUpscaler(scale_method, full_sample_schedule, use_tiled_vae == "enabled", + upscaler = core.TwoSamplersForMaskUpscaler(scale_method, full_sample_schedule, use_tiled_vae, base_sampler, mask_sampler, mask, vae, full_sampler_opt, upscale_model_opt, pk_hook_base_opt, pk_hook_mask_opt, pk_hook_full_opt) return (upscaler, ) @@ -1187,7 +1204,7 @@ class TwoSamplersForMaskUpscalerProviderPipe: "last1", "last2", "interleave1+last1", "interleave2+last1", "interleave3+last1", ],), - "use_tiled_vae": (["disabled", "enabled"],), + "use_tiled_vae": ("BOOLEAN", {"default": False, "label_on": "enabled", "label_off": "disabled"}), "base_sampler": ("KSAMPLER", ), "mask_sampler": ("KSAMPLER", ), "mask": ("MASK", ), @@ -1211,7 +1228,7 @@ class TwoSamplersForMaskUpscalerProviderPipe: full_sampler_opt=None, upscale_model_opt=None, pk_hook_base_opt=None, pk_hook_mask_opt=None, pk_hook_full_opt=None): _, _, vae, _, _ = basic_pipe - upscaler = core.TwoSamplersForMaskUpscaler(scale_method, full_sample_schedule, use_tiled_vae == "enabled", + upscaler = core.TwoSamplersForMaskUpscaler(scale_method, full_sample_schedule, use_tiled_vae, base_sampler, mask_sampler, mask, vae, full_sampler_opt, upscale_model_opt, pk_hook_base_opt, pk_hook_mask_opt, pk_hook_full_opt) return (upscaler, ) @@ -1319,7 +1336,7 @@ class FaceDetailerPipe: "image": ("IMAGE", ), "detailer_pipe": ("DETAILER_PIPE",), "guide_size": ("FLOAT", {"default": 256, "min": 64, "max": nodes.MAX_RESOLUTION, "step": 8}), - "guide_size_for": (["bbox", "crop_region"],), + "guide_size_for": ("BOOLEAN", {"default": True, "label_on": "bbox", "label_off": "crop_region"}), "max_size": ("FLOAT", {"default": 768, "min": 64, "max": nodes.MAX_RESOLUTION, "step": 8}), "seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}), "steps": ("INT", {"default": 20, "min": 1, "max": 10000}), @@ -1328,8 +1345,8 @@ class FaceDetailerPipe: "scheduler": (comfy.samplers.KSampler.SCHEDULERS,), "denoise": ("FLOAT", {"default": 0.5, "min": 0.0001, "max": 1.0, "step": 0.01}), "feather": ("INT", {"default": 5, "min": 0, "max": 100, "step": 1}), - "noise_mask": (["enabled", "disabled"], ), - "force_inpaint": (["disabled", "enabled"], ), + "noise_mask": ("BOOLEAN", {"default": True, "label_on": "enabled", "label_off": "disabled"}), + "force_inpaint": ("BOOLEAN", {"default": False, "label_on": "enabled", "label_off": "disabled"}), "bbox_threshold": ("FLOAT", {"default": 0.5, "min": 0.0, "max": 1.0, "step": 0.01}), "bbox_dilation": ("INT", {"default": 10, "min": 0, "max": 255, "step": 1}), @@ -1619,9 +1636,9 @@ class MaskToSEGS: def INPUT_TYPES(s): return {"required": { "mask": ("MASK",), - "combined": (["False", "True"], ), + "combined": ("BOOLEAN", {"default": False, "label_on": "True", "label_off": "False"}), "crop_factor": ("FLOAT", {"default": 3.0, "min": 1.0, "max": 10, "step": 0.1}), - "bbox_fill": (["disabled", "enabled"], ), + "bbox_fill": ("BOOLEAN", {"default": False, "label_on": "enabled", "label_off": "disabled"}), "drop_size": ("INT", {"min": 1, "max": MAX_RESOLUTION, "step": 1, "default": 10}), } } @@ -1632,7 +1649,7 @@ class MaskToSEGS: CATEGORY = "ImpactPack/Operation" def doit(self, mask, combined, crop_factor, bbox_fill, drop_size): - result = core.mask_to_segs(mask, combined, crop_factor, bbox_fill == "enabled", drop_size) + result = core.mask_to_segs(mask, combined, crop_factor, bbox_fill, drop_size) return (result, ) @@ -2283,7 +2300,7 @@ class ImpactWildcardProcessor: return {"required": { "wildcard_text": ("STRING", {"multiline": True}), "populated_text": ("STRING", {"multiline": True}), - "mode": (["Populate", "Fixed"], ), + "mode": ("BOOLEAN", {"default": True, "label_on": "Populate", "label_off": "Fixed"}), }, } @@ -2377,16 +2394,16 @@ class KSamplerAdvancedBasicPipe: def INPUT_TYPES(s): return {"required": {"basic_pipe": ("BASIC_PIPE",), - "add_noise": (["enable", "disable"], ), - "noise_seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}), - "steps": ("INT", {"default": 20, "min": 1, "max": 10000}), - "cfg": ("FLOAT", {"default": 8.0, "min": 0.0, "max": 100.0}), - "sampler_name": (comfy.samplers.KSampler.SAMPLERS, ), - "scheduler": (comfy.samplers.KSampler.SCHEDULERS, ), - "latent_image": ("LATENT", ), - "start_at_step": ("INT", {"default": 0, "min": 0, "max": 10000}), - "end_at_step": ("INT", {"default": 10000, "min": 0, "max": 10000}), - "return_with_leftover_noise": (["disable", "enable"], ), + "add_noise": ("BOOLEAN", {"default": True, "label_on": "enabled", "label_off": "disabled"}), + "noise_seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}), + "steps": ("INT", {"default": 20, "min": 1, "max": 10000}), + "cfg": ("FLOAT", {"default": 8.0, "min": 0.0, "max": 100.0}), + "sampler_name": (comfy.samplers.KSampler.SAMPLERS, ), + "scheduler": (comfy.samplers.KSampler.SCHEDULERS, ), + "latent_image": ("LATENT", ), + "start_at_step": ("INT", {"default": 0, "min": 0, "max": 10000}), + "end_at_step": ("INT", {"default": 10000, "min": 0, "max": 10000}), + "return_with_leftover_noise": ("BOOLEAN", {"default": False, "label_on": "enabled", "label_off": "disabled"}), } } @@ -2397,6 +2414,17 @@ class KSamplerAdvancedBasicPipe: def sample(self, basic_pipe, add_noise, noise_seed, steps, cfg, sampler_name, scheduler, latent_image, start_at_step, end_at_step, return_with_leftover_noise, denoise=1.0): model, clip, vae, positive, negative = basic_pipe + + if add_noise: + add_noise = "enabled" + else: + add_noise = "disabled" + + if return_with_leftover_noise: + return_with_leftover_noise = "enabled" + else: + return_with_leftover_noise = "disabled" + latent = nodes.KSamplerAdvanced().sample(model, add_noise, noise_seed, steps, cfg, sampler_name, scheduler, positive, negative, latent_image, start_at_step, end_at_step, return_with_leftover_noise, denoise)[0] return (basic_pipe, latent, vae)