UNPKG

molstar

Version:

A comprehensive macromolecular library.

202 lines 10.2 kB
"use strict"; /** * Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose <alexander.rose@weirdbyte.de> */ Object.defineProperty(exports, "__esModule", { value: true }); exports.SliceRepresentationProvider = exports.SliceRepresentation = exports.SliceVisual = exports.getSliceParams = exports.SliceParams = exports.createImage = void 0; var tslib_1 = require("tslib"); var param_definition_1 = require("../../mol-util/param-definition"); var image_1 = require("../../mol-geo/geometry/image/image"); var volume_1 = require("../../mol-model/volume"); var representation_1 = require("./representation"); var location_iterator_1 = require("../../mol-geo/util/location-iterator"); var location_1 = require("../../mol-model/location"); var loci_1 = require("../../mol-model/loci"); var int_1 = require("../../mol-data/int"); var util_1 = require("../../mol-geo/util"); var color_1 = require("../../mol-util/color"); var color_2 = require("../../mol-theme/color"); var float_packing_1 = require("../../mol-util/float-packing"); var util_2 = require("./util"); function createImage(ctx, volume, theme, props, image) { return (0, tslib_1.__awaiter)(this, void 0, void 0, function () { var dim, isoValue, _a, space, data, _b, min, max, isoVal, color, _c, r, g, b, _d, width, height, x, y, z, x0, y0, z0, nx, ny, nz, corners, imageArray, groupArray, i, iy, ix, iz, val, normVal, imageTexture, groupTexture, transform; return (0, tslib_1.__generator)(this, function (_e) { dim = props.dimension.name, isoValue = props.isoValue; _a = volume.grid.cells, space = _a.space, data = _a.data; _b = volume.grid.stats, min = _b.min, max = _b.max; isoVal = volume_1.Volume.IsoValue.toAbsolute(isoValue, volume.grid.stats).absoluteValue; color = theme.color.color(location_1.NullLocation, false); _c = color_1.Color.toRgbNormalized(color), r = _c[0], g = _c[1], b = _c[2]; _d = getSliceInfo(volume.grid, props), width = _d.width, height = _d.height, x = _d.x, y = _d.y, z = _d.z, x0 = _d.x0, y0 = _d.y0, z0 = _d.z0, nx = _d.nx, ny = _d.ny, nz = _d.nz; corners = new Float32Array(dim === 'x' ? [x, 0, 0, x, y, 0, x, 0, z, x, y, z] : dim === 'y' ? [0, y, 0, x, y, 0, 0, y, z, x, y, z] : [0, 0, z, 0, y, z, x, 0, z, x, y, z]); imageArray = new Uint8Array(width * height * 4); groupArray = getPackedGroupArray(volume.grid, props); i = 0; for (iy = y0; iy < ny; ++iy) { for (ix = x0; ix < nx; ++ix) { for (iz = z0; iz < nz; ++iz) { val = space.get(data, ix, iy, iz); normVal = (val - min) / (max - min); imageArray[i] = r * normVal * 2 * 255; imageArray[i + 1] = g * normVal * 2 * 255; imageArray[i + 2] = b * normVal * 2 * 255; imageArray[i + 3] = val >= isoVal ? 255 : 0; i += 4; } } } imageTexture = { width: width, height: height, array: imageArray, flipY: true }; groupTexture = { width: width, height: height, array: groupArray, flipY: true }; transform = volume_1.Grid.getGridToCartesianTransform(volume.grid); (0, util_1.transformPositionArray)(transform, corners, 0, 4); return [2 /*return*/, image_1.Image.create(imageTexture, corners, groupTexture, image)]; }); }); } exports.createImage = createImage; function getSliceInfo(grid, props) { var _a = props.dimension, dim = _a.name, index = _a.params; var space = grid.cells.space; var width, height; var x, y, z; var x0 = 0, y0 = 0, z0 = 0; var _b = space.dimensions, nx = _b[0], ny = _b[1], nz = _b[2]; if (dim === 'x') { x = index, y = ny - 1, z = nz - 1; width = nz, height = ny; x0 = x, nx = x0 + 1; } else if (dim === 'y') { x = nx - 1, y = index, z = nz - 1; width = nz, height = nx; y0 = y, ny = y0 + 1; } else { x = nx - 1, y = ny - 1, z = index; width = nx, height = ny; z0 = z, nz = z0 + 1; } return { width: width, height: height, x: x, y: y, z: z, x0: x0, y0: y0, z0: z0, nx: nx, ny: ny, nz: nz }; } function getPackedGroupArray(grid, props) { var space = grid.cells.space; var _a = getSliceInfo(grid, props), width = _a.width, height = _a.height, x0 = _a.x0, y0 = _a.y0, z0 = _a.z0, nx = _a.nx, ny = _a.ny, nz = _a.nz; var groupArray = new Uint8Array(width * height * 4); var j = 0; for (var iy = y0; iy < ny; ++iy) { for (var ix = x0; ix < nx; ++ix) { for (var iz = z0; iz < nz; ++iz) { (0, float_packing_1.encodeFloatRGBtoArray)(space.dataOffset(ix, iy, iz), groupArray, j); j += 4; } } } return groupArray; } function getGroupArray(grid, props) { var space = grid.cells.space; var _a = getSliceInfo(grid, props), width = _a.width, height = _a.height, x0 = _a.x0, y0 = _a.y0, z0 = _a.z0, nx = _a.nx, ny = _a.ny, nz = _a.nz; var groupArray = new Uint32Array(width * height); var j = 0; for (var iy = y0; iy < ny; ++iy) { for (var ix = x0; ix < nx; ++ix) { for (var iz = z0; iz < nz; ++iz) { groupArray[j] = space.dataOffset(ix, iy, iz); j += 1; } } } return groupArray; } function getLoci(volume, props) { // TODO cache somehow? var groupArray = getGroupArray(volume.grid, props); return volume_1.Volume.Cell.Loci(volume, int_1.SortedArray.ofUnsortedArray(groupArray)); } function getSliceLoci(pickingId, volume, props, id) { var objectId = pickingId.objectId, groupId = pickingId.groupId; if (id === objectId) { return volume_1.Volume.Cell.Loci(volume, int_1.Interval.ofSingleton(groupId)); } return loci_1.EmptyLoci; } function eachSlice(loci, volume, props, apply) { return (0, util_2.eachVolumeLoci)(loci, volume, undefined, apply); } // exports.SliceParams = (0, tslib_1.__assign)((0, tslib_1.__assign)({}, image_1.Image.Params), { quality: (0, tslib_1.__assign)((0, tslib_1.__assign)({}, image_1.Image.Params.quality), { isEssential: false }), dimension: param_definition_1.ParamDefinition.MappedStatic('x', { x: param_definition_1.ParamDefinition.Numeric(0, { min: 0, max: 0, step: 1 }), y: param_definition_1.ParamDefinition.Numeric(0, { min: 0, max: 0, step: 1 }), z: param_definition_1.ParamDefinition.Numeric(0, { min: 0, max: 0, step: 1 }), }, { isEssential: true }), isoValue: volume_1.Volume.IsoValueParam }); function getSliceParams(ctx, volume) { var p = param_definition_1.ParamDefinition.clone(exports.SliceParams); var dim = volume.grid.cells.space.dimensions; p.dimension = param_definition_1.ParamDefinition.MappedStatic('x', { x: param_definition_1.ParamDefinition.Numeric(0, { min: 0, max: dim[0] - 1, step: 1 }), y: param_definition_1.ParamDefinition.Numeric(0, { min: 0, max: dim[1] - 1, step: 1 }), z: param_definition_1.ParamDefinition.Numeric(0, { min: 0, max: dim[2] - 1, step: 1 }), }, { isEssential: true }); p.isoValue = volume_1.Volume.createIsoValueParam(volume_1.Volume.IsoValue.absolute(volume.grid.stats.min), volume.grid.stats); return p; } exports.getSliceParams = getSliceParams; function SliceVisual(materialId) { return (0, representation_1.VolumeVisual)({ defaultProps: param_definition_1.ParamDefinition.getDefaultValues(exports.SliceParams), createGeometry: createImage, createLocationIterator: function (volume) { return (0, location_iterator_1.LocationIterator)(volume.grid.cells.data.length, 1, 1, function () { return location_1.NullLocation; }); }, getLoci: getSliceLoci, eachLocation: eachSlice, setUpdateState: function (state, volume, newProps, currentProps, newTheme, currentTheme) { state.createGeometry = (newProps.dimension.name !== currentProps.dimension.name || newProps.dimension.params !== currentProps.dimension.params || !volume_1.Volume.IsoValue.areSame(newProps.isoValue, currentProps.isoValue, volume.grid.stats) || !color_2.ColorTheme.areEqual(newTheme.color, currentTheme.color)); }, geometryUtils: (0, tslib_1.__assign)((0, tslib_1.__assign)({}, image_1.Image.Utils), { createRenderableState: function (props) { var state = image_1.Image.Utils.createRenderableState(props); updateRenderableState(state, props); return state; }, updateRenderableState: updateRenderableState }) }, materialId); } exports.SliceVisual = SliceVisual; function updateRenderableState(state, props) { image_1.Image.Utils.updateRenderableState(state, props); state.opaque = false; state.writeDepth = true; } function SliceRepresentation(ctx, getParams) { return (0, representation_1.VolumeRepresentation)('Slice', ctx, getParams, SliceVisual, getLoci); } exports.SliceRepresentation = SliceRepresentation; exports.SliceRepresentationProvider = (0, representation_1.VolumeRepresentationProvider)({ name: 'slice', label: 'Slice', description: 'Slice of volume rendered as image with interpolation.', factory: SliceRepresentation, getParams: getSliceParams, defaultValues: param_definition_1.ParamDefinition.getDefaultValues(exports.SliceParams), defaultColorTheme: { name: 'uniform' }, defaultSizeTheme: { name: 'uniform' }, isApplicable: function (volume) { return !volume_1.Volume.isEmpty(volume); } }); //# sourceMappingURL=slice.js.map