فهرست منبع

wip, sync/async visual create/update

Alexander Rose 6 سال پیش
والد
کامیت
303517f6ff

+ 1 - 1
src/mol-repr/representation.ts

@@ -243,7 +243,7 @@ export interface Visual<D, P extends PD.Params> {
     /** Number of addressable groups in all instances of the visual */
     readonly groupCount: number
     readonly renderObject: RenderObject | undefined
-    createOrUpdate: (ctx: VisualContext, theme: Theme, props?: Partial<PD.Values<P>>, data?: D) => void
+    createOrUpdate: (ctx: VisualContext, theme: Theme, props?: Partial<PD.Values<P>>, data?: D) => Promise<void> | void
     getLoci: (pickingId: PickingId) => Loci
     mark: (loci: Loci, action: MarkerAction) => boolean
     setVisibility: (value: boolean) => void

+ 2 - 1
src/mol-repr/structure/complex-representation.ts

@@ -38,7 +38,8 @@ export function ComplexRepresentation<P extends StructureParams>(label: string,
 
         return Task.create('Creating or updating ComplexRepresentation', async runtime => {
             if (!visual) visual = visualCtor()
-            visual.createOrUpdate({ webgl: ctx.webgl, runtime }, _theme, _props, structure)
+            const promise = visual.createOrUpdate({ webgl: ctx.webgl, runtime }, _theme, _props, structure)
+            if (promise) await promise
             updated.next(version++)
         });
     }

+ 52 - 21
src/mol-repr/structure/complex-visual.ts

@@ -38,7 +38,7 @@ type ComplexRenderObject = MeshRenderObject | LinesRenderObject | PointsRenderOb
 
 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): G
+    createGeometry(ctx: VisualContext, structure: Structure, theme: Theme, props: PD.Values<P>, geometry?: G): Promise<G> | G
     createLocationIterator(structure: Structure): LocationIterator
     getLoci(pickingId: PickingId, structure: Structure, id: number): Loci
     mark(loci: Loci, structure: Structure, apply: (interval: Interval) => boolean): boolean,
