From 1b79d349070c91a62867ce958742cbb13482c70d Mon Sep 17 00:00:00 2001 From: Alexander Rose <alexander.rose@weirdbyte.de> Date: Sat, 22 Jan 2022 08:53:47 -0800 Subject: [PATCH] fix marking of carbohydrate visuals --- CHANGELOG.md | 1 + .../visual/carbohydrate-link-cylinder.ts | 11 ++++++++--- .../structure/visual/carbohydrate-symbol-mesh.ts | 15 ++++++++++----- .../visual/carbohydrate-terminal-link-cylinder.ts | 11 ++++++++--- src/mol-repr/visual.ts | 3 ++- 5 files changed, 29 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f4a3a921e..7cdd7d49d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ Note that since we don't clearly distinguish between a public and private interf - Add Model Export extension - Bugfix: Automatically treat empty string as "non-present" value in BinaryCIF writer. - Fix coarse model support in entity-id color theme +- Fix marking of carbohydrate visuals (whole chain could get marked instead of single residue) ## [v3.0.0-dev.10] - 2022-01-17 diff --git a/src/mol-repr/structure/visual/carbohydrate-link-cylinder.ts b/src/mol-repr/structure/visual/carbohydrate-link-cylinder.ts index be0a198f9..b779f658d 100644 --- a/src/mol-repr/structure/visual/carbohydrate-link-cylinder.ts +++ b/src/mol-repr/structure/visual/carbohydrate-link-cylinder.ts @@ -1,5 +1,5 @@ /** - * Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info. + * Copyright (c) 2018-2022 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose <alexander.rose@weirdbyte.de> */ @@ -101,6 +101,8 @@ function getLinkLoci(pickingId: PickingId, structure: Structure, id: number) { return EmptyLoci; } +const __linkIndicesSet = new Set<number>(); + function eachCarbohydrateLink(loci: Loci, structure: Structure, apply: (interval: Interval) => boolean) { let changed = false; if (!StructureElement.Loci.is(loci)) return false; @@ -110,11 +112,14 @@ function eachCarbohydrateLink(loci: Loci, structure: Structure, apply: (interval for (const { unit, indices } of loci.elements) { if (!Unit.isAtomic(unit)) continue; + __linkIndicesSet.clear(); OrderedSet.forEach(indices, v => { - // TODO avoid duplicate calls to apply const linkIndices = getLinkIndices(unit, unit.elements[v]); for (let i = 0, il = linkIndices.length; i < il; ++i) { - if (apply(Interval.ofSingleton(linkIndices[i]))) changed = true; + if (!__linkIndicesSet.has(linkIndices[i])) { + __linkIndicesSet.add(linkIndices[i]); + if (apply(Interval.ofSingleton(linkIndices[i]))) changed = true; + } } }); } diff --git a/src/mol-repr/structure/visual/carbohydrate-symbol-mesh.ts b/src/mol-repr/structure/visual/carbohydrate-symbol-mesh.ts index 8c56b96b7..ab3cfd91a 100644 --- a/src/mol-repr/structure/visual/carbohydrate-symbol-mesh.ts +++ b/src/mol-repr/structure/visual/carbohydrate-symbol-mesh.ts @@ -1,5 +1,5 @@ /** - * Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info. + * Copyright (c) 2018-2022 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose <alexander.rose@weirdbyte.de> */ @@ -29,8 +29,8 @@ import { getAltResidueLociFromId } from './util/common'; import { BaseGeometry } from '../../../mol-geo/geometry/base'; const t = Mat4.identity(); -const sVec = Vec3.zero(); -const pd = Vec3.zero(); +const sVec = Vec3(); +const pd = Vec3(); const SideFactor = 2 * 0.806; // 0.806 == Math.cos(Math.PI / 4) @@ -212,6 +212,8 @@ function getCarbohydrateLoci(pickingId: PickingId, structure: Structure, id: num return EmptyLoci; } +const __elementIndicesSet = new Set<number>(); + /** For each carbohydrate (usually a monosaccharide) when all its residue's elements are in a loci. */ function eachCarbohydrate(loci: Loci, structure: Structure, apply: (interval: Interval) => boolean) { const { getElementIndices } = structure.carbohydrates; @@ -222,11 +224,14 @@ function eachCarbohydrate(loci: Loci, structure: Structure, apply: (interval: In for (const { unit, indices } of loci.elements) { if (!Unit.isAtomic(unit)) continue; + __elementIndicesSet.clear(); OrderedSet.forEach(indices, v => { - // TODO avoid duplicate calls to apply const elementIndices = getElementIndices(unit, unit.elements[v]); for (let i = 0, il = elementIndices.length; i < il; ++i) { - if (apply(Interval.ofSingleton(elementIndices[i] * 2))) changed = true; + if (!__elementIndicesSet.has(elementIndices[i])) { + __elementIndicesSet.add(elementIndices[i]); + if (apply(Interval.ofSingleton(elementIndices[i] * 2))) changed = true; + } } }); } diff --git a/src/mol-repr/structure/visual/carbohydrate-terminal-link-cylinder.ts b/src/mol-repr/structure/visual/carbohydrate-terminal-link-cylinder.ts index a95088d74..4620b0316 100644 --- a/src/mol-repr/structure/visual/carbohydrate-terminal-link-cylinder.ts +++ b/src/mol-repr/structure/visual/carbohydrate-terminal-link-cylinder.ts @@ -1,5 +1,5 @@ /** - * Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info. + * Copyright (c) 2018-2022 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose <alexander.rose@weirdbyte.de> */ @@ -123,6 +123,8 @@ function getTerminalLinkLoci(pickingId: PickingId, structure: Structure, id: num return EmptyLoci; } +const __linkIndicesSet = new Set<number>(); + function eachTerminalLink(loci: Loci, structure: Structure, apply: (interval: Interval) => boolean) { let changed = false; if (!StructureElement.Loci.is(loci)) return false; @@ -132,11 +134,14 @@ function eachTerminalLink(loci: Loci, structure: Structure, apply: (interval: In for (const { unit, indices } of loci.elements) { if (!Unit.isAtomic(unit)) continue; + __linkIndicesSet.clear(); OrderedSet.forEach(indices, v => { - // TODO avoid duplicate calls to apply const linkIndices = getTerminalLinkIndices(unit, unit.elements[v]); for (let i = 0, il = linkIndices.length; i < il; ++i) { - if (apply(Interval.ofSingleton(linkIndices[i]))) changed = true; + if (!__linkIndicesSet.has(linkIndices[i])) { + __linkIndicesSet.add(linkIndices[i]); + if (apply(Interval.ofSingleton(linkIndices[i]))) changed = true; + } } }); } diff --git a/src/mol-repr/visual.ts b/src/mol-repr/visual.ts index 223b4bfcd..90e272b4c 100644 --- a/src/mol-repr/visual.ts +++ b/src/mol-repr/visual.ts @@ -1,5 +1,5 @@ /** - * Copyright (c) 2018-2021 mol* contributors, licensed under MIT, See LICENSE file for more info. + * Copyright (c) 2018-2022 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose <alexander.rose@weirdbyte.de> */ @@ -88,6 +88,7 @@ namespace Visual { const currentStatus = markerStatus.ref.value as MarkerInfo['status']; if (!isEveryLoci(loci)) { + // assume that all interval are non-overlapping let intervalSize = 0; lociApply(loci, interval => { intervalSize += Interval.size(interval); -- GitLab