diff --git a/js/fea/DmaCell.js b/js/fea/DmaCell.js index a725a9a29a2c91008969d02a5bcbef3717b21215..9963ff0f3947e6987006691866c7308a26bc8d3e 100644 --- a/js/fea/DmaCell.js +++ b/js/fea/DmaCell.js @@ -218,7 +218,7 @@ DMACell.prototype.toJSON = function(){ direction.applyQuaternion(this.cellMesh.quaternion); var position = this.getPosition(); - var zScale = dmaGlobals.lattice.zScale(); + var zScale = this.zScale(); position.x += direction.x*zScale/2; position.y += direction.y*zScale/2; position.z += direction.z*zScale/2; @@ -228,13 +228,18 @@ DMACell.prototype.toJSON = function(){ DMAFreeFormOctaCell.prototype._calcPosition = function(){ var position = {}; - var zScale = dmaGlobals.lattice.zScale(); + var zScale = this.zScale(); position.x = this.parentPos.x+this.parentDirection.x*zScale/2; position.y = this.parentPos.y+this.parentDirection.y*zScale/2; position.z = this.parentPos.z+this.parentDirection.z*zScale/2; return position; }; + DMAFreeFormOctaCell.prototype.zScale = function(scale){ + if (!scale) scale = dmaGlobals.lattice.get("scale"); + return 2*scale/Math.sqrt(6); + }; + DMAFreeFormOctaCell.prototype.toJSON = function(){ var json = DMACell.prototype.toJSON.call(this); _.extend(json, { @@ -263,8 +268,8 @@ DMACell.prototype.toJSON = function(){ var unitCellGeoUpsideDown = unitCellGeo.clone(); unitCellGeoUpsideDown.applyMatrix(new THREE.Matrix4().makeRotationX(Math.PI)); - function DMATetraFaceCell(indices, scale){ - DMACell.call(this, indices, scale, true); + function DMATetraFaceCell(indices, scale, inverse){ + DMACell.call(this, indices, scale, inverse); } DMATetraFaceCell.prototype = Object.create(DMACell.prototype); @@ -286,6 +291,65 @@ DMACell.prototype.toJSON = function(){ self.DMATetraFaceCell = DMATetraFaceCell; + var unitCellGeo2 = new THREE.TetrahedronGeometry(Math.sqrt(3/8)); + unitCellGeo2.applyMatrix(new THREE.Matrix4().makeRotationZ(Math.PI/4)); + unitCellGeo2.applyMatrix(new THREE.Matrix4().makeRotationX((Math.PI-Math.atan(2*Math.sqrt(2)))/2)); + + function DMAFreeFormTetraCell(indices, scale, parentCellPos, parentCellQuat, direction){ + this.parentPos = parentCellPos; + this.parentQuaternion = parentCellQuat; + this.parentDirection = direction; + DMATetraFaceCell.call(this, indices, scale); + } + DMAFreeFormTetraCell.prototype = Object.create(DMATetraFaceCell.prototype); + + DMAFreeFormTetraCell.prototype._buildCellMesh = function(){//abstract mesh representation of cell + return this._superBuildCellMesh(unitCellGeo2); + }; + + DMAFreeFormTetraCell.prototype._doMeshTransformations = function(mesh){ + var direction = this.parentDirection.clone(); + var zAxis = new THREE.Vector3(0,0,1); + zAxis.applyQuaternion(this.parentQuaternion); + var quaternion = new THREE.Quaternion().setFromUnitVectors(zAxis, direction); + quaternion.multiply(this.parentQuaternion); + + var eulerRot = new THREE.Euler().setFromQuaternion(quaternion); + mesh.rotation.set(eulerRot.x, eulerRot.y, eulerRot.z); + }; + + DMAFreeFormTetraCell.prototype.calcHighlighterPosition = function(face){ + + var direction = face.normal.clone(); + direction.applyQuaternion(this.cellMesh.quaternion); + + var position = this.getPosition(); + var zScale = this.zScale(); + position.x += direction.x*zScale/2; + position.y += direction.y*zScale/2; + position.z += direction.z*zScale/2; + + return {index: _.clone(this.indices), direction:direction, position:position}; + }; + + DMAFreeFormTetraCell.prototype._calcPosition = function(){ + var position = {}; + var zScale = this.zScale(); + position.x = this.parentPos.x+this.parentDirection.x*zScale/2; + position.y = this.parentPos.y+this.parentDirection.y*zScale/2; + position.z = this.parentPos.z+this.parentDirection.z*zScale/2; + return position; + }; + + DMAFreeFormTetraCell.prototype.zScale = function(scale){ + if (!scale) scale = dmaGlobals.lattice.get("scale"); + return 2*scale/Math.sqrt(24); + }; + + self.DMAFreeFormTetraCell = DMAFreeFormTetraCell; + + + function DMATetraEdgeCell(indices, scale){ DMATetraFaceCell.call(this, indices, scale, true); } diff --git a/js/menus/LatticeMenuView.js b/js/menus/LatticeMenuView.js index dedd06f95ae9b67c0d58c2c1b9dd1bdde1615810..6ea1a5286dd4cd87e63be1edd2698f3c2c5cfd47 100644 --- a/js/menus/LatticeMenuView.js +++ b/js/menus/LatticeMenuView.js @@ -15,7 +15,9 @@ LatticeMenuView = Backbone.View.extend({ "slide #scaleSlider": "_sliderDidSlide", "slideStop #scaleSlider": "_changeScaleSlider", "change #preserveCells": "_changePreserveCells", - "change #showInverse": "_showInverseCells" + "change #showInverse": "_showInverseCells", + "click #freeformTetraCell": "_setTetraCell", + "click #freeformOctaCell": "_setOctaCell" }, @@ -112,6 +114,16 @@ LatticeMenuView = Backbone.View.extend({ this.lattice.set("inverseMode", $(e.target).prop("checked")); }, + _setTetraCell: function(e){ + e.preventDefault(); + this.lattice.set("freeformCellType", "tetra"); + }, + + _setOctaCell: function(e){ + e.preventDefault(); + this.lattice.set("freeformCellType", "octa"); + }, + render: function(){ if (this.model.get("currentTab") != "lattice") return; this.$el.html(this.template(_.extend(this.model.attributes, this.lattice.attributes))); @@ -142,7 +154,10 @@ LatticeMenuView = Backbone.View.extend({ <% }); %>\ </ul>\ </div><br/>\ - <% if (connectionType != "freeformFace") { %>\ + <% if (connectionType == "freeformFace") { %>\ + <a id="freeformOctaCell" href="#">draw with octa</a><br/>\ + <a id="freeformTetraCell" href="#">draw with tetra</a>\ + <% } else { %>\ <label class="checkbox">\ <input type="checkbox" <% if (shouldPreserveCells) { %> checked="checked" <% } %> value="" id="preserveCells" data-toggle="checkbox" class="custom-checkbox"><span class="icons"><span class="icon-unchecked"></span><span class="icon-checked"></span></span>\ Preserve cells on lattice change\ diff --git a/js/models/Lattice.js b/js/models/Lattice.js index 5f905eaab60c051036f61d3e696a58fcacb18a13..3a25b049c7d1a24e918931bef4876aa1c3a7ce4e 100644 --- a/js/models/Lattice.js +++ b/js/models/Lattice.js @@ -579,7 +579,7 @@ Lattice = Backbone.Model.extend({ }, _makeInvCellForLatticeType: function(indices, scale){ - return new DMATetraFaceCell(indices, scale); + return new DMATetraFaceCell(indices, scale, true); }, _inverseIndicesToAdd: function(index){ @@ -646,6 +646,8 @@ Lattice = Backbone.Model.extend({ this.set("basePlane", new OctaBasePlane({scale:this.get("scale")})); this.set("highlighter", new OctaFreeFormHighlighter({scale:this.get("scale")})); + this.set("freeformCellType", "octa"); + }, addFreeFormCell: function(parentCellPos, parentCellOrient, direction){ @@ -657,7 +659,8 @@ Lattice = Backbone.Model.extend({ }, _makeCellForLatticeType: function(index, scale, parentPosition, parentOrientation, direction){ - return new DMAFreeFormOctaCell(index, scale, parentPosition, parentOrientation, direction); + if (this.get("freeformCellType") == "octa") return new DMAFreeFormOctaCell(index, scale, parentPosition, parentOrientation, direction); + return new DMAFreeFormTetraCell(index, scale, parentPosition, parentOrientation, direction); }, getIndexForPosition: function(absPosition){//only used by baseplane @@ -692,11 +695,13 @@ Lattice = Backbone.Model.extend({ zScale: function(scale){ if (!scale) scale = this.get("scale"); - return 2*scale/Math.sqrt(6); + if (this.get("freeformCellType") == "octa") return 2*scale/Math.sqrt(6); + return 2*scale/Math.sqrt(24); }, _undo: function(){//remove all the mixins, this will help with debugging later var self = this; + this.set("freeformCellType", null); this.clearCells(); _.each(_.keys(this.OctaFreeFormFaceLattice), function(key){ self[key] = null;