LibCarna Version 3.4.0
Loading...
Searching...
No Matches
VolumeGridHelperDetails.hpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2010 - 2016 Leonid Kostrykin
3 *
4 * Chair of Medical Engineering (mediTEC)
5 * RWTH Aachen University
6 * Pauwelsstr. 20
7 * 52074 Aachen
8 * Germany
9 *
10 *
11 * Copyright (C) 2021 - 2025 Leonid Kostrykin
12 *
13 */
14
15#ifndef VOLUMEGRIDHELPERDETAILS_H_6014714286
16#define VOLUMEGRIDHELPERDETAILS_H_6014714286
17
18#include <LibCarna/LibCarna.hpp>
24#include <LibCarna/base/Log.hpp>
27#include <map>
28
34namespace LibCarna
35{
36
37namespace helpers
38{
39
40namespace details
41{
42
47{
48
49
50
51// ----------------------------------------------------------------------------------
52// IntensityTextureFactory< SegmentIntensityVolumeType, SegmentNormalsVolumeType >
53// ----------------------------------------------------------------------------------
54
61template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
63{
67 typedef SegmentIntensityVolumeType SegmentIntensityVolume;
68
72 typedef SegmentNormalsVolumeType SegmentNormalsVolume;
73
80};
81
82
83template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
89
90
91
92// ----------------------------------------------------------------------------------
93// NormalsTextureFactory< SegmentIntensityVolumeType, SegmentNormalsVolumeType >
94// ----------------------------------------------------------------------------------
95
102template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
104{
108 typedef SegmentIntensityVolumeType SegmentIntensityVolume;
109
113 typedef SegmentNormalsVolumeType SegmentNormalsVolume;
114
122};
123
124
125template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
131
132
133
134// ----------------------------------------------------------------------------------
135// TextureManager< TextureFactory >
136// ----------------------------------------------------------------------------------
137
145template< typename TextureFactory >
147{
148
150
151 mutable std::map
152 < const base::VolumeSegment
153 < typename TextureFactory::SegmentIntensityVolume
154 , typename TextureFactory::SegmentNormalsVolume >*
155 , base::ManagedTexture3D* > textures;
156
157public:
158
163
168
169protected:
170
176 ( base::Geometry& geometry
177 , unsigned int role
178 , const base::VolumeSegment
179 < typename TextureFactory::SegmentIntensityVolume
180 , typename TextureFactory::SegmentNormalsVolume >& segment ) const;
181
182private:
183
184 base::ManagedTexture3D& getTexture
185 ( const base::VolumeSegment
186 < typename TextureFactory::SegmentIntensityVolume
187 , typename TextureFactory::SegmentNormalsVolume >& segment ) const;
188
189}; // TextureManager
190
191
192template< typename TextureFactory >
194{
195 releaseGeometryFeatures();
196}
197
198
199template< typename TextureFactory >
201{
202 for( auto itr = textures.begin(); itr != textures.end(); ++itr )
203 {
204 base::ManagedTexture3D& texture = *itr->second;
205 texture.release();
206 }
207 textures.clear();
208}
209
210
211template< typename TextureFactory >
213 ( base::Geometry& geometry
214 , unsigned int role
215 , const base::VolumeSegment
216 < typename TextureFactory::SegmentIntensityVolume
217 , typename TextureFactory::SegmentNormalsVolume >& segment ) const
218{
219 base::ManagedTexture3D& texture = getTexture( segment );
220 geometry.putFeature( role, texture );
221}
222
223
224template< typename TextureFactory >
226 ( const base::VolumeSegment
227 < typename TextureFactory::SegmentIntensityVolume
228 , typename TextureFactory::SegmentNormalsVolume >& segment ) const
229{
230 auto textureItr = textures.find( &segment );
231 if( textureItr == textures.end() )
232 {
233 /* Create the texture.
234 */
235 base::ManagedTexture3D& texture = TextureFactory::createTexture( segment );
236 textures[ &segment ] = &texture;
237 return texture;
238 }
239 else
240 {
241 /* Use previously created texture.
242 */
243 return *textureItr->second;
244 }
245}
246
247
248
249// ----------------------------------------------------------------------------------
250// IntensityComponent< SegmentIntensityVolumeType, SegmentNormalsVolumeType >
251// ----------------------------------------------------------------------------------
252
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
366{
367
368public:
369
374
375protected:
376
381
382}; // NormalsComponentBase
383
384
385
386// ----------------------------------------------------------------------------------
387// NormalsComponent< SegmentIntensityVolumeType, SegmentNormalsVolumeType >
388// ----------------------------------------------------------------------------------
389
396template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
398 : public TextureManager< NormalsTextureFactory< SegmentIntensityVolumeType, SegmentNormalsVolumeType > >
399 , public NormalsComponentBase
400{
401
402 unsigned int role;
404
405public:
406
411 const static unsigned int DEFAULT_ROLE_NORMALS = 1;
412
419
424 void setNormalsRole( unsigned int role );
425
430 unsigned int normalsRole() const;
431
435 void computeNormals();
436
437protected:
438
443
449 void attachTexture
450 ( base::Geometry& geometry
452
459 , const base::math::Vector3ui& size ) const;
460
461}; // NormalsComponent
462
463
464template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
469
470
471template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
476
477
478template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
483
484
485template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
487{
488 typedef typename base::VolumeGrid< SegmentIntensityVolumeType, SegmentNormalsVolumeType >:: NormalSelector NormalSelector;
490
494
495 const base::Stopwatch stopwatch;
496 const Vector3ui resolution = gridResolution();
497
498 /* Lets start with the normals for the edge faces of the volume, that do require
499 * an ad-hoc processing.
500 */
501 for( unsigned int dim0 = 0; dim0 < 3; ++dim0 )
502 {
503 for( signed int sign = -1; sign <= +1; sign += 2 )
504 {
505 /* Construct the normal vector along dimension 'dim0' signed with 'sign'.
506 */
507 Vector3f normal( 0, 0, 0 );
508 normal( dim0 ) = sign;
509
510 /* Write the normal vector to the whole face.
511 */
512 const unsigned int dim1 = ( dim0 + 1 ) % 3;
513 const unsigned int dim2 = ( dim0 + 2 ) % 3;
514
515 Vector3ui coord;
516 coord( dim0 ) = sign < 0 ? 0 : resolution( dim0 ) - 1;
517
518 for( coord( dim1 ) = 0; coord( dim1 ) < resolution( dim1 ); ++coord( dim1 ) )
519 for( coord( dim2 ) = 0; coord( dim2 ) < resolution( dim2 ); ++coord( dim2 ) )
520 {
521 grid->template setVoxel< NormalSelector >( coord, normal );
522 }
523 }
524 }
525
526 /* Now we can process all the inner voxels regularly.
527 */
528 const Vector3ui coordLowerBound = Vector3ui( 1, 1, 1 );
529 const Vector3ui coordUpperBound = ( resolution.cast< int >() - Vector3i( 1, 1, 1 ) ).cast< unsigned int >();
530 LIBCARNA_FOR_VECTOR3UI_EX( coord, coordUpperBound, coordLowerBound )
531 {
532 /* Compute the gradient vector.
533 */
534 const Vector3f gradient = base::math::computeFastGradient3f(
535 [this, &coord]( unsigned int dx, unsigned int dy, unsigned int dz )
536 {
537 return grid->template getVoxel< IntensitySelector >( Vector3ui( coord.x() + dx, coord.y() + dy, coord.z() + dz ) );
538 }
539 );
540
541 /* The normal vector points to the *reverse* direction of the gradient, i.e.
542 * away from the steepest ascent.
543 */
544 Vector3f normal = -gradient;
545 if( normal.squaredNorm() > 1e-12 )
546 {
547 normal.normalize();
548 }
549 else
550 {
551 normal = Vector3f( 0, 0, 0 );
552 }
553 grid->template setVoxel< NormalSelector >( coord, normal );
554 }
555
556 /* Log how long it took to compute the normals.
557 */
558 const unsigned int seconds = base::math::round_ui( stopwatch.result() );
560 , "VolumeGridHelper finished normals computation in "
561 + base::text::lexical_cast< std::string >( seconds )
562 + " seconds." );
563}
564
565
566template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
572
573
574template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
582
583
584template< typename SegmentIntensityVolumeType, typename SegmentNormalsVolumeType >
587 , const base::math::Vector3ui& size ) const
588{
589 SegmentNormalsVolumeType* const normals = new SegmentNormalsVolumeType( size );
590 segment.setNormals( new base::Composition< SegmentNormalsVolumeType >( normals ) );
591}
592
593
594
595// ----------------------------------------------------------------------------------
596// NormalsComponent< SegmentIntensityVolumeType, void >
597// ----------------------------------------------------------------------------------
598
604template< typename SegmentIntensityVolumeType >
605class NormalsComponent< SegmentIntensityVolumeType, void > : public NormalsComponentBase
606{
607
608public:
609
614
615protected:
616
620 void computeNormals();
621
626
630 void attachTexture
631 ( base::Geometry& geometry
633
639 , const base::math::Vector3ui& size ) const;
640
641}; // NormalsComponent
642
643
644template< typename SegmentIntensityVolumeType >
648
649
650template< typename SegmentIntensityVolumeType >
654
655
656template< typename SegmentIntensityVolumeType >
661
662
663template< typename SegmentIntensityVolumeType >
669
670
671template< typename SegmentIntensityVolumeType >
677
678
679
680// ----------------------------------------------------------------------------------
681// Partionining
682// ----------------------------------------------------------------------------------
683
690{
698 Partionining( std::size_t nativeSize, std::size_t regularPartitionSize )
701 , tailSize( base::math::makeEven( nativeSize % regularPartitionSize, +1 ) )
702 {
703 LIBCARNA_ASSERT_EX( regularPartitionSize % 2 == 1, "Effective regular partition size must be odd!" );
704 }
705
710
716
720 std::size_t tailSize;
721
725 std::size_t totalSize() const
726 {
728 }
729
733 std::size_t partitionsCount() const
734 {
735 return regularPartitionsCount + ( tailSize > 0 ? 1 : 0 );
736 }
737};
738
739
740
741} // namespace VolumeGridHelper
742
743} // namespace details
744
745} // namespace LibCarna :: helpers
746
747} // namespace LibCarna
748
749#endif // VOLUMEGRIDHELPERDETAILS_H_6014714286
Defines LibCarna::base::BufferedNormalMap3D.
Defines LibCarna::base::BufferedVectorFieldTexture.
Defines LibCarna::base::Geometry.
#define LIBCARNA_ASSERT_EX(expression, description)
If the given expression is false, a break point is raised in debug mode and an AssertionFailure throw...
Contains forward-declarations.
Defines LibCarna::base::Log.
Defines LibCarna::base::Stopwatch.
Defines LibCarna::base::VolumeGrid.
Defines LibCarna::base::VolumeSegment.
Represents an association.
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.hpp:63
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.hpp:92
Represents 3D OpenGL texture object whose lifetime is managed by instances of this class.
static Log & instance()
Returns the only instance from class InstanceType.
Implements stopwatch using the robust wallclock time from OMP that most compilers support.
Definition Stopwatch.hpp:44
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 initializeSegment(base::VolumeSegment< SegmentIntensityVolumeType, SegmentNormalsVolumeType > &segment, const base::math::Vector3ui &size) const
Initializes intensity volume of segment.
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...
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.
IntensityComponent()
Sets the role to use for attaching textures to base::Geometry nodes to DEFAULT_ROLE_INTENSITIES.
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 setGrid(base::VolumeGrid< SegmentIntensityVolumeType, SegmentNormalsVolumeType > &grid)
Sets the grid that computeNormals operates on.
void setNormalsRole(unsigned int role)
Sets the role to use for attaching textures to base::Geometry nodes.
static const unsigned int DEFAULT_ROLE_NORMALS
Holds the default 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.
void initializeSegment(base::VolumeSegment< SegmentIntensityVolumeType, SegmentNormalsVolumeType > &segment, const base::math::Vector3ui &size) const
Initializes normal map of segment.
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...
NormalsComponent()
Sets the role to use for attaching textures to base::Geometry nodes to DEFAULT_ROLE_NORMALS.
void computeNormals()
Computes the normal map on the previously set grid.
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.
#define LIBCARNA_FOR_VECTOR3UI_EX(vecName, vecLimit, vecStart)
Loops vecName over all where is vecLimit and is vecStart.
Definition math.hpp:731
base::math::Vector3f computeFastGradient3f(Sampler func)
Computes fast approximation of the gradient at the origin of the scalar field func.
Definition math.hpp:581
Eigen::Matrix< signed int, 3, 1 > Vector3i
Defines vector.
Definition math.hpp:202
Eigen::Matrix< float, 3, 1 > Vector3f
Defines vector.
Definition math.hpp:200
unsigned int round_ui(ScalarType x)
Rounds x to the closest . Either the data type of must be unsigned or .
Definition math.hpp:598
Eigen::Matrix< unsigned int, 3, 1 > Vector3ui
Defines vector.
Definition math.hpp:203
#define NON_COPYABLE
Marks the class that it is placed in as non-copyable.
References the intensity volume of a given partition.
Creates textures that represents base::VolumeSegment::intensities 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.
static base::ManagedTexture3D & createTexture(const base::VolumeSegment< SegmentIntensityVolumeType, SegmentNormalsVolumeType > &segment)
Creates texture that represents the base::VolumeSegment::intensities of segment in video memory.
Creates textures that represents base::VolumeSegmentNormalsComponent::normals in video memory.
SegmentIntensityVolumeType SegmentIntensityVolume
Reflects the type to use for storing the intensity volume 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 ...
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.
std::size_t partitionsCount() const
Tells the total partitions number.
std::size_t tailSize
Holds the resolution of the last partition that may also be 0.
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.
Partionining(std::size_t nativeSize, std::size_t regularPartitionSize)
Computes the partitioning.
std::size_t regularPartitionsCount
Holds the number of regular partitions, i.e. such of the size held by regularPartitionSize.
Defines LibCarna::base::text.