fix: apply point constraints to sketch preselection

This commit is contained in:
lillith committed 2026-10-11 20:52:48 +02:00
1 parent 9d7be3c292
commit cc2ee6a0f9
4 files changed
+136 -1

No files matched your search

+7
View File
@@ -545,6 +545,13 @@ impl SolveApp {
self.last_command = Some((spec.id.to_string(), spec.label.to_string()));
}
if let Some(mut t) = tools::Tool::for_command(id) {
if let Some(params) = tools::constraint_preselection(id, &self.session.selection) {
if self.run(id, params).is_ok() {
let _ = self.session.execute("select.clear", &json!({}));
self.set_status("Constraint applied", false);
}
return;
}
// Curve-pair constraints can consume an exact preselection. Leave ambiguous
// selections to the ordinary pick tool; never silently constrain a subset.
if matches!(
+35
View File
@@ -323,6 +323,41 @@ fn run_shape(app: &mut SolveApp, t: &Tool) -> Result<Vec<String>, String> {
Ok(result["curves"].as_array().into_iter().flatten().filter_map(|c| c.as_str().map(str::to_string)).collect())
}
/// Only consume a complete, unambiguous selection; command validation owns geometry.
pub(crate) fn constraint_preselection(command: &str, selection: &[solvecraft_engine::Sel]) -> Option<Value> {
use solvecraft_engine::Sel::{SketchCurve, SketchPoint};
match (command, selection) {
("sketch.constraint.coincident", [a, b]) => {
let entity = |s: &solvecraft_engine::Sel| match s {
SketchPoint { id } | SketchCurve { id } => Some(id.clone()),
_ => None,
};
let (a, b) = (entity(a)?, entity(b)?);
(a != b).then(|| json!({"a":a,"b":b}))
}
(
"sketch.constraint.midpoint",
[SketchPoint { id: point }, SketchCurve { id: line }] | [SketchCurve { id: line }, SketchPoint { id: point }],
) => Some(json!({"point":point,"line":line})),
("sketch.constraint.symmetry", [a, b, c]) => {
let mut points = Vec::new();
let mut lines = Vec::new();
for entity in [a, b, c] {
match entity {
SketchPoint { id } => points.push(id),
SketchCurve { id } => lines.push(id),
_ => return None,
}
}
match (points.as_slice(), lines.as_slice()) {
([a, b], [line]) if a != b => Some(json!({"a":a,"b":b,"line":line})),
_ => None,
}
}
_ => None,
}
}
fn run_pick(app: &mut SolveApp, t: &Tool) {
let k = &t.picks;
let params = match t.cmd {