Browse Source

decoupled structure.boundary from lookup

Alexander Rose 4 years ago
parent
commit
8897261836

+ 1 - 1
src/mol-math/geometry/lookup3d/grid.ts

@@ -11,7 +11,7 @@ import { Sphere3D } from '../primitives/sphere3d';
 import { PositionData } from '../common';
 import { Vec3 } from '../../linear-algebra';
 import { OrderedSet } from '../../../mol-data/int';
-import { Boundary } from '../../../mol-model/structure/structure/util/boundary';
+import { Boundary } from '../boundary';
 
 interface GridLookup3D<T = number> extends Lookup3D<T> {
     readonly buckets: { readonly offset: ArrayLike<number>, readonly count: ArrayLike<number>, readonly array: ArrayLike<number> }

+ 1 - 1
src/mol-math/geometry/molecular-surface.ts

@@ -15,7 +15,7 @@ import { PositionData } from './common';
 import { Mat4 } from '../../mol-math/linear-algebra/3d';
 import { Box3D, GridLookup3D, fillGridDim } from '../../mol-math/geometry';
 import { BaseGeometry } from '../../mol-geo/geometry/base';
-import { Boundary } from '../../mol-model/structure/structure/util/boundary';
+import { Boundary } from './boundary';
 
 function normalToLine (out: Vec3, p: Vec3) {
     out[0] = out[1] = out[2] = 1.0;

+ 1 - 1
src/mol-model/structure/structure/element/loci.ts

@@ -11,7 +11,6 @@ import { Vec3 } from '../../../../mol-math/linear-algebra';
 import { MolScriptBuilder as MS } from '../../../../mol-script/language/builder';
 import Structure from '../structure';
 import Unit from '../unit';
-import { Boundary } from '../util/boundary';
 import { sortArray, hashFnv32a, hash2 } from '../../../../mol-data/util';
 import Expression from '../../../../mol-script/language/expression';
 import { ElementIndex } from '../../model';
@@ -22,6 +21,7 @@ import { PrincipalAxes } from '../../../../mol-math/linear-algebra/matrix/princi
 import { NumberArray } from '../../../../mol-util/type-helpers';
 import StructureProperties from '../properties';
 import { BoundaryHelper } from '../../../../mol-math/geometry/boundary-helper';
+import { Boundary } from '../../../../mol-math/geometry/boundary';
 
 /** Represents multiple structure element index locations */
 export interface Loci {

+ 6 - 2
src/mol-model/structure/structure/structure.ts

@@ -28,11 +28,12 @@ import { UUID } from '../../../mol-util';
 import { CustomProperties } from '../../custom-property';
 import { AtomicHierarchy } from '../model/properties/atomic';
 import { StructureSelection } from '../query/selection';
-import { getBoundary } from '../../../mol-math/geometry/boundary';
+import { getBoundary, Boundary } from '../../../mol-math/geometry/boundary';
 import { ElementSymbol } from '../model/types';
 import { CustomStructureProperty } from '../../../mol-model-props/common/custom-structure-property';
 import { Trajectory } from '../trajectory';
 import { RuntimeContext, Task } from '../../../mol-task';
+import { computeStructureBoundary } from './util/boundary';
 
 class Structure {
     /** Maps unit.id to unit */
@@ -44,6 +45,7 @@ class Structure {
 
     private _props: {
         parent?: Structure,
+        boundary?: Boundary,
         lookup3d?: StructureLookup3D,
         interUnitBonds?: InterUnitBonds,
         unitSymmetryGroups?: ReadonlyArray<Unit.SymmetryGroup>,
@@ -225,7 +227,9 @@ class Structure {
     }
 
     get boundary() {
-        return this.lookup3d.boundary;
+        if (this._props.boundary) return this._props.boundary;
+        this._props.boundary = computeStructureBoundary(this);
+        return this._props.boundary;
     }
 
     get lookup3d() {

+ 13 - 21
src/mol-model/structure/structure/util/boundary.ts

@@ -5,24 +5,23 @@
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
 
-import { Box3D, Sphere3D } from '../../../../mol-math/geometry';
-import { Vec3 } from '../../../../mol-math/linear-algebra';
+import { Sphere3D } from '../../../../mol-math/geometry';
 import Structure from '../structure';
 import { BoundaryHelper } from '../../../../mol-math/geometry/boundary-helper';
+import { Boundary } from '../../../../mol-math/geometry/boundary';
 
-export type Boundary = { box: Box3D, sphere: Sphere3D }
-
-const tmpBox = Box3D();
 const tmpSphere = Sphere3D();
 
-const boundaryHelper = new BoundaryHelper('98');
+const boundaryHelperCoarse = new BoundaryHelper('14');
+const boundaryHelperFine = new BoundaryHelper('98');
+function getBoundaryHelper(count: number) {
+    return count > 10_000 ? boundaryHelperCoarse : boundaryHelperFine;
+}
 
 export function computeStructureBoundary(s: Structure): Boundary {
-    const min = Vec3.create(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
-    const max = Vec3.create(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);
-
     const { units } = s;
 
+    const boundaryHelper = getBoundaryHelper(units.length);
     boundaryHelper.reset();
 
     for (let i = 0, _i = units.length; i < _i; i++) {
@@ -31,17 +30,10 @@ export function computeStructureBoundary(s: Structure): Boundary {
         const o = u.conformation.operator;
 
         if (o.isIdentity) {
-            Vec3.min(min, min, invariantBoundary.box.min);
-            Vec3.max(max, max, invariantBoundary.box.max);
-
-            boundaryHelper.includePositionRadius(invariantBoundary.sphere.center, invariantBoundary.sphere.radius);
+            boundaryHelper.includeSphere(invariantBoundary.sphere);
         } else {
-            Box3D.transform(tmpBox, invariantBoundary.box, o.matrix);
-            Vec3.min(min, min, tmpBox.min);
-            Vec3.max(max, max, tmpBox.max);
-
             Sphere3D.transform(tmpSphere, invariantBoundary.sphere, o.matrix);
-            boundaryHelper.includePositionRadius(tmpSphere.center, tmpSphere.radius);
+            boundaryHelper.includeSphere(tmpSphere);
         }
     }
 
@@ -53,12 +45,12 @@ export function computeStructureBoundary(s: Structure): Boundary {
         const o = u.conformation.operator;
 
         if (o.isIdentity) {
-            boundaryHelper.radiusPositionRadius(invariantBoundary.sphere.center, invariantBoundary.sphere.radius);
+            boundaryHelper.radiusSphere(invariantBoundary.sphere);
         } else {
             Sphere3D.transform(tmpSphere, invariantBoundary.sphere, o.matrix);
-            boundaryHelper.radiusPositionRadius(tmpSphere.center, tmpSphere.radius);
+            boundaryHelper.radiusSphere(tmpSphere);
         }
     }
 
-    return { box: { min, max }, sphere: boundaryHelper.getSphere() };
+    return { box: boundaryHelper.getBox(), sphere: boundaryHelper.getSphere() };
 }

+ 5 - 11
src/mol-model/structure/structure/util/lookup3d.ts

@@ -1,19 +1,17 @@
 /**
- * Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2018-2020 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>
  */
 
 import Structure from '../structure';
-import { Lookup3D, GridLookup3D, Box3D, Sphere3D, Result } from '../../../../mol-math/geometry';
+import { Lookup3D, GridLookup3D, Result } from '../../../../mol-math/geometry';
 import { Vec3 } from '../../../../mol-math/linear-algebra';
-import { computeStructureBoundary } from './boundary';
 import { OrderedSet } from '../../../../mol-data/int';
 import { StructureUniqueSubsetBuilder } from './unique-subset-builder';
 import StructureElement from '../element';
 import Unit from '../unit';
-import { getBoundary } from '../../../../mol-math/geometry/boundary';
 
 export interface StructureResult extends Result<StructureElement.UnitIndex> {
     units: Unit[]
@@ -145,16 +143,12 @@ export class StructureLookup3D {
         return false;
     }
 
-    _boundary: { box: Box3D; sphere: Sphere3D; } | undefined = void 0;
-
     get boundary() {
-        if (this._boundary) return this._boundary!;
-        this._boundary = computeStructureBoundary(this.structure);
-        return this._boundary!;
+        return this.structure.boundary;
     }
 
     constructor(private structure: Structure) {
-        const { units } = structure;
+        const { units, boundary } = structure;
         const unitCount = units.length;
         const xs = new Float32Array(unitCount);
         const ys = new Float32Array(unitCount);
@@ -176,6 +170,6 @@ export class StructureLookup3D {
         }
 
         const position = { x: xs, y: ys, z: zs, radius, indices: OrderedSet.ofBounds(0, unitCount) };
-        this.unitLookup = GridLookup3D(position, getBoundary(position));
+        this.unitLookup = GridLookup3D(position, boundary);
     }
 }

+ 1 - 1
src/mol-plugin-state/manager/structure/selection.ts

@@ -11,7 +11,6 @@ import { Vec3 } from '../../../mol-math/linear-algebra';
 import { PrincipalAxes } from '../../../mol-math/linear-algebra/matrix/principal-axes';
 import { EmptyLoci, Loci } from '../../../mol-model/loci';
 import { Structure, StructureElement, StructureSelection } from '../../../mol-model/structure';
-import { Boundary } from '../../../mol-model/structure/structure/util/boundary';
 import { PluginContext } from '../../../mol-plugin/context';
 import { StateObjectRef } from '../../../mol-state';
 import { Task } from '../../../mol-task';
@@ -22,6 +21,7 @@ import { StructureSelectionQuery } from '../../helpers/structure-selection-query
 import { PluginStateObject as PSO } from '../../objects';
 import { UUID } from '../../../mol-util';
 import { StructureRef } from './hierarchy-state';
+import { Boundary } from '../../../mol-math/geometry/boundary';
 
 interface StructureSelectionManagerState {
     entries: Map<string, SelectionEntry>,