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 JSON 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.json")
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 JSON 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.json")
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

xc3_model_py-0.10.0-cp312-none-win_amd64.whl (4.5 MB view details)

Uploaded CPython 3.12 Windows x86-64

xc3_model_py-0.10.0-cp312-cp312-manylinux_2_34_x86_64.whl (5.0 MB view details)

Uploaded CPython 3.12 manylinux: glibc 2.34+ x86-64

xc3_model_py-0.10.0-cp312-cp312-macosx_11_0_arm64.whl (3.8 MB view details)

Uploaded CPython 3.12 macOS 11.0+ ARM64

xc3_model_py-0.10.0-cp312-cp312-macosx_10_12_x86_64.whl (4.5 MB view details)

Uploaded CPython 3.12 macOS 10.12+ x86-64

xc3_model_py-0.10.0-cp311-none-win_amd64.whl (4.5 MB view details)

Uploaded CPython 3.11 Windows x86-64

xc3_model_py-0.10.0-cp311-cp311-manylinux_2_34_x86_64.whl (5.0 MB view details)

Uploaded CPython 3.11 manylinux: glibc 2.34+ x86-64

xc3_model_py-0.10.0-cp311-cp311-macosx_11_0_arm64.whl (3.8 MB view details)

Uploaded CPython 3.11 macOS 11.0+ ARM64

xc3_model_py-0.10.0-cp311-cp311-macosx_10_12_x86_64.whl (4.4 MB view details)

Uploaded CPython 3.11 macOS 10.12+ x86-64

xc3_model_py-0.10.0-cp310-none-win_amd64.whl (4.5 MB view details)

Uploaded CPython 3.10 Windows x86-64

xc3_model_py-0.10.0-cp310-cp310-manylinux_2_34_x86_64.whl (5.0 MB view details)

Uploaded CPython 3.10 manylinux: glibc 2.34+ x86-64

xc3_model_py-0.10.0-cp310-cp310-macosx_11_0_arm64.whl (3.8 MB view details)

Uploaded CPython 3.10 macOS 11.0+ ARM64

xc3_model_py-0.10.0-cp310-cp310-macosx_10_12_x86_64.whl (4.4 MB view details)

Uploaded CPython 3.10 macOS 10.12+ x86-64

xc3_model_py-0.10.0-cp39-none-win_amd64.whl (4.5 MB view details)

Uploaded CPython 3.9 Windows x86-64

xc3_model_py-0.10.0-cp39-cp39-manylinux_2_34_x86_64.whl (5.0 MB view details)

Uploaded CPython 3.9 manylinux: glibc 2.34+ x86-64

xc3_model_py-0.10.0-cp39-cp39-macosx_11_0_arm64.whl (3.8 MB view details)

Uploaded CPython 3.9 macOS 11.0+ ARM64

xc3_model_py-0.10.0-cp39-cp39-macosx_10_12_x86_64.whl (4.4 MB view details)

Uploaded CPython 3.9 macOS 10.12+ x86-64

File details

Details for the file xc3_model_py-0.10.0-cp312-none-win_amd64.whl.

File metadata

File hashes

Hashes for xc3_model_py-0.10.0-cp312-none-win_amd64.whl
Algorithm Hash digest
SHA256 f4722f3a39372f91534b2b4e118d09e2578e020ef42e7fdedff89c10a39996ff
MD5 98bb6f13a555287fbb91c227d8525f8a
BLAKE2b-256 4abfd4598af41feee615cc41d603f028c71bbd07020f95cbf1f505fa76ffbf04

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.10.0-cp312-cp312-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 6beaf2a3d1796a1099a64d0fdfcffba1c8666b5648359868e9224686c43be955
MD5 e1e5cfc3b7839e0cea2b128a975f9c35
BLAKE2b-256 2cbc8678410cad8aabfb92643853b52423e5d417f73b5fe62320e1e0ac0fa05b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.10.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 f1a6b47c8b872908d6cb7b0c295f14d7c38bbd52646a0981f264d100ad38ae97
MD5 3ab16b89032598d188d7f8dbeab1d405
BLAKE2b-256 cfe02810115b3428acada08c1c9bc4ccfaecbf2a46eb6afb3bc994479115c405

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.10.0-cp312-cp312-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 c7f9ed89c3079e66019ebee4faa63bd6f9dd1890f6f3ebecbf7d46f9d889a521
MD5 545f701ce3b18ad764117b2ac3456f29
BLAKE2b-256 5b0fad69b4dd608c2e7c8df700d6e4589e79ea457345d9f609473808ed98da6b

See more details on using hashes here.

File details

Details for the file xc3_model_py-0.10.0-cp311-none-win_amd64.whl.

File metadata

File hashes

