fix:easy globalSeed is not working

This commit is contained in:
yolain
2023-12-25 13:52:39 +08:00
parent 5fff486f40
commit 75f9214b3e
7 changed files with 246 additions and 204 deletions
+5 -2
View File
@@ -11,8 +11,6 @@
## Introduce
**Incompatibility Notice**: Not compatible with the current version of the [cg-use-everywhere](https://github.com/chrisgoringe/cg-use-everywhere) node package at this time
### Random species
<img src="./docs/seed_generate_compare.jpg">
@@ -31,6 +29,11 @@ After installing the node package, the UI interface will be automatically switch
## Changelog
**Updated at 2023-12-25**
- Fixed `easy globalSeed` is not working
- Fixed an issue where all `seed_num` values were out of order due to [cg-use-everywhere](https://github.com/chrisgoringe/cg-use-everywhere) updating the chart in real time
**v1.0.0(Updated at 12/24/2023 GMT+0800)**
- Added `easy positive` - simple positive prompt text
+5 -2
View File
@@ -13,8 +13,6 @@
## 介绍
**不兼容提示**:目前无法与 [cg-use-everywhere](https://github.com/chrisgoringe/cg-use-everywhere) 节点包当前版本兼容(该节点包的机制会导致序列化时随机种一直赋值等问题),可使用 **getNode**、**setNode** 替代。
### 更符合人性化的随机种
<img src="./docs/seed_generate_compare.jpg">
@@ -38,6 +36,11 @@
## 更新日志
**2023-12-25**
- 修复 `easy globalSeed` 不生效问题
- 修复所有的`seed_num` 因 [cg-use-everywhere](https://github.com/chrisgoringe/cg-use-everywhere) 实时更新图表导致值错乱的问题
**v1.0.0(2023-12-24)**
- 新增`easy positive` - 简易正面提示词文本
+47 -46
View File
@@ -1027,14 +1027,14 @@ class wildcardsPrompt:
my_unique_id = int(my_unique_id)
easy_save = easySave(my_unique_id, prompt, extra_pnginfo)
if my_unique_id:
workflow = extra_pnginfo["workflow"]
node = next((x for x in workflow["nodes"] if str(x["id"]) == my_unique_id), None)
if node:
seed_num = prompt[my_unique_id]['inputs']['seed_num'] if 'seed_num' in prompt[my_unique_id][
'inputs'] else 0
length = len(node["widgets_values"])
node["widgets_values"][length - 2] = seed_num
# if my_unique_id:
# workflow = extra_pnginfo["workflow"]
# node = next((x for x in workflow["nodes"] if str(x["id"]) == my_unique_id), None)
# if node:
# seed_num = prompt[my_unique_id]['inputs']['seed_num'] if 'seed_num' in prompt[my_unique_id][
# 'inputs'] else 0
# length = len(node["widgets_values"])
# node["widgets_values"][length - 2] = seed_num
text = kwargs['text']
return {"ui": {"value": [seed_num]}, "result": (text,)}
@@ -1985,14 +1985,14 @@ class samplerSettings:
def settings(self, pipe, steps, cfg, sampler_name, scheduler, denoise, seed_num, image_to_latent=None, latent=None, prompt=None, extra_pnginfo=None, my_unique_id=None):
if my_unique_id:
workflow = extra_pnginfo["workflow"]
node = next((x for x in workflow["nodes"] if str(x["id"]) == my_unique_id), None)
if node:
seed_num = prompt[my_unique_id]['inputs']['seed_num'] if 'seed_num' in prompt[my_unique_id][
'inputs'] else 0
length = len(node["widgets_values"])
node["widgets_values"][length - 2] = seed_num
# if my_unique_id:
# workflow = extra_pnginfo["workflow"]
# node = next((x for x in workflow["nodes"] if str(x["id"]) == my_unique_id), None)
# if node:
# seed_num = prompt[my_unique_id]['inputs']['seed_num'] if 'seed_num' in prompt[my_unique_id][
# 'inputs'] else 0
# length = len(node["widgets_values"])
# node["widgets_values"][length - 2] = seed_num
# 图生图转换
vae = pipe["vae"]
@@ -2070,14 +2070,14 @@ class samplerSettingsAdvanced:
def settings(self, pipe, steps, cfg, sampler_name, scheduler, start_at_step, end_at_step, add_noise, seed_num, image_to_latent=None, latent=None, prompt=None, extra_pnginfo=None, my_unique_id=None):
if my_unique_id:
workflow = extra_pnginfo["workflow"]
node = next((x for x in workflow["nodes"] if str(x["id"]) == my_unique_id), None)
if node:
seed_num = prompt[my_unique_id]['inputs']['seed_num'] if 'seed_num' in prompt[my_unique_id][
'inputs'] else 0
length = len(node["widgets_values"])
node["widgets_values"][length - 2] = seed_num
# if my_unique_id:
# workflow = extra_pnginfo["workflow"]
# node = next((x for x in workflow["nodes"] if str(x["id"]) == my_unique_id), None)
# if node:
# seed_num = prompt[my_unique_id]['inputs']['seed_num'] if 'seed_num' in prompt[my_unique_id][
# 'inputs'] else 0
# length = len(node["widgets_values"])
# node["widgets_values"][length - 2] = seed_num
# 图生图转换
vae = pipe["vae"]
@@ -2192,14 +2192,14 @@ class sdTurboSettings:
_sampler = comfy.samplers.sampler_object(sampler_name)
extra_options = None
if my_unique_id:
workflow = extra_pnginfo["workflow"]
node = next((x for x in workflow["nodes"] if str(x["id"]) == my_unique_id), None)
if node:
seed_num = prompt[my_unique_id]['inputs']['seed_num'] if 'seed_num' in prompt[my_unique_id][
'inputs'] else 0
length = len(node["widgets_values"])
node["widgets_values"][length - 2] = seed_num
# if my_unique_id:
# workflow = extra_pnginfo["workflow"]
# node = next((x for x in workflow["nodes"] if str(x["id"]) == my_unique_id), None)
# if node:
# seed_num = prompt[my_unique_id]['inputs']['seed_num'] if 'seed_num' in prompt[my_unique_id][
# 'inputs'] else 0
# length = len(node["widgets_values"])
# node["widgets_values"][length - 2] = seed_num
new_pipe = {
"model": pipe['model'],
@@ -2278,13 +2278,14 @@ class dynamicCFGSettings:
m = model.clone()
m.set_model_sampler_cfg_function(sampler_dyn_thresh)
if my_unique_id:
workflow = extra_pnginfo["workflow"]
node = next((x for x in workflow["nodes"] if str(x["id"]) == my_unique_id), None)
if node:
seed_num = prompt[my_unique_id]['inputs']['seed_num'] if 'seed_num' in prompt[my_unique_id]['inputs'] else 0
length = len(node["widgets_values"])
node["widgets_values"][length - 2] = seed_num
# if my_unique_id:
# workflow = extra_pnginfo["workflow"]
# node = next((x for x in workflow["nodes"] if str(x["id"]) == my_unique_id), None)
# if node:
# seed_num = prompt[my_unique_id]['inputs']['seed_num'] if 'seed_num' in prompt[my_unique_id][
# 'inputs'] else 0
# length = len(node["widgets_values"])
# node["widgets_values"][length - 2] = seed_num
new_pipe = {
"model": m,
@@ -2406,13 +2407,13 @@ class samplerFull:
my_unique_id = int(my_unique_id)
if my_unique_id:
workflow = extra_pnginfo["workflow"]
node = next((x for x in workflow["nodes"] if str(x["id"]) == my_unique_id), None)
if node and 'seed_num' in prompt[my_unique_id]['inputs']:
seed_num = prompt[my_unique_id]['inputs']['seed_num']
length = len(node["widgets_values"])
node["widgets_values"][length - 2] = seed_num
# if my_unique_id:
# workflow = extra_pnginfo["workflow"]
# node = next((x for x in workflow["nodes"] if str(x["id"]) == my_unique_id), None)
# if node and 'seed_num' in prompt[my_unique_id]['inputs']:
# seed_num = prompt[my_unique_id]['inputs']['seed_num']
# length = len(node["widgets_values"])
# node["widgets_values"][length - 2] = seed_num
easy_save = easySave(my_unique_id, prompt, extra_pnginfo)
+71 -37
View File
@@ -8,6 +8,7 @@ class SGmode(Enum):
DECR = 3
RAND = 4
class SeedGenerator:
def __init__(self, base_value, action):
self.base_value = base_value
@@ -38,9 +39,9 @@ class SeedGenerator:
return seed
def control_seed(v):
action = v['inputs']['action']
value = v['inputs']['value']
def control_seed(v, action, seed_is_global):
action = action or v['inputs']['action']
value = v['inputs']['value'] if seed_is_global else v['inputs']['seed_num']
if action == 'increment' or action == 'increment for each node':
value += 1
@@ -53,7 +54,10 @@ def control_seed(v):
elif action == 'randomize' or action == 'randomize for each node':
value = random.randint(0, 1125899906842624)
v['inputs']['value'] = value
if seed_is_global:
v['inputs']['value'] = value
else:
v['inputs']['seed_num'] = value
return value
@@ -64,57 +68,83 @@ def prompt_seed_update(json_data):
except:
return None
seed_widget_map = json_data['extra_data']['extra_pnginfo']['workflow']['seed_widgets']
workflow = json_data['extra_data']['extra_pnginfo']['workflow']
seed_widget_map = workflow['seed_widgets']
value = None
mode = None
node = None
action = None
seed_is_global = False
for k, v in json_data['prompt'].items():
if 'class_type' not in v:
continue
cls = v['class_type']
if cls == 'globalSeed':
if cls == 'easy globalSeed':
mode = v['inputs']['mode']
action = v['inputs']['action']
value = v['inputs']['value']
node = k, v
seed_is_global = True
# control before generated
if mode is not None and mode:
value = control_seed(node[1])
if mode is not None and mode and seed_is_global:
value = control_seed(node[1], action, seed_is_global)
if value is not None:
seed_generator = SeedGenerator(value, action)
if seed_is_global:
if value is not None:
seed_generator = SeedGenerator(value, action)
for k, v in json_data['prompt'].items():
for k2, v2 in v['inputs'].items():
if isinstance(v2, str) and '$GlobalSeed.value$' in v2:
v['inputs'][k2] = v2.replace('$GlobalSeed.value$', str(value))
if k not in seed_widget_map:
continue
if 'seed_num' in v['inputs']:
if isinstance(v['inputs']['seed_num'], int):
v['inputs']['seed_num'] = seed_generator.next()
if 'seed' in v['inputs']:
if isinstance(v['inputs']['seed'], int):
v['inputs']['seed'] = seed_generator.next()
if 'noise_seed' in v['inputs']:
if isinstance(v['inputs']['noise_seed'], int):
v['inputs']['noise_seed'] = seed_generator.next()
for k2, v2 in v['inputs'].items():
if isinstance(v2, str) and '$GlobalSeed.value$' in v2:
v['inputs'][k2] = v2.replace('$GlobalSeed.value$', str(value))
# control after generated
if mode is not None and not mode:
control_seed(node[1], action, seed_is_global)
else:
for k, v in json_data['prompt'].items():
for k2, v2 in v['inputs'].items():
if isinstance(v2, str) and '$GlobalSeed.value$' in v2:
v['inputs'][k2] = v2.replace('$GlobalSeed.value$', str(value))
if k not in seed_widget_map:
if 'class_type' not in v:
continue
cls = v['class_type']
if cls == "easy wildcards" or cls == "easy preSampling" or cls == "easy preSamplingAdvanced" or cls == "easy preSamplingSdTurbo" or cls == "easy preSamplingDynamicCFG" or cls == "easy fullkSampler":
extra_data = next((x for x in workflow["nodes"] if str(x["id"]) == k), None)
if extra_data is not None:
widgets_value = extra_data.get('widgets_values')
widgets_length = len(widgets_value)
action = widgets_value[widgets_length - 1]
node = k, v
if 'seed_num' in v['inputs']:
if isinstance(v['inputs']['seed_num'], int):
v['inputs']['seed'] = seed_generator.next()
value = control_seed(node[1], action, False)
_seed_generator = SeedGenerator(value, action)
print(value)
if k not in seed_widget_map:
continue
if 'seed' in v['inputs']:
if isinstance(v['inputs']['seed'], int):
v['inputs']['seed'] = seed_generator.next()
if 'noise_seed' in v['inputs']:
if isinstance(v['inputs']['noise_seed'], int):
v['inputs']['noise_seed'] = seed_generator.next()
for k2, v2 in v['inputs'].items():
if isinstance(v2, str) and '$GlobalSeed.value$' in v2:
v['inputs'][k2] = v2.replace('$GlobalSeed.value$', str(value))
# control after generated
if mode is not None and not mode:
control_seed(node[1])
if 'seed_num' in v['inputs']:
if isinstance(v['inputs']['seed_num'], int):
v['inputs']['seed_num'] = _seed_generator.next()
return value is not None
@@ -126,19 +156,22 @@ def workflow_seed_update(json_data):
updated_seed_map = {}
value = None
for node in nodes:
node_id = str(node['id'])
if node_id in prompt:
if node['type'] == 'globalSeed':
if node['type'] == 'easy globalSeed':
value = prompt[node_id]['inputs']['value']
length = len(node['widgets_values'])
node['widgets_values'][length-1] = node['widgets_values'][0]
node['widgets_values'][0] = value
elif node_id in seed_widget_map:
widget_idx = seed_widget_map[node_id]
if 'noise_seed' in prompt[node_id]['inputs']:
seed = prompt[node_id]['inputs']['noise_seed']
elif 'seed_num' in prompt[node_id]['inputs']:
if 'seed_num' in prompt[node_id]['inputs']:
seed = prompt[node_id]['inputs']['seed_num']
elif 'noise_seed' in prompt[node_id]['inputs']:
seed = prompt[node_id]['inputs']['noise_seed']
else:
seed = prompt[node_id]['inputs']['seed']
@@ -147,6 +180,7 @@ def workflow_seed_update(json_data):
server.PromptServer.instance.send_sync("easyuse-global-seed", {"id": node_id, "value": value, "seed_map": updated_seed_map})
def onprompt(json_data):
is_changed = prompt_seed_update(json_data)
if is_changed:
+24 -24
View File
@@ -325,21 +325,21 @@ app.registerExtension({
}
if (["easy wildcards", "easy preSampling", "easy preSamplingAdvanced", "easy preSamplingSdTurbo", "easy preSamplingDynamicCFG", "easy fullkSampler"].includes(nodeData.name)) {
const control_seed = (action,seed) =>{
switch (action){
case 'randomize':
seed = Math.floor(Math.random() * 1125899906842624)
break
case 'increment':
seed = seed + 1
break
case 'decrement':
seed = seed - 1
break
}
return seed
}
// const control_seed = (action,seed) =>{
// switch (action){
// case 'randomize':
// seed = Math.floor(Math.random() * 1125899906842624)
// break
// case 'increment':
// seed = seed + 1
// break
// case 'decrement':
// seed = seed - 1
// break
// }
// return seed
// }
//
const onNodeCreated = nodeType.prototype.onNodeCreated;
nodeType.prototype.onNodeCreated = async function () {
onNodeCreated ? onNodeCreated.apply(this, []) : undefined;
@@ -348,15 +348,15 @@ app.registerExtension({
values,
serialize:false
})
let seedWidget = this.widgets.find(w=> w.name == "seed_num")
seedWidget.serializeValue = async (node, index) => {
const _seed = control_seed(seed_control.value,seedWidget.value)
if(node && node['widgets']){
node['widgets'][index]['value'] = _seed
if(node['widgets_values'] && node['widgets_values'][index]) node['widgets_values'][index] = _seed
}
return _seed
}
// let seedWidget = this.widgets.find(w=> w.name == "seed_num")
// seedWidget.serializeValue = async (node, index) => {
// const _seed = control_seed(seed_control.value,seedWidget.value)
// if(node && node['widgets']){
// node['widgets'][index]['value'] = _seed
// if(node['widgets_values'] && node['widgets_values'][index]) node['widgets_values'][index] = _seed
// }
// return _seed
// }
}
}
},
+92 -92
View File
@@ -794,96 +794,96 @@ app.registerExtension({
}
})
// 补充:解决control_before_generate时从历史记录调起时seed值不一致
const element = document.getElementsByClassName('comfy-list')
let new_element = null
async function load(){
const items = await api.getItems('history');
new_element.replaceChildren(
...Object.keys(items).flatMap((section) => [
$el("h4", {
textContent: section,
}),
$el("div.comfy-list-items", [
...(items[section].reverse()).map((item) => {
// Allow items to specify a custom remove action (e.g. for interrupt current prompt)
const removeAction = item.remove || {
name: "Delete",
cb: () => api.deleteItem('history', item.prompt[1]),
};
return $el("div", {textContent: item.prompt[0] + ": "}, [
$el("button", {
textContent: "Load",
onclick: async () => {
// 补充:解决control_before_generate时从历史记录调起时seed值错误
const outputs = item.outputs
let workflow = item.prompt[3].extra_pnginfo.workflow
const seed_widgets = workflow.seed_widgets
if(seed_widgets){
for(let id in seed_widgets){
id = parseInt(id)
if(outputs[id] && outputs[id]['value']){
const seed = outputs[id]['value'][0]
let nodeIndex = workflow.nodes.findIndex(cate=>cate.id == id)
if(nodeIndex!==-1 && workflow.nodes[nodeIndex]){
workflow.nodes[nodeIndex]['widgets_values'][seed_widgets[id]] = seed
}
}
}
}
// end
await app.loadGraphData(workflow);
if (item.outputs) {
app.nodeOutputs = item.outputs;
}
},
}),
$el("button", {
textContent: removeAction.name,
onclick: async () => {
await removeAction.cb();
if (new_element.style.display != 'none') {
await load();
}
},
}),
]);
}),
]),
]),
$el("div.comfy-list-actions", [
$el("button", {
textContent: "Clear History",
onclick: async () => {
await api.clearItems('history');
await load();
},
}),
$el("button", {textContent: "Refresh", onclick: () => load()}),
])
);
}
if(element && element[1]){
const history_button = document.getElementById('comfy-view-history-button')
history_button.addEventListener('click',e=>{
if(new_element){
if(new_element.style.display == 'none') new_element.style.display = 'block'
else new_element.style.display = 'none'
}
if(element[1].style.display != 'none'){
element[1].remove()
const parentNode = element[0].parentNode
new_element = document.createElement('div')
new_element.className = 'comfy-list easyuse'
new_element.style.display = 'block'
parentNode.insertBefore(new_element, element[0].nextSibling);
setTimeout(_=>load(),10)
}
})
}
api.addEventListener("status", () => {
if (new_element && new_element.style.display != 'none') {
load();
}
});
// 不需要了,之前的解决方案(解决control_before_generate时从历史记录调起时seed值不一致)
// const element = document.getElementsByClassName('comfy-list')
// let new_element = null
// async function load(){
// const items = await api.getItems('history');
// new_element.replaceChildren(
// ...Object.keys(items).flatMap((section) => [
// $el("h4", {
// textContent: section,
// }),
// $el("div.comfy-list-items", [
// ...(items[section].reverse()).map((item) => {
// // Allow items to specify a custom remove action (e.g. for interrupt current prompt)
// const removeAction = item.remove || {
// name: "Delete",
// cb: () => api.deleteItem('history', item.prompt[1]),
// };
// return $el("div", {textContent: item.prompt[0] + ": "}, [
// $el("button", {
// textContent: "Load",
// onclick: async () => {
// // 补充:解决control_before_generate时从历史记录调起时seed值错误
// const outputs = item.outputs
// let workflow = item.prompt[3].extra_pnginfo.workflow
// const seed_widgets = workflow.seed_widgets
// if(seed_widgets){
// for(let id in seed_widgets){
// id = parseInt(id)
// if(outputs[id] && outputs[id]['value']){
// const seed = outputs[id]['value'][0]
// let nodeIndex = workflow.nodes.findIndex(cate=>cate.id == id)
// if(nodeIndex!==-1 && workflow.nodes[nodeIndex]){
// workflow.nodes[nodeIndex]['widgets_values'][seed_widgets[id]] = seed
// }
// }
// }
// }
// // end
// await app.loadGraphData(workflow);
// if (item.outputs) {
// app.nodeOutputs = item.outputs;
// }
// },
// }),
// $el("button", {
// textContent: removeAction.name,
// onclick: async () => {
// await removeAction.cb();
// if (new_element.style.display != 'none') {
// await load();
// }
// },
// }),
// ]);
// }),
// ]),
// ]),
// $el("div.comfy-list-actions", [
// $el("button", {
// textContent: "Clear History",
// onclick: async () => {
// await api.clearItems('history');
// await load();
// },
// }),
// $el("button", {textContent: "Refresh", onclick: () => load()}),
// ])
// );
// }
// if(element && element[1]){
// const history_button = document.getElementById('comfy-view-history-button')
// history_button.addEventListener('click',e=>{
// if(new_element){
// if(new_element.style.display == 'none') new_element.style.display = 'block'
// else new_element.style.display = 'none'
// }
// if(element[1].style.display != 'none'){
// element[1].remove()
// const parentNode = element[0].parentNode
// new_element = document.createElement('div')
// new_element.className = 'comfy-list easyuse'
// new_element.style.display = 'block'
// parentNode.insertBefore(new_element, element[0].nextSibling);
// setTimeout(_=>load(),10)
// }
// })
// }
// api.addEventListener("status", () => {
// if (new_element && new_element.style.display != 'none') {
// load();
// }
// });
+2 -1
View File
@@ -5,7 +5,7 @@ function globalSeedHandler(event) {
let nodes = app.graph._nodes_by_id;
for(let i in nodes) {
let node = nodes[i];
if(node.type == 'globalSeed') {
if(node.type == 'easy globalSeed') {
if(node.widgets) {
const w = node.widgets.find((w) => w.name == 'value');
const last_w = node.widgets.find((w) => w.name == 'last_seed');
@@ -16,6 +16,7 @@ function globalSeedHandler(event) {
else{
if(node.widgets) {
const w = node.widgets.find((w) => w.name == 'seed_num' || w.name == 'seed' || w.name == 'noise_seed');
console.log(w)
if(w && event.detail.seed_map[node.id] != undefined) {
w.value = event.detail.seed_map[node.id];
}