polymer-direction-wedge.ts 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  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 { ParamDefinition as PD } from '../../../mol-util/param-definition';
  7. import { Mat4, Vec3 } from '../../../mol-math/linear-algebra';
  8. import { Wedge } from '../../../mol-geo/primitive/wedge';
  9. import { VisualContext } from '../../visual';
  10. import { Unit, Structure } from '../../../mol-model/structure';
  11. import { Theme } from '../../../mol-theme/theme';
  12. import { Mesh } from '../../../mol-geo/geometry/mesh/mesh';
  13. import { MeshBuilder } from '../../../mol-geo/geometry/mesh/mesh-builder';
  14. import { createCurveSegmentState, PolymerTraceIterator, interpolateCurveSegment, PolymerLocationIterator, getPolymerElementLoci, eachPolymerElement } from './util/polymer';
  15. import { isNucleic, SecondaryStructureType } from '../../../mol-model/structure/model/types';
  16. import { UnitsMeshParams, UnitsVisual, UnitsMeshVisual } from '../units-visual';
  17. import { VisualUpdateState } from '../../util';
  18. import { Sphere3D } from '../../../mol-math/geometry';
  19. const t = Mat4.identity()
  20. const sVec = Vec3.zero()
  21. const n0 = Vec3.zero()
  22. const n1 = Vec3.zero()
  23. const upVec = Vec3.zero()
  24. const depthFactor = 4
  25. const widthFactor = 4
  26. const heightFactor = 6
  27. const wedge = Wedge()
  28. export const PolymerDirectionWedgeParams = {
  29. sizeFactor: PD.Numeric(0.2, { min: 0, max: 10, step: 0.01 }),
  30. }
  31. export const DefaultPolymerDirectionWedgeProps = PD.getDefaultValues(PolymerDirectionWedgeParams)
  32. export type PolymerDirectionWedgeProps = typeof DefaultPolymerDirectionWedgeProps
  33. function createPolymerDirectionWedgeMesh(ctx: VisualContext, unit: Unit, structure: Structure, theme: Theme, props: PolymerDirectionWedgeProps, mesh?: Mesh) {
  34. const polymerElementCount = unit.polymerElements.length
  35. if (!polymerElementCount) return Mesh.createEmpty(mesh)
  36. const { sizeFactor } = props
  37. const vertexCount = polymerElementCount * 24
  38. const builderState = MeshBuilder.createState(vertexCount, vertexCount / 10, mesh)
  39. const linearSegments = 1
  40. const state = createCurveSegmentState(linearSegments)
  41. const { normalVectors, binormalVectors } = state
  42. let i = 0
  43. const polymerTraceIt = PolymerTraceIterator(unit, structure)
  44. while (polymerTraceIt.hasNext) {
  45. const v = polymerTraceIt.move()
  46. builderState.currentGroup = i
  47. const isNucleicType = isNucleic(v.moleculeType)
  48. const isSheet = SecondaryStructureType.is(v.secStrucType, SecondaryStructureType.Flag.Beta)
  49. const tension = (isNucleicType || isSheet) ? 0.5 : 0.9
  50. const shift = isNucleicType ? 0.3 : 0.5
  51. interpolateCurveSegment(state, v, tension, shift)
  52. if ((isSheet && !v.secStrucLast) || !isSheet) {
  53. const size = theme.size.size(v.center) * sizeFactor
  54. const depth = depthFactor * size
  55. const width = widthFactor * size
  56. const height = heightFactor * size
  57. const vectors = isNucleicType ? binormalVectors : normalVectors
  58. Vec3.fromArray(n0, vectors, 0)
  59. Vec3.fromArray(n1, vectors, 3)
  60. Vec3.normalize(upVec, Vec3.add(upVec, n0, n1))
  61. Mat4.targetTo(t, v.p3, v.p1, upVec)
  62. Mat4.mul(t, t, Mat4.rotY90Z180)
  63. Mat4.scale(t, t, Vec3.set(sVec, height, width, depth))
  64. Mat4.setTranslation(t, v.p2)
  65. MeshBuilder.addPrimitive(builderState, t, wedge)
  66. }
  67. ++i
  68. }
  69. const m = MeshBuilder.getMesh(builderState)
  70. const sphere = Sphere3D.expand(Sphere3D(), unit.boundary.sphere, 1 * props.sizeFactor)
  71. m.setBoundingSphere(sphere)
  72. return m
  73. }
  74. export const PolymerDirectionParams = {
  75. ...UnitsMeshParams,
  76. ...PolymerDirectionWedgeParams
  77. }
  78. export type PolymerDirectionParams = typeof PolymerDirectionParams
  79. export function PolymerDirectionVisual(materialId: number): UnitsVisual<PolymerDirectionParams> {
  80. return UnitsMeshVisual<PolymerDirectionParams>({
  81. defaultProps: PD.getDefaultValues(PolymerDirectionParams),
  82. createGeometry: createPolymerDirectionWedgeMesh,
  83. createLocationIterator: PolymerLocationIterator.fromGroup,
  84. getLoci: getPolymerElementLoci,
  85. eachLocation: eachPolymerElement,
  86. setUpdateState: (state: VisualUpdateState, newProps: PD.Values<PolymerDirectionParams>, currentProps: PD.Values<PolymerDirectionParams>) => {
  87. state.createGeometry = (
  88. newProps.sizeFactor !== currentProps.sizeFactor
  89. )
  90. }
  91. }, materialId)
  92. }