nx_nxa_corner_checkpoint_candidate_t280.nx source
↩ module page · 39 lines · 3263 B
1import "nx_nxa_corner_prepare_candidate_t280.nx"
2// Restore topology only. Failed UV coordinates remain unusable. Source hash
3// and every corner index bind the checkpoint to immutable source attributes.
4func ncp_restore_topology(src:*u8,bytes:i64,packet:*u8,n:i64)->*i64{
5 if src==(0 as *u8){return 0 as *i64};if packet==(0 as *u8){return 0 as *i64};if n<NCP_HEADER*8{return 0 as *i64};if n%8!=0{return 0 as *i64}
6 let p:*i64=packet as *i64
7 if p[0]!=NCP_MAGIC{return 0 as *i64};if p[1]!=NCP_VERSION{return 0 as *i64};if p[2]!=NCP_HEADER{return 0 as *i64};if p[3]!=NCP_ROW{return 0 as *i64}
8 if p[6]<3{return 0 as *i64};if p[6]>(NCP_MAX/8-NCP_HEADER)/NCP_ROW{return 0 as *i64};if (NCP_HEADER+p[6]*NCP_ROW)*8!=n{return 0 as *i64};if p[24]!=n/8{return 0 as *i64};if p[21]!=bytes{return 0 as *i64}
9 let hash:*u8=sys_mmap_try(32);if (hash as i64)<=0{return 0 as *i64};let hr:i64=sha256_digest_checked_native(src,bytes,hash);var mismatch:i64=0;var i:i64=0
10 while i<32{if hash[i]!=packet[NCP_HASH_WORD*8+i]{mismatch=1};i=i+1};sys_munmap_direct(hash,32);if hr!=0{return 0 as *i64};if mismatch!=0{return 0 as *i64}
11 let m:*i64=ncp_model_nxa(src,bytes);if m==(0 as *i64){return m}
12 var valid:i64=1;if p[4]!=m[UV_H_NV]{valid=0};if p[5]!=m[UV_H_NT]{valid=0};if p[6]!=m[UV_H_NT]*3{valid=0};if p[9]<1{valid=0};if p[9]>m[UV_H_NT]{valid=0};if p[7]<UV_ST_CHARTS{valid=0}
13 if valid==0{ncp_model_free(m);return 0 as *i64}
14 var t:i64=0
15 while t<m[UV_H_NT]{var k:i64=0;while k<3{let o:i64=NCP_HEADER+(t*3+k)*NCP_ROW
16 if p[o]!=t{valid=0};if p[o+1]!=k{valid=0};if p[o+2]!=uv_ti(m,t,k){valid=0};if p[o+3]<0{valid=0};if p[o+3]>=p[9]{valid=0};if p[o+4]<0{valid=0};if p[o+4]>=p[6]{valid=0};k=k+1};t=t+1}
17 if valid==0{ncp_model_free(m);return 0 as *i64};if uv_chart_build(m)!=UV_OK{ncp_model_free(m);return 0 as *i64}
18 let target:*i64=ncp_model_nxa(src,bytes);if target==(0 as *i64){ncp_model_free(m);return target}
19 var edge:i64=0
20 while edge<m[UV_H_ECAP]{let o:i64=m[UV_O_ETAB]+edge*UV_EREC
21 if m[o+UV_ED_T0]!=0{if m[o+UV_ED_T1]!=0{
22 let ta:i64=m[o+UV_ED_T0]-1;let tb:i64=m[o+UV_ED_T1]-1;var split:i64=0;var side:i64=0
23 while side<2{let v:i64=m[o+side];let a:i64=uvi_corner_of(m,ta,v);let b:i64=uvi_corner_of(m,tb,v)
24 if a<0{valid=0;break};if b<0{valid=0;break}
25 if p[NCP_HEADER+(ta*3+a)*NCP_ROW+4]!=p[NCP_HEADER+(tb*3+b)*NCP_ROW+4]{split=1};side=side+1
26 }
27 if valid==0{break};if split==1{if uv_seam_set(target,m[o+UV_ED_LO],m[o+UV_ED_HI])!=UV_OK{valid=0;break}}
28 }};edge=edge+1
29 };ncp_model_free(m)
30 if valid==0{ncp_model_free(target);return 0 as *i64};if uv_chart_build(target)!=UV_OK{ncp_model_free(target);return 0 as *i64};if uv_chart_count(target)!=p[9]{ncp_model_free(target);return 0 as *i64}
31 let links:*i64=sys_mmap_try(p[6]*2*8) as *i64;if (links as i64)<=0{ncp_model_free(target);return 0 as *i64}
32 t=0;while t<target[UV_H_NT]{var k:i64=0;while k<3{
33 let o:i64=NCP_HEADER+(t*3+k)*NCP_ROW;if p[o+3]!=uv_chart_of_tri(target,t){valid=0}
34 let a:i64=p[o+4];let b:i64=uv_corner_class(target,t,k)
35 if links[a]!=0{if links[a]!=b+1{valid=0}}else{links[a]=b+1}
36 if links[p[6]+b]!=0{if links[p[6]+b]!=a+1{valid=0}}else{links[p[6]+b]=a+1};k=k+1
37 };t=t+1}
38 sys_munmap_direct(links as *u8,p[6]*2*8);if valid==0{ncp_model_free(target);return 0 as *i64};return target
39}