Files
2025-11-24 22:15:15 -05:00

362 lines
14 KiB
Python

"""
ComfyUI_Detonate - Professional Compositing Nodes for ComfyUI
Brings Nuke and Fusion-style compositing workflows to ComfyUI.
"""
# Version info
__version__ = "0.10.0"
__author__ = "ComfyUI_Detonate Contributors"
# Node mappings - will be populated as nodes are implemented
NODE_CLASS_MAPPINGS = {}
NODE_DISPLAY_NAME_MAPPINGS = {}
# Import nodes as they are implemented
# Priority 1 Nodes - Implemented ✓
try:
from .nodes.channel.premultiply import DetonatePremultiply, DetonateUnpremultiply
NODE_CLASS_MAPPINGS["DetonatePremultiply"] = DetonatePremultiply
NODE_CLASS_MAPPINGS["DetonateUnpremultiply"] = DetonateUnpremultiply
NODE_DISPLAY_NAME_MAPPINGS["DetonatePremultiply"] = "Premultiply (Detonate)"
NODE_DISPLAY_NAME_MAPPINGS["DetonateUnpremultiply"] = "Unpremultiply (Detonate)"
except ImportError as e:
print(f"Warning: Could not load Premult nodes: {e}")
try:
from .nodes.channel.shuffle import DetonateShuffle
NODE_CLASS_MAPPINGS["DetonateShuffle"] = DetonateShuffle
NODE_DISPLAY_NAME_MAPPINGS["DetonateShuffle"] = "Shuffle (Detonate)"
except ImportError as e:
print(f"Warning: Could not load Shuffle node: {e}")
try:
from .nodes.filter.blur import DetonateBlur
NODE_CLASS_MAPPINGS["DetonateBlur"] = DetonateBlur
NODE_DISPLAY_NAME_MAPPINGS["DetonateBlur"] = "Blur (Detonate)"
except ImportError as e:
print(f"Warning: Could not load Blur node: {e}")
try:
from .nodes.compositing.merge import DetonateMerge
NODE_CLASS_MAPPINGS["DetonateMerge"] = DetonateMerge
NODE_DISPLAY_NAME_MAPPINGS["DetonateMerge"] = "Merge (Detonate)"
except ImportError as e:
print(f"Warning: Could not load Merge node: {e}")
try:
from .nodes.color.colorcorrect import DetonateColorCorrect
NODE_CLASS_MAPPINGS["DetonateColorCorrect"] = DetonateColorCorrect
NODE_DISPLAY_NAME_MAPPINGS["DetonateColorCorrect"] = "ColorCorrect (Detonate)"
except ImportError as e:
print(f"Warning: Could not load ColorCorrect node: {e}")
try:
from .nodes.color.grade import DetonateGrade
NODE_CLASS_MAPPINGS["DetonateGrade"] = DetonateGrade
NODE_DISPLAY_NAME_MAPPINGS["DetonateGrade"] = "Grade (Detonate)"
except ImportError as e:
print(f"Warning: Could not load Grade node: {e}")
try:
from .nodes.matte.erode_dilate import DetonateErode, DetonateDilate
NODE_CLASS_MAPPINGS["DetonateErode"] = DetonateErode
NODE_CLASS_MAPPINGS["DetonateDilate"] = DetonateDilate
NODE_DISPLAY_NAME_MAPPINGS["DetonateErode"] = "Erode (Detonate)"
NODE_DISPLAY_NAME_MAPPINGS["DetonateDilate"] = "Dilate (Detonate)"
except ImportError as e:
print(f"Warning: Could not load Erode/Dilate nodes: {e}")
try:
from .nodes.transform.transform import DetonateTransform
NODE_CLASS_MAPPINGS["DetonateTransform"] = DetonateTransform
NODE_DISPLAY_NAME_MAPPINGS["DetonateTransform"] = "Transform (Detonate)"
except ImportError as e:
print(f"Warning: Could not load Transform node: {e}")
# Tier 2 Nodes - Essential Utilities ✓
try:
from .nodes.color.clamp import DetonateClamp
NODE_CLASS_MAPPINGS["DetonateClamp"] = DetonateClamp
NODE_DISPLAY_NAME_MAPPINGS["DetonateClamp"] = "Clamp (Detonate)"
except ImportError as e:
print(f"Warning: Could not load Clamp node: {e}")
try:
from .nodes.color.invert import DetonateInvert
NODE_CLASS_MAPPINGS["DetonateInvert"] = DetonateInvert
NODE_DISPLAY_NAME_MAPPINGS["DetonateInvert"] = "Invert (Detonate)"
except ImportError as e:
print(f"Warning: Could not load Invert node: {e}")
try:
from .nodes.generator.constant import DetonateConstant
NODE_CLASS_MAPPINGS["DetonateConstant"] = DetonateConstant
NODE_DISPLAY_NAME_MAPPINGS["DetonateConstant"] = "Constant (Detonate)"
except ImportError as e:
print(f"Warning: Could not load Constant node: {e}")
try:
from .nodes.color.saturation import DetonateSaturation
NODE_CLASS_MAPPINGS["DetonateSaturation"] = DetonateSaturation
NODE_DISPLAY_NAME_MAPPINGS["DetonateSaturation"] = "Saturation (Detonate)"
except ImportError as e:
print(f"Warning: Could not load Saturation node: {e}")
try:
from .nodes.matte.mattecontrol import DetonateMatteControl
NODE_CLASS_MAPPINGS["DetonateMatteControl"] = DetonateMatteControl
NODE_DISPLAY_NAME_MAPPINGS["DetonateMatteControl"] = "MatteControl (Detonate)"
except ImportError as e:
print(f"Warning: Could not load MatteControl node: {e}")
try:
from .nodes.channel.channelcopy import DetonateChannelCopy
NODE_CLASS_MAPPINGS["DetonateChannelCopy"] = DetonateChannelCopy
NODE_DISPLAY_NAME_MAPPINGS["DetonateChannelCopy"] = "ChannelCopy (Detonate)"
except ImportError as e:
print(f"Warning: Could not load ChannelCopy node: {e}")
try:
from .nodes.filter.edgedetect import DetonateEdgeDetect
NODE_CLASS_MAPPINGS["DetonateEdgeDetect"] = DetonateEdgeDetect
NODE_DISPLAY_NAME_MAPPINGS["DetonateEdgeDetect"] = "EdgeDetect (Detonate)"
except ImportError as e:
print(f"Warning: Could not load EdgeDetect node: {e}")
# IO Nodes - File Loaders ✓
try:
from .nodes.io.load_exr import DetonateLoadEXR
NODE_CLASS_MAPPINGS["DetonateLoadEXR"] = DetonateLoadEXR
NODE_DISPLAY_NAME_MAPPINGS["DetonateLoadEXR"] = "Load EXR (Detonate)"
except ImportError as e:
print(f"Warning: Could not load LoadEXR node: {e}")
# Cryptomatte Nodes - Object/Material ID Mattes ✓
try:
from .nodes.cryptomatte.cryptomatte_extract import DetonateCryptomatteExtract
NODE_CLASS_MAPPINGS["DetonateCryptomatteExtract"] = DetonateCryptomatteExtract
NODE_DISPLAY_NAME_MAPPINGS["DetonateCryptomatteExtract"] = "Cryptomatte Extract (Detonate)"
except ImportError as e:
print(f"Warning: Could not load Cryptomatte Extract node: {e}")
# Tier 3 Nodes - Effects & Color ✓
try:
from .nodes.filter.glow import DetonateGlow
NODE_CLASS_MAPPINGS["DetonateGlow"] = DetonateGlow
NODE_DISPLAY_NAME_MAPPINGS["DetonateGlow"] = "Glow (Detonate)"
except ImportError as e:
print(f"Warning: Could not load Glow node: {e}")
try:
from .nodes.filter.sharpen import DetonateSharpen
NODE_CLASS_MAPPINGS["DetonateSharpen"] = DetonateSharpen
NODE_DISPLAY_NAME_MAPPINGS["DetonateSharpen"] = "Sharpen (Detonate)"
except ImportError as e:
print(f"Warning: Could not load Sharpen node: {e}")
try:
from .nodes.filter.defocus import DetonateDefocus
NODE_CLASS_MAPPINGS["DetonateDefocus"] = DetonateDefocus
NODE_DISPLAY_NAME_MAPPINGS["DetonateDefocus"] = "Defocus (Detonate)"
except ImportError as e:
print(f"Warning: Could not load Defocus node: {e}")
try:
from .nodes.filter.zdefocus import DetonateZDefocus
NODE_CLASS_MAPPINGS["DetonateZDefocus"] = DetonateZDefocus
NODE_DISPLAY_NAME_MAPPINGS["DetonateZDefocus"] = "ZDefocus (Detonate)"
except ImportError as e:
print(f"Warning: Could not load ZDefocus node: {e}")
try:
from .nodes.compositing.zmerge import DetonateZMerge
NODE_CLASS_MAPPINGS["DetonateZMerge"] = DetonateZMerge
NODE_DISPLAY_NAME_MAPPINGS["DetonateZMerge"] = "ZMerge (Detonate)"
except ImportError as e:
print(f"Warning: Could not load ZMerge node: {e}")
try:
from .nodes.color.colorcurves import DetonateColorCurves
NODE_CLASS_MAPPINGS["DetonateColorCurves"] = DetonateColorCurves
NODE_DISPLAY_NAME_MAPPINGS["DetonateColorCurves"] = "ColorCurves (Detonate)"
except ImportError as e:
print(f"Warning: Could not load ColorCurves node: {e}")
try:
from .nodes.generator.ramp import DetonateRamp
NODE_CLASS_MAPPINGS["DetonateRamp"] = DetonateRamp
NODE_DISPLAY_NAME_MAPPINGS["DetonateRamp"] = "Ramp (Detonate)"
except ImportError as e:
print(f"Warning: Could not load Ramp node: {e}")
try:
from .nodes.generator.noise import DetonateNoise
NODE_CLASS_MAPPINGS["DetonateNoise"] = DetonateNoise
NODE_DISPLAY_NAME_MAPPINGS["DetonateNoise"] = "Noise (Detonate)"
except ImportError as e:
print(f"Warning: Could not load Noise node: {e}")
# Tier 4 Nodes - Production Finishing ✓
try:
from .nodes.transform.crop import DetonateCrop
NODE_CLASS_MAPPINGS["DetonateCrop"] = DetonateCrop
NODE_DISPLAY_NAME_MAPPINGS["DetonateCrop"] = "Crop (Detonate)"
except ImportError as e:
print(f"Warning: Could not load Crop node: {e}")
try:
from .nodes.color.exposure import DetonateExposure
NODE_CLASS_MAPPINGS["DetonateExposure"] = DetonateExposure
NODE_DISPLAY_NAME_MAPPINGS["DetonateExposure"] = "Exposure (Detonate)"
except ImportError as e:
print(f"Warning: Could not load Exposure node: {e}")
try:
from .nodes.filter.vignette import DetonateVignette
NODE_CLASS_MAPPINGS["DetonateVignette"] = DetonateVignette
NODE_DISPLAY_NAME_MAPPINGS["DetonateVignette"] = "Vignette (Detonate)"
except ImportError as e:
print(f"Warning: Could not load Vignette node: {e}")
try:
from .nodes.filter.grain import DetonateGrain
NODE_CLASS_MAPPINGS["DetonateGrain"] = DetonateGrain
NODE_DISPLAY_NAME_MAPPINGS["DetonateGrain"] = "Grain (Detonate)"
except ImportError as e:
print(f"Warning: Could not load Grain node: {e}")
try:
from .nodes.color.huesatval import DetonateHueSatVal
NODE_CLASS_MAPPINGS["DetonateHueSatVal"] = DetonateHueSatVal
NODE_DISPLAY_NAME_MAPPINGS["DetonateHueSatVal"] = "HueSatVal (Detonate)"
except ImportError as e:
print(f"Warning: Could not load HueSatVal node: {e}")
try:
from .nodes.filter.denoise import DetonateDenoise
NODE_CLASS_MAPPINGS["DetonateDenoise"] = DetonateDenoise
NODE_DISPLAY_NAME_MAPPINGS["DetonateDenoise"] = "Denoise (Detonate)"
except ImportError as e:
print(f"Warning: Could not load Denoise node: {e}")
try:
from .nodes.color.lut import DetonateLUT
NODE_CLASS_MAPPINGS["DetonateLUT"] = DetonateLUT
NODE_DISPLAY_NAME_MAPPINGS["DetonateLUT"] = "LUT (Detonate)"
except ImportError as e:
print(f"Warning: Could not load LUT node: {e}")
try:
from .nodes.transform.cornerpin import DetonateCornerPin
NODE_CLASS_MAPPINGS["DetonateCornerPin"] = DetonateCornerPin
NODE_DISPLAY_NAME_MAPPINGS["DetonateCornerPin"] = "CornerPin (Detonate)"
except ImportError as e:
print(f"Warning: Could not load CornerPin node: {e}")
# Tier 5 Nodes - Interactive Masking ✓
try:
from .nodes.matte.roto_bezier import DetonateRotoBezier, DetonateRotoBezierFromImage
NODE_CLASS_MAPPINGS["DetonateRotoBezier"] = DetonateRotoBezier
NODE_CLASS_MAPPINGS["DetonateRotoBezierFromImage"] = DetonateRotoBezierFromImage
NODE_DISPLAY_NAME_MAPPINGS["DetonateRotoBezier"] = "RotoBezier (Detonate)"
NODE_DISPLAY_NAME_MAPPINGS["DetonateRotoBezierFromImage"] = "RotoBezier From Image (Detonate)"
except ImportError as e:
print(f"Warning: Could not load RotoBezier nodes: {e}")
try:
from .nodes.matte.mask_smoother import DetonateMaskSmoother, DetonateMaskFromColor
NODE_CLASS_MAPPINGS["DetonateMaskSmoother"] = DetonateMaskSmoother
NODE_CLASS_MAPPINGS["DetonateMaskFromColor"] = DetonateMaskFromColor
NODE_DISPLAY_NAME_MAPPINGS["DetonateMaskSmoother"] = "Mask Smoother (Detonate)"
NODE_DISPLAY_NAME_MAPPINGS["DetonateMaskFromColor"] = "Mask From Color (Detonate)"
except ImportError as e:
print(f"Warning: Could not load MaskSmoother nodes: {e}")
# Tier 6 Nodes - Professional Keying ✓
try:
from .nodes.keying.chromakeyer import DetonateChromaKeyer
NODE_CLASS_MAPPINGS["DetonateChromaKeyer"] = DetonateChromaKeyer
NODE_DISPLAY_NAME_MAPPINGS["DetonateChromaKeyer"] = "ChromaKeyer (Detonate)"
except ImportError as e:
print(f"Warning: Could not load ChromaKeyer node: {e}")
try:
from .nodes.keying.lumakeyer import DetonateLumaKeyer, DetonateLumaKeyerSimple
NODE_CLASS_MAPPINGS["DetonateLumaKeyer"] = DetonateLumaKeyer
NODE_CLASS_MAPPINGS["DetonateLumaKeyerSimple"] = DetonateLumaKeyerSimple
NODE_DISPLAY_NAME_MAPPINGS["DetonateLumaKeyer"] = "LumaKeyer (Detonate)"
NODE_DISPLAY_NAME_MAPPINGS["DetonateLumaKeyerSimple"] = "LumaKeyer Simple (Detonate)"
except ImportError as e:
print(f"Warning: Could not load LumaKeyer nodes: {e}")
# Bridge Tools - GenAI/Comp Integration ✓
try:
from .nodes.matte.edgedefringe import DetonateEdgeDefringe
NODE_CLASS_MAPPINGS["DetonateEdgeDefringe"] = DetonateEdgeDefringe
NODE_DISPLAY_NAME_MAPPINGS["DetonateEdgeDefringe"] = "Edge Defringe (Detonate)"
except ImportError as e:
print(f"Warning: Could not load EdgeDefringe node: {e}")
try:
from .nodes.transform.displacementmap import DetonateDisplacementMap
NODE_CLASS_MAPPINGS["DetonateDisplacementMap"] = DetonateDisplacementMap
NODE_DISPLAY_NAME_MAPPINGS["DetonateDisplacementMap"] = "Displacement Map (Detonate)"
except ImportError as e:
print(f"Warning: Could not load DisplacementMap node: {e}")
try:
from .nodes.transform.gridwarp import DetonateGridWarp
NODE_CLASS_MAPPINGS["DetonateGridWarp"] = DetonateGridWarp
NODE_DISPLAY_NAME_MAPPINGS["DetonateGridWarp"] = "GridWarp (Detonate)"
except ImportError as e:
print(f"Warning: Could not load GridWarp node: {e}")
# Bridge Tools Round 2 - More GenAI Integration ✓
try:
from .nodes.matte.trimapgenerator import DetonateTriMapGenerator
NODE_CLASS_MAPPINGS["DetonateTriMapGenerator"] = DetonateTriMapGenerator
NODE_DISPLAY_NAME_MAPPINGS["DetonateTriMapGenerator"] = "TriMap Generator (Detonate)"
except ImportError as e:
print(f"Warning: Could not load TriMapGenerator node: {e}")
try:
from .nodes.compositing.seamblender import DetonateSeamBlender
NODE_CLASS_MAPPINGS["DetonateSeamBlender"] = DetonateSeamBlender
NODE_DISPLAY_NAME_MAPPINGS["DetonateSeamBlender"] = "Seam Blender (Detonate)"
except ImportError as e:
print(f"Warning: Could not load SeamBlender node: {e}")
# Web directory for custom JavaScript widgets
WEB_DIRECTORY = "./web"
# Export for ComfyUI
__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS", "WEB_DIRECTORY"]
# Print debug info on load
print("\n" + "="*60)
print("ComfyUI_Detonate - Professional Compositing Nodes")
print(f"Version: {__version__}")
print(f"Loaded {len(NODE_CLASS_MAPPINGS)} nodes")
if NODE_CLASS_MAPPINGS:
print("\nRegistered nodes:")
for name in sorted(NODE_CLASS_MAPPINGS.keys()):
display_name = NODE_DISPLAY_NAME_MAPPINGS.get(name, name)
print(f" - {display_name}")
else:
print("\nNo nodes loaded yet - nodes will be added in development")
print("This is expected for initial setup.")
print("="*60 + "\n")