Skip to main content

Mesh export

All evaluated outputs can produce a mesh and shared mesh formats:
MeshData contains flat typed arrays:
Each consecutive three indices forms one triangle. A reflected assembly placement reverses triangle winding during mesh transformation so outward orientation remains coherent.

Tessellation options

Exact B-Rep output is tessellated on demand:
Options affect the extracted mesh, not the exact native shape. Manifold already is a mesh representation and may ignore B-Rep-specific controls.

STEP and BREP

Use OCCT:
Unsupported native formats throw CadError with an EXPORT_UNSUPPORTED diagnostic because export() is a direct operation on a live output. Select a compatible kernel before evaluation.

Deterministic single-product STEP

This strong contract was added in 0.2.0. The 0.1.1 package retained ordinary weak native STEP export.
The bundled zero-override createOcctKernel() stock runtime advertises the optional KERNEL_STEP_EXPORT_PROTOCOL_VERSION === 1 capability. This versioned capability is stronger than nativeExports containing "step": nativeExports says only that the format can be written. Inspect the kernel’s capability object—not the kernel itself—before relying on the stronger contract:
A "valid" result contains the strong immutable snapshot; "absent" means only weak STEP availability, while "malformed" means the advertised envelope is invalid. output.export("step") without a second argument remains compatible with weak native exporters; a supporting kernel uses deterministic defaults. Passing any options object, including {}, requests the strong contract; an absent or malformed stepExport envelope throws CadError with KERNEL_CAPABILITY_MISSING instead of silently ignoring the request. The strong contract covers one STEP product. A supporting kernel that can write an output only as several products refuses the strong request with CadError EXPORT_UNSUPPORTED and details.reason === "multiple-products". The stock OCCT kernel does this for an output that holds several disjoint solids, such as a union of separated boxes or a subtraction that splits its target. Without a second argument, output.export("step") then falls back to the weak native STEP bytes instead of failing. Explicit wasm, moduleFactory, and attestedRuntime initialization remains on weak raw STEP export even when the supplied artifact is derived from stock OCCT. InvariantCAD omits stepExport until that exact writer artifact has a separate qualification boundary. Pass deterministic metadata, cancellation, and a caller-specific output ceiling through the STEP-only overload:
Each metadata override is optional; every omitted field receives one of these closed automatic defaults. FILE_NAME uses the design document name and its timestamp is 1970-01-01T00:00:00. A solid output uses its output alias for both product ID and name, with an empty description. A part uses its authored part number when present, otherwise its part-node ID, as the product ID; its part-node ID is the product name, and its authored part description is the product description. Automatic defaults never make a valid document fail to export. Document names, output aliases, part numbers, and descriptions may contain text that the rules below reject for explicit metadata, so each defaulted field is normalized instead: control characters become spaces and unpaired UTF-16 surrogates become U+FFFD. An empty required default becomes InvariantCAD Shape. When the resolved strings would exceed the metadata budget, the longest defaulted values are truncated at Unicode scalar boundaries until they fit; explicit overrides are never altered. Defaults longer than the whole budget share it in field order. Only as much authored or explicit text as the budget could hold is read, so a very long name or description costs no more work than the budget. Pass an explicit metadata field to control the exact text. An explicit timestamp must be a real calendar value in YYYY-MM-DDTHH:MM:SS form. It remains deterministic because it is caller-supplied input; changing it intentionally changes the bytes. The four identity/description values accept Unicode scalar text. Apostrophes use STEP’s doubled-apostrophe convention. Literal backslashes and non-ASCII scalars are encoded with ISO-10303-21 \X2\...\X0\ or \X4\...\X0\ directives as required. Explicit values that contain control characters or unpaired UTF-16 surrogates are rejected. Explicit fileName, productId, and productName values must be nonempty. Invalid option structure, explicit metadata text, calendar values, or the advertised authored-metadata budget throw CadError with EXPORT_OPTIONS_INVALID. Its path is a JSON Pointer relative to the StepExportOptions input, such as /metadata/timestamp or /maxOutputBytes. An already-aborted valid signal still throws AbortError; low-level kernel.exportShape(...) calls retain their kernel-specific validation exceptions. On the stock OCCT kernel, exceeding maxOutputBytes, the default output ceiling, or a fixed input, scan, or entity ceiling throws CadError with RESOURCE_LIMIT_EXCEEDED, both from output.export(...) and from low-level kernel.exportShape(...). details.resource names the ceiling (for example "maxOutputBytes"), details.limit gives its value, and details.actual gives the measured size when it is known. Those defaults are a field-specific identity mapping, not a general metadata pass-through. Root document metadata, arbitrary part metadata, material identity, and the active configuration are omitted. A caller may explicitly override a semantically corresponding supported STEP field, but protocol v1 provides no arbitrary key/value metadata channel. It does not silently fold material data into the description. For one solid or part, the stock writer emits one AP214IS product; it writes several disjoint solids as an assembly of several products, which the strong contract refuses as described above. InvariantCAD then applies a purpose-built structural ISO-10303-21 scanner and transformer to the exact FILE_NAME and PRODUCT string fields; it does not use an unbounded regular expression rewrite. The default output ceiling is 64 MiB and the combined metadata ceiling is 64 KiB measured over the five resolved strings as UTF-8. Part 21 escaping can expand that text; the expanded representation counts toward the 64 MiB output ceiling. Input traversal, scan work, and entity count also have fixed ceilings, and the scan checks cancellation. The underlying stock native writer is synchronous and necessarily materializes its original complete STEP string before InvariantCAD can apply post-write limits or observe cancellation again. Metadata shape, content, timestamp, and the authored UTF-8 budget are validated and encoded before that writer starts, so known-invalid metadata never triggers native serialization. The writer cannot be interrupted mid-call. After it returns, cancellation is checked before, during, and after bounded scanning and before successful return. maxOutputBytes limits the transformed bytes returned to the caller; it does not cap the native writer’s peak allocation or its original string. Isolate untrusted or potentially pathological native work in a disposable worker or process. Byte equality is guaranteed only for the same backend shape representation, options, resolved metadata, implementation, and exact runtime artifact. It does not claim that geometrically equivalent B-Reps serialize identically, make bytes portable as a cross-runtime cache identity, or canonicalize third-party STEP. Exact aggregate STEP for assemblies and body-set results remains unsupported; export retained single solid or part leaves explicitly.

