UNPKG

molstar

Version:

A comprehensive macromolecular library.

126 lines (125 loc) 5.96 kB
"use strict"; /** * Copyright (c) 2026 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.CoordinationPolyhedronMeshParams = void 0; exports.CoordinationPolyhedronMeshVisual = CoordinationPolyhedronMeshVisual; const linear_algebra_1 = require("../../../mol-math/linear-algebra.js"); const structure_1 = require("../../../mol-model/structure.js"); const mesh_builder_1 = require("../../../mol-geo/geometry/mesh/mesh-builder.js"); const complex_visual_1 = require("../complex-visual.js"); const param_definition_1 = require("../../../mol-util/param-definition.js"); const location_iterator_1 = require("../../../mol-geo/util/location-iterator.js"); const picking_1 = require("../../../mol-geo/geometry/picking.js"); const int_1 = require("../../../mol-data/int.js"); const loci_1 = require("../../../mol-model/loci.js"); const convex_hull_1 = require("../../../mol-math/geometry/convex-hull.js"); const sorted_array_1 = require("../../../mol-data/int/sorted-array.js"); exports.CoordinationPolyhedronMeshParams = { ...complex_visual_1.ComplexMeshParams, includeParent: param_definition_1.ParamDefinition.Boolean(false), minCoordination: param_definition_1.ParamDefinition.Numeric(4, { min: 4, max: 12, step: 1 }, { description: 'Minimum number of coordinating atoms to draw a polyhedron' }), maxCoordination: param_definition_1.ParamDefinition.Numeric(12, { min: 4, max: 24, step: 1 }, { description: 'Maximum coordination number' }), }; function createCoordinationPolyhedronMesh(ctx, structure, theme, props, mesh) { const { minCoordination, maxCoordination } = props; const { child, coordination: { sites, eachLigand } } = structure; const count = sites.count * 4; const builderState = mesh_builder_1.MeshBuilder.createState(count, count / 2, mesh); for (let i = 0; i < sites.count; i++) { const number = sites.numbers[i]; if (number < minCoordination || number > maxCoordination) continue; if (child) { const unit = structure.unitMap.get(sites.unitIds[i]); const childUnit = child.unitMap.get(unit.id); const element = unit.elements[sites.indices[i]]; if (!childUnit || !sorted_array_1.SortedArray.has(childUnit.elements, element)) continue; } const positions = []; eachLigand(i, l => { const p = l.unit.conformation.position(l.element, (0, linear_algebra_1.Vec3)()); positions.push(p); }); const hull = (0, convex_hull_1.convexHull)(positions); if (hull) { builderState.currentGroup = i; for (let i = 0; i < hull.indices.length; i += 3) { const a = positions[hull.indices[i]]; const b = positions[hull.indices[i + 1]]; const c = positions[hull.indices[i + 2]]; mesh_builder_1.MeshBuilder.addTriangle(builderState, a, b, c); } } } return mesh_builder_1.MeshBuilder.getMesh(builderState); } function CoordinationPolyhedronIterator(structure, props) { const { sites } = structure.coordination; const groupCount = sites.count; const instanceCount = 1; const location = structure_1.StructureElement.Location.create(structure); function getLocation(groupIndex) { if (groupIndex < sites.count) { const u = structure.unitMap.get(sites.unitIds[groupIndex]); location.unit = u; location.element = u.elements[sites.indices[groupIndex]]; } return location; } return (0, location_iterator_1.LocationIterator)(groupCount, instanceCount, 1, getLocation, true); } function getCoordinationPolyhedronLoci(pickingId, structure, id) { const { objectId, groupId } = pickingId; if (id === objectId) { if (groupId === picking_1.PickingId.Null) { return structure_1.Structure.Loci(structure); } const { sites } = structure.coordination; if (groupId < sites.count) { return structure_1.StructureElement.Loci(structure, [{ unit: structure.unitMap.get(sites.unitIds[groupId]), indices: int_1.OrderedSet.ofSingleton(sites.indices[groupId]) }]); } return structure_1.Structure.Loci(structure); } return loci_1.EmptyLoci; } function eachCoordinationPolyhedron(loci, structure, apply) { let changed = false; if (!structure_1.StructureElement.Loci.is(loci)) return false; if (!structure_1.Structure.areEquivalent(loci.structure, structure)) return false; const { getSiteIndex } = structure.coordination; for (const { unit, indices } of loci.elements) { if (!structure_1.Unit.isAtomic(unit)) continue; int_1.OrderedSet.forEach(indices, v => { const groupIndex = getSiteIndex(unit, unit.elements[v]); if (groupIndex >= 0) { if (apply(int_1.Interval.ofSingleton(groupIndex))) changed = true; } }); } return changed; } function CoordinationPolyhedronMeshVisual(materialId) { return (0, complex_visual_1.ComplexMeshVisual)({ defaultProps: param_definition_1.ParamDefinition.getDefaultValues(exports.CoordinationPolyhedronMeshParams), createGeometry: createCoordinationPolyhedronMesh, createLocationIterator: CoordinationPolyhedronIterator, getLoci: getCoordinationPolyhedronLoci, eachLocation: eachCoordinationPolyhedron, setUpdateState: (state, newProps, currentProps) => { state.createGeometry = (newProps.minCoordination !== currentProps.minCoordination || newProps.maxCoordination !== currentProps.maxCoordination); } }, materialId); }