nx_partloft_capture_t319.nx source
↩ module page · 344 lines · 19314 B
1// nx_partloft_gate.nx -- THE LOFTED PART (nx_partloft_lib) HELD TO KNOWN ANSWERS (procgen PG59 / anatomy AN19,
2// 2026-09-19). A straight cylinder of known radius decomposes into the genes the source's decompose_nurbs_handles
3// would produce (centred skeleton, equal proportions, zero pitch, zero lateral drift, a unit-circle profile facing +x),
4// recomposes to its own handles within the millimetre quantisation, evaluates as a cubic B-spline whose radius is
5// constant around the ring and clamped to the end rows, and writes a WATERTIGHT NXMSH2 whose every directed edge has
6// exactly one reverse twin. A bent part built from genes survives the decompose-recompose round trip in its pitch. The
7// gene mutation is the identity at var = 0 (byte-identical genes), moves the radii at var = 1, keeps its pitch noise
8// zero-mean, and is deterministic per seed. Surface coordinates (t, yaw, rad) land where apply_attach_transform's ray
9// would: yaw 0 is straight down, a half turn is +y, rad 0 is the skeleton itself. NEG-CONTROLS: a cone must read as a
10// cone (the decomposer discriminates radii), a shape the cubic cannot carry must be refused by name, and a face size
11// that leaves no cap fan must be refused rather than floored. license_tier: ORIGINAL. No hw writes (Rule 26).
12import "nx_syscalls.nx"
13import "nx_gate_verdict.nx"
14import "nx_partloft_lib.nx"
15
16const PG_NU: i64 = 6
17const PG_NV: i64 = 8
18const PG_R: i64 = 200 // u10: a 20 mm radius
19const PG_LEN: i64 = 1000 // u10: a 100 mm part along +x
20const PG_CONE_END: i64 = 100
21const PG_PROP: i64 = 13107 // PL_FQ / 5 = 13107.2
22const PG_TOL_U10: i64 = 2
23const PG_TOL_PROF: i64 = 200 // Q16: the fixture octagon's own radial spread (141 for 141.42 at 45 deg) is 0.3 percent
24const PG_TOL_BASIS: i64 = 8
25const PG_TOL_RING: i64 = 3
26const PG_TOL_PROP: i64 = 80 // Q16: a ring centre rounded to 1 u10 on a 200 u10 segment is 0.5 percent
27const PG_RMIN_PERMIL: i64 = 850 // a periodic cubic through a regular octagon of radius R lies between 0.85 R and R
28const PG_PERMIL: i64 = 1000
29const PG_FACE: i64 = 100 // u10: a 10 mm face size
30const PG_NT_EXPECT: i64 = 220 // 11 rows x 10 ring points: 2*10*10 tube + 2*10 caps
31const PG_SS_EXPECT: i64 = 11
32const PG_KU4: i64 = 21845 // PL_FQ / 3
33const PG_KU5: i64 = 43690 // 2 PL_FQ / 3
34const PG_KV3: i64 = 17873 // 3 PL_FQ / 11
35const PG_KV14: i64 = 83409 // PL_FQ + 3 PL_FQ / 11
36const PG_THETA30: i64 = 2144 // VM_PI / 6
37const PG_TOL_THETA: i64 = 40 // about half a degree
38const PG_TOL_COS: i64 = 16 // Q16: the ray and its hit agree to a few milliradians
39const PG_SEED: i64 = 7
40const PG_LOAD_HDR: i64 = 16
41const PG_EDGE_W: i64 = 6
42const PG_MESH: *u8 = "/tmp/nx_partloft_gate.nxmesh"
43const PG_PART: *u8 = "/tmp/nx_partloft_gate.part"
44const PG_ABSENT: *u8 = "/tmp/nx_partloft_gate.absent"
45
46func pg_abs(v: i64) -> i64 { if v < 0 { return 0 - v } return v }
47// a tube of nu rings along +x from radius r0 at x = 0 to r1 at x = len, nv points per ring from -z round through +y
48func pg_tube(hnd: *i64, nu: i64, nv: i64, r0: i64, r1: i64, len: i64) -> i64 {
49 var i: i64 = 0
50 while i < nu {
51 let x: i64 = i * len / (nu - 1)
52 let r: i64 = r0 + (r1 - r0) * i / (nu - 1)
53 var j: i64 = 0
54 while j < nv {
55 let ang: i64 = 0 - VM_PI2 + VM_TAU * j / nv
56 hnd[(i*nv+j)*PL_V3] = x
57 hnd[(i*nv+j)*PL_V3+1] = r * vm_cos(ang) / PL_ONE
58 hnd[(i*nv+j)*PL_V3+2] = r * vm_sin(ang) / PL_ONE
59 j = j + 1
60 }
61 i = i + 1
62 }
63 return nu * nv
64}
65func pg_max_hnd_err(a: *i64, b: *i64, n: i64) -> i64 {
66 var m: i64 = 0
67 var i: i64 = 0
68 while i < n { let d: i64 = pg_abs(a[i] - b[i]); if d > m { m = d }; i = i + 1 }
69 return m
70}
71func pg_sum_absdiff(a: *i64, b: *i64, n: i64) -> i64 {
72 var s: i64 = 0
73 var i: i64 = 0
74 while i < n { s = s + pg_abs(a[i] - b[i]); i = i + 1 }
75 return s
76}
77// the genes of two parts: the sum of absolute differences over root, length, prop, theta, yoff, rad, ts, prof
78func pg_gene_diff(a: *PlPart, b: *PlPart) -> i64 {
79 let nu: i64 = a.nu
80 let nv: i64 = a.nv
81 var s: i64 = pg_sum_absdiff(a.root, b.root, PL_V3) + pg_abs(a.length - b.length)
82 s = s + pg_sum_absdiff(a.prop, b.prop, nu - 1) + pg_sum_absdiff(a.theta, b.theta, nu - 1) + pg_sum_absdiff(a.yoff, b.yoff, nu - 1)
83 s = s + pg_sum_absdiff(a.rad, b.rad, nu) + pg_sum_absdiff(a.ts, b.ts, nu) + pg_sum_absdiff(a.prof, b.prof, nu*nv*PL_V3)
84 return s
85}
86func pg_near(ax: i64, ay: i64, az: i64, bx: i64, by: i64, bz: i64) -> i64 {
87 if pg_abs(ax - bx) > 1 { return 0 }
88 if pg_abs(ay - by) > 1 { return 0 }
89 if pg_abs(az - bz) > 1 { return 0 }
90 return 1
91}
92// read the written mesh back through the ONE layout and count edges without a reverse twin and duplicated edges;
93// rep = [unmatched, duplicates, ntris, nlayers, magic_ok, tube_vertex_radius]
94func pg_watertight(path: *u8, rep: *i64) -> i64 {
95 let ln: *i64 = sys_mmap(PG_LOAD_HDR) as *i64
96 let B: *u8 = sys_read_file(path, ln)
97 if (B as i64) == 0 { rep[0] = 0 - 1; rep[1] = 0 - 1; rep[2] = 0; rep[3] = 0; rep[4] = 0; rep[5] = 0; return 0 - 1 }
98 var magic: i64 = 1
99 if B[0] != (78 as u8) { magic = 0 }
100 if B[1] != (88 as u8) { magic = 0 }
101 if B[5] != (50 as u8) { magic = 0 }
102 let nt: i64 = nm_ntris(B)
103 let tb: i64 = nm_tri_base(B)
104 let ne: i64 = nt * 3
105 let E: *i64 = sys_mmap(ne * PG_EDGE_W * PL_I64) as *i64
106 var t: i64 = 0
107 while t < nt {
108 var v: i64 = 0
109 while v < 3 {
110 let w: i64 = (v + 1) % 3
111 let e: i64 = (t*3 + v) * PG_EDGE_W
112 E[e] = nm_coord(B, tb, t, v, 0); E[e+1] = nm_coord(B, tb, t, v, 1); E[e+2] = nm_coord(B, tb, t, v, 2)
113 E[e+3] = nm_coord(B, tb, t, w, 0); E[e+4] = nm_coord(B, tb, t, w, 1); E[e+5] = nm_coord(B, tb, t, w, 2)
114 v = v + 1
115 }
116 t = t + 1
117 }
118 var unmatched: i64 = 0
119 var dup: i64 = 0
120 var a: i64 = 0
121 while a < ne {
122 let ea: i64 = a * PG_EDGE_W
123 var rev: i64 = 0
124 var same: i64 = 0
125 var b: i64 = 0
126 while b < ne {
127 let eb: i64 = b * PG_EDGE_W
128 if pg_near(E[eb], E[eb+1], E[eb+2], E[ea+3], E[ea+4], E[ea+5]) == 1 {
129 if pg_near(E[eb+3], E[eb+4], E[eb+5], E[ea], E[ea+1], E[ea+2]) == 1 { rev = rev + 1 }
130 }
131 if b != a {
132 if pg_near(E[eb], E[eb+1], E[eb+2], E[ea], E[ea+1], E[ea+2]) == 1 {
133 if pg_near(E[eb+3], E[eb+4], E[eb+5], E[ea+3], E[ea+4], E[ea+5]) == 1 { same = same + 1 }
134 }
135 }
136 b = b + 1
137 }
138 if rev != 1 { unmatched = unmatched + 1 }
139 if same > 0 { dup = dup + 1 }
140 a = a + 1
141 }
142 // a tube vertex: triangle 0 vertex 0 sits on ring 0 of the tube
143 let y0: i64 = nm_coord(B, tb, 0, 0, 1)
144 let z0: i64 = nm_coord(B, tb, 0, 0, 2)
145 rep[0] = unmatched; rep[1] = dup; rep[2] = nt; rep[3] = nm_nlayers(B); rep[4] = magic
146 rep[5] = vm_isqrt(y0*y0 + z0*z0)
147 return unmatched + dup
148}
149
150func main(argc: i64, argv: *i64) -> i64 {
151 // Explicit output paths expose the existing known cylinder fixture for downstream measurement.
152 // No arguments retain the original gate behavior; this fixture is not human anatomy.
153 if argc != 1 { if argc != 3 { return 2 } }
154 var meshPath: *u8 = PG_MESH
155 var partPath: *u8 = PG_PART
156 if argc == 3 { meshPath = argv[1] as *u8; partPath = argv[2] as *u8 }
157 gv_head("nx_partloft_gate -- Infinigen's NurbsPart in NishiLang, held to a cylinder, a bent part and a cone" as *u8)
158 let ctr: *i64 = gv_ctr()
159 gv_check_eq("the-lib-angle-unit-is-vecmath's-unit" as *u8, PL_ONE, VM_ONE, ctr)
160 // ---- the cylinder: decompose ----
161 let H: *i64 = sys_mmap(PG_NU*PG_NV*PL_V3*PL_I64) as *i64
162 pg_tube(H, PG_NU, PG_NV, PG_R, PG_R, PG_LEN)
163 let p: *PlPart = pl_new(PG_NU, PG_NV)
164 gv_check_eq("cylinder-decomposes-to-every-handle" as *u8, pl_decompose(H, PG_NU, PG_NV, p), PG_NU*PG_NV, ctr)
165 gv_check_eq("skeleton-station-3-sits-on-the-axis-x" as *u8, p.skel[3*PL_V3], 600, ctr)
166 gv_check_eq("skeleton-station-3-sits-on-the-axis-yz" as *u8, pg_abs(p.skel[3*PL_V3+1]) + pg_abs(p.skel[3*PL_V3+2]), 0, ctr)
167 gv_check_near("mean-radius-is-the-cylinder's" as *u8, pl_rad_u10(p, 2), PG_R, PG_TOL_U10, ctr)
168 gv_check_near("proportions-are-equal-fifths" as *u8, p.prop[0], PG_PROP, 1, ctr)
169 gv_check_near("proportions-sum-to-one" as *u8, p.prop[0]+p.prop[1]+p.prop[2]+p.prop[3]+p.prop[4], PL_FQ, 5, ctr)
170 gv_check_eq("pitch-is-zero-along-x" as *u8, p.theta[0] + p.theta[4], 0, ctr)
171 gv_check_eq("lateral-drift-is-zero" as *u8, p.yoff[0] + p.yoff[4], 0, ctr)
172 gv_check_near("profile-point-0-faces-straight-down-y" as *u8, p.prof[1], 0, PG_TOL_PROF, ctr)
173 gv_check_near("profile-point-0-faces-straight-down-z" as *u8, p.prof[2], 0 - PL_FQ, PG_TOL_PROF, ctr)
174 gv_check_near("profile-lives-in-the-ring-plane-x" as *u8, p.prof[0], 0, PG_TOL_PROF, ctr)
175 gv_check_eq("ts-is-linspace-0-to-1" as *u8, p.ts[0] + p.ts[PG_NU-1], PL_FQ, ctr)
176 // ---- recompose reproduces the handles ----
177 let H2: *i64 = sys_mmap(PG_NU*PG_NV*PL_V3*PL_I64) as *i64
178 var k: i64 = 0
179 while k < PG_NU*PG_NV*PL_V3 { H2[k] = p.hnd[k]; k = k + 1 }
180 gv_check_eq("recompose-runs" as *u8, pl_recompose(p), 0, ctr)
181 let herr: i64 = pg_max_hnd_err(H2, p.hnd, PG_NU*PG_NV*PL_V3)
182 gv_check("recompose-reproduces-every-handle-within-the-quantum" as *u8, (herr <= PG_TOL_U10) as i64, ctr)
183 // ---- the knot vectors ----
184 gv_check_eq("u-knot-4-is-one-third" as *u8, p.ku[4], PG_KU4, ctr)
185 gv_check_eq("u-knot-5-is-two-thirds" as *u8, p.ku[5], PG_KU5, ctr)
186 gv_check_eq("u-knots-end-clamped-at-one" as *u8, p.ku[PG_NU+3], PL_FQ, ctr)
187 gv_check_eq("v-knot-3-opens-the-periodic-domain" as *u8, p.kv[3], PG_KV3, ctr)
188 gv_check_eq("v-knot-nv+3-closes-it-at-one" as *u8, p.kv[PG_NV+3], PL_FQ, ctr)
189 gv_check_eq("v-knots-wrap-three-intervals-past-the-end" as *u8, p.kv[PG_NV+6], PG_KV14, ctr)
190 // ---- partition of unity ----
191 let S: *i64 = sys_mmap(PL_V3*PL_I64) as *i64
192 pl_surface(p, PL_FQ/3, PL_FQ/5, S)
193 gv_check_near("u-basis-sums-to-one" as *u8, p.bu[0]+p.bu[1]+p.bu[2]+p.bu[3], PL_FQ, PG_TOL_BASIS, ctr)
194 gv_check_near("v-basis-sums-to-one" as *u8, p.bv[0]+p.bv[1]+p.bv[2]+p.bv[3], PL_FQ, PG_TOL_BASIS, ctr)
195 // ---- the surface of the cylinder: one radius all round, clamped to the end rows ----
196 var rmin: i64 = 1000000
197 var rmax: i64 = 0
198 var rsum: i64 = 0
199 var m: i64 = 0
200 while m < PG_NV {
201 pl_surface(p, PL_FQ/2, m*PL_FQ/PG_NV, S)
202 let r: i64 = vm_isqrt(S[1]*S[1] + S[2]*S[2])
203 if r < rmin { rmin = r }
204 if r > rmax { rmax = r }
205 rsum = rsum + r
206 m = m + 1
207 }
208 let rmean: i64 = rsum / PG_NV
209 gv_check("surface-radius-is-constant-round-the-ring" as *u8, (rmax - rmin <= PG_TOL_RING) as i64, ctr)
210 gv_check("surface-radius-lies-between-0.85R-and-R" as *u8, ((rmean >= PG_R*PG_RMIN_PERMIL/PG_PERMIL) * (rmean <= PG_R)) as i64, ctr)
211 pl_surface(p, 0, PL_FQ/3, S)
212 gv_check_near("surface-at-u=0-is-clamped-to-the-first-row" as *u8, S[0], 0, PG_TOL_U10, ctr)
213 pl_surface(p, PL_FQ, PL_FQ/3, S)
214 gv_check_near("surface-at-u=1-is-clamped-to-the-last-row" as *u8, S[0], PG_LEN, PG_TOL_U10, ctr)
215 // ---- the mesh ----
216 let cnt: *i64 = sys_mmap(8*PL_I64) as *i64
217 let nt: i64 = pl_mesh_counts(p, PG_FACE, cnt)
218 gv_check_near("mesh-counts-u-length" as *u8, cnt[0], PG_LEN, PG_TOL_U10, ctr)
219 gv_check_eq("mesh-counts-sample-size-from-the-longer-polyline" as *u8, cnt[2], PG_SS_EXPECT, ctr)
220 gv_check_eq("mesh-counts-triangles-tube-plus-caps" as *u8, nt, PG_NT_EXPECT, ctr)
221 let rep: *i64 = sys_mmap(8*PL_I64) as *i64
222 gv_check_eq("mesh-writes" as *u8, pl_mesh_write(p, PG_FACE, meshPath, rep), PG_NT_EXPECT, ctr)
223 gv_check_eq("mesh-bytes-follow-the-one-layout" as *u8, rep[1], nm_file_bytes(1, PG_NT_EXPECT), ctr)
224 let wt: *i64 = sys_mmap(8*PL_I64) as *i64
225 pg_watertight(meshPath, wt)
226 gv_check_eq("mesh-reads-back-with-the-magic" as *u8, wt[4], 1, ctr)
227 gv_check_eq("mesh-reads-back-one-layer" as *u8, wt[3], 1, ctr)
228 gv_check_eq("mesh-reads-back-every-triangle" as *u8, wt[2], PG_NT_EXPECT, ctr)
229 gv_check_eq("mesh-is-watertight-every-edge-has-one-reverse-twin" as *u8, wt[0], 0, ctr)
230 gv_check_eq("mesh-has-no-duplicate-edge" as *u8, wt[1], 0, ctr)
231 gv_check_near("mesh-tube-vertex-lies-on-the-surface-radius" as *u8, wt[5], rmean, PG_TOL_RING, ctr)
232 // ---- surface coordinates ----
233 let O: *i64 = sys_mmap(PL_V3*PL_I64) as *i64
234 let N: *i64 = sys_mmap(PL_V3*PL_I64) as *i64
235 let T: *i64 = sys_mmap(PL_V3*PL_I64) as *i64
236 let inf: *i64 = sys_mmap(8*PL_I64) as *i64
237 pl_surface_at(p, PL_FQ/2, 0, PL_FQ, O, N, T, inf)
238 gv_check_eq("attach-skeleton-takes-the-cubic-path" as *u8, inf[4], PL_ASKEL_SPLINE, ctr)
239 gv_check_near("yaw-0-lands-at-mid-length" as *u8, O[0], PG_LEN/2, 10, ctr)
240 gv_check("yaw-0-points-straight-down" as *u8, ((O[2] < 0) * (pg_abs(O[1]) <= PG_TOL_RING)) as i64, ctr)
241 gv_check_near("yaw-0-hits-the-surface-radius" as *u8, inf[3], rmean, 4, ctr)
242 gv_check("ray-and-hit-agree-to-a-few-milliradians" as *u8, (inf[0] >= PL_FQ - PG_TOL_COS) as i64, ctr)
243 gv_check_near("tangent-runs-along-x" as *u8, T[0], PL_ONE, PG_TOL_U10, ctr)
244 gv_check("normal-points-down-with-the-ray" as *u8, (N[2] < 0 - PL_ONE/2) as i64, ctr)
245 let cos0: i64 = inf[0]
246 let lat0: i64 = pg_abs(O[1])
247 pl_surface_at(p, PL_FQ/2, PL_FQ/2, PL_FQ, O, N, T, inf)
248 gv_check("half-turn-yaw-points-to-plus-y" as *u8, ((O[1] > 0) * (pg_abs(O[2]) <= PG_TOL_RING)) as i64, ctr)
249 pl_surface_at(p, PL_FQ/2, PL_FQ, PL_FQ, O, N, T, inf)
250 gv_check("full-turn-yaw-points-up" as *u8, ((O[2] > 0) * (pg_abs(O[1]) <= PG_TOL_RING)) as i64, ctr)
251 pl_surface_at(p, PL_FQ/2, 0, 0, O, N, T, inf)
252 gv_check_near("rad-0-is-the-skeleton-itself-yz" as *u8, pg_abs(O[1]) + pg_abs(O[2]), 0, PG_TOL_U10, ctr)
253 // ---- the genes ----
254 let q: *PlPart = pl_new(PG_NU, PG_NV)
255 pl_copy(q, p)
256 pl_mutate(q, PG_SEED, 0)
257 gv_check_eq("var-0-mutation-is-the-identity-on-every-gene" as *u8, pg_gene_diff(p, q), 0, ctr)
258 pl_mutate(q, PG_SEED, PL_FQ)
259 let rdelta: i64 = pg_sum_absdiff(p.rad, q.rad, PG_NU) / PL_FQ
260 gv_check("var-1-mutation-moves-the-radii" as *u8, (rdelta > 0) as i64, ctr)
261 var thsum: i64 = 0
262 var i: i64 = 0
263 while i < PG_NU - 1 { thsum = thsum + q.theta[i]; i = i + 1 }
264 gv_check_near("pitch-noise-is-zero-mean" as *u8, thsum, 0, PG_NU, ctr)
265 gv_check("mutation-keeps-the-radii-positive" as *u8, (q.rad[0] >= PL_MIN_RAD) as i64, ctr)
266 let q2: *PlPart = pl_new(PG_NU, PG_NV)
267 pl_copy(q2, p)
268 pl_mutate(q2, PG_SEED, PL_FQ)
269 gv_check_eq("mutation-is-deterministic-per-seed" as *u8, pg_gene_diff(q, q2), 0, ctr)
270 gv_check_eq("mutated-part-recomposes" as *u8, pl_recompose(q), 0, ctr)
271 // ---- the part file ----
272 gv_check("part-file-saves" as *u8, (pl_save(partPath, p) > 0) as i64, ctr)
273 let L: *PlPart = pl_load(partPath)
274 gv_check("part-file-loads" as *u8, ((L as i64) != 0) as i64, ctr)
275 if (L as i64) != 0 {
276 gv_check_eq("loaded-shape-matches" as *u8, L.nu*100 + L.nv, PG_NU*100 + PG_NV, ctr)
277 gv_check_eq("loaded-genes-are-byte-identical" as *u8, pg_gene_diff(p, L), 0, ctr)
278 gv_check_eq("loaded-part-recomposes-to-the-same-handles" as *u8, pg_sum_absdiff(p.hnd, L.hnd, PG_NU*PG_NV*PL_V3), 0, ctr)
279 }
280 gv_check_eq("absent-part-file-loads-as-null" as *u8, pl_load(PG_ABSENT) as i64, 0, ctr)
281 // ---- the bent part: genes -> handles -> genes ----
282 let b: *PlPart = pl_new(PG_NU, PG_NV)
283 b.root[0] = 0; b.root[1] = 0; b.root[2] = 0
284 b.length = PG_LEN
285 i = 0
286 while i < PG_NU - 1 { b.prop[i] = PG_PROP; b.theta[i] = 0; b.yoff[i] = 0; i = i + 1 }
287 b.theta[3] = PG_THETA30
288 b.theta[4] = PG_THETA30
289 i = 0
290 while i < PG_NU { b.rad[i] = PG_R * PL_FQ; b.ts[i] = i*PL_FQ/(PG_NU-1); i = i + 1 }
291 i = 0
292 while i < PG_NU {
293 var j: i64 = 0
294 while j < PG_NV {
295 let ang: i64 = 0 - VM_PI2 + VM_TAU * j / PG_NV
296 b.prof[(i*PG_NV+j)*PL_V3] = 0
297 b.prof[(i*PG_NV+j)*PL_V3+1] = vm_cos(ang) * PL_FQ / PL_ONE
298 b.prof[(i*PG_NV+j)*PL_V3+2] = vm_sin(ang) * PL_FQ / PL_ONE
299 j = j + 1
300 }
301 i = i + 1
302 }
303 gv_check_eq("bent-part-recomposes" as *u8, pl_recompose(b), 0, ctr)
304 gv_check("bent-skeleton-rises-after-the-pitch" as *u8, ((b.skel[5*PL_V3+2] > 150) * (b.skel[5*PL_V3] < PG_LEN)) as i64, ctr)
305 let b2: *PlPart = pl_new(PG_NU, PG_NV)
306 gv_check_eq("bent-handles-decompose" as *u8, pl_decompose(b.hnd, PG_NU, PG_NV, b2), PG_NU*PG_NV, ctr)
307 gv_check_near("bent-round-trip-recovers-the-pitch" as *u8, b2.theta[3], PG_THETA30, PG_TOL_THETA, ctr)
308 gv_check_near("bent-round-trip-keeps-the-straight-segments-flat" as *u8, b2.theta[1], 0, PG_TOL_THETA, ctr)
309 gv_check_near("bent-round-trip-recovers-the-radius-at-the-bend" as *u8, pl_rad_u10(b2, 3), PG_R, PG_TOL_RING, ctr)
310 gv_check_near("bent-round-trip-recovers-the-length" as *u8, b2.length, PG_LEN, 6, ctr)
311 gv_check_near("bent-round-trip-recovers-the-proportions" as *u8, b2.prop[2], PG_PROP, PG_TOL_PROP, ctr)
312 // ---- neg-controls ----
313 let C: *i64 = sys_mmap(PG_NU*PG_NV*PL_V3*PL_I64) as *i64
314 pg_tube(C, PG_NU, PG_NV, PG_R, PG_CONE_END, PG_LEN)
315 let c: *PlPart = pl_new(PG_NU, PG_NV)
316 pl_decompose(C, PG_NU, PG_NV, c)
317 gv_check("neg-control-a-cone-reads-as-a-cone" as *u8, (pl_rad_u10(c, 0) - pl_rad_u10(c, PG_NU-1) >= 90) as i64, ctr)
318 pl_recompose(c)
319 pl_surface(c, 0, PL_FQ/3, S)
320 let rc0: i64 = vm_isqrt(S[1]*S[1] + S[2]*S[2])
321 pl_surface(c, PL_FQ, PL_FQ/3, S)
322 let rc1: i64 = vm_isqrt(S[1]*S[1] + S[2]*S[2])
323 gv_check("neg-control-cone-surface-narrows-toward-the-tip" as *u8, (rc0 - rc1 >= 60) as i64, ctr)
324 let tiny: *PlPart = pl_new(3, PG_NV)
325 gv_check_eq("neg-control-three-rows-are-refused-by-name" as *u8, pl_decompose(H, 3, PG_NV, tiny), 0 - 1, ctr)
326 gv_check_eq("neg-control-a-face-that-leaves-no-cap-fan-is-refused" as *u8, pl_mesh_counts(p, PG_LEN, cnt), 0 - 1, ctr)
327 gv_values_head()
328 gv_kv("cylinder_handle_roundtrip_err_u10" as *u8, herr)
329 gv_kv("surface_radius_mean_u10" as *u8, rmean)
330 gv_kv("surface_radius_spread_u10" as *u8, rmax - rmin)
331 gv_kv("mesh_ulength_u10" as *u8, cnt[0])
332 gv_kv("mesh_vlength_u10" as *u8, cnt[1])
333 gv_kv("mesh_ntris" as *u8, nt)
334 gv_kv("mesh_bytes" as *u8, rep[1])
335 gv_kv("mesh_unmatched_edges" as *u8, wt[0])
336 gv_kv("attach_cosine_q16" as *u8, cos0)
337 gv_kv("attach_lateral_miss_u10" as *u8, lat0)
338 gv_kv("mutate_rad_delta_u10" as *u8, rdelta)
339 gv_kv("bent_theta3_recovered" as *u8, b2.theta[3])
340 gv_kv("bent_length_recovered_u10" as *u8, b2.length)
341 gv_kv("cone_r0_u10" as *u8, rc0)
342 gv_kv("cone_r1_u10" as *u8, rc1)
343 return gv_verdict("nx_partloft_gate" as *u8, ctr, "Infinigen's NurbsPart in NishiLang: decompose, genes, recompose, cubic B-spline surface, surface coordinates and a watertight NXMSH2, held to known answers" as *u8)
344}