<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 $.getJSON("../json/tutorial/0.json", function(json0) { var maxNumFiles=json0.maxNumFiles-1; $.getJSON("../json/tutorial/"+maxNumFiles+".json", function(json) { var setup=json; var static=false setup.viz.colorMaps=[YlGnBu,coolwarm, winter ,jet]; scale=setup.scale*50.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, dxs:new Array(maxNumFiles).fill(0), dys:new Array(maxNumFiles).fill(0), dzs: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)), color:getColor(setup.viz,edge.stress) })) }; ////////////////////////////////////////////////////////////////////////// const Graph = ForceGraph3D().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) .linkOpacity(1.0) // .linkColor(color3) .nodeThreeObject(({ id }) => new THREE.Mesh( new THREE.BoxGeometry(scale/5.0, scale/5.0, scale/5.0) , new THREE.MeshLambertMaterial({ color: color3, transparent: true, opacity: 0.8 }) )) .d3Force('box', () => { gData.nodes.forEach(node => { node.fx=node.px; node.fy=node.py; node.fz=node.pz; }); }) .cooldownTime(Infinity) .graphData(gData); //////////////////////////////////// drawConstraintBoundingBoxes(json0,Graph.scene(),scale); /////////////////////////////////////// if(static){ var count=0; var totalCount=0; var increment=true; var speed=100; var exaggeration=1.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--; } }, 1); }else{ //dynamic for(let i=0;i<maxNumFiles;i++){ $.getJSON("../json/tutorial/"+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; } for(let j=0;j<setups.edges.length;j++){ gData.links[j].stresses[i]=getColor(setups.viz,setups.edges[j].stress); } }); } var count=0; var totalCount=0; var increment=true; var speed=7; var exaggeration=1.0; setInterval(() => { Graph.d3Force('box', () => { gData.nodes.forEach(node => { node.fx=node.px+node.dxs[count]*exaggeration; node.fy=node.py+node.dys[count]*exaggeration; node.fz=node.pz+node.dzs[count]*exaggeration; }); gData.links.forEach(edge => { edge.color=edge.stresses[count] }); }); count++; if(count>maxNumFiles){ count=0; } }, speed); } }); }); 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(); } </script> </body>