Statistics
| Branch: | Revision:

root / src / layout / basicspringembedderlayout.h @ 5c632378

History | View | Annotate | Download (4.67 KB)

1 01873262 Georg Kunz
//==========================================================================
2
//  BASICSPRINGEMBEDDERLAYOUT.H - part of
3
//                     OMNeT++/OMNEST
4
//            Discrete System Simulation in C++
5
//
6
//  Author: Andras Varga
7
//
8
//==========================================================================
9
10
/*--------------------------------------------------------------*
11
  Copyright (C) 2002-2008 Andras Varga
12
  Copyright (C) 2006-2008 OpenSim Ltd.
13

14
  This file is distributed WITHOUT ANY WARRANTY. See the file
15
  `license' for details on this and other legal matters.
16
*--------------------------------------------------------------*/
17
18
#ifndef __BASICSPRINGEMBEDDERLAYOUT_H
19
#define __BASICSPRINGEMBEDDERLAYOUT_H
20
21
#include <vector>
22
#include <string>
23
24
#include "graphlayouter.h"
25
26
NAMESPACE_BEGIN
27
28
29
/**
30
 * Implementation of the Spring Embedder algorithm. This class is the layouter
31
 * used in OMNeT++ 3.x.
32
 *
33
 * Simplifications:
34
 *  - ignores node sizes (this is visible when item is very long, e.g.
35
 *    500 x 10 pixels)
36
 *  - ignores connections to the parent module (nodes which are connected
37
 *    to the parent may end up in the middle of the layout)
38
 */
39
class LAYOUT_API BasicSpringEmbedderLayout : public GraphLayouter
40
{
41
  protected:
42
    struct Anchor
43
    {
44
        std::string name; // anchor name
45
        double x, y;      // position
46
        int refcount;     // how many nodes are anchored to it
47
        double x1off, y1off, x2off, y2off; // bounding box of anchored nodes, relative to (x,y)
48
        double vx, vy;    // internal: distance moved at each step (preserved between relax() calls)
49
    };
50
51
    struct Node
52
    {
53
        cModule *key;      // node "handle"
54
        bool fixed;        // allowed to move?
55
        Anchor *anchor;    // non-NULL for anchored nodes
56
        double x, y;       // position (of the center of the shape)
57
        int offx, offy;    // anchored nodes: offset to anchor point (and x,y are calculated)
58
        int sx, sy;        // half width/height
59
60
        double vx, vy;     // internal: distance moved at each step (preserved between relax() calls)
61
        int color;         // internal: connected nodes share the same color
62
        bool connectedToFixed; // internal: whether the node is connected (maybe indirectly) to a fixed node
63
    };
64
65
    struct Edge
66
    {
67
        Node *src;
68
        Node *target;
69
        double len;        // preferred length; making it "double" reduces the number of int->double conversions during layouting
70
    };
71
72
    // AnchorList and NodeList must be vectors because iteration on std::map is very slow
73
    typedef std::vector<Anchor*> AnchorList;
74
    typedef std::vector<Node*> NodeList;
75
    typedef std::vector<Edge> EdgeList;
76
77
    AnchorList anchors;
78
    NodeList nodes;
79
    EdgeList edges;
80
81
    int defaultEdgeLen;
82
83
    bool haveFixedNode;
84
    bool haveAnchoredNode;
85
    bool allNodesAreFixed;
86
87
    double minx, miny, maxx, maxy;
88
89
    int maxIterations;
90
    double repulsiveForce;
91
    double attractionForce;
92
93
  protected:
94
    // utility
95
    Node *findNode(cModule *mod);
96
97
    // mark connected nodes with same color; return number of colors used
98
    virtual int doColoring();
99
100
    // fill in the x1off, y1off, x2off, y2off fields of the anchors
101
    virtual void computeAnchorBoundingBoxes();
102
103
    // assign an initial layout that relax() will improve
104
    virtual void assignInitialPositions();
105
106
    // fill in the connectedToFixed fields of nodes
107
    virtual void markNodesConnectedToFixed(int numColors);
108
109
    // calculate bounding box (x1,y1,x2,y2)
110
    virtual void computeBoundingBox(double& x1, double& y1, double& x2, double& y2, bool (*predicate)(Node*));
111
112
    // main algorithm (modified spring embedder)
113
    virtual double relax();
114
115
    // for debugging: draw whole thing in a window
116
    void debugDraw(int step);
117
118
    // predicates for computeBoundingBox()
119
    static bool anyNode(Node *n) {return true;}
120
    static bool isFixedNode(Node *n) {return n->fixed;}
121
    static bool isNotConnectedToFixed(Node *n) {return !n->connectedToFixed;}
122
123
  public:
124
    /**
125
     * Ctor, dtor
126
     */
127
    //@{
128
    BasicSpringEmbedderLayout();
129
    virtual ~BasicSpringEmbedderLayout();
130
    //@}
131
132
    /** @name Redefined GraphLayouter methods */
133
    //@{
134
    virtual void setEnvironment(GraphLayouterEnvironment *environment);
135
    void addMovableNode(cModule *mod, int width, int height);
136
    void addFixedNode(cModule *mod, int x, int y, int width, int height);
137
    void addAnchoredNode(cModule *mod, const char *anchorname, int offx, int offy, int width, int height);
138
    void addEdge(cModule *src, cModule *target, int len=0);
139
    void addEdgeToBorder(cModule *src, int len=0);
140
    virtual void execute();
141
    void getNodePosition(cModule *mod, int& x, int& y);
142
    //@}
143
};
144
145
NAMESPACE_END
146
147
148
#endif
149
150