From da3acd9d19459f3d270c637cb9530f5584d0c5f2 Mon Sep 17 00:00:00 2001
From: Alexander Rose <alex.rose@rcsb.org>
Date: Wed, 2 Oct 2019 17:53:51 -0700
Subject: [PATCH] calculate model center as dynamic prop

---
 src/mol-model/structure/model/model.ts | 10 ++++++
 src/mol-model/structure/model/util.ts  | 45 ++++++++++++++++++++++++++
 2 files changed, 55 insertions(+)
 create mode 100644 src/mol-model/structure/model/util.ts

diff --git a/src/mol-model/structure/model/model.ts b/src/mol-model/structure/model/model.ts
index de0649f49..5c2a45a64 100644
--- a/src/mol-model/structure/model/model.ts
+++ b/src/mol-model/structure/model/model.ts
@@ -15,6 +15,8 @@ import { CustomProperties } from '../common/custom-property';
 import { SecondaryStructure } from './properties/seconday-structure';
 import { SaccharideComponentMap } from '../structure/carbohydrates/constants';
 import { ModelFormat } from '../../../mol-model-formats/structure/format';
+import { calcModelCenter } from './util';
+import { Vec3 } from '../../../mol-math/linear-algebra';
 
 /**
  * Interface to the "source data" of the molecule.
@@ -75,4 +77,12 @@ export interface Model extends Readonly<{
 export namespace Model {
     // TODO: is this enough?
     export type Trajectory = ReadonlyArray<Model>
+
+    const CenterProp = '__Center__'
+    export function getCenter(model: Model): Vec3 {
+        if (model._dynamicPropertyData[CenterProp]) return model._dynamicPropertyData[CenterProp]
+        const center = calcModelCenter(model.atomicConformation, model.coarseConformation)
+        model._dynamicPropertyData[CenterProp] = center
+        return center
+    }
 }
\ No newline at end of file
diff --git a/src/mol-model/structure/model/util.ts b/src/mol-model/structure/model/util.ts
new file mode 100644
index 000000000..2793632f7
--- /dev/null
+++ b/src/mol-model/structure/model/util.ts
@@ -0,0 +1,45 @@
+/**
+ * Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ */
+
+import { Vec3 } from '../../../mol-math/linear-algebra';
+import { AtomicConformation } from './properties/atomic';
+import { CoarseConformation } from './properties/coarse';
+import { arrayMinMax } from '../../../mol-util/array';
+
+export function calcModelCenter(atomicConformation: AtomicConformation, coarseConformation?: CoarseConformation) {
+    let rangesX: number[] = []
+    let rangesY: number[] = []
+    let rangesZ: number[] = []
+
+    if (atomicConformation.x.length) {
+        rangesX.push(...arrayMinMax(atomicConformation.x))
+        rangesY.push(...arrayMinMax(atomicConformation.y))
+        rangesZ.push(...arrayMinMax(atomicConformation.z))
+    }
+
+    if (coarseConformation) {
+        if (coarseConformation.spheres.x.length) {
+            rangesX.push(...arrayMinMax(coarseConformation.spheres.x))
+            rangesY.push(...arrayMinMax(coarseConformation.spheres.y))
+            rangesZ.push(...arrayMinMax(coarseConformation.spheres.z))
+        }
+        if (coarseConformation.gaussians.x.length) {
+            rangesX.push(...arrayMinMax(coarseConformation.gaussians.x))
+            rangesY.push(...arrayMinMax(coarseConformation.gaussians.y))
+            rangesZ.push(...arrayMinMax(coarseConformation.gaussians.z))
+        }
+    }
+
+    const [minX, maxX] = arrayMinMax(rangesX)
+    const [minY, maxY] = arrayMinMax(rangesY)
+    const [minZ, maxZ] = arrayMinMax(rangesZ)
+
+    const x = minX + (maxX - minX) / 2
+    const y = minY + (maxY - minY) / 2
+    const z = minZ + (maxZ - minZ) / 2
+
+    return Vec3.create(x, y, z)
+}
\ No newline at end of file
-- 
GitLab