diff --git a/js/fea/DmaCell.js b/js/fea/DmaCell.js
index a349f0daedafc53bbc2a5fddc8ca54ff74d86045..e357a8045b2230d0d8706861dac5607aff14c8fd 100644
--- a/js/fea/DmaCell.js
+++ b/js/fea/DmaCell.js
@@ -165,6 +165,9 @@ DMACell.prototype.destroy = function(){
     unitTetraCellGeo.applyMatrix(new THREE.Matrix4().makeRotationX((Math.PI-Math.atan(2*Math.sqrt(2)))/2));
     unitTetraCellGeo.applyMatrix(new THREE.Matrix4().makeTranslation(0,0,Math.sqrt(3/8)-1/Math.sqrt(6)));
 
+    var unitTetraCellGeoUpsideDown = unitTetraCellGeo.clone();
+    unitTetraCellGeoUpsideDown.applyMatrix(new THREE.Matrix4().makeRotationX(Math.PI));
+
     function DMATetraFaceCell(indices, scale, lattice){
         DMACell.call(this, indices, scale, lattice, true);
     }
@@ -176,8 +179,8 @@ DMACell.prototype.destroy = function(){
 
     DMATetraFaceCell.prototype._buildCellMesh = function(zIndex){//abstract mesh representation of cell
         var mesh;
-        mesh = THREE.SceneUtils.createMultiMaterialObject(unitTetraCellGeo, cellMaterials);
-        if (zIndex%2 !=0) mesh.rotateX(Math.PI);
+        if (zIndex%2 ==0) mesh = THREE.SceneUtils.createMultiMaterialObject(unitTetraCellGeo, cellMaterials);
+        else mesh = THREE.SceneUtils.createMultiMaterialObject(unitTetraCellGeoUpsideDown, cellMaterials);
         if (Math.abs(zIndex%4) == 2 || Math.abs(zIndex%4) == 3) mesh.rotateZ(Math.PI/3);
 
         mesh.myParent = this;//we need a reference to this instance from the mesh for intersection selection stuff
@@ -189,9 +192,12 @@ DMACell.prototype.destroy = function(){
 
         var direction = face.normal;
         if (face.normal.z<0.99) direction = null;//only highlight horizontal faces
-
-        var position = dmaGlobals.lattice.getPositionForIndex(this.indices);
-        position.z += dmaGlobals.lattice.zScale()/2;
+        var index = _.clone(this.indices);
+        index.z = Math.floor(index.z/2);
+        index.x = Math.floor(index.x/3);
+        index.y = Math.floor(index.y/2);
+        var position = dmaGlobals.lattice.getInvCellPositionForIndex(index);
+        position.z += dmaGlobals.lattice.zScale();
         return {index: _.clone(this.indices), direction:direction, position:position};
     };
 
@@ -208,8 +214,8 @@ DMACell.prototype.destroy = function(){
 
     DMATetraEdgeCell.prototype._buildCellMesh = function(zIndex){//abstract mesh representation of cell
         var mesh;
-        mesh = THREE.SceneUtils.createMultiMaterialObject(unitTetraCellGeo, cellMaterials);
-        if (zIndex%2 !=0) mesh.rotateX(Math.PI);
+        if (zIndex%2 ==0) mesh = THREE.SceneUtils.createMultiMaterialObject(unitTetraCellGeo, cellMaterials);
+        else mesh = THREE.SceneUtils.createMultiMaterialObject(unitTetraCellGeoUpsideDown, cellMaterials);
         mesh.myParent = this;//we need a reference to this instance from the mesh for intersection selection stuff
         dmaGlobals.three.sceneAdd(mesh, "inverseCell");
         return mesh;
diff --git a/js/menus/LatticeMenuView.js b/js/menus/LatticeMenuView.js
index 1a6cbbe41001c5712693d03d6dbf135100139fb2..daf20d0e4815e18edb75a25ad1e6ec9c50fc68eb 100644
--- a/js/menus/LatticeMenuView.js
+++ b/js/menus/LatticeMenuView.js
@@ -148,14 +148,15 @@ LatticeMenuView = Backbone.View.extend({
         </label><br/><br/>\
         <label class="checkbox">\
             <input type="checkbox"  <% if (inverseMode) { %> checked="checked" <% } %> value="" id="showInverse" data-toggle="checkbox" class="custom-checkbox"><span class="icons"><span class="icon-unchecked"></span><span class="icon-checked"></span></span>\
-            Show Inverse Geometry\
+            Show Inverse Geometry (hold "i" key)\
         </label><br/><br/>\
         Scale:&nbsp;&nbsp;<input id="scaleSlider" data-slider-id="ex1Slider" type="text" data-slider-min="1" data-slider-max="100" data-slider-step="0.1" data-slider-value="<%= scale %>"/>\
         <br/><input id="latticeScale" value="<%= scale %>" placeholder="enter scale" class="form-control" type="text"><br/>\
         Num Cells:&nbsp;&nbsp;<%= numCells %><br/>\
         <br/>\
         <a href="#" id="latticeMenuClearCells" class=" btn btn-block btn-lg btn-default">Clear All Cells</a><br/>\
-        hint: click to create cells, shift+drag to create a lot of cells, d+click to delete cells\
+        hint: click to create cells, shift+drag to create a lot of cells, d+click to delete cells<br/>\
+        hold "p" key to see parts\
         ')
 
 //    <label class="checkbox" for="invertGeo">\
diff --git a/js/models/AppState.js b/js/models/AppState.js
index 4d5fcda428336ce763d4178af3e92f7e377afd35..dabe3796b8c2eb4ef589c4ad7bc5378169924e4d 100644
--- a/js/models/AppState.js
+++ b/js/models/AppState.js
@@ -56,6 +56,7 @@ AppState = Backbone.Model.extend({
         this.listenTo(this, "change:currentTab", this._updateCellMode);
 
         this.lattice = options.lattice;//this doesn't need to be tracked for changes
+        this.downKeys = {};//track keypresses to prevent repeat keystrokeson hold
 
         this.set("menuWrapper", new MenuWrapper({model: this}));
     },
@@ -103,6 +104,12 @@ AppState = Backbone.Model.extend({
         var state = e.data.state;
         var currentTab = this.get("currentTab");
 
+        if (state) {
+            if (this.downKeys[e.keyCode]) return;
+            this.downKeys[e.keyCode] = true;
+        } else this.downKeys[e.keyCode] = null;
+
+//        console.log(e.keyCode);
         switch(e.keyCode){
             case 16://shift
                 e.preventDefault();
@@ -117,11 +124,13 @@ AppState = Backbone.Model.extend({
 //                if (currentTab != "sketch") return;
                 this.set("extrudeMode", state);
                 break;
-            case 76://l lattice mode
-                this.set("cellMode", "cell");
-                break;
             case 80://p part mode
-                this.set("cellMode", "part");
+                var cellMode = this.lattice.get("cellMode");
+                if (cellMode == "part") this.lattice.set("cellMode", "cell");
+                else if (cellMode == "cell") this.lattice.set("cellMode", "part");
+                break;
+            case 73://i inverse mode
+                this.lattice.set("inverseMode", !this.lattice.get("inverseMode"));
                 break;
             default:
                 break;
diff --git a/js/models/Lattice.js b/js/models/Lattice.js
index 20acc0d11a59f6a75a3af76f20d71836d2c6be1c..01288ef00f134c714f196d8cfde3cf520c9c443b 100644
--- a/js/models/Lattice.js
+++ b/js/models/Lattice.js
@@ -524,7 +524,11 @@ Lattice = Backbone.Model.extend({
 
             index = _.clone(index);
             index.z*=2;
-            var inverseIndicesToAdd = this._getInverseIndicesToAdd(index, oddZ);
+
+            var z0 = 0;
+            if (oddZ) z0 = 1;
+
+            var inverseIndicesToAdd = this._getInverseIndicesToAdd(index, z0);
 
             var invCells = this.get("inverseCells");
             var scale = this.get("scale");
@@ -539,10 +543,9 @@ Lattice = Backbone.Model.extend({
             });
         },
 
-        _getInverseIndicesToAdd: function(index, oddZ){
+        _getInverseIndicesToAdd: function(index, z0){
 
-            var z0 = 0;
-            if (oddZ) z0 = 1;
+            if (this.get("connectionType") == "edge") z0 = 0;
             var z1 = Math.abs(z0-1);
 
             var inverseIndicesToAdd;
@@ -603,8 +606,15 @@ Lattice = Backbone.Model.extend({
             var scale = this.get("scale");
             var yIndex = Math.floor(absPosition.y/this.yScale(scale));
             if (yIndex%2 != 0) absPosition.x += this.xScale(scale)/2;
+            var yScale = scale/Math.sqrt(3);
+            var index = this._indexForPosition(absPosition);
+            if (index.z%3 == 1) {
+                absPosition.x -= this.xScale(scale)/2;
+                absPosition.y += yScale/2;
+            } else if (index.z%3 == 2){
+                absPosition.y += yScale;
+            }
             var index = this._indexForPosition(absPosition);
-            if (index.z%2 == 1) index.y += 1;
             return index;
         },
 
@@ -636,33 +646,6 @@ Lattice = Backbone.Model.extend({
             return new DMATetraEdgeCell(indices, scale, this);
         },
 
-        _getInverseIndicesToAdd: function(index){
-            var inverseIndicesToAdd;
-            if (index.y%2 == 0){
-
-                inverseIndicesToAdd = [
-                    this._add(index, {x:0,y:0,z:0}),
-                    this._add(index, {x:0,y:1,z:0}),
-                    this._add(index, {x:1,y:1,z:0}),
-
-                    this._add(index, {x:0,y:0,z:1}),
-                    this._add(index, {x:0,y:1,z:1}),
-                    this._add(index, {x:1,y:0,z:1})
-                ];
-            } else {
-                inverseIndicesToAdd = [
-                    this._add(index, {x:0,y:0,z:0}),
-                    this._add(index, {x:-1,y:1,z:0}),
-                    this._add(index, {x:0,y:1,z:0}),
-
-                    this._add(index, {x:-1,y:0,z:1}),
-                    this._add(index, {x:0,y:1,z:1}),
-                    this._add(index, {x:0,y:0,z:1})
-                ];
-            }
-            return inverseIndicesToAdd;
-        },
-
         getInvCellPositionForIndex: function(index){
 
             var scale = this.get("scale");
diff --git a/js/models/ThreeModel.js b/js/models/ThreeModel.js
index 2c47785a73e47fc2766f8176b1bbbbad140f82a3..1e7a3197f084234689eaaf7a67cdd98fc25daaa7 100644
--- a/js/models/ThreeModel.js
+++ b/js/models/ThreeModel.js
@@ -11,7 +11,7 @@ function ThreeModel(){
 
     //store all meshes to highlight
     var cells = [];
-    var invCells = [];
+    var inverseCells = [];
     var parts = [];
     var basePlane = [];
 
@@ -56,7 +56,7 @@ function ThreeModel(){
         if (type == "cell"){
             cells.push(object.children[0]);
         } else if (type == "inverseCell"){
-            invCells.push(object.children[0]);
+            inverseCells.push(object.children[0]);
         } else if (type == "part"){
             parts.push(object);
         } else if (type == "basePlane"){
@@ -71,7 +71,7 @@ function ThreeModel(){
         if (type == "cell"){
             cells.splice(cells.indexOf(objectToRemove.children[0]), 1);
         } else if (type == "inverseCell"){
-            invCells.splice(invCells.indexOf(objectToRemove.children[0]), 1);
+            inverseCells.splice(inverseCells.indexOf(objectToRemove.children[0]), 1);
         } else if (type == "part"){
             parts.splice(parts.indexOf(objectToRemove), 1);
         } else if (type == "basePlane"){
@@ -88,11 +88,11 @@ function ThreeModel(){
         _.each(parts, function(part){
             scene.remove(part);
         });
-        _.each(invCells, function(cell){
+        _.each(inverseCells, function(cell){
             scene.remove(cell);
         });
         cells.splice(0, cells.length);
-        invCells.splice(0, invCells.length);
+        inverseCells.splice(0, inverseCells.length);
         parts.splice(0, parts.length);
     }
 
@@ -116,7 +116,7 @@ function ThreeModel(){
         domElement: renderer.domElement,
         camera: camera,
         cells: cells,
-        invCells: invCells,
+        inverseCells: inverseCells,
         parts: parts,
         basePlane: basePlane,
         removeAllCells: removeAllCells