index.ts 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  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 './index.html'
  7. import Viewer from 'mol-view/viewer';
  8. import CIF, { CifBlock } from 'mol-io/reader/cif'
  9. import { parse as parseObj } from 'mol-io/reader/obj/parser'
  10. import { readUrlAs } from 'mol-util/read'
  11. import { Model, Format, Structure, StructureSymmetry } from 'mol-model/structure';
  12. import { CartoonRepresentation } from 'mol-geo/representation/structure/representation/cartoon';
  13. import { BallAndStickRepresentation } from 'mol-geo/representation/structure/representation/ball-and-stick';
  14. import { EveryLoci } from 'mol-model/loci';
  15. import { MarkerAction } from 'mol-geo/util/marker-data';
  16. import { labelFirst } from 'mol-view/label';
  17. import { Queries as Q, StructureProperties as SP, StructureSelection, StructureQuery } from 'mol-model/structure';
  18. import { MeshBuilder } from 'mol-geo/shape/mesh-builder';
  19. import { CustomRepresentation } from 'mol-geo/representation/custom';
  20. import { Vec3 } from 'mol-math/linear-algebra';
  21. const container = document.getElementById('container')
  22. if (!container) throw new Error('Can not find element with id "container".')
  23. const canvas = document.getElementById('canvas') as HTMLCanvasElement
  24. if (!canvas) throw new Error('Can not find element with id "canvas".')
  25. const info = document.getElementById('info') as HTMLCanvasElement
  26. if (!info) throw new Error('Can not find element with id "info".')
  27. const viewer = Viewer.create(canvas, container)
  28. viewer.animate()
  29. viewer.input.resize.subscribe(() => {
  30. // do whatever appropriate
  31. })
  32. viewer.input.move.subscribe(({x, y, inside, buttons}) => {
  33. if (!inside || buttons) return
  34. const p = viewer.identify(x, y)
  35. const loci = viewer.getLoci(p)
  36. viewer.mark(EveryLoci, MarkerAction.RemoveHighlight)
  37. viewer.mark(loci, MarkerAction.Highlight)
  38. const label = labelFirst(loci)
  39. info.innerText = `${label}`
  40. })
  41. async function getObjFromUrl(url: string) {
  42. const data = await readUrlAs(url, false) as string
  43. const comp = parseObj(data)
  44. const parsed = await comp.run()
  45. if (parsed.isError) throw parsed
  46. return parsed.result
  47. }
  48. async function getCifFromUrl(url: string) {
  49. const data = await readUrlAs(url, false)
  50. const comp = CIF.parse(data)
  51. const parsed = await comp.run()
  52. if (parsed.isError) throw parsed
  53. return parsed.result.blocks[0]
  54. }
  55. async function getModelFromMmcif(cif: CifBlock) {
  56. const models = await Model.create(Format.mmCIF(cif)).run()
  57. return models[0]
  58. }
  59. async function getStructureFromModel(model: Model, assembly = '1') {
  60. const assemblies = model.symmetry.assemblies
  61. if (assemblies.length) {
  62. return await StructureSymmetry.buildAssembly(Structure.ofModel(model), assembly).run()
  63. } else {
  64. return Structure.ofModel(model)
  65. }
  66. }
  67. async function init() {
  68. const cif = await getCifFromUrl('https://files.rcsb.org/download/1crn.cif')
  69. const model = await getModelFromMmcif(cif)
  70. const structure = await getStructureFromModel(model)
  71. viewer.center(structure.boundary.sphere.center)
  72. // cartoon for whole structure
  73. const cartoonRepr = CartoonRepresentation()
  74. await cartoonRepr.create(structure, {
  75. colorTheme: { name: 'chain-id' },
  76. sizeTheme: { name: 'uniform', value: 0.2 },
  77. useFog: false // TODO fog not working properly
  78. }).run()
  79. viewer.add(cartoonRepr)
  80. // create new structure via query
  81. const q1 = Q.generators.atoms({
  82. residueTest: qtx => SP.residue.label_seq_id(qtx.element) < 7
  83. });
  84. const newStructure = StructureSelection.unionStructure(await StructureQuery.run(q1, structure));
  85. // ball+stick for new structure
  86. const ballStickRepr = BallAndStickRepresentation()
  87. await ballStickRepr.create(newStructure, {
  88. colorTheme: { name: 'element-symbol' },
  89. sizeTheme: { name: 'uniform', value: 0.1 },
  90. useFog: false // TODO fog not working properly
  91. }).run()
  92. viewer.add(ballStickRepr)
  93. // create a custom mesh
  94. const meshBuilder = MeshBuilder.create(256, 128)
  95. meshBuilder.setId(0)
  96. meshBuilder.addSphere(Vec3.create(0, 0, 0), 4, 2)
  97. const mesh = meshBuilder.getMesh()
  98. // Mesh.computeNormalsImmediate(mesh)
  99. // mesh = getObjFromUrl('mesh.obj')
  100. // add representation from custom mesh
  101. const customRepr = CustomRepresentation()
  102. await customRepr.create(mesh, {
  103. useFog: false // TODO fog not working properly
  104. }).run()
  105. viewer.add(customRepr)
  106. // ensure the added representations get rendered, i.e. without mouse input
  107. viewer.requestDraw()
  108. }
  109. init()