Browse Source

wip, more geometry refactoring

Alexander Rose 6 years ago
parent
commit
da4368c6c4
43 changed files with 290 additions and 381 deletions
  1. 1 1
      src/apps/canvas/component/viewport.tsx
  2. 1 1
      src/apps/viewer/index.tsx
  3. 13 2
      src/mol-geo/geometry/color-data.ts
  4. 50 82
      src/mol-geo/geometry/geometry.ts
  5. 0 0
      src/mol-geo/geometry/marker-data.ts
  6. 47 1
      src/mol-geo/geometry/mesh/mesh.ts
  7. 0 0
      src/mol-geo/geometry/picking.ts
  8. 44 0
      src/mol-geo/geometry/point/point.ts
  9. 13 1
      src/mol-geo/geometry/size-data.ts
  10. 3 15
      src/mol-geo/geometry/transform-data.ts
  11. 2 2
      src/mol-geo/representation/index.ts
  12. 11 26
      src/mol-geo/representation/shape/index.ts
  13. 2 2
      src/mol-geo/representation/structure/complex-representation.ts
  14. 8 6
      src/mol-geo/representation/structure/complex-visual.ts
  15. 6 4
      src/mol-geo/representation/structure/index.ts
  16. 2 2
      src/mol-geo/representation/structure/representation/backbone.ts
  17. 2 2
      src/mol-geo/representation/structure/representation/ball-and-stick.ts
  18. 2 2
      src/mol-geo/representation/structure/representation/carbohydrate.ts
  19. 2 2
      src/mol-geo/representation/structure/representation/cartoon.ts
  20. 2 2
      src/mol-geo/representation/structure/representation/distance-restraint.ts
  21. 2 2
      src/mol-geo/representation/structure/representation/point.ts
  22. 2 2
      src/mol-geo/representation/structure/representation/spacefill.ts
  23. 2 2
      src/mol-geo/representation/structure/representation/surface.ts
  24. 2 2
      src/mol-geo/representation/structure/units-representation.ts
  25. 9 9
      src/mol-geo/representation/structure/units-visual.ts
  26. 4 5
      src/mol-geo/representation/structure/visual/carbohydrate-link-cylinder.ts
  27. 7 2
      src/mol-geo/representation/structure/visual/carbohydrate-symbol-mesh.ts
  28. 1 1
      src/mol-geo/representation/structure/visual/cross-link-restraint-cylinder.ts
  29. 1 1
      src/mol-geo/representation/structure/visual/inter-unit-link-cylinder.ts
  30. 1 1
      src/mol-geo/representation/structure/visual/intra-unit-link-cylinder.ts
  31. 18 94
      src/mol-geo/representation/structure/visual/util/common.ts
  32. 1 1
      src/mol-geo/representation/structure/visual/util/element.ts
  33. 0 2
      src/mol-geo/representation/structure/visual/util/link.ts
  34. 1 1
      src/mol-geo/representation/structure/visual/util/nucleotide.ts
  35. 1 1
      src/mol-geo/representation/structure/visual/util/polymer.ts
  36. 4 4
      src/mol-geo/representation/volume/index.ts
  37. 16 49
      src/mol-geo/representation/volume/surface.ts
  38. 0 22
      src/mol-geo/util/mesh-data.ts
  39. 0 20
      src/mol-geo/util/point-data.ts
  40. 3 3
      src/mol-gl/_spec/renderer.spec.ts
  41. 1 1
      src/mol-view/theme/color.ts
  42. 1 1
      src/mol-view/theme/size.ts
  43. 2 2
      src/mol-view/viewer.ts

+ 1 - 1
src/apps/canvas/component/viewport.tsx

@@ -6,7 +6,7 @@
 
 import * as React from 'react'
 import { App } from '../app';
-import { MarkerAction } from 'mol-geo/util/marker-data';
+import { MarkerAction } from 'mol-geo/geometry/marker-data';
 import { EmptyLoci, Loci, areLociEqual } from 'mol-model/loci';
 import { labelFirst } from 'mol-view/label';
 

+ 1 - 1
src/apps/viewer/index.tsx

@@ -24,7 +24,7 @@ import { TransformListController } from 'mol-app/controller/transform/list';
 import { TransformList } from 'mol-app/ui/transform/list';
 import { SequenceView } from 'mol-app/ui/visualization/sequence-view';
 import { InteractivityEvents } from 'mol-app/event/basic';
-import { MarkerAction } from 'mol-geo/util/marker-data';
+import { MarkerAction } from 'mol-geo/geometry/marker-data';
 import { EveryLoci } from 'mol-model/loci';
 
 const elm = document.getElementById('app')

+ 13 - 2
src/mol-geo/util/color-data.ts → src/mol-geo/geometry/color-data.ts

@@ -8,10 +8,11 @@ import { ValueCell } from 'mol-util';
 import { TextureImage, createTextureImage } from 'mol-gl/renderable/util';
 import { Color } from 'mol-util/color';
 import { Vec2, Vec3 } from 'mol-math/linear-algebra';
-import { LocationIterator } from './location-iterator';
+import { LocationIterator } from '../util/location-iterator';
 import { NullLocation } from 'mol-model/location';
-import { LocationColor } from 'mol-view/theme/color';
+import { LocationColor, ColorThemeProps, ColorTheme } from 'mol-view/theme/color';
 import { RuntimeContext } from 'mol-task';
+import { getGranularity } from './geometry';
 
 export type ColorType = 'uniform' | 'instance' | 'group' | 'groupInstance'
 
@@ -23,6 +24,16 @@ export type ColorData = {
     dColorType: ValueCell<string>,
 }
 
