]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.diagram.connection/tests/org/simantics/diagram/connection/tests/ConnectionRoutingTests.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.diagram.connection / tests / org / simantics / diagram / connection / tests / ConnectionRoutingTests.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2011 Association for Decentralized Information Management in
3  * Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.diagram.connection.tests;
13
14 import gnu.trove.map.hash.THashMap;
15 import gnu.trove.set.hash.THashSet;
16
17 import java.awt.Color;
18 import java.awt.Graphics2D;
19 import java.awt.RenderingHints;
20 import java.awt.image.BufferedImage;
21 import java.io.ByteArrayInputStream;
22 import java.io.ByteArrayOutputStream;
23 import java.io.IOException;
24 import java.io.ObjectInputStream;
25 import java.io.ObjectOutputStream;
26 import java.util.Arrays;
27
28 import org.junit.Assert;
29 import org.junit.Test;
30 import org.simantics.diagram.connection.RouteGraph;
31 import org.simantics.diagram.connection.RouteLine;
32 import org.simantics.diagram.connection.RouteLink;
33 import org.simantics.diagram.connection.RoutePoint;
34 import org.simantics.diagram.connection.RouteTerminal;
35 import org.simantics.diagram.connection.delta.RouteGraphDelta;
36 import org.simantics.diagram.connection.rendering.ExampleConnectionStyle;
37 import org.simantics.diagram.connection.rendering.IRouteGraphRenderer;
38 import org.simantics.diagram.connection.rendering.StyledRouteGraphRenderer;
39 import org.simantics.diagram.connection.rendering.arrows.ArrowExampleLineEndStyle;
40 import org.simantics.diagram.connection.rendering.arrows.ILineEndStyle;
41 import org.simantics.diagram.connection.rendering.arrows.PlainExampleLineEndStyle;
42 import org.simantics.diagram.connection.rendering.arrows.PlainLineEndStyle;
43
44 public class ConnectionRoutingTests {
45
46     public static final double TOLERANCE = 1e-4;
47     
48     public RouteTerminal addTerminal(RouteGraph rg, double x, double y, int ad) {
49         return rg.addTerminal(x, y, x-1, y-1, x+1, y+1, ad);
50     }
51        
52     public RouteTerminal addTerminal(RouteGraph rg, double x, double y, int ad, ILineEndStyle style) {
53         return rg.addTerminal(x, y, x-1, y-1, x+1, y+1, ad, style);
54     }
55     
56     private double[] routeSimpleConnection(double x, double y, int ad1, int ad2) {
57         RouteGraph rg = new RouteGraph();
58         RouteTerminal a = addTerminal(rg, 0, 0, ad1);
59         RouteTerminal b = addTerminal(rg, x, y, ad2);
60         rg.link(a, b);
61         return rg.getLineLengths(a);
62     }
63     
64     public void testRoute(double x, double y, int ad, double[] expected) {
65         Assert.assertArrayEquals(expected, routeSimpleConnection(x, y, 1, ad), TOLERANCE);
66     }
67     
68     @Test
69     public void testRoutingConsistency() {
70         for(double x = -2.5;x <= 2.5;x += 1.0) {
71             for(double y = -2.5;y <= 2.5;y += 1.0) {
72                 if(Math.abs(x) > 2.0 || Math.abs(y) > 2.0) {
73                     for(int dir = 0;dir < 4;++dir)
74                         if(dir != 2 || x != -2.5 || Math.abs(y) > 1.5) // cannot be consistent
75                             testRoutingConsistency(x, y, dir);
76                 }
77             }   
78         }
79     }
80     
81     private static final boolean DEBUG_ROUTING_CONSISTENCY = false;
82     private void testRoutingConsistency(double origX, double origY, int origDir) {
83         double[] expected = routeSimpleConnection(origX, origY, 1, 1<<origDir);
84         
85         if(DEBUG_ROUTING_CONSISTENCY)
86             System.out.println("(" + origX + "," + origY + ") dir" + origDir + ": " + 
87                     Arrays.toString(expected));
88         
89         for(int rotation=0;rotation<4;++rotation)
90             for(int mirror=0;mirror<2;++mirror) {
91                 double x = origX;
92                 double y = mirror==1 ? -origY : origY;
93                 int dir = origDir;
94                 if(mirror == 1) {
95                     if(dir == 1)
96                         dir = 3;
97                     else if(dir == 3)
98                         dir = 1;
99                 }
100                 for(int i=0;i<rotation;++i) {
101                     double temp = x;
102                     x = -y;
103                     y = temp;
104                 }
105                 
106                 double[] actual = routeSimpleConnection(x, y, 1<<rotation, 1<<((dir+rotation)%4));
107                 if(DEBUG_ROUTING_CONSISTENCY)
108                     System.out.println(mirror + " " + rotation + " -- " + 
109                             Arrays.toString(actual));
110                 Assert.assertArrayEquals(expected, actual, TOLERANCE);
111             }
112     }
113
114     @Test
115     public void testSimpleConnection1() {
116         
117         final double X = -0.5;
118         final double Y = -2.5;
119         testRoute(X, Y, 1, new double[] {1, 2.5, 1.5});
120         testRoute(X, Y, 2, new double[] {1, 1.25, 1.5, 1.25});
121         testRoute(X, Y, 4, new double[] {1, 1.25, 2.5, 1.25, 1});
122         testRoute(X, Y, 8, new double[] {1, 3.5, 1.5, 1});
123         
124     }
125     
126     @Test
127     public void testSimpleConnection2() {
128         
129         final double X = 0.5;
130         final double Y = -4;
131         testRoute(X, Y, 1, new double[] {1.5, 4, 1});
132         testRoute(X, Y, 2, new double[] {1, 2, 0.5, 2});
133         testRoute(X, Y, 4, new double[] {1, 2, 1.5, 2, 1});
134         testRoute(X, Y, 8, new double[] {1.5, 5, 1, 1});
135         
136     }
137     
138     @Test
139     public void testSimpleConnection3() {
140         
141         final double X = -3;
142         final double Y = 0;
143         testRoute(X, Y, 1, new double[] {1, 1, 2.5, 1, 1.5});
144         testRoute(X, Y, 2, new double[] {1, 1, 4, 1});
145         testRoute(X, Y, 4, new double[] {1, 1, 5, 1, 1});
146         testRoute(X, Y, 8, new double[] {1, 1, 4, 1});
147         
148     }
149     
150     @Test
151     public void testSimpleConnection4() {
152         
153         final double X = 3;
154         final double Y = 0;
155         testRoute(X, Y, 1, new double[] {1.5, 1, 2.5, 1, 1});
156         testRoute(X, Y, 2, new double[] {1.5, 1, 1.5, 1});
157         testRoute(X, Y, 4, new double[] {3});
158         testRoute(X, Y, 8, new double[] {1.5, 1, 1.5, 1});
159         
160     }
161     
162     @Test
163     public void testSimpleConnection5() {
164         
165         final double X = -4;
166         final double Y = 0.5;
167         testRoute(X, Y, 1, new double[] {1, 1, 3, 0.5, 2});
168         testRoute(X, Y, 2, new double[] {1, 1.5, 5, 1});
169         // testRoute(X, Y, 4, ); // not consistent
170         testRoute(X, Y, 8, new double[] {1, 1, 5, 1.5});
171         
172     }
173     
174     @Test
175     public void testSimpleConnection6() {        
176         final double X = 4;
177         final double Y = 3;
178         testRoute(X, Y, 1, new double[] {5, 3, 1});
179         testRoute(X, Y, 2, new double[] {2, 4, 2, 1});
180         testRoute(X, Y, 4, new double[] {2, 3, 2});
181         testRoute(X, Y, 8, new double[] {4, 3});
182         
183     }
184     
185     @Test
186     public void testSimpleConnection7() {        
187         final double X = -4;
188         final double Y = 3;
189         testRoute(X, Y, 1, new double[] {1, 3, 5});
190         testRoute(X, Y, 2, new double[] {1, 4, 5, 1});
191         testRoute(X, Y, 4, new double[] {1, 1.5, 6, 1.5, 1});
192         testRoute(X, Y, 8, new double[] {1, 1.5, 5, 1.5});        
193     }
194     
195     static class Line {
196                 double x1, y1, x2, y2;
197                 
198                 public Line(double x1, double y1, double x2, double y2) {
199                         this.x1 = x1;
200                         this.y1 = y1;
201                         this.x2 = x2;
202                         this.y2 = y2;
203                 }
204
205                 public Line(RoutePoint a, RoutePoint b) {
206                         this.x1 = a.getX();
207                         this.y1 = a.getY();
208                         this.x2 = b.getX();
209                         this.y2 = b.getY();
210                 }
211
212                 public Line(RouteLine line) {
213                         this(line.getBegin(), line.getEnd());
214                 }
215                 
216                 @Override
217                 public int hashCode() {
218                         final int prime = 31;
219                         int result = 1;
220                         long temp;
221                         temp = Double.doubleToLongBits(x1);
222                         result = prime * result + (int) (temp ^ (temp >>> 32));
223                         temp = Double.doubleToLongBits(x2);
224                         result = prime * result + (int) (temp ^ (temp >>> 32));
225                         temp = Double.doubleToLongBits(y1);
226                         result = prime * result + (int) (temp ^ (temp >>> 32));
227                         temp = Double.doubleToLongBits(y2);
228                         result = prime * result + (int) (temp ^ (temp >>> 32));
229                         return result;
230                 }
231
232                 @Override
233                 public boolean equals(Object obj) {
234                         if (this == obj)
235                                 return true;
236                         if (obj == null)
237                                 return false;
238                         if (getClass() != obj.getClass())
239                                 return false;
240                         Line other = (Line) obj;
241                         if (Double.doubleToLongBits(x1) != Double
242                                         .doubleToLongBits(other.x1))
243                                 return false;
244                         if (Double.doubleToLongBits(x2) != Double
245                                         .doubleToLongBits(other.x2))
246                                 return false;
247                         if (Double.doubleToLongBits(y1) != Double
248                                         .doubleToLongBits(other.y1))
249                                 return false;
250                         if (Double.doubleToLongBits(y2) != Double
251                                         .doubleToLongBits(other.y2))
252                                 return false;
253                         return true;
254                 }
255         }
256     
257     public static THashSet<Line> lineDiff(RouteGraph rg1, RouteGraph rg2) {
258         THashSet<Line> lines = new THashSet<Line>();
259         
260         for(RouteLine line : rg1.getAllLines())
261                 lines.add(new Line(line));
262         for(RouteLine line : rg2.getAllLines())
263             lines.remove(new Line(line));
264                         
265         return lines;
266     }
267     
268     private void genericSplitTest(RouteGraph rg, RouteLine lineToSplit) {
269         THashMap<Object, Object> map = new THashMap<Object, Object>(); 
270         RouteGraph rgCopy = rg.copy(map);
271         RouteLine lineToSplitCopy = (RouteLine)map.get(lineToSplit);
272         
273         double x1 = lineToSplit.getBegin().getX();
274         double y1 = lineToSplit.getBegin().getY();
275         double x2 = lineToSplit.getEnd().getX();
276         double y2 = lineToSplit.getEnd().getY();
277         double mx = 0.5 * (x1 + x2);
278         double my = 0.5 * (y1 + y2);
279                         
280         rgCopy.split(lineToSplitCopy, lineToSplit.isHorizontal() ? mx : my);
281         THashSet<Line> diff1 = lineDiff(rg, rgCopy);
282         THashSet<Line> diff2 = lineDiff(rgCopy, rg);
283         
284         Assert.assertArrayEquals(new Object[] { new Line(lineToSplit) }, diff1.toArray());
285         Assert.assertEquals(diff2.size(), 3);           
286         Assert.assertTrue(diff2.contains(new Line(x1, y1, mx, my)));
287         Assert.assertTrue(diff2.contains(new Line(mx, my, mx, my)));
288         Assert.assertTrue(diff2.contains(new Line(mx, my, x2, y2)));
289         Assert.assertTrue(rgCopy.isTree());
290     }
291     
292     private void genericSplitTest(RouteGraph rg) {
293         Assert.assertTrue(rg.isTree());         
294         for(RouteLine line : rg.getAllLines())
295                 genericSplitTest(rg, line);
296     }
297     
298     @Test
299     public void testSplit1() {
300         RouteGraph rg = new RouteGraph();
301         rg.link(
302                         addTerminal(rg, -10, 0, 1),
303                         addTerminal(rg, 10, 0, 4));
304         genericSplitTest(rg);
305     } 
306     
307     @Test
308     public void testSplit2() {
309         RouteGraph rg = new RouteGraph();      
310         rg.link(
311                         addTerminal(rg, -20, -20, 1), 
312                         addTerminal(rg, 20, 20, 4));
313         genericSplitTest(rg);
314     }
315     
316     @Test
317     public void testSplit3() {
318         RouteGraph rg = new RouteGraph();      
319         rg.link(
320                         addTerminal(rg, -20, -20, 1), 
321                         addTerminal(rg, 20, 20, 8));
322         genericSplitTest(rg);
323     }
324     
325     @Test
326     public void testSplit4() {
327         RouteGraph rg = new RouteGraph();   
328         rg.link(
329                         addTerminal(rg, -20, -20, 1), 
330                         rg.addLine(false, 0.0), 
331                         addTerminal(rg, 20, 20, 4));
332         genericSplitTest(rg);
333     }
334     
335     @Test
336     public void testSplit5() {
337         RouteGraph rg = new RouteGraph();
338         RouteLine v = rg.addLine(false, 0.0); 
339         rg.link(
340                 addTerminal(rg, -20, -20, 1), 
341                 v);
342         rg.link(
343                 addTerminal(rg, 20, 20, 4),
344                 v);
345         rg.link(
346                 addTerminal(rg, -20, 0, 1),
347                 v);
348         genericSplitTest(rg);
349     }  
350     
351     @Test
352     public void testMerge1() {
353         RouteGraph rg = new RouteGraph();
354         RouteTerminal a = addTerminal(rg, -20, -20, 1);
355         RouteLine l1 = rg.addLine(false, -10);
356         RouteLine l2 = rg.addLine(true, 0);
357         RouteLine l3 = rg.addLine(false, 10);
358         RouteTerminal b = addTerminal(rg, 20, 20, 4);        
359         rg.link(a, l1, l2, l3, b);
360         rg.merge(l2, 0.0);
361         Assert.assertArrayEquals(new double[] {20,40,20}, rg.getLineLengths(a), TOLERANCE);        
362     }
363     
364     @Test
365     public void testMerge2() {
366         RouteGraph rg = new RouteGraph();
367         RouteTerminal a = addTerminal(rg, -20, -20, 1);
368         RouteLine l = rg.addLine(false, -10);
369         RouteTerminal b = addTerminal(rg, 20, 20, 4);          
370         rg.link(a, l, b);
371         rg.merge(l, 0.0);
372         Assert.assertArrayEquals(new double[] {20,40,20}, rg.getLineLengths(a), TOLERANCE);        
373     }
374     
375     @Test
376     public void testMerge3() {
377         RouteGraph rg = new RouteGraph();
378         RouteTerminal a = addTerminal(rg, -20, -20, 1);
379         RouteTerminal b = addTerminal(rg, 20, 20, 4);        
380         rg.link(a, b);
381         rg.merge((RouteLine)rg.pick(0,0), 0.0);
382         Assert.assertArrayEquals(new double[] {20,40,20}, rg.getLineLengths(a), TOLERANCE);        
383     }
384     
385     @Test
386     public void testDeleteCorner1() {
387         RouteGraph rg = new RouteGraph();
388         RouteTerminal a = addTerminal(rg, -20, 0, 1);
389         RouteLine l1 = rg.addLine(false, -10);
390         RouteLine l2 = rg.addLine(true, 10);
391         RouteLine l3 = rg.addLine(false, 10);
392         RouteTerminal b = addTerminal(rg, 20, 0, 4);
393         rg.link(a, l1, l2, l3, b);
394         rg.deleteCorner((RouteLink)rg.pick(10, 10));
395         Assert.assertArrayEquals(new double[] {10,0,30}, rg.getLineLengths(a), TOLERANCE);
396     }
397     
398     @Test
399     public void testRendering1() {
400         RouteGraph rg = new RouteGraph();
401         RouteLine l = rg.addLine(false, 0);
402         rg.link(addTerminal(rg, -20, -20, 1, ArrowExampleLineEndStyle.INSTANCE), l);
403         rg.link(addTerminal(rg, 20, 20, 4, PlainExampleLineEndStyle.INSTANCE), l);
404         rg.link(addTerminal(rg, -40, 0, 2, PlainLineEndStyle.INSTANCE), l);
405         
406         BufferedImage image = new BufferedImage(200, 200, BufferedImage.TYPE_INT_ARGB);
407         Graphics2D g = image.createGraphics();
408         g.setColor(Color.BLACK);
409         g.setBackground(Color.WHITE);
410         g.clearRect(0, 0, 200, 200);
411         g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
412         g.translate(100, 100);
413         new StyledRouteGraphRenderer(new ExampleConnectionStyle()).render(g, rg);
414                 
415         //ImageViewer.run(image);
416     }
417     
418     @Test
419     public void testRendering2() {
420         RouteGraph rg = new RouteGraph();
421         rg.link(addTerminal(rg, -20, 0, 1), addTerminal(rg, 20, 1, 4));
422         
423         BufferedImage image = new BufferedImage(200, 200, BufferedImage.TYPE_INT_ARGB);
424         Graphics2D g = image.createGraphics();
425         g.setColor(Color.BLACK);
426         g.setBackground(Color.WHITE);
427         g.clearRect(0, 0, 200, 200);
428         g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
429         g.translate(100, 100);
430         new StyledRouteGraphRenderer(new ExampleConnectionStyle()).render(g, rg);
431                 
432         //ImageViewer.run(image);
433     }
434     
435     @Test
436     public void testRendering3() {
437         RouteGraph rg = new RouteGraph();
438         rg.link(addTerminal(rg, 0, -20, 2), addTerminal(rg, 1, 20, 8));
439         
440         BufferedImage image = new BufferedImage(200, 200, BufferedImage.TYPE_INT_ARGB);
441         Graphics2D g = image.createGraphics();
442         g.setColor(Color.BLACK);
443         g.setBackground(Color.WHITE);
444         g.clearRect(0, 0, 200, 200);
445         g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
446         g.translate(100, 100);
447         new StyledRouteGraphRenderer(new ExampleConnectionStyle()).render(g, rg);
448                 
449         //ImageViewer.run(image);
450     }
451     
452     @Test
453     public void testPickingLineHalves() {
454         RouteGraph rg = new RouteGraph();
455         RouteLine l = rg.addLine(false, 0);
456         RouteTerminal t1 = addTerminal(rg, -20, -20, 1);
457         /*RouteTerminal t2 = addTerminal(rg, 20, 20, 1);
458         RouteTerminal t3 = addTerminal(rg, -40, 0, 1);
459         */
460         rg.link(t1, l);
461         rg.link(addTerminal(rg, 20, 20, 1), l);
462         rg.link(addTerminal(rg, -40, 0, 1), l);
463  
464         Assert.assertEquals(t1, rg.pickLineHalf(-1, -20, 0).getLine().getTerminal());
465         Assert.assertEquals(null, rg.pickLineHalf(-18, -20, 0));
466         Assert.assertEquals(null, rg.pickLineHalf(0, -18, 0));
467     }
468     
469     @Test
470     public void testCopy() {
471         RouteGraph rg = new RouteGraph();
472         RouteLine l = rg.addLine(false, 0.0);
473         RouteTerminal a = addTerminal(rg, -20, -20, 1);
474         RouteTerminal b = addTerminal(rg, 20, 20, 4);        
475         rg.link(a, l, b);
476         
477         RouteGraph rgc = rg.copy();        
478         rgc.split((RouteLine)rgc.pick(-10, -20), -10.0);
479         
480         Assert.assertArrayEquals(new double[] {20,40,20}, rg.getLineLengths(a), TOLERANCE);        
481     }
482     
483     @Test
484     public void testConnecting1() {
485         RouteGraph rg = new RouteGraph();
486         RouteTerminal a = addTerminal(rg, -10, 0, 1);
487         RouteTerminal b = addTerminal(rg, 10, 0, 4);
488         rg.link(a, b);
489         rg.connectTerminal(addTerminal(rg, -10, 10, 1), 0.0, 0.0, 0.1);
490         Assert.assertTrue(rg.isTree());
491     }
492     
493     @Test
494     public void testConnecting2() {
495         RouteGraph rg = new RouteGraph();
496         RouteTerminal a = addTerminal(rg, -10, -10, 1);
497         RouteTerminal b = addTerminal(rg, 10, 10, 4);
498         rg.link(a, b);
499         rg.connectTerminal(addTerminal(rg, -10, 0, 1), 0.0, 0.0, 0.1);
500         Assert.assertTrue(rg.isTree());
501     }
502     
503     @Test
504     public void testDiff1() {
505         RouteGraph rg = new RouteGraph();
506         RouteTerminal a = addTerminal(rg, -10, -10, 1);
507         a.setData(1);
508         RouteLine l = rg.addLine(false, 0);
509         l.setData(2);
510         RouteTerminal b = addTerminal(rg, 10, 10, 4);
511         b.setData(3);
512         rg.link(a, l, b);
513         
514         RouteGraph rgc = rg.copy();
515         rgc.split(rgc.getLines().iterator().next(), 0);
516         
517         new RouteGraphDelta(rg, rgc).print();
518     }
519     
520     @Test
521     public void testSerialize1() throws IOException, ClassNotFoundException {
522         RouteGraph rg = new RouteGraph();
523         RouteTerminal a = addTerminal(rg, -10, -10, 1);
524         a.setData(1);
525         RouteLine l = rg.addLine(false, 0);
526         l.setData(2);
527         RouteTerminal b = addTerminal(rg, 10, 10, 4);
528         b.setData(3);
529         rg.link(a, l, b);
530
531         IRouteGraphRenderer renderer = new StyledRouteGraphRenderer(new ExampleConnectionStyle());
532
533         ByteArrayOutputStream bos = new ByteArrayOutputStream();
534         ObjectOutputStream oos = new ObjectOutputStream(bos);
535         oos.writeObject(rg);
536         oos.writeObject(renderer);
537
538         ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
539         ObjectInputStream ois = new ObjectInputStream(bis);
540         RouteGraph rgc = (RouteGraph) ois.readObject(); 
541         //IRouteGraphRenderer rendererc = (IRouteGraphRenderer) ois.readObject();
542
543         new RouteGraphDelta(rg, rgc).print();
544     }
545     
546 }