Adaptagrams
constraints.h
1 /*
2  * vim: ts=4 sw=4 et tw=0 wm=0
3  *
4  * libdialect - A library for computing DiAlEcT layouts:
5  * D = Decompose/Distribute
6  * A = Arrange
7  * E = Expand/Emend
8  * T = Transform
9  *
10  * Copyright (C) 2018 Monash University
11  *
12  * This library is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU Lesser General Public
14  * License as published by the Free Software Foundation; either
15  * version 2.1 of the License, or (at your option) any later version.
16  * See the file LICENSE.LGPL distributed with the library.
17  *
18  * This library is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
21  *
22  * Author(s): Steve Kieffer <http://skieffer.info>
23 */
24 
25 #ifndef DIALECT_CONSTRAINTS_H
26 #define DIALECT_CONSTRAINTS_H
27 
28 #include <map>
29 #include <set>
30 #include <string>
31 #include <vector>
32 #include <utility>
33 #include <memory>
34 
35 #include "libvpsc/rectangle.h"
36 #include "libcola/compound_constraints.h"
37 
38 #include "libdialect/commontypes.h"
39 #include "libdialect/ortho.h"
40 
41 namespace dialect {
42 
43 class Graph;
44 
45 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
46 // SepMatrices
47 
48 enum class GapType {
50  CENTRE,
52  BDRY
53 };
54 
55 enum class SepDir {
57  EAST, SOUTH, WEST, NORTH,
59  RIGHT, DOWN, LEFT, UP
60 };
61 
62 enum class SepType {
64  NONE,
66  EQ,
68  INEQ
69 };
70 
71 SepDir negateSepDir(SepDir sd);
72 
73 bool sepDirIsCardinal(SepDir sd);
74 
75 CardinalDir sepDirToCardinalDir(SepDir sd);
76 
77 SepDir cardinalDirToSepDir(CardinalDir dir);
78 
79 SepDir lateralWeakening(SepDir sd);
80 
81 SepDir cardinalStrengthening(SepDir sd);
82 
83 enum class SepTransform {
85  ROTATE90CW,
89  ROTATE180,
91  FLIPV,
93  FLIPH,
97  FLIPMD,
99  FLIPOD
100 };
101 
102 class SepMatrix;
103 
104 struct SepPair {
105  SepPair(void) : src(0), tgt(0), xgt(GapType::CENTRE), ygt(GapType::CENTRE), xst(SepType::NONE), yst(SepType::NONE), xgap(0.0), ygap(0.0) {}
106 
107  id_type src;
108  id_type tgt;
109  GapType xgt;
110  GapType ygt;
111  SepType xst;
112  SepType yst;
113  double xgap;
114  double ygap;
115 
117  unsigned tglfPrecision = 3;
118 
139  bool flippedRetrieval = false;
140 
143  void addSep(GapType gt, SepDir sd, SepType st, double gap);
145  void transform(SepTransform tf);
147  bool isVerticalCardinal(void) const;
149  bool isHorizontalCardinal(void) const;
151  bool isVAlign(void) const;
153  bool isHAlign(void) const;
155  bool isCardinal(void) const;
159  CardinalDir getCardinalDir(void) const;
163  void roundGapsUpAbs(void);
167  std::string writeTglf(std::map<id_type, unsigned> id2ext, const SepMatrix &m) const;
169  bool hasConstraintInDim(vpsc::Dim dim) const;
171  vpsc::Constraint *generateSeparationConstraint(const vpsc::Dim dim, const ColaGraphRep &cgr, SepMatrix *m, vpsc::Variables &vs);
172 };
173 
176 struct SepPairSubConstraintInfo : public cola::SubConstraintInfo {
177  SepPairSubConstraintInfo(SepPair_SP sp, vpsc::Dim dim) : cola::SubConstraintInfo(0), sp(sp), dim(dim) {}
178  SepPair_SP sp = nullptr;
179  vpsc::Dim dim;
180 };
181 
182 
183 static const unsigned int PRIORITY_SEPMATRIX = cola::DEFAULT_CONSTRAINT_PRIORITY;
184 
185 class SepMatrix : public cola::CompoundConstraint {
186 public:
191  SepMatrix(Graph *G) : cola::CompoundConstraint(vpsc::UNSET, PRIORITY_SEPMATRIX), m_graph(G) {
192  _combineSubConstraints = true;
193  }
195  SepMatrix(void) = delete;
197  SepMatrix(const SepMatrix &m) = default;
199  ~SepMatrix(void) = default;
219  void addSep(id_type id1, id_type id2, GapType gt, SepDir sd, SepType st, double gap);
220 
224  void setCardinalOP(id_type id1, id_type id2, dialect::CardinalDir dir) {
225  addSep(id1, id2, GapType::BDRY, (SepDir) dir, SepType::INEQ, 0.0);
226  }
227 
234  void addFixedRelativeSep(id_type id1, id_type id2, double dx, double dy);
235 
240  void addFixedRelativeSep(id_type id1, id_type id2);
241 
243  void hAlign(id_type id1, id_type id2) { addSep(id1, id2, GapType::CENTRE, SepDir::DOWN, SepType::EQ, 0); }
244 
246  void vAlign(id_type id1, id_type id2) { addSep(id1, id2, GapType::CENTRE, SepDir::RIGHT, SepType::EQ, 0); }
247 
254  void alignByEquatedCoord(id_type id1, id_type id2, vpsc::Dim eqCoord);
255 
258  void free(id_type id1, id_type id2);
259 
263  void clear(void) { m_sparseLookup.clear(); }
264 
271  void setCorrespondingConstraints(SepMatrix &matrix) const;
272 
278  void setSepPair(id_type id1, id_type id2, SepPair_SP sp);
279 
281  void transform(SepTransform tf);
288  void transformClosedSubset(SepTransform tf, const std::set<id_type> &ids);
295  void transformOpenSubset(SepTransform tf, const std::set<id_type> &ids);
297  void removeNode(id_type id);
299  void removeNodes(const NodesById &nodes);
305  CardinalDir getCardinalDir(id_type id1, id_type id2) const;
310  void getAlignedSets(std::map<id_type, std::set<id_type>> &hSets,
311  std::map<id_type, std::set<id_type>> &vSets) const;
313  bool areHAligned(id_type id1, id_type id2) const;
315  bool areVAligned(id_type id1, id_type id2) const;
319  std::string writeTglf(std::map<id_type, unsigned> id2ext) const;
321  void setGraph(Graph *G) { m_graph = G; }
323  Graph *getGraph(void) { return m_graph; }
326  void roundGapsUpward(void);
328  void setExtraBdryGap(double extraBdryGap) { m_extraBdryGap = extraBdryGap; }
329  double getExtraBdryGap(void) const { return m_extraBdryGap; }
330 
331 
333  void generateVariables(const vpsc::Dim dim, vpsc::Variables& vars);
334  void generateSeparationConstraints(const vpsc::Dim dim,
336  vpsc::Rectangles& bbs);
337  std::string toString(void) const;
338  void markAllSubConstraintsAsInactive(void);
339  cola::SubConstraintAlternatives getCurrSubConstraintAlternatives(vpsc::Variables vs[]);
340 
341 private:
342 
345  double m_extraBdryGap = 0.0;
346 
361  SepPair_SP &getSepPair(id_type id1, id_type id2);
362 
369  SepPair_SP checkSepPair(id_type id1, id_type id2) const;
370 
375  Graph *m_graph;
376 
395  SparseIdMatrix2d<SepPair_SP>::type m_sparseLookup;
396 };
397 
398 
399 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
400 // SepCos, Projections, ProjSeqs
401 
402 
422 struct SepCo {
423 
430  SepCo(vpsc::Dim dim, Node_SP left, Node_SP right, double gap, bool exact=false)
431  : dim(dim), left(left), right(right), gap(gap), exact(exact) {}
432 
438 
442  CardinalDir getDirecRelativeToNode(Node_SP baseNode) const;
443 
445  void addToMatrix(SepMatrix &matrix) const;
446 
448  double violation(void) const;
449 
451  std::string toString(void) const;
452 
453  vpsc::Dim dim;
454  Node_SP left;
455  Node_SP right;
456  double gap;
457  bool exact;
458 };
459 
460 typedef std::shared_ptr<SepCo> SepCo_SP;
461 typedef std::set<SepCo_SP> SepCoSet;
462 typedef std::vector<SepCoSet> SepCoSets;
463 
466 struct Projection{
467 
471  Projection(SepCoSet s, vpsc::Dim d) : sepCoSet(s), dim(d) {}
472 
474  size_t size(void) { return sepCoSet.size(); }
475 
480 
482  std::string toString(void) const;
483 
484  SepCoSet sepCoSet;
485  vpsc::Dim dim;
486 };
487 typedef std::shared_ptr<Projection> Projection_SP;
488 typedef std::vector<Projection_SP> Projections;
489 
492 class ProjSeq {
493 public:
494 
496  ProjSeq(void) {
497  // Initialize an empty final set in each dimension.
498  m_finalSets[vpsc::XDIM];
499  m_finalSets[vpsc::YDIM];
500  }
501 
506  void addProjection(SepCoSet sepCos, vpsc::Dim dim);
507 
510  Projection_SP nextProjection(void);
511 
513  void noteStresschange(double dS) { m_dSes.push_back(dS); }
514 
516  std::string toString(void) const;
517 
521  ProjSeq &operator+=(const ProjSeq &rhs);
522 
524  SepCoSet getAllConstraints(void) const;
525 
527  void reset(void) { m_ptr = 0; }
528 
530  double violation(void) const;
531 
532 private:
536  Projections m_projections;
538  std::vector<double> m_dSes;
540  size_t m_ptr = 0;
542  std::map<vpsc::Dim, SepCoSet> m_finalSets;
543 };
544 
545 } // namespace dialect
546 
547 // Global Operators
548 dialect::ProjSeq operator+(const dialect::ProjSeq &lhs, const dialect::ProjSeq &rhs);
549 
550 #endif // DIALECT_CONSTRAINTS_H
void reset(void)
Reset to start of sequence.
Definition: constraints.h:527
Flip over horizontal axis.
The Graph class represents graphs consisting of nodes and edges.
Definition: graphs.h:180
SepDir
Definition: constraints.h:55
size_t size(void)
Check how many SepCos are in the projection.
Definition: constraints.h:474
The x-dimension (0).
Definition: rectangle.h:45
ProjSeq(void)
Default constructor.
Definition: constraints.h:496
Gap between the opposite boundaries of two nodes:
Projection_SP nextProjection(void)
Get the next Projection, if any.
Definition: constraints.cpp:1037
An exact separation:
std::string toString(void) const
Write a string representation.
Definition: constraints.cpp:1072
libdialect: A library for computing human-like orthogonal network (DiAlEcT) layouts.
Definition: cola.h:44
std::string toString(void) const
Write a string representation.
Definition: constraints.cpp:1085
Definition: constraints.h:176
SepCo(vpsc::Dim dim, Node_SP left, Node_SP right, double gap, bool exact=false)
Standard constructor.
Definition: constraints.h:430
libvpsc: Variable Placement with Separation Constraints quadratic program solver library.
Definition: assertions.h:61
Definition: constraints.h:492
ProjSeq & operator+=(const ProjSeq &rhs)
When another ProjSeq is added to this one, we simply add each Projection from the other one to this o...
Definition: constraints.cpp:1045
Cardinal constraints imply both a separation and an alignment:
double violation(void) const
Determine the extent to which this separation constraint is currently violated.
Definition: constraints.cpp:1012
SepTransform
Definition: constraints.h:83
std::vector< Variable * > Variables
A vector of pointers to Variable objects.
Definition: constraint.h:38
std::vector< Constraint * > Constraints
A vector of pointers to Constraint objects.
Definition: constraint.h:125
Flip over vertical axis.
std::string toString(void) const
Write a string representation.
Definition: constraints.cpp:1095
Gap between the centres of two nodes:
std::vector< Rectangle * > Rectangles
A vector of pointers to Rectangle objects.
Definition: rectangle.h:246
A constraint determines a minimum or exact spacing required between two Variable objects.
Definition: constraint.h:44
Rotate 90 degrees anticlockwise.
A minimal separation:
GapType
Definition: constraints.h:48
void noteStresschange(double dS)
Note a stress change.
Definition: constraints.h:513
Definition: constraints.h:466
cola::CompoundConstraints generateColaConstraints(const ColaGraphRep &cgr)
Build a vector of cola CompoundConstraints representing the constraints in this Projection.
Definition: constraints.cpp:1020
CardinalDir getDirecRelativeToNode(Node_SP baseNode) const
Determine the constrained direction from one Node to the other.
Definition: constraints.cpp:998
No constraint:
Definition: constraints.h:422
Lateral constraints imply only a separation:
SepType
Definition: constraints.h:62
double violation(void) const
Sum the violations of all SepCos in the final sets.
Definition: constraints.cpp:1065
void addProjection(SepCoSet sepCos, vpsc::Dim dim)
Add a new set of SepCos, ensuring monotonicity by uniting with the previous set of constraints in the...
Definition: constraints.cpp:1028
Rotate 90 degrees clockwise.
void addToMatrix(SepMatrix &matrix) const
Add this constraint to a SepMatrix.
Definition: constraints.cpp:1006
Flip over the "off diagonal".
libcola: Force-directed network layout subject to separation constraints library. ...
Definition: box.cpp:25
Dim
Indicates the x- or y-dimension.
Definition: rectangle.h:41
Projection(SepCoSet s, vpsc::Dim d)
Standard constructor.
Definition: constraints.h:471
The y-dimension (1).
Definition: rectangle.h:49
An abstract base class for all high-level compound constraints.
Definition: compound_constraints.h:146
std::vector< CompoundConstraint * > CompoundConstraints
A vector of pointers to CompoundConstraint objects.
Definition: compound_constraints.h:259
SepCoSet getAllConstraints(void) const
Get the set of all constraints, in both dimensions.
Definition: constraints.cpp:1058
Bundles those data structures required in order to represent a Graph in libcola, and to map infomrati...
Definition: graphs.h:157
void generateVariables(CompoundConstraints &ccs, const vpsc::Dim dim, vpsc::Variables &vars)
Generate just all the variables for a collection of CompoundConstraints.
Definition: compound_constraints.cpp:1466
void generateColaConstraints(const ColaGraphRep &cgr, cola::CompoundConstraints &ccs)
Allocate cola::CompoundConstraints to represent this SepCo.
Definition: constraints.cpp:979