1 line
9.3 KiB
Plaintext
1 line
9.3 KiB
Plaintext
|
|
{"version":3,"file":"VolumeSlice.cjs","sources":["../../src/misc/VolumeSlice.js"],"sourcesContent":["import { ClampToEdgeWrapping, DoubleSide, LinearFilter, Mesh, MeshBasicMaterial, PlaneGeometry, Texture } from 'three'\n\n/**\n * This class has been made to hold a slice of a volume data\n * @class\n * @param {Volume} volume The associated volume\n * @param {number} [index=0] The index of the slice\n * @param {string} [axis='z'] For now only 'x', 'y' or 'z' but later it will change to a normal vector\n * @see Volume\n */\nclass VolumeSlice {\n constructor(volume, index, axis) {\n const slice = this\n /**\n * @member {Volume} volume The associated volume\n */\n this.volume = volume\n /**\n * @member {Number} index The index of the slice, if changed, will automatically call updateGeometry at the next repaint\n */\n index = index || 0\n Object.defineProperty(this, 'index', {\n get: function () {\n return index\n },\n set: function (value) {\n index = value\n slice.geometryNeedsUpdate = true\n return index\n },\n })\n /**\n * @member {String} axis The normal axis\n */\n this.axis = axis || 'z'\n\n /**\n * @member {HTMLCanvasElement} canvas The final canvas used for the texture\n */\n /**\n * @member {CanvasRenderingContext2D} ctx Context of the canvas\n */\n this.canvas = document.createElement('canvas')\n /**\n * @member {HTMLCanvasElement} canvasBuffer The intermediary canvas used to paint the data\n */\n /**\n * @member {CanvasRenderingContext2D} ctxBuffer Context of the canvas buffer\n */\n this.canvasBuffer = document.createElement('canvas')\n this.updateGeometry()\n\n const canvasMap = new Texture(this.canvas)\n canvasMap.minFilter = LinearFilter\n canvasMap.wrapS = canvasMap.wrapT = ClampToEdgeWrapping\n if ('colorSpace' in canvasMap) canvasMap.colorSpace = 'srgb'\n else canvasMap.encoding = 3001 // sRGBEncoding\n const material = new MeshBasicMaterial({ map: canvasMap, side: DoubleSide, transparent: true })\n /**\n * @member {Mesh} mesh The mesh ready to get used in the scene\n */\n this.mesh = new Mesh(this.geometry, material)\n this.mesh.matrixAutoUpdate = false\n /**\n * @member {Boolean} geometryNeedsUpdate If set to true, updateGeometry will be triggered at the next repaint\n */\n this.geometryNeedsUpdate = true\n this.repaint()\n\n /**\n * @member {Number} iLength Width of slice in the original coordinate system, corresponds to the width of the buffer canvas\n */\n\n /**\n * @member {Number} jLength Height of slice in the original coordinate system, corresponds to the height of the buffer canvas\n */\n\n /**\n * @member {Function} sliceAccess Function that allow the slice to access right data\n * @see Volume.extractPerpendicularPlane\n * @param {Number} i The first coordinate\n * @param {Number} j The second coordinate\n * @returns {Number} the index corresponding to the voxel in volume.data of the given position in the slice\n */\n }\n\n /**\n * @member {Function} repaint Refresh the texture and the geometry if geometryNeedsUpdate is set to true\n * @memberof VolumeSlice\n */\n repaint() {\n if (this.geometryNeedsUpdate) {\n this.updateGeometry()\n }\n\n const iLength = this.iLength,\n jLength = this.jLength,\n sliceAccess = this.sliceAccess,\n volume = this.volume,\n canvas = this.canvasBuffer,\n ctx = this.ctxBuffer\n\n // get the imageData and pixel array from the canvas\n const imgData = ctx.getImageData(0, 0, iLength, jLength)\n const data = imgData.data\n const volumeData = volume.data\n const upperThreshold = volume.upperThreshold\n const lowerThreshold = volume.lowerThreshold\n const windowLow = volume.windowLow\n const windowHigh = volume.windowHigh\n\n // manipulate some pixel elements\n let pixelCount = 0\n\n if (volume.dataType === 'label') {\
|