ami-cjs.js
Version:
<p align="center"> <img src="https://cloud.githubusercontent.com/assets/214063/23213764/78ade038-f90c-11e6-8208-4fcade5f3832.png" width="60%"> </p>
515 lines (445 loc) • 13.6 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _helpers = require('../helpers/helpers.border');
var _helpers2 = _interopRequireDefault(_helpers);
var _helpers3 = require('../helpers/helpers.boundingbox');
var _helpers4 = _interopRequireDefault(_helpers3);
var _helpers5 = require('../helpers/helpers.slice');
var _helpers6 = _interopRequireDefault(_helpers5);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** * Imports ***/
/**
* Helper to easily display and interact with a stack.<br>
*<br>
* Defaults:<br>
* - orientation: 0 (acquisition direction)<br>
* - index: middle slice in acquisition direction<br>
*<br>
* Features:<br>
* - slice from the stack (in any direction)<br>
* - slice border<br>
* - stack bounding box<br>
*<br>
* Live demo at: {@link http://jsfiddle.net/gh/get/library/pure/fnndsc/ami/tree/master/lessons/01#run|Lesson 01}
*
* @example
* let stack = new VJS.Models.Stack();
* ... // prepare the stack
*
* let stackHelper = new VJS.Helpers.Stack(stack);
* stackHelper.bbox.color = 0xF9F9F9;
* stackHelper.border.color = 0xF9F9F9;
*
* let scene = new THREE.Scene();
* scene.add(stackHelper);
*
* @extends THREE.Object3D
*
* @see module:helpers/border
* @see module:helpers/boundingbox
* @see module:helpers/slice
*
* @module helpers/stack
*/
var HelpersStack = function (_THREE$Object3D) {
_inherits(HelpersStack, _THREE$Object3D);
function HelpersStack(stack) {
_classCallCheck(this, HelpersStack);
var _this = _possibleConstructorReturn(this, (HelpersStack.__proto__ || Object.getPrototypeOf(HelpersStack)).call(this));
//
_this._stack = stack;
_this._bBox = null;
_this._slice = null;
_this._border = null;
_this._dummy = null;
_this._orientation = 0;
_this._index = 0;
_this._uniforms = null;
_this._autoWindowLevel = false;
_this._outOfBounds = false;
_this._orientationMaxIndex = 0;
_this._canvasWidth = 0;
_this._canvasHeight = 0;
_this._borderColor = null;
// this._arrow = {
// visible: true,
// color: 0xFFF336,
// length: 20,
// material: null,
// geometry: null,
// mesh: null
// };
_this._create();
return _this;
}
//
// PUBLIC METHODS
//
//
// SETTERS/GETTERS
//
/**
* Get stack.
*
* @type {ModelsStack}
*/
_createClass(HelpersStack, [{
key: '_create',
//
// PRIVATE METHODS
//
/**
* Initial setup, including stack prepare, bbox prepare, slice prepare and
* border prepare.
*
* @private
*/
value: function _create() {
if (this._stack) {
// prepare sthe stack internals
this._prepareStack();
// prepare visual objects
this._prepareBBox();
this._prepareSlice();
this._prepareBorder();
// todo: Arrow
} else {
window.console.log('no stack to be prepared...');
}
}
}, {
key: '_computeOrientationMaxIndex',
value: function _computeOrientationMaxIndex() {
var dimensionsIJK = this._stack.dimensionsIJK;
this._orientationMaxIndex = 0;
switch (this._orientation) {
case 0:
this._orientationMaxIndex = dimensionsIJK.z - 1;
break;
case 1:
this._orientationMaxIndex = dimensionsIJK.x - 1;
break;
case 2:
this._orientationMaxIndex = dimensionsIJK.y - 1;
break;
default:
// do nothing!
break;
}
}
/**
* Given orientation, check if index is in/out of bounds.
*
* @private
*/
}, {
key: '_isIndexOutOfBounds',
value: function _isIndexOutOfBounds() {
this._computeOrientationMaxIndex();
if (this._index >= this._orientationMaxIndex || this._index < 0) {
this._outOfBounds = true;
} else {
this._outOfBounds = false;
}
}
/**
* Prepare a stack for visualization. (image to world transform, frames order,
* pack data into 8 bits textures, etc.)
*
* @private
*/
}, {
key: '_prepareStack',
value: function _prepareStack() {
// make sure there is something, if not throw an error
// compute image to workd transform, order frames, etc.
if (!this._stack.prepared) {
this._stack.prepare();
}
// pack data into 8 bits rgba texture for the shader
// this one can be slow...
if (!this._stack.packed) {
this._stack.pack();
}
}
/**
* Setup bounding box helper given prepared stack and add bounding box helper
* to stack helper.
*
* @private
*/
}, {
key: '_prepareBBox',
value: function _prepareBBox() {
this._bBox = new _helpers4.default(this._stack);
this.add(this._bBox);
}
/**
* Setup border helper given slice helper and add border helper
* to stack helper.
*
* @private
*/
}, {
key: '_prepareBorder',
value: function _prepareBorder() {
this._border = new _helpers2.default(this._slice);
this.add(this._border);
}
/**
* Setup slice helper given prepared stack helper and add slice helper
* to stack helper.
*
* @private
*/
}, {
key: '_prepareSlice',
value: function _prepareSlice() {
var halfDimensionsIJK = this._stack.halfDimensionsIJK;
// compute initial index given orientation
this._index = this._prepareSliceIndex(halfDimensionsIJK);
// compute initial position given orientation and index
var position = this._prepareSlicePosition(halfDimensionsIJK, this._index);
// compute initial direction orientation
var direction = this._prepareDirection(this._orientation);
this._slice = new _helpers6.default(this._stack, this._index, position, direction);
this.add(this._slice);
}
/**
* Compute slice index depending on orientation.
*
* @param {THREE.Vector3} indices - Indices in each direction.
*
* @returns {number} Slice index according to current orientation.
*
* @private
*/
}, {
key: '_prepareSliceIndex',
value: function _prepareSliceIndex(indices) {
var index = 0;
switch (this._orientation) {
case 0:
index = Math.floor(indices.z);
break;
case 1:
index = Math.floor(indices.x);
break;
case 2:
index = Math.floor(indices.y);
break;
default:
// do nothing!
break;
}
return index;
}
/**
* Compute slice position depending on orientation.
* Sets index in proper location of reference position.
*
* @param {THREE.Vector3} rPosition - Reference position.
* @param {number} index - Current index.
*
* @returns {number} Slice index according to current orientation.
*
* @private
*/
}, {
key: '_prepareSlicePosition',
value: function _prepareSlicePosition(rPosition, index) {
var position = new THREE.Vector3(0, 0, 0);
switch (this._orientation) {
case 0:
position = new THREE.Vector3(Math.floor(rPosition.x), Math.floor(rPosition.y), index);
break;
case 1:
position = new THREE.Vector3(index, Math.floor(rPosition.y), Math.floor(rPosition.z));
break;
case 2:
position = new THREE.Vector3(Math.floor(rPosition.x), index, Math.floor(rPosition.z));
break;
default:
// do nothing!
break;
}
return position;
}
/**
* Compute slice direction depending on orientation.
*
* @param {number} orientation - Slice orientation.
*
* @returns {THREE.Vector3} Slice direction
*
* @private
*/
}, {
key: '_prepareDirection',
value: function _prepareDirection(orientation) {
var direction = new THREE.Vector3(0, 0, 1);
switch (orientation) {
case 0:
direction = new THREE.Vector3(0, 0, 1);
break;
case 1:
direction = new THREE.Vector3(1, 0, 0);
break;
case 2:
direction = new THREE.Vector3(0, 1, 0);
break;
default:
// do nothing!
break;
}
return direction;
}
}, {
key: 'stack',
get: function get() {
return this._stack;
}
/**
* Get bounding box helper.
*
* @type {HelpersBoundingBox}
*/
}, {
key: 'bbox',
get: function get() {
return this._bBox;
}
/**
* Get slice helper.
*
* @type {HelpersSlice}
*/
}, {
key: 'slice',
get: function get() {
return this._slice;
}
/**
* Get border helper.
*
* @type {HelpersSlice}
*/
}, {
key: 'border',
get: function get() {
return this._border;
}
/**
* Set/get current slice index.<br>
* Sets outOfBounds flag to know if target index is in/out stack bounding box.<br>
* <br>
* Internally updates the sliceHelper index and position. Also updates the
* borderHelper with the updated sliceHelper.
*
* @type {number}
*/
}, {
key: 'index',
get: function get() {
return this._index;
},
set: function set(index) {
this._index = index;
// update the slice
this._slice.index = index;
var halfDimensions = this._stack.halfDimensionsIJK;
this._slice.planePosition = this._prepareSlicePosition(halfDimensions, this._index);
// also update the border
this._border.helpersSlice = this._slice;
// update ourOfBounds flag
this._isIndexOutOfBounds();
}
/**
* Set/get current slice orientation.<br>
* Values: <br>
* - 0: acquisition direction (slice normal is z_cosine)<br>
* - 1: next direction (slice normal is x_cosine)<br>
* - 2: next direction (slice normal is y_cosine)<br>
* - n: set orientation to 0<br>
* <br>
* Internally updates the sliceHelper direction. Also updates the
* borderHelper with the updated sliceHelper.
*
* @type {number}
*/
}, {
key: 'orientation',
set: function set(orientation) {
this._orientation = orientation;
this._computeOrientationMaxIndex();
this._slice.planeDirection = this._prepareDirection(this._orientation);
// also update the border
this._border.helpersSlice = this._slice;
},
get: function get() {
return this._orientation;
}
/**
* Set/get the outOfBound flag.
*
* @type {boolean}
*/
}, {
key: 'outOfBounds',
set: function set(outOfBounds) {
this._outOfBounds = outOfBounds;
},
get: function get() {
return this._outOfBounds;
}
/**
* Set/get the orientationMaxIndex flag.
*
* @type {boolean}
*/
}, {
key: 'orientationMaxIndex',
set: function set(orientationMaxIndex) {
this._orientationMaxIndex = orientationMaxIndex;
},
get: function get() {
return this._orientationMaxIndex;
}
}, {
key: 'canvasWidth',
set: function set(canvasWidth) {
this._canvasWidth = canvasWidth;
this._slice.canvasWidth = this._canvasWidth;
},
get: function get() {
return this._canvasWidth;
}
}, {
key: 'canvasHeight',
set: function set(canvasHeight) {
this._canvasHeight = canvasHeight;
this._slice.canvasHeight = this._canvasHeight;
},
get: function get() {
return this._canvasHeight;
}
}, {
key: 'borderColor',
set: function set(borderColor) {
this._borderColor = borderColor;
this._border.color = borderColor;
this._slice.borderColor = this._borderColor;
},
get: function get() {
return this._borderColor;
}
}]);
return HelpersStack;
}(THREE.Object3D);
exports.default = HelpersStack;
module.exports = exports['default'];