Prechádzať zdrojové kódy

Merge pull request #199 from molstar/original-mesh-data

Better handling of processed meshes
Alexander Rose 3 rokov pred
rodič
commit
976a469cc7

+ 14 - 4
src/extensions/geo-export/mesh-exporter.ts

@@ -133,12 +133,22 @@ export abstract class MeshExporter<D extends RenderObjectExportData> implements
     private async addMesh(values: MeshValues, webgl: WebGLContext, ctx: RuntimeContext) {
         const aPosition = values.aPosition.ref.value;
         const aNormal = values.aNormal.ref.value;
-        const elements = values.elements.ref.value;
         const aGroup = values.aGroup.ref.value;
-        const vertexCount = values.uVertexCount.ref.value;
-        const drawCount = values.drawCount.ref.value;
+        const originalData = Mesh.getOriginalData(values);
+        let indices: Uint32Array;
+        let vertexCount: number;
+        let drawCount: number;
+        if (originalData) {
+            indices = originalData.indexBuffer;
+            vertexCount = originalData.vertexCount;
+            drawCount = originalData.triangleCount * 3;
+        } else {
+            indices = values.elements.ref.value;
+            vertexCount = values.uVertexCount.ref.value;
+            drawCount = values.drawCount.ref.value;
+        }
 
-        await this.addMeshWithColors({ mesh: { vertices: aPosition, normals: aNormal, indices: elements, groups: aGroup, vertexCount, drawCount }, meshes: undefined, values, isGeoTexture: false, webgl, ctx });
+        await this.addMeshWithColors({ mesh: { vertices: aPosition, normals: aNormal, indices, groups: aGroup, vertexCount, drawCount }, meshes: undefined, values, isGeoTexture: false, webgl, ctx });
     }
 
     private async addLines(values: LinesValues, webgl: WebGLContext, ctx: RuntimeContext) {

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

@@ -50,7 +50,7 @@ export interface Mesh {
 
     setBoundingSphere(boundingSphere: Sphere3D): void
 
-    meta?: unknown
+    readonly meta: { [k: string]: unknown }
 }
 
 export namespace Mesh {
@@ -111,7 +111,8 @@ export namespace Mesh {
             setBoundingSphere(sphere: Sphere3D) {
                 Sphere3D.copy(boundingSphere, sphere);
                 currentHash = hashCode(mesh);
-            }
+            },
+            meta: {}
         };
         return mesh;
     }
@@ -176,6 +177,18 @@ export namespace Mesh {
         ValueCell.update(mesh.vertexBuffer, v);
     }
 
