@fusion.dev/helix-graph 0.122.0 → 0.124.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,112 @@
1
+ const CELLS = 72;
2
+ export const surfaceOf = (field, { at = 0, cells = CELLS, } = {}) => {
3
+ const { depth, height, width } = field;
4
+ const cell = Math.max(width, height, depth) / cells;
5
+ const nx = Math.ceil(width / cell) + 3;
6
+ const ny = Math.ceil(height / cell) + 3;
7
+ const nz = Math.ceil(depth / cell) + 3;
8
+ const value = new Float32Array(nx * ny * nz);
9
+ const spot = (x, y, z) => (z * ny + y) * nx + x;
10
+ for (let z = 0; z < nz; z++) {
11
+ for (let y = 0; y < ny; y++) {
12
+ for (let x = 0; x < nx; x++) {
13
+ value[spot(x, y, z)] = field.distance((x - 1) * cell, (y - 1) * cell, (z - 1) * cell) - at;
14
+ }
15
+ }
16
+ }
17
+ const cornerOf = new Int32Array((nx - 1) * (ny - 1) * (nz - 1)).fill(-1);
18
+ const cellSpot = (x, y, z) => (z * (ny - 1) + y) * (nx - 1) + x;
19
+ const corners = [];
20
+ const edges = [
21
+ [0, 1],
22
+ [2, 3],
23
+ [4, 5],
24
+ [6, 7],
25
+ [0, 2],
26
+ [1, 3],
27
+ [4, 6],
28
+ [5, 7],
29
+ [0, 4],
30
+ [1, 5],
31
+ [2, 6],
32
+ [3, 7],
33
+ ];
34
+ const offsets = [
35
+ [0, 0, 0],
36
+ [1, 0, 0],
37
+ [0, 1, 0],
38
+ [1, 1, 0],
39
+ [0, 0, 1],
40
+ [1, 0, 1],
41
+ [0, 1, 1],
42
+ [1, 1, 1],
43
+ ];
44
+ const values = new Float32Array(8);
45
+ for (let z = 0; z < nz - 1; z++) {
46
+ for (let y = 0; y < ny - 1; y++) {
47
+ for (let x = 0; x < nx - 1; x++) {
48
+ let inside = 0;
49
+ for (let corner = 0; corner < 8; corner++) {
50
+ const [dx, dy, dz] = offsets[corner];
51
+ const sample = value[spot(x + dx, y + dy, z + dz)];
52
+ values[corner] = sample;
53
+ if (sample < 0) {
54
+ inside += 1;
55
+ }
56
+ }
57
+ if (inside === 0 || inside === 8) {
58
+ continue;
59
+ }
60
+ let sx = 0;
61
+ let sy = 0;
62
+ let sz = 0;
63
+ let crossed = 0;
64
+ for (const [from, to] of edges) {
65
+ const a = values[from];
66
+ const b = values[to];
67
+ if (a < 0 === b < 0) {
68
+ continue;
69
+ }
70
+ const t = a / (a - b);
71
+ const [ax, ay, az] = offsets[from];
72
+ const [bx, by, bz] = offsets[to];
73
+ sx += ax + (bx - ax) * t;
74
+ sy += ay + (by - ay) * t;
75
+ sz += az + (bz - az) * t;
76
+ crossed += 1;
77
+ }
78
+ cornerOf[cellSpot(x, y, z)] = corners.length / 3;
79
+ corners.push((x + sx / crossed - 1) * cell, (y + sy / crossed - 1) * cell, (z + sz / crossed - 1) * cell);
80
+ }
81
+ }
82
+ }
83
+ const triangles = [];
84
+ const quad = (a, b, c, d, flip) => {
85
+ if (a < 0 || b < 0 || c < 0 || d < 0) {
86
+ return;
87
+ }
88
+ if (flip) {
89
+ triangles.push(a, c, b, a, d, c);
90
+ }
91
+ else {
92
+ triangles.push(a, b, c, a, c, d);
93
+ }
94
+ };
95
+ for (let z = 1; z < nz - 1; z++) {
96
+ for (let y = 1; y < ny - 1; y++) {
97
+ for (let x = 1; x < nx - 1; x++) {
98
+ const here = value[spot(x, y, z)] < 0;
99
+ if (x < nx - 1 && here !== value[spot(x + 1, y, z)] < 0) {
100
+ quad(cornerOf[cellSpot(x, y - 1, z - 1)], cornerOf[cellSpot(x, y, z - 1)], cornerOf[cellSpot(x, y, z)], cornerOf[cellSpot(x, y - 1, z)], here);
101
+ }
102
+ if (y < ny - 1 && here !== value[spot(x, y + 1, z)] < 0) {
103
+ quad(cornerOf[cellSpot(x - 1, y, z - 1)], cornerOf[cellSpot(x - 1, y, z)], cornerOf[cellSpot(x, y, z)], cornerOf[cellSpot(x, y, z - 1)], here);
104
+ }
105
+ if (z < nz - 1 && here !== value[spot(x, y, z + 1)] < 0) {
106
+ quad(cornerOf[cellSpot(x - 1, y - 1, z)], cornerOf[cellSpot(x, y - 1, z)], cornerOf[cellSpot(x, y, z)], cornerOf[cellSpot(x - 1, y, z)], here);
107
+ }
108
+ }
109
+ }
110
+ }
111
+ return { corners: new Float32Array(corners), triangles: new Uint32Array(triangles) };
112
+ };