mirror of
https://github.com/bherbruck/solidcraft.git
synced 2026-11-08 13:01:52 +00:00
dc38349cbf
* Kernel: the B-rep record and the native body file come from solidcore-record
SolidCraft's portable B-rep record (`solidcraft_geom::brep`: brep.rs, topology, history,
envelope, part, curve2) and the native body file (`solidcraft_kernel::native`: the tagged binary
codec and the container) move to solidcore's `solidcore-record` crate: geometry as data, with
structural validation and no maths (solidcore's docs/layers.md, stage 1). Every caller uses
`solidcore_record::brep` and `solidcore_record::native`; the old copies are deleted.
What computes from coordinates stays with the kernel, in geom's `brep`:
- `brep::check`: the record's geometric checks (orthonormal frames, non-degenerate planes,
unit revolution axes, non-singular placements). `check::validate` and
`check::validate_built` are the record's validation and these together, and every caller of
`Brep::validate` uses them, so what is accepted is unchanged;
- `brep::label`: a surface's natural ranges (a cone's apex), `curve_interval`,
`edge_curve_interval` and `form_turns`;
- `brep::pcurve::eval`: a pcurve's point;
- `geometry::check`, `placement::moved` and `split_edges` become functions on the record.
The kernel's native module keeps the conversion between a body and its saved record
(metadata.rs) and checks the decoded record's geometry. `native/analytic.rs`, which no module
declared, is deleted.
solidcore-record is pinned to its rev on solidcore's `layer-record` branch.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NvoxKMbMFSQU8tzRtoJhtT
* Geometry: Vec2, Vec3, Plane and the profile types come from solidcore-record
The plain data of vectors and points, sketch planes and planar profiles (`Seg2`, `Loop2`,
`Region2`) moves to `solidcore-record`, with its constants and component-wise operators only
(owner decision, solidcore layer split). Their geometry stays in geom as traits:
`Vec2Geom`, `Vec3Geom`, `PlaneGeom`, `Seg2Geom`, `Loop2Geom`, `Region2Geom`, `Seg2ArcFit`,
`Loop2ArcFit` and `Region2ArcFit`, in scope with `use solidcraft_geom::prelude::*`. Every caller
names the types from `solidcore_record`; geom no longer defines or re-exports them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NvoxKMbMFSQU8tzRtoJhtT
* Kernel: pin solidcore-record to solidcore main f5e8e9a29
solidcore-record is merged on solidcore main (tangency-labs/solidcore#2519); its crate there is
identical to the rev pinned before but for its clippy configuration. The lock is regenerated
against the merged rev.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NvoxKMbMFSQU8tzRtoJhtT
---------
Co-authored-by: jyviko <2501648+jyviko@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
54 lines
2.6 KiB
Rust
54 lines
2.6 KiB
Rust
//! Matched command timings and analytic cursor-distance error for the reported four-bar.
|
|
#[path = "../tests/support/four_bar.rs"]
|
|
mod four_bar;
|
|
use four_bar::Result;
|
|
use serde_json::json;
|
|
use solidcore_record::Vec2;
|
|
use solidcraft_sketch::profiling::capture;
|
|
use std::{io::Write, time::Instant};
|
|
|
|
fn main() -> Result<()> {
|
|
let mut args = std::env::args().skip(1);
|
|
let path = args.next().ok_or("usage: sketch_target_bench OUTPUT.json [REPEATS]")?;
|
|
let repeats: usize = args.next().map(|v| v.parse()).transpose()?.unwrap_or(10);
|
|
if !(1..=100).contains(&repeats) {
|
|
return Err("repeats must be in 1..100".into());
|
|
}
|
|
let mut cases = Vec::new();
|
|
for target in [Vec2::new(-10.0, 8.0), Vec2::new(-10.0, -8.0), Vec2::new(20.0, 20.0), Vec2::new(20.0, 0.0), Vec2::new(-8.0, 6.0)] {
|
|
for events in [1, 16] {
|
|
let mut samples = Vec::new();
|
|
for i in 0..repeats + 2 {
|
|
let mut s = four_bar::session()?;
|
|
let from = four_bar::point(&s, "crank.end")?;
|
|
let side = four_bar::branch(&s)?;
|
|
let start = Instant::now();
|
|
let (result, profile) = capture(|| -> Result<()> {
|
|
for k in 1..=events {
|
|
let q = from + (target - from) * (k as f64 / events as f64);
|
|
let at = four_bar::point(&s, "crank.end")?;
|
|
s.execute("sketch.drag", &json!({"entity":"crank.end","from":[at.x,at.y],"to":[q.x,q.y],"live":true}))?;
|
|
}
|
|
Ok(())
|
|
});
|
|
let elapsed_ns = start.elapsed().as_nanos().min(u64::MAX as u128) as u64;
|
|
result?;
|
|
let actual = four_bar::point(&s, "crank.end")?;
|
|
let error = four_bar::length_error(&s)?;
|
|
if error > 1e-6 || four_bar::branch(&s)? != side {
|
|
return Err("length or branch violation".into());
|
|
}
|
|
if i >= 2 {
|
|
samples.push(json!({"elapsed_ns":elapsed_ns,"actual":[actual.x,actual.y],"length_error":error,"cursor_distance":actual.dist(target),"nearest_error":actual.dist(target*(10.0/target.len())),"profile":profile}));
|
|
}
|
|
}
|
|
cases.push(json!({"target":[target.x,target.y],"events":events,"samples":samples}));
|
|
}
|
|
}
|
|
let mut out = std::io::BufWriter::new(std::fs::File::create(path)?);
|
|
serde_json::to_writer_pretty(&mut out, &json!({"schema":"solidcraft/sketch-target-bench/1","repeats":repeats,"warmup":2,"cases":cases}))?;
|
|
writeln!(out)?;
|
|
out.flush()?;
|
|
Ok(())
|
|
}
|