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/Math.h>
12 #include <vtkm/cont/DataSet.h>
13 #include <vtkm/cont/testing/MakeTestDataSet.h>
14 #include <vtkm/cont/testing/Testing.h>
15 
16 #include <vtkm/filter/CleanGrid.h>
17 #include <vtkm/filter/Contour.h>
18 
19 #include <vtkm/io/VTKDataSetReader.h>
20 #include <vtkm/source/Tangle.h>
21 
22 namespace
23 {
24 
25 class TestContourFilter
26 {
27 public:
TestContourUniformGrid() const28   void TestContourUniformGrid() const
29   {
30     std::cout << "Testing Contour filter on a uniform grid" << std::endl;
31 
32     vtkm::Id3 dims(4, 4, 4);
33     vtkm::source::Tangle tangle(dims);
34     vtkm::cont::DataSet dataSet = tangle.Execute();
35 
36     vtkm::filter::Contour mc;
37 
38     mc.SetGenerateNormals(true);
39     mc.SetIsoValue(0, 0.5);
40     mc.SetActiveField("nodevar");
41     mc.SetFieldsToPass(vtkm::filter::FieldSelection::MODE_NONE);
42 
43     auto result = mc.Execute(dataSet);
44     {
45       VTKM_TEST_ASSERT(result.GetNumberOfCoordinateSystems() == 1,
46                        "Wrong number of coordinate systems in the output dataset");
47       //since normals is on we have one field
48       VTKM_TEST_ASSERT(result.GetNumberOfFields() == 1,
49                        "Wrong number of fields in the output dataset");
50     }
51 
52     // let's execute with mapping fields.
53     mc.SetFieldsToPass({ "nodevar", "cellvar" });
54     result = mc.Execute(dataSet);
55     {
56       const bool isMapped = result.HasField("nodevar");
57       VTKM_TEST_ASSERT(isMapped, "mapping should pass");
58 
59       VTKM_TEST_ASSERT(result.GetNumberOfFields() == 3,
60                        "Wrong number of fields in the output dataset");
61 
62       //verify the cellvar result
63       vtkm::cont::ArrayHandle<vtkm::FloatDefault> cellFieldArrayOut;
64       result.GetField("cellvar").GetData().AsArrayHandle(cellFieldArrayOut);
65 
66       vtkm::cont::Algorithm::Sort(cellFieldArrayOut);
67       {
68         std::vector<vtkm::Id> correctcellIdStart = { 0, 1, 1, 2, 2, 3, 4, 4, 5, 5, 5, 6, 6, 6 };
69         std::vector<vtkm::Id> correctcellIdEnd = { 57, 57, 58, 58, 58, 59, 59,
70                                                    60, 61, 61, 62, 62, 63 };
71 
72         auto id_portal = cellFieldArrayOut.ReadPortal();
73         for (std::size_t i = 0; i < correctcellIdStart.size(); ++i)
74         {
75           VTKM_TEST_ASSERT(id_portal.Get(vtkm::Id(i)) == correctcellIdStart[i]);
76         }
77 
78         vtkm::Id index = cellFieldArrayOut.GetNumberOfValues() - vtkm::Id(correctcellIdEnd.size());
79         for (std::size_t i = 0; i < correctcellIdEnd.size(); ++i, ++index)
80         {
81           VTKM_TEST_ASSERT(id_portal.Get(index) == correctcellIdEnd[i]);
82         }
83       }
84 
85       vtkm::cont::CoordinateSystem coords = result.GetCoordinateSystem();
86       vtkm::cont::DynamicCellSet dcells = result.GetCellSet();
87       using CellSetType = vtkm::cont::CellSetSingleType<>;
88       const CellSetType& cells = dcells.Cast<CellSetType>();
89 
90       //verify that the number of points is correct (72)
91       //verify that the number of cells is correct (160)
92       VTKM_TEST_ASSERT(coords.GetNumberOfPoints() == 72,
93                        "Should have less coordinates than the unmerged version");
94       VTKM_TEST_ASSERT(cells.GetNumberOfCells() == 160, "");
95     }
96 
97     //Now try with vertex merging disabled. Since this
98     //we use FlyingEdges we now which does point merging for free
99     //so we should see the number of points not change
100     mc.SetMergeDuplicatePoints(false);
101     mc.SetFieldsToPass(vtkm::filter::FieldSelection::MODE_ALL);
102     result = mc.Execute(dataSet);
103     {
104       vtkm::cont::CoordinateSystem coords = result.GetCoordinateSystem();
105 
106       VTKM_TEST_ASSERT(coords.GetNumberOfPoints() == 72,
107                        "Shouldn't have less coordinates than the unmerged version");
108 
109       //verify that the number of cells is correct (160)
110       vtkm::cont::DynamicCellSet dcells = result.GetCellSet();
111 
112       using CellSetType = vtkm::cont::CellSetSingleType<>;
113       const CellSetType& cells = dcells.Cast<CellSetType>();
114       VTKM_TEST_ASSERT(cells.GetNumberOfCells() == 160, "");
115     }
116   }
117 
Test3DUniformDataSet0() const118   void Test3DUniformDataSet0() const
119   {
120     vtkm::cont::testing::MakeTestDataSet maker;
121     vtkm::cont::DataSet inputData = maker.Make3DUniformDataSet0();
122     std::string fieldName = "pointvar";
123     // Defend the test against changes to Make3DUniformDataSet0():
124     VTKM_TEST_ASSERT(inputData.HasField(fieldName));
125     vtkm::cont::Field pointField = inputData.GetField(fieldName);
126     vtkm::Range range;
127     pointField.GetRange(&range);
128     vtkm::FloatDefault isovalue = 100.0;
129     // Range = [10.1, 180.5]
130     VTKM_TEST_ASSERT(range.Contains(isovalue));
131     vtkm::filter::Contour filter;
132     filter.SetGenerateNormals(false);
133     filter.SetMergeDuplicatePoints(true);
134     filter.SetIsoValue(isovalue);
135     filter.SetActiveField(fieldName);
136     vtkm::cont::DataSet outputData = filter.Execute(inputData);
137     VTKM_TEST_ASSERT(outputData.GetNumberOfCells() == 8);
138     VTKM_TEST_ASSERT(outputData.GetNumberOfPoints() == 9);
139   }
140 
TestContourWedges() const141   void TestContourWedges() const
142   {
143     std::cout << "Testing Contour filter on wedge cells" << std::endl;
144 
145     auto pathname = vtkm::cont::testing::Testing::DataPath("unstructured/wedge_cells.vtk");
146     vtkm::io::VTKDataSetReader reader(pathname);
147 
148     vtkm::cont::DataSet dataSet = reader.ReadDataSet();
149 
150     vtkm::cont::CellSetSingleType<> cellSet;
151     dataSet.GetCellSet().CopyTo(cellSet);
152 
153     vtkm::cont::ArrayHandle<vtkm::Float32> fieldArray;
154     dataSet.GetPointField("gyroid").GetData().AsArrayHandle(fieldArray);
155 
156     vtkm::worklet::Contour isosurfaceFilter;
157     isosurfaceFilter.SetMergeDuplicatePoints(false);
158 
159     vtkm::cont::ArrayHandle<vtkm::Vec3f_32> verticesArray;
160     vtkm::cont::ArrayHandle<vtkm::Vec3f_32> normalsArray;
161 
162     auto result = isosurfaceFilter.Run(
163       { 0.0f }, cellSet, dataSet.GetCoordinateSystem(), fieldArray, verticesArray, normalsArray);
164     VTKM_TEST_ASSERT(result.GetNumberOfCells() == 52);
165   }
166 
operator ()() const167   void operator()() const
168   {
169     this->Test3DUniformDataSet0();
170     this->TestContourUniformGrid();
171     this->TestContourWedges();
172   }
173 
174 }; // class TestContourFilter
175 } // namespace
176 
UnitTestContourFilter(int argc,char * argv[])177 int UnitTestContourFilter(int argc, char* argv[])
178 {
179   return vtkm::cont::testing::Testing::Run(TestContourFilter{}, argc, argv);
180 }
181