Skip to main content

No project description provided

Project description

xc3_model_py PyPI

Python bindings to xc3_model for high level and efficient data access to model files for Xenoblade 1 DE, Xenoblade 2, and Xenoblade 3.

Installation

The package can be installed for Python version 3.9, 3.10, 3.11, or 3.12 using pip on newer versions of Windows, Linux, or MacOS. The prebuilt wheels (.whl files) are included only for situations where pip might not be available such as for plugin development for applications. The wheels are zip archives and can be extracted to obtain the compiled .pyd or .so file. xc3_model_py requires the numpy package for transforms and vertex data.

Installing: pip install xc3_model_py
Updating: pip install xc3_model_py --upgrade

Introduction

Parsing and processing happens in optimized Rust code when calling xc3_model_py.load_map or xc3_model_py.load_model. All characters, models, and maps are converted to the same scene hierarchy representation. This avoids needing to add any special handling for maps vs characters. Pregenerated shader databases are available from xc3_lib. For more advanced usage, see xenoblade_blender.

import xc3_model_py

# Get a list of MapRoot.
database = xc3_model_py.shader_database.ShaderDatabase.from_file("xc3.bin")
roots = xc3_model_py.load_map("xenoblade3_dump/map/ma59a.wismhd", database)

for root in roots:
    for group in root.groups:
        for models in group.models:
            for material in models.materials:
                print(material.name)
                # The shader contains assignment information when specifying a database.

            for model in models.models:
                buffers = group.buffers[model.model_buffers_index]

                # prints (num_instances, 4, 4)
                print(len(model.instances.shape))
# This returns only a single ModelRoot.
database = xc3_model_py.shader_database.ShaderDatabase.from_file("xc3.bin")
root = xc3_model_py.load_model("xenoblade3_dump/chr/chr/01012013.wimdo", database)

for material in root.models.materials:
    print(material.name)

for model in root.models.models:
    # prints (1, 4, 4)
    print(len(model.instances.shape))

    # Access vertex and index data for this model.
    buffers = root.buffers
    for buffer in buffers.vertex_buffers:
        for attribute in buffer.attributes:
            print(attribute.attribute_type, attribute.data.shape)

    # Access vertex skinning data for each mesh.
    for mesh in model.meshes:
        vertex_buffer = buffers.vertex_buffers[mesh.vertex_buffer_index]

        if buffers.weights is not None:
            # Calculate the index offset based on the weight group for this mesh.
            pass_type = root.models.materials[mesh.material_index].pass_type
            lod_item_index = 0 if mesh.lod_item_index is None else mesh.lod_item_index
            start_index = buffers.weights.weights_start_index(
                mesh.flags2, lod_item_index, pass_type
            )

            weight_buffer = buffers.weights.weight_buffer(mesh.flags2)
            if weight_buffer is not None:
                # Get vertex skinning attributes.
                for attribute in vertex_buffer.attributes:
                    if (
                        attribute.attribute_type
                        == xc3_model_py.vertex.AttributeType.WeightIndex
                    ):
                        # Find the actual per vertex skinning information.
                        weight_indices = attribute.data[:, 0] + start_index
                        skin_weights = weight_buffer.weights[weight_indices]
                        # Note that these indices index into a different bone list than the skeleton.
                        bone_indices = weight_buffer.bone_indices[weight_indices, 0]
                        bone_name = weight_buffer.bone_names[bone_indices[0]]

Certain types like matrices and vertex atribute data are stored using numpy.ndarray. All transformation matrices are column-major to match the Rust code in xc3_model. This greatly reduces conversion overhead and allows for more optimized Python code. xc3_model_py requires the numpy package to be installed. Blender already provides the numpy package, enabling the use of functions like foreach_get and foreach_set for efficient property access.

# blender
blender_mesh.vertices.add(positions_array.shape[0])
blender_mesh.vertices.foreach_set('co', positions_array.reshape(-1))

Animations can be loaded from a file all at once. The track type is currently opaque, meaning that implementation details are not exposed. The values can be sampled at the desired frame using the appropriate methods.

import xc3_model_py

