From 9d567aca1ad91a4d38821aa1c90b604ff07aa2b8 Mon Sep 17 00:00:00 2001 From: Alexander Rose <alex.rose@rcsb.org> Date: Tue, 13 Nov 2018 15:24:17 -0800 Subject: [PATCH] wip, repr provider --- src/apps/canvas/component/structure-view.tsx | 2 +- src/apps/canvas/component/volume-view.tsx | 2 +- src/mol-repr/representation.ts | 19 +++--- src/mol-repr/shape/representation.ts | 2 + .../structure/complex-representation.ts | 6 +- src/mol-repr/structure/registry.ts | 2 +- .../representation/ball-and-stick.ts | 20 +++--- .../structure/representation/cartoon.ts | 25 +++---- .../structure/units-representation.ts | 17 +++-- src/mol-repr/volume/direct-volume.ts | 68 +++---------------- src/mol-repr/volume/isosurface-mesh.ts | 41 +++-------- src/mol-repr/volume/registry.ts | 2 +- src/mol-repr/volume/representation.ts | 57 ++++++++++------ 13 files changed, 106 insertions(+), 157 deletions(-) diff --git a/src/apps/canvas/component/structure-view.tsx b/src/apps/canvas/component/structure-view.tsx index 3bfd62563..4f8178115 100644 --- a/src/apps/canvas/component/structure-view.tsx +++ b/src/apps/canvas/component/structure-view.tsx @@ -176,7 +176,7 @@ export class StructureViewComponent extends React.Component<StructureViewCompone <RepresentationComponent repr={structureRepresentations[k] as Representation<any>} params={ - structureView.app.structureRepresentationRegistry.get(k)!.params(structureView.app.reprCtx, structure!) + structureView.app.structureRepresentationRegistry.get(k)!.getParams(structureView.app.reprCtx, structure!) } canvas3d={structureView.canvas3d} app={structureView.app} diff --git a/src/apps/canvas/component/volume-view.tsx b/src/apps/canvas/component/volume-view.tsx index bf351b4dc..51239bb52 100644 --- a/src/apps/canvas/component/volume-view.tsx +++ b/src/apps/canvas/component/volume-view.tsx @@ -91,7 +91,7 @@ export class VolumeViewComponent extends React.Component<VolumeViewComponentProp <RepresentationComponent repr={volumeRepresentations[k] as Representation<any>} params={ - volumeView.app.volumeRepresentationRegistry.get(k)!.params(volumeView.app.reprCtx, volume!) + volumeView.app.volumeRepresentationRegistry.get(k)!.getParams(volumeView.app.reprCtx, volume!) } canvas3d={volumeView.viewer} app={volumeView.app} diff --git a/src/mol-repr/representation.ts b/src/mol-repr/representation.ts index 59f07b03e..1a79e1c87 100644 --- a/src/mol-repr/representation.ts +++ b/src/mol-repr/representation.ts @@ -21,11 +21,13 @@ import { ThemeProps, Theme, ThemeRegistryContext } from 'mol-theme/theme'; // } export type RepresentationProps = { [k: string]: any } +export type RepresentationParamsGetter<D> = (ctx: ThemeRegistryContext, data: D) => PD.Params + // export interface RepresentationProvider<D, P extends PD.Params> { - readonly factory: (defaultProps: PD.DefaultValues<P>) => Representation<D, PD.DefaultValues<P>> - readonly params: (ctx: ThemeRegistryContext, data: D) => P + readonly factory: (getParams: RepresentationParamsGetter<D>) => Representation<D, PD.DefaultValues<P>> + readonly getParams: (ctx: ThemeRegistryContext, data: D) => P } export class RepresentationRegistry<D> { @@ -34,8 +36,8 @@ export class RepresentationRegistry<D> { constructor() {}; - add<P extends PD.Params>(name: string, factory: RepresentationProvider<D, P>['factory'], params: RepresentationProvider<D, P>['params']) { - const provider = { factory, params } as RepresentationProvider<D, P> + add<P extends PD.Params>(name: string, factory: RepresentationProvider<D, P>['factory'], getParams: RepresentationProvider<D, P>['getParams']) { + const provider = { factory, getParams } as RepresentationProvider<D, P> this._list.push({ name, provider }) this._map.set(name, provider) } @@ -46,7 +48,7 @@ export class RepresentationRegistry<D> { create(id: string, ctx: ThemeRegistryContext, data: D, props = {}): Representation<D, any> { const provider = this.get(id) - return provider ? provider.factory({ ...PD.getDefaultValues(provider.params(ctx, data)), ...props }) : Representation.Empty + return provider ? provider.factory(provider.getParams) : Representation.Empty } get list() { @@ -83,9 +85,9 @@ namespace Representation { destroy: () => {} } - export type Def<P extends RepresentationProps = {}> = { [k: string]: (defaultProps: P) => Representation<any, P> } + export type Def<D, P extends RepresentationProps = {}> = { [k: string]: (getParams: RepresentationParamsGetter<D>) => Representation<any, P> } - export function createMulti<D, P extends RepresentationProps = {}>(label: string, getParams: (ctx: ThemeRegistryContext, data: D) => PD.Params, reprDefs: Def<P>): Representation<D, P> { + export function createMulti<D, P extends RepresentationProps = {}>(label: string, getParams: RepresentationParamsGetter<D>, reprDefs: Def<D, P>): Representation<D, P> { let currentParams: PD.Params let currentProps: P let currentData: D @@ -93,7 +95,7 @@ namespace Representation { const reprMap: { [k: number]: string } = {} const reprList: Representation<D, P>[] = Object.keys(reprDefs).map((name, i) => { reprMap[i] = name - return reprDefs[name](defaultProps) + return reprDefs[name](getParams) }) return { @@ -117,7 +119,6 @@ namespace Representation { return currentParams }, createOrUpdate: (ctx: RepresentationContext, props: Partial<P> = {}, themeProps: ThemeProps = {}, data?: D) => { - if (data) currentData = data if (data && data !== currentData) { currentParams = getParams(ctx, data) currentData = data diff --git a/src/mol-repr/shape/representation.ts b/src/mol-repr/shape/representation.ts index 718f68ce3..98e3ee8f2 100644 --- a/src/mol-repr/shape/representation.ts +++ b/src/mol-repr/shape/representation.ts @@ -38,6 +38,7 @@ export function ShapeRepresentation<P extends ShapeProps>(): ShapeRepresentation let _renderObject: MeshRenderObject | undefined let _shape: Shape let currentProps: P + let currentParams: PD.Params function createOrUpdate(ctx: RepresentationContext, props: Partial<P> = {}, themeProps: ThemeProps = {}, shape?: Shape) { currentProps = Object.assign({}, DefaultShapeProps, currentProps, props) @@ -64,6 +65,7 @@ export function ShapeRepresentation<P extends ShapeProps>(): ShapeRepresentation return { label: 'Shape mesh', get renderObjects () { return renderObjects }, + get params () { return currentParams }, get props () { return currentProps }, createOrUpdate, getLoci(pickingId: PickingId) { diff --git a/src/mol-repr/structure/complex-representation.ts b/src/mol-repr/structure/complex-representation.ts index 67cc444de..186af8d68 100644 --- a/src/mol-repr/structure/complex-representation.ts +++ b/src/mol-repr/structure/complex-representation.ts @@ -12,11 +12,11 @@ import { StructureProps, StructureRepresentation } from './representation'; import { ComplexVisual } from './complex-visual'; import { PickingId } from 'mol-geo/geometry/picking'; import { MarkerAction } from 'mol-geo/geometry/marker-data'; -import { RepresentationContext } from 'mol-repr/representation'; -import { Theme, ThemeProps, createTheme, ThemeRegistryContext } from 'mol-theme/theme'; +import { RepresentationContext, RepresentationParamsGetter } from 'mol-repr/representation'; +import { Theme, ThemeProps, createTheme } from 'mol-theme/theme'; import { ParamDefinition as PD } from 'mol-util/param-definition'; -export function ComplexRepresentation<P extends StructureProps>(label: string, getParams: (ctx: ThemeRegistryContext, data: Structure) => PD.Params, visualCtor: () => ComplexVisual<P>): StructureRepresentation<P> { +export function ComplexRepresentation<P extends StructureProps>(label: string, getParams: RepresentationParamsGetter<Structure>, visualCtor: () => ComplexVisual<P>): StructureRepresentation<P> { let visual: ComplexVisual<P> | undefined let _structure: Structure diff --git a/src/mol-repr/structure/registry.ts b/src/mol-repr/structure/registry.ts index c6fce5ebf..5dcfe8aaf 100644 --- a/src/mol-repr/structure/registry.ts +++ b/src/mol-repr/structure/registry.ts @@ -14,7 +14,7 @@ export class StructureRepresentationRegistry extends RepresentationRegistry<Stru super() Object.keys(BuiltInStructureRepresentations).forEach(name => { const p = (BuiltInStructureRepresentations as { [k: string]: RepresentationProvider<Structure, any> })[name] - this.add(name, p.factory, p.params) + this.add(name, p.factory, p.getParams) }) } } diff --git a/src/mol-repr/structure/representation/ball-and-stick.ts b/src/mol-repr/structure/representation/ball-and-stick.ts index a6e3d51ce..126230226 100644 --- a/src/mol-repr/structure/representation/ball-and-stick.ts +++ b/src/mol-repr/structure/representation/ball-and-stick.ts @@ -4,25 +4,25 @@ * @author Alexander Rose <alexander.rose@weirdbyte.de> */ -import { ElementSphereVisual, ElementSphereParams, ElementSphereProps } from '../visual/element-sphere'; +import { ElementSphereVisual, ElementSphereParams } from '../visual/element-sphere'; import { IntraUnitLinkVisual, IntraUnitLinkParams } from '../visual/intra-unit-link-cylinder'; -import { InterUnitLinkVisual, InterUnitLinkParams, InterUnitLinkProps } from '../visual/inter-unit-link-cylinder'; +import { InterUnitLinkVisual, InterUnitLinkParams } from '../visual/inter-unit-link-cylinder'; import { ParamDefinition as PD } from 'mol-util/param-definition'; import { UnitsRepresentation } from '../units-representation'; import { ComplexRepresentation } from '../complex-representation'; import { StructureRepresentation, StructureRepresentationProvider } from '../representation'; -import { Representation } from 'mol-repr/representation'; +import { Representation, RepresentationParamsGetter } from 'mol-repr/representation'; import { ThemeRegistryContext } from 'mol-theme/theme'; import { Structure } from 'mol-model/structure'; -import { IntraUnitLinkProps } from '../visual/polymer-gap-cylinder'; import { BuiltInSizeThemeName, BuiltInSizeThemeOptions } from 'mol-theme/size'; import { BuiltInColorThemeName, BuiltInColorThemeOptions } from 'mol-theme/color'; import { UnitKind, UnitKindOptions } from '../visual/util/common'; +type ParamsGetter = RepresentationParamsGetter<Structure> const BallAndStickVisuals = { - 'element-sphere': (defaultProps: ElementSphereProps) => UnitsRepresentation('Element sphere mesh', defaultProps, ElementSphereVisual), - 'intra-link': (defaultProps: IntraUnitLinkProps) => UnitsRepresentation('Intra-unit link cylinder', defaultProps, IntraUnitLinkVisual), - 'inter-link': (defaultProps: InterUnitLinkProps) => ComplexRepresentation('Inter-unit link cylinder', defaultProps, InterUnitLinkVisual), + 'element-sphere': (getParams: ParamsGetter) => UnitsRepresentation('Element sphere mesh', getParams, ElementSphereVisual), + 'intra-link': (getParams: ParamsGetter) => UnitsRepresentation('Intra-unit link cylinder', getParams, IntraUnitLinkVisual), + 'inter-link': (getParams: ParamsGetter) => ComplexRepresentation('Inter-unit link cylinder', getParams, InterUnitLinkVisual), } type BallAndStickVisualName = keyof typeof BallAndStickVisuals const BallAndStickVisualOptions = Object.keys(BallAndStickVisuals).map(name => [name, name] as [BallAndStickVisualName, string]) @@ -44,10 +44,10 @@ export type BallAndStickProps = PD.DefaultValues<typeof BallAndStickParams> export type BallAndStickRepresentation = StructureRepresentation<BallAndStickProps> -export function BallAndStickRepresentation(defaultProps: BallAndStickProps): BallAndStickRepresentation { - return Representation.createMulti('Ball & Stick', defaultProps, BallAndStickVisuals as unknown as Representation.Def<BallAndStickProps>) +export function BallAndStickRepresentation(getParams: ParamsGetter): BallAndStickRepresentation { + return Representation.createMulti('Ball & Stick', getParams, BallAndStickVisuals as unknown as Representation.Def<Structure, BallAndStickProps>) } export const BallAndStickRepresentationProvider: StructureRepresentationProvider<typeof BallAndStickParams> = { - factory: BallAndStickRepresentation, params: getBallAndStickParams + factory: BallAndStickRepresentation, getParams: getBallAndStickParams } \ No newline at end of file diff --git a/src/mol-repr/structure/representation/cartoon.ts b/src/mol-repr/structure/representation/cartoon.ts index da2483be5..38c04eb7e 100644 --- a/src/mol-repr/structure/representation/cartoon.ts +++ b/src/mol-repr/structure/representation/cartoon.ts @@ -4,24 +4,25 @@ * @author Alexander Rose <alexander.rose@weirdbyte.de> */ -import { PolymerTraceVisual, PolymerTraceParams, PolymerTraceProps } from '../visual/polymer-trace-mesh'; -import { PolymerGapVisual, PolymerGapParams, PolymerGapProps } from '../visual/polymer-gap-cylinder'; -import { NucleotideBlockVisual, NucleotideBlockParams, NucleotideBlockProps } from '../visual/nucleotide-block-mesh'; +import { PolymerTraceVisual, PolymerTraceParams } from '../visual/polymer-trace-mesh'; +import { PolymerGapVisual, PolymerGapParams } from '../visual/polymer-gap-cylinder'; +import { NucleotideBlockVisual, NucleotideBlockParams } from '../visual/nucleotide-block-mesh'; import { ParamDefinition as PD } from 'mol-util/param-definition'; import { UnitsRepresentation } from '../units-representation'; import { StructureRepresentation, StructureRepresentationProvider } from '../representation'; -import { Representation } from 'mol-repr/representation'; -import { PolymerDirectionVisual, PolymerDirectionParams, PolymerDirectionProps } from '../visual/polymer-direction-wedge'; +import { Representation, RepresentationParamsGetter } from 'mol-repr/representation'; +import { PolymerDirectionVisual, PolymerDirectionParams } from '../visual/polymer-direction-wedge'; import { Structure } from 'mol-model/structure'; import { ThemeRegistryContext } from 'mol-theme/theme'; import { BuiltInSizeThemeName, BuiltInSizeThemeOptions } from 'mol-theme/size'; import { BuiltInColorThemeOptions, BuiltInColorThemeName } from 'mol-theme/color'; +type ParamsGetter = RepresentationParamsGetter<Structure> const CartoonVisuals = { - 'polymer-trace': (defaultProps: PolymerTraceProps) => UnitsRepresentation('Polymer trace mesh', defaultProps, PolymerTraceVisual), - 'polymer-gap': (defaultProps: PolymerGapProps) => UnitsRepresentation('Polymer gap cylinder', defaultProps, PolymerGapVisual), - 'nucleotide-block': (defaultProps: NucleotideBlockProps) => UnitsRepresentation('Nucleotide block mesh', defaultProps, NucleotideBlockVisual), - 'direction-wedge': (defaultProps: PolymerDirectionProps) => UnitsRepresentation('Polymer direction wedge', defaultProps, PolymerDirectionVisual) + 'polymer-trace': (getParams: ParamsGetter) => UnitsRepresentation('Polymer trace mesh', getParams, PolymerTraceVisual), + 'polymer-gap': (getParams: ParamsGetter) => UnitsRepresentation('Polymer gap cylinder', getParams, PolymerGapVisual), + 'nucleotide-block': (getParams: ParamsGetter) => UnitsRepresentation('Nucleotide block mesh', getParams, NucleotideBlockVisual), + 'direction-wedge': (getParams: ParamsGetter) => UnitsRepresentation('Polymer direction wedge', getParams, PolymerDirectionVisual) } type CartoonVisualName = keyof typeof CartoonVisuals const CartoonVisualOptions = Object.keys(CartoonVisuals).map(name => [name, name] as [CartoonVisualName, string]) @@ -42,10 +43,10 @@ export function getCartoonParams(ctx: ThemeRegistryContext, structure: Structure export type CartoonProps = PD.DefaultValues<typeof CartoonParams> export type CartoonRepresentation = StructureRepresentation<CartoonProps> -export function CartoonRepresentation(defaultProps: CartoonProps): CartoonRepresentation { - return Representation.createMulti('Cartoon', defaultProps, CartoonVisuals as unknown as Representation.Def<CartoonProps>) +export function CartoonRepresentation(getParams: ParamsGetter): CartoonRepresentation { + return Representation.createMulti('Cartoon', getParams, CartoonVisuals as unknown as Representation.Def<Structure, CartoonProps>) } export const CartoonRepresentationProvider: StructureRepresentationProvider<typeof CartoonParams> = { - factory: CartoonRepresentation, params: getCartoonParams + factory: CartoonRepresentation, getParams: getCartoonParams } \ No newline at end of file diff --git a/src/mol-repr/structure/units-representation.ts b/src/mol-repr/structure/units-representation.ts index 3f1b1026d..94a512c76 100644 --- a/src/mol-repr/structure/units-representation.ts +++ b/src/mol-repr/structure/units-representation.ts @@ -8,25 +8,31 @@ import { Structure, Unit } from 'mol-model/structure'; import { Task } from 'mol-task' import { RenderObject } from 'mol-gl/render-object'; -import { RepresentationProps, Visual, RepresentationContext } from '../representation'; +import { RepresentationProps, Visual, RepresentationContext, RepresentationParamsGetter } from '../representation'; import { Loci, EmptyLoci, isEmptyLoci } from 'mol-model/loci'; import { StructureGroup } from './units-visual'; import { StructureProps, StructureRepresentation } from './representation'; import { PickingId } from 'mol-geo/geometry/picking'; import { MarkerAction } from 'mol-geo/geometry/marker-data'; import { Theme, ThemeProps, createTheme } from 'mol-theme/theme'; +import { ParamDefinition as PD } from 'mol-util/param-definition'; export interface UnitsVisual<P extends RepresentationProps = {}> extends Visual<StructureGroup, P> { } -export function UnitsRepresentation<P extends StructureProps>(label: string, defaultProps: P, visualCtor: () => UnitsVisual<P>): StructureRepresentation<P> { +export function UnitsRepresentation<P extends StructureProps>(label: string, getParams: RepresentationParamsGetter<Structure>, visualCtor: () => UnitsVisual<P>): StructureRepresentation<P> { let visuals = new Map<number, { group: Unit.SymmetryGroup, visual: UnitsVisual<P> }>() let _structure: Structure let _groups: ReadonlyArray<Unit.SymmetryGroup> - let _props: P = Object.assign({}, defaultProps) + let _params: PD.Params + let _props: P let _theme: Theme function createOrUpdate(ctx: RepresentationContext, props: Partial<P> = {}, themeProps: ThemeProps = {}, structure?: Structure) { + if (structure && structure !== _structure) { + _params = getParams(ctx, structure) + if (!_props) _props = PD.getDefaultValues(_params) as P + } _props = Object.assign({}, _props, props) _theme = createTheme(ctx, { structure: structure || _structure }, props, themeProps, _theme) @@ -139,9 +145,8 @@ export function UnitsRepresentation<P extends StructureProps>(label: string, def }) return renderObjects }, - get props() { - return _props - }, + get props() { return _props }, + get params() { return _params }, createOrUpdate, getLoci, mark, diff --git a/src/mol-repr/volume/direct-volume.ts b/src/mol-repr/volume/direct-volume.ts index 18c0ba431..59052c648 100644 --- a/src/mol-repr/volume/direct-volume.ts +++ b/src/mol-repr/volume/direct-volume.ts @@ -8,7 +8,7 @@ import { VolumeData } from 'mol-model/volume' import { RuntimeContext } from 'mol-task' import { VolumeVisual, VolumeRepresentation } from './representation'; import { createDirectVolumeRenderObject } from 'mol-gl/render-object'; -import { Loci, EmptyLoci } from 'mol-model/loci'; +import { EmptyLoci } from 'mol-model/loci'; import { ParamDefinition as PD } from 'mol-util/param-definition'; import { Vec3, Mat4 } from 'mol-math/linear-algebra'; import { Box3D } from 'mol-math/geometry'; @@ -18,11 +18,9 @@ import { LocationIterator } from 'mol-geo/util/location-iterator'; import { createIdentityTransform } from 'mol-geo/geometry/transform-data'; import { DirectVolume } from 'mol-geo/geometry/direct-volume/direct-volume'; import { Geometry, createRenderableState } from 'mol-geo/geometry/geometry'; -import { PickingId } from 'mol-geo/geometry/picking'; -import { MarkerAction } from 'mol-geo/geometry/marker-data'; import { VisualUpdateState } from 'mol-repr/util'; -import { VisualContext, RepresentationContext } from 'mol-repr/representation'; -import { ThemeProps, Theme } from 'mol-theme/theme'; +import { VisualContext } from 'mol-repr/representation'; +import { Theme, ThemeRegistryContext } from 'mol-theme/theme'; function getBoundingBox(gridDimension: Vec3, transform: Mat4) { const bbox = Box3D.empty() @@ -114,8 +112,6 @@ function createVolumeTexture3d(volume: VolumeData) { const array = new Uint8Array(width * height * depth * 4) const textureVolume = { array, width, height, depth } - console.log('stats', stats) - let i = 0 for (let z = 0; z < depth; ++z) { for (let y = 0; y < height; ++y) { @@ -124,36 +120,11 @@ function createVolumeTexture3d(volume: VolumeData) { console.log(get(data, x, y, z), ((get(data, x, y, z) - stats.min) / (stats.max - stats.min)) * 255) } array[i + 3] = ((get(data, x, y, z) - stats.min) / (stats.max - stats.min)) * 255 - // array[i + 3] = ((get(data, x, z, y) - stats.min) / (stats.max - stats.min)) * 255 - // array[i + 3] = ((get(data, y, x, z) - stats.min) / (stats.max - stats.min)) * 255 - // array[i + 3] = ((get(data, y, z, x) - stats.min) / (stats.max - stats.min)) * 255 - // array[i + 3] = ((get(data, z, y, x) - stats.min) / (stats.max - stats.min)) * 255 - // array[i + 3] = ((get(data, z, x, y) - stats.min) / (stats.max - stats.min)) * 255 i += 4 } } } - // let i = 0 - // for (let z = 0; z < depth; ++z) { - // for (let x = 0; x < width; ++x) { - // for (let y = 0; y < height; ++y) { - // array[i + 3] = ((get(data, x, y, z) - stats.min) / (stats.max - stats.min)) * 255 - // i += 4 - // } - // } - // } - - // let i = 0 - // for (let x = 0; x < width; ++x) { - // for (let y = 0; y < height; ++y) { - // for (let z = 0; z < depth; ++z) { - // array[i + 3] = ((get(data, x, y, z) - stats.min) / (stats.max - stats.min)) * 255 - // i += 4 - // } - // } - // } - return textureVolume } @@ -188,12 +159,14 @@ export const DirectVolumeParams = { ...Geometry.Params, ...DirectVolume.Params } -export const DefaultDirectVolumeProps = PD.getDefaultValues(DirectVolumeParams) -export type DirectVolumeProps = typeof DefaultDirectVolumeProps +export function getDirectVolumeParams(ctx: ThemeRegistryContext, volume: VolumeData) { + return DirectVolumeParams // TODO return copy +} +export type DirectVolumeProps = PD.DefaultValues<typeof DirectVolumeParams> export function DirectVolumeVisual(): VolumeVisual<DirectVolumeProps> { return VolumeVisual<DirectVolumeProps>({ - defaultProps: DefaultDirectVolumeProps, + defaultProps: PD.getDefaultValues(DirectVolumeParams), createGeometry: createDirectVolume, getLoci: () => EmptyLoci, mark: () => false, @@ -210,28 +183,5 @@ export function DirectVolumeVisual(): VolumeVisual<DirectVolumeProps> { } export function DirectVolumeRepresentation(): VolumeRepresentation<DirectVolumeProps> { - let currentProps: DirectVolumeProps - const volumeRepr = VolumeRepresentation(DirectVolumeVisual) - return { - label: 'Direct Volume', - get renderObjects() { - return [ ...volumeRepr.renderObjects ] - }, - get props() { - return { ...volumeRepr.props } - }, - createOrUpdate: (ctx: RepresentationContext, props: Partial<DirectVolumeProps> = {}, themeProps: ThemeProps = {}, volume?: VolumeData) => { - currentProps = Object.assign({}, DefaultDirectVolumeProps, currentProps, props) - return volumeRepr.createOrUpdate(ctx, currentProps, themeProps, volume) - }, - getLoci: (pickingId: PickingId) => { - return volumeRepr.getLoci(pickingId) - }, - mark: (loci: Loci, action: MarkerAction) => { - return volumeRepr.mark(loci, action) - }, - destroy() { - volumeRepr.destroy() - } - } + return VolumeRepresentation('Direct Volume', getDirectVolumeParams, DirectVolumeVisual) } \ No newline at end of file diff --git a/src/mol-repr/volume/isosurface-mesh.ts b/src/mol-repr/volume/isosurface-mesh.ts index 7ba955e50..78b896a04 100644 --- a/src/mol-repr/volume/isosurface-mesh.ts +++ b/src/mol-repr/volume/isosurface-mesh.ts @@ -8,18 +8,16 @@ import { VolumeData } from 'mol-model/volume' import { VolumeVisual, VolumeRepresentation } from './representation'; import { createMeshRenderObject } from 'mol-gl/render-object'; -import { Loci, EmptyLoci } from 'mol-model/loci'; +import { EmptyLoci } from 'mol-model/loci'; import { ParamDefinition as PD } from 'mol-util/param-definition'; import { Mesh } from 'mol-geo/geometry/mesh/mesh'; import { computeMarchingCubesMesh } from 'mol-geo/util/marching-cubes/algorithm'; import { LocationIterator } from 'mol-geo/util/location-iterator'; import { createIdentityTransform } from 'mol-geo/geometry/transform-data'; import { createRenderableState } from 'mol-geo/geometry/geometry'; -import { PickingId } from 'mol-geo/geometry/picking'; -import { MarkerAction } from 'mol-geo/geometry/marker-data'; import { VisualUpdateState } from 'mol-repr/util'; -import { RepresentationContext, VisualContext } from 'mol-repr/representation'; -import { ThemeProps, Theme } from 'mol-theme/theme'; +import { VisualContext } from 'mol-repr/representation'; +import { Theme, ThemeRegistryContext } from 'mol-theme/theme'; interface VolumeIsosurfaceProps { isoValueAbsolute: number @@ -46,12 +44,14 @@ export const IsosurfaceParams = { isoValueAbsolute: PD.Range('Iso Value Absolute', '', 0.22, -1, 1, 0.01), isoValueRelative: PD.Range('Iso Value Relative', '', 2, -10, 10, 0.1), } -export const DefaultIsosurfaceProps = PD.getDefaultValues(IsosurfaceParams) -export type IsosurfaceProps = typeof DefaultIsosurfaceProps +export function getIsosurfaceParams(ctx: ThemeRegistryContext, volume: VolumeData) { + return IsosurfaceParams // TODO return copy +} +export type IsosurfaceProps = PD.DefaultValues<typeof IsosurfaceParams> export function IsosurfaceVisual(): VolumeVisual<IsosurfaceProps> { return VolumeVisual<IsosurfaceProps>({ - defaultProps: DefaultIsosurfaceProps, + defaultProps: PD.getDefaultValues(IsosurfaceParams), createGeometry: createVolumeIsosurface, getLoci: () => EmptyLoci, mark: () => false, @@ -69,28 +69,5 @@ export function IsosurfaceVisual(): VolumeVisual<IsosurfaceProps> { } export function IsosurfaceRepresentation(): VolumeRepresentation<IsosurfaceProps> { - let currentProps: IsosurfaceProps - const volumeRepr = VolumeRepresentation(IsosurfaceVisual) - return { - label: 'Isosurface', - get renderObjects() { - return [ ...volumeRepr.renderObjects ] - }, - get props() { - return { ...volumeRepr.props } - }, - createOrUpdate: (ctx: RepresentationContext, props: Partial<IsosurfaceProps> = {}, themeProps: ThemeProps = {}, volume?: VolumeData) => { - currentProps = Object.assign({}, DefaultIsosurfaceProps, currentProps, props) - return volumeRepr.createOrUpdate(ctx, currentProps, themeProps, volume) - }, - getLoci: (pickingId: PickingId) => { - return volumeRepr.getLoci(pickingId) - }, - mark: (loci: Loci, action: MarkerAction) => { - return volumeRepr.mark(loci, action) - }, - destroy() { - volumeRepr.destroy() - } - } + return VolumeRepresentation('Isosurface', getIsosurfaceParams, IsosurfaceVisual) } \ No newline at end of file diff --git a/src/mol-repr/volume/registry.ts b/src/mol-repr/volume/registry.ts index 653649b28..30f5902bc 100644 --- a/src/mol-repr/volume/registry.ts +++ b/src/mol-repr/volume/registry.ts @@ -12,7 +12,7 @@ export class VolumeRepresentationRegistry extends RepresentationRegistry<VolumeD super() Object.keys(BuiltInVolumeRepresentations).forEach(name => { const p = (BuiltInVolumeRepresentations as { [k: string]: RepresentationProvider<VolumeData, any> })[name] - this.add(name, p.factory, p.params) + this.add(name, p.factory, p.getParams) }) } } diff --git a/src/mol-repr/volume/representation.ts b/src/mol-repr/volume/representation.ts index bca67799d..c4240356a 100644 --- a/src/mol-repr/volume/representation.ts +++ b/src/mol-repr/volume/representation.ts @@ -5,7 +5,7 @@ */ import { Task } from 'mol-task' -import { RepresentationProps, Representation, Visual, RepresentationContext, VisualContext, RepresentationProvider } from '../representation'; +import { RepresentationProps, Representation, Visual, RepresentationContext, VisualContext, RepresentationProvider, RepresentationParamsGetter } from '../representation'; import { VolumeData, VolumeIsoValue } from 'mol-model/volume'; import { Loci, EmptyLoci, isEveryLoci } from 'mol-model/loci'; import { Geometry, updateRenderableState } from 'mol-geo/geometry/geometry'; @@ -147,13 +147,21 @@ export const VolumeParams = { export const DefaultVolumeProps = PD.getDefaultValues(VolumeParams) export type VolumeProps = typeof DefaultVolumeProps -export function VolumeRepresentation<P extends VolumeProps>(visualCtor: (volumeData: VolumeData) => VolumeVisual<P>): VolumeRepresentation<P> { - let visual: VolumeVisual<any> +export function VolumeRepresentation<P extends VolumeProps>(label: string, getParams: RepresentationParamsGetter<VolumeData>, visualCtor: (volume: VolumeData) => VolumeVisual<P>): VolumeRepresentation<P> { + let visual: VolumeVisual<P> + + let _volume: VolumeData let _props: P + let _params: PD.Params let _theme: Theme let busy = false - function createOrUpdate(ctx: RepresentationContext, props: Partial<P> = {}, themeProps: ThemeProps = {}, volumeData?: VolumeData) { + function createOrUpdate(ctx: RepresentationContext, props: Partial<P> = {}, themeProps: ThemeProps = {}, volume?: VolumeData) { + if (volume && volume !== _volume) { + _params = getParams(ctx, volume) + _volume = volume + if (!_props) _props = PD.getDefaultValues(_params) as P + } _props = Object.assign({}, DefaultVolumeProps, _props, props) _theme = createTheme(ctx, _props, themeProps, {}, _theme) @@ -161,38 +169,43 @@ export function VolumeRepresentation<P extends VolumeProps>(visualCtor: (volumeD // TODO queue it somehow if (busy) return - if (!visual && !volumeData) { - throw new Error('volumeData missing') - } else if (volumeData && !visual) { + if (!visual && !volume) { + throw new Error('volume data missing') + } else if (volume && !visual) { busy = true - visual = visualCtor(volumeData) - await visual.createOrUpdate({ ...ctx, runtime }, _theme, _props, volumeData) + visual = visualCtor(volume) + await visual.createOrUpdate({ ...ctx, runtime }, _theme, _props, volume) busy = false } else { busy = true - await visual.createOrUpdate({ ...ctx, runtime }, _theme, _props, volumeData) + await visual.createOrUpdate({ ...ctx, runtime }, _theme, _props, volume) busy = false } }); } + function getLoci(pickingId: PickingId) { + return visual ? visual.getLoci(pickingId) : EmptyLoci + } + + function mark(loci: Loci, action: MarkerAction) { + return visual ? visual.mark(loci, action) : false + } + + function destroy() { + if (visual) visual.destroy() + } + return { - label: 'Volume', + label, get renderObjects() { return visual && visual.renderObject ? [ visual.renderObject ] : [] }, get props () { return _props }, + get params() { return _params }, createOrUpdate, - getLoci(pickingId: PickingId) { - // TODO - return EmptyLoci - }, - mark(loci: Loci, action: MarkerAction) { - // TODO - return false - }, - destroy() { - // TODO - } + getLoci, + mark, + destroy } } \ No newline at end of file -- GitLab