Select Git revision
behavior.ts
behavior.ts 11.89 KiB
/**
* Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
import CIF from 'mol-io/reader/cif';
import { Box3D } from 'mol-math/geometry';
import { Vec3 } from 'mol-math/linear-algebra';
import { volumeFromDensityServerData } from 'mol-model-formats/volume/density-server';
import { StructureElement } from 'mol-model/structure';
import { VolumeData, VolumeIsoValue } from 'mol-model/volume';
import { PluginBehavior } from 'mol-plugin/behavior';
import { PluginContext } from 'mol-plugin/context';
import { PluginStateObject } from 'mol-plugin/state/objects';
import { createIsoValueParam } from 'mol-repr/volume/isosurface';
import { Color } from 'mol-util/color';
import { LRUCache } from 'mol-util/lru-cache';
import { ParamDefinition as PD } from 'mol-util/param-definition';
import { urlCombine } from 'mol-util/url';
import { VolumeServerHeader, VolumeServerInfo } from './model';
import { ButtonsType } from 'mol-util/input/input-observer';
import { PluginCommands } from 'mol-plugin/command';
import { StateSelection } from 'mol-state';
export class VolumeStreaming extends PluginStateObject.CreateBehavior<VolumeStreaming.Behavior>({ name: 'Volume Streaming' }) { }
export namespace VolumeStreaming {
function channelParam(label: string, color: Color, defaultValue: VolumeIsoValue, stats: VolumeData['dataStats']) {
return PD.Group({
isoValue: createIsoValueParam(defaultValue, stats),
color: PD.Color(color),
opacity: PD.Numeric(0.3, { min: 0, max: 1, step: 0.01 })
}, { label, isExpanded: true });
}
const fakeSampling: VolumeServerHeader.Sampling = {
byteOffset: 0,
rate: 1,
sampleCount: [1, 1, 1],
valuesInfo: [{ mean: 0, min: -1, max: 1, sigma: 0.1 }, { mean: 0, min: -1, max: 1, sigma: 0.1 }]
};
export function createParams(data?: VolumeServerInfo.Data) {
// fake the info
const info = data || { kind: 'em', header: { sampling: [fakeSampling], availablePrecisions: [{ precision: 0, maxVoxels: 0 }] }, emDefaultContourLevel: VolumeIsoValue.relative(0) };
const box = (data && data.structure.boundary.box) || Box3D.empty();
return {
view: PD.MappedStatic('selection-box', {
'box': PD.Group({
bottomLeft: PD.Vec3(box.min),
topRight: PD.Vec3(box.max),
}, { description: 'Static box defined by cartesian coords.', isFlat: true }),
'selection-box': PD.Group({
radius: PD.Numeric(5, { min: 0, max: 50, step: 0.5 }),
bottomLeft: PD.Vec3(Vec3.create(0, 0, 0), { isHidden: true }),
topRight: PD.Vec3(Vec3.create(0, 0, 0), { isHidden: true }),
}, { description: 'Box around last-interacted element.', isFlat: true }),
'cell': PD.Group({}),
// 'auto': PD.Group({ }), // based on camera distance/active selection/whatever, show whole structure or slice.
}, { options: [['box', 'Bounded Box'], ['selection-box', 'Selection'], ['cell', 'Whole Structure']] }),
detailLevel: PD.Select<number>(Math.min(1, info.header.availablePrecisions.length - 1),
info.header.availablePrecisions.map((p, i) => [i, `${i + 1} [ ${Math.pow(p.maxVoxels, 1 / 3) | 0}^3 cells ]`] as [number, string])),
channels: info.kind === 'em'
? PD.Group({
'em': channelParam('EM', Color(0x638F8F), info.emDefaultContourLevel || VolumeIsoValue.relative(1), info.header.sampling[0].valuesInfo[0])
}, { isFlat: true })
: PD.Group({
'2fo-fc': channelParam('2Fo-Fc', Color(0x3362B2), VolumeIsoValue.relative(1.5), info.header.sampling[0].valuesInfo[0]),