mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-08 13:23:51 +00:00
Add method for getting a cononical face id
The cononical face id is stored in a vtkm::Id3 (independent of the actual number of points in the face).
This commit is contained in:
parent
eafacc6dc5
commit
8e72dc738a
@ -245,6 +245,87 @@ static inline VTKM_EXEC vtkm::VecCConst<vtkm::IdComponent> CellFaceLocalIndices(
|
||||
|
||||
return vtkm::make_VecC(detail::PointsInFace[shape.Id][faceIndex], numPointsInFace);
|
||||
}
|
||||
|
||||
/// \brief Returns a cononical identifer for a cell face
|
||||
///
|
||||
/// Given information about a cell face and the global point indices for that cell,
|
||||
/// returns a vtkm::Id3 that contains values that are unique to that face. The
|
||||
/// values for two faces will be the same if and only if the faces contain the same
|
||||
/// points.
|
||||
///
|
||||
/// Note that this property is only try if the mesh is conforming. That is, any two
|
||||
/// neighboring cells that share a face have the same points on that face. This
|
||||
/// preculdes to faces sharing more than a single point or single edge.
|
||||
///
|
||||
template <typename CellShapeTag, typename GlobalPointIndicesVecType>
|
||||
static inline VTKM_EXEC vtkm::Id3 CellFaceCononicalId(
|
||||
vtkm::IdComponent faceIndex,
|
||||
CellShapeTag shape,
|
||||
const GlobalPointIndicesVecType& globalPointIndicesVec,
|
||||
const vtkm::exec::FunctorBase& worklet)
|
||||
{
|
||||
vtkm::VecCConst<vtkm::IdComponent> localPointIndices =
|
||||
vtkm::exec::CellFaceLocalIndices(faceIndex, shape, worklet);
|
||||
|
||||
VTKM_ASSERT(localPointIndices.GetNumberOfComponents() >= 3);
|
||||
|
||||
//Sort the first 3 face points/nodes in ascending order
|
||||
vtkm::Id3 sorted(globalPointIndicesVec[localPointIndices[0]],
|
||||
globalPointIndicesVec[localPointIndices[1]],
|
||||
globalPointIndicesVec[localPointIndices[2]]);
|
||||
vtkm::Id temp;
|
||||
if (sorted[0] > sorted[2])
|
||||
{
|
||||
temp = sorted[0];
|
||||
sorted[0] = sorted[2];
|
||||
sorted[2] = temp;
|
||||
}
|
||||
if (sorted[0] > sorted[1])
|
||||
{
|
||||
temp = sorted[0];
|
||||
sorted[0] = sorted[1];
|
||||
sorted[1] = temp;
|
||||
}
|
||||
if (sorted[1] > sorted[2])
|
||||
{
|
||||
temp = sorted[1];
|
||||
sorted[1] = sorted[2];
|
||||
sorted[2] = temp;
|
||||
}
|
||||
|
||||
// Check the rest of the points to see if they are in the lowest 3
|
||||
vtkm::IdComponent numPointsInFace = localPointIndices.GetNumberOfComponents();
|
||||
for (vtkm::IdComponent pointIndex = 3; pointIndex < numPointsInFace; pointIndex++)
|
||||
{
|
||||
vtkm::Id nextPoint = globalPointIndicesVec[localPointIndices[pointIndex]];
|
||||
if (nextPoint < sorted[2])
|
||||
{
|
||||
if (nextPoint < sorted[1])
|
||||
{
|
||||
sorted[2] = sorted[1];
|
||||
if (nextPoint < sorted[0])
|
||||
{
|
||||
sorted[1] = sorted[0];
|
||||
sorted[0] = nextPoint;
|
||||
}
|
||||
else // nextPoint > P0, nextPoint < P1
|
||||
{
|
||||
sorted[1] = nextPoint;
|
||||
}
|
||||
}
|
||||
else // nextPoint > P1, nextPoint < P2
|
||||
{
|
||||
sorted[2] = nextPoint;
|
||||
}
|
||||
}
|
||||
else // nextPoint > P2
|
||||
{
|
||||
// Do nothing. nextPoint not in top 3.
|
||||
}
|
||||
}
|
||||
|
||||
return sorted;
|
||||
}
|
||||
}
|
||||
} // namespace vtkm::exec
|
||||
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include <vtkm/testing/Testing.h>
|
||||
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
namespace
|
||||
{
|
||||
@ -57,6 +58,13 @@ struct TestCellFacesFunctor
|
||||
vtkm::exec::FunctorBase workletProxy;
|
||||
workletProxy.SetErrorMessageBuffer(errorMessage);
|
||||
|
||||
std::vector<vtkm::Id> pointIndexProxyBuffer(static_cast<std::size_t>(numPoints));
|
||||
for (std::size_t index = 0; index < pointIndexProxyBuffer.size(); ++index)
|
||||
{
|
||||
pointIndexProxyBuffer[index] = static_cast<vtkm::Id>(1000000 - index);
|
||||
}
|
||||
vtkm::VecCConst<vtkm::Id> pointIndexProxy(&pointIndexProxyBuffer.at(0), numPoints);
|
||||
|
||||
vtkm::IdComponent numEdges = vtkm::exec::CellEdgeNumberOfEdges(numPoints, shape, workletProxy);
|
||||
VTKM_TEST_ASSERT(numEdges > 0, "No edges?");
|
||||
|
||||
@ -103,6 +111,12 @@ struct TestCellFacesFunctor
|
||||
VTKM_TEST_ASSERT(edgeSet.find(edge) != edgeSet.end(), "Edge in face not in cell's edges");
|
||||
edgesFoundInFaces.insert(edge);
|
||||
}
|
||||
|
||||
vtkm::Id3 cononicalFaceId =
|
||||
vtkm::exec::CellFaceCononicalId(faceIndex, shape, pointIndexProxy, workletProxy);
|
||||
VTKM_TEST_ASSERT(cononicalFaceId[0] > 0, "Not using global ids?");
|
||||
VTKM_TEST_ASSERT(cononicalFaceId[0] < cononicalFaceId[1], "Bad order.");
|
||||
VTKM_TEST_ASSERT(cononicalFaceId[1] < cononicalFaceId[2], "Bad order.");
|
||||
}
|
||||
VTKM_TEST_ASSERT(edgesFoundInFaces.size() == edgeSet.size(),
|
||||
"Faces did not contain all edges in cell");
|
||||
|
@ -425,72 +425,7 @@ struct ExternalFaces
|
||||
vtkm::Id inputIndex,
|
||||
vtkm::IdComponent visitIndex) const
|
||||
{
|
||||
vtkm::VecCConst<vtkm::IdComponent> localFaceIndices =
|
||||
vtkm::exec::CellFaceLocalIndices(visitIndex, shape, *this);
|
||||
|
||||
VTKM_ASSERT(localFaceIndices.GetNumberOfComponents() >= 3);
|
||||
|
||||
//Assign cell points/nodes to this face
|
||||
vtkm::Id faceP1 = cellNodeIds[localFaceIndices[0]];
|
||||
vtkm::Id faceP2 = cellNodeIds[localFaceIndices[1]];
|
||||
vtkm::Id faceP3 = cellNodeIds[localFaceIndices[2]];
|
||||
|
||||
//Sort the first 3 face points/nodes in ascending order
|
||||
vtkm::Id sorted[3] = { faceP1, faceP2, faceP3 };
|
||||
vtkm::Id temp;
|
||||
if (sorted[0] > sorted[2])
|
||||
{
|
||||
temp = sorted[0];
|
||||
sorted[0] = sorted[2];
|
||||
sorted[2] = temp;
|
||||
}
|
||||
if (sorted[0] > sorted[1])
|
||||
{
|
||||
temp = sorted[0];
|
||||
sorted[0] = sorted[1];
|
||||
sorted[1] = temp;
|
||||
}
|
||||
if (sorted[1] > sorted[2])
|
||||
{
|
||||
temp = sorted[1];
|
||||
sorted[1] = sorted[2];
|
||||
sorted[2] = temp;
|
||||
}
|
||||
|
||||
// Check the rest of the points to see if they are in the lowest 3
|
||||
vtkm::IdComponent numPointsInFace = localFaceIndices.GetNumberOfComponents();
|
||||
for (vtkm::IdComponent pointIndex = 3; pointIndex < numPointsInFace; pointIndex++)
|
||||
{
|
||||
vtkm::Id nextPoint = cellNodeIds[localFaceIndices[pointIndex]];
|
||||
if (nextPoint < sorted[2])
|
||||
{
|
||||
if (nextPoint < sorted[1])
|
||||
{
|
||||
sorted[2] = sorted[1];
|
||||
if (nextPoint < sorted[0])
|
||||
{
|
||||
sorted[1] = sorted[0];
|
||||
sorted[0] = nextPoint;
|
||||
}
|
||||
else // nextPoint > P0, nextPoint < P1
|
||||
{
|
||||
sorted[1] = nextPoint;
|
||||
}
|
||||
}
|
||||
else // nextPoint > P1, nextPoint < P2
|
||||
{
|
||||
sorted[2] = nextPoint;
|
||||
}
|
||||
}
|
||||
else // nextPoint > P2
|
||||
{
|
||||
// Do nothing. nextPoint not in top 3.
|
||||
}
|
||||
}
|
||||
|
||||
faceHash[0] = sorted[0];
|
||||
faceHash[1] = sorted[1];
|
||||
faceHash[2] = sorted[2];
|
||||
faceHash = vtkm::exec::CellFaceCononicalId(visitIndex, shape, cellNodeIds, *this);
|
||||
|
||||
cellIndex = inputIndex;
|
||||
faceIndex = visitIndex;
|
||||
|
@ -50,13 +50,17 @@ vtkm::cont::DataSet RunExternalFaces(vtkm::cont::DataSet& inDataSet)
|
||||
|
||||
//Run the External Faces worklet
|
||||
if (inCellSet.IsSameType(vtkm::cont::CellSetStructured<3>()))
|
||||
{
|
||||
vtkm::worklet::ExternalFaces().Run(inCellSet.Cast<vtkm::cont::CellSetStructured<3>>(),
|
||||
inDataSet.GetCoordinateSystem(),
|
||||
outCellSet,
|
||||
MyDeviceAdapter());
|
||||
}
|
||||
else
|
||||
{
|
||||
vtkm::worklet::ExternalFaces().Run(
|
||||
inCellSet.Cast<vtkm::cont::CellSetExplicit<>>(), outCellSet, MyDeviceAdapter());
|
||||
}
|
||||
|
||||
vtkm::cont::DataSet outDataSet;
|
||||
for (vtkm::IdComponent i = 0; i < inDataSet.GetNumberOfCoordinateSystems(); ++i)
|
||||
|
Loading…
Reference in New Issue
Block a user