Skip to content

Commit 07f2462

Browse files
authored
feat(api-nodes): add Meshy 3D nodes (Comfy-Org#11843)
* feat(api-nodes): add Meshy 3D nodes * rebased, added JSONata price badges
1 parent d150440 commit 07f2462

File tree

4 files changed

+969
-5
lines changed

4 files changed

+969
-5
lines changed

comfy_api_nodes/apis/meshy.py

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
from typing import TypedDict
2+
3+
from pydantic import BaseModel, Field
4+
5+
from comfy_api.latest import Input
6+
7+
8+
class InputShouldRemesh(TypedDict):
9+
should_remesh: str
10+
topology: str
11+
target_polycount: int
12+
13+
14+
class InputShouldTexture(TypedDict):
15+
should_texture: str
16+
enable_pbr: bool
17+
texture_prompt: str
18+
texture_image: Input.Image | None
19+
20+
21+
class MeshyTaskResponse(BaseModel):
22+
result: str = Field(...)
23+
24+
25+
class MeshyTextToModelRequest(BaseModel):
26+
mode: str = Field("preview")
27+
prompt: str = Field(..., max_length=600)
28+
art_style: str = Field(..., description="'realistic' or 'sculpture'")
29+
ai_model: str = Field(...)
30+
topology: str | None = Field(..., description="'quad' or 'triangle'")
31+
target_polycount: int | None = Field(..., ge=100, le=300000)
32+
should_remesh: bool = Field(
33+
True,
34+
description="False returns the original mesh, ignoring topology and polycount.",
35+
)
36+
symmetry_mode: str = Field(..., description="'auto', 'off' or 'on'")
37+
pose_mode: str = Field(...)
38+
seed: int = Field(...)
39+
moderation: bool = Field(False)
40+
41+
42+
class MeshyRefineTask(BaseModel):
43+
mode: str = Field("refine")
44+
preview_task_id: str = Field(...)
45+
enable_pbr: bool | None = Field(...)
46+
texture_prompt: str | None = Field(...)
47+
texture_image_url: str | None = Field(...)
48+
ai_model: str = Field(...)
49+
moderation: bool = Field(False)
50+
51+
52+
class MeshyImageToModelRequest(BaseModel):
53+
image_url: str = Field(...)
54+
ai_model: str = Field(...)
55+
topology: str | None = Field(..., description="'quad' or 'triangle'")
56+
target_polycount: int | None = Field(..., ge=100, le=300000)
57+
symmetry_mode: str = Field(..., description="'auto', 'off' or 'on'")
58+
should_remesh: bool = Field(
59+
True,
60+
description="False returns the original mesh, ignoring topology and polycount.",
61+
)
62+
should_texture: bool = Field(...)
63+
enable_pbr: bool | None = Field(...)
64+
pose_mode: str = Field(...)
65+
texture_prompt: str | None = Field(None, max_length=600)
66+
texture_image_url: str | None = Field(None)
67+
seed: int = Field(...)
68+
moderation: bool = Field(False)
69+
70+
71+
class MeshyMultiImageToModelRequest(BaseModel):
72+
image_urls: list[str] = Field(...)
73+
ai_model: str = Field(...)
74+
topology: str | None = Field(..., description="'quad' or 'triangle'")
75+
target_polycount: int | None = Field(..., ge=100, le=300000)
76+
symmetry_mode: str = Field(..., description="'auto', 'off' or 'on'")
77+
should_remesh: bool = Field(
78+
True,
79+
description="False returns the original mesh, ignoring topology and polycount.",
80+
)
81+
should_texture: bool = Field(...)
82+
enable_pbr: bool | None = Field(...)
83+
pose_mode: str = Field(...)
84+
texture_prompt: str | None = Field(None, max_length=600)
85+
texture_image_url: str | None = Field(None)
86+
seed: int = Field(...)
87+
moderation: bool = Field(False)
88+
89+
90+
class MeshyRiggingRequest(BaseModel):
91+
input_task_id: str = Field(...)
92+
height_meters: float = Field(...)
93+
texture_image_url: str | None = Field(...)
94+
95+
96+
class MeshyAnimationRequest(BaseModel):
97+
rig_task_id: str = Field(...)
98+
action_id: int = Field(...)
99+
100+
101+
class MeshyTextureRequest(BaseModel):
102+
input_task_id: str = Field(...)
103+
ai_model: str = Field(...)
104+
enable_original_uv: bool = Field(...)
105+
enable_pbr: bool = Field(...)
106+
text_style_prompt: str | None = Field(...)
107+
image_style_url: str | None = Field(...)
108+
109+
110+
class MeshyModelsUrls(BaseModel):
111+
glb: str = Field("")
112+
113+
114+
class MeshyRiggedModelsUrls(BaseModel):
115+
rigged_character_glb_url: str = Field("")
116+
117+
118+
class MeshyAnimatedModelsUrls(BaseModel):
119+
animation_glb_url: str = Field("")
120+
121+
122+
class MeshyResultTextureUrls(BaseModel):
123+
base_color: str = Field(...)
124+
metallic: str | None = Field(None)
125+
normal: str | None = Field(None)
126+
roughness: str | None = Field(None)
127+
128+
129+
class MeshyTaskError(BaseModel):
130+
message: str | None = Field(None)
131+
132+
133+
class MeshyModelResult(BaseModel):
134+
id: str = Field(...)
135+
type: str = Field(...)
136+
model_urls: MeshyModelsUrls = Field(MeshyModelsUrls())
137+
thumbnail_url: str = Field(...)
138+
video_url: str | None = Field(None)
139+
status: str = Field(...)
140+
progress: int = Field(0)
141+
texture_urls: list[MeshyResultTextureUrls] | None = Field([])
142+
task_error: MeshyTaskError | None = Field(None)
143+
144+
145+
class MeshyRiggedResult(BaseModel):
146+
id: str = Field(...)
147+
type: str = Field(...)
148+
status: str = Field(...)
149+
progress: int = Field(0)
150+
result: MeshyRiggedModelsUrls = Field(MeshyRiggedModelsUrls())
151+
task_error: MeshyTaskError | None = Field(None)
152+
153+
154+
class MeshyAnimationResult(BaseModel):
155+
id: str = Field(...)
156+
type: str = Field(...)
157+
status: str = Field(...)
158+
progress: int = Field(0)
159+
result: MeshyAnimatedModelsUrls = Field(MeshyAnimatedModelsUrls())
160+
task_error: MeshyTaskError | None = Field(None)

0 commit comments

Comments
 (0)