UNPKG

molstar

Version:

A comprehensive macromolecular library.

135 lines 6.93 kB
/** * Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose <alexander.rose@weirdbyte.de> */ import { __assign, __awaiter, __generator } from "tslib"; import { ParamDefinition as PD } from '../../mol-util/param-definition'; import { Vec3, Mat4 } from '../../mol-math/linear-algebra'; import { Box3D } from '../../mol-math/geometry'; import { Grid, Volume } from '../../mol-model/volume'; import { DirectVolume } from '../../mol-geo/geometry/direct-volume/direct-volume'; import { VolumeVisual, VolumeRepresentation, VolumeRepresentationProvider } from './representation'; import { LocationIterator } from '../../mol-geo/util/location-iterator'; import { NullLocation } from '../../mol-model/location'; import { Interval } from '../../mol-data/int'; import { EmptyLoci } from '../../mol-model/loci'; import { createVolumeTexture2d, createVolumeTexture3d, eachVolumeLoci, getVolumeTexture2dLayout } from './util'; function getBoundingBox(gridDimension, transform) { var bbox = Box3D(); Box3D.add(bbox, gridDimension); Box3D.transform(bbox, bbox, transform); return bbox; } // 2d volume texture export function createDirectVolume2d(ctx, webgl, volume, directVolume) { var gridDimension = volume.grid.cells.space.dimensions; var _a = getVolumeTexture2dLayout(gridDimension), width = _a.width, height = _a.height; if (Math.max(width, height) > webgl.maxTextureSize / 2) { throw new Error('volume too large for direct-volume rendering'); } var textureImage = createVolumeTexture2d(volume, 'normals'); // debugTexture(createImageData(textureImage.array, textureImage.width, textureImage.height), 1/3) var transform = Grid.getGridToCartesianTransform(volume.grid); var bbox = getBoundingBox(gridDimension, transform); var texture = directVolume ? directVolume.gridTexture.ref.value : webgl.resources.texture('image-uint8', 'rgba', 'ubyte', 'linear'); texture.load(textureImage); var _b = getUnitToCartn(volume.grid), unitToCartn = _b.unitToCartn, cellDim = _b.cellDim; return DirectVolume.create(bbox, gridDimension, transform, unitToCartn, cellDim, texture, volume.grid.stats, false, directVolume); } // 3d volume texture function getUnitToCartn(grid) { if (grid.transform.kind === 'matrix') { return { unitToCartn: Mat4.mul(Mat4(), grid.transform.matrix, Mat4.fromScaling(Mat4(), grid.cells.space.dimensions)), cellDim: Mat4.getScaling(Vec3(), grid.transform.matrix) }; } var box = grid.transform.fractionalBox; var size = Box3D.size(Vec3(), box); return { unitToCartn: Mat4.mul3(Mat4(), grid.transform.cell.fromFractional, Mat4.fromTranslation(Mat4(), box.min), Mat4.fromScaling(Mat4(), size)), cellDim: Vec3.div(Vec3(), grid.transform.cell.size, grid.cells.space.dimensions) }; } export function createDirectVolume3d(ctx, webgl, volume, directVolume) { var gridDimension = volume.grid.cells.space.dimensions; if (Math.max.apply(Math, gridDimension) > webgl.max3dTextureSize / 2) { throw new Error('volume too large for direct-volume rendering'); } var textureVolume = createVolumeTexture3d(volume); var transform = Grid.getGridToCartesianTransform(volume.grid); var bbox = getBoundingBox(gridDimension, transform); var texture = directVolume ? directVolume.gridTexture.ref.value : webgl.resources.texture('volume-uint8', 'rgba', 'ubyte', 'linear'); texture.load(textureVolume); var _a = getUnitToCartn(volume.grid), unitToCartn = _a.unitToCartn, cellDim = _a.cellDim; return DirectVolume.create(bbox, gridDimension, transform, unitToCartn, cellDim, texture, volume.grid.stats, false, directVolume); } // export function createDirectVolume(ctx, volume, theme, props, directVolume) { return __awaiter(this, void 0, void 0, function () { var runtime, webgl; return __generator(this, function (_a) { runtime = ctx.runtime, webgl = ctx.webgl; if (webgl === undefined) throw new Error('DirectVolumeVisual requires `webgl` in props'); return [2 /*return*/, webgl.isWebGL2 ? createDirectVolume3d(runtime, webgl, volume, directVolume) : createDirectVolume2d(runtime, webgl, volume, directVolume)]; }); }); } function getLoci(volume, props) { return props.renderMode.name === 'isosurface' ? Volume.Isosurface.Loci(volume, props.renderMode.params.isoValue) : Volume.Loci(volume); } export function getDirectVolumeLoci(pickingId, volume, props, id) { var objectId = pickingId.objectId, groupId = pickingId.groupId; if (id === objectId) { return Volume.Cell.Loci(volume, Interval.ofSingleton(groupId)); } return EmptyLoci; } export function eachDirectVolume(loci, volume, props, apply) { var isoValue = props.renderMode.name === 'isosurface' ? props.renderMode.params.isoValue : undefined; return eachVolumeLoci(loci, volume, isoValue, apply); } // export var DirectVolumeParams = __assign(__assign({}, DirectVolume.Params), { quality: __assign(__assign({}, DirectVolume.Params.quality), { isEssential: false }) }); export function getDirectVolumeParams(ctx, volume) { var p = PD.clone(DirectVolumeParams); p.renderMode = DirectVolume.createRenderModeParam(volume.grid.stats); return p; } export function DirectVolumeVisual(materialId) { return VolumeVisual({ defaultProps: PD.getDefaultValues(DirectVolumeParams), createGeometry: createDirectVolume, createLocationIterator: function (volume) { return LocationIterator(volume.grid.cells.data.length, 1, 1, function () { return NullLocation; }); }, getLoci: getDirectVolumeLoci, eachLocation: eachDirectVolume, setUpdateState: function (state, volume, newProps, currentProps) { }, geometryUtils: DirectVolume.Utils, dispose: function (geometry) { geometry.gridTexture.ref.value.destroy(); } }, materialId); } export function DirectVolumeRepresentation(ctx, getParams) { return VolumeRepresentation('Direct Volume', ctx, getParams, DirectVolumeVisual, getLoci); } export var DirectVolumeRepresentationProvider = VolumeRepresentationProvider({ name: 'direct-volume', label: 'Direct Volume', description: 'Direct rendering of volumetric data.', factory: DirectVolumeRepresentation, getParams: getDirectVolumeParams, defaultValues: PD.getDefaultValues(DirectVolumeParams), defaultColorTheme: { name: 'uniform' }, defaultSizeTheme: { name: 'uniform' }, isApplicable: function (volume) { return !Volume.isEmpty(volume); } }); //# sourceMappingURL=direct-volume.js.map