index.ts 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. /**
  2. * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  5. */
  6. import { ElementGroup, ElementSet, Structure, Unit } from 'mol-model/structure';
  7. import { EquivalenceClasses } from 'mol-data/util';
  8. import { OrderedSet } from 'mol-data/int'
  9. import { Task } from 'mol-task'
  10. import { RenderObject } from 'mol-gl/scene';
  11. export interface RepresentationProps {
  12. }
  13. export interface UnitsRepresentation<Props> {
  14. renderObjects: ReadonlyArray<RenderObject>,
  15. create: (units: ReadonlyArray<Unit>, elementGroup: ElementGroup, props: Props) => Task<void>,
  16. update: (props: RepresentationProps) => boolean,
  17. }
  18. export interface StructureRepresentation<Props> {
  19. renderObjects: ReadonlyArray<RenderObject>,
  20. create: (structure: Structure, props?: Props) => Task<void>,
  21. update: (elements: ElementSet, props: Props) => boolean
  22. }
  23. export function StructureRepresentation<Props>(reprCtor: () => UnitsRepresentation<Props>): StructureRepresentation<Props> {
  24. const renderObjects: RenderObject[] = []
  25. const unitReprs: UnitsRepresentation<Props>[] = []
  26. return {
  27. renderObjects,
  28. create(structure: Structure, props: Props = {} as Props) {
  29. return Task.create('StructureRepresentation', async ctx => {
  30. const { elements, units } = structure;
  31. const uniqueGroups = EquivalenceClasses<number, { unit: Unit, group: ElementGroup }>(
  32. ({ unit, group }) => ElementGroup.hashCode(group),
  33. (a, b) => a.unit.model.id === b.unit.model.id && OrderedSet.areEqual(a.group.elements, b.group.elements)
  34. );
  35. const unitIndices = ElementSet.unitIndices(elements);
  36. for (let i = 0, _i = unitIndices.length; i < _i; i++) {
  37. const unitIndex = unitIndices[i];
  38. const group = ElementSet.groupFromUnitIndex(elements, unitIndex);
  39. uniqueGroups.add(unitIndex, { unit: units[unitIndex], group });
  40. }
  41. for (let i = 0, _i = uniqueGroups.groups.length; i < _i; i++) {
  42. const groupUnits: Unit[] = []
  43. const group = uniqueGroups.groups[i]
  44. // console.log('group', i)
  45. for (let j = 0, _j = group.length; j < _j; j++) {
  46. groupUnits.push(units[group[j]])
  47. }
  48. const elementGroup = ElementSet.groupFromUnitIndex(elements, group[0])
  49. const repr = reprCtor()
  50. unitReprs.push(repr)
  51. await ctx.update({ message: 'Building units...', current: i, max: _i });
  52. await ctx.runChild(repr.create(groupUnits, elementGroup, props));
  53. renderObjects.push(...repr.renderObjects)
  54. }
  55. });
  56. },
  57. update(elements: ElementSet, props: RepresentationProps) {
  58. // TODO check model.id, conformation.id, unit.id, elementGroup(.hashCode/.areEqual)
  59. return false
  60. }
  61. }
  62. }