element-point.ts 3.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. /**
  2. * Copyright (c) 2018-2022 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 { UnitsPointsParams, UnitsVisual, UnitsPointsVisual } from '../units-visual';
  8. import { VisualContext } from '../../visual';
  9. import { Unit, Structure } from '../../../mol-model/structure';
  10. import { Theme } from '../../../mol-theme/theme';
  11. import { Points } from '../../../mol-geo/geometry/points/points';
  12. import { PointsBuilder } from '../../../mol-geo/geometry/points/points-builder';
  13. import { Vec3 } from '../../../mol-math/linear-algebra';
  14. import { ElementIterator, getElementLoci, eachElement, makeElementIgnoreTest } from './util/element';
  15. import { VisualUpdateState } from '../../util';
  16. import { Sphere3D } from '../../../mol-math/geometry';
  17. // avoiding namespace lookup improved performance in Chrome (Aug 2020)
  18. const v3add = Vec3.add;
  19. export const ElementPointParams = {
  20. ...UnitsPointsParams,
  21. pointSizeAttenuation: PD.Boolean(false),
  22. ignoreHydrogens: PD.Boolean(false),
  23. onlyPolarHydrogens: PD.Boolean(false),
  24. traceOnly: PD.Boolean(false),
  25. };
  26. export type ElementPointParams = typeof ElementPointParams
  27. // TODO size
  28. export function createElementPoint(ctx: VisualContext, unit: Unit, structure: Structure, theme: Theme, props: PD.Values<ElementPointParams>, points: Points) {
  29. // TODO sizeFactor
  30. const { child } = structure;
  31. if (child && !child.unitMap.get(unit.id)) return Points.createEmpty(points);
  32. const elements = unit.elements;
  33. const n = elements.length;
  34. const builder = PointsBuilder.create(n, n / 10, points);
  35. const p = Vec3();
  36. const pos = unit.conformation.invariantPosition;
  37. const ignore = makeElementIgnoreTest(structure, unit, props);
  38. const center = Vec3();
  39. let count = 0;
  40. if (ignore) {
  41. for (let i = 0; i < n; ++i) {
  42. if (ignore(elements[i])) continue;
  43. pos(elements[i], p);
  44. v3add(center, center, p);
  45. count += 1;
  46. builder.add(p[0], p[1], p[2], i);
  47. }
  48. } else {
  49. for (let i = 0; i < n; ++i) {
  50. pos(elements[i], p);
  51. v3add(center, center, p);
  52. count += 1;
  53. builder.add(p[0], p[1], p[2], i);
  54. }
  55. }
  56. const oldBoundingSphere = points ? Sphere3D.clone(points.boundingSphere) : undefined;
  57. const pt = builder.getPoints();
  58. if (count === 0) return pt;
  59. // re-use boundingSphere if it has not changed much
  60. let boundingSphere: Sphere3D;
  61. Vec3.scale(center, center, 1 / count);
  62. if (oldBoundingSphere && Vec3.distance(center, oldBoundingSphere.center) / oldBoundingSphere.radius < 1.0) {
  63. boundingSphere = oldBoundingSphere;
  64. } else {
  65. boundingSphere = Sphere3D.expand(Sphere3D(), unit.boundary.sphere, 1 * props.sizeFactor);
  66. }
  67. pt.setBoundingSphere(boundingSphere);
  68. return pt;
  69. }
  70. export function ElementPointVisual(materialId: number): UnitsVisual<ElementPointParams> {
  71. return UnitsPointsVisual<ElementPointParams>({
  72. defaultProps: PD.getDefaultValues(ElementPointParams),
  73. createGeometry: createElementPoint,
  74. createLocationIterator: ElementIterator.fromGroup,
  75. getLoci: getElementLoci,
  76. eachLocation: eachElement,
  77. setUpdateState: (state: VisualUpdateState, newProps: PD.Values<ElementPointParams>, currentProps: PD.Values<ElementPointParams>) => {
  78. state.createGeometry = (
  79. newProps.ignoreHydrogens !== currentProps.ignoreHydrogens ||
  80. newProps.onlyPolarHydrogens !== currentProps.onlyPolarHydrogens ||
  81. newProps.traceOnly !== currentProps.traceOnly
  82. );
  83. }
  84. }, materialId);
  85. }