Ver Fonte

added transperancy-from-bundle, improved overpaint

Alexander Rose há 5 anos atrás
pai
commit
7566cc89ca

+ 1 - 1
src/mol-plugin/index.ts

@@ -52,7 +52,7 @@ export const DefaultPluginSpec: PluginSpec = {
         PluginSpec.Action(StateTransforms.Representation.ExplodeStructureRepresentation3D),
         PluginSpec.Action(StateTransforms.Representation.UnwindStructureAssemblyRepresentation3D),
         PluginSpec.Action(StateTransforms.Representation.OverpaintStructureRepresentation3DFromScript),
-        PluginSpec.Action(StateTransforms.Representation.TransparencyStructureRepresentation3D),
+        PluginSpec.Action(StateTransforms.Representation.TransparencyStructureRepresentation3DFromScript),
 
         PluginSpec.Action(StateTransforms.Volume.VolumeFromCcp4),
         PluginSpec.Action(StateTransforms.Representation.VolumeRepresentation3D),

+ 1 - 42
src/mol-plugin/state/transforms/helpers.ts

@@ -4,50 +4,9 @@
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
 
-import { Structure, StructureSelection, QueryContext, StructureElement } 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';
+import { Structure } from '../../../mol-model/structure';
 import { ComputedSecondaryStructure } from '../../../mol-model-props/computed/secondary-structure';
 
-type Script = { language: string, expression: string }
-
-function scriptToLoci(structure: Structure, script: Script) {
-    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))
-    return StructureSelection.toLoci2(result)
-}
-
-export function getStructureOverpaintFromScript(structure: Structure, scriptLayers: { script: Script, color: Color, clear: boolean }[], alpha: number): Overpaint {
-    const layers: Overpaint.Layer[] = []
-    for (let i = 0, il = scriptLayers.length; i < il; ++i) {
-        const { script, color, clear } = scriptLayers[i]
-        layers.push({ loci: scriptToLoci(structure, script), color, clear })
-    }
-    return { layers, alpha }
-}
-
-export function getStructureOverpaintFromBundle(structure: Structure, bundleLayers: { bundle: StructureElement.Bundle, color: Color, clear: boolean }[], alpha: number): Overpaint {
-    const layers: Overpaint.Layer[] = []
-    for (let i = 0, il = bundleLayers.length; i < il; ++i) {
-        const { bundle, color, clear } = bundleLayers[i]
-        const loci = StructureElement.Bundle.toLoci(bundle, structure.root)
-        layers.push({ loci, color, clear })
-    }
-    return { layers, alpha }
-}
-
-export function getStructureTransparency(structure: Structure, script: Script, value: number, variant: Transparency.Variant): Transparency {
-    return { loci: scriptToLoci(structure, script), value, variant }
-}
-
 /**
  * Attaches ComputedSecondaryStructure property when unavailable in sourceData
  */

+ 55 - 14
src/mol-plugin/state/transforms/representation.ts

@@ -29,8 +29,8 @@ 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 { getStructureOverpaintFromScript, getStructureOverpaintFromBundle, getStructureTransparency } from './helpers';
 import { BaseGeometry } from '../../../mol-geo/geometry/base';
+import { Script } from '../../../mol-script/script';
 
 export { StructureRepresentation3D }
 export { StructureRepresentation3DHelpers }
@@ -39,7 +39,8 @@ export { ExplodeStructureRepresentation3D }
 export { UnwindStructureAssemblyRepresentation3D }
 export { OverpaintStructureRepresentation3DFromScript }
 export { OverpaintStructureRepresentation3DFromBundle }
