Skip to content
Snippets Groups Projects
geometry.js 26.9 KiB
Newer Older
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
const { isRegExp } = require("util");
// Amira Abdel-Rahman
// (c) Massachusetts Institute of Technology 2020
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed

Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
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);
			}
        }
	}
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
}
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
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);
				}
			}
        }
	}
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
}

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;

	}
	
	

Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
	occupancy[i][j][k]=checkandAdd(setup,position,material);
	//create node at size +position
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
	
	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;

Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
	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
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
			
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
			if(occupancy[ii][jj][kk]>-0.5){
				addEdge(setup,occupancy[i][j][k], occupancy[ii][jj][kk], material);
			}
		}
	}	
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
}

///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 },
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
		material: material,
		nomSize:1.0
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
    });
    
	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]);

}

////////////