util.ts 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  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 { defaults } from '../mol-util';
  7. import { Structure } from '../mol-model/structure';
  8. import { VisualQuality } from '../mol-geo/geometry/base';
  9. export interface VisualUpdateState {
  10. updateTransform: boolean
  11. updateMatrix: boolean
  12. updateColor: boolean
  13. updateSize: boolean
  14. createGeometry: boolean
  15. createNew: boolean
  16. /** holds contextual info, is not reset */
  17. info: { [k: string]: unknown }
  18. }
  19. export namespace VisualUpdateState {
  20. export function create(): VisualUpdateState {
  21. return {
  22. updateTransform: false,
  23. updateMatrix: false,
  24. updateColor: false,
  25. updateSize: false,
  26. createGeometry: false,
  27. createNew: false,
  28. info: {}
  29. };
  30. }
  31. export function reset(state: VisualUpdateState) {
  32. state.updateTransform = false;
  33. state.updateMatrix = false;
  34. state.updateColor = false;
  35. state.updateSize = false;
  36. state.createGeometry = false;
  37. state.createNew = false;
  38. }
  39. }
  40. //
  41. export interface QualityProps {
  42. quality: VisualQuality
  43. detail: number
  44. radialSegments: number
  45. linearSegments: number
  46. resolution: number
  47. doubleSided: boolean
  48. alpha: number
  49. }
  50. export const DefaultQualityThresholds = {
  51. lowestElementCount: 500_000,
  52. lowerElementCount: 200_000,
  53. lowElementCount: 60_000,
  54. mediumElementCount: 20_000,
  55. highElementCount: 2_000,
  56. coarseGrainedFactor: 10,
  57. elementCountFactor: 1
  58. };
  59. export type QualityThresholds = typeof DefaultQualityThresholds
  60. export function getStructureQuality(structure: Structure, tresholds: Partial<QualityThresholds> = {}): VisualQuality {
  61. const t = { ...DefaultQualityThresholds, ...tresholds };
  62. let score = structure.elementCount * t.elementCountFactor;
  63. if (structure.isCoarseGrained) score *= t.coarseGrainedFactor;
  64. if (score > t.lowestElementCount) {
  65. return 'lowest';
  66. } else if (score > t.lowerElementCount) {
  67. return 'lower';
  68. } else if (score > t.lowElementCount) {
  69. return 'low';
  70. } else if (score > t.mediumElementCount) {
  71. return 'medium';
  72. } else if (score > t.highElementCount) {
  73. return 'high';
  74. } else {
  75. return 'higher';
  76. }
  77. }
  78. export function getQualityProps(props: Partial<QualityProps>, data?: any) {
  79. let quality = defaults(props.quality, 'auto' as VisualQuality);
  80. let detail = defaults(props.detail, 1);
  81. let radialSegments = defaults(props.radialSegments, 12);
  82. let linearSegments = defaults(props.linearSegments, 8);
  83. let resolution = defaults(props.resolution, 2);
  84. let doubleSided = defaults(props.doubleSided, true);
  85. if (quality === 'auto' && data instanceof Structure) {
  86. quality = getStructureQuality(data.root);
  87. }
  88. switch (quality) {
  89. case 'highest':
  90. detail = 3;
  91. radialSegments = 36;
  92. linearSegments = 18;
  93. resolution = 0.1;
  94. doubleSided = true;
  95. break;
  96. case 'higher':
  97. detail = 3;
  98. radialSegments = 28;
  99. linearSegments = 14;
  100. resolution = 0.3;
  101. doubleSided = true;
  102. break;
  103. case 'high':
  104. detail = 2;
  105. radialSegments = 20;
  106. linearSegments = 10;
  107. resolution = 0.5;
  108. doubleSided = true;
  109. break;
  110. case 'medium':
  111. detail = 1;
  112. radialSegments = 12;
  113. linearSegments = 8;
  114. resolution = 1;
  115. doubleSided = true;
  116. break;
  117. case 'low':
  118. detail = 0;
  119. radialSegments = 8;
  120. linearSegments = 3;
  121. resolution = 2;
  122. doubleSided = false;
  123. break;
  124. case 'lower':
  125. detail = 0;
  126. radialSegments = 4;
  127. linearSegments = 2;
  128. resolution = 4;
  129. doubleSided = false;
  130. break;
  131. case 'lowest':
  132. detail = 0;
  133. radialSegments = 2;
  134. linearSegments = 1;
  135. resolution = 8;
  136. doubleSided = false;
  137. break;
  138. case 'custom':
  139. // use defaults or given props as set above
  140. break;
  141. }
  142. if (props.alpha !== undefined && props.alpha < 1) {
  143. doubleSided = false;
  144. }
  145. return {
  146. detail,
  147. radialSegments,
  148. linearSegments,
  149. resolution,
  150. doubleSided
  151. };
  152. }