Created new "collection primitives" system
This commit is contained in:
@@ -17,6 +17,18 @@ Here's an example of the original [Sytan's SDXL 1.0 Workflow](https://github.com
|
||||

|
||||

|
||||
|
||||
## 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
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user