meshy results

This commit is contained in:
Brandon Thomas
2026-07-10 16:41:19 -04:00
parent ab93790332
commit 0312e3abea
3 changed files with 153 additions and 0 deletions
@@ -138,6 +138,8 @@ pub struct ModelMeshData {
pub struct ModelUrlsData {
/// Untextured base model (Tripo 3D).
pub base_model: Option<ModelGlbData>,
/// Blender project file (Meshy).
pub blend: Option<ModelGlbData>,
pub fbx: Option<ModelGlbData>,
pub glb: Option<ModelGlbData>,
/// OBJ material file (Hunyuan 3D 3.1).
@@ -145,6 +147,8 @@ pub struct ModelUrlsData {
pub obj: Option<ModelGlbData>,
/// PBR-textured model (Tripo 3D).
pub pbr_model: Option<ModelGlbData>,
/// STL model (Meshy).
pub stl: Option<ModelGlbData>,
/// PBR texture image for the OBJ (Hunyuan 3D 3.1).
pub texture: Option<ModelGlbData>,
pub usdz: Option<ModelGlbData>,
@@ -230,6 +230,67 @@ mod tests {
assert!(contents.preprocessed_image.is_none());
}
#[test]
fn model_urls_and_thumbnail_from_meshy_test_file() {
let webhook = load_test_webhook("success/meshy_model_urls_thumbnail_payload_1.json");
let result = hydrate_webhook_contents(&webhook);
let HydratedWebhookContents::Success(data) = result else {
panic!("Expected Success, got {:?}", result);
};
let contents = data.extracted_contents
.expect("extracted_contents should be Some");
let glb = contents.model_glb.expect("model_glb should be Some");
assert_eq!(glb.url.as_deref(), Some("https://v3b.fal.media/files/b/0aa1bbe1/0vrf9NUhVxKZO4GScA0EI_model.glb"));
assert_eq!(glb.content_type.as_deref(), Some("model/gltf-binary"));
assert_eq!(glb.file_name.as_deref(), Some("model.glb"));
assert_eq!(glb.file_size, Some(15943768));
let model_urls = contents.model_urls.expect("model_urls should be Some");
// The `glb` slot duplicates `model_glb` (same URL); the webhook handler
// dedupes by URL so the file uploads only once.
let urls_glb = model_urls.glb.expect("model_urls.glb should be Some");
assert_eq!(urls_glb.url.as_deref(), Some("https://v3b.fal.media/files/b/0aa1bbe1/0vrf9NUhVxKZO4GScA0EI_model.glb"));
// Alternate formats of the same model; parsed but not uploaded.
let urls_fbx = model_urls.fbx.expect("model_urls.fbx should be Some");
assert_eq!(urls_fbx.url.as_deref(), Some("https://v3b.fal.media/files/b/0aa1bbed/yKO-HOjBnWA-LZpRLHHSB_model.fbx"));
assert_eq!(urls_fbx.file_size, Some(13665964));
let urls_obj = model_urls.obj.expect("model_urls.obj should be Some");
assert_eq!(urls_obj.url.as_deref(), Some("https://v3b.fal.media/files/b/0aa1bbe2/NBmqIWBS8LuY_BPYWkOOf_model.obj"));
let urls_stl = model_urls.stl.expect("model_urls.stl should be Some");
assert_eq!(urls_stl.url.as_deref(), Some("https://v3b.fal.media/files/b/0aa1bbe2/3wtOE6iEeVHZFvwAGN6Rl_model.stl"));
assert_eq!(urls_stl.content_type.as_deref(), Some("application/octet-stream"));
assert_eq!(urls_stl.file_size, Some(1508384));
let urls_usdz = model_urls.usdz.expect("model_urls.usdz should be Some");
assert_eq!(urls_usdz.url.as_deref(), Some("https://v3b.fal.media/files/b/0aa1bbed/BsniPBo6Uev85V4hLFACR_model.usdz"));
assert_eq!(urls_usdz.content_type.as_deref(), Some("model/vnd.usdz+zip"));
assert!(model_urls.base_model.is_none());
assert!(model_urls.blend.is_none());
assert!(model_urls.mtl.is_none());
assert!(model_urls.pbr_model.is_none());
assert!(model_urls.texture.is_none());
// The thumbnail is attached to the GLB as its cover image downstream.
let thumbnail = contents.thumbnail.expect("thumbnail should be Some");
assert_eq!(thumbnail.url.as_deref(), Some("https://v3b.fal.media/files/b/0aa1bbe3/tn1qfOr12oGXecA4mRtlI_preview.png"));
assert_eq!(thumbnail.content_type.as_deref(), Some("image/png"));
assert_eq!(thumbnail.file_name.as_deref(), Some("preview.png"));
assert_eq!(thumbnail.file_size, Some(192910));
assert!(contents.model_glb_pbr.is_none());
assert!(contents.model_mesh.is_none());
assert!(contents.rendered_image.is_none());
assert!(contents.preprocessed_image.is_none());
}
#[test]
fn synthetic_model_urls_payload_with_distinct_glb() {
let obj: serde_json::Map<String, serde_json::Value> = serde_json::from_str(r#"{
@@ -0,0 +1,88 @@
{
"error": null,
"gateway_request_id": "019f4db7-e55c-78d1-9719-0303ca50a961",
"payload": {
"animation_fbx": null,
"animation_glb": null,
"basic_animations": null,
"model_glb": {
"content_type": "model/gltf-binary",
"file_name": "model.glb",
"file_size": 15943768,
"url": "https://v3b.fal.media/files/b/0aa1bbe1/0vrf9NUhVxKZO4GScA0EI_model.glb"
},
"model_urls": {
"blend": null,
"fbx": {
"content_type": "application/octet-stream",
"file_name": "model.fbx",
"file_size": 13665964,
"url": "https://v3b.fal.media/files/b/0aa1bbed/yKO-HOjBnWA-LZpRLHHSB_model.fbx"
},
"glb": {
"content_type": "model/gltf-binary",
"file_name": "model.glb",
"file_size": 15943768,
"url": "https://v3b.fal.media/files/b/0aa1bbe1/0vrf9NUhVxKZO4GScA0EI_model.glb"
},
"obj": {
"content_type": "text/plain",
"file_name": "model.obj",
"file_size": 3083671,
"url": "https://v3b.fal.media/files/b/0aa1bbe2/NBmqIWBS8LuY_BPYWkOOf_model.obj"
},
"stl": {
"content_type": "application/octet-stream",
"file_name": "model.stl",
"file_size": 1508384,
"url": "https://v3b.fal.media/files/b/0aa1bbe2/3wtOE6iEeVHZFvwAGN6Rl_model.stl"
},
"usdz": {
"content_type": "model/vnd.usdz+zip",
"file_name": "model.usdz",
"file_size": 16861118,
"url": "https://v3b.fal.media/files/b/0aa1bbed/BsniPBo6Uev85V4hLFACR_model.usdz"
}
},
"rig_task_id": null,
"rigged_character_fbx": null,
"rigged_character_glb": null,
"seed": 274321742,
"texture_urls": [
{
"base_color": {
"content_type": "image/png",
"file_name": "texture_0.png",
"file_size": 7539838,
"url": "https://v3b.fal.media/files/b/0aa1bbe3/EXWiAuAYPobYiJPnW66mQ_texture_0.png"
},
"metallic": {
"content_type": "image/png",
"file_name": "texture_0_metallic.png",
"file_size": 858941,
"url": "https://v3b.fal.media/files/b/0aa1bbee/RTZIZRCDQTvN7jdl4EL_C_texture_0_metallic.png"
},
"normal": {
"content_type": "image/png",
"file_name": "texture_0_normal.png",
"file_size": 8236038,
"url": "https://v3b.fal.media/files/b/0aa1bbe3/yNk-S5Dhw2xc9fb3fIjwD_texture_0_normal.png"
},
"roughness": {
"content_type": "image/png",
"file_name": "texture_0_roughness.png",
"file_size": 1184908,
"url": "https://v3b.fal.media/files/b/0aa1bbe3/nnT25g7wgul2oDTRlI_jX_texture_0_roughness.png"
}
}
],
"thumbnail": {
"content_type": "image/png",
"file_name": "preview.png",
"file_size": 192910,
"url": "https://v3b.fal.media/files/b/0aa1bbe3/tn1qfOr12oGXecA4mRtlI_preview.png"
}
},
"request_id": "019f4db7-e55c-78d1-9719-0303ca50a961",
"status": "OK"
}