39 #ifndef OPENVDB_TOOLS_SIGNEDFLOODFILL_HAS_BEEN_INCLUDED
40 #define OPENVDB_TOOLS_SIGNEDFLOODFILL_HAS_BEEN_INCLUDED
42 #include <boost/utility/enable_if.hpp>
43 #include <openvdb/math/Math.h>
44 #include <openvdb/Types.h>
45 #include <boost/static_assert.hpp>
46 #include <boost/type_traits/is_floating_point.hpp>
47 #include <openvdb/tree/NodeManager.h>
69 template<
typename TreeOrLeafManagerT>
71 signedFloodFill(TreeOrLeafManagerT& tree,
bool threaded =
true,
size_t grainSize = 1);
91 template<
typename TreeOrLeafManagerT>
94 TreeOrLeafManagerT& tree,
95 const typename TreeOrLeafManagerT::ValueType& outsideWidth,
96 const typename TreeOrLeafManagerT::ValueType& insideWidth,
98 size_t grainSize = 1);
104 template<
typename TreeOrLeafManagerT>
108 typedef typename TreeOrLeafManagerT::ValueType
ValueT;
109 typedef typename TreeOrLeafManagerT::RootNodeType
RootT;
110 typedef typename TreeOrLeafManagerT::LeafNodeType
LeafT;
111 BOOST_STATIC_ASSERT(boost::is_floating_point<ValueT>::value);
114 : mOutside(math::
Abs(tree.background()))
120 : mOutside(math::
Abs(background))
126 : mOutside(math::
Abs(outsideValue))
134 #ifndef OPENVDB_2_ABI_COMPATIBLE
135 if (!leaf.allocate())
return;
137 const typename LeafT::NodeMaskType& valueMask = leaf.getValueMask();
139 typename LeafT::ValueType* buffer =
140 const_cast<typename LeafT::ValueType*
>(&(leaf.getFirstValue()));
142 const Index first = valueMask.findFirstOn();
143 if (first < LeafT::SIZE) {
144 bool xInside = buffer[first]<0, yInside = xInside, zInside = xInside;
145 for (
Index x = 0; x != (1 << LeafT::LOG2DIM); ++x) {
146 const Index x00 = x << (2 * LeafT::LOG2DIM);
147 if (valueMask.isOn(x00)) xInside = buffer[x00] < 0;
149 for (
Index y = 0; y != (1 << LeafT::LOG2DIM); ++y) {
150 const Index xy0 = x00 + (y << LeafT::LOG2DIM);
151 if (valueMask.isOn(xy0)) yInside = buffer[xy0] < 0;
153 for (
Index z = 0; z != (1 << LeafT::LOG2DIM); ++z) {
154 const Index xyz = xy0 + z;
155 if (valueMask.isOn(xyz)) {
156 zInside = buffer[xyz] < 0;
158 buffer[xyz] = zInside ? mInside : mOutside;
164 leaf.fill(buffer[0] < 0 ? mInside : mOutside);
169 template<
typename NodeT>
173 const typename NodeT::NodeMaskType& childMask = node.getChildMask();
175 typename NodeT::UnionType* table =
const_cast<typename NodeT::UnionType*
>(node.getTable());
177 const Index first = childMask.findFirstOn();
178 if (first < NodeT::NUM_VALUES) {
179 bool xInside = table[first].getChild()->getFirstValue()<0;
180 bool yInside = xInside, zInside = xInside;
181 for (
Index x = 0; x != (1 << NodeT::LOG2DIM); ++x) {
182 const int x00 = x << (2 * NodeT::LOG2DIM);
183 if (childMask.isOn(x00)) xInside = table[x00].getChild()->getLastValue()<0;
185 for (
Index y = 0; y != (1 << NodeT::LOG2DIM); ++y) {
186 const Index xy0 = x00 + (y << NodeT::LOG2DIM);
187 if (childMask.isOn(xy0)) yInside = table[xy0].getChild()->getLastValue()<0;
189 for (
Index z = 0; z != (1 << NodeT::LOG2DIM); ++z) {
190 const Index xyz = xy0 + z;
191 if (childMask.isOn(xyz)) {
192 zInside = table[xyz].getChild()->getLastValue()<0;
194 table[xyz].setValue(zInside ? mInside : mOutside);
200 const ValueT v = table[0].getValue()<0 ? mInside : mOutside;
201 for (
Index i = 0; i < NodeT::NUM_VALUES; ++i) table[i].setValue(v);
208 typedef typename RootT::ChildNodeType ChildT;
210 std::map<Coord, ChildT*> nodeKeys;
211 typename RootT::ChildOnIter it = root.beginChildOn();
212 for (; it; ++it) nodeKeys.insert(std::pair<Coord, ChildT*>(it.getCoord(), &(*it)));
213 static const Index DIM = RootT::ChildNodeType::DIM;
217 typename std::map<Coord, ChildT*>::const_iterator b = nodeKeys.begin(), e = nodeKeys.end();
218 if ( b == e )
return;
219 for (
typename std::map<Coord, ChildT*>::const_iterator a = b++; b != e; ++a, ++b) {
220 Coord d = b->first - a->first;
221 if (d[0]!=0 || d[1]!=0 || d[2]==
Int32(DIM))
continue;
222 const ValueT fill[] = { a->second->getLastValue(), b->second->getFirstValue() };
223 if (!(fill[0] < 0) || !(fill[1] < 0))
continue;
224 Coord c = a->first + Coord(0u, 0u, DIM);
225 for (; c[2] != b->first[2]; c[2] += DIM) root.addTile(c, mInside,
false);
227 root.setBackground(mOutside,
false);
231 const ValueT mOutside, mInside;
235 template<
typename TreeOrLeafManagerT>
237 typename boost::enable_if<
typename boost::is_floating_point<
238 typename TreeOrLeafManagerT::ValueType>::type>::type
240 typename TreeOrLeafManagerT::ValueType outsideValue,
241 typename TreeOrLeafManagerT::ValueType insideValue,
251 template <
typename TreeOrLeafManagerT>
253 typename boost::disable_if<
typename boost::is_floating_point<
254 typename TreeOrLeafManagerT::ValueType>::type>::type
256 const typename TreeOrLeafManagerT::ValueType&,
257 const typename TreeOrLeafManagerT::ValueType&,
262 "signedFloodFill is supported only for scalar, floating-point grids");
267 template <
typename TreeOrLeafManagerT>
270 TreeOrLeafManagerT& tree,
271 const typename TreeOrLeafManagerT::ValueType& outsideValue,
272 const typename TreeOrLeafManagerT::ValueType& insideValue,
280 template <
typename TreeOrLeafManagerT>
286 const typename TreeOrLeafManagerT::ValueType v = tree.root().background();
294 #endif // OPENVDB_TOOLS_RESETBACKGROUND_HAS_BEEN_INCLUDED
int32_t Abs(int32_t i)
Return the absolute value of the given quantity.
Definition: Math.h:284
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:97
void processBottomUp(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:401
int32_t Int32
Definition: Types.h:61
#define OPENVDB_VERSION_NAME
Definition: version.h:43
Index32 Index
Definition: Types.h:59
Definition: Exceptions.h:87
Definition: Exceptions.h:39
T negative(const T &val)
Return the unary negation of the given value.
Definition: Math.h:107
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:56
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71