From 5ceb7c1f515e6d3acb45713f9914784f5099a21b Mon Sep 17 00:00:00 2001 From: David Sehnal <david.sehnal@gmail.com> Date: Fri, 15 Jun 2018 14:23:01 +0200 Subject: [PATCH] Use OrderedSet for Element.Loci --- src/mol-data/int/ordered-set.ts | 4 +++- src/mol-geo/representation/structure/point.ts | 4 ++-- src/mol-geo/representation/structure/spacefill.ts | 4 ++-- src/mol-geo/representation/structure/utils.ts | 15 ++++++++++++--- src/mol-model/structure/query/selection.ts | 14 +++++++++++--- src/mol-model/structure/structure/element.ts | 11 +++++++---- src/mol-view/label.ts | 5 +++-- 7 files changed, 40 insertions(+), 17 deletions(-) diff --git a/src/mol-data/int/ordered-set.ts b/src/mol-data/int/ordered-set.ts index 54776e79d..8a11562f2 100644 --- a/src/mol-data/int/ordered-set.ts +++ b/src/mol-data/int/ordered-set.ts @@ -6,6 +6,7 @@ import * as Base from './impl/ordered-set' import Interval from './interval' +import SortedArray from './sorted-array'; namespace OrderedSet { export const Empty: OrderedSet = Base.Empty as any; @@ -41,6 +42,7 @@ namespace OrderedSet { } } -interface OrderedSet { '@type': 'int-interval' | 'int-sorted-array' } +type OrderedSet = Interval | SortedArray +//{ '@type': 'int-interval' | 'int-sorted-array' } export default OrderedSet \ No newline at end of file diff --git a/src/mol-geo/representation/structure/point.ts b/src/mol-geo/representation/structure/point.ts index 937797308..9e82a77a4 100644 --- a/src/mol-geo/representation/structure/point.ts +++ b/src/mol-geo/representation/structure/point.ts @@ -16,7 +16,7 @@ import VertexMap from '../../shape/vertex-map'; import { SizeTheme } from '../../theme'; import { createTransforms, createColors, createSizes, markElement } from './utils'; import { deepEqual, defaults } from 'mol-util'; -import { SortedArray } from 'mol-data/int'; +import { SortedArray, OrderedSet } from 'mol-data/int'; import { RenderableState, PointValues } from 'mol-gl/renderable'; import { PickingId } from '../../util/picking'; import { Loci, EmptyLoci } from 'mol-model/loci'; @@ -161,7 +161,7 @@ export default function PointUnitsRepresentation(): UnitsRepresentation<PointPro const { objectId, instanceId, elementId } = pickingId if (points.id === objectId) { const unit = currentGroup.units[instanceId] - const indices = SortedArray.ofSingleton(elementId) + const indices = OrderedSet.ofSingleton(elementId) return Element.Loci([{ unit, indices }]) } return EmptyLoci diff --git a/src/mol-geo/representation/structure/spacefill.ts b/src/mol-geo/representation/structure/spacefill.ts index a80d30964..fe18eb7a1 100644 --- a/src/mol-geo/representation/structure/spacefill.ts +++ b/src/mol-geo/representation/structure/spacefill.ts @@ -19,7 +19,7 @@ import { RenderableState, MeshValues } from 'mol-gl/renderable'; import { getMeshData } from '../../util/mesh-data'; import { Mesh } from '../../shape/mesh'; import { PickingId } from '../../util/picking'; -import { SortedArray } from 'mol-data/int'; +import { OrderedSet } from 'mol-data/int'; import { createMarkers, MarkerAction } from '../../util/marker-data'; import { Loci, EmptyLoci } from 'mol-model/loci'; @@ -149,7 +149,7 @@ export default function SpacefillUnitsRepresentation(): UnitsRepresentation<Spac const { objectId, instanceId, elementId } = pickingId if (spheres.id === objectId) { const unit = currentGroup.units[instanceId] - const indices = SortedArray.ofSingleton(elementId); + const indices = OrderedSet.ofSingleton(elementId); return Element.Loci([{ unit, indices }]) } return EmptyLoci diff --git a/src/mol-geo/representation/structure/utils.ts b/src/mol-geo/representation/structure/utils.ts index 8b876df1a..aee0ab240 100644 --- a/src/mol-geo/representation/structure/utils.ts +++ b/src/mol-geo/representation/structure/utils.ts @@ -22,6 +22,7 @@ import { MeshBuilder } from '../../shape/mesh-builder'; import { TextureImage } from 'mol-gl/renderable/util'; import { applyMarkerAction, MarkerAction } from '../../util/marker-data'; import { Loci, isEveryLoci } from 'mol-model/loci'; +import { Interval } from 'mol-data/int'; export function createTransforms({ units }: Unit.SymmetryGroup, transforms?: ValueCell<Float32Array>) { const unitCount = units.length @@ -101,11 +102,19 @@ export function markElement(tMarker: ValueCell<TextureImage>, group: Unit.Symmet for (const e of loci.elements) { const unitIdx = Unit.findUnitById(e.unit.id, group.units) if (unitIdx !== -1) { - for (let i = 0, il = e.indices.length; i < il; ++i) { - const idx = unitIdx * elementCount + e.indices[i] - if (applyMarkerAction(array, idx, idx + 1, action) && !changed) { + if (Interval.is(e.indices)) { + const idxStart = unitIdx * elementCount + Interval.start(e.indices); + const idxEnd = unitIdx * elementCount + Interval.end(e.indices); + if (applyMarkerAction(array, idxStart, idxEnd, action) && !changed) { changed = true } + } else { + for (let i = 0, _i = e.indices.length; i < _i; i++) { + const idx = unitIdx * elementCount + e.indices[i]; + if (applyMarkerAction(array, idx, idx + 1, action) && !changed) { + changed = true + } + } } } } diff --git a/src/mol-model/structure/query/selection.ts b/src/mol-model/structure/query/selection.ts index 0aaa01922..a68971d3c 100644 --- a/src/mol-model/structure/query/selection.ts +++ b/src/mol-model/structure/query/selection.ts @@ -7,7 +7,7 @@ import { HashSet } from 'mol-data/generic' import { Structure, Element, Unit } from '../structure' import { structureUnion } from './utils/structure'; -import { SortedArray } from 'mol-data/int'; +import { OrderedSet, SortedArray } from 'mol-data/int'; // A selection is a pair of a Structure and a sequence of unique AtomSets type Selection = Selection.Singletons | Selection.Sequence @@ -36,10 +36,18 @@ namespace Selection { } export function toLoci(sel: Selection): Element.Loci { - const loci: { unit: Unit, indices: SortedArray }[] = []; + const loci: { unit: Unit, indices: OrderedSet }[] = []; + const { unitMap } = sel.source; for (const unit of unionStructure(sel).units) { - loci[loci.length] = { unit, indices: SortedArray.indicesOf(sel.source.unitMap.get(unit.id).elements, unit.elements) } + if (unit === unitMap.get(unit.id)) { + loci[loci.length] = { unit, indices: OrderedSet.ofBounds(0, unit.elements.length) }; + } else { + loci[loci.length] = { + unit, + indices: OrderedSet.ofSortedArray(SortedArray.indicesOf(sel.source.unitMap.get(unit.id).elements, unit.elements)) + }; + } } return Element.Loci(loci); diff --git a/src/mol-model/structure/structure/element.ts b/src/mol-model/structure/structure/element.ts index bacc0c4cd..845dfe791 100644 --- a/src/mol-model/structure/structure/element.ts +++ b/src/mol-model/structure/structure/element.ts @@ -4,7 +4,7 @@ * @author David Sehnal <david.sehnal@gmail.com> */ -import { Tuple, SortedArray } from 'mol-data/int' +import { Tuple, OrderedSet } from 'mol-data/int' import Unit from './unit' import Structure from './structure' @@ -55,12 +55,15 @@ namespace Element { /** Access i-th element as unit.elements[indices[i]] */ readonly elements: ReadonlyArray<{ unit: Unit, - /** Indices into the unit.elements array */ - indices: SortedArray + /** + * Indices into the unit.elements array. + * Can use OrderedSet.forEach to iterate (or OrderedSet.size + OrderedSet.getAt) + */ + indices: OrderedSet }> } - export function Loci(elements: ArrayLike<{ unit: Unit, indices: SortedArray }>): Loci { + export function Loci(elements: ArrayLike<{ unit: Unit, indices: OrderedSet }>): Loci { return { kind: 'element-loci', elements: elements as Loci['elements'] }; } diff --git a/src/mol-view/label.ts b/src/mol-view/label.ts index da98fa3b7..aa6b01e71 100644 --- a/src/mol-view/label.ts +++ b/src/mol-view/label.ts @@ -7,6 +7,7 @@ import { Unit, Element, Queries } from 'mol-model/structure'; import { Loci } from 'mol-model/loci'; +import { OrderedSet } from 'mol-data/int'; const elementLocA = Element.Location() const elementLocB = Element.Location() @@ -20,8 +21,8 @@ export function labelFirst(loci: Loci): string { switch (loci.kind) { case 'element-loci': const e = loci.elements[0] - if (e && e.indices[0] !== undefined) { - return elementLabel(Element.Location(e.unit, e.indices[0])) + if (e) { + return elementLabel(Element.Location(e.unit, OrderedSet.getAt(e.indices, 0))) } else { return 'Unknown' } -- GitLab