Browse Source

normals calc in cpu mc

Alexander Rose 6 years ago
parent
commit
431f1ffee8

+ 25 - 5
src/mol-geo/util/marching-cubes/algorithm.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 David Sehnal <david.sehnal@gmail.com>
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
@@ -12,7 +12,6 @@ import { Index, EdgeIdInfo, CubeEdges, EdgeTable, TriTable } from './tables'
 import { defaults } from 'mol-util'
 import { MarchinCubesBuilder, MarchinCubesMeshBuilder, MarchinCubesLinesBuilder } from './builder';
 import { Lines } from '../../geometry/lines/lines';
-// import { Lines } from '../../geometry/lines/lines';
 
 /**
  * The parameters required by the algorithm.
@@ -156,17 +155,38 @@ class MarchingCubesState {
         const ret = this.verticesOnEdges[edgeId];
         if (ret > 0) return ret - 1;
 
+        const sf = this.scalarField
+        const sfg = this.scalarFieldGet
+
         const edge = CubeEdges[edgeNum];
         const a = edge.a, b = edge.b;
         const li = a.i + this.i, lj = a.j + this.j, lk = a.k + this.k;
         const hi = b.i + this.i, hj = b.j + this.j, hk = b.k + this.k;
-        const v0 = this.scalarFieldGet(this.scalarField, li, lj, lk);
-        const v1 = this.scalarFieldGet(this.scalarField, hi, hj, hk);
+        const v0 = sfg(sf, li, lj, lk);
+        const v1 = sfg(sf, hi, hj, hk);
         const t = (this.isoLevel - v0) / (v0 - v1);
 
-        const id = this.builder.addVertex(li + t * (li - hi), lj + t * (lj - hj), lk + t * (lk - hk));
+        const id = this.builder.addVertex(
+            li + t * (li - hi),
+            lj + t * (lj - hj),
+            lk + t * (lk - hk)
+        );
         this.verticesOnEdges[edgeId] = id + 1;
 
+        const n0x = sfg(sf, Math.max(0, li - 1), lj, lk) - sfg(sf, Math.min(this.nX - 1, li + 1), lj, lk)
+        const n0y = sfg(sf, li, Math.max(0, lj - 1), lk) - sfg(sf, li, Math.min(this.nY - 1, lj + 1), lk)
+        const n0z = sfg(sf, li, lj, Math.max(0, lk - 1)) - sfg(sf, li, lj, Math.min(this.nZ, lk + 1))
+
+        const n1x = sfg(sf, Math.max(0, hi - 1), hj, hk) - sfg(sf, Math.min(this.nX - 1, hi + 1), hj, hk)
+        const n1y = sfg(sf, hi, Math.max(0, hj - 1), hk) - sfg(sf, hi, Math.min(this.nY - 1, hj + 1), hk)
+        const n1z = sfg(sf, hi, hj, Math.max(0, hk - 1)) - sfg(sf, hi, hj, Math.min(this.nZ - 1, hk + 1))
+
+        this.builder.addNormal(
+            n0x + t * (n0x - n1x),
+            n0y + t * (n0y - n1y),
+            n0z + t * (n0z - n1z)
+        )
+
         if (this.idField) {
             const u = this.idFieldGet!(this.idField, li, lj, lk);
             const v = this.idFieldGet!(this.idField, hi, hj, hk)

+ 10 - 3
src/mol-geo/util/marching-cubes/builder.ts

@@ -7,7 +7,7 @@
  */
 
 import { ChunkedArray } from '../../../mol-data/util';
-import { ValueCell } from 'mol-util';
+import { ValueCell, noop } from 'mol-util';
 import { Mesh } from '../../geometry/mesh/mesh';
 import { AllowedContours } from './tables';
 import { LinesBuilder } from '../../geometry/lines/lines-builder';
