|
34 | 34 | #include <momentum/character/skeleton_state.h> |
35 | 35 | #include <momentum/character/skin_weights.h> |
36 | 36 | #include <momentum/io/fbx/fbx_io.h> |
| 37 | +#include <momentum/io/file_save_options.h> |
37 | 38 | #include <momentum/io/gltf/gltf_io.h> |
38 | 39 | #include <momentum/io/legacy_json/legacy_json_io.h> |
39 | 40 | #include <momentum/io/marker/coordinate_system.h> |
@@ -179,6 +180,13 @@ PYBIND11_MODULE(geometry, m) { |
179 | 180 | "ellipsoid constraints, and half-plane constraints."); |
180 | 181 | auto gltfOptionsClass = |
181 | 182 | py::class_<mm::GltfOptions>(m, "GltfOptions", "Storage options for Gltf export."); |
| 183 | + auto fileSaveOptionsClass = py::class_<mm::FileSaveOptions>( |
| 184 | + m, |
| 185 | + "FileSaveOptions", |
| 186 | + "Unified options for saving files in both FBX and GLTF formats. " |
| 187 | + "This struct consolidates save options that were previously scattered across " |
| 188 | + "multiple function parameters. Format-specific options (e.g., FBX coordinate " |
| 189 | + "system, GLTF extensions) are included but only used by their respective formats."); |
182 | 190 |
|
183 | 191 | gltfOptionsClass.def(py::init<>()) |
184 | 192 | .def( |
@@ -541,6 +549,128 @@ The resulting tensors are as follows: |
541 | 549 | coordSystemStr); |
542 | 550 | }); |
543 | 551 |
|
| 552 | + // ===================================================== |
| 553 | + // momentum::FileSaveOptions |
| 554 | + // - Common options: mesh, locators, collisions, blendShapes, permissive |
| 555 | + // - FBX-specific: coordSystemInfo, fbxNamespace |
| 556 | + // - GLTF-specific: extensions, gltfFileFormat |
| 557 | + // ===================================================== |
| 558 | + |
| 559 | + fileSaveOptionsClass.def(py::init<>()) |
| 560 | + .def_readwrite( |
| 561 | + "mesh", &mm::FileSaveOptions::mesh, "Include mesh geometry in the output (default: true)") |
| 562 | + .def_readwrite( |
| 563 | + "locators", |
| 564 | + &mm::FileSaveOptions::locators, |
| 565 | + "Include locators in the output (default: true)") |
| 566 | + .def_readwrite( |
| 567 | + "collisions", |
| 568 | + &mm::FileSaveOptions::collisions, |
| 569 | + "Include collision geometry in the output (default: true)") |
| 570 | + .def_readwrite( |
| 571 | + "blend_shapes", |
| 572 | + &mm::FileSaveOptions::blendShapes, |
| 573 | + "Include blend shapes in the output (default: true)") |
| 574 | + .def_readwrite( |
| 575 | + "permissive", |
| 576 | + &mm::FileSaveOptions::permissive, |
| 577 | + "Permissive mode: allow saving mesh-only characters without skin weights (default: false)") |
| 578 | + .def_readwrite( |
| 579 | + "coord_system_info", |
| 580 | + &mm::FileSaveOptions::coordSystemInfo, |
| 581 | + "FBX coordinate system configuration (default: Maya Y-up)") |
| 582 | + .def_readwrite( |
| 583 | + "fbx_namespace", |
| 584 | + &mm::FileSaveOptions::fbxNamespace, |
| 585 | + "Optional namespace prefix for FBX node names (e.g., 'ns' becomes 'ns:'), only used for FBX output (default: empty = no namespace)") |
| 586 | + .def_readwrite( |
| 587 | + "extensions", |
| 588 | + &mm::FileSaveOptions::extensions, |
| 589 | + "Enable GLTF extensions (default: true), only used for GLTF output") |
| 590 | + .def_readwrite( |
| 591 | + "gltf_file_format", |
| 592 | + &mm::FileSaveOptions::gltfFileFormat, |
| 593 | + "GLTF file format selection (default: Extension), only used for GLTF output") |
| 594 | + .def("__repr__", [](const mm::FileSaveOptions& opts) { |
| 595 | + std::string gltfFormatStr; |
| 596 | + switch (opts.gltfFileFormat) { |
| 597 | + case mm::GltfFileFormat::Extension: |
| 598 | + gltfFormatStr = "Extension"; |
| 599 | + break; |
| 600 | + case mm::GltfFileFormat::GltfBinary: |
| 601 | + gltfFormatStr = "GltfBinary"; |
| 602 | + break; |
| 603 | + case mm::GltfFileFormat::GltfAscii: |
| 604 | + gltfFormatStr = "GltfAscii"; |
| 605 | + break; |
| 606 | + default: |
| 607 | + gltfFormatStr = "Unknown"; |
| 608 | + break; |
| 609 | + } |
| 610 | + |
| 611 | + // Format coord_system_info |
| 612 | + std::string upVectorStr; |
| 613 | + switch (opts.coordSystemInfo.upVector) { |
| 614 | + case mm::FBXUpVector::XAxis: |
| 615 | + upVectorStr = "XAxis"; |
| 616 | + break; |
| 617 | + case mm::FBXUpVector::YAxis: |
| 618 | + upVectorStr = "YAxis"; |
| 619 | + break; |
| 620 | + case mm::FBXUpVector::ZAxis: |
| 621 | + upVectorStr = "ZAxis"; |
| 622 | + break; |
| 623 | + default: |
| 624 | + upVectorStr = "Unknown"; |
| 625 | + break; |
| 626 | + } |
| 627 | + |
| 628 | + std::string frontVectorStr; |
| 629 | + switch (opts.coordSystemInfo.frontVector) { |
| 630 | + case mm::FBXFrontVector::ParityEven: |
| 631 | + frontVectorStr = "ParityEven"; |
| 632 | + break; |
| 633 | + case mm::FBXFrontVector::ParityOdd: |
| 634 | + frontVectorStr = "ParityOdd"; |
| 635 | + break; |
| 636 | + default: |
| 637 | + frontVectorStr = "Unknown"; |
| 638 | + break; |
| 639 | + } |
| 640 | + |
| 641 | + std::string coordSystemStr; |
| 642 | + switch (opts.coordSystemInfo.coordSystem) { |
| 643 | + case mm::FBXCoordSystem::RightHanded: |
| 644 | + coordSystemStr = "RightHanded"; |
| 645 | + break; |
| 646 | + case mm::FBXCoordSystem::LeftHanded: |
| 647 | + coordSystemStr = "LeftHanded"; |
| 648 | + break; |
| 649 | + default: |
| 650 | + coordSystemStr = "Unknown"; |
| 651 | + break; |
| 652 | + } |
| 653 | + |
| 654 | + std::string coordSystemInfoStr = fmt::format( |
| 655 | + "FBXCoordSystemInfo(upVector={}, frontVector={}, coordSystem={})", |
| 656 | + upVectorStr, |
| 657 | + frontVectorStr, |
| 658 | + coordSystemStr); |
| 659 | + |
| 660 | + return fmt::format( |
| 661 | + "FileSaveOptions(mesh={}, locators={}, collisions={}, blendShapes={}, permissive={}, " |
| 662 | + "coord_system_info={}, fbx_namespace='{}', extensions={}, gltfFileFormat={})", |
| 663 | + opts.mesh, |
| 664 | + opts.locators, |
| 665 | + opts.collisions, |
| 666 | + opts.blendShapes, |
| 667 | + opts.permissive, |
| 668 | + coordSystemInfoStr, |
| 669 | + opts.fbxNamespace, |
| 670 | + opts.extensions, |
| 671 | + gltfFormatStr); |
| 672 | + }); |
| 673 | + |
544 | 674 | // loadMotion(gltfFilename) |
545 | 675 | m.def( |
546 | 676 | "load_motion", |
|
0 commit comments