brickagent 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. brickagent-0.1.0/.gitignore +4 -0
  2. brickagent-0.1.0/LICENSE +21 -0
  3. brickagent-0.1.0/PKG-INFO +176 -0
  4. brickagent-0.1.0/README.md +159 -0
  5. brickagent-0.1.0/pyproject.toml +34 -0
  6. brickagent-0.1.0/src/brickagent/__init__.py +46 -0
  7. brickagent-0.1.0/src/brickagent/_data/v1/bounds.json.xz +0 -0
  8. brickagent-0.1.0/src/brickagent/_data/v1/colors.json +2795 -0
  9. brickagent-0.1.0/src/brickagent/_data/v1/ids.json.xz +0 -0
  10. brickagent-0.1.0/src/brickagent/_data/v1/keywords.json.xz +0 -0
  11. brickagent-0.1.0/src/brickagent/_data/v1/mirrors.json.xz +0 -0
  12. brickagent-0.1.0/src/brickagent/_data/v1/seating.json.xz +0 -0
  13. brickagent-0.1.0/src/brickagent/catalog.py +119 -0
  14. brickagent-0.1.0/src/brickagent/check.py +148 -0
  15. brickagent-0.1.0/src/brickagent/export.py +60 -0
  16. brickagent-0.1.0/src/brickagent/joints.py +223 -0
  17. brickagent-0.1.0/src/brickagent/model.py +304 -0
  18. brickagent-0.1.0/src/brickagent/physics.py +225 -0
  19. brickagent-0.1.0/src/brickagent/pose.py +84 -0
  20. brickagent-0.1.0/src/brickagent/reflection.py +56 -0
  21. brickagent-0.1.0/src/brickagent/search.py +88 -0
  22. brickagent-0.1.0/src/brickagent/view.py +42 -0
  23. brickagent-0.1.0/src/brickagent/viewer/LDrawLoader.js +2538 -0
  24. brickagent-0.1.0/src/brickagent/viewer/README.md +63 -0
  25. brickagent-0.1.0/src/brickagent/viewer/index.html +43 -0
  26. brickagent-0.1.0/src/brickagent/viewer/package-lock.json +119 -0
  27. brickagent-0.1.0/src/brickagent/viewer/package.json +13 -0
  28. brickagent-0.1.0/src/brickagent/viewer/view.mjs +43 -0
  29. brickagent-0.1.0/src/brickagent/viewer/viewer.js +302 -0
