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. }