Python CLI for converting a 3D model to LDraw.
Project description
legolization
Turn a colored voxel model into a physically buildable LEGO model in LDraw format, with step-by-step build instructions.
This is the classic "LEGO construction problem" from the research literature
(see references/): voxelize → hollow → place bricks → check structural
stability → refine → export. The stability check is a full
Rigid-Block-Equilibrium (RBE) model (StableLego / BrickGPT formulation):
per-brick force and torque balance with knob-friction capacities, solved as
a linear program on an open solver stack — no Gurobi required.
What it does
- Input: a MagicaVoxel
.voxfile or a numpy.npyarray (LDraw colour codes or RGB(A) voxels — colours are quantized to the nearest solid LDraw colour). - Placement: covers every voxel with real parts — bricks, plates, tiles,
and 45°/33° slopes — using true heights (plate = 8 LDU, brick = 24 LDU) and
a pluggable strategy:
greedy(default): largest-first bottom-up fill with stretcher-bond scoring, then delete-and-rebuild reinforcement around the physically weakest bricks.luo: Luo et al. (2015) maximal random merge with split-and-remerge refinement for connectivity and stability.
- Physics: every candidate layout is scored by the RBE — gravity, support, press, drag/pull friction (capacity T = 0.98 N per contact point), and knob/side press forces, with equilibrium residuals in the objective so even collapsing structures solve and the failure localizes to specific bricks.
- Auto-hollow: interiors are hollowed to a shell, but fill is restored wherever the physics says the shell would collapse.
- Output: a valid
.ldror.mpdwith bottom-up0 STEPbuild instructions, written through pyldraw3. Open it in LDView or BrickLink Studio.
Setup
uv sync
uv run ldraw download # once: fetch the LDraw parts library
uv run ldraw generate # once: generate ldraw.library.* part/colour modules
Usage
uv run legolization data/examples/heart.vox -o heart.ldr
uv run legolization model.npy --strategy luo --solid --seed 7
uv run legolization model.vox --slopes --tiles # surface finishing passes
uv run legolization model.vox --milp # exact complementarity physics
The CLI reports brick count, mass, and the physics verdict:
wrote heart.ldr
bricks: 31 mass: 18.1 g slopes: 0 tiles: 0
stability: STABLE (worst score 0.000, min capacity 0.980 N)
Exit code 0 means the model is stable, single-component, and ground-connected;
2 means it is not buildable as-is (try --strategy luo, --solid, or a
different --seed).
Python API:
from pathlib import Path
from legolization import PipelineConfig, VoxelGrid, run, run_file
result = run_file(Path("model.vox"), Path("model.ldr"), PipelineConfig(seed=1))
print(result.buildable, result.stability.max_score)
How the stability model works
Each mated stud contributes 3 or 4 contact points (per StableLego's measured
geometry) carrying a shared normal force and a friction (drag/pull) force, so
Newton's third law holds by construction; each knob adds four horizontal
knob-press forces and laterally touching bricks exchange side presses. Per
brick, five equilibrium residuals (3 forces, 2 torques about the mass centroid)
are minimized rather than constrained. A brick scores 1 when it cannot reach
equilibrium or its friction demand exceeds T; otherwise drag_max / T — so the
score doubles as a stress heatmap. The default solver is a hand-assembled LP
on scipy/HiGHS (fast enough to sit inside refinement loops); --milp adds
big-M complementarity (a contact point cannot press and pull at once) via
cvxpy for final verification.
Development
uv run pytest # analytic physics cases, placement invariants, round-trips
uv run ruff format --check . && uv run ruff check .
uv run ty check src tests
uv run pyrefly check src tests
License
GPL-3.0-or-later (inherited from pyldraw3).
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file legolization-0.1.0.tar.gz.
File metadata
- Download URL: legolization-0.1.0.tar.gz
- Upload date:
- Size: 33.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3cb0d2efb1d6191975816b94c76db995da740e60cbe4be802d8228b2fdf5b18f
|
|
| MD5 |
ff0377b43f9664c5689c9dc4b7fb0a3d
|
|
| BLAKE2b-256 |
ab6ea97d214d344c19fd7008f46b75336fa4bcff12fa179c3e3b5f6b4caef8df
|
Provenance
The following attestation bundles were made for legolization-0.1.0.tar.gz:
Publisher:
publish.yml on hbmartin/legolization
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
legolization-0.1.0.tar.gz -
Subject digest:
3cb0d2efb1d6191975816b94c76db995da740e60cbe4be802d8228b2fdf5b18f - Sigstore transparency entry: 2133435653
- Sigstore integration time:
-
Permalink:
hbmartin/legolization@6d98c83fea9e4cc3a900e861c0d2dedc1c14d9d6 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/hbmartin
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@6d98c83fea9e4cc3a900e861c0d2dedc1c14d9d6 -
Trigger Event:
release
-
Statement type:
File details
Details for the file legolization-0.1.0-py3-none-any.whl.
File metadata
- Download URL: legolization-0.1.0-py3-none-any.whl
- Upload date:
- Size: 44.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
09aade8f2f8f618bed8059fcf429dcee313d8ea508b6a12abcf3c350387acad1
|
|
| MD5 |
bd25d712bb29a45606e2238b45dd2586
|
|
| BLAKE2b-256 |
76214c5c37d0219175aa59d74cc81ffa734fa98a147a5eb8ee93fdfaf4b20c59
|
Provenance
The following attestation bundles were made for legolization-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on hbmartin/legolization
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
legolization-0.1.0-py3-none-any.whl -
Subject digest:
09aade8f2f8f618bed8059fcf429dcee313d8ea508b6a12abcf3c350387acad1 - Sigstore transparency entry: 2133435775
- Sigstore integration time:
-
Permalink:
hbmartin/legolization@6d98c83fea9e4cc3a900e861c0d2dedc1c14d9d6 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/hbmartin
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@6d98c83fea9e4cc3a900e861c0d2dedc1c14d9d6 -
Trigger Event:
release
-
Statement type: