Bladeren bron

refactored geo primitives, added octehedron

Alexander Rose 6 jaren geleden
bovenliggende
commit
d1793a1659

+ 2 - 1
src/mol-geo/primitive/box.ts

@@ -7,6 +7,7 @@
 // adapted from three.js, MIT License Copyright 2010-2018 three.js authors
 
 import { Vec3 } from 'mol-math/linear-algebra'
+import { Primitive } from './primitive';
 
 export const DefaultBoxProps = {
     width: 1,
@@ -17,7 +18,7 @@ export type BoxProps = Partial<typeof DefaultBoxProps>
 
 const tmpVector = Vec3.zero();
 
-export function Box(props?: BoxProps) {
+export function Box(props?: BoxProps): Primitive {
     const { width, height, depth } = { ...DefaultBoxProps, ...props }
 
     // buffers

+ 2 - 1
src/mol-geo/primitive/cylinder.ts

@@ -7,6 +7,7 @@
 // adapted from three.js, MIT License Copyright 2010-2018 three.js authors
 
 import { Vec3 } from 'mol-math/linear-algebra'
+import { Primitive } from './primitive';
 
 export const DefaultCylinderProps = {
     radiusTop: 1,
@@ -21,7 +22,7 @@ export const DefaultCylinderProps = {
 }
 export type CylinderProps = Partial<typeof DefaultCylinderProps>
 
-export function Cylinder(props?: CylinderProps) {
+export function Cylinder(props?: CylinderProps): Primitive {
     const { radiusTop, radiusBottom, height, radialSegments, heightSegments, topCap, bottomCap, thetaStart, thetaLength } = { ...DefaultCylinderProps, ...props };
 
     // buffers

+ 12 - 24
src/mol-geo/primitive/icosahedron.ts

@@ -4,35 +4,23 @@
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
 
-// adapted from three.js, MIT License Copyright 2010-2018 three.js authors
-
-import { Polyhedron } from './polyhedron'
+import { createPrimitive, Primitive } from './primitive';
 
 const t = ( 1 + Math.sqrt( 5 ) ) / 2;
 
-const vertices = [
-    - 1, t, 0, 	1, t, 0, 	- 1, - t, 0, 	1, - t, 0,
-     0, - 1, t, 	0, 1, t,	0, - 1, - t, 	0, 1, - t,
-     t, 0, - 1, 	t, 0, 1, 	- t, 0, - 1, 	- t, 0, 1
+const icosahedronVertices: ReadonlyArray<number> = [
+    -1, t, 0,   1, t, 0,  -1, -t, 0,   1, -t, 0,
+     0, -1, t,  0, 1, t,   0, -1, -t,  0, 1, -t,
+     t, 0, -1,  t, 0, 1,  -t, 0, -1,  -t, 0, 1
 ];
 
-const indices = [
-     0, 11, 5, 	0, 5, 1, 	0, 1, 7, 	0, 7, 10, 	0, 10, 11,
-     1, 5, 9, 	5, 11, 4,	11, 10, 2,	10, 7, 6,	7, 1, 8,
-     3, 9, 4, 	3, 4, 2,	3, 2, 6,	3, 6, 8,	3, 8, 9,
-     4, 9, 5, 	2, 4, 11,	6, 2, 10,	8, 6, 7,	9, 8, 1
+const icosahedronIndices: ReadonlyArray<number> = [
+    0, 11, 5,  0, 5, 1,    0, 1, 7,    0, 7, 10,  0, 10, 11,
+    1, 5, 9,   5, 11, 4,  11, 10, 2,  10, 7, 6,   7, 1, 8,
+    3, 9, 4,   3, 4, 2,    3, 2, 6,    3, 6, 8,   3, 8, 9,
+    4, 9, 5,   2, 4, 11,   6, 2, 10,   8, 6, 7,   9, 8, 1
 ];
 
-export function icosahedronVertexCount(detail: number) {
-    return 10 * Math.pow(Math.pow(2, detail), 2) + 2
-}
-
-export const DefaultIcosahedronProps = {
-    radius: 1,
-    detail: 0
-}
-export type IcosahedronProps = Partial<typeof DefaultIcosahedronProps>
+const icosahedron = createPrimitive(icosahedronVertices, icosahedronIndices)
 
-export function Icosahedron(props?: IcosahedronProps) {
-    return Polyhedron(vertices, indices, { ...DefaultIcosahedronProps, ...props })
-}
+export function Icosahedron(): Primitive { return icosahedron }

+ 22 - 0
src/mol-geo/primitive/octahedron.ts

@@ -0,0 +1,22 @@
+/**
+ * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ */
+
+import { createPrimitive, Primitive } from './primitive';
+
+export const octahedronVertices: ReadonlyArray<number> = [
+    0.5, 0, 0,   -0.5, 0, 0,    0, 0.5, 0,
+    0, -0.5, 0,     0, 0, 0.5,  0, 0, -0.5
+];
+
+export const octahedronIndices: ReadonlyArray<number> = [
+    0, 2, 4,  0, 4, 3,  0, 3, 5,
+    0, 5, 2,  1, 2, 5,  1, 5, 3,
+    1, 3, 4,  1, 4, 2
+];
+
+const octahedron = createPrimitive(octahedronVertices, octahedronIndices)
+
+export function Octahedron(): Primitive { return octahedron }

+ 3 - 1
src/mol-geo/primitive/plane.ts

@@ -1,3 +1,5 @@
+import { Primitive } from './primitive';
+
 /**
  * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
@@ -10,7 +12,7 @@ export const DefaultPlaneProps = {
 }
 export type PlaneProps = Partial<typeof DefaultPlaneProps>
 
-export function Plane(props?: PlaneProps) {
+export function Plane(props?: PlaneProps): Primitive {
     const { width, height } = { ...DefaultPlaneProps, ...props }
 
     return {

+ 2 - 15
src/mol-geo/primitive/polyhedron.ts

@@ -8,6 +8,7 @@
 
 import { Vec3 } from 'mol-math/linear-algebra'
 import { computeIndexedVertexNormals, appplyRadius } from '../util'
+import { Primitive } from './primitive';
 
 export const DefaultPolyhedronProps = {
     radius: 1,
@@ -15,7 +16,7 @@ export const DefaultPolyhedronProps = {
 }
 export type PolyhedronProps = Partial<typeof DefaultPolyhedronProps>
 
-export function Polyhedron(_vertices: Helpers.NumberArray, _indices: Helpers.NumberArray, props?: PolyhedronProps) {
+export function Polyhedron(_vertices: ArrayLike<number>, _indices: ArrayLike<number>, props?: PolyhedronProps): Primitive {
     const { radius, detail } = { ...DefaultPolyhedronProps, ...props }
     const builder = createBuilder()
     const { vertices, indices } = builder
@@ -85,20 +86,6 @@ export function Polyhedron(_vertices: Helpers.NumberArray, _indices: Helpers.Num
             }
         }
 
-        // // construct all of the faces
-        // for (let i = 0; i < cols; ++i) {
-        //     for (let j = 0; j < 2 * (cols - i) - 1; ++j) {
-        //         const k = Math.floor(j / 2)
-        //         if (j % 2 === 0) {
-        //             vertices.push(...v[i][k + 1], ...v[i + 1][k], ...v[i][k])
-        //         } else {
-        //             vertices.push(...v[i][k + 1], ...v[i + 1][k + 1], ...v[i + 1][k])
-        //         }
-        //         const l = vertices.length / 3
-        //         indices.push(l - 3, l - 2, l - 1)
-        //     }
-        // }
-
         // construct all of the faces
         for (let i = 0; i < cols; ++i) {
             for (let j = 0; j < 2 * (cols - i) - 1; ++j) {

+ 40 - 0
src/mol-geo/primitive/primitive.ts

@@ -0,0 +1,40 @@
+/**
+ * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ */
+
+import { Vec3 } from 'mol-math/linear-algebra';
+
+export interface Primitive {
+    vertices: ArrayLike<number>
+    normals: ArrayLike<number>
+    indices: ArrayLike<number>
+}
+
+const tri = [ Vec3.zero(), Vec3.zero(), Vec3.zero() ]
+const n = Vec3.zero()
+
+/** Create primitive with face normals from vertices and indices */
+export function createPrimitive(_vertices: ArrayLike<number>, _indices: ArrayLike<number>): Primitive {
+    const count = _indices.length
+    const vertices = new Float32Array(count * 3)
+    const normals = new Float32Array(count * 3)
+    const indices = new Uint32Array(count)
+
+    for (let i = 0; i < count; i += 3) {
+        for (let j = 0; j < 3; ++j) {
+            Vec3.fromArray(tri[j], _vertices, _indices[i + j] * 3)
+            Vec3.toArray(tri[j], vertices, i * 3 + j * 3)
+        }
+
+        Vec3.triangleNormal(n, tri[0], tri[1], tri[2])
+
+        for (let j = 0; j < 3; ++j) {
+            Vec3.toArray(n, normals, i * 3 + j * 3)
+            indices[i + j] = i + j
+        }
+    }
+
+    return { vertices, normals, indices }
+}

+ 1 - 1
src/mol-geo/primitive/sheet.ts

@@ -30,7 +30,7 @@ const p6 = Vec3.zero()
 const p7 = Vec3.zero()
 const p8 = Vec3.zero()
 
-export function addSheet(controlPoints: Helpers.NumberArray, normalVectors: Helpers.NumberArray, binormalVectors: Helpers.NumberArray, linearSegments: number, width: number, height: number, arrowHeight: number, startCap: boolean, endCap: boolean, state: MeshBuilderState) {
+export function addSheet(controlPoints: ArrayLike<number>, normalVectors: ArrayLike<number>, binormalVectors: ArrayLike<number>, linearSegments: number, width: number, height: number, arrowHeight: number, startCap: boolean, endCap: boolean, state: MeshBuilderState) {
     const { vertices, normals, indices } = state
 
     let vertexCount = vertices.elementCount

+ 27 - 0
src/mol-geo/primitive/sphere.ts

@@ -0,0 +1,27 @@
+/**
+ * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ */
+
+import { Polyhedron } from './polyhedron'
+import { Icosahedron } from  './icosahedron'
+import { Primitive } from './primitive';
+
+const { vertices, indices } = Icosahedron()
+
+/** Calculate vertex count for subdived icosahedron */
+export function sphereVertexCount(detail: number) {
+    return 10 * Math.pow(Math.pow(2, detail), 2) + 2
+}
+
+export const DefaultSphereProps = {
+    radius: 1,
+    detail: 0
+}
+export type SphereProps = Partial<typeof DefaultSphereProps>
+
+/** Create sphere by subdividing an icosahedron */
+export function Sphere(props?: SphereProps): Primitive {
+    return Polyhedron(vertices, indices, { ...DefaultSphereProps, ...props })
+}

+ 2 - 1
src/mol-geo/primitive/star.ts

@@ -5,6 +5,7 @@
  */
 
 import { Vec3 } from 'mol-math/linear-algebra'
+import { Primitive } from './primitive';
 
 export const DefaultStarProps = {
     pointCount: 5,
@@ -21,7 +22,7 @@ const p1 = Vec3.zero()
 const p2 = Vec3.zero()
 const p3 = Vec3.zero()
 
-export function Star(props?: StarProps) {
+export function Star(props?: StarProps): Primitive {
     const { outerRadius, innerRadius, thickness, pointCount } = { ...DefaultStarProps, ...props }
 
     const triangleCount = pointCount * 2 * 2

+ 1 - 1
src/mol-geo/primitive/tube.ts

@@ -18,7 +18,7 @@ const b = Vec3.zero()
 const u = Vec3.zero()
 const v = Vec3.zero()
 
-export function addTube(controlPoints: Helpers.NumberArray, normalVectors: Helpers.NumberArray, binormalVectors: Helpers.NumberArray, linearSegments: number, radialSegments: number, width: number, height: number, waveFactor: number, startCap: boolean, endCap: boolean, state: MeshBuilderState) {
+export function addTube(controlPoints: ArrayLike<number>, normalVectors: ArrayLike<number>, binormalVectors: ArrayLike<number>, linearSegments: number, radialSegments: number, width: number, height: number, waveFactor: number, startCap: boolean, endCap: boolean, state: MeshBuilderState) {
     const { vertices, normals, indices } = state
 
     let vertexCount = vertices.elementCount

+ 2 - 1
src/mol-geo/primitive/wedge.ts

@@ -5,6 +5,7 @@
  */
 
 import { Vec3 } from 'mol-math/linear-algebra'
+import { Primitive } from './primitive';
 
 export const DefaultWedgeProps = {
     width: 1,
@@ -31,7 +32,7 @@ const nacdf = Vec3.zero()
 
 const s = Vec3.zero()
 
-export function Wedge(props?: WedgeProps) {
+export function Wedge(props?: WedgeProps): Primitive {
     const { width, height, depth } = { ...DefaultWedgeProps, ...props }
 
     const vertices = new Float32Array(54)

+ 15 - 1
src/mol-geo/representation/structure/visual/carbohydrate-symbol-mesh.ts

@@ -28,6 +28,8 @@ async function createCarbohydrateSymbolMesh(ctx: RuntimeContext, structure: Stru
     const builder = MeshBuilder.create(256, 128, mesh)
 
     const t = Mat4.identity()
+    const sMat = Mat4.identity()
+    const sVec = Vec3.zero()
     const p = Vec3.zero()
     const pd = Vec3.zero()
     const p1 = Vec3.zero()
@@ -54,11 +56,12 @@ async function createCarbohydrateSymbolMesh(ctx: RuntimeContext, structure: Stru
         const shapeType = getSaccharideShape(c.component.type)
         switch (shapeType) {
             case SaccharideShapes.FilledSphere:
-                builder.addIcosahedron(cGeo.center, radius, 2)
+                builder.addSphere(cGeo.center, radius, 2)
                 break;
             case SaccharideShapes.FilledCube:
                 centerAlign(cGeo.center, cGeo.normal, cGeo.direction)
                 builder.addBox(t, { width: side, height: side, depth: side })
+                builder.addOctahedron(t)
                 break;
             case SaccharideShapes.CrossedCube:
                 // TODO split
@@ -85,7 +88,18 @@ async function createCarbohydrateSymbolMesh(ctx: RuntimeContext, structure: Stru
                 builder.addStar(t, { outerRadius: side, innerRadius: side / 2, thickness: side / 2, pointCount: 5 })
                 break
             case SaccharideShapes.FilledDiamond:
+                centerAlign(cGeo.center, cGeo.normal, cGeo.direction)
+                Mat4.fromScaling(sMat, Vec3.set(sVec, side * 1.4, side * 1.4, side * 1.4))
+                Mat4.mul(t, t, sMat)
+                builder.addOctahedron(t)
+                break
             case SaccharideShapes.DividedDiamond:
+                // TODO split
+                centerAlign(cGeo.center, cGeo.normal, cGeo.direction)
+                Mat4.fromScaling(sMat, Vec3.set(sVec, side * 1.4, side * 1.4, side * 1.4))
+                Mat4.mul(t, t, sMat)
+                builder.addOctahedron(t)
+                break
             case SaccharideShapes.FlatDiamond:
             case SaccharideShapes.Pentagon:
                 centerAlign(cGeo.center, cGeo.normal, cGeo.direction)

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

@@ -46,7 +46,7 @@ async function createPolymerGapCylinderMesh(ctx: RuntimeContext, unit: Unit, mes
         if (centerA.element === centerB.element) {
             builder.setId(centerA.element)
             pos(elements[centerA.element], pA)
-            builder.addIcosahedron(pA, 0.6, 0)
+            builder.addSphere(pA, 0.6, 0)
         } else {
             pos(elements[centerA.element], pA)
             pos(elements[centerB.element], pB)

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

@@ -8,7 +8,7 @@ import { Vec3 } from 'mol-math/linear-algebra';
 import { Unit, StructureElement } from 'mol-model/structure';
 import { SizeTheme } from '../../../../theme';
 import { RuntimeContext } from 'mol-task';
-import { icosahedronVertexCount } from '../../../../primitive/icosahedron';
+import { sphereVertexCount } from '../../../../primitive/sphere';
 import { Mesh } from '../../../../shape/mesh';
 import { MeshBuilder } from '../../../../shape/mesh-builder';
 import { ValueCell, defaults } from 'mol-util';
@@ -33,7 +33,7 @@ export function getElementRadius(unit: Unit, props: SizeTheme): StructureElement
 export async function createElementSphereMesh(ctx: RuntimeContext, unit: Unit, radius: StructureElement.Property<number>, detail: number, mesh?: Mesh) {
     const { elements } = unit;
     const elementCount = elements.length;
-    const vertexCount = elementCount * icosahedronVertexCount(detail)
+    const vertexCount = elementCount * sphereVertexCount(detail)
     const meshBuilder = MeshBuilder.create(vertexCount, vertexCount / 2, mesh)
 
     const v = Vec3.zero()
@@ -46,7 +46,7 @@ export async function createElementSphereMesh(ctx: RuntimeContext, unit: Unit, r
         pos(elements[i], v)
 
         meshBuilder.setId(i)
-        meshBuilder.addIcosahedron(v, radius(l), detail)
+        meshBuilder.addSphere(v, radius(l), detail)
 
         if (i % 10000 === 0 && ctx.shouldUpdate) {
             await ctx.update({ message: 'Sphere mesh', current: i, max: elementCount });

+ 28 - 27
src/mol-geo/shape/mesh-builder.ts

@@ -12,18 +12,14 @@ import { Box, BoxProps } from '../primitive/box';
 import { Plane, PlaneProps } from '../primitive/plane';
 import { Wedge, WedgeProps } from '../primitive/wedge';
 import { Cylinder, CylinderProps } from '../primitive/cylinder';
-import { Icosahedron, IcosahedronProps } from '../primitive/icosahedron';
+import { Sphere, SphereProps } from '../primitive/sphere';
 import { Mesh } from './mesh';
 import { getNormalMatrix } from '../util';
 import { addSheet } from '../primitive/sheet';
 import { addTube } from '../primitive/tube';
 import { StarProps, Star } from '../primitive/star';
-
-interface Primitive {
-    vertices: Float32Array
-    normals: Float32Array
-    indices: Uint32Array
-}
+import { Octahedron } from '../primitive/octahedron';
+import { Primitive } from '../primitive/primitive';
 
 export interface MeshBuilderState {
     vertices: ChunkedArray<number, 3>
@@ -32,23 +28,24 @@ export interface MeshBuilderState {
 }
 
 export interface MeshBuilder {
-    add(t: Mat4, _vertices: Float32Array, _normals: Float32Array, _indices?: Uint32Array): void
+    add(t: Mat4, _vertices: ArrayLike<number>, _normals: ArrayLike<number>, _indices?: ArrayLike<number>): void
     addBox(t: Mat4, props?: BoxProps): void
     addPlane(t: Mat4, props?: PlaneProps): void
     addWedge(t: Mat4, props?: WedgeProps): void
     addStar(t: Mat4, props?: StarProps): void
+    addOctahedron(t: Mat4): void
     addCylinder(start: Vec3, end: Vec3, lengthScale: number, props: CylinderProps): void
     addDoubleCylinder(start: Vec3, end: Vec3, lengthScale: number, shift: Vec3, props: CylinderProps): void
     addFixedCountDashedCylinder(start: Vec3, end: Vec3, lengthScale: number, segmentCount: number, props: CylinderProps): void
-    addIcosahedron(center: Vec3, radius: number, detail: number): void
-    addTube(centers: Helpers.NumberArray, normals: Helpers.NumberArray, binormals: Helpers.NumberArray, linearSegments: number, radialSegments: number, width: number, height: number, waveFactor: number, startCap: boolean, endCap: boolean): void
-    addSheet(centers: Helpers.NumberArray, normals: Helpers.NumberArray, binormals: Helpers.NumberArray, linearSegments: number, width: number, height: number, arrowHeight: number, startCap: boolean, endCap: boolean): void
+    addSphere(center: Vec3, radius: number, detail: number): void
+    addTube(centers: ArrayLike<number>, normals: ArrayLike<number>, binormals: ArrayLike<number>, linearSegments: number, radialSegments: number, width: number, height: number, waveFactor: number, startCap: boolean, endCap: boolean): void
+    addSheet(centers: ArrayLike<number>, normals: ArrayLike<number>, binormals: ArrayLike<number>, linearSegments: number, width: number, height: number, arrowHeight: number, startCap: boolean, endCap: boolean): void
     setId(id: number): void
     getMesh(): Mesh
 }
 
 const cylinderMap = new Map<string, Primitive>()
-const icosahedronMap = new Map<string, Primitive>()
+const sphereMap = new Map<string, Primitive>()
 
 const up = Vec3.create(0, 1, 0)
 const tmpV = Vec3.zero()
@@ -83,20 +80,20 @@ function getCylinder(props: CylinderProps) {
     return cylinder
 }
 
-const tmpIcosahedronMat = Mat4.identity()
+const tmpSphereMat = Mat4.identity()
 
-function setIcosahedronMat(m: Mat4, center: Vec3) {
+function setSphereMat(m: Mat4, center: Vec3) {
     return Mat4.setTranslation(m, center)
 }
 
-function getIcosahedron(props: IcosahedronProps) {
+function getSphere(props: SphereProps) {
     const key = JSON.stringify(props)
-    let icosahedron = icosahedronMap.get(key)
-    if (icosahedron === undefined) {
-        icosahedron = Icosahedron(props)
-        icosahedronMap.set(key, icosahedron)
+    let sphere = sphereMap.get(key)
+    if (sphere === undefined) {
+        sphere = Sphere(props)
+        sphereMap.set(key, sphere)
     }
-    return icosahedron
+    return sphere
 }
 
 // TODO cache primitives based on props
@@ -113,7 +110,7 @@ export namespace MeshBuilder {
 
         let currentId = -1
 
-        function add(t: Mat4, _vertices: Float32Array, _normals: Float32Array, _indices: Uint32Array) {
+        function add(t: Mat4, _vertices: ArrayLike<number>, _normals: ArrayLike<number>, _indices: ArrayLike<number>) {
             const { elementCount } = vertices
             const n = getNormalMatrix(tmpMat3, t)
             for (let i = 0, il = _vertices.length; i < il; i += 3) {
@@ -151,6 +148,10 @@ export namespace MeshBuilder {
                 const { vertices, normals, indices } = Star(props)
                 add(t, vertices, normals, indices)
             },
+            addOctahedron: (t: Mat4) => {
+                const { vertices, normals, indices } = Octahedron()
+                add(t, vertices, normals, indices)
+            },
             addCylinder: (start: Vec3, end: Vec3, lengthScale: number, props: CylinderProps) => {
                 const d = Vec3.distance(start, end) * lengthScale
                 props.height = d
@@ -197,16 +198,16 @@ export namespace MeshBuilder {
                     add(tmpCylinderMat, vertices, normals, indices)
                 }
             },
-            addIcosahedron: (center: Vec3, radius: number, detail: number) => {
-                const { vertices, normals, indices } = getIcosahedron({ radius, detail })
-                setIcosahedronMat(tmpIcosahedronMat, center)
-                add(tmpIcosahedronMat, vertices, normals, indices)
+            addSphere: (center: Vec3, radius: number, detail: number) => {
+                const { vertices, normals, indices } = getSphere({ radius, detail })
+                setSphereMat(tmpSphereMat, center)
+                add(tmpSphereMat, vertices, normals, indices)
             },
-            addTube: (centers: Helpers.NumberArray, normals: Helpers.NumberArray, binormals: Helpers.NumberArray, linearSegments: number, radialSegments: number, width: number, height: number, waveFactor: number, startCap: boolean, endCap: boolean) => {
+            addTube: (centers: ArrayLike<number>, normals: ArrayLike<number>, binormals: ArrayLike<number>, linearSegments: number, radialSegments: number, width: number, height: number, waveFactor: number, startCap: boolean, endCap: boolean) => {
                 const addedVertexCount = addTube(centers, normals, binormals, linearSegments, radialSegments, width, height, waveFactor, startCap, endCap, state)
                 for (let i = 0, il = addedVertexCount; i < il; ++i) ChunkedArray.add(ids, currentId);
             },
-            addSheet: (controls: Helpers.NumberArray, normals: Helpers.NumberArray, binormals: Helpers.NumberArray, linearSegments: number, width: number, height: number, arrowHeight: number, startCap: boolean, endCap: boolean) => {
+            addSheet: (controls: ArrayLike<number>, normals: ArrayLike<number>, binormals: ArrayLike<number>, linearSegments: number, width: number, height: number, arrowHeight: number, startCap: boolean, endCap: boolean) => {
                 const addedVertexCount = addSheet(controls, normals, binormals, linearSegments, width, height, arrowHeight, startCap, endCap, state)
                 for (let i = 0, il = addedVertexCount; i < il; ++i) ChunkedArray.add(ids, currentId);
             },

+ 1 - 1
src/mol-math/linear-algebra/3d/vec3.ts

@@ -46,7 +46,7 @@ namespace Vec3 {
         return { x: v[0], y: v[1], z: v[2] };
     }
 
-    export function fromArray(v: Vec3, array: Helpers.NumberArray, offset: number) {
+    export function fromArray(v: Vec3, array: ArrayLike<number>, offset: number) {
         v[0] = array[offset + 0]
         v[1] = array[offset + 1]
         v[2] = array[offset + 2]