Bladeren bron

wip, gaussian unit surface texture-mesh

Alexander Rose 6 jaren geleden
bovenliggende
commit
d7ba4d88f7

+ 1 - 1
src/mol-geo/geometry/geometry.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>
  */

+ 1 - 1
src/mol-gl/compute/histogram-pyramid/reduction.ts

@@ -12,7 +12,7 @@ import { Texture, createTexture } from 'mol-gl/webgl/texture';
 import { ShaderCode } from 'mol-gl/shader-code';
 import { ValueCell } from 'mol-util';
 import { GLRenderingContext } from 'mol-gl/webgl/compat';
-import { printTexture, QuadSchema, QuadValues } from '../util';
+import { QuadSchema, QuadValues } from '../util';
 import { Vec2 } from 'mol-math/linear-algebra';
 import { getHistopyramidSum } from './sum';
 

+ 3 - 3
src/mol-gl/compute/marching-cubes/isosurface.ts

@@ -13,7 +13,7 @@ import { ShaderCode } from 'mol-gl/shader-code';
 import { ValueCell } from 'mol-util';
 import { GLRenderingContext } from 'mol-gl/webgl/compat';
 import { Vec3, Vec2, Mat4 } from 'mol-math/linear-algebra';
-import { QuadSchema, QuadValues, readTexture } from '../util';
+import { QuadSchema, QuadValues } from '../util';
 import { HistogramPyramid } from '../histogram-pyramid/reduction';
 import { getTriIndices } from './tables';
 
@@ -138,8 +138,8 @@ export function createIsosurfaceBuffers(ctx: WebGLContext, activeVoxelsBase: Tex
     pr.render()
     gl.disable(gl.SCISSOR_TEST)
 
-    const vgt = readTexture(ctx, vertexGroupTexture, pyramidTex.width, height)
-    console.log('vertexGroupTexture', vgt.array.subarray(0, 4 * count))
+    // const vgt = readTexture(ctx, vertexGroupTexture, pyramidTex.width, height)
+    // console.log('vertexGroupTexture', vgt.array.subarray(0, 4 * count))
 
     // const vt = readTexture(ctx, verticesTex, pyramidTex.width, height)
     // console.log('vt', vt)

+ 3 - 1
src/mol-gl/shader/marching-cubes/isosurface.frag

@@ -186,7 +186,7 @@ void main(void) {
 
     float t = (uIsoValue - v0) / (v0 - v1);
     // t = -0.5;
-    gl_FragColor.xyz = b0 + t * (b0 - b1);
+    gl_FragColor.xyz = (uGridTransform * vec4(b0 + t * (b0 - b1), 1.0)).xyz;
     gl_FragColor.w = decodeFloatRGB(d0.rgb); // group id
 
     // normals from gradients
@@ -201,4 +201,6 @@ void main(void) {
         v1 - voxel((b1 + c4) / uGridDim).a
     ));
     gl_FragData[1].xyz = -normalize((v0 * n0 + v1 * n1) / max(v0 + v1, EPS));
+    mat3 normalMatrix = transpose(inverse(mat3(uGridTransform)));
+    gl_FragData[1].xyz = normalMatrix * gl_FragData[1].xyz;
 }

+ 4 - 0
src/mol-repr/structure/representation.ts

@@ -15,6 +15,7 @@ import { Lines } from 'mol-geo/geometry/lines/lines';
 import { DirectVolume } from 'mol-geo/geometry/direct-volume/direct-volume';
 import { Spheres } from 'mol-geo/geometry/spheres/spheres';
 import { StructureUnitTransforms } from 'mol-model/structure/structure/util/unit-transforms';
