Carna Version 3.3.3
Loading...
Searching...
No Matches
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>
20#include <Carna/base/Geometry.h>
21#include <Carna/base/Log.h>
23#include <Carna/base/text.h>
24#include <map>
25
30namespace Carna
31{
32
33namespace helpers
34{
35
36namespace details
37{
38
43{
44
45
46
47// ----------------------------------------------------------------------------------
48// IntensityTextureFactory< SegmentIntensityVolumeType, SegmentNormalsVolumeType >
49// ----------------------------------------------------------------------------------
50
58template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
60{
64 typedef SegmentIntensityVolumeType SegmentIntensityVolume;
65
69 typedef SegmentNormalsVolumeType SegmentNormalsVolume;
70
77};
78
79
80template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
86
87
88
89// ----------------------------------------------------------------------------------
90// NormalsTextureFactory< SegmentIntensityVolumeType, SegmentNormalsVolumeType >
91// ----------------------------------------------------------------------------------
92
100template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
102{
106 typedef SegmentIntensityVolumeType SegmentIntensityVolume;
107
111 typedef SegmentNormalsVolumeType SegmentNormalsVolume;
112
120};
121
122
123template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
129
130
131
132// ----------------------------------------------------------------------------------
133// TextureManager< TextureFactory >
134// ----------------------------------------------------------------------------------
135
144template< typename TextureFactory >
146{
147
149
150 mutable std::map
151 < const base::VolumeSegment
152 < typename TextureFactory::SegmentIntensityVolume
153 , typename TextureFactory::SegmentNormalsVolume >*
154 , base::ManagedTexture3D* > textures;
155
156public:
157
162
167
168protected:
169
175 ( base::Geometry& geometry
176 , unsigned int role
177 , const base::VolumeSegment
178 < typename TextureFactory::SegmentIntensityVolume
179 , typename TextureFactory::SegmentNormalsVolume >& segment ) const;
180
181private:
182
183 base::ManagedTexture3D& getTexture
184 ( const base::VolumeSegment
185 < typename TextureFactory::SegmentIntensityVolume
186 , typename TextureFactory::SegmentNormalsVolume >& segment ) const;
187
188}; // TextureManager
189
190
191template< typename TextureFactory >
193{
194 releaseGeometryFeatures();
195}
196
197
198template< 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
210template< typename TextureFactory >
212 ( base::Geometry& geometry
213 , unsigned int role
214 , const base::VolumeSegment
215 < typename TextureFactory::SegmentIntensityVolume
216 , typename TextureFactory::SegmentNormalsVolume >& segment ) const
217{
218 base::ManagedTexture3D& texture = getTexture( segment );
219 geometry.putFeature( role, texture );
220}
221
222
223template< typename TextureFactory >
225 ( const base::VolumeSegment
226 < typename TextureFactory::SegmentIntensityVolume
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// IntensityComponent< SegmentIntensityVolumeType, SegmentNormalsVolumeType >
250// ----------------------------------------------------------------------------------
251
259template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
260class IntensityComponent : public TextureManager< IntensityTextureFactory< SegmentIntensityVolumeType, SegmentNormalsVolumeType > >
261{
262
263 unsigned int role;
264
265public:
266
271 const static unsigned int DEFAULT_ROLE_INTENSITIES = 0;
272
279
284 void setIntensitiesRole( unsigned int role );
285
290 unsigned int intensitiesRole() const;
291
292protected:
293
299 void attachTexture
300 ( base::Geometry& geometry
302
308 , const base::math::Vector3ui& size ) const;
309
310}; // IntensityComponent
311
312
313template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
318
319
320template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
325
326
327template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
332
333
334template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
342
343
344template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
347 , const base::math::Vector3ui& size ) const
348{
349 SegmentIntensityVolumeType* const intensities = new SegmentIntensityVolumeType( size );
350 segment.setIntensities( new base::Composition< SegmentIntensityVolumeType >( intensities ) );
351}
352
353
354
355// ----------------------------------------------------------------------------------
356// NormalsComponentBase
357// ----------------------------------------------------------------------------------
358
366class CARNA_LIB NormalsComponentBase
367{
368
369public:
370
375
376protected:
377
382
383}; // NormalsComponentBase
384
385
386
387// ----------------------------------------------------------------------------------
388// NormalsComponent< SegmentIntensityVolumeType, SegmentNormalsVolumeType >
389// ----------------------------------------------------------------------------------
390
398template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
400 : public TextureManager< NormalsTextureFactory< SegmentIntensityVolumeType, SegmentNormalsVolumeType > >
401 , public NormalsComponentBase
402{
403
404 unsigned int role;
406
407public:
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
439protected:
440
445
451 void attachTexture
452 ( base::Geometry& geometry
454
461 , const base::math::Vector3ui& size ) const;
462
463}; // NormalsComponent
464
465
466template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
471
472
473template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
478
479
480template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
485
486
487template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
489{
490 typedef typename base::VolumeGrid< SegmentIntensityVolumeType, SegmentNormalsVolumeType >:: NormalSelector NormalSelector;
492
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 /* Compute the gradient vector.
535 */
536 const Vector3f gradient = base::math::computeFastGradient3f(
537 [this, &coord]( unsigned int dx, unsigned int dy, unsigned int dz )
538 {
539 return grid->template getVoxel< IntensitySelector >( Vector3ui( coord.x() + dx, coord.y() + dy, coord.z() + dz ) );
540 }
541 );
542
543 /* The normal vector points to the *reverse* direction of the gradient, i.e.
544 * away from the steepest ascent.
545 */
546 Vector3f normal = -gradient;
547 if( normal.squaredNorm() > 1e-12 )
548 {
549 normal.normalize();
550 }
551 else
552 {
553 normal = Vector3f( 0, 0, 0 );
554 }
555 grid->template setVoxel< NormalSelector >( coord, normal );
556 }
557
558 /* Log how long it took to compute the normals.
559 */
560 const unsigned int seconds = base::math::round_ui( stopwatch.result() );
562 , "VolumeGridHelper finished normals computation in "
563 + base::text::lexical_cast< std::string >( seconds )
564 + " seconds." );
565}
566
567
568template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
574
575
576template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
584
585
586template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
589 , const base::math::Vector3ui& size ) const
590{
591 SegmentNormalsVolumeType* const normals = new SegmentNormalsVolumeType( size );
592 segment.setNormals( new base::Composition< SegmentNormalsVolumeType >( normals ) );
593}
594
595
596
597// ----------------------------------------------------------------------------------
598// NormalsComponent< SegmentIntensityVolumeType, void >
599// ----------------------------------------------------------------------------------
600
607template< typename SegmentIntensityVolumeType >
608class NormalsComponent< SegmentIntensityVolumeType, void > : public NormalsComponentBase
609{
610
611public:
612
617
618protected:
619
623 void computeNormals();
624
629
633 void attachTexture
634 ( base::Geometry& geometry
636
642 , const base::math::Vector3ui& size ) const;
643
644}; // NormalsComponent
645
646
647template< typename SegmentIntensityVolumeType >
651
652
653template< typename SegmentIntensityVolumeType >
657
658
659template< typename SegmentIntensityVolumeType >
664
665
666template< typename SegmentIntensityVolumeType >
672
673
674template< typename SegmentIntensityVolumeType >
680
681
682
683// ----------------------------------------------------------------------------------
684// Partionining
685// ----------------------------------------------------------------------------------
686
694{
702 Partionining( std::size_t nativeSize, std::size_t regularPartitionSize )
705 , tailSize( base::math::makeEven( nativeSize % regularPartitionSize, +1 ) )
706 {
707 CARNA_ASSERT_EX( regularPartitionSize % 2 == 1, "Effective regular partition size must be odd!" );
708 }
709
714
720
724 std::size_t tailSize;
725
729 std::size_t totalSize() const
730 {
732 }
733
737 std::size_t partitionsCount() const
738 {
739 return regularPartitionsCount + ( tailSize > 0 ? 1 : 0 );
740 }
741};
742
743
744
745} // namespace VolumeGridHelper
746
747} // namespace details
748
749} // namespace Carna :: helpers
750
751} // namespace Carna
752
753#endif // VOLUMEGRIDHELPERDETAILS_H_6014714286
Defines Carna::base::BufferedNormalMap3D.
Defines Carna::base::BufferedVectorFieldTexture.
#define CARNA_ASSERT_EX(expression, description)
If the given expression is false, a break point is raised in debug mode and an AssertionFailure throw...
Defines Carna::base::Geometry.
Defines Carna::base::Log.
Defines Carna::base::Stopwatch.
Defines Carna::base::VolumeGrid.
Defines Carna::base::VolumeSegment.
Represents an association.
Definition Association.h:45
static BufferedVectorFieldTexture< BufferedVectorFieldType > & create(const BufferedVectorFieldType &field)
Instantiates. Invoke release when it isn't needed any longer.
void release()
Denotes that this object is no longer required and may be deleted as soon as it is valid to delete it...
Defines scene graph leafs. Instances of this class represent visible geometry that can be rendered....
Definition Geometry.h:60
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 ...
@ verbose
Indicates statistics and suchlike.
Definition Log.h:89
Represents 3D OpenGL texture object whose lifetime is managed by instances of this class.
static Log & instance()
Returns the only instance from class InstanceType.
Definition Singleton.h:109
Implements stopwatch using the robust wallclock time from OMP that most compilers support.
Definition Stopwatch.h:41
double result() const
Tells result in seconds from current time measurement.
Represents a single volumetric data partition.
Computes the partitioning of volumetric data and the corresponding normal map. Also creates scene nod...
Defines the helpers::VolumeGridHelper component that maintains intensity volume data.
static const unsigned int DEFAULT_ROLE_INTENSITIES
Holds the default role to use for attaching textures to base::Geometry nodes.
void setIntensitiesRole(unsigned int role)
Sets the role to use for attaching textures to base::Geometry nodes.
unsigned int intensitiesRole() const
Tels the role used for attaching textures to base::Geometry nodes.
void attachTexture(base::Geometry &geometry, const base::VolumeSegment< SegmentIntensityVolumeType, SegmentNormalsVolumeType > &segment) const
Attaches the texture that represents the base::VolumeSegment::intensities of segment to geometry usin...
IntensityComponent()
Sets the role to use for attaching textures to base::Geometry nodes to DEFAULT_ROLE_INTENSITIES.
void initializeSegment(base::VolumeSegment< SegmentIntensityVolumeType, SegmentNormalsVolumeType > &segment, const base::math::Vector3ui &size) const
Initializes intensity volume of segment.
Defines the NormalsComponent base class that is independent of type arguments.
virtual base::math::Vector3ui gridResolution() const =0
Tells the effective grid resolution.
Defines the helpers::VolumeGridHelper component that computes and maintains normal maps.
void attachTexture(base::Geometry &geometry, const base::VolumeSegment< SegmentIntensityVolumeType, SegmentNormalsVolumeType > &segment) const
Attaches the texture that represents the base::VolumeSegmentNormalsComponent::normals of segment to g...
void setNormalsRole(unsigned int role)
Sets the role to use for attaching textures to base::Geometry nodes.
void computeNormals()
Computes the normal map on the previously set grid.
unsigned int normalsRole() const
Tels the role used for attaching textures to base::Geometry nodes.
NormalsComponent()
Sets the role to use for attaching textures to base::Geometry nodes to DEFAULT_ROLE_NORMALS.
void setGrid(base::VolumeGrid< SegmentIntensityVolumeType, SegmentNormalsVolumeType > &grid)
Sets the grid that computeNormals operates on.
static const unsigned int DEFAULT_ROLE_NORMALS
Holds the default role to use for attaching textures to base::Geometry nodes.
void initializeSegment(base::VolumeSegment< SegmentIntensityVolumeType, SegmentNormalsVolumeType > &segment, const base::math::Vector3ui &size) const
Initializes normal map of segment.
Provides mapping base::VolumeSegment to base::ManagedTexture3D objects in a caching manner....
void attachTexture(base::Geometry &geometry, unsigned int role, const base::VolumeSegment< typename TextureFactory::SegmentIntensityVolume, typename TextureFactory::SegmentNormalsVolume > &segment) const
Attaches the texture that TextureFactory creates from segment to geometry using role.
virtual ~TextureManager()
Releases all textures and deletes.
#define CARNA_FOR_VECTOR3UI_EX(vecName, vecLimit, vecStart)
Loops vecName over all where is vecLimit and is vecStart.
Definition math.h:733
Eigen::Matrix< float, 3, 1 > Vector3f
Defines vector.
Definition math.h:196
base::math::Vector3f computeFastGradient3f(Sampler func)
Computes fast approximation of the gradient at the origin of the scalar field func.
Definition math.h:580
Eigen::Matrix< unsigned int, 3, 1 > Vector3ui
Defines vector.
Definition math.h:199
Eigen::Matrix< signed int, 3, 1 > Vector3i
Defines vector.
Definition math.h:198
unsigned int round_ui(ScalarType x)
Rounds x to the closest . Either the data type of must be unsigned or .
Definition math.h:597
#define NON_COPYABLE
Features class it is placed in as non-copyable.
References the intensity volume of a given partition.
Definition VolumeGrid.h:127
Creates textures that represents base::VolumeSegment::intensities in video memory.
static base::ManagedTexture3D & createTexture(const base::VolumeSegment< SegmentIntensityVolumeType, SegmentNormalsVolumeType > &segment)
Creates texture that represents the base::VolumeSegment::intensities of segment in video memory.
SegmentNormalsVolumeType SegmentNormalsVolume
Reflects the type to use for storing the normal map of a single partition.
SegmentIntensityVolumeType SegmentIntensityVolume
Reflects the type to use for storing the intensity volume of a single partition.
Creates textures that represents base::VolumeSegmentNormalsComponent::normals in video memory.
SegmentNormalsVolumeType SegmentNormalsVolume
Reflects the type to use for storing the normal map of a single partition.
static base::ManagedTexture3D & createTexture(const base::VolumeSegment< SegmentIntensityVolumeType, SegmentNormalsVolumeType > &segment)
Creates texture that represents the base::VolumeSegmentNormalsComponent::normals of segment in video ...
SegmentIntensityVolumeType SegmentIntensityVolume
Reflects the type to use for storing the intensity volume of a single partition.
Computes the partitioning that VolumeGridHelper uses along one dimension.
std::size_t partitionsCount() const
Tells the total partitions number.
Partionining(std::size_t nativeSize, std::size_t regularPartitionSize)
Computes the partitioning.
std::size_t tailSize
Holds the resolution of the last partition that may also be 0.
std::size_t regularPartitionsCount
Holds the number of regular partitions, i.e. such of the size held by regularPartitionSize.
std::size_t totalSize() const
Computes the effective total resolution.
std::size_t regularPartitionSize
Holds the always odd, effective resolution of a single regular partition.
Defines Carna::base::text.