UNPKG

molstar

Version:

A comprehensive macromolecular library.

180 lines (179 loc) 8.37 kB
/** * Copyright (c) 2018-2022 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose <alexander.rose@weirdbyte.de> * @author David Sehnal <david.sehnal@gmail.com> */ import { __awaiter, __generator } from "tslib"; import { ParamDefinition as PD } from '../../mol-util/param-definition'; import { StructureRepresentationStateBuilder } from './representation'; import { Representation } from '../representation'; import { Structure, StructureElement, Bond } from '../../mol-model/structure'; import { Subject } from 'rxjs'; import { getNextMaterialId } from '../../mol-gl/render-object'; import { Theme } from '../../mol-theme/theme'; import { Task } from '../../mol-task'; import { EmptyLoci, Loci, isEveryLoci, isDataLoci, EveryLoci } from '../../mol-model/loci'; import { MarkerActions } from '../../mol-util/marker-action'; import { Overpaint } from '../../mol-theme/overpaint'; import { Clipping } from '../../mol-theme/clipping'; import { Transparency } from '../../mol-theme/transparency'; import { Substance } from '../../mol-theme/substance'; export function ComplexRepresentation(label, ctx, getParams, visualCtor) { var version = 0; var webgl = ctx.webgl; var updated = new Subject(); var geometryState = new Representation.GeometryState(); var materialId = getNextMaterialId(); var renderObjects = []; var _state = StructureRepresentationStateBuilder.create(); var visual; var _structure; var _params; var _props; var _theme = Theme.createEmpty(); function createOrUpdate(props, structure) { var _this = this; if (props === void 0) { props = {}; } if (structure && structure !== _structure) { _params = getParams(ctx, structure); _structure = structure; if (!_props) _props = PD.getDefaultValues(_params); } _props = Object.assign({}, _props, props); return Task.create('Creating or updating ComplexRepresentation', function (runtime) { return __awaiter(_this, void 0, void 0, function () { var newVisual, promise; var _a; return __generator(this, function (_b) { switch (_b.label) { case 0: newVisual = false; if (!visual) { visual = visualCtor(materialId, _structure, _props, webgl); newVisual = true; } else if ((_a = visual.mustRecreate) === null || _a === void 0 ? void 0 : _a.call(visual, _structure, _props, webgl)) { visual.destroy(); visual = visualCtor(materialId, _structure, _props, webgl); newVisual = true; } promise = visual.createOrUpdate({ webgl: webgl, runtime: runtime }, _theme, _props, structure); if (!promise) return [3 /*break*/, 2]; return [4 /*yield*/, promise]; case 1: _b.sent(); _b.label = 2; case 2: if (newVisual) setState(_state); // current state for new visual // update list of renderObjects renderObjects.length = 0; if (visual && visual.renderObject) { renderObjects.push(visual.renderObject); geometryState.add(visual.renderObject.id, visual.geometryVersion); } geometryState.snapshot(); // increment version version += 1; updated.next(version); return [2 /*return*/]; } }); }); }); } function getLoci(pickingId) { return visual ? visual.getLoci(pickingId) : EmptyLoci; } function getAllLoci() { return [Structure.Loci(_structure.target)]; } function mark(loci, action) { if (!_structure) return false; if (!MarkerActions.is(_state.markerActions, action)) return false; if (Structure.isLoci(loci) || StructureElement.Loci.is(loci) || Bond.isLoci(loci)) { if (!Structure.areRootsEquivalent(loci.structure, _structure)) return false; // Remap `loci` from equivalent structure to the current `_structure` loci = Loci.remap(loci, _structure); if (Structure.isLoci(loci) || (StructureElement.Loci.is(loci) && StructureElement.Loci.isWholeStructure(loci))) { // Change to `EveryLoci` to allow for downstream optimizations loci = EveryLoci; } } else if (!isEveryLoci(loci) && !isDataLoci(loci)) { return false; } if (Loci.isEmpty(loci)) return false; return visual ? visual.mark(loci, action) : false; } function setState(state) { StructureRepresentationStateBuilder.update(_state, state); if (state.visible !== undefined && visual) { // hide visual when _unitTransforms is set and not the identity visual.setVisibility(state.visible && (_state.unitTransforms === null || _state.unitTransforms.isIdentity)); } if (state.alphaFactor !== undefined && visual) visual.setAlphaFactor(state.alphaFactor); if (state.pickable !== undefined && visual) visual.setPickable(state.pickable); if (state.overpaint !== undefined && visual) { // Remap loci from equivalent structure to the current structure var remappedOverpaint = Overpaint.remap(state.overpaint, _structure); visual.setOverpaint(remappedOverpaint, webgl); } if (state.transparency !== undefined && visual) { // Remap loci from equivalent structure to the current structure var remappedTransparency = Transparency.remap(state.transparency, _structure); visual.setTransparency(remappedTransparency, webgl); } if (state.substance !== undefined && visual) { // Remap loci from equivalent structure to the current structure var remappedSubstance = Substance.remap(state.substance, _structure); visual.setSubstance(remappedSubstance, webgl); } if (state.clipping !== undefined && visual) { // Remap loci from equivalent structure to the current structure var remappedClipping = Clipping.remap(state.clipping, _structure); visual.setClipping(remappedClipping); } if (state.transform !== undefined && visual) visual.setTransform(state.transform); if (state.unitTransforms !== undefined && visual) { // Since ComplexVisuals always renders geometries between units, the application // of `unitTransforms` does not make sense. When given here and not the identity, // it is ignored and sets the visual's visibility to `false`. visual.setVisibility(_state.visible && (state.unitTransforms === null || state.unitTransforms.isIdentity)); } } function setTheme(theme) { _theme = theme; } function destroy() { if (visual) visual.destroy(); } return { label: label, get groupCount() { return visual ? visual.groupCount : 0; }, get props() { return _props; }, get params() { return _params; }, get state() { return _state; }, get theme() { return _theme; }, get geometryVersion() { return geometryState.version; }, renderObjects: renderObjects, updated: updated, createOrUpdate: createOrUpdate, setState: setState, setTheme: setTheme, getLoci: getLoci, getAllLoci: getAllLoci, mark: mark, destroy: destroy }; }