Skip to content

Commit 8fb25f7

Browse files
authored
Merge pull request #2 from UniverLab/develop
poc
2 parents 2305e1d + 6b0ecb2 commit 8fb25f7

31 files changed

Lines changed: 4307 additions & 28 deletions

.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* text=auto eol=lf

.github/workflows/ci.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,17 @@ name: CI
22

33
on:
44
pull_request:
5+
workflow_dispatch:
6+
push:
7+
branches: [main]
58

69
jobs:
710
rust-ci:
11+
name: Format, Lint & Test
812
uses: UniverLab/workflows/.github/workflows/rust-ci.yml@main
13+
with:
14+
run-tests: true
15+
run-clippy: true
16+
check-fmt: true
17+
publish-check: true
18+
main-pr-checks: true

.gitignore

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,37 @@ target
1919
# and can be added to the global gitignore or merged into this file. For a more nuclear
2020
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
2121
#.idea/
22+
23+
# AI coding agents
24+
.kiro/
25+
.cursor/
26+
.windsurf/
27+
.claude/
28+
.continue/
29+
.copilot/
30+
.kilocode/
31+
.zencoder/
32+
.qwen/
33+
.agents/
34+
skills-lock.json
35+
# Created by https://www.toptal.com/developers/gitignore/api/rust
36+
# Edit at https://www.toptal.com/developers/gitignore?templates=rust
37+
38+
### Rust ###
39+
# Generated by Cargo
40+
# will have compiled files and executables
41+
debug/
42+
target/
43+
44+
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
45+
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
46+
Cargo.lock
47+
48+
# These are backup files generated by rustfmt
49+
50+
# MSVC Windows builds of rustc generate these, which store debugging information
51+
52+
# End of https://www.toptal.com/developers/gitignore/api/rust
53+
output.dxf
54+
preview.png
55+
preview.meta.json

Cargo.toml

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,22 @@
1+
[workspace]
2+
members = ["crates/cadforge-cli", "crates/cadforge-view"]
3+
resolver = "2"
4+
15
[package]
26
name = "cadforge"
3-
version = "0.1.0"
7+
version = "0.1.0-beta.1"
48
edition = "2021"
5-
description = ""
6-
publish = false
9+
description = "Architecture as Code — deterministic geometry engine for reproducible architectural design"
10+
license = "MIT"
11+
publish = true
712

813
[dependencies]
14+
dxf = "0.6.1"
15+
anyhow = "1.0"
16+
serde = { version = "1.0", features = ["derive"] }
17+
serde_json = "1.0"
18+
toml = "0.8"
19+
toml_edit = "0.22"
20+
indexmap = { version = "2", features = ["serde"] }
21+
tiny-skia = "0.11"
22+
notify = "6.1"

README.md

