-
Alexander Rose authoredAlexander Rose authored
common.ts 5.31 KiB
/**
* Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { Unit, Structure, ElementIndex, StructureElement } from 'mol-model/structure';
import { createMeshRenderObject, createPointsRenderObject, createLinesRenderObject, createDirectVolumeRenderObject } from 'mol-gl/render-object';
import { Mat4 } from 'mol-math/linear-algebra';
import { TransformData, createTransform, createIdentityTransform } from 'mol-geo/geometry/transform-data';
import { Mesh } from 'mol-geo/geometry/mesh/mesh';
import { LocationIterator } from 'mol-geo/util/location-iterator';
import { Geometry } from 'mol-geo/geometry/geometry';
import { Points } from 'mol-geo/geometry/points/points';
import { Lines } from 'mol-geo/geometry/lines/lines';
import { DirectVolume } from 'mol-geo/geometry/direct-volume/direct-volume';
import { Theme } from 'mol-theme/theme';
import { ParamDefinition as PD } from 'mol-util/param-definition';
import { StructureMeshParams, StructurePointsParams, StructureLinesParams, StructureDirectVolumeParams } from 'mol-repr/structure/representation';
import { OrderedSet, SortedArray } from 'mol-data/int';
import { EmptyLoci, Loci } from 'mol-model/loci';
/** Return a Loci for the elements of a whole residue the elementIndex belongs to. */
export function getResidueLoci(structure: Structure, unit: Unit, elementIndex: ElementIndex): Loci {
const { elements, model } = unit
if (OrderedSet.indexOf(elements, elementIndex) !== -1) {
const { index, offsets } = model.atomicHierarchy.residueAtomSegments
const rI = index[elementIndex]
const _indices: number[] = []
for (let i = offsets[rI], il = offsets[rI + 1]; i < il; ++i) {
const unitIndex = OrderedSet.indexOf(elements, i)
if (unitIndex !== -1) _indices.push(unitIndex)
}
const indices = OrderedSet.ofSortedArray<StructureElement.UnitIndex>(SortedArray.ofSortedArray(_indices))
return StructureElement.Loci(structure, [{ unit, indices }])
}
return EmptyLoci
}
//
export function createUnitsTransform({ units }: Unit.SymmetryGroup, transformData?: TransformData) {
const unitCount = units.length
const n = unitCount * 16
const array = transformData && transformData.aTransform.ref.value.length >= n ? transformData.aTransform.ref.value : new Float32Array(n)
for (let i = 0; i < unitCount; i++) {
Mat4.toArray(units[i].conformation.operator.matrix, array, i * 16)
}
return createTransform(array, unitCount, transformData)
}
export const UnitKindInfo = {
'atomic': {},
'spheres': {},
'gaussians': {},
}
export type UnitKind = keyof typeof UnitKindInfo
export const UnitKindNames = Object.keys(UnitKindInfo)
export const UnitKindOptions = UnitKindNames.map(n => [n, n] as [UnitKind, string])
export function includesUnitKind(unitKinds: UnitKind[], unit: Unit) {
for (let i = 0, il = unitKinds.length; i < il; ++i) {
if (Unit.isAtomic(unit) && unitKinds[i] === 'atomic') return true
if (Unit.isSpheres(unit) && unitKinds[i] === 'spheres') return true
if (Unit.isGaussians(unit) && unitKinds[i] === 'gaussians') return true
}
return false
}
// mesh
export function createComplexMeshRenderObject(structure: Structure, mesh: Mesh, locationIt: LocationIterator, theme: Theme, props: PD.Values<StructureMeshParams>) {
const transform = createIdentityTransform()
const values = Mesh.createValues(mesh, transform, locationIt, theme, props)
const state = Geometry.createRenderableState(props)
return createMeshRenderObject(values, state)
}
export function createUnitsMeshRenderObject(group: Unit.SymmetryGroup, mesh: Mesh, locationIt: LocationIterator, theme: Theme, props: PD.Values<StructureMeshParams>) {
const transform = createUnitsTransform(group)
const values = Mesh.createValues(mesh, transform, locationIt, theme, props)
const state = Geometry.createRenderableState(props)
return createMeshRenderObject(values, state)
}
// points
export function createUnitsPointsRenderObject(group: Unit.SymmetryGroup, points: Points, locationIt: LocationIterator, theme: Theme, props: PD.Values<StructurePointsParams>) {
const transform = createUnitsTransform(group)
const values = Points.createValues(points, transform, locationIt, theme, props)
const state = Points.createRenderableState(props)
return createPointsRenderObject(values, state)
}
// lines
export function createUnitsLinesRenderObject(group: Unit.SymmetryGroup, lines: Lines, locationIt: LocationIterator, theme: Theme, props: PD.Values<StructureLinesParams>) {
const transform = createUnitsTransform(group)
const values = Lines.createValues(lines, transform, locationIt, theme, props)
const state = Geometry.createRenderableState(props)
return createLinesRenderObject(values, state)
}
// direct-volume
export function createUnitsDirectVolumeRenderObject(group: Unit.SymmetryGroup, directVolume: DirectVolume, locationIt: LocationIterator, theme: Theme, props: PD.Values<StructureDirectVolumeParams>) {
const transform = createUnitsTransform(group)
const values = DirectVolume.createValues(directVolume, transform, locationIt, theme, props)
const state = DirectVolume.createRenderableState(props)
return createDirectVolumeRenderObject(values, state)
}