nx_visual_hull_gate.nx source
↩ module page · 121 lines · 6082 B
1// nx_visual_hull_gate.nx -- liar-killed GATE for silhouette -> 3D form.
2//
3// Proven against SYNTHETIC silhouettes of a KNOWN shape, so the carver is verified end-to-end with
4// no photograph required: two orthogonal views of a square column must intersect to a box.
5//
6// ★THE TOOTH THAT MATTERS is T6: with ONE view folded in, a point far along the VIEW axis must
7// still read INSIDE, because a single silhouette cannot constrain depth. That is the mechanical
8// statement of why an anterior + posterior pair is ONE shape constraint and not two -- both project
9// along the same axis, so the second image adds albedo, not form. Asserting that in a comment is an
10// opinion; T6 makes it a measurement.
11//
12// Tooth total is DERIVED; G_MIN_TEETH is a floor so a deleted tooth trips RED.
13// license_tier: ORIGINAL expect_exit: 0
14import "nx_visual_hull.nx"
15
16const G_MIN_TEETH: i64 = 12
17const IW: i64 = 128
18const IH: i64 = 128
19const GN: i64 = 16
20const CELL: i64 = 64
21const ORG: i64 = 0 - 512
22
23func g_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
24func g_putn(v: i64) -> i64 {
25 if v == 0 { sys_write(1, "0" as *u8, 1); return 0 }
26 var m: i64 = v
27 if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m }
28 let d: *u8 = sys_mmap(24); var k: i64 = 0
29 while m > 0 { d[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
30 let o: *u8 = sys_mmap(24); var w: i64 = 0
31 while w < k { o[w] = d[k-1-w]; w = w + 1 }
32 sys_write(1, o, k)
33 sys_munmap(d, 24); sys_munmap(o, 24)
34 return 0
35}
36func g_bool(name: *u8, got: i64, want: i64, passp: *i64) -> i64 {
37 passp[1] = passp[1] + 1
38 g_puts("T " as *u8); g_puts(name); g_puts(" got=" as *u8); g_putn(got)
39 if got == want { g_puts(" PASS\n" as *u8); passp[0] = passp[0] + 1 } else { g_puts(" want=" as *u8); g_putn(want); g_puts(" FAIL\n" as *u8) }
40 return 0
41}
42// grid lookup at a world point (nearest corner)
43func g_at(grid: *i64, wx: i64, wy: i64, wz: i64) -> i64 {
44 let i: i64 = (wx - ORG) / CELL
45 let j: i64 = (wy - ORG) / CELL
46 let k: i64 = (wz - ORG) / CELL
47 if i < 0 { return 999999 }
48 if j < 0 { return 999999 }
49 if k < 0 { return 999999 }
50 if i > GN { return 999999 }
51 if j > GN { return 999999 }
52 if k > GN { return 999999 }
53 return grid[(i * (GN+1) + j) * (GN+1) + k]
54}
55func g_sign(v: i64) -> i64 { if v < 0 { return 0 - 1 } if v > 0 { return 1 } return 0 }
56
57func main() -> i64 {
58 let pass: *i64 = sys_mmap(16) as *i64
59 pass[0] = 0
60 pass[1] = 0
61
62 // ---- synthetic studio plate: dark backdrop, bright centred column ---------------------------
63 let rgb: *u8 = sys_mmap(IW * IH * 3)
64 var y: i64 = 0
65 while y < IH {
66 var x: i64 = 0
67 while x < IW {
68 let o: i64 = (y * IW + x) * 3
69 var on: i64 = 0
70 if x >= 48 { if x < 80 { if y >= 20 { if y < 108 { on = 1 } } } }
71 if on == 1 { rgb[o] = 220 as u8; rgb[o+1] = 200 as u8; rgb[o+2] = 190 as u8 }
72 else { rgb[o] = 20 as u8; rgb[o+1] = 20 as u8; rgb[o+2] = 24 as u8 }
73 x = x + 1
74 }
75 y = y + 1
76 }
77 let mask: *u8 = sys_mmap(IW * IH)
78 let fg: i64 = vh_bg_mask(rgb, IW, IH, 90, mask)
79 // the column is 32 x 88 = 2816 px
80 g_bool("bg-mask-segments-2816px" as *u8, fg, 2816, pass)
81 g_bool("bg-mask-centre-is-subject" as *u8, mask[64 * IW + 64] as i64, 1, pass)
82 g_bool("bg-mask-corner-is-background" as *u8, mask[0] as i64, 0, pass)
83
84 let f2d: *i64 = sys_mmap(IW * IH * 8) as *i64
85 vh_sdf2d(mask, IW, IH, f2d)
86 g_bool("sdf2d-negative-inside" as *u8, g_sign(f2d[64 * IW + 64]), 0 - 1, pass)
87 g_bool("sdf2d-positive-outside" as *u8, g_sign(f2d[64 * IW + 8]), 1, pass)
88
89 // ---- carve with TWO ORTHOGONAL views -> a box -----------------------------------------------
90 let gn1: i64 = GN + 1
91 let grid: *i64 = sys_mmap(gn1 * gn1 * gn1 * 8) as *i64
92 // front: looks along +z, horizontal image axis = world x -> (cos,sin) = (1024, 0)
93 vh_carve_view(f2d, IW, IH, 1024, 0, grid, GN, GN, GN, ORG, ORG, ORG, CELL, 64, 64, 0, 0, 128, 1)
94 // lateral: rotated 90deg, horizontal image axis = world z -> (cos,sin) = (0, 1024)
95 vh_carve_view(f2d, IW, IH, 0, 1024, grid, GN, GN, GN, ORG, ORG, ORG, CELL, 64, 64, 0, 0, 128, 0)
96 g_bool("carve-origin-is-inside" as *u8, g_sign(g_at(grid, 0, 0, 0)), 0 - 1, pass)
97 g_bool("carve-outside-in-x-is-outside" as *u8, g_sign(g_at(grid, 384, 0, 0)), 1, pass)
98 // THE INTERSECTION: the second view is what makes depth finite
99 g_bool("carve-outside-in-z-is-outside" as *u8, g_sign(g_at(grid, 0, 0, 384)), 1, pass)
100 g_bool("carve-high-y-outside-column" as *u8, g_sign(g_at(grid, 0, 448, 0)), 1, pass)
101
102 // ---- T6: ONE view cannot constrain depth ----------------------------------------------------
103 // Front view ALONE. A point far along +z must STILL be inside: a silhouette back-projects to an
104 // infinite prism. This is exactly why anterior+posterior (same axis) is one constraint, not two.
105 let grid1: *i64 = sys_mmap(gn1 * gn1 * gn1 * 8) as *i64
106 vh_carve_view(f2d, IW, IH, 1024, 0, grid1, GN, GN, GN, ORG, ORG, ORG, CELL, 64, 64, 0, 0, 128, 1)
107 g_bool("single-view-origin-inside" as *u8, g_sign(g_at(grid1, 0, 0, 0)), 0 - 1, pass)
108 g_bool("NEG-single-view-cannot-constrain-depth" as *u8, g_sign(g_at(grid1, 0, 0, 384)), 0 - 1, pass)
109
110 // ---- refusals -------------------------------------------------------------------------------
111 let bad: i64 = vh_carve_view(f2d, IW, IH, 1024, 0, grid, GN, GN, GN, ORG, ORG, ORG, CELL, 64, 64, 0, 0, 0, 1)
112 g_bool("refuses-zero-scale" as *u8, bad, 0 - 1, pass)
113 let badm: i64 = vh_bg_mask(rgb, 0, IH, 90, mask)
114 g_bool("refuses-zero-width-plate" as *u8, badm, 0 - 1, pass)
115
116 g_puts("VISUAL-HULL-GATE pass=" as *u8); g_putn(pass[0]); g_puts("/" as *u8); g_putn(pass[1]); g_puts(" verdict=" as *u8)
117 if pass[1] < G_MIN_TEETH { g_puts("RED reason=teeth_deleted\n" as *u8); return 1 }
118 if pass[0] == pass[1] { g_puts("GREEN\n" as *u8); return 0 }
119 g_puts("RED\n" as *u8)
120 return 1
121}