Adaptagrams
faces.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_FACES_H
26 #define DIALECT_FACES_H
27 
28 #include <vector>
29 #include <set>
30 #include <map>
31 #include <string>
32 
33 #include "libvpsc/rectangle.h"
34 
35 #include "libdialect/commontypes.h"
36 #include "libdialect/ortho.h"
37 #include "libdialect/opts.h"
38 #include "libdialect/constraints.h"
39 
40 namespace dialect {
41 
43 class Side {
44 public:
45 
56  Side(Nodes nodeSeq, CardinalDir direc);
57 
59  Nodes getNodeSeq(void) const { return m_nodeSeq; }
60 
62  bool containsNode(id_type id) const;
63 
67  size_t findNodeIndex(id_type id) const;
68 
70  CardinalDir getForwardDirec(void) const;
71 
73  vpsc::Dim getAlignmentDimension(void) const { return m_vardim; }
74 
76  Node_SP firstNode(void) const;
77 
79  Node_SP lastNode(void) const;
80 
82  std::string toString(void) const;
83 
87  double getCentreCoord(void) const;
88 
90  size_t getNumRootNodes(void) const;
91 
93  void addTreePlacement(TreePlacement_SP tp);
94 
101  ProjSeq_SP computeCollateralProjSeq(TreePlacement_SP tp, double padding=0);
102 
106  interval closedInterval(void) const;
107 
116  interval getIntervalOppositeSegment(LineSegment &seg, bool openInterval=false) const;
117 
125  bool liesOppositeSegment(LineSegment &seg, bool openInterval=false) const;
126 
133  Avoid::Point getFirstPtOppositeSegment(LineSegment &seg) const;
134 
141  double halfWidthOppositeSegment(LineSegment &seg) const;
142 
144  const std::set<TreePlacement_SP> &getTreePlacements(void) const { return m_treePlacements; }
145 
146 private:
147 
150  Nodes m_nodeSeq;
152  CardinalDir m_forward;
154  CardinalDir m_inward;
156  vpsc::Dim m_vardim;
158  vpsc::Dim m_constdim;
160  std::set<TreePlacement_SP> m_treePlacements;
161 
162 };
163 
164 enum class NexusPolarity {
165  ENTER_FROM,
166  EXIT_TO
167 };
168 
182 class Nexus {
183 public:
184 
187  Nexus(Node_SP u) : m_node(u), m_slots(8) {}
188 
190  void addSide(Side_SP side);
191 
198  std::set<Side_SP> getNeighboursOfADirection(CompassDir direc);
199 
201  std::string toString(void) const;
202 
203 private:
204 
238  void writeSlot(CardinalDir direc, NexusPolarity polarity, Side_SP side);
239 
242  static const std::map<CompassDir, size_t> DIREC_TO_INITIAL_SEARCH_INDEX;
243 
244  Node_SP m_node;
245  std::vector<Side_SP> m_slots;
246  bool m_isEmpty = true;
247 };
248 
251 class FaceSet {
252 public:
253  FaceSet(Graph_SP &G);
254 
256  size_t getNumFaces(void) { return m_faces.size(); }
257 
264  TreePlacements listAllPossibleTreePlacements(Tree_SP tree, dialect::HolaOpts opts);
265 
269  TreePlacements getAllTreePlacements(void);
270 
272  Faces getFaces(void) { return m_faces; }
273 
275  Face_SP getExternalFace(void) { return m_externalFace; }
276 
282  std::map<CardinalDir, size_t> getNumTreesByGrowthDir(bool scaleBySize=false) const;
283 
284 private:
285 
287  void computeFaces(void);
289  void identifyExternalFace(void);
290 
292  Graph_SP m_graph;
293  Faces m_faces;
294  Face_SP m_externalFace;
296  std::map<id_type, std::set<Face_SP>> m_facesByMemberNodeId;
300  std::map<id_type, std::set<id_type>> m_hSets;
301  std::map<id_type, std::set<id_type>> m_vSets;
302 };
303 
304 
306 class Face {
307  friend class FaceSet;
308 public:
311  Face(Graph_SP &G) : m_ID(nextID++), m_graph(G) {}
312 
315  void initWithEdgeSeq(const std::vector<IdPair> &edges);
316 
319  Nodes getNodeSeq(void) { return m_nodeSeq; }
320 
322  Sides getSides(void) { return m_sides; }
323 
325  NexesById getNexusLookup(void) { return m_nexesByNodeIds; }
326 
329  bool containsNodeIdSeq(std::vector<id_type> idSeq) const;
330 
332  Graph_SP getGraph(void) { return m_graph; }
333 
337  id_type id(void) const { return m_ID; }
338 
340  bool isExternal(void) const { return m_isExternal; }
341 
343  std::string toString(void) const;
344 
346  std::map<id_type, std::vector<std::pair<Node_SP, Node_SP>>> getNbrPairs(void) {return m_nbrPairs;}
347 
349  Sides getRelevantSidesForPlacement(TreePlacement_SP tp) const;
350 
367  void listAllPossibleTreePlacements(TreePlacements &tps, Tree_SP tree, Node_SP root, HolaOpts opts);
368 
371  CompassDirs inwardDirsAvailable(Node_SP node);
372 
380  void insertTreeNode(TreePlacement_SP tp, double padding=0);
381 
400  ProjSeq_SP computeCollateralProjSeq(TreePlacement_SP tp, double padding=0);
401 
405  bool applyProjSeq(ProjSeq &ps);
406 
419  ProjSeq_SP doCollateralExpansion(TreePlacement_SP tp, double padding=-1);
420 
435  void buildBdrySegsFacingOneDir(CardinalDir facingDir,
436  LineSegments &closedSegs, LineSegments &openSegs,
437  TreePlacement_SP ignoreTP = nullptr);
438 
445  ProjSeq_SP buildBestProjSeq(TreePlacement_SP tp, double padding=0,
446  bool doCostlierDimensionFirst=false,
447  ExpansionEstimateMethod estimateMethod=ExpansionEstimateMethod::CONSTRAINTS);
448 
454  Sides getAllSidesOppositeSegment(LineSegment &seg, bool openInterval=false) const;
455 
458  TreePlacements getAllTreePlacements(void) const;
459 
462  std::set<TreePlacement_SP> getSetOfAllTreePlacements(void) const;
463 
467  void getAllTreePlacements(TreePlacements &tps) const;
468 
475  void getNumTreesByGrowthDir(std::map<CardinalDir, size_t> &counts, bool scaleBySize=false) const;
476 
477 private:
478 
480  void computeNbrPairs(void);
481  void computeSides(void);
482  void buildNexes(void);
483 
500  size_t findIndexOfFirstBend(void);
501 
505  CardinalDir direc(const Node_SP &u, const Node_SP &v);
506 
508  static id_type nextID;
510  const id_type m_ID;
511 
513  Graph_SP m_graph;
515  Nodes m_nodeSeq;
517  size_t m_n;
519  bool m_isExternal = false;
525  std::map<id_type, std::vector<std::pair<Node_SP, Node_SP>>> m_nbrPairs;
527  Sides m_sides;
529  NexesById m_nexesByNodeIds;
531  NodesById m_treeNodes;
535  std::map<id_type, TreePlacement_SP> m_treePlacementsByNodeIds;
536 
537 };
538 
539 
540 } // namespace dialect
541 
542 #endif // DIALECT_FACES_H
std::set< TreePlacement_SP > getSetOfAllTreePlacements(void) const
Get the set of all TreePlacements that have been added to this Face.
Definition: faces.cpp:637
Faces getFaces(void)
Get a copy of the vector of Faces_SP&#39;s.
Definition: faces.h:272
interval getIntervalOppositeSegment(LineSegment &seg, bool openInterval=false) const
Compute the closed interval [a, b] that is the intersection of this Side&#39;s closed interval with that ...
Definition: sides.cpp:224
bool isExternal(void) const
Check whether this is the external face or not.
Definition: faces.h:340
bool containsNode(id_type id) const
Check whether this Side contains a Node of the given ID.
Definition: sides.cpp:54
NexesById getNexusLookup(void)
Get a copy of the Nexus lookup.
Definition: faces.h:325
void getNumTreesByGrowthDir(std::map< CardinalDir, size_t > &counts, bool scaleBySize=false) const
After tree placements have been chosen and performed, get a count of trees by growth direction...
Definition: faces.cpp:653
double halfWidthOppositeSegment(LineSegment &seg) const
Given a LineSegment, find that portion of this Side that lies opposite it, (if any) and report the ma...
Definition: sides.cpp:259
TreePlacements getAllTreePlacements(void)
After tree placements have actually been chosen and performed (i.e. trees have been placed into faces...
Definition: faces.cpp:238
vpsc::Dim getAlignmentDimension(void) const
Check the dimension in which this Side is aligned.
Definition: faces.h:73
TreePlacements listAllPossibleTreePlacements(Tree_SP tree, dialect::HolaOpts opts)
Compute all the possible ways of placing a given Tree into the Faces, given that it must connect at a...
Definition: faces.cpp:219
Nexus(Node_SP u)
Standard constructor.
Definition: faces.h:187
std::string toString(void) const
Write a string representation.
Definition: nexes.cpp:115
TreePlacements getAllTreePlacements(void) const
Get all TreePlacements that have been added to this Face.
Definition: faces.cpp:627
Sides getRelevantSidesForPlacement(TreePlacement_SP tp) const
Get a vector of all Sides that are relevant to a given TreePlacement.
Definition: faces.cpp:456
CardinalDir getForwardDirec(void) const
Check the forward direction of this Side.
Definition: sides.cpp:69
Graph_SP getGraph(void)
Access the underlying Graph.
Definition: faces.h:332
void buildBdrySegsFacingOneDir(CardinalDir facingDir, LineSegments &closedSegs, LineSegments &openSegs, TreePlacement_SP ignoreTP=nullptr)
Build LineSegments to represent all those segments of the internal boundary of this Face that face in...
Definition: faces.cpp:527
void listAllPossibleTreePlacements(TreePlacements &tps, Tree_SP tree, Node_SP root, HolaOpts opts)
Compute all the possible ways of placing a given Tree into this Faces, at a given root Node belonging...
Definition: faces.cpp:257
ProjSeq_SP buildBestProjSeq(TreePlacement_SP tp, double padding=0, bool doCostlierDimensionFirst=false, ExpansionEstimateMethod estimateMethod=ExpansionEstimateMethod::CONSTRAINTS)
Build the best projection sequence for a given tree placement.
Definition: faces.cpp:585
Definition: faces.h:182
libdialect: A library for computing human-like orthogonal network (DiAlEcT) layouts.
Definition: cola.h:44
ProjSeq_SP computeCollateralProjSeq(TreePlacement_SP tp, double padding=0)
Compute a projection sequence to remove/prevent overlaps between the given TreePlacement&#39;s tree box...
Definition: faces.cpp:496
void addSide(Side_SP side)
Add a Side to the Nexus.
Definition: nexes.cpp:48
id_type id(void) const
Access the unique ID of a given instance.
Definition: faces.h:337
Node_SP firstNode(void) const
Get a pointer to the first Node on this Side.
Definition: sides.cpp:73
Definition: constraints.h:492
const std::set< TreePlacement_SP > & getTreePlacements(void) const
Read-only access to the set of TreePlacements that have been attached to this Side.
Definition: faces.h:144
Face_SP getExternalFace(void)
Get the external Face.
Definition: faces.h:275
std::set< Side_SP > getNeighboursOfADirection(CompassDir direc)
Find out what are the first objects you hit as you try sweeping both clockwise and anticlockwise...
Definition: nexes.cpp:62
CompassDirs inwardDirsAvailable(Node_SP node)
List the compass directions in which an edge could point if it were anchored at the given Node...
Definition: faces.cpp:286
size_t getNumRootNodes(void) const
Check how many of the Nodes on this Side are marked as root nodes.
Definition: sides.cpp:90
Sides getSides(void)
Get a copy of the vector of Sides.
Definition: faces.h:322
bool containsNodeIdSeq(std::vector< id_type > idSeq) const
Utility method, to test whether the Face contains a given sequence of Node IDs, in clockwise cyclic o...
Definition: faces.cpp:412
void addTreePlacement(TreePlacement_SP tp)
Record a TreePlacement as having been placed on this Side.
Definition: sides.cpp:96
Nodes getNodeSeq(void)
Access the sequence (vector) of Nodes belonging to the Face, in clockwise order.
Definition: faces.h:319
std::map< id_type, std::vector< std::pair< Node_SP, Node_SP > > > getNbrPairs(void)
Access the neighbour pairs.
Definition: faces.h:346
Side(Nodes nodeSeq, CardinalDir direc)
Standard constructor.
Definition: sides.cpp:47
Definition: faces.h:251
std::string toString(void) const
Write a string representation.
Definition: sides.cpp:83
double getCentreCoord(void) const
Check the centre coordinate of this Side.
Definition: sides.cpp:241
Node_SP lastNode(void) const
Get a pointer to the last Node on this Side.
Definition: sides.cpp:78
The Point class defines a point in the plane.
Definition: geomtypes.h:52
ProjSeq_SP doCollateralExpansion(TreePlacement_SP tp, double padding=-1)
Perform collateral expansion for a given TreePlacement. This means pushing Nodes and tree boxes on re...
Definition: faces.cpp:516
size_t findNodeIndex(id_type id) const
Get the index of a Node in this Side&#39;s node sequence.
Definition: sides.cpp:61
ExpansionEstimateMethod
Definition: opts.h:62
bool applyProjSeq(ProjSeq &ps)
Convenience function for applying a ProjSeq with all the appropriate options.
Definition: faces.cpp:507
interval closedInterval(void) const
Compute the closed interval [a, b], where a and b are the extreme coordinates covered by this Side...
Definition: sides.cpp:214
Face(Graph_SP &G)
Standard constructor.
Definition: faces.h:311
Dim
Indicates the x- or y-dimension.
Definition: rectangle.h:41
bool liesOppositeSegment(LineSegment &seg, bool openInterval=false) const
Check whether the closed interval spanned by this Side runs in the same dimension as a given line seg...
Definition: sides.cpp:234
ProjSeq_SP computeCollateralProjSeq(TreePlacement_SP tp, double padding=0)
Compute a projection sequence to remove/prevent overlaps between the given TreePlacement&#39;s tree box...
Definition: sides.cpp:104
void insertTreeNode(TreePlacement_SP tp, double padding=0)
To be used after the face has been expanded to make room for the tree. This method adds a large node ...
Definition: faces.cpp:471
std::string toString(void) const
Get a string representation.
Definition: faces.cpp:250
std::map< CardinalDir, size_t > getNumTreesByGrowthDir(bool scaleBySize=false) const
After tree placements have been chosen and performed, get a count of trees by growth direction...
Definition: faces.cpp:244
void initWithEdgeSeq(const std::vector< IdPair > &edges)
A method to build the Face, based on the clockwise sequence of "edges" of which it is made up; here a...
Definition: faces.cpp:328
Represents a single face of a 4-planar, orthogonal layout.
Definition: faces.h:306
Sides getAllSidesOppositeSegment(LineSegment &seg, bool openInterval=false) const
Get all the Sides of this Face that lie opposite a given LineSegment.
Definition: faces.cpp:618
size_t getNumFaces(void)
Check how many faces there are.
Definition: faces.h:256
Avoid::Point getFirstPtOppositeSegment(LineSegment &seg) const
Compute the first point of the interval of this Side that lies opposite a given line segment...
Definition: sides.cpp:248
A side of a Face. E.g. a rectangular Face has four Sides: north, south, east, and west...
Definition: faces.h:43
Nodes getNodeSeq(void) const
Get a copy of the node sequence.
Definition: faces.h:59