From 0814ff5291c8dd471ac622ba8815afbca253e32a Mon Sep 17 00:00:00 2001
From: Alexander Rose <alex.rose@rcsb.org>
Date: Tue, 5 Mar 2019 15:46:19 -0800
Subject: [PATCH] added repr overpaint

---
 src/mol-repr/representation.ts                | 11 +++++++-
 src/mol-repr/shape/representation.ts          | 23 ++++++++++++++++
 .../structure/complex-representation.ts       |  8 +++++-
 src/mol-repr/structure/complex-visual.ts      | 26 +++++++++++++++++++
 .../structure/units-representation.ts         |  6 +++++
 src/mol-repr/structure/units-visual.ts        | 26 +++++++++++++++++++
 src/mol-repr/visual.ts                        |  2 ++
 src/mol-repr/volume/representation.ts         |  9 +++++++
 8 files changed, 109 insertions(+), 2 deletions(-)

diff --git a/src/mol-repr/representation.ts b/src/mol-repr/representation.ts
index 6809928fc..6bd5457b1 100644
--- a/src/mol-repr/representation.ts
+++ b/src/mol-repr/representation.ts
@@ -1,5 +1,5 @@
 /**
- * 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>
  */
@@ -19,6 +19,7 @@ import { Subject } from 'rxjs';
 import { Mat4 } from 'mol-math/linear-algebra';
 import { BaseGeometry } from 'mol-geo/geometry/base';
 import { Visual } from './visual';
+import { Overpaint } from 'mol-theme/overpaint';
 
 // export interface RepresentationProps {
 //     visuals?: string[]
@@ -121,6 +122,7 @@ interface Representation<D, P extends PD.Params = {}, S extends Representation.S
     createOrUpdate: (props?: Partial<PD.Values<P>>, data?: D) => Task<void>
     setState: (state: Partial<S>) => void
     setTheme: (theme: Theme) => void
+    setOverpaint: (layers: Overpaint.Layers) => void
     getLoci: (pickingId: PickingId) => ModelLoci
     mark: (loci: ModelLoci, action: MarkerAction) => boolean
     destroy: () => void
@@ -167,6 +169,7 @@ namespace Representation {
         createOrUpdate: () => Task.constant('', undefined),
         setState: () => {},
         setTheme: () => {},
+        setOverpaint: () => false,
         getLoci: () => EmptyLoci,
         mark: () => false,
         destroy: () => {}
@@ -265,6 +268,11 @@ namespace Representation {
                     reprList[i].setTheme(theme)
                 }
             },
+            setOverpaint: (layers: Overpaint.Layers) => {
+                for (let i = 0, il = reprList.length; i < il; ++i) {
+                    reprList[i].setOverpaint(layers)
+                }
+            },
             destroy() {
                 for (let i = 0, il = reprList.length; i < il; ++i) {
                     reprList[i].destroy()
@@ -316,6 +324,7 @@ namespace Representation {
                 Representation.updateState(currentState, state)
             },
             setTheme: () => { },
+            setOverpaint: () => false,
             destroy() { }
         }
     }
diff --git a/src/mol-repr/shape/representation.ts b/src/mol-repr/shape/representation.ts
index 7128c985b..7ab675168 100644
--- a/src/mol-repr/shape/representation.ts
+++ b/src/mol-repr/shape/representation.ts
@@ -26,6 +26,8 @@ import { Mat4 } from 'mol-math/linear-algebra';
 import { Visual } from 'mol-repr/visual';
 import { createSizes } from 'mol-geo/geometry/size-data';
 import { ShapeGroupSizeTheme } from 'mol-theme/size/shape-group';
+import { Overpaint } from 'mol-theme/overpaint';
+import { applyOverpaintColor } from 'mol-geo/geometry/overpaint-data';
 
 export interface ShapeRepresentation<D, G extends Geometry, P extends Geometry.Params<G>> extends Representation<D, P> { }
 
