Browse Source

finalize instanceGranularity

Alexander Rose 2 years ago
parent
commit
a16eaca42e

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

@@ -78,6 +78,10 @@ export function ShapeRepresentation<D, G extends Geometry, P extends Geometry.Pa
             console.warn('unexpected state');
         }
 
+        if (props.instanceGranularity !== currentProps.instanceGranularity) {
+            updateState.updateTransform = true;
+        }
+
         if (updateState.updateTransform) {
             updateState.updateColor = true;
             updateState.updateSize = true;
@@ -126,9 +130,9 @@ export function ShapeRepresentation<D, G extends Geometry, P extends Geometry.Pa
                     locationIt = Shape.groupIterator(_shape);
                     const { instanceCount, groupCount } = locationIt;
                     if (props.instanceGranularity) {
-                        createMarkers(instanceCount * groupCount, 'groupInstance', _renderObject.values);
-                    } else {
                         createMarkers(instanceCount, 'instance', _renderObject.values);
+                    } else {
+                        createMarkers(instanceCount * groupCount, 'groupInstance', _renderObject.values);
                     }
                 }
 
@@ -171,11 +175,30 @@ export function ShapeRepresentation<D, G extends Geometry, P extends Geometry.Pa
         });
     }
 
+    function eachInstance(loci: Loci, shape: Shape, apply: (interval: Interval) => boolean) {
+        let changed = false;
+        if (!ShapeGroup.isLoci(loci)) return false;
+        if (ShapeGroup.isLociEmpty(loci)) return false;
+        if (loci.shape !== shape) return false;
+        for (const g of loci.groups) {
+            if (apply(Interval.ofSingleton(g.instance))) changed = true;
+        }
+        return changed;
+    }
+
     function lociApply(loci: Loci, apply: (interval: Interval) => boolean) {
         if (isEveryLoci(loci) || (Shape.isLoci(loci) && loci.shape === _shape)) {
-            return apply(Interval.ofBounds(0, _shape.groupCount * _shape.transforms.length));
+            if (currentProps.instanceGranularity) {
+                return apply(Interval.ofBounds(0, _shape.transforms.length));
+            } else {
+                return apply(Interval.ofBounds(0, _shape.groupCount * _shape.transforms.length));
+            }
         } else {
-            return eachShapeGroup(loci, _shape, apply);
+            if (currentProps.instanceGranularity) {
+                return eachInstance(loci, _shape, apply);
+            } else {
+                return eachShapeGroup(loci, _shape, apply);
+            }
         }
     }
 

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

@@ -6,7 +6,7 @@
 
 import { ParamDefinition as PD } from '../../mol-util/param-definition';
 import { Visual, VisualContext } from '../visual';
-import { Structure, StructureElement } from '../../mol-model/structure';
+import { Bond, Structure, StructureElement } from '../../mol-model/structure';
 import { Geometry, GeometryUtils } from '../../mol-geo/geometry/geometry';
 import { LocationIterator } from '../../mol-geo/util/location-iterator';
 import { Theme } from '../../mol-theme/theme';
@@ -126,6 +126,10 @@ export function ComplexVisual<G extends Geometry, P extends StructureParams & Ge
             updateState.createGeometry = true;
         }
 
+        if (newProps.instanceGranularity !== currentProps.instanceGranularity) {
+            updateState.updateTransform = true;
+        }
+
         if (updateState.updateSize && !('uSize' in renderObject.values)) {
             updateState.createGeometry = true;
         }
@@ -155,9 +159,9 @@ export function ComplexVisual<G extends Geometry, P extends StructureParams & Ge
                 locationIt = createLocationIterator(newStructure);
                 const { instanceCount, groupCount } = locationIt;
                 if (newProps.instanceGranularity) {
-                    createMarkers(instanceCount * groupCount, 'groupInstance', renderObject.values);
-                } else {
                     createMarkers(instanceCount, 'instance', renderObject.values);
+                } else {
+                    createMarkers(instanceCount * groupCount, 'groupInstance', renderObject.values);
                 }
             }
 
@@ -209,11 +213,27 @@ export function ComplexVisual<G extends Geometry, P extends StructureParams & Ge
         return false;
     }
 
+    function eachInstance(loci: Loci, structure: Structure, apply: (interval: Interval) => boolean) {
+        let changed = false;
+        if (!StructureElement.Loci.is(loci) && !Bond.isLoci(loci)) return false;
+        if (!Structure.areEquivalent(loci.structure, structure)) return false;
+        if (apply(Interval.ofSingleton(0))) changed = true;
+        return changed;
+    }
+
     function lociApply(loci: Loci, apply: (interval: Interval) => boolean, isMarking: boolean) {
         if (lociIsSuperset(loci)) {
-            return apply(Interval.ofBounds(0, locationIt.groupCount * locationIt.instanceCount));
+            if (currentProps.instanceGranularity) {
+                return apply(Interval.ofBounds(0, locationIt.instanceCount));
+            } else {
+                return apply(Interval.ofBounds(0, locationIt.groupCount * locationIt.instanceCount));
+            }
         } else {
-            return eachLocation(loci, currentStructure, apply, isMarking);
+            if (currentProps.instanceGranularity) {
+                return eachInstance(loci, currentStructure, apply);
+            } else {
+                return eachLocation(loci, currentStructure, apply, isMarking);
+            }
         }
     }
 

