diff --git a/src/mol-geo/geometry/mesh/mesh-builder.ts b/src/mol-geo/geometry/mesh/mesh-builder.ts
index 0381fd2c70ad88b050386bb343bf696253f6ff47..87a0bf310e2450f421e58267ac0d1eb3461b8be1 100644
--- a/src/mol-geo/geometry/mesh/mesh-builder.ts
+++ b/src/mol-geo/geometry/mesh/mesh-builder.ts
@@ -101,9 +101,9 @@ export namespace MeshBuilder {
         }
     }
 
-    export function addCage(state: State, t: Mat4, cage: Cage, radius: number, detail: number) {
+    export function addCage(state: State, t: Mat4, cage: Cage, radius: number, detail: number, radialSegments: number) {
         const { vertices: va, edges: ea } = cage
-        const cylinderProps = { radiusTop: radius, radiusBottom: radius }
+        const cylinderProps = { radiusTop: radius, radiusBottom: radius, radialSegments }
         for (let i = 0, il = ea.length; i < il; i += 2) {
             Vec3.fromArray(tmpVecA, va, ea[i] * 3)
             Vec3.fromArray(tmpVecB, va, ea[i + 1] * 3)
diff --git a/src/mol-geo/primitive/cage.ts b/src/mol-geo/primitive/cage.ts
index 6c235c61f28ff2fecfd317bad4568f99c3233800..3fad311d5addffe280af4a58bf410d25ca7cdd04 100644
--- a/src/mol-geo/primitive/cage.ts
+++ b/src/mol-geo/primitive/cage.ts
@@ -4,6 +4,9 @@
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
 
+import { Mat4, Vec3 } from '../../mol-math/linear-algebra'
+import { NumberArray } from '../../mol-util/type-helpers'
+
 export interface Cage {
     readonly vertices: ArrayLike<number>
     readonly edges: ArrayLike<number>
@@ -11,4 +14,24 @@ export interface Cage {
 
 export function createCage(vertices: ArrayLike<number>, edges: ArrayLike<number>): Cage {
     return { vertices, edges }
+}
+
+export function copyCage(cage: Cage): Cage {
+    return {
+        vertices: new Float32Array(cage.vertices),
+        edges: new Uint32Array(cage.edges)
+    }
+}
+
+const tmpV = Vec3.zero()
+
+/** Transform primitive in-place */
+export function transformCage(cage: Cage, t: Mat4) {
+    const { vertices } = cage
+    for (let i = 0, il = vertices.length; i < il; i += 3) {
+        // position
+        Vec3.transformMat4(tmpV, Vec3.fromArray(tmpV, vertices, i), t)
+        Vec3.toArray(tmpV, vertices as NumberArray, i)
+    }
+    return cage
 }
\ No newline at end of file
diff --git a/src/mol-geo/primitive/primitive.ts b/src/mol-geo/primitive/primitive.ts
index c565dbc7063079f9348cf42c47a86c249fc90050..fcac1d23896e1183c1b8a920b4b3bcae9cb2419f 100644
--- a/src/mol-geo/primitive/primitive.ts
+++ b/src/mol-geo/primitive/primitive.ts
@@ -30,6 +30,14 @@ export function createPrimitive(vertices: ArrayLike<number>, indices: ArrayLike<
     return builder.getPrimitive()
 }
 
+export function copyPrimitive(primitive: Primitive): Primitive {
+    return {
+        vertices: new Float32Array(primitive.vertices),
+        normals: new Float32Array(primitive.normals),
+        indices: new Uint32Array(primitive.indices)
+    }
+}
+
 export interface PrimitiveBuilder {
     add(a: Vec3, b: Vec3, c: Vec3): void
     getPrimitive(): Primitive
diff --git a/src/tests/browser/render-mesh.ts b/src/tests/browser/render-mesh.ts
index 363d64150e859ac8120f5813c79b386b4a8359ed..ca5ee131a4db0b7c7875d1a419bea8a099420bb2 100644
--- a/src/tests/browser/render-mesh.ts
+++ b/src/tests/browser/render-mesh.ts
@@ -31,7 +31,7 @@ function meshRepr() {
     const builderState = MeshBuilder.createState()
 
     const t = Mat4.identity()
-    MeshBuilder.addCage(builderState, t, HexagonalPrismCage(), 0.005, 2)
+    MeshBuilder.addCage(builderState, t, HexagonalPrismCage(), 0.005, 2, 20)
 
     const t2 = Mat4.identity()
     Mat4.scaleUniformly(t2, t2, 0.1)