diff --git a/README.en.md b/README.en.md
index c7fc3a3..c99b47a 100644
--- a/README.en.md
+++ b/README.en.md
@@ -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
@@ -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
diff --git a/README.md b/README.md
index 2b4517b..ca1c5ad 100644
--- a/README.md
+++ b/README.md
@@ -13,8 +13,6 @@
## 介绍
-**不兼容提示**:目前无法与 [cg-use-everywhere](https://github.com/chrisgoringe/cg-use-everywhere) 节点包当前版本兼容(该节点包的机制会导致序列化时随机种一直赋值等问题),可使用 **getNode**、**setNode** 替代。
-
### 更符合人性化的随机种
@@ -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` - 简易正面提示词文本
diff --git a/py/easyNodes.py b/py/easyNodes.py
index e3c06d1..7f5fead 100644
--- a/py/easyNodes.py
+++ b/py/easyNodes.py
@@ -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)
diff --git a/py/server.py b/py/server.py
index fcee888..dc6c98d 100644
--- a/py/server.py
+++ b/py/server.py
@@ -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:
diff --git a/web/js/easy/easyDynamicWidgets.js b/web/js/easy/easyDynamicWidgets.js
index 3f8c56f..6b82b12 100644
--- a/web/js/easy/easyDynamicWidgets.js
+++ b/web/js/easy/easyDynamicWidgets.js
@@ -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
+ // }
}
}
},
diff --git a/web/js/easy/easyInterface.js b/web/js/easy/easyInterface.js
index 22e4cd5..7c1ed02 100644
--- a/web/js/easy/easyInterface.js
+++ b/web/js/easy/easyInterface.js
@@ -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();
+// }
+// });
diff --git a/web/js/seed.js b/web/js/seed.js
index 9bccf43..9dff246 100644
--- a/web/js/seed.js
+++ b/web/js/seed.js
@@ -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];
}