diff --git a/index.html b/index.html
index e27bfcdca07ffeba0de76f1c2299f3e8437e9273..a905ae10e8e5c38e9888e468c12ce6026b043479 100644
--- a/index.html
+++ b/index.html
@@ -43,12 +43,18 @@
     <!--fea stuff-->
     <script src="js/fea/DmaNode.js"></script>
     <script src="js/fea/DmaBeam.js"></script>
+
     <script src="js/cell/DmaCell.js"></script>
+    <script src="js/cell/OctaFaceCell.js"></script>
+    <script src="js/cell/OctaEdgeCell.js"></script>
+    <script src="js/cell/OctaRotEdgeCell.js"></script>
+    <script src="js/cell/OctaVertexCell.js"></script>
+
     <script src="js/cell/DMASuperCell.js"></script>
     <script src="js/cell/DMACellFreeform.js"></script>
-    <script src="js/cell/DmaCellOcta.js"></script>
     <script src="js/cell/DmaCellTetra.js"></script>
     <script src="js/cell/DmaCellOther.js"></script>
+
     <script src="js/fea/DmaPart.js"></script>
 
     <!--models-->
diff --git a/js/cell/DMACell.js b/js/cell/DMACell.js
new file mode 100644
index 0000000000000000000000000000000000000000..0e01d770131f84969c9e1b31b6e7f66e71fd78f0
--- /dev/null
+++ b/js/cell/DMACell.js
@@ -0,0 +1,245 @@
+/**
+ * Created by aghassaei on 5/26/15.
+ */
+
+
+var cellMaterial = new THREE.MeshNormalMaterial();
+var wireframeMaterial = new THREE.MeshBasicMaterial({color:0x000000, wireframe:true});
+
+function DMACell(indices){
+    this.indices = indices;
+    this.object3D = this._translateCell(this._rotateCell(new THREE.Object3D()));
+    this.object3D.myParent = this;//reference to get mouse raycasting back
+    this._buildMesh(this.object3D);
+    globals.three.sceneAdd(this.object3D, this._getSceneType());
+    this.setMode();
+}
+
+
+
+
+
+DMACell.prototype._buildMesh = function(object3D){//called from every subclass
+    var geometry = this._getGeometry();
+    if (!object3D || object3D === undefined) object3D = this.object3D;
+
+    var mesh = new THREE.Mesh(geometry, cellMaterial);
+    mesh.name = "cell";
+    object3D.add(mesh);
+    var wireframe = new THREE.Mesh(geometry, wireframeMaterial);
+    wireframe.name = "cell";
+    object3D.add(wireframe);
+};
+
+DMACell.prototype._rotateCell = function(object3D){
+    return object3D;//by default, no mesh transformations
+};
+
+DMACell.prototype._translateCell = function(object3D){
+    var position = globals.lattice.getPositionForIndex(this.indices);
+    object3D.position.set(position.x, position.y, position.z);
+    return object3D;
+};
+
+
+
+
+
+
+DMACell.prototype._initParts = function(){
+    return [];//override in subclasses
+};
+
+DMACell.prototype.changePartType = function(){//override in subclasses
+};
+
+
+
+
+
+
+DMACell.prototype.setMode = function(mode){
+
+    if (mode === undefined) mode = globals.appState.get("cellMode");
+
+    switch(mode) {
+        case "cell":
+            break;
+        case "part":
+            if (!this.parts) this.parts = this._initParts();
+            break;
+        case "beam":
+            if (!this.beams) this.beams = this._initBeams();
+            break;
+        case "node":
+            if (!this.nodes) this.nodes = this._initNodes();
+            break;
+        case "hide":
+            break;
+    }
+
+    _.each(this.object3D.children, function(child){
+        child.visible = child.name == mode;
+    });
+};
+
+DMACell.prototype.hide = function(){
+    this.object3D.visible = false;
+};
+
+DMACell.prototype.show = function(){
+    this.object3D.visible = true;
+};
+
+DMACell.prototype.setOpacity = function(opacity){
+};
+
+DMACell.prototype._getSceneType = function(){
+    if (this.indices) return "cell";
+    return null;
+};
+
+
+
+
+
+
+
+
+DMACell.prototype.getPosition = function(){
+    return this.object3D.position.clone();
+};
+
+DMACell.prototype.getQuaternion = function(){
+    return this.object3D.quaternion.clone();
+};
+
+DMACell.prototype.getEuler = function(){
+    return this.object3D.rotation.clone();
+};
+
+DMACell.prototype.xScale = function(){
+    return globals.lattice.xScale(0);
+};
+
+DMACell.prototype.yScale = function(){
+    return globals.lattice.yScale(0);
+};
+
+DMACell.prototype.zScale = function(){
+    return globals.lattice.zScale(0);
+};
+
+
+
+
+
+
+DMACell.prototype.destroy = function(){
+    if (this.destroyStarted) return;
+    this.destroyStarted = true;
+    if (this.object3D) {
+        globals.three.sceneRemove(this.object3D, this._getSceneType());
+        this.object3D.myParent = null;
+//            this.object3D.dispose();
+//            geometry.dispose();
+//            material.dispose();
+        this.object3D = null;
+    }
+    this.destroyParts();
+    this.nodes = null;
+    this.beams = null;
+    if (this.superCell) {
+        this.superCell.destroy();
+        this.superCell = null;
+    }
+    this.superCellIndex = null;
+    this.indices = null;
+};
+
+DMACell.prototype.destroyParts = function(){
+    _.each(this.parts, function(part){
+        if (part) part.destroy();
+    });
+    this.parts = null;
+};
+
+DMACell.prototype.toJSON = function(){
+    var data = {
+        indices:this.indices//todo get rid of this and calculate from min and max
+    };
+    if (this.parts) data.parts = this.parts;
+    return data;
+};
+
+
+
+//DMACell.prototype.moveTo = function(position, axis){//used for stock simulations
+//    this.object3D.position[axis] = position;
+//    if (globals.appState.get("cellMode") == "part"){
+//        _.each(this.parts, function(part){
+//            if (part) part.moveTo(position, axis);
+//        });
+//    }
+//};
+//
+//DMACell.prototype.getType = function(){
+//    return null;//only used in freeform layout
+//};
+//
+//DMACell.prototype._initNodes = function(vertices){
+//    var position = this.getPosition();
+//    var orientation = this.getOrientation();
+//    var nodes = [];
+//    for (var i=0;i<vertices.length;i++){
+//        var vertex = vertices[i].clone();
+//        vertex.applyQuaternion(orientation);
+//        vertex.add(position);
+//        nodes.push(new DmaNode(vertex, i));
+//    }
+//    return nodes;
+//};
+//
+//DMACell.prototype.removePart = function(index){
+//    this.parts[index].destroy();
+//    this.parts[index] = null;
+//    var hasAnyParts = false;//check if all parts have been deleted
+//    _.each(this.parts, function(part){
+//        if (part) hasAnyParts = true;
+//    });
+//    if (!hasAnyParts) globals.lattice.removeCell(this);//if all parts are gone, remove cell
+//};
+//
+//DMACell.prototype._initBeams = function(nodes, faces){
+//    var beams = [];
+//    var self = this;
+//    var addBeamFunc = function(index1, index2){
+//        var duplicate = false;
+//        _.each(beams, function(beam){
+//            var index = beam.getIndex();
+//            if (index[0] == index1 && index[1] == index2) duplicate = true;
+//        });
+//        if (duplicate) return;
+//        var diff = nodes[index1].getPosition();
+//        diff.sub(nodes[index2].getPosition());
+//        if (diff.length() > self.getScale()*1.01) return;
+//        if (index2>index1) {
+//            beams.push(new DmaBeam(nodes[index1], nodes[index2], self));
+//        }
+//    };
+//    for (var i=0;i<nodes.length;i++){
+//        _.each(faces, function(face){
+//            if (face.a == i) {
+//                addBeamFunc(i, face.b);
+//                addBeamFunc(i, face.c);
+//            } else if (face.b == i){
+//                addBeamFunc(i, face.a);
+//                addBeamFunc(i, face.c);
+//            } else if (face.c == i){
+//                addBeamFunc(i, face.a);
+//                addBeamFunc(i, face.b);
+//            }
+//        })
+//    }
+//    return beams;
+//};
\ No newline at end of file
diff --git a/js/cell/DmaCell.js b/js/cell/DmaCell.js
deleted file mode 100644
index c6e922bb7b88f6eb057730ecbfecdc72b6b106a4..0000000000000000000000000000000000000000
--- a/js/cell/DmaCell.js
+++ /dev/null
@@ -1,236 +0,0 @@
-/**
- * Created by aghassaei on 1/14/15.
- */
-
-
-//a Cell, a unit piece of the lattice
-
-var cellMaterials = [new THREE.MeshNormalMaterial(),
-        new THREE.MeshBasicMaterial({color:0x000000, wireframe:true})];
-
-function DMACell(indices, cellMode, partType) {
-
-    this.indices = indices;
-    this.mesh = this._buildMesh();
-    this._doMeshTransformations(this.mesh);//some cell types require transformations
-    this._setMeshPosition(this.mesh, this._calcPosition());
-
-    globals.three.sceneAdd(this.mesh,this._sceneType(indices));
-
-    this.draw(cellMode, partType);
-
-    this.hideForStockSimulation = false;
-}
-
-DMACell.prototype._sceneType = function(indices){
-    if (!indices || indices == null || indices === undefined) return null;
-    return "cell";
-};
-
-DMACell.prototype.draw = function(cellMode, partType){
-    if (this.hideForStockSimulation) return;
-    if (!cellMode) cellMode = globals.appState.get("cellMode");
-    if (!partType)  partType = globals.lattice.get("partType");
-    //var beamMode = partType == "beam";
-    var beamMode = false;
-    var partMode = cellMode == "part";
-
-    //init parts/beams if needed
-    if (partMode &&!beamMode && !this.parts) this.parts = this._initParts();
-    if (beamMode && !this.beams) {
-        this.nodes = this._initNodes(this.mesh.children[0].geometry.vertices);
-        this.beams = this._initBeams(this.nodes, this.mesh.children[0].geometry.faces);
-    }
-
-    //set visibility
-    this._setCellMeshVisibility(!partMode);
-    _.each(this.parts, function(part){
-        if (part) part.setVisibility(partMode && !beamMode);
-    });
-    _.each(this.beams, function(beam){
-        beam.setVisibility(beamMode && partMode);
-    });
-};
-
-DMACell.prototype.hide = function(){//only used in the context of stock simulation
-    this._setCellMeshVisibility(false);
-    _.each(this.parts, function(part){
-        if (part) part.setVisibility(false);
-    });
-    _.each(this.beams, function(beam){
-        beam.setVisibility(false);
-    });
-};
-
-///////////////////////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////SCALE/POSITION////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////
-
-DMACell.prototype._setMeshPosition = function(mesh, position){
-    mesh.position.x = position.x;
-    mesh.position.y = position.y;
-    mesh.position.z = position.z;
-};
-
-DMACell.prototype.moveTo = function(position, axis){//used for stock simulations
-    this.mesh.position[axis] = position;
-    if (globals.appState.get("cellMode") == "part"){
-        _.each(this.parts, function(part){
-            if (part) part.moveTo(position, axis);
-        });
-    }
-};
-
-DMACell.prototype.getType = function(){
-    return null;//only used in freeform layout
-};
-
-DMACell.prototype.getPosition = function(){
-    return this.mesh.position.clone();
-};
-
-DMACell.prototype.getOrientation = function(){
-    return this.mesh.quaternion.clone();
-};
-
-DMACell.prototype.getEulerRotation = function(){
-    return this.mesh.rotation.clone();
-};
-
-DMACell.prototype._calcPosition = function(){//need for part relay
-    if (this.indices) return globals.lattice.getPositionForIndex(this.indices);
-    return this.mesh.position;//used for cam simulation
-};
-
-DMACell.prototype._setCellMeshVisibility = function(visibility){
-    this.mesh.visible = visibility;
-};
-
-DMACell.prototype.xScale = function(){
-    return globals.lattice.xScale(0);
-};
-
-DMACell.prototype.yScale = function(){
-    return globals.lattice.yScale(0);
-};
-
-DMACell.prototype.zScale = function(){
-    return globals.lattice.zScale(0);
-};
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////META//////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////
-
-DMACell.prototype._buildMesh = function(material){//called from every subclass
-    var unitCellGeo = this._getGeometry();
-    if (!material) material = cellMaterials;
-    var mesh = THREE.SceneUtils.createMultiMaterialObject(unitCellGeo, material);
-    mesh.myParent = this;//we need a reference to this instance from the mesh for intersection selection stuff
-    return mesh;
-};
-
-
-DMACell.prototype._doMeshTransformations = function(mesh){};//by default, no mesh transformations
-
-DMACell.prototype._initParts = function(){
-    return [];//override in subclasses
-};
-
-DMACell.prototype.changePartType = function(){//override in subclasses
-};
-
-DMACell.prototype.removePart = function(index){
-    this.parts[index].destroy();
-    this.parts[index] = null;
-    var hasAnyParts = false;//check if all parts have been deleted
-    _.each(this.parts, function(part){
-        if (part) hasAnyParts = true;
-    });
-    if (!hasAnyParts) globals.lattice.removeCell(this);//if all parts are gone, remove cell
-};
-
-DMACell.prototype.destroyParts = function(){
-    _.each(this.parts, function(part){
-        if (part) part.destroy();
-    });
-    this.parts = null;
-};
-
-DMACell.prototype._initNodes = function(vertices){
-    var position = this.getPosition();
-    var orientation = this.getOrientation();
-    var nodes = [];
-    for (var i=0;i<vertices.length;i++){
-        var vertex = vertices[i].clone();
-        vertex.applyQuaternion(orientation);
-        vertex.add(position);
-        nodes.push(new DmaNode(vertex, i));
-    }
-    return nodes;
-};
-
-DMACell.prototype._initBeams = function(nodes, faces){
-    var beams = [];
-    var self = this;
-    var addBeamFunc = function(index1, index2){
-        var duplicate = false;
-        _.each(beams, function(beam){
-            var index = beam.getIndex();
-            if (index[0] == index1 && index[1] == index2) duplicate = true;
-        });
-        if (duplicate) return;
-        var diff = nodes[index1].getPosition();
-        diff.sub(nodes[index2].getPosition());
-        if (diff.length() > self.getScale()*1.01) return;
-        if (index2>index1) {
-            beams.push(new DmaBeam(nodes[index1], nodes[index2], self));
-        }
-    };
-    for (var i=0;i<nodes.length;i++){
-        _.each(faces, function(face){
-            if (face.a == i) {
-                addBeamFunc(i, face.b);
-                addBeamFunc(i, face.c);
-            } else if (face.b == i){
-                addBeamFunc(i, face.a);
-                addBeamFunc(i, face.c);
-            } else if (face.c == i){
-                addBeamFunc(i, face.a);
-                addBeamFunc(i, face.b);
-            }
-        })
-    }
-    return beams;
-};
-
-DMACell.prototype.destroy = function(){
-    if (this.destroyStarted) return;
-    this.destroyStarted = true;
-    if (this.mesh) {
-        globals.three.sceneRemove(this.mesh, this._sceneType(this.indices));
-        this.mesh.myParent = null;
-//            this.mesh.dispose();
-//            geometry.dispose();
-//            material.dispose();
-        this.mesh = null;
-    }
-    this.destroyParts();
-    this.indices = null;
-    this.nodes = null;
-    this.beams = null;
-    if (this.superCell) {
-        this.superCell.destroy();
-        this.superCell = null;
-    }
-    this.superCellIndex = null;
-};
-
-DMACell.prototype.toJSON = function(){
-    var data = {
-        indices:this.indices//todo get rid of this and calculate from min and max
-    };
-    if (this.parts) data.parts = this.parts;
-    return data;
-};
\ No newline at end of file
diff --git a/js/cell/DmaCellOcta.js b/js/cell/DmaCellOcta.js
deleted file mode 100644
index 7a760c117fd2f2749fbbe441e2cb2940108ac951..0000000000000000000000000000000000000000
--- a/js/cell/DmaCellOcta.js
+++ /dev/null
@@ -1,214 +0,0 @@
-/**
- * Created by aghassaei on 3/9/15.
- */
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////
-////////////////////////FACE CONNECTED/////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////
-
-
-var unitFaceOctaGeo = new THREE.OctahedronGeometry(1/Math.sqrt(2));
-unitFaceOctaGeo.applyMatrix(new THREE.Matrix4().makeRotationZ(-3*Math.PI/12));
-unitFaceOctaGeo.applyMatrix(new THREE.Matrix4().makeRotationX(Math.asin(2/Math.sqrt(2)/Math.sqrt(3))));
-
-function DMAFaceOctaCell(indices, cellMode, partType){
-    DMACell.call(this, indices, cellMode, partType);
-}
-DMAFaceOctaCell.prototype = Object.create(DMACell.prototype);
-
-DMAFaceOctaCell.prototype._initParts = function(){
-    var parts  = [];
-    for (var i=0;i<3;i++){
-        parts.push(new DMATrianglePart(i, this));
-    }
-    return parts;
-};
-
-DMAFaceOctaCell.prototype._doMeshTransformations = function(mesh){
-    if (this.indices && this.indices.z%2!=0) mesh.rotation.set(0, 0, Math.PI);
-};
-
-DMAFaceOctaCell.prototype._getGeometry = function(){
-    return unitFaceOctaGeo;
-};
-
-DMAFaceOctaCell.prototype.calcHighlighterPosition = function(face){
-    if (face.normal.z<0.99) return {index: _.clone(this.indices)};//only highlight horizontal faces
-    var direction = face.normal;
-    var position = this.getPosition();
-    position.z += face.normal.z*this.zScale()/2;
-    return {index: _.clone(this.indices), direction:direction, position:position};
-};
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////
-////////////////////////EDGE CONNECTED/////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////
-
-
-function DMAEdgeOctaCell(indices, cellMode, partType){
-    DMAFaceOctaCell.call(this, indices, cellMode, partType);
-}
-DMAEdgeOctaCell.prototype = Object.create(DMAFaceOctaCell.prototype);
-
-DMAEdgeOctaCell.prototype._doMeshTransformations = function(){};
-
-//todo fix this
-DMAEdgeOctaCell.prototype.calcHighlighterPosition = function(face){
-    var direction = face.normal.clone();
-    direction.applyQuaternion(this.mesh.quaternion);
-    var position = this.getPosition();
-    position.add(direction.clone().multiplyScalar(this.zScale()/2));
-    return {index: _.clone(this.indices), direction:direction, position:position};
-};
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////
-////////////////////////ROTATED EDGE CONNECTED/////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////
-
-
-var unitVertexOcta = new THREE.OctahedronGeometry(1/Math.sqrt(2));
-
-function DMARotatedEdgeCell(indices, cellMode, partType){
-    DMACell.call(this, indices, cellMode, partType);
-}
-DMARotatedEdgeCell.prototype = Object.create(DMACell.prototype);
-
-DMARotatedEdgeCell.prototype._initParts = function(){
-    return this.changePartType(globals.lattice.get("partType"));
-};
-
-DMARotatedEdgeCell.prototype.changePartType = function(type){
-    var newParts = [];
-    if (type == "vox"){
-        newParts.push(new DMAEdgeVoxPart(0, this));
-    } else if (type == "voxLowPoly"){
-        newParts.push(new DMAEdgeVoxPartLowPoly(0, this));
-    } else {
-        console.warn("part type " + type + " not recognized");
-        return;
-    }
-    if (!this.parts) return newParts;
-    this.destroyParts();
-    this.parts = newParts;
-};
-
-DMARotatedEdgeCell.prototype._doMeshTransformations = function(mesh){
-    mesh.rotation.set(0, 0, Math.PI/4);
-};
-
-DMARotatedEdgeCell.prototype.calcHighlighterPosition = function(face, point){
-
-    var position = this.getPosition();
-    var direction = new THREE.Vector3(0,0,0);
-    var rad = this.xScale()*Math.sqrt(2)/6;
-
-    var difference = new THREE.Vector3().subVectors(position, point);
-    difference.divideScalar(this.zScale());
-    if (Math.abs(difference.z) < 0.2){
-        direction.z = 0;
-    } else if (point.z < position.z) {
-        direction.z = -1;
-        position.z -= rad;
-    } else {
-        direction.z = 1;
-        position.z += rad;
-    }
-
-    if (direction.z != 0){
-        if (this.indices.z%2 == 0){
-            if (point.x < position.x) {
-                direction.x -= 1;
-                position.x -= rad;
-            }
-            else position.x += rad;
-            if (point.y < position.y) {
-                direction.y -= 1;
-                position.y -= rad;
-            }
-            else position.y += rad;
-        } else {
-            if (point.x > position.x) {
-                direction.x += 1;
-                position.x += rad;
-            }
-            else position.x -= rad;
-            if (point.y > position.y) {
-                direction.y += 1;
-                position.y += rad;
-            }
-            else position.y -= rad;
-        }
-    } else {
-        if (Math.abs(difference.x) > Math.abs(difference.y)){
-            if (point.x > position.x) direction.x = 1;
-            else direction.x = -1;
-        } else {
-            if (point.y > position.y) direction.y = 1;
-            else direction.y = -1;
-        }
-        position.x += direction.x*this.xScale()/2;
-        position.y += direction.y*this.yScale()/2;
-    }
-
-    return {index: _.clone(this.indices), direction:direction, position:position};
-};
-
-DMARotatedEdgeCell.prototype._getGeometry = function(){
-    return unitVertexOcta;
-};
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////
-////////////////////////VERTEX CONNECTED///////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////
-
-
-function DMAVertexOctaCell(indices, cellMode, partType){
-    DMACell.call(this, indices, cellMode, partType);
-}
-DMAVertexOctaCell.prototype = Object.create(DMACell.prototype);
-
-DMAVertexOctaCell.prototype.calcHighlighterPosition = function(face, point){
-
-    var position = this.getPosition();
-    var direction = null;
-
-    var xScale = this.xScale();
-    if (point.x < position.x+xScale/4 && point.x > position.x-xScale/4){
-        if (point.y > position.y-xScale/4 && point.y < position.y+xScale/4){
-            if (face.normal.z > 0) {
-                direction = new THREE.Vector3(0,0,1);
-                position.z += this.zScale()/2;
-            }
-            else {
-                direction = new THREE.Vector3(0,0,-1);
-                position.z -= this.zScale()/2;
-            }
-        } else {
-            if (point.y < position.y-xScale/4){
-                direction = new THREE.Vector3(0,-1,0);
-                position.y -= xScale/2;
-            } else {
-                direction = new THREE.Vector3(0,1,0);
-                position.y += xScale/2;
-            }
-        }
-    } else {
-        if (point.x < position.x-xScale/4){
-            direction = new THREE.Vector3(-1,0,0);
-            position.x -= xScale/2;
-        } else {
-            direction = new THREE.Vector3(1,0,0);
-            position.x += xScale/2;
-        }
-    }
-
-    return {index: _.clone(this.indices), direction:direction, position:position};
-};
-
-DMAVertexOctaCell.prototype._getGeometry = function(){
-    return unitVertexOcta;
-};
\ No newline at end of file
diff --git a/js/cell/DmaCellOld.js b/js/cell/DmaCellOld.js
new file mode 100644
index 0000000000000000000000000000000000000000..5c185fdfe9f332e34a0afc3346706e506a4ea253
--- /dev/null
+++ b/js/cell/DmaCellOld.js
@@ -0,0 +1,236 @@
+/**
+ * Created by aghassaei on 1/14/15.
+ */
+
+
+//a Cell, a unit piece of the lattice
+
+//var cellMaterials = [new THREE.MeshNormalMaterial(),
+//        new THREE.MeshBasicMaterial({color:0x000000, wireframe:true})];
+//
+//function DMACell(indices, cellMode, partType) {
+//
+//    this.indices = indices;
+//    this.mesh = this._buildMesh();
+//    this._doMeshTransformations(this.mesh);//some cell types require transformations
+//    this._setMeshPosition(this.mesh, this._calcPosition());
+//
+//    globals.three.sceneAdd(this.mesh,this._sceneType(indices));
+//
+//    this.draw(cellMode, partType);
+//
+//    this.hideForStockSimulation = false;
+//}
+//
+//DMACell.prototype._sceneType = function(indices){
+//    if (!indices || indices == null || indices === undefined) return null;
+//    return "cell";
+//};
+//
+//DMACell.prototype.draw = function(cellMode, partType){
+//    if (this.hideForStockSimulation) return;
+//    if (!cellMode) cellMode = globals.appState.get("cellMode");
+//    if (!partType)  partType = globals.lattice.get("partType");
+//    //var beamMode = partType == "beam";
+//    var beamMode = false;
+//    var partMode = cellMode == "part";
+//
+//    //init parts/beams if needed
+//    if (partMode &&!beamMode && !this.parts) this.parts = this._initParts();
+//    if (beamMode && !this.beams) {
+//        this.nodes = this._initNodes(this.mesh.children[0].geometry.vertices);
+//        this.beams = this._initBeams(this.nodes, this.mesh.children[0].geometry.faces);
+//    }
+//
+//    //set visibility
+//    this._setCellMeshVisibility(!partMode);
+//    _.each(this.parts, function(part){
+//        if (part) part.setVisibility(partMode && !beamMode);
+//    });
+//    _.each(this.beams, function(beam){
+//        beam.setVisibility(beamMode && partMode);
+//    });
+//};
+//
+//DMACell.prototype.hide = function(){//only used in the context of stock simulation
+//    this._setCellMeshVisibility(false);
+//    _.each(this.parts, function(part){
+//        if (part) part.setVisibility(false);
+//    });
+//    _.each(this.beams, function(beam){
+//        beam.setVisibility(false);
+//    });
+//};
+//
+/////////////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////SCALE/POSITION////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////
+//
+//DMACell.prototype._setMeshPosition = function(mesh, position){
+//    mesh.position.x = position.x;
+//    mesh.position.y = position.y;
+//    mesh.position.z = position.z;
+//};
+//
+//DMACell.prototype.moveTo = function(position, axis){//used for stock simulations
+//    this.mesh.position[axis] = position;
+//    if (globals.appState.get("cellMode") == "part"){
+//        _.each(this.parts, function(part){
+//            if (part) part.moveTo(position, axis);
+//        });
+//    }
+//};
+//
+//DMACell.prototype.getType = function(){
+//    return null;//only used in freeform layout
+//};
+//
+//DMACell.prototype.getPosition = function(){
+//    return this.mesh.position.clone();
+//};
+//
+//DMACell.prototype.getOrientation = function(){
+//    return this.mesh.quaternion.clone();
+//};
+//
+//DMACell.prototype.getEulerRotation = function(){
+//    return this.mesh.rotation.clone();
+//};
+//
+//DMACell.prototype._calcPosition = function(){//need for part relay
+//    if (this.indices) return globals.lattice.getPositionForIndex(this.indices);
+//    return this.mesh.position;//used for cam simulation
+//};
+//
+//DMACell.prototype._setCellMeshVisibility = function(visibility){
+//    this.mesh.visible = visibility;
+//};
+//
+//DMACell.prototype.xScale = function(){
+//    return globals.lattice.xScale(0);
+//};
+//
+//DMACell.prototype.yScale = function(){
+//    return globals.lattice.yScale(0);
+//};
+//
+//DMACell.prototype.zScale = function(){
+//    return globals.lattice.zScale(0);
+//};
+//
+//
+/////////////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////META//////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////
+//
+//DMACell.prototype._buildMesh = function(material){//called from every subclass
+//    var unitCellGeo = this._getGeometry();
+//    if (!material) material = cellMaterials;
+//    var mesh = THREE.SceneUtils.createMultiMaterialObject(unitCellGeo, material);
+//    mesh.myParent = this;//we need a reference to this instance from the mesh for intersection selection stuff
+//    return mesh;
+//};
+//
+//
+//DMACell.prototype._doMeshTransformations = function(mesh){};//by default, no mesh transformations
+//
+//DMACell.prototype._initParts = function(){
+//    return [];//override in subclasses
+//};
+//
+//DMACell.prototype.changePartType = function(){//override in subclasses
+//};
+//
+//DMACell.prototype.removePart = function(index){
+//    this.parts[index].destroy();
+//    this.parts[index] = null;
+//    var hasAnyParts = false;//check if all parts have been deleted
+//    _.each(this.parts, function(part){
+//        if (part) hasAnyParts = true;
+//    });
+//    if (!hasAnyParts) globals.lattice.removeCell(this);//if all parts are gone, remove cell
+//};
+//
+//DMACell.prototype.destroyParts = function(){
+//    _.each(this.parts, function(part){
+//        if (part) part.destroy();
+//    });
+//    this.parts = null;
+//};
+//
+//DMACell.prototype._initNodes = function(vertices){
+//    var position = this.getPosition();
+//    var orientation = this.getOrientation();
+//    var nodes = [];
+//    for (var i=0;i<vertices.length;i++){
+//        var vertex = vertices[i].clone();
+//        vertex.applyQuaternion(orientation);
+//        vertex.add(position);
+//        nodes.push(new DmaNode(vertex, i));
+//    }
+//    return nodes;
+//};
+//
+//DMACell.prototype._initBeams = function(nodes, faces){
+//    var beams = [];
+//    var self = this;
+//    var addBeamFunc = function(index1, index2){
+//        var duplicate = false;
+//        _.each(beams, function(beam){
+//            var index = beam.getIndex();
+//            if (index[0] == index1 && index[1] == index2) duplicate = true;
+//        });
+//        if (duplicate) return;
+//        var diff = nodes[index1].getPosition();
+//        diff.sub(nodes[index2].getPosition());
+//        if (diff.length() > self.getScale()*1.01) return;
+//        if (index2>index1) {
+//            beams.push(new DmaBeam(nodes[index1], nodes[index2], self));
+//        }
+//    };
+//    for (var i=0;i<nodes.length;i++){
+//        _.each(faces, function(face){
+//            if (face.a == i) {
+//                addBeamFunc(i, face.b);
+//                addBeamFunc(i, face.c);
+//            } else if (face.b == i){
+//                addBeamFunc(i, face.a);
+//                addBeamFunc(i, face.c);
+//            } else if (face.c == i){
+//                addBeamFunc(i, face.a);
+//                addBeamFunc(i, face.b);
+//            }
+//        })
+//    }
+//    return beams;
+//};
+//
+//DMACell.prototype.destroy = function(){
+//    if (this.destroyStarted) return;
+//    this.destroyStarted = true;
+//    if (this.mesh) {
+//        globals.three.sceneRemove(this.mesh, this._sceneType(this.indices));
+//        this.mesh.myParent = null;
+////            this.mesh.dispose();
+////            geometry.dispose();
+////            material.dispose();
+//        this.mesh = null;
+//    }
+//    this.destroyParts();
+//    this.indices = null;
+//    this.nodes = null;
+//    this.beams = null;
+//    if (this.superCell) {
+//        this.superCell.destroy();
+//        this.superCell = null;
+//    }
+//    this.superCellIndex = null;
+//};
+//
+//DMACell.prototype.toJSON = function(){
+//    var data = {
+//        indices:this.indices//todo get rid of this and calculate from min and max
+//    };
+//    if (this.parts) data.parts = this.parts;
+//    return data;
+//};
\ No newline at end of file
diff --git a/js/cell/DmaCellOther.js b/js/cell/DmaCellOther.js
index d27fadaa10cd20085b5d2781a759daa12558c83d..99f1610c551d2919eb9d8ab6b05adce3cb38b392 100644
--- a/js/cell/DmaCellOther.js
+++ b/js/cell/DmaCellOther.js
@@ -3,7 +3,7 @@
  */
 
 