Lines changed: 218 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,242 @@
1-
# cadforge
2-
3-
>
1+
██████ ████████ ██████ ████████ ██ ██ ██ ███████ ████████
2+
██░░███ ░░███░░███░░░░░███ ░░███░░███░███ ░███ ██░███░░░░░░░███░
3+
░███ ░░░ ░███ ░███ ███████ ░███ ░░░ ░███ ░██████░░█████ ░███
4+
░███ ███ ░███ ░███ ███░░███ ░███ ░███ ░███░░░ ░███░░█ ░███
5+
░░██████ ░███████░░████████ ░███ ░███████████ ███████ ░████████
6+
░░░░░░ ░░░░░░░ ░░░░░░░░ ░░░ ░░░░░░░░░░░ ░░░░░░ ░░░░░░░
7+
8+
<p align="center">
9+
<a href="https://github.com/UniverLab/cadforge/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/UniverLab/cadforge/ci.yml?branch=main&style=for-the-badge&label=CI" alt="CI"/></a>
10+
<a href="https://crates.io/crates/cadforge"><img src="https://img.shields.io/crates/v/cadforge?style=for-the-badge&logo=rust&logoColor=white" alt="Crates.io"/></a>
11+
<img src="https://img.shields.io/badge/Status-Active-27AE60?style=for-the-badge" alt="Status"/>
12+
<a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-2E8B57?style=for-the-badge" alt="License"/></a>
13+
</p>
14+
15+
cadforge is an **Architecture as Code** CLI tool and Rust library for declarative 2D CAD modeling. Write geometry as code in `.cf` TOML format, compile to DXF, and generate PNG previews for AI agents.
16+
17+
---
18+
19+
## Features
20+
21+
### 🎯 Core Platform
22+
23+
- **📐 Declarative Geometry** — Define architectural elements (lines, rects, circles, arcs, polylines, text, dimensions) in TOML `.cf` files. Deterministic, reproducible, version-controlled.
24+
- **🔗 Layer System** — Organize geometry by layer with custom names, colors, and line weights. Compile single layers or full projects.
25+
- **📄 DXF Export** — Compile `.cf` → DXF (AutoCAD-compatible). Full layer support, LWPOLYLINE for polylines, HATCH for solid fills, MTEXT for annotations.
26+
- **🖼️ PNG Preview** — Generate raster previews with metadata JSON for AI agent integration. Renders fills, hatches, strokes, and text with boundary resolution. Configurable resolution and layer filtering.
27+
- **✅ Validation Engine**`cadforge check` validates geometry without generating output. Shows project metadata, layer colors, and entity counts.
28+
29+
### 🏗️ Project Management
30+
31+
- **Project Scaffolding**`cadforge new` creates a complete multi-layer project (muros, puertas, mobiliario, cotas) with meaningful architectural examples.
32+
- **Multi-Layer Compilation** — Compile all layers or target specific layers with `--layer`. Custom output path with `--output`.
33+
- **Auto-Rebuild**`cadforge watch` monitors `.cf` and `.toml` files and auto-rebuilds on changes with 300ms debounce.
34+
- **Code Formatting**`cadforge fmt` normalizes `.cf` files. `--check` mode for CI validation.
35+
- **Boundary Resolution** — Automatic detection of closed boundaries for hatch generation. Shared boundary resolution across overlapping entities.
36+
- **Polyline Support** — Full LWPOLYLINE support with bulge factors for arcs. Proper vertex handling and closure detection.
37+
38+
### 🔧 Architecture
39+
40+
- **Compiler Pipeline** — Parse → Resolve → Compile → Emit. Modular design for easy extension.
41+
- **DXF Writer** — Direct DXF entity writing with proper AutoCAD compatibility. Layer/color/lineweight mapping.
42+
- **Preview Renderer** — Tiny-skia based raster rendering with anti-aliasing. PNG + JSON metadata output.
43+
- **Error Reporting** — Structured errors with file, line, and context. Fast-fail on validation errors.
44+
45+
---
46+
47+
## Commands
48+
49+
| Command | Description |
50+
|---------|-------------|
51+
| `cadforge new <name>` | Create a new project with multi-layer scaffold |
52+
| `cadforge init` | Initialize CADforge in current directory |
53+
| `cadforge build` | Compile project to DXF |
54+
| `cadforge build --check` | Validate project and constraints without generating DXF |
55+
| `cadforge build --output <path>` | Compile to custom output path |
56+
| `cadforge build --layer <name>` | Compile specific layer only |
57+
| `cadforge check` | Validate with project metadata and layer colors |
58+
| `cadforge layers` | List layers with entity counts and colors |
59+
| `cadforge preview` | Generate PNG preview + metadata JSON |
60+
| `cadforge preview --width 1024 --height 768` | Custom resolution preview |
61+
| `cadforge preview --layer <name>` | Preview specific layer only |
62+
| `cadforge fmt` | Format .cf files (normalize whitespace) |
63+
| `cadforge fmt --check` | Check formatting without modifying (CI) |
64+
| `cadforge watch` | Auto-rebuild on file changes |
65+
| `cadforge import <file.dxf>` | Import DXF into `.cf` layers + `project.toml` |
66+
| `cadforge import <file.dxf> --layer <name>` | Import only one DXF layer |
67+
| `cadforge view` | Open the dedicated `cadforge-view` viewer |
68+
| `cadforge view --layer <name>` | Open only one layer in the viewer |
69+
| `cadforge config set <key> <value>` | Set global defaults (`author`, `units`) |
70+
| `cadforge config show` | Show global defaults |
71+
72+
### Viewer controls (MVP)
73+
74+
- HUD flotante en pantalla con proyecto, vista, distancia, capas, selección y ayuda de atajos
75+
- `T` / `F` / `V` / `R` → top / front / right / isometric preset views
76+
- `Q` / `E` / `W` / `S` → orbit camera
77+
- Mouse left-drag → orbit
78+
- Mouse right-drag / arrows → pan
79+
- Mouse wheel / `+` / `-` → zoom
80+
- `1`..`9` → toggle layer visibility
81+
- Click entity edge → select primitive id
82+
- Selected entity is highlighted in amber in the viewport HUD context
83+
- `C` → copy selected id to clipboard
84+
85+
---
86+
87+
## .cf Format
88+
89+
```toml
90+
[layer]
91+
name = "muros"
92+
color = "#FFFFFF"
93+
94+
[[line]]
95+
id = "ln-001"
96+
from = [0.0, 0.0]
97+
to = [8.5, 0.0]
98+
weight = 0.50
99+
100+
[[rect]]
101+
id = "rc-001"
102+
origin = [1.0, 1.0]
103+
width = 3.5
104+
height = 4.0
105+
106+
[[circle]]
107+
id = "ci-001"
108+
center = [4.0, 3.0]
109+
radius = 0.5
110+
111+
[[arc]]
112+
id = "ac-001"
113+
center = [2.0, 2.0]
114+
radius = 0.9
115+
from_angle = 0.0
116+
to_angle = 90.0
117+
118+
[[polyline]]
119+
id = "pl-001"
120+
vertices = [[0, 0], [5, 0], [5, 3], [0, 3]]
121+
closed = true
122+
123+
[[text]]
124+
id = "tx-001"
125+
position = [4.0, 3.0]
126+
content = "SALA"
127+
size = 0.2
128+
129+
[[dim]]
130+
id = "dm-001"
131+
from = [0, 0]
132+
to = [5, 0]
133+
offset = 0.5
134+
```
4135

