diff --git a/01_Code/physical_computing_interface/demos/app1.js b/01_Code/physical_computing_interface/demos/app1.js index 94f09b4bf31175a79dabab558209d1fc53146a68..364847f026eb6217a0833d931c6144e0b84847fd 100644 --- a/01_Code/physical_computing_interface/demos/app1.js +++ b/01_Code/physical_computing_interface/demos/app1.js @@ -17,51 +17,67 @@ initEditor();// todo enclose into class var assembler= new Assembler(three,GLOBALS,1,50,[new THREE.Vector3(0,0,0)],[new THREE.Vector3(GLOBALS.gridSize/2.0*GLOBALS.voxelSpacing,0,0)]); assembler.run(); -var info={ - name:"MNIST", - imageSize:"(28,28)", - numDatasets:65000, - numTraining:55000, - numTest:65000-55000, +info={ + name:"prediction", + parent: 'CNN', + classes: 'output', + outputNeigh:-1 //-1:none,0:x+1,1:x-1,2:y+1,3:y-1,4:z+1,5:z-1,6:y+1&&z-1 }; -GLOBALS.addNode(0,8,0 ,false,info); +GLOBALS.addNode(0,12,0,false,info); info={ - name:"conv2d_Conv2D1", - inputShape:"(batch,28,28,1)", - kernelSize:5, - filters:8, - strides:1, - activation: 'relu', + name:"categoricalCrossentropy", + metrics: ['accuracy'], + parent: 'CNN', + classes: 'loss', + outputNeigh:6 //-1:none,0:x+1,1:x-1,2:y+1,3:y-1,4:z+1,5:z-1,6:y+1&&z-1 + +}; +GLOBALS.addNode(0,11,1,false,info); +info={ + name:"dense", + inputShape:"(batch,256)", kernelInitializer: 'varianceScaling', - outputShape:"(batch,24,24,8)", - numParams:208, - Trainable:true + activation: 'softmax', + outputShape:"(batch,10)", + numParams:2570, + Trainable:true, + parent: 'CNN', + classes: 'layers', + outputNeigh:4 //-1:none,0:x+1,1:x-1,2:y+1,3:y-1,4:z+1,5:z-1,6:y+1&&z-1 }; -GLOBALS.addNode(0,8,1 ,false,info); +GLOBALS.addNode(0,11,0,false,info); info={ - name:"testImage", - imageSize:"(1,28,28)" -}; -GLOBALS.addNode(0,8,2 ,false,info); + name:"flatten", + inputShape:"(batch,4,4,16)", + outputShape:"(batch,256)", + numParams:0, + Trainable:true, + parent: 'CNN', + classes: 'layers', + outputNeigh:6 //-1:none,0:x+1,1:x-1,2:y+1,3:y-1,4:z+1,5:z-1,6:y+1&&z-1 +}; +GLOBALS.addNode(0,10,1,false,info); info={ - name:"max_pooling2d_MaxPooling2D1", - inputShape:"(batch,24,24,8)", + name:"maxPooling2d", + inputShape:"(batch,12,12,8)", poolSize:"[2,2]", strides:"[2,2]", - outputShape:"(batch,12,12,8)", + outputShape:"(batch,4,4,16)", numParams:0, - Trainable:true + Trainable:true, + parent: 'CNN', + classes: 'layers', + outputNeigh:4 //-1:none,0:x+1,1:x-1,2:y+1,3:y-1,4:z+1,5:z-1,6:y+1&&z-1 }; -GLOBALS.addNode(0,9,0 ,false,info); - +GLOBALS.addNode(0,10,0,false,info); info={ - name:"conv2d_Conv2D2", + name:"conv2d", inputShape:"(batch,12,12,8)", kernelSize:5, filters:16, @@ -70,57 +86,64 @@ info={ kernelInitializer: 'varianceScaling', outputShape:"(batch,8,8,16)", numParams:3216, - Trainable:true + Trainable:true, + parent: 'CNN', + classes: 'layers', + outputNeigh:6 //-1:none,0:x+1,1:x-1,2:y+1,3:y-1,4:z+1,5:z-1,6:y+1&&z-1 }; GLOBALS.addNode(0,9,1 ,false,info); info={ - name:"max_pooling2d_MaxPooling2D2", - inputShape:"(batch,12,12,8)", + name:"maxPooling2d", + inputShape:"(batch,24,24,8)", poolSize:"[2,2]", strides:"[2,2]", - outputShape:"(batch,4,4,16)", - numParams:0, - Trainable:true - -}; -GLOBALS.addNode(0,10,0,false,info); - -info={ - name:"flatten_Flatten1", - inputShape:"(batch,4,4,16)", - outputShape:"(batch,256)", + outputShape:"(batch,12,12,8)", numParams:0, - Trainable:true + Trainable:true, + parent: 'CNN', + classes: 'layers', + outputNeigh:4 //-1:none,0:x+1,1:x-1,2:y+1,3:y-1,4:z+1,5:z-1,6:y+1&&z-1 }; -GLOBALS.addNode(0,10,1,false,info); +GLOBALS.addNode(0,9,0 ,false,info); info={ - name:"dense_Dense1", - inputShape:"(batch,256)", + name:"conv2d", + inputShape:"(batch,28,28,1)", + kernelSize:5, + filters:8, + strides:1, + activation: 'relu', kernelInitializer: 'varianceScaling', - activation: 'softmax', - outputShape:"(batch,10)", - numParams:2570, - Trainable:true + outputShape:"(batch,24,24,8)", + numParams:208, + Trainable:true, + parent: 'CNN', + classes: 'layers', + outputNeigh:6 //-1:none,0:x+1,1:x-1,2:y+1,3:y-1,4:z+1,5:z-1,6:y+1&&z-1 }; -GLOBALS.addNode(0,11,0,false,info); - - -info={ - name:"loss_categoricalCrossentropy", - metrics: ['accuracy'], +GLOBALS.addNode(0,8,1 ,false,info); +var info={ + name:"MNIST", + imageSize:"(28,28)", + numDatasets:65000, + numTraining:55000, + numTest:65000-55000, + parent: 'CNN', + classes: 'input', + outputNeigh:4 //-1:none,0:x+1,1:x-1,2:y+1,3:y-1,4:z+1,5:z-1,6:y+1&&z-1 }; -GLOBALS.addNode(0,11,1,false,info); +GLOBALS.addNode(0,8,0 ,false,info); info={ - name:"prediction" + name:"Test", + imageSize:"(1,28,28)", + parent: 'CNN', + classes: 'viz', + outputNeigh:5 //-1:none,0:x+1,1:x-1,2:y+1,3:y-1,4:z+1,5:z-1,6:y+1&&z-1 }; -GLOBALS.addNode(0,12,0,false,info); - - - +GLOBALS.addNode(0,8,2 ,false,info); \ No newline at end of file diff --git a/01_Code/physical_computing_interface/demos/indexDNN.html b/01_Code/physical_computing_interface/demos/indexDNN.html index edfaa104c9efd64614eebe81e867a0d970881c67..696213e4787b3afb8d9359e26df86a41fc289463 100644 --- a/01_Code/physical_computing_interface/demos/indexDNN.html +++ b/01_Code/physical_computing_interface/demos/indexDNN.html @@ -99,7 +99,6 @@ <!-- TODO: Clean structure to modules? Add another footer - --> @@ -120,6 +119,9 @@ <script src="https://unpkg.com/cytoscape-cose-bilkent/cytoscape-cose-bilkent.js"></script> <script src="../lib/cytoscape-expand-collapse.js"></script> +<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.js"></script><!-- edge handling--> +<script src="../lib/cytoscape-edgehandles.js"></script><!-- edge handling--> + <script src="../lib/jsoneditor/jsoneditor.js"></script> @@ -140,17 +142,13 @@ <script src="../assembly/replay.js"></script><!-- assembly and timestep handling --> <script src="../graph/graph.js"></script><!--graph flow visualization--> -<script src="../dnn/data.js" type="module"></script><!-- graph flow visualization--> -<script src="../dnn/graph.js"></script><!-- graph flow visualization--> - -<script src="../dnn/script.js" type="module"></script><!-- graph flow visualization--> - - +<script src="../dnn/data.js" type="module"></script><!-- dnn--> +<script src="../dnn/graph.js"></script><!-- dnn graph--> +<script src="../dnn/script.js" type="module"></script><!-- dnn --> <script src="../json/json.js"></script><!-- json --> - <script src="./app1.js"></script><!-- threejs visualization --> diff --git a/01_Code/physical_computing_interface/dnn/graph.js b/01_Code/physical_computing_interface/dnn/graph.js index 1acf35f5e494b807bd5aefbebeea66c893f7f379..ddc4ec216bce9e7690f177a4bbf0f90155ee4c1a 100644 --- a/01_Code/physical_computing_interface/dnn/graph.js +++ b/01_Code/physical_computing_interface/dnn/graph.js @@ -33,19 +33,26 @@ var cyy = cytoscape({ 'color': 'white', 'font-family': "consolas", // 'font-family':"Times New Roman", - 'width': 80, - 'height': 80 + 'width': 120, + 'height': 120 }) .selector('edge') .css({ 'content': 'data(name)', 'width': 8, - 'line-color': '#888', - 'target-arrow-color': '#888', - 'source-arrow-color': '#888', - 'target-arrow-shape': 'triangle' + 'line-color': color6, + 'target-arrow-color': color6, + 'source-arrow-color': color6, + 'target-arrow-shape': 'vee', + 'curve-style': 'bezier', //straight }) .selector(':selected') + .css({ + "border-width": 4, + 'line-color': color4, + 'target-arrow-color': color4, + "border-color": color4 + }) .selector('$node > node') .css({ 'shape': 'roundrectangle', @@ -147,6 +154,41 @@ var cyy = cytoscape({ 'padding-left': 40, 'padding-bottom': 40, 'padding-right': 40 + }) + .selector('.eh-handle') + .css({ + 'background-color': color4, + 'width': 12, + 'height': 12, + 'shape': 'ellipse', + 'overlay-opacity': 0, + 'border-width': 12, // makes the handle easier to hit + 'border-opacity': 0 + }) + .selector('.eh-hover') + .css({ + 'background-color': color4 + }) + .selector('.eh-source') + .css({ + 'border-width': 2, + 'border-color': color4 + }) + .selector('.eh-target') + .css({ + 'border-width': 2, + 'border-color': color4 + }) + .selector('.eh-preview, .eh-ghost-edge') + .css({ + 'background-color': color4, + 'line-color': color4, + 'target-arrow-color': color4, + 'source-arrow-color': color4 + }) + .selector('.eh-ghost-edge.eh-preview-active') + .css({ + 'opacity': 0 }), elements: { @@ -186,60 +228,60 @@ var cyy = cytoscape({ - { - data: { id: 'pred', name: 'prediction', parent: 'CNN' }, - position: { x: 0, y: 0 },classes: 'output', - }, - { - data: { id: '7', name: 'categoricalCrossentropy', parent: 'CNN' }, - position: { x: 0, y: 0 },classes: 'loss', - }, - { - data: { id: '6', name: 'dense', parent: 'CNN' }, - position: { x: 0, y: 0 },classes: 'layers', - }, - { - data: { id: '5', name: 'flatten', parent: 'CNN' }, - position: { x: 0, y: 0 },classes: 'layers', - }, - { - data: { id: '4', name: 'maxPooling2d', parent: 'CNN' }, - position: { x: 0, y: 0 },classes: 'layers', - }, - { - data: { id: '3', name: 'conv2d', parent: 'CNN' }, - position: { x: 0, y: 0 },classes: 'layers', - }, - { - data: { id: '2', name: 'maxPooling2d', parent: 'CNN' }, - position: { x: 0, y: 0 },classes: 'layers', - }, - { - data: { id: '1', name: 'conv2d', parent: 'CNN' }, - position: { x: 0, y: 0 },classes: 'layers', - }, - { - data: { id: '0', name: 'MNIST',parent:'CNN' }, - position: { x: 0, y: 0 },classes: 'input', - }, - { - data: { id: 'ex', name: 'Test',parent:'CNN' }, - position: { x: 0, y: 0 },classes: 'viz', - }, + // { + // data: { id: '[0,12,0]', name: 'prediction', parent: 'CNN' }, + // position: { x: 0, y: 0 },classes: 'output', + // }, + // { + // data: { id: '[0,11,1]', name: 'categoricalCrossentropy', parent: 'CNN' }, + // position: { x: 0, y: 0 },classes: 'loss', + // }, + // { + // data: { id: '[0,11,0]', name: 'dense', parent: 'CNN' }, + // position: { x: 0, y: 0 },classes: 'layers', + // }, + // { + // data: { id: '[0,10,1]', name: 'flatten', parent: 'CNN' }, + // position: { x: 0, y: 0 },classes: 'layers', + // }, + // { + // data: { id: '[0,10,0]', name: 'maxPooling2d', parent: 'CNN' }, + // position: { x: 0, y: 0 },classes: 'layers', + // }, + // { + // data: { id: '[0,9,1]', name: 'conv2d', parent: 'CNN' }, + // position: { x: 0, y: 0 },classes: 'layers', + // }, + // { + // data: { id: '[0,9,0]', name: 'maxPooling2d', parent: 'CNN' }, + // position: { x: 0, y: 0 },classes: 'layers', + // }, + // { + // data: { id: '[0,8,1]', name: 'conv2d', parent: 'CNN' }, + // position: { x: 0, y: 0 },classes: 'layers', + // }, + // { + // data: { id: '[0,8,0]', name: 'MNIST',parent:'CNN' }, + // position: { x: 0, y: 0 },classes: 'input', + // }, + // { + // data: { id: '[0,8,2]', name: 'Test',parent:'CNN' }, + // position: { x: 0, y: 0 },classes: 'viz', + // }, ], edges: [ - { data: { source: '0', target: '1' , name: ''},classes: 'exte', }, - { data: { source: '1', target: '2' , name: ''},classes: 'exte', }, - { data: { source: '2', target: '3' , name: ''},classes: 'exte', }, - { data: { source: '3', target: '4' , name: ''},classes: 'exte', }, - { data: { source: '4', target: '5' , name: ''},classes: 'exte', }, - { data: { source: '5', target: '6' , name: ''},classes: 'exte', }, - { data: { source: '6', target: '7' , name: ''},classes: 'exte', }, - { data: { source: '7', target: 'pred' , name: ''},classes: 'exte', }, - { data: { source: 'ex', target: '1' , name: ''},classes: 'exte', }, + // { data: { source: '[0,8,0]', target: '[0,8,1]' , name: ''},classes: 'exte', }, + // { data: { source: '[0,8,1]', target: '[0,9,0]' , name: ''},classes: 'exte', }, + // { data: { source: '[0,9,0]', target: '[0,9,1]' , name: ''},classes: 'exte', }, + // { data: { source: '[0,9,1]', target: '[0,10,0]' , name: ''},classes: 'exte', }, + // { data: { source: '[0,10,0]', target: '[0,10,1]' , name: ''},classes: 'exte', }, + // { data: { source: '[0,10,1]', target: '[0,11,0]' , name: ''},classes: 'exte', }, + // { data: { source: '[0,11,0]', target: '[0,11,1]' , name: ''},classes: 'exte', }, + // { data: { source: '[0,11,1]', target: '[0,12,0]' , name: ''},classes: 'exte', }, + // { data: { source: '[0,8,2]', target: '[0,8,1]' , name: ''},classes: 'exte', }, @@ -258,7 +300,7 @@ api.expandAll(); // cy.$('#vizs').style('background-image', 'https://farm6.staticflickr.com/5109/5817854163_eaccd688f5_b.jpg'); // cy.$('#vizs').style('background-image', dataUri); -console.log(cyy.$id("vizs")) +// console.log(cyy.$id("vizs")) function createImage(width,height){ @@ -295,3 +337,246 @@ function createImage(width,height){ } +document.addEventListener('selectNode', function (e) { + + var tgt=cyy.$id(e.detail.id); + cyy.nodes().unselect();//unselect the rest + tgt.select(); + +}, false); + +cyy.on('tap', 'node', function(){ + + if (this.selected()) { + //console.log('double clicked ' + this.id()); + if(this.id()=="[0,8,2]") //example node + { + GLOBALS.runExamplePrediction(); + + } + } + + // var nodes = this; + // GLOBALS.selectedjson=this._private.data.data; + var pos=utils.getXYZfromName(this.data('id')); + GLOBALS.selectNode(pos.x,pos.y,pos.z); + + + // this.trigger('blaa'); +}); + +document.addEventListener('addNode', function (e) { + cyy.edges().unselect();//unselect the rest + + var neighborhood=0; + + cyy.add({ + classes: ''+e.detail.data.classes, + data: { + id: e.detail.id, + name: e.detail.data.name, + parent: ''+e.detail.data.parent, + + isNeighborhood :0, + data:{ + id: e.detail.id, + name: '[' +e.detail.x +"," +e.detail.y+"," +e.detail.z+']', + neighbors:[], + dnn:e.detail.data + } + }, + position: { + x: e.detail.posX, + y: e.detail.posY, + } + }); + + x=parseInt(e.detail.x); + y=parseInt(e.detail.y); + z=parseInt(e.detail.z); + var i1,j1,k1; + + //-1:none,0:x+1,1:x-1,2:y+1,3:y-1,4:z+1,5:z-1,6:y+1&&z-1 + if(parseInt(e.detail.data.outputNeigh)==0){ + i1=x+1; + j1=y+0; + k1=z+0; + + }else if(parseInt(e.detail.data.outputNeigh)==1){ + i1=x-1; + j1=y+0; + k1=z+0; + + }else if(parseInt(e.detail.data.outputNeigh)==2){ + i1=x+0; + j1=y+1; + k1=z+0; + + }else if(parseInt(e.detail.data.outputNeigh)==3){ + i1=x+0; + j1=y-1; + k1=z+0; + + }else if(parseInt(e.detail.data.outputNeigh)==4){ + i1=x+0; + j1=y+0; + k1=z+1; + + }else if(parseInt(e.detail.data.outputNeigh)==5){ + i1=x+0; + j1=y+0; + k1=z-1; + + }else if(parseInt(e.detail.data.outputNeigh)==6){ + i1=x+0; + j1=y+1; + k1=z-1; + + } + + if(parseInt(e.detail.data.outputNeigh)>=0){ + cyy.add([ + { group: "edges",data: { name:'', source: '[' +x +"," +y+","+z+']', target: '[' +i1 +"," +j1+","+k1+']'}} + ]); + + } + + + + + // addEdges(e.detail.x,e.detail.y,e.detail.z); + + // var tgt=cy.$id('[' +e.detail.x +"," +e.detail.y+","+e.detail.z+']'); + // updateName(tgt); + + // neighborhood=findNeighborhood(tgt); + + // tgt.move({parent: ''+neighborhood}); + // tgt._private.data.data.parent= neighborhood; + + // api.expandAll(); + +}, false); + +document.addEventListener('updateNode', function (e) { + cyy.edges().unselect();//unselect the rest + + var tgt=cyy.$id(''+e.detail.id); + tgt.remove(); + console.log(tgt._private.position.x) + + // tgt._private.data.name=e.detail.dnn.name; + // tgt._private.data.classes=e.detail.dnn.classes; + // tgt._private.data.parent=''+e.detail.dnn.parent; + // tgt._private.data.data.dnn=''+e.detail.dnn; + + cyy.add({ + classes: ''+e.detail.dnn.classes, + data: { + id: e.detail.id, + name: e.detail.dnn.name, + parent: ''+e.detail.dnn.parent, + + isNeighborhood :0, + data:{ + id: e.detail.id, + name: '[' +e.detail.x +"," +e.detail.y+"," +e.detail.z+']', + neighbors:[], + dnn:e.detail.dnn + } + }, + position: { + x: e.detail.posX, + y: e.detail.posY, + } + }); + + x=parseInt(e.detail.x); + y=parseInt(e.detail.y); + z=parseInt(e.detail.z); + var i1,j1,k1; + + //-1:none,0:x+1,1:x-1,2:y+1,3:y-1,4:z+1,5:z-1,6:y+1&&z-1 + if(parseInt(e.detail.dnn.outputNeigh)==0){ + i1=x+1; + j1=y+0; + k1=z+0; + + }else if(parseInt(e.detail.dnn.outputNeigh)==1){ + i1=x-1; + j1=y+0; + k1=z+0; + + }else if(parseInt(e.detail.dnn.outputNeigh)==2){ + i1=x+0; + j1=y+1; + k1=z+0; + + }else if(parseInt(e.detail.dnn.outputNeigh)==3){ + i1=x+0; + j1=y-1; + k1=z+0; + + }else if(parseInt(e.detail.dnn.outputNeigh)==4){ + i1=x+0; + j1=y+0; + k1=z+1; + + }else if(parseInt(e.detail.dnn.outputNeigh)==5){ + i1=x+0; + j1=y+0; + k1=z-1; + + }else if(parseInt(e.detail.dnn.outputNeigh)==6){ + i1=x+0; + j1=y+1; + k1=z-1; + + } + + if(parseInt(e.detail.dnn.outputNeigh)>=0){ + cyy.add([ + { group: "edges",data: { name:'', source: '[' +x +"," +y+","+z+']', target: '[' +i1 +"," +j1+","+k1+']'}} + ]); + + } + + + + + // addEdges(e.detail.x,e.detail.y,e.detail.z); + + // var tgt=cy.$id('[' +e.detail.x +"," +e.detail.y+","+e.detail.z+']'); + // updateName(tgt); + + // neighborhood=findNeighborhood(tgt); + + // tgt.move({parent: ''+neighborhood}); + // tgt._private.data.data.parent= neighborhood; + + // api.expandAll(); + +}, false); + +document.addEventListener('removeNode', function (e) { + var tgt=cyy.$id(e.detail.id); + tgt.remove(); + +}, false); + + +var eh = cyy.edgehandles(); + +document.querySelector('#draw-on').addEventListener('click', function() { + eh.enableDrawMode(); +}); + +document.querySelector('#draw-off').addEventListener('click', function() { + eh.disableDrawMode(); +}); + +document.querySelector('#start').addEventListener('click', function() { + eh.start( cyy.$('node:selected') ); +}); + + diff --git a/01_Code/physical_computing_interface/dnn/script.js b/01_Code/physical_computing_interface/dnn/script.js index 8418b4077cde2c33c7b8270eff93936dd318bd30..8af7c3826333fab820213ce175dbdaa34f727c42 100644 --- a/01_Code/physical_computing_interface/dnn/script.js +++ b/01_Code/physical_computing_interface/dnn/script.js @@ -43,8 +43,10 @@ async function vizExample(data){ }); const imageArray=imageTensor.arraySync(); var dataUri= createImage(imageArray); - cyy.$('#ex').style('background-image', dataUri); - updateVariable('pred', "????"); + // cyy.$('#ex').style('background-image', dataUri); //?? todo + + cyy.$id("[0,8,2]").style('background-image', dataUri); //?? todo + updateVariable('[0,12,0]', "????"); } @@ -115,6 +117,11 @@ async function run() { } +async function runExample() { + + await doPrediction1(model, data, 1); +} + function getModel() { const model = tf.sequential(); @@ -228,7 +235,7 @@ function doPrediction1(model, data, testDataSize = 1) { }); const imageArray=imageTensor.arraySync(); var dataUri= createImage(imageArray); - cyy.$('#ex').style('background-image', dataUri); + cyy.$id("[0,8,2]").style('background-image', dataUri); @@ -240,7 +247,7 @@ function doPrediction1(model, data, testDataSize = 1) { testxs.dispose(); console.log(preds.arraySync()); - updateVariable('pred', ""+preds.arraySync()); + updateVariable('[0,12,0]', ""+preds.arraySync()); return [preds, labels]; } @@ -280,3 +287,4 @@ async function showConfusion(model, data) { document.addEventListener('DOMContentLoaded', load); document.addEventListener('runNode', run); +document.addEventListener('runExamplePrediction', runExample); diff --git a/01_Code/physical_computing_interface/globals.js b/01_Code/physical_computing_interface/globals.js index cba7f0e88ff374e13221cbda63310cf9bd88b766..0559d46b32ec766da6828e8449df69504bcd8c03 100644 --- a/01_Code/physical_computing_interface/globals.js +++ b/01_Code/physical_computing_interface/globals.js @@ -330,6 +330,8 @@ globals.prototype.removeNode=function (x,y,z,replay=false){ }; globals.prototype.updateNode=function (data){ + var pos=utils.getXYZfromName(data.id); + [p_x ,p_y ,p_z ,s_x ,s_y,s_z,r_y]=this.utils.getTransforms(this.grid,pos.x,pos.y,pos.z); var updateNodeEvent = new CustomEvent('updateNode', { detail: { @@ -342,7 +344,15 @@ globals.prototype.updateNode=function (data){ inputs:data.inputs, outputs:data.outputs, locked:data.locked, - numRuns:data.numRuns + numRuns:data.numRuns, + dnn:data.cnn, + x:pos.x, + y:pos.y, + z:pos.z, + posX:p_x, + posY:p_y, + posZ:p_z, + rotY:r_y } }); document.dispatchEvent(updateNodeEvent); @@ -419,6 +429,22 @@ globals.prototype.selectEdge=function (){ }); document.dispatchEvent(selectEdgeEvent); }; + +globals.prototype.runExamplePrediction=function (){ + var runExamplePredictionEvent = new CustomEvent('runExamplePrediction', { + detail: + { + // x:x, + // y:y, + // z:z, + // id:'[' +x +"," +y+","+z+']', + // posX:p_x, + // posY:p_y, + // posZ:p_z + } + }); + document.dispatchEvent(runExamplePredictionEvent); +}; ////////////////////////////////////////////// //////////////////////utils////////////////// diff --git a/01_Code/physical_computing_interface/graph/graph.js b/01_Code/physical_computing_interface/graph/graph.js index f28995447389f1463028487c26639c3785d11aad..41f4a69d629325d5936268765cf59bb37b85671a 100644 --- a/01_Code/physical_computing_interface/graph/graph.js +++ b/01_Code/physical_computing_interface/graph/graph.js @@ -394,7 +394,6 @@ function initGraph(){ ////////////////////////////////////////////////// //select node - //TODO: HIGHLIGHT NODE IN THREEJS cy.on('tap', 'node', function(){ // var nodes = this; // GLOBALS.selectedjson=this._private.data.data; @@ -484,6 +483,7 @@ function initGraph(){ y: e.detail.posY, } }); + api.expandAll(); @@ -593,6 +593,7 @@ function initGraph(){ tgt._private.data.data.code=data.code; tgt._private.data.data.locked=false; tgt._private.data.data.numRuns=0; + tgt._private.data.data.dnn=data.dnn; runNode(tgt); //todo: call event instead?? diff --git a/01_Code/physical_computing_interface/json/json.js b/01_Code/physical_computing_interface/json/json.js index ebc2aebdfe12e5f83b1bafee60fe7623bc99c195..207e6cd0aef7f8ae5ae84f79dae7afaa0695fead 100644 --- a/01_Code/physical_computing_interface/json/json.js +++ b/01_Code/physical_computing_interface/json/json.js @@ -1,7 +1,201 @@ function initEditor(){ + + // todo ?? move template creation to separate files + var templates = [ + { + text:"DEM simulation node", + title: 'Insert prediction viewer', + className: 'jsoneditor-type-object', + field: 'voxel', + value: { + name:"prediction", + size:5, + E:20000, + area:10.0 + } + }, + { + text: 'MNIST', + title: 'Insert a MNIST dataset', + className: 'jsoneditor-type-object', + field: 'cnn', + value: { + name:"MNIST", + imageSize:"(28,28)", + numDatasets:65000, + numTraining:55000, + numTest:65000-55000, + parent: 'CNN', + classes: 'input', + outputNeigh:-1 //0:x+1,1:x-1,2:y+1,3:y-1,4:z+1,5:z-1, + } + }, + { + text:"conv2d", + title: 'Insert a 3d convolutionsl layer', + className: 'jsoneditor-type-object', + field: 'cnn', + value: { + name:"conv2d_Conv2D1", + inputShape:"(batch,28,28,1)", + kernelSize:5, + filters:8, + strides:1, + activation: 'relu', + kernelInitializer: 'varianceScaling', + outputShape:"(batch,24,24,8)", + numParams:208, + Trainable:true, + parent: 'CNN', + classes: 'layers', + outputNeigh:-1 //0:x+1,1:x-1,2:y+1,3:y-1,4:z+1,5:z-1, + } + }, + { + text:"testImage", + title: 'Insert a test Image', + className: 'jsoneditor-type-object', + field: 'cnn', + value: { + name:"testImage", + imageSize:"(1,28,28)", + parent: 'CNN', + classes: 'viz', + outputNeigh:-1 //0:x+1,1:x-1,2:y+1,3:y-1,4:z+1,5:z-1, + } + }, + { + text:"max_pooling2d", + title: 'Insert a 2d max pooling layer', + className: 'jsoneditor-type-object', + field: 'cnn', + value: { + name:"max_pooling2d_MaxPooling2D1", + inputShape:"(batch,24,24,8)", + poolSize:"[2,2]", + strides:"[2,2]", + outputShape:"(batch,12,12,8)", + numParams:0, + Trainable:true, + parent: 'CNN', + classes: 'layers', + outputNeigh:-1 //0:x+1,1:x-1,2:y+1,3:y-1,4:z+1,5:z-1, + } + + }, + { + text:"flatten", + title: 'flattern layer', + className: 'jsoneditor-type-object', + field: 'cnn', + value: { + name:"flatten_Flatten1", + inputShape:"(batch,4,4,16)", + outputShape:"(batch,256)", + numParams:0, + Trainable:true, + parent: 'CNN', + classes: 'layers', + outputNeigh:-1 //0:x+1,1:x-1,2:y+1,3:y-1,4:z+1,5:z-1, + } + + }, + { + text:"dense", + title: 'Insert a fully connected layer', + className: 'jsoneditor-type-object', + field: 'cnn', + value: { + name:"dense_Dense1", + inputShape:"(batch,256)", + kernelInitializer: 'varianceScaling', + activation: 'softmax', + outputShape:"(batch,10)", + numParams:2570, + Trainable:true, + parent: 'CNN', + classes: 'layers', + outputNeigh:-1 //0:x+1,1:x-1,2:y+1,3:y-1,4:z+1,5:z-1, + } + + }, + { + text:"loss_categoricalCrossentropy", + title: 'Insert a categoricalCrossentropy loss layer', + className: 'jsoneditor-type-object', + field: 'cnn', + value: { + name:"loss_categoricalCrossentropy", + metrics: ['accuracy'], + parent: 'CNN', + classes: 'loss', + outputNeigh:-1 //0:x+1,1:x-1,2:y+1,3:y-1,4:z+1,5:z-1, + } + + }, + { + text:"prediction", + title: 'Insert prediction viewer', + className: 'jsoneditor-type-object', + field: 'cnn', + value: { + name:"prediction", + parent: 'CNN', + classes: 'output', + outputNeigh:-1 //0:x+1,1:x-1,2:y+1,3:y-1,4:z+1,5:z-1, + } + } + + ]; + + var schema = { + "title": "Example Schema", + "type": "array", + "items": { + "type": "object", + "properties": { + "firstName": { + "type": "string" + }, + "lastName": { + "type": "string" + }, + "gender": { + "enum": ["male", "female"] + }, + "age": { + "description": "Age in years", + "type": "integer", + "minimum": 0 + }, + "job": { + "$ref": "job" + } + }, + "required": ["firstName", "lastName"] + } + }; + + var job = { + "title": "Job description", + "type": "object", + "properties": { + "company": { + "type": "string" + }, + "role": { + "type": "string" + } + } + }; + + // create the editor var container = document.getElementById('jsoneditor'); var options = { + // schema: schema, + // schemaRefs: {"job": job}, + templates: templates, onChangeText: function (jsonString) { // console.log(jsonString); // const json = editor.get(); @@ -11,19 +205,6 @@ function initEditor(){ }; var editor = new JSONEditor(container, options); - // set json //get info - // document.getElementById('setJSON').onclick = function () { - // const json = { - // 'array': [1, 2, 3], - // 'boolean': true, - // 'color': '#82b92c', - // 'null': null, - // 'number': 123, - // 'object': {'a': 'b', 'c': 'd'}, - // 'string': 'Hello World' - // }; - // editor.set(GLOBALS.selectedjson); - // }; document.addEventListener('selectNode', function (e) { editor.set(GLOBALS.selectedjson); diff --git a/01_Code/physical_computing_interface/lib/cytoscape-edgehandles.js b/01_Code/physical_computing_interface/lib/cytoscape-edgehandles.js new file mode 100644 index 0000000000000000000000000000000000000000..1d64377ed8ad642f748ae6b94676d6172b3d6380 --- /dev/null +++ b/01_Code/physical_computing_interface/lib/cytoscape-edgehandles.js @@ -0,0 +1,1404 @@ +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(require("lodash.memoize"), require("lodash.throttle")); + else if(typeof define === 'function' && define.amd) + define(["lodash.memoize", "lodash.throttle"], factory); + else if(typeof exports === 'object') + exports["cytoscapeEdgehandles"] = factory(require("lodash.memoize"), require("lodash.throttle")); + else + root["cytoscapeEdgehandles"] = factory(root["_"]["memoize"], root["_"]["throttle"]); +})(this, function(__WEBPACK_EXTERNAL_MODULE_13__, __WEBPACK_EXTERNAL_MODULE_14__) { +return /******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // identity function for calling harmony imports with the correct context +/******/ __webpack_require__.i = function(value) { return value; }; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { +/******/ configurable: false, +/******/ enumerable: true, +/******/ get: getter +/******/ }); +/******/ } +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 12); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +// Simple, internal Object.assign() polyfill for options objects etc. + +module.exports = Object.assign != null ? Object.assign.bind(Object) : function (tgt) { + for (var _len = arguments.length, srcs = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + srcs[_key - 1] = arguments[_key]; + } + + srcs.filter(function (src) { + return src != null; + }).forEach(function (src) { + Object.keys(src).forEach(function (k) { + return tgt[k] = src[k]; + }); + }); + + return tgt; +}; + +/***/ }), +/* 1 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var Edgehandles = __webpack_require__(10); +var assign = __webpack_require__(0); + +module.exports = function (options) { + var cy = this; + + return new Edgehandles(assign({ cy: cy }, options)); +}; + +/***/ }), +/* 2 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +function disableGestures() { + this.saveGestureState(); + + this.cy.zoomingEnabled(false).panningEnabled(false).boxSelectionEnabled(false); + + if (this.options.disableBrowserGestures) { + var wlOpts = this.windowListenerOptions; + + window.addEventListener('touchstart', this.preventDefault, wlOpts); + window.addEventListener('touchmove', this.preventDefault, wlOpts); + window.addEventListener('wheel', this.preventDefault, wlOpts); + } + + return this; +} + +function resetGestures() { + this.cy.zoomingEnabled(this.lastZoomingEnabled).panningEnabled(this.lastPanningEnabled).boxSelectionEnabled(this.lastBoxSelectionEnabled); + + if (this.options.disableBrowserGestures) { + var wlOpts = this.windowListenerOptions; + + window.removeEventListener('touchstart', this.preventDefault, wlOpts); + window.removeEventListener('touchmove', this.preventDefault, wlOpts); + window.removeEventListener('wheel', this.preventDefault, wlOpts); + } + + return this; +} + +function saveGestureState() { + var cy = this.cy; + + + this.lastPanningEnabled = cy.panningEnabled(); + this.lastZoomingEnabled = cy.zoomingEnabled(); + this.lastBoxSelectionEnabled = cy.boxSelectionEnabled(); + + return this; +} + +module.exports = { disableGestures: disableGestures, resetGestures: resetGestures, saveGestureState: saveGestureState }; + +/***/ }), +/* 3 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +function addCytoscapeListeners() { + var _this = this; + + var cy = this.cy, + options = this.options; + + // grabbing nodes + + this.addListener(cy, 'drag', function () { + return _this.grabbingNode = true; + }); + this.addListener(cy, 'free', function () { + return _this.grabbingNode = false; + }); + + // show handle on hover + this.addListener(cy, 'mouseover', 'node', function (e) { + _this.show(e.target); + }); + + // hide handle on tap handle + this.addListener(cy, 'tap', 'node', function (e) { + var node = e.target; + + if (!node.same(_this.handleNode)) { + _this.show(node); + } + }); + + // hide handle when source node moved + this.addListener(cy, 'position', 'node', function (e) { + if (e.target.same(_this.sourceNode)) { + _this.hide(); + } + }); + + // start on tapstart handle + // start on tapstart node (draw mode) + // toggle on source node + this.addListener(cy, 'tapstart', 'node', function (e) { + var node = e.target; + + if (node.same(_this.handleNode)) { + _this.start(_this.sourceNode); + } else if (_this.drawMode) { + _this.start(node); + } else if (node.same(_this.sourceNode)) { + _this.hide(); + } + }); + + // update line on drag + this.addListener(cy, 'tapdrag', function (e) { + _this.update(e.position); + }); + + // hover over preview + this.addListener(cy, 'tapdragover', 'node', function (e) { + if (options.snap) { + // then ignore events like mouseover + } else { + _this.preview(e.target); + } + }); + + // hover out unpreview + this.addListener(cy, 'tapdragout', 'node', function (e) { + if (options.snap) { + // then keep the preview + } else { + _this.unpreview(e.target); + } + }); + + // stop gesture on tapend + this.addListener(cy, 'tapend', function () { + _this.stop(); + }); + + // hide handle if source node is removed + this.addListener(cy, 'remove', function (e) { + if (e.target.same(_this.sourceNode)) { + _this.hide(); + } + }); + + return this; +} + +module.exports = { addCytoscapeListeners: addCytoscapeListeners }; + +/***/ }), +/* 4 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +/* eslint-disable no-unused-vars */ +var defaults = { + preview: true, // whether to show added edges preview before releasing selection + hoverDelay: 150, // time spent hovering over a target node before it is considered selected + handleNodes: 'node', // selector/filter function for whether edges can be made from a given node + snap: false, // when enabled, the edge can be drawn by just moving close to a target node (can be confusing on compound graphs) + snapThreshold: 50, // the target node must be less than or equal to this many pixels away from the cursor/finger + snapFrequency: 15, // the number of times per second (Hz) that snap checks done (lower is less expensive) + noEdgeEventsInDraw: false, // set events:no to edges during draws, prevents mouseouts on compounds + disableBrowserGestures: true, // during an edge drawing gesture, disable browser gestures such as two-finger trackpad swipe and pinch-to-zoom + handlePosition: function handlePosition(node) { + return 'middle top'; // sets the position of the handle in the format of "X-AXIS Y-AXIS" such as "left top", "middle top" + }, + handleInDrawMode: false, // whether to show the handle in draw mode + edgeType: function edgeType(sourceNode, targetNode) { + // can return 'flat' for flat edges between nodes or 'node' for intermediate node between them + // returning null/undefined means an edge can't be added between the two nodes + return 'flat'; + }, + loopAllowed: function loopAllowed(node) { + // for the specified node, return whether edges from itself to itself are allowed + return false; + }, + nodeLoopOffset: -50, // offset for edgeType: 'node' loops + nodeParams: function nodeParams(sourceNode, targetNode) { + // for edges between the specified source and target + // return element object to be passed to cy.add() for intermediary node + return {}; + }, + edgeParams: function edgeParams(sourceNode, targetNode, i) { + // for edges between the specified source and target + // return element object to be passed to cy.add() for edge + // NB: i indicates edge index in case of edgeType: 'node' + return {}; + }, + ghostEdgeParams: function ghostEdgeParams() { + // return element object to be passed to cy.add() for the ghost edge + // (default classes are always added for you) + return {}; + }, + show: function show(sourceNode) { + // fired when handle is shown + }, + hide: function hide(sourceNode) { + // fired when the handle is hidden + }, + start: function start(sourceNode) { + // fired when edgehandles interaction starts (drag on handle) + }, + complete: function complete(sourceNode, targetNode, addedEles) { + // fired when edgehandles is done and elements are added + }, + stop: function stop(sourceNode) { + // fired when edgehandles interaction is stopped (either complete with added edges or incomplete) + }, + cancel: function cancel(sourceNode, cancelledTargets) { + // fired when edgehandles are cancelled (incomplete gesture) + }, + hoverover: function hoverover(sourceNode, targetNode) { + // fired when a target is hovered + }, + hoverout: function hoverout(sourceNode, targetNode) { + // fired when a target isn't hovered anymore + }, + previewon: function previewon(sourceNode, targetNode, previewEles) { + // fired when preview is shown + }, + previewoff: function previewoff(sourceNode, targetNode, previewEles) { + // fired when preview is hidden + }, + drawon: function drawon() { + // fired when draw mode enabled + }, + drawoff: function drawoff() { + // fired when draw mode disabled + } +}; +/* eslint-enable */ + +module.exports = defaults; + +/***/ }), +/* 5 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +function toggleDrawMode(bool) { + var cy = this.cy, + options = this.options; + + + this.drawMode = bool != null ? bool : !this.drawMode; + + if (this.drawMode) { + this.prevUngrabifyState = cy.autoungrabify(); + + cy.autoungrabify(true); + + if (!options.handleInDrawMode && this.handleShown()) { + this.hide(); + } + + this.emit('drawon'); + } else { + cy.autoungrabify(this.prevUngrabifyState); + + this.emit('drawoff'); + } + + return this; +} + +function enableDrawMode() { + return this.toggleDrawMode(true); +} + +function disableDrawMode() { + return this.toggleDrawMode(false); +} + +module.exports = { toggleDrawMode: toggleDrawMode, enableDrawMode: enableDrawMode, disableDrawMode: disableDrawMode }; + +/***/ }), +/* 6 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +var assign = __webpack_require__(0); +var isString = function isString(x) { + return (typeof x === 'undefined' ? 'undefined' : _typeof(x)) === _typeof(''); +}; +var isArray = function isArray(x) { + return (typeof x === 'undefined' ? 'undefined' : _typeof(x)) === _typeof([]) && x.length != null; +}; + +function getEleJson(overrides, params, addedClasses) { + var json = {}; + + // basic values + assign(json, params, overrides); + + // make sure params can specify data but that overrides take precedence + assign(json.data, params.data, overrides.data); + + if (isString(params.classes)) { + json.classes = params.classes + ' ' + addedClasses; + } else if (isArray(params.classes)) { + json.classes = params.classes.join(' ') + ' ' + addedClasses; + } else { + json.classes = addedClasses; + } + + return json; +} + +function makeEdges() { + var preview = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + var cy = this.cy, + options = this.options, + presumptiveTargets = this.presumptiveTargets, + previewEles = this.previewEles, + active = this.active; + + + var source = this.sourceNode; + var target = this.targetNode; + var classes = preview ? 'eh-preview' : ''; + var added = cy.collection(); + var edgeType = options.edgeType(source, target); + + // can't make edges outside of regular gesture lifecycle + if (!active) { + return; + } + + // must have a non-empty edge type + if (!edgeType) { + return; + } + + // can't make preview if disabled + if (preview && !options.preview) { + return; + } + + // detect cancel + if (!target || target.size() === 0) { + previewEles.remove(); + + this.emit('cancel', this.mp(), source, presumptiveTargets); + + return; + } + + // just remove preview class if we already have the edges + if (!preview && options.preview) { + previewEles.removeClass('eh-preview').style('events', ''); + + this.emit('complete', this.mp(), source, target, previewEles); + + return; + } + + var p1 = source.position(); + var p2 = target.position(); + + var p = void 0; + if (source.same(target)) { + p = { + x: p1.x + options.nodeLoopOffset, + y: p1.y + options.nodeLoopOffset + }; + } else { + p = { + x: (p1.x + p2.x) / 2, + y: (p1.y + p2.y) / 2 + }; + } + + if (edgeType === 'node') { + var interNode = cy.add(getEleJson({ + group: 'nodes', + position: p + }, options.nodeParams(source, target), classes)); + + var source2inter = cy.add(getEleJson({ + group: 'edges', + data: { + source: source.id(), + target: interNode.id() + } + }, options.edgeParams(source, target, 0), classes)); + + var inter2target = cy.add(getEleJson({ + group: 'edges', + data: { + source: interNode.id(), + target: target.id() + } + }, options.edgeParams(source, target, 1), classes)); + + added = added.merge(interNode).merge(source2inter).merge(inter2target); + } else { + // flat + var source2target = cy.add(getEleJson({ + group: 'edges', + data: { + source: source.id(), + target: target.id() + } + }, options.edgeParams(source, target, 0), classes)); + + added = added.merge(source2target); + } + + if (preview) { + this.previewEles = added; + + added.style('events', 'no'); + } else { + added.style('events', ''); + + this.emit('complete', this.mp(), source, target, added); + } + + return this; +} + +function makePreview() { + this.makeEdges(true); + + return this; +} + +function previewShown() { + return this.previewEles.nonempty() && this.previewEles.inside(); +} + +function removePreview() { + if (this.previewShown()) { + this.previewEles.remove(); + } + + return this; +} + +function handleShown() { + return this.handleNode.nonempty() && this.handleNode.inside(); +} + +function removeHandle() { + if (this.handleShown()) { + this.handleNode.remove(); + } + + return this; +} + +function setHandleFor(node) { + var _this = this; + + var options = this.options, + cy = this.cy; + + + var handlePosition = _typeof(options.handlePosition) === _typeof('') ? function () { + return options.handlePosition; + } : options.handlePosition; + + var p = node.position(); + var h = node.outerHeight(); + var w = node.outerWidth(); + + // store how much we should move the handle from origin(p.x, p.y) + var moveX = 0; + var moveY = 0; + + // grab axes + var axes = handlePosition(node).toLowerCase().split(/\s+/); + var axisX = axes[0]; + var axisY = axes[1]; + + // based on handlePosition move left/right/top/bottom. Middle/middle will just be normal + if (axisX === 'left') { + moveX = -(w / 2); + } else if (axisX === 'right') { + moveX = w / 2; + }if (axisY === 'top') { + moveY = -(h / 2); + } else if (axisY === 'bottom') { + moveY = h / 2; + } + + // set handle x and y based on adjusted positions + var hx = this.hx = p.x + moveX; + var hy = this.hy = p.y + moveY; + var pos = { x: hx, y: hy }; + + if (this.handleShown()) { + this.handleNode.position(pos); + } else { + cy.batch(function () { + _this.handleNode = cy.add({ + classes: 'eh-handle', + position: pos, + grabbable: false, + selectable: false + }); + + _this.handleNode.style('z-index', 9007199254740991); + }); + } + + return this; +} + +function updateEdge() { + var _this2 = this; + + var sourceNode = this.sourceNode, + ghostNode = this.ghostNode, + cy = this.cy, + mx = this.mx, + my = this.my, + options = this.options; + + var x = mx; + var y = my; + var ghostEdge = void 0, + ghostEles = void 0; + + // can't draw a line without having the starting node + if (!sourceNode) { + return; + } + + if (!ghostNode || ghostNode.length === 0 || ghostNode.removed()) { + ghostEles = this.ghostEles = cy.collection(); + + cy.batch(function () { + ghostNode = _this2.ghostNode = cy.add({ + group: 'nodes', + classes: 'eh-ghost eh-ghost-node', + position: { + x: 0, + y: 0 + } + }); + + ghostNode.style({ + 'background-color': 'blue', + 'width': 0.0001, + 'height': 0.0001, + 'opacity': 0, + 'events': 'no' + }); + + var ghostEdgeParams = options.ghostEdgeParams(); + + ghostEdge = cy.add(assign({}, ghostEdgeParams, { + group: 'edges', + data: assign({}, ghostEdgeParams.data, { + source: sourceNode.id(), + target: ghostNode.id() + }), + classes: 'eh-ghost eh-ghost-edge' + })); + + ghostEdge.style({ + 'events': 'no' + }); + }); + + ghostEles.merge(ghostNode).merge(ghostEdge); + } + + ghostNode.position({ x: x, y: y }); + + return this; +} + +module.exports = { + makeEdges: makeEdges, makePreview: makePreview, removePreview: removePreview, previewShown: previewShown, + updateEdge: updateEdge, + handleShown: handleShown, setHandleFor: setHandleFor, removeHandle: removeHandle +}; + +/***/ }), +/* 7 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +function disableEdgeEvents() { + if (this.options.noEdgeEventsInDraw) { + this.cy.edges().style('events', 'no'); + } + + return this; +} + +function enableEdgeEvents() { + if (this.options.noEdgeEventsInDraw) { + this.cy.edges().style('events', ''); + } + + return this; +} + +module.exports = { disableEdgeEvents: disableEdgeEvents, enableEdgeEvents: enableEdgeEvents }; + +/***/ }), +/* 8 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +function enable() { + this.enabled = true; + + this.emit('enable'); + + return this; +} + +function disable() { + this.enabled = false; + + this.emit('disable'); + + return this; +} + +module.exports = { enable: enable, disable: disable }; + +/***/ }), +/* 9 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var memoize = __webpack_require__(13); +var sqrt2 = Math.sqrt(2); + +function canStartOn(node) { + var options = this.options, + previewEles = this.previewEles, + ghostEles = this.ghostEles, + handleNode = this.handleNode; + + var isPreview = function isPreview(el) { + return previewEles.anySame(el); + }; + var isGhost = function isGhost(el) { + return ghostEles.anySame(el); + }; + var userFilter = function userFilter(el) { + return el.filter(options.handleNodes).length > 0; + }; + var isHandle = function isHandle(el) { + return handleNode.same(el); + }; + var isTemp = function isTemp(el) { + return isPreview(el) || isHandle(el) || isGhost(el); + }; + + var enabled = this.enabled, + active = this.active, + grabbingNode = this.grabbingNode; + + + return enabled && !active && !grabbingNode && (node == null || !isTemp(node) && userFilter(node)); +} + +function canStartDrawModeOn(node) { + return this.canStartOn(node) && this.drawMode; +} + +function canStartNonDrawModeOn(node) { + return this.canStartOn(node) && !this.drawMode; +} + +function show(node) { + var options = this.options, + drawMode = this.drawMode; + + + if (!this.canStartOn(node) || drawMode && !options.handleInDrawMode) { + return; + } + + this.sourceNode = node; + + this.setHandleFor(node); + + this.emit('show', this.hp(), this.sourceNode); + + return this; +} + +function hide() { + this.removeHandle(); + + this.emit('hide', this.hp(), this.sourceNode); + + return this; +} + +function start(node) { + if (!this.canStartOn(node)) { + return; + } + + this.active = true; + + this.sourceNode = node; + this.sourceNode.addClass('eh-source'); + + this.disableGestures(); + this.disableEdgeEvents(); + + this.emit('start', this.hp(), node); +} + +function update(pos) { + if (!this.active) { + return; + } + + var p = pos; + + this.mx = p.x; + this.my = p.y; + + this.updateEdge(); + this.throttledSnap(); + + return this; +} + +function snap() { + if (!this.active || !this.options.snap) { + return false; + } + + var cy = this.cy; + var tgt = this.targetNode; + var threshold = this.options.snapThreshold; + var mousePos = this.mp(); + var handleNode = this.handleNode, + previewEles = this.previewEles, + ghostNode = this.ghostNode; + + + var radius = function radius(n) { + return sqrt2 * Math.max(n.outerWidth(), n.outerHeight()) / 2; + }; // worst-case enclosure of bb by circle + var sqDist = function sqDist(x1, y1, x2, y2) { + var dx = x2 - x1;var dy = y2 - y1;return dx * dx + dy * dy; + }; + var sqDistByPt = function sqDistByPt(p1, p2) { + return sqDist(p1.x, p1.y, p2.x, p2.y); + }; + var nodeSqDist = function nodeSqDist(n) { + return sqDistByPt(n.position(), mousePos); + }; + + var sqThreshold = function sqThreshold(n) { + var r = radius(n);var t = r + threshold;return t * t; + }; + var isWithinTheshold = function isWithinTheshold(n) { + return nodeSqDist(n) <= sqThreshold(n); + }; + + var bbSqDist = function bbSqDist(n) { + var p = n.position(); + var halfW = n.outerWidth() / 2; + var halfH = n.outerHeight() / 2; + + // node and mouse positions, line is formed from node to mouse + var nx = p.x; + var ny = p.y; + var mx = mousePos.x; + var my = mousePos.y; + + // bounding box + var x1 = nx - halfW; + var x2 = nx + halfW; + var y1 = ny - halfH; + var y2 = ny + halfH; + + var insideXBounds = x1 <= mx && mx <= x2; + var insideYBounds = y1 <= my && my <= y2; + + if (insideXBounds && insideYBounds) { + // inside box + return 0; + } else if (insideXBounds) { + // perpendicular distance to box, top or bottom + var dy1 = my - y1; + var dy2 = my - y2; + + return Math.min(dy1 * dy1, dy2 * dy2); + } else if (insideYBounds) { + // perpendicular distance to box, left or right + var dx1 = mx - x1; + var dx2 = mx - x2; + + return Math.min(dx1 * dx1, dx2 * dx2); + } else if (mx < x1 && my < y1) { + // top-left corner distance + return sqDist(mx, my, x1, y1); + } else if (mx > x2 && my < y1) { + // top-right corner distance + return sqDist(mx, my, x2, y1); + } else if (mx < x1 && my > y2) { + // bottom-left corner distance + return sqDist(mx, my, x1, y2); + } else { + // bottom-right corner distance + return sqDist(mx, my, x2, y2); + } + }; + + var cmpBbSqDist = function cmpBbSqDist(n1, n2) { + return bbSqDist(n1) - bbSqDist(n2); + }; + + var cmp = cmpBbSqDist; + + var allowHoverDelay = false; + + var mouseIsInside = function mouseIsInside(n) { + var mp = mousePos; + var w = n.outerWidth(); + var halfW = w / 2; + var h = n.outerHeight(); + var halfH = h / 2; + var p = n.position(); + var x1 = p.x - halfW; + var x2 = p.x + halfW; + var y1 = p.y - halfH; + var y2 = p.y + halfH; + + return x1 <= mp.x && mp.x <= x2 && y1 <= mp.y && mp.y <= y2; + }; + + var isEhEle = function isEhEle(n) { + return n.same(handleNode) || n.same(previewEles) || n.same(ghostNode); + }; + + var nodesByDist = cy.nodes(function (n) { + return !isEhEle(n) && isWithinTheshold(n); + }).sort(cmp); + var snapped = false; + + if (tgt.nonempty() && !isWithinTheshold(tgt)) { + this.unpreview(tgt); + } + + for (var i = 0; i < nodesByDist.length; i++) { + var n = nodesByDist[i]; + + // skip a parent node when the mouse is inside it + if (n.isParent() && mouseIsInside(n)) { + continue; + } + + // skip a child node when the mouse is not inside the parent + if (n.isChild() && !mouseIsInside(n.parent())) { + continue; + } + + if (n.same(tgt) || this.preview(n, allowHoverDelay)) { + snapped = true; + break; + } + } + + return snapped; +} + +function preview(target) { + var _this = this; + + var allowHoverDelay = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + var options = this.options, + sourceNode = this.sourceNode, + ghostNode = this.ghostNode, + ghostEles = this.ghostEles, + presumptiveTargets = this.presumptiveTargets, + previewEles = this.previewEles, + active = this.active; + + var source = sourceNode; + var isLoop = target.same(source); + var loopAllowed = options.loopAllowed(target); + var isGhost = target.same(ghostNode); + var noEdge = !options.edgeType(source, target); + var isHandle = target.same(this.handleNode); + var isExistingTgt = target.same(this.targetNode); + + if (!active || isHandle || isGhost || noEdge || isExistingTgt || isLoop && !loopAllowed + // || (target.isParent()) + ) { + return false; + } + + if (this.targetNode.nonempty()) { + this.unpreview(this.targetNode); + } + + clearTimeout(this.previewTimeout); + + var applyPreview = function applyPreview() { + _this.targetNode = target; + + presumptiveTargets.merge(target); + + target.addClass('eh-presumptive-target'); + target.addClass('eh-target'); + + _this.emit('hoverover', _this.mp(), source, target); + + if (options.preview) { + target.addClass('eh-preview'); + + ghostEles.addClass('eh-preview-active'); + sourceNode.addClass('eh-preview-active'); + target.addClass('eh-preview-active'); + + _this.makePreview(); + + _this.emit('previewon', _this.mp(), source, target, previewEles); + } + }; + + if (allowHoverDelay && options.hoverDelay > 0) { + this.previewTimeout = setTimeout(applyPreview, options.hoverDelay); + } else { + applyPreview(); + } + + return true; +} + +function unpreview(target) { + if (!this.active || target.same(this.handleNode)) { + return; + } + + var previewTimeout = this.previewTimeout, + sourceNode = this.sourceNode, + previewEles = this.previewEles, + ghostEles = this.ghostEles, + cy = this.cy; + + clearTimeout(previewTimeout); + this.previewTimeout = null; + + var source = sourceNode; + + target.removeClass('eh-preview eh-target eh-presumptive-target eh-preview-active'); + ghostEles.removeClass('eh-preview-active'); + sourceNode.removeClass('eh-preview-active'); + + this.targetNode = cy.collection(); + + this.removePreview(source, target); + + this.emit('hoverout', this.mp(), source, target); + this.emit('previewoff', this.mp(), source, target, previewEles); + + return this; +} + +function stop() { + if (!this.active) { + return; + } + + var sourceNode = this.sourceNode, + targetNode = this.targetNode, + ghostEles = this.ghostEles, + presumptiveTargets = this.presumptiveTargets; + + + clearTimeout(this.previewTimeout); + + sourceNode.removeClass('eh-source'); + targetNode.removeClass('eh-target eh-preview eh-hover'); + presumptiveTargets.removeClass('eh-presumptive-target'); + + this.makeEdges(); + + this.removeHandle(); + + ghostEles.remove(); + + this.clearCollections(); + + this.resetGestures(); + this.enableEdgeEvents(); + + this.active = false; + + this.emit('stop', this.mp(), sourceNode); + + return this; +} + +module.exports = { + show: show, hide: hide, start: start, update: update, preview: preview, unpreview: unpreview, stop: stop, snap: snap, + canStartOn: canStartOn, canStartDrawModeOn: canStartDrawModeOn, canStartNonDrawModeOn: canStartNonDrawModeOn +}; + +/***/ }), +/* 10 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var defaults = __webpack_require__(4); +var assign = __webpack_require__(0); +var throttle = __webpack_require__(14); + +var cyGesturesToggle = __webpack_require__(2); +var cyListeners = __webpack_require__(3); +var drawMode = __webpack_require__(5); +var drawing = __webpack_require__(6); +var enabling = __webpack_require__(8); +var gestureLifecycle = __webpack_require__(9); +var listeners = __webpack_require__(11); +var edgeEvents = __webpack_require__(7); + +function Edgehandles(options) { + var cy = options.cy; + + this.cy = cy; + this.listeners = []; + + // edgehandles gesture state + this.enabled = true; + this.drawMode = false; + this.active = false; + this.grabbingNode = false; + + // edgehandles elements + this.handleNode = cy.collection(); + this.clearCollections(); + + // handle + this.hx = 0; + this.hy = 0; + this.hr = 0; + + // mouse position + this.mx = 0; + this.my = 0; + + this.options = assign({}, defaults, options); + + this.saveGestureState(); + this.addListeners(); + + this.throttledSnap = throttle(this.snap.bind(this), 1000 / options.snapFrequency); + + this.preventDefault = function (e) { + return e.preventDefault(); + }; + + var supportsPassive = false; + try { + var opts = Object.defineProperty({}, 'passive', { + get: function get() { + supportsPassive = true; + } + }); + + window.addEventListener('test', null, opts); + } catch (err) {} + + if (supportsPassive) { + this.windowListenerOptions = { capture: true, passive: false }; + } else { + this.windowListenerOptions = true; + } +} + +var proto = Edgehandles.prototype = {}; +var extend = function extend(obj) { + return assign(proto, obj); +}; + +proto.destroy = function () { + this.removeListeners(); +}; + +proto.setOptions = function (options) { + assign(this.options, options); +}; + +proto.mp = function () { + return { x: this.mx, y: this.my }; +}; + +proto.hp = function () { + return { x: this.hx, y: this.hy }; +}; + +proto.clearCollections = function () { + var cy = this.cy; + + + this.previewEles = cy.collection(); + this.ghostEles = cy.collection(); + this.ghostNode = cy.collection(); + this.sourceNode = cy.collection(); + this.targetNode = cy.collection(); + this.presumptiveTargets = cy.collection(); +}; + +[cyGesturesToggle, cyListeners, drawMode, drawing, enabling, gestureLifecycle, listeners, edgeEvents].forEach(extend); + +module.exports = Edgehandles; + +/***/ }), +/* 11 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +function addListeners() { + var _this = this; + + this.addCytoscapeListeners(); + + this.addListener(this.cy, 'destroy', function () { + return _this.destroy(); + }); + + return this; +} + +function removeListeners() { + for (var i = this.listeners.length - 1; i >= 0; i--) { + var l = this.listeners[i]; + + this.removeListener(l.target, l.event, l.selector, l.callback, l.options); + } + + return this; +} + +function getListener(target, event, selector, callback, options) { + if ((typeof selector === 'undefined' ? 'undefined' : _typeof(selector)) !== _typeof('')) { + callback = selector; + options = callback; + selector = null; + } + + if (options == null) { + options = false; + } + + return { target: target, event: event, selector: selector, callback: callback, options: options }; +} + +function isDom(target) { + return target instanceof Element; +} + +function addListener(target, event, selector, callback, options) { + var l = getListener(target, event, selector, callback, options); + + this.listeners.push(l); + + if (isDom(l.target)) { + l.target.addEventListener(l.event, l.callback, l.options); + } else { + if (l.selector) { + l.target.addListener(l.event, l.selector, l.callback, l.options); + } else { + l.target.addListener(l.event, l.callback, l.options); + } + } + + return this; +} + +function removeListener(target, event, selector, callback, options) { + var l = getListener(target, event, selector, callback, options); + + for (var i = this.listeners.length - 1; i >= 0; i--) { + var l2 = this.listeners[i]; + + if (l.target === l2.target && l.event === l2.event && (l.selector == null || l.selector === l2.selector) && (l.callback == null || l.callback === l2.callback)) { + this.listeners.splice(i, 1); + + if (isDom(l.target)) { + l.target.removeEventListener(l.event, l.callback, l.options); + } else { + if (l.selector) { + l.target.removeListener(l.event, l.selector, l.callback, l.options); + } else { + l.target.removeListener(l.event, l.callback, l.options); + } + } + + break; + } + } + + return this; +} + +function emit(type, position) { + var options = this.options, + cy = this.cy; + + for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { + args[_key - 2] = arguments[_key]; + } + + cy.emit({ type: 'eh' + type, position: position }, args); + + var handler = options[type]; + + if (handler != null) { + handler.apply(undefined, args); + } + + return this; +} + +module.exports = { addListener: addListener, addListeners: addListeners, removeListener: removeListener, removeListeners: removeListeners, emit: emit }; + +/***/ }), +/* 12 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var impl = __webpack_require__(1); + +// registers the extension on a cytoscape lib ref +var register = function register(cytoscape) { + if (!cytoscape) { + return; + } // can't register if cytoscape unspecified + + cytoscape('core', 'edgehandles', impl); // register with cytoscape.js +}; + +if (typeof cytoscape !== 'undefined') { + // expose to global cytoscape (i.e. window.cytoscape) + register(cytoscape); // eslint-disable-line no-undef +} + +module.exports = register; + +/***/ }), +/* 13 */ +/***/ (function(module, exports) { + +module.exports = __WEBPACK_EXTERNAL_MODULE_13__; + +/***/ }), +/* 14 */ +/***/ (function(module, exports) { + +module.exports = __WEBPACK_EXTERNAL_MODULE_14__; + +/***/ }) +/******/ ]); +}); \ No newline at end of file diff --git a/01_Code/physical_computing_interface/threejs/grid.js b/01_Code/physical_computing_interface/threejs/grid.js index 055fd44dfad3e0b07b3e9a01fc9a0b95bfaffbb0..8c7bd1144a9583624f28100d788520fc766b322f 100644 --- a/01_Code/physical_computing_interface/threejs/grid.js +++ b/01_Code/physical_computing_interface/threejs/grid.js @@ -468,6 +468,7 @@ function onDocumentMouseDownThree( event ) { var obj=utils.getXYZfromName(intersect.object.name); obj=utils.getXYZfromName(three.rollOverMesh.name); GLOBALS.addNode (obj.x, obj.y,obj.z); + GLOBALS.selectNode (obj.x, obj.y,obj.z); } if ( intersects1.length > 0 && event.which==3){//right click var intersect = intersects1[ 0 ];