Save in Node.js

Send from a web server

export(...) is typed as Uint8Array, which TypeScript reads as Uint8Array<ArrayBufferLike>. With the DOM library, BodyInit and BlobPart accept only views backed by an ArrayBuffer, so the snippets on this page copy the bytes with Uint8Array.from(...) before handing them to Response or Blob. The returned bytes are already detached from native memory, so the evaluated design can be disposed as soon as the copy exists.

Verified single-body import

This public workflow was added in 0.2.0. It is not present in invariantcad@0.1.1.
The public imported-body boundary deliberately covers one exact solid, not the broader staged product-document model:
createImportedBodyDocument(...) returns a CadResult; unwrap it before persisting or evaluating the document. It captures and validates the commitment but does not read, fetch, or hash the bytes. The caller computes the SHA-256 digest and exact byte length. locations are ordered hints passed to the resolver; InvariantCAD never interprets them as files, URLs, or package paths. The protocol-v1 media and unit policy is closed: The explicit format selects the native reader. mediaType is committed provenance and resolver context; it is never sniffed or used to infer the format. Healing is fixed to { mode: "none" }, and the strong kernel contract must produce exactly one valid positive-volume solid. Multiple solids, shells, loose topology, approximate conversion, and weak-import fallback are rejected. Persist only the opaque document facade:
Parsing uses the bounded, duplicate-member-rejecting document boundary and then admits only one resource, one imported-body node, and one direct solid output. It does not publish or accept the broader product Document v7 grammar. options.limits applies to the whole parse, including that subset check. A document admitted only under raised limits, such as one with more than the default 100,000 resource locations, needs the same limits when it is serialized again and as documentLimits when it is evaluated.

Imported-body document format

The JSON that stringifyImportedBodyDocument writes is a fixed, minimal subset of Document v7. It carries schema https://invariantcad.dev/schema/document/v7 and version 7, and contains exactly:
  • one resource commitment: digest, byteLength, mediaType, and optional locations;
  • one importedBody node that references that resource, with its format, units, healing: { mode: "none" }, and expected: "single-solid";
  • one output with the same name as the node, referencing it directly as a solid;
  • empty parameters and the fixed units: { length: "mm", angle: "rad" }.
