Skip to content
Snippets Groups Projects
Commit db350ddf authored by Alexander Rose's avatar Alexander Rose
Browse files

loci/marking performance improvements

- use Interval for ranges instead of SortedArray
- pre-check if loci overlaps with unit visual
parent c0144d82
No related branches found
No related tags found
No related merge requests found
...@@ -10,9 +10,15 @@ Note that since we don't clearly distinguish between a public and private interf ...@@ -10,9 +10,15 @@ Note that since we don't clearly distinguish between a public and private interf
- Add ``Mesh`` processing helper ``.smoothEdges`` - Add ``Mesh`` processing helper ``.smoothEdges``
- Smooth border of molecular-surface with ``includeParent`` enabled - Smooth border of molecular-surface with ``includeParent`` enabled
- Hide ``includeParent`` option from gaussian-surface visuals (not particularly useful) - Hide ``includeParent`` option from gaussian-surface visuals (not particularly useful)
- Improved ``StructureElement.Loci.size`` performance (for marking large cellpack models)
- Fix new ``TransformData`` issues (camera/bounding helper not showing up) - Fix new ``TransformData`` issues (camera/bounding helper not showing up)
- Improve marking performance (avoid superfluous calls to ``StructureElement.Loci.isWholeStructure``) - Improve marking performance
- Avoid superfluous calls to ``StructureElement.Loci.isWholeStructure``
- Check if loci is superset of visual
- Check if loci overlaps with unit visual
- Ensure ``Interval`` is used for ranges instead of ``SortedArray``
- Inline ``StructureElement.Loci.size`` code
- Add uniform marker type
- Special case for reversing previous mark
- Add optional marking pass - Add optional marking pass
- Outlines visible and hidden parts of highlighted/selected groups - Outlines visible and hidden parts of highlighted/selected groups
- Add highlightStrength/selectStrength renderer params - Add highlightStrength/selectStrength renderer params
......
...@@ -253,6 +253,14 @@ export namespace Loci { ...@@ -253,6 +253,14 @@ export namespace Loci {
return isSubset; return isSubset;
} }
function makeIndexSet(newIndices: ArrayLike<UnitIndex>): OrderedSet<UnitIndex> {
if (newIndices.length > 3 && SortedArray.isRange(newIndices)) {
return Interval.ofRange(newIndices[0], newIndices[newIndices.length - 1]);
} else {
return SortedArray.ofSortedArray(newIndices);
}
}
export function extendToWholeResidues(loci: Loci, restrictToConformation?: boolean): Loci { export function extendToWholeResidues(loci: Loci, restrictToConformation?: boolean): Loci {
const elements: Loci['elements'][0][] = []; const elements: Loci['elements'][0][] = [];
const residueAltIds = new Set<string>(); const residueAltIds = new Set<string>();
...@@ -297,7 +305,7 @@ export namespace Loci { ...@@ -297,7 +305,7 @@ export namespace Loci {
} }
} }
elements[elements.length] = { unit: lociElement.unit, indices: SortedArray.ofSortedArray(newIndices) }; elements[elements.length] = { unit: lociElement.unit, indices: makeIndexSet(newIndices) };
} else { } else {
// coarse elements are already by-residue // coarse elements are already by-residue
elements[elements.length] = lociElement; elements[elements.length] = lociElement;
...@@ -319,14 +327,6 @@ export namespace Loci { ...@@ -319,14 +327,6 @@ export namespace Loci {
return element.unit.elements.length === OrderedSet.size(element.indices); return element.unit.elements.length === OrderedSet.size(element.indices);
} }
function makeIndexSet(newIndices: number[]): OrderedSet<UnitIndex> {
if (newIndices.length > 12 && newIndices[newIndices.length - 1] - newIndices[0] === newIndices.length - 1) {
return Interval.ofRange(newIndices[0], newIndices[newIndices.length - 1]);
} else {
return SortedArray.ofSortedArray(newIndices);
}
}
function collectChains(unit: Unit, chainIndices: Set<ChainIndex>, elements: Loci['elements'][0][]) { function collectChains(unit: Unit, chainIndices: Set<ChainIndex>, elements: Loci['elements'][0][]) {
const { index } = getChainSegments(unit); const { index } = getChainSegments(unit);
const xs = unit.elements; const xs = unit.elements;
...@@ -470,7 +470,10 @@ export namespace Loci { ...@@ -470,7 +470,10 @@ export namespace Loci {
} }
function getUnitIndices(elements: SortedArray<ElementIndex>, indices: SortedArray<ElementIndex>) { function getUnitIndices(elements: SortedArray<ElementIndex>, indices: SortedArray<ElementIndex>) {
return OrderedSet.ofSortedArray(SortedArray.indicesOf<ElementIndex, UnitIndex>(elements, indices)); if (SortedArray.areEqual(elements, indices) && SortedArray.isRange(elements)) {
return Interval.ofLength(elements.length);
}
return makeIndexSet(SortedArray.indicesOf<ElementIndex, UnitIndex>(elements, indices));
} }
export function extendToAllInstances(loci: Loci): Loci { export function extendToAllInstances(loci: Loci): Loci {
......
...@@ -290,7 +290,18 @@ export function UnitsVisual<G extends Geometry, P extends StructureParams & Geom ...@@ -290,7 +290,18 @@ export function UnitsVisual<G extends Geometry, P extends StructureParams & Geom
return renderObject ? getLoci(pickingId, currentStructureGroup, renderObject.id) : EmptyLoci; return renderObject ? getLoci(pickingId, currentStructureGroup, renderObject.id) : EmptyLoci;
}, },
mark(loci: Loci, action: MarkerAction) { mark(loci: Loci, action: MarkerAction) {
return Visual.mark(renderObject, loci, action, lociApply, previousMark); let hasInvariantId = true;
if (StructureElement.Loci.is(loci)) {
hasInvariantId = false;
const { invariantId } = currentStructureGroup.group.units[0];
for (const e of loci.elements) {
if (e.unit.invariantId === invariantId) {
hasInvariantId = true;
break;
}
}
}
return hasInvariantId ? Visual.mark(renderObject, loci, action, lociApply, previousMark) : false;
}, },
setVisibility(visible: boolean) { setVisibility(visible: boolean) {
Visual.setVisibility(renderObject, visible); Visual.setVisibility(renderObject, visible);
......
...@@ -164,8 +164,9 @@ export function eachElement(loci: Loci, structureGroup: StructureGroup, apply: ( ...@@ -164,8 +164,9 @@ export function eachElement(loci: Loci, structureGroup: StructureGroup, apply: (
const { structure, group } = structureGroup; const { structure, group } = structureGroup;
if (!Structure.areEquivalent(loci.structure, structure)) return false; if (!Structure.areEquivalent(loci.structure, structure)) return false;
const elementCount = group.elements.length; const elementCount = group.elements.length;
const { unitIndexMap } = group;
for (const e of loci.elements) { for (const e of loci.elements) {
const unitIdx = group.unitIndexMap.get(e.unit.id); const unitIdx = unitIndexMap.get(e.unit.id);
if (unitIdx !== undefined) { if (unitIdx !== undefined) {
const offset = unitIdx * elementCount; // to target unit instance const offset = unitIdx * elementCount; // to target unit instance
if (Interval.is(e.indices)) { if (Interval.is(e.indices)) {
......
...@@ -84,6 +84,7 @@ namespace Visual { ...@@ -84,6 +84,7 @@ namespace Visual {
intervalSize += Interval.size(interval); intervalSize += Interval.size(interval);
return true; return true;
}, true); }, true);
if (intervalSize === 0) return false;
if (intervalSize === count) loci = EveryLoci; if (intervalSize === count) loci = EveryLoci;
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment