ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
ecvPointCloudLOD.h
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
8 #pragma once
9 
10 // CV_DB_LIB
11 #include "ecvFrustum.h"
12 #include "ecvOctree.h"
13 
14 // Qt
15 #include <QMutex>
16 
17 // system
18 #include <stdint.h>
19 
20 #include <array>
21 #include <functional>
22 
23 class ccPointCloud;
24 class ccPointCloudLODThread;
25 
27 struct LODLevelDesc {
31  LODLevelDesc(unsigned _startIndex, unsigned _count)
32  : startIndex(_startIndex), count(_count) {}
34  unsigned startIndex;
36  unsigned count;
37 };
38 
40 typedef std::vector<unsigned> LODIndexSet;
41 
44 public:
47 
51  virtual ~ccPointCloudLOD();
52 
54  bool init(ccPointCloud* cloud);
55 
57  inline void lock() { m_mutex.lock(); }
59  inline void unlock() { m_mutex.unlock(); }
60 
62  inline State getState() {
63  lock();
64  State state = m_state;
65  unlock();
66  return state;
67  }
68 
70  void clear();
71 
73  const ccOctree::Shared& octree() const { return m_octree; }
74 
77  inline bool isNull() { return getState() == NOT_INITIALIZED; }
78 
80  inline bool isInitialized() { return getState() == INITIALIZED; }
81 
83  inline bool isUnderConstruction() {
84  return getState() == UNDER_CONSTRUCTION;
85  }
86 
88  inline bool isBroken() { return getState() == BROKEN; }
89 
91  inline unsigned char maxLevel() {
92  QMutexLocker locker(&m_mutex);
93  return (m_state == INITIALIZED
94  ? static_cast<unsigned char>(
95  std::max<size_t>(1, m_levels.size())) -
96  1
97  : 0);
98  }
99 
101  static const unsigned char UNDEFINED = 255;
102 
104  struct Node {
105  // Warning: put the non aligned members (< 4 bytes) at the end to avoid
106  // too much alignment padding!
107  uint32_t pointCount; // 4 bytes
108  float radius; // 4 bytes
109  CCVector3f center; // 12 bytes
110  std::array<int32_t, 8> childIndexes; // 32 bytes
111  uint32_t firstCodeIndex; // 4 bytes
112  uint32_t displayedPointCount; // 4 bytes
113  uint8_t level; // 1 byte
114  uint8_t childCount; // 1 byte
115  uint8_t intersection; // 1 byte
116 
117  // Total
118  // // 63 bytes (64 with alignment)
119 
121  Node(uint8_t _level = 0)
122  : pointCount(0),
123  radius(0),
124  center(0, 0, 0),
125  firstCodeIndex(0),
127  level(_level),
128  childCount(0),
130  childIndexes.fill(-1);
131  }
132  };
133 
134  inline Node& node(int32_t index, unsigned char level) {
135  assert(level < m_levels.size() && index >= 0 &&
136  index < m_levels[level].data.size());
137  return m_levels[level].data[index];
138  }
139 
140  inline const Node& node(int32_t index, unsigned char level) const {
141  assert(level < m_levels.size() && index >= 0 &&
142  index < m_levels[level].data.size());
143  return m_levels[level].data[index];
144  }
145 
146  inline Node& root() { return node(0, 0); }
147 
148  inline const Node& root() const { return node(0, 0); }
149 
150  // inline float maxRadius(unsigned char level) const
151  //{
152  // assert(level < m_levels.size());
153  // return (level < m_levels.size() ? m_levels[level].maxRadius : 0);
154  // }
155 
157 
159  uint32_t flagVisibility(const Frustum& frustum,
160  ccClipPlaneSet* clipPlanes = 0);
161 
163  LODIndexSet& getIndexMap(unsigned char level,
164  unsigned& maxCount,
165  unsigned& remainingPointsAtThisLevel);
166 
168  inline const LODIndexSet& getLasIndexMap() const { return m_lastIndexMap; }
169 
171  inline bool allDisplayed() const {
173  }
174 
176  size_t memory() const;
177 
178 protected: // methods
180 
182  bool initInternal(ccOctree::Shared octree);
183 
185  inline void setState(State state) {
186  lock();
187  m_state = state;
188  unlock();
189  }
190 
192  void clearExtended(bool autoStopThread, State newState);
193 
195  void clearData();
196 
198 
201  int32_t newCell(unsigned char level);
202 
205 
207  // void updateMaxRadii();
208 
210 
214 
217  uint32_t addNPointsToIndexMap(Node& node, uint32_t count);
218 
219 protected: // members
220  struct Level {
222  //: maxRadius(0)
223  {}
224 
225  std::vector<Node> data;
226  // float maxRadius;
227  };
228 
230  std::vector<Level> m_levels;
231 
233  struct RenderParams {
235  : visiblePoints(0),
236  displayedPoints(0),
237  unfinishedLevel(-1),
238  unfinishedPoints(0) {}
239 
241  uint32_t visiblePoints;
243  uint32_t displayedPoints;
248  };
249 
252 
255 
258 
261 
264 
266  QMutex m_mutex;
267 
270 };
271 
273 public:
274  typedef std::function<void(const ccPointCloudLOD::Node&)> RenderFunc;
275 
277  RenderFunc& func,
278  const Frustum& frustum,
279  unsigned char maxLevel)
280  : m_func(func), m_frustum(frustum), m_lod(lod), m_maxLevel(maxLevel) {}
281 
282  void render(const ccPointCloudLOD::Node& node, bool testVisibility) {
283  if (testVisibility) {
284  switch (m_frustum.sphereInFrustum(node.center, node.radius)) {
285  case Frustum::INSIDE:
286  testVisibility = false;
287  break;
288 
289  case Frustum::INTERSECT:
290  testVisibility = true;
291  break;
292 
293  case Frustum::OUTSIDE:
294  return;
295  }
296  }
297 
298  // go on with the display of the children first
299  if (node.childCount && node.level < m_maxLevel) {
300  for (int i = 0; i < 8; ++i) {
301  if (node.childIndexes[i] >= 0) {
302  const ccPointCloudLOD::Node& childNode =
303  m_lod.node(node.childIndexes[i], node.level + 1);
304  render(childNode, testVisibility);
305  }
306  }
307  } else {
308  m_func(node);
309  }
310  }
311 
315  unsigned char m_maxLevel;
316 };
int count
@ OUTSIDE
Definition: ecvFrustum.h:97
@ INSIDE
Definition: ecvFrustum.h:99
@ INTERSECT
Definition: ecvFrustum.h:98
Intersection sphereInFrustum(const CCVector3f &c, float r) const
Definition: ecvFrustum.h:113
ccPointCloudLOD & m_lod
const Frustum & m_frustum
PointCloudLODRenderer(ccPointCloudLOD &lod, RenderFunc &func, const Frustum &frustum, unsigned char maxLevel)
void render(const ccPointCloudLOD::Node &node, bool testVisibility)
std::function< void(const ccPointCloudLOD::Node &)> RenderFunc
QSharedPointer< ccOctree > Shared
Shared pointer.
Definition: ecvOctree.h:32
L.O.D. (Level of Detail) structure.
QMutex m_mutex
For concurrent access.
bool isUnderConstruction()
Returns whether the structure is initialized or not.
State getState()
Returns the current state.
void clear()
Clears the structure.
bool allDisplayed() const
Returns whether all points have been displayed or not.
int32_t newCell(unsigned char level)
Reserves a new cell at a given level.
const Node & root() const
LODIndexSet m_indexMap
Index map.
ccPointCloudLODThread * m_thread
Computing thread.
void shrink_to_fit()
Shrinks the internal data to its minimum size.
LODIndexSet m_lastIndexMap
Last index map (pointer on)
const LODIndexSet & getLasIndexMap() const
Returns the last index map.
LODIndexSet & getIndexMap(unsigned char level, unsigned &maxCount, unsigned &remainingPointsAtThisLevel)
Builds an index map with the remaining visible points.
State m_state
State.
void unlock()
Unlocks the structure.
const Node & node(int32_t index, unsigned char level) const
uint32_t flagVisibility(const Frustum &frustum, ccClipPlaneSet *clipPlanes=0)
Test all cells visibility with a given frustum.
void clearExtended(bool autoStopThread, State newState)
Clears the structure (with more options)
ccPointCloudLOD()
Default constructor.
uint32_t addNPointsToIndexMap(Node &node, uint32_t count)
size_t memory() const
Returns the memory used by the structure (in bytes)
RenderParams m_currentState
Current rendering state.
virtual ~ccPointCloudLOD()
Destructor.
Node & node(int32_t index, unsigned char level)
bool isBroken()
Returns whether the structure is broken or not.
void setState(State state)
Sets the current state.
void resetVisibility()
Updates the max radius per level FOR ALL CELLS.
void lock()
Locks the structure.
bool init(ccPointCloud *cloud)
Initializes the construction process (asynchronous)
std::vector< Level > m_levels
Per-level cells data.
unsigned char maxLevel()
Returns the maximum accessible level.
void clearData()
Clears the internal (nodes) data.
State
Structure initialization state.
bool isInitialized()
Returns whether the structure is initialized or not.
static const unsigned char UNDEFINED
Undefined visibility flag.
const ccOctree::Shared & octree() const
Returns the associated octree.
friend ccPointCloudLODThread
ccOctree::Shared m_octree
Associated octree.
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
std::vector< ccClipPlane > ccClipPlaneSet
std::vector< unsigned > LODIndexSet
L.O.D. indexes set.
Level descriptor.
unsigned count
Index count for this level.
LODLevelDesc()
Default constructor.
unsigned startIndex
Start index (refers to the 'indexes' table)
LODLevelDesc(unsigned _startIndex, unsigned _count)
Constructor from a start index and a count value.
std::vector< Node > data
Octree 'tree' node.
Node(uint8_t _level=0)
Default constructor.
std::array< int32_t, 8 > childIndexes
Parameters of the current render state.
int unfinishedLevel
Previously unfinished level.
uint32_t visiblePoints
Number of visible points (for the last visibility test)
unsigned unfinishedPoints
Previously unfinished level.
uint32_t displayedPoints
Number of already displayed points.