/** \file * Interface between Inkscape code (SPItem) and graphlayout functions. */ /* * Authors: * Tim Dwyer * * Copyright (C) 2005 Authors * * Released under GNU GPL. Read the file 'COPYING' for more information. */ #include "util/glib-list-iterators.h" #include "graphlayout/graphlayout.h" #include #include #ifdef HAVE_BOOST_GRAPH_LIB #include "sp-path.h" #include "sp-item.h" #include "sp-item-transform.h" #include "sp-conn-end-pair.h" #include "conn-avoid-ref.h" #include "libavoid/connector.h" #include "libavoid/geomtypes.h" #include #include #include #include #include #include #include #include using namespace boost; // create a typedef for the Graph type typedef adjacency_list > Graph; typedef property_map::type WeightMap; typedef graph_traits::vertex_descriptor Vertex; typedef std::vector PositionVec; typedef iterator_property_map::type> PositionMap; /** * 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 &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 * a nice layout */ void graphlayout(GSList const *const items) { if(!items) { return; } using Inkscape::Util::GSListConstIterator; std::list selected; filterConnectors(items,selected); if (selected.empty()) return; int n=selected.size(); std::cout<<"|V|="< nodelookup; for (std::list::iterator i(selected.begin()); i != selected.end(); ++i) { SPItem *u=*i; std::cout<<"Creating node for id: "<id<id]=add_vertex(g); } //Check 2 or more selected objects if (n < 2) return; WeightMap weightmap=get(edge_weight, g); for (std::list::iterator i(selected.begin()); i != selected.end(); ++i) { using NR::X; using NR::Y; SPItem *iu=*i; std::cout<<"Getting neighbours for id: "<id<id]; GSList *nlist=iu->avoidRef->getAttachedShapes(Avoid::runningFrom); std::list neighbours; neighbours.insert >(neighbours.end(),nlist,NULL); for (std::list::iterator j(neighbours.begin()); j != neighbours.end(); ++j) { 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(*i)); NR::Point ll(item_box.min()); minX=std::min(ll[0],minX); minY=std::min(ll[1],minY); NR::Point ur(item_box.max()); maxX=std::max(ur[0],maxX); maxY=std::max(ur[1],maxY); } double width=maxX-minX; double height=maxY-minY; std::cout<<"Graph has |V|="<