@@ -4,69 +4,6 @@ var pool = require("typedarray-pool")
4
4
5
5
module . exports = createSurfaceExtractor
6
6
7
- //Helper macros
8
- function array ( i ) {
9
- return "a" + i
10
- }
11
- function data ( i ) {
12
- return "d" + i
13
- }
14
- function cube ( i , bitmask ) {
15
- return "c" + i + "_" + bitmask
16
- }
17
- function shape ( i ) {
18
- return "s" + i
19
- }
20
- function stride ( i , j ) {
21
- return "t" + i + "_" + j
22
- }
23
- function offset ( i ) {
24
- return "o" + i
25
- }
26
- function scalar ( i ) {
27
- return "x" + i
28
- }
29
- function pointer ( i ) {
30
- return "p" + i
31
- }
32
- function delta ( i , bitmask ) {
33
- return "d" + i + "_" + bitmask
34
- }
35
- function index ( i ) {
36
- return "i" + i
37
- }
38
- function step ( i , j ) {
39
- return "u" + i + "_" + j
40
- }
41
- function pcube ( bitmask ) {
42
- return "b" + bitmask
43
- }
44
- function qcube ( bitmask ) {
45
- return "y" + bitmask
46
- }
47
- function pdelta ( bitmask ) {
48
- return "e" + bitmask
49
- }
50
- function vert ( i ) {
51
- return "v" + i
52
- }
53
- var VERTEX_IDS = "V"
54
- var PHASES = "P"
55
- var VERTEX_COUNT = "N"
56
- var POOL_SIZE = "Q"
57
- var POINTER = "X"
58
- var TEMPORARY = "T"
59
-
60
- function permBitmask ( dimension , mask , order ) {
61
- var r = 0
62
- for ( var i = 0 ; i < dimension ; ++ i ) {
63
- if ( mask & ( 1 << i ) ) {
64
- r |= ( 1 << order [ i ] )
65
- }
66
- }
67
- return r
68
- }
69
-
70
7
var allFns = {
71
8
"false,0,1" : function surfaceProcedure ( vertex , face , phase , mallocUint32 , freeUint32 ) {
72
9
return function extractContour0_1 ( a0 , x0 , x1 , x2 ) {
@@ -387,303 +324,7 @@ var allFns = {
387
324
//Generates the surface procedure
388
325
function compileSurfaceProcedure ( vertexFunc , faceFunc , phaseFunc , scalarArgs , order , typesig ) {
389
326
var key = [ typesig , order ] . join ( ',' )
390
-
391
- var arrayArgs = typesig . length
392
- var dimension = order . length
393
-
394
- if ( dimension < 2 ) {
395
- throw new Error ( "ndarray-extract-contour: Dimension must be at least 2" )
396
- }
397
-
398
- var funcName = "extractContour" + order . join ( "_" )
399
- var code = [ ]
400
- var vars = [ ]
401
- var args = [ ]
402
-
403
- //Assemble arguments
404
- for ( var i = 0 ; i < arrayArgs ; ++ i ) {
405
- args . push ( array ( i ) )
406
- }
407
- for ( var i = 0 ; i < scalarArgs ; ++ i ) {
408
- args . push ( scalar ( i ) )
409
- }
410
-
411
- //Shape
412
- for ( var i = 0 ; i < dimension ; ++ i ) {
413
- vars . push ( shape ( i ) + "=" + array ( 0 ) + ".shape[" + i + "]|0" )
414
- }
415
- //Data, stride, offset pointers
416
- for ( var i = 0 ; i < arrayArgs ; ++ i ) {
417
- vars . push ( data ( i ) + "=" + array ( i ) + ".data" ,
418
- offset ( i ) + "=" + array ( i ) + ".offset|0" )
419
- for ( var j = 0 ; j < dimension ; ++ j ) {
420
- vars . push ( stride ( i , j ) + "=" + array ( i ) + ".stride[" + j + "]|0" )
421
- }
422
- }
423
- //Pointer, delta and cube variables
424
- for ( var i = 0 ; i < arrayArgs ; ++ i ) {
425
- vars . push ( pointer ( i ) + "=" + offset ( i ) )
426
- vars . push ( cube ( i , 0 ) )
427
- for ( var j = 1 ; j < ( 1 << dimension ) ; ++ j ) {
428
- var ptrStr = [ ]
429
- for ( var k = 0 ; k < dimension ; ++ k ) {
430
- if ( j & ( 1 << k ) ) {
431
- ptrStr . push ( "-" + stride ( i , k ) )
432
- }
433
- }
434
- vars . push ( delta ( i , j ) + "=(" + ptrStr . join ( "" ) + ")|0" )
435
- vars . push ( cube ( i , j ) + "=0" )
436
- }
437
- }
438
- //Create step variables
439
- for ( var i = 0 ; i < arrayArgs ; ++ i ) {
440
- for ( var j = 0 ; j < dimension ; ++ j ) {
441
- var stepVal = [ stride ( i , order [ j ] ) ]
442
- if ( j > 0 ) {
443
- stepVal . push ( stride ( i , order [ j - 1 ] ) + "*" + shape ( order [ j - 1 ] ) )
444
- }
445
- vars . push ( step ( i , order [ j ] ) + "=(" + stepVal . join ( "-" ) + ")|0" )
446
- }
447
- }
448
- //Create index variables
449
- for ( var i = 0 ; i < dimension ; ++ i ) {
450
- vars . push ( index ( i ) + "=0" )
451
- }
452
- //Vertex count
453
- vars . push ( VERTEX_COUNT + "=0" )
454
- //Compute pool size, initialize pool step
455
- var sizeVariable = [ "2" ]
456
- for ( var i = dimension - 2 ; i >= 0 ; -- i ) {
457
- sizeVariable . push ( shape ( order [ i ] ) )
458
- }
459
- //Previous phases and vertex_ids
460
- vars . push ( POOL_SIZE + "=(" + sizeVariable . join ( "*" ) + ")|0" ,
461
- PHASES + "=mallocUint32(" + POOL_SIZE + ")" ,
462
- VERTEX_IDS + "=mallocUint32(" + POOL_SIZE + ")" ,
463
- POINTER + "=0" )
464
- //Create cube variables for phases
465
- vars . push ( pcube ( 0 ) + "=0" )
466
- for ( var j = 1 ; j < ( 1 << dimension ) ; ++ j ) {
467
- var cubeDelta = [ ]
468
- var cubeStep = [ ]
469
- for ( var k = 0 ; k < dimension ; ++ k ) {
470
- if ( j & ( 1 << k ) ) {
471
- if ( cubeStep . length === 0 ) {
472
- cubeDelta . push ( "1" )
473
- } else {
474
- cubeDelta . unshift ( cubeStep . join ( "*" ) )
475
- }
476
- }
477
- cubeStep . push ( shape ( order [ k ] ) )
478
- }
479
- var signFlag = ""
480
- if ( cubeDelta [ 0 ] . indexOf ( shape ( order [ dimension - 2 ] ) ) < 0 ) {
481
- signFlag = "-"
482
- }
483
- var jperm = permBitmask ( dimension , j , order )
484
- vars . push ( pdelta ( jperm ) + "=(-" + cubeDelta . join ( "-" ) + ")|0" ,
485
- qcube ( jperm ) + "=(" + signFlag + cubeDelta . join ( "-" ) + ")|0" ,
486
- pcube ( jperm ) + "=0" )
487
- }
488
- vars . push ( vert ( 0 ) + "=0" , TEMPORARY + "=0" )
489
-
490
- function forLoopBegin ( i , start ) {
491
- code . push ( "for(" , index ( order [ i ] ) , "=" , start , ";" ,
492
- index ( order [ i ] ) , "<" , shape ( order [ i ] ) , ";" ,
493
- "++" , index ( order [ i ] ) , "){" )
494
- }
495
-
496
- function forLoopEnd ( i ) {
497
- for ( var j = 0 ; j < arrayArgs ; ++ j ) {
498
- code . push ( pointer ( j ) , "+=" , step ( j , order [ i ] ) , ";" )
499
- }
500
- code . push ( "}" )
501
- }
502
-
503
- function fillEmptySlice ( k ) {
504
- for ( var i = k - 1 ; i >= 0 ; -- i ) {
505
- forLoopBegin ( i , 0 )
506
- }
507
- var phaseFuncArgs = [ ]
508
- for ( var i = 0 ; i < arrayArgs ; ++ i ) {
509
- if ( typesig [ i ] ) {
510
- phaseFuncArgs . push ( data ( i ) + ".get(" + pointer ( i ) + ")" )
511
- } else {
512
- phaseFuncArgs . push ( data ( i ) + "[" + pointer ( i ) + "]" )
513
- }
514
- }
515
- for ( var i = 0 ; i < scalarArgs ; ++ i ) {
516
- phaseFuncArgs . push ( scalar ( i ) )
517
- }
518
- code . push ( PHASES , "[" , POINTER , "++]=phase(" , phaseFuncArgs . join ( ) , ");" )
519
- for ( var i = 0 ; i < k ; ++ i ) {
520
- forLoopEnd ( i )
521
- }
522
- for ( var j = 0 ; j < arrayArgs ; ++ j ) {
523
- code . push ( pointer ( j ) , "+=" , step ( j , order [ k ] ) , ";" )
524
- }
525
- }
526
-
527
- function processGridCell ( mask ) {
528
- //Read in local data
529
- for ( var i = 0 ; i < arrayArgs ; ++ i ) {
530
- if ( typesig [ i ] ) {
531
- code . push ( cube ( i , 0 ) , "=" , data ( i ) , ".get(" , pointer ( i ) , ");" )
532
- } else {
533
- code . push ( cube ( i , 0 ) , "=" , data ( i ) , "[" , pointer ( i ) , "];" )
534
- }
535
- }
536
-
537
- //Read in phase
538
- var phaseFuncArgs = [ ]
539
- for ( var i = 0 ; i < arrayArgs ; ++ i ) {
540
- phaseFuncArgs . push ( cube ( i , 0 ) )
541
- }
542
- for ( var i = 0 ; i < scalarArgs ; ++ i ) {
543
- phaseFuncArgs . push ( scalar ( i ) )
544
- }
545
-
546
- code . push ( pcube ( 0 ) , "=" , PHASES , "[" , POINTER , "]=phase(" , phaseFuncArgs . join ( ) , ");" )
547
-
548
- //Read in other cube data
549
- for ( var j = 1 ; j < ( 1 << dimension ) ; ++ j ) {
550
- code . push ( pcube ( j ) , "=" , PHASES , "[" , POINTER , "+" , pdelta ( j ) , "];" )
551
- }
552
-
553
- //Check for boundary crossing
554
- var vertexPredicate = [ ]
555
- for ( var j = 1 ; j < ( 1 << dimension ) ; ++ j ) {
556
- vertexPredicate . push ( "(" + pcube ( 0 ) + "!==" + pcube ( j ) + ")" )
557
- }
558
- code . push ( "if(" , vertexPredicate . join ( "||" ) , "){" )
559
-
560
- //Read in boundary data
561
- var vertexArgs = [ ]
562
- for ( var i = 0 ; i < dimension ; ++ i ) {
563
- vertexArgs . push ( index ( i ) )
564
- }
565
- for ( var i = 0 ; i < arrayArgs ; ++ i ) {
566
- vertexArgs . push ( cube ( i , 0 ) )
567
- for ( var j = 1 ; j < ( 1 << dimension ) ; ++ j ) {
568
- if ( typesig [ i ] ) {
569
- code . push ( cube ( i , j ) , "=" , data ( i ) , ".get(" , pointer ( i ) , "+" , delta ( i , j ) , ");" )
570
- } else {
571
- code . push ( cube ( i , j ) , "=" , data ( i ) , "[" , pointer ( i ) , "+" , delta ( i , j ) , "];" )
572
- }
573
- vertexArgs . push ( cube ( i , j ) )
574
- }
575
- }
576
- for ( var i = 0 ; i < ( 1 << dimension ) ; ++ i ) {
577
- vertexArgs . push ( pcube ( i ) )
578
- }
579
- for ( var i = 0 ; i < scalarArgs ; ++ i ) {
580
- vertexArgs . push ( scalar ( i ) )
581
- }
582
-
583
- //Generate vertex
584
- code . push ( "vertex(" , vertexArgs . join ( ) , ");" ,
585
- vert ( 0 ) , "=" , VERTEX_IDS , "[" , POINTER , "]=" , VERTEX_COUNT , "++;" )
586
-
587
- //Check for face crossings
588
- var base = ( 1 << dimension ) - 1
589
- var corner = pcube ( base )
590
- for ( var j = 0 ; j < dimension ; ++ j ) {
591
- if ( ( mask & ~ ( 1 << j ) ) === 0 ) {
592
- //Check face
593
- var subset = base ^ ( 1 << j )
594
- var edge = pcube ( subset )
595
- var faceArgs = [ ]
596
- for ( var k = subset ; k > 0 ; k = ( k - 1 ) & subset ) {
597
- faceArgs . push ( VERTEX_IDS + "[" + POINTER + "+" + pdelta ( k ) + "]" )
598
- }
599
- faceArgs . push ( vert ( 0 ) )
600
- for ( var k = 0 ; k < arrayArgs ; ++ k ) {
601
- if ( j & 1 ) {
602
- faceArgs . push ( cube ( k , base ) , cube ( k , subset ) )
603
- } else {
604
- faceArgs . push ( cube ( k , subset ) , cube ( k , base ) )
605
- }
606
- }
607
- if ( j & 1 ) {
608
- faceArgs . push ( corner , edge )
609
- } else {
610
- faceArgs . push ( edge , corner )
611
- }
612
- for ( var k = 0 ; k < scalarArgs ; ++ k ) {
613
- faceArgs . push ( scalar ( k ) )
614
- }
615
- code . push ( "if(" , corner , "!==" , edge , "){" ,
616
- "face(" , faceArgs . join ( ) , ")}" )
617
- }
618
- }
619
-
620
- //Increment pointer, close off if statement
621
- code . push ( "}" ,
622
- POINTER , "+=1;" )
623
- }
624
-
625
- function flip ( ) {
626
- for ( var j = 1 ; j < ( 1 << dimension ) ; ++ j ) {
627
- code . push ( TEMPORARY , "=" , pdelta ( j ) , ";" ,
628
- pdelta ( j ) , "=" , qcube ( j ) , ";" ,
629
- qcube ( j ) , "=" , TEMPORARY , ";" )
630
- }
631
- }
632
-
633
- function createLoop ( i , mask ) {
634
- if ( i < 0 ) {
635
- processGridCell ( mask )
636
- return
637
- }
638
- fillEmptySlice ( i )
639
- code . push ( "if(" , shape ( order [ i ] ) , ">0){" ,
640
- index ( order [ i ] ) , "=1;" )
641
- createLoop ( i - 1 , mask | ( 1 << order [ i ] ) )
642
-
643
- for ( var j = 0 ; j < arrayArgs ; ++ j ) {
644
- code . push ( pointer ( j ) , "+=" , step ( j , order [ i ] ) , ";" )
645
- }
646
- if ( i === dimension - 1 ) {
647
- code . push ( POINTER , "=0;" )
648
- flip ( )
649
- }
650
- forLoopBegin ( i , 2 )
651
- createLoop ( i - 1 , mask )
652
- if ( i === dimension - 1 ) {
653
- code . push ( "if(" , index ( order [ dimension - 1 ] ) , "&1){" ,
654
- POINTER , "=0;}" )
655
- flip ( )
656
- }
657
- forLoopEnd ( i )
658
- code . push ( "}" )
659
- }
660
-
661
- createLoop ( dimension - 1 , 0 )
662
-
663
- //Release scratch memory
664
- code . push ( "freeUint32(" , VERTEX_IDS , ");freeUint32(" , PHASES , ");" )
665
-
666
- //Compile and link procedure
667
- var procedureCode = [
668
- "'use strict';" ,
669
- "function " , funcName , "(" , args . join ( ) , "){" ,
670
- "var " , vars . join ( ) , ";" ,
671
- code . join ( "" ) ,
672
- "}" ,
673
- "return " , funcName ] . join ( "" )
674
-
675
327
var proc = allFns [ key ]
676
- if ( ! proc ) {
677
- proc = new Function (
678
- "vertex" ,
679
- "face" ,
680
- "phase" ,
681
- "mallocUint32" ,
682
- "freeUint32" ,
683
- procedureCode )
684
-
685
- console . log ( key , proc )
686
- }
687
328
688
329
return proc (
689
330
vertexFunc ,
0 commit comments