From 52d8a4d9b76710a51e551be330233337f36a2cca Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Tue, 12 Jan 2016 16:29:54 -0500 Subject: [PATCH 01/12] Fix vtkm::cont::Field default constructor to have valid values. --- vtkm/cont/Field.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vtkm/cont/Field.h b/vtkm/cont/Field.h index 9e879a493..6521a78ea 100644 --- a/vtkm/cont/Field.h +++ b/vtkm/cont/Field.h @@ -481,7 +481,7 @@ public: Field() : Name(), Order(), - Association(), + Association(ASSOC_ANY), AssocCellSetName(), AssocLogicalDim(), Data(), From 4b7054f4da73eb17e42c780a0fc9d076d008bd7a Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Wed, 20 Jan 2016 12:04:05 -0500 Subject: [PATCH 02/12] Changes to computing bounds to allow custom types and storage. --- vtkm/cont/CoordinateSystem.h | 48 +++++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/vtkm/cont/CoordinateSystem.h b/vtkm/cont/CoordinateSystem.h index d042f61da..293594116 100644 --- a/vtkm/cont/CoordinateSystem.h +++ b/vtkm/cont/CoordinateSystem.h @@ -140,14 +140,14 @@ public: this->Superclass::GetData()); } - template + template VTKM_CONT_EXPORT - const vtkm::cont::ArrayHandle& GetBounds(DeviceAdapterTag, - TypeList) const + void GetBounds(vtkm::Float64 *bounds, DeviceAdapterTag) const { - return this->Superclass::GetBounds( + this->Superclass::GetBounds( + bounds, DeviceAdapterTag(), - TypeList(), + VTKM_DEFAULT_COORDINATE_SYSTEM_TYPE_LIST_TAG(), VTKM_DEFAULT_COORDINATE_SYSTEM_STORAGE_LIST_TAG()); } @@ -156,11 +156,23 @@ public: void GetBounds(vtkm::Float64 *bounds, DeviceAdapterTag, TypeList) const { this->Superclass::GetBounds( - bounds, DeviceAdapterTag(), + bounds, + DeviceAdapterTag(), TypeList(), VTKM_DEFAULT_COORDINATE_SYSTEM_STORAGE_LIST_TAG()); } + template + VTKM_CONT_EXPORT + void GetBounds(vtkm::Float64 *bounds, DeviceAdapterTag, TypeList, StorageList) const + { + this->Superclass::GetBounds( + bounds, + DeviceAdapterTag(), + TypeList(), + StorageList()); + } + template VTKM_CONT_EXPORT const vtkm::cont::ArrayHandle& GetBounds(DeviceAdapterTag) const @@ -171,17 +183,31 @@ public: VTKM_DEFAULT_COORDINATE_SYSTEM_STORAGE_LIST_TAG()); } - template + template VTKM_CONT_EXPORT - void GetBounds(vtkm::Float64 *bounds, DeviceAdapterTag) const + const vtkm::cont::ArrayHandle& GetBounds(DeviceAdapterTag, + TypeList) const { - this->Superclass::GetBounds( - bounds, + return this->Superclass::GetBounds( DeviceAdapterTag(), - VTKM_DEFAULT_COORDINATE_SYSTEM_TYPE_LIST_TAG(), + TypeList(), VTKM_DEFAULT_COORDINATE_SYSTEM_STORAGE_LIST_TAG()); } + template + VTKM_CONT_EXPORT + const vtkm::cont::ArrayHandle& GetBounds(DeviceAdapterTag, + TypeList, + StorageList) const + { + return this->Superclass::GetBounds( + DeviceAdapterTag(), + TypeList(), + StorageList()); + } + + + VTKM_CONT_EXPORT virtual void PrintSummary(std::ostream &out) const { From aaa10f0c509b1d0830dee1efc8ba2804bb8846f7 Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Wed, 20 Jan 2016 12:04:43 -0500 Subject: [PATCH 03/12] Remove the ability to get bounds from Make3DExplicitDataSetCowNose. This isn't needed now that vtkm::cont::Field can compute bounds. --- vtkm/cont/testing/MakeTestDataSet.h | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/vtkm/cont/testing/MakeTestDataSet.h b/vtkm/cont/testing/MakeTestDataSet.h index 48602b964..11e7f908b 100644 --- a/vtkm/cont/testing/MakeTestDataSet.h +++ b/vtkm/cont/testing/MakeTestDataSet.h @@ -50,7 +50,7 @@ public: // 3D explicit datasets. vtkm::cont::DataSet Make3DExplicitDataSet0(); vtkm::cont::DataSet Make3DExplicitDataSet1(); - vtkm::cont::DataSet Make3DExplicitDataSetCowNose(double *pBounds = NULL); + vtkm::cont::DataSet Make3DExplicitDataSetCowNose(); }; @@ -287,7 +287,7 @@ MakeTestDataSet::Make3DExplicitDataSet1() } inline vtkm::cont::DataSet -MakeTestDataSet::Make3DExplicitDataSetCowNose(double *pBounds) +MakeTestDataSet::Make3DExplicitDataSetCowNose() { // prepare data array const int nVerts = 17; @@ -333,7 +333,6 @@ MakeTestDataSet::Make3DExplicitDataSetCowNose(double *pBounds) 0, 15, 10, 7, 6, 0 }; - double _bounds[6] = {-0.000169, 0.048088, 0.001378, 0.250062, 0.053925, 0.200755}; // create DataSet vtkm::cont::DataSet dataSet; @@ -352,15 +351,6 @@ MakeTestDataSet::Make3DExplicitDataSetCowNose(double *pBounds) cellSet.Fill(connectivity); dataSet.AddCellSet(cellSet); - // copy bounds - if (pBounds != NULL) - { - for (vtkm::IdComponent i=0; i<6; i++) - { - pBounds[i] = _bounds[i]; - } - } - return dataSet; } From 531dececfdc45afdacdf96d312a2790841d8f01f Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Wed, 20 Jan 2016 12:05:48 -0500 Subject: [PATCH 04/12] Multiple changes to VertexClustering to make it more suitable for filter. The original implementation wasn't flexible enough to handle the requirements that filter requires ( mainly policy support ). --- vtkm/worklet/VertexClustering.h | 26 ++++++++++--------- .../testing/UnitTestVertexClustering.cxx | 12 ++++++--- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/vtkm/worklet/VertexClustering.h b/vtkm/worklet/VertexClustering.h index 79ffa0653..8e621e57e 100644 --- a/vtkm/worklet/VertexClustering.h +++ b/vtkm/worklet/VertexClustering.h @@ -313,14 +313,16 @@ public: /////////////////////////////////////////////////// /// \brief VertexClustering: Mesh simplification /// - template - vtkm::cont::DataSet Run(const vtkm::cont::DynamicCellSet &cellSet, - const vtkm::cont::CoordinateSystem &coordinates, - vtkm::Id nDivisions, + template + vtkm::cont::DataSet Run(const DynamicCellSetType &cellSet, + const DynamicCoordinateHandleType &coordinates, + vtkm::Float64 *bounds, + const vtkm::Id3& nDivisions, DeviceAdapter) { - vtkm::Float64 bounds[6]; - coordinates.GetBounds(bounds, DeviceAdapter()); + /// determine grid resolution for clustering GridInfo gridInfo; @@ -328,16 +330,16 @@ public: vtkm::Float64 res[3]; for (vtkm::IdComponent i=0; i<3; i++) { - res[i] = (bounds[i*2+1]-bounds[i*2])/nDivisions; + res[i] = (bounds[i*2+1]-bounds[i*2])/nDivisions[i]; } gridInfo.grid_width = vtkm::Max(res[0], vtkm::Max(res[1], res[2])); vtkm::Float64 inv_grid_width = gridInfo.inv_grid_width = vtkm::Float64(1) / gridInfo.grid_width; //printf("Bounds: %lf, %lf, %lf, %lf, %lf, %lf\n", bounds[0], bounds[1], bounds[2], bounds[3], bounds[4], bounds[5]); - gridInfo.dim[0] = vtkm::Min((vtkm::Id)vtkm::Ceil((bounds[1]-bounds[0])*inv_grid_width), nDivisions); - gridInfo.dim[1] = vtkm::Min((vtkm::Id)vtkm::Ceil((bounds[3]-bounds[2])*inv_grid_width), nDivisions); - gridInfo.dim[2] = vtkm::Min((vtkm::Id)vtkm::Ceil((bounds[5]-bounds[4])*inv_grid_width), nDivisions); + gridInfo.dim[0] = vtkm::Min((vtkm::Id)vtkm::Ceil((bounds[1]-bounds[0])*inv_grid_width), nDivisions[0]); + gridInfo.dim[1] = vtkm::Min((vtkm::Id)vtkm::Ceil((bounds[3]-bounds[2])*inv_grid_width), nDivisions[1]); + gridInfo.dim[2] = vtkm::Min((vtkm::Id)vtkm::Ceil((bounds[5]-bounds[4])*inv_grid_width), nDivisions[2]); // center the mesh in the grids gridInfo.origin[0] = (bounds[1]+bounds[0])*0.5 - gridInfo.grid_width*(gridInfo.dim[0])*.5; @@ -359,7 +361,7 @@ public: vtkm::cont::ArrayHandle pointCidArray; vtkm::worklet::DispatcherMapField( - MapPointsWorklet(gridInfo)).Invoke(coordinates.GetData(), pointCidArray); + MapPointsWorklet(gridInfo)).Invoke(coordinates, pointCidArray); #ifdef __VTKM_VERTEX_CLUSTERING_BENCHMARK std::cout << "Time map points (s): " << timer.GetElapsedTime() << std::endl; @@ -376,7 +378,7 @@ public: vtkm::cont::ArrayHandle, DeviceAdapter> averageByKey(pointCidArray, pointCidArrayReduced, repPointArray); - coordinates.GetData().CastAndCall(averageByKey); + coordinates.CastAndCall(averageByKey); #ifdef __VTKM_VERTEX_CLUSTERING_BENCHMARK std::cout << "Time after averaging (s): " << timer.GetElapsedTime() << std::endl; diff --git a/vtkm/worklet/testing/UnitTestVertexClustering.cxx b/vtkm/worklet/testing/UnitTestVertexClustering.cxx index af217e11a..4503ebc4b 100644 --- a/vtkm/worklet/testing/UnitTestVertexClustering.cxx +++ b/vtkm/worklet/testing/UnitTestVertexClustering.cxx @@ -31,15 +31,19 @@ void TestVertexClustering() { - vtkm::Float64 bounds[6]; - const vtkm::Id divisions = 3; + const vtkm::Id3 divisions(3, 3, 3); vtkm::cont::testing::MakeTestDataSet maker; - vtkm::cont::DataSet dataSet = maker.Make3DExplicitDataSetCowNose(bounds); + vtkm::cont::DataSet dataSet = maker.Make3DExplicitDataSetCowNose(); + + //compute the bounds before calling the algorithm + vtkm::Float64 bounds[6]; + dataSet.GetCoordinateSystem().GetBounds(bounds, VTKM_DEFAULT_DEVICE_ADAPTER_TAG()); // run vtkm::worklet::VertexClustering clustering; vtkm::cont::DataSet outDataSet = clustering.Run(dataSet.GetCellSet(), - dataSet.GetCoordinateSystem(), + dataSet.GetCoordinateSystem().GetData(), + bounds, divisions, VTKM_DEFAULT_DEVICE_ADAPTER_TAG()); From bcee82709787da039306759438e55270a6636892 Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Tue, 19 Jan 2016 09:59:31 -0500 Subject: [PATCH 05/12] First draft of vtkm::filter design. --- vtkm/CMakeLists.txt | 4 + vtkm/filter/CMakeLists.txt | 59 +++ vtkm/filter/CellAverage.h | 55 ++ vtkm/filter/CellAverage.hxx | 71 +++ vtkm/filter/CellFilter.h | 54 ++ vtkm/filter/CellFilter.hxx | 36 ++ vtkm/filter/DataSetFilter.h | 127 +++++ vtkm/filter/DataSetFilter.hxx | 141 +++++ vtkm/filter/DataSetWithFieldFilter.h | 129 +++++ vtkm/filter/DataSetWithFieldFilter.hxx | 204 ++++++++ vtkm/filter/DefaultPolicy.h | 48 ++ vtkm/filter/ExternalFaces.h | 59 +++ vtkm/filter/ExternalFaces.hxx | 137 +++++ vtkm/filter/FieldFilter.h | 130 +++++ vtkm/filter/FieldFilter.hxx | 181 +++++++ vtkm/filter/FieldMetadata.h | 105 ++++ vtkm/filter/FieldTypes.h | 88 ++++ vtkm/filter/FilterTraits.h | 40 ++ vtkm/filter/MarchingCubes.h | 111 ++++ vtkm/filter/MarchingCubes.hxx | 491 ++++++++++++++++++ vtkm/filter/PointElevation.h | 74 +++ vtkm/filter/PointElevation.hxx | 79 +++ vtkm/filter/PolicyBase.h | 123 +++++ vtkm/filter/Threshold.h | 72 +++ vtkm/filter/Threshold.hxx | 188 +++++++ vtkm/filter/VertexClustering.h | 68 +++ vtkm/filter/VertexClustering.hxx | 89 ++++ vtkm/filter/internal/CMakeLists.txt | 27 + .../internal/ResolveFieldTypeAndExecute.h | 303 +++++++++++ vtkm/filter/internal/ResolveFieldTypeAndMap.h | 229 ++++++++ vtkm/filter/internal/RuntimeDeviceTracker.h | 120 +++++ vtkm/filter/testing/CMakeLists.txt | 31 ++ .../testing/UnitTestCellAverageFilter.cxx | 122 +++++ .../testing/UnitTestExternalFacesFilter.cxx | 104 ++++ vtkm/filter/testing/UnitTestFieldMetadata.cxx | 92 ++++ .../testing/UnitTestMarchingCubesFilter.cxx | 366 +++++++++++++ .../testing/UnitTestPointElevationFilter.cxx | 158 ++++++ .../testing/UnitTestThresholdFilter.cxx | 167 ++++++ .../UnitTestVertexClusteringFilter.cxx | 75 +++ 39 files changed, 4757 insertions(+) create mode 100644 vtkm/filter/CMakeLists.txt create mode 100644 vtkm/filter/CellAverage.h create mode 100644 vtkm/filter/CellAverage.hxx create mode 100644 vtkm/filter/CellFilter.h create mode 100644 vtkm/filter/CellFilter.hxx create mode 100644 vtkm/filter/DataSetFilter.h create mode 100644 vtkm/filter/DataSetFilter.hxx create mode 100644 vtkm/filter/DataSetWithFieldFilter.h create mode 100644 vtkm/filter/DataSetWithFieldFilter.hxx create mode 100644 vtkm/filter/DefaultPolicy.h create mode 100644 vtkm/filter/ExternalFaces.h create mode 100644 vtkm/filter/ExternalFaces.hxx create mode 100644 vtkm/filter/FieldFilter.h create mode 100644 vtkm/filter/FieldFilter.hxx create mode 100644 vtkm/filter/FieldMetadata.h create mode 100644 vtkm/filter/FieldTypes.h create mode 100644 vtkm/filter/FilterTraits.h create mode 100644 vtkm/filter/MarchingCubes.h create mode 100644 vtkm/filter/MarchingCubes.hxx create mode 100644 vtkm/filter/PointElevation.h create mode 100644 vtkm/filter/PointElevation.hxx create mode 100644 vtkm/filter/PolicyBase.h create mode 100644 vtkm/filter/Threshold.h create mode 100644 vtkm/filter/Threshold.hxx create mode 100644 vtkm/filter/VertexClustering.h create mode 100644 vtkm/filter/VertexClustering.hxx create mode 100644 vtkm/filter/internal/CMakeLists.txt create mode 100644 vtkm/filter/internal/ResolveFieldTypeAndExecute.h create mode 100644 vtkm/filter/internal/ResolveFieldTypeAndMap.h create mode 100644 vtkm/filter/internal/RuntimeDeviceTracker.h create mode 100644 vtkm/filter/testing/CMakeLists.txt create mode 100644 vtkm/filter/testing/UnitTestCellAverageFilter.cxx create mode 100644 vtkm/filter/testing/UnitTestExternalFacesFilter.cxx create mode 100644 vtkm/filter/testing/UnitTestFieldMetadata.cxx create mode 100644 vtkm/filter/testing/UnitTestMarchingCubesFilter.cxx create mode 100644 vtkm/filter/testing/UnitTestPointElevationFilter.cxx create mode 100644 vtkm/filter/testing/UnitTestThresholdFilter.cxx create mode 100644 vtkm/filter/testing/UnitTestVertexClusteringFilter.cxx diff --git a/vtkm/CMakeLists.txt b/vtkm/CMakeLists.txt index 87ffcca4d..02d60c6e0 100644 --- a/vtkm/CMakeLists.txt +++ b/vtkm/CMakeLists.txt @@ -65,6 +65,10 @@ add_subdirectory(exec) #add the worklet folder add_subdirectory(worklet) +#----------------------------------------------------------------------------- +#add the filter folder +add_subdirectory(filter) + #----------------------------------------------------------------------------- #add the benchmarking folder add_subdirectory(benchmarking) diff --git a/vtkm/filter/CMakeLists.txt b/vtkm/filter/CMakeLists.txt new file mode 100644 index 000000000..26c03f749 --- /dev/null +++ b/vtkm/filter/CMakeLists.txt @@ -0,0 +1,59 @@ +##============================================================================ +## 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 2014 Sandia Corporation. +## Copyright 2014 UT-Battelle, LLC. +## Copyright 2014 Los Alamos National Security. +## +## Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +## 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. +##============================================================================ + +set(headers + CellAverage.h + CellFilter.h + DataSetFilter.h + DataSetWithFieldFilter.h + DefaultPolicy.h + ExternalFaces.h + FieldFilter.h + FieldMetadata.h + FilterTraits.h + MarchingCubes.h + PointElevation.h + PolicyBase.h + Threshold.h + VertexClustering.h +) + +set(header_template_sources + CellAverage.hxx + CellFilter.hxx + DataSetFilter.hxx + DataSetWithFieldFilter.hxx + ExternalFaces.hxx + FieldFilter.hxx + MarchingCubes.hxx + PointElevation.hxx + Threshold.hxx + VertexClustering.hxx +) + +vtkm_declare_headers(${headers}) + +vtkm_install_headers(${header_template_sources}) + +add_subdirectory(internal) + +#----------------------------------------------------------------------------- +add_subdirectory(testing) + diff --git a/vtkm/filter/CellAverage.h b/vtkm/filter/CellAverage.h new file mode 100644 index 000000000..62e06a56e --- /dev/null +++ b/vtkm/filter/CellAverage.h @@ -0,0 +1,55 @@ +//============================================================================ +// 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 2014 Sandia Corporation. +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2014 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// 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. +//============================================================================ + +#ifndef vtk_m_filter_CellAverage_h +#define vtk_m_filter_CellAverage_h + +#include +#include + +namespace vtkm { +namespace filter { + +class CellAverage : public vtkm::filter::CellFilter +{ +public: + VTKM_CONT_EXPORT + CellAverage(); + + template + VTKM_CONT_EXPORT + vtkm::filter::FieldResult DoExecute(const vtkm::cont::DataSet &input, + const vtkm::cont::ArrayHandle& field, + const vtkm::filter::FieldMetadata& fieldMeta, + const vtkm::filter::PolicyBase& policy, + const DeviceAdapter& tag); + +private: + vtkm::worklet::CellAverage Worklet; + +}; + +} +} // namespace vtkm::filter + + +#include + +#endif // vtk_m_filter_CellAverage_h \ No newline at end of file diff --git a/vtkm/filter/CellAverage.hxx b/vtkm/filter/CellAverage.hxx new file mode 100644 index 000000000..44fa3ca7b --- /dev/null +++ b/vtkm/filter/CellAverage.hxx @@ -0,0 +1,71 @@ +//============================================================================ +// 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 2014 Sandia Corporation. +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2014 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// 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 + +#include + +namespace vtkm { +namespace filter { + + +//----------------------------------------------------------------------------- +CellAverage::CellAverage(): + vtkm::filter::CellFilter(), + Worklet() +{ + +} + +//----------------------------------------------------------------------------- +template +vtkm::filter::FieldResult CellAverage::DoExecute(const vtkm::cont::DataSet &input, + const vtkm::cont::ArrayHandle& field, + const vtkm::filter::FieldMetadata&, + const vtkm::filter::PolicyBase&, + const DeviceAdapter&) +{ + vtkm::cont::DynamicCellSet cellSet = + input.GetCellSet(this->GetActiveCellSetIndex()); + + //todo: we need to ask the policy what storage type we should be using + //If the input is implicit, we should know what to fall back to + vtkm::cont::ArrayHandle outArray = field; + + vtkm::worklet::DispatcherMapTopology dispatcher(this->Worklet); + + //todo: we need to use the policy to determine the valid conversions + //that the dispatcher should do, including the result from GetCellSet + dispatcher.Invoke(field, cellSet, outArray); + + vtkm::cont::Field outField(this->GetOutputFieldName(), 1, + vtkm::cont::Field::ASSOC_CELL_SET, + cellSet.GetCellSet().GetName(), + outArray); + + return vtkm::filter::FieldResult(outField); +} + +} +} // namespace vtkm::filter diff --git a/vtkm/filter/CellFilter.h b/vtkm/filter/CellFilter.h new file mode 100644 index 000000000..c96575a0d --- /dev/null +++ b/vtkm/filter/CellFilter.h @@ -0,0 +1,54 @@ +//============================================================================ +// 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 2014 Sandia Corporation. +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2014 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// 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. +//============================================================================ + +#ifndef vtk_m_filter_CellFilter_h +#define vtk_m_filter_CellFilter_h + +#include + +namespace vtkm { +namespace filter { + +template +class CellFilter : public vtkm::filter::FieldFilter< Derived > +{ +public: + VTKM_CONT_EXPORT + CellFilter(); + + VTKM_CONT_EXPORT + void SetActiveCellSet(vtkm::Id index) + { this->CellSetIndex = index; } + + VTKM_CONT_EXPORT + vtkm::Id GetActiveCellSetIndex() const + { return this->CellSetIndex; } + +protected: + vtkm::Id CellSetIndex; +}; + +} +} // namespace vtkm::filter + + +#include + +#endif // vtk_m_filter_CellFilter_h \ No newline at end of file diff --git a/vtkm/filter/CellFilter.hxx b/vtkm/filter/CellFilter.hxx new file mode 100644 index 000000000..dd320c957 --- /dev/null +++ b/vtkm/filter/CellFilter.hxx @@ -0,0 +1,36 @@ +//============================================================================ +// 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 2014 Sandia Corporation. +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2014 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// 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. +//============================================================================ + +namespace vtkm { +namespace filter { + + +//---------------------------------------------------------------------------- +template +CellFilter::CellFilter(): + vtkm::filter::FieldFilter< Derived >(), + CellSetIndex(0) +{ + +} + + +} +} \ No newline at end of file diff --git a/vtkm/filter/DataSetFilter.h b/vtkm/filter/DataSetFilter.h new file mode 100644 index 000000000..9e9820b7a --- /dev/null +++ b/vtkm/filter/DataSetFilter.h @@ -0,0 +1,127 @@ +//============================================================================ +// 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 2014 Sandia Corporation. +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2014 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// 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. +//============================================================================ + +#ifndef vtk_m_filter_DataSetFilter_h +#define vtk_m_filter_DataSetFilter_h + +#include +#include +#include +#include + +#include +#include + +namespace vtkm { +namespace filter { + +class DataSetResult +{ +public: + VTKM_CONT_EXPORT + DataSetResult(): Valid(false), Data() + { } + + VTKM_CONT_EXPORT + DataSetResult(const vtkm::cont::DataSet& ds): Valid(true), Data(ds) + { } + + VTKM_CONT_EXPORT + bool IsValid() const { return this->Valid; } + + VTKM_CONT_EXPORT + const vtkm::cont::DataSet& GetDataSet() const { return this->Data; } + + VTKM_CONT_EXPORT + vtkm::cont::DataSet& GetDataSet() { return this->Data; } + +private: + bool Valid; + vtkm::cont::DataSet Data; +}; + + + +template +class DataSetFilter +{ +public: + VTKM_CONT_EXPORT + DataSetFilter(); + + VTKM_CONT_EXPORT + void SetActiveCellSet(vtkm::Id index) + { this->CellSetIndex = index; } + + VTKM_CONT_EXPORT + vtkm::Id GetActiveCellSetIndex() const + { return this->CellSetIndex; } + + VTKM_CONT_EXPORT + void SetActiveCoordinateSystem(vtkm::Id index) + { this->CoordinateSystemIndex = index; } + + VTKM_CONT_EXPORT + vtkm::Id GetActiveCoordinateSystemIndex() const + { return this->CoordinateSystemIndex; } + + VTKM_CONT_EXPORT + DataSetResult Execute(const vtkm::cont::DataSet &input); + + template + VTKM_CONT_EXPORT + DataSetResult Execute(const vtkm::cont::DataSet &input, + const vtkm::filter::PolicyBase& policy ); + + //From the field we can extract the association component + // ASSOC_ANY -> unable to map + // ASSOC_WHOLE_MESH -> (I think this is points) + // ASSOC_POINTS -> map using point mapping + // ASSOC_CELL_SET -> how do we map this? + // ASSOC_LOGICAL_DIM -> unable to map? + VTKM_CONT_EXPORT + bool MapFieldOntoOutput(DataSetResult& result, + const vtkm::cont::Field& field); + + template + VTKM_CONT_EXPORT + bool MapFieldOntoOutput(DataSetResult& result, + const vtkm::cont::Field& field, + const vtkm::filter::PolicyBase& policy); + +private: + template + VTKM_CONT_EXPORT + DataSetResult PrepareForExecution(const vtkm::cont::DataSet& input, + const vtkm::filter::PolicyBase& policy); + + std::string OutputFieldName; + vtkm::Id CellSetIndex; + vtkm::Id CoordinateSystemIndex; + vtkm::filter::internal::RuntimeDeviceTracker Tracker; +}; + +} +} // namespace vtkm::filter + + +#include + +#endif // vtk_m_filter_DataSetFilter_h \ No newline at end of file diff --git a/vtkm/filter/DataSetFilter.hxx b/vtkm/filter/DataSetFilter.hxx new file mode 100644 index 000000000..6cb12a070 --- /dev/null +++ b/vtkm/filter/DataSetFilter.hxx @@ -0,0 +1,141 @@ +//============================================================================ +// 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 2014 Sandia Corporation. +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2014 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// 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 +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include + +namespace vtkm { +namespace filter { + +//---------------------------------------------------------------------------- +template +DataSetFilter::DataSetFilter(): + OutputFieldName(), + CellSetIndex(0), + CoordinateSystemIndex(0), + Tracker() +{ + +} + +//----------------------------------------------------------------------------- +template +DataSetResult DataSetFilter::Execute(const vtkm::cont::DataSet &input) +{ + return this->Execute(input, vtkm::filter::DefaultPolicy()); +} + +//----------------------------------------------------------------------------- +template +template +DataSetResult DataSetFilter::Execute(const vtkm::cont::DataSet &input, + const vtkm::filter::PolicyBase& policy ) +{ + return this->PrepareForExecution(input, policy); +} + + +//----------------------------------------------------------------------------- +template +template +DataSetResult DataSetFilter::PrepareForExecution(const vtkm::cont::DataSet &input, + const vtkm::filter::PolicyBase& policy ) +{ + typedef vtkm::cont::DeviceAdapterTagCuda CudaTag; + typedef vtkm::cont::DeviceAdapterTagTBB TBBTag; + typedef vtkm::cont::DeviceAdapterTagSerial SerialTag; + + DataSetResult result = run_if_valid( static_cast(this), + input, + policy, + this->Tracker, + CudaTag() ); + if( !result.IsValid() ) + { + result = run_if_valid( static_cast(this), + input, + policy, + this->Tracker, + TBBTag() ); + } + if( !result.IsValid() ) + { + result = run_if_valid( static_cast(this), + input, + policy, + this->Tracker, + SerialTag() ); + } + + return result; +} + +//----------------------------------------------------------------------------- +template +bool DataSetFilter::MapFieldOntoOutput(DataSetResult& result, + const vtkm::cont::Field& field) +{ + return this->MapFieldOntoOutput(result, field, vtkm::filter::DefaultPolicy()); +} + +//----------------------------------------------------------------------------- +template +template +bool DataSetFilter::MapFieldOntoOutput(DataSetResult& result, + const vtkm::cont::Field& field, + const vtkm::filter::PolicyBase& policy) +{ + bool valid = false; + if(result.IsValid()) + { + typedef internal::ResolveFieldTypeAndMap< Derived, + DerivedPolicy > FunctorType; + FunctorType functor(static_cast(this), + result, + vtkm::filter::FieldMetadata(field), + policy, + this->Tracker, + valid); + + typedef vtkm::filter::FilterTraits< Derived > Traits; + vtkm::filter::Convert(field, policy, Traits()).CastAndCall(functor); + } + + //the bool valid will be modified by the map algorithm to hold if the + //mapping occurred or not. If the mapping was good a new field has been + //added to the DataSetResult that was passed in. + return valid; + +} + + +} +} diff --git a/vtkm/filter/DataSetWithFieldFilter.h b/vtkm/filter/DataSetWithFieldFilter.h new file mode 100644 index 000000000..f03e7fc29 --- /dev/null +++ b/vtkm/filter/DataSetWithFieldFilter.h @@ -0,0 +1,129 @@ +//============================================================================ +// 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 2014 Sandia Corporation. +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2014 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// 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. +//============================================================================ + +#ifndef vtk_m_filter_DataSetWithFieldFilter_h +#define vtk_m_filter_DataSetWithFieldFilter_h + +#include +#include +#include +#include + +#include +#include +#include + +namespace vtkm { +namespace filter { + +template +class DataSetWithFieldFilter +{ +public: + VTKM_CONT_EXPORT + DataSetWithFieldFilter(); + + VTKM_CONT_EXPORT + void SetActiveCellSet(vtkm::Id index) + { this->CellSetIndex = index; } + + VTKM_CONT_EXPORT + vtkm::Id GetActiveCellSetIndex() const + { return this->CellSetIndex; } + + VTKM_CONT_EXPORT + void SetActiveCoordinateSystem(vtkm::Id index) + { this->CoordinateSystemIndex = index; } + + VTKM_CONT_EXPORT + vtkm::Id GetActiveCoordinateSystemIndex() const + { return this->CoordinateSystemIndex; } + + VTKM_CONT_EXPORT + DataSetResult Execute(const vtkm::cont::DataSet &input, const std::string &inFieldName); + + VTKM_CONT_EXPORT + DataSetResult Execute(const vtkm::cont::DataSet &input, const vtkm::cont::Field &field); + + VTKM_CONT_EXPORT + DataSetResult Execute(const vtkm::cont::DataSet &input, const vtkm::cont::CoordinateSystem &field); + + + template + VTKM_CONT_EXPORT + DataSetResult Execute(const vtkm::cont::DataSet &input, + const std::string &inFieldName, + const vtkm::filter::PolicyBase& policy ); + + template + VTKM_CONT_EXPORT + DataSetResult Execute(const vtkm::cont::DataSet &input, + const vtkm::cont::Field &field, + const vtkm::filter::PolicyBase& policy ); + + template + VTKM_CONT_EXPORT + DataSetResult Execute(const vtkm::cont::DataSet &input, + const vtkm::cont::CoordinateSystem &field, + const vtkm::filter::PolicyBase& policy ); + + //From the field we can extract the association component + // ASSOC_ANY -> unable to map + // ASSOC_WHOLE_MESH -> (I think this is points) + // ASSOC_POINTS -> map using point mapping + // ASSOC_CELL_SET -> how do we map this? + // ASSOC_LOGICAL_DIM -> unable to map? + VTKM_CONT_EXPORT + bool MapFieldOntoOutput(DataSetResult& result, + const vtkm::cont::Field& field); + + template + VTKM_CONT_EXPORT + bool MapFieldOntoOutput(DataSetResult& result, + const vtkm::cont::Field& field, + const vtkm::filter::PolicyBase& policy); + +private: + template + VTKM_CONT_EXPORT + DataSetResult PrepareForExecution(const vtkm::cont::DataSet& input, + const vtkm::cont::Field& field, + const vtkm::filter::PolicyBase& policy); + + //How do we specify float/double coordinate types? + template + VTKM_CONT_EXPORT + DataSetResult PrepareForExecution(const vtkm::cont::DataSet& input, + const vtkm::cont::CoordinateSystem& field, + const vtkm::filter::PolicyBase& policy); + + std::string OutputFieldName; + vtkm::Id CellSetIndex; + vtkm::Id CoordinateSystemIndex; + vtkm::filter::internal::RuntimeDeviceTracker Tracker; +}; + +} +} // namespace vtkm::filter + + +#include + +#endif // vtk_m_filter_DataSetFilter_h \ No newline at end of file diff --git a/vtkm/filter/DataSetWithFieldFilter.hxx b/vtkm/filter/DataSetWithFieldFilter.hxx new file mode 100644 index 000000000..8911caa74 --- /dev/null +++ b/vtkm/filter/DataSetWithFieldFilter.hxx @@ -0,0 +1,204 @@ +//============================================================================ +// 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 2014 Sandia Corporation. +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2014 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// 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 +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include + +namespace vtkm { +namespace filter { + +//---------------------------------------------------------------------------- +template +DataSetWithFieldFilter::DataSetWithFieldFilter(): + OutputFieldName(), + CellSetIndex(0), + CoordinateSystemIndex(0), + Tracker() +{ + +} + +//----------------------------------------------------------------------------- +template +DataSetResult DataSetWithFieldFilter::Execute(const vtkm::cont::DataSet &input, + const std::string &inFieldName) +{ + return this->Execute(input, + input.GetField(inFieldName), + vtkm::filter::DefaultPolicy()); +} + +//----------------------------------------------------------------------------- +template +DataSetResult DataSetWithFieldFilter::Execute(const vtkm::cont::DataSet &input, + const vtkm::cont::Field &field) +{ + return this->Execute(input, + field, + vtkm::filter::DefaultPolicy()); +} + +//----------------------------------------------------------------------------- +template +DataSetResult DataSetWithFieldFilter::Execute(const vtkm::cont::DataSet &input, + const vtkm::cont::CoordinateSystem &field) +{ + return this->Execute(input, + field, + vtkm::filter::DefaultPolicy()); +} + +//----------------------------------------------------------------------------- +template +template +DataSetResult DataSetWithFieldFilter::Execute(const vtkm::cont::DataSet &input, + const std::string &inFieldName, + const vtkm::filter::PolicyBase& policy ) +{ + return this->Execute(input, + input.GetField(inFieldName), + policy); +} + +//----------------------------------------------------------------------------- +template +template +DataSetResult DataSetWithFieldFilter::Execute(const vtkm::cont::DataSet &input, + const vtkm::cont::Field &field, + const vtkm::filter::PolicyBase& policy ) +{ + return this->PrepareForExecution(input, field, policy); +} + +//----------------------------------------------------------------------------- +template +template +DataSetResult DataSetWithFieldFilter::Execute(const vtkm::cont::DataSet &input, + const vtkm::cont::CoordinateSystem &field, + const vtkm::filter::PolicyBase& policy ) +{ + //we need to state that the field is actually a coordinate system, so that + //the filter uses the proper policy to convert the types. + return this->PrepareForExecution(input, field, policy); +} + +//----------------------------------------------------------------------------- +template +template +DataSetResult DataSetWithFieldFilter::PrepareForExecution(const vtkm::cont::DataSet &input, + const vtkm::cont::Field &field, + const vtkm::filter::PolicyBase& policy ) +{ + //determine the field type first + DataSetResult result; + typedef internal::ResolveFieldTypeAndExecute< Derived, DerivedPolicy, + DataSetResult > FunctorType; + FunctorType functor(static_cast(this), + input, + vtkm::filter::FieldMetadata(field), + policy, + this->Tracker, + result); + + typedef vtkm::filter::FilterTraits< Derived > Traits; + vtkm::filter::Convert(field, policy, Traits()).CastAndCall(functor); + + return result; +} + +//----------------------------------------------------------------------------- +template +template +DataSetResult DataSetWithFieldFilter::PrepareForExecution(const vtkm::cont::DataSet &input, + const vtkm::cont::CoordinateSystem &field, + const vtkm::filter::PolicyBase& policy ) +{ + //We have a special signature just for CoordinateSystem, so that we can ask + //the policy for the storage types and value types just for coordinate systems + + //determine the field type first + DataSetResult result; + typedef internal::ResolveFieldTypeAndExecute< Derived, DerivedPolicy, + DataSetResult > FunctorType; + FunctorType functor(static_cast(this), + input, + vtkm::filter::FieldMetadata(field), + policy, + this->Tracker, + result); + + typedef vtkm::filter::FilterTraits< Derived > Traits; + vtkm::filter::Convert(field, policy, Traits()).CastAndCall(functor); + + return result; +} + +//----------------------------------------------------------------------------- +template +bool DataSetWithFieldFilter::MapFieldOntoOutput(DataSetResult& result, + const vtkm::cont::Field& field) +{ + return this->MapFieldOntoOutput(result, field, vtkm::filter::DefaultPolicy()); +} + +//----------------------------------------------------------------------------- +template +template +bool DataSetWithFieldFilter::MapFieldOntoOutput(DataSetResult& result, + const vtkm::cont::Field& field, + const vtkm::filter::PolicyBase& policy) +{ + bool valid = false; + if(result.IsValid()) + { + typedef internal::ResolveFieldTypeAndMap< Derived, + DerivedPolicy > FunctorType; + FunctorType functor(static_cast(this), + result, + vtkm::filter::FieldMetadata(field), + policy, + this->Tracker, + valid); + + typedef vtkm::filter::FilterTraits< Derived > Traits; + vtkm::filter::Convert(field, policy, Traits()).CastAndCall(functor); + } + + //the bool valid will be modified by the map algorithm to hold if the + //mapping occurred or not. If the mapping was good a new field has been + //added to the DataSetResult that was passed in. + return valid; + +} + + +} +} diff --git a/vtkm/filter/DefaultPolicy.h b/vtkm/filter/DefaultPolicy.h new file mode 100644 index 000000000..839bdc5f7 --- /dev/null +++ b/vtkm/filter/DefaultPolicy.h @@ -0,0 +1,48 @@ +//============================================================================ +// 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 2014 Sandia Corporation. +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2014 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// 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. +//============================================================================ + +#ifndef vtk_m_filter_DefaultPolicy_h +#define vtk_m_filter_DefaultPolicy_h + +#include +#include +#include +#include + +namespace vtkm { +namespace filter { + +class DefaultPolicy : public vtkm::filter::PolicyBase< DefaultPolicy > +{ +public: + typedef VTKM_DEFAULT_TYPE_LIST_TAG FieldTypeList; + typedef VTKM_DEFAULT_STORAGE_LIST_TAG FieldStorageList; + + typedef VTKM_DEFAULT_CELL_SET_LIST_TAG CellSetList; + + typedef VTKM_DEFAULT_COORDINATE_SYSTEM_TYPE_LIST_TAG CoordinateTypeList; + typedef VTKM_DEFAULT_COORDINATE_SYSTEM_STORAGE_LIST_TAG CoordinateStorageList; +}; + +} +} + + +#endif \ No newline at end of file diff --git a/vtkm/filter/ExternalFaces.h b/vtkm/filter/ExternalFaces.h new file mode 100644 index 000000000..feff4b34c --- /dev/null +++ b/vtkm/filter/ExternalFaces.h @@ -0,0 +1,59 @@ +//============================================================================ +// 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 2014 Sandia Corporation. +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2014 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// 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. +//============================================================================ + +#ifndef vtk_m_filter_ExternalFaces_h +#define vtk_m_filter_ExternalFaces_h + +#include +#include + +namespace vtkm { +namespace filter { + +class ExternalFaces : public vtkm::filter::DataSetFilter +{ +public: + VTKM_CONT_EXPORT + ExternalFaces(); + + template + VTKM_CONT_EXPORT + vtkm::filter::DataSetResult DoExecute(const vtkm::cont::DataSet& input, + const vtkm::filter::PolicyBase& policy, + const DeviceAdapter& tag); + + //Map a new field onto the resulting dataset after running the filter + //this call is only valid + template + VTKM_CONT_EXPORT + bool DoMapField(vtkm::filter::DataSetResult& result, + const vtkm::cont::ArrayHandle& input, + const vtkm::filter::FieldMetadata& fieldMeta, + const vtkm::filter::PolicyBase& policy, + const DeviceAdapter& tag); +}; + +} +} // namespace vtkm::filter + + +#include + +#endif // vtk_m_filter_Threshold_h \ No newline at end of file diff --git a/vtkm/filter/ExternalFaces.hxx b/vtkm/filter/ExternalFaces.hxx new file mode 100644 index 000000000..7f799f3da --- /dev/null +++ b/vtkm/filter/ExternalFaces.hxx @@ -0,0 +1,137 @@ +//============================================================================ +// 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 2014 Sandia Corporation. +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2014 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// 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. +//============================================================================ + +namespace vtkm { +namespace filter { + +namespace +{ + +template< typename DeviceAdapter > +class ExternalFacesWorkletWrapper +{ + vtkm::cont::DataSet* Output; + bool* Valid; +public: + + + ExternalFacesWorkletWrapper(vtkm::cont::DataSet& data, bool& v): + Output(&data), + Valid(&v) + { } + + template + void operator()(const vtkm::cont::CellSetExplicit& cellset ) const + { + vtkm::cont::ArrayHandle shapes; + vtkm::cont::ArrayHandle numIndices; + vtkm::cont::ArrayHandle conn; + + vtkm::cont::ArrayHandle output_shapes; + vtkm::cont::ArrayHandle output_numIndices; + vtkm::cont::ArrayHandle output_conn; + + shapes = cellset.GetShapesArray(vtkm::TopologyElementTagPoint(), + vtkm::TopologyElementTagCell()); + + numIndices = cellset.GetNumIndicesArray(vtkm::TopologyElementTagPoint(), + vtkm::TopologyElementTagCell()); + + conn = cellset.GetConnectivityArray(vtkm::TopologyElementTagPoint(), + vtkm::TopologyElementTagCell()); + + + vtkm::worklet::ExternalFaces exfaces; + exfaces.run(shapes, numIndices, conn, + output_shapes, output_numIndices, output_conn, + DeviceAdapter()); + + vtkm::cont::CellSetExplicit<> output_cs(cellset.GetNumberOfPoints(), + cellset.GetName()); + output_cs.Fill(output_shapes, output_numIndices, output_conn); + + this->Output->AddCellSet(output_cs); + *this->Valid = true; + } + + template + void operator()(const T& ) const + { + //don't support this cell type + *this->Valid = false; + } +}; + +} + +//----------------------------------------------------------------------------- +ExternalFaces::ExternalFaces(): + vtkm::filter::DataSetFilter() +{ + +} + +//----------------------------------------------------------------------------- +template +vtkm::filter::DataSetResult ExternalFaces::DoExecute(const vtkm::cont::DataSet& input, + const vtkm::filter::PolicyBase& policy, + const DeviceAdapter&) +{ + //1. extract the cell set + const vtkm::cont::DynamicCellSet& cells = + input.GetCellSet(this->GetActiveCellSetIndex()); + + //2. using the policy convert the dynamic cell set, and verify + // that we have an explicit cell set. Once that is found run the + // external faces worklet + vtkm::cont::DataSet output; + bool workletRan = false; + ExternalFacesWorkletWrapper wrapper(output, workletRan); + vtkm::filter::Convert(cells,policy).CastAndCall( wrapper ); + + if(!workletRan) + { + return vtkm::filter::DataSetResult(); + } + + //3. add coordinates, etc to the + output.AddCoordinateSystem( + input.GetCoordinateSystem(this->GetActiveCoordinateSystemIndex()) ); + return vtkm::filter::DataSetResult(output); + +} + +//----------------------------------------------------------------------------- +template +bool ExternalFaces::DoMapField(vtkm::filter::DataSetResult&, + const vtkm::cont::ArrayHandle&, + const vtkm::filter::FieldMetadata&, + const vtkm::filter::PolicyBase&, + const DeviceAdapter&) +{ + return false; +} + +} +} diff --git a/vtkm/filter/FieldFilter.h b/vtkm/filter/FieldFilter.h new file mode 100644 index 000000000..11ab4fd54 --- /dev/null +++ b/vtkm/filter/FieldFilter.h @@ -0,0 +1,130 @@ +//============================================================================ +// 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 2014 Sandia Corporation. +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2014 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// 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. +//============================================================================ + +#ifndef vtk_m_filter_FieldFilter_h +#define vtk_m_filter_FieldFilter_h + +#include +#include +#include + +#include +#include + +namespace vtkm { +namespace filter { + +class FieldResult +{ +public: + VTKM_CONT_EXPORT + FieldResult(): Valid(false), Field() + { } + + VTKM_CONT_EXPORT + FieldResult(const vtkm::cont::Field& f): Valid(true), Field(f) + { } + + VTKM_CONT_EXPORT + bool IsValid() const { return this->Valid; } + + VTKM_CONT_EXPORT + const vtkm::cont::Field& GetField() const { return this->Field; } + + template + VTKM_CONT_EXPORT + bool FieldAs(vtkm::cont::ArrayHandle& dest) const; + + template + VTKM_CONT_EXPORT + bool FieldAs(vtkm::cont::ArrayHandle& dest, + const vtkm::filter::PolicyBase& policy) const; + +private: + bool Valid; + vtkm::cont::Field Field; +}; + +template +class FieldFilter +{ +public: + VTKM_CONT_EXPORT + void SetOutputFieldName( const std::string& name ) + { this->OutputFieldName = name; } + + VTKM_CONT_EXPORT + const std::string& GetOutputFieldName() const + { return this->OutputFieldName; } + + VTKM_CONT_EXPORT + FieldResult Execute(const vtkm::cont::DataSet &input, const std::string &inFieldName); + + VTKM_CONT_EXPORT + FieldResult Execute(const vtkm::cont::DataSet &input, const vtkm::cont::Field &field); + + VTKM_CONT_EXPORT + FieldResult Execute(const vtkm::cont::DataSet &input, const vtkm::cont::CoordinateSystem &field); + + + template + VTKM_CONT_EXPORT + FieldResult Execute(const vtkm::cont::DataSet &input, + const std::string &inFieldName, + const vtkm::filter::PolicyBase& policy ); + + template + VTKM_CONT_EXPORT + FieldResult Execute(const vtkm::cont::DataSet &input, + const vtkm::cont::Field &field, + const vtkm::filter::PolicyBase& policy ); + + template + VTKM_CONT_EXPORT + FieldResult Execute(const vtkm::cont::DataSet &input, + const vtkm::cont::CoordinateSystem &field, + const vtkm::filter::PolicyBase& policy ); + + +private: + + template + VTKM_CONT_EXPORT + FieldResult PrepareForExecution(const vtkm::cont::DataSet& input, + const vtkm::cont::Field& field, + const vtkm::filter::PolicyBase& policy); + + template + VTKM_CONT_EXPORT + FieldResult PrepareForExecution(const vtkm::cont::DataSet& input, + const vtkm::cont::CoordinateSystem& field, + const vtkm::filter::PolicyBase& policy); + + std::string OutputFieldName; + vtkm::filter::internal::RuntimeDeviceTracker Tracker; +}; + +} +} // namespace vtkm::filter + + +#include + +#endif // vtk_m_filter_FieldFilter_h \ No newline at end of file diff --git a/vtkm/filter/FieldFilter.hxx b/vtkm/filter/FieldFilter.hxx new file mode 100644 index 000000000..b532bf3a6 --- /dev/null +++ b/vtkm/filter/FieldFilter.hxx @@ -0,0 +1,181 @@ +//============================================================================ +// 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 2014 Sandia Corporation. +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2014 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// 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 +#include +#include + +#include + +#include +#include +#include + +#include +#include + +namespace vtkm { +namespace filter { + + +//----------------------------------------------------------------------------- +template +bool FieldResult::FieldAs(vtkm::cont::ArrayHandle& dest) const +{ + return this->FieldAs(dest, vtkm::filter::DefaultPolicy()); +} + +//----------------------------------------------------------------------------- +template +bool FieldResult::FieldAs(vtkm::cont::ArrayHandle& dest, + const vtkm::filter::PolicyBase&) const +{ + try + { + typedef typename DerivedPolicy::FieldTypeList TypeList; + typedef typename DerivedPolicy::FieldStorageList StorageList; + + vtkm::cont::DynamicArrayHandle handle = this->Field.GetData(); + handle.ResetTypeAndStorageLists(TypeList(),StorageList()).CopyTo(dest); + return true; + } + catch(vtkm::cont::Error e) + { + (void)e; + } + + return false; +} + +//----------------------------------------------------------------------------- +template +FieldResult FieldFilter::Execute(const vtkm::cont::DataSet &input, + const std::string &inFieldName) +{ + return this->Execute(input, + input.GetField(inFieldName), + vtkm::filter::DefaultPolicy()); +} + +//----------------------------------------------------------------------------- +template +FieldResult FieldFilter::Execute(const vtkm::cont::DataSet &input, + const vtkm::cont::Field &field) +{ + return this->Execute(input, + field, + vtkm::filter::DefaultPolicy()); +} + +//----------------------------------------------------------------------------- +template +FieldResult FieldFilter::Execute(const vtkm::cont::DataSet &input, + const vtkm::cont::CoordinateSystem &field) +{ + return this->Execute(input, + field, + vtkm::filter::DefaultPolicy()); +} + +//----------------------------------------------------------------------------- +template +template +FieldResult FieldFilter::Execute(const vtkm::cont::DataSet &input, + const std::string &inFieldName, + const vtkm::filter::PolicyBase& policy ) +{ + return this->Execute(input, + input.GetField(inFieldName), + policy); +} + +//----------------------------------------------------------------------------- +template +template +FieldResult FieldFilter::Execute(const vtkm::cont::DataSet &input, + const vtkm::cont::Field &field, + const vtkm::filter::PolicyBase& policy ) +{ + return this->PrepareForExecution(input, field, policy); +} + +//----------------------------------------------------------------------------- +template +template +FieldResult FieldFilter::Execute(const vtkm::cont::DataSet &input, + const vtkm::cont::CoordinateSystem &field, + const vtkm::filter::PolicyBase& policy ) +{ + //we need to state that the field is actually a coordinate system, so that + //the filter uses the proper policy to convert the types. + return this->PrepareForExecution(input, field, policy); +} + +//----------------------------------------------------------------------------- +template +template +FieldResult FieldFilter::PrepareForExecution(const vtkm::cont::DataSet &input, + const vtkm::cont::Field &field, + const vtkm::filter::PolicyBase& policy ) +{ + //determine the field type first + FieldResult result; + typedef internal::ResolveFieldTypeAndExecute< Derived, DerivedPolicy, + FieldResult > FunctorType; + FunctorType functor(static_cast(this), + input, + vtkm::filter::FieldMetadata(field), + policy, + this->Tracker, + result); + + typedef vtkm::filter::FilterTraits< Derived > Traits; + vtkm::filter::Convert(field, policy, Traits()).CastAndCall(functor); + return result; +} + +//----------------------------------------------------------------------------- +template +template +FieldResult FieldFilter::PrepareForExecution(const vtkm::cont::DataSet &input, + const vtkm::cont::CoordinateSystem &field, + const vtkm::filter::PolicyBase& policy ) +{ + //We have a special signature just for CoordinateSystem, so that we can ask + //the policy for the storage types and value types just for coordinate systems + + //determine the field type first + FieldResult result; + typedef internal::ResolveFieldTypeAndExecute< Derived, DerivedPolicy, + FieldResult > FunctorType; + FunctorType functor(static_cast(this), + input, + vtkm::filter::FieldMetadata(field), + policy, + this->Tracker, + result); + + typedef vtkm::filter::FilterTraits< Derived > Traits; + vtkm::filter::Convert(field, policy, Traits()).CastAndCall(functor); + return result; +} + +} +} diff --git a/vtkm/filter/FieldMetadata.h b/vtkm/filter/FieldMetadata.h new file mode 100644 index 000000000..d89030e14 --- /dev/null +++ b/vtkm/filter/FieldMetadata.h @@ -0,0 +1,105 @@ +//============================================================================ +// 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 2014 Sandia Corporation. +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2014 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// 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. +//============================================================================ + +#ifndef vtk_m_filter_FieldMetadata_h +#define vtk_m_filter_FieldMetadata_h + +#include +#include + +namespace vtkm { +namespace filter { + +class FieldMetadata +{ +public: + VTKM_CONT_EXPORT + FieldMetadata(): + Name(), + Association(vtkm::cont::Field::ASSOC_ANY), + Order(1), + CellSetName() + { + } + + VTKM_CONT_EXPORT + FieldMetadata(const vtkm::cont::Field& f): + Name(f.GetName()), + Association(f.GetAssociation()), + Order(f.GetOrder()), + CellSetName(f.GetAssocCellSet()) + { + } + + VTKM_CONT_EXPORT + FieldMetadata(const vtkm::cont::CoordinateSystem &sys): + Name(sys.GetName()), + Association(sys.GetAssociation()), + Order(sys.GetOrder()), + CellSetName(sys.GetAssocCellSet()) + { + } + + VTKM_CONT_EXPORT + bool IsPointField() const + {return this->Association == vtkm::cont::Field::ASSOC_POINTS; } + + VTKM_CONT_EXPORT + bool IsCellField() const + {return this->Association == vtkm::cont::Field::ASSOC_CELL_SET; } + + VTKM_CONT_EXPORT + const std::string& GetName() const + {return this->Name; } + + VTKM_CONT_EXPORT + const std::string& GetCellSetName() const + {return this->CellSetName; } + + template + VTKM_CONT_EXPORT + vtkm::cont::Field AsField(const vtkm::cont::ArrayHandle &handle) const + { + //Field only handles arrayHandles with default storage tag, so use + //dynamic array handles + vtkm::cont::DynamicArrayHandle dhandle(handle); + if(this->IsCellField()) + { + return vtkm::cont::Field(this->Name, this->Order, this->Association, + this->CellSetName, dhandle); + } + else + { + return vtkm::cont::Field(this->Name, this->Order, this->Association, dhandle); + } + } + +private: + std::string Name; ///< name of field + vtkm::cont::Field::AssociationEnum Association; + vtkm::IdComponent Order; ///< 0=(piecewise) constant, 1=linear, 2=quadratic + std::string CellSetName; ///< only populate if assoc is cells +}; + +} +} + + +#endif \ No newline at end of file diff --git a/vtkm/filter/FieldTypes.h b/vtkm/filter/FieldTypes.h new file mode 100644 index 000000000..92155fd2a --- /dev/null +++ b/vtkm/filter/FieldTypes.h @@ -0,0 +1,88 @@ +//============================================================================ +// 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 2014 Sandia Corporation. +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2014 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// 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. +//============================================================================ + +#ifndef vtk_m_filter_FieldMetadata_h +#define vtk_m_filter_FieldMetadata_h + +#include + +namespace vtkm { +namespace filter { + +class FieldMetadata +{ +public: + VTKM_CONT_EXPORT + FieldMetadata(const vtkm::cont::Field& f): + Name(f.GetName()), + Association(f.GetAssociation()), + Order(f.GetOrder()), + CellSetName(f.GetAssocCellSet()), + LogicalDim(f.GetAssocLogicalDim()), + { + } + + VTKM_CONT_EXPORT + FieldMetadata(const vtkm::cont::CoordinateSystem &sys): + Name(f.GetName()), + Association(f.GetAssociation()), + Order(f.GetOrder()), + CellSetName(f.GetAssocCellSet()), + LogicalDim(f.GetAssocLogicalDim()), + { + } + + VTKM_CONT_EXPORT + bool operator==(const FieldMetadata& other) const + { return this->Association == other.Association; } + + VTKM_CONT_EXPORT + bool operator!=(const FieldMetadata& other) const + { return this->Association != other.Association; } + + VTKM_CONT_EXPORT + bool IsPointField() const + {return this->Association == vtkm::cont::Field::ASSOC_POINTS; } + + VTKM_CONT_EXPORT + bool IsCellField() const + {return this->Association == vtkm::cont::Field::ASSOC_CELL_SET; } + + VTKM_CONT_EXPORT + const std::string& GetName() const + {return this->Name; } + + VTKM_CONT_EXPORT + const std::string& GetCellSetName() const + {return this->AssocCellSetName; } + +private: + std::string Name; ///< name of field + vtkm::cont::Field::AssociationEnum Association; + vtkm::IdComponent Order; ///< 0=(piecewise) constant, 1=linear, 2=quadratic + std::string AssocCellSetName; ///< only populate if assoc is cells + vtkm::IdComponent AssocLogicalDim; ///< only populate if assoc is logical dim +}; + +} +} + + +#endif \ No newline at end of file diff --git a/vtkm/filter/FilterTraits.h b/vtkm/filter/FilterTraits.h new file mode 100644 index 000000000..07c273906 --- /dev/null +++ b/vtkm/filter/FilterTraits.h @@ -0,0 +1,40 @@ +//============================================================================ +// 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 2014 Sandia Corporation. +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2014 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// 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. +//============================================================================ + +#ifndef vtk_m_filter_FilterTraits_h +#define vtk_m_filter_FilterTraits_h + +#include + +namespace vtkm { +namespace filter { +template +class FilterTraits +{ +public: + //A filter can specify a set of data type that it supports for + //the input array + typedef vtkm::TypeListTagCommon InputFieldTypeList; +}; + +} +} + +#endif diff --git a/vtkm/filter/MarchingCubes.h b/vtkm/filter/MarchingCubes.h new file mode 100644 index 000000000..73e6e0c82 --- /dev/null +++ b/vtkm/filter/MarchingCubes.h @@ -0,0 +1,111 @@ +//============================================================================ +// 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 2014 Sandia Corporation. +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2014 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// 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. +//============================================================================ + +#ifndef vtk_m_filter_MarchingCubes_h +#define vtk_m_filter_MarchingCubes_h + +#include +#include + + +namespace vtkm { +namespace filter { + + +/* +* Outstanding issues: +* 1. The output is a proper dataset, which means: +* It needs a cell set +* It needs a coordinate system +* +* +*/ + +class MarchingCubes : public vtkm::filter::DataSetWithFieldFilter +{ +public: + MarchingCubes(); + + VTKM_CONT_EXPORT + void SetIsoValue(vtkm::Float64 value){ this->IsoValue = value; } + + VTKM_CONT_EXPORT + vtkm::Float64 GetIsoValue() const { return this->IsoValue; } + + VTKM_CONT_EXPORT + void SetMergeDuplicatePoints(bool on) { this->MergeDuplicatePoints = on; } + + VTKM_CONT_EXPORT + bool GetMergeDuplicatePoints() const { return this->MergeDuplicatePoints; } + + VTKM_CONT_EXPORT + void SetGenerateNormals(bool on) { this->GenerateNormals = on; } + + VTKM_CONT_EXPORT + bool GetGenerateNormals() const { return this->GenerateNormals; } + + template + VTKM_CONT_EXPORT + vtkm::filter::DataSetResult DoExecute(const vtkm::cont::DataSet& input, + const vtkm::cont::ArrayHandle& field, + const vtkm::filter::FieldMetadata& fieldMeta, + const vtkm::filter::PolicyBase& policy, + const DeviceAdapter& tag); + + //Map a new field onto the resulting dataset after running the filter + //this call is only valid + template + VTKM_CONT_EXPORT + bool DoMapField(vtkm::filter::DataSetResult& result, + const vtkm::cont::ArrayHandle& input, + const vtkm::filter::FieldMetadata& fieldMeta, + const vtkm::filter::PolicyBase& policy, + const DeviceAdapter& tag); + +private: + double IsoValue; + bool MergeDuplicatePoints; + bool GenerateNormals; + + vtkm::cont::ArrayHandle EdgeTable; + vtkm::cont::ArrayHandle NumTrianglesTable; + vtkm::cont::ArrayHandle TriangleTable; + + + vtkm::cont::ArrayHandle InterpolationWeights; + vtkm::cont::ArrayHandle InterpolationIds; +}; + +template<> +class FilterTraits +{ +public: + struct TypeListTagMCScalars : vtkm::ListTagBase { }; + typedef TypeListTagMCScalars InputFieldTypeList; +}; + +} +} // namespace vtkm::filter + + +#include + +#endif // vtk_m_filter_MarchingCubes_h \ No newline at end of file diff --git a/vtkm/filter/MarchingCubes.hxx b/vtkm/filter/MarchingCubes.hxx new file mode 100644 index 000000000..f40c6ec0d --- /dev/null +++ b/vtkm/filter/MarchingCubes.hxx @@ -0,0 +1,491 @@ +//============================================================================ +// 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 2014 Sandia Corporation. +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2014 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// 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 +#include +#include +#include + +#include +#include + +namespace +{ +typedef vtkm::filter::FilterTraits::InputFieldTypeList InputTypes; + +// ----------------------------------------------------------------------------- +template +vtkm::cont::ArrayHandle make_ScalarField(const vtkm::cont::ArrayHandle& ah) +{ return ah; } + +template +vtkm::cont::ArrayHandle make_ScalarField(const vtkm::cont::ArrayHandle& ah) +{ return ah; } + +template +vtkm::cont::ArrayHandleCast > +make_ScalarField(const vtkm::cont::ArrayHandle& ah) +{ return vtkm::cont::make_ArrayHandleCast(ah, vtkm::FloatDefault()); } + +template +vtkm::cont::ArrayHandleCast > +make_ScalarField(const vtkm::cont::ArrayHandle& ah) +{ return vtkm::cont::make_ArrayHandleCast(ah, vtkm::FloatDefault()); } + +// ----------------------------------------------------------------------------- +template +VTKM_EXEC_EXPORT +int GetHexahedronClassification(const T& values, const U isoValue) +{ + return ((values[0] > isoValue) | + (values[1] > isoValue) << 1 | + (values[2] > isoValue) << 2 | + (values[3] > isoValue) << 3 | + (values[4] > isoValue) << 4 | + (values[5] > isoValue) << 5 | + (values[6] > isoValue) << 6 | + (values[7] > isoValue) << 7); +} + +class ClassifyCell : public vtkm::worklet::WorkletMapPointToCell +{ +public: + typedef void ControlSignature( + FieldInPoint inNodes, + TopologyIn topology, + FieldOutCell< IdComponentType > outNumTriangles, + WholeArrayIn< IdComponentType > numTrianglesTable); + typedef void ExecutionSignature(_1, _3, _4); + typedef _2 InputDomain; + + vtkm::Float64 Isovalue; + + VTKM_CONT_EXPORT + ClassifyCell(vtkm::Float64 isovalue) : + Isovalue(isovalue) + { + } + + template + VTKM_EXEC_EXPORT + void operator()(const FieldInType &fieldIn, + vtkm::IdComponent &numTriangles, + const NumTrianglesTablePortalType &numTrianglesTable) const + { + typedef typename vtkm::VecTraits::ComponentType FieldType; + const FieldType iso = static_cast(this->Isovalue); + + const vtkm::IdComponent caseNumber = + GetHexahedronClassification(fieldIn, iso); + numTriangles = numTrianglesTable.Get(caseNumber); + } +}; + +/// \brief Compute the weights for each edge that is used to generate +/// a point in the resulting iso-surface +class EdgeWeightGenerate : public vtkm::worklet::WorkletMapPointToCell +{ + typedef vtkm::Vec< vtkm::Id2, 3 > Vec3Id2; + typedef vtkm::Vec< vtkm::Vec, 3 > FVec3x3; + typedef vtkm::Vec< vtkm::Vec, 3 > DVec3x3; + +public: + + typedef vtkm::worklet::ScatterCounting ScatterType; + + struct InterpolateIdTypes : vtkm::ListTagBase< Vec3Id2 > { }; + struct Vec3FloatTypes : vtkm::ListTagBase< FVec3x3, DVec3x3> { }; + + typedef void ControlSignature( + TopologyIn topology, // Cell set + FieldInPoint fieldIn, // Input point field defining the contour + FieldInPoint pcoordIn, // Input point coordinates + FieldOutCell normalsOut, // Estimated normals (one per tri vertex) + FieldOutCell interpolationWeights, + FieldOutCell interpolationIds, + WholeArrayIn EdgeTable, // An array portal with the edge table + WholeArrayIn TriTable // An array portal with the triangle table + ); + typedef void ExecutionSignature( + CellShape, _2, _3, _4, _5, _6, _7, _8, VisitIndex, FromIndices); + + typedef _1 InputDomain; + + VTKM_CONT_EXPORT + EdgeWeightGenerate(vtkm::Float64 isovalue, + bool genNormals, + const vtkm::worklet::ScatterCounting scatter) : + Isovalue(isovalue), + GenerateNormals(genNormals), + Scatter( scatter ) { } + + template + VTKM_EXEC_EXPORT + void operator()( + CellShapeTag shape, + const FieldInType &fieldIn, // Input point field defining the contour + const CoordType &coords, // Input point coordinates + NormalType &normalsOut, // Estimated normals (one per tri vertex) + WeightType &interpolationWeights, + IdType &interpolationIds, + const EdgeTablePortalType &edgeTable, + const TriTablePortalType &triTable, + vtkm::IdComponent visitIndex, + const IndicesVecType &indices) const + { + typedef typename vtkm::VecTraits::ComponentType FieldType; + const FieldType iso = static_cast(this->Isovalue); + + // Compute the Marching Cubes case number for this cell + const vtkm::IdComponent caseNumber = + GetHexahedronClassification(fieldIn, iso); + + // Interpolate for vertex positions and associated scalar values + const vtkm::Id triTableOffset = + static_cast(caseNumber*16 + visitIndex*3); + for (vtkm::IdComponent triVertex = 0; triVertex < 3; triVertex++) + { + const vtkm::IdComponent edgeIndex = + triTable.Get(triTableOffset + triVertex); + const vtkm::IdComponent edgeVertex0 = edgeTable.Get(2*edgeIndex + 0); + const vtkm::IdComponent edgeVertex1 = edgeTable.Get(2*edgeIndex + 1); + const FieldType fieldValue0 = fieldIn[edgeVertex0]; + const FieldType fieldValue1 = fieldIn[edgeVertex1]; + + interpolationIds[triVertex][0] = indices[edgeVertex0]; + interpolationIds[triVertex][1] = indices[edgeVertex1]; + + //we need to cast each side of the division to WeightType::ComponentType + //so that the interpolation works properly even when iso-contouring + //char/uchar fields + typedef typename vtkm::VecTraits::ComponentType WType; + WType interpolant = + static_cast(iso - fieldValue0) / + static_cast(fieldValue1 - fieldValue0); + interpolationWeights[triVertex] = interpolant; + + if(this->GenerateNormals) + { + const vtkm::Vec edgePCoord0 = + vtkm::exec::ParametricCoordinatesPoint( + fieldIn.GetNumberOfComponents(), edgeVertex0, shape, *this); + const vtkm::Vec edgePCoord1 = + vtkm::exec::ParametricCoordinatesPoint( + fieldIn.GetNumberOfComponents(), edgeVertex1, shape, *this); + + const vtkm::Vec interpPCoord = + vtkm::Lerp(edgePCoord0, edgePCoord1, interpolant); + + normalsOut[triVertex] = + vtkm::Normal(vtkm::exec::CellDerivative( + fieldIn, coords, interpPCoord, shape, *this)); + } + } + } + + VTKM_CONT_EXPORT + ScatterType GetScatter() const + { + return this->Scatter; + } + + +private: + const vtkm::Float64 Isovalue; + const bool GenerateNormals; + ScatterType Scatter; +}; + + +class ApplyToField : public vtkm::worklet::WorkletMapField + { + public: + typedef void ControlSignature(FieldIn< Id2Type > interpolation_ids, + FieldIn< Scalar > interpolation_weights, + WholeArrayIn<> inputField, + FieldOut<> output + ); + typedef void ExecutionSignature(_1, _2, _3, _4); + typedef _1 InputDomain; + + VTKM_CONT_EXPORT + ApplyToField() {} + + template + VTKM_EXEC_EXPORT + void operator()(const vtkm::Id2& low_high, + const WeightType &weight, + const InFieldPortalType& inPortal, + OutFieldType &result) const + { + //fetch the low / high values from inPortal + result = vtkm::Lerp(inPortal.Get(low_high[0]), + inPortal.Get(low_high[1]), + weight); + } + + }; + +} + +namespace vtkm { +namespace filter { + +//----------------------------------------------------------------------------- +MarchingCubes::MarchingCubes(): + vtkm::filter::DataSetWithFieldFilter(), + IsoValue(0), + MergeDuplicatePoints(true), + GenerateNormals(false), + EdgeTable(), + NumTrianglesTable(), + TriangleTable(), + InterpolationWeights(), + InterpolationIds() +{ + // Set up the Marching Cubes case tables as part of the filter so that + // we cache these tables in the execution environment between execution runs + this->EdgeTable = + vtkm::cont::make_ArrayHandle(vtkm::worklet::internal::edgeTable, 24); + + this->NumTrianglesTable = + vtkm::cont::make_ArrayHandle(vtkm::worklet::internal::numTrianglesTable, 256); + + this->TriangleTable = + vtkm::cont::make_ArrayHandle(vtkm::worklet::internal::triTable, 256*16); +} + +//----------------------------------------------------------------------------- +template +vtkm::filter::DataSetResult MarchingCubes::DoExecute(const vtkm::cont::DataSet& input, + const vtkm::cont::ArrayHandle& field, + const vtkm::filter::FieldMetadata& fieldMeta, + const vtkm::filter::PolicyBase& policy, + const DeviceAdapter&) +{ + + if(fieldMeta.IsPointField() == false) + { + //todo: we need to mark this as a failure of input, not a failure + //of the algorithm + return vtkm::filter::DataSetResult(); + } + + //get the cells and coordinates of the dataset + const vtkm::cont::DynamicCellSet& cells = + input.GetCellSet(this->GetActiveCellSetIndex()); + + const vtkm::cont::CoordinateSystem& coords = + input.GetCoordinateSystem(this->GetActiveCoordinateSystemIndex()); + + // Setup the Dispatcher Typedefs + typedef typename vtkm::worklet::DispatcherMapTopology< + ClassifyCell, + DeviceAdapter + > ClassifyDispatcher; + + typedef typename vtkm::worklet::DispatcherMapTopology< + EdgeWeightGenerate, + DeviceAdapter + > GenerateDispatcher; + + + // Call the ClassifyCell functor to compute the Marching Cubes case numbers + // for each cell, and the number of vertices to be generated + ClassifyCell classifyCell( this->IsoValue ); + ClassifyDispatcher classifyCellDispatcher(classifyCell); + + vtkm::cont::ArrayHandle numOutputTrisPerCell; + classifyCellDispatcher.Invoke(field, + vtkm::filter::Convert(cells, policy), + numOutputTrisPerCell, + this->NumTrianglesTable); + + + //Pass 2 Generate the edges + typedef vtkm::cont::ArrayHandle< vtkm::Vec< vtkm::Float32,3> > Vec3HandleType; + Vec3HandleType normals; + + vtkm::worklet::ScatterCounting scatter(numOutputTrisPerCell, DeviceAdapter()); + EdgeWeightGenerate weightGenerate(this->IsoValue, + this->GenerateNormals, + scatter); + + GenerateDispatcher edgeDispatcher(weightGenerate); + edgeDispatcher.Invoke( + vtkm::filter::Convert(cells, policy), + //cast to a scalar field if not one, as cellderivative only works on those + make_ScalarField(field), + vtkm::filter::Convert(coords, policy), + vtkm::cont::make_ArrayHandleGroupVec<3>(normals), + vtkm::cont::make_ArrayHandleGroupVec<3>(this->InterpolationWeights), + vtkm::cont::make_ArrayHandleGroupVec<3>(this->InterpolationIds), + this->EdgeTable, + this->TriangleTable); + + //Now that we have the edge interpolation finished we can generate the + //following: + //1. Coordinates ( with option to do point merging ) + //2. Normals + //todo: We need to run the coords through out policy and determine + //what the output coordinate type should be. We have two problems here + //1. What is the type? float32/float64 + //2. What is the storage backing + vtkm::cont::DataSet output; + vtkm::cont::ArrayHandle< vtkm::Vec< vtkm::Float32,3> > vertices; + + typedef vtkm::cont::ArrayHandle< vtkm::Id2 > Id2HandleType; + typedef vtkm::cont::ArrayHandle WeightHandleType; + if(this->MergeDuplicatePoints) + { + typedef vtkm::cont::DeviceAdapterAlgorithm Algorithm; + + //Do merge duplicate points we need to do the following: + //1. Copy the interpolation Ids + Id2HandleType unqiueIds; + Algorithm::Copy(this->InterpolationIds, unqiueIds); + + if(this->GenerateNormals) + { + typedef vtkm::cont::ArrayHandleZip KeyType; + KeyType keys = vtkm::cont::make_ArrayHandleZip(this->InterpolationWeights, normals); + + //2. now we need to do a sort by key, giving us + Algorithm::SortByKey(unqiueIds, keys); + + //3. lastly we need to do a unique by key, but since vtkm doesn't + // offer that feature, we use a zip handle + vtkm::cont::ArrayHandleZip zipped = + vtkm::cont::make_ArrayHandleZip(unqiueIds,keys); + Algorithm::Unique( zipped ); + } + else + { + //2. now we need to do a sort by key, giving us + Algorithm::SortByKey(unqiueIds, this->InterpolationWeights); + + //3. lastly we need to do a unique by key, but since vtkm doesn't + // offer that feature, we use a zip handle + vtkm::cont::ArrayHandleZip zipped = + vtkm::cont::make_ArrayHandleZip(unqiueIds, this->InterpolationWeights); + Algorithm::Unique( zipped ); + } + + //4. + //LowerBounds generates the output cell connections. It does this by + //finding for each interpolationId where it would be inserted in the + //sorted & unique subset, which generates an index value aka the lookup + //value. + // + vtkm::cont::ArrayHandle< vtkm::Id> connectivity; + Algorithm::LowerBounds(unqiueIds, this->InterpolationIds, connectivity); + + + vtkm::cont::CellSetSingleType< > outputCells( (vtkm::CellShapeTagTriangle()) ); + outputCells.Fill( connectivity ); + output.AddCellSet( outputCells ); + } + else + { + ApplyToField applyToField; + vtkm::worklet::DispatcherMapField applyFieldDispatcher(applyToField); + + applyFieldDispatcher.Invoke(this->InterpolationIds, + this->InterpolationWeights, + vtkm::filter::Convert(coords, policy), + vertices); + + //when we don't merge points, the connectivity array can be represented + //by a counting array + typedef typename vtkm::cont::ArrayHandleIndex::StorageTag IndexStorageTag; + vtkm::cont::CellSetSingleType< IndexStorageTag > outputCells( (vtkm::CellShapeTagTriangle()) ); + vtkm::cont::ArrayHandleIndex connectivity(vertices.GetNumberOfValues()); + outputCells.Fill( connectivity ); + output.AddCellSet( outputCells ); + } + + //no cleanup of the normals is required + if(this->GenerateNormals) + { + vtkm::cont::Field normalField(std::string("normals"), 1, + vtkm::cont::Field::ASSOC_POINTS, normals); + output.AddField( normalField ); + } + + + //add the coordinates to the output dataset + vtkm::cont::CoordinateSystem outputCoords("coordinates", 1, vertices); + output.AddCoordinateSystem( outputCoords ); + + //todo: figure out how to pass the fields to interpolate to the Result + return vtkm::filter::DataSetResult(output); +} + +//----------------------------------------------------------------------------- +template +bool MarchingCubes::DoMapField(vtkm::filter::DataSetResult& result, + const vtkm::cont::ArrayHandle& input, + const vtkm::filter::FieldMetadata& fieldMeta, + const vtkm::filter::PolicyBase&, + const DeviceAdapter&) +{ + if(fieldMeta.IsPointField() == false) + { + //not a point field, we can't map it + return false; + } + + //we have a point field so lets map it + ApplyToField applyToField; + vtkm::worklet::DispatcherMapField applyFieldDispatcher(applyToField); + + //todo: need to use the policy to get the correct storage tag for output + vtkm::cont::ArrayHandle output; + applyFieldDispatcher.Invoke(this->InterpolationIds, + this->InterpolationWeights, + input, + output); + + //use the same meta data as the input so we get the same field name, etc. + result.GetDataSet().AddField( fieldMeta.AsField(output) ); + return true; + +} + + +} +} // namespace vtkm::filter diff --git a/vtkm/filter/PointElevation.h b/vtkm/filter/PointElevation.h new file mode 100644 index 000000000..7607691e8 --- /dev/null +++ b/vtkm/filter/PointElevation.h @@ -0,0 +1,74 @@ +//============================================================================ +// 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 2014 Sandia Corporation. +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2014 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// 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. +//============================================================================ + +#ifndef vtk_m_filter_PointElevation_h +#define vtk_m_filter_PointElevation_h + +#include +#include + + +namespace vtkm { +namespace filter { + +class PointElevation : public vtkm::filter::FieldFilter +{ +public: + VTKM_CONT_EXPORT + PointElevation(); + + VTKM_CONT_EXPORT + void SetLowPoint(vtkm::Float64 x, vtkm::Float64 y, vtkm::Float64 z); + + VTKM_CONT_EXPORT + void SetHighPoint(vtkm::Float64 x, vtkm::Float64 y, vtkm::Float64 z); + + VTKM_CONT_EXPORT + void SetRange(vtkm::Float64 low, vtkm::Float64 high); + + + template + VTKM_CONT_EXPORT + vtkm::filter::FieldResult DoExecute(const vtkm::cont::DataSet &input, + const vtkm::cont::ArrayHandle &field, + const vtkm::filter::FieldMetadata& fieldMeta, + const vtkm::filter::PolicyBase& policy, + const DeviceAdapter& tag); + +private: + vtkm::worklet::PointElevation Worklet; + +}; + +template<> +class FilterTraits +{ +public: + //Point Elevation can only convert Float and Double Vec3 arrays + typedef vtkm::TypeListTagFieldVec3 InputFieldTypeList; +}; + +} +} // namespace vtkm::filter + + +#include + +#endif // vtk_m_filter_PointElevation_h \ No newline at end of file diff --git a/vtkm/filter/PointElevation.hxx b/vtkm/filter/PointElevation.hxx new file mode 100644 index 000000000..83350605e --- /dev/null +++ b/vtkm/filter/PointElevation.hxx @@ -0,0 +1,79 @@ +//============================================================================ +// 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 2014 Sandia Corporation. +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2014 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// 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 + +namespace vtkm { +namespace filter { + + +//----------------------------------------------------------------------------- +PointElevation::PointElevation(): + Worklet() +{ + +} + +//----------------------------------------------------------------------------- +void PointElevation::SetLowPoint(vtkm::Float64 x, vtkm::Float64 y, vtkm::Float64 z) +{ + this->Worklet.SetLowPoint( vtkm::make_Vec(x,y,z) ); +} + +//----------------------------------------------------------------------------- +void PointElevation::SetHighPoint(vtkm::Float64 x, vtkm::Float64 y, vtkm::Float64 z) +{ + this->Worklet.SetHighPoint( vtkm::make_Vec(x,y,z) ); +} + +//----------------------------------------------------------------------------- +void PointElevation::SetRange(vtkm::Float64 low, vtkm::Float64 high) +{ + this->Worklet.SetRange(low,high); +} + +//----------------------------------------------------------------------------- +template +vtkm::filter::FieldResult +PointElevation::DoExecute(const vtkm::cont::DataSet &, + const vtkm::cont::ArrayHandle &field, + const vtkm::filter::FieldMetadata&, + const vtkm::filter::PolicyBase&, + const DeviceAdapter&) +{ + vtkm::cont::ArrayHandle outArray; + vtkm::worklet::DispatcherMapField dispatcher(this->Worklet); + + //todo, we need to use the policy to determine the valid conversions + //that the dispatcher should do + dispatcher.Invoke(field, outArray); + + vtkm::cont::Field outField(this->GetOutputFieldName(), 1, + vtkm::cont::Field::ASSOC_WHOLE_MESH, + outArray); + return vtkm::filter::FieldResult(outField); +} + +} +} // namespace vtkm::filter diff --git a/vtkm/filter/PolicyBase.h b/vtkm/filter/PolicyBase.h new file mode 100644 index 000000000..1889ecdb5 --- /dev/null +++ b/vtkm/filter/PolicyBase.h @@ -0,0 +1,123 @@ +//============================================================================ +// 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 2014 Sandia Corporation. +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2014 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// 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. +//============================================================================ + +#ifndef vtk_m_filter_PolicyBase_h +#define vtk_m_filter_PolicyBase_h + +#include +#include +#include + +#include + +namespace vtkm { +namespace filter { + +template +class PolicyBase +{ + + +}; + + +//----------------------------------------------------------------------------- +template +VTKM_CONT_EXPORT +vtkm::cont::DynamicArrayHandleBase< + typename DerivedPolicy::FieldTypeList, + typename DerivedPolicy::FieldStorageList + > +Convert(const vtkm::cont::Field& field, + const vtkm::filter::PolicyBase&) +{ + typedef typename DerivedPolicy::FieldTypeList TypeList; + typedef typename DerivedPolicy::FieldStorageList StorageList; + return field.GetData().ResetTypeAndStorageLists(TypeList(),StorageList()); +} + +//----------------------------------------------------------------------------- +template +VTKM_CONT_EXPORT +vtkm::cont::DynamicArrayHandleBase< + typename vtkm::filter::FilterTraits::InputFieldTypeList, + typename DerivedPolicy::FieldStorageList + > +Convert(const vtkm::cont::Field& field, + const vtkm::filter::PolicyBase&, + const vtkm::filter::FilterTraits&) +{ + //todo: we need to intersect the policy field type list and the + //filter traits to the get smallest set of valid types + typedef typename vtkm::filter::FilterTraits::InputFieldTypeList TypeList; + // typedef typename DerivedPolicy::FieldTypeList TypeList; + typedef typename DerivedPolicy::FieldStorageList StorageList; + return field.GetData().ResetTypeAndStorageLists(TypeList(),StorageList()); +} + +//----------------------------------------------------------------------------- +template +VTKM_CONT_EXPORT +vtkm::cont::DynamicArrayHandleBase< + typename DerivedPolicy::CoordinateTypeList, + typename DerivedPolicy::CoordinateStorageList + > +Convert(const vtkm::cont::CoordinateSystem& coordinates, + const vtkm::filter::PolicyBase&) +{ + typedef typename DerivedPolicy::CoordinateTypeList TypeList; + typedef typename DerivedPolicy::CoordinateStorageList StorageList; + return coordinates.GetData().ResetTypeAndStorageLists(TypeList(),StorageList()); +} + +//----------------------------------------------------------------------------- +template +VTKM_CONT_EXPORT +vtkm::cont::DynamicArrayHandleBase< + typename vtkm::filter::FilterTraits::InputFieldTypeList, + typename DerivedPolicy::CoordinateStorageList + > +Convert(const vtkm::cont::CoordinateSystem& coordinates, + const vtkm::filter::PolicyBase&, + const vtkm::filter::FilterTraits&) +{ + //todo: we need to intersect the policy field type list and the + //filter traits to the get smallest set of valid types + typedef typename vtkm::filter::FilterTraits::InputFieldTypeList TypeList; + // typedef typename DerivedPolicy::CoordinateTypeList TypeList; + typedef typename DerivedPolicy::CoordinateStorageList StorageList; + return coordinates.GetData().ResetTypeAndStorageLists(TypeList(),StorageList()); +} + +//----------------------------------------------------------------------------- +template +VTKM_CONT_EXPORT +vtkm::cont::DynamicCellSetBase< typename DerivedPolicy::CellSetList > +Convert(const vtkm::cont::DynamicCellSet& cellset, + const vtkm::filter::PolicyBase&) +{ + typedef typename DerivedPolicy::CellSetList CellSetList; + return cellset.ResetCellSetList(CellSetList()); +} + +} +} + +#endif diff --git a/vtkm/filter/Threshold.h b/vtkm/filter/Threshold.h new file mode 100644 index 000000000..71aff41ed --- /dev/null +++ b/vtkm/filter/Threshold.h @@ -0,0 +1,72 @@ +//============================================================================ +// 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 2014 Sandia Corporation. +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2014 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// 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. +//============================================================================ + +#ifndef vtk_m_filter_Threshold_h +#define vtk_m_filter_Threshold_h + +#include +#include + +namespace vtkm { +namespace filter { + +class Threshold : public vtkm::filter::DataSetWithFieldFilter +{ +public: + VTKM_CONT_EXPORT + Threshold(); + + VTKM_CONT_EXPORT + void SetThresholdValue(vtkm::Float64 value){ this->ThresholdValue = value; } + + VTKM_CONT_EXPORT + vtkm::Float64 GetThresholdValue() const { return this->ThresholdValue; } + + template + VTKM_CONT_EXPORT + vtkm::filter::DataSetResult DoExecute(const vtkm::cont::DataSet& input, + const vtkm::cont::ArrayHandle& field, + const vtkm::filter::FieldMetadata& fieldMeta, + const vtkm::filter::PolicyBase& policy, + const DeviceAdapter& tag); + + //Map a new field onto the resulting dataset after running the filter + //this call is only valid + template + VTKM_CONT_EXPORT + bool DoMapField(vtkm::filter::DataSetResult& result, + const vtkm::cont::ArrayHandle& input, + const vtkm::filter::FieldMetadata& fieldMeta, + const vtkm::filter::PolicyBase& policy, + const DeviceAdapter& tag); + + +private: + double ThresholdValue; + vtkm::cont::ArrayHandle ValidCellIds; +}; + +} +} // namespace vtkm::filter + + +#include + +#endif // vtk_m_filter_Threshold_h \ No newline at end of file diff --git a/vtkm/filter/Threshold.hxx b/vtkm/filter/Threshold.hxx new file mode 100644 index 000000000..d516d3b5b --- /dev/null +++ b/vtkm/filter/Threshold.hxx @@ -0,0 +1,188 @@ +//============================================================================ +// 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 2014 Sandia Corporation. +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2014 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// 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 +#include +#include + +#include + +namespace +{ + +class HasValue +{ +public: + VTKM_CONT_EXPORT + HasValue(const vtkm::Float64& value) : Value(value) + { } + + template + VTKM_EXEC_EXPORT + bool operator()(const T& value) const + { + return value == static_cast(this->Value); + } + +private: + vtkm::Float64 Value; +}; + +class AddPermutationCellSet +{ + vtkm::cont::DataSet* Output; + vtkm::cont::ArrayHandle* ValidIds; +public: + AddPermutationCellSet(vtkm::cont::DataSet& data, + vtkm::cont::ArrayHandle& validIds): + Output(&data), + ValidIds(&validIds) + { } + + template + void operator()(const CellSetType& cellset ) const + { + typedef vtkm::cont::CellSetPermutation, + CellSetType> PermutationCellSetType; + + PermutationCellSetType permCellSet(*this->ValidIds, cellset, + cellset.GetName(), + cellset.GetDimensionality()); + + this->Output->AddCellSet(permCellSet); + } +}; + +} + + +namespace vtkm { +namespace filter { + +//----------------------------------------------------------------------------- +Threshold::Threshold(): + vtkm::filter::DataSetWithFieldFilter(), + ThresholdValue(0), + ValidCellIds() +{ + +} + +//----------------------------------------------------------------------------- +template +vtkm::filter::DataSetResult Threshold::DoExecute(const vtkm::cont::DataSet& input, + const vtkm::cont::ArrayHandle& field, + const vtkm::filter::FieldMetadata& fieldMeta, + const vtkm::filter::PolicyBase& policy, + const DeviceAdapter&) +{ + //get the cells and coordinates of the dataset + const vtkm::cont::DynamicCellSet& cells = + input.GetCellSet(this->GetActiveCellSetIndex()); + + HasValue predicate( this->GetThresholdValue() ); + vtkm::cont::ArrayHandle passFlags; + if(fieldMeta.IsPointField()) + { + typedef vtkm::worklet::Threshold Worklets; + typedef Worklets::ThresholdByPointField< HasValue > ThresholdWorklet; + ThresholdWorklet worklet(predicate); + vtkm::worklet::DispatcherMapTopology dispatcher(worklet); + dispatcher.Invoke(vtkm::filter::Convert(cells, policy), field, passFlags); + } + else if(fieldMeta.IsCellField()) + { + typedef vtkm::worklet::Threshold Worklets; + typedef Worklets::ThresholdByCellField< HasValue > ThresholdWorklet; + ThresholdWorklet worklet(predicate); + vtkm::worklet::DispatcherMapTopology dispatcher(worklet); + dispatcher.Invoke(vtkm::filter::Convert(cells, policy), field, passFlags); + } + else + { + //todo: we need to mark this as a failure of input, not a failure + //of the algorithm + return vtkm::filter::DataSetResult(); + } + + typedef vtkm::cont::DeviceAdapterAlgorithm Algorithm; + + Algorithm::StreamCompact(passFlags, this->ValidCellIds); + + vtkm::cont::DataSet output; + output.AddCoordinateSystem( + input.GetCoordinateSystem(this->GetActiveCoordinateSystemIndex()) ); + + //now generate the output cellset. We are going to need to do a cast + //and call to generate the correct form of output. + //todo: see if we can make this into a helper class that other filters + //can use to reduce code duplication, and make it easier to write filters + //that return complex dataset types. + AddPermutationCellSet addCellSet(output, this->ValidCellIds); + vtkm::filter::Convert(cells, policy).CastAndCall(addCellSet); + + //todo: We need to generate a new output policy that replaces + //the original storage tag with a new storage tag where everything is + //wrapped in CellSetPermutation. + return output; +} + +//----------------------------------------------------------------------------- +template +bool Threshold::DoMapField(vtkm::filter::DataSetResult& result, + const vtkm::cont::ArrayHandle& input, + const vtkm::filter::FieldMetadata& fieldMeta, + const vtkm::filter::PolicyBase&, + const DeviceAdapter&) +{ + if(fieldMeta.IsPointField()) + { + //we copy the input handle to the result dataset, reusing the metadata + result.GetDataSet().AddField( fieldMeta.AsField(input) ); + return true; + } + + if(fieldMeta.IsCellField()) + { + //todo: We need to generate a new output policy that replaces + //the original storage tag with a new storage tag where everything is + //wrapped in ArrayHandlePermutation. + typedef vtkm::cont::ArrayHandlePermutation< + vtkm::cont::ArrayHandle, + vtkm::cont::ArrayHandle > PermutationType; + + PermutationType permutation = + vtkm::cont::make_ArrayHandlePermutation(this->ValidCellIds, input); + + result.GetDataSet().AddField( fieldMeta.AsField(permutation) ); + return true; + } + + return false; +} + +} +} diff --git a/vtkm/filter/VertexClustering.h b/vtkm/filter/VertexClustering.h new file mode 100644 index 000000000..abf5decc9 --- /dev/null +++ b/vtkm/filter/VertexClustering.h @@ -0,0 +1,68 @@ +//============================================================================ +// 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 2014 Sandia Corporation. +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2014 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// 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. +//============================================================================ + +#ifndef vtk_m_filter_VertexClustering_h +#define vtk_m_filter_VertexClustering_h + +#include +#include + +namespace vtkm { +namespace filter { + +class VertexClustering : public vtkm::filter::DataSetFilter +{ +public: + VTKM_CONT_EXPORT + VertexClustering(); + + VTKM_CONT_EXPORT + void SetNumberOfDivisions(const vtkm::Id3& num ) { this->NumberOfDivisions = num; } + + VTKM_CONT_EXPORT + const vtkm::Id3& GetNumberOfDivisions() const { return this->NumberOfDivisions; } + + template + VTKM_CONT_EXPORT + vtkm::filter::DataSetResult DoExecute(const vtkm::cont::DataSet& input, + const vtkm::filter::PolicyBase& policy, + const DeviceAdapter& tag); + + //Map a new field onto the resulting dataset after running the filter + //this call is only valid + template + VTKM_CONT_EXPORT + bool DoMapField(vtkm::filter::DataSetResult& result, + const vtkm::cont::ArrayHandle& input, + const vtkm::filter::FieldMetadata& fieldMeta, + const vtkm::filter::PolicyBase& policy, + const DeviceAdapter& tag); + +private: + vtkm::Id3 NumberOfDivisions; +}; + +} +} // namespace vtkm::filter + + +#include + +#endif // vtk_m_filter_Threshold_h \ No newline at end of file diff --git a/vtkm/filter/VertexClustering.hxx b/vtkm/filter/VertexClustering.hxx new file mode 100644 index 000000000..f6fef079a --- /dev/null +++ b/vtkm/filter/VertexClustering.hxx @@ -0,0 +1,89 @@ +//============================================================================ +// 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 2014 Sandia Corporation. +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2014 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// 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. +//============================================================================ + +namespace vtkm { +namespace filter { + +namespace +{ + template + void compute_bounds(const vtkm::cont::CoordinateSystem& coords, + vtkm::Float64 *bounds, + const vtkm::filter::PolicyBase&, + const DeviceAdapter& tag) +{ + typedef typename DerivedPolicy::CoordinateTypeList TypeList; + typedef typename DerivedPolicy::CoordinateStorageList StorageList; + //todo: Look at the GetBounds function. It currently generates + //a significant amount of code, inflating binary sizes considerably + coords.GetBounds(bounds, tag, TypeList(), StorageList()); +} + +} + +//----------------------------------------------------------------------------- +VertexClustering::VertexClustering(): + vtkm::filter::DataSetFilter(), + NumberOfDivisions(256, 256, 256) +{ + +} + +//----------------------------------------------------------------------------- +template +vtkm::filter::DataSetResult VertexClustering::DoExecute(const vtkm::cont::DataSet& input, + const vtkm::filter::PolicyBase& policy, + const DeviceAdapter& tag) +{ + // todo this code needs to obey the policy for what storage types + // the output should use + vtkm::worklet::VertexClustering clustering; + + //need to compute bounds first + vtkm::Float64 bounds[6]; + compute_bounds(input.GetCoordinateSystem(), bounds, policy, tag); + + vtkm::cont::DataSet outDataSet = clustering.Run(vtkm::filter::Convert(input.GetCellSet(), policy), + vtkm::filter::Convert(input.GetCoordinateSystem(), policy), + bounds, + this->GetNumberOfDivisions(), + tag); + + return vtkm::filter::DataSetResult(outDataSet); +} + +//----------------------------------------------------------------------------- +template +bool VertexClustering::DoMapField(vtkm::filter::DataSetResult&, + const vtkm::cont::ArrayHandle&, + const vtkm::filter::FieldMetadata&, + const vtkm::filter::PolicyBase&, + const DeviceAdapter&) +{ + return false; +} + +} +} diff --git a/vtkm/filter/internal/CMakeLists.txt b/vtkm/filter/internal/CMakeLists.txt new file mode 100644 index 000000000..00465f863 --- /dev/null +++ b/vtkm/filter/internal/CMakeLists.txt @@ -0,0 +1,27 @@ +##============================================================================ +## 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 2014 Sandia Corporation. +## Copyright 2014 UT-Battelle, LLC. +## Copyright 2014 Los Alamos National Security. +## +## Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +## 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. +##============================================================================ + +set(headers + ResolveFieldTypeAndExecute.h + ResolveFieldTypeAndMap.h + RuntimeDeviceTracker.h +) + +vtkm_declare_headers(${headers}) diff --git a/vtkm/filter/internal/ResolveFieldTypeAndExecute.h b/vtkm/filter/internal/ResolveFieldTypeAndExecute.h new file mode 100644 index 000000000..98c5bf70d --- /dev/null +++ b/vtkm/filter/internal/ResolveFieldTypeAndExecute.h @@ -0,0 +1,303 @@ +//============================================================================ +// 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 2014 Sandia Corporation. +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2014 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// 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. +//============================================================================ +#ifndef vtk_m_filter_internal_ResolveFieldTypeAndExecute_h +#define vtk_m_filter_internal_ResolveFieldTypeAndExecute_h + +#include +#include + +#include +#include +#include + +namespace +{ + +template struct CanExecute; + +template +ReturnType run_if_valid(ClassType* c, + const vtkm::cont::DataSet& ds, + const ArrayType &field, + const vtkm::filter::FieldMetadata& fieldMeta, + const vtkm::filter::PolicyBase& policy, + vtkm::filter::internal::RuntimeDeviceTracker& tracker, + DeviceAdapterTag tag) +{ + typedef vtkm::cont::DeviceAdapterTraits< + DeviceAdapterTag> DeviceAdapterTraits; + + typedef CanExecute CanExecuteType; + return CanExecuteType::Run(c,ds,field,fieldMeta,policy,tracker,tag); +} + +template +ReturnType run_if_valid(ClassType* c, + const vtkm::cont::DataSet& ds, + const vtkm::filter::PolicyBase& policy, + vtkm::filter::internal::RuntimeDeviceTracker& tracker, + DeviceAdapterTag tag) +{ + typedef vtkm::cont::DeviceAdapterTraits< + DeviceAdapterTag> DeviceAdapterTraits; + + typedef CanExecute CanExecuteType; + return CanExecuteType::Run(c,ds,policy,tracker,tag); +} + + +//Implementation that we call on device adapters we don't have support +//enabled for +template +struct CanExecute +{ + template + static ReturnType Run(ClassType*, + const vtkm::cont::DataSet &, + const ArrayType &, + const vtkm::filter::FieldMetadata&, + const vtkm::filter::PolicyBase&, + vtkm::filter::internal::RuntimeDeviceTracker&, + DeviceAdapterTag) + { + return ReturnType(); + } + + template + static ReturnType Run(ClassType*, + const vtkm::cont::DataSet &, + const vtkm::filter::PolicyBase&, + vtkm::filter::internal::RuntimeDeviceTracker&, + DeviceAdapterTag) + { + return ReturnType(); + } +}; + +//Implementation that we call on device adapters we do have support +//enabled for +template +struct CanExecute +{ + template + static ReturnType Run(ClassType* c, + const vtkm::cont::DataSet &input, + const ArrayType &field, + const vtkm::filter::FieldMetadata& fieldMeta, + const vtkm::filter::PolicyBase& policy, + vtkm::filter::internal::RuntimeDeviceTracker& tracker, + DeviceAdapterTag tag) + { + const bool runtime_usable_device = tracker.CanRunOn(tag); + + ReturnType result; + if(runtime_usable_device) + { + try + { + result = c->DoExecute(input,field,fieldMeta,policy,tag); + } + catch(vtkm::cont::ErrorControlBadAllocation e) + { + std::cerr << "caught ErrorControlBadAllocation " << e.GetMessage() << std::endl; + //currently we only consider OOM errors worth disabling a device for + //than we fallback to another device + tracker.ReportAllocationFailure(tag,e); + } + catch(vtkm::cont::ErrorControlBadType e) + { + //bad type errors should stop the filter, instead of deferring to + //another device adapter + std::cerr << "caught ErrorControlBadType : " << e.GetMessage() << std::endl; + } + catch(vtkm::cont::ErrorControlBadValue e) + { + //bad value errors should stop the filter, instead of deferring to + //another device adapter + std::cerr << "caught ErrorControlBadValue : " << e.GetMessage() << std::endl; + } + catch(vtkm::cont::ErrorControlAssert e) + { + //assert occurred, generally caused by going out of bounds on an array + //this won't be solved by trying a different device adapter + //so stop the filter + std::cerr << "caught ErrorControlAssert : " << e.GetMessage() << std::endl; + } + catch(vtkm::cont::Error e) + { + //general errors should be caught and let us try the next device adapter. + std::cerr << "exception is: " << e.GetMessage() << std::endl; + } + } + + return result; + } + + template + static ReturnType Run(ClassType* c, + const vtkm::cont::DataSet &input, + const vtkm::filter::PolicyBase& policy, + vtkm::filter::internal::RuntimeDeviceTracker& tracker, + DeviceAdapterTag tag) + { + const bool runtime_usable_device = tracker.CanRunOn(tag); + + ReturnType result; + if(runtime_usable_device) + { + try + { + result = c->DoExecute(input,policy,tag); + } + catch(vtkm::cont::ErrorControlBadAllocation e) + { + std::cerr << "caught ErrorControlBadAllocation " << e.GetMessage() << std::endl; + //currently we only consider OOM errors worth disabling a device for + //than we fallback to another device + tracker.ReportAllocationFailure(tag,e); + } + catch(vtkm::cont::ErrorControlBadType e) + { + //bad type errors should stop the filter, instead of deferring to + //another device adapter + std::cerr << "caught ErrorControlBadType : " << e.GetMessage() << std::endl; + } + catch(vtkm::cont::ErrorControlBadValue e) + { + //bad value errors should stop the filter, instead of deferring to + //another device adapter + std::cerr << "caught ErrorControlBadValue : " << e.GetMessage() << std::endl; + } + catch(vtkm::cont::ErrorControlAssert e) + { + //assert occurred, generally caused by going out of bounds on an array + //this won't be solved by trying a different device adapter + //so stop the filter + std::cerr << "caught ErrorControlAssert : " << e.GetMessage() << std::endl; + } + catch(vtkm::cont::Error e) + { + //general errors should be caught and let us try the next device adapter. + std::cerr << "exception is: " << e.GetMessage() << std::endl; + } + } + + return result; + } +}; +} + +namespace vtkm { +namespace filter { +namespace internal { + +namespace +{ + template + struct ResolveFieldTypeAndExecute + { + Derived* DerivedClass; + const vtkm::cont::DataSet &InputData; + const vtkm::filter::FieldMetadata& Metadata; + const vtkm::filter::PolicyBase& Policy; + vtkm::filter::internal::RuntimeDeviceTracker& Tracker; + ResultType& Result; + + ResolveFieldTypeAndExecute(Derived* derivedClass, + const vtkm::cont::DataSet &inputData, + const vtkm::filter::FieldMetadata& fieldMeta, + const vtkm::filter::PolicyBase& policy, + vtkm::filter::internal::RuntimeDeviceTracker& tracker, + ResultType& result): + DerivedClass(derivedClass), + InputData(inputData), + Metadata(fieldMeta), + Policy(policy), + Tracker(tracker), + Result(result) + { + + } + + template + void operator()(const vtkm::cont::ArrayHandle& field) const + { + typedef vtkm::cont::DeviceAdapterTagCuda CudaTag; + typedef vtkm::cont::DeviceAdapterTagTBB TBBTag; + typedef vtkm::cont::DeviceAdapterTagSerial SerialTag; + + { + Result = run_if_valid( this->DerivedClass, + this->InputData, + field, + this->Metadata, + this->Policy, + this->Tracker, + CudaTag() ); + } + + if( !Result.IsValid() ) + { + Result = run_if_valid( this->DerivedClass, + this->InputData, + field, + this->Metadata, + this->Policy, + this->Tracker, + TBBTag() ); + } + if( !Result.IsValid() ) + { + Result = run_if_valid( this->DerivedClass, + this->InputData, + field, + this->Metadata, + this->Policy, + this->Tracker, + SerialTag() ); + } + } + }; +} + +} +} +} // namespace vtkm::filter::internal + +#endif //vtk_m_filter_internal_ResolveFieldTypeAndExecute_h diff --git a/vtkm/filter/internal/ResolveFieldTypeAndMap.h b/vtkm/filter/internal/ResolveFieldTypeAndMap.h new file mode 100644 index 000000000..088b81b80 --- /dev/null +++ b/vtkm/filter/internal/ResolveFieldTypeAndMap.h @@ -0,0 +1,229 @@ +//============================================================================ +// 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 2014 Sandia Corporation. +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2014 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// 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. +//============================================================================ +#ifndef vtk_m_filter_internal_ResolveFieldTypeAndMap_h +#define vtk_m_filter_internal_ResolveFieldTypeAndMap_h + +#include +#include + +#include +#include +#include + +//forward declarations needed +namespace vtkm { +namespace filter { + class DataSetResult; +} +} + +namespace +{ + +template struct CanMap; + +template +bool map_if_valid(ClassType* c, + vtkm::filter::DataSetResult& input, + const ArrayType &field, + const vtkm::filter::FieldMetadata& fieldMeta, + const vtkm::filter::PolicyBase& policy, + vtkm::filter::internal::RuntimeDeviceTracker& tracker, + DeviceAdapterTag tag) +{ + typedef vtkm::cont::DeviceAdapterTraits< + DeviceAdapterTag> DeviceAdapterTraits; + + typedef CanMap CanMapType; + return CanMapType::Run(c,input,field,fieldMeta,policy,tracker,tag); +} + + +//Implementation that we call on device adapters we don't have support +//enabled for +template<> +struct CanMap +{ + template + static bool Run(ClassType*, + vtkm::filter::DataSetResult&, + const ArrayType &, + const vtkm::filter::FieldMetadata&, + const vtkm::filter::PolicyBase&, + vtkm::filter::internal::RuntimeDeviceTracker&, + DeviceAdapterTag) + { + return false; + } +}; + +//Implementation that we call on device adapters we do have support +//enabled for +template<> +struct CanMap +{ + template + static bool Run(ClassType* c, + vtkm::filter::DataSetResult& input, + const ArrayType &field, + const vtkm::filter::FieldMetadata& fieldMeta, + const vtkm::filter::PolicyBase& policy, + vtkm::filter::internal::RuntimeDeviceTracker& tracker, + DeviceAdapterTag tag) + { + const bool runtime_usable_device = tracker.CanRunOn(tag); + + bool valid = false; + if(runtime_usable_device) + { + try + { + valid = c->DoMapField(input,field,fieldMeta,policy,tag); + } + catch(vtkm::cont::ErrorControlBadAllocation e) + { + std::cerr << "caught ErrorControlBadAllocation " << e.GetMessage() << std::endl; + //currently we only consider OOM errors worth disabling a device for + //than we fallback to another device + tracker.ReportAllocationFailure(tag,e); + } + catch(vtkm::cont::ErrorControlBadType e) + { + //bad type errors should stop the filter, instead of deferring to + //another device adapter + std::cerr << "caught ErrorControlBadType : " << e.GetMessage() << std::endl; + } + catch(vtkm::cont::ErrorControlBadValue e) + { + //bad value errors should stop the filter, instead of deferring to + //another device adapter + std::cerr << "caught ErrorControlBadValue : " << e.GetMessage() << std::endl; + } + catch(vtkm::cont::ErrorControlAssert e) + { + //assert occurred, generally caused by going out of bounds on an array + //this won't be solved by trying a different device adapter + //so stop the filter + std::cerr << "caught ErrorControlAssert : " << e.GetMessage() << std::endl; + } + catch(vtkm::cont::Error e) + { + //general errors should be caught and let us try the next device adapter. + std::cerr << "exception is: " << e.GetMessage() << std::endl; + } + } + + return valid; + } +}; +} + +namespace vtkm { +namespace filter { +namespace internal { + +namespace +{ + template + struct ResolveFieldTypeAndMap + { + Derived* DerivedClass; + vtkm::filter::DataSetResult& InputResult; + const vtkm::filter::FieldMetadata& Metadata; + const vtkm::filter::PolicyBase& Policy; + vtkm::filter::internal::RuntimeDeviceTracker& Tracker; + bool& RanProperly; + + + ResolveFieldTypeAndMap(Derived* derivedClass, + vtkm::filter::DataSetResult& inResult, + const vtkm::filter::FieldMetadata& fieldMeta, + const vtkm::filter::PolicyBase& policy, + vtkm::filter::internal::RuntimeDeviceTracker& tracker, + bool& ran): + DerivedClass(derivedClass), + InputResult(inResult), + Metadata(fieldMeta), + Policy(policy), + Tracker(tracker), + RanProperly(ran) + { + + } + + template + void operator()(const vtkm::cont::ArrayHandle& field) const + { + typedef vtkm::cont::DeviceAdapterTagCuda CudaTag; + typedef vtkm::cont::DeviceAdapterTagTBB TBBTag; + typedef vtkm::cont::DeviceAdapterTagSerial SerialTag; + + bool valid = false; + + { + valid = map_if_valid(this->DerivedClass, + this->InputResult, + field, + this->Metadata, + this->Policy, + this->Tracker, + CudaTag() ); + } + + if( !valid ) + { + valid = map_if_valid(this->DerivedClass, + this->InputResult, + field, + this->Metadata, + this->Policy, + this->Tracker, + TBBTag() ); + } + if( !valid ) + { + valid = map_if_valid(this->DerivedClass, + this->InputResult, + field, + this->Metadata, + this->Policy, + this->Tracker, + SerialTag() ); + } + this->RanProperly = valid; + } + }; +} + +} +} +} // namespace vtkm::filter::internal + +#endif //vtk_m_filter_internal_ResolveFieldTypeAndExecute_h diff --git a/vtkm/filter/internal/RuntimeDeviceTracker.h b/vtkm/filter/internal/RuntimeDeviceTracker.h new file mode 100644 index 000000000..27624840d --- /dev/null +++ b/vtkm/filter/internal/RuntimeDeviceTracker.h @@ -0,0 +1,120 @@ +//============================================================================ +// 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 2014 Sandia Corporation. +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2014 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// 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. +//============================================================================ +#ifndef vtk_m_filter_internal_RuntimeDeviceTracker_h +#define vtk_m_filter_internal_RuntimeDeviceTracker_h + +#include +#include +#include + +#include +#include +#include + +#include + +namespace vtkm { +namespace filter { +namespace internal { + +/// A class that can be used to determine if a given device adapter +/// is supported on the current machine at runtime. This is a more +/// complex version of vtkm::cont::RunimeDeviceInformation, as this can +/// also track when worklets fail, why the fail, and will update the list +/// of valid runtime devices based on that information. +/// +/// +class RuntimeDeviceTracker +{ +public: + VTKM_CONT_EXPORT + RuntimeDeviceTracker() + { + this->Reset(); + } + + /// Returns true if the given device adapter is supported on the current + /// machine. + /// + template + bool CanRunOn(DeviceAdapterTag) const + { + typedef vtkm::cont::DeviceAdapterTraits Traits; + return this->RuntimeValid[ Traits::GetId() ]; + } + + ///Report a failure to allocate memory on a device, this will flag the device + ///as being unusable for all future invocations of the instance of the filter. + /// + template + void ReportAllocationFailure(DeviceAdapterTag, + const vtkm::cont::ErrorControlBadAllocation&) + { + typedef vtkm::cont::DeviceAdapterTraits Traits; + this->RuntimeValid[ Traits::GetId() ] = false; + } + + ///Reset the tracker to its default state. + /// Will discard any updates caused by reported failures. + /// + void Reset() + { + std::memset(this->RuntimeValid, 0, sizeof(bool)*8 ); + + //for each device determine the current runtime status at mark it + //self in the validity array + { + typedef vtkm::cont::DeviceAdapterTagCuda CudaTag; + typedef vtkm::cont::DeviceAdapterTraits CudaTraits; + + vtkm::cont::RuntimeDeviceInformation runtimeDevice; + this->RuntimeValid[ CudaTraits::GetId() ] = runtimeDevice.Exists(); + } + + { + typedef vtkm::cont::DeviceAdapterTagTBB TBBTag; + typedef vtkm::cont::DeviceAdapterTraits TBBTraits; + + vtkm::cont::RuntimeDeviceInformation runtimeDevice; + this->RuntimeValid[ TBBTraits::GetId() ] = runtimeDevice.Exists(); + } + + { + typedef vtkm::cont::DeviceAdapterTagSerial SerialTag; + typedef vtkm::cont::DeviceAdapterTraits SerialTraits; + + vtkm::cont::RuntimeDeviceInformation runtimeDevice; + this->RuntimeValid[ SerialTraits::GetId() ] = runtimeDevice.Exists(); + } + } + + + +private: + //make the array size 8 so the sizeof the class doesn't change when + //we add more device adapters. + bool RuntimeValid[8]; +}; + +} +} +} // namespace vtkm::filter::internal + +#endif //vtk_m_filter_internal_RuntimeDeviceTracker_h diff --git a/vtkm/filter/testing/CMakeLists.txt b/vtkm/filter/testing/CMakeLists.txt new file mode 100644 index 000000000..f8674bc6e --- /dev/null +++ b/vtkm/filter/testing/CMakeLists.txt @@ -0,0 +1,31 @@ +##============================================================================ +## 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 2014 Sandia Corporation. +## Copyright 2014 UT-Battelle, LLC. +## Copyright 2014 Los Alamos National Security. +## +## Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +## 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. +##============================================================================ + +set(unit_tests + UnitTestFieldMetadata.cxx + UnitTestCellAverageFilter.cxx + UnitTestExternalFacesFilter.cxx + UnitTestPointElevationFilter.cxx + UnitTestMarchingCubesFilter.cxx + UnitTestThresholdFilter.cxx + UnitTestVertexClusteringFilter.cxx + ) + +vtkm_unit_tests(SOURCES ${unit_tests}) diff --git a/vtkm/filter/testing/UnitTestCellAverageFilter.cxx b/vtkm/filter/testing/UnitTestCellAverageFilter.cxx new file mode 100644 index 000000000..eb772fa78 --- /dev/null +++ b/vtkm/filter/testing/UnitTestCellAverageFilter.cxx @@ -0,0 +1,122 @@ +//============================================================================ +// 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 2014 Sandia Corporation. +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2014 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// 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 +#include +#include + +namespace { + +void TestCellAverageRegular3D() +{ + std::cout << "Testing CellAverage Filter on 3D strucutred data" << std::endl; + + vtkm::cont::testing::MakeTestDataSet testDataSet; + vtkm::cont::DataSet dataSet = testDataSet.Make3DUniformDataSet0(); + + vtkm::filter::FieldResult result; + vtkm::filter::CellAverage cavg; + cavg.SetOutputFieldName("avgvals"); + + result = cavg.Execute( dataSet, dataSet.GetField("pointvar")); + + vtkm::cont::ArrayHandle resultArrayHandle; + const bool valid = result.FieldAs(resultArrayHandle); + + if(valid) + { + vtkm::Float32 expected[4] = { 60.1875f, 70.2125f, 120.3375f, 130.3625f }; + for (int i = 0; i < 4; ++i) + { + VTKM_TEST_ASSERT(test_equal(resultArrayHandle.GetPortalConstControl().Get(i), + expected[i]), "Wrong result for CellAverage worklet on 3D regular data"); + } + } +} + +void TestCellAverageRegular2D() +{ + std::cout << "Testing CellAverage Filter on 2D strucutred data" << std::endl; + + vtkm::cont::testing::MakeTestDataSet testDataSet; + vtkm::cont::DataSet dataSet = testDataSet.Make2DUniformDataSet0(); + + vtkm::filter::FieldResult result; + vtkm::filter::CellAverage cavg; + cavg.SetOutputFieldName("avgvals"); + + result = cavg.Execute( dataSet, dataSet.GetField("pointvar")); + + vtkm::cont::Field resultField = result.GetField(); + vtkm::cont::ArrayHandle resultArrayHandle; + resultField.GetData().CopyTo(resultArrayHandle); + + if(result.IsValid()) + { + vtkm::Float32 expected[2] = { 30.1f, 40.1f }; + for (int i = 0; i < 2; ++i) + { + VTKM_TEST_ASSERT(test_equal(resultArrayHandle.GetPortalConstControl().Get(i), + expected[i]), "Wrong result for CellAverage worklet on 2D regular data"); + } + } +} + +void TestCellAverageExplicit() +{ + std::cout << "Testing CellAverage Filter on Explicit data" << std::endl; + + vtkm::cont::testing::MakeTestDataSet testDataSet; + vtkm::cont::DataSet dataSet = testDataSet.Make3DExplicitDataSet0(); + + vtkm::filter::FieldResult result; + vtkm::filter::CellAverage cavg; + cavg.SetOutputFieldName("avgvals"); + + result = cavg.Execute( dataSet, dataSet.GetField("pointvar")); + + vtkm::cont::ArrayHandle resultArrayHandle; + const bool valid = result.FieldAs(resultArrayHandle); + + if(valid) + { + vtkm::Float32 expected[2] = { 20.1333f, 35.2f }; + for (int i = 0; i < 2; ++i) + { + VTKM_TEST_ASSERT(test_equal(resultArrayHandle.GetPortalConstControl().Get(i), + expected[i]), "Wrong result for CellAverage worklet on 3D regular data"); + } + } +} + + +void TestCellAverage() +{ + TestCellAverageRegular2D(); + TestCellAverageRegular3D(); + TestCellAverageExplicit(); +} + +} + +int UnitTestCellAverageFilter(int, char *[]) +{ + return vtkm::cont::testing::Testing::Run(TestCellAverage); +} diff --git a/vtkm/filter/testing/UnitTestExternalFacesFilter.cxx b/vtkm/filter/testing/UnitTestExternalFacesFilter.cxx new file mode 100644 index 000000000..95c6796a0 --- /dev/null +++ b/vtkm/filter/testing/UnitTestExternalFacesFilter.cxx @@ -0,0 +1,104 @@ +//============================================================================ +// 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 2014 Sandia Corporation. +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2014 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// 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 +#include + +#include + +using vtkm::cont::testing::MakeTestDataSet; + +namespace { +void TestExternalFacesExplicitGrid() +{ + vtkm::cont::DataSet ds; + + const int nVerts = 8; //A cube that is tetrahedralized + typedef vtkm::Vec CoordType; + CoordType coordinates[nVerts] = { + CoordType(0, 0, 0), + CoordType(1, 0, 0), + CoordType(1, 1, 0), + CoordType(0, 1, 0), + CoordType(0, 0, 1), + CoordType(1, 0, 1), + CoordType(1, 1, 1), + CoordType(0, 1, 1) + }; + + ds.AddCoordinateSystem( + vtkm::cont::CoordinateSystem("coordinates", 1, coordinates, nVerts)); + + //Construct the VTK-m shapes and numIndices connectivity arrays + const int nCells = 6; //The tetrahedrons of the cube + vtkm::IdComponent cellVerts[nCells][4] = { + {4,7,6,3}, {4,6,3,2}, {4,0,3,2}, + {4,6,5,2}, {4,5,0,2}, {1,0,5,2} + }; + vtkm::cont::CellSetExplicit<> cs(nVerts, "cells", nCells); + + vtkm::cont::ArrayHandle shapes; + vtkm::cont::ArrayHandle numIndices; + vtkm::cont::ArrayHandle conn; + shapes.Allocate(static_cast(nCells)); + numIndices.Allocate(static_cast(nCells)); + conn.Allocate(static_cast(4 * nCells)); + + int index = 0; + for(int j = 0; j < nCells; j++) + { + shapes.GetPortalControl().Set(j, static_cast(vtkm::CELL_SHAPE_TETRA)); + numIndices.GetPortalControl().Set(j, 4); + for(int k = 0; k < 4; k++) + conn.GetPortalControl().Set(index++, cellVerts[j][k]); + } + + cs.Fill(shapes, numIndices, conn); + + //Add the VTK-m cell set + ds.AddCellSet(cs); + + //Run the External Faces filter + vtkm::filter::ExternalFaces externalFaces; + vtkm::filter::DataSetResult result = externalFaces.Execute(ds); + + //Validate the number of external faces (output) returned by the worklet + VTKM_TEST_ASSERT(result.IsValid(), "Results should be valid"); + + vtkm::cont::CellSetExplicit<> &new_cs = + result.GetDataSet().GetCellSet(0).Cast >(); + + const vtkm::Id numExtFaces_out = new_cs.GetNumberOfCells(); + const vtkm::Id numExtFaces_actual = 12; + VTKM_TEST_ASSERT(numExtFaces_out == numExtFaces_actual, "Number of External Faces mismatch"); +} + +void TestExternalFacesFilter() +{ + TestExternalFacesExplicitGrid(); +} + +} // anonymous namespace + + +int UnitTestExternalFacesFilter(int, char *[]) +{ + return vtkm::cont::testing::Testing::Run(TestExternalFacesFilter); +} \ No newline at end of file diff --git a/vtkm/filter/testing/UnitTestFieldMetadata.cxx b/vtkm/filter/testing/UnitTestFieldMetadata.cxx new file mode 100644 index 000000000..3cb393482 --- /dev/null +++ b/vtkm/filter/testing/UnitTestFieldMetadata.cxx @@ -0,0 +1,92 @@ +//============================================================================ +// 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 2014 Sandia Corporation. +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2014 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// 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 +#include +#include + +namespace { + +vtkm::cont::Field makeCellField() +{ + return vtkm::cont::Field("foo", 1, vtkm::cont::Field::ASSOC_CELL_SET, + std::string(), vtkm::cont::ArrayHandle() ); +} +vtkm::cont::Field makePointField() +{ + return vtkm::cont::Field("foo", 1, vtkm::cont::Field::ASSOC_POINTS, + vtkm::cont::ArrayHandle() ); +} + +void TestFieldTypesUnknown() +{ + vtkm::filter::FieldMetadata defaultMD; + VTKM_TEST_ASSERT(defaultMD.IsPointField() == false, "default is not point or cell"); + VTKM_TEST_ASSERT(defaultMD.IsCellField() == false, "default is not point or cell"); + + //verify the field helper works properly + vtkm::cont::Field field1; + vtkm::filter::FieldMetadata makeMDFromField(field1); + VTKM_TEST_ASSERT(makeMDFromField.IsPointField() == false, "makeMDFromField is not point or cell"); + VTKM_TEST_ASSERT(makeMDFromField.IsCellField() == false, "makeMDFromField is not point or cell"); +} + +void TestFieldTypesPoint() +{ + vtkm::filter::FieldMetadata helperMD(makePointField()); + VTKM_TEST_ASSERT(helperMD.IsPointField() == true, "point should be a point field"); + VTKM_TEST_ASSERT(helperMD.IsCellField() == false, "point can't be a cell field"); + + //verify the field helper works properly + vtkm::Float32 vars[6] = {10.1f, 20.1f, 30.1f, 40.1f, 50.1f, 60.1f}; + vtkm::cont::Field field("pointvar", 1, vtkm::cont::Field::ASSOC_POINTS, vars, 6); + vtkm::filter::FieldMetadata makeMDFromField(field); + VTKM_TEST_ASSERT(makeMDFromField.IsPointField() == true, "point should be a point field"); + VTKM_TEST_ASSERT(makeMDFromField.IsCellField() == false, "point can't be a cell field"); +} + +void TestFieldTypesCell() +{ + vtkm::filter::FieldMetadata defaultMD; + vtkm::filter::FieldMetadata helperMD(makeCellField()); + VTKM_TEST_ASSERT(helperMD.IsPointField() == false, "cell can't be a point field"); + VTKM_TEST_ASSERT(helperMD.IsCellField() == true, "cell should be a cell field"); + + //verify the field helper works properly + vtkm::Float32 vars[6] = {10.1f, 20.1f, 30.1f, 40.1f, 50.1f, 60.1f}; + vtkm::cont::Field field("pointvar", 1, vtkm::cont::Field::ASSOC_CELL_SET, std::string(), vars, 6); + vtkm::filter::FieldMetadata makeMDFromField(field); + VTKM_TEST_ASSERT(makeMDFromField.IsPointField() == false, "cell can't be a point field"); + VTKM_TEST_ASSERT(makeMDFromField.IsCellField() == true, "cell should be a cell field"); +} + +void TestFieldMetadata() +{ + TestFieldTypesUnknown(); + TestFieldTypesPoint(); + TestFieldTypesCell(); +} + +} + +int UnitTestFieldMetadata(int, char *[]) +{ + return vtkm::cont::testing::Testing::Run(TestFieldMetadata); +} diff --git a/vtkm/filter/testing/UnitTestMarchingCubesFilter.cxx b/vtkm/filter/testing/UnitTestMarchingCubesFilter.cxx new file mode 100644 index 000000000..2f8e538bb --- /dev/null +++ b/vtkm/filter/testing/UnitTestMarchingCubesFilter.cxx @@ -0,0 +1,366 @@ +//============================================================================ +// 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 2014 Sandia Corporation. +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2014 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// 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 +#include +#include +#include +#include +#include + +#include + +namespace { + +class TangleField : public vtkm::worklet::WorkletMapField +{ +public: + typedef void ControlSignature(FieldIn vertexId, FieldOut v); + typedef void ExecutionSignature(_1, _2); + typedef _1 InputDomain; + + const vtkm::Id xdim, ydim, zdim; + const vtkm::FloatDefault xmin, ymin, zmin, xmax, ymax, zmax; + const vtkm::Id cellsPerLayer; + + VTKM_CONT_EXPORT + TangleField(const vtkm::Id3 dims, const vtkm::FloatDefault mins[3], const vtkm::FloatDefault maxs[3]) : xdim(dims[0]), ydim(dims[1]), zdim(dims[2]), + xmin(mins[0]), ymin(mins[1]), zmin(mins[2]), xmax(maxs[0]), ymax(maxs[1]), zmax(maxs[2]), cellsPerLayer((xdim) * (ydim)) { } + + VTKM_EXEC_EXPORT + void operator()(const vtkm::Id &vertexId, vtkm::Float32 &v) const + { + const vtkm::Id x = vertexId % (xdim); + const vtkm::Id y = (vertexId / (xdim)) % (ydim); + const vtkm::Id z = vertexId / cellsPerLayer; + + const vtkm::FloatDefault fx = static_cast(x) / static_cast(xdim-1); + const vtkm::FloatDefault fy = static_cast(y) / static_cast(xdim-1); + const vtkm::FloatDefault fz = static_cast(z) / static_cast(xdim-1); + + const vtkm::Float32 xx = 3.0f*vtkm::Float32(xmin+(xmax-xmin)*(fx)); + const vtkm::Float32 yy = 3.0f*vtkm::Float32(ymin+(ymax-ymin)*(fy)); + const vtkm::Float32 zz = 3.0f*vtkm::Float32(zmin+(zmax-zmin)*(fz)); + + v = (xx*xx*xx*xx - 5.0f*xx*xx + yy*yy*yy*yy - 5.0f*yy*yy + zz*zz*zz*zz - 5.0f*zz*zz + 11.8f) * 0.2f + 0.5f; + } +}; + +vtkm::cont::DataSet MakeIsosurfaceTestDataSet(vtkm::Id3 dims) +{ + vtkm::cont::DataSet dataSet; + + const vtkm::Id3 vdims(dims[0] + 1, dims[1] + 1, dims[2] + 1); + + vtkm::FloatDefault mins[3] = {-1.0f, -1.0f, -1.0f}; + vtkm::FloatDefault maxs[3] = {1.0f, 1.0f, 1.0f}; + + vtkm::cont::ArrayHandle fieldArray; + vtkm::cont::ArrayHandleIndex vertexCountImplicitArray(vdims[0]*vdims[1]*vdims[2]); + vtkm::worklet::DispatcherMapField tangleFieldDispatcher(TangleField(vdims, mins, maxs)); + tangleFieldDispatcher.Invoke(vertexCountImplicitArray, fieldArray); + + vtkm::Vec origin(0.0f, 0.0f, 0.0f); + vtkm::Vec spacing( + 1.0f/static_cast(dims[0]), + 1.0f/static_cast(dims[2]), + 1.0f/static_cast(dims[1])); + + vtkm::cont::ArrayHandleUniformPointCoordinates + coordinates(vdims, origin, spacing); + dataSet.AddCoordinateSystem( + vtkm::cont::CoordinateSystem("coordinates", 1, coordinates)); + + dataSet.AddField(vtkm::cont::Field("nodevar", 1, vtkm::cont::Field::ASSOC_POINTS, fieldArray)); + + static const vtkm::IdComponent ndim = 3; + vtkm::cont::CellSetStructured cellSet("cells"); + cellSet.SetPointDimensions(vdims); + dataSet.AddCellSet(cellSet); + + return dataSet; +} + +class EuclideanNorm +{ +public: + VTKM_EXEC_CONT_EXPORT + EuclideanNorm() : Reference(0.,0.,0.) {} + VTKM_EXEC_CONT_EXPORT + EuclideanNorm(vtkm::Vec reference):Reference(reference) {} + + VTKM_EXEC_CONT_EXPORT + vtkm::Float32 operator()(vtkm::Vec v) const + { + vtkm::Vec d(v[0]-this->Reference[0], + v[1]-this->Reference[1], + v[2]-this->Reference[2]); + return vtkm::Magnitude(d); + } + +private: + vtkm::Vec Reference; +}; + +class CubeGridConnectivity +{ +public: + VTKM_EXEC_CONT_EXPORT + CubeGridConnectivity() : Dimension(1), + DimSquared(1), + DimPlus1Squared(4) {} + VTKM_EXEC_CONT_EXPORT + CubeGridConnectivity(vtkm::Id dim) : Dimension(dim), + DimSquared(dim*dim), + DimPlus1Squared((dim+1)*(dim+1)) {} + + VTKM_EXEC_CONT_EXPORT + vtkm::Id operator()(vtkm::Id vertex) const + { + typedef vtkm::CellShapeTagHexahedron HexTag; + typedef vtkm::CellTraits HexTraits; + + vtkm::Id cellId = vertex/HexTraits::NUM_POINTS; + vtkm::Id localId = vertex%HexTraits::NUM_POINTS; + vtkm::Id globalId = + (cellId + cellId/this->Dimension + + (this->Dimension+1)*(cellId/(this->DimSquared))); + + switch (localId) + { + case 2: globalId += 1; + case 3: globalId += this->Dimension; + case 1: globalId += 1; + case 0: break; + case 6: globalId += 1; + case 7: globalId += this->Dimension; + case 5: globalId += 1; + case 4: globalId += this->DimPlus1Squared; break; + } + + return globalId; + } + +private: + vtkm::Id Dimension; + vtkm::Id DimSquared; + vtkm::Id DimPlus1Squared; +}; + +class MakeRadiantDataSet +{ +public: + typedef vtkm::cont::ArrayHandleUniformPointCoordinates CoordinateArrayHandle; + typedef vtkm::cont::ArrayHandleTransform DataArrayHandle; + typedef vtkm::cont::ArrayHandleTransform, + CubeGridConnectivity> ConnectivityArrayHandle; + + typedef vtkm::cont::CellSetSingleType< + vtkm::cont::ArrayHandleTransform, + CubeGridConnectivity>::StorageTag> CellSet; + + vtkm::cont::DataSet Make3DRadiantDataSet(vtkm::IdComponent dim=5); +}; + +class RadiantDataSetPolicy : public vtkm::filter::PolicyBase< RadiantDataSetPolicy > +{ + typedef MakeRadiantDataSet::DataArrayHandle DataHandleType; + typedef MakeRadiantDataSet::ConnectivityArrayHandle CountingHandleType; + + typedef vtkm::cont::ArrayHandleTransform,CubeGridConnectivity + > TransformHandleType; + + +public: + struct TypeListTagRadiantTypes : vtkm::ListTagBase< + DataHandleType::StorageTag, + CountingHandleType::StorageTag, + TransformHandleType::StorageTag> {}; + + typedef TypeListTagRadiantTypes FieldStorageList; + typedef vtkm::filter::DefaultPolicy::FieldTypeList FieldTypeList; + + struct TypeListTagRadiantCellSetTypes : vtkm::ListTagBase< + MakeRadiantDataSet::CellSet > {}; + + typedef TypeListTagRadiantCellSetTypes CellSetList; + + typedef vtkm::filter::DefaultPolicy::CoordinateTypeList CoordinateTypeList; + typedef vtkm::filter::DefaultPolicy::CoordinateStorageList CoordinateStorageList; +}; + +inline vtkm::cont::DataSet MakeRadiantDataSet::Make3DRadiantDataSet(vtkm::IdComponent dim) +{ + // create a cube from -.5 to .5 in x,y,z, consisting of cells on each + // axis, with point values equal to the Euclidean distance from the origin. + + vtkm::cont::DataSet dataSet; + + typedef vtkm::CellShapeTagHexahedron HexTag; + typedef vtkm::CellTraits HexTraits; + + typedef vtkm::Vec CoordType; + + const vtkm::IdComponent nCells = dim*dim*dim; + +vtkm::Float32 spacing = vtkm::Float32(1./dim); + CoordinateArrayHandle coordinates(vtkm::Id3(dim+1,dim+1,dim+1), + CoordType(-.5,-.5,-.5), + CoordType(spacing,spacing,spacing)); + + DataArrayHandle distanceToOrigin(coordinates); + DataArrayHandle distanceToOther(coordinates, + EuclideanNorm(CoordType(1.,1.,1.))); + + ConnectivityArrayHandle connectivity( + vtkm::cont::ArrayHandleCounting(0,1,nCells*HexTraits::NUM_POINTS), + CubeGridConnectivity(dim)); + + dataSet.AddCoordinateSystem( + vtkm::cont::CoordinateSystem("coordinates", 1, coordinates)); + + //Set point scalar + dataSet.AddField( + vtkm::cont::Field("distanceToOrigin", 1,vtkm::cont::Field::ASSOC_POINTS, + vtkm::cont::DynamicArrayHandle(distanceToOrigin))); + dataSet.AddField( + vtkm::cont::Field("distanceToOther", 1,vtkm::cont::Field::ASSOC_POINTS, + vtkm::cont::DynamicArrayHandle(distanceToOther))); + + CellSet cellSet(HexTag(), "cells"); + cellSet.Fill(connectivity); + + dataSet.AddCellSet(cellSet); + + return dataSet; +} + +void TestMarchingCubesUniformGrid() +{ + std::cout << "Testing MarchingCubes filter on a uniform grid" << std::endl; + + vtkm::Id3 dims(4,4,4); + vtkm::cont::DataSet dataSet = MakeIsosurfaceTestDataSet(dims); + + vtkm::filter::DataSetResult result; + vtkm::filter::MarchingCubes mc; + + mc.SetGenerateNormals(true); + mc.SetIsoValue( 0.5 ); + + result = mc.Execute( dataSet, + dataSet.GetField("nodevar") ); + + vtkm::cont::DataSet& outputData = result.GetDataSet(); + VTKM_TEST_ASSERT(outputData.GetNumberOfCellSets() == 1, + "Wrong number of cellsets in the output dataset"); + VTKM_TEST_ASSERT(outputData.GetNumberOfCoordinateSystems() == 1, + "Wrong number of coordinate systems in the output dataset"); + //since normals is on we have one field + VTKM_TEST_ASSERT(outputData.GetNumberOfFields() == 1, + "Wrong number of fields in the output dataset"); + + //Map a field onto the resulting dataset + const bool isMapped = mc.MapFieldOntoOutput(result, dataSet.GetField("nodevar")); + VTKM_TEST_ASSERT( isMapped, "mapping should pass" ); + + VTKM_TEST_ASSERT(outputData.GetNumberOfFields() == 2, + "Wrong number of fields in the output dataset"); + + //verify that the number of cells is correct + //verify that the number of points is correct + + //should have 480 coordinates + //should have 160 cells +} + +void TestMarchingCubesCustomPolicy() +{ + std::cout << "Testing MarchingCubes filter with custom field and cellset" << std::endl; + + typedef MakeRadiantDataSet DataSetGenerator; + DataSetGenerator dataSetGenerator; + + const vtkm::IdComponent Dimension = 10; + vtkm::cont::DataSet dataSet = + dataSetGenerator.Make3DRadiantDataSet(Dimension); + + vtkm::cont::Field contourField = dataSet.GetField("distanceToOrigin"); + + vtkm::filter::DataSetResult result; + vtkm::filter::MarchingCubes mc; + + mc.SetGenerateNormals( false ); + mc.SetIsoValue( 0.45 ); + + //We specify a custom execution policy here, since the contourField is a + //custom field type + result = mc.Execute( dataSet, contourField, RadiantDataSetPolicy() ); + + //Map a field onto the resulting dataset + vtkm::cont::Field projectedField = dataSet.GetField("distanceToOther"); + + mc.MapFieldOntoOutput(result, projectedField, RadiantDataSetPolicy()); + mc.MapFieldOntoOutput(result, contourField, RadiantDataSetPolicy()); + + vtkm::cont::DataSet& outputData = result.GetDataSet(); + VTKM_TEST_ASSERT(outputData.GetNumberOfCellSets() == 1, + "Wrong number of cellsets in the output dataset"); + VTKM_TEST_ASSERT(outputData.GetNumberOfCoordinateSystems() == 1, + "Wrong number of coordinate systems in the output dataset"); + VTKM_TEST_ASSERT(outputData.GetNumberOfFields() == 2, + "Wrong number of fields in the output dataset"); + + + //data arrays + // VTKM_TEST_ASSERT(test_equal(vertices.GetNumberOfValues(), 2472), + // "Wrong vertices result for MarchingCubes filter"); + // VTKM_TEST_ASSERT(test_equal(normals.GetNumberOfValues(), 2472), + // "Wrong normals result for MarchingCubes filter"); + // VTKM_TEST_ASSERT(test_equal(scalars.GetNumberOfValues(), 2472), + // "Wrong scalars result for MarchingCubes filter"); +} + + +void TestMarchingCubesNonDefaultCoordinates() +{ + +} + + +void TestMarchingCubesFilter() +{ + TestMarchingCubesUniformGrid(); + TestMarchingCubesCustomPolicy(); + TestMarchingCubesNonDefaultCoordinates(); +} + +} // anonymous namespace + + +int UnitTestMarchingCubesFilter(int, char *[]) +{ + return vtkm::cont::testing::Testing::Run(TestMarchingCubesFilter); +} diff --git a/vtkm/filter/testing/UnitTestPointElevationFilter.cxx b/vtkm/filter/testing/UnitTestPointElevationFilter.cxx new file mode 100644 index 000000000..d98128be0 --- /dev/null +++ b/vtkm/filter/testing/UnitTestPointElevationFilter.cxx @@ -0,0 +1,158 @@ +//============================================================================ +// 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 2014 Sandia Corporation. +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2014 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// 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 +#include + +#include + +namespace { + +vtkm::cont::DataSet MakePointElevationTestDataSet() +{ + vtkm::cont::DataSet dataSet; + + std::vector > coordinates; + const vtkm::Id dim = 5; + for (vtkm::Id j = 0; j < dim; ++j) + { + vtkm::Float32 z = static_cast(j) / + static_cast(dim - 1); + for (vtkm::Id i = 0; i < dim; ++i) + { + vtkm::Float32 x = static_cast(i) / + static_cast(dim - 1); + vtkm::Float32 y = (x*x + z*z)/2.0f; + coordinates.push_back(vtkm::make_Vec(x,y,z)); + } + } + + vtkm::Id numCells = (dim - 1) * (dim - 1); + dataSet.AddCoordinateSystem( + vtkm::cont::CoordinateSystem("coordinates", 1, coordinates)); + + vtkm::cont::CellSetExplicit<> cellSet(vtkm::Id(coordinates.size()), "cells", 3); + cellSet.PrepareToAddCells(numCells, numCells * 4); + for (vtkm::Id j = 0; j < dim - 1; ++j) + { + for (vtkm::Id i = 0; i < dim - 1; ++i) + { + cellSet.AddCell(vtkm::CELL_SHAPE_QUAD, + 4, + vtkm::make_Vec(j * dim + i, + j * dim + i + 1, + (j + 1) * dim + i + 1, + (j + 1) * dim + i)); + } + } + cellSet.CompleteAddingCells(); + + dataSet.AddCellSet(cellSet); + return dataSet; +} + +} + +void TestPointElevationNoPolicy() +{ + std::cout << "Testing PointElevation Filter With No Policy" << std::endl; + + vtkm::cont::DataSet inputData = MakePointElevationTestDataSet(); + + vtkm::filter::PointElevation filter; + filter.SetLowPoint( 0.0, 0.0, 0.0 ); + filter.SetHighPoint( 0.0, 1.0, 0.0 ); + filter.SetRange( 0.0, 2.0 ); + + filter.SetOutputFieldName("elevation"); + vtkm::filter::FieldResult result; + result = filter.Execute(inputData, + inputData.GetCoordinateSystem()); + + //verify the result + VTKM_TEST_ASSERT( result.IsValid(), "result should be valid" ); + + vtkm::cont::ArrayHandle resultArrayHandle; + const bool valid = result.FieldAs(resultArrayHandle); + if(valid) + { + vtkm::cont::ArrayHandle > coordinates; + inputData.GetCoordinateSystem().GetData().CopyTo(coordinates); + + for (vtkm::Id i = 0; i < resultArrayHandle.GetNumberOfValues(); ++i) + { + VTKM_TEST_ASSERT(test_equal(coordinates.GetPortalConstControl().Get(i)[1] * 2.0, + resultArrayHandle.GetPortalConstControl().Get(i)), + "Wrong result for PointElevation worklet"); + } + } +} + +void TestPointElevationWithPolicy() +{ + + //simple test + std::cout << "Testing PointElevation Filter With Explicit Policy" << std::endl; + + vtkm::cont::DataSet inputData = MakePointElevationTestDataSet(); + + vtkm::filter::PointElevation filter; + filter.SetLowPoint( 0.0, 0.0, 0.0 ); + filter.SetHighPoint( 0.0, 1.0, 0.0 ); + filter.SetRange( 0.0, 2.0 ); + + filter.SetOutputFieldName("elevation"); + vtkm::filter::FieldResult result; + + vtkm::filter::DefaultPolicy p; + result = filter.Execute(inputData, + inputData.GetCoordinateSystem(), + p); + + //verify the result + VTKM_TEST_ASSERT( result.IsValid(), "result should be valid" ); + + vtkm::cont::ArrayHandle resultArrayHandle; + const bool valid = result.FieldAs(resultArrayHandle, p); + if(valid) + { + vtkm::cont::ArrayHandle > coordinates; + inputData.GetCoordinateSystem().GetData().CopyTo(coordinates); + + for (vtkm::Id i = 0; i < resultArrayHandle.GetNumberOfValues(); ++i) + { + VTKM_TEST_ASSERT(test_equal(coordinates.GetPortalConstControl().Get(i)[1] * 2.0, + resultArrayHandle.GetPortalConstControl().Get(i)), + "Wrong result for PointElevation worklet"); + } + } + +} + +void TestPointElevation() +{ + TestPointElevationNoPolicy(); + TestPointElevationWithPolicy(); +} + +int UnitTestPointElevationFilter(int, char *[]) +{ + return vtkm::cont::testing::Testing::Run(TestPointElevation); +} diff --git a/vtkm/filter/testing/UnitTestThresholdFilter.cxx b/vtkm/filter/testing/UnitTestThresholdFilter.cxx new file mode 100644 index 000000000..bba9e3ce0 --- /dev/null +++ b/vtkm/filter/testing/UnitTestThresholdFilter.cxx @@ -0,0 +1,167 @@ +//============================================================================ +// 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 2014 Sandia Corporation. +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2014 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// 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 +#include + +#include + +using vtkm::cont::testing::MakeTestDataSet; + +namespace { + + +class TestingThreshold +{ +public: + void TestRegular2D() const + { + std::cout << "Testing threshold on 2D regular dataset" << std::endl; + + vtkm::cont::DataSet dataset = MakeTestDataSet().Make2DUniformDataSet0(); + + vtkm::filter::Threshold threshold; + vtkm::filter::DataSetResult result; + + threshold.SetThresholdValue(60.1); + result = threshold.Execute(dataset, dataset.GetField("pointvar")); + + threshold.MapFieldOntoOutput(result, dataset.GetField("cellvar") ); + + vtkm::cont::DataSet output = result.GetDataSet(); + VTKM_TEST_ASSERT(output.GetNumberOfFields() == 1, + "Wrong number of fields in the output dataset"); + + typedef vtkm::cont::ArrayHandlePermutation< + vtkm::cont::ArrayHandle, + vtkm::cont::ArrayHandle > OutCellFieldArrayHandleType; + + OutCellFieldArrayHandleType cellFieldArray; + output.GetField("cellvar").GetData().CopyTo(cellFieldArray); + + VTKM_TEST_ASSERT(cellFieldArray.GetNumberOfValues() == 1 && + cellFieldArray.GetPortalConstControl().Get(0) == 200.1f, + "Wrong cell field data"); + } + + void TestRegular3D() const + { + std::cout << "Testing threshold on 3D regular dataset" << std::endl; + vtkm::cont::DataSet dataset = MakeTestDataSet().Make3DUniformDataSet0(); + + vtkm::filter::Threshold threshold; + vtkm::filter::DataSetResult result; + + threshold.SetThresholdValue(20.1); + result = threshold.Execute(dataset, std::string("pointvar")); + + threshold.MapFieldOntoOutput(result, dataset.GetField("cellvar") ); + + vtkm::cont::DataSet output = result.GetDataSet(); + VTKM_TEST_ASSERT(output.GetNumberOfFields() == 1, + "Wrong number of fields in the output dataset"); + + typedef vtkm::cont::ArrayHandlePermutation< + vtkm::cont::ArrayHandle, + vtkm::cont::ArrayHandle > OutCellFieldArrayHandleType; + + OutCellFieldArrayHandleType cellFieldArray; + output.GetField("cellvar").GetData().CopyTo(cellFieldArray); + + VTKM_TEST_ASSERT(cellFieldArray.GetNumberOfValues() == 2 && + cellFieldArray.GetPortalConstControl().Get(0) == 100.1f && + cellFieldArray.GetPortalConstControl().Get(1) == 100.2f, + "Wrong cell field data"); + } + + void TestExplicit3D() const + { + std::cout << "Testing threshold on 3D explicit dataset" << std::endl; + vtkm::cont::DataSet dataset = MakeTestDataSet().Make3DExplicitDataSet1(); + + vtkm::filter::Threshold threshold; + vtkm::filter::DataSetResult result; + + threshold.SetThresholdValue(20.1); + result = threshold.Execute(dataset, std::string("pointvar")); + + threshold.MapFieldOntoOutput(result, dataset.GetField("cellvar") ); + + vtkm::cont::DataSet output = result.GetDataSet(); + VTKM_TEST_ASSERT(output.GetNumberOfFields() == 1, + "Wrong number of fields in the output dataset"); + + typedef vtkm::cont::ArrayHandlePermutation< + vtkm::cont::ArrayHandle, + vtkm::cont::ArrayHandle > OutCellFieldArrayHandleType; + + OutCellFieldArrayHandleType cellFieldArray; + output.GetField("cellvar").GetData().CopyTo(cellFieldArray); + + VTKM_TEST_ASSERT(cellFieldArray.GetNumberOfValues() == 2 && + cellFieldArray.GetPortalConstControl().Get(0) == 100.1f && + cellFieldArray.GetPortalConstControl().Get(1) == 100.2f, + "Wrong cell field data"); + } + + void TestExplicit3DZeroResults() const + { + std::cout << "Testing threshold on 3D explicit dataset with empty results" << std::endl; + vtkm::cont::DataSet dataset = MakeTestDataSet().Make3DExplicitDataSet1(); + + vtkm::filter::Threshold threshold; + vtkm::filter::DataSetResult result; + + threshold.SetThresholdValue(500.1); + result = threshold.Execute(dataset, std::string("pointvar")); + + VTKM_TEST_ASSERT(result.IsValid(), "threshold algorithm should return true"); + + threshold.MapFieldOntoOutput(result, dataset.GetField("cellvar") ); + + vtkm::cont::DataSet output = result.GetDataSet(); + VTKM_TEST_ASSERT(output.GetNumberOfFields() == 1, + "Wrong number of fields in the output dataset"); + + typedef vtkm::cont::ArrayHandlePermutation< + vtkm::cont::ArrayHandle, + vtkm::cont::ArrayHandle > OutCellFieldArrayHandleType; + + OutCellFieldArrayHandleType cellFieldArray; + output.GetField("cellvar").GetData().CopyTo(cellFieldArray); + + VTKM_TEST_ASSERT(cellFieldArray.GetNumberOfValues() == 0, "field should be empty"); + } + + void operator()() const + { + this->TestRegular2D(); + this->TestRegular3D(); + this->TestExplicit3D(); + this->TestExplicit3DZeroResults(); + } +}; + +} + +int UnitTestThresholdFilter(int, char *[]) +{ + return vtkm::cont::testing::Testing::Run(TestingThreshold()); +} \ No newline at end of file diff --git a/vtkm/filter/testing/UnitTestVertexClusteringFilter.cxx b/vtkm/filter/testing/UnitTestVertexClusteringFilter.cxx new file mode 100644 index 000000000..4b4255529 --- /dev/null +++ b/vtkm/filter/testing/UnitTestVertexClusteringFilter.cxx @@ -0,0 +1,75 @@ +//============================================================================ +// 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 2014 Sandia Corporation. +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2014 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// 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 +#include + +#include + +using vtkm::cont::testing::MakeTestDataSet; + +namespace { +} + +void TestVertexClustering() +{ + vtkm::cont::testing::MakeTestDataSet maker; + vtkm::cont::DataSet dataSet = maker.Make3DExplicitDataSetCowNose(); + + vtkm::filter::VertexClustering clustering; + vtkm::filter::DataSetResult result; + + clustering.SetNumberOfDivisions( vtkm::Id3(3, 3, 3) ); + result = clustering.Execute(dataSet); + + VTKM_TEST_ASSERT( result.IsValid(), "results should be valid"); + + vtkm::cont::DataSet output = result.GetDataSet(); + VTKM_TEST_ASSERT(output.GetNumberOfCoordinateSystems() == 1, + "Number of output coordinate systems mismatch"); + + + // test + const vtkm::Id output_pointIds = 9; + vtkm::Id output_pointId[output_pointIds] = {0,1,3, 1,5,4, 1,2,5}; + const vtkm::Id output_points = 6; + vtkm::Float64 output_point[output_points][3] = {{0.0174716003,0.0501927994,0.0930275023}, {0.0320714004,0.14704667,0.0952706337}, {0.0268670674,0.246195346,0.119720004}, {0.00215422804,0.0340906903,0.180881709}, {0.0108188,0.152774006,0.167914003}, {0.0202241503,0.225427493,0.140208006}}; + + typedef vtkm::Vec PointType; + vtkm::cont::ArrayHandle pointArray; + output.GetCoordinateSystem(0).GetData().CopyTo(pointArray); + VTKM_TEST_ASSERT(pointArray.GetNumberOfValues() == output_points, + "Number of output points mismatch" ); + for (vtkm::Id i = 0; i < pointArray.GetNumberOfValues(); ++i) + { + const PointType &p1 = pointArray.GetPortalConstControl().Get(i); + PointType p2 = vtkm::make_Vec(output_point[i][0], + output_point[i][1], + output_point[i][2]); + std::cout << "point: " << p1 << " " << p2 << std::endl; + VTKM_TEST_ASSERT(test_equal(p1, p2), "Point Array mismatch"); + } +} + +int UnitTestVertexClusteringFilter(int, char *[]) +{ + return vtkm::cont::testing::Testing::Run(TestVertexClustering); + +} \ No newline at end of file From 8e72ec8ea4755ab40fafabae030a9471de4a9aba Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Mon, 15 Feb 2016 11:49:48 -0500 Subject: [PATCH 06/12] Switch filter::threshold over to have a lower and upper bounds. --- vtkm/filter/Threshold.h | 11 +++++++--- vtkm/filter/Threshold.hxx | 22 ++++++++++++------- .../testing/UnitTestThresholdFilter.cxx | 12 ++++++---- 3 files changed, 30 insertions(+), 15 deletions(-) diff --git a/vtkm/filter/Threshold.h b/vtkm/filter/Threshold.h index 71aff41ed..4c4ecc418 100644 --- a/vtkm/filter/Threshold.h +++ b/vtkm/filter/Threshold.h @@ -34,10 +34,14 @@ public: Threshold(); VTKM_CONT_EXPORT - void SetThresholdValue(vtkm::Float64 value){ this->ThresholdValue = value; } + void SetLowerThreshold(vtkm::Float64 value){ this->LowerValue = value; } + VTKM_CONT_EXPORT + void SetUpperThreshold(vtkm::Float64 value){ this->UpperValue = value; } VTKM_CONT_EXPORT - vtkm::Float64 GetThresholdValue() const { return this->ThresholdValue; } + vtkm::Float64 GetLowerThreshold() const { return this->LowerValue; } + VTKM_CONT_EXPORT + vtkm::Float64 GetUpperThreshold() const { return this->UpperValue; } template VTKM_CONT_EXPORT @@ -59,7 +63,8 @@ public: private: - double ThresholdValue; + double LowerValue; + double UpperValue; vtkm::cont::ArrayHandle ValidCellIds; }; diff --git a/vtkm/filter/Threshold.hxx b/vtkm/filter/Threshold.hxx index d516d3b5b..45c4729c5 100644 --- a/vtkm/filter/Threshold.hxx +++ b/vtkm/filter/Threshold.hxx @@ -27,22 +27,27 @@ namespace { -class HasValue +class ThresholdRange { public: VTKM_CONT_EXPORT - HasValue(const vtkm::Float64& value) : Value(value) + ThresholdRange(const vtkm::Float64& lower, + const vtkm::Float64& upper) : + Lower(lower), + Upper(upper) { } template VTKM_EXEC_EXPORT bool operator()(const T& value) const { - return value == static_cast(this->Value); + return value >= static_cast(this->Lower) && + value <= static_cast(this->Upper); } private: - vtkm::Float64 Value; + vtkm::Float64 Lower; + vtkm::Float64 Upper; }; class AddPermutationCellSet @@ -79,7 +84,8 @@ namespace filter { //----------------------------------------------------------------------------- Threshold::Threshold(): vtkm::filter::DataSetWithFieldFilter(), - ThresholdValue(0), + LowerValue(0), + UpperValue(0), ValidCellIds() { @@ -100,12 +106,12 @@ vtkm::filter::DataSetResult Threshold::DoExecute(const vtkm::cont::DataSet& inpu const vtkm::cont::DynamicCellSet& cells = input.GetCellSet(this->GetActiveCellSetIndex()); - HasValue predicate( this->GetThresholdValue() ); + ThresholdRange predicate( this->GetLowerThreshold(), this->GetUpperThreshold() ); vtkm::cont::ArrayHandle passFlags; if(fieldMeta.IsPointField()) { typedef vtkm::worklet::Threshold Worklets; - typedef Worklets::ThresholdByPointField< HasValue > ThresholdWorklet; + typedef Worklets::ThresholdByPointField< ThresholdRange > ThresholdWorklet; ThresholdWorklet worklet(predicate); vtkm::worklet::DispatcherMapTopology dispatcher(worklet); dispatcher.Invoke(vtkm::filter::Convert(cells, policy), field, passFlags); @@ -113,7 +119,7 @@ vtkm::filter::DataSetResult Threshold::DoExecute(const vtkm::cont::DataSet& inpu else if(fieldMeta.IsCellField()) { typedef vtkm::worklet::Threshold Worklets; - typedef Worklets::ThresholdByCellField< HasValue > ThresholdWorklet; + typedef Worklets::ThresholdByCellField< ThresholdRange > ThresholdWorklet; ThresholdWorklet worklet(predicate); vtkm::worklet::DispatcherMapTopology dispatcher(worklet); dispatcher.Invoke(vtkm::filter::Convert(cells, policy), field, passFlags); diff --git a/vtkm/filter/testing/UnitTestThresholdFilter.cxx b/vtkm/filter/testing/UnitTestThresholdFilter.cxx index bba9e3ce0..50434a7f1 100644 --- a/vtkm/filter/testing/UnitTestThresholdFilter.cxx +++ b/vtkm/filter/testing/UnitTestThresholdFilter.cxx @@ -40,7 +40,8 @@ public: vtkm::filter::Threshold threshold; vtkm::filter::DataSetResult result; - threshold.SetThresholdValue(60.1); + threshold.SetLowerThreshold(60.1); + threshold.SetUpperThreshold(60.1); result = threshold.Execute(dataset, dataset.GetField("pointvar")); threshold.MapFieldOntoOutput(result, dataset.GetField("cellvar") ); @@ -69,7 +70,8 @@ public: vtkm::filter::Threshold threshold; vtkm::filter::DataSetResult result; - threshold.SetThresholdValue(20.1); + threshold.SetLowerThreshold(20.1); + threshold.SetUpperThreshold(20.1); result = threshold.Execute(dataset, std::string("pointvar")); threshold.MapFieldOntoOutput(result, dataset.GetField("cellvar") ); @@ -99,7 +101,8 @@ public: vtkm::filter::Threshold threshold; vtkm::filter::DataSetResult result; - threshold.SetThresholdValue(20.1); + threshold.SetLowerThreshold(20.1); + threshold.SetUpperThreshold(20.1); result = threshold.Execute(dataset, std::string("pointvar")); threshold.MapFieldOntoOutput(result, dataset.GetField("cellvar") ); @@ -129,7 +132,8 @@ public: vtkm::filter::Threshold threshold; vtkm::filter::DataSetResult result; - threshold.SetThresholdValue(500.1); + threshold.SetLowerThreshold(500.1); + threshold.SetUpperThreshold(500.1); result = threshold.Execute(dataset, std::string("pointvar")); VTKM_TEST_ASSERT(result.IsValid(), "threshold algorithm should return true"); From f699c986025d396fd163337609cc0fb0b091d15c Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Mon, 15 Feb 2016 11:38:51 -0500 Subject: [PATCH 07/12] Renamed the ```Convert``` method to ```ApplyPolicy``` The original name was a really bad name, so thank to Ken for suggesting a better name. --- vtkm/filter/DataSetFilter.hxx | 2 +- vtkm/filter/DataSetWithFieldFilter.hxx | 6 +++--- vtkm/filter/ExternalFaces.hxx | 2 +- vtkm/filter/FieldFilter.hxx | 4 ++-- vtkm/filter/MarchingCubes.hxx | 14 ++++++++------ vtkm/filter/PolicyBase.h | 24 ++++++++++++------------ vtkm/filter/Threshold.hxx | 6 +++--- vtkm/filter/VertexClustering.hxx | 4 ++-- 8 files changed, 32 insertions(+), 30 deletions(-) diff --git a/vtkm/filter/DataSetFilter.hxx b/vtkm/filter/DataSetFilter.hxx index 6cb12a070..7d0412e57 100644 --- a/vtkm/filter/DataSetFilter.hxx +++ b/vtkm/filter/DataSetFilter.hxx @@ -126,7 +126,7 @@ bool DataSetFilter::MapFieldOntoOutput(DataSetResult& result, valid); typedef vtkm::filter::FilterTraits< Derived > Traits; - vtkm::filter::Convert(field, policy, Traits()).CastAndCall(functor); + vtkm::filter::ApplyPolicy(field, policy, Traits()).CastAndCall(functor); } //the bool valid will be modified by the map algorithm to hold if the diff --git a/vtkm/filter/DataSetWithFieldFilter.hxx b/vtkm/filter/DataSetWithFieldFilter.hxx index 8911caa74..cabd0ea56 100644 --- a/vtkm/filter/DataSetWithFieldFilter.hxx +++ b/vtkm/filter/DataSetWithFieldFilter.hxx @@ -129,7 +129,7 @@ DataSetResult DataSetWithFieldFilter::PrepareForExecution(const vtkm::c result); typedef vtkm::filter::FilterTraits< Derived > Traits; - vtkm::filter::Convert(field, policy, Traits()).CastAndCall(functor); + vtkm::filter::ApplyPolicy(field, policy, Traits()).CastAndCall(functor); return result; } @@ -156,7 +156,7 @@ DataSetResult DataSetWithFieldFilter::PrepareForExecution(const vtkm::c result); typedef vtkm::filter::FilterTraits< Derived > Traits; - vtkm::filter::Convert(field, policy, Traits()).CastAndCall(functor); + vtkm::filter::ApplyPolicy(field, policy, Traits()).CastAndCall(functor); return result; } @@ -189,7 +189,7 @@ bool DataSetWithFieldFilter::MapFieldOntoOutput(DataSetResult& result, valid); typedef vtkm::filter::FilterTraits< Derived > Traits; - vtkm::filter::Convert(field, policy, Traits()).CastAndCall(functor); + vtkm::filter::ApplyPolicy(field, policy, Traits()).CastAndCall(functor); } //the bool valid will be modified by the map algorithm to hold if the diff --git a/vtkm/filter/ExternalFaces.hxx b/vtkm/filter/ExternalFaces.hxx index 7f799f3da..e8a61497d 100644 --- a/vtkm/filter/ExternalFaces.hxx +++ b/vtkm/filter/ExternalFaces.hxx @@ -105,7 +105,7 @@ vtkm::filter::DataSetResult ExternalFaces::DoExecute(const vtkm::cont::DataSet& vtkm::cont::DataSet output; bool workletRan = false; ExternalFacesWorkletWrapper wrapper(output, workletRan); - vtkm::filter::Convert(cells,policy).CastAndCall( wrapper ); + vtkm::filter::ApplyPolicy(cells,policy).CastAndCall( wrapper ); if(!workletRan) { diff --git a/vtkm/filter/FieldFilter.hxx b/vtkm/filter/FieldFilter.hxx index b532bf3a6..45997b8ed 100644 --- a/vtkm/filter/FieldFilter.hxx +++ b/vtkm/filter/FieldFilter.hxx @@ -147,7 +147,7 @@ FieldResult FieldFilter::PrepareForExecution(const vtkm::cont::DataSet result); typedef vtkm::filter::FilterTraits< Derived > Traits; - vtkm::filter::Convert(field, policy, Traits()).CastAndCall(functor); + vtkm::filter::ApplyPolicy(field, policy, Traits()).CastAndCall(functor); return result; } @@ -173,7 +173,7 @@ FieldResult FieldFilter::PrepareForExecution(const vtkm::cont::DataSet result); typedef vtkm::filter::FilterTraits< Derived > Traits; - vtkm::filter::Convert(field, policy, Traits()).CastAndCall(functor); + vtkm::filter::ApplyPolicy(field, policy, Traits()).CastAndCall(functor); return result; } diff --git a/vtkm/filter/MarchingCubes.hxx b/vtkm/filter/MarchingCubes.hxx index f40c6ec0d..c4bdcee2e 100644 --- a/vtkm/filter/MarchingCubes.hxx +++ b/vtkm/filter/MarchingCubes.hxx @@ -326,7 +326,7 @@ vtkm::filter::DataSetResult MarchingCubes::DoExecute(const vtkm::cont::DataSet& vtkm::cont::ArrayHandle numOutputTrisPerCell; classifyCellDispatcher.Invoke(field, - vtkm::filter::Convert(cells, policy), + vtkm::filter::ApplyPolicy(cells, policy), numOutputTrisPerCell, this->NumTrianglesTable); @@ -342,10 +342,10 @@ vtkm::filter::DataSetResult MarchingCubes::DoExecute(const vtkm::cont::DataSet& GenerateDispatcher edgeDispatcher(weightGenerate); edgeDispatcher.Invoke( - vtkm::filter::Convert(cells, policy), + vtkm::filter::ApplyPolicy(cells, policy), //cast to a scalar field if not one, as cellderivative only works on those make_ScalarField(field), - vtkm::filter::Convert(coords, policy), + vtkm::filter::ApplyPolicy(coords, policy), vtkm::cont::make_ArrayHandleGroupVec<3>(normals), vtkm::cont::make_ArrayHandleGroupVec<3>(this->InterpolationWeights), vtkm::cont::make_ArrayHandleGroupVec<3>(this->InterpolationIds), @@ -410,7 +410,8 @@ vtkm::filter::DataSetResult MarchingCubes::DoExecute(const vtkm::cont::DataSet& Algorithm::LowerBounds(unqiueIds, this->InterpolationIds, connectivity); - vtkm::cont::CellSetSingleType< > outputCells( (vtkm::CellShapeTagTriangle()) ); + CellShapeTagTriangle triangleTag; + vtkm::cont::CellSetSingleType< > outputCells( triangleTag ); outputCells.Fill( connectivity ); output.AddCellSet( outputCells ); } @@ -422,13 +423,14 @@ vtkm::filter::DataSetResult MarchingCubes::DoExecute(const vtkm::cont::DataSet& applyFieldDispatcher.Invoke(this->InterpolationIds, this->InterpolationWeights, - vtkm::filter::Convert(coords, policy), + vtkm::filter::ApplyPolicy(coords, policy), vertices); //when we don't merge points, the connectivity array can be represented //by a counting array typedef typename vtkm::cont::ArrayHandleIndex::StorageTag IndexStorageTag; - vtkm::cont::CellSetSingleType< IndexStorageTag > outputCells( (vtkm::CellShapeTagTriangle()) ); + CellShapeTagTriangle triangleTag; + vtkm::cont::CellSetSingleType< IndexStorageTag > outputCells( triangleTag ); vtkm::cont::ArrayHandleIndex connectivity(vertices.GetNumberOfValues()); outputCells.Fill( connectivity ); output.AddCellSet( outputCells ); diff --git a/vtkm/filter/PolicyBase.h b/vtkm/filter/PolicyBase.h index 1889ecdb5..ff803885c 100644 --- a/vtkm/filter/PolicyBase.h +++ b/vtkm/filter/PolicyBase.h @@ -45,8 +45,8 @@ vtkm::cont::DynamicArrayHandleBase< typename DerivedPolicy::FieldTypeList, typename DerivedPolicy::FieldStorageList > -Convert(const vtkm::cont::Field& field, - const vtkm::filter::PolicyBase&) +ApplyPolicy(const vtkm::cont::Field& field, + const vtkm::filter::PolicyBase&) { typedef typename DerivedPolicy::FieldTypeList TypeList; typedef typename DerivedPolicy::FieldStorageList StorageList; @@ -60,9 +60,9 @@ vtkm::cont::DynamicArrayHandleBase< typename vtkm::filter::FilterTraits::InputFieldTypeList, typename DerivedPolicy::FieldStorageList > -Convert(const vtkm::cont::Field& field, - const vtkm::filter::PolicyBase&, - const vtkm::filter::FilterTraits&) +ApplyPolicy(const vtkm::cont::Field& field, + const vtkm::filter::PolicyBase&, + const vtkm::filter::FilterTraits&) { //todo: we need to intersect the policy field type list and the //filter traits to the get smallest set of valid types @@ -79,8 +79,8 @@ vtkm::cont::DynamicArrayHandleBase< typename DerivedPolicy::CoordinateTypeList, typename DerivedPolicy::CoordinateStorageList > -Convert(const vtkm::cont::CoordinateSystem& coordinates, - const vtkm::filter::PolicyBase&) +ApplyPolicy(const vtkm::cont::CoordinateSystem& coordinates, + const vtkm::filter::PolicyBase&) { typedef typename DerivedPolicy::CoordinateTypeList TypeList; typedef typename DerivedPolicy::CoordinateStorageList StorageList; @@ -94,9 +94,9 @@ vtkm::cont::DynamicArrayHandleBase< typename vtkm::filter::FilterTraits::InputFieldTypeList, typename DerivedPolicy::CoordinateStorageList > -Convert(const vtkm::cont::CoordinateSystem& coordinates, - const vtkm::filter::PolicyBase&, - const vtkm::filter::FilterTraits&) +ApplyPolicy(const vtkm::cont::CoordinateSystem& coordinates, + const vtkm::filter::PolicyBase&, + const vtkm::filter::FilterTraits&) { //todo: we need to intersect the policy field type list and the //filter traits to the get smallest set of valid types @@ -110,8 +110,8 @@ Convert(const vtkm::cont::CoordinateSystem& coordinates, template VTKM_CONT_EXPORT vtkm::cont::DynamicCellSetBase< typename DerivedPolicy::CellSetList > -Convert(const vtkm::cont::DynamicCellSet& cellset, - const vtkm::filter::PolicyBase&) +ApplyPolicy(const vtkm::cont::DynamicCellSet& cellset, + const vtkm::filter::PolicyBase&) { typedef typename DerivedPolicy::CellSetList CellSetList; return cellset.ResetCellSetList(CellSetList()); diff --git a/vtkm/filter/Threshold.hxx b/vtkm/filter/Threshold.hxx index 45c4729c5..f14da34c6 100644 --- a/vtkm/filter/Threshold.hxx +++ b/vtkm/filter/Threshold.hxx @@ -114,7 +114,7 @@ vtkm::filter::DataSetResult Threshold::DoExecute(const vtkm::cont::DataSet& inpu typedef Worklets::ThresholdByPointField< ThresholdRange > ThresholdWorklet; ThresholdWorklet worklet(predicate); vtkm::worklet::DispatcherMapTopology dispatcher(worklet); - dispatcher.Invoke(vtkm::filter::Convert(cells, policy), field, passFlags); + dispatcher.Invoke(vtkm::filter::ApplyPolicy(cells, policy), field, passFlags); } else if(fieldMeta.IsCellField()) { @@ -122,7 +122,7 @@ vtkm::filter::DataSetResult Threshold::DoExecute(const vtkm::cont::DataSet& inpu typedef Worklets::ThresholdByCellField< ThresholdRange > ThresholdWorklet; ThresholdWorklet worklet(predicate); vtkm::worklet::DispatcherMapTopology dispatcher(worklet); - dispatcher.Invoke(vtkm::filter::Convert(cells, policy), field, passFlags); + dispatcher.Invoke(vtkm::filter::ApplyPolicy(cells, policy), field, passFlags); } else { @@ -145,7 +145,7 @@ vtkm::filter::DataSetResult Threshold::DoExecute(const vtkm::cont::DataSet& inpu //can use to reduce code duplication, and make it easier to write filters //that return complex dataset types. AddPermutationCellSet addCellSet(output, this->ValidCellIds); - vtkm::filter::Convert(cells, policy).CastAndCall(addCellSet); + vtkm::filter::ApplyPolicy(cells, policy).CastAndCall(addCellSet); //todo: We need to generate a new output policy that replaces //the original storage tag with a new storage tag where everything is diff --git a/vtkm/filter/VertexClustering.hxx b/vtkm/filter/VertexClustering.hxx index f6fef079a..dacb89ab9 100644 --- a/vtkm/filter/VertexClustering.hxx +++ b/vtkm/filter/VertexClustering.hxx @@ -62,8 +62,8 @@ vtkm::filter::DataSetResult VertexClustering::DoExecute(const vtkm::cont::DataSe vtkm::Float64 bounds[6]; compute_bounds(input.GetCoordinateSystem(), bounds, policy, tag); - vtkm::cont::DataSet outDataSet = clustering.Run(vtkm::filter::Convert(input.GetCellSet(), policy), - vtkm::filter::Convert(input.GetCoordinateSystem(), policy), + vtkm::cont::DataSet outDataSet = clustering.Run(vtkm::filter::ApplyPolicy(input.GetCellSet(), policy), + vtkm::filter::ApplyPolicy(input.GetCoordinateSystem(), policy), bounds, this->GetNumberOfDivisions(), tag); From c00fb53b54f40b6295a4aadf321a668012157ff7 Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Fri, 19 Feb 2016 16:51:22 -0500 Subject: [PATCH 08/12] Marching Cubes now generates vertices when merge duplicates is enabled. --- vtkm/filter/MarchingCubes.hxx | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/vtkm/filter/MarchingCubes.hxx b/vtkm/filter/MarchingCubes.hxx index c4bdcee2e..9b6f3bc43 100644 --- a/vtkm/filter/MarchingCubes.hxx +++ b/vtkm/filter/MarchingCubes.hxx @@ -64,6 +64,7 @@ int GetHexahedronClassification(const T& values, const U isoValue) (values[7] > isoValue) << 7); } +// ----------------------------------------------------------------------------- class ClassifyCell : public vtkm::worklet::WorkletMapPointToCell { public: @@ -101,6 +102,7 @@ public: /// \brief Compute the weights for each edge that is used to generate /// a point in the resulting iso-surface +// ----------------------------------------------------------------------------- class EdgeWeightGenerate : public vtkm::worklet::WorkletMapPointToCell { typedef vtkm::Vec< vtkm::Id2, 3 > Vec3Id2; @@ -222,7 +224,7 @@ private: ScatterType Scatter; }; - +// ----------------------------------------------------------------------------- class ApplyToField : public vtkm::worklet::WorkletMapField { public: @@ -355,11 +357,8 @@ vtkm::filter::DataSetResult MarchingCubes::DoExecute(const vtkm::cont::DataSet& //Now that we have the edge interpolation finished we can generate the //following: //1. Coordinates ( with option to do point merging ) - //2. Normals - //todo: We need to run the coords through out policy and determine - //what the output coordinate type should be. We have two problems here - //1. What is the type? float32/float64 - //2. What is the storage backing + // + // vtkm::cont::DataSet output; vtkm::cont::ArrayHandle< vtkm::Vec< vtkm::Float32,3> > vertices; @@ -414,6 +413,16 @@ vtkm::filter::DataSetResult MarchingCubes::DoExecute(const vtkm::cont::DataSet& vtkm::cont::CellSetSingleType< > outputCells( triangleTag ); outputCells.Fill( connectivity ); output.AddCellSet( outputCells ); + + + ApplyToField applyToField; + vtkm::worklet::DispatcherMapField applyFieldDispatcher(applyToField); + applyFieldDispatcher.Invoke(unqiueIds, + this->InterpolationWeights, + vtkm::filter::ApplyPolicy(coords, policy), + vertices); + } else { From d370155e74d18012aabc43f5d0be53fb61c01e96 Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Mon, 22 Feb 2016 11:37:39 -0500 Subject: [PATCH 09/12] MarchingCubes filter now generates coordinates when point merging is enabled. --- vtkm/filter/MarchingCubes.hxx | 5 +- .../testing/UnitTestMarchingCubesFilter.cxx | 82 +++++++++++-------- 2 files changed, 54 insertions(+), 33 deletions(-) diff --git a/vtkm/filter/MarchingCubes.hxx b/vtkm/filter/MarchingCubes.hxx index 9b6f3bc43..ffde0184f 100644 --- a/vtkm/filter/MarchingCubes.hxx +++ b/vtkm/filter/MarchingCubes.hxx @@ -422,6 +422,7 @@ vtkm::filter::DataSetResult MarchingCubes::DoExecute(const vtkm::cont::DataSet& this->InterpolationWeights, vtkm::filter::ApplyPolicy(coords, policy), vertices); + vtkm::cont::printSummary_ArrayHandle(vertices, std::cout); } else @@ -436,7 +437,9 @@ vtkm::filter::DataSetResult MarchingCubes::DoExecute(const vtkm::cont::DataSet& vertices); //when we don't merge points, the connectivity array can be represented - //by a counting array + //by a counting array. The danger of doing it this way is that the output + //type is unknown. We should use explicit connectivity, or add this type + //to the default output types typedef typename vtkm::cont::ArrayHandleIndex::StorageTag IndexStorageTag; CellShapeTagTriangle triangleTag; vtkm::cont::CellSetSingleType< IndexStorageTag > outputCells( triangleTag ); diff --git a/vtkm/filter/testing/UnitTestMarchingCubesFilter.cxx b/vtkm/filter/testing/UnitTestMarchingCubesFilter.cxx index 2f8e538bb..5b85807c2 100644 --- a/vtkm/filter/testing/UnitTestMarchingCubesFilter.cxx +++ b/vtkm/filter/testing/UnitTestMarchingCubesFilter.cxx @@ -273,27 +273,57 @@ void TestMarchingCubesUniformGrid() result = mc.Execute( dataSet, dataSet.GetField("nodevar") ); - vtkm::cont::DataSet& outputData = result.GetDataSet(); - VTKM_TEST_ASSERT(outputData.GetNumberOfCellSets() == 1, - "Wrong number of cellsets in the output dataset"); - VTKM_TEST_ASSERT(outputData.GetNumberOfCoordinateSystems() == 1, - "Wrong number of coordinate systems in the output dataset"); - //since normals is on we have one field - VTKM_TEST_ASSERT(outputData.GetNumberOfFields() == 1, - "Wrong number of fields in the output dataset"); + { + vtkm::cont::DataSet& outputData = result.GetDataSet(); + VTKM_TEST_ASSERT(outputData.GetNumberOfCellSets() == 1, + "Wrong number of cellsets in the output dataset"); + VTKM_TEST_ASSERT(outputData.GetNumberOfCoordinateSystems() == 1, + "Wrong number of coordinate systems in the output dataset"); + //since normals is on we have one field + VTKM_TEST_ASSERT(outputData.GetNumberOfFields() == 1, + "Wrong number of fields in the output dataset"); - //Map a field onto the resulting dataset - const bool isMapped = mc.MapFieldOntoOutput(result, dataSet.GetField("nodevar")); - VTKM_TEST_ASSERT( isMapped, "mapping should pass" ); + //Map a field onto the resulting dataset + const bool isMapped = mc.MapFieldOntoOutput(result, dataSet.GetField("nodevar")); + VTKM_TEST_ASSERT( isMapped, "mapping should pass" ); - VTKM_TEST_ASSERT(outputData.GetNumberOfFields() == 2, - "Wrong number of fields in the output dataset"); + VTKM_TEST_ASSERT(outputData.GetNumberOfFields() == 2, + "Wrong number of fields in the output dataset"); - //verify that the number of cells is correct - //verify that the number of points is correct + //verify that the number of points is correct + vtkm::cont::CoordinateSystem coords = outputData.GetCoordinateSystem(); + VTKM_TEST_ASSERT(coords.GetData().GetNumberOfValues() == 402, + "Should have less coordinates than the unmerged version"); - //should have 480 coordinates - //should have 160 cells + //verify that the number of cells is correct (160) + vtkm::cont::DynamicCellSet dcells = outputData.GetCellSet(); + + typedef vtkm::cont::CellSetSingleType<> CellSetType; + const CellSetType& cells = dcells.Cast(); + VTKM_TEST_ASSERT(cells.GetNumberOfCells() == 160, ""); + } + + //Now try with vertex merging disabled + mc.SetMergeDuplicatePoints(false); + result = mc.Execute( dataSet, + dataSet.GetField("nodevar") ); + + { + vtkm::cont::DataSet& outputData = result.GetDataSet(); + vtkm::cont::CoordinateSystem coords = outputData.GetCoordinateSystem(); + + VTKM_TEST_ASSERT(coords.GetData().GetNumberOfValues() == 480, + "Should have less coordinates than the unmerged version"); + + //verify that the number of cells is correct (160) + vtkm::cont::DynamicCellSet dcells = outputData.GetCellSet(); + + //todo: this needs to be an explicit storage tag + typedef vtkm::cont::ArrayHandleIndex::StorageTag IndexStorageTag; + typedef vtkm::cont::CellSetSingleType CellSetType; + const CellSetType& cells = dcells.Cast(); + VTKM_TEST_ASSERT(cells.GetNumberOfCells() == 160, ""); + } } void TestMarchingCubesCustomPolicy() @@ -334,27 +364,15 @@ void TestMarchingCubesCustomPolicy() "Wrong number of fields in the output dataset"); - //data arrays - // VTKM_TEST_ASSERT(test_equal(vertices.GetNumberOfValues(), 2472), - // "Wrong vertices result for MarchingCubes filter"); - // VTKM_TEST_ASSERT(test_equal(normals.GetNumberOfValues(), 2472), - // "Wrong normals result for MarchingCubes filter"); - // VTKM_TEST_ASSERT(test_equal(scalars.GetNumberOfValues(), 2472), - // "Wrong scalars result for MarchingCubes filter"); + vtkm::cont::CoordinateSystem coords = outputData.GetCoordinateSystem(); + VTKM_TEST_ASSERT(coords.GetData().GetNumberOfValues() == 414, + "Should have some coordinates"); } - -void TestMarchingCubesNonDefaultCoordinates() -{ - -} - - void TestMarchingCubesFilter() { TestMarchingCubesUniformGrid(); TestMarchingCubesCustomPolicy(); - TestMarchingCubesNonDefaultCoordinates(); } } // anonymous namespace From 8e4a47ef5704bf56cc81cd93463973107ccf0b29 Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Mon, 22 Feb 2016 11:38:15 -0500 Subject: [PATCH 10/12] Update IsosurfaceUniformGrid to use the marching cubes filter. This way we have an example of how to use the filter code. --- examples/isosurface/IsosurfaceUniformGrid.cxx | 39 +++++++++---------- vtkm/filter/MarchingCubes.hxx | 2 - 2 files changed, 19 insertions(+), 22 deletions(-) diff --git a/examples/isosurface/IsosurfaceUniformGrid.cxx b/examples/isosurface/IsosurfaceUniformGrid.cxx index 92d6db2a6..4dba1c72e 100644 --- a/examples/isosurface/IsosurfaceUniformGrid.cxx +++ b/examples/isosurface/IsosurfaceUniformGrid.cxx @@ -24,7 +24,7 @@ #define VTKM_DEVICE_ADAPTER VTKM_DEVICE_ADAPTER_SERIAL #endif -#include +#include #include #include @@ -48,10 +48,7 @@ #include -typedef VTKM_DEFAULT_DEVICE_ADAPTER_TAG DeviceAdapter; - -vtkm::Id3 dims(16,16,16); -vtkm::worklet::MarchingCubes *isosurfaceFilter; +vtkm::Id3 dims(256, 256, 256); vtkm::cont::ArrayHandle > verticesArray, normalsArray; vtkm::cont::ArrayHandle scalarsArray; Quaternion qrot; @@ -233,27 +230,29 @@ void mouseCall(int button, int state, int x, int y) // Compute and render an isosurface for a uniform grid example int main(int argc, char* argv[]) { - typedef vtkm::cont::DeviceAdapterTraits DeviceAdapterTraits; typedef vtkm::cont::CellSetStructured<3> CellSet; - std::cout << "Running IsosurfaceUniformGrid example on device adapter: " - << DeviceAdapterTraits::GetName() << std::endl; - vtkm::cont::DataSet dataSet = MakeIsosurfaceTestDataSet(dims); - vtkm::cont::ArrayHandle fieldArray; - dataSet.GetField("nodevar").GetData().CopyTo(fieldArray); - isosurfaceFilter = new vtkm::worklet::MarchingCubes(); + vtkm::filter::MarchingCubes filter; + filter.SetGenerateNormals(true); + filter.SetMergeDuplicatePoints( false ); + filter.SetIsoValue( 0.5 ); + vtkm::filter::DataSetResult result = filter.Execute( dataSet, + dataSet.GetField("nodevar") ); - isosurfaceFilter->Run(0.5, - dataSet.GetCellSet().Cast(), - dataSet.GetCoordinateSystem(), - fieldArray, - verticesArray, - normalsArray); + filter.MapFieldOntoOutput(result, dataSet.GetField("nodevar")); - isosurfaceFilter->MapFieldOntoIsosurface(fieldArray, - scalarsArray); + //need to extract vertices, normals, and scalars + vtkm::cont::DataSet& outputData = result.GetDataSet(); + + + typedef vtkm::cont::ArrayHandle< vtkm::Vec > VertType; + vtkm::cont::CoordinateSystem coords = outputData.GetCoordinateSystem(); + + verticesArray = coords.GetData().Cast(); + normalsArray = outputData.GetField("normals").GetData().Cast(); + scalarsArray = outputData.GetField("nodevar").GetData().Cast< vtkm::cont::ArrayHandle >(); std::cout << "Number of output vertices: " << verticesArray.GetNumberOfValues() << std::endl; diff --git a/vtkm/filter/MarchingCubes.hxx b/vtkm/filter/MarchingCubes.hxx index ffde0184f..66c7f54b8 100644 --- a/vtkm/filter/MarchingCubes.hxx +++ b/vtkm/filter/MarchingCubes.hxx @@ -422,8 +422,6 @@ vtkm::filter::DataSetResult MarchingCubes::DoExecute(const vtkm::cont::DataSet& this->InterpolationWeights, vtkm::filter::ApplyPolicy(coords, policy), vertices); - vtkm::cont::printSummary_ArrayHandle(vertices, std::cout); - } else { From 179b48e0948abfef6972f5aaa173abed82fa3afa Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Wed, 9 Mar 2016 08:57:43 -0500 Subject: [PATCH 11/12] Reduce compile time for MarchingCubes by passing less info by Invoke. When the number of parameters to a worklet hits 6+ like the EdgeGenerate worklet did, the compile times when some of those parameters are dynamic array handle is very bad. For example when building the MarchingCubes filter for VTK integration the EdgeGenerate worklet would take 800+ seconds to compile, but when we switch it to have fewer arguments the compile time comes down to ~250sec. --- vtkm/filter/MarchingCubes.hxx | 165 ++++++++++++++++++++++------------ 1 file changed, 108 insertions(+), 57 deletions(-) diff --git a/vtkm/filter/MarchingCubes.hxx b/vtkm/filter/MarchingCubes.hxx index 66c7f54b8..ff441dd43 100644 --- a/vtkm/filter/MarchingCubes.hxx +++ b/vtkm/filter/MarchingCubes.hxx @@ -28,7 +28,14 @@ namespace { + +typedef vtkm::Vec< vtkm::Id2, 3 > Vec3Id2; +typedef vtkm::Vec< vtkm::Vec, 3 > FVec3x3; +typedef vtkm::Vec< vtkm::Vec, 3 > DVec3x3; + typedef vtkm::filter::FilterTraits::InputFieldTypeList InputTypes; +struct InterpolateIdTypes : vtkm::ListTagBase< Vec3Id2 > { }; +struct Vec3FloatTypes : vtkm::ListTagBase< FVec3x3, DVec3x3> { }; // ----------------------------------------------------------------------------- template @@ -99,68 +106,104 @@ public: numTriangles = numTrianglesTable.Get(caseNumber); } }; +/// \brief Used to store data need for the EdgeWeightGenerate worklet. +/// This information is not passed as part of the arguments to the worklet as +/// that dramatically increase compile time by 200% +// ----------------------------------------------------------------------------- +template< typename DeviceAdapter > +class EdgeWeightGenerateMetaData +{ + template + struct PortalTypes + { + public: + typedef vtkm::cont::ArrayHandle HandleType; + typedef typename HandleType::template ExecutionTypes ExecutionTypes; + + typedef typename ExecutionTypes::Portal Portal; + typedef typename ExecutionTypes::PortalConst PortalConst; + }; + +public: + typedef vtkm::worklet::ScatterCounting ScatterType; + + VTKM_CONT_EXPORT + EdgeWeightGenerateMetaData( + vtkm::Id size, + vtkm::cont::ArrayHandle< vtkm::Vec< vtkm::Float32,3> >& normals, + vtkm::cont::ArrayHandle< vtkm::FloatDefault >& interpWeights, + vtkm::cont::ArrayHandle& interpIds, + const vtkm::cont::ArrayHandle< vtkm::IdComponent >& edgeTable, + const vtkm::cont::ArrayHandle< vtkm::IdComponent >& numTriTable, + const vtkm::cont::ArrayHandle< vtkm::IdComponent >& triTable, + const vtkm::worklet::ScatterCounting& scatter): + NormalPortal( normals.PrepareForOutput( 3*size, DeviceAdapter() ) ), + InterpWeightsPortal( interpWeights.PrepareForOutput( 3*size, DeviceAdapter()) ), + InterpIdPortal( interpIds.PrepareForOutput( 3*size, DeviceAdapter() ) ), + EdgeTable( edgeTable.PrepareForInput(DeviceAdapter()) ), + NumTriTable( numTriTable.PrepareForInput(DeviceAdapter()) ), + TriTable( triTable.PrepareForInput(DeviceAdapter()) ), + Scatter(scatter) + { + //any way we can easily build an interface so that we don't need to hold + //onto a billion portals? + + //Normal and Interp need to be 3 times longer than size as they + //are per point of the output triangle + } + + typename PortalTypes< vtkm::Vec< vtkm::Float32,3> >::Portal NormalPortal; + typename PortalTypes::Portal InterpWeightsPortal; + typename PortalTypes::Portal InterpIdPortal; + typename PortalTypes::PortalConst EdgeTable; + typename PortalTypes::PortalConst NumTriTable; + typename PortalTypes::PortalConst TriTable; + ScatterType Scatter; +}; /// \brief Compute the weights for each edge that is used to generate /// a point in the resulting iso-surface // ----------------------------------------------------------------------------- +template class EdgeWeightGenerate : public vtkm::worklet::WorkletMapPointToCell { - typedef vtkm::Vec< vtkm::Id2, 3 > Vec3Id2; - typedef vtkm::Vec< vtkm::Vec, 3 > FVec3x3; - typedef vtkm::Vec< vtkm::Vec, 3 > DVec3x3; - public: - - typedef vtkm::worklet::ScatterCounting ScatterType; - - struct InterpolateIdTypes : vtkm::ListTagBase< Vec3Id2 > { }; - struct Vec3FloatTypes : vtkm::ListTagBase< FVec3x3, DVec3x3> { }; + typedef typename EdgeWeightGenerateMetaData::ScatterType ScatterType; typedef void ControlSignature( TopologyIn topology, // Cell set FieldInPoint fieldIn, // Input point field defining the contour - FieldInPoint pcoordIn, // Input point coordinates - FieldOutCell normalsOut, // Estimated normals (one per tri vertex) - FieldOutCell interpolationWeights, - FieldOutCell interpolationIds, - WholeArrayIn EdgeTable, // An array portal with the edge table - WholeArrayIn TriTable // An array portal with the triangle table + FieldInPoint pcoordIn // Input point coordinates ); - typedef void ExecutionSignature( - CellShape, _2, _3, _4, _5, _6, _7, _8, VisitIndex, FromIndices); + typedef void ExecutionSignature(CellShape, _2, _3, WorkIndex, VisitIndex, FromIndices); typedef _1 InputDomain; + VTKM_CONT_EXPORT EdgeWeightGenerate(vtkm::Float64 isovalue, bool genNormals, - const vtkm::worklet::ScatterCounting scatter) : + const EdgeWeightGenerateMetaData& meta) : Isovalue(isovalue), GenerateNormals(genNormals), - Scatter( scatter ) { } + MetaData( meta ) + { + } template VTKM_EXEC_EXPORT void operator()( CellShapeTag shape, const FieldInType &fieldIn, // Input point field defining the contour const CoordType &coords, // Input point coordinates - NormalType &normalsOut, // Estimated normals (one per tri vertex) - WeightType &interpolationWeights, - IdType &interpolationIds, - const EdgeTablePortalType &edgeTable, - const TriTablePortalType &triTable, + vtkm::Id outputCellId, vtkm::IdComponent visitIndex, const IndicesVecType &indices) const { + const vtkm::Id outputPointId = 3 * outputCellId; typedef typename vtkm::VecTraits::ComponentType FieldType; const FieldType iso = static_cast(this->Isovalue); @@ -174,23 +217,22 @@ public: for (vtkm::IdComponent triVertex = 0; triVertex < 3; triVertex++) { const vtkm::IdComponent edgeIndex = - triTable.Get(triTableOffset + triVertex); - const vtkm::IdComponent edgeVertex0 = edgeTable.Get(2*edgeIndex + 0); - const vtkm::IdComponent edgeVertex1 = edgeTable.Get(2*edgeIndex + 1); + MetaData.TriTable.Get(triTableOffset + triVertex); + const vtkm::IdComponent edgeVertex0 = MetaData.EdgeTable.Get(2*edgeIndex + 0); + const vtkm::IdComponent edgeVertex1 = MetaData.EdgeTable.Get(2*edgeIndex + 1); const FieldType fieldValue0 = fieldIn[edgeVertex0]; const FieldType fieldValue1 = fieldIn[edgeVertex1]; - interpolationIds[triVertex][0] = indices[edgeVertex0]; - interpolationIds[triVertex][1] = indices[edgeVertex1]; + //need to factor in outputCellId + MetaData.InterpIdPortal.Set(outputPointId+triVertex, + vtkm::make_Vec(indices[edgeVertex0], indices[edgeVertex1])); - //we need to cast each side of the division to WeightType::ComponentType - //so that the interpolation works properly even when iso-contouring - //char/uchar fields - typedef typename vtkm::VecTraits::ComponentType WType; - WType interpolant = - static_cast(iso - fieldValue0) / - static_cast(fieldValue1 - fieldValue0); - interpolationWeights[triVertex] = interpolant; + vtkm::FloatDefault interpolant = + static_cast(iso - fieldValue0) / + static_cast(fieldValue1 - fieldValue0); + + //need to factor in outputCellId + MetaData.InterpWeightsPortal.Set(outputPointId+triVertex, interpolant); if(this->GenerateNormals) { @@ -204,24 +246,26 @@ public: const vtkm::Vec interpPCoord = vtkm::Lerp(edgePCoord0, edgePCoord1, interpolant); - normalsOut[triVertex] = + //need to factor in outputCellId + MetaData.NormalPortal.Set(outputPointId+triVertex, vtkm::Normal(vtkm::exec::CellDerivative( - fieldIn, coords, interpPCoord, shape, *this)); + fieldIn, coords, interpPCoord, shape, *this)) + ); } + } } VTKM_CONT_EXPORT ScatterType GetScatter() const { - return this->Scatter; + return this->MetaData.Scatter; } - private: const vtkm::Float64 Isovalue; const bool GenerateNormals; - ScatterType Scatter; + EdgeWeightGenerateMetaData MetaData; }; // ----------------------------------------------------------------------------- @@ -316,7 +360,7 @@ vtkm::filter::DataSetResult MarchingCubes::DoExecute(const vtkm::cont::DataSet& > ClassifyDispatcher; typedef typename vtkm::worklet::DispatcherMapTopology< - EdgeWeightGenerate, + EdgeWeightGenerate, DeviceAdapter > GenerateDispatcher; @@ -338,21 +382,28 @@ vtkm::filter::DataSetResult MarchingCubes::DoExecute(const vtkm::cont::DataSet& Vec3HandleType normals; vtkm::worklet::ScatterCounting scatter(numOutputTrisPerCell, DeviceAdapter()); - EdgeWeightGenerate weightGenerate(this->IsoValue, - this->GenerateNormals, - scatter); + + EdgeWeightGenerateMetaData metaData( + scatter.GetOutputRange(numOutputTrisPerCell.GetNumberOfValues()), + normals, + this->InterpolationWeights, + this->InterpolationIds, + this->EdgeTable, + this->NumTrianglesTable, + this->TriangleTable, + scatter); + + EdgeWeightGenerate weightGenerate(this->IsoValue, + this->GenerateNormals, + metaData); GenerateDispatcher edgeDispatcher(weightGenerate); edgeDispatcher.Invoke( vtkm::filter::ApplyPolicy(cells, policy), //cast to a scalar field if not one, as cellderivative only works on those make_ScalarField(field), - vtkm::filter::ApplyPolicy(coords, policy), - vtkm::cont::make_ArrayHandleGroupVec<3>(normals), - vtkm::cont::make_ArrayHandleGroupVec<3>(this->InterpolationWeights), - vtkm::cont::make_ArrayHandleGroupVec<3>(this->InterpolationIds), - this->EdgeTable, - this->TriangleTable); + vtkm::filter::ApplyPolicy(coords, policy) + ); //Now that we have the edge interpolation finished we can generate the //following: From e4237c3a3bcf60abba1f38b1b2b537e9b3948de9 Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Mon, 14 Mar 2016 08:38:49 -0400 Subject: [PATCH 12/12] Fix warnings found by the dashboard machines. --- vtkm/filter/testing/UnitTestVertexClusteringFilter.cxx | 2 -- 1 file changed, 2 deletions(-) diff --git a/vtkm/filter/testing/UnitTestVertexClusteringFilter.cxx b/vtkm/filter/testing/UnitTestVertexClusteringFilter.cxx index 4b4255529..e84c7c57f 100644 --- a/vtkm/filter/testing/UnitTestVertexClusteringFilter.cxx +++ b/vtkm/filter/testing/UnitTestVertexClusteringFilter.cxx @@ -47,8 +47,6 @@ void TestVertexClustering() // test - const vtkm::Id output_pointIds = 9; - vtkm::Id output_pointId[output_pointIds] = {0,1,3, 1,5,4, 1,2,5}; const vtkm::Id output_points = 6; vtkm::Float64 output_point[output_points][3] = {{0.0174716003,0.0501927994,0.0930275023}, {0.0320714004,0.14704667,0.0952706337}, {0.0268670674,0.246195346,0.119720004}, {0.00215422804,0.0340906903,0.180881709}, {0.0108188,0.152774006,0.167914003}, {0.0202241503,0.225427493,0.140208006}};