@@ -58,6 +58,8 @@ export function ComplexVisual<P extends ComplexParams>(builder: ComplexVisualGeo
     const updateState = VisualUpdateState.create()
 
     let renderObject: ComplexRenderObject | undefined
+    let newProps: PD.Values<P>
+    let newTheme: Theme
     let currentProps: PD.Values<P>
     let currentTheme: Theme
     let geometry: Geometry
@@ -65,24 +67,24 @@ export function ComplexVisual<P extends ComplexParams>(builder: ComplexVisualGeo
     let locationIt: LocationIterator
     let conformationHash: number
 
-    function create(ctx: VisualContext, structure: Structure, theme: Theme, props: Partial<PD.Values<P>> = {}) {
+    function create(newGeometry: Geometry, structure: Structure, theme: Theme, props: Partial<PD.Values<P>> = {}) {
         currentProps = Object.assign({}, defaultProps, props)
         currentTheme = theme
         currentStructure = structure
 
         conformationHash = Structure.conformationHash(currentStructure)
-        geometry = createGeometry(ctx, currentStructure, theme, currentProps, geometry)
+        // geometry = createGeometry(ctx, currentStructure, theme, currentProps, geometry)
 
         locationIt = createLocationIterator(structure)
-        renderObject = createRenderObject(structure, geometry, locationIt, theme, currentProps)
+        renderObject = createRenderObject(structure, newGeometry, locationIt, theme, currentProps)
     }
 
-    function update(ctx: VisualContext, theme: Theme, props: Partial<PD.Values<P>>) {
-        const newProps = Object.assign({}, currentProps, props, { structure: currentStructure })
+    function getUpdateState(theme: Theme, props: Partial<PD.Values<P>>) {
+        if (!renderObject) return
+        
+        newProps = Object.assign({}, currentProps, props, { structure: currentStructure })
+        newTheme = theme
 
-        if (!renderObject) return false
-
-        locationIt.reset()
         VisualUpdateState.reset(updateState)
         setUpdateState(updateState, newProps, currentProps, theme, currentTheme)
 
@@ -95,32 +97,41 @@ export function ComplexVisual<P extends ComplexParams>(builder: ComplexVisualGeo
             updateState.createGeometry = true
         }
 
-        //
-
         if (updateState.createGeometry) {
-            geometry = createGeometry(ctx, currentStructure, theme, newProps, geometry)
-            ValueCell.update(renderObject.values.drawCount, Geometry.getDrawCount(geometry))
-            updateBoundingSphere(renderObject.values, geometry)
             updateState.updateColor = true
         }
+    }
+
+    function update(newGeometry?: Geometry) {
+        if (!renderObject) return
+
+        locationIt.reset()
+
+        if (updateState.createGeometry) {
+            if (newGeometry) {
+                ValueCell.update(renderObject.values.drawCount, Geometry.getDrawCount(newGeometry))
+                updateBoundingSphere(renderObject.values, newGeometry)
+            } else {
+                throw new Error('expected geometry to be given')
+            }
+        }
 
         if (updateState.updateSize) {
             // not all geometries have size data, so check here
             if ('uSize' in renderObject.values) {
-                createSizes(locationIt, theme.size, renderObject.values)
+                createSizes(locationIt, newTheme.size, renderObject.values)
             }
         }
 
         if (updateState.updateColor) {
-            createColors(locationIt, theme.color, renderObject.values)
+            createColors(locationIt, newTheme.color, renderObject.values)
         }
 
         updateValues(renderObject.values, newProps)
         updateRenderableState(renderObject.state, newProps)
 
         currentProps = newProps
-        currentTheme = theme
-        return true
+        currentTheme = newTheme
     }
 
     return {
@@ -130,14 +141,34 @@ export function ComplexVisual<P extends ComplexParams>(builder: ComplexVisualGeo
             if (!structure && !currentStructure) {
                 throw new Error('missing structure')
             } else if (structure && (!currentStructure || !renderObject)) {
-                create(ctx, structure, theme, props)
+                const newGeometry = createGeometry(ctx, structure, theme, Object.assign({}, defaultProps, props), geometry)
+                if (newGeometry instanceof Promise) {
+                    return newGeometry.then(geo => create(geo, structure, theme, props))
+                } else {
+                    create(newGeometry, structure, theme, props)
+                }
             } else if (structure && !Structure.areEquivalent(structure, currentStructure)) {
-                create(ctx, structure, theme, props)
+                const newGeometry = createGeometry(ctx, structure, theme, Object.assign({}, defaultProps, props), geometry)
+                if (newGeometry instanceof Promise) {
+                    return newGeometry.then(geo => create(geo, structure, theme, props))
+                } else {
+                    create(newGeometry, structure, theme, props)
+                }
             } else {
                 if (structure && Structure.conformationHash(structure) !== Structure.conformationHash(currentStructure)) {
                     currentStructure = structure
                 }
-                update(ctx, theme, props)
+                getUpdateState(theme, props)
+                if (updateState.createGeometry) {
+                    const newGeometry = createGeometry(ctx, currentStructure, newTheme, newProps, geometry)
+                    if (newGeometry instanceof Promise) {
+                        return newGeometry.then(update)
+                    } else {
+                        update(newGeometry)
+                    }
+                } else {
+                    update()
+                }
             }
         },
         getLoci(pickingId: PickingId) {

+ 2 - 2
src/mol-repr/structure/registry.ts

@@ -8,7 +8,7 @@ import { Structure } from 'mol-model/structure';
 import { RepresentationProvider, RepresentationRegistry } from '../representation';
 import { CartoonRepresentationProvider } from './representation/cartoon';
 import { BallAndStickRepresentationProvider } from './representation/ball-and-stick';
-// import { MolecularSurfaceRepresentationProvider } from './representation/molecular-surface';
+import { MolecularSurfaceRepresentationProvider } from './representation/molecular-surface';
 import { CarbohydrateRepresentationProvider } from './representation/carbohydrate';
 
 export class StructureRepresentationRegistry extends RepresentationRegistry<Structure> {
@@ -24,7 +24,7 @@ export class StructureRepresentationRegistry extends RepresentationRegistry<Stru
 export const BuiltInStructureRepresentations = {
     'cartoon': CartoonRepresentationProvider,
     'ball-and-stick': BallAndStickRepresentationProvider,
-    // 'molecular-surface': MolecularSurfaceRepresentationProvider,
+    'molecular-surface': MolecularSurfaceRepresentationProvider,
     'carbohydrate': CarbohydrateRepresentationProvider,
 }
 export type BuiltInStructureRepresentationsName = keyof typeof BuiltInStructureRepresentations

+ 42 - 42
src/mol-repr/structure/representation/molecular-surface.ts

@@ -1,47 +1,47 @@
-// /**
-//  * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
-//  *
-//  * @author Alexander Rose <alexander.rose@weirdbyte.de>
-//  */
+/**
+ * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ */
 
-// import { GaussianSurfaceVisual, GaussianSurfaceParams } from '../visual/gaussian-surface-mesh';
-// import { UnitsRepresentation } from '../units-representation';
-// import { GaussianWireframeVisual, GaussianWireframeParams } from '../visual/gaussian-surface-wireframe';
-// import { ParamDefinition as PD } from 'mol-util/param-definition';
-// import { GaussianDensityVolumeParams, GaussianDensityVolumeVisual } from '../visual/gaussian-density-volume';
-// import { StructureRepresentation, StructureRepresentationProvider } from '../representation';
-// import { Representation, RepresentationParamsGetter, RepresentationContext } from 'mol-repr/representation';
-// import { ThemeRegistryContext } from 'mol-theme/theme';
-// import { Structure } from 'mol-model/structure';
+import { GaussianSurfaceVisual, GaussianSurfaceParams } from '../visual/gaussian-surface-mesh';
+import { UnitsRepresentation } from '../units-representation';
+import { GaussianWireframeVisual, GaussianWireframeParams } from '../visual/gaussian-surface-wireframe';
+import { ParamDefinition as PD } from 'mol-util/param-definition';
+import { GaussianDensityVolumeParams, GaussianDensityVolumeVisual } from '../visual/gaussian-density-volume';
+import { StructureRepresentation, StructureRepresentationProvider } from '../representation';
+import { Representation, RepresentationParamsGetter, RepresentationContext } from 'mol-repr/representation';
+import { ThemeRegistryContext } from 'mol-theme/theme';
+import { Structure } from 'mol-model/structure';
 
-// const MolecularSurfaceVisuals = {
-//     'gaussian-surface': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<Structure, GaussianSurfaceParams>) => UnitsRepresentation('Gaussian surface', ctx, getParams, GaussianSurfaceVisual),
-//     'gaussian-wireframe': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<Structure, GaussianWireframeParams>) => UnitsRepresentation('Gaussian wireframe', ctx, getParams, GaussianWireframeVisual),
-//     'gaussian-volume': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<Structure, GaussianDensityVolumeParams>) => UnitsRepresentation('Gaussian volume', ctx, getParams, GaussianDensityVolumeVisual)
-// }
-// type MolecularSurfaceVisualName = keyof typeof MolecularSurfaceVisuals
-// const MolecularSurfaceVisualOptions = Object.keys(MolecularSurfaceVisuals).map(name => [name, name] as [MolecularSurfaceVisualName, string])
+const MolecularSurfaceVisuals = {
+    'gaussian-surface': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<Structure, GaussianSurfaceParams>) => UnitsRepresentation('Gaussian surface', ctx, getParams, GaussianSurfaceVisual),
+    'gaussian-wireframe': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<Structure, GaussianWireframeParams>) => UnitsRepresentation('Gaussian wireframe', ctx, getParams, GaussianWireframeVisual),
+    'gaussian-volume': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<Structure, GaussianDensityVolumeParams>) => UnitsRepresentation('Gaussian volume', ctx, getParams, GaussianDensityVolumeVisual)
+}
+type MolecularSurfaceVisualName = keyof typeof MolecularSurfaceVisuals
+const MolecularSurfaceVisualOptions = Object.keys(MolecularSurfaceVisuals).map(name => [name, name] as [MolecularSurfaceVisualName, string])
 
-// export const MolecularSurfaceParams = {
-//     ...GaussianSurfaceParams,
-//     ...GaussianWireframeParams,
-//     ...GaussianDensityVolumeParams,
-//     visuals: PD.MultiSelect<MolecularSurfaceVisualName>(['gaussian-surface'], MolecularSurfaceVisualOptions),
-// }
-// export type MolecularSurfaceParams = typeof MolecularSurfaceParams
-// export function getMolecularSurfaceParams(ctx: ThemeRegistryContext, structure: Structure) {
-//     return PD.clone(MolecularSurfaceParams)
-// }
+export const MolecularSurfaceParams = {
+    ...GaussianSurfaceParams,
+    ...GaussianWireframeParams,
+    ...GaussianDensityVolumeParams,
+    visuals: PD.MultiSelect<MolecularSurfaceVisualName>(['gaussian-surface'], MolecularSurfaceVisualOptions),
+}
+export type MolecularSurfaceParams = typeof MolecularSurfaceParams
+export function getMolecularSurfaceParams(ctx: ThemeRegistryContext, structure: Structure) {
+    return PD.clone(MolecularSurfaceParams)
+}
 
-// export type MolecularSurfaceRepresentation = StructureRepresentation<MolecularSurfaceParams>
-// export function MolecularSurfaceRepresentation(ctx: RepresentationContext, getParams: RepresentationParamsGetter<Structure, MolecularSurfaceParams>): MolecularSurfaceRepresentation {
-//     return Representation.createMulti('Molecular Surface', ctx, getParams, MolecularSurfaceVisuals as unknown as Representation.Def<Structure, MolecularSurfaceParams>)
-// }
+export type MolecularSurfaceRepresentation = StructureRepresentation<MolecularSurfaceParams>
+export function MolecularSurfaceRepresentation(ctx: RepresentationContext, getParams: RepresentationParamsGetter<Structure, MolecularSurfaceParams>): MolecularSurfaceRepresentation {
+    return Representation.createMulti('Molecular Surface', ctx, getParams, MolecularSurfaceVisuals as unknown as Representation.Def<Structure, MolecularSurfaceParams>)
+}
 
-// export const MolecularSurfaceRepresentationProvider: StructureRepresentationProvider<MolecularSurfaceParams> = {
-//     label: 'Molecular Surface',
-//     description: 'Displays a gaussian molecular surface.',
-//     factory: MolecularSurfaceRepresentation,
-//     getParams: getMolecularSurfaceParams,
-//     defaultValues: PD.getDefaultValues(MolecularSurfaceParams)
-// }
+export const MolecularSurfaceRepresentationProvider: StructureRepresentationProvider<MolecularSurfaceParams> = {
+    label: 'Molecular Surface',
+    description: 'Displays a gaussian molecular surface.',
+    factory: MolecularSurfaceRepresentation,
+    getParams: getMolecularSurfaceParams,
+    defaultValues: PD.getDefaultValues(MolecularSurfaceParams)
+}

+ 10 - 5
src/mol-repr/structure/units-representation.ts

@@ -56,7 +56,8 @@ export function UnitsRepresentation<P extends UnitsParams>(label: string, ctx: R
                 for (let i = 0; i < _groups.length; i++) {
                     const group = _groups[i];
                     const visual = visualCtor()
-                    visual.createOrUpdate({ webgl: ctx.webgl, runtime }, _theme, _props, { group, structure })
+                    const promise = visual.createOrUpdate({ webgl: ctx.webgl, runtime }, _theme, _props, { group, structure })
+                    if (promise) await promise
                     visuals.set(group.hashCode, { visual, group })
                     if (runtime.shouldUpdate) await runtime.update({ message: 'Creating or updating UnitsVisual', current: i, max: _groups.length })
                 }
@@ -76,14 +77,16 @@ export function UnitsRepresentation<P extends UnitsParams>(label: string, ctx: R
                         // console.log('old', visualGroup.group)
                         // console.log('new', group)
                         const { visual } = visualGroup
-                        visual.createOrUpdate({ webgl: ctx.webgl, runtime }, _theme, _props, { group, structure })
+                        const promise = visual.createOrUpdate({ webgl: ctx.webgl, runtime }, _theme, _props, { group, structure })
+                        if (promise) await promise
                         visuals.set(group.hashCode, { visual, group })
                         oldVisuals.delete(group.hashCode)
                     } else {
                         // console.log(label, 'not found visualGroup to reuse, creating new')
                         // newGroups.push(group)
                         const visual = visualCtor()
-                        visual.createOrUpdate({ webgl: ctx.webgl, runtime }, _theme, _props, { group, structure })
+                        const promise = visual.createOrUpdate({ webgl: ctx.webgl, runtime }, _theme, _props, { group, structure })
+                        if (promise) await promise
                         visuals.set(group.hashCode, { visual, group })
                     }
                     if (runtime.shouldUpdate) await runtime.update({ message: 'Creating or updating UnitsVisual', current: i, max: _groups.length })
@@ -115,7 +118,8 @@ export function UnitsRepresentation<P extends UnitsParams>(label: string, ctx: R
                     const group = _groups[i];
                     const visualGroup = visuals.get(group.hashCode)
                     if (visualGroup) {
-                        visualGroup.visual.createOrUpdate({ webgl: ctx.webgl, runtime }, _theme, _props, { group, structure })
+                        const promise = visualGroup.visual.createOrUpdate({ webgl: ctx.webgl, runtime }, _theme, _props, { group, structure })
+                        if (promise) await promise
                         visualGroup.group = group
 
                     } else {
@@ -130,7 +134,8 @@ export function UnitsRepresentation<P extends UnitsParams>(label: string, ctx: R
                 visuals.forEach(({ visual, group }) => visualsList.push([ visual, group ]))
                 for (let i = 0, il = visualsList.length; i < il; ++i) {
                     const [ visual ] = visualsList[i]
-                    visual.createOrUpdate({ webgl: ctx.webgl, runtime }, _theme, _props)
+                    const promise = visual.createOrUpdate({ webgl: ctx.webgl, runtime }, _theme, _props)
+                    if (promise) await promise
                     if (runtime.shouldUpdate) await runtime.update({ message: 'Creating or updating UnitsVisual', current: i, max: il })
                 }
             }

+ 64 - 28
src/mol-repr/structure/units-visual.ts

@@ -38,7 +38,7 @@ type UnitsRenderObject = MeshRenderObject | LinesRenderObject | PointsRenderObje
 
 interface UnitsVisualBuilder<P extends UnitsParams, G extends Geometry> {
     defaultProps: PD.Values<P>
-    createGeometry(ctx: VisualContext, unit: Unit, structure: Structure, theme: Theme, props: PD.Values<P>, geometry?: G): G
+    createGeometry(ctx: VisualContext, unit: Unit, structure: Structure, theme: Theme, props: PD.Values<P>, geometry?: G): Promise<G> | G
     createLocationIterator(group: Unit.SymmetryGroup): LocationIterator
     getLoci(pickingId: PickingId, structureGroup: StructureGroup, id: number): Loci
     mark(loci: Loci, structureGroup: StructureGroup, apply: (interval: Interval) => boolean): boolean
@@ -58,6 +58,8 @@ export function UnitsVisual<P extends UnitsParams>(builder: UnitsVisualGeometryB
     const updateState = VisualUpdateState.create()
 
     let renderObject: UnitsRenderObject | undefined
+    let newProps: PD.Values<P>
+    let newTheme: Theme
     let currentProps: PD.Values<P>
     let currentTheme: Theme
     let geometry: Geometry
@@ -66,29 +68,24 @@ export function UnitsVisual<P extends UnitsParams>(builder: UnitsVisualGeometryB
     let locationIt: LocationIterator
     let currentConformationId: UUID
 
-    function create(ctx: VisualContext, group: Unit.SymmetryGroup, theme: Theme, props: Partial<PD.Values<P>> = {}) {
+    function create(newGeometry: Geometry, group: Unit.SymmetryGroup, theme: Theme, props: Partial<PD.Values<P>> = {}) {
         currentProps = Object.assign({}, defaultProps, props, { structure: currentStructure })
         currentTheme = theme
         currentGroup = group
 
-        const unit = group.units[0]
-        currentConformationId = Unit.conformationId(unit)
-        geometry = includesUnitKind(currentProps.unitKinds, unit)
-            ? createGeometry(ctx, unit, currentStructure, theme, currentProps, geometry)
-            : createEmptyGeometry(geometry)
+        currentConformationId = Unit.conformationId(group.units[0])
 
         // TODO create empty location iterator when not in unitKinds
         locationIt = createLocationIterator(group)
-        renderObject = createRenderObject(group, geometry, locationIt, theme, currentProps)
+        renderObject = createRenderObject(group, newGeometry, locationIt, theme, currentProps)
     }
 
-    function update(ctx: VisualContext, group: Unit.SymmetryGroup, theme: Theme, props: Partial<PD.Values<P>> = {}) {
+    function getUpdateState(group: Unit.SymmetryGroup, theme: Theme, props: Partial<PD.Values<P>> = {}) {
         if (!renderObject) return
 
-        const newProps = Object.assign({}, currentProps, props, { structure: currentStructure })
-        const unit = group.units[0]
+        newProps = Object.assign({}, currentProps, props, { structure: currentStructure })
+        newTheme = theme
 
-        locationIt.reset()
         VisualUpdateState.reset(updateState)
         setUpdateState(updateState, newProps, currentProps, theme, currentTheme)
 
@@ -111,22 +108,33 @@ export function UnitsVisual<P extends UnitsParams>(builder: UnitsVisualGeometryB
         }
 
         // check if the conformation of unit.model has changed
-        const newConformationId = Unit.conformationId(unit)
+        const newConformationId = Unit.conformationId(group.units[0])
         if (newConformationId !== currentConformationId) {
             // console.log('new conformation')
             currentConformationId = newConformationId
             updateState.createGeometry = true
         }
 
-        //
+        if (updateState.updateTransform) {
+            updateState.updateColor = true
+            updateState.updateMatrix = true
+        }
+
+        if (updateState.createGeometry) {
+            updateState.updateColor = true
+        }
+    }
+
+    function update(group: Unit.SymmetryGroup, newGeometry?: Geometry) {
+        if (!renderObject) return
+
+        locationIt.reset()
 
         if (updateState.updateTransform) {
             // console.log('update transform')
             locationIt = createLocationIterator(group)
             const { instanceCount, groupCount } = locationIt
             createMarkers(instanceCount * groupCount, renderObject.values)
-            updateState.updateColor = true
-            updateState.updateMatrix = true
         }
 
         if (updateState.updateMatrix) {
@@ -136,35 +144,41 @@ export function UnitsVisual<P extends UnitsParams>(builder: UnitsVisualGeometryB
 
         if (updateState.createGeometry) {
             // console.log('update geometry')
-            geometry = includesUnitKind(newProps.unitKinds, unit)
-                ? createGeometry(ctx, unit, currentStructure, theme, newProps, geometry)
-                : createEmptyGeometry(geometry)
-            ValueCell.update(renderObject.values.drawCount, Geometry.getDrawCount(geometry))
-            updateBoundingSphere(renderObject.values, geometry)
-            updateState.updateColor = true
+            if (newGeometry) {
+                ValueCell.update(renderObject.values.drawCount, Geometry.getDrawCount(newGeometry))
+                updateBoundingSphere(renderObject.values, newGeometry)
+            } else {
+                throw new Error('expected geometry to be given')
+            }
         }
 
         if (updateState.updateSize) {
             // not all geometries have size data, so check here
             if ('uSize' in renderObject.values) {
                 // console.log('update size')
-                createSizes(locationIt, theme.size, renderObject.values)
+                createSizes(locationIt, newTheme.size, renderObject.values)
             }
         }
 
         if (updateState.updateColor) {
             // console.log('update color')
-            createColors(locationIt, theme.color, renderObject.values)
+            createColors(locationIt, newTheme.color, renderObject.values)
         }
 
         updateValues(renderObject.values, newProps)
         updateRenderableState(renderObject.state, newProps)
 
         currentProps = newProps
-        currentTheme = theme
+        currentTheme = newTheme
         currentGroup = group
     }
 
+    function _createGeometry(ctx: VisualContext, unit: Unit, structure: Structure, theme: Theme, props: PD.Values<P>, geometry?: Geometry) {
+        return includesUnitKind(props.unitKinds, unit)
+                ? createGeometry(ctx, unit, structure, theme, props, geometry)
+                : createEmptyGeometry(geometry)
+    }
+
     return {
         get groupCount() { return locationIt ? locationIt.count : 0 },
         get renderObject () { return renderObject },
@@ -175,13 +189,35 @@ export function UnitsVisual<P extends UnitsParams>(builder: UnitsVisualGeometryB
                 throw new Error('missing group')
             } else if (group && (!currentGroup || !renderObject)) {
                 // console.log('unit-visual first create')
-                create(ctx, group, theme, props)
+                const newGeometry = _createGeometry(ctx, group.units[0], currentStructure, theme, Object.assign({}, defaultProps, props), geometry)
+                if (newGeometry instanceof Promise) {
+                    return newGeometry.then(geo => create(geo, group, theme, props))
+                } else {
+                    create(newGeometry, group, theme, props)
+                }
             } else if (group && group.hashCode !== currentGroup.hashCode) {
                 // console.log('unit-visual group.hashCode !== currentGroup.hashCode')
-                create(ctx, group, theme, props)
+                const newGeometry = _createGeometry(ctx, group.units[0], currentStructure, theme, Object.assign({}, defaultProps, props), geometry)
+                if (newGeometry instanceof Promise) {
+                    return newGeometry.then(geo => create(geo, group, theme, props))
+                } else {
+                    create(newGeometry, group, theme, props)
+                }
             } else {
                 // console.log('unit-visual update')
-                update(ctx, group || currentGroup, theme, props)
+                // update(ctx, group || currentGroup, theme, props)
+
+                getUpdateState(group || currentGroup, theme, props)
+                if (updateState.createGeometry) {
+                    const newGeometry = _createGeometry(ctx, (group || currentGroup).units[0], currentStructure, newTheme, newProps, geometry)
+                    if (newGeometry instanceof Promise) {
+                        return newGeometry.then(geo => update(group || currentGroup, geo))
+                    } else {
+                        update(group || currentGroup, newGeometry)
+                    }
+                } else {
+                    update(group || currentGroup)
+                }
             }
         },
         getLoci(pickingId: PickingId) {

+ 65 - 65
src/mol-repr/structure/visual/gaussian-density-point.ts

@@ -1,73 +1,73 @@
-// /**
-//  * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
-//  *
-//  * @author Alexander Rose <alexander.rose@weirdbyte.de>
-//  */
+/**
+ * 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 } from '../representation';
-// import { VisualUpdateState } from '../../util';
-// import { StructureElementIterator } from './util/element';
-// import { EmptyLoci } from 'mol-model/loci';
-// import { Vec3 } from 'mol-math/linear-algebra';
-// import { UnitsPointsVisual, UnitsPointsParams } from '../units-visual';
-// import { GaussianDensityProps, GaussianDensityParams } from 'mol-model/structure/structure/unit/gaussian-density';
-// import { ParamDefinition as PD } from 'mol-util/param-definition';
-// import { Points } from 'mol-geo/geometry/points/points';
-// import { PointsBuilder } from 'mol-geo/geometry/points/points-builder';
-// import { VisualContext } from 'mol-repr/representation';
-// import { Theme } from 'mol-theme/theme';
+import { Unit, Structure } from 'mol-model/structure';
+import { UnitsVisual } from '../representation';
+import { VisualUpdateState } from '../../util';
+import { StructureElementIterator } from './util/element';
+import { EmptyLoci } from 'mol-model/loci';
+import { Vec3 } from 'mol-math/linear-algebra';
+import { UnitsPointsVisual, UnitsPointsParams } from '../units-visual';
+import { GaussianDensityProps, GaussianDensityParams } from 'mol-model/structure/structure/unit/gaussian-density';
+import { ParamDefinition as PD } from 'mol-util/param-definition';
+import { Points } from 'mol-geo/geometry/points/points';
+import { PointsBuilder } from 'mol-geo/geometry/points/points-builder';
+import { VisualContext } from 'mol-repr/representation';
+import { Theme } from 'mol-theme/theme';
 
-// export const GaussianDensityPointParams = {
-//     ...UnitsPointsParams,
-//     ...GaussianDensityParams,
-//     pointSizeAttenuation: PD.Boolean(false),
-// }
-// export type GaussianDensityPointParams = typeof GaussianDensityPointParams
+export const GaussianDensityPointParams = {
+    ...UnitsPointsParams,
+    ...GaussianDensityParams,
+    pointSizeAttenuation: PD.Boolean(false),
+}
+export type GaussianDensityPointParams = typeof GaussianDensityPointParams
 
-// export async function createGaussianDensityPoint(ctx: VisualContext, unit: Unit, structure: Structure, theme: Theme, props: GaussianDensityProps, points?: Points) {
-//     const { transform, field: { space, data } } = await unit.computeGaussianDensity(props, ctx.runtime, ctx.webgl)
+export async function createGaussianDensityPoint(ctx: VisualContext, unit: Unit, structure: Structure, theme: Theme, props: GaussianDensityProps, points?: Points) {
+    const { transform, field: { space, data } } = await unit.computeGaussianDensity(props, ctx.runtime, ctx.webgl)
 
-//     const { dimensions, get } = space
-//     const [ xn, yn, zn ] = dimensions
+    const { dimensions, get } = space
+    const [ xn, yn, zn ] = dimensions
 
-//     const n = xn * yn * zn * 3
-//     const builder = PointsBuilder.create(n, n / 10, points)
+    const n = xn * yn * zn * 3
+    const builder = PointsBuilder.create(n, n / 10, points)
 
-//     const p = Vec3.zero()
-//     let i = 0
+    const p = Vec3.zero()
+    let i = 0
 
-//     for (let x = 0; x < xn; ++x) {
-//         for (let y = 0; y < yn; ++y) {
-//             for (let z = 0; z < zn; ++z) {
-//                 if (get(data, x, y, z) > 0.001) {
-//                     Vec3.set(p, x, y, z)
-//                     Vec3.transformMat4(p, p, transform)
-//                     builder.add(p[0], p[1], p[2], i)
-//                 }
-//                 if (i % 100000 === 0 && ctx.runtime.shouldUpdate) {
-//                     await ctx.runtime.update({ message: 'Creating density points', current: i, max: n });
-//                 }
-//                 ++i
-//             }
-//         }
-//     }
-//     return builder.getPoints()
-// }
+    for (let x = 0; x < xn; ++x) {
+        for (let y = 0; y < yn; ++y) {
+            for (let z = 0; z < zn; ++z) {
+                if (get(data, x, y, z) > 0.001) {
+                    Vec3.set(p, x, y, z)
+                    Vec3.transformMat4(p, p, transform)
+                    builder.add(p[0], p[1], p[2], i)
+                }
+                if (i % 100000 === 0 && ctx.runtime.shouldUpdate) {
+                    await ctx.runtime.update({ message: 'Creating density points', current: i, max: n });
+                }
+                ++i
+            }
+        }
+    }
+    return builder.getPoints()
+}
 
-// export function GaussianDensityPointVisual(): UnitsVisual<GaussianDensityPointParams> {
-//     return UnitsPointsVisual<GaussianDensityPointParams>({
-//         defaultProps: PD.getDefaultValues(GaussianDensityPointParams),
-//         createGeometry: createGaussianDensityPoint,
-//         createLocationIterator: StructureElementIterator.fromGroup,
-//         getLoci: () => EmptyLoci,
-//         mark: () => false,
-//         setUpdateState: (state: VisualUpdateState, newProps: PD.Values<GaussianDensityPointParams>, currentProps: PD.Values<GaussianDensityPointParams>) => {
-//             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.ignoreCache !== currentProps.ignoreCache) state.createGeometry = true
-//         }
-//     })
-// }
+export function GaussianDensityPointVisual(): UnitsVisual<GaussianDensityPointParams> {
+    return UnitsPointsVisual<GaussianDensityPointParams>({
+        defaultProps: PD.getDefaultValues(GaussianDensityPointParams),
+        createGeometry: createGaussianDensityPoint,
+        createLocationIterator: StructureElementIterator.fromGroup,
+        getLoci: () => EmptyLoci,
+        mark: () => false,
+        setUpdateState: (state: VisualUpdateState, newProps: PD.Values<GaussianDensityPointParams>, currentProps: PD.Values<GaussianDensityPointParams>) => {
+            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.ignoreCache !== currentProps.ignoreCache) state.createGeometry = true
+        }
+    })
+}

+ 48 - 48
src/mol-repr/structure/visual/gaussian-density-volume.ts

@@ -1,54 +1,54 @@
-// /**
-//  * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
-//  *
-//  * @author Alexander Rose <alexander.rose@weirdbyte.de>
-//  */
+/**
+ * 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 } from '../representation';
-// import { VisualUpdateState } from '../../util';
-// import { UnitsDirectVolumeVisual, UnitsDirectVolumeParams } from '../units-visual';
-// import { StructureElementIterator, getElementLoci, markElement } from './util/element';
-// import { GaussianDensityProps, GaussianDensityParams, computeUnitGaussianDensityTexture } from 'mol-model/structure/structure/unit/gaussian-density';
-// import { ParamDefinition as PD } from 'mol-util/param-definition';
-// import { DirectVolume } from 'mol-geo/geometry/direct-volume/direct-volume';
-// import { VisualContext } from 'mol-repr/representation';
-// import { Theme } from 'mol-theme/theme';
+import { Unit, Structure } from 'mol-model/structure';
+import { UnitsVisual } from '../representation';
+import { VisualUpdateState } from '../../util';
+import { UnitsDirectVolumeVisual, UnitsDirectVolumeParams } from '../units-visual';
+import { StructureElementIterator, getElementLoci, markElement } from './util/element';
+import { GaussianDensityProps, GaussianDensityParams, computeUnitGaussianDensityTexture } from 'mol-model/structure/structure/unit/gaussian-density';
+import { ParamDefinition as PD } from 'mol-util/param-definition';
+import { DirectVolume } from 'mol-geo/geometry/direct-volume/direct-volume';
+import { VisualContext } from 'mol-repr/representation';
+import { Theme } from 'mol-theme/theme';
 
-// async function createGaussianDensityVolume(ctx: VisualContext, unit: Unit, structure: Structure, theme: Theme, props: GaussianDensityProps, directVolume?: DirectVolume): Promise<DirectVolume> {
-//     const { runtime, webgl } = ctx
-//     if (webgl === undefined) throw new Error('createGaussianDensityVolume requires `webgl` object in VisualContext')
+async function createGaussianDensityVolume(ctx: VisualContext, unit: Unit, structure: Structure, theme: Theme, props: GaussianDensityProps, directVolume?: DirectVolume): Promise<DirectVolume> {
+    const { runtime, webgl } = ctx
+    if (webgl === undefined) throw new Error('createGaussianDensityVolume requires `webgl` object in VisualContext')
 
-//     const p = { ...props, useGpu: true }
-//     const oldTexture = directVolume ? directVolume.gridTexture.ref.value : undefined
-//     const densityTextureData = await computeUnitGaussianDensityTexture(unit, p, webgl, oldTexture).runInContext(runtime)
-//     const { transform, texture, bbox, gridDimension } = densityTextureData
+    const p = { ...props, useGpu: true }
+    const oldTexture = directVolume ? directVolume.gridTexture.ref.value : undefined
+    const densityTextureData = await computeUnitGaussianDensityTexture(unit, p, webgl, oldTexture).runInContext(runtime)
+    const { transform, texture, bbox, gridDimension } = densityTextureData
 
-//     return DirectVolume.create(bbox, gridDimension, transform, texture, directVolume)
-// }
+    return DirectVolume.create(bbox, gridDimension, transform, texture, directVolume)
+}
 
-// export const GaussianDensityVolumeParams = {
-//     ...UnitsDirectVolumeParams,
-//     ...GaussianDensityParams,
-// }
-// export type GaussianDensityVolumeParams = typeof GaussianDensityVolumeParams
+export const GaussianDensityVolumeParams = {
+    ...UnitsDirectVolumeParams,
+    ...GaussianDensityParams,
+}
+export type GaussianDensityVolumeParams = typeof GaussianDensityVolumeParams
 
-// export function GaussianDensityVolumeVisual(): UnitsVisual<GaussianDensityVolumeParams> {
-//     return UnitsDirectVolumeVisual<GaussianDensityVolumeParams>({
-//         defaultProps: PD.getDefaultValues(GaussianDensityVolumeParams),
-//         createGeometry: createGaussianDensityVolume,
-//         createLocationIterator: StructureElementIterator.fromGroup,
-//         getLoci: getElementLoci,
-//         mark: markElement,
-//         setUpdateState: (state: VisualUpdateState, newProps: PD.Values<GaussianDensityVolumeParams>, currentProps: PD.Values<GaussianDensityVolumeParams>) => {
-//             if (newProps.resolution !== currentProps.resolution) state.createGeometry = true
-//             if (newProps.radiusOffset !== currentProps.radiusOffset) state.createGeometry = true
-//             if (newProps.smoothness !== currentProps.smoothness) {
-//                 state.createGeometry = true
-//                 newProps.isoValue = Math.exp(-newProps.smoothness)
-//             }
-//             if (newProps.useGpu !== currentProps.useGpu) state.createGeometry = true
-//             if (newProps.ignoreCache !== currentProps.ignoreCache) state.createGeometry = true
-//         }
-//     })
-// }
+export function GaussianDensityVolumeVisual(): UnitsVisual<GaussianDensityVolumeParams> {
+    return UnitsDirectVolumeVisual<GaussianDensityVolumeParams>({
+        defaultProps: PD.getDefaultValues(GaussianDensityVolumeParams),
+        createGeometry: createGaussianDensityVolume,
+        createLocationIterator: StructureElementIterator.fromGroup,
+        getLoci: getElementLoci,
+        mark: markElement,
+        setUpdateState: (state: VisualUpdateState, newProps: PD.Values<GaussianDensityVolumeParams>, currentProps: PD.Values<GaussianDensityVolumeParams>) => {
+            if (newProps.resolution !== currentProps.resolution) state.createGeometry = true
+            if (newProps.radiusOffset !== currentProps.radiusOffset) state.createGeometry = true
+            if (newProps.smoothness !== currentProps.smoothness) {
+                state.createGeometry = true
+                newProps.isoValue = Math.exp(-newProps.smoothness)
+            }
+            if (newProps.useGpu !== currentProps.useGpu) state.createGeometry = true
+            if (newProps.ignoreCache !== currentProps.ignoreCache) state.createGeometry = true
+        }
+    })
+}

+ 51 - 51
src/mol-repr/structure/visual/gaussian-surface-mesh.ts

@@ -1,58 +1,58 @@
-// /**
-//  * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
-//  *
-//  * @author Alexander Rose <alexander.rose@weirdbyte.de>
-//  */
+/**
+ * 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 } from '../representation';
-// import { VisualUpdateState } from '../../util';
-// import { UnitsMeshVisual, UnitsMeshParams } from '../units-visual';
-// import { StructureElementIterator, getElementLoci, markElement } from './util/element';
-// import { GaussianDensityProps, GaussianDensityParams } from 'mol-model/structure/structure/unit/gaussian-density';
-// 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 { VisualContext } from 'mol-repr/representation';
-// import { Theme } from 'mol-theme/theme';
+import { Unit, Structure } from 'mol-model/structure';
+import { UnitsVisual } from '../representation';
+import { VisualUpdateState } from '../../util';
+import { UnitsMeshVisual, UnitsMeshParams } from '../units-visual';
+import { StructureElementIterator, getElementLoci, markElement } from './util/element';
+import { GaussianDensityProps, GaussianDensityParams } from 'mol-model/structure/structure/unit/gaussian-density';
+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 { VisualContext } from 'mol-repr/representation';
+import { Theme } from 'mol-theme/theme';
 
-// async function createGaussianSurfaceMesh(ctx: VisualContext, unit: Unit, structure: Structure, theme: Theme, props: GaussianDensityProps, mesh?: Mesh): Promise<Mesh> {
-//     const { smoothness } = props
-//     const { transform, field, idField } = await unit.computeGaussianDensity(props, ctx.runtime, ctx.webgl)
+async function createGaussianSurfaceMesh(ctx: VisualContext, unit: Unit, structure: Structure, theme: Theme, props: GaussianDensityProps, mesh?: Mesh): Promise<Mesh> {
+    const { smoothness } = props
+    const { transform, field, idField } = await unit.computeGaussianDensity(props, ctx.runtime, ctx.webgl)
 
-//     const params = {
-//         isoLevel: Math.exp(-smoothness),
-//         scalarField: field,
-//         idField
-//     }
-//     const surface = await computeMarchingCubesMesh(params, mesh).runAsChild(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.computeNormalsImmediate(surface)
-//     Mesh.uniformTriangleGroup(surface)
+    Mesh.transformImmediate(surface, transform)
+    Mesh.computeNormalsImmediate(surface)
+    Mesh.uniformTriangleGroup(surface)
 
-//     return surface;
-// }
+    return surface;
+}
 
-// export const GaussianSurfaceParams = {
-//     ...UnitsMeshParams,
-//     ...GaussianDensityParams,
-// }
-// export type GaussianSurfaceParams = typeof GaussianSurfaceParams
+export const GaussianSurfaceParams = {
+    ...UnitsMeshParams,
+    ...GaussianDensityParams,
+}
+export type GaussianSurfaceParams = typeof GaussianSurfaceParams
 
-// export function GaussianSurfaceVisual(): UnitsVisual<GaussianSurfaceParams> {
-//     return UnitsMeshVisual<GaussianSurfaceParams>({
-//         defaultProps: PD.getDefaultValues(GaussianSurfaceParams),
-//         createGeometry: createGaussianSurfaceMesh,
-//         createLocationIterator: StructureElementIterator.fromGroup,
-//         getLoci: getElementLoci,
-//         mark: markElement,
-//         setUpdateState: (state: VisualUpdateState, newProps: PD.Values<GaussianSurfaceParams>, currentProps: PD.Values<GaussianSurfaceParams>) => {
-//             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.ignoreCache !== currentProps.ignoreCache) state.createGeometry = true
-//         }
-//     })
-// }
+export function GaussianSurfaceVisual(): UnitsVisual<GaussianSurfaceParams> {
+    return UnitsMeshVisual<GaussianSurfaceParams>({
+        defaultProps: PD.getDefaultValues(GaussianSurfaceParams),
+        createGeometry: createGaussianSurfaceMesh,
+        createLocationIterator: StructureElementIterator.fromGroup,
+        getLoci: getElementLoci,
+        mark: markElement,
+        setUpdateState: (state: VisualUpdateState, newProps: PD.Values<GaussianSurfaceParams>, currentProps: PD.Values<GaussianSurfaceParams>) => {
+            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.ignoreCache !== currentProps.ignoreCache) state.createGeometry = true
+        }
+    })
+}

+ 50 - 50
src/mol-repr/structure/visual/gaussian-surface-wireframe.ts

@@ -1,57 +1,57 @@
-// /**
-//  * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
-//  *
-//  * @author Alexander Rose <alexander.rose@weirdbyte.de>
-//  */
+/**
+ * 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 } from '../representation';
-// import { VisualUpdateState } from '../../util';
-// import { UnitsLinesVisual, UnitsLinesParams } from '../units-visual';
-// import { StructureElementIterator, getElementLoci, markElement } from './util/element';
-// import { GaussianDensityProps, GaussianDensityParams } from 'mol-model/structure/structure/unit/gaussian-density';
-// import { ParamDefinition as PD } from 'mol-util/param-definition';
-// import { Lines } from 'mol-geo/geometry/lines/lines';
-// import { computeMarchingCubesLines } from 'mol-geo/util/marching-cubes/algorithm';
-// import { VisualContext } from 'mol-repr/representation';
-// import { Theme } from 'mol-theme/theme';
+import { Unit, Structure } from 'mol-model/structure';
+import { UnitsVisual } from '../representation';
+import { VisualUpdateState } from '../../util';
+import { UnitsLinesVisual, UnitsLinesParams } from '../units-visual';
+import { StructureElementIterator, getElementLoci, markElement } from './util/element';
+import { GaussianDensityProps, GaussianDensityParams } from 'mol-model/structure/structure/unit/gaussian-density';
+import { ParamDefinition as PD } from 'mol-util/param-definition';
+import { Lines } from 'mol-geo/geometry/lines/lines';
+import { computeMarchingCubesLines } from 'mol-geo/util/marching-cubes/algorithm';
+import { VisualContext } from 'mol-repr/representation';
+import { Theme } from 'mol-theme/theme';
 
-// function createGaussianWireframe(ctx: VisualContext, unit: Unit, structure: Structure, theme: Theme, props: GaussianDensityProps, lines?: Lines): Promise<Lines> {
-//     const { smoothness } = props
-//     const { transform, field, idField } = await unit.computeGaussianDensity(props, ctx.runtime)
+async function createGaussianWireframe(ctx: VisualContext, unit: Unit, structure: Structure, theme: Theme, props: GaussianDensityProps, lines?: Lines): Promise<Lines> {
+    const { smoothness } = props
+    const { transform, field, idField } = await unit.computeGaussianDensity(props, ctx.runtime)
 
-//     const params = {
-//         isoLevel: Math.exp(-smoothness),
-//         scalarField: field,
-//         idField
-//     }
-//     const wireframe = await computeMarchingCubesLines(params, lines).runAsChild(ctx.runtime)
+    const params = {
+        isoLevel: Math.exp(-smoothness),
+        scalarField: field,
+        idField
+    }
+    const wireframe = await computeMarchingCubesLines(params, lines).runAsChild(ctx.runtime)
 
-//     Lines.transformImmediate(wireframe, transform)
+    Lines.transformImmediate(wireframe, transform)
 
-//     return wireframe
-// }
+    return wireframe
+}
 
-// export const GaussianWireframeParams = {
-//     ...UnitsLinesParams,
-//     ...GaussianDensityParams,
-//     lineSizeAttenuation: PD.Boolean(false),
-// }
-// export type GaussianWireframeParams = typeof GaussianWireframeParams
+export const GaussianWireframeParams = {
+    ...UnitsLinesParams,
+    ...GaussianDensityParams,
+    lineSizeAttenuation: PD.Boolean(false),
+}
+export type GaussianWireframeParams = typeof GaussianWireframeParams
 
-// export function GaussianWireframeVisual(): UnitsVisual<GaussianWireframeParams> {
-//     return UnitsLinesVisual<GaussianWireframeParams>({
-//         defaultProps: PD.getDefaultValues(GaussianWireframeParams),
-//         createGeometry: createGaussianWireframe,
-//         createLocationIterator: StructureElementIterator.fromGroup,
-//         getLoci: getElementLoci,
-//         mark: markElement,
-//         setUpdateState: (state: VisualUpdateState, newProps: PD.Values<GaussianWireframeParams>, currentProps: PD.Values<GaussianWireframeParams>) => {
-//             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.ignoreCache !== currentProps.ignoreCache) state.createGeometry = true
-//         }
-//     })
-// }
+export function GaussianWireframeVisual(): UnitsVisual<GaussianWireframeParams> {
+    return UnitsLinesVisual<GaussianWireframeParams>({
+        defaultProps: PD.getDefaultValues(GaussianWireframeParams),
+        createGeometry: createGaussianWireframe,
+        createLocationIterator: StructureElementIterator.fromGroup,
+        getLoci: getElementLoci,
+        mark: markElement,
+        setUpdateState: (state: VisualUpdateState, newProps: PD.Values<GaussianWireframeParams>, currentProps: PD.Values<GaussianWireframeParams>) => {
+            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.ignoreCache !== currentProps.ignoreCache) state.createGeometry = true
+        }
+    })
+}