Skip to content
Snippets Groups Projects
Commit ca5bf7f3 authored by Alexander Rose's avatar Alexander Rose
Browse files

tweaked gausian surface resolution handling

parent 8ed555aa
No related branches found
No related tags found
No related merge requests found
......@@ -70,7 +70,7 @@ export async function StructureView(app: App, viewer: Viewer, models: ReadonlyAr
const active: { [k: string]: boolean } = {
cartoon: true,
point: false,
surface: true,
surface: false,
ballAndStick: false,
carbohydrate: false,
spacefill: false,
......
......@@ -13,6 +13,7 @@ import { Loci } from 'mol-model/loci';
import { PickingId } from '../../../geometry/picking';
import { Task } from 'mol-task';
import { DefaultGaussianWireframeProps, GaussianWireframeVisual } from '../visual/gaussian-surface-wireframe';
import { getQualityProps } from '../../util';
export const DefaultSurfaceProps = {
...DefaultGaussianSurfaceProps,
......@@ -41,8 +42,9 @@ export function SurfaceRepresentation(): SurfaceRepresentation {
return { ...gaussianSurfaceRepr.props, ...gaussianWireframeRepr.props, visuals: currentProps.visuals }
},
createOrUpdate: (props: Partial<SurfaceProps> = {}, structure?: Structure) => {
currentProps = Object.assign({}, DefaultSurfaceProps, currentProps, props)
if (structure) currentStructure = structure
const qualityProps = getQualityProps(Object.assign({}, currentProps, props), currentStructure)
currentProps = Object.assign({}, DefaultSurfaceProps, currentProps, props, qualityProps)
return Task.create('Creating SurfaceRepresentation', async ctx => {
if (currentProps.visuals.surface) await gaussianSurfaceRepr.createOrUpdate(currentProps, currentStructure).runInContext(ctx)
if (currentProps.visuals.wireframe) await gaussianWireframeRepr.createOrUpdate(currentProps, currentStructure).runInContext(ctx)
......
......@@ -63,7 +63,7 @@ export function GaussianDensityPointVisual(): UnitsVisual<GaussianDensityPointPr
getLoci: () => EmptyLoci,
mark: () => false,
setUpdateState: (state: VisualUpdateState, newProps: GaussianDensityPointProps, currentProps: GaussianDensityPointProps) => {
if (newProps.resolutionFactor !== currentProps.resolutionFactor) state.createGeometry = true
if (newProps.resolution !== currentProps.resolution) state.createGeometry = true
if (newProps.radiusOffset !== currentProps.radiusOffset) state.createGeometry = true
if (newProps.smoothness !== currentProps.smoothness) state.createGeometry = true
}
......
......@@ -45,7 +45,7 @@ export function GaussianSurfaceVisual(): UnitsVisual<GaussianSurfaceProps> {
getLoci: getElementLoci,
mark: markElement,
setUpdateState: (state: VisualUpdateState, newProps: GaussianSurfaceProps, currentProps: GaussianSurfaceProps) => {
if (newProps.resolutionFactor !== currentProps.resolutionFactor) state.createGeometry = true
if (newProps.resolution !== currentProps.resolution) state.createGeometry = true
if (newProps.radiusOffset !== currentProps.radiusOffset) state.createGeometry = true
if (newProps.smoothness !== currentProps.smoothness) state.createGeometry = true
}
......
......@@ -43,7 +43,7 @@ export function GaussianWireframeVisual(): UnitsVisual<GaussianWireframeProps> {
getLoci: getElementLoci,
mark: markElement,
setUpdateState: (state: VisualUpdateState, newProps: GaussianWireframeProps, currentProps: GaussianWireframeProps) => {
if (newProps.resolutionFactor !== currentProps.resolutionFactor) state.createGeometry = true
if (newProps.resolution !== currentProps.resolution) state.createGeometry = true
if (newProps.radiusOffset !== currentProps.radiusOffset) state.createGeometry = true
if (newProps.smoothness !== currentProps.smoothness) state.createGeometry = true
}
......
......@@ -13,6 +13,7 @@ export interface QualityProps {
detail: number
radialSegments: number
linearSegments: number
resolution: number
}
export function getQualityProps(props: Partial<QualityProps>, structure?: Structure) {
......@@ -20,6 +21,7 @@ export function getQualityProps(props: Partial<QualityProps>, structure?: Struct
let detail = defaults(props.detail, 1)
let radialSegments = defaults(props.radialSegments, 12)
let linearSegments = defaults(props.linearSegments, 8)
let resolution = defaults(props.resolution, 1)
if (quality === 'auto' && structure) {
let score = structure.elementCount
......@@ -40,26 +42,31 @@ export function getQualityProps(props: Partial<QualityProps>, structure?: Struct
detail = 3
radialSegments = 36
linearSegments = 18
resolution = 0.5
break
case 'high':
detail = 2
radialSegments = 24
linearSegments = 12
resolution = 1.0
break
case 'medium':
detail = 1
radialSegments = 12
linearSegments = 8
resolution = 1.5
break
case 'low':
detail = 0
radialSegments = 8
linearSegments = 3
resolution = 3
break
case 'lowest':
detail = 0
radialSegments = 4
linearSegments = 2
resolution = 6
break
case 'custom':
// use defaults or given props as set above
......@@ -69,6 +76,7 @@ export function getQualityProps(props: Partial<QualityProps>, structure?: Struct
return {
detail,
radialSegments,
linearSegments
linearSegments,
resolution
}
}
\ No newline at end of file
......@@ -11,20 +11,16 @@ import { PositionData, DensityData } from './common';
import { OrderedSet } from 'mol-data/int';
export const DefaultGaussianDensityProps = {
resolutionFactor: 6,
resolution: 1,
radiusOffset: 0,
smoothness: 1.5,
box: Box3D.empty() // TODO remove
smoothness: 1.5
}
export type GaussianDensityProps = typeof DefaultGaussianDensityProps
function getDelta(box: Box3D, resolutionFactor: number) {
function getDelta(box: Box3D, resolution: number) {
const extent = Vec3.sub(Vec3.zero(), box.max, box.min)
const n = Math.pow(Math.pow(2, resolutionFactor), 3)
const f = (extent[0] * extent[1] * extent[2]) / n
const s = Math.pow(f, 1 / 3)
const size = Vec3.zero()
Vec3.ceil(size, Vec3.scale(size, extent, s))
Vec3.ceil(size, Vec3.scale(size, extent, resolution))
const delta = Vec3.div(Vec3.zero(), extent, size)
return delta
}
......@@ -34,7 +30,7 @@ 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> {
const { resolutionFactor, radiusOffset, smoothness } = props
const { resolution, radiusOffset, smoothness } = props
const { indices, x, y, z } = position
const n = OrderedSet.size(indices)
......@@ -47,7 +43,7 @@ export async function GaussianDensity(ctx: RuntimeContext, position: PositionDat
const extent = Vec3.sub(Vec3.zero(), expandedBox.max, expandedBox.min)
const min = expandedBox.min
const delta = getDelta(Box3D.expand(Box3D.empty(), props.box, Vec3.create(pad, pad, pad)), resolutionFactor)
const delta = getDelta(Box3D.expand(Box3D.empty(), box, Vec3.create(pad, pad, pad)), resolution)
const dim = Vec3.zero()
Vec3.ceil(dim, Vec3.mul(dim, extent, delta))
......
......@@ -11,7 +11,7 @@ import { Task, RuntimeContext } from 'mol-task';
import { DensityData } from 'mol-math/geometry';
export const DefaultGaussianDensityProps = {
resolutionFactor: 6,
resolution: 1,
radiusOffset: 0,
smoothness: 1.5,
}
......@@ -43,12 +43,12 @@ export function computeUnitGaussianDensity(unit: Unit, props: GaussianDensityPro
}
return Task.create('Gaussian Density', async ctx => {
return await GaussianDensity(ctx, position, unit.lookup3d.boundary.box, radius, { ...props, box: unit.lookup3d.boundary.box });
return await GaussianDensity(ctx, position, unit.lookup3d.boundary.box, radius, props);
});
}
export async function computeUnitGaussianDensityCached(unit: Unit, props: GaussianDensityProps, cache: Map<string, DensityData>, ctx?: RuntimeContext) {
const key = `${props.radiusOffset}|${props.resolutionFactor}|${props.smoothness}`
const key = `${props.radiusOffset}|${props.resolution}|${props.smoothness}`
let density = cache.get(key)
if (density) return density
density = ctx ? await computeUnitGaussianDensity(unit, props).runInContext(ctx) : await computeUnitGaussianDensity(unit, props).run()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment