Added mapping of cell data onto output dataset

This commit is contained in:
Patricia Kroll Fasel - 090207 2017-03-23 17:14:39 -06:00
parent 984af5a2b4
commit 3a1a6aece3
13 changed files with 139 additions and 24 deletions

@ -31,7 +31,6 @@ add_subdirectory(hello_world)
add_subdirectory(isosurface)
add_subdirectory(multi_backend)
add_subdirectory(streamline)
add_subdirectory(tetrahedra)
if(VTKm_ENABLE_RENDERING)
add_subdirectory(rendering)
endif()

@ -47,6 +47,11 @@ if(VTKm_OpenGL_FOUND AND VTKm_GLUT_FOUND)
target_link_libraries(TriangulateUniformGrid_SERIAL PRIVATE ${VTKm_LIBRARIES})
target_compile_options(TriangulateUniformGrid_SERIAL PRIVATE ${VTKm_COMPILE_OPTIONS})
add_executable(TriangulateStructured_SERIAL TriangulateStructured.cxx)
target_include_directories(TriangulateStructured_SERIAL PRIVATE ${VTKm_INCLUDE_DIRS})
target_link_libraries(TriangulateStructured_SERIAL PRIVATE ${VTKm_LIBRARIES})
target_compile_options(TriangulateStructured_SERIAL PRIVATE ${VTKm_COMPILE_OPTIONS})
if(VTKm_CUDA_FOUND)
# Cuda compiles do not respect target_include_directories
cuda_include_directories(${VTKm_INCLUDE_DIRS})

@ -47,6 +47,9 @@ public:
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
const DeviceAdapter& tag);
private:
vtkm::cont::ArrayHandle<vtkm::IdComponent> OutCellsPerCell;
};
}

@ -18,9 +18,40 @@
// this software.
//============================================================================
#include <vtkm/worklet/ScatterCounting.h>
#include <vtkm/worklet/DispatcherMapField.h>
namespace vtkm {
namespace filter {
struct DistributeCellData : public vtkm::worklet::WorkletMapField
{
typedef void ControlSignature(FieldIn<> inIndices,
FieldOut<> outIndices);
typedef void ExecutionSignature(_1, _2);
typedef vtkm::worklet::ScatterCounting ScatterType;
VTKM_CONT
ScatterType GetScatter() const { return this->Scatter; }
template <typename CountArrayType, typename DeviceAdapter>
VTKM_CONT
DistributeCellData(const CountArrayType &countArray,
DeviceAdapter device) :
Scatter(countArray, device) { }
template <typename T>
VTKM_EXEC
void operator()(T inputIndex,
T &outputIndex) const
{
outputIndex = inputIndex;
}
private:
ScatterType Scatter;
};
//-----------------------------------------------------------------------------
inline VTKM_CONT
Tetrahedralize::Tetrahedralize():
@ -37,22 +68,26 @@ vtkm::filter::ResultDataSet Tetrahedralize::DoExecute(
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
const DeviceAdapter& device)
{
typedef vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter> DeviceAlgorithm;
typedef vtkm::cont::CellSetStructured<3> CellSetStructuredType;
typedef vtkm::cont::CellSetExplicit<> CellSetExplicitType;
const vtkm::cont::DynamicCellSet& cells =
input.GetCellSet(this->GetActiveCellSetIndex());
vtkm::Id numberOfCells = cells.GetNumberOfCells();
vtkm::cont::CellSetSingleType<> outCellSet;
vtkm::worklet::Tetrahedralize<DeviceAdapter> worklet;
if (cells.IsType<CellSetStructuredType>())
{
DeviceAlgorithm::Copy(vtkm::cont::ArrayHandleConstant<vtkm::IdComponent>(5, numberOfCells),
this->OutCellsPerCell);
outCellSet = worklet.Run(cells.Cast<CellSetStructuredType>());
}
else
{
outCellSet = worklet.Run(cells.Cast<CellSetExplicitType>());
outCellSet = worklet.Run(cells.Cast<CellSetExplicitType>(), this->OutCellsPerCell);
}
// create the output dataset
@ -74,7 +109,7 @@ bool Tetrahedralize::DoMapField(
const vtkm::cont::ArrayHandle<T, StorageType>& input,
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
const DeviceAdapter&)
const DeviceAdapter& device)
{
// point data is copied as is because it was not collapsed
if(fieldMeta.IsPointField())
@ -83,12 +118,19 @@ bool Tetrahedralize::DoMapField(
return true;
}
// cell data for structured will be ScatterIndex(2) because every cell became two
// cell data must be scattered to the cells created per input cell
if(fieldMeta.IsCellField())
{
result.GetDataSet().AddField(fieldMeta.AsField(input));
vtkm::cont::ArrayHandle<T, StorageType> output;
DistributeCellData distribute(this->OutCellsPerCell, device);
vtkm::worklet::DispatcherMapField<DistributeCellData, DeviceAdapter> dispatcher(distribute);
dispatcher.Invoke(input, output);
result.GetDataSet().AddField(fieldMeta.AsField(output));
return true;
}
return false;
}

@ -47,6 +47,9 @@ public:
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
const DeviceAdapter& tag);
private:
vtkm::cont::ArrayHandle<vtkm::IdComponent> OutCellsPerCell;
};
}

