Compare commits

..
5 Commits
8 changed files with 122 additions and 44 deletions
+1
View File
@@ -268,6 +268,7 @@ NOTE: The UltralyticsDetectorProvider node is not part of the ComfyUI-Impact-Pac
* `Masks to Mask List`, `Mask List to Masks`, `Make Mask List`, `Make Mask Batch` - It has the same functionality as the nodes above, but uses mask as input instead of image.
* `Flatten Mask Batch` - Flattens a Mask Batch into a single Mask. Normal operation is not guaranteed for non-binary masks.
* `Make List (Any)` - Create a list with arbitrary values.
* `Select Nth Item (Any list)` - Selects the Nth item from a list. If the index is out of range, it returns the last item in the list.
### Logics (experimental)
* These nodes are experimental nodes designed to implement the logic for loops and dynamic switching.
+2
View File
@@ -234,6 +234,7 @@ NODE_CLASS_MAPPINGS = {
"ImpactMakeAnyList": MakeAnyList,
"ImpactMakeMaskList": MakeMaskList,
"ImpactMakeMaskBatch": MakeMaskBatch,
"ImpactSelectNthItemOfAnyList": NthItemOfAnyList,
"RegionalSampler": RegionalSampler,
"RegionalSamplerAdvanced": RegionalSamplerAdvanced,
@@ -407,6 +408,7 @@ NODE_DISPLAY_NAME_MAPPINGS = {
"ImpactMakeMaskList": "Make Mask List",
"ImpactMakeMaskBatch": "Make Mask Batch",
"ImpactMakeAnyList": "Make List (Any)",
"ImpactSelectNthItemOfAnyList": "Select Nth Item (Any list)",
"ImpactStringSelector": "String Selector",
"StringListToString": "String List to String",
+42
View File
@@ -3,6 +3,48 @@ import { app } from "../../scripts/app.js";
let original_show = app.ui.dialog.show;
export function customAlert(message) {
try {
app.extensionManager.toast.addAlert(message);
}
catch {
alert(message);
}
}
export function isBeforeFrontendVersion(compareVersion) {
try {
const frontendVersion = window['__COMFYUI_FRONTEND_VERSION__'];
if (typeof frontendVersion !== 'string') {
return false;
}
function parseVersion(versionString) {
const parts = versionString.split('.').map(Number);
return parts.length === 3 && parts.every(part => !isNaN(part)) ? parts : null;
}
const currentVersion = parseVersion(frontendVersion);
const comparisonVersion = parseVersion(compareVersion);
if (!currentVersion || !comparisonVersion) {
return false;
}
for (let i = 0; i < 3; i++) {
if (currentVersion[i] > comparisonVersion[i]) {
return false;
} else if (currentVersion[i] < comparisonVersion[i]) {
return true;
}
}
return false;
} catch {
return true;
}
}
function dialog_show_wrapper(html) {
if (typeof html === "string") {
if(html.includes("IMPACT-PACK-SIGNAL: STOP CONTROL BRIDGE")) {
+49 -20
View File
@@ -1,6 +1,13 @@
import { ComfyApp, app } from "../../scripts/app.js";
import { ComfyDialog, $el } from "../../scripts/ui.js";
import { api } from "../../scripts/api.js";
import { customAlert, isBeforeFrontendVersion } from "./common.js";
const is_legacy_front = () => isBeforeFrontendVersion('1.16.9');
if(is_legacy_front()) {
customAlert("An outdated version(<1.16.9) of the `comfyui-frontend-package` is installed. It is not compatible with the current version of the Impact Pack.");
}
let wildcards_list = [];
async function load_wildcards() {
@@ -324,6 +331,32 @@ app.registerExtension({
}
}
if(nodeData.name == "ImpactSelectNthItemOfAnyList") {
const onConnectionsChange = nodeType.prototype.onConnectionsChange;
nodeType.prototype.onConnectionsChange = function (type, index, connected, link_info) {
if(!link_info || this.inputs[0].type != '*')
return;
if(index >= 2)
return;
// assign type
let slot_type = '*';
if(type == 2) {
slot_type = link_info.type;
}
else {
const node = app.graph.getNodeById(link_info.origin_id);
slot_type = node.outputs[link_info.origin_slot].type;
}
this.inputs[0].type = slot_type;
this.outputs[0].type = slot_type;
this.outputs[0].label = slot_type;
}
}
if(nodeData.name === 'ImpactInversedSwitch') {
nodeData.output = ['*'];
nodeData.output_is_list = [false];
@@ -474,6 +507,15 @@ app.registerExtension({
const onConnectionsChange = nodeType.prototype.onConnectionsChange;
nodeType.prototype.onConnectionsChange = function (type, index, connected, link_info) {
const stackTrace = new Error().stack;
if(stackTrace.includes('LGraph.configure')) {
if(this.widgets) {
this.widgets[0].options.max = this.inputs.length-3;
this.widgets[0].value = Math.min(this.widgets[0].value, this.widgets[0].options.max);
}
return;
}
if(!link_info)
return;
@@ -516,7 +558,7 @@ app.registerExtension({
if(this.inputs[0].type == '*'){
const node = app.graph.getNodeById(link_info.origin_id);
let origin_type = node.outputs[link_info.origin_slot]?.type;
if(link_info.target_slot == 0 && this.inputs.length > 1) {
if(link_info.target_slot == 0 && this.inputs.length > 3) { // NOTE: widgets are regarded as input since new front
origin_type = this.inputs[1].type;
node.connect(link_info.origin_slot, node.id, 'input1');
}
@@ -539,15 +581,8 @@ app.registerExtension({
}
let select_slot = this.inputs.find(x => x.name == "select");
let mode_slot = this.inputs.find(x => x.name == "sel_mode");
let converted_count = 0;
converted_count += select_slot?1:0;
converted_count += mode_slot?1:0;
if (!connected && (this.inputs.length > 1+converted_count)) {
const stackTrace = new Error().stack;
if (!connected && (this.inputs.length > 3)) {
if(
!stackTrace.includes('LGraphNode.prototype.connect') && // for touch device
!stackTrace.includes('LGraphNode.connect') && // for mouse device
@@ -557,6 +592,7 @@ app.registerExtension({
}
}
let slot_i = 1;
for (let i = 0; i < this.inputs.length; i++) {
let input_i = this.inputs[i];
@@ -566,19 +602,12 @@ app.registerExtension({
}
}
let last_slot = this.inputs[this.inputs.length - 1];
if (
(last_slot.name == 'select' && last_slot.name != 'sel_mode' && this.inputs[this.inputs.length - 2].link != undefined)
|| (last_slot.name != 'select' && last_slot.name != 'sel_mode' && last_slot.link != undefined)) {
this.addInput(`${input_name}${slot_i}`, this.outputs[0].type);
if(connected) {
this.addInput(`${input_name}${slot_i}`, this.outputs[0].type);
}
if(this.widgets?.length) {
this.widgets[0].options.max = select_slot?this.inputs.length-1:this.inputs.length;
this.widgets[0].value = Math.min(this.widgets[0].value, this.widgets[0].options.max);
if(this.widgets[0].options.max > 0 && this.widgets[0].value == 0)
this.widgets[0].value = 1;
}
this.widgets[0].options.max = this.inputs.length-3;
this.widgets[0].value = Math.min(this.widgets[0].value, this.widgets[0].options.max);
}
}
},
+1 -1
View File
@@ -1,7 +1,7 @@
import configparser
import os
version_code = [8, 11]
version_code = [8, 13, 1]
version = f"V{version_code[0]}.{version_code[1]}" + (f'.{version_code[2]}' if len(version_code) > 2 else '')
dependency_version = 24
+1 -22
View File
@@ -8,7 +8,7 @@ from impact.utils import any_typ
import impact.core as core
import re
import nodes
import traceback
class ImpactCompare:
@classmethod
@@ -574,27 +574,6 @@ class ImpactSleep:
return (signal,)
error_skip_flag = False
try:
import cm_global
def filter_message(str):
global error_skip_flag
if "IMPACT-PACK-SIGNAL: STOP CONTROL BRIDGE" in str:
return True
elif error_skip_flag and "ERROR:root:!!! Exception during processing !!!\n" == str:
error_skip_flag = False
return True
else:
return False
cm_global.try_call(api='cm.register_message_collapse', f=filter_message)
except Exception as e:
print(f"[WARN] ComfyUI-Impact-Pack: `ComfyUI` or `ComfyUI-Manager` is an outdated version.")
pass
def workflow_to_map(workflow):
nodes = {}
links = {}
+25
View File
@@ -446,6 +446,31 @@ class MakeMaskList:
return (masks, )
class NthItemOfAnyList:
@classmethod
def INPUT_TYPES(s):
return {"required": {
"any_list": (any_typ,),
"index": ("INT", {"default": 0, "min": 0, "max": sys.maxsize, "step": 1, "tooltip": "The index of the item you want to select from the list."}),
}
}
RETURN_TYPES = (any_typ,)
INPUT_IS_LIST = True
FUNCTION = "doit"
CATEGORY = "ImpactPack/Util"
DESCRIPTION = "Selects the Nth item from a list. If the index is out of range, it returns the last item in the list."
def doit(self, any_list, index):
i = index[0]
if i >= len(any_list):
return (any_list[-1],)
else:
return (any_list[i],)
class MakeImageList:
@classmethod
def INPUT_TYPES(s):
+1 -1
View File
@@ -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.11"
version = "8.13.1"
license = { file = "LICENSE.txt" }
dependencies = ["segment-anything", "scikit-image", "piexif", "transformers", "opencv-python-headless", "GitPython", "scipy>=1.11.4"]