Explorar el Código

model & repr update/selection fixes and tweaks

Alexander Rose hace 4 años
padre
commit
dd278ca964

+ 1 - 0
src/mol-model-props/computed/representations/interactions-intra-unit-cylinder.ts

@@ -119,6 +119,7 @@ function eachInteraction(loci: Loci, structureGroup: StructureGroup, apply: (int
         const contacts = interactions.unitsContacts.get(unit.id);
         const groupCount = contacts.edgeCount * 2;
         for (const e of loci.elements) {
+            if (e.unitA !== e.unitB) continue;
             const unitIdx = group.unitIndexMap.get(e.unitA.id);
             if (unitIdx !== undefined) {
                 const idx = contacts.getDirectedEdgeIndex(e.indexA, e.indexB);

+ 5 - 0
src/mol-model/loci.ts

@@ -264,6 +264,11 @@ namespace Loci {
         }
     });
 
+    /** Exclude `Instances` granularity kinds */
+    export function simpleGranularity(granularity: Granularity) {
+        return granularity.replace('Instances', '') as Granularity;
+    }
+
     export function applyGranularity(loci: Loci, granularity: Granularity) {
         return Granularity[granularity](loci);
     }

+ 4 - 0
src/mol-model/structure/model/model.ts

@@ -205,6 +205,10 @@ export namespace Model {
         return model.parent || model;
     }
 
+    export function areHierarchiesEqual(a: Model, b: Model) {
+        return a.atomicHierarchy === b.atomicHierarchy && a.coarseHierarchy === b.coarseHierarchy;
+    }
+
     const CoordinatesHistoryProp = '__CoordinatesHistory__';
     export type CoordinatesHistory = {
         areEqual(elements: SortedArray<ElementIndex>, kind: Unit.Kind, model: Model): boolean

+ 29 - 15
src/mol-model/structure/structure/element/loci.ts

@@ -13,7 +13,7 @@ import Structure from '../structure';
 import Unit from '../unit';
 import { sortArray, hashFnv32a, hash2 } from '../../../../mol-data/util';
 import Expression from '../../../../mol-script/language/expression';
-import { ElementIndex } from '../../model';
+import { ElementIndex, Model } from '../../model';
 import { UnitIndex } from './element';
 import { Location } from './location';
 import { ChainIndex } from '../../model/indexing';
@@ -446,27 +446,41 @@ export namespace Loci {
         return Loci(loci.structure, elements);
     }
 
+    function getElementIndices(elements: SortedArray<ElementIndex>, indices: OrderedSet) {
+        const elementIndices: ElementIndex[] = [];
+        for (let i = 0, il = OrderedSet.size(indices); i < il; ++i) {
+            elementIndices.push(elements[OrderedSet.getAt(indices, i)]);
+        }
+        return SortedArray.ofSortedArray<ElementIndex>(elementIndices);
+    }
+
+    function getUnitIndices(elements: SortedArray<ElementIndex>, indices: SortedArray<ElementIndex>) {
+        return SortedArray.indicesOf<ElementIndex, UnitIndex>(elements, indices);
+    }
+
     export function extendToAllInstances(loci: Loci): Loci {
         const elements: Loci['elements'][0][] = [];
-        const byInvariantId = new Map<number, OrderedSet<UnitIndex>>();
-        const { unitSymmetryGroups, unitSymmetryGroupsIndexMap } = loci.structure;
+        const byModel = new Map<Model, SortedArray<ElementIndex>>();
 
         for (let i = 0, len = loci.elements.length; i < len; i++) {
             const e = loci.elements[i];
-            const { invariantId } = e.unit;
-            if (byInvariantId.has(invariantId)) {
-                byInvariantId.set(invariantId, OrderedSet.union(e.indices, byInvariantId.get(invariantId)!));
+            const { model } = e.unit;
+            const elementIndices = getElementIndices(e.unit.elements, e.indices);
+            if (byModel.has(model)) {
+                byModel.set(model, SortedArray.union(elementIndices, byModel.get(model)!));
             } else {
-                byInvariantId.set(invariantId, e.indices);
+                byModel.set(model, elementIndices);
             }
         }
 
-        byInvariantId.forEach((indices, invariantId) => {
-            const { units } = unitSymmetryGroups[unitSymmetryGroupsIndexMap.get(invariantId)];
-            for (let i = 0, il = units.length; i < il; ++i) {
-                elements[elements.length] = { unit: units[i], indices };
-            }
-        });
+        for (let i = 0, il = loci.structure.units.length; i < il; ++i) {
+            const unit = loci.structure.units[i];
+            const elementIndices = byModel.get(unit.model);
+            if (!elementIndices) continue;
+
+            const indices = getUnitIndices(unit.elements, elementIndices);
+            elements[elements.length] = { unit, indices };
+        }
 
         return Loci(loci.structure, elements);
     }
@@ -474,7 +488,7 @@ export namespace Loci {
     //
 
     const boundaryHelper = new BoundaryHelper('98');
-    const tempPosBoundary = Vec3.zero();
+    const tempPosBoundary = Vec3();
     export function getBoundary(loci: Loci): Boundary {
         boundaryHelper.reset();
 
@@ -503,7 +517,7 @@ export namespace Loci {
         return { box: boundaryHelper.getBox(), sphere: boundaryHelper.getSphere() };
     }
 
-    const tempPos = Vec3.zero();
+    const tempPos = Vec3();
     export function toPositionsArray(loci: Loci, positions: NumberArray, offset = 0) {
         let m = offset;
         for (const e of loci.elements) {

+ 7 - 4
src/mol-model/structure/structure/structure.ts

@@ -250,7 +250,7 @@ class Structure {
         return this._props.unitSymmetryGroups;
     }
 
-    /** Maps unit.invariantId to index of SymmetryGroup in unitSymmetryGroups array */
+    /** Maps unit.id to index of SymmetryGroup in unitSymmetryGroups array */
     get unitSymmetryGroupsIndexMap(): IntMap<number> {
         if (this._props.unitSymmetryGroupsIndexMap) return this._props.unitSymmetryGroupsIndexMap;
         this._props.unitSymmetryGroupsIndexMap = Unit.SymmetryGroup.getUnitSymmetryGroupsIndexMap(this.unitSymmetryGroups);
@@ -967,10 +967,13 @@ namespace Structure {
     }
 
     export function areHierarchiesEqual(a: Structure, b: Structure) {
-        if (!areUnitIdsEqual(a, b)) return false;
+        if (a.hashCode !== b.hashCode) return false;
 
-        for (let i = 0, il = a.units.length; i < il; i++) {
-            if (Unit.getHierarchy(a.units[i]) !== Unit.getHierarchy(b.units[i])) return false;
+        const len = a.models.length;
+        if (len !== b.models.length) return false;
+
+        for (let i = 0; i < len; i++) {
+            if (!Model.areHierarchiesEqual(a.models[i], b.models[i])) return false;
         }
         return true;
     }

+ 5 - 2
src/mol-model/structure/structure/unit.ts

@@ -102,8 +102,11 @@ namespace Unit {
 
         export function getUnitSymmetryGroupsIndexMap(symmetryGroups: ReadonlyArray<Unit.SymmetryGroup>): IntMap<number> {
             const unitSymmetryGroupsIndexMap = IntMap.Mutable<number>();
-            for (let i = 0, _i = symmetryGroups.length; i < _i; i++) {
-                unitSymmetryGroupsIndexMap.set(symmetryGroups[i].units[0].invariantId, i);
+            for (let i = 0, il = symmetryGroups.length; i < il; ++i) {
+                const sg = symmetryGroups[i];
+                for (let j = 0, jl = sg.units.length; j < jl; ++j) {
+                    unitSymmetryGroupsIndexMap.set(sg.units[j].id, i);
+                }
             }
             return unitSymmetryGroupsIndexMap;
         }

+ 1 - 5
src/mol-plugin-state/helpers/structure-component.ts

@@ -112,11 +112,7 @@ export function updateStructureComponent(a: Structure, b: SO.Molecule.Structure,
                 return StateTransformer.UpdateResult.Recreate;
             }
             if (b.data.model === a.model) return StateTransformer.UpdateResult.Unchanged;
-            if (Model.getRoot(b.data.model) !== Model.getRoot(a.model)
-                && (a.model.atomicHierarchy !== b.data.model.atomicHierarchy
-                    || a.model.coarseHierarchy !== b.data.model.coarseHierarchy)) {
-                return StateTransformer.UpdateResult.Recreate;
-            }
+            if (!Model.areHierarchiesEqual(a.model, b.data.model)) return StateTransformer.UpdateResult.Recreate;
 
             b.data = b.data.remapModel(a.model);
             return StateTransformer.UpdateResult.Updated;

+ 1 - 5
src/mol-plugin-state/transforms/model.ts

@@ -421,11 +421,7 @@ const StructureFromModel = PluginStateTransform.BuiltIn({
     update: ({ a, b, oldParams, newParams }) => {
         if (!deepEqual(oldParams, newParams)) return StateTransformer.UpdateResult.Recreate;
         if (b.data.model === a.data) return StateTransformer.UpdateResult.Unchanged;
-        if (Model.getRoot(b.data.model) !== Model.getRoot(a.data)
-            && (a.data.atomicHierarchy !== b.data.model.atomicHierarchy
-                || a.data.coarseHierarchy !== b.data.model.coarseHierarchy)) {
-            return StateTransformer.UpdateResult.Recreate;
-        }
+        if (!Model.areHierarchiesEqual(a.data, b.data.model)) return StateTransformer.UpdateResult.Recreate;
 
         b.data = b.data.remapModel(a.data);
 

+ 5 - 6
src/mol-repr/structure/complex-visual.ts

@@ -85,13 +85,8 @@ export function ComplexVisual<G extends Geometry, P extends StructureParams & Ge
 
         VisualUpdateState.reset(updateState);
 
-        if (!renderObject) {
+        if (!renderObject || !currentStructure || !Structure.areEquivalent(newStructure, currentStructure)) {
             updateState.createNew = true;
-        } else if (!currentStructure || !Structure.areEquivalent(newStructure, currentStructure)) {
-            updateState.createNew = true;
-        }
-
-        if (updateState.createNew) {
             updateState.createGeometry = true;
             return;
         }
@@ -111,6 +106,10 @@ export function ComplexVisual<G extends Geometry, P extends StructureParams & Ge
             updateState.createGeometry = true;
         }
 
+        if (updateState.updateSize && !('uSize' in renderObject.values)) {
+            updateState.createGeometry = true;
+        }
+
         if (updateState.createGeometry) {
             updateState.updateColor = true;
             updateState.updateSize = true;

+ 6 - 8
src/mol-repr/structure/units-visual.ts

@@ -92,15 +92,9 @@ export function UnitsVisual<G extends Geometry, P extends StructureParams & Geom
 
         VisualUpdateState.reset(updateState);
 
-        if (!renderObject) {
-            // console.log('create new - no renderObject');
+        if (!renderObject || !currentStructureGroup) {
+            // console.log('create new');
             updateState.createNew = true;
-        } else if (!currentStructureGroup || !Unit.SymmetryGroup.areInvariantElementsEqual(newStructureGroup.group, currentStructureGroup.group)) {
-            // console.log('create new - elements not equal');
-            updateState.createNew = true;
-        }
-
-        if (updateState.createNew) {
             updateState.createGeometry = true;
             return;
         }
@@ -149,6 +143,10 @@ export function UnitsVisual<G extends Geometry, P extends StructureParams & Geom
             updateState.updateMatrix = true;
         }
 
+        if (updateState.updateSize && !('uSize' in renderObject.values)) {
+            updateState.createGeometry = true;
+        }
+
         if (updateState.createGeometry || updateState.updateTransform) {
             if (currentStructureGroup.structure.hashCode !== newStructureGroup.structure.hashCode) {
                 // console.log('new hashCode');

+ 1 - 0
src/mol-repr/structure/visual/util/bond.ts

@@ -154,6 +154,7 @@ export function eachIntraBond(loci: Loci, structureGroup: StructureGroup, apply:
         if (!Unit.isAtomic(unit)) return false;
         const groupCount = unit.bonds.edgeCount * 2;
         for (const b of loci.bonds) {
+            if (b.aUnit !== b.bUnit) continue;
             const unitIdx = group.unitIndexMap.get(b.aUnit.id);
             if (unitIdx !== undefined) {
                 const idx = unit.bonds.getDirectedEdgeIndex(b.aIndex, b.bIndex);