MeshLib
 
Loading...
Searching...
No Matches
MRVolumeInterpolation.h
Go to the documentation of this file.
1#pragma once
2
4
5namespace MR
6{
7
16template <typename Accessor>
18{
19public:
20 using VolumeType = typename Accessor::VolumeType;
21 using ValueType = typename Accessor::ValueType;
22
25 explicit VoxelsVolumeInterpolatedAccessor( const VolumeType& volume, const Accessor& accessor )
26 : volume_( volume ), accessor_( accessor )
27 {
28#ifndef MRMESH_NO_OPENVDB
29 if constexpr ( std::is_same_v<VolumeType, VdbVolume> )
30 {
31 openvdb::Coord coord = volume.data->evalActiveVoxelBoundingBox().min();
32 minCoord_ = { coord.x(), coord.y(), coord.z() };
33 }
34#endif
35 }
36
40 explicit VoxelsVolumeInterpolatedAccessor( const VoxelsVolumeInterpolatedAccessor& other, const Accessor& accessor )
41#ifndef MRMESH_NO_OPENVDB
42 : volume_( other.volume_ ), accessor_( accessor ), minCoord_( other.minCoord_ )
43#else
44 : volume_( other.volume_ ), accessor_( accessor )
45#endif
46 {}
47
49 ValueType get( const Vector3f& pos ) const
50 {
51 IndexAndPos index = getIndexAndPos(pos);
52 ValueType value{};
53 float cx[2] = { 1.0f - index.pos.x, index.pos.x };
54 float cy[2] = { 1.0f - index.pos.y, index.pos.y };
55 float cz[2] = { 1.0f - index.pos.z, index.pos.z };
56 for ( int i = 0; i < 8; i++ )
57 {
58 Vector3i d{ i & 1, ( i >> 1 ) & 1, i >> 2 };
59 const auto voxPos = index.index + d;
60 if ( voxPos.x >= 0 && voxPos.x < volume_.dims.x &&
61 voxPos.y >= 0 && voxPos.y < volume_.dims.y &&
62 voxPos.z >= 0 && voxPos.z < volume_.dims.z )
63 {
64 value += accessor_.get( voxPos ) * ( cx[d.x] * cy[d.y] * cz[d.z] );
65 }
66 }
67 return value;
68 }
69
70private:
71 const VolumeType& volume_;
72 const Accessor& accessor_;
73#ifndef MRMESH_NO_OPENVDB
74 Vector3i minCoord_{};
75#endif
76
77 struct IndexAndPos
78 {
79 Vector3i index; // Zero-based voxel index in the volume
80 Vector3f pos; // [0;1) position of a point in the voxel: 0 corresponds to index and 1 to next voxel
81 };
82
83 IndexAndPos getIndexAndPos( Vector3f pos ) const
84 {
85 IndexAndPos res;
86 res.pos.x = pos.x / volume_.voxelSize.x;
87 res.pos.y = pos.y / volume_.voxelSize.y;
88 res.pos.z = pos.z / volume_.voxelSize.z;
89 pos.x = floor( res.pos.x );
90 pos.y = floor( res.pos.y );
91 pos.z = floor( res.pos.z );
92 res.index.x = int( pos.x );
93 res.index.y = int( pos.y );
94 res.index.z = int( pos.z );
95 res.pos.x -= pos.x;
96 res.pos.y -= pos.y;
97 res.pos.z -= pos.z;
98#ifndef MRMESH_NO_OPENVDB
99 if constexpr ( std::is_same_v<VolumeType, VdbVolume> )
100 res.index -= minCoord_;
101#endif
102 return res;
103 }
104};
105
107template <typename Accessor>
109 const typename Accessor::VolumeType &volume,
110 const Accessor &accessor,
111 const Vector3f &newVoxelSize )
112{
113 SimpleVolume res{
114 { .voxelSize{ newVoxelSize } },
115 volume.min,
116 volume.max
117 };
118 res.dims.x = int( volume.dims.x * volume.voxelSize.x / res.voxelSize.x );
119 res.dims.y = int( volume.dims.y * volume.voxelSize.y / res.voxelSize.y );
120 res.dims.z = int( volume.dims.z * volume.voxelSize.z / res.voxelSize.z );
121 res.data.resize( res.dims.x * res.dims.y * res.dims.z );
122 VolumeIndexer indexer( res.dims );
123
124 VoxelsVolumeInterpolatedAccessor<Accessor> interpolator( volume, accessor );
125 for ( int k = 0; k < res.dims.z; k++ )
126 for ( int j = 0; j < res.dims.y; j++ )
127 for ( int i = 0; i < res.dims.x; i++ )
128 res.data[indexer.toVoxelId( { i, j, k } )] = interpolator.get(
129 { i * res.voxelSize.x, j * res.voxelSize.y, k * res.voxelSize.z } );
130
131 return res;
132}
133
134} // namespace MR
Definition MRVolumeIndexer.h:65
Definition MRVolumeInterpolation.h:18
VoxelsVolumeInterpolatedAccessor(const VoxelsVolumeInterpolatedAccessor &)=delete
delete copying constructor to avoid accidentally creating non-thread-safe accessors
ValueType get(const Vector3f &pos) const
get value at specified coordinates
Definition MRVolumeInterpolation.h:49
VoxelsVolumeInterpolatedAccessor(const VolumeType &volume, const Accessor &accessor)
Definition MRVolumeInterpolation.h:25
typename Accessor::VolumeType VolumeType
Definition MRVolumeInterpolation.h:20
typename Accessor::ValueType ValueType
Definition MRVolumeInterpolation.h:21
VoxelsVolumeInterpolatedAccessor(const VoxelsVolumeInterpolatedAccessor &other, const Accessor &accessor)
a copying-like constructor with explicitly provided accessor
Definition MRVolumeInterpolation.h:40
represents a 3-dimentional float-typed vector
Definition MRDotNet/MRVector3.h:8
VoxelId toVoxelId(const Vector3i &pos) const
Definition MRVolumeIndexer.h:141
constexpr A floor(A a)
Definition MRImGuiVectorOperators.h:126
Definition MRCameraOrientationPlugin.h:7
Vector3< int > Vector3i
Definition MRDotNet/MRMeshFwd.h:9
SimpleVolume resampleVolumeByInterpolation(const typename Accessor::VolumeType &volume, const Accessor &accessor, const Vector3f &newVoxelSize)
sample function that resamples the voxel volume using interpolating accessor
Definition MRVolumeInterpolation.h:108
T x
Definition MRMesh/MRVector3.h:25