Merge topic 'vtkm_filters'

e4237c3a Fix warnings found by the dashboard machines.
179b48e0 Reduce compile time for MarchingCubes by passing less info by Invoke.
8e4a47ef Update IsosurfaceUniformGrid to use the marching cubes filter.
d370155e MarchingCubes filter now generates coordinates when point merging is enabled.
c00fb53b Marching Cubes now generates vertices when merge duplicates is enabled.
f699c986 Renamed the ```Convert``` method to ```ApplyPolicy```
8e72ec8e Switch filter::threshold over to have a lower and upper bounds.
bcee8270 First draft of vtkm::filter design.
...

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !311
This commit is contained in:
Robert Maynard 2016-03-15 13:07:20 -04:00 committed by Kitware Robot
commit 2f352f90f4
45 changed files with 4932 additions and 60 deletions

@ -24,7 +24,7 @@
#define VTKM_DEVICE_ADAPTER VTKM_DEVICE_ADAPTER_SERIAL
#endif
#include <vtkm/worklet/MarchingCubes.h>
#include <vtkm/filter/MarchingCubes.h>
#include <vtkm/worklet/DispatcherMapField.h>
#include <vtkm/Math.h>
@ -48,10 +48,7 @@
#include <vector>
typedef VTKM_DEFAULT_DEVICE_ADAPTER_TAG DeviceAdapter;
vtkm::Id3 dims(16,16,16);
vtkm::worklet::MarchingCubes<vtkm::Float32, DeviceAdapter> *isosurfaceFilter;
vtkm::Id3 dims(256, 256, 256);
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32,3> > verticesArray, normalsArray;
vtkm::cont::ArrayHandle<vtkm::Float32> 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<DeviceAdapter> 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<vtkm::Float32> fieldArray;
dataSet.GetField("nodevar").GetData().CopyTo(fieldArray);
isosurfaceFilter = new vtkm::worklet::MarchingCubes<vtkm::Float32, DeviceAdapter>();
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<CellSet>(),
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<vtkm::Float32,3> > VertType;
vtkm::cont::CoordinateSystem coords = outputData.GetCoordinateSystem();
verticesArray = coords.GetData().Cast<VertType>();
normalsArray = outputData.GetField("normals").GetData().Cast<VertType>();
scalarsArray = outputData.GetField("nodevar").GetData().Cast< vtkm::cont::ArrayHandle<vtkm::Float32> >();
std::cout << "Number of output vertices: " << verticesArray.GetNumberOfValues() << std::endl;

@ -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)

@ -140,14 +140,14 @@ public:
this->Superclass::GetData());
}
template<typename DeviceAdapterTag, typename TypeList>
template<typename DeviceAdapterTag>
VTKM_CONT_EXPORT
const vtkm::cont::ArrayHandle<vtkm::Float64>& 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<typename DeviceAdapterTag, typename TypeList, typename StorageList>
VTKM_CONT_EXPORT
void GetBounds(vtkm::Float64 *bounds, DeviceAdapterTag, TypeList, StorageList) const
{
this->Superclass::GetBounds(
bounds,
DeviceAdapterTag(),
TypeList(),
StorageList());
}
template<typename DeviceAdapterTag>
VTKM_CONT_EXPORT
const vtkm::cont::ArrayHandle<vtkm::Float64>& GetBounds(DeviceAdapterTag) const
@ -171,17 +183,31 @@ public:
VTKM_DEFAULT_COORDINATE_SYSTEM_STORAGE_LIST_TAG());
}
template<typename DeviceAdapterTag>
template<typename DeviceAdapterTag, typename TypeList>
VTKM_CONT_EXPORT
void GetBounds(vtkm::Float64 *bounds, DeviceAdapterTag) const
const vtkm::cont::ArrayHandle<vtkm::Float64>& 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<typename DeviceAdapterTag, typename TypeList, typename StorageList>
VTKM_CONT_EXPORT
const vtkm::cont::ArrayHandle<vtkm::Float64>& GetBounds(DeviceAdapterTag,
TypeList,
StorageList) const
{
return this->Superclass::GetBounds(
DeviceAdapterTag(),
TypeList(),
StorageList());
}
VTKM_CONT_EXPORT
virtual void PrintSummary(std::ostream &out) const
{

@ -481,7 +481,7 @@ public:
Field()
: Name(),
Order(),
Association(),
Association(ASSOC_ANY),
AssocCellSetName(),
AssocLogicalDim(),
Data(),

@ -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;
}

@ -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)

55
vtkm/filter/CellAverage.h Normal file

@ -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 <vtkm/filter/CellFilter.h>
#include <vtkm/worklet/CellAverage.h>
namespace vtkm {
namespace filter {
class CellAverage : public vtkm::filter::CellFilter<CellAverage>
{
public:
VTKM_CONT_EXPORT
CellAverage();
template<typename T, typename StorageType, typename DerivedPolicy, typename DeviceAdapter>
VTKM_CONT_EXPORT
vtkm::filter::FieldResult DoExecute(const vtkm::cont::DataSet &input,
const vtkm::cont::ArrayHandle<T, StorageType>& field,
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
const DeviceAdapter& tag);
private:
vtkm::worklet::CellAverage Worklet;
};
}
} // namespace vtkm::filter
#include <vtkm/filter/CellAverage.hxx>
#endif // vtk_m_filter_CellAverage_h

