diff --git a/src/mol-geo/util/location-iterator.ts b/src/mol-geo/util/location-iterator.ts index 16c3517098b273acfd6fc7c48f58055fd07b335e..8c43501c13590ccffb433fbb2a4e8b5faeecdf83 100644 --- a/src/mol-geo/util/location-iterator.ts +++ b/src/mol-geo/util/location-iterator.ts @@ -28,6 +28,7 @@ export interface LocationIterator extends Iterator<LocationValue> { readonly isNextNewInstance: boolean readonly groupCount: number readonly instanceCount: number + readonly count: number /** If true, may have multiple units per instance; if false one unit per instance */ readonly isComplex: boolean move(): LocationValue @@ -55,8 +56,9 @@ export function LocationIterator(groupCount: number, instanceCount: number, getL return { get hasNext () { return hasNext }, get isNextNewInstance () { return isNextNewInstance }, - get groupCount () { return groupCount }, - get instanceCount () { return instanceCount }, + groupCount, + instanceCount, + count: groupCount * instanceCount, isComplex, move() { if (hasNext) { diff --git a/src/mol-repr/representation.ts b/src/mol-repr/representation.ts index d271a2f35b28f501a3921444c79394c1f436e1c9..f2c8b683fd2ffe30ddc353e1af8ee5fc75c4f2ae 100644 --- a/src/mol-repr/representation.ts +++ b/src/mol-repr/representation.ts @@ -81,6 +81,8 @@ export { Representation } interface Representation<D, P extends PD.Params = {}> { readonly label: string readonly updated: Subject<number> + /** Number of addressable groups in all visuals of the representation */ + readonly groupCount: number readonly renderObjects: ReadonlyArray<RenderObject> readonly props: Readonly<PD.Values<P>> readonly params: Readonly<P> @@ -94,7 +96,7 @@ interface Representation<D, P extends PD.Params = {}> { namespace Representation { export type Any = Representation<any> export const Empty: Any = { - label: '', renderObjects: [], props: {}, params: {}, updated: new Subject(), + label: '', groupCount: 0, renderObjects: [], props: {}, params: {}, updated: new Subject(), createOrUpdate: () => Task.constant('', undefined), getLoci: () => EmptyLoci, mark: () => false, @@ -122,6 +124,18 @@ namespace Representation { return { label, updated, + get groupCount() { + let groupCount = 0 + if (currentProps) { + const { visuals } = currentProps + for (let i = 0, il = reprList.length; i < il; ++i) { + if (!visuals || visuals.includes(reprMap[i])) { + groupCount += reprList[i].groupCount + } + } + } + return groupCount + }, get renderObjects() { const renderObjects: RenderObject[] = [] if (currentProps) { @@ -200,6 +214,8 @@ export interface VisualContext { } export interface Visual<D, P extends PD.Params> { + /** Number of addressable groups in all instances of the visual */ + readonly groupCount: number readonly renderObject: RenderObject | undefined createOrUpdate: (ctx: VisualContext, theme: Theme, props?: Partial<PD.Values<P>>, data?: D) => Promise<void> getLoci: (pickingId: PickingId) => Loci diff --git a/src/mol-repr/shape/representation.ts b/src/mol-repr/shape/representation.ts index c8e7ac8db60ea143a510f4358cf3b153cc233f6c..7908459ac25ddff00f3762d81ce8d7dfb3c43a53 100644 --- a/src/mol-repr/shape/representation.ts +++ b/src/mol-repr/shape/representation.ts @@ -38,6 +38,7 @@ export function ShapeRepresentation<P extends ShapeParams>(): ShapeRepresentatio let _shape: Shape let currentProps: PD.Values<P> = PD.getDefaultValues(ShapeParams) as PD.Values<P> let currentParams: P + let locationIt: LocationIterator function createOrUpdate(ctx: RepresentationContext, props: Partial<PD.Values<P>> = {}, shape?: Shape) { currentProps = Object.assign({}, currentProps, props) @@ -49,7 +50,7 @@ export function ShapeRepresentation<P extends ShapeParams>(): ShapeRepresentatio if (!_shape) return const mesh = _shape.mesh - const locationIt = ShapeGroupIterator.fromShape(_shape) + locationIt = ShapeGroupIterator.fromShape(_shape) const theme = createTheme(ctx, currentProps, {}) const transform = createIdentityTransform() @@ -65,6 +66,7 @@ export function ShapeRepresentation<P extends ShapeParams>(): ShapeRepresentatio return { label: 'Shape mesh', updated, + get groupCount () { return locationIt ? locationIt.count : 0 }, get renderObjects () { return renderObjects }, get params () { return currentParams }, get props () { return currentProps }, diff --git a/src/mol-repr/structure/complex-representation.ts b/src/mol-repr/structure/complex-representation.ts index 816f84d4ddb0d95897f6930695a1fb6d22a23b35..fc6253b81b6d069d089f6ad3981691ac9fea4440 100644 --- a/src/mol-repr/structure/complex-representation.ts +++ b/src/mol-repr/structure/complex-representation.ts @@ -65,6 +65,9 @@ export function ComplexRepresentation<P extends StructureParams>(label: string, return { label, + get groupCount() { + return visual ? visual.groupCount : 0 + }, get renderObjects() { return visual && visual.renderObject ? [ visual.renderObject ] : [] }, diff --git a/src/mol-repr/structure/complex-visual.ts b/src/mol-repr/structure/complex-visual.ts index ffccd126bec7138a427b8cdeb6c739f4ea7681c6..4e39ce449219d0c663d2c9f8cad3bb24fe9aa0fc 100644 --- a/src/mol-repr/structure/complex-visual.ts +++ b/src/mol-repr/structure/complex-visual.ts @@ -122,6 +122,7 @@ export function ComplexVisual<P extends ComplexParams>(builder: ComplexVisualGeo } return { + get groupCount() { return locationIt ? locationIt.count : 0 }, get renderObject () { return renderObject }, async createOrUpdate(ctx: VisualContext, theme: Theme, props: Partial<PD.Values<P>> = {}, structure?: Structure) { if (!structure && !currentStructure) { diff --git a/src/mol-repr/structure/units-representation.ts b/src/mol-repr/structure/units-representation.ts index 84aed6c3de81b45c5dd44ff2b813e0b01d2e17dc..abd56451a196e91b1ada57ad8a2319b1129224f5 100644 --- a/src/mol-repr/structure/units-representation.ts +++ b/src/mol-repr/structure/units-representation.ts @@ -161,6 +161,13 @@ export function UnitsRepresentation<P extends UnitsParams>(label: string, getPar return { label, + get groupCount() { + let groupCount = 0 + visuals.forEach(({ visual }) => { + if (visual.renderObject) groupCount += visual.groupCount + }) + return groupCount + }, get renderObjects() { const renderObjects: RenderObject[] = [] visuals.forEach(({ visual }) => { diff --git a/src/mol-repr/structure/units-visual.ts b/src/mol-repr/structure/units-visual.ts index abb5dccb56234f38b41d0e16ff71d2c48953787c..e0f4ba605d0ae2ef534336adb59ef618c43812e5 100644 --- a/src/mol-repr/structure/units-visual.ts +++ b/src/mol-repr/structure/units-visual.ts @@ -146,6 +146,7 @@ export function UnitsVisual<P extends UnitsParams>(builder: UnitsVisualGeometryB } return { + get groupCount() { return locationIt ? locationIt.count : 0 }, get renderObject () { return renderObject }, async createOrUpdate(ctx: VisualContext, theme: Theme, props: Partial<PD.Values<P>> = {}, structureGroup?: StructureGroup) { if (structureGroup) currentStructure = structureGroup.structure diff --git a/src/mol-repr/volume/representation.ts b/src/mol-repr/volume/representation.ts index 075c02c8a417f4671251242aeac212d5387d6132..85a467af2ec2a2aa4b63ad115cbf129d72f3d4f4 100644 --- a/src/mol-repr/volume/representation.ts +++ b/src/mol-repr/volume/representation.ts @@ -76,6 +76,7 @@ export function VolumeVisual<P extends VolumeParams>(builder: VolumeVisualGeomet } return { + get groupCount() { return locationIt ? locationIt.count : 0 }, get renderObject () { return renderObject }, async createOrUpdate(ctx: VisualContext, theme: Theme, props: Partial<PD.Values<P>> = {}, volume?: VolumeData) { if (!volume && !currentVolume) { @@ -204,6 +205,9 @@ export function VolumeRepresentation<P extends VolumeParams>(label: string, getP return { label, + get groupCount() { + return visual ? visual.groupCount : 0 + }, get renderObjects() { return visual && visual.renderObject ? [ visual.renderObject ] : [] },