From a5d3eb9715c80b6ba6b3da299da3bd08c827271a Mon Sep 17 00:00:00 2001 From: pythongosssss <125205205+pythongosssss@users.noreply.github.com> Date: Mon, 13 Mar 2023 22:00:37 +0000 Subject: [PATCH 1/6] Rewrote reroute node for much better usability --- web/extensions/core/rerouteNode.js | 95 +++++++++++++++++++++++++++--- 1 file changed, 88 insertions(+), 7 deletions(-) diff --git a/web/extensions/core/rerouteNode.js b/web/extensions/core/rerouteNode.js index bdc7306b..8ce349ff 100644 --- a/web/extensions/core/rerouteNode.js +++ b/web/extensions/core/rerouteNode.js @@ -14,11 +14,92 @@ app.registerExtension({ this.addInput("", "*"); this.addOutput(this.properties.showOutputText ? "*" : "", "*"); - this.onConnectInput = function (_, type) { - if (type !== this.outputs[0].type) { - this.removeOutput(0); - this.addOutput(this.properties.showOutputText ? type : "", type); - this.size = this.computeSize(); + + this.onConnectionsChange = function (type, index, connected, link_info) { + // Prevent multiple connections to different types when we have no input + if (connected && type === LiteGraph.OUTPUT) { + // Ignore wildcard nodes as these will be updated to real types + const types = new Set(this.outputs[0].links.map((l) => app.graph.links[l].type).filter((t) => t !== "*")); + if (types.size > 1) { + for (let i = 0; i < this.outputs[0].links.length - 1; i++) { + const linkId = this.outputs[0].links[i]; + const link = app.graph.links[linkId]; + const node = app.graph.getNodeById(link.target_id); + node.disconnectInput(link.target_slot); + } + } + } + + // Find root input + let currentNode = this; + let updateNodes = []; + let inputType = null; + while (currentNode) { + updateNodes.unshift(currentNode); + const linkId = currentNode.inputs[0].link; + if (linkId !== null) { + const link = app.graph.links[linkId]; + const node = app.graph.getNodeById(link.origin_id); + const type = node.constructor.type; + if (type === "Reroute") { + // Move the previous node + currentNode = node; + } else { + // We've found the end + inputType = node.outputs[link.origin_slot].type; + break; + } + } else { + // This path has no input node + currentNode = null; + break; + } + } + + // Find all outputs + const nodes = [this]; + let outputType = null; + while (nodes.length) { + currentNode = nodes.pop(); + const outputs = (currentNode.outputs ? currentNode.outputs[0].links : []) || []; + if (outputs.length) { + for (const linkId of outputs) { + const link = app.graph.links[linkId]; + + // When disconnecting sometimes the link is still registered + if (!link) continue; + + const node = app.graph.getNodeById(link.target_id); + const type = node.constructor.type; + + if (type === "Reroute") { + // Follow reroute nodes + nodes.push(node); + updateNodes.push(node); + } else { + // We've found an output + const nodeOutType = node.inputs[link.target_slot].type; + if (inputType && nodeOutType !== inputType) { + // The output doesnt match our input so disconnect it + node.disconnectInput(link.target_slot); + } else { + outputType = nodeOutType; + } + } + } + } else { + // No more outputs for this path + } + } + + // Update the types of each node + for (const node of updateNodes) { + // If we dont have an input type we are always wildcard but we'll show the output type + // This lets you change the output link to a different type and all nodes will update + node.outputs[0].type = inputType || "*"; + node.__outputType = inputType || outputType || "*"; + node.outputs[0].name = node.properties.showOutputText ? inputType || outputType || "*" : ""; + node.size = node.computeSize(); } }; @@ -41,12 +122,12 @@ app.registerExtension({ callback: () => { this.properties.showOutputText = !this.properties.showOutputText; if (this.properties.showOutputText) { - this.outputs[0].name = this.outputs[0].type; + this.outputs[0].name = this.__outputType || this.outputs[0].type; } else { this.outputs[0].name = ""; } this.size = this.computeSize(); - app.graph.setDirtyCanvas(true); + app.graph.setDirtyCanvas(true, true); }, }, { From 97f3c23036870211c73ab0607a55a9aea7e12aa5 Mon Sep 17 00:00:00 2001 From: pythongosssss <125205205+pythongosssss@users.noreply.github.com> Date: Mon, 13 Mar 2023 22:11:09 +0000 Subject: [PATCH 2/6] Fix node link colors --- web/extensions/core/rerouteNode.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/web/extensions/core/rerouteNode.js b/web/extensions/core/rerouteNode.js index 8ce349ff..54356462 100644 --- a/web/extensions/core/rerouteNode.js +++ b/web/extensions/core/rerouteNode.js @@ -65,7 +65,7 @@ app.registerExtension({ if (outputs.length) { for (const linkId of outputs) { const link = app.graph.links[linkId]; - + // When disconnecting sometimes the link is still registered if (!link) continue; @@ -92,14 +92,21 @@ app.registerExtension({ } } + const displayType = inputType || outputType || "*"; + // Update the types of each node for (const node of updateNodes) { // If we dont have an input type we are always wildcard but we'll show the output type // This lets you change the output link to a different type and all nodes will update node.outputs[0].type = inputType || "*"; - node.__outputType = inputType || outputType || "*"; - node.outputs[0].name = node.properties.showOutputText ? inputType || outputType || "*" : ""; + node.__outputType = displayType; + node.outputs[0].name = node.properties.showOutputText ? displayType : ""; node.size = node.computeSize(); + + const color = LGraphCanvas.link_type_colors[displayType]; + for (const l of node.outputs[0].links || []) { + app.graph.links[l].color = color; + } } }; From 37b70d798701295819a50bc64d373b0e6235cf14 Mon Sep 17 00:00:00 2001 From: pythongosssss <125205205+pythongosssss@users.noreply.github.com> Date: Thu, 16 Mar 2023 14:08:11 +0000 Subject: [PATCH 3/6] Made node non collapsable Fixed color of first input link --- web/extensions/core/rerouteNode.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/web/extensions/core/rerouteNode.js b/web/extensions/core/rerouteNode.js index 54356462..8a951d41 100644 --- a/web/extensions/core/rerouteNode.js +++ b/web/extensions/core/rerouteNode.js @@ -34,6 +34,7 @@ app.registerExtension({ let currentNode = this; let updateNodes = []; let inputType = null; + let inputNode = null; while (currentNode) { updateNodes.unshift(currentNode); const linkId = currentNode.inputs[0].link; @@ -46,6 +47,7 @@ app.registerExtension({ currentNode = node; } else { // We've found the end + inputNode = currentNode; inputType = node.outputs[link.origin_slot].type; break; } @@ -93,6 +95,7 @@ app.registerExtension({ } const displayType = inputType || outputType || "*"; + const color = LGraphCanvas.link_type_colors[displayType]; // Update the types of each node for (const node of updateNodes) { @@ -103,11 +106,14 @@ app.registerExtension({ node.outputs[0].name = node.properties.showOutputText ? displayType : ""; node.size = node.computeSize(); - const color = LGraphCanvas.link_type_colors[displayType]; for (const l of node.outputs[0].links || []) { app.graph.links[l].color = color; } } + + if (inputNode) { + app.graph.links[inputNode.inputs[0].link].color = color; + } }; this.clone = function () { @@ -173,6 +179,7 @@ app.registerExtension({ Object.assign(RerouteNode, { title_mode: LiteGraph.NO_TITLE, title: "Reroute", + collapsable: false, }) ); From aff1e3936a327517ca1bae5c3f44e8ef497f0bcd Mon Sep 17 00:00:00 2001 From: pythongosssss <125205205+pythongosssss@users.noreply.github.com> Date: Thu, 16 Mar 2023 19:15:02 +0000 Subject: [PATCH 4/6] Simplify and fix bug with following virtual nodes courtesy of someanon --- web/scripts/app.js | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/web/scripts/app.js b/web/scripts/app.js index e70e1c15..b780bd83 100644 --- a/web/scripts/app.js +++ b/web/scripts/app.js @@ -606,24 +606,10 @@ class ComfyApp { for (let i in node.inputs) { let parent = node.getInputNode(i); if (parent) { - let link; - if (parent.isVirtualNode) { - // Follow the path of virtual nodes until we reach the first real one - while (parent != null) { - link = parent.getInputLink(0); - if (link) { - const from = graph.getNodeById(link.origin_id); - if (from.isVirtualNode) { - parent = from; - } else { - parent = null; - } - } else { - parent = null; - } - } - } else { - link = node.getInputLink(i); + let link = node.getInputLink(i); + while (parent && parent.isVirtualNode) { + link = parent.getInputLink(link.origin_slot); + parent = parent.getInputNode(link.origin_slot); } if (link) { From c0f53250183da8925d438dbc44c3d7d5af3038f1 Mon Sep 17 00:00:00 2001 From: pythongosssss <125205205+pythongosssss@users.noreply.github.com> Date: Thu, 16 Mar 2023 21:04:54 +0000 Subject: [PATCH 5/6] Increase size of node --- web/extensions/core/rerouteNode.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/extensions/core/rerouteNode.js b/web/extensions/core/rerouteNode.js index 8a951d41..0dc9ad37 100644 --- a/web/extensions/core/rerouteNode.js +++ b/web/extensions/core/rerouteNode.js @@ -155,8 +155,8 @@ app.registerExtension({ computeSize() { return [ this.properties.showOutputText && this.outputs && this.outputs.length - ? Math.max(55, LiteGraph.NODE_TEXT_SIZE * this.outputs[0].name.length * 0.6 + 40) - : 55, + ? Math.max(75, LiteGraph.NODE_TEXT_SIZE * this.outputs[0].name.length * 0.6 + 40) + : 75, 26, ]; } From 52e74a2bb2393aebd32e98557e3b547560d878a9 Mon Sep 17 00:00:00 2001 From: pythongosssss <125205205+pythongosssss@users.noreply.github.com> Date: Fri, 17 Mar 2023 17:52:20 +0000 Subject: [PATCH 6/6] Fixed crash removing nodes due to output link is still being set but not valid --- web/extensions/core/rerouteNode.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/web/extensions/core/rerouteNode.js b/web/extensions/core/rerouteNode.js index 0dc9ad37..7188dfd2 100644 --- a/web/extensions/core/rerouteNode.js +++ b/web/extensions/core/rerouteNode.js @@ -107,12 +107,18 @@ app.registerExtension({ node.size = node.computeSize(); for (const l of node.outputs[0].links || []) { - app.graph.links[l].color = color; + const link = app.graph.links[l]; + if (link) { + link.color = color; + } } } if (inputNode) { - app.graph.links[inputNode.inputs[0].link].color = color; + const link = app.graph.links[inputNode.inputs[0].link]; + if (link) { + link.color = color; + } } };