OpenVDB 13.0.1
Loading...
Searching...
No Matches
MorphologyHelpers.h
Go to the documentation of this file.
1// Copyright Contributors to the OpenVDB Project
2// SPDX-License-Identifier: Apache-2.0
3
4/*!
5 \file MorphologyHelpers.h
6
7 \author Efty Sifakis
8
9 \date March 17, 2025
10
11 \brief This file implements helper methods used in morphology operations
12
13*/
14
15#ifndef NANOVDB_UTIL_MORPHOLOGYHELPERS_H_HAS_BEEN_INCLUDED
16#define NANOVDB_UTIL_MORPHOLOGYHELPERS_H_HAS_BEEN_INCLUDED
17
18#include <nanovdb/NanoVDB.h>
19
21
23
24} // namespace nanovdb::tools::morphology
25
26namespace nanovdb::util {
27
28namespace morphology {
29
30template<int di, int dj, int dk>
32 static_assert( (di>=-1) && (di<=1) && (dj>=-1) && (dj<=1) && (dk>=-1) && (dk<=1) );
33 static constexpr uint32_t value = 1u << (di+1)*9+(dj+1)*3+dk+1;
34};
35
36template<tools::morphology::NearestNeighbors nnType>
39{
43
44 uint32_t result = 0;
45 auto words = mask.words();
46 uint64_t allWordsOr = 0;
47 for (int i = 0; i < 8; i++)
48 allWordsOr |= words[i];
49 // Center
50 if ( allWordsOr ) result |= NearestNeighborBitMask< 0, 0, 0>::value;
51 // Neighbors across faces
52 if constexpr (nnType == NN_FACE || nnType == NN_FACE_EDGE || nnType == NN_FACE_EDGE_VERTEX) {
53 if ( words[0] ) result |= NearestNeighborBitMask<-1, 0, 0>::value;
54 if ( words[7] ) result |= NearestNeighborBitMask< 1, 0, 0>::value;
55 if ( allWordsOr & 0x00000000000000ffUL ) result |= NearestNeighborBitMask< 0,-1, 0>::value;
56 if ( allWordsOr & 0xff00000000000000UL ) result |= NearestNeighborBitMask< 0, 1, 0>::value;
57 if ( allWordsOr & 0x0101010101010101UL ) result |= NearestNeighborBitMask< 0, 0,-1>::value;
58 if ( allWordsOr & 0x8080808080808080UL ) result |= NearestNeighborBitMask< 0, 0, 1>::value; }
59 // Neighbors across edges
60 if constexpr (nnType == NN_FACE_EDGE || nnType == NN_FACE_EDGE_VERTEX) {
61 if ( words[0] & 0x00000000000000ffUL ) result |= NearestNeighborBitMask<-1,-1, 0>::value;
62 if ( words[0] & 0xff00000000000000UL ) result |= NearestNeighborBitMask<-1, 1, 0>::value;
63 if ( words[0] & 0x0101010101010101UL ) result |= NearestNeighborBitMask<-1, 0,-1>::value;
64 if ( words[0] & 0x8080808080808080UL ) result |= NearestNeighborBitMask<-1, 0, 1>::value;
65 if ( allWordsOr & 0x0000000000000001UL ) result |= NearestNeighborBitMask< 0,-1,-1>::value;
66 if ( allWordsOr & 0x0000000000000080UL ) result |= NearestNeighborBitMask< 0,-1, 1>::value;
67 if ( allWordsOr & 0x0100000000000000UL ) result |= NearestNeighborBitMask< 0, 1,-1>::value;
68 if ( allWordsOr & 0x8000000000000000UL ) result |= NearestNeighborBitMask< 0, 1, 1>::value;
69 if ( words[7] & 0x00000000000000ffUL ) result |= NearestNeighborBitMask< 1,-1, 0>::value;
70 if ( words[7] & 0xff00000000000000UL ) result |= NearestNeighborBitMask< 1, 1, 0>::value;
71 if ( words[7] & 0x0101010101010101UL ) result |= NearestNeighborBitMask< 1, 0,-1>::value;
72 if ( words[7] & 0x8080808080808080UL ) result |= NearestNeighborBitMask< 1, 0, 1>::value; }
73 // Neighbors across vertices
74 if constexpr (nnType == NN_FACE_EDGE_VERTEX) {
75 if ( words[0] & 0x0000000000000001UL ) result |= NearestNeighborBitMask<-1,-1,-1>::value;
76 if ( words[0] & 0x0000000000000080UL ) result |= NearestNeighborBitMask<-1,-1, 1>::value;
77 if ( words[0] & 0x0100000000000000UL ) result |= NearestNeighborBitMask<-1, 1,-1>::value;
78 if ( words[0] & 0x8000000000000000UL ) result |= NearestNeighborBitMask<-1, 1, 1>::value;
79 if ( words[7] & 0x0000000000000001UL ) result |= NearestNeighborBitMask< 1,-1,-1>::value;
80 if ( words[7] & 0x0000000000000080UL ) result |= NearestNeighborBitMask< 1,-1, 1>::value;
81 if ( words[7] & 0x0100000000000000UL ) result |= NearestNeighborBitMask< 1, 1,-1>::value;
82 if ( words[7] & 0x8000000000000000UL ) result |= NearestNeighborBitMask< 1, 1, 1>::value; }
83 return result;
84}
85
87inline Coord::ValueType
88coarsenComponent(const Coord::ValueType n)
89{return (n>=0) ? (n>>1) : -((-n+1)>>1);} // Round down for negative integers
90
92inline Coord
93coarsenCoord(const Coord& coord)
94{
95 Coord result;
96 result[0] = coarsenComponent(coord[0]);
97 result[1] = coarsenComponent(coord[1]);
98 result[2] = coarsenComponent(coord[2]);
99 return result;
100}
101
103inline Coord::ValueType
104refineComponent(const Coord::ValueType n)
105{return (n>=0) ? (n<<1) : -((-n)<<1);}
106
108inline Coord
109refineCoord(const Coord& coord)
110{
111 Coord result;
112 result[0] = refineComponent(coord[0]);
113 result[1] = refineComponent(coord[1]);
114 result[2] = refineComponent(coord[2]);
115 return result;
116}
117
118} // namespace morphology
119
120} // namespace nanovdb::util
121
122#if defined(__CUDACC__)
123#include <nanovdb/util/cuda/MorphologyHelpers.cuh>
124#endif // defined(__CUDACC__)
125
126#endif // NANOVDB_UTIL_MORPHOLOGYHELPERS_H_HAS_BEEN_INCLUDED
127
Implements a light-weight self-contained VDB data-structure in a single file! In other words,...
Bit-mask to encode active states and facilitate sequential iterators and a fast codec for I/O compres...
Definition NanoVDB.h:1047
__hostdev__ uint64_t * words()
Return a pointer to the list of words of the bit mask.
Definition NanoVDB.h:1171
Definition MorphologyHelpers.h:20
NearestNeighbors
Definition MorphologyHelpers.h:22
@ NN_FACE_EDGE_VERTEX
Definition MorphologyHelpers.h:22
@ NN_FACE_EDGE
Definition MorphologyHelpers.h:22
@ NN_FACE
Definition MorphologyHelpers.h:22
Definition MorphologyHelpers.h:28
__hostdev__ uint32_t neighborMaskStencil(const nanovdb::Mask< 3 > &mask)
Definition MorphologyHelpers.h:38
__hostdev__ Coord::ValueType refineComponent(const Coord::ValueType n)
Definition MorphologyHelpers.h:104
__hostdev__ Coord::ValueType coarsenComponent(const Coord::ValueType n)
Definition MorphologyHelpers.h:88
__hostdev__ Coord refineCoord(const Coord &coord)
Definition MorphologyHelpers.h:109
__hostdev__ Coord coarsenCoord(const Coord &coord)
Definition MorphologyHelpers.h:93
Definition ForEach.h:29
#define __hostdev__
Definition Util.h:73
Definition MorphologyHelpers.h:31
static constexpr uint32_t value
Definition MorphologyHelpers.h:33