code wiki / (root) / nx_nxa_corner_prepare_candidate_t280.nx

nx_nxa_corner_prepare_candidate_t280.nx source

↩ module page · 114 lines · 6377 B

1// nx_nxa_corner_prepare_candidate_t280.nx -- Prepares candidate data for corner processing by extracting vertex and triangle information from an NXA file. 2import "nx_uvunwrap_lib.nx" 3import "nx_nxa.nx" 4import "nx_sha256.nx" 5 6// NCP1 v1 is an inspection/preparation packet, not TEXC and not an anatomical chart. 7// Source bytes remain immutable; source SHA plus corner indices preserve every original attribute. 8const NCP_MAGIC:i64=0x3150434e 9const NCP_VERSION:i64=1 10const NCP_HEADER:i64=36 11const NCP_ROW:i64=8 12const NCP_HASH_WORD:i64=32 13const NCP_MAX:i64=9223372036854775807 14 15func ncp_model_new(nv:i64,nt:i64)->*i64{ 16 if nv<3{return 0 as *i64};if nt<1{return 0 as *i64} 17 // The existing layout is affine in vertex, triangle and hash-table counts. 18 // Derive its coefficients through that owner, then check each extent before allocation. 19 if nt>NCP_MAX/2/MV_LOAD_NUM/UV_TRI{return 0 as *i64} 20 let h:*i64=sys_mmap_try(UV_HDR*UV_I64) as *i64;if (h as i64)<=0{return 0 as *i64} 21 let base:i64=uv_layout(h) 22 h[UV_H_NV]=1;let vc:i64=uv_layout(h)-base;h[UV_H_NV]=0 23 h[UV_H_NT]=1;let tc:i64=uv_layout(h)-base;h[UV_H_NT]=0 24 h[UV_H_ECAP]=1;h[UV_H_SCAP]=1;let ec:i64=uv_layout(h)-base 25 let cap:i64=mv_cap_for(nt*UV_TRI) 26 var words:i64=base;let maxwords:i64=NCP_MAX/UV_I64 27 if nv>(maxwords-words)/vc{sys_munmap_direct(h as *u8,UV_HDR*UV_I64);return 0 as *i64};words=words+nv*vc 28 if nt>(maxwords-words)/tc{sys_munmap_direct(h as *u8,UV_HDR*UV_I64);return 0 as *i64};words=words+nt*tc 29 if cap>(maxwords-words)/ec{sys_munmap_direct(h as *u8,UV_HDR*UV_I64);return 0 as *i64};words=words+cap*ec 30 h[UV_H_NV]=nv;h[UV_H_NT]=nt;h[UV_H_ECAP]=cap;h[UV_H_SCAP]=cap 31 if uv_layout(h)!=words{sys_munmap_direct(h as *u8,UV_HDR*UV_I64);return 0 as *i64} 32 let m:*i64=sys_mmap_try(words*UV_I64) as *i64 33 if (m as i64)>0{ 34 m[UV_H_NV]=nv;m[UV_H_NT]=nt;m[UV_H_ECAP]=cap;m[UV_H_SCAP]=cap 35 uv_layout(m);m[UV_H_ERR]=UV_E_NOTRUN;m[UV_H_STAGE]=UV_ST_NEW;m[UV_H_MVERR]=MV_E_NOTRUN;m[UV_H_MVCLOSED]=0-1 36 } 37 sys_munmap_direct(h as *u8,UV_HDR*UV_I64) 38 if (m as i64)<=0{return 0 as *i64};return m 39} 40func ncp_model_free(m:*i64)->i64{ 41 if m==(0 as *i64){return 0};return sys_munmap_direct(m as *u8,uv_words_used(m)*UV_I64) 42} 43func ncp_model_nxa(b:*u8,n:i64)->*i64{ 44 if b==(0 as *u8){return 0 as *i64} 45 let ve:i64=nxa_section_entry(b,n,nxa_tag4("VERT"));if ve<0{return 0 as *i64} 46 let te:i64=nxa_section_entry(b,n,nxa_tag4("TRIS"));if te<0{return 0 as *i64} 47 let w:*i64=b as *i64 48 if w[ve+2]<1{return 0 as *i64};if w[te+2]<1{return 0 as *i64} 49 let v:i64=w[ve+1]/8;let t:i64=w[te+1]/8 50 let nv:i64=w[v];let nt:i64=w[t] 51 if nv<3{return 0 as *i64};if nt<1{return 0 as *i64} 52 if nv>(w[ve+2]-1)/3{return 0 as *i64};if nt>(w[te+2]-1)/3{return 0 as *i64} 53 let m:*i64=ncp_model_new(nv,nt);if m==(0 as *i64){return m} 54 var i:i64=0;while i<nv{uv_set_vert(m,i,w[v+1+i*3],w[v+2+i*3],w[v+3+i*3]);i=i+1} 55 i=0;while i<nt{ 56 let a:i64=w[t+1+i*3];let bb:i64=w[t+2+i*3];let c:i64=w[t+3+i*3] 57 if a<0{ncp_model_free(m);return 0 as *i64};if bb<0{ncp_model_free(m);return 0 as *i64};if c<0{ncp_model_free(m);return 0 as *i64} 58 if a>=nv{ncp_model_free(m);return 0 as *i64};if bb>=nv{ncp_model_free(m);return 0 as *i64};if c>=nv{ncp_model_free(m);return 0 as *i64} 59 uv_set_tri(m,i,a,bb,c);i=i+1 60 };return m 61} 62// Explicit seam input: packed i64 [count, vertexA, vertexB, ...]. Unknown edges 63// are rejected before modifying the model; chart IDs never substitute for bone IDs. 64func ncp_seams(m:*i64,s:*i64,words:i64)->i64{ 65 if m==(0 as *i64){return UV_E_ARGS};if s==(0 as *i64){return UV_E_ARGS} 66 if words<1{return UV_E_ARGS};let count:i64=s[0] 67 if count<0{return UV_E_ARGS};if count>(words-1)/2{return UV_E_ARGS} 68 if count*2+1!=words{return UV_E_ARGS} 69 var i:i64=0 70 while i<count{ 71 let a:i64=s[1+i*2];let b:i64=s[2+i*2] 72 if a<0{return UV_E_ARGS};if b<0{return UV_E_ARGS};if a>=m[UV_H_NV]{return UV_E_ARGS};if b>=m[UV_H_NV]{return UV_E_ARGS};if a==b{return UV_E_ARGS} 73 var found:i64=0;var t:i64=0 74 while t<m[UV_H_NT]{var k:i64=0;while k<3{ 75 let x:i64=uv_ti(m,t,k);let y:i64=uv_ti(m,t,(k+1)%3) 76 if x==a{if y==b{found=1}};if x==b{if y==a{found=1}};k=k+1 77 };if found==1{break};t=t+1} 78 if found==0{return UV_E_ARGS};i=i+1 79 } 80 i=0;while i<count{let rc:i64=uv_seam_set(m,s[1+i*2],s[2+i*2]);if rc!=UV_OK{return rc};i=i+1};return UV_OK 81} 82// Header words: magic,version,header,row,nv,nt,ncorn,stage,verdict,ncharts, 83// validCorners,metricsAvailable,mvVerdict,closed,angleMean,angleMax,areaMean, 84// areaMax,flipped,uvDegenerate,overlap,sourceBytes,seams,grid, 85// allocationWords,overlapScope(1=chart-box),physicalScaleKnown(0), 86// anatomicalAssignmentKnown(0),reserved*4,sourceSHA256[32 raw bytes]. 87// Row: triangle,corner,sourceVertex,chart,class,uQ16,vQ16,uvValid. 88func ncp_emit(m:*i64,b:*u8,n:i64,result:i64,outbytes:*i64)->*u8{ 89 if outbytes==(0 as *i64){return 0 as *u8};outbytes[0]=0 90 if m==(0 as *i64){return 0 as *u8};if b==(0 as *u8){return 0 as *u8};if n<0{return 0 as *u8} 91 let corners:i64=m[UV_H_NCORN] 92 if corners>(NCP_MAX/8-NCP_HEADER)/NCP_ROW{return 0 as *u8} 93 let words:i64=NCP_HEADER+corners*NCP_ROW 94 let p:*i64=sys_mmap_try(words*8) as *i64;if (p as i64)<=0{return 0 as *u8} 95 p[0]=NCP_MAGIC;p[1]=NCP_VERSION;p[2]=NCP_HEADER;p[3]=NCP_ROW 96 p[4]=m[UV_H_NV];p[5]=m[UV_H_NT];p[6]=corners;p[7]=uv_stage(m);p[8]=result;p[9]=uv_chart_count(m) 97 var valid:i64=0;if result==UV_OK{if uv_stage(m)>=UV_ST_SOLVED{valid=1}} 98 p[10]=corners*valid;p[11]=0;if uv_stage(m)>=UV_ST_MEASURED{p[11]=1} 99 p[12]=uv_mv_verdict(m);p[13]=uv_mv_closed(m) 100 var k:i64=14;while k<=20{p[k]=0-1;k=k+1} 101 if p[11]==1{p[14]=uv_angle_mean(m);p[15]=uv_angle_max(m);p[16]=uv_area_mean(m);p[17]=uv_area_max(m);p[18]=uv_flipped(m);p[19]=uv_uvdegen(m)} 102 if uv_stage(m)>=UV_ST_MEASURED{if result==UV_OK{p[20]=uv_overlaps(m)};if result==UV_E_OVERLAP{p[20]=uv_overlaps(m)}} 103 p[21]=n;p[22]=uv_seam_count(m);p[23]=uv_grid(m);p[24]=words;p[25]=1 104 let hr:i64=sha256_digest_checked_native(b,n,((p as i64)+NCP_HASH_WORD*8) as *u8) 105 if hr!=0{sys_munmap_direct(p as *u8,words*8);return 0 as *u8} 106 var t:i64=0;while t<m[UV_H_NT]{k=0;while k<3{ 107 let o:i64=NCP_HEADER+(t*3+k)*NCP_ROW 108 p[o]=t;p[o+1]=k;p[o+2]=uv_ti(m,t,k);p[o+3]=0-1;p[o+4]=0-1;p[o+5]=0;p[o+6]=0;p[o+7]=valid 109 if uv_stage(m)>=UV_ST_CHARTS{p[o+3]=uv_chart_of_tri(m,t);p[o+4]=uv_corner_class(m,t,k)} 110 if valid==1{p[o+5]=uv_corner_u(m,t,k);p[o+6]=uv_corner_v(m,t,k)} 111 k=k+1 112 };t=t+1} 113 outbytes[0]=words*8;return p as *u8 114}