Skip to content

Commit 8b727c6

Browse files
authored
Merge pull request #1295 from Idclip/minmax_fix
Fixed a bug in new minMax()
2 parents 69e7040 + d13ae10 commit 8b727c6

File tree

2 files changed

+57
-37
lines changed

2 files changed

+57
-37
lines changed

openvdb/openvdb/tools/Count.h

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -329,24 +329,18 @@ struct MinMaxValuesOp
329329
using ValueT = typename TreeType::ValueType;
330330

331331
explicit MinMaxValuesOp()
332-
: min(zeroVal<ValueT>())
333-
, max(zeroVal<ValueT>())
334-
, seen_value(false)
335-
{
336-
}
332+
: min(zeroVal<ValueT>())
333+
, max(zeroVal<ValueT>())
334+
, seen_value(false) {}
337335

338-
MinMaxValuesOp(const MinMaxValuesOp& other, tbb::split)
339-
: min(other.min)
340-
, max(other.max)
341-
, seen_value(other.seen_value)
342-
{
343-
}
336+
MinMaxValuesOp(const MinMaxValuesOp&, tbb::split)
337+
: MinMaxValuesOp() {}
344338

345339
template <typename NodeType>
346340
bool operator()(NodeType& node, size_t)
347341
{
348342
if (auto iter = node.cbeginValueOn()) {
349-
if(!seen_value) {
343+
if (!seen_value) {
350344
seen_value = true;
351345
min = max = *iter;
352346
++iter;
@@ -368,14 +362,20 @@ struct MinMaxValuesOp
368362

369363
bool join(const MinMaxValuesOp& other)
370364
{
371-
if (math::cwiseLessThan(other.min, min))
372-
min = other.min;
365+
if (!other.seen_value) return true;
373366

374-
if (math::cwiseGreaterThan(other.max, max))
367+
if (!seen_value) {
368+
min = other.min;
375369
max = other.max;
370+
}
371+
else {
372+
if (math::cwiseLessThan(other.min, min))
373+
min = other.min;
374+
if (math::cwiseGreaterThan(other.max, max))
375+
max = other.max;
376+
}
376377

377-
seen_value |= other.seen_value;
378-
378+
seen_value = true;
379379
return true;
380380
}
381381

openvdb/openvdb/unittest/TestCount.cc

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -241,44 +241,64 @@ minMaxTest()
241241
{
242242
using ValueT = typename TreeT::ValueType;
243243

244-
struct Local {
245-
static bool isEqual(const ValueT& a, const ValueT& b) {
246-
using namespace openvdb; // for operator>()
247-
return !(math::Abs(a - b) > zeroVal<ValueT>());
248-
}
249-
};
250-
251244
const ValueT
252245
zero = openvdb::zeroVal<ValueT>(),
253246
minusTwo = zero + (-2),
254247
plusTwo = zero + 2,
255-
five = zero + 5;
248+
five = zero + 5,
249+
ten = zero + 10,
250+
twenty = zero + 20;
251+
252+
static constexpr int64_t DIM = TreeT::LeafNodeType::DIM;
256253

257254
TreeT tree(/*background=*/five);
258255

259256
// No set voxels (defaults to min = max = zero)
260257
openvdb::math::MinMax<ValueT> extrema = openvdb::tools::minMax(tree);
261-
EXPECT_TRUE(Local::isEqual(extrema.min(), zero));
262-
EXPECT_TRUE(Local::isEqual(extrema.max(), zero));
258+
EXPECT_EQ(zero, extrema.min());
259+
EXPECT_EQ(zero, extrema.max());
263260

264261
// Only one set voxel
265-
tree.setValue(openvdb::Coord(0, 0, 0), minusTwo);
262+
tree.setValue(openvdb::Coord(0), minusTwo);
266263
extrema = openvdb::tools::minMax(tree);
267-
EXPECT_TRUE(Local::isEqual(extrema.min(), minusTwo));
268-
EXPECT_TRUE(Local::isEqual(extrema.max(), minusTwo));
264+
EXPECT_EQ(minusTwo, extrema.min());
265+
EXPECT_EQ(minusTwo, extrema.max());
269266

270267
// Multiple set voxels, single value
271-
tree.setValue(openvdb::Coord(10, 10, 10), minusTwo);
268+
tree.setValue(openvdb::Coord(DIM), minusTwo);
272269
extrema = openvdb::tools::minMax(tree);
273-
EXPECT_TRUE(Local::isEqual(extrema.min(), minusTwo));
274-
EXPECT_TRUE(Local::isEqual(extrema.max(), minusTwo));
270+
EXPECT_EQ(minusTwo, extrema.min());
271+
EXPECT_EQ(minusTwo, extrema.max());
275272

276273
// Multiple set voxels, multiple values
277-
tree.setValue(openvdb::Coord(10, 10, 10), plusTwo);
278-
tree.setValue(openvdb::Coord(-10, -10, -10), zero);
274+
tree.setValue(openvdb::Coord(DIM), plusTwo);
275+
tree.setValue(openvdb::Coord(DIM*2), zero);
276+
extrema = openvdb::tools::minMax(tree);
277+
EXPECT_EQ(minusTwo, extrema.min());
278+
EXPECT_EQ(plusTwo, extrema.max());
279+
280+
// add some empty leaf nodes to test the join op
281+
tree.setValueOnly(openvdb::Coord(DIM*3), ten);
282+
tree.setValueOnly(openvdb::Coord(DIM*4),-ten);
283+
extrema = openvdb::tools::minMax(tree);
284+
EXPECT_EQ(minusTwo, extrema.min());
285+
EXPECT_EQ(plusTwo, extrema.max());
286+
287+
tree.clear();
288+
289+
// test tiles
290+
using NodeChainT = typename TreeT::RootNodeType::NodeChainType;
291+
using ChildT1 = typename NodeChainT::template Get<1>; // Leaf parent
292+
using ChildT2 = typename NodeChainT::template Get<2>; // ChildT1 parent
293+
tree.addTile(ChildT2::LEVEL, openvdb::Coord(0), -ten, true);
294+
tree.addTile(ChildT2::LEVEL, openvdb::Coord(ChildT2::DIM), ten, true);
295+
tree.addTile(ChildT1::LEVEL, openvdb::Coord(ChildT2::DIM + ChildT2::DIM), -twenty, false);
296+
tree.setValueOnly(openvdb::Coord(-1), twenty);
297+
tree.setValue(openvdb::Coord(-2), five);
298+
279299
extrema = openvdb::tools::minMax(tree);
280-
EXPECT_TRUE(Local::isEqual(extrema.min(), minusTwo));
281-
EXPECT_TRUE(Local::isEqual(extrema.max(), plusTwo));
300+
EXPECT_EQ(-ten, extrema.min());
301+
EXPECT_EQ( ten, extrema.max());
282302
}
283303

284304
/// Specialization for boolean trees

0 commit comments

Comments
 (0)