refactor(snap): producers emit f64 snap points (world_offset removal P3)
TruckEntity.snap_pts is now DVec3 and every entity producer builds snap candidates straight from the acadrust f64 coordinates instead of casting to f32 first (text, mtext, arc, circle, ellipse, point, shape, solid, mline, mtext, attribute, tolerance, table, underlay, ole2frame, mesh, multileader, dimension, block-cache). offset_snap_pts stays f64 throughout. Still offset-relative (inert) — but snap precision is no longer capped at ~0.5 m by an early f32 cast, which fixes a latent UTM-scale snap error and sets up the absolute-coordinate switch. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
a7a1fac09a
commit
cd1d3bb619
18 changed files with 43 additions and 85 deletions
|
|
@ -1,5 +1,4 @@
|
|||
use acadrust::entities::Arc;
|
||||
use glam::Vec3;
|
||||
use truck_modeling::{builder, Point3};
|
||||
|
||||
use crate::command::EntityTransform;
|
||||
|
|
@ -39,11 +38,11 @@ fn to_truck(arc: &Arc) -> TruckEntity {
|
|||
)
|
||||
};
|
||||
|
||||
let cv = Vec3::new(cwx as f32, cwy as f32, cwz as f32);
|
||||
let cv = glam::DVec3::new(cwx, cwy, cwz);
|
||||
// Arc-length centre — one well-defined midpoint snap. Circles and
|
||||
// ellipses (closed curves) deliberately don't emit this; see #34.
|
||||
let mid_pt_3 = arc_pt(mid_a);
|
||||
let mv = Vec3::new(mid_pt_3.x as f32, mid_pt_3.y as f32, mid_pt_3.z as f32);
|
||||
let mv = glam::DVec3::new(mid_pt_3.x, mid_pt_3.y, mid_pt_3.z);
|
||||
let tangent = TangentGeom::Circle {
|
||||
center: [cwx as f32, cwy as f32, cwz as f32],
|
||||
radius: r as f32,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ use acadrust::entities::attribute_definition::{
|
|||
};
|
||||
use acadrust::entities::{AttributeDefinition, AttributeEntity};
|
||||
use acadrust::types::Vector3;
|
||||
use glam::Vec3;
|
||||
|
||||
use crate::command::EntityTransform;
|
||||
use crate::entities::common::{edit_prop as edit, parse_f64, ro_prop as ro, square_grip};
|
||||
|
|
@ -111,7 +110,7 @@ fn build_attr_truck(input: AttrTextInputs<'_>, document: &acadrust::CadDocument)
|
|||
),
|
||||
normal,
|
||||
);
|
||||
let snap_pt = Vec3::new(wsx as f32, wsy as f32, wsz as f32);
|
||||
let snap_pt = glam::DVec3::new(wsx, wsy, wsz);
|
||||
|
||||
let resolved = resolve_text_style(input.text_style, document);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
use acadrust::entities::Circle;
|
||||
use glam::Vec3;
|
||||
use truck_modeling::{builder, Point3, Wire};
|
||||
|
||||
use crate::command::EntityTransform;
|
||||
|
|
@ -35,14 +34,10 @@ fn to_truck(circle: &Circle) -> TruckEntity {
|
|||
let p_top = pt(ay, (0.0, 0.0, 0.0), r);
|
||||
let p_bot = pt((ay.0 * -1.0, ay.1 * -1.0, ay.2 * -1.0), (0.0, 0.0, 0.0), r);
|
||||
|
||||
let cv = Vec3::new(cwx as f32, cwy as f32, cwz as f32);
|
||||
let cv = glam::DVec3::new(cwx, cwy, cwz);
|
||||
let rf = r as f32;
|
||||
let q = |d: (f64, f64, f64)| {
|
||||
Vec3::new(
|
||||
(cwx + r * d.0) as f32,
|
||||
(cwy + r * d.1) as f32,
|
||||
(cwz + r * d.2) as f32,
|
||||
)
|
||||
glam::DVec3::new(cwx + r * d.0, cwy + r * d.1, cwz + r * d.2)
|
||||
};
|
||||
let snap_pts = vec![
|
||||
(cv, SnapHint::Center),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
use acadrust::entities::Ellipse;
|
||||
use glam::Vec3;
|
||||
use truck_modeling::{builder, BSplineCurve, Curve, Edge, KnotVec, Point3, Wire};
|
||||
|
||||
use crate::command::EntityTransform;
|
||||
|
|
@ -41,7 +40,7 @@ fn to_truck(ell: &Ellipse) -> TruckEntity {
|
|||
// Minor axis direction: WCS_normal × u (both unit vectors, always perpendicular).
|
||||
let wcs_normal = glam::Vec3::new(nx as f32, ny as f32, nz as f32);
|
||||
let v_axis = wcs_normal.cross(u);
|
||||
let center_v3 = Vec3::new(cwx as f32, cwy as f32, cwz as f32);
|
||||
let center_v3 = glam::DVec3::new(cwx, cwy, cwz);
|
||||
let is_closed = (t1 - t0 - TAU).abs() < 1e-6;
|
||||
|
||||
if is_closed {
|
||||
|
|
@ -81,10 +80,10 @@ fn to_truck(ell: &Ellipse) -> TruckEntity {
|
|||
let wire: Wire = [edge_upper, edge_lower].into_iter().collect();
|
||||
// Quadrant points at ±major and ±minor axis endpoints in WCS.
|
||||
let q = |lx: f64, lz: f64| {
|
||||
Vec3::new(
|
||||
(cwx + lx * u.x as f64 + lz * v_axis.x as f64) as f32,
|
||||
(cwy + lx * u.y as f64 + lz * v_axis.y as f64) as f32,
|
||||
(cwz + lx * u.z as f64 + lz * v_axis.z as f64) as f32,
|
||||
glam::DVec3::new(
|
||||
cwx + lx * u.x as f64 + lz * v_axis.x as f64,
|
||||
cwy + lx * u.y as f64 + lz * v_axis.y as f64,
|
||||
cwz + lx * u.z as f64 + lz * v_axis.z as f64,
|
||||
)
|
||||
};
|
||||
let snap_pts = vec![
|
||||
|
|
|
|||
|
|
@ -69,10 +69,10 @@ impl TruckConvertible for Face3D {
|
|||
Some(TruckEntity {
|
||||
object: TruckObject::Lines(pts),
|
||||
snap_pts: vec![
|
||||
(Vec3::from(p0f), SnapHint::Node),
|
||||
(Vec3::from(p1f), SnapHint::Node),
|
||||
(Vec3::from(p2f), SnapHint::Node),
|
||||
(Vec3::from(p3f), SnapHint::Node),
|
||||
(Vec3::from(p0f).as_dvec3(), SnapHint::Node),
|
||||
(Vec3::from(p1f).as_dvec3(), SnapHint::Node),
|
||||
(Vec3::from(p2f).as_dvec3(), SnapHint::Node),
|
||||
(Vec3::from(p3f).as_dvec3(), SnapHint::Node),
|
||||
],
|
||||
tangent_geoms: vec![],
|
||||
key_vertices: vec![p0, p1, p2, p3],
|
||||
|
|
@ -552,15 +552,10 @@ impl TruckConvertible for Mesh {
|
|||
}
|
||||
}
|
||||
|
||||
let snap_pts: Vec<(Vec3, SnapHint)> = self
|
||||
let snap_pts: Vec<(glam::DVec3, SnapHint)> = self
|
||||
.vertices
|
||||
.iter()
|
||||
.map(|v| {
|
||||
(
|
||||
Vec3::new(v.x as f32, v.y as f32, v.z as f32),
|
||||
SnapHint::Node,
|
||||
)
|
||||
})
|
||||
.map(|v| (glam::DVec3::new(v.x, v.y, v.z), SnapHint::Node))
|
||||
.collect();
|
||||
let key_vertices: Vec<[f64; 3]> = self.vertices.iter().map(|v| [v.x, v.y, v.z]).collect();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
use acadrust::entities::MLine;
|
||||
use glam::Vec3;
|
||||
|
||||
use crate::command::EntityTransform;
|
||||
use crate::entities::common::{edit_prop as edit, ro_prop as ro, square_grip};
|
||||
|
|
@ -98,11 +97,7 @@ impl TruckConvertible for MLine {
|
|||
.iter()
|
||||
.map(|v| {
|
||||
(
|
||||
Vec3::new(
|
||||
v.position.x as f32,
|
||||
v.position.y as f32,
|
||||
v.position.z as f32,
|
||||
),
|
||||
glam::DVec3::new(v.position.x, v.position.y, v.position.z),
|
||||
SnapHint::Node,
|
||||
)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
use acadrust::entities::{AttachmentPoint, DrawingDirection, MText};
|
||||
use glam::Vec3;
|
||||
|
||||
use crate::command::EntityTransform;
|
||||
use crate::entities::common::{edit_prop as edit, ro_prop as ro, square_grip, triangle_grip};
|
||||
|
|
@ -168,10 +167,10 @@ fn to_truck(t: &MText, document: &acadrust::CadDocument) -> TruckEntity {
|
|||
vertical_text: matches!(t.drawing_direction, DrawingDirection::TopToBottom),
|
||||
want_glyph_boxes: false,
|
||||
});
|
||||
let insertion = Vec3::new(
|
||||
t.insertion_point.x as f32,
|
||||
t.insertion_point.y as f32,
|
||||
t.insertion_point.z as f32,
|
||||
let insertion = glam::DVec3::new(
|
||||
t.insertion_point.x,
|
||||
t.insertion_point.y,
|
||||
t.insertion_point.z,
|
||||
);
|
||||
TruckEntity {
|
||||
object: TruckObject::Text(layout.strokes),
|
||||
|
|
|
|||
|
|
@ -77,17 +77,10 @@ fn to_truck(ml: &MultiLeader, document: &acadrust::CadDocument) -> Option<TruckE
|
|||
let mut points: Vec<[f64; 3]> = Vec::new();
|
||||
let mut tangents: Vec<TangentGeom> = Vec::new();
|
||||
let mut key_verts: Vec<[f64; 3]> = Vec::new();
|
||||
// This builds a TruckEntity (snap_pts in Vec3); tessellate's
|
||||
// offset_snap_pts widens it to the f64 WireModel buffer afterwards.
|
||||
let mut snap_pts: Vec<(Vec3, SnapHint)> = Vec::new();
|
||||
let mut snap_pts: Vec<(glam::DVec3, SnapHint)> = Vec::new();
|
||||
let mut first = true;
|
||||
|
||||
let node = |arr: [f64; 3]| {
|
||||
(
|
||||
Vec3::new(arr[0] as f32, arr[1] as f32, arr[2] as f32),
|
||||
SnapHint::Node,
|
||||
)
|
||||
};
|
||||
let node = |arr: [f64; 3]| (glam::DVec3::new(arr[0], arr[1], arr[2]), SnapHint::Node);
|
||||
|
||||
// Text-side geometry, recomputed every frame so dragging the arrow or the
|
||||
// text re-mirrors the whole layout. The text block is centred on its grip
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
use acadrust::entities::{Ole2Frame, OleObjectType};
|
||||
use glam::Vec3;
|
||||
|
||||
use crate::command::EntityTransform;
|
||||
use crate::entities::common::{center_grip, edit_prop as edit, ro_prop as ro, square_grip};
|
||||
|
|
@ -45,7 +44,7 @@ fn to_truck(ole: &Ole2Frame) -> TruckEntity {
|
|||
[x1, y0, z],
|
||||
[x0, y1, z],
|
||||
];
|
||||
let center = Vec3::new(cx as f32, cy as f32, z as f32);
|
||||
let center = glam::DVec3::new(cx, cy, z);
|
||||
TruckEntity {
|
||||
object: TruckObject::Lines(pts),
|
||||
snap_pts: vec![(center, SnapHint::Center)],
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
use acadrust::entities::Point;
|
||||
use acadrust::EntityType;
|
||||
use glam::Vec3;
|
||||
use truck_modeling::{builder, Point3};
|
||||
|
||||
use crate::command::EntityTransform;
|
||||
|
|
@ -36,7 +35,7 @@ fn point_truck(pt: &Point, pdmode: i16, s: f64) -> TruckEntity {
|
|||
(pt.location.x, pt.location.y, pt.location.z),
|
||||
normal,
|
||||
);
|
||||
let snap = Vec3::new(wx as f32, wy as f32, wz as f32);
|
||||
let snap = glam::DVec3::new(wx, wy, wz);
|
||||
if pdmode == 0 {
|
||||
// Default: a single vertex (driver handles the dot pixel).
|
||||
let p = Point3::new(wx, wy, wz);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
// gives a rough indication of the glyph orientation.
|
||||
|
||||
use acadrust::entities::Shape;
|
||||
use glam::Vec3;
|
||||
|
||||
use crate::command::EntityTransform;
|
||||
use crate::entities::common::{edit_prop as edit, ro_prop as ro, square_grip};
|
||||
|
|
@ -63,7 +62,7 @@ impl TruckConvertible for Shape {
|
|||
let oz = self.insertion_point.z;
|
||||
let size = self.size.abs().max(0.5);
|
||||
|
||||
let snap_pt = Vec3::new(ox as f32, oy as f32, oz as f32);
|
||||
let snap_pt = glam::DVec3::new(ox, oy, oz);
|
||||
let pts = shape_marker(
|
||||
ox,
|
||||
oy,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
// Grips: 4 corner grip points.
|
||||
|
||||
use acadrust::entities::Solid;
|
||||
use glam::Vec3;
|
||||
|
||||
use crate::command::EntityTransform;
|
||||
use crate::entities::common::{edit_prop as edit, square_grip};
|
||||
|
|
@ -22,10 +21,6 @@ fn dvec3(v: &acadrust::types::Vector3) -> glam::DVec3 {
|
|||
glam::DVec3::new(v.x, v.y, v.z)
|
||||
}
|
||||
|
||||
fn v3f32(v: &acadrust::types::Vector3) -> [f32; 3] {
|
||||
[v.x as f32, v.y as f32, v.z as f32]
|
||||
}
|
||||
|
||||
impl TruckConvertible for Solid {
|
||||
fn to_truck(&self, _document: &acadrust::CadDocument) -> Option<TruckEntity> {
|
||||
let p0 = v3(&self.first_corner);
|
||||
|
|
@ -50,11 +45,12 @@ impl TruckConvertible for Solid {
|
|||
p0,
|
||||
];
|
||||
|
||||
let dv = |c: &acadrust::types::Vector3| glam::DVec3::new(c.x, c.y, c.z);
|
||||
let snap = vec![
|
||||
(Vec3::from(v3f32(&self.first_corner)), SnapHint::Node),
|
||||
(Vec3::from(v3f32(&self.second_corner)), SnapHint::Node),
|
||||
(Vec3::from(v3f32(&self.third_corner)), SnapHint::Node),
|
||||
(Vec3::from(v3f32(&self.fourth_corner)), SnapHint::Node),
|
||||
(dv(&self.first_corner), SnapHint::Node),
|
||||
(dv(&self.second_corner), SnapHint::Node),
|
||||
(dv(&self.third_corner), SnapHint::Node),
|
||||
(dv(&self.fourth_corner), SnapHint::Node),
|
||||
];
|
||||
|
||||
Some(TruckEntity {
|
||||
|
|
|
|||
|
|
@ -323,7 +323,7 @@ impl TruckConvertible for Table {
|
|||
.collect();
|
||||
Some(TruckEntity {
|
||||
object: TruckObject::Lines(pts_f64),
|
||||
snap_pts: vec![(v3(&self.insertion_point), SnapHint::Insertion)],
|
||||
snap_pts: vec![(glam::DVec3::new(self.insertion_point.x, self.insertion_point.y, self.insertion_point.z), SnapHint::Insertion)],
|
||||
tangent_geoms: vec![],
|
||||
key_vertices: vec![],
|
||||
fill_tris: vec![],
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
use acadrust::entities::{Text, TextHorizontalAlignment as HA, TextVerticalAlignment as VA};
|
||||
use glam::Vec3;
|
||||
|
||||
use crate::command::EntityTransform;
|
||||
use crate::entities::common::{edit_prop as edit, parse_f64, square_grip};
|
||||
|
|
@ -58,7 +57,7 @@ fn to_truck(t: &Text, document: &acadrust::CadDocument) -> TruckEntity {
|
|||
),
|
||||
normal,
|
||||
);
|
||||
let snap_pt = Vec3::new(wsx as f32, wsy as f32, wsz as f32);
|
||||
let snap_pt = glam::DVec3::new(wsx, wsy, wsz);
|
||||
let resolved_style = resolve_text_style(&t.style, document);
|
||||
let font_name = resolved_style.font_name;
|
||||
// AutoCAD text geometry rule: the entity stores the FINAL width factor /
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
use acadrust::entities::Tolerance;
|
||||
use glam::Vec3;
|
||||
|
||||
use crate::command::EntityTransform;
|
||||
use crate::entities::common::{edit_prop as edit, ro_prop as ro, square_grip};
|
||||
|
|
@ -234,10 +233,10 @@ impl TruckConvertible for Tolerance {
|
|||
return None;
|
||||
}
|
||||
|
||||
let snap_pt = Vec3::new(
|
||||
self.insertion_point.x as f32,
|
||||
self.insertion_point.y as f32,
|
||||
self.insertion_point.z as f32,
|
||||
let snap_pt = glam::DVec3::new(
|
||||
self.insertion_point.x,
|
||||
self.insertion_point.y,
|
||||
self.insertion_point.z,
|
||||
);
|
||||
|
||||
// Build the feature-control frame in local space; origin stored as f64.
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
// Props: position, scales, rotation, contrast, fade, flags.
|
||||
|
||||
use acadrust::entities::{Underlay, UnderlayDisplayFlags};
|
||||
use glam::Vec3;
|
||||
|
||||
use crate::command::EntityTransform;
|
||||
use crate::entities::common::{center_grip, edit_prop as edit, ro_prop as ro, square_grip};
|
||||
|
|
@ -41,7 +40,7 @@ fn cross_wire(origin: [f64; 3], size: f64) -> Vec<[f64; 3]> {
|
|||
impl TruckConvertible for Underlay {
|
||||
fn to_truck(&self, _document: &acadrust::CadDocument) -> Option<TruckEntity> {
|
||||
let origin = v3(&self.insertion_point);
|
||||
let origin_f32 = v3f32(&self.insertion_point);
|
||||
let _origin_f32 = v3f32(&self.insertion_point);
|
||||
|
||||
if !self.clip_boundary_vertices.is_empty() {
|
||||
// Draw clip boundary polygon + close it.
|
||||
|
|
@ -55,7 +54,7 @@ impl TruckConvertible for Underlay {
|
|||
let key: Vec<[f64; 3]> = pts.clone();
|
||||
Some(TruckEntity {
|
||||
object: TruckObject::Lines(pts),
|
||||
snap_pts: vec![(Vec3::from(origin_f32), SnapHint::Node)],
|
||||
snap_pts: vec![(glam::DVec3::new(self.insertion_point.x, self.insertion_point.y, self.insertion_point.z), SnapHint::Node)],
|
||||
tangent_geoms: vec![],
|
||||
key_vertices: key,
|
||||
fill_tris: vec![],
|
||||
|
|
@ -65,7 +64,7 @@ impl TruckConvertible for Underlay {
|
|||
let pts = cross_wire(origin, 1.0);
|
||||
Some(TruckEntity {
|
||||
object: TruckObject::Lines(pts),
|
||||
snap_pts: vec![(Vec3::from(origin_f32), SnapHint::Node)],
|
||||
snap_pts: vec![(glam::DVec3::new(self.insertion_point.x, self.insertion_point.y, self.insertion_point.z), SnapHint::Node)],
|
||||
tangent_geoms: vec![],
|
||||
key_vertices: vec![origin],
|
||||
fill_tris: vec![],
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
// acadrust -> truck topology conversion layer.
|
||||
|
||||
use acadrust::{CadDocument, EntityType};
|
||||
use glam::Vec3;
|
||||
use truck_modeling::{Edge, Solid, Vertex, Wire};
|
||||
|
||||
use crate::entities::traits::EntityTypeOps;
|
||||
|
|
@ -40,7 +39,7 @@ pub enum TruckObject {
|
|||
|
||||
pub struct TruckEntity {
|
||||
pub object: TruckObject,
|
||||
pub snap_pts: Vec<(Vec3, SnapHint)>,
|
||||
pub snap_pts: Vec<(glam::DVec3, SnapHint)>,
|
||||
pub tangent_geoms: Vec<TangentGeom>,
|
||||
/// Polyline vertex positions in WCS f64; converted to offset-relative f32
|
||||
/// at the wire-model boundary.
|
||||
|
|
|
|||
|
|
@ -863,17 +863,12 @@ pub(crate) fn add_polyline(points: &mut Vec<[f32; 3]>, polyline: &[Vec3]) {
|
|||
}
|
||||
|
||||
pub(crate) fn offset_snap_pts(
|
||||
pts: Vec<(Vec3, SnapHint)>,
|
||||
pts: Vec<(glam::DVec3, SnapHint)>,
|
||||
off: [f64; 3],
|
||||
) -> Vec<(glam::DVec3, SnapHint)> {
|
||||
let [ox, oy, oz] = off;
|
||||
pts.into_iter()
|
||||
.map(|(p, h)| {
|
||||
(
|
||||
glam::DVec3::new(p.x as f64 - ox, p.y as f64 - oy, p.z as f64 - oz),
|
||||
h,
|
||||
)
|
||||
})
|
||||
.map(|(p, h)| (glam::DVec3::new(p.x - ox, p.y - oy, p.z - oz), h))
|
||||
.collect()
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue