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.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;

View File

@ -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);