diff --git a/src/mol-model/volume/data.ts b/src/mol-model/volume/data.ts index fce0581ed0e1d209f2f41c701c02fe8294ffae5f..97572d0ef23dc697e20f3747316ab2276da75987 100644 --- a/src/mol-model/volume/data.ts +++ b/src/mol-model/volume/data.ts @@ -21,10 +21,10 @@ interface VolumeData { } namespace VolumeData { - export const Empty: VolumeData = { + export const One: VolumeData = { cell: SpacegroupCell.Zero, fractionalBox: Box3D.empty(), - data: Tensor.create(Tensor.Space([0, 0, 0], [0, 1, 2]), Tensor.Data1([])), + data: Tensor.create(Tensor.Space([1, 1, 1], [0, 1, 2]), Tensor.Data1([0])), dataStats: { min: 0, max: 0, mean: 0, sigma: 0 } } diff --git a/src/mol-plugin/behavior/dynamic/volume.ts b/src/mol-plugin/behavior/dynamic/volume.ts index 7afbba36ab0705fdd66075b247ba079683fb0ccd..856f239f42ed3b2b2a5d31a0a065bf4ec23f1e4e 100644 --- a/src/mol-plugin/behavior/dynamic/volume.ts +++ b/src/mol-plugin/behavior/dynamic/volume.ts @@ -41,7 +41,7 @@ export namespace VolumeStreaming { topRight: PD.Vec3(Vec3.create(-7.1, -10, -0.9)) }, { description: 'Static box defined by cartesian coords.' }), // 'around-selection': PD.Group({ radius: PD.Numeric(5, { min: 0, max: 10 }) }), - // 'whole-structure': PD.Group({ }), + 'cell': PD.Group({ }), // 'auto': PD.Group({ }), // based on camera distance/active selection/whatever, show whole structure or slice. }), detailLevel: PD.Numeric(3, { min: 0, max: 7 }), @@ -55,6 +55,7 @@ export namespace VolumeStreaming { export class Behavior implements PluginBehavior<Params> { // TODO: have special value for "cell"? private cache = LRUCache.create<ChannelData>(25); + // private ref: string = ''; currentData: ChannelData = { } @@ -109,14 +110,28 @@ export namespace VolumeStreaming { } register(ref: string): void { - // TODO: registr camera movement/loci so that "around selection box works" + // TODO: register camera movement/loci so that "around selection box works" + // alternatively, and maybe a better solution, write a global behavior that modifies this node from the outside + // this.ref = ref; this.update(this.params); } async update(params: Params): Promise<boolean> { this.params = params; - const box: Box3D = Box3D.create(params.box.params.bottomLeft, params.box.params.topRight); + let box: Box3D | undefined = void 0; + + switch (params.box.name) { + case 'static-box': + box = Box3D.create(params.box.params.bottomLeft, params.box.params.topRight); + break; + case 'cell': + box = this.params.levels.name === 'x-ray' + ? void 0 // TODO get bounding box of the model (how to solve assemblies) + : void 0; + break; + } + const data = await this.queryData(box); this.currentData = data || { }; diff --git a/src/mol-plugin/state/transforms/representation.ts b/src/mol-plugin/state/transforms/representation.ts index 9bf811edd3bafa994bdede7ee9d635114243d867..25af4e857307005d0aeae0607c18f0896e067b30 100644 --- a/src/mol-plugin/state/transforms/representation.ts +++ b/src/mol-plugin/state/transforms/representation.ts @@ -195,16 +195,16 @@ const VolumeRepresentation3D = PluginStateTransform.BuiltIn({ type: PD.Mapped<any>( registry.default.name, registry.types, - name => PD.Group<any>(registry.get(name).getParams(themeCtx, VolumeData.Empty ))), + name => PD.Group<any>(registry.get(name).getParams(themeCtx, VolumeData.One ))), colorTheme: PD.Mapped<any>( type.defaultColorTheme, themeCtx.colorThemeRegistry.types, - name => PD.Group<any>(themeCtx.colorThemeRegistry.get(name).getParams({ volume: VolumeData.Empty })) + name => PD.Group<any>(themeCtx.colorThemeRegistry.get(name).getParams({ volume: VolumeData.One })) ), sizeTheme: PD.Mapped<any>( type.defaultSizeTheme, themeCtx.sizeThemeRegistry.types, - name => PD.Group<any>(themeCtx.sizeThemeRegistry.get(name).getParams({ volume: VolumeData.Empty })) + name => PD.Group<any>(themeCtx.sizeThemeRegistry.get(name).getParams({ volume: VolumeData.One })) ) } } diff --git a/src/mol-plugin/state/transforms/volume.ts b/src/mol-plugin/state/transforms/volume.ts index 7568a9ab82850e6cfc4581cb1d251c5724c8ed1b..a0516c70ef19d9851d08c479df99ba1607bdbe1c 100644 --- a/src/mol-plugin/state/transforms/volume.ts +++ b/src/mol-plugin/state/transforms/volume.ts @@ -111,6 +111,7 @@ const VolumeStreamingBehavior = PluginStateTransform.BuiltIn({ apply: ({ params }, plugin: PluginContext) => Task.create('Volume Streaming', async ctx => { const behavior = new VolumeStreaming.Behavior(plugin, params); // get the initial data now so that the child projections dont get empty volumes. + // TODO: this is a temporary fix await behavior.update(behavior.params); return new VolumeStreaming.Obj(behavior, { label: 'Volume Streaming' }); }), @@ -174,7 +175,7 @@ const VolumeStreamingVisual = PluginStateTransform.BuiltIn({ }); function createVolumeProps(streaming: VolumeStreaming.Behavior, channel: keyof VolumeStreaming.ChannelData, level: VolumeStreaming.LevelType) { - const data = streaming.currentData[channel] || VolumeData.Empty; + const data = streaming.currentData[channel] || VolumeData.One; // TODO: createTheme fails when VolumeData.Empty is used for some reason. let isoValue: VolumeIsoValue, color: Color; diff --git a/src/mol-repr/volume/isosurface.ts b/src/mol-repr/volume/isosurface.ts index 0082bf2d597c1cca84f18089a72e4329c126b00c..7ebfe7df4ba6f453bcd590045134b82967325380 100644 --- a/src/mol-repr/volume/isosurface.ts +++ b/src/mol-repr/volume/isosurface.ts @@ -24,18 +24,18 @@ export function createIsoValueParam(defaultValue: VolumeIsoValue) { defaultValue, { 'absolute': PD.Converted( - (v: VolumeIsoValue) => VolumeIsoValue.toAbsolute(v, VolumeData.Empty.dataStats).absoluteValue, + (v: VolumeIsoValue) => VolumeIsoValue.toAbsolute(v, VolumeData.One.dataStats).absoluteValue, (v: number) => VolumeIsoValue.absolute(v), PD.Numeric(0.5, { min: -1, max: 1, step: 0.01 }) ), 'relative': PD.Converted( - (v: VolumeIsoValue) => VolumeIsoValue.toRelative(v, VolumeData.Empty.dataStats).relativeValue, + (v: VolumeIsoValue) => VolumeIsoValue.toRelative(v, VolumeData.One.dataStats).relativeValue, (v: number) => VolumeIsoValue.relative(v), PD.Numeric(2, { min: -10, max: 10, step: 0.01 }) ) }, (v: VolumeIsoValue) => v.kind === 'absolute' ? 'absolute' : 'relative', - (v: VolumeIsoValue, c: 'absolute' | 'relative') => c === 'absolute' ? VolumeIsoValue.toAbsolute(v, VolumeData.Empty.dataStats) : VolumeIsoValue.toRelative(v, VolumeData.Empty.dataStats) + (v: VolumeIsoValue, c: 'absolute' | 'relative') => c === 'absolute' ? VolumeIsoValue.toAbsolute(v, VolumeData.One.dataStats) : VolumeIsoValue.toRelative(v, VolumeData.One.dataStats) ) } diff --git a/src/mol-state/transform.ts b/src/mol-state/transform.ts index 57e104f3bcdd5447aead6af0e1bc46e2235d3036..12de75d1c48126ae3f4577e894c014512a007410 100644 --- a/src/mol-state/transform.ts +++ b/src/mol-state/transform.ts @@ -56,6 +56,10 @@ namespace Transform { return { ...t, parent, version: UUID.create22() }; } + export function withNewVersion(t: Transform): Transform { + return { ...t, version: UUID.create22() }; + } + export function createRoot(props?: Props): Transform { return create(RootRef, StateTransformer.ROOT, {}, { ref: RootRef, props }); } diff --git a/src/mol-state/tree/transient.ts b/src/mol-state/tree/transient.ts index cb75faae3a95cc200d1f18b18a2300a8622895bc..571d914c3faeb4a9f049d736ede11e492f317fce 100644 --- a/src/mol-state/tree/transient.ts +++ b/src/mol-state/tree/transient.ts @@ -96,6 +96,16 @@ class TransientTree implements StateTree { const old = this.transforms.get(ref); this.removeChild(old.parent, ref); this.addChild(newParent, ref); + this.changeNodes(); + this.transforms.set(ref, StateTransform.withParent(old, newParent)); + } + + updateVersion(ref: StateTransform.Ref) { + ensurePresent(this.transforms, ref); + + const t = this.transforms.get(ref); + this.changeNodes(); + this.transforms.set(ref, StateTransform.withNewVersion(t)); } add(transform: StateTransform, initialState?: Partial<StateObjectCell.State>) {