It has no metadata, materials, configurations, topology references, or other nodes. The writer emits canonical bytes with object keys in sorted order, on one line by default. With an illustrative digest and a 18,342-byte file, the example above serializes with { pretty: true } as:
Read these documents only with parseImportedBodyDocument, write them only with stringifyImportedBodyDocument, and evaluate them only with Evaluator.evaluateImportedBody. General Document v7 stays repository-staged, so the general document APIs refuse imported-body JSON instead of misinterpreting it: parseDocument, parseDocumentValue, validateDocument, migrateDocument, hashDesignFeatures, analyzeDesignImpact, and Evaluator.evaluate return one IR_INVALID diagnostic at / whose hint names the imported-body functions, and stringifyDocument, hashDocument, and cloneDocument throw a TypeError with the same message. The subset is frozen. Repository tests pin its canonical bytes and their SHA-256, and a future public Document v7 will keep accepting every document in this subset with the same meaning, so imported-body JSON saved by 0.2 stays readable. Evaluation requires an exact B-Rep evaluator with the strong document-body import capability and a caller-supplied resolver:
maxResourceBytes must be a non-negative safe integer, signal an AbortSignal, and documentLimits a plain record of document limits. An invalid option returns IR_INVALID with a path rooted at /options, such as /options/resourceLimits/maxResourceBytes, before the resolver runs. Creation diagnostics name the definition field at fault, such as /name, /definition/id, or /definition/resource/digest, and parse diagnostics point into the document JSON, such as /resources/housingStep/mediaType. The resolver receives a frozen request containing the authored ID, digest, length, media type, location hints, and optional signal. Resolution, byte-length admission, and SHA-256 verification finish before importDocumentBody(...) runs. A successful EvaluatedImportedBody exposes exact B-Rep measurement, topology, tessellation, and capability-gated single-solid STEP/BREP export. Dispose that result independently; it owns the imported native shape but borrows the evaluator and kernel. This executable module creates an exact OCCT box, exports STEP entirely in memory, commits and canonically persists the one-body document, resolves the same bytes, imports them through the strong boundary, inspects measurement and topology, and re-exports deterministic STEP:
The release gate compiles and executes examples/docs/imported-body-round-trip.ts. This slice does not provide imported-body healing or repair, multiple-body selection, body sets, external components, assemblies, automatic location I/O, media-type inference, a public general Document v7 alias, or integration with the ordinary v6 design builder and evaluate(...). Those remain separate product milestones.

Browser download

Repository-only product-document staging

The ordinary v6 design builder still does not expose an imported-body or body-set feature node. The narrow public workflow above is separate from the repository-only broader product grammar. The repository contains stagedBodySetDesignV7(...), a source-only authoring facade for the exact graph admitted by the staged evaluators. This is executable Document v7 evidence, not an end-user product-document workflow: the package-root DesignDocument alias, ordinary builder/evaluator, and migration target remain on the frozen v6 model, and no package subpath exposes the facade. The public one-body facade does not make these broader types callable. The staged facade authors:
  • typed length, angle, mass-density, and scalar parameters, named parameter configurations, document-owned materials, typed part-material substitutions, and assembly-definition instance-suppression overrides;
  • direct boxes, cylinders, and spheres by privately composing the existing v6 builder;
  • owner-bound solid DAGs whose leaves are those primitives or imported bodies and whose internal nodes are ordered union(...), subtract(...), intersect(...), or transform operations, with typed translate(...), rotate(...), scale(...), and mirror(...) conveniences;
  • document-owned commitments with an explicit SHA-256 digest, byte length, media type, ordered location hints, and detached metadata;
  • owner-bound imported-body leaves for STEP with file units or text/binary BREP with an explicit mm, cm, m, or in length unit;
  • owner-bound body sets whose dense, non-empty ordered memberships reference facade-created primitive/import/Boolean/transform DAG roots;
  • owner-bound parts whose geometry is one staged solid DAG root or one admitted body set;
  • external-part handles that bind one named part output from a committed InvariantCAD document resource without publishing a local feature node;
  • external-assembly handles that bind one named assembly output from a committed InvariantCAD document resource without publishing a local feature node; and
  • acyclic nested fixed-placement product assemblies whose instances reference owned local parts, already-completed local assemblies, or either external handle and select inherited, base, or named child configuration contexts, plus outputs that directly target an imported body, body set, part, or staged product assembly.
