Ver Fonte

seperated StructureRepresentation and StructureUnitRepresentation

Alexander Rose há 6 anos atrás
pai
commit
9264c12d85

+ 22 - 12
src/mol-geo/representation/structure/ball-and-stick.ts

@@ -4,7 +4,7 @@
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
 
-import { StructureRepresentation } from '.';
+import { StructureRepresentation, StructureUnitsRepresentation } from '.';
 import { ElementSphereVisual, DefaultElementSphereProps } from './visual/element-sphere';
 import { IntraUnitLinkVisual, DefaultIntraUnitLinkProps } from './visual/intra-unit-link-cylinder';
 import { PickingId } from '../../util/picking';
@@ -25,46 +25,56 @@ export const DefaultBallAndStickProps = {
 export type BallAndStickProps = Partial<typeof DefaultBallAndStickProps>
 
 export function BallAndStickRepresentation(): StructureRepresentation<BallAndStickProps> {
-    const elmementRepr = StructureRepresentation(ElementSphereVisual)
-    const linkRepr = StructureRepresentation(IntraUnitLinkVisual, InterUnitLinkVisual)
+    const elmementRepr = StructureUnitsRepresentation(ElementSphereVisual)
+    const intraLinkRepr = StructureUnitsRepresentation(IntraUnitLinkVisual)
+    const interLinkRepr = StructureRepresentation(InterUnitLinkVisual)
 
     return {
         get renderObjects() {
-            return [ ...elmementRepr.renderObjects, ...linkRepr.renderObjects ]
+            return [ ...elmementRepr.renderObjects, ...intraLinkRepr.renderObjects, ...interLinkRepr.renderObjects ]
         },
         get props() {
-            return { ...elmementRepr.props, ...linkRepr.props }
+            return { ...elmementRepr.props, ...intraLinkRepr.props, ...interLinkRepr.props }
         },
         create: (structure: Structure, props: BallAndStickProps = {} as BallAndStickProps) => {
             const p = Object.assign({}, DefaultBallAndStickProps, props)
-            return Task.create('Creating BallAndStickRepresentation', async ctx => {
+            return Task.create('DistanceRestraintRepresentation', async ctx => {
                 await elmementRepr.create(structure, p).runInContext(ctx)
-                await linkRepr.create(structure, p).runInContext(ctx)
+                await intraLinkRepr.create(structure, p).runInContext(ctx)
+                await interLinkRepr.create(structure, p).runInContext(ctx)
             })
         },
         update: (props: BallAndStickProps) => {
             const p = Object.assign({}, props)
             return Task.create('Updating BallAndStickRepresentation', async ctx => {
                 await elmementRepr.update(p).runInContext(ctx)
-                await linkRepr.update(p).runInContext(ctx)
+                await intraLinkRepr.update(p).runInContext(ctx)
+                await interLinkRepr.update(p).runInContext(ctx)
             })
         },
         getLoci: (pickingId: PickingId) => {
             const sphereLoci = elmementRepr.getLoci(pickingId)
-            const intraLinkLoci = linkRepr.getLoci(pickingId)
+            const intraLinkLoci = intraLinkRepr.getLoci(pickingId)
+            const interLinkLoci = interLinkRepr.getLoci(pickingId)
             if (isEmptyLoci(sphereLoci)) {
-                return intraLinkLoci
+                if (isEmptyLoci(intraLinkLoci)) {
+                    return interLinkLoci
+                } else {
+                    return intraLinkLoci
+                }
             } else {
                 return sphereLoci
             }
         },
         mark: (loci: Loci, action: MarkerAction) => {
             elmementRepr.mark(loci, action)
-            linkRepr.mark(loci, action)
+            intraLinkRepr.mark(loci, action)
+            interLinkRepr.mark(loci, action)
         },
         destroy() {
             elmementRepr.destroy()
-            linkRepr.destroy()
+            intraLinkRepr.destroy()
+            interLinkRepr.destroy()
         }
     }
 }

+ 82 - 47
src/mol-geo/representation/structure/index.ts

@@ -27,9 +27,74 @@ export const DefaultStructureProps = {
 }
 export type StructureProps = Partial<typeof DefaultStructureProps>
 
-export function StructureRepresentation<P extends StructureProps>(unitsVisualCtor: () => UnitsVisual<P>, structureVisualCtor?: () => StructureVisual<P>): StructureRepresentation<P> {
-    let unitsVisuals = new Map<number, { group: Unit.SymmetryGroup, visual: UnitsVisual<P> }>()
-    let structureVisual: StructureVisual<P> | undefined
+export function StructureRepresentation<P extends StructureProps>(visualCtor: () => StructureVisual<P>): StructureRepresentation<P> {
+    let visual: StructureVisual<P>
+
+    let _props: Required<P>
+    let _structure: Structure
+
+    function create(structure: Structure, props: P = {} as P) {
+        _props = Object.assign({}, DefaultStructureProps, _props, props, getQualityProps(props, structure))
+
+        return Task.create('Creating StructureRepresentation', async ctx => {
+            if (!_structure) {
+                visual = visualCtor()
+                await visual.create(ctx, structure, _props)
+            } else {
+                if (_structure.hashCode === structure.hashCode) {
+                    await update(_props)
+                } else {
+                    if (!await visual.update(ctx, _props)) {
+                        await visual.create(ctx, _structure, _props)
+                    }
+                }
+            }
+            _structure = structure
+        });
+    }
+
+    function update(props: P) {
+        return Task.create('Updating StructureRepresentation', async ctx => {
+            _props = Object.assign({}, DefaultStructureProps, _props, props, getQualityProps(props, _structure))
+
+            if (!await visual.update(ctx, _props)) {
+                await visual.create(ctx, _structure, _props)
+            }
+        })
+    }
+
+    function getLoci(pickingId: PickingId) {
+        let loci: Loci = EmptyLoci
+        const _loci = visual.getLoci(pickingId)
+        if (!isEmptyLoci(_loci)) loci = _loci
+        return loci
+    }
+
+    function mark(loci: Loci, action: MarkerAction) {
+        visual.mark(loci, action)
+    }
+
+    function destroy() {
+        visual.destroy()
+    }
+
+    return {
+        get renderObjects() {
+            return visual.renderObjects
+        },
+        get props() {
+            return _props
+        },
+        create,
+        update,
+        getLoci,
+        mark,
+        destroy
+    }
+}
+
+export function StructureUnitsRepresentation<P extends StructureProps>(visualCtor: () => UnitsVisual<P>): StructureRepresentation<P> {
+    let visuals = new Map<number, { group: Unit.SymmetryGroup, visual: UnitsVisual<P> }>()
 
     let _props: Required<P>
     let _structure: Structure
@@ -43,14 +108,9 @@ export function StructureRepresentation<P extends StructureProps>(unitsVisualCto
                 _groups = StructureSymmetry.getTransformGroups(structure);
                 for (let i = 0; i < _groups.length; i++) {
                     const group = _groups[i];
-                    const visual = unitsVisualCtor()
+                    const visual = visualCtor()
                     await visual.create(ctx, group, _props)
-                    unitsVisuals.set(group.hashCode, { visual, group })
-                }
-
-                if (structureVisualCtor) {
-                    structureVisual = structureVisualCtor()
-                    await structureVisual.create(ctx, structure, _props)
+                    visuals.set(group.hashCode, { visual, group })
                 }
             } else {
                 if (_structure.hashCode === structure.hashCode) {
@@ -58,8 +118,8 @@ export function StructureRepresentation<P extends StructureProps>(unitsVisualCto
                 } else {
                     _groups = StructureSymmetry.getTransformGroups(structure);
                     const newGroups: Unit.SymmetryGroup[] = []
-                    const oldUnitsVisuals = unitsVisuals
-                    unitsVisuals = new Map()
+                    const oldUnitsVisuals = visuals
+                    visuals = new Map()
                     for (let i = 0; i < _groups.length; i++) {
                         const group = _groups[i];
                         const visualGroup = oldUnitsVisuals.get(group.hashCode)
@@ -71,9 +131,9 @@ export function StructureRepresentation<P extends StructureProps>(unitsVisualCto
                             oldUnitsVisuals.delete(group.hashCode)
                         } else {
                             newGroups.push(group)
-                            const visual = unitsVisualCtor()
+                            const visual = visualCtor()
                             await visual.create(ctx, group, _props)
-                            unitsVisuals.set(group.hashCode, { visual, group })
+                            visuals.set(group.hashCode, { visual, group })
                         }
                     }
 
@@ -81,17 +141,11 @@ export function StructureRepresentation<P extends StructureProps>(unitsVisualCto
                     const unusedVisuals: UnitsVisual<P>[] = []
                     oldUnitsVisuals.forEach(({ visual }) => unusedVisuals.push(visual))
                     newGroups.forEach(async group => {
-                        const visual = unusedVisuals.pop() || unitsVisualCtor()
+                        const visual = unusedVisuals.pop() || visualCtor()
                         await visual.create(ctx, group, _props)
-                        unitsVisuals.set(group.hashCode, { visual, group })
+                        visuals.set(group.hashCode, { visual, group })
                     })
                     unusedVisuals.forEach(visual => visual.destroy())
-
-                    if (structureVisual) {
-                        if (!await structureVisual.update(ctx, _props)) {
-                            await structureVisual.create(ctx, _structure, _props)
-                        }
-                    }
                 }
             }
             _structure = structure
@@ -100,57 +154,38 @@ export function StructureRepresentation<P extends StructureProps>(unitsVisualCto
 
     function update(props: P) {
         return Task.create('Updating StructureRepresentation', async ctx => {
-            console.log(getQualityProps(props, _structure))
             _props = Object.assign({}, DefaultStructureProps, _props, props, getQualityProps(props, _structure))
 
-            console.log('update struct', (_props as any).detail, (_props as any).radialSegments)
-
-            unitsVisuals.forEach(async ({ visual, group }) => {
+            visuals.forEach(async ({ visual, group }) => {
                 if (!await visual.update(ctx, _props)) {
                     await visual.create(ctx, group, _props)
                 }
             })
-
-            if (structureVisual) {
-                if (!await structureVisual.update(ctx, _props)) {
-                    await structureVisual.create(ctx, _structure, _props)
-                }
-            }
         })
     }
 
     function getLoci(pickingId: PickingId) {
         let loci: Loci = EmptyLoci
-        unitsVisuals.forEach(({ visual }) => {
+        visuals.forEach(({ visual }) => {
             const _loci = visual.getLoci(pickingId)
             if (!isEmptyLoci(_loci)) loci = _loci
         })
-        if (structureVisual) {
-            const _loci = structureVisual.getLoci(pickingId)
-            if (!isEmptyLoci(_loci)) loci = _loci
-        }
         return loci
     }
 
     function mark(loci: Loci, action: MarkerAction) {
-        unitsVisuals.forEach(({ visual }) => visual.mark(loci, action))
-        if (structureVisual) structureVisual.mark(loci, action)
+        visuals.forEach(({ visual }) => visual.mark(loci, action))
     }
 
     function destroy() {
-        unitsVisuals.forEach(({ visual }) => visual.destroy())
-        unitsVisuals.clear()
-        if (structureVisual) {
-            structureVisual.destroy()
-            structureVisual = undefined
-        }
+        visuals.forEach(({ visual }) => visual.destroy())
+        visuals.clear()
     }
 
     return {
         get renderObjects() {
             const renderObjects: RenderObject[] = []
-            unitsVisuals.forEach(({ visual }) => renderObjects.push(...visual.renderObjects))
-            if (structureVisual) renderObjects.push(...structureVisual.renderObjects)
+            visuals.forEach(({ visual }) => renderObjects.push(...visual.renderObjects))
             return renderObjects
         },
         get props() {

+ 2 - 2
src/mol-geo/representation/structure/spacefill.ts

@@ -4,7 +4,7 @@
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
 
-import { StructureRepresentation } from '.';
+import { StructureUnitsRepresentation } from '.';
 import { ElementSphereVisual, DefaultElementSphereProps } from './visual/element-sphere';
 
 export const DefaultSpacefillProps = {
@@ -13,5 +13,5 @@ export const DefaultSpacefillProps = {
 export type SpacefillProps = Partial<typeof DefaultSpacefillProps>
 
 export function SpacefillRepresentation() {
-    return StructureRepresentation(ElementSphereVisual)
+    return StructureUnitsRepresentation(ElementSphereVisual)
 }

+ 1 - 2
src/mol-geo/representation/structure/visual/inter-unit-link-cylinder.ts

@@ -77,8 +77,7 @@ export function InterUnitLinkVisual(): StructureVisual<InterUnitLinkProps> {
             const transforms = createIdentityTransform()
 
             if (ctx.shouldUpdate) await ctx.update('Computing link colors');
-            const color = createUniformColor({ value: 0x999911 })
-            // const color = chainIdLinkColorData({ group, elementCount })
+            const color = createUniformColor({ value: 0x999911 }) // TODO
 
             if (ctx.shouldUpdate) await ctx.update('Computing link marks');
             const marker = createMarkers(instanceCount * elementCount)

+ 5 - 4
src/mol-geo/representation/structure/visual/intra-unit-link-cylinder.ts

@@ -94,8 +94,7 @@ export function IntraUnitLinkVisual(): UnitsVisual<IntraUnitLinkProps> {
             const transforms = createTransforms(group)
 
             if (ctx.shouldUpdate) await ctx.update('Computing link colors');
-            // const color = createUniformColor({ value: 0xFF0000 })
-            const color = chainIdLinkColorData({ group, elementCount })
+            const color = chainIdLinkColorData({ group, elementCount }) // TODO
 
             if (ctx.shouldUpdate) await ctx.update('Computing link marks');
             const marker = createMarkers(instanceCount * elementCount)
@@ -118,8 +117,10 @@ export function IntraUnitLinkVisual(): UnitsVisual<IntraUnitLinkProps> {
         async update(ctx: RuntimeContext, props: IntraUnitLinkProps) {
             const newProps = Object.assign({}, currentProps, props)
 
-            if (!cylinders || currentProps.radialSegments !== newProps.radialSegments) return false
-            // TODO
+            if (!cylinders) return false
+
+            // TODO create in-place
+            if (currentProps.radialSegments !== newProps.radialSegments) return false
 
             updateMeshValues(cylinders.values, newProps)
             updateRenderableState(cylinders.state, newProps)