diff --git a/src/entities/dimension.rs b/src/entities/dimension.rs index b554658f..dbceea69 100644 --- a/src/entities/dimension.rs +++ b/src/entities/dimension.rs @@ -1837,12 +1837,12 @@ fn append_angular_dimension( } } -fn dimension_snap_pts(dim: &Dimension, world_offset: [f64; 3]) -> Vec<(Vec3, SnapHint)> { +fn dimension_snap_pts(dim: &Dimension, world_offset: [f64; 3]) -> Vec<(glam::DVec3, SnapHint)> { let lv = |v: acadrust::types::Vector3| { - Vec3::new( - (v.x - world_offset[0]) as f32, - (v.y - world_offset[1]) as f32, - (v.z - world_offset[2]) as f32, + glam::DVec3::new( + v.x - world_offset[0], + v.y - world_offset[1], + v.z - world_offset[2], ) }; let node = |v: acadrust::types::Vector3| (lv(v), SnapHint::Node); diff --git a/src/entities/multileader.rs b/src/entities/multileader.rs index 9699cc64..985a3f36 100644 --- a/src/entities/multileader.rs +++ b/src/entities/multileader.rs @@ -77,10 +77,11 @@ fn to_truck(ml: &MultiLeader, document: &acadrust::CadDocument) -> Option = Vec::new(); let mut tangents: Vec = 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 first = true; - // snap_pts uses f32 (UI-only); cast at construction. let node = |arr: [f64; 3]| { ( Vec3::new(arr[0] as f32, arr[1] as f32, arr[2] as f32), @@ -1168,7 +1169,7 @@ impl MultiLeaderTess for MultiLeader { // ── Leader / arrow / dogleg points ─────────────────────────────────────── let mut points: Vec<[f32; 3]> = Vec::new(); let mut key_verts: Vec<[f32; 3]> = Vec::new(); - let mut snap_pts: Vec<(Vec3, SnapHint)> = Vec::new(); + let mut snap_pts: Vec<(glam::DVec3, SnapHint)> = Vec::new(); let mut tangents: Vec = Vec::new(); let mut arrow_fill: Vec<[f32; 3]> = Vec::new(); let mut first = true; @@ -1194,7 +1195,7 @@ impl MultiLeaderTess for MultiLeader { for root in &ml.context.leader_roots { let cp = &root.connection_point; let cp_f = p3(cp); - snap_pts.push((Vec3::from(cp_f), SnapHint::Node)); + snap_pts.push((Vec3::from(cp_f).as_dvec3(), SnapHint::Node)); for line in &root.lines { if line.points.is_empty() { @@ -1216,7 +1217,7 @@ impl MultiLeaderTess for MultiLeader { } for &c in &ctrl { key_verts.push(c); - snap_pts.push((Vec3::from(c), SnapHint::Node)); + snap_pts.push((Vec3::from(c).as_dvec3(), SnapHint::Node)); } if ml.path_type == MultiLeaderPathType::Spline && ctrl.len() >= 2 { @@ -1550,7 +1551,7 @@ impl MultiLeaderTess for MultiLeader { pattern_length: 0.0, pattern: [0.0; 8], line_weight_px, - snap_pts: vec![(Vec3::new(local_ins_x, local_ins_y, z), SnapHint::Node)], + snap_pts: vec![(glam::DVec3::new(local_ins_x as f64, local_ins_y as f64, z as f64), SnapHint::Node)], tangent_geoms: vec![], key_vertices: vec![], aabb: WireModel::UNBOUNDED_AABB, @@ -1592,7 +1593,7 @@ impl MultiLeaderTess for MultiLeader { pattern_length: 0.0, pattern: [0.0; 8], line_weight_px: 1.0, - snap_pts: vec![(Vec3::new(local_ins_x, local_ins_y, z), SnapHint::Node)], + snap_pts: vec![(glam::DVec3::new(local_ins_x as f64, local_ins_y as f64, z as f64), SnapHint::Node)], tangent_geoms: vec![], key_vertices: vec![], aabb: WireModel::UNBOUNDED_AABB, @@ -1632,7 +1633,7 @@ impl MultiLeaderTess for MultiLeader { pattern_length: 0.0, pattern: [0.0; 8], line_weight_px, - snap_pts: vec![(Vec3::new(local_ins_x, local_ins_y, z), SnapHint::Node)], + snap_pts: vec![(glam::DVec3::new(local_ins_x as f64, local_ins_y as f64, z as f64), SnapHint::Node)], tangent_geoms: vec![], key_vertices: vec![], aabb: WireModel::UNBOUNDED_AABB, diff --git a/src/scene/cache/block_cache.rs b/src/scene/cache/block_cache.rs index 58f2398a..2f73535e 100644 --- a/src/scene/cache/block_cache.rs +++ b/src/scene/cache/block_cache.rs @@ -39,7 +39,7 @@ pub struct LocalWire { /// sub-f32 precision once the renderer translates them to world space. pub points_low: Vec<[f32; 3]>, pub key_vertices: Vec<[f32; 3]>, - pub snap_pts: Vec<(glam::Vec3, SnapHint)>, + pub snap_pts: Vec<(glam::DVec3, SnapHint)>, pub tangent_geoms: Vec, pub fill_tris: Vec<[f32; 3]>, pub color: [f32; 4], @@ -1041,7 +1041,7 @@ struct BatchEntry { plinegen: bool, points: Vec<[f32; 3]>, points_low: Vec<[f32; 3]>, - snap_pts: Vec<(glam::Vec3, SnapHint)>, + snap_pts: Vec<(glam::DVec3, SnapHint)>, key_vertices: Vec<[f32; 3]>, tangent_geoms: Vec, fill_tris: Vec<[f32; 3]>, @@ -1465,11 +1465,7 @@ fn emit_wire( p.z as f64 + lo_z, )); entry.snap_pts.push(( - glam::Vec3::new( - (v.x - ox) as f32, - (v.y - oy) as f32, - (v.z - oz) as f32, - ), + glam::DVec3::new(v.x - ox, v.y - oy, v.z - oz), *hint, )); } diff --git a/src/scene/convert/tessellate.rs b/src/scene/convert/tessellate.rs index 404c1398..510d71bf 100644 --- a/src/scene/convert/tessellate.rs +++ b/src/scene/convert/tessellate.rs @@ -477,7 +477,7 @@ pub fn tessellate( // Add insertion snap at point_of_reference. let [ox, oy, oz] = world_offset; if let Some(p) = crate::entities::solid3d::point_of_reference(entity) { - let sp = Vec3::new((p.x - ox) as f32, (p.y - oy) as f32, (p.z - oz) as f32); + let sp = glam::DVec3::new(p.x - ox, p.y - oy, p.z - oz); wm.snap_pts.push((sp, SnapHint::Insertion)); } return vec![wm]; @@ -487,6 +487,10 @@ pub fn tessellate( // ── Fallback for Viewport / Insert / Hatch / Ole2Frame ──────────────── let (points, snap_pts, tangent_geoms, key_vertices) = fallback_geometry(entity, world_offset); + // fallback_geometry still emits offset-relative f32 snap points; widen to + // f64 for the WireModel's double-single-era snap buffer. + let snap_pts: Vec<(glam::DVec3, SnapHint)> = + snap_pts.into_iter().map(|(p, h)| (p.as_dvec3(), h)).collect(); vec![WireModel { name, points, @@ -858,12 +862,15 @@ pub(crate) fn add_polyline(points: &mut Vec<[f32; 3]>, polyline: &[Vec3]) { points.extend(polyline.iter().map(|p| [p.x, p.y, p.z])); } -pub(crate) fn offset_snap_pts(pts: Vec<(Vec3, SnapHint)>, off: [f64; 3]) -> Vec<(Vec3, SnapHint)> { +pub(crate) fn offset_snap_pts( + pts: Vec<(Vec3, SnapHint)>, + off: [f64; 3], +) -> Vec<(glam::DVec3, SnapHint)> { let [ox, oy, oz] = off; pts.into_iter() .map(|(p, h)| { ( - Vec3::new(p.x - ox as f32, p.y - oy as f32, p.z - oz as f32), + glam::DVec3::new(p.x as f64 - ox, p.y as f64 - oy, p.z as f64 - oz), h, ) }) diff --git a/src/scene/mod.rs b/src/scene/mod.rs index 3d1375ad..831a76bc 100644 --- a/src/scene/mod.rs +++ b/src/scene/mod.rs @@ -8229,7 +8229,7 @@ fn tessellate_entity( pattern_length: 0.0, pattern: [0.0; 8], line_weight_px: 1.0, - snap_pts: vec![(ip, model::wire_model::SnapHint::Insertion)], + snap_pts: vec![(ip.as_dvec3(), model::wire_model::SnapHint::Insertion)], tangent_geoms: vec![], key_vertices: vec![], aabb: WireModel::UNBOUNDED_AABB, diff --git a/src/scene/model/wire_model.rs b/src/scene/model/wire_model.rs index cc25f24b..88528a62 100644 --- a/src/scene/model/wire_model.rs +++ b/src/scene/model/wire_model.rs @@ -57,7 +57,7 @@ pub struct WireModel { /// ACI color index (1-255). 0 means true-color or unknown (no CTB lookup). pub aci: u8, /// Pre-baked snap candidates (Center, Node, Quadrant, Insertion). - pub snap_pts: Vec<(glam::Vec3, SnapHint)>, + pub snap_pts: Vec<(glam::DVec3, SnapHint)>, /// Per-segment tangent geometry for Tangent snap. /// Line/Arc entities: 1 entry. LwPolyline: 1 entry per segment. pub tangent_geoms: Vec, diff --git a/src/scene/pick/xclip.rs b/src/scene/pick/xclip.rs index 033d2015..7ac225b0 100644 --- a/src/scene/pick/xclip.rs +++ b/src/scene/pick/xclip.rs @@ -104,7 +104,7 @@ pub fn clip_wires(wires: &mut Vec, poly: &[[f32; 2]]) { } w.key_vertices .retain(|v| point_in_poly(v[0], v[1], poly)); - w.snap_pts.retain(|(p, _)| point_in_poly(p.x, p.y, poly)); + w.snap_pts.retain(|(p, _)| point_in_poly(p.x as f32, p.y as f32, poly)); w.aabb = recompute_aabb(&w.points, &w.fill_tris); } wires.retain(|w| !w.points.is_empty() || !w.fill_tris.is_empty()); diff --git a/src/snap/mod.rs b/src/snap/mod.rs index af5ea443..ef4803d2 100644 --- a/src/snap/mod.rs +++ b/src/snap/mod.rs @@ -528,7 +528,7 @@ impl Snapper { SnapHint::Midpoint => SnapType::Midpoint, }; if self.is_on(snap_type) { - try_pt(world, snap_type); + try_pt(world.as_vec3(), snap_type); } } }