From 2ad23d6c2929681497857567c3db4f659b594bc4 Mon Sep 17 00:00:00 2001 From: Alexander Rose <alexander.rose@weirdbyte.de> Date: Sun, 3 Jun 2018 00:19:12 -0400 Subject: [PATCH] refactored spacefill creation a bit --- .../representation/structure/spacefill.ts | 62 +++++-------------- src/mol-geo/representation/structure/utils.ts | 43 ++++++++++++- src/mol-geo/shape/mesh.ts | 22 +++++++ src/mol-geo/util/marching-cubes/algorithm.ts | 1 + 4 files changed, 77 insertions(+), 51 deletions(-) diff --git a/src/mol-geo/representation/structure/spacefill.ts b/src/mol-geo/representation/structure/spacefill.ts index f2ace9de1..ebfbe71a1 100644 --- a/src/mol-geo/representation/structure/spacefill.ts +++ b/src/mol-geo/representation/structure/spacefill.ts @@ -8,15 +8,11 @@ import { ValueCell } from 'mol-util/value-cell' import { RenderObject, createMeshRenderObject, MeshRenderObject } from 'mol-gl/render-object' -// import { createColorTexture } from 'mol-gl/util'; -import { Vec3, Mat4 } from 'mol-math/linear-algebra' import { Unit, Element, Queries } from 'mol-model/structure'; import { UnitsRepresentation, DefaultStructureProps } from './index'; import { Task } from 'mol-task' -import { MeshBuilder } from '../../shape/mesh-builder'; -import { createTransforms, createColors, createFlags, createEmptyFlags } from './utils'; +import { createTransforms, createColors, createFlags, createEmptyFlags, createSphereMesh } from './utils'; import VertexMap from '../../shape/vertex-map'; -import { icosahedronVertexCount } from '../../primitive/icosahedron'; import { deepEqual, defaults } from 'mol-util'; import { fillSerial } from 'mol-gl/renderable/util'; import { RenderableState, MeshValues } from 'mol-gl/renderable'; @@ -24,6 +20,19 @@ import { getMeshData } from '../../util/mesh-data'; import { Mesh } from '../../shape/mesh'; import { PickingId } from '../../util/picking'; +function createSpacefillMesh(unit: Unit, detail: number, mesh?: Mesh) { + let radius: Element.Property<number> + if (Unit.isAtomic(unit)) { + radius = Queries.props.atom.vdw_radius + } else if (Unit.isSpheres(unit)) { + radius = Queries.props.coarse.sphere_radius + } else { + console.warn('Unsupported unit type') + return Task.constant('Empty mesh', Mesh.createEmpty(mesh)) + } + return createSphereMesh(unit, radius, detail, mesh) +} + export const DefaultSpacefillProps = { ...DefaultStructureProps, flipSided: false, @@ -32,49 +41,6 @@ export const DefaultSpacefillProps = { } export type SpacefillProps = Partial<typeof DefaultSpacefillProps> -function createSpacefillMesh(unit: Unit, detail: number, mesh?: Mesh) { - return Task.create('Sphere mesh', async ctx => { - const { elements } = unit; - const elementCount = elements.length; - const vertexCount = elementCount * icosahedronVertexCount(detail) - const meshBuilder = MeshBuilder.create(vertexCount, vertexCount / 2, mesh) - - let radius: Element.Property<number> - if (Unit.isAtomic(unit)) { - radius = Queries.props.atom.vdw_radius - } else if (Unit.isSpheres(unit)) { - radius = Queries.props.coarse.sphere_radius - } else { - console.warn('Unsupported unit type') - return meshBuilder.getMesh() - } - - const v = Vec3.zero() - const m = Mat4.identity() - - const { x, y, z } = unit.conformation - const l = Element.Location() - l.unit = unit - - for (let i = 0; i < elementCount; i++) { - l.element = elements[i] - v[0] = x(l.element) - v[1] = y(l.element) - v[2] = z(l.element) - Mat4.setTranslation(m, v) - - meshBuilder.setId(i) - meshBuilder.addIcosahedron(m, { radius: radius(l), detail }) - - if (i % 10000 === 0 && ctx.shouldUpdate) { - await ctx.update({ message: 'Sphere mesh', current: i, max: elementCount }); - } - } - - return meshBuilder.getMesh() - }) -} - export default function Spacefill(): UnitsRepresentation<SpacefillProps> { const renderObjects: RenderObject[] = [] let spheres: MeshRenderObject diff --git a/src/mol-geo/representation/structure/utils.ts b/src/mol-geo/representation/structure/utils.ts index cee35dd1e..5771c3f12 100644 --- a/src/mol-geo/representation/structure/utils.ts +++ b/src/mol-geo/representation/structure/utils.ts @@ -5,8 +5,8 @@ * @author David Sehnal <david.sehnal@gmail.com> */ -import { Unit } from 'mol-model/structure'; -import { Mat4, Vec2 } from 'mol-math/linear-algebra' +import { Unit, Element } from 'mol-model/structure'; +import { Mat4, Vec2, Vec3 } from 'mol-math/linear-algebra' import { createUniformColor, ColorData } from '../../util/color-data'; import { createUniformSize } from '../../util/size-data'; @@ -16,6 +16,10 @@ import { ColorTheme, SizeTheme } from '../../theme'; import { elementIndexColorData, elementSymbolColorData, instanceIndexColorData, chainIdColorData } from '../../theme/structure/color'; import { ValueCell } from 'mol-util'; import { TextureImage, createTextureImage } from 'mol-gl/renderable/util'; +import { Mesh } from '../../shape/mesh'; +import { Task } from 'mol-task'; +import { icosahedronVertexCount } from '../../primitive/icosahedron'; +import { MeshBuilder } from '../../shape/mesh-builder'; export function createTransforms({ units }: Unit.SymmetryGroup, transforms?: ValueCell<Float32Array>) { const unitCount = units.length @@ -93,4 +97,37 @@ export function createEmptyFlags(flagData?: FlagData) { uFlagTexSize: ValueCell.create(Vec2.create(1, 1)), } } -} \ No newline at end of file +} + +export function createSphereMesh(unit: Unit, radius: Element.Property<number>, detail: number, mesh?: Mesh) { + return Task.create('Sphere mesh', async ctx => { + const { elements } = unit; + const elementCount = elements.length; + const vertexCount = elementCount * icosahedronVertexCount(detail) + const meshBuilder = MeshBuilder.create(vertexCount, vertexCount / 2, mesh) + + const v = Vec3.zero() + const m = Mat4.identity() + + const { x, y, z } = unit.conformation + const l = Element.Location() + l.unit = unit + + for (let i = 0; i < elementCount; i++) { + l.element = elements[i] + v[0] = x(l.element) + v[1] = y(l.element) + v[2] = z(l.element) + Mat4.setTranslation(m, v) + + meshBuilder.setId(i) + meshBuilder.addIcosahedron(m, { radius: radius(l), detail }) + + if (i % 10000 === 0 && ctx.shouldUpdate) { + await ctx.update({ message: 'Sphere mesh', current: i, max: elementCount }); + } + } + + return meshBuilder.getMesh() + }) +} diff --git a/src/mol-geo/shape/mesh.ts b/src/mol-geo/shape/mesh.ts index 6d63fd851..9447404a3 100644 --- a/src/mol-geo/shape/mesh.ts +++ b/src/mol-geo/shape/mesh.ts @@ -15,6 +15,8 @@ export interface Mesh { vertexCount: number, /** Number of triangles in the mesh */ triangleCount: number, + /** Number of offsets in the mesh */ + offsetCount: number, /** Vertex buffer as array of xyz values wrapped in a value cell */ vertexBuffer: ValueCell<Float32Array>, @@ -37,6 +39,26 @@ export interface Mesh { } export namespace Mesh { + export function createEmpty(mesh?: Mesh): Mesh { + const vb = mesh ? mesh.vertexBuffer.ref.value : new Float32Array(0) + const ib = mesh ? mesh.indexBuffer.ref.value : new Uint32Array(0) + const nb = mesh ? mesh.normalBuffer.ref.value : new Float32Array(0) + const idb = mesh ? mesh.idBuffer.ref.value : new Float32Array(0) + const ob = mesh ? mesh.offsetBuffer.ref.value : new Uint32Array(0) + return { + vertexCount: 0, + triangleCount: 0, + offsetCount: 0, + vertexBuffer: mesh ? ValueCell.update(mesh.vertexBuffer, vb) : ValueCell.create(vb), + indexBuffer: mesh ? ValueCell.update(mesh.indexBuffer, ib) : ValueCell.create(ib), + normalBuffer: mesh ? ValueCell.update(mesh.normalBuffer, nb) : ValueCell.create(nb), + idBuffer: mesh ? ValueCell.update(mesh.idBuffer, idb) : ValueCell.create(idb), + offsetBuffer: mesh ? ValueCell.update(mesh.offsetBuffer, ob) : ValueCell.create(ob), + normalsComputed: true, + offsetsComputed: true, + } + } + export function computeNormalsImmediate(surface: Mesh) { if (surface.normalsComputed) return; diff --git a/src/mol-geo/util/marching-cubes/algorithm.ts b/src/mol-geo/util/marching-cubes/algorithm.ts index 248f05397..4b2eaf964 100644 --- a/src/mol-geo/util/marching-cubes/algorithm.ts +++ b/src/mol-geo/util/marching-cubes/algorithm.ts @@ -76,6 +76,7 @@ class MarchingCubesComputation { 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(new Float32Array(0)), -- GitLab