| 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))
|
| },
|
| });
|
| });
|
| }
|
| });
|
|
|