code wiki / (root) / nx_step_write.nx

nx_step_write.nx source

↩ module page · 310 lines · 11263 B

1// nx_step_write.nx -- STEP WRITE (cadtwin P3a write half, first rung): emit a valid ISO-10303-21 file from a 2// twin mesh -- FACETED B-rep class (FACETED_BREP + CLOSED_SHELL + FACE/FACE_OUTER_BOUND/POLY_LOOP + shared 3// CARTESIAN_POINTs) with the full product-identity chain (PRODUCT->PDF->PD->PDS->SDR) and DECLARED mm units + 4// uncertainty (the anti-JPL doctrine: our files SAY their units). Coordinates are written as EXACT decimals: 5// fx256 -> "N.XXXXXXXX" (1/256 = 0.00390625 -> 8 fractional digits, lossless) so a round-trip through our own 6// reader is INTEGER-EXACT by construction. Includes the matching FACETED READ path (POLY_LOOP -> triangles) -- 7// the interop pair in one organ. HONEST scope: faceted geometry write (the mesh-twin class); analytic/NURBS 8// B-rep WRITE = the named residual for full parity. NOTE: '#' cannot appear in NishiLang string literals 9// (scanner gotcha) -- every STEP ref emits byte 35 via swb_c. license_tier: ORIGINAL 10import "nx_step_nurbs.nx" 11const K_MAGIC_390625: i64 = 390625 12const K_MAGIC_10000000: i64 = 10000000 13const K_MAGIC_262144: i64 = 262144 14const K_MAGIC_32768: i64 = 32768 15const K_MAGIC_4000: i64 = 4000 16 17// ---- string builder b[]: [0]=buf ptr [1]=len [2]=cap 18func swb_init(b: *i64, cap: i64) -> i64 { 19 b[0] = sys_mmap(cap) as i64 20 b[1] = 0 21 b[2] = cap 22 return 0 23} 24func swb_c(b: *i64, ch: i64) -> i64 { 25 if b[1] >= b[2] { return 0 - 1 } 26 let p: *u8 = b[0] as *u8 27 p[b[1]] = ch as u8 28 b[1] = b[1] + 1 29 return 0 30} 31func swb_s(b: *i64, s: *u8) -> i64 { 32 var i: i64 = 0 33 while s[i] != (0 as u8) { 34 swb_c(b, s[i] as i64) 35 i = i + 1 36 } 37 return 0 38} 39func swb_n(b: *i64, v0: i64) -> i64 { 40 var v: i64 = v0 41 if v < 0 { swb_c(b, 45); v = 0 - v } 42 let t: *u8 = ((b[0] as i64) + b[2] - 32) as *u8 // scratch at buffer tail (cap includes headroom) 43 var k: i64 = 0 44 if v == 0 { swb_c(b, 48); return 0 } 45 while v > 0 { t[k] = (48 + (v % 10)) as u8; v = v / 10; k = k + 1 } 46 while k > 0 { k = k - 1; swb_c(b, t[k] as i64) } 47 return 0 48} 49// exact decimal mm from fx256: N.XXXXXXXX (8 frac digits = (fx&255)*390625, lossless) 50func swb_fx(b: *i64, v0: i64) -> i64 { 51 var v: i64 = v0 52 if v < 0 { swb_c(b, 45); v = 0 - v } 53 swb_n(b, v / 256) 54 swb_c(b, 46) 55 var f: i64 = (v % 256) * K_MAGIC_390625 56 // zero-pad to 8 digits 57 var dig: i64 = K_MAGIC_10000000 58 var i: i64 = 0 59 while i < 8 { 60 swb_c(b, 48 + (f / dig) % 10) 61 dig = dig / 10 62 i = i + 1 63 } 64 return 0 65} 66func swb_ref(b: *i64, id: i64) -> i64 { 67 swb_c(b, 35) 68 swb_n(b, id) 69 return 0 70} 71func swb_ent(b: *i64, id: i64) -> i64 { 72 swb_ref(b, id) 73 swb_s(b, " = " as *u8) 74 return 0 75} 76 77// ---- write the mesh as a faceted-brep STEP file. Entity ids: prelude 1..24, verts 30..30+nv-1, per-tri 78// (loop,bound,face) 30+nv+3t.., shell/brep at the end. Returns total entity count (>0) or -1. 79func sw_write_mesh(mesh: i64, path: *u8, pname: *u8) -> i64 { 80 let h: *i64 = m3_hdr(mesh) 81 let nv: i64 = h[0] 82 let nt: i64 = h[1] 83 if nv < 3 { return 0 - 1 } 84 if nt < 1 { return 0 - 1 } 85 let b: *i64 = sys_mmap(64) as *i64 86 swb_init(b, K_MAGIC_262144 + nv * 64 + nt * 128) 87 // header 88 swb_s(b, "ISO-10303-21;\nHEADER;\nFILE_DESCRIPTION(('Nishi twin faceted export'),'2;1');\nFILE_NAME('" as *u8) 89 swb_s(b, pname) 90 swb_s(b, "','2026-07-09T00:00:00',('nishi'),('nishi'),'nx_step_write','nx_cadtwin','');\nFILE_SCHEMA(('AUTOMOTIVE_DESIGN " as *u8) 91 swb_c(b, 123) 92 swb_s(b, " 1 0 10303 214 1 1 1 1 " as *u8) 93 swb_c(b, 125) 94 swb_s(b, "'));\nENDSEC;\nDATA;\n" as *u8) 95 // prelude: application + product chain 96 swb_ent(b, 1) 97 swb_s(b, "APPLICATION_PROTOCOL_DEFINITION('international standard','automotive_design',2000," as *u8) 98 swb_ref(b, 2) 99 swb_s(b, ");\n" as *u8) 100 swb_ent(b, 2) 101 swb_s(b, "APPLICATION_CONTEXT('core data for automotive mechanical design processes');\n" as *u8) 102 swb_ent(b, 3) 103 swb_s(b, "PRODUCT_CONTEXT(''," as *u8) 104 swb_ref(b, 2) 105 swb_s(b, ",'mechanical');\n" as *u8) 106 swb_ent(b, 4) 107 swb_s(b, "PRODUCT('" as *u8) 108 swb_s(b, pname) 109 swb_s(b, "','" as *u8) 110 swb_s(b, pname) 111 swb_s(b, "','',(" as *u8) 112 swb_ref(b, 3) 113 swb_s(b, "));\n" as *u8) 114 swb_ent(b, 5) 115 swb_s(b, "PRODUCT_DEFINITION_FORMATION('',''," as *u8) 116 swb_ref(b, 4) 117 swb_s(b, ");\n" as *u8) 118 swb_ent(b, 6) 119 swb_s(b, "PRODUCT_DEFINITION_CONTEXT('part definition'," as *u8) 120 swb_ref(b, 2) 121 swb_s(b, ",'design');\n" as *u8) 122 swb_ent(b, 7) 123 swb_s(b, "PRODUCT_DEFINITION('design',''," as *u8) 124 swb_ref(b, 5) 125 swb_s(b, "," as *u8) 126 swb_ref(b, 6) 127 swb_s(b, ");\n" as *u8) 128 swb_ent(b, 8) 129 swb_s(b, "PRODUCT_DEFINITION_SHAPE('',''," as *u8) 130 swb_ref(b, 7) 131 swb_s(b, ");\n" as *u8) 132 // units context (mm DECLARED + uncertainty) 133 swb_ent(b, 20) 134 swb_s(b, "( GEOMETRIC_REPRESENTATION_CONTEXT(3) GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((" as *u8) 135 swb_ref(b, 24) 136 swb_s(b, ")) GLOBAL_UNIT_ASSIGNED_CONTEXT((" as *u8) 137 swb_ref(b, 21) 138 swb_s(b, "," as *u8) 139 swb_ref(b, 22) 140 swb_s(b, "," as *u8) 141 swb_ref(b, 23) 142 swb_s(b, ")) REPRESENTATION_CONTEXT('','') );\n" as *u8) 143 swb_ent(b, 21) 144 swb_s(b, "( LENGTH_UNIT() NAMED_UNIT(*) SI_UNIT(.MILLI.,.METRE.) );\n" as *u8) 145 swb_ent(b, 22) 146 swb_s(b, "( NAMED_UNIT(*) PLANE_ANGLE_UNIT() SI_UNIT($,.RADIAN.) );\n" as *u8) 147 swb_ent(b, 23) 148 swb_s(b, "( NAMED_UNIT(*) SI_UNIT($,.STERADIAN.) SOLID_ANGLE_UNIT() );\n" as *u8) 149 swb_ent(b, 24) 150 swb_s(b, "UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(5.E-006)," as *u8) 151 swb_ref(b, 21) 152 swb_s(b, ",'distance_accuracy_value','confusion accuracy');\n" as *u8) 153 // placement 154 swb_ent(b, 13) 155 swb_s(b, "AXIS2_PLACEMENT_3D(''," as *u8) 156 swb_ref(b, 14) 157 swb_s(b, "," as *u8) 158 swb_ref(b, 15) 159 swb_s(b, "," as *u8) 160 swb_ref(b, 16) 161 swb_s(b, ");\n" as *u8) 162 swb_ent(b, 14) 163 swb_s(b, "CARTESIAN_POINT('',(0.,0.,0.));\n" as *u8) 164 swb_ent(b, 15) 165 swb_s(b, "DIRECTION('',(0.,0.,1.));\n" as *u8) 166 swb_ent(b, 16) 167 swb_s(b, "DIRECTION('',(1.,0.,0.));\n" as *u8) 168 // vertices (EXACT decimals) 169 let vbase: i64 = 30 170 var i: i64 = 0 171 while i < nv { 172 let v: *i64 = m3_vert(mesh, i) 173 swb_ent(b, vbase + i) 174 swb_s(b, "CARTESIAN_POINT('',(" as *u8) 175 swb_fx(b, v[0]) 176 swb_c(b, 44) 177 swb_fx(b, v[1]) 178 swb_c(b, 44) 179 swb_fx(b, v[2]) 180 swb_s(b, "));\n" as *u8) 181 i = i + 1 182 } 183 // triangles: POLY_LOOP + FACE_OUTER_BOUND + FACE 184 let fbase: i64 = vbase + nv 185 var t: i64 = 0 186 while t < nt { 187 let tr: *i64 = m3_tri(mesh, t) 188 let lid: i64 = fbase + t * 3 189 swb_ent(b, lid) 190 swb_s(b, "POLY_LOOP('',(" as *u8) 191 swb_ref(b, vbase + tr[0]) 192 swb_c(b, 44) 193 swb_ref(b, vbase + tr[1]) 194 swb_c(b, 44) 195 swb_ref(b, vbase + tr[2]) 196 swb_s(b, "));\n" as *u8) 197 swb_ent(b, lid + 1) 198 swb_s(b, "FACE_OUTER_BOUND(''," as *u8) 199 swb_ref(b, lid) 200 swb_s(b, ",.T.);\n" as *u8) 201 swb_ent(b, lid + 2) 202 swb_s(b, "FACE('',(" as *u8) 203 swb_ref(b, lid + 1) 204 swb_s(b, "));\n" as *u8) 205 t = t + 1 206 } 207 // shell + brep + shape rep + SDR 208 let shellid: i64 = fbase + nt * 3 209 swb_ent(b, shellid) 210 swb_s(b, "CLOSED_SHELL('',(" as *u8) 211 t = 0 212 while t < nt { 213 if t > 0 { swb_c(b, 44) } 214 swb_ref(b, fbase + t * 3 + 2) 215 t = t + 1 216 } 217 swb_s(b, "));\n" as *u8) 218 swb_ent(b, shellid + 1) 219 swb_s(b, "FACETED_BREP(''," as *u8) 220 swb_ref(b, shellid) 221 swb_s(b, ");\n" as *u8) 222 swb_ent(b, shellid + 2) 223 swb_s(b, "FACETED_BREP_SHAPE_REPRESENTATION('',(" as *u8) 224 swb_ref(b, 13) 225 swb_c(b, 44) 226 swb_ref(b, shellid + 1) 227 swb_s(b, ")," as *u8) 228 swb_ref(b, 20) 229 swb_s(b, ");\n" as *u8) 230 swb_ent(b, 9) 231 swb_s(b, "SHAPE_DEFINITION_REPRESENTATION(" as *u8) 232 swb_ref(b, 8) 233 swb_c(b, 44) 234 swb_ref(b, shellid + 2) 235 swb_s(b, ");\nENDSEC;\nEND-ISO-10303-21;\n" as *u8) 236 // write file 237 let fd: i64 = sys_openat_wr(path, 420) 238 if fd < 0 { return 0 - 1 } 239 sys_write(fd, b[0] as *u8, b[1]) 240 sys_close(fd) 241 // entity count: 8 product-chain + 1 SDR + 4 placement + 5 units/ctx + nv points + 3*nt facet + 3 shell/brep/rep 242 return 21 + nv + 3 * nt 243} 244 245// ---- FACETED READ: FACETED_BREP -> CLOSED_SHELL -> FACE -> FACE_OUTER_BOUND -> POLY_LOOP -> triangles. 246// Keys on the POLY_LOOP loop type (robust to face entity naming). Returns triangles added to mesh. 247func sw_read_faceted(st: *i64, mesh: i64) -> i64 { 248 let out2: *i64 = st[9] as *i64 249 let cnt: i64 = st[7] 250 var added: i64 = 0 251 let faces: *i64 = sys_mmap(K_MAGIC_32768) as *i64 252 let p3: *i64 = sys_mmap(96) as *i64 253 var idx: i64 = 0 254 while idx < cnt { 255 if sp_name_is(st, idx, "FACETED_BREP" as *u8) == 1 { 256 let shid: i64 = sgt_arg_ref(st, idx, 1, out2) 257 if shid >= 0 { 258 let shidx: i64 = sp_find(st, shid) 259 if shidx >= 0 { 260 let aao: *i64 = st[5] as *i64 261 let aal: *i64 = st[6] as *i64 262 let nf: i64 = sgt_refs(st[0] as *u8, aao[shidx], aal[shidx], faces, K_MAGIC_4000) 263 var f: i64 = 0 264 while f < nf { 265 let fidx: i64 = sp_find(st, faces[f]) 266 if fidx >= 0 { 267 let bid: i64 = sgt_arg_ref(st, fidx, 1, out2) 268 if bid >= 0 { 269 let bidx: i64 = sp_find(st, bid) 270 if bidx >= 0 { 271 let lid: i64 = sgt_arg_ref(st, bidx, 1, out2) 272 if lid >= 0 { 273 let lidx: i64 = sp_find(st, lid) 274 if lidx >= 0 { if sp_name_is(st, lidx, "POLY_LOOP" as *u8) == 1 { 275 added = added + sw_facet_tri(st, lidx, mesh, p3) 276 } } 277 } 278 } 279 } 280 } 281 f = f + 1 282 } 283 } 284 } 285 } 286 idx = idx + 1 287 } 288 return added 289} 290// one POLY_LOOP -> triangle (3 verts appended + tri). Returns 1 if added. 291func sw_facet_tri(st: *i64, lidx: i64, mesh: i64, p3: *i64) -> i64 { 292 let out2: *i64 = st[9] as *i64 293 let aao: *i64 = st[5] as *i64 294 let aal: *i64 = st[6] as *i64 295 let refs: *i64 = ((p3 as i64) + 72) as *i64 // needs p3 alloc >= 96+32 296 let nr: i64 = sgt_refs(st[0] as *u8, aao[lidx], aal[lidx], refs, 3) 297 if nr != 3 { return 0 } 298 var k: i64 = 0 299 while k < 3 { 300 if sgt_tuple_of(st, refs[k], ((p3 as i64) + k * 24) as *i64) == 0 { return 0 } 301 k = k + 1 302 } 303 let h: *i64 = m3_hdr(mesh) 304 let vb: i64 = h[0] 305 m3_add_vert(mesh, p3[0], p3[1], p3[2]) 306 m3_add_vert(mesh, p3[3], p3[4], p3[5]) 307 m3_add_vert(mesh, p3[6], p3[7], p3[8]) 308 m3_add_tri(mesh, vb, vb + 1, vb + 2) 309 return 1 310}