Add widgets to Primitive node for range of values

This commit is contained in:
space-nuko 2023-05-14 16:54:00 -05:00
parent 730dd3cf99
commit 864b439819
2 changed files with 39 additions and 21 deletions

View File

@ -195,8 +195,20 @@ app.registerExtension({
this.addOutput("connect to widget input", "*"); this.addOutput("connect to widget input", "*");
this.serialize_widgets = true; this.serialize_widgets = true;
this.isVirtualNode = true; this.isVirtualNode = true;
this.properties ||= {} this.properties ||= {}
this.properties.isRange = false; 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() { applyToGraph() {
@ -212,16 +224,13 @@ app.registerExtension({
const widget = node.widgets.find((w) => w.name === widgetName); const widget = node.widgets.find((w) => w.name === widgetName);
if (widget) { if (widget) {
widget.value = this.widgets[0].value; 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) { if (widget.callback) {
widget.callback(widget.value, app.canvas, node, app.canvas.graph_mouse, {}); 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") { if (widget.type === "number") {
addValueControlWidget(this, widget, "fixed"); 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 // When our value changes, update other widgets to reflect our changes
// e.g. so LoadImage shows correct image // e.g. so LoadImage shows correct image
const callback = widget.callback; const callback = widget.callback;

View File

@ -1170,6 +1170,10 @@ export class ComfyApp {
async graphToPrompt() { async graphToPrompt() {
const workflow = this.graph.serialize(); const workflow = this.graph.serialize();
const output = {}; const output = {};
let totalExecuted = 0;
let totalCombinatorialNodes = 0;
let executionFactor = 1;
// Process nodes in order of execution // Process nodes in order of execution
for (const node of this.graph.computeExecutionOrder(false)) { for (const node of this.graph.computeExecutionOrder(false)) {
const n = workflow.nodes.find((n) => n.id === node.id); const n = workflow.nodes.find((n) => n.id === node.id);
@ -1195,14 +1199,13 @@ export class ComfyApp {
for (const i in widgets) { for (const i in widgets) {
const widget = widgets[i]; const widget = widgets[i];
if (!widget.options || widget.options.serialize !== false) { if (!widget.options || widget.options.serialize !== false) {
let widgetValue = widget.serializeValue ? await widget.serializeValue(n, i) : widget.value; const widgetValue = widget.serializeValue ? await widget.serializeValue(n, i) : widget.value;
inputs[widget.name] = widgetValue;
if (widget.__rangeData) { if (typeof widgetValue === "object" && widgetValue.__inputType__) {
console.error("SETRANGE", widget.name, widget.__rangeData) totalCombinatorialNodes += 1;
widgetValue = widget.__rangeData; executionFactor *= widgetValue.values.length;
} }
totalExecuted += executionFactor;
inputs[widget.name] = widgetValue
} }
} }
} }
@ -1245,7 +1248,7 @@ export class ComfyApp {
} }
} }
return { workflow, output }; return { prompt: { workflow, output }, totalCombinatorialNodes, totalExecuted };
} }
async queuePrompt(number, batchCount = 1) { async queuePrompt(number, batchCount = 1) {
@ -1262,7 +1265,11 @@ export class ComfyApp {
({ number, batchCount } = this.#queueItems.pop()); ({ number, batchCount } = this.#queueItems.pop());
for (let i = 0; i < batchCount; i++) { 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 { try {
await api.queuePrompt(number, p); await api.queuePrompt(number, p);