| | import { app } from "../../scripts/app.js"; |
| | import { api } from "../../scripts/api.js"; |
| |
|
| | function addMenuHandler(nodeType, cb) { |
| | const getOpts = nodeType.prototype.getExtraMenuOptions; |
| | nodeType.prototype.getExtraMenuOptions = function () { |
| | const r = getOpts.apply(this, arguments); |
| | cb.apply(this, arguments); |
| | return r; |
| | }; |
| | } |
| |
|
| | function distance(node1, node2) { |
| | let dx = (node1.pos[0] + node1.size[0]/2) - (node2.pos[0] + node2.size[0]/2); |
| | let dy = (node1.pos[1] + node1.size[1]/2) - (node2.pos[1] + node2.size[1]/2); |
| | return Math.sqrt(dx * dx + dy * dy); |
| | } |
| |
|
| | function lookup_nearest_nodes(node) { |
| | let nearest_distance = Infinity; |
| | let nearest_node = null; |
| | for(let other of app.graph._nodes) { |
| | if(other === node) |
| | continue; |
| |
|
| | let dist = distance(node, other); |
| | if (dist < nearest_distance && dist < 1000) { |
| | nearest_distance = dist; |
| | nearest_node = other; |
| | } |
| | } |
| |
|
| | return nearest_node; |
| | } |
| |
|
| | function lookup_nearest_inputs(node) { |
| | let input_map = {}; |
| |
|
| | for(let i in node.inputs) { |
| | let input = node.inputs[i]; |
| |
|
| | if(input.link || input_map[input.type]) |
| | continue; |
| |
|
| | input_map[input.type] = {distance: Infinity, input_name: input.name, node: null, slot: null}; |
| | } |
| |
|
| | let x = node.pos[0]; |
| | let y = node.pos[1] + node.size[1]/2; |
| |
|
| | for(let other of app.graph._nodes) { |
| | if(other === node || !other.outputs) |
| | continue; |
| |
|
| | let dx = x - (other.pos[0] + other.size[0]); |
| | let dy = y - (other.pos[1] + other.size[1]/2); |
| |
|
| | if(dx < 0) |
| | continue; |
| |
|
| | let dist = Math.sqrt(dx * dx + dy * dy); |
| |
|
| | for(let input_type in input_map) { |
| | for(let j in other.outputs) { |
| | let output = other.outputs[j]; |
| | if(output.type == input_type) { |
| | if(input_map[input_type].distance > dist) { |
| | input_map[input_type].distance = dist; |
| | input_map[input_type].node = other; |
| | input_map[input_type].slot = parseInt(j); |
| | } |
| | } |
| | } |
| | } |
| | } |
| |
|
| | let res = {}; |
| | for (let i in input_map) { |
| | if (input_map[i].node) { |
| | res[i] = input_map[i]; |
| | } |
| | } |
| |
|
| | return res; |
| | } |
| |
|
| | function connect_inputs(nearest_inputs, node) { |
| | for(let i in nearest_inputs) { |
| | let info = nearest_inputs[i]; |
| | info.node.connect(info.slot, node.id, info.input_name); |
| | } |
| | } |
| |
|
| | function node_info_copy(src, dest, connect_both, copy_shape) { |
| | |
| | for(let i in src.inputs) { |
| | let input = src.inputs[i]; |
| | if (input.widget !== undefined) { |
| | const destWidget = dest.widgets.find(x => x.name === input.widget.name); |
| | dest.convertWidgetToInput(destWidget); |
| | } |
| | if(input.link) { |
| | let link = app.graph.links[input.link]; |
| | let src_node = app.graph.getNodeById(link.origin_id); |
| | src_node.connect(link.origin_slot, dest.id, input.name); |
| | } |
| | } |
| |
|
| | |
| | if(connect_both) { |
| | let output_links = {}; |
| | for(let i in src.outputs) { |
| | let output = src.outputs[i]; |
| | if(output.links) { |
| | let links = []; |
| | for(let j in output.links) { |
| | links.push(app.graph.links[output.links[j]]); |
| | } |
| | output_links[output.name] = links; |
| | } |
| | } |
| |
|
| | for(let i in dest.outputs) { |
| | let links = output_links[dest.outputs[i].name]; |
| | if(links) { |
| | for(let j in links) { |
| | let link = links[j]; |
| | let target_node = app.graph.getNodeById(link.target_id); |
| | dest.connect(parseInt(i), target_node, link.target_slot); |
| | } |
| | } |
| | } |
| | } |
| |
|
| | if(copy_shape) { |
| | dest.color = src.color; |
| | dest.bgcolor = src.bgcolor; |
| | dest.size = max(src.size, dest.size); |
| | } |
| |
|
| | app.graph.afterChange(); |
| | } |
| |
|
| | app.registerExtension({ |
| | name: "Comfy.Manager.NodeFixer", |
| | beforeRegisterNodeDef(nodeType, nodeData, app) { |
| | addMenuHandler(nodeType, function (_, options) { |
| | options.push({ |
| | content: "Fix node (recreate)", |
| | callback: () => { |
| | let new_node = LiteGraph.createNode(nodeType.comfyClass); |
| | new_node.pos = [this.pos[0], this.pos[1]]; |
| | app.canvas.graph.add(new_node, false); |
| | node_info_copy(this, new_node, true); |
| | app.canvas.graph.remove(this); |
| | requestAnimationFrame(() => app.canvas.setDirty(true, true)) |
| | }, |
| | }); |
| | }); |
| | } |
| | }); |
| |
|