Fix/Unfix on every sketch entity: points (Fix constraint) and lines, arcs, circles, ellipses, splines and conics (fixed curves hold their points and radius); ConstraintFix takes entities (fixes them all unless all are fixed); the toolbar button and the context menu act on the whole selection; fixed points never move when dragged or solved; projected geometry counts as fixed; fixed geometry is drawn green; sketch.inspect reports fixed
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
This commit is contained in:
1 parent
b457b6b7b6
commit
5b8816aa7d
11 files changed
+252
-35
No files matched your search
@@ -586,11 +586,8 @@ pub fn run_item(app: &mut SolveApp, item: &Item, at: Pos2) {
|
||||
"ui.unsection" => drop(app.run("FusionHalfSectionViewCommand", json!({"clear": true}))),
|
||||
"ui.fit" => app.animate_view("fit"),
|
||||
"ui.home" => app.animate_view("home"),
|
||||
"ui.fix" => {
|
||||
for e in strs(&p, "entities") {
|
||||
let _ = app.run("ConstraintFix", json!({ "entity": e }));
|
||||
}
|
||||
}
|
||||
// One command for the whole selection: all fixed unless all already are.
|
||||
"ui.fix" => drop(app.run("ConstraintFix", json!({ "entities": strs(&p, "entities") }))),
|
||||
"ui.editSketch" => {
|
||||
if let Some(id) = id_of(&p, "sketch") {
|
||||
app.edit_sketch(id);
|
||||
|
||||
@@ -295,6 +295,22 @@ impl SolveApp {
|
||||
let edges = self.session.selection.iter().any(|s| matches!(s, solvecraft_engine::Sel::Edge { .. }));
|
||||
return self.start(if edges { "FusionFilletEdgesCommand" } else { "Extrude" });
|
||||
}
|
||||
// Fix/Unfix: the selected sketch points and curves change at once, otherwise pick them.
|
||||
if id == "ConstraintFix" {
|
||||
let ents: Vec<String> = self
|
||||
.session
|
||||
.selection
|
||||
.iter()
|
||||
.filter_map(|s| match s {
|
||||
solvecraft_engine::Sel::SketchCurve { id } | solvecraft_engine::Sel::SketchPoint { id } => Some(id.clone()),
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
if !ents.is_empty() {
|
||||
let _ = self.run(id, json!({ "entities": ents }));
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Construction toggle: selected sketch curves switch at once, otherwise pick them.
|
||||
if id == "sketch.construction" {
|
||||
let curves: Vec<String> = self
|
||||
|
||||
@@ -178,6 +178,8 @@ fn sketch_color(t: &Tokens, c: Rgb) -> [u8; 4] {
|
||||
c4(t.sketch)
|
||||
} else if c == colors::SKETCH_DONE || c == colors::SKETCH_FIXED {
|
||||
c4(t.sketch_fixed)
|
||||
} else if c == colors::SKETCH_LOCKED {
|
||||
c4(t.sketch_locked)
|
||||
} else {
|
||||
rgba(c)
|
||||
}
|
||||
@@ -1265,13 +1267,20 @@ fn overlays(app: &SolveApp, painter: &egui::Painter, proj: &Proj) {
|
||||
let Some(sid) = app.session.active_sketch else { return };
|
||||
let Some(ss) = st.sketch(sid) else { return };
|
||||
let sk = &ss.sketch;
|
||||
let locked = sk.locked_points();
|
||||
for (i, p) in sk.points.iter().enumerate() {
|
||||
if !solvecraft_engine::view::sketch_point_visible(sk, i) {
|
||||
continue;
|
||||
}
|
||||
let Some(sp) = proj.to_screen(ss.plane.to_world(p.pos)) else { continue };
|
||||
let det = ss.report.point_determined.get(i).copied().unwrap_or(false);
|
||||
let c = if det { t.sketch_point } else { t.sketch_point_free };
|
||||
let c = if p.link.is_none() && locked.get(i).copied().unwrap_or(false) {
|
||||
t.sketch_locked
|
||||
} else if det {
|
||||
t.sketch_point
|
||||
} else {
|
||||
t.sketch_point_free
|
||||
};
|
||||
if i == 0 {
|
||||
painter.circle(sp, 3.5, Color32::from_rgb(240, 200, 60), Stroke::new(1.0, t.body_edge));
|
||||
} else {
|
||||
|
||||
Reference in new issue
Block a user