UNPKG

molstar

Version:

A comprehensive macromolecular library.

194 lines (193 loc) 6.4 kB
"use strict"; /** * Copyright (c) 2018-2025 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.DefaultQualityThresholds = exports.VisualUpdateState = void 0; exports.getStructureQuality = getStructureQuality; exports.getQualityProps = getQualityProps; const mol_util_1 = require("../mol-util"); const structure_1 = require("../mol-model/structure"); const geometry_1 = require("../mol-math/geometry"); const symmetry_1 = require("../mol-model-formats/structure/property/symmetry"); const volume_1 = require("../mol-model/volume"); var VisualUpdateState; (function (VisualUpdateState) { function create() { return { updateTransform: false, updateMatrix: false, updateColor: false, updateSize: false, createGeometry: false, createNew: false, info: {} }; } VisualUpdateState.create = create; function reset(state) { state.updateTransform = false; state.updateMatrix = false; state.updateColor = false; state.updateSize = false; state.createGeometry = false; state.createNew = false; } VisualUpdateState.reset = reset; })(VisualUpdateState || (exports.VisualUpdateState = VisualUpdateState = {})); exports.DefaultQualityThresholds = { lowestElementCount: 1000000, lowerElementCount: 500000, lowElementCount: 100000, mediumElementCount: 20000, highElementCount: 2000, coarseGrainedFactor: 10, elementCountFactor: 1 }; function getStructureQuality(structure, tresholds = {}) { const t = { ...exports.DefaultQualityThresholds, ...tresholds }; let score = structure.elementCount * t.elementCountFactor; if (structure.isCoarseGrained || structure.isCoarse) score *= t.coarseGrainedFactor; if (score > t.lowestElementCount) { return 'lowest'; } else if (score > t.lowerElementCount) { return 'lower'; } else if (score > t.lowElementCount) { return 'low'; } else if (score > t.mediumElementCount) { return 'medium'; } else if (score > t.highElementCount) { return 'high'; } else { return 'higher'; } } /** * Uses cell volume to avoid costly boundary calculation if * - single model * - non-empty 'P 1' spacegroup */ function getRootVolume(structure) { if (structure.root.models.length === 1) { const sym = symmetry_1.ModelSymmetry.Provider.get(structure.root.model); if (sym && sym.spacegroup.name === 'P 1' && !geometry_1.SpacegroupCell.isZero(sym.spacegroup.cell)) { return sym.spacegroup.cell.volume; } } return geometry_1.Box3D.volume(structure.root.boundary.box); } function getQualityProps(props, data) { let quality = (0, mol_util_1.defaults)(props.quality, 'auto'); let detail = (0, mol_util_1.defaults)(props.detail, 1); let radialSegments = (0, mol_util_1.defaults)(props.radialSegments, 12); let linearSegments = (0, mol_util_1.defaults)(props.linearSegments, 8); let resolution = (0, mol_util_1.defaults)(props.resolution, 2); let imageResolution = (0, mol_util_1.defaults)(props.imageResolution, 1); let probePositions = (0, mol_util_1.defaults)(props.probePositions, 12); let doubleSided = (0, mol_util_1.defaults)(props.doubleSided, true); let volume = 0; if (quality === 'auto') { if (data instanceof structure_1.Structure) { quality = getStructureQuality(data.root); volume = getRootVolume(data); } else if (volume_1.Volume.is(data)) { const [x, y, z] = data.grid.cells.space.dimensions; volume = x * y * z; quality = volume < 10000000 ? 'medium' : 'low'; } } switch (quality) { case 'highest': detail = 3; radialSegments = 36; linearSegments = 18; resolution = 0.1; imageResolution = 0.01; probePositions = 72; doubleSided = true; break; case 'higher': detail = 3; radialSegments = 28; linearSegments = 14; resolution = 0.3; imageResolution = 0.05; probePositions = 48; doubleSided = true; break; case 'high': detail = 2; radialSegments = 20; linearSegments = 10; resolution = 0.5; imageResolution = 0.1; probePositions = 36; doubleSided = true; break; case 'medium': detail = 1; radialSegments = 12; linearSegments = 8; resolution = 0.8; imageResolution = 0.2; probePositions = 24; doubleSided = true; break; case 'low': detail = 0; radialSegments = 8; linearSegments = 3; resolution = 1.3; imageResolution = 0.4; probePositions = 24; doubleSided = false; break; case 'lower': detail = 0; radialSegments = 4; linearSegments = 2; resolution = 3; imageResolution = 0.7; probePositions = 12; doubleSided = false; break; case 'lowest': detail = 0; radialSegments = 2; linearSegments = 1; resolution = 8; imageResolution = 1; probePositions = 12; doubleSided = false; break; case 'custom': // use defaults or given props as set above break; } // max resolution based on volume (for 'auto' quality) if (volume > 0) { resolution = Math.max(resolution, volume / 300000000); resolution = Math.min(resolution, 20); } if (props.transparentBackfaces === 'off' && ((props.alpha !== undefined && props.alpha < 1) || !!props.xrayShaded)) { doubleSided = false; } return { detail, radialSegments, linearSegments, resolution, imageResolution, probePositions, doubleSided }; }