1
1
"use strict"
2
2
3
3
var pool = require ( "typedarray-pool" )
4
+ var beautify = require ( "js-beautify" )
5
+ var invert = require ( "invert-permutation" )
4
6
5
7
module . exports = createSurfaceExtractor
6
8
@@ -11,6 +13,9 @@ function array(i) {
11
13
function data ( i ) {
12
14
return "d" + i
13
15
}
16
+ function cube ( i , bitmask ) {
17
+ return "c" + i + "_" + bitmask
18
+ }
14
19
function shape ( i ) {
15
20
return "s" + i
16
21
}
@@ -35,14 +40,24 @@ function index(i) {
35
40
function step ( i , j ) {
36
41
return "u" + i + "_" + j
37
42
}
43
+ function pcube ( bitmask ) {
44
+ return "b" + bitmask
45
+ }
46
+ function pdelta ( bitmask ) {
47
+ return "e" + bitmask
48
+ }
49
+ function vert ( i ) {
50
+ return "v" + i
51
+ }
38
52
var VERTEX_IDS = "V"
39
53
var PHASES = "P"
40
54
var VERTEX_COUNT = "N"
41
55
var POOL_SIZE = "Q"
56
+ var POINTER = "X"
42
57
43
58
//Generates the surface procedure
44
- function compileSurfaceProcedure ( vertexFunc , faceFunc , phaseFunc , scalarArgs , order , typesignature ) {
45
- var arrayArgs = typesignature . length
59
+ function compileSurfaceProcedure ( vertexFunc , faceFunc , phaseFunc , scalarArgs , order , typesig ) {
60
+ var arrayArgs = typesig . length
46
61
var dimension = order . length
47
62
48
63
var funcName = "extractContour" + order . join ( "_" )
@@ -60,39 +75,40 @@ function compileSurfaceProcedure(vertexFunc, faceFunc, phaseFunc, scalarArgs, or
60
75
61
76
//Shape
62
77
for ( var i = 0 ; i < dimension ; ++ i ) {
63
- vars . push ( shape ( i ) + "=" + array ( i ) + ".shape[" + i + "]|0" )
78
+ vars . push ( shape ( i ) + "=" + array ( 0 ) + ".shape[" + i + "]|0" )
64
79
}
65
80
//Data, stride, offset pointers
66
81
for ( var i = 0 ; i < arrayArgs ; ++ i ) {
67
82
vars . push ( data ( i ) + "=" + array ( i ) + ".data" ,
68
83
offset ( i ) + "=" + array ( i ) + ".offset" )
69
84
for ( var j = 0 ; j < dimension ; ++ j ) {
70
- vars . push ( stride ( i , j ) + "=" + array ( i ) + ".stride[" + j + "]" )
85
+ vars . push ( stride ( i , j ) + "=" + array ( i ) + ".stride[" + j + "]|0 " )
71
86
}
72
87
}
73
- //Pointer and delta variables
88
+ //Pointer, delta and cube variables
74
89
for ( var i = 0 ; i < arrayArgs ; ++ i ) {
75
- var ptrStr = [ offset ( i ) ]
76
- for ( var j = 0 ; j < dimension ; ++ i ) {
77
- ptrStr . push ( stride ( i , j ) )
78
- }
79
- vars . push ( pointer ( i ) + "=" + ptrStr . join ( "+" ) )
80
- for ( var j = 1 ; j < 1 << dimension ; ++ i ) {
81
- ptrStr . length = 0
90
+ vars . push ( pointer ( i ) + "=" + offset ( i ) )
91
+ vars . push ( cube ( i , 0 ) )
92
+ for ( var j = 1 ; j < ( 1 << dimension ) ; ++ j ) {
93
+ var ptrStr = [ ]
82
94
for ( var k = 0 ; k < dimension ; ++ k ) {
83
95
if ( j & ( 1 << k ) ) {
84
- ptrStr . push ( "-" + stride ( i , j ) )
96
+ ptrStr . push ( "-" + stride ( i , k ) )
85
97
}
86
98
}
87
99
vars . push ( delta ( i , j ) + "=" + ptrStr . join ( "" ) )
100
+ vars . push ( cube ( i , j ) )
88
101
}
89
102
}
103
+
90
104
//Create step variables
91
105
for ( var i = 0 ; i < arrayArgs ; ++ i ) {
92
106
for ( var j = 0 ; j < dimension ; ++ j ) {
93
- var stepVal = [ stride ( i , j ) ]
94
- //TODO: Compute step variables here
95
- vars . push ( step ( i , j ) + "=(" + stepVal . join ( "+" ) + ")|0" )
107
+ var stepVal = [ stride ( i , order [ j ] ) ]
108
+ for ( var k = j - 1 ; k >= 0 ; -- k ) {
109
+ stepVal . push ( stride ( i , order [ k ] ) + "*" + shape ( order [ k ] ) )
110
+ }
111
+ vars . push ( step ( i , order [ j ] ) + "=(" + stepVal . join ( "-" ) + ")|0" )
96
112
}
97
113
}
98
114
//Create index variables
@@ -101,21 +117,176 @@ function compileSurfaceProcedure(vertexFunc, faceFunc, phaseFunc, scalarArgs, or
101
117
}
102
118
//Vertex count
103
119
vars . push ( VERTEX_COUNT + "=0" )
104
- //Compute pool size
120
+ //Compute pool size, initialize pool step
105
121
var sizeVariable = [ "2" ]
106
122
for ( var i = dimension - 2 ; i >= 0 ; -- i ) {
107
123
sizeVariable . push ( shape ( order [ i ] ) )
108
124
}
109
125
//Previous phases and vertex_ids
110
126
vars . push ( POOL_SIZE + "=(" + sizeVariable . join ( "*" ) + ")|0" ,
111
127
PHASES + "=mallocUint32(" + POOL_SIZE + ")" ,
112
- VERTEX_IDS + "=mallocUint32(" + POOL_SIZE + ")" )
128
+ VERTEX_IDS + "=mallocUint32(" + POOL_SIZE + ")" ,
129
+ POINTER + "=0" )
130
+ //Create cube variables for phases
131
+ vars . push ( pcube ( 0 ) + "=0" )
132
+ for ( var j = 1 ; j < ( 1 << dimension ) ; ++ j ) {
133
+ var cubeDelta = [ ]
134
+ var cubeStep = [ "1" ]
135
+ for ( var k = dimension - 1 ; k >= 0 ; -- k ) {
136
+ if ( j & ( 1 << order [ k ] ) ) {
137
+ cubeDelta . push ( cubeStep . join ( "*" ) )
138
+ }
139
+ cubeStep . push ( shape ( order [ k ] ) )
140
+ }
141
+ vars . push ( pdelta ( j ) + "=-(" + cubeDelta . join ( "+" ) + ")|0" ,
142
+ pcube ( j ) + "=0" )
143
+ }
144
+ for ( var i = 0 ; i < ( 1 << dimension ) - 1 ; ++ i ) {
145
+ vars . push ( vert ( i ) + "=0" )
146
+ }
147
+
148
+ function forLoopBegin ( i , start ) {
149
+ code . push ( "for(" , index ( order [ i ] ) , "=" , start , ";" ,
150
+ index ( order [ i ] ) , "<" , shape ( order [ i ] ) , ";" ,
151
+ "++" , index ( order [ i ] ) , "){" )
152
+ }
153
+
154
+ function forLoopEnd ( i ) {
155
+ for ( var j = 0 ; j < arrayArgs ; ++ j ) {
156
+ code . push ( pointer ( j ) , "+=" , step ( j , order [ i ] ) , ";" )
157
+ }
158
+ code . push ( "}" )
159
+ }
160
+
161
+ function fillEmptySlice ( k ) {
162
+ for ( var i = k - 1 ; i >= 0 ; -- i ) {
163
+ forLoopBegin ( i , 0 )
164
+ }
165
+ var phaseFuncArgs = [ ]
166
+ for ( var i = 0 ; i < arrayArgs ; ++ i ) {
167
+ if ( typesig [ i ] ) {
168
+ phaseFuncArgs . push ( data ( i ) + ".get(" + pointer ( i ) + ")" )
169
+ } else {
170
+ phaseFuncArgs . push ( data ( i ) + "[" + pointer ( i ) + "]" )
171
+ }
172
+ }
173
+ for ( var i = 0 ; j < scalarArgs ; ++ i ) {
174
+ phaseFuncArgs . push ( scalar ( i ) )
175
+ }
176
+ code . push ( PHASES , "[" , POINTER , "++]=phase(" , phaseFuncArgs . join ( ) , ");" )
177
+ for ( var i = 0 ; i < k ; ++ i ) {
178
+ forLoopEnd ( i )
179
+ }
180
+ for ( var j = 0 ; j < arrayArgs ; ++ j ) {
181
+ code . push ( pointer ( j ) , "+=" , step ( j , order [ k ] ) , ";" )
182
+ }
183
+ }
184
+
185
+ function processGridCell ( mask ) {
186
+ //Read in local data
187
+ for ( var i = 0 ; i < arrayArgs ; ++ i ) {
188
+ if ( typesig [ i ] ) {
189
+ code . push ( cube ( i , 0 ) , "=" , data ( i ) , ".get(" , pointer ( i ) , ");" )
190
+ } else {
191
+ code . push ( cube ( i , 0 ) , "=" , data ( i ) , "[" , pointer ( i ) , "];" )
192
+ }
193
+ }
113
194
114
- //Generate outermost loop
195
+ //Read in phase
196
+ var phaseFuncArgs = [ ]
197
+ for ( var i = 0 ; i < arrayArgs ; ++ i ) {
198
+ phaseFuncArgs . push ( cube ( i , 0 ) )
199
+ }
200
+ for ( var i = 0 ; j < scalarArgs ; ++ i ) {
201
+ phaseFuncArgs . push ( scalar ( i ) )
202
+ }
203
+ code . push ( pcube ( 0 ) , "=" , PHASES , "[" , POINTER , "]=phase(" , phaseFuncArgs . join ( ) , ");" )
204
+
205
+ //Read in other cube data
206
+ for ( var j = 1 ; j < ( 1 << dimension ) ; ++ j ) {
207
+ code . push ( pcube ( j ) , "=" , PHASES , "[" , POINTER , "+" , pdelta ( j ) , "];" )
208
+ }
115
209
116
- //Generate inner loops
210
+ //Check for boundary crossing
211
+ var vertexPredicate = [ ]
212
+ for ( var j = 1 ; j < ( 1 << dimension ) ; ++ j ) {
213
+ vertexPredicate . push ( "(" + pcube ( 0 ) + "!==" + pcube ( j ) + ")" )
214
+ }
215
+ code . push ( "if(" , vertexPredicate . join ( "||" ) , "){" )
216
+
217
+ //Read in boundary data
218
+ var vertexArgs = [ ]
219
+ for ( var i = 0 ; i < dimension ; ++ i ) {
220
+ vertexArgs . push ( index ( i ) )
221
+ }
222
+ for ( var i = 0 ; i < arrayArgs ; ++ i ) {
223
+ vertexArgs . push ( cube ( i , 0 ) )
224
+ for ( var j = 1 ; j < ( 1 << dimension ) ; ++ j ) {
225
+ if ( typesig [ i ] ) {
226
+ code . push ( cube ( i , j ) , "=" , data ( i ) , ".get(" , pointer ( i ) , "+" , delta ( i , j ) , ");" )
227
+ } else {
228
+ code . push ( cube ( i , j ) , "=" , data ( i ) , "[" , pointer ( i ) , "+" , delta ( i , j ) , "];" )
229
+ }
230
+ vertexArgs . push ( cube ( i , j ) )
231
+ }
232
+ }
233
+ for ( var i = 0 ; i < scalarArgs ; ++ i ) {
234
+ vertexArgs . push ( scalar ( i ) )
235
+ }
236
+ for ( var i = 0 ; i < ( 1 << dimension ) ; ++ i ) {
237
+ vertexArgs . push ( pcube ( i ) )
238
+ }
117
239
240
+ //Generate vertex
241
+ code . push ( "vertex(" , vertexArgs . join ( ) , ");" ,
242
+ vert ( 0 ) , "=" , VERTEX_IDS , "[" , POINTER , "]=" , VERTEX_COUNT , "++;" )
118
243
244
+ //TODO: Check face crossing
245
+ if ( mask < ( 1 << dimension ) - 1 ) {
246
+ for ( var j = 1 ; j < ( 1 << dimension ) ; ++ j ) {
247
+ if ( ( j & mask ) === 0 ) {
248
+ code . push ( vert ( j ) , "=" , VERTEX_IDS , "[" , POINTER , "+" , pcube ( j ) , "];" )
249
+ }
250
+ }
251
+ var corner = pcube ( ( 1 << dimension ) - 1 )
252
+ for ( var j = 0 ; j < dimension ; ++ j ) {
253
+ if ( mask & ( 1 << j ) ) {
254
+ //Check face
255
+ var edge = pcube ( ( ( 1 << dimension ) - 1 ) ^ ( 1 << j ) )
256
+ var faceArgs = [ ]
257
+
258
+ faceArgs . push ( corner , edge )
259
+ code . push ( "if(" , corner , "!==" , edge , "){" ,
260
+ "face(" , faceArgs . join ( ) , ")}" )
261
+ }
262
+ }
263
+
264
+ code . push ( "/*" + mask + "*/" )
265
+ }
266
+
267
+ //Increment pointer, close off if statement
268
+ code . push ( "}" ,
269
+ POINTER , "+=1;" )
270
+ }
271
+
272
+ function createLoop ( i , mask ) {
273
+ if ( i < 0 ) {
274
+ processGridCell ( mask )
275
+ return
276
+ }
277
+ fillEmptySlice ( i )
278
+ code . push ( "if(" , shape ( order [ i ] ) , ">0){" )
279
+ createLoop ( i - 1 , mask | ( 1 << i ) )
280
+ for ( var j = 0 ; j < arrayArgs ; ++ j ) {
281
+ code . push ( pointer ( j ) , "+=" , step ( j , i ) , ";" )
282
+ }
283
+ forLoopBegin ( i , 2 )
284
+ createLoop ( i - 1 , mask )
285
+ forLoopEnd ( i )
286
+ code . push ( "}" )
287
+ }
288
+
289
+ createLoop ( dimension - 1 , 0 )
119
290
120
291
//Release scratch memory
121
292
code . push ( "freeUint32(" , VERTEX_IDS , ");freeUint32(" , PHASES , ");" )
@@ -128,6 +299,10 @@ function compileSurfaceProcedure(vertexFunc, faceFunc, phaseFunc, scalarArgs, or
128
299
code . join ( "" ) ,
129
300
"}" ,
130
301
"return " , funcName ] . join ( "" )
302
+
303
+ //Print code
304
+ console . log ( beautify ( procedureCode ) )
305
+
131
306
var proc = new Function (
132
307
"vertex" ,
133
308
"face" ,
@@ -173,19 +348,21 @@ function createSurfaceExtractor(args) {
173
348
}
174
349
var getters = args . getters || [ ]
175
350
var typesig = new Array ( arrays )
351
+ console . log ( getters )
176
352
for ( var i = 0 ; i < arrays ; ++ i ) {
353
+ console . log ( "here1" )
177
354
if ( getters . indexOf ( i ) >= 0 ) {
178
355
typesig [ i ] = true
179
356
} else {
180
357
typesig [ i ] = false
181
358
}
359
+ console . log ( "here2" )
182
360
}
183
361
return compileSurfaceProcedure (
184
362
args . vertex ,
185
363
args . face ,
186
364
args . phase ,
187
- dimension ,
188
365
scalars ,
189
366
order ,
190
- typeSignature )
367
+ typesig )
191
368
}
0 commit comments