Carna  Version 3.0.1
VolumeGridHelperDetails.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 VOLUMEGRIDHELPERDETAILS_H_6014714286
13 #define VOLUMEGRIDHELPERDETAILS_H_6014714286
14 
15 #include <Carna/Carna.h>
16 #include <Carna/base/VolumeGrid.h>
20 #include <Carna/base/Geometry.h>
21 #include <Carna/base/Log.h>
22 #include <Carna/base/Stopwatch.h>
23 #include <Carna/base/text.h>
24 #include <map>
25 
30 namespace Carna
31 {
32 
33 namespace helpers
34 {
35 
36 namespace details
37 {
38 
43 {
44 
45 
46 
47 // ----------------------------------------------------------------------------------
48 // HUTextureFactory< SegmentHUVolumeType, SegmentNormalsVolumeType >
49 // ----------------------------------------------------------------------------------
50 
58 template< typename SegmentHUVolumeType, typename SegmentNormalsVolumeType >
60 {
64  typedef SegmentHUVolumeType SegmentHUVolume;
65 
69  typedef SegmentNormalsVolumeType SegmentNormalsVolume;
70 
77 };
78 
79 
80 template< typename SegmentHUVolumeType, typename SegmentNormalsVolumeType >
83 {
85 }
86 
87 
88 
89 // ----------------------------------------------------------------------------------
90 // NormalsTextureFactory< SegmentHUVolumeType, SegmentNormalsVolumeType >
91 // ----------------------------------------------------------------------------------
92 
100 template< typename SegmentHUVolumeType, typename SegmentNormalsVolumeType >
102 {
106  typedef SegmentHUVolumeType SegmentHUVolume;
107 
111  typedef SegmentNormalsVolumeType SegmentNormalsVolume;
112 
120 };
121 
122 
123 template< typename SegmentHUVolumeType, typename SegmentNormalsVolumeType >
126 {
128 }
129 
130 
131 
132 // ----------------------------------------------------------------------------------
133 // TextureManager< TextureFactory >
134 // ----------------------------------------------------------------------------------
135 
144 template< typename TextureFactory >
146 {
147 
149 
150  mutable std::map
151  < const base::VolumeSegment
152  < typename TextureFactory::SegmentHUVolume
153  , typename TextureFactory::SegmentNormalsVolume >*
154  , base::ManagedTexture3D* > textures;
155 
156 public:
157 
161  virtual ~TextureManager();
162 
167 
168 protected:
169 
174  void attachTexture
175  ( base::Geometry& geometry
176  , unsigned int role
177  , const base::VolumeSegment
178  < typename TextureFactory::SegmentHUVolume
179  , typename TextureFactory::SegmentNormalsVolume >& segment ) const;
180 
181 private:
182 
183  base::ManagedTexture3D& getTexture
184  ( const base::VolumeSegment
185  < typename TextureFactory::SegmentHUVolume
186  , typename TextureFactory::SegmentNormalsVolume >& segment ) const;
187 
188 }; // TextureManager
189 
190 
191 template< typename TextureFactory >
193 {
194  releaseGeometryFeatures();
195 }
196 
197 
198 template< typename TextureFactory >
200 {
201  for( auto itr = textures.begin(); itr != textures.end(); ++itr )
202  {
203  base::ManagedTexture3D& texture = *itr->second;
204  texture.release();
205  }
206  textures.clear();
207 }
208 
209 
210 template< typename TextureFactory >
212  ( base::Geometry& geometry
213  , unsigned int role
214  , const base::VolumeSegment
215  < typename TextureFactory::SegmentHUVolume
216  , typename TextureFactory::SegmentNormalsVolume >& segment ) const
217 {
218  base::ManagedTexture3D& texture = getTexture( segment );
219  geometry.putFeature( role, texture );
220 }
221 
222 
223 template< typename TextureFactory >
225  ( const base::VolumeSegment
226  < typename TextureFactory::SegmentHUVolume
227  , typename TextureFactory::SegmentNormalsVolume >& segment ) const
228 {
229  auto textureItr = textures.find( &segment );
230  if( textureItr == textures.end() )
231  {
232  /* Create the texture.
233  */
234  base::ManagedTexture3D& texture = TextureFactory::createTexture( segment );
235  textures[ &segment ] = &texture;
236  return texture;
237  }
238  else
239  {
240  /* Use previously created texture.
241  */
242  return *textureItr->second;
243  }
244 }
245 
246 
247 
248 // ----------------------------------------------------------------------------------
249 // HUComponent< SegmentHUVolumeType, SegmentNormalsVolumeType >
250 // ----------------------------------------------------------------------------------
251 
259 template< typename SegmentHUVolumeType, typename SegmentNormalsVolumeType >
260 class HUComponent : public TextureManager< HUTextureFactory< SegmentHUVolumeType, SegmentNormalsVolumeType > >
261 {
262 
263  unsigned int role;
264 
265 public:
266 
271  const static unsigned int DEFAULT_ROLE_HU_VOLUME = 0;
272 
278  HUComponent();
279 
284  void setHUVolumeRole( unsigned int role );
285 
290  unsigned int huVolumeRole() const;
291 
292 protected:
293 
299  void attachTexture
300  ( base::Geometry& geometry
302 
306  void initializeSegment
308  , const base::math::Vector3ui& size ) const;
309 
310 }; // HUComponent
311 
312 
313 template< typename SegmentHUVolumeType, typename SegmentNormalsVolumeType >
315  : role( DEFAULT_ROLE_HU_VOLUME )
316 {
317 }
318 
319 
320 template< typename SegmentHUVolumeType, typename SegmentNormalsVolumeType >
322 {
323  this->role = role;
324 }
325 
326 
327 template< typename SegmentHUVolumeType, typename SegmentNormalsVolumeType >
329 {
330  return role;
331 }
332 
333 
334 template< typename SegmentHUVolumeType, typename SegmentNormalsVolumeType >
336  ( base::Geometry& geometry
338 {
340  ::attachTexture( geometry, role, segment );
341 }
342 
343 
344 template< typename SegmentHUVolumeType, typename SegmentNormalsVolumeType >
347  , const base::math::Vector3ui& size ) const
348 {
349  SegmentHUVolumeType* const huVolume = new SegmentHUVolumeType( size );
350  segment.setHUVolume( new base::Composition< SegmentHUVolumeType >( huVolume ) );
351 }
352 
353 
354 
355 // ----------------------------------------------------------------------------------
356 // NormalsComponentBase
357 // ----------------------------------------------------------------------------------
358 
366 class CARNA_LIB NormalsComponentBase
367 {
368 
369 public:
370 
374  virtual ~NormalsComponentBase();
375 
376 protected:
377 
381  virtual base::math::Vector3ui gridResolution() const = 0;
382 
383 }; // NormalsComponentBase
384 
385 
386 
387 // ----------------------------------------------------------------------------------
388 // NormalsComponent< SegmentHUVolumeType, SegmentNormalsVolumeType >
389 // ----------------------------------------------------------------------------------
390 
398 template< typename SegmentHUVolumeType, typename SegmentNormalsVolumeType >
400  : public TextureManager< NormalsTextureFactory< SegmentHUVolumeType, SegmentNormalsVolumeType > >
401  , public NormalsComponentBase
402 {
403 
404  unsigned int role;
406 
407 public:
408 
413  const static unsigned int DEFAULT_ROLE_NORMALS = 1;
414 
421 
426  void setNormalsRole( unsigned int role );
427 
432  unsigned int normalsRole() const;
433 
437  void computeNormals();
438 
439 protected:
440 
445 
451  void attachTexture
452  ( base::Geometry& geometry
454 
459  void initializeSegment
461  , const base::math::Vector3ui& size ) const;
462 
463 }; // NormalsComponent
464 
465 
466 template< typename SegmentHUVolumeType, typename SegmentNormalsVolumeType >
468  : role( DEFAULT_ROLE_NORMALS )
469 {
470 }
471 
472 
473 template< typename SegmentHUVolumeType, typename SegmentNormalsVolumeType >
475 {
476  this->role = role;
477 }
478 
479 
480 template< typename SegmentHUVolumeType, typename SegmentNormalsVolumeType >
482 {
483  return role;
484 }
485 
486 
487 template< typename SegmentHUVolumeType, typename SegmentNormalsVolumeType >
489 {
491  typedef typename base::VolumeGrid< SegmentHUVolumeType, SegmentNormalsVolumeType >:: HUVSelector HUVSelector;
492 
493  using base::math::Vector3ui;
494  using base::math::Vector3i;
495  using base::math::Vector3f;
496 
497  const base::Stopwatch stopwatch;
498  const Vector3ui resolution = gridResolution();
499 
500  /* Lets start with the normals for the edge faces of the volume, that do require
501  * an ad-hoc processing.
502  */
503  for( unsigned int dim0 = 0; dim0 < 3; ++dim0 )
504  {
505  for( signed int sign = -1; sign <= +1; sign += 2 )
506  {
507  /* Construct the normal vector along dimension 'dim0' signed with 'sign'.
508  */
509  Vector3f normal( 0, 0, 0 );
510  normal( dim0 ) = sign;
511 
512  /* Write the normal vector to the whole face.
513  */
514  const unsigned int dim1 = ( dim0 + 1 ) % 3;
515  const unsigned int dim2 = ( dim0 + 2 ) % 3;
516 
517  Vector3ui coord;
518  coord( dim0 ) = sign < 0 ? 0 : resolution( dim0 ) - 1;
519 
520  for( coord( dim1 ) = 0; coord( dim1 ) < resolution( dim1 ); ++coord( dim1 ) )
521  for( coord( dim2 ) = 0; coord( dim2 ) < resolution( dim2 ); ++coord( dim2 ) )
522  {
523  grid->template setVoxel< NormalSelector >( coord, normal );
524  }
525  }
526  }
527 
528  /* Now we can process all the inner voxels regularly.
529  */
530  const Vector3ui coordLowerBound = Vector3ui( 1, 1, 1 );
531  const Vector3ui coordUpperBound = ( resolution.cast< int >() - Vector3i( 1, 1, 1 ) ).cast< unsigned int >();
532  CARNA_FOR_VECTOR3UI_EX( coord, coordUpperBound, coordLowerBound )
533  {
534  /* Sample the neighboring voxels.
535  */
536  const base::HUV huv_0yz = grid->template getVoxel< HUVSelector >( Vector3ui( coord.x() - 1, coord.y(), coord.z() ) );
537  const base::HUV huv_1yz = grid->template getVoxel< HUVSelector >( Vector3ui( coord.x() + 1, coord.y(), coord.z() ) );
538  const base::HUV huv_x0z = grid->template getVoxel< HUVSelector >( Vector3ui( coord.x(), coord.y() - 1, coord.z() ) );
539  const base::HUV huv_x1z = grid->template getVoxel< HUVSelector >( Vector3ui( coord.x(), coord.y() + 1, coord.z() ) );
540  const base::HUV huv_xy0 = grid->template getVoxel< HUVSelector >( Vector3ui( coord.x(), coord.y(), coord.z() - 1 ) );
541  const base::HUV huv_xy1 = grid->template getVoxel< HUVSelector >( Vector3ui( coord.x(), coord.y(), coord.z() + 1 ) );
542 
543  /* Compute the normal vector and write the result. Note that the normal
544  * vector points to the *inverse* direction of the gradient, i.e. away from
545  * the steepest ascent.
546  */
547  Vector3f normal = Vector3f( huv_0yz - huv_1yz, huv_x0z - huv_x1z, huv_xy0 - huv_xy1 ) / 2;
548  if( !base::math::isEqual< float >( normal.squaredNorm(), 0 ) )
549  {
550  normal.normalize();
551  }
552  else
553  {
554  normal = Vector3f( 0, 0, 0 );
555  }
556  grid->template setVoxel< NormalSelector >( coord, normal );
557  }
558 
559  /* Log how long it took to compute the normals.
560  */
561  const unsigned int seconds = base::math::round_ui( stopwatch.result() );
563  , "VolumeGridHelper finished normals computation in "
564  + base::text::lexical_cast< std::string >( seconds )
565  + " seconds." );
566 }
567 
568 
569 template< typename SegmentHUVolumeType, typename SegmentNormalsVolumeType >
572 {
573  this->grid = &grid;
574 }
575 
576 
577 template< typename SegmentHUVolumeType, typename SegmentNormalsVolumeType >
579  ( base::Geometry& geometry
581 {
583  ::attachTexture( geometry, role, segment );
584 }
585 
586 
587 template< typename SegmentHUVolumeType, typename SegmentNormalsVolumeType >
590  , const base::math::Vector3ui& size ) const
591 {
592  SegmentNormalsVolumeType* const normals = new SegmentNormalsVolumeType( size );
594 }
595 
596 
597 
598 // ----------------------------------------------------------------------------------
599 // NormalsComponent< SegmentHUVolumeType, void >
600 // ----------------------------------------------------------------------------------
601 
608 template< typename SegmentHUVolumeType >
609 class NormalsComponent< SegmentHUVolumeType, void > : public NormalsComponentBase
610 {
611 
612 public:
613 
618 
619 protected:
620 
624  void computeNormals();
625 
630 
634  void attachTexture
635  ( base::Geometry& geometry
636  , const base::VolumeSegment< SegmentHUVolumeType, void >& segment ) const;
637 
641  void initializeSegment
643  , const base::math::Vector3ui& size ) const;
644 
645 }; // NormalsComponent
646 
647 
648 template< typename SegmentHUVolumeType >
650 {
651 }
652 
653 
654 template< typename SegmentHUVolumeType >
656 {
657 }
658 
659 
660 template< typename SegmentHUVolumeType >
663 {
664 }
665 
666 
667 template< typename SegmentHUVolumeType >
669  ( base::Geometry& geometry
670  , const base::VolumeSegment< SegmentHUVolumeType, void >& segment ) const
671 {
672 }
673 
674 
675 template< typename SegmentHUVolumeType >
678  , const base::math::Vector3ui& size ) const
679 {
680 }
681 
682 
683 
684 // ----------------------------------------------------------------------------------
685 // Partionining
686 // ----------------------------------------------------------------------------------
687 
695 {
703  Partionining( std::size_t nativeSize, std::size_t regularPartitionSize )
704  : regularPartitionSize( regularPartitionSize )
705  , regularPartitionsCount( nativeSize / regularPartitionSize )
706  , tailSize( base::math::makeEven( nativeSize % regularPartitionSize, +1 ) )
707  {
708  CARNA_ASSERT_EX( regularPartitionSize % 2 == 1, "Effective regular partition size must be odd!" );
709  }
710 
714  std::size_t regularPartitionSize;
715 
721 
725  std::size_t tailSize;
726 
730  std::size_t totalSize() const
731  {
732  return tailSize + regularPartitionsCount * regularPartitionSize;
733  }
734 
738  std::size_t partitionsCount() const
739  {
740  return regularPartitionsCount + ( tailSize > 0 ? 1 : 0 );
741  }
742 };
743 
744 
745 
746 } // namespace VolumeGridHelper
747 
748 } // namespace details
749 
750 } // namespace Carna :: helpers
751 
752 } // namespace Carna
753 
754 #endif // VOLUMEGRIDHELPERDETAILS_H_6014714286
unsigned int huVolumeRole() const
Tels the role used for attaching textures to base::Geometry nodes.
void setGrid(base::VolumeGrid< SegmentHUVolumeType, SegmentNormalsVolumeType > &grid)
Sets the grid that computeNormals operates on.
unsigned int round_ui(ScalarType x)
Rounds x to the closest . Either the data type of must be unsigned or .
Definition: math.h:578
static base::ManagedTexture3D & createTexture(const base::VolumeSegment< SegmentHUVolumeType, SegmentNormalsVolumeType > &segment)
Creates texture that represents the base::VolumeSegment::huVolume of segment in video memory...
void attachTexture(base::Geometry &geometry, unsigned int role, const base::VolumeSegment< typename TextureFactory::SegmentHUVolume, typename TextureFactory::SegmentNormalsVolume > &segment) const
Attaches the texture that TextureFactory creates from segment to geometry using role.
void putFeature(unsigned int role, GeometryFeature &feature)
Adds the feature to this geometry node using role in . The concept of geometry features and roles is ...
ScalarType makeEven(ScalarType x, int s)
Returns if is even and if is odd, where . The data type of must be integral. ...
Definition: math.h:606
SegmentNormalsVolumeType SegmentNormalsVolume
Reflects the type to use for storing the normal map of a single partition.
double result() const
Tells result in seconds from current time measurement.
Defines Carna::base::BufferedVectorFieldTexture.
std::size_t totalSize() const
Computes the effective total resolution.
static const unsigned int DEFAULT_ROLE_NORMALS
Holds the default role to use for attaching textures to base::Geometry nodes.
Defines scene graph leafs. Instances of this class represent visible geometry that can be rendered...
Definition: Geometry.h:59
Defines Carna::base::BufferedNormalMap3D.
void setNormals(Association< SegmentNormalsVolumeType > *volume)
Sets the normal map of this partition.
Definition: VolumeSegment.h:92
Indicates statistics and suchlike.
Definition: Log.h:89
Defines Carna::base::text.
Provides mapping base::VolumeSegment to base::ManagedTexture3D objects in a caching manner...
void initializeSegment(base::VolumeSegment< SegmentHUVolumeType, SegmentNormalsVolumeType > &segment, const base::math::Vector3ui &size) const
Initializes HU volume of segment.
#define CARNA_ASSERT_EX(expression, description)
If the given expression is false, a break point is raised in debug mode and an AssertionFailure throw...
std::size_t partitionsCount() const
Tells the total partitions number.
Implements stopwatch using the robust wallclock time from OMP that most compilers support...
Definition: Stopwatch.h:40
Eigen::Matrix< unsigned int, 3, 1 > Vector3ui
Defines vector.
Definition: math.h:199
Represents a single volumetric data partition.
static BufferedVectorFieldTexture< BufferedVectorFieldType > & create(const BufferedVectorFieldType &field)
Instantiates. Invoke release when it isn't needed any longer.
Creates textures that represents base::VolumeSegmentNormalsComponent::normals in video memory...
void attachTexture(base::Geometry &geometry, const base::VolumeSegment< SegmentHUVolumeType, SegmentNormalsVolumeType > &segment) const
Attaches the texture that represents the base::VolumeSegment::huVolume of segment to geometry using t...
void computeNormals()
Computes the normal map on the previously set grid.
void record(Severity severity, const std::string &entry) const
Instructs current writer to write entry with severity.
Represents 3D OpenGL texture object whose lifetime is managed by instances of this class...
Defines Carna::base::Log.
NormalsComponent()
Sets the role to use for attaching textures to base::Geometry nodes to DEFAULT_ROLE_NORMALS.
SegmentHUVolumeType & huVolume()
References the HU volume data of this partition.
HUComponent()
Sets the role to use for attaching textures to base::Geometry nodes to DEFAULT_ROLE_HU_VOLUME.
Eigen::Matrix< float, 3, 1 > Vector3f
Defines vector.
Definition: math.h:196
SegmentNormalsVolumeType & normals()
References the normal map of this partition.
Definition: VolumeSegment.h:99
Defines the NormalsComponent base class that is independent of type arguments.
SegmentHUVolumeType SegmentHUVolume
Reflects the type to use for storing the HU volume of a single partition.
static const unsigned int DEFAULT_ROLE_HU_VOLUME
Holds the default role to use for attaching textures to base::Geometry nodes.
References the normal map of a given partition.
Definition: VolumeGrid.h:150
Defines Carna::base::VolumeGrid.
static Log & instance()
Returns the only instance from class InstanceType.
Definition: Singleton.h:109
static base::ManagedTexture3D & createTexture(const base::VolumeSegment< SegmentHUVolumeType, SegmentNormalsVolumeType > &segment)
Creates texture that represents the base::VolumeSegmentNormalsComponent::normals of segment in video ...
SegmentHUVolumeType SegmentHUVolume
Reflects the type to use for storing the HU volume of a single partition.
Creates textures that represents base::VolumeSegment::huVolume in video memory.
#define CARNA_FOR_VECTOR3UI_EX(vecName, vecLimit, vecStart)
Loops vecName over all where is vecLimit and is vecStart.
Definition: math.h:714
void setHUVolumeRole(unsigned int role)
Sets the role to use for attaching textures to base::Geometry nodes.
unsigned int normalsRole() const
Tels the role used for attaching textures to base::Geometry nodes.
Defines the helpers::VolumeGridHelper component that maintains HU volume data.
void release()
Denotes that this object is no longer required and may be deleted as soon as it is valid to delete it...
std::size_t tailSize
Holds the resolution of the last partition that may also be 0.
Defines the helpers::VolumeGridHelper component that computes and maintains normal maps...
Defines Carna::base::VolumeSegment.
Defines Carna::base::Stopwatch.
void initializeSegment(base::VolumeSegment< SegmentHUVolumeType, SegmentNormalsVolumeType > &segment, const base::math::Vector3ui &size) const
Initializes normal map of segment.
void attachTexture(base::Geometry &geometry, const base::VolumeSegment< SegmentHUVolumeType, SegmentNormalsVolumeType > &segment) const
Attaches the texture that represents the base::VolumeSegmentNormalsComponent::normals of segment to g...
virtual ~TextureManager()
Releases all textures and deletes.
Computes the partitioning of volumetric data and the corresponding normal map. Also creates scene nod...
Definition: Carna.h:199
signed short HUV
Represents values in .
Definition: Carna.h:56
Represents a composition, i.e. a strong reference. This basically is a std::unique_ptr that supports ...
Definition: Composition.h:52
void setNormalsRole(unsigned int role)
Sets the role to use for attaching textures to base::Geometry nodes.
std::size_t regularPartitionsCount
Holds the number of regular partitions, i.e. such of the size held by regularPartitionSize.
SegmentNormalsVolumeType SegmentNormalsVolume
Reflects the type to use for storing the normal map of a single partition.
Computes the partitioning that VolumeGridHelper uses along one dimension.
#define NON_COPYABLE
Features class it is placed in as non-copyable.
Definition: noncopyable.h:109
Partionining(std::size_t nativeSize, std::size_t regularPartitionSize)
Computes the partitioning.
void setHUVolume(Association< SegmentHUVolumeType > *huVolume)
Sets the HU volume data of this partition.
std::size_t regularPartitionSize
Holds the always odd, effective resolution of a single regular partition.
Defines Carna::base::Geometry.
Represents a particular partitioning of volumetric data.
Definition: VolumeGrid.h:63
Eigen::Matrix< signed int, 3, 1 > Vector3i
Defines vector.
Definition: math.h:198