mirror of
https://github.com/Comfy-Org/ComfyUI.git
synced 2026-09-21 13:38:08 -05:00
[Partner Nodes] feat(Meshy): add Meshy 7.1 support (#16412)
This commit is contained in:
@@ -36,7 +36,8 @@ class MeshyTextToModelRequest(BaseModel):
|
|||||||
)
|
)
|
||||||
symmetry_mode: str = Field(..., description="'auto', 'off' or 'on'")
|
symmetry_mode: str = Field(..., description="'auto', 'off' or 'on'")
|
||||||
pose_mode: str = Field(...)
|
pose_mode: str = Field(...)
|
||||||
ultra_mode: bool = Field(False)
|
ultra_mode: bool | None = Field(None)
|
||||||
|
geometry_resolution: str | None = Field(None)
|
||||||
seed: int = Field(...)
|
seed: int = Field(...)
|
||||||
moderation: bool = Field(False)
|
moderation: bool = Field(False)
|
||||||
|
|
||||||
@@ -66,7 +67,8 @@ class MeshyImageToModelRequest(BaseModel):
|
|||||||
enable_pbr: bool | None = Field(...)
|
enable_pbr: bool | None = Field(...)
|
||||||
texture_resolution: str | None = Field(None)
|
texture_resolution: str | None = Field(None)
|
||||||
pose_mode: str = Field(...)
|
pose_mode: str = Field(...)
|
||||||
ultra_mode: bool = Field(False)
|
ultra_mode: bool | None = Field(None)
|
||||||
|
geometry_resolution: str | None = Field(None)
|
||||||
texture_prompt: str | None = Field(None, max_length=600)
|
texture_prompt: str | None = Field(None, max_length=600)
|
||||||
texture_image_url: str | None = Field(None)
|
texture_image_url: str | None = Field(None)
|
||||||
seed: int = Field(...)
|
seed: int = Field(...)
|
||||||
@@ -87,6 +89,8 @@ class MeshyMultiImageToModelRequest(BaseModel):
|
|||||||
enable_pbr: bool | None = Field(...)
|
enable_pbr: bool | None = Field(...)
|
||||||
texture_resolution: str | None = Field(None)
|
texture_resolution: str | None = Field(None)
|
||||||
pose_mode: str = Field(...)
|
pose_mode: str = Field(...)
|
||||||
|
ultra_mode: bool | None = Field(None)
|
||||||
|
geometry_resolution: str | None = Field(None)
|
||||||
texture_prompt: str | None = Field(None, max_length=600)
|
texture_prompt: str | None = Field(None, max_length=600)
|
||||||
texture_image_url: str | None = Field(None)
|
texture_image_url: str | None = Field(None)
|
||||||
seed: int = Field(...)
|
seed: int = Field(...)
|
||||||
|
|||||||
@@ -26,6 +26,15 @@ from comfy_api_nodes.util import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def validate_ultra_mode(model: str, ultra_mode: bool, ultra_resolution: str = "2k") -> None:
|
||||||
|
if not ultra_mode:
|
||||||
|
return
|
||||||
|
if model not in ("meshy-7.1", "meshy-7", "latest"):
|
||||||
|
raise ValueError("ultra_mode requires the meshy-7.1, meshy-7 or latest model")
|
||||||
|
if ultra_resolution == "4k" and model not in ("meshy-7.1", "latest"):
|
||||||
|
raise ValueError("4k ultra_resolution requires the meshy-7.1 or latest model")
|
||||||
|
|
||||||
|
|
||||||
class MeshyTextToModelNode(IO.ComfyNode):
|
class MeshyTextToModelNode(IO.ComfyNode):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@@ -35,7 +44,7 @@ class MeshyTextToModelNode(IO.ComfyNode):
|
|||||||
display_name="Meshy: Text to Model",
|
display_name="Meshy: Text to Model",
|
||||||
category="partner/3d/Meshy",
|
category="partner/3d/Meshy",
|
||||||
inputs=[
|
inputs=[
|
||||||
IO.Combo.Input("model", options=["meshy-7", "meshy-6", "latest"]),
|
IO.Combo.Input("model", options=["meshy-7.1", "meshy-7", "meshy-6", "latest"]),
|
||||||
IO.String.Input("prompt", multiline=True, default=""),
|
IO.String.Input("prompt", multiline=True, default=""),
|
||||||
IO.Combo.Input("style", options=["realistic"]),
|
IO.Combo.Input("style", options=["realistic"]),
|
||||||
IO.DynamicCombo.Input(
|
IO.DynamicCombo.Input(
|
||||||
@@ -80,6 +89,13 @@ class MeshyTextToModelNode(IO.ComfyNode):
|
|||||||
default=False,
|
default=False,
|
||||||
tooltip="Run an extra refinement pass for higher-fidelity geometry with finer surface detail.",
|
tooltip="Run an extra refinement pass for higher-fidelity geometry with finer surface detail.",
|
||||||
),
|
),
|
||||||
|
IO.Combo.Input(
|
||||||
|
"ultra_resolution",
|
||||||
|
options=["2k", "4k"],
|
||||||
|
tooltip="Resolution of the ultra pass: 2k runs it at 2048³, 4k at 4096³ for the finest "
|
||||||
|
"surface detail. 4k requires meshy-7.1 or latest. Used only when ultra_mode is enabled.",
|
||||||
|
optional=True,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
outputs=[
|
outputs=[
|
||||||
IO.String.Output(display_name="model_file"), # for backward compatibility only
|
IO.String.Output(display_name="model_file"), # for backward compatibility only
|
||||||
@@ -98,8 +114,9 @@ class MeshyTextToModelNode(IO.ComfyNode):
|
|||||||
depends_on=IO.PriceBadgeDepends(widgets=["model", "ultra_mode"]),
|
depends_on=IO.PriceBadgeDepends(widgets=["model", "ultra_mode"]),
|
||||||
expr="""
|
expr="""
|
||||||
(
|
(
|
||||||
$credits := 20 + ((widgets.ultra_mode and widgets.model in ["meshy-7", "latest"]) ? 5 : 0);
|
$credits := 20
|
||||||
{"type":"usd","usd": $round($credits * 0.0572, 4)}
|
+ ((widgets.ultra_mode and widgets.model in ["meshy-7.1", "meshy-7", "latest"]) ? 5 : 0);
|
||||||
|
{"type":"usd","usd": $credits * 0.0572}
|
||||||
)
|
)
|
||||||
""",
|
""",
|
||||||
),
|
),
|
||||||
@@ -116,10 +133,10 @@ class MeshyTextToModelNode(IO.ComfyNode):
|
|||||||
pose_mode: str,
|
pose_mode: str,
|
||||||
seed: int,
|
seed: int,
|
||||||
ultra_mode: bool,
|
ultra_mode: bool,
|
||||||
|
ultra_resolution: str = "2k",
|
||||||
) -> IO.NodeOutput:
|
) -> IO.NodeOutput:
|
||||||
validate_string(prompt, field_name="prompt", min_length=1, max_length=600)
|
validate_string(prompt, field_name="prompt", min_length=1, max_length=600)
|
||||||
if ultra_mode and model not in ("meshy-7", "latest"):
|
validate_ultra_mode(model, ultra_mode, ultra_resolution)
|
||||||
raise ValueError("ultra_mode requires the meshy-7 or latest model")
|
|
||||||
response = await sync_op(
|
response = await sync_op(
|
||||||
cls,
|
cls,
|
||||||
ApiEndpoint(path="/proxy/meshy/openapi/v2/text-to-3d", method="POST"),
|
ApiEndpoint(path="/proxy/meshy/openapi/v2/text-to-3d", method="POST"),
|
||||||
@@ -133,7 +150,8 @@ class MeshyTextToModelNode(IO.ComfyNode):
|
|||||||
should_remesh=should_remesh["should_remesh"] == "true",
|
should_remesh=should_remesh["should_remesh"] == "true",
|
||||||
symmetry_mode=symmetry_mode,
|
symmetry_mode=symmetry_mode,
|
||||||
pose_mode=pose_mode.lower(),
|
pose_mode=pose_mode.lower(),
|
||||||
ultra_mode=ultra_mode,
|
ultra_mode=True if ultra_mode and model == "meshy-7" else None,
|
||||||
|
geometry_resolution=ultra_resolution if ultra_mode and model != "meshy-7" else None,
|
||||||
seed=seed,
|
seed=seed,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@@ -163,7 +181,7 @@ class MeshyRefineNode(IO.ComfyNode):
|
|||||||
category="partner/3d/Meshy",
|
category="partner/3d/Meshy",
|
||||||
description="Refine a previously created draft model.",
|
description="Refine a previously created draft model.",
|
||||||
inputs=[
|
inputs=[
|
||||||
IO.Combo.Input("model", options=["meshy-7", "meshy-6", "latest"]),
|
IO.Combo.Input("model", options=["meshy-7.1", "meshy-7", "meshy-6", "latest"]),
|
||||||
IO.Custom("MESHY_TASK_ID").Input("meshy_task_id"),
|
IO.Custom("MESHY_TASK_ID").Input("meshy_task_id"),
|
||||||
IO.Boolean.Input(
|
IO.Boolean.Input(
|
||||||
"enable_pbr",
|
"enable_pbr",
|
||||||
@@ -207,7 +225,7 @@ class MeshyRefineNode(IO.ComfyNode):
|
|||||||
expr="""
|
expr="""
|
||||||
(
|
(
|
||||||
$credits := widgets.texture_resolution = "8k" ? 15 : 10;
|
$credits := widgets.texture_resolution = "8k" ? 15 : 10;
|
||||||
{"type":"usd","usd": $round($credits * 0.0572, 4)}
|
{"type":"usd","usd": $credits * 0.0572}
|
||||||
)
|
)
|
||||||
""",
|
""",
|
||||||
),
|
),
|
||||||
@@ -268,7 +286,7 @@ class MeshyImageToModelNode(IO.ComfyNode):
|
|||||||
display_name="Meshy: Image to Model",
|
display_name="Meshy: Image to Model",
|
||||||
category="partner/3d/Meshy",
|
category="partner/3d/Meshy",
|
||||||
inputs=[
|
inputs=[
|
||||||
IO.Combo.Input("model", options=["meshy-7", "meshy-6", "latest"]),
|
IO.Combo.Input("model", options=["meshy-7.1", "meshy-7", "meshy-6", "latest"]),
|
||||||
IO.Image.Input("image"),
|
IO.Image.Input("image"),
|
||||||
IO.DynamicCombo.Input(
|
IO.DynamicCombo.Input(
|
||||||
"should_remesh",
|
"should_remesh",
|
||||||
@@ -350,6 +368,13 @@ class MeshyImageToModelNode(IO.ComfyNode):
|
|||||||
default=False,
|
default=False,
|
||||||
tooltip="Run an extra refinement pass for higher-fidelity geometry with finer surface detail.",
|
tooltip="Run an extra refinement pass for higher-fidelity geometry with finer surface detail.",
|
||||||
),
|
),
|
||||||
|
IO.Combo.Input(
|
||||||
|
"ultra_resolution",
|
||||||
|
options=["2k", "4k"],
|
||||||
|
tooltip="Resolution of the ultra pass: 2k runs it at 2048³, 4k at 4096³ for the finest "
|
||||||
|
"surface detail. 4k requires meshy-7.1 or latest. Used only when ultra_mode is enabled.",
|
||||||
|
optional=True,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
outputs=[
|
outputs=[
|
||||||
IO.String.Output(display_name="model_file"), # for backward compatibility only
|
IO.String.Output(display_name="model_file"), # for backward compatibility only
|
||||||
@@ -374,8 +399,8 @@ class MeshyImageToModelNode(IO.ComfyNode):
|
|||||||
$resolution := $textured ? $lookup(widgets, "should_texture.texture_resolution") : "2k";
|
$resolution := $textured ? $lookup(widgets, "should_texture.texture_resolution") : "2k";
|
||||||
$credits := ($textured ? 30 : 20)
|
$credits := ($textured ? 30 : 20)
|
||||||
+ ($resolution = "8k" ? 5 : 0)
|
+ ($resolution = "8k" ? 5 : 0)
|
||||||
+ ((widgets.ultra_mode and widgets.model in ["meshy-7", "latest"]) ? 5 : 0);
|
+ ((widgets.ultra_mode and widgets.model in ["meshy-7.1", "meshy-7", "latest"]) ? 5 : 0);
|
||||||
{"type":"usd","usd": $round($credits * 0.0572, 4)}
|
{"type":"usd","usd": $credits * 0.0572}
|
||||||
)
|
)
|
||||||
""",
|
""",
|
||||||
),
|
),
|
||||||
@@ -392,9 +417,9 @@ class MeshyImageToModelNode(IO.ComfyNode):
|
|||||||
pose_mode: str,
|
pose_mode: str,
|
||||||
seed: int,
|
seed: int,
|
||||||
ultra_mode: bool,
|
ultra_mode: bool,
|
||||||
|
ultra_resolution: str = "2k",
|
||||||
) -> IO.NodeOutput:
|
) -> IO.NodeOutput:
|
||||||
if ultra_mode and model not in ("meshy-7", "latest"):
|
validate_ultra_mode(model, ultra_mode, ultra_resolution)
|
||||||
raise ValueError("ultra_mode requires the meshy-7 or latest model")
|
|
||||||
texture = should_texture["should_texture"] == "true"
|
texture = should_texture["should_texture"] == "true"
|
||||||
texture_image_url = texture_prompt = None
|
texture_image_url = texture_prompt = None
|
||||||
if texture:
|
if texture:
|
||||||
@@ -424,7 +449,8 @@ class MeshyImageToModelNode(IO.ComfyNode):
|
|||||||
enable_pbr=should_texture.get("enable_pbr", None),
|
enable_pbr=should_texture.get("enable_pbr", None),
|
||||||
texture_resolution=should_texture.get("texture_resolution", None),
|
texture_resolution=should_texture.get("texture_resolution", None),
|
||||||
pose_mode=pose_mode.lower(),
|
pose_mode=pose_mode.lower(),
|
||||||
ultra_mode=ultra_mode,
|
ultra_mode=True if ultra_mode and model == "meshy-7" else None,
|
||||||
|
geometry_resolution=ultra_resolution if ultra_mode and model != "meshy-7" else None,
|
||||||
texture_prompt=texture_prompt,
|
texture_prompt=texture_prompt,
|
||||||
texture_image_url=texture_image_url,
|
texture_image_url=texture_image_url,
|
||||||
seed=seed,
|
seed=seed,
|
||||||
@@ -455,7 +481,7 @@ class MeshyMultiImageToModelNode(IO.ComfyNode):
|
|||||||
display_name="Meshy: Multi-Image to Model",
|
display_name="Meshy: Multi-Image to Model",
|
||||||
category="partner/3d/Meshy",
|
category="partner/3d/Meshy",
|
||||||
inputs=[
|
inputs=[
|
||||||
IO.Combo.Input("model", options=["meshy-7", "meshy-6", "latest"]),
|
IO.Combo.Input("model", options=["meshy-7.1", "meshy-7", "meshy-6", "latest"]),
|
||||||
IO.Autogrow.Input(
|
IO.Autogrow.Input(
|
||||||
"images",
|
"images",
|
||||||
template=IO.Autogrow.TemplatePrefix(IO.Image.Input("image"), prefix="image", min=2, max=4),
|
template=IO.Autogrow.TemplatePrefix(IO.Image.Input("image"), prefix="image", min=2, max=4),
|
||||||
@@ -535,6 +561,13 @@ class MeshyMultiImageToModelNode(IO.ComfyNode):
|
|||||||
tooltip="Seed controls whether the node should re-run; "
|
tooltip="Seed controls whether the node should re-run; "
|
||||||
"results are non-deterministic regardless of seed.",
|
"results are non-deterministic regardless of seed.",
|
||||||
),
|
),
|
||||||
|
IO.Boolean.Input(
|
||||||
|
"ultra_mode",
|
||||||
|
default=False,
|
||||||
|
tooltip="Run an extra refinement pass at 2048³ for higher-fidelity geometry "
|
||||||
|
"with finer surface detail.",
|
||||||
|
optional=True,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
outputs=[
|
outputs=[
|
||||||
IO.String.Output(display_name="model_file"), # for backward compatibility only
|
IO.String.Output(display_name="model_file"), # for backward compatibility only
|
||||||
@@ -551,14 +584,16 @@ class MeshyMultiImageToModelNode(IO.ComfyNode):
|
|||||||
is_output_node=True,
|
is_output_node=True,
|
||||||
price_badge=IO.PriceBadge(
|
price_badge=IO.PriceBadge(
|
||||||
depends_on=IO.PriceBadgeDepends(
|
depends_on=IO.PriceBadgeDepends(
|
||||||
widgets=["should_texture", "should_texture.texture_resolution"],
|
widgets=["model", "should_texture", "should_texture.texture_resolution", "ultra_mode"],
|
||||||
),
|
),
|
||||||
expr="""
|
expr="""
|
||||||
(
|
(
|
||||||
$textured := widgets.should_texture = "true";
|
$textured := widgets.should_texture = "true";
|
||||||
$resolution := $textured ? $lookup(widgets, "should_texture.texture_resolution") : "2k";
|
$resolution := $textured ? $lookup(widgets, "should_texture.texture_resolution") : "2k";
|
||||||
$credits := ($textured ? 30 : 20) + ($resolution = "8k" ? 5 : 0);
|
$credits := ($textured ? 30 : 20)
|
||||||
{"type":"usd","usd": $round($credits * 0.0572, 4)}
|
+ ($resolution = "8k" ? 5 : 0)
|
||||||
|
+ ((widgets.ultra_mode and widgets.model in ["meshy-7.1", "meshy-7", "latest"]) ? 5 : 0);
|
||||||
|
{"type":"usd","usd": $credits * 0.0572}
|
||||||
)
|
)
|
||||||
""",
|
""",
|
||||||
),
|
),
|
||||||
@@ -574,7 +609,9 @@ class MeshyMultiImageToModelNode(IO.ComfyNode):
|
|||||||
should_texture: InputShouldTexture,
|
should_texture: InputShouldTexture,
|
||||||
pose_mode: str,
|
pose_mode: str,
|
||||||
seed: int,
|
seed: int,
|
||||||
|
ultra_mode: bool = False,
|
||||||
) -> IO.NodeOutput:
|
) -> IO.NodeOutput:
|
||||||
|
validate_ultra_mode(model, ultra_mode)
|
||||||
texture = should_texture["should_texture"] == "true"
|
texture = should_texture["should_texture"] == "true"
|
||||||
texture_image_url = texture_prompt = None
|
texture_image_url = texture_prompt = None
|
||||||
if texture:
|
if texture:
|
||||||
@@ -606,6 +643,8 @@ class MeshyMultiImageToModelNode(IO.ComfyNode):
|
|||||||
enable_pbr=should_texture.get("enable_pbr", None),
|
enable_pbr=should_texture.get("enable_pbr", None),
|
||||||
texture_resolution=should_texture.get("texture_resolution", None),
|
texture_resolution=should_texture.get("texture_resolution", None),
|
||||||
pose_mode=pose_mode.lower(),
|
pose_mode=pose_mode.lower(),
|
||||||
|
ultra_mode=True if ultra_mode and model == "meshy-7" else None,
|
||||||
|
geometry_resolution="2k" if ultra_mode and model != "meshy-7" else None,
|
||||||
texture_prompt=texture_prompt,
|
texture_prompt=texture_prompt,
|
||||||
texture_image_url=texture_image_url,
|
texture_image_url=texture_image_url,
|
||||||
seed=seed,
|
seed=seed,
|
||||||
@@ -831,7 +870,7 @@ class MeshyTextureNode(IO.ComfyNode):
|
|||||||
expr="""
|
expr="""
|
||||||
(
|
(
|
||||||
$credits := widgets.texture_resolution = "8k" ? 15 : 10;
|
$credits := widgets.texture_resolution = "8k" ? 15 : 10;
|
||||||
{"type":"usd","usd": $round($credits * 0.0572, 4)}
|
{"type":"usd","usd": $credits * 0.0572}
|
||||||
)
|
)
|
||||||
""",
|
""",
|
||||||
),
|
),
|
||||||
@@ -936,7 +975,7 @@ class MeshyTextureMultiViewNode(IO.ComfyNode):
|
|||||||
expr="""
|
expr="""
|
||||||
(
|
(
|
||||||
$credits := widgets.texture_resolution = "8k" ? 15 : 10;
|
$credits := widgets.texture_resolution = "8k" ? 15 : 10;
|
||||||
{"type":"usd","usd": $round($credits * 0.0572, 4)}
|
{"type":"usd","usd": $credits * 0.0572}
|
||||||
)
|
)
|
||||||
""",
|
""",
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user