The slugs of the direct-edit refusals the app explains to a user (its
face-transform help, BREP_render::face_transform_help), shared by each
mint and by face_transform_reason.
The wasm panic hook every #[wasm_bindgen] entry point installs. Replaces
the console_error_panic_hook crate for the whole BREP family — reached as
brep_kernel::panic_hook and, through the render engine’s re-export, as
brep_render::brep_kernel::panic_hook.
The wasm panic hook: a Rust panic reaches the browser console instead of
the bare RuntimeError: unreachable wasm traps produce by default.
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 cube-face chart: direction(s, t) = normal + s·tangent_s + t·tangent_t,
with tangent_s × tangent_t = normal, so ∂p/∂s × ∂p/∂t points OUT of the
sphere everywhere on the chart.
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).
What a SUCCESSFUL feature did with what it was asked, when that is not
“everything, exactly” (plan: typed-refusal-reporting, item 3). Requested and
applied are reference names as the document wrote them; every rejected one
says which kind of rejection and why. A partial fulfilment is a different
answer from the one asked for, so it is reported on the feature that made it
and displayed by the app beside the feature; it is never a refusal class
(a partial selection is a separate outcome) and never carries geometry.
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 kernel REFUSAL: the fail-safe contract’s carrier. The kernel never
degrades a result; where it cannot certify one it refuses, and this is the
refusal — a closed RefusalClass that consumers dispatch on (the boolean’s
perturbation-retry gate, the CI baseline’s per-class diff), the stage that
minted it, and the human text, which Display prints verbatim so every
message a user or a test saw before typing is unchanged.
Names the call site for every integrator call made while it is alive, so
the mass.identity line can say WHO paid for the integral rather than
leaving a log reader to infer it from the neighbouring profile lines.
A bounded, per-solid memo for exact area and volume. Geometry edits are
detected by the face-set content identity; callers never invalidate it.
The contents are private so external code cannot supply a fabricated result.
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. dirty is RESIDENT-ONLY state: set by
refresh_library_entry (edit-in-context / update-components) when the
new document builds differently, it forces the ACOMP self-heal lane on the
next run even with a readable snapshot, and clears when the heal rewrites
the snapshot.
An open tally of the pcurve fits made on this thread — see
PcurveFitLedger. Open it where an operation starts, close it where
the operation returns its diagnostics; a ? that unwinds past it drops the
tally.
The camera snapshot: eye / target / up / projection / viewport size — the
render crate’s ViewCamera minus near/far, which are a per-frame depth
window and never persisted. Applying a snapshot under another viewport
aspect refits the frustum, preserving the apparent size at the target.
A resolved annotation plane: the plane the annotation lies in (its
plane reference — a planar face or a reference plane), normal
oriented toward the view’s captured camera, x_axis the in-plane text
direction (the camera’s right projected into the plane). The viewport
overlay and the AP242 ANNOTATION_PLANE both lay the annotation out in
this frame.
An open tally of the polyline fits made on this thread — see
PolylineFitLedger. Open it where an operation starts, close it where
the operation returns its diagnostics; a ? that unwinds past it drops the
tally.
One resolved connection point, keyed in [SceneMap::ports] by its ADDRESS
(J1.VCC, ACOMP3:J1.VCC once placed - see ports.rs). Published by the
ports tail, by the WAYPOINT feature (under its own feature id) and by an
ACOMP re-publishing a placed part’s points.
A Frame as the ports REPORT carries it: four plain triples rather than
Vec3s, because a report is compared and serialized (a Vec3 carries no
PartialEq, by choice, and this is the shape the app and the verifier
read).
What the ports tail resolved, and everything about the block that does not
hold — a name it refused, a reference that resolved to nothing, a mapping
whose target is not in the scene. Never fatal: a problem is reported and the
point still publishes at whatever placement could be worked out, so nothing
downstream vanishes (the same contract rule the features follow).
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.
What a rib calls its faces: the feature id every name starts with, and the
source name of each profile curve ({sketchId}:G{gid} for a sketch segment),
index-aligned with the profile.
The measured continuity of a ribbon patch. Read Self::cross_derivative_residual
before calling anything G1: it is the number that says whether the
prescribed cross-derivative field was actually met.
The output of one feature execution.
A named world point a feature published (a SKETCH publishes every solved
point as {sketchId}:P{pid}; a spline its anchors, a helix its ends).
construction carries the sketch point’s own flag: a construction point (the
sketcher’s ◐ toggle, or a materialized external reference) still resolves by
name — a helix may start at one — but it is NOT model geometry, so a placement
consumer (the hole) skips it exactly as the profile skips construction lines.
Serialized because the render-side build report carries it across the worker
boundary.
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.
One node of the file’s product structure: a PRODUCT_DEFINITION, or a
representation that a MAPPED_ITEM instantiates and no product definition owns
(bodies::representation_owner_index).
A resolved sweep path AND its classification: the ordered, head-to-tail
curves, the name of each, whether the run is CLOSED, the PLANE it lies in if
it lies in one, and the continuity of every joint — the closing one included.
One <object>’s mesh, in millimetres and in the object’s own coordinates.
Shared: an object placed three times is ONE entry here and three
ThreeMfInstances.
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.
What a refusal’s evidence establishes about the claim every refusal
judges: “this input has a result the kernel can certify”. A refusal is
either REFUTED — a witness in the input itself disproves the claim, and no
re-run of the construction can change that — or UNDECIDED — the
construction failed to certify and the input has not been shown to be at
fault. Retry policy reads this, never a list of variants: a refuted claim
is never retried, and only one undecided cause is one a perturbation
addresses (UndecidedCause::Degeneracy).
Why a Transform Face refused, as far as the app explains it — read off the
refusal’s CLASS and slug, never its text, so a reworded refusal keeps its
explanation and a refusal that merely mentions “parallel” does not borrow
one. None is every other refusal: the app shows the kernel’s own words.
What a feature’s build hands back when it refuses. A feature that drives
a typed producer propagates the KernelRefusal whole (? converts it),
so its class reaches FeatureResult::refusal; one that drives a stringly
producer propagates the text. There is no From<FeatureRefusal> for String: the text of a typed refusal is read through
FeatureRefusal::message, never by dropping the class.
The closed kind of a [ValidationIssue]. Only the kinds a dispatcher
needs are minted (the boolean’s endpoint-gap repair lane keys on
CurveVertexGap); everything else is Other and carries its message as
the payload. A dispatcher matches the kind, never the message text.
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.
Why a pcurve refinement stopped. Only PcurveFitExit::Converged means the
floor was met; every other variant is a BUDGET exit, and the report’s
residual was measured on the returned curve rather than assumed.
Why a polyline fit’s refinement stopped. Only
PolylineFitExit::Converged means the tolerance was met; every other
variant is a BUDGET exit whose deviation was measured on the curve actually
returned.
What a connection point is to the harness router: a cable END, or a
pass-through that joins spline paths into a network. Not a user param any
more - it is decided by WHICH producer made the record (a declared port
point is a termination, a WAYPOINT feature is a waypoint).
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 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.
The port group a new point goes into when a part declares none yet. An
electronics part’s pins ARE its pads, so the group it makes for them is a
pcb one.
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”.
BREP_HORIZON_CROSS_FRAME: set to "0", the wrapped-horizon lane combines
its period images per image (Inside when any image counts odd) instead of
summing each loop’s parity over the images. Read per QUERY, not when the
face is prepared; see horizon_cross_frame.
BREP_HORIZON_SINGLE_LOOP: set to "0", the wrapped-horizon lane declines a
face of one or two loops (compared: face.loops.len() <= 2). Read when a
face is prepared; part of the cache key.
Numerical knot DEDUP epsilon (parameter-space): the tighter floor used when
counting distinct knots (SSI/CSI interior_knot_count) or comparing whole
knot vectors for exact reconstruction (analytic surface recognition). This
answers “are these two knot floats the same value?”, NOT “are these the same
knot for snapping?” — so it stays at 1e-12 and must NOT be unified with the
looser KNOT_IDENTITY_TOL.
Knot IDENTITY tolerance (parameter-space): two knot parameters within this
absolute band are treated as the SAME knot for snapping — insert_knot,
NurbsCurve::split, monotonicity and clamp checks. This is the single
source for the “absolute 1e-9 knot tolerance” that split enforces and
that imprint’s trim guards mirror. Distinct in PURPOSE (not just value)
from KNOT_DEDUP_EPS; the two are deliberately NOT unified.
The largest angle the extension’s cross-boundary tangent may turn through
before the extension is called a FOLD. π/2 is the sign change: past it the
extension has stopped going outwards and is doubling back over the patch it
came from, which is never a usable carrier.
The largest the appended strip may be, as a multiple of the surface’s own
3D extent in the direction being extended: the extension may not be longer
than the surface it continues. A polynomial extrapolated by a fraction r
of its own span diverges like r^degree, so this is a backstop and not a
quality bar — callers that need a trustworthy extension ask for a small
increment and check the result, they do not lean on this limit.
BREP_NO_SPHERE_CHART_TRIM: SET to any value (compared: present in the
environment), the sphere-chart lane stops substituting for the generic scan’s
parity count. BREP_NO_SPHERE_CHARTS, which turns every sphere-chart path
off, does the same here. Read per query.
The reference-name prefix an OCCURRENCE-scoped annotation carries out of a
structured import, until its consumer rewrites it:
OCC#<edge>#<edge>…:<part-local name>, the occurrence chain root first.
An empty chain (OCC:) is the root product’s own geometry.
Fraction of the local characteristic length an APPROXIMATE offset
construction may deviate from the exact geometry it approximates — see
offset_construction_band.
The top-level document key holding a part’s own BOM attribute record
({ "Part_Number": "PN-7", "Material": "6061", ... }). Owned by the app’s
document model; the kernel reads it only to stamp PRODUCT.id.
The id of the tail’s appended result (never a history feature). The scene
entities a declared point publishes ride it, so the display pipeline draws
and picks a connection point exactly as it draws a feature’s curves.
BREP_SEAM_BAND_MERGED: set to "0" (the only value compared), the
doubly-periodic seam-band lane stops unwrapping a single merged seam-carrying
loop, and that face goes on to the two-loop analyses or the generic scan.
Read when a face is prepared; part of the prepared-face cache key.
The reserved id of every sketch’s PART ORIGIN reference point: world
(0, 0, 0) projected onto the sketch plane. The editor adds it on entry as
a fixed, grounded, construction external reference, so geometry can be
constrained to the origin. The sketch feature re-projects it onto the
resolved frame before solving and never publishes it — it exists only
inside the sketch (no scene point, no hole center, no 3D display).
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.
The prefix every tight-bend refusal starts with, so a caller can CLASSIFY one
(the wire harness reports it as a bundle status) without matching free text.
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.
Relative volume drift between two measurements of the same body that is
still the same answer: the case gate’s band between a replay and its
baseline (examples/case_replay.rs), and the perturbation rescue’s bar for
a rung against the exact lane’s inclusion–exclusion identity
(csg::boolean::perturbation_retry). One number, so the rescue can never
accept a body the gate would call a different one. It only absorbs
last-bit summation noise.
Mechanical conversion of a stringly LOWER-layer error consumed inside a
typed stack (geometry evaluation, tolerance policy checks): the text is
kept and the refusal is classed Internal under what at stage. This is
a constructor at the consuming site, not a blanket From.
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).
Scan and CREATE: every accepted candidate becomes a constraint, then ONE
solve runs for the whole batch (each inferred constraint is already
satisfied at the pose it was read from, so a healthy assembly does not
move). Returns {ok, created: [id…], report, solve}.
SCAN the live scene for constraints its component placement implies, without
creating anything. options_json is [super::infer::InferOptions] ({} for
the defaults). Never Err: a missing session or a bad options object comes
back as {ok: false, error} — a JsValue error aborts a native build.
The inferable constraint types, joined to the catalogue: [{type, label, icon, longName, detects, defaultOn}]. Session-free — the dialog can list
what the button offers before any document is open.
Overlay geometry for the viewport graphics lane: per enabled constraint,
the resolved WORLD anchor points/directions/geometry classes (post-solve),
the status, the evaluated value, and (multi-element types) the element
role groups — [{id, type, status, message, anchors, directions, geoms, value, unit, target, groups}]. 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.
The two operands a binary boolean’s arrangement reads: prepared as the
boolean prepares them, with every boundary edge split where the imprint’s
sections meet it. These are the NNN-first and NNN-second stages
BREP_BOOLEAN_DUMP writes, not the operands at the boolean’s entry.
fit_pcurve_on_surface for the callers that only need the curve. The
report is not dropped: it is tallied on the open PcurveFitScope, if any,
so the operation that owns this fit can say in its diagnostics whether every
trim reached the floor.
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.
Connectivity of a resident solid — the check validate() does NOT make.
Per-shell edge-connected face components, edges shared across shells, and
pinch vertices. Pure topology, no geometry, no tolerance; see
crate::solid_connectivity for which part is a gate and which is a
diagnostic. Reads the solid in one registry borrow.
Which lane of parameter_point_in_face a face’s questions go to, read off
the face alone — the kernel’s own lane selection, through the same prepared
data the query uses, for a caller that answers some containment questions
ahead of the kernel and must know which rule the kernel applies.
Divisions per cube edge that hold the chord sag of a radius sphere under
chord_tolerance. A chord subtending θ sags radius·(1 − cos(θ/2)), so
θ = 2·acos(1 − tolerance/radius); the edge arc is 2·atan(1/√2) long.
Canonical index of the cube edge whose VARYING axis is varying and whose
two other axes (varying+1) % 3 and (varying+2) % 3 are pinned to the
given signs. Twelve edges: three varying axes times four sign pairs.
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.
A placed component’s connection points, namespaced — the shape
resolve_component_pin reads when a caller has the part’s declarations
rather than a routing report (an eCAD refresh before the new parts have run).
Every connection point document declares, in block order. Only the
document’s OWN block counts: a nested assembly’s component points reach the
part’s library entry namespaced, and they are not this part’s pins.
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() AND to be sound, 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.
The OCCURRENCE CHAIN an endpoint address is placed under, and the
part-local address inside it: ACOMP7:ACOMP1:J1.VCC reads as
("ACOMP7:ACOMP1", "J1.VCC"), and a document’s OWN point J1.VCC as
("", "J1.VCC").
Closedness and Euler parity of a resident solid — the THIRD check
validate() does not make on its own. Its Euler comparison reduces, on a
freshly derived solid, to exactly “is the characteristic even”, and it is
switched off on any solid carrying a degenerate edge; this asks the question
directly and on every solid. Pure counting, one registry borrow.
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.
execute_history with a progress observer. observe is called
immediately BEFORE each feature the run executes (cached replays are not
reported); returning false stops the run at that boundary — the feature
is not executed, nothing after it runs, and the result holds what was
built so far. The boundary is the only cooperative stop the kernel offers:
nothing inside a feature (a boolean, a blend, a sew) checks anything.
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).
STRUCTURED export: the resident scene PLUS the document’s assembly model, as
an AP242 file with real product structure — one PRODUCT per parts-library
entry, one NEXT_ASSEMBLY_USAGE_OCCURRENCE per placed instance.
Write a product structure as an AP242 Part 21 document: one product per
distinct part, one NEXT_ASSEMBLY_USAGE_OCCURRENCE per placement, exact
B-rep geometry in each part’s own frame.
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).
export_step_handles with each body’s SCENE NAME and an optional PMI
block: the engine-native Export→STEP lane. Names key the
MANIFOLD_SOLID_BREPs and the PMI reference resolution.
The full single-product writer: each body carries its SCENE NAME
(MANIFOLD_SOLID_BREP name — and the key the PMI references resolve
through), and an optional PMI block is written as AP242 semantic
representation + polyline presentation + saved views ([pmi]).
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).
Which of this solid’s faces FOLD THROUGH THEMSELVES in 3D — a face whose
surface carries two distinct trimmed parameter feet to one point in space:
an offset taken past the source’s curvature radius, a section swept through
a bend tighter than its own half-width, a carrier fitted through a
swallowtail.
The pivot a Transform Face whose faces are names gets by default, read
off the scene the results BEFORE it build — the value the app stores into
pivot when the selection is committed, and the value build falls back to
for a null pivot, because both go through [resolve_selection] and
[selection_centre]. None when the selection does not resolve to faces on
one solid.
Assemble the catalogue from every feature’s own schema(). The assembly
constraint schemas 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).
The first reference name of a reference_selection param value (a plain
string, a {name} object, or an array of either — post-sanitization it is an
array). Exact match only; no [N] index / snapshot scoring.
helix_sample_points fitted as ONE cubic curve (global interpolation —
interpolate_curve, the machinery every fitted path here uses). Cubic
interpolation error on a circle of radius R with node spacing Δθ is
≈ R·Δθ⁴/384: ~2·10⁻⁷·R at 64 stations per turn.
Range fitter with explicit sampling knobs, reporting what the fit achieved.
fit_pcurve_on_surface_range keeps the long-standing (base 64, 3
refinement rounds, 513 cap) budget; a fit that binds at that cap with the
bar unmet grows once to [PCURVE_RAISED_SAMPLES]
(fit_pcurve_on_surface_stations).
The body of fit_pcurve_on_surface_range_dense, parameterized by the
3D station the pcurve must pass through at each coedge fraction instead of
by an edge curve and a range.
fit_polyline with the GLOBAL lane’s interpolation degree chosen by the
caller (the local lane is cubic Hermite whatever is asked). A marched
section’s stations lie on both carriers to the march’s residual, and a
degree-p interpolant through them errs by O(h^(p+1)) between stations: on
BadBoolean’s sphere×bore rim at its own 135 stations the cubic sits
2.5e-7 off a carrier with a mean signed bias of −1.2e-8, the quintic 8.5e-9
and +6e-11 — the SAME stations, knots and control-point count, so nothing
downstream that samples per knot pays for it (2026-09-27).
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.
The dimension text: prefix (⌀ / R / "") + the nominal (+ the
tolerance block) + suffix (° / ""); a reference dimension is
parenthesized and shows no tolerance.
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.
Whether the wrapped-horizon lane sums each loop’s parity over the query’s
period images (true, the default) or keeps the per-image combining
(false, HORIZON_CROSS_FRAME_SWITCH = "0"). Read from the environment
on every call, as the lane reads it on every query.
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.
Like import_step but reports how many bodies failed and the first error,
so callers can distinguish a fully- from a partially-imported assembly —
and runs the stated-precision consistency check over the imported bodies,
whose result rides in StepImportReport::diagnostics.
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.
Face-loop self-crossing of a resident solid — the check no OTHER detector
here can make. validate() is silent (the incidence is perfect), the
face-versus-face scan has no pair to confirm (both triangles are on one
face), connectivity and Euler parity count the same cells either way; the
face’s AREA is the only other tell. Pure parameter-space work on the trims
the face already carries — no tessellation — so it is cheap enough to be a
default. Reads the solid in one registry borrow.
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.
A sphere solid whose SEAM direction is chosen as well as its polar axis — see
make_sphere_surface_framed. The topology is identical either way (one
face, one pole-to-pole seam edge, two degenerate pole edges); only WHERE on
the ball the seam and the poles sit changes. A caller that will trim the ball
uses it to hide both inside the removed region, so the surviving face has no
edge bordering itself.
A sphere with BOTH halves of its frame chosen: the polar axis (where the two
degenerate poles sit) and the SEAM direction (where the u = 0 meridian
runs). seam_direction is Gram-Schmidt’d against the axis; None — and a
seam parallel to the axis, which names no meridian — falls back to
Vec3::perpendicular, i.e. exactly what make_sphere_surface builds.
Surface area and volume of a resident solid — the native sibling of
mass_properties_handle_native for a caller that reads NOTHING but
those two numbers (examples/case_replay.rs records volume and area per
solid and discards the rest). The full entry runs a second station sweep
over every trimmed face for the nine moment integrands, which costs as
much again as the area/volume sweep: on anotherBooleanFail’s imported
32-face body 2.6 s against 1.3 s, and 5.3 s of that case’s 12.9 s replay
went to moments nobody read. The two numbers come out of the same
solid_mass_properties call the full entry starts with, so they are
bit-identical to its volume and surface_area; the full entry’s
refusal of a non-positive volume is kept so a caller switching over sees
the same Err on the same solids. Reads the solid in one registry borrow.
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.
Offset a free-form NURBS face whose boundaries have no other incident face.
The fitted offset must pass a dense same-parameter residual check. Intrinsic
iso boundaries use exact iso-curves; other self-incident trims use
crate::image_curve. Rebuilt topology and volume orientation are validated.
Neighbour-trimmed faces require general intersection and are refused.
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.
Push a toroidal face by changing its tube radius. Boundary edges must be
intrinsic to this face; neighbour-trimmed rims require re-intersection and
are refused. The carrier retains its knot vectors, weights, and UV basis,
keeping pcurves valid. Iso boundaries rebuild exactly; other self-incident
trims use crate::image_curve.
The current library in the partsLibrary block shape — 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.)
The EXACT arc of plane ∩ ruled revolution spanning a given AZIMUTH range
about the carrier’s own frame — the arc-restricted, seam-anchorable form of
the full sections [intersect_plane_quadric] returns.
Which point of one part document became which in another, per group, and on
what evidence. There is no id behind a point any more, so this is how a
consumer that must carry something across a part refresh — an eCAD sheet’s
terminals, for one — learns that VCC became VDD rather than being
deleted and replaced.
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.
Read a file’s PMI into a PmiState whose references name the geometry
an IMPORT3D feature feature_name will stamp. Ok(None) when the file
carries no PMI.
Re-cut a solid for a RIGID motion of planar faces: rotation, when given as
(axis point, unit axis, angle in radians), is applied first and
translation after it — Transform Face’s rotate-then-translate.
ALL reference names of a reference_selection param, in order (a multiple
selection). Also accepts a single string or {name} object; empties are dropped.
Replace the faces face_ids of solid with one face on a surface of
family kind fitted to them, within tolerance (maximum vertex residual,
model units). See the module docs for the scope and the refusals.
UPDATE (update-components / edit-in-place commit): replace an existing
entry’s document + signature. When the new document BUILDS differently
(same_build) the entry is marked DIRTY: the next history run’s ACOMP
self-heal lane re-executes the document, re-snapshots, and every instance
of the part follows. When it builds the same — only its symbol, pads or BOM
attributes moved — the snapshot and ports still describe it and are kept,
so the part is not rebuilt for an edit that changed no geometry.
Ingest a solid from the flat f64 codec into the resident registry (arena +
validate kept — external / first-crossing ingest). Returns an opaque handle.
A clone of a resident solid, for Rust callers that need the topology itself:
the case-replay diagnostics and probes, and the history runner answering a
drawing sheet’s topology request (native thread or browser worker alike),
which serializes the clone back to the main side. The feature pipeline’s
results only ever hand out handles, and this is no #[wasm_bindgen] export:
JavaScript never calls it. Short borrow; the clone is the caller’s.
The mesh half of mesh_to_faceted_brep: weld, drop degenerate and
duplicate triangles, prune surplus sheets at non-manifold edges, and cap
the remaining boundary cycles with a fan — returning the repaired triangle
soup instead of a BREP.
The connection-point ADDRESS that pin pin of the placed component
occurrence names, read from a routing report’s endpoints. occurrence is
the placed component’s OCCURRENCE CHAIN — ACOMP3 for a component of this
assembly, ACOMP7:ACOMP1 for one nested a level down; plan decision 5
resolves a Diagram reference such as J1 to it. The endpoint’s point is
the PART-LOCAL name, untouched by namespacing, so pin VCC of ACOMP3 is
the endpoint whose point is VCC, and the result is its address, e.g.
ACOMP3:J1.VCC.
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.
The part-local address that pin pin names among a part’s own connection
points, as its parts-library entry carries them
(crate::PartsLibraryEntry::ports). part only names the part in a
refusal; group narrows it as resolve_component_pin’s does.
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.
Rewrite every occurrence-scoped reference in a lifted annotation’s params
into the consumer’s own namespace. namespace turns an occurrence chain
into the prefix a reference to that instance’s geometry opens with
("ACOMP3:", or "" for a component that IS the document); None from it
means the consumer placed no component for that chain, and the reference is
left naming the chain so the row reports itself rather than resolving to
the wrong instance.
ROTATE the faces face_ids of solid by angle_radians about the axis
through axis_point along axis_direction (right-handed), re-intersecting
the neighbours the rotation moves the selection relative to.
§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.
The world direction a point with this seat and this rotation faces: the
rotation applied to +X (every feature transform’s convention), carried
through the seat’s basis. With the world seat this is the rotated +X
itself.
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).
Face-versus-face self-intersection of a resident solid — the OTHER check
validate() does not make (its one “self-intersects” string is a uv-wire
warning). Opt-in and expensive: it tessellates the solid and walks a
triangle BVH, so no default gate calls it. chord_tolerance overrides the
per-solid display density when positive. Reads the solid in one registry
borrow.
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.
Canonical sketch entity key. Numeric IDs normalize integral floats and signed
zero; string IDs are preserved. Other JSON values use their JSON spelling.
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).
Connectivity of a solid’s topology: are each shell’s faces reachable from
one another across shared edges, do any two shells share an edge, and does
any vertex pinch two otherwise-separate fans together.
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.
Does this solid pass through itself? Tessellates every face once, walks a
triangle BVH for mesh crossings, and confirms each candidate against the
two carrier SURFACES so tangent neighbours and chord error cannot
manufacture a finding. See the module docs for the design and its one
documented blind spot.
Exact signed volume. A single nonempty shell shares its area/volume
measurement with subsequent property queries. Multiple shells retain the
original per-shell compensated sum: substituting the across-face sum can
change the last bits and an orientation gate must not change its answer.
Split a PART-LOCAL address into (port, point). None when it carries no
separator — a WAYPOINT feature id, for one, which is an address in its own
right and belongs to no port.
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.
The ρκ profile a TRANSPLANT sweep of profile along path would carry at
stations stations — the instrument behind the refusal below, exposed so a
caller (or a probe) can measure a path BEFORE asking for the solid.
The CLOSURE a sweep of profile along path applies — the frame-closure
policy’s report, exposed so a caller can read the twist a closed sweep laid
down (see SweepClosure). None for an OPEN path, which has no lap to
close.
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_profile_along_chain with an explicit STATION budget and no twist
— the entry a caller with a long, smooth chain uses when the default 32
stations would under-sample it (a wire-harness bundle along a many-anchor
spline: three pieces per span, so a handful of spans already starves each
piece of stations). The budget is spread over the chain by arc length
exactly as the twisted builder’s law spreads its own; the 1024-station cap
and the tangent-continuity refusal apply unchanged.
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.
The helix is transcendental, not exactly NURBS-representable, so the path
is FIT: points (R·cosθ, R·sinθ, pitch·θ/2π) in the axis frame are sampled
uniformly in θ and globally interpolated with a cubic (interpolate_curve
— the same machinery every other fitted path here uses). DENSITY: 64
samples per turn, capped at 1025 total nodes. Cubic interpolation error
on a circle of radius R with node spacing Δθ is ≈ R·Δθ⁴/384: ~2·10⁻⁷·R at
64/turn, and still ~6·10⁻⁵·R at the cap’s worst case (16/turn at the
64-turn limit) — orders below any profile a caller could sweep without
self-intersecting. Uniform-in-θ parameters are exact chord-length for a
helix (constant speed), which is what the averaged-knot interpolation
assumes.
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.
Take every blend note recorded on this thread since the last call.
Blending runs on the feature’s own thread (no parallel march), so the
history loop’s drain sees every note its feature recorded.
Take every repair made on this thread since the last call, leaving the
ledger empty. The history loop drains it after each feature so the repair
is reported against the feature that made it.
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.
Topology TOTALS of a resident solid as
(faces, edges, non_degenerate_edges, vertices), read straight off the
record: every face of every shell, every edge, every edge that is not a
collapsed pole boundary, every vertex.
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 Transform feature’s BBOX_CENTER pivot for a resident source solid.
Share the kernel’s vertex-bbox definition with viewport controls; display
tessellation bounds would give a different pivot for curved solids.
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).
How many chords the containment lanes sample ONE pcurve at:
max(2, (k + 1)(p + 1)·4), k the pcurve’s distinct interior knots (two
knots are one when they differ by no more than
KNOT_DEDUP_EPS, and a knot that close to an end
of the active domain is not interior) and p its degree. Knot- and
degree-aware, so a spline trim is resolved wherever its shape can bend and a
line is two chords.
Which port group each symbol unit binds its pins into, and everything about
the mapping that does not hold. The map is unit (1-based) -> index into declarations``; a unit absent from it binds no pins.
A world position read back as an offset in seat — the inverse of
seat_point, which is what a gizmo drag writes. The basis is orthonormal,
so the inverse is the transpose.
Topology validation issues of a resident solid as (severity, message)
pairs — the native sibling of the JSON validators, for in-process
qualification tooling (examples/case_replay.rs). An empty Vec means the
incidence checks passed; that is NOT a correctness proof: validate() tests
neither connectivity nor face-vs-face self-intersection, and a validating
solid can still be the wrong solid. Reads the solid in one registry borrow.
The vector-area closure of a resident solid: does each closed shell’s
TRIMS enclose the zero vector area a closed shell owes, and if not, which
faces own the residual. One pass over the trims and the edge curves — no
tessellation, no projection — so unlike the crossing scan it is cheap
enough for a default gate. Reads the solid in one registry borrow.
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.