Joint dialog after the engine's mating default: the dialog's Flip is the command's flip (no double flip with 4c3a5d9); Appearance dialog on the new appearance model; AppearanceCommand takes a colour with any name (the dialog's palette names)
Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
This commit is contained in:
1 parent
2c383460e9
commit
6653db806e
4 files changed
+19
-11
No files matched your search
@@ -303,6 +303,14 @@ fn appearance(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
use solvecraft_doc::appearance::{FaceLook, Look, library};
|
||||
let cmd = "AppearanceCommand";
|
||||
let look: Option<Look> = match (str_(p, "appearance"), p.get("color")) {
|
||||
// A colour with a name: that colour, called that (a name not in the library is fine).
|
||||
(Some(n), Some(v)) if !v.is_null() => {
|
||||
let c = color_param(v).ok_or_else(|| bad(cmd, "`color` must be \"#rrggbb\" or [r, g, b] with values 0–255"))?;
|
||||
let o = p.get("opacity").and_then(Value::as_f64).filter(|x| x.is_finite()).unwrap_or(1.0);
|
||||
let mut l = Look::custom(c, o);
|
||||
l.name = n.chars().take(128).collect();
|
||||
Some(l)
|
||||
}
|
||||
(Some(n), _) => {
|
||||
let mut l = library(n).ok_or_else(|| bad(cmd, format!("no appearance `{n}` in the library (appearance.library)")))?;
|
||||
if let Some(o) = p.get("opacity").and_then(Value::as_f64).filter(|x| x.is_finite()) {
|
||||
|
||||
@@ -177,10 +177,10 @@ fn in_design(app: &mut SolveApp) -> Vec<([u8; 3], usize)> {
|
||||
.collect();
|
||||
}
|
||||
let mut out: Vec<([u8; 3], usize)> = Vec::new();
|
||||
for c in app.session.doc.appearances.values() {
|
||||
match out.iter_mut().find(|(x, _)| x == c) {
|
||||
for c in app.session.doc.appearances.bodies.values().map(|l| l.color) {
|
||||
match out.iter_mut().find(|(x, _)| *x == c) {
|
||||
Some(e) => e.1 += 1,
|
||||
None => out.push((*c, 1)),
|
||||
None => out.push((c, 1)),
|
||||
}
|
||||
}
|
||||
out
|
||||
@@ -391,7 +391,7 @@ mod tests {
|
||||
for (id, p) in c {
|
||||
a.run(&id, p).unwrap();
|
||||
}
|
||||
assert_eq!(a.session.doc.appearances.get("Body2"), Some(&[196, 40, 36]));
|
||||
assert_eq!(a.session.doc.appearances.bodies.get("Body2").map(|l| l.color), Some([196, 40, 36]));
|
||||
assert_eq!(in_design(&mut a), vec![([196, 40, 36], 2)]);
|
||||
}
|
||||
|
||||
|
||||
@@ -196,7 +196,7 @@ pub fn edit_joint(app: &SolveApp, id: u64) -> Option<Dialog> {
|
||||
let mut f = JointForm::new(false);
|
||||
f.editing = Some(id);
|
||||
f.kind = TYPES.iter().position(|t| JointKind::parse(t) == Some(j.kind)).unwrap_or(0);
|
||||
f.flip = !j.flip;
|
||||
f.flip = j.flip;
|
||||
f.angle = num(j.angle.to_degrees(), "deg");
|
||||
f.offset[2] = num(j.offset, "mm");
|
||||
f.fit_limits();
|
||||
@@ -657,7 +657,7 @@ pub fn commands(app: &SolveApp, k: &Asm, inputs: &[SelInput]) -> Result<Vec<(Str
|
||||
let limits: Vec<Value> =
|
||||
f.limits.iter().take(jk.dofs().len()).map(|(on, lo, hi)| if *on { json!([lo, hi]) } else { Value::Null }).collect();
|
||||
if let Some(id) = f.editing {
|
||||
let mut out = cmd("joint.edit", json!({"joint": id, "type": kind, "flip": !f.flip, "offset": f.offset[2], "angle": f.angle}));
|
||||
let mut out = cmd("joint.edit", json!({"joint": id, "type": kind, "flip": f.flip, "offset": f.offset[2], "angle": f.angle}));
|
||||
for (i, l) in limits.iter().enumerate() {
|
||||
let p = match l.as_array() {
|
||||
Some(a) => json!({"joint": id, "index": i, "min": a.first(), "max": a.get(1)}),
|
||||
@@ -684,10 +684,10 @@ pub fn commands(app: &SolveApp, k: &Asm, inputs: &[SelInput]) -> Result<Vec<(Str
|
||||
}
|
||||
let (x, y) = (eval(&f.offset[0], ValueKind::Length)?, eval(&f.offset[1], ValueKind::Length)?);
|
||||
let a_param = if x.abs() > 1e-12 || y.abs() > 1e-12 { shifted(&a, x, y) } else { a.param };
|
||||
// Picked origins mate as in Fusion: B's z opposite A's (faces meet face to face, a pin
|
||||
// goes into its hole); the dialog's Flip turns B the other way. The command's `flip`
|
||||
// turns B over from frames that coincide.
|
||||
let p = json!({"type": kind, "a": a_param, "b": b.param, "flip": !f.flip, "offset": f.offset[2], "angle": f.angle, "limits": limits});
|
||||
// Picked origins mate as in Fusion (the engine's default: B's z opposite A's, faces
|
||||
// meet face to face, a pin goes into its hole); the dialog's Flip is the command's
|
||||
// `flip`, which turns B the other way.
|
||||
let p = json!({"type": kind, "a": a_param, "b": b.param, "flip": f.flip, "offset": f.offset[2], "angle": f.angle, "limits": limits});
|
||||
cmd("JointAssembleCmdNew", p)
|
||||
}
|
||||
Asm::JointOrigin { name, .. } => {
|
||||
|
||||
@@ -217,7 +217,7 @@ fn face_snaps_mate_face_to_face() {
|
||||
d.pick(&app.session, face_sel(&app.session, Vec3::new(10.0, 10.0, 10.0)).unwrap());
|
||||
d.pick(&app.session, face_sel(&app.session, Vec3::new(40.0, 10.0, 10.0)).unwrap());
|
||||
let c = apply_commands(&app, &d).unwrap();
|
||||
assert_eq!(c[0].1["flip"], true, "the mate turns B over");
|
||||
assert_eq!(c[0].1["flip"], false, "mating is the engine's default; no flip");
|
||||
for (id, p) in c {
|
||||
app.run(&id, p).unwrap();
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user