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.11.0-cp312-none-win_amd64.whl (5.2 MB view details)

Uploaded CPython 3.12Windows x86-64

xc3_model_py-0.11.0-cp312-cp312-manylinux_2_34_x86_64.whl (5.9 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.34+ x86-64

xc3_model_py-0.11.0-cp312-cp312-macosx_11_0_arm64.whl (4.6 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

xc3_model_py-0.11.0-cp312-cp312-macosx_10_12_x86_64.whl (5.2 MB view details)

Uploaded CPython 3.12macOS 10.12+ x86-64

xc3_model_py-0.11.0-cp311-none-win_amd64.whl (5.2 MB view details)

Uploaded CPython 3.11Windows x86-64

xc3_model_py-0.11.0-cp311-cp311-manylinux_2_34_x86_64.whl (5.9 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.34+ x86-64

xc3_model_py-0.11.0-cp311-cp311-macosx_11_0_arm64.whl (4.5 MB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

xc3_model_py-0.11.0-cp311-cp311-macosx_10_12_x86_64.whl (5.2 MB view details)

Uploaded CPython 3.11macOS 10.12+ x86-64

xc3_model_py-0.11.0-cp310-none-win_amd64.whl (5.2 MB view details)

Uploaded CPython 3.10Windows x86-64

xc3_model_py-0.11.0-cp310-cp310-manylinux_2_34_x86_64.whl (5.9 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.34+ x86-64

xc3_model_py-0.11.0-cp310-cp310-macosx_11_0_arm64.whl (4.5 MB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

xc3_model_py-0.11.0-cp310-cp310-macosx_10_12_x86_64.whl (5.2 MB view details)

Uploaded CPython 3.10macOS 10.12+ x86-64

xc3_model_py-0.11.0-cp39-none-win_amd64.whl (5.2 MB view details)

Uploaded CPython 3.9Windows x86-64

xc3_model_py-0.11.0-cp39-cp39-manylinux_2_34_x86_64.whl (5.9 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.34+ x86-64

xc3_model_py-0.11.0-cp39-cp39-macosx_11_0_arm64.whl (4.5 MB view details)

Uploaded CPython 3.9macOS 11.0+ ARM64

xc3_model_py-0.11.0-cp39-cp39-macosx_10_12_x86_64.whl (5.3 MB view details)

Uploaded CPython 3.9macOS 10.12+ x86-64

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.11.0-cp312-none-win_amd64.whl
Algorithm Hash digest
SHA256 e0effe8440db793bfe68db0b4db9b8948d3d1bfe2fcdca7013d30a8241210f0e
MD5 2fe2863b9f08e24bf6ddcb76b78f3f9d
BLAKE2b-256 dcc530630f4ab68f810f692378af7b59f9f7634c9d5c410564282664f737a295

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.11.0-cp312-cp312-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 05fe0252b7f0076485850f1f576c3c73a0aac40b8b3b1ae9809e75b9d153184a
MD5 2c53d426d258b0446b949c8c05fcf9c8
BLAKE2b-256 6745bee89e2d959576be08ceacfaea352e41699e3db20a0f808678d7357e84d9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.11.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 69b484743f5cc22639ff0cde4ccf26a90a2850cc37e012d42b29561dde321321
MD5 315f863f30097219a01d490ba45aadc5
BLAKE2b-256 80b90294e06d8fe45d6fec6fa533095ea5e4b5139e3e9c1117597bc3c852617e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.11.0-cp312-cp312-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 f63f70fe6a1ed36b62254cbb9f8ca17f3bce62feb09001ee2a3bac4a6e859845
MD5 7026d27890df9424ccb218ce521674b0
BLAKE2b-256 33081e14cac24a6ec8817eefa7033e4387f827d0aba031463f882010b44cbbf9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.11.0-cp311-none-win_amd64.whl
Algorithm Hash digest
SHA256 c932bfc2dcf660a6fbcf8b13c368d84d68e956f7b6324abb19eacb8b6d5c0ecf
MD5 8f4913576c763539a305e814f9c0d1b0
BLAKE2b-256 108ca50607e8444098ca0b41cd5c6db327b45c85a79a57bb15b6523671989f0e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.11.0-cp311-cp311-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 5bdc76be21e9dd4c66fac330698b376b8827ffef48866528a765385e51a075d7
MD5 228146944820a1534074163ff145ac9d
BLAKE2b-256 334c2fbccbfdc23f0ea6d63399311f1b0df038b8b5c7f159b04ad5a26b187f93

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.11.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 158a4152feccecbe06cfd197b1482eae1fbe6754c111cef2b61425bfd1b7089b
MD5 6ecc62a533455bc92b9f04ab07fac6bc
BLAKE2b-256 7611e16729dcc9bb311be2c2647db3328b2ca649c9367171c322b12f9b923e6e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.11.0-cp311-cp311-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 5aba5dae4100e22efb16a9ce91938e625b898b779df7ebe9d51fd20cfbe8205f
MD5 0c79fa5b7848db0cf07c655257f48666
BLAKE2b-256 de725c0a512960284102d1824073995abf5dd6bf0390879aa1f6af4594a8a9cb

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.11.0-cp310-none-win_amd64.whl
Algorithm Hash digest
SHA256 a48c832eb2b3317fdd63d2acc0401ebd4c1b91a18c6873dd6ebbd29969c62a1a
MD5 e38b108b2f897aa14f828bf3098de52e
BLAKE2b-256 54fdbbf8ca19262f3e94cf904776d6616f2091df267049d183c1f4de6360e4f8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.11.0-cp310-cp310-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 43720aa3203b11f487ff039dd73300d81121aa8834e74dbff1e6e230b381af35
MD5 cecba49a72fd7131bac7035d78b5c73c
BLAKE2b-256 667510b65b82b16d665abb1823e8aec3c6b9418debadc007b6f80987ada8c91a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.11.0-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 157e550cc3d5a8c1b11f77455f5e09fb82875f0dee1c3171089a1ab60e247246
MD5 13d05d88612739de48cca875ad99ab44
BLAKE2b-256 fc11e834a5e4a72a1fd79776a164eadb90e6778635f66bd8feeab41b16115120

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.11.0-cp310-cp310-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 d2716ce45e00aba3bb690c919dddc2397fd546e29d700ae6854c0ee5bb0cb6cb
MD5 b58d020219cae922875cb7d1ab818c9d
BLAKE2b-256 20d14be3f4ebbdc851933adbe74673c3d79aa9d7b391edfd72a64e62bf25c8c2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.11.0-cp39-none-win_amd64.whl
Algorithm Hash digest
SHA256 4e5937f9e35ffb88bf4922c99834118c14402ea0659a496e84c6a3b861e6b06a
MD5 d12c53c7d6aec09b7b285d8f99e0a580
BLAKE2b-256 9a0ba83b5c8baaf940dc53a6fd23456bfdb3f14ad7c6f724d7c81a11506e1128

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.11.0-cp39-cp39-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 31f4904278c2e160a5de088744a10419fb2f786efbb461d0aa79f87f3acf0dc5
MD5 06c343802351c40c5eb7534c070a5af1
BLAKE2b-256 a5d3fcaabc9abb40029d981fab8a436e0920451aeaca34f5b31f96c070dd6e66

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.11.0-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 036cfaebe3d6b5bbbc13d04b379f58b8a7ec0532409184f83d3aca52f446381b
MD5 8c2dc15b2b9053d263d7a3d0d8f8aece
BLAKE2b-256 199f5ba6c92c1039ca0db080cd35929a95f5f179e8806953c081d7ca99f74a5a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xc3_model_py-0.11.0-cp39-cp39-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 1965f025dbdbe829ed10dc3c4f9710054d987589efc8682ee044a97a35fc0690
MD5 cf4ca76e50bd88720841e2217dcfae57
BLAKE2b-256 d00bb193b3ea5e953f5acd247b9dd44e955e609476174bf6ff4f6e6866cccc53

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