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}