pub struct EngineState {Show 16 fields
pub scene: RenderScene,
pub context_scene: RenderScene,
pub camera: ViewCamera,
pub controls: ArcballControls,
pub settings: RenderSettings,
pub emphasis: Emphasis,
pub widgets: WidgetRegistry,
pub history: History,
pub metadata: MetadataStore,
pub settings_generation: u64,
pub dirty: bool,
pub ref_select: Option<RefSelectState>,
pub selection_filter: SelectionFilter,
pub transform_gizmo: TransformArm,
pub component_move: ComponentMoveArm,
pub cam: CamGeneration,
/* private fields */
}Fields§
§scene: RenderScene§context_scene: RenderSceneDisplay-only assembly surroundings in the active work part frame. Never picked or saved.
camera: ViewCamera§controls: ArcballControls§settings: RenderSettings§emphasis: Emphasis§widgets: WidgetRegistryIn-scene overlay widgets: datums/dimensions/curves, transform gizmo, ViewCube — fed as JSON, drawn by the render core’s overlay pass.
history: HistoryThe engine-owned editable model recipe (ordered features + rollback
index) — the SINGLE source of truth for the model. The UI never keeps its
own copy; it mutates/reads this through the history_* / feature methods.
metadata: MetadataStoreThe Properties-panel metadata store: user attributes keyed by OBJECT NAME
(solid / face / edge kernel name), NOT feature id — so a record survives
feature edits as long as the object’s name persists. Persisted with the
model (a top-level metadata field in the history document); see the
crate::metadata module for the store + the object-info/measurement API.
settings_generation: u64Bumped whenever settings change so the renderer re-derives per-solid base styles (a cheap key, not a per-frame diff).
dirty: boolThe engine sets this whenever the camera/scene/emphasis changed; the presentation shell renders only when it is set (R22 on-demand render — the OrthoCameraIdle matrix-compare analogue, made explicit).
ref_select: Option<RefSelectState>The modal reference-selection state (the ref-select widget). Some while
the user is picking references for a feature-dialog field; None
otherwise. The picked-name list here is the SINGLE source of truth while
active (the UI reads it back; the viewport appends to it on a pick).
selection_filter: SelectionFilterWhich entity KINDS a plain viewport click may select (the selection
filter, mirroring the earlier SelectionFilter.allowedSelectionTypes). select_top_at
consults it via pick_filtered; see the appended SelectionFilter impl
block near the end of this file for the state + honoring logic.
transform_gizmo: TransformArmThe transform-controls gizmo controller: which feature (if any) has the move/rotate gizmo armed (via the in-viewport center-sphere toggle), plus the in-flight handle drag. All the arm/drag/apply logic lives in the appended transform-gizmo impl block near the end of this file.
component_move: ComponentMoveArmThe COMPONENT Move gizmo controller (assemblies §8.5): which ACOMP
instance has the bbox-center move/rotate gizmo armed, the translate/
rotate cycle mode, and the commit-on-release drag. Exclusive with
transform_gizmo (shared widget slot). See component_move.rs.
cam: CamGenerationThe CAM workbench’s generation queue and results (cam_ops.rs).
Implementations§
Source§impl EngineState
The simulation’s door to the background runner (lane C17b): the app’s
panel holds the transport and a view of the stock; the runner holds the
stock and advances it in bounded chunks.
impl EngineState
The simulation’s door to the background runner (lane C17b): the app’s panel holds the transport and a view of the stock; the runner holds the stock and advances it in bounded chunks.
Sourcepub fn cam_sim_submit(&mut self, job: CamSimJob) -> bool
pub fn cam_sim_submit(&mut self, job: CamSimJob) -> bool
Submit one simulation command; false when this runner cannot
simulate (the panel then simulates inline).
Sourcepub fn cam_sim_poll(&mut self) -> Option<CamSimReply>
pub fn cam_sim_poll(&mut self) -> Option<CamSimReply>
The next landed simulation reply, oldest first.
Sourcepub fn cam_sim_poll_progress(&mut self) -> Option<CamSimProgress>
pub fn cam_sim_poll_progress(&mut self) -> Option<CamSimProgress>
The newest progress of the chunk in flight.
Sourcepub fn cam_sim_cancel(&mut self)
pub fn cam_sim_cancel(&mut self)
Stop the chunk in flight between two motions where the runner can (the native thread); the panel drops its reply either way.
Source§impl EngineState
impl EngineState
Sourcepub fn history_has_assembly(&self) -> bool
pub fn history_has_assembly(&self) -> bool
Whether the current document is an ASSEMBLY document: any ACOMP-typed
feature, or a present assembly constraint block. Componentless
documents skip every main-side sync (zero cost for modeling files).
Sourcepub fn assembly_components(&self) -> &[ComponentSnapshot]
pub fn assembly_components(&self) -> &[ComponentSnapshot]
The scene’s component records (deterministic id order) as of the last applied run — the Assembly Structure tree’s projection source. A VIEW over the scene, never an owning structure.
Sourcepub fn assembly_statuses_value(&mut self) -> Value
pub fn assembly_statuses_value(&mut self) -> Value
The per-constraint status rows ([{id, type, enabled, open, status, message, satisfied, error}]) the run reported.
Sourcepub fn assembly_state_value(&mut self) -> Value
pub fn assembly_state_value(&mut self) -> Value
The current assembly block (post-solve): {constraints, idCounter}.
Sourcepub fn assembly_dof_value(&mut self) -> Value
pub fn assembly_dof_value(&mut self) -> Value
The last solve’s DOF/diagnostics summary ({ok, dof, rank, redundant, …} — movedSolids may be absent; tolerate it).
Sourcepub fn assembly_overlay_value(&mut self) -> Value
pub fn assembly_overlay_value(&mut self) -> Value
Per-constraint overlay rows (world anchors/directions/status/value) — the constraints panel reads the evaluated value/unit for the distance/angle label suffix; lane G’s viewport graphics read the rest.
Sourcepub fn parts_library_names(&mut self) -> Vec<String>
pub fn parts_library_names(&mut self) -> Vec<String>
The parts-library entry names currently resident (insert-flow “existing
entries first” list). The main-side store, seeded by document ingest and
kept current by the runs that heal or GC it (apply_run_output installs
the store a run moved), and grown by insert_component.
Sourcepub fn forget_assembly_session(&mut self)
pub fn forget_assembly_session(&mut self)
Drop the main-side session’s currency stamp, so the next
Self::ensure_assembly_session replays this document. The kernel
session is one per thread, shared by every open document: a caller that
may have let another document replay (or changed the kernel’s parts
library) since this one’s last replay calls this first.
Sourcepub fn assembly_add_constraint(
&mut self,
constraint_type: &str,
params_json: &str,
) -> Result<String, String>
pub fn assembly_add_constraint( &mut self, constraint_type: &str, params_json: &str, ) -> Result<String, String>
Add a constraint (params_json = inputParams; the kernel mints the id
from the type’s short name when absent). Returns the minted id.
Sourcepub fn assembly_update_constraint(
&mut self,
id: &str,
params_json: &str,
) -> Result<(), String>
pub fn assembly_update_constraint( &mut self, id: &str, params_json: &str, ) -> Result<(), String>
Replace a constraint’s inputParams (the dialog commit).
Sourcepub fn assembly_remove_constraint(&mut self, id: &str) -> Result<(), String>
pub fn assembly_remove_constraint(&mut self, id: &str) -> Result<(), String>
Delete a constraint.
Sourcepub fn assembly_set_constraint_enabled(
&mut self,
id: &str,
enabled: bool,
) -> Result<(), String>
pub fn assembly_set_constraint_enabled( &mut self, id: &str, enabled: bool, ) -> Result<(), String>
Enable/disable a constraint (the row checkbox).
Sourcepub fn assembly_set_constraint_open(
&mut self,
id: &str,
open: bool,
) -> Result<(), String>
pub fn assembly_set_constraint_open( &mut self, id: &str, open: bool, ) -> Result<(), String>
Persist WHICH constraint has its dialog open (view state — SILENT fold,
no solve, no rerun, no undo entry). An open COUNTS
(Self::assembly_constraint_opens) — including a re-open of the
constraint already open, which is what the dialog door needs to surface
the pane for a label click on a form the user cannot see. ACCORDION: at
most ONE constraint is open — opening one first closes every other inside the same silent fold,
so the panel toggle, the context bar’s add-from-selection, and a viewport
label click all converge on a single open constraint. The constraints
PANEL reads this flag as its mode: open one and its form replaces the
tree (panels::assembly_constraints), which is why every one of those
surfaces opens the dialog without knowing the panel exists.
Sourcepub fn assembly_constraint_opens(&self) -> u64
pub fn assembly_constraint_opens(&self) -> u64
How many constraint dialogs this engine has OPENED through
Self::assembly_set_constraint_open — the app’s dialog door reads it
beside Self::assembly_open_constraint so a re-open of the constraint
already open is still an open (the id alone does not move: a viewport
label click on the constraint whose form is up, made precisely because
the user is on another tab).
It counts the OPENS, not the flag’s history. The flag itself lives in
the kernel and a freshly minted constraint arrives open: true without
passing through the setter — that one needs no count, because a new
constraint brings a new id and the door’s id half already sees it.
Sourcepub fn assembly_open_constraint(&self) -> Option<String>
pub fn assembly_open_constraint(&self) -> Option<String>
The id of the constraint whose DIALOG is open, or None.
The accordion keeps at most one (assembly_set_constraint_open closes
every other), so this is the panel’s mode as ONE value. Reads the same
two fields the Constraints panel’s row builder reads — inputParams.id
and open — off the borrowed fold state, without cloning the whole
assembly block the way assembly_state_value does: the app’s dialog
door calls this every frame.
Sourcepub fn assembly_move_constraint(
&mut self,
id: &str,
index: usize,
) -> Result<(), String>
pub fn assembly_move_constraint( &mut self, id: &str, index: usize, ) -> Result<(), String>
Reorder a constraint to index (drag-reorder).
Sourcepub fn assembly_inferable_types(&self) -> Value
pub fn assembly_inferable_types(&self) -> Value
The constraint types the inference lane can produce — [{type, label, icon, longName, detects, defaultOn}], straight off the kernel’s rule
table. The dialog lists THIS; it keeps no roster of its own, so a rule
added in the kernel shows up as a row without an app change.
Sourcepub fn assembly_infer_constraints(&mut self, options: &str) -> Value
pub fn assembly_infer_constraints(&mut self, options: &str) -> Value
SCAN the placed components for the constraints their placement implies,
creating nothing. options is the kernel’s InferOptions JSON ({} for
the defaults; the dialog sends the ticked types).
Sourcepub fn assembly_apply_inferred_constraints(&mut self, options: &str) -> Value
pub fn assembly_apply_inferred_constraints(&mut self, options: &str) -> Value
Scan and CREATE, as one undoable step: the kernel adds every accepted candidate and solves the batch once, then the usual mutation tail folds the result into the document and re-runs the display. A scan that found nothing skips the tail entirely (no checkpoint, no rerun).
Sourcepub fn assembly_run_solve(&mut self) -> Result<(), String>
pub fn assembly_run_solve(&mut self) -> Result<(), String>
Manual solve (the panel’s Solve button): solve the session, fold, and ALWAYS re-run the display (that is the point of pressing Solve — it works with auto-solve disabled).
Sourcepub fn insert_component(
&mut self,
insert: ComponentInsert<'_>,
) -> Result<String, String>
pub fn insert_component( &mut self, insert: ComponentInsert<'_>, ) -> Result<String, String>
Insert a component instance (the palette/insert flow): resolve the
parts-library entry (add or reuse), refresh the document’s
partsLibrary block, append an ACOMP feature referencing the RETURNED
effective part name with an identity transform, and re-run. The FIRST
component of the document writes isFixed: true EXPLICITLY (dialog-
visible); later instances write false. Returns the new feature id
(ACOMP<digits> — the history’s global counter mints that exact form).
Sourcepub fn set_component_fixed(
&mut self,
component_id: &str,
fixed: bool,
) -> Result<(), String>
pub fn set_component_fixed( &mut self, component_id: &str, fixed: bool, ) -> Result<(), String>
Fix/Unfix a component: toggles the OWNING ACOMP feature’s
inputParams.isFixed (one truth, one undo lane) and re-runs. A nested
occurrence (ACOMP1:ACOMP2) is fixed or freed on the top instance that
lends it (inputParams.flexibleFixed, by instance-local path), never in
the sub-assembly’s document; nested_fixed_state says when that is
not possible.
Sourcepub fn set_components_fixed(
&mut self,
component_ids: &[String],
fixed: bool,
) -> Result<(), String>
pub fn set_components_fixed( &mut self, component_ids: &[String], fixed: bool, ) -> Result<(), String>
Fix/Unfix several top-level components at once (a packed BOM row’s
placements): every owning ACOMP’s inputParams.isFixed, ONE undo step,
one re-run. The same write Self::set_component_fixed makes for one.
Sourcepub fn occurrence_fixed(&self, path: &str) -> Result<bool, String>
pub fn occurrence_fixed(&self, path: &str) -> Result<bool, String>
Whether a nested occurrence (ACOMP1:ACOMP2) is fixed, or why it
cannot be fixed or freed from this assembly (nested_fixed_state).
Sourcepub fn select_component(&mut self, component_id: &str)
pub fn select_component(&mut self, component_id: &str)
Select a component in the viewport: emphasis over exactly its member solids (the tree↔viewport sync lane; a viewport pick of any member lights the tree row through the same emphasis set).
Sourcepub fn component_member_solids(&self, component_id: &str) -> Vec<String>
pub fn component_member_solids(&self, component_id: &str) -> Vec<String>
A component’s member SOLID scene names (empty for an unknown id) — the selection/hover unit COMPONENT entries resolve to.
Sourcepub fn toggle_component_selection(&mut self, component_id: &str)
pub fn toggle_component_selection(&mut self, component_id: &str)
TOGGLE a component in the current selection as ONE unit (the additive Ctrl/Cmd+click under COMPONENT promotion): when EVERY member solid is already selected the whole set deselects, otherwise the whole set joins the selection — the rest of the selection stays.
Sourcepub fn select_components(&mut self, component_ids: &[String])
pub fn select_components(&mut self, component_ids: &[String])
Select SEVERAL components at once: emphasis over the union of their member solids (the interference window’s row click highlights both participants of a pair through this).
Sourcepub fn begin_ref_select_for_constraint(
&mut self,
constraint_id: &str,
path: Vec<String>,
label: String,
filter: Vec<String>,
multiple: bool,
seed_names: Vec<String>,
)
pub fn begin_ref_select_for_constraint( &mut self, constraint_id: &str, path: Vec<String>, label: String, filter: Vec<String>, multiple: bool, seed_names: Vec<String>, )
Enter the modal reference picker for an ASSEMBLY CONSTRAINT’s
elements-style field (same widget, different commit target — Finish
routes through Self::assembly_update_constraint_no_rerun instead of
feature params). No roll-to-before: constraints pick against the FULL
assembly.
Source§impl EngineState
impl EngineState
Sourcepub fn context_display(&self) -> (bool, f32)
pub fn context_display(&self) -> (bool, f32)
Whether the context is shown, and its opacity (0..=1).
Sourcepub fn set_context_display(&mut self, shown: bool, opacity: f32)
pub fn set_context_display(&mut self, shown: bool, opacity: f32)
Show or hide the context and set its opacity (clamped to 0.05..=1). Hidden context is neither drawn nor picked, and drops its selection and hover. Kept across context rebuilds.
Sourcepub fn context_hit_at(&self, x: f64, y: f64) -> Option<PickCandidate>
pub fn context_hit_at(&self, x: f64, y: f64) -> Option<PickCandidate>
The context FACE under CSS-pixel (x, y) when it is in front of the
part’s own geometry there (or the part has nothing there), else None.
Sourcepub fn context_edge_at(&self, x: f64, y: f64) -> Option<PickCandidate>
pub fn context_edge_at(&self, x: f64, y: f64) -> Option<PickCandidate>
The context EDGE under CSS-pixel (x, y), unless the part’s own
geometry is clearly in front of it (an edge flush with the part, a
mating edge, still counts).
Sourcepub fn sketch_copy_context_edge(&mut self, edge: &PickCandidate) -> bool
pub fn sketch_copy_context_edge(&mut self, edge: &PickCandidate) -> bool
The sketch pickEdges tool on a Work part’s context edge: copy it into
the active sketch as plain lines / arcs / a circle
(crate::sketch::external_ref::add_copied_edge), each noted “copied
from <part>, not linked”. Nothing links it back: if that part moves,
the copy stays where it is. One undo step. Returns whether it copied.
Sourcepub fn select_context(&mut self, candidate: Option<PickCandidate>) -> bool
pub fn select_context(&mut self, candidate: Option<PickCandidate>) -> bool
Select candidate (a Self::context_hit_at answer) as THE context
selection, or clear it. true when it changed.
Sourcepub fn hover_context(&mut self, candidate: Option<PickCandidate>) -> bool
pub fn hover_context(&mut self, candidate: Option<PickCandidate>) -> bool
Light candidate as hovered context, or clear the hover. true when it
changed.
Sourcepub fn context_selection(&self) -> Option<&PickCandidate>
pub fn context_selection(&self) -> Option<&PickCandidate>
The context selection, if any.
Sourcepub fn sync_context_highlight(&mut self)
pub fn sync_context_highlight(&mut self)
Put the context selection and hover into the context scene’s highlight
list, dropping either whose face the (possibly rebuilt) context no
longer has. Call after replacing Self::context_scene.
Sourcepub fn context_tangent_plane(&self) -> Result<([f64; 3], [f64; 3]), String>
pub fn context_tangent_plane(&self) -> Result<([f64; 3], [f64; 3]), String>
The plane tangent to the selected context face at the point it was
picked: (origin, unit normal), in the part’s frame. For a flat face it
is the face’s own plane; for a curved one, the plane touching it there.
Sourcepub fn datum_on_context(&mut self) -> Result<String, String>
pub fn datum_on_context(&mut self) -> Result<String, String>
“Datum here”: a datum (D) on the plane tangent to the selected context
face at the picked point, named for the part it was copied from. It is a
COPY: if that part moves, the datum stays where it is. Returns its id.
Sourcepub fn sketch_on_context(&mut self) -> Result<String, String>
pub fn sketch_on_context(&mut self) -> Result<String, String>
“Sketch on this face”: Self::datum_on_context, then a new sketch on
its XY plane. Returns the sketch’s id.
Sourcepub fn context_selection_json(&self) -> Value
pub fn context_selection_json(&self) -> Value
{"solid", "face"} of the context selection, or null (automation).
Sourcepub fn context_hover_json(&self) -> Value
pub fn context_hover_json(&self) -> Value
{"solid", "face"} of the hovered context face, or null (automation).
Source§impl EngineState
impl EngineState
Sourcepub fn refresh_constraint_overlay(&mut self)
pub fn refresh_constraint_overlay(&mut self)
Rebuild the constraint-overlay cache from the LIVE kernel session and re-bake the drawn group. Cleared (empty group) while the Show Constraint Graphics setting is off or a sketch edit is active. A live handle drag’s preview survives the rebuild (re-applied onto the fresh cache).
Sourcepub fn refresh_constraint_overlay_from(
&mut self,
overlay_json: &str,
state_json: &str,
)
pub fn refresh_constraint_overlay_from( &mut self, overlay_json: &str, state_json: &str, )
Self::refresh_constraint_overlay with explicit payloads (the parsed
assembly_overlay_json array + assembly_state_json object) — the
testable seam: canned payloads exercise the whole cache/pick/drag path
without a kernel session.
Sourcepub fn ensure_constraint_overlay_current(&mut self)
pub fn ensure_constraint_overlay_current(&mut self)
Per-frame upkeep (the app viewport calls this once per frame): hide the
group while the setting is off / sketch mode is active, restore it when
they flip back, and re-bake when the camera zoom moved the
world_per_pixel materially (>0.5%) so the screen-constant arc/rod
sizing stays pixel-true. Re-bakes only on actual change, so a quiet
frame stays quiet (no dirty loop).
Sourcepub fn freedom_glyph_component(&self) -> Option<String>
pub fn freedom_glyph_component(&self) -> Option<String>
The component whose free motion the glyph shows: the selection is exactly one top-level component’s solids (a component pick, from the viewport or the tree), and nothing else.
Sourcepub fn freedom_glyph_value(&self) -> Value
pub fn freedom_glyph_value(&self) -> Value
What the free-motion glyph draws now: {component, center, slides, axes: [{point, direction}]} from the last solve’s bodyFreedom, or
null (no single component selected, a fixed component, or one the
solve did not analyse).
Sourcepub fn constraint_overlays(&self) -> &[ConstraintOverlay]
pub fn constraint_overlays(&self) -> &[ConstraintOverlay]
The cached overlay records (read-only view for the app’s label pass + tests).
Sourcepub fn constraint_labels_json(&self) -> String
pub fn constraint_labels_json(&self) -> String
The label feed for the app’s chip pass:
[{id, type, icon, text, status, message, color:[r,g,b], world:[x,y,z], draggable, selected}]. text leads with icon (the type’s glyph), so
the chip is a picture plus the measure; id is for the hover tooltip. One row per cached overlay with a resolvable label anchor
(the leader midpoint / arc mid-sweep / anchor midpoint). selected
marks the label-click-selected constraint (thicker chip border). Empty
while hidden.
Sourcepub fn constraint_hover(&mut self, id: &str)
pub fn constraint_hover(&mut self, id: &str)
Hover a constraint LABEL: highlight the referenced elements
(inputParams.elements) through the existing emphasis machinery —
faces/edges by kernel name, a {solid}@x,y,z vertex ref or a bare
component id by its owning solid(s). Deduped by constraint id so a held
hover never re-bumps the emphasis generation. Sets the one-frame
Self::take_constraint_label_hover flag either way so the viewport’s
scene-hover pass yields.
Sourcepub fn constraint_hover_end(&mut self)
pub fn constraint_hover_end(&mut self)
The pointer left the constraint labels: drop the element highlight (only if a label hover set one — never clobbers an unrelated scene hover).
Sourcepub fn take_constraint_label_hover(&mut self) -> bool
pub fn take_constraint_label_hover(&mut self) -> bool
Consume the one-frame “a constraint label is hovering elements” flag —
the viewport’s modeling hover branch skips its scene re-hover while set
(mirrors Self::take_sketch_list_hover) so the label-driven highlight
survives the frame without a per-frame clobber/re-apply dirty loop.
Sourcepub fn constraint_label_clicked(&mut self, id: &str)
pub fn constraint_label_clicked(&mut self, id: &str)
A constraint LABEL was clicked: SELECT that constraint (the chip gains
its selected accent, the context bar offers Delete constraint) and OPEN
it through the ACCORDION open (Self::assembly_set_constraint_open —
every other constraint closes, so the clicked one is the ONE open
constraint, which is what puts the panel into its dialog). Guarded on the
id existing in the live session (the fallible export’s error path would
abort off-wasm).
Sourcepub fn constraint_select(&mut self, id: &str) -> bool
pub fn constraint_select(&mut self, id: &str) -> bool
SELECT a constraint without opening it — the Constraints tree’s single click. The same selection a label click makes (the chip’s selected accent, the context bar’s Delete constraint), minus the dialog. Returns false, changing nothing, for an id the live session does not hold.
Sourcepub fn selected_constraint(&self) -> Option<String>
pub fn selected_constraint(&self) -> Option<String>
The constraint SELECTED via its viewport label (or None), pruned
against the live session — a deleted / undone constraint never lingers
as selected.
Sourcepub fn constraint_deselect(&mut self)
pub fn constraint_deselect(&mut self)
Drop the constraint selection (the Clear action, Esc, and the context
bar’s delete all route here — directly or via clear_selection).
Sourcepub fn constraint_arrow_pick(&self, x: f64, y: f64) -> Option<String>
pub fn constraint_arrow_pick(&self, x: f64, y: f64) -> Option<String>
Whether a screen-px pick lands on a draggable constraint handle; returns the grabbed constraint’s id (the NEAREST containing region wins). The viewport routes a drag that starts here into the constraint drag, and swallows a bare click so the solid behind the arrow isn’t selected.
Sourcepub fn constraint_handle_points_json(&self) -> String
pub fn constraint_handle_points_json(&self) -> String
The GRAB POINT of every draggable constraint handle, as
{constraint id: [x, y]} in VIEWPORT-LOCAL px — the point a host has to
press to start the drag Self::constraint_drag_begin claims, published
so the arrow is addressable BY NAME instead of by projection arithmetic.
The point is crate::feature_dimensions::arrow_handle_point — a
distance arrow’s TIP, an angle arc’s sweep-end handle — projected through
the same point_region builder the hit regions come from, so the
published point and the pickable region can never drift: a press here is
at distance ZERO from the handle’s own region.
Empty while the constraint graphics are hidden (the setting is off, or a
sketch edit is active) and for every overlay that has no draggable
handle — a leader-only type, or a dimensional one whose value is an
expression. The app publishes it as the constraint hit panel, in SCREEN
points.
Sourcepub fn constraint_drag_begin(&mut self, x: f64, y: f64) -> bool
pub fn constraint_drag_begin(&mut self, x: f64, y: f64) -> bool
Begin a constraint-handle drag at screen (x, y). Returns whether a
draggable handle was grabbed (the viewport then routes the drag here
instead of orbiting the camera).
Sourcepub fn constraint_drag_to(&mut self, x: f64, y: f64)
pub fn constraint_drag_to(&mut self, x: f64, y: f64)
Drag a grabbed constraint handle to screen (x, y): map the pointer to a
new value (distance: signed offset along the base-face normal for
plane-based rows, magnitude along the leader otherwise; angle: the
shared arc nearest-projection search, preserving signed sweeps through 360°),
update the PREVIEW (annotation + label track live), and re-bake. No
kernel call — the commit happens on Self::constraint_drag_release.
Sourcepub fn constraint_drag_commit_payload(&self) -> Option<(String, String)>
pub fn constraint_drag_commit_payload(&self) -> Option<(String, String)>
The pending commit (constraint id, inputParams JSON) a release would
send — the drag’s params snapshot with the dragged field set to the
preview value. None when no drag is live. (The pure half of
Self::constraint_drag_release, separated for tests.)
Angle display convention: the drag preview is the INTERIOR arc sweep
(what the arc draws and the kernel’s overlay value measures), but the
stored inputParams.angle is the DISPLAY angle — exterior-remapped when
the constraint’s exteriorAngle toggle is on (map_angle’s contract) —
so the commit remaps interior → 180 − interior for those.
Sourcepub fn constraint_drag_release(&mut self)
pub fn constraint_drag_release(&mut self)
Release the constraint-handle drag: COMMIT the previewed value via
assembly_update_constraint_json (auto-solves), consume the reply’s
movedSolids display seam (re-posed resident solids re-tessellate in
place so the release shows this frame), and then run the SAME tail as
every panel-side constraint edit (Self::after_constraint_mutation):
a checkpointed fold — the drag is one undo entry — and the rerun, which
re-keys the moved instance’s cache entry to the pose it now has. A
commit against a session that no longer has the constraint (or no
session at all — canned-payload tests, the native thread-runner seam)
drops the preview with a notice instead.
Sourcepub fn consume_assembly_moved_solids(&mut self, report_json: &str)
pub fn consume_assembly_moved_solids(&mut self, report_json: &str)
Consume a solve report’s movedSolids: [{name, handle}] display seam:
those resident solids were RE-POSED IN PLACE by the solver (their
producing feature replayed reused, so the run delta kept the stale
mesh) — re-tessellate each from its live resident handle and replace its
display, preserving per-solid view state (visibility, color override).
The key is absent on zero-mate reports; absence is tolerated.
Source§impl EngineState
impl EngineState
Sourcepub fn replace_components(
&mut self,
component_ids: &[String],
insert: ComponentInsert<'_>,
canonicalize: &dyn Fn(&str) -> String,
) -> Result<String, String>
pub fn replace_components( &mut self, component_ids: &[String], insert: ComponentInsert<'_>, canonicalize: &dyn Fn(&str) -> String, ) -> Result<String, String>
Replace the part shown by the ACOMP occurrences component_ids with
insert (an existing parts-library entry or a new part payload).
canonicalize spells a store identity one way (lineage comparison).
One undo step. Returns the new part’s library entry name; the
classification of the mates lands with the run
(Self::replace_report).
Sourcepub fn capture_replace(&mut self, paths: &[String]) -> ReplaceCapture
pub fn capture_replace(&mut self, paths: &[String]) -> ReplaceCapture
The live state a replace of paths must compare against, read BEFORE
anything moves: every healthy mate touching them with each
reference’s local frame, and the old parts’ entity names. A path is an
ACOMP id, or a NESTED occurrence path (ACOMP3:ACOMP1) for a part
inside a sub-assembly (frames are then in the top occurrence’s frame,
which the replace does not move).
Sourcepub fn capture_part_edit(&mut self, paths: &[String]) -> ReplaceCapture
pub fn capture_part_edit(&mut self, paths: &[String]) -> ReplaceCapture
Self::capture_replace for a PART EDIT: also the sub-assemblies’ OWN
mates below paths, at every depth. Those live in the sub-assembly’s
document, not this one, and a renamed face breaks them just the same;
Self::commit_part_edit classifies them with the rest and writes the
outcome back into that document. (A replace takes the old sub-assembly’s
mates away with it, so it captures none.)
Sourcepub fn commit_replace(
&mut self,
capture: ReplaceCapture,
document: Value,
from: BTreeMap<String, String>,
to: String,
lineage: BTreeMap<String, &'static str>,
notes: Vec<String>,
) -> Result<(), String>
pub fn commit_replace( &mut self, capture: ReplaceCapture, document: Value, from: BTreeMap<String, String>, to: String, lineage: BTreeMap<String, &'static str>, notes: Vec<String>, ) -> Result<(), String>
Adopt document (the caller’s replace edit) as ONE undo step, holding
every captured mate on an occurrence without shared lineage
(disabled, marked once the run lands), and classify the rest when the
run lands. from / to / lineage are keyed by the captured paths;
notes join the report.
Sourcepub fn commit_part_edit(
&mut self,
capture: ReplaceCapture,
document: Value,
parts: &[String],
) -> Result<(), String>
pub fn commit_part_edit( &mut self, capture: ReplaceCapture, document: Value, parts: &[String], ) -> Result<(), String>
Adopt document (the caller’s part edit: parts rewritten in its
parts library) as ONE undo step, and classify the mates of the
captured occurrences once its run lands: a reference that still
resolves is kept, one whose name is gone is re-attached when exactly
one entity of the edited part lies on its carrier, and the rest are
held for Repair (module doc, Part edits).
Sourcepub fn components_of_parts(&self, parts: &[String]) -> Vec<String>
pub fn components_of_parts(&self, parts: &[String]) -> Vec<String>
The ACOMP ids (top level) that place any of parts.
Sourcepub fn occurrence_entities(&mut self, path: &str) -> Vec<Value>
pub fn occurrence_entities(&mut self, path: &str) -> Vec<Value>
The named faces and edges of an occurrence path (ACOMP3 or a nested
ACOMP3:ACOMP1), each with its frame in the TOP occurrence’s local
space: what a held mate’s suggestion is chosen from.
Sourcepub fn resolve_refs(&mut self, refs: &[String]) -> Vec<Value>
pub fn resolve_refs(&mut self, refs: &[String]) -> Vec<Value>
Resolve namespaced refs against the live assembly (frames in the
owning top occurrence’s local space; {ref, ok, geom, point, …} rows).
Sourcepub fn replace_report(&mut self) -> Value
pub fn replace_report(&mut self) -> Value
The last replace’s report (null while its run is in flight or when
nothing was replaced this session): {components, from, to, lineage, kept, unresolved: [{id, type, refs: [{ref, reason, suggestion}]}], notes}.
Sourcepub fn part_at_path(&self, path: &str) -> Option<String>
pub fn part_at_path(&self, path: &str) -> Option<String>
The parts-library name an occurrence path shows in the document: a
top ACOMP’s partName, or (ACOMP3:ACOMP1) the placement’s inside
the sub-assembly definitions. None when the path does not exist.
Sourcepub fn replace_unresolved(&self) -> Value
pub fn replace_unresolved(&self) -> Value
Every mate still carrying a replace marker (survives save/reopen):
[{id, type, from, to, refs}].
Sourcepub fn begin_ref_select_for_replace_repair(&mut self, mate: &str, old_ref: &str)
pub fn begin_ref_select_for_replace_repair(&mut self, mate: &str, old_ref: &str)
Start the REPAIR PICK for one held reference of mate mate: the
standard reference selection (RefSelectTarget::ReplaceRepair),
filtered to faces and edges, ONE pick. Nothing rolls: the repair names
the assembly as it stands. The finished pick waits for
Self::take_replace_repair_pick.
Sourcepub fn take_replace_repair_pick(&mut self) -> Option<(String, String, String)>
pub fn take_replace_repair_pick(&mut self) -> Option<(String, String, String)>
The finished repair pick (mate, old ref, picked name), once: the
replace dialog takes it and runs the repair.
Sourcepub fn replace_repair(
&mut self,
repairs: &[(String, String, String)],
) -> Result<(), String>
pub fn replace_repair( &mut self, repairs: &[(String, String, String)], ) -> Result<(), String>
Repair unresolved references, as ONE undo step: each (constraint id, old ref, new ref) rewrites that element and clears the reference from
the marker; a mate with nothing left unresolved drops its marker and
is re-enabled when it was enabled before the replace. new ref equal
to old ref confirms the same-name match.
Source§impl EngineState
impl EngineState
Sourcepub fn export_bom_csv(&mut self) -> Result<String, String>
pub fn export_bom_csv(&mut self) -> Result<String, String>
Export the BOM as CSV: the exact BOM_CSV_HEADER, one line per row,
LF endings. A cut length is written to three decimals; a wire without
one leaves mfQty empty and names the reason in status.
Sourcepub fn export_bom_json(&mut self) -> Result<String, String>
pub fn export_bom_json(&mut self) -> Result<String, String>
Export the BOM as a JSON array of the same records — the CSV sibling of
Self::export_bom_csv, with the cut length at full precision.
Sourcepub fn part_attributes(&self, part_name: &str) -> Value
pub fn part_attributes(&self, part_name: &str) -> Value
Read a part’s attribute record ({} when the part has none / is
unknown). Never errs — a BOM row for a part mid-import simply shows
blanks.
Sourcepub fn part_pmi_count(&self, part_name: &str) -> usize
pub fn part_pmi_count(&self, part_name: &str) -> usize
How many PMI annotations a PART’s own document carries, summed over its
views. 0 for a part with no PMI block and for an unknown part.
A STEP assembly import puts a part-scoped dimension or tolerance on the PART (once, however many instances place it — the exporter’s own rule), so it is not in the open document’s PMI block and the PMI panel, which shows that block, never mentions it. The BOM is where a reader sees it: this is the parts list saying “the bolt is toleranced”, with the annotations themselves one Open Part away.
Sourcepub fn part_source(&self, part_name: &str) -> Option<(String, String)>
pub fn part_source(&self, part_name: &str) -> Option<(String, String)>
A part’s (sourceKey, sourceSignature) — what the app’s write-through
lane needs to decide whether the file on disk is still the one this
entry was built from. None for an unknown part; the key is returned
even when EMPTY (embedded-only), because “” is exactly what the
write-through lane checks for.
Sourcepub fn part_document_json(&self, part_name: &str) -> Option<String>
pub fn part_document_json(&self, part_name: &str) -> Option<String>
A part’s embedded document as text — the payload the app writes through
to the part’s sourceKey after an attribute edit.
Sourcepub fn set_part_attribute(
&mut self,
part_name: &str,
key: &str,
value: Value,
) -> Result<(), String>
pub fn set_part_attribute( &mut self, part_name: &str, key: &str, value: Value, ) -> Result<(), String>
Write ONE part attribute. Value::Null (or an empty string) REMOVES the
key, so clearing a cell leaves no "" litter in the saved document.
§Why this is not just a document edit
The document’s partsLibrary block is a MIRROR of the kernel’s
main-side store, not the truth: a run that heals or GCs the store writes
its result back over the block (apply_run_output), and the per-run
request does not carry the block at all (History::prefix_request
omits it). So a change written only into the block is erased by the next
such run. This therefore
writes BOTH: the kernel store (via refresh_library_entry, which is the
same door edit-in-place and update-components use) and the document
block + undo checkpoint. Self::undo re-installs the rewound block
into the store, which is what makes the pair rewind together.
The snapshot is KEPT: an attribute is not geometry, so there is
nothing to re-evaluate. refresh_library_entry sees that the new
document builds the same part (brep_kernel::same_build) and leaves the
entry clean, so the rerun serves every instance from the snapshot. Before
it did, each attribute edit re-executed the whole part: 23 s for a Mass
edit on a herringbone gear. The panel still commits a text cell on
focus-loss rather than per keystroke, since each commit is a run.
Sourcepub fn document_part_attributes(&self) -> Value
pub fn document_part_attributes(&self) -> Value
The open document’s own attribute record ({} when it has none).
Never errs — a document that was never annotated simply reads blank.
Sourcepub fn set_document_part_attribute(
&mut self,
key: &str,
value: Value,
) -> Result<(), String>
pub fn set_document_part_attribute( &mut self, key: &str, value: Value, ) -> Result<(), String>
Write ONE attribute on the open document. Value::Null (or an empty
string) REMOVES the key, and the last key takes the empty record with
it — write_attribute’s rules, shared with the library-entry lane, so
a document that was never annotated serializes exactly as before.
Unlike Self::set_part_attribute there is no kernel store to keep in
step: this record belongs to the document in hand, not to a
parts-library mirror, so the write is document + undo checkpoint and
nothing else. The re-run that follows is not for geometry — the history
is unchanged, so every feature is a cache hit — it is what moves the
applied-run generation, which is what refreshes the tab’s dirty dot.
Sourcepub fn occurrence_attributes(&self, component_id: &str) -> Value
pub fn occurrence_attributes(&self, component_id: &str) -> Value
Read ONE occurrence’s attribute record ({} when it has none).
Sourcepub fn occurrence_attributes_all(&self) -> HashMap<String, Value>
pub fn occurrence_attributes_all(&self) -> HashMap<String, Value>
Every ACOMP’s occurrenceAttributes in ONE pass over the history,
keyed by component id. The BOM reads all of them every frame, and the
per-id Self::occurrence_attributes resolves its id with a linear
index_of scan — once per row that is quadratic in the component count
(70 ms a frame at 633 components). A component with no attributes maps
to an empty object, so a lookup here reads exactly what the per-id
accessor answers.
Sourcepub fn set_occurrence_attribute(
&mut self,
component_ids: &[String],
key: &str,
value: Value,
) -> Result<(), String>
pub fn set_occurrence_attribute( &mut self, component_ids: &[String], key: &str, value: Value, ) -> Result<(), String>
Write ONE occurrence attribute across component_ids — ONE undo step
however many ids there are.
The fan-out lane: a PACKED BOM row rolls up every occurrence of a part
whose occurrence data matches, and editing that row’s cell must apply to
all of them. One id (the unpacked case) is the same call with a
one-element slice, so there is no second code path to keep in step.
Value::Null / "" removes the key.
Source§impl EngineState
impl EngineState
Sourcepub fn solid_density(&self, solid: &str) -> Option<(f64, DensitySource)>
pub fn solid_density(&self, solid: &str) -> Option<(f64, DensitySource)>
The density (g/cm³) a solid’s mass is computed with, and where it came
from: its own metadata density, else its part’s (see the module).
Sourcepub fn chain_mass(&mut self, chain: &str) -> MassReport
pub fn chain_mass(&mut self, chain: &str) -> MassReport
The mass properties of what one occurrence chain places — a NESTED
BOM line (ACOMP9:ACOMP1 is the part ACOMP1 places inside the
sub-assembly ACOMP9 places), each solid with its own part’s density.
Asks for missing measurements.
Sourcepub fn chain_mass_cached(&self, chain: &str) -> MassReport
pub fn chain_mass_cached(&self, chain: &str) -> MassReport
Self::chain_mass from what is already measured.
Sourcepub fn bom_mass_pending(&mut self) -> bool
pub fn bom_mass_pending(&mut self) -> bool
Ask for every placed part’s measurements; true while any is still in
flight (an export waits on this rather than writing blanks).
Sourcepub fn part_has_geometry(&self, part_name: &str) -> bool
pub fn part_has_geometry(&self, part_name: &str) -> bool
Whether the part has geometry to measure (then its mass is computed and
a typed Mass is refused).
Sourcepub fn document_has_geometry(&self) -> bool
pub fn document_has_geometry(&self) -> bool
Whether the open document has geometry to measure.
Sourcepub fn measure_parts<'a>(&mut self, parts: impl IntoIterator<Item = &'a str>)
pub fn measure_parts<'a>(&mut self, parts: impl IntoIterator<Item = &'a str>)
Ask for the measurements the named parts’ masses need — what a panel
calls before it reads Self::part_bom_record_cached for each row.
Sourcepub fn part_mass(&mut self, part_name: &str) -> MassReport
pub fn part_mass(&mut self, part_name: &str) -> MassReport
A parts-library part’s mass properties (see the module), asking for any measurement still missing.
Sourcepub fn part_mass_cached(&self, part_name: &str) -> MassReport
pub fn part_mass_cached(&self, part_name: &str) -> MassReport
Self::part_mass from what is already measured (never asks; a
solid not measured yet reads as pending).
Sourcepub fn document_mass(&mut self) -> MassReport
pub fn document_mass(&mut self) -> MassReport
The OPEN document’s own mass properties: every measurable solid it shows (a part’s bodies; an assembly’s placed components, each with its own part’s density).
Sourcepub fn document_mass_cached(&self) -> MassReport
pub fn document_mass_cached(&self) -> MassReport
Self::document_mass from what is already measured.
Sourcepub fn part_bom_record(&mut self, part_name: &str) -> Value
pub fn part_bom_record(&mut self, part_name: &str) -> Value
A part’s BOM record: its stored attributes with the DERIVED mass
properties folded in — Volume (mm³) and Mass (kg) as computed, and
Density as resolved when the part names only a Material. A Mass
stored on a part with geometry is not what the BOM shows: the computed
value replaces it, or the key is absent when there is none yet.
Sourcepub fn part_bom_record_cached(&self, part_name: &str) -> (Value, MassReport)
pub fn part_bom_record_cached(&self, part_name: &str) -> (Value, MassReport)
Self::part_bom_record from what is already measured, plus the
reading itself (a panel row shows the note when there is no number).
Sourcepub fn document_bom_record(&mut self) -> Value
pub fn document_bom_record(&mut self) -> Value
The open document’s own record with its derived mass properties — the
same fold as Self::part_bom_record.
Source§impl EngineState
impl EngineState
Sourcepub fn ensure_overlays_current(&mut self)
pub fn ensure_overlays_current(&mut self)
Per-frame overlay upkeep — the ONE call the app viewport makes each frame
(see BREP_app/src/viewport/interaction.rs).
Everything fed through the general set_overlay channel is pre-expanded
into GPU vertices AT FEED TIME (see the “Why not one uniform feed” note in
crate::widgets), so — unlike the specialized widgets (transform gizmo,
datums, ViewCube), which are rebuilt against the LIVE camera every frame —
a baked overlay group keeps whatever screen-constant sizing it was baked
with. A ZOOM changes world_per_pixel and nothing else re-bakes them, so
the draggable gizmos keep their old pixel size — and where a handle’s world
position is ITSELF px × world_per_pixel (the angular arc), their old
POSITION too, drifting away from the live-computed grab region.
So: re-bake on a MATERIAL world_per_pixel change, keyed on that ONE
quantity rather than on any particular gesture. Every zoom path moves it —
the wheel, Self::zoom_to_fit, Self::standard_view (which fits), a
viewport Self::resize — so they are all covered without a per-path
hook. What does NOT move it needs no re-bake, and correctly gets none:
pan and orbit hold the eye→target distance, the ViewCube (face, corner AND
navigation arrow) is a fixed-pivot reorient, and
Self::toggle_projection preserves apparent size by construction
(ViewCamera::toggle_projection solves for the distance/half-height that
keeps world_per_pixel — see projection_toggle_preserves_apparent_size).
The baked buffers are world-space, so the GPU re-projects them for free.
Re-bakes only on actual change, so a quiet frame stays quiet (no per-frame
dirty loop).
Sourcepub fn zoom_to_fit(&mut self)
pub fn zoom_to_fit(&mut self)
Frame the whole scene (used right after the first history feed).
Sourcepub fn resize(&mut self, css_width: f64, css_height: f64)
pub fn resize(&mut self, css_width: f64, css_height: f64)
Update the CSS viewport size (used by all camera math). The physical framebuffer size + DPR are the presentation shell’s concern. The viewport calls this every frame, so it marks the frame dirty only when the size really changes: an unconditional mark re-rendered the whole scene on every repaint (about 0.34 s a frame for a large CAM stock on a machine without a GPU), whether or not anything had changed.
pub fn pointer_down(&mut self, x: f64, y: f64, button: i32) -> bool
pub fn pointer_move(&mut self, x: f64, y: f64) -> bool
pub fn pointer_up(&mut self) -> bool
pub fn wheel(&mut self, delta_y: f64, cursor: Option<[f64; 2]>) -> bool
pub fn set_controls_enabled(&mut self, enabled: bool)
Two-finger pan/pinch, also available with the sketch camera locked: neither operation changes its orientation relative to the sketch plane.
pub fn toggle_projection(&mut self) -> &'static str
pub fn set_projection(&mut self, kind: &str)
Sourcepub fn standard_view(&mut self, name: &str) -> bool
pub fn standard_view(&mut self, name: &str) -> bool
Snap to a named view and fit, the name read in Self::view_frame —
so with a board shown TOP looks down on its component side.
Sourcepub fn view_frame(&self) -> ViewFrame
pub fn view_frame(&self) -> ViewFrame
The frame the named views and the ViewCube are read in: Z-up
(crate::view::ViewFrame::Board) while the document shows a board, Y-up otherwise.
Keyed on the DOCUMENT, not the workbench: the board is seen in 3D from every workbench that draws the 3D view (Modeling, Assembly…) — the PCB workbench itself draws its 2D editor there instead — so a frame the PCB workbench switched on would never be in force where the board is looked at. A document that has a board is one whose 3D view is about the board.
pub fn camera_state_json(&self) -> String
Sourcepub fn camera_state_value(&self) -> Value
pub fn camera_state_value(&self) -> Value
Self::camera_state_json as a JSON value.
pub fn apply_camera_state_json(&mut self, json: &str) -> Result<(), String>
pub fn world_per_pixel(&self) -> f64
Sourcepub fn world_to_screen_json(&self, points_json: &str) -> Result<String, String>
pub fn world_to_screen_json(&self, points_json: &str) -> Result<String, String>
Project world points to CSS-pixel screen coords for host anchoring. Input
is [[x,y,z], …]; output [[sx, sy, depth, inFront], …] where inFront
is 1 when a LABEL anchored at the point should draw
(crate::view::ViewCamera::label_anchor_visible, THE one label policy:
the point is projectable — ortho always, perspective unless at/behind the
eye plane, near/far NEVER cull — AND its projection lands inside the
viewport, so an off-screen anchor’s chip vanishes instead of clamping to
the viewport edge). Every app label pass (sketch dims, feature dims,
constraint chips, gizmo axis text) keys its skip off THIS flag, so the
policy lives in exactly one place.
Sourcepub fn world_to_screen_points(&self, points: &[[f64; 3]]) -> Vec<[f64; 4]>
pub fn world_to_screen_points(&self, points: &[[f64; 3]]) -> Vec<[f64; 4]>
Self::world_to_screen_json without the JSON: what a native pass
that projects every frame calls.
Sourcepub fn camera_matrices_json(&self) -> String
pub fn camera_matrices_json(&self) -> String
The camera matrices for the host overlays’ per-frame world→screen /
screen→world hot path: { viewProj:[16], viewProjInverse:[16], viewport:[w,h] }. Both matrices are column-major (index =
col*4 + row); viewProj maps world → wgpu clip
(x,y in −1..1, z in 0..1) and viewport is the CSS-pixel size. This lets
dimensions + sketch drop the compat mirror camera and read the engine’s
own view-projection directly (see world_to_screen_json for one-shots).
Source§impl EngineState
impl EngineState
Sourcepub fn render_fingerprint(&self) -> [(&'static str, u64); 5]
pub fn render_fingerprint(&self) -> [(&'static str, u64); 5]
One hash per kind of render input, for the app’s stale-frame check
(automation builds): a frame whose inputs hash differently from the last
rendered frame’s but that is not marked dirty would show a stale view.
Selection and hover highlight are emphasis; sketch previews and every
other set_overlay geometry, the gizmos and the ViewCube are widgets;
theme and background colours bump settings_generation; tessellation
arriving later bumps a solid’s revision in scene.
Sourcepub fn build_widget_overlay(&self) -> Option<WidgetOverlay>
pub fn build_widget_overlay(&self) -> Option<WidgetOverlay>
Build this frame’s overlay-widget geometry, or None when nothing is enabled (skips the overlay passes entirely).
Sourcepub fn fit_camera_and_overlay(&mut self) -> (Camera, Option<WidgetOverlay>)
pub fn fit_camera_and_overlay(&mut self) -> (Camera, Option<WidgetOverlay>)
Fit the per-frame depth window to EVERYTHING drawn, then resolve the GPU
camera — the ONE path both frame loops (wasm Engine::render, desktop
redraw) use so they can’t drift. The overlay is built FIRST, then its
WORLD bounds are folded into the fit: near/far never affect the overlay
geometry (it depends only on view direction + world_per_pixel), so
building it before the fit lets construction geometry — datum planes,
world axes, frames, the transform gizmo — be bracketed by the depth
window instead of clipping against the solids-only bounds. The world
ORIGIN is always folded in too, so the origin triad stays bracketed even
when every geometry channel is momentarily empty (an all-empty frame then
yields a tiny origin-centred window — harmless, re-fit next frame). The
ViewCube is excluded (it draws with its own mini-camera; see
WidgetOverlay::world_bbox). Returns the resolved camera + the built
overlay for the frame to hand to the render core.
pub fn set_datums_json(&mut self, json: &str) -> Result<(), String>
Sourcepub fn set_overlay_json(&mut self, json: &str) -> Result<(), String>
pub fn set_overlay_json(&mut self, json: &str) -> Result<(), String>
Feed the general overlay geometry channel (set_overlay): arbitrary named
tri/line/point groups (feature-dialog previews and other display-only
geometry), drawn in the widget overlay pass.
pub fn set_dimensions_json(&mut self, json: &str) -> Result<(), String>
pub fn set_transform_json(&mut self, json: &str) -> Result<(), String>
pub fn set_viewcube_enabled(&mut self, enabled: bool)
Sourcepub fn viewcube_rect_json(&self) -> String
pub fn viewcube_rect_json(&self) -> String
The ViewCube corner rect {x,y,w,h} (CSS px) so the host can decide
whether to forward a pointer event.
Sourcepub fn viewcube_hover(&mut self, local_x: f64, local_y: f64) -> bool
pub fn viewcube_hover(&mut self, local_x: f64, local_y: f64) -> bool
Update the ViewCube hover from cube-local pixels; returns whether it
changed (a hover-out is (None) with local coords outside).
pub fn viewcube_clear_hover(&mut self) -> bool
Sourcepub fn viewcube_click(&mut self, local_x: f64, local_y: f64) -> bool
pub fn viewcube_click(&mut self, local_x: f64, local_y: f64) -> bool
Click the ViewCube at cube-local pixels: snap the shared camera to the region’s standard view (keeping the current pivot distance). Returns true if a region was hit.
Sourcepub fn datum_pick(&self, x: f64, y: f64) -> String
pub fn datum_pick(&self, x: f64, y: f64) -> String
Pick the datum plane/axis under a screen pixel; returns its name (empty when none).
NOT the selection path any more: construction planes are ordinary pick
candidates (Self::pick_candidates_at → the widget’s datum_plane_hits,
which reports EVERY card the ray crosses rather than the first), so the
viewport click router no longer calls this. It survives as the AXIS-aware
second line of defense inside Self::ref_select_click’s total-miss arm.
Sourcepub fn transform_hover(&mut self, x: f64, y: f64) -> u32
pub fn transform_hover(&mut self, x: f64, y: f64) -> u32
Update the transform-gizmo hover from a screen pixel; returns the handle under the pointer (0 = none). Marks dirty when the highlight changed.
Sourcepub fn transform_pick(&self, x: f64, y: f64) -> u32
pub fn transform_pick(&self, x: f64, y: f64) -> u32
The transform-gizmo handle under a screen pixel (0 = none) — the host echoes it back to start a drag.
Sourcepub fn transform_drag(
&mut self,
handle: u32,
sx: f64,
sy: f64,
cx: f64,
cy: f64,
) -> String
pub fn transform_drag( &mut self, handle: u32, sx: f64, sy: f64, cx: f64, cy: f64, ) -> String
Compute a transform drag (frame-space + world delta) as JSON for the feature-edit commit. Marks the handle active for the highlight.
pub fn transform_drag_end(&mut self)
Sourcepub fn dimension_anchors_json(&self) -> String
pub fn dimension_anchors_json(&self) -> String
Per-dimension label placement: [{id, anchor:[x,y,z], screen:[sx,sy,inFront]}] — the host pins each text label at screen.
Source§impl EngineState
impl EngineState
Sourcepub fn refresh_board_geometry(&mut self) -> BoardBuild
pub fn refresh_board_geometry(&mut self) -> BoardBuild
(Re)build the board’s 3D bodies from the document’s pcb block.
Mirrors refresh_committed_sketches
in shape and for the same reason: apply_run_output reconciles the scene
against the RUN’s outputs and drops everything else, so a derived body
has to be re-inserted after it. Bodies shown last time and not this time
(the block went away, a layer emptied, the board shrank) are removed.
Cheap to call: the parsed board is compared against the one the current bodies were built from and an unchanged block returns without touching the scene. That is what lets the eCAD host call it on a track edit, which writes the block and — changing no placement — runs no history.
A board that DID change is rebuilt and every body is then seated over whatever is resident under its name. Replacing, not skipping, is the point: see the seating comment below.
Sourcepub fn board_build(&self) -> BoardBuild
pub fn board_build(&self) -> BoardBuild
What the last refresh_board_geometry
built — body and triangle counts, for the cost the record reports.
Sourcepub fn board_solid_names(&self) -> &[String]
pub fn board_solid_names(&self) -> &[String]
The scene names of the board bodies currently shown, in stack order.
Source§impl EngineState
impl EngineState
Sourcepub fn component_ports_visible(&self) -> bool
pub fn component_ports_visible(&self) -> bool
Whether the ports placed components carry draw their sheets.
Sourcepub fn set_component_ports_visible(&mut self, visible: bool)
pub fn set_component_ports_visible(&mut self, visible: bool)
Show or hide the sheets of the ports placed components carry (the app drives this from the active workbench). A change refreshes the sheets.
Sourcepub fn refresh_committed_sketches(&mut self)
pub fn refresh_committed_sketches(&mut self)
(Re)build the persistent committed-sketch SHEET SOLIDS. For every committed
sketch that should show — committed_sketch_ids
minus hidden_sketches — synthesize its display from the run’s solved
profile AND its own model segments, and insert it as a scene solid (keyed by
the sketch id, dim-cyan, flagged is_sketch); remove any sheet inserted on
the PREVIOUS refresh but not this one (rolled back, deleted, hidden, or
became the active edit). A sketch that closes a region gets its planar sheet;
one that closes NOTHING (an open chain — the single line of the 2026-09-02
report) still draws its segments as named edges, so it is visible and
pickable instead of vanishing; one holding ONLY points (a hole-placement
sketch) draws them as vertices, so it too is visible, listed and pickable
(a vertex hit carries its owning sketch, which the SKETCH pick lane
admits). Only a sketch with no drawable geometry at all (empty /
construction-only) is skipped. Marks dirty.
Sourcepub fn sketch_visible(&self, id: &str) -> bool
pub fn sketch_visible(&self, id: &str) -> bool
Whether the committed sketch id’s persistent overlay is shown (absent from
hidden_sketches = visible).
Sourcepub fn set_sketch_visible(&mut self, id: &str, visible: bool)
pub fn set_sketch_visible(&mut self, id: &str, visible: bool)
Show/hide the committed sketch id’s persistent overlay (the Scene-tree
checkbox). Toggles hidden_sketches, rebuilds the committed overlays (so the
group is fed or cleared immediately), and marks dirty.
Sourcepub fn committed_sketches(&self) -> Vec<(String, bool)>
pub fn committed_sketches(&self) -> Vec<(String, bool)>
The committed sketches to list in the Scene tree: every "S" feature at the
current rollback (minus the active edit), each with its live visibility — the
ordered (id, visible) list the Scene panel snapshots.
Sourcepub fn sketch_entities_json(&self) -> String
pub fn sketch_entities_json(&self) -> String
The committed sketches as JSON ([{"name":<id>,"visible":<bool>}]) — the
sibling of scene_entities_json the Scene panel
publishes for the headed verifier (kept a SEPARATE method so the solids array’s
shape is unchanged).
Source§impl EngineState
impl EngineState
Sourcepub fn component_move_armed(&self) -> bool
pub fn component_move_armed(&self) -> bool
Whether the component Move gizmo is armed (for any component).
Sourcepub fn component_move_armed_feature(&self) -> String
pub fn component_move_armed_feature(&self) -> String
The armed component feature id (empty when disarmed).
Sourcepub fn component_move_group(&self) -> Vec<String>
pub fn component_move_group(&self) -> Vec<String>
Every component the armed gizmo moves (empty when disarmed).
Sourcepub fn component_move_group_toggle(&mut self, ids: &[String])
pub fn component_move_group_toggle(&mut self, ids: &[String])
The Move action for SEVERAL components (a multi-selection, or faces of
several occurrences): one gizmo that moves them together as a rigid
group. Duplicates count once. FIXED members are left out with one toast
naming them; the rest still arm. One movable member falls back to the
single-component Self::component_move_toggle; pressing Move again on
the armed group disarms it.
Sourcepub fn component_move_unfix_toggle(&mut self, ids: &[String])
pub fn component_move_unfix_toggle(&mut self, ids: &[String])
“Unfix and Move”: like Self::component_move_group_toggle, but FIXED
components join the move instead of being skipped. Nothing is unfixed
until a drag commits; the release then writes each fixed member’s
isFixed: false together with its new pose, as one undo step. Pressing
it again on the same armed set disarms.
Sourcepub fn component_move_toggle(&mut self, feature_id: &str)
pub fn component_move_toggle(&mut self, feature_id: &str)
The Move toggle (context bar / tree action): ARMS the full gizmo (all
handle sets) for feature_id, or DISARMS when it is already armed
(arming fresh replaces any other armed component). A FIXED component
refuses with a toast and never arms.
Sourcepub fn component_move_copy(&mut self, source_id: &str) -> Result<String, String>
pub fn component_move_copy(&mut self, source_id: &str) -> Result<String, String>
The Move Copy action (context bar / tree action): append a SECOND
instance of source_id’s part — its inputParams cloned (same
partName, same pose, any other placement keys riding along) under a
fresh ACOMP<n> id and an explicit isFixed: false — then select it
and arm the full Move gizmo on it, so the user drags the copy off the
original. No new part is made: both instances reference one
parts-library entry. A FIXED source copies fine (the copy is free).
Returns the new feature id.
Sourcepub fn component_press(&mut self, x: f64, y: f64) -> bool
pub fn component_press(&mut self, x: f64, y: f64) -> bool
Begin a component-gizmo drag at viewport px (x, y); true when a
handle was grabbed (the viewport routes the drag here, not the camera).
Sourcepub fn component_move_typed(
&mut self,
field: &str,
value: f64,
) -> Result<TypedMove, String>
pub fn component_move_typed( &mut self, field: &str, value: f64, ) -> Result<TypedMove, String>
A TYPED move of the armed component (or group): value mm along, or
degrees about, one of the gizmo’s axes (field = x|y|z|rx|ry|rz) —
the same motion as dragging that arrow or ring by exactly value. It is
solved against the mates once and written through the drag release’s
commit (one undo step, unfix, mechanical references). When the mates
allow only part of it, that part is applied and the report says how
much and which constraints stopped the rest; when they allow none, a
notice names them and nothing is written.
Sourcepub fn component_move_typed_report(&self) -> Option<TypedMove>
pub fn component_move_typed_report(&self) -> Option<TypedMove>
The last typed move’s report (the panel’s status line).
Sourcepub fn component_move_dragging(&self) -> bool
pub fn component_move_dragging(&self) -> bool
Whether a component-gizmo drag is in flight.
Sourcepub fn component_drag_to(&mut self, cx: f64, cy: f64)
pub fn component_drag_to(&mut self, cx: f64, cy: f64)
Continue the drag: resolve the world delta against the FROZEN grab frame, compose the pending pose, solve it live (budget permitting) and pose the member displays and the gizmo where the mates put them.
Sourcepub fn component_release(&mut self)
pub fn component_release(&mut self)
End the drag: COMMIT the pending pose into each moved ACOMP’s
inputParams.transform (one param write — or one batched write for a
group → one undo entry → one rerun whose constraint tail re-solves; the
post-run sync then re-glues the gizmo to wherever the solve left the
components). A grab that never moved commits nothing.
Sourcepub fn component_move_json(&self) -> String
pub fn component_move_json(&self) -> String
The armed component gizmo’s logical state for the verifier:
{armed, feature, group, unfix, anchor}.
Source§impl EngineState
impl EngineState
Sourcepub fn assembly_flip_constraint(&mut self, id: &str) -> Result<String, String>
pub fn assembly_flip_constraint(&mut self, id: &str) -> Result<String, String>
Flip constraint id to its other solution, as one undo step. Returns
the component the seed moved (empty when the flip moves nothing up
front: a mechanical mate, or a path/slot measured from the other end).
Err names why the constraint has no other solution.
Source§impl EngineState
impl EngineState
Sourcepub fn component_of_solid(&self, solid_name: &str) -> Option<String>
pub fn component_of_solid(&self, solid_name: &str) -> Option<String>
The OWNING component feature id of a scene solid — the OUTERMOST
ACOMP<digits>: namespace segment of its name, verified against the
history (the segment must be an ACOMP feature of THIS document; a nested
chain’s inner segments belong to the sub-assembly’s own document).
None for ordinary modeling solids (no prefix) and for sketch-child
names (S1:G20 — S1 is not an ACOMP segment).
Sourcepub fn selected_vertex_components(&self) -> Option<Vec<String>>
pub fn selected_vertex_components(&self) -> Option<Vec<String>>
The owning top-level occurrence of every selected vertex (vertices
carry no names, so the app’s selection read cannot resolve them), or
None when any selected vertex is not component geometry.
Sourcepub fn component_ids(&self) -> Vec<String>
pub fn component_ids(&self) -> Vec<String>
Every ACOMP feature id in history order (the structure tree’s row order).
Sourcepub fn component_info(&self, feature_id: &str) -> Option<ComponentInfo>
pub fn component_info(&self, feature_id: &str) -> Option<ComponentInfo>
The derived ComponentInfo for an ACOMP feature id (None when the id
is missing or not an ACOMP feature).
Sourcepub fn component_bbox_center(&self, feature_id: &str) -> Option<[f64; 3]>
pub fn component_bbox_center(&self, feature_id: &str) -> Option<[f64; 3]>
The world bbox CENTER of a component’s member solids — the Move gizmo’s
attach point. None when the component has no resident members (rolled
back / failed build).
Sourcepub fn component_members(&self, id: &str) -> Vec<String>
pub fn component_members(&self, id: &str) -> Vec<String>
The member solids of a placed component or of a Pattern Component instance (which has no feature of its own).
Sourcepub fn pattern_instance_ids(&self) -> Vec<String>
pub fn pattern_instance_ids(&self) -> Vec<String>
Every Pattern Component instance the last run placed, in run order.
Source§impl EngineState
impl EngineState
Sourcepub fn datum_feature_for_name(&self, name: &str) -> Option<(String, String)>
pub fn datum_feature_for_name(&self, name: &str) -> Option<(String, String)>
The producing (feature id, feature type) of a datum/plane frame NAME, but
ONLY when the name is an actually-resolved D/P frame at the current rollback
— the provenance the Properties Info tab reports for a selected datum.
Sourcepub fn refresh_construction_datums(&mut self)
pub fn refresh_construction_datums(&mut self)
(Re)build the persistent construction datum/plane overlays. Feeds every D/P
frame the last run resolved (minus hidden_datums) to the datum-plane
widget channel as a screen-constant NAMED plane in the calm datum color — or
the selection accent when it is in emphasis.selected_datums / hovered when
it is in emphasis.hovered_datums (hover wins, the EmphasisState order).
The feed
REPLACES the widget’s datum set wholesale, so a departed/hidden/rolled-back
plane is auto-dropped; shown_datum_names mirrors what was fed. Marks dirty.
The fed set is also exactly what is PICKABLE: plane_candidates_at hit-tests
these cards, so a hidden or rolled-back plane can no more be picked than it
can be seen.
Sourcepub fn datum_visible(&self, name: &str) -> bool
pub fn datum_visible(&self, name: &str) -> bool
Whether the construction datum/plane name’s plane is shown (absent from
hidden_datums = visible).
Sourcepub fn set_datum_visible(&mut self, name: &str, visible: bool)
pub fn set_datum_visible(&mut self, name: &str, visible: bool)
Show/hide the construction datum/plane name’s plane (the Scene-tree
checkbox). Toggles hidden_datums and re-feeds the datum planes so the
plane appears/disappears immediately.
Sourcepub fn construction_datums(&self) -> Vec<(String, bool)>
pub fn construction_datums(&self) -> Vec<(String, bool)>
The construction datums/planes to list in the Scene tree: every D/P frame at
the current rollback, each with its live visibility (hidden ones included,
like committed_sketches).
Sourcepub fn datum_entities_json(&self) -> String
pub fn datum_entities_json(&self) -> String
The construction datums/planes as JSON ([{"name","visible"}]) — the datum
sibling of sketch_entities_json the Scene
panel publishes (__brepDatums) for the headed verifier.
Sourcepub fn select_datum(&mut self, name: &str) -> bool
pub fn select_datum(&mut self, name: &str) -> bool
Select a construction datum/plane by frame NAME (replacing the whole selection): a Scene-tree row click or a viewport datum pick. Only a name that is an actually-resolved D/P frame at the current rollback selects; others return false without changing the selection. Re-feeds the datum planes so the selected one shows the accent, and bumps the generation.
Source§impl EngineState
impl EngineState
Sourcepub fn expressions_json(&self) -> String
pub fn expressions_json(&self) -> String
The history’s expressions source string (the variable sheet the panel’s
editor binds to). Raw source text — despite the _json suffix it mirrors
the other engine readouts’ naming; the verifier reads it verbatim.
Sourcepub fn set_expressions(&mut self, expressions: &str) -> String
pub fn set_expressions(&mut self, expressions: &str) -> String
Replace the expressions source and re-run the rolled-to prefix so every
feature param referencing a variable (e.g. sizeX = "boxW") rebuilds with
the new value — the panel’s live-update path. Returns the build-report JSON.
Sourcepub fn set_expression_preview(
&mut self,
preview: Option<ExpressionPreview>,
) -> String
pub fn set_expression_preview( &mut self, preview: Option<ExpressionPreview>, ) -> String
Show the model evaluated with preview’s expressions source instead of
the document’s own, or (None) with the document’s own again. Runs the
history when what the runs evaluate changes; re-arming the same source
runs nothing. Returns the build report.
TRANSIENT by construction: the source is substituted into the run
REQUEST only (Self::rerun_history), never into the history, so the
document, its undo stacks, its dirty state and what Save writes are
untouched.
The preview is armed against the history’s current
edit_serial. The first run
after the user edits the model (or undoes, or redoes) drops it, so the
edit rebuilds against the document’s own values and nothing previewed
is shown under it. A host that edits the document ITSELF while
previewing (the family table writing a cell) re-arms after the write.
Sourcepub fn rearm_expression_preview(&mut self)
pub fn rearm_expression_preview(&mut self)
Re-arm the stored preview at the history’s current edit serial, running nothing: for a host that has just edited the document itself (the family table committing a cell) and keeps previewing.
Sourcepub fn expression_preview(&self) -> Option<&ExpressionPreview>
pub fn expression_preview(&self) -> Option<&ExpressionPreview>
The preview in force: None when there is none, or when the user has
edited the model since it was armed (the next run drops it).
Sourcepub fn configurator_json(&self) -> String
pub fn configurator_json(&self) -> String
The history’s configurator object (typed named inputs) as JSON — a
read/display surface for the panel; deeper configurator editing is deferred.
Sourcepub fn expression_variables_json(&self) -> String
pub fn expression_variables_json(&self) -> String
The parsed variable list for the sheet’s name/value view:
[{ "name": "...", "expr": "..." }, …] — one entry per name = rhs;
assignment in the expressions source, in source order. The RHS is shown
verbatim (its DEFINING expression); evaluating it to a live scalar needs the
kernel’s private Env, so a computed value column is deferred — the text
editor + re-run is the source of truth for applied values.
Source§impl EngineState
impl EngineState
Sourcepub fn gizmo_mode(&self) -> &'static str
pub fn gizmo_mode(&self) -> &'static str
The armed ◎ gizmo mode: "none", "transform", or "dimension". Drives
the ◎ highlight + the app’s dimension-overlay draw / input routing.
Sourcepub fn dimension_armed_for(&self, feature_id: &str) -> bool
pub fn dimension_armed_for(&self, feature_id: &str) -> bool
Whether the DIMENSION gizmo is armed for THIS feature (drives the ◎ dimension-mode highlight).
Sourcepub fn dimension_armed_feature(&self) -> String
pub fn dimension_armed_feature(&self) -> String
The dimension-armed feature id (empty unless in dimension mode).
Sourcepub fn arm_dimension(&mut self, feature_id: &str)
pub fn arm_dimension(&mut self, feature_id: &str)
Arm the DIMENSION gizmo for feature_id: hide the transform widget, show
the annotation overlay. Re-arming a different feature moves it.
Sourcepub fn transform_center_pick(&self, x: f64, y: f64) -> bool
pub fn transform_center_pick(&self, x: f64, y: f64) -> bool
Whether a screen-px pick in TRANSFORM mode lands on the orange CENTER
free-move sphere (HANDLE_CENTER). The viewport uses this to make a bare
click on the center TOGGLE to the dimension arrows (via
toggle_to_dimension) instead of swallowing
it as a generic handle click. False in any other gizmo mode.
Sourcepub fn dimension_origin_pick(&self, x: f64, y: f64) -> bool
pub fn dimension_origin_pick(&self, x: f64, y: f64) -> bool
Whether a screen-px pick in DIMENSION mode lands on an orange ORIGIN
sphere of the armed feature’s dimension arrows. Each distinct annotation
draws such a sphere — a LINEAR dim at its point_a (a cube’s three axis
dims share one, a cone/pyramid draw two), an ANGULAR dim at its arc
center (the vertex; its sweep-END sphere is the angle DRAG handle, not a
toggle) — so every one is projected via the camera and hit-tested against
the screen-constant sphere radius. The viewport uses this to TOGGLE back to
the transform gizmo (via toggle_to_transform),
which is the ONLY way an angular-only feature (a revolve) reaches transform.
False in any other gizmo mode. The hit radius mirrors the gizmo center’s own
tolerance (PX_CENTER_RAD + 2.0, transform.rs) so the two toggle targets match.
Sourcepub fn dimension_arrow_pick(&self, x: f64, y: f64) -> Option<String>
pub fn dimension_arrow_pick(&self, x: f64, y: f64) -> Option<String>
Whether a screen-px pick in DIMENSION mode lands on a dimension ARROWHEAD
(a linear leader’s orange cone TIP at point_b, or an angular arc’s orange
sweep-END handle sphere). Returns the grabbed annotation’s field_key — the
viewport routes a DRAG that starts here to feature_dimension_drag, editing that param live (Fix 4). None in any other
gizmo mode / when no arrowhead is under the pointer. Distinct from
dimension_origin_pick: that grabs the SHARED
origin sphere (a mode toggle), this grabs an arrowHEAD (a value edit). The
nearest arrowhead within the screen-constant hit radius wins.
Sourcepub fn dimension_handle_points(&self) -> Vec<(String, (f64, f64))>
pub fn dimension_handle_points(&self) -> Vec<(String, (f64, f64))>
The grabbable ARROWHEAD of every dimension the armed ◎ gizmo draws, as
(field_key, (x, y)) in viewport-local px — what a host presses to drag
that param’s value.
The point is the arrowHEAD end of the Arrow region
(dimension_hit_regions), not its middle:
a LINEAR leader’s capsule runs point_a → point_b and the whole shaft
grabs, but the cone TIP at b is the thing a reader sees and a
walkthrough should be filmed pulling; an ANGULAR dim’s region is already
the sweep-end handle circle, so its center is the point.
Published ONLY where the gizmo’s own pick answers with that field, AND
still answers it GRAB_MARGIN_PX away in each direction — the same
rule transform_handle_points follows,
with a margin the transform widget does not need.
The margin is not caution, it is a bug this found. A pick is decided by
spine_distance, nearest wins and a tie goes to the first annotation, so
where two handles COINCIDE the winner turns on the last bit of an f32.
A full-circle torus is exactly that: arc’s sweep-end ball sits at 360°,
which is where the majorRadius leader points, so the two are the same
screen point. Publishing dim:arc there passed an equality test taken in
f64 and then lost the press, because a rect goes out through JSON and
comes back a few ulps away — and the drag silently resized the torus
instead of sweeping it. Requiring the field to win by a couple of pixels
drops such a handle rather than publishing one that grabs its neighbour.
Empty in any mode but DIMENSION.
Sourcepub fn dimension_origin_points(&self) -> Vec<(String, (f64, f64))>
pub fn dimension_origin_points(&self) -> Vec<(String, (f64, f64))>
The ORIGIN BALLS the armed ◎ gizmo draws, as (field_key, (x, y)) in
viewport-local px — the orange spheres a CLICK toggles the gizmo between
its dimension and transform forms at.
A ball is keyed by the first dim anchored on it, because several share
one: a cube’s three leaders all start at its min corner and draw a single
sphere (radius/sizeX), while a cone or a pyramid draws two — one at
the base centre and one at the top (radiusBottom and radiusTop). The
name is a stable handle for the ball, not a claim that it belongs to that
dim alone.
Published under the same rule as the arrowheads: only where the gizmo’s
own dimension_origin_pick answers at the
point, so a ball hidden behind an arrowhead that outranks it is dropped
rather than published somewhere a click would do something else.
Empty in any mode but DIMENSION.
Sourcepub fn dimension_hit_areas_json(&self) -> String
pub fn dimension_hit_areas_json(&self) -> String
DEBUG overlay: the EXACT SCREEN-space (viewport-local px) pickable regions
of the armed feature’s dimension gizmo — the SAME regions
dimension_arrow_pick + dimension_origin_pick 2D-test the cursor against
(dimension_hit_regions) — so the red
outline can NEVER drift from the grabbable area. Each item is a
{ kind:"capsule", a:[x,y], b:[x,y], r } (linear leaders) or
{ kind:"circle", c:[x,y], r } (origin / arc-handle spheres); the app only
offsets by rect.min. [] unless the DIMENSION gizmo is armed.
Sourcepub fn toggle_to_dimension(&mut self)
pub fn toggle_to_dimension(&mut self)
Toggle the armed ◎ gizmo from TRANSFORM to DIMENSION for the currently transform-armed feature (the orange center-sphere click). No-op unless a feature is transform-armed.
Sourcepub fn toggle_to_transform(&mut self)
pub fn toggle_to_transform(&mut self)
Toggle the armed ◎ gizmo from DIMENSION to TRANSFORM for the currently dimension-armed feature (the orange origin-sphere click). No-op unless a feature is dimension-armed.
Sourcepub fn feature_dimension_annotations_json(&self, feature_id: &str) -> String
pub fn feature_dimension_annotations_json(&self, feature_id: &str) -> String
The dimension annotations for feature_id as JSON:
[{ fieldKey, pointA, pointB, value, label, mid }] (world-space points;
mid is the leader midpoint the app anchors the label at). [] when the
feature type has no FD-1 builder.
Sourcepub fn feature_dimension_state_json(&self) -> String
pub fn feature_dimension_state_json(&self) -> String
The { mode, feature, annotations } snapshot the headless verifier reads
(published as __brepFeatureDim).
Sourcepub fn refresh_feature_dimension_overlay(&mut self)
pub fn refresh_feature_dimension_overlay(&mut self)
(Re)project the dimension leaders onto the current geometry. Called on arm
- after every param change (drag / value edit / rerun in dimension mode)
- on a material ZOOM (
Self::ensure_feature_dimension_overlay_current). Remembers theworld_per_pixelit baked at, which is what lets that per-frame ensure fire on change ONLY.
Sourcepub fn feature_dimension_release(&mut self, feature_id: &str)
pub fn feature_dimension_release(&mut self, feature_id: &str)
Finalize a dimension drag with a fresh run of the committed parameters. The final run forces this feature and its consumers to rebuild, rather than replaying the cached handle.
It does NOT cancel the preview still in flight. Both background runners
already keep one run in flight and coalesce the rest to the newest (the
browser worker parks it, latest wins; the native thread skips a Run
followed by another), so at most one intermediate of this same feature,
at a nearby value, finishes ahead of the final run, on a warm cache.
Cancelling instead terminated the browser worker on nearly every release
(a preview is almost always pending when the finger lifts): the final
value then waited for a new worker to instantiate the wasm module,
receive the parts library and rebuild the WHOLE history cold, which on a
phone took long enough that users re-opened the feature to see it.
User-invoked cancel (cancel_run) remains the way out of a slow run.
Sourcepub fn feature_dimension_drag(
&mut self,
feature_id: &str,
field_key: &str,
x: f64,
y: f64,
)
pub fn feature_dimension_drag( &mut self, feature_id: &str, field_key: &str, x: f64, y: f64, )
Drag a dimension handle: project the pointer pixel (x, y) onto the
annotation’s world axis (pointA → pointB), take the distance along the
axis from pointA as the new value (correcting for any transform scale so
the PARAM — not the scaled world length — is what changes), set the param,
and re-run the history live. Degenerate projections (parallel ray / zero
axis) no-op.
Sourcepub fn feature_dimension_set_value(
&mut self,
feature_id: &str,
field_key: &str,
input: &str,
)
pub fn feature_dimension_set_value( &mut self, feature_id: &str, field_key: &str, input: &str, )
Edit a dimension value from a label field: a plain numeric literal sets the
param to that number; otherwise the input is treated as an EXPRESSION —
evaluated LIVE against the history’s expressions + configurator (the
kernel eval_expression) and, on success, STORED as the expression string
(the kernel re-evaluates it via ctx.number, so it stays live). A blank /
bad-expression input no-ops (never corrupts the feature). Re-runs live.
Source§impl EngineState
impl EngineState
Sourcepub fn interference_check(&mut self) -> InterferenceReport
pub fn interference_check(&mut self) -> InterferenceReport
Self::interference_check_with without a near-miss check.
Sourcepub fn interference_check_with(&mut self, clearance: f64) -> InterferenceReport
pub fn interference_check_with(&mut self, clearance: f64) -> InterferenceReport
Run the interference check over every component instance (hidden ones
included — interference is a physical question), plus the near-miss
check for gaps up to clearance mm (0 = off). Non-destructive: the
component solids are only READ; each pairwise INTERSECT result is
measured, tessellated for the overlay, and freed. Draws the overlay
and returns the full report for the results window.
Sourcepub fn show_interference_overlay(&mut self, report: &InterferenceReport)
pub fn show_interference_overlay(&mut self, report: &InterferenceReport)
Draw report in the viewport: interference volumes as red triangles,
near-miss gaps as an amber segment with its two end points. An empty
report removes the group.
Sourcepub fn clear_interference_overlay(&mut self)
pub fn clear_interference_overlay(&mut self)
Remove the interference overlay (window closed, report stale).
Sourcepub fn zoom_to_components(&mut self, component_ids: &[String])
pub fn zoom_to_components(&mut self, component_ids: &[String])
Frame the camera on the union of the given components’ member solids (the interference window’s row click). Unknown ids are ignored.
Source§impl EngineState
impl EngineState
Sourcepub fn interference_page(
&mut self,
scope: Option<Vec<String>>,
budget: usize,
token: Option<String>,
clearance: Option<f64>,
) -> Result<Value, String>
pub fn interference_page( &mut self, scope: Option<Vec<String>>, budget: usize, token: Option<String>, clearance: Option<f64>, ) -> Result<Value, String>
A pair budget bounds progress even for assemblies whose boxes are disjoint. Zero-volume intersections do not establish contact: without an exact distance witness they remain unresolved (never an all-clear).
Source§impl EngineState
impl EngineState
Sourcepub fn geometry_diagnostics(&self, id: &str) -> Option<Value>
pub fn geometry_diagnostics(&self, id: &str) -> Option<Value>
Full diagnostics from the last batch, including a rolled-back attempt.
Sourcepub fn stage_feature_begin(&mut self, item: &Value) -> Result<String, String>
pub fn stage_feature_begin(&mut self, item: &Value) -> Result<String, String>
Wait on the installed native runner, preserving its resident geometry
and delta baseline. A transaction is one app command, so other commands
cannot observe its intermediate recipes. Kernel operations are not
preemptible inside a feature.
Stage ONE feature without waiting for it (an agent’s cad.* write,
contract §5.1/§6): snapshot the recipe, metadata and parts library,
append the seeded, validated feature and hand its run to the runner,
then return. Self::stage_feature_poll finishes it on the frame the
run lands — committing it as one undo checkpoint, or restoring the
snapshot if it failed — so no frame waits for geometry. One stage at a
time per document; item is a batch item ({type, params, …}).
Sourcepub fn stage_feature_pending(&self) -> bool
pub fn stage_feature_pending(&self) -> bool
Whether a feature is staged and its run has not been finished yet.
Sourcepub fn stage_feature_poll(&mut self) -> Option<Result<Value, String>>
pub fn stage_feature_poll(&mut self) -> Option<Result<Value, String>>
Finish a staged feature once its run has landed: None while it is
still evaluating, else its row {id, committed, status, generatedSolids, error}.
Full-document rollback includes recipe, library, metadata, counters and undo/redo. Runtime caches and the generation counter are deliberately invalidated, not rewound. No file, network or document-tab side effects.
Source§impl EngineState
impl EngineState
Sourcepub fn restore_plugins(&mut self, packages: Value) -> Result<(), String>
pub fn restore_plugins(&mut self, packages: Value) -> Result<(), String>
Restore persisted installations in one atomic registry revision.
Sourcepub fn submit_plugin_installations(
&mut self,
installations: Value,
) -> Result<u64, String>
pub fn submit_plugin_installations( &mut self, installations: Value, ) -> Result<u64, String>
Submit a complete installation set to the runner for atomic validation. Does not enable code or change an existing registry before the reply succeeds.
pub fn plugin_installation_status(&self) -> Value
Sourcepub fn set_plugin_packages(
&mut self,
packages: Vec<PackageBundle>,
) -> Result<(), String>
pub fn set_plugin_packages( &mut self, packages: Vec<PackageBundle>, ) -> Result<(), String>
Restore explicitly installed/enabled packages, independently of loading a document.
pub fn install_plugin(&mut self, package: Value) -> Result<Value, String>
pub fn installed_plugins(&self) -> Value
pub fn export_plugin(&self, id: &str, digest: &str) -> Result<Value, String>
pub fn enable_plugin( &mut self, id: &str, digest: &str, enabled: bool, ) -> Result<(), String>
pub fn remove_plugin(&mut self, id: &str, digest: &str) -> Result<(), String>
pub fn plugin_catalogue(&self) -> Value
pub fn plugin_workbenches(&self) -> Value
Sourcepub fn feature_catalogue(&self) -> Value
pub fn feature_catalogue(&self) -> Value
Engine-local schema overlay; never adds package schemas to the process-wide built-ins.
pub fn feature_schema(&self, feature_type: &str) -> Option<Value>
pub fn feature_form_fields(&self, feature_type: &str) -> Vec<FormField>
pub fn feature_default_params(&self, feature_type: &str) -> Value
Sourcepub fn select_plugin(&mut self, id: &str, digest: &str) -> Result<(), String>
pub fn select_plugin(&mut self, id: &str, digest: &str) -> Result<(), String>
Selecting a first pin is undoable; replacing an existing pin requires migration.
pub fn migrate_plugin(&mut self, id: &str, digest: &str) -> Result<u64, String>
pub fn submit_plugin_action( &mut self, id: &str, params: Value, ) -> Result<(), String>
Sourcepub fn plugin_action(
&mut self,
id: &str,
params: Value,
selection: Value,
) -> Result<u64, String>
pub fn plugin_action( &mut self, id: &str, params: Value, selection: Value, ) -> Result<u64, String>
Submit a callback; neither callback commands nor recompute touch live history.
pub fn plugin_action_status(&self) -> Value
Sourcepub fn run_javascript(&mut self, source: &str) -> Result<u64, String>
pub fn run_javascript(&mut self, source: &str) -> Result<u64, String>
Run an editor script through the same worker and atomic undo transaction as named actions, without installing the editor source as a dependency.
pub fn poll_plugin_action(&mut self) -> Option<Result<Value, String>>
pub fn cancel_plugin_action(&mut self) -> bool
Source§impl EngineState
impl EngineState
pub fn plugin_panels(&self) -> Value
pub fn plugin_annotation_catalogue(&self) -> Value
Sourcepub fn annotation_schema(&self, kind: &str) -> Option<Value>
pub fn annotation_schema(&self, kind: &str) -> Option<Value>
Built-ins and document-scoped providers share the normal annotation form shape.
pub fn plugin_add_annotation( &mut self, view_id: &str, kind: &str, params: Value, ) -> Result<u64, String>
pub fn plugin_update_annotation( &mut self, id: &str, params: Value, ) -> Result<u64, String>
pub fn plugin_delete_annotation(&mut self, id: &str) -> Result<u64, String>
pub fn plugin_set_annotation_enabled( &mut self, id: &str, enabled: bool, ) -> Result<u64, String>
Source§impl EngineState
impl EngineState
Source§impl EngineState
impl EngineState
Sourcepub fn run_history_json(&mut self, request_json: &str) -> Result<String, String>
pub fn run_history_json(&mut self, request_json: &str) -> Result<String, String>
Run a whole history and reconcile the display scene (R10 incremental):
reused solids keep their buffers, the rest re-tessellate. Returns the build
report JSON ({featureErrors, unresolved, displayErrors}). Marks dirty.
A SCENE-ONLY one-shot: it does not touch the engine-owned history document
and does not run the Self::finish_apply tail, so it also does not paint
model colours. Callers that need those use Self::set_history_json.
Sourcepub fn pump(&mut self)
pub fn pump(&mut self)
Drain every completed run reply and APPLY it — the POLL/APPLY half of the
M2a seam. Called from rerun_history for the Inline
runner’s immediate apply, and once per frame from the app so a future async
runner’s completed runs land on the main thread. A reply older than
applied_generation (a newer run that finished
first) is dropped.
Sourcepub fn pump_holding_runs(&mut self)
pub fn pump_holding_runs(&mut self)
pump leaving a run reply, and a refusal asking for the
parts library, for a later pump: everything else drains. For a
background document whose library is not installed this frame (see
run_landing); a reply that arrives meanwhile
waits for the next frame, which installs the library first.
Sourcepub fn request_exact_solids<'a>(
&mut self,
names: impl IntoIterator<Item = &'a str>,
)
pub fn request_exact_solids<'a>( &mut self, names: impl IntoIterator<Item = &'a str>, )
Ask the runner for the B-rep topology of the displayed solids names
that the scene does not hold for their current handle and that have not
been asked for since the last applied run, then drain whatever has
already answered (all of it, for the synchronous Inline runner). The
drawing sheet’s door, and the balloon bubble drag’s (which re-projects
the arrow head on the exact solid, pmi_reproject_balloon_head):
nothing else needs topology on this side, so a document with neither a
sheet nor a dragged balloon never asks.
Sourcepub fn pump_topology(&mut self)
pub fn pump_topology(&mut self)
Fold every answered topology request into the scene. A reply for a display that has moved on to another handle is dropped; the next projection asks for the new one.
Sourcepub fn topology_pending(&self) -> bool
pub fn topology_pending(&self) -> bool
Whether a topology request is still in flight — the frame loop and the idle contract wait on it like a measurement query.
Sourcepub fn queries_pending(&self) -> bool
pub fn queries_pending(&self) -> bool
Whether a measurement query is still in flight (its reply not yet drained) —
the query analogue of run_pending, so the app keeps the
frame loop alive until a background runner’s measurement lands and displays.
Always false for the synchronous Inline runner.
Sourcepub fn mesh_imports_pending(&self) -> bool
pub fn mesh_imports_pending(&self) -> bool
Whether RANSAC reconstruction is still executing on the native runner thread or browser worker.
Sourcepub fn run_landing(&mut self) -> bool
pub fn run_landing(&mut self) -> bool
Whether the run in flight has something to land this frame: its reply,
a refusal to re-submit, or plugin work (which is not told apart). A
background document’s pump needs its own parts
library installed only then.
Sourcepub fn run_pending(&self) -> bool
pub fn run_pending(&self) -> bool
Whether a submitted run has not yet been applied (run_generation != applied_generation). Always false for the synchronous Inline runner
(submit → immediate pump keeps the two in lockstep); a background runner
uses it to keep the frame loop alive until its reply lands.
Sourcepub fn applied_generation(&self) -> u64
pub fn applied_generation(&self) -> u64
The generation of the last APPLIED run — bumps once per applied history run (document loads, edits, constraint mutations, solves). A cheap staleness key for app-side caches derived from the applied document (the update-components outdated badge keys on it).
Sourcepub fn run_progress(&self) -> Option<&RunProgress>
pub fn run_progress(&self) -> Option<&RunProgress>
What the in-flight run is executing right now, as far as the runner
has reported (see crate::runner::RunProgress); None when nothing
is running or the run has not reached its first executed feature.
Sourcepub fn cancelled_run(&self) -> Option<&str>
pub fn cancelled_run(&self) -> Option<&str>
The feature id the last cancelled run was executing (empty when it was cancelled before any progress arrived), until the next submit.
Sourcepub fn cancel_run(&mut self) -> bool
pub fn cancel_run(&mut self) -> bool
CANCEL the in-flight run. The runner abandons its work and comes back
with an EMPTY resident registry (a fresh thread / a fresh worker — see
crate::runner::HistoryRunner::cancel), so this side forgets
everything that was waiting on it: the run itself (generations are
bumped past it, so a straggling reply from the old runner is dropped
as stale), pending measurement queries, document-bound mesh imports
and a deferred fit. The DISPLAY SCENE is left as the last applied run
built it — the document is ahead of it now, which the notice says; the
next edit re-runs the whole history through the new runner (a cold
run: the warm cache went with the old one). Nothing inside a feature
is interruptible, so the native thread keeps burning CPU until the
feature it is on finishes; the browser worker is terminated outright.
false when nothing was running, or the runner cannot abandon (the
synchronous Inline runner, whose runs are over before anyone can ask).
Sourcepub fn runs_replied(&self) -> u64
pub fn runs_replied(&self) -> u64
How many run replies the runner has sent back (see runs_replied).
Sourcepub fn has_solids(&self) -> bool
pub fn has_solids(&self) -> bool
Whether the display scene currently holds at least one solid. Used by the
app’s async-safe first-frame framing: under a background runner (thread /
worker) the seed run lands a frame (or many) after boot, so the shell waits
for has_solids() && !run_pending() before its one-shot zoom_to_fit.
Sourcepub fn set_runner(&mut self, runner: Box<dyn HistoryRunner>)
pub fn set_runner(&mut self, runner: Box<dyn HistoryRunner>)
Swap in a different history runner (the platform injects its own — the native
app installs a ThreadRunner; wasm keeps the
default Inline until M3’s worker). Resets the new runner’s delta baseline so
the next run rebuilds fully. Call BEFORE seeding a document so the seed builds
through the installed runner.
Sourcepub fn set_history_json(&mut self, request_json: &str) -> Result<String, String>
pub fn set_history_json(&mut self, request_json: &str) -> Result<String, String>
Load a whole history document (a saved part file parses as one); the engine now OWNS this recipe. Rolls to the last feature and builds it.
The document’s top-level metadata field (the Properties-panel
name-keyed store) is lifted out into Self::metadata before the feature
list is handed to the kernel — loading a part REPLACES the store wholesale
(a document with no metadata clears it), mirroring the previous metadata
manager’s load semantics. Round-trips with Self::history_request_json.
The top-level workbench field (the ACTIVE-WORKBENCH id the save embedded
— see Self::history_request_json) is lifted off the kernel recipe the
same way and applied through Self::apply_settings_json — the SAME seam
the toolbar’s workbench dropdown writes through — so the palette / context
offers / workbench buttons react to a restored workbench exactly as they
do to a manual switch (settings generation bump included). Tolerances:
- a legacy document WITHOUT the field (or with a non-string value) leaves the current workbench untouched — opening an old file never yanks the user out of their workbench;
- an unknown/stale id is stored RAW (never an error): the settings layer
deliberately doesn’t validate ids, and every consumer resolves through
the app-side registry’s
resolve(), which falls back to the default workbench — so a file saved by a build with a workbench this build doesn’t know still opens cleanly; - the restored id is deliberately NOT persisted to the settings blob — that blob stays the user’s boot preference; a document’s workbench is session-scoped (the next explicit dropdown change persists as usual).
Sourcepub fn history_request_json(&self) -> String
pub fn history_request_json(&self) -> String
The whole history request document (persistence / debugging), with the engine-owned extras folded back in on top of the kernel recipe so save→open round-trips them:
metadata— the Properties-panel store, written only when non-empty so an un-annotated model persists as before;workbench— the CURRENT active-workbench id (self.settings.workbench), ALWAYS written so a saved part reopens in the workbench it was saved from (restored bySelf::set_history_json). Always-embed keeps the invariant simple: the serialized field tracks the LIVE setting, never a stale stored copy — the load lifts it off the kernel recipe entirely, so this is the ONE place it is (re)written. Note the deliberate consequence: switching workbench changes this document, so the file panel’s dirty flag flips — consistent with themetadataprecedent, and semantically true now that the workbench is part of the saved file.
Sourcepub fn history_request_value(&self) -> Value
pub fn history_request_value(&self) -> Value
Self::history_request_json as a value, for a caller that edits the
document (Update components): nothing is printed or parsed.
Sourcepub fn history_listing_json(&self) -> String
pub fn history_listing_json(&self) -> String
The tree listing { step, features:[{index,type,id}] } for the UI panel.
Sourcepub fn history_report_json(&self) -> String
pub fn history_report_json(&self) -> String
The last build report JSON.
pub fn history_len(&self) -> usize
Sourcepub fn history_rollback(&self) -> usize
pub fn history_rollback(&self) -> usize
The rolled-to (selected) feature index.
Sourcepub fn history_revision(&self) -> u64
pub fn history_revision(&self) -> u64
A monotonic counter of mutation opportunities on the history document —
the cache key for anything derived from it. See crate::history::History::revision.
pub fn feature_type_at(&self, index: usize) -> Option<String>
pub fn feature_id_at(&self, index: usize) -> Option<String>
Sourcepub fn feature_params_json(&self, index: usize) -> String
pub fn feature_params_json(&self, index: usize) -> String
The inputParams document of feature index ("null" if none) — the
dialog’s editing-buffer source.
Sourcepub fn next_feature_id(&mut self, base: &str) -> String
pub fn next_feature_id(&mut self, base: &str) -> String
Mint the id for a NEW feature: {base}{N} where base is the feature’s
shortName (crate::features::feature_short_name) and N is the part
history’s persistent GLOBAL counter (monotonic, never reused, round-trips
save/load — see History::next_feature_id). &mut because the counter
advances; if the caller’s add_feature then fails the number is simply
skipped (monotonic-with-gaps is the contract, not an error).
Sourcepub fn edit_document_json(&mut self, document: &str) -> Result<String, String>
pub fn edit_document_json(&mut self, document: &str) -> Result<String, String>
Adopt an edited document as one undo step and rebuild through the normal runner, preserving the tab’s scene settings and history stack.
Callers edit what Self::history_request_json gave them, which carries
the session’s workbench and thumbnail. Those are lifted off, as a load
lifts them (Self::set_history_json): a copy kept inside the history
goes stale at the next workbench switch or render and reads as an unsaved
change of the document (and a stamped thumbnail made a freshly refreshed
tab read dirty, which hid a reload that threw the refresh away).
Sourcepub fn edit_document(&mut self, value: Value) -> Result<String, String>
pub fn edit_document(&mut self, value: Value) -> Result<String, String>
Self::edit_document_json for a caller that holds the document as a
value: nothing is printed or parsed again (at 500 parts the library’s
text round trips were most of an Update Components commit).
Sourcepub fn rebuild_current_history(&mut self) -> String
pub fn rebuild_current_history(&mut self) -> String
Publish derived changes folded into the current user edit, without adding another undo step (for example PCB placement and its assembly pose).
Sourcepub fn roll_to(&mut self, index: usize) -> String
pub fn roll_to(&mut self, index: usize) -> String
Roll the model to feature index: re-run features[0..=index].
Sourcepub fn update_feature_params(
&mut self,
id: &str,
input_params_json: &str,
) -> Result<String, String>
pub fn update_feature_params( &mut self, id: &str, input_params_json: &str, ) -> Result<String, String>
Replace feature id’s input params and re-run at the current rollback →
the viewport updates live.
Sourcepub fn pattern_instance_of(&self, name: &str) -> Option<(String, i64)>
pub fn pattern_instance_of(&self, name: &str) -> Option<(String, i64)>
The pattern instance name (a copy solid, or a face/edge of one)
belongs to: (pattern feature id, instance number). For a part Pattern
the numbers are the kernel’s copy suffixes (PAT1_3 is instance 3; the
source is 1); for a Pattern Component, the instance component’s own
number (APAT1.ACOMP3.i3:Part, or the bare component id).
Sourcepub fn pattern_suppressed(&self, id: &str) -> Vec<i64>
pub fn pattern_suppressed(&self, id: &str) -> Vec<i64>
The Pattern feature id’s suppressed instance numbers.
Sourcepub fn pattern_set_suppressed(
&mut self,
id: &str,
number: Option<i64>,
suppressed: bool,
) -> Result<(), String>
pub fn pattern_set_suppressed( &mut self, id: &str, number: Option<i64>, suppressed: bool, ) -> Result<(), String>
Suppress (or unsuppress) instance number of the Pattern feature id:
one parameter edit, one undo step. None for number with
suppressed == false unsuppresses every instance.
Sourcepub fn update_many_feature_params(
&mut self,
edits: &[(String, Value)],
) -> Result<String, String>
pub fn update_many_feature_params( &mut self, edits: &[(String, Value)], ) -> Result<String, String>
Replace the inputParams of MANY features as ONE model edit — the
Self::update_feature_params batch sibling (Self::add_features is
the append-only one). ONE undo checkpoint and ONE history re-run for the
whole set.
The lane that needs it: a PACKED BOM row rolls up every occurrence whose
occurrence data matches, so editing one of its cells writes the same key
into N ACOMP features. Looping update_feature_params would cost N
re-runs and — worse — N undo entries, so taking back one visible edit
would need N presses of undo.
Unknown ids are reported (the whole batch is refused before anything is written, so a typo can never half-apply); an empty batch is a no-op that neither checkpoints nor runs.
Sourcepub fn add_feature(&mut self, feature_json: &str) -> Result<String, String>
pub fn add_feature(&mut self, feature_json: &str) -> Result<String, String>
Append a feature (a full {type, inputParams, …} descriptor) and roll to
it. The caller assigns a unique id (see Self::next_feature_id).
Sourcepub fn add_features(&mut self, features: &[Value]) -> String
pub fn add_features(&mut self, features: &[Value]) -> String
Append MANY features and roll to the last — Self::add_feature’s batch
sibling, and the reason it exists: add_feature re-runs the WHOLE history
per call, so a lane that appends N features by looping it costs N rebuilds
(O(N²) work on an N-part STEP-assembly import). This pushes all of them,
then re-runs ONCE — one rebuild, one undo checkpoint, one
applied_generation bump.
Deliberately NOT Self::set_history_json: that is the document-SWITCH
path (it clears the kernel history cache and resets the runner’s delta
baseline, forcing a full cold rebuild), which is the wrong mechanism for an
append onto the live document.
An empty batch is a no-op — no checkpoint, no run, no generation bump —
and returns the standing report. The caller assigns each feature’s unique
id (see Self::next_feature_id).
Sourcepub fn delete_feature(&mut self, id: &str) -> String
pub fn delete_feature(&mut self, id: &str) -> String
Delete the feature with id id (no-op if absent) and re-run, clamping the
rolled-to step.
Sourcepub fn delete_feature_at(&mut self, index: usize) -> String
pub fn delete_feature_at(&mut self, index: usize) -> String
Delete the feature at index (no-op when out of range) and re-run,
clamping the rolled-to step.
The POSITIONAL twin of Self::delete_feature, and the only way to
remove a feature whose inputParams carry no id — a shape a hand-built
history JSON can still contain, and one an id-keyed delete can never
address.
Sourcepub fn reorder_feature(&mut self, index: usize, up: bool) -> String
pub fn reorder_feature(&mut self, index: usize, up: bool) -> String
Move feature index one slot up/down (reorder), keeping it selected.
Source§impl EngineState
impl EngineState
Sourcepub fn can_undo(&self) -> bool
pub fn can_undo(&self) -> bool
Whether an undo step is available (to enable the toolbar’s Undo button).
Sourcepub fn undo(&mut self) -> String
pub fn undo(&mut self) -> String
Undo the last model mutation: restore the previous document + rolled-to step, then re-run + reconcile the scene. Returns the build report; a no-op (empty undo stack) returns the last report unchanged.
Sourcepub fn history_group_begin(&mut self) -> u64
pub fn history_group_begin(&mut self) -> u64
Open an undo group on this document’s history: every edit until
Self::history_group_end is one undo step (a script’s run).
Sourcepub fn history_group_end(
&mut self,
token: u64,
rollback: bool,
) -> Result<bool, String>
pub fn history_group_end( &mut self, token: u64, rollback: bool, ) -> Result<bool, String>
Close undo group token; with rollback, restore the document as it
was when the group opened and re-run. Whether it rolled back.
Sourcepub fn undo_before_edit(&mut self) -> bool
pub fn undo_before_edit(&mut self) -> bool
Self::undo without its run, for a caller that edits the document
straight after (the Work part replacing a coalesced step): that edit’s
run is the one the document needs, and an undo run before it would be
executed and thrown away. Whether there was a step to undo.
Sourcepub fn redo(&mut self) -> String
pub fn redo(&mut self) -> String
Redo the last undone model mutation (symmetric with Self::undo).
Source§impl EngineState
impl EngineState
Sourcepub fn load_model_and_fit(
&mut self,
request_json: &str,
) -> Result<String, String>
pub fn load_model_and_fit( &mut self, request_json: &str, ) -> Result<String, String>
Load a whole model document (a saved .nbrep recipe) and FRAME it:
set_history_json (which rolls to the last
feature) followed by zoom_to_fit. The one call the
file panel’s Open needs — the model IS the engine-owned history, so
opening a file is loading its request JSON and reframing. Returns the
build-report JSON.
Source§impl EngineState
impl EngineState
Sourcepub fn import_stl_feature(&mut self, bytes: &[u8]) -> Result<String, String>
pub fn import_stl_feature(&mut self, bytes: &[u8]) -> Result<String, String>
Import an STL triangle mesh through topology-aware RANSAC recognition. Unsupported regions remain as validated facets, so every repairable source triangle reaches the resulting CAD body.
Sourcepub fn import_obj_feature(&mut self, text: &str) -> Result<String, String>
pub fn import_obj_feature(&mut self, text: &str) -> Result<String, String>
Import a Wavefront OBJ mesh through the same RANSAC reconstruction path.
Sourcepub fn import_obj_bytes_feature(
&mut self,
bytes: &[u8],
) -> Result<String, String>
pub fn import_obj_bytes_feature( &mut self, bytes: &[u8], ) -> Result<String, String>
Byte-oriented OBJ entry used by the picker so decoding also stays on the background runner with parsing and reconstruction.
Sourcepub fn import_3mf_bytes_feature(
&mut self,
bytes: &[u8],
) -> Result<String, String>
pub fn import_3mf_bytes_feature( &mut self, bytes: &[u8], ) -> Result<String, String>
Import a 3MF package (core specification) through the same chain. The package is unzipped and its build flattened on the runner, so a large model never decompresses on the UI thread.
Sourcepub fn reconstruct_mesh_preview(
&mut self,
format: MeshImportFormat,
bytes: Vec<u8>,
options: StlConversionOptions,
) -> Result<u64, String>
pub fn reconstruct_mesh_preview( &mut self, format: MeshImportFormat, bytes: Vec<u8>, options: StlConversionOptions, ) -> Result<u64, String>
Reconstruct without editing history. The caller owns confirmation and
can inspect the exact STEP and diagnostics returned by take_mesh_preview.
pub fn take_mesh_preview(&mut self) -> Option<MeshImportReply>
Sourcepub fn take_mesh_preview_phase(&mut self) -> Option<MeshImportPhaseReply>
pub fn take_mesh_preview_phase(&mut self) -> Option<MeshImportPhaseReply>
The next phase of a preview import (its parsed mesh, then its regions), posted before the preview’s final reply.
Sourcepub fn submit_region_fit(&mut self, job: RegionFitJob)
pub fn submit_region_fit(&mut self, job: RegionFitJob)
Refit one region of a preview import on the runner (inline when the
runner cannot: a region is a small mesh). The reply comes back through
Self::take_region_fit.
pub fn take_region_fit(&mut self) -> Option<RegionFitReply>
Sourcepub fn submit_apply_region_choices(&mut self, job: ApplyRegionChoicesJob)
pub fn submit_apply_region_choices(&mut self, job: ApplyRegionChoicesJob)
Apply an interactive import’s region choices on the runner (inline
when the runner cannot). The reply comes back through
Self::take_apply_region_choices.
pub fn take_apply_region_choices(&mut self) -> Option<ApplyRegionChoicesReply>
Sourcepub fn import_step_feature(&mut self, step_text: &str) -> Result<String, String>
pub fn import_step_feature(&mut self, step_text: &str) -> Result<String, String>
Import a STEP document into the model: append an IMPORT3D feature whose
inputParams.stepText is the raw ISO-10303-21 text (the exact headless
source the kernel importer reads — no fileToImport data-URL marshaling
needed), mint it a persistent-counter id, roll to it, and rebuild. Returns the
build report JSON (imported bodies + any per-feature error). A non-STEP
payload is refused up front so a bad upload never leaves a dead feature.
Sourcepub fn export_step_text(&mut self) -> Result<String, String>
pub fn export_step_text(&mut self) -> Result<String, String>
Export the CURRENT model’s resident solids to an ISO-10303-21 STEP
document. Collects the resident handles of the rolled-to model (a warm
re-run of the same prefix the display scene was built from — see
crate::pipeline::resident_solid_handles) and hands them to the kernel’s
brep_kernel::export_step_handles, so the exact NURBS topology is
serialized (never the display mesh). Errs clearly when the model is empty.
Sourcepub fn export_step_text_named(
&mut self,
document_name: &str,
) -> Result<String, String>
pub fn export_step_text_named( &mut self, document_name: &str, ) -> Result<String, String>
Self::export_step_text with the document’s own name, which becomes
the root PRODUCT’s name (and the file’s FILE_NAME).
A document with ASSEMBLY COMPONENTS takes the STRUCTURED lane: each
parts-library entry is written once as its own product, in its own local
frame, and every instance becomes a NEXT_ASSEMBLY_USAGE_OCCURRENCE
carrying its pose — nested sub-assemblies included. Without components
the flat single-product writer is used, exactly as before.
Sourcepub fn export_step_text_selected(
&mut self,
document_name: &str,
only: Option<&[String]>,
) -> Result<String, String>
pub fn export_step_text_selected( &mut self, document_name: &str, only: Option<&[String]>, ) -> Result<String, String>
Self::export_step_text_named restricted to the resident solids
named in only (each must be one; none may repeat). A subset is a
flat part’s: a document with assembly components or a board refuses
it, and its PMI is left out, since the annotations may reference
solids the file no longer holds.
Sourcepub fn export_flat_pattern_dxf(&self) -> Result<String, String>
pub fn export_flat_pattern_dxf(&self) -> Result<String, String>
Export the part’s sheet-metal FLAT PATTERN (the unfold) as a DXF (R12
ASCII) 2D vector document. Runs the unfold TRANSIENTLY off the target
body’s resident tree — no feature is added and history is not mutated. Errs
("no sheet-metal body in the part") when the part carries no sheet metal.
Sourcepub fn export_flat_pattern_svg(&self) -> Result<String, String>
pub fn export_flat_pattern_svg(&self) -> Result<String, String>
Export the part’s sheet-metal flat pattern as an SVG — the DXF sibling of
Self::export_flat_pattern_dxf.
Sourcepub fn import_iges_feature(&mut self, iges_text: &str) -> Result<String, String>
pub fn import_iges_feature(&mut self, iges_text: &str) -> Result<String, String>
Import an IGES document into the model: append an IMPORT3D feature whose
inputParams.igesText is the raw IGES text (the kernel importer reads it
via brep_kernel::import_iges), mint an id, roll to it, and rebuild.
Refuses a non-IGES payload up front so a bad upload never leaves a dead
feature.
Sourcepub fn export_iges_text(&self) -> Result<String, String>
pub fn export_iges_text(&self) -> Result<String, String>
Export the CURRENT model’s resident solids to an IGES 5.3 document of
trimmed NURBS surfaces — the IGES analogue of Self::export_step_text,
handing the resident handles to brep_kernel::export_iges_handles.
Sourcepub fn export_stl_text(&self) -> Result<String, String>
pub fn export_stl_text(&self) -> Result<String, String>
Export the CURRENT display scene to an ASCII STL string (one solid with a
per-triangle geometric normal for every mesh triangle of every displayed
solid). STL is a triangle-soup format with no multi-body concept, so all
solids fold into a single solid brep … endsolid brep. String-shaped so it
crosses the same string ModelStore seam the STEP lane uses. Errs when the
scene has no triangles.
Sourcepub fn export_obj_text(&self) -> Result<String, String>
pub fn export_obj_text(&self) -> Result<String, String>
Export the CURRENT display scene as Wavefront OBJ text — the same
triangles Self::export_stl_text writes, folded into ONE object brep
with the display normals kept per vertex, through the kernel’s
brep_kernel::write_obj. Millimetres, like every other export lane.
Errs when the scene has no triangles.
Sourcepub fn export_glb_bytes(&self, document_name: &str) -> Result<Vec<u8>, String>
pub fn export_glb_bytes(&self, document_name: &str) -> Result<Vec<u8>, String>
Export the CURRENT display scene as a binary glTF 2.0 (.glb) document —
the same triangles Self::export_stl_text and Self::export_obj_text
write, through the kernel’s brep_kernel::write_glb. Unlike those two,
glTF HAS a multi-body concept, so each scene solid becomes its own named
mesh instead of folding into one object.
BINARY, not text: the bytes cross the store’s byte-shaped interchange
(export_file_named_bytes), because base64 through the text lane would
inflate the file by a third for nothing.
The axis convention (+Y up, which is both glTF’s and this application’s,
so the identity) and the millimetre-to-metre unit both ride on the root
NODE’s transform — see the kernel module’s doc. COLOURS are the metadata
store’s, the same authority the STEP lane reads, with a face’s beating its
body’s; a body the store says nothing about takes the colour the viewport
shows it in (Self::display_body_color). override_model_colors is not
honoured, exactly as it is not by the STEP lane: it is a display switch
whose contract is that the store is never touched.
Errs when the scene has no triangles.
Sourcepub fn export_3mf_bytes(&self, document_name: &str) -> Result<Vec<u8>, String>
pub fn export_3mf_bytes(&self, document_name: &str) -> Result<Vec<u8>, String>
Export the CURRENT display scene as a 3MF package (.3mf) — the same
triangles the STL, OBJ and GLB lanes write, through the kernel’s
brep_kernel::write_3mf, one named <object> per scene solid with
its vertices welded (3MF wants a closed manifold, which the per-face
display soup is not). BINARY, so the bytes cross the store’s byte-shaped
interchange like a GLB’s.
COLOURS follow the STEP lane’s rule, not the GLB lane’s: the metadata
store is the authority, a face’s colour beats its body’s, and a body the
store says nothing about is written with NO material — 3MF, unlike glTF,
has that state, and it is what a slicer user wants of an unpainted part
(it prints in the filament’s colour, not a grey this app chose). The one
exception is the same as STEP’s: in the hashedBySolid face-colour mode
an uncoloured body is written in the name-derived colour the viewport
shows. override_model_colors is not honoured, as in the other lanes.
Errs when the scene has no triangles.
Sourcepub fn pdf3d_bodies(&self) -> Vec<Body>
pub fn pdf3d_bodies(&self) -> Vec<Body>
The solids a 3D PDF shows (crate::sheets::pdf3d::Body): every
visible, non-sketch solid with triangles, UN-POSED (an explode the
active PMI view applies to the viewport is that view’s, not the
model’s), coloured by the GLB lane’s rule — a face’s persisted colour,
else its body’s, else the colour the viewport shows the body in — with
its real edges (not the auxiliary or centre-line display edges).
Source§impl EngineState
impl EngineState
Sourcepub fn probe_step_assembly(
&mut self,
step_text: &str,
) -> Result<Option<StepAssemblyProbe>, String>
pub fn probe_step_assembly( &mut self, step_text: &str, ) -> Result<Option<StepAssemblyProbe>, String>
Read a STEP file’s product structure — THE parse of a structured import.
Stashes the parsed assembly (with every product’s solids) for
Self::import_probed_step_assembly and returns the dialog’s counts.
Ok(None) = no usable structure (no NAUO edges, or none reaching built
geometry): the caller imports through the flat
Self::import_step_feature lane with the text it already holds, which
is byte-for-byte today’s behaviour. Err only for text that is not a
Part 21 file at all — a BROKEN assembly degrades, it does not fail.
Replaces any previously stashed assembly on EVERY outcome, Ok(None)
included: a stale stash surviving a probe of a different file is how a
consume silently imports the wrong one.
Sourcepub fn submit_step_probe(&mut self, step_text: &str) -> u64
pub fn submit_step_probe(&mut self, step_text: &str) -> u64
SUBMIT a STEP text to be probed for product structure on the runner
(the parse builds every product’s bodies: seconds for a real assembly,
which is why it leaves the UI thread). The answer arrives through
Self::take_step_probe under the returned id, after a later pump;
a found structure is stashed for Self::import_probed_step_assembly.
Any earlier stash is dropped now — the probe REPLACES it on every
outcome, so a stale parse can never be consumed for the wrong file.
The structure test the parse would make is “any NEXT_ASSEMBLY_USAGE_
OCCURRENCE entity” (assembly_edges), so a text with none cannot have
structure and is answered Flat without a trip to the runner: a part
file — the common upload — no longer pays a full parse only to be told
to take the flat lane, where the worker parses it anyway. (The text
test is a superset of the entity test: a stray mention in a comment
merely runs the parse.)
Sourcepub fn take_step_probe(&mut self) -> Option<(u64, StepProbeOutcome)>
pub fn take_step_probe(&mut self) -> Option<(u64, StepProbeOutcome)>
The oldest answered probe, if any: its submission id and what it found.
Sourcepub fn step_probes_pending(&self) -> bool
pub fn step_probes_pending(&self) -> bool
Whether a submitted probe has not been answered yet — the app keeps the frame loop alive (and the panel its “reading…” status) while it is.
Sourcepub fn import_probed_step_assembly(
&mut self,
doc_name: &str,
opts: StepAssemblyImport,
sink: &mut dyn PartSink,
) -> Result<StepAssemblyReport, String>
pub fn import_probed_step_assembly( &mut self, doc_name: &str, opts: StepAssemblyImport, sink: &mut dyn PartSink, ) -> Result<StepAssemblyReport, String>
Import the assembly Self::probe_step_assembly stashed: one
parts-library entry per unique product, one ACOMP instance per
occurrence, ONE rebuild. TAKES the stash, so a double-import is an error
rather than a double-insert.
doc_name names products the file left unnamed ({doc_name}-part-{id}).
opts.nested chooses between the flat and nested shapes — see
StepAssemblyImport::nested. Errs when nothing is stashed, and when
every product failed to encode — the latter being the caller’s cue to
re-run the flat import with the file text it holds.
sink receives every unique part document so the app can write it to
the model store and hand back a real sourceKey; pass EmbeddedOnly
to keep the parts embedded (what a caller with no store does).
Sourcepub fn discard_probed_step_assembly(&mut self)
pub fn discard_probed_step_assembly(&mut self)
Drop a probed assembly and the solids it holds resident — the dialog’s Cancel. Idempotent.
Sourcepub fn import_step_assembly(
&mut self,
step_text: &str,
doc_name: &str,
opts: StepAssemblyImport,
) -> Result<StepAssemblyReport, String>
pub fn import_step_assembly( &mut self, step_text: &str, doc_name: &str, opts: StepAssemblyImport, ) -> Result<StepAssemblyReport, String>
Probe + consume in one call, falling back to the flat lane by itself — the HEADLESS/test entry point. The app uses the probe/consume pair instead, because it has a dialog between the two halves.
Still exactly one parse: this is probe_step_assembly followed by the
consume of what it stashed.
Parts stay EMBEDDED here (EmbeddedOnly): this entry point has no
store handle and no way to ask for a destination. The app uses the
probe/consume pair with a real sink.
Source§impl EngineState
impl EngineState
Sourcepub fn pick_candidates_at(&self, x: f64, y: f64) -> Vec<PickCandidate>
pub fn pick_candidates_at(&self, x: f64, y: f64) -> Vec<PickCandidate>
EVERY pick candidate under CSS-pixel (x, y): the scene’s
vertices/edges/faces/solids (pick::pick) PLUS the construction PLANE
cards the pointer ray crosses, ranked together category-major
(VERTEX > EDGE > FACE > PLANE > SOLID > COMPONENT), nearest first within a
category.
This is the RAW list (no selection filter); the filter-honoring callers are
Self::candidates_filtered_at (the pick-list popup) and
Self::pick_top_at (every single-hit pick).
Sourcepub fn candidate_kind_label(&self, candidate: &PickCandidate) -> &'static str
pub fn candidate_kind_label(&self, candidate: &PickCandidate) -> &'static str
The kind LABEL a candidate should present under — PickKind::as_str,
except that a committed-sketch sheet reads "SKETCH" rather than the
"SOLID" its PickKind carries. The pick-list popup and the published
candidate JSON both use it, so what a row calls itself matches the filter
lane that admitted it.
Source§impl EngineState
impl EngineState
Sourcepub fn pick_json(&self, x: f64, y: f64) -> String
pub fn pick_json(&self, x: f64, y: f64) -> String
Ranked candidate list under CSS-pixel (x, y), kernel names, priority
VERTEX > EDGE > FACE > … > SOLID.
SCENE ONLY, deliberately: this R3-boundary accessor (and its
hover_json sibling) reports kernel-named GEOMETRY, and
its in-tree consumer is the sketch’s external-edge picker, which wants
edges. The construction PLANE cards join the pick list one level up, in
pick_candidates_at — that is what the
selection paths and the app’s pick-list popup consume.
Sourcepub fn hover_json(&self, x: f64, y: f64) -> String
pub fn hover_json(&self, x: f64, y: f64) -> String
The single best candidate under (x, y) (hover), or null.
pub fn apply_settings_json(&mut self, json: &str) -> Result<(), String>
Sourcepub fn settings_json(&self) -> String
pub fn settings_json(&self) -> String
The FULL current settings as JSON (the round-trip counterpart of
apply_settings_json): the schema-driven form seeds its widgets from
this and the storage seam persists it.
Sourcepub fn settings_value(&self) -> Value
pub fn settings_value(&self) -> Value
Self::settings_json as a JSON value.
Sourcepub fn solid_color_overrides_json(&self) -> String
pub fn solid_color_overrides_json(&self) -> String
The current per-solid metadata color overrides as JSON —
[{"name": "...", "override": "#rrggbb" | null}, …]. Lets a UI list the
scene’s solids with their current override so the picker reflects state.
pub fn apply_emphasis_json(&mut self, json: &str) -> Result<(), String>
Sourcepub fn set_visible(&mut self, name: &str, visible: bool) -> bool
pub fn set_visible(&mut self, name: &str, visible: bool) -> bool
Show or hide the scene object name. A committed SKETCH has one
visibility, hidden_sketches (the Scene checkbox’s): its sheet solid’s
own flag is rebuilt away by every refresh, so a sketch name goes through
Self::set_sketch_visible whichever path asked (context-bar Hide,
MCP set_visible, a Scene “all” toggle). False for an unknown name.
While a PMI view is active, hiding or showing a solid is an edit of
that view’s hide steps (Self::pmi_record_visibility), never a
live-only change the next exit or re-entry would lose.
Sourcepub fn set_visible_many(&mut self, names: &[String], visible: bool) -> usize
pub fn set_visible_many(&mut self, names: &[String], visible: bool) -> usize
Self::set_visible for several names at once — a BOM row or a
component standing for many solids — so an active view records ONE
hide step (one undo) for them all. How many names were known.
pub fn scene_listing_json(&self) -> String
Sourcepub fn depth_range_bbox(&self) -> Aabb
pub fn depth_range_bbox(&self) -> Aabb
The BASE bbox the camera depth-range fit starts from: the visible SOLIDS
unioned with the pushed OVERLAY groups (sketch curves/points, dimension
leaders, constraint glyphs — the set_overlay channel). Folding in the
groups stops orbiting an editing sketch from clipping it against the
solids-only bounds (the reported clipping when “Lock to sketch” is off).
The render path (Self::fit_camera_and_overlay) unions the FULL widget
overlay’s world bounds (datum planes, world axes, frames, transform
gizmo — NOT in this bbox’s channels) and the world origin on top of this
before fitting, so construction geometry never clips. Callers must bind
this to a local before camera.fit_depth_range (which needs
&mut self.camera).
Source§impl EngineState
impl EngineState
Sourcepub fn scene_entities_json(&self) -> String
pub fn scene_entities_json(&self) -> String
A RICHER scene listing than scene_listing_json
(which is counts only): per solid the individual face + edge kernel NAMES
and vertex refs (topo id + world position), plus visibility — the shape the
engine-native Scene tree lists entities from and the headed verifier asserts
against. Vertices carry no kernel name, so they are keyed by topo id + world
position (the same shape the emphasis vertex-ref selection uses).
Sourcepub fn select_by_name(&mut self, kind: &str, name: &str) -> bool
pub fn select_by_name(&mut self, kind: &str, name: &str) -> bool
Drive the engine SELECTION by kernel NAME from a UI tree (the name-based
analogue of select_top_at, which picks under the
cursor). Replaces the current selection with the single named solid /
face / edge so clicking a Scene-tree row highlights that entity in the
viewport (the render pass reads emphasis). Vertices have no kernel name —
use select_vertex_by_position. Returns
false for an unknown kind or an empty name.
Sourcepub fn select_vertex_by_position(
&mut self,
solid: &str,
position: [f64; 3],
) -> bool
pub fn select_vertex_by_position( &mut self, solid: &str, position: [f64; 3], ) -> bool
Select a single vertex by its owning solid + world position — vertices have no kernel name, so emphasis keys them by solid + position (matched with a tolerance in the render pass). Replaces the current selection. Returns false for an empty solid name.
Sourcepub fn hover_by_name(&mut self, kind: &str, name: &str) -> bool
pub fn hover_by_name(&mut self, kind: &str, name: &str) -> bool
Hover-highlight by kernel NAME from a UI tree — the hover twin of
select_by_name (kind is "solid" / "face" /
"edge" / "datum"; vertices carry no kernel name, so they use
hover_vertex_by_position).
Deliberately does NOT consult the selection filter, matching the row’s
CLICK: a row selects whatever kind it is, so its hover previews the same
entity. An unknown kind, an empty name or an unresolved datum frame is
refused without touching the current hover.
Call it EVERY frame the row is hovered: it re-arms the one-frame
take_scene_tree_hover yield flag and
re-lights nothing when the hover is already this entity. Returns whether
the hover CHANGED (the hover_at convention) so the
caller can request a repaint.
Sourcepub fn hover_vertex_by_position(
&mut self,
solid: &str,
position: [f64; 3],
) -> bool
pub fn hover_vertex_by_position( &mut self, solid: &str, position: [f64; 3], ) -> bool
Hover a single vertex by its owning solid + world position — the hover twin
of select_vertex_by_position (vertices
have no kernel name, so emphasis keys them by solid + position). Same
per-frame contract and return as hover_by_name.
Sourcepub fn scene_tree_hover_end(&mut self) -> bool
pub fn scene_tree_hover_end(&mut self) -> bool
The pointer left the Scene tree’s rows: drop the row-driven highlight. Clears ONLY a hover the tree itself lit and that is STILL lit — if the viewport has since hovered something else (it may draw before the panel in the dock), that hover is left alone. Safe to call every frame no row is hovered: the target is taken, so it is a no-op from the second call on. Returns whether the hover changed.
Sourcepub fn take_scene_tree_hover(&mut self) -> bool
pub fn take_scene_tree_hover(&mut self) -> bool
Consume the one-frame “a Scene-tree row is hovering an entity” flag — the
viewport’s modeling hover branch skips its pointer-off-viewport
clear_hover while it is set (mirrors
take_sketch_list_hover) so the row-driven
highlight survives the frame instead of being cleared and re-applied.
Source§impl EngineState
impl EngineState
Sourcepub fn hover_entity_by_name(&mut self, owner: &'static str, name: &str) -> bool
pub fn hover_entity_by_name(&mut self, owner: &'static str, name: &str) -> bool
Hover-highlight the entity a DIALOG row names — the kind-less twin of
hover_by_name, for the lists that show a bare
kernel name (a reference line, an Outputs line, the picker card).
owner is the pane that is hovering ("history", "constraints",
"pmi", "refsel"): dialog_hover_end acts
only for the owner that set the hover, so panes that are on screen together
in a split dock cannot end each other’s highlight.
The name is resolved by resolve_entity_name,
which also covers the row whose entity the feature CONSUMED — an open
fillet form is rolled to the fillet, so its Edges rows name edges that no
longer exist and the blend faces the kernel built from them are lit
instead. Call it EVERY frame the row is hovered: the resolution is memoized
on the row text and the emphasis re-feed is deduped, so a held hover costs
nothing. Returns whether the hover CHANGED (the
hover_at convention), so the caller can repaint.
Sourcepub fn dialog_hover_end(&mut self, owner: &'static str) -> bool
pub fn dialog_hover_end(&mut self, owner: &'static str) -> bool
The pointer left owner’s dialog rows: drop the row-driven highlight.
Clears ONLY a hover THIS owner lit and that is STILL lit — a pane that
never hovered a row (or whose hover the viewport has since replaced) is a
no-op, which is what lets every consumer call it unconditionally every
frame. Returns whether the hover changed.
Sourcepub fn take_dialog_hover(&mut self) -> bool
pub fn take_dialog_hover(&mut self) -> bool
Consume the one-frame “a dialog row is hovering an entity” flag — the
viewport’s modeling hover branch skips its pointer-off-viewport
clear_hover while it is set (the twin of
take_scene_tree_hover).
Source§impl EngineState
impl EngineState
Sourcepub fn model_inspect_poll(&mut self) -> Option<Value>
pub fn model_inspect_poll(&mut self) -> Option<Value>
Mass properties for the Inspector panel, from the kernel’s exact
(divergence-theorem) integrator. name = Some(solid) reports that resident
solid; None reports the whole model. density (mass units per mm³; the
kernel length convention is millimetres) scales mass and the inertia
tensor — the centroid and principal axes are density-independent.
Returns JSON:
{ "ok": true, "target": "Box", "solidCount": 1, "density": 1.0,
"volume": 5738.05, "surfaceArea": 2927.79, "mass": 5738.05,
"centroid": [10.0, 10.0, 10.0],
"inertia": [[..],[..],[..]] | null,
"principalMoments": [a,b,c] | null,
"principalAxes": [[..],[..],[..]] | null }A single resolved solid carries the full centroidal inertia tensor +
principal axes/moments; a multi-solid aggregate reports summed volume /
area / mass and the volume-weighted centroid, with the tensor fields
null (select one solid for its inertia). ok:false with a message on
no solids / an unknown name / an integrator failure.
The model summary an agent checks a build against: every scene solid
with resident geometry, each with its kernel validation (topology
incidence checks; an error issue makes it invalid), its exact volume
and its display bounds (the mesh’s world box, which edges lie on).
valid is true only when every solid validated and measured; an empty
model is valid with no solids, bounds and volume null. Numbers the
kernel could not give are null with a warning naming the solid.
The checks run on the RUNNER, against its warm registry, as
measurement queries (crate::runner::MeasureKind::Inspect): None
while any is still in flight (call again on a later frame). A
main-thread re-execution of the history — what a resident-handle
collection here would cost — replayed a 27 MB STEP import on the frame
thread for 157 s (2026-10-28).
pub fn mass_properties_json(&self, name: Option<&str>, density: f64) -> String
Source§impl EngineState
impl EngineState
Sourcepub fn selection_filter(&self) -> SelectionFilter
pub fn selection_filter(&self) -> SelectionFilter
The current selection filter (a cheap Copy) — a panel reads it to seed
its toggles, edits the copy, and writes back via set_selection_filter.
Sourcepub fn set_selection_filter(&mut self, filter: SelectionFilter)
pub fn set_selection_filter(&mut self, filter: SelectionFilter)
Replace the whole selection filter. Purely a policy change (no geometry or camera moves), so it does NOT mark the scene dirty; the NEXT click honors it.
Sourcepub fn set_kind_pickable(&mut self, kind: &str, on: bool)
pub fn set_kind_pickable(&mut self, kind: &str, on: bool)
Toggle one kind’s pickability by name ("SOLID"/"FACE"/"EDGE"/"VERTEX").
Sourcepub fn selection_filter_json(&self) -> String
pub fn selection_filter_json(&self) -> String
The filter as JSON ({"SOLID":true,…,"PLANE":true,"COMPONENT":true}) —
lets a UI / the headed verifier read the pickable-kind state.
Sourcepub fn apply_selection_filter_json(&mut self, json: &str) -> Result<(), String>
pub fn apply_selection_filter_json(&mut self, json: &str) -> Result<(), String>
Apply a partial filter JSON (any subset of the keys); absent keys keep
their current value. The round-trip counterpart of selection_filter_json.
Sourcepub fn select_filtered_at(&mut self, x: f64, y: f64) -> bool
pub fn select_filtered_at(&mut self, x: f64, y: f64) -> bool
The filter-honoring plain-click selection (what select_top_at delegates
to): resolve the TOP-priority candidate under (x, y) whose kind the filter
admits (via pick_top_at with the enabled kinds —
scene entities AND construction plane cards) and select THAT kind, replacing
the current selection. A miss — or a click while the filter
admits nothing — clears the selection. Returns whether something selected.
Sourcepub fn has_selection(&self) -> bool
pub fn has_selection(&self) -> bool
Whether ANYTHING is currently selected (solids/faces/edges/vertices OR a
construction datum/plane) — distinct from emphasis.is_empty() (which also
counts hover). Drives the selection action bar’s visibility: a datum-only
selection must show the bar so the plane can offer “Sketch”.
Sourcepub fn hide_selected(&mut self) -> usize
pub fn hide_selected(&mut self) -> usize
Toggle the visibility of EXACTLY what is selected (the action bar’s
Hide/Show): each selected SOLID flips its whole-solid visibility
(set_visible); each selected FACE / EDGE / VERTEX
flips only that sub-entity (set_entity_visible,
the same per-entity mask the Scene-tree checkboxes use — a hidden face’s
triangles are simply not drawn). Every target toggles INDEPENDENTLY off its
own live state (hide if visible, show if hidden), so a mixed / repeat click
flips each item. Returns how many targets were toggled. Leaves the selection
as-is, so a second click toggles the same items back.
Source§impl EngineState
impl EngineState
Sourcepub fn clear_selection(&mut self) -> bool
pub fn clear_selection(&mut self) -> bool
Clear the current SELECTION (Esc): drop all selected solids/faces/edges/ vertices (hover is left untouched). Bumps the emphasis generation + marks dirty only when something was actually cleared. Returns whether it changed.
Sourcepub fn set_selection(
&mut self,
solids: &[String],
faces: &[String],
edges: &[String],
datums: &[String],
)
pub fn set_selection( &mut self, solids: &[String], faces: &[String], edges: &[String], datums: &[String], )
REPLACE the whole selection with these named entities — the write twin of
Self::selection_json, and the only way to put a MULTI-entity selection
back the way it was (select_by_name takes one name and clears the rest).
Names are taken as given, IN THE ORDER GIVEN: this is the write twin of a
pick order, so a selection saved from selection_json and put back here
seeds exactly what it seeded before. An unknown name simply highlights
nothing, the same as a stale name after a rebuild. VERTICES are not
addressable here —
they have no kernel name and emphasis keys them by position
(Self::select_vertex_by_position) — so a saved selection’s vertices do
not come back through this call.
Sourcepub fn select_feature(&mut self, id: &str) -> bool
pub fn select_feature(&mut self, id: &str) -> bool
SELECT a feature, as the history tree’s single click does: the feature becomes the selected one and the geometry it contributed to the model on screen becomes the viewport selection, replacing whatever was selected.
What a feature “contributed” is read from the last run, first match wins: the FACES it created that are still in the scene (a fillet’s blends, a hole’s bore — a feature later rewritten by another keeps its own faces); else the SOLIDS it was the last to write (a boolean, which makes no face of its own); else its own sketch or datum frames. A feature past the rollback has built nothing, so it selects with an empty geometry selection — the tree row still shows it.
Returns false, changing nothing, when id is not a feature.
Sourcepub fn selected_feature(&self) -> Option<&str>
pub fn selected_feature(&self) -> Option<&str>
The feature selected through Self::select_feature, while the
geometry selection it made still stands and the feature still exists.
Any other selection — a viewport pick, Esc, Clear, a Scene-tree row —
replaces that geometry and so reads as the feature being deselected.
Sourcepub fn select_top_at(&mut self, x: f64, y: f64) -> bool
pub fn select_top_at(&mut self, x: f64, y: f64) -> bool
Select the top-priority pick under CSS-pixel (x, y) that the SELECTION
FILTER admits — replacing the current selection (a plain viewport click).
A miss (or a click when the filter admits nothing) clears the selection.
Marks dirty when the selection changed; returns whether something was
selected. The by-kind honoring lives in select_filtered_at in the
appended selection-filter impl block (kept separate so concurrent edits to
this primary block don’t conflict).
Sourcepub fn selection_json(&self) -> String
pub fn selection_json(&self) -> String
The current SELECTION (not hover) as JSON
{ solids:[..], faces:[..], edges:[..], vertices: n } — lets a UI / the
headed verifier read selection state (e.g. assert Esc cleared it).
Each array is in PICK ORDER, oldest first (OrderedNames): the first name in faces is the face that was picked
first, and a face toggled off and on again is last. That is the order
every seeder reads — the assembly constraint’s elements (whose first
element is the Distance BASE face), the context bar’s reference pre-fill,
a boolean’s target/tool, a fillet’s edge list — so the same picks seed the
same feature in every process. Order is per BUCKET: a face and an edge
picked in either order still list under faces and edges, and a seeder
that takes both reads them in ITS OWN kind order (the field’s
selectionFilter), which is fixed by the schema.
Sourcepub fn selection_value(&self) -> Value
pub fn selection_value(&self) -> Value
Self::selection_json as a JSON value.
Sourcepub fn ref_select_active(&self) -> bool
pub fn ref_select_active(&self) -> bool
True while the reference-selection modal is active (the shell hides the rest of the UI and the viewport routes clicks to picking).
Sourcepub fn begin_ref_select(
&mut self,
feature_id: &str,
path: Vec<String>,
label: String,
filter: Vec<String>,
multiple: bool,
seed_names: Vec<String>,
)
pub fn begin_ref_select( &mut self, feature_id: &str, path: Vec<String>, label: String, filter: Vec<String>, multiple: bool, seed_names: Vec<String>, )
Enter reference-selection mode for feature feature_id’s param at path.
Seeds the running list from seed_names (the field’s current value), rolls
the model to the pre-feature “before” state (the step just before the
edited feature ran), and highlights the seeded names. filter constrains
the pick kind (["SOLID"], ["FACE"], …); multiple allows a list.
Sourcepub fn ref_select_names(&self) -> Vec<String>
pub fn ref_select_names(&self) -> Vec<String>
The running list of picked names (empty when not active) — the modal UI reads this back to draw its one-per-line list.
Sourcepub fn ref_select_label(&self) -> String
pub fn ref_select_label(&self) -> String
The active field’s label (for the modal heading), or empty.
Sourcepub fn ref_select_prompt(&self) -> String
pub fn ref_select_prompt(&self) -> String
A one-line summary of the active field for the modal heading:
"Tool solids (SOLID, multiple)".
Sourcepub fn ref_select_click(&mut self, x: f64, y: f64)
pub fn ref_select_click(&mut self, x: f64, y: f64)
A viewport click while active: type-constrained-pick the nearest allowed
hit under CSS-pixel (x, y) and add its name to the running list (single
fields replace; multiple fields append, de-duplicated). Re-lights the
highlight. No-op on a miss / an empty (unnamed) hit.
Sourcepub fn ref_select_candidates_at(&self, x: f64, y: f64) -> Vec<PickCandidate>
pub fn ref_select_candidates_at(&self, x: f64, y: f64) -> Vec<PickCandidate>
The candidates a reference pick may take under CSS-pixel (x, y), for
the PICK LIST the viewport opens on a dwelled (or Alt) click while a
reference field is picking: the raw list
(pick_candidates_at) admitted by the
field’s OWN kind strings — the same admission
ref_select_click applies — in the shared
pick-list order. A plain click takes the top admitted row by kind, so
with a ["SOLID","FACE","SKETCH"] field the face always wins it and the
solid behind that face is reachable only through this list. Empty when
no field is picking, for a sheet pick (anchors are on the paper), and
when a Work part’s context is in front (the click refuses that too).
Sourcepub fn ref_select_has_candidate(&self, candidate: &PickCandidate) -> bool
pub fn ref_select_has_candidate(&self, candidate: &PickCandidate) -> bool
Whether candidate is already in the running reference list — the pick
list’s per-row selected state while a reference field is picking.
Sourcepub fn ref_select_take_candidate(&mut self, hit: &PickCandidate)
pub fn ref_select_take_candidate(&mut self, hit: &PickCandidate)
Take ONE candidate into the running reference list — what a plain click does with its top hit, and what a pick-list row does with its own. The candidate resolves to a name exactly as the click’s did (a plane only by a resolved D/P frame name, a vertex as a coordinate ref for the targets that read one, a spline anchor as its owning port); single fields replace, multiple fields append, de-duplicated. No-op while no field is picking, for a sheet pick, and for a hit that resolves to no name.
Sourcepub fn ref_select_add_name(&mut self, name: String)
pub fn ref_select_add_name(&mut self, name: String)
Feed a picked NAME into the running list — what Self::ref_select_click
does after its pick (single fields replace; multiple fields append,
de-duplicated), for a caller that already holds the name (a test, an
automation driver). No-op while no selection is running.
Sourcepub fn ref_select_remove(&mut self, index: usize)
pub fn ref_select_remove(&mut self, index: usize)
Remove the name at index from the running list (the modal’s per-line X).
Sourcepub fn finish_ref_select(&mut self)
pub fn finish_ref_select(&mut self)
Finish: write the running names into the edited feature’s params at the field path, restore the rolled-to step, clear the highlight, and re-run so the feature rebuilds with the chosen references.
Sourcepub fn ref_select_ghosts_lit(&self) -> Vec<String>
pub fn ref_select_ghosts_lit(&self) -> Vec<String>
The ghosts a running instructions pick lights whole (Self::sync_ref_select_emphasis).
Sourcepub fn cancel_ref_select(&mut self)
pub fn cancel_ref_select(&mut self)
Cancel: discard the running selection, clear the highlight, restore the rolled-to step, and re-run (no param change).
Sourcepub fn ref_select_is_sheet(&self) -> bool
pub fn ref_select_is_sheet(&self) -> bool
Whether the active picker is picking ANCHORS on a drawing sheet — the
sheet viewport routes its clicks to Self::ref_select_pick_sheet_anchor
and the modal’s hint speaks of the paper rather than the 3D view.
Sourcepub fn ref_select_in_form(&self) -> bool
pub fn ref_select_in_form(&self) -> bool
Whether the active pick belongs to a FORM FIELD — a feature’s, an
assembly constraint’s, a PMI annotation’s or a sheet object’s reference
row. Such a pick is drawn by the field itself, the way other CAD
applications keep the dialog up and the selection box focused: the
field lists the picks, its button ends them, and the rest of the UI
stays. The other targets (a connection point’s seat, a spline anchor’s
port) are opened from list rows that have no field, so they keep the
top-right card and the shell steps everything else aside for them —
Self::ref_select_modal.
Sourcepub fn ref_select_modal(&self) -> bool
pub fn ref_select_modal(&self) -> bool
Whether a pick is up that takes the shell over (the dock folds away and the top-right card is the picker): an active pick that is NOT a form field’s. The shell’s “special mode” question.
Sourcepub fn ref_select_field(&self) -> Option<RefSelectField>
pub fn ref_select_field(&self) -> Option<RefSelectField>
The active pick as its form sees it — who it is for, which field, what
it holds — or None while no pick is up. A form draws the field whose
subject and path match as the FOCUSED one.
Sourcepub fn ref_select_claim(&mut self)
pub fn ref_select_claim(&mut self)
The pick’s form drew it this frame. Called by the form’s consumer every
frame it draws the focused field; read back by the shell through
Self::ref_select_take_claim.
Sourcepub fn ref_select_request_finish(&mut self)
pub fn ref_select_request_finish(&mut self)
Ask for the running pick to finish at the end of the frame (see
RefSelectState::finish_requested); the shell’s settle step does it.
Sourcepub fn ref_select_finish_requested(&self) -> bool
pub fn ref_select_finish_requested(&self) -> bool
Whether Self::ref_select_request_finish was called on the running
pick.
Sourcepub fn ref_select_take_claim(&mut self) -> bool
pub fn ref_select_take_claim(&mut self) -> bool
Whether the pick was claimed since the last call — and reset, so each
frame answers for itself. true while no pick is up, so the shell’s
“finish an unclaimed in-form pick” never fires on nothing.
Source§impl EngineState
impl EngineState
Sourcepub fn nearest_candidate_at(&self, x: f64, y: f64) -> Option<PickCandidate>
pub fn nearest_candidate_at(&self, x: f64, y: f64) -> Option<PickCandidate>
The ONE candidate under CSS-pixel (x, y) that the hover highlight lights
and a plain click takes: the filter-admitted candidate FIRST IN THE
RAYCAST by depth, the shared kind order breaking ties inside the nearest
depth layer (front_layer_winner).
None on a miss, or when the filter admits nothing.
Built from candidates_filtered_at, so
what the pointer promises is drawn from exactly the set the PICK LIST
offers — one selection rule over one list, never a second pick with its
own admission rules. The list’s own ordering is untouched.
The layer band is the camera’s world-per-pixel times the picker’s
EDGE_PICK_PX: the same 6 px neighbourhood
the picker already accepts laterally for an edge or a vertex, applied in
depth. It is a screen-space quantity, so it tracks zoom and model scale
without a unit of its own. (A face seen at a grazing angle changes depth
faster than that across 6 px, so its bounding edge can fall outside the
band and lose to the face — click nearer the edge, or dwell for the list.)
COMPONENT promotion mirrors
select_filtered_at: with the filter’s
COMPONENT lane on, a winner that is component geometry answers as its
owning COMPONENT, so the highlight lights the same whole component the
click would select.
Sourcepub fn hover_at(&mut self, x: f64, y: f64) -> bool
pub fn hover_at(&mut self, x: f64, y: f64) -> bool
Hover-highlight the candidate under CSS-pixel (x, y) that a plain click
would take — the NEAREST admitted hit by depth
(nearest_candidate_at) — setting it
HOVERED in emphasis (the renderer tints it). A miss — or a filter
admitting nothing — clears the hover. No-ops (returns false, no dirty)
when the hovered entity is unchanged, so a stationary pointer over the
same face doesn’t re-render every frame. Returns whether the hover state
changed — the signal the viewport’s dwell clock restarts on, so “how long
has THIS highlight been showing” is answered without a second pick.
The highlight is the promise the click keeps: both resolve through the one query above, so what lights up is what a plain click selects.
Sourcepub fn hover_is_lit(&self) -> bool
pub fn hover_is_lit(&self) -> bool
Whether ANY hover highlight is lit right now. The viewport’s dwell clock runs only over a lit highlight (there is nothing to open a list about over empty space), and this is the cheap read of that.
Sourcepub fn clear_hover(&mut self) -> bool
pub fn clear_hover(&mut self) -> bool
Clear the hover highlight (pointer moved to empty space / off the
viewport). Bumps the emphasis generation + marks dirty only when a hover
was actually lit. Returns whether it changed. (Distinct from
clear_selection, which leaves hover alone.)
Sourcepub fn hovered_json(&self) -> String
pub fn hovered_json(&self) -> String
The current HOVER (not selection) as JSON
{ solids:[..], faces:[..], edges:[..], vertices: n } — the hover twin of
selection_json so a UI / the headed verifier can
assert that moving the pointer over a face lit the hover emphasis.
Sourcepub fn select_toggle_at(&mut self, x: f64, y: f64) -> bool
pub fn select_toggle_at(&mut self, x: f64, y: f64) -> bool
TOGGLE the admitted pick under CSS-pixel (x, y) — the NEAREST by depth,
the one the hover highlight is showing — in the current
selection (a Ctrl/Cmd+click): add it if absent, remove it if present,
leaving the rest of the selection intact (unlike select_top_at, which
REPLACES). With the COMPONENT filter on, a hit on component geometry
toggles the whole component (all member solids as one unit). A miss — or
a filter admitting nothing — leaves the selection untouched (additive
mode never clears). Returns whether a hit was toggled.
Sourcepub fn candidates_at(&self, x: f64, y: f64) -> String
pub fn candidates_at(&self, x: f64, y: f64) -> String
The RANKED, filter-respecting candidates under CSS-pixel (x, y) as JSON
[{kind, name, solid, depth}] — the “candidates under the cursor” list
(feeds the pick-list popup + the headed verifier).
Sorted category-major in the pick-list order (VERTEX > EDGE > FACE >
PLANE > SOLID > COMPONENT), nearest (smallest depth) first within each
category — see candidates_filtered_at.
Sourcepub fn nearest_candidate_json(&self, x: f64, y: f64) -> String
pub fn nearest_candidate_json(&self, x: f64, y: f64) -> String
What a REGULAR (non-dwelling) viewport click at CSS-pixel (x, y) takes,
as one JSON {kind, name, solid, depth} — the same shape a row of
candidates_at carries — or null on a miss.
The automation bridge reads this to answer “would a click here reach the entity I named”: since the trigger moved, the top ROW of the list and what a plain click resolves to are no longer the same question, and a script that guesses wrong picks the wrong thing silently.
Sourcepub fn candidates_filtered_at(&self, x: f64, y: f64) -> Vec<PickCandidate>
pub fn candidates_filtered_at(&self, x: f64, y: f64) -> Vec<PickCandidate>
The same ranked, filter-respecting candidate list as typed values (the
in-process egui pick-list popup consumes these directly, then re-hovers /
selects a chosen one via hover_candidate /
select_candidate /
toggle_candidate). EMPTY when the filter admits
nothing (not the pick_filtered “empty filter = any” case).
The raw list is pick_candidates_at, so
construction PLANE cards are ordinary entries here — a plane under other
geometry is listed (right after the faces) instead of being reachable only
on a geometry miss.
With the filter’s COMPONENT lane on, one COMPONENT entry per owning
assembly component of ANY raw hit is appended (name = component id, depth
= the component’s nearest hit) — a raw hit of a filtered-OFF kind still
reaches its owning component, mirroring select_filtered_at’s
component-only promotion (a PLANE hit owns no component). The final list is
sorted category-major in the pick-list order
(VERTEX > EDGE > FACE > PLANE > SOLID > COMPONENT), nearest first within
each category.
Sourcepub fn candidate_is_selected(&self, candidate: &PickCandidate) -> bool
pub fn candidate_is_selected(&self, candidate: &PickCandidate) -> bool
Whether a candidate is CURRENTLY selected (drives the pick-list popup’s per-row selected state so click-toggling reads back visually).
Sourcepub fn hover_candidate(&mut self, candidate: &PickCandidate)
pub fn hover_candidate(&mut self, candidate: &PickCandidate)
Hover a SPECIFIC candidate (the popup entry the pointer is over) — sets it
HOVERED in emphasis, replacing any prior hover.
Sourcepub fn select_candidate(&mut self, candidate: &PickCandidate)
pub fn select_candidate(&mut self, candidate: &PickCandidate)
REPLACE the selection with a specific candidate (a plain click on a popup entry) — reuses the same bucketing as a plain viewport click.
Sourcepub fn toggle_candidate(&mut self, candidate: &PickCandidate) -> bool
pub fn toggle_candidate(&mut self, candidate: &PickCandidate) -> bool
TOGGLE a specific candidate in the selection (a Ctrl/Cmd+click on a popup
entry, or the select_toggle_at hit): add if
absent, remove if present. Returns whether it is NOW selected (true =
added, false = removed). Bumps the emphasis generation + marks dirty.
Source§impl EngineState
impl EngineState
Sourcepub fn set_sketch_overlay(&mut self, session: &SketchSession)
pub fn set_sketch_overlay(&mut self, session: &SketchSession)
Display a solved crate::sketch::SketchSession as a read-only overlay.
The plane geometry is tessellated to world space and pushed via
set_overlay_json; construction dashes are sized
against the LIVE camera so they stay screen-constant.
Sourcepub fn clear_sketch_overlay(&mut self)
pub fn clear_sketch_overlay(&mut self)
Remove the sketch overlay groups (feeding empty same-named groups upserts them to empty, which the overlay channel treats as a removal — other overlay groups are left untouched).
Source§impl EngineState
impl EngineState
Sourcepub fn sketch_dimension_labels_json(&self) -> String
pub fn sketch_dimension_labels_json(&self) -> String
The dimension labels for the active sketch (S5): one entry per dimensional
constraint — [{ id, text, world:[x,y,z], value, valueExpr, mode }]. world
is the label anchor in world space; brep-app projects it via
world_to_screen_json and draws editable text
there. [] when not in sketch mode.
Sourcepub fn sketch_dimension_value_json(&self, constraint_id: &Value) -> String
pub fn sketch_dimension_value_json(&self, constraint_id: &Value) -> String
The current {value, valueExpr, mode} for a dimensional constraint (S5) — the
seed for the inline edit field. {} when the constraint is absent / not in
sketch mode. mode is "distance" | "radius" | "diameter" | "angle". For a
diameter dim value is the DISPLAYED diameter (twice the stored radius), so
the edit field round-trips what the user sees.
Sourcepub fn sketch_set_dimension_value(
&mut self,
constraint_id: &Value,
input: &str,
) -> bool
pub fn sketch_set_dimension_value( &mut self, constraint_id: &Value, input: &str, ) -> bool
Edit a dimensional constraint’s value (S5), a port of the previous double-click edit:
- A PLAIN NUMBER (
^-?\d*\.?\d+$, optional exponent) → setvalueand REMOVEvalueExpr/valueExprMode(a literal dimension). - Otherwise → an EXPRESSION: set
valueExpr, evaluate it LIVE against the history’sexpressions+configurator(the kernel’seval_expression). On eval success setvalue; on FAILURE keep the old value and returnfalse(never corrupt the doc). A diameter dim stores half the entered/ evaluated diameter as the solver radius and tagsvalueExprMode:"diameter".
Sets valueNeedsSetup:false once a real value lands, re-solves (swallowing
errors), refreshes the overlay + marks dirty. Returns whether the value was
applied. No-op returning false when the constraint is absent / not in
sketch mode.
Sourcepub fn sketch_dimension_drag_to(
&mut self,
constraint_id: &Value,
x: f64,
y: f64,
)
pub fn sketch_dimension_drag_to( &mut self, constraint_id: &Value, x: f64, y: f64, )
Drag a dimension label to CSS-pixel (x, y) (S5): map the pixel to plane
(u, v) (the S2 pixel→plane math), compute the label offset {du, dv} =
(label uv) − (the dimension’s anchor uv), and store it in session.dim_offsets
keyed by the constraint id. Refreshes the overlay (leaders + labels follow the
cursor). No-op when not in sketch mode / the ray misses the plane / the
constraint is not dimensional.
Source§impl EngineState
impl EngineState
Sourcepub fn sketch_undo(&mut self) -> bool
pub fn sketch_undo(&mut self) -> bool
Undo the last sketch edit (S6a) — pop the undo stack, stash the current state on redo, restore. Returns whether anything was undone. A no-op (false) when not in sketch mode or the stack is empty.
Sourcepub fn sketch_redo(&mut self) -> bool
pub fn sketch_redo(&mut self) -> bool
Redo the last undone sketch edit (S6a) — the inverse of sketch_undo.
Returns whether anything was redone.
Sourcepub fn sketch_can_undo(&self) -> bool
pub fn sketch_can_undo(&self) -> bool
Whether a sketch undo is available (drives the mode-bar Undo button).
Sourcepub fn sketch_can_redo(&self) -> bool
pub fn sketch_can_redo(&self) -> bool
Whether a sketch redo is available (drives the mode-bar Redo button).
Sourcepub fn sketch_dimension_drag_end(&mut self)
pub fn sketch_dimension_drag_end(&mut self)
End a dimension-label drag gesture (S6a): reset the first-move snapshot guard so the NEXT drag records its own single undo step. No-op when not in sketch mode. Called from the viewport when the label drag stops.
Sourcepub fn sketch_diagnostics_dump_json(&self, feature_id: &str) -> String
pub fn sketch_diagnostics_dump_json(&self, feature_id: &str) -> String
A debug dump of a SKETCH feature’s document + solved diagnostics (S6a — the
dumpSketchDiagnostics button). Uses the LIVE session when that feature is
being edited, else reads the persisted sketch/basis off the history and
solves a throwaway session. Returns { error } when the feature is absent /
not a sketch / unparseable.
Source§impl EngineState
impl EngineState
Sourcepub fn sketch_trim_at(&mut self, x: f64, y: f64) -> bool
pub fn sketch_trim_at(&mut self, x: f64, y: f64) -> bool
Trim the geometry under CSS-pixel (x, y) (S6b): map to plane uv (the S2
pixel→plane math) and trim the geometry there. Returns whether the doc
changed. A no-op returning false when not in sketch mode, the ray misses the
plane, or no geometry is under the cursor.
Sourcepub fn sketch_trim_uv(&mut self, u: f64, v: f64) -> bool
pub fn sketch_trim_uv(&mut self, u: f64, v: f64) -> bool
The plane-space trim core (sketch_trim_at delegates here; so does the tool
state machine, which already has uv). Picks the nearest geometry within the
grab radius, snapshots undo, trims it (split or delete), re-solves + refreshes.
Returns whether the doc changed; a no-op pops its own undo snapshot so it never
leaves a dead step.
Source§impl EngineState
impl EngineState
Sourcepub fn sketch_pick_edge_at(&mut self, x: f64, y: f64) -> bool
pub fn sketch_pick_edge_at(&mut self, x: f64, y: f64) -> bool
Link (as a construction reference) the 3D solid edge under CSS-pixel (x, y)
into the active sketch (S6b-2). Ranks the pixel through the modeling picker,
takes the top EDGE candidate, and delegates to sketch_link_edge. Returns
whether a link was made / updated. A no-op returning false when not in sketch
mode or no scene edge is under the cursor.
Sourcepub fn sketch_link_edge(&mut self, edge_name: &str) -> bool
pub fn sketch_link_edge(&mut self, edge_name: &str) -> bool
Link a scene edge by kernel NAME into the active sketch as an external
reference (the headless-testable core sketch_pick_edge_at delegates to).
Fetches the edge’s world polyline from the scene, projects it into the sketch
plane, classifies + materializes (or updates) the reference, records one undo
snapshot (popped on a no-op), re-solves, and refreshes. Returns whether the doc
changed. A no-op returning false when not in sketch mode or the edge is
absent / degenerate.
Sourcepub fn sketch_external_ref_count(&self) -> usize
pub fn sketch_external_ref_count(&self) -> usize
The number of external-reference edge links in the active sketch (0 when not in
sketch mode) — the __brepSketch verifier readout.
Source§impl EngineState
impl EngineState
Sourcepub fn sketch_handdraw_begin(&mut self, x: f64, y: f64)
pub fn sketch_handdraw_begin(&mut self, x: f64, y: f64)
Begin a freehand stroke at CSS-pixel (x, y) (a handdraw drag start): map to
plane uv and delegate. No-op when not in sketch mode or the ray misses the plane.
Sourcepub fn sketch_handdraw_move(&mut self, x: f64, y: f64)
pub fn sketch_handdraw_move(&mut self, x: f64, y: f64)
Extend the freehand stroke toward CSS-pixel (x, y) (a handdraw drag move).
Sourcepub fn sketch_handdraw_begin_uv(&mut self, u: f64, v: f64)
pub fn sketch_handdraw_begin_uv(&mut self, u: f64, v: f64)
Begin a freehand stroke at plane (u, v) (the headless-testable core): snapshot
for undo (S6a), clear any prior stroke, and seed it with the start sample. The
undo snapshot is popped in sketch_handdraw_end if the stroke produces nothing.
No-op when not in sketch mode.
Sourcepub fn sketch_handdraw_move_uv(&mut self, u: f64, v: f64)
pub fn sketch_handdraw_move_uv(&mut self, u: f64, v: f64)
Append plane (u, v) to the live stroke (the headless-testable core), throttled
so a sample nearer than ~2px world to the last is skipped. No-op when not in
sketch mode or no stroke is live.
Sourcepub fn sketch_handdraw_end(&mut self) -> bool
pub fn sketch_handdraw_end(&mut self) -> bool
End the freehand stroke (a handdraw drag stop): recognize it into one shape and
materialize the geometry, re-solve, and clear the stroke + preview. A stroke that
is too short (fewer than 3 samples) or too tiny (extent below the grab radius) is
discarded, popping the undo snapshot recorded at begin so no dead step remains.
Returns whether geometry was created. No-op returning false when not in sketch
mode / no stroke is live.
Sourcepub fn sketch_handdraw_len(&self) -> usize
pub fn sketch_handdraw_len(&self) -> usize
The number of samples in the live handdraw stroke (0 when none / not in sketch
mode) — the __brepSketch verifier readout.
Source§impl EngineState
impl EngineState
Sourcepub fn sketch_selected_angle_constraint(&self) -> Option<Value>
pub fn sketch_selected_angle_constraint(&self) -> Option<Value>
The id of the ONE selected ∠ constraint when the sketch selection is
exactly that constraint and nothing else — the condition under which the
Sketch actions card offers “Angle measure”. None otherwise / not in sketch
mode.
Sourcepub fn sketch_cycle_angle_measure(&mut self) -> bool
pub fn sketch_cycle_angle_measure(&mut self) -> bool
Cycle the selected ∠ constraint to the NEXT way of measuring the angle
between its two lines, without moving any geometry:
- a convex reading (≤ 180°) steps to the adjacent sector counter-clockwise
around the intersection — points
[p0,p1,p2,p3]become[p3,p2,p0,p1]and the value becomes180 − value, so 167° flips to its 13° supplement, then 167°, 13°, and back to the start after four steps; - a reflex reading (> 180°) first comes back to the SAME sector measured
the short way — the lines swap (
[p2,p3,p0,p1]) and the value becomes360 − value— after which the steps above apply.
The value is transformed, never re-measured, so a conflicting constraint
keeps the intent it had; an expression dimension keeps its expression,
wrapped as 180 - (…) / 360 - (…). An unset value (valueNeedsSetup) is
seeded from the geometry first. Records an undo step, re-solves, refreshes
the overlay and marks the document dirty. Returns whether a constraint
changed; false unless exactly one ∠ constraint is selected.
Source§impl EngineState
impl EngineState
Sourcepub fn sketch_uv_at(&self, x: f64, y: f64) -> Option<(f64, f64)>
pub fn sketch_uv_at(&self, x: f64, y: f64) -> Option<(f64, f64)>
Map CSS-pixel (x, y) to the active sketch plane’s (u, v) via the camera
pick ray ∩ the sketch plane. None when not in sketch mode or the ray misses
the plane (parallel / behind).
Sourcepub fn sketch_hover_at(&mut self, x: f64, y: f64) -> bool
pub fn sketch_hover_at(&mut self, x: f64, y: f64) -> bool
Update the sketch hover to the entity under CSS-pixel (x, y) (S2). Returns
whether the hover changed. A no-op returning false when not in sketch mode.
Sourcepub fn sketch_clear_hover(&mut self) -> bool
pub fn sketch_clear_hover(&mut self) -> bool
Clear the sketch hover (pointer left the viewport / moved over the ViewCube). Returns whether a hover was cleared.
Sourcepub fn sketch_click_at(&mut self, x: f64, y: f64, additive: bool)
pub fn sketch_click_at(&mut self, x: f64, y: f64, additive: bool)
Click-select in sketch mode: pick the entity under (x, y); nothing → clear
the selection. Otherwise honor the SAME “Multi-select” setting the 3D viewport
reads (settings.multi_select): under ClickToggles a plain click toggles the
hit in the set (no modifier needed for a multi-selection); under
CtrlClick a plain click replaces the set with just the hit and additive
(Ctrl/Cmd) toggles. Re-pushes the overlay + marks dirty.
Sourcepub fn sketch_drag_begin(&mut self, x: f64, y: f64) -> bool
pub fn sketch_drag_begin(&mut self, x: f64, y: f64) -> bool
Begin a point drag if a DRAGGABLE point is under (x, y) (S2): remember it
(id + original fixed flag). Returns true iff a point was grabbed (the
viewport routes the drag to the sketch; otherwise it orbits the camera). A
locked / fully-constrained point is not draggable, so an empty-space or
locked-point drag falls through to a camera orbit.
Sourcepub fn sketch_drag_to(&mut self, x: f64, y: f64)
pub fn sketch_drag_to(&mut self, x: f64, y: f64)
Drag the grabbed target to (x, y) (S2): pin every grabbed point at its
ORIGINAL position plus the cursor delta (fixed = true) so the solver anchors
the whole shape there, re-solve, then restore each point’s ORIGINAL fixed
flag. Absolute-from-anchor (never incremental), so a rigid geometry translate
tracks the cursor 1:1 without drifting as the solver nudges points between
frames. A resolve error rolls every grabbed point back to its pre-drag coords
(the last good state). No-op when nothing is grabbed / not in sketch mode / the
ray misses the plane.
Sourcepub fn sketch_drag_end(&mut self)
pub fn sketch_drag_end(&mut self)
End a point drag (S2): clear the grab, then one final re-solve + overlay refresh. No-op when no drag is live.
Sourcepub fn sketch_selection_count(&self) -> usize
pub fn sketch_selection_count(&self) -> usize
The number of selected sketch entities (0 when not in sketch mode) — the mode bar / verifier readout.
Sourcepub fn sketch_selected_constraint_count(&self) -> usize
pub fn sketch_selected_constraint_count(&self) -> usize
The number of selected CONSTRAINTS (refs whose kind is "constraint"; 0 when
not in sketch mode) — the __brepSketch verifier readout for constraint
selection + delete.
Source§impl EngineState
impl EngineState
Sourcepub fn sketch_set_tool(&mut self, tool: Option<&str>)
pub fn sketch_set_tool(&mut self, tool: Option<&str>)
Set (or clear) the active draw tool: "select"/None → selection mode (S2);
"point"|"line"|"rect"|"circle"|"arc"|"bezier" arm the corresponding draw
tool; "handdraw" arms the freehand stroke tool (S6b-3); "trim" arms the
trim tool (S6b); "pickEdges" arms the external-edge link tool (S6b-2). Clears
any in-progress click buffer + preview and refreshes the overlay. No-op when not
in sketch mode.
Sourcepub fn sketch_active_tool(&self) -> Option<&str>
pub fn sketch_active_tool(&self) -> Option<&str>
The active draw tool ("point"|"line"|"rect"|"circle"|"arc"), or None in
selection mode / when not in sketch mode.
Sourcepub fn sketch_pending_len(&self) -> usize
pub fn sketch_pending_len(&self) -> usize
The number of in-progress draw-tool clicks buffered (0 in selection mode / when not in sketch mode) — the UI/preview + verifier readout.
Sourcepub fn sketch_tool_click_at(&mut self, x: f64, y: f64)
pub fn sketch_tool_click_at(&mut self, x: f64, y: f64)
A draw-tool click at CSS-pixel (x, y): map to plane uv (the S2 pixel→plane
math) and drive the tool state machine. No-op when not in sketch mode, in
selection mode, or the ray misses the plane.
Sourcepub fn sketch_tool_place_uv(&mut self, u: f64, v: f64)
pub fn sketch_tool_place_uv(&mut self, u: f64, v: f64)
The per-tool placement logic, in plane (u, v) (the headless-testable core
sketch_tool_click_at delegates to). Snaps to existing points within the grab
radius so shared vertices coincide; appends geometry and re-solves when a
primitive completes; carries the line chain via pending.
Sourcepub fn sketch_tool_cancel(&mut self)
pub fn sketch_tool_cancel(&mut self)
Abort the in-progress draw geometry (Escape / right-click): clear the pending clicks + preview and refresh. No-op when not in sketch mode.
Source§impl EngineState
impl EngineState
Sourcepub fn sketch_auto_constrain(&mut self) -> usize
pub fn sketch_auto_constrain(&mut self) -> usize
Auto-constrain the active sketch (the toolbar’s one-click “constrain what I
roughed in”): infer ━/│ on nearly-axis-aligned lines and ≡ between
near-coincident points, then re-solve. Records ONE undo step, popped when the
pass adds nothing so a dead click neither pollutes undo nor clobbers redo.
Returns the number of constraints added; a no-op (0) when not in sketch mode.
Source§impl EngineState
impl EngineState
Sourcepub fn sketch_delete_selection(&mut self) -> bool
pub fn sketch_delete_selection(&mut self) -> bool
Delete the selected sketch entities (S3b): the selected geometries + points,
plus any geometry orphaned by a deleted vertex, plus orphaned points and the
constraints referencing any removed point. Re-solves + refreshes the overlay.
Returns true when something was deleted; false when not in sketch mode or
the selection is empty.
Source§impl EngineState
impl EngineState
Sourcepub fn sketch_mode(&self) -> bool
pub fn sketch_mode(&self) -> bool
True while a sketch is being edited (the shell hides the normal side panel and shows the sketch-mode bar).
Sourcepub fn sketch_edit_session(&self) -> Option<&SketchSession>
pub fn sketch_edit_session(&self) -> Option<&SketchSession>
The live sketch session while in sketch mode (for the DOF readout / overlay
/ the headless verifier), else None.
Sourcepub fn sketch_edit_feature_id(&self) -> Option<&str>
pub fn sketch_edit_feature_id(&self) -> Option<&str>
The id of the feature being edited while in sketch mode, else None.
Sourcepub fn sketch_camera_locked(&self) -> bool
pub fn sketch_camera_locked(&self) -> bool
Whether the sketch camera is locked flat to the plane (only panning). On by default every sketch entry; the sketch-mode bar’s checkbox reflects this.
Sourcepub fn toggle_sketch_camera_lock(&mut self)
pub fn toggle_sketch_camera_lock(&mut self)
Toggle the sketch camera lock. Turning it ON re-faces the camera to the current sketch plane (so “off → spin around → on” snaps back flat); turning it OFF just frees orbiting. No-op outside sketch mode.
Sourcepub fn enter_sketch_mode(&mut self, feature_id: &str) -> Result<String, String>
pub fn enter_sketch_mode(&mut self, feature_id: &str) -> Result<String, String>
Enter sketch mode for the "S" feature with id feature_id: snapshot the
camera + rolled-to step, roll to the step BEFORE the sketch (its backdrop),
read the persisted plane basis + sketch doc off the history JSON, solve
a live session, orient the camera onto the plane, and push the read-only
overlay. Returns the session’s diagnostics JSON. Errors when the feature is
absent or is not a sketch.
Sourcepub fn exit_sketch_mode(&mut self, commit: bool) -> String
pub fn exit_sketch_mode(&mut self, commit: bool) -> String
Exit sketch mode. commit writes the edited doc back to the feature’s
persistentData.sketch; a non-commit exit of a brand-new sketch DELETES the
feature (a fresh sketch nobody kept). Restores the snapshotted camera +
rolled-to step, clears the overlay, re-runs the history, and returns the
build report. A no-op (returns "{}") when not in sketch mode.
Sourcepub fn new_sketch(&mut self, plane: &str) -> Result<String, String>
pub fn new_sketch(&mut self, plane: &str) -> Result<String, String>
Create a NEW engine-native sketch on a base plane ("XY" | "XZ" | "YZ") and
enter sketch mode on it. The feature persists an analytic basis (computed
via crate::sketch::PlaneFrame) and an empty sketch doc; a cancel exit
deletes it. Returns the new session’s diagnostics JSON. Errors on an unknown
plane name.
Sourcepub fn new_sketch_on(
&mut self,
plane: &str,
frame: PlaneFrame,
) -> Result<String, String>
pub fn new_sketch_on( &mut self, plane: &str, frame: PlaneFrame, ) -> Result<String, String>
A new sketch on the named plane (a base plane, or a datum’s
<id>:XY), its basis seeded with frame; enters sketch mode.
Source§impl EngineState
impl EngineState
Sourcepub fn sketch3d_mode(&self) -> bool
pub fn sketch3d_mode(&self) -> bool
True while a 3D sketch is being edited.
Sourcepub fn any_sketch_mode(&self) -> bool
pub fn any_sketch_mode(&self) -> bool
Either sketch editor is open — what the shell keys its sketch takeover on (the dock hides, the mode-exit card shows, undo routes to the session).
pub fn sketch3d_edit_session(&self) -> Option<&Sketch3dSession>
pub fn sketch3d_edit_feature_id(&self) -> Option<&str>
Sourcepub fn enter_sketch3d_mode(
&mut self,
feature_id: &str,
) -> Result<String, String>
pub fn enter_sketch3d_mode( &mut self, feature_id: &str, ) -> Result<String, String>
Enter 3D sketch mode on the S3D feature feature_id: snapshot the
camera + rolled-to step, roll to the step before the sketch (its
backdrop), load the document and the reference records, materialize
every listed reference the backdrop can see, solve, and show the
overlay. Returns the diagnostics JSON.
Sourcepub fn exit_sketch3d_mode(&mut self, commit: bool) -> String
pub fn exit_sketch3d_mode(&mut self, commit: bool) -> String
Exit 3D sketch mode. commit writes the document, the reference
records and the working plane back; a cancel of a sketch this session
created deletes it. Restores the camera + rolled-to step and re-runs.
Sourcepub fn new_sketch3d(&mut self) -> Result<String, String>
pub fn new_sketch3d(&mut self) -> Result<String, String>
Create a NEW 3D sketch feature and enter its edit. A cancel exit deletes it. Returns the diagnostics JSON.
pub fn clear_sketch3d_overlay(&mut self)
pub fn sketch3d_diagnostics_json(&self) -> String
Sourcepub fn sketch3d_state_json(&self) -> String
pub fn sketch3d_state_json(&self) -> String
The __brepSketch3d state: mode, feature, DOF readout, tool, working
plane, counts, selection, the palette and the labels.
Sourcepub fn sketch3d_dimension_labels_json(&self) -> String
pub fn sketch3d_dimension_labels_json(&self) -> String
The dimension labels as JSON (the same shape as the planar sketch’s).
pub fn sketch3d_active_tool(&self) -> Option<&str>
pub fn sketch3d_selection_count(&self) -> usize
pub fn sketch3d_pending_len(&self) -> usize
pub fn sketch3d_work_plane(&self) -> Option<&str>
Sourcepub fn sketch3d_set_tool(&mut self, tool: Option<&str>) -> Result<(), String>
pub fn sketch3d_set_tool(&mut self, tool: Option<&str>) -> Result<(), String>
Arm a draw tool (point, line, arc, bezier, pickRef); select
/ None returns to selection. Errors on an unknown tool.
Sourcepub fn sketch3d_tool_cancel(&mut self)
pub fn sketch3d_tool_cancel(&mut self)
Drop the in-progress placement (right-click / Escape with clicks pending) without changing the armed tool.
Sourcepub fn sketch3d_set_work_plane(&mut self, name: &str) -> Result<(), String>
pub fn sketch3d_set_work_plane(&mut self, name: &str) -> Result<(), String>
Set the working plane by name (XY / YZ / XZ); it keeps passing
through the current anchor.
Sourcepub fn sketch3d_cycle_work_plane(&mut self)
pub fn sketch3d_cycle_work_plane(&mut self)
Cycle the working plane XY → YZ → XZ → XY (the Tab key).
Sourcepub fn sketch3d_cursor_hit(&self, x: f64, y: f64) -> Option<Sketch3dCursorHit>
pub fn sketch3d_cursor_hit(&self, x: f64, y: f64) -> Option<Sketch3dCursorHit>
What the cursor at CSS-pixel (x, y) lands on when PLACING a point:
an existing sketch point within the grab radius, else a model vertex /
edge / planar face under the cursor (the pick ranking, committed
sketch displays excluded), else the working plane.
Sourcepub fn sketch3d_cursor_world(&self, x: f64, y: f64) -> Option<[f64; 3]>
pub fn sketch3d_cursor_world(&self, x: f64, y: f64) -> Option<[f64; 3]>
The world point the cursor would place at (x, y) (the readback /
rubber band), None when the ray misses the working plane.
Sourcepub fn sketch3d_tool_click_at(&mut self, x: f64, y: f64)
pub fn sketch3d_tool_click_at(&mut self, x: f64, y: f64)
A click with a draw tool armed: place the next point of the geometry
being drawn; when the tool has all its points, create the geometry.
line chains: each click after the first lands a segment and starts
the next from its end.
Sourcepub fn sketch3d_pick_reference_at(&mut self, x: f64, y: f64) -> bool
pub fn sketch3d_pick_reference_at(&mut self, x: f64, y: f64) -> bool
The pickRef tool: link the model entity under the cursor (vertex,
edge, planar face or datum plane) into the sketch as fixed construction
geometry. Returns whether something was linked.
Sourcepub fn sketch3d_link_reference(&mut self, name: &str) -> bool
pub fn sketch3d_link_reference(&mut self, name: &str) -> bool
Link a model entity BY NAME (a {solid}@x,y,z vertex, an edge or face
name, a datum / plane frame name): materialize it as fixed construction
geometry and record it. Re-linking an already linked name updates its
coordinates in place. Returns whether it resolved.
Sourcepub fn sketch3d_unlink_reference(&mut self, name: &str) -> bool
pub fn sketch3d_unlink_reference(&mut self, name: &str) -> bool
Drop a linked reference by name: its record, its construction geometry and points, and every constraint touching them.
pub fn sketch3d_hover_at(&mut self, x: f64, y: f64) -> bool
pub fn sketch3d_clear_hover(&mut self) -> bool
Sourcepub fn sketch3d_click_at(&mut self, x: f64, y: f64, additive: bool)
pub fn sketch3d_click_at(&mut self, x: f64, y: f64, additive: bool)
Click-select: the entity under the cursor replaces (or, additive / click-toggles, toggles in) the selection; empty space clears it.
Sourcepub fn sketch3d_select_entity(&mut self, entity_ref: Value, additive: bool)
pub fn sketch3d_select_entity(&mut self, entity_ref: Value, additive: bool)
Select an entity by ref from a list row (replacing the selection).
pub fn sketch3d_clear_selection(&mut self)
Sourcepub fn sketch3d_drag_begin(&mut self, x: f64, y: f64) -> bool
pub fn sketch3d_drag_begin(&mut self, x: f64, y: f64) -> bool
Begin a drag of the hovered (or picked) draggable entity. Returns whether something was grabbed; otherwise the drag is the camera’s.
Sourcepub fn sketch3d_drag_to(&mut self, x: f64, y: f64)
pub fn sketch3d_drag_to(&mut self, x: f64, y: f64)
Drag the grabbed points to the cursor: each is pinned at its original position plus the cursor delta on the drag plane, the sketch re-solved, and the original fixed flags restored.
pub fn sketch3d_drag_end(&mut self)
Sourcepub fn sketch3d_add_constraint(&mut self, ctype: &str) -> Result<Value, String>
pub fn sketch3d_add_constraint(&mut self, ctype: &str) -> Result<Value, String>
Add a constraint of ctype over the palette’s point ids for the
current selection (sketch3d_applicable_constraints); a dimensional
one is seeded with the current measurement. Returns the constraint id.
Sourcepub fn sketch3d_add_constraint_over(
&mut self,
ctype: &str,
points: Vec<Value>,
value: Option<f64>,
) -> Result<Value, String>
pub fn sketch3d_add_constraint_over( &mut self, ctype: &str, points: Vec<Value>, value: Option<f64>, ) -> Result<Value, String>
Add a constraint over EXPLICIT point ids (automation / tests).
Sourcepub fn sketch3d_applicable_constraints_json(&self) -> String
pub fn sketch3d_applicable_constraints_json(&self) -> String
The palette for the current selection, as JSON.
Sourcepub fn sketch3d_set_dimension_value(
&mut self,
id: &Value,
value: &str,
) -> Result<(), String>
pub fn sketch3d_set_dimension_value( &mut self, id: &Value, value: &str, ) -> Result<(), String>
Set a dimensional constraint’s value (a number, or an expression
string kept as valueExpr and evaluated now against the document’s
expressions). Re-solves; an unsolvable value is taken back.
Sourcepub fn sketch3d_toggle_construction(&mut self)
pub fn sketch3d_toggle_construction(&mut self)
Toggle the construction flag of every selected geometry.
Sourcepub fn sketch3d_toggle_fixed(&mut self)
pub fn sketch3d_toggle_fixed(&mut self)
Toggle the fixed flag of every selected point (a linked reference
point stays fixed).
Sourcepub fn sketch3d_delete_selection(&mut self)
pub fn sketch3d_delete_selection(&mut self)
Delete the selection: constraints by id; geometries with every constraint touching their points; points with their geometries and constraints. Orphaned points no geometry or constraint uses are swept away, and reference records whose entities are gone are dropped.
pub fn sketch3d_undo(&mut self) -> bool
pub fn sketch3d_redo(&mut self) -> bool
pub fn sketch3d_can_undo(&self) -> bool
pub fn sketch3d_can_redo(&self) -> bool
Source§impl EngineState
impl EngineState
Sourcepub fn push_notice_as(
&mut self,
severity: NoticeSeverity,
message: impl Into<String>,
)
pub fn push_notice_as( &mut self, severity: NoticeSeverity, message: impl Into<String>, )
Queue a notice of severity. Self::push_notice is this with
NoticeSeverity::Error; bounded the same way.
Sourcepub fn take_graded_notices(&mut self) -> Vec<(NoticeSeverity, String)>
pub fn take_graded_notices(&mut self) -> Vec<(NoticeSeverity, String)>
Drain every queued notice with its severity: the errors, then the warnings and successes. The shell’s toast overlay reads this.
Sourcepub fn push_notice(&mut self, message: impl Into<String>)
pub fn push_notice(&mut self, message: impl Into<String>)
Queue a transient user-facing notice (shown as a toast by the shell) and, on native, also log it. Bounded so a pathological loop can’t grow it.
Sourcepub fn take_notices(&mut self) -> Vec<String>
pub fn take_notices(&mut self) -> Vec<String>
Drain the queued notices (the shell calls this once per frame and shows each as a toast).
Sourcepub fn sketch_point_rows(&self) -> Vec<SketchEntityRow>
pub fn sketch_point_rows(&self) -> Vec<SketchEntityRow>
The Points list: P{id} (x, y) plus ⛓ external / ◐ construction / ⏚ ground
markers, mirroring the previous Points rows.
Sourcepub fn sketch_geometry_rows(&self) -> Vec<SketchEntityRow>
pub fn sketch_geometry_rows(&self) -> Vec<SketchEntityRow>
The Curves list: {type}:{id} [p0,p1,…] (◐ for construction), mirroring the
previous Curves rows.
Sourcepub fn sketch_constraint_rows(&self) -> Vec<SketchEntityRow>
pub fn sketch_constraint_rows(&self) -> Vec<SketchEntityRow>
The Constraints list: {id} {type} {value} [points], mirroring the previous
Constraints rows.
Sourcepub fn sketch_select_entity(&mut self, kind: &str, id: Value, additive: bool)
pub fn sketch_select_entity(&mut self, kind: &str, id: Value, additive: bool)
Select an entity BY ref from a list row (mirrors sketch_click_at): honors the
SAME “Multi-select” setting — under ClickToggles a plain click toggles the row
(no modifier needed); under CtrlClick a plain click replaces the
selection and an additive (Ctrl/Cmd) click toggles.
Sourcepub fn sketch_delete_entity(&mut self, kind: &str, id: Value) -> bool
pub fn sketch_delete_entity(&mut self, kind: &str, id: Value) -> bool
Delete exactly ONE entity BY ref — a list row’s ✕ (owner bug 2026-11-04). The
row ✕ used to select the row and run sketch_delete_selection,
but under the ClickToggles multi-select setting a plain select does not
replace the selection, so the ✕ deleted everything selected (or, on an
already-selected row, toggled it OFF and deleted the rest). This deletes
only the clicked entity (with the usual dependent cleanup) and keeps the
rest of the selection where its entities survive. Returns whether
something was deleted.
Sourcepub fn sketch_hover_entity(&mut self, kind: &str, id: Value)
pub fn sketch_hover_entity(&mut self, kind: &str, id: Value)
Hover an entity BY ref from a list row (list→canvas highlight). Sets the one-frame guard so the viewport — which draws after the panel and would otherwise clear the hover because the pointer is off the viewport — keeps it.
Sourcepub fn take_sketch_list_hover(&mut self) -> bool
pub fn take_sketch_list_hover(&mut self) -> bool
Consume the “list panel set the hover this frame” guard (read + reset). The
viewport calls this before its off-viewport sketch_clear_hover so a
panel-set hover survives the frame.
Sourcepub fn sketch_solver_settings(&self) -> Option<SketchSolverSettings>
pub fn sketch_solver_settings(&self) -> Option<SketchSolverSettings>
The active sketch’s solver settings (the Solver Settings panel reads this).
None when not editing a sketch.
Sourcepub fn sketch_set_solver_settings(&mut self, settings: SketchSolverSettings)
pub fn sketch_set_solver_settings(&mut self, settings: SketchSolverSettings)
Replace the active sketch’s solver settings and re-solve so the change takes effect immediately. No-op when not editing a sketch.
Source§impl EngineState
impl EngineState
Sourcepub fn sketch_applicable_constraints(&self) -> Vec<SketchConstraintAction>
pub fn sketch_applicable_constraints(&self) -> Vec<SketchConstraintAction>
The ordered palette of constraints applicable to the active sketch selection
(a faithful port of #refreshContextBar). Empty when not in sketch mode or
the selection surfaces no constraint. The Fix/Unfix + construction + cleanup
affordances are exposed separately (see sketch_selection_all_grounded /
sketch_selection_all_construction / sketch_cleanup_unused_points).
Sourcepub fn sketch_add_constraint(&mut self, symbol: &str) -> bool
pub fn sketch_add_constraint(&mut self, symbol: &str) -> bool
Add the constraint named by symbol from the current selection (a port of
createConstraint): build the ordered point-id list, dedup on
type + sorted-points, append (dimensional → value:null), then re-solve +
refresh (keeping the selection). Returns whether a constraint was added.
Sourcepub fn sketch_toggle_ground(&mut self) -> bool
pub fn sketch_toggle_ground(&mut self) -> bool
Toggle the ground (⏚) constraint on the selected points: if ALL selected
points are already grounded → remove those grounds (and clear their fixed
flag); else add a ⏚ for each ungrounded selected point (and set fixed).
Re-solves + refreshes. Returns whether anything changed. No-op with no point
selected / not in sketch mode.
Sourcepub fn sketch_toggle_construction(&mut self) -> bool
pub fn sketch_toggle_construction(&mut self) -> bool
Flip the construction flag on ALL selected points AND geometries: if every
selected entity is already construction → make them regular, else make them
all construction. Re-solves + refreshes. Returns whether anything was
selected. No-op with nothing selected / not in sketch mode.
Sourcepub fn sketch_cleanup_unused_points(&mut self) -> bool
pub fn sketch_cleanup_unused_points(&mut self) -> bool
Remove points referenced by NO geometry AND no constraint (the 🧹 action). Re-solves + refreshes only when something was dropped. Returns whether a point was removed. No-op when not in sketch mode.
Sourcepub fn sketch_constraint_count(&self) -> usize
pub fn sketch_constraint_count(&self) -> usize
The number of constraints in the active sketch (0 when not in sketch mode) — the verifier / palette readout.
Sourcepub fn sketch_selection_all_grounded(&self) -> Option<bool>
pub fn sketch_selection_all_grounded(&self) -> Option<bool>
Whether the selected points are ALL grounded (Some(true)), NOT all grounded
(Some(false)), or no point is selected (None) — labels the Fix vs Unfix
button.
Sourcepub fn sketch_selection_all_construction(&self) -> Option<bool>
pub fn sketch_selection_all_construction(&self) -> Option<bool>
Whether the selected points + geometries are ALL construction (Some(true)),
NOT all construction (Some(false)), or nothing is selected (None) — labels
the ◐ construction-toggle button’s direction.
Source§impl EngineState
impl EngineState
Source§impl EngineState
impl EngineState
Sourcepub fn transform_armed(&self) -> bool
pub fn transform_armed(&self) -> bool
Whether the TRANSFORM gizmo (move/rotate) is armed for ANY feature. False in dimension mode — the two ◎ modes are exclusive, so the transform gizmo arms/handles never render while dimensions are shown.
Sourcepub fn transform_armed_feature(&self) -> String
pub fn transform_armed_feature(&self) -> String
The transform-gizmo-armed feature id (empty unless in transform mode).
Sourcepub fn gizmo_state_json(&self) -> String
pub fn gizmo_state_json(&self) -> String
The gizmo as the headed verifier sees it: the mode, the armed feature,
the spline anchor index when the gizmo sits on one, and origin — the
DRAWN move/rotate widget’s frame origin (null when no widget is
drawn), which is the proof a handle is on screen, unlike any
params-derived pose.
Sourcepub fn armed_face_transform_pivot(&self) -> Option<[f64; 3]>
pub fn armed_face_transform_pivot(&self) -> Option<[f64; 3]>
The armed feature’s Transform Face pivot in WORLD space, or None when
the armed feature is not a Transform Face (every other transform feature
turns about its own origin, which the gizmo is already on).
Sourcepub fn transform_readout_json(&self) -> String
pub fn transform_readout_json(&self) -> String
What the gizmo drag is WORTH, for the chip the viewport draws on it — and, when the motion refused, why it refused, said about the user’s model rather than about the kernel’s internals.
A gizmo drag used to be the one edit in the app that reported nothing:
the model followed the pointer, the number went into transform, the
form’s Transform section is collapsed by default, and so the distance
the user had just dragged appeared NOWHERE on screen. The Extrude
distance arrow carries its value in a chip on the geometry; this is the
same answer for the gizmo.
The readout is live in two states, and silent otherwise:
- while a handle is being dragged — the distance or angle so far.
- while the armed feature is REFUSING — because that is the state the user is left in after letting go of a refused drag, and it is the state that most needs saying. The gizmo tracks the pointer while the geometry stays at its last good answer, so on a refusal the handles end up somewhere the model is not — measured at 15.4 mm INSIDE the solid — and without this the only signal was a red banner in a dock on the far side of the window from the pointer.
origin is where to draw it: the gizmo’s own frame origin, which is
where the pointer is.
Sourcepub fn transform_armed_for(&self, feature_id: &str) -> bool
pub fn transform_armed_for(&self, feature_id: &str) -> bool
Whether the TRANSFORM gizmo is armed for THIS feature.
Sourcepub fn arm_transform(&mut self, feature_id: &str)
pub fn arm_transform(&mut self, feature_id: &str)
Arm the TRANSFORM gizmo for feature_id and feed it at the feature’s
transform frame. Re-arming a different feature moves the gizmo to it.
Clears any dimension overlay (the modes are exclusive).
An ACOMP (assembly component) feature ROUTES to the component Move gizmo
instead: its transform is the component pose ({translate, rotateEulerDeg}, a different shape), its gizmo attaches at the member
bbox center, commits on release, and refuses fixed instances — the
generic position/rotationEuler gizmo must never write its keys into an
ACOMP’s params. This covers the history panel’s arm-on-expand path too.
Sourcepub fn disarm_transform(&mut self)
pub fn disarm_transform(&mut self)
Disarm: hide BOTH gizmos + drop any in-flight drag. Also resets the component Move gizmo (the widget slot is shared, so a disarm clears whichever controller was feeding it).
Sourcepub fn is_face_transform_feature(&self, index: usize) -> bool
pub fn is_face_transform_feature(&self, index: usize) -> bool
Whether the feature at index is a Transform Face — the feature whose
motion turns about a STORED pivot param.
Sourcepub fn face_transform_has_pivot(&self, feature_id: &str) -> bool
pub fn face_transform_has_pivot(&self, feature_id: &str) -> bool
Whether the Transform Face feature_id has a pivot to put its gizmo on —
a stored one, or faces that resolve to a default. The history panel arms
the gizmo on the frame this first holds.
Sourcepub fn sync_transform_gizmo(&mut self)
pub fn sync_transform_gizmo(&mut self)
(Re)feed the widget gizmo at the armed feature’s frame: origin =
position, axes = the feature’s rotated basis (intrinsic XYZ Euler order, matching
the kernel bake). Auto-disarms if the feature vanished. Called every drag
frame from transform_drag_to so the widget tracks the moving pose live
(Fix 3); the drag delta resolves against the frozen grab frame, so this
re-sync never feeds back into the drag math.
Sourcepub fn feature_has_transform(&self, feature_id: &str) -> bool
pub fn feature_has_transform(&self, feature_id: &str) -> bool
Whether the feature schema exposes the shared Transform controls. Capability belongs to the schema, not to which default-valued fields happen to have been serialized in the model.
Sourcepub fn transform_gizmo_anchor(&self) -> Option<(f64, f64)>
pub fn transform_gizmo_anchor(&self) -> Option<(f64, f64)>
The armed gizmo origin projected to VIEWPORT-LOCAL px (the center handle
sits here). The history panel publishes it so the headed verifier can
locate + drag the gizmo. None when disarmed / not projectable (the ONE
crate::view::ViewCamera::projectable policy — ortho always projects).
Sourcepub fn transform_axis_labels_json(&self) -> String
pub fn transform_axis_labels_json(&self) -> String
The transform gizmo’s axis-end labels as JSON:
[{ text:"XC"|"YC"|"ZC", rgb:[r,g,b], world:[x,y,z] }]. The app projects
each world point and draws the colored egui label just past the matching
cone tip (X=red, Y=green, Z=blue). [] unless the TRANSFORM gizmo is armed.
Sourcepub fn transform_handle_points(&self) -> Vec<(&'static str, (f64, f64))>
pub fn transform_handle_points(&self) -> Vec<(&'static str, (f64, f64))>
A press point for every AXIS ARROW and ROTATION GRAB of the drawn
transform gizmo, in VIEWPORT-LOCAL px, keyed axis:x|y|z and
ring:x|y|z (a ring is named by the frame axis it turns about). Read off
the SAME regions Self::transform_pick tests — three quarters of the way
along an arrow’s capsule spine, a grab ball’s centre — and kept only where
a press there picks THAT handle, so a published key can never grab a
neighbour (an arrow foreshortened onto a ring ball, say). Empty while no
transform widget is drawn. The centre handle is gizmo/anchor’s.
Sourcepub fn transform_hit_areas_json(&self) -> String
pub fn transform_hit_areas_json(&self) -> String
Viewport-local pick regions for the debug overlay, shared by feature and
component controllers. The widget feed determines visibility; hidden
widgets return []. The app offsets these circles/capsules by rect.min.
Sourcepub fn transform_press(&mut self, x: f64, y: f64) -> bool
pub fn transform_press(&mut self, x: f64, y: f64) -> bool
Begin a gizmo drag at viewport px (x, y) when the gizmo is armed AND a
handle is under the pointer. Returns whether a handle was grabbed — the
viewport routes the drag to the gizmo (not the camera) when true; a press
on empty space returns false and still orbits.
Sourcepub fn transform_dragging(&self) -> bool
pub fn transform_dragging(&self) -> bool
Whether a gizmo handle drag is in flight.
Sourcepub fn transform_drag_to(&mut self, cx: f64, cy: f64)
pub fn transform_drag_to(&mut self, cx: f64, cy: f64)
Continue the in-flight gizmo drag to viewport px (cx, cy): resolve the
world delta from the grab (against the frozen grab-time frame), apply it to
the grab pose, write it back into the feature’s transform, and re-run so
the model follows live. Then re-sync the VISIBLE gizmo to the moved pose so
the widget tracks the pointer in real time (Fix 3) — the delta stays
anchored to drag.start, so this visual sync never feeds back on itself.
Sourcepub fn transform_release(&mut self)
pub fn transform_release(&mut self)
End the drag: clear the active-handle highlight + re-sync the gizmo to the feature’s final (moved) pose (unpin the frame).
Source§impl EngineState
impl EngineState
Sourcepub fn transform_armed_port_point(&self) -> Option<&str>
pub fn transform_armed_port_point(&self) -> Option<&str>
Whether the transform gizmo is armed on a connection point, and which.
Sourcepub fn arm_transform_for_port_point(&mut self, address: &str) -> bool
pub fn arm_transform_for_port_point(&mut self, address: &str) -> bool
Arm the TRANSFORM gizmo on the connection point at address, or refuse
and say why (Self::port_point_gizmo_refusal).
Sourcepub fn port_point_gizmo_refusal(&self, address: &str) -> Option<String>
pub fn port_point_gizmo_refusal(&self, address: &str) -> Option<String>
Why the gizmo will not arm on this point, in words, or None when it
will. There are two reasons, and both are cases where the handles would
LIE — draw somewhere a drag cannot write to:
- the point maps down. Its placement is its target’s: the kernel’s
resolve_pointreturns onmapsTobefore it ever reads the transform, so handles would sit on the descendant’s geometry and a drag would write numbers nothing reads, leaving the point where it was while the handles walked away from it; - an expression places it. The gizmo writes numbers, and replacing
width/2with12.5because a user dragged something is a loss the document cannot show them. Typing in the panel still works, which is where an expression belongs.
Public because the panel must say the same thing the arm decides rather than inferring a reason from the gizmo not being armed: it is drawn a moment BEFORE the arm runs, so an inference would flash a refusal on the frame a perfectly armable point is selected.
Source§impl EngineState
impl EngineState
Sourcepub fn wire_harness_report(&self) -> Option<&WireHarnessReport>
pub fn wire_harness_report(&self) -> Option<&WireHarnessReport>
The routing report of the last APPLIED run: endpoints (every port in
the model), the harness segments, one route per connection, and the
bundles. None before the first run.
Sourcepub fn wire_harness_state(&self) -> WireHarnessState
pub fn wire_harness_state(&self) -> WireHarnessState
The document’s wireHarness block as typed state (the default — no
connections — when the document carries none).
Sourcepub fn wire_harness_state_json(&self) -> String
pub fn wire_harness_state_json(&self) -> String
The panel’s verifier global: the block, the report, and the endpoint choices, as one JSON object.
Sourcepub fn wire_harness_state_value(&self) -> Value
pub fn wire_harness_state_value(&self) -> Value
Self::wire_harness_state_json as a JSON value.
Sourcepub fn wire_harness_add_connection(
&mut self,
from: &str,
to: &str,
diameter: f64,
) -> String
pub fn wire_harness_add_connection( &mut self, from: &str, to: &str, diameter: f64, ) -> String
Add a connection between two port ids (either may be empty — the panel
fills them in) and return its minted id (wire-N, named Wire N).
Sourcepub fn wire_harness_update_connection(
&mut self,
id: &str,
patch: &ConnectionPatch,
) -> Result<(), String>
pub fn wire_harness_update_connection( &mut self, id: &str, patch: &ConnectionPatch, ) -> Result<(), String>
Apply a patch to one connection. An unknown id is an error; a non-positive diameter is refused (the connection keeps its diameter).
Sourcepub fn wire_harness_remove_connection(&mut self, id: &str) -> Result<(), String>
pub fn wire_harness_remove_connection(&mut self, id: &str) -> Result<(), String>
Remove one connection. An unknown id is an error.
Sourcepub fn wire_harness_set_build_bundles(&mut self, on: bool)
pub fn wire_harness_set_build_bundles(&mut self, on: bool)
Switch the bundle solids on / off (the routing report stays either way).
Sourcepub fn wire_harness_set_cut_margin(&mut self, margin: f64) -> Result<(), String>
pub fn wire_harness_set_cut_margin(&mut self, margin: f64) -> Result<(), String>
Set the cut margin every wire’s BOM cut length adds to its routed
length (see WireHarnessState::cut_margin). A negative or non-finite
margin is refused and the block is left alone; an unchanged one writes
nothing, so it takes no undo step. The re-run replays the harness from
its cache — the router does not read the margin.
Sourcepub fn wire_harness_hover_connection(&mut self, id: &str)
pub fn wire_harness_hover_connection(&mut self, id: &str)
Highlight a connection under the panel’s pointer: its two ports (their sheet solids are keyed by the port feature id) and the bundle solids of every segment its route crosses. An unknown id highlights nothing.
Sourcepub fn wire_harness_hover_end(&mut self)
pub fn wire_harness_hover_end(&mut self)
The pointer left the panel’s rows: drop the highlight.
Source§impl EngineState
impl EngineState
Sourcepub fn port_point_row(&self, address: &str) -> Option<&PortPointRow>
pub fn port_point_row(&self, address: &str) -> Option<&PortPointRow>
The tail’s row for one point of THIS document, by part-local address —
its seat, where it resolved and which way it faces. None for a point
the last run did not resolve (one just typed in, or one whose group
name is refused).
Sourcepub fn selected_port_point(&self) -> Option<String>
pub fn selected_port_point(&self) -> Option<String>
The connection point of THIS DOCUMENT that the viewport selection names, if any — the 3D half of “select it there, see it here”.
A declared point draws as a synthesized sheet keyed by its ADDRESS, and its base vertex and line hang off that address, so a click anywhere on it selects one of three names that all peel back to the same point.
A NAMESPACED address (ACOMP1:J1.VCC) is deliberately not adopted: it
belongs to a component this assembly places, not to the document being
qualified, and selecting its row here would offer to edit a point this
document does not own.
Sourcepub fn edit_port_point(
&mut self,
address: &str,
coalesce: Option<&str>,
edit: impl FnOnce(&mut Map<String, Value>),
) -> bool
pub fn edit_port_point( &mut self, address: &str, coalesce: Option<&str>, edit: impl FnOnce(&mut Map<String, Value>), ) -> bool
Edit ONE declared point’s JSON object in place, by address, and write
the block back through History::set_ports_block (which carries the
pin/point follow and re-runs). Returns whether the point was found.
The point is handed to edit as its RAW object, one key at a time, for
the reason the Qualify panel edits it that way: a round trip through
PortDeclaration drops any field the struct does not model, and no
lane may be the reason a later slice’s field disappears when the field
beside it is touched.
Sourcepub fn begin_ref_select_for_port_point(
&mut self,
address: &str,
field: PortRefField,
)
pub fn begin_ref_select_for_port_point( &mut self, address: &str, field: PortRefField, )
Enter the reference picker to seat address on geometry.
Unlike every feature field, this does NOT roll the history back: a connection point resolves at the TAIL of the run, against the finished part, so the geometry it may be seated on is exactly what is on screen. Rolling would hide from the user the very faces the point can name.
Sourcepub fn clear_port_point_ref(&mut self, address: &str, field: PortRefField)
pub fn clear_port_point_ref(&mut self, address: &str, field: PortRefField)
Unseat a connection point: clear one of its reference fields and re-run. The OFFSET is deliberately left as it is — it is on screen, and silently rewriting the numbers a user can see is worse than a point that visibly moved to where those numbers say.
Sourcepub fn ports_report(&self) -> Option<&PortsReport>
pub fn ports_report(&self) -> Option<&PortsReport>
The ports tail’s report of the last APPLIED run: whether this document
is an encapsulation boundary, every point it resolved, and everything
about the block that does not hold. None before the first run, and
for a document that declares no ports block.
Sourcepub fn ports_state_json(&self) -> String
pub fn ports_state_json(&self) -> String
The Qualify panel’s verifier global: the declared block and the tail’s
report, as one JSON object. report is null before the first run.
Source§impl EngineState
impl EngineState
Sourcepub fn wire_bom_lines(&self) -> Vec<WireBomLine>
pub fn wire_bom_lines(&self) -> Vec<WireBomLine>
Every harness wire as a BOM line, in block order, each with the cut length of the last applied run — or, when that run does not speak for the model as it stands, the reason there is none (see the module doc).
Source§impl EngineState
impl EngineState
Sourcepub fn pmi_state(&self) -> PmiState
pub fn pmi_state(&self) -> PmiState
The document’s pmi block as typed state (the default — no views —
when the document carries none).
Self::pmi_state parsed once per history revision and shared: what
a frame reads (an animation frame’s section check and overlay), where
parsing the whole block each time cost ~14 ms a parse on a 500-step
view.
Sourcepub fn pmi_report(&self) -> Option<&PmiReport>
pub fn pmi_report(&self) -> Option<&PmiReport>
The PMI report of the last APPLIED run.
pub fn pmi_active_view(&self) -> Option<&str>
pub fn pmi_open_annotation(&self) -> Option<&str>
Sourcepub fn pmi_open_view(&self) -> Option<&str>
pub fn pmi_open_view(&self) -> Option<&str>
The view whose dialog the PMI pane shows, if one is open.
Sourcepub fn pmi_dialog_opens(&self) -> u64
pub fn pmi_dialog_opens(&self) -> u64
How many PMI dialogs — annotation or view — this engine has OPENED. The app’s dialog door reads it beside the open subject so a re-open of the dialog already open is still an open (the id alone does not move). Monotonic and never reset; a CLOSE does not count.
Sourcepub fn pmi_selected_annotation(&self) -> Option<&str>
pub fn pmi_selected_annotation(&self) -> Option<&str>
The annotation selected in the PMI tree (or opened), while it exists. Asked every frame (the tree’s highlight), so it reads the shared parse.
Sourcepub fn pmi_selected_view(&self) -> Option<&str>
pub fn pmi_selected_view(&self) -> Option<&str>
The view selected in the PMI tree (or opened), while it exists.
Sourcepub fn pmi_workbench_entered(&self) -> bool
pub fn pmi_workbench_entered(&self) -> bool
Whether the PMI workbench remembered a modeling state (it is “entered”).
Sourcepub fn pmi_state_json(&self) -> String
pub fn pmi_state_json(&self) -> String
The __brepPmi verifier global: the block, the report, the active
view, the open annotation and the datum letters, as one object.
Sourcepub fn pmi_state_value(&self) -> Value
pub fn pmi_state_value(&self) -> Value
Self::pmi_state_json as a JSON value.
Sourcepub fn pmi_capture_view(&mut self, name: Option<&str>) -> String
pub fn pmi_capture_view(&mut self, name: Option<&str>) -> String
Capture a view: the current camera, hidden objects (its baseline hide
step) and wireframe setting, named name (or View N). The new view
becomes active.
pub fn pmi_rename_view(&mut self, id: &str, name: &str) -> Result<(), String>
Sourcepub fn pmi_delete_view(&mut self, id: &str) -> Result<(), String>
pub fn pmi_delete_view(&mut self, id: &str) -> Result<(), String>
Delete a view (and its annotations). An active view deactivates first.
Sourcepub fn pmi_update_view_camera(&mut self, id: &str) -> Result<(), String>
pub fn pmi_update_view_camera(&mut self, id: &str) -> Result<(), String>
Re-capture a view’s camera from the current camera (the explicit Update Camera action — orbiting never rewrites a snapshot silently).
Sourcepub fn pmi_hide_selected(
&mut self,
view_id: Option<&str>,
) -> Result<String, String>
pub fn pmi_hide_selected( &mut self, view_id: Option<&str>, ) -> Result<String, String>
Hide the selection in view view_id (the active view when None) as
a new hide step — a hide annotation naming the selected
components (whole placements, a part inside a sub-assembly by its
occurrence path, as an explode step names them) and any other
selected solids — tracked, listed, edited and undone like an explode
step. The step’s form opens. Refused with nothing selected.
Sourcepub fn pmi_set_view_display(
&mut self,
id: &str,
patch: &PmiViewPatch,
) -> Result<(), String>
pub fn pmi_set_view_display( &mut self, id: &str, patch: &PmiViewPatch, ) -> Result<(), String>
Patch a view’s name / display state. The active view re-applies.
Sourcepub fn pmi_update_view(
&mut self,
id: &str,
params_json: &str,
) -> Result<(), String>
pub fn pmi_update_view( &mut self, id: &str, params_json: &str, ) -> Result<(), String>
Apply an edited PMI view form (pmi_view_schema’s params). Only
the fields that differ from the view are written, and a run of edits to
one view is ONE undo step — the form writes on every keystroke of the
name, the way an annotation’s form does.
Sourcepub fn pmi_set_view_section(
&mut self,
id: &str,
enabled: bool,
axis: Option<&str>,
offset: Option<f64>,
flip: Option<bool>,
plane: Option<&str>,
exclude: Option<Vec<String>>,
planes: Option<Vec<PmiSectionPlane>>,
) -> Result<(), String>
pub fn pmi_set_view_section( &mut self, id: &str, enabled: bool, axis: Option<&str>, offset: Option<f64>, flip: Option<bool>, plane: Option<&str>, exclude: Option<Vec<String>>, planes: Option<Vec<PmiSectionPlane>>, ) -> Result<(), String>
Set view id’s section the way its form’s section rows do, as ONE
undo step: enabled turns it on or off, and each field left None
keeps what the section has (or the form’s default: View, offset 0,
not reversed, no plane, nothing left whole, no further planes).
planes replaces the further planes (a half or corner cut away;
empty: none). The plane is anchored as the form anchors it
(Self::pmi_update_view).
Sourcepub fn pmi_set_view_open(&mut self, id: Option<&str>)
pub fn pmi_set_view_open(&mut self, id: Option<&str>)
Open view id’s dialog (None closes it). Opening activates the view,
as opening one of its annotations does: the dialog describes what is on
screen. An id that names no view opens nothing and counts nothing.
Sourcepub fn pmi_enter_workbench(&mut self)
pub fn pmi_enter_workbench(&mut self)
Entering the PMI workbench: remember the modeling camera, visibility and wireframe so a view activation can be undone exactly.
Sourcepub fn pmi_leave_workbench(&mut self)
pub fn pmi_leave_workbench(&mut self)
Leaving the PMI workbench: deactivate the view (restoring the modeling state), close its dialogs, and forget the snapshot. An open SHEET is not this workbench’s to close — sheets are the Drawing workbench’s, and the shell closes the paper when a workbench hides the Sheets pane.
Sourcepub fn pmi_activate_view(&mut self, id: &str) -> Result<(), String>
pub fn pmi_activate_view(&mut self, id: &str) -> Result<(), String>
Activate a view: apply its camera (refit to the live viewport), hidden names, wireframe and explode poses; its annotations become the drawn and editable set.
Sourcepub fn pmi_deactivate_view(&mut self)
pub fn pmi_deactivate_view(&mut self)
Deactivate the active view: restore the explode poses, the modeling visibility, wireframe and camera. A no-op without an active view.
Sourcepub fn pmi_add_annotation(
&mut self,
view_id: Option<&str>,
type_id: &str,
params_json: &str,
) -> Result<String, String>
pub fn pmi_add_annotation( &mut self, view_id: Option<&str>, type_id: &str, params_json: &str, ) -> Result<String, String>
Add an annotation of type_id to view view_id (the active view when
None) with params_json (the schema params; id is minted). A datum
with no letter gets the next unused one. Returns the id; the new
annotation’s form opens.
Sourcepub fn pmi_update_annotation(
&mut self,
id: &str,
params_json: &str,
) -> Result<(), String>
pub fn pmi_update_annotation( &mut self, id: &str, params_json: &str, ) -> Result<(), String>
Replace an annotation’s params (a form edit). Re-runs.
pub fn pmi_remove_annotation(&mut self, id: &str) -> Result<(), String>
pub fn pmi_set_annotation_enabled( &mut self, id: &str, enabled: bool, ) -> Result<(), String>
Sourcepub fn pmi_move_annotation(
&mut self,
id: &str,
index: usize,
) -> Result<(), String>
pub fn pmi_move_annotation( &mut self, id: &str, index: usize, ) -> Result<(), String>
Move an annotation to index within its view.
Sourcepub fn pmi_move_annotation_to_view(
&mut self,
id: &str,
view_id: &str,
) -> Result<(), String>
pub fn pmi_move_annotation_to_view( &mut self, id: &str, view_id: &str, ) -> Result<(), String>
Move an annotation to another view (append).
Sourcepub fn pmi_set_annotation_open(&mut self, id: Option<&str>)
pub fn pmi_set_annotation_open(&mut self, id: Option<&str>)
Open one annotation’s form (engine memory; None closes). Opening an
annotation of another view activates that view. An open COUNTS
(Self::open_pmi_annotation) — including a re-open of the annotation
already open, which is a viewport label double click on the form the user
cannot see; an id that resolves to no annotation opens nothing and
counts nothing.
Sourcepub fn pmi_set_label_world(
&mut self,
id: &str,
world: [f64; 3],
) -> Result<(), String>
pub fn pmi_set_label_world( &mut self, id: &str, world: [f64; 3], ) -> Result<(), String>
Move an annotation’s label (world). Coalesced per annotation into ONE
undo step, and NEVER a re-run: the cached report is patched in place
and the overlay re-baked. A balloon’s arrow head is re-derived from
the moved bubble (Self::pmi_reproject_balloon_head).
Sourcepub fn pmi_label_drag_to(&mut self, id: &str, x: f64, y: f64)
pub fn pmi_label_drag_to(&mut self, id: &str, x: f64, y: f64)
Drag an annotation’s label to the pointer: the new position is where the pick ray crosses the plane through the current label perpendicular to the viewing direction (so a drag never changes the label’s depth).
Sourcepub fn pmi_label_drag_end(&mut self)
pub fn pmi_label_drag_end(&mut self)
A label drag ended: the next drag is a fresh undo step.
Sourcepub fn pmi_hover(&mut self, id: &str)
pub fn pmi_hover(&mut self, id: &str)
Hover a label: highlight the annotation’s referenced geometry.
pub fn pmi_hover_end(&mut self)
Sourcepub fn take_pmi_label_hover(&mut self) -> bool
pub fn take_pmi_label_hover(&mut self) -> bool
Consume the one-frame “a PMI label is hovering elements” flag (the viewport’s scene-hover pass yields while set).
Sourcepub fn pmi_label_clicked(&mut self, id: &str)
pub fn pmi_label_clicked(&mut self, id: &str)
A label was clicked: SELECT that annotation, as its tree row’s single click does — the label carries the accent and nothing opens.
Sourcepub fn pmi_label_double_clicked(&mut self, id: &str)
pub fn pmi_label_double_clicked(&mut self, id: &str)
A label was double-clicked: open that annotation’s form, as its tree row’s double click does.
Sourcepub fn pmi_select_annotation(&mut self, id: &str) -> bool
pub fn pmi_select_annotation(&mut self, id: &str) -> bool
SELECT an annotation without opening it — the PMI tree’s single click. Its view activates when it is not the active one, as opening does, so the selected label is on screen to carry the selection accent. Returns false, changing nothing, for an id that names no annotation.
Sourcepub fn pmi_select_view(&mut self, id: &str) -> bool
pub fn pmi_select_view(&mut self, id: &str) -> bool
SELECT a view without activating it — the PMI tree’s single click on a view row. The camera, visibility and wireframe stay as they are: a double click (which opens the view’s dialog) or the row’s On toggle is what activates. A selected annotation gives up the selection. Returns false, changing nothing, for an id that names no view.
Source§impl EngineState
impl EngineState
Sourcepub fn exploded_views(&self) -> Vec<ExplodedView>
pub fn exploded_views(&self) -> Vec<ExplodedView>
Every PMI view with at least one explode step, in view order.
Sourcepub fn is_exploded_view(&self, id: &str) -> bool
pub fn is_exploded_view(&self, id: &str) -> bool
Whether view id holds explode steps (cheap: no labels).
Sourcepub fn exploded_step_count(&self) -> usize
pub fn exploded_step_count(&self) -> usize
The number of explode steps the active view poses (enabled rows the
last run resolved), the unit of ExplodePlayback::progress.
Sourcepub fn exploded_progress(&self) -> f64
pub fn exploded_progress(&self) -> f64
The playback state, for the panel and automation.
The shown view’s progress, 0 ..= steps (the slider’s value).
pub fn exploded_state_json(&self) -> Value
Sourcepub fn exploded_set_progress(&mut self, progress: f64)
pub fn exploded_set_progress(&mut self, progress: f64)
Show the active view’s steps up to progress (clamped to
0 ..= steps), stopping any animation.
Sourcepub fn exploded_animate(
&mut self,
explode: bool,
steps_per_second: f64,
) -> Result<(), String>
pub fn exploded_animate( &mut self, explode: bool, steps_per_second: f64, ) -> Result<(), String>
Animate the active view: explode plays its steps out from where it
stands to fully exploded, else back to collapsed, at steps_per_second.
Sourcepub fn exploded_tick(&mut self, dt: f64) -> bool
pub fn exploded_tick(&mut self, dt: f64) -> bool
Advance an animation by dt seconds; true while another frame is
needed. The app calls it once per frame.
Sourcepub fn selected_occurrences(&self) -> Vec<String>
pub fn selected_occurrences(&self) -> Vec<String>
The placements the selection covers, as occurrence paths, in selection
order: for each selected solid, the shallowest placement above it whose
every solid is selected. A whole sub-assembly picked in the viewport is
ACOMP1; the pin inside it picked from the BOM is ACOMP1:ACOMP2. A
body of the assembly’s own (no placement) is not one.
Sourcepub fn exploded_add_step(
&mut self,
targets: &[String],
) -> Result<String, String>
pub fn exploded_add_step( &mut self, targets: &[String], ) -> Result<String, String>
Add a step to the shown exploded view that moves targets (the
selection’s placements when empty) straight up by their own size, and
select it, so its gizmo is armed to drag it where it belongs. Returns
the step’s id.
Sourcepub fn assembly_auto_explode(
&mut self,
name: Option<&str>,
spread: f64,
) -> Result<String, String>
pub fn assembly_auto_explode( &mut self, name: Option<&str>, spread: f64, ) -> Result<String, String>
A new exploded view of the assembly, one step per top-level component.
The base component stays: the first fixed one, else the largest. Every
other moves straight away from the base’s centre (along +Z when the
two centres coincide) by spread times half the assembly’s diagonal,
the outermost first. Returns the view’s id; the view is active.
Sourcepub fn assembly_auto_explode_deep(
&mut self,
name: Option<&str>,
spread: f64,
depth: usize,
) -> Result<String, String>
pub fn assembly_auto_explode_deep( &mut self, name: Option<&str>, spread: f64, depth: usize, ) -> Result<String, String>
Self::assembly_auto_explode depth levels down: level 1 is the
assembly’s own placements; at each further level every sub-assembly
placement (the base included) opens, its placements moving away from
its own base by spread × its own size. A nested step moves on top of
the steps of the placements above it. Steps go level by level, so
Explode takes the big pieces apart first.
Source§impl EngineState
impl EngineState
Sourcepub fn instructions(&self) -> Result<Option<Instructions>, String>
pub fn instructions(&self) -> Result<Option<Instructions>, String>
The document’s instructions block; Ok(None) when it has none.
Sourcepub fn is_instructions(&self) -> bool
pub fn is_instructions(&self) -> bool
Whether the document is an instructions document.
Sourcepub fn instructions_edit<T>(
&mut self,
coalesce: Option<&str>,
edit: impl FnOnce(&mut Instructions) -> Result<T, String>,
) -> Result<T, String>
pub fn instructions_edit<T>( &mut self, coalesce: Option<&str>, edit: impl FnOnce(&mut Instructions) -> Result<T, String>, ) -> Result<T, String>
Read the block, apply edit, validate and write it back as ONE undo
step (coalesce groups a typing run). Nothing is written on a refusal.
Sourcepub fn instructions_wrapper(&self) -> Result<(String, String), String>
pub fn instructions_wrapper(&self) -> Result<(String, String), String>
The wrapper component: (id, part name) of the first placement.
Sourcepub fn instructions_level(&self) -> Result<Level, String>
pub fn instructions_level(&self) -> Result<Level, String>
The wrapper’s assembly as the wizard’s occurrence tree.
Sourcepub fn instructions_start(
&mut self,
insert: ComponentInsert<'_>,
target: Target,
) -> Result<String, String>
pub fn instructions_start( &mut self, insert: ComponentInsert<'_>, target: Target, ) -> Result<String, String>
Make this EMPTY document the instructions for an assembly: place it as
the grounded wrapper, mark the document class and start a block for
target. One undo step. Returns the wrapper’s id.
Sourcepub fn instructions_run_wizard(&mut self) -> Result<usize, String>
pub fn instructions_run_wizard(&mut self) -> Result<usize, String>
Propose the step tree from the wrapper’s assembly, replacing the block’s steps (the target, template and front matter stay), and give each step its view. The views the old steps had are removed. One undo step. Returns the step count.
Sourcepub fn instructions_run_wizard_when_built(&mut self) -> Result<(), String>
pub fn instructions_run_wizard_when_built(&mut self) -> Result<(), String>
instructions_run_wizard now when
the scene is current, else once the pending run lands (a background
runner has not built the wrapper’s solids yet right after
instructions_start).
Sourcepub fn instructions_wizard_pending(&self) -> bool
pub fn instructions_wizard_pending(&self) -> bool
Whether the wizard is waiting for a run to land.
Sourcepub fn instructions_restructure<T>(
&mut self,
edit: impl FnOnce(&mut Instructions) -> Result<T, String>,
) -> Result<T, String>
pub fn instructions_restructure<T>( &mut self, edit: impl FnOnce(&mut Instructions) -> Result<T, String>, ) -> Result<T, String>
A structural edit (merge, split, insert, reorder, move a part, delete):
edit on the block, then every step’s view brought up to date: the
parts hidden and the balloons follow the steps’ parts, each step keeps
its camera and the author’s own annotations, a step without a view
gets one, and the views of steps that went away are removed. One undo
step.
Sourcepub fn instructions_retarget_approve(&mut self) -> Result<Target, String>
pub fn instructions_retarget_approve(&mut self) -> Result<Target, String>
Approve the pending re-target: the new revision becomes the target and the steps it left empty go, with their views. One undo step. Returns the new target.
Sourcepub fn instructions_retarget_reject(&mut self) -> Result<Target, String>
pub fn instructions_retarget_reject(&mut self) -> Result<Target, String>
Reject the pending re-target: the ONE undo that takes the new revision
and its re-target back together (what Undo does), offered as a button
and a command. Refused when none waits; when the re-target came in with
the file (nothing in this session takes it back: approve it, or update
again later); and when a later edit sits on top of that undo step (it
would go too: undo it first, or approve). The newest step is the
re-target’s when the block as it stood before it has no retarget.
Returns the target the instructions keep describing.
Sourcepub fn begin_ref_select_for_instructions(
&mut self,
step_id: &str,
field: InstructionsRefField,
seed: Option<&str>,
)
pub fn begin_ref_select_for_instructions( &mut self, step_id: &str, field: InstructionsRefField, seed: Option<&str>, )
Enter reference selection for step step_id’s occurrence field (an
arrow’s part or a callout’s): the field takes ONE solid of the placed
assembly, picked in the viewport, and Finish derives its occurrence
(Self::instructions_commit_ref). seed is the occurrence it holds
now, lit as the pick’s seed through its first solid. Nothing rolls.
Sourcepub fn instructions_occurrence_of_solid(
&self,
solid: &str,
) -> Result<String, String>
pub fn instructions_occurrence_of_solid( &self, solid: &str, ) -> Result<String, String>
The occurrence a picked solid belongs to: its name without the member
(ACOMP1:ACOMP3:Pin → ACOMP1:ACOMP3), when the placed assembly
holds that occurrence.
Sourcepub fn instructions_occurrence_solid(&self, occurrence: &str) -> Option<String>
pub fn instructions_occurrence_solid(&self, occurrence: &str) -> Option<String>
The first drawn solid of occurrence (<occurrence>:<member>), for
lighting the occurrence in the viewport.
Sourcepub fn instructions_new_step(
&mut self,
after: Option<&str>,
) -> Result<String, String>
pub fn instructions_new_step( &mut self, after: Option<&str>, ) -> Result<String, String>
A new empty step after after (or at the end), with its own view.
Returns its id.
Sourcepub fn instructions_add_parts(
&mut self,
step_id: &str,
occurrences: &[String],
) -> Result<AddReport, String>
pub fn instructions_add_parts( &mut self, step_id: &str, occurrences: &[String], ) -> Result<AddReport, String>
A BOM row dragged into a step: add occurrences of the wrapper’s
assembly to step_id (edit::add_parts). An occurrence not in the
assembly, or a step that does not exist, is refused with nothing
written. The step views follow in the same undo step. Returns what
was added and what was left where it is.
Sourcepub fn instructions_add_part(
&mut self,
step_id: &str,
part: &str,
) -> Result<AddReport, String>
pub fn instructions_add_part( &mut self, step_id: &str, part: &str, ) -> Result<AddReport, String>
Every occurrence of the part named part (its name or its PLM part id) at the assembly’s top level
(what a packed BOM row stands for; a sub-assembly’s own parts belong
to its group) into step_id, the ones already in a step reported.
Refused for a part the top level does not have.
Sourcepub fn instructions_remove_add(
&mut self,
step_id: &str,
add_index: usize,
) -> Result<(), String>
pub fn instructions_remove_add( &mut self, step_id: &str, add_index: usize, ) -> Result<(), String>
Take a part out of a step (edit::remove_add): it is not planned
any more until it is added again. One undo step, views following.
Sourcepub fn instructions_nest_step(
&mut self,
step_id: &str,
parent: Option<&str>,
index: usize,
) -> Result<(), String>
pub fn instructions_nest_step( &mut self, step_id: &str, parent: Option<&str>, index: usize, ) -> Result<(), String>
Move a step under parent (None: the top level) at index, its
children with it (edit::nest_step). One undo step, views following
(a nested step’s camera looks from its new parent’s direction).
Sourcepub fn instructions_unplanned(&self) -> Vec<(String, String)>
pub fn instructions_unplanned(&self) -> Vec<(String, String)>
The parts of the assembly not yet in any step, as (occurrence, part)
(edit::unplanned); empty when the document is not instructions.
Sourcepub fn instructions_capture_camera(
&mut self,
step_id: &str,
) -> Result<(), String>
pub fn instructions_capture_camera( &mut self, step_id: &str, ) -> Result<(), String>
Capture the viewport’s camera as step_id’s view camera. It is the
author’s from then on: every edit keeps it, until
Self::instructions_reset_view. One undo step.
Sourcepub fn instructions_reset_view(&mut self, step_id: &str) -> Result<(), String>
pub fn instructions_reset_view(&mut self, step_id: &str) -> Result<(), String>
Drop step_id’s captured camera: its view’s camera is generated again
from the step’s parts and its parent’s direction. One undo step.
Sourcepub fn instructions_show_step(&mut self, step_id: &str) -> Result<(), String>
pub fn instructions_show_step(&mut self, step_id: &str) -> Result<(), String>
Show a step’s view (its camera, hidden parts and balloons).
Sourcepub fn instructions_play(&mut self, to: PlayTo) -> Result<String, String>
pub fn instructions_play(&mut self, to: PlayTo) -> Result<String, String>
Play a step in the in-app player: show its view (its camera, ghosts and balloons) and start its parts’ insertion along their arrows. Steps go in reading order (a step’s children before it); Next on the last step and Back on the first stay put. Returns the step shown.
Sourcepub fn instructions_insertion_tick(&mut self, dt: f64) -> bool
pub fn instructions_insertion_tick(&mut self, dt: f64) -> bool
Advance the insertion by dt seconds; true while another frame is
needed. The app calls it once per frame.
Sourcepub fn instructions_insertion_fraction(&self) -> Option<f64>
pub fn instructions_insertion_fraction(&self) -> Option<f64>
How far the shown step’s parts have come home (0..1), while they move.
Sourcepub fn instructions_shown_step(&self) -> Option<String>
pub fn instructions_shown_step(&self) -> Option<String>
The step whose view is shown.
Sourcepub fn instructions_state_json(&self) -> Value
pub fn instructions_state_json(&self) -> Value
What automation and the panes read: the block, the step being shown, the steps left empty and the step count.
Source§impl EngineState
impl EngineState
Sourcepub fn simulation(&self) -> Result<Option<Simulation>, String>
pub fn simulation(&self) -> Result<Option<Simulation>, String>
The document’s simulation block; Ok(None) when it has none.
Sourcepub fn simulation_available(&self) -> bool
pub fn simulation_available(&self) -> bool
Whether the document has an assembly whose mates a study can drive.
Sourcepub fn simulation_edit<T>(
&mut self,
coalesce: Option<&str>,
edit: impl FnOnce(&mut Simulation) -> Result<T, String>,
) -> Result<T, String>
pub fn simulation_edit<T>( &mut self, coalesce: Option<&str>, edit: impl FnOnce(&mut Simulation) -> Result<T, String>, ) -> Result<T, String>
Read the block (a new one when the document has none), apply edit,
validate and write it back as ONE undo step (coalesce groups a typing
run). Nothing is written on a refusal.
Sourcepub fn simulation_motor_mates(&self) -> Vec<MotorMate>
pub fn simulation_motor_mates(&self) -> Vec<MotorMate>
This document’s distance and angle constraints, in history order.
Sourcepub fn simulation_add_study(&mut self, name: &str) -> Result<String, String>
pub fn simulation_add_study(&mut self, name: &str) -> Result<String, String>
A new study (numbered when name is empty), made active. One undo step.
Sourcepub fn simulation_set_active(&mut self, study: &str) -> Result<(), String>
pub fn simulation_set_active(&mut self, study: &str) -> Result<(), String>
Make study the one the workbench shows.
Sourcepub fn simulation_add_motor(
&mut self,
study: Option<&str>,
constraint: Option<&str>,
) -> Result<(String, String), String>
pub fn simulation_add_motor( &mut self, study: Option<&str>, constraint: Option<&str>, ) -> Result<(String, String), String>
Add a motor on mate constraint (the first mate a motor can drive
when None) to study (the active one when None): the whole study
long at 90 °/s for an angle mate, 10 mm/s for a distance mate. Returns
(study id, motor id).
Sourcepub fn simulation_constraint_ids(&self) -> Vec<String>
pub fn simulation_constraint_ids(&self) -> Vec<String>
Every constraint of the assembly block, by id, for a suppress clip to pick from (a motor drives only distance and angle mates; a suppress clip switches any mate off).
Sourcepub fn simulation_add_clip(
&mut self,
study: Option<&str>,
kind: &str,
target: Option<&str>,
) -> Result<(String, String), String>
pub fn simulation_add_clip( &mut self, study: Option<&str>, kind: &str, target: Option<&str>, ) -> Result<(String, String), String>
Add a clip of kind to study (the active one when None; a study
is started when there is none), on target or the natural default:
disable (alias suppress) the first constraint, camera through every PMI view (or
the one named), visibility or transparency (1 → 0.3) of the
selected occurrences or the first component, section of the first
PMI view with a section, explode of the first exploded view. The
span is the whole study. Returns (study id, clip id). One undo step.
Sourcepub fn simulation_remove(
&mut self,
study: &str,
item: Option<&str>,
) -> Result<(), String>
pub fn simulation_remove( &mut self, study: &str, item: Option<&str>, ) -> Result<(), String>
Delete the study study, or its motor or clip item. One undo step.
Sourcepub fn simulation_state_json(&self) -> Value
pub fn simulation_state_json(&self) -> Value
What automation and the pane read: the block (or null), the mates a
motor can drive, and whether the document can hold a study.
Sourcepub fn simulation_patch(
&mut self,
study: &str,
item: Option<&str>,
patch: &Value,
coalesce: Option<&str>,
) -> Result<(), String>
pub fn simulation_patch( &mut self, study: &str, item: Option<&str>, patch: &Value, coalesce: Option<&str>, ) -> Result<(), String>
Merge patch’s fields into the study study, or into its motor or
clip item (an object patch; null removes an optional field), as one
undo step. The result must still be a valid study.
Source§impl EngineState
impl EngineState
Sourcepub fn simulation_bake_all(
&mut self,
study: Option<&str>,
) -> Result<String, String>
pub fn simulation_bake_all( &mut self, study: Option<&str>, ) -> Result<String, String>
Bake study (the active one when None) to the end, now: the whole
bake in one call, as an export or a published motion needs it. Pauses
playback; the playhead is kept. Returns the study id.
Sourcepub fn simulation_play(
&mut self,
study: Option<&str>,
looping: Option<bool>,
) -> Result<String, String>
pub fn simulation_play( &mut self, study: Option<&str>, looping: Option<bool>, ) -> Result<String, String>
Play study (the active one when None) from where its playhead
stands — from 0 when it stands at the end — baking it first if need
be; looping sets whether it repeats. Returns the study id.
Sourcepub fn simulation_pause(&mut self)
pub fn simulation_pause(&mut self)
Hold the playhead where it is; the frame stays shown.
Sourcepub fn simulation_stop(&mut self)
pub fn simulation_stop(&mut self)
Every display back at its document pose, the playhead at 0. The bake is kept, so Play starts again at once.
Sourcepub fn simulation_seek(
&mut self,
study: Option<&str>,
time: f64,
) -> Result<(), String>
pub fn simulation_seek( &mut self, study: Option<&str>, time: f64, ) -> Result<(), String>
Put the playhead at time (seconds, clamped to the study) and show
that frame, pausing; a frame not baked yet is shown when it is.
Sourcepub fn simulation_set_looping(
&mut self,
study: Option<&str>,
looping: bool,
) -> Result<(), String>
pub fn simulation_set_looping( &mut self, study: Option<&str>, looping: bool, ) -> Result<(), String>
Whether playback repeats at the study’s end.
Sourcepub fn simulation_playing_or_shown(&self) -> bool
pub fn simulation_playing_or_shown(&self) -> bool
Whether a study is being played or scrubbed (its displays may be posed).
Sourcepub fn simulation_tick(&mut self, dt: f64) -> bool
pub fn simulation_tick(&mut self, dt: f64) -> bool
Advance by dt seconds: bake frames under the budget, move the
playhead and show its frame. true while another frame is needed
(playing, or still baking). The app calls it once per frame.
Sourcepub fn simulation_forget_playback(&mut self)
pub fn simulation_forget_playback(&mut self)
Forget the playback entirely (displays restored): the document closed or the workbench left.
Sourcepub fn simulation_playback_json(&self) -> Value
pub fn simulation_playback_json(&self) -> Value
What automation and the pane read (__brepSimulation.playback):
{study, time, playheadFrame, shown, baked, total, playing, looping, failed: [frame…], error, poses: {occurrence: {translate, rotateEulerDeg}}, interference, clashes: [frame…], shownClashes: [[a, b]…], hidden: [occurrence…], explode: [{view, progress}…], camera: {from, to, t} | null, cameraHeld, opacity: {occurrence: value}, section: {view, offset} | null} — poses are the
occurrences the shown frame moved from their document poses (explode
clips included), clashes the baked frames where parts interfere,
shownClashes the pairs at the shown frame, and hidden, explode
and camera the shown frame’s clips (cameraHeld: a camera clip has
taken the camera, which Stop gives back); null with no playback.
Source§impl EngineState
impl EngineState
Sourcepub fn simulation_motion(
&mut self,
study: Option<&str>,
) -> Result<Motion, String>
pub fn simulation_motion( &mut self, study: Option<&str>, ) -> Result<Motion, String>
The study (the active one when None) baked to the end and read out
frame by frame as the player’s motion.
Sourcepub fn simulation_publish(
&mut self,
study: Option<&str>,
) -> Result<(String, usize), String>
pub fn simulation_publish( &mut self, study: Option<&str>, ) -> Result<(String, usize), String>
Publish the study (the active one when None): bake it to the end
and write its motion into the document’s simulation block as the
study’s motion — the player’s Motion JSON with study and
assemblySignature (assembly_signature of this document) beside
the frames — for a manufacturing-instructions step to attach. One
undo step; the bake is kept. Returns the study id and the frame count.
Sourcepub fn simulation_player_data_baked(&self) -> Result<PlayerData, String>
pub fn simulation_player_data_baked(&self) -> Result<PlayerData, String>
The player data of the study as its bake stands — no baking, no
posing, nothing touched: what a PLM save publishes without disturbing
the scene. Err until a study has been played or scrubbed and its
bake has finished.
Sourcepub fn simulation_player_data(
&mut self,
study: Option<&str>,
) -> Result<PlayerData, String>
pub fn simulation_player_data( &mut self, study: Option<&str>, ) -> Result<PlayerData, String>
The study’s player data: the scene’s solids as the document poses them (a frame shown right now is read through its recorded originals), the study’s motion, its name as the title.
Sourcepub fn simulation_html(
&mut self,
study: Option<&str>,
) -> Result<(String, PlayerData), String>
pub fn simulation_html( &mut self, study: Option<&str>, ) -> Result<(String, PlayerData), String>
The study’s offline player: one self-contained .html with the data
inlined. Returns the page and the data it carries.
Source§impl EngineState
impl EngineState
Sourcepub fn begin_ref_select_for_simulation(
&mut self,
clip: &str,
path: Vec<String>,
label: String,
filter: Vec<String>,
multiple: bool,
seed_names: Vec<String>,
)
pub fn begin_ref_select_for_simulation( &mut self, clip: &str, path: Vec<String>, label: String, filter: Vec<String>, multiple: bool, seed_names: Vec<String>, )
Enter reference selection for clip clip’s list field at path
(["occurrences"]). The filter is the schema’s (SOLID, COMPONENT:
a click on component geometry answers as its component).
Source§impl EngineState
impl EngineState
Sourcepub fn instructions_published_motions(
&self,
) -> Result<Vec<PublishedMotion>, String>
pub fn instructions_published_motions( &self, ) -> Result<Vec<PublishedMotion>, String>
The assembly’s studies that carry a published motion, in block order.
Sourcepub fn instructions_attach_motion(
&mut self,
step: &str,
study: Option<&str>,
) -> Result<String, String>
pub fn instructions_attach_motion( &mut self, step: &str, study: Option<&str>, ) -> Result<String, String>
Attach the published motion of study (the only published one when
None) to step as its motion. Refused when the study has none, when
it was published before the assembly changed (publish it again there),
or when several are published and none is named. One undo step.
Returns the study id.
Source§impl EngineState
impl EngineState
Sourcepub fn begin_instructions_pdf(
&mut self,
) -> Result<InstructionsPdfExport, String>
pub fn begin_instructions_pdf( &mut self, ) -> Result<InstructionsPdfExport, String>
Begin without waiting for topology or projecting any picture.
Sourcepub fn poll_instructions_pdf(
&mut self,
job: &mut InstructionsPdfExport,
) -> Result<Option<(Vec<u8>, usize)>, String>
pub fn poll_instructions_pdf( &mut self, job: &mut InstructionsPdfExport, ) -> Result<Option<(Vec<u8>, usize)>, String>
Poll at most one picture per frame. Never wait for the runner or fall back to computing hidden lines on the UI thread if the runner refuses a job.
Sourcepub fn instructions_request_topology(&mut self) -> bool
pub fn instructions_request_topology(&mut self) -> bool
Ask the runner for the B-rep of every solid the step pictures draw
(see Self::request_exact_solids) and wait for the reply, up to
TOPOLOGY_WAIT, on a runner that can be waited on (the Inline runner
answers before the request returns; the thread runner is waited on; a
worker cannot be, and the caller holds the export until
Self::topology_pending clears). Returns whether every drawn solid’s
B-rep is in the scene now: the exact pass draws the pictures. Otherwise
the mesh approximation does, and the file says so.
Ask for the exact solids the step pictures draw WITHOUT waiting:
returns whether they are all here already. The frame’s pump lands the
replies; a caller that may not block (automation) checks
Self::topology_pending on later frames.
pub fn instructions_topology_ready(&mut self) -> bool
Sourcepub fn instructions_pdf(&mut self) -> Result<(Vec<u8>, usize), String>
pub fn instructions_pdf(&mut self) -> Result<(Vec<u8>, usize), String>
The instructions as one PDF: the cover, the parts list, the tools list
and the steps on the document’s page template, the pictures drawn by
the exact pass (Self::instructions_topology_ready). Returns the
bytes and the page count.
Sourcepub fn instructions_step_svg(&mut self, step_id: &str) -> Result<String, String>
pub fn instructions_step_svg(&mut self, step_id: &str) -> Result<String, String>
One step’s picture as SVG: its number and title over its view, hidden
lines removed by the exact pass (Self::instructions_topology_ready).
Sourcepub fn instructions_step_png(
&self,
step_id: &str,
size: u32,
) -> Result<Vec<u8>, String>
pub fn instructions_step_png( &self, step_id: &str, size: u32, ) -> Result<Vec<u8>, String>
One step’s picture as a size-pixel square PNG from its view’s camera:
what the step adds in its colours with its edges, what earlier steps
placed in grey, what comes later left out, each part where the view’s
explode rows put it.
Sourcepub fn instructions_player_data(&self) -> Result<PlayerData, String>
pub fn instructions_player_data(&self) -> Result<PlayerData, String>
The interactive player’s data: the steps over every drawn solid, each step’s camera from its view, its picture and its view’s PMI, and the assembly’s tree with each part’s thumbnail. What PLM serves per revision and the offline copy inlines.
Sourcepub fn instructions_occurrence_placement(
&self,
occurrence: &str,
) -> Option<[f64; 16]>
pub fn instructions_occurrence_placement( &self, occurrence: &str, ) -> Option<[f64; 16]>
The engine’s placement of an occurrence of the wrapper’s assembly
(ACOMP1:ACOMP3), column-major for the player: the component
features’ solved poses composed along the path, the top document’s
then each sub-assembly document’s, as the kernel places them. None
for a path the documents do not place.
Sourcepub fn instructions_html(
&self,
mode: Mode,
) -> Result<(String, PlayerData), String>
pub fn instructions_html( &self, mode: Mode, ) -> Result<(String, PlayerData), String>
The offline player: one self-contained .html with the player data
inlined, in mode. Returns the page and the data it carries.
Source§impl EngineState
impl EngineState
Source§impl EngineState
impl EngineState
Sourcepub fn cam_named_axis(&self, name: &str) -> Option<([f64; 3], [f64; 3])>
pub fn cam_named_axis(&self, name: &str) -> Option<([f64; 3], [f64; 3])>
A feature’s published axis by name (AxisFixture:Axis, from the last
history run): a point on it and its direction, for a CAM setup’s Z.
Sourcepub fn cam_chain_geometry(
&self,
chains: &[ChainRef],
) -> Result<(Vec<(String, String, NurbsCurve)>, Vec<(String, SketchProfile)>), String>
pub fn cam_chain_geometry( &self, chains: &[ChainRef], ) -> Result<(Vec<(String, String, NurbsCurve)>, Vec<(String, SketchProfile)>), String>
The sketch curves and profiles chains name, from the last history
run: {sketch}:G{id} segments and each sketch’s world profile. A name
the run did not produce is refused by name (the sketch was deleted,
rolled back past, or the id is stale), so the job never reaches the
generator with a hole in it.
Source§impl EngineState
impl EngineState
Sourcepub fn cam_enqueue(&mut self, jobs: Vec<(CamJob, u64)>) -> Vec<String>
pub fn cam_enqueue(&mut self, jobs: Vec<(CamJob, u64)>) -> Vec<String>
Queue operations for generation: each (job, inputs_hash) is one
runner job; an operation already queued or in flight is not queued
twice. The jobs’ ids are minted here.
Sourcepub fn cam_cancel(&mut self) -> usize
pub fn cam_cancel(&mut self) -> usize
Cancel: the queue is dropped at once; the job in flight is told to stop at its next chunk where the runner can (the native thread) and its reply is dropped either way; every result already landed stays.
Sourcepub fn cam_pump(&mut self)
pub fn cam_pump(&mut self)
Submit the next job when none is in flight and fold every landed reply into the results. Called every frame with the other pumps.
Sourcepub fn cam_hold_replies(&mut self, hold: bool)
pub fn cam_hold_replies(&mut self, hold: bool)
The generation state for the pane and the automation.
TEST HOLD for automation scripts (see HistoryRunner::hold_cam_replies):
while held, a generation job stays in flight on this side however fast
the runner finished it, so a scripted cancel always meets it; releasing
lets the kept replies land (a cancelled one is dropped as usual).
pub fn cam_generation_json(&self) -> Value
Source§impl EngineState
impl EngineState
Sourcepub fn sheet_state(&self) -> SheetState
pub fn sheet_state(&self) -> SheetState
The document’s sheets block as typed state (the default — no sheets —
when the document carries none).
Sourcepub fn sheet_open(&self) -> Option<&str>
pub fn sheet_open(&self) -> Option<&str>
The sheet the sheet viewport shows, if any.
Sourcepub fn set_document_name(&mut self, name: &str)
pub fn set_document_name(&mut self, name: &str)
The open document’s name — what a sheet’s TITLE BLOCK prints. The shell owns it (the document does not carry its own name), so the app sets it from the active tab; this is a no-op when it has not changed, so it can be called every frame.
pub fn document_name(&self) -> &str
Sourcepub fn sheet_open_object(&self) -> Option<&str>
pub fn sheet_open_object(&self) -> Option<&str>
The sheet or placed view whose form the Sheets pane shows.
Sourcepub fn sheet_object_opens(&self) -> u64
pub fn sheet_object_opens(&self) -> u64
How many sheet-object forms this engine has OPENED — the app’s dialog
door reads it beside Self::sheet_open_object so a re-open of the
object already open is still an open (the id alone does not move).
Monotonic and never reset; a CLOSE does not count.
Sourcepub fn sheet_selected_object(&self) -> Option<&str>
pub fn sheet_selected_object(&self) -> Option<&str>
The placement, dimension or ordinate set selected in the Sheets tree or on the paper, while it exists.
Sourcepub fn sheet_select_object(&mut self, id: Option<&str>) -> bool
pub fn sheet_select_object(&mut self, id: Option<&str>) -> bool
SELECT a placement, dimension or ordinate set without opening its form
— the Sheets tree’s single click (None deselects). Returns false,
changing nothing, for an id that names none of those.
Sourcepub fn sheet_pmi_view_ids(&self) -> Vec<String>
pub fn sheet_pmi_view_ids(&self) -> Vec<String>
The saved PMI view ids a placement may name, in block order.
Sourcepub fn sheet_catalogue(&self) -> Value
pub fn sheet_catalogue(&self) -> Value
The sheet object schemas, with the document’s own PMI views as the
view field’s options.
Sourcepub fn sheet_state_json(&mut self) -> String
pub fn sheet_state_json(&mut self) -> String
The __brepSheets automation blob: the block, which sheet is open,
which object’s form is open, and the OPEN sheet’s projection.
Assembled rather than json!-built, because the projection is the big
part and it is already serialised in the cache: everything this adds is
O(sheets), never O(model). The registry publishes it every frame.
Sourcepub fn sheet_project(&mut self, id: &str) -> bool
pub fn sheet_project(&mut self, id: &str) -> bool
Project sheet id into the cache unless it is already there. false
when the block carries no such sheet.
The pair with Self::sheet_drawing_cached is what keeps the sheet
viewport off a per-frame COPY of the drawing: the lookup needs &mut
(it may project), the paint needs only &, and a caller that wants
both at once used to satisfy the borrow by cloning the whole projection
every frame.
Sourcepub fn pump_sheet_lines(&mut self)
pub fn pump_sheet_lines(&mut self)
Land every sheet pass the runner has answered (see SheetLinesWork).
Sourcepub fn sheet_lines_pending(&self) -> bool
pub fn sheet_lines_pending(&self) -> bool
Whether a sheet’s exact pass is on the runner or waiting for it — the frame loop and the idle contract wait on it like a topology request.
Sourcepub fn sheet_drawing_cached(&self, id: &str) -> Option<&SheetDrawing>
pub fn sheet_drawing_cached(&self, id: &str) -> Option<&SheetDrawing>
The CACHED projection of sheet id, without projecting: None unless
Self::sheet_project put that sheet in the cache and nothing has
invalidated it since (the whole key is checked, not just the id).
Sourcepub fn sheet_drawing(&mut self, id: &str) -> Option<&SheetDrawing>
pub fn sheet_drawing(&mut self, id: &str) -> Option<&SheetDrawing>
The projected sheet id, built on demand and cached until the model
rebuilds or the block changes. None when the block carries no such
sheet. The one-call door for an export; a PAINT uses the split pair
above.
Sourcepub fn export_sheet_svg(&mut self, id: &str) -> Result<String, String>
pub fn export_sheet_svg(&mut self, id: &str) -> Result<String, String>
Sheet id as SVG — one of the sheet export’s two output contracts.
Sourcepub fn sheet_drawing_exact(&mut self, id: &str) -> Option<&SheetDrawing>
pub fn sheet_drawing_exact(&mut self, id: &str) -> Option<&SheetDrawing>
Self::sheet_drawing with every exact pass it lacks run HERE: a file
is never written from a mesh approximation that only stood in while a
pass was on the runner. The finished drawing replaces the cached one,
so the viewport shows what was exported.
Sourcepub fn export_sheet_pdf(&mut self, id: &str) -> Result<Vec<u8>, String>
pub fn export_sheet_pdf(&mut self, id: &str) -> Result<Vec<u8>, String>
Sheet id as a one-page PDF titled with the sheet’s name — the
one-page case of Self::export_sheets_pdf. What the PDF cannot carry
that the SVG does is written down in crate::sheets::pdf.
Sourcepub fn export_document_pdf(&mut self) -> Result<Vec<u8>, String>
pub fn export_document_pdf(&mut self) -> Result<Vec<u8>, String>
EVERY sheet of the document as one PDF, in the block’s sheet order —
one page per sheet, each at its own paper size — titled with the
document’s name (the first sheet’s when the document has none). This is
what the export doors write; the SVG stays one file per sheet. The plain
2D drawing set: a placement’s threeD is the 3D export’s alone.
Sourcepub fn export_document_pdf_3d(&mut self) -> Result<Vec<u8>, String>
pub fn export_document_pdf_3d(&mut self) -> Result<Vec<u8>, String>
The same drawing set with the live 3D model (crate::sheets::pdf3d):
a 3D box over every placement marked threeD, and a last page given
over to the model with a button per saved PMI view — Sheets + 3D (PDF).
Sourcepub fn export_sheets_pdf(
&mut self,
ids: &[String],
title: &str,
) -> Result<Vec<u8>, String>
pub fn export_sheets_pdf( &mut self, ids: &[String], title: &str, ) -> Result<Vec<u8>, String>
Sheets ids as one PDF, one page each in the order given.
The projection cache holds ONE sheet, the one on screen, and an export must not evict it: a sheet the cache already holds is read from it, and every other is projected for this export alone and dropped, so closing the export leaves the viewport exactly as warm as it was.
Sourcepub fn export_sheets_pdf_with(
&mut self,
ids: &[String],
title: &str,
three_d: bool,
) -> Result<Vec<u8>, String>
pub fn export_sheets_pdf_with( &mut self, ids: &[String], title: &str, three_d: bool, ) -> Result<Vec<u8>, String>
Self::export_sheets_pdf, with the 3D model when three_d: over
every placement marked threeD, and on a last page. Without it the
file is crate::sheets::pdf::write_pdf’s, byte for byte, whatever
the placements say.
Sourcepub fn resolve_sheet(&self, id: &str) -> Result<String, String>
pub fn resolve_sheet(&self, id: &str) -> Result<String, String>
The sheet an export writes: the named one, else the OPEN one, else the first in the block.
Sourcepub fn sheet_add(&mut self, name: Option<&str>) -> String
pub fn sheet_add(&mut self, name: Option<&str>) -> String
Add a sheet (name or Sheet N, the default paper size) and open it.
Returns the id.
Sourcepub fn sheet_insert_bom(&mut self) -> Result<(), String>
pub fn sheet_insert_bom(&mut self) -> Result<(), String>
Insert a live BOM table on the open sheet and open its settings.
Sourcepub fn sheet_bom_columns(&self) -> Vec<String>
pub fn sheet_bom_columns(&self) -> Vec<String>
Available built-in and custom attributes, in stable order.
Sourcepub fn sheet_update(
&mut self,
id: &str,
params_json: &str,
) -> Result<(), String>
pub fn sheet_update( &mut self, id: &str, params_json: &str, ) -> Result<(), String>
Apply an edited Sheet form.
Sourcepub fn sheet_add_revision(
&mut self,
id: &str,
rev: Option<&str>,
date: Option<&str>,
description: Option<&str>,
) -> Result<usize, String>
pub fn sheet_add_revision( &mut self, id: &str, rev: Option<&str>, date: Option<&str>, description: Option<&str>, ) -> Result<usize, String>
Append a revision row to sheet id and return its index. Absent
fields are seeded the way a drawing office starts a row: the letter
after the last row’s (A on an empty table, skipping I, O and Q
as a view letter does), today’s date, and no description.
Sourcepub fn sheet_update_revision(
&mut self,
id: &str,
index: usize,
params_json: &str,
) -> Result<(), String>
pub fn sheet_update_revision( &mut self, id: &str, index: usize, params_json: &str, ) -> Result<(), String>
Patch revision row index of sheet id (rev, date,
description; absent keys are unchanged).
Sourcepub fn sheet_remove_revision(
&mut self,
id: &str,
index: usize,
) -> Result<(), String>
pub fn sheet_remove_revision( &mut self, id: &str, index: usize, ) -> Result<(), String>
Remove revision row index of sheet id. The rows after it move up
one and keep their order.
pub fn sheet_delete(&mut self, id: &str) -> Result<(), String>
Sourcepub fn sheet_set_open(&mut self, id: Option<&str>) -> Result<(), String>
pub fn sheet_set_open(&mut self, id: Option<&str>) -> Result<(), String>
Show sheet id in the sheet viewport (None returns to the 3D view).
Sourcepub fn sheet_set_object_open(&mut self, id: Option<&str>)
pub fn sheet_set_object_open(&mut self, id: Option<&str>)
Open a sheet or placed view’s form in the Sheets pane (None closes).
An open COUNTS (Self::open_sheet_object) — including a re-open of
the object already open, which is a click on the same dimension on the
paper while the Sheets pane sits behind another tab.
Sourcepub fn sheet_place_view(
&mut self,
sheet_id: Option<&str>,
view_id: &str,
position: Option<[f64; 2]>,
scale: Option<f64>,
) -> Result<String, String>
pub fn sheet_place_view( &mut self, sheet_id: Option<&str>, view_id: &str, position: Option<[f64; 2]>, scale: Option<f64>, ) -> Result<String, String>
Place PMI view view_id on sheet sheet_id (the open sheet when
absent), centred on the paper unless position says otherwise, and
open its form. Returns the placement id.
Sourcepub fn sheet_update_view(
&mut self,
id: &str,
params_json: &str,
) -> Result<(), String>
pub fn sheet_update_view( &mut self, id: &str, params_json: &str, ) -> Result<(), String>
Apply an edited Placed view form.
Sourcepub fn sheet_move_view(
&mut self,
id: &str,
position: [f64; 2],
coalesce: bool,
) -> Result<(), String>
pub fn sheet_move_view( &mut self, id: &str, position: [f64; 2], coalesce: bool, ) -> Result<(), String>
Move a placed view to position (paper millimetres). coalesce groups
a drag into ONE undo step, the PMI label drag’s rule.
Sourcepub fn sheet_move_view_end(&mut self)
pub fn sheet_move_view_end(&mut self)
End a placement drag: the next move starts a fresh undo entry.
pub fn sheet_remove_view(&mut self, id: &str) -> Result<(), String>
Sourcepub fn sheet_add_dimension(
&mut self,
sheet_id: Option<&str>,
kind: &str,
alignment: Option<&str>,
anchors: Vec<String>,
) -> Result<String, String>
pub fn sheet_add_dimension( &mut self, sheet_id: Option<&str>, kind: &str, alignment: Option<&str>, anchors: Vec<String>, ) -> Result<String, String>
Add a dimension to sheet sheet_id (the open sheet when absent) and
open its form. anchors are reference strings; an EMPTY list is
allowed and gives an unresolved dimension whose form is where its
anchors get picked.
Sourcepub fn sheet_update_dimension(
&mut self,
id: &str,
params_json: &str,
) -> Result<(), String>
pub fn sheet_update_dimension( &mut self, id: &str, params_json: &str, ) -> Result<(), String>
Apply an edited Sheet dimension form.
Sourcepub fn sheet_move_dimension(
&mut self,
id: &str,
offset_mm: f64,
coalesce: bool,
) -> Result<(), String>
pub fn sheet_move_dimension( &mut self, id: &str, offset_mm: f64, coalesce: bool, ) -> Result<(), String>
Move a dimension’s line: offset_mm from its anchors, signed. What
dragging its value box in the sheet viewport does, so coalesce groups
a drag into ONE undo step exactly as a placement drag does.
Sourcepub fn sheet_move_dimension_end(&mut self)
pub fn sheet_move_dimension_end(&mut self)
End an offset drag: the next move starts a fresh undo entry.
pub fn sheet_remove_dimension(&mut self, id: &str) -> Result<(), String>
Sourcepub fn sheet_add_ordinate(
&mut self,
sheet_id: Option<&str>,
axis: &str,
datum: Option<&str>,
members: Vec<String>,
) -> Result<String, String>
pub fn sheet_add_ordinate( &mut self, sheet_id: Option<&str>, axis: &str, datum: Option<&str>, members: Vec<String>, ) -> Result<String, String>
Add an ordinate set to sheet sheet_id (the open sheet when absent)
and open its form. datum may be empty: the set is then unresolved and
its form is where the datum gets picked.
Sourcepub fn sheet_update_ordinate(
&mut self,
id: &str,
params_json: &str,
) -> Result<(), String>
pub fn sheet_update_ordinate( &mut self, id: &str, params_json: &str, ) -> Result<(), String>
Apply an edited Ordinate set form.
A set with no DATUM is kept, unresolved: it is what the Ordinate set button creates, and its form is where the datum gets picked. Every value it would draw is a distance from that datum, so until there is one the set draws its id and the reason instead.
Sourcepub fn sheet_move_ordinate(
&mut self,
id: &str,
offset_mm: f64,
coalesce: bool,
) -> Result<(), String>
pub fn sheet_move_ordinate( &mut self, id: &str, offset_mm: f64, coalesce: bool, ) -> Result<(), String>
Move a set’s BASELINE: its signed distance from the datum in paper
millimetres. One number for the whole set, so coalesce groups a drag
into one undo step exactly as a dimension’s offset drag does.
Sourcepub fn sheet_move_ordinate_end(&mut self)
pub fn sheet_move_ordinate_end(&mut self)
End a baseline drag: the next move starts a fresh undo entry.
pub fn sheet_remove_ordinate(&mut self, id: &str) -> Result<(), String>
Sourcepub fn sheet_ordinate_offset_at(
&mut self,
id: &str,
at: [f64; 2],
) -> Option<f64>
pub fn sheet_ordinate_offset_at( &mut self, id: &str, at: [f64; 2], ) -> Option<f64>
The baseline offset that would put set id’s baseline through the
paper point at. None when the set has no datum to measure from.
Unlike a dimension’s, this needs no probe: a set’s offset runs along ONE known paper axis — down the page for a horizontal set, across it for a vertical one — and the datum’s own anchor point is the base.
Sourcepub fn sheet_add_section(
&mut self,
source: &str,
from: &str,
to: &str,
position: Option<[f64; 2]>,
) -> Result<String, String>
pub fn sheet_add_section( &mut self, source: &str, from: &str, to: &str, position: Option<[f64; 2]>, ) -> Result<String, String>
Add a SECTION VIEW of source, cutting along the line through the two
anchors, placed at position (beside the source when absent).
The section places the SAME saved PMI view its source does — it needs that view’s hidden-solid set and its text size — and overrides only the camera, which is derived from the cut rather than stored. Returns the placement id.
Sourcepub fn sheet_new_section(
&mut self,
sheet_id: Option<&str>,
) -> Result<String, String>
pub fn sheet_new_section( &mut self, sheet_id: Option<&str>, ) -> Result<String, String>
Add a SECTION VIEW with no cutting line yet to sheet sheet_id (the
open sheet when absent) and open its form — what the Drawing
workbench’s Section view button does. The placement is unresolved and
says so on the paper; its form’s Cutting line row is where the two
anchors are picked (Self::sheet_set_placement_refs), and the first
line picked decides which placement it is a section OF.
Sourcepub fn sheet_new_detail(
&mut self,
sheet_id: Option<&str>,
) -> Result<String, String>
pub fn sheet_new_detail( &mut self, sheet_id: Option<&str>, ) -> Result<String, String>
The detail twin of Self::sheet_new_section: a DETAIL VIEW with no
circle yet, whose form’s Centre and Point on the rim rows are
picked on a placed view.
Sourcepub fn sheet_set_placement_refs(
&mut self,
id: &str,
field: &str,
names: &[String],
) -> Result<(), String>
pub fn sheet_set_placement_refs( &mut self, id: &str, field: &str, names: &[String], ) -> Result<(), String>
Set a derived placement’s PICKED references: cut (a section’s two
cutting-line anchors), centre or rim (a detail circle’s). What a
form’s reference rows commit, the picker’s Finish and a row’s ✕ alike.
The anchors must all lie on ONE plain placement of the same sheet — the
line or circle is drawn on that view and read through its camera — and
that placement becomes the source. A placement that has no saved view
yet (made by Self::sheet_new_section / _detail) takes its
source’s view and scale — twice it, for a detail — and moves beside the
source, where Self::sheet_add_section would have put it. Fewer
anchors than the construction needs is allowed: the placement stays
unresolved and says what is missing.
Sourcepub fn begin_ref_select_for_sheet(
&mut self,
id: &str,
path: Vec<String>,
label: String,
filter: Vec<String>,
multiple: bool,
seed_names: Vec<String>,
) -> Result<(), String>
pub fn begin_ref_select_for_sheet( &mut self, id: &str, path: Vec<String>, label: String, filter: Vec<String>, multiple: bool, seed_names: Vec<String>, ) -> Result<(), String>
Enter the reference picker for sheet object id’s reference field
path — a dimension’s anchors, an ordinate set’s datum or
members, a section’s cut, a detail’s centre or rim. The same
modal the feature, constraint and PMI dialogs use: the rest of the UI
steps aside, picks land in the running list, Finish commits and
Cancel discards. Here the picks are ANCHORS clicked on the paper, so
the object’s sheet is opened first, and nothing rolls.
Sourcepub fn ref_select_pick_sheet_anchor(
&mut self,
anchor: &str,
) -> Result<(), String>
pub fn ref_select_pick_sheet_anchor( &mut self, anchor: &str, ) -> Result<(), String>
An anchor clicked on the paper while the sheet picker is up: added to the running list — replacing it in a single field, appended in a list (once), and in a list that is FULL for its object (a linear dimension’s two, a cutting line’s two) the oldest pick makes room, so a wrong pick is corrected by picking again.
Sourcepub fn sheet_add_detail(
&mut self,
source: &str,
centre: &str,
rim: &str,
position: Option<[f64; 2]>,
scale: Option<f64>,
) -> Result<String, String>
pub fn sheet_add_detail( &mut self, source: &str, centre: &str, rim: &str, position: Option<[f64; 2]>, scale: Option<f64>, ) -> Result<String, String>
Add a DETAIL VIEW of source: the region inside the circle centred on
anchor centre and passing through anchor rim, redrawn at scale
(twice the source’s when absent) and placed at position (beside the
source when absent).
The detail places the SAME saved PMI view its source does and looks through the source’s camera; its scale and its clip are its own. Returns the placement id.
Sourcepub fn sheet_dimension_offset_at(
&mut self,
id: &str,
at: [f64; 2],
) -> Option<f64>
pub fn sheet_dimension_offset_at( &mut self, id: &str, at: [f64; 2], ) -> Option<f64>
The offset that would put dimension id’s line through the paper point
at: the component of at - (the dimension's own base point) along the
direction the offset moves the line in. None when the dimension has
not resolved — there is nothing to measure from.
This is a PROBE of the current projection rather than a second layout:
it re-reads the dimension’s drawn label, which already sits at
base + offset, so the answer is exact for any kind without this
module knowing how any of them is constructed.
Source§impl EngineState
impl EngineState
Sourcepub fn refresh_pmi_overlay(&mut self)
pub fn refresh_pmi_overlay(&mut self)
Re-bake the overlay from the cached report (empty without an active view or while a sketch edit is live).
Sourcepub fn ensure_pmi_overlay_current(&mut self)
pub fn ensure_pmi_overlay_current(&mut self)
Per-frame upkeep: re-bake when the zoom (>0.5 %) or the viewing direction (>0.5°) moved, so arrowheads stay pixel-sized and face the camera.
Sourcepub fn pmi_labels_json(&self) -> String
pub fn pmi_labels_json(&self) -> String
The label feed for the app’s chip pass — the active view’s
annotations: [{id, type, icon, text, status, message, color:[r,g,b], world:[x,y,z], enabled, open, selected, textSizePt}]. Empty without an
active view. The automation registry’s copy of Self::pmi_labels.
Sourcepub fn pmi_labels(&self) -> Vec<PmiLabel>
pub fn pmi_labels(&self) -> Vec<PmiLabel>
The label feed, typed: what the viewport’s chip pass reads every frame. It reads the shared parse of the PMI block, so a frame with nothing changed builds the rows and nothing else.
Source§impl EngineState
impl EngineState
Sourcepub fn is_port_feature(&self, name: &str) -> bool
pub fn is_port_feature(&self, name: &str) -> bool
Whether name is a WAYPOINT feature’s id.
Sourcepub fn is_port_id(&self, name: &str) -> bool
pub fn is_port_id(&self, name: &str) -> bool
Whether name addresses a harness node at all: a WAYPOINT feature of
this document, a connection point it declares (J1.VCC), or one a
placed component carries (ACOMP1:J1.VCC), which the harness report
lists among its endpoints.
Sourcepub fn is_spline_feature(&self, feature_id: &str) -> bool
pub fn is_spline_feature(&self, feature_id: &str) -> bool
Whether feature_id names a SPLINE feature.
Sourcepub fn spline_anchors(&self, feature_id: &str) -> Vec<SplineAnchorRow>
pub fn spline_anchors(&self, feature_id: &str) -> Vec<SplineAnchorRow>
The spline’s anchors, resolved (empty for a non-spline id).
Sourcepub fn armed_spline_anchor(&self) -> Option<(String, usize)>
pub fn armed_spline_anchor(&self) -> Option<(String, usize)>
The armed spline anchor (feature id, index), if the gizmo is on one.
Sourcepub fn spline_edit_feature(&self) -> Option<&str>
pub fn spline_edit_feature(&self) -> Option<&str>
The spline whose anchor editor is open, if any (the history panel feeds it with the cage overlay).
Sourcepub fn spline_anchor_pick_at(&mut self, x: f64, y: f64) -> Option<usize>
pub fn spline_anchor_pick_at(&mut self, x: f64, y: f64) -> Option<usize>
A viewport click while a spline’s editor is open: when one of THAT
spline’s anchor dots (the sheet’s vertex there) sits under CSS-pixel
(x, y), select the anchor — the gizmo arms on a free one — and report
its index. The RAW pick is used, so the selection filter cannot hide
the anchors; None leaves the click to the ordinary selection.
Sourcepub fn take_spline_anchor_pick(&mut self) -> Option<usize>
pub fn take_spline_anchor_pick(&mut self) -> Option<usize>
The anchor the last viewport click selected, once — the history panel takes it to move its row selection.
Sourcepub fn spline_set_anchor_position(
&mut self,
feature_id: &str,
anchor: usize,
position: [f64; 3],
) -> Result<(), String>
pub fn spline_set_anchor_position( &mut self, feature_id: &str, anchor: usize, position: [f64; 3], ) -> Result<(), String>
Set an anchor’s stored position (ignored by the kernel while attached).
Sourcepub fn spline_set_anchor_distances(
&mut self,
feature_id: &str,
anchor: usize,
forward: Option<f64>,
backward: Option<f64>,
) -> Result<(), String>
pub fn spline_set_anchor_distances( &mut self, feature_id: &str, anchor: usize, forward: Option<f64>, backward: Option<f64>, ) -> Result<(), String>
Set an anchor’s forward / backward straight-run distances (either may be left alone). Negative values clamp to zero.
Sourcepub fn spline_set_anchor_flip(
&mut self,
feature_id: &str,
anchor: usize,
flip: bool,
) -> Result<(), String>
pub fn spline_set_anchor_flip( &mut self, feature_id: &str, anchor: usize, flip: bool, ) -> Result<(), String>
Flip an anchor’s travel direction (no effect while attached — the side decides).
Sourcepub fn spline_set_anchor_side(
&mut self,
feature_id: &str,
anchor: usize,
side: PortSide,
) -> Result<(), String>
pub fn spline_set_anchor_side( &mut self, feature_id: &str, anchor: usize, side: PortSide, ) -> Result<(), String>
Switch an attached anchor’s port side.
Sourcepub fn spline_detach_anchor(
&mut self,
feature_id: &str,
anchor: usize,
) -> Result<(), String>
pub fn spline_detach_anchor( &mut self, feature_id: &str, anchor: usize, ) -> Result<(), String>
Detach an anchor from its port, keeping the curve where it is: the resolved position and direction the port gave it become its stored placement.
Sourcepub fn spline_add_anchor(
&mut self,
feature_id: &str,
after: Option<usize>,
) -> Result<usize, String>
pub fn spline_add_anchor( &mut self, feature_id: &str, after: Option<usize>, ) -> Result<usize, String>
Add an anchor after after (the last anchor when None), placed past
it along its direction by its forward run plus a gap, facing the same
way. Returns the new anchor’s index.
Sourcepub fn spline_remove_anchor(
&mut self,
feature_id: &str,
anchor: usize,
) -> Result<(), String>
pub fn spline_remove_anchor( &mut self, feature_id: &str, anchor: usize, ) -> Result<(), String>
Remove an anchor. A spline keeps at least two.
Sourcepub fn spline_move_anchor(
&mut self,
feature_id: &str,
anchor: usize,
up: bool,
) -> Result<(), String>
pub fn spline_move_anchor( &mut self, feature_id: &str, anchor: usize, up: bool, ) -> Result<(), String>
Move an anchor one place up (towards the start) or down.
Sourcepub fn arm_spline_anchor(&mut self, feature_id: &str, anchor: usize) -> bool
pub fn arm_spline_anchor(&mut self, feature_id: &str, anchor: usize) -> bool
Arm the move/rotate gizmo on one anchor. Refused (false) for an attached anchor — the port owns its pose — and for a bad index.
Sourcepub fn begin_ref_select_for_spline_anchor(
&mut self,
feature_id: &str,
anchor: usize,
)
pub fn begin_ref_select_for_spline_anchor( &mut self, feature_id: &str, anchor: usize, )
Enter the reference picker to attach anchor to a port: the pick
admits a port’s drawn sheet (its line / base vertex / the sheet), and
Finish writes the attachment.
Source§impl EngineState
impl EngineState
Sourcepub fn is_cage_feature(&self, feature_id: &str) -> bool
pub fn is_cage_feature(&self, feature_id: &str) -> bool
Whether feature_id names a NURBS Solid.
Sourcepub fn cage_of(&self, feature_id: &str) -> Result<ControlCage, String>
pub fn cage_of(&self, feature_id: &str) -> Result<ControlCage, String>
The cage the kernel builds feature_id from (persisted or primitive),
or the reason it cannot be read.
Sourcepub fn cage_points(&self, feature_id: &str) -> Vec<[f64; 3]>
pub fn cage_points(&self, feature_id: &str) -> Vec<[f64; 3]>
Every control point of the cage in linear order (empty for a non-cage, or a cage the document cannot build).
Sourcepub fn cage_summary(&self, feature_id: &str) -> Option<CageSummary>
pub fn cage_summary(&self, feature_id: &str) -> Option<CageSummary>
The cage’s shape for the panel, None for a non-cage.
Sourcepub fn cage_edit_feature(&self) -> Option<&str>
pub fn cage_edit_feature(&self) -> Option<&str>
The NURBS solid whose cage editor is open, if any (the history panel feeds it with the overlay).
Sourcepub fn cage_selected(&self) -> Vec<usize>
pub fn cage_selected(&self) -> Vec<usize>
The selected point indices of the armed cage (empty unless the gizmo is armed on a cage).
Sourcepub fn cage_armed_for(&self, feature_id: &str) -> bool
pub fn cage_armed_for(&self, feature_id: &str) -> bool
Whether the gizmo is armed on the cage of feature_id.
Sourcepub fn cage_select(
&mut self,
feature_id: &str,
indices: &[usize],
mode: CageSelect,
)
pub fn cage_select( &mut self, feature_id: &str, indices: &[usize], mode: CageSelect, )
Change the selection of feature_id’s cage and arm the gizmo at the
selection’s centroid (disarmed when nothing is left selected).
Indices outside the cage are ignored.
Sourcepub fn cage_select_all(&mut self, feature_id: &str)
pub fn cage_select_all(&mut self, feature_id: &str)
Select every point of the cage.
Sourcepub fn cage_clear_selection(&mut self, feature_id: &str)
pub fn cage_clear_selection(&mut self, feature_id: &str)
Clear the selection (and so disarm the gizmo).
Sourcepub fn cage_select_rings_of_selection(&mut self, feature_id: &str)
pub fn cage_select_rings_of_selection(&mut self, feature_id: &str)
Grow the selection to the whole ring of every selected ring point (a selected pole stays as it is).
Sourcepub fn cage_select_columns_of_selection(&mut self, feature_id: &str)
pub fn cage_select_columns_of_selection(&mut self, feature_id: &str)
Grow the selection to the whole column (pole to pole, poles excluded) of every selected ring point.
Sourcepub fn cage_point_pick_at(
&mut self,
x: f64,
y: f64,
toggle: bool,
) -> Option<usize>
pub fn cage_point_pick_at( &mut self, x: f64, y: f64, toggle: bool, ) -> Option<usize>
A viewport click while a cage editor is open: when one of the cage’s
dots sits within CAGE_PICK_RADIUS_PX of CSS-pixel (x, y), select
it — REPLACING the selection, or TOGGLING it in with toggle (a
modifier held) — and report its index. Dots are picked by projection,
so a point behind the body is as pickable as one in front, which is
what a cage wants. None leaves the click to the ordinary selection.
Sourcepub fn cage_point_screen_points(&self) -> Vec<(usize, (f64, f64))>
pub fn cage_point_screen_points(&self) -> Vec<(usize, (f64, f64))>
Every cage dot projected to VIEWPORT-LOCAL px, (index, (x, y)), for
the host’s hit blob. Empty unless a cage editor is open.
Sourcepub fn cage_set_point_position(
&mut self,
feature_id: &str,
index: usize,
position: [f64; 3],
) -> Result<(), String>
pub fn cage_set_point_position( &mut self, feature_id: &str, index: usize, position: [f64; 3], ) -> Result<(), String>
Move one point to position (a typed edit; coalesced per point).
Sourcepub fn cage_insert_ring(
&mut self,
feature_id: &str,
above: bool,
) -> Result<usize, String>
pub fn cage_insert_ring( &mut self, feature_id: &str, above: bool, ) -> Result<usize, String>
Insert a ring beside the selected point: above puts it between that
point’s ring and the next towards the top pole, else towards the
bottom. With several points selected the first decides. The body is
unchanged; the new ring is selected. Returns its ring index.
Sourcepub fn cage_insert_column(
&mut self,
feature_id: &str,
next: bool,
) -> Result<usize, String>
pub fn cage_insert_column( &mut self, feature_id: &str, next: bool, ) -> Result<usize, String>
Insert a column (pole to pole) beside the selected point: next puts
it between that point’s column and the next around the ring, else the
previous. A selected pole offers no column, so a ring point must be
selected. The body is unchanged; the new column is selected. Returns
its column index.
Sourcepub fn cage_reset(&mut self, feature_id: &str) -> Result<(), String>
pub fn cage_reset(&mut self, feature_id: &str) -> Result<(), String>
Drop the edited cage: the body returns to the primitive the params describe. Clears the selection.
Sourcepub fn refresh_cage_edit_overlay(&mut self, feature_id: Option<&str>)
pub fn refresh_cage_edit_overlay(&mut self, feature_id: Option<&str>)
Feed the cage overlay for feature_id — its rings, its columns and a
dot per point, the selected ones highlighted — or clear it with
None. Cheap to call every frame: an unchanged feed is skipped.
Source§impl EngineState
impl EngineState
Source§impl EngineState
impl EngineState
Sourcepub fn object_metadata_json(&self, name: &str) -> String
pub fn object_metadata_json(&self, name: &str) -> String
One object’s metadata record as JSON { key: value, ... } ({} if none).
Sourcepub fn set_metadata_attribute(&mut self, name: &str, key: &str, value: &str)
pub fn set_metadata_attribute(&mut self, name: &str, key: &str, value: &str)
Set (or overwrite) one metadata attribute of an object by NAME. String
value; the well-known density key drives the object’s weight and the
well-known color key drives its shaded colour.
Sourcepub fn remove_metadata_attribute(&mut self, name: &str, key: &str) -> bool
pub fn remove_metadata_attribute(&mut self, name: &str, key: &str) -> bool
Remove one metadata attribute of an object. Returns whether it existed.
Sourcepub fn sync_colors_from_metadata(&mut self) -> bool
pub fn sync_colors_from_metadata(&mut self) -> bool
Re-derive the display scene’s colours from the metadata store — the ONE
call that connects the durable color attribute to the renderer.
Every colour the viewport shows comes from here: a STEP import’s stamped
body/face colours, a colour typed or picked in the Info window, a colour
restored from a saved document. The store is the authority; the display’s
color_override fields are a derived cache of it, rebuilt after every
history apply (EngineState::finish_apply), on every document load, on
a metadata edit, and whenever the display setting flips.
crate::style::RenderSettings::override_model_colors is honoured HERE
rather than in the renderer, and it is deliberately a READ of the store,
never a write: ticking the box resolves every colour to None so the
viewport falls back to faceColorMode, while the stored attributes stay
exactly as they were. Unticking restores them from the same records.
Returns whether anything changed, and marks the engine dirty only then — the no-op case must stay free, since this runs after every single run.
Sourcepub fn metadata_json(&self) -> String
pub fn metadata_json(&self) -> String
The whole metadata store as JSON { name: { key: value } }.
Sourcepub fn metadata_value(&self) -> Value
pub fn metadata_value(&self) -> Value
Self::metadata_json as a JSON value.
Source§impl EngineState
impl EngineState
Sourcepub fn creating_feature(&self, name: &str) -> Option<(String, String)>
pub fn creating_feature(&self, name: &str) -> Option<(String, String)>
The feature that an object ORIGINATES from, as (feature id, feature type).
For a FACE/EDGE this is the feature that first gave it its name (its true
origin, from the eager entity_origin first-writer map) — NOT the owning
solid’s last producer — so “Edit owning feature” rolls back to where the
entity was born. For a SOLID it’s the solid’s producer (last writer, the
eager provenance map). None if the name is unknown or has no known
producer. Reads only the eager maps the last run shipped, so it never re-runs
the history — the freeze side-door context_bar hit every selected frame is
now O(1).
Sourcepub fn is_sheet_metal_object(&self, name: &str) -> bool
pub fn is_sheet_metal_object(&self, name: &str) -> bool
Whether the object name (a solid, or a face/edge owned by a solid) sits
on a SHEET-METAL body — its owning display solid carries the sheet-metal
marker the pipeline stamped from the resident handle’s SheetTree. Reads
only the display scene, so it is O(1) and thread-safe (no SheetTree
thread-local touched on the UI thread — [crate::scene::SolidDisplay:: is_sheet_metal]). The gate for the sheet-metal edit features (SM Flange /
Fillet / Chamfer). false for an unknown name or a synthesized sketch
sheet (no resident handle, no tree).
Sourcepub fn object_info_json(&mut self, name: &str) -> String
pub fn object_info_json(&mut self, name: &str) -> String
The full Properties-panel info for an object by NAME: its resolved kind, the right measurements, and provenance. Units are millimetres.
- Solid —
{ ok, name, kind:"solid", volume, surfaceArea, edgeLengthTotal, density, weight, creatingFeature }, whereweight = density · volumeanddensitycomes from the object’s metadata (defaultDEFAULT_DENSITY). - Face —
{ ok, name, kind:"face", solid, surfaceType, area, edgeLengthTotal, creatingFeature }(edgeLengthTotal= its boundary edges;surfaceType= the carrier-surface classification, e.g."Plane"/"Cylinder"/"Cone"/"Sphere"/"Torus"/"NURBS"), plus the carrier’s dimensions when it has them:radius+diameter(cylinder, sphere),halfAngleDeg(cone),majorRadius+minorRadius(torus). - Edge —
{ ok, name, kind:"edge", solid, length, creatingFeature }, pluscurveType("Circle"/"Arc"),radius,diameterand an arc’ssweepDegwhen the edge lies on a circle.
{ ok:false, name, message } for an empty/unknown name, a non-resident
solid, or a kernel measurement failure.
The real solid/face/edge MEASUREMENT is routed to the HistoryRunner (so
the warm-registry runner answers it, never the potentially-cold main side)
and CACHED here keyed by name — fired once per selection, served from the
cache every subsequent frame. For the synchronous
InlineRunner the submit → pump_queries
resolves same-call, so this returns the merged JSON immediately and stays
byte-identical to the pre-seam in-process result; a background
ThreadRunner returns a pending placeholder
for the frame(s) until its reply lands (drained by pump_queries). The cache
is invalidated on any geometry change (apply_run_output) or metadata edit
(set_metadata_attribute).
Sourcepub fn pump_queries(&mut self)
pub fn pump_queries(&mut self)
Drain every completed measurement reply from the runner and fold it into the
name-keyed info cache — the query counterpart of EngineState::pump. Called
once per frame from pump AND synchronously from
Self::object_info_json (so the Inline runner resolves same-call). Each
reply is MERGED with the main-injected name + creatingFeature (from the
eager provenance) into the final object-info JSON.
Source§impl EngineState
impl EngineState
Sourcepub fn set_entity_visible(
&mut self,
solid: &str,
kind: EntityKind,
index: usize,
visible: bool,
) -> bool
pub fn set_entity_visible( &mut self, solid: &str, kind: EntityKind, index: usize, visible: bool, ) -> bool
Show/hide ONE face/edge/vertex of a solid, by its index in the solid’s face/edge/vertex list — the same index the Scene tree enumerates. Marks dirty. Returns false if the solid is unknown.
Sourcepub fn set_group_visible(
&mut self,
solid: &str,
kind: EntityKind,
visible: bool,
) -> bool
pub fn set_group_visible( &mut self, solid: &str, kind: EntityKind, visible: bool, ) -> bool
Show/hide a WHOLE group (all faces / all edges / all vertices of a solid). Marks dirty. Returns false if the solid is unknown.
Sourcepub fn entity_visible(
&self,
solid: &str,
kind: EntityKind,
index: usize,
) -> Option<bool>
pub fn entity_visible( &self, solid: &str, kind: EntityKind, index: usize, ) -> Option<bool>
Whether entity index of kind on solid is shown (None if unknown).
Sourcepub fn group_visibility(
&self,
solid: &str,
kind: EntityKind,
) -> Option<GroupState>
pub fn group_visibility( &self, solid: &str, kind: EntityKind, ) -> Option<GroupState>
The group tristate for solid’s kind (None if the solid is unknown).
Sourcepub fn scene_visibility_json(&self) -> String
pub fn scene_visibility_json(&self) -> String
Per-entity + group visibility as JSON — the readout the headed verifier
asserts against (a companion to
scene_entities_json, which lists the
entities but not their per-entity visibility):
[{name, visible, faces:{group, states:[bool;n]}, edges:{…}, vertices:{…}}]
where states[i] is entity i’s visibility and group is
"all"|"partial"|"none".
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for EngineState
impl !RefUnwindSafe for EngineState
impl !Send for EngineState
impl !Sync for EngineState
impl !UnwindSafe for EngineState
impl Forget for EngineState
impl Unpin for EngineState
impl UnsafeUnpin for EngineState
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
Source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
Source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.Source§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.Source§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.Source§impl<T> Pointable for T
impl<T> Pointable for T
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read moreSource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read moreSource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read moreSource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read moreSource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.Source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.Source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.Source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.Source§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.