Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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
/**
* 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 { computeGaussianDensity, DefaultGaussianDensityProps, GaussianDensityProps } from './util/gaussian';
import { Lines } from '../../../geometry/lines/lines';
import { LinesBuilder } from '../../../geometry/lines/lines-builder';
async function createGaussianWireframe(ctx: RuntimeContext, unit: Unit, structure: Structure, props: GaussianDensityProps, lines?: Lines): Promise<Lines> {
const { smoothness } = props
const { transform, field, idField } = await computeGaussianDensity(unit, structure, props).runAsChild(ctx)
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
}
})
}