code wiki / (root) / nx_solid_column_union_candidate_t365.nx

nx_solid_column_union_candidate_t365.nx source

↩ module page · 50 lines · 3394 B

1// Versioned solid-column composition shared by mesh-field consumers. 2// Crossings are sorted, distinct, parity events for each CLOSED part, in caller units. 3// Output is disjoint union intervals; this is not a Euclidean distance field. 4import "nx_buf_dyn.nx" 5import "nx_syscalls.nx" 6import "nx_sort.nx" 7const SFU_INVALID:i64=-701 8const SFU_ODD:i64=-702 9const SFU_ORDER:i64=-703 10const SFU_RESOURCE:i64=-704 11const SFU_ALLOCATION:i64=-705 12struct SfuFailure { code:i64, part:i64, crossing:i64, } 13func sfu_fail(e:*SfuFailure,code:i64,part:i64,crossing:i64)->i64{e.code=code;e.part=part;e.crossing=crossing;return code} 14// In-place workspace path for callers retaining an allocation across many columns. 15// Input contains paired intervals. Caller has already checked each part's parity/order. 16func sfu_merge_workspace_v1(pairs:*i64,nh:i64)->i64{ 17 if nh<0||(nh&1)!=0{return SFU_INVALID};if nh==0{return 0} 18 let sorted:i64=nx_sort_pairs_first(pairs,nh/2);if sorted<0{return sorted} 19 var used:i64=2;var i:i64=2;while i<nh{if pairs[i]<=pairs[used-1]{if pairs[i+1]>pairs[used-1]{pairs[used-1]=pairs[i+1]}}else{pairs[used]=pairs[i];pairs[used+1]=pairs[i+1];used=used+2};i=i+2};return used 20} 21func sfu_union_v1(h:*i64,nh:i64,counts:*i64,np:i64,budget:i64,out:*NxBufOwned,e:*SfuFailure)->i64{ 22 if (e as i64)<=0{return SFU_INVALID};e.code=0;e.part=-1;e.crossing=-1 23 if nh<0||np<0||budget<0{return sfu_fail(e,SFU_INVALID,-1,-1)} 24 if nx_bo_state(out)!=0{return sfu_fail(e,SFU_INVALID,-1,-1)} 25 if out.cap!=0{return sfu_fail(e,SFU_INVALID,-1,-1)} 26 if nh>NX_BO_I64_MAX/8||np>NX_BO_I64_MAX/8{return sfu_fail(e,SFU_RESOURCE,-1,-1)} 27 if nh>0&&(h as i64)<=0{return sfu_fail(e,SFU_INVALID,-1,-1)} 28 if np>0&&(counts as i64)<=0{return sfu_fail(e,SFU_INVALID,-1,-1)} 29 var off:i64=0;var p:i64=0 30 while p<np{let n:i64=counts[p];if n<0||n>nh-off{return sfu_fail(e,SFU_INVALID,p,n)};if (n&1)!=0{return sfu_fail(e,SFU_ODD,p,n)} 31 var i:i64=1;while i<n{if h[off+i]<=h[off+i-1]{return sfu_fail(e,SFU_ORDER,p,i)};i=i+1};off=off+n;p=p+1} 32 if off!=nh{return sfu_fail(e,SFU_INVALID,np,off)} 33 if nh==0{return 0};let bytes:i64=nh*8;if budget>0&&bytes>budget{return sfu_fail(e,SFU_RESOURCE,-1,bytes)} 34 let raw:*u8=sys_mmap_try(bytes);if (raw as i64)<=0{return sfu_fail(e,SFU_ALLOCATION,-1,bytes)};let pairs:*i64=raw as *i64 35 var i:i64=0;while i<nh{pairs[i]=h[i];i=i+1} 36 let used:i64=sfu_merge_workspace_v1(pairs,nh);if used<0{sys_munmap_direct(raw,bytes);return sfu_fail(e,used,-1,nh/2)} 37 out.buf=raw;out.len=used*8;out.cap=bytes;return 0 38} 39// Exact capped distance to the union boundary ALONG THIS COLUMN, not metric SDF. 40// The symmetric coordinate domain makes every subtraction representable in signed i64. 41const SFU_COORD:i64=4611686018427387903 42func sfu_column_value(intervals:*i64,n:i64,x:i64,far:i64,value:*i64)->i64{ 43 if n<0||(n&1)!=0||n>NX_BO_I64_MAX/8||far<=0||x<0-SFU_COORD||x>SFU_COORD{return SFU_INVALID} 44 if (value as i64)<=0{return SFU_INVALID};if n>0&&(intervals as i64)<=0{return SFU_INVALID} 45 var i:i64=0;while i<n{if intervals[i]<0-SFU_COORD||intervals[i]>SFU_COORD{return SFU_INVALID};if i>0{if intervals[i]<=intervals[i-1]{return SFU_ORDER}};i=i+1} 46 var best:i64=far;var inside:i64=0;i=0 47 while i<n{let lo:i64=intervals[i];let hi:i64=intervals[i+1];var d:i64=0 48 if x<lo{d=lo-x}else{if x>hi{d=x-hi}else{inside=1;d=x-lo;if hi-x<d{d=hi-x}}};if d<best{best=d};i=i+2} 49 if inside==1{best=0-best};value[0]=best;return 0 50}