UNPKG

molstar

Version:

A comprehensive macromolecular library.

267 lines 13.4 kB
"use strict"; /** * Copyright (c) 2018-2020 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.ShapeRepresentation = void 0; var tslib_1 = require("tslib"); var geometry_1 = require("../../mol-geo/geometry/geometry"); var representation_1 = require("../representation"); var shape_1 = require("../../mol-model/shape"); var rxjs_1 = require("rxjs"); var render_object_1 = require("../../mol-gl/render-object"); var theme_1 = require("../../mol-theme/theme"); var util_1 = require("../util"); var marker_data_1 = require("../../mol-geo/geometry/marker-data"); var marker_action_1 = require("../../mol-util/marker-action"); var mol_util_1 = require("../../mol-util"); var color_data_1 = require("../../mol-geo/geometry/color-data"); var size_data_1 = require("../../mol-geo/geometry/size-data"); var loci_1 = require("../../mol-model/loci"); var int_1 = require("../../mol-data/int"); var visual_1 = require("../visual"); var mol_task_1 = require("../../mol-task"); var param_definition_1 = require("../../mol-util/param-definition"); var debug_1 = require("../../mol-util/debug"); function ShapeRepresentation(getShape, geometryUtils, builder) { if (builder === void 0) { builder = {}; } var version = 0; var updated = new rxjs_1.Subject(); var _state = representation_1.Representation.createState(); var materialId = (0, render_object_1.getNextMaterialId)(); var renderObjects = []; var _renderObject; var _shape; var _theme = theme_1.Theme.createEmpty(); var currentProps = param_definition_1.ParamDefinition.getDefaultValues(geometryUtils.Params); // TODO avoid casting var currentParams; var locationIt; var positionIt; if (builder.modifyState) representation_1.Representation.updateState(_state, builder.modifyState(_state)); var updateState = util_1.VisualUpdateState.create(); function prepareUpdate(props, shape) { if (props === void 0) { props = {}; } util_1.VisualUpdateState.reset(updateState); if (!shape && !_shape) { // console.error('no shape given') return; } else if (shape && !_shape) { // console.log('first shape') updateState.createNew = true; } else if (shape && _shape && shape.id === _shape.id) { // console.log('same shape') // nothing to set } else if (shape && _shape && shape.id !== _shape.id) { // console.log('new shape') updateState.updateTransform = true; updateState.createGeometry = true; } else if (!shape) { // console.log('only props') // nothing to set } else { console.warn('unexpected state'); } if (updateState.updateTransform) { updateState.updateColor = true; updateState.updateSize = true; } if (updateState.createGeometry) { updateState.updateColor = true; updateState.updateSize = true; } } function createOrUpdate(props, data) { var _this = this; if (props === void 0) { props = {}; } if (builder.modifyProps) props = builder.modifyProps(props); return mol_task_1.Task.create('ShapeRepresentation.create', function (runtime) { return (0, tslib_1.__awaiter)(_this, void 0, void 0, function () { var newProps, shape, _a, transform, values, state, instanceCount, groupCount; return (0, tslib_1.__generator)(this, function (_b) { switch (_b.label) { case 0: newProps = Object.assign(currentProps, props); if (!data) return [3 /*break*/, 2]; return [4 /*yield*/, getShape(runtime, data, newProps, _shape)]; case 1: _a = _b.sent(); return [3 /*break*/, 3]; case 2: _a = undefined; _b.label = 3; case 3: shape = _a; prepareUpdate(props, shape); if (shape) { _shape = shape; Object.assign(_theme, shape_1.Shape.getTheme(_shape)); } if (updateState.createNew) { renderObjects.length = 0; // clear list o renderObjects locationIt = shape_1.Shape.groupIterator(_shape); transform = shape_1.Shape.createTransform(_shape.transforms); values = geometryUtils.createValues(_shape.geometry, transform, locationIt, _theme, newProps); state = geometryUtils.createRenderableState(newProps); if (builder.modifyState) Object.assign(state, builder.modifyState(state)); representation_1.Representation.updateState(_state, state); _renderObject = (0, render_object_1.createRenderObject)(_shape.geometry.kind, values, state, materialId); if (_renderObject) renderObjects.push(_renderObject); // add new renderObject to list positionIt = geometryUtils.createPositionIterator(_shape.geometry, _renderObject.values); } else { if (!_renderObject) { throw new Error('expected renderObject to be available'); } if (updateState.updateTransform) { // console.log('update transform') shape_1.Shape.createTransform(_shape.transforms, _renderObject.values); locationIt = shape_1.Shape.groupIterator(_shape); instanceCount = locationIt.instanceCount, groupCount = locationIt.groupCount; (0, marker_data_1.createMarkers)(instanceCount * groupCount, _renderObject.values); } if (updateState.createGeometry) { // console.log('update geometry') mol_util_1.ValueCell.updateIfChanged(_renderObject.values.drawCount, geometry_1.Geometry.getDrawCount(_shape.geometry)); mol_util_1.ValueCell.updateIfChanged(_renderObject.values.uVertexCount, geometry_1.Geometry.getVertexCount(_shape.geometry)); } if (updateState.updateTransform || updateState.createGeometry) { // console.log('updateBoundingSphere') geometryUtils.updateBoundingSphere(_renderObject.values, _shape.geometry); positionIt = geometryUtils.createPositionIterator(_shape.geometry, _renderObject.values); } if (updateState.updateColor) { // console.log('update color') (0, color_data_1.createColors)(locationIt, positionIt, _theme.color, _renderObject.values); } if (updateState.updateSize) { // not all geometries have size data, so check here if ('uSize' in _renderObject.values) { // console.log('update size') (0, size_data_1.createSizes)(locationIt, _theme.size, _renderObject.values); } } geometryUtils.updateValues(_renderObject.values, newProps); geometryUtils.updateRenderableState(_renderObject.state, newProps); } currentProps = newProps; // increment version updated.next(version++); return [2 /*return*/]; } }); }); }); } function lociApply(loci, apply) { if ((0, loci_1.isEveryLoci)(loci) || (shape_1.Shape.isLoci(loci) && loci.shape === _shape)) { return apply(int_1.Interval.ofBounds(0, _shape.groupCount * _shape.transforms.length)); } else { return eachShapeGroup(loci, _shape, apply); } } return { label: 'Shape geometry', get groupCount() { return locationIt ? locationIt.count : 0; }, get props() { return currentProps; }, get params() { return currentParams; }, get state() { return _state; }, get theme() { return _theme; }, renderObjects: renderObjects, updated: updated, createOrUpdate: createOrUpdate, getLoci: function (pickingId) { if (pickingId === undefined) return shape_1.Shape.Loci(_shape); var objectId = pickingId.objectId, groupId = pickingId.groupId, instanceId = pickingId.instanceId; if (_renderObject && _renderObject.id === objectId) { return shape_1.ShapeGroup.Loci(_shape, [{ ids: int_1.OrderedSet.ofSingleton(groupId), instance: instanceId }]); } return loci_1.EmptyLoci; }, mark: function (loci, action) { if (!marker_action_1.MarkerActions.is(_state.markerActions, action)) return false; if (shape_1.ShapeGroup.isLoci(loci) || shape_1.Shape.isLoci(loci)) { if (loci.shape !== _shape) return false; } else if (!(0, loci_1.isEveryLoci)(loci)) { return false; } return visual_1.Visual.mark(_renderObject, loci, action, lociApply); }, setState: function (state) { if (builder.modifyState) state = builder.modifyState(state); if (_renderObject) { if (state.visible !== undefined) visual_1.Visual.setVisibility(_renderObject, state.visible); if (state.alphaFactor !== undefined) visual_1.Visual.setAlphaFactor(_renderObject, state.alphaFactor); if (state.pickable !== undefined) visual_1.Visual.setPickable(_renderObject, state.pickable); if (state.colorOnly !== undefined) visual_1.Visual.setColorOnly(_renderObject, state.colorOnly); if (state.overpaint !== undefined) { visual_1.Visual.setOverpaint(_renderObject, state.overpaint, lociApply, true); } if (state.transparency !== undefined) { visual_1.Visual.setTransparency(_renderObject, state.transparency, lociApply, true); } if (state.transform !== undefined) visual_1.Visual.setTransform(_renderObject, state.transform); } representation_1.Representation.updateState(_state, state); }, setTheme: function (theme) { if (debug_1.isDebugMode) { console.warn('The `ShapeRepresentation` theme is fixed to `ShapeGroupColorTheme` and `ShapeGroupSizeTheme`. Colors are taken from `Shape.getColor` and sizes from `Shape.getSize`'); } }, destroy: function () { renderObjects.length = 0; if (_renderObject) { _renderObject.state.disposed = true; _renderObject = undefined; } } }; } exports.ShapeRepresentation = ShapeRepresentation; function eachShapeGroup(loci, shape, apply) { if (!shape_1.ShapeGroup.isLoci(loci)) return false; if (loci.shape !== shape) return false; var changed = false; var groupCount = shape.groupCount; var groups = loci.groups; for (var _a = 0, groups_1 = groups; _a < groups_1.length; _a++) { var _b = groups_1[_a], ids = _b.ids, instance = _b.instance; if (int_1.Interval.is(ids)) { var start = instance * groupCount + int_1.Interval.start(ids); var end = instance * groupCount + int_1.Interval.end(ids); if (apply(int_1.Interval.ofBounds(start, end))) changed = true; } else { for (var i = 0, _i = ids.length; i < _i; i++) { var idx = instance * groupCount + ids[i]; if (apply(int_1.Interval.ofSingleton(idx))) changed = true; } } } return changed; } //# sourceMappingURL=representation.js.map