1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3 
4 #include <openvdb/openvdb.h>
5 #include <openvdb/math/Math.h> // for math::Random01
6 #include <openvdb/tools/PointsToMask.h>
7 #include <openvdb/util/CpuTimer.h>
8 #include "gtest/gtest.h"
9 #include <vector>
10 #include <algorithm>
11 #include <cmath>
12 #include "util.h" // for genPoints
13 
14 
15 struct TestPointsToMask: public ::testing::Test
16 {
17 };
18 
19 
20 ////////////////////////////////////////
21 
22 namespace {
23 
24 class PointList
25 {
26 public:
PointList(const std::vector<openvdb::Vec3R> & points)27     PointList(const std::vector<openvdb::Vec3R>& points) : mPoints(&points) {}
28 
size() const29     size_t size() const { return mPoints->size(); }
30 
getPos(size_t n,openvdb::Vec3R & xyz) const31     void getPos(size_t n, openvdb::Vec3R& xyz) const { xyz = (*mPoints)[n]; }
32 protected:
33     std::vector<openvdb::Vec3R> const * const mPoints;
34 }; // PointList
35 
36 } // namespace
37 
38 
39 
40 ////////////////////////////////////////
41 
42 
TEST_F(TestPointsToMask,testPointsToMask)43 TEST_F(TestPointsToMask, testPointsToMask)
44 {
45     {// BoolGrid
46         // generate one point
47         std::vector<openvdb::Vec3R> points;
48         points.push_back( openvdb::Vec3R(-19.999, 4.50001, 6.71) );
49         //points.push_back( openvdb::Vec3R( 20,-4.5,-5.2) );
50         PointList pointList(points);
51 
52         // construct an empty mask grid
53         openvdb::BoolGrid grid( false );
54         const float voxelSize = 0.1f;
55         grid.setTransform( openvdb::math::Transform::createLinearTransform(voxelSize) );
56         EXPECT_TRUE( grid.empty() );
57 
58         // generate mask from points
59         openvdb::tools::PointsToMask<openvdb::BoolGrid> mask( grid );
60         mask.addPoints( pointList );
61         EXPECT_TRUE(!grid.empty() );
62         EXPECT_EQ( 1, int(grid.activeVoxelCount()) );
63         openvdb::BoolGrid::ValueOnCIter iter = grid.cbeginValueOn();
64         //std::cerr << "Coord = " << iter.getCoord() << std::endl;
65         const openvdb::Coord p(-200, 45, 67);
66         EXPECT_TRUE( iter.getCoord() == p );
67         EXPECT_TRUE(grid.tree().isValueOn( p ) );
68     }
69 
70     {// MaskGrid
71         // generate one point
72         std::vector<openvdb::Vec3R> points;
73         points.push_back( openvdb::Vec3R(-19.999, 4.50001, 6.71) );
74         //points.push_back( openvdb::Vec3R( 20,-4.5,-5.2) );
75         PointList pointList(points);
76 
77         // construct an empty mask grid
78         openvdb::MaskGrid grid( false );
79         const float voxelSize = 0.1f;
80         grid.setTransform( openvdb::math::Transform::createLinearTransform(voxelSize) );
81         EXPECT_TRUE( grid.empty() );
82 
83         // generate mask from points
84         openvdb::tools::PointsToMask<> mask( grid );
85         mask.addPoints( pointList );
86         EXPECT_TRUE(!grid.empty() );
87         EXPECT_EQ( 1, int(grid.activeVoxelCount()) );
88         openvdb::TopologyGrid::ValueOnCIter iter = grid.cbeginValueOn();
89         //std::cerr << "Coord = " << iter.getCoord() << std::endl;
90         const openvdb::Coord p(-200, 45, 67);
91         EXPECT_TRUE( iter.getCoord() == p );
92         EXPECT_TRUE(grid.tree().isValueOn( p ) );
93     }
94 
95 
96     // generate shared transformation
97     openvdb::Index64 voxelCount = 0;
98     const float voxelSize = 0.001f;
99     const openvdb::math::Transform::Ptr xform =
100         openvdb::math::Transform::createLinearTransform(voxelSize);
101 
102     // generate lots of points
103     std::vector<openvdb::Vec3R> points;
104     unittest_util::genPoints(15000000, points);
105     PointList pointList(points);
106 
107     //openvdb::util::CpuTimer timer;
108     {// serial BoolGrid
109         // construct an empty mask grid
110         openvdb::BoolGrid grid( false );
111         grid.setTransform( xform );
112         EXPECT_TRUE( grid.empty() );
113 
114         // generate mask from points
115         openvdb::tools::PointsToMask<openvdb::BoolGrid> mask( grid );
116         //timer.start("\nSerial BoolGrid");
117         mask.addPoints( pointList, 0 );
118         //timer.stop();
119 
120         EXPECT_TRUE(!grid.empty() );
121         //grid.print(std::cerr, 3);
122         voxelCount = grid.activeVoxelCount();
123     }
124     {// parallel BoolGrid
125         // construct an empty mask grid
126         openvdb::BoolGrid grid( false );
127         grid.setTransform( xform );
128         EXPECT_TRUE( grid.empty() );
129 
130         // generate mask from points
131         openvdb::tools::PointsToMask<openvdb::BoolGrid> mask( grid );
132         //timer.start("\nParallel BoolGrid");
133         mask.addPoints( pointList );
134         //timer.stop();
135 
136         EXPECT_TRUE(!grid.empty() );
137         //grid.print(std::cerr, 3);
138         EXPECT_EQ( voxelCount, grid.activeVoxelCount() );
139     }
140     {// parallel MaskGrid
141         // construct an empty mask grid
142         openvdb::MaskGrid grid( false );
143         grid.setTransform( xform );
144         EXPECT_TRUE( grid.empty() );
145 
146         // generate mask from points
147         openvdb::tools::PointsToMask<> mask( grid );
148         //timer.start("\nParallel MaskGrid");
149         mask.addPoints( pointList );
150         //timer.stop();
151 
152         EXPECT_TRUE(!grid.empty() );
153         //grid.print(std::cerr, 3);
154         EXPECT_EQ( voxelCount, grid.activeVoxelCount() );
155     }
156     {// parallel create TopologyGrid
157         //timer.start("\nParallel Create MaskGrid");
158         openvdb::MaskGrid::Ptr grid = openvdb::tools::createPointMask(pointList, *xform);
159         //timer.stop();
160 
161         EXPECT_TRUE(!grid->empty() );
162         //grid->print(std::cerr, 3);
163         EXPECT_EQ( voxelCount, grid->activeVoxelCount() );
164     }
165 }
166