migrate clean_grid and extract_entity filters

This commit is contained in:
Li-Ta Lo 2022-01-06 14:52:27 -07:00
parent e5639b1f91
commit f5bbc6fc83
56 changed files with 1012 additions and 1665 deletions

@ -29,19 +29,19 @@
#include <vtkm/filter/CellAverage.h>
#include <vtkm/filter/Contour.h>
#include <vtkm/filter/ExternalFaces.h>
#include <vtkm/filter/FieldSelection.h>
#include <vtkm/filter/Gradient.h>
#include <vtkm/filter/PointAverage.h>
#include <vtkm/filter/PolicyBase.h>
#include <vtkm/filter/Tetrahedralize.h>
#include <vtkm/filter/Threshold.h>
#include <vtkm/filter/ThresholdPoints.h>
#include <vtkm/filter/Triangulate.h>
#include <vtkm/filter/VectorMagnitude.h>
#include <vtkm/filter/VertexClustering.h>
#include <vtkm/filter/WarpScalar.h>
#include <vtkm/filter/WarpVector.h>
#include <vtkm/filter/entity_extraction/ExternalFaces.h>
#include <vtkm/filter/entity_extraction/ThresholdPoints.h>
#include <vtkm/io/VTKDataSetReader.h>

@ -14,8 +14,8 @@
#include <vtkm/cont/BoundsGlobalCompute.h>
#include <vtkm/cont/EnvironmentTracker.h>
#include <vtkm/cont/Serialization.h>
#include <vtkm/filter/ExtractPoints.h>
#include <vtkm/filter/Filter.h>
#include <vtkm/filter/entity_extraction/ExtractPoints.h>
#include <vtkm/thirdparty/diy/diy.h>

