Add 8 geometric constraint kinds and an opt-in DWG-native persistence toggle

New ConstraintKind variants — Concentric, CenterPoint, Colinear, Midpoint,
Fixed, PointOnCurve, EqualDistance, Symmetric — each built entirely from
existing ocs_gcs (FreeCAD planegcs) primitives, no new solver math needed.
build_constraint now returns Vec<Rc<dyn Constraint>> instead of
Option<Rc<...>>, generalizing the old Coincident-only "needs a second
system-level constraint" special case to every kind that needs one.
Wired into the ribbon (7 new buttons), a new point+pre-selected-entity
command for CenterPoint/Midpoint/PointOnCurve, a new 4-point command for
EqualDistance, and the existing DWG-native class-name mapping (all 8 reuse
the same generic "plain Geometrical node" path already built for
Coincident/Horizontal/etc.). Deliberately not modeled: Normal and
EqualCurvature, which for this app's Line/Circle-only entity model would
just be Perpendicular and Equal wearing different DWG class names.

Also makes DWG-native constraint persistence opt-in (Options > General,
off by default) rather than unconditional: a scope that doesn't yet have
the native graph is only given one when the setting is on, but a scope
that already has one — from an earlier save, or a file that came from
real AutoCAD — keeps getting it resynced regardless of the setting, so
toggling it off never freezes a stale graph in place.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
Felix RiestraandClaude Sonnet 5 committed 2026-09-09 19:38:31 +02:00
1 parent cf33a1d019
commit 31b5ef4ec3
18 files changed
+1076 -106

No files matched your search

+26
View File
@@ -1360,6 +1360,32 @@ pub enum CmdResult {
point_b: DVec3,
label: &'static str,
},
/// Add a persistent `CenterPoint`/`Midpoint`/`PointOnCurve` constraint
/// (`crate::modules::draw::constrain::point_on_entity`) between one
/// picked point and `target`, a whole entity selected before the tool
/// ran. Like `AddCoincidentConstraint`, the host resolves `point` via
/// `sketch_constraints::nearest_sketch_point` (a `CadCommand` has no
/// document access) and, for `CenterPoint` specifically, addresses
/// `target` via its center marker rather than as a whole entity — see
/// `ConstraintKind::CenterPoint`'s own doc comment for why it's the
/// same solve as `Coincident`/`Concentric` under a different DWG-native
/// class name.
AddPointOnEntityConstraint {
point: DVec3,
target: Handle,
kind: crate::scene::sketch_constraints::ConstraintKind,
label: &'static str,
},
/// Add a persistent `EqualDistance` constraint
/// (`crate::modules::draw::constrain::equal_distance`): the distance
/// between `points[0]`/`points[1]` equals the distance between
/// `points[2]`/`points[3]`. The host resolves each point via
/// `sketch_constraints::nearest_sketch_point`, same reasoning as
/// `AddCoincidentConstraint`.
AddEqualDistanceConstraint {
points: [DVec3; 4],
label: &'static str,
},
/// Attach one smart centre mark to a newly selected circular source.
ReassociateCenterMark {
target: Handle,