ec34cb56c4
Also fix deadlocks that occur when portals are not destroyed in time.
231 lines
8.4 KiB
C++
231 lines
8.4 KiB
C++
//============================================================================
|
|
// Copyright (c) Kitware, Inc.
|
|
// All rights reserved.
|
|
// See LICENSE.txt for details.
|
|
//
|
|
// This software is distributed WITHOUT ANY WARRANTY; without even
|
|
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
// PURPOSE. See the above copyright notice for more information.
|
|
//============================================================================
|
|
#include <vtkm/worklet/SplitSharpEdges.h>
|
|
#include <vtkm/worklet/SurfaceNormals.h>
|
|
|
|
#include <vtkm/cont/testing/MakeTestDataSet.h>
|
|
#include <vtkm/cont/testing/Testing.h>
|
|
#include <vtkm/worklet/DispatcherMapTopology.h>
|
|
|
|
namespace
|
|
{
|
|
|
|
using NormalsArrayHandle = vtkm::cont::ArrayHandle<vtkm::Vec3f>;
|
|
|
|
const vtkm::Vec3f expectedCoords[24] = {
|
|
{ 0.0, 0.0, 0.0 }, { 1.0, 0.0, 0.0 }, { 1.0, 0.0, 1.0 }, { 0.0, 0.0, 1.0 }, { 0.0, 1.0, 0.0 },
|
|
{ 1.0, 1.0, 0.0 }, { 1.0, 1.0, 1.0 }, { 0.0, 1.0, 1.0 }, { 0.0, 0.0, 0.0 }, { 0.0, 0.0, 0.0 },
|
|
{ 1.0, 0.0, 0.0 }, { 1.0, 0.0, 0.0 }, { 1.0, 0.0, 1.0 }, { 1.0, 0.0, 1.0 }, { 0.0, 0.0, 1.0 },
|
|
{ 0.0, 0.0, 1.0 }, { 0.0, 1.0, 0.0 }, { 0.0, 1.0, 0.0 }, { 1.0, 1.0, 0.0 }, { 1.0, 1.0, 0.0 },
|
|
{ 1.0, 1.0, 1.0 }, { 1.0, 1.0, 1.0 }, { 0.0, 1.0, 1.0 }, { 0.0, 1.0, 1.0 }
|
|
};
|
|
|
|
const std::vector<vtkm::FloatDefault> expectedPointvar{ 10.1f, 20.1f, 30.2f, 40.2f, 50.3f, 60.3f,
|
|
70.3f, 80.3f, 10.1f, 10.1f, 20.1f, 20.1f,
|
|
30.2f, 30.2f, 40.2f, 40.2f, 50.3f, 50.3f,
|
|
60.3f, 60.3f, 70.3f, 70.3f, 80.3f, 80.3f };
|
|
|
|
const std::vector<vtkm::Id> expectedConnectivityArray91{ 0, 1, 5, 4, 1, 2, 6, 5, 2, 3, 7, 6,
|
|
3, 0, 4, 7, 4, 5, 6, 7, 0, 3, 2, 1 };
|
|
|
|
vtkm::cont::DataSet Make3DExplicitSimpleCube()
|
|
{
|
|
vtkm::cont::DataSet dataSet;
|
|
vtkm::cont::DataSetBuilderExplicit dsb;
|
|
|
|
const int nVerts = 8;
|
|
const int nCells = 6;
|
|
using CoordType = vtkm::Vec3f;
|
|
std::vector<CoordType> coords = {
|
|
CoordType(0, 0, 0), // 0
|
|
CoordType(1, 0, 0), // 1
|
|
CoordType(1, 0, 1), // 2
|
|
CoordType(0, 0, 1), // 3
|
|
CoordType(0, 1, 0), // 4
|
|
CoordType(1, 1, 0), // 5
|
|
CoordType(1, 1, 1), // 6
|
|
CoordType(0, 1, 1) // 7
|
|
};
|
|
|
|
//Connectivity
|
|
std::vector<vtkm::UInt8> shapes;
|
|
std::vector<vtkm::IdComponent> numIndices;
|
|
for (size_t i = 0; i < 6; i++)
|
|
{
|
|
shapes.push_back(vtkm::CELL_SHAPE_QUAD);
|
|
numIndices.push_back(4);
|
|
}
|
|
|
|
|
|
std::vector<vtkm::Id> conn;
|
|
// Down face
|
|
conn.push_back(0);
|
|
conn.push_back(1);
|
|
conn.push_back(5);
|
|
conn.push_back(4);
|
|
// Right face
|
|
conn.push_back(1);
|
|
conn.push_back(2);
|
|
conn.push_back(6);
|
|
conn.push_back(5);
|
|
// Top face
|
|
conn.push_back(2);
|
|
conn.push_back(3);
|
|
conn.push_back(7);
|
|
conn.push_back(6);
|
|
// Left face
|
|
conn.push_back(3);
|
|
conn.push_back(0);
|
|
conn.push_back(4);
|
|
conn.push_back(7);
|
|
// Front face
|
|
conn.push_back(4);
|
|
conn.push_back(5);
|
|
conn.push_back(6);
|
|
conn.push_back(7);
|
|
// Back face
|
|
conn.push_back(0);
|
|
conn.push_back(3);
|
|
conn.push_back(2);
|
|
conn.push_back(1);
|
|
|
|
//Create the dataset.
|
|
dataSet = dsb.Create(coords, shapes, numIndices, conn, "coordinates");
|
|
|
|
vtkm::FloatDefault vars[nVerts] = { 10.1f, 20.1f, 30.2f, 40.2f, 50.3f, 60.3f, 70.3f, 80.3f };
|
|
vtkm::FloatDefault cellvar[nCells] = { 100.1f, 200.2f, 300.3f, 400.4f, 500.5f, 600.6f };
|
|
|
|
vtkm::cont::DataSetFieldAdd dsf;
|
|
dsf.AddPointField(dataSet, "pointvar", vars, nVerts);
|
|
dsf.AddCellField(dataSet, "cellvar", cellvar, nCells);
|
|
|
|
return dataSet;
|
|
}
|
|
|
|
void TestSplitSharpEdgesSplitEveryEdge(vtkm::cont::DataSet& simpleCube,
|
|
NormalsArrayHandle& faceNormals,
|
|
vtkm::worklet::SplitSharpEdges& splitSharpEdges)
|
|
|
|
{ // Split every edge
|
|
vtkm::FloatDefault featureAngle = 89.0;
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Vec3f> newCoords;
|
|
vtkm::cont::CellSetExplicit<> newCellset;
|
|
|
|
splitSharpEdges.Run(simpleCube.GetCellSet(),
|
|
featureAngle,
|
|
faceNormals,
|
|
simpleCube.GetCoordinateSystem().GetData(),
|
|
newCoords,
|
|
newCellset);
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::FloatDefault> pointvar;
|
|
simpleCube.GetPointField("pointvar").GetData().CopyTo(pointvar);
|
|
vtkm::cont::ArrayHandle<vtkm::FloatDefault> newPointFields =
|
|
splitSharpEdges.ProcessPointField(pointvar);
|
|
VTKM_TEST_ASSERT(newCoords.GetNumberOfValues() == 24,
|
|
"new coordinates"
|
|
" number is wrong");
|
|
|
|
auto newCoordsP = newCoords.ReadPortal();
|
|
for (vtkm::Id i = 0; i < newCoords.GetNumberOfValues(); i++)
|
|
{
|
|
VTKM_TEST_ASSERT(test_equal(newCoordsP.Get(i)[0], expectedCoords[vtkm::IdComponent(i)][0]),
|
|
"result value does not match expected value");
|
|
VTKM_TEST_ASSERT(test_equal(newCoordsP.Get(i)[1], expectedCoords[vtkm::IdComponent(i)][1]),
|
|
"result value does not match expected value");
|
|
VTKM_TEST_ASSERT(test_equal(newCoordsP.Get(i)[2], expectedCoords[vtkm::IdComponent(i)][2]),
|
|
"result value does not match expected value");
|
|
}
|
|
|
|
auto newPointFieldsPortal = newPointFields.ReadPortal();
|
|
for (int i = 0; i < newPointFields.GetNumberOfValues(); i++)
|
|
{
|
|
VTKM_TEST_ASSERT(
|
|
test_equal(newPointFieldsPortal.Get(i), expectedPointvar[static_cast<unsigned long>(i)]),
|
|
"point field array result does not match expected value");
|
|
}
|
|
}
|
|
|
|
void TestSplitSharpEdgesNoSplit(vtkm::cont::DataSet& simpleCube,
|
|
NormalsArrayHandle& faceNormals,
|
|
vtkm::worklet::SplitSharpEdges& splitSharpEdges)
|
|
|
|
{ // Do nothing
|
|
vtkm::FloatDefault featureAngle = 91.0;
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Vec3f> newCoords;
|
|
vtkm::cont::CellSetExplicit<> newCellset;
|
|
|
|
splitSharpEdges.Run(simpleCube.GetCellSet(),
|
|
featureAngle,
|
|
faceNormals,
|
|
simpleCube.GetCoordinateSystem().GetData(),
|
|
newCoords,
|
|
newCellset);
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::FloatDefault> pointvar;
|
|
simpleCube.GetPointField("pointvar").GetData().CopyTo(pointvar);
|
|
vtkm::cont::ArrayHandle<vtkm::FloatDefault> newPointFields =
|
|
splitSharpEdges.ProcessPointField(pointvar);
|
|
VTKM_TEST_ASSERT(newCoords.GetNumberOfValues() == 8,
|
|
"new coordinates"
|
|
" number is wrong");
|
|
|
|
auto newCoordsP = newCoords.ReadPortal();
|
|
for (int i = 0; i < newCoords.GetNumberOfValues(); i++)
|
|
{
|
|
VTKM_TEST_ASSERT(test_equal(newCoordsP.Get(i)[0], expectedCoords[i][0]),
|
|
"result value does not match expected value");
|
|
VTKM_TEST_ASSERT(test_equal(newCoordsP.Get(i)[1], expectedCoords[i][1]),
|
|
"result value does not match expected value");
|
|
VTKM_TEST_ASSERT(test_equal(newCoordsP.Get(i)[2], expectedCoords[i][2]),
|
|
"result value does not match expected value");
|
|
}
|
|
|
|
const auto& connectivityArray = newCellset.GetConnectivityArray(vtkm::TopologyElementTagCell(),
|
|
vtkm::TopologyElementTagPoint());
|
|
auto connectivityArrayPortal = connectivityArray.ReadPortal();
|
|
for (int i = 0; i < connectivityArray.GetNumberOfValues(); i++)
|
|
{
|
|
VTKM_TEST_ASSERT(test_equal(connectivityArrayPortal.Get(i),
|
|
expectedConnectivityArray91[static_cast<unsigned long>(i)]),
|
|
"connectivity array result does not match expected value");
|
|
}
|
|
|
|
auto newPointFieldsPortal = newPointFields.ReadPortal();
|
|
for (int i = 0; i < newPointFields.GetNumberOfValues(); i++)
|
|
{
|
|
VTKM_TEST_ASSERT(
|
|
test_equal(newPointFieldsPortal.Get(i), expectedPointvar[static_cast<unsigned long>(i)]),
|
|
"point field array result does not match expected value");
|
|
}
|
|
}
|
|
|
|
void TestSplitSharpEdges()
|
|
{
|
|
vtkm::cont::DataSet simpleCube = Make3DExplicitSimpleCube();
|
|
NormalsArrayHandle faceNormals;
|
|
vtkm::worklet::FacetedSurfaceNormals faceted;
|
|
faceted.Run(simpleCube.GetCellSet(), simpleCube.GetCoordinateSystem().GetData(), faceNormals);
|
|
|
|
vtkm::worklet::SplitSharpEdges splitSharpEdges;
|
|
|
|
TestSplitSharpEdgesSplitEveryEdge(simpleCube, faceNormals, splitSharpEdges);
|
|
TestSplitSharpEdgesNoSplit(simpleCube, faceNormals, splitSharpEdges);
|
|
}
|
|
|
|
} // anonymous namespace
|
|
|
|
int UnitTestSplitSharpEdges(int argc, char* argv[])
|
|
{
|
|
return vtkm::cont::testing::Testing::Run(TestSplitSharpEdges, argc, argv);
|
|
}
|