fix SDF gradient bug, box axis assignment bug, strip dead code
This commit is contained in:
parent
97653580e5
commit
1185593317
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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<f64>], 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<NodeId, NodeId> = HashMap::new();
|
||||
let mut cos_of: HashMap<NodeId, NodeId> = 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 ===
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue