diff --git a/src/mol-plugin/index.ts b/src/mol-plugin/index.ts index 3fce9342c9409b2ce783bb4559a0f3b8de0aa507..7650a7447a7f29aa2a4330aa3107b440fc019772 100644 --- a/src/mol-plugin/index.ts +++ b/src/mol-plugin/index.ts @@ -46,7 +46,8 @@ export const DefaultPluginSpec: PluginSpec = { PluginSpec.Action(StateTransforms.Representation.StructureLabels3D), PluginSpec.Action(StateTransforms.Representation.ExplodeStructureRepresentation3D), PluginSpec.Action(StateTransforms.Representation.UnwindStructureAssemblyRepresentation3D), - PluginSpec.Action(StateTransforms.Representation.ColorStructureRepresentation3D), + PluginSpec.Action(StateTransforms.Representation.OverpaintStructureRepresentation3D), + PluginSpec.Action(StateTransforms.Representation.TransparencyStructureRepresentation3D), PluginSpec.Action(StateTransforms.Representation.VolumeRepresentation3D), PluginSpec.Action(StateActions.Structure.StructureFromSelection), diff --git a/src/mol-plugin/state/animation/helpers.ts b/src/mol-plugin/state/animation/helpers.ts index df6bfb962bbc35bfe78088aed47fc39df1d854f2..d86448d5fedb44a6d39f2e87c4c3a895e112d238 100644 --- a/src/mol-plugin/state/animation/helpers.ts +++ b/src/mol-plugin/state/animation/helpers.ts @@ -4,16 +4,10 @@ * @author David Sehnal <david.sehnal@gmail.com> */ - import { SymmetryOperator } from 'mol-math/geometry'; import { Mat4, Vec3 } from 'mol-math/linear-algebra'; -import { Structure, StructureSelection, QueryContext } from 'mol-model/structure'; +import { Structure } from 'mol-model/structure'; import { StructureUnitTransforms } from 'mol-model/structure/structure/util/unit-transforms'; -import { Color } from 'mol-util/color'; -import { Overpaint } from 'mol-theme/overpaint'; -import { parseMolScript } from 'mol-script/language/parser'; -import { transpileMolScript } from 'mol-script/script/mol-script/symbols'; -import { compile } from 'mol-script/runtime/query/compiler'; const _unwindMatrix = Mat4.zero(); export function unwindStructureAssembly(structure: Structure, unitTransforms: StructureUnitTransforms, t: number) { @@ -38,22 +32,4 @@ export function explodeStructure(structure: Structure, unitTransforms: Structure unitTransforms.setTransform(_transMat, u); } -} - -type ScriptLayers = { script: { language: string, expression: string }, color: Color }[] -export function getStructureOverpaint(structure: Structure, scriptLayers: ScriptLayers, alpha: number): Overpaint { - const layers: Overpaint.Layer[] = [] - for (let i = 0, il = scriptLayers.length; i < il; ++i) { - const { script, color } = scriptLayers[i] - const parsed = parseMolScript(script.expression) - if (parsed.length === 0) throw new Error('No query') - const query = transpileMolScript(parsed[0]) - - const compiled = compile<StructureSelection>(query) - const result = compiled(new QueryContext(structure)) - const loci = StructureSelection.toLoci2(result) - - layers.push({ loci, color }) - } - return { layers, alpha } } \ No newline at end of file diff --git a/src/mol-plugin/state/transforms/helpers.ts b/src/mol-plugin/state/transforms/helpers.ts new file mode 100644 index 0000000000000000000000000000000000000000..e5a55427d9b51d3cd90bf47b60be79acd78cf873 --- /dev/null +++ b/src/mol-plugin/state/transforms/helpers.ts @@ -0,0 +1,49 @@ +/** + * Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info. + * + * @author Alexander Rose <alexander.rose@weirdbyte.de> + */ + +import { Structure, StructureSelection, QueryContext } from 'mol-model/structure'; +import { Color } from 'mol-util/color'; +import { Overpaint } from 'mol-theme/overpaint'; +import { parseMolScript } from 'mol-script/language/parser'; +import { transpileMolScript } from 'mol-script/script/mol-script/symbols'; +import { compile } from 'mol-script/runtime/query/compiler'; +import { Transparency } from 'mol-theme/transparency'; + +type Script = { language: string, expression: string } + +export function getStructureOverpaint(structure: Structure, scriptLayers: { script: Script, color: Color }[], alpha: number): Overpaint { + const layers: Overpaint.Layer[] = [] + for (let i = 0, il = scriptLayers.length; i < il; ++i) { + const { script, color } = scriptLayers[i] + const parsed = parseMolScript(script.expression) + if (parsed.length === 0) throw new Error('No query') + const query = transpileMolScript(parsed[0]) + + const compiled = compile<StructureSelection>(query) + const result = compiled(new QueryContext(structure)) + const loci = StructureSelection.toLoci2(result) + + layers.push({ loci, color }) + } + return { layers, alpha } +} + +export function getStructureTransparency(structure: Structure, scriptLayers: { script: Script, value: number }[]): Transparency { + const layers: Transparency.Layer[] = [] + for (let i = 0, il = scriptLayers.length; i < il; ++i) { + const { script, value } = scriptLayers[i] + const parsed = parseMolScript(script.expression) + if (parsed.length === 0) throw new Error('No query') + const query = transpileMolScript(parsed[0]) + + const compiled = compile<StructureSelection>(query) + const result = compiled(new QueryContext(structure)) + const loci = StructureSelection.toLoci2(result) + + layers.push({ loci, value }) + } + return { layers } +} \ No newline at end of file diff --git a/src/mol-plugin/state/transforms/representation.ts b/src/mol-plugin/state/transforms/representation.ts index b5c9e1a8257281547faf30b096c49b42558d1816..79af0ae63b5b0b93f2ce91643cfb4f77542839df 100644 --- a/src/mol-plugin/state/transforms/representation.ts +++ b/src/mol-plugin/state/transforms/representation.ts @@ -25,16 +25,19 @@ import { ColorNames } from 'mol-util/color/tables'; import { getLabelRepresentation } from 'mol-plugin/util/structure-labels'; import { ShapeRepresentation } from 'mol-repr/shape/representation'; import { StructureUnitTransforms } from 'mol-model/structure/structure/util/unit-transforms'; -import { unwindStructureAssembly, explodeStructure, getStructureOverpaint } from '../animation/helpers'; +import { unwindStructureAssembly, explodeStructure } from '../animation/helpers'; import { Color } from 'mol-util/color'; import { Overpaint } from 'mol-theme/overpaint'; +import { Transparency } from 'mol-theme/transparency'; +import { getStructureOverpaint, getStructureTransparency } from './helpers'; export { StructureRepresentation3D } export { StructureRepresentation3DHelpers } export { StructureLabels3D} export { ExplodeStructureRepresentation3D } export { UnwindStructureAssemblyRepresentation3D } -export { OverpaintStructureRepresentation3D as ColorStructureRepresentation3D } +export { OverpaintStructureRepresentation3D } +export { TransparencyStructureRepresentation3D } export { VolumeRepresentation3D } namespace StructureRepresentation3DHelpers { @@ -366,6 +369,57 @@ const OverpaintStructureRepresentation3D = PluginStateTransform.BuiltIn({ } }); +type TransparencyStructureRepresentation3D = typeof TransparencyStructureRepresentation3D +const TransparencyStructureRepresentation3D = PluginStateTransform.BuiltIn({ + name: 'transparency-structure-representation-3d', + display: 'Transparency 3D Representation', + from: SO.Molecule.Structure.Representation3D, + to: SO.Molecule.Structure.Representation3DState, + params: { + layers: PD.ObjectList({ + script: PD.ScriptExpression({ language: 'mol-script', expression: '(sel.atom.atom-groups :chain-test (= atom.label_asym_id A))' }), + value: PD.Numeric(0.5) + }, e => `Transparency ${e.value}`, { + defaultValue: [ + { + script: { + language: 'mol-script', + expression: '(sel.atom.atom-groups :chain-test (= atom.label_asym_id A))' + }, + value: 0.5 + } + ] + }), + } +})({ + canAutoUpdate() { + return true; + }, + apply({ a, params }) { + const structure = a.data.source.data + const transparency = getStructureTransparency(structure, params.layers) + + return new SO.Molecule.Structure.Representation3DState({ + state: { transparency }, + initialState: { transparency: Transparency.Empty }, + info: structure, + source: a + }, { label: `Transparency (${transparency.layers.length} Layers)` }) + }, + update({ a, b, newParams, oldParams }) { + const structure = b.data.info as Structure + if (a.data.source.data !== structure) return StateTransformer.UpdateResult.Recreate + const oldTransparency = b.data.state.transparency! + const newTransparency = getStructureTransparency(structure, newParams.layers) + if (Transparency.areEqual(oldTransparency, newTransparency)) return StateTransformer.UpdateResult.Unchanged + + b.data.state.transparency = newTransparency + b.data.source = a + b.label = `Transparency (${newTransparency.layers.length} Layers)` + return StateTransformer.UpdateResult.Updated + } +}); + // export namespace VolumeRepresentation3DHelpers {