|
@@ -0,0 +1,151 @@
|
|
|
+/**
|
|
|
+ * Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
|
|
+ *
|
|
|
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
|
|
|
+ */
|
|
|
+
|
|
|
+import './index.html'
|
|
|
+import { Canvas3D } from 'mol-canvas3d/canvas3d';
|
|
|
+import { Representation } from 'mol-repr/representation';
|
|
|
+import { Color } from 'mol-util/color';
|
|
|
+import { createRenderObject } from 'mol-gl/render-object';
|
|
|
+import { computeGaussianDensity, computeGaussianDensityTexture2d } from 'mol-math/geometry/gaussian-density';
|
|
|
+import { PositionData, Box3D, Sphere3D } from 'mol-math/geometry';
|
|
|
+import { OrderedSet } from 'mol-data/int';
|
|
|
+import { Vec3 } from 'mol-math/linear-algebra';
|
|
|
+import { computeMarchingCubesMesh } from 'mol-geo/util/marching-cubes/algorithm';
|
|
|
+import { Mesh } from 'mol-geo/geometry/mesh/mesh';
|
|
|
+import { ColorNames } from 'mol-util/color/tables';
|
|
|
+import { Isosurface } from 'mol-geo/geometry/isosurface/isosurface';
|
|
|
+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';
|
|
|
+
|
|
|
+const parent = document.getElementById('app')!
|
|
|
+parent.style.width = '100%'
|
|
|
+parent.style.height = '100%'
|
|
|
+
|
|
|
+const canvas = document.createElement('canvas')
|
|
|
+canvas.style.width = '100%'
|
|
|
+canvas.style.height = '100%'
|
|
|
+parent.appendChild(canvas)
|
|
|
+
|
|
|
+const canvas3d = Canvas3D.create(canvas, parent, {
|
|
|
+ backgroundColor: ColorNames.white,
|
|
|
+ cameraMode: 'orthographic'
|
|
|
+})
|
|
|
+canvas3d.animate()
|
|
|
+
|
|
|
+async function init() {
|
|
|
+ const { webgl } = canvas3d
|
|
|
+
|
|
|
+ const position: PositionData = {
|
|
|
+ x: [0, 2],
|
|
|
+ y: [0, 2],
|
|
|
+ z: [0, 2],
|
|
|
+ indices: OrderedSet.ofSortedArray([0, 1]),
|
|
|
+ }
|
|
|
+ const box = Box3D.create(Vec3.create(-1, -1, -1), Vec3.create(3, 3, 3))
|
|
|
+ // const position: PositionData = {
|
|
|
+ // x: [0],
|
|
|
+ // y: [0],
|
|
|
+ // z: [0],
|
|
|
+ // indices: OrderedSet.ofSortedArray([0]),
|
|
|
+ // }
|
|
|
+ // const box = Box3D.create(Vec3.create(-1, -1, -1), Vec3.create(1, 1, 1))
|
|
|
+ const radius = () => 1.6
|
|
|
+ const props = {
|
|
|
+ resolution: 0.1,
|
|
|
+ radiusOffset: 0,
|
|
|
+ smoothness: 1.5
|
|
|
+ }
|
|
|
+ const isoValue = Math.exp(-props.smoothness)
|
|
|
+
|
|
|
+ // console.log('bbox', densityTextureData.bbox)
|
|
|
+
|
|
|
+ // console.time('gpu gaussian2')
|
|
|
+ // const densityTextureData2 = await computeGaussianDensityTexture2d(position, box, radius, props, webgl).run()
|
|
|
+ // webgl.waitForGpuCommandsCompleteSync()
|
|
|
+ // console.timeEnd('gpu gaussian2')
|
|
|
+
|
|
|
+ // console.time('gpu mc2')
|
|
|
+ // console.time('gpu mc active2')
|
|
|
+ // const activeVoxelsTex2 = calcActiveVoxels(webgl, densityTextureData2.texture, densityTextureData2.gridDimension, isoValue)
|
|
|
+ // webgl.waitForGpuCommandsCompleteSync()
|
|
|
+ // console.timeEnd('gpu mc active2')
|
|
|
+
|
|
|
+ // console.time('gpu mc pyramid2')
|
|
|
+ // const compacted2 = createHistogramPyramid(webgl, activeVoxelsTex2)
|
|
|
+ // webgl.waitForGpuCommandsCompleteSync()
|
|
|
+ // console.timeEnd('gpu mc pyramid2')
|
|
|
+
|
|
|
+ // console.time('gpu mc vert2')
|
|
|
+ // const gv2 = createIsosurfaceBuffers(webgl, activeVoxelsTex2, densityTextureData2.texture, compacted2, densityTextureData2.gridDimension, densityTextureData2.transform, isoValue)
|
|
|
+ // webgl.waitForGpuCommandsCompleteSync()
|
|
|
+ // console.timeEnd('gpu mc vert2')
|
|
|
+ // console.timeEnd('gpu mc2')
|
|
|
+
|
|
|
+ console.time('gpu gaussian')
|
|
|
+ const densityTextureData = await computeGaussianDensityTexture2d(position, box, radius, props, webgl).run()
|
|
|
+ webgl.waitForGpuCommandsCompleteSync()
|
|
|
+ console.timeEnd('gpu gaussian')
|
|
|
+
|
|
|
+ console.time('gpu mc')
|
|
|
+ console.time('gpu mc active')
|
|
|
+ const activeVoxelsTex = calcActiveVoxels(webgl, densityTextureData.texture, densityTextureData.gridDimension, isoValue)
|
|
|
+ webgl.waitForGpuCommandsCompleteSync()
|
|
|
+ console.timeEnd('gpu mc active')
|
|
|
+
|
|
|
+ console.time('gpu mc pyramid')
|
|
|
+ const compacted = createHistogramPyramid(webgl, activeVoxelsTex)
|
|
|
+ webgl.waitForGpuCommandsCompleteSync()
|
|
|
+ console.timeEnd('gpu mc pyramid')
|
|
|
+
|
|
|
+ console.time('gpu mc vert')
|
|
|
+ const gv = createIsosurfaceBuffers(webgl, activeVoxelsTex, densityTextureData.texture, compacted, densityTextureData.gridDimension, densityTextureData.transform, isoValue)
|
|
|
+ webgl.waitForGpuCommandsCompleteSync()
|
|
|
+ console.timeEnd('gpu mc vert')
|
|
|
+ console.timeEnd('gpu mc')
|
|
|
+
|
|
|
+ console.log({ ...webgl.stats, programCount: webgl.programCache.count, shaderCount: webgl.shaderCache.count })
|
|
|
+
|
|
|
+ const mcIsosurface = Isosurface.create(gv.vertexCount, 1, gv.vertexTexture, gv.normalBuffer, gv.groupBuffer, Sphere3D.fromBox3D(Sphere3D.zero(), densityTextureData.bbox))
|
|
|
+ const mcIsoSurfaceProps = { doubleSided: true, flatShaded: true, alpha: 1.0 }
|
|
|
+ const mcIsoSurfaceValues = Isosurface.Utils.createValuesSimple(mcIsosurface, mcIsoSurfaceProps, Color(0x112299), 1)
|
|
|
+ // console.log('mcIsoSurfaceValues', mcIsoSurfaceValues)
|
|
|
+ const mcIsoSurfaceState = Isosurface.Utils.createRenderableState(mcIsoSurfaceProps)
|
|
|
+ const mcIsoSurfaceRenderObject = createRenderObject('isosurface', mcIsoSurfaceValues, mcIsoSurfaceState, -1)
|
|
|
+ const mcIsoSurfaceRepr = Representation.fromRenderObject('isosurface', mcIsoSurfaceRenderObject)
|
|
|
+
|
|
|
+ canvas3d.add(mcIsoSurfaceRepr)
|
|
|
+ canvas3d.resetCamera()
|
|
|
+
|
|
|
+ //
|
|
|
+
|
|
|
+ console.time('cpu gaussian')
|
|
|
+ const densityData = await computeGaussianDensity(position, box, radius, { ...props, useGpu: false }, webgl).run()
|
|
|
+ console.timeEnd('cpu gaussian')
|
|
|
+ // console.log({ densityData })
|
|
|
+
|
|
|
+ const params = {
|
|
|
+ isoLevel: isoValue,
|
|
|
+ scalarField: densityData.field,
|
|
|
+ idField: densityData.idField
|
|
|
+ }
|
|
|
+
|
|
|
+ console.time('cpu mc')
|
|
|
+ const surface = await computeMarchingCubesMesh(params).run()
|
|
|
+ console.timeEnd('cpu mc')
|
|
|
+ // console.log('surface', surface)
|
|
|
+ Mesh.computeNormalsImmediate(surface)
|
|
|
+ const meshProps = { doubleSided: true, flatShaded: true, alpha: 1.0 }
|
|
|
+ const meshValues = Mesh.Utils.createValuesSimple(surface, meshProps, Color(0x995511), 1)
|
|
|
+ const meshState = Mesh.Utils.createRenderableState(meshProps)
|
|
|
+ const meshRenderObject = createRenderObject('mesh', meshValues, meshState, -1)
|
|
|
+ const meshRepr = Representation.fromRenderObject('mesh', meshRenderObject)
|
|
|
+
|
|
|
+ canvas3d.add(meshRepr)
|
|
|
+ canvas3d.resetCamera()
|
|
|
+}
|
|
|
+
|
|
|
+init()
|