Sketch drawing: clicking a model vertex projects it into the sketch (linked point) and draws from it, as Fusion does ("vertex:x,y,z" point arguments)
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
8c88fb8d2d
commit
13b72bb011
3 files changed
+19
-2
No files matched your search
@@ -329,13 +329,23 @@ fn auto_project(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
/// Point arguments that snap to model geometry while drawing, rewritten to sketch point ids:
|
||||
/// `{"vertex": [x,y,z]}` projects the vertex (a linked point); `{"on_edge": [x,y,z]}` projects
|
||||
/// the edge and makes a free point on it (coincident with the projection); `"mid:<line>"`
|
||||
/// makes a point held at the line's midpoint. Everything else is left as it is. The links are added to the active sketch in the session's document.
|
||||
/// makes a point held at the line's midpoint (and `"vertex:x,y,z"` is the vertex form). Everything
|
||||
/// else is left as it is. The links are added to the active sketch in the session's document.
|
||||
pub(super) fn snap_points(s: &mut Session, p: &Value, cmd: &str) -> Result<Value> {
|
||||
let Some(id) = s.active_sketch else { return Ok(p.clone()) };
|
||||
let mut out = p.clone();
|
||||
let mut doc: Option<(Document, Sketch)> = None;
|
||||
let fix = |v: &mut Value, s: &Session, doc: &mut Option<(Document, Sketch)>| -> Result<()> {
|
||||
let (vertex, edge) = (v.get("vertex").and_then(vec3), v.get("on_edge").and_then(vec3));
|
||||
// String forms from interactive snapping: "vertex:x,y,z" and "mid:<line>".
|
||||
let vertex = vertex.or_else(|| {
|
||||
let t = v.as_str()?.strip_prefix("vertex:")?;
|
||||
let n: Vec<f64> = t.split(',').filter_map(|x| x.trim().parse().ok()).collect();
|
||||
match n[..] {
|
||||
[x, y, z] if x.is_finite() && y.is_finite() && z.is_finite() => Some(Vec3::new(x, y, z)),
|
||||
_ => None,
|
||||
}
|
||||
});
|
||||
let mid = v.as_str().and_then(|x| x.strip_prefix("mid:")).map(str::to_string);
|
||||
if vertex.is_none() && edge.is_none() && mid.is_none() {
|
||||
return Ok(());
|
||||
|
||||
@@ -181,7 +181,7 @@ fn drawing_on_a_model_vertex_projects_it() {
|
||||
let mut s = Session::default();
|
||||
box_part(&mut s);
|
||||
run(&mut s, "SketchCreate", json!({"plane": "XY"}));
|
||||
let r = run(&mut s, "DrawPolyline", json!({"points": [{"vertex": [40, 30, 20]}, [60, 45]]}));
|
||||
let r = run(&mut s, "DrawPolyline", json!({"points": ["vertex:40,30,20", [60, 45]]}));
|
||||
let l = ids(&r["curves"])[0].clone();
|
||||
let si = inspect(&mut s);
|
||||
let start = si["curves"].as_array().unwrap().iter().find(|c| c["id"] == l).unwrap()["start"].clone();
|
||||
|
||||
@@ -40,6 +40,13 @@ pub fn refine_snap(
|
||||
let (a, b) = (proj.to_screen(plane.to_world(lp))?, proj.to_screen(plane.to_world(lp + Vec2::X))?);
|
||||
let px = 1.0 / (a.distance(b) as f64).max(1e-9);
|
||||
let tol = 7.0 * px;
|
||||
// A model vertex under the cursor: drawing on it projects it into the sketch.
|
||||
for h in pick(app, proj, a) {
|
||||
if let Hit::Vertex { point, .. } = h {
|
||||
SNAP.with(|s| *s.borrow_mut() = Some(("Pt", plane.to_local(point))));
|
||||
return Some((plane.to_local(point), Some(format!("vertex:{},{},{}", point.x, point.y, point.z))));
|
||||
}
|
||||
}
|
||||
let mut best: Option<(f64, &'static str, Vec2)> = None;
|
||||
let mut mid_of: Option<String> = None;
|
||||
for (i, c) in sk.curves.iter().enumerate() {
|
||||
|
||||
Reference in new issue
Block a user