Metadata-Version: 2.3
Name: pyldraw3
Version: 0.12.0
Summary: Python wrapper for LDraw library.
Keywords: ldraw,lego,cad,3d,modeling,parts,bricks
Author: David Boddie, Matthieu Berthomé, Harold Martin
Author-email: David Boddie <david@boddie.org.uk>, Matthieu Berthomé <rienafairefr@gmail.com>, Harold Martin <harold.martin@gmail.com>
License: GPL-3.0-or-later
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: End Users/Desktop
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Artistic Software
Classifier: Topic :: Multimedia :: Graphics :: 3D Modeling
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Dist: platformdirs>=4.3.8
Requires-Dist: pystache>=0.6.0
Requires-Dist: progress>=1.6.1
Requires-Dist: requests>=2.32.4
Requires-Dist: inflect>=7.5.0
Requires-Dist: numpy>=2.0
Requires-Dist: pyyaml>=6.0.1
Requires-Python: >=3.12
Project-URL: Changelog, https://github.com/hbmartin/pyldraw3/releases
Project-URL: Documentation, https://github.com/hbmartin/pyldraw3/blob/main/GUIDE.md
Project-URL: Homepage, https://github.com/hbmartin/pyldraw3
Project-URL: Repository, https://github.com/hbmartin/pyldraw3
Description-Content-Type: text/markdown

# pyldraw3