@ -37,8 +37,6 @@ set(common_headers
FilterParticleAdvection.h
FilterTemporalParticleAdvection.h
FilterTraits.h
MapFieldMergeAverage.h
MapFieldPermutation.h
PolicyBase.h
PolicyDefault.h
TaskQueue.h
@ -50,9 +48,7 @@ set(common_headers
set(common_header_template_sources
CellAverage.hxx
CellMeasures.hxx
CleanGrid.hxx
ExtractGeometry.hxx
ExtractPoints.hxx
ExtractStructured.hxx
FilterDataSet.hxx
FilterDataSetWithField.hxx
@ -62,16 +58,12 @@ set(common_header_template_sources
FilterTemporalParticleAdvection.hxx
PointAverage.hxx
Threshold.hxx
ThresholdPoints.hxx
)
set(common_sources_device
CellAverage.cxx
CleanGrid.cxx
ExtractGeometry.cxx
ExtractStructured.cxx
MapFieldMergeAverage.cxx
MapFieldPermutation.cxx
PointAverage.cxx
Threshold.cxx
)
@ -100,7 +92,6 @@ set(extra_headers
Lagrangian.h
LagrangianStructures.h
Mask.h
MaskPoints.h
MeshQuality.h
MIRFilter.h
NDEntropy.h
@ -145,7 +136,6 @@ set(extra_header_template_sources
CoordinateSystemTransform.hxx
CrossProduct.hxx
Entropy.hxx
ExternalFaces.hxx
FieldToColors.hxx
GhostCellClassify.hxx
GhostCellRemove.hxx
@ -156,7 +146,6 @@ set(extra_header_template_sources
Lagrangian.hxx
LagrangianStructures.hxx
Mask.hxx
MaskPoints.hxx
MeshQuality.hxx
MIRFilter.hxx
NDEntropy.hxx
@ -191,7 +180,6 @@ set(extra_header_template_sources
set(extra_sources_device
${ClipWithFieldInstantiations}
${ClipWithImplicitFunctionInstantiations}
ExternalFaces.cxx
VectorMagnitude.cxx
particleadvection/Messenger.cxx
particleadvection/ParticleMessenger.cxx
@ -237,9 +225,13 @@ vtkm_pyexpander_generated_file(ClipWithImplicitFunctionExternInstantiations.h)
set(core_headers
NewFilter.h
NewFilterField.h
MapFieldMergeAverage.h
MapFieldPermutation.h
)
set(core_sources
NewFilterField.cxx
MapFieldMergeAverage.cxx
MapFieldPermutation.cxx
)
set(core_sources_device
NewFilter.cxx)
@ -318,7 +310,8 @@ target_link_libraries(vtkm_filter PUBLIC INTERFACE
install(TARGETS vtkm_filter EXPORT ${VTKm_EXPORT_NAME})
add_subdirectory(clean_grid)
add_subdirectory(entity_extraction)
add_subdirectory(internal)
add_subdirectory(particleadvection)
add_subdirectory(field_transform)

@ -1,167 +0,0 @@
//============================================================================
// 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.
//============================================================================
#define vtkm_filter_CleanGrid_cxx
#include <vtkm/filter/CleanGrid.h>
#include <vtkm/filter/CleanGrid.hxx>
#include <vtkm/filter/MapFieldMergeAverage.h>
#include <vtkm/filter/MapFieldPermutation.h>
namespace vtkm
{
namespace filter
{
//-----------------------------------------------------------------------------
CleanGrid::CleanGrid()
: CompactPointFields(true)
, MergePoints(true)
, Tolerance(1.0e-6)
, ToleranceIsAbsolute(false)
, RemoveDegenerateCells(true)
, FastMerge(true)
{
}
//-----------------------------------------------------------------------------
vtkm::cont::DataSet CleanGrid::GenerateOutput(const vtkm::cont::DataSet& inData,
vtkm::cont::CellSetExplicit<>& outputCellSet)
{
using VecId = std::size_t;
const VecId activeCoordIndex = static_cast<VecId>(this->GetActiveCoordinateSystemIndex());
const VecId numCoordSystems = static_cast<VecId>(inData.GetNumberOfCoordinateSystems());
std::vector<vtkm::cont::CoordinateSystem> outputCoordinateSystems(numCoordSystems);
// Start with a shallow copy of the coordinate systems
for (VecId coordSystemIndex = 0; coordSystemIndex < numCoordSystems; ++coordSystemIndex)
{
outputCoordinateSystems[coordSystemIndex] =
inData.GetCoordinateSystem(static_cast<vtkm::IdComponent>(coordSystemIndex));
}
// Optionally adjust the cell set indices to remove all unused points
if (this->GetCompactPointFields())
{
this->PointCompactor.FindPointsStart();
this->PointCompactor.FindPoints(outputCellSet);
this->PointCompactor.FindPointsEnd();
outputCellSet = this->PointCompactor.MapCellSet(outputCellSet);
for (VecId coordSystemIndex = 0; coordSystemIndex < numCoordSystems; ++coordSystemIndex)
{
outputCoordinateSystems[coordSystemIndex] =
vtkm::cont::CoordinateSystem(outputCoordinateSystems[coordSystemIndex].GetName(),
this->PointCompactor.MapPointFieldDeep(
outputCoordinateSystems[coordSystemIndex].GetData()));
}
}
// Optionally find and merge coincident points
if (this->GetMergePoints())
{
vtkm::cont::CoordinateSystem activeCoordSystem = outputCoordinateSystems[activeCoordIndex];
vtkm::Bounds bounds = activeCoordSystem.GetBounds();
vtkm::Float64 delta = this->GetTolerance();
if (!this->GetToleranceIsAbsolute())
{
delta *=
vtkm::Magnitude(vtkm::make_Vec(bounds.X.Length(), bounds.Y.Length(), bounds.Z.Length()));
}
auto coordArray = activeCoordSystem.GetData();
this->PointMerger.Run(delta, this->GetFastMerge(), bounds, coordArray);
activeCoordSystem = vtkm::cont::CoordinateSystem(activeCoordSystem.GetName(), coordArray);
for (VecId coordSystemIndex = 0; coordSystemIndex < numCoordSystems; ++coordSystemIndex)
{
if (coordSystemIndex == activeCoordIndex)
{
outputCoordinateSystems[coordSystemIndex] = activeCoordSystem;
}
else
{
outputCoordinateSystems[coordSystemIndex] = vtkm::cont::CoordinateSystem(
outputCoordinateSystems[coordSystemIndex].GetName(),
this->PointMerger.MapPointField(outputCoordinateSystems[coordSystemIndex].GetData()));
}
}
outputCellSet = this->PointMerger.MapCellSet(outputCellSet);
}
// Optionally remove degenerate cells
if (this->GetRemoveDegenerateCells())
{
outputCellSet = this->CellCompactor.Run(outputCellSet);
}
// Construct resulting data set with new cell sets
vtkm::cont::DataSet outData;
outData.SetCellSet(outputCellSet);
// Pass the coordinate systems
for (VecId coordSystemIndex = 0; coordSystemIndex < numCoordSystems; ++coordSystemIndex)
{
outData.AddCoordinateSystem(outputCoordinateSystems[coordSystemIndex]);
}
return outData;
}
bool CleanGrid::MapFieldOntoOutput(vtkm::cont::DataSet& result, const vtkm::cont::Field& field)
{
if (field.IsFieldPoint() && (this->GetCompactPointFields() || this->GetMergePoints()))
{
vtkm::cont::Field compactedField;
if (this->GetCompactPointFields())
{
bool success = vtkm::filter::MapFieldPermutation(
field, this->PointCompactor.GetPointScatter().GetOutputToInputMap(), compactedField);
if (!success)
{
return false;
}
}
else
{
compactedField = field;
}
if (this->GetMergePoints())
{
return vtkm::filter::MapFieldMergeAverage(
compactedField, this->PointMerger.GetMergeKeys(), result);
}
else
{
result.AddField(compactedField);
return true;
}
}
else if (field.IsFieldCell() && this->GetRemoveDegenerateCells())
{
return vtkm::filter::MapFieldPermutation(field, this->CellCompactor.GetValidCellIds(), result);
}
else
{
result.AddField(field);
return true;
}
}
//-----------------------------------------------------------------------------
template VTKM_FILTER_COMMON_TEMPLATE_EXPORT vtkm::cont::DataSet CleanGrid::DoExecute(
const vtkm::cont::DataSet& inData,
vtkm::filter::PolicyBase<vtkm::filter::PolicyDefault> policy);
}
}

@ -10,137 +10,28 @@
#ifndef vtk_m_filter_CleanGrid_h
#define vtk_m_filter_CleanGrid_h
#include <vtkm/filter/vtkm_filter_common_export.h>
#include <vtkm/filter/FilterDataSet.h>
#include <vtkm/worklet/PointMerge.h>
#include <vtkm/worklet/RemoveDegenerateCells.h>
#include <vtkm/worklet/RemoveUnusedPoints.h>
#include <vtkm/Deprecated.h>
#include <vtkm/filter/clean_grid/CleanGrid.h>
namespace vtkm
{
namespace filter
{
/// \brief Clean a mesh to an unstructured grid
///
/// This filter takes a data set and essentially copies it into a new data set.
/// The newly constructed data set will have the same cells as the input and
/// the topology will be stored in a \c CellSetExplicit<>. The filter will also
/// optionally remove all unused points.
///
/// Note that the result of \c CleanGrid is not necessarily smaller than the
/// input. For example, "cleaning" a data set with a \c CellSetStructured
/// topology will actually result in a much larger data set.
///
/// \todo Add a feature to merge points that are coincident or within a
/// tolerance.
///
class VTKM_FILTER_COMMON_EXPORT CleanGrid : public vtkm::filter::FilterDataSet<CleanGrid>
VTKM_DEPRECATED(1.8, "Use vtkm/filter/clean_grid/CleanGrid.h instead of vtkm/filter/CleanGrid.h.")
inline void CleanGrid_deprecated() {}
inline void CleanGrid_deprecated_warning()
{
public:
CleanGrid();
CleanGrid_deprecated();
}
VTKM_CONT
Filter* Clone() const override
{
CleanGrid* clone = new CleanGrid();
clone->CopyStateFrom(this);
return clone;
}
VTKM_CONT
bool CanThread() const override { return true; }
/// When the CompactPointFields flag is true, the filter will identify any
/// points that are not used by the topology. This is on by default.
///
VTKM_CONT bool GetCompactPointFields() const { return this->CompactPointFields; }
VTKM_CONT void SetCompactPointFields(bool flag) { this->CompactPointFields = flag; }
/// When the MergePoints flag is true, the filter will identify any coincident
/// points and merge them together. The distance two points can be to considered
/// coincident is set with the tolerance flags. This is on by default.
///
VTKM_CONT bool GetMergePoints() const { return this->MergePoints; }
VTKM_CONT void SetMergePoints(bool flag) { this->MergePoints = flag; }
/// Defines the tolerance used when determining whether two points are considered
/// coincident. If the ToleranceIsAbsolute flag is false (the default), then this
/// tolerance is scaled by the diagonal of the points.
///
VTKM_CONT vtkm::Float64 GetTolerance() const { return this->Tolerance; }
VTKM_CONT void SetTolerance(vtkm::Float64 tolerance) { this->Tolerance = tolerance; }
/// When ToleranceIsAbsolute is false (the default) then the tolerance is scaled
/// by the diagonal of the bounds of the dataset. If true, then the tolerance is
/// taken as the actual distance to use.
///
VTKM_CONT bool GetToleranceIsAbsolute() const { return this->ToleranceIsAbsolute; }
VTKM_CONT void SetToleranceIsAbsolute(bool flag) { this->ToleranceIsAbsolute = flag; }
/// Determine whether a cell is degenerate (that is, has repeated points that drops
/// its dimensionalit) and removes them. This is on by default.
///
VTKM_CONT bool GetRemoveDegenerateCells() const { return this->RemoveDegenerateCells; }
VTKM_CONT void SetRemoveDegenerateCells(bool flag) { this->RemoveDegenerateCells = flag; }
/// When FastMerge is true (the default), some corners are cut when computing
/// coincident points. The point merge will go faster but the tolerance will not
/// be strictly followed.
///
VTKM_CONT bool GetFastMerge() const { return this->FastMerge; }
VTKM_CONT void SetFastMerge(bool flag) { this->FastMerge = flag; }
template <typename Policy>
VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& inData,
vtkm::filter::PolicyBase<Policy> policy);
VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, const vtkm::cont::Field& field);
template <typename DerivedPolicy>
VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::Field& field,
vtkm::filter::PolicyBase<DerivedPolicy>)
{
return this->MapFieldOntoOutput(result, field);
}
VTKM_CONT
void CopyStateFrom(const CleanGrid* cleanGrid)
{
this->FilterDataSet<CleanGrid>::CopyStateFrom(cleanGrid);
this->CompactPointFields = cleanGrid->CompactPointFields;
this->MergePoints = cleanGrid->MergePoints;
this->Tolerance = cleanGrid->Tolerance;
this->ToleranceIsAbsolute = cleanGrid->ToleranceIsAbsolute;
this->RemoveDegenerateCells = cleanGrid->RemoveDegenerateCells;
this->FastMerge = cleanGrid->FastMerge;
}
private:
bool CompactPointFields;
bool MergePoints;
vtkm::Float64 Tolerance;
bool ToleranceIsAbsolute;
bool RemoveDegenerateCells;
bool FastMerge;
vtkm::cont::DataSet GenerateOutput(const vtkm::cont::DataSet& inData,
vtkm::cont::CellSetExplicit<>& outputCellSet);
vtkm::worklet::RemoveUnusedPoints PointCompactor;
vtkm::worklet::RemoveDegenerateCells CellCompactor;
vtkm::worklet::PointMerge PointMerger;
class VTKM_DEPRECATED(1.8, "Use vtkm::filter::clean_grid::CleanGrid.") CleanGrid
: public vtkm::filter::clean_grid::CleanGrid
{
using clean_grid::CleanGrid::CleanGrid;
};
#ifndef vtkm_filter_CleanGrid_cxx
extern template VTKM_FILTER_COMMON_TEMPLATE_EXPORT vtkm::cont::DataSet CleanGrid::DoExecute(
const vtkm::cont::DataSet&,
vtkm::filter::PolicyBase<vtkm::filter::PolicyDefault>);
#endif
}
} // namespace vtkm::filter

@ -1,75 +0,0 @@
//============================================================================
// 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.
//============================================================================
#ifndef vtkm_m_filter_CleanGrid_hxx
#define vtkm_m_filter_CleanGrid_hxx
#include <vtkm/worklet/CellDeepCopy.h>
#include <vtkm/worklet/RemoveUnusedPoints.h>
#include <vtkm/cont/ConvertNumComponentsToOffsets.h>
#include <vector>
namespace vtkm
{
namespace filter
{
template <typename Policy>
vtkm::cont::DataSet CleanGrid::DoExecute(const vtkm::cont::DataSet& inData,
vtkm::filter::PolicyBase<Policy> policy)
{
using CellSetType = vtkm::cont::CellSetExplicit<>;
CellSetType outputCellSet;
// Do a deep copy of the cells to new CellSetExplicit structures
const vtkm::cont::UnknownCellSet& inCellSet = inData.GetCellSet();
if (inCellSet.IsType<CellSetType>())
{
// Is expected type, do a shallow copy
outputCellSet = inCellSet.AsCellSet<CellSetType>();
}
else
{ // Clean the grid
auto deducedCellSet = vtkm::filter::ApplyPolicyCellSet(inCellSet, policy, *this);
vtkm::cont::ArrayHandle<vtkm::IdComponent> numIndices;
this->Invoke(worklet::CellDeepCopy::CountCellPoints{}, deducedCellSet, numIndices);
vtkm::cont::ArrayHandle<vtkm::UInt8> shapes;
vtkm::cont::ArrayHandle<vtkm::Id> offsets;
vtkm::Id connectivitySize;
vtkm::cont::ConvertNumComponentsToOffsets(numIndices, offsets, connectivitySize);
numIndices.ReleaseResourcesExecution();
vtkm::cont::ArrayHandle<vtkm::Id> connectivity;
connectivity.Allocate(connectivitySize);
this->Invoke(worklet::CellDeepCopy::PassCellStructure{},
deducedCellSet,
shapes,
vtkm::cont::make_ArrayHandleGroupVecVariable(connectivity, offsets));
shapes.ReleaseResourcesExecution();
offsets.ReleaseResourcesExecution();
connectivity.ReleaseResourcesExecution();
outputCellSet.Fill(deducedCellSet.GetNumberOfPoints(), shapes, connectivity, offsets);
//Release the input grid from the execution space
deducedCellSet.ReleaseResourcesExecution();
}
return this->GenerateOutput(inData, outputCellSet);
}
}
}
#endif

@ -7,84 +7,34 @@
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#ifndef vtk_m_filter_ExternalFaces_h
#define vtk_m_filter_ExternalFaces_h
#include <vtkm/filter/vtkm_filter_extra_export.h>
#include <vtkm/filter/CleanGrid.h>
#include <vtkm/filter/FilterDataSet.h>
#include <vtkm/filter/MapFieldPermutation.h>
#include <vtkm/worklet/ExternalFaces.h>
#include <vtkm/Deprecated.h>
#include <vtkm/filter/entity_extraction/ExternalFaces.h>
namespace vtkm
{
namespace filter
{
/// \brief Extract external faces of a geometry
///
/// ExternalFaces is a filter that extracts all external faces from a
/// data set. An external face is defined is defined as a face/side of a cell
/// that belongs only to one cell in the entire mesh.
/// @warning
/// This filter is currently only supports propagation of point properties
///
class VTKM_FILTER_EXTRA_EXPORT ExternalFaces : public vtkm::filter::FilterDataSet<ExternalFaces>
VTKM_DEPRECATED(
1.8,
"Use vtkm/filter/entity_extraction/ExternalFaces.h instead of vtkm/filter/ExternalFaces.h.")
inline void ExternalFaces_deprecated() {}
inline void ExternalFaces_deprecated_warning()
{
public:
ExternalFaces();
ExternalFaces_deprecated();
}
// When CompactPoints is set, instead of copying the points and point fields
// from the input, the filter will create new compact fields without the
// unused elements
VTKM_CONT
bool GetCompactPoints() const { return this->CompactPoints; }
VTKM_CONT
void SetCompactPoints(bool value) { this->CompactPoints = value; }
// When PassPolyData is set (the default), incoming poly data (0D, 1D, and 2D cells)
// will be passed to the output external faces data set.
VTKM_CONT
bool GetPassPolyData() const { return this->PassPolyData; }
VTKM_CONT
void SetPassPolyData(bool value)
{
this->PassPolyData = value;
this->Worklet.SetPassPolyData(value);
}
template <typename DerivedPolicy>
VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input,
vtkm::filter::PolicyBase<DerivedPolicy> policy);
VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, const vtkm::cont::Field& field);
template <typename DerivedPolicy>
VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::Field& field,
vtkm::filter::PolicyBase<DerivedPolicy>)
{
return this->MapFieldOntoOutput(result, field);
}
private:
bool CompactPoints;
bool PassPolyData;
vtkm::cont::DataSet GenerateOutput(const vtkm::cont::DataSet& input,
vtkm::cont::CellSetExplicit<>& outCellSet);
vtkm::filter::CleanGrid Compactor;
vtkm::worklet::ExternalFaces Worklet;
class VTKM_DEPRECATED(1.8, "Use vtkm::filter::entity_extraction::ExternalFaces.") ExternalFaces
: public vtkm::filter::entity_extraction::ExternalFaces
{
using entity_extraction::ExternalFaces::ExternalFaces;
};
#ifndef vtkm_filter_ExternalFaces_cxx
extern template VTKM_FILTER_EXTRA_TEMPLATE_EXPORT vtkm::cont::DataSet ExternalFaces::DoExecute(
const vtkm::cont::DataSet&,
vtkm::filter::PolicyBase<vtkm::filter::PolicyDefault>);
#endif
}
} // namespace vtkm::filter
#endif // vtk_m_filter_ExternalFaces_h
#endif //vtk_m_filter_ExternalFaces_h

@ -1,48 +0,0 @@
//============================================================================
// 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.
//============================================================================
#ifndef vtk_m_filter_ExternalFaces_hxx
#define vtk_m_filter_ExternalFaces_hxx
namespace vtkm
{
namespace filter
{
//-----------------------------------------------------------------------------
template <typename DerivedPolicy>
vtkm::cont::DataSet ExternalFaces::DoExecute(const vtkm::cont::DataSet& input,
vtkm::filter::PolicyBase<DerivedPolicy> policy)
{
//1. extract the cell set
const vtkm::cont::UnknownCellSet& cells = input.GetCellSet();
//2. using the policy convert the dynamic cell set, and run the
// external faces worklet
vtkm::cont::CellSetExplicit<> outCellSet;
if (cells.CanConvert<vtkm::cont::CellSetStructured<3>>())
{
this->Worklet.Run(cells.AsCellSet<vtkm::cont::CellSetStructured<3>>(),
input.GetCoordinateSystem(this->GetActiveCoordinateSystemIndex()),
outCellSet);
}
else
{
this->Worklet.Run(vtkm::filter::ApplyPolicyCellSetUnstructured(cells, policy, *this),
outCellSet);
}
return this->GenerateOutput(input, outCellSet);
}
}
}
#endif

@ -7,80 +7,34 @@
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#ifndef vtk_m_filter_ExtractPoints_h
#define vtk_m_filter_ExtractPoints_h
#include <vtkm/ImplicitFunction.h>
#ifndef VTKM_NO_DEPRECATED_VIRTUAL
#include <vtkm/cont/ImplicitFunctionHandle.h>
#endif //VTKM_NO_DEPRECATED_VIRTUAL
#include <vtkm/filter/CleanGrid.h>
#include <vtkm/filter/FilterDataSet.h>
#include <vtkm/worklet/ExtractPoints.h>
#include <vtkm/Deprecated.h>
#include <vtkm/filter/entity_extraction/ExtractPoints.h>
namespace vtkm
{
namespace filter
{
/// @brief Extract only points from a geometry using an implicit function
///
///
/// Extract only the points that are either inside or outside of a
/// VTK-m implicit function. Examples include planes, spheres, boxes,
/// etc.
/// Note that while any geometry type can be provided as input, the output is
/// represented by an explicit representation of points using
/// vtkm::cont::CellSetSingleType
class ExtractPoints : public vtkm::filter::FilterDataSet<ExtractPoints>
VTKM_DEPRECATED(
1.8,
"Use vtkm/filter/entity_extraction/ExtractPoints.h instead of vtkm/filter/ExtractPoints.h.")
inline void ExtractPoints_deprecated() {}
inline void ExtractPoints_deprecated_warning()
{
public:
VTKM_CONT
ExtractPoints();
ExtractPoints_deprecated();
}
/// When CompactPoints is set, instead of copying the points and point fields
/// from the input, the filter will create new compact fields without the unused elements
VTKM_CONT
bool GetCompactPoints() const { return this->CompactPoints; }
VTKM_CONT
void SetCompactPoints(bool value) { this->CompactPoints = value; }
/// Set the volume of interest to extract
void SetImplicitFunction(const vtkm::ImplicitFunctionGeneral& func) { this->Function = func; }
const vtkm::ImplicitFunctionGeneral& GetImplicitFunction() const { return this->Function; }
VTKM_CONT
bool GetExtractInside() { return this->ExtractInside; }
VTKM_CONT
void SetExtractInside(bool value) { this->ExtractInside = value; }
VTKM_CONT
void ExtractInsideOn() { this->ExtractInside = true; }
VTKM_CONT
void ExtractInsideOff() { this->ExtractInside = false; }
template <typename DerivedPolicy>
vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input,
vtkm::filter::PolicyBase<DerivedPolicy> policy);
//Map a new field onto the resulting dataset after running the filter
template <typename DerivedPolicy>
VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::Field& field,
vtkm::filter::PolicyBase<DerivedPolicy>);
private:
bool ExtractInside;
vtkm::ImplicitFunctionGeneral Function;
bool CompactPoints;
vtkm::filter::CleanGrid Compactor;
class VTKM_DEPRECATED(1.8, "Use vtkm::filter::entity_extraction::ExtractPoints.") ExtractPoints
: public vtkm::filter::entity_extraction::ExtractPoints
{
using entity_extraction::ExtractPoints::ExtractPoints;
};
}
} // namespace vtkm::filter
#include <vtkm/filter/ExtractPoints.hxx>
#endif // vtk_m_filter_ExtractPoints_h
#endif //vtk_m_filter_ExtractPoints_h

@ -7,58 +7,34 @@
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#ifndef vtk_m_filter_MaskPoints_h
#define vtk_m_filter_MaskPoints_h
#include <vtkm/filter/CleanGrid.h>
#include <vtkm/filter/FilterDataSet.h>
#include <vtkm/worklet/MaskPoints.h>
#include <vtkm/Deprecated.h>
#include <vtkm/filter/entity_extraction/MaskPoints.h>
namespace vtkm
{
namespace filter
{
/// \brief Subselect points using a stride
///
/// Extract only every Nth point where N is equal to a stride value
class MaskPoints : public vtkm::filter::FilterDataSet<MaskPoints>
VTKM_DEPRECATED(
1.8,
"Use vtkm/filter/entity_extraction/MaskPoints.h instead of vtkm/filter/MaskPoints.h.")
inline void MaskPoints_deprecated() {}
inline void MaskPoints_deprecated_warning()
{
public:
VTKM_CONT
MaskPoints();
MaskPoints_deprecated();
}
// When CompactPoints is set, instead of copying the points and point fields
// from the input, the filter will create new compact fields without the unused elements
VTKM_CONT
bool GetCompactPoints() const { return this->CompactPoints; }
VTKM_CONT
void SetCompactPoints(bool value) { this->CompactPoints = value; }
VTKM_CONT
vtkm::Id GetStride() const { return this->Stride; }
VTKM_CONT
void SetStride(vtkm::Id stride) { this->Stride = stride; }
template <typename DerivedPolicy>
VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input,
vtkm::filter::PolicyBase<DerivedPolicy> policy);
//Map a new field onto the resulting dataset after running the filter
template <typename DerivedPolicy>
VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::Field& field,
vtkm::filter::PolicyBase<DerivedPolicy>);
private:
vtkm::Id Stride;
bool CompactPoints;
vtkm::filter::CleanGrid Compactor;
class VTKM_DEPRECATED(1.8, "Use vtkm::filter::entity_extraction::MaskPoints.") MaskPoints
: public vtkm::filter::entity_extraction::MaskPoints
{
using entity_extraction::MaskPoints::MaskPoints;
};
}
} // namespace vtkm::filter
#include <vtkm/filter/MaskPoints.hxx>
#endif // vtk_m_filter_MaskPoints_h
#endif //vtk_m_filter_MaskPoints_h

