diff --git a/css/main.css b/css/main.css
index fcacc16b1c500e40a4800f6242fb73a45cef83ba..f96e21000a0c414fd223b3e24d2ee1f054aadd56 100644
--- a/css/main.css
+++ b/css/main.css
@@ -83,7 +83,7 @@ nav .btn {
     z-index: 2;
     position: absolute;
     display: block;
-    background-color: rgba(255,255,255,0.7);
+    background-color: rgba(255,255,255,0.8);
     right: 0px;
     overflow:hidden;
 }
diff --git a/js/fea/DmaCell.js b/js/fea/DmaCell.js
index 08d23a57cd518fdb983ab871db8bc9bdf394078b..1e4f81ad9c016841e727e212785615da00b370c7 100644
--- a/js/fea/DmaCell.js
+++ b/js/fea/DmaCell.js
@@ -152,7 +152,7 @@ DMACell.prototype.destroy = function(){
         return mesh;
     };
 
-    DMASideOctaCell.prototype.getHighlighterVertices = function(face){
+    DMASideOctaCell.prototype.calcHighlighterPosition = function(face){
         if (face.normal.z<0.99) return null;//only highlight horizontal faces
 
         //the vertices don't include the position transformation applied to cell.  Add these to create highlighter vertices
@@ -262,20 +262,17 @@ DMACell.prototype.destroy = function(){
         return mesh;
     };
 
-    DMACubeCell.prototype.getHighlighterVertices = function(face){
-//        if (face.normal.z<0.99) return null;//only highlight horizontal faces
+    DMACubeCell.prototype.calcHighlighterPosition = function(face){
 
-        //the vertices don't include the position transformation applied to cell.  Add these to create highlighter vertices
-        var mesh = this.cellMesh.children[0];
-        var vertices = mesh.geometry.vertices;
-        var newVertices = [vertices[face.a].clone(), vertices[face.b].clone(), vertices[face.c].clone(), new THREE.Vector3(0,0,0)];
-        var scale = this.cellMesh.scale.x;
-        var position = (new THREE.Vector3()).setFromMatrixPosition(mesh.matrixWorld);
-        _.each(newVertices, function(vertex){//apply scale
-            vertex.multiplyScalar(scale);
-            vertex.add(position);
+        var direction = face.normal;
+//        if (direction.z<0.99) direction = null;//only highlight horizontal faces
+
+        var position = dmaGlobals.lattice.getPositionForIndex(this.indices);
+        var scale = dmaGlobals.lattice.xScale();
+        _.each(_.keys(position), function(key){
+            position[key] += direction[key]*scale/2;
         });
-        return newVertices;
+        return {index: _.clone(this.indices), direction:direction, position:position};
     }
 
     self.DMACubeCell = DMACubeCell;
diff --git a/js/models/AppState.js b/js/models/AppState.js
index 16ac7e4b111f55b68341c1f37a6ec7218e0057e5..775aa210b334611d082810a1792f1cae45bda6b9 100644
--- a/js/models/AppState.js
+++ b/js/models/AppState.js
@@ -35,7 +35,7 @@ AppState = Backbone.Model.extend({
                 face: {triangle:"Triangle"},
                 edge: {triangle:"Triangle"},
                 edgeRot: {triangle:"Triangle"},
-                vertex:{square:"Square", xShape:"X"}
+                vertex: null//{square:"Square", xShape:"X"}
             },
             cube:{
                 face: null
diff --git a/js/models/BasePlane.js b/js/models/BasePlane.js
index c52308adae50c84e05b2c8641da022020cdc9ce1..0ad8668d6819ab19fd8c5f9ca6a1a996f8e4562b 100644
--- a/js/models/BasePlane.js
+++ b/js/models/BasePlane.js
@@ -172,7 +172,7 @@ OctaBasePlane = BasePlane.extend({
         geometry.verticesNeedUpdate = true;
     },
 
-    getHighlighterVertices: function(face){
+    calcHighlighterPosition: function(face, position){
         //the vertices don't include the position transformation applied to cell.  Add these to create highlighter vertices
         var mesh = this.get("mesh")[0];
         var vertices = mesh.geometry.vertices;
@@ -183,7 +183,7 @@ OctaBasePlane = BasePlane.extend({
             vertex.multiplyScalar(scale);
             vertex.add(position);
         });
-        return newVertices;
+        return {index: {}, direction: new THREE.Vector3(0,0,1), position:position};
     }
 
 });
@@ -232,18 +232,12 @@ SquareBasePlane = BasePlane.extend({
         dmaGlobals.three.render();
     },
 
-    getHighlighterVertices: function(face, position){
-        //the vertices don't include the position transformation applied to cell.  Add these to create highlighter vertices
+    calcHighlighterPosition: function(face, position){
         var index = dmaGlobals.lattice.getIndexForPosition(position);
-        index.z += 1;
-        var scale = dmaGlobals.lattice.get("scale");
-        var vertices = [];
-        vertices.push(new THREE.Vector3(index.x*scale, index.y*scale, index.z*scale));
-        vertices.push(new THREE.Vector3((index.x+1)*scale, index.y*scale, index.z*scale));
-        vertices.push(new THREE.Vector3((index.x+1)*scale, (index.y+1)*scale, index.z*scale));
-        vertices.push(new THREE.Vector3(index.x*scale, (index.y+1)*scale, index.z*scale));
-
-        return vertices;
+        index.z = this.get("zIndex") - 1;//pretend we're on the top of the cell underneath the baseplane
+        var position = dmaGlobals.lattice.getPositionForIndex(index);
+        position.z += dmaGlobals.lattice.zScale()/2;
+        return {index: index, direction: new THREE.Vector3(0,0,1), position:position};
     }
 
 
diff --git a/js/models/Lattice.js b/js/models/Lattice.js
index 70c12184e739088be2b16ee9b30f873269d5f983..ad73131757418a2e1916fc864883984019f60d34 100644
--- a/js/models/Lattice.js
+++ b/js/models/Lattice.js
@@ -66,6 +66,14 @@ Lattice = Backbone.Model.extend({
 
     },
 
+    _indexForPosition: function(absPosition){
+            var position = {};
+            position.x = Math.floor(absPosition.x/this.xScale());
+            position.y = Math.floor(absPosition.y/this.yScale());
+            position.z = Math.floor(absPosition.z/this.zScale());
+            return position;
+        },
+
     removeCellAtIndex: function(indices){
 
         var index = this._subtract(indices, this.get("cellsMin"));
@@ -106,6 +114,7 @@ Lattice = Backbone.Model.extend({
     ////////////////////////////////////////////////////////////////////////////////////
 
     subtractMesh: function(mesh){
+        //todo this is specific to octa face
 
         var scale = this.getScale();
         var yscale = scale/2*Math.sqrt(3);
@@ -270,6 +279,7 @@ Lattice = Backbone.Model.extend({
     _scaleDidChange: function(){
         var scale = this.get("scale");
         this.get("basePlane").updateScale(scale);
+        this.get("highlighter").updateScale(scale);
         this._iterCells(this.get("cells"), function(cell){
             if (cell) cell.updateForScale(scale);
         });
@@ -320,10 +330,6 @@ Lattice = Backbone.Model.extend({
         });
     },
 
-    getScale: function(){
-        return this.get("scale");
-    },
-
 ////////////////////////////////////////////////////////////////////////////////////////
 //////////////////////////////FACE CONN OCTA LATTICE////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////////////////////
@@ -337,7 +343,7 @@ Lattice = Backbone.Model.extend({
             this.listenTo(this, "change:columnSeparation", this._changeColSeparation);
 
             this.set("basePlane", new OctaBasePlane({scale:this.get("scale")}));
-            this.set("highlighter", new OctaFaceHighlighter());
+            this.set("highlighter", new OctaFaceHighlighter({scale:this.get("scale")}));
             this.set("columnSeparation", 0.0);
         },
 
@@ -352,24 +358,28 @@ Lattice = Backbone.Model.extend({
         },
 
         getIndexForPosition: function(absPosition){
+            var position = this._indexForPosition(absPosition);
+            if (position.z%2 == 1) position.y += 1;
+            return position;
+        },
 
-            //calc indices in cell matrix
+        getScale: function(){//todo get rid of this
+            return this.get("scale")*(1.0+2*this.get("columnSeparation"));
+        },
+
+        xScale: function(){
             var scale = this.get("scale");
             var colSep = this.get("columnSeparation");
-            var latticeScale = scale*(1+2*colSep);
-            var octHeight = 2*scale/Math.sqrt(6);
-            var triHeight = latticeScale/2*Math.sqrt(3);
-            var position = {};
-            position.x = Math.round(absPosition.x/latticeScale);
-            position.y = Math.round(absPosition.y/triHeight);
-            position.z = Math.round(absPosition.z/octHeight)-1;
-            if (position.z%2 == 1) position.y += 1;
+            return scale*(1+2*colSep);
+        },
 
-            return position;
+        yScale: function(){
+            return this.xScale()/2*Math.sqrt(3);
         },
 
-        getScale: function(){
-            return this.get("scale")*(1.0+2*this.get("columnSeparation"));
+        zScale: function(){
+            var scale = this.get("scale");
+            return 2*scale/Math.sqrt(6);
         },
 
         _makeCellForLatticeType: function(indices, scale){
@@ -377,14 +387,12 @@ Lattice = Backbone.Model.extend({
         },
 
         _undo: function(){//remove all the mixins, this will help with debugging later
-            this._initLatticeType = null;
-            this._changeColSeparation = null;
-            this.getIndexForPosition = null;
-            this.getScale = null;
-            this._makeCellForLatticeType = null;
             this.stopListening(this, "columnSeparation");
             this.set("columnSeparation", null);
-            this._undo = null;
+            var self = this;
+            _.each(_.keys(this.OctaFaceLattice), function(key){
+                self[key] = null;
+            });
         }
 
     },
@@ -401,7 +409,7 @@ Lattice = Backbone.Model.extend({
             this.listenTo(this, "change:columnSeparation", this._changeColSeparation);
 
             this.set("basePlane", new OctaBasePlane({scale:this.get("scale")}));
-            this.set("highlighter", new OctaFaceHighlighter());
+            this.set("highlighter", new OctaFaceHighlighter({scale:this.get("scale")}));
             this.set("columnSeparation", 0.0);
         },
 
@@ -416,19 +424,8 @@ Lattice = Backbone.Model.extend({
         },
 
         getIndexForPosition: function(absPosition){
-
-            //calc indices in cell matrix
-            var scale = this.get("scale");
-            var colSep = this.get("columnSeparation");
-            var latticeScale = scale*(1+2*colSep);
-            var octHeight = 2*scale/Math.sqrt(6);
-            var triHeight = latticeScale/2*Math.sqrt(3);
-            var position = {};
-            position.x = Math.round(absPosition.x/latticeScale);
-            position.y = Math.round(absPosition.y/triHeight);
-            position.z = Math.round(absPosition.z/octHeight);
+            var position = this._indexForPosition(absPosition);
             if (position.z%2 == 1) position.y += 1;
-
             return position;
         },
 
@@ -436,19 +433,32 @@ Lattice = Backbone.Model.extend({
             return this.get("scale")*(1.0+2*this.get("columnSeparation"));
         },
 
+        xScale: function(){
+            var scale = this.get("scale");
+            var colSep = this.get("columnSeparation");
+            return scale*(1+2*colSep);
+        },
+
+        yScale: function(){
+            return this.xScale()/2*Math.sqrt(3);
+        },
+
+        zScale: function(){
+            var scale = this.get("scale");
+            return 2*scale/Math.sqrt(6);
+        },
+
         _makeCellForLatticeType: function(indices, scale){
             return new DMASideOctaCell(indices, scale, this);
         },
 
         _undo: function(){//remove all the mixins, this will help with debugging later
-            this._initLatticeType = null;
-            this._changeColSeparation = null;
-            this.getIndexForPosition = null;
-            this.getScale = null;
-            this._makeCellForLatticeType = null;
             this.stopListening(this, "columnSeparation");
             this.set("columnSeparation", null);
-            this._undo = null;
+            var self = this;
+            _.each(_.keys(this.OctaEdgeLattice), function(key){
+                self[key] = null;
+            });
         }
 
     },
@@ -465,22 +475,11 @@ Lattice = Backbone.Model.extend({
             //bind events
 
             this.set("basePlane", new SquareBasePlane({scale:this.get("scale")}));
-            this.set("highlighter", new CubeHighlighter());
+            this.set("highlighter", new OctaVertexHighlighter({scale:this.get("scale")}));
         },
 
         getIndexForPosition: function(absPosition){
-
-            //calc indices in cell matrix
-            var scale = this.get("scale");
-            var octHeight = 2*scale/Math.sqrt(6);
-            var triHeight = scale/2*Math.sqrt(3);
-            var position = {};
-            position.x = Math.round(absPosition.x/latticeScale);
-            position.y = Math.round(absPosition.y/triHeight);
-            position.z = Math.round(absPosition.z/octHeight)-1;
-            if (position.z%2 == 1) position.y += 1;
-
-            return position;
+            return this._indexForPosition(absPosition);
         },
 
 
@@ -488,18 +487,27 @@ Lattice = Backbone.Model.extend({
             return this.get("scale");
         },
 
+        xScale: function(){
+            return this.get("scale");
+        },
+
+        yScale: function(){
+            return this.xScale();
+        },
+
+        zScale: function(){
+            return this.xScale();
+        },
+
         _makeCellForLatticeType: function(indices, scale){
             return new DMASideOctaCell(indices, scale, this);
         },
 
         _undo: function(){//remove all the mixins, this will help with debugging later
-            this._initLatticeType = null;
-            this.getIndexForPosition = null;
-            this.getScale = null;
-            this._makeCellForLatticeType = null;
-            this.stopListening(this, "columnSeparation");
-            this.set("columnSeparation", null);
-            this._undo = null;
+            var self = this;
+            _.each(_.keys(this.OctaVertexLattice), function(key){
+                self[key] = null;
+            });
         }
 
     },
@@ -517,38 +525,47 @@ Lattice = Backbone.Model.extend({
             //bind events
 
             this.set("basePlane", new SquareBasePlane({scale:this.get("scale")}));
-            this.set("highlighter", new CubeHighlighter());
+            this.set("highlighter", new CubeHighlighter({scale:this.get("scale")}));
         },
 
         getIndexForPosition: function(absPosition){
-
-            //calc indices in cell matrix
-            var scale = this.get("scale");
-            var index = {};
-            index.x = Math.round((absPosition.x-scale/2)/scale);
-            index.y = Math.round((absPosition.y-scale/2)/scale);
-            index.z = Math.round(absPosition.z/scale)-1;
-
-            return index;
+            return this._indexForPosition(absPosition);
         },
 
+        getPositionForIndex: function(index){
+            var scale = this.xScale();
+            var position = _.clone(index);
+            _.each(_.keys(position), function(key){
+                position[key] = (position[key]+0.5)*scale;
+            })
+            return position;
+        },
 
         getScale: function(){
             return this.get("scale");
         },
 
+        xScale: function(){
+            return this.get("scale");
+        },
+
+        yScale: function(){
+            return this.xScale();
+        },
+
+        zScale: function(){
+            return this.xScale();
+        },
+
         _makeCellForLatticeType: function(indices, scale){
             return new DMACubeCell(indices, scale, this);
         },
 
         _undo: function(){//remove all the mixins, this will help with debugging later
-            this._initLatticeType = null;
-            this.getIndexForPosition = null;
-            this.getScale = null;
-            this._makeCellForLatticeType = null;
-            this.stopListening(this, "columnSeparation");
-            this.set("columnSeparation", null);
-            this._undo = null;
+            var self = this;
+            _.each(_.keys(this.CubeLattice), function(key){
+                self[key] = null;
+            });
         }
 
     }
diff --git a/js/threeViews/Highlighter.js b/js/threeViews/Highlighter.js
index 1ff9dd41326ce2ada99d1469774326687e244067..d4d2b14a5e2e1c2173298d1bcf3d52a9c98df23a 100644
--- a/js/threeViews/Highlighter.js
+++ b/js/threeViews/Highlighter.js
@@ -6,8 +6,10 @@ Highlighter = Backbone.View.extend({
 
     mesh: null,
     highlightedObject: null,
+    index: null,
+    direction: null,
 
-    initialize: function(){
+    initialize: function(options){
 
         var geometry = this._makeGeometry();
         geometry.dynamic = true;
@@ -21,6 +23,7 @@ Highlighter = Backbone.View.extend({
             }));
 
         dmaGlobals.three.sceneAdd(this.mesh, null);
+        this.updateScale(options.scale);
         this.hide();
 
         //bind events
@@ -50,64 +53,83 @@ Highlighter = Backbone.View.extend({
         return this.mesh.visible;
     },
 
+    setNothingHighlighted: function(){
+        this.highlightedObject = null;
+        this.index = null;
+        this.direction = null;
+        this.hide();
+    },
+
     highlight: function(intersection){
         if (!intersection.object) return;
-        var highlightable = intersection.object;
-        if (!(highlightable.parent instanceof THREE.Scene)) highlightable = highlightable.parent;//cell mesh parent is object3d
-        if (!highlightable.myParent) console.warn("no parent for highlightable object");
+        var highlighted = intersection.object;
+        if (!(highlighted.parent instanceof THREE.Scene)) highlighted = highlighted.parent;//cell mesh parent is object3d
+        if (!highlighted.myParent) console.warn("no parent for highlighted object");
+
+        this.highlightedObject = highlighted.myParent;
 
-        this.highlightedObject = highlightable.myParent;
-        var newVertices = highlightable.myParent.getHighlighterVertices(intersection.face, intersection.point);
-        if (!newVertices) {
+        var highlightedPos = highlighted.myParent.calcHighlighterPosition(intersection.face, intersection.point);
+        this.index = highlightedPos.index;
+        if (!highlightedPos.direction) {//may be hovering over a face that we shouldn't highlight
             this.hide();
             return;
         }
+        this.direction = highlightedPos.direction;
+        this._setPosition(highlightedPos.position, this.direction);//position of center point
 
-        var geometry = this.mesh.geometry;
-        if (geometry.vertices.length != newVertices.length) console.warn("vertices array is changing size");
-        geometry.vertices = newVertices;
-        geometry.verticesNeedUpdate = true;
-//        this.mesh.geometry.normalsNeedUpdate = true;
-//        this.mesh.geometry.computeFaceNormals();
-//        this.mesh.geometry.computeVertexNormals();
-        geometry.computeBoundingSphere();
         this.show(true);
     },
 
+    ///////////////////////////////////////////////////////////////////////////////////
+    /////////////////////////////POSITION/SCALE////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    updateScale: function(scale){
+        this.mesh.scale.set(scale, scale, scale);
+    },
+
+    _setPosition: function(position, direction){
+        this.mesh.position.set(position.x, position.y, position.z);
+        this.mesh.rotation.set(direction.y*Math.PI, direction.x*Math.PI, 0);
+//        this.mesh.updateMatrix();
+    },
+
     ///////////////////////////////////////////////////////////////////////////////////
     /////////////////////////////ADD REMOVE////////////////////////////////////////////
     ///////////////////////////////////////////////////////////////////////////////////
 
-    //todo this could be more than just z additions
-    _getNextCellPosition: function(index){//add one to z index
-        index.z += 1;
-        return index;
+    _getNextCellPosition: function(){//add direction vector to current index
+        var newIndex = _.clone(this.index);
+        var direction = this.direction;
+        _.each(_.keys(newIndex), function(key){
+            newIndex[key] += direction[key];
+        });
+        return newIndex;
     },
 
     addRemoveVoxel: function(shouldAdd){
 
         if (shouldAdd){
             if (!this.isVisible() || !this.highlightedObject) return;
-            dmaGlobals.lattice.addCellAtIndex(this._getNextCellPosition(this.highlightedObject.getIndex(this.mesh)));
+            dmaGlobals.lattice.addCellAtIndex(this._getNextCellPosition());
         } else {
             if (!this.highlightedObject) return;
             if (!(this.highlightedObject instanceof DMACell)) return;
             dmaGlobals.lattice.removeCell(this.highlightedObject);
         }
-        this.hide();
-        this.highlightedObject = null;
+        this.setNothingHighlighted();
     },
 
     destroy: function(){
+        this.setNothingHighlighted();
         dmaGlobals.three.sceneRemove(this.mesh, null);
         this.mesh = null;
-        this.highlightedObject = null;
         this.stopListening();
     }
 });
 
 ///////////////////////////////////////////////////////////////////////////////////
-/////////////////////////////OCTA FACE/////////////////////////////////////////////
+/////////////////////////////////OCTA//////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////
 
 OctaFaceHighlighter = Highlighter.extend({
@@ -124,6 +146,14 @@ OctaFaceHighlighter = Highlighter.extend({
 
 });
 
+OctaVertexHighlighter = Highlighter.extend({
+
+    _makeGeometry: function(){
+        return new THREE.SphereGeometry(1);
+    }
+
+});
+
 ///////////////////////////////////////////////////////////////////////////////////
 /////////////////////////////CUBE /////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////
@@ -132,11 +162,7 @@ CubeHighlighter = Highlighter.extend({
 
     _makeGeometry: function(){
 
-        var geometry = new THREE.Geometry();
-        //can't change size of faces or vertices buffers dynamically
-        geometry.vertices = [new THREE.Vector3(0,0,0), new THREE.Vector3(0,0,0), new THREE.Vector3(0,0,0), new THREE.Vector3(0,0,0)];
-        geometry.faces = [new THREE.Face3(0,1,2), new THREE.Face3(0,2,3)];
-
+        var geometry = new THREE.BoxGeometry(1,1,0.01);
         return geometry;
     }
 
diff --git a/js/threeViews/ThreeView.js b/js/threeViews/ThreeView.js
index 3fd1c6d1cdb32f1bf75d46c6b72416e898bef42a..a441ca836fa2415f281a4067c320390fac0718aa 100644
--- a/js/threeViews/ThreeView.js
+++ b/js/threeViews/ThreeView.js
@@ -62,7 +62,7 @@ ThreeView = Backbone.View.extend({
     ////////////////////////////////////////////////////////////////////////////////
 
     _mouseOut: function(){
-        this.highlighter.hide();
+        this.highlighter.setNothingHighlighted();
         this._setNoPartIntersections();
     },
 
@@ -79,7 +79,7 @@ ThreeView = Backbone.View.extend({
     _mouseMoved: function(e){
 
         if (this.mouseIsDown && this.controls.enabled) {//in the middle of a camera move
-            this.highlighter.hide();
+            this.highlighter.setNothingHighlighted();
             this._setNoPartIntersections();
             return;
         }
@@ -95,7 +95,7 @@ ThreeView = Backbone.View.extend({
 
         var intersections = this.mouseProjection.intersectObjects(this.model.cells.concat(this.model.basePlane), true);
         if (intersections.length == 0) {//no intersections
-            this.highlighter.hide();
+            this.highlighter.setNothingHighlighted();
             this._setNoPartIntersections();
             return;
         }