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}