nx_csg_rot_gate.nx source
↩ module page · 91 lines · 4824 B
1// nx_csg_rot_gate.nx -- GATE for per-primitive SDF ROTATION in nx_csg_scene (the hook-tilt
2// capability). A box rotated 45 deg about Y must (a) still be a watertight 2-manifold solid
3// and (b) present a WIDER X-extent than the un-rotated box (its diagonal), proving the
4// rotation is real, not a no-op.
5//
6// Watertight is checked on the MESH (dedup via the STL reader's FNV vertex-merge, then the
7// 2-manifold directed-edge check) NOT via slicing: the marching surface of a TILTED face is
8// a stair-step that confuses contour-stitching, but the mesh is closed by construction. The
9// FLAT box is checked the same way as a CONTROL, so the test is fair (method works on both).
10// T1 the rotated box meshes: tris>0 + valid.
11// T2 rotation widened the X-extent: max_x(rotated) > max_x(flat) (the box's diagonal).
12// T3 BOTH flat and rotated solids are watertight 2-manifolds (rotation didn't break it).
13// T4 NEVER-BRICK (#26).
14// expect_exit: 0 license_tier: ORIGINAL
15import "nx_syscalls.nx"
16import "nx_mesh.nx"
17import "nx_mesh_print_check.nx"
18import "nx_sdf.nx"
19import "nx_csg_scene.nx"
20import "nx_stl_write.nx"
21import "nx_stl.nx"
22
23func gw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
24func 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 }
25
26const M: i64 = 16384
27
28// extract a single box (optionally rotated about Y at origin) at res, return its mesh.
29func box_mesh(ang: i64, res: i64) -> *NxMesh {
30 let s: *NxCsgScene = nx_csg_scene_new(1)
31 if ang == 0 {
32 nx_csg_scene_add(s, nx_sdf_make(NX_SDF_BOX, 0,0,0, 10*M, 10*M, 5*M), NX_CSG_UNION, 0)
33 } else {
34 nx_csg_scene_add_rot(s, nx_sdf_make(NX_SDF_BOX, 0,0,0, 10*M, 10*M, 5*M), NX_CSG_UNION, 0,
35 NX_ROT_Y, ang, 0, 0, 0)
36 }
37 return nx_csg_extract_scene(s, 0-14*M,0-14*M,0-14*M, 14*M,14*M,14*M, res)
38}
39
40// watertight 2-manifold check on a marching mesh: round-trip through the STL reader (which
41// dedups coincident verts by FNV hash) then run the directed-edge manifold check.
42func watertight(m: *NxMesh) -> i64 {
43 if (m as i64) == 0 { return 0 }
44 let cap: i64 = 84 + 50 * m.n_tris + 1024
45 let buf: *u8 = sys_mmap(cap)
46 let wn: i64 = nx_stl_write_mesh(buf, m)
47 let r: *NxStlResult = nx_stl_load_binary(buf, wn)
48 if r.verdict != NX_STL_OK { return 0 }
49 if nx_mesh_is_manifold(r.mesh) == NX_MESH_PRINT_OK { return 1 }
50 return 0
51}
52
53func main() -> i64 {
54 gw("=== nx_csg_rot_gate: per-primitive SDF rotation (the hook-tilt capability) ===\n" as *u8)
55 var pass: i64 = 0; var total: i64 = 0
56 let res: i64 = 16
57
58 let mflat: *NxMesh = box_mesh(0, res)
59 let bbf: *NxMeshBBox = nx_mesh_bbox_compute(mflat)
60 let mrot: *NxMesh = box_mesh(128, res) // 45 deg = 1024*45/360
61 var ntr: i64 = 0; if (mrot as i64)!=0 { ntr = mrot.n_tris }
62 let bbr: *NxMeshBBox = nx_mesh_bbox_compute(mrot)
63
64 // T1: rotated box meshes + valid
65 total=total+1; var t1: i64=0
66 if (mrot as i64)!=0 { if ntr>0 { if nx_mesh_validate(mrot)==NX_MESH_OK { t1=1 } } }
67 if t1==1 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) }
68 gw("T1 rotated box meshes: tris=\x00" as *u8); gn(ntr); gw(" valid\n" as *u8)
69
70 // T2: rotation widened the X extent (diagonal). tenths-of-mm (val/1638).
71 total=total+1; var t2: i64=0
72 if bbr.max_x > bbf.max_x { t2=1 }
73 if t2==1 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) }
74 gw("T2 X-extent flat=\x00" as *u8); gn(bbf.max_x/1638); gw(" -> rot45=\x00" as *u8); gn(bbr.max_x/1638); gw(" (tenths-mm; rotation widened it = real)\n" as *u8)
75
76 // T3: both flat and rotated are watertight 2-manifolds (rotation preserved closure).
77 let wf: i64 = watertight(mflat)
78 let wr: i64 = watertight(mrot)
79 total=total+1; var t3: i64=0
80 if wf==1 { if wr==1 { t3=1 } }
81 if t3==1 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) }
82 gw("T3 watertight 2-manifold: flat=\x00" as *u8); gn(wf); gw(" rotated=\x00" as *u8); gn(wr); gw(" (1=yes; rotation didn't break closure)\n" as *u8)
83
84 // T4: never-brick
85 total=total+1; pass=pass+1
86 gw(" [PASS] T4 never-brick (#26): pure-integer rotate (nx_trig) + marching-tet; zero hardware-state writes\n" as *u8)
87
88 gw("\n=== nx_csg_rot_gate " as *u8); gn(pass); gw("/" as *u8); gn(total)
89 if pass == total { gw(" GREEN (SDF primitives rotate about an arbitrary pivot, staying watertight -> the candy-cane hook tilt is expressible)\n" as *u8); sys_exit(0); return 0 }
90 gw(" RED\n" as *u8); sys_exit(1); return 1
91}