Browse Source

wip, structure visuals refactoring

Alexander Rose 6 years ago
parent
commit
0101a49cc1

+ 6 - 27
src/mol-geo/representation/structure/visual/carbohydrate-link-cylinder.ts

@@ -6,19 +6,17 @@
 
 import { ValueCell } from 'mol-util/value-cell'
 
-import { createMeshRenderObject, MeshRenderObject } from 'mol-gl/render-object'
+import { MeshRenderObject } from 'mol-gl/render-object'
 import { Unit, Structure, Link, StructureElement } from 'mol-model/structure';
 import { DefaultStructureProps, StructureVisual } from '..';
 import { RuntimeContext } from 'mol-task'
-import { createIdentityTransform, createColors } from './util/common';
-import { MeshValues } from 'mol-gl/renderable';
-import { getMeshData } from '../../../util/mesh-data';
+import { createColors, createStructureMeshRenderObject } from './util/common';
 import { Mesh } from '../../../shape/mesh';
 import { PickingId } from '../../../util/picking';
-import { createMarkers, MarkerAction, MarkerData, applyMarkerAction } from '../../../util/marker-data';
+import { MarkerAction, MarkerData, applyMarkerAction } from '../../../util/marker-data';
 import { Loci, EmptyLoci, isEveryLoci } from 'mol-model/loci';
 import { SizeTheme } from '../../../theme';
-import { createMeshValues, updateMeshValues, updateRenderableState, createRenderableState, DefaultMeshProps } from '../../util';
+import { updateMeshValues, updateRenderableState, DefaultMeshProps } from '../../util';
 import { Vec3 } from 'mol-math/linear-algebra';
 import { deepEqual } from 'mol-util';
 import { LocationIterator } from './util/location-iterator';
@@ -77,29 +75,10 @@ export function CarbohydrateLinkVisual(): StructureVisual<CarbohydrateLinkProps>
             currentProps = Object.assign({}, DefaultCarbohydrateLinkProps, props)
             currentStructure = structure
 
-            const { colorTheme } = { ...DefaultCarbohydrateLinkProps, ...props }
-            const elementCount = structure.carbohydrates.links.length
-            const instanceCount = 1
-
             mesh = await createCarbohydrateLinkCylinderMesh(ctx, currentStructure, currentProps, mesh)
 