@@ -0,0 +1,4 @@
1
+ __pycache__/
2
+ *.egg-info/
3
+ dist/
4
+ node_modules/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Peter Kulits
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,176 @@
1
+ Metadata-Version: 2.5
2
+ Name: brickagent
3
+ Version: 0.1.0
4
+ Summary: Programmatic LEGO design
5
+ Project-URL: Paper, https://brickben.ch
6
+ Author: Peter Kulits
7
+ License-Expression: MIT
8
+ License-File: LICENSE
9
+ Classifier: Operating System :: OS Independent
10
+ Classifier: Programming Language :: Python :: 3
11
+ Requires-Python: >=3.10
12
+ Requires-Dist: bricknet>=0.1.1
13
+ Requires-Dist: numpy
14
+ Requires-Dist: pybullet
15
+ Requires-Dist: scipy
16
+ Description-Content-Type: text/markdown
17
+
18
+ <div align="center">
19
+
20
+ # BrickAgent: Programmatic LEGO Design
21
+ [Peter Kulits](https://kulits.github.io/)&nbsp;&nbsp;&nbsp;&nbsp;[Yiqing Xu](https://eeching.github.io/)&nbsp;&nbsp;&nbsp;&nbsp;[R. Kenny Jones](https://rkjones4.github.io/)&nbsp;&nbsp;&nbsp;&nbsp;[Cordelia Schmid](https://cordeliaschmid.github.io/)&nbsp;&nbsp;&nbsp;&nbsp;[Jiajun Wu](https://jiajunwu.com/)
22
+
23
+ [\[Project Page\]](https://brickben.ch) | [\[Gallery\]](https://gallery.brickben.ch)
24
+
25
+ <img src="https://raw.githubusercontent.com/kulits/BrickAgent/master/docs/images/teaser_mosaic.avif" alt="BrickBench teaser" width="800">
26
+
27
+ </div>
28
+
29
+ BrickAgent is the environment of BrickBench, a benchmark for agentic text-conditioned LEGO-set design. Coding agents
30
+ use it to programmatically construct, inspect, and validate LEGO assemblies, placing parts through the connector system
31
+ of [BrickNet](https://github.com/kulits/BrickNet).
32
+
33
+ This repository contains:
34
+ - **`brickagent`** (`src/brickagent/`), the environment, on PyPI.
35
+ - **BrickBench**: 300 task prompts (`benchmark/`), the agent prompt, validator, and evaluation (`scripts/`), and the
36
+ agent container (`Dockerfile`).
37
+
38
+ ## Install
39
+ ```bash
40
+ pip install brickagent
41
+ python -m bricknet fetch-meshes
42
+ ```
43
+
44
+ `fetch-meshes` downloads BrickNet's convex colliders (1 GB), which collision and stability checks need, into the
45
+ platform user-data directory; to use another location, export `BRICKNET_DATA` before fetching and keep it set.
46
+
47
+ ## Usage
48
+ ```python
49
+ from brickagent import Assembly
50
+
51
+ wall = Assembly("wall")
52
+ base = wall.add("plate 2x8", color="dark gray")
53
+ top = base.stud
54
+ for course in range(4):
55
+ next_top, column = [], 0
56
+ for width in (4, 4) if course % 2 == 0 else (2, 4, 2):
57
+ brick = wall.attach(f"brick 2x{width}", to=top[2 * column], by=("hole", 0), color="tan")
58
+ next_top.extend(brick.stud)
59
+ column += width
60
+ top = next_top
61
+ wall.write("wall.mpd", check=True)
62
+ ```
63
+
64
+ `add` places a part or subassembly at a pose; `attach` places it by an exact connector fit. Connectors are indexed in
65
+ BrickNet order (`part.stud[i]`, `part.hole[i]`, ...).
66
+
67
+ ```python
68
+ # continues the example above
69
+ from brickagent import find, describe, name, connectors, check, view
70
+
71
+ beams = [stem for stem in find("technic beam") if len(connectors(stem, "socket")) == 5]
72
+ print(beams[0], name(beams[0]))
73
+ print(describe("6629"))
74
+ check(wall)
75
+ view(wall, "wall.png") # needs the Rendering setup below
76
+ ```
77
+
78
+ `check` raises `ValueError` on collisions, inexact connections, exceeded inventory, or instability, naming the parts
79
+ involved. Each connected component is simulated as a rigid body under gravity in PyBullet. Only parts that BrickNet
80
+ supports can be used; `find` lists them. The full API guide, with examples, is the agent prompt, `scripts/prompt.md`.
81
+
82
+ ## Building from a Restricted Part Set
83
+ `BRICKAGENT_SET` limits building to an inventory that maps LDraw part numbers to color names and maximum quantities
84
+ (`null` for any); `check` enforces the colors and counts:
85
+ ```json
86
+ {"3001": {"red": 8, "blue": 6}, "3020": {"tan": 2}, "3062b": {"white": null}}
87
+ ```
88
+
89
+ ## Rendering
90
+ `view` needs Node 22.14+ or 23.6+, Mesa (`libegl1`, `libgles2`, `libegl-mesa0`, `libgl1-mesa-dri`), a C++ runtime
91
+ from GCC 11 or newer (Ubuntu 22.04+), the viewer's npm packages, and the LDraw snapshot used in the experiments:
92
+ ```bash
93
+ npm ci --prefix "$(python -c 'from importlib.resources import files; print(files("brickagent") / "viewer")')"
94
+ curl -L https://codeload.github.com/kulits/ldraw-parts/tar.gz/b61b905f1173f120f528be9521bb870619c36785 | tar -xz
95
+ export BRICKAGENT_LDRAW="$PWD/ldraw-parts-b61b905f1173f120f528be9521bb870619c36785/ldraw"
96
+ # Render with Mesa, as in the experiments; NVIDIA's EGL driver currently renders washed-out colors.
97
+ export EGL_PLATFORM=surfaceless LIBGL_ALWAYS_SOFTWARE=1
98
+ export __EGL_VENDOR_LIBRARY_FILENAMES=/usr/share/glvnd/egl_vendor.d/50_mesa.json
99
+ ```
100
+
101
+ To explore a model in a browser instead, see the [viewer README](https://github.com/kulits/BrickAgent/blob/master/src/brickagent/viewer/README.md#browser).
102
+
103
+ ## BrickBench
104
+ ### Settings
105
+ | Setting | Prompts | Questions | Requirement |
106
+ | --- | --- | --- | --- |
107
+ | `Model` | 100 | 1,719 | At most 400 parts |
108
+ | `Set` | 100 | 2,369 | 400–4000 parts |
109
+ | `Alt-Build` | 100 | 1,182 | Only the pieces of retail set 10698 (`benchmark/alt-build/inventory.json`) |
110
+
111
+ Each setting's `benchmark/<setting>/tasks.json` lists its prompts, each decomposed into a question graph in the style of
112
+ [DSG](https://arxiv.org/abs/2310.18235): every question has a `key`, its text, a `kind` and `subtype`, and the keys it
113
+ depends on.
114
+
115
+ ### Running an Agent
116
+ The agent needs the setup above, either installed directly or through the container used in the experiments. Render the
117
+ prompt for a task:
118
+ ```bash
119
+ pip install jinja2
120
+ python scripts/prompt.py "$(jq -r '.[0].prompt' benchmark/model/tasks.json)" --split model > prompt.txt
121
+ ```
122
+
123
+ Give it to a coding agent in an empty workspace outside this repository, without web search, in a shell where the
124
+ variables above are exported. The experiments ran Codex in the container:
125
+ ```bash
126
+ docker build -t brickagent .
127
+ docker build -t brickagent-codex - <<< $'FROM brickagent\nRUN npm install --global @openai/codex'
128
+ mkdir -p work
129
+ docker run --rm -v "$PWD/work:/work" -e OPENAI_API_KEY brickagent-codex \
130
+ codex exec --skip-git-repo-check --dangerously-bypass-approvals-and-sandbox -c web_search=disabled \
131
+ "$(cat prompt.txt)"
132
+ ```
133
+
134
+ For `Alt-Build`, export `BRICKAGENT_SET=$PWD/benchmark/alt-build/inventory.json` (in Docker, also pass
135
+ `-v "$BRICKAGENT_SET:$BRICKAGENT_SET:ro" -e BRICKAGENT_SET`). The agent delivers `build.py`, whose `build()` returns the assembly, and `model.mpd`.
136
+
137
+ ### Evaluation
138
+ **Valid.** `verify.py` rebuilds the assembly from `build.py` and checks the setting's part requirements, collisions,
139
+ and stability (for `Alt-Build`, with the same `BRICKAGENT_SET`):
140
+ ```bash
141
+ python scripts/verify.py work --split model # or set, alt-build; writes work/verification.json, exits 1 if invalid
142
+ ```
143
+
144
+ Assemblies are rendered from eight views with [BrickNet-Render](https://github.com/kulits/BrickNet-Render) and judged
145
+ by Gemma 4 31B ([google/gemma-4-31B-it](https://huggingface.co/google/gemma-4-31B-it), revision `842da37`), loaded
146
+ with Transformers (about 62 GB of GPU memory). The scripts read `RENDERS/<system>/<task id>/`, e.g.
147
+ `RENDERS/my-agent/alt-001/`. BrickNet-Render needs Python 3.13:
148
+ ```bash
149
+ pip install bricknet-render "bpy>=5.1" transformers torch torchvision accelerate pillow
150
+ python -m bricknet_render fetch-glbs
151
+ python scripts/flatten.py work/model.mpd work/model.ldr
152
+ bricknet-render work/model.ldr RENDERS/my-agent/model-001 --views 8 --resolution 1024x1024 --samples 64
153
+ ```
154
+
155
+ **VQA.** The judge answers each assembly's question graph from its eight views; a question counts only if the
156
+ questions it depends on also hold.
157
+ ```bash
158
+ python scripts/vqa.py RENDERS --out vqa.jsonl
159
+ ```
160
+
161
+ **ELO.** For each prompt, every pair of assemblies from different systems is judged from four views each, in both
162
+ orders, on alignment with the prompt and on design by the standard of an official set. A Bradley--Terry fit gives
163
+ `Align ELO` and `Design ELO`; `ELO` is their average after rescaling to a common spread over the `--core` systems.
164
+ ```bash
165
+ python scripts/judge.py RENDERS --question align --out align.jsonl
166
+ python scripts/judge.py RENDERS --question design --out design.jsonl
167
+ python scripts/elo.py align.jsonl design.jsonl
168
+ ```
169
+
170
+ ## Submitting Results
171
+ Submit through the [form](https://forms.gle/GP8FX43EzfaTxkTT9). Upload one zip of at most 10 MB with a folder per task,
172
+ named by task id (`model-001/`, `set-001/`, `alt-001/`, ...), holding `build.py`, `model.mpd`, or both; `build.py` is
173
+ preferred. Missing tasks count as invalid. Check the zip first:
174
+ ```bash
175
+ python scripts/check_submission.py submission.zip
176
+ ```
@@ -0,0 +1,159 @@
1
+ <div align="center">
2
+
3
+ # BrickAgent: Programmatic LEGO Design
4
+ [Peter Kulits](https://kulits.github.io/)&nbsp;&nbsp;&nbsp;&nbsp;[Yiqing Xu](https://eeching.github.io/)&nbsp;&nbsp;&nbsp;&nbsp;[R. Kenny Jones](https://rkjones4.github.io/)&nbsp;&nbsp;&nbsp;&nbsp;[Cordelia Schmid](https://cordeliaschmid.github.io/)&nbsp;&nbsp;&nbsp;&nbsp;[Jiajun Wu](https://jiajunwu.com/)
5
+
6
+ [\[Project Page\]](https://brickben.ch) | [\[Gallery\]](https://gallery.brickben.ch)
7
+
8
+ <img src="https://raw.githubusercontent.com/kulits/BrickAgent/master/docs/images/teaser_mosaic.avif" alt="BrickBench teaser" width="800">
9
+
10
+ </div>
11
+
12
+ BrickAgent is the environment of BrickBench, a benchmark for agentic text-conditioned LEGO-set design. Coding agents
13
+ use it to programmatically construct, inspect, and validate LEGO assemblies, placing parts through the connector system
14
+ of [BrickNet](https://github.com/kulits/BrickNet).
15
+
16
+ This repository contains:
17
+ - **`brickagent`** (`src/brickagent/`), the environment, on PyPI.
18
+ - **BrickBench**: 300 task prompts (`benchmark/`), the agent prompt, validator, and evaluation (`scripts/`), and the
19
+ agent container (`Dockerfile`).
20
+
21
+ ## Install
22
+ ```bash
23
+ pip install brickagent
24
+ python -m bricknet fetch-meshes
25
+ ```
26
+
27
+ `fetch-meshes` downloads BrickNet's convex colliders (1 GB), which collision and stability checks need, into the
28
+ platform user-data directory; to use another location, export `BRICKNET_DATA` before fetching and keep it set.
29
+
30
+ ## Usage
31
+ ```python
32
+ from brickagent import Assembly
33
+
34
+ wall = Assembly("wall")
35
+ base = wall.add("plate 2x8", color="dark gray")
36
+ top = base.stud
37
+ for course in range(4):
38
+ next_top, column = [], 0
39
+ for width in (4, 4) if course % 2 == 0 else (2, 4, 2):
40
+ brick = wall.attach(f"brick 2x{width}", to=top[2 * column], by=("hole", 0), color="tan")
41
+ next_top.extend(brick.stud)
42
+ column += width
43
+ top = next_top
44
+ wall.write("wall.mpd", check=True)
45
+ ```
46
+
47
+ `add` places a part or subassembly at a pose; `attach` places it by an exact connector fit. Connectors are indexed in
48
+ BrickNet order (`part.stud[i]`, `part.hole[i]`, ...).
49
+
50
+ ```python
51
+ # continues the example above
52
+ from brickagent import find, describe, name, connectors, check, view
53
+
54
+ beams = [stem for stem in find("technic beam") if len(connectors(stem, "socket")) == 5]
55
+ print(beams[0], name(beams[0]))
56
+ print(describe("6629"))
57
+ check(wall)
58
+ view(wall, "wall.png") # needs the Rendering setup below
59
+ ```
60
+
61
+ `check` raises `ValueError` on collisions, inexact connections, exceeded inventory, or instability, naming the parts
62
+ involved. Each connected component is simulated as a rigid body under gravity in PyBullet. Only parts that BrickNet
63
+ supports can be used; `find` lists them. The full API guide, with examples, is the agent prompt, `scripts/prompt.md`.
64
+
65
+ ## Building from a Restricted Part Set
66
+ `BRICKAGENT_SET` limits building to an inventory that maps LDraw part numbers to color names and maximum quantities
67
+ (`null` for any); `check` enforces the colors and counts:
68
+ ```json
69
+ {"3001": {"red": 8, "blue": 6}, "3020": {"tan": 2}, "3062b": {"white": null}}
70
+ ```
71
+
72
+ ## Rendering
73
+ `view` needs Node 22.14+ or 23.6+, Mesa (`libegl1`, `libgles2`, `libegl-mesa0`, `libgl1-mesa-dri`), a C++ runtime
74
+ from GCC 11 or newer (Ubuntu 22.04+), the viewer's npm packages, and the LDraw snapshot used in the experiments:
75
+ ```bash
76
+ npm ci --prefix "$(python -c 'from importlib.resources import files; print(files("brickagent") / "viewer")')"
77
+ curl -L https://codeload.github.com/kulits/ldraw-parts/tar.gz/b61b905f1173f120f528be9521bb870619c36785 | tar -xz
78
+ export BRICKAGENT_LDRAW="$PWD/ldraw-parts-b61b905f1173f120f528be9521bb870619c36785/ldraw"
79
+ # Render with Mesa, as in the experiments; NVIDIA's EGL driver currently renders washed-out colors.
80
+ export EGL_PLATFORM=surfaceless LIBGL_ALWAYS_SOFTWARE=1
81
+ export __EGL_VENDOR_LIBRARY_FILENAMES=/usr/share/glvnd/egl_vendor.d/50_mesa.json
82
+ ```
83
+
84
+ To explore a model in a browser instead, see the [viewer README](https://github.com/kulits/BrickAgent/blob/master/src/brickagent/viewer/README.md#browser).
85
+
86
+ ## BrickBench
87
+ ### Settings
88
+ | Setting | Prompts | Questions | Requirement |
89
+ | --- | --- | --- | --- |
90
+ | `Model` | 100 | 1,719 | At most 400 parts |
91
+ | `Set` | 100 | 2,369 | 400–4000 parts |
92
+ | `Alt-Build` | 100 | 1,182 | Only the pieces of retail set 10698 (`benchmark/alt-build/inventory.json`) |
93
+
94
+ Each setting's `benchmark/<setting>/tasks.json` lists its prompts, each decomposed into a question graph in the style of
95
+ [DSG](https://arxiv.org/abs/2310.18235): every question has a `key`, its text, a `kind` and `subtype`, and the keys it
96
+ depends on.
97
+
98
+ ### Running an Agent
99
+ The agent needs the setup above, either installed directly or through the container used in the experiments. Render the
100
+ prompt for a task:
101
+ ```bash
102
+ pip install jinja2
103
+ python scripts/prompt.py "$(jq -r '.[0].prompt' benchmark/model/tasks.json)" --split model > prompt.txt
104
+ ```
105
+
106
+ Give it to a coding agent in an empty workspace outside this repository, without web search, in a shell where the
107
+ variables above are exported. The experiments ran Codex in the container:
108
+ ```bash
109
+ docker build -t brickagent .
110
+ docker build -t brickagent-codex - <<< $'FROM brickagent\nRUN npm install --global @openai/codex'
111
+ mkdir -p work
112
+ docker run --rm -v "$PWD/work:/work" -e OPENAI_API_KEY brickagent-codex \
113
+ codex exec --skip-git-repo-check --dangerously-bypass-approvals-and-sandbox -c web_search=disabled \
114
+ "$(cat prompt.txt)"
115
+ ```
116
+
117
+ For `Alt-Build`, export `BRICKAGENT_SET=$PWD/benchmark/alt-build/inventory.json` (in Docker, also pass
118
+ `-v "$BRICKAGENT_SET:$BRICKAGENT_SET:ro" -e BRICKAGENT_SET`). The agent delivers `build.py`, whose `build()` returns the assembly, and `model.mpd`.
119
+
120
+ ### Evaluation
121
+ **Valid.** `verify.py` rebuilds the assembly from `build.py` and checks the setting's part requirements, collisions,
122
+ and stability (for `Alt-Build`, with the same `BRICKAGENT_SET`):
123
+ ```bash
124
+ python scripts/verify.py work --split model # or set, alt-build; writes work/verification.json, exits 1 if invalid
125
+ ```
126
+
127
+ Assemblies are rendered from eight views with [BrickNet-Render](https://github.com/kulits/BrickNet-Render) and judged
128
+ by Gemma 4 31B ([google/gemma-4-31B-it](https://huggingface.co/google/gemma-4-31B-it), revision `842da37`), loaded
129
+ with Transformers (about 62 GB of GPU memory). The scripts read `RENDERS/<system>/<task id>/`, e.g.
130
+ `RENDERS/my-agent/alt-001/`. BrickNet-Render needs Python 3.13:
131
+ ```bash
132
+ pip install bricknet-render "bpy>=5.1" transformers torch torchvision accelerate pillow
133
+ python -m bricknet_render fetch-glbs
134
+ python scripts/flatten.py work/model.mpd work/model.ldr
135
+ bricknet-render work/model.ldr RENDERS/my-agent/model-001 --views 8 --resolution 1024x1024 --samples 64
136
+ ```
137
+
138
+ **VQA.** The judge answers each assembly's question graph from its eight views; a question counts only if the
139
+ questions it depends on also hold.
140
+ ```bash
141
+ python scripts/vqa.py RENDERS --out vqa.jsonl
142
+ ```
143
+
144
+ **ELO.** For each prompt, every pair of assemblies from different systems is judged from four views each, in both
145
+ orders, on alignment with the prompt and on design by the standard of an official set. A Bradley--Terry fit gives
146
+ `Align ELO` and `Design ELO`; `ELO` is their average after rescaling to a common spread over the `--core` systems.
147
+ ```bash
148
+ python scripts/judge.py RENDERS --question align --out align.jsonl
149
+ python scripts/judge.py RENDERS --question design --out design.jsonl
150
+ python scripts/elo.py align.jsonl design.jsonl
151
+ ```
152
+
153
+ ## Submitting Results
154
+ Submit through the [form](https://forms.gle/GP8FX43EzfaTxkTT9). Upload one zip of at most 10 MB with a folder per task,
155
+ named by task id (`model-001/`, `set-001/`, `alt-001/`, ...), holding `build.py`, `model.mpd`, or both; `build.py` is
156
+ preferred. Missing tasks count as invalid. Check the zip first:
157
+ ```bash
158
+ python scripts/check_submission.py submission.zip
159
+ ```
@@ -0,0 +1,34 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "brickagent"
7
+ version = "0.1.0"
8
+ description = "Programmatic LEGO design"
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ license-files = ["LICENSE"]
12
+ requires-python = ">=3.10"
13
+ authors = [{ name = "Peter Kulits" }]
14
+ dependencies = ["numpy", "scipy", "pybullet", "bricknet>=0.1.1"]
15
+ classifiers = [
16
+ "Programming Language :: Python :: 3",
17
+ "Operating System :: OS Independent",
18
+ ]
19
+
20
+ [project.urls]
21
+ Paper = "https://brickben.ch"
22
+
23
+ [tool.hatch.build]
24
+ exclude = ["**/node_modules/**"]
25
+
26
+ [tool.hatch.build.targets.wheel]
27
+ packages = ["src/brickagent"]
28
+
29
+ [tool.hatch.build.targets.sdist]
30
+ include = ["/src/brickagent", "/README.md", "/LICENSE", "/pyproject.toml"]
31
+ exclude = ["**/node_modules/**"]
32
+
33
+ [tool.black]
34
+ line-length = 120
@@ -0,0 +1,46 @@
1
+ """BrickAgent: Programmatic LEGO Design."""
2
+
3
+ from .catalog import color, name, resolve
4
+ from .export import ldraw, write
5
+ from .joints import Connector, NoMate, compatible, placement
6
+ from .model import Assembly, Occurrence, Placed, attachments, connectors, measure, parts
7
+ from .pose import BRICK, ID, PLATE, STUD, UP, Pose, at, move, spin
8
+ from .search import describe, find
9
+ from .check import check, clashes, connections
10
+ from .view import view
11
+
12
+ __version__ = "0.1.0"
13
+
14
+ __all__ = [
15
+ "Assembly",
16
+ "BRICK",
17
+ "Connector",
18
+ "ID",
19
+ "NoMate",
20
+ "Occurrence",
21
+ "PLATE",
22
+ "Placed",
23
+ "Pose",
24
+ "STUD",
25
+ "UP",
26
+ "at",
27
+ "attachments",
28
+ "check",
29
+ "clashes",
30
+ "color",
31
+ "compatible",
32
+ "connections",
33
+ "connectors",
34
+ "describe",
35
+ "find",
36
+ "ldraw",
37
+ "measure",
38
+ "move",
39
+ "name",
40
+ "parts",
41
+ "placement",
42
+ "resolve",
43
+ "spin",
44
+ "view",
45
+ "write",
46
+ ]