[![PyPI](https://img.shields.io/pypi/v/pyldraw3.svg)](https://pypi.org/project/pyldraw3/)
[![Lint and Test](https://github.com/hbmartin/pyldraw3/actions/workflows/lint-test.yml/badge.svg)](https://github.com/hbmartin/pyldraw3/actions/workflows/lint-test.yml)
[![Coverage Status](https://coveralls.io/repos/github/hbmartin/pyldraw3/badge.svg?branch=main)](https://coveralls.io/github/hbmartin/pyldraw3?branch=main)
[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
[![Code style: black](https://img.shields.io/badge/🐧️-black-000000.svg)](https://github.com/psf/black)

A modern Python package for creating and manipulating LDraw format files - the standard for CAD applications that create LEGO models. It is a drop-in replacement for the unmaintained `pyldraw` library.

## Features

- 🧱 **Complete LDraw Support**: Full compatibility with the LDraw standard format
- 🐍 **Pythonic API**: Import LEGO parts directly as Python modules
- 📦 **Dynamic Library Generation**: Automatically generate Python modules from LDraw libraries
- 📜 **Comprehensive Guide**: Jump into example or the quick start below, or read a [detailed usage guide](GUIDE.md)

## Table of Contents

- [Features](#features)
- [Quick Start](#quick-start)
  - [Installation](#installation)
  - [Setup](#setup)
  - [Examples](#examples)
  - [Basic Usage](#basic-usage)
- [Requirements](#requirements)
- [Configuration](#configuration)
- [CLI Reference](#cli-reference)
- [Development](#development)
  - [Setup Development Environment](#setup-development-environment)
  - [Development Commands](#development-commands)
- [Architecture](#architecture)
  - [Core Components](#core-components)
  - [Key Classes](#key-classes)
- [Contributing](#contributing)
- [License](#license)
- [Trademarks](#trademarks)
- [Credits](#credits)


## Quick Start

### Installation

```bash
uv add pyldraw3
```

### Setup

Activate your virtual environment and set up the LDraw library - this will download the LDraw library and create the parts classes:

```bash
source .venv/bin/activate
ldraw download --yes
ldraw generate --yes
```

By default `ldraw download` fetches the `complete` LDraw release (~80 MB, everything LDraw publishes). To pin a specific dated release instead - useful for reproducible builds or a smaller download - pass `--version`, e.g. `ldraw download --version 2018-02 --yes`. Each downloaded release is cached separately, and `ldraw generate` builds `ldraw.library.*` from whichever release is currently configured (see [Configuration](#configuration)).

### Examples

Check the `examples/` directory for sample scripts demonstrating various features:

```bash
# Run an example
python examples/figures.py > my_model.ldr
```

### Basic Usage

This package allows users to create LDraw scene descriptions using `Piece`s which are `Part`s that have a specific position and orientation. `Piece.to_ldraw()` and `Group.to_ldraw()` produce LDraw file content; `str(piece)` and `str(group)` delegate to those serializers:

```python
from ldraw.library.colours import Light_Grey
from ldraw.library.parts.bricks import Brick1X2WithClassicSpaceLogoPattern
from ldraw.pieces import Group, Piece
from ldraw.geometry import Vector, Identity

# Create a simple model
model = Group()
Piece(Light_Grey, Vector(-10, -32, -90), Identity(), Brick1X2WithClassicSpaceLogoPattern, model)

with open("my_model.ldr", "w") as ldr_file:
    print(model, file=ldr_file)
```

`ldraw.library.*` is generated by `ldraw generate` and gives you every part as an importable, autocompletable Python name (as used above). If you'd rather look a part up by its catalog description or LDraw code at runtime - for example when the part name isn't known until your program runs - load the parts catalog directly instead:

```python
from pathlib import Path

from ldraw.config import Config
from ldraw.parts import Parts

config = Config.load()
parts = Parts(Path(config.ldraw_library_path) / "ldraw" / "parts.lst")
cowboy_hat = parts.get_entry_by_description("Hat Cowboy").code  # -> "3629"
head = parts.get_entry_by_description("Head with Solid Stud").code  # -> "3626a"
brick1x1 = parts.get_entry_by_description("Brick  1 x  1").code  # -> "3005"
```

Both `cowboy_hat` and `Brick1X2WithClassicSpaceLogoPattern` are just LDraw part code strings, so either style can be passed as the `part` argument to `Piece`.

## Requirements

- Python 3.12+

## Configuration

`ldraw download` and `ldraw generate` write their settings to a YAML config file in an OS-appropriate config directory (via [`platformdirs`](https://pypi.org/project/platformdirs/)). Run `ldraw config` to see the current values:

```bash
$ ldraw config
generated_path: /Users/you/Library/Application Support/pyldraw3/generated
ldraw_library_path: /Users/you/Library/Caches/pyldraw3/2018-02
```

- `ldraw_library_path` - the downloaded LDraw release currently in use (switch releases by re-running `ldraw download --version ...`)
- `generated_path` - where `ldraw generate` writes the `ldraw.library.*` package that you `import`

## CLI Reference

```
usage: ldraw [-h] command ...

Download the LDraw parts library and generate the ldraw.library Python
modules.

positional arguments:
  command
    download  Download and unpack an LDraw parts library release.
    generate  Generate the ldraw.library modules from the downloaded library.
    config    Print the current configuration.
    version   Print the installed pyldraw3 version.

options:
  -h, --help  show this help message and exit
```

- `ldraw download [--version VERSION] [--yes]` - download and unpack an LDraw release (default version: `complete`)
- `ldraw generate [--yes] [--force]` - (re)generate `ldraw.library.*` from the currently configured release; `--force` regenerates even if already up to date
- `ldraw config` - print the current configuration as YAML
- `ldraw version` - print the installed `pyldraw3` version

Run `ldraw <command> --help` for a command's full option list.

## Development

This project uses [uv](https://docs.astral.sh/uv/) for dependency management and packaging.

### Setup Development Environment

```bash
# Clone the repository
git clone https://github.com/hbmartin/pyldraw3.git
cd pyldraw3

# Install dependencies
uv sync

# Activate virtual environment
source .venv/bin/activate

# Download and set up LDraw library
uv run ldraw download --version 2018-02 --yes
uv run ldraw generate --yes
```

### Development Commands

```bash
# Run tests
uv run pytest                 # All tests
uv run pytest --cov=ldraw     # With coverage
uv run pytest --integration   # Integration tests only

# Code formatting and linting
uv run black .               # Format code
uv run ruff check            # Lint code
uv run ruff check --fix      # Fix linting issues

# Build package
uv build
```

## Architecture

### Core Components

- **CLI Interface** (`ldraw/cli.py`): Command-line interface with `download`, `generate`, `config`, and `version` subcommands
- **Dynamic Library Generation** (`ldraw/generation/`): Converts LDraw libraries to Python modules
- **Import System** (`ldraw/imports.py`): Custom meta path hook for dynamic imports

### Key Classes

- `Parts` - Manages parts catalog and loading
- `Piece` - Represents individual LEGO pieces in models  
- `Figure` - High-level minifigure construction
- Geometry classes - Matrix operations and 3D mathematics

## Contributing

Contributions are welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for the fork/branch/PR workflow.

## License

This project is licensed under the GNU General Public License v3.0 or later - see the [license (COPYING)](COPYING) file for details.

```
pyldraw, a Python package for creating LDraw format files.
Copyright (C) 2008 David Boddie <david@boddie.org.uk>
Some parts Copyright (C) 2021 Matthieu Berthomé <matthieu@mmea.fr>
Some parts Copyright (C) 2025 Harold Martin <harold.martin@gmail.com>
```

## Trademarks

LDraw is a trademark of the Estate of James Jessiman. LEGO is a registered trademark of the LEGO Group.

## Credits

- **Original Author**: [David Boddie](mailto:david@boddie.org.uk)
- **Previous Maintainer**: [Matthieu Berthomé](mailto:matthieu@mmea.fr)
- **Current Maintainer**: [Harold Martin](mailto:harold.martin@gmail.com)

This repository was extracted from the original Mercurial repository and modernized for current Python practices.