@ -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 <vtkm/cont/DynamicCellSet.h>
#include <vtkm/worklet/DispatcherMapTopology.h>
namespace vtkm {
namespace filter {
//-----------------------------------------------------------------------------
CellAverage::CellAverage():
vtkm::filter::CellFilter<CellAverage>(),
Worklet()
{
}
//-----------------------------------------------------------------------------
template<typename T,
typename StorageType,
typename DerivedPolicy,
typename DeviceAdapter>
vtkm::filter::FieldResult CellAverage::DoExecute(const vtkm::cont::DataSet &input,
const vtkm::cont::ArrayHandle<T, StorageType>& field,
const vtkm::filter::FieldMetadata&,
const vtkm::filter::PolicyBase<DerivedPolicy>&,
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<T> outArray = field;
vtkm::worklet::DispatcherMapTopology<vtkm::worklet::CellAverage,
DeviceAdapter > 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

54
vtkm/filter/CellFilter.h Normal file

@ -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 <vtkm/filter/FieldFilter.h>
namespace vtkm {
namespace filter {
template<class Derived>
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 <vtkm/filter/CellFilter.hxx>
#endif // vtk_m_filter_CellFilter_h

@ -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<class Derived>
CellFilter<Derived>::CellFilter():
vtkm::filter::FieldFilter< Derived >(),
CellSetIndex(0)
{
}
}
}

127
vtkm/filter/DataSetFilter.h Normal file

@ -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 <vtkm/cont/DataSet.h>
#include <vtkm/cont/DynamicCellSet.h>
#include <vtkm/cont/CoordinateSystem.h>
#include <vtkm/cont/Field.h>
#include <vtkm/filter/PolicyBase.h>
#include <vtkm/filter/internal/RuntimeDeviceTracker.h>
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 Derived>
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<typename DerivedPolicy>
VTKM_CONT_EXPORT
DataSetResult Execute(const vtkm::cont::DataSet &input,
const vtkm::filter::PolicyBase<DerivedPolicy>& 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<typename DerivedPolicy>
VTKM_CONT_EXPORT
bool MapFieldOntoOutput(DataSetResult& result,
const vtkm::cont::Field& field,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy);
private:
template<typename DerivedPolicy>
VTKM_CONT_EXPORT
DataSetResult PrepareForExecution(const vtkm::cont::DataSet& input,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy);
std::string OutputFieldName;
vtkm::Id CellSetIndex;
vtkm::Id CoordinateSystemIndex;
vtkm::filter::internal::RuntimeDeviceTracker Tracker;
};
}
} // namespace vtkm::filter
#include <vtkm/filter/DataSetFilter.hxx>
#endif // vtk_m_filter_DataSetFilter_h

@ -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 <vtkm/filter/DefaultPolicy.h>
#include <vtkm/filter/FieldMetadata.h>
#include <vtkm/filter/FilterTraits.h>
#include <vtkm/filter/internal/ResolveFieldTypeAndExecute.h>
#include <vtkm/filter/internal/ResolveFieldTypeAndMap.h>
#include <vtkm/cont/Error.h>
#include <vtkm/cont/ErrorControlBadAllocation.h>
#include <vtkm/cont/ErrorExecution.h>
#include <vtkm/cont/cuda/DeviceAdapterCuda.h>
#include <vtkm/cont/tbb/DeviceAdapterTBB.h>
namespace vtkm {
namespace filter {
//----------------------------------------------------------------------------
template<class Derived>
DataSetFilter<Derived>::DataSetFilter():
OutputFieldName(),
CellSetIndex(0),
CoordinateSystemIndex(0),
Tracker()
{
}
//-----------------------------------------------------------------------------
template<typename Derived>
DataSetResult DataSetFilter<Derived>::Execute(const vtkm::cont::DataSet &input)
{
return this->Execute(input, vtkm::filter::DefaultPolicy());
}
//-----------------------------------------------------------------------------
template<typename Derived>
template<typename DerivedPolicy>
DataSetResult DataSetFilter<Derived>::Execute(const vtkm::cont::DataSet &input,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy )
{
return this->PrepareForExecution(input, policy);
}
//-----------------------------------------------------------------------------
template<typename Derived>
template<typename DerivedPolicy>
DataSetResult DataSetFilter<Derived>::PrepareForExecution(const vtkm::cont::DataSet &input,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy )
{
typedef vtkm::cont::DeviceAdapterTagCuda CudaTag;
typedef vtkm::cont::DeviceAdapterTagTBB TBBTag;
typedef vtkm::cont::DeviceAdapterTagSerial SerialTag;
DataSetResult result = run_if_valid<DataSetResult>( static_cast<Derived*>(this),
input,
policy,
this->Tracker,
CudaTag() );
if( !result.IsValid() )
{
result = run_if_valid<DataSetResult>( static_cast<Derived*>(this),
input,
policy,
this->Tracker,
TBBTag() );
}
if( !result.IsValid() )
{
result = run_if_valid<DataSetResult>( static_cast<Derived*>(this),
input,
policy,
this->Tracker,
SerialTag() );
}
return result;
}
//-----------------------------------------------------------------------------
template<typename Derived>
bool DataSetFilter<Derived>::MapFieldOntoOutput(DataSetResult& result,
const vtkm::cont::Field& field)
{
return this->MapFieldOntoOutput(result, field, vtkm::filter::DefaultPolicy());
}
//-----------------------------------------------------------------------------
template<typename Derived>
template<typename DerivedPolicy>
bool DataSetFilter<Derived>::MapFieldOntoOutput(DataSetResult& result,
const vtkm::cont::Field& field,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy)
{
bool valid = false;
if(result.IsValid())
{
typedef internal::ResolveFieldTypeAndMap< Derived,
DerivedPolicy > FunctorType;
FunctorType functor(static_cast<Derived*>(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;
}
}
}

@ -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 <vtkm/cont/DataSet.h>
#include <vtkm/cont/DynamicCellSet.h>
#include <vtkm/cont/CoordinateSystem.h>
#include <vtkm/cont/Field.h>
#include <vtkm/filter/PolicyBase.h>
#include <vtkm/filter/DataSetFilter.h>
#include <vtkm/filter/internal/RuntimeDeviceTracker.h>
namespace vtkm {
namespace filter {
template<class Derived>
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<typename DerivedPolicy>
VTKM_CONT_EXPORT
DataSetResult Execute(const vtkm::cont::DataSet &input,
const std::string &inFieldName,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy );
template<typename DerivedPolicy>
VTKM_CONT_EXPORT
DataSetResult Execute(const vtkm::cont::DataSet &input,
const vtkm::cont::Field &field,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy );
template<typename DerivedPolicy>
VTKM_CONT_EXPORT
DataSetResult Execute(const vtkm::cont::DataSet &input,
const vtkm::cont::CoordinateSystem &field,
const vtkm::filter::PolicyBase<DerivedPolicy>& 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<typename DerivedPolicy>
VTKM_CONT_EXPORT
bool MapFieldOntoOutput(DataSetResult& result,
const vtkm::cont::Field& field,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy);
private:
template<typename DerivedPolicy>
VTKM_CONT_EXPORT
DataSetResult PrepareForExecution(const vtkm::cont::DataSet& input,
const vtkm::cont::Field& field,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy);
//How do we specify float/double coordinate types?
template<typename DerivedPolicy>
VTKM_CONT_EXPORT
DataSetResult PrepareForExecution(const vtkm::cont::DataSet& input,
const vtkm::cont::CoordinateSystem& field,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy);
std::string OutputFieldName;
vtkm::Id CellSetIndex;
vtkm::Id CoordinateSystemIndex;
vtkm::filter::internal::RuntimeDeviceTracker Tracker;
};
}
} // namespace vtkm::filter
#include <vtkm/filter/DataSetWithFieldFilter.hxx>
#endif // vtk_m_filter_DataSetFilter_h

@ -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 <vtkm/filter/DefaultPolicy.h>
#include <vtkm/filter/FieldMetadata.h>
#include <vtkm/filter/FilterTraits.h>
#include <vtkm/filter/internal/ResolveFieldTypeAndExecute.h>
#include <vtkm/filter/internal/ResolveFieldTypeAndMap.h>
#include <vtkm/cont/Error.h>
#include <vtkm/cont/ErrorControlBadAllocation.h>
#include <vtkm/cont/ErrorExecution.h>
#include <vtkm/cont/cuda/DeviceAdapterCuda.h>
#include <vtkm/cont/tbb/DeviceAdapterTBB.h>
namespace vtkm {
namespace filter {
//----------------------------------------------------------------------------
template<class Derived>
DataSetWithFieldFilter<Derived>::DataSetWithFieldFilter():
OutputFieldName(),
CellSetIndex(0),
CoordinateSystemIndex(0),
Tracker()
{
}
//-----------------------------------------------------------------------------
template<typename Derived>
DataSetResult DataSetWithFieldFilter<Derived>::Execute(const vtkm::cont::DataSet &input,
const std::string &inFieldName)
{
return this->Execute(input,
input.GetField(inFieldName),
vtkm::filter::DefaultPolicy());
}
//-----------------------------------------------------------------------------
template<typename Derived>
DataSetResult DataSetWithFieldFilter<Derived>::Execute(const vtkm::cont::DataSet &input,
const vtkm::cont::Field &field)
{
return this->Execute(input,
field,
vtkm::filter::DefaultPolicy());
}
//-----------------------------------------------------------------------------
template<typename Derived>
DataSetResult DataSetWithFieldFilter<Derived>::Execute(const vtkm::cont::DataSet &input,
const vtkm::cont::CoordinateSystem &field)
{
return this->Execute(input,
field,
vtkm::filter::DefaultPolicy());
}
//-----------------------------------------------------------------------------
template<typename Derived>
template<typename DerivedPolicy>
DataSetResult DataSetWithFieldFilter<Derived>::Execute(const vtkm::cont::DataSet &input,
const std::string &inFieldName,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy )
{
return this->Execute(input,
input.GetField(inFieldName),
policy);
}
//-----------------------------------------------------------------------------
template<typename Derived>
template<typename DerivedPolicy>
DataSetResult DataSetWithFieldFilter<Derived>::Execute(const vtkm::cont::DataSet &input,
const vtkm::cont::Field &field,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy )
{
return this->PrepareForExecution(input, field, policy);
}
//-----------------------------------------------------------------------------
template<typename Derived>
template<typename DerivedPolicy>
DataSetResult DataSetWithFieldFilter<Derived>::Execute(const vtkm::cont::DataSet &input,
const vtkm::cont::CoordinateSystem &field,
const vtkm::filter::PolicyBase<DerivedPolicy>& 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<typename Derived>
template<typename DerivedPolicy>
DataSetResult DataSetWithFieldFilter<Derived>::PrepareForExecution(const vtkm::cont::DataSet &input,
const vtkm::cont::Field &field,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy )
{
//determine the field type first
DataSetResult result;
typedef internal::ResolveFieldTypeAndExecute< Derived, DerivedPolicy,
DataSetResult > FunctorType;
FunctorType functor(static_cast<Derived*>(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<typename Derived>
template<typename DerivedPolicy>
DataSetResult DataSetWithFieldFilter<Derived>::PrepareForExecution(const vtkm::cont::DataSet &input,
const vtkm::cont::CoordinateSystem &field,
const vtkm::filter::PolicyBase<DerivedPolicy>& 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<Derived*>(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<typename Derived>
bool DataSetWithFieldFilter<Derived>::MapFieldOntoOutput(DataSetResult& result,
const vtkm::cont::Field& field)
{
return this->MapFieldOntoOutput(result, field, vtkm::filter::DefaultPolicy());
}
//-----------------------------------------------------------------------------
template<typename Derived>
template<typename DerivedPolicy>
bool DataSetWithFieldFilter<Derived>::MapFieldOntoOutput(DataSetResult& result,
const vtkm::cont::Field& field,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy)
{
bool valid = false;
if(result.IsValid())
{
typedef internal::ResolveFieldTypeAndMap< Derived,
DerivedPolicy > FunctorType;
FunctorType functor(static_cast<Derived*>(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;
}
}
}

@ -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 <vtkm/filter/PolicyBase.h>
#include <vtkm/cont/CellSetListTag.h>
#include <vtkm/cont/StorageListTag.h>
#include <vtkm/TypeListTag.h>
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

@ -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 <vtkm/filter/DataSetFilter.h>
#include <vtkm/worklet/ExternalFaces.h>
namespace vtkm {
namespace filter {
class ExternalFaces : public vtkm::filter::DataSetFilter<ExternalFaces>
{
public:
VTKM_CONT_EXPORT
ExternalFaces();
template<typename DerivedPolicy, typename DeviceAdapter>
VTKM_CONT_EXPORT
vtkm::filter::DataSetResult DoExecute(const vtkm::cont::DataSet& input,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
const DeviceAdapter& tag);
//Map a new field onto the resulting dataset after running the filter
//this call is only valid
template<typename T, typename StorageType, typename DerivedPolicy, typename DeviceAdapter>
VTKM_CONT_EXPORT
bool DoMapField(vtkm::filter::DataSetResult& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input,
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
const DeviceAdapter& tag);
};
}
} // namespace vtkm::filter
#include <vtkm/filter/ExternalFaces.hxx>
#endif // vtk_m_filter_Threshold_h

@ -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<typename T, typename U, typename V, typename W>
void operator()(const vtkm::cont::CellSetExplicit<T,U,V,W>& cellset ) const
{
vtkm::cont::ArrayHandle<vtkm::UInt8> shapes;
vtkm::cont::ArrayHandle<vtkm::IdComponent> numIndices;
vtkm::cont::ArrayHandle<vtkm::Id> conn;
vtkm::cont::ArrayHandle<vtkm::UInt8> output_shapes;
vtkm::cont::ArrayHandle<vtkm::IdComponent> output_numIndices;
vtkm::cont::ArrayHandle<vtkm::Id> 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<typename T>
void operator()(const T& ) const
{
//don't support this cell type
*this->Valid = false;
}
};
}
//-----------------------------------------------------------------------------
ExternalFaces::ExternalFaces():
vtkm::filter::DataSetFilter<ExternalFaces>()
{
}
//-----------------------------------------------------------------------------
template<typename DerivedPolicy,
typename DeviceAdapter>
vtkm::filter::DataSetResult ExternalFaces::DoExecute(const vtkm::cont::DataSet& input,
const vtkm::filter::PolicyBase<DerivedPolicy>& 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<DeviceAdapter> 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<typename T,
typename StorageType,
typename DerivedPolicy,
typename DeviceAdapter>
bool ExternalFaces::DoMapField(vtkm::filter::DataSetResult&,
const vtkm::cont::ArrayHandle<T, StorageType>&,
const vtkm::filter::FieldMetadata&,
const vtkm::filter::PolicyBase<DerivedPolicy>&,
const DeviceAdapter&)
{
return false;
}
}
}

130
vtkm/filter/FieldFilter.h Normal file

@ -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 <vtkm/cont/DataSet.h>
#include <vtkm/cont/CoordinateSystem.h>
#include <vtkm/cont/Field.h>
#include <vtkm/filter/PolicyBase.h>
#include <vtkm/filter/internal/RuntimeDeviceTracker.h>
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<typename T, typename StorageTag>
VTKM_CONT_EXPORT
bool FieldAs(vtkm::cont::ArrayHandle<T, StorageTag>& dest) const;
template<typename T, typename StorageTag, typename DerivedPolicy>
VTKM_CONT_EXPORT
bool FieldAs(vtkm::cont::ArrayHandle<T, StorageTag>& dest,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy) const;
private:
bool Valid;
vtkm::cont::Field Field;
};
template<class Derived>
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<typename DerivedPolicy>
VTKM_CONT_EXPORT
FieldResult Execute(const vtkm::cont::DataSet &input,
const std::string &inFieldName,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy );
template<typename DerivedPolicy>
VTKM_CONT_EXPORT
FieldResult Execute(const vtkm::cont::DataSet &input,
const vtkm::cont::Field &field,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy );
template<typename DerivedPolicy>
VTKM_CONT_EXPORT
FieldResult Execute(const vtkm::cont::DataSet &input,
const vtkm::cont::CoordinateSystem &field,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy );
private:
template<typename DerivedPolicy>
VTKM_CONT_EXPORT
FieldResult PrepareForExecution(const vtkm::cont::DataSet& input,
const vtkm::cont::Field& field,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy);
template<typename DerivedPolicy>
VTKM_CONT_EXPORT
FieldResult PrepareForExecution(const vtkm::cont::DataSet& input,
const vtkm::cont::CoordinateSystem& field,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy);
std::string OutputFieldName;
vtkm::filter::internal::RuntimeDeviceTracker Tracker;
};
}
} // namespace vtkm::filter
#include <vtkm/filter/FieldFilter.hxx>
#endif // vtk_m_filter_FieldFilter_h

181
vtkm/filter/FieldFilter.hxx Normal file

@ -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 <vtkm/filter/DefaultPolicy.h>
#include <vtkm/filter/FieldMetadata.h>
#include <vtkm/filter/FilterTraits.h>
#include <vtkm/filter/internal/ResolveFieldTypeAndExecute.h>
#include <vtkm/cont/Error.h>
#include <vtkm/cont/ErrorControlBadAllocation.h>
#include <vtkm/cont/ErrorExecution.h>
#include <vtkm/cont/cuda/DeviceAdapterCuda.h>
#include <vtkm/cont/tbb/DeviceAdapterTBB.h>
namespace vtkm {
namespace filter {
//-----------------------------------------------------------------------------
template<typename T, typename StorageTag>
bool FieldResult::FieldAs(vtkm::cont::ArrayHandle<T, StorageTag>& dest) const
{
return this->FieldAs(dest, vtkm::filter::DefaultPolicy());
}
//-----------------------------------------------------------------------------
template<typename T, typename StorageTag, typename DerivedPolicy>
bool FieldResult::FieldAs(vtkm::cont::ArrayHandle<T, StorageTag>& dest,
const vtkm::filter::PolicyBase<DerivedPolicy>&) 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<typename Derived>
FieldResult FieldFilter<Derived>::Execute(const vtkm::cont::DataSet &input,
const std::string &inFieldName)
{
return this->Execute(input,
input.GetField(inFieldName),
vtkm::filter::DefaultPolicy());
}
//-----------------------------------------------------------------------------
template<typename Derived>
FieldResult FieldFilter<Derived>::Execute(const vtkm::cont::DataSet &input,
const vtkm::cont::Field &field)
{
return this->Execute(input,
field,
vtkm::filter::DefaultPolicy());
}
//-----------------------------------------------------------------------------
template<typename Derived>
FieldResult FieldFilter<Derived>::Execute(const vtkm::cont::DataSet &input,
const vtkm::cont::CoordinateSystem &field)
{
return this->Execute(input,
field,
vtkm::filter::DefaultPolicy());
}
//-----------------------------------------------------------------------------
template<typename Derived>
template<typename DerivedPolicy>
FieldResult FieldFilter<Derived>::Execute(const vtkm::cont::DataSet &input,
const std::string &inFieldName,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy )
{
return this->Execute(input,
input.GetField(inFieldName),
policy);
}
//-----------------------------------------------------------------------------
template<typename Derived>
template<typename DerivedPolicy>
FieldResult FieldFilter<Derived>::Execute(const vtkm::cont::DataSet &input,
const vtkm::cont::Field &field,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy )
{
return this->PrepareForExecution(input, field, policy);
}
//-----------------------------------------------------------------------------
template<typename Derived>
template<typename DerivedPolicy>
FieldResult FieldFilter<Derived>::Execute(const vtkm::cont::DataSet &input,
const vtkm::cont::CoordinateSystem &field,
const vtkm::filter::PolicyBase<DerivedPolicy>& 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<typename Derived>
template<typename DerivedPolicy>
FieldResult FieldFilter<Derived>::PrepareForExecution(const vtkm::cont::DataSet &input,
const vtkm::cont::Field &field,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy )
{
//determine the field type first
FieldResult result;
typedef internal::ResolveFieldTypeAndExecute< Derived, DerivedPolicy,
FieldResult > FunctorType;
FunctorType functor(static_cast<Derived*>(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<typename Derived>
template<typename DerivedPolicy>
FieldResult FieldFilter<Derived>::PrepareForExecution(const vtkm::cont::DataSet &input,
const vtkm::cont::CoordinateSystem &field,
const vtkm::filter::PolicyBase<DerivedPolicy>& 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<Derived*>(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;
}
}
}

105
vtkm/filter/FieldMetadata.h Normal file

@ -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 <vtkm/cont/Field.h>
#include <vtkm/cont/CoordinateSystem.h>
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<typename T, typename StorageTag>
VTKM_CONT_EXPORT
vtkm::cont::Field AsField(const vtkm::cont::ArrayHandle<T,StorageTag> &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

88
vtkm/filter/FieldTypes.h Normal file

@ -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 <vtkm/filter/PolicyBase.h>
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

@ -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 <vtkm/TypeListTag.h>
namespace vtkm {
namespace filter {
template<typename Filter>
class FilterTraits
{
public:
//A filter can specify a set of data type that it supports for
//the input array
typedef vtkm::TypeListTagCommon InputFieldTypeList;
};
}
}
#endif

111
vtkm/filter/MarchingCubes.h Normal file

@ -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 <vtkm/filter/DataSetWithFieldFilter.h>
#include <vtkm/worklet/MarchingCubes.h>
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<MarchingCubes>
{
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<typename T, typename StorageType, typename DerivedPolicy, typename DeviceAdapter>
VTKM_CONT_EXPORT
vtkm::filter::DataSetResult DoExecute(const vtkm::cont::DataSet& input,
const vtkm::cont::ArrayHandle<T, StorageType>& field,
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
const DeviceAdapter& tag);
//Map a new field onto the resulting dataset after running the filter
//this call is only valid
template<typename T, typename StorageType, typename DerivedPolicy, typename DeviceAdapter>
VTKM_CONT_EXPORT
bool DoMapField(vtkm::filter::DataSetResult& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input,
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
const DeviceAdapter& tag);
private:
double IsoValue;
bool MergeDuplicatePoints;
bool GenerateNormals;
vtkm::cont::ArrayHandle<vtkm::IdComponent> EdgeTable;
vtkm::cont::ArrayHandle<vtkm::IdComponent> NumTrianglesTable;
vtkm::cont::ArrayHandle<vtkm::IdComponent> TriangleTable;
vtkm::cont::ArrayHandle<vtkm::FloatDefault> InterpolationWeights;
vtkm::cont::ArrayHandle<vtkm::Id2> InterpolationIds;
};
template<>
class FilterTraits<MarchingCubes>
{
public:
struct TypeListTagMCScalars : vtkm::ListTagBase<vtkm::UInt8, vtkm::Int8,
vtkm::Float32,vtkm::Float64> { };
typedef TypeListTagMCScalars InputFieldTypeList;
};
}
} // namespace vtkm::filter
#include <vtkm/filter/MarchingCubes.hxx>
#endif // vtk_m_filter_MarchingCubes_h

@ -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 <vtkm/cont/ArrayHandleIndex.h>
#include <vtkm/cont/ArrayHandleZip.h>
#include <vtkm/cont/DynamicCellSet.h>
#include <vtkm/cont/CellSetSingleType.h>
#include <vtkm/worklet/DispatcherMapTopology.h>
#include <vtkm/worklet/ScatterCounting.h>
namespace
{
typedef vtkm::Vec< vtkm::Id2, 3 > Vec3Id2;
typedef vtkm::Vec< vtkm::Vec<vtkm::Float32,3>, 3 > FVec3x3;
typedef vtkm::Vec< vtkm::Vec<vtkm::Float64,3>, 3 > DVec3x3;
typedef vtkm::filter::FilterTraits<vtkm::filter::MarchingCubes>::InputFieldTypeList InputTypes;
struct InterpolateIdTypes : vtkm::ListTagBase< Vec3Id2 > { };
struct Vec3FloatTypes : vtkm::ListTagBase< FVec3x3, DVec3x3> { };
// -----------------------------------------------------------------------------
template<typename S>
vtkm::cont::ArrayHandle<vtkm::Float32,S> make_ScalarField(const vtkm::cont::ArrayHandle<vtkm::Float32,S>& ah)
{ return ah; }
template<typename S>
vtkm::cont::ArrayHandle<vtkm::Float64,S> make_ScalarField(const vtkm::cont::ArrayHandle<vtkm::Float64,S>& ah)
{ return ah; }
template<typename S>
vtkm::cont::ArrayHandleCast<vtkm::FloatDefault, vtkm::cont::ArrayHandle<vtkm::UInt8,S> >
make_ScalarField(const vtkm::cont::ArrayHandle<vtkm::UInt8,S>& ah)
{ return vtkm::cont::make_ArrayHandleCast(ah, vtkm::FloatDefault()); }
template<typename S>
vtkm::cont::ArrayHandleCast<vtkm::FloatDefault, vtkm::cont::ArrayHandle<vtkm::Int8,S> >
make_ScalarField(const vtkm::cont::ArrayHandle<vtkm::Int8,S>& ah)
{ return vtkm::cont::make_ArrayHandleCast(ah, vtkm::FloatDefault()); }
// -----------------------------------------------------------------------------
template<typename T, typename U>
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<InputTypes> 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<typename FieldInType,
typename NumTrianglesTablePortalType>
VTKM_EXEC_EXPORT
void operator()(const FieldInType &fieldIn,
vtkm::IdComponent &numTriangles,
const NumTrianglesTablePortalType &numTrianglesTable) const
{
typedef typename vtkm::VecTraits<FieldInType>::ComponentType FieldType;
const FieldType iso = static_cast<FieldType>(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<typename FieldType>
struct PortalTypes
{
public:
typedef vtkm::cont::ArrayHandle<FieldType> HandleType;
typedef typename HandleType::template ExecutionTypes<DeviceAdapter> 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<vtkm::Id2>& 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<vtkm::FloatDefault>::Portal InterpWeightsPortal;
typename PortalTypes<vtkm::Id2>::Portal InterpIdPortal;
typename PortalTypes<vtkm::IdComponent>::PortalConst EdgeTable;
typename PortalTypes<vtkm::IdComponent>::PortalConst NumTriTable;
typename PortalTypes<vtkm::IdComponent>::PortalConst TriTable;
ScatterType Scatter;
};
/// \brief Compute the weights for each edge that is used to generate
/// a point in the resulting iso-surface
// -----------------------------------------------------------------------------
template<typename DeviceAdapter>
class EdgeWeightGenerate : public vtkm::worklet::WorkletMapPointToCell
{
public:
typedef typename EdgeWeightGenerateMetaData<DeviceAdapter>::ScatterType ScatterType;
typedef void ControlSignature(
TopologyIn topology, // Cell set
FieldInPoint<Scalar> fieldIn, // Input point field defining the contour
FieldInPoint<Vec3> 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<DeviceAdapter>& meta) :
Isovalue(isovalue),
GenerateNormals(genNormals),
MetaData( meta )
{
}
template<typename CellShapeTag,
typename FieldInType, // Vec-like, one per input point
typename CoordType,
typename IndicesVecType>
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<FieldInType>::ComponentType FieldType;
const FieldType iso = static_cast<FieldType>(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<vtkm::Id>(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<vtkm::FloatDefault>(iso - fieldValue0) /
static_cast<vtkm::FloatDefault>(fieldValue1 - fieldValue0);
//need to factor in outputCellId
MetaData.InterpWeightsPortal.Set(outputPointId+triVertex, interpolant);
if(this->GenerateNormals)
{
const vtkm::Vec<vtkm::FloatDefault,3> edgePCoord0 =
vtkm::exec::ParametricCoordinatesPoint(
fieldIn.GetNumberOfComponents(), edgeVertex0, shape, *this);
const vtkm::Vec<vtkm::FloatDefault,3> edgePCoord1 =
vtkm::exec::ParametricCoordinatesPoint(
fieldIn.GetNumberOfComponents(), edgeVertex1, shape, *this);
const vtkm::Vec<vtkm::FloatDefault,3> 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<DeviceAdapter> 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 <typename WeightType, typename InFieldPortalType, typename OutFieldType>
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<MarchingCubes>(),
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<typename T,
typename StorageType,
typename DerivedPolicy,
typename DeviceAdapter>
vtkm::filter::DataSetResult MarchingCubes::DoExecute(const vtkm::cont::DataSet& input,
const vtkm::cont::ArrayHandle<T, StorageType>& field,
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& 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>,
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<vtkm::IdComponent> 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<DeviceAdapter> metaData(
scatter.GetOutputRange(numOutputTrisPerCell.GetNumberOfValues()),
normals,
this->InterpolationWeights,
this->InterpolationIds,
this->EdgeTable,
this->NumTrianglesTable,
this->TriangleTable,
scatter);
EdgeWeightGenerate<DeviceAdapter> 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<vtkm::FloatDefault> WeightHandleType;
if(this->MergeDuplicatePoints)
{
typedef vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter> 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<WeightHandleType, Vec3HandleType> 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<Id2HandleType, KeyType> 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<Id2HandleType, WeightHandleType> 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<ApplyToField,
DeviceAdapter> applyFieldDispatcher(applyToField);
applyFieldDispatcher.Invoke(unqiueIds,
this->InterpolationWeights,
vtkm::filter::ApplyPolicy(coords, policy),
vertices);
}
else
{
ApplyToField applyToField;
vtkm::worklet::DispatcherMapField<ApplyToField,
DeviceAdapter> 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<typename T,
typename StorageType,
typename DerivedPolicy,
typename DeviceAdapter>
bool MarchingCubes::DoMapField(vtkm::filter::DataSetResult& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input,
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>&,
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<ApplyToField,
DeviceAdapter> applyFieldDispatcher(applyToField);
//todo: need to use the policy to get the correct storage tag for output
vtkm::cont::ArrayHandle<T> 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

@ -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 <vtkm/filter/FieldFilter.h>
#include <vtkm/worklet/PointElevation.h>
namespace vtkm {
namespace filter {
class PointElevation : public vtkm::filter::FieldFilter<PointElevation>
{
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<typename T, typename StorageType, typename DerivedPolicy, typename DeviceAdapter>
VTKM_CONT_EXPORT
vtkm::filter::FieldResult DoExecute(const vtkm::cont::DataSet &input,
const vtkm::cont::ArrayHandle<T, StorageType> &field,
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
const DeviceAdapter& tag);
private:
vtkm::worklet::PointElevation Worklet;
};
template<>
class FilterTraits<PointElevation>
{
public:
//Point Elevation can only convert Float and Double Vec3 arrays
typedef vtkm::TypeListTagFieldVec3 InputFieldTypeList;
};
}
} // namespace vtkm::filter
#include <vtkm/filter/PointElevation.hxx>
#endif // vtk_m_filter_PointElevation_h

@ -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 <vtkm/worklet/DispatcherMapField.h>
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<typename T,
typename StorageType,
typename DerivedPolicy,
typename DeviceAdapter>
vtkm::filter::FieldResult
PointElevation::DoExecute(const vtkm::cont::DataSet &,
const vtkm::cont::ArrayHandle<T,StorageType> &field,
const vtkm::filter::FieldMetadata&,
const vtkm::filter::PolicyBase<DerivedPolicy>&,
const DeviceAdapter&)
{
vtkm::cont::ArrayHandle<vtkm::Float64> outArray;
vtkm::worklet::DispatcherMapField<vtkm::worklet::PointElevation,
DeviceAdapter > 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

123
vtkm/filter/PolicyBase.h Normal file

@ -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 <vtkm/cont/CoordinateSystem.h>
#include <vtkm/cont/DynamicCellSet.h>
#include <vtkm/cont/Field.h>
#include <vtkm/filter/FilterTraits.h>
namespace vtkm {
namespace filter {
template<typename Derived>
class PolicyBase
{
};
//-----------------------------------------------------------------------------
template<typename DerivedPolicy>
VTKM_CONT_EXPORT
vtkm::cont::DynamicArrayHandleBase<
typename DerivedPolicy::FieldTypeList,
typename DerivedPolicy::FieldStorageList
>
ApplyPolicy(const vtkm::cont::Field& field,
const vtkm::filter::PolicyBase<DerivedPolicy>&)
{
typedef typename DerivedPolicy::FieldTypeList TypeList;
typedef typename DerivedPolicy::FieldStorageList StorageList;
return field.GetData().ResetTypeAndStorageLists(TypeList(),StorageList());
}
//-----------------------------------------------------------------------------
template<typename DerivedPolicy, typename FilterType>
VTKM_CONT_EXPORT
vtkm::cont::DynamicArrayHandleBase<
typename vtkm::filter::FilterTraits<FilterType>::InputFieldTypeList,
typename DerivedPolicy::FieldStorageList
>
ApplyPolicy(const vtkm::cont::Field& field,
const vtkm::filter::PolicyBase<DerivedPolicy>&,
const vtkm::filter::FilterTraits<FilterType>&)
{
//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<FilterType>::InputFieldTypeList TypeList;
// typedef typename DerivedPolicy::FieldTypeList TypeList;
typedef typename DerivedPolicy::FieldStorageList StorageList;
return field.GetData().ResetTypeAndStorageLists(TypeList(),StorageList());
}
//-----------------------------------------------------------------------------
template<typename DerivedPolicy>
VTKM_CONT_EXPORT
vtkm::cont::DynamicArrayHandleBase<
typename DerivedPolicy::CoordinateTypeList,
typename DerivedPolicy::CoordinateStorageList
>
ApplyPolicy(const vtkm::cont::CoordinateSystem& coordinates,
const vtkm::filter::PolicyBase<DerivedPolicy>&)
{
typedef typename DerivedPolicy::CoordinateTypeList TypeList;
typedef typename DerivedPolicy::CoordinateStorageList StorageList;
return coordinates.GetData().ResetTypeAndStorageLists(TypeList(),StorageList());
}
//-----------------------------------------------------------------------------
template<typename DerivedPolicy, typename FilterType>
VTKM_CONT_EXPORT
vtkm::cont::DynamicArrayHandleBase<
typename vtkm::filter::FilterTraits<FilterType>::InputFieldTypeList,
typename DerivedPolicy::CoordinateStorageList
>
ApplyPolicy(const vtkm::cont::CoordinateSystem& coordinates,
const vtkm::filter::PolicyBase<DerivedPolicy>&,
const vtkm::filter::FilterTraits<FilterType>&)
{
//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<FilterType>::InputFieldTypeList TypeList;
// typedef typename DerivedPolicy::CoordinateTypeList TypeList;
typedef typename DerivedPolicy::CoordinateStorageList StorageList;
return coordinates.GetData().ResetTypeAndStorageLists(TypeList(),StorageList());
}
//-----------------------------------------------------------------------------
template<typename DerivedPolicy>
VTKM_CONT_EXPORT
vtkm::cont::DynamicCellSetBase< typename DerivedPolicy::CellSetList >
ApplyPolicy(const vtkm::cont::DynamicCellSet& cellset,
const vtkm::filter::PolicyBase<DerivedPolicy>&)
{
typedef typename DerivedPolicy::CellSetList CellSetList;
return cellset.ResetCellSetList(CellSetList());
}
}
}
#endif

77
vtkm/filter/Threshold.h Normal file

@ -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 <vtkm/filter/DataSetWithFieldFilter.h>
#include <vtkm/worklet/Threshold.h>
namespace vtkm {
namespace filter {
class Threshold : public vtkm::filter::DataSetWithFieldFilter<Threshold>
{
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<typename T, typename StorageType, typename DerivedPolicy, typename DeviceAdapter>
VTKM_CONT_EXPORT
vtkm::filter::DataSetResult DoExecute(const vtkm::cont::DataSet& input,
const vtkm::cont::ArrayHandle<T, StorageType>& field,
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
const DeviceAdapter& tag);
//Map a new field onto the resulting dataset after running the filter
//this call is only valid
template<typename T, typename StorageType, typename DerivedPolicy, typename DeviceAdapter>
VTKM_CONT_EXPORT
bool DoMapField(vtkm::filter::DataSetResult& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input,
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
const DeviceAdapter& tag);
private:
double LowerValue;
double UpperValue;
vtkm::cont::ArrayHandle<vtkm::Id> ValidCellIds;
};
}
} // namespace vtkm::filter
#include <vtkm/filter/Threshold.hxx>
#endif // vtk_m_filter_Threshold_h

194
vtkm/filter/Threshold.hxx Normal file

@ -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 <vtkm/cont/DynamicCellSet.h>
#include <vtkm/cont/ArrayHandlePermutation.h>
#include <vtkm/cont/CellSetPermutation.h>
#include <vtkm/worklet/DispatcherMapTopology.h>
namespace
{
class ThresholdRange
{
public:
VTKM_CONT_EXPORT
ThresholdRange(const vtkm::Float64& lower,
const vtkm::Float64& upper) :
Lower(lower),
Upper(upper)
{ }
template<typename T>
VTKM_EXEC_EXPORT
bool operator()(const T& value) const
{
return value >= static_cast<T>(this->Lower) &&
value <= static_cast<T>(this->Upper);
}
private:
vtkm::Float64 Lower;
vtkm::Float64 Upper;
};
class AddPermutationCellSet
{
vtkm::cont::DataSet* Output;
vtkm::cont::ArrayHandle<vtkm::Id>* ValidIds;
public:
AddPermutationCellSet(vtkm::cont::DataSet& data,
vtkm::cont::ArrayHandle<vtkm::Id>& validIds):
Output(&data),
ValidIds(&validIds)
{ }
template<typename CellSetType>
void operator()(const CellSetType& cellset ) const
{
typedef vtkm::cont::CellSetPermutation<vtkm::cont::ArrayHandle<vtkm::Id>,
CellSetType> PermutationCellSetType;
PermutationCellSetType permCellSet(*this->ValidIds, cellset,
cellset.GetName(),
cellset.GetDimensionality());
this->Output->AddCellSet(permCellSet);
}
};
}
namespace vtkm {
namespace filter {
//-----------------------------------------------------------------------------
Threshold::Threshold():
vtkm::filter::DataSetWithFieldFilter<Threshold>(),
LowerValue(0),
UpperValue(0),
ValidCellIds()
{
}
//-----------------------------------------------------------------------------
template<typename T,
typename StorageType,
typename DerivedPolicy,
typename DeviceAdapter>
vtkm::filter::DataSetResult Threshold::DoExecute(const vtkm::cont::DataSet& input,
const vtkm::cont::ArrayHandle<T, StorageType>& field,
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& 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<bool> passFlags;
if(fieldMeta.IsPointField())
{
typedef vtkm::worklet::Threshold Worklets;
typedef Worklets::ThresholdByPointField< ThresholdRange > ThresholdWorklet;
ThresholdWorklet worklet(predicate);
vtkm::worklet::DispatcherMapTopology<ThresholdWorklet, DeviceAdapter> 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<ThresholdWorklet, DeviceAdapter> 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<DeviceAdapter> 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<typename T,
typename StorageType,
typename DerivedPolicy,
typename DeviceAdapter>
bool Threshold::DoMapField(vtkm::filter::DataSetResult& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input,
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>&,
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::Id>,
vtkm::cont::ArrayHandle<T, StorageType> > PermutationType;
PermutationType permutation =
vtkm::cont::make_ArrayHandlePermutation(this->ValidCellIds, input);
result.GetDataSet().AddField( fieldMeta.AsField(permutation) );
return true;
}
return false;
}
}
}

@ -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 <vtkm/filter/DataSetFilter.h>
#include <vtkm/worklet/VertexClustering.h>
namespace vtkm {
namespace filter {
class VertexClustering : public vtkm::filter::DataSetFilter<VertexClustering>
{
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<typename DerivedPolicy, typename DeviceAdapter>
VTKM_CONT_EXPORT
vtkm::filter::DataSetResult DoExecute(const vtkm::cont::DataSet& input,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
const DeviceAdapter& tag);
//Map a new field onto the resulting dataset after running the filter
//this call is only valid
template<typename T, typename StorageType, typename DerivedPolicy, typename DeviceAdapter>
VTKM_CONT_EXPORT
bool DoMapField(vtkm::filter::DataSetResult& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input,
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
const DeviceAdapter& tag);
private:
vtkm::Id3 NumberOfDivisions;
};
}
} // namespace vtkm::filter
#include <vtkm/filter/VertexClustering.hxx>
#endif // vtk_m_filter_Threshold_h

@ -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<typename DerivedPolicy,
typename DeviceAdapter>
void compute_bounds(const vtkm::cont::CoordinateSystem& coords,
vtkm::Float64 *bounds,
const vtkm::filter::PolicyBase<DerivedPolicy>&,
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<VertexClustering>(),
NumberOfDivisions(256, 256, 256)
{
}
//-----------------------------------------------------------------------------
template<typename DerivedPolicy,
typename DeviceAdapter>
vtkm::filter::DataSetResult VertexClustering::DoExecute(const vtkm::cont::DataSet& input,
const vtkm::filter::PolicyBase<DerivedPolicy>& 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<typename T,
typename StorageType,
typename DerivedPolicy,
typename DeviceAdapter>
bool VertexClustering::DoMapField(vtkm::filter::DataSetResult&,
const vtkm::cont::ArrayHandle<T, StorageType>&,
const vtkm::filter::FieldMetadata&,
const vtkm::filter::PolicyBase<DerivedPolicy>&,
const DeviceAdapter&)
{
return false;
}
}
}

@ -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})

@ -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 <vtkm/cont/DataSet.h>
#include <vtkm/cont/internal/DeviceAdapterTag.h>
#include <vtkm/filter/FieldMetadata.h>
#include <vtkm/filter/PolicyBase.h>
#include <vtkm/filter/internal/RuntimeDeviceTracker.h>
namespace
{
template<typename ReturnType, bool> struct CanExecute;
template<typename ReturnType,
typename ClassType,
typename ArrayType,
typename DerivedPolicy,
typename DeviceAdapterTag
>
ReturnType run_if_valid(ClassType* c,
const vtkm::cont::DataSet& ds,
const ArrayType &field,
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
vtkm::filter::internal::RuntimeDeviceTracker& tracker,
DeviceAdapterTag tag)
{
typedef vtkm::cont::DeviceAdapterTraits<
DeviceAdapterTag> DeviceAdapterTraits;
typedef CanExecute<ReturnType, DeviceAdapterTraits::Valid> CanExecuteType;
return CanExecuteType::Run(c,ds,field,fieldMeta,policy,tracker,tag);
}
template<typename ReturnType,
typename ClassType,
typename DerivedPolicy,
typename DeviceAdapterTag
>
ReturnType run_if_valid(ClassType* c,
const vtkm::cont::DataSet& ds,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
vtkm::filter::internal::RuntimeDeviceTracker& tracker,
DeviceAdapterTag tag)
{
typedef vtkm::cont::DeviceAdapterTraits<
DeviceAdapterTag> DeviceAdapterTraits;
typedef CanExecute<ReturnType, DeviceAdapterTraits::Valid> CanExecuteType;
return CanExecuteType::Run(c,ds,policy,tracker,tag);
}
//Implementation that we call on device adapters we don't have support
//enabled for
template<typename ReturnType>
struct CanExecute<ReturnType, false>
{
template<typename ClassType,
typename ArrayType,
typename DerivedPolicy,
typename DeviceAdapterTag>
static ReturnType Run(ClassType*,
const vtkm::cont::DataSet &,
const ArrayType &,
const vtkm::filter::FieldMetadata&,
const vtkm::filter::PolicyBase<DerivedPolicy>&,
vtkm::filter::internal::RuntimeDeviceTracker&,
DeviceAdapterTag)
{
return ReturnType();
}
template<typename ClassType,
typename DerivedPolicy,
typename DeviceAdapterTag>
static ReturnType Run(ClassType*,
const vtkm::cont::DataSet &,
const vtkm::filter::PolicyBase<DerivedPolicy>&,
vtkm::filter::internal::RuntimeDeviceTracker&,
DeviceAdapterTag)
{
return ReturnType();
}
};
//Implementation that we call on device adapters we do have support
//enabled for
template<typename ReturnType>
struct CanExecute<ReturnType,true>
{
template<typename ClassType,
typename ArrayType,
typename DerivedPolicy,
typename DeviceAdapterTag>
static ReturnType Run(ClassType* c,
const vtkm::cont::DataSet &input,
const ArrayType &field,
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& 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<typename ClassType,
typename DerivedPolicy,
typename DeviceAdapterTag>
static ReturnType Run(ClassType* c,
const vtkm::cont::DataSet &input,
const vtkm::filter::PolicyBase<DerivedPolicy>& 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<typename Derived, typename DerivedPolicy, typename ResultType>
struct ResolveFieldTypeAndExecute
{
Derived* DerivedClass;
const vtkm::cont::DataSet &InputData;
const vtkm::filter::FieldMetadata& Metadata;
const vtkm::filter::PolicyBase<DerivedPolicy>& 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<DerivedPolicy>& policy,
vtkm::filter::internal::RuntimeDeviceTracker& tracker,
ResultType& result):
DerivedClass(derivedClass),
InputData(inputData),
Metadata(fieldMeta),
Policy(policy),
Tracker(tracker),
Result(result)
{
}
template<typename T, typename StorageTag>
void operator()(const vtkm::cont::ArrayHandle<T,StorageTag>& field) const
{
typedef vtkm::cont::DeviceAdapterTagCuda CudaTag;
typedef vtkm::cont::DeviceAdapterTagTBB TBBTag;
typedef vtkm::cont::DeviceAdapterTagSerial SerialTag;
{
Result = run_if_valid<ResultType>( this->DerivedClass,
this->InputData,
field,
this->Metadata,
this->Policy,
this->Tracker,
CudaTag() );
}
if( !Result.IsValid() )
{
Result = run_if_valid<ResultType>( this->DerivedClass,
this->InputData,
field,
this->Metadata,
this->Policy,
this->Tracker,
TBBTag() );
}
if( !Result.IsValid() )
{
Result = run_if_valid<ResultType>( this->DerivedClass,
this->InputData,
field,
this->Metadata,
this->Policy,
this->Tracker,
SerialTag() );
}
}
};
}
}
}
} // namespace vtkm::filter::internal
#endif //vtk_m_filter_internal_ResolveFieldTypeAndExecute_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 <vtkm/cont/DataSet.h>
#include <vtkm/cont/internal/DeviceAdapterTag.h>
#include <vtkm/filter/FieldMetadata.h>
#include <vtkm/filter/PolicyBase.h>
#include <vtkm/filter/internal/RuntimeDeviceTracker.h>
//forward declarations needed
namespace vtkm {
namespace filter {
class DataSetResult;
}
}
namespace
{
template<bool> struct CanMap;
template<typename ClassType,
typename ArrayType,
typename DerivedPolicy,
typename DeviceAdapterTag
>
bool map_if_valid(ClassType* c,
vtkm::filter::DataSetResult& input,
const ArrayType &field,
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
vtkm::filter::internal::RuntimeDeviceTracker& tracker,
DeviceAdapterTag tag)
{
typedef vtkm::cont::DeviceAdapterTraits<
DeviceAdapterTag> DeviceAdapterTraits;
typedef CanMap<DeviceAdapterTraits::Valid> 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<false>
{
template<typename ClassType,
typename ArrayType,
typename DerivedPolicy,
typename DeviceAdapterTag>
static bool Run(ClassType*,
vtkm::filter::DataSetResult&,
const ArrayType &,
const vtkm::filter::FieldMetadata&,
const vtkm::filter::PolicyBase<DerivedPolicy>&,
vtkm::filter::internal::RuntimeDeviceTracker&,
DeviceAdapterTag)
{
return false;
}
};
//Implementation that we call on device adapters we do have support
//enabled for
template<>
struct CanMap<true>
{
template<typename ClassType,
typename ArrayType,
typename DerivedPolicy,
typename DeviceAdapterTag>
static bool Run(ClassType* c,
vtkm::filter::DataSetResult& input,
const ArrayType &field,
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& 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<typename Derived, typename DerivedPolicy>
struct ResolveFieldTypeAndMap
{
Derived* DerivedClass;
vtkm::filter::DataSetResult& InputResult;
const vtkm::filter::FieldMetadata& Metadata;
const vtkm::filter::PolicyBase<DerivedPolicy>& Policy;
vtkm::filter::internal::RuntimeDeviceTracker& Tracker;
bool& RanProperly;
ResolveFieldTypeAndMap(Derived* derivedClass,
vtkm::filter::DataSetResult& inResult,
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
vtkm::filter::internal::RuntimeDeviceTracker& tracker,
bool& ran):
DerivedClass(derivedClass),
InputResult(inResult),
Metadata(fieldMeta),
Policy(policy),
Tracker(tracker),
RanProperly(ran)
{
}
template<typename T, typename StorageTag>
void operator()(const vtkm::cont::ArrayHandle<T,StorageTag>& 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

@ -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 <vtkm/cont/ErrorControlBadAllocation.h>
#include <vtkm/cont/RuntimeDeviceInformation.h>
#include <vtkm/cont/DeviceAdapter.h>
#include <vtkm/cont/DeviceAdapterSerial.h>
#include <vtkm/cont/cuda/DeviceAdapterCuda.h>
#include <vtkm/cont/tbb/DeviceAdapterTBB.h>
#include <cstring>
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<typename DeviceAdapterTag>
bool CanRunOn(DeviceAdapterTag) const
{
typedef vtkm::cont::DeviceAdapterTraits<DeviceAdapterTag> 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<typename DeviceAdapterTag>
void ReportAllocationFailure(DeviceAdapterTag,
const vtkm::cont::ErrorControlBadAllocation&)
{
typedef vtkm::cont::DeviceAdapterTraits<DeviceAdapterTag> 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<CudaTag> CudaTraits;
vtkm::cont::RuntimeDeviceInformation<CudaTag> runtimeDevice;
this->RuntimeValid[ CudaTraits::GetId() ] = runtimeDevice.Exists();
}
{
typedef vtkm::cont::DeviceAdapterTagTBB TBBTag;
typedef vtkm::cont::DeviceAdapterTraits<TBBTag> TBBTraits;
vtkm::cont::RuntimeDeviceInformation<TBBTag> runtimeDevice;
this->RuntimeValid[ TBBTraits::GetId() ] = runtimeDevice.Exists();
}
{
typedef vtkm::cont::DeviceAdapterTagSerial SerialTag;
typedef vtkm::cont::DeviceAdapterTraits<SerialTag> SerialTraits;
vtkm::cont::RuntimeDeviceInformation<SerialTag> 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

@ -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})

@ -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 <vtkm/filter/CellAverage.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/cont/testing/MakeTestDataSet.h>
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<vtkm::Float32> 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<vtkm::Float32> 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<vtkm::Float32> 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);
}

@ -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 <vtkm/cont/testing/MakeTestDataSet.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/filter/ExternalFaces.h>
using vtkm::cont::testing::MakeTestDataSet;
namespace {
void TestExternalFacesExplicitGrid()
{
vtkm::cont::DataSet ds;
const int nVerts = 8; //A cube that is tetrahedralized
typedef vtkm::Vec<vtkm::Float32,3> 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<vtkm::UInt8> shapes;
vtkm::cont::ArrayHandle<vtkm::IdComponent> numIndices;
vtkm::cont::ArrayHandle<vtkm::Id> conn;
shapes.Allocate(static_cast<vtkm::Id>(nCells));
numIndices.Allocate(static_cast<vtkm::Id>(nCells));
conn.Allocate(static_cast<vtkm::Id>(4 * nCells));
int index = 0;
for(int j = 0; j < nCells; j++)
{
shapes.GetPortalControl().Set(j, static_cast<vtkm::UInt8>(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<vtkm::cont::CellSetExplicit<> >();
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);
}

@ -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 <vtkm/filter/CellAverage.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/cont/testing/MakeTestDataSet.h>
namespace {
vtkm::cont::Field makeCellField()
{
return vtkm::cont::Field("foo", 1, vtkm::cont::Field::ASSOC_CELL_SET,
std::string(), vtkm::cont::ArrayHandle<vtkm::Float32>() );
}
vtkm::cont::Field makePointField()
{
return vtkm::cont::Field("foo", 1, vtkm::cont::Field::ASSOC_POINTS,
vtkm::cont::ArrayHandle<vtkm::Float32>() );
}
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);
}

@ -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 <vtkm/Math.h>
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
#include <vtkm/cont/CellSetSingleType.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/cont/DynamicArrayHandle.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/filter/MarchingCubes.h>
namespace {
class TangleField : public vtkm::worklet::WorkletMapField
{
public:
typedef void ControlSignature(FieldIn<IdType> vertexId, FieldOut<Scalar> 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<vtkm::FloatDefault>(x) / static_cast<vtkm::FloatDefault>(xdim-1);
const vtkm::FloatDefault fy = static_cast<vtkm::FloatDefault>(y) / static_cast<vtkm::FloatDefault>(xdim-1);
const vtkm::FloatDefault fz = static_cast<vtkm::FloatDefault>(z) / static_cast<vtkm::FloatDefault>(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<vtkm::Float32> fieldArray;
vtkm::cont::ArrayHandleIndex vertexCountImplicitArray(vdims[0]*vdims[1]*vdims[2]);
vtkm::worklet::DispatcherMapField<TangleField> tangleFieldDispatcher(TangleField(vdims, mins, maxs));
tangleFieldDispatcher.Invoke(vertexCountImplicitArray, fieldArray);
vtkm::Vec<vtkm::FloatDefault,3> origin(0.0f, 0.0f, 0.0f);
vtkm::Vec<vtkm::FloatDefault,3> spacing(
1.0f/static_cast<vtkm::FloatDefault>(dims[0]),
1.0f/static_cast<vtkm::FloatDefault>(dims[2]),
1.0f/static_cast<vtkm::FloatDefault>(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<ndim> 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<vtkm::Float32,3> reference):Reference(reference) {}
VTKM_EXEC_CONT_EXPORT
vtkm::Float32 operator()(vtkm::Vec<vtkm::Float32,3> v) const
{
vtkm::Vec<vtkm::Float32,3> d(v[0]-this->Reference[0],
v[1]-this->Reference[1],
v[2]-this->Reference[2]);
return vtkm::Magnitude(d);
}
private:
vtkm::Vec<vtkm::Float32,3> 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<HexTag> 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<vtkm::Float32,
vtkm::cont::ArrayHandleUniformPointCoordinates,
EuclideanNorm> DataArrayHandle;
typedef vtkm::cont::ArrayHandleTransform<vtkm::Id,
vtkm::cont::ArrayHandleCounting<vtkm::Id>,
CubeGridConnectivity> ConnectivityArrayHandle;
typedef vtkm::cont::CellSetSingleType<
vtkm::cont::ArrayHandleTransform<vtkm::Id,
vtkm::cont::ArrayHandleCounting<vtkm::Id>,
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<vtkm::Id,
vtkm::cont::ArrayHandleCounting<vtkm::Id>,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 <dim> 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<HexTag> HexTraits;
typedef vtkm::Vec<vtkm::Float32,3> 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<vtkm::Id>(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<CellSetType>();
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<IndexStorageTag> CellSetType;
const CellSetType& cells = dcells.Cast<CellSetType>();
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);
}

@ -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 <vtkm/filter/PointElevation.h>
#include <vtkm/cont/testing/Testing.h>
#include <vector>
namespace {
vtkm::cont::DataSet MakePointElevationTestDataSet()
{
vtkm::cont::DataSet dataSet;
std::vector<vtkm::Vec<vtkm::Float32,3> > coordinates;
const vtkm::Id dim = 5;
for (vtkm::Id j = 0; j < dim; ++j)
{
vtkm::Float32 z = static_cast<vtkm::Float32>(j) /
static_cast<vtkm::Float32>(dim - 1);
for (vtkm::Id i = 0; i < dim; ++i)
{
vtkm::Float32 x = static_cast<vtkm::Float32>(i) /
static_cast<vtkm::Float32>(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<vtkm::Id>(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<vtkm::Float64> resultArrayHandle;
const bool valid = result.FieldAs(resultArrayHandle);
if(valid)
{
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32,3> > 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<vtkm::Float64> resultArrayHandle;
const bool valid = result.FieldAs(resultArrayHandle, p);
if(valid)
{
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32,3> > 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);
}

@ -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 <vtkm/cont/testing/MakeTestDataSet.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/filter/Threshold.h>
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::Id>,
vtkm::cont::ArrayHandle<vtkm::Float32> > 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::Id>,
vtkm::cont::ArrayHandle<vtkm::Float32> > 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::Id>,
vtkm::cont::ArrayHandle<vtkm::Float32> > 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::Id>,
vtkm::cont::ArrayHandle<vtkm::Float32> > 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());
}

@ -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 <vtkm/cont/testing/MakeTestDataSet.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/filter/VertexClustering.h>
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<vtkm::Float64, 3> PointType;
vtkm::cont::ArrayHandle<PointType> 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);
}

@ -313,14 +313,16 @@ public:
///////////////////////////////////////////////////
/// \brief VertexClustering: Mesh simplification
///
template<typename DeviceAdapter>
vtkm::cont::DataSet Run(const vtkm::cont::DynamicCellSet &cellSet,
const vtkm::cont::CoordinateSystem &coordinates,
vtkm::Id nDivisions,
template<typename DynamicCellSetType,
typename DynamicCoordinateHandleType,
typename DeviceAdapter>
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<vtkm::Id> pointCidArray;
vtkm::worklet::DispatcherMapField<MapPointsWorklet, DeviceAdapter>(
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<vtkm::Id>,
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;

@ -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());