Vertex Weight Limit

examples/vertex-weight-limit/

A rigged industrial robot arm pruned to the game-engine cap of four bone influences per vertex, through the data API. The check proves no vertex exceeds the cap, weights still sum to one, the pose survives pruning, and the modifier is still exact linear blend skinning.

Rendered headless by the example itself. Select it to enlarge.

witnesses Limit-total and normalize without bpy.ops: keep the top four groups, VertexGroup.remove the rest, renormalize. LBS is verified against the weights read back from the mesh's own deform layer, not the authoring function.

tags armature mesh

runs on 4.5 LTS · 5.1 · 5.2 LTS

blender --background --python examples/vertex-weight-limit/vertex_weight_limit.py --

falsify it Breaks the contract on purpose and must exit 4

blender --background --python examples/vertex-weight-limit/vertex_weight_limit.py -- --skip-limit

A runnable example that rigs a six-axis-style industrial robot arm — bolted floor plinth and turret drum with a finned rear drive pack, clevis cheeks and servo drums at the shoulder and elbow, a tapered box-section upper arm and forearm, a gas-spring balancer across the shoulder, a wrist fork and a two-jaw gripper — as one skinned mesh, then enforces the game-engine maximum of four bone influences per vertex through the data API, following mesh-editing-and-bmesh and building on the linear-blend-skinning precedent of armature-bend.

Every rigid part (armor, motors, cheeks, piston, gripper) is weighted 1.0 to one bone. The two cable runs along the arm's back are the flex parts: they hand over smoothly from bone to bone across each joint and carry the tail an auto-weighting pass leaves behind — a small, distance-ranked spill onto all five bones. That tail is the five-influence authoring the limit prunes.

Pipeline arc: modeling/LOD in lod-decimate-chain, weighting here, export in gltf-export-roundtrip.

What it witnesses: the skinning constraint every game engine enforces and AI-generated rigging code most often violates silently.

The vertex-group API (v.groups, VertexGroup.add/remove) is stable between Blender 4.5 LTS and 5.2 — the example runs identically on 4.5, 5.1 and 5.2, which is itself the version witness (measured values match to the digit).

What the render shows#

The render path paints the post-limit weights onto the arm as a BoneBlend colour attribute — Σ wᵢ · colourᵢ per vertex, read back from v.groups after the prune — and the cables, side hatches and trim bands display it through a matte Attribute-node material. Each rigid segment therefore shows its bone's flat colour (blue turret, teal upper arm, violet forearm, magenta wrist, lime gripper), and the cables grade from colour to colour exactly where the skin weights blend across each joint, while the posed arm shows those weights deforming it.

Numeric-only contract (docs/VISUAL-STYLE.md § The render is the proof): the four-influence cap itself has no visual signature. The pruned fifth weight is the small spill (at most 0.0027 on any vertex), so a five-influence arm deforms and paints indistinguishably — the prune preserves the pose by design, and that is what check 3 asserts. The render depicts the subject and where its weights blend; the cap is witnessed by the numbers above and by the --skip-limit falsifier.

Run#

# Cheap correctness check (no render) — the CI check:
blender --background --python vertex_weight_limit.py --

# Falsifier: skip the 4-influence prune. Must exit non-zero.
blender --background --python vertex_weight_limit.py -- --skip-limit

# Also render a still (EEVEE on a GPU host; use --engine cycles on GPU-less hosts):
blender --background --python vertex_weight_limit.py -- --output arm.png
blender --background --python vertex_weight_limit.py -- --output arm.png --engine cycles

Exit codes#

Per-script sequential checks. 9 is a valid check code; there is no rule against it. 10 is the shared framing helper; it is also the missing-render code. 11 is the shared asset-quality helper.

CodeMeaning
0Success
1Uncaught exception (FATAL wrapper)
2argparse / usage
3Pre-limit max influences ≠ 5
4Vertex over the 4-influence cap (--skip-limit lands here)
5Limit changed nothing
6Weight sums off 1.0 after renormalize
7Pose damaged by pruning, or evaluated vert count changed
8Evaluated mesh off LBS over limited weights
9Root-weighted mount moved
10Gallery framing violation (--output only; gallery_framing)
11Asset-quality floor violation (--output only)
12--output produced no file

The blender-smoke workflow runs the check on Blender 5.2 LTS and 4.5 LTS (5.1 on the weekly cron, the needs-5.1 PR label, or manual dispatch). Smoke does not pass --output. Its catalog falsifier is --skip-limit (expects exit 4).

Source

examples/vertex-weight-limit/vertex_weight_limit.py View the script on GitHub →
An orange industrial robot arm reaching down with a two-jaw gripper, each segment glowing in its bone colour and the cables on its back grading from colour to colour across each joint.