molstar
Version:
A comprehensive macromolecular library.
181 lines • 8.47 kB
JavaScript
"use strict";
/**
* Copyright (c) 2018-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.calculateBoundingSphere = exports.calculateTransformBoundingSphere = exports.calculateInvariantBoundingSphere = exports.printImageData = exports.printTextureImage = exports.createTextureImage = exports.calculateTextureInfo = void 0;
var tslib_1 = require("tslib");
var geometry_1 = require("../../mol-math/geometry");
var linear_algebra_1 = require("../../mol-math/linear-algebra");
var boundary_helper_1 = require("../../mol-math/geometry/boundary-helper");
function calculateTextureInfo(n, itemSize) {
n = Math.max(n, 2); // observed issues with 1 pixel textures
var sqN = Math.sqrt(n);
var width = Math.ceil(sqN);
width = width + (itemSize - (width % itemSize)) % itemSize;
var height = width > 0 ? Math.ceil(n / width) : 0;
return { width: width, height: height, length: width * height * itemSize };
}
exports.calculateTextureInfo = calculateTextureInfo;
function createTextureImage(n, itemSize, arrayCtor, array) {
var _a = calculateTextureInfo(n, itemSize), length = _a.length, width = _a.width, height = _a.height;
array = array && array.length >= length ? array : new arrayCtor(length);
return { array: array, width: width, height: height };
}
exports.createTextureImage = createTextureImage;
var DefaultPrintImageOptions = {
scale: 1,
pixelated: false,
id: 'molstar.debug.image'
};
function printTextureImage(textureImage, options) {
if (options === void 0) { options = {}; }
var array = textureImage.array, width = textureImage.width, height = textureImage.height;
var itemSize = array.length / (width * height);
var data = new Uint8ClampedArray(width * height * 4);
if (itemSize === 1) {
for (var y = 0; y < height; ++y) {
for (var x = 0; x < width; ++x) {
data[(y * width + x) * 4 + 3] = array[y * width + x];
}
}
}
else if (itemSize === 4) {
data.set(array);
}
else {
console.warn("itemSize '" + itemSize + "' not supported");
}
return printImageData(new ImageData(data, width, height), options);
}
exports.printTextureImage = printTextureImage;
var tmpCanvas;
var tmpCanvasCtx;
var tmpContainer;
function printImageData(imageData, options) {
if (options === void 0) { options = {}; }
var o = (0, tslib_1.__assign)((0, tslib_1.__assign)({}, DefaultPrintImageOptions), options);
var canvas = tmpCanvas || document.createElement('canvas');
tmpCanvas = canvas;
canvas.width = imageData.width;
canvas.height = imageData.height;
var ctx = tmpCanvasCtx || canvas.getContext('2d');
tmpCanvasCtx = ctx;
if (!ctx)
throw new Error('Could not create canvas 2d context');
ctx.putImageData(imageData, 0, 0);
if (!tmpContainer) {
tmpContainer = document.createElement('div');
tmpContainer.style.position = 'absolute';
tmpContainer.style.bottom = '0px';
tmpContainer.style.right = '0px';
tmpContainer.style.border = 'solid orange';
tmpContainer.style.pointerEvents = 'none';
document.body.appendChild(tmpContainer);
}
canvas.toBlob(function (imgBlob) {
var objectURL = URL.createObjectURL(imgBlob);
var existingImg = document.getElementById(o.id);
var img = existingImg || document.createElement('img');
img.id = o.id;
img.src = objectURL;
img.style.width = imageData.width * o.scale + 'px';
img.style.height = imageData.height * o.scale + 'px';
if (o.pixelated) {
// not supported in Firefox and IE
img.style.imageRendering = 'pixelated';
}
img.style.position = 'relative';
img.style.border = 'solid grey';
img.style.pointerEvents = 'none';
if (!existingImg)
tmpContainer.appendChild(img);
}, 'image/png');
}
exports.printImageData = printImageData;
//
var v = (0, linear_algebra_1.Vec3)();
var boundaryHelperCoarse = new boundary_helper_1.BoundaryHelper('14');
var boundaryHelperFine = new boundary_helper_1.BoundaryHelper('98');
function getHelper(count) {
return count > 100000 ? boundaryHelperCoarse : boundaryHelperFine;
}
function calculateInvariantBoundingSphere(position, positionCount, stepFactor) {
var step = stepFactor * 3;
var boundaryHelper = getHelper(positionCount);
boundaryHelper.reset();
for (var i = 0, _i = positionCount * 3; i < _i; i += step) {
linear_algebra_1.Vec3.fromArray(v, position, i);
boundaryHelper.includePosition(v);
}
boundaryHelper.finishedIncludeStep();
for (var i = 0, _i = positionCount * 3; i < _i; i += step) {
linear_algebra_1.Vec3.fromArray(v, position, i);
boundaryHelper.radiusPosition(v);
}
var sphere = boundaryHelper.getSphere();
if (positionCount <= 98) {
var extrema = [];
for (var i = 0, _i = positionCount * 3; i < _i; i += step) {
extrema.push(linear_algebra_1.Vec3.fromArray((0, linear_algebra_1.Vec3)(), position, i));
}
geometry_1.Sphere3D.setExtrema(sphere, extrema);
}
return sphere;
}
exports.calculateInvariantBoundingSphere = calculateInvariantBoundingSphere;
var _mat4 = (0, linear_algebra_1.Mat4)();
function calculateTransformBoundingSphere(invariantBoundingSphere, transform, transformCount) {
if (transformCount === 1) {
linear_algebra_1.Mat4.fromArray(_mat4, transform, 0);
var s = geometry_1.Sphere3D.clone(invariantBoundingSphere);
return linear_algebra_1.Mat4.isIdentity(_mat4) ? s : geometry_1.Sphere3D.transform(s, s, _mat4);
}
var boundaryHelper = getHelper(transformCount);
boundaryHelper.reset();
var center = invariantBoundingSphere.center, radius = invariantBoundingSphere.radius, extrema = invariantBoundingSphere.extrema;
// only use extrema if there are not too many transforms
if (extrema && transformCount < 50) {
for (var i = 0, _i = transformCount; i < _i; ++i) {
for (var _a = 0, extrema_1 = extrema; _a < extrema_1.length; _a++) {
var e = extrema_1[_a];
linear_algebra_1.Vec3.transformMat4Offset(v, e, transform, 0, 0, i * 16);
boundaryHelper.includePosition(v);
}
}
boundaryHelper.finishedIncludeStep();
for (var i = 0, _i = transformCount; i < _i; ++i) {
for (var _b = 0, extrema_2 = extrema; _b < extrema_2.length; _b++) {
var e = extrema_2[_b];
linear_algebra_1.Vec3.transformMat4Offset(v, e, transform, 0, 0, i * 16);
boundaryHelper.radiusPosition(v);
}
}
}
else {
for (var i = 0, _i = transformCount; i < _i; ++i) {
linear_algebra_1.Vec3.transformMat4Offset(v, center, transform, 0, 0, i * 16);
boundaryHelper.includePositionRadius(v, radius);
}
boundaryHelper.finishedIncludeStep();
for (var i = 0, _i = transformCount; i < _i; ++i) {
linear_algebra_1.Vec3.transformMat4Offset(v, center, transform, 0, 0, i * 16);
boundaryHelper.radiusPositionRadius(v, radius);
}
}
return boundaryHelper.getSphere();
}
exports.calculateTransformBoundingSphere = calculateTransformBoundingSphere;
function calculateBoundingSphere(position, positionCount, transform, transformCount, padding, stepFactor) {
if (padding === void 0) { padding = 0; }
if (stepFactor === void 0) { stepFactor = 1; }
var invariantBoundingSphere = calculateInvariantBoundingSphere(position, positionCount, stepFactor);
var boundingSphere = calculateTransformBoundingSphere(invariantBoundingSphere, transform, transformCount);
geometry_1.Sphere3D.expand(boundingSphere, boundingSphere, padding);
geometry_1.Sphere3D.expand(invariantBoundingSphere, invariantBoundingSphere, padding);
return { boundingSphere: boundingSphere, invariantBoundingSphere: invariantBoundingSphere };
}
exports.calculateBoundingSphere = calculateBoundingSphere;
//# sourceMappingURL=util.js.map