6 * $Date: 2012-07-07 17:14:54 +0200 (Sa, 07. Jul 2012) $
7 ***************************************************************/
10 * \brief MMM is a Multilevel Graph drawing Algorithm that can use different modules.
12 * \author Gereon Bartel
15 * This file is part of the Open Graph Drawing Framework (OGDF).
19 * See README.txt in the root directory of the OGDF installation for details.
22 * This program is free software; you can redistribute it and/or
23 * modify it under the terms of the GNU General Public License
24 * Version 2 or 3 as published by the Free Software Foundation;
25 * see the file LICENSE.txt included in the packaging of this file
29 * This program is distributed in the hope that it will be useful,
30 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 * GNU General Public License for more details.
35 * You should have received a copy of the GNU General Public
36 * License along with this program; if not, write to the Free
37 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
38 * Boston, MA 02110-1301, USA.
40 * \see http://www.gnu.org/copyleft/gpl.html
41 ***************************************************************/
45 #include <ogdf/basic/basic.h>
46 #include <ogdf/energybased/multilevelmixer/ModularMultilevelMixer.h>
47 #include <ogdf/energybased/multilevelmixer/SolarMerger.h>
48 #include <ogdf/energybased/multilevelmixer/BarycenterPlacer.h>
49 #include <ogdf/energybased/FastMultipoleEmbedder.h>
50 #include <ogdf/energybased/SpringEmbedderFR.h>
53 #ifdef OGDF_MMM_LEVEL_OUTPUTS
61 ModularMultilevelMixer::ModularMultilevelMixer()
65 m_fixedEdgeLength
= -1.0f
;
66 m_fixedNodeSize
= -1.0f
;
67 m_coarseningRatio
= 1.0;
72 setMultilevelBuilder(new SolarMerger
);
73 setInitialPlacer (new BarycenterPlacer
);
74 setLevelLayoutModule(new SpringEmbedderFR
);
78 void ModularMultilevelMixer::call(GraphAttributes
&GA
)
79 { //ensure consistent behaviour of the two call Methods
80 MultilevelGraph
MLG(GA
);
82 MLG
.exportAttributes(GA
);
86 void ModularMultilevelMixer::call(MultilevelGraph
&MLG
)
88 const Graph
&G
= MLG
.getGraph();
90 m_errorCode
= ercNone
;
91 clock_t time
= clock();
92 if ((m_multilevelBuilder
.valid() == false || m_initialPlacement
.valid() == false) && m_oneLevelLayoutModule
.valid() == false) {
93 OGDF_THROW(AlgorithmFailureException
);
96 if (m_fixedEdgeLength
> 0.0) {
99 MLG
.weight(e
, m_fixedEdgeLength
);
103 if (m_fixedNodeSize
> 0.0) {
106 MLG
.radius(v
, m_fixedNodeSize
);
110 if (m_multilevelBuilder
.valid() && m_initialPlacement
.valid())
112 double lbound
= 16.0 * log(double(G
.numberOfNodes()))/log(2.0);
113 m_multilevelBuilder
.get().buildAllLevels(MLG
);
115 //Part for experiments: Stop if number of levels too high
116 #ifdef OGDF_MMM_LEVEL_OUTPUTS
117 int nlevels
= m_multilevelBuilder
.get().getNumLevels();
121 if ( m_multilevelBuilder
.get().getNumLevels() > lbound
)
123 m_errorCode
= ercLevelBound
;
131 MLG
.x(v
, (float)randomDouble(-1.0, 1.0));
132 MLG
.y(v
, (float)randomDouble(-1.0, 1.0));
136 while(MLG
.getLevel() > 0)
138 if (m_oneLevelLayoutModule
.valid()) {
139 for(int i
= 1; i
<= m_times
; i
++) {
140 m_oneLevelLayoutModule
.get().call(MLG
.getGraphAttributes());
144 #ifdef OGDF_MMM_LEVEL_OUTPUTS
146 std::stringstream ss
;
151 String
fs(s
.c_str());
158 int nNodes
= G
.numberOfNodes();
159 m_initialPlacement
.get().placeOneLevel(MLG
);
160 m_coarseningRatio
= float(G
.numberOfNodes()) / nNodes
;
162 #ifdef OGDF_MMM_LEVEL_OUTPUTS
165 MLG
.writeGML(String(s
.c_str()));
172 if(m_finalLayoutModule
.valid() || m_oneLevelLayoutModule
.valid())
174 LayoutModule
&lastLayoutModule
= (m_finalLayoutModule
.valid() != 0 ? m_finalLayoutModule
.get() : m_oneLevelLayoutModule
.get());
176 for(int i
= 1; i
<= m_times
; i
++) {
177 lastLayoutModule
.call(MLG
.getGraphAttributes());
181 time
= clock() - time
;