11 #ifndef OPENVDB_TOOLS_SIGNEDFLOODFILL_HAS_BEEN_INCLUDED 12 #define OPENVDB_TOOLS_SIGNEDFLOODFILL_HAS_BEEN_INCLUDED 14 #include <openvdb/version.h> 20 #include <type_traits> 43 template<
typename TreeOrLeafManagerT>
46 size_t grainSize = 1, Index minLevel = 0);
67 template<
typename TreeOrLeafManagerT>
70 TreeOrLeafManagerT& tree,
71 const typename TreeOrLeafManagerT::ValueType& outsideWidth,
72 const typename TreeOrLeafManagerT::ValueType& insideWidth,
81 template<
typename TreeOrLeafManagerT>
85 using ValueT =
typename TreeOrLeafManagerT::ValueType;
86 using RootT =
typename TreeOrLeafManagerT::RootNodeType;
87 using LeafT =
typename TreeOrLeafManagerT::LeafNodeType;
88 static_assert(std::is_signed<ValueT>::value,
89 "signed flood fill is supported only for signed value grids");
92 : mOutside(
ValueT(math::
Abs(tree.background())))
99 : mOutside(
ValueT(math::
Abs(outsideValue)))
101 , mMinLevel(minLevel)
108 if (LeafT::LEVEL < mMinLevel)
return;
110 if (!leaf.allocate())
return;
112 const typename LeafT::NodeMaskType& valueMask = leaf.getValueMask();
114 typename LeafT::ValueType* buffer =
115 const_cast<typename LeafT::ValueType*
>(&(leaf.getFirstValue()));
117 const Index first = valueMask.findFirstOn();
118 if (first < LeafT::SIZE) {
119 bool xInside = buffer[first]<0, yInside = xInside, zInside = xInside;
120 for (
Index x = 0; x != (1 << LeafT::LOG2DIM); ++x) {
121 const Index x00 = x << (2 * LeafT::LOG2DIM);
122 if (valueMask.isOn(x00)) xInside = buffer[x00] < 0;
124 for (
Index y = 0; y != (1 << LeafT::LOG2DIM); ++y) {
125 const Index xy0 = x00 + (y << LeafT::LOG2DIM);
126 if (valueMask.isOn(xy0)) yInside = buffer[xy0] < 0;
128 for (
Index z = 0; z != (1 << LeafT::LOG2DIM); ++z) {
129 const Index xyz = xy0 + z;
130 if (valueMask.isOn(xyz)) {
131 zInside = buffer[xyz] < 0;
133 buffer[xyz] = zInside ? mInside : mOutside;
139 leaf.fill(buffer[0] < 0 ? mInside : mOutside);
144 template<
typename NodeT>
147 if (NodeT::LEVEL < mMinLevel)
return;
149 const typename NodeT::NodeMaskType& childMask = node.getChildMask();
151 typename NodeT::UnionType* table =
const_cast<typename NodeT::UnionType*
>(node.getTable());
153 const Index first = childMask.findFirstOn();
154 if (first < NodeT::NUM_VALUES) {
155 bool xInside = table[first].getChild()->getFirstValue()<0;
156 bool yInside = xInside, zInside = xInside;
157 for (
Index x = 0; x != (1 << NodeT::LOG2DIM); ++x) {
158 const int x00 = x << (2 * NodeT::LOG2DIM);
159 if (childMask.isOn(x00)) xInside = table[x00].getChild()->getLastValue()<0;
161 for (
Index y = 0; y != (1 << NodeT::LOG2DIM); ++y) {
162 const Index xy0 = x00 + (y << NodeT::LOG2DIM);
163 if (childMask.isOn(xy0)) yInside = table[xy0].getChild()->getLastValue()<0;
165 for (
Index z = 0; z != (1 << NodeT::LOG2DIM); ++z) {
166 const Index xyz = xy0 + z;
167 if (childMask.isOn(xyz)) {
168 zInside = table[xyz].getChild()->getLastValue()<0;
170 table[xyz].setValue(zInside ? mInside : mOutside);
176 const ValueT v = table[0].getValue()<0 ? mInside : mOutside;
177 for (
Index i = 0; i < NodeT::NUM_VALUES; ++i) table[i].setValue(v);
184 if (RootT::LEVEL < mMinLevel)
return;
185 using ChildT =
typename RootT::ChildNodeType;
187 std::map<Coord, ChildT*> nodeKeys;
188 typename RootT::ChildOnIter it = root.beginChildOn();
189 for (; it; ++it) nodeKeys.insert(std::pair<Coord, ChildT*>(it.getCoord(), &(*it)));
190 static const Index DIM = RootT::ChildNodeType::DIM;
194 typename std::map<Coord, ChildT*>::const_iterator b = nodeKeys.begin(), e = nodeKeys.end();
195 if ( b == e )
return;
196 for (
typename std::map<Coord, ChildT*>::const_iterator a = b++; b != e; ++a, ++b) {
197 Coord d = b->first - a->first;
198 if (d[0]!=0 || d[1]!=0 || d[2]==
Int32(DIM))
continue;
199 const ValueT fill[] = { a->second->getLastValue(), b->second->getFirstValue() };
200 if (!(fill[0] < 0) || !(fill[1] < 0))
continue;
201 Coord c = a->first + Coord(0u, 0u, DIM);
202 for (; c[2] != b->first[2]; c[2] += DIM) root.addTile(c, mInside,
false);
204 root.setBackground(mOutside,
false);
208 const ValueT mOutside, mInside;
209 const Index mMinLevel;
216 template<
typename TreeOrLeafManagerT>
218 typename std::enable_if<std::is_signed<typename TreeOrLeafManagerT::ValueType>::value,
void>::type
219 doSignedFloodFill(TreeOrLeafManagerT& tree,
220 typename TreeOrLeafManagerT::ValueType outsideValue,
221 typename TreeOrLeafManagerT::ValueType insideValue,
232 template <
typename TreeOrLeafManagerT>
234 typename std::enable_if<!std::is_signed<typename TreeOrLeafManagerT::ValueType>::value,
void>::type
235 doSignedFloodFill(TreeOrLeafManagerT&,
236 const typename TreeOrLeafManagerT::ValueType&,
237 const typename TreeOrLeafManagerT::ValueType&,
243 "signedFloodFill is supported only for signed value grids");
251 template <
typename TreeOrLeafManagerT>
254 TreeOrLeafManagerT& tree,
255 const typename TreeOrLeafManagerT::ValueType& outsideValue,
256 const typename TreeOrLeafManagerT::ValueType& insideValue,
261 doSignedFloodFill(tree, outsideValue, insideValue, threaded, grainSize, minLevel);
265 template <
typename TreeOrLeafManagerT>
272 const typename TreeOrLeafManagerT::ValueType v = tree.root().background();
273 doSignedFloodFill(tree, v,
math::negative(v), threaded, grainSize, minLevel);
282 #ifdef OPENVDB_USE_EXPLICIT_INSTANTIATION 284 #ifdef OPENVDB_INSTANTIATE_SIGNEDFLOODFILL 288 #define _FUNCTION(TreeT) \ 289 void signedFloodFill(TreeT&, bool, size_t, Index) 293 #define _FUNCTION(TreeT) \ 294 void signedFloodFill(tree::LeafManager<TreeT>&, bool, size_t, Index) 298 #define _FUNCTION(TreeT) \ 299 void signedFloodFillWithValues(TreeT&, const TreeT::ValueType&, const TreeT::ValueType&, bool, size_t, Index) 303 #define _FUNCTION(TreeT) \ 304 void signedFloodFillWithValues(tree::LeafManager<TreeT>&, const TreeT::ValueType&, const TreeT::ValueType&, bool, size_t, Index) 308 #endif // OPENVDB_USE_EXPLICIT_INSTANTIATION 315 #endif // OPENVDB_TOOLS_RESETBACKGROUND_HAS_BEEN_INCLUDED 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:31
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:74
Coord Abs(const Coord &xyz)
Definition: Coord.h:518
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
int32_t Int32
Definition: Types.h:56
Index32 Index
Definition: Types.h:54
T negative(const T &val)
Return the unary negation of the given value.
Definition: Math.h:128
void foreachBottomUp(const NodeOp &op, bool threaded=true, size_t grainSize=1)
Threaded method that applies a user-supplied functor to all the nodes in the tree.
Definition: NodeManager.h:625
Definition: Exceptions.h:13
Definition: Exceptions.h:64
#define OPENVDB_REAL_TREE_INSTANTIATE(Function)
Definition: version.h.in:162
NodeManager produces linear arrays of all tree nodes allowing for efficient threading and bottom-up p...
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:121
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:218