@ -21,6 +21,8 @@ namespace filter
class VTKM_FILTER_CORE_EXPORT NewFilterField : public vtkm::filter::NewFilter
{
public:
NewFilterField() { this->SetActiveCoordinateSystem(0); }
VTKM_CONT
void SetOutputFieldName(const std::string& name) { this->OutputFieldName = name; }
@ -148,7 +150,7 @@ private:
std::vector<std::string> ActiveFieldNames;
std::vector<vtkm::cont::Field::Association> ActiveFieldAssociation;
std::vector<bool> UseCoordinateSystemAsField;
std::vector<vtkm ::Id> ActiveCoordinateSystemIndices;
std::vector<vtkm::Id> ActiveCoordinateSystemIndices;
};
} // namespace filter
} // namespace vtkm

@ -7,73 +7,34 @@
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#ifndef vtk_m_filter_ThresholdPoints_h
#define vtk_m_filter_ThresholdPoints_h
#include <vtkm/filter/CleanGrid.h>
#include <vtkm/filter/FilterDataSetWithField.h>
#include <vtkm/worklet/ThresholdPoints.h>
#include <vtkm/Deprecated.h>
#include <vtkm/filter/entity_extraction/ThresholdPoints.h>
namespace vtkm
{
namespace filter
{
class ThresholdPoints : public vtkm::filter::FilterDataSetWithField<ThresholdPoints>
VTKM_DEPRECATED(
1.8,
"Use vtkm/filter/entity_extraction/ThresholdPoints.h instead of vtkm/filter/ThresholdPoints.h.")
inline void ThresholdPoints_deprecated() {}
inline void ThresholdPoints_deprecated_warning()
{
public:
using SupportedTypes = vtkm::TypeListScalarAll;
ThresholdPoints_deprecated();
}
VTKM_CONT
ThresholdPoints();
// When CompactPoints is set, instead of copying the points and point fields
// from the input, the filter will create new compact fields without the unused elements
VTKM_CONT
bool GetCompactPoints() const { return this->CompactPoints; }
VTKM_CONT
void SetCompactPoints(bool value) { this->CompactPoints = value; }
VTKM_CONT
vtkm::Float64 GetLowerThreshold() const { return this->LowerValue; }
VTKM_CONT
void SetLowerThreshold(vtkm::Float64 value) { this->LowerValue = value; }
VTKM_CONT
vtkm::Float64 GetUpperThreshold() const { return this->UpperValue; }
VTKM_CONT
void SetUpperThreshold(vtkm::Float64 value) { this->UpperValue = value; }
VTKM_CONT
void SetThresholdBelow(const vtkm::Float64 value);
VTKM_CONT
void SetThresholdAbove(const vtkm::Float64 value);
VTKM_CONT
void SetThresholdBetween(const vtkm::Float64 value1, const vtkm::Float64 value2);
template <typename T, typename StorageType, typename DerivedPolicy>
VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input,
const vtkm::cont::ArrayHandle<T, StorageType>& field,
const vtkm::filter::FieldMetadata& fieldMeta,
vtkm::filter::PolicyBase<DerivedPolicy> policy);
template <typename DerivedPolicy>
VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::Field& field,
vtkm::filter::PolicyBase<DerivedPolicy>);
private:
double LowerValue;
double UpperValue;
int ThresholdType;
bool CompactPoints;
vtkm::filter::CleanGrid Compactor;
class VTKM_DEPRECATED(1.8, "Use vtkm::filter::entity_extraction::ThresholdPoints.") ThresholdPoints
: public vtkm::filter::entity_extraction::ThresholdPoints
{
using entity_extraction::ThresholdPoints::ThresholdPoints;
};
}
} // namespace vtkm::filter
#include <vtkm/filter/ThresholdPoints.hxx>
#endif // vtk_m_filter_ThresholdPoints_h
#endif //vtk_m_filter_ThresholdPoints_h

@ -0,0 +1,30 @@
##============================================================================
## 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.
##============================================================================
set(clean_grid_headers
CleanGrid.h)
set(clean_grid_sources_device
CleanGrid.cxx)
vtkm_library(
NAME vtkm_filter_clean_grid
HEADERS ${clean_grid_headers}
DEVICE_SOURCES ${clean_grid_sources_device}
USE_VTKM_JOB_POOL
)
target_link_libraries(vtkm_filter_clean_grid PUBLIC vtkm_worklet vtkm_filter_core)
target_link_libraries(vtkm_filter PUBLIC INTERFACE vtkm_filter_clean_grid)
add_subdirectory(worklet)
#-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -
if (VTKm_ENABLE_TESTING)
add_subdirectory(testing)
endif ()

@ -0,0 +1,241 @@
//============================================================================
// 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.
//============================================================================
#include <vtkm/filter/MapFieldMergeAverage.h>
#include <vtkm/filter/MapFieldPermutation.h>
#include <vtkm/filter/clean_grid/CleanGrid.h>
#include <vtkm/filter/clean_grid/worklet/PointMerge.h>
#include <vtkm/filter/clean_grid/worklet/RemoveDegenerateCells.h>
#include <vtkm/filter/clean_grid/worklet/RemoveUnusedPoints.h>
namespace vtkm
{
namespace filter
{
namespace clean_grid
{
struct SharedStates
{
vtkm::worklet::RemoveUnusedPoints PointCompactor;
vtkm::worklet::RemoveDegenerateCells CellCompactor;
vtkm::worklet::PointMerge PointMerger;
};
}
//-----------------------------------------------------------------------------
vtkm::cont::DataSet CleanGrid::GenerateOutput(const vtkm::cont::DataSet& inData,
vtkm::cont::CellSetExplicit<>& outputCellSet,
clean_grid::SharedStates& Worklets)
{
using VecId = std::size_t;
const auto activeCoordIndex = static_cast<VecId>(this->GetActiveCoordinateSystemIndex());
const auto numCoordSystems = static_cast<VecId>(inData.GetNumberOfCoordinateSystems());
std::vector<vtkm::cont::CoordinateSystem> outputCoordinateSystems(numCoordSystems);
// Start with a shallow copy of the coordinate systems
for (VecId coordSystemIndex = 0; coordSystemIndex < numCoordSystems; ++coordSystemIndex)
{
outputCoordinateSystems[coordSystemIndex] =
inData.GetCoordinateSystem(static_cast<vtkm::IdComponent>(coordSystemIndex));
}
// Optionally adjust the cell set indices to remove all unused points
if (this->GetCompactPointFields())
{
Worklets.PointCompactor.FindPointsStart();
Worklets.PointCompactor.FindPoints(outputCellSet);
Worklets.PointCompactor.FindPointsEnd();
outputCellSet = Worklets.PointCompactor.MapCellSet(outputCellSet);
for (VecId coordSystemIndex = 0; coordSystemIndex < numCoordSystems; ++coordSystemIndex)
{
outputCoordinateSystems[coordSystemIndex] =
vtkm::cont::CoordinateSystem(outputCoordinateSystems[coordSystemIndex].GetName(),
Worklets.PointCompactor.MapPointFieldDeep(
outputCoordinateSystems[coordSystemIndex].GetData()));
}
}
// Optionally find and merge coincident points
if (this->GetMergePoints())
{
vtkm::cont::CoordinateSystem activeCoordSystem = outputCoordinateSystems[activeCoordIndex];
vtkm::Bounds bounds = activeCoordSystem.GetBounds();
vtkm::Float64 delta = this->GetTolerance();
if (!this->GetToleranceIsAbsolute())
{
delta *=
vtkm::Magnitude(vtkm::make_Vec(bounds.X.Length(), bounds.Y.Length(), bounds.Z.Length()));
}
auto coordArray = activeCoordSystem.GetData();
Worklets.PointMerger.Run(delta, this->GetFastMerge(), bounds, coordArray);
activeCoordSystem = vtkm::cont::CoordinateSystem(activeCoordSystem.GetName(), coordArray);
for (VecId coordSystemIndex = 0; coordSystemIndex < numCoordSystems; ++coordSystemIndex)
{
if (coordSystemIndex == activeCoordIndex)
{
outputCoordinateSystems[coordSystemIndex] = activeCoordSystem;
}
else
{
outputCoordinateSystems[coordSystemIndex] = vtkm::cont::CoordinateSystem(
outputCoordinateSystems[coordSystemIndex].GetName(),
Worklets.PointMerger.MapPointField(outputCoordinateSystems[coordSystemIndex].GetData()));
}
}
outputCellSet = Worklets.PointMerger.MapCellSet(outputCellSet);
}
// Optionally remove degenerate cells
if (this->GetRemoveDegenerateCells())
{
outputCellSet = Worklets.CellCompactor.Run(outputCellSet);
}
// Construct resulting data set with new cell sets
vtkm::cont::DataSet outData;
outData.SetCellSet(outputCellSet);
// Pass the coordinate systems
for (VecId coordSystemIndex = 0; coordSystemIndex < numCoordSystems; ++coordSystemIndex)
{
outData.AddCoordinateSystem(outputCoordinateSystems[coordSystemIndex]);
}
return outData;
}
// New Filter Design: DoMapField is now a free function in an anonymous namespace. It should be
// considered as a convenience/extension to the lambda passed to the MapFieldsOntoOutput.
// Being a free function discourages the developer to "pass" mutable states from DoExecute phase
// to DoMapField phase via data member. However, there is nothing to prevent developer doing
// stupid thing to circumvent the protection. One example here is that the developer could
// always pass a mutable reference/pointer to the filter instance and thus pass mutable state
// across the DoExecute and DoMapField boundary. We need to explicitly discourage developer
// trying to do such a thing in the manual.
namespace
{
bool DoMapField(vtkm::cont::DataSet& result,
const vtkm::cont::Field& field,
const CleanGrid& self,
clean_grid::SharedStates& worklets)
{
if (field.IsFieldPoint() && (self.GetCompactPointFields() || self.GetMergePoints()))
{
vtkm::cont::Field compactedField;
if (self.GetCompactPointFields())
{
bool success = vtkm::filter::MapFieldPermutation(
field, worklets.PointCompactor.GetPointScatter().GetOutputToInputMap(), compactedField);
if (!success)
{
return false;
}
}
else
{
compactedField = field;
}
if (self.GetMergePoints())
{
return vtkm::filter::MapFieldMergeAverage(
compactedField, worklets.PointMerger.GetMergeKeys(), result);
}
else
{
result.AddField(compactedField);
return true;
}
}
else if (field.IsFieldCell() && self.GetRemoveDegenerateCells())
{
return vtkm::filter::MapFieldPermutation(
field, worklets.CellCompactor.GetValidCellIds(), result);
}
else
{
result.AddField(field);
return true;
}
}
} // anonymous namespace
vtkm::cont::DataSet CleanGrid::DoExecute(const vtkm::cont::DataSet& inData)
{
// New Filter Design: mutable states that was a data member of the filter is now a local
// variable. Each invocation of DoExecute() in the std::async will have a copy of Worklets
// thus making it thread-safe.
clean_grid::SharedStates Worklets;
using CellSetType = vtkm::cont::CellSetExplicit<>;
CellSetType outputCellSet;
vtkm::cont::UnknownCellSet inCellSet = inData.GetCellSet();
if (inCellSet.IsType<CellSetType>())
{
// Is expected type, do a shallow copy
outputCellSet = inCellSet.AsCellSet<CellSetType>();
}
else
{ // Clean the grid
vtkm::cont::ArrayHandle<vtkm::IdComponent> numIndices;
this->Invoke(worklet::CellDeepCopy::CountCellPoints{}, inCellSet, numIndices);
vtkm::cont::ArrayHandle<vtkm::UInt8> shapes;
vtkm::cont::ArrayHandle<vtkm::Id> offsets;
vtkm::Id connectivitySize;
vtkm::cont::ConvertNumComponentsToOffsets(numIndices, offsets, connectivitySize);
numIndices.ReleaseResourcesExecution();
vtkm::cont::ArrayHandle<vtkm::Id> connectivity;
connectivity.Allocate(connectivitySize);
this->Invoke(worklet::CellDeepCopy::PassCellStructure{},
inCellSet,
shapes,
vtkm::cont::make_ArrayHandleGroupVecVariable(connectivity, offsets));
shapes.ReleaseResourcesExecution();
offsets.ReleaseResourcesExecution();
connectivity.ReleaseResourcesExecution();
outputCellSet.Fill(inCellSet.GetNumberOfPoints(), shapes, connectivity, offsets);
//Release the input grid from the execution space
inCellSet.ReleaseResourcesExecution();
}
// New Filter Design: The share, mutable state is pass to other methods via parameter, not as
// a data member.
auto outData = this->GenerateOutput(inData, outputCellSet, Worklets);
// New Filter Design: We pass the actions needed to be done as a lambda to the generic
// MapFieldsOntoOutput method. MapFieldsOntoOutput now acts as thrust::transform_if on the
// Fields. Shared mutable state is captured by the lambda. We could also put all the logic
// of field mapping in the lambda. However, it is cleaner to put it in the filter specific
// implementation of DoMapField which takes mutable state as an extra parameter.
//
// For filters that do not need to do interpolation for mapping fields, we provide an overload
// that does not take the extra arguments and just AddField.
auto mapper = [&, this](auto& output, const auto& field) {
DoMapField(output, field, *this, Worklets);
};
MapFieldsOntoOutput(inData, outData, mapper);
return outData;
}
}
}

