MeVisLab Toolbox Reference
CSOLabelPlacementGlobal.h
Go to the documentation of this file.
1 /*************************************************************************************
2 **
3 ** Copyright 2014, MeVis Medical Solutions AG
4 **
5 ** The user may use this file in accordance with the license agreement provided with
6 ** the Software or, alternatively, in accordance with the terms contained in a
7 ** written agreement between the user and MeVis Medical Solutions AG.
8 **
9 ** For further information use the contact form at https://www.mevislab.de/contact
10 **
11 **************************************************************************************/
12 
13 
15 
16 #pragma once
17 
18 #include "../CSOLabelPlacement.h"
19 
20 #include <ThirdPartyWarningsDisable.h>
21 
22 #include <boost/unordered_map.hpp>
23 #include <boost/geometry.hpp>
24 #include <boost/geometry/geometries/point_xy.hpp>
25 #include <boost/geometry/geometries/polygon.hpp>
26 #include <boost/geometry/geometries/adapted/boost_tuple.hpp>
27 #include <boost/geometry/algorithms/convex_hull.hpp>
28 
29 #include <ThirdPartyWarningsRestore.h>
30 
31 
32 ML_START_NAMESPACE
33 
34 typedef boost::tuple <MLint, MLint> Point2D;
35 
38 {
39 public:
40 
41  enum HullMode {
42  CONVEX_CSO_HULL = 0,
43  HULL_POINTS_FROM_CSO_LIST
44  };
45 
47 
48  void layoutVisibleCSOs(const std::vector<CSODrawCSOInfos>& drawCSOInfos,
49  const std::map < int, SbVec2f>& labelBoxes,
50  const CSODrawView2DInfos& view2DInfos,
51  SoCSOLabelRenderer* labelRenderer) override;
52 
54  void getAttachedLabelPosition( const CSODrawCSOInfos& csoInfos, const CSODrawView2DInfos& view2DInfos, int labelWidth, int labelHeight, float& deviceX, float& deviceY ) override;
55 
56 protected:
57 
58  void handleNotification(Field* field) override;
59 
60 private:
61 
62  FloatField* _labelDeviceOffsetFld;
63  IntField* _additionalSlotsFld;
64  EnumField* _hullModeFld;
65  FloatField* _startAngleFld;
66  FloatField* _endAngleFld;
67  BaseField* _inHullCSOListFld;
68 
69  struct LabelBoundingBox
70  {
71  SbVec2f upper;
72  float width;
73  float height;
74  bool overlaps(const LabelBoundingBox& labelBoundingBox) const
75  {
76  const MLdouble augment = 3.;
77 
78  const MLdouble bb1v1x = labelBoundingBox.upper[0] - augment;
79  const MLdouble bb1v1y = labelBoundingBox.upper[1] - augment;
80  const MLdouble bb1v2x = labelBoundingBox.upper[0] + augment + labelBoundingBox.width;
81  const MLdouble bb1v2y = labelBoundingBox.upper[1] + augment + labelBoundingBox.height;
82 
83  const MLdouble bb2v1x = upper[0] - augment;
84  const MLdouble bb2v1y = upper[1] - augment;
85  const MLdouble bb2v2x = upper[0] + width + augment;
86  const MLdouble bb2v2y = upper[1] + height + augment;
87 
88  // store v1 maximum values in min-variables
89  const MLdouble minX = (bb1v1x > bb2v1x) ? bb1v1x : bb2v1x;
90  const MLdouble minY = (bb1v1y > bb2v1y) ? bb1v1y : bb2v1y;
91 
92  // store v2 minimum values in max-variables
93  const MLdouble maxX = (bb1v2x < bb2v2x) ? bb1v2x : bb2v2x;
94  const MLdouble maxY = (bb1v2y < bb2v2y) ? bb1v2y : bb2v2y;
95 
96  // if boxes intersect, all min values must be less/equal than the max values
97  bool result = true;
98 
99  result = result && (minX <= maxX);
100  result = result && (minY <= maxY);
101 
102  return result;
103  }
104  };
105 
106  void computeDeviceConvexHullOfAllCSOs(const std::vector<CSODrawCSOInfos>& drawCSOInfos,
107  boost::geometry::model::polygon < Point2D >& convexHull);
108  void computeCSODevicePositions(const std::vector<CSODrawCSOInfos>& drawCSOInfos,
109  const CSODrawView2DInfos& view2DInfos);
110  bool seedPointIsInSlicePlane(CSO* cso, int index, const CSODrawView2DInfos& view2DInfos) const;
111  CSO* getCSOInPlane(const CSODrawView2DInfos& view2DInfos) const;
112  bool computeDeviceHullForCSOList(const CSODrawView2DInfos& view2DInfos,
113  boost::geometry::model::polygon<Point2D>& convexHull) const;
114 
115  void offsetConvexHull(boost::geometry::model::polygon < Point2D >& convexHull, const Point2D& centroidOfHull, float deviceOffset) const;
116  static float computeMaxDistanceOfConvexHullFromCentroid(const boost::geometry::model::polygon < Point2D >& convexHull, const Point2D& centroidOfHull);
117  void computeLabelRays(size_t numCSOs, float rayLength, const Point2D& centroidOfHull, std::vector <Point2D>& labelRayEndPositions) const;
118  static void computeLabelSlotPositions( const boost::geometry::model::polygon < Point2D >& convexHull, const Point2D& centroidOfHull,
119  const std::vector <Point2D>& labelRayEndPositions, std::vector <Point2D>& labelSlotPositions );
120 
121  std::vector < std::pair < int, int> > computeNearestCSOForLabelPositionSlot(const std::vector <Point2D>& labelSlotPositions, const std::vector<unsigned int>& csoIds);
122  void computeCSOToSlotDistanceMatrix(const std::vector <Point2D>& labelSlotPositions, const std::vector<unsigned int>& csoIds, std::vector < std::vector < float > >& csoSlotDistancesMatrix);
123 
124  static float computeMinDistanceCSOToSlot(const std::vector<Point2D>& csoDevicePositions, const Point2D& slotPosition);
125  void setLabelPositionsForCSOs( const std::vector< std::pair< int, int > >& csoToSlotMapping,
126  const std::vector<unsigned int>& csoIds,
127  const std::map< int, SbVec2f>& labelBoxes,
128  const std::vector<Point2D>& labelSlotPositions,
129  const CSODrawView2DInfos& view2DInfos );
130  static SbVec2f getLabelBoxForCSO(const std::map < int, SbVec2f >& labelBoxes, int csoId);
131  void moveLabelByWidthHeight(const CSODrawView2DInfos& view2DInfos, int labelWidth, int labelHeight, MLint64& deviceX, MLint64& deviceY);
132  void avoidLabelOverlap(const std::map < int, SbVec2f >& labelBoxes);
133 
134  void setupLabelBoundingBoxes( const std::map< int, SbVec2f >& labelBoxes, std::map< int, LabelBoundingBox >& labelBoundingBoxes );
135  static bool boundingBoxHasOverlap( int csoId, const LabelBoundingBox& labelBoundingBox, const std::map< int, LabelBoundingBox >& labelBoundingBoxes );
136  bool moveLabelOutwards(LabelBoundingBox& labelBoundingBox);
137 
138  std::map <unsigned int, Point2D> _labelPositions;
139  std::map <unsigned int, std::vector<Point2D> > _csoDevicePositions;
140  CSOListPtr _hullCSOList;
141 
142  Point2D _centroidOfConvexHull;
143 
144  ML_MODULE_CLASS_HEADER(CSOLabelPlacementGlobal);
145 };
146 
147 ML_END_NAMESPACE
#define SOCSO_EXPORT
Header file for system independent resolution.
Definition: SoCSOSystem.h:21
Extension for rendering labels for CSOs.
Field to encapsulate a pointer to an ML base object.
Definition: mlFields.h:1187
Label placement strategy.
void handleNotification(Field *field) override
Called when any field data in the field container of this module is modified.
void layoutVisibleCSOs(const std::vector< CSODrawCSOInfos > &drawCSOInfos, const std::map< int, SbVec2f > &labelBoxes, const CSODrawView2DInfos &view2DInfos, SoCSOLabelRenderer *labelRenderer) override
void getAttachedLabelPosition(const CSODrawCSOInfos &csoInfos, const CSODrawView2DInfos &view2DInfos, int labelWidth, int labelHeight, float &deviceX, float &deviceY) override
Fills up the device position for an attached label.
Base module for providing custom label placement strategies.
Field to encapsulate an enumerated value.
Definition: mlFields.h:363
Base class for all fields used in the ML.
Definition: mlField.h:73
Field to encapsulate a float value.
Definition: mlFields.h:627
Field to encapsulate an integer value.
Definition: mlFields.h:161
#define ML_MODULE_CLASS_HEADER(className)
Like ML_CLASS_HEADER for the usage of derived classes from Module.
double MLdouble
Definition: mlTypeDefs.h:223
INT64 MLint64
Include 64 bit integer support for Windows or Unix.
Definition: mlTypeDefs.h:500
boost::tuple< MLint, MLint > Point2D