Procházet zdrojové kódy

add repr.getAllLoci

Alexander Rose před 2 roky
rodič
revize
eddc616b14

+ 1 - 0
CHANGELOG.md

@@ -9,6 +9,7 @@ Note that since we don't clearly distinguish between a public and private interf
 - [Fix] Clone ``Canvas3DParams`` when creating a ``Canvas3D`` instance to prevent shared state between multiple instances
 - Add ``includeResidueTest`` option to ``alignAndSuperposeWithSIFTSMapping``
 - Add ``parentDisplay`` param for interactions representation.
+- Add support for getting multiple loci from a representation (``.getAllLoci()``)
 
 ## [v3.16.0] - 2022-08-25
 

+ 7 - 2
src/mol-plugin-ui/structure/measurements.tsx

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2020-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2020-2022 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>
@@ -288,7 +288,12 @@ class MeasurementEntry extends PurePluginUIComponent<{ cell: StructureMeasuremen
         for (const loci of this.lociArray) {
             this.plugin.managers.interactivity.lociHighlights.highlight({ loci }, false);
         }
-        this.plugin.managers.interactivity.lociHighlights.highlight({ loci: this.props.cell.obj?.data.repr.getLoci()! }, false);
+        const reprLocis = this.props.cell.obj?.data.repr.getAllLoci();
+        if (reprLocis) {
+            for (const loci of reprLocis) {
+                this.plugin.managers.interactivity.lociHighlights.highlight({ loci }, false);
+            }
+        }
     };
 
     clearHighlight = () => {

+ 4 - 2
src/mol-plugin/behavior/static/state.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2018-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author David Sehnal <david.sehnal@gmail.com>
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
@@ -119,7 +119,9 @@ export function Highlight(ctx: PluginContext) {
                 ctx.managers.interactivity.lociHighlights.highlight({ loci: Structure.Loci(cell.obj.data) }, false);
             } else if (cell && SO.isRepresentation3D(cell.obj)) {
                 const { repr } = cell.obj.data;
-                ctx.managers.interactivity.lociHighlights.highlight({ loci: repr.getLoci(), repr }, false);
+                for (const loci of repr.getAllLoci()) {
+                    ctx.managers.interactivity.lociHighlights.highlight({ loci, repr }, false);
+                }
             } else if (SO.Molecule.Structure.Selections.is(cell.obj)) {
                 for (const entry of cell.obj.data) {
                     ctx.managers.interactivity.lociHighlights.highlight({ loci: entry.loci }, false);

+ 19 - 4
src/mol-repr/representation.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2018-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2018-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
@@ -154,8 +154,8 @@ 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
-    /** If no pickingId is given, returns a Loci for the whole representation */
-    getLoci: (pickingId?: PickingId) => ModelLoci
+    getLoci: (pickingId: PickingId) => ModelLoci
+    getAllLoci: () => ModelLoci[]
     mark: (loci: ModelLoci, action: MarkerAction) => boolean
     destroy: () => void
 }
@@ -227,6 +227,7 @@ namespace Representation {
         setState: () => {},
         setTheme: () => {},
         getLoci: () => EmptyLoci,
+        getAllLoci: () => [],
         mark: () => false,
         destroy: () => {}
     };
@@ -327,7 +328,7 @@ namespace Representation {
             },
             get state() { return currentState; },
             get theme() { return currentTheme; },
-            getLoci: (pickingId?: PickingId) => {
+            getLoci: (pickingId: PickingId) => {
                 const { visuals } = currentProps;
                 for (let i = 0, il = reprList.length; i < il; ++i) {
                     if (!visuals || visuals.includes(reprMap[i])) {
@@ -337,6 +338,16 @@ namespace Representation {
                 }
                 return EmptyLoci;
             },
+            getAllLoci: () => {
+                const loci: ModelLoci[] = [];
+                const { visuals } = currentProps;
+                for (let i = 0, il = reprList.length; i < il; ++i) {
+                    if (!visuals || visuals.includes(reprMap[i])) {
+                        loci.push(...reprList[i].getAllLoci());
+                    }
+                }
+                return loci;
+            },
             mark: (loci: ModelLoci, action: MarkerAction) => {
                 let marked = false;
                 for (let i = 0, il = reprList.length; i < il; ++i) {
@@ -399,6 +410,10 @@ namespace Representation {
                 // TODO
                 return EmptyLoci;
             },
+            getAllLoci: () => {
+                // TODO
+                return [];
+            },
             mark: (loci: ModelLoci, action: MarkerAction) => {
                 // TODO
                 return false;

+ 4 - 2
src/mol-repr/shape/representation.ts

@@ -213,14 +213,16 @@ export function ShapeRepresentation<D, G extends Geometry, P extends Geometry.Pa
         get geometryVersion() { return geometryVersion; },
         updated,
         createOrUpdate,
-        getLoci(pickingId?: PickingId) {
-            if (pickingId === undefined) return Shape.Loci(_shape);
+        getLoci(pickingId: PickingId) {
             const { objectId, groupId, instanceId } = pickingId;
             if (_renderObject && _renderObject.id === objectId) {
                 return ShapeGroup.Loci(_shape, [{ ids: OrderedSet.ofSingleton(groupId), instance: instanceId }]);
             }
             return EmptyLoci;
         },
+        getAllLoci() {
+            return [Shape.Loci(_shape)];
+        },
         mark(loci: Loci, action: MarkerAction) {
             if (!MarkerActions.is(_state.markerActions, action)) return false;
             if (ShapeGroup.isLoci(loci) || Shape.isLoci(loci)) {

+ 7 - 3
src/mol-repr/structure/complex-representation.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2018-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2018-2022 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>
@@ -72,11 +72,14 @@ export function ComplexRepresentation<P extends StructureParams>(label: string,
         });
     }
 
-    function getLoci(pickingId?: PickingId) {
-        if (pickingId === undefined) return Structure.Loci(_structure.target);
+    function getLoci(pickingId: PickingId) {
         return visual ? visual.getLoci(pickingId) : EmptyLoci;
     }
 
+    function getAllLoci() {
+        return [Structure.Loci(_structure.target)];
+    }
+
     function mark(loci: Loci, action: MarkerAction) {
         if (!_structure) return false;
         if (!MarkerActions.is(_state.markerActions, action)) return false;
@@ -157,6 +160,7 @@ export function ComplexRepresentation<P extends StructureParams>(label: string,
         setState,
         setTheme,
         getLoci,
+        getAllLoci,
         mark,
         destroy
     };

+ 7 - 3
src/mol-repr/structure/units-representation.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2018-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2018-2022 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>
@@ -185,8 +185,7 @@ export function UnitsRepresentation<P extends StructureParams>(label: string, ct
         });
     }
 
-    function getLoci(pickingId?: PickingId) {
-        if (pickingId === undefined) return Structure.Loci(_structure.target);
+    function getLoci(pickingId: PickingId) {
         let loci: Loci = EmptyLoci;
         visuals.forEach(({ visual }) => {
             const _loci = visual.getLoci(pickingId);
@@ -195,6 +194,10 @@ export function UnitsRepresentation<P extends StructureParams>(label: string, ct
         return loci;
     }
 
+    function getAllLoci() {
+        return [Structure.Loci(_structure.target)];
+    }
+
     function mark(loci: Loci, action: MarkerAction) {
         if (!_structure) return false;
         if (!MarkerActions.is(_state.markerActions, action)) return false;
@@ -302,6 +305,7 @@ export function UnitsRepresentation<P extends StructureParams>(label: string, ct
         setState,
         setTheme,
         getLoci,
+        getAllLoci,
         mark,
         destroy
     };

+ 4 - 2
src/mol-repr/volume/representation.ts

@@ -358,10 +358,12 @@ export function VolumeRepresentation<P extends VolumeParams>(label: string, ctx:
         createOrUpdate,
         setState,
         setTheme,
-        getLoci: (pickingId?: PickingId): Loci => {
-            if (pickingId === undefined) return getLoci(_volume, _props);
+        getLoci: (pickingId: PickingId): Loci => {
             return visual ? visual.getLoci(pickingId) : EmptyLoci;
         },
+        getAllLoci: (): Loci[] => {
+            return [getLoci(_volume, _props)];
+        },
         mark,
         destroy
     };