/******************************************************************************* * Copyright (c) 2007, 2011 Association for Decentralized Information Management in * Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.diagram.connection.tests; import gnu.trove.map.hash.THashMap; import gnu.trove.set.hash.THashSet; import java.awt.Color; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.Arrays; import org.junit.Assert; import org.junit.Test; import org.simantics.diagram.connection.RouteGraph; import org.simantics.diagram.connection.RouteLine; import org.simantics.diagram.connection.RouteLink; import org.simantics.diagram.connection.RoutePoint; import org.simantics.diagram.connection.RouteTerminal; import org.simantics.diagram.connection.delta.RouteGraphDelta; import org.simantics.diagram.connection.rendering.ExampleConnectionStyle; import org.simantics.diagram.connection.rendering.IRouteGraphRenderer; import org.simantics.diagram.connection.rendering.StyledRouteGraphRenderer; import org.simantics.diagram.connection.rendering.arrows.ArrowExampleLineEndStyle; import org.simantics.diagram.connection.rendering.arrows.ILineEndStyle; import org.simantics.diagram.connection.rendering.arrows.PlainExampleLineEndStyle; import org.simantics.diagram.connection.rendering.arrows.PlainLineEndStyle; public class ConnectionRoutingTests { public static final double TOLERANCE = 1e-4; public RouteTerminal addTerminal(RouteGraph rg, double x, double y, int ad) { return rg.addTerminal(x, y, x-1, y-1, x+1, y+1, ad); } public RouteTerminal addTerminal(RouteGraph rg, double x, double y, int ad, ILineEndStyle style) { return rg.addTerminal(x, y, x-1, y-1, x+1, y+1, ad, style); } private double[] routeSimpleConnection(double x, double y, int ad1, int ad2) { RouteGraph rg = new RouteGraph(); RouteTerminal a = addTerminal(rg, 0, 0, ad1); RouteTerminal b = addTerminal(rg, x, y, ad2); rg.link(a, b); return rg.getLineLengths(a); } public void testRoute(double x, double y, int ad, double[] expected) { Assert.assertArrayEquals(expected, routeSimpleConnection(x, y, 1, ad), TOLERANCE); } @Test public void testRoutingConsistency() { for(double x = -2.5;x <= 2.5;x += 1.0) { for(double y = -2.5;y <= 2.5;y += 1.0) { if(Math.abs(x) > 2.0 || Math.abs(y) > 2.0) { for(int dir = 0;dir < 4;++dir) if(dir != 2 || x != -2.5 || Math.abs(y) > 1.5) // cannot be consistent testRoutingConsistency(x, y, dir); } } } } private static final boolean DEBUG_ROUTING_CONSISTENCY = false; private void testRoutingConsistency(double origX, double origY, int origDir) { double[] expected = routeSimpleConnection(origX, origY, 1, 1<>> 32)); temp = Double.doubleToLongBits(x2); result = prime * result + (int) (temp ^ (temp >>> 32)); temp = Double.doubleToLongBits(y1); result = prime * result + (int) (temp ^ (temp >>> 32)); temp = Double.doubleToLongBits(y2); result = prime * result + (int) (temp ^ (temp >>> 32)); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Line other = (Line) obj; if (Double.doubleToLongBits(x1) != Double .doubleToLongBits(other.x1)) return false; if (Double.doubleToLongBits(x2) != Double .doubleToLongBits(other.x2)) return false; if (Double.doubleToLongBits(y1) != Double .doubleToLongBits(other.y1)) return false; if (Double.doubleToLongBits(y2) != Double .doubleToLongBits(other.y2)) return false; return true; } } public static THashSet lineDiff(RouteGraph rg1, RouteGraph rg2) { THashSet lines = new THashSet(); for(RouteLine line : rg1.getAllLines()) lines.add(new Line(line)); for(RouteLine line : rg2.getAllLines()) lines.remove(new Line(line)); return lines; } private void genericSplitTest(RouteGraph rg, RouteLine lineToSplit) { THashMap map = new THashMap(); RouteGraph rgCopy = rg.copy(map); RouteLine lineToSplitCopy = (RouteLine)map.get(lineToSplit); double x1 = lineToSplit.getBegin().getX(); double y1 = lineToSplit.getBegin().getY(); double x2 = lineToSplit.getEnd().getX(); double y2 = lineToSplit.getEnd().getY(); double mx = 0.5 * (x1 + x2); double my = 0.5 * (y1 + y2); rgCopy.split(lineToSplitCopy, lineToSplit.isHorizontal() ? mx : my); THashSet diff1 = lineDiff(rg, rgCopy); THashSet diff2 = lineDiff(rgCopy, rg); Assert.assertArrayEquals(new Object[] { new Line(lineToSplit) }, diff1.toArray()); Assert.assertEquals(diff2.size(), 3); Assert.assertTrue(diff2.contains(new Line(x1, y1, mx, my))); Assert.assertTrue(diff2.contains(new Line(mx, my, mx, my))); Assert.assertTrue(diff2.contains(new Line(mx, my, x2, y2))); Assert.assertTrue(rgCopy.isTree()); } private void genericSplitTest(RouteGraph rg) { Assert.assertTrue(rg.isTree()); for(RouteLine line : rg.getAllLines()) genericSplitTest(rg, line); } @Test public void testSplit1() { RouteGraph rg = new RouteGraph(); rg.link( addTerminal(rg, -10, 0, 1), addTerminal(rg, 10, 0, 4)); genericSplitTest(rg); } @Test public void testSplit2() { RouteGraph rg = new RouteGraph(); rg.link( addTerminal(rg, -20, -20, 1), addTerminal(rg, 20, 20, 4)); genericSplitTest(rg); } @Test public void testSplit3() { RouteGraph rg = new RouteGraph(); rg.link( addTerminal(rg, -20, -20, 1), addTerminal(rg, 20, 20, 8)); genericSplitTest(rg); } @Test public void testSplit4() { RouteGraph rg = new RouteGraph(); rg.link( addTerminal(rg, -20, -20, 1), rg.addLine(false, 0.0), addTerminal(rg, 20, 20, 4)); genericSplitTest(rg); } @Test public void testSplit5() { RouteGraph rg = new RouteGraph(); RouteLine v = rg.addLine(false, 0.0); rg.link( addTerminal(rg, -20, -20, 1), v); rg.link( addTerminal(rg, 20, 20, 4), v); rg.link( addTerminal(rg, -20, 0, 1), v); genericSplitTest(rg); } @Test public void testMerge1() { RouteGraph rg = new RouteGraph(); RouteTerminal a = addTerminal(rg, -20, -20, 1); RouteLine l1 = rg.addLine(false, -10); RouteLine l2 = rg.addLine(true, 0); RouteLine l3 = rg.addLine(false, 10); RouteTerminal b = addTerminal(rg, 20, 20, 4); rg.link(a, l1, l2, l3, b); rg.merge(l2, 0.0); Assert.assertArrayEquals(new double[] {20,40,20}, rg.getLineLengths(a), TOLERANCE); } @Test public void testMerge2() { RouteGraph rg = new RouteGraph(); RouteTerminal a = addTerminal(rg, -20, -20, 1); RouteLine l = rg.addLine(false, -10); RouteTerminal b = addTerminal(rg, 20, 20, 4); rg.link(a, l, b); rg.merge(l, 0.0); Assert.assertArrayEquals(new double[] {20,40,20}, rg.getLineLengths(a), TOLERANCE); } @Test public void testMerge3() { RouteGraph rg = new RouteGraph(); RouteTerminal a = addTerminal(rg, -20, -20, 1); RouteTerminal b = addTerminal(rg, 20, 20, 4); rg.link(a, b); rg.merge((RouteLine)rg.pick(0,0), 0.0); Assert.assertArrayEquals(new double[] {20,40,20}, rg.getLineLengths(a), TOLERANCE); } @Test public void testDeleteCorner1() { RouteGraph rg = new RouteGraph(); RouteTerminal a = addTerminal(rg, -20, 0, 1); RouteLine l1 = rg.addLine(false, -10); RouteLine l2 = rg.addLine(true, 10); RouteLine l3 = rg.addLine(false, 10); RouteTerminal b = addTerminal(rg, 20, 0, 4); rg.link(a, l1, l2, l3, b); rg.deleteCorner((RouteLink)rg.pick(10, 10)); Assert.assertArrayEquals(new double[] {10,0,30}, rg.getLineLengths(a), TOLERANCE); } @Test public void testRendering1() { RouteGraph rg = new RouteGraph(); RouteLine l = rg.addLine(false, 0); rg.link(addTerminal(rg, -20, -20, 1, ArrowExampleLineEndStyle.INSTANCE), l); rg.link(addTerminal(rg, 20, 20, 4, PlainExampleLineEndStyle.INSTANCE), l); rg.link(addTerminal(rg, -40, 0, 2, PlainLineEndStyle.INSTANCE), l); BufferedImage image = new BufferedImage(200, 200, BufferedImage.TYPE_INT_ARGB); Graphics2D g = image.createGraphics(); g.setColor(Color.BLACK); g.setBackground(Color.WHITE); g.clearRect(0, 0, 200, 200); g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g.translate(100, 100); new StyledRouteGraphRenderer(new ExampleConnectionStyle()).render(g, rg); //ImageViewer.run(image); } @Test public void testRendering2() { RouteGraph rg = new RouteGraph(); rg.link(addTerminal(rg, -20, 0, 1), addTerminal(rg, 20, 1, 4)); BufferedImage image = new BufferedImage(200, 200, BufferedImage.TYPE_INT_ARGB); Graphics2D g = image.createGraphics(); g.setColor(Color.BLACK); g.setBackground(Color.WHITE); g.clearRect(0, 0, 200, 200); g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g.translate(100, 100); new StyledRouteGraphRenderer(new ExampleConnectionStyle()).render(g, rg); //ImageViewer.run(image); } @Test public void testRendering3() { RouteGraph rg = new RouteGraph(); rg.link(addTerminal(rg, 0, -20, 2), addTerminal(rg, 1, 20, 8)); BufferedImage image = new BufferedImage(200, 200, BufferedImage.TYPE_INT_ARGB); Graphics2D g = image.createGraphics(); g.setColor(Color.BLACK); g.setBackground(Color.WHITE); g.clearRect(0, 0, 200, 200); g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g.translate(100, 100); new StyledRouteGraphRenderer(new ExampleConnectionStyle()).render(g, rg); //ImageViewer.run(image); } @Test public void testPickingLineHalves() { RouteGraph rg = new RouteGraph(); RouteLine l = rg.addLine(false, 0); RouteTerminal t1 = addTerminal(rg, -20, -20, 1); /*RouteTerminal t2 = addTerminal(rg, 20, 20, 1); RouteTerminal t3 = addTerminal(rg, -40, 0, 1); */ rg.link(t1, l); rg.link(addTerminal(rg, 20, 20, 1), l); rg.link(addTerminal(rg, -40, 0, 1), l); Assert.assertEquals(t1, rg.pickLineHalf(-1, -20, 0).getLine().getTerminal()); Assert.assertEquals(null, rg.pickLineHalf(-18, -20, 0)); Assert.assertEquals(null, rg.pickLineHalf(0, -18, 0)); } @Test public void testCopy() { RouteGraph rg = new RouteGraph(); RouteLine l = rg.addLine(false, 0.0); RouteTerminal a = addTerminal(rg, -20, -20, 1); RouteTerminal b = addTerminal(rg, 20, 20, 4); rg.link(a, l, b); RouteGraph rgc = rg.copy(); rgc.split((RouteLine)rgc.pick(-10, -20), -10.0); Assert.assertArrayEquals(new double[] {20,40,20}, rg.getLineLengths(a), TOLERANCE); } @Test public void testConnecting1() { RouteGraph rg = new RouteGraph(); RouteTerminal a = addTerminal(rg, -10, 0, 1); RouteTerminal b = addTerminal(rg, 10, 0, 4); rg.link(a, b); rg.connectTerminal(addTerminal(rg, -10, 10, 1), 0.0, 0.0, 0.1); Assert.assertTrue(rg.isTree()); } @Test public void testConnecting2() { RouteGraph rg = new RouteGraph(); RouteTerminal a = addTerminal(rg, -10, -10, 1); RouteTerminal b = addTerminal(rg, 10, 10, 4); rg.link(a, b); rg.connectTerminal(addTerminal(rg, -10, 0, 1), 0.0, 0.0, 0.1); Assert.assertTrue(rg.isTree()); } @Test public void testDiff1() { RouteGraph rg = new RouteGraph(); RouteTerminal a = addTerminal(rg, -10, -10, 1); a.setData(1); RouteLine l = rg.addLine(false, 0); l.setData(2); RouteTerminal b = addTerminal(rg, 10, 10, 4); b.setData(3); rg.link(a, l, b); RouteGraph rgc = rg.copy(); rgc.split(rgc.getLines().iterator().next(), 0); new RouteGraphDelta(rg, rgc).print(); } @Test public void testSerialize1() throws IOException, ClassNotFoundException { RouteGraph rg = new RouteGraph(); RouteTerminal a = addTerminal(rg, -10, -10, 1); a.setData(1); RouteLine l = rg.addLine(false, 0); l.setData(2); RouteTerminal b = addTerminal(rg, 10, 10, 4); b.setData(3); rg.link(a, l, b); IRouteGraphRenderer renderer = new StyledRouteGraphRenderer(new ExampleConnectionStyle()); ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(rg); oos.writeObject(renderer); ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); RouteGraph rgc = (RouteGraph) ois.readObject(); //IRouteGraphRenderer rendererc = (IRouteGraphRenderer) ois.readObject(); new RouteGraphDelta(rg, rgc).print(); } }