Interoperability · ACIS SAT

ACIS SAT — the other kernel-format spoke

ACIS text transmits — .sat — are the second kernel format NativeCAD speaks: like Parasolid XT, a SAT file carries the whole topology graph (body, lump, shell, face, loop, coedge, edge, vertex), so a solid imports watertight straight out of the reader with nothing to sew. Wired at the cad_import/cad_export_body surface 2026-08-29, on a reader and writer this kernel wrote from the published format description. A SAT file is single-body — solids, not sheets — and the binary twin .sab is refused by name (SAT_BINARY_UNSUPPORTED), never mis-parsed.

Import — cad_import

Records map one-for-one onto the kernel's STEP entity graph: body/lump/shell become MANIFOLD_SOLID_BREP + CLOSED_SHELL, and faces, loops, coedges, edges and vertices land as their STEP counterparts. Analytic geometry stays analytic — plane, cylinder and cone (both read from cone-surface, split on the half-angle sine), sphere, torus, with straights, circles and ellipses as the curve classes. The header's units scale (mm per model unit) is applied to every coordinate and radius on read.

Real-file dialects

Two public NIST files are committed as fixtures, and each broke an assumption the generated corpus could not: the 1.05 nist_arm_blnk.sat has a single-line header with no units line — its mm-per-unit 1 is reported as source:"default", not as something the file declared — and the 1.06 nist_wrench.sat declares a record count of 0 (“read to the terminator”), writes explicit infinite-interval markers that shift cone-surface's half-angle fields, and chains an inner loop first. The reader handles all of it by token shape rather than by header version, and the wrench builds watertight with zero ops/check findings.

Options

OptionKindWhat it does
unitsbehavior Overrides the header's mm-per-model-unit scale. The import report carries {declared, applied, source}, so “the file said inches” is distinguishable from “I was told inches” — the distinction that matters most on pre-R14 single-line headers, which carry no units line at all.

Export — cad_export_body format:"sat"

SatWriter.fromSolid() takes one solid id, so of picks which body — like the XT transmits, a SAT file is single-body, refused otherwise by name. Analytic geometry writes as the record classes above; a body carrying B-spline geometry refuses with a SAT_WRITE_* code rather than approximating.

Try it

SAT nativecad-plate.sat 16 KB

The kernel-authored sample plate as ACIS SAT text — re-importing it through SatReader hands back the same 1 solid / 20 faces / 54 edges it left with, volume 12,296.17 mm³ exact.

Refusals are named

Eleven SAT_* reader codes plus the SAT_WRITE_* family: a binary .sab, a spline surface, a wire body, a double-sided (sheet) face, a dangling $n pointer, a cone whose half-angle fields fail the sin² + cos² = 1 check — each refusal names exactly what stopped it, with the record index and type. Attribute records are skipped silently (colour, names, application data — no geometry), and the inventory probe never throws: it reports the same refusals as data, so a file that cannot build can still be described.

Roadmap: spline surfaces and intcurves (today SAT_UNSUPPORTED_SURFACE/_CURVE) · geometric outer-loop classification on read (real files chain inner loops first; the built solid is already correct, the loop label is not) · .sab binary transmits · real vendor corpus growth beyond the two NIST fixtures.