Skip to content
Snippets Groups Projects
geometry.js 26.9 KiB
Newer Older
  • Learn to ignore specific revisions
  • 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]);
    
    }
    
    ////////////