cc2DLabel.h 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. #pragma once
  2. //##########################################################################
  3. //# #
  4. //# CLOUDCOMPARE #
  5. //# #
  6. //# This program is free software; you can redistribute it and/or modify #
  7. //# it under the terms of the GNU General Public License as published by #
  8. //# the Free Software Foundation; version 2 or later of the License. #
  9. //# #
  10. //# This program is distributed in the hope that it will be useful, #
  11. //# but WITHOUT ANY WARRANTY; without even the implied warranty of #
  12. //# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
  13. //# GNU General Public License for more details. #
  14. //# #
  15. //# COPYRIGHT: EDF R&D / TELECOM ParisTech (ENST-TSI) #
  16. //# #
  17. //##########################################################################
  18. //Local
  19. #include "ccHObject.h"
  20. #include "ccInteractor.h"
  21. #include "ccGenericGLDisplay.h"
  22. //Qt
  23. #include <QRect>
  24. //System
  25. #include <array>
  26. class ccGenericPointCloud;
  27. class ccGenericMesh;
  28. //! 2D label (typically attached to points)
  29. class QCC_DB_LIB_API cc2DLabel : public ccHObject, public ccInteractor
  30. {
  31. public:
  32. //! Default constructor
  33. cc2DLabel(QString name = QString("label"));
  34. //! Copy constructor
  35. cc2DLabel(const cc2DLabel& label, bool copyPoints = true);
  36. //inherited from ccObject
  37. virtual QString getName() const override;
  38. //inherited from ccHObject
  39. inline virtual CC_CLASS_ENUM getClassID() const override { return CC_TYPES::LABEL_2D; }
  40. inline virtual bool isSerializable() const override { return true; }
  41. //! Returns 'raw' name (no replacement of default keywords)
  42. inline QString getRawName() const { return m_name; }
  43. //! Gets label content (as it will be displayed)
  44. /** \param precision displayed numbers precision
  45. \return label body (one string per line)
  46. **/
  47. QStringList getLabelContent(int precision) const;
  48. //! Returns the (3D) label title
  49. /** \param precision displayed numbers precision
  50. \return label title
  51. **/
  52. QString getTitle(int precision) const;
  53. //inherited from ccInteractor
  54. virtual bool acceptClick(int x, int y, Qt::MouseButton button) override;
  55. virtual bool move2D(int x, int y, int dx, int dy, int screenWidth, int screenHeight) override;
  56. //! Relative position (percentage)
  57. typedef std::array<float, 2> RelativePos;
  58. //! Sets relative position
  59. void setPosition(float x, float y);
  60. //! Returns relative position
  61. inline const RelativePos& getPosition() const { return m_screenPos; }
  62. //! Clears label
  63. void clear(bool ignoreDependencies = false);
  64. //! Returns current size
  65. inline unsigned size() const { return static_cast<unsigned>(m_pickedPoints.size()); }
  66. //! Adds a point to this label
  67. /** Adding a point to a label will automatically make it 'mutate'.
  68. 1 point = 'point' label (point position, normal, color, etc.)
  69. 2 points = 'vector' label (vertices position, distance)
  70. 3 points = "triangle/plane' label (vertices position, area, normal)
  71. \return false if 'full'
  72. **/
  73. bool addPickedPoint(ccGenericPointCloud* cloud, unsigned pointIndex, bool entityCenter = false);
  74. //! Adds a point to this label
  75. /** Adding a point to a label will automatically make it 'mutate'.
  76. 1 point = 'point' label (point position, normal, color, etc.)
  77. 2 points = 'vector' label (vertices position, distance)
  78. 3 points = "triangle/plane' label (vertices position, area, normal)
  79. \return false if 'full'
  80. **/
  81. bool addPickedPoint(ccGenericMesh* mesh, unsigned triangleIndex, const CCVector2d& uv, bool entityCenter = false);
  82. //! Whether to collapse label or not
  83. inline void setCollapsed(bool state) { m_showFullBody = !state; }
  84. //! Returns whether the label is collapsed or not
  85. inline bool isCollapsed() const { return !m_showFullBody; }
  86. //! Whether to display the point(s) legend (title only)
  87. inline void displayPointLegend(bool state) { m_dispPointsLegend = state; }
  88. //! Returns whether the point(s) legend is displayed
  89. inline bool isPointLegendDisplayed() const { return m_dispPointsLegend; }
  90. //! Whether to display the label in 2D
  91. inline void setDisplayedIn2D(bool state) { m_dispIn2D = state; }
  92. //! Returns whether the label is displayed in 2D
  93. inline bool isDisplayedIn2D() const { return m_dispIn2D; }
  94. //! Picked point descriptor
  95. /** Label 'points' can be shared between multiple entities
  96. **/
  97. struct QCC_DB_LIB_API PickedPoint
  98. {
  99. //! Cloud
  100. ccGenericPointCloud* _cloud;
  101. //! Mesh
  102. ccGenericMesh* _mesh;
  103. //! Point/triangle index
  104. unsigned index;
  105. //! Last known '2D' position (i.e. in screen space)
  106. /** This position is updated on each call to drawMeOnly3D
  107. **/
  108. CCVector3d pos2D;
  109. //! Last known marker scale
  110. float markerScale;
  111. //! Barycentric coordinates (for triangles)
  112. CCVector2d uv;
  113. //! Entity center mode (index will be invalid)
  114. bool entityCenterPoint;
  115. //! Returns the point position (3D)
  116. CCVector3 getPointPosition() const;
  117. //! Returns the cloud or the mesh vertices
  118. ccGenericPointCloud* cloudOrVertices() const;
  119. //! Returns the cloud or the mesh unique ID
  120. unsigned getUniqueID() const;
  121. //! Returns the associated entity (cloud or mesh)
  122. ccHObject* entity() const;
  123. //! Returns the item 'title' (either its index or 'Center' if it's a center point)
  124. QString itemTitle() const;
  125. //! Returns the point prefix ('Point' or 'Point@Tri' or 'IDXX Center')
  126. QString prefix(const char* pointTag) const;
  127. //! Default constructor
  128. PickedPoint()
  129. : _cloud(nullptr)
  130. , _mesh(nullptr)
  131. , index(0)
  132. , pos2D(0, 0, 0)
  133. , markerScale(0)
  134. , uv(0, 0)
  135. , entityCenterPoint(false)
  136. {}
  137. //! Constructor from a point and its index
  138. PickedPoint(ccGenericPointCloud* _cloud, unsigned pointIndex, bool centerPoint = false)
  139. : _cloud(_cloud)
  140. , _mesh(nullptr)
  141. , index(pointIndex)
  142. , pos2D(0, 0, 0)
  143. , markerScale(0)
  144. , uv(0, 0)
  145. , entityCenterPoint(centerPoint)
  146. {}
  147. //! Constructor from a triangle, its index and barycentric coordinates
  148. PickedPoint(ccGenericMesh* _mesh, unsigned triIindex, const CCVector2d& _uv, bool centerPoint = false)
  149. : _cloud(nullptr)
  150. , _mesh(_mesh)
  151. , index(triIindex)
  152. , pos2D(0, 0, 0)
  153. , markerScale(0)
  154. , uv(_uv)
  155. , entityCenterPoint(centerPoint)
  156. {}
  157. };
  158. //! Adds a point to this label (direct - handle with care)
  159. bool addPickedPoint(const PickedPoint& pp);
  160. //! Returns a given point (const version)
  161. inline const PickedPoint& getPickedPoint(unsigned index) const { return m_pickedPoints[index]; }
  162. //! Returns a given point
  163. inline PickedPoint& getPickedPoint(unsigned index) { return m_pickedPoints[index]; }
  164. //! Sets marker (relative) scale
  165. /** Default value: 1.0
  166. **/
  167. inline void setRelativeMarkerScale(float scale) { m_relMarkerScale = scale; }
  168. //! Point (marker) picking
  169. bool pointPicking( const CCVector2d& clickPos,
  170. const ccGLCameraParameters& camera,
  171. int& nearestPointIndex,
  172. double& nearestSquareDist) const;
  173. protected:
  174. //! One-point label info
  175. struct LabelInfo1
  176. {
  177. bool hasNormal;
  178. CCVector3 normal;
  179. bool hasRGB;
  180. ccColor::Rgba color;
  181. bool hasSF;
  182. ScalarType sfValue;
  183. QString sfName;
  184. //! Default constructor
  185. LabelInfo1()
  186. : hasNormal(false)
  187. , normal(0, 0, 0)
  188. , hasRGB(false)
  189. , color(0, 0, 0, 0)
  190. , hasSF(false)
  191. , sfValue(0)
  192. {}
  193. };
  194. //! Returns one-point label info
  195. void getLabelInfo1(LabelInfo1& info) const;
  196. //! Returns the SF value as a string
  197. /** Handles:
  198. - NaN values
  199. - shifted SF
  200. **/
  201. static QString GetSFValueAsString(const LabelInfo1& info, int precision);
  202. //! Two-points label info
  203. struct LabelInfo2
  204. {
  205. CCVector3 diff;
  206. //! Default constructor
  207. LabelInfo2()
  208. : diff(0, 0, 0)
  209. {}
  210. };
  211. //! Gets two-points label info
  212. void getLabelInfo2(LabelInfo2& info) const;
  213. //! Three-points label info
  214. struct LabelInfo3
  215. {
  216. CCVector3 normal;
  217. PointCoordinateType area;
  218. CCVector3d angles;
  219. CCVector3d edges;
  220. //! Default constructor
  221. LabelInfo3()
  222. : normal(0, 0, 0)
  223. , area(0)
  224. , angles(0, 0, 0)
  225. , edges(0, 0, 0)
  226. {}
  227. };
  228. //! Gets three-points label info
  229. void getLabelInfo3(LabelInfo3& info) const;
  230. //inherited from ccHObject
  231. bool toFile_MeOnly(QFile& out, short dataVersion) const override;
  232. bool fromFile_MeOnly(QFile& in, short dataVersion, int flags, LoadedIDMap& oldToNewIDMap) override;
  233. short minimumFileVersion_MeOnly() const override;
  234. void drawMeOnly(CC_DRAW_CONTEXT& context) override;
  235. void onDeletionOf(const ccHObject* obj) override;
  236. //! Draws the entity only (not its children) - 2D version
  237. void drawMeOnly2D(CC_DRAW_CONTEXT& context);
  238. //! Draws the entity only (not its children) - 3D version
  239. void drawMeOnly3D(CC_DRAW_CONTEXT& context);
  240. //! Updates the label 'name'
  241. void updateName();
  242. protected:
  243. //! Picked points
  244. std::vector<PickedPoint> m_pickedPoints;
  245. //! Whether to show full label body or not
  246. bool m_showFullBody;
  247. //! label ROI
  248. /** ROI is displayed relatively to m_screenPos
  249. (projected in displayed screen space). m_screenPos
  250. corresponds to its top-left corner. So ROI[1] is
  251. the distance to the upper border and ROI[3] is the
  252. distance to the lower border (relatively to m_screenPos).
  253. **/
  254. QRect m_labelROI;
  255. //! Label position (percentage of screen size)
  256. RelativePos m_screenPos;
  257. //! Absolute position (pixels)
  258. typedef std::array<int, 2> AbsolutePos;
  259. //! Label position at last display (absolute)
  260. AbsolutePos m_lastScreenPos;
  261. //! Whether to display the point(s) legend
  262. bool m_dispPointsLegend;
  263. //! Whether to display the label in 2D
  264. bool m_dispIn2D;
  265. //! Relative marker scale
  266. float m_relMarkerScale;
  267. };