path = "xenoblade3_dump/chr/ch/ch01027000_event.mot"
animations = xc3_model_py.load_animations(path)

for animation in animations:
    print(
        animation.name, animation.space_mode, animation.play_mode, animation.blend_mode
    )
    print(f"frames: {animation.frame_count}, tracks: {len(animation.tracks)}")

    track = animation.tracks[0]

    # Each track references a bone in one of three ways.
    bone_index = track.bone_index()
    bone_hash = track.bone_hash()
    bone_name = track.bone_name()
    if bone_index is not None:
        pass
    elif bone_hash is not None:
        # Use xc3_model_py.murmur3(bone_name) for hashing the skeleton bones.
        pass
    elif bone_name is not None:
        pass

    # Sample the transform for a given track at each frame.
    # This essentially "bakes" the keyframes of the animation.
    for frame in range(animation.frame_count):
        print(track.sample_scale(frame, animation.frame_count))
        print(track.sample_rotation(frame, animation.frame_count))
        print(track.sample_translation(frame, animation.frame_count))
    print()

xc3_model_py enables Rust log output by default to use with Python's logging module. Logging can be disabled entirely if not needed using logging.disable().

import logging

# Configure log messages to include more information.
FORMAT = "%(levelname)s %(name)s %(filename)s:%(lineno)d %(message)s"
logging.basicConfig(format=FORMAT, level=logging.INFO)

Documentation

See the pyi stub file for complete function and type information. This also enables autocomplete in supported editors like the Python extension for VSCode. The Python API attempts to match the Rust functions and types in xc3_model as closely as possible.

Installation

The compiled extension module can be imported just like any other Python file. On Windows, rename xc3_model_py.dll to xc3_model_py.pyd. If importing xc3_model_py fails, make sure the import path is specified correctly and the current Python version matches the version used when building. For installing in the current Python environment, install maturin and use maturin develop --release.

Building

Build the project with cargo build --release. This will compile a native python module for the current Python interpreter. For use with Blender, make sure to build for the Python version used by Blender. This can be achieved by activating a virtual environment with the appropriate Python version or setting the Python interpeter using the PYO3_PYTHON environment variable. See the PyO3 guide for details.

Limitations

Some types from xc3_model_py are opaque wrappers around the underlying Rust types and cannot be constructed in any way from Python. Some of these limitations should hopefully be resolved in the future.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

xc3_model_py-0.14.0-cp312-cp312-win_amd64.whl (5.3 MB view details)

Uploaded CPython 3.12Windows x86-64