Hashes for xc3_model_py-0.10.0-cp311-none-win_amd64.whl
Algorithm Hash digest
SHA256 5afd0e4a1e39d88ca98311fab1c49f19d24d53578fd262a52933dbc78896e77b
MD5 333622926c2b0c75f783c41ff5a9b1d4
BLAKE2b-256 631143468ab2fb46b65d14f54d5b5d9585a8f7c8bccd4d5548d76514fec49698

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.10.0-cp311-cp311-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 3448c5f393e3117162ea981fd579e8580abed4a7929d10afc7ed3947f4165728
MD5 7978fb0f3f11bf12a0909a5e77d4f2c1
BLAKE2b-256 800b1f8c69c55541c1cb56810ea6a6f6260c51bdbf7e6461f0d17bd8a1526262

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.10.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 f706c3759a66dfa3de1eb340da51272e4d490668bdde1b43e0ca23ef02b5109b
MD5 100d998eceff9c8d0e7c87b35c038b87
BLAKE2b-256 7d2a50bc2bc65fbd1a10d36a8f474cff203b541b67541e9e4fc01f820c230c14

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.10.0-cp311-cp311-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 456c3d544adf88ce81e69acbc9de9e41cfa2926c192054b511f6b03f3373dd8f
MD5 8576848f62458cb91c02d2cd14745758
BLAKE2b-256 989054e88240d1aea3817c8a3abe15309d8ec963b31b8b8e5c64ed5594649b2c

See more details on using hashes here.

File details

Details for the file xc3_model_py-0.10.0-cp310-none-win_amd64.whl.

File metadata

File hashes

Hashes for xc3_model_py-0.10.0-cp310-none-win_amd64.whl
Algorithm Hash digest
SHA256 508a4cd328b2d6da15dfef59c15907d094245cd3525ed9a9547af91482e26f81
MD5 fc4453bee72af78799dd4d12e2aeaf12
BLAKE2b-256 4ff5518a35f0424d10db7f6d971ef79bcc287de9c8ccf37a8005e5efd7f3e62a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.10.0-cp310-cp310-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 2017347a95d7446b36e6175aadc41e2c5472616ca8ad73ef7a5a4967bb0feb2a
MD5 f66b1c53ed16d280e75f2b1a7f77419d
BLAKE2b-256 d26b92e01e90e0a172a03d62bd371469574769671ea2e319dd147123df91450b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.10.0-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 91b33f486f7df056ad3e5074b238370c1fd8f6832df48a106895c0655805dd65
MD5 35053bd04ced07406ebe53f54974ce9f
BLAKE2b-256 daa4b3333c30de1288d63ad51931cda0db4226fea5c714e65f07acd1db040097

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.10.0-cp310-cp310-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 63bc6b1e7702bfa3d8e6d8763041ae314d9cb703a2d134479c0350765cd8cb24
MD5 4cea1d4a27130c8105046a199efefbff
BLAKE2b-256 0e20971e4f42d7ffd7187ec08e2615fb530334f4de1ca38d4d3fac19c2d7a7a2

See more details on using hashes here.

File details

Details for the file xc3_model_py-0.10.0-cp39-none-win_amd64.whl.

File metadata

File hashes

Hashes for xc3_model_py-0.10.0-cp39-none-win_amd64.whl
Algorithm Hash digest
SHA256 a77b8e075d5b3fc0e4c9a91aff8fb99379d4b09fe7c7ef0ba034593a083cf448
MD5 5560a0b7b20998f8bbd6a82ebbc4f18a
BLAKE2b-256 00d177e5d53a688227ab21062ca37da20334f59bb95b33f8bc2d842a342f1d0a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.10.0-cp39-cp39-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 533b4595751802ca6d7206d8c68025806facf8666d3a05ac8405f4f097d0c055
MD5 c6b5791f2259d9dab299eafc15101a37
BLAKE2b-256 0c39be42bd80d1c130d299ba7eae7ef05d78ea00e9caccd680dc2049f689c609

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.10.0-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 5a2a9468dd8168a7d6400bea79d00685c37a733ae95eaa45eddd4fd4976cb33f
MD5 7fd4d21ee74344773738db3592b80496
BLAKE2b-256 c88cead6afcc3a3fb595d0ca31473b5ea01d94781e8f0b2912ee3107a10a878b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.10.0-cp39-cp39-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 9a4441b4f4340d64550700418b4554891ce65a79e8a4c8f9ac2b7208156b298d
MD5 b93c5b9e35ec8e3cf1445def1f9d3a7d
BLAKE2b-256 57ecd1a64b515680dc22e14047166e47d4aea5e177b1c3d9d6ed3c5994c9f70f

See more details on using hashes here.

Supported by

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