UNPKG

molstar

Version:

A comprehensive macromolecular library.

130 lines (129 loc) 6.46 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 { Representation } from '../../../mol-repr/representation'; import { Mesh } from '../../../mol-geo/geometry/mesh/mesh'; import { LocationIterator } from '../../../mol-geo/util/location-iterator'; import { EmptyLoci } from '../../../mol-model/loci'; import { Interval } from '../../../mol-data/int'; import { ParamDefinition as PD } from '../../../mol-util/param-definition'; import { Structure, StructureElement } from '../../../mol-model/structure'; import { createLinkCylinderMesh, LinkCylinderParams } from '../../../mol-repr/structure/visual/util/link'; import { ComplexMeshParams, ComplexMeshVisual } from '../../../mol-repr/structure/complex-visual'; import { ComplexRepresentation, StructureRepresentationStateBuilder, StructureRepresentationProvider } from '../../../mol-repr/structure/representation'; import { CrossLinkRestraintProvider, CrossLinkRestraint } from './property'; import { Sphere3D } from '../../../mol-math/geometry'; function createCrossLinkRestraintCylinderMesh(ctx, structure, theme, props, mesh) { var crossLinks = CrossLinkRestraintProvider.get(structure).value; if (!crossLinks.count) return Mesh.createEmpty(mesh); var sizeFactor = props.sizeFactor; var location = StructureElement.Location.create(structure); var builderProps = { linkCount: crossLinks.count, position: function (posA, posB, edgeIndex) { var b = crossLinks.pairs[edgeIndex]; var uA = b.unitA, uB = b.unitB; uA.conformation.position(uA.elements[b.indexA], posA); uB.conformation.position(uB.elements[b.indexB], posB); }, radius: function (edgeIndex) { var b = crossLinks.pairs[edgeIndex]; location.unit = b.unitA; location.element = b.unitA.elements[b.indexA]; return theme.size.size(location) * sizeFactor; }, }; var _a = createLinkCylinderMesh(ctx, builderProps, props, mesh), m = _a.mesh, boundingSphere = _a.boundingSphere; if (boundingSphere) { m.setBoundingSphere(boundingSphere); } else if (m.triangleCount > 0) { var sphere = Sphere3D.expand(Sphere3D(), structure.boundary.sphere, 1 * sizeFactor); m.setBoundingSphere(sphere); } return m; } export var CrossLinkRestraintCylinderParams = __assign(__assign(__assign({}, ComplexMeshParams), LinkCylinderParams), { sizeFactor: PD.Numeric(0.5, { min: 0, max: 10, step: 0.1 }) }); export function CrossLinkRestraintVisual(materialId) { return ComplexMeshVisual({ defaultProps: PD.getDefaultValues(CrossLinkRestraintCylinderParams), createGeometry: createCrossLinkRestraintCylinderMesh, createLocationIterator: createCrossLinkRestraintIterator, getLoci: getLinkLoci, eachLocation: eachCrossLink, setUpdateState: function (state, newProps, currentProps) { state.createGeometry = (newProps.sizeFactor !== currentProps.sizeFactor || newProps.radialSegments !== currentProps.radialSegments || newProps.linkCap !== currentProps.linkCap); } }, materialId); } function createCrossLinkRestraintIterator(structure) { var crossLinkRestraints = CrossLinkRestraintProvider.get(structure).value; var pairs = crossLinkRestraints.pairs; var groupCount = pairs.length; var instanceCount = 1; var location = CrossLinkRestraint.Location(crossLinkRestraints, structure); var getLocation = function (groupIndex) { location.element = groupIndex; return location; }; return LocationIterator(groupCount, instanceCount, 1, getLocation, true); } function getLinkLoci(pickingId, structure, id) { var objectId = pickingId.objectId, groupId = pickingId.groupId; if (id === objectId) { var crossLinkRestraints = CrossLinkRestraintProvider.get(structure).value; var pair = crossLinkRestraints.pairs[groupId]; if (pair) { return CrossLinkRestraint.Loci(structure, crossLinkRestraints, [groupId]); } } return EmptyLoci; } function eachCrossLink(loci, structure, apply) { var changed = false; if (CrossLinkRestraint.isLoci(loci)) { if (!Structure.areEquivalent(loci.data.structure, structure)) return false; var crossLinkRestraints = CrossLinkRestraintProvider.get(structure).value; if (loci.data.crossLinkRestraints !== crossLinkRestraints) return false; for (var _i = 0, _a = loci.elements; _i < _a.length; _i++) { var e = _a[_i]; if (apply(Interval.ofSingleton(e))) changed = true; } } return changed; } // var CrossLinkRestraintVisuals = { 'cross-link-restraint': function (ctx, getParams) { return ComplexRepresentation('Cross-link restraint', ctx, getParams, CrossLinkRestraintVisual); }, }; export var CrossLinkRestraintParams = __assign({}, CrossLinkRestraintCylinderParams); export function getCrossLinkRestraintParams(ctx, structure) { return PD.clone(CrossLinkRestraintParams); } export function CrossLinkRestraintRepresentation(ctx, getParams) { return Representation.createMulti('CrossLinkRestraint', ctx, getParams, StructureRepresentationStateBuilder, CrossLinkRestraintVisuals); } export var CrossLinkRestraintRepresentationProvider = StructureRepresentationProvider({ name: CrossLinkRestraint.Tag.CrossLinkRestraint, label: 'Cross Link Restraint', description: 'Displays cross-link restraints.', factory: CrossLinkRestraintRepresentation, getParams: getCrossLinkRestraintParams, defaultValues: PD.getDefaultValues(CrossLinkRestraintParams), defaultColorTheme: { name: CrossLinkRestraint.Tag.CrossLinkRestraint }, defaultSizeTheme: { name: 'uniform' }, isApplicable: function (structure) { return CrossLinkRestraint.isApplicable(structure); }, ensureCustomProperties: { attach: function (ctx, structure) { return CrossLinkRestraintProvider.attach(ctx, structure, void 0, true); }, detach: function (data) { return CrossLinkRestraintProvider.ref(data, false); } } });