Select Git revision
indexMultiscaleDynamic.html 13.44 KiB
<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();
var fileName="multiscale";
var fileName="tutorial";
$.getJSON("../json/"+fileName+"/0.json", function(json0) {
var maxNumFiles=json0.maxNumFiles-1;
$.getJSON("../json/"+fileName+"/"+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*10;
}else{
scale=setup.scale*50;
nodeScale=scale*2.0;
}
if (setup.multiscale===undefined){
scale=setup.scale*0.003
;
nodeScale=scale*10
}
var stress=0.0;
var gData =
{
nodes: setup.nodes.map(node => ({
// id: node.id,
id: (node.parent=="11")?node.id:(node.parent+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),
size:(node.material===undefined) ? nodeScale:(( setup.multiscale===undefined || !setup.multiscale)?(nodeScale*0.8):(node.scale*nodeScale*0.8**(1/node.scale))),
opacity: (node.parent=="11"|| setup.multiscale===undefined ||node.parent=="")?0.0:0.8,
})),
links: setup.edges
.filter(edge => edge.id)
.map(edge => ({
// source: 'n'+edge.source,
// target: 'n'+edge.target,
source: (setup.multiscale===undefined || !setup.multiscale ||edge.sourceNodalCoordinate==0)?'n'+edge.source:('n'+edge.source+'n'+edge.sourceNodalCoordinate),
target: (setup.multiscale===undefined || !setup.multiscale ||edge.targetNodalCoordinate==0)?'n'+edge.target:('n'+edge.target+'n'+edge.targetNodalCoordinate),
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(({ size,restrained,loaded,displaced,opacity }) => new THREE.Mesh(
new THREE.BoxGeometry(size, size, size)
,
new THREE.MeshLambertMaterial({
color: getNodeColor(restrained,loaded,displaced),
transparent: opacity>0.0?false:true,
opacity: opacity
})
))
.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/"+fileName+"/"+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(({ size,restrained,loaded,displaced,axs,ays,azs,opacity }) => getMesh(size,restrained,loaded,displaced,axs[count],ays[count],azs[count],opacity) );
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;
if (setup.hierarchical){
helper.position.y=setup.voxelSize*scale*(1.2 -0.1)
}
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(size,restrained,loaded,displaced,ax,ay,az,opacity){
var m=new THREE.Mesh(
new THREE.BoxGeometry(size, size, size),
new THREE.MeshLambertMaterial({
color: getNodeColor(restrained,loaded,displaced),
transparent: opacity>0.0?false:true,
opacity: opacity
})
);
m.rotation.x=ax;
m.rotation.y=ay;
m.rotation.z=az;
return m;
}
</script>
</body>