diff --git a/src/apps/render-test/state.ts b/src/apps/render-test/state.ts
index 4e6453fdc9f91a71229686cd67ef7d95fe3e0511..212a941cbe4fcf02a0060200e61ba268cfe67eb0 100644
--- a/src/apps/render-test/state.ts
+++ b/src/apps/render-test/state.ts
@@ -13,8 +13,8 @@ import Viewer from 'mol-view/viewer'
 // import { createColorTexture } from 'mol-gl/util';
 // import Icosahedron from 'mol-geo/primitive/icosahedron'
 // import Box from 'mol-geo/primitive/box'
-import Spacefill from 'mol-geo/representation/structure/spacefill'
-import Point from 'mol-geo/representation/structure/point'
+import Spacefill, { SpacefillProps } from 'mol-geo/representation/structure/spacefill'
+import Point, { PointProps } from 'mol-geo/representation/structure/point'
 
 import { Run } from 'mol-task'
 import { Symmetry } from 'mol-model/structure'
@@ -48,11 +48,22 @@ export default class State {
         const struct = await Run(Symmetry.buildAssembly(structures[0], '1'), log, 100)
 
         const structPointRepr = StructureRepresentation(Point)
-        await Run(structPointRepr.create(struct), log, 100)
+        const pointProps: PointProps = {
+            colorTheme: { name: 'uniform', value: 0xFF4411 },
+            sizeTheme: { name: 'uniform', value: 0.1 }
+        }
+        await Run(structPointRepr.create(struct, pointProps), log, 100)
         structPointRepr.renderObjects.forEach(viewer.add)
 
         const structSpacefillRepr = StructureRepresentation(Spacefill)
-        await Run(structSpacefillRepr.create(struct, { detail: 2 }), log, 100)
+        const spacefillProps: SpacefillProps = {
+            detail: 1,
+            // colorTheme: { name: 'uniform', value: 0xFF4411 },
+            // colorTheme: { name: 'instance-id' },
+            // colorTheme: { name: 'element-symbol' },
+            colorTheme: { name: 'atom-id' },
+        }
+        await Run(structSpacefillRepr.create(struct, spacefillProps), log, 100)
         structSpacefillRepr.renderObjects.forEach(viewer.add)
 
         viewer.requestDraw()
diff --git a/src/mol-geo/representation/structure/point.ts b/src/mol-geo/representation/structure/point.ts
index 511bcd018025e1c6f141f8ed54d99304f48fbc6b..0555750a059ac0752e6ec2c9cf0eb3b486eaad73 100644
--- a/src/mol-geo/representation/structure/point.ts
+++ b/src/mol-geo/representation/structure/point.ts
@@ -7,86 +7,78 @@
 import { ValueCell } from 'mol-util/value-cell'
 
 import { createPointRenderObject, RenderObject } from 'mol-gl/scene'
-import { Mat4 } from 'mol-math/linear-algebra'
+
 import { OrderedSet } from 'mol-data/int'
-import { ChunkedArray } from 'mol-data/util';
 import { Unit, ElementGroup } from 'mol-model/structure';
 import { RepresentationProps, UnitsRepresentation } from './index';
 import { Task } from 'mol-task'
-import { VdwRadius } from 'mol-model/structure/model/properties/atomic';
-import { createUniformColor, createInstanceColor } from '../../color/data';
 import { fillSerial } from 'mol-gl/renderable/util';
-import { ColorScale } from '../../color/scale';
-import { createUniformSize } from '../../size/data';
-import { vdwSizeData } from '../../size/structure/vdw';
+
 import VertexMap from '../../shape/vertex-map';
+import { ColorTheme, SizeTheme } from '../../theme';
+import { createTransforms, createColors, createSizes } from './utils';
 
 export const DefaultPointProps = {
-
+    colorTheme: { name: 'instance-id' } as ColorTheme,
+    sizeTheme: { name: 'vdw' } as SizeTheme
 }
 export type PointProps = Partial<typeof DefaultPointProps>
 
+export function createPointVertices(unit: Unit, elementGroup: ElementGroup) {
+    const elementCount = OrderedSet.size(elementGroup.elements)
+    const vertices = new Float32Array(elementCount * 3)
+    const { x, y, z } = unit.model.conformation
+    for (let i = 0; i < elementCount; i++) {
+        const e = OrderedSet.getAt(elementGroup.elements, i)
+        const i3 = i * 3
+        vertices[i3] = x[e]
+        vertices[i3 + 1] = y[e]
+        vertices[i3 + 2] = z[e]
+    }
+    return vertices
+}
+
 export default function Point(): UnitsRepresentation<PointProps> {
     const renderObjects: RenderObject[] = []
-    const vertices = ChunkedArray.create(Float32Array, 3, 1024, 2048);
-    const sizes = ChunkedArray.create(Float32Array, 1, 1024, 2048);
 
     return {
         renderObjects,
         create: (units: ReadonlyArray<Unit>, elementGroup: ElementGroup, props: PointProps = {}) => Task.create('Spacefill', async ctx => {
-            // const l = Element.Location();
-
-            const { x, y, z } = units[0].model.conformation
-            const { type_symbol } = units[0].model.hierarchy.atoms
+            const { colorTheme, sizeTheme } = { ...DefaultPointProps, ...props }
             const elementCount = OrderedSet.size(elementGroup.elements)
-            for (let i = 0; i < elementCount; i++) {
-                const e = OrderedSet.getAt(elementGroup.elements, i)
-                ChunkedArray.add3(vertices, x[e], y[e], z[e])
-                ChunkedArray.add(sizes, VdwRadius(type_symbol.value(e)))
+            const unitCount = units.length
 
-                if (i % 10000 === 0 && ctx.shouldUpdate) {
-                    await ctx.update({ message: 'Point', current: i, max: elementCount });
-                }
-            }
+            const vertexMap = VertexMap.create(
+                elementCount,
+                elementCount + 1,
+                fillSerial(new Uint32Array(elementCount)),
+                fillSerial(new Uint32Array(elementCount + 1))
+            )
 
-            const unitCount = units.length
-            const transformArray = new Float32Array(unitCount * 16)
-            for (let i = 0; i < unitCount; i++) {
-                Mat4.toArray(units[i].operator.matrix, transformArray, i * 16)
-            }
-
-            // const color = createUniformColor({ value: 0xFF4411 })
-            const scale = ColorScale.create({ domain: [ 0, unitCount - 1 ] })
-            const color = createInstanceColor({
-                colorFn: scale.color,
-                unitCount
-            })
+            await ctx.update('Computing point vertices');
+            const vertices = createPointVertices(units[0], elementGroup)
 
-            // const size = createUniformSize({ value: 1 })
-            const size = vdwSizeData({
-                units,
-                elementGroup,
-                vertexMap: VertexMap.create(
-                    elementCount,
-                    elementCount + 1,
-                    fillSerial(new Uint32Array(elementCount)),
-                    fillSerial(new Uint32Array(elementCount + 1))
-                )
-            })
-            console.log(size)
+            await ctx.update('Computing point transforms');
+            const transforms = createTransforms(units)
+
+            await ctx.update('Computing point colors');
+            const color = createColors(units, elementGroup, vertexMap, colorTheme)
+
+            await ctx.update('Computing point sizes');
+            const size = createSizes(units, elementGroup, vertexMap, sizeTheme)
 
             const points = createPointRenderObject({
                 objectId: 0,
 
-                position: ValueCell.create(ChunkedArray.compact(vertices, true) as Float32Array),
+                position: ValueCell.create(vertices),
                 id: ValueCell.create(fillSerial(new Float32Array(unitCount))),
                 size,
                 color,
-                transform: ValueCell.create(transformArray),
+                transform: ValueCell.create(transforms),
 
                 instanceCount: unitCount,
                 elementCount,
-                positionCount: vertices.elementCount,
+                positionCount: vertices.length / 3,
 
                 usePointSizeAttenuation: true
             })
diff --git a/src/mol-geo/representation/structure/spacefill.ts b/src/mol-geo/representation/structure/spacefill.ts
index 9a38a8526a8a15b1e1d81b4af45fe0f54ba763e4..2cdc6d5e877005d0a6fd1b44857d1b5749fe8a9f 100644
--- a/src/mol-geo/representation/structure/spacefill.ts
+++ b/src/mol-geo/representation/structure/spacefill.ts
@@ -15,86 +15,79 @@ import { RepresentationProps, UnitsRepresentation } from './index';
 import { Task } from 'mol-task'
 import { MeshBuilder } from '../../shape/mesh-builder';
 import { VdwRadius } from 'mol-model/structure/model/properties/atomic';
-import { elementSymbolColorData } from '../../color/structure/element';
-import { ColorData } from '../../color';
-import { createInstanceColor, createUniformColor, createElementInstanceColor } from '../../color/data';
-import { ColorScale } from '../../color/scale';
+import { createTransforms, createColors } from './utils';
+import { ColorTheme } from '../../theme';
+import VertexMap from '../../shape/vertex-map';
 
 export const DefaultSpacefillProps = {
-    detail: 0
+    detail: 0,
+    colorTheme: { name: 'instance-id' } as ColorTheme,
 }
 export type SpacefillProps = Partial<typeof DefaultSpacefillProps>
 
+function createSpacefillMesh(unit: Unit, elementGroup: ElementGroup, detail: number) {
+    return Task.create('Spacefill', async ctx => {
+        const meshBuilder = MeshBuilder.create()
+
+        const v = Vec3.zero()
+        const m = Mat4.identity()
+
+        const { x, y, z } = unit.model.conformation
+        const { type_symbol } = unit.model.hierarchy.atoms
+        const elementCount = OrderedSet.size(elementGroup.elements)
+        for (let i = 0; i < elementCount; i++) {
+            const e = OrderedSet.getAt(elementGroup.elements, i)
+            v[0] = x[e]
+            v[1] = y[e]
+            v[2] = z[e]
+            Mat4.setTranslation(m, v)
+
+            meshBuilder.setId(i)
+            meshBuilder.addIcosahedron(m, {
+                radius: VdwRadius(type_symbol.value(e)),
+                detail
+            })
+
+            if (i % 10000 === 0 && ctx.shouldUpdate) {
+                await ctx.update({ message: 'Spacefill', current: i, max: elementCount });
+            }
+        }
+
+        return meshBuilder.getMesh()
+    })
+}
+
 export default function Spacefill(): UnitsRepresentation<SpacefillProps> {
     const renderObjects: RenderObject[] = []
 
     return {
         renderObjects,
         create: (units: ReadonlyArray<Unit>, elementGroup: ElementGroup, props: SpacefillProps = {}) => Task.create('Spacefill', async ctx => {
-            const { detail } = { ...DefaultSpacefillProps, ...props }
-            const meshBuilder = MeshBuilder.create()
+            const { detail, colorTheme } = { ...DefaultSpacefillProps, ...props }
 
-            const v = Vec3.zero()
-            const m = Mat4.identity()
-
-            const { x, y, z } = units[0].model.conformation
-            const { type_symbol } = units[0].model.hierarchy.atoms
+            const unitCount = units.length
             const elementCount = OrderedSet.size(elementGroup.elements)
-            for (let i = 0; i < elementCount; i++) {
-                const e = OrderedSet.getAt(elementGroup.elements, i)
-                v[0] = x[e]
-                v[1] = y[e]
-                v[2] = z[e]
-                Mat4.setTranslation(m, v)
-
-                meshBuilder.setId(i)
-                meshBuilder.addIcosahedron(m, {
-                    radius: VdwRadius(type_symbol.value(e)),
-                    detail
-                })
-
-                if (i % 10000 === 0 && ctx.shouldUpdate) {
-                    await ctx.update({ message: 'Spacefill', current: i, max: elementCount });
-                }
-            }
 
-            const mesh = meshBuilder.getMesh()
+            await ctx.update('Computing spacefill mesh');
+            const mesh = await ctx.runChild(createSpacefillMesh(units[0], elementGroup, detail))
             // console.log(mesh)
 
-            const unitCount = units.length
-            const transformArray = new Float32Array(unitCount * 16)
-            for (let i = 0; i < unitCount; i++) {
-                Mat4.toArray(units[i].operator.matrix, transformArray, i * 16)
-            }
-
-            // console.log({ unitCount, elementCount })
+            const vertexMap = VertexMap.fromMesh(mesh)
 
-            // const color = createUniformColor({ value: 0xFF4411 })
-
-            // const color = elementSymbolColorData({ units, elementGroup, mesh })
-
-            const scale = ColorScale.create({ domain: [ 0, unitCount - 1 ] })
-            const color = createInstanceColor({
-                colorFn: scale.color,
-                unitCount
-            })
+            await ctx.update('Computing spacefill transforms');
+            const transforms = createTransforms(units)
 
-            // const scale = ColorScale.create({ domain: [ 0, unitCount * elementCount - 1 ] })
-            // const color = createElementInstanceColor({
-            //     colorFn: (unitIdx, elementIdx) => scale.color(unitIdx * elementCount + elementIdx),
-            //     unitCount,
-            //     offsetCount: mesh.offsetCount,
-            //     offsets: mesh.offsetBuffer as any
-            // })
+            await ctx.update('Computing spacefill colors');
+            const color = createColors(units, elementGroup, vertexMap, colorTheme)
 
             const spheres = createMeshRenderObject({
                 objectId: 0,
 
                 position: mesh.vertexBuffer,
                 normal: mesh.normalBuffer as ValueCell<Float32Array>,
-                color: color as ColorData,
+                color: color,
                 id: mesh.idBuffer as ValueCell<Float32Array>,
-                transform: ValueCell.create(transformArray),
+                transform: ValueCell.create(transforms),
                 index: mesh.indexBuffer,
 
                 instanceCount: unitCount,
diff --git a/src/mol-geo/representation/structure/utils.ts b/src/mol-geo/representation/structure/utils.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a0eb47202621bcec8307d0d5a9ebd0f51a4f86e9
--- /dev/null
+++ b/src/mol-geo/representation/structure/utils.ts
@@ -0,0 +1,58 @@
+/**
+ * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ */
+
+import { Unit, ElementGroup } from 'mol-model/structure';
+import { Mat4 } from 'mol-math/linear-algebra'
+
+import { ColorScale } from 'mol-util/color';
+import { createUniformColor, createInstanceColor, createElementInstanceColor } from '../../util/color-data';
+import { createUniformSize } from '../../util/size-data';
+import { vdwSizeData } from '../../theme/structure/size/vdw';
+import VertexMap from '../../shape/vertex-map';
+import { ColorTheme, SizeTheme } from '../../theme';
+import { elementSymbolColorData } from '../../theme/structure/color/element';
+import { OrderedSet } from 'mol-data/int';
+
+export function createTransforms(units: ReadonlyArray<Unit>) {
+    const unitCount = units.length
+    const transforms = new Float32Array(unitCount * 16)
+    for (let i = 0; i < unitCount; i++) {
+        Mat4.toArray(units[i].operator.matrix, transforms, i * 16)
+    }
+    return transforms
+}
+
+export function createColors(units: ReadonlyArray<Unit>, elementGroup: ElementGroup, vertexMap: VertexMap, props: ColorTheme) {
+    const instanceCount = units.length
+    const elementCount = OrderedSet.size(elementGroup.elements)
+    switch (props.name) {
+        case 'uniform':
+            return createUniformColor(props)
+        case 'instance-id':
+            const instanceDomain = props.domain ? props.domain : [ 0, instanceCount - 1 ]
+            const instanceScale = ColorScale.create({ domain: instanceDomain })
+            return createInstanceColor({ colorFn: instanceScale.color, instanceCount })
+        case 'atom-id':
+            const atomDomain = props.domain ? props.domain : [ 0, instanceCount * elementCount - 1 ]
+            const atomScale = ColorScale.create({ domain: atomDomain })
+            return createElementInstanceColor({
+                colorFn: (unitIdx, elementIdx) => atomScale.color(unitIdx * elementCount + elementIdx),
+                instanceCount,
+                vertexMap
+            })
+        case 'element-symbol':
+            return elementSymbolColorData({ units, elementGroup, vertexMap })
+    }
+}
+
+export function createSizes(units: ReadonlyArray<Unit>, elementGroup: ElementGroup, vertexMap: VertexMap, props: SizeTheme) {
+    switch (props.name) {
+        case 'uniform':
+            return createUniformSize(props)
+        case 'vdw':
+            return vdwSizeData({ units, elementGroup, vertexMap })
+    }
+}
\ No newline at end of file
diff --git a/src/mol-geo/shape/vertex-map.ts b/src/mol-geo/shape/vertex-map.ts
index e21f0bf00456dc3ee61ee6572991f3c5b36c2f18..e0fe9168bbdfc7da68ee11676fbc8929c8f7cd7a 100644
--- a/src/mol-geo/shape/vertex-map.ts
+++ b/src/mol-geo/shape/vertex-map.ts
@@ -4,6 +4,7 @@
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
 
+import { ChunkedArray } from 'mol-data/util';
 import { Mesh } from './mesh';
 
 /** Mapping between vertices and ids */
@@ -11,15 +12,26 @@ interface VertexMap {
     idCount: number,
     offsetCount: number,
     ids: Helpers.NumberArray | undefined
-    offsets: Helpers.NumberArray,
+    offsets: Uint32Array,
 }
 
-function createOffsets(ids: Helpers.NumberArray | undefined) {
-    return []
+function createOffsets(idCount: number, ids: Helpers.NumberArray | undefined) {
+    if (!ids) return new Uint32Array(0)
+    const offsets = ChunkedArray.create(Uint32Array, 1, 1024, 2048);
+    let prevId = ids[0]
+    ChunkedArray.add(offsets, 0)
+    for (let i = 1; i < idCount; ++i) {
+        if (prevId !== ids[i]) {
+            prevId = ids[i]
+            ChunkedArray.add(offsets, i)
+        }
+    }
+    ChunkedArray.add(offsets, idCount)
+    return ChunkedArray.compact(offsets, false) as Uint32Array
 }
 
 namespace VertexMap {
-    export function create(idCount: number, offsetCount: number, ids: Helpers.NumberArray | undefined, offsets: Helpers.NumberArray): VertexMap {
+    export function create(idCount: number, offsetCount: number, ids: Helpers.NumberArray | undefined, offsets: Uint32Array): VertexMap {
         return {
             idCount,
             offsetCount,
@@ -30,7 +42,7 @@ namespace VertexMap {
 
     export function fromMesh(mesh: Mesh) {
         const ids = mesh.idBuffer.ref.value
-        const offsets = createOffsets(ids)
+        const offsets = createOffsets(mesh.vertexCount, ids)
         return create(mesh.vertexCount, offsets.length, ids, offsets)
     }
 
diff --git a/src/mol-geo/size/index.ts b/src/mol-geo/size/index.ts
deleted file mode 100644
index 5936b8ac26f25282d0868ab5127a4e233b845a15..0000000000000000000000000000000000000000
--- a/src/mol-geo/size/index.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-/**
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * @author Alexander Rose <alexander.rose@weirdbyte.de>
- */
-
-import { SizeData } from './data'
-
-export { SizeData }
\ No newline at end of file
diff --git a/src/mol-geo/theme/index.ts b/src/mol-geo/theme/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..70eaa22d9a0e2dcbf257a1b5c3b45962451a7ca6
--- /dev/null
+++ b/src/mol-geo/theme/index.ts
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ */
+
+import { Color } from 'mol-util/color';
+
+export interface UniformColorTheme {
+    name: 'uniform'
+    value: Color
+}
+
+export interface ScaleColorTheme {
+    name: 'instance-id' | 'element-symbol' | 'atom-id'
+    domain?: [number, number]
+}
+
+export type ColorTheme = UniformColorTheme | ScaleColorTheme
+
+export interface UniformSizeTheme {
+    name: 'uniform',
+    value: number
+}
+
+export interface ScaleSizeTheme {
+    name: 'vdw'
+}
+
+export type SizeTheme = UniformSizeTheme | ScaleSizeTheme
\ No newline at end of file
diff --git a/src/mol-geo/color/structure/element.ts b/src/mol-geo/theme/structure/color/element.ts
similarity index 90%
rename from src/mol-geo/color/structure/element.ts
rename to src/mol-geo/theme/structure/color/element.ts
index 70574c14cbce7ee2d8ecf162b699fd4dbdca3ba7..432807d2bb4ee75947a70538afc9f93844591b97 100644
--- a/src/mol-geo/color/structure/element.ts
+++ b/src/mol-geo/theme/structure/color/element.ts
@@ -5,10 +5,10 @@
  */
 
 import { ElementSymbol } from 'mol-model/structure/model/types';
-import Color from '../color';
-import { createAttributeOrElementColor } from '../data';
+import { Color } from 'mol-util/color';
 import { StructureColorDataProps } from '.';
 import { OrderedSet } from 'mol-data/int';
+import { createAttributeOrElementColor } from '../../../util/color-data';
 
 // from Jmol http://jmol.sourceforge.net/jscolors/ (or 0xFFFFFF)
 export const ElementSymbolColors: { [k: string]: Color } = {
@@ -23,15 +23,13 @@ export function elementSymbolColor(element: ElementSymbol): Color {
 }
 
 export function elementSymbolColorData(props: StructureColorDataProps) {
-    const { units, elementGroup, mesh } = props
+    const { units, elementGroup, vertexMap } = props
     const { type_symbol } = units[0].model.hierarchy.atoms
-    return createAttributeOrElementColor(mesh, {
+    return createAttributeOrElementColor(vertexMap, {
         colorFn: (elementIdx: number) => {
             const e = OrderedSet.getAt(elementGroup.elements, elementIdx)
             return elementSymbolColor(type_symbol.value(e))
         },
-        vertexCount: mesh.vertexCount,
-        offsetCount: mesh.offsetCount,
-        offsets: mesh.offsetBuffer as any
+        vertexMap
     })
 }
\ No newline at end of file
diff --git a/src/mol-geo/color/structure/index.ts b/src/mol-geo/theme/structure/color/index.ts
similarity index 81%
rename from src/mol-geo/color/structure/index.ts
rename to src/mol-geo/theme/structure/color/index.ts
index 71b59a49e20e30d2f107e0fac180bb156399890c..35b994ba9d275b4ec6265d50d22d9e40209518dc 100644
--- a/src/mol-geo/color/structure/index.ts
+++ b/src/mol-geo/theme/structure/color/index.ts
@@ -5,10 +5,10 @@
  */
 
 import { ElementGroup, Unit } from 'mol-model/structure';
-import { Mesh } from '../../shape/mesh';
+import VertexMap from '../../../shape/vertex-map';
 
 export interface StructureColorDataProps {
     units: ReadonlyArray<Unit>,
     elementGroup: ElementGroup,
-    mesh: Mesh
+    vertexMap: VertexMap
 }
\ No newline at end of file
diff --git a/src/mol-geo/size/structure/index.ts b/src/mol-geo/theme/structure/size/index.ts
similarity index 87%
rename from src/mol-geo/size/structure/index.ts
rename to src/mol-geo/theme/structure/size/index.ts
index 4ec3dee79cd5467e969fe3cc1679661991cc9274..775c3c0d71726f5fab694d47ce1487a6ce2bed36 100644
--- a/src/mol-geo/size/structure/index.ts
+++ b/src/mol-geo/theme/structure/size/index.ts
@@ -5,7 +5,7 @@
  */
 
 import { ElementGroup, Unit } from 'mol-model/structure';
-import VertexMap from '../../shape/vertex-map';
+import VertexMap from '../../../shape/vertex-map';
 
 export interface StructureSizeDataProps {
     units: ReadonlyArray<Unit>,
diff --git a/src/mol-geo/size/structure/vdw.ts b/src/mol-geo/theme/structure/size/vdw.ts
similarity index 91%
rename from src/mol-geo/size/structure/vdw.ts
rename to src/mol-geo/theme/structure/size/vdw.ts
index 522033493e26bcca88abab4cdfdfb8c57792fec1..3010380904ab0810d3d79ff5f0a5b0a0d1f7a921 100644
--- a/src/mol-geo/size/structure/vdw.ts
+++ b/src/mol-geo/theme/structure/size/vdw.ts
@@ -7,7 +7,8 @@
 import { OrderedSet } from 'mol-data/int';
 import { VdwRadius } from 'mol-model/structure/model/properties/atomic';
 import { StructureSizeDataProps } from '.';
-import { createAttributeSize } from '../data';
+import { createAttributeSize } from '../../../util/size-data';
+
 
 export function vdwSizeData(props: StructureSizeDataProps) {
     const { units, elementGroup, vertexMap } = props
diff --git a/src/mol-geo/color/data.ts b/src/mol-geo/util/color-data.ts
similarity index 68%
rename from src/mol-geo/color/data.ts
rename to src/mol-geo/util/color-data.ts
index 3e98a815c43a27429fef9b8cbe209122d17eff92..fa565427133ce24ad5092f50842f84a60624d443 100644
--- a/src/mol-geo/color/data.ts
+++ b/src/mol-geo/util/color-data.ts
@@ -6,8 +6,8 @@
 
 import { ValueCell } from 'mol-util';
 import { Texture, createColorTexture } from 'mol-gl/renderable/util';
-import Color from './color';
-import { Mesh } from '../shape/mesh';
+import { Color } from 'mol-util/color';
+import VertexMap from '../shape/vertex-map';
 
 export type UniformColor = { type: 'uniform', value: number[] }
 export type AttributeColor = { type: 'attribute', value: ValueCell<Float32Array> }
@@ -27,19 +27,17 @@ export function createUniformColor(props: UniformColorProps): UniformColor {
 
 export interface AttributeColorProps {
     colorFn: (elementIdx: number) => Color
-    vertexCount: number,
-    offsetCount: number,
-    offsets: ValueCell<Uint32Array>
+    vertexMap: VertexMap
 }
 
 /** Creates color attribute with color for each element (i.e. shared across indtances/units) */
 export function createAttributeColor(props: AttributeColorProps): AttributeColor {
-    const { colorFn, vertexCount, offsetCount, offsets} = props
-    const colors = new Float32Array(vertexCount * 3);
-    const _offsets = offsets.ref.value
+    const { colorFn, vertexMap } = props
+    const { idCount, offsetCount, offsets } = vertexMap
+    const colors = new Float32Array(idCount * 3);
     for (let i = 0, il = offsetCount - 1; i < il; ++i) {
-        const start = _offsets[i]
-        const end = _offsets[i + 1]
+        const start = offsets[i]
+        const end = offsets[i + 1]
         const hexColor = colorFn(i)
         for (let i = start, il = end; i < il; ++i) {
             Color.toArrayNormalized(hexColor, colors, i * 3)
@@ -49,15 +47,15 @@ export function createAttributeColor(props: AttributeColorProps): AttributeColor
 }
 
 export interface InstanceColorProps {
-    colorFn: (unitIdx: number) => Color
-    unitCount: number
+    colorFn: (instanceIdx: number) => Color
+    instanceCount: number
 }
 
 /** Creates color texture with color for each instance/unit */
 export function createInstanceColor(props: InstanceColorProps): InstanceColor {
-    const { colorFn, unitCount} = props
-    const colors = createColorTexture(unitCount)
-    for (let i = 0; i < unitCount; i++) {
+    const { colorFn, instanceCount} = props
+    const colors = createColorTexture(instanceCount)
+    for (let i = 0; i < instanceCount; i++) {
         Color.toArray(colorFn(i), colors, i * 3)
     }
     return { type: 'instance', value: ValueCell.create(colors) }
@@ -65,14 +63,13 @@ export function createInstanceColor(props: InstanceColorProps): InstanceColor {
 
 export interface ElementColorProps {
     colorFn: (elementIdx: number) => Color
-    offsetCount: number,
-    offsets: ValueCell<Uint32Array>
+    vertexMap: VertexMap
 }
 
 /** Creates color texture with color for each element (i.e. shared across indtances/units) */
 export function createElementColor(props: ElementColorProps): ElementColor {
-    const { colorFn, offsetCount } = props
-    const elementCount = offsetCount - 1
+    const { colorFn, vertexMap } = props
+    const elementCount = vertexMap.offsetCount - 1
     const colors = createColorTexture(elementCount)
     for (let i = 0, il = elementCount; i < il; ++i) {
         Color.toArray(colorFn(i), colors, i * 3)
@@ -81,20 +78,19 @@ export function createElementColor(props: ElementColorProps): ElementColor {
 }
 
 export interface ElementInstanceColorProps {
-    colorFn: (unitIdx: number, elementIdx: number) => Color
-    unitCount: number,
-    offsetCount: number,
-    offsets: ValueCell<Uint32Array>
+    colorFn: (instanceIdx: number, elementIdx: number) => Color
+    instanceCount: number,
+    vertexMap: VertexMap
 }
 
 /** Creates color texture with color for each element instance (i.e. for each unit) */
 export function createElementInstanceColor(props: ElementInstanceColorProps): ElementInstanceColor {
-    const { colorFn, unitCount, offsetCount } = props
-    const elementCount = offsetCount - 1
-    const count = unitCount * elementCount
+    const { colorFn, instanceCount, vertexMap } = props
+    const elementCount = vertexMap.offsetCount - 1
+    const count = instanceCount * elementCount
     const colors = createColorTexture(count)
     let colorOffset = 0
-    for (let i = 0; i < unitCount; i++) {
+    for (let i = 0; i < instanceCount; i++) {
         for (let j = 0, jl = elementCount; j < jl; ++j) {
             Color.toArray(colorFn(i, j), colors, colorOffset)
             colorOffset += 3
@@ -103,8 +99,7 @@ export function createElementInstanceColor(props: ElementInstanceColorProps): El
     return { type: 'element-instance', value: ValueCell.create(colors) }
 }
 
-/** Create color attribute or texture, depending on the mesh */
-export function createAttributeOrElementColor(mesh: Mesh, props: AttributeColorProps) {
-    // return mesh.vertexCount < 4 * mesh.offsetCount ? createAttributeColor(props) : createElementColor(props)
-    return createAttributeColor(props)
+/** Create color attribute or texture, depending on the vertexMap */
+export function createAttributeOrElementColor(vertexMap: VertexMap, props: AttributeColorProps) {
+    return vertexMap.idCount < 4 * vertexMap.offsetCount ? createAttributeColor(props) : createElementColor(props)
 }
\ No newline at end of file
diff --git a/src/mol-geo/size/data.ts b/src/mol-geo/util/size-data.ts
similarity index 100%
rename from src/mol-geo/size/data.ts
rename to src/mol-geo/util/size-data.ts
diff --git a/src/mol-gl/_spec/renderer.spec.ts b/src/mol-gl/_spec/renderer.spec.ts
index 155e8ed5cadc0b970332728f0afca49026acdf8b..d46b8931f58b002accf73344c27b778f39eb4941 100644
--- a/src/mol-gl/_spec/renderer.spec.ts
+++ b/src/mol-gl/_spec/renderer.spec.ts
@@ -13,8 +13,8 @@ import { ValueCell } from 'mol-util';
 import Renderer from '../renderer';
 import { createPointRenderObject } from '../scene';
 import { fillSerial } from '../renderable/util';
-import { createUniformColor } from 'mol-geo/color/data';
-import { createUniformSize } from 'mol-geo/size/data';
+import { createUniformColor } from 'mol-geo/util/color-data';
+import { createUniformSize } from 'mol-geo/util/size-data';
 
 function writeImage(gl: WebGLRenderingContext, width: number, height: number) {
     const pixels = new Uint8Array(width * height * 4)
diff --git a/src/mol-gl/renderable/mesh.ts b/src/mol-gl/renderable/mesh.ts
index e58fe1d8b0943a42fcdcc2fdad9ca6b00f15320f..420e9f055e42ba086ab5de14fde009d46a043994 100644
--- a/src/mol-gl/renderable/mesh.ts
+++ b/src/mol-gl/renderable/mesh.ts
@@ -6,7 +6,7 @@
 
 import REGL = require('regl');
 import { ValueCell } from 'mol-util/value-cell'
-import { ColorData } from 'mol-geo/color';
+import { ColorData } from 'mol-geo/util/color-data';
 
 import { Renderable } from '../renderable'
 import { createBaseDefines, createBaseUniforms, createBaseAttributes, destroyAttributes, destroyUniforms } from './util'
diff --git a/src/mol-gl/renderable/point.ts b/src/mol-gl/renderable/point.ts
index 7ec9b4f0583ccdfeaf8680f64271bb6104e96830..d35dd0b73e19fe1ab6e4e83b5120bad58069c67a 100644
--- a/src/mol-gl/renderable/point.ts
+++ b/src/mol-gl/renderable/point.ts
@@ -10,8 +10,8 @@ import { ValueCell } from 'mol-util/value-cell'
 import { Renderable } from '../renderable'
 import { createBaseDefines, createBaseUniforms, createBaseAttributes, destroyUniforms, destroyAttributes } from './util'
 import { PointShaders, addDefines } from '../shaders'
-import { ColorData } from 'mol-geo/color';
-import { SizeData } from 'mol-geo/size';
+import { ColorData } from 'mol-geo/util/color-data';
+import { SizeData } from 'mol-geo/util/size-data';
 
 type Point = 'point'
 
diff --git a/src/mol-gl/renderable/util.ts b/src/mol-gl/renderable/util.ts
index e72399fa149c98c488c4c1ea2372f81a2faf673e..3c78cd3903deefdab253e08da30c9ac01828f2b8 100644
--- a/src/mol-gl/renderable/util.ts
+++ b/src/mol-gl/renderable/util.ts
@@ -6,12 +6,12 @@
 
 import REGL = require('regl');
 import { ValueCell } from 'mol-util/value-cell'
+import { ColorData } from 'mol-geo/util/color-data';
+import { SizeData } from 'mol-geo/util/size-data';
 
 import { Attributes, AttributesData, AttributesBuffers } from '../renderable'
 import Attribute from '../attribute'
-import { ColorData } from 'mol-geo/color';
 import { ShaderDefines } from '../shaders';
-import { SizeData } from 'mol-geo/size';
 
 export type ReglUniforms = { [k: string]: REGL.Uniform | REGL.Texture }
 export type ReglAttributes = { [k: string]: REGL.AttributeConfig }
diff --git a/src/mol-geo/color/color.ts b/src/mol-util/color/color.ts
similarity index 100%
rename from src/mol-geo/color/color.ts
rename to src/mol-util/color/color.ts
diff --git a/src/mol-geo/color/index.ts b/src/mol-util/color/index.ts
similarity index 78%
rename from src/mol-geo/color/index.ts
rename to src/mol-util/color/index.ts
index e1f138de4862ebe331aacd0afdf48db86b864319..f62264a7c1da8c4869dfd6c207b9391a297ff884 100644
--- a/src/mol-geo/color/index.ts
+++ b/src/mol-util/color/index.ts
@@ -5,7 +5,7 @@
  */
 
 import Color from './color'
-import { ColorData } from './data'
+import { ColorScale } from './scale';
 
-export { Color, ColorData }
+export { Color, ColorScale }
 export { ColorBrewer, ColorNames } from './tables'
\ No newline at end of file
diff --git a/src/mol-geo/color/scale.ts b/src/mol-util/color/scale.ts
similarity index 100%
rename from src/mol-geo/color/scale.ts
rename to src/mol-util/color/scale.ts
diff --git a/src/mol-geo/color/tables.ts b/src/mol-util/color/tables.ts
similarity index 100%
rename from src/mol-geo/color/tables.ts
rename to src/mol-util/color/tables.ts