diff --git a/src/apps/canvas/assembly-symmetry.ts b/src/apps/canvas/assembly-symmetry.ts
index 0fe6a734730dd50f51c2a8af3ba15af36d5c0517..f4cdb2888466a56c6f9babcc311ea010249714db 100644
--- a/src/apps/canvas/assembly-symmetry.ts
+++ b/src/apps/canvas/assembly-symmetry.ts
@@ -66,10 +66,10 @@ export function getClusterColorTheme(symmetryId: number, assemblySymmetry: Assem
const DefaultColor = Color(0xCCCCCC)
const s = assemblySymmetry.db.rcsb_assembly_symmetry
const symmetry = Table.pickRow(s, i => s.id.value(i) === symmetryId)
- if (!symmetry) return { granularity: 'uniform', color: () => DefaultColor }
+ if (!symmetry) return { features: {}, granularity: 'uniform', color: () => DefaultColor }
const clusters = assemblySymmetry.getClusters(symmetryId)
- if (!clusters._rowCount) return { granularity: 'uniform', color: () => DefaultColor }
+ if (!clusters._rowCount) return { features: {}, granularity: 'uniform', color: () => DefaultColor }
const clusterByMember = new Map<string, number>()
for (let i = 0, il = clusters._rowCount; i < il; ++i) {
@@ -83,6 +83,7 @@ export function getClusterColorTheme(symmetryId: number, assemblySymmetry: Assem
const scale = ColorScale.create({ domain: [ 0, clusters._rowCount - 1 ] })
return {
+ features: {},
granularity: 'instance',
color: (location: Location): Color => {
if (StructureElement.isLocation(location)) {
diff --git a/src/apps/canvas/component/representation.tsx b/src/apps/canvas/component/representation.tsx
index 02fcdea19363ea0b39cc1db364d986908efd46a0..bb68eed9c9f071ec7741879df1e891a9c3422d84 100644
--- a/src/apps/canvas/component/representation.tsx
+++ b/src/apps/canvas/component/representation.tsx
@@ -41,7 +41,8 @@ export class RepresentationComponent extends React.Component<RepresentationCompo
}
async onChange(k: string, v: any) {
- await this.props.app.runTask(this.props.repr.createOrUpdate({ [k]: v }).run(
+ const ctx = { webgl: this.props.canvas3d.webgl }
+ await this.props.app.runTask(this.props.repr.createOrUpdate(ctx, { [k]: v }).run(
progress => this.props.app.log(progress)
), 'Representation Update')
this.props.canvas3d.add(this.props.repr)
diff --git a/src/apps/canvas/index.ts b/src/apps/canvas/index.ts
index cbc1a3a568a9c81c31a702134dce10a4c80471d7..dd72f8aaa98406272ed4a2d583781a38dc97743e 100644
--- a/src/apps/canvas/index.ts
+++ b/src/apps/canvas/index.ts
@@ -25,8 +25,8 @@ if (pdbId) app.loadPdbIdOrMmcifUrl(pdbId, { assemblyId })
// app.loadPdbIdOrMmcifUrl('http://localhost:8091/ngl/data/1crn.cif')
-app.loadPdbIdOrMmcifUrl('3pqr')
-app.loadCcp4Url('http://localhost:8091/ngl/data/3pqr-mode0.ccp4')
+// app.loadPdbIdOrMmcifUrl('3pqr')
+// app.loadCcp4Url('http://localhost:8091/ngl/data/3pqr-mode0.ccp4')
// app.loadPdbIdOrMmcifUrl('1lee')
// app.loadCcp4Url('http://localhost:8091/ngl/data/1lee.ccp4')
diff --git a/src/apps/canvas/structure-view.ts b/src/apps/canvas/structure-view.ts
index 80bcac4134052e676c5ef77439c9131291fdb244..eeff5581a4cb6d4dcc4e95fe1055642be4122aee 100644
--- a/src/apps/canvas/structure-view.ts
+++ b/src/apps/canvas/structure-view.ts
@@ -208,8 +208,7 @@ export async function StructureView(app: App, canvas3d: Canvas3D, models: Readon
console.log('createStructureRepr')
for (const k in structureRepresentations) {
if (active[k]) {
- const p = { webgl: canvas3d.webgl }
- await app.runTask(structureRepresentations[k].createOrUpdate(p, structure).run(
+ await app.runTask(structureRepresentations[k].createOrUpdate({ webgl: canvas3d.webgl }, {}, structure).run(
progress => app.log(progress)
), 'Create/update representation')
canvas3d.add(structureRepresentations[k])
@@ -265,7 +264,7 @@ export async function StructureView(app: App, canvas3d: Canvas3D, models: Readon
// colorFunction: colorTheme.color,
// colorGranularity: colorTheme.granularity,
// }).run()
- await symmetryAxes.createOrUpdate({}, axesShape).run()
+ await symmetryAxes.createOrUpdate({ webgl: canvas3d.webgl }, {}, axesShape).run()
canvas3d.add(symmetryAxes)
} else {
canvas3d.remove(symmetryAxes)
diff --git a/src/apps/canvas/volume-view.ts b/src/apps/canvas/volume-view.ts
index bfe46d0e444d3047eea21886908b1d1b7ffba373..6c05559ef90422c25527822337f72f7e0e602d02 100644
--- a/src/apps/canvas/volume-view.ts
+++ b/src/apps/canvas/volume-view.ts
@@ -54,8 +54,7 @@ export async function VolumeView(app: App, viewer: Canvas3D, volume: VolumeData,
async function createVolumeRepr() {
for (const k in volumeRepresentations) {
if (active[k]) {
- const p = { webgl: viewer.webgl }
- await app.runTask(volumeRepresentations[k].createOrUpdate(p, volume).run(
+ await app.runTask(volumeRepresentations[k].createOrUpdate({ webgl: viewer.webgl }, {}, volume).run(
progress => app.log(progress)
), 'Create/update representation')
viewer.add(volumeRepresentations[k])
diff --git a/src/apps/structure-info/volume.ts b/src/apps/structure-info/volume.ts
index 3b7d8cc3f184d882b534f7c38417a8abfb91e6f0..d9921d7a4003693e1827c0db22399a3e6d2c73dd 100644
--- a/src/apps/structure-info/volume.ts
+++ b/src/apps/structure-info/volume.ts
@@ -38,7 +38,7 @@ function print(data: Volume) {
}
async function doMesh(data: Volume, filename: string) {
- const mesh = await Task.create('', ctx => createVolumeIsosurface(ctx, data.volume, { isoValueAbsolute: VolumeIsoValue.calcAbsolute(data.volume.dataStats, 1.5) } )).run();
+ const mesh = await Task.create('', runtime => createVolumeIsosurface({ runtime }, data.volume, { isoValueAbsolute: VolumeIsoValue.calcAbsolute(data.volume.dataStats, 1.5) } )).run();
console.log({ vc: mesh.vertexCount, tc: mesh.triangleCount });
// Export the mesh in OBJ format.
diff --git a/src/mol-canvas3d/canvas3d.ts b/src/mol-canvas3d/canvas3d.ts
index 0d21ff0bebd0beaaf279e0a18f2b6c0bb5562fc6..ee2a3c419d1fd59cc3d3a8a74233db8c335b687a 100644
--- a/src/mol-canvas3d/canvas3d.ts
+++ b/src/mol-canvas3d/canvas3d.ts
@@ -24,10 +24,17 @@ import { PickingId, decodeIdRGB } from 'mol-geo/geometry/picking';
import { MarkerAction } from 'mol-geo/geometry/marker-data';
import { Loci, EmptyLoci, isEmptyLoci } from 'mol-model/loci';
import { Color } from 'mol-util/color';
-import { CombinedCamera } from './camera/combined';
+import { CombinedCamera, CombinedCameraMode } from './camera/combined';
+
+export const DefaultCanvas3DProps = {
+ cameraPosition: Vec3.create(0, 0, 50),
+ cameraMode: 'perspective' as CombinedCameraMode,
+ backgroundColor: Color(0x000000),
+}
+export type Canvas3DProps = typeof DefaultCanvas3DProps
interface Canvas3D {
- webgl: WebGLContext,
+ readonly webgl: WebGLContext,
center: (p: Vec3) => void
@@ -47,23 +54,27 @@ interface Canvas3D {
mark: (loci: Loci, action: MarkerAction) => void
getLoci: (pickingId: PickingId) => Loci
- reprCount: BehaviorSubject<number>
- identified: BehaviorSubject<string>
- didDraw: BehaviorSubject<number>
+ readonly reprCount: BehaviorSubject<number>
+ readonly identified: BehaviorSubject<string>
+ readonly didDraw: BehaviorSubject<number>
handleResize: () => void
resetCamera: () => void
- camera: CombinedCamera
+ readonly camera: CombinedCamera
downloadScreenshot: () => void
getImageData: (variant: RenderVariant) => ImageData
- input: InputObserver
- stats: RendererStats
+ /** Returns a copy of the current Canvas3D instance props */
+ readonly props: Canvas3DProps
+ readonly input: InputObserver
+ readonly stats: RendererStats
dispose: () => void
}
namespace Canvas3D {
- export function create(canvas: HTMLCanvasElement, container: Element): Canvas3D {
+ export function create(canvas: HTMLCanvasElement, container: Element, props: Partial<Canvas3DProps> = {}): Canvas3D {
+ const p = { ...props, ...DefaultCanvas3DProps }
+
const reprMap = new Map<Representation<any>, Set<RenderObject>>()
const reprCount = new BehaviorSubject(0)
const identified = new BehaviorSubject('')
@@ -75,14 +86,9 @@ namespace Canvas3D {
const camera = CombinedCamera.create({
near: 0.1,
far: 10000,
- position: Vec3.create(0, 0, 50),
- mode: 'orthographic'
+ position: Vec3.clone(p.cameraPosition),
+ mode: p.cameraMode
})
- // const camera = OrthographicCamera.create({
- // zoom: 8,
- // position: Vec3.create(0, 0, 50)
- // })
- // camera.lookAt(Vec3.create(0, 0, 0))
const gl = getGLContext(canvas, {
alpha: false,
@@ -93,18 +99,18 @@ namespace Canvas3D {
if (gl === null) {
throw new Error('Could not create a WebGL rendering context')
}
- const ctx = createContext(gl)
+ const webgl = createContext(gl)
- const scene = Scene.create(ctx)
+ const scene = Scene.create(webgl)
const controls = TrackballControls.create(input, camera, {})
- const renderer = Renderer.create(ctx, camera, { clearColor: Color(0x000000) })
+ const renderer = Renderer.create(webgl, camera, { clearColor: p.backgroundColor })
const pickScale = 1
const pickWidth = Math.round(canvas.width * pickScale)
const pickHeight = Math.round(canvas.height * pickScale)
- const objectPickTarget = createRenderTarget(ctx, pickWidth, pickHeight)
- const instancePickTarget = createRenderTarget(ctx, pickWidth, pickHeight)
- const groupPickTarget = createRenderTarget(ctx, pickWidth, pickHeight)
+ const objectPickTarget = createRenderTarget(webgl, pickWidth, pickHeight)
+ const instancePickTarget = createRenderTarget(webgl, pickWidth, pickHeight)
+ const groupPickTarget = createRenderTarget(webgl, pickWidth, pickHeight)
let pickDirty = true
let isPicking = false
@@ -173,7 +179,7 @@ namespace Canvas3D {
case 'pickInstance': instancePickTarget.bind(); break;
case 'pickGroup': groupPickTarget.bind(); break;
case 'draw':
- ctx.unbindFramebuffer();
+ webgl.unbindFramebuffer();
renderer.setViewport(0, 0, canvas.width, canvas.height);
break;
}
@@ -219,7 +225,7 @@ namespace Canvas3D {
render('pickObject', pickDirty)
render('pickInstance', pickDirty)
render('pickGroup', pickDirty)
- ctx.gl.finish()
+ webgl.gl.finish()
pickDirty = false
}
@@ -229,8 +235,8 @@ namespace Canvas3D {
isPicking = true
- x *= ctx.pixelRatio
- y *= ctx.pixelRatio
+ x *= webgl.pixelRatio
+ y *= webgl.pixelRatio
y = canvas.height - y // flip y
const buffer = new Uint8Array(4)
@@ -238,15 +244,15 @@ namespace Canvas3D {
const yp = Math.round(y * pickScale)
objectPickTarget.bind()
- await ctx.readPixelsAsync(xp, yp, 1, 1, buffer)
+ await webgl.readPixelsAsync(xp, yp, 1, 1, buffer)
const objectId = decodeIdRGB(buffer[0], buffer[1], buffer[2])
instancePickTarget.bind()
- await ctx.readPixels(xp, yp, 1, 1, buffer)
+ await webgl.readPixels(xp, yp, 1, 1, buffer)
const instanceId = decodeIdRGB(buffer[0], buffer[1], buffer[2])
groupPickTarget.bind()
- await ctx.readPixels(xp, yp, 1, 1, buffer)
+ await webgl.readPixels(xp, yp, 1, 1, buffer)
const groupId = decodeIdRGB(buffer[0], buffer[1], buffer[2])
isPicking = false
@@ -262,7 +268,7 @@ namespace Canvas3D {
handleResize()
return {
- webgl: ctx,
+ webgl,
center: (p: Vec3) => {
Vec3.set(controls.target, p[0], p[1], p[2])
@@ -336,6 +342,13 @@ namespace Canvas3D {
identified,
didDraw,
+ get props() {
+ return {
+ cameraPosition: Vec3.clone(camera.position),
+ cameraMode: camera.mode,
+ backgroundColor: renderer.props.clearColor
+ }
+ },
get input() {
return input
},
diff --git a/src/mol-geo/geometry/color-data.ts b/src/mol-geo/geometry/color-data.ts
index cc66f80c9edd161b5a518d38acab4be1f9faedc1..59c2a16686bd0a4a97ee1e3877f51995965482c4 100644
--- a/src/mol-geo/geometry/color-data.ts
+++ b/src/mol-geo/geometry/color-data.ts
@@ -6,11 +6,11 @@
import { ValueCell } from 'mol-util';
import { TextureImage, createTextureImage } from 'mol-gl/renderable/util';
-import { Color } from 'mol-util/color';
+import { Color, ColorMap } from 'mol-util/color';
import { Vec2, Vec3 } from 'mol-math/linear-algebra';
import { LocationIterator } from '../util/location-iterator';
import { NullLocation } from 'mol-model/location';
-import { LocationColor, ColorThemeProps, ColorTheme, ColorThemeName, ScaleLegend, TableLegend } from 'mol-theme/color';
+import { LocationColor, ColorThemeProps, ColorTheme, ColorThemeName, ScaleLegend, TableLegend, ColorScaleName, getColorScaleFromName } from 'mol-theme/color';
import { RuntimeContext } from 'mol-task';
import { getGranularity } from './geometry';
import { Structure } from 'mol-model/structure';
@@ -27,6 +27,8 @@ export type ColorData = {
export interface ColorProps {
colorTheme: ColorThemeName
+ colorList?: Color[] | ColorScaleName
+ colorMap?: ColorMap<any>
colorDomain?: [number, number]
colorValue?: Color
colorFunction?: LocationColor,
@@ -41,6 +43,10 @@ export function getColorThemeProps(props: ColorProps): ColorThemeProps {
name: props.colorTheme
}
if (props.colorDomain !== undefined) p.domain = props.colorDomain
+ if (props.colorList !== undefined) {
+ p.list = typeof props.colorList === 'string' ? getColorScaleFromName(props.colorList) : props.colorList
+ }
+ if (props.colorMap !== undefined) p.map = props.colorMap
if (props.colorValue !== undefined) p.value = props.colorValue
if (props.structure !== undefined) p.structure = props.structure
if (props.colorFunction !== undefined) p.color = props.colorFunction
diff --git a/src/mol-geo/geometry/direct-volume/transfer-function.ts b/src/mol-geo/geometry/direct-volume/transfer-function.ts
index 98f496f143517cebdb1345d5a7a48168ecb9b94b..1679daa27fe7867c4e128141509e5bdd362f4a41 100644
--- a/src/mol-geo/geometry/direct-volume/transfer-function.ts
+++ b/src/mol-geo/geometry/direct-volume/transfer-function.ts
@@ -29,7 +29,7 @@ export function createTransferFunctionTexture(controlPoints: ControlPoint[], tex
]
const scale = ColorScale.create({
domain: [0, 1],
- colors: ColorMatplotlib.viridis
+ list: ColorMatplotlib.viridis
})
const n = 256
diff --git a/src/mol-geo/geometry/geometry.ts b/src/mol-geo/geometry/geometry.ts
index a1e1e221eb5315ced13742d3db3bb1199d44a1ed..57df5ab488d3f3c0d6f006ca8a4cf15223d8de6a 100644
--- a/src/mol-geo/geometry/geometry.ts
+++ b/src/mol-geo/geometry/geometry.ts
@@ -10,14 +10,13 @@ import { RenderableState } from 'mol-gl/renderable';
import { ValueCell } from 'mol-util';
import { BaseValues } from 'mol-gl/renderable/schema';
import { Color } from 'mol-util/color';
-import { ColorThemeOptions, ColorThemeName } from 'mol-theme/color';
+import { ColorThemeOptions, ColorThemeName, ColorScaleOptions, ColorScaleName } from 'mol-theme/color';
import { LocationIterator } from '../util/location-iterator';
import { ColorType } from './color-data';
import { SizeType } from './size-data';
import { Lines } from './lines/lines';
-import { paramDefaultValues, RangeParam, BooleanParam, SelectParam, ColorParam, ValueParam } from 'mol-util/parameter'
+import { paramDefaultValues, RangeParam, BooleanParam, SelectParam, ColorParam } from 'mol-util/parameter'
import { DirectVolume } from './direct-volume/direct-volume';
-import { WebGLContext } from 'mol-gl/webgl/context';
//
@@ -66,8 +65,8 @@ export namespace Geometry {
useFog: BooleanParam('Use Fog', '', false),
quality: SelectParam<VisualQuality>('Quality', '', 'auto', VisualQualityOptions),
colorTheme: SelectParam<ColorThemeName>('Color Theme', '', 'uniform', ColorThemeOptions),
+ colorList: SelectParam<ColorScaleName>('Color Scale', '', 'default', ColorScaleOptions),
colorValue: ColorParam('Color Value', '', Color(0xCCCCCC)),
- webgl: ValueParam('WebGL Context', '', undefined as WebGLContext | undefined),
}
export const DefaultProps = paramDefaultValues(Params)
export type Props = typeof DefaultProps
diff --git a/src/mol-geo/util/marching-cubes/algorithm.ts b/src/mol-geo/util/marching-cubes/algorithm.ts
index d58abc44f87cd0931485a462cac063bcf27b8b35..e9d9e4ad46ee87691bc4c9d34b01dfe8a476b071 100644
--- a/src/mol-geo/util/marching-cubes/algorithm.ts
+++ b/src/mol-geo/util/marching-cubes/algorithm.ts
@@ -105,9 +105,7 @@ class MarchingCubesComputation {
}
async run() {
- await this.ctx.update({ message: 'Computing surface...', current: 0, max: this.size });
await this.doSlices();
- await this.ctx.update('Finalizing...');
}
constructor(private ctx: RuntimeContext, builder: MarchinCubesBuilder<any>, params: MarchingCubesInputParams) {
diff --git a/src/mol-gl/renderer.ts b/src/mol-gl/renderer.ts
index 39e422e602689b06f7b258b87f47655bb57bc235..4234cc38fb50fc17c1b144e2750d4c2a28049e54 100644
--- a/src/mol-gl/renderer.ts
+++ b/src/mol-gl/renderer.ts
@@ -34,6 +34,7 @@ export interface RendererStats {
interface Renderer {
readonly stats: RendererStats
+ readonly props: RendererProps
render: (scene: Scene, variant: RenderVariant) => void
setViewport: (x: number, y: number, width: number, height: number) => void
@@ -46,10 +47,10 @@ export const DefaultRendererProps = {
clearColor: 0x000000 as Color,
viewport: Viewport.create(0, 0, 0, 0)
}
-export type RendererProps = Partial<typeof DefaultRendererProps>
+export type RendererProps = typeof DefaultRendererProps
namespace Renderer {
- export function create(ctx: WebGLContext, camera: Camera, props: RendererProps = {}): Renderer {
+ export function create(ctx: WebGLContext, camera: Camera, props: Partial<RendererProps> = {}): Renderer {
const { gl } = ctx
let { clearColor, viewport: _viewport } = { ...DefaultRendererProps, ...props }
@@ -64,6 +65,7 @@ namespace Renderer {
const fogColor = Vec3.create(0.0, 0.0, 0.0)
function setClearColor(color: Color) {
+ clearColor = color
const [ r, g, b ] = Color.toRgbNormalized(color)
gl.clearColor(r, g, b, 1.0)
}
@@ -192,6 +194,12 @@ namespace Renderer {
return createImageData(buffer, width, height)
},
+ get props() {
+ return {
+ clearColor,
+ viewport
+ }
+ },
get stats(): RendererStats {
return {
programCount: ctx.programCache.count,
diff --git a/src/mol-math/geometry/gaussian-density.ts b/src/mol-math/geometry/gaussian-density.ts
index fc89c5fe9491713933427a86905aef784ec5576f..91675ddc156b804814c7651fbfbe88daebd335eb 100644
--- a/src/mol-math/geometry/gaussian-density.ts
+++ b/src/mol-math/geometry/gaussian-density.ts
@@ -21,7 +21,6 @@ export const DefaultGaussianDensityProps = {
radiusOffset: 0,
smoothness: 1.5,
useGpu: true,
- webgl: undefined as WebGLContext | undefined
}
export type GaussianDensityProps = typeof DefaultGaussianDensityProps
@@ -39,10 +38,11 @@ export function computeGaussianDensity(position: PositionData, box: Box3D, radiu
});
}
-export async function GaussianDensity(ctx: RuntimeContext, position: PositionData, box: Box3D, radius: (index: number) => number, props: GaussianDensityProps): Promise<DensityData> {
+export async function GaussianDensity(ctx: RuntimeContext, position: PositionData, box: Box3D, radius: (index: number) => number, props: GaussianDensityProps, webgl?: WebGLContext): Promise<DensityData> {
if (props.useGpu) {
if (!GaussianDensityGPU) throw 'GPU computation not supported on this platform';
- return await GaussianDensityGPU(ctx, position, box, radius, props)
+ if (!webgl) throw 'No WebGL context provided';
+ return await GaussianDensityGPU(ctx, position, box, radius, props, webgl)
} else {
return await GaussianDensityCPU(ctx, position, box, radius, props)
}
diff --git a/src/mol-math/geometry/gaussian-density/gpu.ts b/src/mol-math/geometry/gaussian-density/gpu.ts
index 32dda1527f3999e14aa5d04694d08a849a106f39..e14fb754a15fa825b4b1b98dcfda5593a076c65e 100644
--- a/src/mol-math/geometry/gaussian-density/gpu.ts
+++ b/src/mol-math/geometry/gaussian-density/gpu.ts
@@ -12,10 +12,10 @@ import { GaussianDensityProps, getDelta } from '../gaussian-density'
import { OrderedSet } from 'mol-data/int'
import { Vec3, Tensor, Mat4 } from '../../linear-algebra'
import { GaussianDensityValues } from 'mol-gl/renderable/gaussian-density'
-import { ValueCell, defaults } from 'mol-util'
+import { ValueCell } from 'mol-util'
import { RenderableState, Renderable } from 'mol-gl/renderable'
import { createRenderable, createGaussianDensityRenderObject } from 'mol-gl/render-object'
-import { WebGLContext, createContext, getGLContext } from 'mol-gl/webgl/context';
+import { WebGLContext } from 'mol-gl/webgl/context';
import { createTexture, Texture } from 'mol-gl/webgl/texture';
import { GLRenderingContext } from 'mol-gl/webgl/compat';
import { decodeIdRGB } from 'mol-geo/geometry/picking';
@@ -23,8 +23,7 @@ import { decodeIdRGB } from 'mol-geo/geometry/picking';
/** name for shared framebuffer used for gpu gaussian surface operations */
const FramebufferName = 'gaussian-density-gpu'
-export async function GaussianDensityGPU(ctx: RuntimeContext, position: PositionData, box: Box3D, radius: (index: number) => number, props: GaussianDensityProps): Promise<DensityData> {
- const webgl = defaults(props.webgl, getWebGLContext())
+export async function GaussianDensityGPU(ctx: RuntimeContext, position: PositionData, box: Box3D, radius: (index: number) => number, props: GaussianDensityProps, webgl: WebGLContext): Promise<DensityData> {
// always use texture2d when the gaussian density needs to be downloaded from the GPU,
// it's faster than texture3d
// console.time('GaussianDensityTexture2d')
@@ -110,7 +109,7 @@ async function GaussianDensityTexture2d(ctx: RuntimeContext, webgl: WebGLContext
setupGroupIdRendering(webgl, renderable)
render(texture)
- await ctx.update({ message: 'gpu gaussian density calculation' });
+ if (ctx.shouldUpdate) await ctx.update({ message: 'gpu gaussian density calculation' })
await webgl.waitForGpuCommandsComplete()
return { texture, scale: Vec3.inverse(Vec3.zero(), delta), bbox: expandedBox, dim }
@@ -165,21 +164,6 @@ async function GaussianDensityTexture3d(ctx: RuntimeContext, webgl: WebGLContext
//
-let webglContext: WebGLContext
-function getWebGLContext() {
- if (webglContext) return webglContext
- const canvas = document.createElement('canvas')
- const gl = getGLContext(canvas, {
- alpha: true,
- antialias: false,
- depth: false,
- preserveDrawingBuffer: true
- })
- if (!gl) throw new Error('Could not create a WebGL rendering context')
- webglContext = createContext(gl)
- return webglContext
-}
-
async function prepareGaussianDensityData(ctx: RuntimeContext, position: PositionData, box: Box3D, radius: (index: number) => number, props: GaussianDensityProps) {
const { resolution, radiusOffset } = props
diff --git a/src/mol-model/structure/structure/unit.ts b/src/mol-model/structure/structure/unit.ts
index bce4b286b1aa335ef0e8f6ec589d37161593cf70..fd41f3db12facc596554f41aacc7d8af0d36c489 100644
--- a/src/mol-model/structure/structure/unit.ts
+++ b/src/mol-model/structure/structure/unit.ts
@@ -20,6 +20,7 @@ import { getAtomicPolymerElements, getCoarsePolymerElements, getAtomicGapElement
import { getNucleotideElements } from './util/nucleotide';
import { GaussianDensityProps, computeUnitGaussianDensityCached } from './unit/gaussian-density';
import { RuntimeContext } from 'mol-task';
+import { WebGLContext } from 'mol-gl/webgl/context';
// A building block of a structure that corresponds to an atomic or a coarse grained representation
// 'conveniently grouped together'.
@@ -182,8 +183,8 @@ namespace Unit {
return this.model.atomicHierarchy.residueAtomSegments.index[this.elements[elementIndex]];
}
- async computeGaussianDensity(props: GaussianDensityProps, ctx?: RuntimeContext) {
- return computeUnitGaussianDensityCached(this, props, this.props.gaussianDensities, ctx);
+ async computeGaussianDensity(props: GaussianDensityProps, ctx: RuntimeContext, webgl?: WebGLContext) {
+ return computeUnitGaussianDensityCached(this, props, this.props.gaussianDensities, ctx, webgl);
}
constructor(id: number, invariantId: number, model: Model, elements: StructureElement.Set, conformation: SymmetryOperator.ArrayMapping, props: AtomicProperties) {
@@ -271,8 +272,8 @@ namespace Unit {
return this.kind === Kind.Spheres ? this.model.coarseConformation.spheres : this.model.coarseConformation.gaussians;
}
- async computeGaussianDensity(props: GaussianDensityProps, ctx?: RuntimeContext): Promise<DensityData> {
- return computeUnitGaussianDensityCached(this as Unit.Spheres | Unit.Gaussians, props, this.props.gaussianDensities, ctx); // TODO get rid of casting
+ async computeGaussianDensity(props: GaussianDensityProps, ctx: RuntimeContext, webgl?: WebGLContext): Promise<DensityData> {
+ return computeUnitGaussianDensityCached(this as Unit.Spheres | Unit.Gaussians, props, this.props.gaussianDensities, ctx, webgl); // TODO get rid of casting
}
constructor(id: number, invariantId: number, model: Model, kind: K, elements: StructureElement.Set, conformation: SymmetryOperator.ArrayMapping, props: CoarseProperties) {
diff --git a/src/mol-model/structure/structure/unit/gaussian-density.ts b/src/mol-model/structure/structure/unit/gaussian-density.ts
index b7895e3def40aab3624de5784dfb76227297e1ec..66290495e89ffef7a61fccd29bdd6f2273369483 100644
--- a/src/mol-model/structure/structure/unit/gaussian-density.ts
+++ b/src/mol-model/structure/structure/unit/gaussian-density.ts
@@ -9,10 +9,10 @@ import { SizeTheme } from 'mol-theme/size';
import { GaussianDensity } from 'mol-math/geometry/gaussian-density';
import { Task, RuntimeContext } from 'mol-task';
import { DensityData } from 'mol-math/geometry';
-import { NumberParam, paramDefaultValues, BooleanParam, ValueParam } from 'mol-util/parameter';
-import { WebGLContext } from 'mol-gl/webgl/context';
+import { NumberParam, paramDefaultValues, BooleanParam } from 'mol-util/parameter';
import { GaussianDensityTexture } from 'mol-math/geometry/gaussian-density/gpu';
import { Texture } from 'mol-gl/webgl/texture';
+import { WebGLContext } from 'mol-gl/webgl/context';
export const GaussianDensityParams = {
resolution: NumberParam('Resolution', '', 1, 0.1, 10, 0.1),
@@ -20,7 +20,6 @@ export const GaussianDensityParams = {
smoothness: NumberParam('Smoothness', '', 1.5, 0.5, 2.5, 0.1),
useGpu: BooleanParam('Use GPU', '', true),
ignoreCache: BooleanParam('Ignore Cache', '', false),
- webgl: ValueParam('WebGL Context', '', undefined as WebGLContext | undefined),
}
export const DefaultGaussianDensityProps = paramDefaultValues(GaussianDensityParams)
export type GaussianDensityProps = typeof DefaultGaussianDensityProps
@@ -53,27 +52,25 @@ function getConformationAndRadius(unit: Unit) {
return { position, radius }
}
-export function computeUnitGaussianDensity(unit: Unit, props: GaussianDensityProps) {
+export function computeUnitGaussianDensity(unit: Unit, props: GaussianDensityProps, webgl?: WebGLContext) {
const { position, radius } = getConformationAndRadius(unit)
return Task.create('Gaussian Density', async ctx => {
- return await GaussianDensity(ctx, position, unit.lookup3d.boundary.box, radius, props);
+ return await GaussianDensity(ctx, position, unit.lookup3d.boundary.box, radius, props, webgl);
});
}
-export function computeUnitGaussianDensityTexture(unit: Unit, props: GaussianDensityProps, texture?: Texture) {
- const webgl = props.webgl
- if (!webgl) throw new Error('nned webgl context for computeUnitGaussianDensityTexture')
+export function computeUnitGaussianDensityTexture(unit: Unit, props: GaussianDensityProps, webgl: WebGLContext, texture?: Texture) {
const { position, radius } = getConformationAndRadius(unit)
return Task.create('Gaussian Density', async ctx => {
return await GaussianDensityTexture(ctx, webgl, position, unit.lookup3d.boundary.box, radius, props, texture);
});
}
-export async function computeUnitGaussianDensityCached(unit: Unit, props: GaussianDensityProps, cache: Map<string, DensityData>, ctx?: RuntimeContext) {
+export async function computeUnitGaussianDensityCached(unit: Unit, props: GaussianDensityProps, cache: Map<string, DensityData>, ctx: RuntimeContext, webgl?: WebGLContext) {
const key = `${props.radiusOffset}|${props.resolution}|${props.smoothness}`
let density = cache.get(key)
if (density && !props.ignoreCache) return density
- density = ctx ? await computeUnitGaussianDensity(unit, props).runInContext(ctx) : await computeUnitGaussianDensity(unit, props).run()
+ density = await computeUnitGaussianDensity(unit, props, webgl).runInContext(ctx)
if (!props.ignoreCache) cache.set(key, density)
return density
}
\ No newline at end of file
diff --git a/src/mol-plugin/state/transforms/visuals.ts b/src/mol-plugin/state/transforms/visuals.ts
index 9da25b631f8e6a6d03a2408c82d5fcc8c9d17a6b..f03e8bdc247dcf84d95b75ce2f31d88413e9cd48 100644
--- a/src/mol-plugin/state/transforms/visuals.ts
+++ b/src/mol-plugin/state/transforms/visuals.ts
@@ -18,13 +18,13 @@ export const CreateStructureRepresentation = PluginStateTransform.Create<SO.Stru
apply({ a, params }) {
return Task.create('Structure Representation', async ctx => {
const repr = CartoonRepresentation();
- await repr.createOrUpdate({ ...DefaultCartoonProps }, a.data).runInContext(ctx);
+ await repr.createOrUpdate({ /* TODO add `webgl: WebGLContext` */ }, { ...DefaultCartoonProps }, a.data).runInContext(ctx);
return new SO.StructureRepresentation3D({ label: 'Cartoon' }, { repr });
});
},
update({ a, b }) {
return Task.create('Structure Representation', async ctx => {
- await b.data.repr.createOrUpdate(b.data.repr.props, a.data).runInContext(ctx);
+ await b.data.repr.createOrUpdate({ /* TODO add `webgl: WebGLContext` */ }, b.data.repr.props, a.data).runInContext(ctx);
return Transformer.UpdateResult.Updated;
});
}
diff --git a/src/mol-repr/index.ts b/src/mol-repr/index.ts
index 83a39d2e0423353e61c93229d6c01395b6962e18..a293cf595c352db3bd053bf82228a0e3080f8be6 100644
--- a/src/mol-repr/index.ts
+++ b/src/mol-repr/index.ts
@@ -10,18 +10,24 @@ import { PickingId } from '../mol-geo/geometry/picking';
import { Loci, isEmptyLoci, EmptyLoci } from 'mol-model/loci';
import { MarkerAction } from '../mol-geo/geometry/marker-data';
import { Params, MultiSelectParam } from 'mol-util/parameter';
+import { WebGLContext } from 'mol-gl/webgl/context';
+// import { ColorTheme } from 'mol-theme/color';
// export interface RepresentationProps {
// visuals?: string[]
// }
export type RepresentationProps = { [k: string]: any }
+export interface RepresentationContext {
+ webgl?: WebGLContext
+}
+
export interface Representation<D, P extends RepresentationProps = {}> {
readonly label: string
readonly params: Params
readonly renderObjects: ReadonlyArray<RenderObject>
readonly props: Readonly<P>
- createOrUpdate: (props?: Partial<P>, data?: D) => Task<void>
+ createOrUpdate: (ctx: RepresentationContext, props?: Partial<P>, data?: D) => Task<void>
getLoci: (pickingId: PickingId) => Loci
mark: (loci: Loci, action: MarkerAction) => boolean
destroy: () => void
@@ -60,17 +66,17 @@ export namespace Representation {
reprList.forEach(r => Object.assign(props, r.props))
return props as P
},
- createOrUpdate: (props: Partial<P> = {}, data?: D) => {
+ createOrUpdate: (ctx: RepresentationContext, props: Partial<P> = {}, data?: D) => {
if (data) currentData = data
// const qualityProps = getQualityProps(Object.assign({}, currentProps, props), structure)
// currentProps = Object.assign({}, DefaultCartoonProps, currentProps, props, qualityProps)
currentProps = Object.assign({}, defaultProps, currentProps, props)
const { visuals } = currentProps
- return Task.create(`Creating '${label}' representation`, async ctx => {
+ return Task.create(`Creating '${label}' representation`, async runtime => {
for (let i = 0, il = reprList.length; i < il; ++i) {
if (!visuals || visuals.includes(i.toString())) {
- await reprList[i].createOrUpdate(currentProps, currentData).runInContext(ctx)
+ await reprList[i].createOrUpdate(ctx, currentProps, currentData).runInContext(runtime)
}
}
})
@@ -98,9 +104,17 @@ export namespace Representation {
}
}
+//
+
+export interface VisualContext extends RepresentationContext {
+ runtime: RuntimeContext,
+ // TODO
+ // colorTheme: ColorTheme,
+}
+
export interface Visual<D, P extends RepresentationProps> {
readonly renderObject: RenderObject | undefined
- createOrUpdate: (ctx: RuntimeContext, props?: Partial<P>, data?: D) => Promise<void>
+ createOrUpdate: (ctx: VisualContext, props?: Partial<P>, data?: D) => Promise<void>
getLoci: (pickingId: PickingId) => Loci
mark: (loci: Loci, action: MarkerAction) => boolean
destroy: () => void
diff --git a/src/mol-repr/shape/index.ts b/src/mol-repr/shape/index.ts
index a953f8ecc75edb35c2504a38412bfe3372fea80c..209f2b2aa6142cb2c2d2fda564ab3cee6ea346d8 100644
--- a/src/mol-repr/shape/index.ts
+++ b/src/mol-repr/shape/index.ts
@@ -6,7 +6,7 @@
import { Task } from 'mol-task'
import { RenderObject, createMeshRenderObject, MeshRenderObject } from 'mol-gl/render-object';
-import { RepresentationProps, Representation } from '..';
+import { RepresentationProps, Representation, RepresentationContext } from '..';
import { Loci, EmptyLoci, isEveryLoci } from 'mol-model/loci';
import { ValueCell } from 'mol-util';
import { ColorThemeName, ColorThemeOptions } from 'mol-theme/color';
@@ -38,11 +38,11 @@ export function ShapeRepresentation<P extends ShapeProps>(): ShapeRepresentation
let _shape: Shape
let currentProps: P
- function createOrUpdate(props: Partial<P> = {}, shape?: Shape) {
+ function createOrUpdate(ctx: RepresentationContext, props: Partial<P> = {}, shape?: Shape) {
currentProps = Object.assign({}, DefaultShapeProps, currentProps, props)
if (shape) _shape = shape
- return Task.create('ShapeRepresentation.create', async ctx => {
+ return Task.create('ShapeRepresentation.create', async runtime => {
renderObjects.length = 0
if (!_shape) return
@@ -51,7 +51,7 @@ export function ShapeRepresentation<P extends ShapeProps>(): ShapeRepresentation
const locationIt = ShapeGroupIterator.fromShape(_shape)
const transform = createIdentityTransform()
- const values = await Mesh.createValues(ctx, mesh, transform, locationIt, currentProps)
+ const values = await Mesh.createValues(runtime, mesh, transform, locationIt, currentProps)
const state = createRenderableState(currentProps)
_renderObject = createMeshRenderObject(values, state)
diff --git a/src/mol-repr/structure/complex-representation.ts b/src/mol-repr/structure/complex-representation.ts
index 77dc1ac957bf8bdc3f8697fe096748ae47746ed2..62d828bb2c0d8b783c8c87dd58c21dd1eaefe374 100644
--- a/src/mol-repr/structure/complex-representation.ts
+++ b/src/mol-repr/structure/complex-representation.ts
@@ -12,17 +12,18 @@ import { StructureProps, StructureRepresentation, StructureParams } from './inde
import { ComplexVisual } from './complex-visual';
import { PickingId } from 'mol-geo/geometry/picking';
import { MarkerAction } from 'mol-geo/geometry/marker-data';
+import { RepresentationContext } from 'mol-repr';
export function ComplexRepresentation<P extends StructureProps>(label: string, visualCtor: () => ComplexVisual<P>): StructureRepresentation<P> {
let visual: ComplexVisual<P> | undefined
let _props: P
- function createOrUpdate(props: Partial<P> = {}, structure?: Structure) {
+ function createOrUpdate(ctx: RepresentationContext, props: Partial<P> = {}, structure?: Structure) {
_props = Object.assign({}, _props, props)
- return Task.create('Creating or updating ComplexRepresentation', async ctx => {
+ return Task.create('Creating or updating ComplexRepresentation', async runtime => {
if (!visual) visual = visualCtor()
- await visual.createOrUpdate(ctx, _props, structure)
+ await visual.createOrUpdate({ ...ctx, runtime }, _props, structure)
});
}
diff --git a/src/mol-repr/structure/complex-visual.ts b/src/mol-repr/structure/complex-visual.ts
index 4e7acbf7577d1647079ff316b606b4d2392cacc6..78856279772da9b6c2be60afd55140b69b9be298 100644
--- a/src/mol-repr/structure/complex-visual.ts
+++ b/src/mol-repr/structure/complex-visual.ts
@@ -5,9 +5,8 @@
*/
import { Structure } from 'mol-model/structure';
-import { Visual } from '..';
+import { Visual, VisualContext } from '..';
import { MeshRenderObject, LinesRenderObject, PointsRenderObject, DirectVolumeRenderObject } from 'mol-gl/render-object';
-import { RuntimeContext } from 'mol-task';
import { createComplexMeshRenderObject, UnitKind, UnitKindOptions } from './visual/util/common';
import { StructureProps, StructureMeshParams, StructureParams } from './index';
import { deepEqual, ValueCell } from 'mol-util';
@@ -37,7 +36,7 @@ type ComplexRenderObject = MeshRenderObject | LinesRenderObject | PointsRenderOb
interface ComplexVisualBuilder<P extends ComplexProps, G extends Geometry> {
defaultProps: P
- createGeometry(ctx: RuntimeContext, structure: Structure, props: P, geometry?: G): Promise<G>
+ createGeometry(ctx: VisualContext, structure: Structure, props: P, geometry?: G): Promise<G>
createLocationIterator(structure: Structure): LocationIterator
getLoci(pickingId: PickingId, structure: Structure, id: number): Loci
mark(loci: Loci, structure: Structure, apply: (interval: Interval) => boolean): boolean,
@@ -46,7 +45,7 @@ interface ComplexVisualBuilder<P extends ComplexProps, G extends Geometry> {
interface ComplexVisualGeometryBuilder<P extends ComplexProps, G extends Geometry> extends ComplexVisualBuilder<P, G> {
createEmptyGeometry(geometry?: G): G
- createRenderObject(ctx: RuntimeContext, structure: Structure, geometry: Geometry, locationIt: LocationIterator, currentProps: P): Promise<ComplexRenderObject>
+ createRenderObject(ctx: VisualContext, structure: Structure, geometry: Geometry, locationIt: LocationIterator, currentProps: P): Promise<ComplexRenderObject>
updateValues(values: RenderableValues, newProps: P): void
}
@@ -62,7 +61,7 @@ export function ComplexVisual<P extends ComplexMeshProps>(builder: ComplexVisual
let locationIt: LocationIterator
let conformationHash: number
- async function create(ctx: RuntimeContext, structure: Structure, props: Partial<P> = {}) {
+ async function create(ctx: VisualContext, structure: Structure, props: Partial<P> = {}) {
currentProps = Object.assign({}, defaultProps, props, { structure })
currentStructure = structure
@@ -73,7 +72,7 @@ export function ComplexVisual<P extends ComplexMeshProps>(builder: ComplexVisual
renderObject = await createRenderObject(ctx, structure, geometry, locationIt, currentProps)
}
- async function update(ctx: RuntimeContext, props: Partial<P>) {
+ async function update(ctx: VisualContext, props: Partial<P>) {
const newProps = Object.assign({}, currentProps, props, { structure: currentStructure })
if (!renderObject) return false
@@ -102,12 +101,12 @@ export function ComplexVisual<P extends ComplexMeshProps>(builder: ComplexVisual
if (updateState.updateSize) {
// not all geometries have size data, so check here
if ('uSize' in renderObject.values) {
- await createSizes(ctx, locationIt, newProps, renderObject.values)
+ await createSizes(ctx.runtime, locationIt, newProps, renderObject.values)
}
}
if (updateState.updateColor) {
- await createColors(ctx, locationIt, newProps, renderObject.values)
+ await createColors(ctx.runtime, locationIt, newProps, renderObject.values)
}
updateValues(renderObject.values, newProps)
@@ -119,7 +118,7 @@ export function ComplexVisual<P extends ComplexMeshProps>(builder: ComplexVisual
return {
get renderObject () { return renderObject },
- async createOrUpdate(ctx: RuntimeContext, props: Partial<P> = {}, structure?: Structure) {
+ async createOrUpdate(ctx: VisualContext, props: Partial<P> = {}, structure?: Structure) {
if (!structure && !currentStructure) {
throw new Error('missing structure')
} else if (structure && (!currentStructure || !renderObject)) {
diff --git a/src/mol-repr/structure/units-representation.ts b/src/mol-repr/structure/units-representation.ts
index d0694f68ab48a9c4a9ead72c3ae11904c602032d..50e350f5cbef9a0c40fec28635278495f8fbc30e 100644
--- a/src/mol-repr/structure/units-representation.ts
+++ b/src/mol-repr/structure/units-representation.ts
@@ -8,7 +8,7 @@
import { Structure, Unit } from 'mol-model/structure';
import { Task } from 'mol-task'
import { RenderObject } from 'mol-gl/render-object';
-import { RepresentationProps, Visual } from '..';
+import { RepresentationProps, Visual, RepresentationContext } from '..';
import { Loci, EmptyLoci, isEmptyLoci } from 'mol-model/loci';
import { StructureGroup } from './units-visual';
import { StructureProps, StructureParams, StructureRepresentation } from './index';
@@ -24,10 +24,10 @@ export function UnitsRepresentation<P extends StructureProps>(label: string, vis
let _structure: Structure
let _groups: ReadonlyArray<Unit.SymmetryGroup>
- function createOrUpdate(props: Partial<P> = {}, structure?: Structure) {
+ function createOrUpdate(ctx: RepresentationContext, props: Partial<P> = {}, structure?: Structure) {
_props = Object.assign({}, _props, props)
- return Task.create('Creating or updating UnitsRepresentation', async ctx => {
+ return Task.create('Creating or updating UnitsRepresentation', async runtime => {
if (!_structure && !structure) {
throw new Error('missing structure')
} else if (structure && !_structure) {
@@ -37,7 +37,7 @@ export function UnitsRepresentation<P extends StructureProps>(label: string, vis
for (let i = 0; i < _groups.length; i++) {
const group = _groups[i];
const visual = visualCtor()
- await visual.createOrUpdate(ctx, _props, { group, structure })
+ await visual.createOrUpdate({ ...ctx, runtime }, _props, { group, structure })
visuals.set(group.hashCode, { visual, group })
}
} else if (structure && _structure.hashCode !== structure.hashCode) {
@@ -53,13 +53,13 @@ export function UnitsRepresentation<P extends StructureProps>(label: string, vis
const visualGroup = oldVisuals.get(group.hashCode)
if (visualGroup) {
const { visual } = visualGroup
- await visual.createOrUpdate(ctx, _props, { group, structure })
+ await visual.createOrUpdate({ ...ctx, runtime }, _props, { group, structure })
visuals.set(group.hashCode, { visual, group })
oldVisuals.delete(group.hashCode)
} else {
// newGroups.push(group)
const visual = visualCtor()
- await visual.createOrUpdate(ctx, _props, { group, structure })
+ await visual.createOrUpdate({ ...ctx, runtime }, _props, { group, structure })
visuals.set(group.hashCode, { visual, group })
}
}
@@ -71,7 +71,7 @@ export function UnitsRepresentation<P extends StructureProps>(label: string, vis
// oldVisuals.forEach(({ visual }) => unusedVisuals.push(visual))
// newGroups.forEach(async group => {
// const visual = unusedVisuals.pop() || visualCtor()
- // await visual.createOrUpdate(ctx, _props, group)
+ // await visual.createOrUpdate({ ...ctx, runtime }, _props, group)
// visuals.set(group.hashCode, { visual, group })
// })
// unusedVisuals.forEach(visual => visual.destroy())
@@ -85,7 +85,7 @@ export function UnitsRepresentation<P extends StructureProps>(label: string, vis
const group = _groups[i];
const visualGroup = visuals.get(group.hashCode)
if (visualGroup) {
- await visualGroup.visual.createOrUpdate(ctx, _props, { group, structure })
+ await visualGroup.visual.createOrUpdate({ ...ctx, runtime }, _props, { group, structure })
visualGroup.group = group
} else {
throw new Error(`expected to find visual for hashCode ${group.hashCode}`)
@@ -98,7 +98,7 @@ export function UnitsRepresentation<P extends StructureProps>(label: string, vis
visuals.forEach(({ visual, group }) => visualsList.push([ visual, group ]))
for (let i = 0, il = visualsList.length; i < il; ++i) {
const [ visual, group ] = visualsList[i]
- await visual.createOrUpdate(ctx, _props, { group, structure: _structure })
+ await visual.createOrUpdate({ ...ctx, runtime }, _props, { group, structure: _structure })
}
}
if (structure) _structure = structure
diff --git a/src/mol-repr/structure/units-visual.ts b/src/mol-repr/structure/units-visual.ts
index 641d232f6fe2e09783a2e4be3a88891109b01c3d..7f8ef19694e4f25bfb5362831550a9b2e8836a55 100644
--- a/src/mol-repr/structure/units-visual.ts
+++ b/src/mol-repr/structure/units-visual.ts
@@ -5,9 +5,8 @@
*/
import { Unit, Structure } from 'mol-model/structure';
-import { RepresentationProps, Visual } from '../';
+import { RepresentationProps, Visual, VisualContext } from '../';
import { StructureMeshParams, StructurePointsParams, StructureLinesParams, StructureDirectVolumeParams, StructureParams } from './index';
-import { RuntimeContext } from 'mol-task';
import { Loci, isEveryLoci, EmptyLoci } from 'mol-model/loci';
import { MeshRenderObject, PointsRenderObject, LinesRenderObject, DirectVolumeRenderObject } from 'mol-gl/render-object';
import { createUnitsMeshRenderObject, createUnitsPointsRenderObject, createUnitsTransform, createUnitsLinesRenderObject, createUnitsDirectVolumeRenderObject, UnitKind, UnitKindOptions, includesUnitKind } from './visual/util/common';
@@ -49,7 +48,7 @@ type UnitsRenderObject = MeshRenderObject | LinesRenderObject | PointsRenderObje
interface UnitsVisualBuilder<P extends UnitsProps, G extends Geometry> {
defaultProps: P
- createGeometry(ctx: RuntimeContext, unit: Unit, structure: Structure, props: P, geometry?: G): Promise<G>
+ createGeometry(ctx: VisualContext, unit: Unit, structure: Structure, props: P, geometry?: G): Promise<G>
createLocationIterator(group: Unit.SymmetryGroup): LocationIterator
getLoci(pickingId: PickingId, group: Unit.SymmetryGroup, id: number): Loci
mark(loci: Loci, group: Unit.SymmetryGroup, apply: (interval: Interval) => boolean): boolean
@@ -58,7 +57,7 @@ interface UnitsVisualBuilder<P extends UnitsProps, G extends Geometry> {
interface UnitsVisualGeometryBuilder<P extends UnitsProps, G extends Geometry> extends UnitsVisualBuilder<P, G> {
createEmptyGeometry(geometry?: G): G
- createRenderObject(ctx: RuntimeContext, group: Unit.SymmetryGroup, geometry: Geometry, locationIt: LocationIterator, currentProps: P): Promise<UnitsRenderObject>
+ createRenderObject(ctx: VisualContext, group: Unit.SymmetryGroup, geometry: Geometry, locationIt: LocationIterator, currentProps: P): Promise<UnitsRenderObject>
updateValues(values: RenderableValues, newProps: P): void
}
@@ -75,7 +74,7 @@ export function UnitsVisual<P extends UnitsProps>(builder: UnitsVisualGeometryBu
let locationIt: LocationIterator
let currentConformationId: UUID
- async function create(ctx: RuntimeContext, group: Unit.SymmetryGroup, props: Partial<P> = {}) {
+ async function create(ctx: VisualContext, group: Unit.SymmetryGroup, props: Partial<P> = {}) {
currentProps = Object.assign({}, defaultProps, props, { structure: currentStructure })
currentGroup = group
@@ -90,7 +89,7 @@ export function UnitsVisual<P extends UnitsProps>(builder: UnitsVisualGeometryBu
renderObject = await createRenderObject(ctx, group, geometry, locationIt, currentProps)
}
- async function update(ctx: RuntimeContext, props: Partial<P> = {}) {
+ async function update(ctx: VisualContext, props: Partial<P> = {}) {
if (!renderObject) return
const newProps = Object.assign({}, currentProps, props, { structure: currentStructure })
@@ -132,12 +131,12 @@ export function UnitsVisual<P extends UnitsProps>(builder: UnitsVisualGeometryBu
if (updateState.updateSize) {
// not all geometries have size data, so check here
if ('uSize' in renderObject.values) {
- await createSizes(ctx, locationIt, newProps, renderObject.values)
+ await createSizes(ctx.runtime, locationIt, newProps, renderObject.values)
}
}
if (updateState.updateColor) {
- await createColors(ctx, locationIt, newProps, renderObject.values)
+ await createColors(ctx.runtime, locationIt, newProps, renderObject.values)
}
updateValues(renderObject.values, newProps)
@@ -148,7 +147,7 @@ export function UnitsVisual<P extends UnitsProps>(builder: UnitsVisualGeometryBu
return {
get renderObject () { return renderObject },
- async createOrUpdate(ctx: RuntimeContext, props: Partial<P> = {}, structureGroup?: StructureGroup) {
+ async createOrUpdate(ctx: VisualContext, props: Partial<P> = {}, structureGroup?: StructureGroup) {
if (structureGroup) currentStructure = structureGroup.structure
const group = structureGroup ? structureGroup.group : undefined
if (!group && !currentGroup) {
diff --git a/src/mol-repr/structure/visual/carbohydrate-link-cylinder.ts b/src/mol-repr/structure/visual/carbohydrate-link-cylinder.ts
index 8babf03f724fb46b27db2e0a4359956aab8e4a94..0b064012b8c56b7c9db6611e3f1524edf065a7b4 100644
--- a/src/mol-repr/structure/visual/carbohydrate-link-cylinder.ts
+++ b/src/mol-repr/structure/visual/carbohydrate-link-cylinder.ts
@@ -5,7 +5,6 @@
*/
import { Structure, Link, StructureElement } from 'mol-model/structure';
-import { RuntimeContext } from 'mol-task'
import { Loci, EmptyLoci } from 'mol-model/loci';
import { Vec3 } from 'mol-math/linear-algebra';
import { createLinkCylinderMesh, LinkCylinderProps, LinkCylinderParams } from './util/link';
@@ -20,6 +19,7 @@ import { Mesh } from 'mol-geo/geometry/mesh/mesh';
import { LocationIterator } from 'mol-geo/util/location-iterator';
import { PickingId } from 'mol-geo/geometry/picking';
import { VisualUpdateState } from '../../util';
+import { VisualContext } from 'mol-repr';
// TODO create seperate visual
// for (let i = 0, il = carbohydrates.terminalLinks.length; i < il; ++i) {
@@ -35,7 +35,7 @@ import { VisualUpdateState } from '../../util';
const radiusFactor = 0.3
-async function createCarbohydrateLinkCylinderMesh(ctx: RuntimeContext, structure: Structure, props: LinkCylinderProps, mesh?: Mesh) {
+async function createCarbohydrateLinkCylinderMesh(ctx: VisualContext, structure: Structure, props: LinkCylinderProps, mesh?: Mesh) {
const { links, elements } = structure.carbohydrates
const sizeTheme = SizeTheme({ name: props.sizeTheme, value: props.sizeValue })
const location = StructureElement.create()
diff --git a/src/mol-repr/structure/visual/carbohydrate-symbol-mesh.ts b/src/mol-repr/structure/visual/carbohydrate-symbol-mesh.ts
index 806fbd4dd35ce671beb618f44421725660902243..ddbd3215d3c7c9c4f9a9d30a9510b43d9bd572fa 100644
--- a/src/mol-repr/structure/visual/carbohydrate-symbol-mesh.ts
+++ b/src/mol-repr/structure/visual/carbohydrate-symbol-mesh.ts
@@ -10,7 +10,6 @@ import { OctagonalPyramid, PerforatedOctagonalPyramid } from 'mol-geo/primitive/
import { Star } from 'mol-geo/primitive/star';
import { Octahedron, PerforatedOctahedron } from 'mol-geo/primitive/octahedron';
import { DiamondPrism, PentagonalPrism, HexagonalPrism } from 'mol-geo/primitive/prism';
-import { RuntimeContext } from 'mol-task';
import { Structure, StructureElement } from 'mol-model/structure';
import { Mesh } from 'mol-geo/geometry/mesh/mesh';
import { MeshBuilder } from 'mol-geo/geometry/mesh/mesh-builder';
@@ -25,6 +24,7 @@ import { LocationIterator } from 'mol-geo/util/location-iterator';
import { PickingId } from 'mol-geo/geometry/picking';
import { OrderedSet, Interval } from 'mol-data/int';
import { EmptyLoci, Loci } from 'mol-model/loci';
+import { VisualContext } from 'mol-repr';
const t = Mat4.identity()
const sVec = Vec3.zero()
@@ -44,7 +44,7 @@ const diamondPrism = DiamondPrism()
const pentagonalPrism = PentagonalPrism()
const hexagonalPrism = HexagonalPrism()
-async function createCarbohydrateSymbolMesh(ctx: RuntimeContext, structure: Structure, props: CarbohydrateSymbolProps, mesh?: Mesh) {
+async function createCarbohydrateSymbolMesh(ctx: VisualContext, structure: Structure, props: CarbohydrateSymbolProps, mesh?: Mesh) {
const builder = MeshBuilder.create(256, 128, mesh)
const sizeTheme = SizeTheme({ name: props.sizeTheme, value: props.sizeValue })
@@ -138,8 +138,8 @@ async function createCarbohydrateSymbolMesh(ctx: RuntimeContext, structure: Stru
break
}
- if (i % 10000 === 0 && ctx.shouldUpdate) {
- await ctx.update({ message: 'Carbohydrate symbols', current: i, max: n });
+ if (i % 10000 === 0 && ctx.runtime.shouldUpdate) {
+ await ctx.runtime.update({ message: 'Carbohydrate symbols', current: i, max: n });
}
}
diff --git a/src/mol-repr/structure/visual/cross-link-restraint-cylinder.ts b/src/mol-repr/structure/visual/cross-link-restraint-cylinder.ts
index e71655c2a555c7d0f80dfbbf993fc9f066d102d8..190565acb8ecba70588c608fbaf1822fcf4d50c1 100644
--- a/src/mol-repr/structure/visual/cross-link-restraint-cylinder.ts
+++ b/src/mol-repr/structure/visual/cross-link-restraint-cylinder.ts
@@ -7,7 +7,6 @@
import { Link, Structure, StructureElement } from 'mol-model/structure';
import { ComplexVisual } from '../index';
import { VisualUpdateState } from '../../util';
-import { RuntimeContext } from 'mol-task'
import { LinkCylinderProps, createLinkCylinderMesh, LinkCylinderParams } from './util/link';
import { Vec3 } from 'mol-math/linear-algebra';
import { Loci, EmptyLoci } from 'mol-model/loci';
@@ -20,8 +19,9 @@ import { SelectParam, NumberParam, paramDefaultValues } from 'mol-util/parameter
import { Mesh } from 'mol-geo/geometry/mesh/mesh';
import { LocationIterator } from 'mol-geo/util/location-iterator';
import { PickingId } from 'mol-geo/geometry/picking';
+import { VisualContext } from 'mol-repr';
-async function createCrossLinkRestraintCylinderMesh(ctx: RuntimeContext, structure: Structure, props: LinkCylinderProps, mesh?: Mesh) {
+async function createCrossLinkRestraintCylinderMesh(ctx: VisualContext, structure: Structure, props: LinkCylinderProps, mesh?: Mesh) {
const crossLinks = structure.crossLinkRestraints
if (!crossLinks.count) return Mesh.createEmpty(mesh)
diff --git a/src/mol-repr/structure/visual/element-point.ts b/src/mol-repr/structure/visual/element-point.ts
index d770bb0af5b2d42da434b1e9ed398f3703c5f870..c0b7ebb436024bd2cc0508021ebe0401d934e7a6 100644
--- a/src/mol-repr/structure/visual/element-point.ts
+++ b/src/mol-repr/structure/visual/element-point.ts
@@ -5,7 +5,6 @@
*/
import { Unit, Structure } from 'mol-model/structure';
-import { RuntimeContext } from 'mol-task'
import { UnitsVisual } from '../index';
import { VisualUpdateState } from '../../util';
import { getElementLoci, StructureElementIterator, markElement } from './util/element';
@@ -15,6 +14,7 @@ import { UnitsPointsVisual, UnitsPointsParams } from '../units-visual';
import { SelectParam, NumberParam, BooleanParam, paramDefaultValues } from 'mol-util/parameter';
import { Points } from 'mol-geo/geometry/points/points';
import { PointsBuilder } from 'mol-geo/geometry/points/points-builder';
+import { VisualContext } from 'mol-repr';
export const ElementPointParams = {
...UnitsPointsParams,
@@ -27,7 +27,7 @@ export type ElementPointProps = typeof DefaultElementPointProps
// TODO size
-export async function createElementPoint(ctx: RuntimeContext, unit: Unit, structure: Structure, props: ElementPointProps, points: Points) {
+export async function createElementPoint(ctx: VisualContext, unit: Unit, structure: Structure, props: ElementPointProps, points: Points) {
const elements = unit.elements
const n = elements.length
const builder = PointsBuilder.create(n, n / 10, points)
@@ -39,8 +39,8 @@ export async function createElementPoint(ctx: RuntimeContext, unit: Unit, struct
pos(elements[i], p)
builder.add(p[0], p[1], p[2], i)
- if (i % 10000 === 0 && ctx.shouldUpdate) {
- await ctx.update({ message: 'Creating points', current: i, max: n });
+ if (i % 10000 === 0 && ctx.runtime.shouldUpdate) {
+ await ctx.runtime.update({ message: 'Creating points', current: i, max: n });
}
}
return builder.getPoints()
diff --git a/src/mol-repr/structure/visual/gaussian-density-point.ts b/src/mol-repr/structure/visual/gaussian-density-point.ts
index c4bfbc40208c7206a085bb865febfd626b981075..f14268e78eebe8ea5b51439a9b4746479d790310 100644
--- a/src/mol-repr/structure/visual/gaussian-density-point.ts
+++ b/src/mol-repr/structure/visual/gaussian-density-point.ts
@@ -5,7 +5,6 @@
*/
import { Unit, Structure } from 'mol-model/structure';
-import { RuntimeContext } from 'mol-task'
import { UnitsVisual } from '../index';
import { VisualUpdateState } from '../../util';
import { StructureElementIterator } from './util/element';
@@ -17,6 +16,7 @@ import { GaussianDensityProps, GaussianDensityParams } from 'mol-model/structure
import { paramDefaultValues, SelectParam, NumberParam, BooleanParam } from 'mol-util/parameter';
import { Points } from 'mol-geo/geometry/points/points';
import { PointsBuilder } from 'mol-geo/geometry/points/points-builder';
+import { VisualContext } from 'mol-repr';
export const GaussianDensityPointParams = {
...UnitsPointsParams,
@@ -28,8 +28,8 @@ export const GaussianDensityPointParams = {
export const DefaultGaussianDensityPointProps = paramDefaultValues(GaussianDensityPointParams)
export type GaussianDensityPointProps = typeof DefaultGaussianDensityPointProps
-export async function createGaussianDensityPoint(ctx: RuntimeContext, unit: Unit, structure: Structure, props: GaussianDensityProps, points?: Points) {
- const { transform, field: { space, data } } = await unit.computeGaussianDensity(props, ctx)
+export async function createGaussianDensityPoint(ctx: VisualContext, unit: Unit, structure: Structure, props: GaussianDensityProps, points?: Points) {
+ const { transform, field: { space, data } } = await unit.computeGaussianDensity(props, ctx.runtime, ctx.webgl)
const { dimensions, get } = space
const [ xn, yn, zn ] = dimensions
@@ -48,8 +48,8 @@ export async function createGaussianDensityPoint(ctx: RuntimeContext, unit: Unit
Vec3.transformMat4(p, p, transform)
builder.add(p[0], p[1], p[2], i)
}
- if (i % 100000 === 0 && ctx.shouldUpdate) {
- await ctx.update({ message: 'Creating density points', current: i, max: n });
+ if (i % 100000 === 0 && ctx.runtime.shouldUpdate) {
+ await ctx.runtime.update({ message: 'Creating density points', current: i, max: n });
}
++i
}
diff --git a/src/mol-repr/structure/visual/gaussian-density-volume.ts b/src/mol-repr/structure/visual/gaussian-density-volume.ts
index 4179da8c11a01950daaf31575f434e9421c17a9e..e0b96b1f9c25c7cf092fa22d9e6284fddb5989c0 100644
--- a/src/mol-repr/structure/visual/gaussian-density-volume.ts
+++ b/src/mol-repr/structure/visual/gaussian-density-volume.ts
@@ -7,20 +7,20 @@
import { Unit, Structure } from 'mol-model/structure';
import { UnitsVisual } from '../index';
import { VisualUpdateState } from '../../util';
-import { RuntimeContext } from 'mol-task'
import { UnitsDirectVolumeVisual, UnitsDirectVolumeParams } from '../units-visual';
import { StructureElementIterator, getElementLoci, markElement } from './util/element';
import { GaussianDensityProps, GaussianDensityParams, computeUnitGaussianDensityTexture } from 'mol-model/structure/structure/unit/gaussian-density';
import { paramDefaultValues } from 'mol-util/parameter';
import { DirectVolume } from 'mol-geo/geometry/direct-volume/direct-volume';
+import { VisualContext } from 'mol-repr';
-async function createGaussianDensityVolume(ctx: RuntimeContext, unit: Unit, structure: Structure, props: GaussianDensityProps, directVolume?: DirectVolume): Promise<DirectVolume> {
- const { webgl } = props
- if (webgl === undefined) throw new Error('createGaussianDensityVolume requires `webgl` in props')
+async function createGaussianDensityVolume(ctx: VisualContext, unit: Unit, structure: Structure, props: GaussianDensityProps, directVolume?: DirectVolume): Promise<DirectVolume> {
+ const { runtime, webgl } = ctx
+ if (webgl === undefined) throw new Error('createGaussianDensityVolume requires `webgl` object in VisualContext')
const p = { ...props, useGpu: true }
const oldTexture = directVolume ? directVolume.gridTexture.ref.value : undefined
- const densityTextureData = await computeUnitGaussianDensityTexture(unit, p, oldTexture).runInContext(ctx)
+ const densityTextureData = await computeUnitGaussianDensityTexture(unit, p, webgl, oldTexture).runInContext(runtime)
const { transform, texture, bbox, gridDimension } = densityTextureData
return DirectVolume.create(bbox, gridDimension, transform, texture, directVolume)
diff --git a/src/mol-repr/structure/visual/gaussian-surface-mesh.ts b/src/mol-repr/structure/visual/gaussian-surface-mesh.ts
index 7982008eb57523049b55eb80474a830e4d558f1e..3e983cff2dc9e2d5657d932e98839e04a2b789af 100644
--- a/src/mol-repr/structure/visual/gaussian-surface-mesh.ts
+++ b/src/mol-repr/structure/visual/gaussian-surface-mesh.ts
@@ -7,24 +7,24 @@
import { Unit, Structure } from 'mol-model/structure';
import { UnitsVisual } from '../index';
import { VisualUpdateState } from '../../util';
-import { RuntimeContext } from 'mol-task'
import { UnitsMeshVisual, UnitsMeshParams } from '../units-visual';
import { StructureElementIterator, getElementLoci, markElement } from './util/element';
import { GaussianDensityProps, GaussianDensityParams } from 'mol-model/structure/structure/unit/gaussian-density';
import { paramDefaultValues } from 'mol-util/parameter';
import { Mesh } from 'mol-geo/geometry/mesh/mesh';
import { computeMarchingCubesMesh } from 'mol-geo/util/marching-cubes/algorithm';
+import { VisualContext } from 'mol-repr';
-async function createGaussianSurfaceMesh(ctx: RuntimeContext, unit: Unit, structure: Structure, props: GaussianDensityProps, mesh?: Mesh): Promise<Mesh> {
+async function createGaussianSurfaceMesh(ctx: VisualContext, unit: Unit, structure: Structure, props: GaussianDensityProps, mesh?: Mesh): Promise<Mesh> {
const { smoothness } = props
- const { transform, field, idField } = await unit.computeGaussianDensity(props, ctx)
+ const { transform, field, idField } = await unit.computeGaussianDensity(props, ctx.runtime, ctx.webgl)
const params = {
isoLevel: Math.exp(-smoothness),
scalarField: field,
idField
}
- const surface = await computeMarchingCubesMesh(params, mesh).runAsChild(ctx)
+ const surface = await computeMarchingCubesMesh(params, mesh).runAsChild(ctx.runtime)
Mesh.transformImmediate(surface, transform)
Mesh.computeNormalsImmediate(surface)
diff --git a/src/mol-repr/structure/visual/gaussian-surface-wireframe.ts b/src/mol-repr/structure/visual/gaussian-surface-wireframe.ts
index beb21243742d43009bf4c8ae9600ae6978b11ff4..1b3e3033144751186ca6637b197f7048ff6d9822 100644
--- a/src/mol-repr/structure/visual/gaussian-surface-wireframe.ts
+++ b/src/mol-repr/structure/visual/gaussian-surface-wireframe.ts
@@ -7,7 +7,6 @@
import { Unit, Structure } from 'mol-model/structure';
import { UnitsVisual } from '../index';
import { VisualUpdateState } from '../../util';
-import { RuntimeContext } from 'mol-task'
import { UnitsLinesVisual, UnitsLinesParams } from '../units-visual';
import { StructureElementIterator, getElementLoci, markElement } from './util/element';
import { GaussianDensityProps, GaussianDensityParams } from 'mol-model/structure/structure/unit/gaussian-density';
@@ -15,17 +14,18 @@ import { paramDefaultValues, SelectParam, NumberParam, BooleanParam } from 'mol-
import { SizeThemeName, SizeThemeOptions } from 'mol-theme/size';
import { Lines } from 'mol-geo/geometry/lines/lines';
import { computeMarchingCubesLines } from 'mol-geo/util/marching-cubes/algorithm';
+import { VisualContext } from 'mol-repr';
-async function createGaussianWireframe(ctx: RuntimeContext, unit: Unit, structure: Structure, props: GaussianDensityProps, lines?: Lines): Promise<Lines> {
+async function createGaussianWireframe(ctx: VisualContext, unit: Unit, structure: Structure, props: GaussianDensityProps, lines?: Lines): Promise<Lines> {
const { smoothness } = props
- const { transform, field, idField } = await unit.computeGaussianDensity(props, ctx)
+ const { transform, field, idField } = await unit.computeGaussianDensity(props, ctx.runtime)
const params = {
isoLevel: Math.exp(-smoothness),
scalarField: field,
idField
}
- const wireframe = await computeMarchingCubesLines(params, lines).runAsChild(ctx)
+ const wireframe = await computeMarchingCubesLines(params, lines).runAsChild(ctx.runtime)
Lines.transformImmediate(wireframe, transform)
diff --git a/src/mol-repr/structure/visual/inter-unit-link-cylinder.ts b/src/mol-repr/structure/visual/inter-unit-link-cylinder.ts
index 4f2c957086e467c4abf67579331bbb4c2c396131..76a51d6805d4d925a91c2f2d2fa3e20356d02f83 100644
--- a/src/mol-repr/structure/visual/inter-unit-link-cylinder.ts
+++ b/src/mol-repr/structure/visual/inter-unit-link-cylinder.ts
@@ -7,7 +7,6 @@
import { Link, Structure, StructureElement } from 'mol-model/structure';
import { ComplexVisual } from '../index';
import { VisualUpdateState } from '../../util';
-import { RuntimeContext } from 'mol-task'
import { LinkCylinderProps, createLinkCylinderMesh, LinkIterator, LinkCylinderParams } from './util/link';
import { Vec3 } from 'mol-math/linear-algebra';
import { Loci, EmptyLoci } from 'mol-model/loci';
@@ -18,8 +17,9 @@ import { BitFlags } from 'mol-util';
import { SelectParam, NumberParam, paramDefaultValues } from 'mol-util/parameter';
import { Mesh } from 'mol-geo/geometry/mesh/mesh';
import { PickingId } from 'mol-geo/geometry/picking';
+import { VisualContext } from 'mol-repr';
-async function createInterUnitLinkCylinderMesh(ctx: RuntimeContext, structure: Structure, props: LinkCylinderProps, mesh?: Mesh) {
+async function createInterUnitLinkCylinderMesh(ctx: VisualContext, structure: Structure, props: LinkCylinderProps, mesh?: Mesh) {
const links = structure.links
const { bondCount, bonds } = links
diff --git a/src/mol-repr/structure/visual/intra-unit-link-cylinder.ts b/src/mol-repr/structure/visual/intra-unit-link-cylinder.ts
index 97179ec276ec08c01494f8569a38bdb1882095ed..b4239034cf5e80e3c974b7cf5db1655b9fbd6bd3 100644
--- a/src/mol-repr/structure/visual/intra-unit-link-cylinder.ts
+++ b/src/mol-repr/structure/visual/intra-unit-link-cylinder.ts
@@ -8,7 +8,6 @@
import { Unit, Link, StructureElement, Structure } from 'mol-model/structure';
import { UnitsVisual } from '../index';
import { VisualUpdateState } from '../../util';
-import { RuntimeContext } from 'mol-task'
import { LinkCylinderProps, createLinkCylinderMesh, LinkIterator, LinkCylinderParams } from './util/link';
import { Vec3 } from 'mol-math/linear-algebra';
import { Loci, EmptyLoci } from 'mol-model/loci';
@@ -19,8 +18,9 @@ import { BitFlags } from 'mol-util';
import { SelectParam, NumberParam, paramDefaultValues } from 'mol-util/parameter';
import { Mesh } from 'mol-geo/geometry/mesh/mesh';
import { PickingId } from 'mol-geo/geometry/picking';
+import { VisualContext } from 'mol-repr';
-async function createIntraUnitLinkCylinderMesh(ctx: RuntimeContext, unit: Unit, structure: Structure, props: LinkCylinderProps, mesh?: Mesh) {
+async function createIntraUnitLinkCylinderMesh(ctx: VisualContext, unit: Unit, structure: Structure, props: LinkCylinderProps, mesh?: Mesh) {
if (!Unit.isAtomic(unit)) return Mesh.createEmpty(mesh)
const sizeTheme = SizeTheme({ name: props.sizeTheme, value: props.sizeValue, factor: props.sizeFactor })
diff --git a/src/mol-repr/structure/visual/nucleotide-block-mesh.ts b/src/mol-repr/structure/visual/nucleotide-block-mesh.ts
index f7c0aa0a32a29330c4b2ebf8e2a82d19f2b40296..9a2e8372608dbd3bcfbba7806545b127096e5e3b 100644
--- a/src/mol-repr/structure/visual/nucleotide-block-mesh.ts
+++ b/src/mol-repr/structure/visual/nucleotide-block-mesh.ts
@@ -6,7 +6,6 @@
import { Unit, Structure } from 'mol-model/structure';
import { UnitsVisual } from '../index';
-import { RuntimeContext } from 'mol-task'
import { Vec3, Mat4 } from 'mol-math/linear-algebra';
import { Segmentation } from 'mol-data/int';
import { MoleculeType, isNucleic, isPurinBase, isPyrimidineBase } from 'mol-model/structure/model/types';
@@ -18,6 +17,7 @@ import { Box } from 'mol-geo/primitive/box';
import { Mesh } from 'mol-geo/geometry/mesh/mesh';
import { MeshBuilder } from 'mol-geo/geometry/mesh/mesh-builder';
import { addCylinder } from 'mol-geo/geometry/mesh/builder/cylinder';
+import { VisualContext } from 'mol-repr';
const p1 = Vec3.zero()
const p2 = Vec3.zero()
@@ -34,7 +34,7 @@ const sVec = Vec3.zero()
const box = Box()
// TODO define props, should be scalable
-async function createNucleotideBlockMesh(ctx: RuntimeContext, unit: Unit, structure: Structure, props: {}, mesh?: Mesh) {
+async function createNucleotideBlockMesh(ctx: VisualContext, unit: Unit, structure: Structure, props: {}, mesh?: Mesh) {
if (!Unit.isAtomic(unit)) return Mesh.createEmpty(mesh)
// TODO better vertex count estimate
@@ -100,8 +100,8 @@ async function createNucleotideBlockMesh(ctx: RuntimeContext, unit: Unit, struct
}
}
- if (i % 10000 === 0 && ctx.shouldUpdate) {
- await ctx.update({ message: 'Nucleotide block mesh', current: i });
+ if (i % 10000 === 0 && ctx.runtime.shouldUpdate) {
+ await ctx.runtime.update({ message: 'Nucleotide block mesh', current: i });
}
++i
}
diff --git a/src/mol-repr/structure/visual/polymer-backbone-cylinder.ts b/src/mol-repr/structure/visual/polymer-backbone-cylinder.ts
index b43c0dfc2231fdd5ae7c89c63c9dab192ec6e79f..6968ac9b53c676171198f5e113cec87672f3f51c 100644
--- a/src/mol-repr/structure/visual/polymer-backbone-cylinder.ts
+++ b/src/mol-repr/structure/visual/polymer-backbone-cylinder.ts
@@ -7,7 +7,6 @@
import { Unit, Structure } from 'mol-model/structure';
import { UnitsVisual } from '../index';
import { VisualUpdateState } from '../../util';
-import { RuntimeContext } from 'mol-task'
import { PolymerBackboneIterator } from './util/polymer';
import { getElementLoci, markElement, StructureElementIterator } from './util/element';
import { Vec3 } from 'mol-math/linear-algebra';
@@ -19,6 +18,7 @@ import { Mesh } from 'mol-geo/geometry/mesh/mesh';
import { MeshBuilder } from 'mol-geo/geometry/mesh/mesh-builder';
import { CylinderProps } from 'mol-geo/primitive/cylinder';
import { addCylinder } from 'mol-geo/geometry/mesh/builder/cylinder';
+import { VisualContext } from 'mol-repr';
export const PolymerBackboneCylinderParams = {
sizeTheme: SelectParam<SizeThemeName>('Size Theme', '', 'uniform', SizeThemeOptions),
@@ -28,7 +28,7 @@ export const PolymerBackboneCylinderParams = {
export const DefaultPolymerBackboneCylinderProps = paramDefaultValues(PolymerBackboneCylinderParams)
export type PolymerBackboneCylinderProps = typeof DefaultPolymerBackboneCylinderProps
-async function createPolymerBackboneCylinderMesh(ctx: RuntimeContext, unit: Unit, structure: Structure, props: PolymerBackboneCylinderProps, mesh?: Mesh) {
+async function createPolymerBackboneCylinderMesh(ctx: VisualContext, unit: Unit, structure: Structure, props: PolymerBackboneCylinderProps, mesh?: Mesh) {
const polymerElementCount = unit.polymerElements.length
if (!polymerElementCount) return Mesh.createEmpty(mesh)
@@ -59,8 +59,8 @@ async function createPolymerBackboneCylinderMesh(ctx: RuntimeContext, unit: Unit
builder.setGroup(OrderedSet.indexOf(elements, centerB.element))
addCylinder(builder, pB, pA, 0.5, cylinderProps)
- if (i % 10000 === 0 && ctx.shouldUpdate) {
- await ctx.update({ message: 'Backbone mesh', current: i, max: polymerElementCount });
+ if (i % 10000 === 0 && ctx.runtime.shouldUpdate) {
+ await ctx.runtime.update({ message: 'Backbone mesh', current: i, max: polymerElementCount });
}
++i
}
diff --git a/src/mol-repr/structure/visual/polymer-direction-wedge.ts b/src/mol-repr/structure/visual/polymer-direction-wedge.ts
index 68049ec37d1758e163325661e536927721b7d7b7..461df57daff267d3d244e8f1aff061a0dd8df159 100644
--- a/src/mol-repr/structure/visual/polymer-direction-wedge.ts
+++ b/src/mol-repr/structure/visual/polymer-direction-wedge.ts
@@ -6,7 +6,6 @@
import { Unit, Structure } from 'mol-model/structure';
import { UnitsVisual } from '../index';
-import { RuntimeContext } from 'mol-task'
import { PolymerTraceIterator, createCurveSegmentState, interpolateCurveSegment, PolymerLocationIterator, getPolymerElementLoci, markPolymerElement } from './util/polymer';
import { Vec3, Mat4 } from 'mol-math/linear-algebra';
import { SecondaryStructureType, isNucleic } from 'mol-model/structure/model/types';
@@ -16,6 +15,7 @@ import { SelectParam, NumberParam, paramDefaultValues } from 'mol-util/parameter
import { Wedge } from 'mol-geo/primitive/wedge';
import { Mesh } from 'mol-geo/geometry/mesh/mesh';
import { MeshBuilder } from 'mol-geo/geometry/mesh/mesh-builder';
+import { VisualContext } from 'mol-repr';
const t = Mat4.identity()
const sVec = Vec3.zero()
@@ -36,7 +36,7 @@ export const PolymerDirectionWedgeParams = {
export const DefaultPolymerDirectionWedgeProps = paramDefaultValues(PolymerDirectionWedgeParams)
export type PolymerDirectionWedgeProps = typeof DefaultPolymerDirectionWedgeProps
-async function createPolymerDirectionWedgeMesh(ctx: RuntimeContext, unit: Unit, structure: Structure, props: PolymerDirectionWedgeProps, mesh?: Mesh) {
+async function createPolymerDirectionWedgeMesh(ctx: VisualContext, unit: Unit, structure: Structure, props: PolymerDirectionWedgeProps, mesh?: Mesh) {
const polymerElementCount = unit.polymerElements.length
if (!polymerElementCount) return Mesh.createEmpty(mesh)
@@ -80,8 +80,8 @@ async function createPolymerDirectionWedgeMesh(ctx: RuntimeContext, unit: Unit,
builder.add(t, wedge)
}
- if (i % 10000 === 0 && ctx.shouldUpdate) {
- await ctx.update({ message: 'Polymer direction mesh', current: i, max: polymerElementCount });
+ if (i % 10000 === 0 && ctx.runtime.shouldUpdate) {
+ await ctx.runtime.update({ message: 'Polymer direction mesh', current: i, max: polymerElementCount });
}
++i
}
diff --git a/src/mol-repr/structure/visual/polymer-gap-cylinder.ts b/src/mol-repr/structure/visual/polymer-gap-cylinder.ts
index 389b494a229089a2c6da9c18299698de7b3528c3..c00559b244db6e1efc308e05c9cdb641d79c5769 100644
--- a/src/mol-repr/structure/visual/polymer-gap-cylinder.ts
+++ b/src/mol-repr/structure/visual/polymer-gap-cylinder.ts
@@ -7,7 +7,6 @@
import { Unit, Structure } from 'mol-model/structure';
import { UnitsVisual } from '../index';
import { VisualUpdateState } from '../../util';
-import { RuntimeContext } from 'mol-task'
import { PolymerGapIterator, PolymerGapLocationIterator, markPolymerGapElement, getPolymerGapElementLoci } from './util/polymer';
import { Vec3 } from 'mol-math/linear-algebra';
import { UnitsMeshVisual, UnitsMeshParams } from '../units-visual';
@@ -19,6 +18,7 @@ import { MeshBuilder } from 'mol-geo/geometry/mesh/mesh-builder';
import { CylinderProps } from 'mol-geo/primitive/cylinder';
import { addSphere } from 'mol-geo/geometry/mesh/builder/sphere';
import { addFixedCountDashedCylinder } from 'mol-geo/geometry/mesh/builder/cylinder';
+import { VisualContext } from 'mol-repr';
const segmentCount = 10
@@ -31,7 +31,7 @@ export const PolymerGapCylinderParams = {
export const DefaultPolymerGapCylinderProps = paramDefaultValues(PolymerGapCylinderParams)
export type PolymerGapCylinderProps = typeof DefaultPolymerGapCylinderProps
-async function createPolymerGapCylinderMesh(ctx: RuntimeContext, unit: Unit, structure: Structure, props: PolymerGapCylinderProps, mesh?: Mesh) {
+async function createPolymerGapCylinderMesh(ctx: VisualContext, unit: Unit, structure: Structure, props: PolymerGapCylinderProps, mesh?: Mesh) {
const polymerGapCount = unit.gapElements.length
if (!polymerGapCount) return Mesh.createEmpty(mesh)
@@ -69,8 +69,8 @@ async function createPolymerGapCylinderMesh(ctx: RuntimeContext, unit: Unit, str
addFixedCountDashedCylinder(builder, pB, pA, 0.5, segmentCount, cylinderProps)
}
- if (i % 10000 === 0 && ctx.shouldUpdate) {
- await ctx.update({ message: 'Gap mesh', current: i, max: polymerGapCount });
+ if (i % 10000 === 0 && ctx.runtime.shouldUpdate) {
+ await ctx.runtime.update({ message: 'Gap mesh', current: i, max: polymerGapCount });
}
i += 2
}
diff --git a/src/mol-repr/structure/visual/polymer-trace-mesh.ts b/src/mol-repr/structure/visual/polymer-trace-mesh.ts
index 910f59b26e2d34ff85d078db1aeedb646ee1a65f..941d9d65148863cbe615120c238e0534f8ff75ee 100644
--- a/src/mol-repr/structure/visual/polymer-trace-mesh.ts
+++ b/src/mol-repr/structure/visual/polymer-trace-mesh.ts
@@ -7,7 +7,6 @@
import { Unit, Structure } from 'mol-model/structure';
import { UnitsVisual } from '../index';
import { VisualUpdateState } from '../../util';
-import { RuntimeContext } from 'mol-task'
import { PolymerTraceIterator, createCurveSegmentState, interpolateCurveSegment, PolymerLocationIterator, getPolymerElementLoci, markPolymerElement } from './util/polymer';
import { SecondaryStructureType, isNucleic } from 'mol-model/structure/model/types';
import { UnitsMeshVisual, UnitsMeshParams } from '../units-visual';
@@ -17,6 +16,7 @@ import { Mesh } from 'mol-geo/geometry/mesh/mesh';
import { MeshBuilder } from 'mol-geo/geometry/mesh/mesh-builder';
import { addSheet } from 'mol-geo/geometry/mesh/builder/sheet';
import { addTube } from 'mol-geo/geometry/mesh/builder/tube';
+import { VisualContext } from 'mol-repr';
export const PolymerTraceMeshParams = {
sizeTheme: SelectParam<SizeThemeName>('Size Theme', '', 'physical', SizeThemeOptions),
@@ -32,7 +32,7 @@ export type PolymerTraceMeshProps = typeof DefaultPolymerTraceMeshProps
// TODO handle polymer ends properly
-async function createPolymerTraceMesh(ctx: RuntimeContext, unit: Unit, structure: Structure, props: PolymerTraceMeshProps, mesh?: Mesh) {
+async function createPolymerTraceMesh(ctx: VisualContext, unit: Unit, structure: Structure, props: PolymerTraceMeshProps, mesh?: Mesh) {
const polymerElementCount = unit.polymerElements.length
if (!polymerElementCount) return Mesh.createEmpty(mesh)
@@ -80,8 +80,8 @@ async function createPolymerTraceMesh(ctx: RuntimeContext, unit: Unit, structure
addTube(builder, curvePoints, normalVectors, binormalVectors, linearSegments, radialSegments, width, height, 1, true, true)
}
- if (i % 10000 === 0 && ctx.shouldUpdate) {
- await ctx.update({ message: 'Polymer trace mesh', current: i, max: polymerElementCount });
+ if (i % 10000 === 0 && ctx.runtime.shouldUpdate) {
+ await ctx.runtime.update({ message: 'Polymer trace mesh', current: i, max: polymerElementCount });
}
++i
}
diff --git a/src/mol-repr/structure/visual/util/common.ts b/src/mol-repr/structure/visual/util/common.ts
index 33f226f22aafb4fecb3019379eea8fdf58f27858..a0cff0c67bd20c61ab0626bfa00bc8dbdd48f064 100644
--- a/src/mol-repr/structure/visual/util/common.ts
+++ b/src/mol-repr/structure/visual/util/common.ts
@@ -7,7 +7,6 @@
import { Unit, Structure } from 'mol-model/structure';
import { StructureProps } from '../../index';
import { createMeshRenderObject, createPointsRenderObject, createLinesRenderObject, createDirectVolumeRenderObject } from 'mol-gl/render-object';
-import { RuntimeContext } from 'mol-task';
import { Mat4 } from 'mol-math/linear-algebra';
import { TransformData, createTransform, createIdentityTransform } from 'mol-geo/geometry/transform-data';
import { Mesh } from 'mol-geo/geometry/mesh/mesh';
@@ -16,6 +15,7 @@ import { createRenderableState } from 'mol-geo/geometry/geometry';
import { Points } from 'mol-geo/geometry/points/points';
import { Lines } from 'mol-geo/geometry/lines/lines';
import { DirectVolume } from 'mol-geo/geometry/direct-volume/direct-volume';
+import { VisualContext } from 'mol-repr';
export function createUnitsTransform({ units }: Unit.SymmetryGroup, transformData?: TransformData) {
const unitCount = units.length
@@ -49,16 +49,16 @@ export function includesUnitKind(unitKinds: UnitKind[], unit: Unit) {
type StructureMeshProps = Mesh.Props & StructureProps
-export async function createComplexMeshRenderObject(ctx: RuntimeContext, structure: Structure, mesh: Mesh, locationIt: LocationIterator, props: StructureMeshProps) {
+export async function createComplexMeshRenderObject(ctx: VisualContext, structure: Structure, mesh: Mesh, locationIt: LocationIterator, props: StructureMeshProps) {
const transform = createIdentityTransform()
- const values = await Mesh.createValues(ctx, mesh, transform, locationIt, props)
+ const values = await Mesh.createValues(ctx.runtime, mesh, transform, locationIt, props)
const state = createRenderableState(props)
return createMeshRenderObject(values, state)
}
-export async function createUnitsMeshRenderObject(ctx: RuntimeContext, group: Unit.SymmetryGroup, mesh: Mesh, locationIt: LocationIterator, props: StructureMeshProps) {
+export async function createUnitsMeshRenderObject(ctx: VisualContext, group: Unit.SymmetryGroup, mesh: Mesh, locationIt: LocationIterator, props: StructureMeshProps) {
const transform = createUnitsTransform(group)
- const values = await Mesh.createValues(ctx, mesh, transform, locationIt, props)
+ const values = await Mesh.createValues(ctx.runtime, mesh, transform, locationIt, props)
const state = createRenderableState(props)
return createMeshRenderObject(values, state)
}
@@ -67,9 +67,9 @@ export async function createUnitsMeshRenderObject(ctx: RuntimeContext, group: Un
type StructurePointsProps = Points.Props & StructureProps
-export async function createUnitsPointsRenderObject(ctx: RuntimeContext, group: Unit.SymmetryGroup, points: Points, locationIt: LocationIterator, props: StructurePointsProps) {
+export async function createUnitsPointsRenderObject(ctx: VisualContext, group: Unit.SymmetryGroup, points: Points, locationIt: LocationIterator, props: StructurePointsProps) {
const transform = createUnitsTransform(group)
- const values = await Points.createValues(ctx, points, transform, locationIt, props)
+ const values = await Points.createValues(ctx.runtime, points, transform, locationIt, props)
const state = createRenderableState(props)
return createPointsRenderObject(values, state)
}
@@ -78,9 +78,9 @@ export async function createUnitsPointsRenderObject(ctx: RuntimeContext, group:
type StructureLinesProps = Lines.Props & StructureProps
-export async function createUnitsLinesRenderObject(ctx: RuntimeContext, group: Unit.SymmetryGroup, lines: Lines, locationIt: LocationIterator, props: StructureLinesProps) {
+export async function createUnitsLinesRenderObject(ctx: VisualContext, group: Unit.SymmetryGroup, lines: Lines, locationIt: LocationIterator, props: StructureLinesProps) {
const transform = createUnitsTransform(group)
- const values = await Lines.createValues(ctx, lines, transform, locationIt, props)
+ const values = await Lines.createValues(ctx.runtime, lines, transform, locationIt, props)
const state = createRenderableState(props)
return createLinesRenderObject(values, state)
}
@@ -89,9 +89,9 @@ export async function createUnitsLinesRenderObject(ctx: RuntimeContext, group: U
type StructureDirectVolumeProps = DirectVolume.Props & StructureProps
-export async function createUnitsDirectVolumeRenderObject(ctx: RuntimeContext, group: Unit.SymmetryGroup, directVolume: DirectVolume, locationIt: LocationIterator, props: StructureDirectVolumeProps) {
+export async function createUnitsDirectVolumeRenderObject(ctx: VisualContext, group: Unit.SymmetryGroup, directVolume: DirectVolume, locationIt: LocationIterator, props: StructureDirectVolumeProps) {
const transform = createUnitsTransform(group)
- const values = await DirectVolume.createValues(ctx, directVolume, transform, locationIt, props)
+ const values = await DirectVolume.createValues(ctx.runtime, directVolume, transform, locationIt, props)
const state = createRenderableState(props)
return createDirectVolumeRenderObject(values, state)
}
\ No newline at end of file
diff --git a/src/mol-repr/structure/visual/util/element.ts b/src/mol-repr/structure/visual/util/element.ts
index 4c1362033225ef4a8c9d1cbbacfe465d08bfda6e..909bce22aa260a8a8491c31d1cc015d4c7f90dac 100644
--- a/src/mol-repr/structure/visual/util/element.ts
+++ b/src/mol-repr/structure/visual/util/element.ts
@@ -6,7 +6,6 @@
import { Vec3 } from 'mol-math/linear-algebra';
import { Unit, StructureElement, Structure } from 'mol-model/structure';
-import { RuntimeContext } from 'mol-task';
import { Loci, EmptyLoci } from 'mol-model/loci';
import { Interval, OrderedSet } from 'mol-data/int';
import { SizeTheme, SizeThemeName } from 'mol-theme/size';
@@ -16,6 +15,7 @@ import { MeshBuilder } from 'mol-geo/geometry/mesh/mesh-builder';
import { addSphere } from 'mol-geo/geometry/mesh/builder/sphere';
import { PickingId } from 'mol-geo/geometry/picking';
import { LocationIterator } from 'mol-geo/util/location-iterator';
+import { VisualContext } from 'mol-repr';
export interface ElementSphereMeshProps {
sizeTheme: SizeThemeName,
@@ -23,7 +23,7 @@ export interface ElementSphereMeshProps {
detail: number,
}
-export async function createElementSphereMesh(ctx: RuntimeContext, unit: Unit, structure: Structure, props: ElementSphereMeshProps, mesh?: Mesh) {
+export async function createElementSphereMesh(ctx: VisualContext, unit: Unit, structure: Structure, props: ElementSphereMeshProps, mesh?: Mesh) {
const { detail } = props
const { elements } = unit;
@@ -44,8 +44,8 @@ export async function createElementSphereMesh(ctx: RuntimeContext, unit: Unit, s
meshBuilder.setGroup(i)
addSphere(meshBuilder, v, sizeTheme.size(l), detail)
- if (i % 10000 === 0 && ctx.shouldUpdate) {
- await ctx.update({ message: 'Sphere mesh', current: i, max: elementCount });
+ if (i % 10000 === 0 && ctx.runtime.shouldUpdate) {
+ await ctx.runtime.update({ message: 'Sphere mesh', current: i, max: elementCount });
}
}
diff --git a/src/mol-repr/structure/visual/util/link.ts b/src/mol-repr/structure/visual/util/link.ts
index 53d9688bcbd168100046207df44a5c80160a2c4b..4f3931f480ddf07a77f3dc13c3830542ff8b4a32 100644
--- a/src/mol-repr/structure/visual/util/link.ts
+++ b/src/mol-repr/structure/visual/util/link.ts
@@ -5,7 +5,6 @@
*/
import { Vec3 } from 'mol-math/linear-algebra';
-import { RuntimeContext } from 'mol-task';
import { LinkType } from 'mol-model/structure/model/types';
import { SizeThemeName, SizeThemeOptions } from 'mol-theme/size';
import { Unit, StructureElement, Structure, Link } from 'mol-model/structure';
@@ -15,6 +14,7 @@ import { MeshBuilder } from 'mol-geo/geometry/mesh/mesh-builder';
import { CylinderProps } from 'mol-geo/primitive/cylinder';
import { addFixedCountDashedCylinder, addCylinder, addDoubleCylinder } from 'mol-geo/geometry/mesh/builder/cylinder';
import { LocationIterator } from 'mol-geo/util/location-iterator';
+import { VisualContext } from 'mol-repr';
export const LinkCylinderParams = {
sizeTheme: SelectParam<SizeThemeName>('Size Theme', '', 'uniform', SizeThemeOptions),
@@ -71,7 +71,7 @@ export interface LinkCylinderMeshBuilderProps {
* Each edge is included twice to allow for coloring/picking
* the half closer to the first vertex, i.e. vertex a.
*/
-export async function createLinkCylinderMesh(ctx: RuntimeContext, linkBuilder: LinkCylinderMeshBuilderProps, props: LinkCylinderProps, mesh?: Mesh) {
+export async function createLinkCylinderMesh(ctx: VisualContext, linkBuilder: LinkCylinderMeshBuilderProps, props: LinkCylinderProps, mesh?: Mesh) {
const { linkCount, referencePosition, position, order, flags, radius } = linkBuilder
if (!linkCount) return Mesh.createEmpty(mesh)
@@ -115,8 +115,8 @@ export async function createLinkCylinderMesh(ctx: RuntimeContext, linkBuilder: L
addCylinder(meshBuilder, va, vb, 0.5, cylinderProps)
}
- if (edgeIndex % 10000 === 0 && ctx.shouldUpdate) {
- await ctx.update({ message: 'Cylinder mesh', current: edgeIndex, max: linkCount });
+ if (edgeIndex % 10000 === 0 && ctx.runtime.shouldUpdate) {
+ await ctx.runtime.update({ message: 'Cylinder mesh', current: edgeIndex, max: linkCount });
}
}
diff --git a/src/mol-repr/util.ts b/src/mol-repr/util.ts
index 792e9ff05be9e3331d77b8323948daba894e4916..0b71cd247d96592ae3dc676a30a4fd54b88cb27b 100644
--- a/src/mol-repr/util.ts
+++ b/src/mol-repr/util.ts
@@ -44,7 +44,10 @@ export function sizeChanged(oldProps: SizeProps, newProps: SizeProps) {
export function colorChanged(oldProps: ColorProps, newProps: ColorProps) {
return (
oldProps.colorTheme !== newProps.colorTheme ||
- oldProps.colorValue !== newProps.colorValue
+ oldProps.colorValue !== newProps.colorValue ||
+ oldProps.colorDomain !== newProps.colorDomain ||
+ oldProps.colorList !== newProps.colorList ||
+ oldProps.colorMap !== newProps.colorMap
)
}
diff --git a/src/mol-repr/volume/direct-volume.ts b/src/mol-repr/volume/direct-volume.ts
index 5ec65ef71512ba9a5d0f93c7abaeb4dfad9f8809..ce412b099d4f6a811e62e9481cd05c2a1130a146 100644
--- a/src/mol-repr/volume/direct-volume.ts
+++ b/src/mol-repr/volume/direct-volume.ts
@@ -7,7 +7,7 @@
import { VolumeData } from 'mol-model/volume'
import { RuntimeContext } from 'mol-task'
import { VolumeVisual, VolumeRepresentation } from './index';
-import { DirectVolumeRenderObject, createDirectVolumeRenderObject } from 'mol-gl/render-object';
+import { createDirectVolumeRenderObject } from 'mol-gl/render-object';
import { Loci, EmptyLoci } from 'mol-model/loci';
import { paramDefaultValues } from 'mol-util/parameter';
import { Vec3, Mat4 } from 'mol-math/linear-algebra';
@@ -15,12 +15,13 @@ import { Box3D } from 'mol-math/geometry';
import { WebGLContext } from 'mol-gl/webgl/context';
import { createTexture } from 'mol-gl/webgl/texture';
import { LocationIterator } from 'mol-geo/util/location-iterator';
-import { NullLocation } from 'mol-model/location';
import { createIdentityTransform } from 'mol-geo/geometry/transform-data';
import { DirectVolume } from 'mol-geo/geometry/direct-volume/direct-volume';
-import { Geometry, createRenderableState, updateRenderableState } from 'mol-geo/geometry/geometry';
+import { Geometry, createRenderableState } from 'mol-geo/geometry/geometry';
import { PickingId } from 'mol-geo/geometry/picking';
import { MarkerAction } from 'mol-geo/geometry/marker-data';
+import { VisualUpdateState } from 'mol-repr/util';
+import { VisualContext, RepresentationContext } from 'mol-repr';
function getBoundingBox(gridDimension: Vec3, transform: Mat4) {
const bbox = Box3D.empty()
@@ -168,6 +169,18 @@ export function createDirectVolume3d(ctx: RuntimeContext, webgl: WebGLContext, v
return DirectVolume.create(bbox, gridDimension, transform, texture, directVolume)
}
+//
+
+export async function createDirectVolume(ctx: VisualContext, volume: VolumeData, props: DirectVolumeProps, directVolume?: DirectVolume) {
+ const { runtime, webgl } = ctx
+ if (webgl === undefined) throw new Error('DirectVolumeVisual requires `webgl` in props')
+
+ return webgl.isWebGL2 ?
+ await createDirectVolume3d(runtime, webgl, volume, directVolume) :
+ await createDirectVolume2d(runtime, webgl, volume, directVolume)
+}
+
+
//
export const DirectVolumeParams = {
@@ -178,81 +191,21 @@ export const DefaultDirectVolumeProps = paramDefaultValues(DirectVolumeParams)
export type DirectVolumeProps = typeof DefaultDirectVolumeProps
export function DirectVolumeVisual(): VolumeVisual<DirectVolumeProps> {
- let currentProps = DefaultDirectVolumeProps
- let renderObject: DirectVolumeRenderObject
- let currentVolume: VolumeData
- let directVolume: DirectVolume
-
- async function create(ctx: RuntimeContext, volume: VolumeData, props: Partial<DirectVolumeProps> = {}) {
- const { webgl } = props
- if (webgl === undefined) throw new Error('DirectVolumeVisual requires `webgl` in props')
-
- currentProps = { ...DefaultDirectVolumeProps, ...props }
- if (props.isoValueRelative) {
- // currentProps.isoValueAbsolute = VolumeIsoValue.calcAbsolute(currentVolume.dataStats, props.isoValueRelative)
- }
-
- const state = createRenderableState(currentProps)
- const locationIt = LocationIterator(1, 1, () => NullLocation)
- const transform = createIdentityTransform()
-
- if (webgl.isWebGL2) {
- directVolume = await createDirectVolume3d(ctx, webgl, volume, directVolume)
- const values = await DirectVolume.createValues(ctx, directVolume, transform, locationIt, currentProps)
- renderObject = createDirectVolumeRenderObject(values, state)
- } else {
- directVolume = await createDirectVolume2d(ctx, webgl, volume, directVolume)
- const values = await DirectVolume.createValues(ctx, directVolume, transform, locationIt, currentProps)
- renderObject = createDirectVolumeRenderObject(values, state)
- }
- }
-
- async function update(ctx: RuntimeContext, props: Partial<DirectVolumeProps> = {}) {
- const { webgl } = props
- if (webgl === undefined) throw new Error('DirectVolumeVisual requires `webgl` in props')
-
- const newProps = { ...currentProps, ...props }
- if (props.isoValueRelative) {
- // newProps.isoValueAbsolute = VolumeIsoValue.calcAbsolute(currentVolume.dataStats, props.isoValueRelative)
- }
-
- console.log('newProps.isoValueAbsolute', newProps.isoValueAbsolute)
-
- DirectVolume.updateValues(renderObject.values, newProps)
- updateRenderableState(renderObject.state, newProps)
-
- currentProps = newProps
- }
-
- return {
- get renderObject () { return renderObject },
- async createOrUpdate(ctx: RuntimeContext, props: Partial<DirectVolumeProps> = {}, volume?: VolumeData) {
- if (!volume && !currentVolume) {
- throw new Error('missing volume')
- } else if (volume && (!currentVolume || !renderObject)) {
- currentVolume = volume
- await create(ctx, volume, props)
- } else if (volume && volume !== currentVolume) {
- currentVolume = volume
- await create(ctx, volume, props)
- } else {
- await update(ctx, props)
- }
-
- currentProps = { ...DefaultDirectVolumeProps, ...props }
- },
- getLoci(pickingId: PickingId) {
- // TODO
- return EmptyLoci
+ return VolumeVisual<DirectVolumeProps>({
+ defaultProps: DefaultDirectVolumeProps,
+ createGeometry: createDirectVolume,
+ getLoci: () => EmptyLoci,
+ mark: () => false,
+ setUpdateState: (state: VisualUpdateState, newProps: DirectVolumeProps, currentProps: DirectVolumeProps) => {
},
- mark(loci: Loci, action: MarkerAction) {
- // TODO
- return false
+ createRenderObject: async (ctx: VisualContext, geometry: DirectVolume, locationIt: LocationIterator, props: DirectVolumeProps) => {
+ const transform = createIdentityTransform()
+ const values = await DirectVolume.createValues(ctx.runtime, geometry, transform, locationIt, props)
+ const state = createRenderableState(props)
+ return createDirectVolumeRenderObject(values, state)
},
- destroy() {
- // TODO
- }
- }
+ updateValues: DirectVolume.updateValues
+ })
}
export function DirectVolumeRepresentation(): VolumeRepresentation<DirectVolumeProps> {
@@ -267,9 +220,9 @@ export function DirectVolumeRepresentation(): VolumeRepresentation<DirectVolumeP
get props() {
return { ...volumeRepr.props }
},
- createOrUpdate: (props: Partial<DirectVolumeProps> = {}, volume?: VolumeData) => {
+ createOrUpdate: (ctx: RepresentationContext, props: Partial<DirectVolumeProps> = {}, volume?: VolumeData) => {
currentProps = Object.assign({}, DefaultDirectVolumeProps, currentProps, props)
- return volumeRepr.createOrUpdate(currentProps, volume)
+ return volumeRepr.createOrUpdate(ctx, currentProps, volume)
},
getLoci: (pickingId: PickingId) => {
return volumeRepr.getLoci(pickingId)
diff --git a/src/mol-repr/volume/index.ts b/src/mol-repr/volume/index.ts
index 49f6a31cbc4a82bb0b9a40027db320eef005075a..f7d0ddded2558081b882009f0301a535cdbaa51f 100644
--- a/src/mol-repr/volume/index.ts
+++ b/src/mol-repr/volume/index.ts
@@ -4,8 +4,8 @@
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
-import { Task, RuntimeContext } from 'mol-task'
-import { RepresentationProps, Representation, Visual } from '..';
+import { Task } from 'mol-task'
+import { RepresentationProps, Representation, Visual, RepresentationContext, VisualContext } from '..';
import { VolumeData, VolumeIsoValue } from 'mol-model/volume';
import { Loci, EmptyLoci, isEveryLoci } from 'mol-model/loci';
import { paramDefaultValues, RangeParam } from 'mol-util/parameter';
@@ -26,14 +26,14 @@ type VolumeRenderObject = MeshRenderObject | LinesRenderObject | PointsRenderObj
interface VolumeVisualBuilder<P extends VolumeProps, G extends Geometry> {
defaultProps: P
- createGeometry(ctx: RuntimeContext, volumeData: VolumeData, props: P, geometry?: G): Promise<G>
+ createGeometry(ctx: VisualContext, volumeData: VolumeData, props: P, geometry?: G): Promise<G>
getLoci(pickingId: PickingId, id: number): Loci
mark(loci: Loci, apply: (interval: Interval) => boolean): boolean
setUpdateState(state: VisualUpdateState, newProps: P, currentProps: P): void
}
interface VolumeVisualGeometryBuilder<P extends VolumeProps, G extends Geometry> extends VolumeVisualBuilder<P, G> {
- createRenderObject(ctx: RuntimeContext, geometry: G, locationIt: LocationIterator, currentProps: P): Promise<VolumeRenderObject>
+ createRenderObject(ctx: VisualContext, geometry: G, locationIt: LocationIterator, currentProps: P): Promise<VolumeRenderObject>
updateValues(values: RenderableValues, newProps: P): void
}
@@ -48,7 +48,7 @@ export function VolumeVisual<P extends VolumeProps>(builder: VolumeVisualGeometr
let geometry: Geometry
let locationIt: LocationIterator
- async function create(ctx: RuntimeContext, volume: VolumeData, props: Partial<VolumeProps> = {}) {
+ async function create(ctx: VisualContext, volume: VolumeData, props: Partial<VolumeProps> = {}) {
currentProps = Object.assign({}, defaultProps, props)
if (props.isoValueRelative) {
currentProps.isoValueAbsolute = VolumeIsoValue.calcAbsolute(currentVolume.dataStats, props.isoValueRelative)
@@ -60,7 +60,7 @@ export function VolumeVisual<P extends VolumeProps>(builder: VolumeVisualGeometr
renderObject = await createRenderObject(ctx, geometry, locationIt, currentProps)
}
- async function update(ctx: RuntimeContext, props: Partial<VolumeProps> = {}) {
+ async function update(ctx: VisualContext, props: Partial<VolumeProps> = {}) {
if (!renderObject) return
const newProps = Object.assign({}, currentProps, props)
@@ -85,7 +85,7 @@ export function VolumeVisual<P extends VolumeProps>(builder: VolumeVisualGeometr
return {
get renderObject () { return renderObject },
- async createOrUpdate(ctx: RuntimeContext, props: Partial<VolumeProps> = {}, volume?: VolumeData) {
+ async createOrUpdate(ctx: VisualContext, props: Partial<VolumeProps> = {}, volume?: VolumeData) {
if (!volume && !currentVolume) {
throw new Error('missing volume')
} else if (volume && (!currentVolume || !renderObject)) {
@@ -147,9 +147,9 @@ export function VolumeRepresentation<P extends VolumeProps>(visualCtor: (volumeD
let _props: P
let busy = false
- function createOrUpdate(props: Partial<P> = {}, volumeData?: VolumeData) {
+ function createOrUpdate(ctx: RepresentationContext, props: Partial<P> = {}, volumeData?: VolumeData) {
_props = Object.assign({}, DefaultVolumeProps, _props, props)
- return Task.create('VolumeRepresentation.create', async ctx => {
+ return Task.create('VolumeRepresentation.create', async runtime => {
// TODO queue it somehow
if (busy) return
@@ -158,11 +158,11 @@ export function VolumeRepresentation<P extends VolumeProps>(visualCtor: (volumeD
} else if (volumeData && !visual) {
busy = true
visual = visualCtor(volumeData)
- await visual.createOrUpdate(ctx, props, volumeData)
+ await visual.createOrUpdate({ ...ctx, runtime } , props, volumeData)
busy = false
} else {
busy = true
- await visual.createOrUpdate(ctx, props, volumeData)
+ await visual.createOrUpdate({ ...ctx, runtime }, props, volumeData)
busy = false
}
});
diff --git a/src/mol-repr/volume/isosurface-mesh.ts b/src/mol-repr/volume/isosurface-mesh.ts
index 0dd1b600d245b7f94de9f147d4b17f471b8f8033..1f81989e83bab70631a943033fe36d39a466d790 100644
--- a/src/mol-repr/volume/isosurface-mesh.ts
+++ b/src/mol-repr/volume/isosurface-mesh.ts
@@ -6,7 +6,6 @@
*/
import { VolumeData } from 'mol-model/volume'
-import { RuntimeContext } from 'mol-task'
import { VolumeVisual, VolumeRepresentation } from './index';
import { createMeshRenderObject } from 'mol-gl/render-object';
import { Loci, EmptyLoci } from 'mol-model/loci';
@@ -19,21 +18,22 @@ import { createRenderableState } from 'mol-geo/geometry/geometry';
import { PickingId } from 'mol-geo/geometry/picking';
import { MarkerAction } from 'mol-geo/geometry/marker-data';
import { VisualUpdateState } from 'mol-repr/util';
+import { RepresentationContext, VisualContext } from 'mol-repr';
interface VolumeIsosurfaceProps {
isoValueAbsolute: number
}
-export async function createVolumeIsosurface(ctx: RuntimeContext, volume: VolumeData, props: VolumeIsosurfaceProps, mesh?: Mesh) {
- ctx.update({ message: 'Marching cubes...' });
+export async function createVolumeIsosurface(ctx: VisualContext, volume: VolumeData, props: VolumeIsosurfaceProps, mesh?: Mesh) {
+ ctx.runtime.update({ message: 'Marching cubes...' });
const surface = await computeMarchingCubesMesh({
isoLevel: props.isoValueAbsolute,
scalarField: volume.data
- }, mesh).runAsChild(ctx);
+ }, mesh).runAsChild(ctx.runtime);
const transform = VolumeData.getGridToCartesianTransform(volume);
- ctx.update({ message: 'Transforming mesh...' });
+ ctx.runtime.update({ message: 'Transforming mesh...' });
Mesh.transformImmediate(surface, transform);
Mesh.computeNormalsImmediate(surface)
@@ -48,7 +48,7 @@ export const IsosurfaceParams = {
export const DefaultIsosurfaceProps = paramDefaultValues(IsosurfaceParams)
export type IsosurfaceProps = typeof DefaultIsosurfaceProps
-export function IsosurfaceVisual(): VolumeVisual<IsosurfaceProps> {
+export function IsosurfaceVisual(): VolumeVisual<IsosurfaceProps> {
return VolumeVisual<IsosurfaceProps>({
defaultProps: DefaultIsosurfaceProps,
createGeometry: createVolumeIsosurface,
@@ -57,9 +57,9 @@ export function IsosurfaceVisual(): VolumeVisual<IsosurfaceProps> {
setUpdateState: (state: VisualUpdateState, newProps: IsosurfaceProps, currentProps: IsosurfaceProps) => {
if (newProps.isoValueAbsolute !== currentProps.isoValueAbsolute) state.createGeometry = true
},
- createRenderObject: async (ctx: RuntimeContext, geometry: Mesh, locationIt: LocationIterator, props: IsosurfaceProps) => {
+ createRenderObject: async (ctx: VisualContext, geometry: Mesh, locationIt: LocationIterator, props: IsosurfaceProps) => {
const transform = createIdentityTransform()
- const values = await Mesh.createValues(ctx, geometry, transform, locationIt, props)
+ const values = await Mesh.createValues(ctx.runtime, geometry, transform, locationIt, props)
const state = createRenderableState(props)
return createMeshRenderObject(values, state)
},
@@ -79,9 +79,9 @@ export function IsosurfaceRepresentation(): VolumeRepresentation<IsosurfaceProps
get props() {
return { ...volumeRepr.props }
},
- createOrUpdate: (props: Partial<IsosurfaceProps> = {}, volume?: VolumeData) => {
+ createOrUpdate: (ctx: RepresentationContext, props: Partial<IsosurfaceProps> = {}, volume?: VolumeData) => {
currentProps = Object.assign({}, DefaultIsosurfaceProps, currentProps, props)
- return volumeRepr.createOrUpdate(currentProps, volume)
+ return volumeRepr.createOrUpdate(ctx, currentProps, volume)
},
getLoci: (pickingId: PickingId) => {
return volumeRepr.getLoci(pickingId)
diff --git a/src/mol-theme/color.ts b/src/mol-theme/color.ts
index c11848731cdae4a30529c7d2e62a9ed272b8cc26..d087e249c80cbd17e3e30f49102a5bdde537f012 100644
--- a/src/mol-theme/color.ts
+++ b/src/mol-theme/color.ts
@@ -4,7 +4,7 @@
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
-import { Color } from 'mol-util/color';
+import { Color, ColorMap } from 'mol-util/color';
import { Structure } from 'mol-model/structure';
import { Location } from 'mol-model/location';
import { ColorType } from 'mol-geo/geometry/color-data';
@@ -23,6 +23,7 @@ import { SequenceIdColorTheme } from './color/sequence-id';
import { SecondaryStructureColorTheme } from './color/secondary-structure';
import { MoleculeTypeColorTheme } from './color/molecule-type';
import { PolymerIndexColorTheme } from './color/polymer-index';
+import { ColorMatplotlib, ColorBrewer, ColorOther } from 'mol-util/color/tables';
export type LocationColor = (location: Location, isSecondary: boolean) => Color
@@ -36,6 +37,29 @@ export function ScaleLegend(minLabel: string, maxLabel: string, colors: Color[])
return { kind: 'scale-legend', minLabel, maxLabel, colors }
}
+export type ColorScaleName = (
+ 'default' |
+ keyof typeof ColorBrewer | keyof typeof ColorMatplotlib | keyof typeof ColorOther
+)
+export const ColorScaleNames = [
+ 'default',
+ ...Object.keys(ColorBrewer), ...Object.keys(ColorMatplotlib), ...Object.keys(ColorOther)
+]
+export const ColorScaleOptions = ColorScaleNames.map(n => [n, n] as [ColorScaleName, string])
+
+export function getColorScaleFromName(name: string) {
+ if (name === 'default') {
+ return
+ } else if (name in ColorBrewer) {
+ return ColorBrewer[name as keyof typeof ColorBrewer]
+ } else if (name in ColorMatplotlib) {
+ return ColorMatplotlib[name as keyof typeof ColorMatplotlib]
+ } else if (name in ColorOther) {
+ return ColorOther[name as keyof typeof ColorOther]
+ }
+ console.warn(`unknwon color list named '${name}'`)
+}
+
export interface TableLegend {
kind: 'table-legend'
table: [ string, Color ][]
@@ -44,7 +68,23 @@ export function TableLegend(table: [ string, Color ][]): TableLegend {
return { kind: 'table-legend', table }
}
+export interface ColorThemeFeatures {
+ /** Does allow providing a structure object */
+ structure?: boolean
+ /** Does allow providing a volume object */
+ volume?: boolean
+ /** Does allow providing a list of colors (for creating a scale) */
+ list?: boolean
+ /** Does allow providing a map of colors */
+ map?: boolean
+ /** Does allow providing the boundaries for the scale */
+ domain?: boolean
+ /** Does allow providing a single/special color value */
+ value?: boolean
+}
+
export interface ColorTheme {
+ features: ColorThemeFeatures
granularity: ColorType
color: LocationColor
description?: string
@@ -74,6 +114,8 @@ export interface ColorThemeProps {
name: ColorThemeName
domain?: [number, number]
value?: Color
+ list?: Color[]
+ map?: ColorMap<any>
structure?: Structure
color?: LocationColor
granularity?: ColorType,
diff --git a/src/mol-theme/color/carbohydrate-symbol.ts b/src/mol-theme/color/carbohydrate-symbol.ts
index c777c91d538684085041c23698ee19657fb18de7..a21853d87f941f899f7071ff3260b55b9d346541 100644
--- a/src/mol-theme/color/carbohydrate-symbol.ts
+++ b/src/mol-theme/color/carbohydrate-symbol.ts
@@ -47,6 +47,7 @@ export function CarbohydrateSymbolColorTheme(props: ColorThemeProps): ColorTheme
}
return {
+ features: {},
granularity: 'group',
color: color,
description: Description,
diff --git a/src/mol-theme/color/chain-id.ts b/src/mol-theme/color/chain-id.ts
index e281dc9a20dc39fd36c3f937ec8920bb87e1f9b3..0fd9e3955a12238e72496d5e527a8a7e71741944 100644
--- a/src/mol-theme/color/chain-id.ts
+++ b/src/mol-theme/color/chain-id.ts
@@ -63,6 +63,7 @@ export function ChainIdColorTheme(props: ColorThemeProps): ColorTheme {
}
return {
+ features: {},
granularity: 'group',
color,
description: Description,
diff --git a/src/mol-theme/color/cross-link.ts b/src/mol-theme/color/cross-link.ts
index 6f8ab371e6ff957f71fd081850f25acc55b23ac0..bb3cf176c4f5a5c8fdbc330b63e7c69e5436c089 100644
--- a/src/mol-theme/color/cross-link.ts
+++ b/src/mol-theme/color/cross-link.ts
@@ -6,10 +6,12 @@
import { Link } from 'mol-model/structure';
-import { Color, ColorScale, ColorBrewer } from 'mol-util/color';
+import { Color, ColorScale } from 'mol-util/color';
import { Location } from 'mol-model/location';
import { ColorThemeProps, ColorTheme, LocationColor } from '../color';
import { Vec3 } from 'mol-math/linear-algebra';
+import { ColorBrewer } from 'mol-util/color/tables';
+import { defaults } from 'mol-util';
const DefaultColor = Color(0xCCCCCC)
const Description = 'Colors cross-links by the deviation of the observed distance versus the modeled distance (e.g. `ihm_cross_link_restraint.distance_threshold`).'
@@ -27,7 +29,10 @@ export function CrossLinkColorTheme(props: ColorThemeProps): ColorTheme {
if (props.structure) {
const crosslinks = props.structure.crossLinkRestraints
- scale = ColorScale.create({ domain: [ -10, 10 ], colors: ColorBrewer.RdYlBu })
+ scale = ColorScale.create({
+ domain: defaults(props.domain, [ -10, 10 ]),
+ list: defaults(props.list, ColorBrewer.RdYlBu)
+ })
const scaleColor = scale.color
color = (location: Location): Color => {
@@ -44,6 +49,7 @@ export function CrossLinkColorTheme(props: ColorThemeProps): ColorTheme {
}
return {
+ features: { list: true, domain: true },
granularity: 'group',
color,
description: Description,
diff --git a/src/mol-theme/color/custom.ts b/src/mol-theme/color/custom.ts
index 4901ac06f6860660a7cfb1edb9a1505d9e052c17..4eb5a10ea4497ba5c419607e1467245b4758dc0e 100644
--- a/src/mol-theme/color/custom.ts
+++ b/src/mol-theme/color/custom.ts
@@ -13,6 +13,7 @@ const DefaultColor = Color(0xCCCCCC)
export function CustomColorTheme(props: ColorThemeProps): ColorTheme {
const value = defaults(props.value, DefaultColor)
return {
+ features: {},
granularity: defaults(props.granularity, 'uniform'),
color: defaults(props.color, () => value),
description: props.description,
diff --git a/src/mol-theme/color/element-index.ts b/src/mol-theme/color/element-index.ts
index 8ca2d273a0c5c30c2d16c323adefd77ed043295d..ecce0a1c1bc0804043f2c9ee4c5f8aaabbc69882 100644
--- a/src/mol-theme/color/element-index.ts
+++ b/src/mol-theme/color/element-index.ts
@@ -29,7 +29,7 @@ export function ElementIndexColorTheme(props: ColorThemeProps): ColorTheme {
elementCount += units[i].elements.length
unitIdIndex.set(units[i].id, i)
}
- scale = ColorScale.create({ domain: [ 0, elementCount - 1 ] })
+ scale = ColorScale.create({ domain: [ 0, elementCount - 1 ], list: props.list })
const scaleColor = scale.color
color = (location: Location): Color => {
@@ -48,6 +48,7 @@ export function ElementIndexColorTheme(props: ColorThemeProps): ColorTheme {
}
return {
+ features: { list: true },
granularity: 'groupInstance',
color,
description: Description,
diff --git a/src/mol-theme/color/element-symbol.ts b/src/mol-theme/color/element-symbol.ts
index e382f14d87f48d496faaa8eb2c0e794bbc04aa5c..8d7f87b21d0d99e686fea90c4011a3df572d7b2d 100644
--- a/src/mol-theme/color/element-symbol.ts
+++ b/src/mol-theme/color/element-symbol.ts
@@ -40,6 +40,7 @@ export function ElementSymbolColorTheme(props: ColorThemeProps): ColorTheme {
}
return {
+ features: {},
granularity: 'group',
color,
description: Description,
diff --git a/src/mol-theme/color/molecule-type.ts b/src/mol-theme/color/molecule-type.ts
index f2be520fe8c9791b3d4920d8634aa7da709d9662..9bdc21d39a52dae10358d5f0d3c61feda2cabd44 100644
--- a/src/mol-theme/color/molecule-type.ts
+++ b/src/mol-theme/color/molecule-type.ts
@@ -49,6 +49,7 @@ export function MoleculeTypeColorTheme(props: ColorThemeProps): ColorTheme {
}
return {
+ features: {},
granularity: 'group',
color,
description: Description,
diff --git a/src/mol-theme/color/polymer-index.ts b/src/mol-theme/color/polymer-index.ts
index 891b17300f72f94ab19e1c1883e19c303f9d0659..b32fa80cbaa1649bbdf2b0aed8d2ace1f6f9b3e8 100644
--- a/src/mol-theme/color/polymer-index.ts
+++ b/src/mol-theme/color/polymer-index.ts
@@ -22,7 +22,7 @@ export function PolymerIndexColorTheme(props: ColorThemeProps): ColorTheme {
for (let i = 0, il = units.length; i <il; ++i) {
if (units[i].polymerElements.length > 0) ++polymerCount
}
- scale = ColorScale.create({ domain: [ 0, polymerCount - 1 ] })
+ scale = ColorScale.create({ list: props.list, domain: [ 0, polymerCount - 1 ] })
const unitIdColor = new Map<number, Color>()
for (let i = 0, j = 0, il = units.length; i <il; ++i) {
if (units[i].polymerElements.length > 0) {
@@ -45,6 +45,7 @@ export function PolymerIndexColorTheme(props: ColorThemeProps): ColorTheme {
}
return {
+ features: { structure: true, list: true },
granularity: 'instance',
color,
description: Description,
diff --git a/src/mol-theme/color/residue-name.ts b/src/mol-theme/color/residue-name.ts
index 02f2425fbc446cc9ca174ae743073b9b047c2501..756ef8c482458704ceaca1f097cfbe8f9fa9216a 100644
--- a/src/mol-theme/color/residue-name.ts
+++ b/src/mol-theme/color/residue-name.ts
@@ -105,6 +105,7 @@ export function ResidueNameColorTheme(props: ColorThemeProps): ColorTheme {
}
return {
+ features: {},
granularity: 'group',
color,
description: Description,
diff --git a/src/mol-theme/color/secondary-structure.ts b/src/mol-theme/color/secondary-structure.ts
index 55e76a3da44858ad6703322fc7956abfc38f3434..d9a6fd7b6e15518dd354c721417e7e1c73ca75b6 100644
--- a/src/mol-theme/color/secondary-structure.ts
+++ b/src/mol-theme/color/secondary-structure.ts
@@ -72,6 +72,7 @@ export function SecondaryStructureColorTheme(props: ColorThemeProps): ColorTheme
}
return {
+ features: {},
granularity: 'group',
color,
description: Description,
diff --git a/src/mol-theme/color/sequence-id.ts b/src/mol-theme/color/sequence-id.ts
index 7f68bf57e787716054a599e67c789c1214e5814e..808e4ace55c17a952ee46d6dd8fc14f8c68dd8e5 100644
--- a/src/mol-theme/color/sequence-id.ts
+++ b/src/mol-theme/color/sequence-id.ts
@@ -10,6 +10,7 @@ import { ColorScale, Color } from 'mol-util/color';
import { Location } from 'mol-model/location';
import { ColorThemeProps, ColorTheme } from '../color';
import { ColorOther } from 'mol-util/color/tables';
+import { defaults } from 'mol-util';
const DefaultColor = Color(0xCCCCCC)
const Description = 'Gives every polymer residue a color based on its `seq_id` value.'
@@ -57,7 +58,7 @@ function getSequenceLength(unit: Unit, element: ElementIndex) {
export function SequenceIdColorTheme(props: ColorThemeProps): ColorTheme {
const p = {
...props,
- colors: ColorOther.rainbow,
+ list: defaults(props.list, ColorOther.rainbow),
minLabel: 'Start',
maxLabel: 'End',
}
@@ -83,6 +84,7 @@ export function SequenceIdColorTheme(props: ColorThemeProps): ColorTheme {
}
return {
+ features: { list: true },
granularity: 'group',
color,
description: Description,
diff --git a/src/mol-theme/color/shape-group.ts b/src/mol-theme/color/shape-group.ts
index 6743791a3c58d823359eab0f6f8052c1bb8b55aa..0d74a08c77afa0c23f265036e0279daf2c1d76b5 100644
--- a/src/mol-theme/color/shape-group.ts
+++ b/src/mol-theme/color/shape-group.ts
@@ -13,6 +13,7 @@ const DefaultColor = Color(0xCCCCCC)
export function ShapeGroupColorTheme(props: ColorThemeProps): ColorTheme {
return {
+ features: {},
granularity: 'group',
color: (location: Location): Color => {
if (Shape.isLocation(location)) {
diff --git a/src/mol-theme/color/uniform.ts b/src/mol-theme/color/uniform.ts
index d9ab15c4db1cae6a21d6dd7b3376d3cd87817ce1..f7fb57769ecbdcfbdbe6a9ba6bda5507eedbd45f 100644
--- a/src/mol-theme/color/uniform.ts
+++ b/src/mol-theme/color/uniform.ts
@@ -14,6 +14,7 @@ export function UniformColorTheme(props: ColorThemeProps): ColorTheme {
const color = props.value || DefaultColor
return {
+ features: {},
granularity: 'uniform',
color: () => color,
description: Description,
diff --git a/src/mol-theme/color/unit-index.ts b/src/mol-theme/color/unit-index.ts
index 3e4fed18b986e43f85fa9c076d9d765695f73494..f41b29199a01f064b84b4c3155fd64b06da9c4cd 100644
--- a/src/mol-theme/color/unit-index.ts
+++ b/src/mol-theme/color/unit-index.ts
@@ -37,6 +37,7 @@ export function UnitIndexColorTheme(props: ColorThemeProps): ColorTheme {
}
return {
+ features: {},
granularity: 'instance',
color,
description: Description,
diff --git a/src/mol-util/color/color.ts b/src/mol-util/color/color.ts
index 1668282d9125336756abbd5b20296924472b2552..426c639b538118909cfc392688197f6db691020a 100644
--- a/src/mol-util/color/color.ts
+++ b/src/mol-util/color/color.ts
@@ -65,8 +65,8 @@ export namespace Color {
}
}
-type ColorTable<T extends { [k: string]: number[] }> = { [k in keyof T]: Color[] }
+export type ColorTable<T extends { [k: string]: number[] }> = { [k in keyof T]: Color[] }
export function ColorTable<T extends { [k: string]: number[] }>(o: T) { return o as ColorTable<T> }
-type ColorMap<T extends { [k: string]: number }> = { [k in keyof T]: Color }
+export type ColorMap<T extends { [k: string]: number }> = { [k in keyof T]: Color }
export function ColorMap<T extends { [k: string]: number }>(o: T) { return o as ColorMap<T> }
\ No newline at end of file
diff --git a/src/mol-util/color/index.ts b/src/mol-util/color/index.ts
index 2332d4a24ec9502444a54e46e15a1b546b412f49..33691a4115e086ca31cd68ca87f5ee7fdb129885 100644
--- a/src/mol-util/color/index.ts
+++ b/src/mol-util/color/index.ts
@@ -4,6 +4,5 @@
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
-export { Color, ColorMap, ColorTable } from './color'
-export { ColorScale } from './scale';
-export { ColorBrewer, ColorNames } from './tables'
\ No newline at end of file
+export { Color, ColorMap, ColorTable } from './color';
+export { ColorScale } from './scale';
\ No newline at end of file
diff --git a/src/mol-util/color/scale.ts b/src/mol-util/color/scale.ts
index e4bc9bb02e0efa3bd0f34b34dc4c6bf8b069d29d..c7cf7980c114e7b5363ede0cc7b80a1b176c0f5e 100644
--- a/src/mol-util/color/scale.ts
+++ b/src/mol-util/color/scale.ts
@@ -25,7 +25,7 @@ export interface ColorScale {
export const DefaultColorScale = {
domain: [0, 1],
reverse: false,
- colors: ColorBrewer.RdYlBu,
+ list: ColorBrewer.RdYlBu,
minLabel: '' as string | undefined,
maxLabel: '' as string | undefined,
}
@@ -33,8 +33,10 @@ export type ColorScaleProps = Partial<typeof DefaultColorScale>
export namespace ColorScale {
export function create(props: ColorScaleProps): ColorScale {
- const { domain, reverse, colors: _colors } = { ...DefaultColorScale, ...props }
- const colors = reverse ? _colors.slice().reverse() : _colors
+ // ensure that no undefined .list property exists so that the default assignment works
+ if (props.list === undefined) delete props.list
+ const { domain, reverse, list } = { ...DefaultColorScale, ...props }
+ const colors = reverse ? list.slice().reverse() : list
const count1 = colors.length - 1
let diff = 0, min = 0, max = 0