nx_meshvalid_lib.nx
buildroot/runtime/nx_meshvalid_lib.nx
about
nx_meshvalid_lib.nx -- THE MESH VALIDITY REFEREE: it REFUSES a broken asset instead of shipping it.
/compare/dcc DC3, and it is the tooth the retopology and sculpt rungs both bind their claims to.
WHY THIS AND NOT AN OVERLAY. Blender, ZBrush and Maya all SHOW mesh problems to an artist in a viewport
overlay; none of them REFUSES on one, because a person is always there to look. An estate that emits
assets from rules with no person in the loop needs the opposite: a named count, the offending element
index, and a non-zero verdict. nx_spendgate found no incumbent -- nx_meshgen BUILDS watertight meshes by
construction (surface nets) and nx_step_tess2 tessellates with hole bridging, but nothing in the estate
VALIDATES a mesh it did not itself produce, which is exactly the case an importer creates.
EVERY DEFECT IS ITS OWN NAMED CLASS, never a single boolean. A compound assertion that will not name its
failing conjunct is a false-alarm generator: the reader always guesses the alarming one. Six classes,
each with a count AND a first-offender index, and a manifold verdict composed from them.
COMPLEXITY IS DECLARED, NOT DISCOVERED. Edge and vertex identity both go through an open-addressing hash
table whose capacity is DERIVED from the input size (next power of two at or above four times the element
count, a load factor at or below one quarter), so the check is linear in triangles rather than the
quadratic pairwise scan the naive version would be. There is no fixed table size to outgrow and no cap to
silently hit. All integer: the zero-area test is an exact cross product, never a float epsilon, so
DEGENERATE here means exactly degenerate rather than nearly so.
100% sovereign. No hardware writes (Rule 26). license_tier: ORIGINAL
dependencies 1 imports · 4 importers
imports: nx_syscalls.nx
imported by: nx_body_skin_junction_gate_t345.nxnx_meshvalid_gate.nxnx_uvunwrap_gate.nxnx_uvunwrap_lib.nx
structs
| none |
consts
| 24 | const MV_H_NV: i64 = 0 |
| 25 | const MV_H_NT: i64 = 1 |
| 26 | const MV_H_ECAP: i64 = 2 |
| 27 | const MV_H_VCAP: i64 = 3 |
| 28 | const MV_H_ERR: i64 = 4 |
| 29 | const MV_H_RAN: i64 = 5 |
| 38 | const MV_HDR: i64 = 24 |
| 39 | const MV_I64: i64 = 8 |
| 42 | const MV_C_DEGEN: i64 = 6 |
| 43 | const MV_C_INDEX: i64 = 7 |
| 44 | const MV_C_NONMAN: i64 = 8 |
| 45 | const MV_C_BOUND: i64 = 9 |
| 46 | const MV_C_WIND: i64 = 10 |
| 47 | const MV_C_DUPV: i64 = 11 |
| 48 | const MV_FIRST_STRIDE: i64 = 8 |
| 50 | const MV_OK: i64 = 0 |
| 51 | const MV_E_INDEX: i64 = 0 - 1 |
| 52 | const MV_E_DEGEN: i64 = 0 - 2 |
| 53 | const MV_E_NONMAN: i64 = 0 - 3 |
| 54 | const MV_E_BOUND: i64 = 0 - 4 |
| 55 | const MV_E_WIND: i64 = 0 - 5 |
| 56 | const MV_E_DUPV: i64 = 0 - 6 |
| 57 | const MV_E_ARGS: i64 = 0 - 7 |
| 58 | const MV_E_NOTRUN: i64 = 0 - 8 |
| 63 | const MV_MUL_A: i64 = 1099511628211 |
| 64 | const MV_MUL_B: i64 = 2654435761 |
| 65 | const MV_LOAD_NUM: i64 = 4 |
| 68 | const MV_TREC: i64 = 4 |
| 69 | const MV_T_K0: i64 = 0 |
| 70 | const MV_T_K1: i64 = 1 |
| 71 | const MV_T_CNT: i64 = 2 |
| 72 | const MV_T_BAL: i64 = 3 |
| 73 | const MV_EMPTY: i64 = 0 - 999999999 |
| 81 | const MV_VCOMP: i64 = 3 // components per vertex: [x, y, z] |
| 82 | const MV_VX: i64 = 0 |
| 83 | const MV_VY: i64 = 1 |
| 84 | const MV_VZ: i64 = 2 |
| 85 | const MV_TVERT: i64 = 3 // vertices per triangle: [a, b, c] -- and a triangle contributes exactly |
| 87 | const MV_TA: i64 = 0 |
| 88 | const MV_TB: i64 = 1 |
| 89 | const MV_TC: i64 = 2 |
| 94 | const MV_BOUNDARY_FACES: i64 = 1 |
| 95 | const MV_MANIFOLD_FACES: i64 = 2 |
| 100 | const MV_VKEY_FOLD: i64 = 3 |
functions
| 102 | func mv_err_name(e: i64) -> *u8 called by 1: main |
| 116 | func mv_cap_for(n: i64) -> i64 |
| 124 | func mv_verts_off(m: *i64) -> i64 { return MV_HDR } |
| 125 | func mv_tris_off(m: *i64) -> i64 { return MV_HDR + m[MV_H_NV] * MV_VCOMP } |
| 126 | func mv_etab_off(m: *i64) -> i64 { return MV_HDR + m[MV_H_NV] * MV_VCOMP + m[MV_H_NT] * MV_TVERT } |
| 127 | func mv_vtab_off(m: *i64) -> i64 { return mv_etab_off(m) + m[MV_H_ECAP] * MV_TREC } |
| 129 | func mv_words_for(nv: i64, nt: i64, ecap: i64, vcap: i64) -> i64 called by 1: mv_new |
| 133 | func mv_new(nv: i64, nt: i64) -> *i64 |
| 148 | func mv_set_vert(m: *i64, i: i64, x: i64, y: i64, z: i64) -> i64 |
| 158 | func mv_set_tri(m: *i64, i: i64, a: i64, b: i64, c: i64) -> i64 |
| 168 | func mv_count(m: *i64, slot: i64) -> i64 |
| 175 | func mv_first(m: *i64, slot: i64) -> i64 called by 1: main |
| 182 | func mv_bump(m: *i64, slot: i64, idx: i64) -> i64 called by 1: mv_check |
| 188 | func mv_mix(a: i64, b: i64, cap: i64) -> i64 |
| 197 | func mv_edge_touch(m: *i64, a: i64, b: i64, dir: i64) -> i64 |
| 229 | func mv_vert_touch(m: *i64, i: i64) -> i64 |
| 261 | func mv_is_degenerate(m: *i64, a: i64, b: i64, c: i64) -> i64 |
| 283 | func mv_check(m: *i64) -> i64 called by 3: mainmainuvi_validate calls 6: mv_tris_offmv_bumpmv_is_degeneratemv_edge_touchmv_etab_offmv_vert_touch |
| 361 | func mv_manifold(m: *i64) -> i64 |
| 367 | func mv_verdict(m: *i64) -> i64 { return m[MV_H_ERR] } called by 1: main |