@ -0,0 +1,103 @@
//============================================================================
// 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.
//============================================================================
#ifndef vtk_m_filter_clean_grid_CleanGrid_h
#define vtk_m_filter_clean_grid_CleanGrid_h
#include <vtkm/filter/NewFilterField.h>
#include <vtkm/filter/clean_grid/vtkm_filter_clean_grid_export.h>
namespace vtkm
{
namespace filter
{
// Forward declaration for stateful Worklets
namespace clean_grid
{
struct SharedStates;
}
/// \brief Clean a mesh to an unstructured grid
///
/// This filter takes a data set and essentially copies it into a new data set.
/// The newly constructed data set will have the same cells as the input and
/// the topology will be stored in a \c CellSetExplicit<>. The filter will also
/// optionally remove all unused points.
///
/// Note that the result of \c CleanGrid is not necessarily smaller than the
/// input. For example, "cleaning" a data set with a \c CellSetStructured
/// topology will actually result in a much larger data set.
///
/// \todo Add a feature to merge points that are coincident or within a
/// tolerance.
///
class VTKM_FILTER_CLEAN_GRID_EXPORT CleanGrid : public vtkm::filter::NewFilterField
{
public:
/// When the CompactPointFields flag is true, the filter will identify any
/// points that are not used by the topology. This is on by default.
///
VTKM_CONT bool GetCompactPointFields() const { return this->CompactPointFields; }
VTKM_CONT void SetCompactPointFields(bool flag) { this->CompactPointFields = flag; }
/// When the MergePoints flag is true, the filter will identify any coincident
/// points and merge them together. The distance two points can be to considered
/// coincident is set with the tolerance flags. This is on by default.
///
VTKM_CONT bool GetMergePoints() const { return this->MergePoints; }
VTKM_CONT void SetMergePoints(bool flag) { this->MergePoints = flag; }
/// Defines the tolerance used when determining whether two points are considered
/// coincident. If the ToleranceIsAbsolute flag is false (the default), then this
/// tolerance is scaled by the diagonal of the points.
///
VTKM_CONT vtkm::Float64 GetTolerance() const { return this->Tolerance; }
VTKM_CONT void SetTolerance(vtkm::Float64 tolerance) { this->Tolerance = tolerance; }
/// When ToleranceIsAbsolute is false (the default) then the tolerance is scaled
/// by the diagonal of the bounds of the dataset. If true, then the tolerance is
/// taken as the actual distance to use.
///
VTKM_CONT bool GetToleranceIsAbsolute() const { return this->ToleranceIsAbsolute; }
VTKM_CONT void SetToleranceIsAbsolute(bool flag) { this->ToleranceIsAbsolute = flag; }
/// Determine whether a cell is degenerate (that is, has repeated points that drops
/// its dimensionalit) and removes them. This is on by default.
///
VTKM_CONT bool GetRemoveDegenerateCells() const { return this->RemoveDegenerateCells; }
VTKM_CONT void SetRemoveDegenerateCells(bool flag) { this->RemoveDegenerateCells = flag; }
/// When FastMerge is true (the default), some corners are cut when computing
/// coincident points. The point merge will go faster but the tolerance will not
/// be strictly followed.
///
VTKM_CONT bool GetFastMerge() const { return this->FastMerge; }
VTKM_CONT void SetFastMerge(bool flag) { this->FastMerge = flag; }
private:
VTKM_CONT
vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& inData) override;
VTKM_CONT vtkm::cont::DataSet GenerateOutput(const vtkm::cont::DataSet& inData,
vtkm::cont::CellSetExplicit<>& outputCellSet,
clean_grid::SharedStates& worklets);
bool CompactPointFields = true;
bool MergePoints = true;
vtkm::Float64 Tolerance = 1.0e-6;
bool ToleranceIsAbsolute = false;
bool RemoveDegenerateCells = true;
bool FastMerge = true;
};
} // namespace filter
} // namespace vtkm
#endif //vtk_m_filter_clean_grid_CleanGrid_h

@ -0,0 +1,22 @@
##============================================================================
## 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.
##============================================================================
set(unit_tests
UnitTestCleanGrid.cxx)
set(libraries
vtkm_filter_clean_grid
vtkm_filter_contour)
vtkm_unit_tests(
SOURCES ${unit_tests}
LIBRARIES ${libraries}
USE_VTKM_JOB_POOL
)

@ -8,7 +8,7 @@
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#include <vtkm/filter/CleanGrid.h>
#include <vtkm/filter/clean_grid/CleanGrid.h>
#include <vtkm/filter/Contour.h>

@ -0,0 +1,16 @@
##============================================================================
## 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.
##============================================================================
set(headers
PointMerge.h
RemoveDegenerateCells.h
RemoveUnusedPoints.h)
vtkm_declare_headers(${headers})

@ -10,11 +10,11 @@
#ifndef vtk_m_worklet_PointMerge_h
#define vtk_m_worklet_PointMerge_h
#include <vtkm/filter/clean_grid/worklet/RemoveUnusedPoints.h>
#include <vtkm/worklet/AverageByKey.h>
#include <vtkm/worklet/DispatcherMapField.h>
#include <vtkm/worklet/DispatcherReduceByKey.h>
#include <vtkm/worklet/Keys.h>
#include <vtkm/worklet/RemoveUnusedPoints.h>
#include <vtkm/worklet/WorkletMapField.h>
#include <vtkm/worklet/WorkletReduceByKey.h>

@ -0,0 +1,38 @@
##============================================================================
## 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.
##============================================================================
set(entity_extraction_headers
ExternalFaces.h
ExtractPoints.h
MaskPoints.h
ThresholdPoints.h
)
set(entity_extraction_sources_device
ExternalFaces.cxx
ExtractPoints.cxx
MaskPoints.cxx
ThresholdPoints.cxx
)
vtkm_library(
NAME vtkm_filter_entity_extraction
HEADERS ${entity_extraction_headers}
DEVICE_SOURCES ${entity_extraction_sources_device}
USE_VTKM_JOB_POOL
)
target_link_libraries(vtkm_filter_entity_extraction PUBLIC vtkm_worklet vtkm_filter_core)
target_link_libraries(vtkm_filter PUBLIC INTERFACE vtkm_filter_entity_extraction)
add_subdirectory(worklet)
#-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -
if (VTKm_ENABLE_TESTING)
add_subdirectory(testing)
endif ()

