import traceback NODE_CLASS_MAPPINGS = {} NODE_DISPLAY_NAME_MAPPINGS = {} WEB_DIRECTORY = "./web" def register_node(class_name, node_class, display_name): NODE_CLASS_MAPPINGS[class_name] = node_class NODE_DISPLAY_NAME_MAPPINGS[class_name] = display_name # 1. Wan Native Resize (이미지 -> WAN 해상도 리사이즈, 비율 유지 + 정렬) try: from .wan_resizer import WanNativeResize_Dolphin register_node("WanNativeResize_Dolphin", WanNativeResize_Dolphin, "🐬 Wan Native Resize (Dolphin)") except Exception: print(f"\n❌ [Dolphin] Wan Resize 로드 실패:\n{traceback.format_exc()}") # 2. Story Splitter V32 (텍스트 서사 -> 4샷 프롬프트 분배) try: from .promp_logic_v32_story import DolphinMultiActionPromptNode_V32 register_node("DolphinMultiActionPromptNode_V32", DolphinMultiActionPromptNode_V32, "🐬 Dolphin Story Splitter V32") except Exception: print(f"\n❌ [Dolphin] V32 Story Splitter 로드 실패:\n{traceback.format_exc()}") # 3. Architect V16 (클립별 LoRA -> TripleKSampler, model-only) try: from .arch_logic_v16 import DolphinTripleLoraMatrix as DolphinArchitectV16 register_node("DolphinArchitectV16", DolphinArchitectV16, "🐬 Dolphin Architect V16") except Exception: print(f"\n❌ [Dolphin] Architect V16 로드 실패:\n{traceback.format_exc()}") # 4. Cinematic Director (올인원: 스토리 분배 + 클립별 로라 + 트리거 주입) try: from .dolphin_director import DolphinCinematicDirector register_node("DolphinCinematicDirector", DolphinCinematicDirector, "🎬 Dolphin Cinematic Director (All-in-One)") except Exception: print(f"\n❌ [Dolphin] Cinematic Director 로드 실패:\n{traceback.format_exc()}") # 5. Vision Director (이미지 인식 + 필수동작 + 클립당 로라 4개) try: from .dolphin_vision_director import DolphinVisionDirector register_node("DolphinVisionDirector", DolphinVisionDirector, "🎬👁 Dolphin Vision Director (Image→4Clips)") except Exception: print(f"\n❌ [Dolphin] Vision Director 로드 실패:\n{traceback.format_exc()}") # 6. Architect V15 (arch_logic_v16 이전 구버전, model_base/high/low + clip 개별 입력) try: from .arch_logic import DolphinArchitectV15 register_node("DolphinArchitectV15", DolphinArchitectV15, "🐬 Dolphin Architect V15 (legacy)") except Exception: print(f"\n❌ [Dolphin] Architect V15 로드 실패:\n{traceback.format_exc()}") # 7. Story Splitter V28 (V32 이전 구버전, stitch 방식) try: from .promp_logic_v28_stitch import DolphinMultiActionPromptNode_V28 register_node("DolphinMultiActionPromptNode_V28", DolphinMultiActionPromptNode_V28, "🐬 Dolphin Story Splitter V28 (legacy)") except Exception: print(f"\n❌ [Dolphin] V28 Story Splitter 로드 실패:\n{traceback.format_exc()}") # 8. Story Splitter V30 (V32 이전 구버전) try: from .promp_logic_v30_story import DolphinMultiActionPromptNode_V30 register_node("DolphinMultiActionPromptNode_V30", DolphinMultiActionPromptNode_V30, "🐬 Dolphin Story Splitter V30 (legacy)") except Exception: print(f"\n❌ [Dolphin] V30 Story Splitter 로드 실패:\n{traceback.format_exc()}") # 9. Prompt V32 Vision (promp_logic_v32_story.py의 DolphinMultiActionPromptNode_V32와 # 클래스명이 동일해서 충돌 — 등록 키/클래스명을 _Vision으로 구분해서 둘 다 살림) try: from .promp_logic_v32_vision import DolphinMultiActionPromptNode_V32 as DolphinMultiActionPromptNode_V32_Vision register_node("DolphinMultiActionPromptNode_V32_Vision", DolphinMultiActionPromptNode_V32_Vision, "🐬 Dolphin Prompt V32 Vision (legacy)") except Exception: print(f"\n❌ [Dolphin] V32 Vision 로드 실패:\n{traceback.format_exc()}") # 10. Match Image & Mask Size (인페인트 블렌드용: 이미지/마스크를 참조 이미지 실제 크기에 맞춤) try: from .match_size import MatchImageAndMaskSize_Dolphin register_node("MatchImageAndMaskSize_Dolphin", MatchImageAndMaskSize_Dolphin, "🐬 Match Image & Mask Size (Dolphin)") except Exception: print(f"\n❌ [Dolphin] Match Image & Mask Size 로드 실패:\n{traceback.format_exc()}") # 11. Mask-Region Color Match (인페인트 마스크 영역만 국소적으로 색보정) try: from .mask_region_color_match import MaskRegionColorMatch_Dolphin register_node("MaskRegionColorMatch_Dolphin", MaskRegionColorMatch_Dolphin, "🐬 Mask-Region Color Match (Dolphin)") except Exception: print(f"\n❌ [Dolphin] Mask-Region Color Match 로드 실패:\n{traceback.format_exc()}") # 12. Prompt Director (Vision Director와 동일한 비전+LLM 엔진, MODEL/LoRA 전부 제거 - # 프롬프트 분배만. 로라/모델은 Architect V16 등 별도 노드에서 처리한다는 전제) try: from .dolphin_prompt_director import ( DolphinPromptDirector, DolphinPromptDirectorSingle, DolphinActionSplitter, ) register_node("DolphinPromptDirector", DolphinPromptDirector, "🎬📝 Dolphin Prompt Director (Image→N Prompts, no model/LoRA)") register_node("DolphinPromptDirectorSingle", DolphinPromptDirectorSingle, "🎬📝 Dolphin Prompt Director (Single, Image→1 Prompt)") register_node("DolphinActionSplitter", DolphinActionSplitter, "✂️ Dolphin Action Splitter (deterministic, no LLM)") except Exception: print(f"\n❌ [Dolphin] Prompt Director 로드 실패:\n{traceback.format_exc()}") # 13. WanImageToVideoSVIPro mask 버그 수정판 (comfyui-kjnodes 원본은 motion_latent_count로 # 이어붙인 모션 컨텍스트 프레임을 concat_mask에서 "known"으로 표시하지 않아서, 클립 # 경계에서 몇 프레임 반복 후 전혀 다른 영상으로 튀는 문제가 있었음. anchor+motion 프레임 # 전체를 known(0.0)으로 마스킹하도록 수정.) try: from .wan_svipro_fixed import WanImageToVideoSVIProFixed_Dolphin register_node("WanImageToVideoSVIProFixed_Dolphin", WanImageToVideoSVIProFixed_Dolphin, "🐬 Wan I2V SVIPro (motion-mask fix)") except Exception: print(f"\n❌ [Dolphin] SVIPro Fixed 로드 실패:\n{traceback.format_exc()}") # 14. Wan I2V Continuity (코어 WanImageToVideo 방식 = known 프레임 여러 장을 회색 filler와 # 함께 한 번에 통짜 VAE 인코딩 → latent 문맥 일관성 보장. SVIPro식 raw latent 스플라이싱의 # 화질 튐/불연속 문제를 회피. PainterI2V의 motion_amplitude(슬로우모션 방지) 이식.) try: from .wan_i2v_continuity import WanI2VContinuity_Dolphin register_node("WanI2VContinuity_Dolphin", WanI2VContinuity_Dolphin, "🐬 Wan I2V Continuity (multi-frame + amplitude)") except Exception: print(f"\n❌ [Dolphin] Wan I2V Continuity 로드 실패:\n{traceback.format_exc()}") # 15. SVIPro 드롭인 교체 (슬로우모션 수정). 원본은 filler를 latent 공간에서 # Wan21().process_out(zeros) = latents_mean 상수로 채워서 "변화 없음" 신호를 주고 # 분포 밖 입력이 됐음 -> 코어 WanImageToVideo/PainterI2V처럼 회색(0.5) 픽셀을 VAE # 인코딩한 filler로 교체. 마스크 버그(anchor 1프레임만 known)도 함께 수정. try: from .wan_svipro_gray import WanImageToVideoSVIProGray_Dolphin register_node("WanImageToVideoSVIProGray_Dolphin", WanImageToVideoSVIProGray_Dolphin, "🐬 Wan I2V SVIPro (gray filler, slow-motion fix)") except Exception: print(f"\n❌ [Dolphin] SVIPro Gray 로드 실패:\n{traceback.format_exc()}") # 16. SVIPro 드롭인 교체 (모션 증폭판). 15번(gray)과 달리 패딩·마스크는 상류 원본 그대로 두고 # PainterI2V의 diff 증폭만 얹는다 — SVI Pro LoRA가 원본 규약 위에서 학습됐기 때문. # high/low conditioning을 따로 뽑아서 모션 증폭은 high-noise 스테이지에만 먹인다. # motion_amplitude=1.0이면 상류 원본과 출력이 동일(회귀 확인용). try: from .wan_svipro_motion import WanImageToVideoSVIProMotion_Dolphin register_node("WanImageToVideoSVIProMotion_Dolphin", WanImageToVideoSVIProMotion_Dolphin, "🐬 Wan I2V SVIPro (motion amplitude, hi/lo split)") except Exception: print(f"\n❌ [Dolphin] SVIPro Motion 로드 실패:\n{traceback.format_exc()}") # 17. 디스크 노드 캐시 (노드가 아니라 ComfyUI cache provider 등록). # 시드/프롬프트/이미지가 같으면 재시작 후에도 JoyCaption~샘플러 체인을 스킵하고 # 디스크에서 결과 복원. RAM_PRESSURE 모드의 캐시 증발도 디스크에서 자동 복구. try: from . import disk_cache_provider disk_cache_provider.register() except Exception: print(f"\n❌ [Dolphin] 디스크 노드 캐시 로드 실패 (구버전 ComfyUI엔 provider API 없음):\n{traceback.format_exc()}") # 18. Batch Seed Controller (4클립 영상 샘플러 시드를 한 노드에서 스위칭: # 고정/전체랜덤/특정클립만재생성). try: from .dolphin_seed_controller import DolphinBatchSeedController register_node("DolphinBatchSeedController", DolphinBatchSeedController, "🎲 Dolphin Batch Seed Controller (random-all / regen-from-clip)") except Exception: print(f"\n❌ [Dolphin] Batch Seed Controller 로드 실패:\n{traceback.format_exc()}") # 19. LoRA Prompt Weaver (완성된 클립 프롬프트를 "그 클립에 걸리는 로라들이 잘 발화하도록" # 다시 쓰는 후처리 노드. 로라 사이드카(.metadata.json)의 설명/태그/학습캡션을 LLM에 # 먼저 주고, 트리거를 문장 안 해당 부위에 붙여서 재작성한다 - 예전처럼 이름 옆에 # 콤마로 나열하면 bounce/swing 같은 범용 동사가 전신 모션으로 새기 때문. # 기존 노드는 건드리지 않고 뒤에 끼워 넣는 방식이라 어떤 프롬프트 소스에도 붙는다.) try: from .dolphin_lora_prompt import DolphinLoraPromptWeaver register_node("DolphinLoraPromptWeaver", DolphinLoraPromptWeaver, "🧬 Dolphin LoRA Prompt Weaver (프롬프트→로라에 맞게 재작성)") except Exception: print(f"\n❌ [Dolphin] LoRA Prompt Weaver 로드 실패:\n{traceback.format_exc()}") # 20. Minimax Director (MiniMax/Hailuo용 프롬프트 디렉터. Wan용 Prompt Director와 달리 # 클립 하나가 6/10초라서, 그 안을 초 단위 비트로 쪼개고 각 구간에 동작 + MiniMax # 공식 카메라 무브 태그를 박아준다.) try: from .dolphin_minimax_director import DolphinMinimaxDirector register_node("DolphinMinimaxDirector", DolphinMinimaxDirector, "🎬🅜 Dolphin Minimax Director (초 단위 타임라인 → Hailuo 프롬프트)") except Exception: print(f"\n❌ [Dolphin] Minimax Director 로드 실패:\n{traceback.format_exc()}") # 21. Wan Refine H3 (MiniMax H3 출력 → Wan 2.2 LOW noise 저-denoise 리파인 패스 올인원). # H3(24fps / 17k+5 프레임 그리드 / 768 short edge)와 Wan(16fps / 4n+1 / Wan2.1 VAE 16ch) # 사이의 배선 함정을 한 노드에서 처리: 4n+1 정렬, VAE 오배선 차단, 소스 라텐트 인코딩, # concat 컨디셔닝 재구성, sigma_shift 직접 패치, 색 드리프트 복원, 오디오 길이 정렬. # 같이 등록되는 Frame Grid 노드는 두 그리드가 겹치는 length(5/73/141/209/277/345…)를 계산한다. try: from .wan_h3_refine import WanH3Refine_Dolphin, WanH3FrameGrid_Dolphin register_node("WanH3Refine_Dolphin", WanH3Refine_Dolphin, "🐬🅜 Wan Refine H3 (low-denoise pass)") register_node("WanH3FrameGrid_Dolphin", WanH3FrameGrid_Dolphin, "🐬🅜 H3↔Wan Frame Grid") except Exception: print(f"\n❌ [Dolphin] Wan Refine H3 로드 실패:\n{traceback.format_exc()}") __all__ = ['NODE_CLASS_MAPPINGS', 'NODE_DISPLAY_NAME_MAPPINGS', 'WEB_DIRECTORY']