Every imported node fixes healing to none and expects one solid. Its explicit format chooses the reader; committed mediaType is provenance and resolver context, not reader inference. The caller supplies the digest and byte-length commitments; the facade does not read or hash the resource bytes. Ordered resource locations are resolver hints only. Neither the facade nor the staged evaluators perform file, URL, or package I/O. Authoring methods validate namespaces, commitments, owner identity, material and configuration references, dense collections, and unique member IDs. Build applies caller-selected DesignDocumentLimits and strict v7 validation before returning detached, deeply frozen v7 data. Immediate authoring ceilings default to 10,000 resources, 100,000 aggregate location hints, and 16 MiB of aggregate UTF-8 location text. An individual body set is also rejected before copying above the default 1,000,000 structural-value ceiling. Caller-selected build limits can be stricter but cannot raise these immediate safeguards. Parameter, configuration, material, part, assembly-instance, placement, resource, import, unit-policy, and body-member options must be plain own-data records, and required collections must be dense. Accessor-backed and unknown fields are rejected without invocation or silent interpretation, and caller metadata is detached. The repository has four source-only staged geometry-evaluator slices:
  • A direct imported-body output admits bytes only through the caller-supplied resolver, verifies the declared byte length and SHA-256 digest, and invokes the kernel’s strong exact single-solid import contract.
  • A direct body-set output preserves authored member order, stable member IDs, optional names, and detached metadata. Every listed member is active and no member is treated as a primary body. Its solid reference may point to a box, cylinder, sphere, imported-body leaf, or a bounded Boolean/transform DAG rooted in those leaves. Shared graph nodes are evaluated once without collapsing authored memberships.
  • A direct part output preserves part metadata and effective material/density provenance while retaining an explicit single-solid or body-set geometry branch. Its geometry must be one supported solid DAG root or one body set admitted by the preceding slice. The staged facade authors exactly this part boundary through material(...), part(...), configuration .partMaterial(...), and direct part output(...).
  • A product-assembly output iteratively expands active local assemblies, resolves direct external-part outputs, and expands one fixed external subassembly boundary into its child-local part leaves. It preserves full root-to-leaf occurrence paths, root-relative placements composed parent first, and each part occurrence’s effective inherit, base, or named configuration context. Every containing assembly’s context controls that definition’s suppression and placement expressions, including explicit false unsuppression, before component admission. Active local and external leaves may use the same single-solid or multibody geometry admitted by the direct part slice, including verified imported leaves.

Document-scoped external resources

