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/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/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 { 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(), 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; } 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..7d0412e57 --- /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::ApplyPolicy(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..cabd0ea56 --- /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::ApplyPolicy(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::ApplyPolicy(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::ApplyPolicy(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..e8a61497d --- /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::ApplyPolicy(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..45997b8ed --- /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::ApplyPolicy(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::ApplyPolicy(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..ff441dd43 --- /dev/null +++ b/vtkm/filter/MarchingCubes.hxx @@ -0,0 +1,554 @@ +//============================================================================ +// 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::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 +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 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 +{ +public: + 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 + ); + typedef void ExecutionSignature(CellShape, _2, _3, WorkIndex, VisitIndex, FromIndices); + + typedef _1 InputDomain; + + + VTKM_CONT_EXPORT + EdgeWeightGenerate(vtkm::Float64 isovalue, + bool genNormals, + const EdgeWeightGenerateMetaData& meta) : + Isovalue(isovalue), + GenerateNormals(genNormals), + 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 + 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); + + // 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 = + 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]; + + //need to factor in outputCellId + MetaData.InterpIdPortal.Set(outputPointId+triVertex, + vtkm::make_Vec(indices[edgeVertex0], indices[edgeVertex1])); + + 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) + { + 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); + + //need to factor in outputCellId + MetaData.NormalPortal.Set(outputPointId+triVertex, + vtkm::Normal(vtkm::exec::CellDerivative( + fieldIn, coords, interpPCoord, shape, *this)) + ); + } + + } + } + + VTKM_CONT_EXPORT + ScatterType GetScatter() const + { + return this->MetaData.Scatter; + } + +private: + const vtkm::Float64 Isovalue; + const bool GenerateNormals; + EdgeWeightGenerateMetaData MetaData; +}; + +// ----------------------------------------------------------------------------- +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::ApplyPolicy(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()); + + 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) + ); + + //Now that we have the edge interpolation finished we can generate the + //following: + //1. Coordinates ( with option to do point merging ) + // + // + 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); + + + CellShapeTagTriangle triangleTag; + 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 + { + ApplyToField applyToField; + vtkm::worklet::DispatcherMapField applyFieldDispatcher(applyToField); + + applyFieldDispatcher.Invoke(this->InterpolationIds, + this->InterpolationWeights, + vtkm::filter::ApplyPolicy(coords, policy), + vertices); + + //when we don't merge points, the connectivity array can be represented + //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 ); + 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..ff803885c --- /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 + > +ApplyPolicy(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 + > +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 + 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 + > +ApplyPolicy(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 + > +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 + 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 > +ApplyPolicy(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..4c4ecc418 --- /dev/null +++ b/vtkm/filter/Threshold.h @@ -0,0 +1,77 @@ +//============================================================================ +// 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 SetLowerThreshold(vtkm::Float64 value){ this->LowerValue = value; } + VTKM_CONT_EXPORT + void SetUpperThreshold(vtkm::Float64 value){ this->UpperValue = value; } + + VTKM_CONT_EXPORT + vtkm::Float64 GetLowerThreshold() const { return this->LowerValue; } + VTKM_CONT_EXPORT + vtkm::Float64 GetUpperThreshold() const { return this->UpperValue; } + + 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 LowerValue; + double UpperValue; + 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..f14da34c6 --- /dev/null +++ b/vtkm/filter/Threshold.hxx @@ -0,0 +1,194 @@ +//============================================================================ +// 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 ThresholdRange +{ +public: + VTKM_CONT_EXPORT + 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->Lower) && + value <= static_cast(this->Upper); + } + +private: + vtkm::Float64 Lower; + vtkm::Float64 Upper; +}; + +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(), + LowerValue(0), + UpperValue(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()); + + ThresholdRange predicate( this->GetLowerThreshold(), this->GetUpperThreshold() ); + vtkm::cont::ArrayHandle passFlags; + if(fieldMeta.IsPointField()) + { + typedef vtkm::worklet::Threshold Worklets; + typedef Worklets::ThresholdByPointField< ThresholdRange > ThresholdWorklet; + ThresholdWorklet worklet(predicate); + vtkm::worklet::DispatcherMapTopology dispatcher(worklet); + dispatcher.Invoke(vtkm::filter::ApplyPolicy(cells, policy), field, passFlags); + } + else if(fieldMeta.IsCellField()) + { + typedef vtkm::worklet::Threshold Worklets; + typedef Worklets::ThresholdByCellField< ThresholdRange > ThresholdWorklet; + ThresholdWorklet worklet(predicate); + vtkm::worklet::DispatcherMapTopology dispatcher(worklet); + dispatcher.Invoke(vtkm::filter::ApplyPolicy(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::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 + //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..dacb89ab9 --- /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::ApplyPolicy(input.GetCellSet(), policy), + vtkm::filter::ApplyPolicy(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..5b85807c2 --- /dev/null +++ b/vtkm/filter/testing/UnitTestMarchingCubesFilter.cxx @@ -0,0 +1,384 @@ +//============================================================================ +// 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 points is correct + vtkm::cont::CoordinateSystem coords = outputData.GetCoordinateSystem(); + VTKM_TEST_ASSERT(coords.GetData().GetNumberOfValues() == 402, + "Should have less coordinates than the unmerged version"); + + //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() +{ + 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"); + + + vtkm::cont::CoordinateSystem coords = outputData.GetCoordinateSystem(); + VTKM_TEST_ASSERT(coords.GetData().GetNumberOfValues() == 414, + "Should have some coordinates"); +} + +void TestMarchingCubesFilter() +{ + TestMarchingCubesUniformGrid(); + TestMarchingCubesCustomPolicy(); +} + +} // 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..50434a7f1 --- /dev/null +++ b/vtkm/filter/testing/UnitTestThresholdFilter.cxx @@ -0,0 +1,171 @@ +//============================================================================ +// 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.SetLowerThreshold(60.1); + threshold.SetUpperThreshold(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.SetLowerThreshold(20.1); + threshold.SetUpperThreshold(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.SetLowerThreshold(20.1); + threshold.SetUpperThreshold(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.SetLowerThreshold(500.1); + threshold.SetUpperThreshold(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..e84c7c57f --- /dev/null +++ b/vtkm/filter/testing/UnitTestVertexClusteringFilter.cxx @@ -0,0 +1,73 @@ +//============================================================================ +// 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_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 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());