code wiki / _hdl_build / nx_meshseg3d_gate.nx
nx_meshseg3d_gate.nx source
↩ module page · 99 lines · 4805 B
1// nx_meshseg3d_gate.nx -- benchmark 3D part segmentation (cadtwin P2). Known meshes -> correct segment count:
2// CONNECTIVITY (2 separate boxes -> 2 parts), CREASE split (1 box, cos>0.5 -> 6 faces), CREASE merge (1 box,
3// cos>-0.9 -> 1 part), DATA-DRIVEN threshold controls granularity, determinism. Segment = decompose a scanned
4// mesh into parts for per-part analysis. expect_exit: 0 license_tier: ORIGINAL
5import "nx_meshseg3d.nx"
6
7func sg_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
8func sg_putn(v: i64) -> i64 {
9 let bb: *u8 = sys_mmap(28)
10 var m: i64 = v
11 if m < 0 { sg_puts("-" as *u8); m = 0 - m }
12 let t: *u8 = sys_mmap(28)
13 var k: i64 = 0
14 if m == 0 { t[0] = 48 as u8; k = 1 }
15 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
16 var i: i64 = 0
17 while i < k { bb[i] = t[k - 1 - i]; i = i + 1 }
18 sys_write(1, bb, k)
19 return 0
20}
21func sg_tooth(name: *u8, pass: i64, fails: *i64) -> i64 {
22 sg_puts(" " as *u8); sg_puts(name); sg_puts(" -> " as *u8)
23 if pass == 1 { sg_puts("PASS\n" as *u8); return 0 }
24 sg_puts("FAIL\n" as *u8)
25 fails[0] = fails[0] + 1
26 return 0
27}
28
29func main() -> i64 {
30 sg_puts("=== nx_meshseg3d_gate -- 3D part segmentation (connectivity + crease region-growing) ===\n" as *u8)
31 let fails: *i64 = sys_mmap(8) as *i64
32 fails[0] = 0
33 let labels: *i64 = sys_mmap(4096) as *i64
34
35 // T1 CONNECTIVITY: two SEPARATE boxes -> 2 parts (grow across everything within each; boxes disjoint)
36 let two: i64 = sys_mmap(m3_bytes()) as i64
37 m3_init(two)
38 m3_box(two, 0, 0, 0, 500, 500, 500) // box A
39 m3_box(two, 3000, 0, 0, 500, 500, 500) // box B (far, not touching)
40 let hh: *i64 = m3_hdr(two)
41 let nseg1: i64 = ms_segment(two, 0 - 300, labels) // thresh -300 = pure connectivity
42 sg_puts(" two separate boxes: faces=" as *u8); sg_putn(hh[1]); sg_puts(" segments=" as *u8); sg_putn(nseg1); sg_puts(" (expect 2)\n" as *u8)
43 var t1: i64 = 0
44 if nseg1 == 2 { t1 = 1 }
45 let ig1: i64 = sg_tooth("T1 connectivity: 2 disjoint boxes -> 2 parts" as *u8, t1, fails)
46
47 // T2 CREASE split: one box, cos>0.5 (thresh 128) -> each of 6 faces is a segment (90deg edges = creases)
48 let box: i64 = sys_mmap(m3_bytes()) as i64
49 m3_init(box)
50 m3_box(box, 0, 0, 0, 600, 600, 600)
51 let nseg2: i64 = ms_segment(box, 128, labels)
52 sg_puts(" box crease cos>0.5: segments=" as *u8); sg_putn(nseg2); sg_puts(" (expect 6 = the 6 faces)\n" as *u8)
53 var t2: i64 = 0
54 if nseg2 == 6 { t2 = 1 }
55 let ig2: i64 = sg_tooth("T2 crease split: box -> 6 face-parts" as *u8, t2, fails)
56
57 // T3 CREASE merge: one box, cos>-0.9 (thresh -230) -> 90deg edges are smooth-enough -> 1 part
58 let nseg3: i64 = ms_segment(box, 0 - 230, labels)
59 sg_puts(" box crease cos>-0.9: segments=" as *u8); sg_putn(nseg3); sg_puts(" (expect 1 = whole box)\n" as *u8)
60 var t3: i64 = 0
61 if nseg3 == 1 { t3 = 1 }
62 let ig3: i64 = sg_tooth("T3 crease merge: box -> 1 part" as *u8, t3, fails)
63
64 // T4 DATA-DRIVEN: threshold controls granularity (already shown 6 vs 1); assert they DIFFER
65 var t4: i64 = 0
66 if nseg2 != nseg3 { if nseg2 > nseg3 { t4 = 1 } }
67 let ig4: i64 = sg_tooth("T4 data-driven threshold controls granularity (6 != 1)" as *u8, t4, fails)
68
69 // T5 determinism
70 let l2: *i64 = sys_mmap(4096) as *i64
71 let nseg2b: i64 = ms_segment(box, 128, l2)
72 var t5: i64 = 0
73 if nseg2b == nseg2 {
74 var same: i64 = 1
75 var i: i64 = 0
76 while i < hh[1] { if l2[i] != labels[i] { same = 0 } i = i + 1 }
77 // note labels was overwritten by T3/T4; re-run T2 into labels for a fair compare
78 i = 0
79 }
80 let nseg2c: i64 = ms_segment(box, 128, labels)
81 let nseg2d: i64 = ms_segment(box, 128, l2)
82 var t5b: i64 = 0
83 if nseg2c == nseg2d {
84 var same2: i64 = 1
85 var j: i64 = 0
86 let bh: *i64 = m3_hdr(box)
87 while j < bh[1] { if labels[j] != l2[j] { same2 = 0 } j = j + 1 }
88 if same2 == 1 { t5b = 1 }
89 }
90 let ig5: i64 = sg_tooth("T5 deterministic (same labels)" as *u8, t5b, fails)
91
92 sg_puts("\nSOTA CONTEXT: neural 3D part-seg (SAMPart3D/PartField/GeoSAM2, PartObjaverse-Tiny mIoU ~84) = trained-\n" as *u8)
93 sg_puts("model-bound; classical connectivity+crease region-growing = the sovereign first rung (geometric parts,\n" as *u8)
94 sg_puts("not semantic). Composes: segment a scanned car -> per-part wall-thickness (nx_meshthick) + underbuilt flag.\n" as *u8)
95 sg_puts("\nfails=" as *u8); sg_putn(fails[0]); sg_puts("\n" as *u8)
96 if fails[0] == 0 { sg_puts("GREEN -- 3D part segmentation 5/5 (connectivity + data-driven crease)\n" as *u8); return 0 }
97 sg_puts("RED\n" as *u8)
98 return 1
99}