molstar
Version:
A comprehensive macromolecular library.
188 lines • 9.93 kB
JavaScript
"use strict";
/**
* Copyright (c) 2019-2021 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");
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;
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 /* 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 /* Filtered */)
return true;
if (child) {
var b = edges[edgeIndex];
var childUnitA = child.unitMap.get(b.unitA);
if (!childUnitA)
return true;
var unitA = structure.unitMap.get(b.unitA);
var fA = unitsFeatures.get(b.unitA);
// TODO: check all members
var eA = unitA.elements[fA.members[fA.offsets[b.indexA]]];
if (!int_1.SortedArray.has(childUnitA.elements, eA))
return true;
}
return false;
}
};
var m = (0, link_1.createLinkCylinderMesh)(ctx, builderProps, props, mesh);
var sphere = geometry_1.Sphere3D.expand((0, geometry_1.Sphere3D)(), (child !== null && child !== void 0 ? child : structure).boundary.sphere, 1 * sizeFactor);
m.setBoundingSphere(sphere);
return m;
}
exports.InteractionsInterUnitParams = (0, tslib_1.__assign)((0, tslib_1.__assign)((0, tslib_1.__assign)({}, complex_visual_1.ComplexMeshParams), link_1.LinkCylinderParams), { sizeFactor: param_definition_1.ParamDefinition.Numeric(0.3, { min: 0, max: 10, step: 0.01 }), dashCount: param_definition_1.ParamDefinition.Numeric(6, { min: 2, max: 10, step: 2 }), dashScale: param_definition_1.ParamDefinition.Numeric(0.4, { min: 0, max: 2, step: 0.1 }), includeParent: param_definition_1.ParamDefinition.Boolean(false) });
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);
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;
}
function eachInteraction(loci, structure, apply, isMarking) {
var _a;
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, _b = loci.elements; _i < _b.length; _i++) {
var c = _b[_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 contacts_1 = (_a = interactions_2.InteractionsProvider.get(structure).value) === null || _a === void 0 ? void 0 : _a.contacts;
if (!contacts_1)
return false;
var _loop_1 = function (e) {
var unit = e.unit;
if (!structure_2.Unit.isAtomic(unit))
return "continue";
if (isMarking && int_1.OrderedSet.size(e.indices) === 1)
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];
if (apply(int_1.Interval.ofSingleton(idx)))
changed = true;
}
});
};
// TODO when isMarking, all elements of contact features need to be in the loci
for (var _c = 0, _d = loci.elements; _c < _d.length; _c++) {
var e = _d[_c];
_loop_1(e);
}
}
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);
}
//# sourceMappingURL=interactions-inter-unit-cylinder.js.map