Browse Source

fixed gaussian surface update (todo, normals broken)

Alexander Rose 6 years ago
parent
commit
0447ec6cb3

+ 2 - 2
src/mol-geo/mesh/mesh.ts

@@ -37,14 +37,14 @@ export namespace 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.groupBuffer.ref.value : new Float32Array(0)
+        const gb = mesh ? mesh.groupBuffer.ref.value : new Float32Array(0)
         return {
             vertexCount: 0,
             triangleCount: 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),
-            groupBuffer: mesh ? ValueCell.update(mesh.groupBuffer, idb) : ValueCell.create(idb),
+            groupBuffer: mesh ? ValueCell.update(mesh.groupBuffer, gb) : ValueCell.create(gb),
             normalsComputed: true,
         }
     }

+ 21 - 14
src/mol-geo/representation/structure/visual/gaussian-surface-mesh.ts

@@ -4,7 +4,7 @@
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
 
-import { Unit, Structure } from 'mol-model/structure';
+import { Unit, Structure, StructureElement } from 'mol-model/structure';
 import { UnitsVisual, MeshUpdateState } from '..';
 import { RuntimeContext } from 'mol-task'
 import { Mesh } from '../../../mesh/mesh';
@@ -15,9 +15,10 @@ import { Tensor, Vec3, Mat4 } from 'mol-math/linear-algebra';
 import { Box3D } from 'mol-math/geometry';
 import { ValueCell } from 'mol-util';
 import { smoothstep } from 'mol-math/interpolate';
+import { LocationIterator } from '../../../util/location-iterator';
 
 export interface GaussianSurfaceMeshProps {
-    
+
 }
 
 function getDelta(box: Box3D) {
@@ -94,8 +95,8 @@ async function createGaussianSurfaceMesh(ctx: RuntimeContext, unit: Unit, struct
                         const density = 1.0 - smoothstep(0.0, radius * 1.0, dist)
                         space.set(data, x, y, z, space.get(data, x, y, z) + density)
                     }
-                } 
-            }   
+                }
+            }
         }
 
         if (i % 10000 === 0 && ctx.shouldUpdate) {
@@ -109,22 +110,15 @@ async function createGaussianSurfaceMesh(ctx: RuntimeContext, unit: Unit, struct
         isoLevel: 0.1,
         scalarField: field,
         oldSurface: mesh
-        
+
     }).runAsChild(ctx);
 
     const t = Mat4.identity()
     Mat4.fromUniformScaling(t, 1 / delta[0])
     Mat4.setTranslation(t, expandedBox.min)
 
-    ValueCell.update(surface.groupBuffer, new Float32Array(surface.vertexCount)) 
     Mesh.transformImmediate(surface, t)
-    await Mesh.computeNormals(surface).runAsChild(ctx)
-
-    // console.log('surface', surface)
-
-    // const transform = VolumeData.getGridToCartesianTransform(volume);
-    // ctx.update({ message: 'Transforming mesh...' });
-    // Mesh.transformImmediate(surface, transform);
+    Mesh.computeNormalsImmediate(surface)
 
     return surface;
 }
@@ -150,4 +144,17 @@ export function GaussianSurfaceVisual(): UnitsVisual<GaussianSurfaceProps> {
         mark: markElement,
         setUpdateState: (state: MeshUpdateState, newProps: GaussianSurfaceProps, currentProps: GaussianSurfaceProps) => {}
     })
-}
+}
+
+// function SingleGroupLocationIterator(group: Unit.SymmetryGroup): LocationIterator {
+//     const groupCount = 1
+//         const instanceCount = group.units.length
+//         const location = StructureElement.create()
+//         const getLocation = (groupIndex: number, instanceIndex: number) => {
+//             const unit = group.units[instanceIndex]
+//             location.unit = unit
+//             location.element = unit.elements[groupIndex]
+//             return location
+//         }
+//         return LocationIterator(groupCount, instanceCount, getLocation)
+// }

+ 17 - 16
src/mol-geo/util/marching-cubes/algorithm.ts

