UNPKG

molstar

Version:

A comprehensive macromolecular library.

259 lines (258 loc) 13.2 kB
"use strict"; /** * Copyright (c) 2019-2022 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.InteractionsInterUnitVisual = exports.InteractionsInterUnitParams = void 0; var tslib_1 = require("tslib"); var param_definition_1 = require("../../../mol-util/param-definition"); var structure_1 = require("../../../mol-model/structure"); var mesh_1 = require("../../../mol-geo/geometry/mesh/mesh"); var linear_algebra_1 = require("../../../mol-math/linear-algebra"); var link_1 = require("../../../mol-repr/structure/visual/util/link"); var complex_visual_1 = require("../../../mol-repr/structure/complex-visual"); var loci_1 = require("../../../mol-model/loci"); var int_1 = require("../../../mol-data/int"); var interactions_1 = require("../interactions/interactions"); var interactions_2 = require("../interactions"); var location_iterator_1 = require("../../../mol-geo/util/location-iterator"); var structure_2 = require("../../../mol-model/structure/structure"); var geometry_1 = require("../../../mol-math/geometry"); var type_helpers_1 = require("../../../mol-util/type-helpers"); var shared_1 = require("./shared"); function createInterUnitInteractionCylinderMesh(ctx, structure, theme, props, mesh) { if (!structure.hasAtomic) return mesh_1.Mesh.createEmpty(mesh); var l = structure_1.StructureElement.Location.create(structure); var interactions = interactions_2.InteractionsProvider.get(structure).value; var contacts = interactions.contacts, unitsFeatures = interactions.unitsFeatures; var edgeCount = contacts.edgeCount, edges = contacts.edges; var sizeFactor = props.sizeFactor, parentDisplay = props.parentDisplay; if (!edgeCount) return mesh_1.Mesh.createEmpty(mesh); var child = structure.child; var builderProps = { linkCount: edgeCount, position: function (posA, posB, edgeIndex) { var _a = edges[edgeIndex], unitA = _a.unitA, indexA = _a.indexA, unitB = _a.unitB, indexB = _a.indexB; var fA = unitsFeatures.get(unitA); var fB = unitsFeatures.get(unitB); var uA = structure.unitMap.get(unitA); var uB = structure.unitMap.get(unitB); linear_algebra_1.Vec3.set(posA, fA.x[indexA], fA.y[indexA], fA.z[indexA]); linear_algebra_1.Vec3.transformMat4(posA, posA, uA.conformation.operator.matrix); linear_algebra_1.Vec3.set(posB, fB.x[indexB], fB.y[indexB], fB.z[indexB]); linear_algebra_1.Vec3.transformMat4(posB, posB, uB.conformation.operator.matrix); }, style: function (edgeIndex) { return 1 /* LinkStyle.Dashed */; }, radius: function (edgeIndex) { var b = edges[edgeIndex]; var fA = unitsFeatures.get(b.unitA); l.unit = structure.unitMap.get(b.unitA); l.element = l.unit.elements[fA.members[fA.offsets[b.indexA]]]; var sizeA = theme.size.size(l); var fB = unitsFeatures.get(b.unitB); l.unit = structure.unitMap.get(b.unitB); l.element = l.unit.elements[fB.members[fB.offsets[b.indexB]]]; var sizeB = theme.size.size(l); return Math.min(sizeA, sizeB) * sizeFactor; }, ignore: function (edgeIndex) { if (edges[edgeIndex].props.flag === 1 /* InteractionFlag.Filtered */) return true; if (child) { var b = edges[edgeIndex]; if (parentDisplay === 'stub') { var childUnitA = child.unitMap.get(b.unitA); if (!childUnitA) return true; var unitA = structure.unitMap.get(b.unitA); var _a = unitsFeatures.get(b.unitA), offsets = _a.offsets, members = _a.members; for (var i = offsets[b.indexA], il = offsets[b.indexA + 1]; i < il; ++i) { var eA = unitA.elements[members[i]]; if (!int_1.SortedArray.has(childUnitA.elements, eA)) return true; } } else if (parentDisplay === 'full' || parentDisplay === 'between') { var flagA = false; var flagB = false; var childUnitA = child.unitMap.get(b.unitA); if (!childUnitA) { flagA = true; } else { var unitA = structure.unitMap.get(b.unitA); var _b = unitsFeatures.get(b.unitA), offsets = _b.offsets, members = _b.members; for (var i = offsets[b.indexA], il = offsets[b.indexA + 1]; i < il; ++i) { var eA = unitA.elements[members[i]]; if (!int_1.SortedArray.has(childUnitA.elements, eA)) flagA = true; } } var childUnitB = child.unitMap.get(b.unitB); if (!childUnitB) { flagB = true; } else { var unitB = structure.unitMap.get(b.unitB); var _c = unitsFeatures.get(b.unitB), offsets = _c.offsets, members = _c.members; for (var i = offsets[b.indexB], il = offsets[b.indexB + 1]; i < il; ++i) { var eB = unitB.elements[members[i]]; if (!int_1.SortedArray.has(childUnitB.elements, eB)) flagB = true; } } return parentDisplay === 'full' ? flagA && flagB : flagA === flagB; } else { (0, type_helpers_1.assertUnreachable)(parentDisplay); } } return false; } }; var _a = (0, link_1.createLinkCylinderMesh)(ctx, builderProps, props, mesh), m = _a.mesh, boundingSphere = _a.boundingSphere; if (boundingSphere) { m.setBoundingSphere(boundingSphere); } else if (m.triangleCount > 0) { var child_1 = structure.child; var sphere = geometry_1.Sphere3D.expand((0, geometry_1.Sphere3D)(), (child_1 !== null && child_1 !== void 0 ? child_1 : structure).boundary.sphere, 1 * sizeFactor); m.setBoundingSphere(sphere); } return m; } exports.InteractionsInterUnitParams = tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, complex_visual_1.ComplexMeshParams), link_1.LinkCylinderParams), shared_1.InteractionsSharedParams); function InteractionsInterUnitVisual(materialId) { return (0, complex_visual_1.ComplexMeshVisual)({ defaultProps: param_definition_1.ParamDefinition.getDefaultValues(exports.InteractionsInterUnitParams), createGeometry: createInterUnitInteractionCylinderMesh, createLocationIterator: createInteractionsIterator, getLoci: getInteractionLoci, eachLocation: eachInteraction, setUpdateState: function (state, newProps, currentProps, newTheme, currentTheme, newStructure, currentStructure) { state.createGeometry = (newProps.sizeFactor !== currentProps.sizeFactor || newProps.dashCount !== currentProps.dashCount || newProps.dashScale !== currentProps.dashScale || newProps.dashCap !== currentProps.dashCap || newProps.radialSegments !== currentProps.radialSegments || newProps.parentDisplay !== currentProps.parentDisplay); var interactionsHash = interactions_2.InteractionsProvider.get(newStructure).version; if (state.info.interactionsHash !== interactionsHash) { state.createGeometry = true; state.updateTransform = true; state.updateColor = true; state.info.interactionsHash = interactionsHash; } } }, materialId); } exports.InteractionsInterUnitVisual = InteractionsInterUnitVisual; function getInteractionLoci(pickingId, structure, id) { var objectId = pickingId.objectId, groupId = pickingId.groupId; if (id === objectId) { var interactions = interactions_2.InteractionsProvider.get(structure).value; var c = interactions.contacts.edges[groupId]; var unitA = structure.unitMap.get(c.unitA); var unitB = structure.unitMap.get(c.unitB); return interactions_1.Interactions.Loci(structure, interactions, [ { unitA: unitA, indexA: c.indexA, unitB: unitB, indexB: c.indexB }, { unitA: unitB, indexA: c.indexB, unitB: unitA, indexB: c.indexA }, ]); } return loci_1.EmptyLoci; } var __unitMap = new Map(); var __contactIndicesSet = new Set(); function eachInteraction(loci, structure, apply, isMarking) { var changed = false; if (interactions_1.Interactions.isLoci(loci)) { if (!structure_1.Structure.areEquivalent(loci.data.structure, structure)) return false; var interactions = interactions_2.InteractionsProvider.get(structure).value; if (loci.data.interactions !== interactions) return false; var contacts = interactions.contacts; for (var _i = 0, _a = loci.elements; _i < _a.length; _i++) { var c = _a[_i]; var idx = contacts.getEdgeIndex(c.indexA, c.unitA.id, c.indexB, c.unitB.id); if (idx !== -1) { if (apply(int_1.Interval.ofSingleton(idx))) changed = true; } } } else if (structure_1.StructureElement.Loci.is(loci)) { if (!structure_1.Structure.areEquivalent(loci.structure, structure)) return false; if (isMarking && loci.elements.length === 1) return false; // only a single unit var interactions = interactions_2.InteractionsProvider.get(structure).value; if (!interactions) return false; var contacts_1 = interactions.contacts, unitsFeatures_1 = interactions.unitsFeatures; for (var _b = 0, _c = loci.elements; _b < _c.length; _b++) { var e = _c[_b]; __unitMap.set(e.unit.id, e.indices); } var _loop_1 = function (e) { var unit = e.unit; if (!structure_2.Unit.isAtomic(unit)) return "continue"; int_1.OrderedSet.forEach(e.indices, function (v) { for (var _i = 0, _a = contacts_1.getContactIndicesForElement(v, unit); _i < _a.length; _i++) { var idx = _a[_i]; __contactIndicesSet.add(idx); } }); }; for (var _d = 0, _e = loci.elements; _d < _e.length; _d++) { var e = _e[_d]; _loop_1(e); } __contactIndicesSet.forEach(function (i) { if (isMarking) { var _a = contacts_1.edges[i], indexA = _a.indexA, unitA = _a.unitA, indexB = _a.indexB, unitB = _a.unitB; var indicesA = __unitMap.get(unitA); var indicesB = __unitMap.get(unitB); if (!indicesA || !indicesB) return; var _b = unitsFeatures_1.get(unitA), offsetsA = _b.offsets, membersA = _b.members; for (var j = offsetsA[indexA], jl = offsetsA[indexA + 1]; j < jl; ++j) { if (!int_1.OrderedSet.has(indicesA, membersA[j])) return; } var _c = unitsFeatures_1.get(unitB), offsetsB = _c.offsets, membersB = _c.members; for (var j = offsetsB[indexB], jl = offsetsB[indexB + 1]; j < jl; ++j) { if (!int_1.OrderedSet.has(indicesB, membersB[j])) return; } } if (apply(int_1.Interval.ofSingleton(i))) changed = true; }); __unitMap.clear(); __contactIndicesSet.clear(); } return changed; } function createInteractionsIterator(structure) { var interactions = interactions_2.InteractionsProvider.get(structure).value; var contacts = interactions.contacts; var groupCount = contacts.edgeCount; var instanceCount = 1; var location = interactions_1.Interactions.Location(interactions, structure); var element = location.element; var getLocation = function (groupIndex) { var c = contacts.edges[groupIndex]; element.unitA = structure.unitMap.get(c.unitA); element.indexA = c.indexA; element.unitB = structure.unitMap.get(c.unitB); element.indexB = c.indexB; return location; }; return (0, location_iterator_1.LocationIterator)(groupCount, instanceCount, 1, getLocation, true); }