code wiki / (root) / nx_bezier_patch.nx

nx_bezier_patch.nx source

↩ module page · 76 lines · 2581 B

1// nx_bezier_patch.nx -- PARAMETRIC SPLINE SURFACE: a bicubic Bezier tensor-product patch (the non-rational core of 2// NURBS, and exactly what D3D11+ hull/domain tessellation shaders evaluate). A 4x4 control net -> S(u,v) via the 3// cubic Bernstein basis -> tessellated triangle mesh. Smooth CAD/industrial forms from a small control net. Corners 4// are INTERPOLATED (Bezier property); interior control points PULL the surface (not interpolated) = smoothness. 5// Integer Bernstein numerators (denominator N^3 each -> N^6 for the tensor product); exact at the corners+center. 6// license_tier: ORIGINAL 7import "nx_syscalls.nx" 8import "nx_mesh3.nx" 9 10// cubic Bernstein numerator for control index a (0..3) at parameter i/N. denominator = N^3. sum over a == N^3. 11func bez_bern(a: i64, i: i64, N: i64) -> i64 { 12 let m: i64 = N - i 13 if a == 0 { return m*m*m } 14 if a == 1 { return 3*i*m*m } 15 if a == 2 { return 3*i*i*m } 16 return i*i*i 17} 18 19// evaluate S(i/N, j/N) of the 4x4 net into out[3] (fx256). net = 16 pts * 3 coords, row-major P[a*4+b]. 20func bez_eval(net: *i64, i: i64, j: i64, N: i64, out: *i64) -> i64 { 21 let d: i64 = N*N*N*N*N*N 22 var sx: i64 = 0 23 var sy: i64 = 0 24 var sz: i64 = 0 25 var a: i64 = 0 26 while a < 4 { 27 let ba: i64 = bez_bern(a, i, N) 28 var b: i64 = 0 29 while b < 4 { 30 let bb: i64 = bez_bern(b, j, N) 31 let w: i64 = ba * bb 32 let p: i64 = (a*4 + b) * 3 33 sx = sx + w * net[p] 34 sy = sy + w * net[p+1] 35 sz = sz + w * net[p+2] 36 b = b + 1 37 } 38 a = a + 1 39 } 40 out[0] = sx / d 41 out[1] = sy / d 42 out[2] = sz / d 43 return 0 44} 45 46// tessellate the patch into an (N+1)x(N+1) vertex grid + 2 tris/cell (watertight: cells share grid vertices). 47func bez_tessellate(net: *i64, N: i64, mesh: i64) -> i64 { 48 m3_init(mesh) 49 let out: *i64 = sys_mmap(24) as *i64 50 var j: i64 = 0 51 while j <= N { 52 var i: i64 = 0 53 while i <= N { 54 bez_eval(net, i, j, N, out) 55 m3_add_vert(mesh, out[0], out[1], out[2]) 56 i = i + 1 57 } 58 j = j + 1 59 } 60 let w: i64 = N + 1 61 var jj: i64 = 0 62 while jj < N { 63 var ii: i64 = 0 64 while ii < N { 65 let v00: i64 = jj*w + ii 66 let v10: i64 = jj*w + ii + 1 67 let v01: i64 = (jj+1)*w + ii 68 let v11: i64 = (jj+1)*w + ii + 1 69 m3_add_tri(mesh, v00, v10, v11) 70 m3_add_tri(mesh, v00, v11, v01) 71 ii = ii + 1 72 } 73 jj = jj + 1 74 } 75 return 0 76}