39 #ifndef OPENVDB_TOOLS_SIGNEDFLOODFILL_HAS_BEEN_INCLUDED 40 #define OPENVDB_TOOLS_SIGNEDFLOODFILL_HAS_BEEN_INCLUDED 45 #include <type_traits> 68 template<
typename TreeOrLeafManagerT>
71 size_t grainSize = 1,
Index minLevel = 0);
92 template<
typename TreeOrLeafManagerT>
95 TreeOrLeafManagerT& tree,
96 const typename TreeOrLeafManagerT::ValueType& outsideWidth,
97 const typename TreeOrLeafManagerT::ValueType& insideWidth,
106 template<
typename TreeOrLeafManagerT>
110 using ValueT =
typename TreeOrLeafManagerT::ValueType;
111 using RootT =
typename TreeOrLeafManagerT::RootNodeType;
112 using LeafT =
typename TreeOrLeafManagerT::LeafNodeType;
113 static_assert(std::is_signed<ValueT>::value,
114 "signed flood fill is supported only for signed value grids");
117 : mOutside(
ValueT(math::
Abs(tree.background())))
119 , mMinLevel(minLevel)
124 : mOutside(
ValueT(math::
Abs(outsideValue)))
126 , mMinLevel(minLevel)
133 if (LeafT::LEVEL < mMinLevel)
return;
135 #ifndef OPENVDB_2_ABI_COMPATIBLE 136 if (!leaf.allocate())
return;
138 const typename LeafT::NodeMaskType& valueMask = leaf.getValueMask();
140 typename LeafT::ValueType* buffer =
141 const_cast<typename LeafT::ValueType*
>(&(leaf.getFirstValue()));
143 const Index first = valueMask.findFirstOn();
144 if (first < LeafT::SIZE) {
145 bool xInside = buffer[first]<0, yInside = xInside, zInside = xInside;
146 for (
Index x = 0; x != (1 << LeafT::LOG2DIM); ++x) {
147 const Index x00 = x << (2 * LeafT::LOG2DIM);
148 if (valueMask.isOn(x00)) xInside = buffer[x00] < 0;
150 for (
Index y = 0; y != (1 << LeafT::LOG2DIM); ++y) {
151 const Index xy0 = x00 + (y << LeafT::LOG2DIM);
152 if (valueMask.isOn(xy0)) yInside = buffer[xy0] < 0;
154 for (
Index z = 0; z != (1 << LeafT::LOG2DIM); ++z) {
155 const Index xyz = xy0 + z;
156 if (valueMask.isOn(xyz)) {
157 zInside = buffer[xyz] < 0;
159 buffer[xyz] = zInside ? mInside : mOutside;
165 leaf.fill(buffer[0] < 0 ? mInside : mOutside);
170 template<
typename NodeT>
173 if (NodeT::LEVEL < mMinLevel)
return;
175 const typename NodeT::NodeMaskType& childMask = node.getChildMask();
177 typename NodeT::UnionType* table =
const_cast<typename NodeT::UnionType*
>(node.getTable());
179 const Index first = childMask.findFirstOn();
180 if (first < NodeT::NUM_VALUES) {
181 bool xInside = table[first].getChild()->getFirstValue()<0;
182 bool yInside = xInside, zInside = xInside;
183 for (
Index x = 0; x != (1 << NodeT::LOG2DIM); ++x) {
184 const int x00 = x << (2 * NodeT::LOG2DIM);
185 if (childMask.isOn(x00)) xInside = table[x00].getChild()->getLastValue()<0;
187 for (
Index y = 0; y != (1 << NodeT::LOG2DIM); ++y) {
188 const Index xy0 = x00 + (y << NodeT::LOG2DIM);
189 if (childMask.isOn(xy0)) yInside = table[xy0].getChild()->getLastValue()<0;
191 for (
Index z = 0; z != (1 << NodeT::LOG2DIM); ++z) {
192 const Index xyz = xy0 + z;
193 if (childMask.isOn(xyz)) {
194 zInside = table[xyz].getChild()->getLastValue()<0;
196 table[xyz].setValue(zInside ? mInside : mOutside);
202 const ValueT v = table[0].getValue()<0 ? mInside : mOutside;
203 for (
Index i = 0;
i < NodeT::NUM_VALUES; ++
i) table[
i].setValue(v);
210 if (RootT::LEVEL < mMinLevel)
return;
211 using ChildT =
typename RootT::ChildNodeType;
213 std::map<Coord, ChildT*> nodeKeys;
214 typename RootT::ChildOnIter it = root.beginChildOn();
215 for (; it; ++it) nodeKeys.insert(std::pair<Coord, ChildT*>(it.getCoord(), &(*it)));
216 static const Index DIM = RootT::ChildNodeType::DIM;
220 typename std::map<Coord, ChildT*>::const_iterator b = nodeKeys.begin(), e = nodeKeys.end();
221 if ( b == e )
return;
222 for (
typename std::map<Coord, ChildT*>::const_iterator a = b++; b != e; ++a, ++b) {
223 Coord d = b->first - a->first;
224 if (d[0]!=0 || d[1]!=0 || d[2]==
Int32(DIM))
continue;
225 const ValueT fill[] = { a->second->getLastValue(), b->second->getFirstValue() };
226 if (!(fill[0] < 0) || !(fill[1] < 0))
continue;
228 for (; c[2] != b->first[2]; c[2] += DIM) root.addTile(c, mInside,
false);
230 root.setBackground(mOutside,
false);
234 const ValueT mOutside, mInside;
235 const Index mMinLevel;
242 template<
typename TreeOrLeafManagerT>
244 typename std::enable_if<std::is_signed<typename TreeOrLeafManagerT::ValueType>::value,
void>::type
245 doSignedFloodFill(TreeOrLeafManagerT& tree,
246 typename TreeOrLeafManagerT::ValueType outsideValue,
247 typename TreeOrLeafManagerT::ValueType insideValue,
253 SignedFloodFillOp<TreeOrLeafManagerT> op(outsideValue, insideValue, minLevel);
254 nodes.foreachBottomUp(op, threaded, grainSize);
258 template <
typename TreeOrLeafManagerT>
260 typename std::enable_if<!std::is_signed<typename TreeOrLeafManagerT::ValueType>::value,
void>::type
261 doSignedFloodFill(TreeOrLeafManagerT&,
262 const typename TreeOrLeafManagerT::ValueType&,
263 const typename TreeOrLeafManagerT::ValueType&,
269 "signedFloodFill is supported only for signed value grids");
277 template <
typename TreeOrLeafManagerT>
280 TreeOrLeafManagerT& tree,
281 const typename TreeOrLeafManagerT::ValueType& outsideValue,
282 const typename TreeOrLeafManagerT::ValueType& insideValue,
287 doSignedFloodFill(tree, outsideValue, insideValue, threaded, grainSize, minLevel);
291 template <
typename TreeOrLeafManagerT>
298 const typename TreeOrLeafManagerT::ValueType v = tree.root().background();
299 doSignedFloodFill(tree, v,
math::negative(v), threaded, grainSize, minLevel);
306 #endif // OPENVDB_TOOLS_RESETBACKGROUND_HAS_BEEN_INCLUDED
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:101
NodeManager produces linear arrays of all tree nodes allowing for efficient threading and bottom-up p...
To facilitate threading over the nodes of a tree, cache node pointers in linear arrays, one for each level of the tree.
Definition: NodeManager.h:57
tbb::atomic< Index32 > i
Definition: LeafBuffer.h:71
Index32 Index
Definition: Types.h:57
#define OPENVDB_VERSION_NAME
Definition: version.h:43
T negative(const T &val)
Return the unary negation of the given value.
Definition: Math.h:108
Coord Abs(const Coord &xyz)
Definition: Coord.h:509
Definition: Exceptions.h:39
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:48
int32_t Int32
Definition: Types.h:59
Definition: Exceptions.h:91
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71