- Look for TRELLIS in /content/TRELLIS_repo (outside custom_nodes) - Add comment explaining why TRELLIS must NOT be inside custom_nodes - ComfyUI tries to load all folders in custom_nodes as node packages - Prioritize Colab paths first for faster detection 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
100 lines
3.8 KiB
Python
100 lines
3.8 KiB
Python
"""
|
|
ComfyUI-TRELLIS2_Motion - Video to 3D Mesh Reconstruction with Effects
|
|
|
|
A comprehensive ComfyUI node package that uses Microsoft's TRELLIS2 to transform
|
|
video footage into 3D mesh reconstructions with advanced rendering effects.
|
|
|
|
Features:
|
|
- Single image to 3D mesh conversion
|
|
- Video batch processing
|
|
- Camera trajectory control (orbit, dolly, pan)
|
|
- Multiple rendering modes (PBR, wireframe, cel shading)
|
|
- Onion skinning for motion visualization
|
|
- Post-processing effects (bloom, DoF, motion blur)
|
|
"""
|
|
|
|
import logging
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
# Auto-detect and add TRELLIS to Python path if cloned nearby
|
|
def _setup_trellis_path():
|
|
"""Add TRELLIS repo to sys.path if found in common locations."""
|
|
this_dir = Path(__file__).parent
|
|
|
|
# Possible locations for TRELLIS repo
|
|
# IMPORTANT: TRELLIS must NOT be inside custom_nodes/ or ComfyUI will try to load it as a node
|
|
possible_paths = [
|
|
Path("/content/TRELLIS_repo"), # Colab - OUTSIDE custom_nodes!
|
|
Path("/content/TRELLIS"), # Colab alternative
|
|
this_dir.parent / "TRELLIS", # ../TRELLIS (sibling to custom_nodes)
|
|
this_dir.parent / "TRELLIS_repo", # ../TRELLIS_repo
|
|
this_dir.parent.parent / "TRELLIS", # ComfyUI root level
|
|
this_dir.parent.parent / "TRELLIS_repo",
|
|
Path.home() / "TRELLIS", # ~/TRELLIS
|
|
Path.home() / "TRELLIS_repo", # ~/TRELLIS_repo
|
|
]
|
|
|
|
for trellis_path in possible_paths:
|
|
if trellis_path.exists() and (trellis_path / "trellis").exists():
|
|
if str(trellis_path) not in sys.path:
|
|
sys.path.insert(0, str(trellis_path))
|
|
logger.info(f"Added TRELLIS to path: {trellis_path}")
|
|
return True
|
|
|
|
return False
|
|
|
|
_setup_trellis_path()
|
|
|
|
# Node imports
|
|
from .nodes.trellis_predict import Trellis2Predict
|
|
from .nodes.video_to_meshes import VideoToMeshes, MergeMeshSequences
|
|
from .nodes.camera_trajectory import CameraTrajectory
|
|
from .nodes.mesh_renderer import MeshRenderer
|
|
from .nodes.mesh_sequence_renderer import MeshSequenceRenderer
|
|
from .nodes.onion_skinning import OnionSkinning
|
|
from .nodes.rendering_effects import RenderingEffects
|
|
from .nodes.combined_node import Trellis2VideoAngleShift
|
|
|
|
# Collect all node mappings
|
|
NODE_CLASS_MAPPINGS = {}
|
|
NODE_DISPLAY_NAME_MAPPINGS = {}
|
|
|
|
# Core nodes
|
|
NODE_CLASS_MAPPINGS["Trellis2Predict"] = Trellis2Predict
|
|
NODE_DISPLAY_NAME_MAPPINGS["Trellis2Predict"] = "TRELLIS2 Predict (Image to 3D Mesh)"
|
|
|
|
NODE_CLASS_MAPPINGS["VideoToMeshes"] = VideoToMeshes
|
|
NODE_DISPLAY_NAME_MAPPINGS["VideoToMeshes"] = "Video to Meshes (Batch TRELLIS2)"
|
|
|
|
NODE_CLASS_MAPPINGS["MergeMeshSequences"] = MergeMeshSequences
|
|
NODE_DISPLAY_NAME_MAPPINGS["MergeMeshSequences"] = "Merge Mesh Sequences"
|
|
|
|
# Camera
|
|
NODE_CLASS_MAPPINGS["CameraTrajectory_T2"] = CameraTrajectory
|
|
NODE_DISPLAY_NAME_MAPPINGS["CameraTrajectory_T2"] = "Camera Trajectory (TRELLIS2)"
|
|
|
|
# Rendering
|
|
NODE_CLASS_MAPPINGS["MeshRenderer"] = MeshRenderer
|
|
NODE_DISPLAY_NAME_MAPPINGS["MeshRenderer"] = "Mesh Renderer (3D to Image)"
|
|
|
|
NODE_CLASS_MAPPINGS["MeshSequenceRenderer"] = MeshSequenceRenderer
|
|
NODE_DISPLAY_NAME_MAPPINGS["MeshSequenceRenderer"] = "Mesh Sequence Renderer"
|
|
|
|
# Effects
|
|
NODE_CLASS_MAPPINGS["OnionSkinning"] = OnionSkinning
|
|
NODE_DISPLAY_NAME_MAPPINGS["OnionSkinning"] = "Onion Skinning (Motion Ghosts)"
|
|
|
|
NODE_CLASS_MAPPINGS["RenderingEffects"] = RenderingEffects
|
|
NODE_DISPLAY_NAME_MAPPINGS["RenderingEffects"] = "Rendering Effects"
|
|
|
|
# Combined convenience node
|
|
NODE_CLASS_MAPPINGS["Trellis2VideoAngleShift"] = Trellis2VideoAngleShift
|
|
NODE_DISPLAY_NAME_MAPPINGS["Trellis2VideoAngleShift"] = "TRELLIS2 Video Angle Shift"
|
|
|
|
__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS"]
|
|
|
|
logger.info(f"ComfyUI-TRELLIS2_Motion loaded {len(NODE_CLASS_MAPPINGS)} nodes")
|