Browse Source

mol-model within query

David Sehnal 6 years ago
parent
commit
1a2d523ab0
1 changed files with 33 additions and 6 deletions
  1. 33 6
      src/mol-model/structure/query/queries/filters.ts

+ 33 - 6
src/mol-model/structure/query/queries/filters.ts

@@ -11,6 +11,7 @@ import { StructureQuery } from '../query';
 import { StructureSelection } from '../selection';
 import { structureAreIntersecting } from '../utils/structure';
 import { Vec3 } from 'mol-math/linear-algebra';
+import { checkStructureMaxRadiusDistance, checkStructureMinMaxDistance } from '../utils/structure-distance';
 
 export function pick(query: StructureQuery, pred: QueryPredicate): StructureQuery {
     return ctx => {
@@ -111,8 +112,6 @@ export interface WithinParams {
     invert?: boolean
 }
 
-function _zeroRadius(ctx: QueryContext) { return 0; }
-
 export function within(params: WithinParams): StructureQuery {
     return queryCtx => {
         const ctx: WithinContext = {
@@ -126,11 +125,11 @@ export function within(params: WithinParams): StructureQuery {
         }
 
         if (ctx.minRadius === 0 && typeof params.minRadius === 'undefined') {
+            return withinMaxRadiusLookup(ctx);
+        } else if (ctx.minRadius === 0) {
             return withinMaxRadius(ctx);
         } else {
-            // TODO
-            throw 'not implemented';
-            // return withinMinMaxRadius(ctx);
+            return withinMinMaxRadius(ctx);
         }
     }
 }
@@ -144,7 +143,7 @@ interface WithinContext {
     invert: boolean,
     elementRadius: QueryFn<number>
 }
-function withinMaxRadius({ queryCtx, selection, target, maxRadius, invert }: WithinContext) {
+function withinMaxRadiusLookup({ queryCtx, selection, target, maxRadius, invert }: WithinContext) {
     const targetLookup = StructureSelection.unionStructure(target).lookup3d;
     const ret = StructureSelection.LinearBuilder(queryCtx.inputStructure);
 
@@ -174,5 +173,33 @@ function withinMaxRadius({ queryCtx, selection, target, maxRadius, invert }: Wit
     return ret.getSelection();
 }
 
+function withinMaxRadius({ queryCtx, selection, target, maxRadius, invert, elementRadius }: WithinContext) {
+    const targetStructure = StructureSelection.unionStructure(target);
+    const ret = StructureSelection.LinearBuilder(queryCtx.inputStructure);
+
+    StructureSelection.forEach(selection, (s, sI) => {
+        let withinRadius = checkStructureMaxRadiusDistance(queryCtx, targetStructure, s, maxRadius, elementRadius);
+        if (invert) withinRadius = !withinRadius;
+        if (withinRadius) ret.add(s);
+        if (sI % 10 === 0) queryCtx.throwIfTimedOut();
+    });
+
+    return ret.getSelection();
+}
+
+function withinMinMaxRadius({ queryCtx, selection, target, minRadius, maxRadius, invert, elementRadius }: WithinContext) {
+    const targetStructure = StructureSelection.unionStructure(target);
+    const ret = StructureSelection.LinearBuilder(queryCtx.inputStructure);
+
+    StructureSelection.forEach(selection, (s, sI) => {
+        let withinRadius = checkStructureMinMaxDistance(queryCtx, targetStructure, s, minRadius, maxRadius, elementRadius);
+        if (invert) withinRadius = !withinRadius;
+        if (withinRadius) ret.add(s);
+        if (sI % 10 === 0) queryCtx.throwIfTimedOut();
+    });
+
+    return ret.getSelection();
+}
+
 
 // TODO: isConnectedTo