@ -18,13 +18,45 @@
// this software.
//============================================================================
#include <vtkm/worklet/ScatterCounting.h>
#include <vtkm/worklet/DispatcherMapField.h>
namespace vtkm {
namespace filter {
struct DistributeCellData : public vtkm::worklet::WorkletMapField
{
typedef void ControlSignature(FieldIn<> inIndices,
FieldOut<> outIndices);
typedef void ExecutionSignature(_1, _2);
typedef vtkm::worklet::ScatterCounting ScatterType;
VTKM_CONT
ScatterType GetScatter() const { return this->Scatter; }
template <typename CountArrayType, typename DeviceAdapter>
VTKM_CONT
DistributeCellData(const CountArrayType &countArray,
DeviceAdapter device) :
Scatter(countArray, device) { }
template <typename T>
VTKM_EXEC
void operator()(T inputIndex,
T &outputIndex) const
{
outputIndex = inputIndex;
}
private:
ScatterType Scatter;
};
//-----------------------------------------------------------------------------
inline VTKM_CONT
Triangulate::Triangulate():
vtkm::filter::FilterDataSet<Triangulate>()
vtkm::filter::FilterDataSet<Triangulate>(),
OutCellsPerCell()
{
}
@ -37,22 +69,26 @@ vtkm::filter::ResultDataSet Triangulate::DoExecute(
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
const DeviceAdapter& device)
{
typedef vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter> DeviceAlgorithm;
typedef vtkm::cont::CellSetStructured<2> CellSetStructuredType;
typedef vtkm::cont::CellSetExplicit<> CellSetExplicitType;
const vtkm::cont::DynamicCellSet& cells =
input.GetCellSet(this->GetActiveCellSetIndex());
vtkm::Id numberOfCells = cells.GetNumberOfCells();
vtkm::cont::CellSetSingleType<> outCellSet;
vtkm::worklet::Triangulate<DeviceAdapter> worklet;
if (cells.IsType<CellSetStructuredType>())
{
DeviceAlgorithm::Copy(vtkm::cont::ArrayHandleConstant<vtkm::IdComponent>(2, numberOfCells),
this->OutCellsPerCell);
outCellSet = worklet.Run(cells.Cast<CellSetStructuredType>());
}
else
{
outCellSet = worklet.Run(cells.Cast<CellSetExplicitType>());
outCellSet = worklet.Run(cells.Cast<CellSetExplicitType>(), this->OutCellsPerCell);
}
// create the output dataset
@ -74,7 +110,7 @@ bool Triangulate::DoMapField(
const vtkm::cont::ArrayHandle<T, StorageType>& input,
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
const DeviceAdapter&)
const DeviceAdapter& device)
{
// point data is copied as is because it was not collapsed
if(fieldMeta.IsPointField())
@ -83,12 +119,19 @@ bool Triangulate::DoMapField(
return true;
}
// cell data for structured will be ScatterIndex(2) because every cell became two
// cell data must be scattered to the cells created per input cell
if(fieldMeta.IsCellField())
{
result.GetDataSet().AddField(fieldMeta.AsField(input));
vtkm::cont::ArrayHandle<T, StorageType> output;
DistributeCellData distribute(this->OutCellsPerCell, device);
vtkm::worklet::DispatcherMapField<DistributeCellData, DeviceAdapter> dispatcher(distribute);
dispatcher.Invoke(input, output);
result.GetDataSet().AddField(fieldMeta.AsField(output));
return true;
}
return false;
}

@ -48,6 +48,14 @@ public:
"Wrong result for Triangulate");
VTKM_TEST_ASSERT(test_equal(output.GetField("pointvar").GetData().GetNumberOfValues(), 25),
"Wrong number of points for Triangulate");
vtkm::cont::ArrayHandle<vtkm::Float32> outData =
output.GetField("cellvar").GetData().Cast<vtkm::cont::ArrayHandle<vtkm::Float32> >();
VTKM_TEST_ASSERT(outData.GetPortalConstControl().Get(2) == 1.f, "Wrong cell field data");
VTKM_TEST_ASSERT(outData.GetPortalConstControl().Get(3) == 1.f, "Wrong cell field data");
VTKM_TEST_ASSERT(outData.GetPortalConstControl().Get(30) == 15.f, "Wrong cell field data");
VTKM_TEST_ASSERT(outData.GetPortalConstControl().Get(31) == 15.f, "Wrong cell field data");
}
void TestExplicit() const
@ -68,6 +76,14 @@ public:
"Wrong result for Triangulate");
VTKM_TEST_ASSERT(test_equal(output.GetField("pointvar").GetData().GetNumberOfValues(), 16),
"Wrong number of points for Triangulate");
vtkm::cont::ArrayHandle<vtkm::Float32> outData =
output.GetField("cellvar").GetData().Cast<vtkm::cont::ArrayHandle<vtkm::Float32> >();
VTKM_TEST_ASSERT(outData.GetPortalConstControl().Get(1) == 1.f, "Wrong cell field data");
VTKM_TEST_ASSERT(outData.GetPortalConstControl().Get(2) == 1.f, "Wrong cell field data");
VTKM_TEST_ASSERT(outData.GetPortalConstControl().Get(5) == 3.f, "Wrong cell field data");
VTKM_TEST_ASSERT(outData.GetPortalConstControl().Get(6) == 3.f, "Wrong cell field data");
}
void operator()() const

