molstar
Version:
A comprehensive macromolecular library.
168 lines • 7.51 kB
JavaScript
"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