Skip to content

Commit

Permalink
plugins/layout/OGDF: Wrap new planar layout algorithms
Browse files Browse the repository at this point in the history
  • Loading branch information
anlambert committed Jul 16, 2024
1 parent cf0ac34 commit c9f67cf
Show file tree
Hide file tree
Showing 7 changed files with 291 additions and 1 deletion.
7 changes: 6 additions & 1 deletion plugins/layout/OGDF/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@ SET(PLUGINS_SRCS
OGDFTileToRowsPacking.cpp
OGDFPlanarizationLayout.cpp
OGDFDTreeMultilevelEmbedder.cpp
OGDFRadialTreeLayout.cpp)
OGDFRadialTreeLayout.cpp
OGDFMixedModel.cpp
OGDFSchnyderLayout.cpp
OGDFFPPLayout.cpp
OGDFPlanarDrawLayout.cpp
OGDFPlanarStraightLayout.cpp)

DISABLE_COMPILER_WARNINGS()

Expand Down
34 changes: 34 additions & 0 deletions plugins/layout/OGDF/OGDFFPPLayout.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
*
* Copyright (C) 2024 The Talipot developers
*
* Talipot is a fork of Tulip, created by David Auber
* and the Tulip development Team from LaBRI, University of Bordeaux
*
* See the AUTHORS file at the top-level directory of this distribution
* License: GNU General Public License version 3, or any later version
* See top-level LICENSE file for more information
*
*/

#include <ogdf/planarlayout/FPPLayout.h>

#include "OGDFPlanarLayoutBase.h"

// static constexpr std::string_view paramHelp[] = {};

class OGDFFPPLayout : public OGDFPlanarLayoutBase {

public:
PLUGININFORMATION("FPP (OGDF)", "", "", "", "1.0", "Planar")
OGDFFPPLayout(const tlp::PluginContext *context)
: OGDFPlanarLayoutBase(context, tlp::getOGDFLayoutModule<ogdf::FPPLayout>(context)),
fppLayout(static_cast<ogdf::FPPLayout *>(ogdfLayoutAlgo)) {}

void beforeCall() override {}

private:
ogdf::FPPLayout *fppLayout;
};

PLUGIN(OGDFFPPLayout)
68 changes: 68 additions & 0 deletions plugins/layout/OGDF/OGDFMixedModel.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/**
*
* Copyright (C) 2024 The Talipot developers
*
* Talipot is a fork of Tulip, created by David Auber
* and the Tulip development Team from LaBRI, University of Bordeaux
*
* See the AUTHORS file at the top-level directory of this distribution
* License: GNU General Public License version 3, or any later version
* See top-level LICENSE file for more information
*
*/

#include <ogdf/planarlayout/MixedModelLayout.h>
#include <ogdf/planarlayout/MMCBDoubleGrid.h>
#include <ogdf/planarlayout/MMCBLocalStretch.h>

#include <talipot/StringCollection.h>

#include "OGDFPlanarLayoutBase.h"

#define ELT_CROSSINGS_BEAUTIFIER "crossings beautifier"
#define ELT_CROSSINGS_BEAUTIFIER_LIST "MMDummyCrossingsBeautifier;MMCBDoubleGrid;MMCBLocalStretch"
static const std::vector<std::function<ogdf::MixedModelCrossingsBeautifierModule *()>>
crossingsBeautifier = {
[]() { return new ogdf::MMDummyCrossingsBeautifier; },
[]() { return new ogdf::MMCBDoubleGrid; },
[]() { return new ogdf::MMCBLocalStretch; },
};
static const char *crossingsBeautifierValuesDescription =
"<b>MMDummyCrossingsBeautifier</b> <i>(does no beautification at "
"all)</i><br><b>MMCBDoubleGrid</b> <i>(crossings beautifier using grid "
"doubling)</i><br><b>MMCBLocalStretch</b> <i>(crossings beautifier using a local stretch "
"strategy)</i>";

static constexpr std::string_view paramHelp[] = {
// crossings beautifiers
"The crossings beautifier is applied as preprocessing to dummy nodes in the graph that "
"actually represent crossings. By default, crossings might look weird, since they are not "
"drawn as two crossing horizontal and vertical lines; the other available crossings beautifier "
"correct this.",
};

