diff --git a/src/apps/render-test/state.ts b/src/apps/render-test/state.ts index aeaf9c4f135f4318c753efe8301ea8e29e04f3c8..4e6453fdc9f91a71229686cd67ef7d95fe3e0511 100644 --- a/src/apps/render-test/state.ts +++ b/src/apps/render-test/state.ts @@ -51,9 +51,9 @@ export default class State { await Run(structPointRepr.create(struct), log, 100) structPointRepr.renderObjects.forEach(viewer.add) - // const structSpacefillRepr = StructureRepresentation(Spacefill) - // await Run(structSpacefillRepr.create(struct, { detail: 2 }), log, 100) - // structSpacefillRepr.renderObjects.forEach(viewer.add) + const structSpacefillRepr = StructureRepresentation(Spacefill) + await Run(structSpacefillRepr.create(struct, { detail: 2 }), log, 100) + structSpacefillRepr.renderObjects.forEach(viewer.add) viewer.requestDraw() console.log(viewer.stats) diff --git a/src/mol-geo/color/data.ts b/src/mol-geo/color/data.ts index 6e32d8d42d94ea7b1f058003e766526e03e1711e..3e98a815c43a27429fef9b8cbe209122d17eff92 100644 --- a/src/mol-geo/color/data.ts +++ b/src/mol-geo/color/data.ts @@ -105,5 +105,6 @@ export function createElementInstanceColor(props: ElementInstanceColorProps): El /** Create color attribute or texture, depending on the mesh */ export function createAttributeOrElementColor(mesh: Mesh, props: AttributeColorProps) { - return mesh.vertexCount < 4 * mesh.offsetCount ? createAttributeColor(props) : createElementColor(props) + // return mesh.vertexCount < 4 * mesh.offsetCount ? createAttributeColor(props) : createElementColor(props) + return createAttributeColor(props) } \ No newline at end of file diff --git a/src/mol-geo/representation/structure/point.ts b/src/mol-geo/representation/structure/point.ts index 7f187d1720a85741123053ea4375eaaad351a227..511bcd018025e1c6f141f8ed54d99304f48fbc6b 100644 --- a/src/mol-geo/representation/structure/point.ts +++ b/src/mol-geo/representation/structure/point.ts @@ -19,6 +19,7 @@ import { fillSerial } from 'mol-gl/renderable/util'; import { ColorScale } from '../../color/scale'; import { createUniformSize } from '../../size/data'; import { vdwSizeData } from '../../size/structure/vdw'; +import VertexMap from '../../shape/vertex-map'; export const DefaultPointProps = { @@ -65,11 +66,12 @@ export default function Point(): UnitsRepresentation<PointProps> { const size = vdwSizeData({ units, elementGroup, - offsetData: { - primitiveCount: elementCount, - offsetCount: elementCount + 1, - offsets: fillSerial(new Uint32Array(elementCount + 1)) - } + vertexMap: VertexMap.create( + elementCount, + elementCount + 1, + fillSerial(new Uint32Array(elementCount)), + fillSerial(new Uint32Array(elementCount + 1)) + ) }) console.log(size) diff --git a/src/mol-geo/representation/structure/spacefill.ts b/src/mol-geo/representation/structure/spacefill.ts index 39c206cf87be50dbcff62dd7565dacd9cd045463..9a38a8526a8a15b1e1d81b4af45fe0f54ba763e4 100644 --- a/src/mol-geo/representation/structure/spacefill.ts +++ b/src/mol-geo/representation/structure/spacefill.ts @@ -60,7 +60,6 @@ export default function Spacefill(): UnitsRepresentation<SpacefillProps> { const mesh = meshBuilder.getMesh() // console.log(mesh) - if (!mesh.offsetBuffer.ref.value) return const unitCount = units.length const transformArray = new Float32Array(unitCount * 16) @@ -100,7 +99,7 @@ export default function Spacefill(): UnitsRepresentation<SpacefillProps> { instanceCount: unitCount, indexCount: mesh.triangleCount, - elementCount: mesh.offsetCount - 1, + elementCount: elementCount, positionCount: mesh.vertexCount }) renderObjects.push(spheres) diff --git a/src/mol-geo/shape/mesh.ts b/src/mol-geo/shape/mesh.ts index fce47eec05ff4ccd62b43378190e7771e2b00330..daab5862beadae5b31a7ac0388058dbd876ca65d 100644 --- a/src/mol-geo/shape/mesh.ts +++ b/src/mol-geo/shape/mesh.ts @@ -11,18 +11,24 @@ import Sphere from 'mol-math/geometry/sphere' import { transformPositionArray } from '../util'; export interface Mesh { + /** Number of vertices in the mesh */ vertexCount: number, + /** Number of triangles in the mesh */ triangleCount: number, - offsetCount: number, + /** Vertex buffer as array of xyz values wrapped in a value cell */ vertexBuffer: ValueCell<Float32Array>, + /** Index buffer as array of vertex index triplets wrapped in a value cell */ indexBuffer: ValueCell<Uint32Array>, + /** Normal buffer as array of xyz values for each vertex wrapped in a value cell */ normalBuffer: ValueCell<Float32Array | undefined>, + /** Id buffer as array of ids for each vertex wrapped in a value cell */ idBuffer: ValueCell<Float32Array | undefined>, - offsetBuffer: ValueCell<Uint32Array | undefined>, + + /** Flag indicating if normals are computed for the current set of vertices */ normalsComputed: boolean, - vertexAnnotation?: ValueCell<ArrayLike<number>> + /** Bounding sphere of the mesh */ boundingSphere?: Sphere } @@ -84,6 +90,38 @@ export namespace Mesh { mesh.normalsComputed = false; // mesh.boundingSphere = void 0; } + + export function computeBoundingSphere(mesh: Mesh): Task<Mesh> { + return Task.create<Mesh>('Mesh (Compute Bounding Sphere)', async ctx => { + if (mesh.boundingSphere) { + return mesh; + } + await ctx.update('Computing bounding sphere...'); + + const vertices = mesh.vertexBuffer.ref.value; + let x = 0, y = 0, z = 0; + for (let i = 0, _c = vertices.length; i < _c; i += 3) { + x += vertices[i]; + y += vertices[i + 1]; + z += vertices[i + 2]; + } + x /= mesh.vertexCount; + y /= mesh.vertexCount; + z /= mesh.vertexCount; + let r = 0; + for (let i = 0, _c = vertices.length; i < _c; i += 3) { + const dx = x - vertices[i]; + const dy = y - vertices[i + 1]; + const dz = z - vertices[i + 2]; + r = Math.max(r, dx * dx + dy * dy + dz * dz); + } + mesh.boundingSphere = { + center: Vec3.create(x, y, z), + radius: Math.sqrt(r) + } + return mesh; + }); + } } // function addVertex(src: Float32Array, i: number, dst: Float32Array, j: number) { @@ -167,45 +205,4 @@ export namespace Mesh { // if (iterCount === 0) return Computation.resolve(surface); // return computation(async ctx => await laplacianSmoothComputation(ctx, surface, iterCount, (1.1 * vertexWeight) / 1.1)); -// } - - export function computeBoundingSphere(mesh: Mesh): Task<Mesh> { - return Task.create<Mesh>('Mesh (Compute Bounding Sphere)', async ctx => { - if (mesh.boundingSphere) { - return mesh; - } - await ctx.update('Computing bounding sphere...'); - - const vertices = mesh.vertexBuffer.ref.value; - let x = 0, y = 0, z = 0; - for (let i = 0, _c = vertices.length; i < _c; i += 3) { - x += vertices[i]; - y += vertices[i + 1]; - z += vertices[i + 2]; - } - x /= mesh.vertexCount; - y /= mesh.vertexCount; - z /= mesh.vertexCount; - let r = 0; - for (let i = 0, _c = vertices.length; i < _c; i += 3) { - const dx = x - vertices[i]; - const dy = y - vertices[i + 1]; - const dz = z - vertices[i + 2]; - r = Math.max(r, dx * dx + dy * dy + dz * dz); - } - mesh.boundingSphere = { - center: Vec3.create(x, y, z), - radius: Math.sqrt(r) - } - return mesh; - }); - } - -// export function transform(surface: Surface, t: number[]): Computation<Surface> { -// return computation<Surface>(async ctx => { -// ctx.updateProgress('Updating surface...'); -// transformImmediate(surface, t); -// return surface; -// }); -// } -// } \ No newline at end of file +// } \ No newline at end of file diff --git a/src/mol-geo/shape/point.ts b/src/mol-geo/shape/point.ts deleted file mode 100644 index 5720e664f898570e2de8b3e8808f8199df111f5f..0000000000000000000000000000000000000000 --- a/src/mol-geo/shape/point.ts +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info. - * - * @author Alexander Rose <alexander.rose@weirdbyte.de> - */ - - -export function countFromModel(model: any) {} -export function positionFromModel(model: any, array: Float32Array, offset: number) { - -} -export function colorFromModel(model: any, params: any, array: Float32Array, offset: number) { - -} -export function sizeFromModel(model: any, params: any, array: Float32Array, offset: number) { - -} \ No newline at end of file diff --git a/src/mol-geo/shape/sphere.ts b/src/mol-geo/shape/sphere.ts deleted file mode 100644 index 54cd72a4b8ba4dcf581d87842432de530588078b..0000000000000000000000000000000000000000 --- a/src/mol-geo/shape/sphere.ts +++ /dev/null @@ -1,5 +0,0 @@ -/** - * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info. - * - * @author Alexander Rose <alexander.rose@weirdbyte.de> - */ diff --git a/src/mol-geo/shape/vertex-map.ts b/src/mol-geo/shape/vertex-map.ts new file mode 100644 index 0000000000000000000000000000000000000000..e21f0bf00456dc3ee61ee6572991f3c5b36c2f18 --- /dev/null +++ b/src/mol-geo/shape/vertex-map.ts @@ -0,0 +1,42 @@ +/** + * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info. + * + * @author Alexander Rose <alexander.rose@weirdbyte.de> + */ + +import { Mesh } from './mesh'; + +/** Mapping between vertices and ids */ +interface VertexMap { + idCount: number, + offsetCount: number, + ids: Helpers.NumberArray | undefined + offsets: Helpers.NumberArray, +} + +function createOffsets(ids: Helpers.NumberArray | undefined) { + return [] +} + +namespace VertexMap { + export function create(idCount: number, offsetCount: number, ids: Helpers.NumberArray | undefined, offsets: Helpers.NumberArray): VertexMap { + return { + idCount, + offsetCount, + ids, + offsets + } + } + + export function fromMesh(mesh: Mesh) { + const ids = mesh.idBuffer.ref.value + const offsets = createOffsets(ids) + return create(mesh.vertexCount, offsets.length, ids, offsets) + } + + export function rangeFromId (id: number, vertexMap: VertexMap) { + return [0, 0] + } +} + +export default VertexMap \ No newline at end of file diff --git a/src/mol-geo/size/data.ts b/src/mol-geo/size/data.ts index fe8be6a3a7fbc2f88a87a29d2c2a11c6d3cd5765..a05726b17e76cdd1d0631db82b516f5526d8e120 100644 --- a/src/mol-geo/size/data.ts +++ b/src/mol-geo/size/data.ts @@ -5,17 +5,11 @@ */ import { ValueCell } from 'mol-util'; +import VertexMap from '../shape/vertex-map'; export type UniformSize = { type: 'uniform', value: number } export type AttributeSize = { type: 'attribute', value: ValueCell<Float32Array> } export type SizeData = UniformSize | AttributeSize - -export interface OffsetData { - primitiveCount: number, - offsetCount: number, - offsets: Uint32Array -} - export interface UniformSizeProps { value: number } @@ -27,18 +21,17 @@ export function createUniformSize(props: UniformSizeProps): UniformSize { export interface AttributeSizeProps { sizeFn: (elementIdx: number) => number - offsetData: OffsetData + vertexMap: VertexMap } /** Creates size attribute with size for each element (i.e. shared across indtances/units) */ export function createAttributeSize(props: AttributeSizeProps): AttributeSize { - const { sizeFn, offsetData } = props - const { primitiveCount, offsetCount, offsets } = offsetData - const sizes = new Float32Array(primitiveCount); - const _offsets = offsets // .ref.value + const { sizeFn, vertexMap } = props + const { idCount, offsetCount, offsets } = vertexMap + const sizes = new Float32Array(idCount); for (let i = 0, il = offsetCount - 1; i < il; ++i) { - const start = _offsets[i] - const end = _offsets[i + 1] + const start = offsets[i] + const end = offsets[i + 1] const size = sizeFn(i) for (let i = start, il = end; i < il; ++i) { sizes[i] = size diff --git a/src/mol-geo/size/structure/index.ts b/src/mol-geo/size/structure/index.ts index 20e1a15617b1084aee91f124377a32cb576c7dc8..4ec3dee79cd5467e969fe3cc1679661991cc9274 100644 --- a/src/mol-geo/size/structure/index.ts +++ b/src/mol-geo/size/structure/index.ts @@ -5,10 +5,10 @@ */ import { ElementGroup, Unit } from 'mol-model/structure'; -import { OffsetData } from '../data'; +import VertexMap from '../../shape/vertex-map'; export interface StructureSizeDataProps { units: ReadonlyArray<Unit>, elementGroup: ElementGroup, - offsetData: OffsetData + vertexMap: VertexMap } \ No newline at end of file diff --git a/src/mol-geo/size/structure/vdw.ts b/src/mol-geo/size/structure/vdw.ts index dd4e230b93e5a0d772064e6a00808abd118fde58..522033493e26bcca88abab4cdfdfb8c57792fec1 100644 --- a/src/mol-geo/size/structure/vdw.ts +++ b/src/mol-geo/size/structure/vdw.ts @@ -10,13 +10,13 @@ import { StructureSizeDataProps } from '.'; import { createAttributeSize } from '../data'; export function vdwSizeData(props: StructureSizeDataProps) { - const { units, elementGroup, offsetData } = props + const { units, elementGroup, vertexMap } = props const { type_symbol } = units[0].model.hierarchy.atoms return createAttributeSize({ sizeFn: (elementIdx: number) => { const e = OrderedSet.getAt(elementGroup.elements, elementIdx) return VdwRadius(type_symbol.value(e)) }, - offsetData + vertexMap }) } \ No newline at end of file diff --git a/src/mol-geo/util/marching-cubes/algorithm.ts b/src/mol-geo/util/marching-cubes/algorithm.ts index 015f7f4db104d0fc5a9defef176264e46e62934f..25b266773ce26c0afd7a22332083f915f63aa913 100644 --- a/src/mol-geo/util/marching-cubes/algorithm.ts +++ b/src/mol-geo/util/marching-cubes/algorithm.ts @@ -21,7 +21,7 @@ export interface MarchingCubesParameters { bottomLeft?: ArrayLike<number>, topRight?: ArrayLike<number>, - annotationField?: Tensor, + idField?: Tensor, oldSurface?: Mesh } @@ -73,20 +73,17 @@ class MarchingCubesComputation { const os = this.parameters.oldSurface - let ret: Mesh = { + const ret: Mesh = { vertexCount: this.state.vertexCount, triangleCount: this.state.triangleCount, - offsetCount: 0, vertexBuffer: os ? ValueCell.update(os.vertexBuffer, vb) : ValueCell.create(vb), indexBuffer: os ? ValueCell.update(os.indexBuffer, ib) : ValueCell.create(ib), normalBuffer: os ? os.normalBuffer : ValueCell.create(void 0), - idBuffer: os ? os.idBuffer : ValueCell.create(void 0), - offsetBuffer: os ? os.offsetBuffer : ValueCell.create(void 0), - vertexAnnotation: this.state.annotate - ? os && os.vertexAnnotation - ? ValueCell.update(os.vertexAnnotation, ChunkedArray.compact(this.state.annotationBuffer)) - : ValueCell.create(ChunkedArray.compact(this.state.annotationBuffer)) - : void 0, + idBuffer: this.state.assignIds + ? os && os.idBuffer + ? ValueCell.update(os.idBuffer, ChunkedArray.compact(this.state.idBuffer) as Float32Array) + : ValueCell.create(ChunkedArray.compact(this.state.idBuffer) as Float32Array) + : ValueCell.create(void 0), normalsComputed: false } @@ -124,9 +121,9 @@ class MarchingCubesState { isoLevel: number; scalarFieldGet: Tensor.Space['get']; scalarField: Tensor.Data; - annotationFieldGet?: Tensor.Space['get']; - annotationField?: Tensor.Data; - annotate: boolean; + idFieldGet?: Tensor.Space['get']; + idField?: Tensor.Data; + assignIds: boolean; // two layers of vertex indices. Each vertex has 3 edges associated. verticesOnEdges: Int32Array; @@ -134,7 +131,7 @@ class MarchingCubesState { i: number = 0; j: number = 0; k: number = 0; vertexBuffer: ChunkedArray<number, 3>; - annotationBuffer: ChunkedArray<number, 1>; + idBuffer: ChunkedArray<number, 1>; triangleBuffer: ChunkedArray<number, 3>; vertexCount = 0; triangleCount = 0; @@ -164,7 +161,8 @@ class MarchingCubesState { const a = edge.a, b = edge.b; const li = a.i + this.i, lj = a.j + this.j, lk = a.k + this.k; const hi = b.i + this.i, hj = b.j + this.j, hk = b.k + this.k; - const v0 = this.scalarFieldGet(this.scalarField, li, lj, lk), v1 = this.scalarFieldGet(this.scalarField, hi, hj, hk); + const v0 = this.scalarFieldGet(this.scalarField, li, lj, lk); + const v1 = this.scalarFieldGet(this.scalarField, hi, hj, hk); const t = (this.isoLevel - v0) / (v0 - v1); const id = ChunkedArray.add3( @@ -175,12 +173,12 @@ class MarchingCubesState { this.verticesOnEdges[edgeId] = id + 1; - if (this.annotate) { - const u = this.annotationFieldGet!(this.annotationField!, li, lj, lk); - const v = this.annotationFieldGet!(this.annotationField!, hi, hj, hk) + if (this.assignIds) { + const u = this.idFieldGet!(this.idField!, li, lj, lk); + const v = this.idFieldGet!(this.idField!, hi, hj, hk) let a = t < 0.5 ? u : v; if (a < 0) a = t < 0.5 ? v : u; - ChunkedArray.add(this.annotationBuffer, a); + ChunkedArray.add(this.idBuffer, a); } this.vertexCount++; @@ -194,9 +192,9 @@ class MarchingCubesState { this.isoLevel = params.isoLevel; this.scalarFieldGet = params.scalarField.space.get; this.scalarField = params.scalarField.data; - if (params.annotationField) { - this.annotationField = params.annotationField.data; - this.annotationFieldGet = params.annotationField.space.get; + if (params.idField) { + this.idField = params.idField.data; + this.idFieldGet = params.idField.space.get; } let dX = params.topRight![0] - params.bottomLeft![0], dY = params.topRight![1] - params.bottomLeft![1], dZ = params.topRight![2] - params.bottomLeft![2], @@ -208,8 +206,8 @@ class MarchingCubesState { this.triangleBuffer = ChunkedArray.create(Uint32Array, 3, triangleBufferSize, params.oldSurface && params.oldSurface.indexBuffer.ref.value); - this.annotate = !!params.annotationField; - if (this.annotate) this.annotationBuffer = ChunkedArray.create(Int32Array, 1, vertexBufferSize); + this.assignIds = !!params.idField; + if (this.assignIds) this.idBuffer = ChunkedArray.create(Int32Array, 1, vertexBufferSize); // two layers of vertex indices. Each vertex has 3 edges associated. this.verticesOnEdges = new Int32Array(3 * this.nX * this.nY * 2);