code wiki / (root) / nx_partloft_capture_t319.nx

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}