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

fix marking of carbohydrate visuals

parent fc52e29c
Branches
Tags
No related merge requests found
...@@ -14,6 +14,7 @@ Note that since we don't clearly distinguish between a public and private interf ...@@ -14,6 +14,7 @@ Note that since we don't clearly distinguish between a public and private interf
- Add Model Export extension - Add Model Export extension
- Bugfix: Automatically treat empty string as "non-present" value in BinaryCIF writer. - Bugfix: Automatically treat empty string as "non-present" value in BinaryCIF writer.
- Fix coarse model support in entity-id color theme - 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 ## [v3.0.0-dev.10] - 2022-01-17
......
/** /**
* 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> * @author Alexander Rose <alexander.rose@weirdbyte.de>
*/ */
...@@ -101,6 +101,8 @@ function getLinkLoci(pickingId: PickingId, structure: Structure, id: number) { ...@@ -101,6 +101,8 @@ function getLinkLoci(pickingId: PickingId, structure: Structure, id: number) {
return EmptyLoci; return EmptyLoci;
} }
const __linkIndicesSet = new Set<number>();
function eachCarbohydrateLink(loci: Loci, structure: Structure, apply: (interval: Interval) => boolean) { function eachCarbohydrateLink(loci: Loci, structure: Structure, apply: (interval: Interval) => boolean) {
let changed = false; let changed = false;
if (!StructureElement.Loci.is(loci)) return false; if (!StructureElement.Loci.is(loci)) return false;
...@@ -110,12 +112,15 @@ function eachCarbohydrateLink(loci: Loci, structure: Structure, apply: (interval ...@@ -110,12 +112,15 @@ function eachCarbohydrateLink(loci: Loci, structure: Structure, apply: (interval
for (const { unit, indices } of loci.elements) { for (const { unit, indices } of loci.elements) {
if (!Unit.isAtomic(unit)) continue; if (!Unit.isAtomic(unit)) continue;
__linkIndicesSet.clear();
OrderedSet.forEach(indices, v => { OrderedSet.forEach(indices, v => {
// TODO avoid duplicate calls to apply
const linkIndices = getLinkIndices(unit, unit.elements[v]); const linkIndices = getLinkIndices(unit, unit.elements[v]);
for (let i = 0, il = linkIndices.length; i < il; ++i) { for (let i = 0, il = linkIndices.length; i < il; ++i) {
if (!__linkIndicesSet.has(linkIndices[i])) {
__linkIndicesSet.add(linkIndices[i]);
if (apply(Interval.ofSingleton(linkIndices[i]))) changed = true; if (apply(Interval.ofSingleton(linkIndices[i]))) changed = true;
} }
}
}); });
} }
return changed; return changed;
......
/** /**
* 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> * @author Alexander Rose <alexander.rose@weirdbyte.de>
*/ */
...@@ -29,8 +29,8 @@ import { getAltResidueLociFromId } from './util/common'; ...@@ -29,8 +29,8 @@ import { getAltResidueLociFromId } from './util/common';
import { BaseGeometry } from '../../../mol-geo/geometry/base'; import { BaseGeometry } from '../../../mol-geo/geometry/base';
const t = Mat4.identity(); const t = Mat4.identity();
const sVec = Vec3.zero(); const sVec = Vec3();
const pd = Vec3.zero(); const pd = Vec3();
const SideFactor = 2 * 0.806; // 0.806 == Math.cos(Math.PI / 4) const SideFactor = 2 * 0.806; // 0.806 == Math.cos(Math.PI / 4)
...@@ -212,6 +212,8 @@ function getCarbohydrateLoci(pickingId: PickingId, structure: Structure, id: num ...@@ -212,6 +212,8 @@ function getCarbohydrateLoci(pickingId: PickingId, structure: Structure, id: num
return EmptyLoci; return EmptyLoci;
} }
const __elementIndicesSet = new Set<number>();
/** For each carbohydrate (usually a monosaccharide) when all its residue's elements are in a loci. */ /** 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) { function eachCarbohydrate(loci: Loci, structure: Structure, apply: (interval: Interval) => boolean) {
const { getElementIndices } = structure.carbohydrates; const { getElementIndices } = structure.carbohydrates;
...@@ -222,12 +224,15 @@ function eachCarbohydrate(loci: Loci, structure: Structure, apply: (interval: In ...@@ -222,12 +224,15 @@ function eachCarbohydrate(loci: Loci, structure: Structure, apply: (interval: In
for (const { unit, indices } of loci.elements) { for (const { unit, indices } of loci.elements) {
if (!Unit.isAtomic(unit)) continue; if (!Unit.isAtomic(unit)) continue;
__elementIndicesSet.clear();
OrderedSet.forEach(indices, v => { OrderedSet.forEach(indices, v => {
// TODO avoid duplicate calls to apply
const elementIndices = getElementIndices(unit, unit.elements[v]); const elementIndices = getElementIndices(unit, unit.elements[v]);
for (let i = 0, il = elementIndices.length; i < il; ++i) { for (let i = 0, il = elementIndices.length; i < il; ++i) {
if (!__elementIndicesSet.has(elementIndices[i])) {
__elementIndicesSet.add(elementIndices[i]);
if (apply(Interval.ofSingleton(elementIndices[i] * 2))) changed = true; if (apply(Interval.ofSingleton(elementIndices[i] * 2))) changed = true;
} }
}
}); });
} }
return changed; return changed;
......
/** /**
* 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> * @author Alexander Rose <alexander.rose@weirdbyte.de>
*/ */
...@@ -123,6 +123,8 @@ function getTerminalLinkLoci(pickingId: PickingId, structure: Structure, id: num ...@@ -123,6 +123,8 @@ function getTerminalLinkLoci(pickingId: PickingId, structure: Structure, id: num
return EmptyLoci; return EmptyLoci;
} }
const __linkIndicesSet = new Set<number>();
function eachTerminalLink(loci: Loci, structure: Structure, apply: (interval: Interval) => boolean) { function eachTerminalLink(loci: Loci, structure: Structure, apply: (interval: Interval) => boolean) {
let changed = false; let changed = false;
if (!StructureElement.Loci.is(loci)) return false; if (!StructureElement.Loci.is(loci)) return false;
...@@ -132,12 +134,15 @@ function eachTerminalLink(loci: Loci, structure: Structure, apply: (interval: In ...@@ -132,12 +134,15 @@ function eachTerminalLink(loci: Loci, structure: Structure, apply: (interval: In
for (const { unit, indices } of loci.elements) { for (const { unit, indices } of loci.elements) {
if (!Unit.isAtomic(unit)) continue; if (!Unit.isAtomic(unit)) continue;
__linkIndicesSet.clear();
OrderedSet.forEach(indices, v => { OrderedSet.forEach(indices, v => {
// TODO avoid duplicate calls to apply
const linkIndices = getTerminalLinkIndices(unit, unit.elements[v]); const linkIndices = getTerminalLinkIndices(unit, unit.elements[v]);
for (let i = 0, il = linkIndices.length; i < il; ++i) { for (let i = 0, il = linkIndices.length; i < il; ++i) {
if (!__linkIndicesSet.has(linkIndices[i])) {
__linkIndicesSet.add(linkIndices[i]);
if (apply(Interval.ofSingleton(linkIndices[i]))) changed = true; if (apply(Interval.ofSingleton(linkIndices[i]))) changed = true;
} }
}
}); });
} }
return changed; return changed;
......
/** /**
* 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> * @author Alexander Rose <alexander.rose@weirdbyte.de>
*/ */
...@@ -88,6 +88,7 @@ namespace Visual { ...@@ -88,6 +88,7 @@ namespace Visual {
const currentStatus = markerStatus.ref.value as MarkerInfo['status']; const currentStatus = markerStatus.ref.value as MarkerInfo['status'];
if (!isEveryLoci(loci)) { if (!isEveryLoci(loci)) {
// assume that all interval are non-overlapping
let intervalSize = 0; let intervalSize = 0;
lociApply(loci, interval => { lociApply(loci, interval => {
intervalSize += Interval.size(interval); intervalSize += Interval.size(interval);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment