Browse Source

membrane orientation tweaks

- registered custom repr so it shows up in components
- some renames to make it more in line with the other extensions
- fix shapes to reuse existing geometries (fails to update on prop changes otherwise)
- added label to repr visuals on hover/highlight
- ignore light forbilayer planes mesh
- TODO: layer spheres seem to be broken (e.g. 3pqr)
Alexander Rose 4 years ago
parent
commit
181646f052

+ 2 - 2
src/apps/viewer/index.ts

@@ -24,7 +24,7 @@ import { PluginState } from '../../mol-plugin/state';
 import { DownloadDensity } from '../../mol-plugin-state/actions/volume';
 import { PluginLayoutControlsDisplay } from '../../mol-plugin/layout';
 import { BuiltInTrajectoryFormat } from '../../mol-plugin-state/formats/trajectory';
-import { MembraneOrientationData } from '../../extensions/membrane-orientation/behavior';
+import { ANVILMembraneOrientation } from '../../extensions/anvil/behavior';
 import { DnatcoConfalPyramids } from '../../extensions/dnatco';
 
 require('mol-plugin-ui/skin/light.scss');
@@ -38,7 +38,7 @@ const Extensions = {
     'pdbe-structure-quality-report': PluginSpec.Behavior(PDBeStructureQualityReport),
     'rcsb-assembly-symmetry': PluginSpec.Behavior(RCSBAssemblySymmetry),
     'rcsb-validation-report': PluginSpec.Behavior(RCSBValidationReport),
-    'membrane-orientation': PluginSpec.Behavior(MembraneOrientationData)
+    'anvil-membrane-orientation': PluginSpec.Behavior(ANVILMembraneOrientation)
 };
 
 const DefaultViewerOptions = {

+ 16 - 2
src/extensions/membrane-orientation/ANVIL.ts → src/extensions/anvil/algorithm.ts

@@ -5,7 +5,6 @@
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
 
-import { ANVILContext } from './anvil/common';
 import { Structure, StructureElement, StructureProperties } from '../../mol-model/structure';
 import { Task, RuntimeContext } from '../../mol-task';
 import { CentroidHelper } from '../../mol-math/geometry/centroid-helper';
@@ -15,7 +14,22 @@ import { getElementMoleculeType } from '../../mol-model/structure/util';
 import { MoleculeType } from '../../mol-model/structure/model/types';
 import { AccessibleSurfaceArea } from '../../mol-model-props/computed/accessible-surface-area/shrake-rupley';
 import { ParamDefinition as PD } from '../../mol-util/param-definition';
-import { MembraneOrientation } from './membrane-orientation';
+import { MembraneOrientation } from './prop';
+
+interface ANVILContext {
+    structure: Structure,
+
+    numberOfSpherePoints: number,
+    stepSize: number,
+    minThickness: number,
+    maxThickness: number,
+    asaCutoff: number,
+
+    offsets: ArrayLike<number>,
+    exposed: ArrayLike<boolean>,
+    centroid: Vec3,
+    extent: number
+};
 
 export const ANVILParams = {
     numberOfSpherePoints: PD.Numeric(120, { min: 35, max: 700, step: 1 }, { description: 'Number of spheres/directions to test for membrane placement. Original value is 350.' }),

+ 39 - 26
src/extensions/membrane-orientation/behavior.ts → src/extensions/anvil/behavior.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  * @author Sebastian Bittrich <sebastian.bittrich@rcsb.org>
@@ -7,8 +7,8 @@
 
 import { ParamDefinition as PD } from '../../mol-util/param-definition';
 import { StructureRepresentationPresetProvider, PresetStructureRepresentations } from '../../mol-plugin-state/builder/structure/representation-preset';
-import { MembraneOrientationProvider, isTransmembrane } from './membrane-orientation';
-import { StateObjectRef, StateAction, StateTransformer, StateTransform } from '../../mol-state';
+import { MembraneOrientationProvider, MembraneOrientation } from './prop';
+import { StateObjectRef, StateTransformer, StateTransform } from '../../mol-state';
 import { Task } from '../../mol-task';
 import { PluginBehavior } from '../../mol-plugin/behavior';
 import { MembraneOrientationRepresentationProvider, MembraneOrientationParams, MembraneOrientationRepresentation } from './representation';
@@ -16,13 +16,18 @@ import { HydrophobicityColorThemeProvider } from '../../mol-theme/color/hydropho
 import { PluginStateObject, PluginStateTransform } from '../../mol-plugin-state/objects';
 import { PluginContext } from '../../mol-plugin/context';
 import { DefaultQueryRuntimeTable } from '../../mol-script/runtime/query/compiler';
+import { StructureSelectionQuery, StructureSelectionCategory } from '../../mol-plugin-state/helpers/structure-selection-query';
+import { MolScriptBuilder as MS } from '../../mol-script/language/builder';
+import { GenericRepresentationRef } from '../../mol-plugin-state/manager/structure/hierarchy-state';
 
-export const MembraneOrientationData = PluginBehavior.create<{ autoAttach: boolean }>({
-    name: 'membrane-orientation-prop',
+const Tag = MembraneOrientation.Tag;
+
+export const ANVILMembraneOrientation = PluginBehavior.create<{ autoAttach: boolean }>({
+    name: 'anvil-membrane-orientation-prop',
     category: 'custom-props',
     display: {
         name: 'Membrane Orientation',
-        description: 'Initialize orientation of membrane layers. Data calculated with ANVIL algorithm.' // TODO add ' or obtained via RCSB PDB'
+        description: 'Data calculated with ANVIL algorithm.'
     },
     ctor: class extends PluginBehavior.Handler<{ autoAttach: boolean }> {
         private provider = MembraneOrientationProvider
@@ -30,12 +35,19 @@ export const MembraneOrientationData = PluginBehavior.create<{ autoAttach: boole
         register(): void {
             DefaultQueryRuntimeTable.addCustomProp(this.provider.descriptor);
 
-            this.ctx.state.data.actions.add(InitMembraneOrientation3D);
             this.ctx.customStructureProperties.register(this.provider, this.params.autoAttach);
 
             this.ctx.representation.structure.registry.add(MembraneOrientationRepresentationProvider);
             this.ctx.query.structure.registry.add(isTransmembrane);
 
+            this.ctx.genericRepresentationControls.set(Tag.Representation, selection => {
+                const refs: GenericRepresentationRef[] = [];
+                selection.structures.forEach(structure => {
+                    const memRepr = structure.genericRepresentations?.filter(r => r.cell.transform.transformer.id === MembraneOrientation3D.id)[0];
+                    if (memRepr) refs.push(memRepr);
+                });
+                return [refs, 'Membrane Orientation'];
+            });
             this.ctx.builders.structure.representation.registerPreset(MembraneOrientationPreset);
         }
 
@@ -49,12 +61,12 @@ export const MembraneOrientationData = PluginBehavior.create<{ autoAttach: boole
         unregister() {
             DefaultQueryRuntimeTable.removeCustomProp(this.provider.descriptor);
 
-            this.ctx.state.data.actions.remove(InitMembraneOrientation3D);
             this.ctx.customStructureProperties.unregister(this.provider.descriptor.name);
 
             this.ctx.representation.structure.registry.remove(MembraneOrientationRepresentationProvider);
             this.ctx.query.structure.registry.remove(isTransmembrane);
 
+            this.ctx.genericRepresentationControls.delete(Tag.Representation);
             this.ctx.builders.structure.representation.unregisterPreset(MembraneOrientationPreset);
         }
     },
@@ -63,25 +75,26 @@ export const MembraneOrientationData = PluginBehavior.create<{ autoAttach: boole
     })
 });
 
-export const InitMembraneOrientation3D = StateAction.build({
-    display: {
-        name: 'Membrane Orientation',
-        description: 'Initialize Membrane Orientation planes and rims. Data calculated with ANVIL algorithm.'
-    },
-    from: PluginStateObject.Molecule.Structure,
-    isApplicable: (a) => MembraneOrientationProvider.isApplicable(a.data)
-})(({ a, ref, state }, plugin: PluginContext) => Task.create('Init Membrane Orientation', async ctx => {
-    try {
-        const propCtx = { runtime: ctx, assetManager: plugin.managers.asset };
-        await MembraneOrientationProvider.attach(propCtx, a.data);
-    } catch(e) {
-        plugin.log.error(`Membrane Orientation: ${e}`);
-        return;
+//
+
+export const isTransmembrane = StructureSelectionQuery('Residues Embedded in Membrane', MS.struct.modifier.union([
+    MS.struct.modifier.wholeResidues([
+        MS.struct.modifier.union([
+            MS.struct.generator.atomGroups({
+                'chain-test': MS.core.rel.eq([MS.ammp('objectPrimitive'), 'atomistic']),
+                'atom-test': MembraneOrientation.symbols.isTransmembrane.symbol(),
+            })
+        ])
+    ])
+]), {
+    description: 'Select residues that are embedded between the membrane layers.',
+    category: StructureSelectionCategory.Residue,
+    ensureCustomProperties: (ctx, structure) => {
+        return MembraneOrientationProvider.attach(ctx, structure);
     }
-    const tree = state.build().to(ref)
-        .applyOrUpdateTagged('membrane-orientation-3d', MembraneOrientation3D);
-    await state.updateTree(tree).runInContext(ctx);
-}));
+});
+
+//
 
 export { MembraneOrientation3D };
 

+ 24 - 37
src/extensions/membrane-orientation/membrane-orientation.ts → src/extensions/anvil/prop.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2019-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Sebastian Bittrich <sebastian.bittrich@rcsb.org>
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
@@ -8,7 +8,7 @@
 import { ParamDefinition as PD } from '../../mol-util/param-definition';
 import { Structure, StructureProperties, Unit } from '../../mol-model/structure';
 import { CustomPropertyDescriptor } from '../../mol-model/custom-property';
-import { ANVILParams, ANVILProps, computeANVIL, isInMembranePlane } from './ANVIL';
+import { ANVILParams, ANVILProps, computeANVIL, isInMembranePlane } from './algorithm';
 import { CustomStructureProperty } from '../../mol-model-props/common/custom-structure-property';
 import { CustomProperty } from '../../mol-model-props/common/custom-property';
 import { AccessibleSurfaceAreaProvider } from '../../mol-model-props/computed/accessible-surface-area';
@@ -16,8 +16,6 @@ import { Vec3 } from '../../mol-math/linear-algebra';
 import { QuerySymbolRuntime } from '../../mol-script/runtime/query/base';
 import { CustomPropSymbol } from '../../mol-script/language/symbol';
 import Type from '../../mol-script/language/type';
-import { StructureSelectionQuery, StructureSelectionCategory } from '../../mol-plugin-state/helpers/structure-selection-query';
-import { MolScriptBuilder as MS } from '../../mol-script/language/builder';
 
 export const MembraneOrientationParams = {
     ...ANVILParams
@@ -25,6 +23,8 @@ export const MembraneOrientationParams = {
 export type MembraneOrientationParams = typeof MembraneOrientationParams
 export type MembraneOrientationProps = PD.Values<MembraneOrientationParams>
 
+export { MembraneOrientation };
+
 interface MembraneOrientation {
     // point in membrane boundary
     readonly planePoint1: Vec3,
@@ -37,45 +37,32 @@ interface MembraneOrientation {
     readonly centroid: Vec3
 }
 
-const pos = Vec3();
-export const MembraneOrientationSymbols = {
-    isTransmembrane: QuerySymbolRuntime.Dynamic(CustomPropSymbol('computed', 'membrane-orientation.is-transmembrane', Type.Bool),
-        ctx => {
-            const { unit, structure } = ctx.element;
-            const { x, y, z } = StructureProperties.atom;
-            if (!Unit.isAtomic(unit)) return 0;
-            const membraneOrientation = MembraneOrientationProvider.get(structure).value;
-            if (!membraneOrientation) return 0;
-            Vec3.set(pos, x(ctx.element), y(ctx.element), z(ctx.element));
-            const { normalVector, planePoint1, planePoint2 } = membraneOrientation!;
-            return isInMembranePlane(pos, normalVector, planePoint1, planePoint2);
-        })
-}
-
-export const isTransmembrane = StructureSelectionQuery('Residues Embedded in Membrane', MS.struct.modifier.union([
-    MS.struct.modifier.wholeResidues([
-        MS.struct.modifier.union([
-            MS.struct.generator.atomGroups({
-                'chain-test': MS.core.rel.eq([MS.ammp('objectPrimitive'), 'atomistic']),
-                'atom-test': MembraneOrientationSymbols.isTransmembrane.symbol(),
-            })
-        ])
-    ])
-]), {
-    description: 'Select residues that are embedded between the membrane layers.',
-    category: StructureSelectionCategory.Residue,
-    ensureCustomProperties: (ctx, structure) => {
-        return MembraneOrientationProvider.attach(ctx, structure);
+namespace MembraneOrientation {
+    export enum Tag {
+        Representation = 'membrane-orientation-3d'
     }
-});
 
-export { MembraneOrientation };
+    const pos = Vec3();
+    export const symbols = {
+        isTransmembrane: QuerySymbolRuntime.Dynamic(CustomPropSymbol('computed', 'membrane-orientation.is-transmembrane', Type.Bool),
+            ctx => {
+                const { unit, structure } = ctx.element;
+                const { x, y, z } = StructureProperties.atom;
+                if (!Unit.isAtomic(unit)) return 0;
+                const membraneOrientation = MembraneOrientationProvider.get(structure).value;
+                if (!membraneOrientation) return 0;
+                Vec3.set(pos, x(ctx.element), y(ctx.element), z(ctx.element));
+                const { normalVector, planePoint1, planePoint2 } = membraneOrientation!;
+                return isInMembranePlane(pos, normalVector, planePoint1, planePoint2);
+            })
+    };
+}
 
 export const MembraneOrientationProvider: CustomStructureProperty.Provider<MembraneOrientationParams, MembraneOrientation> = CustomStructureProperty.createProvider({
     label: 'Membrane Orientation',
     descriptor: CustomPropertyDescriptor({
-        name: 'molstar_computed_membrane_orientation',
-        symbols: MembraneOrientationSymbols,
+        name: 'anvil_computed_membrane_orientation',
+        symbols: MembraneOrientation.symbols,
         // TODO `cifExport`
     }),
     type: 'root',

+ 28 - 22
src/extensions/membrane-orientation/representation.ts → src/extensions/anvil/representation.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  * @author Sebastian Bittrich <sebastian.bittrich@rcsb.org>
@@ -12,11 +12,10 @@ import { Structure } from '../../mol-model/structure';
 import { Spheres } from '../../mol-geo/geometry/spheres/spheres';
 import { SpheresBuilder } from '../../mol-geo/geometry/spheres/spheres-builder';
 import { StructureRepresentationProvider, StructureRepresentation, StructureRepresentationStateBuilder } from '../../mol-repr/structure/representation';
-import { MembraneOrientation } from './membrane-orientation';
+import { MembraneOrientation } from './prop';
 import { ThemeRegistryContext } from '../../mol-theme/theme';
 import { ShapeRepresentation } from '../../mol-repr/shape/representation';
 import { Shape } from '../../mol-model/shape';
-import { ColorNames } from '../../mol-util/color/names';
 import { RuntimeContext } from '../../mol-task';
 import { Lines } from '../../mol-geo/geometry/lines/lines';
 import { Mesh } from '../../mol-geo/geometry/mesh/mesh';
@@ -24,7 +23,10 @@ import { LinesBuilder } from '../../mol-geo/geometry/lines/lines-builder';
 import { Circle } from '../../mol-geo/primitive/circle';
 import { transformPrimitive } from '../../mol-geo/primitive/primitive';
 import { MeshBuilder } from '../../mol-geo/geometry/mesh/mesh-builder';
-import { MembraneOrientationProvider } from './membrane-orientation';
+import { MembraneOrientationProvider } from './prop';
+import { MarkerActions } from '../../mol-util/marker-action';
+import { lociLabel } from '../../mol-theme/label';
+import { ColorNames } from '../../mol-util/color/names';
 
 const SharedParams = {
     color: PD.Color(ColorNames.lightgrey),
@@ -32,8 +34,8 @@ const SharedParams = {
 };
 
 const BilayerSpheresParams = {
-    ...SharedParams,
     ...Spheres.Params,
+    ...SharedParams,
     sphereSize: PD.Numeric(1, { min: 0.1, max: 10, step: 0.1 }, { description: 'Size of spheres that represent membrane planes' }),
     density: PD.Numeric(1, { min: 0.25, max: 10, step: 0.25 }, { description: 'Distance between spheres'})
 };
@@ -41,27 +43,27 @@ export type BilayerSpheresParams = typeof BilayerSpheresParams
 export type BilayerSpheresProps = PD.Values<BilayerSpheresParams>
 
 const BilayerPlanesParams = {
-    ...SharedParams,
     ...Mesh.Params,
-    sectorOpacity: PD.Numeric(0.5, { min: 0, max: 1, step: 0.01 })
+    ...SharedParams,
+    sectorOpacity: PD.Numeric(0.5, { min: 0, max: 1, step: 0.01 }),
 };
 export type BilayerPlanesParams = typeof BilayerPlanesParams
 export type BilayerPlanesProps = PD.Values<BilayerPlanesParams>
 
 const BilayerRimsParams = {
-    ...SharedParams,
     ...Lines.Params,
+    ...SharedParams,
     lineSizeAttenuation: PD.Boolean(true),
-    linesSize: PD.Numeric(0.5, { min: 0.01, max: 50, step: 0.01 }),
-    dashedLines: PD.Boolean(true)
+    linesSize: PD.Numeric(0.3, { min: 0.01, max: 50, step: 0.01 }),
+    dashedLines: PD.Boolean(true),
 };
 export type BilayerRimsParams = typeof BilayerRimsParams
 export type BilayerRimsProps = PD.Values<BilayerRimsParams>
 
 const MembraneOrientationVisuals = {
-    'bilayer-spheres': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<MembraneOrientation, BilayerSpheresParams>) => ShapeRepresentation(getBilayerSpheres, Spheres.Utils, { modifyState: s => ({ ...s, pickable: false }) }),
-    'bilayer-planes': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<MembraneOrientation, BilayerPlanesParams>) => ShapeRepresentation(getBilayerPlanes, Mesh.Utils, { modifyProps: p => ({ ...p, alpha: p.sectorOpacity }), modifyState: s => ({ ...s, pickable: false }) }),
-    'bilayer-rims': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<MembraneOrientation, BilayerRimsParams>) => ShapeRepresentation(getBilayerRims, Lines.Utils, { modifyState: s => ({ ...s, pickable: false }) })
+    'bilayer-spheres': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<MembraneOrientation, BilayerSpheresParams>) => ShapeRepresentation(getBilayerSpheres, Spheres.Utils, { modifyState: s => ({ ...s, markerActions: MarkerActions.Highlighting }) }),
+    'bilayer-planes': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<MembraneOrientation, BilayerPlanesParams>) => ShapeRepresentation(getBilayerPlanes, Mesh.Utils, { modifyState: s => ({ ...s, markerActions: MarkerActions.Highlighting }), modifyProps: p => ({ ...p, alpha: p.sectorOpacity, ignoreLight: true, doubleSided: false }) }),
+    'bilayer-rims': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<MembraneOrientation, BilayerRimsParams>) => ShapeRepresentation(getBilayerRims, Lines.Utils, { modifyState: s => ({ ...s, markerActions: MarkerActions.Highlighting }) })
 };
 
 export const MembraneOrientationParams = {
@@ -94,16 +96,20 @@ export const MembraneOrientationRepresentationProvider = StructureRepresentation
     isApplicable: (structure: Structure) => structure.elementCount > 0
 });
 
-function getBilayerRims(ctx: RuntimeContext, data: Structure, props: BilayerRimsProps): Shape<Lines> {
+function membraneLabel(data: Structure) {
+    return `${lociLabel(Structure.Loci(data))} | Membrane Orientation`;
+}
+
+function getBilayerRims(ctx: RuntimeContext, data: Structure, props: BilayerRimsProps, shape?: Shape<Lines>): Shape<Lines> {
     const { planePoint1: p1, planePoint2: p2, centroid, normalVector: normal, radius } = MembraneOrientationProvider.get(data).value!;
     const scaledRadius = props.radiusFactor * radius;
-    const builder = LinesBuilder.create(128, 64);
+    const builder = LinesBuilder.create(128, 64, shape?.geometry);
     getLayerCircle(builder, p1, centroid, normal, scaledRadius, props);
     getLayerCircle(builder, p2, centroid, normal, scaledRadius, props);
-    return Shape.create(name, data, builder.getLines(), () => props.color, () => props.linesSize, () => '');
+    return Shape.create(name, data, builder.getLines(), () => props.color, () => props.linesSize, () => membraneLabel(data));
 }
 
-function getLayerCircle(builder: LinesBuilder, p: Vec3, centroid: Vec3, normal: Vec3, radius: number, props: BilayerRimsProps) {
+function getLayerCircle(builder: LinesBuilder, p: Vec3, centroid: Vec3, normal: Vec3, radius: number, props: BilayerRimsProps, shape?: Shape<Lines>) {
     const circle = getCircle(p, centroid, normal, radius);
     const { indices, vertices } = circle;
     for (let j = 0, jl = indices.length; j < jl; j += 3) {
@@ -126,7 +132,7 @@ function getCircle(p: Vec3, centroid: Vec3, normal: Vec3, radius: number) {
     Mat4.setTranslation(tmpMat, p);
     Mat4.mul(tmpMat, tmpMat, Mat4.rotX90);
 
-    const circle = Circle({ radius });
+    const circle = Circle({ radius, segments: 64 });
     return transformPrimitive(circle, tmpMat);
 }
 
@@ -136,7 +142,7 @@ function getBilayerPlanes(ctx: RuntimeContext, data: Structure, props: BilayerPl
     const scaledRadius = props.radiusFactor * radius;
     getLayerPlane(state, p1, centroid, normal, scaledRadius);
     getLayerPlane(state, p2, centroid, normal, scaledRadius);
-    return Shape.create(name, data, MeshBuilder.getMesh(state), () => props.color, () => 1, () => '');
+    return Shape.create(name, data, MeshBuilder.getMesh(state), () => props.color, () => 1, () => membraneLabel(data));
 }
 
 function getLayerPlane(state: MeshBuilder.State, p: Vec3, centroid: Vec3, normal: Vec3, radius: number) {
@@ -146,15 +152,15 @@ function getLayerPlane(state: MeshBuilder.State, p: Vec3, centroid: Vec3, normal
     MeshBuilder.addPrimitiveFlipped(state, Mat4.id, circle);
 }
 
-function getBilayerSpheres(ctx: RuntimeContext, data: Structure, props: BilayerSpheresProps): Shape<Spheres> {
+function getBilayerSpheres(ctx: RuntimeContext, data: Structure, props: BilayerSpheresProps, shape?: Shape<Spheres>): Shape<Spheres> {
     const { density } = props;
     const { radius, planePoint1, planePoint2, normalVector } = MembraneOrientationProvider.get(data).value!;
     const scaledRadius = (props.radiusFactor * radius) * (props.radiusFactor * radius);
 
-    const spheresBuilder = SpheresBuilder.create();
+    const spheresBuilder = SpheresBuilder.create(256, 128, shape?.geometry);
     getLayerSpheres(spheresBuilder, planePoint1, normalVector, density, scaledRadius);
     getLayerSpheres(spheresBuilder, planePoint2, normalVector, density, scaledRadius);
-    return Shape.create(name, data, spheresBuilder.getSpheres(), () => props.color, () => props.sphereSize, () => '');
+    return Shape.create(name, data, spheresBuilder.getSpheres(), () => props.color, () => props.sphereSize, () => membraneLabel(data));
 }
 
 function getLayerSpheres(spheresBuilder: SpheresBuilder, point: Vec3, normalVector: Vec3, density: number, sqRadius: number) {

+ 0 - 23
src/extensions/membrane-orientation/anvil/common.ts

@@ -1,23 +0,0 @@
-/**
- * Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * @author Sebastian Bittrich <sebastian.bittrich@rcsb.org>
- */
-
-import { Structure } from '../../../mol-model/structure';
-import { Vec3 } from '../../../mol-math/linear-algebra';
-
-export interface ANVILContext {
-    structure: Structure,
-
-    numberOfSpherePoints: number,
-    stepSize: number,
-    minThickness: number,
-    maxThickness: number,
-    asaCutoff: number,
-
-    offsets: ArrayLike<number>,
-    exposed: ArrayLike<boolean>,
-    centroid: Vec3,
-    extent: number
-};

+ 2 - 2
src/tests/browser/render-structure.ts

@@ -26,8 +26,8 @@ import { InteractionsProvider } from '../../mol-model-props/computed/interaction
 import { SecondaryStructureProvider } from '../../mol-model-props/computed/secondary-structure';
 import { SyncRuntimeContext } from '../../mol-task/execution/synchronous';
 import { AssetManager } from '../../mol-util/assets';
-import { MembraneOrientationProvider } from '../../extensions/membrane-orientation/membrane-orientation';
-import { MembraneOrientationRepresentationProvider } from '../../extensions/membrane-orientation/representation';
+import { MembraneOrientationProvider } from '../../extensions/anvil/prop';
+import { MembraneOrientationRepresentationProvider } from '../../extensions/anvil/representation';
 
 const parent = document.getElementById('app')!;
 parent.style.width = '100%';