# 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 ```