const { isRegExp } = require("util"); // Amira Abdel-Rahman // (c) Massachusetts Institute of Technology 2020 var solveFea; var _rhino3dm = null; var occupancy=[]; var gridSize=10; // initialize function latticeSetup(setup,latticeSize,voxelSize,voxelBuilder,forces,material) {//later change type to dictiary // console.log(_rhino3dm); // var voxelSize=10.0; // var latticeSize=5; // const material={ // area:1.0, // density:0.028, // stiffness:1000000 // }; createLattice(setup,voxelSize,latticeSize,latticeSize,latticeSize,voxelBuilder,material); //todo fix this if(setup.hierarchical){ addForceAbove(setup,0.75*voxelSize*latticeSize,forces); restrainBelow(setup,voxelSize*0.75); }else{ addForceAbove(setup,0.8*voxelSize*latticeSize,forces); restrainBelow(setup,-voxelSize/2); } } /// function lateralLoadSetup(setup,position,length,voxelSize,voxelBuilder,supports,loads,material) { createLattice(setup,voxelSize,1,1,length,voxelBuilder,material,position); //todo incorporate this into the drawing phase so you don't have to loop twice restrainFromBox(setup,supports); loadFromBox(setup,loads); } function lateralLoadSetup1(setup,position,length,voxelSize,voxelBuilder,supports,loads,material) { createLattice(setup,voxelSize,1,length,1,voxelBuilder,material,position); //todo incorporate this into the drawing phase so you don't have to loop twice restrainFromBox(setup,supports); loadFromBox(setup,loads); } //////////////////////////////////////////////////////////// function createLattice(setup,size,sizeX,sizeY,sizeZ,voxelBuilder,material,position=new THREE.Vector3(0,0,0)){ for (var i=0;i<gridSize;++i){ occupancy.push([]); for (var j=0;j<gridSize;++j){ occupancy[i].push([]); for (var k=0;k<gridSize;++k){ occupancy[i][j].push(-1); } } } var count=0; for(var i=0;i<sizeX;i++){ for(var j=0;j<sizeY;j++){ for(var k=0;k<sizeZ;k++){ // if(i>sizeX/3){ // stiffness=100000; // } voxelBuilder(setup,size,new THREE.Vector3(i*size+position.x,j*size+position.y,k*size+position.z),material); } } } } function createLatticeFromFrep(setup,size,frep,voxelBuilder,material,position=new THREE.Vector3(0,0,0)){ for (var i=0;i<gridSize;++i){ occupancy.push([]); for (var j=0;j<gridSize;++j){ occupancy[i].push([]); for (var k=0;k<gridSize;++k){ occupancy[i][j].push(-1); } } } for(var i=0;i<gridSize;i++){ for(var j=0;j<gridSize;j++){ for(var k=0;k<gridSize;k++){ if(frep(i,j,k)>0){ voxelBuilder(setup,size,new THREE.Vector3(i*size+position.x,j*size+position.y,k*size+position.z),material); } } } } } function createGeometryFromRhino(setup,fileName,layerIndex,voxelSize,sizeX,sizeY,sizeZ,material){ let rhinoFile= fs.readFileSync(fileName); let doc = _rhino3dm.File3dm.fromByteArray(rhinoFile); let objects = doc.objects(); let counter=0; function useLayer(layer,layerIndex,useMaterialList){ if(useMaterialList){ if(layerIndex.some(elem => elem == layer)){ const isLayer = (element) => element == layer; // console.log("materialIdex1 "+(parseInt(layerIndex.findIndex(isLayer))+2.0)) // console.log((parseInt(layerIndex.findIndex(isLayer))+2.0)) return (parseInt(layerIndex.findIndex(isLayer))+2.0); }else{ return false; } }else{ return layer==layerIndex; } } for (let ii = 0; ii < objects.count; ii++) { let object = objects.get(ii).geometry(); let layer=objects.get(ii).attributes().layerIndex; let materialIndex=useLayer(layer,layerIndex,setup.useMaterialList); //0 if doesn't exists, 1 if exists but not material list, >1 if exists and use material list // console.log("materialIndex "+materialIndex) if((object instanceof _rhino3dm.LineCurve ||object instanceof _rhino3dm.NurbsCurve ||object instanceof _rhino3dm.PolylineCurve )&& materialIndex>0 ) { //only get lines no nurbs curves // console.log("yes!") for(var i=0;i<sizeX;i++){ for(var j=0;j<sizeY;j++){ for(var k=0;k<sizeZ;k++){ var pos= new THREE.Vector3(i*voxelSize,j*voxelSize,k*voxelSize); var pos1=new THREE.Vector3(object.pointAtStart[0]+pos.x,object.pointAtStart[2]+pos.y,object.pointAtStart[1]+pos.z); var pos2=new THREE.Vector3( object.pointAtEnd[0]+pos.x, object.pointAtEnd[2]+pos.y, object.pointAtEnd[1]+pos.z); var source = checkandAdd(setup,pos1,material); var target = checkandAdd(setup,pos2,material); if(materialIndex==1){ addEdge(setup,source,target,material); }else{ addEdge(setup,source,target,setup.materialList[materialIndex-2]); } } } } }else if(layer==layerIndex){ console.log("Warning: unknown object imported from Rhino on layer:"+object) } } setup.materialList=[];//don't need it anymore } function createVoxel(setup,size,position,material){ // var sphere = new _rhino3dm.Sphere([0,0,0], size/2); // var box = sphere.toBrep().getBoundingBox(); var box=new _rhino3dm.BoundingBox([0,0,0], [size,size,size]); // console.log(box.min) box = box.toBrep(); // position.x-=size/2; // position.y-=size/2; // position.z-=size/2; for(var i=0; i<6;i++){//for each face // var restrained=false; // var force=new THREE.Vector3(0,0,0); // if(i==0){ // restrained=true; // } // if(i==2){ // force=new THREE.Vector3(0,-200,0); // // restrained=true; // } nodesIndices=[]; var face=box.faces().get(i); nodesIndices.push(checkandAdd(setup,add(position,toPosition(face.pointAt(size , size/2))),material) ); nodesIndices.push(checkandAdd(setup,add(position,toPosition(face.pointAt(size/2, 0 ))),material) ); nodesIndices.push(checkandAdd(setup,add(position,toPosition(face.pointAt(0 , size/2))),material) ); nodesIndices.push(checkandAdd(setup,add(position,toPosition(face.pointAt(size/2, size ))),material) ); linkNodes(setup,nodesIndices,material); } } function createChiralVoxel(setup,size,position,material){ // var sphere = new _rhino3dm.Sphere([0,0,0], size/2); // var box = sphere.toBrep().getBoundingBox(); // console.log(box.min) var box=new _rhino3dm.BoundingBox([0,0,0], [size,size,size]); box = box.toBrep(); position.x-=size/2; position.y-=size/2; position.z-=size/2; for(var i=0; i<6;i++){//for each face var nodesIndices=[]; var face=box.faces().get(i); nodesIndices.push(checkandAdd(setup,add(position,toPosition(face.pointAt(size , size/2))),material)); nodesIndices.push(checkandAdd(setup,add(position,toPosition(face.pointAt(size/2, 0 ))),material)); nodesIndices.push(checkandAdd(setup,add(position,toPosition(face.pointAt(0 , size/2))),material)); nodesIndices.push(checkandAdd(setup,add(position,toPosition(face.pointAt(size/2, size ))),material)); // linkNodes(nodesIndices); var n=8; var c= new _rhino3dm.Circle(size/3.5); c=c.toNurbsCurve(); var rot=[1,0,0]; var nodesIndices1=[]; c.domain=[0,1]; // console.log(rot); // console.log(c.tangentAt(i*1/4+1/4)); rot=c.tangentAt(i*1/4+1/4); if(i>3){ rot=face.normalAt(0, 0); } c.rotate(Math.PI/2,rot , [0,0,0]); c.translate(face.pointAt(size/2, size/2)); for(var ii=0; ii<n;ii++){//for each face // createNode(toPosition(c.pointAt(ii*1/n)),'e',false,[]); nodesIndices1.push(checkandAdd(setup,add(position,toPosition(c.pointAt(ii*1/n))),material)); } linkNodes(setup,nodesIndices1,material); if(i==0){ addEdge(setup,nodesIndices[0], nodesIndices1[1] ,material); addEdge(setup,nodesIndices[1], nodesIndices1[3] ,material); addEdge(setup,nodesIndices[2], nodesIndices1[5] ,material); addEdge(setup,nodesIndices[3], nodesIndices1[7] ,material); }else if(i==1){ addEdge(setup,nodesIndices[3], nodesIndices1[1],material); addEdge(setup,nodesIndices[0], nodesIndices1[3],material); addEdge(setup,nodesIndices[1], nodesIndices1[5],material); addEdge(setup,nodesIndices[2], nodesIndices1[7],material); }else if(i==2){ addEdge(setup,nodesIndices[0], nodesIndices1[5],material); addEdge(setup,nodesIndices[1], nodesIndices1[7],material); addEdge(setup,nodesIndices[2], nodesIndices1[1],material); addEdge(setup,nodesIndices[3], nodesIndices1[3],material); // var force=new THREE.Vector3(0,-400,0); // addForce(setup,'n'+nodesIndices[0],force); // addForce(setup,'n'+nodesIndices[1],force); // addForce(setup,'n'+nodesIndices[2],force); // addForce(setup,'n'+nodesIndices[3],force); }else if(i==3){ addEdge(setup,nodesIndices[3], nodesIndices1[5],material); addEdge(setup,nodesIndices[0], nodesIndices1[7],material); addEdge(setup,nodesIndices[1], nodesIndices1[1],material); addEdge(setup,nodesIndices[2], nodesIndices1[3],material); }else if(i==4){ addEdge(setup,nodesIndices[0], nodesIndices1[5],material); addEdge(setup,nodesIndices[1], nodesIndices1[7],material); addEdge(setup,nodesIndices[2], nodesIndices1[1],material); addEdge(setup,nodesIndices[3], nodesIndices1[3],material); }else if(i==5){ addEdge(setup,nodesIndices[0], nodesIndices1[5],material); addEdge(setup,nodesIndices[1], nodesIndices1[3],material); addEdge(setup,nodesIndices[2], nodesIndices1[1],material); addEdge(setup,nodesIndices[3], nodesIndices1[7],material); } } } ///////////////// function createOldVoxelnotRhino(setup,size,position){ addNode(setup,position.clone().add(new THREE.Vector3(0,0,0)),true, new THREE.Vector3(0,0,0)); addNode(setup,position.clone().add(new THREE.Vector3(-size, size*1.5,-size)),false, new THREE.Vector3(0,-200,0)); addNode(setup,position.clone().add(new THREE.Vector3(-size, size*1.5, size)),false, new THREE.Vector3(0,-200,0)); addNode(setup,position.clone().add(new THREE.Vector3( size, size*1.5, size)),false, new THREE.Vector3(0,-200,0)); addNode(setup,position.clone().add(new THREE.Vector3( size, size*1.5,-size)),false, new THREE.Vector3(0,-200,0)); addNode(setup,position.clone().add(new THREE.Vector3(0, size*1.5*2,0)),false, new THREE.Vector3(0,-400,0)); addEdge(setup,0, 1, 1.0, 0.284 , 30.0e6); addEdge(setup,0, 2, 1.0, 0.284 , 30.0e6); addEdge(setup,0, 3, 1.0, 0.284 , 30.0e6); addEdge(setup,0, 4, 1.0, 0.284 , 30.0e6); addEdge(setup,1, 2, 1.0, 0.284 , 30.0e6); addEdge(setup,2, 3, 1.0, 0.284 , 30.0e6); addEdge(setup,3, 4, 1.0, 0.284 , 30.0e6); addEdge(setup,4, 1, 1.0, 0.284 , 30.0e6); addEdge(setup,5, 1, 1.0, 0.284 , 30.0e6); addEdge(setup,5, 2, 1.0, 0.284 , 30.0e6); addEdge(setup,5, 3, 1.0, 0.284 , 30.0e6); addEdge(setup,5, 4, 1.0, 0.284 , 30.0e6); // console.log(setup) } function createVoxelnotRhino(setup,size,position){ //down square addNode(setup,position.clone().add(new THREE.Vector3(-size, 0,-size)),true, new THREE.Vector3(0,0,0));//0 addNode(setup,position.clone().add(new THREE.Vector3(-size, 0, 0)),true, new THREE.Vector3(0,0,0));//1//mid addNode(setup,position.clone().add(new THREE.Vector3(-size, 0, size)),true, new THREE.Vector3(0,0,0));//2 addNode(setup,position.clone().add(new THREE.Vector3( 0, 0, size)),true, new THREE.Vector3(0,0,0));//3//mid addNode(setup,position.clone().add(new THREE.Vector3( size, 0, size)),true, new THREE.Vector3(0,0,0));//4 addNode(setup,position.clone().add(new THREE.Vector3( size, 0, 0)),true, new THREE.Vector3(0,0,0));//5//mid addNode(setup,position.clone().add(new THREE.Vector3( size, 0,-size)),true, new THREE.Vector3(0,0,0));//6 addNode(setup,position.clone().add(new THREE.Vector3( 0, 0,-size)),true, new THREE.Vector3(0,0,0));//7//mid addEdge(setup,0, 1, 1.0, 0.284 , 30.0e6); addEdge(setup,1, 2, 1.0, 0.284 , 30.0e6); addEdge(setup,2, 3, 1.0, 0.284 , 30.0e6); addEdge(setup,3, 4, 1.0, 0.284 , 30.0e6); addEdge(setup,4, 5, 1.0, 0.284 , 30.0e6); addEdge(setup,5, 6, 1.0, 0.284 , 30.0e6); addEdge(setup,6, 7, 1.0, 0.284 , 30.0e6); addEdge(setup,7, 0, 1.0, 0.284 , 30.0e6); addEdge(setup,1, 3, 1.0, 0.284 , 30.0e6); addEdge(setup,3, 5, 1.0, 0.284 , 30.0e6); addEdge(setup,5, 7, 1.0, 0.284 , 30.0e6); addEdge(setup,7, 1, 1.0, 0.284 , 30.0e6); //up square addNode(setup,position.clone().add(new THREE.Vector3(-size, size*2,-size)),false, new THREE.Vector3(0,-400,0));//0+8 addNode(setup,position.clone().add(new THREE.Vector3(-size, size*2, 0)),false, new THREE.Vector3(0,-400,0));//1+8//mid addNode(setup,position.clone().add(new THREE.Vector3(-size, size*2, size)),false, new THREE.Vector3(0,-400,0));//2+8 addNode(setup,position.clone().add(new THREE.Vector3( 0, size*2, size)),false, new THREE.Vector3(0,-400,0));//3+8//mid addNode(setup,position.clone().add(new THREE.Vector3( size, size*2, size)),false, new THREE.Vector3(0,-400,0));//4+8 addNode(setup,position.clone().add(new THREE.Vector3( size, size*2, 0)),false, new THREE.Vector3(0,-400,0));//5+8//mid addNode(setup,position.clone().add(new THREE.Vector3( size, size*2,-size)),false, new THREE.Vector3(0,-400,0));//6+8 addNode(setup,position.clone().add(new THREE.Vector3( 0, size*2,-size)),false, new THREE.Vector3(0,-400,0));//7+8//mid addEdge(setup,0+8, 1+8, 1.0, 0.284 , 30.0e6); addEdge(setup,1+8, 2+8, 1.0, 0.284 , 30.0e6); addEdge(setup,2+8, 3+8, 1.0, 0.284 , 30.0e6); addEdge(setup,3+8, 4+8, 1.0, 0.284 , 30.0e6); addEdge(setup,4+8, 5+8, 1.0, 0.284 , 30.0e6); addEdge(setup,5+8, 6+8, 1.0, 0.284 , 30.0e6); addEdge(setup,6+8, 7+8, 1.0, 0.284 , 30.0e6); addEdge(setup,7+8, 0+8, 1.0, 0.284 , 30.0e6); addEdge(setup,1+8, 3+8, 1.0, 0.284 , 30.0e6); addEdge(setup,3+8, 5+8, 1.0, 0.284 , 30.0e6); addEdge(setup,5+8, 7+8, 1.0, 0.284 , 30.0e6); addEdge(setup,7+8, 1+8, 1.0, 0.284 , 30.0e6); //left square addNode(setup,position.clone().add(new THREE.Vector3(-size, size,-size)),false, new THREE.Vector3(0,0,0));//0+16 addNode(setup,position.clone().add(new THREE.Vector3( size, size,-size)),false, new THREE.Vector3(0,0,0));//1+16 addEdge(setup,0, 16, 1.0, 0.284 , 30.0e6); addEdge(setup,16, 8, 1.0, 0.284 , 30.0e6); addEdge(setup,6, 17, 1.0, 0.284 , 30.0e6); addEdge(setup,17, 14, 1.0, 0.284 , 30.0e6); addEdge(setup,16, 7, 1.0, 0.284 , 30.0e6); addEdge(setup,15, 16, 1.0, 0.284 , 30.0e6); addEdge(setup,17, 15, 1.0, 0.284 , 30.0e6); addEdge(setup, 7, 17, 1.0, 0.284 , 30.0e6); //right square addNode(setup,position.clone().add(new THREE.Vector3(-size, size, size)),false, new THREE.Vector3(0,0,0));//0+18 addNode(setup,position.clone().add(new THREE.Vector3( size, size, size)),false, new THREE.Vector3(0,0,0));//1+18 addEdge(setup,2, 18, 1.0, 0.284 , 30.0e6); addEdge(setup,18, 10, 1.0, 0.284 , 30.0e6); addEdge(setup,4, 19, 1.0, 0.284 , 30.0e6); addEdge(setup,19, 12, 1.0, 0.284 , 30.0e6); addEdge(setup,18, 3, 1.0, 0.284 , 30.0e6); addEdge(setup,11, 18, 1.0, 0.284 , 30.0e6); addEdge(setup,19, 11, 1.0, 0.284 , 30.0e6); addEdge(setup, 3, 19, 1.0, 0.284 , 30.0e6); //front square addEdge(setup,16, 1, 1.0, 0.284 , 30.0e6); addEdge(setup, 9, 16, 1.0, 0.284 , 30.0e6); addEdge(setup,18, 9, 1.0, 0.284 , 30.0e6); addEdge(setup, 1, 18, 1.0, 0.284 , 30.0e6); //back square addEdge(setup,17, 5, 1.0, 0.284 , 30.0e6); addEdge(setup,13, 17, 1.0, 0.284 , 30.0e6); addEdge(setup,19, 13, 1.0, 0.284 , 30.0e6); addEdge(setup, 5, 19, 1.0, 0.284 , 30.0e6); } function createSimpleSetupnotRhino(setup,size,position){ addNode(setup,position.clone().add(new THREE.Vector3(-0, 2*size,-0)),true, new THREE.Vector3(0,0,0));//0 addNode(setup,position.clone().add(new THREE.Vector3(-0, 0,-0)),true, new THREE.Vector3(0,0,0));//0 addNode(setup,position.clone().add(new THREE.Vector3(2*size, size,)),false, new THREE.Vector3(0,-200,0));//0 addEdge(setup,0, 2, 1.0, 0.284 , 30.0e6); addEdge(setup,1, 2, 2.0, 0.284 , 30.0e6); } /////////////hierarchical nodes/// function createHierarchalVoxel(setup,size,position,material,shift=false,parent="11"){ var i,j,k; if (shift){ i=parseInt((position.x)/size); j=parseInt((position.y)/size); k=parseInt((position.z)/size); // console.log(" i:"+i+" j:"+j+" k:"+k); position.x+=size/2; position.y+=size/2; position.z+=size/2; position.x-=size*gridSize/2.0 position.y-=size*gridSize/2.0 position.z-=size*gridSize/2.0 }else{ i=parseInt(position.x/size); j=parseInt(position.y/size); k=parseInt(position.z/size); position.x+=size/2; position.y+=size/2; position.z+=size/2; } var nodeScale=1 if(typeof setup.multiscale === 'undefined'|| !setup.multiscale){ //not multiscale parent='11'; nodeScale=1; occupancy[i][j][k]=checkandAdd(setup,position,material,parent,nodeScale); //create node at size +position var list=[]; list.push([0,0,1]); list.push([0,0,-1]); list.push([1,0,0]); list.push([-1,0,0]); list.push([0,1,0]); list.push([0,-1,0]); var count=0; for(var count=0;count<list.length;count++){ var ii=i+list[count][0]; var jj=j+list[count][1]; var kk=k+list[count][2]; if((ii>=0 && ii<gridSize) && (jj>=0 && jj<gridSize) && (kk>=0 && kk<gridSize)){//in bounds //check neighbours if(occupancy[ii][jj][kk]>-0.5){ addEdge(setup,occupancy[i][j][k], occupancy[ii][jj][kk], material); } } } }else{ nodeScale=material.scale; material.scale=""; parent=''; if(nodeScale==1){ occupancy[i][j][k]=checkandAdd(setup,position,material,parent,nodeScale); var list=[]; list.push([0,0,1]); list.push([0,0,-1]); list.push([1,0,0]); list.push([-1,0,0]); list.push([0,1,0]); list.push([0,-1,0]); var count=0; for(var count=0;count<list.length;count++){ var ii=i+list[count][0]; var jj=j+list[count][1]; var kk=k+list[count][2]; if((ii>=0 && ii<gridSize) && (jj>=0 && jj<gridSize) && (kk>=0 && kk<gridSize)){//in bounds //check neighbours if(occupancy[ii][jj][kk]>-0.5){ var sourceNodalCoordinate=0; var targetNodalCoordinate=0; if (parent==''){ sourceNodalCoordinate=0 } if (setup.nodes[occupancy[ii][jj][kk]].parent==''){ targetNodalCoordinate=0; addEdge(setup,occupancy[i][j][k], occupancy[ii][jj][kk], material, sourceNodalCoordinate,targetNodalCoordinate ); }else{ //get parent index var parentIndex=parseInt(setup.nodes[occupancy[ii][jj][kk]].parent.substring(1)); //get targetNodalCoordinate targetNodalCoordinate=getNodalCoordinateOrder(setup.nodes[parentIndex].position,setup.nodes[occupancy[ii][jj][kk]].position); addEdge(setup,occupancy[i][j][k], parentIndex, material, sourceNodalCoordinate,targetNodalCoordinate ); } } } } }else if (nodeScale==2){ // position.x+=size/2;position.y+=size/2;position.z+=size/2; var parentId=checkandAdd(setup,position,material,"",2); //add main node //add children occupancy[i+0][j+0][k+0]=addVirtualNode(setup,new THREE.Vector3(position.x-size/2.0,position.y-size/2.0,position.z-size/2.0),material,parentId,1,"n1"); occupancy[i+0][j+0][k+1]=addVirtualNode(setup,new THREE.Vector3(position.x-size/2.0,position.y-size/2.0,position.z+size/2.0),material,parentId,1,"n2"); occupancy[i+0][j+1][k+0]=addVirtualNode(setup,new THREE.Vector3(position.x-size/2.0,position.y+size/2.0,position.z-size/2.0),material,parentId,1,"n3"); occupancy[i+0][j+1][k+1]=addVirtualNode(setup,new THREE.Vector3(position.x-size/2.0,position.y+size/2.0,position.z+size/2.0),material,parentId,1,"n4"); occupancy[i+1][j+0][k+0]=addVirtualNode(setup,new THREE.Vector3(position.x+size/2.0,position.y-size/2.0,position.z-size/2.0),material,parentId,1,"n5"); occupancy[i+1][j+0][k+1]=addVirtualNode(setup,new THREE.Vector3(position.x+size/2.0,position.y-size/2.0,position.z+size/2.0),material,parentId,1,"n6"); occupancy[i+1][j+1][k+0]=addVirtualNode(setup,new THREE.Vector3(position.x+size/2.0,position.y+size/2.0,position.z-size/2.0),material,parentId,1,"n7"); occupancy[i+1][j+1][k+1]=addVirtualNode(setup,new THREE.Vector3(position.x+size/2.0,position.y+size/2.0,position.z+size/2.0),material,parentId,1,"n8"); //add children var list=[]; list.push([[-1,0,0],1]); list.push([[0,-1,0],1]); list.push([[0,0,-1],1]); list.push([[-1,0,1],2]); list.push([[0,-1,1],2]); list.push([[0,0,2] ,2]); list.push([[-1,1,0],3]); list.push([[0,2,0] ,3]); list.push([[0,1,-1],3]); list.push([[-1,1,1],4]); list.push([[0,2,1] ,4]); list.push([[0,1,2] ,4]); list.push([[2,0,0] ,5]); list.push([[1,-1,0],5]); list.push([[1,0,-1],5]); list.push([[2,0,1] ,6]); list.push([[1,-1,1],6]); list.push([[1,0,2] ,6]); list.push([[2,1,0] ,7]); list.push([[1,2,0] ,7]); list.push([[1,1,-1],7]); list.push([[2,1,1],8]); list.push([[1,2,1],8]); list.push([[1,1,2],8]); var count=0; for(var count=0;count<list.length;count++){ var ii=i+list[count][0][0]; var jj=j+list[count][0][1]; var kk=k+list[count][0][2]; if((ii>=0 && ii<gridSize) && (jj>=0 && jj<gridSize) && (kk>=0 && kk<gridSize)){//in bounds //check neighbours if(occupancy[ii][jj][kk]>-0.5){ var sourceNodalCoordinate=0; var targetNodalCoordinate=0; if (setup.nodes[occupancy[ii][jj][kk]].scale==1){ sourceNodalCoordinate=list[count][1]; targetNodalCoordinate=0; addEdge(setup,parentId, occupancy[ii][jj][kk], material, sourceNodalCoordinate,targetNodalCoordinate ); }else if (setup.nodes[occupancy[ii][jj][kk]].scale==2){ sourceNodalCoordinate=0; targetNodalCoordinate=0; addEdge(setup,parentId, occupancy[ii][jj][kk], material, sourceNodalCoordinate,targetNodalCoordinate ); } // if (setup.nodes[occupancy[ii][jj][kk]].parent==''){ // sourceNodalCoordinate=list[count][1]; // targetNodalCoordinate=0; // // addEdge(setup,parentId, occupancy[ii][jj][kk], material, sourceNodalCoordinate,targetNodalCoordinate ); // }else{ //join 2 scale 2 nodes // //get parent index // var parentIndex=parseInt(setup.nodes[occupancy[ii][jj][kk]].parent.substring(1)); // //get targetNodalCoordinate // targetNodalCoordinate=0; // // addEdge(setup,parentId, parentIndex, material, sourceNodalCoordinate,targetNodalCoordinate ); // } } } } } } } /////////////////////drawing utils////////////////////// function addNode(setup,position,restrained,force,material,parent='11',scale=1){ var bar=setup.bar; var numNode=setup.nodes.length; setup.nodes.push({ id: 'n'+numNode, parent: parent, degrees_of_freedom:[numNode*3,numNode*3+1,numNode*3+2] , restrained_degrees_of_freedom:[restrained,restrained,restrained], position: toPos(position), force:toPos(force), displacement: { x: 0, y: 0,z:0 }, fixedDisplacement: { x: 0, y: 0,z:0 }, angle: { x: 0, y: 0,z:0 }, material: material, nomSize:1.0 }); if(parent!='11'){ setup.nodes[numNode].multiscale=true; setup.nodes[numNode].scale=scale; } setup.nodes[numNode].id='n'+numNode; setup.nodes[numNode].position=toPos(position); setup.nodes[numNode].force=toPos(force); setup.nodes[numNode].degrees_of_freedom=[numNode*3,numNode*3+1,numNode*3+2]; setup.nodes[numNode].restrained_degrees_of_freedom=[restrained,restrained,restrained]; setup.ndofs = 3 * setup.nodes.length; if(!bar){ setup.nodes[numNode].degrees_of_freedom=[numNode*6,numNode*6+1,numNode*6+2,numNode*6+3,numNode*6+4,numNode*6+5]; if(restrained){ restrained=[true,true,true,true,true,true]; }else{ restrained=[false,false,false,true,true,true]; } setup.nodes[numNode].restrained_degrees_of_freedom=restrained; setup.ndofs = 6 * setup.nodes.length; } } function addVirtualNode(setup,position,material,parent='11',scale=1,id=""){ var restrained=false; var force= new THREE.Vector3(0,0,0); setup.virtualNodes.push({ id: id, scale:scale, multiscale:true, parent: 'n'+parent, degrees_of_freedom:[] , restrained_degrees_of_freedom:restrained?[true,true,true,true,true,true]:[false,false,false,true,true,true], position: toPos(position), force:toPos(force), displacement: { x: 0, y: 0,z:0 }, fixedDisplacement: { x: 0, y: 0,z:0 }, angle: { x: 0, y: 0,z:0 }, material: material, nomSize:1.0 }); return parent; } function addEdge(setup,source,target,material,sourceNodalCoordinate=0,targetNodalCoordinate=0){ var area=material.area; var density=material.density; var stiffness=material.stiffness; var poissonRatio=material.poissonRatio; if (edgeNeeded(setup,source,target)){ var numEdge=setup.edges.length; if(typeof material.cTE !== 'undefined'){ var cTE=material.cTE; setup.edges.push({ id: 'e'+numEdge, source: source, target: target ,material:material,stress:0, sourceNodalCoordinate:sourceNodalCoordinate,targetNodalCoordinate:targetNodalCoordinate }); }else{ setup.edges.push({ id: 'e'+numEdge, source: source, target: target ,material:material,stress:0, sourceNodalCoordinate:sourceNodalCoordinate,targetNodalCoordinate:targetNodalCoordinate }); } if(typeof setup.multiscale !== 'undefined' && setup.multiscale){ setup.edges[numEdge].multiscale=true; } // setup.edges[numEdge].id='e'+numEdge; // setup.edges[numEdge].source=source; // setup.edges[numEdge].target=target; // setup.edges[numEdge].area=area; // setup.edges[numEdge].density=density; // setup.edges[numEdge].stiffness=stiffness; } } function checkandAdd(setup,pos,material,parent='11',scale=1){ var restrained=false; var force= new THREE.Vector3(0,0,0); var node=nodeAt(setup,pos); if(typeof node === 'undefined'){ //doesn't exist addNode(setup,toThreeVec(pos),restrained, force,material,parent,scale); return parseInt(setup.nodes[setup.nodes.length-1].id.substring(1)); }else{ // setup.nodes.find(v => v.name === node.name).enabled = false; // if(restrained){ // restrain(setup,node.id) // } // addForce(setup,node.id,force); return parseInt(node.id.substring(1));//return name } } function linkNodes(setup,nodesIndices,material){ //create square/circle for(var i=0;i<nodesIndices.length-1;i++){ addEdge(setup,nodesIndices[i], nodesIndices[i+1], material); } addEdge(setup,nodesIndices[nodesIndices.length-1], nodesIndices[0], material); } function getRelativePosition(index,size){ // todo check if more efficient to encode it if (index==0){ return new THREE.Vector3(0,0,0) }else if (index==1){ return new THREE.Vector3(-size,-size,-size); }else if (index==2){ return new THREE.Vector3(-size, -size,size); }else if (index==3){ return new THREE.Vector3(-size, size, -size); }else if (index==4){ return new THREE.Vector3(-size, size, size); }else if (index==5){ return new THREE.Vector3( size,-size,-size); }else if (index==6){ return new THREE.Vector3( size, -size,size); }else if (index==7){ return new THREE.Vector3( size, size, -size); }else if (index==8){ return new THREE.Vector3( size, size, size); } return new THREE.Vector3(0,0,0); } function getNodalCoordinateOrder(parentPos,childPos){ // todo check if more efficient to encode it if (childPos.x==parentPos.x && childPos.y==parentPos.y && childPos.z==parentPos.z){ return 0; }else if (childPos.x<parentPos.x && childPos.y<parentPos.y && childPos.z<parentPos.z){ return 1; }else if (childPos.x<parentPos.x && childPos.y<parentPos.y && childPos.z>parentPos.z){ return 2; }else if (childPos.x<parentPos.x && childPos.y>parentPos.y && childPos.z<parentPos.z){ return 3; }else if (childPos.x<parentPos.x && childPos.y>parentPos.y && childPos.z>parentPos.z){ return 4; }else if (childPos.x>parentPos.x && childPos.y<parentPos.y && childPos.z<parentPos.z){ return 5; }else if (childPos.x>parentPos.x && childPos.y<parentPos.y && childPos.z>parentPos.z){ return 6; }else if (childPos.x>parentPos.x && childPos.y>parentPos.y && childPos.z<parentPos.z){ return 7; }else if (childPos.x>parentPos.x && childPos.y>parentPos.y && childPos.z>parentPos.z){ return 8; } return 0; } function restrain(setup,name){ var restrained; if(!setup.bar){ restrained=[true,true,true,true,true,true]; }else{ restrained=[true,true,true]; } setup.nodes.find(v => v.id === name).restrained_degrees_of_freedom=restrained; } function addForce(setup,name,force){ var node=setup.nodes.find(v => v.id === name); node.force.x += force.x; node.force.y += force.y; node.force.z += force.z; } function restrainBelow(setup,y){ for(var i=0;i<setup.nodes.length;i++){ if(setup.nodes[i].position.y<=y){ if(setup.bar){ setup.nodes[i].restrained_degrees_of_freedom=[true,true,true]; }else{ setup.nodes[i].restrained_degrees_of_freedom=[true,true,true,true,true,true]; } } } } function addForceAbove(setup,y,force){ for(var i=0;i<setup.nodes.length;i++){ if(setup.nodes[i].position.y>=y){ setup.nodes[i].force.x += force.x; setup.nodes[i].force.y += force.y; setup.nodes[i].force.z += force.z; } } } function restrainFromBox(setup,supports){ for(var i=0;i<setup.nodes.length;i++){ for(var j=0;j<supports.length;j++){ if(supports[j][0].contains([setup.nodes[i].position.x,setup.nodes[i].position.y,setup.nodes[i].position.z])){ setup.nodes[i].restrained_degrees_of_freedom=supports[j][1]; } } } } function idFromBox(setup,box){ var list=[]; for(var i=0;i<setup.nodes.length;i++){ if(box.contains([setup.nodes[i].position.x,setup.nodes[i].position.y,setup.nodes[i].position.z])){ // list.push(setup.nodes[i].id) list.push(i) } } return list; } function loadFromBox(setup,loads){ for(var i=0;i<setup.nodes.length;i++){ for(var j=0;j<loads.length;j++){ if(loads[j][0].contains([setup.nodes[i].position.x,setup.nodes[i].position.y,setup.nodes[i].position.z])){ var force=loads[j][1]; setup.nodes[i].force.x += force.x; setup.nodes[i].force.y += force.y; setup.nodes[i].force.z += force.z; } } } } function displacementFromBox(setup,fixedDisplacements){ for(var i=0;i<setup.nodes.length;i++){ for(var j=0;j<fixedDisplacements.length;j++){ if(fixedDisplacements[j][0].contains([setup.nodes[i].position.x,setup.nodes[i].position.y,setup.nodes[i].position.z])){ var fixedDisplacement=fixedDisplacements[j][1]; setup.nodes[i].fixedDisplacement.x += fixedDisplacement.x; setup.nodes[i].fixedDisplacement.y += fixedDisplacement.y; setup.nodes[i].fixedDisplacement.z += fixedDisplacement.z; } } } } function changeMaterialFromBox(setup,box){ for(var j=0;j<box.length;j++){ for(var i=0;i<setup.edges.length;i++){ //todo remove later //todo change to map if(edgeInBox(setup,setup.edges[i],box[j][0])){ setup.edges[i].material=box[j][1]; } } for(var i=0;i<setup.nodes.length;i++){ //todo change to map var node=setup.nodes[i]; if(box[j][0].contains([node.position.x,node.position.y,node.position.z])){ node.material=box[j][1]; } } } } function edgeInBox(setup,edge,box){ const node1=setup.nodes[edge.source]; const node2=setup.nodes[edge.target]; return box.contains([node1.position.x,node1.position.y,node1.position.z])&&box.contains([node2.position.x,node2.position.y,node2.position.z]); } //////////// ///old setups var setupSimple={ nodes: [ { id: 'n0', parent: '11', degrees_of_freedom:[0,1,2,3,4,5] , restrained_degrees_of_freedom:[true,true,true,true,true,true], position: { x: 0, y: 10,z:0 }, force:{ x: 0, y: 0,z:0 }, displacement: { x: 0, y: -0,z:0 }, angle: { x: 0, y: 0,z:0 } }, { id: 'n1', parent: '11', degrees_of_freedom:[6,7,8,9,10,11] , restrained_degrees_of_freedom:[true,true,true,true,true,true], position: { x: 0, y: 0,z:0 }, force:{ x: 0, y: 0 }, displacement: { x: 0, y: 0,z:0 }, angle: { x: 0, y: 0,z:0 } }, { id: 'n2', parent: '11', degrees_of_freedom:[12,13,14,15,16,17,18] , restrained_degrees_of_freedom:[false,false,false,false,false,false], position: { x: 10, y: 5,z:0 }, force:{ x: 0, y: -200,z:0 }, displacement: { x: 0, y: 0,z:0 }, angle: { x: 0, y: 0,z:0 } } ], edges: [ { id: 'e0', source: 0, target: 2 ,area:1.0,density:0.284,stiffness:30.0e6,stress:0 }, { id: 'e1', source: 1, target: 2 ,area:2.0,density:0.284,stiffness:30.0e6,stress:0} ], //material properties - AISI 1095 Carbon Steel (Spring Steel) ndofs : 3*6, animation : { showDisplacement : true, exaggeration : 10000, speed:3.0 }, viz : { minStress:-500, maxStress: 500, colorMaps:[YlGnBu, winter, coolwarm,jet], colorMap:0, }, solve: solveFea, bar:false }; var oldVoxel={ nodes: [ { id: 'n0', parent: '11', degrees_of_freedom:[0,1,2] , //todo automate restrained_degrees_of_freedom:[true,true,true], position: { x: 0, y: 0,z:0 }, force:{ x: 0, y: 0,z:0 }, displacement: { x: 0, y: 0,z:0 } }, { id: 'n1', parent: '11', degrees_of_freedom:[3,4,5] , restrained_degrees_of_freedom:[false,false,false], position: { x: -5, y: 7.5,z:-5 }, force:{ x: 0, y: -200,z:0 }, displacement: { x: 0, y: 0,z:0 } }, { id: 'n2', parent: '11', degrees_of_freedom:[6,7,8] , restrained_degrees_of_freedom:[false,false,false], position: { x: -5, y: 7.5,z:5 }, force:{ x: 0, y: -200,z:0 }, displacement: { x: 0, y: 0,z:0 } }, { id: 'n3', parent: '11', degrees_of_freedom:[9,10,11] , restrained_degrees_of_freedom:[false,false,false], position: { x: 5, y: 7.5,z:5 }, force:{ x: 0, y:-200,z:0 }, displacement: { x: 0, y: 0,z:0 } }, { id: 'n4', parent: '11', degrees_of_freedom:[12,13,14] , restrained_degrees_of_freedom:[false,false,false], position: { x: 5, y: 7.5,z: -5 }, force:{ x: 0, y: -200,z:0 }, displacement: { x: 0, y: 0,z:0 } }, { id: 'n5', parent: '11', degrees_of_freedom:[15,16,17] , restrained_degrees_of_freedom:[false,false,false], position: { x: 0, y: 15,z: 0 }, force:{ x: 0, y: -400,z:0 }, displacement: { x: 0, y: 0,z:0 } } ], edges: [ { id: 'e0', source: 0, target: 1 ,area:1.0,density:0.284,stiffness:30.0e6,stress:0 }, { id: 'e1', source: 0, target: 2 ,area:1.0,density:0.284,stiffness:30.0e6,stress:0 }, { id: 'e2', source: 0, target: 3 ,area:1.0,density:0.284,stiffness:30.0e6,stress:0 }, { id: 'e3', source: 0, target: 4 ,area:1.0,density:0.284,stiffness:30.0e6,stress:0 }, { id: 'e4', source: 1, target: 2 ,area:1.0,density:0.284,stiffness:30.0e6,stress:0 }, { id: 'e5', source: 2, target: 3 ,area:1.0,density:0.284,stiffness:30.0e6,stress:0 }, { id: 'e6', source: 3, target: 4 ,area:1.0,density:0.284,stiffness:30.0e6,stress:0 }, { id: 'e7', source: 4, target: 1 ,area:1.0,density:0.284,stiffness:30.0e6,stress:0 }, { id: 'e8', source: 5, target: 1 ,area:1.0,density:0.284,stiffness:30.0e6,stress:0 }, { id: 'e9', source: 5, target: 2 ,area:1.0,density:0.284,stiffness:30.0e6,stress:0 }, { id: 'e10', source: 5, target: 3 ,area:1.0,density:0.284,stiffness:30.0e6,stress:0 }, { id: 'e11', source: 5, target: 4 ,area:1.0,density:0.284,stiffness:30.0e6,stress:0 }, ], //material properties - AISI 1095 Carbon Steel (Spring Steel) ndofs : 6*3, animation : { showDisplacement : true, exaggeration : 10000, speed:3.0 }, viz : { minStress:-500, maxStress: 500, colorMaps:[YlGnBu, winter, coolwarm,jet], colorMap:0, }, solve: solveFea, bar:true }; var setupEmpty={//empty nodes: [ ], edges: [ ], //material properties - AISI 1095 Carbon Steel (Spring Steel) ndofs : 3*6, animation : { showDisplacement : true, exaggeration : 20e2, speed:3.0 }, viz : { minStress:10e6, maxStress: -10e6, colorMaps:[coolwarm,YlGnBu, winter ,jet], colorMap:0, }, };