Skip to content
Snippets Groups Projects
geometry.js 35.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();

	

	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;
		}
	}
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
	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
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
			// 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]);
						}
						
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
					}
				}
			}
		}else if(layer==layerIndex){
			console.log("Warning: unknown object imported from Rhino on layer:"+object)
		}
	}

	setup.materialList=[];//don't need it anymore

Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
}

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;

	}
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed


	if(typeof setup.multiscale === 'undefined'|| !setup.multiscale){ //not multiscale
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed

		occupancy[i][j][k]=checkandAdd(setup,position,material,parent,nodeScale);
		//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;
		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];
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
			
			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);
				}
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
			}
	}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 );

						}
					}
				}
			}	
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed

Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed

			// position.x+=size/2;position.y+=size/2;position.z+=size/2;
			
			var parentId=checkandAdd(setup,position,material,"",2); //add main node
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed

			//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;
							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 );

						// }
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed

Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed



/////////////////////drawing utils//////////////////////

function addNode(setup,position,restrained,force,material,parent='11',scale=1){
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
	var bar=setup.bar;
	var numNode=setup.nodes.length;
	setup.nodes.push({
		id: 'n'+numNode, 
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
		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
    });
	if(parent!='11'){
		setup.nodes[numNode].multiscale=true;
		setup.nodes[numNode].scale=scale;
	}
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 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){
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed

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

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

		}

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

}

Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
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,