+import { TextureMesh } from 'mol-geo/geometry/texture-mesh/texture-mesh';
 
 export interface StructureRepresentationState extends Representation.State {
     unitTransforms: StructureUnitTransforms | null
@@ -56,6 +57,9 @@ export type StructureLinesParams = typeof StructureLinesParams
 export const StructureDirectVolumeParams = { ...DirectVolume.Params, ...StructureParams }
 export type StructureDirectVolumeParams = typeof StructureDirectVolumeParams
 
+export const StructureTextureMeshParams = { ...TextureMesh.Params, ...StructureParams }
+export type StructureTextureMeshParams = typeof StructureTextureMeshParams
+
 export { ComplexRepresentation } from './complex-representation'
 export { UnitsRepresentation } from './units-representation'
 export { ComplexVisual } from './complex-visual'

+ 5 - 4
src/mol-repr/structure/representation/molecular-surface.ts

@@ -1,10 +1,10 @@
 /**
- * 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>
  */
 
-import { GaussianSurfaceVisual, GaussianSurfaceParams } from '../visual/gaussian-surface-mesh';
+import { GaussianSurfaceMeshVisual, GaussianSurfaceTextureMeshVisual, GaussianSurfaceParams } from '../visual/gaussian-surface-mesh';
 import { UnitsRepresentation } from '../units-representation';
 import { GaussianWireframeVisual, GaussianWireframeParams } from '../visual/gaussian-surface-wireframe';
 import { ParamDefinition as PD } from 'mol-util/param-definition';
@@ -14,7 +14,8 @@ import { ThemeRegistryContext } from 'mol-theme/theme';
 import { Structure } from 'mol-model/structure';
 
 const MolecularSurfaceVisuals = {
-    'gaussian-surface': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<Structure, GaussianSurfaceParams>) => UnitsRepresentation('Gaussian surface', ctx, getParams, GaussianSurfaceVisual),
+    'gaussian-surface-mesh': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<Structure, GaussianSurfaceParams>) => UnitsRepresentation('Gaussian surface', ctx, getParams, GaussianSurfaceMeshVisual),
+    'gaussian-surface-texture-mesh': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<Structure, GaussianSurfaceParams>) => UnitsRepresentation('Gaussian surface', ctx, getParams, GaussianSurfaceTextureMeshVisual),
     'gaussian-wireframe': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<Structure, GaussianWireframeParams>) => UnitsRepresentation('Gaussian wireframe', ctx, getParams, GaussianWireframeVisual),
 }
 type MolecularSurfaceVisualName = keyof typeof MolecularSurfaceVisuals