@@ -200,6 +202,27 @@ export function ShapeRepresentation<D, G extends Geometry, P extends Geometry.Pa
         setTheme(theme: Theme) {
             console.warn('The `ShapeRepresentation` theme is fixed to `ShapeGroupColorTheme` and `ShapeGroupSizeTheme`. Colors are taken from `Shape.getColor` and sizes from `Shape.getSize`')
         },
+        setOverpaint(layers: Overpaint.Layers) {
+            if (!_renderObject) return false
+            const { tOverpaint } = _renderObject.values
+            const { groupCount, instanceCount } = locationIt
+
+            for (let i = 0, il = layers.length; i < il; ++i) {
+                const { loci, color } = layers[i]
+                const apply = (interval: Interval) => {
+                    const start = Interval.start(interval)
+                    const end = Interval.end(interval)
+                    return applyOverpaintColor(tOverpaint.ref.value.array, start, end, color)
+                }
+
+                if (isEveryLoci(loci) || (Shape.isLoci(loci) && loci.shape === _shape)) {
+                    apply(Interval.ofBounds(0, groupCount * instanceCount))
+                } else {
+                    eachShapeLocation(loci, _shape, apply)
+                }
+            }
+            ValueCell.update(tOverpaint, tOverpaint.ref.value)
+        },
         destroy() {
             // TODO
             renderObjects.length = 0
diff --git a/src/mol-repr/structure/complex-representation.ts b/src/mol-repr/structure/complex-representation.ts
index 05d82e964..4f5601885 100644
--- a/src/mol-repr/structure/complex-representation.ts
+++ b/src/mol-repr/structure/complex-representation.ts
@@ -1,5 +1,5 @@
 /**
- * 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 David Sehnal <david.sehnal@gmail.com>
@@ -17,6 +17,7 @@ import { Theme, createEmptyTheme } from 'mol-theme/theme';
 import { ParamDefinition as PD } from 'mol-util/param-definition';
 import { Subject } from 'rxjs';
 import { GraphicsRenderObject } from 'mol-gl/render-object';
+import { Overpaint } from 'mol-theme/overpaint';
 
 export function ComplexRepresentation<P extends StructureParams>(label: string, ctx: RepresentationContext, getParams: RepresentationParamsGetter<Structure, P>, visualCtor: () => ComplexVisual<P>): StructureRepresentation<P> {
     let version = 0
@@ -78,6 +79,10 @@ export function ComplexRepresentation<P extends StructureParams>(label: string,
         _theme = theme
     }
 
+    function setOverpaint(layers: Overpaint.Layers) {
+        if (visual) visual.setOverpaint(layers)
+    }
+
     function destroy() {
         if (visual) visual.destroy()
     }
@@ -96,6 +101,7 @@ export function ComplexRepresentation<P extends StructureParams>(label: string,
         createOrUpdate,
         setState,
         setTheme,
+        setOverpaint,
         getLoci,
         mark,
         destroy
diff --git a/src/mol-repr/structure/complex-visual.ts b/src/mol-repr/structure/complex-visual.ts
index c58d824cd..e6785d1f7 100644
--- a/src/mol-repr/structure/complex-visual.ts
+++ b/src/mol-repr/structure/complex-visual.ts
@@ -28,6 +28,8 @@ import { UnitsParams } from './units-representation';
 import { DirectVolume } from 'mol-geo/geometry/direct-volume/direct-volume';
 import { Mat4 } from 'mol-math/linear-algebra';
 import { createIdentityTransform } from 'mol-geo/geometry/transform-data';
+import { Overpaint } from 'mol-theme/overpaint';
+import { applyOverpaintColor, createOverpaint } from 'mol-geo/geometry/overpaint-data';
 
 export interface  ComplexVisual<P extends StructureParams> extends Visual<Structure, P> { }
 
@@ -203,6 +205,30 @@ export function ComplexVisual<G extends Geometry, P extends ComplexParams & Geom
         setTransform(matrix?: Mat4, instanceMatrices?: Float32Array | null) {
             Visual.setTransform(renderObject, matrix, instanceMatrices)
         },
+        setOverpaint(layers: Overpaint.Layers) {
+            if (!renderObject) return false
+            const { tOverpaint } = renderObject.values
+            const { groupCount, instanceCount } = locationIt
+
+            // ensure texture has right size
+            createOverpaint(layers.length ? groupCount * instanceCount : 0, renderObject.values)
+
+            for (let i = 0, il = layers.length; i < il; ++i) {
+                const { loci, color } = layers[i]
+                const apply = (interval: Interval) => {
+                    const start = Interval.start(interval)
+                    const end = Interval.end(interval)
+                    return applyOverpaintColor(tOverpaint.ref.value.array, start, end, color)
+                }
+
+                if (isEveryLoci(loci) || (Structure.isLoci(loci) && loci.structure === currentStructure)) {
+                    apply(Interval.ofBounds(0, groupCount * instanceCount))
+                } else {
+                    eachLocation(loci, currentStructure, apply)
+                }
+            }
+            ValueCell.update(tOverpaint, tOverpaint.ref.value)
+        },
         destroy() {
             // TODO
             renderObject = undefined
diff --git a/src/mol-repr/structure/units-representation.ts b/src/mol-repr/structure/units-representation.ts
index ab8bb1d26..7c479fd4a 100644
--- a/src/mol-repr/structure/units-representation.ts
+++ b/src/mol-repr/structure/units-representation.ts
@@ -19,6 +19,7 @@ import { Theme, createEmptyTheme } from 'mol-theme/theme';
 import { ParamDefinition as PD } from 'mol-util/param-definition';
 import { UnitKind, UnitKindOptions } from './visual/util/common';
 import { Subject } from 'rxjs';
+import { Overpaint } from 'mol-theme/overpaint';
 
 export const UnitsParams = {
     ...StructureParams,
@@ -193,6 +194,10 @@ export function UnitsRepresentation<P extends UnitsParams>(label: string, ctx: R
         _theme = theme
     }
 
+    function setOverpaint(layers: Overpaint.Layers) {
+        visuals.forEach(({ visual }) => visual.setOverpaint(layers))
+    }
+
     function destroy() {
         visuals.forEach(({ visual }) => visual.destroy())
         visuals.clear()
@@ -216,6 +221,7 @@ export function UnitsRepresentation<P extends UnitsParams>(label: string, ctx: R
         createOrUpdate,
         setState,
         setTheme,
+        setOverpaint,
         getLoci,
         mark,
         destroy
diff --git a/src/mol-repr/structure/units-visual.ts b/src/mol-repr/structure/units-visual.ts
index b036046bd..fa3c97cdb 100644
--- a/src/mol-repr/structure/units-visual.ts
+++ b/src/mol-repr/structure/units-visual.ts
@@ -31,6 +31,8 @@ import { UnitsParams } from './units-representation';
 import { Mat4 } from 'mol-math/linear-algebra';
 import { Spheres } from 'mol-geo/geometry/spheres/spheres';
 import { createUnitsTransform, includesUnitKind } from './visual/util/common';
+import { Overpaint } from 'mol-theme/overpaint';
+import { applyOverpaintColor, createOverpaint } from 'mol-geo/geometry/overpaint-data';
 
 export type StructureGroup = { structure: Structure, group: Unit.SymmetryGroup }
 
@@ -249,6 +251,30 @@ export function UnitsVisual<G extends Geometry, P extends UnitsParams & Geometry
         setTransform(matrix?: Mat4, instanceMatrices?: Float32Array | null) {
             Visual.setTransform(renderObject, matrix, instanceMatrices)
         },
+        setOverpaint(layers: Overpaint.Layers) {
+            if (!renderObject) return false
+            const { tOverpaint } = renderObject.values
+            const { groupCount, instanceCount } = locationIt
+
+            // ensure texture has right size
+            createOverpaint(layers.length ? groupCount * instanceCount : 0, renderObject.values)
+
+            for (let i = 0, il = layers.length; i < il; ++i) {
+                const { loci, color } = layers[i]
+                const apply = (interval: Interval) => {
+                    const start = Interval.start(interval)
+                    const end = Interval.end(interval)
+                    return applyOverpaintColor(tOverpaint.ref.value.array, start, end, color)
+                }
+
+                if (isEveryLoci(loci) || (Structure.isLoci(loci) && loci.structure === currentStructureGroup.structure)) {
+                    apply(Interval.ofBounds(0, groupCount * instanceCount))
+                } else {
+                    eachLocation(loci, currentStructureGroup, apply)
+                }
+            }
+            ValueCell.update(tOverpaint, tOverpaint.ref.value)
+        },
         destroy() {
             // TODO
             renderObject = undefined
diff --git a/src/mol-repr/visual.ts b/src/mol-repr/visual.ts
index 7c24baaa9..bfb82dbec 100644
--- a/src/mol-repr/visual.ts
+++ b/src/mol-repr/visual.ts
@@ -16,6 +16,7 @@ import { Mat4 } from 'mol-math/linear-algebra';
 import { updateTransformData, fillIdentityTransform } from 'mol-geo/geometry/transform-data';
 import { calculateTransformBoundingSphere } from 'mol-gl/renderable/util';
 import { ValueCell } from 'mol-util';
+import { Overpaint } from 'mol-theme/overpaint';
 
 export interface VisualContext {
     readonly runtime: RuntimeContext
@@ -34,6 +35,7 @@ interface Visual<D, P extends PD.Params> {
     setVisibility: (visible: boolean) => void
     setPickable: (pickable: boolean) => void
     setTransform: (matrix?: Mat4, instanceMatrices?: Float32Array | null) => void
+    setOverpaint: (layers: Overpaint.Layers) => void
     destroy: () => void
 }
 namespace Visual {
diff --git a/src/mol-repr/volume/representation.ts b/src/mol-repr/volume/representation.ts
index 0a68fe847..c83d92def 100644
--- a/src/mol-repr/volume/representation.ts
+++ b/src/mol-repr/volume/representation.ts
@@ -26,6 +26,7 @@ import { createIdentityTransform } from 'mol-geo/geometry/transform-data';
 import { ColorTheme } from 'mol-theme/color';
 import { createColors } from 'mol-geo/geometry/color-data';
 import { createSizes } from 'mol-geo/geometry/size-data';
+import { Overpaint } from 'mol-theme/overpaint';
 
 export interface VolumeVisual<P extends VolumeParams> extends Visual<VolumeData, P> { }
 
@@ -190,6 +191,9 @@ export function VolumeVisual<G extends Geometry, P extends VolumeParams & Geomet
         setTransform(matrix?: Mat4, instanceMatrices?: Float32Array | null) {
             Visual.setTransform(renderObject, matrix, instanceMatrices)
         },
+        setOverpaint(layers: Overpaint.Layers) {
+            return false // TODO
+        },
         destroy() {
             // TODO
             renderObject = undefined
@@ -260,6 +264,10 @@ export function VolumeRepresentation<P extends VolumeParams>(label: string, ctx:
         _theme = theme
     }
 
+    function setOverpaint(layers: Overpaint.Layers) {
+        return visual ? visual.setOverpaint(layers) : false
+    }
+
     function destroy() {
         if (visual) visual.destroy()
     }
@@ -278,6 +286,7 @@ export function VolumeRepresentation<P extends VolumeParams>(label: string, ctx:
         createOrUpdate,
         setState,
         setTheme,
+        setOverpaint,
         getLoci,
         mark,
         destroy
-- 
GitLab