Search in sources :

Example 1 with DCPolyomino

use of org.eclipse.elk.alg.disco.structures.DCPolyomino in project elk by eclipse.

the class DisCoPolyominoCompactor method createPolyominoes.

/**
 * Creates {@link DCPolyomino polyominoes} from all {@link DCComponent DCComponents} of the {@link DCGraph} to
 * compact. Initializes an underlying grid structure to represent the polyomino based layout. Prerequisite:
 * {@link #computeCellSize(DCGraph)} must have been called before this method.
 */
private void createPolyominoes() {
    DCPolyomino poly;
    Set<DCComponent> comps = cmpGraph.getComponents();
    for (DCComponent comp : comps) {
        poly = new DCPolyomino(comp, gridCellSizeX, gridCellSizeY);
        polys.add(poly);
    }
}
Also used : DCPolyomino(org.eclipse.elk.alg.disco.structures.DCPolyomino) DCComponent(org.eclipse.elk.alg.disco.graph.DCComponent)

Example 2 with DCPolyomino

use of org.eclipse.elk.alg.disco.structures.DCPolyomino in project elk by eclipse.

the class DisCoPolyominoCompactor method applyToDCGraph.

/**
 * Sets an offset to the {@link DCComponent DCComponents} of the given graph indicating a vector, which yields its
 * new absolute position after packing, if added to its original coordinates. Prerequisite:
 * {@link #packPolyominoes()} must have been called before this method.
 */
private void applyToDCGraph() {
    // Crop base grid to the bounding box of all filled/marked cells.
    Quadruple<Integer, Integer, Integer, Integer> gridCrop = grid.getFilledBounds();
    // Compute width and height of the minimum bounding box of the new layout and set the the dimensions of the
    // graph accordingly. The coordinates are thereby translated from the discrete integer coordinates of the low
    // resolution polyominoes back to the real coordinates of the DCGraph.
    ElkPadding padding = cmpGraph.getProperty(DisCoOptions.PADDING);
    double paddingHori = padding.getHorizontal();
    double paddingVert = padding.getVertical();
    double parentWidth = (gridCrop.getThird() * gridCellSizeX) + paddingHori;
    double parentHeight = (gridCrop.getFourth() * gridCellSizeY) + paddingVert;
    cmpGraph.setDimensions(new KVector(parentWidth, parentHeight));
    for (DCPolyomino poly : polys) {
        // Compute the position of the upper left corner of each polyomino relative to the upper left corner of the
        // bounding box of all filled/marked cells of the base grid.
        int absoluteIntPositionX = poly.getX() - gridCrop.getFirst();
        int absoluteIntPositionY = poly.getY() - gridCrop.getSecond();
        // Compute new position of DCComponent
        KVector absolutePositionOnCanvas = new KVector(absoluteIntPositionX, absoluteIntPositionY).scale(poly.getCellSizeX(), poly.getCellSizeY()).add(poly.getOffset());
        // Get original coordinates of DCCopmponent (These will not be updated, as so far all classes implementing
        // the IGraphTransformer only use the offsets of the components to layout their underlying graph structures.
        KVector originalCoordinates = poly.getRepresentee().getMinCorner();
        // Set offset of new position relative to the original position of the component
        poly.getRepresentee().setOffset(absolutePositionOnCanvas.sub(originalCoordinates));
    }
}
Also used : DCPolyomino(org.eclipse.elk.alg.disco.structures.DCPolyomino) KVector(org.eclipse.elk.core.math.KVector) ElkPadding(org.eclipse.elk.core.math.ElkPadding)

Example 3 with DCPolyomino

use of org.eclipse.elk.alg.disco.structures.DCPolyomino in project elk by eclipse.

the class DisCoGraphRenderer method renderRecursively.