-export { TransparencyStructureRepresentation3D }
+export { TransparencyStructureRepresentation3DFromScript }
+export { TransparencyStructureRepresentation3DFromBundle }
 export { VolumeRepresentation3D }
 
 namespace StructureRepresentation3DHelpers {
@@ -334,12 +335,12 @@ const OverpaintStructureRepresentation3DFromScript = PluginStateTransform.BuiltI
     to: SO.Molecule.Structure.Representation3DState,
     params: {
         layers: PD.ObjectList({
-            script: PD.ScriptExpression({ language: 'mol-script', expression: '(sel.atom.all)' }),
+            script: PD.Script(Script('(sel.atom.all)', 'mol-script')),
             color: PD.Color(ColorNames.blueviolet),
             clear: PD.Boolean(false)
         }, e => `${e.clear ? 'Clear' : Color.toRgbString(e.color)}`, {
             defaultValue: [{
-                script: { language: 'mol-script', expression: '(sel.atom.all)' },
+                script: Script('(sel.atom.all)', 'mol-script'),
                 color: ColorNames.blueviolet,
                 clear: false
             }]
@@ -352,7 +353,7 @@ const OverpaintStructureRepresentation3DFromScript = PluginStateTransform.BuiltI
     },
     apply({ a, params }) {
         const structure = a.data.source.data
-        const overpaint = getStructureOverpaintFromScript(structure, params.layers, params.alpha)
+        const overpaint = Overpaint.ofScript(params.layers, params.alpha, structure)
 
         return new SO.Molecule.Structure.Representation3DState({
             state: { overpaint },
@@ -366,7 +367,7 @@ const OverpaintStructureRepresentation3DFromScript = PluginStateTransform.BuiltI
         const newStructure = a.data.source.data
         if (newStructure !== oldStructure) return StateTransformer.UpdateResult.Recreate
         const oldOverpaint = b.data.state.overpaint!
-        const newOverpaint = getStructureOverpaintFromScript(newStructure, newParams.layers, newParams.alpha)
+        const newOverpaint = Overpaint.ofScript(newParams.layers, newParams.alpha, newStructure)
         if (oldParams.alpha === newParams.alpha && Overpaint.areEqual(oldOverpaint, newOverpaint)) return StateTransformer.UpdateResult.Unchanged
 
         b.data.state.overpaint = newOverpaint
@@ -403,7 +404,7 @@ const OverpaintStructureRepresentation3DFromBundle = PluginStateTransform.BuiltI
     },
     apply({ a, params }) {
         const structure = a.data.source.data
-        const overpaint = getStructureOverpaintFromBundle(structure, params.layers, params.alpha)
+        const overpaint = Overpaint.ofBundle(params.layers, params.alpha, structure)
 
         return new SO.Molecule.Structure.Representation3DState({
             state: { overpaint },
@@ -417,7 +418,7 @@ const OverpaintStructureRepresentation3DFromBundle = PluginStateTransform.BuiltI
         const newStructure = a.data.source.data
         if (newStructure !== oldStructure) return StateTransformer.UpdateResult.Recreate
         const oldOverpaint = b.data.state.overpaint!
-        const newOverpaint = getStructureOverpaintFromBundle(newStructure, newParams.layers, newParams.alpha)
+        const newOverpaint = Overpaint.ofBundle(newParams.layers, newParams.alpha, newStructure)
         if (oldParams.alpha === newParams.alpha && Overpaint.areEqual(oldOverpaint, newOverpaint)) return StateTransformer.UpdateResult.Unchanged
 
         b.data.state.overpaint = newOverpaint
@@ -427,14 +428,14 @@ const OverpaintStructureRepresentation3DFromBundle = PluginStateTransform.BuiltI
     }
 });
 
-type TransparencyStructureRepresentation3D = typeof TransparencyStructureRepresentation3D
-const TransparencyStructureRepresentation3D = PluginStateTransform.BuiltIn({
-    name: 'transparency-structure-representation-3d',
+type TransparencyStructureRepresentation3DFromScript = typeof TransparencyStructureRepresentation3DFromScript
+const TransparencyStructureRepresentation3DFromScript = PluginStateTransform.BuiltIn({
+    name: 'transparency-structure-representation-3d-from-script',
     display: 'Transparency 3D Representation',
     from: SO.Molecule.Structure.Representation3D,
     to: SO.Molecule.Structure.Representation3DState,
     params: {
-        script: PD.ScriptExpression({ language: 'mol-script', expression: '(sel.atom.all)' }),
+        script: PD.Script(Script('(sel.atom.all)', 'mol-script')),
         value: PD.Numeric(0.75, { min: 0, max: 1, step: 0.01 }, { label: 'Transparency' }),
         variant: PD.Select('single', [['single', 'Single-layer'], ['multi', 'Multi-layer']])
     }
@@ -444,7 +445,7 @@ const TransparencyStructureRepresentation3D = PluginStateTransform.BuiltIn({
     },
     apply({ a, params }) {
         const structure = a.data.source.data
-        const transparency = getStructureTransparency(structure, params.script, params.value, params.variant)
+        const transparency = Transparency.ofScript(params.script, params.value, params.variant, structure)
 
         return new SO.Molecule.Structure.Representation3DState({
             state: { transparency },
@@ -457,7 +458,47 @@ const TransparencyStructureRepresentation3D = PluginStateTransform.BuiltIn({
         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.script, newParams.value, newParams.variant)
+        const newTransparency = Transparency.ofScript(newParams.script, newParams.value, newParams.variant, structure)
+        if (Transparency.areEqual(oldTransparency, newTransparency)) return StateTransformer.UpdateResult.Unchanged
+
+        b.data.state.transparency = newTransparency
+        b.data.source = a
+        b.label = `Transparency (${newTransparency.value})`
+        return StateTransformer.UpdateResult.Updated
+    }
+});
+
+type TransparencyStructureRepresentation3DFromBundle = typeof TransparencyStructureRepresentation3DFromBundle
+const TransparencyStructureRepresentation3DFromBundle = PluginStateTransform.BuiltIn({
+    name: 'transparency-structure-representation-3d-from-bundle',
+    display: 'Transparency 3D Representation',
+    from: SO.Molecule.Structure.Representation3D,
+    to: SO.Molecule.Structure.Representation3DState,
+    params: {
+        bundle: PD.Value<StructureElement.Bundle>(StructureElement.Bundle.Empty),
+        value: PD.Numeric(0.75, { min: 0, max: 1, step: 0.01 }, { label: 'Transparency' }),
+        variant: PD.Select('single', [['single', 'Single-layer'], ['multi', 'Multi-layer']])
+    }
+})({
+    canAutoUpdate() {
+        return true;
+    },
+    apply({ a, params }) {
+        const structure = a.data.source.data
+        const transparency = Transparency.ofBundle(params.bundle, params.value, params.variant, structure)
+
+        return new SO.Molecule.Structure.Representation3DState({
+            state: { transparency },
+            initialState: { transparency: Transparency.Empty },
+            info: structure,
+            source: a
+        }, { label: `Transparency (${transparency.value})` })
+    },
+    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 = Transparency.ofBundle(newParams.bundle, newParams.value, newParams.variant, structure)
         if (Transparency.areEqual(oldTransparency, newTransparency)) return StateTransformer.UpdateResult.Unchanged
 
         b.data.state.transparency = newTransparency

+ 21 - 1
src/mol-theme/overpaint.ts

@@ -6,7 +6,8 @@
 
 import { Loci } from '../mol-model/loci';
 import { Color } from '../mol-util/color';
-import { Structure } from '../mol-model/structure';
+import { Structure, StructureElement } from '../mol-model/structure';
+import { Script } from '../mol-script/script';
 
 export { Overpaint }
 
@@ -36,4 +37,23 @@ namespace Overpaint {
         }
         return { layers, alpha: overpaint.alpha }
     }
+
+    export function ofScript(scriptLayers: { script: Script, color: Color, clear: boolean }[], alpha: number, structure: Structure): Overpaint {
+        const layers: Overpaint.Layer[] = []
+        for (let i = 0, il = scriptLayers.length; i < il; ++i) {
+            const { script, color, clear } = scriptLayers[i]
+            layers.push({ loci: Script.toLoci(script, structure), color, clear })
+        }
+        return { layers, alpha }
+    }
+
+    export function ofBundle(bundleLayers: { bundle: StructureElement.Bundle, color: Color, clear: boolean }[], alpha: number, structure: Structure): Overpaint {
+        const layers: Overpaint.Layer[] = []
+        for (let i = 0, il = bundleLayers.length; i < il; ++i) {
+            const { bundle, color, clear } = bundleLayers[i]
+            const loci = StructureElement.Bundle.toLoci(bundle, structure.root)
+            layers.push({ loci, color, clear })
+        }
+        return { layers, alpha }
+    }
 }

+ 10 - 0
src/mol-theme/transparency.ts

@@ -5,6 +5,8 @@
  */
 
 import { Loci, EmptyLoci } from '../mol-model/loci';
+import { StructureElement, Structure } from '../mol-model/structure';
+import { Script } from '../mol-script/script';
 
 export { Transparency }
 
@@ -24,4 +26,12 @@ namespace Transparency {
         if (!Loci.areEqual(tA.loci, tB.loci)) return false
         return true
     }
+
+    export function ofScript(script: Script, value: number, variant: Transparency.Variant, structure: Structure): Transparency {
+        return { loci: Script.toLoci(script, structure), value, variant }
+    }
+
+    export function ofBundle(bundle: StructureElement.Bundle, value: number, variant: Transparency.Variant, structure: Structure): Transparency {
+        return { loci: StructureElement.Bundle.toLoci(bundle, structure), value, variant }
+    }
 }