/** * 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()