fix: delegate dimension transforms to cadcodec

This commit is contained in:
Hakan Seven committed 2026-09-14 14:22:10 +03:00
1 parent 247e48bfe8
commit 912b217d26
7 files changed
+17 -251

No files matched your search

Generated
+3 -3
View File
@@ -82,7 +82,7 @@ checksum = "366ffbaa4442f4684d91e2cd7c5ea7c4ed8add41959a31447066e279e432b618"
[[package]]
name = "acadrust"
version = "0.5.5"
source = "git+https://github.com/HakanSeven12/cadcodec.git?rev=65e61b631e6a8e33e47f906b8fbbdd8fb1388ee7#65e61b631e6a8e33e47f906b8fbbdd8fb1388ee7"
source = "git+https://github.com/HakanSeven12/cadcodec.git?rev=4d7b359b0571f9b6e0f85a62a21c67508722b83e#4d7b359b0571f9b6e0f85a62a21c67508722b83e"
dependencies = [
"ahash 0.8.12",
"anyhow",
@@ -908,7 +908,7 @@ checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04"
[[package]]
name = "cadkernel"
version = "0.1.0"
source = "git+https://github.com/HakanSeven12/cadkernel.git?rev=30bba0feaf998d1b308b05e82843468d3c6c1697#30bba0feaf998d1b308b05e82843468d3c6c1697"
source = "git+https://github.com/HakanSeven12/cadkernel.git?rev=ef843c6b151344d0fe03080ec80bcd975560a937#ef843c6b151344d0fe03080ec80bcd975560a937"
dependencies = [
"acadrust",
"cavalier_contours",
@@ -919,7 +919,7 @@ dependencies = [
[[package]]
name = "cadkernel-constraints"
version = "0.1.0"
source = "git+https://github.com/HakanSeven12/cadkernel.git?rev=30bba0feaf998d1b308b05e82843468d3c6c1697#30bba0feaf998d1b308b05e82843468d3c6c1697"
source = "git+https://github.com/HakanSeven12/cadkernel.git?rev=ef843c6b151344d0fe03080ec80bcd975560a937#ef843c6b151344d0fe03080ec80bcd975560a937"
dependencies = [
"nalgebra",
]
+3 -3
View File
@@ -31,9 +31,9 @@ glam = { version = "0.33", features = ["bytemuck"] }
rfd = "0.17"
clap = { version = "4", features = ["derive", "string"] }
env_logger = "0.11"
acadrust = { git = "https://github.com/HakanSeven12/cadcodec.git", rev = "65e61b631e6a8e33e47f906b8fbbdd8fb1388ee7", features = ["serde"] }
cadkernel = { git = "https://github.com/HakanSeven12/cadkernel.git", rev = "30bba0feaf998d1b308b05e82843468d3c6c1697", features = ["acis", "offset"] }
cadkernel-constraints = { git = "https://github.com/HakanSeven12/cadkernel.git", rev = "30bba0feaf998d1b308b05e82843468d3c6c1697" }
acadrust = { git = "https://github.com/HakanSeven12/cadcodec.git", rev = "4d7b359b0571f9b6e0f85a62a21c67508722b83e", features = ["serde"] }
cadkernel = { git = "https://github.com/HakanSeven12/cadkernel.git", rev = "ef843c6b151344d0fe03080ec80bcd975560a937", features = ["acis", "offset"] }
cadkernel-constraints = { git = "https://github.com/HakanSeven12/cadkernel.git", rev = "ef843c6b151344d0fe03080ec80bcd975560a937" }
dwg-thumbnailer = { path = "crates/dwg-thumbnailer" }
flate2 = "1"
image = { version = "0.25", default-features = false, features = ["png", "jpeg", "bmp", "tiff"] }
+2 -2
View File
@@ -14,7 +14,7 @@ serde = { version = "1", features = ["derive"] }
# Pulled in only by the `host` feature, which adds the `acadrust`-typed
# `HostApi` runtime surface. The default crate stays dependency-free so engine
# crates and external tooling can depend on the manifest/ribbon contract cheaply.
acadrust = { git = "https://github.com/HakanSeven12/cadcodec.git", rev = "65e61b631e6a8e33e47f906b8fbbdd8fb1388ee7", optional = true, features = ["serde"] }
acadrust = { git = "https://github.com/HakanSeven12/cadcodec.git", rev = "4d7b359b0571f9b6e0f85a62a21c67508722b83e", optional = true, features = ["serde"] }
# Runtime IPC and serialization (host feature only).
interprocess = { version = "2", optional = true }
@@ -38,7 +38,7 @@ serde_json = "1"
serde = { version = "1", features = ["derive"] }
cargo-lock = "11"
# acadrust is scanned at build time to generate the embedded type registry.
acadrust = { git = "https://github.com/HakanSeven12/cadcodec.git", rev = "65e61b631e6a8e33e47f906b8fbbdd8fb1388ee7", features = ["serde"] }
acadrust = { git = "https://github.com/HakanSeven12/cadcodec.git", rev = "4d7b359b0571f9b6e0f85a62a21c67508722b83e", features = ["serde"] }
[dev-dependencies]
serde_json = "1"
+1 -1
View File
@@ -8,7 +8,7 @@ publish = false
crate-type = ["cdylib"]
[dependencies]
acadrust = { git = "https://github.com/HakanSeven12/cadcodec.git", rev = "65e61b631e6a8e33e47f906b8fbbdd8fb1388ee7", features = ["serde"] }
acadrust = { git = "https://github.com/HakanSeven12/cadcodec.git", rev = "4d7b359b0571f9b6e0f85a62a21c67508722b83e", features = ["serde"] }
bincode = "1.3"
serde = { version = "1", features = ["derive"] }
console_error_panic_hook = "0.1"
+1 -1
View File
@@ -10,4 +10,4 @@ crate-type = ["cdylib"]
[dependencies]
ocs_plugin_api = { path = "../ocs_plugin_api", features = ["host"] }
acadrust = { git = "https://github.com/HakanSeven12/cadcodec.git", rev = "65e61b631e6a8e33e47f906b8fbbdd8fb1388ee7", features = ["serde"] }
acadrust = { git = "https://github.com/HakanSeven12/cadcodec.git", rev = "4d7b359b0571f9b6e0f85a62a21c67508722b83e", features = ["serde"] }
+1 -1
View File
@@ -12,4 +12,4 @@ crate-type = ["cdylib"]
[dependencies]
ocs_plugin_api = { path = "../../crates/ocs_plugin_api", features = ["host"] }
acadrust = { git = "https://github.com/HakanSeven12/cadcodec.git", rev = "65e61b631e6a8e33e47f906b8fbbdd8fb1388ee7" }
acadrust = { git = "https://github.com/HakanSeven12/cadcodec.git", rev = "4d7b359b0571f9b6e0f85a62a21c67508722b83e" }
+6 -240
View File
@@ -3,7 +3,6 @@ use acadrust::entities::{
DimensionBase, DimensionDiameter, DimensionLargeRadial, DimensionLinear, DimensionOrdinate,
DimensionRadius,
};
use acadrust::Entity;
use glam::{DVec3, Vec3};
use crate::command::EntityTransform;
@@ -833,245 +832,12 @@ fn large_radial_rotation(d: &DimensionLargeRadial) -> f64 {
}
fn apply_transform(dim: &mut Dimension, t: &EntityTransform) {
if matches!(dim, Dimension::Ordinate(_)) {
match t {
EntityTransform::Translate(delta) => dim.translate(Vector3::new(
delta.x, delta.y, delta.z,
)),
EntityTransform::Rotate {
center,
axis,
angle_rad,
} => crate::scene::view::transform::apply_standard_transform(
dim,
*center,
*axis,
*angle_rad,
),
EntityTransform::Scale { center, factor } => {
crate::scene::view::transform::apply_standard_scale(dim, *center, *factor)
}
EntityTransform::Mirror {
p1,
p2,
working_normal,
} => acadrust::Entity::apply_transform(
dim,
&crate::scene::view::transform::reflection_about_working_line(
*p1,
*p2,
*working_normal,
),
),
EntityTransform::Affine(transform) => {
acadrust::Entity::apply_transform(dim, transform)
}
}
return;
}
match t {
EntityTransform::Translate(d) => dim.translate(acadrust::types::Vector3::new(
d.x as f64, d.y as f64, d.z as f64,
)),
EntityTransform::Rotate { center, axis, angle_rad } => {
if axis.normalize_or(DVec3::Z).abs_diff_eq(DVec3::Z, 1e-10) {
transform_dimension_points(dim, |pt| rotate_point(pt, *center, *angle_rad));
// A linear dimension measures along its stored rotation, so the
// axis must turn with the points or the value collapses.
if let Dimension::Linear(d) = dim {
d.rotation += *angle_rad;
}
} else {
// acadrust only moves a non-ordinate dimension by where the
// origin goes, so turn it through the affine path below.
use acadrust::types::Transform;
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,
))
.then(&Transform::from_translation(Vector3::new(
center.x, center.y, center.z,
)));
apply_transform(dim, &EntityTransform::Affine(rotation));
}
}
EntityTransform::Scale { center, factor } => {
transform_dimension_points(dim, |pt| scale_point(pt, *center, *factor))
}
EntityTransform::Mirror { p1, p2, working_normal } => {
if working_normal.normalize_or(DVec3::Z).abs_diff_eq(DVec3::Z, 1e-10) {
transform_dimension_points(dim, |pt| mirror_point(pt, *p1, *p2));
let axis = *p2 - *p1;
if let Dimension::Linear(d) = dim {
if axis.x * axis.x + axis.y * axis.y >= 1e-12 {
d.rotation = 2.0 * axis.y.atan2(axis.x) - d.rotation;
}
}
} else {
// Same as ROTATE: reflect points, plane and angles together.
let reflection = crate::scene::view::transform::reflection_about_working_line(
*p1,
*p2,
*working_normal,
);
apply_transform(dim, &EntityTransform::Affine(reflection));
}
}
EntityTransform::Affine(transform) => {
let old_normal = dim.base().normal;
let text_rotation =
transformed_dimension_angle(old_normal, dim.base().text_rotation, transform);
let horizontal_direction = transformed_dimension_angle(
old_normal,
dim.base().horizontal_direction,
transform,
);
let insertion_rotation = transformed_dimension_angle(
old_normal,
dim.base().insertion_rotation,
transform,
);
let linear_angles = match dim {
Dimension::Linear(value) => Some((
transformed_dimension_angle(old_normal, value.rotation, transform),
transformed_dimension_angle(old_normal, value.ext_line_rotation, transform),
)),
_ => None,
};
transform_dimension_points(dim, |point| {
*point = transform.apply(*point);
});
let transformed_normal = transform.apply_rotation(old_normal);
let base = dim.base_mut();
base.normal = if transformed_normal.length() > 1e-12 {
transformed_normal.normalize()
} else {
old_normal
};
base.text_rotation = text_rotation;
base.horizontal_direction = horizontal_direction;
base.insertion_rotation = insertion_rotation;
if let Some((rotation, ext_line_rotation)) = linear_angles {
if let Dimension::Linear(value) = dim {
value.rotation = rotation;
value.ext_line_rotation = ext_line_rotation;
}
}
}
}
dim.base_mut().actual_measurement = dim.measurement();
}
fn transform_dimension_points<F>(dim: &mut Dimension, mut f: F)
where
F: FnMut(&mut acadrust::types::Vector3),
{
f(&mut dim.base_mut().definition_point);
f(&mut dim.base_mut().text_middle_point);
f(&mut dim.base_mut().insertion_point);
match dim {
Dimension::Aligned(d) => {
f(&mut d.first_point);
f(&mut d.second_point);
f(&mut d.definition_point);
}
Dimension::Linear(d) => {
f(&mut d.first_point);
f(&mut d.second_point);
f(&mut d.definition_point);
}
Dimension::Radius(d) => {
f(&mut d.angle_vertex);
f(&mut d.definition_point);
}
Dimension::Diameter(d) => {
f(&mut d.angle_vertex);
f(&mut d.definition_point);
}
Dimension::Angular2Ln(d) => {
f(&mut d.dimension_arc);
f(&mut d.first_point);
f(&mut d.second_point);
f(&mut d.angle_vertex);
f(&mut d.definition_point);
}
Dimension::Angular3Pt(d) => {
f(&mut d.first_point);
f(&mut d.second_point);
f(&mut d.angle_vertex);
f(&mut d.definition_point);
}
Dimension::Ordinate(d) => {
f(&mut d.definition_point);
f(&mut d.feature_location);
f(&mut d.leader_endpoint);
}
Dimension::Arc(d) => {
f(&mut d.definition_point);
f(&mut d.first_extension_point);
f(&mut d.second_extension_point);
f(&mut d.center_point);
if d.has_leader {
f(&mut d.first_leader_point);
f(&mut d.second_leader_point);
}
}
Dimension::LargeRadial(d) => {
f(&mut d.definition_point);
f(&mut d.chord_point);
f(&mut d.override_center);
f(&mut d.jog_point);
}
}
}
fn transformed_dimension_angle(
normal: acadrust::types::Vector3,
angle: f64,
transform: &acadrust::types::Transform,
) -> f64 {
let ((xx, xy, xz), (yx, yy, yz)) =
crate::scene::view::transform::ocs_axes((normal.x, normal.y, normal.z));
let direction = acadrust::types::Vector3::new(
xx * angle.cos() + yx * angle.sin(),
xy * angle.cos() + yy * angle.sin(),
xz * angle.cos() + yz * angle.sin(),
);
let transformed_normal = transform.apply_rotation(normal).normalize();
let transformed_direction = transform.apply_rotation(direction).normalize();
let ((nxx, nxy, nxz), (nyx, nyy, nyz)) = crate::scene::view::transform::ocs_axes((
transformed_normal.x,
transformed_normal.y,
transformed_normal.z,
));
let new_x = acadrust::types::Vector3::new(nxx, nxy, nxz);
let new_y = acadrust::types::Vector3::new(nyx, nyy, nyz);
transformed_direction
.dot(&new_y)
.atan2(transformed_direction.dot(&new_x))
}
fn rotate_point(p: &mut acadrust::types::Vector3, center: DVec3, angle_rad: f64) {
let dx = p.x - center.x;
let dy = p.y - center.y;
let (s, c) = angle_rad.sin_cos();
p.x = center.x + dx * c - dy * s;
p.y = center.y + dx * s + dy * c;
}
fn scale_point(p: &mut acadrust::types::Vector3, center: DVec3, factor: f64) {
let f = factor;
p.x = center.x + (p.x - center.x) * f;
p.y = center.y + (p.y - center.y) * f;
p.z = center.z + (p.z - center.z) * f;
}
fn mirror_point(p: &mut acadrust::types::Vector3, p1: DVec3, p2: DVec3) {
crate::scene::view::transform::reflect_xy_point(&mut p.x, &mut p.y, p1, p2);
crate::scene::view::transform::apply_standard_entity_transform(dim, t, |entity, p1, p2| {
acadrust::Entity::apply_transform(
entity,
&crate::scene::view::transform::reflection_about_xy_line(p1, p2),
);
});
}
impl PropertyEditable for Dimension {