molstar
Version:
A comprehensive macromolecular library.
938 lines • 59.5 kB
JavaScript
/**
* Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { __assign, __awaiter, __generator } from "tslib";
import { Structure, StructureElement } from '../../mol-model/structure';
import { Volume } from '../../mol-model/volume';
import { StateTransformer, StateObject } from '../../mol-state';
import { Task } from '../../mol-task';
import { Theme } from '../../mol-theme/theme';
import { ParamDefinition as PD } from '../../mol-util/param-definition';
import { PluginStateObject as SO, PluginStateTransform } from '../objects';
import { ColorNames } from '../../mol-util/color/names';
import { ShapeRepresentation } from '../../mol-repr/shape/representation';
import { StructureUnitTransforms } from '../../mol-model/structure/structure/util/unit-transforms';
import { unwindStructureAssembly, explodeStructure, spinStructure, SpinStructureParams, getSpinStructureAxisAndOrigin } from '../animation/helpers';
import { Color } from '../../mol-util/color';
import { Overpaint } from '../../mol-theme/overpaint';
import { Transparency } from '../../mol-theme/transparency';
import { BaseGeometry } from '../../mol-geo/geometry/base';
import { Script } from '../../mol-script/script';
import { UnitcellParams, UnitcellRepresentation, getUnitcellData } from '../../mol-repr/shape/model/unitcell';
import { DistanceParams, DistanceRepresentation } from '../../mol-repr/shape/loci/distance';
import { getDistanceDataFromStructureSelections, getLabelDataFromStructureSelections, getOrientationDataFromStructureSelections, getAngleDataFromStructureSelections, getDihedralDataFromStructureSelections } from './helpers';
import { LabelParams, LabelRepresentation } from '../../mol-repr/shape/loci/label';
import { OrientationRepresentation, OrientationParams } from '../../mol-repr/shape/loci/orientation';
import { AngleParams, AngleRepresentation } from '../../mol-repr/shape/loci/angle';
import { DihedralParams, DihedralRepresentation } from '../../mol-repr/shape/loci/dihedral';
import { ModelSymmetry } from '../../mol-model-formats/structure/property/symmetry';
import { Clipping } from '../../mol-theme/clipping';
import { ObjectKeys } from '../../mol-util/type-helpers';
import { Mesh } from '../../mol-geo/geometry/mesh/mesh';
import { getBoxMesh } from './shape';
import { Shape } from '../../mol-model/shape';
export { StructureRepresentation3D };
export { ExplodeStructureRepresentation3D };
export { SpinStructureRepresentation3D };
export { UnwindStructureAssemblyRepresentation3D };
export { OverpaintStructureRepresentation3DFromScript };
export { OverpaintStructureRepresentation3DFromBundle };
export { TransparencyStructureRepresentation3DFromScript };
export { TransparencyStructureRepresentation3DFromBundle };
export { ClippingStructureRepresentation3DFromScript };
export { ClippingStructureRepresentation3DFromBundle };
export { VolumeRepresentation3D };
var StructureRepresentation3D = PluginStateTransform.BuiltIn({
name: 'structure-representation-3d',
display: '3D Representation',
from: SO.Molecule.Structure,
to: SO.Molecule.Structure.Representation3D,
params: function (a, ctx) {
var _a = ctx.representation.structure, registry = _a.registry, themeCtx = _a.themes;
var type = registry.get(registry.default.name);
if (!a) {
var colorThemeInfo_1 = {
help: function (value) {
var name = value.name, params = value.params;
var p = themeCtx.colorThemeRegistry.get(name);
var ct = p.factory({}, params);
return { description: ct.description, legend: ct.legend };
}
};
return {
type: PD.Mapped(registry.default.name, registry.types, function (name) { return PD.Group(registry.get(name).getParams(themeCtx, Structure.Empty)); }),
colorTheme: PD.Mapped(type.defaultColorTheme.name, themeCtx.colorThemeRegistry.types, function (name) { return PD.Group(themeCtx.colorThemeRegistry.get(name).getParams({ structure: Structure.Empty })); }, colorThemeInfo_1),
sizeTheme: PD.Mapped(type.defaultSizeTheme.name, themeCtx.sizeThemeRegistry.types, function (name) { return PD.Group(themeCtx.sizeThemeRegistry.get(name).getParams({ structure: Structure.Empty })); })
};
}
var dataCtx = { structure: a.data };
var colorThemeInfo = {
help: function (value) {
var name = value.name, params = value.params;
var p = themeCtx.colorThemeRegistry.get(name);
var ct = p.factory(dataCtx, params);
return { description: ct.description, legend: ct.legend };
}
};
return ({
type: PD.Mapped(registry.default.name, registry.getApplicableTypes(a.data), function (name) { return PD.Group(registry.get(name).getParams(themeCtx, a.data)); }),
colorTheme: PD.Mapped(type.defaultColorTheme.name, themeCtx.colorThemeRegistry.getApplicableTypes(dataCtx), function (name) { return PD.Group(themeCtx.colorThemeRegistry.get(name).getParams(dataCtx)); }, colorThemeInfo),
sizeTheme: PD.Mapped(type.defaultSizeTheme.name, themeCtx.sizeThemeRegistry.types, function (name) { return PD.Group(themeCtx.sizeThemeRegistry.get(name).getParams(dataCtx)); })
});
}
})({
canAutoUpdate: function (_a) {
var a = _a.a, oldParams = _a.oldParams, newParams = _a.newParams;
// TODO: other criteria as well?
return a.data.elementCount < 10000 || (oldParams.type.name === newParams.type.name && newParams.type.params.quality !== 'custom');
},
apply: function (_a, plugin) {
var _this = this;
var a = _a.a, params = _a.params, cache = _a.cache;
return Task.create('Structure Representation', function (ctx) { return __awaiter(_this, void 0, void 0, function () {
var propertyCtx, provider, data, repr, props;
var _a, _b;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
propertyCtx = { runtime: ctx, assetManager: plugin.managers.asset };
provider = plugin.representation.structure.registry.get(params.type.name);
data = ((_a = provider.getData) === null || _a === void 0 ? void 0 : _a.call(provider, a.data, params.type.params)) || a.data;
if (!provider.ensureCustomProperties) return [3 /*break*/, 2];
return [4 /*yield*/, provider.ensureCustomProperties.attach(propertyCtx, data)];
case 1:
_c.sent();
_c.label = 2;
case 2:
repr = provider.factory(__assign({ webgl: (_b = plugin.canvas3d) === null || _b === void 0 ? void 0 : _b.webgl }, plugin.representation.structure.themes), provider.getParams);
return [4 /*yield*/, Theme.ensureDependencies(propertyCtx, plugin.representation.structure.themes, { structure: data }, params)];
case 3:
_c.sent();
repr.setTheme(Theme.create(plugin.representation.structure.themes, { structure: data }, params));
props = params.type.params || {};
return [4 /*yield*/, repr.createOrUpdate(props, data).runInContext(ctx)];
case 4:
_c.sent();
return [2 /*return*/, new SO.Molecule.Structure.Representation3D({ repr: repr, sourceData: a.data }, { label: provider.label })];
}
});
}); });
},
update: function (_a, plugin) {
var _this = this;
var a = _a.a, b = _a.b, oldParams = _a.oldParams, newParams = _a.newParams, cache = _a.cache;
return Task.create('Structure Representation', function (ctx) { return __awaiter(_this, void 0, void 0, function () {
var provider, data, propertyCtx, props;
var _a, _b;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
if (newParams.type.name !== oldParams.type.name)
return [2 /*return*/, StateTransformer.UpdateResult.Recreate];
provider = plugin.representation.structure.registry.get(newParams.type.name);
if ((_a = provider.mustRecreate) === null || _a === void 0 ? void 0 : _a.call(provider, oldParams.type.params, newParams.type.params))
return [2 /*return*/, StateTransformer.UpdateResult.Recreate];
data = ((_b = provider.getData) === null || _b === void 0 ? void 0 : _b.call(provider, a.data, newParams.type.params)) || a.data;
propertyCtx = { runtime: ctx, assetManager: plugin.managers.asset };
if (!provider.ensureCustomProperties) return [3 /*break*/, 2];
return [4 /*yield*/, provider.ensureCustomProperties.attach(propertyCtx, data)];
case 1:
_c.sent();
_c.label = 2;
case 2:
// TODO: if themes had a .needsUpdate method the following block could
// be optimized and only executed conditionally
Theme.releaseDependencies(plugin.representation.structure.themes, { structure: b.data.sourceData }, oldParams);
return [4 /*yield*/, Theme.ensureDependencies(propertyCtx, plugin.representation.structure.themes, { structure: data }, newParams)];
case 3:
_c.sent();
b.data.repr.setTheme(Theme.create(plugin.representation.structure.themes, { structure: data }, newParams));
props = __assign(__assign({}, b.data.repr.props), newParams.type.params);
return [4 /*yield*/, b.data.repr.createOrUpdate(props, data).runInContext(ctx)];
case 4:
_c.sent();
b.data.sourceData = a.data;
return [2 /*return*/, StateTransformer.UpdateResult.Updated];
}
});
}); });
},
dispose: function (_a, plugin) {
var b = _a.b, params = _a.params;
if (!b || !params)
return;
var structure = b.data.sourceData;
var provider = plugin.representation.structure.registry.get(params.type.name);
if (provider.ensureCustomProperties)
provider.ensureCustomProperties.detach(structure);
Theme.releaseDependencies(plugin.representation.structure.themes, { structure: structure }, params);
},
interpolate: function (src, tar, t) {
if (src.colorTheme.name !== 'uniform' || tar.colorTheme.name !== 'uniform') {
return t <= 0.5 ? src : tar;
}
var from = src.colorTheme.params.value, to = tar.colorTheme.params.value;
var value = Color.interpolate(from, to, t);
return {
type: t <= 0.5 ? src.type : tar.type,
colorTheme: { name: 'uniform', params: { value: value } },
sizeTheme: t <= 0.5 ? src.sizeTheme : tar.sizeTheme,
};
}
});
var UnwindStructureAssemblyRepresentation3D = PluginStateTransform.BuiltIn({
name: 'unwind-structure-assembly-representation-3d',
display: 'Unwind Assembly 3D Representation',
from: SO.Molecule.Structure.Representation3D,
to: SO.Molecule.Structure.Representation3DState,
params: { t: PD.Numeric(0, { min: 0, max: 1, step: 0.01 }) }
})({
canAutoUpdate: function () {
return true;
},
apply: function (_a) {
var a = _a.a, params = _a.params;
var structure = a.data.sourceData;
var unitTransforms = new StructureUnitTransforms(structure);
unwindStructureAssembly(structure, unitTransforms, params.t);
return new SO.Molecule.Structure.Representation3DState({
state: { unitTransforms: unitTransforms },
initialState: { unitTransforms: new StructureUnitTransforms(structure) },
info: structure,
repr: a.data.repr
}, { label: "Unwind T = " + params.t.toFixed(2) });
},
update: function (_a) {
var a = _a.a, b = _a.b, newParams = _a.newParams, oldParams = _a.oldParams;
var structure = b.data.info;
if (a.data.sourceData !== structure)
return StateTransformer.UpdateResult.Recreate;
if (a.data.repr !== b.data.repr)
return StateTransformer.UpdateResult.Recreate;
if (oldParams.t === newParams.t)
return StateTransformer.UpdateResult.Unchanged;
var unitTransforms = b.data.state.unitTransforms;
unwindStructureAssembly(structure, unitTransforms, newParams.t);
b.label = "Unwind T = " + newParams.t.toFixed(2);
b.data.repr = a.data.repr;
return StateTransformer.UpdateResult.Updated;
}
});
var ExplodeStructureRepresentation3D = PluginStateTransform.BuiltIn({
name: 'explode-structure-representation-3d',
display: 'Explode 3D Representation',
from: SO.Molecule.Structure.Representation3D,
to: SO.Molecule.Structure.Representation3DState,
params: { t: PD.Numeric(0, { min: 0, max: 1, step: 0.01 }) }
})({
canAutoUpdate: function () {
return true;
},
apply: function (_a) {
var a = _a.a, params = _a.params;
var structure = a.data.sourceData;
var unitTransforms = new StructureUnitTransforms(structure);
explodeStructure(structure, unitTransforms, params.t, structure.root.boundary.sphere);
return new SO.Molecule.Structure.Representation3DState({
state: { unitTransforms: unitTransforms },
initialState: { unitTransforms: new StructureUnitTransforms(structure) },
info: structure,
repr: a.data.repr
}, { label: "Explode T = " + params.t.toFixed(2) });
},
update: function (_a) {
var a = _a.a, b = _a.b, newParams = _a.newParams, oldParams = _a.oldParams;
var structure = a.data.sourceData;
if (b.data.info !== structure)
return StateTransformer.UpdateResult.Recreate;
if (a.data.repr !== b.data.repr)
return StateTransformer.UpdateResult.Recreate;
if (oldParams.t === newParams.t)
return StateTransformer.UpdateResult.Unchanged;
var unitTransforms = b.data.state.unitTransforms;
explodeStructure(structure, unitTransforms, newParams.t, structure.root.boundary.sphere);
b.label = "Explode T = " + newParams.t.toFixed(2);
b.data.repr = a.data.repr;
return StateTransformer.UpdateResult.Updated;
}
});
var SpinStructureRepresentation3D = PluginStateTransform.BuiltIn({
name: 'spin-structure-representation-3d',
display: 'Spin 3D Representation',
from: SO.Molecule.Structure.Representation3D,
to: SO.Molecule.Structure.Representation3DState,
params: __assign({ t: PD.Numeric(0, { min: 0, max: 1, step: 0.01 }) }, SpinStructureParams)
})({
canAutoUpdate: function () {
return true;
},
apply: function (_a) {
var a = _a.a, params = _a.params;
var structure = a.data.sourceData;
var unitTransforms = new StructureUnitTransforms(structure);
var _b = getSpinStructureAxisAndOrigin(structure.root, params), axis = _b.axis, origin = _b.origin;
spinStructure(structure, unitTransforms, params.t, axis, origin);
return new SO.Molecule.Structure.Representation3DState({
state: { unitTransforms: unitTransforms },
initialState: { unitTransforms: new StructureUnitTransforms(structure) },
info: structure,
repr: a.data.repr
}, { label: "Spin T = " + params.t.toFixed(2) });
},
update: function (_a) {
var a = _a.a, b = _a.b, newParams = _a.newParams, oldParams = _a.oldParams;
var structure = a.data.sourceData;
if (b.data.info !== structure)
return StateTransformer.UpdateResult.Recreate;
if (a.data.repr !== b.data.repr)
return StateTransformer.UpdateResult.Recreate;
if (oldParams.t === newParams.t && oldParams.axis === newParams.axis && oldParams.origin === newParams.origin)
return StateTransformer.UpdateResult.Unchanged;
var unitTransforms = b.data.state.unitTransforms;
var _b = getSpinStructureAxisAndOrigin(structure.root, newParams), axis = _b.axis, origin = _b.origin;
spinStructure(structure, unitTransforms, newParams.t, axis, origin);
b.label = "Spin T = " + newParams.t.toFixed(2);
b.data.repr = a.data.repr;
return StateTransformer.UpdateResult.Updated;
}
});
var OverpaintStructureRepresentation3DFromScript = PluginStateTransform.BuiltIn({
name: 'overpaint-structure-representation-3d-from-script',
display: 'Overpaint 3D Representation',
from: SO.Molecule.Structure.Representation3D,
to: SO.Molecule.Structure.Representation3DState,
params: function () { return ({
layers: PD.ObjectList({
script: PD.Script(Script('(sel.atom.all)', 'mol-script')),
color: PD.Color(ColorNames.blueviolet),
clear: PD.Boolean(false)
}, function (e) { return "" + (e.clear ? 'Clear' : Color.toRgbString(e.color)); }, {
defaultValue: [{
script: Script('(sel.atom.all)', 'mol-script'),
color: ColorNames.blueviolet,
clear: false
}]
}),
}); }
})({
canAutoUpdate: function () {
return true;
},
apply: function (_a) {
var a = _a.a, params = _a.params;
var structure = a.data.sourceData;
var overpaint = Overpaint.ofScript(params.layers, structure);
return new SO.Molecule.Structure.Representation3DState({
state: { overpaint: overpaint },
initialState: { overpaint: Overpaint.Empty },
info: structure,
repr: a.data.repr
}, { label: "Overpaint (" + overpaint.layers.length + " Layers)" });
},
update: function (_a) {
var a = _a.a, b = _a.b, newParams = _a.newParams, oldParams = _a.oldParams;
var oldStructure = b.data.info;
var newStructure = a.data.sourceData;
if (newStructure !== oldStructure)
return StateTransformer.UpdateResult.Recreate;
if (a.data.repr !== b.data.repr)
return StateTransformer.UpdateResult.Recreate;
var oldOverpaint = b.data.state.overpaint;
var newOverpaint = Overpaint.ofScript(newParams.layers, newStructure);
if (Overpaint.areEqual(oldOverpaint, newOverpaint))
return StateTransformer.UpdateResult.Unchanged;
b.data.state.overpaint = newOverpaint;
b.data.repr = a.data.repr;
b.label = "Overpaint (" + newOverpaint.layers.length + " Layers)";
return StateTransformer.UpdateResult.Updated;
}
});
var OverpaintStructureRepresentation3DFromBundle = PluginStateTransform.BuiltIn({
name: 'overpaint-structure-representation-3d-from-bundle',
display: 'Overpaint 3D Representation',
from: SO.Molecule.Structure.Representation3D,
to: SO.Molecule.Structure.Representation3DState,
params: function () { return ({
layers: PD.ObjectList({
bundle: PD.Value(StructureElement.Bundle.Empty),
color: PD.Color(ColorNames.blueviolet),
clear: PD.Boolean(false)
}, function (e) { return "" + (e.clear ? 'Clear' : Color.toRgbString(e.color)); }, {
defaultValue: [{
bundle: StructureElement.Bundle.Empty,
color: ColorNames.blueviolet,
clear: false
}],
isHidden: true
}),
}); }
})({
canAutoUpdate: function () {
return true;
},
apply: function (_a) {
var a = _a.a, params = _a.params;
var structure = a.data.sourceData;
var overpaint = Overpaint.ofBundle(params.layers, structure);
return new SO.Molecule.Structure.Representation3DState({
state: { overpaint: overpaint },
initialState: { overpaint: Overpaint.Empty },
info: structure,
repr: a.data.repr
}, { label: "Overpaint (" + overpaint.layers.length + " Layers)" });
},
update: function (_a) {
var a = _a.a, b = _a.b, newParams = _a.newParams, oldParams = _a.oldParams;
var oldStructure = b.data.info;
var newStructure = a.data.sourceData;
if (newStructure !== oldStructure)
return StateTransformer.UpdateResult.Recreate;
if (a.data.repr !== b.data.repr)
return StateTransformer.UpdateResult.Recreate;
var oldOverpaint = b.data.state.overpaint;
var newOverpaint = Overpaint.ofBundle(newParams.layers, newStructure);
if (Overpaint.areEqual(oldOverpaint, newOverpaint))
return StateTransformer.UpdateResult.Unchanged;
b.data.state.overpaint = newOverpaint;
b.data.repr = a.data.repr;
b.label = "Overpaint (" + newOverpaint.layers.length + " Layers)";
return StateTransformer.UpdateResult.Updated;
}
});
var 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: function () { return ({
layers: PD.ObjectList({
script: PD.Script(Script('(sel.atom.all)', 'mol-script')),
value: PD.Numeric(0.5, { min: 0, max: 1, step: 0.01 }, { label: 'Transparency' }),
}, function (e) { return "Transparency (" + e.value + ")"; }, {
defaultValue: [{
script: Script('(sel.atom.all)', 'mol-script'),
value: 0.5,
}]
})
}); }
})({
canAutoUpdate: function () {
return true;
},
apply: function (_a) {
var a = _a.a, params = _a.params;
var structure = a.data.sourceData;
var transparency = Transparency.ofScript(params.layers, structure);
return new SO.Molecule.Structure.Representation3DState({
state: { transparency: transparency },
initialState: { transparency: Transparency.Empty },
info: structure,
repr: a.data.repr
}, { label: "Transparency (" + transparency.layers.length + " Layers)" });
},
update: function (_a) {
var a = _a.a, b = _a.b, newParams = _a.newParams, oldParams = _a.oldParams;
var structure = b.data.info;
if (a.data.sourceData !== structure)
return StateTransformer.UpdateResult.Recreate;
if (a.data.repr !== b.data.repr)
return StateTransformer.UpdateResult.Recreate;
var oldTransparency = b.data.state.transparency;
var newTransparency = Transparency.ofScript(newParams.layers, structure);
if (Transparency.areEqual(oldTransparency, newTransparency))
return StateTransformer.UpdateResult.Unchanged;
b.data.state.transparency = newTransparency;
b.data.repr = a.data.repr;
b.label = "Transparency (" + newTransparency.layers.length + " Layers)";
return StateTransformer.UpdateResult.Updated;
}
});
var 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: function () { return ({
layers: PD.ObjectList({
bundle: PD.Value(StructureElement.Bundle.Empty),
value: PD.Numeric(0.5, { min: 0, max: 1, step: 0.01 }, { label: 'Transparency' }),
}, function (e) { return "Transparency (" + e.value + ")"; }, {
defaultValue: [{
bundle: StructureElement.Bundle.Empty,
value: 0.5,
}],
isHidden: true
})
}); }
})({
canAutoUpdate: function () {
return true;
},
apply: function (_a) {
var a = _a.a, params = _a.params;
var structure = a.data.sourceData;
var transparency = Transparency.ofBundle(params.layers, structure);
return new SO.Molecule.Structure.Representation3DState({
state: { transparency: transparency },
initialState: { transparency: Transparency.Empty },
info: structure,
repr: a.data.repr
}, { label: "Transparency (" + transparency.layers.length + " Layers)" });
},
update: function (_a) {
var a = _a.a, b = _a.b, newParams = _a.newParams, oldParams = _a.oldParams;
var structure = b.data.info;
if (a.data.sourceData !== structure)
return StateTransformer.UpdateResult.Recreate;
if (a.data.repr !== b.data.repr)
return StateTransformer.UpdateResult.Recreate;
var oldTransparency = b.data.state.transparency;
var newTransparency = Transparency.ofBundle(newParams.layers, structure);
if (Transparency.areEqual(oldTransparency, newTransparency))
return StateTransformer.UpdateResult.Unchanged;
b.data.state.transparency = newTransparency;
b.data.repr = a.data.repr;
b.label = "Transparency (" + newTransparency.layers.length + " Layers)";
return StateTransformer.UpdateResult.Updated;
}
});
var ClippingStructureRepresentation3DFromScript = PluginStateTransform.BuiltIn({
name: 'clipping-structure-representation-3d-from-script',
display: 'Clipping 3D Representation',
from: SO.Molecule.Structure.Representation3D,
to: SO.Molecule.Structure.Representation3DState,
params: function () { return ({
layers: PD.ObjectList({
script: PD.Script(Script('(sel.atom.all)', 'mol-script')),
groups: PD.Converted(function (g) { return Clipping.Groups.toNames(g); }, function (n) { return Clipping.Groups.fromNames(n); }, PD.MultiSelect(ObjectKeys(Clipping.Groups.Names), PD.objectToOptions(Clipping.Groups.Names))),
}, function (e) { return Clipping.Groups.toNames(e.groups).length + " group(s)"; }, {
defaultValue: [{
script: Script('(sel.atom.all)', 'mol-script'),
groups: 0 /* None */,
}]
}),
}); }
})({
canAutoUpdate: function () {
return true;
},
apply: function (_a) {
var a = _a.a, params = _a.params;
var structure = a.data.sourceData;
var clipping = Clipping.ofScript(params.layers, structure);
return new SO.Molecule.Structure.Representation3DState({
state: { clipping: clipping },
initialState: { clipping: Clipping.Empty },
info: structure,
repr: a.data.repr
}, { label: "Clipping (" + clipping.layers.length + " Layers)" });
},
update: function (_a) {
var a = _a.a, b = _a.b, newParams = _a.newParams, oldParams = _a.oldParams;
var structure = b.data.info;
if (a.data.sourceData !== structure)
return StateTransformer.UpdateResult.Recreate;
if (a.data.repr !== b.data.repr)
return StateTransformer.UpdateResult.Recreate;
var oldClipping = b.data.state.clipping;
var newClipping = Clipping.ofScript(newParams.layers, structure);
if (Clipping.areEqual(oldClipping, newClipping))
return StateTransformer.UpdateResult.Unchanged;
b.data.state.clipping = newClipping;
b.data.repr = a.data.repr;
b.label = "Clipping (" + newClipping.layers.length + " Layers)";
return StateTransformer.UpdateResult.Updated;
}
});
var ClippingStructureRepresentation3DFromBundle = PluginStateTransform.BuiltIn({
name: 'clipping-structure-representation-3d-from-bundle',
display: 'Clipping 3D Representation',
from: SO.Molecule.Structure.Representation3D,
to: SO.Molecule.Structure.Representation3DState,
params: function () { return ({
layers: PD.ObjectList({
bundle: PD.Value(StructureElement.Bundle.Empty),
groups: PD.Converted(function (g) { return Clipping.Groups.toNames(g); }, function (n) { return Clipping.Groups.fromNames(n); }, PD.MultiSelect(ObjectKeys(Clipping.Groups.Names), PD.objectToOptions(Clipping.Groups.Names))),
}, function (e) { return Clipping.Groups.toNames(e.groups).length + " group(s)"; }, {
defaultValue: [{
bundle: StructureElement.Bundle.Empty,
groups: 0 /* None */,
}],
isHidden: true
}),
}); }
})({
canAutoUpdate: function () {
return true;
},
apply: function (_a) {
var a = _a.a, params = _a.params;
var structure = a.data.sourceData;
var clipping = Clipping.ofBundle(params.layers, structure);
return new SO.Molecule.Structure.Representation3DState({
state: { clipping: clipping },
initialState: { clipping: Clipping.Empty },
info: structure,
repr: a.data.repr
}, { label: "Clipping (" + clipping.layers.length + " Layers)" });
},
update: function (_a) {
var a = _a.a, b = _a.b, newParams = _a.newParams, oldParams = _a.oldParams;
var structure = b.data.info;
if (a.data.sourceData !== structure)
return StateTransformer.UpdateResult.Recreate;
if (a.data.repr !== b.data.repr)
return StateTransformer.UpdateResult.Recreate;
var oldClipping = b.data.state.clipping;
var newClipping = Clipping.ofBundle(newParams.layers, structure);
if (Clipping.areEqual(oldClipping, newClipping))
return StateTransformer.UpdateResult.Unchanged;
b.data.state.clipping = newClipping;
b.data.repr = a.data.repr;
b.label = "Clipping (" + newClipping.layers.length + " Layers)";
return StateTransformer.UpdateResult.Updated;
}
});
//
export var VolumeRepresentation3DHelpers;
(function (VolumeRepresentation3DHelpers) {
function getDefaultParams(ctx, name, volume, volumeParams) {
var type = ctx.representation.volume.registry.get(name);
var themeDataCtx = { volume: volume };
var colorParams = ctx.representation.volume.themes.colorThemeRegistry.get(type.defaultColorTheme.name).getParams(themeDataCtx);
var sizeParams = ctx.representation.volume.themes.sizeThemeRegistry.get(type.defaultSizeTheme.name).getParams(themeDataCtx);
var volumeDefaultParams = PD.getDefaultValues(type.getParams(ctx.representation.volume.themes, volume));
return ({
type: { name: name, params: volumeParams ? __assign(__assign({}, volumeDefaultParams), volumeParams) : volumeDefaultParams },
colorTheme: { name: type.defaultColorTheme.name, params: PD.getDefaultValues(colorParams) },
sizeTheme: { name: type.defaultSizeTheme.name, params: PD.getDefaultValues(sizeParams) }
});
}
VolumeRepresentation3DHelpers.getDefaultParams = getDefaultParams;
function getDefaultParamsStatic(ctx, name, volumeParams, colorName, colorParams, sizeName, sizeParams) {
var type = ctx.representation.volume.registry.get(name);
var colorType = ctx.representation.volume.themes.colorThemeRegistry.get(colorName || type.defaultColorTheme.name);
var sizeType = ctx.representation.volume.themes.sizeThemeRegistry.get(sizeName || type.defaultSizeTheme.name);
return ({
type: { name: name, params: volumeParams ? __assign(__assign({}, type.defaultValues), volumeParams) : type.defaultValues },
colorTheme: { name: type.defaultColorTheme.name, params: colorParams ? __assign(__assign({}, colorType.defaultValues), colorParams) : colorType.defaultValues },
sizeTheme: { name: type.defaultSizeTheme.name, params: sizeParams ? __assign(__assign({}, sizeType.defaultValues), sizeParams) : sizeType.defaultValues }
});
}
VolumeRepresentation3DHelpers.getDefaultParamsStatic = getDefaultParamsStatic;
function getDescription(props) {
var _a, _b, _c, _d;
if (props.isoValue) {
return Volume.IsoValue.toString(props.isoValue);
}
else if ((_b = (_a = props.renderMode) === null || _a === void 0 ? void 0 : _a.params) === null || _b === void 0 ? void 0 : _b.isoValue) {
return Volume.IsoValue.toString((_d = (_c = props.renderMode) === null || _c === void 0 ? void 0 : _c.params) === null || _d === void 0 ? void 0 : _d.isoValue);
}
}
VolumeRepresentation3DHelpers.getDescription = getDescription;
})(VolumeRepresentation3DHelpers || (VolumeRepresentation3DHelpers = {}));
var VolumeRepresentation3D = PluginStateTransform.BuiltIn({
name: 'volume-representation-3d',
display: '3D Representation',
from: SO.Volume.Data,
to: SO.Volume.Representation3D,
params: function (a, ctx) {
var _a = ctx.representation.volume, registry = _a.registry, themeCtx = _a.themes;
var type = registry.get(registry.default.name);
if (!a) {
return {
type: PD.Mapped(registry.default.name, registry.types, function (name) { return PD.Group(registry.get(name).getParams(themeCtx, Volume.One)); }),
colorTheme: PD.Mapped(type.defaultColorTheme.name, themeCtx.colorThemeRegistry.types, function (name) { return PD.Group(themeCtx.colorThemeRegistry.get(name).getParams({ volume: Volume.One })); }),
sizeTheme: PD.Mapped(type.defaultSizeTheme.name, themeCtx.sizeThemeRegistry.types, function (name) { return PD.Group(themeCtx.sizeThemeRegistry.get(name).getParams({ volume: Volume.One })); })
};
}
var dataCtx = { volume: a.data };
return ({
type: PD.Mapped(registry.default.name, registry.types, function (name) { return PD.Group(registry.get(name).getParams(themeCtx, a.data)); }),
colorTheme: PD.Mapped(type.defaultColorTheme.name, themeCtx.colorThemeRegistry.getApplicableTypes(dataCtx), function (name) { return PD.Group(themeCtx.colorThemeRegistry.get(name).getParams(dataCtx)); }),
sizeTheme: PD.Mapped(type.defaultSizeTheme.name, themeCtx.sizeThemeRegistry.types, function (name) { return PD.Group(themeCtx.sizeThemeRegistry.get(name).getParams(dataCtx)); })
});
}
})({
canAutoUpdate: function (_a) {
var oldParams = _a.oldParams, newParams = _a.newParams;
return oldParams.type.name === newParams.type.name;
},
apply: function (_a, plugin) {
var _this = this;
var a = _a.a, params = _a.params;
return Task.create('Volume Representation', function (ctx) { return __awaiter(_this, void 0, void 0, function () {
var propertyCtx, provider, repr, props;
var _a;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
propertyCtx = { runtime: ctx, assetManager: plugin.managers.asset };
provider = plugin.representation.volume.registry.get(params.type.name);
if (!provider.ensureCustomProperties) return [3 /*break*/, 2];
return [4 /*yield*/, provider.ensureCustomProperties.attach(propertyCtx, a.data)];
case 1:
_b.sent();
_b.label = 2;
case 2:
repr = provider.factory(__assign({ webgl: (_a = plugin.canvas3d) === null || _a === void 0 ? void 0 : _a.webgl }, plugin.representation.volume.themes), provider.getParams);
repr.setTheme(Theme.create(plugin.representation.volume.themes, { volume: a.data }, params));
props = params.type.params || {};
return [4 /*yield*/, repr.createOrUpdate(props, a.data).runInContext(ctx)];
case 3:
_b.sent();
return [2 /*return*/, new SO.Volume.Representation3D({ repr: repr, sourceData: a.data }, { label: provider.label, description: VolumeRepresentation3DHelpers.getDescription(props) })];
}
});
}); });
},
update: function (_a, plugin) {
var _this = this;
var a = _a.a, b = _a.b, oldParams = _a.oldParams, newParams = _a.newParams;
return Task.create('Volume Representation', function (ctx) { return __awaiter(_this, void 0, void 0, function () {
var oldProvider, props;
var _a;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
if (newParams.type.name !== oldParams.type.name) {
oldProvider = plugin.representation.volume.registry.get(oldParams.type.name);
(_a = oldProvider.ensureCustomProperties) === null || _a === void 0 ? void 0 : _a.detach(a.data);
return [2 /*return*/, StateTransformer.UpdateResult.Recreate];
}
props = __assign(__assign({}, b.data.repr.props), newParams.type.params);
b.data.repr.setTheme(Theme.create(plugin.representation.volume.themes, { volume: a.data }, newParams));
return [4 /*yield*/, b.data.repr.createOrUpdate(props, a.data).runInContext(ctx)];
case 1:
_b.sent();
b.data.sourceData = a.data;
b.description = VolumeRepresentation3DHelpers.getDescription(props);
return [2 /*return*/, StateTransformer.UpdateResult.Updated];
}
});
}); });
}
});
//
export { ShapeRepresentation3D };
var ShapeRepresentation3D = PluginStateTransform.BuiltIn({
name: 'shape-representation-3d',
display: '3D Representation',
from: SO.Shape.Provider,
to: SO.Shape.Representation3D,
params: function (a, ctx) {
return a ? a.data.params : BaseGeometry.Params;
}
})({
canAutoUpdate: function () {
return true;
},
apply: function (_a, plugin) {
var _this = this;
var a = _a.a, params = _a.params;
return Task.create('Shape Representation', function (ctx) { return __awaiter(_this, void 0, void 0, function () {
var props, repr;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
props = __assign(__assign({}, PD.getDefaultValues(a.data.params)), params);
repr = ShapeRepresentation(a.data.getShape, a.data.geometryUtils);
return [4 /*yield*/, repr.createOrUpdate(props, a.data.data).runInContext(ctx)];
case 1:
_a.sent();
return [2 /*return*/, new SO.Shape.Representation3D({ repr: repr, sourceData: a.data }, { label: a.data.label })];
}
});
}); });
},
update: function (_a, plugin) {
var _this = this;
var a = _a.a, b = _a.b, oldParams = _a.oldParams, newParams = _a.newParams;
return Task.create('Shape Representation', function (ctx) { return __awaiter(_this, void 0, void 0, function () {
var props;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
props = __assign(__assign({}, b.data.repr.props), newParams);
return [4 /*yield*/, b.data.repr.createOrUpdate(props, a.data.data).runInContext(ctx)];
case 1:
_a.sent();
b.data.sourceData = a.data;
return [2 /*return*/, StateTransformer.UpdateResult.Updated];
}
});
}); });
}
});
export { ModelUnitcell3D };
var ModelUnitcell3D = PluginStateTransform.BuiltIn({
name: 'model-unitcell-3d',
display: 'Model Unit Cell',
from: SO.Molecule.Model,
to: SO.Shape.Representation3D,
params: function () { return (__assign({}, UnitcellParams)); }
})({
isApplicable: function (a) { return !!ModelSymmetry.Provider.get(a.data); },
canAutoUpdate: function (_a) {
var oldParams = _a.oldParams, newParams = _a.newParams;
return true;
},
apply: function (_a, plugin) {
var _this = this;
var a = _a.a, params = _a.params;
return Task.create('Model Unit Cell', function (ctx) { return __awaiter(_this, void 0, void 0, function () {
var symmetry, data, repr;
var _a;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
symmetry = ModelSymmetry.Provider.get(a.data);
if (!symmetry)
return [2 /*return*/, StateObject.Null];
data = getUnitcellData(a.data, symmetry, params);
repr = UnitcellRepresentation(__assign({ webgl: (_a = plugin.canvas3d) === null || _a === void 0 ? void 0 : _a.webgl }, plugin.representation.structure.themes), function () { return UnitcellParams; });
return [4 /*yield*/, repr.createOrUpdate(params, data).runInContext(ctx)];
case 1:
_b.sent();
return [2 /*return*/, new SO.Shape.Representation3D({ repr: repr, sourceData: data }, { label: "Unit Cell", description: symmetry.spacegroup.name })];
}
});
}); });
},
update: function (_a) {
var _this = this;
var a = _a.a, b = _a.b, newParams = _a.newParams;
return Task.create('Model Unit Cell', function (ctx) { return __awaiter(_this, void 0, void 0, function () {
var symmetry, props, data;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
symmetry = ModelSymmetry.Provider.get(a.data);
if (!symmetry)
return [2 /*return*/, StateTransformer.UpdateResult.Null];
props = __assign(__assign({}, b.data.repr.props), newParams);
data = getUnitcellData(a.data, symmetry, props);
return [4 /*yield*/, b.data.repr.createOrUpdate(props, data).runInContext(ctx)];
case 1:
_a.sent();
b.data.sourceData = data;
return [2 /*return*/, StateTransformer.UpdateResult.Updated];
}
});
}); });
}
});
export { StructureBoundingBox3D };
var StructureBoundingBox3D = PluginStateTransform.BuiltIn({
name: 'structure-bounding-box-3d',
display: 'Bounding Box',
from: SO.Molecule.Structure,
to: SO.Shape.Representation3D,
params: __assign({ radius: PD.Numeric(0.05, { min: 0.01, max: 4, step: 0.01 }, { isEssential: true }), color: PD.Color(ColorNames.red, { isEssential: true }) }, Mesh.Params)
})({
canAutoUpdate: function () {
return true;
},
apply: function (_a, plugin) {
var _this = this;
var a = _a.a, params = _a.params;
return Task.create('Bounding Box', function (ctx) { return __awaiter(_this, void 0, void 0, function () {
var repr;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
repr = ShapeRepresentation(function (_, data, __, shape) {
var mesh = getBoxMesh(data.box, data.radius, shape === null || shape === void 0 ? void 0 : shape.geometry);
return Shape.create('Bouding Box', data, mesh, function () { return data.color; }, function () { return 1; }, function () { return 'Bounding Box'; });
}, Mesh.Utils);
return [4 /*yield*/, repr.createOrUpdate(params, { box: a.data.boundary.box, radius: params.radius, color: params.color }).runInContext(ctx)];
case 1:
_a.sent();
return [2 /*return*/, new SO.Shape.Representation3D({ repr: repr, sourceData: a.data }, { label: "Bounding Box" })];
}
});
}); });
},
update: function (_a, plugin) {
var _this = this;
var a = _a.a, b = _a.b, oldParams = _a.oldParams, newParams = _a.newParams;
return Task.create('Bounding Box', function (ctx) { return __awaiter(_this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, b.data.repr.createOrUpdate(newParams, { box: a.data.boundary.box, radius: newParams.radius, color: newParams.color }).runInContext(ctx)];
case 1:
_a.sent();
b.data.sourceData = a.data;
return [2 /*return*/, StateTransformer.UpdateResult.Updated];
}
});
}); });
}
});
export { StructureSelectionsDistance3D };
var StructureSelectionsDistance3D = PluginStateTransform.BuiltIn({
name: 'structure-selections-distance-3d',
display: '3D Distance',
from: SO.Molecule.Structure.Selections,
to: SO.Shape.Representation3D,
params: function () { return (__assign({}, DistanceParams)); }
})({
canAutoUpdate: function (_a) {
var oldParams = _a.oldParams, newParams = _a.newParams;
return true;
},
apply: function (_a, plugin) {
var _this = this;
var a = _a.a, params = _a.params;
return Task.create('Structure Distance', function (ctx) { return __awaiter(_this, void 0, void 0, function () {
var data, repr;
var _a;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
data = getDistanceDataFromStructureSelections(a.data);
repr = DistanceRepresentation(__assign({ webgl: (_a = plugin.canvas3d) === null || _a === void 0 ? void 0 : _a.webgl }, plugin.representation.structure.themes), function () { return DistanceParams; });
return [4 /*yield*/, repr.createOrUpdate(params, data).runInContext(ctx)];
case 1:
_b.sent();
return [2 /*return*/, new SO.Shape.Representation3D({ repr: repr, sourceData: data }, { label: "Distance" })];
}
});
}); });
},
update: function (_a, plugin) {
var _this = this;
var a = _a.a, b = _a.b, oldParams = _a.oldParams, newParams = _a.newParams;
return Task.create('Structure Distance', function (ctx) { return __awaiter(_this, void 0, void 0, function () {
var props, data;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
props = __assign(__assign({}, b.data.repr.props), newParams);
data = getDistanceDataFromStructureSelections(a.data);
return [4 /*yield*/, b.data.repr.createOrUpdate(props, data).runInContext(ctx)];
case 1:
_a.sent();
b.data.sourceData = data;
return [2 /*return*/, StateTransformer.UpdateResult.Updated];
}
});
}); });
},
});
export { StructureSelectionsAngle3D };
var StructureSelectionsAngle3D = PluginStateTransform.BuiltIn({
name: 'structure-selections-angle-3d',
display: '3D Angle',
from: SO.Molecule.Structure.Selections,
to: SO.Shape.Representation3D,
params: function () { return (__assign({}, AngleParams)); }
})({
canAutoUpdate: function (_a) {
var oldParams = _a.oldParams, newParams = _a.newParams;
return true;
},
apply: functi