A 3D design tool built exclusively for AI agents: parametric code in, renders + machine-readable validation reports out.
Project description
solidsight
A 3D design tool built exclusively for AI agents. Parametric Python in; deterministic geometry, multi-angle PNG renders, and a machine-readable validation report out.
An LLM writing CAD code is blind: it can reason about geometry but cannot see what it made. Human CAD tools assume eyes on a screen and a hand on a mouse. solidsight closes the loop the way an agent needs it closed — every build produces images to look at and exact numbers to check, plus errors written to be read by a model, not a human at a console.
write code -> solidsight build -> renders + report.json -> inspect -> adjust -> repeat
Same prompt, with and without the tool
"Make a detailed 3D model of an inline-4 engine block" — once as a blind
one-shot by a fresh-context agent (plain Python + trimesh, no renders, no
validation: what a bare agent does), once through solidsight's loop. Same
kinds of mistakes on both sides; the loop is the difference between
shipping them and catching them. The blind result ended convinced of
success (is_watertight: True) — the audit found its main oil gallery
tangent to the block's outer face (a 0.45 mm skin over a pressurized oil
line), oil drain-backs that dead-end inside a wall 1.0 mm from the water
jacket, and a crankcase open to the outside through a slot a ray crosses
with 0 crossings.
left: blind one-shot · right: same prompt through the loop — full protocol, audit evidence and honest caveats in docs/comparison
Quickstart (30 seconds)
pip install solidsight
# unreleased main: pip install "git+https://github.com/VortexJer/AISight#subdirectory=solidsight"
cat > model.py <<'EOF'
from solidsight import *
plate = rect(60, 40).round_corners(4).extrude(5)
hole = cylinder(h=7, d=4.5).translate(0, 0, -1)
plate = plate - parts.grid_pattern(hole, 2, 2, 44, 28).translate(-22, -14, 0)
boss = parts.standoff(h=8, od=8, id_=3.2)
emit(plate + boss, name="plate")
EOF
solidsight build model.py --print-safe --stl
# -> out/renders/01_iso.png ... 04_top.png (look at these)
# -> out/report.json (volume, walls, overhangs, checks)
# -> out/stl/plate.stl
Or as a Claude Code plugin:
/plugin marketplace add VortexJer/AISight
/plugin install solidsight@aisight
(the plugin carries the skill; the CLI it drives still comes from pip)
The build summary ends with the tool's whole philosophy in one line:
NEXT: open the renders and LOOK at them, then read report.json checks.
What the agent gets on every build
- Renders — orthographic PNGs (iso/front/right/top + more, turntable, exploded view), one muted color per named part with an on-image legend, sharp-edge overlay, 10 mm ground grid, axis triad, exact bbox dimensions and a scale bar burned into every frame. Deterministic software rasterizer: no GPU, no OpenGL, byte-identical output for identical input.
- report.json — per part: exact volume, surface area, bbox, center of
mass, shell count, genus, watertightness, minimum wall thickness (with the
coordinates of the thinnest point), overhang analysis, sealed-cavity
detection. Per pair of parts: exact collision bbox + volume + a concrete
move suggestion, or the minimum clearance between surfaces. Every finding
carries
whereand atry:suggestion. - Cross-sections —
--slice z=5renders the filled section; internal walls and fits are invisible from outside. - Exact spatial queries (no vision needed):
solidsight query model.py point|ray|section|voxels ...— point classification, ray crossings with per-wall thicknesses, ASCII material grids, voxel grids with flood-fill cavity detection. - Errors written for LLMs — what failed, where (file:line, names, coordinates, bounding boxes), and what to try next. Never "invalid geometry".
Before / after: one turn of the loop
Real, committed output from 05-assembly: a
divider tray was designed 8 mm too tall and pokes through the closed lid.
before: the tray (green) pierces the lid · after: seated under the lip with declared clearance
Before — the agent doesn't have to see it; the report says exactly what, where and how much:
[WARN] parts "lid" and "card" occupy the same space (160 mm3 of overlap)
where: overlap bbox x -20..20, y 4.2..5.8, z 24..26.5
try: move 'card' 1.7 mm along y, or rework the joint; ...
After — one edit later, the declared spec holds:
pair 'box' <-> 'lid': touching, clearance 0.0 mm [spec MET: touching]
pair 'card' <-> 'lid': clear, clearance 0.2 mm [spec MET: clearance >= 0.15 mm]
And the change is auditable — solidsight diff before/ after/:
diff: model_collision.py [warnings] -> model.py [ok]
part 'card': volume 1536.0 -> 1024.0 (-512.0 mm3); size [40.0, 1.6, 24.0] -> [40.0, 1.6, 16.0]
part 'box': unchanged part 'lid': unchanged
GONE [WARN] parts "lid" and "card" occupy the same space (160 mm3 of overlap)
render 01_iso.png: 0.3% of pixels differ
The edit did what it meant — and provably nothing else.
The engineering platform (v0.6)
Everything an autonomous agent needs from concept to manufacturing, all deterministic and headless:
- Live mode —
solidsight watchrebuilds on save with provable skips (exact scene fingerprints);solidsight viewserves an interactive viewer (isolate, x-ray, section planes, explode, finding markers with fly-to, two-point measuring) that hot-reloads on every successful rebuild. It opens as an app window (Chromium--app: no tab strip, no address bar, own taskbar entry;--tabfor a normal tab), takes the next free port when yours is busy and says which, ships geometry as binarymesh.bin(a 22 MB JSON scene became a few MB of typed arrays), and writesstatus.json— pid, url, state, build count — so a caller can tell "still serving" from "crashed" without killing it. Self-contained: vendored three.js, no CDN. - Progress everywhere —
--progresslive stage lines (%, ETA) and--events file.ndjsonstructured streams; artifacts stay byte-deterministic. - Formats — STL, 3MF, OBJ, GLB (combined GLB keeps part names +
colors), DXF/SVG section outlines,
solidsight convert. - Real components — an offline database of ~70 real parts with the
standards' exact dimensions:
solidsight components search "m4 socket head"→parts.component("iso4762_m4", length=16). Plus catalog generators for bearings, NEMA motors, GT2 pulleys, MGN rails, T-slot extrusions, springs, shafts, servos. - Engineering outputs —
solidsight drawing(dimensioned third-angle PDF with true hidden lines and a hole table),solidsight robot(joint() → URDF/SDF with exact inertials),solidsight motion(sweep joints through limits → exact collision map). - Reasoning & review —
query distance,fit 8 H7 g6(real ISO 286),explain <check-id>,critique(design review with fix menus and a verified-good list),cost(FDM/SLA/CNC estimates),assembly(BOM, axis play, assembly sequence). - Extensible & measurable — plugin entry points
(
solidsight.plugins, crash-isolated) and a graded benchmark suite (benchmarks/, six commissions with machine-checkable expectations).
Two validation modes
--print-safe— for parts that will be manufactured: enforces watertight, single shell per part, minimum wall thickness, no sealed cavities; warns on overhangs and floating parts. Non-zero exit code on failure, so CI works.--free(default) — visual/artistic exploration: same metrics reported, nothing enforced.
Scope: parts and machines — not styling
solidsight is a CSG kernel driven by code, and it is at its best where a shape is specified: brackets, enclosures, mechanisms, gears, engine internals, fixtures, furniture, robots — anything whose correctness is a number (a wall, a clearance, a centre distance, a hole pattern, a print angle). There the loop is decisive: the report finds what nobody can see and the diff proves the fix did only what you meant.
It is bad at styled organic surfaces — cars, character bodies, sculpted consumer shells, anything whose acceptance test is "does it look like the photo". Not a matter of trying harder; it is what the stack cannot do:
- No surface modelling. No NURBS patches, no subdivision, no
sculpting, no curvature-continuous (class-A) blends, no 3D fillet
across arbitrary edges —
round_corners/offsetlive in 2D sketches. Booleans of primitives plus station lofts give faceted shoulders and hard transitions exactly where a car body needs continuity. - The report measures manufacturability, not likeness. Watertight,
single shell, 0 findings, every spec met — and it can still look
nothing like the car.
--refprints a reference-vs-render sheet, but nothing in the tool scores resemblance; that judgement stays with the human eye, which is the one thing this tool was built to replace. - Details on a curved body are hand-carved. Glass, lights, grilles, trim and shutlines have to be cut out of the body shell with booleans against an eroded copy of itself, each one a fight with coincident faces and z-fighting — and the piece count grows far faster than the loop can iterate (a full body scene is minutes per build, not seconds).
- Likeness is per-piece work. Getting a mirror or a headlight to read as the real part takes its own commission, its own photos and its own iterations; a car is fifty of those, and any one that looks wrong ruins the whole.
Rule of thumb: if the acceptance test is a caliper, use solidsight; if
it is an eye, don't. For styled exteriors expect a recognisable
massing at best — 04-vase and
09-coupe-body are that honest ceiling,
not a finished product — and take the real surfacing to a sub-D /
NURBS modeller.
Images as input
The agent has eyes; the kernel does not. image_outline() traces the
dark shapes of a photo or drawing into an exact sketch (holes preserved,
real size declared by the agent — pixels carry no millimetres), and
image_heightfield() turns brightness into a watertight relief solid
(lithophanes, terrain). Building with --ref photo.png adds a
reference-vs-render comparison sheet to every build, so the loop closes
against the source image. Example: 08-from-image.
image_outline is for flat art. Pointed at a photograph it used to
trace the texture — 19,194 contours from one car photo, 42 s just to
extrude — so it now caps the trace resolution and refuses a shredded
result with the counts and the way out (threshold the image, raise
min_area, or use profile_read(), which is the one built to measure
photographed silhouettes).
The Claude Code skill
skills/solidsight/SKILL.md teaches an agent the full workflow — bill
of parts before code, catalog before derivation, build-and-look after every
change, exact queries when eyes are not enough, the assembly
collision/clearance loop, detail mode for faithful technical models, and a
definition-of-done checklist.
Beneath it, skills/solidsight/domains/ carries 12 deep domain
playbooks — enclosures, mechanisms, product design, furniture,
architecture, vehicles, organic, terrain, jewelry/miniatures, game-ready
assets, toys, scientific — each with the numbers a domain expert would
assume (heat-set insert holes, gear centre distances, NACA profiles,
stair rules, ring sizes, the small-parts choking cylinder, triangle
budgets), the build order, the failure modes, and its own definition of
done. The agent loads exactly the one that matches the request. (The
vehicles and organic playbooks are subject to the same ceiling as the
Scope section: they teach
correct proportions and build order, not class-A surfacing.)
It installs itself. The skill ships inside the pip package: the first
solidsight command on a machine with Claude Code drops it into
~/.claude/skills/solidsight and keeps it updated. From then on, any 3D
design request in Claude Code routes through it. Manual control:
solidsight install-skill # (re)install explicitly
solidsight uninstall # remove the skill AND the package
# the whole family: pip install aisight && aisight uninstall
Parametric parts catalog
solidsight catalog lists battle-tested components so agents compose instead
of re-deriving: involute spur gears, ISO threads/bolts/nuts, print-in-place
hinges, cantilever snap clips + slots, boxes with fitted lids, uniform-wall
containers, standoffs, hex vent cutters + honeycomb panels, linear/grid/
circular patterns, 3D tube sweeps (tube_path), 2D ribbon curves
(stroke), and real text (emboss/engrave) from the bundled font.
The whole stack was hardened by blind dogfooding: five design commissions
executed using only the skill and the CLI (no knowledge of the internals),
with every point of friction fixed at the root — 16 findings, from a
silently-broken shading fallback to false positives in the wall-thickness
metric. Each real bug is pinned by a regression test in tool/tests/
(see CHANGELOG.md).
Examples (all outputs generated by the tool, committed as proof)
| example | shows |
|---|---|
01-mounting-bracket |
primitives, patterns, print-safe |
02-snap-box |
booleans, snap-fit clip/slot pairing |
03-gear-train |
catalog gears; pair clearance proves the mesh (0.19 mm backlash) |
04-vase |
organic twisted form in --free mode |
05-assembly |
multi-part assembly; intentional collision caught with exact bbox/volume, then fixed with measured clearances |
06-hidden-cavity |
a sealed cavity invisible in renders, caught by the report and provable via query ray/voxels |
07-engine-block |
detail mode: a faithful inline-4 block (bores, liner steps, head-bolt matrix, water jacket, cam tunnel, oil galleries, pan rail, gussets, filter pad, inclined mounts) built region-by-region from a feature specification |
08-from-image |
from an image: a user's emblem traced with image_outline and engraved, built with the --ref comparison sheet |
09-coupe-body |
styled bodywork — and the tool's ceiling: a 2024-coupe-proportioned one-piece body by station lofting (loft_sections, concave shoulder sections, carved arches). Correct proportions and a clean single shell; not a class-A exterior — see Scope |
Stack and why
| layer | choice | why |
|---|---|---|
| geometry kernel | manifold3d | guaranteed-manifold CSG, exact booleans, deterministic, fast, pip-installable everywhere. Not reinvented here — solidsight's value is the feedback loop on top. |
| mesh analysis | trimesh | mass properties, adjacency, watertightness |
| rendering | own numpy z-buffer rasterizer + Pillow | zero GPU/driver dependencies, headless on any CI, fully deterministic — the reasons pyrender/OpenGL were rejected |
| text | matplotlib's font machinery | bundled DejaVu font = identical glyph geometry on every machine |
Alternatives considered: JSCAD (JS kernel is solid but headless PNG rendering in Node needs GPU or fragile native deps), build123d/OCCT (real BREP fillets, but a heavyweight install and less cross-platform determinism), trimesh-only (boolean robustness depends on external engines). Manifold hits the sweet spot: robust, light, deterministic.
Design principles
- Code is the design language — parametric primitives, booleans, transforms. No hand-edited meshes, no GUI.
- The agent is blind until it renders — so rendering + reporting is the core feature, not an add-on.
- Total determinism — same input, byte-identical output. Agents can trust their mental model; CI can diff artifacts.
- Errors are for LLMs — specific, located, actionable.
- Don't reinvent the kernel — reinvent the feedback loop.
Leaving: solidsight uninstall removes this tool's skill and package.
pip install aisight && aisight uninstall removes the whole family —
every skill, every package and the plugin marketplace. See
aisight.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file solidsight-0.11.12.tar.gz.
File metadata
- Download URL: solidsight-0.11.12.tar.gz
- Upload date:
- Size: 409.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b3dadc63c2d99acb4e110174d3c6625c8f22b62e0185abf02a3f9ed64a85375b
|
|
| MD5 |
6defd1bca1ae9ca5841a167b8916bc0d
|
|
| BLAKE2b-256 |
bc9acdcb428d46df4558adfd6be0504113078f3879d442190a352a4d022ad0de
|
Provenance
The following attestation bundles were made for solidsight-0.11.12.tar.gz:
Publisher:
release.yml on VortexJer/AISight
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
solidsight-0.11.12.tar.gz -
Subject digest:
b3dadc63c2d99acb4e110174d3c6625c8f22b62e0185abf02a3f9ed64a85375b - Sigstore transparency entry: 2251434899
- Sigstore integration time:
-
Permalink:
VortexJer/AISight@ef1f5423a3a497e53a69e1b8e231f5d9f4d3801a -
Branch / Tag:
refs/tags/solidsight-v0.11.12 - Owner: https://github.com/VortexJer
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ef1f5423a3a497e53a69e1b8e231f5d9f4d3801a -
Trigger Event:
push
-
Statement type:
File details
Details for the file solidsight-0.11.12-py3-none-any.whl.
File metadata
- Download URL: solidsight-0.11.12-py3-none-any.whl
- Upload date:
- Size: 412.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
49f7cbd6e8c37429c4821f1edd939a2f02077e8cd32585414d44f137bdc3fef8
|
|
| MD5 |
5a97279dd50df8c0b716f148934cf06e
|
|
| BLAKE2b-256 |
07c1dde0d6579801bdccc806da0f6f2c595c4b6c3e4c1f292280df816b6eade0
|
Provenance
The following attestation bundles were made for solidsight-0.11.12-py3-none-any.whl:
Publisher:
release.yml on VortexJer/AISight
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
solidsight-0.11.12-py3-none-any.whl -
Subject digest:
49f7cbd6e8c37429c4821f1edd939a2f02077e8cd32585414d44f137bdc3fef8 - Sigstore transparency entry: 2251435174
- Sigstore integration time:
-
Permalink:
VortexJer/AISight@ef1f5423a3a497e53a69e1b8e231f5d9f4d3801a -
Branch / Tag:
refs/tags/solidsight-v0.11.12 - Owner: https://github.com/VortexJer
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ef1f5423a3a497e53a69e1b8e231f5d9f4d3801a -
Trigger Event:
push
-
Statement type: