diff --git a/docs/api/lemonade.md b/docs/api/lemonade.md index 0c1e336ed..5427b3804 100644 --- a/docs/api/lemonade.md +++ b/docs/api/lemonade.md @@ -772,6 +772,7 @@ This endpoint is not part of the OpenAI API, so it is a Lemonade-specific extens | `image` | Yes | Base64-encoded input image (optionally a `data:` URL). | | `resolution` | No | Cascade resolution: `512`, `1024`, or `1536`. Default: `512`. | | `bg_removal` | No | Background removal mode: `threshold` or `birefnet`. Use `birefnet` for photos with real backgrounds. | +| `uv` | No | UV atlas method: `xatlas` (default) or `box`. `xatlas` runs a full UV unwrap giving every face unique atlas space — best quality, but chart computation is superlinear in face count. `box` is a faster 6-plane projection with occlusion-aware bucket assignment and depth-tested rasterization; small texture artifacts remain possible in concave regions. | | `seed` | No | Random seed for reproducibility. | | `response_format` | No | Output encoding. Only formats the backend natively produces are accepted (currently `glb`); other values are rejected with `400 Bad Request`. Default: `glb`. | diff --git a/src/cpp/resources/backend_versions.json b/src/cpp/resources/backend_versions.json index 5f4dc0185..1986d7ab3 100644 --- a/src/cpp/resources/backend_versions.json +++ b/src/cpp/resources/backend_versions.json @@ -122,9 +122,9 @@ "cuda": "v0.1.1" }, "trellis": { - "vulkan": "v0.1.5", - "rocm-stable": "v0.1.5", - "cuda": "v0.1.5" + "vulkan": "v0.2.1", + "rocm-stable": "v0.2.1", + "cuda": "v0.2.1" }, "openmoss": { "vulkan": "v0.1.2", diff --git a/src/cpp/server/backends/trellis/trellis_server.cpp b/src/cpp/server/backends/trellis/trellis_server.cpp index a0d55069b..72279fd02 100644 --- a/src/cpp/server/backends/trellis/trellis_server.cpp +++ b/src/cpp/server/backends/trellis/trellis_server.cpp @@ -183,6 +183,9 @@ void TrellisServer::model_3d_generations(const json& request, httplib::DataSink& if (request.contains("bg_removal") && request["bg_removal"].is_string()) { fields.push_back({"bg_removal", request["bg_removal"].get(), "", ""}); } + if (request.contains("uv") && request["uv"].is_string()) { + fields.push_back({"uv", request["uv"].get(), "", ""}); + } auto fail = [&sink](const std::string& message) { const std::string payload = diff --git a/src/cpp/server/server.cpp b/src/cpp/server/server.cpp index f2c4f3aec..8a20e0f3c 100644 --- a/src/cpp/server/server.cpp +++ b/src/cpp/server/server.cpp @@ -3502,6 +3502,12 @@ void Server::handle_3d_generations(const httplib::Request& req, httplib::Respons if (request_json.contains("seed") && !request_json["seed"].is_number_integer()) { return reject("'seed' must be an integer"); } + if (request_json.contains("uv")) { + const auto& u = request_json["uv"]; + if (!u.is_string() || (u != "box" && u != "xatlas")) { + return reject("'uv' must be 'box' or 'xatlas'"); + } + } std::string requested_model = request_json["model"]; try {