]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/spatial/RTreeNode.java
Performance and resource consumption optimization for G2D picking
[simantics/platform.git] / bundles / org.simantics.scenegraph / src / org / simantics / scenegraph / g2d / nodes / spatial / RTreeNode.java
index d9b34dee60455bdf819e03d078cf89a4d1c429d4..52403edd02ea251522270f43ec9904614cda8c0b 100644 (file)
@@ -11,9 +11,6 @@
  *******************************************************************************/
 package org.simantics.scenegraph.g2d.nodes.spatial;
 
-import gnu.trove.TIntObjectHashMap;
-import gnu.trove.TIntProcedure;
-
 import java.awt.Graphics2D;
 import java.awt.RenderingHints;
 import java.awt.Shape;
@@ -22,6 +19,7 @@ import java.awt.geom.Rectangle2D;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Properties;
 import java.util.Set;
 
@@ -37,6 +35,9 @@ import org.simantics.scenegraph.utils.NodeUtil;
 import com.infomatiq.jsi.Rectangle;
 import com.infomatiq.jsi.rtree.RTree;
 
+import gnu.trove.TIntObjectHashMap;
+import gnu.trove.TIntProcedure;
+
 /**
  * A G2D scene graph node that spatially decomposes all of its immediate child
  * nodes into an R-Tree structure to optimize the painting of its direct child
@@ -311,6 +312,31 @@ public class RTreeNode extends G2DParentNode implements INodeEventHandlerProvide
         return new Rectangle((float) rect.getMinX(), (float) rect.getMinY(), (float) rect.getMaxX(), (float) rect.getMaxY());
     }
 
+    public List<IG2DNode> intersectingNodes(Rectangle2D rect, List<IG2DNode> result) {
+        final Tree tree = getSpatialDecomposition();
+        if (rect == null || tree.bounds == null || containedBy(tree.bounds, rect)) {
+            IG2DNode[] nodes = getSortedNodes();
+            for (IG2DNode node : nodes) {
+                if (node.validate()) {
+                    result.add(node);
+                }
+            }
+        } else {
+            tree.rtree.intersects(toRectangle(rect), value -> {
+                //System.out.println("exec: " + value);
+                IG2DNode node = tree.toNodes.get(value);
+                //System.out.println("  node: " + node);
+                if (node == null || !node.validate())
+                    return true;
+
+                result.add(node);
+                return true;
+            });
+        }
+        Collections.sort(result, G2DParentNode.G2DNODE_Z_COMPARATOR);
+        return result;
+    }
+
     /**
      * Determine whether this rectangle is contained by the passed rectangle
      *