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

added structure gaussian surface complex-visual

parent 34798179
No related branches found
No related tags found
No related merge requests found
...@@ -4,17 +4,18 @@ ...@@ -4,17 +4,18 @@
* @author Alexander Rose <alexander.rose@weirdbyte.de> * @author Alexander Rose <alexander.rose@weirdbyte.de>
*/ */
import { GaussianSurfaceMeshVisual, GaussianSurfaceTextureMeshVisual, GaussianSurfaceMeshParams } from '../visual/gaussian-surface-mesh'; import { GaussianSurfaceMeshVisual, GaussianSurfaceTextureMeshVisual, GaussianSurfaceMeshParams, StructureGaussianSurfaceMeshParams, StructureGaussianSurfaceMeshVisual } from '../visual/gaussian-surface-mesh';
import { UnitsRepresentation } from '../units-representation'; import { UnitsRepresentation } from '../units-representation';
import { GaussianWireframeVisual, GaussianWireframeParams } from '../visual/gaussian-surface-wireframe'; import { GaussianWireframeVisual, GaussianWireframeParams } from '../visual/gaussian-surface-wireframe';
import { ParamDefinition as PD } from '../../../mol-util/param-definition'; import { ParamDefinition as PD } from '../../../mol-util/param-definition';
import { StructureRepresentation, StructureRepresentationProvider, StructureRepresentationStateBuilder } from '../representation'; import { StructureRepresentation, StructureRepresentationProvider, StructureRepresentationStateBuilder, ComplexRepresentation } from '../representation';
import { Representation, RepresentationParamsGetter, RepresentationContext } from '../../../mol-repr/representation'; import { Representation, RepresentationParamsGetter, RepresentationContext } from '../../../mol-repr/representation';
import { ThemeRegistryContext } from '../../../mol-theme/theme'; import { ThemeRegistryContext } from '../../../mol-theme/theme';
import { Structure } from '../../../mol-model/structure'; import { Structure } from '../../../mol-model/structure';
const GaussianSurfaceVisuals = { const GaussianSurfaceVisuals = {
'gaussian-surface-mesh': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<Structure, GaussianSurfaceMeshParams>) => UnitsRepresentation('Gaussian surface', ctx, getParams, GaussianSurfaceMeshVisual), 'gaussian-surface-mesh': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<Structure, GaussianSurfaceMeshParams>) => UnitsRepresentation('Gaussian surface', ctx, getParams, GaussianSurfaceMeshVisual),
'structure-gaussian-surface-mesh': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<Structure, StructureGaussianSurfaceMeshParams>) => ComplexRepresentation('Structure-Gaussian surface', ctx, getParams, StructureGaussianSurfaceMeshVisual),
'gaussian-surface-texture-mesh': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<Structure, GaussianSurfaceMeshParams>) => UnitsRepresentation('Gaussian surface', ctx, getParams, GaussianSurfaceTextureMeshVisual), 'gaussian-surface-texture-mesh': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<Structure, GaussianSurfaceMeshParams>) => UnitsRepresentation('Gaussian surface', ctx, getParams, GaussianSurfaceTextureMeshVisual),
'gaussian-wireframe': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<Structure, GaussianWireframeParams>) => UnitsRepresentation('Gaussian wireframe', ctx, getParams, GaussianWireframeVisual), 'gaussian-wireframe': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<Structure, GaussianWireframeParams>) => UnitsRepresentation('Gaussian wireframe', ctx, getParams, GaussianWireframeVisual),
} }
......
...@@ -12,7 +12,7 @@ import { Theme } from '../../../mol-theme/theme'; ...@@ -12,7 +12,7 @@ import { Theme } from '../../../mol-theme/theme';
import { Points } from '../../../mol-geo/geometry/points/points'; import { Points } from '../../../mol-geo/geometry/points/points';
import { PointsBuilder } from '../../../mol-geo/geometry/points/points-builder'; import { PointsBuilder } from '../../../mol-geo/geometry/points/points-builder';
import { Vec3 } from '../../../mol-math/linear-algebra'; import { Vec3 } from '../../../mol-math/linear-algebra';
import { StructureElementIterator, getElementLoci, eachElement } from './util/element'; import { ElementIterator, getElementLoci, eachElement } from './util/element';
import { VisualUpdateState } from '../../util'; import { VisualUpdateState } from '../../util';
export const ElementPointParams = { export const ElementPointParams = {
...@@ -46,7 +46,7 @@ export function ElementPointVisual(materialId: number): UnitsVisual<ElementPoint ...@@ -46,7 +46,7 @@ export function ElementPointVisual(materialId: number): UnitsVisual<ElementPoint
return UnitsPointsVisual<ElementPointParams>({ return UnitsPointsVisual<ElementPointParams>({
defaultProps: PD.getDefaultValues(ElementPointParams), defaultProps: PD.getDefaultValues(ElementPointParams),
createGeometry: createElementPoint, createGeometry: createElementPoint,
createLocationIterator: StructureElementIterator.fromGroup, createLocationIterator: ElementIterator.fromGroup,
getLoci: getElementLoci, getLoci: getElementLoci,
eachLocation: eachElement, eachLocation: eachElement,
setUpdateState: (state: VisualUpdateState, newProps: PD.Values<ElementPointParams>, currentProps: PD.Values<ElementPointParams>) => { setUpdateState: (state: VisualUpdateState, newProps: PD.Values<ElementPointParams>, currentProps: PD.Values<ElementPointParams>) => {
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
import { ParamDefinition as PD } from '../../../mol-util/param-definition'; import { ParamDefinition as PD } from '../../../mol-util/param-definition';
import { UnitsMeshParams, UnitsSpheresParams, UnitsVisual, UnitsSpheresVisual, UnitsMeshVisual } from '../units-visual'; import { UnitsMeshParams, UnitsSpheresParams, UnitsVisual, UnitsSpheresVisual, UnitsMeshVisual } from '../units-visual';
import { WebGLContext } from '../../../mol-gl/webgl/context'; import { WebGLContext } from '../../../mol-gl/webgl/context';
import { createElementSphereImpostor, StructureElementIterator, getElementLoci, eachElement, createElementSphereMesh } from './util/element'; import { createElementSphereImpostor, ElementIterator, getElementLoci, eachElement, createElementSphereMesh } from './util/element';
import { VisualUpdateState } from '../../util'; import { VisualUpdateState } from '../../util';
export const ElementSphereParams = { export const ElementSphereParams = {
...@@ -28,7 +28,7 @@ export function ElementSphereImpostorVisual(materialId: number): UnitsVisual<Ele ...@@ -28,7 +28,7 @@ export function ElementSphereImpostorVisual(materialId: number): UnitsVisual<Ele
return UnitsSpheresVisual<ElementSphereParams>({ return UnitsSpheresVisual<ElementSphereParams>({
defaultProps: PD.getDefaultValues(ElementSphereParams), defaultProps: PD.getDefaultValues(ElementSphereParams),
createGeometry: createElementSphereImpostor, createGeometry: createElementSphereImpostor,
createLocationIterator: StructureElementIterator.fromGroup, createLocationIterator: ElementIterator.fromGroup,
getLoci: getElementLoci, getLoci: getElementLoci,
eachLocation: eachElement, eachLocation: eachElement,
setUpdateState: (state: VisualUpdateState, newProps: PD.Values<ElementSphereParams>, currentProps: PD.Values<ElementSphereParams>) => { setUpdateState: (state: VisualUpdateState, newProps: PD.Values<ElementSphereParams>, currentProps: PD.Values<ElementSphereParams>) => {
...@@ -43,7 +43,7 @@ export function ElementSphereMeshVisual(materialId: number): UnitsVisual<Element ...@@ -43,7 +43,7 @@ export function ElementSphereMeshVisual(materialId: number): UnitsVisual<Element
return UnitsMeshVisual<ElementSphereParams>({ return UnitsMeshVisual<ElementSphereParams>({
defaultProps: PD.getDefaultValues(ElementSphereParams), defaultProps: PD.getDefaultValues(ElementSphereParams),
createGeometry: createElementSphereMesh, createGeometry: createElementSphereMesh,
createLocationIterator: StructureElementIterator.fromGroup, createLocationIterator: ElementIterator.fromGroup,
getLoci: getElementLoci, getLoci: getElementLoci,
eachLocation: eachElement, eachLocation: eachElement,
setUpdateState: (state: VisualUpdateState, newProps: PD.Values<ElementSphereParams>, currentProps: PD.Values<ElementSphereParams>) => { setUpdateState: (state: VisualUpdateState, newProps: PD.Values<ElementSphereParams>, currentProps: PD.Values<ElementSphereParams>) => {
......
...@@ -6,20 +6,21 @@ ...@@ -6,20 +6,21 @@
import { ParamDefinition as PD } from '../../../mol-util/param-definition'; import { ParamDefinition as PD } from '../../../mol-util/param-definition';
import { UnitsMeshParams, UnitsTextureMeshParams, UnitsVisual, UnitsMeshVisual, UnitsTextureMeshVisual } from '../units-visual'; import { UnitsMeshParams, UnitsTextureMeshParams, UnitsVisual, UnitsMeshVisual, UnitsTextureMeshVisual } from '../units-visual';
import { GaussianDensityParams, computeUnitGaussianDensity, GaussianDensityTextureProps, computeUnitGaussianDensityTexture2d, GaussianDensityProps } from './util/gaussian'; import { GaussianDensityParams, computeUnitGaussianDensity, GaussianDensityTextureProps, computeUnitGaussianDensityTexture2d, GaussianDensityProps, computeStructureGaussianDensity } from './util/gaussian';
import { WebGLContext } from '../../../mol-gl/webgl/context'; import { WebGLContext } from '../../../mol-gl/webgl/context';
import { VisualContext } from '../../visual'; import { VisualContext } from '../../visual';
import { Unit, Structure } from '../../../mol-model/structure'; import { Unit, Structure } from '../../../mol-model/structure';
import { Theme } from '../../../mol-theme/theme'; import { Theme } from '../../../mol-theme/theme';
import { Mesh } from '../../../mol-geo/geometry/mesh/mesh'; import { Mesh } from '../../../mol-geo/geometry/mesh/mesh';
import { computeMarchingCubesMesh } from '../../../mol-geo/util/marching-cubes/algorithm'; import { computeMarchingCubesMesh } from '../../../mol-geo/util/marching-cubes/algorithm';
import { StructureElementIterator, getElementLoci, eachElement } from './util/element'; import { ElementIterator, getElementLoci, eachElement, getSerialElementLoci, eachSerialElement } from './util/element';
import { VisualUpdateState } from '../../util'; import { VisualUpdateState } from '../../util';
import { TextureMesh } from '../../../mol-geo/geometry/texture-mesh/texture-mesh'; import { TextureMesh } from '../../../mol-geo/geometry/texture-mesh/texture-mesh';
import { calcActiveVoxels } from '../../../mol-gl/compute/marching-cubes/active-voxels'; import { calcActiveVoxels } from '../../../mol-gl/compute/marching-cubes/active-voxels';
import { createHistogramPyramid } from '../../../mol-gl/compute/histogram-pyramid/reduction'; import { createHistogramPyramid } from '../../../mol-gl/compute/histogram-pyramid/reduction';
import { createIsosurfaceBuffers } from '../../../mol-gl/compute/marching-cubes/isosurface'; import { createIsosurfaceBuffers } from '../../../mol-gl/compute/marching-cubes/isosurface';
import { Sphere3D } from '../../../mol-math/geometry'; import { Sphere3D } from '../../../mol-math/geometry';
import { ComplexVisual, ComplexMeshParams, ComplexMeshVisual } from '../complex-visual';
export const GaussianSurfaceMeshParams = { export const GaussianSurfaceMeshParams = {
...UnitsMeshParams, ...UnitsMeshParams,
...@@ -56,7 +57,7 @@ export function GaussianSurfaceMeshVisual(materialId: number): UnitsVisual<Gauss ...@@ -56,7 +57,7 @@ export function GaussianSurfaceMeshVisual(materialId: number): UnitsVisual<Gauss
return UnitsMeshVisual<GaussianSurfaceMeshParams>({ return UnitsMeshVisual<GaussianSurfaceMeshParams>({
defaultProps: PD.getDefaultValues(GaussianSurfaceMeshParams), defaultProps: PD.getDefaultValues(GaussianSurfaceMeshParams),
createGeometry: createGaussianSurfaceMesh, createGeometry: createGaussianSurfaceMesh,
createLocationIterator: StructureElementIterator.fromGroup, createLocationIterator: ElementIterator.fromGroup,
getLoci: getElementLoci, getLoci: getElementLoci,
eachLocation: eachElement, eachLocation: eachElement,
setUpdateState: (state: VisualUpdateState, newProps: PD.Values<GaussianSurfaceMeshParams>, currentProps: PD.Values<GaussianSurfaceMeshParams>) => { setUpdateState: (state: VisualUpdateState, newProps: PD.Values<GaussianSurfaceMeshParams>, currentProps: PD.Values<GaussianSurfaceMeshParams>) => {
...@@ -71,6 +72,49 @@ export function GaussianSurfaceMeshVisual(materialId: number): UnitsVisual<Gauss ...@@ -71,6 +72,49 @@ export function GaussianSurfaceMeshVisual(materialId: number): UnitsVisual<Gauss
// //
export const StructureGaussianSurfaceMeshParams = {
...ComplexMeshParams,
...GaussianDensityParams,
ignoreHydrogens: PD.Boolean(false),
}
export type StructureGaussianSurfaceMeshParams = typeof StructureGaussianSurfaceMeshParams
async function createStructureGaussianSurfaceMesh(ctx: VisualContext, structure: Structure, theme: Theme, props: GaussianDensityProps, mesh?: Mesh): Promise<Mesh> {
const { smoothness } = props
const { transform, field, idField } = await computeStructureGaussianDensity(structure, props, ctx.webgl).runInContext(ctx.runtime)
const params = {
isoLevel: Math.exp(-smoothness),
scalarField: field,
idField
}
const surface = await computeMarchingCubesMesh(params, mesh).runAsChild(ctx.runtime)
Mesh.transformImmediate(surface, transform)
Mesh.uniformTriangleGroup(surface)
return surface
}
export function StructureGaussianSurfaceMeshVisual(materialId: number): ComplexVisual<StructureGaussianSurfaceMeshParams> {
return ComplexMeshVisual<StructureGaussianSurfaceMeshParams>({
defaultProps: PD.getDefaultValues(StructureGaussianSurfaceMeshParams),
createGeometry: createStructureGaussianSurfaceMesh,
createLocationIterator: ElementIterator.fromStructure,
getLoci: getSerialElementLoci,
eachLocation: eachSerialElement,
setUpdateState: (state: VisualUpdateState, newProps: PD.Values<GaussianSurfaceMeshParams>, currentProps: PD.Values<GaussianSurfaceMeshParams>) => {
if (newProps.resolution !== currentProps.resolution) state.createGeometry = true
if (newProps.radiusOffset !== currentProps.radiusOffset) state.createGeometry = true
if (newProps.smoothness !== currentProps.smoothness) state.createGeometry = true
if (newProps.useGpu !== currentProps.useGpu) state.createGeometry = true
if (newProps.ignoreHydrogens !== currentProps.ignoreHydrogens) state.createGeometry = true
}
}, materialId)
}
//
async function createGaussianSurfaceTextureMesh(ctx: VisualContext, unit: Unit, structure: Structure, theme: Theme, props: GaussianDensityTextureProps, textureMesh?: TextureMesh): Promise<TextureMesh> { async function createGaussianSurfaceTextureMesh(ctx: VisualContext, unit: Unit, structure: Structure, theme: Theme, props: GaussianDensityTextureProps, textureMesh?: TextureMesh): Promise<TextureMesh> {
if (!ctx.webgl) throw new Error('webgl context required to create gaussian surface texture-mesh') if (!ctx.webgl) throw new Error('webgl context required to create gaussian surface texture-mesh')
const isoLevel = Math.exp(-props.smoothness) const isoLevel = Math.exp(-props.smoothness)
...@@ -102,7 +146,7 @@ export function GaussianSurfaceTextureMeshVisual(materialId: number): UnitsVisua ...@@ -102,7 +146,7 @@ export function GaussianSurfaceTextureMeshVisual(materialId: number): UnitsVisua
return UnitsTextureMeshVisual<GaussianSurfaceMeshParams>({ return UnitsTextureMeshVisual<GaussianSurfaceMeshParams>({
defaultProps: PD.getDefaultValues(GaussianSurfaceMeshParams), defaultProps: PD.getDefaultValues(GaussianSurfaceMeshParams),
createGeometry: createGaussianSurfaceTextureMesh, createGeometry: createGaussianSurfaceTextureMesh,
createLocationIterator: StructureElementIterator.fromGroup, createLocationIterator: ElementIterator.fromGroup,
getLoci: getElementLoci, getLoci: getElementLoci,
eachLocation: eachElement, eachLocation: eachElement,
setUpdateState: (state: VisualUpdateState, newProps: PD.Values<GaussianSurfaceMeshParams>, currentProps: PD.Values<GaussianSurfaceMeshParams>) => { setUpdateState: (state: VisualUpdateState, newProps: PD.Values<GaussianSurfaceMeshParams>, currentProps: PD.Values<GaussianSurfaceMeshParams>) => {
......
...@@ -12,7 +12,7 @@ import { Lines } from '../../../mol-geo/geometry/lines/lines'; ...@@ -12,7 +12,7 @@ import { Lines } from '../../../mol-geo/geometry/lines/lines';
import { computeUnitGaussianDensity, GaussianDensityParams, GaussianDensityProps } from './util/gaussian'; import { computeUnitGaussianDensity, GaussianDensityParams, GaussianDensityProps } from './util/gaussian';
import { computeMarchingCubesLines } from '../../../mol-geo/util/marching-cubes/algorithm'; import { computeMarchingCubesLines } from '../../../mol-geo/util/marching-cubes/algorithm';
import { UnitsLinesParams, UnitsVisual, UnitsLinesVisual } from '../units-visual'; import { UnitsLinesParams, UnitsVisual, UnitsLinesVisual } from '../units-visual';
import { StructureElementIterator, getElementLoci, eachElement } from './util/element'; import { ElementIterator, getElementLoci, eachElement } from './util/element';
import { VisualUpdateState } from '../../util'; import { VisualUpdateState } from '../../util';
async function createGaussianWireframe(ctx: VisualContext, unit: Unit, structure: Structure, theme: Theme, props: GaussianDensityProps, lines?: Lines): Promise<Lines> { async function createGaussianWireframe(ctx: VisualContext, unit: Unit, structure: Structure, theme: Theme, props: GaussianDensityProps, lines?: Lines): Promise<Lines> {
...@@ -43,7 +43,7 @@ export function GaussianWireframeVisual(materialId: number): UnitsVisual<Gaussia ...@@ -43,7 +43,7 @@ export function GaussianWireframeVisual(materialId: number): UnitsVisual<Gaussia
return UnitsLinesVisual<GaussianWireframeParams>({ return UnitsLinesVisual<GaussianWireframeParams>({
defaultProps: PD.getDefaultValues(GaussianWireframeParams), defaultProps: PD.getDefaultValues(GaussianWireframeParams),
createGeometry: createGaussianWireframe, createGeometry: createGaussianWireframe,
createLocationIterator: StructureElementIterator.fromGroup, createLocationIterator: ElementIterator.fromGroup,
getLoci: getElementLoci, getLoci: getElementLoci,
eachLocation: eachElement, eachLocation: eachElement,
setUpdateState: (state: VisualUpdateState, newProps: PD.Values<GaussianWireframeParams>, currentProps: PD.Values<GaussianWireframeParams>) => { setUpdateState: (state: VisualUpdateState, newProps: PD.Values<GaussianWireframeParams>, currentProps: PD.Values<GaussianWireframeParams>) => {
......
...@@ -13,7 +13,7 @@ import { Theme } from '../../../mol-theme/theme'; ...@@ -13,7 +13,7 @@ import { Theme } from '../../../mol-theme/theme';
import { Mesh } from '../../../mol-geo/geometry/mesh/mesh'; import { Mesh } from '../../../mol-geo/geometry/mesh/mesh';
import { computeUnitMolecularSurface, MolecularSurfaceProps } from './util/molecular-surface'; import { computeUnitMolecularSurface, MolecularSurfaceProps } from './util/molecular-surface';
import { computeMarchingCubesMesh } from '../../../mol-geo/util/marching-cubes/algorithm'; import { computeMarchingCubesMesh } from '../../../mol-geo/util/marching-cubes/algorithm';
import { StructureElementIterator, getElementLoci, eachElement } from './util/element'; import { ElementIterator, getElementLoci, eachElement } from './util/element';
import { VisualUpdateState } from '../../util'; import { VisualUpdateState } from '../../util';
export const MolecularSurfaceMeshParams = { export const MolecularSurfaceMeshParams = {
...@@ -46,7 +46,7 @@ export function MolecularSurfaceMeshVisual(materialId: number): UnitsVisual<Mole ...@@ -46,7 +46,7 @@ export function MolecularSurfaceMeshVisual(materialId: number): UnitsVisual<Mole
return UnitsMeshVisual<MolecularSurfaceMeshParams>({ return UnitsMeshVisual<MolecularSurfaceMeshParams>({
defaultProps: PD.getDefaultValues(MolecularSurfaceMeshParams), defaultProps: PD.getDefaultValues(MolecularSurfaceMeshParams),
createGeometry: createMolecularSurfaceMesh, createGeometry: createMolecularSurfaceMesh,
createLocationIterator: StructureElementIterator.fromGroup, createLocationIterator: ElementIterator.fromGroup,
getLoci: getElementLoci, getLoci: getElementLoci,
eachLocation: eachElement, eachLocation: eachElement,
setUpdateState: (state: VisualUpdateState, newProps: PD.Values<MolecularSurfaceMeshParams>, currentProps: PD.Values<MolecularSurfaceMeshParams>) => { setUpdateState: (state: VisualUpdateState, newProps: PD.Values<MolecularSurfaceMeshParams>, currentProps: PD.Values<MolecularSurfaceMeshParams>) => {
......
...@@ -16,7 +16,7 @@ import { PolymerBackboneIterator } from './util/polymer'; ...@@ -16,7 +16,7 @@ import { PolymerBackboneIterator } from './util/polymer';
import { OrderedSet } from '../../../mol-data/int'; import { OrderedSet } from '../../../mol-data/int';
import { addCylinder } from '../../../mol-geo/geometry/mesh/builder/cylinder'; import { addCylinder } from '../../../mol-geo/geometry/mesh/builder/cylinder';
import { UnitsMeshParams, UnitsVisual, UnitsMeshVisual } from '../units-visual'; import { UnitsMeshParams, UnitsVisual, UnitsMeshVisual } from '../units-visual';
import { StructureElementIterator, getElementLoci, eachElement } from './util/element'; import { ElementIterator, getElementLoci, eachElement } from './util/element';
import { VisualUpdateState } from '../../util'; import { VisualUpdateState } from '../../util';
export const PolymerBackboneCylinderParams = { export const PolymerBackboneCylinderParams = {
...@@ -71,7 +71,7 @@ export function PolymerBackboneVisual(materialId: number): UnitsVisual<PolymerBa ...@@ -71,7 +71,7 @@ export function PolymerBackboneVisual(materialId: number): UnitsVisual<PolymerBa
defaultProps: PD.getDefaultValues(PolymerBackboneParams), defaultProps: PD.getDefaultValues(PolymerBackboneParams),
createGeometry: createPolymerBackboneCylinderMesh, createGeometry: createPolymerBackboneCylinderMesh,
// TODO create a specialized location iterator // TODO create a specialized location iterator
createLocationIterator: StructureElementIterator.fromGroup, createLocationIterator: ElementIterator.fromGroup,
getLoci: getElementLoci, getLoci: getElementLoci,
eachLocation: eachElement, eachLocation: eachElement,
setUpdateState: (state: VisualUpdateState, newProps: PD.Values<PolymerBackboneParams>, currentProps: PD.Values<PolymerBackboneParams>) => { setUpdateState: (state: VisualUpdateState, newProps: PD.Values<PolymerBackboneParams>, currentProps: PD.Values<PolymerBackboneParams>) => {
......
...@@ -138,37 +138,69 @@ export function getUnitConformationAndRadius(unit: Unit, ignoreHydrogens = false ...@@ -138,37 +138,69 @@ export function getUnitConformationAndRadius(unit: Unit, ignoreHydrogens = false
} }
export function getStructureConformationAndRadius(structure: Structure, ignoreHydrogens = false) { export function getStructureConformationAndRadius(structure: Structure, ignoreHydrogens = false) {
const xs: number[] = []
const ys: number[] = []
const zs: number[] = []
const rs: number[] = []
const id: number[] = []
const l = StructureElement.create() const l = StructureElement.create()
const sizeTheme = PhysicalSizeTheme({}, {}) const sizeTheme = PhysicalSizeTheme({}, {})
let m = 0 let xs: ArrayLike<number>
for (let i = 0, il = structure.units.length; i < il; ++i) { let ys: ArrayLike<number>
const unit = structure.units[i] let zs: ArrayLike<number>
const { elements } = unit let rs: ArrayLike<number>
const { x, y, z } = unit.conformation let id: ArrayLike<number>
l.unit = unit
for (let j = 0, jl = elements.length; j < jl; ++j) { if (ignoreHydrogens) {
const eI = elements[j] const _xs: number[] = []
if (ignoreHydrogens && isHydrogen(unit, eI)) continue const _ys: number[] = []
const _zs: number[] = []
const mj = m + j const _rs: number[] = []
xs[mj] = x(eI) const _id: number[] = []
ys[mj] = y(eI) for (let i = 0, m = 0, il = structure.units.length; i < il; ++i) {
zs[mj] = z(eI) const unit = structure.units[i]
l.element = eI const { elements } = unit
rs[mj] = sizeTheme.size(l) const { x, y, z } = unit.conformation
id[mj] = mj l.unit = unit
for (let j = 0, jl = elements.length; j < jl; ++j) {
const eI = elements[j]
if (ignoreHydrogens && isHydrogen(unit, eI)) continue
_xs.push(x(eI))
_ys.push(y(eI))
_zs.push(z(eI))
l.element = eI
_rs.push(sizeTheme.size(l))
_id.push(m + j)
}
m += elements.length
}
xs = _xs, ys = _ys, zs = _zs, rs = _rs
id = _id
} else {
const { elementCount } = structure
const _xs = new Float32Array(elementCount)
const _ys = new Float32Array(elementCount)
const _zs = new Float32Array(elementCount)
const _rs = new Float32Array(elementCount)
for (let i = 0, m = 0, il = structure.units.length; i < il; ++i) {
const unit = structure.units[i]
const { elements } = unit
const { x, y, z } = unit.conformation
l.unit = unit
for (let j = 0, jl = elements.length; j < jl; ++j) {
const eI = elements[j]
const mj = m + j
_xs[mj] = x(eI)
_ys[mj] = y(eI)
_zs[mj] = z(eI)
l.element = eI
_rs[mj] = sizeTheme.size(l)
}
m += elements.length
} }
m += elements.length xs = _xs, ys = _ys, zs = _zs, rs = _rs
id = fillSerial(new Uint32Array(elementCount))
} }
const position = { indices: OrderedSet.ofRange(0, m), x: xs, y: ys, z: zs, id } const position = { indices: OrderedSet.ofRange(0, id.length), x: xs, y: ys, z: zs, id }
const radius = (index: number) => rs[index] const radius = (index: number) => rs[index]
return { position, radius } return { position, radius }
......
/** /**
* Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info. * Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
* *
* @author Alexander Rose <alexander.rose@weirdbyte.de> * @author Alexander Rose <alexander.rose@weirdbyte.de>
*/ */
...@@ -86,12 +86,12 @@ export function eachElement(loci: Loci, structureGroup: StructureGroup, apply: ( ...@@ -86,12 +86,12 @@ export function eachElement(loci: Loci, structureGroup: StructureGroup, apply: (
const unitIdx = group.unitIndexMap.get(e.unit.id) const unitIdx = group.unitIndexMap.get(e.unit.id)
if (unitIdx !== undefined) { if (unitIdx !== undefined) {
if (Interval.is(e.indices)) { if (Interval.is(e.indices)) {
const start = unitIdx * elementCount + Interval.start(e.indices); const start = unitIdx * elementCount + Interval.start(e.indices)
const end = unitIdx * elementCount + Interval.end(e.indices); const end = unitIdx * elementCount + Interval.end(e.indices)
if (apply(Interval.ofBounds(start, end))) changed = true if (apply(Interval.ofBounds(start, end))) changed = true
} else { } else {
for (let i = 0, _i = e.indices.length; i < _i; i++) { for (let i = 0, _i = e.indices.length; i < _i; i++) {
const idx = unitIdx * elementCount + e.indices[i]; const idx = unitIdx * elementCount + e.indices[i]
if (apply(Interval.ofSingleton(idx))) changed = true if (apply(Interval.ofSingleton(idx))) changed = true
} }
} }
...@@ -105,13 +105,53 @@ export function getElementLoci(pickingId: PickingId, structureGroup: StructureGr ...@@ -105,13 +105,53 @@ export function getElementLoci(pickingId: PickingId, structureGroup: StructureGr
if (id === objectId) { if (id === objectId) {
const { structure, group } = structureGroup const { structure, group } = structureGroup
const unit = group.units[instanceId] const unit = group.units[instanceId]
const indices = OrderedSet.ofSingleton(groupId as StructureElement.UnitIndex); const indices = OrderedSet.ofSingleton(groupId as StructureElement.UnitIndex)
return StructureElement.Loci(structure, [{ unit, indices }]) return StructureElement.Loci(structure, [{ unit, indices }])
} }
return EmptyLoci return EmptyLoci
} }
export namespace StructureElementIterator { //
export function eachSerialElement(loci: Loci, structure: Structure, apply: (interval: Interval) => boolean) {
let changed = false
if (!StructureElement.isLoci(loci)) return false
if (!Structure.areEquivalent(loci.structure, structure)) return false
const { unitElementCount } = structure.serialMapping
for (const e of loci.elements) {
const unitIdx = structure.unitIndexMap.get(e.unit.id)
if (unitIdx !== undefined) {
if (Interval.is(e.indices)) {
const start = unitElementCount[unitIdx] + Interval.start(e.indices)
const end = unitElementCount[unitIdx] + Interval.end(e.indices)
if (apply(Interval.ofBounds(start, end))) changed = true
} else {
for (let i = 0, _i = e.indices.length; i < _i; i++) {
const idx = unitElementCount[unitIdx] + e.indices[i]
if (apply(Interval.ofSingleton(idx))) changed = true
}
}
}
}
return changed
}
export function getSerialElementLoci(pickingId: PickingId, structure: Structure, id: number) {
const { objectId, groupId } = pickingId
if (id === objectId) {
const { unitIndices, unitElementCount } = structure.serialMapping
const unitIdx = unitIndices[groupId]
const unit = structure.units[unitIdx]
const idx = groupId - unitElementCount[unitIdx]
const indices = OrderedSet.ofSingleton(idx as StructureElement.UnitIndex)
return StructureElement.Loci(structure, [{ unit, indices }])
}
return EmptyLoci
}
//
export namespace ElementIterator {
export function fromGroup(group: Unit.SymmetryGroup): LocationIterator { export function fromGroup(group: Unit.SymmetryGroup): LocationIterator {
const groupCount = group.elements.length const groupCount = group.elements.length
const instanceCount = group.units.length const instanceCount = group.units.length
...@@ -124,4 +164,18 @@ export namespace StructureElementIterator { ...@@ -124,4 +164,18 @@ export namespace StructureElementIterator {
} }
return LocationIterator(groupCount, instanceCount, getLocation) return LocationIterator(groupCount, instanceCount, getLocation)
} }
export function fromStructure(structure: Structure): LocationIterator {
const { units, elementCount } = structure
const groupCount = elementCount
const instanceCount = 1
const { unitIndices, elementIndices } = structure.serialMapping
const location = StructureElement.create()
const getLocation = (groupIndex: number) => {
location.unit = units[unitIndices[groupIndex]]
location.element = elementIndices[groupIndex]
return location
}
return LocationIterator(groupCount, instanceCount, getLocation, true)
}
} }
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment