Browse Source

fix repr update for Structure.asParent objects

Alexander Rose 3 years ago
parent
commit
65ba401850

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

@@ -368,13 +368,16 @@ class Structure {
 
     private _child: Structure | undefined;
     private _target: Structure | undefined;
+    private _proxy: Structure | undefined;
 
     /**
      * For `structure` with `parent` this returns a proxy that
      * targets `parent` and has `structure` attached as a child.
      */
     asParent(): Structure {
-        return this.parent ? new Structure(this.parent.units, this.parent.unitMap, this.parent.unitIndexMap, this.parent.state, { child: this, target: this.parent }) : this;
+        if (this._proxy) return this._proxy;
+        this._proxy = this.parent ? new Structure(this.parent.units, this.parent.unitMap, this.parent.unitIndexMap, this.parent.state, { child: this, target: this.parent }) : this;
+        return this._proxy;
     }
 
     get child(): Structure | undefined {

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

@@ -118,6 +118,11 @@ export function ComplexVisual<G extends Geometry, P extends StructureParams & Ge
             updateState.createGeometry = true;
         }
 
+        if (currentStructure.child !== newStructure.child) {
+            // console.log('new child');
+            updateState.createGeometry = true;
+        }
+
         if (updateState.updateSize && !('uSize' in renderObject.values)) {
             updateState.createGeometry = true;
         }

+ 1 - 1
src/mol-repr/structure/units-representation.ts

@@ -66,7 +66,7 @@ export function UnitsRepresentation<P extends StructureParams>(label: string, ct
                     visuals.set(group.hashCode, { visual, group });
                     if (runtime.shouldUpdate) await runtime.update({ message: 'Creating or updating UnitsVisual', current: i, max: _groups.length });
                 }
-            } else if (structure && !Structure.areUnitIdsAndIndicesEqual(structure, _structure)) {
+            } else if (structure && (!Structure.areUnitIdsAndIndicesEqual(structure, _structure) || structure.child !== _structure.child)) {
                 // console.log(label, 'structures not equivalent');
                 // Tries to re-use existing visuals for the groups of the new structure.
                 // Creates additional visuals if needed, destroys left-over visuals.

+ 5 - 0
src/mol-repr/structure/units-visual.ts

@@ -120,6 +120,11 @@ export function UnitsVisual<G extends Geometry, P extends StructureParams & Geom
             updateState.updateColor = true;
         }
 
