diff --git a/src/mol-math/graph/int-adjacency-graph.ts b/src/mol-math/graph/int-adjacency-graph.ts index fabc636e9bf86fc3e28548ee306faa9dede5adbc..fe26bfdfd852966881ddf063bcd6c275ce27e389 100644 --- a/src/mol-math/graph/int-adjacency-graph.ts +++ b/src/mol-math/graph/int-adjacency-graph.ts @@ -5,7 +5,7 @@ * @author Alexander Rose <alexander.rose@weirdbyte.de> */ -import { arrayPickIndices } from 'mol-data/util'; +import { arrayPickIndices, cantorPairing } from 'mol-data/util'; import { LinkedIndex } from 'mol-data/int'; /** @@ -160,6 +160,35 @@ export namespace IntAdjacencyGraph { } } + export class UniqueEdgeBuilder { + private xs: number[] = []; + private ys: number[] = []; + private included = new Set<number>(); + + addEdge(i: number, j: number) { + let u = i, v = j; + if (i > j) { u = j; v = i; } + const id = cantorPairing(u, v); + if (this.included.has(id)) return false; + this.included.add(id); + this.xs[this.xs.length] = u; + this.ys[this.ys.length] = v; + return true; + } + + getGraph(): IntAdjacencyGraph { + return fromVertexPairs(this.vertexCount, this.xs, this.ys); + } + + // if we cant to add custom props as well + getEdgeBuiler() { + return new EdgeBuilder(this.vertexCount, this.xs, this.ys); + } + + constructor(public vertexCount: number) { + } + } + export function fromVertexPairs(vertexCount: number, xs: number[], ys: number[]) { const graphBuilder = new IntAdjacencyGraph.EdgeBuilder(vertexCount, xs, ys); graphBuilder.addAllEdges(); diff --git a/src/mol-model/structure/structure/unit/rings/compute.ts b/src/mol-model/structure/structure/unit/rings/compute.ts index c1a7cfaba1ebc4e0758441d48e68ea0045e05376..a6d5da313c4492df5e1814f522717409834c554a 100644 --- a/src/mol-model/structure/structure/unit/rings/compute.ts +++ b/src/mol-model/structure/structure/unit/rings/compute.ts @@ -4,13 +4,12 @@ * @author David Sehnal <david.sehnal@gmail.com> */ -import Unit from '../../unit'; -import { IntraUnitLinks } from '../links/data'; import { Segmentation } from 'mol-data/int'; +import { IntAdjacencyGraph } from 'mol-math/graph'; import { LinkType } from '../../../model/types'; import { StructureElement } from '../../../structure'; -import { sortedCantorPairing } from 'mol-data/util'; -import { IntAdjacencyGraph } from 'mol-math/graph'; +import Unit from '../../unit'; +import { IntraUnitLinks } from '../links/data'; export function computeRings(unit: Unit.Atomic) { const size = largestResidue(unit); @@ -262,9 +261,7 @@ export function createIndex(rings: StructureElement.UnitIndex[][]) { } // create a graph where vertices are rings, edge if two rings share at least one atom - const addedEdges = new Set<number>(); - const xs: RingIndex[] = [], ys: RingIndex[] = []; - + const graph = new IntAdjacencyGraph.UniqueEdgeBuilder(rings.length); for (let rI = 0 as RingIndex, _rI = rings.length; rI < _rI; rI++) { const r = rings[rI]; @@ -278,19 +275,12 @@ export function createIndex(rings: StructureElement.UnitIndex[][]) { for (let j = 0, _j = containedRings.length; j < _j; j++) { const rJ = containedRings[j]; if (rI >= rJ) continue; - - const edgeIndex = sortedCantorPairing(rI, rJ); - if (addedEdges.has(edgeIndex)) continue; - - addedEdges.add(edgeIndex); - xs[xs.length] = rI; - ys[ys.length] = rJ; + graph.addEdge(rI, rJ); } } } - const graph = IntAdjacencyGraph.fromVertexPairs(rings.length, xs, ys); - const components = IntAdjacencyGraph.connectedComponents(graph); + const components = IntAdjacencyGraph.connectedComponents(graph.getGraph()); const ringComponentIndex = components.componentIndex as any as RingComponentIndex[]; const ringComponents: RingIndex[][] = [];