code wiki / _hdl_build / nx_assemseq.nx
nx_assemseq.nx source
↩ module page · 80 lines · 3081 B
1// nx_assemseq.nx -- ASSEMBLY / DISASSEMBLY SEQUENCING from the STEP assembly tree (cadtwin P4b). Given the
2// parsed as1 product structure (nx_step_parse: NAUO parent->child edges), compute a valid DISASSEMBLY ORDER:
3// deepest parts (fasteners/leaves) come out first, the top assembly last -- a part is removable only after all
4// its children are removed. = teardown/repair instructions for a flipped car, and the correct order for the
5// /explodelab explode animation (explodelab already offsets by assembly depth = this order). Depth = longest
6// path from the root (handles shared sub-assemblies). Verifies every edge: child removed BEFORE its parent.
7// Composes nx_step_parse. Deterministic. LIB (no main; gated by nx_assemseq_gate). license_tier: ORIGINAL
8import "nx_step_parse.nx"
9
10// collect the unique PD ids referenced by the NAUO edges into pd[] (returns count). rootpd = the parent that
11// is never a child.
12func asq_collect_pds(pe: *i64, ce: *i64, en: i64, pd: *i64) -> i64 {
13 var n: i64 = 0
14 var e: i64 = 0
15 while e < en {
16 var side: i64 = 0
17 while side < 2 {
18 var v: i64 = pe[e]
19 if side == 1 { v = ce[e] }
20 var seen: i64 = 0
21 var i: i64 = 0
22 while i < n { if pd[i] == v { seen = 1 } i = i + 1 }
23 if seen == 0 { pd[n] = v; n = n + 1 }
24 side = side + 1
25 }
26 e = e + 1
27 }
28 return n
29}
30func asq_root(pe: *i64, ce: *i64, en: i64) -> i64 {
31 var e: i64 = 0
32 while e < en {
33 let p: i64 = pe[e]
34 var ischild: i64 = 0
35 var j: i64 = 0
36 while j < en { if ce[j] == p { ischild = 1 } j = j + 1 }
37 if ischild == 0 { return p }
38 e = e + 1
39 }
40 return 0 - 1
41}
42// longest-path DEPTH from root for each pd (relaxation over the edges); depth[i] for pd[i]. root depth 0.
43func asq_depths(pd: *i64, npd: i64, pe: *i64, ce: *i64, en: i64, rootpd: i64, depth: *i64) -> i64 {
44 var i: i64 = 0
45 while i < npd { depth[i] = 0; i = i + 1 }
46 // iterate relaxation npd times (longest path in a DAG)
47 var pass: i64 = 0
48 while pass < npd {
49 var e: i64 = 0
50 while e < en {
51 var pi: i64 = 0 - 1
52 var ci: i64 = 0 - 1
53 var k: i64 = 0
54 while k < npd {
55 if pd[k] == pe[e] { pi = k }
56 if pd[k] == ce[e] { ci = k }
57 k = k + 1
58 }
59 if pi >= 0 { if ci >= 0 { if depth[pi] + 1 > depth[ci] { depth[ci] = depth[pi] + 1 } } }
60 e = e + 1
61 }
62 pass = pass + 1
63 }
64 return 0
65}
66// disassembly order = pd indices sorted by depth DESCENDING into order[]. stable by original index for ties.
67func asq_order(depth: *i64, npd: i64, order: *i64) -> i64 {
68 var w: i64 = 0
69 // find max depth
70 var maxd: i64 = 0
71 var i: i64 = 0
72 while i < npd { if depth[i] > maxd { maxd = depth[i] } i = i + 1 }
73 var d: i64 = maxd
74 while d >= 0 {
75 i = 0
76 while i < npd { if depth[i] == d { order[w] = i; w = w + 1 } i = i + 1 }
77 d = d - 1
78 }
79 return w
80}