mirror of
https://github.com/bherbruck/solidcraft.git
synced 2026-11-03 18:45:55 +00:00
smlib: a horn or spindle torus face comes out as its NURBS form
The record's torus label is a ring torus (major > minor; the validator refuses any other). SMLib keeps horn and spindle tori: a half disc revolved about a line through its rim's end is a horn torus, its major radius a rounding below its minor, and the export wrote it as a torus label the record then refused (rig sweeps/4007, "ring torus radii"). Such a face is now its NURBS form, unlabelled, which is its geometry in any case. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -404,6 +404,13 @@ fn surfaces(flat: View, n_faces: usize) -> Res<Vec<(b::Surface, Option<b::Surfac
|
||||
};
|
||||
// A NURBS face's own block came first; a form follows the analytic face's canonical entry.
|
||||
let form = if kind != SURFACE_NURBS && forms.get(f) == Some(&1) { Some(next_nurbs(&mut nurbs_at)?) } else { None };
|
||||
// The record's torus is a ring torus. SMLib keeps horn and spindle tori too (a half disc
|
||||
// revolved about a line through its rim's end, its tube touching the axis, the major
|
||||
// radius a rounding below the minor): such a face is its NURBS form, unlabelled.
|
||||
let (surface, form) = match (surface, form) {
|
||||
(b::Surface::Torus { major_radius, minor_radius, .. }, Some(n)) if !(major_radius > minor_radius) => (n, None),
|
||||
other => other,
|
||||
};
|
||||
out.push((surface, form));
|
||||
}
|
||||
Ok(out)
|
||||
|
||||
@@ -49,6 +49,24 @@ fn revolutions_whole_and_partial() {
|
||||
assert_close(solid_volume(&b, "quarter ring"), PI / 2.0 * 7.0 * 4.0, 1e-6, "quarter ring");
|
||||
}
|
||||
|
||||
/// A half disc of radius 14 centred 14 off the axis, its rim outward, three quarters of a turn
|
||||
/// (rig sweeps/4007): a horn torus, which SMLib gives a major radius a rounding below its minor.
|
||||
/// The record's torus is a ring torus, so the face comes out as its NURBS form, unlabelled, and
|
||||
/// the record validates. Pappus: 3/4 turn · 2π (14 + 4·14 / 3π) · π 14² / 2.
|
||||
#[test]
|
||||
fn a_horn_torus_comes_out_as_its_nurbs() {
|
||||
let half = vec![
|
||||
Curve::Arc { center: [14.0, 0.0, 0.0], axis: [0.0, -1.0, 0.0], reference: [1.0, 0.0, 0.0], radius: 14.0, start: -PI / 2.0, end: PI / 2.0 },
|
||||
Curve::Line { start: [14.0, 0.0, 14.0], end: [14.0, 0.0, -14.0] },
|
||||
];
|
||||
let b = Brep::revolve(&half, [0.0; 3], [0.0, 0.0, 1.0], 1.5 * PI, true).unwrap();
|
||||
let want = 1.5 * PI * (14.0 + 56.0 / (3.0 * PI)) * PI * 98.0;
|
||||
assert_close(solid_volume(&b, "horn torus"), want, 1e-6, "horn torus");
|
||||
let record = b.to_native().unwrap();
|
||||
record.validate().unwrap();
|
||||
assert!(record.faces.iter().all(|f| !matches!(f.surface, solidcraft_geom::brep::Surface::Torus { .. })), "a torus label on a horn torus");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sweeps_lofts_and_screws() {
|
||||
let disc = [circle([5.0, 0.0, 0.0], 2.0)];
|
||||
|
||||
Reference in New Issue
Block a user