+ 19 - 9
src/mol-repr/structure/units-visual.ts

@@ -5,7 +5,7 @@
  */
 
 import { ParamDefinition as PD } from '../../mol-util/param-definition';
-import { Structure, Unit, StructureElement } from '../../mol-model/structure';
+import { Structure, Unit, StructureElement, Bond } from '../../mol-model/structure';
 import { RepresentationProps } from '../representation';
 import { Visual, VisualContext } from '../visual';
 import { Geometry, GeometryUtils } from '../../mol-geo/geometry/geometry';
@@ -269,14 +269,24 @@ export function UnitsVisual<G extends Geometry, P extends StructureParams & Geom
 
     function eachInstance(loci: Loci, structureGroup: StructureGroup, apply: (interval: Interval) => boolean) {
         let changed = false;
-        if (!StructureElement.Loci.is(loci)) return false;
-        const { structure, group } = structureGroup;
-        if (!Structure.areEquivalent(loci.structure, structure)) return false;
-        const { unitIndexMap } = group;
-        for (const e of loci.elements) {
-            const unitIdx = unitIndexMap.get(e.unit.id);
-            if (unitIdx !== undefined) {
-                if (apply(Interval.ofSingleton(unitIdx))) changed = true;
+        if (Bond.isLoci(loci)) {
+            const { structure, group } = structureGroup;
+            if (!Structure.areEquivalent(loci.structure, structure)) return false;
+            for (const b of loci.bonds) {
+                if (b.aUnit !== b.bUnit) continue;
+                const unitIdx = group.unitIndexMap.get(b.aUnit.id);
+                if (unitIdx !== undefined) {
+                    if (apply(Interval.ofSingleton(unitIdx))) changed = true;
+                }
+            }
+        } else if (StructureElement.Loci.is(loci)) {
+            const { structure, group } = structureGroup;
+            if (!Structure.areEquivalent(loci.structure, structure)) return false;
+            for (const e of loci.elements) {
+                const unitIdx = group.unitIndexMap.get(e.unit.id);
+                if (unitIdx !== undefined) {
+                    if (apply(Interval.ofSingleton(unitIdx))) changed = true;
+                }
             }
         }
         return changed;

+ 36 - 3
src/mol-repr/volume/representation.ts

@@ -33,6 +33,7 @@ import { Clipping } from '../../mol-theme/clipping';
 import { WebGLContext } from '../../mol-gl/webgl/context';
 import { isPromiseLike } from '../../mol-util/type-helpers';
 import { Substance } from '../../mol-theme/substance';
+import { createMarkers } from '../../mol-geo/geometry/marker-data';
 
 export interface VolumeVisual<P extends VolumeParams> extends Visual<Volume, P> { }
 
@@ -108,6 +109,10 @@ export function VolumeVisual<G extends Geometry, P extends VolumeParams & Geomet
         if (updateState.createGeometry) {
             updateState.updateColor = true;
         }
+
+        if (newProps.instanceGranularity !== currentProps.instanceGranularity) {
+            updateState.updateTransform = true;
+        }
     }
 
     function update(newGeometry?: G) {
@@ -124,7 +129,18 @@ export function VolumeVisual<G extends Geometry, P extends VolumeParams & Geomet
                 throw new Error('expected renderObject to be available');
             }
 
-            locationIt.reset();
+            if (updateState.updateTransform) {
+                // console.log('update transform');
+                locationIt = createLocationIterator(newVolume);
+                const { instanceCount, groupCount } = locationIt;
+                if (newProps.instanceGranularity) {
+                    createMarkers(instanceCount, 'instance', renderObject.values);
+                } else {
+                    createMarkers(instanceCount * groupCount, 'groupInstance', renderObject.values);
+                }
+            } else {
+                locationIt.reset();
+            }
 
             if (updateState.createGeometry) {
                 if (newGeometry) {
@@ -165,11 +181,28 @@ export function VolumeVisual<G extends Geometry, P extends VolumeParams & Geomet
         }
     }
 
+    function eachInstance(loci: Loci, volume: Volume, apply: (interval: Interval) => boolean) {
+        let changed = false;
+        if (!Volume.Cell.isLoci(loci)) return false;
+        if (Volume.Cell.isLociEmpty(loci)) return false;
+        if (!Volume.areEquivalent(loci.volume, volume)) return false;
+        if (apply(Interval.ofSingleton(0))) changed = true;
+        return changed;
+    }
+
     function lociApply(loci: Loci, apply: (interval: Interval) => boolean) {
         if (isEveryLoci(loci)) {
-            return apply(Interval.ofBounds(0, locationIt.groupCount * locationIt.instanceCount));
+            if (currentProps.instanceGranularity) {
+                return apply(Interval.ofBounds(0, locationIt.instanceCount));
+            } else {
+                return apply(Interval.ofBounds(0, locationIt.groupCount * locationIt.instanceCount));
+            }
         } else {
-            return eachLocation(loci, currentVolume, currentProps, apply);
+            if (currentProps.instanceGranularity) {
+                return eachInstance(loci, currentVolume, apply);
+            } else {
+                return eachLocation(loci, currentVolume, currentProps, apply);
+            }
         }
     }