Browse Source

add includeParent support to interactions

Alexander Rose 4 years ago
parent
commit
034370b44c

+ 22 - 3
src/mol-model-props/computed/representations/interactions-inter-unit-cylinder.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2019-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2019-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
@@ -15,7 +15,7 @@ import { ComplexMeshParams, ComplexVisual, ComplexMeshVisual } from '../../../mo
 import { VisualUpdateState } from '../../../mol-repr/util';
 import { PickingId } from '../../../mol-geo/geometry/picking';
 import { EmptyLoci, Loci } from '../../../mol-model/loci';
-import { Interval, OrderedSet } from '../../../mol-data/int';
+import { Interval, OrderedSet, SortedArray } from '../../../mol-data/int';
 import { Interactions } from '../interactions/interactions';
 import { InteractionsProvider } from '../interactions';
 import { LocationIterator } from '../../../mol-geo/util/location-iterator';
@@ -35,6 +35,8 @@ function createInterUnitInteractionCylinderMesh(ctx: VisualContext, structure: S
 
     if (!edgeCount) return Mesh.createEmpty(mesh);
 
+    const { child } = structure;
+
     const builderProps = {
         linkCount: edgeCount,
         position: (posA: Vec3, posB: Vec3, edgeIndex: number) => {
@@ -63,7 +65,23 @@ function createInterUnitInteractionCylinderMesh(ctx: VisualContext, structure: S
             const sizeB = theme.size.size(l);
             return Math.min(sizeA, sizeB) * sizeFactor;
         },
-        ignore: (edgeIndex: number) => edges[edgeIndex].props.flag === InteractionFlag.Filtered
+        ignore: (edgeIndex: number) => {
+            if (edges[edgeIndex].props.flag === InteractionFlag.Filtered) return true;
+
+            if (child) {
+                const b = edges[edgeIndex];
+                const childUnitA = child.unitMap.get(b.unitA);
+                if (!childUnitA) return true;
+
+                const unitA = structure.unitMap.get(b.unitA);
+                const fA = unitsFeatures.get(b.unitA);
+                // TODO: check all members
+                const eA = unitA.elements[fA.members[fA.offsets[b.indexA]]];
+                if (!SortedArray.has(childUnitA.elements, eA)) return true;
+            }
+
+            return false;
+        }
     };
 
     const m = createLinkCylinderMesh(ctx, builderProps, props, mesh);
@@ -80,6 +98,7 @@ export const InteractionsInterUnitParams = {
     sizeFactor: PD.Numeric(0.3, { min: 0, max: 10, step: 0.01 }),
     dashCount: PD.Numeric(6, { min: 2, max: 10, step: 2 }),
     dashScale: PD.Numeric(0.4, { min: 0, max: 2, step: 0.1 }),
+    includeParent: PD.Boolean(false),
 };
 export type InteractionsInterUnitParams = typeof InteractionsInterUnitParams
 

+ 13 - 4
src/mol-model-props/computed/representations/interactions-intra-unit-cylinder.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2019-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2019-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
@@ -7,7 +7,7 @@
 import { Unit, Structure, StructureElement } from '../../../mol-model/structure';
 import { Vec3 } from '../../../mol-math/linear-algebra';
 import { Loci, EmptyLoci } from '../../../mol-model/loci';
-import { Interval, OrderedSet } from '../../../mol-data/int';
+import { Interval, OrderedSet, SortedArray } from '../../../mol-data/int';
 import { ParamDefinition as PD } from '../../../mol-util/param-definition';
 import { Mesh } from '../../../mol-geo/geometry/mesh/mesh';
 import { PickingId } from '../../../mol-geo/geometry/picking';
@@ -25,6 +25,10 @@ import { Sphere3D } from '../../../mol-math/geometry';
 async function createIntraUnitInteractionsCylinderMesh(ctx: VisualContext, unit: Unit, structure: Structure, theme: Theme, props: PD.Values<InteractionsIntraUnitParams>, mesh?: Mesh) {
     if (!Unit.isAtomic(unit)) return Mesh.createEmpty(mesh);
 
+    const { child } = structure;
+    const childUnit = child?.unitMap.get(unit.id);
+    if (child && !childUnit) return Mesh.createEmpty(mesh);
+
     const location = StructureElement.Location.create(structure, unit);
 
     const interactions = InteractionsProvider.get(structure).value!;
@@ -51,7 +55,11 @@ async function createIntraUnitInteractionsCylinderMesh(ctx: VisualContext, unit:
             const sizeB = theme.size.size(location);
             return Math.min(sizeA, sizeB) * sizeFactor;
         },
-        ignore: (edgeIndex: number) => flag[edgeIndex] === InteractionFlag.Filtered
+        ignore: (edgeIndex: number) => (
+            flag[edgeIndex] === InteractionFlag.Filtered ||
+            // TODO: check all members
+            (!!childUnit && !SortedArray.has(childUnit.elements, unit.elements[members[offsets[a[edgeIndex]]]]))
+        )
     };
 
     const m = createLinkCylinderMesh(ctx, builderProps, props, mesh);
@@ -68,6 +76,7 @@ export const InteractionsIntraUnitParams = {
     sizeFactor: PD.Numeric(0.3, { min: 0, max: 10, step: 0.01 }),
     dashCount: PD.Numeric(6, { min: 2, max: 10, step: 2 }),
     dashScale: PD.Numeric(0.4, { min: 0, max: 2, step: 0.1 }),
+    includeParent: PD.Boolean(false),
 };
 export type InteractionsIntraUnitParams = typeof InteractionsIntraUnitParams
 
@@ -147,7 +156,7 @@ function eachInteraction(loci: Loci, structureGroup: StructureGroup, apply: (int
         const { offset } = contacts;
         const { offsets: fOffsets, indices: fIndices } = features.elementsIndex;
 
-        // TODO when isMarking, all elements of contact features need to be in the loci
+        // TODO: when isMarking, all elements of contact features need to be in the loci
         for (const e of loci.elements) {
             const unitIdx = group.unitIndexMap.get(e.unit.id);
             if (unitIdx !== undefined) continue;

+ 7 - 1
src/mol-model-props/computed/representations/interactions.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2019-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
@@ -50,5 +50,11 @@ export const InteractionsRepresentationProvider = StructureRepresentationProvide
     ensureCustomProperties: {
         attach: (ctx: CustomProperty.Context, structure: Structure) => InteractionsProvider.attach(ctx, structure, void 0, true),
         detach: (data) => InteractionsProvider.ref(data, false)
+    },
+    getData: (structure: Structure, props: PD.Values<InteractionsParams>) => {
+        return props.includeParent ? structure.asParent() : structure;
+    },
+    mustRecreate: (oldProps: PD.Values<InteractionsParams>, newProps: PD.Values<InteractionsParams>) => {
+        return oldProps.includeParent !== newProps.includeParent;
     }
 });