From 58a208e96edcddb07af89796859416dc6fc59f14 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Hannu=20Niemist=C3=B6?= Date: Thu, 19 Apr 2018 09:09:34 +0300 Subject: [PATCH] Some SCL functions to control graphical debugger Possibility to set statement filter and add resources with a function. refs #7869 Change-Id: Ifb5cc1fb09d3120ea73302d0b1195bc00ec2949e --- .../scl/Simantics/GraphicalDebugger.scl | 11 +- .../debug/graphical/DebuggerCanvas.java | 94 ++++++--- .../debug/graphical/DebuggerSelection.java | 14 -- .../debug/graphical/GraphicalDebugger.java | 4 +- .../debug/graphical/layout/BarnesHut.java | 139 ------------- .../debug/graphical/layout/BarnesHut2.java | 189 ------------------ 6 files changed, 83 insertions(+), 368 deletions(-) delete mode 100644 bundles/org.simantics.debug.graphical/src/org/simantics/debug/graphical/DebuggerSelection.java delete mode 100644 bundles/org.simantics.debug.graphical/src/org/simantics/debug/graphical/layout/BarnesHut.java delete mode 100644 bundles/org.simantics.debug.graphical/src/org/simantics/debug/graphical/layout/BarnesHut2.java diff --git a/bundles/org.simantics.debug.graphical/scl/Simantics/GraphicalDebugger.scl b/bundles/org.simantics.debug.graphical/scl/Simantics/GraphicalDebugger.scl index 490b481d4..7a23274c4 100644 --- a/bundles/org.simantics.debug.graphical/scl/Simantics/GraphicalDebugger.scl +++ b/bundles/org.simantics.debug.graphical/scl/Simantics/GraphicalDebugger.scl @@ -1,2 +1,11 @@ +import "Simantics/DB" + +importJava "org.simantics.debug.graphical.DebuggerCanvas" where + data GraphDebugger + + setStatementFilter :: GraphDebugger -> (Statement -> Boolean) -> () + removeStatementFilter :: GraphDebugger -> () + addResource :: GraphDebugger -> Resource -> () + importJava "org.simantics.debug.graphical.GraphicalDebugger" where - newGraphDebugger :: () \ No newline at end of file + newGraphDebugger :: GraphDebugger \ No newline at end of file diff --git a/bundles/org.simantics.debug.graphical/src/org/simantics/debug/graphical/DebuggerCanvas.java b/bundles/org.simantics.debug.graphical/src/org/simantics/debug/graphical/DebuggerCanvas.java index 00a539990..107125f46 100644 --- a/bundles/org.simantics.debug.graphical/src/org/simantics/debug/graphical/DebuggerCanvas.java +++ b/bundles/org.simantics.debug.graphical/src/org/simantics/debug/graphical/DebuggerCanvas.java @@ -1,9 +1,5 @@ package org.simantics.debug.graphical; -import gnu.trove.list.array.TDoubleArrayList; -import gnu.trove.map.hash.THashMap; -import gnu.trove.map.hash.TObjectIntHashMap; - import java.awt.Color; import java.awt.GradientPaint; import java.awt.Graphics; @@ -53,11 +49,17 @@ import org.simantics.debug.graphical.model.LabelContent; import org.simantics.debug.graphical.model.Node; import org.simantics.debug.graphical.model.NodeData; import org.simantics.layer0.Layer0; +import org.simantics.scl.runtime.SCLContext; +import org.simantics.scl.runtime.function.Function; import org.simantics.ui.dnd.LocalObjectTransfer; import org.simantics.ui.dnd.LocalObjectTransferable; import org.simantics.ui.selection.AnyResource; import org.simantics.ui.selection.WorkbenchSelectionElement; +import gnu.trove.list.array.TDoubleArrayList; +import gnu.trove.map.hash.THashMap; +import gnu.trove.map.hash.TObjectIntHashMap; + public class DebuggerCanvas extends JPanel { private static final long serialVersionUID = -718678297301786379L; @@ -74,10 +76,19 @@ public class DebuggerCanvas extends JPanel { double canvasZoom = 1.0; boolean extensionMode = false; Random random = new Random(); - + public Function statementFilter; + LabelingPreferences labelingPreferences = new LabelingPreferences(); + public void setStatementFilter(Function statementFilter) { + this.statementFilter = statementFilter; + } + + public void removeStatementFilter() { + this.statementFilter = null; + } + @Override public void paint(Graphics _g) { Graphics2D g = (Graphics2D)_g; @@ -284,6 +295,29 @@ public class DebuggerCanvas extends JPanel { nodes.add(a); return a; } + + public void addResource(Resource resource) { + double x, y; + if(nodes.isEmpty()) { + x = 0.0; + y = 0.0; + } + else { + double xMin=Double.POSITIVE_INFINITY, yMin=Double.POSITIVE_INFINITY; + double xMax=Double.NEGATIVE_INFINITY, yMax=Double.NEGATIVE_INFINITY; + for(Node node : nodes) { + xMin = Math.min(node.getMinX(), xMin); + yMin = Math.min(node.getMinY(), yMin); + xMax = Math.max(node.getMaxX(), xMax); + yMax = Math.max(node.getMaxY(), yMax); + } + x = xMin + (xMax - xMin) * random.nextDouble(); + y = yMin + (yMax - yMin) * random.nextDouble(); + } + + addResource(x, y, resource); + repaint(); + } private void scheduleUpdate() { Simantics.getSession().asyncRequest(new ReadRequest() { @@ -462,29 +496,41 @@ public class DebuggerCanvas extends JPanel { Simantics.getSession().syncRequest(new ReadRequest() { @Override public void run(ReadGraph graph) throws DatabaseException { - THashMap oldExtensionNodeMap = DebuggerCanvas.this.extensionNodeMap; - THashMap extensionNodeMap = new THashMap(); - for(Node node : nodes) { - for(Statement stat : node.getData().getStatements()) { - Resource object = stat.getObject(); - Node node2 = extensionNodeMap.get(object); - if(node2 == null) { - node2 = oldExtensionNodeMap.get(object); + SCLContext sclContext = SCLContext.getCurrent(); + Object oldGraph = sclContext.put("graph", graph); + try { + THashMap oldExtensionNodeMap = DebuggerCanvas.this.extensionNodeMap; + THashMap extensionNodeMap = new THashMap(); + for(Node node : nodes) { + for(Statement stat : node.getData().getStatements()) { + Resource object = stat.getObject(); + Node node2 = extensionNodeMap.get(object); if(node2 == null) { - node2 = new Node(new NodeData(object)); - double angle = random.nextDouble() * Math.PI * 2.0; - double dx = Math.cos(angle); - double dy = Math.sin(angle); - double len = 150.0; - node2.setPos(node.getX() + dx*len, node.getY() + dy*len); + if(statementFilter != null && Boolean.FALSE.equals(statementFilter.apply(stat))) + continue; + node2 = oldExtensionNodeMap.get(object); + if(node2 == null) { + node2 = new Node(new NodeData(object)); + double angle = random.nextDouble() * Math.PI * 2.0; + double dx = Math.cos(angle); + double dy = Math.sin(angle); + double len = 150.0; + node2.setPos(node.getX() + dx*len, node.getY() + dy*len); + } + node2.getData().updateData(graph, labelingPreferences); + node2.setContent(new LabelContent(node2.getData().getLabels())); + extensionNodeMap.put(object, node2); + extensionNodes.add(node2); } - node2.getData().updateData(graph, labelingPreferences); - node2.setContent(new LabelContent(node2.getData().getLabels())); - extensionNodeMap.put(object, node2); - extensionNodes.add(node2); + extensionEdges.add(createEdge(graph, stat, node, node2)); } - extensionEdges.add(createEdge(graph, stat, node, node2)); } + } catch (Throwable t) { + if (t instanceof DatabaseException) + throw (DatabaseException) t; + throw new DatabaseException(t); + } finally { + sclContext.put("graph", oldGraph); } DebuggerCanvas.this.extensionNodeMap = extensionNodeMap; layoutExtension(); diff --git a/bundles/org.simantics.debug.graphical/src/org/simantics/debug/graphical/DebuggerSelection.java b/bundles/org.simantics.debug.graphical/src/org/simantics/debug/graphical/DebuggerSelection.java deleted file mode 100644 index 6be6ee64c..000000000 --- a/bundles/org.simantics.debug.graphical/src/org/simantics/debug/graphical/DebuggerSelection.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.simantics.debug.graphical; - -import javax.swing.JList; - -public class DebuggerSelection extends JList { - - private static final long serialVersionUID = 2502385778204965742L; - - public DebuggerSelection() { - super(new String[] {"a", "b", "c"}); - } - - -} diff --git a/bundles/org.simantics.debug.graphical/src/org/simantics/debug/graphical/GraphicalDebugger.java b/bundles/org.simantics.debug.graphical/src/org/simantics/debug/graphical/GraphicalDebugger.java index 7db2772b5..9091a27f9 100644 --- a/bundles/org.simantics.debug.graphical/src/org/simantics/debug/graphical/GraphicalDebugger.java +++ b/bundles/org.simantics.debug.graphical/src/org/simantics/debug/graphical/GraphicalDebugger.java @@ -11,7 +11,7 @@ import javax.swing.JFrame; public class GraphicalDebugger { - public static void newGraphDebugger() { + public static DebuggerCanvas newGraphDebugger() { final JFrame frame = new JFrame(); frame.setTitle("Graph debugger"); Toolkit tk = Toolkit.getDefaultToolkit(); @@ -52,6 +52,8 @@ public class GraphicalDebugger { }); frame.setVisible(true); + + return canvas; } } diff --git a/bundles/org.simantics.debug.graphical/src/org/simantics/debug/graphical/layout/BarnesHut.java b/bundles/org.simantics.debug.graphical/src/org/simantics/debug/graphical/layout/BarnesHut.java deleted file mode 100644 index ef54c25f7..000000000 --- a/bundles/org.simantics.debug.graphical/src/org/simantics/debug/graphical/layout/BarnesHut.java +++ /dev/null @@ -1,139 +0,0 @@ -package org.simantics.debug.graphical.layout; - -public class BarnesHut { - - static class Bounds { - final double minX; - final double minY; - final double maxX; - final double maxY; - - public Bounds(double minX, double minY, double maxX, double maxY) { - this.minX = minX; - this.minY = minY; - this.maxX = maxX; - this.maxY = maxY; - } - } - - private static Bounds computeOctreeBounds(double[] posX, double[] posY) { - double minX = posX[0]; - double minY = posY[0]; - double maxX = posX[0]; - double maxY = posY[0]; - - for(int i=1;i maxX) - maxX = x; - if(y < minY) - minY = y; - else if(y > maxY) - maxY = y; - } - - double diff = (maxX - minX) - (maxY - minY); - diff *= 0.5; - if(diff > 0.0) { - minY -= diff; - maxY += diff; - } - else { - minX += diff; - maxX -= diff; - } - return new Bounds(minX, minY, maxX, maxY); - } - - private static class VecRef { - double x; - double y; - } - - /*private static void force(VecRef f, double x1, double y1, double x2, double y2) { - double dx = x2 - x1; - double dy = y2 - y1; - double l2 = dx*dx + dy*dy; - double s = Q / l2; - f.x -= s * dx; - f.y -= s * dy; - } - - private static void forceNear(VecRef f, double x1, double y1, OctreeNode node, double[] posX, double[] posY) { - if(node instanceof OctreeLeaf) { - for(int id : ((OctreeLeaf)node).ids) { - force(f, x1, y1, posX[id], posY[id]); - } - } - else { - OctreeInnerNode inner = (OctreeInnerNode)node; - forceNear(f, x1, y1, inner.n00, posX, posY); - forceNear(f, x1, y1, inner.n10, posX, posY); - forceNear(f, x1, y1, inner.n01, posX, posY); - forceNear(f, x1, y1, inner.n11, posX, posY); - } - } - - private static void forceFar(VecRef f, double x1, double y1, OctreeNode node) { - double dx = node.massCenterX - x1; - double dy = node.massCenterY - y1; - double l2 = dx*dx + dy*dy; - double s = Q * node.mass / l2; - f.x -= s * dx; - f.y -= s * dy; - } - - private static void computeForce(OctreeNode octree, - ArrayList farNodes, - ArrayList nearNodes, - double[] posX, double[] posY, - double[] forceX, double[] forceY) { - VecRef f = new VecRef(); - if(octree instanceof OctreeLeaf) { - int[] ids = ((OctreeLeaf)octree).ids; - for(int i=0;i(), new ArrayList(), posX, posY, forceX, forceY); - }*/ - -} diff --git a/bundles/org.simantics.debug.graphical/src/org/simantics/debug/graphical/layout/BarnesHut2.java b/bundles/org.simantics.debug.graphical/src/org/simantics/debug/graphical/layout/BarnesHut2.java deleted file mode 100644 index 537655f5e..000000000 --- a/bundles/org.simantics.debug.graphical/src/org/simantics/debug/graphical/layout/BarnesHut2.java +++ /dev/null @@ -1,189 +0,0 @@ -package org.simantics.debug.graphical.layout; - -import java.util.ArrayList; -import java.util.Iterator; - -public class BarnesHut2 { - - static final double OPTIMAL_DISTANCE = 150.0; - static final double C = 0.1; - static final double K = C / OPTIMAL_DISTANCE; - static final double G = K; - static final double Q = C * OPTIMAL_DISTANCE * OPTIMAL_DISTANCE; - - public static final int OCTREE_LEAF_SIZE = 25; - - public static void applyDirectedForce(Particle a, Particle b) { - double dx = a.x - b.x; - double dy = a.y - b.y; - double l2 = dx*dx + dy*dy; - double s = Q / l2; - a.fx += s * dx; - a.fy += s * dy; - } - - public static void applyDirectedForce(Particle a, OctreeNode b) { - double dx = a.x - b.massCenterX; - double dy = a.y - b.massCenterY; - double l2 = dx*dx + dy*dy; - double s = Q * b.mass / l2; - a.fx += s * dx; - a.fy += s * dy; - } - - private static abstract class OctreeNode { - double mass; - double massCenterX; - double massCenterY; - } - - private static class OctreeInnerNode extends OctreeNode { - final OctreeNode n00; - final OctreeNode n10; - final OctreeNode n01; - final OctreeNode n11; - - public OctreeInnerNode(OctreeNode n00, OctreeNode n10, OctreeNode n01, OctreeNode n11) { - this.n00 = n00; - this.n10 = n10; - this.n01 = n01; - this.n11 = n11; - - double mass00 = n00.mass; - double mass10 = n10.mass; - double mass01 = n01.mass; - double mass11 = n11.mass; - double totalMass = mass00 + mass10 + mass01 + mass11; - - this.mass = totalMass; - this.massCenterX = - (n00.massCenterX*mass00 + n10.massCenterX*mass10 + - n01.massCenterX*mass01 + n11.massCenterX*mass11) - / totalMass; - this.massCenterY = - (n00.massCenterY*mass00 + n10.massCenterY*mass10 + - n01.massCenterY*mass01 + n11.massCenterY*mass11) - / totalMass; - } - } - - private static class OctreeLeaf extends OctreeNode { - final Particle[] ps; - - public OctreeLeaf(Particle[] ps) { - this.ps = ps; - - double massCenterX = 0.0; - double massCenterY = 0.0; - for(Particle p : ps) { - massCenterX += p.x; - massCenterY += p.y; - } - - this.mass = ps.length; - this.massCenterX = massCenterX / ps.length; - this.massCenterY = massCenterY / ps.length; - } - } - - private static OctreeNode constructOctree(double minX, double minY, double maxX, double maxY, - ArrayList ps) { - if(ps.size() < OCTREE_LEAF_SIZE) - return new OctreeLeaf(ps.toArray(new Particle[ps.size()])); - - double midX = 0.5 * (minX + maxX); - double midY = 0.5 * (minY + maxY); - - ArrayList ps00 = new ArrayList(); - ArrayList ps10 = new ArrayList(); - ArrayList ps01 = new ArrayList(); - ArrayList ps11 = new ArrayList(); - - for(Particle p : ps) { - double x = p.x; - double y = p.y; - if(x < midX) { - if(y < midY) - ps00.add(p); - else - ps01.add(p); - } - else { - if(y < midY) - ps10.add(p); - else - ps11.add(p); - } - } - - return new OctreeInnerNode( - constructOctree(minX, minY, midX, midY, ps00), - constructOctree(midX, minY, maxX, midY, ps10), - constructOctree(minX, midY, midX, maxY, ps01), - constructOctree(midX, midY, maxX, maxY, ps11) - ); - } - - static class Bounds { - final double minX; - final double minY; - final double maxX; - final double maxY; - - public Bounds(double minX, double minY, double maxX, double maxY) { - this.minX = minX; - this.minY = minY; - this.maxX = maxX; - this.maxY = maxY; - } - } - - private static Bounds computeOctreeBounds(ArrayList ps) { - Iterator it = ps.iterator(); - - Particle pFirst = it.next(); - - double minX = pFirst.x; - double minY = pFirst.y; - double maxX = pFirst.x; - double maxY = pFirst.y; - - while(it.hasNext()) { - Particle p = it.next(); - double x = p.x; - double y = p.y; - if(x < minX) - minX = x; - else if(x > maxX) - maxX = x; - if(y < minY) - minY = y; - else if(y > maxY) - maxY = y; - } - - double diff = (maxX - minX) - (maxY - minY); - diff *= 0.5; - if(diff > 0.0) { - minY -= diff; - maxY += diff; - } - else { - minX += diff; - maxX -= diff; - } - return new Bounds(minX, minY, maxX, maxY); - } - - private static void computeForce(OctreeNode octree, - ArrayList nearNodes, ArrayList farNodes) { - // TODO Auto-generated method stub - - } - - public static void computeRepulsiveForces(ArrayList ps) { - Bounds bounds = computeOctreeBounds(ps); - OctreeNode octree = constructOctree(bounds.minX, bounds.minY, bounds.maxX, bounds.maxY, ps); - computeForce(octree, new ArrayList(), new ArrayList()); - } -} -- 2.43.2