molstar
Version:
A comprehensive macromolecular library.
171 lines • 7.45 kB
JavaScript
/**
* Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { __assign } from "tslib";
import { Sphere3D } from '../../mol-math/geometry';
import { Vec3, Mat4 } from '../../mol-math/linear-algebra';
import { BoundaryHelper } from '../../mol-math/geometry/boundary-helper';
export 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 };
}
export 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 };
}
var DefaultPrintImageOptions = {
scale: 1,
pixelated: false,
id: 'molstar.debug.image'
};
export 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);
}
var tmpCanvas;
var tmpCanvasCtx;
var tmpContainer;
export function printImageData(imageData, options) {
if (options === void 0) { options = {}; }
var o = __assign(__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');
}
//
var v = Vec3();
var boundaryHelperCoarse = new BoundaryHelper('14');
var boundaryHelperFine = new BoundaryHelper('98');
function getHelper(count) {
return count > 100000 ? boundaryHelperCoarse : boundaryHelperFine;
}
export 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) {
Vec3.fromArray(v, position, i);
boundaryHelper.includePosition(v);
}
boundaryHelper.finishedIncludeStep();
for (var i = 0, _i = positionCount * 3; i < _i; i += step) {
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(Vec3.fromArray(Vec3(), position, i));
}
Sphere3D.setExtrema(sphere, extrema);
}
return sphere;
}
var _mat4 = Mat4();
export function calculateTransformBoundingSphere(invariantBoundingSphere, transform, transformCount) {
if (transformCount === 1) {
Mat4.fromArray(_mat4, transform, 0);
var s = Sphere3D.clone(invariantBoundingSphere);
return Mat4.isIdentity(_mat4) ? s : 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];
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];
Vec3.transformMat4Offset(v, e, transform, 0, 0, i * 16);
boundaryHelper.radiusPosition(v);
}
}
}
else {
for (var i = 0, _i = transformCount; i < _i; ++i) {
Vec3.transformMat4Offset(v, center, transform, 0, 0, i * 16);
boundaryHelper.includePositionRadius(v, radius);
}
boundaryHelper.finishedIncludeStep();
for (var i = 0, _i = transformCount; i < _i; ++i) {
Vec3.transformMat4Offset(v, center, transform, 0, 0, i * 16);
boundaryHelper.radiusPositionRadius(v, radius);
}
}
return boundaryHelper.getSphere();
}
export 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);
Sphere3D.expand(boundingSphere, boundingSphere, padding);
Sphere3D.expand(invariantBoundingSphere, invariantBoundingSphere, padding);
return { boundingSphere: boundingSphere, invariantBoundingSphere: invariantBoundingSphere };
}
//# sourceMappingURL=util.js.map