From 864b439819545ac4bd4f589a2ee8ac8520e97dea Mon Sep 17 00:00:00 2001 From: space-nuko <24979496+space-nuko@users.noreply.github.com> Date: Sun, 14 May 2023 16:54:00 -0500 Subject: [PATCH] Add widgets to Primitive node for range of values --- web/extensions/core/widgetInputs.js | 33 +++++++++++++++++++---------- web/scripts/app.js | 27 ++++++++++++++--------- 2 files changed, 39 insertions(+), 21 deletions(-) diff --git a/web/extensions/core/widgetInputs.js b/web/extensions/core/widgetInputs.js index 051e71420..243ba32d2 100644 --- a/web/extensions/core/widgetInputs.js +++ b/web/extensions/core/widgetInputs.js @@ -195,8 +195,20 @@ app.registerExtension({ this.addOutput("connect to widget input", "*"); this.serialize_widgets = true; this.isVirtualNode = true; - this.properties ||= {} - this.properties.isRange = false; + this.properties ||= {} + this.properties.isRange = false; + this.properties.rangeMin = 0; + this.properties.rangeMax = 1024; + this.properties.rangeSteps = 2; + } + + getRange(min, max, steps) { + const range = []; + const stepSize = (max - min) / (steps - 1); + for (let i = 0; i < steps; i++) { + range.push(Math.round((min + i * stepSize) * 100) / 100); + } + return range; } applyToGraph() { @@ -212,16 +224,13 @@ app.registerExtension({ const widget = node.widgets.find((w) => w.name === widgetName); if (widget) { widget.value = this.widgets[0].value; - if (this.properties.isRange) { - console.error("RANGE") - widget.__rangeData = { __inputType__: "list", values: [widget.value, widget.value + 256] } - } - else { - widget.__rangeData = undefined - } if (widget.callback) { widget.callback(widget.value, app.canvas, node, app.canvas.graph_mouse, {}); } + if (widget.type === "number" && this.properties.isRange) { + const values = this.getRange(this.properties.rangeMin, this.properties.rangeMax, this.properties.rangeSteps); + widget.value = { __inputType__: "combinatorial", values: values } + } } } } @@ -311,10 +320,12 @@ app.registerExtension({ if (widget.type === "number") { addValueControlWidget(this, widget, "fixed"); + this.addWidget("toggle", "Enable Range", this.properties.isRange, "isRange"); + this.addWidget("number", "Range Min.", this.properties.rangeMin, "rangeMin"); + this.addWidget("number", "Range Max.", this.properties.rangeMax, "rangeMax"); + this.addWidget("number", "Range Steps", this.properties.rangeSteps, "rangeSteps", { min: 1, max: 128, step: 10 }); } - const isRangeWidget = this.addWidget("toggle", "isRange", this.properties.isRange, "isRange"); - // When our value changes, update other widgets to reflect our changes // e.g. so LoadImage shows correct image const callback = widget.callback; diff --git a/web/scripts/app.js b/web/scripts/app.js index cbf3fb0ad..6e3d66134 100644 --- a/web/scripts/app.js +++ b/web/scripts/app.js @@ -1170,6 +1170,10 @@ export class ComfyApp { async graphToPrompt() { const workflow = this.graph.serialize(); const output = {}; + let totalExecuted = 0; + let totalCombinatorialNodes = 0; + let executionFactor = 1; + // Process nodes in order of execution for (const node of this.graph.computeExecutionOrder(false)) { const n = workflow.nodes.find((n) => n.id === node.id); @@ -1195,14 +1199,13 @@ export class ComfyApp { for (const i in widgets) { const widget = widgets[i]; if (!widget.options || widget.options.serialize !== false) { - let widgetValue = widget.serializeValue ? await widget.serializeValue(n, i) : widget.value; - - if (widget.__rangeData) { - console.error("SETRANGE", widget.name, widget.__rangeData) - widgetValue = widget.__rangeData; - } - - inputs[widget.name] = widgetValue + const widgetValue = widget.serializeValue ? await widget.serializeValue(n, i) : widget.value; + inputs[widget.name] = widgetValue; + if (typeof widgetValue === "object" && widgetValue.__inputType__) { + totalCombinatorialNodes += 1; + executionFactor *= widgetValue.values.length; + } + totalExecuted += executionFactor; } } } @@ -1245,7 +1248,7 @@ export class ComfyApp { } } - return { workflow, output }; + return { prompt: { workflow, output }, totalCombinatorialNodes, totalExecuted }; } async queuePrompt(number, batchCount = 1) { @@ -1262,7 +1265,11 @@ export class ComfyApp { ({ number, batchCount } = this.#queueItems.pop()); for (let i = 0; i < batchCount; i++) { - const p = await this.graphToPrompt(); + const result = await this.graphToPrompt(); + if (result.totalExecuted > 128 && !confirm("You are about to execute " + result.totalExecuted + " nodes total across " + result.totalCombinatorialNodes + " combinatorial axes. Are you sure you want to do this?")) { + continue + } + const p = result.prompt; try { await api.queuePrompt(number, p);