<head> <style> body { margin: 0; } </style> <title>MetaVoxel</title> <script src="../lib/dat.gui.js"></script> <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 scale,nodeScale; var interaction= { exaggeration:1, speed:100 } var gui = new dat.GUI(); gui.add(interaction,'exaggeration',0.0,10.0).listen(); gui.add(interaction,'speed',0.0,200.0).listen(); $.getJSON("../json/coupon/0.json", function(json0) { var maxNumFiles=json0.maxNumFiles-1; $.getJSON("../json/coupon/"+maxNumFiles+".json", function(json) { var setup=json; var static=false setup.viz.colorMaps=[YlGnBu,coolwarm, winter ,jet]; if(setup.hierarchical){ // scale=setup.scale*200; // nodeScale=scale/1500; scale=setup.scale*0.001; nodeScale=scale*4; }else{ scale=setup.scale*50; nodeScale=scale/2.0; } var stress=0.0; var 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, restrained:node.restrained_degrees_of_freedom[0], loaded:!(node.force.x==0.0&&node.force.y==0.0&&node.force.z==0.0), displaced:(node.fixedDisplacement===undefined ||(node.fixedDisplacement.x==0&&node.fixedDisplacement.y==0&&node.fixedDisplacement.z==0))?false:true, dxs:new Array(maxNumFiles).fill(0), dys:new Array(maxNumFiles).fill(0), dzs:new Array(maxNumFiles).fill(0), axs:new Array(maxNumFiles).fill(0), ays:new Array(maxNumFiles).fill(0), azs:new Array(maxNumFiles).fill(0), })), links: setup.edges .filter(edge => edge.id) .map(edge => ({ source: 'n'+edge.source, target: 'n'+edge.target, stresses:new Array(maxNumFiles).fill(getColor(setup.viz,edge.stress)), stressesVal:new Array(maxNumFiles).fill(edge.stress), color:getColor(setup.viz,edge.stress) })) }; // console.log(getColor(setup.viz,setup.edges[0].stress)) ////////////////////////////////////////////////////////////////////////// const Graph = ForceGraph3D({ controlType: 'orbit' }).backgroundColor(color2) (document.getElementById('3d-graph')) .d3Force('center', null) .d3Force('charge', null) // .linkDirectionalParticles(0.5) // .linkThreeObject(link => { // // extend link with text sprite // const sprite = new SpriteText(`${link.source} > ${link.target}`); // sprite.color = 'lightgrey'; // sprite.textHeight = 1.5; // return sprite; // }) // .linkPositionUpdate((sprite, { start, end }) => { // const middlePos = Object.assign(...['x', 'y', 'z'].map(c => ({ // [c]: start[c] + (end[c] - start[c]) / 2 // calc middle point // }))); // // Position sprite // Object.assign(sprite.position, middlePos); // }) .linkWidth(1.0*scale) .linkOpacity(1.0) // .linkColor(color3) .nodeThreeObject(({ restrained,loaded,displaced }) => new THREE.Mesh( new THREE.BoxGeometry(nodeScale, nodeScale, nodeScale) , new THREE.MeshLambertMaterial({ color: getNodeColor(restrained,loaded,displaced), transparent: false, opacity: 0.95 }) )) .d3Force('box', () => { gData.nodes.forEach(node => { node.fx=node.px; node.fy=node.py; node.fz=node.pz; }); }) .cooldownTime(Infinity) .graphData(gData); var position=new THREE.Vector3(500,100,3000); Graph.camera().position.copy( position ); // Graph.camera().lookAt( 500, orbit.target.y, orbit.target.z ); // Graph.camera().lookAt( 500, 0, 0 ); Graph.controls().target.set( 500, 100, 0 ); //////////////////////////////////// drawConstraintBoundingBoxes(json0,Graph.scene(),scale); /////////////////////////////////////// if(static){ var count=0; var totalCount=0; var increment=true; setInterval(() => { Graph.d3Force('box', () => { gData.nodes.forEach(node => { node.fx=node.px+count/interaction.speed*node.dx*interaction.exaggeration; node.fy=node.py+count/interaction.speed*node.dy*interaction.exaggeration; node.fz=node.pz+count/interaction.speed*node.dz*interaction.exaggeration; }); }); if(count>interaction.speed){ increment=false; }else if (count<0){ increment=true; } if(increment){ count++; }else{ count--; } }, 1); }else{ //dynamic for(let i=0;i<maxNumFiles;i++){ $.getJSON("../json/coupon/"+i+".json", function(jsons) { var setups=jsons; for(let j=0;j<setups.nodes.length;j++){ gData.nodes[j].dxs[i]=setups.nodes[j].displacement.x*scale; gData.nodes[j].dys[i]=setups.nodes[j].displacement.y*scale; gData.nodes[j].dzs[i]=setups.nodes[j].displacement.z*scale; gData.nodes[j].axs[i]=setups.nodes[j].angle.x; gData.nodes[j].ays[i]=setups.nodes[j].angle.y; gData.nodes[j].azs[i]=setups.nodes[j].angle.z; } for(let j=0;j<setups.edges.length;j++){ setups.viz.colorMaps=[YlGnBu,coolwarm, winter ,jet]; setups.viz.colorMap=0; // console.log(getColor(setups.viz,setups.edges[j].stress)) gData.links[j].stresses[i]=getColor(setups.viz,setups.edges[j].stress); gData.links[j].stressesVal[i]=setups.edges[j].stress; } }); } var count=0; var totalCount=0; var increment=true; setInterval(() => { Graph.d3Force('box', () => { gData.nodes.forEach(node => { node.fx=node.px+node.dxs[count]*interaction.exaggeration; node.fy=node.py+node.dys[count]*interaction.exaggeration; node.fz=node.pz+node.dzs[count]*interaction.exaggeration; }); }); // gData.links.forEach(edge => {edge.color=edge.stresses[count]}); // Graph.graphData(gData); Graph.nodeThreeObject(({ restrained,loaded,displaced,axs,ays,azs }) => getMesh(restrained,loaded,displaced,axs[count],ays[count],azs[count]) ); Graph.linkColor(({ stresses }) => stresses[count]); Graph.linkWidth(({ stressesVal }) => (stressesVal[count]==0.0)?(scale/10.0):scale) // Graph.linkOpacity(({ stresses }) => stresses[count]); // console.log() count++; if(count>maxNumFiles-1){ count=0; } // if(count>=maxNumFiles-1){ // increment=false; // }else if (count<=1){ // increment=true; // } // if(increment){ // count++; // }else{ // count--; // } }, interaction.speed); } }); }); function drawConstraintBoundingBoxes(setup,scene,scale){ //grid helper var helper = new THREE.GridHelper( 100, 100 ); helper.position.y = -setup.voxelSize/2.0*scale; // helper.position.y = -setup.voxelSize/2.0*scale +2*setup.voxelSize*scale; helper.material.opacity = 0.4; 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 getNodeColor(restrained,loaded,displaced){ if (restrained){ return 0xfa6e70; }else if(loaded){ return 0x03dbfc; }else if(displaced){ return 0x03dbfc; }else{ return color3; } } function getMesh(restrained,loaded,displaced,ax,ay,az){ var m=new THREE.Mesh( new THREE.BoxGeometry(nodeScale, nodeScale, nodeScale), new THREE.MeshLambertMaterial({ color: getNodeColor(restrained,loaded,displaced), transparent: false, opacity: 0.8 }) ); m.rotation.x=ax; m.rotation.y=ay; m.rotation.z=az; return m; } </script> </body>