@@ -67,6 +67,7 @@ class MarchingCubesComputation {
     private finish() {
         const vb = ChunkedArray.compact(this.state.vertexBuffer, true) as Float32Array;
         const ib = ChunkedArray.compact(this.state.triangleBuffer, true) as Uint32Array;
+        const gb = ChunkedArray.compact(this.state.groupBuffer, true) as Float32Array;
 
         this.state.vertexBuffer = <any>void 0;
         this.state.verticesOnEdges = <any>void 0;
@@ -77,13 +78,9 @@ class MarchingCubesComputation {
             vertexCount:  this.state.vertexCount,
             triangleCount: this.state.triangleCount,
             vertexBuffer: os ? ValueCell.update(os.vertexBuffer, vb) : ValueCell.create(vb),
+            groupBuffer: os ? ValueCell.update(os.groupBuffer, gb) : ValueCell.create(gb),
             indexBuffer: os ? ValueCell.update(os.indexBuffer, ib) : ValueCell.create(ib),
             normalBuffer: os ? os.normalBuffer : ValueCell.create(new Float32Array(0)),
-            groupBuffer: this.state.assignIds
-                ? os && os.groupBuffer
-                    ? ValueCell.update(os.groupBuffer, ChunkedArray.compact(this.state.idBuffer) as Float32Array)
-                    : ValueCell.create(ChunkedArray.compact(this.state.idBuffer) as Float32Array)
-                : ValueCell.create(new Float32Array(0)),
             normalsComputed: false
         }
 
@@ -131,7 +128,7 @@ class MarchingCubesState {
     i: number = 0; j: number = 0; k: number = 0;
 
     vertexBuffer: ChunkedArray<number, 3>;
-    idBuffer: ChunkedArray<number, 1>;
+    groupBuffer: ChunkedArray<number, 1>;
     triangleBuffer: ChunkedArray<number, 3>;
     vertexCount = 0;
     triangleCount = 0;
@@ -173,12 +170,14 @@ class MarchingCubesState {
 
         this.verticesOnEdges[edgeId] = id + 1;
 
-        if (this.assignIds) {
-            const u = this.idFieldGet!(this.idField!, li, lj, lk);
-            const v = this.idFieldGet!(this.idField!, hi, hj, hk)
+        if (this.idField) {
+            const u = this.idFieldGet!(this.idField, li, lj, lk);
+            const v = this.idFieldGet!(this.idField, hi, hj, hk)
             let a = t < 0.5 ? u : v;
             if (a < 0) a = t < 0.5 ? v : u;
-            ChunkedArray.add(this.idBuffer, a);
+            ChunkedArray.add(this.groupBuffer, a);
+        } else {
+            ChunkedArray.add(this.groupBuffer, 0);
         }
 
         this.vertexCount++;
@@ -197,18 +196,20 @@ class MarchingCubesState {
             this.idFieldGet = params.idField.space.get;
         }
 
-        let dX = params.topRight![0] - params.bottomLeft![0], dY = params.topRight![1] - params.bottomLeft![1], dZ = params.topRight![2] - params.bottomLeft![2],
-            vertexBufferSize = Math.min(262144, Math.max(dX * dY * dZ / 16, 1024) | 0),
-            triangleBufferSize = Math.min(1 << 16, vertexBufferSize * 4);
+        const dX = params.topRight![0] - params.bottomLeft![0]
+        const dY = params.topRight![1] - params.bottomLeft![1]
+        const dZ = params.topRight![2] - params.bottomLeft![2]
+        // TODO should it be configurable? Scalar fields can produce meshes with vastly different densities.
+        const vertexBufferSize = Math.min(262144, Math.max(dX * dY * dZ / 32, 1024) | 0)
+        const triangleBufferSize = Math.min(1 << 16, vertexBufferSize * 4)
 
         this.vertexBuffer = ChunkedArray.create(Float32Array, 3, vertexBufferSize,
             params.oldSurface && params.oldSurface.vertexBuffer.ref.value);
+        this.groupBuffer = ChunkedArray.create(Float32Array, 1, vertexBufferSize,
+            params.oldSurface && params.oldSurface.groupBuffer.ref.value);
         this.triangleBuffer = ChunkedArray.create(Uint32Array, 3, triangleBufferSize,
             params.oldSurface && params.oldSurface.indexBuffer.ref.value);
 
-        this.assignIds = !!params.idField;
-        if (this.assignIds) this.idBuffer = ChunkedArray.create(Int32Array, 1, vertexBufferSize);
-
         // two layers of vertex indices. Each vertex has 3 edges associated.
         this.verticesOnEdges = new Int32Array(3 * this.nX * this.nY * 2);
     }