Преглед изворни кода

reuse unit boundary if it has not changed too much

Alexander Rose пре 3 година
родитељ
комит
ad08e7c67f
3 измењених фајлова са 27 додато и 34 уклоњено
  1. 1 0
      CHANGELOG.md
  2. 23 2
      src/mol-model/structure/structure/unit.ts
  3. 3 32
      src/mol-repr/structure/visual/util/element.ts

+ 1 - 0
CHANGELOG.md

@@ -14,6 +14,7 @@ Note that since we don't clearly distinguish between a public and private interf
 - Change line geometry default ``scaleFactor`` to 2 (3 is too big after fixing line rendering)
 - Trajectory animation performance improvements
     - Reuse ``Model.CoarseGrained`` for coordinate trajectories
+    - Reuse unit boundary if sphere has not changed too much
     - Don't show 'inter-bond' and 'element-cross' visuals in line representations of polymerAndLigand preset
 - Fix additional mononucleotides detected as polymer components
 

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

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2017-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2017-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>
@@ -26,6 +26,9 @@ import { IndexPairBonds } from '../../../mol-model-formats/structure/property/bo
 import { ElementSetIntraBondCache } from './unit/bonds/element-set-intra-bond-cache';
 import { ModelSymmetry } from '../../../mol-model-formats/structure/property/symmetry';
 
+// avoiding namespace lookup improved performance in Chrome (Aug 2020)
+const v3add = Vec3.add;
+
 /**
  * A building block of a structure that corresponds to an atomic or
  * a coarse grained representation 'conveniently grouped together'.
@@ -222,7 +225,25 @@ namespace Unit {
             if (!props) {
                 props = { ...this.props, bonds: dynamicBonds ? undefined : tryRemapBonds(this, this.props.bonds, model) };
                 if (!Unit.isSameConformation(this, model)) {
-                    props.boundary = undefined;
+                    const b = props.boundary;
+                    if (b) {
+                        const { elements } = this;
+                        const pos = this.conformation.invariantPosition;
+                        const v = Vec3();
+                        const center = Vec3();
+
+                        for (let i = 0, il = elements.length; i < il; i++) {
+                            pos(elements[i], v);
+                            v3add(center, center, v);
+                        }
+                        Vec3.scale(center, center, 1 / elements.length);
+
+                        // only invalidate boundary if sphere has changed too much
+                        if (Vec3.distance(center, b.sphere.center) / b.sphere.radius >= 1.0) {
+                            props.boundary = undefined;
+                        }
+                    }
+
                     props.lookup3d = undefined;
                     props.principalAxes = undefined;
                 }

+ 3 - 32
src/mol-repr/structure/visual/util/element.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>
@@ -22,9 +22,6 @@ import { SpheresBuilder } from '../../../../mol-geo/geometry/spheres/spheres-bui
 import { isTrace, isH, StructureGroup } from './common';
 import { Sphere3D } from '../../../../mol-math/geometry';
 
-// avoiding namespace lookup improved performance in Chrome (Aug 2020)
-const v3add = Vec3.add;
-
 type ElementProps = {
     ignoreHydrogens: boolean,
     traceOnly: boolean,
@@ -73,17 +70,13 @@ export function createElementSphereMesh(ctx: VisualContext, unit: Unit, structur
     const ignore = makeElementIgnoreTest(structure, unit, props);
     const l = StructureElement.Location.create(structure, unit);
     const themeSize = theme.size.size;
-    const center = Vec3();
     let maxSize = 0;
-    let count = 0;
 
     for (let i = 0; i < elementCount; i++) {
         if (ignore && ignore(elements[i])) continue;
 
         l.element = elements[i];
         pos(elements[i], v);
-        v3add(center, center, v);
-        count += 1;
 
         builderState.currentGroup = i;
         const size = themeSize(l);
@@ -92,17 +85,8 @@ export function createElementSphereMesh(ctx: VisualContext, unit: Unit, structur
         addSphere(builderState, v, size * sizeFactor, detail);
     }
 
-    // re-use boundingSphere if it has not changed much
-    let boundingSphere: Sphere3D;
-    Vec3.scale(center, center, 1 / count);
-    if (mesh && Vec3.distance(center, mesh.boundingSphere.center) / mesh.boundingSphere.radius < 1.0) {
-        boundingSphere = Sphere3D.clone(mesh.boundingSphere);
-    } else {
-        boundingSphere = Sphere3D.expand(Sphere3D(), (childUnit ?? unit).boundary.sphere, maxSize * sizeFactor + 0.05);
-    }
-
     const m = MeshBuilder.getMesh(builderState);
-    m.setBoundingSphere(boundingSphere);
+    m.setBoundingSphere(Sphere3D.expand(Sphere3D(), (childUnit ?? unit).boundary.sphere, maxSize * sizeFactor + 0.05));
 
     return m;
 }
@@ -126,34 +110,21 @@ export function createElementSphereImpostor(ctx: VisualContext, unit: Unit, stru
 
     const l = StructureElement.Location.create(structure, unit);
     const themeSize = theme.size.size;
-    const center = Vec3();
     let maxSize = 0;
-    let count = 0;
 
     for (let i = 0; i < elementCount; i++) {
         if (ignore?.(elements[i])) continue;
 
         pos(elements[i], v);
         builder.add(v[0], v[1], v[2], i);
-        v3add(center, center, v);
-        count += 1;
 
         l.element = elements[i];
         const size = themeSize(l);
         if (size > maxSize) maxSize = size;
     }
 
-    // re-use boundingSphere if it has not changed much
-    let boundingSphere: Sphere3D;
-    Vec3.scale(center, center, 1 / count);
-    if (spheres && Vec3.distance(center, spheres.boundingSphere.center) / spheres.boundingSphere.radius < 1.0) {
-        boundingSphere = Sphere3D.clone(spheres.boundingSphere);
-    } else {
-        boundingSphere = Sphere3D.expand(Sphere3D(), (childUnit ?? unit).boundary.sphere, maxSize * props.sizeFactor + 0.05);
-    }
-
     const s = builder.getSpheres();
-    s.setBoundingSphere(boundingSphere);
+    s.setBoundingSphere(Sphere3D.expand(Sphere3D(), (childUnit ?? unit).boundary.sphere, maxSize * props.sizeFactor + 0.05));
 
     return s;
 }