index.ts 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /**
  2. * Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  5. */
  6. import { createPlugin, DefaultPluginSpec } from '../../../mol-plugin';
  7. import './index.html'
  8. import { PluginContext } from '../../../mol-plugin/context';
  9. import { PluginCommands } from '../../../mol-plugin/commands';
  10. import { StateTransforms } from '../../../mol-plugin-state/transforms';
  11. import { PluginStateObject as PSO } from '../../../mol-plugin-state/objects';
  12. import { StateBuilder } from '../../../mol-state';
  13. import { Canvas3DProps } from '../../../mol-canvas3d/canvas3d';
  14. import { createStructureRepresentationParams } from '../../../mol-plugin-state/helpers/structure-representation-params';
  15. require('mol-plugin-ui/skin/light.scss')
  16. type SupportedFormats = 'cif' | 'pdb'
  17. type LoadParams = { url: string, format?: SupportedFormats, assemblyId?: string }
  18. const Canvas3DPresets = {
  19. illustrative: {
  20. multiSample: {
  21. mode: 'temporal' as Canvas3DProps['multiSample']['mode']
  22. },
  23. postprocessing: {
  24. occlusionEnable: true,
  25. occlusionBias: 0.8,
  26. occlusionKernelSize: 6,
  27. outlineEnable: true,
  28. },
  29. renderer: {
  30. ambientIntensity: 1,
  31. lightIntensity: 0,
  32. }
  33. },
  34. occlusion: {
  35. multiSample: {
  36. mode: 'temporal' as Canvas3DProps['multiSample']['mode']
  37. },
  38. postprocessing: {
  39. occlusionEnable: true,
  40. occlusionBias: 0.8,
  41. occlusionKernelSize: 6,
  42. outlineEnable: false,
  43. },
  44. renderer: {
  45. ambientIntensity: 0.4,
  46. lightIntensity: 0.6,
  47. }
  48. },
  49. standard: {
  50. multiSample: {
  51. mode: 'off' as Canvas3DProps['multiSample']['mode']
  52. },
  53. postprocessing: {
  54. occlusionEnable: false,
  55. outlineEnable: false,
  56. },
  57. renderer: {
  58. ambientIntensity: 0.4,
  59. lightIntensity: 0.6,
  60. }
  61. }
  62. }
  63. type Canvas3DPreset = keyof typeof Canvas3DPresets
  64. function getPreset(preset: Canvas3DPreset) {
  65. switch (preset) {
  66. case 'illustrative': return Canvas3DPresets['illustrative']
  67. case 'standard': return Canvas3DPresets['standard']
  68. case 'occlusion': return Canvas3DPresets['occlusion']
  69. }
  70. }
  71. class LightingDemo {
  72. plugin: PluginContext;
  73. init(target: string | HTMLElement) {
  74. this.plugin = createPlugin(typeof target === 'string' ? document.getElementById(target)! : target, {
  75. ...DefaultPluginSpec,
  76. layout: {
  77. initial: {
  78. isExpanded: false,
  79. showControls: false
  80. },
  81. controls: { left: 'none', right: 'none', top: 'none', bottom: 'none' }
  82. }
  83. });
  84. this.setPreset('illustrative');
  85. }
  86. setPreset(preset: Canvas3DPreset) {
  87. const props = getPreset(preset)
  88. PluginCommands.Canvas3D.SetSettings(this.plugin, { settings: {
  89. ...props,
  90. multiSample: {
  91. ...this.plugin.canvas3d!.props.multiSample,
  92. ...props.multiSample
  93. },
  94. renderer: {
  95. ...this.plugin.canvas3d!.props.renderer,
  96. ...props.renderer
  97. },
  98. postprocessing: {
  99. ...this.plugin.canvas3d!.props.postprocessing,
  100. ...props.postprocessing
  101. },
  102. }});
  103. }
  104. private download(b: StateBuilder.To<PSO.Root>, url: string) {
  105. return b.apply(StateTransforms.Data.Download, { url, isBinary: false })
  106. }
  107. private parse(b: StateBuilder.To<PSO.Data.Binary | PSO.Data.String>, format: SupportedFormats, assemblyId: string) {
  108. const parsed = format === 'cif'
  109. ? b.apply(StateTransforms.Data.ParseCif).apply(StateTransforms.Model.TrajectoryFromMmCif)
  110. : b.apply(StateTransforms.Model.TrajectoryFromPDB);
  111. const props = {
  112. type: {
  113. name: 'assembly' as const,
  114. params: { id: assemblyId || 'deposited' }
  115. }
  116. }
  117. return parsed
  118. .apply(StateTransforms.Model.ModelFromTrajectory, { modelIndex: 0 })
  119. .apply(StateTransforms.Model.StructureFromModel, props, { ref: 'asm' });
  120. }
  121. private visual(visualRoot: StateBuilder.To<PSO.Molecule.Structure>) {
  122. visualRoot.apply(StateTransforms.Model.StructureComplexElement, { type: 'atomic-sequence' })
  123. .apply(StateTransforms.Representation.StructureRepresentation3D,
  124. createStructureRepresentationParams(this.plugin, void 0, { type: 'spacefill', color: 'illustrative' }), { ref: 'seq-visual' });
  125. visualRoot.apply(StateTransforms.Model.StructureComplexElement, { type: 'atomic-het' })
  126. .apply(StateTransforms.Representation.StructureRepresentation3D,
  127. createStructureRepresentationParams(this.plugin, void 0, { type: 'ball-and-stick' }), { ref: 'het-visual' });
  128. return visualRoot;
  129. }
  130. private loadedParams: LoadParams = { url: '', format: 'cif', assemblyId: '' };
  131. async load({ url, format = 'cif', assemblyId = '' }: LoadParams) {
  132. let loadType: 'full' | 'update' = 'full';
  133. const state = this.plugin.state.data;
  134. if (this.loadedParams.url !== url || this.loadedParams.format !== format) {
  135. loadType = 'full';
  136. } else if (this.loadedParams.url === url) {
  137. if (state.select('asm').length > 0) loadType = 'update';
  138. }
  139. let tree: StateBuilder.Root;
  140. if (loadType === 'full') {
  141. await PluginCommands.State.RemoveObject(this.plugin, { state, ref: state.tree.root.ref });
  142. tree = state.build();
  143. this.visual(this.parse(this.download(tree.toRoot(), url), format, assemblyId));
  144. } else {
  145. const props = {
  146. type: {
  147. name: 'assembly' as const,
  148. params: { id: assemblyId || 'deposited' }
  149. }
  150. }
  151. tree = state.build();
  152. tree.to('asm').update(StateTransforms.Model.StructureFromModel, p => ({ ...p, ...props }));
  153. }
  154. await PluginCommands.State.Update(this.plugin, { state: this.plugin.state.data, tree });
  155. this.loadedParams = { url, format, assemblyId };
  156. PluginCommands.Camera.Reset(this.plugin, { });
  157. }
  158. }
  159. (window as any).LightingDemo = new LightingDemo();