38 #ifndef OPENVDB_TOOLS_SIGNEDFLOODFILL_HAS_BEEN_INCLUDED 39 #define OPENVDB_TOOLS_SIGNEDFLOODFILL_HAS_BEEN_INCLUDED 46 #include <type_traits> 69 template<
typename TreeOrLeafManagerT>
72 size_t grainSize = 1,
Index minLevel = 0);
93 template<
typename TreeOrLeafManagerT>
96 TreeOrLeafManagerT& tree,
97 const typename TreeOrLeafManagerT::ValueType& outsideWidth,
98 const typename TreeOrLeafManagerT::ValueType& insideWidth,
100 size_t grainSize = 1,
107 template<
typename TreeOrLeafManagerT>
111 using ValueT =
typename TreeOrLeafManagerT::ValueType;
112 using RootT =
typename TreeOrLeafManagerT::RootNodeType;
113 using LeafT =
typename TreeOrLeafManagerT::LeafNodeType;
114 static_assert(std::is_signed<ValueT>::value,
115 "signed flood fill is supported only for signed value grids");
118 : mOutside(
ValueT(math::
Abs(tree.background())))
120 , mMinLevel(minLevel)
125 : mOutside(
ValueT(math::
Abs(outsideValue)))
127 , mMinLevel(minLevel)
134 if (LeafT::LEVEL < mMinLevel)
return;
136 #if OPENVDB_ABI_VERSION_NUMBER >= 3 137 if (!leaf.allocate())
return;
139 const typename LeafT::NodeMaskType& valueMask = leaf.getValueMask();
141 typename LeafT::ValueType* buffer =
142 const_cast<typename LeafT::ValueType*>(&(leaf.getFirstValue()));
144 const Index first = valueMask.findFirstOn();
145 if (first < LeafT::SIZE) {
146 bool xInside = buffer[first]<0, yInside = xInside, zInside = xInside;
147 for (
Index x = 0; x != (1 << LeafT::LOG2DIM); ++x) {
148 const Index x00 = x << (2 * LeafT::LOG2DIM);
149 if (valueMask.isOn(x00)) xInside = buffer[x00] < 0;
151 for (
Index y = 0; y != (1 << LeafT::LOG2DIM); ++y) {
152 const Index xy0 = x00 + (y << LeafT::LOG2DIM);
153 if (valueMask.isOn(xy0)) yInside = buffer[xy0] < 0;
155 for (
Index z = 0; z != (1 << LeafT::LOG2DIM); ++z) {
156 const Index xyz = xy0 + z;
157 if (valueMask.isOn(xyz)) {
158 zInside = buffer[xyz] < 0;
160 buffer[xyz] = zInside ? mInside : mOutside;
166 leaf.fill(buffer[0] < 0 ? mInside : mOutside);
171 template<
typename NodeT>
174 if (NodeT::LEVEL < mMinLevel)
return;
176 const typename NodeT::NodeMaskType& childMask = node.getChildMask();
178 typename NodeT::UnionType* table = const_cast<typename NodeT::UnionType*>(node.getTable());
180 const Index first = childMask.findFirstOn();
181 if (first < NodeT::NUM_VALUES) {
182 bool xInside = table[first].getChild()->getFirstValue()<0;
183 bool yInside = xInside, zInside = xInside;
184 for (
Index x = 0; x != (1 << NodeT::LOG2DIM); ++x) {
185 const int x00 = x << (2 * NodeT::LOG2DIM);
186 if (childMask.isOn(x00)) xInside = table[x00].getChild()->getLastValue()<0;
188 for (
Index y = 0; y != (1 << NodeT::LOG2DIM); ++y) {
189 const Index xy0 = x00 + (y << NodeT::LOG2DIM);
190 if (childMask.isOn(xy0)) yInside = table[xy0].getChild()->getLastValue()<0;
192 for (
Index z = 0; z != (1 << NodeT::LOG2DIM); ++z) {
193 const Index xyz = xy0 + z;
194 if (childMask.isOn(xyz)) {
195 zInside = table[xyz].getChild()->getLastValue()<0;
197 table[xyz].setValue(zInside ? mInside : mOutside);
203 const ValueT v = table[0].getValue()<0 ? mInside : mOutside;
204 for (
Index i = 0; i < NodeT::NUM_VALUES; ++i) table[i].setValue(v);
211 if (RootT::LEVEL < mMinLevel)
return;
212 using ChildT =
typename RootT::ChildNodeType;
214 std::map<Coord, ChildT*> nodeKeys;
215 typename RootT::ChildOnIter it = root.beginChildOn();
216 for (; it; ++it) nodeKeys.insert(std::pair<Coord, ChildT*>(it.getCoord(), &(*it)));
217 static const Index DIM = RootT::ChildNodeType::DIM;
221 typename std::map<Coord, ChildT*>::const_iterator b = nodeKeys.begin(), e = nodeKeys.end();
222 if ( b == e )
return;
223 for (
typename std::map<Coord, ChildT*>::const_iterator a = b++; b != e; ++a, ++b) {
224 Coord d = b->first - a->first;
225 if (d[0]!=0 || d[1]!=0 || d[2]==
Int32(DIM))
continue;
226 const ValueT fill[] = { a->second->getLastValue(), b->second->getFirstValue() };
227 if (!(fill[0] < 0) || !(fill[1] < 0))
continue;
229 for (; c[2] != b->first[2]; c[2] += DIM) root.addTile(c, mInside,
false);
231 root.setBackground(mOutside,
false);
235 const ValueT mOutside, mInside;
236 const Index mMinLevel;
243 template<
typename TreeOrLeafManagerT>
245 typename std::enable_if<std::is_signed<typename TreeOrLeafManagerT::ValueType>::value,
void>::type
246 doSignedFloodFill(TreeOrLeafManagerT& tree,
247 typename TreeOrLeafManagerT::ValueType outsideValue,
248 typename TreeOrLeafManagerT::ValueType insideValue,
254 SignedFloodFillOp<TreeOrLeafManagerT> op(outsideValue, insideValue, minLevel);
255 nodes.foreachBottomUp(op, threaded, grainSize);
259 template <
typename TreeOrLeafManagerT>
261 typename std::enable_if<!std::is_signed<typename TreeOrLeafManagerT::ValueType>::value,
void>::type
262 doSignedFloodFill(TreeOrLeafManagerT&,
263 const typename TreeOrLeafManagerT::ValueType&,
264 const typename TreeOrLeafManagerT::ValueType&,
270 "signedFloodFill is supported only for signed value grids");
278 template <
typename TreeOrLeafManagerT>
281 TreeOrLeafManagerT& tree,
282 const typename TreeOrLeafManagerT::ValueType& outsideValue,
283 const typename TreeOrLeafManagerT::ValueType& insideValue,
288 doSignedFloodFill(tree, outsideValue, insideValue, threaded, grainSize, minLevel);
292 template <
typename TreeOrLeafManagerT>
299 const typename TreeOrLeafManagerT::ValueType v = tree.root().background();
300 doSignedFloodFill(tree, v,
math::negative(v), threaded, grainSize, minLevel);
307 #endif // OPENVDB_TOOLS_RESETBACKGROUND_HAS_BEEN_INCLUDED
Index32 Index
Definition: Types.h:61
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:109
NodeManager produces linear arrays of all tree nodes allowing for efficient threading and bottom-up p...
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:51
int32_t Int32
Definition: Types.h:63
Definition: Exceptions.h:91
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:136
T negative(const T &val)
Return the unary negation of the given value.
Definition: Math.h:108
To facilitate threading over the nodes of a tree, cache node pointers in linear arrays,...
Definition: NodeManager.h:58
Definition: Exceptions.h:40
Library and file format version numbers.
Coord Abs(const Coord &xyz)
Definition: Coord.h:513
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:188