diff --git a/js/fea/DmaCell.js b/js/fea/DmaCell.js index 9e5842bc078500146c00f7656a2d9f1ea24c76ff..7bf7350420b5108f2d6896afaf868ea088cd12a2 100644 --- a/js/fea/DmaCell.js +++ b/js/fea/DmaCell.js @@ -23,31 +23,15 @@ var cellMaterials = [new THREE.MeshNormalMaterial(), new THREE.MeshBasicMaterial({color:0x000000, wireframe:true})]; - var cellGeometry1; - var cellGeometry2; - - var globalCellScale = window.defaultLatticeScale; - - setGlobalCellScale(globalCellScale); - - function setGlobalCellScale(scale){ - globalCellScale = scale; - cellGeometry1 = unitCellGeo1.clone(); - cellGeometry1.applyMatrix(new THREE.Matrix4().makeScale(scale, scale, scale)); - cellGeometry2 = unitCellGeo2.clone(); - cellGeometry2.applyMatrix(new THREE.Matrix4().makeScale(scale, scale, scale)); - } - function DMACell(mode, indices, scale, lattice) { this.indices = indices; - this.scale = scale; this.lattice = lattice;//need ref back to lattice - this.position = this._calcPosition(scale, indices); - this.cellMesh = this._buildCellMesh(this.position, indices.z); - window.three.sceneAdd(this.cellMesh, "cell"); + this.cellMesh = this._buildCellMesh(indices.z); + this.parts = this._initParts(indices.z); + this.updateForScale(scale); - this.parts = this._initParts(this.position, indices.z); + window.three.sceneAdd(this.cellMesh, "cell"); this.drawForMode(mode); } @@ -63,7 +47,7 @@ return position; }; - DMACell.prototype._initParts = function(position, zIndex){ + DMACell.prototype._initParts = function(zIndex){ var parts = []; for (var i=0;i<3;i++){ parts.push(new DMAPart(i, zIndex%2==1, this)); @@ -78,20 +62,16 @@ _.each(this.parts, function(part){ if (part) hasAnyParts = true; }); - if (!hasAnyParts) this.lattice.removeCell(this); + if (!hasAnyParts) this.lattice.removeCell(this);//if all parts are gone, remove cell }; - DMACell.prototype._buildCellMesh = function(position, zIndex){//abstract mesh representation of cell - + DMACell.prototype._buildCellMesh = function(zIndex){//abstract mesh representation of cell var mesh; - if (zIndex%2==0){ - mesh = THREE.SceneUtils.createMultiMaterialObject(cellGeometry1, cellMaterials); + mesh = THREE.SceneUtils.createMultiMaterialObject(unitCellGeo1, cellMaterials); } else { - mesh = THREE.SceneUtils.createMultiMaterialObject(cellGeometry2, cellMaterials); + mesh = THREE.SceneUtils.createMultiMaterialObject(unitCellGeo2, cellMaterials); } - mesh = this._setMeshPosition(mesh, position); - mesh.myCell = this;//we need a reference to this instance from the mesh for intersection selection stuff return mesh; }; @@ -124,38 +104,15 @@ this.cellMesh.visible = visibility; }; - DMACell.prototype.changeScale = function(scale){ - - this.scale = scale; - - //update geometry - if (globalCellScale != scale) { - setGlobalCellScale(scale); - } - if (this.indices.z%2==0){ - this._updateVertices(cellGeometry1.vertices); - } else { - this._updateVertices(cellGeometry2.vertices); - } - - this.position = this._calcPosition(scale, this.indices); - this._setMeshPosition(this.cellMesh, this.position); + DMACell.prototype.updateForScale = function(scale){ + this.cellMesh.scale.set(scale, scale, scale); + var position = this._calcPosition(scale, this.indices); + this._setMeshPosition(this.cellMesh, position); _.each(this.parts, function(part){ - if (part) part.changeScale(scale, this.position); + if (part) part.updateForScale(scale, position); }); }; - DMACell.prototype._updateVertices = function(vertices){ - _.each(this.cellMesh.children, function(mesh){ - mesh.geometry.vertices = vertices; - mesh.geometry.verticesNeedUpdate = true; - }); - }; - - DMACell.prototype.getScale = function(){ - return this.scale;//I don't like this stored here - }; - DMACell.prototype.destroy = function(){ if (this.cellMesh) { window.three.sceneRemove(this.cellMesh, "cell"); @@ -169,8 +126,6 @@ if (part) part.destroy(); }); this.indices = null; - this.scale = null; - this.position = null; this.lattice = null; this.parts = null; }; diff --git a/js/fea/DmaPart.js b/js/fea/DmaPart.js index f3bccf07f7866e8aa4016bea15bfcc9b2ef4ede5..96b20c9b166309159aacc55adcde12bcbca9878a 100644 --- a/js/fea/DmaPart.js +++ b/js/fea/DmaPart.js @@ -42,18 +42,19 @@ partMaterial.color.setRGB( 0.9619657144369509, 0.6625466032079207, 0.20799727886007258 ); function DMAPart(type, oddZFlag, parent) { + //todo remove this? this.parentCell = parent;//use this reference to get position and scale this.oddZFlag = oddZFlag;//this tells me if cell is at an odd z height in lattice, everything needs to rotate 180 this.type = type; } DMAPart.prototype._draw = function(){ + if (this.mesh) console.warn("part mesh already in scene"); this.mesh = this._makeMeshForType(this.type); window.three.sceneAdd(this.mesh, "part"); }; DMAPart.prototype._makeMeshForType = function(type){ - var mesh; switch(type){ case 0: @@ -69,37 +70,24 @@ else mesh = new THREE.Mesh(unitPartGeo3, partMaterial.clone()); break; } - - mesh = this._setMeshPosition(mesh); - mesh = this._setMeshScale(mesh); + mesh.myPart = this;//need a ref back to this part return mesh; }; DMAPart.prototype._setMeshPosition = function(mesh, scale, position){ - position = position || this.parentCell.position; - scale = scale || this.parentCell.getScale(); mesh.position.x = position.x; mesh.position.y = -scale/3*Math.sqrt(3)+position.y; mesh.position.z = position.z; - if (this.oddZFlag){//adjust some offsets for odd z layers mesh.position.y += 7*scale/6; } - mesh.myPart = this;//need a ref back to this part - return mesh; - }; - - DMAPart.prototype._setMeshScale = function(mesh, scale){ - scale = scale || this.parentCell.getScale(); - mesh.scale.set(scale, scale, scale); return mesh; }; - DMAPart.prototype.changeScale = function(scale, position){ - this.position = position; + DMAPart.prototype.updateForScale = function(scale, position){ if (this.mesh) { + this.mesh.scale.set(scale, scale, scale); this._setMeshPosition(this.mesh, scale, position); - this._setMeshScale(this.mesh, scale); } }; @@ -123,7 +111,6 @@ DMAPart.prototype.removeFromCell = function(){//send message back to parent cell to destroy this if (this.parentCell) { this.parentCell.removePart(this.type); -// this.currentIntersectedPart = null; window.three.render(); } else console.warn("part has no parent cell"); }; diff --git a/js/menus/LatticeMenuView.js b/js/menus/LatticeMenuView.js index d9b9d29ce6bd5337ff466547ce970f8ef260280f..67a60bb928548a5b6566c7118d9eebc88bc0f69a 100644 --- a/js/menus/LatticeMenuView.js +++ b/js/menus/LatticeMenuView.js @@ -129,7 +129,7 @@ LatticeMenuView = Backbone.View.extend({ <% }); %>\ </ul>\ </div><br/><br/>\ - Scale: <input id="scaleSlider" data-slider-id="ex1Slider" type="text" data-slider-min="1" data-slider-max="100" data-slider-step="1" data-slider-value="<%= scale %>"/>\ + Scale: <input id="scaleSlider" data-slider-id="ex1Slider" type="text" data-slider-min="1" data-slider-max="100" data-slider-step="0.1" data-slider-value="<%= scale %>"/>\ <br/><input id="latticeScale" value="<%= scale %>" placeholder="enter scale" class="form-control" type="text"><br/>\ Num Cells: <%= numCells %><br/>\ <br/>\ diff --git a/js/menus/PartMenuView.js b/js/menus/PartMenuView.js index 0ba2011e6dd2483351dd29c57612edbcd8733dbc..69ac2e452803f409f29c9a459b15b284511c0d12 100644 --- a/js/menus/PartMenuView.js +++ b/js/menus/PartMenuView.js @@ -39,7 +39,7 @@ PartMenuView = Backbone.View.extend({ <% }); %>\ </ul>\ </div><br/><br/>\ - Column Separation: <input id="columnSepSlider" data-slider-id="ex1Slider" type="text" data-slider-min="0" data-slider-max="50" data-slider-step="1" data-slider-value="<%= scale %>"/>\ + Column Separation: <input id="columnSepSlider" data-slider-id="ex1Slider" type="text" data-slider-min="0" data-slider-max="50" data-slider-step="0.1" data-slider-value="<%= scale %>"/>\ <br/><input id="columnSep" value="<%= scale %>" placeholder="enter scale" class="form-control" type="text"><br/>\<br/>\ ') diff --git a/js/models/Lattice.js b/js/models/Lattice.js index fde2f765aeeae3dec3733bfe0209c7220d6328eb..0fac5990c7842db589df54049c64cd641bdf7c64 100644 --- a/js/models/Lattice.js +++ b/js/models/Lattice.js @@ -223,7 +223,7 @@ Lattice = Backbone.Model.extend({ var scale = this.get("scale"); this.get("basePlane").updateScale(scale); this._iterCells(this.get("cells"), function(cell){ - if (cell) cell.changeScale(scale); + if (cell) cell.updateForScale(scale); }); window.three.render(); }, diff --git a/js/threeViews/Highlighter.js b/js/threeViews/Highlighter.js index 88a53e64ecf99a41693df8a3c483f5f081022592..de4cb9805e821b77d6b217409e14dbb4545e3bbf 100644 --- a/js/threeViews/Highlighter.js +++ b/js/threeViews/Highlighter.js @@ -5,7 +5,8 @@ Highlighter = Backbone.View.extend({ mesh: null, - currentHighlightedFace: null, + intersectedFace: null, + intersectedCell: null,//current cell we are intersecting initialize: function(){ @@ -33,24 +34,55 @@ Highlighter = Backbone.View.extend({ } }, - show: function(shouldRender){ + show: function(){ if (!this.mesh.visible){ this.mesh.visible = true; - if (shouldRender) window.three.render(); + window.three.render(); + } + }, + + highlightCell: function(object, face){ + + if (object.parent && object.parent.myCell) { + this.intersectedCell = object.parent.myCell; + } else { + this.intersectedCell = null;//we're on the base plane } + + if (this.isVisible() && this._isHighlighting(face)) return;//nothing has changed + + this.currentHighlightedFace = face; + + if (face.normal.z<0.99){//only highlight horizontal faces + this.hide(); + return; + } + + //update highlighter + this._highlightFace(object, face); + this.show(); + }, + + _getCurrentIntersectedCell: function(){ + return this.currentIntersectedCell; + }, + + setNoCellIntersections: function(){ + this.intersectedCell = null; + this.currentIntersectedCell = null; + this.hide(); }, isVisible: function(){ return this.mesh.visible; }, - isHighlighting: function(face){ + _isHighlighting: function(face){ return this.currentHighlightedFace == face; }, - highlightFace: function(intersection){ - this.currentHighlightedFace = intersection.face; - this.mesh.geometry.vertices = this._calcNewHighlighterVertices(intersection.object, intersection.face); + _highlightFace: function(object, face){ + this.mesh.geometry.vertices = this._calcNewHighlighterVertices(object, face); this.mesh.geometry.verticesNeedUpdate = true; }, @@ -69,6 +101,20 @@ Highlighter = Backbone.View.extend({ getNextCellPosition: function(){ return this.mesh.geometry.vertices[0]; + }, + + addRemoveVoxel: function(shouldAdd){ + + if (shouldAdd){ + if (!this.isVisible()) return; + this.model.addCell(this.highlighter.getNextCellPosition()); + } else { + var currentIntersectedCell = this._getCurrentIntersectedCell(); + if (currentIntersectedCell === this.model.basePlane[0]) return; + this.model.removeCellFromMesh(currentIntersectedCell); + } + this.highlighter.hide(); } + }); \ No newline at end of file diff --git a/js/threeViews/ThreeView.js b/js/threeViews/ThreeView.js index 7272947a92ddcbfb8fa163c669510e1242d54c45..1657612ba721ac82e62b88412c836e89fed8dd44 100644 --- a/js/threeViews/ThreeView.js +++ b/js/threeViews/ThreeView.js @@ -17,7 +17,6 @@ ThreeView = Backbone.View.extend({ //intersections/object highlighting mouseProjection: new THREE.Raycaster(), highlighter: null, - currentIntersectedCell: null, currentIntersectedPart:null, el: "#threeContainer", @@ -65,14 +64,14 @@ ThreeView = Backbone.View.extend({ //////////////////////////////////////////////////////////////////////////////// _mouseOut: function(){ - this._setNoCellIntersections(); + this.highlighter.setNoCellIntersections(); this._setNoPartIntersections(); }, _mouseUp: function(){ this.mouseIsDown = false; if (this.currentIntersectedPart) this.currentIntersectedPart.removeFromCell(); - else this._addRemoveVoxel(!this.appState.get("deleteMode")); + else this.highlighter.addRemoveVoxel(!this.appState.get("deleteMode")); }, _mouseDown: function(){ @@ -82,7 +81,7 @@ ThreeView = Backbone.View.extend({ _mouseMoved: function(e){ if (this.mouseIsDown && this.controls.enabled) {//in the middle of a camera move - this._setNoCellIntersections(); + this.highlighter.setNoCellIntersections(); this._setNoPartIntersections(); return; } @@ -95,11 +94,11 @@ ThreeView = Backbone.View.extend({ //check if we're intersecting anything var cellIntersections = this.mouseProjection.intersectObjects(this.model.cells.concat(this.model.basePlane), true); if (cellIntersections.length == 0) { - this._setNoCellIntersections(); + this.highlighter.setNoCellIntersections(); this._setNoPartIntersections(); return; } - this._handleCellIntersections(cellIntersections); + this._handleCellIntersections(cellIntersections[0]); if (this.lattice.get("cellMode") == "part"){//additionally check for part intersections in part mode var partIntersections = this.mouseProjection.intersectObjects(this.model.parts, false); @@ -115,11 +114,6 @@ ThreeView = Backbone.View.extend({ ///////////////////////////////INTERSECTIONS//////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// - _setNoCellIntersections: function(){ - this.currentIntersectedCell = null; - this.highlighter.hide(); - }, - _setNoPartIntersections: function(){ if (this.currentIntersectedPart){ this.currentIntersectedPart.unhighlight(); @@ -134,7 +128,7 @@ ThreeView = Backbone.View.extend({ this._setNoPartIntersections(); return; } - this._setNoCellIntersections(); + this.highlighter.setNoCellIntersections(); if (part!= this.currentIntersectedPart){ if (this.currentIntersectedPart) this.currentIntersectedPart.unhighlight(); part.highlight(); @@ -143,49 +137,21 @@ ThreeView = Backbone.View.extend({ } }, - _handleCellIntersections: function(intersections){ + _handleCellIntersections: function(intersection){ - this.currentIntersectedCell = intersections[0].object; - - if (this.appState.get("deleteMode") && this.mouseIsDown){ - this._addRemoveVoxel(false); - return; - } + this.highlighter.highlightCell(intersection.object, intersection.face); +// if (this.appState.get("deleteMode") && this.mouseIsDown){ +// this.highlighter.addRemoveVoxel(false); +// } else if (this.mouseIsDown && this.appState.get("shift")){ +// this.highlighter.addRemoveVoxel(true); +// } // if (this.appState.get("extrudeMode") && this.mouseIsDown){ // if (!this.highlighter.isVisible) return; // this.extrudeVisualizer.makeMeshFromProfile([this.highlighter]); // return; // } - //check if we've moved to a new face - var intersection = intersections[0].face; - if (this.highlighter.isVisible() && this.highlighter.isHighlighting(intersection)) return; - - if (intersection.normal.z<0.99){//only highlight horizontal faces - this.highlighter.hide(); - return; - } - - //update highlighter - this.highlighter.show(false); - this.highlighter.highlightFace(intersections[0]); - - if (this.mouseIsDown && this.appState.get("shift")) this._addRemoveVoxel(true); - - window.three.render(); - }, - - _addRemoveVoxel: function(shouldAdd){ - - if (shouldAdd){ - if (!this.highlighter.isVisible()) return; - this.lattice.addCell(this.highlighter.getNextCellPosition()); - } else { - if (this.currentIntersectedCell === this.model.basePlane[0]) return; - this.lattice.removeCellFromMesh(this.currentIntersectedCell); - } - this.highlighter.hide(); } }); \ No newline at end of file