2019-06-26 16:53:15 +00:00
|
|
|
//=============================================================================
|
|
|
|
//
|
|
|
|
// 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.
|
|
|
|
//
|
|
|
|
// Copyright 2019 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
|
|
|
// Copyright 2019 UT-Battelle, LLC.
|
|
|
|
// Copyright 2019 Los Alamos National Security.
|
|
|
|
//
|
|
|
|
// Under the terms of Contract DE-NA0003525 with NTESS,
|
|
|
|
// the U.S. Government retains certain rights in this software.
|
|
|
|
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
|
|
|
|
// Laboratory (LANL), the U.S. Government retains certain rights in
|
|
|
|
// this software.
|
|
|
|
//
|
|
|
|
//=============================================================================
|
|
|
|
|
|
|
|
#include <vtkm/worklet/TriangleWinding.h>
|
|
|
|
|
|
|
|
#include <vtkm/Types.h>
|
|
|
|
|
|
|
|
#include <vtkm/cont/Algorithm.h>
|
|
|
|
#include <vtkm/cont/ArrayHandle.h>
|
|
|
|
#include <vtkm/cont/ArrayHandleGroupVecVariable.h>
|
|
|
|
#include <vtkm/cont/DataSet.h>
|
|
|
|
#include <vtkm/cont/Field.h>
|
|
|
|
|
|
|
|
#include <vtkm/cont/testing/MakeTestDataSet.h>
|
|
|
|
#include <vtkm/cont/testing/Testing.h>
|
|
|
|
|
2019-08-21 19:04:07 +00:00
|
|
|
using MyNormalT = vtkm::Vec<vtkm::Float32, 3>;
|
2019-06-26 16:53:15 +00:00
|
|
|
|
|
|
|
namespace
|
|
|
|
{
|
|
|
|
|
|
|
|
vtkm::cont::DataSet GenerateDataSet()
|
|
|
|
{
|
|
|
|
auto ds = vtkm::cont::testing::MakeTestDataSet{}.Make3DExplicitDataSetPolygonal();
|
|
|
|
const auto numCells = ds.GetCellSet().GetNumberOfCells();
|
|
|
|
|
2019-08-21 19:04:07 +00:00
|
|
|
vtkm::cont::ArrayHandle<MyNormalT> cellNormals;
|
|
|
|
vtkm::cont::Algorithm::Fill(cellNormals, MyNormalT{ 1., 0., 0. }, numCells);
|
2019-06-26 16:53:15 +00:00
|
|
|
|
2019-08-13 14:10:52 +00:00
|
|
|
ds.AddField(vtkm::cont::make_FieldCell("normals", ds.GetCellSet().GetName(), cellNormals));
|
2019-06-26 16:53:15 +00:00
|
|
|
return ds;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Validate(vtkm::cont::DataSet dataSet)
|
|
|
|
{
|
|
|
|
const auto cellSet = dataSet.GetCellSet().Cast<vtkm::cont::CellSetExplicit<>>();
|
|
|
|
const auto coordsArray = dataSet.GetCoordinateSystem().GetData();
|
|
|
|
const auto conn =
|
2019-07-30 16:53:51 +00:00
|
|
|
cellSet.GetConnectivityArray(vtkm::TopologyElementTagCell{}, vtkm::TopologyElementTagPoint{});
|
2019-06-26 16:53:15 +00:00
|
|
|
const auto offsets =
|
2019-07-30 16:53:51 +00:00
|
|
|
cellSet.GetIndexOffsetArray(vtkm::TopologyElementTagCell{}, vtkm::TopologyElementTagPoint{});
|
2019-06-26 16:53:15 +00:00
|
|
|
const auto cellArray = vtkm::cont::make_ArrayHandleGroupVecVariable(conn, offsets);
|
2019-08-13 14:10:52 +00:00
|
|
|
const auto cellNormalsVar = dataSet.GetCellField("normals").GetData();
|
2019-08-21 19:04:07 +00:00
|
|
|
const auto cellNormalsArray = cellNormalsVar.Cast<vtkm::cont::ArrayHandle<MyNormalT>>();
|
2019-06-26 16:53:15 +00:00
|
|
|
|
|
|
|
const auto cellPortal = cellArray.GetPortalConstControl();
|
|
|
|
const auto cellNormals = cellNormalsArray.GetPortalConstControl();
|
|
|
|
const auto coords = coordsArray.GetPortalConstControl();
|
|
|
|
|
|
|
|
const auto numCells = cellPortal.GetNumberOfValues();
|
|
|
|
VTKM_TEST_ASSERT(numCells == cellNormals.GetNumberOfValues());
|
|
|
|
|
|
|
|
for (vtkm::Id cellId = 0; cellId < numCells; ++cellId)
|
|
|
|
{
|
|
|
|
const auto cell = cellPortal.Get(cellId);
|
|
|
|
if (cell.GetNumberOfComponents() != 3)
|
|
|
|
{ // Triangles only!
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2019-08-21 19:04:07 +00:00
|
|
|
const MyNormalT cellNormal = cellNormals.Get(cellId);
|
|
|
|
const MyNormalT p0 = coords.Get(cell[0]);
|
|
|
|
const MyNormalT p1 = coords.Get(cell[1]);
|
|
|
|
const MyNormalT p2 = coords.Get(cell[2]);
|
|
|
|
const MyNormalT v01 = p1 - p0;
|
|
|
|
const MyNormalT v02 = p2 - p0;
|
|
|
|
const MyNormalT triangleNormal = vtkm::Cross(v01, v02);
|
2019-06-26 16:53:15 +00:00
|
|
|
VTKM_TEST_ASSERT(vtkm::Dot(triangleNormal, cellNormal) > 0,
|
|
|
|
"Triangle at index ",
|
|
|
|
cellId,
|
|
|
|
" incorrectly wound.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void DoTest()
|
|
|
|
{
|
|
|
|
auto ds = GenerateDataSet();
|
|
|
|
|
|
|
|
// Ensure that the test dataset needs to be rewound:
|
|
|
|
bool threw = false;
|
|
|
|
try
|
|
|
|
{
|
|
|
|
std::cerr << "Expecting an exception...\n";
|
|
|
|
Validate(ds);
|
|
|
|
}
|
|
|
|
catch (...)
|
|
|
|
{
|
|
|
|
threw = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_TEST_ASSERT(threw, "Test dataset is already wound consistently wrt normals.");
|
|
|
|
|
|
|
|
auto cellSet = ds.GetCellSet().Cast<vtkm::cont::CellSetExplicit<>>();
|
|
|
|
const auto coords = ds.GetCoordinateSystem().GetData();
|
2019-08-13 14:10:52 +00:00
|
|
|
const auto cellNormalsVar = ds.GetCellField("normals").GetData();
|
2019-08-21 19:04:07 +00:00
|
|
|
const auto cellNormals = cellNormalsVar.Cast<vtkm::cont::ArrayHandle<MyNormalT>>();
|
2019-06-26 16:53:15 +00:00
|
|
|
|
|
|
|
|
|
|
|
auto newCells = vtkm::worklet::TriangleWinding::Run(cellSet, coords, cellNormals);
|
|
|
|
|
|
|
|
vtkm::cont::DataSet result;
|
|
|
|
result.AddCoordinateSystem(ds.GetCoordinateSystem());
|
|
|
|
result.AddCellSet(newCells);
|
|
|
|
for (vtkm::Id i = 0; i < ds.GetNumberOfFields(); ++i)
|
|
|
|
{
|
|
|
|
result.AddField(ds.GetField(i));
|
|
|
|
}
|
|
|
|
|
|
|
|
Validate(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
} // end anon namespace
|
|
|
|
|
|
|
|
int UnitTestTriangleWinding(int argc, char* argv[])
|
|
|
|
{
|
|
|
|
return vtkm::cont::testing::Testing::Run(DoTest, argc, argv);
|
|
|
|
}
|