| 306 | } |
| 307 | |
| 308 | static void setupModelShow(CLI::App& model) |
| 309 | { |
| 310 | auto* cmd = model.add_subcommand("show", "Display P3D model wireframe in a window"); |
| 311 | static std::string inputPath; |
| 312 | static std::string screenshotPath; |
| 313 | static int lodIndex = 0; |
| 314 | static std::string view = "front"; |
| 315 | |
| 316 | cmd->add_option("input", inputPath, "Input P3D file path")->required()->check(CLI::ExistingFile); |
| 317 | cmd->add_option("--screenshot", screenshotPath, "Save screenshot to file and exit"); |
| 318 | cmd->add_option("-l,--lod", lodIndex, "LOD level to render")->default_val(0); |
| 319 | cmd->add_option("--view", view, "View: front, back, top, bottom, right, left, 3d, quad")->default_val("front"); |
| 320 | |
| 321 | cmd->callback( |
| 322 | [&]() |
| 323 | { |
| 324 | int imgW = (view == "quad") ? 900 : 800; |
| 325 | int imgH = imgW; |
| 326 | |
| 327 | Poseidon::ModelPreviewOptions opts; |
| 328 | opts.width = imgW; |
| 329 | opts.height = imgH; |
| 330 | opts.lodIndex = lodIndex; |
| 331 | opts.view = view; |
| 332 | |
| 333 | if (!screenshotPath.empty()) |
| 334 | { |
| 335 | auto preview = Poseidon::PreviewModel(inputPath, opts); |
| 336 | if (!preview.valid()) |
| 337 | { |
| 338 | std::cerr << "Error: Failed to render model" << std::endl; |
| 339 | throw CLI::RuntimeError(1); |
| 340 | } |
| 341 | if (!preview.saveToFile(screenshotPath)) |
| 342 | throw CLI::RuntimeError(1); |
| 343 | std::cout << "Screenshot: " << screenshotPath << " (" << imgW << "x" << imgH << ")" << std::endl; |
| 344 | return; |
| 345 | } |
| 346 | |
| 347 | auto preview = Poseidon::PreviewModel(inputPath, opts); |
| 348 | if (!preview.valid()) |
| 349 | { |
| 350 | std::cerr << "Error: Failed to render model" << std::endl; |
| 351 | throw CLI::RuntimeError(1); |
| 352 | } |
| 353 | |
| 354 | char title[256]; |
| 355 | std::snprintf(title, sizeof(title), "PoseidonTools - %s (LOD %d, %s)", inputPath.c_str(), lodIndex, |
| 356 | view.c_str()); |
| 357 | std::string viewCopy = view; |
| 358 | std::string pathCopy = inputPath; |
| 359 | int lodCopy = lodIndex; |
| 360 | DisplayWindowRGB(title, imgW, imgH, preview.data.data(), |
| 361 | [pathCopy, lodCopy, viewCopy](int w, int h) -> std::vector<uint8_t> |
| 362 | { |
| 363 | Poseidon::ModelPreviewOptions resizeOpts; |
| 364 | resizeOpts.width = w; |
| 365 | resizeOpts.height = h; |
no test coverage detected