1 //============================================================================
2 // Copyright (c) Kitware, Inc.
3 // All rights reserved.
4 // See LICENSE.txt for details.
5 //
6 // This software is distributed WITHOUT ANY WARRANTY; without even
7 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8 // PURPOSE. See the above copyright notice for more information.
9 //============================================================================
10
11 #include <vtkm/worklet/Clip.h>
12
13 #include <vtkm/cont/CellSet.h>
14 #include <vtkm/cont/CellSetExplicit.h>
15 #include <vtkm/cont/CellSetStructured.h>
16 #include <vtkm/cont/CoordinateSystem.h>
17 #include <vtkm/cont/DataSet.h>
18 #include <vtkm/cont/DataSetBuilderExplicit.h>
19 #include <vtkm/cont/DataSetBuilderUniform.h>
20 #include <vtkm/cont/Field.h>
21 #include <vtkm/cont/testing/Testing.h>
22
23 #include <vtkm/ImplicitFunction.h>
24
25 #include <vector>
26
27 using Coord3D = vtkm::Vec3f;
28
29 const vtkm::Float32 clipValue = 0.5;
30
31 template <typename T, typename Storage>
TestArrayHandle(const vtkm::cont::ArrayHandle<T,Storage> & ah,const T * expected,vtkm::Id size)32 bool TestArrayHandle(const vtkm::cont::ArrayHandle<T, Storage>& ah,
33 const T* expected,
34 vtkm::Id size)
35 {
36 if (size != ah.GetNumberOfValues())
37 {
38 return false;
39 }
40
41 for (vtkm::Id i = 0; i < size; ++i)
42 {
43 if (ah.ReadPortal().Get(i) != expected[i])
44 {
45 return false;
46 }
47 }
48
49 return true;
50 }
51
MakeTestDatasetExplicit()52 vtkm::cont::DataSet MakeTestDatasetExplicit()
53 {
54 std::vector<Coord3D> coords;
55 coords.push_back(Coord3D(0.0f, 0.0f, 0.0f));
56 coords.push_back(Coord3D(1.0f, 0.0f, 0.0f));
57 coords.push_back(Coord3D(1.0f, 1.0f, 0.0f));
58 coords.push_back(Coord3D(0.0f, 1.0f, 0.0f));
59
60 std::vector<vtkm::Id> connectivity;
61 connectivity.push_back(0);
62 connectivity.push_back(1);
63 connectivity.push_back(3);
64 connectivity.push_back(3);
65 connectivity.push_back(1);
66 connectivity.push_back(2);
67
68 vtkm::cont::DataSet ds;
69 vtkm::cont::DataSetBuilderExplicit builder;
70 ds = builder.Create(coords, vtkm::CellShapeTagTriangle(), 3, connectivity, "coords");
71
72
73 std::vector<vtkm::Float32> values;
74 values.push_back(1.0);
75 values.push_back(2.0);
76 values.push_back(1.0);
77 values.push_back(0.0);
78 ds.AddPointField("scalars", values);
79
80 values.clear();
81 values.push_back(100.f);
82 values.push_back(-100.f);
83 ds.AddCellField("cellvar", values);
84
85 return ds;
86 }
87
MakeTestDatasetStructured()88 vtkm::cont::DataSet MakeTestDatasetStructured()
89 {
90 static constexpr vtkm::Id xdim = 3, ydim = 3;
91 static const vtkm::Id2 dim(xdim, ydim);
92 static constexpr vtkm::Id numVerts = xdim * ydim;
93
94 vtkm::Float32 scalars[numVerts];
95 for (vtkm::Id i = 0; i < numVerts; ++i)
96 {
97 scalars[i] = 1.0f;
98 }
99 scalars[4] = 0.0f;
100
101 vtkm::cont::DataSet ds;
102 vtkm::cont::DataSetBuilderUniform builder;
103 ds = builder.Create(dim);
104
105 ds.AddPointField("scalars", scalars, numVerts);
106
107 std::vector<vtkm::Float32> cellvar = { -100.f, 100.f, 30.f, -30.f };
108 ds.AddCellField("cellvar", cellvar);
109
110 return ds;
111 }
112
TestClippingExplicit()113 void TestClippingExplicit()
114 {
115 vtkm::cont::DataSet ds = MakeTestDatasetExplicit();
116 vtkm::worklet::Clip clip;
117 bool invertClip = false;
118 vtkm::cont::CellSetExplicit<> outputCellSet =
119 clip.Run(ds.GetCellSet(),
120 ds.GetField("scalars").GetData().ResetTypes(vtkm::TypeListFieldScalar{},
121 VTKM_DEFAULT_STORAGE_LIST{}),
122 clipValue,
123 invertClip);
124
125 auto coordsIn = ds.GetCoordinateSystem("coords").GetDataAsMultiplexer();
126 vtkm::cont::ArrayHandle<Coord3D> coords = clip.ProcessPointField(coordsIn);
127
128 vtkm::cont::ArrayHandle<vtkm::Float32> scalarsIn;
129 ds.GetField("scalars").GetData().AsArrayHandle(scalarsIn);
130 vtkm::cont::ArrayHandle<vtkm::Float32> scalars = clip.ProcessPointField(scalarsIn);
131
132 vtkm::cont::ArrayHandle<vtkm::Float32> cellvarIn;
133 ds.GetField("cellvar").GetData().AsArrayHandle(cellvarIn);
134 vtkm::cont::ArrayHandle<vtkm::Float32> cellvar = clip.ProcessCellField(cellvarIn);
135
136 vtkm::Id connectivitySize = 8;
137 vtkm::Id fieldSize = 7;
138 vtkm::Id expectedConnectivity[] = { 0, 1, 5, 4, 1, 2, 6, 5 };
139 Coord3D expectedCoords[] = {
140 Coord3D(0.00f, 0.00f, 0.0f), Coord3D(1.00f, 0.00f, 0.0f), Coord3D(1.00f, 1.00f, 0.0f),
141 Coord3D(0.00f, 1.00f, 0.0f), Coord3D(0.00f, 0.50f, 0.0f), Coord3D(0.25f, 0.75f, 0.0f),
142 Coord3D(0.50f, 1.00f, 0.0f),
143 };
144 vtkm::Float32 expectedScalars[] = { 1, 2, 1, 0, 0.5, 0.5, 0.5 };
145 std::vector<vtkm::Float32> expectedCellvar = { 100.f, -100.f };
146
147 VTKM_TEST_ASSERT(outputCellSet.GetNumberOfPoints() == fieldSize,
148 "Wrong number of points in cell set.");
149
150 VTKM_TEST_ASSERT(
151 TestArrayHandle(outputCellSet.GetConnectivityArray(vtkm::TopologyElementTagCell(),
152 vtkm::TopologyElementTagPoint()),
153 expectedConnectivity,
154 connectivitySize),
155 "Got incorrect conectivity");
156
157 VTKM_TEST_ASSERT(TestArrayHandle(coords, expectedCoords, fieldSize), "Got incorrect coordinates");
158
159 VTKM_TEST_ASSERT(TestArrayHandle(scalars, expectedScalars, fieldSize), "Got incorrect scalars");
160
161 VTKM_TEST_ASSERT(
162 TestArrayHandle(cellvar, expectedCellvar.data(), static_cast<vtkm::Id>(expectedCellvar.size())),
163 "Got incorrect cellvar");
164 }
165
TestClippingStructured()166 void TestClippingStructured()
167 {
168 using CoordsValueType = vtkm::cont::ArrayHandleUniformPointCoordinates::ValueType;
169 using CoordsOutType = vtkm::cont::ArrayHandle<CoordsValueType>;
170
171 vtkm::cont::DataSet ds = MakeTestDatasetStructured();
172
173 bool invertClip = false;
174 vtkm::worklet::Clip clip;
175 vtkm::cont::CellSetExplicit<> outputCellSet =
176 clip.Run(ds.GetCellSet(),
177 ds.GetField("scalars").GetData().ResetTypes(vtkm::TypeListFieldScalar{},
178 VTKM_DEFAULT_STORAGE_LIST{}),
179 clipValue,
180 invertClip);
181
182 auto coordsIn = ds.GetCoordinateSystem("coords").GetDataAsMultiplexer();
183 CoordsOutType coords = clip.ProcessPointField(coordsIn);
184
185 vtkm::cont::ArrayHandle<vtkm::Float32> scalarsIn;
186 ds.GetField("scalars").GetData().AsArrayHandle(scalarsIn);
187 vtkm::cont::ArrayHandle<vtkm::Float32> scalars = clip.ProcessPointField(scalarsIn);
188
189 vtkm::cont::ArrayHandle<vtkm::Float32> cellvarIn;
190 ds.GetField("cellvar").GetData().AsArrayHandle(cellvarIn);
191 vtkm::cont::ArrayHandle<vtkm::Float32> cellvar = clip.ProcessCellField(cellvarIn);
192
193
194 vtkm::Id connectivitySize = 28;
195 vtkm::Id fieldSize = 13;
196 vtkm::Id expectedConnectivity[] = { 9, 10, 3, 1, 1, 3, 0, 11, 9, 1, 5, 5, 1, 2,
197 10, 12, 7, 3, 3, 7, 6, 12, 11, 5, 7, 7, 5, 8 };
198
199 Coord3D expectedCoords[] = {
200 Coord3D(0.0f, 0.0f, 0.0f), Coord3D(1.0f, 0.0f, 0.0f), Coord3D(2.0f, 0.0f, 0.0f),
201 Coord3D(0.0f, 1.0f, 0.0f), Coord3D(1.0f, 1.0f, 0.0f), Coord3D(2.0f, 1.0f, 0.0f),
202 Coord3D(0.0f, 2.0f, 0.0f), Coord3D(1.0f, 2.0f, 0.0f), Coord3D(2.0f, 2.0f, 0.0f),
203 Coord3D(1.0f, 0.5f, 0.0f), Coord3D(0.5f, 1.0f, 0.0f), Coord3D(1.5f, 1.0f, 0.0f),
204 Coord3D(1.0f, 1.5f, 0.0f),
205 };
206 vtkm::Float32 expectedScalars[] = { 1, 1, 1, 1, 0, 1, 1, 1, 1, 0.5, 0.5, 0.5, 0.5 };
207 std::vector<vtkm::Float32> expectedCellvar = { -100.f, -100.f, 100.f, 100.f,
208 30.f, 30.f, -30.f, -30.f };
209
210 VTKM_TEST_ASSERT(outputCellSet.GetNumberOfPoints() == fieldSize,
211 "Wrong number of points in cell set.");
212
213 VTKM_TEST_ASSERT(
214 TestArrayHandle(outputCellSet.GetConnectivityArray(vtkm::TopologyElementTagCell(),
215 vtkm::TopologyElementTagPoint()),
216 expectedConnectivity,
217 connectivitySize),
218 "Got incorrect conectivity");
219
220 VTKM_TEST_ASSERT(TestArrayHandle(coords, expectedCoords, fieldSize), "Got incorrect coordinates");
221
222 VTKM_TEST_ASSERT(TestArrayHandle(scalars, expectedScalars, fieldSize), "Got incorrect scalars");
223
224 VTKM_TEST_ASSERT(
225 TestArrayHandle(cellvar, expectedCellvar.data(), static_cast<vtkm::Id>(expectedCellvar.size())),
226 "Got incorrect cellvar");
227 }
228
TestClippingWithImplicitFunction()229 void TestClippingWithImplicitFunction()
230 {
231 vtkm::Vec3f center(1, 1, 0);
232 vtkm::FloatDefault radius(0.5);
233
234 vtkm::cont::DataSet ds = MakeTestDatasetStructured();
235
236 bool invertClip = false;
237 vtkm::worklet::Clip clip;
238 vtkm::cont::CellSetExplicit<> outputCellSet = clip.Run(
239 ds.GetCellSet(), vtkm::Sphere(center, radius), ds.GetCoordinateSystem("coords"), invertClip);
240
241 auto coordsIn = ds.GetCoordinateSystem("coords").GetDataAsMultiplexer();
242 vtkm::cont::ArrayHandle<Coord3D> coords = clip.ProcessPointField(coordsIn);
243
244 vtkm::cont::ArrayHandle<vtkm::Float32> scalarsIn;
245 ds.GetField("scalars").GetData().AsArrayHandle(scalarsIn);
246 vtkm::cont::ArrayHandle<vtkm::Float32> scalars = clip.ProcessPointField(scalarsIn);
247
248 vtkm::cont::ArrayHandle<vtkm::Float32> cellvarIn;
249 ds.GetField("cellvar").GetData().AsArrayHandle(cellvarIn);
250 vtkm::cont::ArrayHandle<vtkm::Float32> cellvar = clip.ProcessCellField(cellvarIn);
251
252 vtkm::Id connectivitySize = 28;
253 vtkm::Id fieldSize = 13;
254
255 vtkm::Id expectedConnectivity[] = { 9, 10, 3, 1, 1, 3, 0, 11, 9, 1, 5, 5, 1, 2,
256 10, 12, 7, 3, 3, 7, 6, 12, 11, 5, 7, 7, 5, 8 };
257
258 Coord3D expectedCoords[] = {
259 Coord3D(0.0f, 0.0f, 0.0f), Coord3D(1.0f, 0.0f, 0.0f), Coord3D(2.0f, 0.0f, 0.0f),
260 Coord3D(0.0f, 1.0f, 0.0f), Coord3D(1.0f, 1.0f, 0.0f), Coord3D(2.0f, 1.0f, 0.0f),
261 Coord3D(0.0f, 2.0f, 0.0f), Coord3D(1.0f, 2.0f, 0.0f), Coord3D(2.0f, 2.0f, 0.0f),
262 Coord3D(1.0f, 0.75f, 0.0f), Coord3D(0.75f, 1.0f, 0.0f), Coord3D(1.25f, 1.0f, 0.0f),
263 Coord3D(1.0f, 1.25f, 0.0f),
264 };
265 vtkm::Float32 expectedScalars[] = { 1, 1, 1, 1, 0, 1, 1, 1, 1, 0.25, 0.25, 0.25, 0.25 };
266 std::vector<vtkm::Float32> expectedCellvar = { -100.f, -100.f, 100.f, 100.f,
267 30.f, 30.f, -30.f, -30.f };
268
269 VTKM_TEST_ASSERT(
270 TestArrayHandle(outputCellSet.GetConnectivityArray(vtkm::TopologyElementTagCell(),
271 vtkm::TopologyElementTagPoint()),
272 expectedConnectivity,
273 connectivitySize),
274 "Got incorrect conectivity");
275
276 VTKM_TEST_ASSERT(TestArrayHandle(coords, expectedCoords, fieldSize), "Got incorrect coordinates");
277
278 VTKM_TEST_ASSERT(TestArrayHandle(scalars, expectedScalars, fieldSize), "Got incorrect scalars");
279
280 VTKM_TEST_ASSERT(
281 TestArrayHandle(cellvar, expectedCellvar.data(), static_cast<vtkm::Id>(expectedCellvar.size())),
282 "Got incorrect cellvar");
283 }
284
TestClippingWithImplicitFunctionInverted()285 void TestClippingWithImplicitFunctionInverted()
286 {
287 vtkm::Vec3f center(1, 1, 0);
288 vtkm::FloatDefault radius(0.5);
289
290 vtkm::cont::DataSet ds = MakeTestDatasetStructured();
291
292 bool invertClip = true;
293 vtkm::worklet::Clip clip;
294 vtkm::cont::CellSetExplicit<> outputCellSet = clip.Run(
295 ds.GetCellSet(), vtkm::Sphere(center, radius), ds.GetCoordinateSystem("coords"), invertClip);
296
297 auto coordsIn = ds.GetCoordinateSystem("coords").GetDataAsMultiplexer();
298 vtkm::cont::ArrayHandle<Coord3D> coords = clip.ProcessPointField(coordsIn);
299
300 vtkm::cont::ArrayHandle<vtkm::Float32> scalarsIn;
301 ds.GetField("scalars").GetData().AsArrayHandle(scalarsIn);
302 vtkm::cont::ArrayHandle<vtkm::Float32> scalars = clip.ProcessPointField(scalarsIn);
303
304 vtkm::cont::ArrayHandle<vtkm::Float32> cellvarIn;
305 ds.GetField("cellvar").GetData().AsArrayHandle(cellvarIn);
306 vtkm::cont::ArrayHandle<vtkm::Float32> cellvar = clip.ProcessCellField(cellvarIn);
307
308 vtkm::Id connectivitySize = 12;
309 vtkm::Id fieldSize = 13;
310 vtkm::Id expectedConnectivity[] = { 10, 9, 4, 9, 11, 4, 12, 10, 4, 11, 12, 4 };
311 Coord3D expectedCoords[] = {
312 Coord3D(0.0f, 0.0f, 0.0f), Coord3D(1.0f, 0.0f, 0.0f), Coord3D(2.0f, 0.0f, 0.0f),
313 Coord3D(0.0f, 1.0f, 0.0f), Coord3D(1.0f, 1.0f, 0.0f), Coord3D(2.0f, 1.0f, 0.0f),
314 Coord3D(0.0f, 2.0f, 0.0f), Coord3D(1.0f, 2.0f, 0.0f), Coord3D(2.0f, 2.0f, 0.0f),
315 Coord3D(1.0f, 0.75f, 0.0f), Coord3D(0.75f, 1.0f, 0.0f), Coord3D(1.25f, 1.0f, 0.0f),
316 Coord3D(1.0f, 1.25f, 0.0f),
317 };
318 vtkm::Float32 expectedScalars[] = { 1, 1, 1, 1, 0, 1, 1, 1, 1, 0.25, 0.25, 0.25, 0.25 };
319 std::vector<vtkm::Float32> expectedCellvar = { -100.f, 100.f, 30.f, -30.f };
320
321 VTKM_TEST_ASSERT(
322 TestArrayHandle(outputCellSet.GetConnectivityArray(vtkm::TopologyElementTagCell(),
323 vtkm::TopologyElementTagPoint()),
324 expectedConnectivity,
325 connectivitySize),
326 "Got incorrect conectivity");
327
328 VTKM_TEST_ASSERT(TestArrayHandle(coords, expectedCoords, fieldSize), "Got incorrect coordinates");
329
330 VTKM_TEST_ASSERT(TestArrayHandle(scalars, expectedScalars, fieldSize), "Got incorrect scalars");
331
332 VTKM_TEST_ASSERT(
333 TestArrayHandle(cellvar, expectedCellvar.data(), static_cast<vtkm::Id>(expectedCellvar.size())),
334 "Got incorrect cellvar");
335 }
336
TestClipping()337 void TestClipping()
338 {
339 std::cout << "Testing explicit dataset:" << std::endl;
340 TestClippingExplicit();
341 std::cout << "Testing structured dataset:" << std::endl;
342 TestClippingStructured();
343 std::cout << "Testing clipping with implicit function (sphere):" << std::endl;
344 TestClippingWithImplicitFunction();
345 TestClippingWithImplicitFunctionInverted();
346 }
347
UnitTestClipping(int argc,char * argv[])348 int UnitTestClipping(int argc, char* argv[])
349 {
350 return vtkm::cont::testing::Testing::Run(TestClipping, argc, argv);
351 }
352