Prop Origin Transform

examples/prop-origin-transform/

Street pedestal origin-to-base-center + data-API scale apply + matrix_parent_inverse for a flanged conduit elbow. After bake: scale (1,1,1), local min.z==0, world AABB unchanged. Bare parent throws the elbow off its mount; MPI keeps it seated.

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

witnesses Bare child.parent = parent teleports accessories off their mounts; skipping view_layer.update() before matrix_world, or leaving non-uniform scale / centered origin, breaks engine ingest placement.

tags transforms parenting game-pipeline

runs on 4.5 LTS · 5.1 · 5.2 LTS

blender --background --python examples/prop-origin-transform/prop_origin_transform.py --

falsify it Breaks the contract on purpose and must exit 8

blender --background --python examples/prop-origin-transform/prop_origin_transform.py -- --skip-mpi

A runnable example that builds a street utility pedestal with a flanged conduit elbow and proves the origin / scale-apply / MPI contract a prop pipeline relies on before engine ingest — following operators and the data-API parenting idiom from parent-inverse-orrery.

Pipeline arc neighbors: MPI + stale matrix_world in parent-inverse-orrery, export origin sensitivity in gltf-export-roundtrip, collision bounds in collision-hull-proxy, and mesh hygiene in mesh-hygiene-audit. Origin at the base center with applied scale is what placement and physics ingest assume.

Scope: this witnesses the bpy-level contract a prop pipeline relies on (post-bake scale exactly (1,1,1), local bbox min.z == 0, world bbox unchanged, MPI so a parented accessory does not teleport). It is not an engine exporter — it proves the transform properties such an asset must have.

What it witnesses:

What each check catches on failure: skipping scale apply leaves (1.15, 0.92, 1.08) (exit 5); skipping the origin bake leaves min.z = -0.58 (exit 6); skipping MPI leaves the accessory 0.298 m off (exit 8).

Version witness: identical numbers on Blender 5.2.1 LTS, 5.1.2 and 4.5.11 LTS.

The asset. The pedestal is one mesh with five materials: a precast concrete footing, a galvanised base plate with anchor nuts, a green cabinet on a black kick skirt, a hipped lid, a door with hinges, a T-handle and a hazard plate, louvred side vents, a conduit boss on the +X face and a sleeve in the pad. It is authored the way an import often arrives: origin at the geometric centre and coordinates divided by a non-uniform object scale. The bake lands it on exactly the designed shape. The accessory is a flanged PVC conduit elbow with bolt heads, a strap clamp and a coupling that drops into the sleeve.

The render. Two baked pedestals stand on a sidewalk slab. On the left the elbow is parented with MPI and stays bolted to its boss, seated in the sleeve. On the right, bare child.parent = parent applies the pedestal's transform a second time. The elbow is thrown 0.65 m, past the slab edge and into the air, and a glowing cyan outline (a Wireframe modifier on a copy) marks the seat it left. The slab raises both origins 0.20 m, so the doubled translation lifts the elbow instead of sliding it along the floor. A pivot ring on the floor is centred on each pedestal's origin, with red notches on its X axis and green notches on Y. The origin is under the base, so the ring frames it. There are no text labels: the ghost and the stranded elbow carry the proof. The check's closed forms are unchanged.

Run#

blender --background --python prop_origin_transform.py --
blender --background --python prop_origin_transform.py -- --skip-mpi
blender --background --python prop_origin_transform.py -- --output origin.png
blender --background --python prop_origin_transform.py -- --output origin.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.

CodeMeaning
0Success
1Uncaught exception (FATAL wrapper)
2argparse / usage
3Stale matrix_world contract broken
4World bbox moved across bake
5Scale after bake is not (1,1,1)
6Origin not at local base center
7Bare parenting did not jump
8MPI did not restore world location (--skip-mpi lands here)
9--output produced no file
10Gallery framing violation
11Gallery asset-quality violation (render path only)

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-mpi (expects exit 8).

Source

examples/prop-origin-transform/prop_origin_transform.py View the script on GitHub →
Two green street utility pedestals in floor pivot rings: the left one keeps its orange conduit elbow bolted on, the right one's elbow hangs in the air beside a glowing cyan outline of its seat.