/* * This file is part of the OSMembrane project. * More informations under www.osmembrane.de * * The project is licensed under the GNU GENERAL PUBLIC LICENSE 3.0. * for more details about the license see http://www.osmembrane.de/license/ * * Source: $HeadURL$ ($Revision$) * Last changed: $Date$ */ package de.osmembrane.model.algorithms; import java.util.ArrayList; import java.util.List; import de.osmembrane.model.ModelProxy; import de.osmembrane.model.pipeline.AbstractConnector; import de.osmembrane.model.pipeline.AbstractFunction; import de.osmembrane.model.settings.SettingType; import de.osmembrane.resources.Constants; /** * The graph planarizer tries to optimize the given graph. * * @author jakob_jarosch */ public class GraphPlanarizer { private List<AbstractFunction> functions; private double pipelineRasterSize; private double X_OFFSET; private double Y_OFFSET; /** * Creates an new planarizer. * * @param functions * which should be planarized */ public GraphPlanarizer(List<AbstractFunction> functions) { this.functions = functions; } /** * Execute the planarization. */ public void planarize() { resetAllFunctions(); calculateGridSize(); List<AbstractFunction> primaryFunctions = getPrimaryFunctions(); /* * set the xOffsetfactor to -1.0 'cause orderFunction will add 1.0 in * the first step */ double xOffsetFactor = -1.0; double yOffsetFactor = 0.0; for (AbstractFunction function : primaryFunctions) { yOffsetFactor = orderFunctions(function, xOffsetFactor, yOffsetFactor); yOffsetFactor++; } } /** * Resets all functions to the (0.0, 0.0) coordinate. */ private void resetAllFunctions() { for (AbstractFunction function : functions) { function.getCoordinate().setLocation(0.0, 0.0); } } /** * Returns all functions with no connections at their inConnectors. * * @return all functions with no connections at their inConnectors */ private List<AbstractFunction> getPrimaryFunctions() { List<AbstractFunction> primaryFunctions = new ArrayList<AbstractFunction>(); for (AbstractFunction function : functions) { boolean foundConnection = false; for (AbstractConnector connector : function.getInConnectors()) { if (connector.getConnections().length > 0) { /* found a inConnection, do not add as a primary one */ foundConnection = true; } } if (!foundConnection) { primaryFunctions.add(function); } } return primaryFunctions; } /** * Orders all functions connected to this function. * * @return returns the required space in height */ private double orderFunctions(AbstractFunction function, double xOffsetFactor, double yOffsetFactor) { /* move in this recursision step one position right */ xOffsetFactor++; /* Set the coordinate of the functions */ function.getUnrasteredCoordinate().setLocation( X_OFFSET * xOffsetFactor, Y_OFFSET * yOffsetFactor); boolean moreThanOneConnection = false; for (AbstractConnector connector : function.getOutConnectors()) { for (AbstractConnector connector2 : connector.getConnections()) { /* move all functions step by step one position lower */ if (moreThanOneConnection) { yOffsetFactor++; } else { moreThanOneConnection = true; } yOffsetFactor = orderFunctions(connector2.getParent(), xOffsetFactor, yOffsetFactor); } } return yOffsetFactor; } /** * Calculates the grid size. */ private void calculateGridSize() { pipelineRasterSize = Math.max(1.0, new Double((Integer) ModelProxy.getInstance().getSettings() .getValue(SettingType.PIPELINE_RASTER_SIZE))); X_OFFSET = 0.0; Y_OFFSET = 0.0; while (X_OFFSET < Constants.PIPELINE_FUNCTION_MINIMAL_X_DISTANCE) { X_OFFSET += pipelineRasterSize; } while (Y_OFFSET < Constants.PIPELINE_FUNCTION_MINIMAL_Y_DISTANCE) { Y_OFFSET += pipelineRasterSize; } } }