ChunkHashGrid.cpp
Go to the documentation of this file.
1 
36 
37 namespace lvr2
38 {
39 ChunkHashGrid::ChunkHashGrid(std::string hdf5Path, size_t cacheSize, float chunkSize)
40  : m_cacheSize(cacheSize)
41 {
42  m_io.open(hdf5Path);
43 
44  try
45  {
46  setChunkSize(m_io.loadChunkSize());
47  setBoundingBox(m_io.loadBoundingBox());
48  }
49  catch (...)
50  {
51  setChunkSize(chunkSize);
52  }
53 }
54 
55 ChunkHashGrid::ChunkHashGrid(std::string hdf5Path,
56  size_t cacheSize,
57  BoundingBox<BaseVector<float>> boundingBox,
58  float chunkSize)
59  : m_cacheSize(cacheSize)
60 {
61  m_io.open(hdf5Path);
62  setChunkSize(chunkSize);
63  setBoundingBox(boundingBox);
64 }
65 
66 bool ChunkHashGrid::isChunkLoaded(std::string layer, std::size_t hashValue)
67 {
68  auto layerIt = m_hashGrid.find(layer);
69  if (layerIt != m_hashGrid.end())
70  {
71  auto chunkIt = layerIt->second.find(hashValue);
72  if (chunkIt != layerIt->second.end())
73  {
74  return true;
75  }
76  }
77  return false;
78 }
79 
80 bool ChunkHashGrid::isChunkLoaded(std::string layer, int x, int y, int z)
81 {
82  return isChunkLoaded(layer, hashValue(x, y, z));
83 }
84 
86  const BaseVector<std::size_t>& oldChunkIndexOffset)
87 {
88  std::unordered_map<std::string, std::unordered_map<std::size_t, val_type>> tmpCache;
89  for (std::pair<std::string, std::size_t>& elem : m_items)
90  {
91  // undo old hash function
92  int k = elem.second % oldChunkAmount.z - oldChunkIndexOffset.z;
93  int j = (elem.second / oldChunkAmount.z) % oldChunkAmount.y - oldChunkIndexOffset.y;
94  int i = elem.second / (oldChunkAmount.y * oldChunkAmount.z) - oldChunkIndexOffset.x;
95 
96  val_type chunk;
97 
98  auto layerIt = tmpCache.find(elem.first);
99  if (layerIt != tmpCache.end())
100  {
101  auto chunkIt = tmpCache[elem.first].find(elem.second);
102  if (chunkIt != tmpCache[elem.first].end())
103  {
104  chunk = tmpCache[elem.first][elem.second];
105  }
106  else
107  {
108  chunk = m_hashGrid[elem.first][elem.second];
109  }
110  }
111  else
112  {
113  chunk = m_hashGrid[elem.first][elem.second];
114  }
115 
116  std::size_t newHash = hashValue(i, j, k);
117 
118  auto chunkIt = m_hashGrid[elem.first].find(newHash);
119  if (chunkIt != m_hashGrid[elem.first].end())
120  {
121  tmpCache[elem.first][newHash] = m_hashGrid[elem.first][newHash];
122  }
123  m_hashGrid[elem.first][newHash] = chunk;
124  m_hashGrid[elem.first].erase(elem.second);
125 
126  elem.second = newHash;
127  }
128 }
129 
131 {
132  FloatChannelOptional geometryChannel = boost::apply_visitor(ChunkGeomtryChannelVisitor(), data);
133  if (geometryChannel)
134  {
136  for (unsigned int i = 0; i < geometryChannel.get().numElements(); i++)
137  {
138  boundingBox.expand(static_cast<BaseVector<float>>(geometryChannel.get()[i]));
139  }
140 
141  setBoundingBox(boundingBox);
142  }
143 }
144 
145 void ChunkHashGrid::loadChunk(std::string layer, int x, int y, int z, const val_type& data)
146 {
147  std::size_t chunkHash = hashValue(x, y, z);
148 
149  if (isChunkLoaded(layer, chunkHash))
150  {
151  // chunk exists for layer in grid
152  // remove chunk from cache to put the chunk to front of lru cache later
153  m_items.remove({layer, chunkHash});
154  }
155 
156  // add new chunk to cache
157  m_items.push_front({layer, chunkHash});
158 
159  // check if cache is full
160  if (m_items.size() > m_cacheSize)
161  {
162  // remove chunk from grid keep the grid for the current layer even if it holds no elements
163  m_hashGrid[m_items.back().first].erase(m_items.back().second);
164 
165  // remove erased element from cache
166  m_items.pop_back();
167  }
168 
169  m_hashGrid[layer][chunkHash] = data;
170 }
171 
173 {
174  if (m_boundingBox.getMin() == boundingBox.getMin()
175  && m_boundingBox.getMax() == boundingBox.getMax())
176  {
177  return;
178  }
179 
180  m_boundingBox = boundingBox;
181  m_io.saveBoundingBox(m_boundingBox);
182 
183  BaseVector<std::size_t> chunkIndexOffset;
184  chunkIndexOffset.x
185  = static_cast<std::size_t>(std::ceil(-getBoundingBox().getMin().x / getChunkSize()) + 1);
186  chunkIndexOffset.y
187  = static_cast<std::size_t>(std::ceil(-getBoundingBox().getMin().y / getChunkSize()) + 1);
188  chunkIndexOffset.z
189  = static_cast<std::size_t>(std::ceil(-getBoundingBox().getMin().z / getChunkSize()) + 1);
190 
191  BaseVector<std::size_t> chunkAmount;
192  chunkAmount.x
193  = static_cast<std::size_t>(std::ceil(getBoundingBox().getXSize() / getChunkSize()) + 1);
194  chunkAmount.y
195  = static_cast<std::size_t>(std::ceil(getBoundingBox().getYSize() / getChunkSize()) + 1);
196  chunkAmount.z
197  = static_cast<std::size_t>(std::ceil(getBoundingBox().getZSize() / getChunkSize()) + 1);
198 
199  setChunkAmountAndOffset(chunkAmount, chunkIndexOffset);
200 }
201 
203  const BaseVector<std::size_t>& chunkIndexOffset)
204 {
205  if (m_chunkAmount != chunkAmount || m_chunkIndexOffset != chunkIndexOffset)
206  {
207  BaseVector<std::size_t> oldChunkAmount = m_chunkAmount;
208  BaseVector<std::size_t> oldChunkIndexOffset = m_chunkIndexOffset;
209 
210  m_chunkAmount = chunkAmount;
211  m_chunkIndexOffset = chunkIndexOffset;
212 
213  rehashCache(oldChunkAmount, oldChunkIndexOffset);
214  }
215 }
216 
217 } /* namespace lvr2 */
const BoundingBox< BaseVector< float > > & getBoundingBox() const
float getChunkSize() const
void rehashCache(const BaseVector< std::size_t > &oldChunkAmount, const BaseVector< std::size_t > &oldChunkIndexOffset)
regenerates cache hash grid
void expand(T v)
Expands the bounding box if the given Vector v} is outside the current volume.
BaseVecT getMin() const
Returns the lower left coordinates.
bool isChunkLoaded(std::string layer, size_t hashValue)
indicates if wether or not a chunk is currently loaded in the local cache
std::size_t hashValue(int i, int j, int k) const
Calculates the hash value for the given index triple.
visitor that returns the channel that holds geometic information (like vertices-channel for meshes) ...
ChunkHashGrid(std::string hdf5Path, size_t cacheSize, float chunkSize=10.0f)
class to load chunks from an HDF5 file
BaseVector< std::size_t > m_chunkIndexOffset
A dynamic bounding box class.
Definition: BoundingBox.hpp:49
void setBoundingBox(const BoundingBox< BaseVector< float >> boundingBox)
sets the bounding box in this container and in persistend storage
void setChunkAmountAndOffset(const BaseVector< std::size_t > &chunkAmount, const BaseVector< std::size_t > &chunkIndexOffset)
sets the amount of chunks in x y and z direction in this container and in persistent storage ...
bool loadChunk(std::string layer, int x, int y, int z)
loads a chunk from persistent storage into cache
boost::variant< MeshBufferPtr, PointBufferPtr > val_type
FloatChannel::Optional FloatChannelOptional
Definition: Channel.hpp:88
void setChunkSize(float chunkSize)
sets chunk size in this container and in persistent storage
BaseVecT getMax() const
Returns the upper right coordinates.
BoundingBox< BaseVector< float > > m_boundingBox
std::list< std::pair< std::string, size_t > > m_items
std::unordered_map< std::string, std::unordered_map< size_t, val_type > > m_hashGrid
BaseVector< std::size_t > m_chunkAmount
void expandBoundingBox(const val_type &data)


lvr2
Author(s): Thomas Wiemann , Sebastian Pütz , Alexander Mock , Lars Kiesow , Lukas Kalbertodt , Tristan Igelbrink , Johan M. von Behren , Dominik Feldschnieders , Alexander Löhr
autogenerated on Mon Feb 28 2022 22:46:06