-            const transforms = createIdentityTransform()
-            const color = createColors(CarbohydrateLinkIterator(structure), colorTheme)
-            const marker = createMarkers(instanceCount * elementCount)
-
-            const counts = { drawCount: mesh.triangleCount * 3, elementCount, instanceCount }
-
-            const values: MeshValues = {
-                ...getMeshData(mesh),
-                ...color,
-                ...marker,
-                aTransform: transforms,
-                elements: mesh.indexBuffer,
-                ...createMeshValues(currentProps, counts)
-            }
-            const state = createRenderableState(currentProps)
-
-            renderObject = createMeshRenderObject(values, state)
+            const locationIt = CarbohydrateLinkIterator(structure)
+            renderObject = createStructureMeshRenderObject(structure, mesh, locationIt, currentProps)
         },
         async update(ctx: RuntimeContext, props: CarbohydrateLinkProps) {
             const newProps = Object.assign({}, currentProps, props)

+ 6 - 27
src/mol-geo/representation/structure/visual/carbohydrate-symbol-mesh.ts

@@ -6,19 +6,17 @@
 
 import { ValueCell } from 'mol-util/value-cell'
 
-import { createMeshRenderObject, MeshRenderObject } from 'mol-gl/render-object'
+import { MeshRenderObject } from 'mol-gl/render-object'
 import { Unit, Structure, StructureElement } from 'mol-model/structure';
 import { DefaultStructureProps, StructureVisual } from '..';
 import { RuntimeContext } from 'mol-task'
-import { createIdentityTransform, createColors } from './util/common';
-import { MeshValues } from 'mol-gl/renderable';
-import { getMeshData } from '../../../util/mesh-data';
+import { createColors, createStructureMeshRenderObject } from './util/common';
 import { Mesh } from '../../../shape/mesh';
 import { PickingId } from '../../../util/picking';
-import { createMarkers, MarkerAction, MarkerData, applyMarkerAction } from '../../../util/marker-data';
+import { MarkerAction, MarkerData, applyMarkerAction } from '../../../util/marker-data';
 import { Loci, EmptyLoci, isEveryLoci } from 'mol-model/loci';
 import { SizeTheme } from '../../../theme';
-import { createMeshValues, updateMeshValues, updateRenderableState, createRenderableState, DefaultMeshProps } from '../../util';
+import { updateMeshValues, updateRenderableState, DefaultMeshProps } from '../../util';
 import { MeshBuilder } from '../../../shape/mesh-builder';
 import { Vec3, Mat4 } from 'mol-math/linear-algebra';
 import { getSaccharideShape, SaccharideShapes } from 'mol-model/structure/structure/carbohydrates/constants';
@@ -140,29 +138,10 @@ export function CarbohydrateSymbolVisual(): StructureVisual<CarbohydrateSymbolPr
             currentProps = Object.assign({}, DefaultCarbohydrateSymbolProps, props)
             currentStructure = structure
 
-            const { colorTheme } = { ...DefaultCarbohydrateSymbolProps, ...props }
-            const instanceCount = 1
-            const elementCount = currentStructure.elementCount
-
             mesh = await createCarbohydrateSymbolMesh(ctx, currentStructure, mesh)
 
-            const transforms = createIdentityTransform()
-            const color = createColors(CarbohydrateElementIterator(structure), colorTheme)
-            const marker = createMarkers(instanceCount * elementCount)
-
-            const counts = { drawCount: mesh.triangleCount * 3, elementCount, instanceCount }
-
-            const values: MeshValues = {
-                ...getMeshData(mesh),
-                ...color,
-                ...marker,
-                aTransform: transforms,
-                elements: mesh.indexBuffer,
-                ...createMeshValues(currentProps, counts)
-            }
-            const state = createRenderableState(currentProps)
-
-            renderObject = createMeshRenderObject(values, state)
+            const locationIt = CarbohydrateElementIterator(structure)
+            renderObject = createStructureMeshRenderObject(structure, mesh, locationIt, currentProps)
         },
         async update(ctx: RuntimeContext, props: CarbohydrateSymbolProps) {
             const newProps = Object.assign({}, currentProps, props)

+ 7 - 26
src/mol-geo/representation/structure/visual/element-sphere.ts

@@ -7,21 +7,19 @@
 
 import { ValueCell } from 'mol-util/value-cell'
 
-import { createMeshRenderObject, MeshRenderObject } from 'mol-gl/render-object'
+import { MeshRenderObject } from 'mol-gl/render-object'
 import { Unit } from 'mol-model/structure';
 import { DefaultStructureProps, UnitsVisual } from '..';
 import { RuntimeContext } from 'mol-task'
-import { createTransforms, createColors } from './util/common';
+import { createColors, createUnitsMeshRenderObject } from './util/common';
 import { createElementSphereMesh, markElement, getElementRadius, getElementLoci } from './util/element';
 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';
-import { createMarkers, MarkerAction } from '../../../util/marker-data';
+import { MarkerAction } from '../../../util/marker-data';
 import { Loci } from 'mol-model/loci';
 import { SizeTheme } from '../../../theme';
-import { createMeshValues, updateMeshValues, updateRenderableState, createRenderableState, DefaultMeshProps } from '../../util';
+import { updateMeshValues, updateRenderableState, DefaultMeshProps } from '../../util';
 import { StructureElementIterator } from './util/location-iterator';
 
 export const DefaultElementSphereProps = {
@@ -45,9 +43,7 @@ export function ElementSphereVisual(): UnitsVisual<ElementSphereProps> {
             currentProps = Object.assign({}, DefaultElementSphereProps, props)
             currentGroup = group
 
-            const { detail, colorTheme, sizeTheme, unitKinds } = { ...DefaultElementSphereProps, ...props }
-            const instanceCount = group.units.length
-            const elementCount = group.elements.length
+            const { detail, sizeTheme, unitKinds } = { ...DefaultElementSphereProps, ...props }
             const unit = group.units[0]
 
             const radius = getElementRadius(unit, sizeTheme)
@@ -55,23 +51,8 @@ export function ElementSphereVisual(): UnitsVisual<ElementSphereProps> {
                 ? await createElementSphereMesh(ctx, unit, radius, detail, mesh)
                 : Mesh.createEmpty(mesh)
 
-            const transforms = createTransforms(group)
-            const color = createColors(StructureElementIterator.fromGroup(group), colorTheme)
-            const marker = createMarkers(instanceCount * elementCount)
-
-            const counts = { drawCount: mesh.triangleCount * 3, elementCount, instanceCount }
-
-            const values: MeshValues = {
-                ...getMeshData(mesh),
-                ...color,
-                ...marker,
-                aTransform: transforms,
-                elements: mesh.indexBuffer,
-                ...createMeshValues(currentProps, counts),
-            }
-            const state = createRenderableState(currentProps)
-
-            renderObject = createMeshRenderObject(values, state)
+            const locationIt = StructureElementIterator.fromGroup(group)
+            renderObject = createUnitsMeshRenderObject(group, mesh, locationIt, currentProps)
         },
         async update(ctx: RuntimeContext, props: ElementSphereProps) {
             const newProps = Object.assign({}, currentProps, props)

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

@@ -6,21 +6,19 @@
 
 import { ValueCell } from 'mol-util/value-cell'
 
-import { createMeshRenderObject, MeshRenderObject } from 'mol-gl/render-object'
+import { MeshRenderObject } from 'mol-gl/render-object'
 import { Link, Structure, StructureElement } from 'mol-model/structure';
 import { DefaultStructureProps, StructureVisual } from '..';
 import { RuntimeContext } from 'mol-task'
 import { LinkCylinderProps, DefaultLinkCylinderProps, createLinkCylinderMesh } from './util/link';
-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 { Loci, isEveryLoci, EmptyLoci } from 'mol-model/loci';
-import { MarkerAction, applyMarkerAction, createMarkers, MarkerData } from '../../../util/marker-data';
+import { MarkerAction, applyMarkerAction, MarkerData } from '../../../util/marker-data';
 import { SizeTheme } from '../../../theme';
-import { createIdentityTransform, createColors } from './util/common';
-import { updateMeshValues, updateRenderableState, createMeshValues, createRenderableState } from '../../util';
+import { createColors, createStructureMeshRenderObject } from './util/common';
+import { updateMeshValues, updateRenderableState } from '../../util';
 import { LinkIterator } from './util/location-iterator';
 import { deepEqual } from 'mol-util';
 
@@ -65,29 +63,10 @@ export function InterUnitLinkVisual(): StructureVisual<InterUnitLinkProps> {
             currentProps = Object.assign({}, DefaultInterUnitLinkProps, props)
             currentStructure = structure
 
-            const { colorTheme } = { ...DefaultInterUnitLinkProps, ...props }
-            const elementCount = structure.links.bondCount
-            const instanceCount = 1
-
             mesh = await createInterUnitLinkCylinderMesh(ctx, structure, currentProps)
 
-            const transforms = createIdentityTransform()
-            const color = createColors(LinkIterator.fromStructure(structure), colorTheme) // TODO
-            const marker = createMarkers(instanceCount * elementCount)
-
-            const counts = { drawCount: mesh.triangleCount * 3, elementCount, instanceCount }
-
-            const values: MeshValues = {
-                ...getMeshData(mesh),
-                ...color,
-                ...marker,
-                aTransform: transforms,
-                elements: mesh.indexBuffer,
-                ...createMeshValues(currentProps, counts),
-            }
-            const state = createRenderableState(currentProps)
-
-            renderObject = createMeshRenderObject(values, state)
+            const locationIt = LinkIterator.fromStructure(structure)
+            renderObject = createStructureMeshRenderObject(structure, mesh, locationIt, currentProps)
         },
         async update(ctx: RuntimeContext, props: InterUnitLinkProps) {
             const newProps = Object.assign({}, currentProps, props)

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

@@ -7,22 +7,20 @@
 
 import { ValueCell } from 'mol-util/value-cell'
 
-import { createMeshRenderObject, MeshRenderObject } from 'mol-gl/render-object'
+import { MeshRenderObject } from 'mol-gl/render-object'
 import { Unit, Link, StructureElement } from 'mol-model/structure';
 import { UnitsVisual, DefaultStructureProps } from '..';
 import { RuntimeContext } from 'mol-task'
 import { DefaultLinkCylinderProps, LinkCylinderProps, createLinkCylinderMesh } from './util/link';
-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 { Loci, isEveryLoci, EmptyLoci } from 'mol-model/loci';
-import { MarkerAction, applyMarkerAction, createMarkers, MarkerData } from '../../../util/marker-data';
+import { MarkerAction, applyMarkerAction, MarkerData } from '../../../util/marker-data';
 import { SizeTheme } from '../../../theme';
-import { createTransforms, createColors } from './util/common';
-import { createMeshValues, createRenderableState, updateMeshValues, updateRenderableState, DefaultMeshProps } from '../../util';
+import { createColors, createUnitsMeshRenderObject } from './util/common';
+import { updateMeshValues, updateRenderableState, DefaultMeshProps } from '../../util';
 import { LinkIterator } from './util/location-iterator';
 import { deepEqual } from 'mol-util';
 
@@ -83,30 +81,11 @@ export function IntraUnitLinkVisual(): UnitsVisual<IntraUnitLinkProps> {
             currentProps = Object.assign({}, DefaultIntraUnitLinkProps, props)
             currentGroup = group
 
-            const { colorTheme } = { ...DefaultIntraUnitLinkProps, ...props }
             const unit = group.units[0]
-            const elementCount = Unit.isAtomic(unit) ? unit.links.edgeCount * 2 : 0
-            const instanceCount = group.units.length
-
             mesh = await createIntraUnitLinkCylinderMesh(ctx, unit, currentProps)
 
-            const transforms = createTransforms(group)
-            const color = createColors(LinkIterator.fromGroup(currentGroup), colorTheme)
-            const marker = createMarkers(instanceCount * elementCount)
-
-            const counts = { drawCount: mesh.triangleCount * 3, elementCount, instanceCount }
-
-            const values: MeshValues = {
-                ...getMeshData(mesh),
-                ...color,
-                ...marker,
-                aTransform: transforms,
-                elements: mesh.indexBuffer,
-                ...createMeshValues(currentProps, counts),
-            }
-            const state = createRenderableState(currentProps)
-
-            renderObject = createMeshRenderObject(values, state)
+            const locationIt = LinkIterator.fromGroup(group)
+            renderObject = createUnitsMeshRenderObject(group, mesh, locationIt, currentProps)
         },
         async update(ctx: RuntimeContext, props: IntraUnitLinkProps) {
             const newProps = Object.assign({}, currentProps, props)

+ 7 - 28
src/mol-geo/representation/structure/visual/nucleotide-block-mesh.ts

@@ -6,20 +6,18 @@
 
 import { ValueCell } from 'mol-util/value-cell'
 
-import { createMeshRenderObject, MeshRenderObject } from 'mol-gl/render-object'
+import { MeshRenderObject } from 'mol-gl/render-object'
 import { Unit } from 'mol-model/structure';
 import { DefaultStructureProps, UnitsVisual } from '..';
 import { RuntimeContext } from 'mol-task'
-import { createTransforms, createColors } from './util/common';
+import { createColors, createUnitsMeshRenderObject } from './util/common';
 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';
-import { createMarkers, MarkerAction } from '../../../util/marker-data';
+import { MarkerAction } from '../../../util/marker-data';
 import { Loci } from 'mol-model/loci';
 import { SizeTheme } from '../../../theme';
-import { createMeshValues, updateMeshValues, updateRenderableState, createRenderableState, DefaultMeshProps } from '../../util';
+import { updateMeshValues, updateRenderableState, DefaultMeshProps } from '../../util';
 import { MeshBuilder } from '../../../shape/mesh-builder';
 import { getElementLoci, markElement } from './util/element';
 import { Vec3, Mat4 } from 'mol-math/linear-algebra';
@@ -135,34 +133,15 @@ export function NucleotideBlockVisual(): UnitsVisual<NucleotideBlockProps> {
             currentProps = Object.assign({}, DefaultNucleotideBlockProps, props)
             currentGroup = group
 
-            const { colorTheme, unitKinds } = { ...DefaultNucleotideBlockProps, ...props }
-            const instanceCount = group.units.length
-            const elementCount = group.elements.length
+            const { unitKinds } = { ...DefaultNucleotideBlockProps, ...props }
             const unit = group.units[0]
 
             mesh = unitKinds.includes(unit.kind)
                 ? await createNucleotideBlockMesh(ctx, unit, mesh)
                 : Mesh.createEmpty(mesh)
-            // console.log(mesh)
-
-            const transforms = createTransforms(group)
-            const color = createColors(StructureElementIterator.fromGroup(group), colorTheme)
-            const marker = createMarkers(instanceCount * elementCount)
-
-            const counts = { drawCount: mesh.triangleCount * 3, elementCount, instanceCount }
-
-            const values: MeshValues = {
-                ...getMeshData(mesh),
-                ...color,
-                ...marker,
-                aTransform: transforms,
-                elements: mesh.indexBuffer,
-                ...createMeshValues(currentProps, counts),
-                aColor: ValueCell.create(new Float32Array(mesh.vertexCount * 3))
-            }
-            const state = createRenderableState(currentProps)
 
-            renderObject = createMeshRenderObject(values, state)
+            const locationIt = StructureElementIterator.fromGroup(group)
+            renderObject = createUnitsMeshRenderObject(group, mesh, locationIt, currentProps)
         },
         async update(ctx: RuntimeContext, props: NucleotideBlockProps) {
             const newProps = Object.assign({}, currentProps, props)

+ 7 - 28
src/mol-geo/representation/structure/visual/polymer-backbone-cylinder.ts

@@ -6,20 +6,18 @@
 
 import { ValueCell } from 'mol-util/value-cell'
 
-import { createMeshRenderObject, MeshRenderObject } from 'mol-gl/render-object'
+import { MeshRenderObject } from 'mol-gl/render-object'
 import { Unit } from 'mol-model/structure';
 import { DefaultStructureProps, UnitsVisual } from '..';
 import { RuntimeContext } from 'mol-task'
-import { createTransforms, createColors } from './util/common';
+import { createColors, createUnitsMeshRenderObject } from './util/common';
 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';
-import { createMarkers, MarkerAction } from '../../../util/marker-data';
+import { MarkerAction } from '../../../util/marker-data';
 import { Loci } from 'mol-model/loci';
 import { SizeTheme } from '../../../theme';
-import { createMeshValues, updateMeshValues, updateRenderableState, createRenderableState, DefaultMeshProps } from '../../util';
+import { updateMeshValues, updateRenderableState, DefaultMeshProps } from '../../util';
 import { MeshBuilder } from '../../../shape/mesh-builder';
 import { getPolymerElementCount, PolymerBackboneIterator } from './util/polymer';
 import { getElementLoci, markElement } from './util/element';
@@ -81,34 +79,15 @@ export function PolymerBackboneVisual(): UnitsVisual<PolymerBackboneProps> {
             currentProps = Object.assign({}, DefaultPolymerBackboneProps, props)
             currentGroup = group
 
-            const { colorTheme, unitKinds } = { ...DefaultPolymerBackboneProps, ...props }
-            const instanceCount = group.units.length
-            const elementCount = group.elements.length
+            const { unitKinds } = { ...DefaultPolymerBackboneProps, ...props }
             const unit = group.units[0]
 
             mesh = unitKinds.includes(unit.kind)
                 ? await createPolymerBackboneCylinderMesh(ctx, unit, mesh)
                 : Mesh.createEmpty(mesh)
-            // console.log(mesh)
-
-            const transforms = createTransforms(group)
-            const color = createColors(StructureElementIterator.fromGroup(group), colorTheme)
-            const marker = createMarkers(instanceCount * elementCount)
-
-            const counts = { drawCount: mesh.triangleCount * 3, elementCount, instanceCount }
-
-            const values: MeshValues = {
-                ...getMeshData(mesh),
-                ...color,
-                ...marker,
-                aTransform: transforms,
-                elements: mesh.indexBuffer,
-                ...createMeshValues(currentProps, counts),
-                aColor: ValueCell.create(new Float32Array(mesh.vertexCount * 3))
-            }
-            const state = createRenderableState(currentProps)
 
-            renderObject = createMeshRenderObject(values, state)
+            const locationIt = StructureElementIterator.fromGroup(group)
+            renderObject = createUnitsMeshRenderObject(group, mesh, locationIt, currentProps)
         },
         async update(ctx: RuntimeContext, props: PolymerBackboneProps) {
             const newProps = Object.assign({}, currentProps, props)

+ 7 - 26
src/mol-geo/representation/structure/visual/polymer-direction-wedge.ts

@@ -6,22 +6,20 @@
 
 import { ValueCell } from 'mol-util/value-cell'
 
-import { createMeshRenderObject, MeshRenderObject } from 'mol-gl/render-object'
+import { MeshRenderObject } from 'mol-gl/render-object'
 import { Unit, StructureElement } from 'mol-model/structure';
 import { DefaultStructureProps, UnitsVisual } from '..';
 import { RuntimeContext } from 'mol-task'
-import { createTransforms, createColors } from './util/common';
+import { createColors, createUnitsMeshRenderObject } from './util/common';
 import { markElement } from './util/element';
 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';
 import { OrderedSet } from 'mol-data/int';
-import { createMarkers, MarkerAction } from '../../../util/marker-data';
+import { MarkerAction } from '../../../util/marker-data';
 import { Loci, EmptyLoci } from 'mol-model/loci';
 import { SizeTheme } from '../../../theme';
-import { createMeshValues, updateMeshValues, updateRenderableState, createRenderableState, DefaultMeshProps } from '../../util';
+import { updateMeshValues, updateRenderableState, DefaultMeshProps } from '../../util';
 import { MeshBuilder } from '../../../shape/mesh-builder';
 import { getPolymerElementCount, PolymerTraceIterator, createCurveSegmentState, interpolateCurveSegment } from './util/polymer';
 import { Vec3, Mat4 } from 'mol-math/linear-algebra';
@@ -109,32 +107,15 @@ export function PolymerDirectionVisual(): UnitsVisual<PolymerDirectionProps> {
             currentProps = Object.assign({}, DefaultPolymerDirectionProps, props)
             currentGroup = group
 
-            const { colorTheme, unitKinds } = { ...DefaultPolymerDirectionProps, ...props }
-            const instanceCount = group.units.length
-            const elementCount = group.elements.length
+            const { unitKinds } = { ...DefaultPolymerDirectionProps, ...props }
             const unit = group.units[0]
 
             mesh = unitKinds.includes(unit.kind)
                 ? await createPolymerDirectionWedgeMesh(ctx, unit, mesh)
                 : Mesh.createEmpty(mesh)
 
-            const transforms = createTransforms(group)
-            const color = createColors(StructureElementIterator.fromGroup(group), colorTheme)
-            const marker = createMarkers(instanceCount * elementCount)
-
-            const counts = { drawCount: mesh.triangleCount * 3, elementCount, instanceCount }
-
-            const values: MeshValues = {
-                ...getMeshData(mesh),
-                ...color,
-                ...marker,
-                aTransform: transforms,
-                elements: mesh.indexBuffer,
-                ...createMeshValues(currentProps, counts),
-            }
-            const state = createRenderableState(currentProps)
-
-            renderObject = createMeshRenderObject(values, state)
+            const locationIt = StructureElementIterator.fromGroup(group)
+            renderObject = createUnitsMeshRenderObject(group, mesh, locationIt, currentProps)
         },
         async update(ctx: RuntimeContext, props: PolymerDirectionProps) {
             const newProps = Object.assign({}, currentProps, props)

+ 7 - 28
src/mol-geo/representation/structure/visual/polymer-gap-cylinder.ts

@@ -6,20 +6,18 @@
 
 import { ValueCell } from 'mol-util/value-cell'
 
-import { createMeshRenderObject, MeshRenderObject } from 'mol-gl/render-object'
+import { MeshRenderObject } from 'mol-gl/render-object'
 import { Unit } from 'mol-model/structure';
 import { DefaultStructureProps, UnitsVisual } from '..';
 import { RuntimeContext } from 'mol-task'
-import { createTransforms, createColors } from './util/common';
+import { createColors, createUnitsMeshRenderObject } from './util/common';
 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';
-import { createMarkers, MarkerAction } from '../../../util/marker-data';
+import { MarkerAction } from '../../../util/marker-data';
 import { Loci } from 'mol-model/loci';
 import { SizeTheme } from '../../../theme';
-import { createMeshValues, updateMeshValues, updateRenderableState, createRenderableState, DefaultMeshProps } from '../../util';
+import { updateMeshValues, updateRenderableState, DefaultMeshProps } from '../../util';
 import { MeshBuilder } from '../../../shape/mesh-builder';
 import { getPolymerGapCount, PolymerGapIterator } from './util/polymer';
 import { getElementLoci, markElement } from './util/element';
@@ -87,34 +85,15 @@ export function PolymerGapVisual(): UnitsVisual<PolymerGapProps> {
             currentProps = Object.assign({}, DefaultPolymerGapProps, props)
             currentGroup = group
 
-            const { colorTheme, unitKinds } = { ...DefaultPolymerGapProps, ...props }
-            const instanceCount = group.units.length
-            const elementCount = group.elements.length
+            const { unitKinds } = { ...DefaultPolymerGapProps, ...props }
             const unit = group.units[0]
 
             mesh = unitKinds.includes(unit.kind)
                 ? await createPolymerGapCylinderMesh(ctx, unit, mesh)
                 : Mesh.createEmpty(mesh)
-            // console.log(mesh)
-
-            const transforms = createTransforms(group)
-            const color = createColors(StructureElementIterator.fromGroup(group), colorTheme)
-            const marker = createMarkers(instanceCount * elementCount)
-
-            const counts = { drawCount: mesh.triangleCount * 3, elementCount, instanceCount }
-
-            const values: MeshValues = {
-                ...getMeshData(mesh),
-                ...color,
-                ...marker,
-                aTransform: transforms,
-                elements: mesh.indexBuffer,
-                ...createMeshValues(currentProps, counts),
-                aColor: ValueCell.create(new Float32Array(mesh.vertexCount * 3))
-            }
-            const state = createRenderableState(currentProps)
 
-            renderObject = createMeshRenderObject(values, state)
+            const locationIt = StructureElementIterator.fromGroup(group)
+            renderObject = createUnitsMeshRenderObject(group, mesh, locationIt, currentProps)
         },
         async update(ctx: RuntimeContext, props: PolymerGapProps) {
             const newProps = Object.assign({}, currentProps, props)

+ 7 - 26
src/mol-geo/representation/structure/visual/polymer-trace-mesh.ts

@@ -6,22 +6,20 @@
 
 import { ValueCell } from 'mol-util/value-cell'
 
-import { createMeshRenderObject, MeshRenderObject } from 'mol-gl/render-object'
+import { MeshRenderObject } from 'mol-gl/render-object'
 import { Unit, StructureElement } from 'mol-model/structure';
 import { DefaultStructureProps, UnitsVisual } from '..';
 import { RuntimeContext } from 'mol-task'
-import { createTransforms, createColors } from './util/common';
+import { createColors, createUnitsMeshRenderObject } from './util/common';
 import { markElement } from './util/element';
 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';
 import { OrderedSet } from 'mol-data/int';
-import { createMarkers, MarkerAction } from '../../../util/marker-data';
+import { MarkerAction } from '../../../util/marker-data';
 import { Loci, EmptyLoci } from 'mol-model/loci';
 import { SizeTheme } from '../../../theme';
-import { createMeshValues, updateMeshValues, updateRenderableState, createRenderableState, DefaultMeshProps } from '../../util';
+import { updateMeshValues, updateRenderableState, DefaultMeshProps } from '../../util';
 import { MeshBuilder } from '../../../shape/mesh-builder';
 import { getPolymerElementCount, PolymerTraceIterator, createCurveSegmentState, interpolateCurveSegment } from './util/polymer';
 import { SecondaryStructureType, MoleculeType } from 'mol-model/structure/model/types';
@@ -102,32 +100,15 @@ export function PolymerTraceVisual(): UnitsVisual<PolymerTraceProps> {
             currentProps = Object.assign({}, DefaultPolymerTraceProps, props)
             currentGroup = group
 
-            const { colorTheme, unitKinds } = { ...DefaultPolymerTraceProps, ...props }
-            const instanceCount = group.units.length
-            const elementCount = group.elements.length
+            const { unitKinds } = { ...DefaultPolymerTraceProps, ...props }
             const unit = group.units[0]
 
             mesh = unitKinds.includes(unit.kind)
                 ? await createPolymerTraceMesh(ctx, unit, mesh)
                 : Mesh.createEmpty(mesh)
 
-            const transforms = createTransforms(group)
-            const color = createColors(StructureElementIterator.fromGroup(group), colorTheme)
-            const marker = createMarkers(instanceCount * elementCount)
-
-            const counts = { drawCount: mesh.triangleCount * 3, elementCount, instanceCount }
-
-            const values: MeshValues = {
-                ...getMeshData(mesh),
-                ...color,
-                ...marker,
-                aTransform: transforms,
-                elements: mesh.indexBuffer,
-                ...createMeshValues(currentProps, counts),
-            }
-            const state = createRenderableState(currentProps)
-
-            renderObject = createMeshRenderObject(values, state)
+            const locationIt = StructureElementIterator.fromGroup(group)
+            renderObject = createUnitsMeshRenderObject(group, mesh, locationIt, currentProps)
         },
         async update(ctx: RuntimeContext, props: PolymerTraceProps) {
             const newProps = Object.assign({}, currentProps, props)

+ 49 - 13
src/mol-geo/representation/structure/visual/util/common.ts

@@ -5,7 +5,7 @@
  * @author David Sehnal <david.sehnal@gmail.com>
  */
 
-import { Unit } from 'mol-model/structure';
+import { Unit, Structure } from 'mol-model/structure';
 import { Mat4 } from 'mol-math/linear-algebra'
 
 import { createUniformColor, ColorData } from '../../../../util/color-data';
@@ -17,6 +17,13 @@ import { elementIndexColorData, elementSymbolColorData, instanceIndexColorData,
 import { ValueCell, defaults } from 'mol-util';
 import { LocationIterator } from './location-iterator';
 import { carbohydrateSymbolColorData } from '../../../../theme/structure/color/carbohydrate-symbol';
+import { Mesh } from '../../../../shape/mesh';
+import { MeshValues } from 'mol-gl/renderable';
+import { getMeshData } from '../../../../util/mesh-data';
+import { MeshProps, createMeshValues, createRenderableState } from '../../../util';
+import { StructureProps } from '../..';
+import { createMarkers } from '../../../../util/marker-data';
+import { createMeshRenderObject } from 'mol-gl/render-object';
 
 export function createTransforms({ units }: Unit.SymmetryGroup, transforms?: ValueCell<Float32Array>) {
     const unitCount = units.length
@@ -51,18 +58,6 @@ export function createColors(locationIt: LocationIterator, props: ColorTheme, co
     }
 }
 
-// export function createLinkColors(group: Unit.SymmetryGroup, props: ColorTheme, colorData?: ColorData): ColorData {
-//     switch (props.name) {
-//         case 'atom-index':
-//         case 'chain-id':
-//         case 'element-symbol':
-//         case 'instance-index':
-//             return chainIdLinkColorData({ group, vertexMap }, colorData)
-//         case 'uniform':
-//             return createUniformColor(props, colorData)
-//     }
-// }
-
 export function createSizes(group: Unit.SymmetryGroup, vertexMap: VertexMap, props: SizeTheme): SizeData {
     switch (props.name) {
         case 'uniform':
@@ -70,4 +65,45 @@ export function createSizes(group: Unit.SymmetryGroup, vertexMap: VertexMap, pro
         case 'physical':
             return physicalSizeData(defaults(props.factor, 1), { group, vertexMap })
     }
+}
+
+type StructureMeshProps = Required<MeshProps & StructureProps>
+
+function _createMeshValues(transforms: ValueCell<Float32Array>, mesh: Mesh, locationIt: LocationIterator, props: StructureMeshProps): MeshValues {
+    const { instanceCount, elementCount } = locationIt
+    const color = createColors(locationIt, props.colorTheme)
+    const marker = createMarkers(instanceCount * elementCount)
+
+    const counts = { drawCount: mesh.triangleCount * 3, elementCount, instanceCount }
+
+    return {
+        ...getMeshData(mesh),
+        ...color,
+        ...marker,
+        aTransform: transforms,
+        elements: mesh.indexBuffer,
+        ...createMeshValues(props, counts)
+    }
+}
+
+export function createStructureMeshValues(structure: Structure, mesh: Mesh, locationIt: LocationIterator, props: StructureMeshProps): MeshValues {
+    const transforms = createIdentityTransform()
+    return _createMeshValues(transforms, mesh, locationIt, props)
+}
+
+export function createUnitsMeshValues(group: Unit.SymmetryGroup, mesh: Mesh, locationIt: LocationIterator, props: StructureMeshProps): MeshValues {
+    const transforms = createTransforms(group)
+    return _createMeshValues(transforms, mesh, locationIt, props)
+}
+
+export function createStructureMeshRenderObject(structure: Structure, mesh: Mesh, locationIt: LocationIterator, props: StructureMeshProps) {
+    const values = createStructureMeshValues(structure, mesh, locationIt, props)
+    const state = createRenderableState(props)
+    return createMeshRenderObject(values, state)
+}
+
+export function createUnitsMeshRenderObject(group: Unit.SymmetryGroup, mesh: Mesh, locationIt: LocationIterator, props: StructureMeshProps) {
+    const values = createUnitsMeshValues(group, mesh, locationIt, props)
+    const state = createRenderableState(props)
+    return createMeshRenderObject(values, state)
 }