forked from 1b-agent/opencadstudio-upstream
Merge pull request #1248 from kevin9327/fix/dimension-rotate-mirror-off-world-z
This commit is contained in:
commit
247e48bfe8
1 file changed
+86
-12
+86
-12
@@ -882,12 +882,21 @@ fn apply_transform(dim: &mut Dimension, t: &EntityTransform) {
|
|||||||
d.rotation += *angle_rad;
|
d.rotation += *angle_rad;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
crate::scene::view::transform::apply_standard_transform(
|
// acadrust only moves a non-ordinate dimension by where the
|
||||||
dim,
|
// origin goes, so turn it through the affine path below.
|
||||||
*center,
|
use acadrust::types::Transform;
|
||||||
*axis,
|
let unit = axis.normalize_or(DVec3::Z);
|
||||||
|
let rotation = Transform::from_translation(Vector3::new(
|
||||||
|
-center.x, -center.y, -center.z,
|
||||||
|
))
|
||||||
|
.then(&Transform::from_rotation(
|
||||||
|
Vector3::new(unit.x, unit.y, unit.z),
|
||||||
*angle_rad,
|
*angle_rad,
|
||||||
);
|
))
|
||||||
|
.then(&Transform::from_translation(Vector3::new(
|
||||||
|
center.x, center.y, center.z,
|
||||||
|
)));
|
||||||
|
apply_transform(dim, &EntityTransform::Affine(rotation));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EntityTransform::Scale { center, factor } => {
|
EntityTransform::Scale { center, factor } => {
|
||||||
@@ -903,14 +912,13 @@ fn apply_transform(dim: &mut Dimension, t: &EntityTransform) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
acadrust::Entity::apply_transform(
|
// Same as ROTATE: reflect points, plane and angles together.
|
||||||
dim,
|
let reflection = crate::scene::view::transform::reflection_about_working_line(
|
||||||
&crate::scene::view::transform::reflection_about_working_line(
|
*p1,
|
||||||
*p1,
|
*p2,
|
||||||
*p2,
|
*working_normal,
|
||||||
*working_normal,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
|
apply_transform(dim, &EntityTransform::Affine(reflection));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EntityTransform::Affine(transform) => {
|
EntityTransform::Affine(transform) => {
|
||||||
@@ -7743,4 +7751,70 @@ mod linear_transform_tests {
|
|||||||
assert_eq!(rotation(&dim), 0.0);
|
assert_eq!(rotation(&dim), 0.0);
|
||||||
assert_measures_ten(&dim);
|
assert_measures_ten(&dim);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The point the dimension line passes through.
|
||||||
|
fn definition_point(dim: &Dimension) -> DVec3 {
|
||||||
|
let p = dimension_definition_point(dim);
|
||||||
|
DVec3::new(p.x, p.y, p.z)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn assert_near(actual: DVec3, expected: DVec3, what: &str) {
|
||||||
|
assert!(
|
||||||
|
actual.abs_diff_eq(expected, 1e-9),
|
||||||
|
"{what}: expected {expected:?}, got {actual:?}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ROTATE about an axis off world Z (a working plane other than world XY)
|
||||||
|
/// turns the dimension like the geometry it measures. It used to only move
|
||||||
|
/// by where the origin went, leaving the dimension line and plane unturned.
|
||||||
|
#[test]
|
||||||
|
fn rotate_off_world_z_turns_the_dimension() {
|
||||||
|
let center = DVec3::new(0.0, 10.0, 0.0);
|
||||||
|
let turn = glam::DQuat::from_axis_angle(DVec3::X, FRAC_PI_2);
|
||||||
|
let mut dim = horizontal();
|
||||||
|
apply_transform(
|
||||||
|
&mut dim,
|
||||||
|
&EntityTransform::Rotate {
|
||||||
|
center,
|
||||||
|
axis: DVec3::X,
|
||||||
|
angle_rad: FRAC_PI_2,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
assert_near(
|
||||||
|
definition_point(&dim),
|
||||||
|
turn * (DVec3::new(0.0, 5.0, 0.0) - center) + center,
|
||||||
|
"definition point",
|
||||||
|
);
|
||||||
|
let normal = dim.base().normal;
|
||||||
|
assert_near(
|
||||||
|
DVec3::new(normal.x, normal.y, normal.z),
|
||||||
|
turn * DVec3::Z,
|
||||||
|
"normal",
|
||||||
|
);
|
||||||
|
assert_measures_ten(&dim);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// MIRROR in a working plane off world Z reflects the dimension through
|
||||||
|
/// the mirror plane instead of only moving it.
|
||||||
|
#[test]
|
||||||
|
fn mirror_off_world_z_reflects_the_dimension() {
|
||||||
|
// Working plane YZ; the line runs along Z at y = 2, so the mirror
|
||||||
|
// plane is y = 2.
|
||||||
|
let mut dim = horizontal();
|
||||||
|
apply_transform(
|
||||||
|
&mut dim,
|
||||||
|
&EntityTransform::Mirror {
|
||||||
|
p1: DVec3::new(0.0, 2.0, 0.0),
|
||||||
|
p2: DVec3::new(0.0, 2.0, 1.0),
|
||||||
|
working_normal: DVec3::X,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
assert_near(
|
||||||
|
definition_point(&dim),
|
||||||
|
DVec3::new(0.0, -1.0, 0.0),
|
||||||
|
"definition point",
|
||||||
|
);
|
||||||
|
assert_measures_ten(&dim);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user