mesh-tool: mesht - create/inspect/edit OBJ+STL with ASCII multi-view rendering
- OBJ read/write (multi-object, ngon fan-triangulation, negative indices), STL binary+ascii with auto-detect and vertex welding - info: bbox/size/area/volume + watertightness via edge manifold stats - view: z-buffered orthographic ASCII renders (front/side/top/iso/back) - transform: center/mirror/scale/rotate/translate/fit, per-object filter, winding auto-flip on negative determinant - create: box/sphere/cylinder/cone/plane/torus; merge; convert - go tests: primitive volumes vs analytic values, roundtrips, topology Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MmdG9GqfSWCzts7AkDwRDh
This commit is contained in:
101
mesh-tool/README.md
Normal file
101
mesh-tool/README.md
Normal file
@@ -0,0 +1,101 @@
|
||||
# mesh-tool (`mesht`)
|
||||
|
||||
Create, inspect and edit **3D models** from the command line — built so an
|
||||
agent can *see* a model (ASCII multi-view rendering + measurements),
|
||||
reason about it, and edit it step by step. Written in Go, zero
|
||||
dependencies, single static binary.
|
||||
|
||||
## Formats
|
||||
|
||||
| Format | Read | Write | Notes |
|
||||
|--------|------|-------|-------|
|
||||
| OBJ | ✔ | ✔ | multiple named objects, quads/ngons triangulated |
|
||||
| STL | ✔ | ✔ | binary + ASCII, auto-detected; vertices re-welded on load |
|
||||
|
||||
OBJ and STL cover the vast majority of simple editing/printing/game
|
||||
pipelines and are plain enough to survive round-trips. glTF/GLB is out of
|
||||
scope for now (a full JSON+buffer+material model; use Blender for that).
|
||||
|
||||
Normals, UVs and materials are ignored on read — this tool edits
|
||||
*geometry*. Viewers recompute normals; STL export writes correct face
|
||||
normals from the winding.
|
||||
|
||||
## Build
|
||||
|
||||
```bash
|
||||
# Arch/Garuda: sudo pacman -S go
|
||||
cd mesh-tool
|
||||
go build -o build/mesht . # or the VS Code task "build mesh-tool"
|
||||
go test ./...
|
||||
```
|
||||
|
||||
## Commands
|
||||
|
||||
```bash
|
||||
mesht info model.obj # verts/tris, bbox, size, area, volume, watertight?
|
||||
mesht view model.obj # ASCII render: front, side, top (default)
|
||||
mesht view model.obj --views iso --width 100 --object wheel
|
||||
|
||||
# creation — box|sphere|cylinder|cone|plane|torus
|
||||
mesht create box --size 2,1,1 --name crate -o crate.obj
|
||||
mesht create sphere --radius 1 --segments 32 --rings 16 -o ball.stl
|
||||
|
||||
# editing (applied in the listed order)
|
||||
mesht transform m.obj --center # bbox center -> origin
|
||||
mesht transform m.obj --mirror x # winding auto-corrected
|
||||
mesht transform m.obj --scale 2 # or --scale 1,2,1
|
||||
mesht transform m.obj --rotate 0,45,0 # degrees, X then Y then Z
|
||||
mesht transform m.obj --translate 0,2,0
|
||||
mesht transform m.obj --fit 10 # largest dimension -> 10 units
|
||||
mesht transform m.obj --object wheel --scale 1.2 -o out.obj # edit one part
|
||||
|
||||
mesht merge body.obj wheels.obj -o car.obj # keeps objects, renames dups
|
||||
mesht merge a.stl b.stl --flatten -o one.obj # single combined object
|
||||
mesht convert model.obj -o model.stl # --ascii for text STL
|
||||
```
|
||||
|
||||
`-o` picks the output format from the extension. `transform` overwrites
|
||||
the input when `-o` is omitted.
|
||||
|
||||
## Conventions
|
||||
|
||||
- **Axes:** right-handed, **+Y up**, +X right, +Z toward the "front" viewer.
|
||||
- Primitives are centered on the origin.
|
||||
- Mirroring / negative scaling automatically flips triangle winding so
|
||||
surfaces keep facing outward.
|
||||
- `info` reports **volume only for watertight meshes** — otherwise it
|
||||
tells you how many boundary/non-manifold edges the mesh has.
|
||||
|
||||
## How an agent should edit a model
|
||||
|
||||
1. `mesht info m.obj` — learn size, orientation and object names.
|
||||
2. `mesht view m.obj` — see the shape (front/side/top; add `iso` for depth).
|
||||
3. Apply **one small transform**, write to a new file.
|
||||
4. `mesht view` again and compare — verify before continuing.
|
||||
|
||||
The ASCII views are z-buffered orthographic renders; brightness = how
|
||||
much the surface faces the light over the viewer's shoulder, so shape
|
||||
and curvature read directly from the text. Each view header repeats the
|
||||
axis legend and model dimensions.
|
||||
|
||||
Example (a 32-segment sphere, front view, width 48):
|
||||
|
||||
```
|
||||
front view — X→right Y↑up (seen from +Z)
|
||||
model 2 x 2 x 2 (XYZ)
|
||||
==++**####%%%%%%%%%%%%###*
|
||||
-==++**######%%%%%%%%%%%%%%####*
|
||||
:-=+++**#######%%%%%%%%%%%%%%%%%%#**
|
||||
-==++***#######%%%%%%%%%%%%%%%%%%%%##*
|
||||
.:--+++***########%%%%%%%%%%%%%%%%%%%%%%##*+
|
||||
```
|
||||
|
||||
## Viewing the results as a human
|
||||
|
||||
Any of these (Arch/Garuda):
|
||||
|
||||
```bash
|
||||
sudo pacman -S f3d # fast minimal viewer: f3d model.obj
|
||||
sudo pacman -S blender # full editor
|
||||
flatpak install org.prusa3d.PrusaSlicer # if you also want to print
|
||||
```
|
||||
Reference in New Issue
Block a user