forked from 1b-agent/opencadstudio-upstream
fix(render): UTM-precise UCS icon + fallback outlines (hatch etc.)
Two UTM-scale rendering defects. - UCS icon jittered: it projects only axis DIRECTIONS but went through the full view_proj, whose ~5.7e6 translation cancels catastrophically in f32. Feed it the rotation-only view_proj_rte instead (translation dropped). - Fallback outline geometry (hatch boundary, viewport/insert/ole2frame frames, Solid3D edge wires) built absolute f32 points with an empty points_low, so at UTM the outline sat ~0.5 m off its own fill (the hatch fill renders precisely via the world_origin-relative HatchModel pipeline). FallbackGeometry now carries absolute f64 points + key vertices; the tessellate dispatcher splits them into the double-single high/low pair the relative-to-eye wire pass needs, so outlines land exactly on their fills. Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
ef55b49db5
commit
dd1f2e49bb
7 files changed
+72
-46
No files matched your search
+12
-10
@@ -348,13 +348,15 @@ impl FallbackTess for Hatch {
|
||||
let [ox, oy, oz] = world_offset;
|
||||
let normal = (self.normal.x, self.normal.y, self.normal.z);
|
||||
// Convert a 2D OCS hatch boundary point to WCS, then subtract world_offset.
|
||||
let to_wcs = |x: f64, y: f64| -> [f32; 3] {
|
||||
let to_wcs = |x: f64, y: f64| -> [f64; 3] {
|
||||
let (wx, wy, wz) =
|
||||
crate::scene::view::transform::ocs_point_to_wcs((x, y, self.elevation), normal);
|
||||
[(wx - ox) as f32, (wy - oy) as f32, (wz - oz) as f32]
|
||||
[wx - ox, wy - oy, wz - oz]
|
||||
};
|
||||
let mut pts: Vec<[f32; 3]> = Vec::new();
|
||||
let mut key_verts: Vec<[f32; 3]> = Vec::new();
|
||||
// Snap point at a world (f64) location, cast to the f32 snap buffer.
|
||||
let snap_at = |w: [f64; 3]| Vec3::new(w[0] as f32, w[1] as f32, w[2] as f32);
|
||||
let mut pts: Vec<[f64; 3]> = Vec::new();
|
||||
let mut key_verts: Vec<[f64; 3]> = Vec::new();
|
||||
let mut snap_pts: Vec<(Vec3, SnapHint)> = Vec::new();
|
||||
for path in &self.paths {
|
||||
for edge in &path.edges {
|
||||
@@ -376,7 +378,7 @@ impl FallbackTess for Hatch {
|
||||
// shows up as a stray boundary line between hatch
|
||||
// regions.
|
||||
if !pts.is_empty() {
|
||||
pts.push([f32::NAN; 3]);
|
||||
pts.push([f64::NAN; 3]);
|
||||
}
|
||||
let start_idx = pts.len();
|
||||
let seg_count = if poly.is_closed {
|
||||
@@ -435,7 +437,7 @@ impl FallbackTess for Hatch {
|
||||
let p0 = to_wcs(ln.start.x, ln.start.y);
|
||||
let p1 = to_wcs(ln.end.x, ln.end.y);
|
||||
if !pts.is_empty() {
|
||||
pts.push([f32::NAN; 3]);
|
||||
pts.push([f64::NAN; 3]);
|
||||
}
|
||||
pts.push(p0);
|
||||
pts.push(p1);
|
||||
@@ -447,7 +449,7 @@ impl FallbackTess for Hatch {
|
||||
arc_signed_span(arc.start_angle, arc.end_angle, arc.counter_clockwise);
|
||||
let segs = arc_segments(arc.radius, span.abs(), wire_chord_tol(arc.radius));
|
||||
if !pts.is_empty() {
|
||||
pts.push([f32::NAN; 3]);
|
||||
pts.push([f64::NAN; 3]);
|
||||
}
|
||||
for i in 0..=segs {
|
||||
let t = sa + span * (i as f64 / segs as f64);
|
||||
@@ -461,7 +463,7 @@ impl FallbackTess for Hatch {
|
||||
}
|
||||
}
|
||||
snap_pts.push((
|
||||
Vec3::from(to_wcs(arc.center.x, arc.center.y)),
|
||||
snap_at(to_wcs(arc.center.x, arc.center.y)),
|
||||
SnapHint::Center,
|
||||
));
|
||||
}
|
||||
@@ -475,7 +477,7 @@ impl FallbackTess for Hatch {
|
||||
arc_signed_span(ell.start_angle, ell.end_angle, ell.counter_clockwise);
|
||||
let segs = arc_segments(r_maj, span.abs(), wire_chord_tol(r_maj));
|
||||
if !pts.is_empty() {
|
||||
pts.push([f32::NAN; 3]);
|
||||
pts.push([f64::NAN; 3]);
|
||||
}
|
||||
let (cr, sr) = (rot.cos(), rot.sin());
|
||||
for i in 0..=segs {
|
||||
@@ -492,7 +494,7 @@ impl FallbackTess for Hatch {
|
||||
}
|
||||
}
|
||||
snap_pts.push((
|
||||
Vec3::from(to_wcs(ell.center.x, ell.center.y)),
|
||||
snap_at(to_wcs(ell.center.x, ell.center.y)),
|
||||
SnapHint::Center,
|
||||
));
|
||||
}
|
||||
|
||||
+10
-9
@@ -104,17 +104,18 @@ impl crate::entities::traits::FallbackTess for Insert {
|
||||
world_offset: [f64; 3],
|
||||
) -> crate::scene::convert::tess_util::FallbackGeometry {
|
||||
let [ox, oy, oz] = world_offset;
|
||||
let ip = Vec3::new(
|
||||
(self.insert_point.x - ox) as f32,
|
||||
(self.insert_point.y - oy) as f32,
|
||||
(self.insert_point.z - oz) as f32,
|
||||
let (ipx, ipy, ipz) = (
|
||||
self.insert_point.x - ox,
|
||||
self.insert_point.y - oy,
|
||||
self.insert_point.z - oz,
|
||||
);
|
||||
let s = 0.1_f32;
|
||||
let ip = Vec3::new(ipx as f32, ipy as f32, ipz as f32);
|
||||
let s = 0.1_f64;
|
||||
let pts = vec![
|
||||
[ip.x - s, ip.y, ip.z],
|
||||
[ip.x + s, ip.y, ip.z],
|
||||
[ip.x, ip.y - s, ip.z],
|
||||
[ip.x, ip.y + s, ip.z],
|
||||
[ipx - s, ipy, ipz],
|
||||
[ipx + s, ipy, ipz],
|
||||
[ipx, ipy - s, ipz],
|
||||
[ipx, ipy + s, ipz],
|
||||
];
|
||||
(
|
||||
pts,
|
||||
|
||||
@@ -187,14 +187,14 @@ impl crate::entities::traits::FallbackTess for Ole2Frame {
|
||||
// OLE objects carry a bounding rectangle in model space.
|
||||
// Render a simple X-through-rectangle placeholder.
|
||||
let [ox, oy, oz] = world_offset;
|
||||
let x0 = (self.upper_left_corner.x - ox) as f32;
|
||||
let y0 = (self.lower_right_corner.y - oy) as f32;
|
||||
let x1 = (self.lower_right_corner.x - ox) as f32;
|
||||
let y1 = (self.upper_left_corner.y - oy) as f32;
|
||||
let z = (self.upper_left_corner.z - oz) as f32;
|
||||
let x0 = self.upper_left_corner.x - ox;
|
||||
let y0 = self.lower_right_corner.y - oy;
|
||||
let x1 = self.lower_right_corner.x - ox;
|
||||
let y1 = self.upper_left_corner.y - oy;
|
||||
let z = self.upper_left_corner.z - oz;
|
||||
if (x1 - x0).abs() < 1e-6 && (y1 - y0).abs() < 1e-6 {
|
||||
// Degenerate / unknown size — show a small cross.
|
||||
let s = 0.5_f32;
|
||||
let s = 0.5_f64;
|
||||
return (vec![[-s, 0.0, 0.0], [s, 0.0, 0.0]], vec![], vec![], vec![]);
|
||||
}
|
||||
let pts = vec![
|
||||
@@ -210,7 +210,7 @@ impl crate::entities::traits::FallbackTess for Ole2Frame {
|
||||
// Diagonal X
|
||||
[x0, y0, z],
|
||||
[x1, y1, z],
|
||||
[f32::NAN, f32::NAN, f32::NAN],
|
||||
[f64::NAN, f64::NAN, f64::NAN],
|
||||
[x1, y0, z],
|
||||
[x0, y1, z],
|
||||
];
|
||||
|
||||
@@ -551,11 +551,11 @@ impl crate::entities::traits::FallbackTess for Viewport {
|
||||
world_offset: [f64; 3],
|
||||
) -> crate::scene::convert::tess_util::FallbackGeometry {
|
||||
let [ox, oy, oz] = world_offset;
|
||||
let cx = (self.center.x - ox) as f32;
|
||||
let cy = (self.center.y - oy) as f32;
|
||||
let cz = (self.center.z - oz) as f32;
|
||||
let hw = (self.width / 2.0) as f32;
|
||||
let hh = (self.height / 2.0) as f32;
|
||||
let cx = self.center.x - ox;
|
||||
let cy = self.center.y - oy;
|
||||
let cz = self.center.z - oz;
|
||||
let hw = self.width / 2.0;
|
||||
let hh = self.height / 2.0;
|
||||
let pts = vec![
|
||||
[cx - hw, cy - hh, cz],
|
||||
[cx + hw, cy - hh, cz],
|
||||
|
||||
Reference in new issue
Block a user