code wiki / _hdl_build / nx_meshthick_gate.nx
nx_meshthick_gate.nx source
↩ module page · 110 lines · 6087 B
1// nx_meshthick_gate.nx -- teeth for R5 wall-thickness (cadtwin P6a, the geometric half of underbuilt-part
2// detection). T1 ray-triangle KAT (known hit distance + miss + parallel) = catches any fixed-point scale bug
3// at the primitive. T2 solid plate through-thickness = 2*hz. T3 argmin face is the thin (z) direction.
4// T4 solid cube uniform thickness > plate. T5 DATA-DRIVEN underbuilt classifier (threshold param, not
5// hardcoded): plate flagged, cube OK, and neg-control threshold flips the verdict = tracks the number.
6// T6 STL round-trip: measure thickness on a mesh loaded back from disk (real interchange). expect_exit: 0
7// license_tier: ORIGINAL
8import "nx_meshthick.nx"
9
10func mg_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
11func mg_putn(v: i64) -> i64 {
12 let bb: *u8 = sys_mmap(28)
13 var m: i64 = v
14 if m < 0 { mg_puts("-" as *u8); m = 0 - m }
15 let t: *u8 = sys_mmap(28)
16 var k: i64 = 0
17 if m == 0 { t[0] = 48 as u8; k = 1 }
18 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
19 var i: i64 = 0
20 while i < k { bb[i] = t[k - 1 - i]; i = i + 1 }
21 sys_write(1, bb, k)
22 return 0
23}
24func mg_tooth(name: *u8, pass: i64, fails: *i64) -> i64 {
25 mg_puts(" " as *u8); mg_puts(name); mg_puts(" -> " as *u8)
26 if pass == 1 { mg_puts("PASS\n" as *u8); return 0 }
27 mg_puts("FAIL\n" as *u8)
28 fails[0] = fails[0] + 1
29 return 0
30}
31func mg_near(a: i64, b: i64, tol: i64) -> i64 { var d: i64 = a - b; if d < 0 { d = 0 - d } if d <= tol { return 1 } return 0 }
32
33func main() -> i64 {
34 mg_puts("=== nx_meshthick_gate -- wall-thickness by ray-casting (underbuilt-part geometric detector) ===\n" as *u8)
35 let fails: *i64 = sys_mmap(8) as *i64
36 fails[0] = 0
37
38 // T1 ray-triangle KAT: triangle in plane z=1000 around origin
39 let ax: i64 = 0 - 2000
40 let ay: i64 = 0 - 2000
41 let bx: i64 = 2000
42 let by: i64 = 0 - 2000
43 let cxx: i64 = 0
44 let cyy: i64 = 2000
45 let hit: i64 = mtk_ray_tri(0, 0, 0, 0, 0, 256, ax, ay, 1000, bx, by, 1000, cxx, cyy, 1000)
46 let miss: i64 = mtk_ray_tri(0, 0, 0, 0, 0, 0 - 256, ax, ay, 1000, bx, by, 1000, cxx, cyy, 1000)
47 let par: i64 = mtk_ray_tri(0, 0, 0, 256, 0, 0, ax, ay, 1000, bx, by, 1000, cxx, cyy, 1000)
48 mg_puts(" ray-tri: hit t=" as *u8); mg_putn(hit); mg_puts(" (expect ~1000) miss=" as *u8); mg_putn(miss); mg_puts(" parallel=" as *u8); mg_putn(par); mg_puts("\n" as *u8)
49 var t1: i64 = 0
50 if mg_near(hit, 1000, 2) == 1 { if miss < 0 { if par < 0 { t1 = 1 } } }
51 let ig1: i64 = mg_tooth("T1 ray-triangle KAT (hit 1000, miss, parallel)" as *u8, t1, fails)
52
53 // T2/T3 solid PLATE: 8000 x 8000 x 600 (thin in z)
54 let plate: i64 = sys_mmap(m3_bytes()) as i64
55 m3_init(plate)
56 m3_box(plate, 0, 0, 0, 4000, 4000, 300)
57 let pf: *i64 = sys_mmap(8) as *i64
58 let pmin: i64 = mtk_min_thickness(plate, pf)
59 mg_puts(" plate min thickness=" as *u8); mg_putn(pmin); mg_puts(" (expect ~600) argmin face=" as *u8); mg_putn(pf[0]); mg_puts("\n" as *u8)
60 var t2: i64 = 0
61 if mg_near(pmin, 600, 4) == 1 { t2 = 1 }
62 let ig2: i64 = mg_tooth("T2 plate through-thickness == 2*hz (600)" as *u8, t2, fails)
63 // argmin face normal must be z-dominant (the thin direction)
64 let n3: *i64 = sys_mmap(32) as *i64
65 mtk_face_normal(plate, pf[0], n3)
66 var t3: i64 = 0
67 let nz: i64 = mtk_abs(n3[2])
68 if nz > mtk_abs(n3[0]) { if nz > mtk_abs(n3[1]) { t3 = 1 } }
69 mg_puts(" argmin normal=(" as *u8); mg_putn(n3[0]); mg_puts("," as *u8); mg_putn(n3[1]); mg_puts("," as *u8); mg_putn(n3[2]); mg_puts(")\n" as *u8)
70 let ig3: i64 = mg_tooth("T3 thinnest wall is the z (plate) direction" as *u8, t3, fails)
71
72 // T4 solid CUBE 8000^3 -> uniform thickness 8000
73 let cube: i64 = sys_mmap(m3_bytes()) as i64
74 m3_init(cube)
75 m3_box(cube, 0, 0, 0, 4000, 4000, 4000)
76 let cf: *i64 = sys_mmap(8) as *i64
77 let cmin: i64 = mtk_min_thickness(cube, cf)
78 mg_puts(" cube min thickness=" as *u8); mg_putn(cmin); mg_puts(" (expect ~8000)\n" as *u8)
79 var t4: i64 = 0
80 if mg_near(cmin, 8000, 8) == 1 { if cmin > pmin { t4 = 1 } }
81 let ig4: i64 = mg_tooth("T4 cube uniform thickness (8000) > plate" as *u8, t4, fails)
82
83 // T5 DATA-DRIVEN underbuilt classifier: threshold param drives the verdict
84 let thr_hi: i64 = 1000 // between plate(600) and cube(8000)
85 let thr_lo: i64 = 500 // below plate(600)
86 let plate_flag: i64 = mtk_is_underbuilt(pmin, thr_hi) // expect 1 UNDERBUILT
87 let cube_flag: i64 = mtk_is_underbuilt(cmin, thr_hi) // expect 0 OK
88 let plate_flag_lo: i64 = mtk_is_underbuilt(pmin, thr_lo) // expect 0 (threshold now below plate)
89 mg_puts(" @thr=1000: plate=" as *u8); mg_putn(plate_flag); mg_puts("(1=underbuilt) cube=" as *u8); mg_putn(cube_flag)
90 mg_puts(" @thr=500: plate=" as *u8); mg_putn(plate_flag_lo); mg_puts("\n" as *u8)
91 var t5: i64 = 0
92 if plate_flag == 1 { if cube_flag == 0 { if plate_flag_lo == 0 { t5 = 1 } } }
93 let ig5: i64 = mg_tooth("T5 data-driven underbuilt classifier tracks the threshold" as *u8, t5, fails)
94
95 // T6 STL round-trip: write the plate, read it back, re-measure
96 let wb: i64 = m3_write_stl(plate, "knowledge/mthk_plate.stl" as *u8)
97 let rl: i64 = sys_mmap(m3_bytes()) as i64
98 let nr: i64 = m3_read_stl(rl, "knowledge/mthk_plate.stl" as *u8)
99 let rf: *i64 = sys_mmap(8) as *i64
100 let rmin: i64 = mtk_min_thickness(rl, rf)
101 mg_puts(" STL bytes=" as *u8); mg_putn(wb); mg_puts(" reloaded tris=" as *u8); mg_putn(nr); mg_puts(" min thickness=" as *u8); mg_putn(rmin); mg_puts(" (expect ~600)\n" as *u8)
102 var t6: i64 = 0
103 if nr > 0 { if mg_near(rmin, 600, 4) == 1 { t6 = 1 } }
104 let ig6: i64 = mg_tooth("T6 thickness on a mesh round-tripped through STL" as *u8, t6, fails)
105
106 mg_puts("\nfails=" as *u8); mg_putn(fails[0]); mg_puts("\n" as *u8)
107 if fails[0] == 0 { mg_puts("GREEN -- wall-thickness detector 6/6 (ray-cast, data-driven underbuilt flag, STL interchange)\n" as *u8); return 0 }
108 mg_puts("RED\n" as *u8)
109 return 1
110}