class OGDFMixedModelLayout : public OGDFPlanarLayoutBase {

public:
PLUGININFORMATION("Mixed Model (OGDF)", "", "", "", "1.0", "Planar")
OGDFMixedModelLayout(const tlp::PluginContext *context)
: OGDFPlanarLayoutBase(context, tlp::getOGDFLayoutModule<ogdf::MixedModelLayout>(context)),
mixedModel(static_cast<ogdf::MixedModelLayout *>(ogdfLayoutAlgo)) {
addInParameter<tlp::StringCollection>(ELT_CROSSINGS_BEAUTIFIER, paramHelp[0].data(),
ELT_CROSSINGS_BEAUTIFIER_LIST, true,
crossingsBeautifierValuesDescription);
}

void beforeCall() override {
tlp::StringCollection sc;
if (dataSet && dataSet->get(ELT_CROSSINGS_BEAUTIFIER, sc)) {
mixedModel->setCrossingsBeautifier(crossingsBeautifier[sc.getCurrent()]());
}
tlpToOGDF->makeOGDFGraphSimple();
}

private:
ogdf::MixedModelLayout *mixedModel;
};

PLUGIN(OGDFMixedModelLayout)
34 changes: 34 additions & 0 deletions plugins/layout/OGDF/OGDFPlanarDrawLayout.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
*
* Copyright (C) 2024 The Talipot developers
*
* Talipot is a fork of Tulip, created by David Auber
* and the Tulip development Team from LaBRI, University of Bordeaux
*
* See the AUTHORS file at the top-level directory of this distribution
* License: GNU General Public License version 3, or any later version
* See top-level LICENSE file for more information
*
*/

#include <ogdf/planarlayout/PlanarDrawLayout.h>

#include "OGDFPlanarLayoutBase.h"

// static constexpr std::string_view paramHelp[] = {};

class OGDFPlanarDrawLayout : public OGDFPlanarLayoutBase {

public:
PLUGININFORMATION("Planar Draw (OGDF)", "", "", "", "1.0", "Planar")
OGDFPlanarDrawLayout(const tlp::PluginContext *context)
: OGDFPlanarLayoutBase(context, tlp::getOGDFLayoutModule<ogdf::PlanarDrawLayout>(context)),
planarDrawLayout(static_cast<ogdf::PlanarDrawLayout *>(ogdfLayoutAlgo)) {}

void beforeCall() override {}

private:
ogdf::PlanarDrawLayout *planarDrawLayout;
};

PLUGIN(OGDFPlanarDrawLayout)
43 changes: 43 additions & 0 deletions plugins/layout/OGDF/OGDFPlanarLayoutBase.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
*
* Copyright (C) 2024 The Talipot developers
*
* Talipot is a fork of Tulip, created by David Auber
* and the Tulip development Team from LaBRI, University of Bordeaux
*
* See the AUTHORS file at the top-level directory of this distribution
* License: GNU General Public License version 3, or any later version
* See top-level LICENSE file for more information
*
*/

#ifndef OGDF_PLANAR_LAYOUT_BASE_H
#define OGDF_PLANAR_LAYOUT_BASE_H

#include <talipot/OGDFLayoutPluginBase.h>

#include <talipot/ConnectedTest.h>
#include <talipot/PlanarityTest.h>

class OGDFPlanarLayoutBase : public tlp::OGDFLayoutPluginBase {

public:
OGDFPlanarLayoutBase(const tlp::PluginContext *context, ogdf::LayoutModule *ogdfLayoutAlgo)
: OGDFLayoutPluginBase(context, ogdfLayoutAlgo) {}

bool check(std::string &errorMsg) override {
auto connectedComponents = tlp::ConnectedTest::computeConnectedComponents(graph);
for (const auto &connectedComponent : connectedComponents) {
auto *sg = graph->inducedSubGraph(connectedComponent);
if (!tlp::PlanarityTest::isPlanar(sg)) {
graph->delSubGraph(sg);
errorMsg = "Each connected component must be planar.";
return false;
}
graph->delSubGraph(sg);
}
return true;
}
};

#endif // OGDF_PLANAR_LAYOUT_BASE_H
35 changes: 35 additions & 0 deletions plugins/layout/OGDF/OGDFPlanarStraightLayout.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
*
* Copyright (C) 2024 The Talipot developers
*
* Talipot is a fork of Tulip, created by David Auber
* and the Tulip development Team from LaBRI, University of Bordeaux
*
* See the AUTHORS file at the top-level directory of this distribution
* License: GNU General Public License version 3, or any later version
* See top-level LICENSE file for more information
*
*/