+export function createColors(ctx: RuntimeContext, locationIt: LocationIterator, props: ColorThemeProps, colorData?: ColorData): Promise<ColorData> {
+    const colorTheme = ColorTheme(props)
+    switch (getGranularity(locationIt, colorTheme.granularity)) {
+        case 'uniform': return createUniformColor(ctx, locationIt, colorTheme.color, colorData)
+        case 'group': return createGroupColor(ctx, locationIt, colorTheme.color, colorData)
+        case 'groupInstance': return createGroupInstanceColor(ctx, locationIt, colorTheme.color, colorData)
+        case 'instance': return createInstanceColor(ctx, locationIt, colorTheme.color, colorData)
+    }
+}
+
 const emptyColorTexture = { array: new Uint8Array(3), width: 1, height: 1 }
 function createEmptyColorTexture() {
     return {

+ 50 - 82
src/mol-geo/geometry/geometry.ts

@@ -6,20 +6,19 @@
 
 import { Mesh } from './mesh/mesh';
 import { Point } from './point/point';
-import { PointValues, MeshValues, RenderableState } from 'mol-gl/renderable';
-import { MeshRenderObject, PointRenderObject } from 'mol-gl/render-object';
+import { RenderableState } from 'mol-gl/renderable';
 import { ValueCell } from 'mol-util';
 import { BaseValues } from 'mol-gl/renderable/schema';
+import { Color } from 'mol-util/color';
+import { ColorThemeProps } from 'mol-view/theme/color';
+import { LocationIterator } from '../util/location-iterator';
+import { ColorType } from './color-data';
+import { SizeType } from './size-data';
 
 export type GeometryKindType = { 'mesh': Mesh, 'point': Point }
 export type GeometryKind = keyof GeometryKindType
 export type Geometry = Helpers.ValueOf<GeometryKindType>
 
-export type GeometryDef = {
-    'mesh': { 'props': MeshProps, 'values': MeshValues, 'renderObject': MeshRenderObject }
-    'point': { 'props': PointProps, 'values': PointValues, 'renderObject': PointRenderObject }
-}
-
 export namespace Geometry {
     export function getDrawCount(geometry: Geometry) {
         switch (geometry.kind) {
@@ -27,99 +26,68 @@ export namespace Geometry {
             case 'point': return geometry.vertexCount
         }
     }
-}
 
-//
+    //
 
-export const VisualQualityInfo = {
-    'custom': {},
-    'auto': {},
-    'highest': {},
-    'high': {},
-    'medium': {},
-    'low': {},
-    'lowest': {},
-}
-export type VisualQuality = keyof typeof VisualQualityInfo
-export const VisualQualityNames = Object.keys(VisualQualityInfo)
-
-//
-
-export const DefaultBaseProps = {
-    alpha: 1,
-    visible: true,
-    depthMask: true,
-    useFog: false,
-    quality: 'auto' as VisualQuality
-}
-export type BaseProps = typeof DefaultBaseProps
-
-export const DefaultMeshProps = {
-    ...DefaultBaseProps,
-    doubleSided: false,
-    flipSided: false,
-    flatShaded: false,
-}
-export type MeshProps = typeof DefaultMeshProps
-
-export const DefaultPointProps = {
-    ...DefaultBaseProps,
-    pointSizeAttenuation: true
-}
-export type PointProps = typeof DefaultPointProps
+    export const DefaultProps = {
+        alpha: 1,
+        visible: true,
+        depthMask: true,
+        useFog: false,
+        quality: 'auto' as VisualQuality,
+        colorTheme: { name: 'uniform', value: Color(0x22EE11) } as ColorThemeProps,
+    }
+    export type Props = typeof DefaultProps
 
-type Counts = { drawCount: number, groupCount: number, instanceCount: number }
+    export type Counts = { drawCount: number, groupCount: number, instanceCount: number }
 
-export function createBaseValues(props: BaseProps, counts: Counts) {
-    return {
-        uAlpha: ValueCell.create(props.alpha),
-        uGroupCount: ValueCell.create(counts.groupCount),
-        drawCount: ValueCell.create(counts.drawCount),
-        dUseFog: ValueCell.create(props.useFog),
+    export function createValues(props: Props, counts: Counts) {
+        return {
+            uAlpha: ValueCell.create(props.alpha),
+            uGroupCount: ValueCell.create(counts.groupCount),
+            drawCount: ValueCell.create(counts.drawCount),
+            dUseFog: ValueCell.create(props.useFog),
+        }
     }
-}
 
-export function createMeshValues(props: MeshProps, counts: Counts) {
-    return {
-        ...createBaseValues(props, counts),
-        dDoubleSided: ValueCell.create(props.doubleSided),
-        dFlatShaded: ValueCell.create(props.flatShaded),
-        dFlipSided: ValueCell.create(props.flipSided),
+    export function updateValues(values: BaseValues, props: Props) {
+        ValueCell.updateIfChanged(values.uAlpha, props.alpha)
+        ValueCell.updateIfChanged(values.dUseFog, props.useFog)
     }
 }
 
-export function createPointValues(props: PointProps, counts: Counts) {
-    return {
-        ...createBaseValues(props, counts),
-        dPointSizeAttenuation: ValueCell.create(props.pointSizeAttenuation),
-    }
-}
+//
 
-export function createRenderableState(props: BaseProps): RenderableState {
+export function createRenderableState(props: Geometry.Props): RenderableState {
     return {
         visible: props.visible,
         depthMask: props.depthMask
     }
 }
 
-export function updateBaseValues(values: BaseValues, props: BaseProps) {
-    ValueCell.updateIfChanged(values.uAlpha, props.alpha)
-    ValueCell.updateIfChanged(values.dUseFog, props.useFog)
+export function updateRenderableState(state: RenderableState, props: Geometry.Props) {
+    state.visible = props.visible
+    state.depthMask = props.depthMask
 }
 
-export function updateMeshValues(values: MeshValues, props: MeshProps) {
-    updateBaseValues(values, props)
-    ValueCell.updateIfChanged(values.dDoubleSided, props.doubleSided)
-    ValueCell.updateIfChanged(values.dFlatShaded, props.flatShaded)
-    ValueCell.updateIfChanged(values.dFlipSided, props.flipSided)
-}
+//
 
-export function updatePointValues(values: PointValues, props: PointProps) {
-    updateBaseValues(values, props)
-    ValueCell.updateIfChanged(values.dPointSizeAttenuation, props.pointSizeAttenuation)
+export function getGranularity(locationIt: LocationIterator, granularity: ColorType | SizeType) {
+    // Always use 'group' granularity for 'complex' location iterators,
+    // i.e. for which an instance may include multiple units
+    return granularity === 'instance' && locationIt.isComplex ? 'group' : granularity
 }
 
-export function updateRenderableState(state: RenderableState, props: BaseProps) {
-    state.visible = props.visible
-    state.depthMask = props.depthMask
-}
+//
+
+export const VisualQualityInfo = {
+    'custom': {},
+    'auto': {},
+    'highest': {},
+    'high': {},
+    'medium': {},
+    'low': {},
+    'lowest': {},
+}
+export type VisualQuality = keyof typeof VisualQualityInfo
+export const VisualQualityNames = Object.keys(VisualQualityInfo)

+ 0 - 0
src/mol-geo/util/marker-data.ts → src/mol-geo/geometry/marker-data.ts


+ 47 - 1
src/mol-geo/geometry/mesh/mesh.ts

@@ -4,11 +4,17 @@
  * @author David Sehnal <david.sehnal@gmail.com>
  */
 
-import { Task } from 'mol-task'
+import { Task, RuntimeContext } from 'mol-task'
 import { ValueCell } from 'mol-util'
 import { Vec3, Mat4 } from 'mol-math/linear-algebra'
 import { Sphere3D } from 'mol-math/geometry'
 import { transformPositionArray/* , transformDirectionArray, getNormalMatrix */ } from '../../util';
+import { MeshValues } from 'mol-gl/renderable';
+import { Geometry } from '../geometry';
+import { createMarkers } from '../marker-data';
+import { TransformData } from '../transform-data';
+import { LocationIterator } from '../../util/location-iterator';
+import { createColors } from '../color-data';
 
 export interface Mesh {
     readonly kind: 'mesh',
@@ -153,6 +159,46 @@ export namespace Mesh {
             return mesh;
         });
     }
+
+    //
+
+    export const DefaultProps = {
+        ...Geometry.DefaultProps,
+        doubleSided: false,
+        flipSided: false,
+        flatShaded: false,
+    }
+    export type Props = typeof DefaultProps
+
+    export async function createValues(ctx: RuntimeContext, mesh: Mesh, transform: TransformData, locationIt: LocationIterator, props: Props): Promise<MeshValues> {
+        const { instanceCount, groupCount } = locationIt
+        const color = await createColors(ctx, locationIt, props.colorTheme)
+        const marker = createMarkers(instanceCount * groupCount)
+
+        const counts = { drawCount: mesh.triangleCount * 3, groupCount, instanceCount }
+
+        return {
+            aPosition: mesh.vertexBuffer,
+            aNormal: mesh.normalBuffer,
+            aGroup: mesh.groupBuffer,
+            elements: mesh.indexBuffer,
+            ...color,
+            ...marker,
+            ...transform,
+
+            ...Geometry.createValues(props, counts),
+            dDoubleSided: ValueCell.create(props.doubleSided),
+            dFlatShaded: ValueCell.create(props.flatShaded),
+            dFlipSided: ValueCell.create(props.flipSided),
+        }
+    }
+
+    export function updateValues(values: MeshValues, props: Props) {
+        Geometry.updateValues(values, props)
+        ValueCell.updateIfChanged(values.dDoubleSided, props.doubleSided)
+        ValueCell.updateIfChanged(values.dFlatShaded, props.flatShaded)
+        ValueCell.updateIfChanged(values.dFlipSided, props.flipSided)
+    }
 }
 
 //     function addVertex(src: Float32Array, i: number, dst: Float32Array, j: number) {

+ 0 - 0
src/mol-geo/util/picking.ts → src/mol-geo/geometry/picking.ts


+ 44 - 0
src/mol-geo/geometry/point/point.ts

@@ -7,6 +7,15 @@
 import { ValueCell } from 'mol-util'
 import { Mat4 } from 'mol-math/linear-algebra'
 import { transformPositionArray/* , transformDirectionArray, getNormalMatrix */ } from '../../util';
+import { Geometry } from '../geometry';
+import { PointValues } from 'mol-gl/renderable';
+import { RuntimeContext } from 'mol-task';
+import { createColors } from '../color-data';
+import { createMarkers } from '../marker-data';
+import { createSizes } from '../size-data';
+import { TransformData } from '../transform-data';
+import { LocationIterator } from '../../util/location-iterator';
+import { SizeThemeProps } from 'mol-view/theme/size';
 
 /** Point cloud */
 export interface Point {
@@ -40,4 +49,39 @@ export namespace Point {
         transformPositionArray(t, v, offset, count)
         ValueCell.update(point.vertexBuffer, v);
     }
+
+    //
+
+    export const DefaultProps = {
+        ...Geometry.DefaultProps,
+        pointSizeAttenuation: false,
+        sizeTheme: { name: 'uniform', value: 1 } as SizeThemeProps,
+    }
+    export type Props = typeof DefaultProps
+
+    export async function createValues(ctx: RuntimeContext, point: Point, transform: TransformData, locationIt: LocationIterator, props: Props): Promise<PointValues> {
+        const { instanceCount, groupCount } = locationIt
+        const color = await createColors(ctx, locationIt, props.colorTheme)
+        const size = await createSizes(ctx, locationIt, props.sizeTheme)
+        const marker = createMarkers(instanceCount * groupCount)
+
+        const counts = { drawCount: point.vertexCount, groupCount, instanceCount }
+
+        return {
+            aPosition: point.vertexBuffer,
+            aGroup: point.groupBuffer,
+            ...color,
+            ...size,
+            ...marker,
+            ...transform,
+
+            ...Geometry.createValues(props, counts),
+            dPointSizeAttenuation: ValueCell.create(props.pointSizeAttenuation),
+        }
+    }
+
+    export function updateValues(values: PointValues, props: Props) {
+        Geometry.updateValues(values, props)
+        ValueCell.updateIfChanged(values.dPointSizeAttenuation, props.pointSizeAttenuation)
+    }
 }

+ 13 - 1
src/mol-geo/util/size-data.ts → src/mol-geo/geometry/size-data.ts

@@ -7,9 +7,11 @@
 import { ValueCell } from 'mol-util';
 import { Vec2 } from 'mol-math/linear-algebra';
 import { TextureImage, createTextureImage } from 'mol-gl/renderable/util';
-import { LocationIterator } from './location-iterator';
+import { LocationIterator } from '../util/location-iterator';
 import { Location, NullLocation } from 'mol-model/location';
 import { RuntimeContext } from 'mol-task';
+import { SizeThemeProps, SizeTheme } from 'mol-view/theme/size';
+import { getGranularity } from './geometry';
 
 export type SizeType = 'uniform' | 'instance' | 'group' | 'groupInstance'
 
@@ -21,6 +23,16 @@ export type SizeData = {
     dSizeType: ValueCell<string>,
 }
 
+export async function createSizes(ctx: RuntimeContext, locationIt: LocationIterator, props: SizeThemeProps, sizeData?: SizeData): Promise<SizeData> {
+    const sizeTheme = SizeTheme(props)
+    switch (getGranularity(locationIt, sizeTheme.granularity)) {
+        case 'uniform': return createUniformSize(ctx, locationIt, sizeTheme.size, sizeData)
+        case 'group': return createGroupSize(ctx, locationIt, sizeTheme.size, sizeData)
+        case 'groupInstance': return createGroupInstanceSize(ctx, locationIt, sizeTheme.size, sizeData)
+        case 'instance': return createInstanceSize(ctx, locationIt, sizeTheme.size, sizeData)
+    }
+}
+
 export type LocationSize = (location: Location) => number
 
 const emptySizeTexture = { array: new Uint8Array(1), width: 1, height: 1 }

+ 3 - 15
src/mol-geo/util/transform-data.ts → src/mol-geo/geometry/transform-data.ts

@@ -7,7 +7,6 @@
 import { ValueCell } from 'mol-util';
 import { Mat4 } from 'mol-math/linear-algebra';
 import { fillSerial } from 'mol-util/array';
-import { Unit } from 'mol-model/structure';
 
 export type TransformData = {
     aTransform: ValueCell<Float32Array>,
@@ -16,7 +15,7 @@ export type TransformData = {
     aInstance: ValueCell<Float32Array>,
 }
 
-export function _createTransforms(transformArray: Float32Array, instanceCount: number, transformData?: TransformData): TransformData {
+export function createTransform(transformArray: Float32Array, instanceCount: number, transformData?: TransformData): TransformData {
     if (transformData) {
         ValueCell.update(transformData.aTransform, transformArray)
         ValueCell.update(transformData.uInstanceCount, instanceCount)
@@ -37,16 +36,5 @@ export function _createTransforms(transformArray: Float32Array, instanceCount: n
 const identityTransform = new Float32Array(16)
 Mat4.toArray(Mat4.identity(), identityTransform, 0)
 export function createIdentityTransform(transformData?: TransformData): TransformData {
-    return _createTransforms(identityTransform, 1, transformData)
-}
-
-export function createTransforms({ units }: Unit.SymmetryGroup, transformData?: TransformData) {
-    const unitCount = units.length
-    const n = unitCount * 16
-    const array = transformData && transformData.aTransform.ref.value.length >= n ? transformData.aTransform.ref.value : new Float32Array(n)
-    for (let i = 0; i < unitCount; i++) {
-        Mat4.toArray(units[i].conformation.operator.matrix, array, i * 16)
-    }
-    return _createTransforms(array, unitCount, transformData)
-}
-
+    return createTransform(identityTransform, 1, transformData)
+}

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

@@ -6,9 +6,9 @@
 
 import { Task, RuntimeContext } from 'mol-task'
 import { RenderObject } from 'mol-gl/render-object'
-import { PickingId } from '../util/picking';
+import { PickingId } from '../geometry/picking';
 import { Loci } from 'mol-model/loci';
-import { MarkerAction } from '../util/marker-data';
+import { MarkerAction } from '../geometry/marker-data';
 
 export interface RepresentationProps {}
 

+ 11 - 26
src/mol-geo/representation/shape/index.ts

@@ -7,24 +7,22 @@
 import { Task } from 'mol-task'
 import { RenderObject, createMeshRenderObject, MeshRenderObject } from 'mol-gl/render-object';
 import { RepresentationProps, Representation } from '..';
-import { PickingId } from '../../util/picking';
+import { PickingId } from '../../geometry/picking';
 import { Loci, EmptyLoci, isEveryLoci } from 'mol-model/loci';
-import { MarkerAction, applyMarkerAction, createMarkers } from '../../util/marker-data';
-import { getMeshData } from '../../util/mesh-data';
-import { MeshValues } from 'mol-gl/renderable';
+import { MarkerAction, applyMarkerAction } from '../../geometry/marker-data';
 import { ValueCell } from 'mol-util';
 import { ColorThemeProps } from 'mol-view/theme/color';
 import { Shape } from 'mol-model/shape';
 import { LocationIterator } from '../../util/location-iterator';
-import { createColors } from '../structure/visual/util/common';
 import { OrderedSet, Interval } from 'mol-data/int';
-import { createIdentityTransform } from '../../util/transform-data';
-import { DefaultMeshProps, createMeshValues, createRenderableState } from '../../geometry/geometry';
+import { createIdentityTransform } from '../../geometry/transform-data';
+import { createRenderableState } from '../../geometry/geometry';
+import { Mesh } from '../../geometry/mesh/mesh';
 
 export interface ShapeRepresentation<P extends RepresentationProps = {}> extends Representation<Shape, P> { }
 
 export const DefaultShapeProps = {
-    ...DefaultMeshProps,
+    ...Mesh.DefaultProps,
 
     colorTheme: { name: 'shape-group' } as ColorThemeProps
 }
@@ -37,10 +35,10 @@ export function ShapeRepresentation<P extends ShapeProps>(): ShapeRepresentation
     const renderObjects: RenderObject[] = []
     let _renderObject: MeshRenderObject | undefined
     let _shape: Shape
-    let _props: P
+    let currentProps: P
 
     function createOrUpdate(props: Partial<P> = {}, shape?: Shape) {
-        _props = Object.assign({}, DefaultShapeProps, _props, props)
+        currentProps = Object.assign({}, DefaultShapeProps, currentProps, props)
         if (shape) _shape = shape
 
         return Task.create('ShapeRepresentation.create', async ctx => {
@@ -50,23 +48,10 @@ export function ShapeRepresentation<P extends ShapeProps>(): ShapeRepresentation
 
             const mesh = _shape.mesh
             const locationIt = ShapeGroupIterator.fromShape(_shape)
-            const { groupCount, instanceCount } = locationIt
-
             const transform = createIdentityTransform()
-            const color = await createColors(ctx, locationIt, _props.colorTheme)
-            const marker = createMarkers(instanceCount * groupCount)
-            const counts = { drawCount: mesh.triangleCount * 3, groupCount, instanceCount }
-
-            const values: MeshValues = {
-                ...getMeshData(mesh),
-                ...createMeshValues(_props, counts),
-                ...transform,
-                ...color,
-                ...marker,
 
-                elements: mesh.indexBuffer,
-            }
-            const state = createRenderableState(_props)
+            const values = await Mesh.createValues(ctx, mesh, transform, locationIt, currentProps)
+            const state = createRenderableState(currentProps)
 
             _renderObject = createMeshRenderObject(values, state)
             renderObjects.push(_renderObject)
@@ -76,7 +61,7 @@ export function ShapeRepresentation<P extends ShapeProps>(): ShapeRepresentation
     return {
         label: 'Shape mesh',
         get renderObjects () { return renderObjects },
-        get props () { return _props },
+        get props () { return currentProps },
         createOrUpdate,
         getLoci(pickingId: PickingId) {
             const { objectId, groupId } = pickingId

+ 2 - 2
src/mol-geo/representation/structure/complex-representation.ts

@@ -7,9 +7,9 @@
 
 import { Structure } from 'mol-model/structure';
 import { Task } from 'mol-task'
-import { PickingId } from '../../util/picking';
+import { PickingId } from '../../geometry/picking';
 import { Loci, EmptyLoci } from 'mol-model/loci';
-import { MarkerAction } from '../../util/marker-data';
+import { MarkerAction } from '../../geometry/marker-data';
 import { StructureProps, StructureRepresentation } from '.';
 import { ComplexVisual } from './complex-visual';
 

+ 8 - 6
src/mol-geo/representation/structure/complex-visual.ts

@@ -10,14 +10,15 @@ import { MeshRenderObject } from 'mol-gl/render-object';
 import { Mesh } from '../../geometry/mesh/mesh';
 import { RuntimeContext } from 'mol-task';
 import { LocationIterator } from '../../util/location-iterator';
-import { createComplexMeshRenderObject, createColors } from './visual/util/common';
+import { createComplexMeshRenderObject } from './visual/util/common';
 import { StructureProps, DefaultStructureMeshProps, VisualUpdateState } from '.';
 import { deepEqual, ValueCell } from 'mol-util';
-import { PickingId } from '../../util/picking';
+import { PickingId } from '../../geometry/picking';
 import { Loci, isEveryLoci, EmptyLoci } from 'mol-model/loci';
-import { MarkerAction, applyMarkerAction } from '../../util/marker-data';
+import { MarkerAction, applyMarkerAction } from '../../geometry/marker-data';
 import { Interval } from 'mol-data/int';
-import { updateMeshValues, updateRenderableState } from '../../geometry/geometry';
+import { updateRenderableState } from '../../geometry/geometry';
+import { createColors } from '../../geometry/color-data';
 
 export interface  ComplexVisual<P extends StructureProps> extends Visual<Structure, P> { }
 
@@ -90,8 +91,9 @@ export function ComplexMeshVisual<P extends ComplexMeshProps>(builder: ComplexMe
             await createColors(ctx, locationIt, newProps.colorTheme, renderObject.values)
         }
 
-        updateMeshValues(renderObject.values, newProps)
-        updateRenderableState(renderObject.state, newProps)
+        // TODO why do I need to cast here?
+        Mesh.updateValues(renderObject.values, newProps as ComplexMeshProps)
+        updateRenderableState(renderObject.state, newProps as ComplexMeshProps)
 
         currentProps = newProps
         return true

+ 6 - 4
src/mol-geo/representation/structure/index.ts

@@ -9,26 +9,28 @@ import { Structure } from 'mol-model/structure';
 import { ColorThemeProps } from 'mol-view/theme/color';
 import { SizeThemeProps } from 'mol-view/theme/size';
 import { Representation, RepresentationProps } from '..';
-import { DefaultMeshProps, DefaultBaseProps, DefaultPointProps } from '../../geometry/geometry';
+import { Geometry } from '../../geometry/geometry';
+import { Mesh } from '../../geometry/mesh/mesh';
+import { Point } from '../../geometry/point/point';
 
 export interface StructureRepresentation<P extends RepresentationProps = {}> extends Representation<Structure, P> { }
 
 export const DefaultStructureProps = {
-    ...DefaultBaseProps,
+    ...Geometry.DefaultProps,
     colorTheme: { name: 'unit-index' } as ColorThemeProps,
     sizeTheme: { name: 'physical' } as SizeThemeProps,
 }
 export type StructureProps = typeof DefaultStructureProps
 
 export const DefaultStructureMeshProps = {
+    ...Mesh.DefaultProps,
     ...DefaultStructureProps,
-    ...DefaultMeshProps
 }
 export type StructureMeshProps = typeof DefaultStructureMeshProps
 
 export const DefaultStructurePointProps = {
     ...DefaultStructureProps,
-    ...DefaultPointProps
+    ...Point.DefaultProps
 }
 export type StructurePointProps = typeof DefaultStructurePointProps
 

+ 2 - 2
src/mol-geo/representation/structure/representation/backbone.ts

@@ -5,11 +5,11 @@
  */
 
 import { StructureRepresentation, UnitsRepresentation } from '..';
-import { PickingId } from '../../../util/picking';
+import { PickingId } from '../../../geometry/picking';
 import { Structure } from 'mol-model/structure';
 import { Task } from 'mol-task';
 import { Loci } from 'mol-model/loci';
-import { MarkerAction } from '../../../util/marker-data';
+import { MarkerAction } from '../../../geometry/marker-data';
 import { PolymerBackboneVisual, DefaultPolymerBackboneProps } from '../visual/polymer-backbone-cylinder';
 import { getQualityProps } from '../../util';
 

+ 2 - 2
src/mol-geo/representation/structure/representation/ball-and-stick.ts

@@ -7,11 +7,11 @@
 import { ComplexRepresentation, StructureRepresentation, UnitsRepresentation } from '..';
 import { ElementSphereVisual, DefaultElementSphereProps } from '../visual/element-sphere';
 import { IntraUnitLinkVisual, DefaultIntraUnitLinkProps } from '../visual/intra-unit-link-cylinder';
-import { PickingId } from '../../../util/picking';
+import { PickingId } from '../../../geometry/picking';
 import { Structure, Unit } from 'mol-model/structure';
 import { Task } from 'mol-task';
 import { Loci, isEmptyLoci } from 'mol-model/loci';
-import { MarkerAction } from '../../../util/marker-data';
+import { MarkerAction } from '../../../geometry/marker-data';
 import { InterUnitLinkVisual } from '../visual/inter-unit-link-cylinder';
 import { SizeThemeProps } from 'mol-view/theme/size';
 import { getQualityProps } from '../../util';

+ 2 - 2
src/mol-geo/representation/structure/representation/carbohydrate.ts

@@ -5,11 +5,11 @@
  */
 
 import { ComplexRepresentation, StructureRepresentation } from '..';
-import { PickingId } from '../../../util/picking';
+import { PickingId } from '../../../geometry/picking';
 import { Structure } from 'mol-model/structure';
 import { Task } from 'mol-task';
 import { Loci, isEmptyLoci } from 'mol-model/loci';
-import { MarkerAction } from '../../../util/marker-data';
+import { MarkerAction } from '../../../geometry/marker-data';
 import { CarbohydrateSymbolVisual, DefaultCarbohydrateSymbolProps } from '../visual/carbohydrate-symbol-mesh';
 import { CarbohydrateLinkVisual, DefaultCarbohydrateLinkProps } from '../visual/carbohydrate-link-cylinder';
 import { SizeThemeProps } from 'mol-view/theme/size';

+ 2 - 2
src/mol-geo/representation/structure/representation/cartoon.ts

@@ -5,11 +5,11 @@
  */
 
 import { StructureRepresentation, UnitsRepresentation } from '..';
-import { PickingId } from '../../../util/picking';
+import { PickingId } from '../../../geometry/picking';
 import { Structure } from 'mol-model/structure';
 import { Task } from 'mol-task';
 import { Loci, isEmptyLoci } from 'mol-model/loci';
-import { MarkerAction } from '../../../util/marker-data';
+import { MarkerAction } from '../../../geometry/marker-data';
 import { PolymerTraceVisual, DefaultPolymerTraceProps } from '../visual/polymer-trace-mesh';
 import { PolymerGapVisual, DefaultPolymerGapProps } from '../visual/polymer-gap-cylinder';
 import { NucleotideBlockVisual, DefaultNucleotideBlockProps } from '../visual/nucleotide-block-mesh';

+ 2 - 2
src/mol-geo/representation/structure/representation/distance-restraint.ts

@@ -5,11 +5,11 @@
  */
 
 import { ComplexRepresentation, StructureRepresentation } from '..';
-import { PickingId } from '../../../util/picking';
+import { PickingId } from '../../../geometry/picking';
 import { Structure } from 'mol-model/structure';
 import { Task } from 'mol-task';
 import { Loci } from 'mol-model/loci';
-import { MarkerAction } from '../../../util/marker-data';
+import { MarkerAction } from '../../../geometry/marker-data';
 import { CrossLinkRestraintVisual, DefaultCrossLinkRestraintProps } from '../visual/cross-link-restraint-cylinder';
 import { SizeThemeProps } from 'mol-view/theme/size';
 import { getQualityProps } from '../../util';

+ 2 - 2
src/mol-geo/representation/structure/representation/point.ts

@@ -8,9 +8,9 @@ import { UnitsRepresentation } from '..';
 import { ElementPointVisual, DefaultElementPointProps } from '../visual/element-point';
 import { StructureRepresentation } from '../units-representation';
 import { Structure } from 'mol-model/structure';
-import { MarkerAction } from '../../../util/marker-data';
+import { MarkerAction } from '../../../geometry/marker-data';
 import { Loci } from 'mol-model/loci';
-import { PickingId } from '../../../util/picking';
+import { PickingId } from '../../../geometry/picking';
 
 export const DefaultPointProps = {
     ...DefaultElementPointProps,

+ 2 - 2
src/mol-geo/representation/structure/representation/spacefill.ts

@@ -8,8 +8,8 @@ import { UnitsRepresentation } from '..';
 import { ElementSphereVisual, DefaultElementSphereProps } from '../visual/element-sphere';
 import { StructureRepresentation } from '../units-representation';
 import { Structure } from 'mol-model/structure';
-import { PickingId } from '../../../util/picking';
-import { MarkerAction } from '../../../util/marker-data';
+import { PickingId } from '../../../geometry/picking';
+import { MarkerAction } from '../../../geometry/marker-data';
 import { Loci } from 'mol-model/loci';
 import { getQualityProps } from '../../util';
 

+ 2 - 2
src/mol-geo/representation/structure/representation/surface.ts

@@ -8,9 +8,9 @@ import { UnitsRepresentation } from '..';
 import { GaussianSurfaceVisual, DefaultGaussianSurfaceProps } from '../visual/gaussian-surface-mesh';
 import { StructureRepresentation } from '../units-representation';
 import { Structure } from 'mol-model/structure';
-import { MarkerAction } from '../../../util/marker-data';
+import { MarkerAction } from '../../../geometry/marker-data';
 import { Loci } from 'mol-model/loci';
-import { PickingId } from '../../../util/picking';
+import { PickingId } from '../../../geometry/picking';
 import { Task } from 'mol-task';
 import { GaussianDensityPointVisual, DefaultGaussianDensityPointProps } from '../visual/gaussian-density-point';
 

+ 2 - 2
src/mol-geo/representation/structure/units-representation.ts

@@ -9,9 +9,9 @@ import { Structure, Unit } from 'mol-model/structure';
 import { Task } from 'mol-task'
 import { RenderObject } from 'mol-gl/render-object';
 import { Representation, RepresentationProps, Visual } from '..';
-import { PickingId } from '../../util/picking';
+import { PickingId } from '../../geometry/picking';
 import { Loci, EmptyLoci, isEmptyLoci } from 'mol-model/loci';
-import { MarkerAction } from '../../util/marker-data';
+import { MarkerAction } from '../../geometry/marker-data';
 import { StructureProps } from '.';
 import { StructureGroup } from './units-visual';
 

+ 9 - 9
src/mol-geo/representation/structure/units-visual.ts

@@ -8,18 +8,18 @@ import { Unit, Structure } from 'mol-model/structure';
 import { RepresentationProps, Visual } from '../';
 import { DefaultStructureMeshProps, VisualUpdateState, DefaultStructurePointProps } from '.';
 import { RuntimeContext } from 'mol-task';
-import { PickingId } from '../../util/picking';
+import { PickingId } from '../../geometry/picking';
 import { LocationIterator } from '../../util/location-iterator';
 import { Mesh } from '../../geometry/mesh/mesh';
-import { MarkerAction, applyMarkerAction, createMarkers } from '../../util/marker-data';
+import { MarkerAction, applyMarkerAction, createMarkers } from '../../geometry/marker-data';
 import { Loci, isEveryLoci, EmptyLoci } from 'mol-model/loci';
 import { MeshRenderObject, PointRenderObject } from 'mol-gl/render-object';
-import { createUnitsMeshRenderObject, createColors, createUnitsPointRenderObject } from './visual/util/common';
+import { createUnitsMeshRenderObject, createUnitsPointRenderObject, createUnitsTransform } from './visual/util/common';
 import { deepEqual, ValueCell, UUID } from 'mol-util';
 import { Interval } from 'mol-data/int';
-import { createTransforms } from '../../util/transform-data';
-import { updateMeshValues, updateRenderableState, updatePointValues } from '../../geometry/geometry';
 import { Point } from '../../geometry/point/point';
+import { updateRenderableState } from '../../geometry/geometry';
+import { createColors } from '../../geometry/color-data';
 
 export type StructureGroup = { structure: Structure, group: Unit.SymmetryGroup }
 
@@ -96,7 +96,7 @@ export function UnitsMeshVisual<P extends UnitsMeshProps>(builder: UnitsMeshVisu
         if (updateState.updateTransform) {
             locationIt = createLocationIterator(currentGroup)
             const { instanceCount, groupCount } = locationIt
-            createTransforms(currentGroup, renderObject.values)
+            createUnitsTransform(currentGroup, renderObject.values)
             createMarkers(instanceCount * groupCount, renderObject.values)
             updateState.updateColor = true
         }
@@ -114,7 +114,7 @@ export function UnitsMeshVisual<P extends UnitsMeshProps>(builder: UnitsMeshVisu
         }
 
         // TODO why do I need to cast here?
-        updateMeshValues(renderObject.values, newProps as UnitsMeshProps)
+        Mesh.updateValues(renderObject.values, newProps as UnitsMeshProps)
         updateRenderableState(renderObject.state, newProps as UnitsMeshProps)
 
         currentProps = newProps
@@ -254,7 +254,7 @@ export function UnitsPointVisual<P extends UnitsPointProps>(builder: UnitsPointV
         if (updateState.updateTransform) {
             locationIt = createLocationIterator(currentGroup)
             const { instanceCount, groupCount } = locationIt
-            createTransforms(currentGroup, renderObject.values)
+            createUnitsTransform(currentGroup, renderObject.values)
             createMarkers(instanceCount * groupCount, renderObject.values)
             updateState.updateColor = true
         }
@@ -272,7 +272,7 @@ export function UnitsPointVisual<P extends UnitsPointProps>(builder: UnitsPointV
         }
 
         // TODO why do I need to cast here?
-        updatePointValues(renderObject.values, newProps as UnitsPointProps)
+        Point.updateValues(renderObject.values, newProps as UnitsPointProps)
         updateRenderableState(renderObject.state, newProps as UnitsPointProps)
 
         currentProps = newProps

+ 4 - 5
src/mol-geo/representation/structure/visual/carbohydrate-link-cylinder.ts

@@ -5,10 +5,10 @@
  */
 
 import { Unit, Structure, Link, StructureElement } from 'mol-model/structure';
-import { DefaultStructureProps, ComplexVisual, VisualUpdateState } from '..';
+import { ComplexVisual, VisualUpdateState } from '..';
 import { RuntimeContext } from 'mol-task'
 import { Mesh } from '../../../geometry/mesh/mesh';
-import { PickingId } from '../../../util/picking';
+import { PickingId } from '../../../geometry/picking';
 import { Loci, EmptyLoci } from 'mol-model/loci';
 import { Vec3 } from 'mol-math/linear-algebra';
 import { LocationIterator } from '../../../util/location-iterator';
@@ -18,7 +18,7 @@ import { ComplexMeshVisual } from '../complex-visual';
 import { SizeThemeProps, SizeTheme } from 'mol-view/theme/size';
 import { LinkType } from 'mol-model/structure/model/types';
 import { BitFlags } from 'mol-util';
-import { DefaultMeshProps } from '../../../geometry/geometry';
+import { DefaultUnitsMeshProps } from '../units-visual';
 
 // TODO create seperate visual
 // for (let i = 0, il = carbohydrates.terminalLinks.length; i < il; ++i) {
@@ -61,8 +61,7 @@ async function createCarbohydrateLinkCylinderMesh(ctx: RuntimeContext, structure
 }
 
 export const DefaultCarbohydrateLinkProps = {
-    ...DefaultMeshProps,
-    ...DefaultStructureProps,
+    ...DefaultUnitsMeshProps,
     ...DefaultLinkCylinderProps,
     sizeTheme: { name: 'physical', factor: 1 } as SizeThemeProps,
     detail: 0,

+ 7 - 2
src/mol-geo/representation/structure/visual/carbohydrate-symbol-mesh.ts

@@ -8,7 +8,7 @@ import { Unit, Structure, StructureElement } from 'mol-model/structure';
 import { ComplexVisual, VisualUpdateState } from '..';
 import { RuntimeContext } from 'mol-task'
 import { Mesh } from '../../../geometry/mesh/mesh';
-import { PickingId } from '../../../util/picking';
+import { PickingId } from '../../../geometry/picking';
 import { Loci, EmptyLoci } from 'mol-model/loci';
 import { MeshBuilder } from '../../../geometry/mesh/mesh-builder';
 import { Vec3, Mat4 } from 'mol-math/linear-algebra';
@@ -49,9 +49,10 @@ async function createCarbohydrateSymbolMesh(ctx: RuntimeContext, structure: Stru
     const { detail } = props
 
     const carbohydrates = structure.carbohydrates
+    const n = carbohydrates.elements.length
     const l = StructureElement.create()
 
-    for (let i = 0, il = carbohydrates.elements.length; i < il; ++i) {
+    for (let i = 0; i < n; ++i) {
         const c = carbohydrates.elements[i];
         const shapeType = getSaccharideShape(c.component.type)
 
@@ -134,6 +135,10 @@ async function createCarbohydrateSymbolMesh(ctx: RuntimeContext, structure: Stru
                 builder.add(t, hexagonalPrism)
                 break
         }
+
+        if (i % 10000 === 0 && ctx.shouldUpdate) {
+            await ctx.update({ message: 'Carbohydrate symbols', current: i, max: n });
+        }
     }
 
     return builder.getMesh()

+ 1 - 1
src/mol-geo/representation/structure/visual/cross-link-restraint-cylinder.ts

@@ -9,7 +9,7 @@ import { ComplexVisual, VisualUpdateState } from '..';
 import { RuntimeContext } from 'mol-task'
 import { LinkCylinderProps, DefaultLinkCylinderProps, createLinkCylinderMesh } from './util/link';
 import { Mesh } from '../../../geometry/mesh/mesh';
-import { PickingId } from '../../../util/picking';
+import { PickingId } from '../../../geometry/picking';
 import { Vec3 } from 'mol-math/linear-algebra';
 import { Loci, EmptyLoci } from 'mol-model/loci';
 import { ComplexMeshVisual, DefaultComplexMeshProps } from '../complex-visual';

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

@@ -9,7 +9,7 @@ import { ComplexVisual, VisualUpdateState } from '..';
 import { RuntimeContext } from 'mol-task'
 import { LinkCylinderProps, DefaultLinkCylinderProps, createLinkCylinderMesh, LinkIterator } from './util/link';
 import { Mesh } from '../../../geometry/mesh/mesh';
-import { PickingId } from '../../../util/picking';
+import { PickingId } from '../../../geometry/picking';
 import { Vec3 } from 'mol-math/linear-algebra';
 import { Loci, EmptyLoci } from 'mol-model/loci';
 import { ComplexMeshVisual, DefaultComplexMeshProps } from '../complex-visual';

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

@@ -10,7 +10,7 @@ import { UnitsVisual, VisualUpdateState } from '..';
 import { RuntimeContext } from 'mol-task'
 import { DefaultLinkCylinderProps, LinkCylinderProps, createLinkCylinderMesh, LinkIterator } from './util/link';
 import { Mesh } from '../../../geometry/mesh/mesh';
-import { PickingId } from '../../../util/picking';
+import { PickingId } from '../../../geometry/picking';
 import { Vec3 } from 'mol-math/linear-algebra';
 import { Loci, EmptyLoci } from 'mol-model/loci';
 import { UnitsMeshVisual, DefaultUnitsMeshProps } from '../units-visual';

+ 18 - 94
src/mol-geo/representation/structure/visual/util/common.ts

@@ -2,131 +2,55 @@
  * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
- * @author David Sehnal <david.sehnal@gmail.com>
  */
 
 import { Unit, Structure } from 'mol-model/structure';
-import { createUniformColor, ColorData, createGroupColor, createGroupInstanceColor, createInstanceColor, ColorType } from '../../../../util/color-data';
-import { createUniformSize, SizeData, createGroupSize, createGroupInstanceSize, createInstanceSize, SizeType } from '../../../../util/size-data';
 import { LocationIterator } from '../../../../util/location-iterator';
 import { Mesh } from '../../../../geometry/mesh/mesh';
-import { MeshValues, PointValues } from 'mol-gl/renderable';
-import { getMeshData } from '../../../../util/mesh-data';
 import { StructureProps } from '../..';
-import { createMarkers } from '../../../../util/marker-data';
 import { createMeshRenderObject, createPointRenderObject } from 'mol-gl/render-object';
-import { ColorThemeProps, ColorTheme } from 'mol-view/theme/color';
-import { SizeThemeProps, SizeTheme } from 'mol-view/theme/size';
 import { RuntimeContext } from 'mol-task';
 import { PointProps } from 'mol-geo/representation/structure/representation/point';
-import { TransformData, createIdentityTransform, createTransforms } from '../../../../util/transform-data';
+import { TransformData, createIdentityTransform, createTransform } from '../../../../geometry/transform-data';
 import { Point } from '../../../../geometry/point/point';
-import { getPointData } from '../../../../util/point-data';
-import { MeshProps, createMeshValues, createRenderableState, createPointValues } from '../../../../geometry/geometry';
-
-function getGranularity(locationIt: LocationIterator, granularity: ColorType | SizeType) {
-    // Always use 'group' granularity for 'complex' location iterators,
-    // i.e. for which an instance may include multiple units
-    return granularity === 'instance' && locationIt.isComplex ? 'group' : granularity
-}
-
-export function createColors(ctx: RuntimeContext, locationIt: LocationIterator, props: ColorThemeProps, colorData?: ColorData): Promise<ColorData> {
-    const colorTheme = ColorTheme(props)
-    switch (getGranularity(locationIt, colorTheme.granularity)) {
-        case 'uniform': return createUniformColor(ctx, locationIt, colorTheme.color, colorData)
-        case 'group': return createGroupColor(ctx, locationIt, colorTheme.color, colorData)
-        case 'groupInstance': return createGroupInstanceColor(ctx, locationIt, colorTheme.color, colorData)
-        case 'instance': return createInstanceColor(ctx, locationIt, colorTheme.color, colorData)
-    }
-}
-
-export async function createSizes(ctx: RuntimeContext, locationIt: LocationIterator, props: SizeThemeProps, sizeData?: SizeData): Promise<SizeData> {
-    const sizeTheme = SizeTheme(props)
-    switch (getGranularity(locationIt, sizeTheme.granularity)) {
-        case 'uniform': return createUniformSize(ctx, locationIt, sizeTheme.size, sizeData)
-        case 'group': return createGroupSize(ctx, locationIt, sizeTheme.size, sizeData)
-        case 'groupInstance': return createGroupInstanceSize(ctx, locationIt, sizeTheme.size, sizeData)
-        case 'instance': return createInstanceSize(ctx, locationIt, sizeTheme.size, sizeData)
+import { createRenderableState } from '../../../../geometry/geometry';
+import { Mat4 } from 'mol-math/linear-algebra';
+
+export function createUnitsTransform({ units }: Unit.SymmetryGroup, transformData?: TransformData) {
+    const unitCount = units.length
+    const n = unitCount * 16
+    const array = transformData && transformData.aTransform.ref.value.length >= n ? transformData.aTransform.ref.value : new Float32Array(n)
+    for (let i = 0; i < unitCount; i++) {
+        Mat4.toArray(units[i].conformation.operator.matrix, array, i * 16)
     }
+    return createTransform(array, unitCount, transformData)
 }
 
 // mesh
 
-type StructureMeshProps = MeshProps & StructureProps
-
-async function _createMeshValues(ctx: RuntimeContext, transforms: TransformData, mesh: Mesh, locationIt: LocationIterator, props: StructureMeshProps): Promise<MeshValues> {
-    const { instanceCount, groupCount } = locationIt
-    const color = await createColors(ctx, locationIt, props.colorTheme)
-    const marker = createMarkers(instanceCount * groupCount)
-
-    const counts = { drawCount: mesh.triangleCount * 3, groupCount, instanceCount }
-
-    return {
-        ...getMeshData(mesh),
-        ...color,
-        ...marker,
-        ...transforms,
-        elements: mesh.indexBuffer,
-        ...createMeshValues(props, counts)
-    }
-}
-
-export async function createComplexMeshValues(ctx: RuntimeContext, structure: Structure, mesh: Mesh, locationIt: LocationIterator, props: StructureMeshProps): Promise<MeshValues> {
-    const transforms = createIdentityTransform()
-    return _createMeshValues(ctx, transforms, mesh, locationIt, props)
-}
-
-export async function createUnitsMeshValues(ctx: RuntimeContext, group: Unit.SymmetryGroup, mesh: Mesh, locationIt: LocationIterator, props: StructureMeshProps): Promise<MeshValues> {
-    const transforms = createTransforms(group)
-    return _createMeshValues(ctx, transforms, mesh, locationIt, props)
-}
+type StructureMeshProps = Mesh.Props & StructureProps
 
 export async function createComplexMeshRenderObject(ctx: RuntimeContext, structure: Structure, mesh: Mesh, locationIt: LocationIterator, props: StructureMeshProps) {
-    const values = await createComplexMeshValues(ctx, structure, mesh, locationIt, props)
+    const transform = createIdentityTransform()
+    const values = await Mesh.createValues(ctx, mesh, transform, locationIt, props)
     const state = createRenderableState(props)
     return createMeshRenderObject(values, state)
 }
 
 export async function createUnitsMeshRenderObject(ctx: RuntimeContext, group: Unit.SymmetryGroup, mesh: Mesh, locationIt: LocationIterator, props: StructureMeshProps) {
-    const values = await createUnitsMeshValues(ctx, group, mesh, locationIt, props)
+    const transform = createUnitsTransform(group)
+    const values = await Mesh.createValues(ctx, mesh, transform, locationIt, props)
     const state = createRenderableState(props)
     return createMeshRenderObject(values, state)
 }
 
-export async function updateComplexMeshRenderObject(ctx: RuntimeContext, structure: Structure, mesh: Mesh, locationIt: LocationIterator, props: StructureMeshProps): Promise<MeshValues> {
-    const transforms = createIdentityTransform()
-    return _createMeshValues(ctx, transforms, mesh, locationIt, props)
-}
-
 // point
 
 type StructurePointProps = PointProps & StructureProps
 
-async function _createPointValues(ctx: RuntimeContext, transforms: TransformData, point: Point, locationIt: LocationIterator, props: StructurePointProps): Promise<PointValues> {
-    const { instanceCount, groupCount } = locationIt
-    const color = await createColors(ctx, locationIt, props.colorTheme)
-    const size = await createSizes(ctx, locationIt, props.sizeTheme)
-    const marker = createMarkers(instanceCount * groupCount)
-
-    const counts = { drawCount: point.vertexCount, groupCount, instanceCount }
-
-    return {
-        ...getPointData(point),
-        ...color,
-        ...size,
-        ...marker,
-        ...transforms,
-        ...createPointValues(props, counts)
-    }
-}
-
-export async function createUnitsPointValues(ctx: RuntimeContext, group: Unit.SymmetryGroup, point: Point, locationIt: LocationIterator, props: StructurePointProps): Promise<PointValues> {
-    const transforms = createTransforms(group)
-    return _createPointValues(ctx, transforms, point, locationIt, props)
-}
-
 export async function createUnitsPointRenderObject(ctx: RuntimeContext, group: Unit.SymmetryGroup, point: Point, locationIt: LocationIterator, props: StructurePointProps) {
-    const values = await createUnitsPointValues(ctx, group, point, locationIt, props)
+    const transform = createUnitsTransform(group)
+    const values = await Point.createValues(ctx, point, transform, locationIt, props)
     const state = createRenderableState(props)
     return createPointRenderObject(values, state)
 }

+ 1 - 1
src/mol-geo/representation/structure/visual/util/element.ts

@@ -12,7 +12,7 @@ import { Mesh } from '../../../../geometry/mesh/mesh';
 import { MeshBuilder } from '../../../../geometry/mesh/mesh-builder';
 import { Loci, EmptyLoci } from 'mol-model/loci';
 import { Interval, OrderedSet } from 'mol-data/int';
-import { PickingId } from '../../../../util/picking';
+import { PickingId } from '../../../../geometry/picking';
 import { SizeTheme, SizeThemeProps } from 'mol-view/theme/size';
 import { LocationIterator } from '../../../../util/location-iterator';
 import { addSphere } from '../../../../geometry/mesh/builder/sphere';

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

@@ -14,10 +14,8 @@ import { CylinderProps } from '../../../../primitive/cylinder';
 import { LocationIterator } from '../../../../util/location-iterator';
 import { Unit, StructureElement, Structure, Link } from 'mol-model/structure';
 import { addFixedCountDashedCylinder, addCylinder, addDoubleCylinder } from '../../../../geometry/mesh/builder/cylinder';
-import { DefaultMeshProps } from '../../../../geometry/geometry';
 
 export const DefaultLinkCylinderProps = {
-    ...DefaultMeshProps,
     sizeTheme: { name: 'uniform', value: 0.15 } as SizeThemeProps,
     linkScale: 0.4,
     linkSpacing: 1,

+ 1 - 1
src/mol-geo/representation/structure/visual/util/nucleotide.ts

@@ -7,7 +7,7 @@
 import { Unit, StructureElement } from 'mol-model/structure';
 import { LocationIterator } from '../../../../util/location-iterator';
 import { getNucleotideElements } from 'mol-model/structure/structure/util/nucleotide';
-import { PickingId } from '../../../../util/picking';
+import { PickingId } from '../../../../geometry/picking';
 import { Loci, EmptyLoci } from 'mol-model/loci';
 import { OrderedSet, Interval } from 'mol-data/int';
 

+ 1 - 1
src/mol-geo/representation/structure/visual/util/polymer.ts

@@ -7,7 +7,7 @@
 import { Unit, ElementIndex, StructureElement, Link } from 'mol-model/structure';
 import SortedRanges from 'mol-data/int/sorted-ranges';
 import { LocationIterator } from '../../../../util/location-iterator';
-import { PickingId } from '../../../../util/picking';
+import { PickingId } from '../../../../geometry/picking';
 import { OrderedSet, Interval } from 'mol-data/int';
 import { EmptyLoci, Loci } from 'mol-model/loci';
 

+ 4 - 4
src/mol-geo/representation/volume/index.ts

@@ -8,17 +8,17 @@ import { Task } from 'mol-task'
 import { RenderObject } from 'mol-gl/render-object';
 import { RepresentationProps, Representation, Visual } from '..';
 import { VolumeData } from 'mol-model/volume';
-import { PickingId } from '../../util/picking';
+import { PickingId } from '../../geometry/picking';
 import { Loci, EmptyLoci } from 'mol-model/loci';
-import { MarkerAction } from '../../util/marker-data';
-import { DefaultBaseProps } from '../../geometry/geometry';
+import { MarkerAction } from '../../geometry/marker-data';
+import { Geometry } from '../../geometry/geometry';
 
 export interface VolumeVisual<P extends RepresentationProps = {}> extends Visual<VolumeData, P> { }
 
 export interface VolumeRepresentation<P extends RepresentationProps = {}> extends Representation<VolumeData, P> { }
 
 export const DefaultVolumeProps = {
-    ...DefaultBaseProps
+    ...Geometry.DefaultProps
 }
 export type VolumeProps = typeof DefaultVolumeProps
 

+ 16 - 49
src/mol-geo/representation/volume/surface.ts

@@ -11,16 +11,13 @@ import { computeMarchingCubes } from '../../util/marching-cubes/algorithm';
 import { Mesh } from '../../geometry/mesh/mesh';
 import { VolumeVisual } from '.';
 import { createMeshRenderObject, MeshRenderObject } from 'mol-gl/render-object';
-import { ValueCell, defaults } from 'mol-util';
-import { Mat4 } from 'mol-math/linear-algebra';
-import { createValueColor } from '../../util/color-data';
-import { getMeshData } from '../../util/mesh-data';
-import { RenderableState, MeshValues } from 'mol-gl/renderable';
-import { PickingId } from '../../util/picking';
-import { createEmptyMarkers, MarkerAction } from '../../util/marker-data';
+import { PickingId } from '../../geometry/picking';
+import { MarkerAction } from '../../geometry/marker-data';
 import { Loci, EmptyLoci } from 'mol-model/loci';
-import { fillSerial } from 'mol-util/array';
-import { Color } from 'mol-util/color';
+import { LocationIterator } from '../../util/location-iterator';
+import { NullLocation } from 'mol-model/location';
+import { createIdentityTransform } from '../../geometry/transform-data';
+import { createRenderableState } from '../../geometry/geometry';
 
 export function computeVolumeSurface(volume: VolumeData, isoValue: VolumeIsoValue) {
     return Task.create<Mesh>('Volume Surface', async ctx => {
@@ -40,62 +37,32 @@ export function computeVolumeSurface(volume: VolumeData, isoValue: VolumeIsoValu
 }
 
 export const DefaultSurfaceProps = {
+    ...Mesh.DefaultProps,
     isoValue: VolumeIsoValue.relative({ min: 0, max: 0, mean: 0, sigma: 0 }, 0),
-    alpha: 0.5,
-    visible: true,
-    flatShaded: true,
-    flipSided: true,
-    doubleSided: true,
-    depthMask: true,
-    useFog: true
 }
-export type SurfaceProps = Partial<typeof DefaultSurfaceProps>
+export type SurfaceProps = typeof DefaultSurfaceProps
 
 export default function SurfaceVisual(): VolumeVisual<SurfaceProps> {
     let renderObject: MeshRenderObject
-    let curProps = DefaultSurfaceProps
+    let currentProps = DefaultSurfaceProps
 
     return {
         get renderObject () { return renderObject },
-        async createOrUpdate(ctx: RuntimeContext, props: SurfaceProps = {}, volume?: VolumeData) {
-            props = { ...DefaultSurfaceProps, ...props }
+        async createOrUpdate(ctx: RuntimeContext, props: Partial<SurfaceProps> = {}, volume?: VolumeData) {
+            currentProps = { ...DefaultSurfaceProps, ...props }
 
             if (!volume) return
 
-            const mesh = await computeVolumeSurface(volume, curProps.isoValue).runAsChild(ctx)
+            const mesh = await computeVolumeSurface(volume, currentProps.isoValue).runAsChild(ctx)
             if (!props.flatShaded) {
                 Mesh.computeNormalsImmediate(mesh)
             }
 
-            const instanceCount = 1
-            const color = createValueColor(Color(0x7ec0ee))
-            const marker = createEmptyMarkers()
+            const locationIt = LocationIterator(1, 1, () => NullLocation)
+            const transform = createIdentityTransform()
 
-            const values: MeshValues = {
-                ...getMeshData(mesh),
-                aTransform: ValueCell.create(new Float32Array(Mat4.identity())),
-                aInstance: ValueCell.create(fillSerial(new Float32Array(instanceCount))),
-                ...color,
-                ...marker,
-
-                uAlpha: ValueCell.create(defaults(props.alpha, 1.0)),
-                uInstanceCount: ValueCell.create(instanceCount),
-                uGroupCount: ValueCell.create(mesh.triangleCount),
-
-                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, true)),
-                dFlipSided: ValueCell.create(false),
-                dUseFog: ValueCell.create(defaults(props.useFog, true)),
-            }
-            const state: RenderableState = {
-                depthMask: defaults(props.depthMask, true),
-                visible: defaults(props.visible, true)
-            }
+            const values = await Mesh.createValues(ctx, mesh, transform, locationIt, currentProps)
+            const state = createRenderableState(currentProps)
 
             renderObject = createMeshRenderObject(values, state)
         },

+ 0 - 22
src/mol-geo/util/mesh-data.ts

@@ -1,22 +0,0 @@
-/**
- * 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 { Mesh } from '../geometry/mesh/mesh';
-
-type MeshData = {
-    aPosition: ValueCell<Float32Array>,
-    aNormal: ValueCell<Float32Array>,
-    aGroup: ValueCell<Float32Array>,
-}
-
-export function getMeshData(mesh: Mesh): MeshData {
-    return {
-        aPosition: mesh.vertexBuffer,
-        aNormal: mesh.normalBuffer,
-        aGroup: mesh.groupBuffer,
-    }
-}

+ 0 - 20
src/mol-geo/util/point-data.ts

@@ -1,20 +0,0 @@
-/**
- * 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 { Point } from '../geometry/point/point';
-
-type PointData = {
-    aPosition: ValueCell<Float32Array>,
-    aGroup: ValueCell<Float32Array>,
-}
-
-export function getPointData(point: Point): PointData {
-    return {
-        aPosition: point.vertexBuffer,
-        aGroup: point.groupBuffer,
-    }
-}

+ 3 - 3
src/mol-gl/_spec/renderer.spec.ts

@@ -11,14 +11,14 @@ import { Vec3, Mat4 } from 'mol-math/linear-algebra';
 import { ValueCell } from 'mol-util';
 
 import Renderer from '../renderer';
-import { createValueColor } from 'mol-geo/util/color-data';
-import { createValueSize } from 'mol-geo/util/size-data';
+import { createValueColor } from 'mol-geo/geometry/color-data';
+import { createValueSize } from 'mol-geo/geometry/size-data';
 import { createContext } from '../webgl/context';
 import { RenderableState } from '../renderable';
 import { createPointRenderObject } from '../render-object';
 import { PointValues } from '../renderable/point';
 import Scene from '../scene';
-import { createEmptyMarkers } from 'mol-geo/util/marker-data';
+import { createEmptyMarkers } from 'mol-geo/geometry/marker-data';
 import { fillSerial } from 'mol-util/array';
 import { Color } from 'mol-util/color';
 

+ 1 - 1
src/mol-view/theme/color.ts

@@ -7,7 +7,7 @@
 import { Color } from 'mol-util/color';
 import { Structure } from 'mol-model/structure';
 import { Location } from 'mol-model/location';
-import { ColorType } from 'mol-geo/util/color-data';
+import { ColorType } from 'mol-geo/geometry/color-data';
 
 import { ElementIndexColorTheme } from './color/element-index';
 import { CarbohydrateSymbolColorTheme } from './color/carbohydrate-symbol';

+ 1 - 1
src/mol-view/theme/size.ts

@@ -5,7 +5,7 @@
  */
 
 import { Structure } from 'mol-model/structure';
-import { SizeType, LocationSize } from 'mol-geo/util/size-data';
+import { SizeType, LocationSize } from 'mol-geo/geometry/size-data';
 
 import { PhysicalSizeTheme } from './size/physical';
 import { UniformSizeTheme } from './size/uniform';

+ 2 - 2
src/mol-view/viewer.ts

@@ -21,8 +21,8 @@ import { Representation } from 'mol-geo/representation';
 import { createRenderTarget } from 'mol-gl/webgl/render-target';
 import Scene from 'mol-gl/scene';
 import { RenderVariant } from 'mol-gl/webgl/render-item';
-import { PickingId, decodeIdRGBA } from 'mol-geo/util/picking';
-import { MarkerAction } from 'mol-geo/util/marker-data';
+import { PickingId, decodeIdRGBA } from 'mol-geo/geometry/picking';
+import { MarkerAction } from 'mol-geo/geometry/marker-data';
 import { Loci, EmptyLoci, isEmptyLoci } from 'mol-model/loci';
 import { Color } from 'mol-util/color';