44#ifdef MAKEFEASIBLE_DEBUG
73inline double dotProd(valarray<double> x, valarray<double> y) {
74 COLA_ASSERT(x.size()==y.size());
76 for(
unsigned i=0;i<x.size();i++) {
83 printf(
"Matrix %dX%d\n{",n,n);
84 for(
unsigned i=0;i<n;i++) {
86 for(
unsigned j=0;j<n;j++) {
88 char c=j==n-1?
'}':
',';
91 char c=i==n-1?
'}':
',';
97 const std::vector< Edge >&
es,
const double idealLength,
101 X(valarray<double>(n)),
102 Y(valarray<double>(n)),
104 using_default_done(false),
105 preIteration(preIteration),
108 desiredPositions(nullptr),
109 clusterHierarchy(nullptr),
110 rectClusterBuffer(0),
111 m_idealEdgeLength(idealLength),
112 m_generateNonOverlapConstraints(false),
113 m_useNeighbourStress(false),
114 m_edge_lengths(eLengths.
data(), eLengths.
size()),
132 for(vpsc::Rectangles::const_iterator ri=
rs.begin();ri!=
rs.end();++ri,++i) {
133 X[i]=(*ri)->getCentreX();
134 Y[i]=(*ri)->getCentreY();
138 G=
new unsigned short*[
n];
139 for(
unsigned i=0;i<
n;i++) {
141 G[i]=
new unsigned short[
n];
149 std::vector<double> d;
151 for (
unsigned i = 0; i <
n; ++i) {
152 for (
unsigned j = 0; j <
n; ++j) {
153 d[
n*i + j] =
D[i][j];
161 std::vector<unsigned> g;
163 for (
unsigned i = 0; i <
n; ++i) {
164 for (
unsigned j = 0; j <
n; ++j) {
165 g[
n*i + j] =
G[i][j];
172 for (
unsigned i = 0; i <
n; ++i) {
175 for (vector<Edge>::iterator it =
es.begin(); it!=
es.end(); ++it) {
177 unsigned s = e.first, t = e.second;
183void dijkstra(
const unsigned s,
const unsigned n,
double* d,
184 const vector<Edge>&
es,
const std::valarray<double> & eLengths)
195 std::vector<std::vector<unsigned> > listOfNodeGroups)
228 const vector<Edge>&
es, std::valarray<double> eLengths)
231 for (
size_t i = 0; i < eLengths.size(); ++i)
233 if (eLengths[i] <= 0)
235 fprintf(stderr,
"Warning: ignoring non-positive length at index %d "
236 "in ideal edge length array.\n", (
int) i);
243 for(
unsigned i=0;i<
n;i++) {
244 for(
unsigned j=0;j<
n;j++) {
247 unsigned short& p=
G[i][j];
256 if ((d > 0) && (d <
minD)) {
263 for(vector<Edge>::const_iterator e=
es.begin();e!=
es.end();++e) {
264 unsigned u=e->first, v=e->second;
274 COLA_ASSERT(Y.size()==n);
275 COLA_ASSERT(pos.size()==2*n);
276 for(
unsigned i=0;i<n;++i) {
287 COLA_ASSERT(
Y.size()==
X.size());
288 COLA_ASSERT(pos.size()==2*
X.size());
298 const bool xAxis,
const bool yAxis,
326 FILE_LOG(
logDEBUG) <<
"ConstrainedFDLayout::run...";
327 double stress=DBL_MAX;
338 FILE_LOG(
logDEBUG) <<
" Resize event!";
360 FILE_LOG(
logDEBUG) <<
"stress="<<stress;
361 }
while(!(*
done)(stress,
X,
Y));
362 for(
unsigned i=0;i<
n;i++) {
366 FILE_LOG(
logDEBUG) <<
"ConstrainedFDLayout::run done.";
373 for (
size_t dim = 0; dim < 2; ++dim)
375 for (
size_t i =
n; i < vs[dim].size(); ++i)
388 double stress=DBL_MAX;
421 for (std::vector<Cluster*>::iterator curr = cluster->
clusters.begin();
422 curr != cluster->
clusters.end(); ++curr)
426 noc, *curr, idleConstraints);
429 if ( (noc ==
nullptr) && (
dynamic_cast<RootCluster *
> (cluster) ==
nullptr) )
436 COLA_ASSERT(vars[XDIM].
size() == vars[YDIM].
size());
440 vars[XDIM].push_back(variable);
444 vars[XDIM].push_back(variable);
448 vars[YDIM].push_back(variable);
452 vars[YDIM].push_back(variable);
465 idleConstraints.push_back(ccc);
479 std::set<Cluster *> expandedClusterSet(cluster->
clusters.begin(),
481 for (std::set<unsigned>::iterator curr = cluster->
nodes.begin();
482 curr != cluster->
nodes.end(); ++curr)
491 expandedClusterSet.insert(
499 for (std::set<Cluster*>::iterator curr = expandedClusterSet.begin();
500 curr != expandedClusterSet.end(); ++curr)
523 for (std::set<unsigned>::iterator curr =
542 std::vector<unsigned> nodesInClusterCounts(
boundingBoxes.size(), 0);
545 for (
unsigned int i = 0; i < nodesInClusterCounts.size(); ++i)
547 unsigned count = nodesInClusterCounts[i];
551 fprintf(stderr,
"Warning: node %u is contained in %d "
552 "clusters.\n", i, count);
613 for (
unsigned int dim = 0; dim < 2; ++dim)
616 for (
unsigned int i = 0; i < vs[dim].size(); ++i)
618 double pos = (dim == 0) ?
632 idleConstraints.insert(idleConstraints.end(),
635 std::sort(idleConstraints.begin(), idleConstraints.end(),
639 for (
unsigned int dim = 0; dim < 2; ++dim)
644#ifdef MAKEFEASIBLE_DEBUG
661 while (!idleConstraints.empty())
666 idleConstraints.pop_back();
668#ifdef MAKEFEASIBLE_DEBUG
671 std::vector<cola::Edge>
es;
678 std::sstream filename;
679 filename <<
"out/file-" << std::setfill(
'0') << std::setw(5) <<
iteration <<
".pdf";
688 bool subConstraintSatisfiable =
true;
703 COLA_ASSERT(alternatives.size() == 1);
704 vpsc::Dim& dim = alternatives.front().dim;
708 valid[dim].push_back(newConstraint);
718 for (
size_t dim = 0; dim < 2; ++dim)
720 if (solver[dim] ==
nullptr)
736 if (alternatives.empty())
741 while (!alternatives.empty())
744 subConstraintSatisfiable =
true;
746 vpsc::Dim& dim = alternatives.front().dim;
750 for (
unsigned int i = 0; i < priorPos.size(); ++i)
752 priorPos[i] = vs[dim][i]->finalPosition;
762 valid[dim].push_back(newConstraint);
767 if (solver[dim] ==
nullptr)
781 subConstraintSatisfiable =
false;
783 std::cerr <<
"++++ IN ERROR BLOCK" << std::endl;
784 std::cerr << str << std::endl;
788 std::cerr << **r <<std::endl;
791 for (
size_t i = 0; i < valid[dim].size(); ++i)
799 valid[dim][i]->unsatisfiable =
false;
801 subConstraintSatisfiable =
false;
805 if (!subConstraintSatisfiable)
810 solver[dim] =
nullptr;
813 for (
unsigned int i = 0; i < priorPos.size(); ++i)
815 vs[dim][i]->finalPosition = priorPos[i];
820 delete valid[dim].back();
821 valid[dim].pop_back();
829 alternatives.pop_front();
831#ifdef MAKEFEASIBLE_DEBUG
832 if (
true || idleConstraints.size() == 0)
836 std::vector<cola::Edge>
es;
843 std::sstream filename;
844 filename <<
"out/file-" << std::setfill(
'0') << std::setw(5) <<
iteration <<
".pdf";
857 for (
size_t dim = 0; dim < 2; ++dim)
862 solver[dim] =
nullptr;
877 for (
unsigned int dim = 0; dim < 2; ++dim)
905 for (
unsigned i = 0; i <
n; ++i)
923 std::list<CompoundConstraint *> freeList(
ccs.begin(),
ccs.end());
926 if (freeList.size() !=
ccs.size())
929 fprintf(stderr,
"Warning: CompoundConstraints vector contained %d "
930 "duplicates.\n", (
int) (
ccs.size() - freeList.size()));
961 valarray<double> &coords)
964 for (
unsigned i = 0; i < n; ++i)
969 if (clusterHierarchy && !clusterHierarchy->
flat())
973 clusterHierarchy->
createVars(dim, boundingBoxes, vs);
976 for (CompoundConstraints::const_iterator
c = ccs.begin();
979 (*c)->generateVariables(dim, vs);
981 for (CompoundConstraints::const_iterator
c = ccs.begin();
984 (*c)->generateSeparationConstraints(dim, vs, cs, boundingBoxes);
993 for (CompoundConstraints::const_iterator
c = ccs.begin();
996 (*c)->generateVariables(dim, vs);
998 for (CompoundConstraints::const_iterator
c = ccs.begin();
1001 (*c)->generateSeparationConstraints(dim, vs, cs, boundingBoxes);
1008 for (CompoundConstraints::const_iterator
c = ccs.begin();
1009 c != ccs.end(); ++
c)
1011 (*c)->updatePosition(dim);
1015 unsigned n=coords.size();
1018 for(
unsigned i=0;i<n;++i) {
1019 coords[i]=vs[i]->finalPosition;
1027 unsigned n=coords.size();
1028 COLA_ASSERT(vs.size()>=n);
1029 for(
unsigned i=0;i<n;++i) {
1031 v->desiredPosition = coords[i];
1034 for (DesiredPositionsInDim::const_iterator d=des.begin();
1035 d!=des.end(); ++d) {
1036 COLA_ASSERT(d->first<vs.size());
1038 v->desiredPosition = d->second;
1044 for(vpsc::Constraints::const_iterator
c=cs.begin();
c!=cs.end();++
c) {
1045 if((*c)->unsatisfiable) {
1047 unsatisfiable->push_back(i);
1064 COLA_ASSERT(target.size()==2*
n);
1065 FILE_LOG(
logDEBUG) <<
"ConstrainedFDLayout::moveTo(): dim="<<dim;
1075 des.push_back(make_pair(l->getID(),l->pos(dim)));
1082 v->desiredPosition = target[j];
1106 FILE_LOG(
logDEBUG) <<
"ConstrainedFDLayout::applyForcesAndConstraints(): dim="<<dim;
1107 valarray<double> g(
n);
1113 des.push_back(make_pair(l->getID(),l->pos(dim)));
1127 coords, des, oldStress);
1135 valarray<double> oldCoords=coords;
1139 valarray<double> d(
n);
1142 stepsize=max(0.,min(stepsize,1.));
1151 FILE_LOG(
logDEBUG) <<
"ConstrainedFDLayout::applyForcesAndConstraints... done, stress="<<stress;
1173 valarray<double>
const &d,
1174 valarray<double>
const &oldCoords,
1175 valarray<double> &coords,
1176 const double oldStress,
1180 COLA_UNUSED(oldStress);
1182 COLA_ASSERT(d.size()==oldCoords.size());
1183 COLA_ASSERT(d.size()==coords.size());
1184 while(fabs(stepsize)>0.00000000001) {
1185 coords=oldCoords-stepsize*d;
1201 std::vector<double> u(2);
1203 for (
size_t i = 0; i < 2; ++i)
1210 for (
size_t i = 0; i < 2; ++i)
1228 valarray<double> &g) {
1232 for(
unsigned u=0;u<
n;u++) {
1235 for(
unsigned v=0;v<
n;v++) {
1240 double rx=
X[u]-
X[v], ry=
Y[u]-
Y[v];
1241 double sd2 = rx*rx+ry*ry;
1242 unsigned maxDisplaces =
n;
1244 while (maxDisplaces--)
1254 rx=
X[u]-
X[v], ry=
Y[u]-
Y[v];
1258 unsigned short p =
G[u][v];
1263 if(l>d && p>1)
continue;
1271 g[u]+=dx*(l-d)/(d2*l);
1272 Huu-=H(u,v)=(d*dy*dy/(l*l*l)-1)/d2;
1281 ?p->x-
X[i]:p->y-
Y[i];
1294 valarray<double>
const &g,
1295 valarray<double>
const &d)
const
1297 COLA_ASSERT(g.size()==d.size());
1298 COLA_ASSERT(g.size()==H.
rowSize());
1300 double numerator =
dotProd(g,d);
1301 valarray<double> Hd(d.size());
1303 double denominator =
dotProd(d,Hd);
1306 if(denominator==0)
return 0;
1307 return numerator/denominator;
1315 FILE_LOG(
logDEBUG)<<
"ConstrainedFDLayout::computeStress()";
1317 for(
unsigned u=0;(u + 1)<
n;u++) {
1318 for(
unsigned v=u+1;v<
n;v++) {
1320 unsigned short p=
G[u][v];
1323 double rx=
X[u]-
X[v], ry=
Y[u]-
Y[v];
1324 double l=sqrt(rx*rx+ry*ry);
1326 if(l>d && p>1)
continue;
1331 FILE_LOG(
logDEBUG2)<<
"s("<<u<<
","<<v<<
")="<<s;
1339 double s=10000*(dx*dx+dy*dy);
1341 FILE_LOG(
logDEBUG2)<<
"d("<<l->getID()<<
")="<<s;
1349 double dx =
X[p->id] - p->x, dy =
Y[p->id] - p->y;
1350 stress+=0.5*p->weight*(dx*dx+dy*dy);
1356 for(
unsigned i=0;i<
n;i++) {
1365 val = std::min(val,
LIMIT);
1366 val = std::max(val, -
LIMIT);
1371 std::string filename;
1372 if (!instanceName.empty())
1374 filename = instanceName;
1378 filename =
"libcola-debug";
1381 FILE *fp = fopen(filename.c_str(),
"w");
1389 double minX =
LIMIT;
1390 double minY =
LIMIT;
1391 double maxX = -
LIMIT;
1392 double maxY = -
LIMIT;
1409 minX = std::min(minX, rMinX);
1413 maxX = std::max(maxX,rMaxX);
1417 minY = std::min(minY, rMinY);
1421 maxY = std::max(maxY, rMaxY);
1430 fprintf(fp,
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
1431 fprintf(fp,
"<svg xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" xmlns=\"http://www.w3.org/2000/svg\" width=\"100%%\" height=\"100%%\" viewBox=\"%g %g %g %g\">\n", minX, minY, maxX - minX, maxY - minY);
1434 fprintf(fp,
"<!-- Source code to generate this instance:\n");
1435 fprintf(fp,
"#include <vector>\n");
1436 fprintf(fp,
"#include <utility>\n");
1437 fprintf(fp,
"#include \"libcola/cola.h\"\n");
1438 fprintf(fp,
"using namespace cola;\n");
1439 fprintf(fp,
"int main(void) {\n");
1440 fprintf(fp,
" CompoundConstraints ccs;\n");
1441 fprintf(fp,
" std::vector<Edge> es;\n");
1442 fprintf(fp,
" EdgeLengths eLengths;\n");
1444 fprintf(fp,
" std::vector<vpsc::Rectangle*> rs;\n");
1445 fprintf(fp,
" vpsc::Rectangle *rect = nullptr;\n\n");
1448 fprintf(fp,
" rect = new vpsc::Rectangle(%g, %g, %g, %g);\n",
1451 fprintf(fp,
" rs.push_back(rect);\n\n");
1454 for (
size_t i = 0; i <
n; ++i)
1456 for (
size_t j = i + 1; j <
n; ++j)
1460 fprintf(fp,
" es.push_back(std::make_pair(%lu, %lu));\n", i, j);
1468 fprintf(fp,
" eLengths.resize(%d);\n", (
int)
m_edge_lengths.size());
1471 fprintf(fp,
" eLengths[%d] = %g;\n", (
int) i,
m_edge_lengths[i]);
1476 for (cola::CompoundConstraints::iterator
c =
ccs.begin();
1477 c !=
ccs.end(); ++
c)
1479 (*c)->printCreationCode(fp);
1482 fprintf(fp,
" ConstrainedFDLayout alg(rs, es, defaultEdgeLength, eLengths);\n");
1486 fprintf(fp,
" alg.setClusterHierarchy(cluster%llu);\n",
1489 fprintf(fp,
" alg.setConstraints(ccs);\n");
1490 fprintf(fp,
" alg.setAvoidNodeOverlaps(%s);\n",
1492 fprintf(fp,
" alg.makeFeasible();\n");
1493 fprintf(fp,
" alg.run();\n");
1494 fprintf(fp,
" alg.freeAssociatedObjects();\n");
1495 fprintf(fp,
" return 0;\n");
1496 fprintf(fp,
"};\n");
1497 fprintf(fp,
"-->\n");
1502 fprintf(fp,
"<g inkscape:groupmode=\"layer\" "
1503 "inkscape:label=\"Clusters\">\n");
1505 fprintf(fp,
"</g>\n");
1508 fprintf(fp,
"<g inkscape:groupmode=\"layer\" "
1509 "inkscape:label=\"Rects\">\n");
1517 fprintf(fp,
"<rect id=\"rect-%u\" x=\"%g\" y=\"%g\" width=\"%g\" "
1518 "height=\"%g\" style=\"stroke-width: 1px; stroke: black; "
1519 "fill: blue; fill-opacity: 0.3;\" />\n",
1520 (
unsigned) i, minX, minY, maxX - minX, maxY - minY);
1522 fprintf(fp,
"</g>\n");
1524 fprintf(fp,
"<g inkscape:groupmode=\"layer\" "
1525 "inkscape:label=\"Edges\">\n");
1526 for (
size_t i = 0; i <
n; ++i)
1528 for (
size_t j = i + 1; j <
n; ++j)
1532 fprintf(fp,
"<path d=\"M %g %g L %g %g\" "
1533 "style=\"stroke-width: 1px; stroke: black;\" />\n",
1541 fprintf(fp,
"</g>\n");
1543 fprintf(fp,
"</svg>\n");
1548 bool preventOverlaps,
int accept,
unsigned debugLevel)
1550 size_t n =
rs.size();
1554 if (preventOverlaps) {
1557 for (
size_t i = 0; i < n; ++i) {
1566 for (
size_t i = 0; i < n; ++i) {
1567 vs[i] =
new Variable(i,
rs[i]->getCentreD(dim));
1569 for (CompoundConstraints::iterator it=ccs.begin(); it!=ccs.end(); ++it) {
1577 if (
result.errorLevel <= accept) {
1578 for (
size_t i = 0; i < n; ++i) {
1579 rs[i]->moveCentreD(dim, vs[i]->finalPosition);
1583 for (Variables::iterator it=vs.begin(); it!=vs.end(); ++it)
delete *it;
1584 for (Constraints::iterator it=cs.begin(); it!=cs.end(); ++it)
delete *it;
1599 for (Constraints::iterator it=cs.begin(); it!=cs.end(); it++) {
1601 if (
c->unsatisfiable) {
1603 if (cc->
toString() ==
"NonOverlapConstraints()") {
1611 std::string unsatinfo;
1613 std::set<Variable*> varsInvolved;
1614 unsatinfo +=
"===================================================\n";
1615 unsatinfo +=
"UNSATISFIED CONSTRAINTS:\n";
1617 for (Constraints::iterator it=cs.begin(); it!=cs.end(); it++) {
1619 if (
c->unsatisfiable) {
1620 varsInvolved.insert(
c->left);
1621 varsInvolved.insert(
c->right);
1622 sprintf(
buf,
"v_%d + %f",
c->left->id,
c->gap);
1624 unsatinfo +=
c->equality ?
" == " :
" <= ";
1625 sprintf(
buf,
"v_%d\n",
c->right->id);
1627 if ((
unsigned)
c->left->id <
rs.size()) {
1629 sprintf(
buf,
" v_%d rect: [%f, %f] x [%f, %f]\n",
c->left->id,
1633 if ((
unsigned)
c->right->id <
rs.size()) {
1635 sprintf(
buf,
" v_%d rect: [%f, %f] x [%f, %f]\n",
c->right->id,
1640 unsatinfo +=
" Creator: " + cc->
toString() +
"\n";
1644 unsatinfo +=
"--------------------------------------------------\n";
1645 unsatinfo +=
"RELATED CONSTRAINTS:\n";
1646 std::set<Variable*>::iterator lit, rit, eit = varsInvolved.end();
1647 for (Constraints::iterator it=cs.begin(); it!=cs.end(); it++) {
1649 lit = varsInvolved.find(
c->left);
1650 rit = varsInvolved.find(
c->right);
1651 if (lit != eit || rit != eit) {
1652 sprintf(
buf,
"v_%d + %f",
c->left->id,
c->gap);
1654 unsatinfo +=
c->equality ?
" == " :
" <= ";
1655 sprintf(
buf,
"v_%d\n",
c->right->id);
1657 if ((
unsigned)
c->left->id <
rs.size()) {
1659 sprintf(
buf,
" v_%d rect: [%f, %f] x [%f, %f]\n",
c->left->id,
1663 if ((
unsigned)
c->right->id <
rs.size()) {
1665 sprintf(
buf,
" v_%d rect: [%f, %f] x [%f, %f]\n",
c->right->id,
1670 unsatinfo +=
" Creator: " + cc->
toString() +
"\n";
void setLabels(std::vector< std::string > ls)
A cluster defines a hierarchical partitioning over the nodes which should be kept disjoint by the lay...
std::set< unsigned > m_nodes_replaced_with_clusters
std::map< unsigned, Cluster * > m_overlap_replacement_map
std::vector< Cluster * > clusters
virtual void countContainedNodes(std::vector< unsigned > &counts)
std::set< ShapePair > m_cluster_cluster_overlap_exceptions
virtual void computeBoundingRect(const vpsc::Rectangles &rs)
std::set< unsigned > nodes
virtual void computeVarRect(vpsc::Variables &vs, size_t dim)
void createVars(const vpsc::Dim dim, const vpsc::Rectangles &rs, vpsc::Variables &vars)
An abstract base class for all high-level compound constraints.
unsigned int priority(void) const
virtual void generateSeparationConstraints(const vpsc::Dim dim, vpsc::Variables &var, vpsc::Constraints &cs, vpsc::Rectangles &bbs)=0
Implemented by the compound constraint to generate the low-level separation constraints in the given ...
virtual bool subConstraintsRemaining(void) const
virtual void generateVariables(const vpsc::Dim dim, vpsc::Variables &vars)=0
Implemented by the compound constraint to generate any additional required variables in the given dim...
virtual SubConstraintAlternatives getCurrSubConstraintAlternatives(vpsc::Variables vs[])=0
virtual std::string toString(void) const =0
Returns a textual description of the compound constraint.
virtual void markAllSubConstraintsAsInactive(void)
virtual void markCurrSubConstraintAsActive(const bool satisfiable)
bool shouldCombineSubConstraints(void) const
RootCluster * clusterHierarchy
void run(bool x=true, bool y=true)
Implements the main layout loop, taking descent steps until stress is no-longer significantly reduced...
ConstrainedFDLayout(const vpsc::Rectangles &rs, const std::vector< cola::Edge > &es, const double idealLength, const EdgeLengths &eLengths=StandardEdgeLengths, TestConvergence *doneTest=nullptr, PreIteration *preIteration=nullptr)
Constructs a constrained force-directed layout instance.
void computeDescentVectorOnBothAxes(const bool xaxis, const bool yaxis, double stress, std::valarray< double > &x0, std::valarray< double > &x1)
void freeAssociatedObjects(void)
A convenience method that can be called from Java to free the memory of nodes (Rectangles),...
DesiredPositions * desiredPositions
bool m_generateNonOverlapConstraints
void computeNeighbours(std::vector< Edge > es)
void setConstraints(const cola::CompoundConstraints &ccs)
Specify a set of compound constraints to apply to the layout.
std::vector< std::vector< unsigned > > neighbours
void computePathLengths(const std::vector< Edge > &es, std::valarray< double > eLengths)
std::vector< double > offsetDir(double minD)
double applyDescentVector(const std::valarray< double > &d, const std::valarray< double > &oldCoords, std::valarray< double > &coords, const double oldStress, double stepsize)
void setPosition(std::valarray< double > &pos)
TopologyAddonInterface * topologyAddon
double applyForcesAndConstraints(const vpsc::Dim dim, const double oldStress)
vpsc::Rectangles boundingBoxes
TopologyAddonInterface * getTopology(void)
std::vector< unsigned > readLinearG(void)
Retrieve a copy of the "G matrix" computed by the computePathLengths method, linearised as a vector.
double computeStepSize(const SparseMatrix &H, const std::valarray< double > &g, const std::valarray< double > &d) const
void setTopology(TopologyAddonInterface *topology)
Set an addon for doing topology preserving layout.
NonOverlapConstraintExemptions * m_nonoverlap_exemptions
void setDesiredPositions(DesiredPositions *desiredPositions)
std::valarray< double > Y
double computeStress() const
std::valarray< double > X
void computeForces(const vpsc::Dim dim, SparseMap &H, std::valarray< double > &g)
void handleResizes(const Resizes &)
std::vector< double > readLinearD(void)
Retrieve a copy of the "D matrix" computed by the computePathLengths method, linearised as a vector.
std::vector< UnsatisfiableConstraintInfos * > unsatisfiable
const std::valarray< double > m_edge_lengths
void moveTo(const vpsc::Dim dim, std::valarray< double > &target)
void makeFeasible(double xBorder=1, double yBorder=1)
Finds a feasible starting position for nodes that satisfies the given constraints.
bool m_useNeighbourStress
void setAvoidNodeOverlaps(bool avoidOverlaps, ListOfNodeIndexes listOfNodeGroups=ListOfNodeIndexes())
Specifies whether non-overlap constraints should be automatically generated between all nodes,...
cola::CompoundConstraints ccs
void generateNonOverlapAndClusterCompoundConstraints(vpsc::Variables(&vs)[2])
void recGenerateClusterVariablesAndConstraints(vpsc::Variables(&vars)[2], unsigned int &priority, cola::NonOverlapConstraints *noc, Cluster *cluster, cola::CompoundConstraints &idleConstraints)
void outputInstanceToSVG(std::string filename=std::string())
Generates an SVG file containing debug output and code that can be used to regenerate the instance.
cola::CompoundConstraints extraConstraints
PreIteration * preIteration
void runOnce(bool x=true, bool y=true)
Same as run(), but only applies one iteration.
void setUseNeighbourStress(bool useNeighbourStress)
Specifies whether neighbour stress should be used.
static TLogLevel & ReportingLevel()
void addExemptGroupOfNodes(ListOfNodeIndexes listOfNodeGroups)
void addShape(unsigned id, double halfW, double halfH, unsigned int group=1, std::set< unsigned > exemptions=std::set< unsigned >())
Use this method to add all the shapes between which you want to prevent overlaps.
void setClusterClusterExemptions(std::set< ShapePair > exemptions)
void addCluster(Cluster *cluster, unsigned int group)
A default functor that is called before each iteration in the main loop of the ConstrainedFDLayout::r...
static Resizes __resizesNotUsed
static Locks __locksNotUsed
double getNextBetween(double min, double max)
Defines a rectangular cluster, either variable-sized with floating sides or a fixed size based on a p...
virtual bool clusterIsFromFixedRectangle(void) const
void generateFixedRectangleConstraints(cola::CompoundConstraints &idleConstraints, vpsc::Rectangles &rc, vpsc::Variables(&vars)[2]) const
int rectangleIndex(void) const
Holds the cluster hierarchy specification for a diagram.
virtual void outputToSVG(FILE *fp) const
virtual void printCreationCode(FILE *fp) const
void calculateClusterPathsToEachNode(size_t nodesCount)
bool allowsMultipleParents(void) const
Returns true if this cluster hierarchy allows multiple parents, otherwise returns false.
void rightMultiply(std::valarray< double > const &v, std::valarray< double > &r) const
A default functor that is called after each iteration of the layout algorithm.
Interface for writing COLA addons to handle topology preserving layout.
virtual double applyForcesAndConstraints(ConstrainedFDLayout *layout, const vpsc::Dim dim, std::valarray< double > &g, vpsc::Variables &vs, vpsc::Constraints &cs, std::valarray< double > &coords, DesiredPositionsInDim &des, double oldStress)
virtual bool useTopologySolver(void) const
virtual void freeAssociatedObjects(void)
virtual double computeStress(void) const
virtual TopologyAddonInterface * clone(void) const
virtual void makeFeasible(bool generateNonOverlapConstraints, vpsc::Rectangles &boundingBoxes, cola::RootCluster *clusterHierarchy)
virtual void computePathLengths(unsigned short **G)
virtual void moveTo(const vpsc::Dim dim, vpsc::Variables &vs, vpsc::Constraints &cs, std::valarray< double > &coords, cola::RootCluster *clusterHierarchy)
virtual void handleResizes(const Resizes &resizeList, unsigned n, std::valarray< double > &X, std::valarray< double > &Y, cola::CompoundConstraints &ccs, vpsc::Rectangles &boundingBoxes, cola::RootCluster *clusterHierarchy)
Info about constraints that could not be satisfied in gradient projection process.
A constraint determines a minimum or exact spacing required between two Variable objects.
Incremental solver for Variable Placement with Separation Constraints problem instance.
void addConstraint(Constraint *constraint)
Adds a constraint to the existing VPSC solver.
bool solve()
Results in an optimum solution subject to the constraints.
bool satisfy()
Results in an approximate solution subject to the constraints.
A rectangle represents a fixed-size shape in the diagram that may be moved to prevent overlaps and sa...
static void setXBorder(double x)
static void setYBorder(double y)
A variable is comprised of an ideal position, final position and a weight.
vector< vpsc::Rectangle * > rs
libcola: Force-directed network layout subject to separation constraints library.
double dotProd(valarray< double > x, valarray< double > y)
ProjectionResult solve(vpsc::Variables &vs, vpsc::Constraints &cs, vpsc::Rectangles &rs, unsigned debugLevel=0)
Constructs a solver and attempts to solve the passed constraints on the passed vars.
std::vector< cola::Lock > Locks
A vector of Lock objects.
std::vector< CompoundConstraint * > CompoundConstraints
A vector of pointers to CompoundConstraint objects.
static const unsigned int PRIORITY_NONOVERLAP
void setVariableDesiredPositions(vpsc::Variables &vs, vpsc::Constraints &cs, const DesiredPositionsInDim &des, std::valarray< double > &coords)
void updateCompoundConstraints(const vpsc::Dim dim, const CompoundConstraints &ccs)
static const double freeWeight
static void setupExtraConstraints(const CompoundConstraints &ccs, const vpsc::Dim dim, vpsc::Variables &vs, vpsc::Constraints &cs, vpsc::Rectangles &boundingBoxes)
std::vector< cola::Resize > Resizes
A vector of Resize objects.
void setupVarsAndConstraints(unsigned n, const CompoundConstraints &ccs, const vpsc::Dim dim, vpsc::Rectangles &boundingBoxes, RootCluster *clusterHierarchy, vpsc::Variables &vs, vpsc::Constraints &cs, std::valarray< double > &coords)
void checkUnsatisfiable(const vpsc::Constraints &cs, UnsatisfiableConstraintInfos *unsatisfiable)
static const double LIMIT
static void reduceRange(double &val)
void project(vpsc::Variables &vs, vpsc::Constraints &cs, valarray< double > &coords)
std::vector< UnsatisfiableConstraintInfo * > UnsatisfiableConstraintInfos
A vector of pointers to UnsatisfiableConstraintInfo objects.
std::vector< cola::DesiredPosition > DesiredPositions
void generateVariables(CompoundConstraints &ccs, const vpsc::Dim dim, vpsc::Variables &vars)
Generate just all the variables for a collection of CompoundConstraints.
static bool cmpCompoundConstraintPriority(const cola::CompoundConstraint *lhs, const cola::CompoundConstraint *rhs)
void dumpSquareMatrix(unsigned n, T **L)
void delete_vector(vector< T * > &v)
std::list< SubConstraint > SubConstraintAlternatives
void dijkstra(const unsigned s, const unsigned n, double *d, const std::vector< cola::Edge > &es, const std::valarray< double > &eLengths)
valarray< double > Position
std::pair< unsigned, unsigned > Edge
Edges are simply a pair of indices to entries in the Node vector.
ProjectionResult projectOntoCCs(vpsc::Dim dim, vpsc::Rectangles &rs, cola::CompoundConstraints ccs, bool preventOverlaps, int accept=0, unsigned debugLevel=0)
Attempt to do a projection onto a vector of cola CompoundConstraints.
void getPosition(Position &X, Position &Y, Position &pos)
std::vector< double > EdgeLengths
EdgeLengths is a vector of ideal lengths for edges corresponding to edges in the edge list.
std::vector< DesiredPositionInDim > DesiredPositionsInDim
void dijkstra(unsigned const s, unsigned const n, T *d, std::vector< Edge > const &es, std::valarray< T > const &eweights=std::valarray< T >())
find shortest path lengths from node s to all other nodes
void johnsons(unsigned const n, T **D, std::vector< Edge > const &es, std::valarray< T > const &eweights=std::valarray< T >())
find all pairs shortest paths, faster, uses dijkstra
Dim
Indicates the x- or y-dimension.
@ HORIZONTAL
The x-dimension (0).
@ XDIM
The x-dimension (0).
@ VERTICAL
The y-dimension (1).
@ YDIM
The y-dimension (1).
std::vector< vpsc::Variable * > Variables
A vector of pointers to Variable objects.
std::vector< vpsc::Constraint * > Constraints
A vector of pointers to Constraint objects.
std::vector< Rectangle * > Rectangles
A vector of pointers to Rectangle objects.