@@ -23,7 +24,7 @@ const MolecularSurfaceVisualOptions = Object.keys(MolecularSurfaceVisuals).map(n
 export const MolecularSurfaceParams = {
     ...GaussianSurfaceParams,
     ...GaussianWireframeParams,
-    visuals: PD.MultiSelect<MolecularSurfaceVisualName>(['gaussian-surface'], MolecularSurfaceVisualOptions),
+    visuals: PD.MultiSelect<MolecularSurfaceVisualName>(['gaussian-surface-mesh'], MolecularSurfaceVisualOptions),
 }
 export type MolecularSurfaceParams = typeof MolecularSurfaceParams
 export function getMolecularSurfaceParams(ctx: ThemeRegistryContext, structure: Structure) {

+ 20 - 2
src/mol-repr/structure/units-visual.ts

@@ -7,7 +7,7 @@
 import { Unit, Structure } from 'mol-model/structure';
 import { RepresentationProps } from '../representation';
 import { Visual, VisualContext } from '../visual';
-import { StructureMeshParams, StructurePointsParams, StructureLinesParams, StructureDirectVolumeParams, StructureSpheresParams } from './representation';
+import { StructureMeshParams, StructurePointsParams, StructureLinesParams, StructureDirectVolumeParams, StructureSpheresParams, StructureTextureMeshParams } from './representation';
 import { Loci, isEveryLoci, EmptyLoci } from 'mol-model/loci';
 import { GraphicsRenderObject, createRenderObject } from 'mol-gl/render-object';
 import { deepEqual, ValueCell } from 'mol-util';
@@ -33,6 +33,7 @@ import { Spheres } from 'mol-geo/geometry/spheres/spheres';
 import { createUnitsTransform, includesUnitKind } from './visual/util/common';
 import { Overpaint } from 'mol-theme/overpaint';
 import { Transparency } from 'mol-theme/transparency';
+import { TextureMesh } from 'mol-geo/geometry/texture-mesh/texture-mesh';
 
 export type StructureGroup = { structure: Structure, group: Unit.SymmetryGroup }
 
@@ -328,7 +329,7 @@ export function UnitsLinesVisual<P extends UnitsLinesParams>(builder: UnitsLines
 
 export const UnitsDirectVolumeParams = { ...StructureDirectVolumeParams, ...UnitsParams }
 export type UnitsDirectVolumeParams = typeof UnitsDirectVolumeParams
-export interface UnitsDirectVolumeVisualBuilder<P extends UnitsDirectVolumeParams> extends UnitsVisualGeometryBuilder<P, DirectVolume> { }
+export interface UnitsDirectVolumeVisualBuilder<P extends UnitsDirectVolumeParams> extends UnitsVisualBuilder<P, DirectVolume> { }
 
 export function UnitsDirectVolumeVisual<P extends UnitsDirectVolumeParams>(builder: UnitsDirectVolumeVisualBuilder<P>, materialId: number): UnitsVisual<P> {
     return UnitsVisual<DirectVolume, StructureDirectVolumeParams & UnitsParams>({
@@ -339,4 +340,21 @@ export function UnitsDirectVolumeVisual<P extends UnitsDirectVolumeParams>(build
         },
         geometryUtils: DirectVolume.Utils
     }, materialId)
+}
+
+// texture-mesh
+
+export const UnitsTextureMeshParams = { ...StructureTextureMeshParams, ...UnitsParams }
+export type UnitsTextureMeshParams = typeof UnitsTextureMeshParams
+export interface UnitsTextureMeshVisualBuilder<P extends UnitsTextureMeshParams> extends UnitsVisualBuilder<P, TextureMesh> { }
+
+export function UnitsTextureMeshVisual<P extends UnitsTextureMeshParams>(builder: UnitsTextureMeshVisualBuilder<P>, materialId: number): UnitsVisual<P> {
+    return UnitsVisual<TextureMesh, StructureTextureMeshParams & UnitsParams>({
+        ...builder,
+        setUpdateState: (state: VisualUpdateState, newProps: PD.Values<P>, currentProps: PD.Values<P>, newTheme: Theme, currentTheme: Theme) => {
+            builder.setUpdateState(state, newProps, currentProps, newTheme, currentTheme)
+            if (!SizeTheme.areEqual(newTheme.size, currentTheme.size)) state.createGeometry = true
+        },
+        geometryUtils: TextureMesh.Utils
+    }, materialId)
 }

+ 68 - 11
src/mol-repr/structure/visual/gaussian-surface-mesh.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>
  */
@@ -7,14 +7,33 @@
 import { Unit, Structure } from 'mol-model/structure';
 import { UnitsVisual } from '../representation';
 import { VisualUpdateState } from '../../util';
-import { UnitsMeshVisual, UnitsMeshParams } from '../units-visual';
+import { UnitsMeshVisual, UnitsMeshParams, UnitsTextureMeshParams, UnitsTextureMeshVisual } from '../units-visual';
 import { StructureElementIterator, getElementLoci, eachElement } from './util/element';
 import { ParamDefinition as PD } from 'mol-util/param-definition';
 import { Mesh } from 'mol-geo/geometry/mesh/mesh';
 import { computeMarchingCubesMesh } from 'mol-geo/util/marching-cubes/algorithm';
 import { VisualContext } from 'mol-repr/visual';
 import { Theme } from 'mol-theme/theme';
-import { GaussianDensityProps, computeUnitGaussianDensity, GaussianDensityParams } from './util/gaussian';
+import { GaussianDensityProps, computeUnitGaussianDensity, GaussianDensityParams, computeUnitGaussianDensityTexture2d, GaussianDensityTextureProps } from './util/gaussian';
+import { WebGLContext } from 'mol-gl/webgl/context';
+import { TextureMesh } from 'mol-geo/geometry/texture-mesh/texture-mesh';
+import { calcActiveVoxels } from 'mol-gl/compute/marching-cubes/active-voxels';
+import { createHistogramPyramid } from 'mol-gl/compute/histogram-pyramid/reduction';
+import { createIsosurfaceBuffers } from 'mol-gl/compute/marching-cubes/isosurface';
+import { Sphere3D } from 'mol-math/geometry';
+
+export const GaussianSurfaceParams = {
+    ...UnitsMeshParams,
+    ...UnitsTextureMeshParams,
+    ...GaussianDensityParams,
+}
+export type GaussianSurfaceParams = typeof GaussianSurfaceParams
+
+export function getGaussianSurfaceVisual(webgl?: WebGLContext) {
+    return webgl && webgl.extensions.drawBuffers ? GaussianSurfaceTextureMeshVisual : GaussianSurfaceMeshVisual
+}
+
+//
 
 async function createGaussianSurfaceMesh(ctx: VisualContext, unit: Unit, structure: Structure, theme: Theme, props: GaussianDensityProps, mesh?: Mesh): Promise<Mesh> {
     const { smoothness } = props
@@ -31,16 +50,10 @@ async function createGaussianSurfaceMesh(ctx: VisualContext, unit: Unit, structu
     Mesh.computeNormalsImmediate(surface)
     Mesh.uniformTriangleGroup(surface)
 
-    return surface;
+    return surface
 }
 
-export const GaussianSurfaceParams = {
-    ...UnitsMeshParams,
-    ...GaussianDensityParams,
-}
-export type GaussianSurfaceParams = typeof GaussianSurfaceParams
-
-export function GaussianSurfaceVisual(materialId: number): UnitsVisual<GaussianSurfaceParams> {
+export function GaussianSurfaceMeshVisual(materialId: number): UnitsVisual<GaussianSurfaceParams> {
     return UnitsMeshVisual<GaussianSurfaceParams>({
         defaultProps: PD.getDefaultValues(GaussianSurfaceParams),
         createGeometry: createGaussianSurfaceMesh,
@@ -54,4 +67,48 @@ export function GaussianSurfaceVisual(materialId: number): UnitsVisual<GaussianS
             if (newProps.useGpu !== currentProps.useGpu) state.createGeometry = true
         }
     }, materialId)
+}
+
+//
+
+async function createGaussianSurfaceTextureMesh(ctx: VisualContext, unit: Unit, structure: Structure, theme: Theme, props: GaussianDensityTextureProps, textureMesh?: TextureMesh): Promise<TextureMesh> {
+    if (!ctx.webgl) throw new Error('webgl context required to create gaussian surface texture-mesh')
+    const isoLevel = Math.exp(-props.smoothness)
+
+    const densityTextureData = await computeUnitGaussianDensityTexture2d(unit, props, ctx.webgl).runInContext(ctx.runtime)
+    // console.log(densityTextureData)
+    // console.log('vertexGroupTexture', readTexture(ctx.webgl, densityTextureData.texture))
+    // ctx.webgl.waitForGpuCommandsCompleteSync()
+
+    const activeVoxelsTex = calcActiveVoxels(ctx.webgl, densityTextureData.texture, densityTextureData.gridDimension, isoLevel)
+    // ctx.webgl.waitForGpuCommandsCompleteSync()
+
+    const compacted = createHistogramPyramid(ctx.webgl, activeVoxelsTex)
+    // ctx.webgl.waitForGpuCommandsCompleteSync()
+
+    const gv = createIsosurfaceBuffers(ctx.webgl, activeVoxelsTex, densityTextureData.texture, compacted, densityTextureData.gridDimension, densityTextureData.transform, isoLevel)
+    // ctx.webgl.waitForGpuCommandsCompleteSync()
+
+    // const boundingSphere = Sphere3D.zero()
+    // Sphere3D.addVec3(boundingSphere, boundingSphere, densityTextureData.gridDimension)
+    const boundingSphere = Sphere3D.fromBox3D(Sphere3D(), densityTextureData.bbox)
+    const surface = TextureMesh.create(gv.vertexCount, 1, gv.vertexGroupTexture, gv.normalTexture, boundingSphere, textureMesh)
+
+    // ctx.webgl.waitForGpuCommandsCompleteSync()
+    return surface
+}
+
+export function GaussianSurfaceTextureMeshVisual(materialId: number): UnitsVisual<GaussianSurfaceParams> {
+    return UnitsTextureMeshVisual<GaussianSurfaceParams>({
+        defaultProps: PD.getDefaultValues(GaussianSurfaceParams),
+        createGeometry: createGaussianSurfaceTextureMesh,
+        createLocationIterator: StructureElementIterator.fromGroup,
+        getLoci: getElementLoci,
+        eachLocation: eachElement,
+        setUpdateState: (state: VisualUpdateState, newProps: PD.Values<GaussianSurfaceParams>, currentProps: PD.Values<GaussianSurfaceParams>) => {
+            if (newProps.resolution !== currentProps.resolution) state.createGeometry = true
+            if (newProps.radiusOffset !== currentProps.radiusOffset) state.createGeometry = true
+            if (newProps.smoothness !== currentProps.smoothness) state.createGeometry = true
+        }
+    }, materialId)
 }

+ 9 - 2
src/mol-repr/structure/visual/util/gaussian.ts

@@ -8,7 +8,7 @@ import { Unit, StructureElement, ElementIndex, Structure } from 'mol-model/struc
 import { GaussianDensity } from 'mol-math/geometry/gaussian-density';
 import { Task } from 'mol-task';
 import { ParamDefinition as PD } from 'mol-util/param-definition';
-import { GaussianDensityTexture } from 'mol-math/geometry/gaussian-density/gpu';
+import { GaussianDensityTexture, GaussianDensityTexture2d } from 'mol-math/geometry/gaussian-density/gpu';
 import { Texture } from 'mol-gl/webgl/texture';
 import { WebGLContext } from 'mol-gl/webgl/context';
 import { PhysicalSizeTheme } from 'mol-theme/size/physical';
@@ -68,13 +68,20 @@ export function computeUnitGaussianDensity(unit: Unit, props: GaussianDensityPro
     });
 }
 
-export function computeUnitGaussianDensityTexture(unit: Unit, props: GaussianDensityProps, webgl: WebGLContext, texture?: Texture) {
+export function computeUnitGaussianDensityTexture(unit: Unit, props: GaussianDensityTextureProps, webgl: WebGLContext, texture?: Texture) {
     const { position, radius } = getUnitConformationAndRadius(unit)
     return Task.create('Gaussian Density', async ctx => {
         return await GaussianDensityTexture(ctx, webgl, position, unit.lookup3d.boundary.box, radius, props, texture);
     });
 }
 
+export function computeUnitGaussianDensityTexture2d(unit: Unit, props: GaussianDensityTextureProps, webgl: WebGLContext, texture?: Texture) {
+    const { position, radius } = getUnitConformationAndRadius(unit)
+    return Task.create('Gaussian Density', async ctx => {
+        return await GaussianDensityTexture2d(ctx, webgl, position, unit.lookup3d.boundary.box, radius, props, texture);
+    });
+}
+
 //
 
 function getStructureConformationAndRadius(structure: Structure) {