3
3
var pool = require ( "typedarray-pool" )
4
4
var beautify = require ( "js-beautify" )
5
5
var invert = require ( "invert-permutation" )
6
+ var gray = require ( "gray-code" )
6
7
7
8
module . exports = createSurfaceExtractor
8
9
@@ -43,6 +44,9 @@ function step(i,j) {
43
44
function pcube ( bitmask ) {
44
45
return "b" + bitmask
45
46
}
47
+ function qcube ( bitmask ) {
48
+ return "y" + bitmask
49
+ }
46
50
function pdelta ( bitmask ) {
47
51
return "e" + bitmask
48
52
}
@@ -54,6 +58,22 @@ var PHASES = "P"
54
58
var VERTEX_COUNT = "N"
55
59
var POOL_SIZE = "Q"
56
60
var POINTER = "X"
61
+ var TEMPORARY = "T"
62
+
63
+ function fixPerm ( face , dimension , k ) {
64
+ var seq = gray ( dimension - 1 ) . map ( function ( f ) {
65
+ return f . reduce ( function ( p , x , i ) {
66
+ return p + ( x << i )
67
+ } , 0 )
68
+ } )
69
+ var x = seq . map ( function ( y ) {
70
+ return face [ y ]
71
+ } )
72
+ if ( k & 1 ) {
73
+ x . reverse ( )
74
+ }
75
+ return x
76
+ }
57
77
58
78
//Generates the surface procedure
59
79
function compileSurfaceProcedure ( vertexFunc , faceFunc , phaseFunc , scalarArgs , order , typesig ) {
@@ -100,7 +120,6 @@ function compileSurfaceProcedure(vertexFunc, faceFunc, phaseFunc, scalarArgs, or
100
120
vars . push ( cube ( i , j ) )
101
121
}
102
122
}
103
-
104
123
//Create step variables
105
124
for ( var i = 0 ; i < arrayArgs ; ++ i ) {
106
125
for ( var j = 0 ; j < dimension ; ++ j ) {
@@ -131,19 +150,40 @@ function compileSurfaceProcedure(vertexFunc, faceFunc, phaseFunc, scalarArgs, or
131
150
vars . push ( pcube ( 0 ) + "=0" )
132
151
for ( var j = 1 ; j < ( 1 << dimension ) ; ++ j ) {
133
152
var cubeDelta = [ ]
134
- var cubeStep = [ "1" ]
153
+ var cubeStep = [ ]
135
154
for ( var k = dimension - 1 ; k >= 0 ; -- k ) {
136
- if ( j & ( 1 << order [ k ] ) ) {
137
- cubeDelta . push ( cubeStep . join ( "*" ) )
155
+ if ( j & ( 1 << k ) ) {
156
+ if ( cubeStep . length === 0 ) {
157
+ cubeDelta . push ( "1" )
158
+ } else {
159
+ cubeDelta . push ( cubeStep . join ( "*" ) )
160
+ }
138
161
}
139
162
cubeStep . push ( shape ( order [ k ] ) )
140
163
}
141
- vars . push ( pdelta ( j ) + "=-( " + cubeDelta . join ( "+ " ) + ")|0" ,
164
+ vars . push ( pdelta ( j ) + "=(- " + cubeDelta . join ( "- " ) + ")|0" ,
142
165
pcube ( j ) + "=0" )
143
166
}
144
- for ( var i = 0 ; i < ( 1 << dimension ) - 1 ; ++ i ) {
145
- vars . push ( vert ( i ) + "=0" )
167
+ for ( var j = 1 ; j < ( 1 << dimension ) ; ++ j ) {
168
+ var cubeDelta = [ ]
169
+ var cubeStep = [ ]
170
+ for ( var k = dimension - 1 ; k >= 0 ; -- k ) {
171
+ if ( j & ( 1 << k ) ) {
172
+ if ( cubeStep . length === 0 ) {
173
+ cubeDelta . push ( "1" )
174
+ } else {
175
+ if ( k === 0 ) {
176
+ cubeDelta . push ( "-" + cubeStep . join ( "*" ) )
177
+ } else {
178
+ cubeDelta . push ( cubeStep . join ( "*" ) )
179
+ }
180
+ }
181
+ }
182
+ cubeStep . push ( shape ( order [ k ] ) )
183
+ }
184
+ vars . push ( qcube ( j ) + "=-(" + cubeDelta . join ( "+" ) + ")|0" )
146
185
}
186
+ vars . push ( vert ( 0 ) + "=0" , TEMPORARY )
147
187
148
188
function forLoopBegin ( i , start ) {
149
189
code . push ( "for(" , index ( order [ i ] ) , "=" , start , ";" ,
@@ -241,20 +281,20 @@ function compileSurfaceProcedure(vertexFunc, faceFunc, phaseFunc, scalarArgs, or
241
281
code . push ( "vertex(" , vertexArgs . join ( ) , ");" ,
242
282
vert ( 0 ) , "=" , VERTEX_IDS , "[" , POINTER , "]=" , VERTEX_COUNT , "++;" )
243
283
244
- //TODO: Check face crossing
284
+ //Check for face crossings
245
285
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
286
var corner = pcube ( ( 1 << dimension ) - 1 )
252
287
for ( var j = 0 ; j < dimension ; ++ j ) {
253
- if ( mask & ( 1 << j ) ) {
288
+ if ( ! ( mask & ( 1 << j ) ) ) {
254
289
//Check face
255
- var edge = pcube ( ( ( 1 << dimension ) - 1 ) ^ ( 1 << j ) )
256
- var faceArgs = [ ]
257
-
290
+ var subset = ( ( 1 << dimension ) - 1 ) ^ ( 1 << j )
291
+ var edge = pcube ( subset )
292
+ var faceArgs = [ ]
293
+ for ( var k = subset ; k > 0 ; k = ( k - 1 ) & subset ) {
294
+ faceArgs . push ( VERTEX_IDS + "[" + POINTER + "+" + pdelta ( k ) + "]" )
295
+ }
296
+ faceArgs . push ( vert ( 0 ) )
297
+ faceArgs = fixPerm ( faceArgs , dimension , j )
258
298
faceArgs . push ( corner , edge )
259
299
code . push ( "if(" , corner , "!==" , edge , "){" ,
260
300
"face(" , faceArgs . join ( ) , ")}" )
@@ -269,6 +309,14 @@ function compileSurfaceProcedure(vertexFunc, faceFunc, phaseFunc, scalarArgs, or
269
309
POINTER , "+=1;" )
270
310
}
271
311
312
+ function flip ( ) {
313
+ for ( var j = 1 ; j < ( 1 << dimension ) ; ++ j ) {
314
+ code . push ( TEMPORARY , "=" , pcube ( j ) , ";" ,
315
+ pcube ( j ) , "=" , qcube ( j ) , ";" ,
316
+ qcube ( j ) , "=" , TEMPORARY , ";" )
317
+ }
318
+ }
319
+
272
320
function createLoop ( i , mask ) {
273
321
if ( i < 0 ) {
274
322
processGridCell ( mask )
@@ -280,8 +328,17 @@ function compileSurfaceProcedure(vertexFunc, faceFunc, phaseFunc, scalarArgs, or
280
328
for ( var j = 0 ; j < arrayArgs ; ++ j ) {
281
329
code . push ( pointer ( j ) , "+=" , step ( j , i ) , ";" )
282
330
}
331
+ if ( i === dimension - 1 ) {
332
+ code . push ( POINTER , "=0;" )
333
+ flip ( )
334
+ }
283
335
forLoopBegin ( i , 2 )
284
336
createLoop ( i - 1 , mask )
337
+ if ( i === dimension - 1 ) {
338
+ code . push ( "if(" , index ( order [ dimension - 1 ] ) , "&1){" ,
339
+ POINTER , "=0;}" )
340
+ flip ( )
341
+ }
285
342
forLoopEnd ( i )
286
343
code . push ( "}" )
287
344
}
@@ -348,15 +405,12 @@ function createSurfaceExtractor(args) {
348
405
}
349
406
var getters = args . getters || [ ]
350
407
var typesig = new Array ( arrays )
351
- console . log ( getters )
352
408
for ( var i = 0 ; i < arrays ; ++ i ) {
353
- console . log ( "here1" )
354
409
if ( getters . indexOf ( i ) >= 0 ) {
355
410
typesig [ i ] = true
356
411
} else {
357
412
typesig [ i ] = false
358
413
}
359
- console . log ( "here2" )
360
414
}
361
415
return compileSurfaceProcedure (
362
416
args . vertex ,
0 commit comments