@ -32,10 +32,11 @@ class Tetrahedralize
public:
Tetrahedralize() {}
vtkm::cont::CellSetSingleType<> Run(const vtkm::cont::CellSetExplicit<> &cellSet)
vtkm::cont::CellSetSingleType<> Run(const vtkm::cont::CellSetExplicit<> &cellSet,
vtkm::cont::ArrayHandle<vtkm::IdComponent> &outCellsPerCell)
{
TetrahedralizeExplicit<DeviceAdapter> worklet;
return worklet.Run(cellSet);
return worklet.Run(cellSet, outCellsPerCell);
}
vtkm::cont::CellSetSingleType<> Run(const vtkm::cont::CellSetStructured<3> &cellSet)

@ -32,10 +32,11 @@ class Triangulate
public:
Triangulate() {}
vtkm::cont::CellSetSingleType<> Run(const vtkm::cont::CellSetExplicit<> &cellSet)
vtkm::cont::CellSetSingleType<> Run(const vtkm::cont::CellSetExplicit<> &cellSet,
vtkm::cont::ArrayHandle<vtkm::IdComponent> &outCellsPerCell)
{
TriangulateExplicit<DeviceAdapter> worklet;
return worklet.Run(cellSet);
return worklet.Run(cellSet, outCellsPerCell);
}
vtkm::cont::CellSetSingleType<> Run(const vtkm::cont::CellSetStructured<2> &cellSet)

