From 4beed27c3e5a9f14b900f29e4a08481d6b93a657 Mon Sep 17 00:00:00 2001
From: Amanda Ghassaei <amandaghassaei@gmail.com>
Date: Wed, 25 Feb 2015 15:47:40 -0500
Subject: [PATCH] beginning to add inverse cells

---
 js/fea/DmaCell.js    |  78 +++++++++++++++------
 js/models/Lattice.js | 158 ++++++++++++++++++++-----------------------
 2 files changed, 131 insertions(+), 105 deletions(-)

diff --git a/js/fea/DmaCell.js b/js/fea/DmaCell.js
index 314f156e..1c9f0b07 100644
--- a/js/fea/DmaCell.js
+++ b/js/fea/DmaCell.js
@@ -13,7 +13,6 @@ function DMACell(indices, scale, lattice) {
     this.parts = this._initParts(indices.z);
     this.updateForScale(scale);
 
-    dmaGlobals.three.sceneAdd(this.cellMesh, "cell");
     this.drawForMode(dmaGlobals.appState.get("cellMode"));
 }
 
@@ -101,21 +100,15 @@ DMACell.prototype.destroy = function(){
 
 (function () {
 
-    var unitCellGeo1 = new THREE.OctahedronGeometry(1/Math.sqrt(2));
-    unitCellGeo1.applyMatrix(new THREE.Matrix4().makeRotationZ(-3*Math.PI/12));
-    unitCellGeo1.applyMatrix(new THREE.Matrix4().makeRotationX(Math.asin(2/Math.sqrt(2)/Math.sqrt(3))));
-//    var unitOctHeight = 2/Math.sqrt(6);
-//    unitCellGeo1.applyMatrix(new THREE.Matrix4().makeTranslation(0,0,unitOctHeight/2));
-
-    var unitCellGeo2 = unitCellGeo1.clone();
-
-    unitCellGeo2.applyMatrix(new THREE.Matrix4().makeRotationZ(Math.PI));
+    var unitCellGeo = new THREE.OctahedronGeometry(1/Math.sqrt(2));
+    unitCellGeo.applyMatrix(new THREE.Matrix4().makeRotationZ(-3*Math.PI/12));
+    unitCellGeo.applyMatrix(new THREE.Matrix4().makeRotationX(Math.asin(2/Math.sqrt(2)/Math.sqrt(3))));
 
     var cellMaterials = [new THREE.MeshNormalMaterial(),
         new THREE.MeshBasicMaterial({color:0x000000, wireframe:true})];
 
-    function DMASideOctaCell(mode, indices, scale, lattice){
-        DMACell.call(this, mode, indices, scale, lattice);
+    function DMASideOctaCell(indices, scale, lattice){
+        DMACell.call(this, indices, scale, lattice);
     }
     DMASideOctaCell.prototype = Object.create(DMACell.prototype);
 
@@ -129,12 +122,10 @@ DMACell.prototype.destroy = function(){
 
     DMASideOctaCell.prototype._buildCellMesh = function(zIndex){//abstract mesh representation of cell
         var mesh;
-        if (zIndex%2==0){
-            mesh = THREE.SceneUtils.createMultiMaterialObject(unitCellGeo1, cellMaterials);
-        } else {
-            mesh = THREE.SceneUtils.createMultiMaterialObject(unitCellGeo2, cellMaterials);
-        }
+        mesh = THREE.SceneUtils.createMultiMaterialObject(unitCellGeo, cellMaterials);
+        if (zIndex%2!=0) mesh.rotation.set(0, 0, Math.PI);
         mesh.myParent = this;//we need a reference to this instance from the mesh for intersection selection stuff
+        dmaGlobals.three.sceneAdd(mesh, "cell");
         return mesh;
     };
 
@@ -150,6 +141,49 @@ DMACell.prototype.destroy = function(){
 
     self.DMASideOctaCell = DMASideOctaCell;
 
+    /////////////////////////////////////////////////TETRA CELL////////////////////////////////////
+
+    var unitTetraCellGeo = new THREE.TetrahedronGeometry(Math.sqrt(3/8));
+    unitTetraCellGeo.applyMatrix(new THREE.Matrix4().makeRotationZ(Math.PI/4));
+    unitTetraCellGeo.applyMatrix(new THREE.Matrix4().makeRotationX((Math.PI-Math.atan(2*Math.sqrt(2)))/2));
+    unitTetraCellGeo.applyMatrix(new THREE.Matrix4().makeTranslation(0,0,1/Math.sqrt(8)/2));
+
+    function DMATetraCell(indices, scale, lattice){
+        DMACell.call(this, indices, scale, lattice);
+    }
+    DMATetraCell.prototype = Object.create(DMACell.prototype);
+
+    DMATetraCell.prototype._initParts = function(){
+        return [];
+    };
+
+    DMATetraCell.prototype._buildCellMesh = function(zIndex){//abstract mesh representation of cell
+        var mesh;
+        mesh = THREE.SceneUtils.createMultiMaterialObject(unitTetraCellGeo, cellMaterials);
+        if (zIndex%2!=0) mesh.rotation.set(Math.PI,0,0);
+
+        mesh.myParent = this;//we need a reference to this instance from the mesh for intersection selection stuff
+        dmaGlobals.three.sceneAdd(mesh, "inverseCell");
+        mesh.visible = false;
+        return mesh;
+    };
+
+    DMATetraCell.prototype.calcHighlighterPosition = function(face){
+
+        var direction = face.normal;
+        if (face.normal.z<0.99) direction = null;//only highlight horizontal faces
+
+        var position = dmaGlobals.lattice.getPositionForIndex(this.indices);
+        position.z += dmaGlobals.lattice.zScale()/2;
+        return {index: _.clone(this.indices), direction:direction, position:position};
+    };
+
+    DMATetraCell.prototype.getPosition = function(){//need for part relay
+        return dmaGlobals.lattice.getInvCellPositionForIndex(this.indices);
+    };
+
+    self.DMATetraCell = DMATetraCell;
+
 })();
 
 ///////////////////////////////////////////////////////////////////////////////////////////////
@@ -165,8 +199,8 @@ DMACell.prototype.destroy = function(){
         new THREE.MeshBasicMaterial({color:0x000000, wireframe:true})];
 
 
-    function DMAVertexOctaCell(mode, indices, scale, lattice){
-        DMACell.call(this, mode, indices, scale, lattice);
+    function DMAVertexOctaCell(indices, scale, lattice){
+        DMACell.call(this, indices, scale, lattice);
     }
     DMAVertexOctaCell.prototype = Object.create(DMACell.prototype);
 
@@ -181,6 +215,7 @@ DMACell.prototype.destroy = function(){
     DMAVertexOctaCell.prototype._buildCellMesh = function(zIndex){//abstract mesh representation of cell
         var mesh = THREE.SceneUtils.createMultiMaterialObject(unitCellGeo, cellMaterials);
         mesh.myParent = this;//we need a reference to this instance from the mesh for intersection selection stuff
+        dmaGlobals.three.sceneAdd(mesh, "cell");
         return mesh;
     };
 
@@ -202,8 +237,8 @@ DMACell.prototype.destroy = function(){
         new THREE.MeshBasicMaterial({color:0x000000, wireframe:true})];
 
 
-    function DMACubeCell(mode, indices, scale, lattice){
-        DMACell.call(this, mode, indices, scale, lattice);
+    function DMACubeCell(indices, scale, lattice){
+        DMACell.call(this, indices, scale, lattice);
     }
     DMACubeCell.prototype = Object.create(DMACell.prototype);
 
@@ -221,6 +256,7 @@ DMACell.prototype.destroy = function(){
 //        var wireframe = new THREE.BoxHelper(mesh);
 //        wireframe.material.color.set(0x000000);
 //        mesh.add(wireframe);
+        dmaGlobals.three.sceneAdd(mesh, "cell");
         return mesh;
     };
 
diff --git a/js/models/Lattice.js b/js/models/Lattice.js
index 05f4a9a6..8bf03b4f 100644
--- a/js/models/Lattice.js
+++ b/js/models/Lattice.js
@@ -9,12 +9,15 @@ Lattice = Backbone.Model.extend({
         scale: window.defaultLatticeScale,
         nodes: [],
         cells: [[[null]]],//3D matrix containing all cells and null, dynamic size
-        inverseCells: [[[null]]],//3d matrix containing all inverse cells and null, dynamic size
         cellsMin: {x:0, y:0, z:0},//min position of cells matrix
         cellsMax: {x:0, y:0, z:0},//max position of cells matrix
+        inverseCells: [[[null]]],//3d matrix containing all inverse cells and null, dynamic size
+        inverseCellsMin: {x:0, y:0, z:0},//min position of inverse cells matrix
+        inverseCellsMax: {x:0, y:0, z:0},//max position of inverse cells matrix
         numCells: 0,
+        numInvCells: 0,
         basePlane: null,//plane to build from
-        highlighter: null,//highlights buildable surfaces
+        highlighter: null,//highlights build-able surfaces
         shouldPreserveCells: true//preserve cells when changing lattice type
     },
 
@@ -33,7 +36,7 @@ Lattice = Backbone.Model.extend({
     addCellsInRange: function(range){//add a block of cells
         var scale = this.get("scale");
         var cells = this.get("cells");
-        this._checkForMatrixExpansion(cells, range.max, range.min);
+        this._checkForMatrixExpansion(cells, range.max, range.min, "cellsMax", "cellsMin");
 
         var cellsMin = this.get("cellsMin");
         var relativeMin = this._subtract(range.min, cellsMin);
@@ -56,12 +59,13 @@ Lattice = Backbone.Model.extend({
 
         var scale = this.get("scale");
         var cells = this.get("cells");
-        this._checkForMatrixExpansion(cells, indices, indices);
+        this._checkForMatrixExpansion(cells, indices, indices, "cellsMax", "cellsMin");
 
         var index = this._subtract(indices, this.get("cellsMin"));
         if (!cells[index.x][index.y][index.z]) {
             cells[index.x][index.y][index.z] = this._makeCellForLatticeType(indices, scale);
             this.set("numCells", this.get("numCells")+1);
+            if (this._shouldHaveInverseCells()) this._addInverseCellsForIndex(indices);
             dmaGlobals.three.render();
         } else console.warn("already a cell there");
 
@@ -177,19 +181,19 @@ Lattice = Backbone.Model.extend({
     ///////////////////////////////CELLS ARRAY//////////////////////////////////////////
     ////////////////////////////////////////////////////////////////////////////////////
 
-    _checkForMatrixExpansion: function(cells, indicesMax, indicesMin){
+    _checkForMatrixExpansion: function(cells, indicesMax, indicesMin, maxName, minName){
 
-        var lastMax = this.get("cellsMax");
-        var lastMin = this.get("cellsMin");
+        var lastMax = this.get(maxName);
+        var lastMin = this.get(minName);
         var newMax = this._updateCellsMax(indicesMax, lastMax);
         var newMin = this._updateCellsMin(indicesMin, lastMin);
         if (newMax) {
             this._expandCellsArray(cells, this._subtract(newMax, lastMax), false);
-            this.set("cellsMax", newMax);
+            this.set(maxName, newMax);
         }
         if (newMin) {
             this._expandCellsArray(cells, this._subtract(lastMin, newMin), true);
-            this.set("cellsMin", newMin);
+            this.set(minName, newMin);
         }
     },
 
@@ -409,7 +413,28 @@ Lattice = Backbone.Model.extend({
             position.x = (position.x+1/2)*xScale;
             position.y = position.y*this.yScale(scale)+scale/Math.sqrt(3)/2;
             position.z = (position.z+0.5)*this.zScale(scale);
-            if (Math.abs(index.y%2) == 1) position.x -= this.xScale()/2;
+            if ((index.y%2) != 0) position.x -= this.xScale()/2;
+            return position;
+        },
+
+        getInvCellPositionForIndex: function(index){
+
+            var scale = this.get("scale");
+            var position = _.clone(index);
+
+            var oddZ = (position.z%2 != 0);
+            position.z /= 2;
+            var xScale = this.xScale(scale);
+            if (oddZ){
+                position.x = (position.x)*xScale;
+                position.y = position.y*this.yScale(scale);
+                position.z = (position.z+0.5)*this.zScale(scale);
+            } else {
+                position.x = (position.x+0.5)*xScale;
+                position.y = (position.y)*this.yScale(scale)-scale/Math.sqrt(3)/2;
+                position.z = (position.z)*this.zScale(scale);
+            }
+            if ((index.y%2) != 0) position.x -= this.xScale()/2;
             return position;
         },
 
@@ -432,6 +457,41 @@ Lattice = Backbone.Model.extend({
             return new DMASideOctaCell(indices, scale, this);
         },
 
+        _makeInvCellForLatticeType: function(indices, scale){
+            return new DMATetraCell(indices, scale, this);
+        },
+
+        _shouldHaveInverseCells: function(){
+            return true;
+        },
+
+        _addInverseCellsForIndex: function(index){
+
+            index = _.clone(index);
+            index.z*=2;
+            var inverseIndicesToAdd = [
+                this._add(index, {x:0,y:0,z:0}),
+                this._add(index, {x:0,y:1,z:0}),
+                this._add(index, {x:1,y:1,z:0}),
+
+                this._add(index, {x:0,y:0,z:1}),
+                this._add(index, {x:1,y:0,z:1}),
+                this._add(index, {x:1,y:1,z:1})
+            ];
+
+            var invCells = this.get("inverseCells");
+            var scale = this.get("scale");
+            var self = this;
+            _.each(inverseIndicesToAdd, function(invIndex){
+                self._checkForMatrixExpansion(invCells, invIndex, invIndex, "inverseCellsMax", "inverseCellsMin");
+                var indexRel = self._subtract(invIndex, self.get("inverseCellsMin"));
+                if (!invCells[indexRel.x][indexRel.y][indexRel.z]) {
+                    invCells[indexRel.x][indexRel.y][indexRel.z] = self._makeInvCellForLatticeType(invIndex, scale);
+                    self.set("numInvCells", self.get("numInvCells")+1);
+                }
+            });
+        },
+
         _undo: function(){//remove all the mixins, this will help with debugging later
             this.stopListening(this, "columnSeparation");
             this.set("columnSeparation", null);
@@ -449,51 +509,6 @@ Lattice = Backbone.Model.extend({
 
     OctaEdgeLattice: {
 
-        _initLatticeType: function(){
-
-            //bind events
-            this.set("columnSeparation", 0.0, {silent:true});
-            this.listenTo(this, "change:columnSeparation", this._changeColSeparation);
-
-            this.set("basePlane", new OctaBasePlane({scale:this.get("scale")}));
-            this.set("highlighter", new OctaFaceHighlighter({scale:this.get("scale")}));
-        },
-
-        _changeColSeparation: function(){
-            var colSep = this.get("columnSeparation");
-            var scale = this.get("scale");
-            this.get("basePlane").updateColSeparation(colSep);
-            this._iterCells(this.get("cells"), function(cell){
-                if (cell) cell.updateForScale(scale);
-            });
-            dmaGlobals.three.render();
-        },
-
-        getIndexForPosition: function(absPosition){
-            var position = this._indexForPosition(absPosition);
-            if (position.z%2 == 1) position.y += 1;
-            return position;
-        },
-
-        xScale: function(scale){
-            if (!scale) scale = this.get("scale");
-            var colSep = this.get("columnSeparation");
-            return scale*(1+2*colSep);
-        },
-
-        yScale: function(scale){
-            return this.xScale(scale)/2*Math.sqrt(3);
-        },
-
-        zScale: function(scale){
-            if (!scale) 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.stopListening(this, "columnSeparation");
             this.set("columnSeparation", null);
@@ -512,35 +527,6 @@ Lattice = Backbone.Model.extend({
 
     OctaVertexLattice: {
 
-        _initLatticeType: function(){
-
-            //bind events
-
-            this.set("basePlane", new SquareBasePlane({scale:this.get("scale")}));
-            this.set("highlighter", new OctaVertexHighlighter({scale:this.get("scale")}));
-        },
-
-        getIndexForPosition: function(absPosition){
-            return this._indexForPosition(absPosition);
-        },
-
-        xScale: function(scale){
-            if (!scale) scale = this.get("scale");
-            return scale;
-        },
-
-        yScale: function(scale){
-            return this.xScale(scale);
-        },
-
-        zScale: function(scale){
-            return this.xScale(scale);
-        },
-
-        _makeCellForLatticeType: function(indices, scale){
-            return new DMASideOctaCell(indices, scale, this);
-        },
-
         _undo: function(){//remove all the mixins, this will help with debugging later
             var self = this;
             _.each(_.keys(this.OctaVertexLattice), function(key){
@@ -591,6 +577,10 @@ Lattice = Backbone.Model.extend({
             return new DMACubeCell(indices, scale, this);
         },
 
+        _shouldHaveInverseCells: function(){
+            return false;
+        },
+
         _undo: function(){//remove all the mixins, this will help with debugging later
             var self = this;
             _.each(_.keys(this.CubeLattice), function(key){
-- 
GitLab