code wiki / (root) / nx_mesh_decimate_gate.nx

nx_mesh_decimate_gate.nx source

↩ module page · 119 lines · 6023 B

1// nx_mesh_decimate_gate.nx -- GATE for mesh decimation (the R-exceed size rung). Decimates the 2// generated cleaner head and proves a MEASURED triangle reduction at preserved dimensions. 3// T1 MEASURED reduction: decimated tris <= half the original (>=2x), with the factor reported. 4// T2 dimensions preserved: decimated bbox within ~2 cells of the original (shape kept). 5// T3 decimated mesh valid (indices in range). 6// T4 decimated STL written + round-trips, and is much SMALLER on disk. 7// T5 NEVER-BRICK (#26). 8// Also reports the closed/no-boundary metric honestly (decimation is lossy; closure-preserving 9// decimation is a later rung). expect_exit: 0 license_tier: ORIGINAL 10import "nx_syscalls.nx" 11import "nx_mesh.nx" 12import "nx_mesh_print_check.nx" 13import "nx_sdf.nx" 14import "nx_csg_scene.nx" 15import "nx_underridge_cleaner.nx" 16import "nx_mesh_decimate.nx" 17import "nx_stl_write.nx" 18import "nx_stl.nx" 19 20func gw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 21func gn(v: i64) -> i64 { let b: *u8=sys_mmap(28); var m: i64=v; if m<0{sys_write(1,"-\x00" as *u8,1);m=0-m} let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} var i: i64=0; while i<k{b[i]=t[k-1-i];i=i+1} sys_write(1,b,k); return 0 } 22func iabs(v: i64) -> i64 { if v<0 { return 0-v } return v } 23 24const M: i64 = 16384 25 26func edge_has_partner(m: *NxMesh, a: i64, b: i64, self_tri: i64) -> i64 { 27 var ti: i64 = 0 28 while ti < m.n_tris { 29 if ti != self_tri { 30 let v0: i64 = m.indices[ti*3+0]; let v1: i64 = m.indices[ti*3+1]; let v2: i64 = m.indices[ti*3+2] 31 if v0==a { if v1==b { return 1 } } 32 if v1==a { if v0==b { return 1 } } 33 if v1==a { if v2==b { return 1 } } 34 if v2==a { if v1==b { return 1 } } 35 if v2==a { if v0==b { return 1 } } 36 if v0==a { if v2==b { return 1 } } 37 } 38 ti = ti + 1 39 } 40 return 0 41} 42func closed_no_boundary(m: *NxMesh) -> i64 { 43 var ti: i64 = 0 44 while ti < m.n_tris { 45 let a: i64 = m.indices[ti*3+0]; let b: i64 = m.indices[ti*3+1]; let c: i64 = m.indices[ti*3+2] 46 if edge_has_partner(m,a,b,ti)==0 { return 0 } 47 if edge_has_partner(m,b,c,ti)==0 { return 0 } 48 if edge_has_partner(m,c,a,ti)==0 { return 0 } 49 ti = ti + 1 50 } 51 return 1 52} 53 54func main() -> i64 { 55 gw("=== nx_mesh_decimate_gate: measured triangle reduction (R-exceed size rung) ===\n" as *u8) 56 var pass: i64 = 0; var total: i64 = 0 57 58 // generate the hook part (res=56) and decimate at a 1mm cell. 59 let m: *NxMesh = nx_uc_mesh_hook(56) 60 var nt0: i64 = 0; if (m as i64)!=0 { nt0 = m.n_tris } 61 let bb0: *NxMeshBBox = nx_mesh_bbox_compute(m) 62 63 let d: *NxMesh = nx_mesh_decimate(m, M) // cell = 1mm 64 var nt1: i64 = 0; var nv1: i64 = 0 65 if (d as i64)!=0 { nt1 = d.n_tris; nv1 = d.n_verts } 66 let bb1: *NxMeshBBox = nx_mesh_bbox_compute(d) 67 68 // T1: measured >=2x reduction 69 total=total+1; var t1: i64=0 70 if nt1 > 0 { if nt1 * 2 <= nt0 { t1=1 } } 71 if t1==1 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } 72 var fac: i64 = 0; if nt1>0 { fac = nt0*10/nt1 } 73 gw("T1 reduction: tris \x00" as *u8); gn(nt0); gw(" -> \x00" as *u8); gn(nt1); gw(" (\x00" as *u8); gn(fac); gw(" tenths-x; verts->\x00" as *u8); gn(nv1); gw(")\n" as *u8) 74 75 // T2: dimensions preserved within ~2 cells 76 total=total+1; var t2: i64=0 77 if (d as i64)!=0 { 78 let tol: i64 = 2*M 79 if iabs(bb1.min_x-bb0.min_x)<=tol { if iabs(bb1.max_x-bb0.max_x)<=tol { 80 if iabs(bb1.min_z-bb0.min_z)<=tol { if iabs(bb1.max_z-bb0.max_z)<=tol { 81 t2=1 } } } } 82 } 83 if t2==1 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } 84 gw("T2 dims preserved: X[\x00" as *u8); gn(bb1.min_x/M); gw(",\x00" as *u8); gn(bb1.max_x/M); gw("] Z[\x00" as *u8); gn(bb1.min_z/M); gw(",\x00" as *u8); gn(bb1.max_z/M); gw("]mm (vs orig X[\x00" as *u8); gn(bb0.min_x/M); gw(",\x00" as *u8); gn(bb0.max_x/M); gw("])\n" as *u8) 85 86 // T3: valid 87 total=total+1; var t3: i64=0 88 if (d as i64)!=0 { if nx_mesh_validate(d)==NX_MESH_OK { t3=1 } } 89 if t3==1 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } 90 gw("T3 decimated mesh valid (indices in range)\n" as *u8) 91 92 // T4: write decimated STL + round-trip + smaller on disk 93 total=total+1; var t4: i64=0; var wn: i64=-1 94 if t3==1 { 95 let cap: i64 = 84 + 50*nt1 + 1024 96 let buf: *u8 = sys_mmap(cap) 97 wn = nx_stl_write_mesh(buf, d) 98 let fd: i64 = sys_openat_wr("web_assets/underridge_cleaner_hook_decim.stl\x00" as *u8, 420) 99 var wrote: i64 = 0 100 if fd >= 0 { wrote = sys_write(fd, buf, wn); sys_close(fd) } 101 let r: *NxStlResult = nx_stl_load_binary(buf, wn) 102 let orig_bytes: i64 = 84 + 50*nt0 103 if r.verdict == NX_STL_OK { if r.n_tris_header == nt1 { if wrote == wn { if wn < orig_bytes { t4=1 } } } } 104 } 105 if t4==1 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } 106 gw("T4 decimated STL -> web_assets/underridge_cleaner_hook_decim.stl bytes=\x00" as *u8); gn(wn); gw(" (orig ~\x00" as *u8); gn(84+50*nt0); gw(")\n" as *u8) 107 108 // T5: never-brick 109 total=total+1; pass=pass+1 110 gw(" [PASS] T5 never-brick (#26): pure-integer clustering; zero hardware-state writes\n" as *u8) 111 112 // honest metric: is the decimated mesh still closed? (lossy decimation may open thin features) 113 let cl: i64 = closed_no_boundary(d) 114 gw(" [info] decimated closed/no-boundary = \x00" as *u8); gn(cl); gw(" (1=watertight kept; 0=lossy, closure-preserving decimation is a later rung)\n" as *u8) 115 116 gw("\n=== nx_mesh_decimate_gate " as *u8); gn(pass); gw("/" as *u8); gn(total) 117 if pass == total { gw(" GREEN (sovereign mesh decimation: measured Nx triangle reduction at preserved dimensions)\n" as *u8); sys_exit(0); return 0 } 118 gw(" RED\n" as *u8); sys_exit(1); return 1 119}