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/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-geo/geometry/geometry.ts b/src/mol-geo/geometry/geometry.ts index a1e1e221eb5315ced13742d3db3bb1199d44a1ed..42cef994a0120f6b5f47dc7fab7912a1c2c0aaf7 100644 --- a/src/mol-geo/geometry/geometry.ts +++ b/src/mol-geo/geometry/geometry.ts @@ -15,9 +15,8 @@ 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'; // @@ -67,7 +66,6 @@ export namespace Geometry { quality: SelectParam<VisualQuality>('Quality', '', 'auto', VisualQualityOptions), colorTheme: SelectParam<ColorThemeName>('Color Theme', '', 'uniform', ColorThemeOptions), 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-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..7ae464d9501497a8a2e1bd2fff2a7d47136d6a0b 100644 --- a/src/mol-repr/index.ts +++ b/src/mol-repr/index.ts @@ -10,18 +10,23 @@ 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'; // 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 +65,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 +103,15 @@ export namespace Representation { } } +// + +export interface VisualContext extends RepresentationContext { + runtime: RuntimeContext +} + 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/volume/direct-volume.ts b/src/mol-repr/volume/direct-volume.ts index 3f7c678496c7e95892c75645ff826bf59689cc87..ce412b099d4f6a811e62e9481cd05c2a1130a146 100644 --- a/src/mol-repr/volume/direct-volume.ts +++ b/src/mol-repr/volume/direct-volume.ts @@ -21,6 +21,7 @@ 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() @@ -170,13 +171,13 @@ export function createDirectVolume3d(ctx: RuntimeContext, webgl: WebGLContext, v // -export async function createDirectVolume(ctx: RuntimeContext, volume: VolumeData, props: DirectVolumeProps, directVolume?: DirectVolume) { - const { webgl } = props +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(ctx, webgl, volume, directVolume) : - await createDirectVolume2d(ctx, webgl, volume, directVolume) + await createDirectVolume3d(runtime, webgl, volume, directVolume) : + await createDirectVolume2d(runtime, webgl, volume, directVolume) } @@ -197,9 +198,9 @@ export function DirectVolumeVisual(): VolumeVisual<DirectVolumeProps> { mark: () => false, setUpdateState: (state: VisualUpdateState, newProps: DirectVolumeProps, currentProps: DirectVolumeProps) => { }, - createRenderObject: async (ctx: RuntimeContext, geometry: DirectVolume, locationIt: LocationIterator, props: DirectVolumeProps) => { + createRenderObject: async (ctx: VisualContext, geometry: DirectVolume, locationIt: LocationIterator, props: DirectVolumeProps) => { const transform = createIdentityTransform() - const values = await DirectVolume.createValues(ctx, geometry, transform, locationIt, props) + const values = await DirectVolume.createValues(ctx.runtime, geometry, transform, locationIt, props) const state = createRenderableState(props) return createDirectVolumeRenderObject(values, state) }, @@ -219,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 fb8be424e5cac658140a96b062d2d57f5977e802..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) @@ -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)