diff --git a/src/mol-canvas3d/helper/bounding-sphere-helper.ts b/src/mol-canvas3d/helper/bounding-sphere-helper.ts index 48562b323419199ab9e66b00c5871bc3da3253fb..6fc1a26c2c333b98b693375f70ee656e2355dca4 100644 --- a/src/mol-canvas3d/helper/bounding-sphere-helper.ts +++ b/src/mol-canvas3d/helper/bounding-sphere-helper.ts @@ -4,7 +4,7 @@ * @author Alexander Rose <alexander.rose@weirdbyte.de> */ -import { createMeshRenderObject, RenderObject } from 'mol-gl/render-object' +import { createRenderObject, RenderObject } from 'mol-gl/render-object' import { MeshBuilder } from 'mol-geo/geometry/mesh/mesh-builder'; import { addSphere } from 'mol-geo/geometry/mesh/builder/sphere'; import { Mesh } from 'mol-geo/geometry/mesh/mesh'; @@ -135,6 +135,6 @@ function createBoundingSphereMesh(boundingSphere: Sphere3D, mesh?: Mesh) { } function createBoundingSphereRenderObject(mesh: Mesh, color: Color, transform?: TransformData) { - const values = Mesh.createValuesSimple(mesh, { alpha: 0.1, doubleSided: false }, color, transform) - return createMeshRenderObject(values, { visible: true, pickable: false, opaque: false }) + const values = Mesh.Utils.createValuesSimple(mesh, { alpha: 0.1, doubleSided: false }, color, 1, transform) + return createRenderObject('mesh', values, { visible: true, pickable: false, opaque: false }) } \ No newline at end of file diff --git a/src/mol-geo/geometry/color-data.ts b/src/mol-geo/geometry/color-data.ts index 8cba01234c580d30a22e0034b60db439d73cb954..d244746fd63c3be891d0fcdcae38c66d50a848ea 100644 --- a/src/mol-geo/geometry/color-data.ts +++ b/src/mol-geo/geometry/color-data.ts @@ -11,7 +11,7 @@ import { Vec2, Vec3 } from 'mol-math/linear-algebra'; import { LocationIterator } from '../util/location-iterator'; import { NullLocation } from 'mol-model/location'; import { LocationColor, ColorTheme } from 'mol-theme/color'; -import { getGranularity } from './geometry'; +import { Geometry } from './geometry'; export type ColorType = 'uniform' | 'instance' | 'group' | 'groupInstance' @@ -23,7 +23,7 @@ export type ColorData = { } export function createColors(locationIt: LocationIterator, colorTheme: ColorTheme<any>, colorData?: ColorData): ColorData { - switch (getGranularity(locationIt, colorTheme.granularity)) { + switch (Geometry.getGranularity(locationIt, colorTheme.granularity)) { case 'uniform': return createUniformColor(locationIt, colorTheme.color, colorData) case 'group': return createGroupColor(locationIt, colorTheme.color, colorData) case 'groupInstance': return createGroupInstanceColor(locationIt, colorTheme.color, colorData) diff --git a/src/mol-geo/geometry/direct-volume/direct-volume.ts b/src/mol-geo/geometry/direct-volume/direct-volume.ts index 66472e954b4d4e69ed7ed9fca40193ba2c90e44e..b53ec053fcd6803e121fd3d8bae955cfb44b044a 100644 --- a/src/mol-geo/geometry/direct-volume/direct-volume.ts +++ b/src/mol-geo/geometry/direct-volume/direct-volume.ts @@ -16,12 +16,14 @@ import { LocationIterator } from 'mol-geo/util/location-iterator'; import { TransformData } from '../transform-data'; import { createColors } from '../color-data'; import { createMarkers } from '../marker-data'; -import { Geometry } from '../geometry'; +import { GeometryUtils } from '../geometry'; import { transformPositionArray } from 'mol-geo/util'; import { calculateBoundingSphere } from 'mol-gl/renderable/util'; import { Theme } from 'mol-theme/theme'; import { RenderableState } from 'mol-gl/renderable'; import { ColorListOptions, ColorListName } from 'mol-util/color/scale'; +import { Color } from 'mol-util/color'; +import { BaseGeometry } from '../base'; const VolumeBox = Box() const RenderModeOptions = [['isosurface', 'Isosurface'], ['volume', 'Volume']] as [string, string][] @@ -70,7 +72,7 @@ export namespace DirectVolume { } export const Params = { - ...Geometry.Params, + ...BaseGeometry.Params, isoValue: PD.Numeric(0.22, { min: -1, max: 1, step: 0.01 }), renderMode: PD.Select('volume', RenderModeOptions), controlPoints: PD.LineGraph([ @@ -81,7 +83,18 @@ export namespace DirectVolume { } export type Params = typeof Params - export function createValues(directVolume: DirectVolume, transform: TransformData, locationIt: LocationIterator, theme: Theme, props: PD.Values<Params>): DirectVolumeValues { + export const Utils: GeometryUtils<DirectVolume, Params> = { + Params, + createEmpty, + createValues, + createValuesSimple, + updateValues, + updateBoundingSphere, + createRenderableState, + updateRenderableState + } + + function createValues(directVolume: DirectVolume, transform: TransformData, locationIt: LocationIterator, theme: Theme, props: PD.Values<Params>): DirectVolumeValues { const { gridTexture, gridTextureDim } = directVolume const { bboxSize, bboxMin, bboxMax, gridDimension, transform: gridTransform } = directVolume @@ -102,7 +115,7 @@ export namespace DirectVolume { ...color, ...marker, ...transform, - ...Geometry.createValues(props, counts), + ...BaseGeometry.createValues(props, counts), aPosition: ValueCell.create(VolumeBox.vertices as Float32Array), elements: ValueCell.create(VolumeBox.indices as Uint32Array), @@ -125,7 +138,13 @@ export namespace DirectVolume { } } - export function updateValues(values: DirectVolumeValues, props: PD.Values<Params>) { + function createValuesSimple(directVolume: DirectVolume, props: Partial<PD.Values<Params>>, colorValue: Color, sizeValue: number, transform?: TransformData) { + const s = BaseGeometry.createSimple(colorValue, sizeValue, transform) + const p = { ...PD.getDefaultValues(Params), props } + return createValues(directVolume, s.transform, s.locationIterator, s.theme, p) + } + + function updateValues(values: DirectVolumeValues, props: PD.Values<Params>) { ValueCell.updateIfChanged(values.uIsoValue, props.isoValue) ValueCell.updateIfChanged(values.uAlpha, props.alpha) ValueCell.updateIfChanged(values.dUseFog, props.useFog) @@ -135,7 +154,7 @@ export namespace DirectVolume { createTransferFunctionTexture(controlPoints, props.list, values.tTransferTex) } - export function updateBoundingSphere(values: DirectVolumeValues, directVolume: DirectVolume) { + function updateBoundingSphere(values: DirectVolumeValues, directVolume: DirectVolume) { const { boundingSphere, invariantBoundingSphere } = getBoundingSphere(values.uGridDim.ref.value, values.uTransform.ref.value, values.aTransform.ref.value, values.instanceCount.ref.value) if (!Sphere3D.equals(boundingSphere, values.boundingSphere.ref.value)) { ValueCell.update(values.boundingSphere, boundingSphere) @@ -145,14 +164,14 @@ export namespace DirectVolume { } } - export function createRenderableState(props: PD.Values<Params>): RenderableState { - const state = Geometry.createRenderableState(props) + function createRenderableState(props: PD.Values<Params>): RenderableState { + const state = BaseGeometry.createRenderableState(props) state.opaque = false return state } - export function updateRenderableState(state: RenderableState, props: PD.Values<Params>) { - Geometry.updateRenderableState(state, props) + function updateRenderableState(state: RenderableState, props: PD.Values<Params>) { + BaseGeometry.updateRenderableState(state, props) state.opaque = false } } diff --git a/src/mol-geo/geometry/geometry.ts b/src/mol-geo/geometry/geometry.ts index 8b1a6b7d0735c892e3e54fac94c94e31cc71b2b6..e0df6e5420a5e1ea0411cee2ca4a21c8ac68b258 100644 --- a/src/mol-geo/geometry/geometry.ts +++ b/src/mol-geo/geometry/geometry.ts @@ -6,9 +6,8 @@ import { Mesh } from './mesh/mesh'; import { Points } from './points/points'; +import { Text } from './text/text'; import { RenderableState } from 'mol-gl/renderable'; -import { ValueCell } from 'mol-util'; -import { BaseValues } from 'mol-gl/renderable/schema'; import { LocationIterator } from '../util/location-iterator'; import { ColorType } from './color-data'; import { SizeType } from './size-data'; @@ -16,102 +15,84 @@ import { Lines } from './lines/lines'; import { ParamDefinition as PD } from 'mol-util/param-definition' import { DirectVolume } from './direct-volume/direct-volume'; import { Color } from 'mol-util/color'; -import { Vec3 } from 'mol-math/linear-algebra'; import { Spheres } from './spheres/spheres'; - -// - -export const VisualQualityInfo = { - 'custom': {}, - 'auto': {}, - 'highest': {}, - 'higher': {}, - 'high': {}, - 'medium': {}, - 'low': {}, - 'lower': {}, - 'lowest': {}, -} -export type VisualQuality = keyof typeof VisualQualityInfo -export const VisualQualityNames = Object.keys(VisualQualityInfo) -export const VisualQualityOptions = VisualQualityNames.map(n => [n, n] as [VisualQuality, string]) - -// +import { arrayMax } from 'mol-util/array'; +import { TransformData } from './transform-data'; +import { Theme } from 'mol-theme/theme'; +import { RenderObjectValuesType } from 'mol-gl/render-object'; export type GeometryKindType = { 'mesh': Mesh, 'points': Points, 'spheres': Spheres, + 'text': Text, 'lines': Lines, 'direct-volume': DirectVolume, } +export type GeometryKindParams = { + 'mesh': Mesh.Params, + 'points': Points.Params, + 'spheres': Spheres.Params, + 'text': Text.Params, + 'lines': Lines.Params, + 'direct-volume': DirectVolume.Params, +} export type GeometryKind = keyof GeometryKindType export type Geometry = Helpers.ValueOf<GeometryKindType> +export interface GeometryUtils<G extends Geometry, P extends PD.Params = GeometryKindParams[G['kind']], V = RenderObjectValuesType[G['kind']]> { + Params: P + createEmpty(geometry?: G): G + createValues(geometry: G, transform: TransformData, locationIt: LocationIterator, theme: Theme, props: PD.Values<P>): V + createValuesSimple(geometry: G, props: Partial<PD.Values<P>>, colorValue: Color, sizeValue: number, transform?: TransformData): V + updateValues(values: V, props: PD.Values<P>): void + updateBoundingSphere(values: V, geometry: G): void + createRenderableState(props: Partial<PD.Values<P>>): RenderableState + updateRenderableState(state: RenderableState, props: PD.Values<P>): void +} + export namespace Geometry { - export function getDrawCount(geometry: Geometry) { + export type Params<G extends Geometry> = GeometryKindParams[G['kind']] + + export function getDrawCount(geometry: Geometry): number { switch (geometry.kind) { case 'mesh': return geometry.triangleCount * 3 case 'points': return geometry.pointCount case 'spheres': return geometry.sphereCount * 2 * 3 + case 'text': return geometry.charCount * 2 * 3 case 'lines': return geometry.lineCount * 2 * 3 case 'direct-volume': return 12 * 3 } } - // - - export const Params = { - alpha: PD.Numeric(1, { min: 0, max: 1, step: 0.01 }, { label: 'Opacity' }), - useFog: PD.Boolean(true), - highlightColor: PD.Color(Color.fromNormalizedRgb(1.0, 0.4, 0.6)), - selectColor: PD.Color(Color.fromNormalizedRgb(0.2, 1.0, 0.1)), - - quality: PD.Select<VisualQuality>('auto', VisualQualityOptions), - } - export type Params = typeof Params - - export type Counts = { drawCount: number, groupCount: number, instanceCount: number } - - export function createValues(props: PD.Values<Params>, counts: Counts) { - return { - uAlpha: ValueCell.create(props.alpha), - uHighlightColor: ValueCell.create(Color.toArrayNormalized(props.highlightColor, Vec3.zero(), 0)), - uSelectColor: ValueCell.create(Color.toArrayNormalized(props.selectColor, Vec3.zero(), 0)), - uGroupCount: ValueCell.create(counts.groupCount), - drawCount: ValueCell.create(counts.drawCount), - dUseFog: ValueCell.create(props.useFog), - } - } - - export function updateValues(values: BaseValues, props: PD.Values<Params>) { - if (Color.fromNormalizedArray(values.uHighlightColor.ref.value, 0) !== props.highlightColor) { - ValueCell.update(values.uHighlightColor, Color.toArrayNormalized(props.highlightColor, values.uHighlightColor.ref.value, 0)) - } - if (Color.fromNormalizedArray(values.uSelectColor.ref.value, 0) !== props.selectColor) { - ValueCell.update(values.uSelectColor, Color.toArrayNormalized(props.selectColor, values.uSelectColor.ref.value, 0)) + export function getGroupCount(geometry: Geometry): number { + switch (geometry.kind) { + case 'mesh': + case 'points': + case 'spheres': + case 'text': + case 'lines': + return arrayMax(geometry.groupBuffer.ref.value) + 1 + case 'direct-volume': + return 1 } - ValueCell.updateIfChanged(values.uAlpha, props.alpha) - ValueCell.updateIfChanged(values.dUseFog, props.useFog) } - export function createRenderableState(props: Partial<PD.Values<Params>> = {}): RenderableState { - return { - visible: true, - pickable: true, - opaque: props.alpha === undefined ? true : props.alpha === 1 + export function getUtils<K extends GeometryKind>(kind: K): GeometryUtils<GeometryKindType[K]> { + switch (kind) { + case 'mesh': return Mesh.Utils + case 'points': return Points.Utils + case 'spheres': return Spheres.Utils + case 'text': return Text.Utils + case 'lines': return Lines.Utils + case 'direct-volume': return DirectVolume.Utils } + throw new Error('unknown geometry kind') } - export function updateRenderableState(state: RenderableState, props: PD.Values<Params>) { - state.opaque = props.alpha === 1 + export function getGranularity(locationIt: LocationIterator, granularity: ColorType | SizeType) { + // Always use 'group' granularity for 'complex' location iterators, + // i.e. for which an instance may include multiple units + return granularity === 'instance' && locationIt.isComplex ? 'group' : granularity } -} - -// - -export function getGranularity(locationIt: LocationIterator, granularity: ColorType | SizeType) { - // Always use 'group' granularity for 'complex' location iterators, - // i.e. for which an instance may include multiple units - return granularity === 'instance' && locationIt.isComplex ? 'group' : granularity } \ No newline at end of file diff --git a/src/mol-geo/geometry/lines/lines.ts b/src/mol-geo/geometry/lines/lines.ts index 2ba76bd83541ebd8bf1bbc7fba472ecf179070d4..8c5fa075d314453458ea22ee3b4ddfdf3c396929 100644 --- a/src/mol-geo/geometry/lines/lines.ts +++ b/src/mol-geo/geometry/lines/lines.ts @@ -7,7 +7,7 @@ import { ValueCell } from 'mol-util' import { Mat4 } from 'mol-math/linear-algebra' import { transformPositionArray/* , transformDirectionArray, getNormalMatrix */ } from '../../util'; -import { Geometry } from '../geometry'; +import { GeometryUtils } from '../geometry'; import { createColors } from '../color-data'; import { createMarkers } from '../marker-data'; import { createSizes } from '../size-data'; @@ -20,6 +20,8 @@ import { ParamDefinition as PD } from 'mol-util/param-definition'; import { calculateBoundingSphere } from 'mol-gl/renderable/util'; import { Sphere3D } from 'mol-math/geometry'; import { Theme } from 'mol-theme/theme'; +import { Color } from 'mol-util/color'; +import { BaseGeometry } from '../base'; /** Wide line */ export interface Lines { @@ -93,13 +95,24 @@ export namespace Lines { // export const Params = { - ...Geometry.Params, + ...BaseGeometry.Params, sizeFactor: PD.Numeric(1, { min: 0, max: 10, step: 0.1 }), lineSizeAttenuation: PD.Boolean(false), } export type Params = typeof Params - export function createValues(lines: Lines, transform: TransformData, locationIt: LocationIterator, theme: Theme, props: PD.Values<Params>): LinesValues { + export const Utils: GeometryUtils<Lines, Params> = { + Params, + createEmpty, + createValues, + createValuesSimple, + updateValues, + updateBoundingSphere, + createRenderableState: BaseGeometry.createRenderableState, + updateRenderableState: BaseGeometry.updateRenderableState + } + + function createValues(lines: Lines, transform: TransformData, locationIt: LocationIterator, theme: Theme, props: PD.Values<Params>): LinesValues { const { instanceCount, groupCount } = locationIt const color = createColors(locationIt, theme.color) const size = createSizes(locationIt, theme.size) @@ -123,7 +136,7 @@ export namespace Lines { ...marker, ...transform, - ...Geometry.createValues(props, counts), + ...BaseGeometry.createValues(props, counts), uSizeFactor: ValueCell.create(props.sizeFactor), dLineSizeAttenuation: ValueCell.create(props.lineSizeAttenuation), dDoubleSided: ValueCell.create(true), @@ -131,13 +144,19 @@ export namespace Lines { } } - export function updateValues(values: LinesValues, props: PD.Values<Params>) { - Geometry.updateValues(values, props) + function createValuesSimple(lines: Lines, props: Partial<PD.Values<Params>>, colorValue: Color, sizeValue: number, transform?: TransformData) { + const s = BaseGeometry.createSimple(colorValue, sizeValue, transform) + const p = { ...PD.getDefaultValues(Params), props } + return createValues(lines, s.transform, s.locationIterator, s.theme, p) + } + + function updateValues(values: LinesValues, props: PD.Values<Params>) { + BaseGeometry.updateValues(values, props) ValueCell.updateIfChanged(values.uSizeFactor, props.sizeFactor) ValueCell.updateIfChanged(values.dLineSizeAttenuation, props.lineSizeAttenuation) } - export function updateBoundingSphere(values: LinesValues, lines: Lines) { + function updateBoundingSphere(values: LinesValues, lines: Lines) { const { boundingSphere, invariantBoundingSphere } = getBoundingSphere(values.aStart.ref.value, values.aEnd.ref.value, lines.lineCount, values.aTransform.ref.value, values.instanceCount.ref.value) if (!Sphere3D.equals(boundingSphere, values.boundingSphere.ref.value)) { diff --git a/src/mol-geo/geometry/mesh/mesh.ts b/src/mol-geo/geometry/mesh/mesh.ts index 6f4956b4e1e278e0533abe86e49fc3514c7cd802..73bbb81451013c3c1123807a3fe94d1208ab2c01 100644 --- a/src/mol-geo/geometry/mesh/mesh.ts +++ b/src/mol-geo/geometry/mesh/mesh.ts @@ -9,17 +9,18 @@ import { ValueCell } from 'mol-util' import { Vec3, Mat4 } from 'mol-math/linear-algebra' import { Sphere3D } from 'mol-math/geometry' import { transformPositionArray/* , transformDirectionArray, getNormalMatrix */ } from '../../util'; -import { Geometry } from '../geometry'; +import { GeometryUtils } from '../geometry'; import { createMarkers } from '../marker-data'; -import { TransformData, createIdentityTransform } from '../transform-data'; +import { TransformData } from '../transform-data'; import { LocationIterator } from '../../util/location-iterator'; -import { createColors, createValueColor } from '../color-data'; +import { createColors } from '../color-data'; import { ChunkedArray } from 'mol-data/util'; import { ParamDefinition as PD } from 'mol-util/param-definition'; import { calculateBoundingSphere } from 'mol-gl/renderable/util'; import { Theme } from 'mol-theme/theme'; import { MeshValues } from 'mol-gl/renderable/mesh'; -import { ColorNames } from 'mol-util/color/tables'; +import { Color } from 'mol-util/color'; +import { BaseGeometry } from '../base'; export interface Mesh { readonly kind: 'mesh', @@ -341,14 +342,25 @@ export namespace Mesh { // export const Params = { - ...Geometry.Params, + ...BaseGeometry.Params, doubleSided: PD.Boolean(false), flipSided: PD.Boolean(false), flatShaded: PD.Boolean(false), } export type Params = typeof Params - export function createValues(mesh: Mesh, transform: TransformData, locationIt: LocationIterator, theme: Theme, props: PD.Values<Params>): MeshValues { + export const Utils: GeometryUtils<Mesh, Params> = { + Params, + createEmpty, + createValues, + createValuesSimple, + updateValues, + updateBoundingSphere, + createRenderableState: BaseGeometry.createRenderableState, + updateRenderableState: BaseGeometry.updateRenderableState + } + + function createValues(mesh: Mesh, transform: TransformData, locationIt: LocationIterator, theme: Theme, props: PD.Values<Params>): MeshValues { const { instanceCount, groupCount } = locationIt if (instanceCount !== transform.instanceCount.ref.value) { throw new Error('instanceCount values in TransformData and LocationIterator differ') @@ -375,54 +387,27 @@ export namespace Mesh { ...marker, ...transform, - ...Geometry.createValues(props, counts), + ...BaseGeometry.createValues(props, counts), dDoubleSided: ValueCell.create(props.doubleSided), dFlatShaded: ValueCell.create(props.flatShaded), dFlipSided: ValueCell.create(props.flipSided), } } - export function createValuesSimple(mesh: Mesh, props: Partial<PD.Values<Params>>, colorValue = ColorNames.grey, transform?: TransformData): MeshValues { - const p = { ...PD.getDefaultValues(Params), ...props } - if (!transform) transform = createIdentityTransform() - const instanceCount = transform.instanceCount.ref.value - const groupCount = 1 - const color = createValueColor(colorValue) - const marker = createMarkers(instanceCount * groupCount) - - const counts = { drawCount: mesh.triangleCount * 3, groupCount, instanceCount } - - const { boundingSphere, invariantBoundingSphere } = calculateBoundingSphere( - mesh.vertexBuffer.ref.value, mesh.vertexCount, - transform.aTransform.ref.value, instanceCount - ) - - return { - aPosition: mesh.vertexBuffer, - aNormal: mesh.normalBuffer, - aGroup: mesh.groupBuffer, - elements: mesh.indexBuffer, - boundingSphere: ValueCell.create(boundingSphere), - invariantBoundingSphere: ValueCell.create(invariantBoundingSphere), - ...color, - ...marker, - ...transform, - - ...Geometry.createValues(p, counts), - dDoubleSided: ValueCell.create(p.doubleSided), - dFlatShaded: ValueCell.create(p.flatShaded), - dFlipSided: ValueCell.create(p.flipSided), - } + function createValuesSimple(mesh: Mesh, props: Partial<PD.Values<Params>>, colorValue: Color, sizeValue: number, transform?: TransformData) { + const s = BaseGeometry.createSimple(colorValue, sizeValue, transform) + const p = { ...PD.getDefaultValues(Params), props } + return createValues(mesh, s.transform, s.locationIterator, s.theme, p) } - export function updateValues(values: MeshValues, props: PD.Values<Params>) { - Geometry.updateValues(values, props) + function updateValues(values: MeshValues, props: PD.Values<Params>) { + BaseGeometry.updateValues(values, props) ValueCell.updateIfChanged(values.dDoubleSided, props.doubleSided) ValueCell.updateIfChanged(values.dFlatShaded, props.flatShaded) ValueCell.updateIfChanged(values.dFlipSided, props.flipSided) } - export function updateBoundingSphere(values: MeshValues, mesh: Mesh) { + function updateBoundingSphere(values: MeshValues, mesh: Mesh) { const { boundingSphere, invariantBoundingSphere } = calculateBoundingSphere( values.aPosition.ref.value, mesh.vertexCount, values.aTransform.ref.value, values.instanceCount.ref.value diff --git a/src/mol-geo/geometry/points/points.ts b/src/mol-geo/geometry/points/points.ts index d4cdc622604f3b8c6e6657f22d09ca758468bd9e..7818a17a052588038bd2da1587c60a5a2baa0c4c 100644 --- a/src/mol-geo/geometry/points/points.ts +++ b/src/mol-geo/geometry/points/points.ts @@ -7,7 +7,7 @@ import { ValueCell } from 'mol-util' import { Mat4 } from 'mol-math/linear-algebra' import { transformPositionArray/* , transformDirectionArray, getNormalMatrix */ } from '../../util'; -import { Geometry } from '../geometry'; +import { GeometryUtils } from '../geometry'; import { createColors } from '../color-data'; import { createMarkers } from '../marker-data'; import { createSizes } from '../size-data'; @@ -19,6 +19,8 @@ import { Sphere3D } from 'mol-math/geometry'; import { Theme } from 'mol-theme/theme'; import { PointsValues } from 'mol-gl/renderable/points'; import { RenderableState } from 'mol-gl/renderable'; +import { Color } from 'mol-util/color'; +import { BaseGeometry } from '../base'; /** Point cloud */ export interface Points { @@ -56,7 +58,7 @@ export namespace Points { // export const Params = { - ...Geometry.Params, + ...BaseGeometry.Params, sizeFactor: PD.Numeric(1, { min: 0, max: 10, step: 0.1 }), pointSizeAttenuation: PD.Boolean(false), pointFilledCircle: PD.Boolean(false), @@ -64,7 +66,18 @@ export namespace Points { } export type Params = typeof Params - export function createValues(points: Points, transform: TransformData, locationIt: LocationIterator, theme: Theme, props: PD.Values<Params>): PointsValues { + export const Utils: GeometryUtils<Points, Params> = { + Params, + createEmpty, + createValues, + createValuesSimple, + updateValues, + updateBoundingSphere, + createRenderableState, + updateRenderableState + } + + function createValues(points: Points, transform: TransformData, locationIt: LocationIterator, theme: Theme, props: PD.Values<Params>): PointsValues { const { instanceCount, groupCount } = locationIt const color = createColors(locationIt, theme.color) const size = createSizes(locationIt, theme.size) @@ -87,7 +100,7 @@ export namespace Points { ...marker, ...transform, - ...Geometry.createValues(props, counts), + ...BaseGeometry.createValues(props, counts), uSizeFactor: ValueCell.create(props.sizeFactor), dPointSizeAttenuation: ValueCell.create(props.pointSizeAttenuation), dPointFilledCircle: ValueCell.create(props.pointFilledCircle), @@ -95,15 +108,21 @@ export namespace Points { } } - export function updateValues(values: PointsValues, props: PD.Values<Params>) { - Geometry.updateValues(values, props) + function createValuesSimple(points: Points, props: Partial<PD.Values<Params>>, colorValue: Color, sizeValue: number, transform?: TransformData) { + const s = BaseGeometry.createSimple(colorValue, sizeValue, transform) + const p = { ...PD.getDefaultValues(Params), props } + return createValues(points, s.transform, s.locationIterator, s.theme, p) + } + + function updateValues(values: PointsValues, props: PD.Values<Params>) { + BaseGeometry.updateValues(values, props) ValueCell.updateIfChanged(values.uSizeFactor, props.sizeFactor) ValueCell.updateIfChanged(values.dPointSizeAttenuation, props.pointSizeAttenuation) ValueCell.updateIfChanged(values.dPointFilledCircle, props.pointFilledCircle) ValueCell.updateIfChanged(values.uPointEdgeBleach, props.pointEdgeBleach) } - export function updateBoundingSphere(values: PointsValues, points: Points) { + function updateBoundingSphere(values: PointsValues, points: Points) { const { boundingSphere, invariantBoundingSphere } = calculateBoundingSphere( values.aPosition.ref.value, points.pointCount, values.aTransform.ref.value, values.instanceCount.ref.value @@ -116,14 +135,14 @@ export namespace Points { } } - export function createRenderableState(props: PD.Values<Params>): RenderableState { - const state = Geometry.createRenderableState(props) + function createRenderableState(props: PD.Values<Params>): RenderableState { + const state = BaseGeometry.createRenderableState(props) updateRenderableState(state, props) return state } - export function updateRenderableState(state: RenderableState, props: PD.Values<Params>) { - Geometry.updateRenderableState(state, props) + function updateRenderableState(state: RenderableState, props: PD.Values<Params>) { + BaseGeometry.updateRenderableState(state, props) state.opaque = state.opaque && ( !props.pointFilledCircle || (props.pointFilledCircle && props.pointEdgeBleach === 0) diff --git a/src/mol-geo/geometry/size-data.ts b/src/mol-geo/geometry/size-data.ts index f0c4d8e7c597f1a181cfc5ca1737b62a6b9840c0..9c68b5559fe4baca93cc862bcb805bc263ff9054 100644 --- a/src/mol-geo/geometry/size-data.ts +++ b/src/mol-geo/geometry/size-data.ts @@ -10,7 +10,7 @@ import { TextureImage, createTextureImage } from 'mol-gl/renderable/util'; import { LocationIterator } from '../util/location-iterator'; import { Location, NullLocation } from 'mol-model/location'; import { SizeTheme } from 'mol-theme/size'; -import { getGranularity } from './geometry'; +import { Geometry } from './geometry'; import { encodeFloatLog } from 'mol-util/float-packing'; export type SizeType = 'uniform' | 'instance' | 'group' | 'groupInstance' @@ -23,7 +23,7 @@ export type SizeData = { } export function createSizes(locationIt: LocationIterator, sizeTheme: SizeTheme<any>, sizeData?: SizeData): SizeData { - switch (getGranularity(locationIt, sizeTheme.granularity)) { + switch (Geometry.getGranularity(locationIt, sizeTheme.granularity)) { case 'uniform': return createUniformSize(locationIt, sizeTheme.size, sizeData) case 'group': return createGroupSize(locationIt, sizeTheme.size, sizeData) case 'groupInstance': return createGroupInstanceSize(locationIt, sizeTheme.size, sizeData) diff --git a/src/mol-geo/geometry/spheres/spheres.ts b/src/mol-geo/geometry/spheres/spheres.ts index 84c79a72d2c75702eb278c815d08c4d238b273e3..bd90b3cc1cc29acbe0c5eca439c43efae9285568 100644 --- a/src/mol-geo/geometry/spheres/spheres.ts +++ b/src/mol-geo/geometry/spheres/spheres.ts @@ -5,21 +5,19 @@ */ import { ValueCell } from 'mol-util'; -import { Geometry } from '../geometry'; +import { GeometryUtils } from '../geometry'; import { ParamDefinition as PD } from 'mol-util/param-definition'; -import { TransformData, createIdentityTransform } from '../transform-data'; +import { TransformData } from '../transform-data'; import { LocationIterator } from 'mol-geo/util/location-iterator'; import { Theme } from 'mol-theme/theme'; import { SpheresValues } from 'mol-gl/renderable/spheres'; import { createColors } from '../color-data'; import { createMarkers } from '../marker-data'; import { calculateBoundingSphere } from 'mol-gl/renderable/util'; -import { ColorNames } from 'mol-util/color/tables'; import { Sphere3D } from 'mol-math/geometry'; import { createSizes, getMaxSize } from '../size-data'; -import { NullLocation } from 'mol-model/location'; -import { UniformColorTheme } from 'mol-theme/color/uniform'; -import { UniformSizeTheme } from 'mol-theme/size/uniform'; +import { Color } from 'mol-util/color'; +import { BaseGeometry } from '../base'; /** Spheres */ export interface Spheres { @@ -55,13 +53,24 @@ export namespace Spheres { } export const Params = { - ...Geometry.Params, + ...BaseGeometry.Params, sizeFactor: PD.Numeric(1, { min: 0, max: 10, step: 0.1 }), doubleSided: PD.Boolean(false), } export type Params = typeof Params - export function createValues(spheres: Spheres, transform: TransformData, locationIt: LocationIterator, theme: Theme, props: PD.Values<Params>): SpheresValues { + export const Utils: GeometryUtils<Spheres, Params> = { + Params, + createEmpty, + createValues, + createValuesSimple, + updateValues, + updateBoundingSphere, + createRenderableState: BaseGeometry.createRenderableState, + updateRenderableState: BaseGeometry.updateRenderableState + } + + function createValues(spheres: Spheres, transform: TransformData, locationIt: LocationIterator, theme: Theme, props: PD.Values<Params>): SpheresValues { const { instanceCount, groupCount } = locationIt if (instanceCount !== transform.instanceCount.ref.value) { throw new Error('instanceCount values in TransformData and LocationIterator differ') @@ -93,32 +102,25 @@ export namespace Spheres { padding: ValueCell.create(padding), - ...Geometry.createValues(props, counts), + ...BaseGeometry.createValues(props, counts), uSizeFactor: ValueCell.create(props.sizeFactor), dDoubleSided: ValueCell.create(props.doubleSided), } } - export function createValuesSimple(spheres: Spheres, props: Partial<PD.Values<Params>>, colorValue = ColorNames.grey, sizeValue = 1, transform?: TransformData): SpheresValues { - - if (!transform) transform = createIdentityTransform() - const locationIterator = LocationIterator(1, transform.instanceCount.ref.value, () => NullLocation, false, () => false) - const theme: Theme = { - color: UniformColorTheme({}, { value: colorValue}), - size: UniformSizeTheme({}, { value: sizeValue}) - } - const p = { ...PD.getDefaultValues(Params), ...props } - - return createValues(spheres, transform, locationIterator, theme, p) + function createValuesSimple(spheres: Spheres, props: Partial<PD.Values<Params>>, colorValue: Color, sizeValue: number, transform?: TransformData) { + const s = BaseGeometry.createSimple(colorValue, sizeValue, transform) + const p = { ...PD.getDefaultValues(Params), props } + return createValues(spheres, s.transform, s.locationIterator, s.theme, p) } - export function updateValues(values: SpheresValues, props: PD.Values<Params>) { - Geometry.updateValues(values, props) + function updateValues(values: SpheresValues, props: PD.Values<Params>) { + BaseGeometry.updateValues(values, props) ValueCell.updateIfChanged(values.uSizeFactor, props.sizeFactor) ValueCell.updateIfChanged(values.dDoubleSided, props.doubleSided) } - export function updateBoundingSphere(values: SpheresValues, spheres: Spheres) { + function updateBoundingSphere(values: SpheresValues, spheres: Spheres) { const padding = getMaxSize(values) const { boundingSphere, invariantBoundingSphere } = calculateBoundingSphere( values.aPosition.ref.value, spheres.sphereCount * 4, diff --git a/src/mol-geo/geometry/text/text.ts b/src/mol-geo/geometry/text/text.ts index bdc31447af7e4b5fb06ae7ee36060d5deb923b31..3d1fd7ff81d6d1b3b1383c97689a01042c05691d 100644 --- a/src/mol-geo/geometry/text/text.ts +++ b/src/mol-geo/geometry/text/text.ts @@ -6,17 +6,14 @@ import { ParamDefinition as PD } from 'mol-util/param-definition'; import { ValueCell } from 'mol-util'; -import { Geometry } from '../geometry'; +import { GeometryUtils } from '../geometry'; import { LocationIterator } from 'mol-geo/util/location-iterator'; -import { TransformData, createIdentityTransform } from '../transform-data'; +import { TransformData } from '../transform-data'; import { Theme } from 'mol-theme/theme'; import { createColors } from '../color-data'; import { createSizes, getMaxSize } from '../size-data'; import { createMarkers } from '../marker-data'; import { ColorNames } from 'mol-util/color/tables'; -import { NullLocation } from 'mol-model/location'; -import { UniformColorTheme } from 'mol-theme/color/uniform'; -import { UniformSizeTheme } from 'mol-theme/size/uniform'; import { Sphere3D } from 'mol-math/geometry'; import { calculateBoundingSphere, TextureImage, createTextureImage } from 'mol-gl/renderable/util'; import { TextValues } from 'mol-gl/renderable/text'; @@ -25,6 +22,8 @@ import { Vec3 } from 'mol-math/linear-algebra'; import { FontAtlasParams } from './font-atlas'; import { RenderableState } from 'mol-gl/renderable'; import { clamp } from 'mol-math/interpolate'; +import { createRenderObject as _createRenderObject } from 'mol-gl/render-object'; +import { BaseGeometry } from '../base'; type TextAttachment = 'bottom-left' | 'bottom-center' | 'bottom-right' | 'middle-left' | 'middle-center' | 'middle-right' | 'top-left' | 'top-center' | 'top-right' @@ -70,7 +69,7 @@ export namespace Text { } export const Params = { - ...Geometry.Params, + ...BaseGeometry.Params, ...FontAtlasParams, sizeFactor: PD.Numeric(1, { min: 0, max: 10, step: 0.1 }), @@ -88,7 +87,19 @@ export namespace Text { } export type Params = typeof Params - export function createValues(text: Text, transform: TransformData, locationIt: LocationIterator, theme: Theme, props: PD.Values<Params>): TextValues { + export const Utils: GeometryUtils<Text, Params> = { + Params, + createEmpty, + createValues, + createValuesSimple, + updateValues, + updateBoundingSphere, + createRenderableState, + updateRenderableState, + // createRenderObject + } + + function createValues(text: Text, transform: TransformData, locationIt: LocationIterator, theme: Theme, props: PD.Values<Params>): TextValues { const { instanceCount, groupCount } = locationIt if (instanceCount !== transform.instanceCount.ref.value) { throw new Error('instanceCount values in TransformData and LocationIterator differ') @@ -122,7 +133,7 @@ export namespace Text { tFont: text.fontTexture, padding: ValueCell.create(padding), - ...Geometry.createValues(props, counts), + ...BaseGeometry.createValues(props, counts), uSizeFactor: ValueCell.create(props.sizeFactor), uBorderWidth: ValueCell.create(clamp(props.borderWidth / 2, 0, 0.5)), @@ -135,25 +146,18 @@ export namespace Text { } } - export function createValuesSimple(text: Text, props: Partial<PD.Values<Params>>, colorValue = ColorNames.grey, sizeValue = 1, transform?: TransformData): TextValues { - - if (!transform) transform = createIdentityTransform() - const locationIterator = LocationIterator(1, transform.instanceCount.ref.value, () => NullLocation, false, () => false) - const theme: Theme = { - color: UniformColorTheme({}, { value: colorValue}), - size: UniformSizeTheme({}, { value: sizeValue}) - } - const p = { ...PD.getDefaultValues(Params), ...props } - - return createValues(text, transform, locationIterator, theme, p) + function createValuesSimple(text: Text, props: Partial<PD.Values<Params>>, colorValue: Color, sizeValue: number, transform?: TransformData) { + const s = BaseGeometry.createSimple(colorValue, sizeValue, transform) + const p = { ...PD.getDefaultValues(Params), props } + return createValues(text, s.transform, s.locationIterator, s.theme, p) } - export function updateValues(values: TextValues, props: PD.Values<Params>) { - Geometry.updateValues(values, props) + function updateValues(values: TextValues, props: PD.Values<Params>) { + BaseGeometry.updateValues(values, props) ValueCell.updateIfChanged(values.uSizeFactor, props.sizeFactor) } - export function updateBoundingSphere(values: TextValues, text: Text) { + function updateBoundingSphere(values: TextValues, text: Text) { const padding = getMaxSize(values) const { boundingSphere, invariantBoundingSphere } = calculateBoundingSphere( values.aPosition.ref.value, text.charCount * 4, @@ -167,14 +171,18 @@ export namespace Text { } } - export function createRenderableState(props: PD.Values<Params>): RenderableState { - const state = Geometry.createRenderableState(props) + function createRenderableState(props: PD.Values<Params>): RenderableState { + const state = BaseGeometry.createRenderableState(props) updateRenderableState(state, props) return state } - export function updateRenderableState(state: RenderableState, props: PD.Values<Params>) { - Geometry.updateRenderableState(state, props) + function updateRenderableState(state: RenderableState, props: PD.Values<Params>) { + BaseGeometry.updateRenderableState(state, props) state.opaque = false } + + // function createRenderObject(values: TextValues, state: RenderableState) { + // return _createRenderObject('text', values, state) + // } } \ No newline at end of file diff --git a/src/mol-gl/_spec/renderer.spec.ts b/src/mol-gl/_spec/renderer.spec.ts index 0b74164e775b9fe394d5a3a67658d7bb76aec85a..10b09294ee8f53f87e578860883b2802d1a9871d 100644 --- a/src/mol-gl/_spec/renderer.spec.ts +++ b/src/mol-gl/_spec/renderer.spec.ts @@ -15,7 +15,7 @@ import { createValueColor } from 'mol-geo/geometry/color-data'; import { createValueSize } from 'mol-geo/geometry/size-data'; import { createContext } from '../webgl/context'; import { RenderableState } from '../renderable'; -import { createPointsRenderObject } from '../render-object'; +import { createRenderObject } from '../render-object'; import { PointsValues } from '../renderable/points'; import Scene from '../scene'; import { createEmptyMarkers } from 'mol-geo/geometry/marker-data'; @@ -94,7 +94,7 @@ function createPoints() { opaque: true } - return createPointsRenderObject(values, state) + return createRenderObject('points', values, state) } describe('renderer', () => { diff --git a/src/mol-gl/render-object.ts b/src/mol-gl/render-object.ts index 19c05d0e7410b1b198c7f6a8ba7cc9f6792dd8b1..57ad487070e0ec547dc07fe982808eecab3690ae 100644 --- a/src/mol-gl/render-object.ts +++ b/src/mol-gl/render-object.ts @@ -36,29 +36,32 @@ export type ComputeRenderObject = GaussianDensityRenderObject export type RenderObject = GraphicsRenderObject | ComputeRenderObject -// +export type RenderObjectKindType = { + 'mesh': MeshRenderObject + 'points': PointsRenderObject + 'spheres': SpheresRenderObject + 'text': TextRenderObject + 'lines': LinesRenderObject + 'direct-volume': DirectVolumeRenderObject -export function createMeshRenderObject(values: MeshValues, state: RenderableState): MeshRenderObject { - return { id: getNextId(), type: 'mesh', values, state } -} -export function createPointsRenderObject(values: PointsValues, state: RenderableState): PointsRenderObject { - return { id: getNextId(), type: 'points', values, state } -} -export function createSpheresRenderObject(values: SpheresValues, state: RenderableState): SpheresRenderObject { - return { id: getNextId(), type: 'spheres', values, state } -} -export function createTextRenderObject(values: TextValues, state: RenderableState): TextRenderObject { - return { id: getNextId(), type: 'text', values, state } + 'gaussian-density': GaussianDensityRenderObject } -export function createLinesRenderObject(values: LinesValues, state: RenderableState): LinesRenderObject { - return { id: getNextId(), type: 'lines', values, state } -} -export function createDirectVolumeRenderObject(values: DirectVolumeValues, state: RenderableState): DirectVolumeRenderObject { - return { id: getNextId(), type: 'direct-volume', values, state } +export type RenderObjectValuesType = { + 'mesh': MeshValues + 'points': PointsValues + 'spheres': SpheresValues + 'text': TextValues + 'lines': LinesValues + 'direct-volume': DirectVolumeValues + + 'gaussian-density': GaussianDensityValues } +export type RenderObjectType = keyof RenderObjectKindType + +// -export function createGaussianDensityRenderObject(values: GaussianDensityValues, state: RenderableState): GaussianDensityRenderObject { - return { id: getNextId(), type: 'gaussian-density', values, state } +export function createRenderObject<T extends RenderObjectType>(type: T, values: RenderObjectValuesType[T], state: RenderableState): RenderObjectKindType[T] { + return { id: getNextId(), type, values, state } as RenderObjectKindType[T] } export function createRenderable(ctx: WebGLContext, o: RenderObject): Renderable<any> { diff --git a/src/mol-math/geometry/gaussian-density/gpu.ts b/src/mol-math/geometry/gaussian-density/gpu.ts index fd087282e22a55608965bab8c3160d0914802728..17dfac6f8a379d6729d6a251b46eec0982bdef34 100644 --- a/src/mol-math/geometry/gaussian-density/gpu.ts +++ b/src/mol-math/geometry/gaussian-density/gpu.ts @@ -14,7 +14,7 @@ import { Vec3, Tensor, Mat4 } from '../../linear-algebra' import { GaussianDensityValues } from 'mol-gl/renderable/gaussian-density' import { ValueCell } from 'mol-util' import { RenderableState, Renderable } from 'mol-gl/renderable' -import { createRenderable, createGaussianDensityRenderObject } from 'mol-gl/render-object' +import { createRenderable, createRenderObject } from 'mol-gl/render-object' import { WebGLContext } from 'mol-gl/webgl/context'; import { createTexture, Texture } from 'mol-gl/webgl/texture'; import { GLRenderingContext } from 'mol-gl/webgl/compat'; @@ -236,7 +236,7 @@ function getGaussianDensityRenderObject(webgl: WebGLContext, drawCount: number, opaque: true } - const renderObject = createGaussianDensityRenderObject(values, state) + const renderObject = createRenderObject('gaussian-density', values, state) return renderObject } diff --git a/src/mol-model/loci.ts b/src/mol-model/loci.ts index 9dac68c638f89e96aa01f7d1cea82a5d8167d186..34bb4d4e6fa78f9b3b2b0796147c41f26253dd7d 100644 --- a/src/mol-model/loci.ts +++ b/src/mol-model/loci.ts @@ -27,6 +27,7 @@ export function isEmptyLoci(x: any): x is EmptyLoci { return !!x && x.kind === 'empty-loci'; } +/** A generic data loci */ export interface DataLoci { readonly kind: 'data-loci', readonly data: any, @@ -71,12 +72,14 @@ namespace Loci { const sphereHelper = new CentroidHelper(), tempPos = Vec3.zero(); - export function getBoundingSphere(loci: Loci): Sphere3D | undefined { + export function getBoundingSphere(loci: Loci, boundingSphere?: Sphere3D): Sphere3D | undefined { if (loci.kind === 'every-loci' || loci.kind === 'empty-loci') return void 0; + if (!boundingSphere) boundingSphere = Sphere3D.zero() sphereHelper.reset(); + if (loci.kind === 'structure-loci') { - return Sphere3D.clone(loci.structure.boundary.sphere) + return Sphere3D.copy(boundingSphere, loci.structure.boundary.sphere) } else if (loci.kind === 'element-loci') { for (const e of loci.elements) { const { indices } = e; @@ -99,20 +102,16 @@ namespace Loci { } } else if (loci.kind === 'link-loci') { for (const e of loci.links) { - let pos = e.aUnit.conformation.position; - pos(e.aUnit.elements[e.aIndex], tempPos); + e.aUnit.conformation.position(e.aUnit.elements[e.aIndex], tempPos); sphereHelper.includeStep(tempPos); - pos = e.bUnit.conformation.position; - pos(e.bUnit.elements[e.bIndex], tempPos); + e.bUnit.conformation.position(e.bUnit.elements[e.bIndex], tempPos); sphereHelper.includeStep(tempPos); } sphereHelper.finishedIncludeStep(); for (const e of loci.links) { - let pos = e.aUnit.conformation.position; - pos(e.aUnit.elements[e.aIndex], tempPos); + e.aUnit.conformation.position(e.aUnit.elements[e.aIndex], tempPos); sphereHelper.radiusStep(tempPos); - pos = e.bUnit.conformation.position; - pos(e.bUnit.elements[e.bIndex], tempPos); + e.aUnit.conformation.position(e.bUnit.elements[e.bIndex], tempPos); sphereHelper.radiusStep(tempPos); } } else if (loci.kind === 'group-loci') { @@ -123,6 +122,14 @@ namespace Loci { return void 0; } - return Sphere3D.create(Vec3.clone(sphereHelper.center), Math.sqrt(sphereHelper.radiusSq)); + Vec3.copy(boundingSphere.center, sphereHelper.center) + boundingSphere.radius = Math.sqrt(sphereHelper.radiusSq) + return boundingSphere + } + + const tmpSphere3D = Sphere3D.zero() + export function getCenter(loci: Loci, center?: Vec3): Vec3 | undefined { + const boundingSphere = getBoundingSphere(loci, tmpSphere3D) + return boundingSphere ? Vec3.copy(center || Vec3.zero(), boundingSphere.center) : undefined } } \ No newline at end of file diff --git a/src/mol-model/shape/shape.ts b/src/mol-model/shape/shape.ts index 6ded3bec5c76b51c45689713bfaabb7f63d2f2fa..dc115c474ff915dce380887801a5d0aa89e6c3b6 100644 --- a/src/mol-model/shape/shape.ts +++ b/src/mol-model/shape/shape.ts @@ -4,36 +4,27 @@ * @author Alexander Rose <alexander.rose@weirdbyte.de> */ -import { Mesh } from 'mol-geo/geometry/mesh/mesh'; import { Color } from 'mol-util/color'; import { UUID, ValueCell } from 'mol-util'; import { OrderedSet } from 'mol-data/int'; -import { arrayMax } from 'mol-util/array'; +import { Geometry } from 'mol-geo/geometry/geometry'; export interface Shape { readonly id: UUID readonly name: string - readonly mesh: Mesh + readonly geometry: Geometry readonly colors: ValueCell<Color[]> readonly labels: ValueCell<string[]> readonly groupCount: number } export namespace Shape { - export function create(name: string, mesh: Mesh, colors: Color[], labels: string[]): Shape { - let currentGroupBufferVersion = -1 - let currentGroupCount = -1 - + export function create(name: string, geometry: Geometry, colors: Color[], labels: string[]): Shape { return { id: UUID.create22(), name, - mesh, - get groupCount() { - if (mesh.groupBuffer.ref.version !== currentGroupBufferVersion) { - currentGroupCount = arrayMax(mesh.groupBuffer.ref.value) + 1 - } - return currentGroupCount - }, + geometry, + groupCount: Geometry.getGroupCount(geometry), colors: ValueCell.create(colors), labels: ValueCell.create(labels), } diff --git a/src/mol-repr/representation.ts b/src/mol-repr/representation.ts index c206d7149a5d70d8f763e90209ea79e77de95760..8c620d049888c730e4bc84e964081f59980bcd12 100644 --- a/src/mol-repr/representation.ts +++ b/src/mol-repr/representation.ts @@ -17,7 +17,7 @@ import { SizeTheme } from 'mol-theme/size'; import { Theme, ThemeRegistryContext, createEmptyTheme } from 'mol-theme/theme'; import { Subject } from 'rxjs'; import { Mat4 } from 'mol-math/linear-algebra'; -import { Geometry } from 'mol-geo/geometry/geometry'; +import { BaseGeometry } from 'mol-geo/geometry/base'; // export interface RepresentationProps { // visuals?: string[] @@ -242,14 +242,14 @@ namespace Representation { } } - export function fromRenderObject(label: string, renderObject: GraphicsRenderObject): Representation<GraphicsRenderObject, Geometry.Params> { + export function fromRenderObject(label: string, renderObject: GraphicsRenderObject): Representation<GraphicsRenderObject, BaseGeometry.Params> { let version = 0 const updated = new Subject<number>() const currentState = Representation.createState() const currentTheme = createEmptyTheme() - const currentParams = PD.clone(Geometry.Params) - const currentProps = PD.getDefaultValues(Geometry.Params) + const currentParams = PD.clone(BaseGeometry.Params) + const currentProps = PD.getDefaultValues(BaseGeometry.Params) return { label, @@ -258,7 +258,7 @@ namespace Representation { get renderObjects() { return [renderObject] }, get props() { return currentProps }, get params() { return currentParams }, - createOrUpdate: (props: Partial<PD.Values<Geometry.Params>> = {}) => { + createOrUpdate: (props: Partial<PD.Values<BaseGeometry.Params>> = {}) => { const qualityProps = getQualityProps(Object.assign({}, currentProps, props)) Object.assign(currentProps, props, qualityProps) diff --git a/src/mol-repr/shape/representation.ts b/src/mol-repr/shape/representation.ts index 52569ad324fb9df486f33dee17775b4bd5be3f73..44e941bc649758d1940be8b7bae9e6c9b9220556 100644 --- a/src/mol-repr/shape/representation.ts +++ b/src/mol-repr/shape/representation.ts @@ -5,7 +5,7 @@ */ import { Task } from 'mol-task' -import { RenderObject, createMeshRenderObject, MeshRenderObject } from 'mol-gl/render-object'; +import { RenderObject, createRenderObject, MeshRenderObject } from 'mol-gl/render-object'; import { Representation, RepresentationContext } from '../representation'; import { Loci, EmptyLoci, isEveryLoci } from 'mol-model/loci'; import { ValueCell } from 'mol-util'; @@ -14,7 +14,6 @@ import { OrderedSet, Interval } from 'mol-data/int'; import { ParamDefinition as PD } from 'mol-util/param-definition'; import { Mesh } from 'mol-geo/geometry/mesh/mesh'; import { createIdentityTransform } from 'mol-geo/geometry/transform-data'; -import { Geometry } from 'mol-geo/geometry/geometry'; import { PickingId } from 'mol-geo/geometry/picking'; import { MarkerAction, applyMarkerAction } from 'mol-geo/geometry/marker-data'; import { LocationIterator } from 'mol-geo/util/location-iterator'; @@ -51,14 +50,13 @@ export function ShapeRepresentation<P extends ShapeParams>(ctx: RepresentationCo if (!_shape) return - const mesh = _shape.mesh locationIt = ShapeGroupIterator.fromShape(_shape) const transform = createIdentityTransform() - const values = Mesh.createValues(mesh, transform, locationIt, _theme, currentProps) - const state = Geometry.createRenderableState(currentProps) + const values = Mesh.Utils.createValues(_shape.mesh, transform, locationIt, _theme, currentProps) + const state = Mesh.Utils.createRenderableState(currentProps) - _renderObject = createMeshRenderObject(values, state) + _renderObject = createRenderObject('mesh', values, state) renderObjects.push(_renderObject) updated.next(version++) }); diff --git a/src/mol-repr/structure/complex-visual.ts b/src/mol-repr/structure/complex-visual.ts index d5ce56381d82bd2f4598311be0878be4a2aa6d46..570e25e1a5bfafabc6e894110554df8b6cb798ec 100644 --- a/src/mol-repr/structure/complex-visual.ts +++ b/src/mol-repr/structure/complex-visual.ts @@ -6,16 +6,15 @@ import { Structure } from 'mol-model/structure'; import { Visual, VisualContext } from '../visual'; -import { MeshRenderObject, LinesRenderObject, PointsRenderObject, DirectVolumeRenderObject } from 'mol-gl/render-object'; -import { createComplexMeshRenderObject, UnitKind, UnitKindOptions, createComplexDirectVolumeRenderObject } from './visual/util/common'; +import { createRenderObject, GraphicsRenderObject } from 'mol-gl/render-object'; +import { UnitKind, UnitKindOptions } from './visual/util/common'; import { StructureMeshParams, StructureParams, StructureDirectVolumeParams } from './representation'; import { deepEqual, ValueCell } from 'mol-util'; import { Loci, isEveryLoci, EmptyLoci } from 'mol-model/loci'; import { Interval } from 'mol-data/int'; import { ParamDefinition as PD } from 'mol-util/param-definition'; -import { RenderableValues } from 'mol-gl/renderable/schema'; import { createSizes } from 'mol-geo/geometry/size-data'; -import { Geometry } from 'mol-geo/geometry/geometry'; +import { Geometry, GeometryUtils } from 'mol-geo/geometry/geometry'; import { LocationIterator } from 'mol-geo/util/location-iterator'; import { PickingId } from 'mol-geo/geometry/picking'; import { createColors } from 'mol-geo/geometry/color-data'; @@ -25,21 +24,27 @@ import { VisualUpdateState } from 'mol-repr/util'; import { Theme, createEmptyTheme } from 'mol-theme/theme'; import { ColorTheme } from 'mol-theme/color'; import { SizeTheme } from 'mol-theme/size'; -import { RenderableState } from 'mol-gl/renderable'; import { UnitsParams } from './units-representation'; import { DirectVolume } from 'mol-geo/geometry/direct-volume/direct-volume'; import { Mat4 } from 'mol-math/linear-algebra'; +import { createIdentityTransform } from 'mol-geo/geometry/transform-data'; export interface ComplexVisual<P extends StructureParams> extends Visual<Structure, P> { } +function createComplexRenderObject(structure: Structure, geometry: Geometry, locationIt: LocationIterator, theme: Theme, props: PD.Values<StructureParams>) { + const { createValues, createRenderableState } = Geometry.getUtils(geometry.kind) + const transform = createIdentityTransform() + const values = createValues(geometry, transform, locationIt, theme, props as any) // TODO + const state = createRenderableState(props) + return createRenderObject(geometry.kind, values, state) +} + const ComplexParams = { ...StructureParams, unitKinds: PD.MultiSelect<UnitKind>(['atomic', 'spheres'], UnitKindOptions), } type ComplexParams = typeof ComplexParams -type ComplexRenderObject = MeshRenderObject | LinesRenderObject | PointsRenderObject | DirectVolumeRenderObject - interface ComplexVisualBuilder<P extends ComplexParams, G extends Geometry> { defaultProps: PD.Values<P> createGeometry(ctx: VisualContext, structure: Structure, theme: Theme, props: PD.Values<P>, geometry?: G): Promise<G> | G @@ -49,20 +54,16 @@ interface ComplexVisualBuilder<P extends ComplexParams, G extends Geometry> { setUpdateState(state: VisualUpdateState, newProps: PD.Values<P>, currentProps: PD.Values<P>, newTheme: Theme, currentTheme: Theme): void } -interface ComplexVisualGeometryBuilder<P extends ComplexParams, G extends Geometry> extends ComplexVisualBuilder<P, G> { - createEmptyGeometry(geometry?: G): G - createRenderObject(structure: Structure, geometry: Geometry, locationIt: LocationIterator, theme: Theme, currentProps: PD.Values<P>): ComplexRenderObject - updateValues(values: RenderableValues, newProps: PD.Values<P>): void, - updateBoundingSphere(values: RenderableValues, geometry: Geometry): void - updateRenderableState(state: RenderableState, props: PD.Values<P>): void +interface ComplexVisualGeometryBuilder<P extends UnitsParams, G extends Geometry> extends ComplexVisualBuilder<P, G> { + geometryUtils: GeometryUtils<G> } -export function ComplexVisual<P extends ComplexParams>(builder: ComplexVisualGeometryBuilder<P, Geometry>): ComplexVisual<P> { +export function ComplexVisual<G extends Geometry, P extends ComplexParams & Geometry.Params<G>>(builder: ComplexVisualGeometryBuilder<P, G>): ComplexVisual<P> { const { defaultProps, createGeometry, createLocationIterator, getLoci, mark, setUpdateState } = builder - const { createRenderObject, updateValues, updateBoundingSphere, updateRenderableState } = builder + const { updateValues, updateBoundingSphere, updateRenderableState } = builder.geometryUtils const updateState = VisualUpdateState.create() - let renderObject: ComplexRenderObject | undefined + let renderObject: GraphicsRenderObject | undefined let newProps: PD.Values<P> let newTheme: Theme @@ -72,7 +73,7 @@ export function ComplexVisual<P extends ComplexParams>(builder: ComplexVisualGeo let currentTheme: Theme = createEmptyTheme() let currentStructure: Structure - let geometry: Geometry + let geometry: G let locationIt: LocationIterator function prepareUpdate(theme: Theme, props: Partial<PD.Values<P>>, structure: Structure) { @@ -111,11 +112,11 @@ export function ComplexVisual<P extends ComplexParams>(builder: ComplexVisualGeo } } - function update(newGeometry?: Geometry) { + function update(newGeometry?: G) { if (updateState.createNew) { locationIt = createLocationIterator(newStructure) if (newGeometry) { - renderObject = createRenderObject(newStructure, newGeometry, locationIt, newTheme, newProps) + renderObject = createComplexRenderObject(newStructure, newGeometry, locationIt, newTheme, newProps) } else { throw new Error('expected geometry to be given') } @@ -220,17 +221,13 @@ export type ComplexMeshParams = typeof ComplexMeshParams export interface ComplexMeshVisualBuilder<P extends ComplexMeshParams> extends ComplexVisualBuilder<P, Mesh> { } export function ComplexMeshVisual<P extends ComplexMeshParams>(builder: ComplexMeshVisualBuilder<P>): ComplexVisual<P> { - return ComplexVisual<StructureMeshParams & UnitsParams>({ + return ComplexVisual<Mesh, StructureMeshParams & UnitsParams>({ ...builder, setUpdateState: (state: VisualUpdateState, newProps: PD.Values<P>, currentProps: PD.Values<P>, newTheme: Theme, currentTheme: Theme) => { builder.setUpdateState(state, newProps, currentProps, newTheme, currentTheme) if (!SizeTheme.areEqual(newTheme.size, currentTheme.size)) state.createGeometry = true }, - createEmptyGeometry: Mesh.createEmpty, - createRenderObject: createComplexMeshRenderObject, - updateValues: Mesh.updateValues, - updateBoundingSphere: Mesh.updateBoundingSphere, - updateRenderableState: Geometry.updateRenderableState + geometryUtils: Mesh.Utils }) } @@ -245,16 +242,12 @@ export type ComplexDirectVolumeParams = typeof ComplexDirectVolumeParams export interface ComplexDirectVolumeVisualBuilder<P extends ComplexDirectVolumeParams> extends ComplexVisualBuilder<P, DirectVolume> { } export function ComplexDirectVolumeVisual<P extends ComplexDirectVolumeParams>(builder: ComplexDirectVolumeVisualBuilder<P>): ComplexVisual<P> { - return ComplexVisual<StructureDirectVolumeParams & UnitsParams>({ + return ComplexVisual<DirectVolume, StructureDirectVolumeParams & UnitsParams>({ ...builder, setUpdateState: (state: VisualUpdateState, newProps: PD.Values<P>, currentProps: PD.Values<P>, newTheme: Theme, currentTheme: Theme) => { builder.setUpdateState(state, newProps, currentProps, newTheme, currentTheme) if (!SizeTheme.areEqual(newTheme.size, currentTheme.size)) state.createGeometry = true }, - createEmptyGeometry: DirectVolume.createEmpty, - createRenderObject: createComplexDirectVolumeRenderObject, - updateValues: DirectVolume.updateValues, - updateBoundingSphere: DirectVolume.updateBoundingSphere, - updateRenderableState: DirectVolume.updateRenderableState + geometryUtils: DirectVolume.Utils }) } \ No newline at end of file diff --git a/src/mol-repr/structure/representation.ts b/src/mol-repr/structure/representation.ts index ae35178342399c80509b7b73a0f855791acfb494..6e2991d13f4973d5f922e355c22fbeebb92b85e6 100644 --- a/src/mol-repr/structure/representation.ts +++ b/src/mol-repr/structure/representation.ts @@ -8,7 +8,7 @@ import { Structure } from 'mol-model/structure'; import { Representation, RepresentationProps, RepresentationProvider } from '../representation'; import { ParamDefinition as PD } from 'mol-util/param-definition'; -import { Geometry } from 'mol-geo/geometry/geometry'; +import { BaseGeometry } from 'mol-geo/geometry/base'; import { Mesh } from 'mol-geo/geometry/mesh/mesh'; import { Points } from 'mol-geo/geometry/points/points'; import { Lines } from 'mol-geo/geometry/lines/lines'; @@ -21,7 +21,7 @@ export type StructureRepresentationProvider<P extends PD.Params> = Representatio // -export const StructureParams = { ...Geometry.Params } +export const StructureParams = { ...BaseGeometry.Params } export type StructureParams = typeof StructureParams export const StructureMeshParams = { ...Mesh.Params, ...StructureParams } diff --git a/src/mol-repr/structure/units-visual.ts b/src/mol-repr/structure/units-visual.ts index 01e10cc28cf300bd0e696fa01e9d3bb46a442676..20023f022db704196ccaa5619592f4b0b7a9af95 100644 --- a/src/mol-repr/structure/units-visual.ts +++ b/src/mol-repr/structure/units-visual.ts @@ -9,13 +9,11 @@ import { RepresentationProps } from '../representation'; import { Visual, VisualContext } from '../visual'; import { StructureMeshParams, StructurePointsParams, StructureLinesParams, StructureDirectVolumeParams, StructureSpheresParams } from './representation'; import { Loci, isEveryLoci, EmptyLoci } from 'mol-model/loci'; -import { MeshRenderObject, PointsRenderObject, LinesRenderObject, DirectVolumeRenderObject, SpheresRenderObject } from 'mol-gl/render-object'; -import { createUnitsMeshRenderObject, createUnitsPointsRenderObject, createUnitsTransform, createUnitsLinesRenderObject, createUnitsDirectVolumeRenderObject, includesUnitKind, createUnitsSpheresRenderObject } from './visual/util/common'; +import { GraphicsRenderObject, createRenderObject } from 'mol-gl/render-object'; import { deepEqual, ValueCell } from 'mol-util'; import { Interval } from 'mol-data/int'; import { ParamDefinition as PD } from 'mol-util/param-definition'; -import { RenderableValues } from 'mol-gl/renderable/schema'; -import { Geometry } from 'mol-geo/geometry/geometry'; +import { Geometry, GeometryUtils } from 'mol-geo/geometry/geometry'; import { LocationIterator } from 'mol-geo/util/location-iterator'; import { PickingId } from 'mol-geo/geometry/picking'; import { createMarkers, MarkerAction, applyMarkerAction } from 'mol-geo/geometry/marker-data'; @@ -30,15 +28,21 @@ import { Theme, createEmptyTheme } from 'mol-theme/theme'; import { ColorTheme } from 'mol-theme/color'; import { SizeTheme } from 'mol-theme/size'; import { UnitsParams } from './units-representation'; -import { RenderableState } from 'mol-gl/renderable'; import { Mat4 } from 'mol-math/linear-algebra'; import { Spheres } from 'mol-geo/geometry/spheres/spheres'; +import { createUnitsTransform, includesUnitKind } from './visual/util/common'; export type StructureGroup = { structure: Structure, group: Unit.SymmetryGroup } export interface UnitsVisual<P extends RepresentationProps = {}> extends Visual<StructureGroup, P> { } -type UnitsRenderObject = MeshRenderObject | LinesRenderObject | PointsRenderObject | SpheresRenderObject | DirectVolumeRenderObject +function createUnitsRenderObject<G extends Geometry>(group: Unit.SymmetryGroup, geometry: G, locationIt: LocationIterator, theme: Theme, props: PD.Values<Geometry.Params<G>>) { + const { createValues, createRenderableState } = Geometry.getUtils(geometry.kind) + const transform = createUnitsTransform(group) + const values = createValues(geometry, transform, locationIt, theme, props as any) // TODO + const state = createRenderableState(props) + return createRenderObject(geometry.kind, values, state) +} interface UnitsVisualBuilder<P extends UnitsParams, G extends Geometry> { defaultProps: PD.Values<P> @@ -50,19 +54,15 @@ interface UnitsVisualBuilder<P extends UnitsParams, G extends Geometry> { } interface UnitsVisualGeometryBuilder<P extends UnitsParams, G extends Geometry> extends UnitsVisualBuilder<P, G> { - createEmptyGeometry(geometry?: G): G - createRenderObject(group: Unit.SymmetryGroup, geometry: Geometry, locationIt: LocationIterator, theme: Theme, currentProps: PD.Values<P>): UnitsRenderObject - updateValues(values: RenderableValues, newProps: Partial<PD.Values<P>>): void - updateBoundingSphere(values: RenderableValues, geometry: Geometry): void - updateRenderableState(state: RenderableState, props: Partial<PD.Values<P>>): void + geometryUtils: GeometryUtils<G> } -export function UnitsVisual<P extends UnitsParams>(builder: UnitsVisualGeometryBuilder<P, Geometry>): UnitsVisual<P> { +export function UnitsVisual<G extends Geometry, P extends UnitsParams & Geometry.Params<G>>(builder: UnitsVisualGeometryBuilder<P, G>): UnitsVisual<P> { const { defaultProps, createGeometry, createLocationIterator, getLoci, mark, setUpdateState } = builder - const { createEmptyGeometry, createRenderObject, updateValues, updateBoundingSphere, updateRenderableState } = builder + const { createEmpty: createEmptyGeometry, updateValues, updateBoundingSphere, updateRenderableState } = builder.geometryUtils const updateState = VisualUpdateState.create() - let renderObject: UnitsRenderObject | undefined + let renderObject: GraphicsRenderObject | undefined let newProps: PD.Values<P> = Object.assign({}, defaultProps) let newTheme: Theme = createEmptyTheme() @@ -72,7 +72,7 @@ export function UnitsVisual<P extends UnitsParams>(builder: UnitsVisualGeometryB let currentTheme: Theme let currentStructureGroup: StructureGroup - let geometry: Geometry + let geometry: G let locationIt: LocationIterator function prepareUpdate(theme: Theme, props: Partial<PD.Values<P>> = {}, structureGroup: StructureGroup) { @@ -133,11 +133,11 @@ export function UnitsVisual<P extends UnitsParams>(builder: UnitsVisualGeometryB } } - function update(newGeometry?: Geometry) { + function update(newGeometry?: G) { if (updateState.createNew) { locationIt = createLocationIterator(newStructureGroup.group) if (newGeometry) { - renderObject = createRenderObject(newStructureGroup.group, newGeometry, locationIt, newTheme, newProps) + renderObject = createUnitsRenderObject(newStructureGroup.group, newGeometry, locationIt, newTheme, newProps) } else { throw new Error('expected geometry to be given') } @@ -197,7 +197,7 @@ export function UnitsVisual<P extends UnitsParams>(builder: UnitsVisualGeometryB if (newGeometry) geometry = newGeometry } - function _createGeometry(ctx: VisualContext, unit: Unit, structure: Structure, theme: Theme, props: PD.Values<P>, geometry?: Geometry) { + function _createGeometry(ctx: VisualContext, unit: Unit, structure: Structure, theme: Theme, props: PD.Values<P>, geometry?: G) { return includesUnitKind(props.unitKinds, unit) ? createGeometry(ctx, unit, structure, theme, props, geometry) : createEmptyGeometry(geometry) @@ -210,7 +210,7 @@ export function UnitsVisual<P extends UnitsParams>(builder: UnitsVisualGeometryB prepareUpdate(theme, props, structureGroup || currentStructureGroup) if (updateState.createGeometry) { const newGeometry = _createGeometry(ctx, newStructureGroup.group.units[0], newStructureGroup.structure, newTheme, newProps, geometry) - return newGeometry instanceof Promise ? newGeometry.then(update) : update(newGeometry) + return newGeometry instanceof Promise ? newGeometry.then(update) : update(newGeometry as G) } else { update() } @@ -263,17 +263,13 @@ export type UnitsMeshParams = typeof UnitsMeshParams export interface UnitsMeshVisualBuilder<P extends UnitsMeshParams> extends UnitsVisualBuilder<P, Mesh> { } export function UnitsMeshVisual<P extends UnitsMeshParams>(builder: UnitsMeshVisualBuilder<P>): UnitsVisual<P> { - return UnitsVisual<StructureMeshParams & UnitsParams>({ + return UnitsVisual<Mesh, StructureMeshParams & UnitsParams>({ ...builder, setUpdateState: (state: VisualUpdateState, newProps: PD.Values<P>, currentProps: PD.Values<P>, newTheme: Theme, currentTheme: Theme) => { builder.setUpdateState(state, newProps, currentProps, newTheme, currentTheme) if (!SizeTheme.areEqual(newTheme.size, currentTheme.size)) state.createGeometry = true }, - createEmptyGeometry: Mesh.createEmpty, - createRenderObject: createUnitsMeshRenderObject, - updateValues: Mesh.updateValues, - updateBoundingSphere: Mesh.updateBoundingSphere, - updateRenderableState: Geometry.updateRenderableState + geometryUtils: Mesh.Utils }) } @@ -284,17 +280,13 @@ export type UnitsSpheresParams = typeof UnitsSpheresParams export interface UnitsSpheresVisualBuilder<P extends UnitsSpheresParams> extends UnitsVisualBuilder<P, Spheres> { } export function UnitsSpheresVisual<P extends UnitsSpheresParams>(builder: UnitsSpheresVisualBuilder<P>): UnitsVisual<P> { - return UnitsVisual<StructureSpheresParams & UnitsParams>({ + return UnitsVisual<Spheres, StructureSpheresParams & UnitsParams>({ ...builder, setUpdateState: (state: VisualUpdateState, newProps: PD.Values<P>, currentProps: PD.Values<P>, newTheme: Theme, currentTheme: Theme) => { builder.setUpdateState(state, newProps, currentProps, newTheme, currentTheme) if (!SizeTheme.areEqual(newTheme.size, currentTheme.size)) state.updateSize = true }, - createEmptyGeometry: Spheres.createEmpty, - createRenderObject: createUnitsSpheresRenderObject, - updateValues: Spheres.updateValues, - updateBoundingSphere: Spheres.updateBoundingSphere, - updateRenderableState: Geometry.updateRenderableState + geometryUtils: Spheres.Utils }) } @@ -305,17 +297,13 @@ export type UnitsPointsParams = typeof UnitsPointsParams export interface UnitsPointVisualBuilder<P extends UnitsPointsParams> extends UnitsVisualBuilder<P, Points> { } export function UnitsPointsVisual<P extends UnitsPointsParams>(builder: UnitsPointVisualBuilder<P>): UnitsVisual<P> { - return UnitsVisual<StructurePointsParams & UnitsParams>({ + return UnitsVisual<Points, StructurePointsParams & UnitsParams>({ ...builder, - createEmptyGeometry: Points.createEmpty, - createRenderObject: createUnitsPointsRenderObject, setUpdateState: (state: VisualUpdateState, newProps: PD.Values<P>, currentProps: PD.Values<P>, newTheme: Theme, currentTheme: Theme) => { builder.setUpdateState(state, newProps, currentProps, newTheme, currentTheme) if (!SizeTheme.areEqual(newTheme.size, currentTheme.size)) state.updateSize = true }, - updateValues: Points.updateValues, - updateBoundingSphere: Points.updateBoundingSphere, - updateRenderableState: Points.updateRenderableState + geometryUtils: Points.Utils }) } @@ -326,17 +314,13 @@ export type UnitsLinesParams = typeof UnitsLinesParams export interface UnitsLinesVisualBuilder<P extends UnitsLinesParams> extends UnitsVisualBuilder<P, Lines> { } export function UnitsLinesVisual<P extends UnitsLinesParams>(builder: UnitsLinesVisualBuilder<P>): UnitsVisual<P> { - return UnitsVisual<StructureLinesParams & UnitsParams>({ + return UnitsVisual<Lines, StructureLinesParams & UnitsParams>({ ...builder, - createEmptyGeometry: Lines.createEmpty, - createRenderObject: createUnitsLinesRenderObject, setUpdateState: (state: VisualUpdateState, newProps: PD.Values<P>, currentProps: PD.Values<P>, newTheme: Theme, currentTheme: Theme) => { builder.setUpdateState(state, newProps, currentProps, newTheme, currentTheme) if (!SizeTheme.areEqual(newTheme.size, currentTheme.size)) state.updateSize = true }, - updateValues: Lines.updateValues, - updateBoundingSphere: Lines.updateBoundingSphere, - updateRenderableState: Geometry.updateRenderableState + geometryUtils: Lines.Utils }) } @@ -344,19 +328,15 @@ export function UnitsLinesVisual<P extends UnitsLinesParams>(builder: UnitsLines export const UnitsDirectVolumeParams = { ...StructureDirectVolumeParams, ...UnitsParams } export type UnitsDirectVolumeParams = typeof UnitsDirectVolumeParams -export interface UnitsDirectVolumeVisualBuilder<P extends UnitsDirectVolumeParams> extends UnitsVisualBuilder<P, DirectVolume> { } +export interface UnitsDirectVolumeVisualBuilder<P extends UnitsDirectVolumeParams> extends UnitsVisualGeometryBuilder<P, DirectVolume> { } export function UnitsDirectVolumeVisual<P extends UnitsDirectVolumeParams>(builder: UnitsDirectVolumeVisualBuilder<P>): UnitsVisual<P> { - return UnitsVisual<StructureDirectVolumeParams & UnitsParams>({ + return UnitsVisual<DirectVolume, StructureDirectVolumeParams & UnitsParams>({ ...builder, - createEmptyGeometry: DirectVolume.createEmpty, - createRenderObject: createUnitsDirectVolumeRenderObject, setUpdateState: (state: VisualUpdateState, newProps: PD.Values<P>, currentProps: PD.Values<P>, newTheme: Theme, currentTheme: Theme) => { builder.setUpdateState(state, newProps, currentProps, newTheme, currentTheme) if (!SizeTheme.areEqual(newTheme.size, currentTheme.size)) state.createGeometry = true }, - updateValues: DirectVolume.updateValues, - updateBoundingSphere: DirectVolume.updateBoundingSphere, - updateRenderableState: DirectVolume.updateRenderableState + geometryUtils: DirectVolume.Utils }) } \ No newline at end of file diff --git a/src/mol-repr/structure/visual/util/common.ts b/src/mol-repr/structure/visual/util/common.ts index b77ab1958180f44151d1094def2575b5cc998f22..1e2f479d22e546a668aab603854caf7841db563f 100644 --- a/src/mol-repr/structure/visual/util/common.ts +++ b/src/mol-repr/structure/visual/util/common.ts @@ -5,21 +5,10 @@ */ import { Unit, Structure, ElementIndex, StructureElement } from 'mol-model/structure'; -import { createMeshRenderObject, createPointsRenderObject, createLinesRenderObject, createDirectVolumeRenderObject, createSpheresRenderObject } from 'mol-gl/render-object'; 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'; -import { LocationIterator } from 'mol-geo/util/location-iterator'; -import { Geometry } 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 { Theme } from 'mol-theme/theme'; -import { ParamDefinition as PD } from 'mol-util/param-definition'; -import { StructureMeshParams, StructurePointsParams, StructureLinesParams, StructureDirectVolumeParams, StructureSpheresParams } from 'mol-repr/structure/representation'; +import { TransformData, createTransform } from 'mol-geo/geometry/transform-data'; import { OrderedSet, SortedArray } from 'mol-data/int'; import { EmptyLoci, Loci } from 'mol-model/loci'; -import { Spheres } from 'mol-geo/geometry/spheres/spheres'; /** Return a Loci for the elements of a whole residue the elementIndex belongs to. */ export function getResidueLoci(structure: Structure, unit: Unit, elementIndex: ElementIndex): Loci { @@ -66,63 +55,4 @@ export function includesUnitKind(unitKinds: UnitKind[], unit: Unit) { if (Unit.isGaussians(unit) && unitKinds[i] === 'gaussians') return true } return false -} - -// mesh - -export function createComplexMeshRenderObject(structure: Structure, mesh: Mesh, locationIt: LocationIterator, theme: Theme, props: PD.Values<StructureMeshParams>) { - const transform = createIdentityTransform() - const values = Mesh.createValues(mesh, transform, locationIt, theme, props) - const state = Geometry.createRenderableState(props) - return createMeshRenderObject(values, state) -} - -export function createUnitsMeshRenderObject(group: Unit.SymmetryGroup, mesh: Mesh, locationIt: LocationIterator, theme: Theme, props: PD.Values<StructureMeshParams>) { - const transform = createUnitsTransform(group) - const values = Mesh.createValues(mesh, transform, locationIt, theme, props) - const state = Geometry.createRenderableState(props) - return createMeshRenderObject(values, state) -} - -// spheres - -export function createUnitsSpheresRenderObject(group: Unit.SymmetryGroup, spheres: Spheres, locationIt: LocationIterator, theme: Theme, props: PD.Values<StructureSpheresParams>) { - const transform = createUnitsTransform(group) - const values = Spheres.createValues(spheres, transform, locationIt, theme, props) - const state = Geometry.createRenderableState(props) - return createSpheresRenderObject(values, state) -} - -// points - -export function createUnitsPointsRenderObject(group: Unit.SymmetryGroup, points: Points, locationIt: LocationIterator, theme: Theme, props: PD.Values<StructurePointsParams>) { - const transform = createUnitsTransform(group) - const values = Points.createValues(points, transform, locationIt, theme, props) - const state = Points.createRenderableState(props) - return createPointsRenderObject(values, state) -} - -// lines - -export function createUnitsLinesRenderObject(group: Unit.SymmetryGroup, lines: Lines, locationIt: LocationIterator, theme: Theme, props: PD.Values<StructureLinesParams>) { - const transform = createUnitsTransform(group) - const values = Lines.createValues(lines, transform, locationIt, theme, props) - const state = Geometry.createRenderableState(props) - return createLinesRenderObject(values, state) -} - -// direct-volume - -export function createComplexDirectVolumeRenderObject(structure: Structure, directVolume: DirectVolume, locationIt: LocationIterator, theme: Theme, props: PD.Values<StructureDirectVolumeParams>) { - const transform = createIdentityTransform() - const values = DirectVolume.createValues(directVolume, transform, locationIt, theme, props) - const state = DirectVolume.createRenderableState(props) - return createDirectVolumeRenderObject(values, state) -} - -export function createUnitsDirectVolumeRenderObject(group: Unit.SymmetryGroup, directVolume: DirectVolume, locationIt: LocationIterator, theme: Theme, props: PD.Values<StructureDirectVolumeParams>) { - const transform = createUnitsTransform(group) - const values = DirectVolume.createValues(directVolume, transform, locationIt, theme, props) - const state = DirectVolume.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 81fa4a5e16c3da255ea84efd938e7ac0fae9cf42..ae67e9c7aafdcbd6070d58120e62973c94ef4d6f 100644 --- a/src/mol-repr/structure/visual/util/element.ts +++ b/src/mol-repr/structure/visual/util/element.ts @@ -25,7 +25,7 @@ export interface ElementSphereMeshProps { sizeFactor: number } -export function createElementSphereMesh(ctx: VisualContext, unit: Unit, structure: Structure, theme: Theme, props: ElementSphereMeshProps, mesh?: Mesh) { +export function createElementSphereMesh(ctx: VisualContext, unit: Unit, structure: Structure, theme: Theme, props: ElementSphereMeshProps, mesh?: Mesh): Mesh { const { detail, sizeFactor } = props const { elements } = unit; @@ -51,7 +51,7 @@ export function createElementSphereMesh(ctx: VisualContext, unit: Unit, structur export interface ElementSphereImpostorProps { } -export function createElementSphereImpostor(ctx: VisualContext, unit: Unit, structure: Structure, theme: Theme, props: ElementSphereImpostorProps, spheres?: Spheres) { +export function createElementSphereImpostor(ctx: VisualContext, unit: Unit, structure: Structure, theme: Theme, props: ElementSphereImpostorProps, spheres?: Spheres): Spheres { const { elements } = unit; const elementCount = elements.length; diff --git a/src/mol-repr/util.ts b/src/mol-repr/util.ts index b5f27195f85950c7cd400b78cdd71efe5e374b00..d4428fad2a1b15fedbe677377346e0f093156dea 100644 --- a/src/mol-repr/util.ts +++ b/src/mol-repr/util.ts @@ -6,7 +6,7 @@ import { defaults } from 'mol-util'; import { Structure } from 'mol-model/structure'; -import { VisualQuality } from 'mol-geo/geometry/geometry'; +import { VisualQuality } from 'mol-geo/geometry/base'; export interface VisualUpdateState { updateTransform: boolean diff --git a/src/mol-repr/volume/direct-volume.ts b/src/mol-repr/volume/direct-volume.ts index 5853a5870da55d5f4c586cc9ed1ab9f21f5c8fef..581c35cdf37db4e110c2e59933c23233788cc562 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, VolumeRepresentationProvider } from './representation'; -import { createDirectVolumeRenderObject } from 'mol-gl/render-object'; +import { createRenderObject } from 'mol-gl/render-object'; import { EmptyLoci } from 'mol-model/loci'; import { ParamDefinition as PD } from 'mol-util/param-definition'; import { Vec3, Mat4 } from 'mol-math/linear-algebra'; @@ -17,7 +17,7 @@ import { createTexture } from 'mol-gl/webgl/texture'; import { LocationIterator } from 'mol-geo/util/location-iterator'; import { createIdentityTransform } from 'mol-geo/geometry/transform-data'; import { DirectVolume } from 'mol-geo/geometry/direct-volume/direct-volume'; -import { Geometry } from 'mol-geo/geometry/geometry'; +import { BaseGeometry } from 'mol-geo/geometry/base'; import { VisualUpdateState } from 'mol-repr/util'; import { RepresentationContext, RepresentationParamsGetter } from 'mol-repr/representation'; import { Theme, ThemeRegistryContext } from 'mol-theme/theme'; @@ -157,7 +157,7 @@ export async function createDirectVolume(ctx: VisualContext, volume: VolumeData, // export const DirectVolumeParams = { - ...Geometry.Params, + ...BaseGeometry.Params, ...DirectVolume.Params } export type DirectVolumeParams = typeof DirectVolumeParams @@ -175,13 +175,13 @@ export function DirectVolumeVisual(): VolumeVisual<DirectVolumeParams> { }, createRenderObject: (geometry: DirectVolume, locationIt: LocationIterator, theme: Theme, props: PD.Values<DirectVolumeParams>) => { const transform = createIdentityTransform() - const values = DirectVolume.createValues(geometry, transform, locationIt, theme, props) - const state = DirectVolume.createRenderableState(props) - return createDirectVolumeRenderObject(values, state) + const values = DirectVolume.Utils.createValues(geometry, transform, locationIt, theme, props) + const state = DirectVolume.Utils.createRenderableState(props) + return createRenderObject('direct-volume', values, state) }, - updateValues: DirectVolume.updateValues, - updateBoundingSphere: DirectVolume.updateBoundingSphere, - updateRenderableState: DirectVolume.updateRenderableState + updateValues: DirectVolume.Utils.updateValues, + updateBoundingSphere: DirectVolume.Utils.updateBoundingSphere, + updateRenderableState: DirectVolume.Utils.updateRenderableState }) } diff --git a/src/mol-repr/volume/isosurface-mesh.ts b/src/mol-repr/volume/isosurface-mesh.ts index 7dce42eb7828b1920448cca7ed056b504b3ae719..272d879992c4c5d12207e5874b04e96e72f547ba 100644 --- a/src/mol-repr/volume/isosurface-mesh.ts +++ b/src/mol-repr/volume/isosurface-mesh.ts @@ -7,14 +7,13 @@ import { VolumeData } from 'mol-model/volume' import { VolumeVisual, VolumeRepresentation, VolumeRepresentationProvider } from './representation'; -import { createMeshRenderObject } from 'mol-gl/render-object'; +import { createRenderObject } from 'mol-gl/render-object'; import { EmptyLoci } from 'mol-model/loci'; import { ParamDefinition as PD } from 'mol-util/param-definition'; import { Mesh } from 'mol-geo/geometry/mesh/mesh'; import { computeMarchingCubesMesh } from 'mol-geo/util/marching-cubes/algorithm'; import { LocationIterator } from 'mol-geo/util/location-iterator'; import { createIdentityTransform } from 'mol-geo/geometry/transform-data'; -import { Geometry } from 'mol-geo/geometry/geometry'; import { VisualUpdateState } from 'mol-repr/util'; import { RepresentationContext, RepresentationParamsGetter } from 'mol-repr/representation'; import { Theme, ThemeRegistryContext } from 'mol-theme/theme'; @@ -60,13 +59,13 @@ export function IsosurfaceVisual(): VolumeVisual<IsosurfaceParams> { }, createRenderObject: (geometry: Mesh, locationIt: LocationIterator, theme: Theme, props: PD.Values<IsosurfaceParams>) => { const transform = createIdentityTransform() - const values = Mesh.createValues(geometry, transform, locationIt, theme, props) - const state = Geometry.createRenderableState(props) - return createMeshRenderObject(values, state) + const values = Mesh.Utils.createValues(geometry, transform, locationIt, theme, props) + const state = Mesh.Utils.createRenderableState(props) + return createRenderObject('mesh', values, state) }, - updateValues: Mesh.updateValues, - updateBoundingSphere: Mesh.updateBoundingSphere, - updateRenderableState: Geometry.updateRenderableState + updateValues: Mesh.Utils.updateValues, + updateBoundingSphere: Mesh.Utils.updateBoundingSphere, + updateRenderableState: Mesh.Utils.updateRenderableState }) } diff --git a/src/mol-repr/volume/representation.ts b/src/mol-repr/volume/representation.ts index 88a38cd2e2be53d1893d8d7cf8f0c746a08d15b5..080463a6fca463c2bf000f49f27d190d39c37529 100644 --- a/src/mol-repr/volume/representation.ts +++ b/src/mol-repr/volume/representation.ts @@ -13,7 +13,7 @@ import { Geometry } from 'mol-geo/geometry/geometry'; import { ParamDefinition as PD } from 'mol-util/param-definition'; import { PickingId } from 'mol-geo/geometry/picking'; import { MarkerAction, applyMarkerAction } from 'mol-geo/geometry/marker-data'; -import { DirectVolumeRenderObject, PointsRenderObject, LinesRenderObject, MeshRenderObject } from 'mol-gl/render-object'; +import { GraphicsRenderObject } from 'mol-gl/render-object'; import { Interval } from 'mol-data/int'; import { RenderableValues } from 'mol-gl/renderable/schema'; import { LocationIterator } from 'mol-geo/util/location-iterator'; @@ -24,11 +24,10 @@ import { Theme, createEmptyTheme } from 'mol-theme/theme'; import { Subject } from 'rxjs'; import { RenderableState } from 'mol-gl/renderable'; import { Mat4 } from 'mol-math/linear-algebra'; +import { BaseGeometry } from 'mol-geo/geometry/base'; export interface VolumeVisual<P extends VolumeParams> extends Visual<VolumeData, P> { } -type VolumeRenderObject = MeshRenderObject | LinesRenderObject | PointsRenderObject | DirectVolumeRenderObject - interface VolumeVisualBuilder<P extends VolumeParams, G extends Geometry> { defaultProps: PD.Values<P> createGeometry(ctx: VisualContext, volumeData: VolumeData, props: PD.Values<P>, geometry?: G): Promise<G> @@ -38,7 +37,7 @@ interface VolumeVisualBuilder<P extends VolumeParams, G extends Geometry> { } interface VolumeVisualGeometryBuilder<P extends VolumeParams, G extends Geometry> extends VolumeVisualBuilder<P, G> { - createRenderObject(geometry: G, locationIt: LocationIterator, theme: Theme, currentProps: PD.Values<P>): VolumeRenderObject + createRenderObject(geometry: G, locationIt: LocationIterator, theme: Theme, currentProps: PD.Values<P>): GraphicsRenderObject updateValues(values: RenderableValues, newProps: PD.Values<P>): void, updateBoundingSphere(values: RenderableValues, geometry: G): void updateRenderableState(state: RenderableState, props: PD.Values<P>): void @@ -50,7 +49,7 @@ export function VolumeVisual<P extends VolumeParams>(builder: VolumeVisualGeomet const updateState = VisualUpdateState.create() let currentProps: PD.Values<P> - let renderObject: VolumeRenderObject | undefined + let renderObject: GraphicsRenderObject | undefined let currentVolume: VolumeData let geometry: Geometry let locationIt: LocationIterator @@ -147,7 +146,7 @@ export type VolumeRepresentationProvider<P extends VolumeParams> = Representatio // export const VolumeParams = { - ...Geometry.Params, + ...BaseGeometry.Params, isoValue: PD.Numeric(0.22, { min: -1, max: 1, step: 0.01 }), } export type VolumeParams = typeof VolumeParams diff --git a/src/tests/browser/render-mesh.ts b/src/tests/browser/render-mesh.ts index 6722814452a39e4803af10838c07d7816e40499a..7ba18624d3bd25771e5edcf028ed6e7aaf62d571 100644 --- a/src/tests/browser/render-mesh.ts +++ b/src/tests/browser/render-mesh.ts @@ -10,10 +10,9 @@ import { MeshBuilder } from 'mol-geo/geometry/mesh/mesh-builder'; import { Sphere } from 'mol-geo/primitive/sphere'; import { Mat4 } from 'mol-math/linear-algebra'; import { Mesh } from 'mol-geo/geometry/mesh/mesh'; -import { Geometry } from 'mol-geo/geometry/geometry'; -import { createMeshRenderObject } from 'mol-gl/render-object'; import { Representation } from 'mol-repr/representation'; import { Color } from 'mol-util/color'; +import { createRenderObject } from 'mol-gl/render-object'; const parent = document.getElementById('app')! parent.style.width = '100%' @@ -33,9 +32,9 @@ const sphere = Sphere(2) MeshBuilder.addPrimitive(builderState, t, sphere) const mesh = MeshBuilder.getMesh(builderState) -const values = Mesh.createValuesSimple(mesh, {}, Color(0xFF0000)) -const state = Geometry.createRenderableState() -const renderObject = createMeshRenderObject(values, state) +const values = Mesh.Utils.createValuesSimple(mesh, {}, Color(0xFF0000), 1) +const state = Mesh.Utils.createRenderableState({}) +const renderObject = createRenderObject('mesh', values, state) const repr = Representation.fromRenderObject('sphere-mesh', renderObject) canvas3d.add(repr) diff --git a/src/tests/browser/render-spheres.ts b/src/tests/browser/render-spheres.ts index bd5bbc08bd582684b088839353ac99eff0598747..d17e32eb5250a57ee4376f759b57c7d22a96af77 100644 --- a/src/tests/browser/render-spheres.ts +++ b/src/tests/browser/render-spheres.ts @@ -7,11 +7,10 @@ import './index.html' import { Canvas3D } from 'mol-canvas3d/canvas3d'; import { SpheresBuilder } from 'mol-geo/geometry/spheres/spheres-builder'; -import { Geometry } from 'mol-geo/geometry/geometry'; -import { createSpheresRenderObject } from 'mol-gl/render-object'; import { Representation } from 'mol-repr/representation'; import { Spheres } from 'mol-geo/geometry/spheres/spheres'; import { Color } from 'mol-util/color'; +import { createRenderObject } from 'mol-gl/render-object'; const parent = document.getElementById('app')! parent.style.width = '100%' @@ -32,9 +31,9 @@ function spheresRepr() { spheresBuilder.add(-4, 1, 0, 0) const spheres = spheresBuilder.getSpheres() - const values = Spheres.createValuesSimple(spheres, {}, Color(0xFF0000), 1) - const state = Geometry.createRenderableState() - const renderObject = createSpheresRenderObject(values, state) + const values = Spheres.Utils.createValuesSimple(spheres, {}, Color(0xFF0000), 1) + const state = Spheres.Utils.createRenderableState({}) + const renderObject = createRenderObject('spheres', values, state) console.log(renderObject) const repr = Representation.fromRenderObject('spheres', renderObject) return repr diff --git a/src/tests/browser/render-text.ts b/src/tests/browser/render-text.ts index 5b98512563f042bb2cddfd7e79dd4fb47890d4b9..a299d3cefae15e1c68d64b835462b4893e3a31a0 100644 --- a/src/tests/browser/render-text.ts +++ b/src/tests/browser/render-text.ts @@ -6,14 +6,13 @@ import './index.html' import { Canvas3D } from 'mol-canvas3d/canvas3d'; -import { Geometry } from 'mol-geo/geometry/geometry'; import { TextBuilder } from 'mol-geo/geometry/text/text-builder'; import { Text } from 'mol-geo/geometry/text/text'; import { ParamDefinition as PD } from 'mol-util/param-definition'; import { Color } from 'mol-util/color'; -import { createTextRenderObject, createSpheresRenderObject } from 'mol-gl/render-object'; import { Representation } from 'mol-repr/representation'; import { SpheresBuilder } from 'mol-geo/geometry/spheres/spheres-builder'; +import { createRenderObject } from 'mol-gl/render-object'; import { Spheres } from 'mol-geo/geometry/spheres/spheres'; const parent = document.getElementById('app')! @@ -45,9 +44,9 @@ function textRepr() { textBuilder.add('αβγ Å', 0, -2, 0, 0) const text = textBuilder.getText() - const values = Text.createValuesSimple(text, props, Color(0xFFDD00), 1) - const state = Text.createRenderableState(props) - const renderObject = createTextRenderObject(values, state) + const values = Text.Utils.createValuesSimple(text, props, Color(0xFFDD00), 1) + const state = Text.Utils.createRenderableState(props) + const renderObject = createRenderObject('text', values, state) console.log('text', renderObject) const repr = Representation.fromRenderObject('text', renderObject) return repr @@ -60,9 +59,9 @@ function spheresRepr() { spheresBuilder.add(-4, 1, 0, 0) const spheres = spheresBuilder.getSpheres() - const values = Spheres.createValuesSimple(spheres, {}, Color(0xFF0000), 0.2) - const state = Geometry.createRenderableState() - const renderObject = createSpheresRenderObject(values, state) + const values = Spheres.Utils.createValuesSimple(spheres, {}, Color(0xFF0000), 0.2) + const state = Spheres.Utils.createRenderableState({}) + const renderObject = createRenderObject('spheres', values, state) console.log('spheres', renderObject) const repr = Representation.fromRenderObject('spheres', renderObject) return repr