private void renderRecursively(final ElkNode parent, final GC graphics, final Rectangle area, final KVector offset, final int nodeAlpha, final int fillingAlpha, final int levelNumber) {
    /**
     * by mic: the associated graph of connected components
     */
    DCGraph componentGraph = (DCGraph) parent.getProperty(DisCoOptions.DEBUG_DISCO_GRAPH);
    int lowerLvl = state.getLowerLvl();
    int upperLvl = state.getUpperLvl();
    if ((paintElkGraph && levelNumber >= lowerLvl && levelNumber <= upperLvl) || (state.drawGhostParent() && levelNumber == 0)) {
        Set<ElkEdge> edgeSet = new HashSet<ElkEdge>();
        // render the nodes and ports
        if (lowerLvl > 0 && state.drawGhostParent() && levelNumber == 0) {
            renderNodeChildren(parent, graphics, area, offset, edgeSet, nodeAlpha, 0);
        } else {
            renderNodeChildren(parent, graphics, area, offset, edgeSet, nodeAlpha, fillingAlpha);
        }
        // render the edges
        for (ElkEdge edge : edgeSet) {
            renderEdge(parent, edge, graphics, area, offset, nodeAlpha);
        }
    }
    if (paintDCGraph && componentGraph != null && levelNumber >= lowerLvl && levelNumber <= upperLvl) {
        renderComponentGraph(parent, componentGraph, graphics, area, offset, nodeAlpha, fillingAlpha, levelNumber);
    }
    if (paintPolys && levelNumber >= lowerLvl && levelNumber <= upperLvl) {
        // by mic: low resolution polyominos generated from the graph of
        // connected components
        @SuppressWarnings("unchecked") List<DCPolyomino> polys = (List<DCPolyomino>) parent.getProperty(DisCoOptions.DEBUG_DISCO_POLYS);
        if (polys != null) {
            renderPolyominoes(parent, polys, graphics, area, offset, nodeAlpha, fillingAlpha, levelNumber);
        }
    }
    for (ElkNode child : parent.getChildren()) {
        // compute the offset required to make the children's
        KVector contentOffset = new KVector(child.getX() * getScale(), child.getY() * getScale());
        contentOffset.add(offset);
        renderRecursively(child, graphics, area, contentOffset, nodeAlpha, fillingAlpha, levelNumber + 1);
    }
}
Also used : ElkNode(org.eclipse.elk.graph.ElkNode) DCGraph(org.eclipse.elk.alg.disco.graph.DCGraph) DCPolyomino(org.eclipse.elk.alg.disco.structures.DCPolyomino) List(java.util.List) KVector(org.eclipse.elk.core.math.KVector) ElkEdge(org.eclipse.elk.graph.ElkEdge) HashSet(java.util.HashSet)

Example 4 with DCPolyomino

use of org.eclipse.elk.alg.disco.structures.DCPolyomino in project elk by eclipse.

the class DisCoGraphRenderer method renderPolyominoes.

// added by mic
/**
 * Paints all polyominoes that fall into the given dirty area.
 *
 * @param polys
 *            the polyominoes to paint
 * @param graphics
 *            the graphics context used to paint
 * @param area
 *            dirty area that needs painting
 * @param offset
 *            offset to be added to relative coordinates
 * @param nodeAlpha
 *            alpha value for nodes
 * @param fillingAlpha
 *            alpha value for node fillings
 */
