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.13.0-cp312-cp312-win_amd64.whl (5.0 MB view details)

Uploaded CPython 3.12Windows x86-64

xc3_model_py-0.13.0-cp312-cp312-manylinux_2_34_x86_64.whl (5.2 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.34+ x86-64

xc3_model_py-0.13.0-cp312-cp312-macosx_11_0_arm64.whl (4.0 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

xc3_model_py-0.13.0-cp312-cp312-macosx_10_12_x86_64.whl (4.8 MB view details)

Uploaded CPython 3.12macOS 10.12+ x86-64

xc3_model_py-0.13.0-cp311-cp311-win_amd64.whl (5.0 MB view details)

Uploaded CPython 3.11Windows x86-64

xc3_model_py-0.13.0-cp311-cp311-manylinux_2_34_x86_64.whl (5.2 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.34+ x86-64

xc3_model_py-0.13.0-cp311-cp311-macosx_11_0_arm64.whl (4.0 MB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

xc3_model_py-0.13.0-cp311-cp311-macosx_10_12_x86_64.whl (4.8 MB view details)

Uploaded CPython 3.11macOS 10.12+ x86-64

xc3_model_py-0.13.0-cp310-cp310-win_amd64.whl (5.0 MB view details)

Uploaded CPython 3.10Windows x86-64

xc3_model_py-0.13.0-cp310-cp310-manylinux_2_34_x86_64.whl (5.2 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.34+ x86-64

xc3_model_py-0.13.0-cp310-cp310-macosx_11_0_arm64.whl (4.0 MB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

xc3_model_py-0.13.0-cp310-cp310-macosx_10_12_x86_64.whl (4.8 MB view details)

Uploaded CPython 3.10macOS 10.12+ x86-64

xc3_model_py-0.13.0-cp39-cp39-win_amd64.whl (5.0 MB view details)

Uploaded CPython 3.9Windows x86-64

xc3_model_py-0.13.0-cp39-cp39-manylinux_2_34_x86_64.whl (5.2 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.34+ x86-64

xc3_model_py-0.13.0-cp39-cp39-macosx_11_0_arm64.whl (4.0 MB view details)

Uploaded CPython 3.9macOS 11.0+ ARM64

xc3_model_py-0.13.0-cp39-cp39-macosx_10_12_x86_64.whl (4.8 MB view details)

Uploaded CPython 3.9macOS 10.12+ x86-64

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.13.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 52371957a67b4d1c02d1352628a30a3f09890d8032988e36049805028d52cc44
MD5 298b855c41f205e7f988758ec7939529
BLAKE2b-256 6b309760f09478380bef8049cf6065f5c59cba79ad0c677a53e30dd2b41f878e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.13.0-cp312-cp312-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 21ee8915437a9169e5cab5cf0bff4b4ed21584ed0454c7f3983435aacb01237f
MD5 781499b7cb8734553c153f218a35372e
BLAKE2b-256 238da4104d80493a82ce6d028364f9ff8421bb58aac50a45c56443e1bca44356

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.13.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 114b1299d95fdf18f27703314dc3bee00a674aad8314f17fbd1ed5e00760cc9c
MD5 f0efb21c1a245b266182130b65190559
BLAKE2b-256 fa35fde1cc58ec63daae11fc26676249a89f80bcc1e11e7bc8d9c485d4e6cc12

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.13.0-cp312-cp312-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 5fc3a541ae38189b31473f08d89b4bf94251c8bff0863b5f27327d8d3cfeafe8
MD5 72129985f37b1bb291e60745a2c4e5e3
BLAKE2b-256 1180581108eb62ccc2b00cc377a8639bba387d8b8baf626ae53c0a72f15c523f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.13.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 631743a1b75bf3b155c561e41d67d7840df3e8946b982e859d440ba9c309e37f
MD5 6554fc399e0cd8843c00abb7675a64cf
BLAKE2b-256 2db35cb232be29d44ee27e3d7d870b860a6ef5889dd0ece41e4f9cb1cd17dcf9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.13.0-cp311-cp311-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 8ec0ddcca5c391245c3b04f380a7469e3259e77379556aace542ce779c5ebedb
MD5 d796e910a8d185a03c4b7b22406405b7
BLAKE2b-256 2616f6119c0d046dd970507eb03fd26299e86fc44ef7aab0d14b0f407e6cd0cc

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.13.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 0d22d673a83f8ea836bb767b87c3ea7f55e7b78363862761b7fe0c88530630de
MD5 c1c972276992719c13f131ad827f8706
BLAKE2b-256 2a2b361bc2f5a1510057a4255b3cfd8a86ef0e76b7643bf48bdaab36f04fdea2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.13.0-cp311-cp311-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 377909de1dd7575ee69be7a016bb945bedb724ee228f27bdc31701c97b2f450d
MD5 397b3f9ea0383830971d65491b47eb69
BLAKE2b-256 f9eb79f3f8ce1cb3618774bf298381a5a0daaf83c2a0fbd4d52d5d99dba2d475

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.13.0-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 124b4ae2f91f718076042051b736bf9e233953fb1f63e8555b60e1384176b052
MD5 9f03b175a3b71f6b3d70a06f06879cfb
BLAKE2b-256 1e18b28c8d2625df88075a2da8355d4010f0c1fd65cc631ea27c162b38d8c425

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.13.0-cp310-cp310-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 51f5e538cb5b719c3c65c2ae70971d51a8035be541dae109734b07800b7371d7
MD5 4a03f1a06612d149f750cb6c42c1982b
BLAKE2b-256 cbe97dcd43ee5863c37ac32bfe60af8b59e8e0985443277dbbbfb16cce9420f2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.13.0-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 a1474d91e7b5799bae319298e70082a271f418b192a7ee789edbe41a2ed22c95
MD5 6a1fb9741b13d12074d8afbb5045db52
BLAKE2b-256 969e40bf3cacf29e78628e8dad06f17acb41c28ade71c90a28c28d3a271ed17c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.13.0-cp310-cp310-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 746d3a33f319e847b8aa400f7b6b31000fca4ca7131bce3bda0481c0d140bd26
MD5 2382991e1e208512622fcafe8fb16c7d
BLAKE2b-256 527ed32458f9520a9a9cbd20bda7e1a964b9f9d508bdb756908a0e6641044b30

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.13.0-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 52783831504c00e77a54cb32c0660abd0bf3bd54c3db85b8a2bf7f15befada9b
MD5 ad862b530cab8ebd97cce9feb15d5c22
BLAKE2b-256 5b5390461ff8b1e73a71d9513dc553ff6e9e17f35334426d832127b828f4f1a1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.13.0-cp39-cp39-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 02700bd8d7ff1fa9b4822a346131c4694087351268780e108ae4d70d05d6f0ac
MD5 5d062825e157c9ab93e651fa882d8584
BLAKE2b-256 d0a42ec9ed823b75306686ebe975b2c0e2cf7d9a0b16b239430d738c5713e870

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.13.0-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 3de9b1f17f9d9cc246e6ab587c9d3d50d135e7caa64cc652f475143124b5633c
MD5 7762eef78c6247965cdaa2e8e0f1702b
BLAKE2b-256 a48318cb10e9c015bd20e60b9aa9c9e3fb027896bc3b6b9c9d2c1bd2f8211602

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.13.0-cp39-cp39-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 f80ac0c9e69d8df7ade83f94d57618d5222518957f103644d4427650ef8deda5
MD5 2683e15c31a9774dbb1cf265790fab42
BLAKE2b-256 a2445e10d3f29dc0df2625b4c8544de47e3f03431d31bd9eec4409ea2af6f351

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