ccPointCloudLOD.h 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  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: CloudCompare project #
  16. //# #
  17. //##########################################################################
  18. //qCC_db
  19. #include <ccOctree.h>
  20. #include <ccFrustum.h>
  21. //Qt
  22. #include <QMutex>
  23. //system
  24. #include <stdint.h>
  25. #include <array>
  26. #include <functional>
  27. class ccPointCloud;
  28. class ccPointCloudLODThread;
  29. //! Level descriptor
  30. struct LODLevelDesc
  31. {
  32. //! Default constructor
  33. LODLevelDesc() : startIndex(0), count(0) {}
  34. //! Constructor from a start index and a count value
  35. LODLevelDesc(unsigned _startIndex, unsigned _count) : startIndex(_startIndex), count(_count) {}
  36. //! Start index (refers to the 'indexes' table)
  37. unsigned startIndex;
  38. //! Index count for this level
  39. unsigned count;
  40. };
  41. //! L.O.D. indexes set
  42. typedef std::vector<unsigned> LODIndexSet;
  43. //! L.O.D. (Level of Detail) structure
  44. class ccPointCloudLOD
  45. {
  46. public:
  47. //! Structure initialization state
  48. enum State { NOT_INITIALIZED, UNDER_CONSTRUCTION, INITIALIZED, BROKEN };
  49. //! Default constructor
  50. ccPointCloudLOD();
  51. //! Destructor
  52. ~ccPointCloudLOD();
  53. //! Initializes the construction process (asynchronous)
  54. bool init(ccPointCloud* cloud);
  55. //! Locks the structure
  56. inline void lock() const
  57. {
  58. m_mutex.lock();
  59. }
  60. //! Unlocks the structure
  61. inline void unlock() const
  62. {
  63. m_mutex.unlock();
  64. }
  65. //! Returns the current state
  66. inline State getState() const
  67. {
  68. lock();
  69. State state = m_state;
  70. unlock();
  71. return state;
  72. }
  73. //! Clears the structure
  74. void clear();
  75. //! Returns the associated octree
  76. const ccOctree::Shared& octree() const
  77. {
  78. return m_octree;
  79. }
  80. //! Returns whether the structure is null (i.e. not under construction or initialized) or not
  81. inline bool isNull() const { return getState() == NOT_INITIALIZED; }
  82. //! Returns whether the structure is initialized or not
  83. inline bool isInitialized() const { return getState() == INITIALIZED; }
  84. //! Returns whether the structure is initialized or not
  85. inline bool isUnderConstruction() const { return getState() == UNDER_CONSTRUCTION; }
  86. //! Returns whether the structure is broken or not
  87. inline bool isBroken() const { return getState() == BROKEN; }
  88. //! Returns the maximum accessible level
  89. inline unsigned char maxLevel() const
  90. {
  91. QMutexLocker locker(&m_mutex);
  92. return (m_state == INITIALIZED ? static_cast<unsigned char>(std::max<size_t>(1, m_levels.size())) - 1 : 0);
  93. }
  94. //! Undefined visibility flag
  95. static const unsigned char UNDEFINED = 255;
  96. //! Octree 'tree' node
  97. struct Node
  98. {
  99. //Warning: put the non aligned members (< 4 bytes) at the end to avoid too much alignment padding!
  100. uint32_t pointCount; // 4 bytes
  101. float radius; // 4 bytes
  102. CCVector3f center; // 12 bytes
  103. std::array<int32_t, 8> childIndexes; // 32 bytes
  104. uint32_t firstCodeIndex; // 4 bytes
  105. uint32_t displayedPointCount; // 4 bytes
  106. uint8_t level; // 1 byte
  107. uint8_t childCount; // 1 byte
  108. uint8_t intersection; // 1 byte
  109. //Total // 63 bytes (64 with alignment)
  110. //! Default constructor
  111. Node(uint8_t _level = 0)
  112. : pointCount(0)
  113. , radius(0)
  114. , center(0, 0, 0)
  115. , childIndexes{-1, -1, -1, -1, -1, -1, -1, -1}
  116. , firstCodeIndex(0)
  117. , displayedPointCount(0)
  118. , level(_level)
  119. , childCount(0)
  120. , intersection(UNDEFINED)
  121. {
  122. }
  123. };
  124. inline Node& node(int32_t index, unsigned char level)
  125. {
  126. assert(level < m_levels.size() && index >= 0 && index < m_levels[level].data.size());
  127. return m_levels[level].data[index];
  128. }
  129. inline const Node& node(int32_t index, unsigned char level) const
  130. {
  131. assert(level < m_levels.size() && index >= 0 && index < m_levels[level].data.size());
  132. return m_levels[level].data[index];
  133. }
  134. inline Node& root() { return node(0, 0); }
  135. inline const Node& root() const { return node(0, 0); }
  136. //! Test all cells visibility with a given frustum
  137. /** Automatically calls resetVisibility
  138. **/
  139. uint32_t flagVisibility(const Frustum& frustum, ccClipPlaneSet* clipPlanes = nullptr);
  140. //! Builds an index map with the remaining visible points
  141. LODIndexSet& getIndexMap(unsigned char level, unsigned& maxCount, unsigned& remainingPointsAtThisLevel);
  142. //! Returns the last index map
  143. inline const LODIndexSet& getLasIndexMap() const { return m_lastIndexMap; }
  144. //! Returns whether all points have been displayed or not
  145. inline bool allDisplayed() const { return m_currentState.displayedPoints >= m_currentState.visiblePoints; }
  146. //! Returns the memory used by the structure (in bytes)
  147. size_t memory() const;
  148. protected: //methods
  149. friend ccPointCloudLODThread;
  150. //! Reserves memory
  151. bool initInternal(ccOctree::Shared octree);
  152. //! Sets the current state
  153. inline void setState(State state) { lock(); m_state = state; unlock(); }
  154. //! Clears the internal (nodes) data
  155. void clearData();
  156. //! Reserves a new cell at a given level
  157. /** \return the new cell index in the array corresponding to this level (see m_levels)
  158. **/
  159. int32_t newCell(unsigned char level);
  160. //! Shrinks the internal data to its minimum size
  161. void shrink_to_fit();
  162. //! Resets the internal visibility flags
  163. /** All nodes are flagged as 'INSIDE' (= visible) and their 'visibleCount' attribute is set to 0.
  164. **/
  165. void resetVisibility();
  166. //! Adds a given number of points to the active index map (should be dispatched among the children cells)
  167. uint32_t addNPointsToIndexMap(Node& node, uint32_t count);
  168. protected: //members
  169. //! Level data
  170. struct Level
  171. {
  172. std::vector<Node> data;
  173. };
  174. //! Per-level cells data
  175. std::vector<Level> m_levels;
  176. //! Parameters of the current render state
  177. struct RenderParams
  178. {
  179. RenderParams()
  180. : visiblePoints(0)
  181. , displayedPoints(0)
  182. , unfinishedLevel(-1)
  183. , unfinishedPoints(0)
  184. {}
  185. //! Number of visible points (for the last visibility test)
  186. uint32_t visiblePoints;
  187. //! Number of already displayed points
  188. uint32_t displayedPoints;
  189. //! Previously unfinished level
  190. int unfinishedLevel;
  191. //! Previously unfinished level
  192. unsigned unfinishedPoints;
  193. };
  194. //! Current rendering state
  195. RenderParams m_currentState;
  196. //! Index map
  197. LODIndexSet m_indexMap;
  198. //! Last index map (pointer on)
  199. LODIndexSet m_lastIndexMap;
  200. //! Associated octree
  201. ccOctree::Shared m_octree;
  202. //! Computing thread
  203. ccPointCloudLODThread* m_thread;
  204. //! For concurrent access
  205. mutable QMutex m_mutex;
  206. //! State
  207. State m_state;
  208. };