diff --git a/src/mol-repr/index.ts b/src/mol-repr/index.ts index 447aba5461ffe173aa1c476dbb8ffc27e8fac8b1..83a39d2e0423353e61c93229d6c01395b6962e18 100644 --- a/src/mol-repr/index.ts +++ b/src/mol-repr/index.ts @@ -7,11 +7,14 @@ import { Task, RuntimeContext } from 'mol-task' import { RenderObject } from 'mol-gl/render-object' import { PickingId } from '../mol-geo/geometry/picking'; -import { Loci } from 'mol-model/loci'; +import { Loci, isEmptyLoci, EmptyLoci } from 'mol-model/loci'; import { MarkerAction } from '../mol-geo/geometry/marker-data'; -import { Params } from 'mol-util/parameter'; +import { Params, MultiSelectParam } from 'mol-util/parameter'; -export interface RepresentationProps {} +// export interface RepresentationProps { +// visuals?: string[] +// } +export type RepresentationProps = { [k: string]: any } export interface Representation<D, P extends RepresentationProps = {}> { readonly label: string @@ -24,7 +27,78 @@ export interface Representation<D, P extends RepresentationProps = {}> { destroy: () => void } -export interface Visual<D, P extends RepresentationProps = {}> { +export namespace Representation { + export function createMulti<D, P extends RepresentationProps = {}>(label: string, params: Params, defaultProps: P, reprList: Representation<D, P>[]): Representation<D, P> { + let currentProps: P + let currentData: D + + const visualsOptions: [string, string][] = [] + for (let i = 0, il = reprList.length; i < il; ++i) { + visualsOptions.push([ i.toString(), reprList[i].label ]) + } + params['visuals'] = MultiSelectParam<string>('Visuals', '', ['surface'], visualsOptions) + + if (!defaultProps.visuals) { + defaultProps.visuals = reprList.map((r, i) => i.toString()) + } + + return { + label, + params, + get renderObjects() { + const { visuals } = currentProps + const renderObjects: RenderObject[] = [] + for (let i = 0, il = reprList.length; i < il; ++i) { + if (!visuals || visuals.includes(i.toString())) { + renderObjects.push(...reprList[i].renderObjects) + } + } + return renderObjects + }, + get props() { + const props = {} + reprList.forEach(r => Object.assign(props, r.props)) + return props as P + }, + createOrUpdate: (props: Partial<P> = {}, data?: D) => { + if (data) currentData = data + // const qualityProps = getQualityProps(Object.assign({}, currentProps, props), structure) + // currentProps = Object.assign({}, DefaultCartoonProps, currentProps, props, qualityProps) + currentProps = Object.assign({}, defaultProps, currentProps, props) + + const { visuals } = currentProps + return Task.create(`Creating '${label}' representation`, async ctx => { + for (let i = 0, il = reprList.length; i < il; ++i) { + if (!visuals || visuals.includes(i.toString())) { + await reprList[i].createOrUpdate(currentProps, currentData).runInContext(ctx) + } + } + }) + }, + getLoci: (pickingId: PickingId) => { + for (let i = 0, il = reprList.length; i < il; ++i) { + const loci = reprList[i].getLoci(pickingId) + if (!isEmptyLoci(loci)) return loci + } + return EmptyLoci + }, + mark: (loci: Loci, action: MarkerAction) => { + let marked = false + for (let i = 0, il = reprList.length; i < il; ++i) { + marked = reprList[i].mark(loci, action) || marked + } + return marked + }, + destroy() { + for (let i = 0, il = reprList.length; i < il; ++i) { + reprList[i].destroy() + } + } + } + } +} + +export interface Visual<D, P extends RepresentationProps> { readonly renderObject: RenderObject | undefined createOrUpdate: (ctx: RuntimeContext, props?: Partial<P>, data?: D) => Promise<void> getLoci: (pickingId: PickingId) => Loci diff --git a/src/mol-repr/structure/index.ts b/src/mol-repr/structure/index.ts index 07692cf84a17f3c068f1eefb8673d18b28583c36..800c07203b045521222975e2982c655134c40e6d 100644 --- a/src/mol-repr/structure/index.ts +++ b/src/mol-repr/structure/index.ts @@ -17,10 +17,8 @@ import { Lines } from 'mol-geo/geometry/lines/lines'; import { DirectVolume } from 'mol-geo/geometry/direct-volume/direct-volume'; export interface StructureRepresentation<P extends RepresentationProps = {}> extends Representation<Structure, P> { } - // export interface StructureVisual<P extends RepresentationProps = {}> extends Visual<Structure, P> { } - export const StructureParams = { ...Geometry.Params, colorTheme: SelectParam<ColorThemeName>('Color Theme', '', 'polymer-index', ColorThemeOptions), diff --git a/src/mol-repr/structure/representation/backbone.ts b/src/mol-repr/structure/representation/backbone.ts index 8c82b62289b13e8f36d1e458eda2cae6cd628350..eea531a2eb38bc38130ec0e6efdba6bd865b85aa 100644 --- a/src/mol-repr/structure/representation/backbone.ts +++ b/src/mol-repr/structure/representation/backbone.ts @@ -4,16 +4,11 @@ * @author Alexander Rose <alexander.rose@weirdbyte.de> */ -import { Structure } from 'mol-model/structure'; -import { Task } from 'mol-task'; -import { Loci } from 'mol-model/loci'; import { PolymerBackboneVisual, PolymerBackboneParams } from '../visual/polymer-backbone-cylinder'; -import { getQualityProps } from '../../util'; import { paramDefaultValues } from 'mol-util/parameter'; import { UnitsRepresentation } from '../units-representation'; -import { PickingId } from 'mol-geo/geometry/picking'; -import { MarkerAction } from 'mol-geo/geometry/marker-data'; import { StructureRepresentation } from '../index'; +import { Representation } from 'mol-repr'; export const BackboneParams = { ...PolymerBackboneParams @@ -24,33 +19,7 @@ export type BackboneProps = typeof DefaultBackboneProps export type BackboneRepresentation = StructureRepresentation<BackboneProps> export function BackboneRepresentation(): BackboneRepresentation { - const traceRepr = UnitsRepresentation('Polymer backbone cylinder', PolymerBackboneVisual) - - let currentProps: BackboneProps - return { - label: 'Backbone', - params: BackboneParams, - get renderObjects() { - return [ ...traceRepr.renderObjects ] - }, - get props() { - return { ...traceRepr.props } - }, - createOrUpdate: (props: Partial<BackboneProps> = {}, structure?: Structure) => { - const qualityProps = getQualityProps(Object.assign({}, currentProps, props), structure) - currentProps = Object.assign({}, DefaultBackboneProps, currentProps, props, qualityProps) - return Task.create('BackboneRepresentation', async ctx => { - await traceRepr.createOrUpdate(currentProps, structure).runInContext(ctx) - }) - }, - getLoci: (pickingId: PickingId) => { - return traceRepr.getLoci(pickingId) - }, - mark: (loci: Loci, action: MarkerAction) => { - return traceRepr.mark(loci, action) - }, - destroy() { - traceRepr.destroy() - } - } + return Representation.createMulti('Backbone', BackboneParams, DefaultBackboneProps, [ + UnitsRepresentation('Polymer backbone cylinder', PolymerBackboneVisual) + ] as StructureRepresentation<BackboneProps>[]) } \ No newline at end of file diff --git a/src/mol-repr/structure/representation/ball-and-stick.ts b/src/mol-repr/structure/representation/ball-and-stick.ts index 493815b9cba8150ce7cad4961716c8d249ae3b28..f4271f3a803887ec32ba5bba9d5e9749b38dc996 100644 --- a/src/mol-repr/structure/representation/ball-and-stick.ts +++ b/src/mol-repr/structure/representation/ball-and-stick.ts @@ -6,23 +6,19 @@ import { ElementSphereVisual, ElementSphereParams } from '../visual/element-sphere'; import { IntraUnitLinkVisual, IntraUnitLinkParams } from '../visual/intra-unit-link-cylinder'; -import { Structure } from 'mol-model/structure'; -import { Task } from 'mol-task'; -import { Loci, isEmptyLoci } from 'mol-model/loci'; -import { InterUnitLinkVisual } from '../visual/inter-unit-link-cylinder'; +import { InterUnitLinkVisual, InterUnitLinkParams } from '../visual/inter-unit-link-cylinder'; import { SizeThemeName, SizeThemeOptions } from 'mol-theme/size'; -import { getQualityProps } from '../../util'; import { paramDefaultValues, SelectParam, NumberParam, MultiSelectParam } from 'mol-util/parameter'; import { UnitKind, UnitKindOptions } from '../visual/util/common'; import { UnitsRepresentation } from '../units-representation'; -import { PickingId } from 'mol-geo/geometry/picking'; -import { MarkerAction } from 'mol-geo/geometry/marker-data'; import { ComplexRepresentation } from '../complex-representation'; import { StructureRepresentation } from '../index'; +import { Representation } from 'mol-repr'; export const BallAndStickParams = { ...ElementSphereParams, ...IntraUnitLinkParams, + ...InterUnitLinkParams, sizeTheme: SelectParam<SizeThemeName>('Size Theme', '', 'uniform', SizeThemeOptions), sizeValue: NumberParam('Size Value', '', 0.2, 0, 10, 0.1), sizeFactor: NumberParam('Size Factor', '', 1, 0, 10, 0.1), @@ -34,53 +30,9 @@ export type BallAndStickProps = typeof DefaultBallAndStickProps export type BallAndStickRepresentation = StructureRepresentation<BallAndStickProps> export function BallAndStickRepresentation(): BallAndStickRepresentation { - const elmementRepr = UnitsRepresentation('Element sphere mesh', ElementSphereVisual) - const intraLinkRepr = UnitsRepresentation('Intra-unit link cylinder', IntraUnitLinkVisual) - const interLinkRepr = ComplexRepresentation('Inter-unit link cylinder', InterUnitLinkVisual) - - let currentProps: BallAndStickProps - return { - label: 'Ball & Stick', - params: BallAndStickParams, - get renderObjects() { - return [ ...elmementRepr.renderObjects, ...intraLinkRepr.renderObjects, ...interLinkRepr.renderObjects ] - }, - get props() { - return { ...elmementRepr.props, ...intraLinkRepr.props, ...interLinkRepr.props } - }, - createOrUpdate: (props: Partial<BallAndStickProps> = {}, structure?: Structure) => { - const qualityProps = getQualityProps(Object.assign({}, currentProps, props), structure) - currentProps = Object.assign({}, DefaultBallAndStickProps, currentProps, props, qualityProps) - return Task.create('BallAndStickRepresentation', async ctx => { - await elmementRepr.createOrUpdate(currentProps, structure).runInContext(ctx) - await intraLinkRepr.createOrUpdate(currentProps, structure).runInContext(ctx) - await interLinkRepr.createOrUpdate(currentProps, structure).runInContext(ctx) - }) - }, - getLoci: (pickingId: PickingId) => { - const sphereLoci = elmementRepr.getLoci(pickingId) - const intraLinkLoci = intraLinkRepr.getLoci(pickingId) - const interLinkLoci = interLinkRepr.getLoci(pickingId) - if (isEmptyLoci(sphereLoci)) { - if (isEmptyLoci(intraLinkLoci)) { - return interLinkLoci - } else { - return intraLinkLoci - } - } else { - return sphereLoci - } - }, - mark: (loci: Loci, action: MarkerAction) => { - const markElement = elmementRepr.mark(loci, action) - const markIntraLink = intraLinkRepr.mark(loci, action) - const markInterLink = interLinkRepr.mark(loci, action) - return markElement || markIntraLink || markInterLink - }, - destroy() { - elmementRepr.destroy() - intraLinkRepr.destroy() - interLinkRepr.destroy() - } - } + return Representation.createMulti('Ball & Stick', BallAndStickParams, DefaultBallAndStickProps, [ + UnitsRepresentation('Element sphere mesh', ElementSphereVisual), + UnitsRepresentation('Intra-unit link cylinder', IntraUnitLinkVisual), + ComplexRepresentation('Inter-unit link cylinder', InterUnitLinkVisual) + ] as unknown as StructureRepresentation<BallAndStickProps>[]) // TODO avoid cast to unknown } \ No newline at end of file diff --git a/src/mol-repr/structure/representation/carbohydrate.ts b/src/mol-repr/structure/representation/carbohydrate.ts index 4fc4cb1cc3f92f1a1343fa22ffe415857871af44..941fda8878243123069dfae22f20fd0df4e1b20e 100644 --- a/src/mol-repr/structure/representation/carbohydrate.ts +++ b/src/mol-repr/structure/representation/carbohydrate.ts @@ -4,18 +4,13 @@ * @author Alexander Rose <alexander.rose@weirdbyte.de> */ -import { Structure } from 'mol-model/structure'; -import { Task } from 'mol-task'; -import { Loci, isEmptyLoci } from 'mol-model/loci'; import { CarbohydrateSymbolVisual, CarbohydrateSymbolParams } from '../visual/carbohydrate-symbol-mesh'; import { CarbohydrateLinkVisual, CarbohydrateLinkParams } from '../visual/carbohydrate-link-cylinder'; import { SizeThemeName, SizeThemeOptions } from 'mol-theme/size'; -import { getQualityProps } from '../../util'; import { paramDefaultValues, SelectParam, NumberParam } from 'mol-util/parameter'; -import { PickingId } from 'mol-geo/geometry/picking'; -import { MarkerAction } from 'mol-geo/geometry/marker-data'; import { ComplexRepresentation } from '../complex-representation'; import { StructureRepresentation } from '../index'; +import { Representation } from 'mol-repr'; export const CarbohydrateParams = { ...CarbohydrateSymbolParams, @@ -30,41 +25,8 @@ export type CarbohydrateProps = typeof DefaultCarbohydrateProps export type CarbohydrateRepresentation = StructureRepresentation<CarbohydrateProps> export function CarbohydrateRepresentation(): CarbohydrateRepresentation { - const carbohydrateSymbolRepr = ComplexRepresentation('Carbohydrate symbol mesh', CarbohydrateSymbolVisual) - const carbohydrateLinkRepr = ComplexRepresentation('Carbohydrate link cylinder', CarbohydrateLinkVisual) - - let currentProps: CarbohydrateProps - return { - label: 'Carbohydrate', - params: CarbohydrateParams, - get renderObjects() { - return [ ...carbohydrateSymbolRepr.renderObjects, ...carbohydrateLinkRepr.renderObjects ] - }, - get props() { - return { ...carbohydrateSymbolRepr.props, ...carbohydrateLinkRepr.props } - }, - createOrUpdate: (props: Partial<CarbohydrateProps> = {}, structure?: Structure) => { - const qualityProps = getQualityProps(Object.assign({}, currentProps, props), structure) - currentProps = Object.assign({}, DefaultCarbohydrateProps, currentProps, props, qualityProps) - return Task.create('Creating CarbohydrateRepresentation', async ctx => { - await carbohydrateSymbolRepr.createOrUpdate(currentProps, structure).runInContext(ctx) - await carbohydrateLinkRepr.createOrUpdate(currentProps, structure).runInContext(ctx) - }) - }, - getLoci: (pickingId: PickingId) => { - const carbohydrateSymbolLoci = carbohydrateSymbolRepr.getLoci(pickingId) - const carbohydrateLinkLoci = carbohydrateLinkRepr.getLoci(pickingId) - return !isEmptyLoci(carbohydrateSymbolLoci) ? carbohydrateSymbolLoci - : carbohydrateLinkLoci - }, - mark: (loci: Loci, action: MarkerAction) => { - const markSymbol = carbohydrateSymbolRepr.mark(loci, action) - const markLink = carbohydrateLinkRepr.mark(loci, action) - return markSymbol || markLink - }, - destroy() { - carbohydrateSymbolRepr.destroy() - carbohydrateLinkRepr.destroy() - } - } + return Representation.createMulti('Carbohydrate', CarbohydrateParams, DefaultCarbohydrateProps, [ + ComplexRepresentation('Carbohydrate symbol mesh', CarbohydrateSymbolVisual), + ComplexRepresentation('Carbohydrate link cylinder', CarbohydrateLinkVisual) + ] as StructureRepresentation<CarbohydrateProps>[]) } \ 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 b4c5fa65748982b5278e76c3134763dc4916cf8f..6a4e48bb0ed2fb78aa0ff5397d36c414fd721389 100644 --- a/src/mol-repr/structure/representation/cartoon.ts +++ b/src/mol-repr/structure/representation/cartoon.ts @@ -4,19 +4,14 @@ * @author Alexander Rose <alexander.rose@weirdbyte.de> */ -import { Structure } from 'mol-model/structure'; -import { Task } from 'mol-task'; -import { Loci, isEmptyLoci } from 'mol-model/loci'; 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 { SizeThemeName, SizeThemeOptions } from 'mol-theme/size'; -import { getQualityProps } from '../../util'; import { paramDefaultValues, SelectParam, NumberParam } from 'mol-util/parameter'; import { UnitsRepresentation } from '../units-representation'; -import { PickingId } from 'mol-geo/geometry/picking'; -import { MarkerAction } from 'mol-geo/geometry/marker-data'; import { StructureRepresentation } from '../index'; +import { Representation } from 'mol-repr'; // import { PolymerDirectionVisual, DefaultPolymerDirectionProps } from '../visual/polymer-direction-wedge'; export const CartoonParams = { @@ -33,56 +28,10 @@ export type CartoonProps = typeof DefaultCartoonProps export type CartoonRepresentation = StructureRepresentation<CartoonProps> export function CartoonRepresentation(): CartoonRepresentation { - const traceRepr = UnitsRepresentation('Polymer trace mesh', PolymerTraceVisual) - const gapRepr = UnitsRepresentation('Polymer gap cylinder', PolymerGapVisual) - const blockRepr = UnitsRepresentation('Nucleotide block mesh', NucleotideBlockVisual) - // const directionRepr = UnitsRepresentation('Polymer direction wedge', PolymerDirectionVisual) - - let currentProps: CartoonProps - return { - label: 'Cartoon', - params: CartoonParams, - get renderObjects() { - return [ ...traceRepr.renderObjects, ...gapRepr.renderObjects, - ...blockRepr.renderObjects // , ...directionRepr.renderObjects - ] - }, - get props() { - return { ...traceRepr.props, ...gapRepr.props, ...blockRepr.props } - }, - createOrUpdate: (props: Partial<CartoonProps> = {}, structure?: Structure) => { - const qualityProps = getQualityProps(Object.assign({}, currentProps, props), structure) - currentProps = Object.assign({}, DefaultCartoonProps, currentProps, props, qualityProps) - return Task.create('Creating CartoonRepresentation', async ctx => { - await traceRepr.createOrUpdate(currentProps, structure).runInContext(ctx) - await gapRepr.createOrUpdate(currentProps, structure).runInContext(ctx) - await blockRepr.createOrUpdate(currentProps, structure).runInContext(ctx) - // await directionRepr.createOrUpdate(currentProps, structure).runInContext(ctx) - }) - }, - getLoci: (pickingId: PickingId) => { - const traceLoci = traceRepr.getLoci(pickingId) - const gapLoci = gapRepr.getLoci(pickingId) - const blockLoci = blockRepr.getLoci(pickingId) - // const directionLoci = directionRepr.getLoci(pickingId) - return !isEmptyLoci(traceLoci) ? traceLoci - : !isEmptyLoci(gapLoci) ? gapLoci - : blockLoci - // : !isEmptyLoci(blockLoci) ? blockLoci - // : directionLoci - }, - mark: (loci: Loci, action: MarkerAction) => { - const markTrace = traceRepr.mark(loci, action) - const markGap = gapRepr.mark(loci, action) - const markBlock = blockRepr.mark(loci, action) - // const markDirection = directionRepr.mark(loci, action) - return markTrace || markGap || markBlock // \\ markDirection - }, - destroy() { - traceRepr.destroy() - gapRepr.destroy() - blockRepr.destroy() - // directionRepr.destroy() - } - } + return Representation.createMulti('Cartoon', CartoonParams, DefaultCartoonProps, [ + UnitsRepresentation('Polymer trace mesh', PolymerTraceVisual), + UnitsRepresentation('Polymer gap cylinder', PolymerGapVisual), + UnitsRepresentation('Nucleotide block mesh', NucleotideBlockVisual), + // UnitsRepresentation('Polymer direction wedge', PolymerDirectionVisual) + ] as StructureRepresentation<CartoonProps>[]) } \ No newline at end of file diff --git a/src/mol-repr/structure/representation/distance-restraint.ts b/src/mol-repr/structure/representation/distance-restraint.ts index aec99db93f07894afb598e066c0123d7a85755df..28509b3fb78b9313c53d969e70eb35134ad9c1d2 100644 --- a/src/mol-repr/structure/representation/distance-restraint.ts +++ b/src/mol-repr/structure/representation/distance-restraint.ts @@ -4,17 +4,12 @@ * @author Alexander Rose <alexander.rose@weirdbyte.de> */ -import { Structure } from 'mol-model/structure'; -import { Task } from 'mol-task'; -import { Loci } from 'mol-model/loci'; import { CrossLinkRestraintVisual, CrossLinkRestraintParams } from '../visual/cross-link-restraint-cylinder'; import { SizeThemeName, SizeThemeOptions } from 'mol-theme/size'; -import { getQualityProps } from '../../util'; import { paramDefaultValues, SelectParam, NumberParam } from 'mol-util/parameter'; import { ComplexRepresentation } from '../complex-representation'; -import { PickingId } from 'mol-geo/geometry/picking'; -import { MarkerAction } from 'mol-geo/geometry/marker-data'; import { StructureRepresentation } from '../index'; +import { Representation } from 'mol-repr'; export const DistanceRestraintParams = { ...CrossLinkRestraintParams, @@ -27,33 +22,7 @@ export type DistanceRestraintProps = typeof DefaultDistanceRestraintProps export type DistanceRestraintRepresentation = StructureRepresentation<DistanceRestraintProps> export function DistanceRestraintRepresentation(): DistanceRestraintRepresentation { - const crossLinkRepr = ComplexRepresentation('Cross-link restraint', CrossLinkRestraintVisual) - - let currentProps: DistanceRestraintProps - return { - label: 'Distance restraint', - params: DistanceRestraintParams, - get renderObjects() { - return [ ...crossLinkRepr.renderObjects ] - }, - get props() { - return { ...crossLinkRepr.props } - }, - createOrUpdate: (props: Partial<DistanceRestraintProps> = {}, structure?: Structure) => { - const qualityProps = getQualityProps(Object.assign({}, currentProps, props), structure) - currentProps = Object.assign({}, DefaultDistanceRestraintProps, currentProps, props, qualityProps) - return Task.create('DistanceRestraintRepresentation', async ctx => { - await crossLinkRepr.createOrUpdate(currentProps, structure).runInContext(ctx) - }) - }, - getLoci: (pickingId: PickingId) => { - return crossLinkRepr.getLoci(pickingId) - }, - mark: (loci: Loci, action: MarkerAction) => { - return crossLinkRepr.mark(loci, action) - }, - destroy() { - crossLinkRepr.destroy() - } - } + return Representation.createMulti('Distance restraint', DistanceRestraintParams, DefaultDistanceRestraintProps, [ + ComplexRepresentation('Cross-link restraint', CrossLinkRestraintVisual) + ] as StructureRepresentation<DistanceRestraintProps>[]) } \ No newline at end of file diff --git a/src/mol-repr/structure/representation/molecular-surface.ts b/src/mol-repr/structure/representation/molecular-surface.ts index 9d68f2e44c147d35a22d256d2ec28b39dedfaa56..eed341e26444bc8ae41c7791e9f317c6511f4944 100644 --- a/src/mol-repr/structure/representation/molecular-surface.ts +++ b/src/mol-repr/structure/representation/molecular-surface.ts @@ -6,86 +6,28 @@ import { GaussianSurfaceVisual, GaussianSurfaceParams } from '../visual/gaussian-surface-mesh'; import { UnitsRepresentation } from '../units-representation'; -import { Structure } from 'mol-model/structure'; -import { Loci, isEmptyLoci } from 'mol-model/loci'; -import { Task } from 'mol-task'; import { GaussianWireframeVisual, GaussianWireframeParams } from '../visual/gaussian-surface-wireframe'; -import { getQualityProps } from '../../util'; -import { paramDefaultValues, MultiSelectParam, SelectParam } from 'mol-util/parameter'; +import { paramDefaultValues, SelectParam } from 'mol-util/parameter'; import { GaussianDensityVolumeParams, GaussianDensityVolumeVisual } from '../visual/gaussian-density-volume'; import { SizeThemeName, SizeThemeOptions } from 'mol-theme/size'; -import { PickingId } from 'mol-geo/geometry/picking'; -import { MarkerAction } from 'mol-geo/geometry/marker-data'; import { StructureRepresentation } from '../index'; - -const VisualOptions = [['surface', 'Surface'], ['wireframe', 'Wireframe'], ['volume', 'Volume']] as [string, string][] +import { Representation } from 'mol-repr'; export const MolecularSurfaceParams = { ...GaussianSurfaceParams, ...GaussianWireframeParams, ...GaussianDensityVolumeParams, - sizeTheme: SelectParam<SizeThemeName>('Size Theme', '', 'uniform', SizeThemeOptions), - visuals: MultiSelectParam<string>('Visuals', '', ['surface'], VisualOptions) } -export const DefaultMolecularSurfaceProps = paramDefaultValues(MolecularSurfaceParams) +export const DefaultMolecularSurfaceProps = { ...paramDefaultValues(MolecularSurfaceParams), visuals: [ '0' ] } export type MolecularSurfaceProps = typeof DefaultMolecularSurfaceProps export type MolecularSurfaceRepresentation = StructureRepresentation<MolecularSurfaceProps> export function MolecularSurfaceRepresentation(): MolecularSurfaceRepresentation { - let currentProps: MolecularSurfaceProps - let currentStructure: Structure - const gaussianSurfaceRepr = UnitsRepresentation('Gaussian surface', GaussianSurfaceVisual) - const gaussianWireframeRepr = UnitsRepresentation('Gaussian wireframe', GaussianWireframeVisual) - const gaussianVolumeRepr = UnitsRepresentation('Gaussian volume', GaussianDensityVolumeVisual) - return { - label: 'Molecular Surface', - params: MolecularSurfaceParams, - get renderObjects() { - const renderObjects = [] - if (currentProps.visuals.includes('surface')) renderObjects.push(...gaussianSurfaceRepr.renderObjects) - if (currentProps.visuals.includes('wireframe')) renderObjects.push(...gaussianWireframeRepr.renderObjects) - if (currentProps.visuals.includes('volume')) renderObjects.push(...gaussianVolumeRepr.renderObjects) - return renderObjects - }, - get props() { - return { ...gaussianSurfaceRepr.props, ...gaussianWireframeRepr.props, ...gaussianVolumeRepr.props, visuals: currentProps.visuals } - }, - createOrUpdate: (props: Partial<MolecularSurfaceProps> = {}, structure?: Structure) => { - if (structure) currentStructure = structure - const qualityProps = getQualityProps(Object.assign({}, currentProps, props), currentStructure) - currentProps = Object.assign({}, DefaultMolecularSurfaceProps, currentProps, props, qualityProps) - return Task.create('Creating MolecularSurfaceRepresentation', async ctx => { - if (currentProps.visuals.includes('surface')) await gaussianSurfaceRepr.createOrUpdate(currentProps, currentStructure).runInContext(ctx) - if (currentProps.visuals.includes('wireframe')) await gaussianWireframeRepr.createOrUpdate(currentProps, currentStructure).runInContext(ctx) - if (currentProps.visuals.includes('volume')) await gaussianVolumeRepr.createOrUpdate(currentProps, currentStructure).runInContext(ctx) - }) - }, - getLoci: (pickingId: PickingId) => { - const surfaceLoci = gaussianSurfaceRepr.getLoci(pickingId) - const wireframeLoci = gaussianWireframeRepr.getLoci(pickingId) - const volumeLoci = gaussianVolumeRepr.getLoci(pickingId) - if (isEmptyLoci(surfaceLoci)) { - if (isEmptyLoci(wireframeLoci)) { - return volumeLoci - } else { - return wireframeLoci - } - } else { - return surfaceLoci - } - }, - mark: (loci: Loci, action: MarkerAction) => { - const markSurfaceElement = gaussianSurfaceRepr.mark(loci, action) - const markWireframeElement = gaussianWireframeRepr.mark(loci, action) - const markVolumeElement = gaussianVolumeRepr.mark(loci, action) - return markSurfaceElement || markWireframeElement || markVolumeElement - }, - destroy() { - gaussianSurfaceRepr.destroy() - gaussianWireframeRepr.destroy() - gaussianVolumeRepr.destroy() - } - } + return Representation.createMulti('Molecular Surface', MolecularSurfaceParams, DefaultMolecularSurfaceProps, [ + UnitsRepresentation('Gaussian surface', GaussianSurfaceVisual), + UnitsRepresentation('Gaussian wireframe', GaussianWireframeVisual), + UnitsRepresentation('Gaussian volume', GaussianDensityVolumeVisual) + ] as unknown as StructureRepresentation<MolecularSurfaceProps>[]) // TODO avoid cast to unknown } \ No newline at end of file diff --git a/src/mol-repr/structure/representation/point.ts b/src/mol-repr/structure/representation/point.ts index f0c70da1dec3c5f46e51885aca3aca192ce21d3b..fc4637af4c817ec2ba787d5a8f9fdc099db4085a 100644 --- a/src/mol-repr/structure/representation/point.ts +++ b/src/mol-repr/structure/representation/point.ts @@ -6,12 +6,9 @@ import { ElementPointVisual, ElementPointParams } from '../visual/element-point'; import { UnitsRepresentation } from '../units-representation'; -import { Structure } from 'mol-model/structure'; -import { Loci } from 'mol-model/loci'; import { paramDefaultValues } from 'mol-util/parameter'; -import { PickingId } from 'mol-geo/geometry/picking'; -import { MarkerAction } from 'mol-geo/geometry/marker-data'; import { StructureRepresentation } from '../index'; +import { Representation } from 'mol-repr'; export const PointParams = { ...ElementPointParams, @@ -22,29 +19,7 @@ export type PointProps = typeof DefaultPointProps export type PointRepresentation = StructureRepresentation<PointProps> export function PointRepresentation(): PointRepresentation { - let currentProps: PointProps - const pointRepr = UnitsRepresentation('Point', ElementPointVisual) - return { - label: 'Point', - params: PointParams, - get renderObjects() { - return [ ...pointRepr.renderObjects ] - }, - get props() { - return { ...pointRepr.props } - }, - createOrUpdate: (props: Partial<PointProps> = {}, structure?: Structure) => { - currentProps = Object.assign({}, DefaultPointProps, currentProps, props) - return pointRepr.createOrUpdate(currentProps, structure) - }, - getLoci: (pickingId: PickingId) => { - return pointRepr.getLoci(pickingId) - }, - mark: (loci: Loci, action: MarkerAction) => { - return pointRepr.mark(loci, action) - }, - destroy() { - pointRepr.destroy() - } - } + return Representation.createMulti('Point', PointParams, DefaultPointProps, [ + UnitsRepresentation('Point', ElementPointVisual) + ] as StructureRepresentation<PointProps>[]) } \ No newline at end of file diff --git a/src/mol-repr/structure/representation/spacefill.ts b/src/mol-repr/structure/representation/spacefill.ts index 2c5531f4a8ba5145ecd2964c42baa422e0558d3c..d5a19bcc1d3352d7efd30c49ae8b5f50fde88713 100644 --- a/src/mol-repr/structure/representation/spacefill.ts +++ b/src/mol-repr/structure/representation/spacefill.ts @@ -6,13 +6,9 @@ import { ElementSphereVisual, ElementSphereParams } from '../visual/element-sphere'; import { UnitsRepresentation } from '../units-representation'; -import { Structure } from 'mol-model/structure'; -import { Loci } from 'mol-model/loci'; -import { getQualityProps } from '../../util'; import { paramDefaultValues } from 'mol-util/parameter'; -import { PickingId } from 'mol-geo/geometry/picking'; -import { MarkerAction } from 'mol-geo/geometry/marker-data'; import { StructureRepresentation } from '../index'; +import { Representation } from 'mol-repr'; export const SpacefillParams = { ...ElementSphereParams @@ -23,30 +19,7 @@ export type SpacefillProps = typeof DefaultSpacefillProps export type SpacefillRepresentation = StructureRepresentation<SpacefillProps> export function SpacefillRepresentation(): SpacefillRepresentation { - let currentProps: SpacefillProps - const sphereRepr = UnitsRepresentation('Sphere mesh', ElementSphereVisual) - return { - label: 'Spacefill', - params: SpacefillParams, - get renderObjects() { - return [ ...sphereRepr.renderObjects ] - }, - get props() { - return { ...sphereRepr.props } - }, - createOrUpdate: (props: Partial<SpacefillProps> = {}, structure?: Structure) => { - const qualityProps = getQualityProps(Object.assign({}, currentProps, props), structure) - currentProps = Object.assign({}, DefaultSpacefillProps, currentProps, props, qualityProps) - return sphereRepr.createOrUpdate(currentProps, structure) - }, - getLoci: (pickingId: PickingId) => { - return sphereRepr.getLoci(pickingId) - }, - mark: (loci: Loci, action: MarkerAction) => { - return sphereRepr.mark(loci, action) - }, - destroy() { - sphereRepr.destroy() - } - } + return Representation.createMulti('Spacefill', SpacefillParams, DefaultSpacefillProps, [ + UnitsRepresentation('Sphere mesh', ElementSphereVisual) + ] as StructureRepresentation<SpacefillProps>[]) } \ No newline at end of file