diff --git a/src/mol-model-formats/shape/ply.ts b/src/mol-model-formats/shape/ply.ts index 61add2ae67fecf902d94435ba2b56405cba34758..4eb687020db3aff1946eb9fb0f307fb59c7106dd 100644 --- a/src/mol-model-formats/shape/ply.ts +++ b/src/mol-model-formats/shape/ply.ts @@ -13,8 +13,9 @@ import { MeshBuilder } from 'mol-geo/geometry/mesh/mesh-builder'; import { Mesh } from 'mol-geo/geometry/mesh/mesh'; import { Shape } from 'mol-model/shape'; import { ChunkedArray } from 'mol-data/util'; +import { arrayMax } from 'mol-util/array'; -async function getPlyMesh(ctx: RuntimeContext, vertex: PlyTable, face: PlyList, mesh?: Mesh) { +async function getPlyMesh(ctx: RuntimeContext, vertex: PlyTable, face: PlyList, groupIds: ArrayLike<number>, mesh?: Mesh) { const builderState = MeshBuilder.createState(face.rowCount, face.rowCount, mesh) const { vertices, normals, indices, groups } = builderState @@ -28,15 +29,12 @@ async function getPlyMesh(ctx: RuntimeContext, vertex: PlyTable, face: PlyList, const nz = vertex.getProperty('nz') if (!nx || !ny || !nz) throw new Error('missing normal properties') - const atomid = vertex.getProperty('atomid') - if (!atomid) throw new Error('missing atomid property') - for (let i = 0, il = vertex.rowCount; i < il; ++i) { if (i % 10000 === 0 && ctx.shouldUpdate) await ctx.update({ current: i, max: il, message: `adding vertex ${i}` }) ChunkedArray.add3(vertices, x.value(i), y.value(i), z.value(i)) ChunkedArray.add3(normals, nx.value(i), ny.value(i), nz.value(i)); - ChunkedArray.add(groups, atomid.value(i)) + ChunkedArray.add(groups, groupIds[i]) } for (let i = 0, il = face.rowCount; i < il; ++i) { @@ -57,6 +55,11 @@ async function getShape(ctx: RuntimeContext, plyFile: PlyFile, props: {}, shape? const atomid = vertex.getProperty('atomid') if (!atomid) throw new Error('missing atomid property') + const groupIds = atomid.toArray({ array: Int32Array }) + const maxGroupId = arrayMax(groupIds) // assumes uint group ids + const groupIdMap = new Uint32Array(maxGroupId + 1) + for (let i = 0, il = groupIds.length; i < il; ++i) groupIdMap[groupIds[i]] = i + const red = vertex.getProperty('red') const green = vertex.getProperty('green') const blue = vertex.getProperty('blue') @@ -65,15 +68,16 @@ async function getShape(ctx: RuntimeContext, plyFile: PlyFile, props: {}, shape? const face = plyFile.getElement('face') as PlyList if (!face) throw new Error('missing face element') - const mesh = await getPlyMesh(ctx, vertex, face, shape && shape.geometry) + const mesh = await getPlyMesh(ctx, vertex, face, groupIds, shape && shape.geometry) return shape || Shape.create( 'test', plyFile, mesh, (groupId: number) => { - return Color.fromRgb(red.value(groupId), green.value(groupId), blue.value(groupId)) + const idx = groupIdMap[groupId] + return Color.fromRgb(red.value(idx), green.value(idx), blue.value(idx)) }, () => 1, // size: constant (groupId: number) => { - return atomid.value(groupId).toString() + return atomid.value(groupIdMap[groupId]).toString() } ) } diff --git a/src/mol-util/array.ts b/src/mol-util/array.ts index 078ab5319b4db6bdd612c7655390a8e4a0e2225f..d9c19419b1ee4a0f91f79f54033f72ee1c56e65e 100644 --- a/src/mol-util/array.ts +++ b/src/mol-util/array.ts @@ -1,5 +1,5 @@ /** - * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info. + * Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose <alexander.rose@weirdbyte.de> */ @@ -9,7 +9,7 @@ import { NumberArray } from './type-helpers'; // TODO move to mol-math as Vector??? /** Get the maximum value in an array */ -export function arrayMax(array: NumberArray) { +export function arrayMax(array: ArrayLike<number>) { let max = -Infinity for (let i = 0, il = array.length; i < il; ++i) { if (array[i] > max) max = array[i] @@ -18,7 +18,7 @@ export function arrayMax(array: NumberArray) { } /** Get the minimum value in an array */ -export function arrayMin(array: NumberArray) { +export function arrayMin(array: ArrayLike<number>) { let min = Infinity for (let i = 0, il = array.length; i < il; ++i) { if (array[i] < min) min = array[i] @@ -27,7 +27,7 @@ export function arrayMin(array: NumberArray) { } /** Get the sum of values in an array */ -export function arraySum(array: NumberArray, stride = 1, offset = 0) { +export function arraySum(array: ArrayLike<number>, stride = 1, offset = 0) { const n = array.length let sum = 0 for (let i = offset; i < n; i += stride) { @@ -37,12 +37,12 @@ export function arraySum(array: NumberArray, stride = 1, offset = 0) { } /** Get the mean of values in an array */ -export function arrayMean(array: NumberArray, stride = 1, offset = 0) { +export function arrayMean(array: ArrayLike<number>, stride = 1, offset = 0) { return arraySum(array, stride, offset) / (array.length / stride) } /** Get the root mean square of values in an array */ -export function arrayRms(array: NumberArray) { +export function arrayRms(array: ArrayLike<number>) { const n = array.length let sumSq = 0 for (let i = 0; i < n; ++i) {