From 582a0e2a38a9c4573566927537dabac38748092c Mon Sep 17 00:00:00 2001 From: Alexander Rose <alexander.rose@weirdbyte.de> Date: Sat, 29 Jan 2022 11:13:19 -0800 Subject: [PATCH] fix Sphere.expand for highly directional extrema --- CHANGELOG.md | 2 ++ src/mol-math/geometry/primitives/sphere3d.ts | 26 ++++++++++++++++--- .../visual/molecular-surface-mesh.ts | 4 +-- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 993d1e72f..28d051aa7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ Note that since we don't clearly distinguish between a public and private interf ## [Unreleased] +- Fix color smoothing of elongated structures (by fixing ``Sphere.expand`` for spheres with highly directional extrema) + ## [v3.0.1] - 2022-01-27 - Fix marking pass not working with ``transparentBackground`` diff --git a/src/mol-math/geometry/primitives/sphere3d.ts b/src/mol-math/geometry/primitives/sphere3d.ts index 1f4287627..8356dbf0d 100644 --- a/src/mol-math/geometry/primitives/sphere3d.ts +++ b/src/mol-math/geometry/primitives/sphere3d.ts @@ -1,5 +1,5 @@ /** - * Copyright (c) 2018-2020 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 David Sehnal <david.sehnal@gmail.com> * @author Alexander Rose <alexander.rose@weirdbyte.de> @@ -11,6 +11,7 @@ import { OrderedSet } from '../../../mol-data/int'; import { NumberArray, PickRequired } from '../../../mol-util/type-helpers'; import { Box3D } from './box3d'; import { Axes3D } from './axes3d'; +import { PrincipalAxes } from '../../linear-algebra/matrix/principal-axes'; interface Sphere3D { center: Vec3, @@ -202,11 +203,28 @@ namespace Sphere3D { return out; } if (hasExtrema(sphere)) { + const positions = new Float32Array(sphere.extrema.length * 3); + for (let i = 0; i < sphere.extrema.length; i++) { + Vec3.toArray(sphere.extrema[i], positions, i * 3); + } + + const axes = PrincipalAxes.calculateMomentsAxes(positions); + Axes3D.scale(axes, Axes3D.normalize(axes, axes), delta); + setExtrema(out, sphere.extrema.map(e => { Vec3.sub(tmpDir, e, sphere.center); - const dist = Vec3.distance(sphere.center, e); - Vec3.normalize(tmpDir, tmpDir); - return Vec3.scaleAndAdd(Vec3(), sphere.center, tmpDir, dist + delta); + const out = Vec3.clone(e); + + const sA = Vec3.dot(tmpDir, axes.dirA) < 0 ? -1 : 1; + Vec3.scaleAndAdd(out, out, axes.dirA, sA); + + const sB = Vec3.dot(tmpDir, axes.dirB) < 0 ? -1 : 1; + Vec3.scaleAndAdd(out, out, axes.dirB, sB); + + const sC = Vec3.dot(tmpDir, axes.dirC) < 0 ? -1 : 1; + Vec3.scaleAndAdd(out, out, axes.dirC, sC); + + return out; })); } return out; diff --git a/src/mol-repr/structure/visual/molecular-surface-mesh.ts b/src/mol-repr/structure/visual/molecular-surface-mesh.ts index 08f329686..306bccb0c 100644 --- a/src/mol-repr/structure/visual/molecular-surface-mesh.ts +++ b/src/mol-repr/structure/visual/molecular-surface-mesh.ts @@ -1,5 +1,5 @@ /** - * Copyright (c) 2019-2021 mol* contributors, licensed under MIT, See LICENSE file for more info. + * Copyright (c) 2019-2022 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose <alexander.rose@weirdbyte.de> */ @@ -57,7 +57,7 @@ async function createMolecularSurfaceMesh(ctx: VisualContext, unit: Unit, struct Mesh.transform(surface, transform); if (ctx.webgl && !ctx.webgl.isWebGL2) Mesh.uniformTriangleGroup(surface); - const sphere = Sphere3D.expand(Sphere3D(), unit.boundary.sphere, props.probeRadius + getUnitExtraRadius(unit)); + const sphere = Sphere3D.expand(Sphere3D(), unit.boundary.sphere, getUnitExtraRadius(unit)); surface.setBoundingSphere(sphere); (surface.meta as MolecularSurfaceMeta).resolution = resolution; -- GitLab