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(); for (let ii = 0; ii < objects.count; ii++) { let object = objects.get(ii).geometry(); let layer=objects.get(ii).attributes().layerIndex; if((object instanceof _rhino3dm.LineCurve ||object instanceof _rhino3dm.NurbsCurve ||object instanceof _rhino3dm.PolylineCurve )&& layer==layerIndex ) { //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); addEdge(setup,source,target,material); } } } }else if(layer==layerIndex){ console.log("Warning: unknown object imported from Rhino on layer:"+object) } } } 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){ 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; } occupancy[i][j][k]=checkandAdd(setup,position,material); //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); } } } } ///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, }, }; /////////////////////drawing utils////////////////////// function addNode(setup,position,restrained,force,material){ var bar=setup.bar; var numNode=setup.nodes.length; setup.nodes.push({ id: 'n'+numNode, parent: '11', 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 }); 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 addEdge(setup,source,target,material){ 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 }); }else{ setup.edges.push({ id: 'e'+numEdge, source: source, target: target ,material:material,stress:0 }); } // 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){ 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); 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 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]); } ////////////