-var cellMaterial = [new THREE.MeshNormalMaterial()];
+//var cellMaterial = [new THREE.MeshNormalMaterial()];
 
 
 ///////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/js/cell/OctaEdgeCell.js b/js/cell/OctaEdgeCell.js
new file mode 100644
index 0000000000000000000000000000000000000000..eedc0a86b985edc1a41d6c23fa23c499df6617f8
--- /dev/null
+++ b/js/cell/OctaEdgeCell.js
@@ -0,0 +1,22 @@
+/**
+ * Created by aghassaei on 5/26/15.
+ */
+
+
+function OctaEdgeCell(indices){
+    OctaFaceCell.call(this, indices);
+}
+OctaEdgeCell.prototype = Object.create(OctaFaceCell.prototype);
+
+OctaEdgeCell.prototype._rotateCell = function(object3D){
+    return object3D;
+};
+
+//todo fix this
+OctaEdgeCell.prototype.calcHighlighterPosition = function(face){
+    var direction = face.normal.clone();
+    direction.applyQuaternion(this.mesh.quaternion);
+    var position = this.getPosition();
+    position.add(direction.clone().multiplyScalar(this.zScale()/2));
+    return {index: _.clone(this.indices), direction:direction, position:position};
+};
\ No newline at end of file
diff --git a/js/cell/OctaFaceCell.js b/js/cell/OctaFaceCell.js
new file mode 100644
index 0000000000000000000000000000000000000000..be3d0f003c90b4b946c28c06c9221dcdbb5fe9c4
--- /dev/null
+++ b/js/cell/OctaFaceCell.js
@@ -0,0 +1,38 @@
+/**
+ * Created by aghassaei on 5/26/15.
+ */
+
+
+var unitFaceOctaGeo = new THREE.OctahedronGeometry(1/Math.sqrt(2));
+unitFaceOctaGeo.applyMatrix(new THREE.Matrix4().makeRotationZ(-3*Math.PI/12));
+unitFaceOctaGeo.applyMatrix(new THREE.Matrix4().makeRotationX(Math.asin(2/Math.sqrt(2)/Math.sqrt(3))));
+
+function OctaFaceCell(mode, indices){
+    DMACell.call(this, mode, indices);
+}
+OctaFaceCell.prototype = Object.create(DMACell.prototype);
+
+OctaFaceCell.prototype._initParts = function(){
+    var parts  = [];
+    for (var i=0;i<3;i++){
+        parts.push(new DMATrianglePart(i, this));
+    }
+    return parts;
+};
+
+OctaFaceCell.prototype._rotateCell = function(object3D){
+    if (this.indices && this.indices.z%2!=0) object3D.rotation.set(0, 0, Math.PI);
+    return object3D;
+};
+
+OctaFaceCell.prototype._getGeometry = function(){
+    return unitFaceOctaGeo;
+};
+
+OctaFaceCell.prototype.calcHighlighterPosition = function(face){
+    if (face.normal.z<0.99) return {index: _.clone(this.indices)};//only highlight horizontal faces
+    var direction = face.normal;
+    var position = this.getPosition();
+    position.z += face.normal.z*this.zScale()/2;
+    return {index:_.clone(this.indices), direction:direction, position:position};
+};
\ No newline at end of file
diff --git a/js/cell/OctaRotEdgeCell.js b/js/cell/OctaRotEdgeCell.js
new file mode 100644
index 0000000000000000000000000000000000000000..c2d6a1e743f3d7407f89a66f2a6779359bc9e8e3
--- /dev/null
+++ b/js/cell/OctaRotEdgeCell.js
@@ -0,0 +1,96 @@
+/**
+ * Created by aghassaei on 5/26/15.
+ */
+
+
+var unitVertexOcta = new THREE.OctahedronGeometry(1/Math.sqrt(2));
+
+function OctaRotEdgeCell(indices){
+    DMACell.call(this, indices);
+}
+OctaRotEdgeCell.prototype = Object.create(DMACell.prototype);
+
+OctaRotEdgeCell.prototype._initParts = function(){
+    return this.changePartType(globals.lattice.get("partType"));
+};
+
+OctaRotEdgeCell.prototype.changePartType = function(type){
+    var newParts = [];
+    if (type == "vox"){
+        newParts.push(new DMAEdgeVoxPart(0, this));
+    } else if (type == "voxLowPoly"){
+        newParts.push(new DMAEdgeVoxPartLowPoly(0, this));
+    } else {
+        console.warn("part type " + type + " not recognized");
+        return;
+    }
+    if (!this.parts) return newParts;
+    this.destroyParts();
+    this.parts = newParts;
+};
+
+OctaRotEdgeCell.prototype._getGeometry = function(){
+    return unitVertexOcta;
+};
+
+OctaRotEdgeCell.prototype._rotateCell = function(object3D){
+    object3D.rotation.set(0, 0, Math.PI/4);
+    return object3D;
+};
+
+OctaRotEdgeCell.prototype.calcHighlighterPosition = function(face, point){
+
+    var position = this.getPosition();
+    var direction = new THREE.Vector3(0,0,0);
+    var rad = this.xScale()*Math.sqrt(2)/6;
+
+    var difference = new THREE.Vector3().subVectors(position, point);
+    difference.divideScalar(this.zScale());
+    if (Math.abs(difference.z) < 0.2){
+        direction.z = 0;
+    } else if (point.z < position.z) {
+        direction.z = -1;
+        position.z -= rad;
+    } else {
+        direction.z = 1;
+        position.z += rad;
+    }
+
+    if (direction.z != 0){
+        if (this.indices.z%2 == 0){
+            if (point.x < position.x) {
+                direction.x -= 1;
+                position.x -= rad;
+            }
+            else position.x += rad;
+            if (point.y < position.y) {
+                direction.y -= 1;
+                position.y -= rad;
+            }
+            else position.y += rad;
+        } else {
+            if (point.x > position.x) {
+                direction.x += 1;
+                position.x += rad;
+            }
+            else position.x -= rad;
+            if (point.y > position.y) {
+                direction.y += 1;
+                position.y += rad;
+            }
+            else position.y -= rad;
+        }
+    } else {
+        if (Math.abs(difference.x) > Math.abs(difference.y)){
+            if (point.x > position.x) direction.x = 1;
+            else direction.x = -1;
+        } else {
+            if (point.y > position.y) direction.y = 1;
+            else direction.y = -1;
+        }
+        position.x += direction.x*this.xScale()/2;
+        position.y += direction.y*this.yScale()/2;
+    }
+
+    return {index: _.clone(this.indices), direction:direction, position:position};
+};
\ No newline at end of file
diff --git a/js/cell/OctaVertexCell.js b/js/cell/OctaVertexCell.js
new file mode 100644
index 0000000000000000000000000000000000000000..cbc1431a08987a0177038be11042123ef78bb42f
--- /dev/null
+++ b/js/cell/OctaVertexCell.js
@@ -0,0 +1,51 @@
+/**
+ * Created by aghassaei on 5/26/15.
+ */
+
+
+function OctaVertexCell(indices){
+    DMACell.call(this, indices);
+}
+OctaVertexCell.prototype = Object.create(DMACell.prototype);
+
+OctaVertexCell.prototype._getGeometry = function(){
+    return unitVertexOcta;
+};
+
+OctaVertexCell.prototype.calcHighlighterPosition = function(face, point){
+
+    var position = this.getPosition();
+    var direction = null;
+
+    var xScale = this.xScale();
+    if (point.x < position.x+xScale/4 && point.x > position.x-xScale/4){
+        if (point.y > position.y-xScale/4 && point.y < position.y+xScale/4){
+            if (face.normal.z > 0) {
+                direction = new THREE.Vector3(0,0,1);
+                position.z += this.zScale()/2;
+            }
+            else {
+                direction = new THREE.Vector3(0,0,-1);
+                position.z -= this.zScale()/2;
+            }
+        } else {
+            if (point.y < position.y-xScale/4){
+                direction = new THREE.Vector3(0,-1,0);
+                position.y -= xScale/2;
+            } else {
+                direction = new THREE.Vector3(0,1,0);
+                position.y += xScale/2;
+            }
+        }
+    } else {
+        if (point.x < position.x-xScale/4){
+            direction = new THREE.Vector3(-1,0,0);
+            position.x -= xScale/2;
+        } else {
+            direction = new THREE.Vector3(1,0,0);
+            position.x += xScale/2;
+        }
+    }
+
+    return {index: _.clone(this.indices), direction:direction, position:position};
+};
\ No newline at end of file
diff --git a/js/lattice/OctaFaceLattice.js b/js/lattice/OctaFaceLattice.js
index 3431adb14431575b548a7783ece99a69b2b87fe5..385349151ad29ebcd99897b1bcd5eb66555e998b 100644
--- a/js/lattice/OctaFaceLattice.js
+++ b/js/lattice/OctaFaceLattice.js
@@ -43,7 +43,7 @@ latticeSubclasses["OctaFaceLattice"] = {
         },
 
         makeCellForLatticeType: function(indices){
-            return new DMAFaceOctaCell(indices);
+            return new OctaFaceCell(indices);
         },
 
         _undo: function(){//remove all the mixins
diff --git a/js/lattice/OctaRotEdgeLattice.js b/js/lattice/OctaRotEdgeLattice.js
index ebd5a7de3eaa2aa0a664a01c393a5a9bb03ed6d6..c1190f11e3759de34449104d989f5b8ad6660c6f 100644
--- a/js/lattice/OctaRotEdgeLattice.js
+++ b/js/lattice/OctaRotEdgeLattice.js
@@ -46,7 +46,7 @@ latticeSubclasses["OctaRotEdgeLattice"] = {
         },
 
         makeCellForLatticeType: function(indices){
-            return new DMARotatedEdgeCell(indices);
+            return new OctaRotEdgeCell(indices);
         },
 
         _undo: function(){//remove all the mixins
diff --git a/js/lattice/OctaVertexLattice.js b/js/lattice/OctaVertexLattice.js
index 174bb730d1471ccc4de10e2548440090b0d3e2e6..b61c207e9ba520be8d8d74abff608639cec0ff74 100644
--- a/js/lattice/OctaVertexLattice.js
+++ b/js/lattice/OctaVertexLattice.js
@@ -42,7 +42,7 @@ latticeSubclasses["OctaVertexLattice"] = {
         },
 
         makeCellForLatticeType: function(indices){
-            return new DMAVertexOctaCell(indices);
+            return new OctaVertexCell(indices);
         },
 
         _undo: function(){//remove all the mixins, this will help with debugging later