diff --git a/src/mol-repr/structure/visual/polymer-trace-mesh.ts b/src/mol-repr/structure/visual/polymer-trace-mesh.ts index 65d6b070eacfdc1d0b933048b3da26af57fee671..65a2a3f9a2e38a31bb5cc31168140e8cb48e131d 100644 --- a/src/mol-repr/structure/visual/polymer-trace-mesh.ts +++ b/src/mol-repr/structure/visual/polymer-trace-mesh.ts @@ -62,8 +62,8 @@ async function createPolymerTraceMesh(ctx: VisualContext, unit: Unit, structure: if (isSheet) { const height = width * aspectRatio - const arrowHeight = v.secStrucChange ? height * arrowFactor : 0 - addSheet(builder, curvePoints, normalVectors, binormalVectors, linearSegments, width, height, arrowHeight, true, true) + const arrowHeight = v.secStrucLast ? height * arrowFactor : 0 + addSheet(builder, curvePoints, normalVectors, binormalVectors, linearSegments, width, height, arrowHeight, v.secStrucFirst, v.secStrucLast) } else { let height: number if (isHelix) { @@ -74,7 +74,7 @@ async function createPolymerTraceMesh(ctx: VisualContext, unit: Unit, structure: } else { height = width } - addTube(builder, curvePoints, normalVectors, binormalVectors, linearSegments, radialSegments, width, height, 1, true, true) + addTube(builder, curvePoints, normalVectors, binormalVectors, linearSegments, radialSegments, width, height, 1, v.secStrucFirst, v.secStrucLast) } if (i % 10000 === 0 && ctx.runtime.shouldUpdate) { diff --git a/src/mol-repr/structure/visual/util/polymer/trace-iterator.ts b/src/mol-repr/structure/visual/util/polymer/trace-iterator.ts index 37bfc18d317b5c96c015f13bda2c9c15bafbb37b..22438a0b1d2fec459a695d46d3ccf35303e75cd5 100644 --- a/src/mol-repr/structure/visual/util/polymer/trace-iterator.ts +++ b/src/mol-repr/structure/visual/util/polymer/trace-iterator.ts @@ -13,6 +13,7 @@ import SortedRanges from 'mol-data/int/sorted-ranges'; import { CoarseSphereConformation, CoarseGaussianConformation } from 'mol-model/structure/model/properties/coarse'; import { getAtomicMoleculeType, getElementIndexForAtomRole } from 'mol-model/structure/util'; import { getPolymerRanges } from '../polymer'; +import { AtomicConformation } from 'mol-model/structure/model/properties/atomic'; /** * Iterates over individual residues/coarse elements in polymers of a unit while @@ -30,20 +31,22 @@ export function PolymerTraceIterator(unit: Unit): Iterator<PolymerTraceElement> interface PolymerTraceElement { center: StructureElement first: boolean, last: boolean + secStrucFirst: boolean, secStrucLast: boolean secStrucType: SecondaryStructureType - secStrucChange: boolean moleculeType: MoleculeType p0: Vec3, p1: Vec3, p2: Vec3, p3: Vec3, p4: Vec3 d12: Vec3, d23: Vec3 } +const SecStrucTypeNA = SecondaryStructureType.create(SecondaryStructureType.Flag.NA) + function createPolymerTraceElement (unit: Unit): PolymerTraceElement { return { center: StructureElement.create(unit), first: false, last: false, - secStrucType: SecondaryStructureType.create(SecondaryStructureType.Flag.NA), - secStrucChange: false, + secStrucFirst: false, secStrucLast: false, + secStrucType: SecStrucTypeNA, moleculeType: MoleculeType.unknown, p0: Vec3.zero(), p1: Vec3.zero(), p2: Vec3.zero(), p3: Vec3.zero(), p4: Vec3.zero(), d12: Vec3.create(1, 0, 0), d23: Vec3.create(1, 0, 0), @@ -57,10 +60,15 @@ export class AtomicPolymerTraceIterator implements Iterator<PolymerTraceElement> private polymerIt: SortedRanges.Iterator<ElementIndex, ResidueIndex> private residueIt: Segmentation.SegmentIterator<ResidueIndex> private polymerSegment: Segmentation.Segment<ResidueIndex> + private secondaryStructureType: ArrayLike<SecondaryStructureType> private residueSegmentMin: ResidueIndex private residueSegmentMax: ResidueIndex + private prevSecStrucType: SecondaryStructureType + private currSecStrucType: SecondaryStructureType + private nextSecStrucType: SecondaryStructureType private state: AtomicPolymerTraceIteratorState = AtomicPolymerTraceIteratorState.nextPolymer private residueAtomSegments: Segmentation<ElementIndex, ResidueIndex> + private atomicConformation: AtomicConformation private p0 = Vec3.zero(); private p1 = Vec3.zero(); @@ -78,13 +86,13 @@ export class AtomicPolymerTraceIterator implements Iterator<PolymerTraceElement> hasNext: boolean = false; private pos(target: Vec3, index: number) { - target[0] = this.unit.model.atomicConformation.x[index] - target[1] = this.unit.model.atomicConformation.y[index] - target[2] = this.unit.model.atomicConformation.z[index] + target[0] = this.atomicConformation.x[index] + target[1] = this.atomicConformation.y[index] + target[2] = this.atomicConformation.z[index] } private updateResidueSegmentRange(polymerSegment: Segmentation.Segment<ResidueIndex>) { - const { index } = this.unit.model.atomicHierarchy.residueAtomSegments + const { index } = this.residueAtomSegments this.residueSegmentMin = index[this.unit.elements[polymerSegment.start]] this.residueSegmentMax = index[this.unit.elements[polymerSegment.end - 1]] } @@ -151,7 +159,11 @@ export class AtomicPolymerTraceIterator implements Iterator<PolymerTraceElement> this.pos(this.v23, this.getElementIndex(residueIndex, 'direction')) // this.pos(this.v34, this.getAtomIndex(residueIndex + 1 as ResidueIndex, 'direction')) - this.value.secStrucType = this.unit.model.properties.secondaryStructure.type[residueIndex] + this.prevSecStrucType = this.currSecStrucType + this.currSecStrucType = this.nextSecStrucType + this.nextSecStrucType = residueIt.hasNext ? this.secondaryStructureType[residueIndex + 1] : SecStrucTypeNA + + this.value.secStrucType = this.currSecStrucType this.setControlPoint(value.p0, this.p0, this.p1, this.p2, residueIndex - 2 as ResidueIndex) this.setControlPoint(value.p1, this.p1, this.p2, this.p3, residueIndex - 1 as ResidueIndex) @@ -164,7 +176,8 @@ export class AtomicPolymerTraceIterator implements Iterator<PolymerTraceElement> value.first = residueIndex === this.residueSegmentMin value.last = residueIndex === this.residueSegmentMax - value.secStrucChange = this.unit.model.properties.secondaryStructure.key[residueIndex] !== this.unit.model.properties.secondaryStructure.key[residueIndex + 1] + value.secStrucFirst = this.prevSecStrucType !== this.currSecStrucType + value.secStrucLast = this.currSecStrucType !== this.nextSecStrucType value.moleculeType = getAtomicMoleculeType(this.unit.model, residueIndex) if (!residueIt.hasNext) { @@ -178,7 +191,9 @@ export class AtomicPolymerTraceIterator implements Iterator<PolymerTraceElement> } constructor(private unit: Unit.Atomic) { + this.atomicConformation = unit.model.atomicConformation this.residueAtomSegments = unit.model.atomicHierarchy.residueAtomSegments + this.secondaryStructureType = unit.model.properties.secondaryStructure.type this.polymerIt = SortedRanges.transientSegments(getPolymerRanges(unit), unit.elements) this.residueIt = Segmentation.transientSegments(this.residueAtomSegments, unit.elements); this.value = createPolymerTraceElement(unit)