How to Work with Deformers in Python

How to Work with Deformers in Python

A Deformer modifies how a Geometry (such as a Mesh) is influenced by external structures. SkinDeformer — the real, working deformer in this release — models skeletal skinning: a list of Bone entries, each linking a scene Node (the joint) to per-vertex influence weights on the mesh.

Step-by-Step Guide

Step 1: Install the Package

pip install aspose-3d-foss
python -c "import aspose.threed; print(aspose.threed.__name__)"

Step 2: Import Required Classes

from aspose.threed import Scene
from aspose.threed.entities import Mesh
from aspose.threed.deformers import SkinDeformer, Bone, BoneLinkMode
from aspose.threed.utilities import Vector4

Step 3: Build the Mesh and Its Joint Nodes

A skin deformer references ordinary scene nodes as joints — create them like any other node, positioned where the joint should sit:

scene = Scene()
mesh = Mesh("Limb")
mesh.control_points.add(Vector4(0.0, 0.0, 0.0, 1.0))
mesh.control_points.add(Vector4(1.0, 0.0, 0.0, 1.0))
mesh.control_points.add(Vector4(0.0, 1.0, 0.0, 1.0))
mesh.control_points.add(Vector4(0.0, 0.0, 1.0, 1.0))
mesh.create_polygon(0, 1, 2)
mesh.create_polygon(0, 2, 3)

mesh_node = scene.root_node.create_child_node("Limb", entity=mesh)

upper_joint = scene.root_node.create_child_node("UpperJoint")
lower_joint = scene.root_node.create_child_node("LowerJoint")

Step 4: Create Bones and Assign Weights

Each Bone links one joint node to a weight for every control point index it influences. set_weight(index, weight) grows the weight list as needed:

from aspose.threed.deformers import Bone, BoneLinkMode

upper_bone = Bone("UpperJoint")
upper_bone.node = upper_joint
upper_bone.link_mode = BoneLinkMode.NORMALIZE
upper_bone.set_weight(0, 1.0)
upper_bone.set_weight(1, 1.0)

lower_bone = Bone("LowerJoint")
lower_bone.node = lower_joint
lower_bone.link_mode = BoneLinkMode.NORMALIZE
lower_bone.set_weight(2, 1.0)
lower_bone.set_weight(3, 1.0)

Step 5: Build the Skin Deformer

Collect the bones into a SkinDeformer:

from aspose.threed.deformers import SkinDeformer

skin = SkinDeformer("LimbSkin")
skin.bones.append(upper_bone)
skin.bones.append(lower_bone)

Step 6: Attach the Deformer to the Mesh

A mesh’s deformer-list property returns the live underlying list — append directly to it to attach the deformer:

mesh.deformers.append(skin)

Step 7: Read Deformers Back

get_deformers(deformer_type) filters by type, or returns everything when no type is given:

from aspose.threed.deformers import SkinDeformer

for deformer in mesh.get_deformers(SkinDeformer):
    print(deformer.name, "bones:", len(deformer.bones))
    for bone in deformer.bones:
        print(" ", bone.node.name, "weight_count:", bone.weight_count)

Common Issues and Fixes

Reading a bone’s node raises an error. Bone.node raises a runtime error if it is read before being set — always assign it before reading it back.

get_weight(index) returns zero for an index you expect to have a value. set_weight() grows the internal weight list on demand; an index that was never written (or was written on a different Bone) simply reads back as zero rather than raising — check that you set the weight on the bone you expect.

Trying to build a morph-target (blend-shape) deformer instead. MorphTargetDeformer/MorphTargetChannel exist in the API surface, but their target geometry type, Shape, raises an error on construction in this release — there is no working way to build the Shape objects a morph-target channel needs. Use SkinDeformer for working deformer functionality in this release.

Deformer attached but get_deformers() returns an empty list. Confirm the deformer was appended to the same Mesh instance that is actually attached to a node (mesh.deformers.append(...), not a separate mesh object created afterward).

Frequently Asked Questions

What deformer types does Aspose.3D for Python support?

SkinDeformer (skeletal skinning via Bone entries) is the fully working deformer. MorphTargetDeformer exists in the class hierarchy but depends on the Shape class, which is not implemented in this release.

Do I need to normalize bone weights myself?

BoneLinkMode records the intended blending mode (normalize, additive, or total-one) as metadata on the bone, but Aspose.3D for Python does not perform runtime skinning/deformation math itself — that is the responsibility of the consuming renderer or game engine that reads the exported skin data.

Can one mesh have more than one deformer?

Yes — a mesh’s deformer list is a regular list, so it can hold multiple Deformer instances (for example, more than one SkinDeformer for different parts of a rig) at the same time.

How do I remove a deformer from a mesh?

Use the standard list method on that list, for example mesh.deformers.remove(skin), since the property exposes the live underlying list rather than a copy.

See Also