forked from mikolalysenko/surface-nets
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsurfacenets.js
127 lines (120 loc) · 4.26 KB
/
surfacenets.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
"use strict"
module.exports = surfaceNets
var generateContourExtractor = require("ndarray-extract-contour")
var zeroCrossings = require("zero-crossings")
var allFns = {
"2d": function (genContour, order, dtype) {
var contour = genContour({
order: order,
scalarArguments: 3,
getters: dtype === "generic" ? [0] : undefined,
phase: function phaseFunc(p, a, b, c) {
return (p > c) | 0;
},
vertex: function vertexFunc(d0, d1, v0, v1, v2, v3, p0, p1, p2, p3, a, b, c) {
var m = ((p0 << 0) + (p1 << 1) + (p2 << 2) + (p3 << 3)) | 0;
if (m === 0 || m === 15) {
return;
}
switch (m) {
case 0:
a.push([d0 - 0.5, d1 - 0.5]);
break;
case 1:
a.push([d0 - 0.25 - (0.25 * (v1 + v0 - 2 * c)) / (v0 - v1), d1 - 0.25 - (0.25 * (v2 + v0 - 2 * c)) / (v0 - v2)]);
break;
case 2:
a.push([d0 - 0.75 - (0.25 * (-v1 - v0 + 2 * c)) / (v1 - v0), d1 - 0.25 - (0.25 * (v3 + v1 - 2 * c)) / (v1 - v3)]);
break;
case 3:
a.push([d0 - 0.5, d1 - 0.5 - (0.5 * (v2 + v0 + v3 + v1 - 4 * c)) / (v0 - v2 + v1 - v3)]);
break;
case 4:
a.push([d0 - 0.25 - (0.25 * (v3 + v2 - 2 * c)) / (v2 - v3), d1 - 0.75 - (0.25 * (-v2 - v0 + 2 * c)) / (v2 - v0)]);
break;
case 5:
a.push([d0 - 0.5 - (0.5 * (v1 + v0 + v3 + v2 - 4 * c)) / (v0 - v1 + v2 - v3), d1 - 0.5]);
break;
case 6:
a.push([d0 - 0.5 - (0.25 * (-v1 - v0 + v3 + v2)) / (v1 - v0 + v2 - v3), d1 - 0.5 - (0.25 * (-v2 - v0 + v3 + v1)) / (v2 - v0 + v1 - v3)]);
break;
case 7:
a.push([d0 - 0.75 - (0.25 * (v3 + v2 - 2 * c)) / (v2 - v3), d1 - 0.75 - (0.25 * (v3 + v1 - 2 * c)) / (v1 - v3)]);
break;
case 8:
a.push([d0 - 0.75 - (0.25 * (-v3 - v2 + 2 * c)) / (v3 - v2), d1 - 0.75 - (0.25 * (-v3 - v1 + 2 * c)) / (v3 - v1)]);
break;
case 9:
a.push([d0 - 0.5 - (0.25 * (v1 + v0 + -v3 - v2)) / (v0 - v1 + v3 - v2), d1 - 0.5 - (0.25 * (v2 + v0 + -v3 - v1)) / (v0 - v2 + v3 - v1)]);
break;
case 10:
a.push([d0 - 0.5 - (0.5 * (-v1 - v0 + -v3 - v2 + 4 * c)) / (v1 - v0 + v3 - v2), d1 - 0.5]);
break;
case 11:
a.push([d0 - 0.25 - (0.25 * (-v3 - v2 + 2 * c)) / (v3 - v2), d1 - 0.75 - (0.25 * (v2 + v0 - 2 * c)) / (v0 - v2)]);
break;
case 12:
a.push([d0 - 0.5, d1 - 0.5 - (0.5 * (-v2 - v0 + -v3 - v1 + 4 * c)) / (v2 - v0 + v3 - v1)]);
break;
case 13:
a.push([d0 - 0.75 - (0.25 * (v1 + v0 - 2 * c)) / (v0 - v1), d1 - 0.25 - (0.25 * (-v3 - v1 + 2 * c)) / (v3 - v1)]);
break;
case 14:
a.push([d0 - 0.25 - (0.25 * (-v1 - v0 + 2 * c)) / (v1 - v0), d1 - 0.25 - (0.25 * (-v2 - v0 + 2 * c)) / (v2 - v0)]);
break;
case 15:
a.push([d0 - 0.5, d1 - 0.5]);
break;
}
},
cell: function cellFunc(v0, v1, c0, c1, p0, p1, a, b, c) {
if (p0) {
b.push([v0, v1]);
} else {
b.push([v1, v0]);
}
},
});
return function (array, level) {
var verts = [],
cells = [];
contour(array, verts, cells, level);
return { positions: verts, cells: cells };
};
}
}
function buildSurfaceNets(order, dtype) {
var inKey = order.length + 'd'
var fn = allFns[inKey]
if(fn) return fn(generateContourExtractor, order, dtype)
}
//1D case: Need to handle specially
function mesh1D(array, level) {
var zc = zeroCrossings(array, level)
var n = zc.length
var npos = new Array(n)
var ncel = new Array(n)
for(var i=0; i<n; ++i) {
npos[i] = [ zc[i] ]
ncel[i] = [ i ]
}
return {
positions: npos,
cells: ncel
}
}
var CACHE = {}
function surfaceNets(array,level) {
if(array.dimension <= 0) {
return { positions: [], cells: [] }
} else if(array.dimension === 1) {
return mesh1D(array, level)
}
var typesig = array.order.join() + "-" + array.dtype
var proc = CACHE[typesig]
var level = (+level) || 0.0
if(!proc) {
proc = CACHE[typesig] = buildSurfaceNets(array.order, array.dtype)
}
return proc(array,level)
}