+        if (currentStructureGroup.structure.child !== newStructureGroup.structure.child) {
+            // console.log('new child');
+            updateState.createGeometry = true;
+        }
+
         if (!deepEqual(newProps.unitKinds, currentProps.unitKinds)) {
             // console.log('new unitKinds');
             updateState.createGeometry = true;

+ 4 - 6
src/mol-repr/structure/visual/bond-inter-unit-cylinder.ts

@@ -11,7 +11,7 @@ import { Theme } from '../../../mol-theme/theme';
 import { Mesh } from '../../../mol-geo/geometry/mesh/mesh';
 import { Vec3 } from '../../../mol-math/linear-algebra';
 import { BitFlags, arrayEqual } from '../../../mol-util';
-import { createLinkCylinderImpostors, createLinkCylinderMesh, LinkStyle } from './util/link';
+import { createLinkCylinderImpostors, createLinkCylinderMesh, LinkBuilderProps, LinkStyle } from './util/link';
 import { ComplexMeshParams, ComplexVisual, ComplexMeshVisual, ComplexCylindersParams, ComplexCylindersVisual } from '../complex-visual';
 import { VisualUpdateState } from '../../util';
 import { BondType } from '../../../mol-model/structure/model/types';
@@ -34,7 +34,7 @@ function setRefPosition(pos: Vec3, structure: Structure, unit: Unit.Atomic, inde
 
 const tmpRef = Vec3();
 
-function getInterUnitBondCylinderBuilderProps(structure: Structure, theme: Theme, props: PD.Values<InterUnitBondCylinderParams>) {
+function getInterUnitBondCylinderBuilderProps(structure: Structure, theme: Theme, props: PD.Values<InterUnitBondCylinderParams>): LinkBuilderProps {
     const locE = StructureElement.Location.create(structure);
     const locB = Bond.Location(structure, undefined, undefined, structure, undefined, undefined);
 
@@ -46,10 +46,8 @@ function getInterUnitBondCylinderBuilderProps(structure: Structure, theme: Theme
 
     let stub: undefined | ((edgeIndex: number) => boolean);
 
-    if (props.includeParent) {
-        const { child } = structure;
-        if (!child) throw new Error('expected child to exist');
-
+    const { child } = structure;
+    if (props.includeParent && child) {
         stub = (edgeIndex: number) => {
             const b = edges[edgeIndex];
             const childUnitA = child.unitMap.get(b.unitA);

+ 2 - 2
src/mol-repr/structure/visual/bond-inter-unit-line.ts

@@ -10,7 +10,7 @@ import { Structure, StructureElement, Bond, Unit } from '../../../mol-model/stru
 import { Theme } from '../../../mol-theme/theme';
 import { Vec3 } from '../../../mol-math/linear-algebra';
 import { BitFlags, arrayEqual } from '../../../mol-util';
-import { LinkStyle, createLinkLines } from './util/link';
+import { LinkStyle, createLinkLines, LinkBuilderProps } from './util/link';
 import { ComplexVisual, ComplexLinesVisual, ComplexLinesParams } from '../complex-visual';
 import { VisualUpdateState } from '../../util';
 import { BondType } from '../../../mol-model/structure/model/types';
@@ -39,7 +39,7 @@ function createInterUnitBondLines(ctx: VisualContext, structure: Structure, them
     const ref = Vec3();
     const loc = StructureElement.Location.create();
 
-    const builderProps = {
+    const builderProps: LinkBuilderProps = {
         linkCount: edgeCount,
         referencePosition: (edgeIndex: number) => {
             const b = edges[edgeIndex];

+ 4 - 5
src/mol-repr/structure/visual/bond-intra-unit-cylinder.ts

@@ -12,7 +12,7 @@ import { Theme } from '../../../mol-theme/theme';
 import { Mesh } from '../../../mol-geo/geometry/mesh/mesh';
 import { Vec3 } from '../../../mol-math/linear-algebra';
 import { arrayEqual } from '../../../mol-util';
-import { createLinkCylinderImpostors, createLinkCylinderMesh, LinkStyle } from './util/link';
+import { createLinkCylinderImpostors, createLinkCylinderMesh, LinkBuilderProps, LinkStyle } from './util/link';
 import { UnitsMeshParams, UnitsVisual, UnitsMeshVisual, StructureGroup, UnitsCylindersParams, UnitsCylindersVisual } from '../units-visual';
 import { VisualUpdateState } from '../../util';
 import { BondType } from '../../../mol-model/structure/model/types';
@@ -26,7 +26,7 @@ import { SortedArray } from '../../../mol-data/int';
 // avoiding namespace lookup improved performance in Chrome (Aug 2020)
 const isBondType = BondType.is;
 
-function getIntraUnitBondCylinderBuilderProps(unit: Unit.Atomic, structure: Structure, theme: Theme, props: PD.Values<IntraUnitBondCylinderParams>) {
+function getIntraUnitBondCylinderBuilderProps(unit: Unit.Atomic, structure: Structure, theme: Theme, props: PD.Values<IntraUnitBondCylinderParams>): LinkBuilderProps {
     const elements = unit.elements;
     const bonds = unit.bonds;
     const { edgeCount, a, b, edgeProps, offset } = bonds;
@@ -41,9 +41,8 @@ function getIntraUnitBondCylinderBuilderProps(unit: Unit.Atomic, structure: Stru
     const locE = StructureElement.Location.create(structure, unit);
     const locB = Bond.Location(structure, unit, undefined, structure, unit, undefined);
 
-    if (props.includeParent) {
-        const { child } = structure;
-        if (!child) throw new Error('expected child to exist');
+    const { child } = structure;
+    if (props.includeParent && child) {
         const childUnit = child.unitMap.get(unit.id);
         if (!childUnit) throw new Error('expected childUnit to exist');
 

+ 1 - 5
src/mol-repr/structure/visual/bond-intra-unit-line.ts

@@ -10,7 +10,7 @@ import { Unit, Structure, StructureElement } from '../../../mol-model/structure'
 import { Theme } from '../../../mol-theme/theme';
 import { Vec3 } from '../../../mol-math/linear-algebra';
 import { arrayEqual } from '../../../mol-util';
-import { LinkStyle, createLinkLines } from './util/link';
+import { LinkStyle, createLinkLines, LinkBuilderProps } from './util/link';
 import { UnitsVisual, UnitsLinesParams, UnitsLinesVisual, StructureGroup } from '../units-visual';
 import { VisualUpdateState } from '../../util';
 import { BondType } from '../../../mol-model/structure/model/types';
@@ -29,10 +29,6 @@ function createIntraUnitBondLines(ctx: VisualContext, unit: Unit, structure: Str
     const childUnit = child?.unitMap.get(unit.id);
     if (child && !childUnit) return Lines.createEmpty(lines);
 
-    if (props.includeParent) {
-        if (!child) throw new Error('expected child to exist');
-    }
-
     const location = StructureElement.Location.create(structure, unit);
 
     const elements = unit.elements;