5-
## Getting started
136+
### Supported Primitives
6137

7-
### Prerequisites
138+
`line`, `polyline`, `rect`, `circle`, `arc`, `text`, `point`, `dim`, `hatch`, `solid`
8139

9-
- Rust 1.70+
10-
- Cargo
140+
---
11141

12-
### Build
142+
## Architecture Overview
13143

14-
```bash
15-
cargo build --release
144+
```
145+
.cf file (TOML)
146+
147+
148+
┌─────────┐ ┌──────────┐ ┌─────────┐ ┌─────────┐
149+
│ Parser │───▶│ Resolver │───▶│Compiler │───▶│ DXF Emit│
150+
└─────────┘ └──────────┘ └─────────┘ └─────────┘
151+
152+
153+
┌──────────┐ ┌─────────────┐
154+
│ Boundary │───▶│ Preview PNG │
155+
│ Resolver │ │ + JSON meta │
156+
└──────────┘ └─────────────┘
16157
```
17158

18-
### Run
159+
- **Parser** — TOML parsing with custom array-of-tables detection, primitive validation
160+
- **Resolver** — Layer dependency resolution, coordinate validation, boundary detection
161+
- **Compiler** — Entity compilation to DXF format, hatch generation, polyline closure
162+
- **DXF Writer** — Direct DXF entity emission with proper layer/color/lineweight mapping
163+
- **Preview Renderer** — Tiny-skia raster rendering with hatch/fill support
19164

20-
```bash
21-
cargo run
22-
```
165+
---
166+
167+
## Main Modules
168+
169+
- `compiler/` — Project compilation pipeline, layer targeting, validation, build stats
170+
- `dxf_writer/` — DXF entity writing, LWPOLYLINE, HATCH, MTEXT generation
171+
- `preview/` — PNG rendering with configurable resolution, layer filtering, metadata JSON
172+
- `parser/` — TOML parsing, primitive extraction, array-of-tables handling
173+
- `model/` — Data structures: Layer, Primitive, Project
174+
- `scaffold/` — Multi-layer project creation with architectural examples
175+
- `fmt/` — .cf file formatting and normalization
176+
- `watch/` — File system watcher with auto-rebuild and debounce
177+
- `color/` — Color parsing and DXF color mapping
178+
179+
---
180+
181+
## Data Storage
182+
183+
| Data | Location | Format |
184+
|------|----------|--------|
185+
| Project files | `./` | TOML (`.cf` + `project.toml`) |
186+
| Build output | `output/` | DXF |
187+
| Preview output | `output/preview.png` | PNG |
188+
| Preview metadata | `output/preview.json` | JSON |
189+
| Build cache | `target/` | Cargo build |
23190

24-
### Test
191+
---
25192

193+
## Usage
194+
195+
**Create a new project:**
26196
```bash
27-
cargo test
197+
cadforge new mi-proyecto
198+
cd mi-proyecto
28199
```
29200

30-
## Development
201+
**Edit `.cf` files** (TOML format with your geometry)
31202

32-
### Format code
203+
**Format and validate:**
204+
```bash
205+
cadforge fmt # normalize .cf files
206+
cadforge check # validate without generating DXF
207+
```
33208

209+
**Compile to DXF:**
34210
```bash
35-
cargo fmt
211+
cadforge build # default output.dxf
212+
cadforge build --output plano.dxf # custom output path
213+
cadforge build --layer muros # compile single layer
36214
```
37215

38-
### Lint with Clippy
216+
**Preview:**
217+
```bash
218+
cadforge preview # default 2048x1536
219+
cadforge preview --width 1024 --height 768 # custom resolution
220+
cadforge preview --layer muros # single layer preview
221+
```
39222

223+
**Auto-rebuild on changes:**
40224
```bash
41-
cargo clippy -- -D warnings
225+
cadforge watch # monitors .cf and .toml files
42226
```
43227

228+
---
229+
230+
## Tech Stack
231+
232+
| Rust 2021 | clap | toml | toml_edit | tiny-skia | dxf | notify | anyhow | serde |
233+
234+
---
235+
44236
## License
45237

46-
This project is licensed under the MIT License — see LICENSE for details.
238+
MIT — see [LICENSE](LICENSE) for details.
239+
240+
---
241+
242+
Made with ❤️ by [JheisonMB](https://github.com/JheisonMB) and [UniverLab](https://github.com/UniverLab)

crates/cadforge-cli/Cargo.toml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[package]
2+
name = "cadforge-cli"
3+
version = "0.1.0-beta.1"
4+
edition = "2021"
5+
description = "CLI binary for cadforge"
6+
license = "MIT"
7+
publish = true
8+
9+
[[bin]]
10+
name = "cadforge"
11+
path = "src/main.rs"
12+
13+
[dependencies]
14+
anyhow = "1.0"
15+
clap = { version = "4.6", features = ["derive"] }
16+
cadforge = { path = "../.." }
17+
cadforge-view = { path = "../cadforge-view" }

0 commit comments

Comments
 (0)