private void renderPolyominoes(final ElkNode parent, final List<DCPolyomino> polys, final GC graphics, final Rectangle area, final KVector offset, final int nodeAlpha, final int fillingAlpha, final int levelNumber) {
    for (DCPolyomino poly : polys) {
        KVector polyCorner = poly.getMinCornerOnCanvas();
        double topLeftCornerX = polyCorner.x;
        double topLeftCornerY = polyCorner.y;
        double cellSizeX = poly.getCellSizeX();
        double cellSizeY = poly.getCellSizeY();
        double bottomRightCornerX = topLeftCornerX + cellSizeX * poly.getWidth();
        double bottomRightCornerY = topLeftCornerY + cellSizeY * poly.getHeight();
        for (int x = 0; x < poly.getWidth(); x++) {
            for (int y = 0; y < poly.getHeight(); y++) {
                Triple<Polyomino, Integer, Integer> polyoCell = new Triple<Polyomino, Integer, Integer>(poly, x, y);
                PaintRectangle rect = polyominoMap.get(polyoCell);
                if (rect == null) {
                    rect = new PaintRectangle(topLeftCornerX, topLeftCornerY, cellSizeX, cellSizeY, x, y, offset, getScale());
                    polyominoMap.put(polyoCell, rect);
                }
                if (!rect.painted && rect.intersects(area)) {
                    // paint this node
                    graphics.setAlpha(fillingAlpha);
                    if (configurator.getPolyominoFillColor() != null && poly.isBlocked(x, y)) {
                        graphics.setBackground(configurator.getPolyominoFillColor());
                        graphics.fillRectangle(rect.x, rect.y, rect.width, rect.height);
                        if (configurator.getNodeLabelFont() != null) {
                            graphics.setFont(configurator.getNodeLabelFont());
                        }
                        graphics.setAlpha(nodeAlpha);
                        graphics.setForeground(configurator.getPolyominoBorderTextColor());
                        if (state.drawLabels()) {
                            String levelprefix = levelNumber + "_";
                            if (state.removeLvl()) {
                                levelprefix = "";
                            }
                            graphics.drawString(levelprefix + Integer.toString(poly.getId()), rect.x, rect.y, true);
                        }
                    }
                    if (configurator.getPolyominoFillColor() != null && poly.isWeaklyBlocked(x, y)) {
                        // CHECKSTYLEOFF MagicNumber
                        graphics.setBackgroundPattern(patterns.getPolyominoExtensionPattern(state.makeSolid() ? 255 : fillingAlpha));
                        // CHECKSTYLEON MagicNumber
                        graphics.fillRectangle(rect.x, rect.y, rect.width, rect.height);
                        graphics.setAlpha(nodeAlpha);
                        graphics.setForeground(configurator.getPolyominoWeaklyBlockedBorderTextColor());
                        graphics.drawRectangle(rect.x, rect.y, rect.width, rect.height);
                        if (configurator.getNodeLabelFont() != null) {
                            graphics.setFont(configurator.getNodeLabelFont());
                        }
                        graphics.setAlpha(nodeAlpha);
                        if (state.drawLabels()) {
                            String levelprefix = levelNumber + "_";
                            if (state.removeLvl()) {
                                levelprefix = "";
                            }
                            graphics.drawString(levelprefix + Integer.toString(poly.getId()), rect.x, rect.y, true);
                        }
                    }
                    graphics.setAlpha(nodeAlpha);
                    if (configurator.getPolyominoBorderTextColor() != null && !poly.isWeaklyBlocked(x, y)) {
                        graphics.setForeground(configurator.getPolyominoBorderTextColor());
                        if (state.drawPolyLinesBlack()) {
                            graphics.setForeground(configurator.getBlack());
                        }
                        graphics.drawRectangle(rect.x, rect.y, rect.width, rect.height);
                    }
                    rect.painted = true;
                }
            }
        }
        if (state.markTheCenter()) {
            int x = poly.getCenterX();
            int y = poly.getCenterY();
            PaintRectangle centerRect = polyominoCenterMap.get(poly);
            if (centerRect == null) {
                centerRect = new PaintRectangle(topLeftCornerX, topLeftCornerY, cellSizeX, cellSizeY, x, y, offset, getScale());
                polyominoCenterMap.put(poly, centerRect);
            }
            if (configurator.getPolyominoFillColor() != null) {
                // CHECKSTYLEOFF MagicNumber
                graphics.setBackgroundPattern(patterns.getPolyominoCenterPattern(state.makeSolid() ? 255 : fillingAlpha));
                // CHECKSTYLEON MagicNumber
                graphics.fillRectangle(centerRect.x, centerRect.y, centerRect.width, centerRect.height);
                graphics.setAlpha(nodeAlpha);
            }
        }
        for (UniqueTriple<Direction, Integer, Integer> ext : poly.getPolyominoExtensions()) {
            PaintRectangle rect = polyominoExtensionMap.get(ext);
            if (rect == null) {
                Direction dir = ext.getFirst();
                int extStart = ext.getSecond();
                int extEnd = ext.getThird();
                switch(dir) {
                    case NORTH:
                        rect = new PaintRectangle(topLeftCornerX + extStart * cellSizeX, 0, (extEnd - extStart + 1) * cellSizeX, topLeftCornerY, offset, getScale());
                        break;
                    case SOUTH:
                        rect = new PaintRectangle(topLeftCornerX + extStart * cellSizeX, bottomRightCornerY, (extEnd - extStart + 1) * cellSizeX, parent.getHeight() - bottomRightCornerY, offset, getScale());
                        break;
                    case WEST:
                        rect = new PaintRectangle(0, topLeftCornerY + extStart * cellSizeY, topLeftCornerX, (extEnd - extStart + 1) * cellSizeY, offset, getScale());
                        break;
                    default:
                        // EAST
                        rect = new PaintRectangle(bottomRightCornerX, topLeftCornerY + extStart * cellSizeY, parent.getWidth() - bottomRightCornerX, (extEnd - extStart + 1) * cellSizeY, offset, getScale());
                        break;
                }
                // Maybe not unique in extreme cases where extensions
                // are very close to each other, but it doesn't matter
                // for the drawing
                polyominoExtensionMap.put(ext, rect);
            }
            graphics.setAlpha(fillingAlpha);
            // CHECKSTYLEOFF MagicNumber
            graphics.setBackgroundPattern(patterns.getPolyominoExtensionPattern(state.makeSolid() ? 255 : fillingAlpha));
            // CHECKSTYLEON MagicNumber
            graphics.fillRectangle(rect.x, rect.y, rect.width, rect.height);
            graphics.setAlpha(nodeAlpha);
            graphics.setForeground(configurator.getPolyominoWeaklyBlockedBorderTextColor());
            graphics.drawRectangle(rect.x, rect.y, rect.width, rect.height);
            if (configurator.getNodeLabelFont() != null) {
                graphics.setFont(configurator.getNodeLabelFont());
            }
            graphics.setAlpha(nodeAlpha);
            if (state.drawLabels()) {
                String levelprefix = levelNumber + "_";
                if (state.removeLvl()) {
                    levelprefix = "";
                }
                graphics.drawString(levelprefix + Integer.toString(poly.getId()), rect.x, rect.y, true);
            }
        }
    }
}
Also used : Triple(org.eclipse.elk.core.util.Triple) UniqueTriple(org.eclipse.elk.alg.common.utils.UniqueTriple) DCPolyomino(org.eclipse.elk.alg.disco.structures.DCPolyomino) KVector(org.eclipse.elk.core.math.KVector) Direction(org.eclipse.elk.alg.common.polyomino.structures.Direction) DCDirection(org.eclipse.elk.alg.disco.graph.DCDirection) DCPolyomino(org.eclipse.elk.alg.disco.structures.DCPolyomino) Polyomino(org.eclipse.elk.alg.common.polyomino.structures.Polyomino)

