nx_step_brepw.nx source
↩ module page · 414 lines · 15421 B
1// nx_step_brepw.nx -- ANALYTIC B-REP STEP WRITE (cadtwin P3a write parity): two capabilities.
2// (A) sw2_box AUTHORS a true analytic B-rep from parameters: 8 VERTEX_POINTs, 12 EDGE_CURVEs on LINEs, 24
3// ORIENTED_EDGEs, 6 ADVANCED_FACEs on PLANEs (AXIS2 origin/normal/refdir), MANIFOLD_SOLID_BREP + product
4// chain + DECLARED mm units -- generated numerically, not copied. Verified by reading it back through the
5// full gated v2 pipeline (planar tessellation, exact invariants, exact dimensions).
6// (B) sw2_reemit RE-SERIALIZES any parsed model's reachable B-rep graph (BFS from every SDR/NAUO/CDSR seed)
7// with renumbered ids -- entity args copied span-wise with refs REWRITTEN (strings skipped), complex
8// instances preserved. = persistence for anything we can read (planes, degree-5 splines, rational Bezier
9// surfaces/curves). Verified: re-parse -> full planar+NURBS tessellation == the original model's (face
10// counts + order-invariant geometry checksum).
11// Uses swb_* from nx_step_write ('#' emitted as byte 35 -- literal gotcha). license_tier: ORIGINAL
12import "nx_step_write.nx"
13const K_MAGIC_262144: i64 = 262144
14const K_MAGIC_16384: i64 = 16384
15const K_MAGIC_131072: i64 = 131072
16const K_MAGIC_65536: i64 = 65536
17const K_MAGIC_2048: i64 = 2048
18const K_MAGIC_4194304: i64 = 4194304
19
20// shared prelude: header + application/product chain + units + placement. rep entity id emitted later by caller.
21func sw2_prelude(b: *i64, pname: *u8) -> i64 {
22 swb_s(b, "ISO-10303-21;\nHEADER;\nFILE_DESCRIPTION(('Nishi twin B-rep export'),'2;1');\nFILE_NAME('" as *u8)
23 swb_s(b, pname)
24 swb_s(b, "','2026-07-09T00:00:00',('nishi'),('nishi'),'nx_step_brepw','nx_cadtwin','');\nFILE_SCHEMA(('AUTOMOTIVE_DESIGN " as *u8)
25 swb_c(b, 123)
26 swb_s(b, " 1 0 10303 214 1 1 1 1 " as *u8)
27 swb_c(b, 125)
28 swb_s(b, "'));\nENDSEC;\nDATA;\n" as *u8)
29 swb_ent(b, 1)
30 swb_s(b, "APPLICATION_PROTOCOL_DEFINITION('international standard','automotive_design',2000," as *u8)
31 swb_ref(b, 2)
32 swb_s(b, ");\n" as *u8)
33 swb_ent(b, 2)
34 swb_s(b, "APPLICATION_CONTEXT('core data for automotive mechanical design processes');\n" as *u8)
35 swb_ent(b, 3)
36 swb_s(b, "PRODUCT_CONTEXT(''," as *u8)
37 swb_ref(b, 2)
38 swb_s(b, ",'mechanical');\n" as *u8)
39 swb_ent(b, 4)
40 swb_s(b, "PRODUCT('" as *u8)
41 swb_s(b, pname)
42 swb_s(b, "','" as *u8)
43 swb_s(b, pname)
44 swb_s(b, "','',(" as *u8)
45 swb_ref(b, 3)
46 swb_s(b, "));\n" as *u8)
47 swb_ent(b, 5)
48 swb_s(b, "PRODUCT_DEFINITION_FORMATION('',''," as *u8)
49 swb_ref(b, 4)
50 swb_s(b, ");\n" as *u8)
51 swb_ent(b, 6)
52 swb_s(b, "PRODUCT_DEFINITION_CONTEXT('part definition'," as *u8)
53 swb_ref(b, 2)
54 swb_s(b, ",'design');\n" as *u8)
55 swb_ent(b, 7)
56 swb_s(b, "PRODUCT_DEFINITION('design',''," as *u8)
57 swb_ref(b, 5)
58 swb_s(b, "," as *u8)
59 swb_ref(b, 6)
60 swb_s(b, ");\n" as *u8)
61 swb_ent(b, 8)
62 swb_s(b, "PRODUCT_DEFINITION_SHAPE('',''," as *u8)
63 swb_ref(b, 7)
64 swb_s(b, ");\n" as *u8)
65 swb_ent(b, 20)
66 swb_s(b, "( GEOMETRIC_REPRESENTATION_CONTEXT(3) GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((" as *u8)
67 swb_ref(b, 24)
68 swb_s(b, ")) GLOBAL_UNIT_ASSIGNED_CONTEXT((" as *u8)
69 swb_ref(b, 21)
70 swb_c(b, 44)
71 swb_ref(b, 22)
72 swb_c(b, 44)
73 swb_ref(b, 23)
74 swb_s(b, ")) REPRESENTATION_CONTEXT('','') );\n" as *u8)
75 swb_ent(b, 21)
76 swb_s(b, "( LENGTH_UNIT() NAMED_UNIT(*) SI_UNIT(.MILLI.,.METRE.) );\n" as *u8)
77 swb_ent(b, 22)
78 swb_s(b, "( NAMED_UNIT(*) PLANE_ANGLE_UNIT() SI_UNIT($,.RADIAN.) );\n" as *u8)
79 swb_ent(b, 23)
80 swb_s(b, "( NAMED_UNIT(*) SI_UNIT($,.STERADIAN.) SOLID_ANGLE_UNIT() );\n" as *u8)
81 swb_ent(b, 24)
82 swb_s(b, "UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(5.E-006)," as *u8)
83 swb_ref(b, 21)
84 swb_s(b, ",'distance_accuracy_value','confusion accuracy');\n" as *u8)
85 swb_ent(b, 13)
86 swb_s(b, "AXIS2_PLACEMENT_3D(''," as *u8)
87 swb_ref(b, 14)
88 swb_c(b, 44)
89 swb_ref(b, 15)
90 swb_c(b, 44)
91 swb_ref(b, 16)
92 swb_s(b, ");\n" as *u8)
93 swb_ent(b, 14)
94 swb_s(b, "CARTESIAN_POINT('',(0.,0.,0.));\n" as *u8)
95 swb_ent(b, 15)
96 swb_s(b, "DIRECTION('',(0.,0.,1.));\n" as *u8)
97 swb_ent(b, 16)
98 swb_s(b, "DIRECTION('',(1.,0.,0.));\n" as *u8)
99 return 18
100}
101// emit "CARTESIAN_POINT('',(x,y,z));" for fx coords
102func sw2_pt(b: *i64, id: i64, x: i64, y: i64, z: i64) -> i64 {
103 swb_ent(b, id)
104 swb_s(b, "CARTESIAN_POINT('',(" as *u8)
105 swb_fx(b, x)
106 swb_c(b, 44)
107 swb_fx(b, y)
108 swb_c(b, 44)
109 swb_fx(b, z)
110 swb_s(b, "));\n" as *u8)
111 return 0
112}
113// emit an ORIENTED_EDGE
114func sw2_oe(b: *i64, id: i64, ecid: i64, fwd: i64) -> i64 {
115 swb_ent(b, id)
116 swb_s(b, "ORIENTED_EDGE('',*,*," as *u8)
117 swb_ref(b, ecid)
118 if fwd == 1 { swb_s(b, ",.T.);\n" as *u8) } else { swb_s(b, ",.F.);\n" as *u8) }
119 return 0
120}
121
122// (A) AUTHOR an analytic B-rep box (w,h,d in fx256 mm) -> expected entity count.
123// ids: prelude 1..24(18 used) | pts 30..37 | vps 40..47 | dirs 50..52 | vecs 53..55 | lines 60..71 |
124// ecs 80..91 | axis2 100..105 | planes 110..115 | oes 130..153 | loops 160..165 | fobs 170..175 |
125// faces 180..185 | shell 190 | brep 191 | rep 192
126func sw2_box(path: *u8, w: i64, h: i64, d: i64, pname: *u8) -> i64 {
127 let b: *i64 = sys_mmap(64) as *i64
128 swb_init(b, K_MAGIC_262144)
129 sw2_prelude(b, pname)
130 // 8 corners: bit1=x bit2=y bit4=z
131 var ci: i64 = 0
132 while ci < 8 {
133 var x: i64 = 0
134 if (ci % 2) == 1 { x = w }
135 var y: i64 = 0
136 if ((ci / 2) % 2) == 1 { y = h }
137 var z: i64 = 0
138 if ci >= 4 { z = d }
139 sw2_pt(b, 30 + ci, x, y, z)
140 swb_ent(b, 40 + ci)
141 swb_s(b, "VERTEX_POINT(''," as *u8)
142 swb_ref(b, 30 + ci)
143 swb_s(b, ");\n" as *u8)
144 ci = ci + 1
145 }
146 // axis dirs + unit vectors
147 swb_ent(b, 50)
148 swb_s(b, "DIRECTION('',(1.,0.,0.));\n" as *u8)
149 swb_ent(b, 51)
150 swb_s(b, "DIRECTION('',(0.,1.,0.));\n" as *u8)
151 swb_ent(b, 52)
152 swb_s(b, "DIRECTION('',(0.,0.,1.));\n" as *u8)
153 var vi: i64 = 0
154 while vi < 3 {
155 swb_ent(b, 53 + vi)
156 swb_s(b, "VECTOR(''," as *u8)
157 swb_ref(b, 50 + vi)
158 swb_s(b, ",1.);\n" as *u8)
159 vi = vi + 1
160 }
161 // 12 edges: pairs (a,b) + line axis (0=x 1=y 2=z)
162 let ea: *i64 = sys_mmap(128) as *i64
163 let eb: *i64 = sys_mmap(128) as *i64
164 let ex: *i64 = sys_mmap(128) as *i64
165 ea[0] = 0; eb[0] = 1; ex[0] = 0
166 ea[1] = 1; eb[1] = 3; ex[1] = 1
167 ea[2] = 3; eb[2] = 2; ex[2] = 0
168 ea[3] = 2; eb[3] = 0; ex[3] = 1
169 ea[4] = 4; eb[4] = 5; ex[4] = 0
170 ea[5] = 5; eb[5] = 7; ex[5] = 1
171 ea[6] = 7; eb[6] = 6; ex[6] = 0
172 ea[7] = 6; eb[7] = 4; ex[7] = 1
173 ea[8] = 0; eb[8] = 4; ex[8] = 2
174 ea[9] = 1; eb[9] = 5; ex[9] = 2
175 ea[10] = 3; eb[10] = 7; ex[10] = 2
176 ea[11] = 2; eb[11] = 6; ex[11] = 2
177 var e: i64 = 0
178 while e < 12 {
179 swb_ent(b, 60 + e)
180 swb_s(b, "LINE(''," as *u8)
181 swb_ref(b, 30 + ea[e])
182 swb_c(b, 44)
183 swb_ref(b, 53 + ex[e])
184 swb_s(b, ");\n" as *u8)
185 swb_ent(b, 80 + e)
186 swb_s(b, "EDGE_CURVE(''," as *u8)
187 swb_ref(b, 40 + ea[e])
188 swb_c(b, 44)
189 swb_ref(b, 40 + eb[e])
190 swb_c(b, 44)
191 swb_ref(b, 60 + e)
192 swb_s(b, ",.T.);\n" as *u8)
193 e = e + 1
194 }
195 // 6 faces: loops as (edge, fwd) x4; plane origin corner + normal dir + refdir
196 let lo: *i64 = sys_mmap(512) as *i64 // 6 faces x 4 x (edge, fwd)
197 // bottom: e0+, e1+, e2+, e3+ origin c0, n=dz, ref=dx
198 lo[0] = 0; lo[1] = 1; lo[2] = 1; lo[3] = 1; lo[4] = 2; lo[5] = 1; lo[6] = 3; lo[7] = 1
199 // top: e7-, e6-, e5-, e4- origin c4, n=dz, ref=dx
200 lo[8] = 7; lo[9] = 0; lo[10] = 6; lo[11] = 0; lo[12] = 5; lo[13] = 0; lo[14] = 4; lo[15] = 0
201 // front y=0: e8+, e4+, e9-, e0- origin c0, n=dy, ref=dx
202 lo[16] = 8; lo[17] = 1; lo[18] = 4; lo[19] = 1; lo[20] = 9; lo[21] = 0; lo[22] = 0; lo[23] = 0
203 // back y=h: e2-, e10+, e6+, e11- origin c2, n=dy, ref=dx
204 lo[24] = 2; lo[25] = 0; lo[26] = 10; lo[27] = 1; lo[28] = 6; lo[29] = 1; lo[30] = 11; lo[31] = 0
205 // left x=0: e3-, e11+, e7+, e8- origin c0, n=dx, ref=dy
206 lo[32] = 3; lo[33] = 0; lo[34] = 11; lo[35] = 1; lo[36] = 7; lo[37] = 1; lo[38] = 8; lo[39] = 0
207 // right x=w: e9+, e5+, e10-, e1- origin c1, n=dx, ref=dy
208 lo[40] = 9; lo[41] = 1; lo[42] = 5; lo[43] = 1; lo[44] = 10; lo[45] = 0; lo[46] = 1; lo[47] = 0
209 let forg: *i64 = sys_mmap(64) as *i64
210 let fnrm: *i64 = sys_mmap(64) as *i64
211 let fref: *i64 = sys_mmap(64) as *i64
212 forg[0] = 0; fnrm[0] = 2; fref[0] = 0
213 forg[1] = 4; fnrm[1] = 2; fref[1] = 0
214 forg[2] = 0; fnrm[2] = 1; fref[2] = 0
215 forg[3] = 2; fnrm[3] = 1; fref[3] = 0
216 forg[4] = 0; fnrm[4] = 0; fref[4] = 1
217 forg[5] = 1; fnrm[5] = 0; fref[5] = 1
218 var f: i64 = 0
219 while f < 6 {
220 // 4 oriented edges
221 var k: i64 = 0
222 while k < 4 {
223 sw2_oe(b, 130 + f * 4 + k, 80 + lo[f * 8 + k * 2], lo[f * 8 + k * 2 + 1])
224 k = k + 1
225 }
226 swb_ent(b, 160 + f)
227 swb_s(b, "EDGE_LOOP('',(" as *u8)
228 k = 0
229 while k < 4 {
230 if k > 0 { swb_c(b, 44) }
231 swb_ref(b, 130 + f * 4 + k)
232 k = k + 1
233 }
234 swb_s(b, "));\n" as *u8)
235 swb_ent(b, 100 + f)
236 swb_s(b, "AXIS2_PLACEMENT_3D(''," as *u8)
237 swb_ref(b, 30 + forg[f])
238 swb_c(b, 44)
239 swb_ref(b, 50 + fnrm[f])
240 swb_c(b, 44)
241 swb_ref(b, 50 + fref[f])
242 swb_s(b, ");\n" as *u8)
243 swb_ent(b, 110 + f)
244 swb_s(b, "PLANE(''," as *u8)
245 swb_ref(b, 100 + f)
246 swb_s(b, ");\n" as *u8)
247 swb_ent(b, 170 + f)
248 swb_s(b, "FACE_OUTER_BOUND(''," as *u8)
249 swb_ref(b, 160 + f)
250 swb_s(b, ",.T.);\n" as *u8)
251 swb_ent(b, 180 + f)
252 swb_s(b, "ADVANCED_FACE('',(" as *u8)
253 swb_ref(b, 170 + f)
254 swb_s(b, ")," as *u8)
255 swb_ref(b, 110 + f)
256 swb_s(b, ",.T.);\n" as *u8)
257 f = f + 1
258 }
259 swb_ent(b, 190)
260 swb_s(b, "CLOSED_SHELL('',(" as *u8)
261 f = 0
262 while f < 6 {
263 if f > 0 { swb_c(b, 44) }
264 swb_ref(b, 180 + f)
265 f = f + 1
266 }
267 swb_s(b, "));\n" as *u8)
268 swb_ent(b, 191)
269 swb_s(b, "MANIFOLD_SOLID_BREP(''," as *u8)
270 swb_ref(b, 190)
271 swb_s(b, ");\n" as *u8)
272 swb_ent(b, 192)
273 swb_s(b, "ADVANCED_BREP_SHAPE_REPRESENTATION('',(" as *u8)
274 swb_ref(b, 13)
275 swb_c(b, 44)
276 swb_ref(b, 191)
277 swb_s(b, ")," as *u8)
278 swb_ref(b, 20)
279 swb_s(b, ");\n" as *u8)
280 swb_ent(b, 9)
281 swb_s(b, "SHAPE_DEFINITION_REPRESENTATION(" as *u8)
282 swb_ref(b, 8)
283 swb_c(b, 44)
284 swb_ref(b, 192)
285 swb_s(b, ");\nENDSEC;\nEND-ISO-10303-21;\n" as *u8)
286 let fd: i64 = sys_openat_wr(path, 420)
287 if fd < 0 { return 0 - 1 }
288 sys_write(fd, b[0] as *u8, b[1])
289 sys_close(fd)
290 // 17 prelude (8 product-chain + 5 units/ctx + 4 placement) + 1 SDR + 8 pts + 8 vps + 3 dirs + 3 vecs
291 // + 12 lines + 12 ecs + 24 oes + 6 loops + 6 axis2 + 6 planes + 6 fobs + 6 faces + shell + brep + rep
292 return 17 + 1 + 8 + 8 + 3 + 3 + 12 + 12 + 24 + 6 + 6 + 6 + 6 + 6 + 3
293}
294
295// copy entity args byte-wise, rewriting refs via map; strings copied verbatim
296func sw2_copy_args(st: *i64, eidx: i64, b: *i64, map: *i64) -> i64 {
297 let buf: *u8 = st[0] as *u8
298 let aao: *i64 = st[5] as *i64
299 let aal: *i64 = st[6] as *i64
300 var v: i64 = aao[eidx]
301 let e: i64 = v + aal[eidx]
302 while v < e {
303 let ch: i64 = buf[v] as i64
304 if ch == 39 {
305 let se: i64 = sp_skip_string(buf, e, v)
306 while v < se {
307 swb_c(b, buf[v] as i64)
308 v = v + 1
309 }
310 } else {
311 if ch == 35 {
312 var id: i64 = 0
313 var w: i64 = v + 1
314 var going: i64 = 1
315 while going == 1 {
316 if w < e { let d: i64 = buf[w] as i64; if sg_isdigit(d) == 1 { id = id * 10 + (d - 48); w = w + 1 } else { going = 0 } } else { going = 0 }
317 }
318 var nid: i64 = 0
319 if id < K_MAGIC_16384 { nid = map[id] }
320 swb_ref(b, nid)
321 v = w
322 } else {
323 swb_c(b, ch)
324 v = v + 1
325 }
326 }
327 }
328 return 0
329}
330
331// (B) RE-EMIT the parsed model's reachable graph with renumbered ids. Seeds: every SDR + NAUO + CDSR.
332// Returns emitted entity count.
333func sw2_reemit(st: *i64, path: *u8) -> i64 {
334 let cnt: i64 = st[7]
335 let aid: *i64 = st[2] as *i64
336 let map: *i64 = sys_mmap(K_MAGIC_131072) as *i64 // old id -> new id (0 = unvisited); ids < K_MAGIC_16384
337 let queue: *i64 = sys_mmap(K_MAGIC_65536) as *i64 // entity INDEXES to emit, in visit order
338 let refs: *i64 = sys_mmap(K_MAGIC_2048) as *i64
339 var qn: i64 = 0
340 var nextid: i64 = 1
341 // seed
342 var i: i64 = 0
343 while i < cnt {
344 var seed: i64 = 0
345 if sp_name_is(st, i, "SHAPE_DEFINITION_REPRESENTATION" as *u8) == 1 { seed = 1 }
346 if sp_name_is(st, i, "NEXT_ASSEMBLY_USAGE_OCCURRENCE" as *u8) == 1 { seed = 1 }
347 if sp_name_is(st, i, "CONTEXT_DEPENDENT_SHAPE_REPRESENTATION" as *u8) == 1 { seed = 1 }
348 if seed == 1 {
349 if map[aid[i]] == 0 {
350 map[aid[i]] = nextid
351 nextid = nextid + 1
352 queue[qn] = i
353 qn = qn + 1
354 }
355 }
356 i = i + 1
357 }
358 // BFS over refs
359 let aao: *i64 = st[5] as *i64
360 let aal: *i64 = st[6] as *i64
361 var qh: i64 = 0
362 while qh < qn {
363 let eidx: i64 = queue[qh]
364 let nr: i64 = sgt_refs(st[0] as *u8, aao[eidx], aal[eidx], refs, 256)
365 var r: i64 = 0
366 while r < nr {
367 let oid: i64 = refs[r]
368 if oid < K_MAGIC_16384 { if map[oid] == 0 {
369 let ridx: i64 = sp_find(st, oid)
370 if ridx >= 0 {
371 map[oid] = nextid
372 nextid = nextid + 1
373 queue[qn] = ridx
374 qn = qn + 1
375 }
376 } }
377 r = r + 1
378 }
379 qh = qh + 1
380 }
381 // emit
382 let b: *i64 = sys_mmap(64) as *i64
383 swb_init(b, K_MAGIC_4194304)
384 swb_s(b, "ISO-10303-21;\nHEADER;\nFILE_DESCRIPTION(('Nishi twin B-rep re-emit'),'2;1');\nFILE_NAME('reemit','2026-07-09T00:00:00',('nishi'),('nishi'),'nx_step_brepw','nx_cadtwin','');\nFILE_SCHEMA(('AUTOMOTIVE_DESIGN " as *u8)
385 swb_c(b, 123)
386 swb_s(b, " 1 0 10303 214 1 1 1 1 " as *u8)
387 swb_c(b, 125)
388 swb_s(b, "'));\nENDSEC;\nDATA;\n" as *u8)
389 let buf: *u8 = st[0] as *u8
390 let anm: *i64 = st[3] as *i64
391 let anl: *i64 = st[4] as *i64
392 var q: i64 = 0
393 while q < qn {
394 let eidx: i64 = queue[q]
395 swb_ent(b, map[aid[eidx]])
396 if anl[eidx] > 0 {
397 var w: i64 = 0
398 while w < anl[eidx] {
399 swb_c(b, buf[anm[eidx] + w] as i64)
400 w = w + 1
401 }
402 }
403 swb_c(b, 40)
404 sw2_copy_args(st, eidx, b, map)
405 swb_s(b, ");\n" as *u8)
406 q = q + 1
407 }
408 swb_s(b, "ENDSEC;\nEND-ISO-10303-21;\n" as *u8)
409 let fd: i64 = sys_openat_wr(path, 420)
410 if fd < 0 { return 0 - 1 }
411 sys_write(fd, b[0] as *u8, b[1])
412 sys_close(fd)
413 return qn
414}