UNPKG

molstar

Version:

A comprehensive macromolecular library.

168 lines 7.51 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.createVolumeTexture3d = exports.createVolumeTexture2d = exports.getVolumeTexture2dLayout = exports.eachVolumeLoci = void 0; var volume_1 = require("../../mol-model/volume"); var int_1 = require("../../mol-data/int"); var common_1 = require("../../mol-math/linear-algebra/3d/common"); var vec3_1 = require("../../mol-math/linear-algebra/3d/vec3"); var float_packing_1 = require("../../mol-util/float-packing"); // avoiding namespace lookup improved performance in Chrome (Aug 2020) var v3set = vec3_1.Vec3.set; var v3normalize = vec3_1.Vec3.normalize; var v3sub = vec3_1.Vec3.sub; var v3addScalar = vec3_1.Vec3.addScalar; var v3scale = vec3_1.Vec3.scale; var v3toArray = vec3_1.Vec3.toArray; function eachVolumeLoci(loci, volume, isoValue, apply) { var changed = false; if (volume_1.Volume.isLoci(loci)) { if (!volume_1.Volume.areEquivalent(loci.volume, volume)) return false; if (apply(int_1.Interval.ofLength(volume.grid.cells.data.length))) changed = true; } else if (volume_1.Volume.Isosurface.isLoci(loci)) { if (!volume_1.Volume.areEquivalent(loci.volume, volume)) return false; if (isoValue) { if (!volume_1.Volume.IsoValue.areSame(loci.isoValue, isoValue, volume.grid.stats)) return false; if (apply(int_1.Interval.ofLength(volume.grid.cells.data.length))) changed = true; } else { // TODO find a cheaper way? var _a = volume.grid, stats = _a.stats, data = _a.cells.data; var eps = stats.sigma; var v = volume_1.Volume.IsoValue.toAbsolute(loci.isoValue, stats).absoluteValue; for (var i = 0, il = data.length; i < il; ++i) { if ((0, common_1.equalEps)(v, data[i], eps)) { if (apply(int_1.Interval.ofSingleton(i))) changed = true; } } } } else if (volume_1.Volume.Cell.isLoci(loci)) { if (!volume_1.Volume.areEquivalent(loci.volume, volume)) return false; if (int_1.Interval.is(loci.indices)) { if (apply(loci.indices)) changed = true; } else { int_1.OrderedSet.forEach(loci.indices, function (v) { if (apply(int_1.Interval.ofSingleton(v))) changed = true; }); } } return changed; } exports.eachVolumeLoci = eachVolumeLoci; // function getVolumeTexture2dLayout(dim, padding) { if (padding === void 0) { padding = 0; } var area = dim[0] * dim[1] * dim[2]; var squareDim = Math.sqrt(area); var powerOfTwoSize = Math.pow(2, Math.ceil(Math.log(squareDim) / Math.log(2))); var width = dim[0] + padding; var height = dim[1] + padding; var rows = 1; var columns = width; if (powerOfTwoSize < width * dim[2]) { columns = Math.floor(powerOfTwoSize / width); rows = Math.ceil(dim[2] / columns); width *= columns; height *= rows; } else { width *= dim[2]; } return { width: width, height: height, columns: columns, rows: rows, powerOfTwoSize: height < powerOfTwoSize ? powerOfTwoSize : powerOfTwoSize * 2 }; } exports.getVolumeTexture2dLayout = getVolumeTexture2dLayout; function createVolumeTexture2d(volume, variant, padding) { if (padding === void 0) { padding = 0; } var _a = volume.grid, _b = _a.cells, space = _b.space, data = _b.data, _c = _a.stats, max = _c.max, min = _c.min; var dim = space.dimensions; var o = space.dataOffset; var _d = getVolumeTexture2dLayout(dim, padding), width = _d.width, height = _d.height; var itemSize = variant === 'data' ? 1 : 4; var array = new Uint8Array(width * height * itemSize); var textureImage = { array: array, width: width, height: height }; var diff = max - min; var xn = dim[0], yn = dim[1], zn = dim[2]; var xnp = xn + padding; var ynp = yn + padding; var n0 = (0, vec3_1.Vec3)(); var n1 = (0, vec3_1.Vec3)(); var xn1 = xn - 1; var yn1 = yn - 1; var zn1 = zn - 1; for (var z = 0; z < zn; ++z) { for (var y = 0; y < yn; ++y) { for (var x = 0; x < xn; ++x) { var column = Math.floor(((z * xnp) % width) / xnp); var row = Math.floor((z * xnp) / width); var px = column * xnp + x; var index = itemSize * ((row * ynp * width) + (y * width) + px); var offset = o(x, y, z); if (variant === 'data') { array[index] = Math.round(((data[offset] - min) / diff) * 255); } else { if (variant === 'groups') { (0, float_packing_1.encodeFloatRGBtoArray)(offset, array, index); } else { v3set(n0, data[o(Math.max(0, x - 1), y, z)], data[o(x, Math.max(0, y - 1), z)], data[o(x, y, Math.max(0, z - 1))]); v3set(n1, data[o(Math.min(xn1, x + 1), y, z)], data[o(x, Math.min(yn1, y + 1), z)], data[o(x, y, Math.min(zn1, z + 1))]); v3normalize(n0, v3sub(n0, n0, n1)); v3addScalar(n0, v3scale(n0, n0, 0.5), 0.5); v3toArray(v3scale(n0, n0, 255), array, index); } array[index + 3] = Math.round(((data[offset] - min) / diff) * 255); } } } } return textureImage; } exports.createVolumeTexture2d = createVolumeTexture2d; function createVolumeTexture3d(volume) { var _a = volume.grid, _b = _a.cells, space = _b.space, data = _b.data, _c = _a.stats, max = _c.max, min = _c.min; var _d = space.dimensions, width = _d[0], height = _d[1], depth = _d[2]; var o = space.dataOffset; var array = new Uint8Array(width * height * depth * 4); var textureVolume = { array: array, width: width, height: height, depth: depth }; var diff = max - min; var n0 = (0, vec3_1.Vec3)(); var n1 = (0, vec3_1.Vec3)(); var width1 = width - 1; var height1 = height - 1; var depth1 = depth - 1; var i = 0; for (var z = 0; z < depth; ++z) { for (var y = 0; y < height; ++y) { for (var x = 0; x < width; ++x) { var offset = o(x, y, z); v3set(n0, data[o(Math.max(0, x - 1), y, z)], data[o(x, Math.max(0, y - 1), z)], data[o(x, y, Math.max(0, z - 1))]); v3set(n1, data[o(Math.min(width1, x + 1), y, z)], data[o(x, Math.min(height1, y + 1), z)], data[o(x, y, Math.min(depth1, z + 1))]); v3normalize(n0, v3sub(n0, n0, n1)); v3addScalar(n0, v3scale(n0, n0, 0.5), 0.5); v3toArray(v3scale(n0, n0, 255), array, i); array[i + 3] = Math.round(((data[offset] - min) / diff) * 255); i += 4; } } } return textureVolume; } exports.createVolumeTexture3d = createVolumeTexture3d; //# sourceMappingURL=util.js.map