diff --git a/js/fea/dmaCell.js b/js/fea/dmaCell.js
index 7ff26b32a33067b4629607f03462d73fcd24c580..7e643426968229b2b3de5b2c73380090ddc72871 100644
--- a/js/fea/dmaCell.js
+++ b/js/fea/dmaCell.js
@@ -149,7 +149,7 @@
         if (this.cellMesh) {
             window.three.sceneRemove(this.cellMesh);
             this.cellMesh.myCell = null;
-            this.cellMesh.dispose();
+//            this.cellMesh.dispose();
 //            geometry.dispose();
 //            material.dispose();
             this.cellMesh = null;
diff --git a/js/fea/dmaPart.js b/js/fea/dmaPart.js
index a28c86e44a780dbf45356cb7f872fb42a4049302..2e3f0e9e251bd6a413a45d1d58baff3a0d00530e 100644
--- a/js/fea/dmaPart.js
+++ b/js/fea/dmaPart.js
@@ -94,7 +94,7 @@
     DMAPart.prototype.destroy = function(){
         if (this.mesh) {
             window.three.sceneRemove(this.mesh);
-            this.mesh.dispose();
+//            this.mesh.dispose();
 //            geometry.dispose();
 //            material.dispose();
             this.mesh = null;
diff --git a/js/main.js b/js/main.js
index 85044f23d9755ff0363262ee6caacd395b1092bd..b5183a15f0e3ea1a2a71ae4c67875545572ee44a 100644
--- a/js/main.js
+++ b/js/main.js
@@ -11,12 +11,14 @@ $(function(){
     //init threeJS and geometry models
     window.three = new ThreeModel();
     var lattice = new Lattice();
-    new ThreeView({model:window.three, lattice:lattice});
 
     //setup ui
     var appState = new AppState({lattice:lattice});
     new MenuWrapper({lattice:lattice, model:appState});
     new NavBar({model:appState});
 
+    //threeJS View
+    new ThreeView({model:window.three, lattice:lattice, appState:appState});
+
     lattice.addCell(new THREE.Vector3(0,0,0));
 });
diff --git a/js/menus/LatticeMenuView.js b/js/menus/LatticeMenuView.js
index 853daa0c8a30042f9e85d80efe5a0d728e1b7c21..941d73f21fff4e3f9c1735f30fa40c785515f4ed 100644
--- a/js/menus/LatticeMenuView.js
+++ b/js/menus/LatticeMenuView.js
@@ -19,8 +19,9 @@ LatticeMenuView = Backbone.View.extend({
 
         _.bindAll(this, "render");
         this.listenTo(this.model, "change", function(){
-            if(!model.hasChanged('cellMode')) return;//ignore cell mode changes
-            this.render();
+            if(!this.model.hasChanged('cellMode')){//ignore cell mode changes
+                this.render();
+            };
         });
     },
 
diff --git a/js/models/AppState.js b/js/models/AppState.js
index 9e573047e7c3380c47e3b64d264ce4c35acf5770..5d2e4280796ee396529598a5e6b789a5158afeef 100644
--- a/js/models/AppState.js
+++ b/js/models/AppState.js
@@ -16,11 +16,21 @@ AppState = Backbone.Model.extend({
         lastSimulationTab: "physics",
         lastAssembleTab: "assembler",
 
-        menuIsVisible: true
+        menuIsVisible: true,
+
+        //key bindings
+        shift: false,
+        deleteMode: false,
+        extrudeMode: false
     },
 
     initialize: function(options){
 
+        _.bindAll(this, "_handleKeyStroke");
+
+        //bind events
+        $(document).bind('keydown', {state:true}, this._handleKeyStroke);
+        $(document).bind('keyup', {state:false}, this._handleKeyStroke);
         this.listenTo(this, "change:currentTab", this._storeTab);
         this.listenTo(this, "change:currentTab", this._updateLatticeMode);
         this.listenTo(this, "change:currentNav", this._updateCurrentTabForNav);
@@ -47,10 +57,40 @@ AppState = Backbone.Model.extend({
     //update to last tab open in that section
     _updateCurrentTabForNav: function(){
         var navSelection = this.get("currentNav");
-        if (navSelection=="navDesign") this.set("currentTab", this.get("lastDesignTab"), {silent:true});
-        else if (navSelection=="navSim") this.set("currentTab", this.get("lastSimulationTab"), {silent:true});
-        else if (navSelection=="navAssemble") this.set("currentTab", this.get("lastAssembleTab"), {silent:true});
+        if (navSelection == "navDesign") this.set("currentTab",
+            this.get("lastDesignTab"), {silent:true});
+        else if (navSelection == "navSim") this.set("currentTab",
+            this.get("lastSimulationTab"), {silent:true});
+        else if (navSelection == "navAssemble") this.set("currentTab",
+            this.get("lastAssembleTab"), {silent:true});
         this._updateLatticeMode();//a little bit hacky, this updates the lattice, but holds off on updating the menus til the animation has happened
+    },
+
+    ///////////////////////////////////////////////////////////////////////////////
+    ////////////////////KEYS AND MOUSE EVENTS//////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////////
+
+    _handleKeyStroke: function(e){//receives keyup and keydown
+
+        var state = e.data.state;
+        var currentTab = this.get("currentTab");
+
+        switch(e.keyCode){
+            case 16://shift
+                this.set("shift", state);
+                break;
+            case 32://space bar
+                e.preventDefault();
+                this.set("deleteMode", state);
+                break;
+            case 69://e
+//                if (currentTab != "sketch") return;
+                this.set("extrudeMode", state);
+                break;
+
+            default:
+                break;
+        }
     }
 
 });
\ No newline at end of file
diff --git a/js/models/lattice.js b/js/models/lattice.js
index b184cc0894382e903ce413a833710c5db68115b8..5d414822bd8d0d8ee59b2b197a52df1274cf03b5 100644
--- a/js/models/lattice.js
+++ b/js/models/lattice.js
@@ -151,6 +151,7 @@ Lattice = Backbone.Model.extend({
 
     removeCell: function(object){
 
+        if (!object) return;
         var cell = object.parent.myCell;
         var index = this._subtract(cell.indices, this.get("cellsMin"));
         var cells = this.get("cells");
diff --git a/js/threeViews/threeView.js b/js/threeViews/threeView.js
index 5ce802cc613902a3572eecca9cc7ebcb598e3798..646ee2cec2b3a89f97a35f3de25d7f839bc37603 100644
--- a/js/threeViews/threeView.js
+++ b/js/threeViews/threeView.js
@@ -5,15 +5,12 @@
 ThreeView = Backbone.View.extend({
 
     events: {
-        "mousemove":            "_mouseMoved",
-        "mousedown":            "_mouseDown",
-        "mouseup":              "_mouseUp"
+        "mousemove":                            "_mouseMoved",
+        "mouseup":                              "_mouseUp",
+        "mousedown":                            "_mouseDown"
     },
 
-    mouseIsDown: false,//store state of mouse click
-    shiftIsDown: false,//used to add many voxels at once
-    deleteMode: false,//delete cells instead of adding (space bar)
-    extrudeMode: false,//extrude a column of cells
+    mouseIsDown: false,//store state of mouse click inside this el
     extrudeVisualizer: ExtrudeVisualizer(),
     mouseProjection: new THREE.Raycaster(),
     highlighter: null,
@@ -28,63 +25,55 @@ ThreeView = Backbone.View.extend({
     initialize: function(options){
 
         this.lattice = options.lattice;
+        this.appState = options.appState;
 
-        _.bindAll(this, "_animate", "_mouseMoved", "_handleKeyStroke", "_drawBasePlane");
+        _.bindAll(this, "_animate", "_mouseMoved", "_drawBasePlane");
 
         //bind events
-        $(document).bind('keydown', {state:true}, this._handleKeyStroke);
-        $(document).bind('keyup', {state:false}, this._handleKeyStroke);
-        this.listenTo(this.lattice, "change:type, change:scale", this._drawBasePlane);
+        this.listenTo(this.lattice, "change:type change:scale", this._drawBasePlane);
+        this.listenTo(this.appState, "change:deleteMode change:extrudeMode change:shift", this._setControlsEnabled);
 
         this.controls = new THREE.OrbitControls(this.model.camera, this.$el.get(0));
         this.controls.addEventListener('change', this.model.render);
 
-        this.$el.append(this.model.domElement);
-
-        this._animate();
+        this.$el.append(this.model.domElement);//render only once
 
         this.basePlane = this._drawBasePlane();
 
         //init highlighter
+        this.highlighter = this._initHighlighter();
+        window.three.sceneAdd(this.highlighter, true);
+
+        this.model.render();
+        this._animate();
+    },
+
+    _initHighlighter: function(){
         var highlightGeometry = new THREE.Geometry();
         //can't change size of faces or vertices buffers dynamically
         highlightGeometry.vertices = [new THREE.Vector3(0,0,0), new THREE.Vector3(0,0,0), new THREE.Vector3(0,0,0)];
         highlightGeometry.faces = [new THREE.Face3(0,1,2)];
-        this.highlighter = new THREE.Mesh(highlightGeometry,
+        var highlighter = new THREE.Mesh(highlightGeometry,
             new THREE.MeshBasicMaterial({side:THREE.DoubleSide, transparent:true, opacity:0.4, color:0xffffff, vertexColors:THREE.FaceColors}));
-        this.highlighter.geometry.dynamic = true;
-        this.highlighter.visible = false;
-        window.three.sceneAdd(this.highlighter, true);
-
-        this.model.render();
+        highlighter.geometry.dynamic = true;
+        highlighter.visible = false;
+        return highlighter;
     },
 
+    ////////////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////CONTROLS/////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////////
+
     _animate: function(){
         requestAnimationFrame(this._animate);
         this.controls.update();
     },
 
-    _handleKeyStroke: function(e){//receives keyup and keydown
-
-        var state = e.data.state;
-
-        switch(e.keyCode){
-            case 16://shift
-                this.shiftIsDown = state;
-                this.controls.enabled = !state;
-                break;
-            case 32://space bar
-                e.preventDefault();
-                this.deleteMode = state;
-                this.controls.enabled = !state;
-                break;
-            case 69://e
-                this.extrudeMode = state;
-                this.controls.enabled = !state;
-                break;
-
-            default:
-                break;
+    _setControlsEnabled: function(){
+        if (this.appState.get("deleteMode") || this.appState.get("shift") || this.appState.get("extrudeMode")){
+            this.controls.enabled = false;
+        } else {
+            this.controls.enabled = true;
         }
     },
 
@@ -104,10 +93,10 @@ ThreeView = Backbone.View.extend({
             return;
         }
 
-        if (this.extrudeMode && this.mouseIsDown && this.extrudeVisualizer.getMeshNum()>0){
-            this.extrudeVisualizer.dragHandle(1-2*(e.pageY-this.$el.offset().top)/this.$el.height());
-            return;
-        }
+//        if (this.appState.get("extrudeMode") && this.mouseIsDown && this.extrudeVisualizer.getMeshNum()>0){
+//            this.extrudeVisualizer.dragHandle(1-2*(e.pageY-this.$el.offset().top)/this.$el.height());
+//            return;
+//        }
 
         //make projection vector
         var vector = new THREE.Vector2(2*(e.pageX-this.$el.offset().left)/this.$el.width()-1, 1-2*(e.pageY-this.$el.offset().top)/this.$el.height());
@@ -118,19 +107,19 @@ ThreeView = Backbone.View.extend({
         //check if we're intersecting anything
         var intersections = this.mouseProjection.intersectObjects(this.model.objects, true);
         if (intersections.length == 0) {
-            this.currentIntersectedObject == null;
+            this.currentIntersectedObject = null;
             this._hideHighlighter();
             return;
         }
 
         this.currentIntersectedObject = intersections[0].object;
 
-        if (this.deleteMode && this.mouseIsDown){
+        if (this.appState.get("deleteMode") && this.mouseIsDown){
             this._addRemoveVoxel();
             return;
         }
 
-        if (this.extrudeMode && this.mouseIsDown){
+        if (this.appState.get("extrudeMode") && this.mouseIsDown){
             if (!this.highlighter.visible) return;
             this.extrudeVisualizer.makeMeshFromProfile([this.highlighter]);
             return;
@@ -157,14 +146,14 @@ ThreeView = Backbone.View.extend({
             (new THREE.Vector3()).addVectors(vertices[intersection.b], position), (new THREE.Vector3()).addVectors(vertices[intersection.c], position)];
         this.highlighter.geometry.verticesNeedUpdate = true;
 
-        if (this.mouseIsDown && this.shiftIsDown) this._addRemoveVoxel();
+        if (this.mouseIsDown && this.appState.get("shift")) this._addRemoveVoxel();
 
         window.three.render();
     },
 
     _addRemoveVoxel: function(){
 
-        if (this.deleteMode){
+        if (this.appState.get("deleteMode")){
             if (this.currentIntersectedObject === this.basePlane) return;
             this.lattice.removeCell(this.currentIntersectedObject);
         } else {