Browse Source

wip, added canvas app

Alexander Rose 6 years ago
parent
commit
7d16daacdf

+ 2 - 0
package.json

@@ -19,6 +19,8 @@
     "test": "jest",
     "build-viewer": "webpack build/node_modules/apps/viewer/index.js --mode development -o build/viewer/index.js",
     "watch-viewer": "webpack build/node_modules/apps/viewer/index.js -w --mode development -o build/viewer/index.js",
+    "build-canvas": "webpack build/node_modules/apps/canvas/index.js --mode development -o build/canvas/index.js",
+    "watch-canvas": "webpack build/node_modules/apps/canvas/index.js -w --mode development -o build/canvas/index.js",
     "model-server": "node build/node_modules/servers/model/server.js",
     "model-server-watch": "nodemon --watch build/node_modules build/node_modules/servers/model/server.js"
   },

+ 15 - 0
src/apps/canvas/index.html

@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html lang="en">
+    <head>
+        <meta charset="utf-8" />
+        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
+        <title>Mol* Canvas</title>
+    </head>
+    <body>
+        <div id="container" style="width:800px; height: 600px;">
+            <canvas id="canvas"></canvas>
+        </div>
+        <span id="info"></span>
+        <script type="text/javascript" src="./index.js"></script>
+    </body>
+</html>

+ 122 - 0
src/apps/canvas/index.ts

@@ -0,0 +1,122 @@
+/**
+ * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ */
+
+import './index.html'
+
+import Viewer from 'mol-view/viewer';
+import CIF, { CifBlock } from 'mol-io/reader/cif'
+import { readUrlAs } from 'mol-util/read'
+import { Model, Format, Structure, StructureSymmetry } from 'mol-model/structure';
+import { CartoonRepresentation } from 'mol-geo/representation/structure/representation/cartoon';
+import { BallAndStickRepresentation } from 'mol-geo/representation/structure/representation/ball-and-stick';
+import { EveryLoci } from 'mol-model/loci';
+import { MarkerAction } from 'mol-geo/util/marker-data';
+import { labelFirst } from 'mol-view/label';
+import { Queries as Q, StructureProperties as SP, StructureSelection, StructureQuery } from 'mol-model/structure';
+import { MeshBuilder } from 'mol-geo/shape/mesh-builder';
+import { CustomRepresentation } from 'mol-geo/representation/custom';
+import { Vec3 } from 'mol-math/linear-algebra';
+
+const container = document.getElementById('container')
+if (!container) throw new Error('Can not find element with id "container".')
+
+const canvas = document.getElementById('canvas') as HTMLCanvasElement
+if (!canvas) throw new Error('Can not find element with id "canvas".')
+
+const info = document.getElementById('info') as HTMLCanvasElement
+if (!info) throw new Error('Can not find element with id "info".')
+
+const viewer = Viewer.create(canvas, container)
+viewer.animate()
+
+viewer.input.resize.subscribe(() => {
+    // do whatever appropriate
+})
+
+viewer.input.move.subscribe(({x, y, inside, buttons}) => {
+    if (!inside || buttons) return
+    const p = viewer.identify(x, y)
+    const loci = viewer.getLoci(p)
+
+    viewer.mark(EveryLoci, MarkerAction.RemoveHighlight)
+    viewer.mark(loci, MarkerAction.Highlight)
+
+    const label = labelFirst(loci)
+    info.innerText = `${label}`
+})
+
+async function getCifFromUrl(url: string) {
+    const data = await readUrlAs(url, false)
+    const comp = CIF.parse(data)
+    const parsed = await comp.run()
+    if (parsed.isError) throw parsed
+    return parsed.result.blocks[0]
+}
+
+async function getModelFromMmcif(cif: CifBlock) {
+    const models = await Model.create(Format.mmCIF(cif)).run()
+    return models[0]
+}
+
+async function getStructureFromModel(model: Model, assembly = '1') {
+    const assemblies = model.symmetry.assemblies
+    if (assemblies.length) {
+        return await StructureSymmetry.buildAssembly(Structure.ofModel(model), assembly).run()
+    } else {
+        return Structure.ofModel(model)
+    }
+}
+
+async function init() {
+    const cif = await getCifFromUrl('https://files.rcsb.org/download/1crn.cif')
+    const model = await getModelFromMmcif(cif)
+    const structure = await getStructureFromModel(model)
+
+    viewer.center(structure.boundary.sphere.center)
+
+    // cartoon for whole structure
+    const cartoonRepr = CartoonRepresentation()
+    await cartoonRepr.create(structure, {
+        colorTheme: { name: 'chain-id' },
+        sizeTheme: { name: 'uniform', value: 0.2 },
+        useFog: false // TODO fog not working properly
+    }).run()
+    viewer.add(cartoonRepr)
+
+    // create new structure via query
+    const q1 = Q.generators.atoms({
+        residueTest: qtx => SP.residue.label_seq_id(qtx.element) < 7
+    });
+    const newStructure = StructureSelection.unionStructure(await StructureQuery.run(q1, structure));
+
+    // ball+stick for new structure
+    const ballStickRepr = BallAndStickRepresentation()
+    await ballStickRepr.create(newStructure, {
+        colorTheme: { name: 'element-symbol' },
+        sizeTheme: { name: 'uniform', value: 0.1 },
+        useFog: false // TODO fog not working properly
+    }).run()
+    viewer.add(ballStickRepr)
+
+    // create a custom mesh
+    const meshBuilder = MeshBuilder.create(256, 128)
+    meshBuilder.setId(0)
+    meshBuilder.addSphere(Vec3.create(0, 0, 0), 4, 2)
+    const mesh = meshBuilder.getMesh()
+    // Mesh.computeNormalsImmediate(mesh)
+
+    // add representation from custom mesh
+    const customRepr = CustomRepresentation()
+    await customRepr.create(mesh, {
+        useFog: false // TODO fog not working properly
+    }).run()
+    viewer.add(customRepr)
+
+    // ensure the added representations get rendered, i.e. without mouse input
+    viewer.requestDraw()
+}
+
+init()

+ 2 - 1
src/mol-geo/representation/structure/representation/cartoon.ts

@@ -33,7 +33,8 @@ export function CartoonRepresentation(): StructureRepresentation<CartoonProps> {
     return {
         get renderObjects() {
             return [ ...traceRepr.renderObjects, ...gapRepr.renderObjects,
-                ...blockRepr.renderObjects, ...directionRepr.renderObjects ]
+                ...blockRepr.renderObjects // , ...directionRepr.renderObjects
+            ]
         },
         get props() {
             return { ...traceRepr.props, ...gapRepr.props, ...blockRepr.props }