@ -75,10 +75,11 @@ public:
vtkm::cont::DataSet dataSet = MakeTestDataSet().Make3DExplicitDataSet5();
CellSetType cellSet;
dataSet.GetCellSet(0).CopyTo(cellSet);
vtkm::cont::ArrayHandle<vtkm::IdComponent> outCellsPerCell;
// Convert explicit cells to tetrahedra
vtkm::worklet::Tetrahedralize<DeviceAdapter> tetrahedralize;
OutCellSetType outCellSet = tetrahedralize.Run(cellSet);
OutCellSetType outCellSet = tetrahedralize.Run(cellSet, outCellsPerCell);
// Create the output dataset explicit cell set with same coordinate system
vtkm::cont::DataSet outDataSet;

@ -67,10 +67,11 @@ public:
vtkm::cont::DataSet dataSet = MakeTestDataSet().Make2DExplicitDataSet0();
CellSetType cellSet;
dataSet.GetCellSet(0).CopyTo(cellSet);
vtkm::cont::ArrayHandle<vtkm::IdComponent> outCellsPerCell;
// Convert explicit cells to triangles
vtkm::worklet::Triangulate<DeviceAdapter> triangulate;
OutCellSetType outCellSet = triangulate.Run(cellSet);
OutCellSetType outCellSet = triangulate.Run(cellSet, outCellsPerCell);
// Create the output dataset explicit cell set with same coordinate system
vtkm::cont::DataSet outDataSet;

@ -121,7 +121,8 @@ public:
};
template <typename CellSetType>
vtkm::cont::CellSetSingleType<> Run(const CellSetType &cellSet)
vtkm::cont::CellSetSingleType<> Run(const CellSetType &cellSet,
vtkm::cont::ArrayHandle<vtkm::IdComponent> &outCellsPerCell)
{
vtkm::cont::CellSetSingleType<> outCellSet(cellSet.GetName());
@ -139,15 +140,14 @@ public:
vtkm::worklet::internal::TetrahedralizeTables tables;
// Determine the number of output cells each input cell will generate
vtkm::cont::ArrayHandle<vtkm::IdComponent> numOutCellArray;
vtkm::worklet::DispatcherMapField<TetrahedraPerCell,DeviceAdapter>
tetPerCellDispatcher;
tetPerCellDispatcher.Invoke(inShapes,
tables.PrepareForInput(DeviceAdapter()),
numOutCellArray);
outCellsPerCell);
// Build new cells
TetrahedralizeCell tetrahedralizeWorklet(numOutCellArray);
TetrahedralizeCell tetrahedralizeWorklet(outCellsPerCell);
vtkm::worklet::DispatcherMapTopology<TetrahedralizeCell,DeviceAdapter>
tetrahedralizeDispatcher(tetrahedralizeWorklet);
tetrahedralizeDispatcher.Invoke(cellSet,

@ -123,7 +123,8 @@ public:
};
template <typename CellSetType>
vtkm::cont::CellSetSingleType<> Run(const CellSetType &cellSet)
vtkm::cont::CellSetSingleType<> Run(const CellSetType &cellSet,
vtkm::cont::ArrayHandle<vtkm::IdComponent> &outCellsPerCell)
{
vtkm::cont::CellSetSingleType<> outCellSet(cellSet.GetName());
@ -141,16 +142,15 @@ public:
vtkm::worklet::internal::TriangulateTables tables;
// Determine the number of output cells each input cell will generate
vtkm::cont::ArrayHandle<vtkm::IdComponent> numOutCellArray;
vtkm::worklet::DispatcherMapField<TrianglesPerCell,DeviceAdapter>
triPerCellDispatcher;
triPerCellDispatcher.Invoke(inShapes,
inNumIndices,
tables.PrepareForInput(DeviceAdapter()),
numOutCellArray);
outCellsPerCell);
// Build new cells
TriangulateCell triangulateWorklet(numOutCellArray);
TriangulateCell triangulateWorklet(outCellsPerCell);
vtkm::worklet::DispatcherMapTopology<TriangulateCell,DeviceAdapter>
triangulateDispatcher(triangulateWorklet);
triangulateDispatcher.Invoke(cellSet,