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

Uploaded CPython 3.12Windows x86-64

xc3_model_py-0.12.0-cp312-cp312-manylinux_2_34_x86_64.whl (6.0 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.34+ x86-64

xc3_model_py-0.12.0-cp312-cp312-macosx_11_0_arm64.whl (4.8 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

xc3_model_py-0.12.0-cp312-cp312-macosx_10_12_x86_64.whl (5.6 MB view details)

Uploaded CPython 3.12macOS 10.12+ x86-64

xc3_model_py-0.12.0-cp311-cp311-win_amd64.whl (5.4 MB view details)

Uploaded CPython 3.11Windows x86-64

xc3_model_py-0.12.0-cp311-cp311-manylinux_2_34_x86_64.whl (6.1 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.34+ x86-64

xc3_model_py-0.12.0-cp311-cp311-macosx_11_0_arm64.whl (4.8 MB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

xc3_model_py-0.12.0-cp311-cp311-macosx_10_12_x86_64.whl (5.6 MB view details)

Uploaded CPython 3.11macOS 10.12+ x86-64

xc3_model_py-0.12.0-cp310-cp310-win_amd64.whl (5.4 MB view details)

Uploaded CPython 3.10Windows x86-64

xc3_model_py-0.12.0-cp310-cp310-manylinux_2_34_x86_64.whl (6.1 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.34+ x86-64

xc3_model_py-0.12.0-cp310-cp310-macosx_11_0_arm64.whl (4.8 MB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

xc3_model_py-0.12.0-cp310-cp310-macosx_10_12_x86_64.whl (5.6 MB view details)

Uploaded CPython 3.10macOS 10.12+ x86-64

xc3_model_py-0.12.0-cp39-cp39-win_amd64.whl (5.4 MB view details)

Uploaded CPython 3.9Windows x86-64

xc3_model_py-0.12.0-cp39-cp39-manylinux_2_34_x86_64.whl (6.1 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.34+ x86-64

xc3_model_py-0.12.0-cp39-cp39-macosx_11_0_arm64.whl (4.8 MB view details)

Uploaded CPython 3.9macOS 11.0+ ARM64

xc3_model_py-0.12.0-cp39-cp39-macosx_10_12_x86_64.whl (5.6 MB view details)

Uploaded CPython 3.9macOS 10.12+ x86-64

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.12.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 d10c91121704e5ce7db9bc605ce9070d4a4c2c68037223dc4627196cffd348b3
MD5 9242e5d759f9234dc6471acfb46edca9
BLAKE2b-256 ad096ae2ceb5fb3c99761b7fd5198150d30181aae106c335621f2406ed297e47

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.12.0-cp312-cp312-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 3abf89431e941d514b89f5a7e8e35e3efffe8559b6e5fc7c44b7e002909a4efb
MD5 8398a75129df783205135d268b7378f2
BLAKE2b-256 f76d2bbc7bacef1e3235210a56da3d779974310cad72d550dbf8ef5d236af5ca

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.12.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 c0367c8e64974ac7511924c1a8901b4f4148978580aab1e77025b1af9dd1c80f
MD5 7a5944e8b3372a5d8dedc10a649f357c
BLAKE2b-256 9aa1b05da1a19337f1bbd3c5dc69d07af02d9bf5774ab545b4bbfab2015637ab

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.12.0-cp312-cp312-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 ec48d6699f59515cd34f1a4c99727add74ae0bba71fbc73b373b992b32ad9a45
MD5 cefc4bff3e2903f594dbc61be6d16249
BLAKE2b-256 eefddb5355a2f715e9c1aafbeae75f9d855ffa6e11eb76e3663fd87edd03f93e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.12.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 491e29ae2aaaf459cd68d55b94fa1e44cdbec7160c9785569108735503cbfb76
MD5 56a6665b3a3f8879342b3efeddac1365
BLAKE2b-256 b62c4f9c2d6d11f9667ee507456c7fd04c9ad504a1b6c7b30c6e4482131beb9f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.12.0-cp311-cp311-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 4ca86d6a51123510aec4bc6fcdee031dd383dcaae22adfa092ae70db5ee17988
MD5 a7334b43c8e789885ce639e14dd8567f
BLAKE2b-256 9d4d1526499a343685b28bfe81dd2deda05215cb6c835c29322a3e2507a93851

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.12.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 2fc3d7ec4251b8ecb5d7b01fa03eab4f24b30b05544356f72c682f4d70614358
MD5 2f801f3fbb35c56eabf4f266823fbba6
BLAKE2b-256 eba5500c782deca0055c596bd456d3cd8306ed5dd2c9a16f8755d699ac466ea0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.12.0-cp311-cp311-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 c043db9a1da062928d59535922c3c1ce6172d6d4eee3c611f71890cea1aa0591
MD5 fed79dbdb279dd13e666caf5a08b4119
BLAKE2b-256 664779fa93ea510e2ab1a9c48401c607d1d2c7a14b23e601e5aa9b0c6d95d2ba

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.12.0-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 b3397649c07473fbaa14fc2bbadd4f4624cfc70c637b26fff094f9584ce9203b
MD5 962f12c0b468e0a4b6c0342a2429bbbc
BLAKE2b-256 fcd4607d37c727e95af97412d953216010893748f59f48a25c24dab3e3e7f96e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.12.0-cp310-cp310-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 bb7ef9b7d2fc37bf0b9af66e670f229389ee37dc69ec639fdcfd6bc6a174977a
MD5 fac112a229533828a64ba74bdefdb1ae
BLAKE2b-256 b561ca8a8423583c09ba4a32ed49ce4ea55d4c018c2bf9503854ed34049797d7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.12.0-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 f7be6aaa97c46a46b4f99bb9eab24f9ffb3afe99ad457fc630feb788c01cfad1
MD5 d3094c003e7a7929bdbd69bdd74f7838
BLAKE2b-256 2f6d18ae7c0f684cbc1a974f604433a531814370885728acda30cda401ddcf07

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.12.0-cp310-cp310-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 76f007f6b8bf6644c4d2ad3d8dc5320a90f122f184c8f93ba7192a55b5224056
MD5 065008eb683782f65920f953c3cc1dab
BLAKE2b-256 103d03e3511cf1f11249839659952078a22ec2a9f69412025feaf35e7e4eff24

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.12.0-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 a954672779775ac1a29c421c49407a228dbb3059e0b5d68aaeef0dd0b77c55b5
MD5 d5263289279fb3a318cc2597aab427af
BLAKE2b-256 2e8a1c523960b52dba04f9f1aa2f79b8beb0756d33d1177ad3d654a8416fd167

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.12.0-cp39-cp39-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 bf11e01fb733540d18a227abdeadb1a92432c079bb0a5efe1d53115a08a1dbc7
MD5 1b976ac066d7652856473fbe169d7f24
BLAKE2b-256 8b5206cc0391e29bf19c04c171ac2fc025b88e8e0f4fba20522a939b6addae81

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.12.0-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 b3a29cdde8c59cfb597a983dc20f84bc657494c4fecb1b642b2ccca3e8357dbf
MD5 19810e611bcf36a1616550572b07ed89
BLAKE2b-256 1a9ec5886c56532a34ac97c29cf37aa6408461ddb710f632dcc4a5c371e93a3f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.12.0-cp39-cp39-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 e1776a2ccc6e97f264eecc81b8c65be103f3471b4a91654f01f4a0c595bd51d0
MD5 5291cbe54d6f81b2ec45b8f212ba4328
BLAKE2b-256 966b14853150a6ccf1d7eb17d12852e4f3d7d175271996f035f01a9f5f5e3c57

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