polymer-direction-wedge.ts 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  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 { Unit } from 'mol-model/structure';
  7. import { UnitsVisual } from '..';
  8. import { RuntimeContext } from 'mol-task'
  9. import { markElement, getElementLoci } from './util/element';
  10. import { Mesh } from '../../../shape/mesh';
  11. import { MeshBuilder } from '../../../shape/mesh-builder';
  12. import { getPolymerElementCount, PolymerTraceIterator, createCurveSegmentState, interpolateCurveSegment } from './util/polymer';
  13. import { Vec3, Mat4 } from 'mol-math/linear-algebra';
  14. import { SecondaryStructureType, MoleculeType } from 'mol-model/structure/model/types';
  15. import { StructureElementIterator } from './util/location-iterator';
  16. import { DefaultUnitsMeshProps, UnitsMeshVisual } from '../units-visual';
  17. const t = Mat4.identity()
  18. const sVec = Vec3.zero()
  19. const n0 = Vec3.zero()
  20. const n1 = Vec3.zero()
  21. const upVec = Vec3.zero()
  22. async function createPolymerDirectionWedgeMesh(ctx: RuntimeContext, unit: Unit, props: {}, mesh?: Mesh) {
  23. const polymerElementCount = getPolymerElementCount(unit)
  24. console.log('polymerElementCount direction', polymerElementCount)
  25. if (!polymerElementCount) return Mesh.createEmpty(mesh)
  26. // TODO better vertex count estimates
  27. const builder = MeshBuilder.create(polymerElementCount * 30, polymerElementCount * 30 / 2, mesh)
  28. const linearSegments = 1
  29. const state = createCurveSegmentState(linearSegments)
  30. const { normalVectors, binormalVectors } = state
  31. let i = 0
  32. const polymerTraceIt = PolymerTraceIterator(unit)
  33. while (polymerTraceIt.hasNext) {
  34. const v = polymerTraceIt.move()
  35. builder.setId(v.center.element)
  36. const isNucleic = v.moleculeType === MoleculeType.DNA || v.moleculeType === MoleculeType.RNA
  37. const isSheet = SecondaryStructureType.is(v.secStrucType, SecondaryStructureType.Flag.Beta)
  38. const tension = (isNucleic || isSheet) ? 0.5 : 0.9
  39. interpolateCurveSegment(state, v, tension)
  40. if ((isSheet && !v.secStrucChange) || !isSheet) {
  41. let width = 0.5, height = 1.2, depth = 0.6
  42. if (isNucleic) {
  43. Vec3.fromArray(n0, binormalVectors, 0)
  44. Vec3.fromArray(n1, binormalVectors, 3)
  45. Vec3.normalize(upVec, Vec3.add(upVec, n0, n1))
  46. depth = 0.9
  47. } else {
  48. Vec3.fromArray(n0, normalVectors, 0)
  49. Vec3.fromArray(n1, normalVectors, 3)
  50. Vec3.normalize(upVec, Vec3.add(upVec, n0, n1))
  51. }
  52. Mat4.targetTo(t, v.p3, v.p1, upVec)
  53. Mat4.mul(t, t, Mat4.rotY90Z180)
  54. Mat4.scale(t, t, Vec3.set(sVec, height, width, depth))
  55. Mat4.setTranslation(t, v.p2)
  56. builder.addWedge(t)
  57. }
  58. if (i % 10000 === 0 && ctx.shouldUpdate) {
  59. await ctx.update({ message: 'Polymer direction mesh', current: i, max: polymerElementCount });
  60. }
  61. ++i
  62. }
  63. return builder.getMesh()
  64. }
  65. export const DefaultPolymerDirectionProps = {
  66. ...DefaultUnitsMeshProps
  67. }
  68. export type PolymerDirectionProps = typeof DefaultPolymerDirectionProps
  69. export function PolymerDirectionVisual(): UnitsVisual<PolymerDirectionProps> {
  70. return UnitsMeshVisual<PolymerDirectionProps>({
  71. defaultProps: DefaultPolymerDirectionProps,
  72. createMesh: createPolymerDirectionWedgeMesh,
  73. createLocationIterator: StructureElementIterator.fromGroup,
  74. getLoci: getElementLoci,
  75. mark: markElement,
  76. setUpdateState: () => {}
  77. })
  78. }