diff --git a/src/mol-geo/representation/structure/visual/nucleotide-block-mesh.ts b/src/mol-geo/representation/structure/visual/nucleotide-block-mesh.ts index 25578ea9b311aed23be07b72bdd3204abb628ffa..eb4ffed1f450e0c598a74142f4fe8a5168c3f07b 100644 --- a/src/mol-geo/representation/structure/visual/nucleotide-block-mesh.ts +++ b/src/mol-geo/representation/structure/visual/nucleotide-block-mesh.ts @@ -33,6 +33,7 @@ const sVec = Vec3.zero() async function createNucleotideBlockMesh(ctx: RuntimeContext, unit: Unit, props: {}, mesh?: Mesh) { if (!Unit.isAtomic(unit)) return Mesh.createEmpty(mesh) + // TODO better vertex count estimate const builder = MeshBuilder.create(256, 128, mesh) const { elements, model } = unit diff --git a/src/mol-geo/representation/structure/visual/polymer-backbone-cylinder.ts b/src/mol-geo/representation/structure/visual/polymer-backbone-cylinder.ts index bf30fc790faeb7d84be074fdd6fba1956c54ed0f..a80dae5b8a1882a6e93e797c749797873a1f8367 100644 --- a/src/mol-geo/representation/structure/visual/polymer-backbone-cylinder.ts +++ b/src/mol-geo/representation/structure/visual/polymer-backbone-cylinder.ts @@ -4,7 +4,7 @@ * @author Alexander Rose <alexander.rose@weirdbyte.de> */ -import { Unit, StructureElement } from 'mol-model/structure'; +import { Unit } from 'mol-model/structure'; import { UnitsVisual } from '..'; import { RuntimeContext } from 'mol-task' import { Mesh } from '../../../shape/mesh'; @@ -16,6 +16,7 @@ import { StructureElementIterator } from './util/location-iterator'; import { DefaultUnitsMeshProps, UnitsMeshVisual } from '../units-visual'; import { SizeThemeProps, SizeTheme } from 'mol-view/theme/size'; import { CylinderProps } from '../../../primitive/cylinder'; +import { OrderedSet } from 'mol-data/int'; export interface PolymerBackboneCylinderProps { sizeTheme: SizeThemeProps @@ -36,26 +37,21 @@ async function createPolymerBackboneCylinderMesh(ctx: RuntimeContext, unit: Unit const pos = unit.conformation.invariantPosition const pA = Vec3.zero() const pB = Vec3.zero() - const l = StructureElement.create(unit) const cylinderProps: CylinderProps = { radiusTop: 1, radiusBottom: 1, radialSegments } let i = 0 const polymerBackboneIt = PolymerBackboneIterator(unit) while (polymerBackboneIt.hasNext) { const { centerA, centerB } = polymerBackboneIt.move() - const elmA = elements[centerA.element] - const elmB = elements[centerB.element] - pos(elmA, pA) - pos(elmB, pB) + pos(centerA.element, pA) + pos(centerB.element, pB) - l.element = elmA - cylinderProps.radiusTop = cylinderProps.radiusBottom = sizeTheme.size(l) - builder.setId(centerA.element) + cylinderProps.radiusTop = cylinderProps.radiusBottom = sizeTheme.size(centerA) + builder.setId(OrderedSet.findPredecessorIndex(elements, centerA.element)) builder.addCylinder(pA, pB, 0.5, cylinderProps) - l.element = elmB - cylinderProps.radiusTop = cylinderProps.radiusBottom = sizeTheme.size(l) - builder.setId(centerB.element) + cylinderProps.radiusTop = cylinderProps.radiusBottom = sizeTheme.size(centerB) + builder.setId(OrderedSet.findPredecessorIndex(elements, centerB.element)) builder.addCylinder(pB, pA, 0.5, cylinderProps) if (i % 10000 === 0 && ctx.shouldUpdate) { diff --git a/src/mol-geo/representation/structure/visual/util/polymer/backbone-iterator.ts b/src/mol-geo/representation/structure/visual/util/polymer/backbone-iterator.ts index eb5dd18cd1ed4d8b4fa7bff7b1717b1e61101269..eaa3c029c7ab1455a093701b7b7b3bc3fb582da1 100644 --- a/src/mol-geo/representation/structure/visual/util/polymer/backbone-iterator.ts +++ b/src/mol-geo/representation/structure/visual/util/polymer/backbone-iterator.ts @@ -5,11 +5,10 @@ */ import { Unit, StructureElement, ElementIndex, ResidueIndex } from 'mol-model/structure'; -import { Segmentation, SortedArray } from 'mol-data/int'; +import { Segmentation } from 'mol-data/int'; import Iterator from 'mol-data/iterator'; import SortedRanges from 'mol-data/int/sorted-ranges'; import { getElementIndexForAtomRole } from 'mol-model/structure/util'; -import { AtomRole } from 'mol-model/structure/model/types'; import { getPolymerRanges } from '../polymer'; /** Iterates over consecutive pairs of residues/coarse elements in polymers */ @@ -44,23 +43,13 @@ export class AtomicPolymerBackboneIterator implements Iterator<PolymerBackbonePa private residueSegment: Segmentation.Segment<ResidueIndex> hasNext: boolean = false; - private getElementIndex(residueIndex: ResidueIndex, atomRole: AtomRole) { - const index = getElementIndexForAtomRole(this.unit.model, residueIndex, atomRole) - // TODO handle case when it returns -1 - const elementIndex = SortedArray.indexOf(this.unit.elements, index) as ElementIndex - if (elementIndex === -1) { - console.log('-1', residueIndex, atomRole, index) - } - return elementIndex === -1 ? 0 as ElementIndex : elementIndex - } - move() { if (this.state === AtomicPolymerBackboneIteratorState.nextPolymer) { while (this.polymerIt.hasNext) { this.residueIt.setSegment(this.polymerIt.move()); if (this.residueIt.hasNext) { this.residueSegment = this.residueIt.move() - this.value.centerB.element = this.getElementIndex(this.residueSegment.index, 'trace') + this.value.centerB.element = getElementIndexForAtomRole(this.unit.model, this.residueSegment.index, 'trace') this.state = AtomicPolymerBackboneIteratorState.nextResidue break } @@ -70,7 +59,7 @@ export class AtomicPolymerBackboneIterator implements Iterator<PolymerBackbonePa if (this.state === AtomicPolymerBackboneIteratorState.nextResidue) { this.residueSegment = this.residueIt.move() this.value.centerA.element = this.value.centerB.element - this.value.centerB.element = this.getElementIndex(this.residueSegment.index, 'trace') + this.value.centerB.element = getElementIndexForAtomRole(this.unit.model, this.residueSegment.index, 'trace') if (!this.residueIt.hasNext) { if (this.unit.model.atomicHierarchy.cyclicPolymerMap.has(this.residueSegment.index)) { this.state = AtomicPolymerBackboneIteratorState.cycle @@ -82,7 +71,7 @@ export class AtomicPolymerBackboneIterator implements Iterator<PolymerBackbonePa } else if (this.state === AtomicPolymerBackboneIteratorState.cycle) { const { cyclicPolymerMap } = this.unit.model.atomicHierarchy this.value.centerA.element = this.value.centerB.element - this.value.centerB.element = this.getElementIndex(cyclicPolymerMap.get(this.residueSegment.index)!, 'trace') + this.value.centerB.element = getElementIndexForAtomRole(this.unit.model, cyclicPolymerMap.get(this.residueSegment.index)!, 'trace') // TODO need to advance to a polymer that has two or more residues (can't assume it has) this.state = AtomicPolymerBackboneIteratorState.nextPolymer } diff --git a/src/mol-view/stage.ts b/src/mol-view/stage.ts index 81eff8fd786debfa5592a46ed8e77b5c43ba808c..3c21cce9fc41f1f8e750ef17b3ddd154372720a5 100644 --- a/src/mol-view/stage.ts +++ b/src/mol-view/stage.ts @@ -21,6 +21,7 @@ import { CarbohydrateProps } from 'mol-geo/representation/structure/representati const spacefillProps: Partial<SpacefillProps> = { doubleSided: true, colorTheme: { name: 'chain-id' }, + sizeTheme: { name: 'physical', factor: 1.0 }, quality: 'auto', useFog: false } @@ -88,7 +89,7 @@ export class Stage { // this.loadPdbid('1hrv') // viral assembly // this.loadPdbid('1rb8') // virus // this.loadPdbid('1blu') // metal coordination - this.loadPdbid('3pqr') // inter unit bonds, two polymer chains, ligands, water, carbohydrates linked to protein + // this.loadPdbid('3pqr') // inter unit bonds, two polymer chains, ligands, water, carbohydrates linked to protein // this.loadPdbid('4v5a') // ribosome // this.loadPdbid('3j3q') // ... // this.loadPdbid('2np2') // dna @@ -123,25 +124,24 @@ export class Stage { // this.loadPdbid('5u0q') // mixed dna/rna in same polymer // this.loadPdbid('5u0q') // temp - // this.loadMmcifUrl(`../../../test/pdb-dev/PDBDEV_00000001.cif`) // ok + this.loadMmcifUrl(`../../../test/pdb-dev/PDBDEV_00000001.cif`) // ok // this.loadMmcifUrl(`../../../test/pdb-dev/PDBDEV_00000002.cif`) // ok // this.loadMmcifUrl(`../../../test/pdb-dev/PDBDEV_00000003.cif`) // ok - // this.loadMmcifUrl(`../../../test/pdb-dev/PDBDEV_00000004.cif`) // TODO issue with cross-link extraction + // this.loadMmcifUrl(`../../../test/pdb-dev/PDBDEV_00000004.cif`) // TODO issue with cross-link extraction, not shown // this.loadMmcifUrl(`../../../test/pdb-dev/PDBDEV_00000005.cif`) // ok - // this.loadMmcifUrl(`../../../test/pdb-dev/PDBDEV_00000006.cif`) // TODO only three spacefill atoms rendered - // this.loadMmcifUrl(`../../../test/pdb-dev/PDBDEV_00000007.cif`) // TODO only three spacefill atoms rendered + // this.loadMmcifUrl(`../../../test/pdb-dev/PDBDEV_00000006.cif`) // ok + // this.loadMmcifUrl(`../../../test/pdb-dev/PDBDEV_00000007.cif`) // ok // this.loadMmcifUrl(`../../../test/pdb-dev/PDBDEV_00000008.cif`) // ok // this.loadMmcifUrl(`../../../test/pdb-dev/PDBDEV_00000010.cif`) // ok // this.loadMmcifUrl(`../../../test/pdb-dev/PDBDEV_00000011.cif`) // ok // this.loadMmcifUrl(`../../../test/pdb-dev/PDBDEV_00000012.cif`) // ok // this.loadMmcifUrl(`../../../test/pdb-dev/PDBDEV_00000014.cif`) // ok - // this.loadMmcifUrl(`../../../test/pdb-dev/PDBDEV_00000016.cif`) // TODO only three spacefill atoms rendered + // this.loadMmcifUrl(`../../../test/pdb-dev/PDBDEV_00000016.cif`) // ok } async loadMmcifUrl (url: string) { const urlEntity = UrlEntity.ofUrl(this.ctx, url) const modelEntity = await MmcifUrlToModel.apply(this.ctx, urlEntity) - console.log(modelEntity.value) const structureEntity = await ModelToStructure.apply(this.ctx, modelEntity) StructureToBallAndStick.apply(this.ctx, structureEntity, { ...ballAndStickProps, visible: true })