The staged product evaluator resolves external document JSON from the root document’s resource registry before resolving geometry resources declared by those children. Its resolver requests carry a frozen documentScope:
The root scope identifies commitments in the product document, including each external document. An external scope identifies the admitted child registry by the root resource ID and digest. Resolver implementations for this staged operation must use both the scope and request.id: two child documents may legitimately reuse the same document-local resource ID while resolving different committed bytes. Ordinary resolveResourcesV7(...) requests remain unscoped; documentScope belongs to this repository-only staged session, not a new public 0.2.0 resolver contract. Resolution is deterministic and two-phase. All selected external document commitments are preflighted and resolved before child assembly expansion or part preparation. Prepared child batches and kernel capabilities are then preflighted before any child geometry resource callback, and all child geometry bytes are admitted before document-body import callbacks run. Repeated (documentScope, resourceId) commitments reuse verified retained bytes; the same resource ID in a different scope remains distinct. Native primitive/Boolean/transform body sets can run on either exact or approximate kernels, and the result records the kernel representation as mesh, brep, or sdf together with its exactness claim. Stock OCCT constructs exact B-Rep geometry with partial Boolean history; a matched owned facade supplies complete bounded evolution for the current Boolean only when it proves the existing feature-scoped protocol. That promise cannot upgrade partial history already carried by an operand, and the result’s exact flag describes geometry rather than complete history. Manifold constructs approximate mesh geometry with no topology snapshots. Evaluation never falls back from one backend to the other. An imported member, including an imported leaf below Booleans or transforms, is different: the complete body set must use an exact brep kernel with strong single-solid document-body import support. Imported bytes cross the same verified-resource boundary as a direct imported-body output. There is no weak importShape(...) fallback and no automatic conversion to a mesh representation. Executable stock-OCCT evidence resolves a commitment-verified STEP box, subtracts a native tool, transforms the result, inspects partial topology, exports STEP, and restores the native ownership baseline. Separate real Manifold evidence evaluates configuration-sensitive native Boolean graphs through nested products, BOM, mass, suppression, limits, and complete cleanup. External-product OCCT evidence separately resolves a child document and its scoped STEP resource, evaluates an imported/translated/Boolean child part beside a native part through a nested local subassembly, reuses both exact child leaves across two fixed-subassembly occurrences, exports retained child solids as STEP, produces aggregate mesh/STL, and restores the native ownership baseline. The staged body-set result owns its distinct kernel shapes until disposal. Each member can produce a detached mesh and measurements. Topology and native single-body STEP/BREP export remain gated by the kernel’s separate capabilities. A shared leaf can be evaluated once without collapsing its distinct authored memberships; shared Boolean and transform nodes are memoized the same way. Aggregate tessellation preserves the authored member sequence, while aggregate STL and OBJ export are mesh-derived and therefore explicitly approximate/lossy even when the source bodies are exact. No exact aggregate STEP or BREP export is available: the evaluator does not fuse the bodies, invent a compound, or otherwise reinterpret the authored set. The selected kernel must advertise and implement boolean before resolver or shape work, and malformed optional exact-evolution metadata fails closed. A null or exactly zero-volume subtraction/intersection returns error-level EMPTY_RESULT; an impossible empty union or invalid measurement is a kernel protocol failure. Every remaining Boolean result must be classified by the kernel as exactly one body. A disjoint union or a subtraction that splits its target returns EVALUATION_UNSUPPORTED with details.reason set to multiple-bodies; loose or empty non-body topology uses non-body-topology. The evaluator does not split such a result into invented members or exchange it as a multibody file; author each body as an explicit body-set member instead. There is no staged allowEmpty option. Failure releases every distinct acquired or intermediate shape exactly once. Success keeps those shapes live until the staged design is disposed; subsequent facade and per-body solid operations then fail deterministically. The supplied kernel is borrowed and is never disposed by this operation. The staged operation bounds selected outputs, caller parameter overrides, authored memberships, distinct primitive/import leaves, all solid-graph nodes, all Boolean target/tool and transform input edges, authored transform operations, documents, and resolved resources. Repeated Boolean tool references count as repeated edges. The solid-DAG ceilings are maxSolidGraphNodes, maxSolidDependencyLinks, and maxTransformOperations, each defaulting to 100,000; maxDistinctSolids separately counts leaves. Those admission limits do not bound mesh buffers created by later facade calls; applications handling hostile or very large tessellations still need a disposable worker or process and an application-owned output ceiling. For a direct part, a named configuration can replace the authored materialId. An explicit part density still overrides the effective material density, and a legacy material label or material name is never used as a catalogue lookup. Length and density parameters first resolve in the selected configuration and may then be specialized by bounded caller overrides. The one-row part BOM and physicalMassProperties() use one uniform effective density across all memberships. Mass is additive over independent bodies: repeated aliases and spatial overlaps each contribute once per authored membership rather than being fused or unioned. The numeric result inherits the selected backend’s measurement quality; a kernel capability marked exact is not a separate proof of mathematically exact floating-point mass. Part-level mesh() and STL/OBJ export are aggregate tessellation views and are therefore approximate/lossy. Exact native export remains a per-solid or per-body capability. Multibody parts do not expose aggregate geometric measurement, exact aggregate STEP/BREP, a cross-body topology namespace, interference subtraction, or primary-body inference. Bare body sets still have no aggregate mass contract; the part supplies the uniform-density semantics. For a product assembly, repeated part instances retain distinct full occurrence paths and BOM quantities. One local part result is reused for equal (part, effective configuration) contexts; one direct external-part result is reused for equal (resource, output, effective child configuration) contexts. Fixed-subassembly leaves reuse geometry by (resource, child part node, effective child configuration). Distinct external output aliases retain distinct component, diagnostic, and BOM identity even when they select the same child part or assembly and share the same evaluated geometry. Neither optimization is a cross-run cache or geometric-equivalence claim. Aggregate product mesh, binary/ASCII STL, and OBJ apply each root-relative occurrence placement and remain approximate/lossy. Exact native export remains available from a retained child solid when its kernel supports the requested format: the stock-OCCT product evidence exports the child as STEP. The product itself rejects STEP/BREP aggregate export with EXPORT_UNSUPPORTED; evaluation does not fuse child solids or invent a compound. The contextual BOM keeps unlike component/configuration states separate, while physical mass applies each effective density and placement before combining mass, center of mass, and inertia. A suppressed assembly edge prunes its entire subtree before descendant admission or work accounting. Traversal is bounded by maxAssemblyDepth, maxOccurrencePathSegments, scanned-instance, active-occurrence, placement, and downstream part/resource ceilings. Solid-graph nodes, all Boolean target/tool and transform input edges, and transform operations are counted globally by (node, effective configuration) across active occurrences: repeated occurrences in one context share the charge, while different contexts are independent. Repeated Boolean references still charge every authored edge. An active external part or fixed subassembly is evaluated only after its committed child document has been admitted. Child inherit maps parent base to child base or a parent named configuration to the same child ID; explicit base and named selectors target the child directly. Descendant selectors, suppression, and placement expressions are interpreted inside that child document. Root caller parameter overrides never flow into it. An external-part handle must select a direct part output, and an external-assembly handle must select a direct assembly output. The latter may expand child-local parts and nested local assemblies. Each active occurrence path may cross only that one external-document boundary: a suppressed nested external component is inert, while an active one is rejected before nested resolution or child geometry/kernel work. The facade cannot construct a local cycle because it accepts only already-completed same-builder local assembly handles; strict document admission and evaluation reject hand-authored recursive local graphs. The authoring facade, all four staged geometry-evaluator slices, and the kernel-independent datum resolver remain repository-only source work: none is exported by the public 0.2.0 package root, available from a package subpath, or integrated with the public builder or CLI. The facade can author datum points, axes, planes, and coordinate systems, but they are resolved by selected node ID rather than published as design outputs or consumed by sketches or shape algebra. The facade authors direct external-part and external-assembly handles, but not a recursive external product graph. External part outputs and the local part leaves reached through one selected external assembly must still be admitted by the existing staged part evaluator; the product evaluator does not widen the child’s supported feature families. A migrated v6 part backed by an extrusion, for example, is rejected before geometry or scoped child-resource work. Cyclic local-assembly graphs, Boolean or transform inputs that are body sets, parts, or assemblies, other body-consuming operations, per-body materials, and general solid graphs beyond primitive/import/Boolean/transform DAGs remain unsupported. The facade cannot publish a direct primitive or a generic Boolean or transformed solid output either; generic solid geometry must be retained by a body set or part. The narrower imported-body handle remains the only directly publishable solid-like staged reference. The operations perform no location I/O and admit no healing beyond none. A resource’s mediaType is committed provenance passed to the resolver; it is not used to choose the reader or accepted as a substitute for the imported-body node’s explicit format. Assembly mates, motion, interference/collision, assembly-wide topology or geometric measurement, and exact aggregate STEP/BREP remain unsupported. The narrow public one-body facade applies the closed protocol-v1 format/media/unit table documented above; that policy does not promote this broader product grammar. There are deliberately two kernel boundaries:
  • nativeImports plus importShape(...) is weak exchange support. It may return any shape accepted by the backend.
  • documentBodyImport plus importDocumentBody(...) is the versioned strong boundary required by a canonical imported-body node.
Stock OCCT admits STEP only with { mode: "from-file" }. Text and binary BREP are unitless, so they require { mode: "declared", length: "mm" | "cm" | "m" | "in" }. Protocol v1 requires { healing: { mode: "none" } }.
This low-level call snapshots the supplied bytes but does not verify a document resource digest. Every staged evaluator that admits an imported leaf composes the existing resolver and strong importer: byte-length and SHA-256 admission completes before the imported parser is called. Missing resolvers, failed resolution, integrity mismatches, limits, cancellation, unsupported capability combinations, and kernel failures remain structured diagnostics. The strong importer requires exactly one valid, positive-volume solid with no loose topology and reports only partial imported history. It does not invent stable feature lineage or authored topology roles. Native STEP/BREP parsers can allocate or execute beyond JavaScript byte limits. Applications handling hostile files still need a disposable worker or process boundary; cooperative cancellation cannot preempt a synchronous native parser.

Exchange is not artifact caching

STL, OBJ, STEP, and BREP are interoperability formats. They do not preserve the complete evaluator wrapper state, topology evolution history, analytic overrides, or compatibility fingerprint needed for transparent feature-cache reuse. See design impact and hashes.