A solid produced by a feature: its resident handle, its solid name, and its
named faces/edges ((topology_id, name)). the caller tessellates/pulls names via the
handle; the scene-map registers the names for downstream reference resolution.
The document’s assembly block: the ordered constraint list plus the
persistent id counter (monotonic, never reused — mirrors the feature
counter’s contract).
A named world-space line — a revolve/sweep axis. Published by SKETCH features
(every sketch line geometry, construction included) and resolvable from a
resident solid edge, so an axis/path reference resolves fully headless.
One scene component: an ACOMP instance’s identity, pose, and member solids.
Rides the crate::feature_pipeline::FeatureResultcomponents side-channel
into [SceneMap::apply], exactly like profiles/frames — the scene’s component
set is rebuilt from feature results every history run (a projected view,
never an owning data structure).
One persisted constraint: { type, inputParams, persistentData, enabled, open }. inputParams carries id, elements (selection ref strings) and
the type-specific params; persistentData is the solver-state merge target
(status/message/diagnostics/orientation cache).
Mass properties scaled to a physical density (Golovanov §8.11). The
underlying FullMassProperties is a UNIT-density geometric result; here
mass = density * volume and every inertia quantity scales linearly with
density (inertia = density * geometric_inertia). The centroid and the
principal AXES are density-independent; only the principal MOMENTS and the
mass scale with density.
The expression environment: the variable bindings produced by evaluating the
prelude (resolution = 32), the injected configurator object, and the
user’s expressions statements in order.
One feature as serialized by PartHistory.toSerializable. Permissive: unknown
fields are ignored, so an entire saved part file’s features[] deserializes
as-is. input_params stays a serde_json::Value (an object) so features read
their own params with their own type knowledge (which params are numeric).
The execute_history_json request: the expression source, the configurator
state, and the ordered feature list. Permissive — a whole saved part file
parses as a request (extra top-level fields ignored).
A deviation measured between a constructed entity and the geometry that
entity was built to reproduce, recorded next to the derived band it was
judged against.
Segmentation result: triangle_region_ids[t] is the region id of input
triangle t (index into regions; UNASSIGNED_REGION for degenerate
triangles with no assignable neighbor).
One unique part payload (spec §2.1). dirty is RESIDENT-ONLY state: set by
refresh_library_entry (edit-in-context / update-components), it forces
the ACOMP self-heal lane on the next run even with a readable snapshot, and
clears when the heal rewrites the snapshot.
The placement anchor a path sweep transplants its profile with: the plane
frame (origin = boundary-sample centroid, normal, pu, pv) the station
loop maps profile points through (local = p − origin → station + ri·(local ·pu) + si·(local·pv)). Extracted as data so a HOLE loop can sweep with its
OUTER loop’s anchor — sweeping each loop with its OWN centroid would
re-center every loop onto the path and lose the hole’s in-plane offset.
One closed boundary of a SketchProfile: head-to-tail world-space curves plus
the per-curve source edge name ({sketchId}:G{gid}, parallel to curves). The
profile-consumers stamp sidewall names from edge_names (extrude → {name}_E).
The output of restore_solids: solids in snapshot order plus the
captured scene-metadata records (entity name -> own record), NOT stamped
into the store — see the metadata seam in the module doc.
Frame, generatrix, and sweep of any surface built by make_revolution
(full or partial), validated by exact reconstruction. Unlike
AnalyticSurface this does not require the generatrix to be a line or
classic quadric profile.
Options for segment_mesh_faces. All tolerances are dimensionless or in
degrees; distances derive from the region/mesh scale so the segmentation
is size-invariant.
A solved sketch’s extracted profile, placed in 3D. Produced by the SKETCH
pipeline feature and consumed BY NAME by the profile-consumers (extrude,
revolve, loft, sweep, rib, sheet-metal tab/contour-flange) — the exact-BREP
replacement for the old “marshal the resolved curves into inputParams”.
Point-in-solid classification with per-solid precomputation: face
bounds, the solid box, and a face BVH are built once so repeated
queries (boolean fragment selection asks once per fragment) prune to
the few faces a probe point or ray can actually touch.
A solid encoded as one flat Float64Array plus a tiny JSON side channel
for face/edge names — the zero-JSON result path for topology-heavy ops.
Getters consume the buffers (each may be read once) to avoid double copies.
Which branch of offset_surface built a carrier — and, with it, whether
comparing that carrier against the pointwise offset at the same (u, v) is
even the right question.
Recognized analytic carrier of a region. Axis directions are unit
vectors; sense is +1 when the mesh normals point along the carrier’s
outward normal (away from the axis/center) and -1 for a cavity.
Typed resolution failure. Self::status maps each variant onto the
constraint status vocabulary (requirements §5) so the constraint lifecycle
reports it without string-matching messages.
A resolved analytic selection frame, in the coordinate space of the solid
it was resolved from (module docs: pass the component’s world→local inverse
to Self::transformed for the solver’s component-local mate inputs).
A closed analytic tool region used to cut a body. Each variant is realised
as a closed solid (unbounded carriers are capped well beyond the body) whose
interior is one side of the analytic surface.
A boolean is FLAGGED structurally wrong when its decidable-point
disagreement rate exceeds this. Tuned from the measured spread (fixed-seed,
so these numbers are stable): every KNOWN-GOOD boolean scores ≤ 0.7% (a
handful of stray points on the fused seam of tangent/glue unions), benign
doubly-curved cases (sphere/torus tubes) top out near 1.7%, while a genuine
structural defect — a mis-selected fragment, a lost overlap region, an
opened shell — flips a whole region and scores ≥ 7%. The 3% line sits
cleanly in the gap: above the near-boundary noise the On-skip + threshold are
meant to absorb, well below any real wrongness. One named constant so the
audit, the tests, and the stress binary share a single definition of “wrong”.
Fraction of the local characteristic length an APPROXIMATE offset
construction may deviate from the exact geometry it approximates — see
offset_construction_band.
Bumped whenever the container layout changes. A mismatch is always a clean
Err — the self-heal signal for a snapshot whose part document can be
re-executed. For a payload that IS the document (nativeBrep) that Err is
unrecoverable, so per the durability commitment in the module doc a bump MUST
ship a reader for the previous version, or a migration.
Absolute floor (mm) of the edge-endpoint-vs-vertex identity band used by
BrepSolid::validate: below this a curve end and its topological vertex
ARE the same point (vendor export precision), above it the model is asked to
state the meeting exactly.
INSERT: hand the opened sub-part document over to the library. Executes the
document once, snapshots, stores the entry, and returns the EFFECTIVE part
name (the ACOMP partName the app must reference):
Exact 3D image of a pcurve on an AFFINE sheet: an affine map applied to
the homogeneous control points commutes with the rational evaluation, so
the image shares the pcurve’s degree / knots / weights and is
parametrized identically — a rational circle pcurve maps to the exact 3D
circle.
apply_edge_splits plus the identity ledger: original edge id → the
minted sub-edge ids that replaced it. Consumers keyed on ORIGINAL edge
ids (the fragment-selection barrier set) must remap through it, since the
split solid’s coedges reference the minted ids.
Add a constraint of constraint_type with the given inputParams JSON
(elements etc.; id is minted from the type’s short name + the persistent
counter when absent). Auto-solves; returns {id, report}.
Fold the session’s solved state into a history DOCUMENT: replaces the
top-level assembly block and writes each pending pose / grounded flag
into the owning feature’s inputParams (matched by inputParams.id —
generic JSON, no dependency on the ACOMP feature shape). The app calls this
on its document before persisting or re-running (the pose-authority
write-back, spec §6 step 4).
Overlay geometry for the viewport graphics lane: per enabled constraint,
the resolved WORLD anchor points/directions/geometry classes (post-solve),
the status, and the evaluated value — [{id, type, status, message, anchors, directions, geoms, value, unit, target}]. Constraints whose
selections do not resolve emit status/message only (no anchors).
Audit the serialized entity graph rather than assuming that valid
in-memory topology was necessarily written correctly. Every EDGE_CURVE
in a closed shell must have exactly two ORIENTED_EDGE users with opposite
senses.
Audit the curve-on-surface half of the emitted graph, on the serialized
text, for the same reason audit_step_manifold exists: valid in-memory
intent is not proof of a correctly written file.
Variable-radius blend (4.9.5): radius stops as (edge fraction, radius)
pairs, linearly interpolated along the edge parameter and clamped at
the ends. Closed edges must supply matching first/last radii.
Blend a chain of conjugated edges with one rolling-ball blend face
(Golovanov §6.9.5: all conjugated edges processed together). A CLOSED
chain (stadium rim, T-pipe saddle) welds into a periodic blend; an OPEN
chain (line->arc->line capped by end faces) rolls a clamped blend that
terminates in a transverse edge on each end face.
Boolean of two resident solids -> a NEW resident handle. The result never
crosses the boundary as topology; only its handle is returned. Kernel-produced
result is trusted (no double-validate).
Native sibling of boolean_handle (String errors — constructing a
JsValue error panics off-wasm): boolean of two RESIDENT solids → a NEW
resident handle, operands untouched. The assembly interference check’s
non-destructive INTERSECT lane; callers free the result handle when done.
Part 2 — the fuse-after detector. Any geometry in result that is
coincident within tol yet NOT topologically shared is an intersector /
assembler bug: the weld pass should have fused it. Reports distinct
vertices at one point and duplicate coincident edges. Purely diagnostic.
Part 1 — the semantic cross-check. Sample points across the combined box of
first ∪ second, classify each versus the two operands and the result, and
flag every decidable point where the result membership disagrees with the
CSG expectation for operation. See the module docs for the sampling /
On-skip / threshold design.
N-ary semantic cross-check — the correctness gate for
crate::boolean_operation_nary. Sample points across the combined box of
all operands, classify each versus every operand and the result, and flag
every decidable point where the result membership disagrees with the n-ary
CSG expectation (Union = In any, Intersect = In all, Subtract = In
operand 0 and Out of the rest). Points on or near ANY operand or result
boundary are skipped, so a correct n-ary boolean scores ~0.
Build a pcurve for a represented subrange of a larger edge curve. Unlike
trimming the curve’s homogeneous control net, this samples only the
represented interval, which is essential when off-interval control points
do not lie on the target carrier.
Diagnostic “carrier preview” patch (§3.15 applied to display): re-express
the surface over an INFLATED domain so an inspector can show where the
carrier continues beyond the face’s trim. Open directions inflate about
the domain centre by inflate (a factor; 1 = unchanged), evaluated
through evaluate_extended — exact linear extension for affine carriers,
ruled/tangent extension generally. CLOSED (periodic) directions keep the
stored full period instead of inflating — wrapping further would overlap
the surface onto itself. A torus (closed both ways) returns unchanged.
Diagnostic carrier preview: re-express a surface over an inflated domain
(open directions inflate about the centre via extended evaluation; closed
directions keep their full period). inflate <= 0 defaults to 2.
Distance-angle chamfer of one STRAIGHT edge between two planar faces
(Golovanov §6.11): setback d1 along face 1 and angle angle_rad between
the chamfer face and face 1. d2 is constructed geometrically in the
cross-section plane (see chamfer_angle_second_distance), then the
two-distance builder is applied.
Asymmetric (two-distance) chamfer of one STRAIGHT edge between two planar
faces (Golovanov §6.11): setback d1 along face 1 and d2 along face 2 —
the standard CAD “d1 × d2” bevel. General/curved edges are out of scope for
this slice and return a clear error.
Distance-angle chamfer of a GROUP of edges, the app entry: each selected
edge (resolved by a point on it) gets a setback d1 on face 1 and a chamfer
face at angle_rad from face 1 (§6.11); d2 is constructed per edge.
Asymmetric (two-distance) chamfer of a GROUP of edges, the app entry: each
selected edge (resolved by a point on it) gets a d1 × d2 bevel (§6.11).
Edges are chamfered independently — asymmetric chamfers keep sharp vertices,
so there is no shared-corner blending.
Parameter of the standard tangent-intersection rational quadratic arc
construction (make_arc / make_revolution): a sweep split uniformly
into spans segments, each with middle weight cos(segment/2). Maps an
angle in [0, sweep] to the curve parameter in [0, 1] exactly.
Classify a pair before generic SSI runs. The classifier is conservative:
only separated control hulls are declared disjoint; uncertain pairs stay
Candidate rather than being incorrectly culled.
The nine constraint schemas, spec §4 order. number params are
expression-capable against the part’s expression scope (the dialog engine’s
established convention).
Exact 3D arc length of a NURBS curve over the parameter range [t0, t1] —
∫|C’(t)| dt evaluated with a composite 8-point Gauss–Legendre rule paneled at
the curve’s interior knots (each knot span further halved for headroom). The
speed integrand |C'(t)| is polynomial-exact for the line/circle-arc curves
the kernel emits and converges tightly for general NURBS. Returns 0.0 for a
zero-width (or inverted) range.
Golovanov §6.12 — delete a transition face and heal the hole by extending
and re-intersecting its immediate neighbours. See the module docs for the
covered vs deferred cases. Returns a fresh solid that is guaranteed to
validate(), or a clear Err describing why the heal was refused.
The app’s display chord tolerance (BetterSolid._kernelTessellationOptions):
vertex |coord| extent — falling back to the control-point hull / sqrt(2) for
vertex-free solids (full spheres/tori) — times 1.5e-3, times the render-LOD
factor (1.0 = the app’s “Normal” preset).
Native display payload for a resident solid: watertight mesh + face list (in
mesh face_ids order) + edge polylines + vertices, all in one registry
borrow. lod_factor scales the per-solid display chord tolerance (1.0 = the
app’s “Normal” preset; higher = coarser mesh). Callers pass a sanitized,
finite, positive value — display_chord_tolerance multiplies it in directly.
One-shot: build an Env from a history’s expressions source + its
configurator JSON, then evaluate source to a scalar. The small surface the
engine-native sketcher’s live dimension-value edit uses (deliverable S5.0) —
equivalent to Env::build(expressions, configurator_json)?.eval(source).
Run a whole feature history incrementally: build the expression env once,
then walk the ordered features. A CLEAN feature (see the cache section above)
replays its cached result; a DIRTY one re-executes (its old outputs are freed
first). On a feature error, record it and HALT (abort-on-error);
errored results are never cached. Never panics.
Deserialize a history request, run it, and serialize the per-feature results.
The handles in the result are u32s the caller tessellates / pulls names
from via the existing *_handle wasm exports.
Native: export the CURRENT resident solids (by handle) to an IGES 5.3
document of trimmed NURBS surfaces. The IGES analogue of
export_step_handles — reads the resident solids out of the thread-local
registry, clones them into a Vec<BrepSolid>, and hands the batch to
export_iges. String error (JsValue-free — links on native and wasm).
Native: export the CURRENT resident solids (by handle) to an ISO-10303-21
STEP document. Reads each resident solid out of the thread-local registry —
the SAME registry display_payload_handle_native reads — clones them into
a Vec<BrepSolid>, and hands the batch to export_step. The engine-native
app’s Export→STEP lane calls this with the handles the pipeline left resident
after the last history run, so the topology never crosses a boundary as JSON.
String error (JsValue-free — it links + runs on native and wasm alike).
Straight extrude of a LINE/ARC profile loop with a draft (taper) angle,
built DIRECTLY as a BREP: every wall is the EXACT drafted surface of its
segment — a tilted plane for a line, a cone patch (rational ruled surface
between the source arc and its concentric offset, over one shared angular
window) for a circular arc — and every junction edge is the EXACT
intersection curve of the two adjacent walls. Because all drafted walls
shrink linearly at the same rate, any two of them intersect in a straight
line (plane∧plane, or a tangent-junction ruling) or a CONIC (plane∧cone and
cone∧cone both reduce to a plane section of a cone — the z² terms of the
squared implicits cancel), so the junction edges are exact rational
quadratics: no lofted approximation anywhere.
Total 3D arc length of a face’s boundary edges: the unique edges referenced by
the face’s loop coedges, resolved against the owning solid’s edge table and
summed once each. An edge referenced twice by the same face (e.g. a seam) is
still counted once.
(area, boundary_edge_total_length, surface_type) of a resident solid’s
named face (mm² / mm / classification): the face’s surface area, the summed
arc length of its boundary edges, and a short label for its underlying
carrier surface ("Plane", "Cylinder", "Cone", "Sphere", "Torus",
"Surface of revolution", or "NURBS" when the exact rational patch is not
a recognized analytic carrier). Errs if no face carries face_name.
The resident solid’s face id -> name map (Stage 1b; lets the host rebuild its
selection/name index from a handle without materializing the full graph).
Assemble the catalogue from every feature’s own schema(). The assembly
constraint schemas (build-spec §4) join the export under their own
assemblyConstraints namespace so the dialog engine renders them with the
same machinery.
Fillet (or chamfer) a GROUP of edges as ONE operation, and — for fillets —
round the convex “star” vertices where three or more of the selected edges
meet (Golovanov §6.9.7). This is the whole multi-edge fillet in a single
kernel call: the caller passes the object plus one 3D point on each edge,
and the kernel orchestrates the filleting and corner blending against the
full topology (so acute corners resolve coherently instead of being
stitched edge-by-edge by the app). A corner the kernel cannot round (e.g.
non-orthogonal beyond support, or a general no-common-ball star) is left as
the edge fillets rather than failing the whole group.
Variable-radius fillet/chamfer of a GROUP of edges (§4.9.5), the app entry
for tapered blends: each selected edge (resolved by a point on it) is
blended with the SAME radius profile radii — a list of (edge-fraction,
radius) stops in [0,1] — applied along that edge’s own parameterization.
Edges are blended independently (no shared-vertex corner rounding; a
variable-radius star has no single tangent ball), so this is the tapered
counterpart of fillet_edges for the constant case.
Fillet (or chamfer) a chain of edges under a composable radius law
evaluated on the chain’s cumulative arc-length abscissa (the OCCT
Law_Composite model; see crate::law::RadiusLaw). The selected edges
must form ONE OPEN CHAIN (or be a single edge); the chain starts at the
free end of the earliest-selected end edge, and the law’s abscissa maps
proportionally onto the chain’s measured arc length (a law built with the
chain’s own lengths — e.g. crate::law::RadiusLaw::from_vertex_radii —
maps 1:1). Endpoint radii are met exactly; radii at shared chain vertices
match by the law’s continuity, so the per-edge blends miter through the
corners; a chain whose blends cannot be mitered REFUSES rather than
distorting the law through the sequential rebuild.
The natural per-vertex user model: radius vertex_radii[i] at chain
vertex i (in CHAIN order, starting at the free end of the
earliest-selected edge), smoothly interpolated along the chain
(monotone C1 — every vertex radius met exactly, no overshoot). Requires
exactly one radius per chain vertex (edges + 1).
Export the flat pattern of the sheet-metal body handle as DXF (R12 ASCII).
Runs the unfold TRANSIENTLY off the resident tree — no feature, no history
mutation. Errors if the handle carries no sheet-metal tree.
Import Wavefront OBJ text as a faceted (planar-triangle) BREP solid.
tolerance <= 0 derives the vertex-weld band from the model’s
bounding-box diagonal.
Public entry: parse a STEP Part 21 document and return one BrepSolid per
MANIFOLD_SOLID_BREP, FACETED_BREP, or certified BREP_WITH_VOIDS. Every
returned solid passes validate().
Import an ISO-10303-21 (STEP Part 21) document and return the reconstructed
kernel solids as a JSON array of BrepSolid records. Round-trips exactly
what export_step writes; unsupported entities yield a clear error string.
INSTALL a library wholesale — the app → history-runner channel (the runner
owns its own thread-local store, and the per-run request no longer carries
the block, so this is how a background thread/worker learns the library).
EXACT closed (periodic) cubic interpolation. points are the S >= 4
distinct stations (first NOT repeated); parameters has S+1 strictly
increasing values whose last entry closes the period. The cyclic
collocation system is solved densely (S is small for lofts), and the
periodic B-spline is re-expressed in CLAMPED form by Boehm-inserting the
domain ends to full multiplicity — the representation every kernel
consumer expects — so the seam is C² by construction, not by welding.
Cubic interpolation with PRESCRIBED end derivatives (Piegl–Tiller §9.2.2):
n+1 points plus two tangent rows give n+3 clamped control points. The
derivative conditions use the exact clamped end forms
C’(t0) = p/(u_{p+1}−t0)·(Q1−Q0) and C’(t1) = p/(t1−u_{m−p−1})·(Qn−Qn−1),
so the requested tangents are reproduced exactly — the §5.8 loft tangency
building block.
Exact intersection curves for recognized analytic pairs, or None when
the pair is not handled and the caller must fall back to SSI marching.
Some(vec![]) means “provably empty” and skips marching entirely.
Whether the resident solid handle carries a sheet-metal tree — the
SheetTree-free predicate the export lane filters resident solids with (so the
native engine picks the flat-pattern target without touching SheetTree).
§5.8 CLOSED loft: the sections form a RING (the last flows back into the
first), producing a capless genus-1 solid. Every interpolation column runs
through interpolate_curve_closed, so the ring is C² across the closure —
not a welded seam. Topology per skin is the cylinder-wall rectangle turned
on its side: u runs along the section curve (open), v through the sections
(closed); the section-0 curves themselves serve as the doubled v-seam
edges and the corner rings (one closed curve through every section at each
section corner) are shared between adjacent skins.
Rotation-to-frame guided loft (§5.8): like loft_profile_brep_guided, but
intermediate sections ROTATE with the guide’s rotation-minimizing moving
frame (double-reflection RMF, the same frames the path sweep uses) instead
of keeping their world orientation.
§5.8 loft with END TANGENCY: the skin leaves the first section along
start_direction and arrives at the last along end_direction (unit
directions; each interpolation column scales them by its own chord length,
the standard magnitude that keeps the v-parametrization well conditioned).
Exact by construction — the column interpolant reproduces the prescribed
end derivatives.
Exact arc of the hyperbola branch x²/a² − y²/b² = 1, x > 0 in the local
frame (center at the origin, major_axis = +x, minor_axis = +y),
parametrized P(t) = (a·cosh t, b·sinh t) and trimmed to t ∈ [t0, t1].
A single rational quadratic Bézier is exact for any sweep on one branch:
endpoints on the curve, middle control point at the intersection of the
end tangents, and middle weight cosh((t1−t0)/2) chosen so the shoulder
point lands back on the branch. Only the point set is hyperbola-exact
away from the ends; the NURBS parameter coincides with the hyperbolic
parameter t exactly at t0, (t0+t1)/2 and t1.
Exact parabola segment y² = 4·focal·x in the local frame (vertex at the
origin, axis = +x, latus_direction = +y), parametrized the standard
way P(t) = (focal·t², 2·focal·t) and trimmed to t ∈ [t0, t1]. A parabola
segment is a plain quadratic polynomial in t (all weights 1), so a single
degree-2 Bézier over the knot span [t0, t1] reproduces both the point set
AND the parametrization exactly — no fitting, and evaluate(t) == P(t) for
every t, not just at the ends.
Full mass properties of a resident solid, scaled to density (the native,
non-wasm sibling of mass_properties_handle for the in-process renderer):
volume + surface area + centroid + centroidal inertia tensor + principal
axes/moments (Golovanov §8.11). The underlying geometry is unit-density; here
mass = density * volume and every inertia quantity scales linearly with
density (centroid + principal axes are density-independent). density is in
mass units per mm³ (the kernel’s length convention is millimetres); pass
1.0 for the raw geometric result (mass == volume). Reads the solid in one
registry borrow; the topology never crosses a boundary.
Like merge_same_surface_faces, but any face whose name CONTAINS one of
keep_unmerged is pinned: it never merges with a coplanar/cosurface
neighbour and is emitted unchanged, while every other face merges exactly as
merge_same_surface_faces would. An empty keep_unmerged is identical to
the plain call.
Rebuild a BrepSolid whose faces are the mesh’s segmented regions. The
result always passes full topology validation (watertight edge pairing,
Euler accounting, pcurve consistency) or the call returns Err — an
invalid solid is never returned. See the module-level v1 scope notes.
Build a faceted (planar-triangle) BREP solid from a triangle soup or an
indexed triangle mesh — the STL/mesh import entry (§8.6 inverse: mesh →
body). Vertices weld within tolerance (pass <= 0 to derive it from the
bounding-box diagonal), duplicate and degenerate triangles are dropped,
surplus sheets at non-manifold edges are pruned, and remaining boundary
cycles are capped with a fan so the result closes watertight whenever the
input is close to a manifold. Validation is authoritative: an input too
broken to close returns an error, never a silently-invalid solid.
Reflect an exact BREP across the plane through plane_point with unit
normal n = plane_normal.normalized(). The reflection is the affine map
p' = R p + t with linear part R = I - 2 n nᵀ and translation
t = 2 (plane_point·n) n, so points on the plane map to themselves. A
reflection has negative determinant (it flips handedness), so faces are
re-oriented via the existing transform with reverse_orientation = true,
keeping outward normals.
Encode solids as a native IMPORT3D payload: stamp the names this feature
would stamp under feature_name, then seal them into the io/snapshot
container. The result is exactly what the nativeBrep source above reads
back, so a part is named identically however it arrived — imported live from
a text source, or restored from a payload built here.
The band an approximate offset construction is judged against: 0.05% of the
caller’s local characteristic length, floored at
OFFSET_CONSTRUCTION_FLOOR.
Push a CYLINDER or CONE face along its outward normal by distance (positive
grows the solid) by OFFSETTING its carrier surface and re-deriving the trim as
the intersection of that offset surface with the neighbour carriers.
Push a SPHERICAL face along its outward normal by distance (positive grows
the solid) by replacing its carrier with the concentric offset sphere and
re-trimming its neighbours: planar caps through the centre keep their exact-
scale great-circle rim, while off-centre planes, spheres, and coaxial ruled
neighbours have their rim re-derived as S′ ∩ neighbour.
Construct the same fitted offset carrier surface as the reference shell
implementation. Positive distance follows its convention and moves
opposite the face’s outward normal.
The current library in the partsLibrary block shape (spec §2.1) — what
SAVE must serialize into the document (never the loaded block: this copy
carries healed snapshots, refreshes, and GC).
A CLONE of the root store — what the app hands a runner through
install_parts_library. (parts_library_json is the SAVE door; this is
the in-process one, with no JSON round trip on the native paths.)
Project a point onto a surface starting Newton from an explicit (u, v)
guess, WITHOUT the global grid seed. This is a footpoint refiner for
continuity-preserving curve-on-surface tracing: seeding each edge sample
from its neighbour’s parameters keeps the fit on ONE branch of a surface
that folds back over the small trimmed patch, where an independent global
search would snap to whichever fold is momentarily closest and tear the
pcurve into a self-crossing zig-zag. The caller compares the returned
distance against the global answer and only adopts this result when it is
geometrically just as valid, so a bad seed can never make a fit worse.
UPDATE (update-components / edit-in-place commit): replace an existing
entry’s document + signature and mark it DIRTY. The next history run’s
ACOMP self-heal lane re-executes the document, re-snapshots, and every
instance of the part follows.
Ingest a solid from the flat f64 codec into the resident registry (arena +
validate kept — external / first-crossing ingest). Returns an opaque handle.
Whole-component representative point: the center of the aggregate AABB of
every face surface’s control-point hull (plus topology vertices) across the
component’s solids. The hull BOUNDS the exact surfaces (convex-hull
property) without touching tessellation; it overshoots curved faces, so
this is a representative anchor for coincident/parallel-with-component
semantics, not an exact bounding box.
Resolve a component-LOCAL topology name (already namespace-stripped)
against one solid: faces first, then edges. Names never collide across the
two kinds under the deterministic-naming scheme; the order only settles
pathological ties.
Resolve a vertex selection by position (vertices have no kernel names; the
renderer references them by owning solid + position). Nearest topology
vertex wins — deterministic when two vertices are close — then the
scale-relative snap tolerance gates acceptance; the returned point is the
EXACT vertex position, not the query.
Revolve with caller-supplied names. side_names is aligned with the
INPUT curves; the kernel carries it through winding normalization and
axis-curve skips, which the caller cannot reconstruct from the emitted
face order. cap_names is [start_cap, end_cap] for partial
revolutions. Empty slices leave faces unnamed.
§6.9.7 vertex (“star”) blend: round a convex trihedral corner whose three
incident edges are ALREADY filleted, by pure topology surgery — no
booleans. corner is the ORIGINAL sharp corner coordinate (already
trimmed away by the edge fillets). A spherical octant of radius,
tangent to all three cylindrical fillets along their tangent circles, is
sewn into the notch; the three fillet loops are closed on those tangent
circles and the leftover flat caps are removed.
Display edge polylines for native in-process consumers (brep-render): every
NON-degenerate edge’s chord-tolerance samples as (edge_id, points), sorted
by edge id so the output is deterministic (the sample map is a HashMap).
The samples are the same shared samples the watertight tessellation uses, so
the displayed edges lie exactly on the mesh’s face boundaries.
Compute every edge’s shared samples and serialize them into a flat f64
buffer for transfer to face-range workers. Layout:
[edge_count, (edge_id, sample_count, frac_0..n, x_0,y_0,z_0, ...), ...]
(fractions.len() == positions.len(), so one count per edge). Edge ids ride
as f64 exactly as the solid codec already carries them.
Segment a triangle mesh into smooth regions and recognize each region’s
analytic carrier. positions are xyz triples; indices is a triangle
index buffer, or empty to treat positions as a raw soup of consecutive
triangles (the binary-STL layout of read_binary_stl).
Native display payload for a whole committed SKETCH: its profile SHEET (when
the sketch closes a region) PLUS every model SEGMENT the sheet does not
already draw.
Native display payload for a solved sketch PROFILE — the SHEET-SOLID view of a
committed sketch: a planar FACE mesh + its named boundary EDGES + corner
VERTICES, so a sketch is pickable / selectable / measurable through the exact
same display path as a real solid. NO solid is registered — the payload is
synthesized directly from the profile, so it owns no scene handle (the display
carries source_handle = 0).
Serialize (name, solid) pairs into one base64 snapshot payload. Captures
each entity’s OWN scene-metadata record (solid name + every face/edge name)
alongside the geometry, so a stamped part restores with its metadata. The
payload is byte-deterministic for identical input (solids in caller order,
metadata sorted by name).
Total 3D arc length of every non-degenerate edge of a solid (each shared edge
counted ONCE — the solid’s edge table is already edge-unique). This is the
solid’s “total edge length” measurement.
Total 3D arc length (mm) of every non-degenerate edge of a resident solid —
the Properties panel’s “total edge length” measurement. Native sibling of the
mass-properties accessors; one short registry borrow, topology never crosses
the boundary.
Escape hatch: pull a resident solid’s full topology across the boundary (for
STEP export or JSON-only lanes during the migration). Prefer handle-native
ops — this re-incurs the serialization cost the registry exists to avoid.
Area, volume, centroid, and centroidal inertia (unit density). Area and
volume use the same exact paths as solid_mass_properties; the moment
integrals use divergence-theorem surface quadrature (exact for untrimmed
spans, trim-polygon scanline accuracy for trimmed faces).
model_scale of a solid’s vertices — the RAW bounding-box diagonal, with
no >= 1.0 floor. This is what direct-edit wants: a sub-unit part must keep
sub-unit bands. (BrepSolid::validate wants the same thing and still
hand-rolls it, for the reason its own comment gives — it answers 0.0, not
1.0, for a vertexless solid. Reconciling that contract is a follow-up, not
a free ride-along.) Use solid_scale for the floored variant the
tolerance policy is built on.
solid_model_scale floored at 1.0 — the characteristic length
KernelTolerances::for_solid and the boolean/imprint/heal sites are tuned
against. The floor keeps a unit-and-below part on the historical bands those
call sites were fitted to; new size-relative sites should prefer the unfloored
model_scale family and floor explicitly where they mean to.
Exact signed volume only — same per-face integration paths as
solid_mass_properties but without the surface-area pass. The boolean
assembly orientation gate consumes only the volume sign, and the area
integral costs as much again as the volume one.
Split a possibly-namespaced topology name into its ACOMP…: component-id
chain (outermost first) and the remaining component-LOCAL name. A segment
is peeled only when it matches ACOMP<digits> AND is followed by :, so a
bare whole-component reference stays in the LOCAL position — callers detect
it with is_component_reference:
Split PINCHED vertices — points where two (or more) umbrella fans of
faces meet at a single vertex record. Local manifold checks (edge use
counts, loop closure, orientation) cannot see a pinch; it surfaces only
as an odd Euler characteristic. The link of a manifold boundary vertex is
a single edge-connected fan: union incident edges through every loop
CORNER at the vertex (consecutive coedges meeting there inside one face);
more than one component means distinct fans sharing the record — give
each extra fan its own vertex at the same point and reassign that fan’s
edge endpoints. Geometry is untouched; only identity is repaired.
Split solid by the analytic carrier of a selected face surface
(Golovanov §6.4). The face may be a plane, cylinder, cone, or sphere; the
carrier is extended to fully span the body. Returns the two pieces
([below, above] for a plane, [inside, outside] otherwise). Errors on
non-analytic / general-revolution faces, or when the carrier does not
cleanly divide the body.
Cut a solid by the analytic carrier of a selected face’s surface (Golovanov
§6.4). The face may be a plane, cylinder, cone, or sphere; the kernel
recognizes its analytic type and extends it to span the body. Returns
{ "pieces": [<below/inside>, <above/outside>] }. Errors on non-analytic
faces or when the carrier does not cleanly divide the body.
Split solid into two pieces by the plane through plane_point with normal
plane_normal. Returns (below, above) where below is the piece on the
−n side of the plane and above the piece on the +n side.
Cut a solid by a plane (Golovanov §6.4). Returns { "below": <solid>, "above": <solid> } — the −n and +n pieces of the split. Errors with
“plane does not intersect the solid” when the plane misses the body.
Cut a solid by an analytic tool surface (Golovanov §6.4). The request is
{ "solid": <solid>, "tool": { "type": "cylinder"|"sphere"|"cone"|"torus"| "plane", ... } }. Returns { "pieces": [<inside>, <outside>] } (for a
plane, [below, above]). Errors with “tool surface does not divide the
solid” when the tool does not cleanly cut the body.
Sweep a CLOSED PLANAR profile along a CHAIN of path curves joined
head-to-tail — the multi-segment entry point, with the twist and anchor
options the single-curve family exposes as separate functions folded into
one signature (the feature layer picks all three per loop, so splitting them
four ways here would only push the same match into the caller).
Sweep a CLOSED PLANAR profile loop along a path curve (§3.3/§5.7),
TRANSPLANTING the profile onto the path — see SectionPlacement for the
other reading, and for why the choice changes the solid.
sweep_profile_along_path with an explicit placement anchor (see
ProfileAnchor) — the hole-loop cutter path: the swept loop is validated
as usual but PLACED in its outer loop’s frame.
Helical sweep (§5.7): sweep a CLOSED PLANAR profile loop along a helix of
helix_radius about the axis through axis_origin with direction
axis_direction, rising pitch per revolution for turns revolutions.
Twisted path sweep (§5.7): identical to sweep_profile_along_path, but
the profile additionally ROTATES about the path tangent, linearly in ARC
LENGTH, from 0 at the sweep start to twist_angle radians (right-handed
about the tangent) at the end. The arc-length fraction comes from the
sampled station polyline, not the raw path parameter, so a non-uniformly
parameterized path still twists uniformly in space.
sweep_profile_twisted with an explicit placement anchor: the hole loop
twists about the SAME path axis as its outer loop (shared anchor), so the
cutter stays registered with the outer wall through the whole twist.
As tessellate_brep_watertight_face_stride, but the caller supplies edge
samples already computed (and serialized) by sample_edges_encoded. The
worker-pool split uses this so sample_all_edges runs ONCE (in the prepare
step) instead of redundantly in every face-range worker. The samples are
deterministic, so meshing against a shared copy is identical to recomputing
them locally.
Rigid/affine transform of a resident solid -> a NEW resident handle (Stage 1b;
unblocks Transform/Pattern/bakeTransform from the legacy serialize lane). The
result never crosses the boundary as topology. Kernel-produced, so trusted.
The generic inputParams.transform pose write-back JSON: {translate, rotateEulerDeg} with degrees in the intrinsic XYZ order (R = Rx·Ry·Rz
— features::common::compose_trs_matrix). This is the write-side half of
the ACOMP feature’s reader contract (assembly_component.rs reads exactly
transform.translate + transform.rotateEulerDeg; a mismatched key would
silently zero the pose on the next history run).
Propagate measured tolerances up one level of the entity hierarchy: from a
vertex’s incident edges (and the gaps between their ends and the vertex
point) to the vertex itself.