MeshLib
 
Loading...
Searching...
No Matches
MRVolumeIndexer.h
Go to the documentation of this file.
1#pragma once
2
3#include "MRMeshFwd.h"
4#include "MRVector3.h"
5#include "MRId.h"
6
7#include <array>
8
9namespace MR
10{
11
15
19
20enum class OutEdge : signed char
21{
22 Invalid = -1,
23 PlusZ = 0,
24 MinusZ,
25 PlusY,
26 MinusY,
27 PlusX,
28 MinusX,
29 Count
30};
31
32static_assert( sizeof( OutEdge ) == 1 );
33
34static const std::initializer_list<OutEdge> all6Edges = { OutEdge::PlusZ, OutEdge::MinusZ, OutEdge::PlusY, OutEdge::MinusY, OutEdge::PlusX, OutEdge::MinusX };
35
36[[nodiscard]] inline OutEdge opposite( OutEdge e )
37{
39 return map[ (size_t)e + 1 ];
40}
41
42static constexpr int OutEdgeCount = 6;
43
44constexpr Vector3i neiPosDelta[ OutEdgeCount ] =
45{
46 { 0, 0, 1 }, // PlusZ
47 { 0, 0,-1 }, // MinusZ
48 { 0, 1, 0 }, // PlusY
49 { 0,-1, 0 }, // MinusY
50 { 1, 0, 0 }, // PlusX
51 {-1, 0, 0 } // MinusX
52};
53
56{
57 VoxelId id;
59
61 explicit operator bool() const { return id.valid(); }
62};
63
65{
66public:
67 [[nodiscard]] VolumeIndexer( const Vector3i & dims );
68
69 [[nodiscard]] const Vector3i & dims() const { return dims_; }
70
72 [[nodiscard]] size_t size() const { return size_; }
73
75 [[nodiscard]] VoxelId endId() const { return VoxelId( size_ ); }
76
77 [[nodiscard]] size_t sizeXY() const { return sizeXY_; }
78
79 [[nodiscard]] Vector3i toPos( VoxelId id ) const;
80
81 [[nodiscard]] VoxelId toVoxelId( const Vector3i & pos ) const;
82
83 [[nodiscard]] VoxelLocation toLoc( VoxelId id ) const { return { id, toPos( id ) }; }
84 [[nodiscard]] VoxelLocation toLoc( const Vector3i & pos ) const { return { toVoxelId( pos ), pos }; }
85
87 [[nodiscard]] bool isInDims( const Vector3i& pos ) const { return pos.x >= 0 && pos.x < dims_.x && pos.y >= 0 && pos.y < dims_.y && pos.z >= 0 && pos.z < dims_.z; }
88
90 [[nodiscard]] bool isBdVoxel( const Vector3i & pos ) const { return pos.x == 0 || pos.x + 1 == dims_.x || pos.y == 0 || pos.y + 1 == dims_.y || pos.z == 0 || pos.z + 1 == dims_.z; }
91
93 [[nodiscard]] bool areNeigbors( VoxelId v0, VoxelId v1 ) const { return areNeigbors( toPos( v0 ), toPos( v1 ) ); }
94 [[nodiscard]] bool areNeigbors( const Vector3i & pos0, const Vector3i & pos1 ) const { return ( pos0 - pos1 ).lengthSq() == 1; }
95
97 [[nodiscard]] MRMESH_API bool hasNeighbour( const Vector3i & pos, OutEdge toNei ) const;
98
100 [[nodiscard]] VoxelId getNeighbor( VoxelId v, OutEdge toNei ) const { return getNeighbor( v, toPos( v ), toNei ); }
101 [[nodiscard]] VoxelId getNeighbor( VoxelId v, const Vector3i & pos, OutEdge toNei ) const { return hasNeighbour( pos, toNei ) ? getExistingNeighbor( v, toNei ) : VoxelId{}; }
102
105 [[nodiscard]] VoxelLocation getNeighbor( const VoxelLocation & loc, OutEdge toNei ) const;
106
108 [[nodiscard]] VoxelId getExistingNeighbor( VoxelId v, OutEdge toNei ) const;
109 [[nodiscard]] VoxelId getNeighbor( VoxelId v, const Vector3i & pos, bool bdPos, OutEdge toNei ) const { return bdPos ? getNeighbor( v, pos, toNei ) : getExistingNeighbor( v, toNei ); }
110
111protected:
113 size_t sizeXY_ = 0;
114 size_t size_ = 0;
115 int neiInc_[ OutEdgeCount ] = {};
116};
117
119 : dims_( dims )
120 , sizeXY_( size_t( dims_.x ) * dims_.y )
121 , size_( sizeXY_ * dims_.z )
122{
123 neiInc_[(int)OutEdge::PlusZ] = (int)sizeXY_;
124 neiInc_[(int)OutEdge::MinusZ] =-(int)sizeXY_;
127 neiInc_[(int)OutEdge::PlusX] = 1;
128 neiInc_[(int)OutEdge::MinusX] =-1;
129}
130
131inline Vector3i VolumeIndexer::toPos( VoxelId id ) const
132{
133 assert( id.valid() );
134 int z = int( id / sizeXY_ );
135 int sumZ = int( id % sizeXY_ );
136 int y = sumZ / dims_.x;
137 int x = sumZ % dims_.x;
138 return {x,y,z};
139}
140
141inline VoxelId VolumeIndexer::toVoxelId( const Vector3i & pos ) const
142{
143 return VoxelId{ pos.x + pos.y * size_t(dims_.x) + pos.z * sizeXY_ };
144}
145
146inline VoxelId VolumeIndexer::getExistingNeighbor( VoxelId v, OutEdge toNei ) const
147{
148 assert( toNei > OutEdge::Invalid && toNei < OutEdge::Count );
149 return v + neiInc_[(int)toNei];
150}
151
153{
154 assert( loc );
155 return hasNeighbour( loc.pos, toNei ) ?
156 VoxelLocation{ getExistingNeighbor( loc.id, toNei ), loc.pos + neiPosDelta[(int)toNei] } :
158}
159
161MRMESH_API void expandVoxelsMask( VoxelBitSet& mask, const VolumeIndexer& indexer, int expansion = 1 );
162
164MRMESH_API void shrinkVoxelsMask( VoxelBitSet& mask, const VolumeIndexer& indexer, int shrinkage = 1 );
165
167
168} // namespace MR
#define MRMESH_API
Definition MRMesh/MRMeshFwd.h:46
Definition MRVolumeIndexer.h:65
OutEdge2 opposite(OutEdge2 e)
Definition MRRectIndexer.h:28
MRMESH_API void expandVoxelsMask(VoxelBitSet &mask, const VolumeIndexer &indexer, int expansion=1)
expands VoxelBitSet with given number of steps
constexpr Vector3i neiPosDelta[OutEdgeCount]
Definition MRVolumeIndexer.h:44
OutEdge
Definition MRVolumeIndexer.h:21
MRMESH_API void shrinkVoxelsMask(VoxelBitSet &mask, const VolumeIndexer &indexer, int shrinkage=1)
shrinks VoxelBitSet with given number of steps
size_t size() const
returns the total number of voxels
Definition MRVolumeIndexer.h:72
bool isInDims(const Vector3i &pos) const
returns true if this voxel is within dimensions
Definition MRVolumeIndexer.h:87
VoxelId toVoxelId(const Vector3i &pos) const
Definition MRVolumeIndexer.h:141
const Vector3i & dims() const
Definition MRVolumeIndexer.h:69
VoxelLocation toLoc(VoxelId id) const
Definition MRVolumeIndexer.h:83
VoxelId id
Definition MRVolumeIndexer.h:57
size_t sizeXY_
= dims_.x * dims_.y
Definition MRVolumeIndexer.h:113
VoxelLocation toLoc(const Vector3i &pos) const
Definition MRVolumeIndexer.h:84
bool isBdVoxel(const Vector3i &pos) const
returns true if this voxel is on the boundary of the volume
Definition MRVolumeIndexer.h:90
VoxelId getNeighbor(VoxelId v, OutEdge toNei) const
returns id of v's neighbor specified by the edge
Definition MRVolumeIndexer.h:100
size_t size_
= dims_.x * dims_.y * dims_.z
Definition MRVolumeIndexer.h:114
VoxelId endId() const
returns the last plus one voxel Id for defining iteration range
Definition MRVolumeIndexer.h:75
VoxelId getExistingNeighbor(VoxelId v, OutEdge toNei) const
returns id of v's neighbor specified by the edge, which is known to exist (so skipping a lot of check...
Definition MRVolumeIndexer.h:146
bool areNeigbors(const Vector3i &pos0, const Vector3i &pos1) const
Definition MRVolumeIndexer.h:94
Vector3i dims_
Definition MRVolumeIndexer.h:112
int neiInc_[OutEdgeCount]
Definition MRVolumeIndexer.h:115
VoxelId getNeighbor(VoxelId v, const Vector3i &pos, bool bdPos, OutEdge toNei) const
Definition MRVolumeIndexer.h:109
VolumeIndexer(const Vector3i &dims)
Definition MRVolumeIndexer.h:118
bool areNeigbors(VoxelId v0, VoxelId v1) const
returns true if v1 is within at most 6 neighbors of v0
Definition MRVolumeIndexer.h:93
Vector3i pos
Definition MRVolumeIndexer.h:58
MRMESH_API bool hasNeighbour(const Vector3i &pos, OutEdge toNei) const
given existing voxel at (pos), returns whether it has valid neighbor specified by the edge (toNei)
size_t sizeXY() const
Definition MRVolumeIndexer.h:77
Vector3i toPos(VoxelId id) const
Definition MRVolumeIndexer.h:131
VoxelId getNeighbor(VoxelId v, const Vector3i &pos, OutEdge toNei) const
Definition MRVolumeIndexer.h:101
Definition MRCameraOrientationPlugin.h:7
T x
Definition MRMesh/MRVector3.h:25
T y
Definition MRMesh/MRVector3.h:25
T z
Definition MRMesh/MRVector3.h:25
contains both linear Id and 3D coordinates of the same voxel
Definition MRVolumeIndexer.h:56