Ver Fonte

wip, visual refactoring

Alexander Rose há 6 anos atrás
pai
commit
be1737a8d7

+ 17 - 0
src/mol-geo/representation/index.ts

@@ -12,6 +12,23 @@ import { MarkerAction } from '../util/marker-data';
 
 export type VisualQuality = 'custom' | 'auto' | 'highest' | 'high' | 'medium' | 'low' | 'lowest'
 
+export const DefaultBaseProps = {
+    alpha: 1,
+    visible: true,
+    depthMask: true,
+    useFog: true,
+    quality: 'auto' as VisualQuality
+}
+export type BaseProps = Partial<typeof DefaultBaseProps>
+
+export const DefaultMeshProps = {
+    ...DefaultBaseProps,
+    doubleSided: false,
+    flipSided: false,
+    flatShaded: false,
+}
+export type MeshProps = Partial<typeof DefaultMeshProps>
+
 export interface RepresentationProps {}
 
 export interface Representation<D, P extends RepresentationProps = {}> {

+ 2 - 8
src/mol-geo/representation/structure/index.ts

@@ -8,7 +8,7 @@
 import { Structure, StructureSymmetry, Unit } from 'mol-model/structure';
 import { Task } from 'mol-task'
 import { RenderObject } from 'mol-gl/render-object';
-import { Representation, RepresentationProps, Visual, VisualQuality } from '..';
+import { Representation, RepresentationProps, Visual, VisualQuality, DefaultBaseProps } from '..';
 import { ColorTheme, SizeTheme } from '../../theme';
 import { PickingId } from '../../util/picking';
 import { Loci, EmptyLoci, isEmptyLoci } from 'mol-model/loci';
@@ -78,14 +78,9 @@ function getQualityProps(props: Partial<QualityProps>, structure: Structure) {
 }
 
 export const DefaultStructureProps = {
+    ...DefaultBaseProps,
     colorTheme: { name: 'instance-index' } as ColorTheme,
     sizeTheme: { name: 'physical' } as SizeTheme,
-    alpha: 1,
-    visible: true,
-    doubleSided: false,
-    depthMask: true,
-    useFog: true,
-    quality: 'auto' as VisualQuality
 }
 export type StructureProps = Partial<typeof DefaultStructureProps>
 
@@ -99,7 +94,6 @@ export function StructureRepresentation<P extends StructureProps>(unitsVisualCto
 
     function create(structure: Structure, props: P = {} as P) {
         _props = Object.assign({}, DefaultStructureProps, _props, props, getQualityProps(props, structure))
-        console.log('create struct', (_props as any).detail, (_props as any).radialSegments)
 
         return Task.create('Creating StructureRepresentation', async ctx => {
             if (!_structure) {

+ 12 - 31
src/mol-geo/representation/structure/visual/element-sphere.ts

@@ -13,9 +13,8 @@ import { DefaultStructureProps, UnitsVisual } from '../index';
 import { RuntimeContext } from 'mol-task'
 import { createTransforms, createColors } from '../visual/util/common';
 import { createElementSphereMesh, markElement, getElementRadius } from '../visual/util/element';
-import { deepEqual, defaults } from 'mol-util';
-import { fillSerial } from 'mol-gl/renderable/util';
-import { RenderableState, MeshValues } from 'mol-gl/renderable';
+import { deepEqual } from 'mol-util';
+import { MeshValues } from 'mol-gl/renderable';
 import { getMeshData } from '../../../util/mesh-data';
 import { Mesh } from '../../../shape/mesh';
 import { PickingId } from '../../../util/picking';
@@ -23,12 +22,13 @@ import { OrderedSet } from 'mol-data/int';
 import { createMarkers, MarkerAction } from '../../../util/marker-data';
 import { Loci, EmptyLoci } from 'mol-model/loci';
 import { SizeTheme } from '../../../theme';
+import { DefaultMeshProps } from '../..';
+import { createMeshValues, updateMeshValues, updateRenderableState, createRenderableState } from '../../util';
 
 export const DefaultElementSphereProps = {
+    ...DefaultMeshProps,
     ...DefaultStructureProps,
     sizeTheme: { name: 'physical', factor: 1 } as SizeTheme,
-    flipSided: false,
-    flatShaded: false,
     detail: 0,
 }
 export type ElementSphereProps = Partial<typeof DefaultElementSphereProps>
@@ -65,31 +65,17 @@ export function ElementSphereVisual(): UnitsVisual<ElementSphereProps> {
             if (ctx.shouldUpdate) await ctx.update('Computing spacefill marks');
             const marker = createMarkers(instanceCount * elementCount)
 
+            const counts = { drawCount: mesh.triangleCount * 3, elementCount, instanceCount }
+
             const values: MeshValues = {
                 ...getMeshData(mesh),
-                aTransform: transforms,
-                aInstanceId: ValueCell.create(fillSerial(new Float32Array(instanceCount))),
                 ...color,
                 ...marker,
-
-                uAlpha: ValueCell.create(defaults(props.alpha, 1.0)),
-                uInstanceCount: ValueCell.create(instanceCount),
-                uElementCount: ValueCell.create(elementCount),
-
+                aTransform: transforms,
                 elements: mesh.indexBuffer,
-
-                drawCount: ValueCell.create(mesh.triangleCount * 3),
-                instanceCount: ValueCell.create(instanceCount),
-
-                dDoubleSided: ValueCell.create(defaults(props.doubleSided, true)),
-                dFlatShaded: ValueCell.create(defaults(props.flatShaded, false)),
-                dFlipSided: ValueCell.create(defaults(props.flipSided, false)),
-                dUseFog: ValueCell.create(defaults(props.useFog, true)),
-            }
-            const state: RenderableState = {
-                depthMask: defaults(props.depthMask, true),
-                visible: defaults(props.visible, true)
+                ...createMeshValues(currentProps, counts),
             }
+            const state = createRenderableState(currentProps)
 
             spheres = createMeshRenderObject(values, state)
             renderObjects.push(spheres)
@@ -119,13 +105,8 @@ export function ElementSphereVisual(): UnitsVisual<ElementSphereProps> {
                 createColors(currentGroup, elementCount, newProps.colorTheme, spheres.values)
             }
 
-            ValueCell.updateIfChanged(spheres.values.uAlpha, newProps.alpha)
-            ValueCell.updateIfChanged(spheres.values.dDoubleSided, newProps.doubleSided)
-            ValueCell.updateIfChanged(spheres.values.dFlipSided, newProps.flipSided)
-            ValueCell.updateIfChanged(spheres.values.dFlatShaded, newProps.flatShaded)
-
-            spheres.state.visible = newProps.visible
-            spheres.state.depthMask = newProps.depthMask
+            updateMeshValues(spheres.values, newProps)
+            updateRenderableState(spheres.state, newProps)
 
             currentProps = newProps
             return true

+ 12 - 32
src/mol-geo/representation/structure/visual/inter-unit-link-cylinder.ts

@@ -11,18 +11,17 @@ import { Link, Structure } from 'mol-model/structure';
 import { DefaultStructureProps, StructureVisual } from '../index';
 import { RuntimeContext } from 'mol-task'
 import { LinkCylinderProps, DefaultLinkCylinderProps, createLinkCylinderMesh } from './util/link';
-import { fillSerial } from 'mol-gl/renderable/util';
-import { RenderableState, MeshValues } from 'mol-gl/renderable';
+import { MeshValues } from 'mol-gl/renderable';
 import { getMeshData } from '../../../util/mesh-data';
 import { Mesh } from '../../../shape/mesh';
 import { PickingId } from '../../../util/picking';
 import { Vec3 } from 'mol-math/linear-algebra';
 import { createUniformColor } from '../../../util/color-data';
-import { defaults } from 'mol-util';
 import { Loci, isEveryLoci, EmptyLoci } from 'mol-model/loci';
 import { MarkerAction, applyMarkerAction, createMarkers, MarkerData } from '../../../util/marker-data';
 import { SizeTheme } from '../../../theme';
 import { createIdentityTransform } from './util/common';
+import { updateMeshValues, updateRenderableState, createMeshValues, createRenderableState } from '../../util';
 // import { chainIdLinkColorData } from '../../../theme/structure/color/chain-id';
 
 async function createInterUnitLinkCylinderMesh(ctx: RuntimeContext, structure: Structure, props: LinkCylinderProps, mesh?: Mesh) {
@@ -51,8 +50,6 @@ export const DefaultInterUnitLinkProps = {
     ...DefaultStructureProps,
     ...DefaultLinkCylinderProps,
     sizeTheme: { name: 'physical', factor: 0.3 } as SizeTheme,
-    flipSided: false,
-    flatShaded: false,
 }
 export type InterUnitLinkProps = Partial<typeof DefaultInterUnitLinkProps>
 
@@ -86,31 +83,17 @@ export function InterUnitLinkVisual(): StructureVisual<InterUnitLinkProps> {
             if (ctx.shouldUpdate) await ctx.update('Computing link marks');
             const marker = createMarkers(instanceCount * elementCount)
 
+            const counts = { drawCount: mesh.triangleCount * 3, elementCount, instanceCount }
+
             const values: MeshValues = {
                 ...getMeshData(mesh),
-                aTransform: transforms,
-                aInstanceId: ValueCell.create(fillSerial(new Float32Array(instanceCount))),
                 ...color,
                 ...marker,
-
-                uAlpha: ValueCell.create(defaults(props.alpha, 1.0)),
-                uInstanceCount: ValueCell.create(instanceCount),
-                uElementCount: ValueCell.create(elementCount),
-
+                aTransform: transforms,
                 elements: mesh.indexBuffer,
-
-                drawCount: ValueCell.create(mesh.triangleCount * 3),
-                instanceCount: ValueCell.create(instanceCount),
-
-                dDoubleSided: ValueCell.create(defaults(props.doubleSided, true)),
-                dFlatShaded: ValueCell.create(defaults(props.flatShaded, false)),
-                dFlipSided: ValueCell.create(defaults(props.flipSided, false)),
-                dUseFog: ValueCell.create(defaults(props.useFog, true)),
-            }
-            const state: RenderableState = {
-                depthMask: defaults(props.depthMask, true),
-                visible: defaults(props.visible, true)
+                ...createMeshValues(currentProps, counts),
             }
+            const state = createRenderableState(currentProps)
 
             cylinders = createMeshRenderObject(values, state)
             renderObjects.push(cylinders)
@@ -118,16 +101,13 @@ export function InterUnitLinkVisual(): StructureVisual<InterUnitLinkProps> {
         async update(ctx: RuntimeContext, props: InterUnitLinkProps) {
             const newProps = Object.assign({}, currentProps, props)
 
-            if (!cylinders || currentProps.radialSegments !== newProps.radialSegments) return false
-            // TODO
+            if (!cylinders) return false
 
-            ValueCell.updateIfChanged(cylinders.values.uAlpha, newProps.alpha)
-            ValueCell.updateIfChanged(cylinders.values.dDoubleSided, newProps.doubleSided)
-            ValueCell.updateIfChanged(cylinders.values.dFlipSided, newProps.flipSided)
-            ValueCell.updateIfChanged(cylinders.values.dFlatShaded, newProps.flatShaded)
+            // TODO create in-place
+            if (currentProps.radialSegments !== newProps.radialSegments) return false
 
-            cylinders.state.visible = newProps.visible
-            cylinders.state.depthMask = newProps.depthMask
+            updateMeshValues(cylinders.values, newProps)
+            updateRenderableState(cylinders.state, newProps)
 
             return false
         },

+ 9 - 31
src/mol-geo/representation/structure/visual/intra-unit-link-cylinder.ts

@@ -12,19 +12,18 @@ import { Unit, Link } from 'mol-model/structure';
 import { UnitsVisual, DefaultStructureProps } from '../index';
 import { RuntimeContext } from 'mol-task'
 import { DefaultLinkCylinderProps, LinkCylinderProps, createLinkCylinderMesh } from './util/link';
-import { fillSerial } from 'mol-gl/renderable/util';
-import { RenderableState, MeshValues } from 'mol-gl/renderable';
+import { MeshValues } from 'mol-gl/renderable';
 import { getMeshData } from '../../../util/mesh-data';
 import { Mesh } from '../../../shape/mesh';
 import { PickingId } from '../../../util/picking';
 import { Vec3 } from 'mol-math/linear-algebra';
 // import { createUniformColor } from '../../../util/color-data';
-import { defaults } from 'mol-util';
 import { Loci, isEveryLoci, EmptyLoci } from 'mol-model/loci';
 import { MarkerAction, applyMarkerAction, createMarkers, MarkerData } from '../../../util/marker-data';
 import { SizeTheme } from '../../../theme';
 import { chainIdLinkColorData } from '../../../theme/structure/color/chain-id';
 import { createTransforms } from './util/common';
+import { createMeshValues, createRenderableState, updateMeshValues, updateRenderableState } from '../../util';
 
 async function createIntraUnitLinkCylinderMesh(ctx: RuntimeContext, unit: Unit, props: LinkCylinderProps, mesh?: Mesh) {
     if (!Unit.isAtomic(unit)) return Mesh.createEmpty(mesh)
@@ -67,8 +66,6 @@ export const DefaultIntraUnitLinkProps = {
     ...DefaultStructureProps,
     ...DefaultLinkCylinderProps,
     sizeTheme: { name: 'physical', factor: 0.3 } as SizeTheme,
-    flipSided: false,
-    flatShaded: false,
 }
 export type IntraUnitLinkProps = Partial<typeof DefaultIntraUnitLinkProps>
 
@@ -103,31 +100,17 @@ export function IntraUnitLinkVisual(): UnitsVisual<IntraUnitLinkProps> {
             if (ctx.shouldUpdate) await ctx.update('Computing link marks');
             const marker = createMarkers(instanceCount * elementCount)
 
+            const counts = { drawCount: mesh.triangleCount * 3, elementCount, instanceCount }
+
             const values: MeshValues = {
                 ...getMeshData(mesh),
-                aTransform: transforms,
-                aInstanceId: ValueCell.create(fillSerial(new Float32Array(instanceCount))),
                 ...color,
                 ...marker,
-
-                uAlpha: ValueCell.create(defaults(props.alpha, 1.0)),
-                uInstanceCount: ValueCell.create(instanceCount),
-                uElementCount: ValueCell.create(elementCount),
-
+                aTransform: transforms,
                 elements: mesh.indexBuffer,
-
-                drawCount: ValueCell.create(mesh.triangleCount * 3),
-                instanceCount: ValueCell.create(instanceCount),
-
-                dDoubleSided: ValueCell.create(defaults(props.doubleSided, true)),
-                dFlatShaded: ValueCell.create(defaults(props.flatShaded, false)),
-                dFlipSided: ValueCell.create(defaults(props.flipSided, false)),
-                dUseFog: ValueCell.create(defaults(props.useFog, true)),
-            }
-            const state: RenderableState = {
-                depthMask: defaults(props.depthMask, true),
-                visible: defaults(props.visible, true)
+                ...createMeshValues(currentProps, counts),
             }
+            const state = createRenderableState(currentProps)
 
             cylinders = createMeshRenderObject(values, state)
             renderObjects.push(cylinders)
@@ -138,13 +121,8 @@ export function IntraUnitLinkVisual(): UnitsVisual<IntraUnitLinkProps> {
             if (!cylinders || currentProps.radialSegments !== newProps.radialSegments) return false
             // TODO
 
-            ValueCell.updateIfChanged(cylinders.values.uAlpha, newProps.alpha)
-            ValueCell.updateIfChanged(cylinders.values.dDoubleSided, newProps.doubleSided)
-            ValueCell.updateIfChanged(cylinders.values.dFlipSided, newProps.flipSided)
-            ValueCell.updateIfChanged(cylinders.values.dFlatShaded, newProps.flatShaded)
-
-            cylinders.state.visible = newProps.visible
-            cylinders.state.depthMask = newProps.depthMask
+            updateMeshValues(cylinders.values, newProps)
+            updateRenderableState(cylinders.state, newProps)
 
             return true
         },

+ 2 - 0
src/mol-geo/representation/structure/visual/util/link.ts

@@ -9,8 +9,10 @@ import { RuntimeContext } from 'mol-task';
 import { Mesh } from '../../../../shape/mesh';
 import { MeshBuilder } from '../../../../shape/mesh-builder';
 import { LinkType } from 'mol-model/structure/model/types';
+import { DefaultMeshProps } from '../../..';
 
 export const DefaultLinkCylinderProps = {
+    ...DefaultMeshProps,
     linkScale: 0.4,
     linkSpacing: 1,
     linkRadius: 0.25,

+ 58 - 0
src/mol-geo/representation/util.ts

@@ -0,0 +1,58 @@
+/**
+ * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ */
+
+import { ValueCell } from 'mol-util/value-cell'
+import { BaseValues } from 'mol-gl/renderable/schema';
+import { BaseProps, MeshProps } from '.';
+import { MeshValues, RenderableState } from 'mol-gl/renderable';
+import { fillSerial } from 'mol-gl/renderable/util';
+
+type Counts = { drawCount: number, elementCount: number, instanceCount: number }
+
+export function createBaseValues(props: Required<BaseProps>, counts: Counts) {
+    return {
+        uAlpha: ValueCell.create(props.alpha),
+        uInstanceCount: ValueCell.create(counts.instanceCount),
+        uElementCount: ValueCell.create(counts.elementCount),
+        aInstanceId: ValueCell.create(fillSerial(new Float32Array(counts.instanceCount))),
+        drawCount: ValueCell.create(counts.drawCount),
+        instanceCount: ValueCell.create(counts.instanceCount),
+    }
+}
+
+export function createMeshValues(props: Required<MeshProps>, counts: Counts) {
+    return {
+        ...createBaseValues(props, counts),
+        dDoubleSided: ValueCell.create(props.doubleSided),
+        dFlatShaded: ValueCell.create(props.flatShaded),
+        dFlipSided: ValueCell.create(props.flipSided),
+        dUseFog: ValueCell.create(props.useFog),
+    }
+}
+
+export function createRenderableState(props: Required<BaseProps>): RenderableState {
+    return {
+        visible: props.visible,
+        depthMask: props.depthMask
+    }
+}
+
+export function updateBaseValues(values: BaseValues, props: Required<BaseProps>) {
+    ValueCell.updateIfChanged(values.uAlpha, props.alpha)
+}
+
+export function updateMeshValues(values: MeshValues, props: Required<MeshProps>) {
+    updateBaseValues(values, props)
+    ValueCell.updateIfChanged(values.dDoubleSided, props.doubleSided)
+    ValueCell.updateIfChanged(values.dFlatShaded, props.flatShaded)
+    ValueCell.updateIfChanged(values.dFlipSided, props.flipSided)
+    ValueCell.updateIfChanged(values.dUseFog, props.useFog)
+}
+
+export function updateRenderableState(state: RenderableState, props: Required<BaseProps>) {
+    state.visible = props.visible
+    state.depthMask = props.depthMask
+}