From 11855933175242a5c3df5005661bebba7c54fb2f Mon Sep 17 00:00:00 2001 From: jess Date: Tue, 31 Mar 2026 13:14:57 -0700 Subject: [PATCH] fix SDF gradient bug, box axis assignment bug, strip dead code --- crates/cord-decompile/src/reconstruct.rs | 16 +++---- crates/cord-decompile/src/sparse_grid.rs | 2 +- crates/cord-trig/src/ir.rs | 3 +- crates/cord-trig/src/optimize.rs | 29 ++--------- crates/cord-trig/src/traverse.rs | 61 ++---------------------- 5 files changed, 19 insertions(+), 92 deletions(-) diff --git a/crates/cord-decompile/src/reconstruct.rs b/crates/cord-decompile/src/reconstruct.rs index 3389f3e..e89e479 100644 --- a/crates/cord-decompile/src/reconstruct.rs +++ b/crates/cord-decompile/src/reconstruct.rs @@ -104,8 +104,6 @@ fn merge_planes_into_boxes( let d2 = axis.dot(*p2); let half = (d1 - d2).abs() / 2.0; if half > 1e-6 { - let center_along_axis = (d1 + d2) / 2.0; - let _ = center_along_axis; pairs.push((ia, ib, axis, half)); used[ia] = true; used[ib] = true; @@ -236,18 +234,18 @@ fn align_box_axes( Vec3::new(0.0, 0.0, 1.0), ]; - // Assign each detected axis to the closest canonical axis let mut assignment = [0usize; 3]; - let mut assigned = [false; 3]; + let mut src_used = [false; 3]; + let mut dst_used = [false; 3]; - for pass in 0..3 { + for _ in 0..3 { let mut best_dot = 0.0f64; let mut best_src = 0; let mut best_dst = 0; for src in 0..3 { - if assignment[src] != 0 && pass > 0 { continue; } + if src_used[src] { continue; } for dst in 0..3 { - if assigned[dst] { continue; } + if dst_used[dst] { continue; } let d = axes[src].dot(canonical[dst]).abs(); if d > best_dot { best_dot = d; @@ -257,8 +255,8 @@ fn align_box_axes( } } assignment[best_src] = best_dst; - assigned[best_dst] = true; - let _ = pass; + src_used[best_src] = true; + dst_used[best_dst] = true; } let mut ordered = [0.0; 3]; diff --git a/crates/cord-decompile/src/sparse_grid.rs b/crates/cord-decompile/src/sparse_grid.rs index 5b97e05..3dd038a 100644 --- a/crates/cord-decompile/src/sparse_grid.rs +++ b/crates/cord-decompile/src/sparse_grid.rs @@ -150,7 +150,7 @@ fn sdf_gradient(mesh: &TriangleMesh, bvh: &BVH, p: Vec3) -> Vec3 { let dx = bvh.signed_distance(mesh, Vec3::new(p.x + eps, p.y, p.z)) - bvh.signed_distance(mesh, Vec3::new(p.x - eps, p.y, p.z)); let dy = bvh.signed_distance(mesh, Vec3::new(p.x, p.y + eps, p.z)) - - bvh.signed_distance(mesh, Vec3::new(p.x, p.y, p.z - eps)); + - bvh.signed_distance(mesh, Vec3::new(p.x, p.y - eps, p.z)); let dz = bvh.signed_distance(mesh, Vec3::new(p.x, p.y, p.z + eps)) - bvh.signed_distance(mesh, Vec3::new(p.x, p.y, p.z - eps)); Vec3::new(dx, dy, dz).normalized() diff --git a/crates/cord-trig/src/ir.rs b/crates/cord-trig/src/ir.rs index f196778..0a4e1a9 100644 --- a/crates/cord-trig/src/ir.rs +++ b/crates/cord-trig/src/ir.rs @@ -120,7 +120,8 @@ impl TrigGraph { TrigOp::Add(_, _) | TrigOp::Sub(_, _) | TrigOp::Neg(_) | TrigOp::Abs(_) | TrigOp::Min(_, _) | TrigOp::Max(_, _) | TrigOp::Clamp { .. } => cost.binary += 1, - _ => {} + TrigOp::InputX | TrigOp::InputY | TrigOp::InputZ + | TrigOp::Const(_) => {} } } cost diff --git a/crates/cord-trig/src/optimize.rs b/crates/cord-trig/src/optimize.rs index 5ed81b1..d6a59b1 100644 --- a/crates/cord-trig/src/optimize.rs +++ b/crates/cord-trig/src/optimize.rs @@ -1,5 +1,5 @@ use crate::ir::{NodeId, TrigGraph, TrigOp}; -use std::collections::{HashMap, HashSet}; +use std::collections::HashSet; /// Optimize a TrigGraph in-place. /// @@ -53,7 +53,7 @@ fn constant_fold(graph: &mut TrigGraph) { _ => None, } } - _ => None, + TrigOp::InputX | TrigOp::InputY | TrigOp::InputZ => None, }; if let Some(c) = val { @@ -96,28 +96,9 @@ fn fold2(values: &[Option], a: NodeId, b: NodeId, f: fn(f64, f64) -> f64) - // for the cost model and leave the graph structure intact. The CORDIC // compiler already recognizes shared-angle patterns. -fn fuse_sincos_pairs(graph: &mut TrigGraph) { - let mut sin_of: HashMap = HashMap::new(); - let mut cos_of: HashMap = HashMap::new(); - - for (i, op) in graph.nodes.iter().enumerate() { - match op { - TrigOp::Sin(a) => { sin_of.insert(*a, i as NodeId); } - TrigOp::Cos(a) => { cos_of.insert(*a, i as NodeId); } - _ => {} - } - } - - // Count fused pairs (both sin and cos of same angle exist) - let _fused: Vec<(NodeId, NodeId)> = sin_of.iter() - .filter_map(|(angle, sin_id)| { - cos_of.get(angle).map(|cos_id| (*sin_id, *cos_id)) - }) - .collect(); - - // The CORDIC compiler handles fusion; this pass is a no-op for now - // but validates that pairs exist. Future: rewrite to a fused op. -} +// Sin/cos pair fusion: placeholder for future CORDIC fused-op rewriting. +// The CORDIC compiler already recognizes shared-angle patterns. +fn fuse_sincos_pairs(_graph: &mut TrigGraph) {} // === Pass 3: Dead node elimination === diff --git a/crates/cord-trig/src/traverse.rs b/crates/cord-trig/src/traverse.rs index 5056ab0..031030a 100644 --- a/crates/cord-trig/src/traverse.rs +++ b/crates/cord-trig/src/traverse.rs @@ -108,15 +108,9 @@ fn traverse_sequential(graph: &TrigGraph, bounds: &EvalBounds) -> EvalResult { fn traverse_parallel_mesh( graph: &TrigGraph, bounds: &EvalBounds, - divisions: usize, - overlap: f64, + _divisions: usize, + _overlap: f64, ) -> EvalResult { - let center = [ - (bounds.min[0] + bounds.max[0]) * 0.5, - (bounds.min[1] + bounds.max[1]) * 0.5, - (bounds.min[2] + bounds.max[2]) * 0.5, - ]; - let res = bounds.resolution; let step = [ (bounds.max[0] - bounds.min[0]) / (res - 1).max(1) as f64, @@ -124,11 +118,6 @@ fn traverse_parallel_mesh( (bounds.max[2] - bounds.min[2]) / (res - 1).max(1) as f64, ]; - // Sector boundaries in spherical angles - let theta_step = PI / divisions as f64; - let phi_step = 2.0 * PI / divisions as f64; - let _overlap_angle = overlap * theta_step; - let mut values = Vec::with_capacity(res * res * res); for iz in 0..res { @@ -138,39 +127,8 @@ fn traverse_parallel_mesh( for ix in 0..res { let x = bounds.min[0] + ix as f64 * step[0]; - let dx = x - center[0]; - let dy = y - center[1]; - let dz = z - center[2]; - let r = (dx * dx + dy * dy + dz * dz).sqrt(); - let val = evaluate(graph, x, y, z); - - if r < 1e-10 { - values.push(SpatialSample { position: [x, y, z], value: val }); - continue; - } - - let theta = (dz / r).acos(); - let phi = dy.atan2(dx) + PI; - - // Determine which sector this point is in - let sector_t = (theta / theta_step).floor() as usize; - let sector_p = (phi / phi_step).floor() as usize; - - // Overlap zone blending - let t_frac = theta / theta_step - sector_t as f64; - let p_frac = phi / phi_step - sector_p as f64; - - let t_blend = if t_frac < overlap { t_frac / overlap } - else if t_frac > (1.0 - overlap) { (1.0 - t_frac) / overlap } - else { 1.0 }; - let p_blend = if p_frac < overlap { p_frac / overlap } - else if p_frac > (1.0 - overlap) { (1.0 - p_frac) / overlap } - else { 1.0 }; - - let blend = t_blend.min(1.0) * p_blend.min(1.0); - let _ = (sector_t, sector_p, blend); // Sector info for parallel dispatch - + // TODO: sector assignment + blend weights for actual parallel dispatch values.push(SpatialSample { position: [x, y, z], value: val }); } } @@ -216,8 +174,6 @@ fn traverse_spherical( continue; } - // Angular samples scale with r² (surface area of the shell) - let shell_area = 4.0 * PI * r * r; let angular_samples = (base_angular_samples as f64 * t * t).max(6.0) as usize; // Fibonacci sphere sampling for uniform angular distribution @@ -237,18 +193,9 @@ fn traverse_spherical( volume_count += 1; } - // Convergence check: RMS of volume vs surface area of current shell let rms = (volume_sum_sq / volume_count as f64).sqrt(); - - // Normalize both to comparable scales: - // RMS is in distance units, surface area is in distance² units. - // Compare RMS * r (information density scaled by radius) - // against shell_area / (4π) = r² (normalized surface area). - // Convergence when: rms * r >= r² → rms >= r - // Meaning: the average signal strength exceeds the current radius. - // More precisely: the information captured exceeds what the boundary can add. let volume_metric = rms * r; - let surface_metric = shell_area / (4.0 * PI); // = r² + let surface_metric = r * r; if volume_metric >= surface_metric && ri > radial_steps / 4 { convergence_radius = r;