Add persistent sketch-constraint system (ocs_gcs port) and named-parameters handoff docs

Ports FreeCAD's planegcs 2D geometric constraint solver to Rust as a new
crates/ocs_gcs workspace member, and wires it into the document/scene model
as a persistent SketchConstraintSet: Coincident, Horizontal/Vertical,
Parallel/Perpendicular, Equal, Tangent, Distance, Angle and Radius
constraints that re-solve live (including mid-drag, not just on release),
render glyphs and a DOF badge, flag conflicts with a one-click resolver
pill, and round-trip through save/load via an XRecord blob.

Also includes docs/command_reference.md (a statically generated reference
of every registered command and its prompt sequence) and
docs/named_parameters_design.md + docs/backlog.md, which hand off the next
queued feature (a named-parameter/expression table) and consolidate every
deliberate scope-down and open gap found along the way, so a fresh session
has a complete starting point.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Felix RiestraandClaude Sonnet 5 committed 2026-09-08 22:19:23 +02:00
1 parent a39c7b8f71
commit 63a74b19a9
63 files changed
+12193 -49

No files matched your search

+67
View File
@@ -125,6 +125,16 @@ impl StatusBar {
// Which pills the user has chosen to show on the bar.
config: &'a StatusBarConfig,
menu_data: StatusMenuData<'a>,
// Remaining degrees of freedom for the current sketch scope's
// persistent constraints (design doc §6.3) — `None` when the scope
// has no `SketchConstraintSet` yet (nothing constrained), so the
// badge stays invisible until it's actually relevant.
sketch_dof: Option<usize>,
// Number of redundant/conflicting constraints `solve_scope` flagged
// in the current sketch scope (design doc §6.4, stage 11) — 0 hides
// the pill entirely, so an ordinarily/fully-constrained drawing sees
// no new clutter.
sketch_conflicts: usize,
) -> Element<'a, Message> {
let StatusMenuData {
layout_names,
@@ -243,6 +253,44 @@ impl StatusBar {
.into(),
);
}
// Not a `StatusPill` (so not user-hideable yet): invisible until the
// current scope actually has a SketchConstraintSet, so a drawing
// that never uses parametric constraints sees no new clutter.
if let Some(dof) = sketch_dof {
let pill = if dof == 0 {
success_pill(crate::tf!("DOF: {dof}").into_owned())
} else {
status_pill(crate::tf!("DOF: {dof}").into_owned())
};
pills.push(
tip(
pill,
if dof == 0 {
t!("Fully constrained — no remaining degrees of freedom")
} else {
t!("Remaining degrees of freedom in the current sketch's persistent constraints")
},
)
.into(),
);
}
// Design doc §6.4 (stage 11): a bounded v1 of the guided conflict
// resolver — click removes one flagged constraint at a time. See
// `OpenCADStudio::resolve_one_sketch_conflict`'s doc comment for the
// full scope-down rationale versus the design doc's named-candidate,
// cyclable-preview panel.
if sketch_conflicts > 0 {
pills.push(
tip(
action_pill(
crate::tf!("⚠ {sketch_conflicts} conflicting").into_owned(),
Message::ResolveOneSketchConflict,
),
t!("One or more constraints in this sketch conflict or are redundant\nClick to remove one and re-solve"),
)
.into(),
);
}
if vis(StatusPill::Ortho) {
pills.push(
tip(
@@ -1034,6 +1082,25 @@ fn status_pill(label: impl Into<String>) -> Element<'static, Message> {
.into()
}
/// Like [`status_pill`], but with the theme's `success` accent — design doc
/// §6.3's "simple color-coded constraint state" cue: used for the DOF badge
/// when a sketch scope has reached zero remaining degrees of freedom, so
/// "fully constrained" is visible at a glance without opening anything.
fn success_pill(label: impl Into<String>) -> Element<'static, Message> {
container(text(label.into()).size(12))
.style(|theme: &Theme| {
let palette = theme.palette();
container::Style {
background: Some(Background::Color(palette.success.weak.color)),
text_color: Some(palette.success.weak.text),
border: Border { color: palette.success.base.color, width: 1.0, radius: 4.0.into() },
..Default::default()
}
})
.padding([4, 8])
.into()
}
// ── Scale popup button ────────────────────────────────────────────────────
/// Shared visual root for labelled status-bar menus (units, scale, …).