Carna  Version 3.3.2
VolumeGrid.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2010 - 2015 Leonid Kostrykin
3  *
4  * Chair of Medical Engineering (mediTEC)
5  * RWTH Aachen University
6  * Pauwelsstr. 20
7  * 52074 Aachen
8  * Germany
9  *
10  */
11 
12 #ifndef VOLUMEGRID_H_6014714286
13 #define VOLUMEGRID_H_6014714286
14 
23 #include <Carna/Carna.h>
27 
28 namespace Carna
29 {
30 
31 namespace base
32 {
33 
34 
35 
36 // ----------------------------------------------------------------------------------
37 // VolumeGrid< SegmentIntensityVolumeType, SegmentNormalsVolumeType >
38 // ----------------------------------------------------------------------------------
39 
62 template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
64 {
65 
67 
68 public:
69 
73  typedef SegmentIntensityVolumeType SegmentIntensityVolume;
74 
78  typedef SegmentNormalsVolumeType SegmentNormalsVolume;
79 
84 
92 
96  virtual ~VolumeGrid();
97 
100 
105  Segment& segmentAt( const base::math::Vector3ui& location );
106 
109  const Segment& segmentAt( const base::math::Vector3ui& ) const;
110 
113  Segment& segmentAt( unsigned int segmentX, unsigned int segmentY, unsigned int segmentZ );
114 
117  const Segment& segmentAt( unsigned int segmentX, unsigned int segmentY, unsigned int segmentZ ) const;
118 
119  // ------------------------------------------------------------------------------
120  // VolumeGrid< SegmentIntensityVolumeType, SegmentNormalsVolumeType > :: IntensitySelector
121  // ------------------------------------------------------------------------------
122 
127  {
131  typedef typename SegmentIntensityVolumeType::Value VoxelType;
132 
136  static SegmentIntensityVolumeType& volume( Segment& segment );
137 
140  static const SegmentIntensityVolumeType& volume( const Segment& segment );
141  };
142 
143  // ------------------------------------------------------------------------------
144  // VolumeGrid< SegmentIntensityVolumeType, SegmentNormalsVolumeType > :: NormalSelector
145  // ------------------------------------------------------------------------------
146 
151  {
155  typedef typename SegmentNormalsVolumeType::Value VoxelType;
156 
160  static SegmentNormalsVolumeType& volume( Segment& segment );
161 
164  static const SegmentNormalsVolumeType& volume( const Segment& segment );
165  };
166 
167  // ------------------------------------------------------------------------------
168 
173  template< typename Selector >
174  typename Selector::VoxelType getVoxel( const math::Vector3ui& location );
175 
178  template< typename Selector >
179  typename Selector::VoxelType getVoxel( unsigned int x, unsigned int y, unsigned int z );
180 
185  template< typename Selector >
186  void setVoxel( const math::Vector3ui& location, const typename Selector::VoxelType& voxel );
187 
190  template< typename Selector >
191  void setVoxel( unsigned int x, unsigned int y, unsigned int z, const typename Selector::VoxelType& voxel );
192 
193 private:
194 
195  std::vector< Segment* > segments;
196 
197  std::size_t segmentIndex( unsigned int segmentX, unsigned int segmentY, unsigned int segmentZ ) const;
198 
199 }; // VolumeGrid
200 
201 
202 template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
205  , const math::Vector3ui& segmentCounts )
206  : maxSegmentSize( maxSegmentSize )
207  , segmentCounts( segmentCounts )
208 {
209  CARNA_ASSERT( maxSegmentSize.x() > 0 && maxSegmentSize.y() > 0 && maxSegmentSize.z() > 0 );
210  CARNA_ASSERT( segmentCounts.x() > 0 && segmentCounts.y() > 0 && segmentCounts.z() > 0 );
211  segments.resize( segmentCounts.x() * segmentCounts.y() * segmentCounts.z() );
212  for( unsigned int z = 0; z < segmentCounts.z(); ++z )
213  for( unsigned int y = 0; y < segmentCounts.y(); ++y )
214  for( unsigned int x = 0; x < segmentCounts.x(); ++x )
215  {
216  const std::size_t index = segmentIndex( x, y, z );
217  Segment* const segment = new Segment( *this );
218  segment->offset = math::Vector3ui( x * maxSegmentSize.x(), y * maxSegmentSize.y(), z * maxSegmentSize.z() );
219  segments[ index ] = segment;
220  }
221 }
222 
223 
224 template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
226 {
227  std::for_each( segments.begin(), segments.end(), std::default_delete< Segment >() );
228 }
229 
230 
231 template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
233  ( unsigned int segmentX
234  , unsigned int segmentY
235  , unsigned int segmentZ ) const
236 {
237  return segmentX + segmentY * segmentCounts.x() + segmentZ * segmentCounts.x() * segmentCounts.y();
238 }
239 
240 
241 template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
245 {
246  return segmentAt( p.x(), p.y(), p.z() );
247 }
248 
249 
250 template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
253  ( const base::math::Vector3ui& p ) const
254 {
255  return segmentAt( p.x(), p.y(), p.z() );
256 }
257 
258 
259 template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
262  ( unsigned int segmentX
263  , unsigned int segmentY
264  , unsigned int segmentZ )
265 {
266  const std::size_t index = segmentIndex( segmentX, segmentY, segmentZ );
267  Segment& segment = *segments[ index ];
268  return segment;
269 }
270 
271 
272 template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
275  ( unsigned int segmentX
276  , unsigned int segmentY
277  , unsigned int segmentZ ) const
278 {
279  const std::size_t index = segmentIndex( segmentX, segmentY, segmentZ );
280  const Segment& segment = *segments[ index ];
281  return segment;
282 }
283 
284 
285 template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
286 template< typename Selector >
288  ( unsigned int x, unsigned int y, unsigned int z )
289 {
290  const unsigned int segmentX = x / maxSegmentSize.x();
291  const unsigned int segmentY = y / maxSegmentSize.y();
292  const unsigned int segmentZ = z / maxSegmentSize.z();
293 
294  const unsigned int localX = x % maxSegmentSize.x();
295  const unsigned int localY = y % maxSegmentSize.y();
296  const unsigned int localZ = z % maxSegmentSize.z();
297 
298  const Segment& segment = segmentAt( segmentX, segmentY, segmentZ );
299  return Selector::volume( segment )( localX, localY, localZ );
300 }
301 
302 
303 template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
304 template< typename Selector >
306  ( const math::Vector3ui& at )
307 {
308  return getVoxel< Selector >( at.x(), at.y(), at.z() );
309 }
310 
311 
312 template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
313 template< typename Selector >
315  ( unsigned int x, unsigned int y, unsigned int z, const typename Selector::VoxelType& voxel )
316 {
317  const unsigned int segmentX = x / maxSegmentSize.x();
318  const unsigned int segmentY = y / maxSegmentSize.y();
319  const unsigned int segmentZ = z / maxSegmentSize.z();
320 
321  const unsigned int localX = x % maxSegmentSize.x();
322  const unsigned int localY = y % maxSegmentSize.y();
323  const unsigned int localZ = z % maxSegmentSize.z();
324 
325  Segment& segment = segmentAt( segmentX, segmentY, segmentZ );
326  Selector::volume( segment ).setVoxel( localX, localY, localZ, voxel );
327 
328  /* Note that segments are not disjoint,
329  * so we might need to update the redundant texels as well.
330  */
331  const bool updateRedundantX = localX == 0 && segmentX > 0;
332  const bool updateRedundantY = localY == 0 && segmentY > 0;
333  const bool updateRedundantZ = localZ == 0 && segmentZ > 0;
334 
335  if( updateRedundantX )
336  {
337  Selector::volume( segmentAt( segmentX - 1, segmentY, segmentZ ) )
338  .setVoxel( maxSegmentSize.x(), localY, localZ, voxel );
339  }
340  if( updateRedundantY )
341  {
342  Selector::volume( segmentAt( segmentX, segmentY - 1, segmentZ ) )
343  .setVoxel( localX, maxSegmentSize.y(), localZ, voxel );
344  }
345  if( updateRedundantZ )
346  {
347  Selector::volume( segmentAt( segmentX, segmentY, segmentZ - 1 ) )
348  .setVoxel( localX, localY, maxSegmentSize.z(), voxel );
349  }
350 
351  if( updateRedundantX && updateRedundantY )
352  {
353  Selector::volume( segmentAt( segmentX - 1, segmentY - 1, segmentZ ) )
354  .setVoxel( maxSegmentSize.x(), maxSegmentSize.y(), localZ, voxel );
355  }
356  if( updateRedundantX && updateRedundantZ )
357  {
358  Selector::volume( segmentAt( segmentX - 1, segmentY, segmentZ - 1 ) )
359  .setVoxel( maxSegmentSize.x(), localY, maxSegmentSize.z(), voxel );
360  }
361  if( updateRedundantY && updateRedundantZ )
362  {
363  Selector::volume( segmentAt( segmentX, segmentY - 1, segmentZ - 1 ) )
364  .setVoxel( localX, maxSegmentSize.y(), maxSegmentSize.z(), voxel );
365  }
366 
367  if( updateRedundantX && updateRedundantY && updateRedundantZ )
368  {
369  Selector::volume( segmentAt( segmentX - 1, segmentY - 1, segmentZ - 1 ) )
370  .setVoxel( maxSegmentSize, voxel );
371  }
372 }
373 
374 
375 template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
376 template< typename Selector >
378  ( const math::Vector3ui& at, const typename Selector::VoxelType& voxel )
379 {
380  setVoxel< Selector >( at.x(), at.y(), at.z(), voxel );
381 }
382 
383 
384 
385 // ----------------------------------------------------------------------------------
386 // VolumeGrid< SegmentIntensityVolumeType, SegmentNormalsVolumeType > :: IntensitySelector
387 // ----------------------------------------------------------------------------------
388 
389 template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
392 {
393  return segment.intensities();
394 }
395 
396 
397 template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
400 {
401  return segment.intensities();
402 }
403 
404 
405 
406 // ----------------------------------------------------------------------------------
407 // VolumeGrid< SegmentIntensityVolumeType, SegmentNormalsVolumeType > :: NormalSelector
408 // ----------------------------------------------------------------------------------
409 
410 template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
413 {
414  return segment.normals();
415 }
416 
417 
418 template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
421 {
422  return segment.normals();
423 }
424 
425 
426 
427 } // namespace Carna :: base
428 
429 } // namespace Carna
430 
431 #endif // VOLUMEGRID_H_6014714286
static SegmentIntensityVolumeType & volume(Segment &segment)
References the intensity volume of a given partition.
Definition: VolumeGrid.h:391
VolumeGrid(const math::Vector3ui &maxSegmentSize, const math::Vector3ui &segmentCounts)
Instantiates.
Definition: VolumeGrid.h:204
void setVoxel(const math::Vector3ui &location, const typename Selector::VoxelType &voxel)
Writes the voxel of the volume that the Selector selects from the partition at location.
Definition: VolumeGrid.h:378
SegmentNormalsVolumeType::Value VoxelType
Reflects the voxel type of the volume this selector references.
Definition: VolumeGrid.h:155
Eigen::Matrix< unsigned int, 3, 1 > Vector3ui
Defines vector.
Definition: math.h:199
Represents a single volumetric data partition.
Defines Carna::base::IntensityVolume.
const math::Vector3ui maxSegmentSize
Holds the maximum resolution of a single partition.
Definition: VolumeGrid.h:98
Selector::VoxelType getVoxel(const math::Vector3ui &location)
Reads the voxel of the volume that the Selector selects from the partition at location.
Definition: VolumeGrid.h:306
References the intensity volume of a given partition.
Definition: VolumeGrid.h:126
virtual ~VolumeGrid()
Deletes this and all partitions.
Definition: VolumeGrid.h:225
SegmentNormalsVolumeType & normals()
References the normal map of this partition.
Definition: VolumeSegment.h:99
References the normal map of a given partition.
Definition: VolumeGrid.h:150
SegmentIntensityVolumeType::Value VoxelType
Reflects the voxel type of the volume this selector references.
Definition: VolumeGrid.h:131
VolumeSegment< SegmentIntensityVolumeType, SegmentNormalsVolumeType > Segment
Reflects the data type that represents a single partition.
Definition: VolumeGrid.h:83
Segment & segmentAt(const base::math::Vector3ui &location)
References the partition at location.
Definition: VolumeGrid.h:244
SegmentNormalsVolumeType SegmentNormalsVolume
Reflects the type to use for storing the normal map of a single partition.
Definition: VolumeGrid.h:78
math::Vector3ui offset
Holds the coordinate offset this partition within the whole volumetric data partitioning.
Defines Carna::base::VolumeSegment.
const math::Vector3ui segmentCounts
Holds the number of partitions along each dimension.
Definition: VolumeGrid.h:99
SegmentIntensityVolumeType & intensities()
References the intensity volume data of this partition.
static SegmentNormalsVolumeType & volume(Segment &segment)
References the normal map of a given partition.
Definition: VolumeGrid.h:412
Defines Carna::base::CarnaException, Carna::base::AssertionFailure.
SegmentIntensityVolumeType SegmentIntensityVolume
Reflects the type to use for storing the intensity volume of a single partition.
Definition: VolumeGrid.h:73
#define CARNA_ASSERT(expression)
If the given expression is false, a break point is raised in debug mode and an AssertionFailure throw...
#define NON_COPYABLE
Features class it is placed in as non-copyable.
Definition: noncopyable.h:109
Represents a particular partitioning of volumetric data.
Definition: VolumeGrid.h:63