@@ -15,6 +15,7 @@ import { Lines } from '../../geometry/lines/lines';
 
  export interface MarchinCubesBuilder<T> {
     addVertex(x: number, y: number, z: number): number
+    addNormal(x: number, y: number, z: number): void
     addGroup(group: number): void
     addTriangle(vertList: number[], a: number, b: number, c: number, edgeFilter: number): void
     get(): T
@@ -24,6 +25,7 @@ export function MarchinCubesMeshBuilder(vertexChunkSize: number, mesh?: Mesh): M
     const triangleChunkSize = Math.min(1 << 16, vertexChunkSize * 4)
 
     const vertices = ChunkedArray.create(Float32Array, 3, vertexChunkSize, mesh && mesh.vertexBuffer.ref.value);
+    const normals = ChunkedArray.create(Float32Array, 3, vertexChunkSize, mesh && mesh.normalBuffer.ref.value);
     const groups = ChunkedArray.create(Float32Array, 1, vertexChunkSize, mesh && mesh.groupBuffer.ref.value);
     const indices = ChunkedArray.create(Uint32Array, 3, triangleChunkSize, mesh && mesh.indexBuffer.ref.value);
 
@@ -35,6 +37,9 @@ export function MarchinCubesMeshBuilder(vertexChunkSize: number, mesh?: Mesh): M
             ++vertexCount
             return ChunkedArray.add3(vertices, x, y, z );
         },
+        addNormal: (x: number, y: number, z: number) => {
+            ChunkedArray.add3(normals, x, y, z );
+        },
         addGroup: (group: number) => {
             ChunkedArray.add(groups, group);
         },
@@ -44,6 +49,7 @@ export function MarchinCubesMeshBuilder(vertexChunkSize: number, mesh?: Mesh): M
         },
         get: () => {
             const vb = ChunkedArray.compact(vertices, true) as Float32Array;
+            const nb = ChunkedArray.compact(normals, true) as Float32Array;
             const ib = ChunkedArray.compact(indices, true) as Uint32Array;
             const gb = ChunkedArray.compact(groups, true) as Float32Array;
 
@@ -54,8 +60,8 @@ export function MarchinCubesMeshBuilder(vertexChunkSize: number, mesh?: Mesh): M
                 vertexBuffer: mesh ? ValueCell.update(mesh.vertexBuffer, vb) : ValueCell.create(vb),
                 groupBuffer: mesh ? ValueCell.update(mesh.groupBuffer, gb) : ValueCell.create(gb),
                 indexBuffer: mesh ? ValueCell.update(mesh.indexBuffer, ib) : ValueCell.create(ib),
-                normalBuffer: mesh ? mesh.normalBuffer : ValueCell.create(new Float32Array(0)),
-                normalsComputed: false
+                normalBuffer: mesh ? ValueCell.update(mesh.normalBuffer, nb) : ValueCell.create(nb),
+                normalsComputed: true
             }
         }
     }
@@ -72,6 +78,7 @@ export function MarchinCubesLinesBuilder(vertexChunkSize: number, lines?: Lines)
         addVertex: (x: number, y: number, z: number) => {
             return ChunkedArray.add3(vertices, x, y, z);
         },
+        addNormal: () => noop,
         addGroup: (group: number) => {
             ChunkedArray.add(groups, group);
         },

+ 0 - 1
src/mol-repr/structure/visual/gaussian-surface-mesh.ts

@@ -47,7 +47,6 @@ async function createGaussianSurfaceMesh(ctx: VisualContext, unit: Unit, structu
     const surface = await computeMarchingCubesMesh(params, mesh).runAsChild(ctx.runtime)
 
     Mesh.transformImmediate(surface, transform)
-    Mesh.computeNormalsImmediate(surface)
     Mesh.uniformTriangleGroup(surface)
 
     return surface

+ 0 - 1
src/mol-repr/structure/visual/molecular-surface-mesh.ts

@@ -37,7 +37,6 @@ async function createMolecularSurfaceMesh(ctx: VisualContext, unit: Unit, struct
     const surface = await computeMarchingCubesMesh(params, mesh).runAsChild(ctx.runtime)
 
     Mesh.transformImmediate(surface, transform)
-    Mesh.computeNormalsImmediate(surface)
     Mesh.uniformTriangleGroup(surface)
 
     return surface

+ 0 - 1
src/mol-repr/volume/isosurface.ts

@@ -78,7 +78,6 @@ export async function createVolumeIsosurfaceMesh(ctx: VisualContext, volume: Vol
     const transform = VolumeData.getGridToCartesianTransform(volume);
     ctx.runtime.update({ message: 'Transforming mesh...' });
     Mesh.transformImmediate(surface, transform);
-    Mesh.computeNormalsImmediate(surface)
 
     return surface;
 }