/** * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose * @author David Sehnal */ import { Structure, StructureSymmetry, Unit } from 'mol-model/structure'; import { Task } from 'mol-task' import { RenderObject } from 'mol-gl/render-object'; import { Representation, RepresentationProps } from '..'; import { ColorTheme } from '../../theme'; import { PickingId } from '../../util/picking'; import { Loci } from 'mol-model/loci'; export interface UnitsRepresentation

{ renderObjects: ReadonlyArray create: (group: Unit.SymmetryGroup, props: P) => Task update: (props: P) => Task getLoci: (pickingId: PickingId) => Loci | null } export interface StructureRepresentation

extends Representation { renderObjects: ReadonlyArray create: (structure: Structure, props?: P) => Task update: (props: P) => Task getLoci: (pickingId: PickingId) => Loci | null } interface GroupRepresentation { repr: UnitsRepresentation group: Unit.SymmetryGroup } export const DefaultStructureProps = { colorTheme: { name: 'instance-index' } as ColorTheme, alpha: 1, visible: true, doubleSided: false, depthMask: true, hoverSelection: { objectId: -1, instanceId: -1, elementId: -1 } as PickingId } export type StructureProps = Partial export function StructureRepresentation

(reprCtor: () => UnitsRepresentation

): StructureRepresentation

{ const renderObjects: RenderObject[] = [] const groupReprs: GroupRepresentation

[] = [] // let currentProps: typeof DefaultStructureProps function getLoci(pickingId: PickingId) { for (let i = 0, il = groupReprs.length; i < il; ++i) { const loc = groupReprs[i].repr.getLoci(pickingId) if (loc) return loc } return null } return { renderObjects, create(structure: Structure, props: P = {} as P) { // currentProps = Object.assign({}, DefaultStructureProps, props) return Task.create('StructureRepresentation.create', async ctx => { // const { query } = currentProps // const qs = await query(structure).runAsChild(ctx) // const subStructure = Selection.unionStructure(qs) const groups = StructureSymmetry.getTransformGroups(structure); for (let i = 0; i < groups.length; i++) { const group = groups[i]; const repr = reprCtor() groupReprs.push({ repr, group }) await repr.create(group, props).runAsChild(ctx, { message: 'Building structure unit representations...', current: i, max: groups.length }); renderObjects.push(...repr.renderObjects) } }); }, update(props: P) { return Task.create('StructureRepresentation.update', async ctx => { renderObjects.length = 0 // clear for (let i = 0, il = groupReprs.length; i < il; ++i) { const groupRepr = groupReprs[i] const { repr, group } = groupRepr const state = { message: 'Updating structure unit representations...', current: i, max: il }; if (!await repr.update(props).runAsChild(ctx, state)) { console.log('update failed, need to rebuild') await repr.create(group, props).runAsChild(ctx, state) } renderObjects.push(...repr.renderObjects) } }) }, getLoci } }