Example 5 with DCPolyomino

use of org.eclipse.elk.alg.disco.structures.DCPolyomino in project elk by eclipse.

the class DisCoPolyominoCompactor method packPolyominoes.

/**
 * Places {@link DCPolyomino polyominoes} close together, in order to achieve a minimum area for the final drawing,
 * based on the heuristic algorithm PackPolyominoes from the paper. Prerequisite: {@link #createPolyominoes()} must
 * have been called before this method.
 */
private void packPolyominoes() {
    // Id is for debugging purposes only (s. DisCoDebugView).
    int id = 0;
    for (DCPolyomino poly : polys) {
        poly.setId(id);
        id++;
    }
    // Use the more generic polyomino compactor which isn't restricted to components
    Polyominoes<DCPolyomino> polyHolder = new Polyominoes<DCPolyomino>(polys, aspectRatio, fill);
    new PolyominoCompactor().packPolyominoes(polyHolder);
    polys = polyHolder.getPolyominoes();
    grid = polyHolder.getGrid();
}
Also used : Polyominoes(org.eclipse.elk.alg.common.polyomino.structures.Polyominoes) DCPolyomino(org.eclipse.elk.alg.disco.structures.DCPolyomino) PolyominoCompactor(org.eclipse.elk.alg.common.polyomino.PolyominoCompactor)

Aggregations

DCPolyomino (org.eclipse.elk.alg.disco.structures.DCPolyomino)5 KVector (org.eclipse.elk.core.math.KVector)3 HashSet (java.util.HashSet)1 List (java.util.List)1 PolyominoCompactor (org.eclipse.elk.alg.common.polyomino.PolyominoCompactor)1 Direction (org.eclipse.elk.alg.common.polyomino.structures.Direction)1 Polyomino (org.eclipse.elk.alg.common.polyomino.structures.Polyomino)1 Polyominoes (org.eclipse.elk.alg.common.polyomino.structures.Polyominoes)1 UniqueTriple (org.eclipse.elk.alg.common.utils.UniqueTriple)1 DCComponent (org.eclipse.elk.alg.disco.graph.DCComponent)1 DCDirection (org.eclipse.elk.alg.disco.graph.DCDirection)1 DCGraph (org.eclipse.elk.alg.disco.graph.DCGraph)1 ElkPadding (org.eclipse.elk.core.math.ElkPadding)1 Triple (org.eclipse.elk.core.util.Triple)1 ElkEdge (org.eclipse.elk.graph.ElkEdge)1 ElkNode (org.eclipse.elk.graph.ElkNode)1