From 27f10d52d05fa8b2e350a1e31f7db346e8fb67a8 Mon Sep 17 00:00:00 2001 From: David Sehnal <david.sehnal@gmail.com> Date: Fri, 1 Mar 2019 22:42:37 +0100 Subject: [PATCH] mol-plugin: StructureElement.Loci.getBoundary --- src/mol-model/loci.ts | 20 +----------- src/mol-model/structure/structure/element.ts | 32 +++++++++++++++++++ .../dynamic/volume-streaming/behavior.ts | 17 +++++----- 3 files changed, 41 insertions(+), 28 deletions(-) diff --git a/src/mol-model/loci.ts b/src/mol-model/loci.ts index 34bb4d4e6..35cad50ed 100644 --- a/src/mol-model/loci.ts +++ b/src/mol-model/loci.ts @@ -81,25 +81,7 @@ namespace Loci { if (loci.kind === 'structure-loci') { return Sphere3D.copy(boundingSphere, loci.structure.boundary.sphere) } else if (loci.kind === 'element-loci') { - for (const e of loci.elements) { - const { indices } = e; - const pos = e.unit.conformation.position; - const { elements } = e.unit; - for (let i = 0, _i = OrderedSet.size(indices); i < _i; i++) { - pos(elements[OrderedSet.getAt(indices, i)], tempPos); - sphereHelper.includeStep(tempPos); - } - } - sphereHelper.finishedIncludeStep(); - for (const e of loci.elements) { - const { indices } = e; - const pos = e.unit.conformation.position; - const { elements } = e.unit; - for (let i = 0, _i = OrderedSet.size(indices); i < _i; i++) { - pos(elements[OrderedSet.getAt(indices, i)], tempPos); - sphereHelper.radiusStep(tempPos); - } - } + return StructureElement.Loci.getBoundary(loci).sphere; } else if (loci.kind === 'link-loci') { for (const e of loci.links) { e.aUnit.conformation.position(e.aUnit.elements[e.aIndex], tempPos); diff --git a/src/mol-model/structure/structure/element.ts b/src/mol-model/structure/structure/element.ts index 4e5148225..1bd19cde9 100644 --- a/src/mol-model/structure/structure/element.ts +++ b/src/mol-model/structure/structure/element.ts @@ -9,6 +9,9 @@ import Unit from './unit' import { ElementIndex } from '../model'; import { ResidueIndex, ChainIndex } from '../model/indexing'; import Structure from './structure'; +import { Boundary } from './util/boundary'; +import { BoundaryHelper } from 'mol-math/geometry/boundary-helper'; +import { Vec3 } from 'mol-math/linear-algebra'; interface StructureElement<U = Unit> { readonly kind: 'element-location', @@ -208,6 +211,35 @@ namespace StructureElement { return Loci(loci.structure, elements); } + + const boundaryHelper = new BoundaryHelper(), tempPos = Vec3.zero(); + export function getBoundary(loci: Loci): Boundary { + boundaryHelper.reset(0); + + for (const e of loci.elements) { + const { indices } = e; + const pos = e.unit.conformation.position, r = e.unit.conformation.r; + const { elements } = e.unit; + for (let i = 0, _i = OrderedSet.size(indices); i < _i; i++) { + const eI = elements[OrderedSet.getAt(indices, i)]; + pos(eI, tempPos); + boundaryHelper.boundaryStep(tempPos, r(eI)); + } + } + boundaryHelper.finishBoundaryStep(); + for (const e of loci.elements) { + const { indices } = e; + const pos = e.unit.conformation.position, r = e.unit.conformation.r; + const { elements } = e.unit; + for (let i = 0, _i = OrderedSet.size(indices); i < _i; i++) { + const eI = elements[OrderedSet.getAt(indices, i)]; + pos(eI, tempPos); + boundaryHelper.extendStep(tempPos, r(eI)); + } + } + + return { box: boundaryHelper.getBox(), sphere: boundaryHelper.getSphere() }; + } } } diff --git a/src/mol-plugin/behavior/dynamic/volume-streaming/behavior.ts b/src/mol-plugin/behavior/dynamic/volume-streaming/behavior.ts index d2ce4aa51..846b9d299 100644 --- a/src/mol-plugin/behavior/dynamic/volume-streaming/behavior.ts +++ b/src/mol-plugin/behavior/dynamic/volume-streaming/behavior.ts @@ -19,7 +19,6 @@ import { Box3D } from 'mol-math/geometry'; import { urlCombine } from 'mol-util/url'; import { volumeFromDensityServerData } from 'mol-model-formats/volume/density-server'; import { StructureElement } from 'mol-model/structure'; -import { Loci } from 'mol-model/loci'; import { CreateVolumeStreamingBehavior } from './transformers'; export class VolumeStreaming extends PluginStateObject.CreateBehavior<VolumeStreaming.Behavior>({ name: 'Volume Streaming' }) { } @@ -150,18 +149,15 @@ export namespace VolumeStreaming { this.subscribeObservable(this.plugin.events.canvas3d.click, ({ current }) => { if (this.params.view.name !== 'selection-box') return; + // TODO: support link loci as well? + // Perhaps structure loci too? if (!StructureElement.isLoci(current.loci)) return; // TODO: check if it's the related structure - const loci = StructureElement.Loci.extendToWholeResidues(current.loci); const eR = this.params.view.params.radius; - - const sphere = Loci.getBoundingSphere(loci)!; - const r = Vec3.create(sphere.radius + eR, sphere.radius + eR, sphere.radius + eR); - const box = Box3D.create(Vec3.sub(Vec3.zero(), sphere.center, r), Vec3.add(Vec3.zero(), sphere.center, r)); - + const box = StructureElement.Loci.getBoundary(loci).box; const update = this.plugin.state.dataState.build().to(ref) .update(CreateVolumeStreamingBehavior, old => ({ ...old, @@ -188,10 +184,13 @@ export namespace VolumeStreaming { case 'box': box = Box3D.create(params.view.params.bottomLeft, params.view.params.topRight); break; - case 'selection-box': - box = Box3D.create(params.view.params.bottomLeft, params.view.params.topRight); + case 'selection-box': { + box = Box3D.create(Vec3.clone(params.view.params.bottomLeft), Vec3.clone(params.view.params.topRight)); + const r = params.view.params.radius; emptyData = Box3D.volume(box) < 0.0001; + Box3D.expand(box, box, Vec3.create(r, r, r)); break; + } case 'cell': box = this.info.kind === 'x-ray' ? this.info.structure.boundary.box -- GitLab