+    export type OriginalData = {
+        indexBuffer: Uint32Array
+        vertexCount: number
+        triangleCount: number
+    }
+
+    /** Meshes may contain some original data in case any processing was done. */
+    export function getOriginalData(x: Mesh | MeshValues) {
+        const { originalData } = 'kind' in x ? x.meta : x.meta.ref.value as Mesh['meta'];
+        return originalData as OriginalData | undefined;
+    }
+
     /**
      * Ensure that each vertices of each triangle have the same group id.
      * Note that normals are copied over and can't be re-created from the new mesh.
@@ -324,6 +337,9 @@ export namespace Mesh {
         ValueCell.update(indexBuffer, newIb) as ValueCell<Uint32Array>;
         ValueCell.update(normalBuffer, newNb) as ValueCell<Float32Array>;
 
+        // keep some original data, e.g., for geometry export
+        (mesh.meta.originalData as OriginalData) = { indexBuffer: ib, vertexCount, triangleCount };
+
         return mesh;
     }
 
@@ -408,6 +424,8 @@ export namespace Mesh {
             dFlipSided: ValueCell.create(props.flipSided),
             dIgnoreLight: ValueCell.create(props.ignoreLight),
             dXrayShaded: ValueCell.create(props.xrayShaded),
+
+            meta: ValueCell.create(mesh.meta),
         };
     }
 

+ 2 - 1
src/mol-gl/renderable/mesh.ts

@@ -7,7 +7,7 @@
 import { Renderable, RenderableState, createRenderable } from '../renderable';
 import { WebGLContext } from '../webgl/context';
 import { createGraphicsRenderItem } from '../webgl/render-item';
-import { GlobalUniformSchema, BaseSchema, AttributeSpec, ElementsSpec, DefineSpec, Values, InternalSchema, InternalValues, GlobalTextureSchema } from './schema';
+import { GlobalUniformSchema, BaseSchema, AttributeSpec, ElementsSpec, DefineSpec, Values, InternalSchema, InternalValues, GlobalTextureSchema, ValueSpec } from './schema';
 import { MeshShaderCode } from '../shader-code';
 import { ValueCell } from '../../mol-util';
 
@@ -22,6 +22,7 @@ export const MeshSchema = {
     dFlipSided: DefineSpec('boolean'),
     dIgnoreLight: DefineSpec('boolean'),
     dXrayShaded: DefineSpec('boolean'),
+    meta: ValueSpec('unknown')
 } as const;
 export type MeshSchema = typeof MeshSchema
 export type MeshValues = Values<MeshSchema>

+ 1 - 0
src/mol-gl/renderable/schema.ts

@@ -17,6 +17,7 @@ export type ValueKindType = {
     'string': string
     'boolean': boolean
     'any': any
+    'unknown': unknown
 
     'm4': Mat4,
     'float32': Float32Array

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

@@ -93,10 +93,10 @@ async function createGaussianSurfaceMesh(ctx: VisualContext, unit: Unit, structu
         idField
     };
     const surface = await computeMarchingCubesMesh(params, mesh).runAsChild(ctx.runtime);
-    (surface.meta as GaussianSurfaceMeta) = { resolution };
+    (surface.meta.resolution as GaussianSurfaceMeta['resolution']) = resolution;
 
     Mesh.transform(surface, transform);
-    if (ctx.webgl && !ctx.webgl.isWebGL2) Mesh.uniformTriangleGroup(surface, false);
+    if (ctx.webgl && !ctx.webgl.isWebGL2) Mesh.uniformTriangleGroup(surface);
 
     const sphere = Sphere3D.expand(Sphere3D(), unit.boundary.sphere, props.radiusOffset + getUnitExtraRadius(unit));
     surface.setBoundingSphere(sphere);
@@ -133,7 +133,7 @@ export function GaussianSurfaceMeshVisual(materialId: number): UnitsVisual<Gauss
             const csp = getColorSmoothingProps(props, theme, resolution, webgl);
             if (csp) {
                 applyMeshColorSmoothing(values, csp.resolution, csp.stride, csp.webgl, colorTexture);
-                (geometry.meta as GaussianSurfaceMeta).colorTexture = values.tColorGrid.ref.value;
+                (geometry.meta.colorTexture as GaussianSurfaceMeta['colorTexture']) = values.tColorGrid.ref.value;
             }
         },
         dispose: (geometry: Mesh) => {
@@ -154,10 +154,10 @@ async function createStructureGaussianSurfaceMesh(ctx: VisualContext, structure:
         idField
     };
     const surface = await computeMarchingCubesMesh(params, mesh).runAsChild(ctx.runtime);
-    (surface.meta as GaussianSurfaceMeta) = { resolution };
+    (surface.meta.resolution as GaussianSurfaceMeta['resolution']) = resolution;
 
     Mesh.transform(surface, transform);
-    if (ctx.webgl && !ctx.webgl.isWebGL2) Mesh.uniformTriangleGroup(surface, false);
+    if (ctx.webgl && !ctx.webgl.isWebGL2) Mesh.uniformTriangleGroup(surface);
 
     const sphere = Sphere3D.expand(Sphere3D(), structure.boundary.sphere, props.radiusOffset + getStructureExtraRadius(structure));
     surface.setBoundingSphere(sphere);
@@ -193,7 +193,7 @@ export function StructureGaussianSurfaceMeshVisual(materialId: number): ComplexV
             const csp = getColorSmoothingProps(props, theme, resolution, webgl);
             if (csp) {
                 applyMeshColorSmoothing(values, csp.resolution, csp.stride, csp.webgl, colorTexture);
-                (geometry.meta as GaussianSurfaceMeta).colorTexture = values.tColorGrid.ref.value;
+                (geometry.meta.colorTexture as GaussianSurfaceMeta['colorTexture']) = values.tColorGrid.ref.value;
             }
         },
         dispose: (geometry: Mesh) => {

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

@@ -48,11 +48,11 @@ async function createMolecularSurfaceMesh(ctx: VisualContext, unit: Unit, struct
     const surface = await computeMarchingCubesMesh(params, mesh).runAsChild(ctx.runtime);
 
     Mesh.transform(surface, transform);
-    if (ctx.webgl && !ctx.webgl.isWebGL2) Mesh.uniformTriangleGroup(surface, false);
+    if (ctx.webgl && !ctx.webgl.isWebGL2) Mesh.uniformTriangleGroup(surface);
 
     const sphere = Sphere3D.expand(Sphere3D(), unit.boundary.sphere, props.probeRadius + getUnitExtraRadius(unit));
     surface.setBoundingSphere(sphere);
-    (surface.meta as MolecularSurfaceMeta) = { resolution };
+    (surface.meta.resolution as MolecularSurfaceMeta['resolution']) = resolution;
 
     return surface;
 }
@@ -83,7 +83,7 @@ export function MolecularSurfaceMeshVisual(materialId: number): UnitsVisual<Mole
             const csp = getColorSmoothingProps(props, theme, resolution, webgl);
             if (csp) {
                 applyMeshColorSmoothing(values, csp.resolution, csp.stride, csp.webgl, colorTexture);
-                (geometry.meta as MolecularSurfaceMeta).colorTexture = values.tColorGrid.ref.value;
+                (geometry.meta.colorTexture as MolecularSurfaceMeta['colorTexture']) = values.tColorGrid.ref.value;
             }
         },
         dispose: (geometry: Mesh) => {