molstar
Version:
A comprehensive macromolecular library.
645 lines (644 loc) • 31.4 kB
JavaScript
"use strict";
/**
* Copyright (c) 2023-2025 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.MesoscaleState = exports.MesoscaleStateObject = exports.MesoscaleStateParams = exports.MesoscaleGroup = exports.MesoscaleGroupObject = exports.MesoscaleGroupParams = exports.SimpleClipParams = exports.LodParams = exports.StyleParams = exports.PatternParams = exports.celShaded = exports.EmissiveParams = exports.OpacityParams = exports.IllustrativeParams = exports.DimLightness = exports.LightnessParams = exports.RootParams = exports.ColorValueParam = exports.ColorParams = void 0;
exports.getDistinctGroupColors = getDistinctGroupColors;
exports.getDistinctBaseColors = getDistinctBaseColors;
exports.getClipObjects = getClipObjects;
exports.createClipMapping = createClipMapping;
exports.getMesoscaleGroupParams = getMesoscaleGroupParams;
exports.getLodLevels = getLodLevels;
exports.getGraphicsModeProps = getGraphicsModeProps;
exports.setGraphicsCanvas3DProps = setGraphicsCanvas3DProps;
exports.getRoots = getRoots;
exports.getGroups = getGroups;
exports.getAllGroups = getAllGroups;
exports.getAllLeafGroups = getAllLeafGroups;
exports.getEntities = getEntities;
exports.getFilteredEntities = getFilteredEntities;
exports.getAllEntities = getAllEntities;
exports.getAllFilteredEntities = getAllFilteredEntities;
exports.getEveryEntity = getEveryEntity;
exports.getEntityLabel = getEntityLabel;
exports.getCellDescription = getCellDescription;
exports.getEntityDescription = getEntityDescription;
exports.updateStyle = updateStyle;
exports.updateColors = updateColors;
exports.expandAllGroups = expandAllGroups;
const objects_1 = require("../../../mol-plugin-state/objects");
const param_definition_1 = require("../../../mol-util/param-definition");
const mol_task_1 = require("../../../mol-task");
const color_1 = require("../../../mol-util/color");
const spheres_1 = require("../../../mol-geo/geometry/spheres/spheres");
const clip_1 = require("../../../mol-util/clip");
const string_1 = require("../../../mol-util/string");
const linear_algebra_1 = require("../../../mol-math/linear-algebra");
const param_mapping_1 = require("../../../mol-util/param-mapping");
const distinct_1 = require("../../../mol-util/color/distinct");
const hcl_1 = require("../../../mol-util/color/spaces/hcl");
const mol_state_1 = require("../../../mol-state");
const representation_1 = require("../../../mol-plugin-state/transforms/representation");
const type_helpers_1 = require("../../../mol-util/type-helpers");
const interpolate_1 = require("../../../mol-math/interpolate");
const material_1 = require("../../../mol-util/material");
function getHueRange(hue, variability) {
let min = hue - variability;
const minOverflow = (min < 0 ? -min : 0);
let max = hue + variability;
if (max > 360)
min -= max - 360;
max += minOverflow;
return [Math.max(0, min), Math.min(360, max)];
}
function getGrayscaleColors(count, luminance, variability) {
const out = [];
for (let i = 0; i < count; ++i) {
const l = (0, interpolate_1.saturate)(luminance / 100);
const v = (0, interpolate_1.saturate)(variability / 180) * Math.random();
const s = Math.random() > 0.5 ? 1 : -1;
const d = Math.abs(l + s * v) % 1;
out[i] = color_1.Color.fromNormalizedRgb(d, d, d);
}
return out;
}
function getDistinctGroupColors(count, color, variability, shift, props) {
const hcl = hcl_1.Hcl.fromColor((0, hcl_1.Hcl)(), color);
if (isNaN(hcl[0])) {
return getGrayscaleColors(count, hcl[2], variability);
}
if (count === 1) {
hcl[1] = 65;
hcl[2] = 55;
return [hcl_1.Hcl.toColor(hcl)];
}
const colors = (0, distinct_1.distinctColors)(count, {
hue: getHueRange(hcl[0], variability),
chroma: [30, 100],
luminance: [50, 100],
clusteringStepCount: 0,
minSampleCount: 1000,
sampleCountFactor: 100,
sort: 'none',
...props,
});
if (shift !== 0) {
const offset = Math.floor(shift / 100 * count);
return [...colors.slice(offset), ...colors.slice(0, offset)];
}
else {
return colors;
}
}
const Colors = [0x377eb8, 0xe41a1c, 0x4daf4a, 0x984ea3, 0xff7f00, 0xffff33, 0xa65628, 0xf781bf];
function getDistinctBaseColors(count, shift, props) {
let colors;
if (count <= Colors.length) {
colors = Colors.slice(0, count).map(e => Array.isArray(e) ? e[0] : e);
}
else {
colors = (0, distinct_1.distinctColors)(count, {
hue: [1, 360],
chroma: [25, 100],
luminance: [30, 100],
clusteringStepCount: 0,
minSampleCount: 1000,
sampleCountFactor: 100,
sort: 'none',
...props,
});
}
if (shift !== 0) {
const offset = Math.floor(shift / 100 * count);
return [...colors.slice(offset), ...colors.slice(0, offset)];
}
else {
return colors;
}
}
exports.ColorParams = {
type: param_definition_1.ParamDefinition.Select('generate', param_definition_1.ParamDefinition.arrayToOptions(['generate', 'uniform', 'custom'])),
illustrative: param_definition_1.ParamDefinition.Boolean(false, { description: 'Illustrative style', hideIf: p => p.type === 'custom' }),
value: param_definition_1.ParamDefinition.Color((0, color_1.Color)(0xFFFFFF), { hideIf: p => p.type === 'custom' }),
variability: param_definition_1.ParamDefinition.Numeric(20, { min: 1, max: 180, step: 1 }, { hideIf: p => p.type !== 'generate' }),
shift: param_definition_1.ParamDefinition.Numeric(0, { min: 0, max: 100, step: 1 }, { hideIf: p => !p.type.includes('generate') }),
lightness: param_definition_1.ParamDefinition.Numeric(0, { min: -6, max: 6, step: 0.1 }, { hideIf: p => p.type === 'custom' }),
alpha: param_definition_1.ParamDefinition.Numeric(1, { min: 0, max: 1, step: 0.01 }, { hideIf: p => p.type === 'custom' }),
emissive: param_definition_1.ParamDefinition.Numeric(0, { min: 0, max: 1, step: 0.01 }, { hideIf: p => p.type === 'custom' }),
};
exports.ColorValueParam = param_definition_1.ParamDefinition.Color((0, color_1.Color)(0xFFFFFF));
exports.RootParams = {
type: param_definition_1.ParamDefinition.Select('custom', param_definition_1.ParamDefinition.arrayToOptions(['group-generate', 'group-uniform', 'generate', 'uniform', 'custom'])),
illustrative: param_definition_1.ParamDefinition.Boolean(false, { description: 'Illustrative style', hideIf: p => p.type === 'custom' }),
value: param_definition_1.ParamDefinition.Color((0, color_1.Color)(0xFFFFFF), { hideIf: p => p.type !== 'uniform' }),
variability: param_definition_1.ParamDefinition.Numeric(20, { min: 1, max: 180, step: 1 }, { hideIf: p => p.type !== 'group-generate' }),
shift: param_definition_1.ParamDefinition.Numeric(0, { min: 0, max: 100, step: 1 }, { hideIf: p => !p.type.includes('generate') }),
lightness: param_definition_1.ParamDefinition.Numeric(0, { min: -6, max: 6, step: 0.1 }, { hideIf: p => p.type === 'custom' }),
alpha: param_definition_1.ParamDefinition.Numeric(1, { min: 0, max: 1, step: 0.01 }, { hideIf: p => p.type === 'custom' }),
emissive: param_definition_1.ParamDefinition.Numeric(0, { min: 0, max: 1, step: 0.01 }, { hideIf: p => p.type === 'custom' }),
};
exports.LightnessParams = {
lightness: param_definition_1.ParamDefinition.Numeric(0, { min: -6, max: 6, step: 0.1 }),
};
exports.DimLightness = 6;
exports.IllustrativeParams = {
illustrative: param_definition_1.ParamDefinition.Boolean(false, { description: 'Illustrative style' }),
};
exports.OpacityParams = {
alpha: param_definition_1.ParamDefinition.Numeric(1, { min: 0, max: 1, step: 0.01 }),
};
exports.EmissiveParams = {
emissive: param_definition_1.ParamDefinition.Numeric(0, { min: 0, max: 1, step: 0.01 }),
};
exports.celShaded = {
celShaded: param_definition_1.ParamDefinition.Boolean(false, { description: 'Cel Shading light for stylized rendering of representations' })
};
exports.PatternParams = {
frequency: param_definition_1.ParamDefinition.Numeric(1, { min: 0, max: 1, step: 0.01 }),
amplitude: param_definition_1.ParamDefinition.Numeric(1, { min: 0, max: 1, step: 0.01 }),
};
exports.StyleParams = {
ignoreLight: param_definition_1.ParamDefinition.Boolean(false, { description: 'Ignore light for stylized rendering of representations' }),
materialStyle: material_1.Material.getParam(),
celShaded: param_definition_1.ParamDefinition.Boolean(false, { description: 'Cel Shading light for stylized rendering of representations' }),
};
exports.LodParams = {
lodLevels: spheres_1.Spheres.Params.lodLevels,
cellSize: spheres_1.Spheres.Params.cellSize,
batchSize: spheres_1.Spheres.Params.batchSize,
approximate: spheres_1.Spheres.Params.approximate,
};
exports.SimpleClipParams = {
type: param_definition_1.ParamDefinition.Select('none', param_definition_1.ParamDefinition.objectToOptions(clip_1.Clip.Type, t => (0, string_1.stringToWords)(t))),
invert: param_definition_1.ParamDefinition.Boolean(false),
position: param_definition_1.ParamDefinition.Group({
x: param_definition_1.ParamDefinition.Numeric(0, { min: -100, max: 100, step: 1 }, { immediateUpdate: true }),
y: param_definition_1.ParamDefinition.Numeric(0, { min: -100, max: 100, step: 1 }, { immediateUpdate: true }),
z: param_definition_1.ParamDefinition.Numeric(0, { min: -100, max: 100, step: 1 }, { immediateUpdate: true }),
}, { hideIf: g => g.type === 'none', isExpanded: true }),
rotation: param_definition_1.ParamDefinition.Group({
axis: param_definition_1.ParamDefinition.Vec3(linear_algebra_1.Vec3.create(1, 0, 0)),
angle: param_definition_1.ParamDefinition.Numeric(0, { min: -180, max: 180, step: 1 }, { immediateUpdate: true }),
}, { hideIf: g => g.type === 'none', isExpanded: true }),
scale: param_definition_1.ParamDefinition.Group({
x: param_definition_1.ParamDefinition.Numeric(100, { min: 0, max: 100, step: 1 }, { immediateUpdate: true }),
y: param_definition_1.ParamDefinition.Numeric(100, { min: 0, max: 100, step: 1 }, { immediateUpdate: true }),
z: param_definition_1.ParamDefinition.Numeric(100, { min: 0, max: 100, step: 1 }, { immediateUpdate: true }),
}, { hideIf: g => ['none', 'plane'].includes(g.type), isExpanded: true }),
};
function getClipObjects(values, boundingSphere) {
const { center, radius } = boundingSphere;
const position = linear_algebra_1.Vec3.clone(center);
linear_algebra_1.Vec3.add(position, position, linear_algebra_1.Vec3.create(radius * values.position.x / 100, radius * values.position.y / 100, radius * values.position.z / 100));
const scale = linear_algebra_1.Vec3.create(values.scale.x, values.scale.y, values.scale.z);
linear_algebra_1.Vec3.scale(scale, scale, 2 * radius / 100);
return [{
type: values.type,
invert: values.invert,
position,
scale,
rotation: values.rotation,
transform: linear_algebra_1.Mat4.identity(),
}];
}
function createClipMapping(node) {
return (0, param_mapping_1.ParamMapping)({
params: exports.SimpleClipParams,
target: (ctx) => {
return node.clipValue;
}
})({
values(props, ctx) {
if (!props || props.objects.length === 0) {
return {
type: 'none',
invert: false,
position: { x: 0, y: 0, z: 0 },
rotation: { axis: linear_algebra_1.Vec3.create(1, 0, 0), angle: 0 },
scale: { x: 100, y: 100, z: 100 },
};
}
const { center, radius } = node.plugin.canvas3d.boundingSphere;
const { invert, position, scale, rotation, type } = props.objects[0];
const p = linear_algebra_1.Vec3.clone(position);
linear_algebra_1.Vec3.sub(p, p, center);
linear_algebra_1.Vec3.scale(p, p, 100 / radius);
linear_algebra_1.Vec3.round(p, p);
const s = linear_algebra_1.Vec3.clone(scale);
linear_algebra_1.Vec3.scale(s, s, 100 / radius / 2);
linear_algebra_1.Vec3.round(s, s);
return {
type,
invert,
position: { x: p[0], y: p[1], z: p[2] },
rotation,
scale: { x: s[0], y: s[1], z: s[2] },
};
},
update: (s, props) => {
if (!props)
return;
const clipObjects = getClipObjects(s, node.plugin.canvas3d.boundingSphere);
props.objects = clipObjects;
},
apply: async (props, ctx) => {
if (props)
node.updateClip(props);
}
});
}
exports.MesoscaleGroupParams = {
root: param_definition_1.ParamDefinition.Value(false, { isHidden: true }),
index: param_definition_1.ParamDefinition.Value(-1, { isHidden: true }),
tag: param_definition_1.ParamDefinition.Value('', { isHidden: true }),
label: param_definition_1.ParamDefinition.Value('', { isHidden: true }),
description: param_definition_1.ParamDefinition.Value('', { isHidden: true }),
hidden: param_definition_1.ParamDefinition.Boolean(false),
color: param_definition_1.ParamDefinition.Group(exports.RootParams),
lightness: param_definition_1.ParamDefinition.Numeric(0, { min: -6, max: 6, step: 0.1 }),
alpha: param_definition_1.ParamDefinition.Numeric(1, { min: 0, max: 1, step: 0.01 }),
emissive: param_definition_1.ParamDefinition.Numeric(0, { min: 0, max: 1, step: 0.01 }),
lod: param_definition_1.ParamDefinition.Group(exports.LodParams),
clip: param_definition_1.ParamDefinition.Group(exports.SimpleClipParams),
};
class MesoscaleGroupObject extends objects_1.PluginStateObject.Create({ name: 'Mesoscale Group', typeClass: 'Object' }) {
}
exports.MesoscaleGroupObject = MesoscaleGroupObject;
exports.MesoscaleGroup = objects_1.PluginStateTransform.BuiltIn({
name: 'mesoscale-group',
display: { name: 'Mesoscale Group' },
from: [objects_1.PluginStateObject.Root, MesoscaleGroupObject],
to: MesoscaleGroupObject,
params: exports.MesoscaleGroupParams,
})({
apply({ a, params }, plugin) {
return mol_task_1.Task.create('Apply Mesoscale Group', async () => {
return new MesoscaleGroupObject({}, { label: params.label, description: params.description });
});
},
});
function getMesoscaleGroupParams(graphicsMode) {
const groupParams = param_definition_1.ParamDefinition.getDefaultValues(exports.MesoscaleGroupParams);
if (graphicsMode === 'custom')
return groupParams;
return {
...groupParams,
lod: {
...groupParams.lod,
...getGraphicsModeProps(graphicsMode),
}
};
}
function getLodLevels(graphicsMode) {
switch (graphicsMode) {
case 'performance':
return [
{ minDistance: 1, maxDistance: 300, overlap: 0, stride: 1, scaleBias: 1 },
{ minDistance: 300, maxDistance: 2000, overlap: 0, stride: 40, scaleBias: 3 },
{ minDistance: 2000, maxDistance: 6000, overlap: 0, stride: 150, scaleBias: 3 },
{ minDistance: 6000, maxDistance: 10000000, overlap: 0, stride: 300, scaleBias: 2.5 },
];
case 'balanced':
return [
{ minDistance: 1, maxDistance: 500, overlap: 0, stride: 1, scaleBias: 1 },
{ minDistance: 500, maxDistance: 2000, overlap: 0, stride: 15, scaleBias: 3 },
{ minDistance: 2000, maxDistance: 6000, overlap: 0, stride: 70, scaleBias: 2.7 },
{ minDistance: 6000, maxDistance: 10000000, overlap: 0, stride: 200, scaleBias: 2.5 },
];
case 'quality':
return [
{ minDistance: 1, maxDistance: 1000, overlap: 0, stride: 1, scaleBias: 1 },
{ minDistance: 1000, maxDistance: 4000, overlap: 0, stride: 10, scaleBias: 3 },
{ minDistance: 4000, maxDistance: 10000, overlap: 0, stride: 50, scaleBias: 2.7 },
{ minDistance: 10000, maxDistance: 10000000, overlap: 0, stride: 200, scaleBias: 2.3 },
];
case 'ultra':
return [
{ minDistance: 1, maxDistance: 5000, overlap: 0, stride: 1, scaleBias: 1 },
{ minDistance: 5000, maxDistance: 10000, overlap: 0, stride: 10, scaleBias: 3 },
{ minDistance: 10000, maxDistance: 30000, overlap: 0, stride: 50, scaleBias: 2.5 },
{ minDistance: 30000, maxDistance: 10000000, overlap: 0, stride: 200, scaleBias: 2 },
];
default:
(0, type_helpers_1.assertUnreachable)(graphicsMode);
}
}
function getGraphicsModeProps(graphicsMode) {
return {
lodLevels: getLodLevels(graphicsMode),
approximate: graphicsMode !== 'quality' && graphicsMode !== 'ultra',
alphaThickness: graphicsMode === 'performance' ? 15 : 12,
};
}
function setGraphicsCanvas3DProps(ctx, graphics) {
var _a, _b;
const pixelScale = graphics === 'balanced' ? 0.75
: graphics === 'performance' ? 0.5 : 1;
(_a = ctx.canvas3dContext) === null || _a === void 0 ? void 0 : _a.setProps({ pixelScale });
(_b = ctx.canvas3d) === null || _b === void 0 ? void 0 : _b.setProps({
postprocessing: {
sharpening: pixelScale < 1 ? {
name: 'on',
params: { sharpness: 0.5, denoise: true }
} : { name: 'off', params: {} }
}
});
}
//
exports.MesoscaleStateParams = {
filter: param_definition_1.ParamDefinition.Value('', { isHidden: true }),
graphics: param_definition_1.ParamDefinition.Select('quality', param_definition_1.ParamDefinition.arrayToOptions(['ultra', 'quality', 'balanced', 'performance', 'custom'])),
description: param_definition_1.ParamDefinition.Value('', { isHidden: true }),
focusInfo: param_definition_1.ParamDefinition.Value('', { isHidden: true }),
link: param_definition_1.ParamDefinition.Value('', { isHidden: true }),
textSizeDescription: param_definition_1.ParamDefinition.Numeric(14, { min: 1, max: 100, step: 1 }, { isHidden: true }),
index: param_definition_1.ParamDefinition.Value(-1, { isHidden: true })
};
class MesoscaleStateObject extends objects_1.PluginStateObject.Create({ name: 'Mesoscale State', typeClass: 'Object' }) {
}
exports.MesoscaleStateObject = MesoscaleStateObject;
const MesoscaleStateTransform = objects_1.PluginStateTransform.BuiltIn({
name: 'mesoscale-state',
display: { name: 'Mesoscale State' },
from: objects_1.PluginStateObject.Root,
to: MesoscaleStateObject,
params: exports.MesoscaleStateParams,
})({
apply({ a, params }, plugin) {
return mol_task_1.Task.create('Apply Mesoscale State', async () => {
return new MesoscaleStateObject(params);
});
},
});
const MesoscaleState = {
async init(ctx) {
const cell = ctx.state.data.selectQ(q => q.ofType(MesoscaleStateObject))[0];
if (cell)
throw new Error('MesoscaleState already initialized');
const customState = ctx.customState;
const state = await ctx.state.data.build().toRoot().apply(MesoscaleStateTransform, {
filter: '',
graphics: customState.graphicsMode,
}).commit();
customState.stateRef = state.ref;
},
get(ctx) {
const ref = this.ref(ctx);
return ctx.state.data.tryGetCellData(ref);
},
async set(ctx, props) {
const ref = this.ref(ctx);
await ctx.state.data.build().to(ref).update(MesoscaleStateTransform, old => Object.assign(old, props)).commit();
},
ref(ctx) {
const ref = ctx.customState.stateRef;
if (!ref)
throw new Error('MesoscaleState not initialized');
return ref;
},
has(ctx) {
const ref = ctx.customState.stateRef || '';
return ctx.state.data.cells.has(ref) ? true : false;
},
};
exports.MesoscaleState = MesoscaleState;
//
function getRoots(plugin) {
const s = plugin.customState;
if (!s.stateCache.roots) {
s.stateCache.roots = plugin.state.data.select(mol_state_1.StateSelection.Generators.rootsOfType(MesoscaleGroupObject));
}
return s.stateCache.roots;
}
function getGroups(plugin, tag) {
const s = plugin.customState;
const k = `groups-${tag || ''}`;
if (!s.stateCache[k]) {
const selector = tag !== undefined
? mol_state_1.StateSelection.Generators.ofTransformer(exports.MesoscaleGroup).withTag(tag)
: mol_state_1.StateSelection.Generators.ofTransformer(exports.MesoscaleGroup);
s.stateCache[k] = plugin.state.data.select(selector);
}
return s.stateCache[k];
}
function _getAllGroups(plugin, tag, list) {
var _a;
const groups = getGroups(plugin, tag);
list.push(...groups);
for (const g of groups) {
_getAllGroups(plugin, (_a = g.params) === null || _a === void 0 ? void 0 : _a.values.tag, list);
}
return list;
}
function getAllGroups(plugin, tag) {
return _getAllGroups(plugin, tag, []);
}
function getAllLeafGroups(plugin, tag) {
const allGroups = getAllGroups(plugin, tag);
allGroups.sort((a, b) => { var _a, _b; return ((_a = a.params) === null || _a === void 0 ? void 0 : _a.values.index) - ((_b = b.params) === null || _b === void 0 ? void 0 : _b.values.index); });
return allGroups.filter(g => {
var _a;
return getEntities(plugin, (_a = g.params) === null || _a === void 0 ? void 0 : _a.values.tag).length > 0;
});
}
function getEntities(plugin, tag) {
const s = plugin.customState;
const k = `entities-${tag || ''}`;
if (!s.stateCache[k]) {
const structureSelector = tag !== undefined
? mol_state_1.StateSelection.Generators.ofTransformer(representation_1.StructureRepresentation3D).withTag(tag)
: mol_state_1.StateSelection.Generators.ofTransformer(representation_1.StructureRepresentation3D);
const shapeSelector = tag !== undefined
? mol_state_1.StateSelection.Generators.ofTransformer(representation_1.ShapeRepresentation3D).withTag(tag)
: mol_state_1.StateSelection.Generators.ofTransformer(representation_1.ShapeRepresentation3D);
s.stateCache[k] = [
...plugin.state.data.select(structureSelector).filter(c => c.obj.data.sourceData.elementCount > 0),
...plugin.state.data.select(shapeSelector),
];
}
return s.stateCache[k];
}
function getFilterMatcher(filter) {
return filter.startsWith('"') && filter.endsWith('"')
? new RegExp(`^${(0, string_1.escapeRegExp)(filter.substring(1, filter.length - 1))}$`, 'g')
: new RegExp((0, string_1.escapeRegExp)(filter), 'gi');
}
function getFilteredEntities(plugin, tag, filter) {
if (!filter)
return getEntities(plugin, tag);
const matcher = getFilterMatcher(filter);
return getEntities(plugin, tag).filter(c => getEntityLabel(plugin, c).match(matcher) !== null);
}
function _getAllEntities(plugin, tag, list) {
var _a;
list.push(...getEntities(plugin, tag));
for (const g of getGroups(plugin, tag)) {
_getAllEntities(plugin, (_a = g.params) === null || _a === void 0 ? void 0 : _a.values.tag, list);
}
return list;
}
function getAllEntities(plugin, tag) {
return _getAllEntities(plugin, tag, []);
}
function getAllFilteredEntities(plugin, tag, filter) {
if (!filter)
return getAllEntities(plugin, tag);
const matcher = getFilterMatcher(filter);
return getAllEntities(plugin, tag).filter(c => getEntityLabel(plugin, c).match(matcher) !== null);
}
function getEveryEntity(plugin, filter, tag) {
if (filter) {
const matcher = getFilterMatcher(filter);
return getAllEntities(plugin, tag).filter(c => getEntityLabel(plugin, c).match(matcher) !== null);
}
else {
return getAllEntities(plugin, tag);
}
}
function getEntityLabel(plugin, cell) {
var _a, _b;
return ((_b = (_a = mol_state_1.StateObjectRef.resolve(plugin.state.data, cell.transform.parent)) === null || _a === void 0 ? void 0 : _a.obj) === null || _b === void 0 ? void 0 : _b.label) || 'Entity';
}
function getCellDescription(cell) {
var _a, _b;
// markdown style for description
return '**' + ((_a = cell === null || cell === void 0 ? void 0 : cell.obj) === null || _a === void 0 ? void 0 : _a.label) + '**\n\n' + ((_b = cell === null || cell === void 0 ? void 0 : cell.obj) === null || _b === void 0 ? void 0 : _b.description);
}
function getEntityDescription(plugin, cell) {
const s = mol_state_1.StateObjectRef.resolve(plugin.state.data, cell.transform.parent);
const d = getCellDescription(s);
return d;
}
async function updateStyle(plugin, options) {
const update = plugin.state.data.build();
const { ignoreLight, material, celShaded, illustrative } = options;
const entities = getAllEntities(plugin);
for (let j = 0; j < entities.length; ++j) {
update.to(entities[j]).update(old => {
if (old.type) {
const value = old.colorTheme.name === 'illustrative'
? old.colorTheme.params.style.params.value
: old.colorTheme.params.value;
const lightness = old.colorTheme.name === 'illustrative'
? old.colorTheme.params.style.params.lightness
: old.colorTheme.params.lightness;
if (illustrative) {
old.colorTheme = { name: 'illustrative', params: { style: { name: 'uniform', params: { value, lightness } } } };
}
else {
old.colorTheme = { name: 'uniform', params: { value, lightness } };
}
old.type.params.ignoreLight = ignoreLight;
old.type.params.material = material;
old.type.params.celShaded = celShaded;
}
});
}
await update.commit();
}
;
async function updateColors(plugin, values, tag, filter) {
var _a, _b;
const update = plugin.state.data.build();
const { type, illustrative, value, shift, lightness, alpha, emissive } = values;
if (type === 'group-generate' || type === 'group-uniform') {
const leafGroups = getAllLeafGroups(plugin, tag);
const rootLeafGroups = getRoots(plugin).filter(g => { var _a, _b; return ((_a = g.params) === null || _a === void 0 ? void 0 : _a.values.tag) === tag && getEntities(plugin, (_b = g.params) === null || _b === void 0 ? void 0 : _b.values.tag).length > 0; });
const groups = [...leafGroups, ...rootLeafGroups];
const baseColors = getDistinctBaseColors(groups.length, shift);
for (let i = 0; i < groups.length; ++i) {
const g = groups[i];
const entities = getFilteredEntities(plugin, (_a = g.params) === null || _a === void 0 ? void 0 : _a.values.tag, filter);
let groupColors = [];
if (type === 'group-generate') {
const c = (_b = g.params) === null || _b === void 0 ? void 0 : _b.values.color;
groupColors = getDistinctGroupColors(entities.length, baseColors[i], c.variability, c.shift);
}
for (let j = 0; j < entities.length; ++j) {
const c = type === 'group-generate' ? groupColors[j] : baseColors[i];
update.to(entities[j]).update(old => {
if (old.type) {
if (illustrative) {
old.colorTheme = { name: 'illustrative', params: { style: { name: 'uniform', params: { value: c, lightness: lightness } } } };
}
else {
old.colorTheme = { name: 'uniform', params: { value: c, lightness: lightness } };
}
old.type.params.alpha = alpha;
old.type.params.xrayShaded = alpha < 1 ? 'inverted' : false;
old.type.params.emissive = emissive;
}
else if (old.coloring) {
old.coloring.params.color = c;
old.coloring.params.lightness = lightness;
old.alpha = alpha;
old.xrayShaded = alpha < 1 ? true : false;
old.emissive = emissive;
}
});
}
update.to(g.transform.ref).update(old => {
old.color.type = type === 'group-generate' ? 'generate' : 'uniform';
old.color.illustrative = illustrative;
old.color.value = baseColors[i];
old.color.lightness = lightness;
old.color.alpha = alpha;
old.color.emissive = emissive;
});
}
}
else if (type === 'generate' || type === 'uniform') {
const entities = getAllFilteredEntities(plugin, tag, filter);
let groupColors = [];
if (type === 'generate') {
groupColors = getDistinctBaseColors(entities.length, shift);
}
for (let j = 0; j < entities.length; ++j) {
const c = type === 'generate' ? groupColors[j] : value;
update.to(entities[j]).update(old => {
if (old.type) {
if (illustrative) {
old.colorTheme = { name: 'illustrative', params: { style: { name: 'uniform', params: { value: c, lightness: lightness } } } };
}
else {
old.colorTheme = { name: 'uniform', params: { value: c, lightness: lightness } };
}
old.type.params.alpha = alpha;
old.type.params.xrayShaded = alpha < 1 ? 'inverted' : false;
old.type.params.emissive = emissive;
}
else if (old.coloring) {
old.coloring.params.color = c;
old.coloring.params.lightness = lightness;
old.alpha = alpha;
old.xrayShaded = alpha < 1 ? true : false;
old.emissive = emissive;
}
});
}
const others = getAllLeafGroups(plugin, tag);
for (const o of others) {
update.to(o).update(old => {
old.color.type = type === 'generate' ? 'custom' : 'uniform';
old.color.illustrative = illustrative;
old.color.value = value;
old.color.lightness = lightness;
old.color.alpha = alpha;
old.color.emissive = emissive;
});
}
}
await update.commit();
}
;
function expandAllGroups(plugin) {
for (const g of getAllGroups(plugin)) {
if (g.state.isCollapsed) {
plugin.state.data.updateCellState(g.transform.ref, { isCollapsed: false });
}
}
}
;