Skip to content

Commit 6add394

Browse files
committed
Add various tests for HalfGrid: LevelSetAdvect, Interpolation, Morphology, Grid, LevelSetUtil, RayIntersector, etc.
Signed-off-by: apradhana <[email protected]>
1 parent aef3050 commit 6add394

16 files changed

+669
-241
lines changed

openvdb/openvdb/Types.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,13 @@ template<typename FromType, typename ToType> struct CopyConstness<const FromType
426426
};
427427
/// @endcond
428428

429+
////////////////////////////////////////
430+
431+
template<class T>
432+
struct is_floating_point : std::is_floating_point<T> { };
433+
434+
template<>
435+
struct is_floating_point<math::half> : std::is_floating_point<float> { };
429436

430437
////////////////////////////////////////
431438

openvdb/openvdb/tools/Diagnostics.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#define OPENVDB_TOOLS_DIAGNOSTICS_HAS_BEEN_INCLUDED
1313

1414
#include <openvdb/Grid.h>
15+
#include <openvdb/Types.h> // for openvdb::is_floating_point
1516
#include <openvdb/math/Math.h>
1617
#include <openvdb/math/Vec3.h>
1718
#include <openvdb/math/Stencils.h>
@@ -428,7 +429,7 @@ template<typename GridT,
428429
struct CheckNormGrad
429430
{
430431
using ValueType = typename GridT::ValueType;
431-
static_assert(std::is_floating_point<ValueType>::value,
432+
static_assert(openvdb::is_floating_point<ValueType>::value,
432433
"openvdb::tools::CheckNormGrad requires a scalar, floating-point grid");
433434
using TileIterT = TreeIterT;
434435
using VoxelIterT = typename tree::IterTraits<typename TreeIterT::NodeT,

openvdb/openvdb/tools/RayIntersector.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ class LevelSetRayIntersector
9292
using TreeT = typename GridT::TreeType;
9393

9494
static_assert(NodeLevel >= -1 && NodeLevel < int(TreeT::DEPTH)-1, "NodeLevel out of range");
95-
static_assert(std::is_floating_point<ValueT>::value,
95+
static_assert(openvdb::is_floating_point<ValueT>::value,
9696
"level set grids must have scalar, floating-point value types");
9797

9898
/// @brief Constructor

openvdb/openvdb/unittest/TestDiagnostics.cc

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,29 @@ TEST_F(TestDiagnostics, testDiagnose)
262262
}
263263
}// testDiagnose
264264

265+
TEST_F(TestDiagnostics, testDiagnoseHalf)
266+
{
267+
using namespace openvdb;
268+
using half = openvdb::math::half;
269+
270+
const half radius = 4.3f;
271+
const openvdb::Vec3H center(half(15.8), half(13.2), half(16.7));
272+
const half voxelSize = 0.1f, width = 2.0f, gamma=voxelSize*width;
273+
274+
HalfGrid::Ptr gridSphere =
275+
tools::createLevelSetSphere<HalfGrid>(radius, center, voxelSize, width);
276+
277+
{// check norm of gradient of sphere w/o mask
278+
tools::CheckNormGrad<HalfGrid> c(*gridSphere, 0.75f, 1.25f);
279+
tools::Diagnose<HalfGrid> d(*gridSphere);
280+
std::string str = d.check(c, false, true, false, false);
281+
//std::cerr << "NormGrad:\n" << str;
282+
EXPECT_TRUE(str.empty());
283+
EXPECT_EQ(0, int(d.valueCount()));
284+
EXPECT_EQ(0, int(d.failureCount()));
285+
}
286+
}// testDiagnoseHalf
287+
265288
TEST_F(TestDiagnostics, testCheckLevelSet)
266289
{
267290
using namespace openvdb;

openvdb/openvdb/unittest/TestGrid.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class ProxyTree: public openvdb::TreeBase
2929
public:
3030
using ValueType = int;
3131
using BuildType = int;
32+
using ComputeType = int;
3233
using LeafNodeType = void;
3334
using ValueAllCIter = void;
3435
using ValueAllIter = void;

openvdb/openvdb/unittest/TestLevelSetRayIntersector.cc

Lines changed: 62 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ class TestLevelSetRayIntersector : public ::testing::Test
3434
};
3535

3636

37-
TEST_F(TestLevelSetRayIntersector, tests)
37+
template<typename GridT>
38+
void
39+
testLevelSetRayIntersectorImpl()
3840
{
3941
using namespace openvdb;
4042
typedef math::Ray<double> RayT;
@@ -45,9 +47,9 @@ TEST_F(TestLevelSetRayIntersector, tests)
4547
const Vec3f c(20.0f, 0.0f, 0.0f);
4648
const float s = 0.5f, w = 2.0f;
4749

48-
FloatGrid::Ptr ls = tools::createLevelSetSphere<FloatGrid>(r, c, s, w);
50+
typename GridT::Ptr ls = tools::createLevelSetSphere<GridT>(r, c, s, w);
4951

50-
tools::LevelSetRayIntersector<FloatGrid> lsri(*ls);
52+
tools::LevelSetRayIntersector<GridT> lsri(*ls);
5153

5254
const Vec3T dir(1.0, 0.0, 0.0);
5355
const Vec3T eye(2.0, 0.0, 0.0);
@@ -73,9 +75,9 @@ TEST_F(TestLevelSetRayIntersector, tests)
7375
const Vec3f c(20.0f, 0.0f, 0.0f);
7476
const float s = 0.5f, w = 2.0f;
7577

76-
FloatGrid::Ptr ls = tools::createLevelSetSphere<FloatGrid>(r, c, s, w);
78+
typename GridT::Ptr ls = tools::createLevelSetSphere<GridT>(r, c, s, w);
7779

78-
tools::LevelSetRayIntersector<FloatGrid> lsri(*ls);
80+
tools::LevelSetRayIntersector<GridT> lsri(*ls);
7981

8082
const Vec3T dir(1.0,-0.0,-0.0);
8183
const Vec3T eye(2.0, 0.0, 0.0);
@@ -101,74 +103,79 @@ TEST_F(TestLevelSetRayIntersector, tests)
101103
const Vec3f c(0.0f, 20.0f, 0.0f);
102104
const float s = 1.5f, w = 2.0f;
103105

104-
FloatGrid::Ptr ls = tools::createLevelSetSphere<FloatGrid>(r, c, s, w);
106+
typename GridT::Ptr ls = tools::createLevelSetSphere<GridT>(r, c, s, w);
105107

106-
tools::LevelSetRayIntersector<FloatGrid> lsri(*ls);
108+
tools::LevelSetRayIntersector<GridT> lsri(*ls);
107109

108110
const Vec3T dir(0.0, 1.0, 0.0);
109111
const Vec3T eye(0.0,-2.0, 0.0);
110112
RayT ray(eye, dir);
111113
Vec3T xyz(0);
112114
Real time = 0;
115+
constexpr double tolerance = std::is_floating_point_v<typename GridT::ValueType> ? 1e-6 : 1e-3;
116+
113117
EXPECT_TRUE(lsri.intersectsWS(ray, xyz, time));
114-
ASSERT_DOUBLES_APPROX_EQUAL( 0.0, xyz[0]);
115-
ASSERT_DOUBLES_APPROX_EQUAL(15.0, xyz[1]);
116-
ASSERT_DOUBLES_APPROX_EQUAL( 0.0, xyz[2]);
117-
ASSERT_DOUBLES_APPROX_EQUAL(17.0, time);
118+
EXPECT_NEAR( 0.0, xyz[0], tolerance);
119+
EXPECT_NEAR(15.0, xyz[1], tolerance);
120+
EXPECT_NEAR( 0.0, xyz[2], tolerance);
121+
EXPECT_NEAR(17.0, time, tolerance);
118122
double t0=0, t1=0;
119123
EXPECT_TRUE(ray.intersects(c, r, t0, t1));
120-
ASSERT_DOUBLES_APPROX_EQUAL(t0, time);
124+
EXPECT_NEAR(t0, time, tolerance);
121125
//std::cerr << "\nray("<<t0<<")="<<ray(t0)<<std::endl;
122126
//std::cerr << "Intersection at xyz = " << xyz << std::endl;
123-
ASSERT_DOUBLES_APPROX_EQUAL( 0.0, ray(t0)[0]);
124-
ASSERT_DOUBLES_APPROX_EQUAL(15.0, ray(t0)[1]);
125-
ASSERT_DOUBLES_APPROX_EQUAL( 0.0, ray(t0)[2]);
127+
EXPECT_NEAR( 0.0, ray(t0)[0], tolerance);
128+
EXPECT_NEAR(15.0, ray(t0)[1], tolerance);
129+
EXPECT_NEAR( 0.0, ray(t0)[2], tolerance);
126130
}
127131

128132
{// voxel intersection against a level set sphere
129133
const float r = 5.0f;
130134
const Vec3f c(0.0f, 20.0f, 0.0f);
131135
const float s = 1.5f, w = 2.0f;
132136

133-
FloatGrid::Ptr ls = tools::createLevelSetSphere<FloatGrid>(r, c, s, w);
137+
typename GridT::Ptr ls = tools::createLevelSetSphere<GridT>(r, c, s, w);
134138

135-
tools::LevelSetRayIntersector<FloatGrid> lsri(*ls);
139+
tools::LevelSetRayIntersector<GridT> lsri(*ls);
136140

137141
const Vec3T dir(-0.0, 1.0,-0.0);
138142
const Vec3T eye( 0.0,-2.0, 0.0);
139143
RayT ray(eye, dir);
140144
Vec3T xyz(0);
141145
Real time = 0;
146+
constexpr double tolerance = std::is_floating_point_v<typename GridT::ValueType> ? 1e-6 : 1e-3;
147+
142148
EXPECT_TRUE(lsri.intersectsWS(ray, xyz, time));
143-
ASSERT_DOUBLES_APPROX_EQUAL( 0.0, xyz[0]);
144-
ASSERT_DOUBLES_APPROX_EQUAL(15.0, xyz[1]);
145-
ASSERT_DOUBLES_APPROX_EQUAL( 0.0, xyz[2]);
146-
ASSERT_DOUBLES_APPROX_EQUAL(17.0, time);
149+
EXPECT_NEAR( 0.0, xyz[0], tolerance);
150+
EXPECT_NEAR(15.0, xyz[1], tolerance);
151+
EXPECT_NEAR( 0.0, xyz[2], tolerance);
152+
EXPECT_NEAR(17.0, time, tolerance);
147153
double t0=0, t1=0;
148154
EXPECT_TRUE(ray.intersects(c, r, t0, t1));
149-
ASSERT_DOUBLES_APPROX_EQUAL(t0, time);
155+
EXPECT_NEAR(t0, time, tolerance);
150156
//std::cerr << "\nray("<<t0<<")="<<ray(t0)<<std::endl;
151157
//std::cerr << "Intersection at xyz = " << xyz << std::endl;
152-
ASSERT_DOUBLES_APPROX_EQUAL( 0.0, ray(t0)[0]);
153-
ASSERT_DOUBLES_APPROX_EQUAL(15.0, ray(t0)[1]);
154-
ASSERT_DOUBLES_APPROX_EQUAL( 0.0, ray(t0)[2]);
158+
EXPECT_NEAR( 0.0, ray(t0)[0], tolerance);
159+
EXPECT_NEAR(15.0, ray(t0)[1], tolerance);
160+
EXPECT_NEAR( 0.0, ray(t0)[2], tolerance);
155161
}
156162

157163
{// voxel intersection against a level set sphere
158164
const float r = 5.0f;
159165
const Vec3f c(0.0f, 0.0f, 20.0f);
160166
const float s = 1.0f, w = 3.0f;
161167

162-
FloatGrid::Ptr ls = tools::createLevelSetSphere<FloatGrid>(r, c, s, w);
168+
typename GridT::Ptr ls = tools::createLevelSetSphere<GridT>(r, c, s, w);
163169

164-
typedef tools::LinearSearchImpl<FloatGrid> SearchImplT;
165-
tools::LevelSetRayIntersector<FloatGrid, SearchImplT, -1> lsri(*ls);
170+
typedef tools::LinearSearchImpl<GridT> SearchImplT;
171+
tools::LevelSetRayIntersector<GridT, SearchImplT, -1> lsri(*ls);
166172

167173
const Vec3T dir(0.0, 0.0, 1.0);
168174
const Vec3T eye(0.0, 0.0, 4.0);
169175
RayT ray(eye, dir);
170176
Vec3T xyz(0);
171177
Real time = 0;
178+
172179
EXPECT_TRUE(lsri.intersectsWS(ray, xyz, time));
173180
ASSERT_DOUBLES_APPROX_EQUAL( 0.0, xyz[0]);
174181
ASSERT_DOUBLES_APPROX_EQUAL( 0.0, xyz[1]);
@@ -189,10 +196,10 @@ TEST_F(TestLevelSetRayIntersector, tests)
189196
const Vec3f c(0.0f, 0.0f, 20.0f);
190197
const float s = 1.0f, w = 3.0f;
191198

192-
FloatGrid::Ptr ls = tools::createLevelSetSphere<FloatGrid>(r, c, s, w);
199+
typename GridT::Ptr ls = tools::createLevelSetSphere<GridT>(r, c, s, w);
193200

194-
typedef tools::LinearSearchImpl<FloatGrid> SearchImplT;
195-
tools::LevelSetRayIntersector<FloatGrid, SearchImplT, -1> lsri(*ls);
201+
typedef tools::LinearSearchImpl<GridT> SearchImplT;
202+
tools::LevelSetRayIntersector<GridT, SearchImplT, -1> lsri(*ls);
196203

197204
const Vec3T dir(-0.0,-0.0, 1.0);
198205
const Vec3T eye( 0.0, 0.0, 4.0);
@@ -220,10 +227,10 @@ TEST_F(TestLevelSetRayIntersector, tests)
220227
const Vec3f c(0.0f, 0.0f, 20.0f);
221228
const float s = 1.0f, w = 3.0f;
222229

223-
FloatGrid::Ptr ls = tools::createLevelSetSphere<FloatGrid>(r, c, s, w);
230+
typename GridT::Ptr ls = tools::createLevelSetSphere<GridT>(r, c, s, w);
224231

225-
typedef tools::LinearSearchImpl<FloatGrid> SearchImplT;
226-
tools::LevelSetRayIntersector<FloatGrid, SearchImplT, -1> lsri(*ls);
232+
typedef tools::LinearSearchImpl<GridT> SearchImplT;
233+
tools::LevelSetRayIntersector<GridT, SearchImplT, -1> lsri(*ls);
227234

228235
const Vec3T dir(-0.0,-0.0, 1.0);
229236
const Vec3T eye( 0.0, 0.0, 4.0);
@@ -251,41 +258,43 @@ TEST_F(TestLevelSetRayIntersector, tests)
251258
const Vec3f c(10.0f, 10.0f, 10.0f);
252259
const float s = 1.0f, w = 3.0f;
253260

254-
FloatGrid::Ptr ls = tools::createLevelSetSphere<FloatGrid>(r, c, s, w);
261+
typename GridT::Ptr ls = tools::createLevelSetSphere<GridT>(r, c, s, w);
255262

256-
tools::LevelSetRayIntersector<FloatGrid> lsri(*ls);
263+
tools::LevelSetRayIntersector<GridT> lsri(*ls);
257264

258265
Vec3T dir(1.0, 1.0, 1.0); dir.normalize();
259266
const Vec3T eye(0.0, 0.0, 0.0);
260267
RayT ray(eye, dir);
261268
//std::cerr << "ray: " << ray << std::endl;
262269
Vec3T xyz(0);
263270
Real time = 0;
271+
constexpr double tolerance = std::is_floating_point_v<typename GridT::ValueType> ? 1e-6 : 2e-5;
272+
264273
EXPECT_TRUE(lsri.intersectsWS(ray, xyz, time));
265274
//std::cerr << "\nIntersection at xyz = " << xyz << std::endl;
266275
//analytical intersection test
267276
double t0=0, t1=0;
268277
EXPECT_TRUE(ray.intersects(c, r, t0, t1));
269-
ASSERT_DOUBLES_APPROX_EQUAL(t0, time);
270-
ASSERT_DOUBLES_APPROX_EQUAL((ray(t0)-c).length()-r, 0);
271-
ASSERT_DOUBLES_APPROX_EQUAL((ray(t1)-c).length()-r, 0);
278+
EXPECT_NEAR(t0, time, tolerance);
279+
EXPECT_NEAR((ray(t0)-c).length()-r, 0, tolerance);
280+
EXPECT_NEAR((ray(t1)-c).length()-r, 0, tolerance);
272281
//std::cerr << "\nray("<<t0<<")="<<ray(t0)<<std::endl;
273282
//std::cerr << "\nray("<<t1<<")="<<ray(t1)<<std::endl;
274283
const Vec3T delta = xyz - ray(t0);
275284
//std::cerr << "delta = " << delta << std::endl;
276285
//std::cerr << "|delta|/dx=" << (delta.length()/ls->voxelSize()[0]) << std::endl;
277-
ASSERT_DOUBLES_APPROX_EQUAL(0, delta.length());
286+
EXPECT_NEAR(0, delta.length(), tolerance);
278287
}
279288

280289
{// test intersections against a high-resolution level set sphere @1024^3
281290
const float r = 5.0f;
282291
const Vec3f c(10.0f, 10.0f, 20.0f);
283292
const float s = 0.01f, w = 2.0f;
284293
double t0=0, t1=0;
285-
FloatGrid::Ptr ls = tools::createLevelSetSphere<FloatGrid>(r, c, s, w);
294+
typename GridT::Ptr ls = tools::createLevelSetSphere<GridT>(r, c, s, w);
286295

287-
typedef tools::LinearSearchImpl<FloatGrid, /*iterations=*/2> SearchImplT;
288-
tools::LevelSetRayIntersector<FloatGrid, SearchImplT> lsri(*ls);
296+
typedef tools::LinearSearchImpl<GridT, /*iterations=*/2> SearchImplT;
297+
tools::LevelSetRayIntersector<GridT, SearchImplT> lsri(*ls);
289298

290299
Vec3T xyz(0);
291300
Real time = 0;
@@ -308,6 +317,16 @@ TEST_F(TestLevelSetRayIntersector, tests)
308317
}
309318
}
310319

