Skip to content
Snippets Groups Projects
Commit 2ad23d6c authored by Alexander Rose's avatar Alexander Rose
Browse files

refactored spacefill creation a bit

parent e5ef4cc7
No related branches found
No related tags found
No related merge requests found
...@@ -8,15 +8,11 @@ ...@@ -8,15 +8,11 @@
import { ValueCell } from 'mol-util/value-cell' import { ValueCell } from 'mol-util/value-cell'
import { RenderObject, createMeshRenderObject, MeshRenderObject } from 'mol-gl/render-object' 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 { Unit, Element, Queries } from 'mol-model/structure';
import { UnitsRepresentation, DefaultStructureProps } from './index'; import { UnitsRepresentation, DefaultStructureProps } from './index';
import { Task } from 'mol-task' import { Task } from 'mol-task'
import { MeshBuilder } from '../../shape/mesh-builder'; import { createTransforms, createColors, createFlags, createEmptyFlags, createSphereMesh } from './utils';
import { createTransforms, createColors, createFlags, createEmptyFlags } from './utils';
import VertexMap from '../../shape/vertex-map'; import VertexMap from '../../shape/vertex-map';
import { icosahedronVertexCount } from '../../primitive/icosahedron';
import { deepEqual, defaults } from 'mol-util'; import { deepEqual, defaults } from 'mol-util';
import { fillSerial } from 'mol-gl/renderable/util'; import { fillSerial } from 'mol-gl/renderable/util';
import { RenderableState, MeshValues } from 'mol-gl/renderable'; import { RenderableState, MeshValues } from 'mol-gl/renderable';
...@@ -24,6 +20,19 @@ import { getMeshData } from '../../util/mesh-data'; ...@@ -24,6 +20,19 @@ import { getMeshData } from '../../util/mesh-data';
import { Mesh } from '../../shape/mesh'; import { Mesh } from '../../shape/mesh';
import { PickingId } from '../../util/picking'; 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 = { export const DefaultSpacefillProps = {
...DefaultStructureProps, ...DefaultStructureProps,
flipSided: false, flipSided: false,
...@@ -32,49 +41,6 @@ export const DefaultSpacefillProps = { ...@@ -32,49 +41,6 @@ export const DefaultSpacefillProps = {
} }
export type SpacefillProps = Partial<typeof 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> { export default function Spacefill(): UnitsRepresentation<SpacefillProps> {
const renderObjects: RenderObject[] = [] const renderObjects: RenderObject[] = []
let spheres: MeshRenderObject let spheres: MeshRenderObject
......
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
* @author David Sehnal <david.sehnal@gmail.com> * @author David Sehnal <david.sehnal@gmail.com>
*/ */
import { Unit } from 'mol-model/structure'; import { Unit, Element } from 'mol-model/structure';
import { Mat4, Vec2 } from 'mol-math/linear-algebra' import { Mat4, Vec2, Vec3 } from 'mol-math/linear-algebra'
import { createUniformColor, ColorData } from '../../util/color-data'; import { createUniformColor, ColorData } from '../../util/color-data';
import { createUniformSize } from '../../util/size-data'; import { createUniformSize } from '../../util/size-data';
...@@ -16,6 +16,10 @@ import { ColorTheme, SizeTheme } from '../../theme'; ...@@ -16,6 +16,10 @@ import { ColorTheme, SizeTheme } from '../../theme';
import { elementIndexColorData, elementSymbolColorData, instanceIndexColorData, chainIdColorData } from '../../theme/structure/color'; import { elementIndexColorData, elementSymbolColorData, instanceIndexColorData, chainIdColorData } from '../../theme/structure/color';
import { ValueCell } from 'mol-util'; import { ValueCell } from 'mol-util';
import { TextureImage, createTextureImage } from 'mol-gl/renderable/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>) { export function createTransforms({ units }: Unit.SymmetryGroup, transforms?: ValueCell<Float32Array>) {
const unitCount = units.length const unitCount = units.length
...@@ -93,4 +97,37 @@ export function createEmptyFlags(flagData?: FlagData) { ...@@ -93,4 +97,37 @@ export function createEmptyFlags(flagData?: FlagData) {
uFlagTexSize: ValueCell.create(Vec2.create(1, 1)), 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()
})
}
...@@ -15,6 +15,8 @@ export interface Mesh { ...@@ -15,6 +15,8 @@ export interface Mesh {
vertexCount: number, vertexCount: number,
/** Number of triangles in the mesh */ /** Number of triangles in the mesh */
triangleCount: number, triangleCount: number,
/** Number of offsets in the mesh */
offsetCount: number,
/** Vertex buffer as array of xyz values wrapped in a value cell */ /** Vertex buffer as array of xyz values wrapped in a value cell */
vertexBuffer: ValueCell<Float32Array>, vertexBuffer: ValueCell<Float32Array>,
...@@ -37,6 +39,26 @@ export interface Mesh { ...@@ -37,6 +39,26 @@ export interface Mesh {
} }
export namespace 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) { export function computeNormalsImmediate(surface: Mesh) {
if (surface.normalsComputed) return; if (surface.normalsComputed) return;
......
...@@ -76,6 +76,7 @@ class MarchingCubesComputation { ...@@ -76,6 +76,7 @@ class MarchingCubesComputation {
const ret: Mesh = { const ret: Mesh = {
vertexCount: this.state.vertexCount, vertexCount: this.state.vertexCount,
triangleCount: this.state.triangleCount, triangleCount: this.state.triangleCount,
offsetCount: 0,
vertexBuffer: os ? ValueCell.update(os.vertexBuffer, vb) : ValueCell.create(vb), vertexBuffer: os ? ValueCell.update(os.vertexBuffer, vb) : ValueCell.create(vb),
indexBuffer: os ? ValueCell.update(os.indexBuffer, ib) : ValueCell.create(ib), indexBuffer: os ? ValueCell.update(os.indexBuffer, ib) : ValueCell.create(ib),
normalBuffer: os ? os.normalBuffer : ValueCell.create(new Float32Array(0)), normalBuffer: os ? os.normalBuffer : ValueCell.create(new Float32Array(0)),
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment