common.ts 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  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. * @author David Sehnal <david.sehnal@gmail.com>
  6. */
  7. import { Unit, Structure } from 'mol-model/structure';
  8. import { createUniformColor, ColorData, createGroupColor, createGroupInstanceColor, createInstanceColor, ColorType } from '../../../../util/color-data';
  9. import { createUniformSize, SizeData, createGroupSize, createGroupInstanceSize, createInstanceSize, SizeType } from '../../../../util/size-data';
  10. import { LocationIterator } from '../../../../util/location-iterator';
  11. import { Mesh } from '../../../../geometry/mesh/mesh';
  12. import { MeshValues, PointValues } from 'mol-gl/renderable';
  13. import { getMeshData } from '../../../../util/mesh-data';
  14. import { StructureProps } from '../..';
  15. import { createMarkers } from '../../../../util/marker-data';
  16. import { createMeshRenderObject, createPointRenderObject } from 'mol-gl/render-object';
  17. import { ColorThemeProps, ColorTheme } from 'mol-view/theme/color';
  18. import { SizeThemeProps, SizeTheme } from 'mol-view/theme/size';
  19. import { RuntimeContext } from 'mol-task';
  20. import { PointProps } from 'mol-geo/representation/structure/representation/point';
  21. import { TransformData, createIdentityTransform, createTransforms } from '../../../../util/transform-data';
  22. import { Point } from '../../../../geometry/point/point';
  23. import { getPointData } from '../../../../util/point-data';
  24. import { MeshProps, createMeshValues, createRenderableState, createPointValues } from '../../../../geometry/geometry';
  25. function getGranularity(locationIt: LocationIterator, granularity: ColorType | SizeType) {
  26. // Always use 'group' granularity for 'complex' location iterators,
  27. // i.e. for which an instance may include multiple units
  28. return granularity === 'instance' && locationIt.isComplex ? 'group' : granularity
  29. }
  30. export function createColors(ctx: RuntimeContext, locationIt: LocationIterator, props: ColorThemeProps, colorData?: ColorData): Promise<ColorData> {
  31. const colorTheme = ColorTheme(props)
  32. switch (getGranularity(locationIt, colorTheme.granularity)) {
  33. case 'uniform': return createUniformColor(ctx, locationIt, colorTheme.color, colorData)
  34. case 'group': return createGroupColor(ctx, locationIt, colorTheme.color, colorData)
  35. case 'groupInstance': return createGroupInstanceColor(ctx, locationIt, colorTheme.color, colorData)
  36. case 'instance': return createInstanceColor(ctx, locationIt, colorTheme.color, colorData)
  37. }
  38. }
  39. export async function createSizes(ctx: RuntimeContext, locationIt: LocationIterator, props: SizeThemeProps, sizeData?: SizeData): Promise<SizeData> {
  40. const sizeTheme = SizeTheme(props)
  41. switch (getGranularity(locationIt, sizeTheme.granularity)) {
  42. case 'uniform': return createUniformSize(ctx, locationIt, sizeTheme.size, sizeData)
  43. case 'group': return createGroupSize(ctx, locationIt, sizeTheme.size, sizeData)
  44. case 'groupInstance': return createGroupInstanceSize(ctx, locationIt, sizeTheme.size, sizeData)
  45. case 'instance': return createInstanceSize(ctx, locationIt, sizeTheme.size, sizeData)
  46. }
  47. }
  48. // mesh
  49. type StructureMeshProps = MeshProps & StructureProps
  50. async function _createMeshValues(ctx: RuntimeContext, transforms: TransformData, mesh: Mesh, locationIt: LocationIterator, props: StructureMeshProps): Promise<MeshValues> {
  51. const { instanceCount, groupCount } = locationIt
  52. const color = await createColors(ctx, locationIt, props.colorTheme)
  53. const marker = createMarkers(instanceCount * groupCount)
  54. const counts = { drawCount: mesh.triangleCount * 3, groupCount, instanceCount }
  55. return {
  56. ...getMeshData(mesh),
  57. ...color,
  58. ...marker,
  59. ...transforms,
  60. elements: mesh.indexBuffer,
  61. ...createMeshValues(props, counts)
  62. }
  63. }
  64. export async function createComplexMeshValues(ctx: RuntimeContext, structure: Structure, mesh: Mesh, locationIt: LocationIterator, props: StructureMeshProps): Promise<MeshValues> {
  65. const transforms = createIdentityTransform()
  66. return _createMeshValues(ctx, transforms, mesh, locationIt, props)
  67. }
  68. export async function createUnitsMeshValues(ctx: RuntimeContext, group: Unit.SymmetryGroup, mesh: Mesh, locationIt: LocationIterator, props: StructureMeshProps): Promise<MeshValues> {
  69. const transforms = createTransforms(group)
  70. return _createMeshValues(ctx, transforms, mesh, locationIt, props)
  71. }
  72. export async function createComplexMeshRenderObject(ctx: RuntimeContext, structure: Structure, mesh: Mesh, locationIt: LocationIterator, props: StructureMeshProps) {
  73. const values = await createComplexMeshValues(ctx, structure, mesh, locationIt, props)
  74. const state = createRenderableState(props)
  75. return createMeshRenderObject(values, state)
  76. }
  77. export async function createUnitsMeshRenderObject(ctx: RuntimeContext, group: Unit.SymmetryGroup, mesh: Mesh, locationIt: LocationIterator, props: StructureMeshProps) {
  78. const values = await createUnitsMeshValues(ctx, group, mesh, locationIt, props)
  79. const state = createRenderableState(props)
  80. return createMeshRenderObject(values, state)
  81. }
  82. export async function updateComplexMeshRenderObject(ctx: RuntimeContext, structure: Structure, mesh: Mesh, locationIt: LocationIterator, props: StructureMeshProps): Promise<MeshValues> {
  83. const transforms = createIdentityTransform()
  84. return _createMeshValues(ctx, transforms, mesh, locationIt, props)
  85. }
  86. // point
  87. type StructurePointProps = PointProps & StructureProps
  88. async function _createPointValues(ctx: RuntimeContext, transforms: TransformData, point: Point, locationIt: LocationIterator, props: StructurePointProps): Promise<PointValues> {
  89. const { instanceCount, groupCount } = locationIt
  90. const color = await createColors(ctx, locationIt, props.colorTheme)
  91. const size = await createSizes(ctx, locationIt, props.sizeTheme)
  92. const marker = createMarkers(instanceCount * groupCount)
  93. const counts = { drawCount: point.vertexCount, groupCount, instanceCount }
  94. return {
  95. ...getPointData(point),
  96. ...color,
  97. ...size,
  98. ...marker,
  99. ...transforms,
  100. ...createPointValues(props, counts)
  101. }
  102. }
  103. export async function createUnitsPointValues(ctx: RuntimeContext, group: Unit.SymmetryGroup, point: Point, locationIt: LocationIterator, props: StructurePointProps): Promise<PointValues> {
  104. const transforms = createTransforms(group)
  105. return _createPointValues(ctx, transforms, point, locationIt, props)
  106. }
  107. export async function createUnitsPointRenderObject(ctx: RuntimeContext, group: Unit.SymmetryGroup, point: Point, locationIt: LocationIterator, props: StructurePointProps) {
  108. const values = await createUnitsPointValues(ctx, group, point, locationIt, props)
  109. const state = createRenderableState(props)
  110. return createPointRenderObject(values, state)
  111. }