From 3a1a6aece3ff97f2f9d273b52c62c2733d42385a Mon Sep 17 00:00:00 2001 From: Patricia Kroll Fasel - 090207 Date: Thu, 23 Mar 2017 17:14:39 -0600 Subject: [PATCH] Added mapping of cell data onto output dataset --- examples/CMakeLists.txt | 1 - examples/tetrahedra/CMakeLists.txt | 5 ++ vtkm/filter/Tetrahedralize.h | 3 ++ vtkm/filter/Tetrahedralize.hxx | 50 +++++++++++++++-- vtkm/filter/Triangulate.h | 3 ++ vtkm/filter/Triangulate.hxx | 53 +++++++++++++++++-- .../testing/UnitTestTriangulateFilter.cxx | 16 ++++++ vtkm/worklet/Tetrahedralize.h | 5 +- vtkm/worklet/Triangulate.h | 5 +- .../testing/UnitTestTetrahedralize.cxx | 3 +- vtkm/worklet/testing/UnitTestTriangulate.cxx | 3 +- .../tetrahedralize/TetrahedralizeExplicit.h | 8 +-- .../worklet/triangulate/TriangulateExplicit.h | 8 +-- 13 files changed, 139 insertions(+), 24 deletions(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 95edf8f5c..2605031c3 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -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() diff --git a/examples/tetrahedra/CMakeLists.txt b/examples/tetrahedra/CMakeLists.txt index a062c2ca0..c60eb7634 100644 --- a/examples/tetrahedra/CMakeLists.txt +++ b/examples/tetrahedra/CMakeLists.txt @@ -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}) diff --git a/vtkm/filter/Tetrahedralize.h b/vtkm/filter/Tetrahedralize.h index 914dc8eeb..cbe3d5a04 100644 --- a/vtkm/filter/Tetrahedralize.h +++ b/vtkm/filter/Tetrahedralize.h @@ -47,6 +47,9 @@ public: const vtkm::filter::FieldMetadata& fieldMeta, const vtkm::filter::PolicyBase& policy, const DeviceAdapter& tag); + +private: + vtkm::cont::ArrayHandle OutCellsPerCell; }; } diff --git a/vtkm/filter/Tetrahedralize.hxx b/vtkm/filter/Tetrahedralize.hxx index db813ee3a..4e1ddfab3 100644 --- a/vtkm/filter/Tetrahedralize.hxx +++ b/vtkm/filter/Tetrahedralize.hxx @@ -18,9 +18,40 @@ // this software. //============================================================================ +#include +#include + 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 + VTKM_CONT + DistributeCellData(const CountArrayType &countArray, + DeviceAdapter device) : + Scatter(countArray, device) { } + + template + 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& policy, const DeviceAdapter& device) { + typedef vtkm::cont::DeviceAdapterAlgorithm 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 worklet; if (cells.IsType()) { + DeviceAlgorithm::Copy(vtkm::cont::ArrayHandleConstant(5, numberOfCells), + this->OutCellsPerCell); outCellSet = worklet.Run(cells.Cast()); } else { - outCellSet = worklet.Run(cells.Cast()); + outCellSet = worklet.Run(cells.Cast(), this->OutCellsPerCell); } // create the output dataset @@ -74,7 +109,7 @@ bool Tetrahedralize::DoMapField( const vtkm::cont::ArrayHandle& input, const vtkm::filter::FieldMetadata& fieldMeta, const vtkm::filter::PolicyBase& 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 output; + + DistributeCellData distribute(this->OutCellsPerCell, device); + vtkm::worklet::DispatcherMapField dispatcher(distribute); + dispatcher.Invoke(input, output); + + result.GetDataSet().AddField(fieldMeta.AsField(output)); return true; } + return false; } diff --git a/vtkm/filter/Triangulate.h b/vtkm/filter/Triangulate.h index 12b49a634..93f1af869 100644 --- a/vtkm/filter/Triangulate.h +++ b/vtkm/filter/Triangulate.h @@ -47,6 +47,9 @@ public: const vtkm::filter::FieldMetadata& fieldMeta, const vtkm::filter::PolicyBase& policy, const DeviceAdapter& tag); + +private: + vtkm::cont::ArrayHandle OutCellsPerCell; }; } diff --git a/vtkm/filter/Triangulate.hxx b/vtkm/filter/Triangulate.hxx index a14dd0bf0..de29f4fc8 100644 --- a/vtkm/filter/Triangulate.hxx +++ b/vtkm/filter/Triangulate.hxx @@ -18,13 +18,45 @@ // this software. //============================================================================ +#include +#include + 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 + VTKM_CONT + DistributeCellData(const CountArrayType &countArray, + DeviceAdapter device) : + Scatter(countArray, device) { } + + template + VTKM_EXEC + void operator()(T inputIndex, + T &outputIndex) const + { + outputIndex = inputIndex; + } +private: + ScatterType Scatter; +}; + //----------------------------------------------------------------------------- inline VTKM_CONT Triangulate::Triangulate(): - vtkm::filter::FilterDataSet() + vtkm::filter::FilterDataSet(), + OutCellsPerCell() { } @@ -37,22 +69,26 @@ vtkm::filter::ResultDataSet Triangulate::DoExecute( const vtkm::filter::PolicyBase& policy, const DeviceAdapter& device) { + typedef vtkm::cont::DeviceAdapterAlgorithm 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 worklet; if (cells.IsType()) { + DeviceAlgorithm::Copy(vtkm::cont::ArrayHandleConstant(2, numberOfCells), + this->OutCellsPerCell); outCellSet = worklet.Run(cells.Cast()); } else { - outCellSet = worklet.Run(cells.Cast()); + outCellSet = worklet.Run(cells.Cast(), this->OutCellsPerCell); } // create the output dataset @@ -74,7 +110,7 @@ bool Triangulate::DoMapField( const vtkm::cont::ArrayHandle& input, const vtkm::filter::FieldMetadata& fieldMeta, const vtkm::filter::PolicyBase& 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 output; + + DistributeCellData distribute(this->OutCellsPerCell, device); + vtkm::worklet::DispatcherMapField dispatcher(distribute); + dispatcher.Invoke(input, output); + + result.GetDataSet().AddField(fieldMeta.AsField(output)); return true; } + return false; } diff --git a/vtkm/filter/testing/UnitTestTriangulateFilter.cxx b/vtkm/filter/testing/UnitTestTriangulateFilter.cxx index 4b930feb5..945c6ddc3 100644 --- a/vtkm/filter/testing/UnitTestTriangulateFilter.cxx +++ b/vtkm/filter/testing/UnitTestTriangulateFilter.cxx @@ -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 outData = + output.GetField("cellvar").GetData().Cast >(); + + 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 outData = + output.GetField("cellvar").GetData().Cast >(); + + 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 diff --git a/vtkm/worklet/Tetrahedralize.h b/vtkm/worklet/Tetrahedralize.h index 92ab9fa28..f90e6e360 100644 --- a/vtkm/worklet/Tetrahedralize.h +++ b/vtkm/worklet/Tetrahedralize.h @@ -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 &outCellsPerCell) { TetrahedralizeExplicit worklet; - return worklet.Run(cellSet); + return worklet.Run(cellSet, outCellsPerCell); } vtkm::cont::CellSetSingleType<> Run(const vtkm::cont::CellSetStructured<3> &cellSet) diff --git a/vtkm/worklet/Triangulate.h b/vtkm/worklet/Triangulate.h index 3142802d6..e2cffcb3e 100644 --- a/vtkm/worklet/Triangulate.h +++ b/vtkm/worklet/Triangulate.h @@ -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 &outCellsPerCell) { TriangulateExplicit worklet; - return worklet.Run(cellSet); + return worklet.Run(cellSet, outCellsPerCell); } vtkm::cont::CellSetSingleType<> Run(const vtkm::cont::CellSetStructured<2> &cellSet) diff --git a/vtkm/worklet/testing/UnitTestTetrahedralize.cxx b/vtkm/worklet/testing/UnitTestTetrahedralize.cxx index 2e339aba7..94af4f970 100644 --- a/vtkm/worklet/testing/UnitTestTetrahedralize.cxx +++ b/vtkm/worklet/testing/UnitTestTetrahedralize.cxx @@ -75,10 +75,11 @@ public: vtkm::cont::DataSet dataSet = MakeTestDataSet().Make3DExplicitDataSet5(); CellSetType cellSet; dataSet.GetCellSet(0).CopyTo(cellSet); + vtkm::cont::ArrayHandle outCellsPerCell; // Convert explicit cells to tetrahedra vtkm::worklet::Tetrahedralize 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; diff --git a/vtkm/worklet/testing/UnitTestTriangulate.cxx b/vtkm/worklet/testing/UnitTestTriangulate.cxx index d94b58c83..3df4ca2cb 100644 --- a/vtkm/worklet/testing/UnitTestTriangulate.cxx +++ b/vtkm/worklet/testing/UnitTestTriangulate.cxx @@ -67,10 +67,11 @@ public: vtkm::cont::DataSet dataSet = MakeTestDataSet().Make2DExplicitDataSet0(); CellSetType cellSet; dataSet.GetCellSet(0).CopyTo(cellSet); + vtkm::cont::ArrayHandle outCellsPerCell; // Convert explicit cells to triangles vtkm::worklet::Triangulate 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; diff --git a/vtkm/worklet/tetrahedralize/TetrahedralizeExplicit.h b/vtkm/worklet/tetrahedralize/TetrahedralizeExplicit.h index 4a7e3f5e4..b56acd532 100644 --- a/vtkm/worklet/tetrahedralize/TetrahedralizeExplicit.h +++ b/vtkm/worklet/tetrahedralize/TetrahedralizeExplicit.h @@ -121,7 +121,8 @@ public: }; template - vtkm::cont::CellSetSingleType<> Run(const CellSetType &cellSet) + vtkm::cont::CellSetSingleType<> Run(const CellSetType &cellSet, + vtkm::cont::ArrayHandle &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 numOutCellArray; vtkm::worklet::DispatcherMapField tetPerCellDispatcher; tetPerCellDispatcher.Invoke(inShapes, tables.PrepareForInput(DeviceAdapter()), - numOutCellArray); + outCellsPerCell); // Build new cells - TetrahedralizeCell tetrahedralizeWorklet(numOutCellArray); + TetrahedralizeCell tetrahedralizeWorklet(outCellsPerCell); vtkm::worklet::DispatcherMapTopology tetrahedralizeDispatcher(tetrahedralizeWorklet); tetrahedralizeDispatcher.Invoke(cellSet, diff --git a/vtkm/worklet/triangulate/TriangulateExplicit.h b/vtkm/worklet/triangulate/TriangulateExplicit.h index b988c6307..d6719cad2 100644 --- a/vtkm/worklet/triangulate/TriangulateExplicit.h +++ b/vtkm/worklet/triangulate/TriangulateExplicit.h @@ -123,7 +123,8 @@ public: }; template - vtkm::cont::CellSetSingleType<> Run(const CellSetType &cellSet) + vtkm::cont::CellSetSingleType<> Run(const CellSetType &cellSet, + vtkm::cont::ArrayHandle &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 numOutCellArray; vtkm::worklet::DispatcherMapField triPerCellDispatcher; triPerCellDispatcher.Invoke(inShapes, inNumIndices, tables.PrepareForInput(DeviceAdapter()), - numOutCellArray); + outCellsPerCell); // Build new cells - TriangulateCell triangulateWorklet(numOutCellArray); + TriangulateCell triangulateWorklet(outCellsPerCell); vtkm::worklet::DispatcherMapTopology triangulateDispatcher(triangulateWorklet); triangulateDispatcher.Invoke(cellSet,