]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.g2d/src/org/simantics/g2d/routing/algorithm1/Router.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.g2d / src / org / simantics / g2d / routing / algorithm1 / Router.java
index 6622bf9ad44a4972ddb8d4ee2f75cdd010084cae..50fb1c937dc71692af8615ec21ae98fcb5d7aea5 100644 (file)
-/*******************************************************************************\r
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
- * in Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.g2d.routing.algorithm1;\r
-\r
-import gnu.trove.map.hash.TCustomHashMap;\r
-import gnu.trove.strategy.IdentityHashingStrategy;\r
-\r
-import java.awt.geom.AffineTransform;\r
-import java.awt.geom.Path2D;\r
-import java.awt.geom.PathIterator;\r
-import java.awt.geom.Rectangle2D;\r
-import java.util.Arrays;\r
-import java.util.Collection;\r
-import java.util.HashSet;\r
-\r
-import org.simantics.g2d.routing.IGraphModel;\r
-import org.simantics.g2d.routing.IRouter;\r
-import org.simantics.g2d.routing.Terminal;\r
-import org.simantics.g2d.routing.spatial.IRectangleProcedure;\r
-import org.simantics.g2d.routing.spatial.RTree;\r
-\r
-public class Router implements IRouter {\r
-       \r
-       TCustomHashMap<Object, PenaltyRectangle> oldObstacles;\r
-       TCustomHashMap<Object, ConnectionInfo> oldConnections = new TCustomHashMap<Object, ConnectionInfo>(IdentityHashingStrategy.INSTANCE);\r
-       \r
-       static class ConnectionInfo extends Rectangle {\r
-\r
-               Rectangle bounds;\r
-               int hash;\r
-               \r
-               public ConnectionInfo(double x0, double y0, double x1, double y1, Rectangle bounds, int hash) {\r
-                       super(x0, y0, x1, y1);\r
-                       this.bounds = bounds;\r
-                       this.hash = hash;\r
-               }\r
-               \r
-       }\r
-       \r
-       @Override\r
-       public void update(IGraphModel model) {\r
-               double[] coords = new double[6];\r
-               \r
-               RTree rtree = new RTree();\r
-               RTree modifications = null;\r
-               if(oldObstacles == null) {\r
-                       oldObstacles = new TCustomHashMap<Object, PenaltyRectangle>(IdentityHashingStrategy.INSTANCE);\r
-                       for(Object obstacle : model.getObstacles()) {\r
-                               Rectangle2D rect2d = model.getObstacleShape(obstacle);\r
-                               PenaltyRectangle pRect = new PenaltyRectangle(\r
-                                       rect2d.getMinX(), rect2d.getMinY(), rect2d.getMaxX(), rect2d.getMaxY(),\r
-                                       Penalty.OBSTACLE_PENALTY, Penalty.OBSTACLE_PENALTY\r
-                                       ); \r
-                               rtree.add(pRect, pRect);\r
-                               oldObstacles.put(obstacle, pRect);\r
-                       }               \r
-               }\r
-               else {\r
-                       modifications = new RTree();\r
-                       TCustomHashMap<Object, PenaltyRectangle> newObstacles = new TCustomHashMap<Object, PenaltyRectangle>(IdentityHashingStrategy.INSTANCE); \r
-                       for(Object obstacle : model.getObstacles()) {\r
-                               Rectangle2D rect2d = model.getObstacleShape(obstacle);\r
-                               PenaltyRectangle oldRect = oldObstacles.remove(obstacle);\r
-                               if(oldRect != null && rect2d.getMinX() == oldRect.x0 && rect2d.getMaxX() == oldRect.x1 &&\r
-                                  rect2d.getMinY() == oldRect.y0 && rect2d.getMaxY() == oldRect.y1) {\r
-                                       newObstacles.put(obstacle, oldRect);\r
-                                       rtree.add(oldRect, oldRect);\r
-                               }\r
-                               else {\r
-                                       PenaltyRectangle pRect = new PenaltyRectangle(\r
-                                               rect2d.getMinX(), rect2d.getMinY(), rect2d.getMaxX(), rect2d.getMaxY(),\r
-                                               Penalty.OBSTACLE_PENALTY, Penalty.OBSTACLE_PENALTY\r
-                                               ); \r
-                                       rtree.add(pRect, pRect);\r
-                                       newObstacles.put(obstacle, pRect);\r
-                                       modifications.add(pRect, pRect);\r
-                                       if(oldRect != null)\r
-                                               modifications.add(oldRect, oldRect);\r
-                               }\r
-                       }\r
-                       oldObstacles = newObstacles;\r
-               }\r
-               \r
-               TCustomHashMap<Object, ConnectionInfo> newConnections = new TCustomHashMap<Object, ConnectionInfo>(IdentityHashingStrategy.INSTANCE);\r
-               Collection<Object> connections = model.getConnections();\r
-               if(modifications != null) {                     \r
-                       for(Object c : connections) {\r
-                               ConnectionInfo oldInfo = oldConnections.remove(c);\r
-                               if(oldInfo != null)\r
-                                       newConnections.put(c, oldInfo);\r
-                       }\r
-                       for(ConnectionInfo info : oldConnections.values())\r
-                               modifications.add(info.bounds, info);\r
-               }\r
-               int count = 0;\r
-               for(Object c : connections) {\r
-                       Terminal begin = model.getBeginTerminal(c);\r
-                       double[] routePoints = model.getRoutePoints(c);\r
-                       Terminal end = model.getEndTerminal(c);         \r
-                       \r
-                       int hash = (begin == null ? 0 : begin.hashCode()) + 31 * ((end == null ? 0 : end.hashCode()) + 31 * Arrays.hashCode(routePoints));\r
-                       \r
-                       if(modifications != null) {\r
-                               ConnectionInfo info = newConnections.get(c);\r
-                               if(info != null) {                              \r
-                                       if(hash==info.hash && !modifications.intersects(info)) {\r
-                                               newConnections.put(c, info);\r
-                                               continue;\r
-                                       }\r
-                                       modifications.add(info.bounds, info);\r
-                               }\r
-                       }\r
-                       \r
-                       ++ count;\r
-                       \r
-                       double x0 = Double.POSITIVE_INFINITY;\r
-                       double y0 = Double.POSITIVE_INFINITY;\r
-                       double x1 = Double.NEGATIVE_INFINITY;\r
-                       double y1 = Double.NEGATIVE_INFINITY;\r
-                       \r
-                       if(begin != null) {\r
-                               if(begin.x < x0) x0 = begin.x;\r
-                               else if(begin.x > x1) x1 = begin.x;\r
-                               if(begin.y < y0) y0 = begin.x;\r
-                               else if(begin.y > y1) y1 = begin.x;\r
-                       }\r
-                       \r
-                       if(end != null) {\r
-                               if(end.x < x0) x0 = end.x;\r
-                               else if(end.x > x1) x1 = end.x;\r
-                               if(end.y < y0) y0 = end.x;\r
-                               else if(end.y > y1) y1 = end.x;\r
-                       }\r
-                       \r
-                       for(int i=0;i<routePoints.length;i+=2) {\r
-                               double x = routePoints[i];\r
-                               if(x < x0) x0 = x;\r
-                               else if(x > x1) x1 = x;\r
-                               double y = routePoints[i+1];\r
-                               if(y < y0) y0 = x;\r
-                               else if(y > y1) y1 = x;\r
-                       }\r
-                       \r
-                       final HashSet<PenaltyRectangle> rectangles = new HashSet<PenaltyRectangle>();\r
-                       rtree.search(new Rectangle(x0, y0, x1, y1), new IRectangleProcedure() {\r
-\r
-                               @Override\r
-                               public void call(double x0, double y0, double x1, double y1, Object value) {\r
-                                       rectangles.add((PenaltyRectangle)value);\r
-                               }\r
-                               \r
-                       });\r
-                       \r
-                       while(true) {                           \r
-                               \r
-                               Path2D path = new StaticRouter(rectangles).route(begin, routePoints, end);\r
-                               if(path == null)\r
-                                       break;\r
-                               \r
-                               Rectangle2D rect = path.getBounds2D();\r
-                               boolean contained = true;\r
-                               if(rect.getMinX() < x0) {\r
-                                       x0 = rect.getMinX();\r
-                                       contained = false;\r
-                               }\r
-                               if(rect.getMaxX() > x1) {\r
-                                       x1 = rect.getMaxX();\r
-                                       contained = false;\r
-                               }\r
-                               if(rect.getMinY() < y0) {\r
-                                       y0 = rect.getMinY();\r
-                                       contained = false;\r
-                               }\r
-                               if(rect.getMaxY() > y1) {\r
-                                       y1 = rect.getMaxY();\r
-                                       contained = false;\r
-                               }\r
-                               \r
-                               final boolean[] ff = new boolean[] { true };\r
-                               if(!contained) {\r
-                                       rtree.search(new Rectangle(x0, y0, x1, y1), new IRectangleProcedure() {\r
-\r
-                                               @Override\r
-                                               public void call(double x0, double y0, double x1, double y1, Object value) {\r
-                                                       if(!rectangles.contains(value)) {\r
-                                                               rectangles.add((PenaltyRectangle)value);\r
-                                                               ff[0] = false;\r
-                                                       }\r
-                                               }\r
-                                               \r
-                                       });\r
-                               }\r
-                               \r
-                               if(ff[0]) {\r
-                                       model.setPath(c, path);\r
-                                       PathIterator it = path.getPathIterator(new AffineTransform());\r
-                                       double curX = 0.0, curY = 0.0, newX = 0.0, newY = 0.0;\r
-                                       while(!it.isDone()) {                                           \r
-                                               switch(it.currentSegment(coords)) {\r
-                                               case PathIterator.SEG_MOVETO:\r
-                                                       curX = coords[0];\r
-                                                       curY = coords[1];\r
-                                                       break;\r
-                                               case PathIterator.SEG_LINETO:\r
-                                                       newX = coords[0];\r
-                                                       newY = coords[1];\r
-                                                       \r
-                                                       PenaltyRectangle pRect;\r
-                                                       if(newX == curX) {\r
-                                                               pRect = new PenaltyRectangle(\r
-                                                                       curX-Penalty.CONNECTION_MARGINAL, Math.min(curY, newY), curX+Penalty.CONNECTION_MARGINAL, Math.max(curY, newY),\r
-                                                                       Penalty.CONNECTION_CROSS_PENALTY, Penalty.CONNECTION_SIDE_PENALTY\r
-                                                                       );                                                              \r
-                                                       }\r
-                                                       else {\r
-                                                               pRect = new PenaltyRectangle(\r
-                                                                       Math.min(curX, newX), curY-Penalty.CONNECTION_MARGINAL, Math.max(curX, newX), curY+Penalty.CONNECTION_MARGINAL, \r
-                                                                       Penalty.CONNECTION_SIDE_PENALTY, Penalty.CONNECTION_CROSS_PENALTY\r
-                                                                       );      \r
-                                                       }\r
-                                                       rtree.add(pRect, pRect);\r
-                                                       \r
-                                                       curX = newX;\r
-                                                       curY = newY;\r
-                                               }\r
-                                               it.next();\r
-                                       }\r
-                                       ConnectionInfo info = new ConnectionInfo(x0, y0, x1, y1, Rectangle.of(path.getBounds2D()), hash);\r
-                                       if(modifications != null)\r
-                                               modifications.add(info.bounds, info);\r
-                                       newConnections.put(c, info);                                    \r
-                                       break;\r
-                               }\r
-                       }\r
-                       \r
-               \r
-               }\r
-               \r
-               oldConnections = newConnections;\r
-\r
-               //System.out.println("updated " + count + "/" + connections.size() + " connections");\r
-       }       \r
-\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.g2d.routing.algorithm1;
+
+import gnu.trove.map.hash.TCustomHashMap;
+import gnu.trove.strategy.IdentityHashingStrategy;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Path2D;
+import java.awt.geom.PathIterator;
+import java.awt.geom.Rectangle2D;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+
+import org.simantics.g2d.routing.IGraphModel;
+import org.simantics.g2d.routing.IRouter;
+import org.simantics.g2d.routing.Terminal;
+import org.simantics.g2d.routing.spatial.IRectangleProcedure;
+import org.simantics.g2d.routing.spatial.RTree;
+
+public class Router implements IRouter {
+       
+       TCustomHashMap<Object, PenaltyRectangle> oldObstacles;
+       TCustomHashMap<Object, ConnectionInfo> oldConnections = new TCustomHashMap<Object, ConnectionInfo>(IdentityHashingStrategy.INSTANCE);
+       
+       static class ConnectionInfo extends Rectangle {
+
+               Rectangle bounds;
+               int hash;
+               
+               public ConnectionInfo(double x0, double y0, double x1, double y1, Rectangle bounds, int hash) {
+                       super(x0, y0, x1, y1);
+                       this.bounds = bounds;
+                       this.hash = hash;
+               }
+               
+       }
+       
+       @Override
+       public void update(IGraphModel model) {
+               double[] coords = new double[6];
+               
+               RTree rtree = new RTree();
+               RTree modifications = null;
+               if(oldObstacles == null) {
+                       oldObstacles = new TCustomHashMap<Object, PenaltyRectangle>(IdentityHashingStrategy.INSTANCE);
+                       for(Object obstacle : model.getObstacles()) {
+                               Rectangle2D rect2d = model.getObstacleShape(obstacle);
+                               PenaltyRectangle pRect = new PenaltyRectangle(
+                                       rect2d.getMinX(), rect2d.getMinY(), rect2d.getMaxX(), rect2d.getMaxY(),
+                                       Penalty.OBSTACLE_PENALTY, Penalty.OBSTACLE_PENALTY
+                                       ); 
+                               rtree.add(pRect, pRect);
+                               oldObstacles.put(obstacle, pRect);
+                       }               
+               }
+               else {
+                       modifications = new RTree();
+                       TCustomHashMap<Object, PenaltyRectangle> newObstacles = new TCustomHashMap<Object, PenaltyRectangle>(IdentityHashingStrategy.INSTANCE); 
+                       for(Object obstacle : model.getObstacles()) {
+                               Rectangle2D rect2d = model.getObstacleShape(obstacle);
+                               PenaltyRectangle oldRect = oldObstacles.remove(obstacle);
+                               if(oldRect != null && rect2d.getMinX() == oldRect.x0 && rect2d.getMaxX() == oldRect.x1 &&
+                                  rect2d.getMinY() == oldRect.y0 && rect2d.getMaxY() == oldRect.y1) {
+                                       newObstacles.put(obstacle, oldRect);
+                                       rtree.add(oldRect, oldRect);
+                               }
+                               else {
+                                       PenaltyRectangle pRect = new PenaltyRectangle(
+                                               rect2d.getMinX(), rect2d.getMinY(), rect2d.getMaxX(), rect2d.getMaxY(),
+                                               Penalty.OBSTACLE_PENALTY, Penalty.OBSTACLE_PENALTY
+                                               ); 
+                                       rtree.add(pRect, pRect);
+                                       newObstacles.put(obstacle, pRect);
+                                       modifications.add(pRect, pRect);
+                                       if(oldRect != null)
+                                               modifications.add(oldRect, oldRect);
+                               }
+                       }
+                       oldObstacles = newObstacles;
+               }
+               
+               TCustomHashMap<Object, ConnectionInfo> newConnections = new TCustomHashMap<Object, ConnectionInfo>(IdentityHashingStrategy.INSTANCE);
+               Collection<Object> connections = model.getConnections();
+               if(modifications != null) {                     
+                       for(Object c : connections) {
+                               ConnectionInfo oldInfo = oldConnections.remove(c);
+                               if(oldInfo != null)
+                                       newConnections.put(c, oldInfo);
+                       }
+                       for(ConnectionInfo info : oldConnections.values())
+                               modifications.add(info.bounds, info);
+               }
+               int count = 0;
+               for(Object c : connections) {
+                       Terminal begin = model.getBeginTerminal(c);
+                       double[] routePoints = model.getRoutePoints(c);
+                       Terminal end = model.getEndTerminal(c);         
+                       
+                       int hash = (begin == null ? 0 : begin.hashCode()) + 31 * ((end == null ? 0 : end.hashCode()) + 31 * Arrays.hashCode(routePoints));
+                       
+                       if(modifications != null) {
+                               ConnectionInfo info = newConnections.get(c);
+                               if(info != null) {                              
+                                       if(hash==info.hash && !modifications.intersects(info)) {
+                                               newConnections.put(c, info);
+                                               continue;
+                                       }
+                                       modifications.add(info.bounds, info);
+                               }
+                       }
+                       
+                       ++ count;
+                       
+                       double x0 = Double.POSITIVE_INFINITY;
+                       double y0 = Double.POSITIVE_INFINITY;
+                       double x1 = Double.NEGATIVE_INFINITY;
+                       double y1 = Double.NEGATIVE_INFINITY;
+                       
+                       if(begin != null) {
+                               if(begin.x < x0) x0 = begin.x;
+                               else if(begin.x > x1) x1 = begin.x;
+                               if(begin.y < y0) y0 = begin.x;
+                               else if(begin.y > y1) y1 = begin.x;
+                       }
+                       
+                       if(end != null) {
+                               if(end.x < x0) x0 = end.x;
+                               else if(end.x > x1) x1 = end.x;
+                               if(end.y < y0) y0 = end.x;
+                               else if(end.y > y1) y1 = end.x;
+                       }
+                       
+                       for(int i=0;i<routePoints.length;i+=2) {
+                               double x = routePoints[i];
+                               if(x < x0) x0 = x;
+                               else if(x > x1) x1 = x;
+                               double y = routePoints[i+1];
+                               if(y < y0) y0 = x;
+                               else if(y > y1) y1 = x;
+                       }
+                       
+                       final HashSet<PenaltyRectangle> rectangles = new HashSet<PenaltyRectangle>();
+                       rtree.search(new Rectangle(x0, y0, x1, y1), new IRectangleProcedure() {
+
+                               @Override
+                               public void call(double x0, double y0, double x1, double y1, Object value) {
+                                       rectangles.add((PenaltyRectangle)value);
+                               }
+                               
+                       });
+                       
+                       while(true) {                           
+                               
+                               Path2D path = new StaticRouter(rectangles).route(begin, routePoints, end);
+                               if(path == null)
+                                       break;
+                               
+                               Rectangle2D rect = path.getBounds2D();
+                               boolean contained = true;
+                               if(rect.getMinX() < x0) {
+                                       x0 = rect.getMinX();
+                                       contained = false;
+                               }
+                               if(rect.getMaxX() > x1) {
+                                       x1 = rect.getMaxX();
+                                       contained = false;
+                               }
+                               if(rect.getMinY() < y0) {
+                                       y0 = rect.getMinY();
+                                       contained = false;
+                               }
+                               if(rect.getMaxY() > y1) {
+                                       y1 = rect.getMaxY();
+                                       contained = false;
+                               }
+                               
+                               final boolean[] ff = new boolean[] { true };
+                               if(!contained) {
+                                       rtree.search(new Rectangle(x0, y0, x1, y1), new IRectangleProcedure() {
+
+                                               @Override
+                                               public void call(double x0, double y0, double x1, double y1, Object value) {
+                                                       if(!rectangles.contains(value)) {
+                                                               rectangles.add((PenaltyRectangle)value);
+                                                               ff[0] = false;
+                                                       }
+                                               }
+                                               
+                                       });
+                               }
+                               
+                               if(ff[0]) {
+                                       model.setPath(c, path);
+                                       PathIterator it = path.getPathIterator(new AffineTransform());
+                                       double curX = 0.0, curY = 0.0, newX = 0.0, newY = 0.0;
+                                       while(!it.isDone()) {                                           
+                                               switch(it.currentSegment(coords)) {
+                                               case PathIterator.SEG_MOVETO:
+                                                       curX = coords[0];
+                                                       curY = coords[1];
+                                                       break;
+                                               case PathIterator.SEG_LINETO:
+                                                       newX = coords[0];
+                                                       newY = coords[1];
+                                                       
+                                                       PenaltyRectangle pRect;
+                                                       if(newX == curX) {
+                                                               pRect = new PenaltyRectangle(
+                                                                       curX-Penalty.CONNECTION_MARGINAL, Math.min(curY, newY), curX+Penalty.CONNECTION_MARGINAL, Math.max(curY, newY),
+                                                                       Penalty.CONNECTION_CROSS_PENALTY, Penalty.CONNECTION_SIDE_PENALTY
+                                                                       );                                                              
+                                                       }
+                                                       else {
+                                                               pRect = new PenaltyRectangle(
+                                                                       Math.min(curX, newX), curY-Penalty.CONNECTION_MARGINAL, Math.max(curX, newX), curY+Penalty.CONNECTION_MARGINAL, 
+                                                                       Penalty.CONNECTION_SIDE_PENALTY, Penalty.CONNECTION_CROSS_PENALTY
+                                                                       );      
+                                                       }
+                                                       rtree.add(pRect, pRect);
+                                                       
+                                                       curX = newX;
+                                                       curY = newY;
+                                               }
+                                               it.next();
+                                       }
+                                       ConnectionInfo info = new ConnectionInfo(x0, y0, x1, y1, Rectangle.of(path.getBounds2D()), hash);
+                                       if(modifications != null)
+                                               modifications.add(info.bounds, info);
+                                       newConnections.put(c, info);                                    
+                                       break;
+                               }
+                       }
+                       
+               
+               }
+               
+               oldConnections = newConnections;
+
+               //System.out.println("updated " + count + "/" + connections.size() + " connections");
+       }       
+
+}