#include <ogdf/planarlayout/PlanarStraightLayout.h>

#include "OGDFPlanarLayoutBase.h"

// static constexpr std::string_view paramHelp[] = {};

class OGDFPlanarStraightLayout : public OGDFPlanarLayoutBase {

public:
PLUGININFORMATION("Planar Straight (OGDF)", "", "", "", "1.0", "Planar")
OGDFPlanarStraightLayout(const tlp::PluginContext *context)
: OGDFPlanarLayoutBase(context,
tlp::getOGDFLayoutModule<ogdf::PlanarStraightLayout>(context)),
planarStraightLayout(static_cast<ogdf::PlanarStraightLayout *>(ogdfLayoutAlgo)) {}

void beforeCall() override {}

private:
ogdf::PlanarStraightLayout *planarStraightLayout;
};

PLUGIN(OGDFPlanarStraightLayout)
71 changes: 71 additions & 0 deletions plugins/layout/OGDF/OGDFSchnyderLayout.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/**
*
* Copyright (C) 2024 The Talipot developers
*
* Talipot is a fork of Tulip, created by David Auber
* and the Tulip development Team from LaBRI, University of Bordeaux
*
* See the AUTHORS file at the top-level directory of this distribution
* License: GNU General Public License version 3, or any later version
* See top-level LICENSE file for more information
*
*/

#include <ogdf/planarlayout/SchnyderLayout.h>

#include <talipot/StringCollection.h>

#include "OGDFPlanarLayoutBase.h"

#define ELT_COMBINATORIAL_OBJECTS "combinatorial objects"
#define ELT_COMBINATORIAL_OBJECTS_LIST "VerticesMinusDepth;Faces"
static const std::vector<ogdf::SchnyderLayout::CombinatorialObjects> combinatorialObjects = {
ogdf::SchnyderLayout::CombinatorialObjects::VerticesMinusDepth,
ogdf::SchnyderLayout::CombinatorialObjects::Faces};

static constexpr std::string_view paramHelp[] = {
// combinatorial objects
"Each node in a Schnyder wood splits the graph into three regions. The barycentric coordinates "
"of the nodes are given by the count of combinatorial objects in these regions.",
};

static const char *combinatorialObjectsValuesDescription =
"<b>VerticesMinusDepth</b> <i>(Count the number of vertices in each region i and subtract "
"the depth of the (i-1)-path of the node. The grid layout size is (n - 2) × (n - "
"2).)</i><br>"
"<b>Faces</b> <i>(Count the number of faces in each region i. The grid layout size is (2n - 5) "
"× (2n - 5).)</i><br>";

class OGDFSchnyderLayout : public OGDFPlanarLayoutBase {

public:
PLUGININFORMATION(
"Schnyder (OGDF)", "Antoine Lambert", "O6/2024",
"This algorithm draws a planar graph G straight-line without crossings. G (with |V| ≥ 3) "
"must not contain self-loops or multiple edges. The algorithm runs in three phases. In the "
"first phase, the graph is augmented by adding new artificial edges to get a triangulated "
"plane graph. Then, a partition of the set of interior edges in three trees (also called "
"Schnyder trees) with special orientation properties is derived. In the third step, the "
"actual coordinates are computed.",
"1.0", "Planar")
OGDFSchnyderLayout(const tlp::PluginContext *context)
: OGDFPlanarLayoutBase(context, tlp::getOGDFLayoutModule<ogdf::SchnyderLayout>(context)),
schnyderLayout(static_cast<ogdf::SchnyderLayout *>(ogdfLayoutAlgo)) {
addInParameter<tlp::StringCollection>(ELT_COMBINATORIAL_OBJECTS, paramHelp[0].data(),
ELT_COMBINATORIAL_OBJECTS_LIST, true,
combinatorialObjectsValuesDescription);
}

void beforeCall() override {
tlp::StringCollection sc;
if (dataSet->get(ELT_COMBINATORIAL_OBJECTS, sc)) {
schnyderLayout->setCombinatorialObjects(combinatorialObjects[sc.getCurrent()]);
}
tlpToOGDF->makeOGDFGraphSimple();
}

private:
ogdf::SchnyderLayout *schnyderLayout;
};

PLUGIN(OGDFSchnyderLayout)

0 comments on commit c9f67cf

Please sign in to comment.