Newer
Older
/**
* Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { Unit, Structure } from 'mol-model/structure';
import { UnitsVisual, VisualUpdateState } from '..';
import { RuntimeContext } from 'mol-task'
import { Mesh } from '../../../geometry/mesh/mesh';
import { UnitsLinesVisual, DefaultUnitsLinesProps } from '../units-visual';
import { StructureElementIterator, getElementLoci, markElement } from './util/element';
import { computeMarchingCubes } from '../../../util/marching-cubes/algorithm';
import { Lines } from '../../../geometry/lines/lines';
import { LinesBuilder } from '../../../geometry/lines/lines-builder';
import { GaussianDensityProps, DefaultGaussianDensityProps } from 'mol-model/structure/structure/unit/gaussian-density';
async function createGaussianWireframe(ctx: RuntimeContext, unit: Unit, structure: Structure, props: GaussianDensityProps, lines?: Lines): Promise<Lines> {
const { smoothness } = props
const { transform, field, idField } = await unit.computeGaussianDensity(props, ctx)
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
const surface = await computeMarchingCubes({
isoLevel: Math.exp(-smoothness),
scalarField: field,
idField
}).runAsChild(ctx)
Mesh.transformImmediate(surface, transform)
const vb = surface.vertexBuffer.ref.value
const ib = surface.indexBuffer.ref.value
const gb = surface.groupBuffer.ref.value
const builder = LinesBuilder.create(surface.triangleCount * 3, surface.triangleCount / 10, lines)
// TODO avoid duplicate lines and move to '../../../geometry/lines/lines' as Lines.fromMesh()
for (let i = 0, il = surface.triangleCount * 3; i < il; i += 3) {
const i0 = ib[i], i1 = ib[i + 1], i2 = ib[i + 2];
const x0 = vb[i0 * 3], y0 = vb[i0 * 3 + 1], z0 = vb[i0 * 3 + 2];
const x1 = vb[i1 * 3], y1 = vb[i1 * 3 + 1], z1 = vb[i1 * 3 + 2];
const x2 = vb[i2 * 3], y2 = vb[i2 * 3 + 1], z2 = vb[i2 * 3 + 2];
builder.add(x0, y0, z0, x1, y1, z1, gb[i0])
builder.add(x0, y0, z0, x2, y2, z2, gb[i0])
builder.add(x1, y1, z1, x2, y2, z2, gb[i1])
}
const l = builder.getLines();
console.log(l)
return l
}
export const DefaultGaussianWireframeProps = {
...DefaultUnitsLinesProps,
...DefaultGaussianDensityProps,
}
export type GaussianWireframeProps = typeof DefaultGaussianWireframeProps
export function GaussianWireframeVisual(): UnitsVisual<GaussianWireframeProps> {
return UnitsLinesVisual<GaussianWireframeProps>({
defaultProps: DefaultGaussianWireframeProps,
createLines: createGaussianWireframe,
createLocationIterator: StructureElementIterator.fromGroup,
getLoci: getElementLoci,
mark: markElement,
setUpdateState: (state: VisualUpdateState, newProps: GaussianWireframeProps, currentProps: GaussianWireframeProps) => {
if (newProps.resolutionFactor !== currentProps.resolutionFactor) state.createGeometry = true
if (newProps.radiusOffset !== currentProps.radiusOffset) state.createGeometry = true
if (newProps.smoothness !== currentProps.smoothness) state.createGeometry = true
}
})
}