nx_mesh_edit_test.nx source
↩ module page · 82 lines · 4133 B
1// nx_mesh_edit_test.nx -- KAT gate for the DCC modeling verbs. Closed-form
2// invariants only (no external oracle needed -- these are exact integer ops):
3// translate shifts the AABB, scale shrinks it, subdivide quadruples triangles
4// while preserving the AABB + validity, pyramid factory has the right counts +
5// extent. expect_exit: 0.
6
7import "nx_syscalls.nx"
8import "nx_mesh.nx"
9import "nx_mesh_edit.nx"
10
11func w(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
12func wn(v: i64) -> i64 {
13 let b: *u8 = sys_mmap(28); var m: i64 = v
14 if m < 0 { m = 0 - m; sys_write(1, "-" as *u8, 1) }
15 let t: *u8 = sys_mmap(28); var k: i64 = 0
16 if m == 0 { t[0] = 48 as u8; k = 1 }
17 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
18 var i: i64 = 0; while i < k { b[i] = t[k - 1 - i]; i = i + 1 }
19 sys_write(1, b, k); return 0
20}
21func chk(cond: i64, pass: *i64, fail: *i64, label: *u8) -> i64 {
22 if cond == 1 { pass[0] = pass[0] + 1; w(" ok " as *u8); w(label); w("\n" as *u8) }
23 else { fail[0] = fail[0] + 1; w(" XX " as *u8); w(label); w("\n" as *u8) }
24 return 0
25}
26func eqi(a: i64, b: i64) -> i64 { if a == b { return 1 } return 0 }
27
28func main() -> i64 {
29 let pass: *i64 = (sys_mmap(8)) as *i64
30 let fail: *i64 = (sys_mmap(8)) as *i64
31 pass[0] = 0
32 fail[0] = 0
33 let bb: *i64 = (sys_mmap(48)) as *i64
34 w("=== nx_mesh_edit KAT (Blender-class modeling verbs) ===\n" as *u8)
35
36 // --- TRANSLATE: cube +/-163840, shift +163840 in x -> x in [0, 327680] ---
37 let c1: *NxMesh = nx_mesh_make_cube(163840, 0)
38 nx_mesh_aabb(c1, bb)
39 chk(eqi(bb[0], 0 - 163840), pass, fail, "cube min_x = -10mm before translate" as *u8)
40 nx_mesh_translate(c1, 163840, 0, 0)
41 nx_mesh_aabb(c1, bb)
42 chk(eqi(bb[0], 0), pass, fail, "after +10mm x: min_x = 0" as *u8)
43 chk(eqi(bb[3], 327680), pass, fail, "after +10mm x: max_x = 20mm" as *u8)
44 chk(eqi(bb[1], 0 - 163840), pass, fail, "y untouched by x-translate" as *u8)
45
46 // --- SCALE: fresh cube, scale by 1/2 -> +/-81920 ---
47 let c2: *NxMesh = nx_mesh_make_cube(163840, 0)
48 nx_mesh_scale_rat(c2, 1, 2)
49 nx_mesh_aabb(c2, bb)
50 chk(eqi(bb[3], 81920), pass, fail, "scale 1/2: max_x = 5mm" as *u8)
51 chk(eqi(bb[0], 0 - 81920), pass, fail, "scale 1/2: min_x = -5mm" as *u8)
52 chk(eqi(nx_mesh_validate(c2), NX_MESH_OK), pass, fail, "scaled cube still valid" as *u8)
53
54 // --- SUBDIVIDE: cube 8v/12t -> 44v/48t, AABB preserved, valid ---
55 let c3: *NxMesh = nx_mesh_make_cube(163840, 0)
56 let s3: *NxMesh = nx_mesh_subdivide(c3)
57 w(" subdiv cube: verts=" as *u8); wn(s3.n_verts); w(" tris=" as *u8); wn(s3.n_tris); w("\n" as *u8)
58 chk(eqi(s3.n_tris, 48), pass, fail, "subdivide quadruples tris (12 -> 48)" as *u8)
59 chk(eqi(s3.n_verts, 44), pass, fail, "subdivide verts = 8 + 12*3 = 44" as *u8)
60 chk(eqi(nx_mesh_validate(s3), NX_MESH_OK), pass, fail, "subdivided mesh valid (indices in range)" as *u8)
61 nx_mesh_aabb(s3, bb)
62 chk(eqi(bb[3], 163840), pass, fail, "subdivide preserves AABB (max_x still 10mm)" as *u8)
63 chk(eqi(bb[0], 0 - 163840), pass, fail, "subdivide preserves AABB (min_x still -10mm)" as *u8)
64
65 // --- PYRAMID: 5v/6t, apex at z=20mm, base +/-10mm ---
66 let p: *NxMesh = nx_mesh_make_pyramid(163840, 327680, 0)
67 chk(eqi(p.n_verts, 5), pass, fail, "pyramid has 5 verts" as *u8)
68 chk(eqi(p.n_tris, 6), pass, fail, "pyramid has 6 tris" as *u8)
69 chk(eqi(nx_mesh_validate(p), NX_MESH_OK), pass, fail, "pyramid valid" as *u8)
70 nx_mesh_aabb(p, bb)
71 chk(eqi(bb[2], 0), pass, fail, "pyramid base at z=0" as *u8)
72 chk(eqi(bb[5], 327680), pass, fail, "pyramid apex at z=20mm" as *u8)
73
74 // --- SUBDIVIDE PYRAMID: 6t -> 24t, 5+18=23 verts ---
75 let sp: *NxMesh = nx_mesh_subdivide(p)
76 chk(eqi(sp.n_tris, 24), pass, fail, "subdivided pyramid 6 -> 24 tris" as *u8)
77 chk(eqi(sp.n_verts, 23), pass, fail, "subdivided pyramid 5 + 6*3 = 23 verts" as *u8)
78
79 w("=== VERDICT pass=" as *u8); wn(pass[0]); w(" fail=" as *u8); wn(fail[0]); w(" ===\n" as *u8)
80 if fail[0] == 0 { return 0 }
81 return 1
82}