forked from 1b-agent/opencadstudio-upstream
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 <noreply@anthropic.com>
This commit is contained in:
1 parent
cf33a1d019
commit
31b5ef4ec3
18 files changed
+1076
-106
No files matched your search
@@ -2375,6 +2375,62 @@ impl OpenCADStudio {
|
||||
}
|
||||
}
|
||||
}
|
||||
CmdResult::AddPointOnEntityConstraint { point, target, kind, label } => {
|
||||
let scope = self.tabs[i].current_sketch_scope();
|
||||
let to_world = |p: glam::DVec3| acadrust::types::Vector3::new(p.x, p.y, p.z);
|
||||
let resolved = crate::scene::sketch_constraints::nearest_sketch_point(&self.tabs[i].scene.document, scope, to_world(point), Some(target));
|
||||
match resolved {
|
||||
Some(point_ref) => {
|
||||
use crate::scene::sketch_constraints::{ConstraintKind, SketchRef};
|
||||
// `CenterPoint` addresses its whole-entity side via
|
||||
// the center marker (same solve as Coincident /
|
||||
// Concentric — `ConstraintKind::CenterPoint`'s own
|
||||
// doc comment); `Midpoint`/`PointOnCurve` address it
|
||||
// as a whole entity.
|
||||
let target_ref =
|
||||
if kind == ConstraintKind::CenterPoint { SketchRef::center(target) } else { SketchRef::whole(target) };
|
||||
return self.apply_cmd_result(CmdResult::AddSketchConstraint {
|
||||
kind,
|
||||
refs: vec![point_ref, target_ref],
|
||||
driving_param: None,
|
||||
label,
|
||||
});
|
||||
}
|
||||
None => {
|
||||
self.command_line.push_error(
|
||||
"Pick didn't land on a point (endpoint, center, or vertex) — enable an Endpoint/Center object snap and try again.",
|
||||
);
|
||||
self.tabs[i].active_cmd = None;
|
||||
self.tabs[i].snap_result = None;
|
||||
}
|
||||
}
|
||||
}
|
||||
CmdResult::AddEqualDistanceConstraint { points, label } => {
|
||||
let scope = self.tabs[i].current_sketch_scope();
|
||||
let to_world = |p: glam::DVec3| acadrust::types::Vector3::new(p.x, p.y, p.z);
|
||||
let mut refs = Vec::with_capacity(4);
|
||||
for p in points {
|
||||
let Some(r) = crate::scene::sketch_constraints::nearest_sketch_point(&self.tabs[i].scene.document, scope, to_world(p), None)
|
||||
else {
|
||||
refs.clear();
|
||||
break;
|
||||
};
|
||||
refs.push(r);
|
||||
}
|
||||
if refs.len() == 4 {
|
||||
return self.apply_cmd_result(CmdResult::AddSketchConstraint {
|
||||
kind: crate::scene::sketch_constraints::ConstraintKind::EqualDistance,
|
||||
refs,
|
||||
driving_param: None,
|
||||
label,
|
||||
});
|
||||
}
|
||||
self.command_line.push_error(
|
||||
"Equal Distance: a pick didn't land on a point (endpoint, center, or vertex) — enable an Endpoint/Center object snap and try again.",
|
||||
);
|
||||
self.tabs[i].active_cmd = None;
|
||||
self.tabs[i].snap_result = None;
|
||||
}
|
||||
CmdResult::ReassociateCenterMark { target, source, point } => {
|
||||
if self.reject_locked_edit(i, target) {
|
||||
return Task::none();
|
||||
|
||||
Reference in new issue
Block a user