CLI Reference¶
The ldraw executable downloads LDraw libraries, generates importable Python
modules, queries parts, validates and inspects model files, renders standard
preview views, exports bills of materials, and produces renderer-neutral
instruction data.
usage: ldraw [-h] command ...
Manage LDraw libraries and create, inspect, validate, and render LDraw models.
positional arguments:
command
download Download and unpack an LDraw parts library release.
generate Generate the ldraw.library modules from the downloaded library.
parts Query the parts catalog.
validate Validate an LDraw file (.ldr, .mpd, or .dat).
bom Print a bill of materials for an LDraw model file.
inspect Inspect exact world bounds, provenance, contacts, and gaps.
render Render a deterministic set of standard preview views.
stubs Write a type-stub package for ldraw.library into your project.
instructions
Inspect, validate, and export renderer-neutral instructions.
config Print the current configuration.
version Print the installed pyldraw3 version.
options:
-h, --help show this help message and exit
Commands¶
ldraw download [--version VERSION] [--yes]downloads and unpacks an LDraw release. The default version iscomplete.ldraw generate [--yes] [--force]regeneratesldraw.library.*from the currently configured release.--forceregenerates even when already up to date.ldraw parts search TERM [--limit N]searches the catalog across part codes, descriptions, categories, and keywords. Every whitespace-separated token inTERMmust match (case-insensitive), and results are ranked by relevance. It exits with code 1 when nothing matches.ldraw parts info CODEshows a part's description, category, file path, and the generated-library import to use.ldraw parts geometry CODE [--format table|json]expands the part's drawable subfile tree and reports exact local bounds, points, connectors, completeness, and structured diagnostics.ldraw validate FILE [--strict]lints.ldr,.mpd, and.datfiles. Malformed lines, unknown parts, and unknown colour codes are errors. Suspect matrices, legacy dithered colours, and unknown meta-commands are warnings.--strictmakes warnings fail.ldraw bom FILE [--format table|csv|json] [-o OUT]prints a bill of materials counted by part and colour, with submodels expanded.ldraw inspect FILE [--format table|json] [--gap-threshold LDU] [--chronological] [--page-marker-prefix TEXT] [-o OUT]reports exact transformed occurrence geometry, provenance, stud contacts, nearest AABB gaps, skipped geometry, and structured diagnostics.ldraw render FILE [--view front|isometric|top] [--size WIDTHxHEIGHT] [--backend auto|ldview|leocad] [--output-dir DIR] [--prefix NAME] [--refresh] [--overwrite]renders a safely staged standard-view set.ldraw stubs [--out PATH]writes anldraw-stubs/PEP 561 stub package for IDE autocompletion of generatedldraw.library.*imports.ldraw instructions inspect FILE [--section NAME] [--parts]prints one row per section-local step.--partsadds each step's parts tray.ldraw instructions validate FILE [--strict] [--max-parts N]runs both the ordinary LDraw linter and semantic instruction validation.ldraw instructions export FILE [-o MANIFEST] [--force]writes manifest schema v1 to stdout or a file.ldraw instructions snapshots FILE --out DIR [--section NAME] [--force]writes cumulative MPD and flattened LDR files plusinstructions.json.ldraw configprints the current configuration as YAML.ldraw versionprints the installedpyldraw3version.
Run ldraw <command> --help for a command's full option list.
Geometry and model inspection¶
parts geometry returns useful partial geometry when a part references a
missing or unreadable child. Table output labels the result incomplete; JSON
adds complete and serialized diagnostics alongside the original bounds,
point, and stud fields. An unavailable library or unknown root part exits 1,
while reportable incomplete geometry exits 0.
inspect loads models tolerantly and preserves valid occurrences around
malformed lines. Its table and JSON reports include root-to-leaf model,
reference, source-line, step, and attributed-page paths; exact world bounds;
skipped geometry; stud contacts; and nearest AABB gaps. The default page
marker is 0 // PDF_PAGE NNN, controlled by --page-marker-prefix.
ldraw parts geometry 3001 --format json
ldraw inspect model.mpd --chronological --gap-threshold 5 -o inspection.txt
ldraw inspect model.mpd --ldcad-shadow shadow.csl --studio-metadata studio.json
When a partial inspection contains error diagnostics the report is still written, but the command exits 1. Warnings alone exit 0. Missing or undecodable files that cannot produce a model are diagnosed on stderr and also exit 1.
Both parts geometry and inspect accept repeatable --ldcad-shadow PATH
and --studio-metadata PATH. Their JSON reports include metadata coverage,
stable world-space feature IDs and structured provenance. Model inspection
also includes contact status/residual evidence and confirmed/optimistic
parallel graph edges; unresolved occurrences remain graph nodes.
Rendering previews¶
render uses the same optional, cached preview boundary as render_preview().
With no --view, it renders front, isometric, and top at 800x600.
Repeat --view to choose an ordered subset. --backend auto prefers the first
available current backend; an explicit ldview or leocad fails if that
backend is unavailable. --refresh bypasses cache reads.
Outputs are named PREFIX.VIEW.png, using the model stem as the default
prefix. Every requested view is first completed in destination-local temporary
storage. Final files are promoted only after all views succeed, and existing
files are restored if promotion fails. Existing outputs are rejected before
rendering unless --overwrite is supplied.
$ ldraw render model.mpd --view front --view top --output-dir renders
RENDERED: /work/renders/model.front.png
RENDERED: /work/renders/model.top.png
Validating files¶
ldraw validate FILE lints a single .ldr, .mpd, or .dat file line by
line and reports every problem it finds with the file name and 1-based line
number. It parses each line, checks part references and colours against the
catalog, and inspects transformation matrices and meta-commands.
If no parts library has been downloaded and generated yet, validation still runs but skips the checks that need the catalog (unknown parts and unknown colour codes). It prints a note when it does so:
Severity levels¶
Issues come in two severities:
error— the line is malformed or references something that does not exist. Errors always makeldraw validateexit non-zero.warning— the line is legal LDraw but suspicious. Warnings are reported but do not fail the command by default. Pass--strictto make warnings fail as well.
What is checked¶
Errors
| Issue | Meaning |
|---|---|
| malformed / unparseable line | The line does not parse as valid LDraw (bad token count, non-numeric coordinates, etc.). |
invalid colour value |
A colour that resolves to neither a code nor an RGB value. |
unknown colour code N |
A colour code with no definition in the loaded catalog. |
unknown part CODE |
A type-1 reference to a part that is not in the catalog and is not a submodel defined inside the file. |
Warnings
| Issue | Meaning |
|---|---|
legacy dithered colour code N |
A colour in the legacy dithered range 256–511. |
singular transformation matrix (flattens geometry) |
The part's matrix collapses it to zero volume. |
transformation matrix is not orthonormal (scaled or sheared part) |
The matrix scales or shears rather than only rotating. |
unknown meta-command !NAME |
A 0 !NAME ... bang meta-command that is not one of the recognised LDraw/editor commands. Plain 0 STEP-style comments are not checked. |
MPD submodels are resolved from their 0 FILE sections, so references to
sections defined inside the same file are not flagged as unknown parts.
Example output¶
A file with one bad part reference and one suspect matrix:
$ ldraw validate castle.ldr
castle.ldr:12: error: unknown part 9999
castle.ldr:47: warning: singular transformation matrix (flattens geometry)
castle.ldr: 1 error(s), 1 warning(s)
A clean file prints a single OK line and exits 0:
Making warnings fail with --strict:
$ ldraw validate castle.ldr --strict
castle.ldr:47: warning: singular transformation matrix (flattens geometry)
castle.ldr: 0 error(s), 1 warning(s)
$ echo $?
1
Exit codes¶
0— no issues, or only warnings without--strict.1— one or more errors, any warning when--strictis set, or the file does not exist.
Programmatic API¶
The same checks are available in Python through iter_ldr_issues, which
yields ValidationIssue records (line_number, message, severity) so
you can build your own tooling, editor integrations, or CI gates:
from pathlib import Path
from ldraw import iter_ldr_issues
from ldraw.validation import Severity
from ldraw.parts import Parts
parts = Parts.get("~/ldraw/parts.lst") # optional; enables catalog checks
issues = list(iter_ldr_issues(Path("castle.ldr"), parts))
errors = [i for i in issues if i.severity is Severity.ERROR]
for issue in issues:
print(f"{issue.line_number}: {issue.severity}: {issue.message}")
Passing parts=None (or omitting it) runs the parse, matrix, and
meta-command checks but skips the unknown-part and unknown-colour checks,
mirroring the CLI's behaviour when no library is available.
Instruction commands¶
All four ldraw instructions commands require the configured parts catalog,
because counts, descriptions, colours, and geometry bounds must be
deterministic. If it is unavailable they print the existing ldraw download
installation hint and exit 1.
inspect reports direct placements, expanded additions, cumulative leaf
counts, ROTSTEP, camera, callout/multi-step, page-break, and suppression state.
Section selection is case-insensitive:
$ ldraw instructions inspect model.mpd --section module.ldr --parts
section step direct expanded cumulative rotation camera callouts group page suppressed
module.ldr 1 2 2 2 - - 0 - - -
qty part colour description
2 3001 Red Brick 2 x 4
validate emits instruction diagnostics with section and source-line context.
Errors always fail. Warnings (including missing explicit boundaries, orphan
sections, and --max-parts overflow) fail only with --strict.
Manifest schema v1 is snake_case and contains root-first reachable sections, source provenance, direct and expanded additions, cumulative count/BOM/bounds, ROTSTEP and LPub camera state, directives, callouts/groups, and suppression or page-break flags. Cumulative occurrences are deliberately represented only by aggregates so manifests do not grow quadratically.
snapshots writes this layout by default:
output/
instructions.json
001-main/
step-0001.mpd
step-0001.ldr
002-module/
step-0001.mpd
step-0001.ldr
MPDs preserve submodel references and include the transitive dependency
closure. LDRs flatten .ldr submodels into section-local coordinates, retain
.dat references, and write embedded .dat definitions as safe relative
sidecars. Instruction directives live in the manifest rather than snapshot
geometry. Suppressed steps still receive artifacts; page breaks do not create
steps.
Without --force, any collision fails. Forced regeneration trusts only paths
listed in an existing pyldraw3-owned manifest, removes stale owned paths, and
never deletes or overwrites unrelated files. Output is staged beside the
destination before commit. These commands create data for renderers; they do
not generate PDF, image, HTML, typography, or page layout.
Development Commands¶
This project uses uv for dependency management and packaging.
Run tests and checks:
uv run pytest
uv run pytest --cov=ldraw
uv run pytest --integration
uv run ruff format .
uv run ruff check .
uv build
Build and preview documentation:
GitHub Pages must use the "GitHub Actions" publishing source. If the
repository remains configured to publish from a branch such as gh-pages, the
live site will continue to serve that branch instead of this workflow's
Zensical artifact.