diff --git a/01_Code/physical_computing_interface/index.html b/01_Code/physical_computing_interface/index.html
index d84376c7191e50d050adf849128a8ef2ebc2ee54..825190e5063721ec69f60c8032754ec6a69c8407 100644
--- a/01_Code/physical_computing_interface/index.html
+++ b/01_Code/physical_computing_interface/index.html
@@ -108,7 +108,7 @@
 <!-- code -->
 <script src="./main.js"></script> <!-- event handling and main json structure -->
 <script src="./threejs/assembly.js"></script><!-- assembly and timestep handling -->
-<script src="./threejs/main.js"></script><!-- threejs visualization -->
+<script src="./threejs/grid.js"></script><!-- threejs visualization -->
 <script src="./graph/main.js"></script><!-- graph flow visualization-->
 <script src="./json/main.js"></script><!-- json -->
 
diff --git a/01_Code/physical_computing_interface/threejs/grid.js b/01_Code/physical_computing_interface/threejs/grid.js
index 69ca6cdc0c506948a336cac0c8ae199e4a7ddfae..e9f47dbc107249b43545120ad5c434d31d0e846a 100644
--- a/01_Code/physical_computing_interface/threejs/grid.js
+++ b/01_Code/physical_computing_interface/threejs/grid.js
@@ -203,451 +203,465 @@ var gridPresets={
 var grid=gridPresets.Dice;
 
 function threejs(){
-    var camera, scene, renderer;
-    var plane;
-    var mouse, raycaster, isShiftDown = false;
-    // var rollOverMesh, rollOverMaterial;
-    var cubeGeo, cubeMaterial,sphereGeo,helperMaterial,helperPosition,helperColor;
-    var objects = [];
-    var container = document.getElementById( 'webgl' );
+    this.camera;
+    this.scene;
+    this.renderer;
+    this.plane;
+    this.mouse;
+    this.raycaster;
+    this.isShiftDown = false;
+    this.rollOverMesh;
+    this.rollOverMaterial;
+    this.cubeGeo;
+    this.cubeMaterial;
+    this.sphereGeo;
+    this.helperMaterial;
+    this.helperPosition;
+    this.helperColor;
+    this.objects = [];
+    this.container = document.getElementById( 'webgl' );
     // var container1 = document.getElementById( 'threejs' );
-    var controls;
-    var voxelSpacing=50.0;
-    var occupancyHelper;
-    var voxels=[];
-
+    this.controls;
+    this.voxelSpacing=50.0;
+    this.occupancyHelper;
+    this.voxels=[];
+}
 
-    init();
+threejs.prototype.init=function() {
+    this.camera = new THREE.PerspectiveCamera( 45, this.getWidth()/ this.getHeight()  , 1, 10000 );
+    this.camera.position.set( 500, 800, 1300 );
+    this.camera.lookAt( gridSize/2, 0, gridSize/2 );
+    this.scene = new THREE.Scene();
+    this.scene.background = new THREE.Color( 0xffffff );
+
+    this.cubeGeo = new THREE.BoxBufferGeometry( voxelSpacing, voxelSpacing, voxelSpacing );
+    this.sphereGeo = new THREE.SphereGeometry( voxelSpacing/2, 32, 32 );
+    this.cubeMaterial = new THREE.MeshPhongMaterial( { color: 0x1c5c61 } );
+
+    // grid
+    var gridHelper = new THREE.GridHelper( (gridSize)*voxelSpacing, gridSize );
+    gridHelper.position.x=gridSize/2.0*voxelSpacing-voxelSpacing/2.0;
+    gridHelper.position.z=gridSize/2.0*voxelSpacing-voxelSpacing/2.0;
+    gridHelper.position.y=-voxelSpacing/2.0*grid.voxelScaleZ;
+
+    gridHelper.scale.x=grid.xScale;
+    gridHelper.scale.z=grid.yScale;
+    gridHelper.scale.y=grid.zScale;
+    this.scene.add( gridHelper );
+
+
+
+    // roll-over helpers
+    var rollOverGeo = new THREE.BoxBufferGeometry( voxelSpacing, voxelSpacing, voxelSpacing  );
+    this.rollOverMaterial = new THREE.MeshBasicMaterial( { color: color4, opacity: 0.8, transparent: true } );
+    this.rollOverMesh = new THREE.Mesh( rollOverGeo, this.rollOverMaterial );
+    this.rollOverMesh.scale.x=grid.voxelScaleX;
+    this.rollOverMesh.scale.z=grid.voxelScaleY;
+    this.rollOverMesh.scale.y=grid.voxelScaleZ;
+    this.scene.add( this.rollOverMesh );
+
+    this.raycaster = new THREE.Raycaster();
+    this.mouse = new THREE.Vector2();
+    // var geometry = new THREE.PlaneBufferGeometry( 1000, 1000 );
+    // geometry.rotateX( - Math.PI / 2 );
+    // plane = new THREE.Mesh( geometry, new THREE.MeshBasicMaterial( { visible: false } ) );
+    // scene.add( plane );
+    // objects.push( plane );
+    
+    this.helperPosition = new Float32Array( 1 * 3 );
+    var c = new THREE.Color( color1 );
+    this.helperColor = new Float32Array( 1 * 3 );
+    this.helperColor[0]=c.r;
+    this.helperColor[1]=c.g;
+    this.helperColor[2]=c.b;
+    this.helperMaterial = new THREE.PointsMaterial( { size: 5, vertexColors: THREE.VertexColors,color:color3 } );
+
+    this.buildGrid(gridSize);
+    this.createHelperMeshes(gridSize);
+    
 
-    function init() {
-        camera = new THREE.PerspectiveCamera( 45, getWidth()/ getHeight()  , 1, 10000 );
-        camera.position.set( 500, 800, 1300 );
-        camera.lookAt( gridSize/2, 0, gridSize/2 );
-        scene = new THREE.Scene();
-        scene.background = new THREE.Color( 0xffffff );
+    // var axesHelper = new THREE.AxesHelper( 20 *grid.voxelSpacing);
+    // scene.add( axesHelper );
 
-        cubeGeo = new THREE.BoxBufferGeometry( voxelSpacing, voxelSpacing, voxelSpacing );
-        sphereGeo = new THREE.SphereGeometry( voxelSpacing/2, 32, 32 );
-        cubeMaterial = new THREE.MeshPhongMaterial( { color: 0x1c5c61 } );
+    // lights
+    var ambientLight = new THREE.AmbientLight( 0x606060 );
+    this.scene.add( ambientLight );
+    var directionalLight = new THREE.DirectionalLight( 0xffffff );
+    directionalLight.position.set( 1, 0.75, 0.5 ).normalize();
+    this.scene.add( directionalLight );
+    this.renderer = new THREE.WebGLRenderer( { antialias: true } );
+    this.renderer.setPixelRatio( window.devicePixelRatio );
+    this.renderer.setSize( this.getWidth(), this.getHeight() );
 
-        // grid
-        var gridHelper = new THREE.GridHelper( (gridSize)*voxelSpacing, gridSize );
-        gridHelper.position.x=gridSize/2.0*voxelSpacing-voxelSpacing/2.0;
-        gridHelper.position.z=gridSize/2.0*voxelSpacing-voxelSpacing/2.0;
-        gridHelper.position.y=-voxelSpacing/2.0*grid.voxelScaleZ;
+    this.renderer = new THREE.WebGLRenderer();
+    
+    this.container.appendChild( this.renderer.domElement );
+    this.controls = new THREE.OrbitControls( this.camera, this.renderer.domElement );
+    this.controls.target=new THREE.Vector3( gridSize/2*voxelSpacing,0 ,gridSize/2*voxelSpacing );
+    this.controls.update();
+    
+    // document.body.appendChild( renderer.domElement );
+    onWindowResizeThree();
+    this.container.addEventListener( 'mousemove', onDocumentMouseMoveThree, false );
+    this.container.addEventListener( 'mousedown', onDocumentMouseDownThree, false );
+    // window.addEventListener( 'keydown', onDocumentKeyDown, false );
+    // window.addEventListener( 'keyup', onDocumentKeyUp, false );
+    //
+    window.addEventListener( 'mouseup', onWindowResizeThree, false );
 
-        gridHelper.scale.x=grid.xScale;
-        gridHelper.scale.z=grid.yScale;
-        gridHelper.scale.y=grid.zScale;
-        scene.add( gridHelper );
+    window.addEventListener( 'resize', onWindowResizeThree, false );
 
-    
 
-        // roll-over helpers
-        var rollOverGeo = new THREE.BoxBufferGeometry( voxelSpacing, voxelSpacing, voxelSpacing  );
-        rollOverMaterial = new THREE.MeshBasicMaterial( { color: color4, opacity: 0.8, transparent: true } );
-        rollOverMesh = new THREE.Mesh( rollOverGeo, rollOverMaterial );
-        rollOverMesh.scale.x=grid.voxelScaleX;
-        rollOverMesh.scale.z=grid.voxelScaleY;
-        rollOverMesh.scale.y=grid.voxelScaleZ;
-        scene.add( rollOverMesh );
-
-        raycaster = new THREE.Raycaster();
-        mouse = new THREE.Vector2();
-        // var geometry = new THREE.PlaneBufferGeometry( 1000, 1000 );
-        // geometry.rotateX( - Math.PI / 2 );
-        // plane = new THREE.Mesh( geometry, new THREE.MeshBasicMaterial( { visible: false } ) );
-        // scene.add( plane );
-        // objects.push( plane );
-        
-        helperPosition = new Float32Array( 1 * 3 );
-        var c = new THREE.Color( color1 );
-        helperColor = new Float32Array( 1 * 3 );
-        helperColor[0]=c.r;
-        helperColor[1]=c.g;
-        helperColor[2]=c.b;
-        helperMaterial = new THREE.PointsMaterial( { size: 5, vertexColors: THREE.VertexColors,color:color3 } );
-
-        buildGrid(gridSize);
-        createHelperMeshes(gridSize);
-        
+    this.animate();
+}
 
-        // var axesHelper = new THREE.AxesHelper( 20 *grid.voxelSpacing);
-        // scene.add( axesHelper );
+////////////////////////
 
-        // lights
-        var ambientLight = new THREE.AmbientLight( 0x606060 );
-        scene.add( ambientLight );
-        var directionalLight = new THREE.DirectionalLight( 0xffffff );
-        directionalLight.position.set( 1, 0.75, 0.5 ).normalize();
-        scene.add( directionalLight );
-        renderer = new THREE.WebGLRenderer( { antialias: true } );
-        renderer.setPixelRatio( window.devicePixelRatio );
-        renderer.setSize( getWidth(), getHeight() );
+threejs.prototype.animate=function() {
 
-        renderer = new THREE.WebGLRenderer();
-        
-        container.appendChild( renderer.domElement );
-        controls = new THREE.OrbitControls( camera, renderer.domElement );
-        controls.target=new THREE.Vector3( gridSize/2*voxelSpacing,0 ,gridSize/2*voxelSpacing );
-        controls.update();
-        
-        // document.body.appendChild( renderer.domElement );
-        onWindowResize();
-        container.addEventListener( 'mousemove', onDocumentMouseMove, false );
-        container.addEventListener( 'mousedown', onDocumentMouseDown, false );
-        // window.addEventListener( 'keydown', onDocumentKeyDown, false );
-        // window.addEventListener( 'keyup', onDocumentKeyUp, false );
-        //
-        window.addEventListener( 'mouseup', onWindowResize, false );
+    requestAnimationFrame(this.animate.bind(this));
 
-        window.addEventListener( 'resize', onWindowResize, false );
+    this.render();
+}
 
+threejs.prototype.render=function() {
+    this.renderer.render( this.scene, this.camera );
+    this.controls.update();
+}
 
-        animate();
+////////////////////////////
+threejs.prototype.buildGrid=function(gridSize){
+    // occupancy=[];
+    this.occupancyHelper=[];
+    for (var i=0;i<gridSize;++i){
+        // occupancy.push([]);
+        this.occupancyHelper.push([]);
+        for (var j=0;j<gridSize;++j){
+            // occupancy[i].push([]);
+            this.occupancyHelper[i].push([]);
+            for (var k=0;k<gridSize;++k){
+                // occupancy[i][j].push(false);
+                this.occupancyHelper[i][j].push(false);
+            }
+        }
     }
+    // buildVoxelAt( 10, 0,0);
+    // for (var i=0;i<gridSize;++i){
+    //     for (var j=0;j<gridSize;++j){
+    //         for (var k=0;k<3;++k){
+    //             // if(k<5){
+    //                 buildVoxelAt(grid, i, j,k);
+    //                 // console.log(i+" "+ j+" "+k)
+    //                 occupancy[i][j][k]=true;
+    //             // }
+    //         }
+    //     }
+    // }
+}
 
+threejs.prototype.buildVoxelAt=function( grid,x, y,z){
+    // occupancy[x][y][z]=true;
+    // console.log(occupancy);
+    var voxel = new THREE.Mesh( this.cubeGeo, this.cubeMaterial );
+    // var voxel = new THREE.Mesh( sphereGeo, cubeMaterial );
 
-    ////////////////////////
+    var p_x ,p_y ,p_z ,s_x ,s_y,s_z,r_y;
+    [p_x ,p_y ,p_z ,s_x ,s_y,s_z,r_y]=this.getTransforms(grid,x, y,z);
+    // console.log(getTransforms(grid,x, y,z))
 
-    function onWindowResize( event ) {
+    voxel.scale.x=s_x;
+    voxel.scale.z=s_z;
+    voxel.scale.y=s_y;
 
-        camera.aspect = getWidth() / getHeight();
-        camera.updateProjectionMatrix();
+    voxel.position.x=0;
+    voxel.position.y=0;
+    voxel.position.z=0;
 
-        renderer.setSize( getWidth(), getHeight() );
-    }
+    voxel.rotation.y=r_y;
 
-    function animate() {
+    
+    voxel.position.x=p_x;
+    voxel.position.y=p_y;
+    voxel.position.z=p_z;
+    
+    voxel.name="["+parseInt(x) +","+parseInt(y) +","+parseInt(z) +"]";
 
-        requestAnimationFrame( animate );
+    this.scene.add(voxel);
+    this.voxels.push(voxel);
+}
+
+threejs.prototype.getTransforms=function(grid,x, y,z){
+    var s_x=grid.voxelScaleX;
+    var s_z=grid.voxelScaleY;
+    var s_y=grid.voxelScaleZ;
+
+    var p_x=0.0;
+    var p_y=0.0;
+    var p_z=0.0;
+    var r_y=0.0;
+    if(z%2!=0){
+        r_y=grid.zLayerRotation;
+        p_x+=grid.voxelSpacing*grid.xScale*(grid.xLayerOffset);
+        p_z+=grid.voxelSpacing*grid.yScale*(grid.yLayerOffset);
 
-        render();
     }
+    if(grid.doubleOffset){
+        if(parseInt(z/2)%2!=0){
+            p_x+=grid.voxelSpacing*grid.xScale*(grid.xLayerOffset2);
+            p_z+=grid.voxelSpacing*grid.yScale*(grid.yLayerOffset2);
+        }
+    }
+
+    p_x+=grid.voxelSpacing*grid.xScale*(x );
+    p_z+=grid.voxelSpacing*grid.yScale*(y );
+    p_y+=grid.voxelSpacing*grid.zScale*(z );
+
+    if(y%2!=0){
+        p_x+=grid.voxelSpacing*grid.xScale*(grid.xLineOffset);
+        p_z+=grid.voxelSpacing*grid.yScale*(grid.yLineOffset);
 
-    function render() {
-        renderer.render( scene, camera );
-        controls.update();
     }
+    return [p_x ,p_y ,p_z ,s_x ,s_y,s_z,r_y];
+}
 
-    ////////////////////////////
-    function buildGrid(gridSize){
-        // occupancy=[];
-        occupancyHelper=[];
-        for (var i=0;i<gridSize;++i){
-            // occupancy.push([]);
-            occupancyHelper.push([]);
-            for (var j=0;j<gridSize;++j){
-                // occupancy[i].push([]);
-                occupancyHelper[i].push([]);
-                for (var k=0;k<gridSize;++k){
-                    // occupancy[i][j].push(false);
-                    occupancyHelper[i][j].push(false);
-                }
-            }
+threejs.prototype.createHelperMeshes=function(gridSize){
+    for (var i=0;i<gridSize;++i){
+        for (var j=0;j<gridSize;++j){
+            this.buildHelperSnap(grid,i,j,0);
         }
-        // buildVoxelAt( 10, 0,0);
-        // for (var i=0;i<gridSize;++i){
-        //     for (var j=0;j<gridSize;++j){
-        //         for (var k=0;k<3;++k){
-        //             // if(k<5){
-        //                 buildVoxelAt(grid, i, j,k);
-        //                 // console.log(i+" "+ j+" "+k)
-        //                 occupancy[i][j][k]=true;
-        //             // }
-        //         }
-        //     }
-        // }
     }
 
-    function buildVoxelAt( grid,x, y,z){
-        // occupancy[x][y][z]=true;
-        // console.log(occupancy);
-        var voxel = new THREE.Mesh( cubeGeo, cubeMaterial );
-        // var voxel = new THREE.Mesh( sphereGeo, cubeMaterial );
+}
 
-        var p_x ,p_y ,p_z ,s_x ,s_y,s_z,r_y;
-        [p_x ,p_y ,p_z ,s_x ,s_y,s_z,r_y]=getTransforms(grid,x, y,z);
+threejs.prototype.buildHelperSnap=function(grid,x,y,z){
+    this.occupancyHelper[x][y][z]=true;
+    var geometry = new THREE.PlaneBufferGeometry( grid.voxelSpacing*grid.xScale, grid.voxelSpacing*grid.yScale );
+    geometry.rotateX( - Math.PI / 2 );
+    this.plane = new THREE.Mesh( geometry, new THREE.MeshBasicMaterial( { visible: false } ) );
+    // plane = new THREE.Mesh( geometry,helperMaterial );
+    
+
+    [p_x ,p_y ,p_z ,s_x ,s_y,s_z,r_y]=this.getTransforms(grid,x, y,z);
         // console.log(getTransforms(grid,x, y,z))
 
-        voxel.scale.x=s_x;
-        voxel.scale.z=s_z;
-        voxel.scale.y=s_y;
+    this.plane.scale.x=s_x;
+    this.plane.scale.z=s_z;
+    // rollOverMesh.scale.y=s_y;
 
-        voxel.position.x=0;
-        voxel.position.y=0;
-        voxel.position.z=0;
+    this.plane.position.x=0;
+    this.plane.position.y=0;
+    this.plane.position.z=0;
 
-        voxel.rotation.y=r_y;
+    this.plane.rotation.y=r_y;
 
-        
-        voxel.position.x=p_x;
-        voxel.position.y=p_y;
-        voxel.position.z=p_z;
-        
-        voxel.name="["+parseInt(x) +","+parseInt(y) +","+parseInt(z) +"]";
-
-        scene.add(voxel);
-        voxels.push(voxel);
-    }
+    
+    this.plane.position.x=p_x;
+    this.plane.position.y=p_y;
+    this.plane.position.z=p_z;
 
-    function getTransforms(grid,x, y,z){
-        var s_x=grid.voxelScaleX;
-        var s_z=grid.voxelScaleY;
-        var s_y=grid.voxelScaleZ;
+    // plane.scale.x=grid.xScale*0.95;
+    // plane.scale.z=grid.yScale*0.95;
 
-        var p_x=0.0;
-        var p_y=0.0;
-        var p_z=0.0;
-        var r_y=0.0;
-        if(z%2!=0){
-            r_y=grid.zLayerRotation;
-            p_x+=grid.voxelSpacing*grid.xScale*(grid.xLayerOffset);
-            p_z+=grid.voxelSpacing*grid.yScale*(grid.yLayerOffset);
+    // plane.position.x=0.0;
+    // plane.position.y=0.0;
+    // plane.position.z=0.0;
 
-        }
-        if(grid.doubleOffset){
-            if(parseInt(z/2)%2!=0){
-                p_x+=grid.voxelSpacing*grid.xScale*(grid.xLayerOffset2);
-                p_z+=grid.voxelSpacing*grid.yScale*(grid.yLayerOffset2);
-            }
-        }
+    // plane.position.x+=grid.voxelSpacing*grid.xScale*(x );
+    // plane.position.z+=grid.voxelSpacing*grid.yScale*(y );
+    // plane.position.y+=grid.voxelSpacing*grid.zScale*(z );
 
-        p_x+=grid.voxelSpacing*grid.xScale*(x );
-        p_z+=grid.voxelSpacing*grid.yScale*(y );
-        p_y+=grid.voxelSpacing*grid.zScale*(z );
+    // if(y%2!=0){
+    //     plane.position.x+=grid.voxelSpacing*grid.xScale*(grid.xLineOffset);
+    //     plane.position.z+=grid.voxelSpacing*grid.yScale*(grid.yLineOffset);
 
-        if(y%2!=0){
-            p_x+=grid.voxelSpacing*grid.xScale*(grid.xLineOffset);
-            p_z+=grid.voxelSpacing*grid.yScale*(grid.yLineOffset);
+    // }
+    // plane.position.y-=grid.voxelSpacing*grid.zScale/2.0;
+    this.plane.name="p["+parseInt(x) +","+parseInt(y) +","+parseInt(z) +"]";
+    
+    this.helperPosition[0]=this.plane.position.x;
+    this.helperPosition[1]=this.plane.position.y;
+    this.helperPosition[2]=this.plane.position.z;
+    var helperGeometry = new THREE.BufferGeometry();
+    helperGeometry.setAttribute( 'position', new THREE.BufferAttribute( this.helperPosition.slice(), 3 ) );
+    helperGeometry.setAttribute( 'color', new THREE.BufferAttribute( this.helperColor.slice(), 3 ) );
+    this.helper = new THREE.Points( helperGeometry, this.helperMaterial );
+    this.helper.name="s["+parseInt(x) +","+parseInt(y) +","+parseInt(z) +"]";
+
+    this.scene.add( this.helper );
+    this.scene.add( this.plane );
+    this.objects.push( this.plane );
+}
 
-        }
-        return [p_x ,p_y ,p_z ,s_x ,s_y,s_z,r_y];
-    }
+threejs.prototype.buildNeighbourHelpers=function(grid, x, y,z){
 
-    function createHelperMeshes(gridSize){
-        for (var i=0;i<gridSize;++i){
-            for (var j=0;j<gridSize;++j){
-                buildHelperSnap(grid,i,j,0);
-            }
+    var list=getNeighboursList(grid,x,y,z); //TODO ENCLOSE
+    
+    for(var i=0;i<list.length;i++){
+        var x1,y1,z1;
+        [x1,y1,z1]=list[i];
+        if(this.helperAt(x1,y1,z1)){
+            this.buildHelperSnap(grid,x1,y1,z1);
         }
 
     }
 
-    function buildHelperSnap(grid,x,y,z){
-        occupancyHelper[x][y][z]=true;
-        var geometry = new THREE.PlaneBufferGeometry( grid.voxelSpacing*grid.xScale, grid.voxelSpacing*grid.yScale );
-        geometry.rotateX( - Math.PI / 2 );
-        plane = new THREE.Mesh( geometry, new THREE.MeshBasicMaterial( { visible: false } ) );
-        // plane = new THREE.Mesh( geometry,helperMaterial );
-        
+    //go through all neighbours
+        //if occupancy empty
+            //add helper meshes??
+            //how to rotate plane
 
-        [p_x ,p_y ,p_z ,s_x ,s_y,s_z,r_y]=getTransforms(grid,x, y,z);
-            // console.log(getTransforms(grid,x, y,z))
+}
 
-        plane.scale.x=s_x;
-        plane.scale.z=s_z;
-        // rollOverMesh.scale.y=s_y;
+threejs.prototype.helperAt=function(x,y,z){
+    if(x<0||y<0||z<0){
+        return false;
+    }
+    if(x>=gridSize||y>=gridSize||z>=gridSize){
+        return false;
+    }
+    if(occupancy[x][y][z]||this.occupancyHelper[x][y][z]){
+        return false;
+    }
+    
+    return true;
 
-        plane.position.x=0;
-        plane.position.y=0;
-        plane.position.z=0;
+}
 
-        plane.rotation.y=r_y;
+threejs.prototype.updateHelperMeshesAfterRemove=function(grid,x,y,z){
+    this.buildHelperSnap(grid,x,y,z);
+    var list=getNeighboursList(grid,x,y,z); //TODO ENCLOSE
+    
+    for(var i=0;i<list.length;i++){
+        var x1,y1,z1;
+        [x1,y1,z1]=list[i];
+        if(!this.helperAt(x1,y1,z1)&&z1>0){
+            // buildHelperSnap(grid,x1,y1,z1);
+            var name='[' +x1+"," +y1+","+z1+']';
+            var object = this.scene.getObjectByName( 'p'+name );
+            this.scene.remove( object );
+            this.objects.splice( three.objects.indexOf( object ), 1 );
+            object = three.scene.getObjectByName( 's'+name );
+            this.scene.remove( object );
+            this.occupancyHelper[x1][y1][z1]=false;
+        }
 
-        
-        plane.position.x=p_x;
-        plane.position.y=p_y;
-        plane.position.z=p_z;
+    }
+}
+//
+threejs.prototype.changeToGrid=function(newGrid){
 
-        // plane.scale.x=grid.xScale*0.95;
-        // plane.scale.z=grid.yScale*0.95;
+}
 
-        // plane.position.x=0.0;
-        // plane.position.y=0.0;
-        // plane.position.z=0.0;
+threejs.prototype.getWidth=function(){
+    // return container.style.width;
+    return $('#threejs').width() ;
+}
 
-        // plane.position.x+=grid.voxelSpacing*grid.xScale*(x );
-        // plane.position.z+=grid.voxelSpacing*grid.yScale*(y );
-        // plane.position.y+=grid.voxelSpacing*grid.zScale*(z );
+threejs.prototype.getHeight=function(){
+    // return container.style.height;
+    return $('#threejs').height() ;
+}
+/////////////////////
 
-        // if(y%2!=0){
-        //     plane.position.x+=grid.voxelSpacing*grid.xScale*(grid.xLineOffset);
-        //     plane.position.z+=grid.voxelSpacing*grid.yScale*(grid.yLineOffset);
+var three=new threejs();
+three.init();
 
-        // }
-        // plane.position.y-=grid.voxelSpacing*grid.zScale/2.0;
-        plane.name="p["+parseInt(x) +","+parseInt(y) +","+parseInt(z) +"]";
-        
-        helperPosition[0]=plane.position.x;
-        helperPosition[1]=plane.position.y;
-        helperPosition[2]=plane.position.z;
-        var helperGeometry = new THREE.BufferGeometry();
-        helperGeometry.setAttribute( 'position', new THREE.BufferAttribute( helperPosition.slice(), 3 ) );
-        helperGeometry.setAttribute( 'color', new THREE.BufferAttribute( helperColor.slice(), 3 ) );
-        helper = new THREE.Points( helperGeometry, helperMaterial );
-        helper.name="s["+parseInt(x) +","+parseInt(y) +","+parseInt(z) +"]";
-
-        scene.add( helper );
-        scene.add( plane );
-        objects.push( plane );
-    }
 
-    function buildNeighbourHelpers(grid, x, y,z){
+//////////////////////////////////////////////////
+function onWindowResizeThree( event ) {
 
-        var list=getNeighboursList(grid,x,y,z);
-        
-        for(var i=0;i<list.length;i++){
-            var x1,y1,z1;
-            [x1,y1,z1]=list[i];
-            if(helperAt(x1,y1,z1)){
-                buildHelperSnap(grid,x1,y1,z1);
-            }
+    three.camera.aspect = three.getWidth() / three.getHeight();
+    three.camera.updateProjectionMatrix();
 
-        }
+    three.renderer.setSize( three.getWidth(), three.getHeight() );
+}
 
-        //go through all neighbours
-            //if occupancy empty
-                //add helper meshes??
-                //how to rotate plane
+function onDocumentMouseMoveThree( event ) {
+    event.preventDefault();
+    three.mouse.set( ( event.clientX / three.getWidth() ) * 2 - 1, - ( event.clientY /three.getHeight() ) * 2 + 1 );
+    three.raycaster.setFromCamera(three.mouse, three.camera );
+    var intersects = three.raycaster.intersectObjects( three.objects );
+    if ( intersects.length > 0 ) {
+        var intersect = intersects[ 0 ];
+        var obj=getXYZfromName(intersect.object.name);
 
-    }
+        [p_x ,p_y ,p_z ,s_x ,s_y,s_z,r_y]=three.getTransforms(grid,obj.x, obj.y,obj.z);
+        // console.log(getTransforms(grid,x, y,z))
 
-    function helperAt(x,y,z){
-        if(x<0||y<0||z<0){
-            return false;
-        }
-        if(x>=gridSize||y>=gridSize||z>=gridSize){
-            return false;
-        }
-        if(occupancy[x][y][z]||occupancyHelper[x][y][z]){
-            return false;
-        }
-        
-        return true;
+        // rollOverMesh.scale.x=s_x;
+        // rollOverMesh.scale.z=s_z;
+        // rollOverMesh.scale.y=s_y;
+        three.rollOverMesh.name="r["+parseInt(obj.x) +","+parseInt(obj.y) +","+parseInt(obj.z) +"]"
+        three.rollOverMesh.position.x=0;
+        three.rollOverMesh.position.y=0;
+        three.rollOverMesh.position.z=0;
 
-    }
+        three.rollOverMesh.rotation.y=r_y;
 
-    function updateHelperMeshesAfterRemove(grid,x,y,z){
-        buildHelperSnap(grid,x,y,z);
-        var list=getNeighboursList(grid,x,y,z);
         
-        for(var i=0;i<list.length;i++){
-            var x1,y1,z1;
-            [x1,y1,z1]=list[i];
-            if(!helperAt(x1,y1,z1)&&z1>0){
-                // buildHelperSnap(grid,x1,y1,z1);
-                var name='[' +x1+"," +y1+","+z1+']';
-                var object = scene.getObjectByName( 'p'+name );
-                scene.remove( object );
-                objects.splice( objects.indexOf( object ), 1 );
-                object = scene.getObjectByName( 's'+name );
-                scene.remove( object );
-                occupancyHelper[x1][y1][z1]=false;
-            }
+        three.rollOverMesh.position.x=p_x;
+        three.rollOverMesh.position.y=p_y;
+        three.rollOverMesh.position.z=p_z;
 
-        }
+        
+        // rollOverMesh.position.copy( intersect.object.position ).add(temp );
+        
     }
+    three.render();
+}
 
-    /////////////////////
+function onDocumentMouseDownThree( event ) {
 
-    function onDocumentMouseMove( event ) {
-        event.preventDefault();
-        mouse.set( ( event.clientX / getWidth() ) * 2 - 1, - ( event.clientY /getHeight() ) * 2 + 1 );
-        raycaster.setFromCamera( mouse, camera );
-        var intersects = raycaster.intersectObjects( objects );
-        if ( intersects.length > 0 ) {
+    event.preventDefault();
+    three.mouse.set( ( event.clientX / three.getWidth() ) * 2 - 1, - ( event.clientY / three.getHeight() ) * 2 + 1 );
+    three.raycaster.setFromCamera( three.mouse, three.camera );
+    var intersects = three.raycaster.intersectObjects( three.objects );
+    var intersects1 = three.raycaster.intersectObjects( three.voxels );
+    if ( intersects.length > 0  ||intersects1.length>0){
+        if(event.which==1 && intersects.length > 0) { //left click
             var intersect = intersects[ 0 ];
             var obj=getXYZfromName(intersect.object.name);
-
-            [p_x ,p_y ,p_z ,s_x ,s_y,s_z,r_y]=getTransforms(grid,obj.x, obj.y,obj.z);
-            // console.log(getTransforms(grid,x, y,z))
-
-            // rollOverMesh.scale.x=s_x;
-            // rollOverMesh.scale.z=s_z;
-            // rollOverMesh.scale.y=s_y;
-            rollOverMesh.name="r["+parseInt(obj.x) +","+parseInt(obj.y) +","+parseInt(obj.z) +"]"
-            rollOverMesh.position.x=0;
-            rollOverMesh.position.y=0;
-            rollOverMesh.position.z=0;
-
-            rollOverMesh.rotation.y=r_y;
-
-            
-            rollOverMesh.position.x=p_x;
-            rollOverMesh.position.y=p_y;
-            rollOverMesh.position.z=p_z;
-
-            
-            // rollOverMesh.position.copy( intersect.object.position ).add(temp );
-            
+            obj=getXYZfromName(three.rollOverMesh.name);
+            addNode (obj.x, obj.y,obj.z);
+        }else if ( intersects1.length > 0 && event.which==3){//right click
+                var intersect = intersects1[ 0 ];
+                // console.log(intersect.object);
+                var obj=getXYZfromName(intersect.object.name);
+                removeNode(obj.x,obj.y,obj.z);
         }
-        render();
+        three.render();
     }
+    
+}
 
-    function onDocumentMouseDown( event ) {
+document.addEventListener('removeNode', function (e) { 
+    var name='[' +e.detail.x +"," +e.detail.y+","+e.detail.z+']';
+    var object = three.scene.getObjectByName( name );
+    three.scene.remove( object );
+    three.voxels.splice( three.objects.indexOf( object ), 1 );
+    three.updateHelperMeshesAfterRemove(grid,e.detail.x,e.detail.y,e.detail.z);
+    
+    
+}, false);
 
-        event.preventDefault();
-        mouse.set( ( event.clientX / getWidth() ) * 2 - 1, - ( event.clientY / getHeight() ) * 2 + 1 );
-        raycaster.setFromCamera( mouse, camera );
-        var intersects = raycaster.intersectObjects( objects );
-        var intersects1 = raycaster.intersectObjects( voxels );
-        if ( intersects.length > 0  ||intersects1.length>0){
-            if(event.which==1 && intersects.length > 0) { //left click
-                var intersect = intersects[ 0 ];
-                var obj=getXYZfromName(intersect.object.name);
-                obj=getXYZfromName(rollOverMesh.name);
-                addNode (obj.x, obj.y,obj.z);
-            }else if ( intersects1.length > 0 && event.which==3){//right click
-                    var intersect = intersects1[ 0 ];
-                    // console.log(intersect.object);
-                    var obj=getXYZfromName(intersect.object.name);
-                    removeNode(obj.x,obj.y,obj.z);
-            }
-            render();
-        }
-        
-    }
+document.addEventListener('addNode', function (e) { 
+    three.buildVoxelAt( grid, e.detail.x, e.detail.y,e.detail.z);
 
-    document.addEventListener('removeNode', function (e) { 
-        var name='[' +e.detail.x +"," +e.detail.y+","+e.detail.z+']';
-        var object = scene.getObjectByName( name );
-        scene.remove( object );
-        voxels.splice( objects.indexOf( object ), 1 );
-        updateHelperMeshesAfterRemove(grid,e.detail.x,e.detail.y,e.detail.z);
-        
-        
-    }, false);
+    //deleteHelper Meshes
+    var name='[' +e.detail.x +"," +e.detail.y+","+e.detail.z+']';
+    var object = three.scene.getObjectByName( 'p'+name );
+    three.scene.remove( object );
+    three.objects.splice( three.objects.indexOf( object ), 1 );
+    object = three.scene.getObjectByName( 's'+name );
+    three.scene.remove( object );
+    three.occupancyHelper[e.detail.x][e.detail.y][e.detail.z]=false;
 
-    document.addEventListener('addNode', function (e) { 
-        buildVoxelAt( grid, e.detail.x, e.detail.y,e.detail.z);
+    three.buildNeighbourHelpers(grid, e.detail.x, e.detail.y,e.detail.z);
+    
+}, false);
 
-        //deleteHelper Meshes
-        var name='[' +e.detail.x +"," +e.detail.y+","+e.detail.z+']';
-        var object = scene.getObjectByName( 'p'+name );
-        scene.remove( object );
-        objects.splice( objects.indexOf( object ), 1 );
-        object = scene.getObjectByName( 's'+name );
-        scene.remove( object );
-        occupancyHelper[e.detail.x][e.detail.y][e.detail.z]=false;
 
-        buildNeighbourHelpers(grid, e.detail.x, e.detail.y,e.detail.z);
-        
-    }, false);
 
-    //
-    function changeToGrid(newGrid){
 
-    }
-    function getWidth(){
-        // return container.style.width;
-        return $('#threejs').width() ;
-    }
 
-    function getHeight(){
-        // return container.style.height;
-        return $('#threejs').height() ;
-    }
-}
-threejs();