Created new "collection primitives" system

This commit is contained in:
80sVectorz
2023-12-08 19:43:51 +01:00
parent edbea49e74
commit 58bf09cddb
5 changed files with 174 additions and 1 deletions
+12
View File
@@ -17,6 +17,18 @@ Here's an example of the original [Sytan's SDXL 1.0 Workflow](https://github.com
![Example](https://github.com/80sVectorz/ComfyUI-Static-Primitives/blob/main/images/Original.png?raw=true)
![Example](https://github.com/80sVectorz/ComfyUI-Static-Primitives/blob/main/images/CleanedUpExample.png?raw=true)
## Collection primitives
Aside from the basic types included in this extension there's also a
collection type system.
This system allows users to add custom collection types.
There are 2 included by default:
- samplers
- schedulers
More info about how you can add your own collection primitives can be found
[here](https://github.com/80sVectorz/ComfyUI-Static-Primitives/blob/main/collection_primitives/collection_primitives_readme.md).
# Rambling
I decided to install ComfyUI but got really discouraged by the wire spaghetti.
+38 -1
View File
@@ -1,6 +1,8 @@
from .static_primitives import *
from .collection_primitives import *
import os, shutil
import folder_paths
import json
module_js_directory = os.path.join(os.path.dirname(os.path.realpath(__file__)), "js")
application_root_directory = os.path.dirname(folder_paths.__file__)
@@ -8,17 +10,52 @@ application_web_extensions_directory = os.path.join(application_root_directory,
shutil.copytree(module_js_directory, application_web_extensions_directory, dirs_exist_ok=True)
collection_primitives_definitions_directory = os.path.join(os.path.dirname(os.path.realpath(__file__)), "collection_primitives")
definition_files = [f for f in os.listdir(collection_primitives_definitions_directory) if f.endswith('.json')]
collection_primitives_classes = {}
collection_primitives_node_class_mappings = {}
collection_primitives_node_display_name_mappings = {}
duplicate_counter = {}
for file in definition_files:
with open(os.path.join(collection_primitives_definitions_directory, file), 'r') as f:
data = json.load(f)
for key in data.keys():
duplicate_counter[key]=0
if key in collection_primitives_classes.keys():
duplicate_counter[key]+=1
continue
if type(data[key]) is not list or len(data[key]) == 0 or type(data[key][0]) is not str:
print(f"ComfyUI-Static-Primitives:\n !!Found invalid collection primitive definition with key: {key} skipping!!")
continue
new_class = CollectionPrimitiveFactory(key, data[key])
collection_primitives_classes[key] = new_class
collection_primitives_node_class_mappings[f"{key}StaticCollectionPrimitive"] = new_class
collection_primitives_node_display_name_mappings[f"{key}StaticCollectionPrimitive"] = f"Collection Primitive ({key})"
for key, duplicates in duplicate_counter.items():
if duplicates > 0:
print(f"ComfyUI-Static-Primitives:\n !!Found {duplicates+1} definitions using the same key: {key} skipping all!!")
collection_primitives_classes.remove(key)
collection_primitives_node_class_mappings.remove(f"{key}StaticCollectionPrimitive")
collection_primitives_node_display_name_mappings.remove(f"{key}StaticCollectionPrimitive")
NODE_CLASS_MAPPINGS = {
"StringStaticPrimitive": StringStaticPrimitive,
"StringMlStaticPrimitive": StringMlStaticPrimitive,
"IntStaticPrimitive": IntStaticPrimitive,
"FloatStaticPrimitive": FloatStaticPrimitive,
}
NODE_CLASS_MAPPINGS.update(collection_primitives_node_class_mappings)
# A dictionary that contains the friendly/humanly readable titles for the nodes
NODE_DISPLAY_NAME_MAPPINGS = {
"StringStaticPrimitive": "Primitive (STRING)",
"StringMlStaticPrimitive": "Primitive (STRING MULTI-LINE)",
"IntStaticPrimitive": "Primitive (INT)",
"FloatStaticPrimitive": "Primitive (FLOAT)",
}
NODE_DISPLAY_NAME_MAPPINGS.update(collection_primitives_node_display_name_mappings)
+33
View File
@@ -0,0 +1,33 @@
class BaseCollectionPrimitive:
def __init__(self):
pass
@classmethod
def INPUT_TYPES(s):
return {
"required": {
f"Input_{s.COLLECTION_TYPE}": (s.RETURN_TYPES[0],),
},
}
COLLECTION_TYPE = None
RETURN_TYPES = ([],)
INPUT_FIELD_CONFIG_ID = None
FUNCTION = "output"
CATEGORY = "primitives"
def output(self, **kwargs):
return (kwargs[f"Input_{self.COLLECTION_TYPE}"],)
def CollectionPrimitiveFactory(key,collection):
def __init__(self, **kwargs):
BaseCollectionPrimitive.__init__(self)
new_class = type(f"{key}StaticCollectionPrimitive", (BaseCollectionPrimitive,),{"__init__": __init__})
new_class.COLLECTION_TYPE = key
new_class.RETURN_TYPES = (collection,)
return new_class
@@ -0,0 +1,57 @@
# Adding custom collection primitives
Adding your own collection primitives is quite simple.
Each group of collection primitives is defined in a `.json` file.
These files should be placed in this directory:
`ComfyUI-Static-Primitives/collection_primitives/`
## Collection primitive definition structure
Let's look at an example.
```json
{
"scheduler": [
"normal",
"karras",
"exponential",
"sgm_uniform",
"simple",
"ddim_uniform"
],
"sampler" : [
"euler",
"euler_ancestral",
"heun",
"heunpp2",
"dpm_2",
"dpm_2_ancestral",
"lms",
"dpm_fast",
"dpm_adaptive",
"dpmpp_2s_ancestral",
"dpmpp_sde",
"dpmpp_sde_gpu",
"dpmpp_2m",
"dpmpp_2m_sde",
"dpmpp_2m_sde_gpu",
"dpmpp_3m_sde",
"dpmpp_3m_sde_gpu",
"ddpm",
"lcm",
"ddim",
"uni_pc",
"uni_pc_bh2"
]
}
```
This is the contents of the by default included file
`samplers_and_schedulers.json`.
You can see two key value pairs scheduler and sampler.
The key will be used for the display name of their respective nodes.
The value of each key is a list of strings.
These directly translate to the options for the node's dropdown.
*NOTE*:
It is important to avoid having duplicate keys across files.
If any duplicate keys are found while loading, all definitions with that key will be ignored
@@ -0,0 +1,34 @@
{
"scheduler": [
"normal",
"karras",
"exponential",
"sgm_uniform",
"simple",
"ddim_uniform"
],
"sampler" : [
"euler",
"euler_ancestral",
"heun",
"heunpp2",
"dpm_2",
"dpm_2_ancestral",
"lms",
"dpm_fast",
"dpm_adaptive",
"dpmpp_2s_ancestral",
"dpmpp_sde",
"dpmpp_sde_gpu",
"dpmpp_2m",
"dpmpp_2m_sde",
"dpmpp_2m_sde_gpu",
"dpmpp_3m_sde",
"dpmpp_3m_sde_gpu",
"ddpm",
"lcm",
"ddim",
"uni_pc",
"uni_pc_bh2"
]
}