Prepare 0.2.0 usability release and refresh desktop demo

This commit is contained in:
bherbruck committed 2026-10-11 10:55:55 -04:00
1 parent a094fa46b5
commit ab05b24dee
54 files changed
+4888 -234

No files matched your search

+9 -1
View File
@@ -664,7 +664,15 @@ pub(super) fn paste(
}
}
}
if (ma.volume - mb.volume).abs() > 1e-5 * (1.0 + ma.volume.abs())
// Meshes of the same current circular section can have different
// chord-volume biases after STEP. Only independently certified current
// sections may replace that volume comparison; shape mismatches still
// refuse even when their volumes happen to agree.
let volume_matches = match solvecraft_kernel::certified_prism_equivalent(&a, &b)? {
Some(same) => same,
None => (ma.volume - mb.volume).abs() <= 1e-5 * (1.0 + ma.volume.abs()),
};
if !volume_matches
|| (ma.area - mb.area).abs() > 1e-5 * (1.0 + ma.area.abs())
|| ma.centroid.dist(mb.centroid) > tolerance
|| ma.bbox.min.dist(mb.bbox.min) > tolerance
@@ -519,3 +519,36 @@ fn frozen_bore_boundary_copy_preserves_stock_void_and_reopen() {
check(&s);
check(&Session::new(solvecraft_doc::Document::from_json(&s.doc.to_json()).unwrap()));
}
#[test]
fn frozen_r6_bore_copy_uses_current_geometry_despite_mesh_measure_bias() {
use solvecraft_geom::Vec3;
let mut s = Session::default();
run(&mut s, "solid.box", json!({"length":20,"width":20,"height":10,"body_name":"Drilled"}));
run(&mut s, "solid.cylinder", json!({"base":[10,10,0],"radius":6,"height":10,"operation":"cut"}));
let source = s.model.state().body("Drilled").unwrap().body.clone();
let original = solvecraft_kernel::step_export(&[&source], "source").unwrap();
let created = run(&mut s, "component.from_bodies", json!({"bodies":["Drilled"]}));
let part = created["components"][0]["component"].as_u64().unwrap();
let before = s.doc.to_json();
let copied = copy(&mut s, part)["component"].as_u64().unwrap();
let check = |session: &Session| {
let state = session.model.state();
let body = state.bodies.iter().find(|b| session.doc.model_body_component(b) == copied).unwrap();
assert_eq!(solvecraft_kernel::certified_prism_equivalent(&source, &body.body).unwrap(), Some(true));
let mesh = body.body.tessellate(1e-3).unwrap();
for (point, material) in
[(Vec3::new(3., 10., 5.), true), (Vec3::new(5., 10., 5.), false), (Vec3::new(10., 10., 5.), false), (Vec3::new(18., 10., 5.), true)]
{
assert_eq!(mesh.contains(point), material, "{point:?}");
}
let original_body = state.body("Drilled").unwrap();
assert_eq!(solvecraft_kernel::step_export(&[&original_body.body], "source").unwrap(), original);
};
check(&s);
check(&Session::new(solvecraft_doc::Document::from_json(&s.doc.to_json()).unwrap()));
run(&mut s, "edit.undo", json!({}));
assert_eq!(s.doc.to_json(), before);
run(&mut s, "edit.redo", json!({}));
check(&s);
}