mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2026-02-08 12:32:32 +08:00
update Tripo nodes to use File3DGLB
This commit is contained in:
parent
9574fa144c
commit
be8676e500
@ -1,10 +1,6 @@
|
|||||||
import os
|
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
import torch
|
|
||||||
from typing_extensions import override
|
from typing_extensions import override
|
||||||
|
|
||||||
from comfy_api.latest import IO, ComfyExtension
|
from comfy_api.latest import IO, ComfyExtension, Input
|
||||||
from comfy_api_nodes.apis.tripo import (
|
from comfy_api_nodes.apis.tripo import (
|
||||||
TripoAnimateRetargetRequest,
|
TripoAnimateRetargetRequest,
|
||||||
TripoAnimateRigRequest,
|
TripoAnimateRigRequest,
|
||||||
@ -26,12 +22,11 @@ from comfy_api_nodes.apis.tripo import (
|
|||||||
)
|
)
|
||||||
from comfy_api_nodes.util import (
|
from comfy_api_nodes.util import (
|
||||||
ApiEndpoint,
|
ApiEndpoint,
|
||||||
download_url_as_bytesio,
|
download_url_to_file_3d,
|
||||||
poll_op,
|
poll_op,
|
||||||
sync_op,
|
sync_op,
|
||||||
upload_images_to_comfyapi,
|
upload_images_to_comfyapi,
|
||||||
)
|
)
|
||||||
from folder_paths import get_output_directory
|
|
||||||
|
|
||||||
|
|
||||||
def get_model_url_from_response(response: TripoTaskResponse) -> str:
|
def get_model_url_from_response(response: TripoTaskResponse) -> str:
|
||||||
@ -45,7 +40,7 @@ def get_model_url_from_response(response: TripoTaskResponse) -> str:
|
|||||||
async def poll_until_finished(
|
async def poll_until_finished(
|
||||||
node_cls: type[IO.ComfyNode],
|
node_cls: type[IO.ComfyNode],
|
||||||
response: TripoTaskResponse,
|
response: TripoTaskResponse,
|
||||||
average_duration: Optional[int] = None,
|
average_duration: int | None = None,
|
||||||
) -> IO.NodeOutput:
|
) -> IO.NodeOutput:
|
||||||
"""Polls the Tripo API endpoint until the task reaches a terminal state, then returns the response."""
|
"""Polls the Tripo API endpoint until the task reaches a terminal state, then returns the response."""
|
||||||
if response.code != 0:
|
if response.code != 0:
|
||||||
@ -69,12 +64,8 @@ async def poll_until_finished(
|
|||||||
)
|
)
|
||||||
if response_poll.data.status == TripoTaskStatus.SUCCESS:
|
if response_poll.data.status == TripoTaskStatus.SUCCESS:
|
||||||
url = get_model_url_from_response(response_poll)
|
url = get_model_url_from_response(response_poll)
|
||||||
bytesio = await download_url_as_bytesio(url)
|
file_glb = await download_url_to_file_3d(url, "glb", task_id=task_id)
|
||||||
# Save the downloaded model file
|
return IO.NodeOutput(file_glb, task_id, file_glb)
|
||||||
model_file = f"tripo_model_{task_id}.glb"
|
|
||||||
with open(os.path.join(get_output_directory(), model_file), "wb") as f:
|
|
||||||
f.write(bytesio.getvalue())
|
|
||||||
return IO.NodeOutput(model_file, task_id)
|
|
||||||
raise RuntimeError(f"Failed to generate mesh: {response_poll}")
|
raise RuntimeError(f"Failed to generate mesh: {response_poll}")
|
||||||
|
|
||||||
|
|
||||||
@ -107,8 +98,9 @@ class TripoTextToModelNode(IO.ComfyNode):
|
|||||||
IO.Combo.Input("geometry_quality", default="standard", options=["standard", "detailed"], optional=True),
|
IO.Combo.Input("geometry_quality", default="standard", options=["standard", "detailed"], optional=True),
|
||||||
],
|
],
|
||||||
outputs=[
|
outputs=[
|
||||||
IO.String.Output(display_name="model_file"),
|
IO.String.Output(display_name="model_file"), # for backward compatibility only
|
||||||
IO.Custom("MODEL_TASK_ID").Output(display_name="model task_id"),
|
IO.Custom("MODEL_TASK_ID").Output(display_name="model task_id"),
|
||||||
|
IO.File3DGLB.Output(display_name="GLB"),
|
||||||
],
|
],
|
||||||
hidden=[
|
hidden=[
|
||||||
IO.Hidden.auth_token_comfy_org,
|
IO.Hidden.auth_token_comfy_org,
|
||||||
@ -155,18 +147,18 @@ class TripoTextToModelNode(IO.ComfyNode):
|
|||||||
async def execute(
|
async def execute(
|
||||||
cls,
|
cls,
|
||||||
prompt: str,
|
prompt: str,
|
||||||
negative_prompt: Optional[str] = None,
|
negative_prompt: str | None = None,
|
||||||
model_version=None,
|
model_version=None,
|
||||||
style: Optional[str] = None,
|
style: str | None = None,
|
||||||
texture: Optional[bool] = None,
|
texture: bool | None = None,
|
||||||
pbr: Optional[bool] = None,
|
pbr: bool | None = None,
|
||||||
image_seed: Optional[int] = None,
|
image_seed: int | None = None,
|
||||||
model_seed: Optional[int] = None,
|
model_seed: int | None = None,
|
||||||
texture_seed: Optional[int] = None,
|
texture_seed: int | None = None,
|
||||||
texture_quality: Optional[str] = None,
|
texture_quality: str | None = None,
|
||||||
geometry_quality: Optional[str] = None,
|
geometry_quality: str | None = None,
|
||||||
face_limit: Optional[int] = None,
|
face_limit: int | None = None,
|
||||||
quad: Optional[bool] = None,
|
quad: bool | None = None,
|
||||||
) -> IO.NodeOutput:
|
) -> IO.NodeOutput:
|
||||||
style_enum = None if style == "None" else style
|
style_enum = None if style == "None" else style
|
||||||
if not prompt:
|
if not prompt:
|
||||||
@ -232,8 +224,9 @@ class TripoImageToModelNode(IO.ComfyNode):
|
|||||||
IO.Combo.Input("geometry_quality", default="standard", options=["standard", "detailed"], optional=True),
|
IO.Combo.Input("geometry_quality", default="standard", options=["standard", "detailed"], optional=True),
|
||||||
],
|
],
|
||||||
outputs=[
|
outputs=[
|
||||||
IO.String.Output(display_name="model_file"),
|
IO.String.Output(display_name="model_file"), # for backward compatibility only
|
||||||
IO.Custom("MODEL_TASK_ID").Output(display_name="model task_id"),
|
IO.Custom("MODEL_TASK_ID").Output(display_name="model task_id"),
|
||||||
|
IO.File3DGLB.Output(display_name="GLB"),
|
||||||
],
|
],
|
||||||
hidden=[
|
hidden=[
|
||||||
IO.Hidden.auth_token_comfy_org,
|
IO.Hidden.auth_token_comfy_org,
|
||||||
@ -279,19 +272,19 @@ class TripoImageToModelNode(IO.ComfyNode):
|
|||||||
@classmethod
|
@classmethod
|
||||||
async def execute(
|
async def execute(
|
||||||
cls,
|
cls,
|
||||||
image: torch.Tensor,
|
image: Input.Image,
|
||||||
model_version: Optional[str] = None,
|
model_version: str | None = None,
|
||||||
style: Optional[str] = None,
|
style: str | None = None,
|
||||||
texture: Optional[bool] = None,
|
texture: bool | None = None,
|
||||||
pbr: Optional[bool] = None,
|
pbr: bool | None = None,
|
||||||
model_seed: Optional[int] = None,
|
model_seed: int | None = None,
|
||||||
orientation=None,
|
orientation=None,
|
||||||
texture_seed: Optional[int] = None,
|
texture_seed: int | None = None,
|
||||||
texture_quality: Optional[str] = None,
|
texture_quality: str | None = None,
|
||||||
geometry_quality: Optional[str] = None,
|
geometry_quality: str | None = None,
|
||||||
texture_alignment: Optional[str] = None,
|
texture_alignment: str | None = None,
|
||||||
face_limit: Optional[int] = None,
|
face_limit: int | None = None,
|
||||||
quad: Optional[bool] = None,
|
quad: bool | None = None,
|
||||||
) -> IO.NodeOutput:
|
) -> IO.NodeOutput:
|
||||||
style_enum = None if style == "None" else style
|
style_enum = None if style == "None" else style
|
||||||
if image is None:
|
if image is None:
|
||||||
@ -368,8 +361,9 @@ class TripoMultiviewToModelNode(IO.ComfyNode):
|
|||||||
IO.Combo.Input("geometry_quality", default="standard", options=["standard", "detailed"], optional=True),
|
IO.Combo.Input("geometry_quality", default="standard", options=["standard", "detailed"], optional=True),
|
||||||
],
|
],
|
||||||
outputs=[
|
outputs=[
|
||||||
IO.String.Output(display_name="model_file"),
|
IO.String.Output(display_name="model_file"), # for backward compatibility only
|
||||||
IO.Custom("MODEL_TASK_ID").Output(display_name="model task_id"),
|
IO.Custom("MODEL_TASK_ID").Output(display_name="model task_id"),
|
||||||
|
IO.File3DGLB.Output(display_name="GLB"),
|
||||||
],
|
],
|
||||||
hidden=[
|
hidden=[
|
||||||
IO.Hidden.auth_token_comfy_org,
|
IO.Hidden.auth_token_comfy_org,
|
||||||
@ -411,21 +405,21 @@ class TripoMultiviewToModelNode(IO.ComfyNode):
|
|||||||
@classmethod
|
@classmethod
|
||||||
async def execute(
|
async def execute(
|
||||||
cls,
|
cls,
|
||||||
image: torch.Tensor,
|
image: Input.Image,
|
||||||
image_left: Optional[torch.Tensor] = None,
|
image_left: Input.Image | None = None,
|
||||||
image_back: Optional[torch.Tensor] = None,
|
image_back: Input.Image | None = None,
|
||||||
image_right: Optional[torch.Tensor] = None,
|
image_right: Input.Image | None = None,
|
||||||
model_version: Optional[str] = None,
|
model_version: str | None = None,
|
||||||
orientation: Optional[str] = None,
|
orientation: str | None = None,
|
||||||
texture: Optional[bool] = None,
|
texture: bool | None = None,
|
||||||
pbr: Optional[bool] = None,
|
pbr: bool | None = None,
|
||||||
model_seed: Optional[int] = None,
|
model_seed: int | None = None,
|
||||||
texture_seed: Optional[int] = None,
|
texture_seed: int | None = None,
|
||||||
texture_quality: Optional[str] = None,
|
texture_quality: str | None = None,
|
||||||
geometry_quality: Optional[str] = None,
|
geometry_quality: str | None = None,
|
||||||
texture_alignment: Optional[str] = None,
|
texture_alignment: str | None = None,
|
||||||
face_limit: Optional[int] = None,
|
face_limit: int | None = None,
|
||||||
quad: Optional[bool] = None,
|
quad: bool | None = None,
|
||||||
) -> IO.NodeOutput:
|
) -> IO.NodeOutput:
|
||||||
if image is None:
|
if image is None:
|
||||||
raise RuntimeError("front image for multiview is required")
|
raise RuntimeError("front image for multiview is required")
|
||||||
@ -487,8 +481,9 @@ class TripoTextureNode(IO.ComfyNode):
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
outputs=[
|
outputs=[
|
||||||
IO.String.Output(display_name="model_file"),
|
IO.String.Output(display_name="model_file"), # for backward compatibility only
|
||||||
IO.Custom("MODEL_TASK_ID").Output(display_name="model task_id"),
|
IO.Custom("MODEL_TASK_ID").Output(display_name="model task_id"),
|
||||||
|
IO.File3DGLB.Output(display_name="GLB"),
|
||||||
],
|
],
|
||||||
hidden=[
|
hidden=[
|
||||||
IO.Hidden.auth_token_comfy_org,
|
IO.Hidden.auth_token_comfy_org,
|
||||||
@ -512,11 +507,11 @@ class TripoTextureNode(IO.ComfyNode):
|
|||||||
async def execute(
|
async def execute(
|
||||||
cls,
|
cls,
|
||||||
model_task_id,
|
model_task_id,
|
||||||
texture: Optional[bool] = None,
|
texture: bool | None = None,
|
||||||
pbr: Optional[bool] = None,
|
pbr: bool | None = None,
|
||||||
texture_seed: Optional[int] = None,
|
texture_seed: int | None = None,
|
||||||
texture_quality: Optional[str] = None,
|
texture_quality: str | None = None,
|
||||||
texture_alignment: Optional[str] = None,
|
texture_alignment: str | None = None,
|
||||||
) -> IO.NodeOutput:
|
) -> IO.NodeOutput:
|
||||||
response = await sync_op(
|
response = await sync_op(
|
||||||
cls,
|
cls,
|
||||||
@ -547,8 +542,9 @@ class TripoRefineNode(IO.ComfyNode):
|
|||||||
IO.Custom("MODEL_TASK_ID").Input("model_task_id", tooltip="Must be a v1.4 Tripo model"),
|
IO.Custom("MODEL_TASK_ID").Input("model_task_id", tooltip="Must be a v1.4 Tripo model"),
|
||||||
],
|
],
|
||||||
outputs=[
|
outputs=[
|
||||||
IO.String.Output(display_name="model_file"),
|
IO.String.Output(display_name="model_file"), # for backward compatibility only
|
||||||
IO.Custom("MODEL_TASK_ID").Output(display_name="model task_id"),
|
IO.Custom("MODEL_TASK_ID").Output(display_name="model task_id"),
|
||||||
|
IO.File3DGLB.Output(display_name="GLB"),
|
||||||
],
|
],
|
||||||
hidden=[
|
hidden=[
|
||||||
IO.Hidden.auth_token_comfy_org,
|
IO.Hidden.auth_token_comfy_org,
|
||||||
@ -583,8 +579,9 @@ class TripoRigNode(IO.ComfyNode):
|
|||||||
category="api node/3d/Tripo",
|
category="api node/3d/Tripo",
|
||||||
inputs=[IO.Custom("MODEL_TASK_ID").Input("original_model_task_id")],
|
inputs=[IO.Custom("MODEL_TASK_ID").Input("original_model_task_id")],
|
||||||
outputs=[
|
outputs=[
|
||||||
IO.String.Output(display_name="model_file"),
|
IO.String.Output(display_name="model_file"), # for backward compatibility only
|
||||||
IO.Custom("RIG_TASK_ID").Output(display_name="rig task_id"),
|
IO.Custom("RIG_TASK_ID").Output(display_name="rig task_id"),
|
||||||
|
IO.File3DGLB.Output(display_name="GLB"),
|
||||||
],
|
],
|
||||||
hidden=[
|
hidden=[
|
||||||
IO.Hidden.auth_token_comfy_org,
|
IO.Hidden.auth_token_comfy_org,
|
||||||
@ -642,8 +639,9 @@ class TripoRetargetNode(IO.ComfyNode):
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
outputs=[
|
outputs=[
|
||||||
IO.String.Output(display_name="model_file"),
|
IO.String.Output(display_name="model_file"), # for backward compatibility only
|
||||||
IO.Custom("RETARGET_TASK_ID").Output(display_name="retarget task_id"),
|
IO.Custom("RETARGET_TASK_ID").Output(display_name="retarget task_id"),
|
||||||
|
IO.File3DGLB.Output(display_name="GLB"),
|
||||||
],
|
],
|
||||||
hidden=[
|
hidden=[
|
||||||
IO.Hidden.auth_token_comfy_org,
|
IO.Hidden.auth_token_comfy_org,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user