Files

107 lines
3.2 KiB
Python

import sys
from os import path
sys.path.insert(0, path.dirname(__file__))
from folder_paths import get_filename_list, get_full_path, get_save_image_path, get_output_directory
from comfy.model_management import get_torch_device
from tsr.system import TSR
from PIL import Image
import numpy as np
import torch
class TripoSRSampler:
def __init__(self):
self.initialized_model = None
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"model": (get_filename_list("checkpoints"),),
"reference_image": ("IMAGE",),
"chunk_size": ("INT", {"default": 8192, "min": 1, "max": 10000})
}
}
RETURN_TYPES = ("MESH",)
FUNCTION = "sample"
CATEGORY = "Flowty TripoSR"
def sample(self, model, reference_image, chunk_size):
outputs = []
device = get_torch_device()
if not torch.cuda.is_available():
device = "cpu"
if not self.initialized_model:
print("Loading TripoSR model")
self.initialized_model = TSR.from_pretrained_custom(
weight_path=get_full_path("checkpoints", model),
config_path=path.join(path.dirname(__file__), "config.yaml")
)
self.initialized_model.renderer.set_chunk_size(chunk_size)
self.initialized_model.to(device)
with torch.no_grad():
for image in reference_image:
i = 255. * image.cpu().numpy()
i = Image.fromarray(np.clip(i, 0, 255).astype(np.uint8))
if i.mode == 'RGBA':
i = i.convert('RGB')
scene_codes = self.initialized_model([i], device)
meshes = self.initialized_model.extract_mesh(scene_codes)
outputs.append(meshes[0])
return (outputs,)
class TripoSRViewer:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"mesh": ("MESH",)
}
}
RETURN_TYPES = ()
OUTPUT_NODE = True
FUNCTION = "display"
CATEGORY = "Flowty TripoSR"
def display(self, mesh):
saved = list()
full_output_folder, filename, counter, subfolder, filename_prefix = get_save_image_path("meshsave",
get_output_directory())
for (batch_number, single_mesh) in enumerate(mesh):
filename_with_batch_num = filename.replace("%batch_num%", str(batch_number))
file = f"{filename_with_batch_num}_{counter:05}_.obj"
single_mesh.apply_transform(np.array([[1, 0, 0, 0], [0, 0, 1, 0], [0, -1, 0, 0], [0, 0, 0, 1]]))
single_mesh.export(path.join(full_output_folder, file))
saved.append({
"filename": file,
"type": "output",
"subfolder": subfolder
})
return {"ui": {"mesh": saved}}
NODE_CLASS_MAPPINGS = {
"TripoSRSampler": TripoSRSampler,
"TripoSRViewer": TripoSRViewer
}
NODE_DISPLAY_NAME_MAPPINGS = {
"TripoSRSampler": "TripoSR Sampler",
"TripoSRViewer": "TripoSR Viewer"
}
WEB_DIRECTORY = "./web"
__all__ = ['NODE_CLASS_MAPPINGS', 'NODE_DISPLAY_NAME_MAPPINGS', 'WEB_DIRECTORY']