nx_step_geom.nx source
↩ module page · 102 lines · 4263 B
1// nx_step_geom.nx -- REAL GEOMETRY extraction from a STEP file (cadtwin P3a: structure -> actual coordinates).
2// nx_step_parse gave the assembly tree/BOM; this pulls the model's real 3D geometry: parse every CARTESIAN_POINT
3// entity's coordinate tuple (STEP reals like -10., 0.E+000, 2.5) into a fixed-point point cloud (fx256). That
4// cloud is real model geometry -- feeds the bounding box, and directly into nx_partid (shape descriptor needs
5// only vertices). Composes nx_step_parse. First rung toward face tessellation (planar/B-spline = the next rungs).
6// license_tier: ORIGINAL
7import "nx_step_parse.nx"
8
9const SG_FX: i64 = 256
10
11func sg_isdigit(c: i64) -> i64 { if c >= 48 { if c <= 57 { return 1 } } return 0 }
12// a coordinate token starts with a digit, '-', '+', or '.'
13func sg_is_numstart(c: i64) -> i64 {
14 if sg_isdigit(c) == 1 { return 1 }
15 if c == 45 { return 1 }
16 if c == 43 { return 1 }
17 if c == 46 { return 1 }
18 return 0
19}
20// advance past non-number chars (spaces, '(', ',') to the next coordinate token
21func sg_skip_to_num(buf: *u8, v0: i64, e: i64) -> i64 {
22 var v: i64 = v0
23 var go: i64 = 1
24 while go == 1 {
25 if v >= e { go = 0 } else {
26 if sg_is_numstart(buf[v] as i64) == 1 { go = 0 } else { v = v + 1 }
27 }
28 }
29 return v
30}
31// parse a STEP real at p (< e) -> fx256 into out_val; returns index after the number
32func sg_parse_real(buf: *u8, p: i64, e: i64, out_val: *i64) -> i64 {
33 var v: i64 = p
34 var sign: i64 = 1
35 if v < e { if buf[v] == (45 as u8) { sign = 0 - 1; v = v + 1 } else { if buf[v] == (43 as u8) { v = v + 1 } } }
36 var intval: i64 = 0
37 var g1: i64 = 1
38 while g1 == 1 {
39 if v < e { let d: i64 = buf[v] as i64; if sg_isdigit(d) == 1 { intval = intval * 10 + (d - 48); v = v + 1 } else { g1 = 0 } } else { g1 = 0 }
40 }
41 var fx: i64 = intval * SG_FX
42 if v < e { if buf[v] == (46 as u8) { // fraction
43 v = v + 1
44 var fnum: i64 = 0
45 var fden: i64 = 1
46 var g2: i64 = 1
47 while g2 == 1 {
48 if v < e { let d: i64 = buf[v] as i64; if sg_isdigit(d) == 1 { fnum = fnum * 10 + (d - 48); fden = fden * 10; v = v + 1 } else { g2 = 0 } } else { g2 = 0 }
49 }
50 if fden > 1 { fx = fx + (fnum * SG_FX) / fden }
51 } }
52 var exp: i64 = 0
53 var esign: i64 = 1
54 var hase: i64 = 0
55 if v < e { if buf[v] == (69 as u8) { hase = 1; v = v + 1 } } // 'E'
56 if hase == 0 { if v < e { if buf[v] == (101 as u8) { hase = 1; v = v + 1 } } } // 'e'
57 if hase == 1 {
58 if v < e { if buf[v] == (45 as u8) { esign = 0 - 1; v = v + 1 } else { if buf[v] == (43 as u8) { v = v + 1 } } }
59 var g3: i64 = 1
60 while g3 == 1 {
61 if v < e { let d: i64 = buf[v] as i64; if sg_isdigit(d) == 1 { exp = exp * 10 + (d - 48); v = v + 1 } else { g3 = 0 } } else { g3 = 0 }
62 }
63 }
64 if exp > 0 {
65 var k: i64 = 0
66 while k < exp { if esign > 0 { fx = fx * 10 } else { fx = fx / 10 } k = k + 1 }
67 }
68 out_val[0] = fx * sign
69 return v
70}
71// parse the (x,y,z) tuple of CARTESIAN_POINT entity idx into out3 (fx256); 1 if ok
72func sg_point_tuple(st: *i64, idx: i64, out3: *i64) -> i64 {
73 let buf: *u8 = st[0] as *u8
74 let sp2: *i64 = sys_mmap(16) as *i64
75 let ok: i64 = sp_arg_span(st, idx, 1, sp2) // arg 1 = the coordinate tuple
76 if ok == 0 { return 0 }
77 let off: i64 = sp2[0]
78 let e: i64 = sp2[0] + sp2[1]
79 var v: i64 = sg_skip_to_num(buf, off, e)
80 v = sg_parse_real(buf, v, e, out3)
81 v = sg_skip_to_num(buf, v, e)
82 v = sg_parse_real(buf, v, e, ((out3 as i64) + 8) as *i64)
83 v = sg_skip_to_num(buf, v, e)
84 v = sg_parse_real(buf, v, e, ((out3 as i64) + 16) as *i64)
85 return 1
86}
87// extract every CARTESIAN_POINT into out_pts (stride-3 fx256); returns point count (capped at maxp)
88func sg_extract_points(st: *i64, out_pts: *i64, maxp: i64) -> i64 {
89 var n: i64 = 0
90 let cnt: i64 = st[7]
91 var idx: i64 = 0
92 while idx < cnt {
93 if sp_name_is(st, idx, "CARTESIAN_POINT" as *u8) == 1 {
94 if n < maxp {
95 sg_point_tuple(st, idx, ((out_pts as i64) + n * 24) as *i64)
96 n = n + 1
97 }
98 }
99 idx = idx + 1
100 }
101 return n
102}