index dff414895517ea6897c352234e6e920729540744..00829dac889cdafce1590b08dc3bcdd28f28b7bc 100644 (file)
*
* Released under GNU GPL. Read the file 'COPYING' for more information.
*/
+#include "util/glib-list-iterators.h"
#include "graphlayout/graphlayout.h"
#include <iostream>
#include <config.h>
#include "sp-conn-end-pair.h"
#include "conn-avoid-ref.h"
#include "libavoid/connector.h"
+#include "libavoid/geomtypes.h"
#include <boost/graph/kamada_kawai_spring_layout.hpp>
#include <boost/graph/circle_layout.hpp>
#include <boost/graph/adjacency_list.hpp>
-#include <boost/graph/simple_point.hpp>
#include <boost/graph/graphviz.hpp>
#include <map>
#include <vector>
#include <algorithm>
#include <float.h>
-#include <string.h>
using namespace boost;
+
// create a typedef for the Graph type
typedef adjacency_list<vecS, vecS, undirectedS, no_property,
property<edge_weight_t, double> > Graph;
typedef property_map<Graph, edge_weight_t>::type WeightMap;
typedef graph_traits<Graph>::vertex_descriptor Vertex;
-typedef std::vector<simple_point<double> > PositionVec;
+typedef std::vector<Avoid::Point> PositionVec;
typedef iterator_property_map<PositionVec::iterator, property_map<Graph, vertex_index_t>::type> PositionMap;
-#endif // HAVE_BOOST_GRAPH_LIB
-bool isConnector(SPItem *i) {
+/**
+ * Returns true if item is a connector
+ */
+bool isConnector(SPItem const *const i) {
SPPath *path = NULL;
if(SP_IS_PATH(i)) {
path = SP_PATH(i);
}
return path && path->connEndPair.isAutoRoutingConn();
}
+
+/**
+ * Scans the items list and places those items that are
+ * not connectors in filtered
+ */
+void filterConnectors(GSList const *const items, std::list<SPItem *> &filtered) {
+ for(GSList *i=(GSList *)items; i!=NULL; i=i->next) {
+ SPItem *item=SP_ITEM(i->data);
+ if(!isConnector(item)) {
+ filtered.push_back(item);
+ }
+ }
+}
/**
* Takes a list of inkscape items, extracts the graph defined by
* connectors between them, and uses graph layout techniques to find
if(!items) {
return;
}
-#ifdef HAVE_BOOST_GRAPH_LIB
-
using Inkscape::Util::GSListConstIterator;
std::list<SPItem *> selected;
- selected.insert<GSListConstIterator<SPItem *> >(selected.end(), items, NULL);
+ filterConnectors(items,selected);
if (selected.empty()) return;
- int n=selected.size();
- //Check 2 or more selected objects
- if (n < 2) return;
+ int n=selected.size();
+ std::cout<<"|V|="<<n<<std::endl;
Graph g;
double minX=DBL_MAX, minY=DBL_MAX, maxX=-DBL_MAX, maxY=-DBL_MAX;
std::map<std::string,Vertex> nodelookup;
- for (std::list<SPItem *>::iterator it(selected.begin());
- it != selected.end();
- ++it)
+ for (std::list<SPItem *>::iterator i(selected.begin());
+ i != selected.end();
+ ++i)
{
- SPItem *u=*it;
- if(!isConnector(u)) {
- std::cout<<"Creating node for id: "<<u->id<<std::endl;
- nodelookup[u->id]=add_vertex(g);
- }
+ SPItem *u=*i;
+ std::cout<<"Creating node for id: "<<u->id<<std::endl;
+ nodelookup[u->id]=add_vertex(g);
}
+ //Check 2 or more selected objects
+ if (n < 2) return;
+
WeightMap weightmap=get(edge_weight, g);
- int i=0;
- for (std::list<SPItem *>::iterator it(selected.begin());
- it != selected.end();
- ++it)
+ for (std::list<SPItem *>::iterator i(selected.begin());
+ i != selected.end();
+ ++i)
{
using NR::X; using NR::Y;
- SPItem *itu=*it;
- Vertex u=nodelookup[itu->id];
- GSList *nlist=itu->avoidRef->getAttachedConnectors(Avoid::ConnRef::runningFrom);
+ SPItem *iu=*i;
+ std::cout<<"Getting neighbours for id: "<<iu->id<<std::endl;
+ Vertex u=nodelookup[iu->id];
+ GSList *nlist=iu->avoidRef->getAttachedShapes(Avoid::runningFrom);
std::list<SPItem *> neighbours;
neighbours.insert<GSListConstIterator<SPItem *> >(neighbours.end(),nlist,NULL);
- for (std::list<SPItem *>::iterator ne(neighbours.begin());
- ne != neighbours.end();
- ++ne) {
+ for (std::list<SPItem *>::iterator j(neighbours.begin());
+ j != neighbours.end();
+ ++j) {
- SPItem *itv=*ne;
- Vertex v=nodelookup[itv->id];
+ SPItem *iv=*j;
+ Vertex v=nodelookup[iv->id];
Graph::edge_descriptor e; bool inserted;
tie(e, inserted)=add_edge(u,v,g);
weightmap[e]=1.0;
if(nlist) {
g_slist_free(nlist);
}
- NR::Rect const item_box(sp_item_bbox_desktop(*it));
+ NR::Rect const item_box(sp_item_bbox_desktop(*i));
NR::Point ll(item_box.min());
minX=std::min(ll[0],minX);
kamada_kawai_spring_layout(g, position, weightmap, side_length(width));
graph_traits<Graph>::vertex_iterator vi, vi_end;
- i=0;
for (std::list<SPItem *>::iterator it(selected.begin());
it != selected.end();
++it)
sp_item_move_rel(u, NR::translate(dest - curr));
}
}
+}
#else
+void graphlayout(GSList const *const items) {
std::cout<<"Connector network layout not available! Install boost graph library and recompile to enable."<<std::endl;
-#endif // HAVE_BOOST_GRAPH_LIB
}
+#endif // HAVE_BOOST_GRAPH_LIB