UNPKG

molstar

Version:

A comprehensive macromolecular library.

171 lines 7.45 kB
/** * 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