@ -1,4 +1,3 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
@ -8,33 +7,38 @@
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#define vtkm_filter_ExternalFaces_cxx
#include <vtkm/filter/ExternalFaces.h>
#include <vtkm/filter/ExternalFaces.hxx>
#include <vtkm/cont/UncertainCellSet.h>
#include <vtkm/filter/MapFieldPermutation.h>
#include <vtkm/filter/clean_grid/CleanGrid.h>
#include <vtkm/filter/entity_extraction/ExternalFaces.h>
#include <vtkm/filter/entity_extraction/worklet/ExternalFaces.h>
namespace vtkm
{
namespace filter
{
//-----------------------------------------------------------------------------
ExternalFaces::ExternalFaces()
: vtkm::filter::FilterDataSet<ExternalFaces>()
, CompactPoints(false)
, Worklet()
: Worklet(std::make_unique<vtkm::worklet::ExternalFaces>())
{
this->SetPassPolyData(true);
}
ExternalFaces::~ExternalFaces() = default;
//-----------------------------------------------------------------------------
void ExternalFaces::SetPassPolyData(bool value)
{
this->PassPolyData = value;
this->Worklet->SetPassPolyData(value);
}
//-----------------------------------------------------------------------------
vtkm::cont::DataSet ExternalFaces::GenerateOutput(const vtkm::cont::DataSet& input,
vtkm::cont::CellSetExplicit<>& outCellSet)
{
//This section of ExternalFaces is independent of any input so we can build it
//into the vtkm_filter library
//3. Check the fields of the dataset to see what kinds of fields are present so
//3. Check the fields of the dataset to see what kinds of fields are present, so
// we can free the cell mapping array if it won't be needed.
const vtkm::Id numFields = input.GetNumberOfFields();
bool hasCellFields = false;
@ -46,7 +50,7 @@ vtkm::cont::DataSet ExternalFaces::GenerateOutput(const vtkm::cont::DataSet& inp
if (!hasCellFields)
{
this->Worklet.ReleaseCellMapArrays();
this->Worklet->ReleaseCellMapArrays();
}
//4. create the output dataset
@ -54,11 +58,47 @@ vtkm::cont::DataSet ExternalFaces::GenerateOutput(const vtkm::cont::DataSet& inp
output.SetCellSet(outCellSet);
output.AddCoordinateSystem(input.GetCoordinateSystem(this->GetActiveCoordinateSystemIndex()));
return output;
}
//-----------------------------------------------------------------------------
vtkm::cont::DataSet ExternalFaces::DoExecute(const vtkm::cont::DataSet& input)
{
//1. extract the cell set
const vtkm::cont::UnknownCellSet& cells = input.GetCellSet();
//2. using the policy convert the dynamic cell set, and run the
// external faces worklet
vtkm::cont::CellSetExplicit<> outCellSet;
if (cells.CanConvert<vtkm::cont::CellSetStructured<3>>())
{
this->Worklet->Run(cells.AsCellSet<vtkm::cont::CellSetStructured<3>>(),
input.GetCoordinateSystem(this->GetActiveCoordinateSystemIndex()),
outCellSet);
}
else
{
this->Worklet->Run(cells.ResetCellSetList<VTKM_DEFAULT_CELL_SET_LIST_UNSTRUCTURED>(),
outCellSet);
}
// New Filter Design: we generate new output and map the fields first.
auto output = this->GenerateOutput(input, outCellSet);
auto mapper = [&, this](auto& result, const auto& f) {
// New Design: We are still using the old MapFieldOntoOutput to demonstrate the transition
this->MapFieldOntoOutput(result, f);
};
MapFieldsOntoOutput(input, output, mapper);
// New Filter Design: then we remove entities if requested.
if (this->CompactPoints)
{
this->Compactor.SetCompactPointFields(true);
this->Compactor.SetMergePoints(false);
return this->Compactor.Execute(output);
vtkm::filter::CleanGrid Compactor;
Compactor.SetCompactPointFields(true);
Compactor.SetMergePoints(false);
return Compactor.Execute(output);
}
else
{
@ -70,19 +110,12 @@ bool ExternalFaces::MapFieldOntoOutput(vtkm::cont::DataSet& result, const vtkm::
{
if (field.IsFieldPoint())
{
if (this->CompactPoints)
{
return this->Compactor.MapFieldOntoOutput(result, field);
}
else
{
result.AddField(field);
return true;
}
result.AddField(field);
return true;
}
else if (field.IsFieldCell())
{
return vtkm::filter::MapFieldPermutation(field, this->Worklet.GetCellIdMap(), result);
return vtkm::filter::MapFieldPermutation(field, this->Worklet->GetCellIdMap(), result);
}
else if (field.IsFieldGlobal())
{
@ -95,9 +128,5 @@ bool ExternalFaces::MapFieldOntoOutput(vtkm::cont::DataSet& result, const vtkm::
}
}
//-----------------------------------------------------------------------------
template VTKM_FILTER_EXTRA_TEMPLATE_EXPORT vtkm::cont::DataSet ExternalFaces::DoExecute(
const vtkm::cont::DataSet& inData,
vtkm::filter::PolicyBase<vtkm::filter::PolicyDefault> policy);
}
}

@ -0,0 +1,80 @@
//============================================================================
// 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.
//============================================================================
#ifndef vtkm_filter_entity_extraction_ExternalFaces_h
#define vtkm_filter_entity_extraction_ExternalFaces_h
#include <vtkm/filter/NewFilterField.h>
#include <vtkm/filter/entity_extraction/vtkm_filter_entity_extraction_export.h>
namespace vtkm
{
namespace worklet
{
struct ExternalFaces;
}
namespace filter
{
/// \brief Extract external faces of a geometry
///
/// ExternalFaces is a filter that extracts all external faces from a
/// data set. An external face is defined is defined as a face/side of a cell
/// that belongs only to one cell in the entire mesh.
/// @warning
/// This filter is currently only supports propagation of point properties
///
class VTKM_FILTER_ENTITY_EXTRACTION_EXPORT ExternalFaces : public vtkm::filter::NewFilterField
{
public:
ExternalFaces();
~ExternalFaces();
// New Design: I am too lazy to make this filter thread-safe. Let's use it as an example of
// thread un-safe filter.
bool CanThread() const override { return false; }
// When CompactPoints is set, instead of copying the points and point fields
// from the input, the filter will create new compact fields without the
// unused elements
VTKM_CONT
bool GetCompactPoints() const { return this->CompactPoints; }
VTKM_CONT
void SetCompactPoints(bool value) { this->CompactPoints = value; }
// When PassPolyData is set (the default), incoming poly data (0D, 1D, and 2D cells)
// will be passed to the output external faces data set.
VTKM_CONT
bool GetPassPolyData() const { return this->PassPolyData; }
VTKM_CONT
void SetPassPolyData(bool value);
private:
VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override;
vtkm::cont::DataSet GenerateOutput(const vtkm::cont::DataSet& input,
vtkm::cont::CellSetExplicit<>& outCellSet);
VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, const vtkm::cont::Field& field);
bool CompactPoints = false;
bool PassPolyData = true;
// Note: This shared state as a data member requires us to explicitly implement the
// constructor and destructor in the .cxx file, after the compiler actually have
// seen the definition of worklet:ExternalFaces, even if the implementation of
// the cstr/dstr is just = default. Otherwise the compiler does not know how to
// allocate/free storage for the std::unique_ptr.
std::unique_ptr<vtkm::worklet::ExternalFaces> Worklet;
};
}
} // namespace vtkm::filter
#endif // vtkm_filter_entity_extraction_ExternalFaces_h

@ -7,12 +7,12 @@
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#ifndef vtk_m_filter_ExtractPoints_hxx
#define vtk_m_filter_ExtractPoints_hxx
#include <vtkm/cont/CoordinateSystem.h>
#include <vtkm/cont/UncertainCellSet.h>
#include <vtkm/cont/UnknownCellSet.h>
#include <vtkm/filter/clean_grid/CleanGrid.h>
#include <vtkm/filter/entity_extraction/ExtractPoints.h>
#include <vtkm/filter/entity_extraction/worklet/ExtractPoints.h>
namespace vtkm
{
@ -20,17 +20,8 @@ namespace filter
{
//-----------------------------------------------------------------------------
inline VTKM_CONT ExtractPoints::ExtractPoints()
: vtkm::filter::FilterDataSet<ExtractPoints>()
, ExtractInside(true)
, CompactPoints(false)
{
}
//-----------------------------------------------------------------------------
template <typename DerivedPolicy>
inline vtkm::cont::DataSet ExtractPoints::DoExecute(const vtkm::cont::DataSet& input,
vtkm::filter::PolicyBase<DerivedPolicy> policy)
VTKM_CONT
vtkm::cont::DataSet ExtractPoints::DoExecute(const vtkm::cont::DataSet& input)
{
// extract the input cell set and coordinates
const vtkm::cont::UnknownCellSet& cells = input.GetCellSet();
@ -41,7 +32,8 @@ inline vtkm::cont::DataSet ExtractPoints::DoExecute(const vtkm::cont::DataSet& i
vtkm::cont::CellSetSingleType<> outCellSet;
vtkm::worklet::ExtractPoints worklet;
outCellSet = worklet.Run(vtkm::filter::ApplyPolicyCellSet(cells, policy, *this),
// FIXME: is the other overload of .Run ever used?
outCellSet = worklet.Run(cells.ResetCellSetList<VTKM_DEFAULT_CELL_SET_LIST>(),
coords.GetData(),
this->Function,
this->ExtractInside);
@ -51,12 +43,16 @@ inline vtkm::cont::DataSet ExtractPoints::DoExecute(const vtkm::cont::DataSet& i
output.SetCellSet(outCellSet);
output.AddCoordinateSystem(input.GetCoordinateSystem(this->GetActiveCoordinateSystemIndex()));
auto mapper = [&, this](auto& result, const auto& f) { this->MapFieldOntoOutput(result, f); };
MapFieldsOntoOutput(input, output, mapper);
// compact the unused points in the output dataset
if (this->CompactPoints)
{
this->Compactor.SetCompactPointFields(true);
this->Compactor.SetMergePoints(false);
return this->Compactor.Execute(output);
vtkm::filter::CleanGrid Compactor;
Compactor.SetCompactPointFields(true);
Compactor.SetMergePoints(false);
return Compactor.Execute(output);
}
else
{
@ -65,24 +61,14 @@ inline vtkm::cont::DataSet ExtractPoints::DoExecute(const vtkm::cont::DataSet& i
}
//-----------------------------------------------------------------------------
template <typename DerivedPolicy>
inline VTKM_CONT bool ExtractPoints::MapFieldOntoOutput(
vtkm::cont::DataSet& result,
const vtkm::cont::Field& field,
vtkm::filter::PolicyBase<DerivedPolicy> policy)
VTKM_CONT bool ExtractPoints::MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::Field& field)
{
// point data is copied as is because it was not collapsed
if (field.IsFieldPoint())
{
if (this->CompactPoints)
{
return this->Compactor.MapFieldOntoOutput(result, field, policy);
}
else
{
result.AddField(field);
return true;
}
result.AddField(field);
return true;
}
else if (field.IsFieldGlobal())
{
@ -97,5 +83,3 @@ inline VTKM_CONT bool ExtractPoints::MapFieldOntoOutput(
}
}
}
#endif

@ -0,0 +1,75 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
//
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#ifndef vtkm_filter_entity_extraction_ExtractPoints_h
#define vtkm_filter_entity_extraction_ExtractPoints_h
#include <vtkm/ImplicitFunction.h>
#ifndef VTKM_NO_DEPRECATED_VIRTUAL
#include <vtkm/cont/ImplicitFunctionHandle.h>
#endif //VTKM_NO_DEPRECATED_VIRTUAL
#include <vtkm/filter/NewFilterField.h>
#include <vtkm/filter/entity_extraction/vtkm_filter_entity_extraction_export.h>
namespace vtkm
{
namespace filter
{
/// @brief Extract only points from a geometry using an implicit function
///
///
/// Extract only the points that are either inside or outside of a
/// VTK-m implicit function. Examples include planes, spheres, boxes,
/// etc.
/// Note that while any geometry type can be provided as input, the output is
/// represented by an explicit representation of points using
/// vtkm::cont::CellSetSingleType
class VTKM_FILTER_ENTITY_EXTRACTION_EXPORT ExtractPoints : public vtkm::filter::NewFilterField
{
public:
/// When CompactPoints is set, instead of copying the points and point fields
/// from the input, the filter will create new compact fields without the unused elements
VTKM_CONT
bool GetCompactPoints() const { return this->CompactPoints; }
VTKM_CONT
void SetCompactPoints(bool value) { this->CompactPoints = value; }
/// Set the volume of interest to extract
void SetImplicitFunction(const vtkm::ImplicitFunctionGeneral& func) { this->Function = func; }
const vtkm::ImplicitFunctionGeneral& GetImplicitFunction() const { return this->Function; }
VTKM_CONT
bool GetExtractInside() { return this->ExtractInside; }
VTKM_CONT
void SetExtractInside(bool value) { this->ExtractInside = value; }
VTKM_CONT
void ExtractInsideOn() { this->ExtractInside = true; }
VTKM_CONT
void ExtractInsideOff() { this->ExtractInside = false; }
private:
VTKM_CONT
vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override;
//Map a new field onto the resulting dataset after running the filter
VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, const vtkm::cont::Field& field);
bool ExtractInside = true;
vtkm::ImplicitFunctionGeneral Function;
bool CompactPoints = false;
};
}
} // namespace vtkm::filter
#endif // vtkm_filter_entity_extraction_ExtractPoints_h

@ -7,9 +7,10 @@
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#ifndef vtk_m_filter_MaskPoints_hxx
#define vtk_m_filter_MaskPoints_hxx
#include <vtkm/cont/UncertainCellSet.h>
#include <vtkm/filter/clean_grid/CleanGrid.h>
#include <vtkm/filter/entity_extraction/MaskPoints.h>
#include <vtkm/filter/entity_extraction/worklet/MaskPoints.h>
namespace vtkm
{
@ -17,18 +18,7 @@ namespace filter
{
//-----------------------------------------------------------------------------
inline VTKM_CONT MaskPoints::MaskPoints()
: vtkm::filter::FilterDataSet<MaskPoints>()
, Stride(1)
, CompactPoints(true)
{
}
//-----------------------------------------------------------------------------
template <typename DerivedPolicy>
inline VTKM_CONT vtkm::cont::DataSet MaskPoints::DoExecute(
const vtkm::cont::DataSet& input,
vtkm::filter::PolicyBase<DerivedPolicy> policy)
VTKM_CONT vtkm::cont::DataSet MaskPoints::DoExecute(const vtkm::cont::DataSet& input)
{
// extract the input cell set
const vtkm::cont::UnknownCellSet& cells = input.GetCellSet();
@ -37,19 +27,23 @@ inline VTKM_CONT vtkm::cont::DataSet MaskPoints::DoExecute(
vtkm::cont::CellSetSingleType<> outCellSet;
vtkm::worklet::MaskPoints worklet;
outCellSet = worklet.Run(vtkm::filter::ApplyPolicyCellSet(cells, policy, *this), this->Stride);
outCellSet = worklet.Run(cells.ResetCellSetList<VTKM_DEFAULT_CELL_SET_LIST>(), this->Stride);
// create the output dataset
vtkm::cont::DataSet output;
output.SetCellSet(outCellSet);
output.AddCoordinateSystem(input.GetCoordinateSystem(this->GetActiveCoordinateSystemIndex()));
auto mapper = [&, this](auto& result, const auto& f) { this->MapFieldOntoOutput(result, f); };
MapFieldsOntoOutput(input, output, mapper);
// compact the unused points in the output dataset
if (this->CompactPoints)
{
this->Compactor.SetCompactPointFields(true);
this->Compactor.SetMergePoints(false);
return this->Compactor.Execute(output);
vtkm::filter::CleanGrid Compactor;
Compactor.SetCompactPointFields(true);
Compactor.SetMergePoints(false);
return this->Execute(output);
}
else
{
@ -58,23 +52,14 @@ inline VTKM_CONT vtkm::cont::DataSet MaskPoints::DoExecute(
}
//-----------------------------------------------------------------------------
template <typename DerivedPolicy>
inline VTKM_CONT bool MaskPoints::MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::Field& field,
vtkm::filter::PolicyBase<DerivedPolicy> policy)
VTKM_CONT bool MaskPoints::MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::Field& field)
{
// point data is copied as is because it was not collapsed
if (field.IsFieldPoint())
{
if (this->CompactPoints)
{
return this->Compactor.MapFieldOntoOutput(result, field, policy);
}
else
{
result.AddField(field);
return true;
}
result.AddField(field);
return true;
}
else if (field.IsFieldGlobal())
{
@ -89,4 +74,3 @@ inline VTKM_CONT bool MaskPoints::MapFieldOntoOutput(vtkm::cont::DataSet& result
}
}
}
#endif

@ -0,0 +1,52 @@
//============================================================================
// 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.
//============================================================================
#ifndef vtk_m_filter_entity_extraction_MaskPoints_h
#define vtk_m_filter_entity_extraction_MaskPoints_h
#include <vtkm/filter/NewFilterField.h>
#include <vtkm/filter/entity_extraction/vtkm_filter_entity_extraction_export.h>
namespace vtkm
{
namespace filter
{
/// \brief Subselect points using a stride
///
/// Extract only every Nth point where N is equal to a stride value
class VTKM_FILTER_ENTITY_EXTRACTION_EXPORT MaskPoints : public vtkm::filter::NewFilterField
{
public:
// When CompactPoints is set, instead of copying the points and point fields
// from the input, the filter will create new compact fields without the unused elements
VTKM_CONT
bool GetCompactPoints() const { return this->CompactPoints; }
VTKM_CONT
void SetCompactPoints(bool value) { this->CompactPoints = value; }
VTKM_CONT
vtkm::Id GetStride() const { return this->Stride; }
VTKM_CONT
void SetStride(vtkm::Id stride) { this->Stride = stride; }
private:
VTKM_CONT
vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override;
VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, const vtkm::cont::Field& field);
vtkm::Id Stride = 1;
bool CompactPoints = true;
};
}
} // namespace vtkm::filter
#endif // vtk_m_filter_entity_extraction_MaskPoints_h

@ -7,10 +7,10 @@
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#ifndef vtk_m_filter_ThresholdPoints_hxx
#define vtk_m_filter_ThresholdPoints_hxx
#include <vtkm/cont/ErrorFilterExecution.h>
#include <vtkm/filter/clean_grid/CleanGrid.h>
#include <vtkm/filter/entity_extraction/ThresholdPoints.h>
#include <vtkm/filter/entity_extraction/worklet/ThresholdPoints.h>
namespace
{
@ -84,37 +84,23 @@ namespace vtkm
namespace filter
{
const int THRESHOLD_BELOW = 0;
const int THRESHOLD_ABOVE = 1;
const int THRESHOLD_BETWEEN = 2;
//-----------------------------------------------------------------------------
inline VTKM_CONT ThresholdPoints::ThresholdPoints()
: vtkm::filter::FilterDataSetWithField<ThresholdPoints>()
, LowerValue(0)
, UpperValue(0)
, ThresholdType(THRESHOLD_BETWEEN)
, CompactPoints(false)
{
}
//-----------------------------------------------------------------------------
inline VTKM_CONT void ThresholdPoints::SetThresholdBelow(const vtkm::Float64 value)
VTKM_CONT void ThresholdPoints::SetThresholdBelow(const vtkm::Float64 value)
{
this->SetLowerThreshold(value);
this->SetUpperThreshold(value);
this->ThresholdType = THRESHOLD_BELOW;
}
inline VTKM_CONT void ThresholdPoints::SetThresholdAbove(const vtkm::Float64 value)
VTKM_CONT void ThresholdPoints::SetThresholdAbove(const vtkm::Float64 value)
{
this->SetLowerThreshold(value);
this->SetUpperThreshold(value);
this->ThresholdType = THRESHOLD_ABOVE;
}
inline VTKM_CONT void ThresholdPoints::SetThresholdBetween(const vtkm::Float64 value1,
const vtkm::Float64 value2)
VTKM_CONT void ThresholdPoints::SetThresholdBetween(const vtkm::Float64 value1,
const vtkm::Float64 value2)
{
this->SetLowerThreshold(value1);
this->SetUpperThreshold(value2);
@ -122,18 +108,14 @@ inline VTKM_CONT void ThresholdPoints::SetThresholdBetween(const vtkm::Float64 v
}
//-----------------------------------------------------------------------------
template <typename T, typename StorageType, typename DerivedPolicy>
inline VTKM_CONT vtkm::cont::DataSet ThresholdPoints::DoExecute(
const vtkm::cont::DataSet& input,
const vtkm::cont::ArrayHandle<T, StorageType>& field,
const vtkm::filter::FieldMetadata& fieldMeta,
vtkm::filter::PolicyBase<DerivedPolicy> policy)
VTKM_CONT vtkm::cont::DataSet ThresholdPoints::DoExecute(const vtkm::cont::DataSet& input)
{
// extract the input cell set
const vtkm::cont::UnknownCellSet& cells = input.GetCellSet();
const auto& field = this->GetFieldFromDataSet(input);
// field to threshold on must be a point field
if (fieldMeta.IsPointField() == false)
if (!field.IsFieldPoint())
{
throw vtkm::cont::ErrorFilterExecution("Point field expected.");
}
@ -142,43 +124,47 @@ inline VTKM_CONT vtkm::cont::DataSet ThresholdPoints::DoExecute(
vtkm::cont::CellSetSingleType<> outCellSet;
vtkm::worklet::ThresholdPoints worklet;
switch (this->ThresholdType)
{
case THRESHOLD_BELOW:
auto ResolveType = [&, this](const auto& concrete) {
switch (this->ThresholdType)
{
outCellSet = worklet.Run(vtkm::filter::ApplyPolicyCellSet(cells, policy, *this),
field,
ValuesBelow(this->GetLowerThreshold()));
break;
case THRESHOLD_BELOW:
{
outCellSet = worklet.Run(cells, concrete, ValuesBelow(this->GetLowerThreshold()));
break;
}
case THRESHOLD_ABOVE:
{
outCellSet = worklet.Run(cells, concrete, ValuesAbove(this->GetUpperThreshold()));
break;
}
case THRESHOLD_BETWEEN:
default:
{
outCellSet = worklet.Run(
cells, concrete, ValuesBetween(this->GetLowerThreshold(), this->GetUpperThreshold()));
break;
}
}
case THRESHOLD_ABOVE:
{
outCellSet = worklet.Run(vtkm::filter::ApplyPolicyCellSet(cells, policy, *this),
field,
ValuesAbove(this->GetUpperThreshold()));
break;
}
case THRESHOLD_BETWEEN:
default:
{
outCellSet = worklet.Run(vtkm::filter::ApplyPolicyCellSet(cells, policy, *this),
field,
ValuesBetween(this->GetLowerThreshold(), this->GetUpperThreshold()));
break;
}
}
};
const auto& fieldArray = field.GetData();
fieldArray.CastAndCallForTypes<vtkm::TypeListScalarAll, VTKM_DEFAULT_STORAGE_LIST>(ResolveType);
// create the output dataset
vtkm::cont::DataSet output;
output.SetCellSet(outCellSet);
output.AddCoordinateSystem(input.GetCoordinateSystem(this->GetActiveCoordinateSystemIndex()));
auto mapper = [&, this](auto& result, const auto& f) { this->MapFieldOntoOutput(result, f); };
MapFieldsOntoOutput(input, output, mapper);
// compact the unused points in the output dataset
if (this->CompactPoints)
{
this->Compactor.SetCompactPointFields(true);
this->Compactor.SetMergePoints(true);
return this->Compactor.Execute(output);
vtkm::filter::CleanGrid Compactor;
Compactor.SetCompactPointFields(true);
Compactor.SetMergePoints(true);
return Compactor.Execute(output);
}
else
{
@ -187,24 +173,14 @@ inline VTKM_CONT vtkm::cont::DataSet ThresholdPoints::DoExecute(
}
//-----------------------------------------------------------------------------
template <typename DerivedPolicy>
inline VTKM_CONT bool ThresholdPoints::MapFieldOntoOutput(
vtkm::cont::DataSet& result,
const vtkm::cont::Field& field,
vtkm::filter::PolicyBase<DerivedPolicy> policy)
VTKM_CONT bool ThresholdPoints::MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::Field& field)
{
// point data is copied as is because it was not collapsed
if (field.IsFieldPoint())
{
if (this->CompactPoints)
{
return this->Compactor.MapFieldOntoOutput(result, field, policy);
}
else
{
result.AddField(field);
return true;
}
result.AddField(field);
return true;
}
else if (field.IsFieldGlobal())
{
@ -219,4 +195,3 @@ inline VTKM_CONT bool ThresholdPoints::MapFieldOntoOutput(
}
}
}
#endif

@ -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.
//============================================================================
#ifndef vtk_m_filter_entity_extraction_ThresholdPoints_h
#define vtk_m_filter_entity_extraction_ThresholdPoints_h
#include <vtkm/filter/NewFilterField.h>
#include <vtkm/filter/entity_extraction/vtkm_filter_entity_extraction_export.h>
namespace vtkm
{
namespace filter
{
class VTKM_FILTER_ENTITY_EXTRACTION_EXPORT ThresholdPoints : public vtkm::filter::NewFilterField
{
public:
// When CompactPoints is set, instead of copying the points and point fields
// from the input, the filter will create new compact fields without the unused elements
VTKM_CONT
bool GetCompactPoints() const { return this->CompactPoints; }
VTKM_CONT
void SetCompactPoints(bool value) { this->CompactPoints = value; }
VTKM_CONT
vtkm::Float64 GetLowerThreshold() const { return this->LowerValue; }
VTKM_CONT
void SetLowerThreshold(vtkm::Float64 value) { this->LowerValue = value; }
VTKM_CONT
vtkm::Float64 GetUpperThreshold() const { return this->UpperValue; }
VTKM_CONT
void SetUpperThreshold(vtkm::Float64 value) { this->UpperValue = value; }
VTKM_CONT
void SetThresholdBelow(const vtkm::Float64 value);
VTKM_CONT
void SetThresholdAbove(const vtkm::Float64 value);
VTKM_CONT
void SetThresholdBetween(const vtkm::Float64 value1, const vtkm::Float64 value2);
private:
VTKM_CONT
vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override;
VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, const vtkm::cont::Field& field);
constexpr static int THRESHOLD_BELOW = 0;
constexpr static int THRESHOLD_ABOVE = 1;
constexpr static int THRESHOLD_BETWEEN = 2;
double LowerValue = 0;
double UpperValue = 0;
int ThresholdType = THRESHOLD_BETWEEN;
bool CompactPoints = false;
};
}
} // namespace vtkm::filter
#endif // vtk_m_filter_entity_extraction_ThresholdPoints_h

@ -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.
##============================================================================
set(unit_tests
UnitTestExternalFacesFilter.cxx
UnitTestExtractPointsFilter.cxx
UnitTestMaskPointsFilter.cxx
UnitTestThresholdPointsFilter.cxx
)
set(libraries
vtkm_filter_clean_grid
vtkm_filter_entity_extraction
)
vtkm_unit_tests(
SOURCES ${unit_tests}
LIBRARIES ${libraries}
USE_VTKM_JOB_POOL
)

@ -11,8 +11,8 @@
#include <vtkm/cont/testing/MakeTestDataSet.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/filter/CleanGrid.h>
#include <vtkm/filter/ExternalFaces.h>
#include <vtkm/filter/clean_grid/CleanGrid.h>
#include <vtkm/filter/entity_extraction/ExternalFaces.h>
using vtkm::cont::testing::MakeTestDataSet;

@ -11,7 +11,7 @@
#include <vtkm/cont/testing/MakeTestDataSet.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/filter/ExtractPoints.h>
#include <vtkm/filter/entity_extraction/ExtractPoints.h>
using vtkm::cont::testing::MakeTestDataSet;

@ -11,7 +11,7 @@
#include <vtkm/cont/testing/MakeTestDataSet.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/filter/MaskPoints.h>
#include <vtkm/filter/entity_extraction/MaskPoints.h>
using vtkm::cont::testing::MakeTestDataSet;

@ -11,7 +11,7 @@
#include <vtkm/cont/testing/MakeTestDataSet.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/filter/ThresholdPoints.h>
#include <vtkm/filter/entity_extraction/ThresholdPoints.h>
using vtkm::cont::testing::MakeTestDataSet;

@ -0,0 +1,17 @@
##============================================================================
## 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.
##============================================================================
set(headers
ExternalFaces.h
ExternalFaces.h
MaskPoints.h
)
vtkm_declare_headers(${headers})

@ -16,7 +16,6 @@ set(unit_tests
UnitTestCellAverageFilter.cxx
UnitTestCellMeasuresFilter.cxx
UnitTestCellSetConnectivityFilter.cxx
UnitTestCleanGrid.cxx
UnitTestClipWithFieldFilter.cxx
UnitTestClipWithImplicitFunctionFilter.cxx
UnitTestContourFilter.cxx
@ -27,9 +26,7 @@ set(unit_tests
UnitTestCoordinateSystemTransform.cxx
UnitTestCrossProductFilter.cxx
UnitTestEntropyFilter.cxx
UnitTestExternalFacesFilter.cxx
UnitTestExtractGeometryFilter.cxx
UnitTestExtractPointsFilter.cxx
UnitTestExtractStructuredFilter.cxx
UnitTestFieldMetadata.cxx
UnitTestFieldSelection.cxx
@ -47,7 +44,6 @@ set(unit_tests
UnitTestMapFieldMergeAverage.cxx
UnitTestMapFieldPermutation.cxx
UnitTestMaskFilter.cxx
UnitTestMaskPointsFilter.cxx
UnitTestMeshQualityFilter.cxx
UnitTestMIRFilter.cxx
UnitTestMultiBlockFilter.cxx
@ -67,7 +63,6 @@ set(unit_tests
UnitTestSurfaceNormalsFilter.cxx
UnitTestTetrahedralizeFilter.cxx
UnitTestThresholdFilter.cxx
UnitTestThresholdPointsFilter.cxx
UnitTestTriangulateFilter.cxx
UnitTestTubeFilter.cxx
UnitTestVectorMagnitudeFilter.cxx

@ -9,8 +9,8 @@
//============================================================================
#include <vtkm/cont/MergePartitionedDataSet.h>
#include <vtkm/filter/ExternalFaces.h>
#include <vtkm/filter/Threshold.h>
#include <vtkm/filter/entity_extraction/ExternalFaces.h>
#include <vtkm/source/Amr.h>
#include <vtkm/rendering/testing/RenderTest.h>

@ -13,8 +13,8 @@
#include <vtkm/cont/testing/MakeTestDataSet.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/filter/CleanGrid.h>
#include <vtkm/filter/Contour.h>
#include <vtkm/filter/clean_grid/CleanGrid.h>
#include <vtkm/source/Tangle.h>
#include <vtkm/io/VTKDataSetReader.h>

@ -13,8 +13,8 @@
#include <vtkm/cont/testing/MakeTestDataSet.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/filter/CleanGrid.h>
#include <vtkm/filter/Contour.h>
#include <vtkm/filter/clean_grid/CleanGrid.h>
#include <vtkm/filter/field_transform/GenerateIds.h>
#include <vtkm/io/VTKDataSetReader.h>

@ -12,7 +12,7 @@
#include <vtkm/cont/DataSet.h>
#include <vtkm/cont/DataSetBuilderUniform.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/filter/CleanGrid.h>
#include <vtkm/filter/clean_grid/CleanGrid.h>
#include <vtkm/filter/Contour.h>

@ -13,10 +13,10 @@
#include <vtkm/cont/testing/MakeTestDataSet.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/filter/CleanGrid.h>
#include <vtkm/filter/ClipWithField.h>
#include <vtkm/filter/Contour.h>
#include <vtkm/filter/Gradient.h>
#include <vtkm/filter/clean_grid/CleanGrid.h>
#include <vtkm/io/VTKDataSetReader.h>
#include <vtkm/source/Tangle.h>

@ -10,8 +10,8 @@
#include <vtkm/cont/testing/MakeTestDataSet.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/filter/CleanGrid.h>
#include <vtkm/filter/Threshold.h>
#include <vtkm/filter/clean_grid/CleanGrid.h>
using vtkm::cont::testing::MakeTestDataSet;

@ -13,7 +13,7 @@
#include <vtkm/cont/TryExecute.h>
#include <vtkm/exec/CellEdge.h>
#include <vtkm/filter/ExternalFaces.h>
#include <vtkm/filter/entity_extraction/ExternalFaces.h>
#include <vtkm/rendering/CanvasRayTracer.h>
#include <vtkm/rendering/MapperRayTracer.h>
#include <vtkm/rendering/MapperWireframer.h>

@ -27,9 +27,7 @@ set(headers
DispatcherPointNeighborhood.h
DispatcherReduceByKey.h
DotProduct.h
ExternalFaces.h
ExtractGeometry.h
ExtractPoints.h
ExtractStructured.h
FieldEntropy.h
FieldHistogram.h
@ -45,7 +43,6 @@ set(headers
Mask.h
MaskIndices.h
MaskNone.h
MaskPoints.h
MaskSelect.h
MeshQuality.h
MIR.h
@ -60,11 +57,8 @@ set(headers
ParticleAdvection.h
PointAverage.h
PointElevation.h
PointMerge.h
PointTransform.h
Probe.h
RemoveDegenerateCells.h
RemoveUnusedPoints.h
ScalarsToColors.h
ScatterCounting.h
ScatterIdentity.h
@ -78,7 +72,6 @@ set(headers
SurfaceNormals.h
Tetrahedralize.h
Threshold.h
ThresholdPoints.h
TriangleWinding.h
Triangulate.h
Tube.h

@ -32,9 +32,7 @@ set(unit_tests
UnitTestCrossProduct.cxx
UnitTestDescriptiveStatistics.cxx
UnitTestDotProduct.cxx
UnitTestExternalFaces.cxx
UnitTestExtractGeometry.cxx
UnitTestExtractPoints.cxx
UnitTestExtractStructured.cxx
UnitTestFieldHistogram.cxx
UnitTestFieldStatistics.cxx
@ -45,7 +43,6 @@ set(unit_tests
UnitTestMagnitude.cxx
UnitTestMask.cxx
UnitTestMaskIndices.cxx
UnitTestMaskPoints.cxx
UnitTestMaskSelect.cxx
UnitTestNormalize.cxx
UnitTestNDimsEntropy.cxx
@ -58,7 +55,6 @@ set(unit_tests
UnitTestPointGradient.cxx
UnitTestPointTransform.cxx
UnitTestProbe.cxx
UnitTestRemoveUnusedPoints.cxx
UnitTestScalarsToColors.cxx
UnitTestScatterAndMask.cxx
UnitTestScatterCounting.cxx
@ -72,7 +68,6 @@ set(unit_tests
UnitTestTemporalAdvection.cxx
UnitTestTetrahedralize.cxx
UnitTestThreshold.cxx
UnitTestThresholdPoints.cxx
UnitTestTriangleWinding.cxx
UnitTestTriangulate.cxx
UnitTestTube.cxx

@ -1,192 +0,0 @@
//============================================================================
// 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.
//============================================================================
#include <vtkm/cont/DataSetBuilderExplicit.h>
#include <vtkm/cont/DataSetBuilderUniform.h>
#include <vtkm/cont/DeviceAdapter.h>
#include <vtkm/cont/testing/MakeTestDataSet.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/worklet/ExternalFaces.h>
#include <algorithm>
#include <iostream>
namespace
{
vtkm::cont::DataSet RunExternalFaces(vtkm::cont::DataSet& inDataSet)
{
const vtkm::cont::UnknownCellSet& inCellSet = inDataSet.GetCellSet();
vtkm::cont::CellSetExplicit<> outCellSet;
//Run the External Faces worklet
if (inCellSet.CanConvert<vtkm::cont::CellSetStructured<3>>())
{
vtkm::worklet::ExternalFaces().Run(inCellSet.AsCellSet<vtkm::cont::CellSetStructured<3>>(),
inDataSet.GetCoordinateSystem(),
outCellSet);
}
else
{
vtkm::worklet::ExternalFaces().Run(inCellSet.AsCellSet<vtkm::cont::CellSetExplicit<>>(),
outCellSet);
}
vtkm::cont::DataSet outDataSet;
for (vtkm::IdComponent i = 0; i < inDataSet.GetNumberOfCoordinateSystems(); ++i)
{
outDataSet.AddCoordinateSystem(inDataSet.GetCoordinateSystem(i));
}
outDataSet.SetCellSet(outCellSet);
return outDataSet;
}
void TestExternalFaces1()
{
std::cout << "Test 1" << std::endl;
//--------------Construct a VTK-m Test Dataset----------------
const int nVerts = 8; //A cube that is tetrahedralized
using CoordType = vtkm::Vec3f_32;
vtkm::cont::ArrayHandle<CoordType> coordinates;
coordinates.Allocate(nVerts);
coordinates.WritePortal().Set(0, CoordType(0.0f, 0.0f, 0.0f));
coordinates.WritePortal().Set(1, CoordType(1.0f, 0.0f, 0.0f));
coordinates.WritePortal().Set(2, CoordType(1.0f, 1.0f, 0.0f));
coordinates.WritePortal().Set(3, CoordType(0.0f, 1.0f, 0.0f));
coordinates.WritePortal().Set(4, CoordType(0.0f, 0.0f, 1.0f));
coordinates.WritePortal().Set(5, CoordType(1.0f, 0.0f, 1.0f));
coordinates.WritePortal().Set(6, CoordType(1.0f, 1.0f, 1.0f));
coordinates.WritePortal().Set(7, CoordType(0.0f, 1.0f, 1.0f));
//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::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.WritePortal().Set(j, static_cast<vtkm::UInt8>(vtkm::CELL_SHAPE_TETRA));
numIndices.WritePortal().Set(j, 4);
for (int k = 0; k < 4; k++)
conn.WritePortal().Set(index++, cellVerts[j][k]);
}
vtkm::cont::DataSetBuilderExplicit builder;
vtkm::cont::DataSet ds = builder.Create(coordinates, shapes, numIndices, conn);
//Run the External Faces worklet
vtkm::cont::DataSet new_ds = RunExternalFaces(ds);
vtkm::cont::CellSetExplicit<> new_cs;
new_ds.GetCellSet().AsCellSet(new_cs);
vtkm::Id numExtFaces_out = new_cs.GetNumberOfCells();
//Validate the number of external faces (output) returned by the worklet
const vtkm::Id numExtFaces_actual = 12;
VTKM_TEST_ASSERT(numExtFaces_out == numExtFaces_actual, "Number of External Faces mismatch");
} // TestExternalFaces1
void TestExternalFaces2()
{
std::cout << "Test 2" << std::endl;
vtkm::cont::testing::MakeTestDataSet dataSetMaker;
vtkm::cont::DataSet inDataSet = dataSetMaker.Make3DExplicitDataSet5();
// Expected faces
const vtkm::IdComponent MAX_POINTS_PER_FACE = 4;
const vtkm::Id NUM_FACES = 12;
const vtkm::Id ExpectedExternalFaces[NUM_FACES][MAX_POINTS_PER_FACE] = {
{ 0, 3, 7, 4 }, { 0, 1, 2, 3 }, { 0, 4, 5, 1 }, { 3, 2, 6, 7 },
{ 1, 5, 8, -1 }, { 6, 2, 8, -1 }, { 2, 1, 8, -1 }, { 8, 10, 6, -1 },
{ 5, 10, 8, -1 }, { 4, 7, 9, -1 }, { 7, 6, 10, 9 }, { 9, 10, 5, 4 }
};
vtkm::cont::DataSet outDataSet = RunExternalFaces(inDataSet);
vtkm::cont::CellSetExplicit<> outCellSet;
outDataSet.GetCellSet().AsCellSet(outCellSet);
VTKM_TEST_ASSERT(outCellSet.GetNumberOfCells() == NUM_FACES, "Got wrong number of faces.");
bool foundFaces[NUM_FACES];
for (vtkm::Id faceId = 0; faceId < NUM_FACES; faceId++)
{
foundFaces[faceId] = false;
}
for (vtkm::Id dataFaceId = 0; dataFaceId < NUM_FACES; dataFaceId++)
{
vtkm::Vec<vtkm::Id, MAX_POINTS_PER_FACE> dataIndices(-1);
outCellSet.GetIndices(dataFaceId, dataIndices);
std::cout << "Looking for face " << dataIndices << std::endl;
bool foundFace = false;
for (vtkm::Id expectedFaceId = 0; expectedFaceId < NUM_FACES; expectedFaceId++)
{
vtkm::Vec<vtkm::Id, MAX_POINTS_PER_FACE> expectedIndices;
vtkm::make_VecC(ExpectedExternalFaces[expectedFaceId], 4).CopyInto(expectedIndices);
if (expectedIndices == dataIndices)
{
VTKM_TEST_ASSERT(!foundFaces[expectedFaceId], "Found face twice.");
std::cout << " found" << std::endl;
foundFace = true;
foundFaces[expectedFaceId] = true;
break;
}
}
VTKM_TEST_ASSERT(foundFace, "Face not found.");
}
}
void TestExternalFaces3()
{
std::cout << "Test 3" << std::endl;
vtkm::cont::DataSetBuilderUniform dataSetBuilder;
vtkm::cont::DataSet dataSet = dataSetBuilder.Create(vtkm::Id3(6, 6, 5));
//Run the External Faces worklet
vtkm::cont::DataSet new_ds = RunExternalFaces(dataSet);
vtkm::cont::CellSetExplicit<> new_cs;
new_ds.GetCellSet().AsCellSet(new_cs);
vtkm::Id numExtFaces_out = new_cs.GetNumberOfCells();
//Validate the number of external faces (output) returned by the worklet
const vtkm::Id numExtFaces_actual = 130;
VTKM_TEST_ASSERT(numExtFaces_out == numExtFaces_actual, "Number of External Faces mismatch");
}
void TestExternalFaces()
{
TestExternalFaces1();
TestExternalFaces2();
TestExternalFaces3();
}
}
int UnitTestExternalFaces(int argc, char* argv[])
{
return vtkm::cont::testing::Testing::Run(TestExternalFaces, argc, argv);
}

@ -1,238 +0,0 @@
//============================================================================
// 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.
//============================================================================
#include <vtkm/worklet/ExtractPoints.h>
#include <vtkm/cont/testing/MakeTestDataSet.h>
#include <vtkm/cont/testing/Testing.h>
using vtkm::cont::testing::MakeTestDataSet;
class TestingExtractPoints
{
public:
void TestUniformById() const
{
std::cout << "Testing extract points structured by id:" << std::endl;
using OutCellSetType = vtkm::cont::CellSetSingleType<>;
// Input data set created
vtkm::cont::DataSet dataset = MakeTestDataSet().Make3DUniformDataSet1();
// Points to extract
vtkm::cont::ArrayHandle<vtkm::Id> pointIds =
vtkm::cont::make_ArrayHandle<vtkm::Id>({ 0, 1, 2, 3, 4, 5, 10, 15, 20, 25, 50, 75, 100 });
// Output dataset contains input coordinate system and point data
vtkm::cont::DataSet outDataSet;
outDataSet.AddCoordinateSystem(dataset.GetCoordinateSystem(0));
// Output data set with cell set containing extracted points
vtkm::worklet::ExtractPoints extractPoints;
OutCellSetType outCellSet = extractPoints.Run(dataset.GetCellSet(), pointIds);
outDataSet.SetCellSet(outCellSet);
VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfCells(), pointIds.GetNumberOfValues()),
"Wrong result for ExtractPoints");
}
void TestUniformByBox0() const
{
std::cout << "Testing extract points with implicit function (box):" << std::endl;
using OutCellSetType = vtkm::cont::CellSetSingleType<>;
// Input data set created
vtkm::cont::DataSet dataset = MakeTestDataSet().Make3DUniformDataSet1();
// Implicit function
vtkm::Vec3f minPoint(1.f, 1.f, 1.f);
vtkm::Vec3f maxPoint(3.f, 3.f, 3.f);
bool extractInside = true;
// Output dataset contains input coordinate system and point data
vtkm::cont::DataSet outDataSet;
outDataSet.AddCoordinateSystem(dataset.GetCoordinateSystem(0));
// Output data set with cell set containing extracted points
vtkm::worklet::ExtractPoints extractPoints;
OutCellSetType outCellSet = extractPoints.Run(dataset.GetCellSet(),
dataset.GetCoordinateSystem("coords"),
vtkm::Box(minPoint, maxPoint),
extractInside);
outDataSet.SetCellSet(outCellSet);
VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfCells(), 27),
"Wrong result for ExtractPoints");
}
void TestUniformByBox1() const
{
std::cout << "Testing extract points with implicit function (box):" << std::endl;
using OutCellSetType = vtkm::cont::CellSetSingleType<>;
// Input data set created
vtkm::cont::DataSet dataset = MakeTestDataSet().Make3DUniformDataSet1();
// Implicit function
vtkm::Vec3f minPoint(1.f, 1.f, 1.f);
vtkm::Vec3f maxPoint(3.f, 3.f, 3.f);
bool extractInside = false;
// Output dataset contains input coordinate system and point data
vtkm::cont::DataSet outDataSet;
outDataSet.AddCoordinateSystem(dataset.GetCoordinateSystem(0));
// Output data set with cell set containing extracted points
vtkm::worklet::ExtractPoints extractPoints;
OutCellSetType outCellSet = extractPoints.Run(dataset.GetCellSet(),
dataset.GetCoordinateSystem("coords"),
vtkm::Box(minPoint, maxPoint),
extractInside);
outDataSet.SetCellSet(outCellSet);
VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfCells(), 98),
"Wrong result for ExtractPoints");
}
void TestUniformBySphere() const
{
std::cout << "Testing extract points with implicit function (sphere):" << std::endl;
using OutCellSetType = vtkm::cont::CellSetSingleType<>;
// Input data set created
vtkm::cont::DataSet dataset = MakeTestDataSet().Make3DUniformDataSet1();
// Implicit function
vtkm::Vec3f center(2.f, 2.f, 2.f);
vtkm::FloatDefault radius(1.8f);
bool extractInside = true;
// Output dataset contains input coordinate system and point data
vtkm::cont::DataSet outDataSet;
outDataSet.AddCoordinateSystem(dataset.GetCoordinateSystem(0));
// Output data set with cell set containing extracted points
vtkm::worklet::ExtractPoints extractPoints;
OutCellSetType outCellSet = extractPoints.Run(dataset.GetCellSet(),
dataset.GetCoordinateSystem("coords"),
vtkm::Sphere(center, radius),
extractInside);
outDataSet.SetCellSet(outCellSet);
VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfCells(), 27),
"Wrong result for ExtractPoints");
}
void TestExplicitByBox0() const
{
std::cout << "Testing extract points with implicit function (box) on explicit:" << std::endl;
using OutCellSetType = vtkm::cont::CellSetSingleType<>;
// Input data set created
vtkm::cont::DataSet dataset = MakeTestDataSet().Make3DExplicitDataSet5();
// Implicit function
vtkm::Vec3f minPoint(0.f, 0.f, 0.f);
vtkm::Vec3f maxPoint(1.f, 1.f, 1.f);
bool extractInside = true;
// Output dataset contains input coordinate system and point data
vtkm::cont::DataSet outDataSet;
outDataSet.AddCoordinateSystem(dataset.GetCoordinateSystem(0));
// Output data set with cell set containing extracted points
vtkm::worklet::ExtractPoints extractPoints;
OutCellSetType outCellSet = extractPoints.Run(dataset.GetCellSet(),
dataset.GetCoordinateSystem("coordinates"),
vtkm::Box(minPoint, maxPoint),
extractInside);
outDataSet.SetCellSet(outCellSet);
VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfCells(), 8),
"Wrong result for ExtractPoints");
}
void TestExplicitByBox1() const
{
std::cout << "Testing extract points with implicit function (box) on explicit:" << std::endl;
using OutCellSetType = vtkm::cont::CellSetSingleType<>;
// Input data set created
vtkm::cont::DataSet dataset = MakeTestDataSet().Make3DExplicitDataSet5();
// Implicit function
vtkm::Vec3f minPoint(0.f, 0.f, 0.f);
vtkm::Vec3f maxPoint(1.f, 1.f, 1.f);
bool extractInside = false;
// Output dataset contains input coordinate system and point data
vtkm::cont::DataSet outDataSet;
outDataSet.AddCoordinateSystem(dataset.GetCoordinateSystem(0));
// Output data set with cell set containing extracted points
vtkm::worklet::ExtractPoints extractPoints;
OutCellSetType outCellSet = extractPoints.Run(dataset.GetCellSet(),
dataset.GetCoordinateSystem("coordinates"),
vtkm::Box(minPoint, maxPoint),
extractInside);
outDataSet.SetCellSet(outCellSet);
VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfCells(), 3),
"Wrong result for ExtractPoints");
}
void TestExplicitById() const
{
std::cout << "Testing extract points explicit by id:" << std::endl;
using OutCellSetType = vtkm::cont::CellSetSingleType<>;
// Input data set created
vtkm::cont::DataSet dataset = MakeTestDataSet().Make3DExplicitDataSet5();
// Points to extract
vtkm::cont::ArrayHandle<vtkm::Id> pointIds =
vtkm::cont::make_ArrayHandle<vtkm::Id>({ 0, 4, 5, 7, 9, 10 });
// Output dataset contains input coordinate system and point data
vtkm::cont::DataSet outDataSet;
outDataSet.AddCoordinateSystem(dataset.GetCoordinateSystem(0));
// Output data set with cell set containing extracted points
vtkm::worklet::ExtractPoints extractPoints;
OutCellSetType outCellSet = extractPoints.Run(dataset.GetCellSet(), pointIds);
outDataSet.SetCellSet(outCellSet);
VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfCells(), pointIds.GetNumberOfValues()),
"Wrong result for ExtractPoints");
}
void operator()() const
{
this->TestUniformById();
this->TestUniformByBox0();
this->TestUniformByBox1();
this->TestUniformBySphere();
this->TestExplicitById();
this->TestExplicitByBox0();
this->TestExplicitByBox1();
}
};
int UnitTestExtractPoints(int argc, char* argv[])
{
return vtkm::cont::testing::Testing::Run(TestingExtractPoints(), argc, argv);
}

@ -1,106 +0,0 @@
//============================================================================
// 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.
//============================================================================
#include <vtkm/worklet/MaskPoints.h>
#include <vtkm/cont/testing/MakeTestDataSet.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/cont/ArrayPortalToIterators.h>
#include <vtkm/cont/CellSet.h>
#include <algorithm>
#include <iostream>
#include <vector>
namespace
{
using vtkm::cont::testing::MakeTestDataSet;
class TestingMaskPoints
{
public:
void TestUniform2D() const
{
std::cout << "Testing mask points stride on 2D uniform dataset" << std::endl;
using OutCellSetType = vtkm::cont::CellSetSingleType<>;
vtkm::cont::DataSet dataset = MakeTestDataSet().Make2DUniformDataSet1();
// Output dataset contains input coordinate system
vtkm::cont::DataSet outDataSet;
outDataSet.AddCoordinateSystem(dataset.GetCoordinateSystem(0));
// Output dataset gets new cell set of points that pass subsampling
vtkm::worklet::MaskPoints maskPoints;
OutCellSetType outCellSet;
outCellSet = maskPoints.Run(dataset.GetCellSet(), 2);
outDataSet.SetCellSet(outCellSet);
VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfCells(), 12), "Wrong result for MaskPoints");
}
void TestUniform3D() const
{
std::cout << "Testing mask points stride on 3D uniform dataset" << std::endl;
using OutCellSetType = vtkm::cont::CellSetSingleType<>;
vtkm::cont::DataSet dataset = MakeTestDataSet().Make3DUniformDataSet1();
// Output dataset contains input coordinate system and point data
vtkm::cont::DataSet outDataSet;
outDataSet.AddCoordinateSystem(dataset.GetCoordinateSystem(0));
// Output dataset gets new cell set of points that meet threshold predicate
vtkm::worklet::MaskPoints maskPoints;
OutCellSetType outCellSet;
outCellSet = maskPoints.Run(dataset.GetCellSet(), 5);
outDataSet.SetCellSet(outCellSet);
VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfCells(), 25), "Wrong result for MaskPoints");
}
void TestExplicit3D() const
{
std::cout << "Testing mask points stride on 3D explicit dataset" << std::endl;
using OutCellSetType = vtkm::cont::CellSetSingleType<>;
vtkm::cont::DataSet dataset = MakeTestDataSet().Make3DExplicitDataSet5();
// Output dataset contains input coordinate system and point data
vtkm::cont::DataSet outDataSet;
outDataSet.AddCoordinateSystem(dataset.GetCoordinateSystem(0));
// Output dataset gets new cell set of points that meet threshold predicate
vtkm::worklet::MaskPoints maskPoints;
OutCellSetType outCellSet;
outCellSet = maskPoints.Run(dataset.GetCellSet(), 3);
outDataSet.SetCellSet(outCellSet);
VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfCells(), 3), "Wrong result for MaskPoints");
}
void operator()() const
{
this->TestUniform2D();
this->TestUniform3D();
this->TestExplicit3D();
}
};
}
int UnitTestMaskPoints(int argc, char* argv[])
{
return vtkm::cont::testing::Testing::Run(TestingMaskPoints(), argc, argv);
}

@ -32,10 +32,10 @@
#include <vtkm/cont/CoordinateSystem.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/filter/CleanGrid.h>
#include <vtkm/filter/Contour.h>
#include <vtkm/filter/PolicyBase.h>
#include <vtkm/filter/SurfaceNormals.h>
#include <vtkm/filter/clean_grid/CleanGrid.h>
#include <vtkm/source/Wavelet.h>

@ -1,84 +0,0 @@
//============================================================================
// 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.
//============================================================================
#include <vtkm/worklet/RemoveUnusedPoints.h>
#include <vtkm/cont/testing/Testing.h>
namespace
{
vtkm::cont::CellSetExplicit<> CreateInputCellSet()
{
vtkm::cont::CellSetExplicit<> cellSet;
cellSet.PrepareToAddCells(2, 7);
cellSet.AddCell(vtkm::CELL_SHAPE_TRIANGLE, 3, vtkm::make_Vec<vtkm::Id>(0, 2, 4));
cellSet.AddCell(vtkm::CELL_SHAPE_QUAD, 4, vtkm::make_Vec<vtkm::Id>(4, 2, 6, 8));
cellSet.CompleteAddingCells(11);
return cellSet;
}
void CheckOutputCellSet(const vtkm::cont::CellSetExplicit<>& cellSet,
const vtkm::cont::ArrayHandle<vtkm::Float32>& field)
{
VTKM_TEST_ASSERT(cellSet.GetNumberOfCells() == 2, "Wrong num cells.");
VTKM_TEST_ASSERT(cellSet.GetNumberOfPoints() == 5, "Wrong num points.");
VTKM_TEST_ASSERT(cellSet.GetCellShape(0) == vtkm::CELL_SHAPE_TRIANGLE, "Wrong shape");
VTKM_TEST_ASSERT(cellSet.GetCellShape(1) == vtkm::CELL_SHAPE_QUAD, "Wrong shape");
VTKM_TEST_ASSERT(cellSet.GetNumberOfPointsInCell(0) == 3, "Wrong num points");
VTKM_TEST_ASSERT(cellSet.GetNumberOfPointsInCell(1) == 4, "Wrong num points");
vtkm::Id3 pointIds3;
cellSet.GetIndices(0, pointIds3);
VTKM_TEST_ASSERT(pointIds3[0] == 0, "Wrong point id for cell");
VTKM_TEST_ASSERT(pointIds3[1] == 1, "Wrong point id for cell");
VTKM_TEST_ASSERT(pointIds3[2] == 2, "Wrong point id for cell");
vtkm::Id4 pointIds4;
cellSet.GetIndices(1, pointIds4);
VTKM_TEST_ASSERT(pointIds4[0] == 2, "Wrong point id for cell");
VTKM_TEST_ASSERT(pointIds4[1] == 1, "Wrong point id for cell");
VTKM_TEST_ASSERT(pointIds4[2] == 3, "Wrong point id for cell");
VTKM_TEST_ASSERT(pointIds4[3] == 4, "Wrong point id for cell");
auto fieldPortal = field.ReadPortal();
VTKM_TEST_ASSERT(test_equal(fieldPortal.Get(0), TestValue(0, vtkm::Float32())), "Bad field");
VTKM_TEST_ASSERT(test_equal(fieldPortal.Get(1), TestValue(2, vtkm::Float32())), "Bad field");
VTKM_TEST_ASSERT(test_equal(fieldPortal.Get(2), TestValue(4, vtkm::Float32())), "Bad field");
VTKM_TEST_ASSERT(test_equal(fieldPortal.Get(3), TestValue(6, vtkm::Float32())), "Bad field");
VTKM_TEST_ASSERT(test_equal(fieldPortal.Get(4), TestValue(8, vtkm::Float32())), "Bad field");
}
void RunTest()
{
std::cout << "Creating input" << std::endl;
vtkm::cont::CellSetExplicit<> inCellSet = CreateInputCellSet();
vtkm::cont::ArrayHandle<vtkm::Float32> inField;
inField.Allocate(inCellSet.GetNumberOfPoints());
SetPortal(inField.WritePortal());
std::cout << "Removing unused points" << std::endl;
vtkm::worklet::RemoveUnusedPoints compactPoints(inCellSet);
vtkm::cont::CellSetExplicit<> outCellSet = compactPoints.MapCellSet(inCellSet);
vtkm::cont::ArrayHandle<vtkm::Float32> outField = compactPoints.MapPointFieldDeep(inField);
std::cout << "Checking resulting cell set" << std::endl;
CheckOutputCellSet(outCellSet, outField);
}
} // anonymous namespace
int UnitTestRemoveUnusedPoints(int argc, char* argv[])
{
return vtkm::cont::testing::Testing::Run(RunTest, argc, argv);
}

@ -1,194 +0,0 @@
//============================================================================
// 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.
//============================================================================
#include <vtkm/worklet/ThresholdPoints.h>
#include <vtkm/cont/testing/MakeTestDataSet.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/cont/ArrayPortalToIterators.h>
#include <vtkm/cont/CellSet.h>
#include <algorithm>
#include <iostream>
#include <vector>
namespace
{
// Predicate for values less than minimum
class ValuesBelow
{
public:
VTKM_CONT
ValuesBelow(const vtkm::FloatDefault& value)
: Value(value)
{
}
template <typename ScalarType>
VTKM_EXEC bool operator()(const ScalarType& value) const
{
return static_cast<vtkm::FloatDefault>(value) <= this->Value;
}
private:
vtkm::FloatDefault Value;
};
// Predicate for values greater than maximum
class ValuesAbove
{
public:
VTKM_CONT
ValuesAbove(const vtkm::FloatDefault& value)
: Value(value)
{
}
template <typename ScalarType>
VTKM_EXEC bool operator()(const ScalarType& value) const
{
return static_cast<vtkm::FloatDefault>(value) >= this->Value;
}
private:
vtkm::FloatDefault Value;
};
// Predicate for values between minimum and maximum
class ValuesBetween
{
public:
VTKM_CONT
ValuesBetween(const vtkm::FloatDefault& lower, const vtkm::FloatDefault& upper)
: Lower(lower)
, Upper(upper)
{
}
template <typename ScalarType>
VTKM_EXEC bool operator()(const ScalarType& value) const
{
return static_cast<vtkm::FloatDefault>(value) >= this->Lower &&
static_cast<vtkm::FloatDefault>(value) <= this->Upper;
}
private:
vtkm::FloatDefault Lower;
vtkm::FloatDefault Upper;
};
using vtkm::cont::testing::MakeTestDataSet;
class TestingThresholdPoints
{
public:
void TestUniform2D() const
{
std::cout << "Testing threshold on 2D uniform dataset" << std::endl;
using OutCellSetType = vtkm::cont::CellSetSingleType<>;
vtkm::cont::DataSet dataset = MakeTestDataSet().Make2DUniformDataSet1();
// Output dataset contains input coordinate system and point data
vtkm::cont::DataSet outDataSet;
outDataSet.AddCoordinateSystem(dataset.GetCoordinateSystem(0));
outDataSet.AddField(dataset.GetField("pointvar"));
// Output dataset gets new cell set of points that meet threshold predicate
vtkm::worklet::ThresholdPoints threshold;
OutCellSetType outCellSet;
outCellSet =
threshold.Run(dataset.GetCellSet(),
dataset.GetField("pointvar")
.GetData()
.ResetTypes(vtkm::TypeListFieldScalar{}, VTKM_DEFAULT_STORAGE_LIST{}),
ValuesBetween(40.0f, 71.0f));
outDataSet.SetCellSet(outCellSet);
VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfCells(), 11),
"Wrong result for ThresholdPoints");
vtkm::cont::Field pointField = outDataSet.GetField("pointvar");
vtkm::cont::ArrayHandle<vtkm::Float32> pointFieldArray;
pointField.GetData().AsArrayHandle(pointFieldArray);
VTKM_TEST_ASSERT(pointFieldArray.ReadPortal().Get(12) == 50.0f, "Wrong point field data");
}
void TestUniform3D() const
{
std::cout << "Testing threshold on 3D uniform dataset" << std::endl;
using OutCellSetType = vtkm::cont::CellSetSingleType<>;
vtkm::cont::DataSet dataset = MakeTestDataSet().Make3DUniformDataSet1();
// Output dataset contains input coordinate system and point data
vtkm::cont::DataSet outDataSet;
outDataSet.AddCoordinateSystem(dataset.GetCoordinateSystem(0));
outDataSet.AddField(dataset.GetField("pointvar"));
// Output dataset gets new cell set of points that meet threshold predicate
vtkm::worklet::ThresholdPoints threshold;
OutCellSetType outCellSet;
outCellSet =
threshold.Run(dataset.GetCellSet(),
dataset.GetField("pointvar")
.GetData()
.ResetTypes(vtkm::TypeListFieldScalar{}, VTKM_DEFAULT_STORAGE_LIST{}),
ValuesAbove(1.0f));
outDataSet.SetCellSet(outCellSet);
VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfCells(), 27),
"Wrong result for ThresholdPoints");
}
void TestExplicit3D() const
{
std::cout << "Testing threshold on 3D explicit dataset" << std::endl;
using OutCellSetType = vtkm::cont::CellSetSingleType<>;
vtkm::cont::DataSet dataset = MakeTestDataSet().Make3DExplicitDataSet5();
// Output dataset contains input coordinate system and point data
vtkm::cont::DataSet outDataSet;
outDataSet.AddCoordinateSystem(dataset.GetCoordinateSystem(0));
// Output dataset gets new cell set of points that meet threshold predicate
vtkm::worklet::ThresholdPoints threshold;
OutCellSetType outCellSet;
outCellSet =
threshold.Run(dataset.GetCellSet(),
dataset.GetField("pointvar")
.GetData()
.ResetTypes(vtkm::TypeListFieldScalar{}, VTKM_DEFAULT_STORAGE_LIST{}),
ValuesBelow(50.0f));
outDataSet.SetCellSet(outCellSet);
VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfCells(), 6),
"Wrong result for ThresholdPoints");
}
void operator()() const
{
this->TestUniform2D();
this->TestUniform3D();
this->TestExplicit3D();
}
};
}
int UnitTestThresholdPoints(int argc, char* argv[])
{
return vtkm::cont::testing::Testing::Run(TestingThresholdPoints(), argc, argv);
}