STEP export: shelled revolved bodies export instead of panicking (#1496)
A scale across a revolution's axis keeps the face a surface of revolution and is written as one; any other refusal from the writer is an export error, not a panic.
This commit is contained in:
1 parent
d188eea1f4
commit
63accec16e
5 files changed
+161
-13
No files matched your search
Vendored
+6
@@ -53,6 +53,12 @@ Changes:
|
||||
mirrored revolutions (ISO 10303-42 parameterises them by angle then profile, so their normal
|
||||
is the opposite of truck's; a mirroring transform reverses it again), and the modeling-surface
|
||||
wrapper passes the revolution's sense through instead of always `true`.
|
||||
- `out/geometry.rs`: a surface of revolution under a transform that commutes with turning about
|
||||
its axis (a scale across the axis that differs from the scale along it, as a shell or offset
|
||||
makes of a revolved face) is written as the transformed profile revolved about the
|
||||
transformed axis. Only uniform scales were taken. Other transforms are still refused: the
|
||||
writer stops with a formatting error, which SolidCraft's `step.rs` now reports as an export
|
||||
error (`to_string` panicked on it).
|
||||
- `lib.rs`: compiler warnings no longer fail the build. Example and test targets are dropped
|
||||
(their sources are not vendored).
|
||||
|
||||
|
||||
+32
-12
@@ -748,22 +748,42 @@ impl<C> StepSurface for RevolutedCurve<C> {
|
||||
impl<C> DisplayByStep for Processor<RevolutedCurve<C>, Matrix4>
|
||||
where C: StepLength + Transformed<Matrix4> + DisplayByStep
|
||||
{
|
||||
// SolidCraft: a transform that commutes with turning about the axis keeps the surface one of
|
||||
// revolution: the transformed profile revolved about the transformed axis. That holds for
|
||||
// uniform scales (the only case taken before) and also for a scale across the axis that
|
||||
// differs from the scale along it, which is how a shell or an offset moves a revolved
|
||||
// cylinder or cone face. Any other transform is still refused.
|
||||
fn fmt(&self, idx: usize, f: &mut Formatter<'_>) -> Result {
|
||||
let surface = self.entity();
|
||||
let transform = self.transform();
|
||||
let (k, a, _) = match transform.iwasawa_decomposition() {
|
||||
Some(x) => x,
|
||||
None => {
|
||||
f.write_str("Transform is not regular")?;
|
||||
return ERR;
|
||||
}
|
||||
};
|
||||
if !a[0][0].near(&a[1][1]) || !a[1][1].near(&a[2][2]) {
|
||||
f.write_str("Transform contains non-uniform scale.")?;
|
||||
let transform = *self.transform();
|
||||
if transform.determinant().so_small() {
|
||||
f.write_str("Transform is not regular")?;
|
||||
return ERR;
|
||||
}
|
||||
let curve = surface.entity_curve().transformed(*transform);
|
||||
let axis = k.transform_vector(surface.axis());
|
||||
let a = surface.axis().normalize();
|
||||
let la = transform.transform_vector(a);
|
||||
if la.so_small() {
|
||||
f.write_str("Transform is not regular")?;
|
||||
return ERR;
|
||||
}
|
||||
let axis = la.normalize();
|
||||
// Two directions across the axis, and their images.
|
||||
let seed = if a.x.abs() < 0.9 { Vector3::unit_x() } else { Vector3::unit_y() };
|
||||
let u = (seed - a * a.dot(seed)).normalize();
|
||||
let v = a.cross(u);
|
||||
let (lu, lv) = (transform.transform_vector(u), transform.transform_vector(v));
|
||||
let s = lu.magnitude();
|
||||
// Across the axis: a similarity onto the plane across the image axis.
|
||||
let commutes = !s.so_small()
|
||||
&& (lu.dot(axis) / s).so_small()
|
||||
&& (lv.dot(axis) / s).so_small()
|
||||
&& (lu.dot(lv) / (s * s)).so_small()
|
||||
&& (lv.magnitude() / s).near(&1.0);
|
||||
if !commutes {
|
||||
f.write_str("Transform does not keep the surface one of revolution.")?;
|
||||
return ERR;
|
||||
}
|
||||
let curve = surface.entity_curve().transformed(transform);
|
||||
let origin = transform.transform_point(surface.origin());
|
||||
let surface = RevolutedCurve::by_revolution(curve, origin, axis);
|
||||
DisplayByStep::fmt(&surface, idx, f)
|
||||
|
||||
Reference in new issue
Block a user