<head> <style> body { margin: 0; } </style> <title>MetaVoxel</title> <script src="//unpkg.com/three"></script> <script src="../lib/js-colormaps.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script> <script src="//unpkg.com/3d-force-graph"></script> <!-- <script src="../lib/3d-force-graph.js"></script> --> <script src="//unpkg.com/three-spritetext"></script> <script src="../visualization/utils.js"></script> </head> <body> <div id="3d-graph"></div> <script> var color1= 0xffffff; /*white*/ var color2= '#020227'; /*kohly*/ var color3= 0x1c5c61; /*teal*/ var color4= "#fa6e70"; //red/orange var color5="#380152"; //purple var color6="#696767"; //grey var color7="#03dbfc"; //blue var nodes=[]; var buildList=[]; var offset2=12; var offset=offset2+8; var buildSize=32; var gridSize=buildSize+2*(offset); var scale,setup; var voxelIndexList=[ null, { size:1, list:[ new THREE.Vector3(0,0,0), ] }, { size:2, list:[ new THREE.Vector3(0,0,0), new THREE.Vector3(0,1,0), new THREE.Vector3(1,0,0), new THREE.Vector3(1,1,0), new THREE.Vector3(0,0,1), new THREE.Vector3(0,1,1), new THREE.Vector3(1,0,1), new THREE.Vector3(1,1,1) ] }, null, { size:4, list:[ new THREE.Vector3(0,0,0), new THREE.Vector3(0,1,0), new THREE.Vector3(0,2,0), new THREE.Vector3(0,3,0), new THREE.Vector3(1,0,0), new THREE.Vector3(1,1,0), new THREE.Vector3(1,2,0), new THREE.Vector3(1,3,0), new THREE.Vector3(2,0,0), new THREE.Vector3(2,1,0), new THREE.Vector3(2,2,0), new THREE.Vector3(2,3,0), new THREE.Vector3(3,0,0), new THREE.Vector3(3,1,0), new THREE.Vector3(3,2,0), new THREE.Vector3(3,3,0), new THREE.Vector3(0,0,1), new THREE.Vector3(0,1,1), new THREE.Vector3(0,2,1), new THREE.Vector3(0,3,1), new THREE.Vector3(1,0,1), // new THREE.Vector3(1,1,1), // new THREE.Vector3(1,2,1), new THREE.Vector3(1,3,1), new THREE.Vector3(2,0,1), // new THREE.Vector3(2,1,1), // new THREE.Vector3(2,2,1), new THREE.Vector3(2,3,1), new THREE.Vector3(3,0,1), new THREE.Vector3(3,1,1), new THREE.Vector3(3,2,1), new THREE.Vector3(3,3,1), new THREE.Vector3(0,0,2), new THREE.Vector3(0,1,2), new THREE.Vector3(0,2,2), new THREE.Vector3(0,3,2), new THREE.Vector3(1,0,2), // new THREE.Vector3(1,1,2), // new THREE.Vector3(1,2,2), new THREE.Vector3(1,3,2), new THREE.Vector3(2,0,2), // new THREE.Vector3(2,1,2), // new THREE.Vector3(2,2,2), new THREE.Vector3(2,3,2), new THREE.Vector3(3,0,2), new THREE.Vector3(3,1,2), new THREE.Vector3(3,2,2), new THREE.Vector3(3,3,2), new THREE.Vector3(0,0,3), new THREE.Vector3(0,1,3), new THREE.Vector3(0,2,3), new THREE.Vector3(0,3,3), new THREE.Vector3(1,0,3), new THREE.Vector3(1,1,3), new THREE.Vector3(1,2,3), new THREE.Vector3(1,3,3), new THREE.Vector3(2,0,3), new THREE.Vector3(2,1,3), new THREE.Vector3(2,2,3), new THREE.Vector3(2,3,3), new THREE.Vector3(3,0,3), new THREE.Vector3(3,1,3), new THREE.Vector3(3,2,3), new THREE.Vector3(3,3,3), ] } ]; var opacity=0.9; $.getJSON("../json/asdf/cubeCone4.json", function(json) { console.log(json); //todo move this to other document scale=1/0.1875; var shift=gridSize/2.0; buildList={ currentZIndex:0, maxZIndex:json.length, listZ:[], done:false, availablePickup:[], listToBuild:[] }; setup={}; setup.nodes=[]; setup.edges=[]; setup.viz={}; setup.viz.colorMaps=[YlGnBu,coolwarm, winter ,jet]; // todo multiply by 4 as smallest size in cubeCone is 0.25 // y is z and z is y // shift z by 1 cause sacrificial layer is 0 // shift x and y to not have negative values for(var i=0;i<json.length;i++){ //for each z layer bin buildList.listZ.push({ layerZ:json[i][0][0][0].origin[1]*scale+1, done:false, currentSizeIndex:0, maxSizeIndex:json[i].length, listSize:[] }); for(var j=0;j<json[i].length;j++){ //for each size bin buildList.listZ[i].listSize.push({ size:json[i][j][0][0].widths[0]*scale, layerZ:buildList.listZ[i].layerZ, done:false, currentSDFIndex:0, maxSDFIndex:json[i][j].length, listSDF:[] }); for(var k=0;k<json[i][j].length;k++){ //for each sdf bin (signed distance field) buildList.listZ[i].listSize[j].listSDF.push({ sdfRank:k, layerZ:buildList.listZ[i].layerZ, size:buildList.listZ[i].listSize[j].size, done:false, currentCubeIndex:0, maxCubeIndex:json[i][j][k].length, listCubes:[] }); for(var l=0;l<json[i][j][k].length;l++){ //for each cube add location (todo check if int) var stockBuilt=false; if(buildList.listZ[i].listSize[j].size==1){ stockBuilt=true; } buildList.listZ[i].listSize[j].listSDF[k].listCubes.push({ layerZ:buildList.listZ[i].layerZ, size:buildList.listZ[i].listSize[j].size, sdfRank:buildList.listZ[i].listSize[j].listSDF[k].sdfRank, done:false, stockBuilt:stockBuilt, stockAssigned:false, stockPickedUp:false, position:new THREE.Vector3( json[i][j][k][l].origin[0]*scale+shift, json[i][j][k][l].origin[2]*scale+shift, json[i][j][k][l].origin[1]*scale+1) }); var nomSize=buildList.listZ[i].listSize[j].size; var x=json[i][j][k][l].origin[0]*scale; var y=json[i][j][k][l].origin[1]*scale; var z=json[i][j][k][l].origin[2]*scale; // if(true){ if(json[i][j][k][l].origin[2]*scale+nomSize/2.0<0){ setup.nodes.push({ id:"["+nomSize+","+x+","+y+","+z+"]", position:{ x:x+nomSize/2.0, y:y+nomSize/2.0, z:z+nomSize/2.0 }, displacement:{ x:0, y:0, z:0 }, nomSize:nomSize, orgNomSize:nomSize, viz:opacity }); addEdge(setup,nomSize,nomSize,x,y,z,opacity); if(nomSize==2){ for(var ii=0;ii<voxelIndexList[2].list.length;ii++){ var nomSize1=1; var x1=x+voxelIndexList[2].list[ii].x; var y1=y+voxelIndexList[2].list[ii].y; var z1=z+voxelIndexList[2].list[ii].z; setup.nodes.push({ id:"["+nomSize1+","+x1+","+y1+","+z1+"]", position:{ x:x1+nomSize1/2.0, y:y1+nomSize1/2.0, z:z1+nomSize1/2.0 }, displacement:{ x:0, y:0, z:0 }, nomSize:nomSize1, orgNomSize:nomSize, viz:0.0 }); addEdge(setup,nomSize1,nomSize,x1,y1,z1,0); } } if(nomSize==4){ for(var ii=0;ii<voxelIndexList[4].list.length;ii++){ var nomSize1=1; var x1=x+voxelIndexList[4].list[ii].x; var y1=y+voxelIndexList[4].list[ii].y; var z1=z+voxelIndexList[4].list[ii].z; setup.nodes.push({ id:"["+nomSize1+","+x1+","+y1+","+z1+"]", position:{ x:x1+nomSize1/2.0, y:y1+nomSize1/2.0, z:z1+nomSize1/2.0 }, displacement:{ x:0, y:0, z:0 }, nomSize:nomSize1, orgNomSize:nomSize, viz:0.0 }); addEdge(setup,nomSize1,nomSize,x1,y1,z1,0); } } } } } } } // console.log(buildList); // console.log(nodes); scale=10.0; var stress=0.0; function getColor(stress){ // console.log(stress) var val=map(stress,setup.viz.minStress,setup.viz.maxStress,1.0,0.0); color=interpolateLinearly(val, setup.viz.colorMaps[setup.viz.colorMap]); return new THREE.Color(color[0],color[1],color[2]).getHex(); } const gData = { nodes: setup.nodes.map(node => ({ id: node.id, px:node.position.x*scale, py:node.position.y*scale, pz:node.position.z*scale, dx:node.displacement.x*scale, dy:node.displacement.y*scale, dz:node.displacement.z*scale, nomSize:node.nomSize, viz:node.viz, })), links: setup.edges .filter(edge => edge.id) .map(edge => ({ source: edge.source, target: edge.target, color:getColor(edge.stress) })) }; const Graph = ForceGraph3D().backgroundColor(color2) (document.getElementById('3d-graph')) .d3Force('center', null) .d3Force('charge', null) .linkWidth(1.0) .linkOpacity(1.0) .nodeThreeObject(({ nomSize,viz }) => new THREE.Mesh( new THREE.BoxGeometry(scale*nomSize*0.9, scale*nomSize*0.9, scale*nomSize*0.9), new THREE.MeshLambertMaterial({ color: color3, transparent: true, opacity: viz }) ) ) .d3Force('box', () => { gData.nodes.forEach(node => { node.fx=node.px; node.fy=node.py; node.fz=node.pz; }); }) .cooldownTime(Infinity) .graphData(gData); // var count=0; var totalCount=0; var increment=true; var speed=100; var exaggeration=10000.0; // setInterval(() => { // Graph.d3Force('box', () => { // gData.nodes.forEach(node => { // node.fx=node.px+count/speed*node.dx*exaggeration; // node.fy=node.py+count/speed*node.dy*exaggeration; // node.fz=node.pz+count/speed*node.dz*exaggeration; // }); // }); // if(count>speed){ // increment=false; // }else if (count<0){ // increment=true; // } // if(increment){ // count++; // }else{ // count--; // } // // totalCount++; // // console.log(totalCount); // }, 1); var helper = new THREE.GridHelper( scale*2, scale*2 ); helper.position.y = 0; helper.material.opacity = 0.5; helper.material.transparent = true; helper.scale.x=2.0*scale helper.scale.z=2.0*scale Graph.scene().add(helper); }); function drawConstraintBoundingBoxes(setup,scene,scale){ //grid helper var helper = new THREE.GridHelper( 100, 100 ); helper.position.y = -5.0*scale; helper.material.opacity = 0.5; helper.material.transparent = true; helper.scale.x=2.0*scale helper.scale.z=2.0*scale scene.add(helper); let supports=setup.supports; let loads=setup.loads; let mat=setup.materials; let disps=setup.fixedDisplacements; if (supports ) { for (var i=0;i< supports.length;i++) { let s=supports[i][0]; drawBox(s.min,s.max,color4,scene,scale); } } if (loads ) { for (var i=0;i< loads.length;i++) { let l=loads[i][0]; drawBox(l.min,l.max,color7,scene,scale); } } if (disps ) { for (var i=0;i< disps.length;i++) { let l=disps[i][0]; drawBox(l.min,l.max,color7,scene,scale); } } if (mat ) { for (var i=0;i< mat.length;i++) { let l=mat[i][0]; // console.log(l) drawBox(l.min,l.max,color5,scene,scale); } } }; function drawBox (min,max,color,scene,scale) { var box = new THREE.Box3(new THREE.Vector3(min.x*scale,min.y*scale,min.z*scale),new THREE.Vector3(max.x*scale,max.y*scale,max.z*scale)); var helper = new THREE.Box3Helper( box, color ); scene.add( helper ); // todo add name?? }; function getColor(viz,stress){ // console.log(stress) var val=map(stress,viz.minStress,viz.maxStress,1.0,0.0); color=interpolateLinearly(val, viz.colorMaps[viz.colorMap]); return new THREE.Color(color[0],color[1],color[2]).getHex(); } function addEdge(setup,nomSize,orgNomSize,x,y,z,viz){ var source="["+nomSize+","+x+","+y+","+z+"]"; for(var i=-1;i<2;i++){ for(var j=-1;j<2;j++){ for(var k=-1;k<2;k++){ if(((i==0&&j==0)||(i==0&&k==0)||(j==0&&k==0))){ //not same voxel and no diagonals if(!(i==0&&j==0&&k==0)){ var x1=x+i*nomSize; var y1=y+j*nomSize; var z1=z+k*nomSize; var target="["+nomSize+","+x1+","+y1+","+z1+"]"; var node=setup.nodes.find(v => v.id === target); if(node!==undefined){ if(!(viz==0&&node.viz==0)){ setup.edges.push({ id: 'e'+setup.edges.length, source: source, target: target ,stress:0 }); } if(orgNomSize!=node.orgNomSize){ setup.edges.push({ id: 'e'+setup.edges.length, source: source, target: target ,stress:0 }); } } } } } } } } </script> </body>