320+
321+
TEST_F(TestLevelSetRayIntersector, testLevelSetRayIntersectorFloat)
322+
{
323+
testLevelSetRayIntersectorImpl<openvdb::FloatGrid>();
324+
}
325+
326+
TEST_F(TestLevelSetRayIntersector, testLevelSetRayIntersectorHalf)
327+
{
328+
testLevelSetRayIntersectorImpl<openvdb::HalfGrid>();
329+
}
311330
#ifdef STATS_TEST
312331
TEST_F(TestLevelSetRayIntersector, stats)
313332
{

openvdb/openvdb/unittest/TestLevelSetUtil.cc

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,25 +19,39 @@ class TestLevelSetUtil: public ::testing::Test
1919

2020
////////////////////////////////////////
2121

22-
TEST_F(TestLevelSetUtil, testSDFToFogVolume)
22+
template<typename GridT>
23+
void
24+
testSDFToFogVolumeImpl()
2325
{
24-
openvdb::FloatGrid::Ptr grid = openvdb::FloatGrid::create(10.0);
26+
using ValueT = typename GridT::ValueType;
2527

26-
grid->fill(openvdb::CoordBBox(openvdb::Coord(-100), openvdb::Coord(100)), 9.0);
27-
grid->fill(openvdb::CoordBBox(openvdb::Coord(-50), openvdb::Coord(50)), -9.0);
28+
typename GridT::Ptr grid = GridT::create(ValueT(10.0));
29+
30+
grid->fill(openvdb::CoordBBox(openvdb::Coord(-100), openvdb::Coord(100)), ValueT(9.0));
31+
grid->fill(openvdb::CoordBBox(openvdb::Coord(-50), openvdb::Coord(50)), ValueT(-9.0));
2832

2933

3034
openvdb::tools::sdfToFogVolume(*grid);
3135

3236
EXPECT_TRUE(grid->background() < 1e-7);
3337

34-
openvdb::FloatGrid::ValueOnIter iter = grid->beginValueOn();
38+
typename GridT::ValueOnIter iter = grid->beginValueOn();
3539
for (; iter; ++iter) {
3640
EXPECT_TRUE(iter.getValue() > 0.0);
3741
EXPECT_TRUE(std::abs(iter.getValue() - 1.0) < 1e-7);
3842
}
3943
}
4044

45+
TEST_F(TestLevelSetUtil, testSDFToFogVolumeFloat)
46+
{
47+
testSDFToFogVolumeImpl<openvdb::FloatGrid>();
48+
}
49+
50+
TEST_F(TestLevelSetUtil, testSDFToFogVolumeHalf)
51+
{
52+
testSDFToFogVolumeImpl<openvdb::HalfGrid>();
53+
}
54+
4155

4256
TEST_F(TestLevelSetUtil, testSDFInteriorMask)
4357
{

0 commit comments

Comments
 (0)