STEP export: Fusion round-trip fixes (sense, analytic surfaces, horn torus)
- Surfaces of revolution follow ISO 10303-42 strictly in reader and writer: the normal is d/d(angle) x d/d(profile), the opposite of truck's revolution, as Fusion reads it (fixes Fusion inverting fillet sphere corners and the dimple). step_orientation_errors flags faces whose loop runs clockwise round their normal; engine, oracle and kernel round trips assert it. - Revolved faces with analytic profiles are written as native PLANE, CYLINDRICAL/CONICAL/SPHERICAL/TOROIDAL surfaces, and the pieces truck splits a revolution into are merged back into one face per surface (with a seam edge for full turns), so face counts match other systems. - A horn torus (tight sweep: tube touching its axis) is written as one rational B-spline face whose loop passes the pole twice, with truck's zero-length pole edges collapsed, instead of a degenerate surface of revolution; the reader starts such figure-eight loops off the pole (Fusion's own part 50 now imports with the right volume). 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
178fc47ed7
commit
7382ebd6e8
12 files changed
+958
-85
No files matched your search
@@ -133,7 +133,7 @@ pub(crate) fn frame(cx: &Ctx, id: u64) -> R<Frame> {
|
||||
}
|
||||
|
||||
/// AXIS1_PLACEMENT: origin and unit axis.
|
||||
fn axis1(cx: &Ctx, id: u64) -> R<(mt::Point3, mt::Vector3)> {
|
||||
pub(crate) fn axis1(cx: &Ctx, id: u64) -> R<(mt::Point3, mt::Vector3)> {
|
||||
let e = entity(cx, id)?;
|
||||
let p = e.params();
|
||||
let o = point(cx, p.get(1).and_then(Param::as_ref_id).ok_or("axis without location")?)?;
|
||||
@@ -875,8 +875,10 @@ pub(crate) fn surface(cx: &Ctx, id: u64, extent: &[mt::Point3], seam: &[mt::Poin
|
||||
CurveGeo::Line { p, d } => revolved_line(*p, *d, o, axis, extent)?,
|
||||
_ => bounded_curve(&g, extent)?,
|
||||
};
|
||||
// Reversed sense: turn the other way round the axis.
|
||||
Ok(revolved(profile, o, axis * sign))
|
||||
// ISO 10303-42 parameterises a surface of revolution by the angle u and the profile
|
||||
// v, so its normal is ∂S/∂angle × ∂S/∂profile: the opposite of truck's revolution
|
||||
// (profile first). Fusion reads it this way. Reversed sense turns it back.
|
||||
Ok(revolved(profile, o, -axis * sign))
|
||||
}
|
||||
"SURFACE_OF_LINEAR_EXTRUSION" => {
|
||||
let g = curve(cx, p.get(1).and_then(Param::as_ref_id).ok_or("extrusion without profile")?, depth + 1)?;
|
||||
|
||||
Reference in new issue
Block a user