xc3_model_py-0.14.0-cp312-cp312-manylinux_2_34_x86_64.whl (5.5 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.34+ x86-64

xc3_model_py-0.14.0-cp312-cp312-macosx_11_0_arm64.whl (4.3 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

xc3_model_py-0.14.0-cp312-cp312-macosx_10_12_x86_64.whl (5.1 MB view details)

Uploaded CPython 3.12macOS 10.12+ x86-64

xc3_model_py-0.14.0-cp311-cp311-win_amd64.whl (5.3 MB view details)

Uploaded CPython 3.11Windows x86-64

xc3_model_py-0.14.0-cp311-cp311-manylinux_2_34_x86_64.whl (5.5 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.34+ x86-64

xc3_model_py-0.14.0-cp311-cp311-macosx_11_0_arm64.whl (4.3 MB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

xc3_model_py-0.14.0-cp311-cp311-macosx_10_12_x86_64.whl (5.1 MB view details)

Uploaded CPython 3.11macOS 10.12+ x86-64

xc3_model_py-0.14.0-cp310-cp310-win_amd64.whl (5.3 MB view details)

Uploaded CPython 3.10Windows x86-64

xc3_model_py-0.14.0-cp310-cp310-manylinux_2_34_x86_64.whl (5.5 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.34+ x86-64

xc3_model_py-0.14.0-cp310-cp310-macosx_11_0_arm64.whl (4.3 MB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

xc3_model_py-0.14.0-cp310-cp310-macosx_10_12_x86_64.whl (5.1 MB view details)

Uploaded CPython 3.10macOS 10.12+ x86-64

xc3_model_py-0.14.0-cp39-cp39-win_amd64.whl (5.3 MB view details)

Uploaded CPython 3.9Windows x86-64

xc3_model_py-0.14.0-cp39-cp39-manylinux_2_34_x86_64.whl (5.5 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.34+ x86-64

xc3_model_py-0.14.0-cp39-cp39-macosx_11_0_arm64.whl (4.3 MB view details)

Uploaded CPython 3.9macOS 11.0+ ARM64

xc3_model_py-0.14.0-cp39-cp39-macosx_10_12_x86_64.whl (5.1 MB view details)

Uploaded CPython 3.9macOS 10.12+ x86-64

File details

Details for the file xc3_model_py-0.14.0-cp312-cp312-win_amd64.whl.

File metadata

File hashes

Hashes for xc3_model_py-0.14.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 c46ffd4bf7cf605f1d6c6414aece00cd2a7c5ead4e63025bbc5e13014a47b4a2
MD5 28e2e397917ea13fa3a3657a83dd6cd1
BLAKE2b-256 a3d1568573cad2543c1b3e4fab246e2642206662df1341982a811de2ff0bfed9

See more details on using hashes here.

File details

Details for the file xc3_model_py-0.14.0-cp312-cp312-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for xc3_model_py-0.14.0-cp312-cp312-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 cb4abf14b5b275abb1bb4518b55db56b74477e7d80c897c0c81c15ea1201a964
MD5 4ae6a7e54f266f44e76d828febfed4c4
BLAKE2b-256 06850b7b1187628e5962eb4736e602c849986ba03cd63c678331ad6f6ae64318

See more details on using hashes here.

File details

Details for the file xc3_model_py-0.14.0-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for xc3_model_py-0.14.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 cf71382a8aebb96e2ad8fe5b45235e849ee3a01b74ccd4c66417fff4c504aa65
MD5 cc8205e95adcec82e72b8a66fee221d3
BLAKE2b-256 27d217eef9bac19e66118ea38fb4d053ec13bbfe4bbe83f9c1f0ab9b2af1ba60

See more details on using hashes here.

File details

Details for the file xc3_model_py-0.14.0-cp312-cp312-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for xc3_model_py-0.14.0-cp312-cp312-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 f34a08ddcca8b395d0e49ba571742a9535a99f9c69da83a80b267f91578d74e0
MD5 11b22f97dcbe3643b4926c5485ab9d0d
BLAKE2b-256 05db36229e547df7d1e113d6910a723f36810695ea753a68105150f5ddb57da9

See more details on using hashes here.

File details

Details for the file xc3_model_py-0.14.0-cp311-cp311-win_amd64.whl.

File metadata

File hashes

Hashes for xc3_model_py-0.14.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 3ed5c28e745055f492210f56323a1c6602ffc7710dd2c8379bffe4926e44ae4f
MD5 478e464929fdc7d74f5b6ee0d3ac22f4
BLAKE2b-256 9680910a3ec7c405a62031d9fe9fd994933629ce06efd3f81261edfe65229f3a

See more details on using hashes here.

File details

Details for the file xc3_model_py-0.14.0-cp311-cp311-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for xc3_model_py-0.14.0-cp311-cp311-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 24409f16ef450ce7bad78438ec2e72351aa527ab33a23cbdf904203b29d83ba6
MD5 daa95b04fa5f091360f2be24bb12ab45
BLAKE2b-256 af81b41742efec80f5836db861c9f8395ebf2c5a198552e9188a61c38c8758d1

See more details on using hashes here.

File details

Details for the file xc3_model_py-0.14.0-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for xc3_model_py-0.14.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 f9316ff86f97b2c11c8e03e078007a950b42fee5677b6c90ee392d24d2373c84
MD5 b2e32173b1ff6fdcca7a528c862b9062
BLAKE2b-256 2e5fa6feb25b03757e613064907c4c7935730391c3eaa82453acb6cf43620352

See more details on using hashes here.

File details

Details for the file xc3_model_py-0.14.0-cp311-cp311-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for xc3_model_py-0.14.0-cp311-cp311-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 073f580f13cfcafda8fb64f77fd3554944e54a1f8d46b548ba5da684339df627
MD5 97ea7213dce6c5ff34a28c1859ac7a23
BLAKE2b-256 30ca02951bb71a6fcf51c658bfb217782c281fd9993bf721cf053cfeb8bd0b76

See more details on using hashes here.

File details

Details for the file xc3_model_py-0.14.0-cp310-cp310-win_amd64.whl.

File metadata

File hashes

Hashes for xc3_model_py-0.14.0-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 35677714c9f9a40a5915f6cf30b096bd1df2f96e94cb83fda97d1386f01c56e0
MD5 315e8fb7c9832ed77fc980494293b982
BLAKE2b-256 897c2af9dc3da269acf0c1bcb68e1333171e97be0081bf8129fc6330f7f93552

See more details on using hashes here.

File details

Details for the file xc3_model_py-0.14.0-cp310-cp310-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for xc3_model_py-0.14.0-cp310-cp310-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 27204120b5bbf7fb1c1a726c38fc28fe59689a95c3427eb27a8508b1ed3c1a04
MD5 2cda968a3b37b6fdad9dca6b76025521
BLAKE2b-256 a01dd94d92200d594d3f064c309ea1e0bd87a65a3497875e8053a64c45989b4b

See more details on using hashes here.

File details

Details for the file xc3_model_py-0.14.0-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for xc3_model_py-0.14.0-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 51b1bd7b724c573ff1f7b6cef08d098610ddc987a64d5fd794ecdd60e423f030
MD5 d6b5f7ded42c005a7968712d0544920d
BLAKE2b-256 80266a82d4676efab024a6a16e4da04d00e97f00ba3a110f9fa97cac3d4e9c18

See more details on using hashes here.

File details

Details for the file xc3_model_py-0.14.0-cp310-cp310-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for xc3_model_py-0.14.0-cp310-cp310-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 96bf6413b020e21be5c31237e630344091eb713c7ee741d03e487fa973fc73d1
MD5 b1624f8d23cbe80129433ebc7fd36eb8
BLAKE2b-256 9feb2e80f09e5a41c5276bcdd87fc3de92736c6eb5e526a81f58bc116c4f3f48

See more details on using hashes here.

File details

Details for the file xc3_model_py-0.14.0-cp39-cp39-win_amd64.whl.

File metadata

File hashes

Hashes for xc3_model_py-0.14.0-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 e08ea817271400c50176e55b9a1ffda0a2909522d2d238cacc3664413f92a6c3
MD5 0835c9f1bd9d72ee8d5aa900df3833fa
BLAKE2b-256 0431219c7ed47610371b57cc07031bdfb94d2d5ab08baf804fd460282cb86995

See more details on using hashes here.

File details

Details for the file xc3_model_py-0.14.0-cp39-cp39-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for xc3_model_py-0.14.0-cp39-cp39-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 473de48b9862145323376ee6970c27c444cb9db3858b0908957703de785d1ed7
MD5 02cd69825dc407485d859436d3a417c8
BLAKE2b-256 898998d7ef5f3e6b71487f459769297133626e69ac757e67e770c4fc3bc55141

See more details on using hashes here.

File details

Details for the file xc3_model_py-0.14.0-cp39-cp39-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for xc3_model_py-0.14.0-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 e29ead30b30b3e0eec75a418634fee0bb9c77392cb7be6ad2b013327ea297abc
MD5 6b957e3f9fb2631e49d3daf586b3f71c
BLAKE2b-256 66b81609876a9d0c0abb8c1bafbca60d47ad21183374969beef882778073681e

See more details on using hashes here.

File details

Details for the file xc3_model_py-0.14.0-cp39-cp39-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for xc3_model_py-0.14.0-cp39-cp39-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 90b48f5bc02ce21a3d270a9a4ae34c546a6bd47f211dc7dffd716012f19442b6
MD5 d9916ec81b18f2762756d007354e2b83
BLAKE2b-256 42486b4ce51b15b884bb82d4d3ac7a95fc05ae8d80d3d690e098f99a0e60d691

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page