code wiki / _hdl_build / nx_cadtwin_report.nx

nx_cadtwin_report.nx source

↩ module page · 197 lines · 7820 B

1// nx_cadtwin_report.nx -- THE TWIN REPORT (cadtwin capstone): compose every gated organ into one per-PART 2// engineering report from a raw STEP file. Part attribution comes from the FILE'S OWN semantics (engineering- 3// twin doctrine: file truth over geometric guessing): SHAPE_DEFINITION_REPRESENTATION -> PRODUCT_DEFINITION -> 4// PRODUCT name, and SDR -> ADVANCED_BREP_SHAPE_REPRESENTATION -> MANIFOLD_SOLID_BREP -> CLOSED_SHELL -> faces. 5// Per part: tessellate ITS faces (nx_step_tess planar + nx_step_nurbs round) into a per-part mesh -> WELD 6// duplicate vertices (new mw-helper; per-face tessellation emits copies -- welding makes meshseg3d/meshthick 7// correct on real tess output) -> measure: bbox (dual-dimensioned mm + thou via nx_unitconv), wall thickness 8// (nx_meshthick), shape-class descriptor (nx_partid), connectivity components (nx_meshseg3d), disassembly rank 9// (nx_assemseq). COMPOSES 9 organs; every number measured, coverage counted honestly. license_tier: ORIGINAL 10import "nx_step_tess2.nx" 11import "nx_meshseg3d.nx" 12import "nx_partid.nx" 13import "nx_unitconv.nx" 14import "nx_assemseq.nx" 15const K_MAGIC_7919: i64 = 7919 16const K_MAGIC_104729: i64 = 104729 17 18// ---- vertex WELD: merge exact-duplicate vertices, compact, rewrite tris, drop degenerates. Returns new nverts. 19func cr_weld(mesh: i64) -> i64 { 20 let h: *i64 = m3_hdr(mesh) 21 let nv: i64 = h[0] 22 if nv == 0 { return 0 } 23 let map: *i64 = sys_mmap(nv * 8 + 64) as *i64 24 let newi: *i64 = sys_mmap(nv * 8 + 64) as *i64 25 var i: i64 = 0 26 while i < nv { 27 map[i] = i 28 var j: i64 = 0 29 var go: i64 = 1 30 while go == 1 { 31 if j >= i { go = 0 } else { 32 let a: *i64 = m3_vert(mesh, i) 33 let b: *i64 = m3_vert(mesh, j) 34 if a[0] == b[0] { if a[1] == b[1] { if a[2] == b[2] { map[i] = j; go = 0 } } } 35 j = j + 1 36 } 37 } 38 i = i + 1 39 } 40 // compact canonicals in order 41 var used: i64 = 0 42 i = 0 43 while i < nv { 44 if map[i] == i { 45 newi[i] = used 46 let src: *i64 = m3_vert(mesh, i) 47 let dst: *i64 = m3_vert(mesh, used) 48 dst[0] = src[0]; dst[1] = src[1]; dst[2] = src[2] 49 used = used + 1 50 } 51 i = i + 1 52 } 53 // rewrite tris via canonical->new, drop degenerates 54 let ntr: i64 = h[1] 55 var w: i64 = 0 56 var t: i64 = 0 57 while t < ntr { 58 let tr: *i64 = m3_tri(mesh, t) 59 let a: i64 = newi[map[tr[0]]] 60 let b: i64 = newi[map[tr[1]]] 61 let c: i64 = newi[map[tr[2]]] 62 if a != b { if b != c { if a != c { 63 let dw: *i64 = m3_tri(mesh, w) 64 dw[0] = a; dw[1] = b; dw[2] = c 65 w = w + 1 66 } } } 67 t = t + 1 68 } 69 h[0] = used 70 h[1] = w 71 return used 72} 73 74// ---- find the 5 solid parts from the file: SDR whose rep is an ABSR. Fills (per part, stride 1): 75// pdid[], prodidx[], shellidx[]. Returns part count. 76func cr_find_parts(st: *i64, pdid: *i64, prodidx: *i64, shellidx: *i64) -> i64 { 77 let out2: *i64 = st[9] as *i64 78 var np: i64 = 0 79 let cnt: i64 = st[7] 80 var idx: i64 = 0 81 while idx < cnt { 82 if sp_name_is(st, idx, "SHAPE_DEFINITION_REPRESENTATION" as *u8) == 1 { 83 let repid: i64 = sgt_arg_ref(st, idx, 1, out2) 84 if repid >= 0 { 85 let repidx: i64 = sp_find(st, repid) 86 if repidx >= 0 { if sp_name_is(st, repidx, "ADVANCED_BREP_SHAPE_REPRESENTATION" as *u8) == 1 { 87 // PDS -> PD 88 let pdsid: i64 = sgt_arg_ref(st, idx, 0, out2) 89 if pdsid >= 0 { 90 let pdsidx: i64 = sp_find(st, pdsid) 91 if pdsidx >= 0 { 92 let pd: i64 = sgt_arg_ref(st, pdsidx, 2, out2) 93 let pidx: i64 = sp_pd_product(st, pd) 94 // ABSR args -> the MANIFOLD_SOLID_BREP ref -> shell 95 let refs: *i64 = sys_mmap(64) as *i64 96 let aao: *i64 = st[5] as *i64 97 let aal: *i64 = st[6] as *i64 98 let nr: i64 = sgt_refs(st[0] as *u8, aao[repidx], aal[repidx], refs, 8) 99 var k: i64 = 0 100 var shidx: i64 = 0 - 1 101 while k < nr { 102 let ridx: i64 = sp_find(st, refs[k]) 103 if ridx >= 0 { if sp_name_is(st, ridx, "MANIFOLD_SOLID_BREP" as *u8) == 1 { 104 let shid: i64 = sgt_arg_ref(st, ridx, 1, out2) 105 if shid >= 0 { shidx = sp_find(st, shid) } 106 } } 107 k = k + 1 108 } 109 if pidx >= 0 { if shidx >= 0 { if np < 8 { 110 pdid[np] = pd 111 prodidx[np] = pidx 112 shellidx[np] = shidx 113 np = np + 1 114 } } } 115 } 116 } 117 } } 118 } 119 } 120 idx = idx + 1 121 } 122 return np 123} 124 125// ---- tessellate ONE part's shell faces into mesh (tt=planar-v2 ctx, nt=nurbs ctx, t2=curve ctx, slab=bound 126// storage; all pointed at the part mesh). v2 planar path = COMPLETE (B-spline/Bezier/circle edges + hole 127// bridging -> 53/53 coverage). out4: [0]=faces_total [1]=tessellated [2]=planar_done [3]=round_done 128func cr_tess_part(tt: *i64, nt: *i64, t2: *i64, slab: *i64, shellidx: i64, out4: *i64) -> i64 { 129 let st: *i64 = tt[0] as *i64 130 let anl: *i64 = st[4] as *i64 131 let aao: *i64 = st[5] as *i64 132 let aal: *i64 = st[6] as *i64 133 let c: *i64 = tt[2] as *i64 134 let c2: *i64 = nt[2] as *i64 135 let faces: *i64 = sys_mmap(512) as *i64 136 let nf: i64 = sgt_refs(st[0] as *u8, aao[shellidx], aal[shellidx], faces, 64) 137 out4[0] = nf 138 out4[1] = 0 139 out4[2] = 0 140 out4[3] = 0 141 let out2: *i64 = tt[8] as *i64 142 var i: i64 = 0 143 while i < nf { 144 let fidx: i64 = sp_find(st, faces[i]) 145 if fidx >= 0 { 146 let sid: i64 = sgt_arg_ref(st, fidx, 2, out2) 147 if sid >= 0 { 148 let sidx: i64 = sp_find(st, sid) 149 if sidx >= 0 { 150 if anl[sidx] == 0 { 151 // complex instance -> rational spline (round) 152 let before: i64 = c2[2] 153 sgn_tess_face(nt, sidx) 154 if c2[2] > before { out4[1] = out4[1] + 1; out4[3] = out4[3] + 1 } 155 } else { 156 let before2: i64 = c[11] 157 sgt2_face(tt, t2, fidx, slab) 158 if c[11] > before2 { out4[1] = out4[1] + 1; out4[2] = out4[2] + 1 } 159 } 160 } 161 } 162 } 163 i = i + 1 164 } 165 return out4[1] 166} 167 168// mm with 2 decimals from fx256 -> print 169func cr_mm2(v: i64) -> i64 { 170 var a: i64 = v * 100 171 if a < 0 { sp_puts("-" as *u8); a = 0 - a } 172 let cents: i64 = (a + 128) / 256 173 sp_putn(cents / 100) 174 sp_puts("." as *u8) 175 let r: i64 = cents % 100 176 if r < 10 { sp_puts("0" as *u8) } 177 sp_putn(r) 178 return 0 179} 180// deterministic mesh checksum 181func cr_cksum(mesh: i64) -> i64 { 182 let h: *i64 = m3_hdr(mesh) 183 var s: i64 = h[0] * K_MAGIC_7919 + h[1] * K_MAGIC_104729 184 var i: i64 = 0 185 while i < h[0] { 186 let v: *i64 = m3_vert(mesh, i) 187 s = s + v[0] + v[1] * 3 + v[2] * 7 188 i = i + 1 189 } 190 var t: i64 = 0 191 while t < h[1] { 192 let tr: *i64 = m3_tri(mesh, t) 193 s = s + tr[0] * 11 + tr[1] * 13 + tr[2] * 17 194 t = t + 1 195 } 196 return s 197}