diff --git a/index.html b/index.html
index d12d1680b321c54f7af27353fae0dbac3ee810fc..6204112524b7242217e10785cfbe6835d47b110d 100644
--- a/index.html
+++ b/index.html
@@ -55,7 +55,10 @@
     <script src="js/cells/DmaCellTetra.js"></script>
     <script src="js/cells/DmaCellOther.js"></script>
 
-    <script src="js/fea/DmaPart.js"></script>
+    <script src="js/parts/DmaPart.js"></script>
+    <script src="js/parts/GIKMicroLegoPart.js"></script>
+    <script src="js/parts/OctaEdgeVoxPart.js"></script>
+    <script src="js/parts/OctaFaceTriPart.js"></script>
 
     <!--models-->
     <script src="js/models/ThreeModel.js"></script>
diff --git a/js/cells/DMACell.js b/js/cells/DMACell.js
index 49f71dd2e8c13332dcd05db8f8cd8a5a14729e0e..9795d55a8c5a106cd72fb26fc99f78a9a670dd70 100644
--- a/js/cells/DMACell.js
+++ b/js/cells/DMACell.js
@@ -40,12 +40,22 @@ DMACell.prototype._translateCell = function(object3D){
 };
 
 DMACell.prototype._addMeshes = function(meshes, object3D){//accepts an array or a single mesh
+    this._addRemoveMeshes(true, meshes, object3D);
+};
+
+DMACell.prototype._removeMeshes = function(meshes, object3D){//accepts an array or a single mesh
+    this._addRemoveMeshes(false, meshes, object3D);
+};
+
+DMACell.prototype._addRemoveMeshes = function(shouldAdd, meshes, object3D){//accepts an array or a single mesh
     if (object3D === undefined) object3D = this.object3D;
     if (meshes.constructor === Array){
         _.each(meshes, function(mesh){
-            object3D.add(mesh);
+            if (shouldAdd) object3D.add(mesh);
+            else object3D.remove(mesh);
         });
-    } else object3D.add(meshes);
+    } else if (shouldAdd) object3D.add(meshes);
+    else object3D.remove(meshes);
 };
 
 DMACell.prototype._buildMesh = function(){//called from every subclass
@@ -75,7 +85,13 @@ DMACell.prototype.setMode = function(mode){
         case "cell":
             break;
         case "part":
-            if (!this.parts) this.parts = this._initParts();
+            if (!this.parts) {
+                this.parts = this._initParts();
+                var self = this;
+                _.each(this.parts, function(part){
+                    self._addMeshes(part.getMesh());
+                });
+            }
             break;
         case "beam":
             if (!this.beams) this.beams = this._initBeams();
@@ -94,8 +110,9 @@ DMACell.prototype.hide = function(){
     this.object3D.visible = false;
 };
 
-DMACell.prototype.show = function(){
+DMACell.prototype.show = function(mode){
     this.object3D.visible = true;
+    this.setMode(mode);
 };
 
 DMACell.prototype.setOpacity = function(opacity){
@@ -154,6 +171,16 @@ DMACell.prototype.destroyParts = function(){
     this.parts = null;
 };
 
+//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.toJSON = function(){
     var data = {
         indices:this.indices//todo get rid of this and calculate from min and max
@@ -190,15 +217,6 @@ DMACell.prototype.toJSON = function(){
 //    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 = [];
diff --git a/js/cells/OctaFaceCell.js b/js/cells/OctaFaceCell.js
index be3d0f003c90b4b946c28c06c9221dcdbb5fe9c4..a183db8af45634950766a15dad873d1976eab6d8 100644
--- a/js/cells/OctaFaceCell.js
+++ b/js/cells/OctaFaceCell.js
@@ -15,7 +15,7 @@ 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));
+        parts.push(new OctaFaceTriPart(i, this));
     }
     return parts;
 };
diff --git a/js/cells/OctaRotEdgeCell.js b/js/cells/OctaRotEdgeCell.js
index c2d6a1e743f3d7407f89a66f2a6779359bc9e8e3..44c663e02ebe08c47e3f5f327791a4feeb0e946a 100644
--- a/js/cells/OctaRotEdgeCell.js
+++ b/js/cells/OctaRotEdgeCell.js
@@ -17,9 +17,9 @@ OctaRotEdgeCell.prototype._initParts = function(){
 OctaRotEdgeCell.prototype.changePartType = function(type){
     var newParts = [];
     if (type == "vox"){
-        newParts.push(new DMAEdgeVoxPart(0, this));
+        newParts.push(new OctaEdgeVoxPart(0));
     } else if (type == "voxLowPoly"){
-        newParts.push(new DMAEdgeVoxPartLowPoly(0, this));
+        newParts.push(new OctaEdgeVoxPartLowPoly(0));
     } else {
         console.warn("part type " + type + " not recognized");
         return;
diff --git a/js/fea/DmaPart.js b/js/fea/DmaPart.js
deleted file mode 100644
index c91fb0de2efff8deaff554cecfa9df486a17ca66..0000000000000000000000000000000000000000
--- a/js/fea/DmaPart.js
+++ /dev/null
@@ -1,352 +0,0 @@
-/**
- * Created by aghassaei on 1/14/15.
- */
-
-
-var partMaterial = new THREE.MeshLambertMaterial({ color:0xffffff, shading: THREE.FlatShading });
-    partMaterial.color.setRGB( 0.9619657144369509, 0.6625466032079207, 0.20799727886007258 );
-
-//a part, element with a single material, handled by assembler
-
-    function DMAPart(type, parent) {
-        this.parentCell = parent;//use this reference to get position and scale
-        this.type = type;
-    }
-
-    DMAPart.prototype._draw = function(){
-        if (this.mesh) console.warn("part mesh already in scene");
-        this.mesh = this._makeMeshForType(this.type);
-        var rotation = this.parentCell.getEulerRotation();
-        this.mesh.rotation.set(rotation.x, rotation.y, rotation.z);
-        this._setMeshPosition(this.parentCell.getPosition());
-        globals.three.sceneAdd(this.mesh, "part");
-    };
-
-    DMAPart.prototype._setMeshPosition = function(position){
-        var mesh = this.mesh;
-        mesh.position.x = position.x;
-        mesh.position.y = position.y;
-        mesh.position.z = position.z;
-    };
-
-    DMAPart.prototype.moveTo = function(position, axis){//used for stock simulation
-        this.mesh.position[axis] = position;
-    };
-
-    DMAPart.prototype.setVisibility = function(visibility){
-        if (visibility) this._show();
-        else this._hide();
-    };
-
-    DMAPart.prototype._show = function(){
-        if (!this.mesh) this._draw();
-        this.mesh.visible = true;
-    };
-
-    DMAPart.prototype._hide = function(){
-        if (this.mesh) this.mesh.visible = false;
-    };
-
-    DMAPart.prototype.highlight = function(){
-//        this.mesh.material.color.setRGB(1,0,0);
-    };
-
-    DMAPart.prototype.unhighlight = function(){
-//        if (this.mesh) this.mesh.material.color.setRGB(0.9619657144369509, 0.6625466032079207, 0.20799727886007258);
-    };
-
-    DMAPart.prototype.removeFromCell = function(){//send message back to parent cell to destroy this
-        if (this.parentCell) {
-            this.parentCell.removePart(this.type);
-            globals.three.render();
-        } else console.warn("part has no parent cell");
-    };
-
-    DMAPart.prototype.destroy = function(){
-        if (this.mesh) {
-            globals.three.sceneRemove(this.mesh, "part");
-            this.mesh.myPart = null;
-//            this.mesh.dispose();
-//            geometry.dispose();
-//            material.dispose();
-            this.mesh = null;
-        }
-        this.parentCell = null;
-        this.type = null;
-    };
-
-    DMAPart.prototype.toJSON = function(){
-        return {
-        }
-    };
-
-
-//////////////////////////////////////////////////////////////
-/////////////////TRIANGLE PART////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-(function () {
-
-    var unitPartGeo1, unitPartGeo2, unitPartGeo3;
-
-    //import part geometry
-    var loader = new THREE.STLLoader();
-    loader.load("assets/stls/parts/trianglePart.stl", function(geometry){
-
-        unitPartGeo1 = geometry;
-        unitPartGeo1.computeBoundingBox();
-        var unitScale = 1.2/unitPartGeo1.boundingBox.max.y;
-        unitPartGeo1.applyMatrix(new THREE.Matrix4().makeScale(unitScale, unitScale, unitScale));
-        unitPartGeo1.applyMatrix(new THREE.Matrix4().makeTranslation(0.25,-0.6, -0.45));
-        unitPartGeo1.applyMatrix(new THREE.Matrix4().makeRotationZ(-Math.PI/6));
-
-        unitPartGeo2 = unitPartGeo1.clone();
-        unitPartGeo2.applyMatrix(new THREE.Matrix4().makeRotationZ(2*Math.PI/3));
-
-        unitPartGeo3 = unitPartGeo1.clone();
-        unitPartGeo3.applyMatrix(new THREE.Matrix4().makeRotationZ(-2*Math.PI/3));
-    });
-
-    function DMATrianglePart(type, parent){
-        DMAPart.call(this, type, parent);
-    }
-    DMATrianglePart.prototype = Object.create(DMAPart.prototype);
-
-    DMATrianglePart.prototype._makeMeshForType = function(type){
-        var mesh;
-        switch(type){
-            case 0:
-                mesh = new THREE.Mesh(unitPartGeo1, partMaterial);
-                break;
-            case 1:
-                mesh = new THREE.Mesh(unitPartGeo2, partMaterial);
-                break;
-            case 2:
-                 mesh = new THREE.Mesh(unitPartGeo3, partMaterial);
-                break;
-        }
-        mesh.myPart = this;//need a ref back to this part
-        return mesh;
-    };
-
-    self.DMATrianglePart = DMATrianglePart;
-
-})();
-
-
-//////////////////////////////////////////////////////////////
-/////////////////EDGE VOX PART////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-
-(function () {
-
-    var unitPartGeo;
-
-    //import part geometry
-    var loader = new THREE.STLLoader();
-    loader.load("assets/stls/parts/edgeVoxPart.stl", function(geometry){
-
-        unitPartGeo = geometry;
-        unitPartGeo.computeBoundingBox();
-        var unitScale = 0.706/unitPartGeo.boundingBox.max.y;
-        unitPartGeo.applyMatrix(new THREE.Matrix4().makeScale(unitScale, unitScale, unitScale));
-        unitPartGeo.applyMatrix(new THREE.Matrix4().makeRotationY(Math.PI));
-        unitPartGeo.applyMatrix(new THREE.Matrix4().makeTranslation(0,0,0.09));
-    });
-
-    function DMAEdgeVoxPart(type, parent){
-        DMAPart.call(this, type, parent);
-    }
-    DMAEdgeVoxPart.prototype = Object.create(DMAPart.prototype);
-
-    DMAEdgeVoxPart.prototype._makeMeshForType = function(){
-        var mesh = new THREE.Mesh(unitPartGeo, partMaterial);
-        mesh.myPart = this;//need a ref back to this part
-        return mesh;
-    };
-
-    self.DMAEdgeVoxPart = DMAEdgeVoxPart;
-
-})();
-
-
-(function () {
-
-    var unitPartGeo;
-
-    //import part geometry
-    var loader = new THREE.STLLoader();
-    loader.load("assets/stls/parts/edgeVoxPartLowPoly.stl", function(geometry){
-
-        unitPartGeo = geometry;
-        unitPartGeo.computeBoundingBox();
-        var unitScale = 0.706/unitPartGeo.boundingBox.max.y;
-        unitPartGeo.applyMatrix(new THREE.Matrix4().makeScale(unitScale, unitScale, unitScale));
-    });
-
-    function DMAEdgeVoxPartLowPoly(type, parent){
-        DMAPart.call(this, type, parent);
-    }
-    DMAEdgeVoxPartLowPoly.prototype = Object.create(DMAPart.prototype);
-
-    DMAEdgeVoxPartLowPoly.prototype._makeMeshForType = function(){
-        var mesh = new THREE.Mesh(unitPartGeo, partMaterial);
-        mesh.myPart = this;//need a ref back to this part
-        return mesh;
-    };
-
-    self.DMAEdgeVoxPartLowPoly = DMAEdgeVoxPartLowPoly;
-
-})();
-
-//////////////////////////////////////////////////////////////
-/////////////////Micro LEGO///////////////////////////////////
-//////////////////////////////////////////////////////////////
-
-
-(function () {
-
-    var unitPartGeo;
-
-    //import part geometry
-    var loader = new THREE.STLLoader();
-    loader.load("assets/stls/parts/GIKPart.stl", function(geometry){
-
-        unitPartGeo = geometry;
-        unitPartGeo.computeBoundingBox();
-        unitPartGeo.applyMatrix(new THREE.Matrix4().makeTranslation(-(unitPartGeo.boundingBox.min.x+unitPartGeo.boundingBox.max.x)/2,
-            -(unitPartGeo.boundingBox.min.y+unitPartGeo.boundingBox.max.y)/2, -(unitPartGeo.boundingBox.min.z+unitPartGeo.boundingBox.max.z)/2));
-        var unitScale = 1/(1.2699999809265137);
-        unitPartGeo.applyMatrix(new THREE.Matrix4().makeRotationX(Math.PI/2));
-        unitPartGeo.applyMatrix(new THREE.Matrix4().makeScale(unitScale, unitScale, unitScale));
-    });
-
-    function DMAGIKPart(type, parent){
-        DMAPart.call(this, type, parent);
-    }
-    DMAGIKPart.prototype = Object.create(DMAPart.prototype);
-
-    DMAGIKPart.prototype._makeGikWireframe = function(positions, yPosition){
-        var geometry = new THREE.Geometry();
-        _.each(positions, function(position, index){
-            if (position == yPosition){
-                geometry.vertices.push(new THREE.Vector3(positions[index-1], yPosition, positions[index+1]));
-            }
-        });
-        console.log(geometry.vertices);
-        return new THREE.Line(geometry);
-    };
-
-    DMAGIKPart.prototype._makeMeshForType = function(){
-        var mesh = new THREE.Mesh(unitPartGeo, this.parentCell.getMaterialType());
-
-
-
-        mesh.myPart = this;//need a ref back to this part
-        var wireframe = new THREE.EdgesHelper(mesh, 0x000000);
-        mesh.children.push(wireframe);
-        return mesh;
-    };
-
-    self.DMAGIKPart = DMAGIKPart;
-
-})();
-
-(function () {
-
-    var unitPartGeo;
-
-    //import part geometry
-    var loader = new THREE.STLLoader();
-    loader.load("assets/stls/parts/GIKPartLowPoly.stl", function(geometry){
-
-        unitPartGeo = geometry;
-        unitPartGeo.computeBoundingBox();
-        unitPartGeo.applyMatrix(new THREE.Matrix4().makeTranslation(-(unitPartGeo.boundingBox.min.x+unitPartGeo.boundingBox.max.x)/2,
-            -(unitPartGeo.boundingBox.min.y+unitPartGeo.boundingBox.max.y)/2, -(unitPartGeo.boundingBox.min.z+unitPartGeo.boundingBox.max.z)/2));
-        var unitScale = 1/(1.2699999809265137);
-        unitPartGeo.applyMatrix(new THREE.Matrix4().makeRotationX(Math.PI/2));
-        unitPartGeo.applyMatrix(new THREE.Matrix4().makeScale(unitScale, unitScale, unitScale));
-    });
-
-    function DMAGIKPartLowPoly(type, parent){
-        DMAGIKPart.call(this, type, parent);
-    }
-    DMAGIKPartLowPoly.prototype = Object.create(DMAGIKPart.prototype);
-
-    DMAGIKPartLowPoly.prototype._makeMeshForType = function(){
-        var mesh = new THREE.Mesh(unitPartGeo, this.parentCell.getMaterialType());
-        mesh.myPart = this;//need a ref back to this part
-        return mesh;
-    };
-
-    self.DMAGIKPartLowPoly = DMAGIKPartLowPoly;
-
-})();
-
-(function () {
-
-    var unitPartGeo;
-
-    //import part geometry
-    var loader = new THREE.STLLoader();
-    loader.load("assets/stls/parts/GIKEndPart.stl", function(geometry){
-
-        unitPartGeo = geometry;
-        unitPartGeo.computeBoundingBox();
-        unitPartGeo.applyMatrix(new THREE.Matrix4().makeTranslation(-(unitPartGeo.boundingBox.min.x+0.5),
-            -(unitPartGeo.boundingBox.min.y+unitPartGeo.boundingBox.max.y)/2, -(unitPartGeo.boundingBox.min.z+unitPartGeo.boundingBox.max.z)/2));
-        var unitScale = 1/(1.2699999809265137);
-        unitPartGeo.applyMatrix(new THREE.Matrix4().makeRotationX(Math.PI/2));
-        unitPartGeo.applyMatrix(new THREE.Matrix4().makeScale(unitScale, unitScale, unitScale));
-    });
-
-    function DMAGIKEndPart(type, parent){
-        DMAGIKPart.call(this, type, parent);
-    }
-    DMAGIKEndPart.prototype = Object.create(DMAGIKPart.prototype);
-
-    DMAGIKEndPart.prototype._makeMeshForType = function(){
-        var mesh = new THREE.Mesh(unitPartGeo, this.parentCell.getMaterialType());
-        mesh.myPart = this;//need a ref back to this part
-        return mesh;
-    };
-
-    self.DMAGIKEndPart = DMAGIKEndPart;
-
-})();
-
-(function () {
-
-    var unitPartGeo;
-
-    //import part geometry
-    var loader = new THREE.STLLoader();
-    loader.load("assets/stls/parts/GIKEndPartLowPoly.stl", function(geometry){
-
-        unitPartGeo = geometry;
-        unitPartGeo.computeBoundingBox();
-        unitPartGeo.applyMatrix(new THREE.Matrix4().makeTranslation(-(unitPartGeo.boundingBox.min.x+0.5),
-            -(unitPartGeo.boundingBox.min.y+unitPartGeo.boundingBox.max.y)/2, -(unitPartGeo.boundingBox.min.z+unitPartGeo.boundingBox.max.z)/2));
-        var unitScale = 1/(1.2699999809265137);
-        unitPartGeo.applyMatrix(new THREE.Matrix4().makeRotationX(Math.PI/2));
-        unitPartGeo.applyMatrix(new THREE.Matrix4().makeScale(unitScale, unitScale, unitScale));
-    });
-
-    function DMAGIKEndPartLowPoly(type, parent){
-        DMAGIKPart.call(this, type, parent);
-    }
-    DMAGIKEndPartLowPoly.prototype = Object.create(DMAGIKPart.prototype);
-
-    DMAGIKEndPartLowPoly.prototype._makeMeshForType = function(){
-        var mesh = new THREE.Mesh(unitPartGeo, this.parentCell.getMaterialType());
-        mesh.myPart = this;//need a ref back to this part
-        return mesh;
-    };
-
-    self.DMAGIKEndPartLowPoly = DMAGIKEndPartLowPoly;
-
-})();
\ No newline at end of file
diff --git a/js/lattice/Lattice.js b/js/lattice/Lattice.js
index ac7c6075ff68af0370d0e824ffe938872ecdf3c0..e349ffa4bd78f5d92268365c2c871b9cf4e622e3 100644
--- a/js/lattice/Lattice.js
+++ b/js/lattice/Lattice.js
@@ -333,9 +333,8 @@ Lattice = Backbone.Model.extend({
 
     _updateForMode: function(){
         var cellMode = globals.appState.get("cellMode");
-        var partType =  this.get("partType");
         this._iterCells(this.get("cells"), function(cell){
-            if (cell) cell.draw(cellMode, partType);
+            if (cell) cell.setMode(cellMode);
         });
         globals.three.render();
     },
@@ -364,20 +363,15 @@ Lattice = Backbone.Model.extend({
     //hide show cells during stock simulation
     hideCells: function(){
         this._iterCells(this.get("cells"), function(cell){
-            if (cell) {
-                cell.hide();
-                cell.hideForStockSimulation = true;
-            }
+            if (cell) cell.hide();
         });
         globals.three.render();
     },
 
     showCells: function(){
+        var cellMode = globals.appState.get("cellMode");
         this._iterCells(this.get("cells"), function(cell){
-            if (cell) {
-                cell.hideForStockSimulation = false;
-                cell.draw();
-            }
+            if (cell) cell.show(cellMode)
         });
         globals.three.render();
     },
@@ -385,10 +379,7 @@ Lattice = Backbone.Model.extend({
     showCellAtIndex: function(index){
         var latticeIndex = this._subtract(index, this.get("cellsMin"));
         var cell = this.get("cells")[latticeIndex.x][latticeIndex.y][latticeIndex.z];
-        if (cell) {
-            cell.hideForStockSimulation = false;
-            cell.draw();
-        }
+        if (cell) cell.show();
         else console.warn("placing a cell that does not exist");
     },
 
diff --git a/js/parts/DMAPart.js b/js/parts/DMAPart.js
index 9311de8510e74109622bab3b3c47260c3c6a673a..43ef549e55e1a1ce14c283aedaf65d2b4eabc67f 100644
--- a/js/parts/DMAPart.js
+++ b/js/parts/DMAPart.js
@@ -7,26 +7,17 @@ var partMaterial = new THREE.MeshLambertMaterial({ color:0xffffff, shading: THRE
     partMaterial.color.setRGB( 0.9619657144369509, 0.6625466032079207, 0.20799727886007258 );
 
 function DMAPart(index) {
-    this.index = index;
-    this.mesh = this._buildMesh();
+    this.index = index;//todo need this?
+    this.mesh = this._buildMesh(index);
 }
 
-DMAPart.prototype._buildMesh = function(){
-    var geometry = this._getGeometry();
+DMAPart.prototype._buildMesh = function(index){
+    var geometry = this._getGeometry(index);
     var mesh = new THREE.Mesh(geometry, partMaterial);
     mesh.name = "part";
     return mesh;
 };
 
-DMAPart.prototype._draw = function(){
-    if (this.mesh) console.warn("part mesh already in scene");
-    this.mesh = this._makeMeshForType(this.type);
-    var rotation = this.parentCell.getEulerRotation();
-    this.mesh.rotation.set(rotation.x, rotation.y, rotation.z);
-    this._setMeshPosition(this.parentCell.getPosition());
-    globals.three.sceneAdd(this.mesh, "part");
-};
-
 DMAPart.prototype.highlight = function(){
 //        this.mesh.material.color.setRGB(1,0,0);
 };
@@ -35,24 +26,23 @@ DMAPart.prototype.unhighlight = function(){
 //        if (this.mesh) this.mesh.material.color.setRGB(0.9619657144369509, 0.6625466032079207, 0.20799727886007258);
 };
 
-DMAPart.prototype.removeFromCell = function(){//send message back to parent cell to destroy this
-    if (this.parentCell) {
-        this.parentCell.removePart(this.type);
-        globals.three.render();
-    } else console.warn("part has no parent cell");
+//DMAPart.prototype.removeFromCell = function(){//send message back to parent cell to destroy this
+//    if (this.parentCell) {
+//        this.parentCell.removePart(this.index);
+//        globals.three.render();
+//    } else console.warn("part has no parent cell");
+//};
+
+DMAPart.prototype.getMesh = function(){//only call by parent cell
+    return this.mesh;
 };
 
 DMAPart.prototype.destroy = function(){
     if (this.mesh) {
-        globals.three.sceneRemove(this.mesh, "part");
-        this.mesh.myPart = null;
-//            this.mesh.dispose();
-//            geometry.dispose();
-//            material.dispose();
+        this.mesh.parent.remove(this.mesh);
         this.mesh = null;
     }
-    this.parentCell = null;
-    this.type = null;
+    this.index = null;
 };
 
 DMAPart.prototype.toJSON = function(){
diff --git a/js/parts/GIKMicroLegoPart.js b/js/parts/GIKMicroLegoPart.js
new file mode 100644
index 0000000000000000000000000000000000000000..0098a4c6dea56e92fe027ed7aa0b066a56ac002b
--- /dev/null
+++ b/js/parts/GIKMicroLegoPart.js
@@ -0,0 +1,148 @@
+/**
+ * Created by aghassaei on 5/26/15.
+ */
+
+
+(function () {
+
+    var unitPartGeo;
+
+    //import part geometry
+    var loader = new THREE.STLLoader();
+    loader.load("assets/stls/parts/GIKPart.stl", function(geometry){
+
+        unitPartGeo = geometry;
+        unitPartGeo.computeBoundingBox();
+        unitPartGeo.applyMatrix(new THREE.Matrix4().makeTranslation(-(unitPartGeo.boundingBox.min.x+unitPartGeo.boundingBox.max.x)/2,
+            -(unitPartGeo.boundingBox.min.y+unitPartGeo.boundingBox.max.y)/2, -(unitPartGeo.boundingBox.min.z+unitPartGeo.boundingBox.max.z)/2));
+        var unitScale = 1/(1.2699999809265137);
+        unitPartGeo.applyMatrix(new THREE.Matrix4().makeRotationX(Math.PI/2));
+        unitPartGeo.applyMatrix(new THREE.Matrix4().makeScale(unitScale, unitScale, unitScale));
+    });
+
+    function DMAGIKPart(type, parent){
+        DMAPart.call(this, type, parent);
+    }
+    DMAGIKPart.prototype = Object.create(DMAPart.prototype);
+
+    DMAGIKPart.prototype._makeGikWireframe = function(positions, yPosition){
+        var geometry = new THREE.Geometry();
+        _.each(positions, function(position, index){
+            if (position == yPosition){
+                geometry.vertices.push(new THREE.Vector3(positions[index-1], yPosition, positions[index+1]));
+            }
+        });
+        console.log(geometry.vertices);
+        return new THREE.Line(geometry);
+    };
+
+    DMAGIKPart.prototype._makeMeshForType = function(){
+        var mesh = new THREE.Mesh(unitPartGeo, this.parentCell.getMaterialType());
+
+
+
+        mesh.myPart = this;//need a ref back to this part
+        var wireframe = new THREE.EdgesHelper(mesh, 0x000000);
+        mesh.children.push(wireframe);
+        return mesh;
+    };
+
+    self.DMAGIKPart = DMAGIKPart;
+
+})();
+
+(function () {
+
+    var unitPartGeo;
+
+    //import part geometry
+    var loader = new THREE.STLLoader();
+    loader.load("assets/stls/parts/GIKPartLowPoly.stl", function(geometry){
+
+        unitPartGeo = geometry;
+        unitPartGeo.computeBoundingBox();
+        unitPartGeo.applyMatrix(new THREE.Matrix4().makeTranslation(-(unitPartGeo.boundingBox.min.x+unitPartGeo.boundingBox.max.x)/2,
+            -(unitPartGeo.boundingBox.min.y+unitPartGeo.boundingBox.max.y)/2, -(unitPartGeo.boundingBox.min.z+unitPartGeo.boundingBox.max.z)/2));
+        var unitScale = 1/(1.2699999809265137);
+        unitPartGeo.applyMatrix(new THREE.Matrix4().makeRotationX(Math.PI/2));
+        unitPartGeo.applyMatrix(new THREE.Matrix4().makeScale(unitScale, unitScale, unitScale));
+    });
+
+    function DMAGIKPartLowPoly(type, parent){
+        DMAGIKPart.call(this, type, parent);
+    }
+    DMAGIKPartLowPoly.prototype = Object.create(DMAGIKPart.prototype);
+
+    DMAGIKPartLowPoly.prototype._makeMeshForType = function(){
+        var mesh = new THREE.Mesh(unitPartGeo, this.parentCell.getMaterialType());
+        mesh.myPart = this;//need a ref back to this part
+        return mesh;
+    };
+
+    self.DMAGIKPartLowPoly = DMAGIKPartLowPoly;
+
+})();
+
+(function () {
+
+    var unitPartGeo;
+
+    //import part geometry
+    var loader = new THREE.STLLoader();
+    loader.load("assets/stls/parts/GIKEndPart.stl", function(geometry){
+
+        unitPartGeo = geometry;
+        unitPartGeo.computeBoundingBox();
+        unitPartGeo.applyMatrix(new THREE.Matrix4().makeTranslation(-(unitPartGeo.boundingBox.min.x+0.5),
+            -(unitPartGeo.boundingBox.min.y+unitPartGeo.boundingBox.max.y)/2, -(unitPartGeo.boundingBox.min.z+unitPartGeo.boundingBox.max.z)/2));
+        var unitScale = 1/(1.2699999809265137);
+        unitPartGeo.applyMatrix(new THREE.Matrix4().makeRotationX(Math.PI/2));
+        unitPartGeo.applyMatrix(new THREE.Matrix4().makeScale(unitScale, unitScale, unitScale));
+    });
+
+    function DMAGIKEndPart(type, parent){
+        DMAGIKPart.call(this, type, parent);
+    }
+    DMAGIKEndPart.prototype = Object.create(DMAGIKPart.prototype);
+
+    DMAGIKEndPart.prototype._makeMeshForType = function(){
+        var mesh = new THREE.Mesh(unitPartGeo, this.parentCell.getMaterialType());
+        mesh.myPart = this;//need a ref back to this part
+        return mesh;
+    };
+
+    self.DMAGIKEndPart = DMAGIKEndPart;
+
+})();
+
+(function () {
+
+    var unitPartGeo;
+
+    //import part geometry
+    var loader = new THREE.STLLoader();
+    loader.load("assets/stls/parts/GIKEndPartLowPoly.stl", function(geometry){
+
+        unitPartGeo = geometry;
+        unitPartGeo.computeBoundingBox();
+        unitPartGeo.applyMatrix(new THREE.Matrix4().makeTranslation(-(unitPartGeo.boundingBox.min.x+0.5),
+            -(unitPartGeo.boundingBox.min.y+unitPartGeo.boundingBox.max.y)/2, -(unitPartGeo.boundingBox.min.z+unitPartGeo.boundingBox.max.z)/2));
+        var unitScale = 1/(1.2699999809265137);
+        unitPartGeo.applyMatrix(new THREE.Matrix4().makeRotationX(Math.PI/2));
+        unitPartGeo.applyMatrix(new THREE.Matrix4().makeScale(unitScale, unitScale, unitScale));
+    });
+
+    function DMAGIKEndPartLowPoly(type, parent){
+        DMAGIKPart.call(this, type, parent);
+    }
+    DMAGIKEndPartLowPoly.prototype = Object.create(DMAGIKPart.prototype);
+
+    DMAGIKEndPartLowPoly.prototype._makeMeshForType = function(){
+        var mesh = new THREE.Mesh(unitPartGeo, this.parentCell.getMaterialType());
+        mesh.myPart = this;//need a ref back to this part
+        return mesh;
+    };
+
+    self.DMAGIKEndPartLowPoly = DMAGIKEndPartLowPoly;
+
+})();
\ No newline at end of file
diff --git a/js/parts/OctaEdgeVoxPart.js b/js/parts/OctaEdgeVoxPart.js
new file mode 100644
index 0000000000000000000000000000000000000000..b4d29f18150c131dab3570e825f05ced5e0bfaa6
--- /dev/null
+++ b/js/parts/OctaEdgeVoxPart.js
@@ -0,0 +1,60 @@
+/**
+ * Created by aghassaei on 5/26/15.
+ */
+
+
+(function () {
+
+    var unitPartGeo;
+
+    //import part geometry
+    var loader = new THREE.STLLoader();
+    loader.load("assets/stls/parts/edgeVoxPart.stl", function(geometry){
+
+        unitPartGeo = geometry;
+        unitPartGeo.computeBoundingBox();
+        var unitScale = 0.706/unitPartGeo.boundingBox.max.y;
+        unitPartGeo.applyMatrix(new THREE.Matrix4().makeScale(unitScale, unitScale, unitScale));
+        unitPartGeo.applyMatrix(new THREE.Matrix4().makeRotationY(Math.PI));
+        unitPartGeo.applyMatrix(new THREE.Matrix4().makeTranslation(0,0,0.09));
+    });
+
+    function OctaEdgeVoxPart(type){
+        DMAPart.call(this, type);
+    }
+    OctaEdgeVoxPart.prototype = Object.create(DMAPart.prototype);
+
+    OctaEdgeVoxPart.prototype._getGeometry = function(){
+        return unitPartGeo;
+    };
+
+    self.OctaEdgeVoxPart = OctaEdgeVoxPart;
+
+})();
+
+(function () {
+
+    var unitPartGeo;
+
+    //import part geometry
+    var loader = new THREE.STLLoader();
+    loader.load("assets/stls/parts/edgeVoxPartLowPoly.stl", function(geometry){
+
+        unitPartGeo = geometry;
+        unitPartGeo.computeBoundingBox();
+        var unitScale = 0.706/unitPartGeo.boundingBox.max.y;
+        unitPartGeo.applyMatrix(new THREE.Matrix4().makeScale(unitScale, unitScale, unitScale));
+    });
+
+    function OctaEdgeVoxPartLowPoly(type, parent){
+        DMAPart.call(this, type, parent);
+    }
+    OctaEdgeVoxPartLowPoly.prototype = Object.create(DMAPart.prototype);
+
+    OctaEdgeVoxPartLowPoly.prototype._getGeometry = function(){
+        return unitPartGeo;
+    };
+
+    self.OctaEdgeVoxPartLowPoly = OctaEdgeVoxPartLowPoly;
+
+})();
\ No newline at end of file
diff --git a/js/parts/OctaFaceTriPart.js b/js/parts/OctaFaceTriPart.js
new file mode 100644
index 0000000000000000000000000000000000000000..317ab03e3d7d4304a4cfc17dc6ff8a5e111082ee
--- /dev/null
+++ b/js/parts/OctaFaceTriPart.js
@@ -0,0 +1,47 @@
+/**
+ * Created by aghassaei on 5/26/15.
+ */
+
+
+(function () {
+
+var unitPartGeo1, unitPartGeo2, unitPartGeo3;
+
+//import part geometry
+var loader = new THREE.STLLoader();
+loader.load("assets/stls/parts/trianglePart.stl", function(geometry){
+
+    unitPartGeo1 = geometry;
+    unitPartGeo1.computeBoundingBox();
+    var unitScale = 1.2/unitPartGeo1.boundingBox.max.y;
+    unitPartGeo1.applyMatrix(new THREE.Matrix4().makeScale(unitScale, unitScale, unitScale));
+    unitPartGeo1.applyMatrix(new THREE.Matrix4().makeTranslation(0.25,-0.6, -0.45));
+    unitPartGeo1.applyMatrix(new THREE.Matrix4().makeRotationZ(-Math.PI/6));
+
+    unitPartGeo2 = unitPartGeo1.clone();
+    unitPartGeo2.applyMatrix(new THREE.Matrix4().makeRotationZ(2*Math.PI/3));
+
+    unitPartGeo3 = unitPartGeo1.clone();
+    unitPartGeo3.applyMatrix(new THREE.Matrix4().makeRotationZ(-2*Math.PI/3));
+});
+
+function OctaFaceTriPart(type){
+    DMAPart.call(this, type);
+}
+OctaFaceTriPart.prototype = Object.create(DMAPart.prototype);
+
+OctaFaceTriPart.prototype._getGeometry = function(index){
+    switch(index){
+        case 0:
+            return unitPartGeo1;
+        case 1:
+            return unitPartGeo2;
+        case 2:
+            return unitPartGeo3;
+    }
+    console.warn("no geometry for index " + index);
+    return null;
+};
+
+self.OctaFaceTriPart = OctaFaceTriPart;
+})();
\ No newline at end of file
diff --git a/js/parts/OctaTrianglePart.js b/js/parts/OctaTrianglePart.js
deleted file mode 100644
index 3a69655c88c371a20fe62e547001ccf24a03ab85..0000000000000000000000000000000000000000
--- a/js/parts/OctaTrianglePart.js
+++ /dev/null
@@ -1,3 +0,0 @@
-/**
- * Created by aghassaei on 5/26/15.
- */