Merge branch 'master' into image_processing

# Conflicts:
#	vtkm/filter/CMakeLists.txt
#	vtkm/filter/testing/CMakeLists.txt
This commit is contained in:
Li-Ta Lo 2022-02-08 11:03:32 -07:00
commit b81d200a63
58 changed files with 905 additions and 729 deletions

@ -22,7 +22,8 @@
#include <vector>
#include <vtkm/cont/DataSet.h>
#include <vtkm/cont/DataSetBuilderExplicit.h>
#include <vtkm/filter/MeshQuality.h>
#include <vtkm/cont/ErrorExecution.h>
#include <vtkm/filter/mesh_info/MeshQuality.h>
#include <vtkm/io/VTKDataSetReader.h>
#include <vtkm/io/VTKDataSetWriter.h>
@ -200,7 +201,7 @@ inline vtkm::cont::DataSet Make3DExplicitDataSet()
int TestMetrics(const char* outFileName,
vtkm::cont::DataSet data,
vtkm::filter::MeshQuality& filter)
vtkm::filter::mesh_info::MeshQuality& filter)
{
vtkm::cont::DataSet outputData;
try
@ -257,7 +258,7 @@ int main(int argc, char* argv[])
// A cell metric is now computed for every shape type that exists in the
// input dataset.
vtkm::filter::CellMetric shapeMetric = vtkm::filter::CellMetric::VOLUME;
vtkm::filter::mesh_info::CellMetric shapeMetric = vtkm::filter::mesh_info::CellMetric::VOLUME;
try
{
@ -270,7 +271,7 @@ int main(int argc, char* argv[])
return 1;
}
vtkm::filter::MeshQuality filter(shapeMetric);
vtkm::filter::mesh_info::MeshQuality filter(shapeMetric);
TestMetrics(outFileName, input, filter);
return 0;
}

@ -10,6 +10,8 @@
#ifndef vtk_m_CellClassification_h
#define vtk_m_CellClassification_h
#include <vtkm/Types.h>
namespace vtkm
{

@ -10,6 +10,7 @@
set(deprecated_headers
CellAverage.h
CellMeasures.h
CellSetConnectivity.h
CleanGrid.h
ClipWithField.h
@ -26,6 +27,7 @@ set(deprecated_headers
ExtractStructured.h
FieldToColors.h
GenerateIds.h
GhostCellClassify.h
GhostCellRemove.h
Gradient.h
Histogram.h
@ -34,6 +36,7 @@ set(deprecated_headers
ImageMedian.h
Mask.h
MaskPoints.h
MeshQuality.h
NDEntropy.h
NDHistogram.h
ParticleDensityCloudInCell.h
@ -53,7 +56,6 @@ set(deprecated_headers
vtkm_declare_headers(${deprecated_headers})
set(common_headers
CellMeasures.h
FieldMetadata.h
FilterCell.h
FilterDataSet.h
@ -72,7 +74,6 @@ set(common_headers
vtkm_declare_headers(${common_headers})
set(common_header_template_sources
CellMeasures.hxx
FilterDataSet.hxx
FilterDataSetWithField.hxx
FilterField.hxx
@ -90,10 +91,8 @@ set(extra_headers
ContourTreeUniform.h
CreateResult.h
FieldSelection.h
GhostCellClassify.h
Lagrangian.h
LagrangianStructures.h
MeshQuality.h
MIRFilter.h
ParticleAdvection.h
Pathline.h
@ -119,10 +118,8 @@ set(extra_header_template_sources
ContourTreeUniformAugmented.hxx
ContourTreeUniformDistributed.hxx
ContourTreeUniform.hxx
GhostCellClassify.hxx
Lagrangian.hxx
LagrangianStructures.hxx
MeshQuality.hxx
MIRFilter.hxx
ParticleAdvection.hxx
Pathline.hxx
@ -212,6 +209,7 @@ add_subdirectory(internal)
add_subdirectory(particleadvection)
add_subdirectory(field_conversion)
add_subdirectory(field_transform)
add_subdirectory(mesh_info)
add_subdirectory(vector_analysis)
#-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -

@ -7,48 +7,83 @@
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#ifndef vtk_m_filter_CellMeasures_h
#define vtk_m_filter_CellMeasures_h
#include <vtkm/filter/FilterField.h>
#include <vtkm/worklet/CellMeasure.h>
#include <vtkm/Deprecated.h>
#include <vtkm/filter/mesh_info/CellMeasures.h>
namespace vtkm
{
struct VTKM_DEPRECATED(1.8, "IntegrateOver is no longer supported") IntegrateOver
{
};
struct VTKM_DEPRECATED(1.8, "IntegrateOverCurve is no longer supported") IntegrateOverCurve
: IntegrateOver
{
static constexpr IntegrationType value = ArcLength;
};
struct VTKM_DEPRECATED(1.8, "IntegrateOverSurface is no longer supported") IntegrateOverSurface
: IntegrateOver
{
static constexpr IntegrationType value = Area;
};
struct VTKM_DEPRECATED(1.8, "IntegrateOverSurface is no longer supported") IntegrateOverSolid
: IntegrateOver
{
static constexpr IntegrationType value = Volume;
};
// Lists of acceptable types of integration
using ArcLength VTKM_DEPRECATED(1.8, "Use vtkm::filter::mesh_info::IntegrationType::ArcLength") =
vtkm::List<IntegrateOverCurve>;
using Area VTKM_DEPRECATED(1.8, "Use vtkm::filter::mesh_info::IntegrationType::Area") =
vtkm::List<IntegrateOverSurface>;
using Volume VTKM_DEPRECATED(1.8, "Use vtkm::filter::mesh_info::IntegrationType::Volume") =
vtkm::List<IntegrateOverSolid>;
using AllMeasures VTKM_DEPRECATED(1.8,
"Use vtkm::filter::mesh_info::IntegrationType::AllMeasures") =
vtkm::List<IntegrateOverSolid, IntegrateOverSurface, IntegrateOverCurve>;
namespace detail
{
IntegrationType OldToNewIntegrationType(vtkm::List<>)
{
return static_cast<IntegrationType>(0);
}
template <typename T, typename... Ts>
IntegrationType OldToNewIntegrationType(vtkm::List<T, Ts...>)
{
return T::value | OldToNewIntegrationType(vtkm::List<Ts...>{});
}
} // namespace detail
namespace filter
{
/// \brief Compute the measure of each (3D) cell in a dataset.
///
/// CellMeasures is a filter that generates a new cell data array (i.e., one value
/// specified per cell) holding the signed measure of the cell
/// or 0 (if measure is not well defined or the cell type is unsupported).
///
/// By default, the new cell-data array is named "measure".
template <typename IntegrationType>
class CellMeasures : public vtkm::filter::FilterField<CellMeasures<IntegrationType>>
template <typename IntegrationTypeList>
class VTKM_DEPRECATED(1.8, "Use vtkm::filter::mesh_info::CellMeasures.") CellMeasures
: public vtkm::filter::mesh_info::CellMeasures
{
public:
using SupportedTypes = vtkm::TypeListFieldVec3;
VTKM_CONT
CellMeasures();
/// Set/Get the name of the cell measure field. If not set, "measure" is used.
void SetCellMeasureName(const std::string& name) { this->SetOutputFieldName(name); }
const std::string& GetCellMeasureName() const { return this->GetOutputFieldName(); }
template <typename T, typename StorageType, typename DerivedPolicy>
VTKM_CONT vtkm::cont::DataSet DoExecute(
const vtkm::cont::DataSet& input,
const vtkm::cont::ArrayHandle<vtkm::Vec<T, 3>, StorageType>& points,
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy);
CellMeasures()
: vtkm::filter::mesh_info::CellMeasures(vtkm::detail::OldToNewIntegrationType(IntegrationTypeList{})
{
}
};
VTKM_DEPRECATED(1.8,
"Use vtkm/filter/mesh_info/CellMeasures.h instead of vtkm/filter/CellMeasures.h.")
inline void CellMeasures_deprecated() {}
inline void CellMeasures_deprecated_warning()
{
CellMeasures_deprecated();
}
} // namespace vtkm::filter
#include <vtkm/filter/CellMeasures.hxx>
#endif // vtk_m_filter_CellMeasures_h
} // namespace filter
} // namespace vtkm
#endif //vtk_m_filter_CellMeasures_h

@ -10,46 +10,31 @@
#ifndef vtk_m_filter_GhostCellClassify_h
#define vtk_m_filter_GhostCellClassify_h
#include <vtkm/filter/FilterDataSet.h>
#include <vtkm/Deprecated.h>
#include <vtkm/filter/mesh_info/GhostCellClassify.h>
namespace vtkm
{
namespace filter
{
struct VTKM_DEPRECATED(1.6,
"GhostCellClassifyPolicy no longer has an effect.") GhostCellClassifyPolicy
: vtkm::filter::PolicyBase<GhostCellClassifyPolicy>
VTKM_DEPRECATED(
1.8,
"Use vtkm/filter/mesh_info/GhostCellClassify.h instead of vtkm/filter/GhostCellClassify.h.")
inline void GhostCellClassify_deprecated() {}
inline void GhostCellClassify_deprecated_warning()
{
using FieldTypeList = vtkm::List<vtkm::UInt8>;
GhostCellClassify_deprecated();
}
class VTKM_DEPRECATED(1.8, "Use vtkm::filter::mesh_info::GhostCellClassify.") GhostCellClassify
: public vtkm::filter::mesh_info::GhostCellClassify
{
using mesh_info::GhostCellClassify::GhostCellClassify;
};
class GhostCellClassify : public vtkm::filter::FilterDataSet<GhostCellClassify>
{
public:
using SupportedTypes = vtkm::List<vtkm::UInt8>;
VTKM_CONT
GhostCellClassify();
template <typename Policy>
VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& inData,
vtkm::filter::PolicyBase<Policy> policy);
template <typename DerivedPolicy>
VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::Field& field,
const vtkm::filter::PolicyBase<DerivedPolicy>&)
{
result.AddField(field);
return true;
}
private:
};
}
} // namespace vtkm::filter
#include <vtkm/filter/GhostCellClassify.hxx>
#endif //vtk_m_filter_GhostCellClassify_h

@ -39,7 +39,7 @@
#include <vtkm/worklet/WorkletMapTopology.h>
#include <vtkm/worklet/WorkletReduceByKey.h>
#include <vtkm/filter/MeshQuality.h>
#include <vtkm/filter/mesh_info/worklet/MeshQuality.h>
namespace vtkm
{
@ -99,8 +99,9 @@ inline VTKM_CONT vtkm::cont::DataSet MIRFilter::DoExecute(
const vtkm::cont::CoordinateSystem inputCoords =
input.GetCoordinateSystem(this->GetActiveCoordinateSystemIndex());
vtkm::cont::ArrayHandle<vtkm::Float64> avgSizeTot;
vtkm::worklet::MeshQuality<vtkm::filter::CellMetric> getVol;
getVol.SetMetric(c3 > 0 ? vtkm::filter::CellMetric::VOLUME : vtkm::filter::CellMetric::AREA);
vtkm::worklet::MeshQuality getVol;
getVol.SetMetric(c3 > 0 ? vtkm::filter::mesh_info::CellMetric::VOLUME
: vtkm::filter::mesh_info::CellMetric::AREA);
this->Invoke(getVol,
vtkm::filter::ApplyPolicyCellSet(input.GetCellSet(), policy, *this),
inputCoords.GetData(),

@ -2,120 +2,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.
//
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_filter_MeshQuality_h
#define vtk_m_filter_MeshQuality_h
#include <vtkm/CellShape.h>
#include <vtkm/filter/FilterField.h>
#include <vtkm/worklet/MeshQuality.h>
#include <vtkm/Deprecated.h>
#include <vtkm/filter/mesh_info/MeshQuality.h>
namespace vtkm
{
namespace filter
{
//Names of the available cell metrics, for use in
//the output dataset fields
static const std::string MetricNames[] = { "area",
"aspectGamma",
"aspectRatio",
"condition",
"diagonalRatio",
"dimension",
"jacobian",
"maxAngle",
"maxDiagonal",
"minAngle",
"minDiagonal",
"oddy",
"relativeSizeSquared",
"scaledJacobian",
"shape",
"shapeAndSize",
"shear",
"skew",
"stretch",
"taper",
"volume",
"warpage" };
VTKM_DEPRECATED(1.8,
"Use vtkm/filter/mesh_info/MeshQuality.h instead of vtkm/filter/MeshQuality.h.")
inline void MeshQuality_deprecated() {}
//Different cell metrics available to use
//This must follow the same order as the MetricNames above
enum class CellMetric
inline void MeshQuality_deprecated_warning()
{
AREA,
ASPECT_GAMMA,
ASPECT_RATIO,
CONDITION,
DIAGONAL_RATIO,
DIMENSION,
JACOBIAN,
MAX_ANGLE,
MAX_DIAGONAL,
MIN_ANGLE,
MIN_DIAGONAL,
ODDY,
RELATIVE_SIZE_SQUARED,
SCALED_JACOBIAN,
SHAPE,
SHAPE_AND_SIZE,
SHEAR,
SKEW,
STRETCH,
TAPER,
VOLUME,
WARPAGE,
NUMBER_OF_CELL_METRICS,
EMPTY
MeshQuality_deprecated();
}
class VTKM_DEPRECATED(1.8, "Use vtkm::filter::mesh_info::MeshQuality.") MeshQuality
: public vtkm::filter::mesh_info::MeshQuality
{
using mesh_info::MeshQuality::MeshQuality;
};
/** \brief Computes the quality of an unstructured cell-based mesh. The quality is defined in terms of the
* summary statistics (frequency, mean, variance, min, max) of metrics computed over the mesh
* cells. One of several different metrics can be specified for a given cell type, and the mesh
* can consist of one or more different cell types. The resulting mesh quality is stored as one
* or more new fields in the output dataset of this filter, with a separate field for each cell type.
* Each field contains the metric summary statistics for the cell type.
* Summary statists with all 0 values imply that the specified metric does not support the cell type.
*/
class MeshQuality : public vtkm::filter::FilterField<MeshQuality>
{
public:
using SupportedTypes = vtkm::TypeListFieldVec3;
using SupportedCellSets =
vtkm::List<vtkm::cont::CellSetExplicit<>, vtkm::cont::CellSetSingleType<>>;
}
} // namespace vtkm::filter
VTKM_CONT MeshQuality(CellMetric);
template <typename T, typename StorageType, typename DerivedPolicy>
VTKM_CONT vtkm::cont::DataSet DoExecute(
const vtkm::cont::DataSet& input,
const vtkm::cont::ArrayHandle<vtkm::Vec<T, 3>, StorageType>& points,
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy);
private:
CellMetric MyMetric;
};
} // namespace filter
} // namespace vtkm
#include <vtkm/filter/MeshQuality.hxx>
#endif // vtk_m_filter_MeshQuality_h
#endif //vtk_m_filter_MeshQuality_h

@ -1,116 +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.
//
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//=========================================================================
#ifndef vtk_m_filter_MeshQuality_hxx
#define vtk_m_filter_MeshQuality_hxx
#include <vtkm/cont/Algorithm.h>
#include <vtkm/cont/ErrorFilterExecution.h>
#include <vtkm/cont/Field.h>
#include <vtkm/filter/CellMeasures.h>
#include <vtkm/filter/CreateResult.h>
// #define DEBUG_PRINT
namespace vtkm
{
namespace filter
{
inline VTKM_CONT MeshQuality::MeshQuality(CellMetric metric)
: vtkm::filter::FilterField<MeshQuality>()
{
this->SetUseCoordinateSystemAsField(true);
this->MyMetric = metric;
if (this->MyMetric < CellMetric::AREA || this->MyMetric >= CellMetric::NUMBER_OF_CELL_METRICS)
{
VTKM_ASSERT(true);
}
this->SetOutputFieldName(MetricNames[(int)this->MyMetric]);
}
template <typename T, typename StorageType, typename DerivedPolicy>
inline VTKM_CONT vtkm::cont::DataSet MeshQuality::DoExecute(
const vtkm::cont::DataSet& input,
const vtkm::cont::ArrayHandle<vtkm::Vec<T, 3>, StorageType>& points,
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy)
{
if (!fieldMeta.IsPointField())
{
throw vtkm::cont::ErrorBadValue("Active field for MeshQuality must be point coordinates. "
"But the active field is not a point field.");
}
vtkm::worklet::MeshQuality<CellMetric> qualityWorklet;
if (this->MyMetric == vtkm::filter::CellMetric::RELATIVE_SIZE_SQUARED ||
this->MyMetric == vtkm::filter::CellMetric::SHAPE_AND_SIZE)
{
vtkm::FloatDefault averageArea = 1.;
vtkm::worklet::MeshQuality<CellMetric> subWorklet;
vtkm::cont::ArrayHandle<T> array;
subWorklet.SetMetric(vtkm::filter::CellMetric::AREA);
this->Invoke(subWorklet,
vtkm::filter::ApplyPolicyCellSet(input.GetCellSet(), policy, *this),
points,
array);
T zero = 0.0;
vtkm::FloatDefault totalArea = (vtkm::FloatDefault)vtkm::cont::Algorithm::Reduce(array, zero);
vtkm::FloatDefault averageVolume = 1.;
subWorklet.SetMetric(vtkm::filter::CellMetric::VOLUME);
this->Invoke(subWorklet,
vtkm::filter::ApplyPolicyCellSet(input.GetCellSet(), policy, *this),
points,
array);
vtkm::FloatDefault totalVolume = (vtkm::FloatDefault)vtkm::cont::Algorithm::Reduce(array, zero);
vtkm::Id numVals = array.GetNumberOfValues();
if (numVals > 0)
{
averageArea = totalArea / static_cast<vtkm::FloatDefault>(numVals);
averageVolume = totalVolume / static_cast<vtkm::FloatDefault>(numVals);
}
qualityWorklet.SetAverageArea(averageArea);
qualityWorklet.SetAverageVolume(averageVolume);
}
//Invoke the MeshQuality worklet
vtkm::cont::ArrayHandle<T> outArray;
qualityWorklet.SetMetric(this->MyMetric);
this->Invoke(qualityWorklet,
vtkm::filter::ApplyPolicyCellSet(input.GetCellSet(), policy, *this),
points,
outArray);
vtkm::cont::DataSet result;
result.CopyStructure(input); //clone of the input dataset
//Append the metric values of all cells into the output
//dataset as a new field
result.AddField(vtkm::cont::make_FieldCell(this->GetOutputFieldName(), outArray));
return result;
}
} // namespace filter
} // namespace vtkm
#endif

@ -0,0 +1,37 @@
##============================================================================
## 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(mesh_info_headers
CellMeasures.h
GhostCellClassify.h
MeshQuality.h
)
set(mesh_info_sources
CellMeasures.cxx
GhostCellClassify.cxx
MeshQuality.cxx
)
vtkm_library(
NAME vtkm_filter_mesh_info
HEADERS ${mesh_info_headers}
DEVICE_SOURCES ${mesh_info_sources}
USE_VTKM_JOB_POOL
)
target_link_libraries(vtkm_filter_mesh_info PUBLIC vtkm_worklet vtkm_filter_core)
target_link_libraries(vtkm_filter PUBLIC INTERFACE vtkm_filter_mesh_info)
add_subdirectory(worklet)
#-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -
if (VTKm_ENABLE_TESTING)
add_subdirectory(testing)
endif ()

@ -8,46 +8,41 @@
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#ifndef vtk_m_filter_CellMeasures_hxx
#define vtk_m_filter_CellMeasures_hxx
#include <vtkm/cont/ErrorFilterExecution.h>
#include <vtkm/filter/mesh_info/CellMeasures.h>
#include <vtkm/filter/mesh_info/worklet/CellMeasure.h>
namespace vtkm
{
namespace filter
{
namespace mesh_info
{
//-----------------------------------------------------------------------------
template <typename IntegrationType>
inline VTKM_CONT CellMeasures<IntegrationType>::CellMeasures()
: vtkm::filter::FilterField<CellMeasures<IntegrationType>>()
VTKM_CONT CellMeasures::CellMeasures(IntegrationType m)
: measure(m)
{
this->SetUseCoordinateSystemAsField(true);
this->SetCellMeasureName("measure");
}
//-----------------------------------------------------------------------------
template <typename IntegrationType>
template <typename T, typename StorageType, typename DerivedPolicy>
inline VTKM_CONT vtkm::cont::DataSet CellMeasures<IntegrationType>::DoExecute(
const vtkm::cont::DataSet& input,
const vtkm::cont::ArrayHandle<vtkm::Vec<T, 3>, StorageType>& points,
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy)
VTKM_CONT vtkm::cont::DataSet CellMeasures::DoExecute(const vtkm::cont::DataSet& input)
{
if (fieldMeta.IsPointField() == false)
const auto& field = this->GetFieldFromDataSet(input);
if (!field.IsFieldPoint())
{
throw vtkm::cont::ErrorFilterExecution("CellMeasures expects point field input.");
}
const auto& cellset = input.GetCellSet();
vtkm::cont::ArrayHandle<T> outArray;
vtkm::cont::ArrayHandle<vtkm::FloatDefault> outArray;
this->Invoke(vtkm::worklet::CellMeasure<IntegrationType>{},
vtkm::filter::ApplyPolicyCellSet(cellset, policy, *this),
points,
outArray);
auto resolveType = [&](const auto& concrete) {
this->Invoke(vtkm::worklet::CellMeasure{ this->measure }, cellset, concrete, outArray);
};
this->CastAndCallVecField<3>(field, resolveType);
std::string outputName = this->GetCellMeasureName();
if (outputName.empty())
@ -55,9 +50,8 @@ inline VTKM_CONT vtkm::cont::DataSet CellMeasures<IntegrationType>::DoExecute(
// Default name is name of input.
outputName = "measure";
}
return CreateResultFieldCell(input, outArray, outputName);
return this->CreateResultFieldCell(input, outputName, outArray);
}
}
} // namespace vtkm::filter
#endif
} // namespace mesh_info
} // namespace filter
} // namespace vtkm

@ -0,0 +1,57 @@
//============================================================================
// 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_mesh_info_CellMeasure_h
#define vtk_m_filter_mesh_info_CellMeasure_h
#include <vtkm/filter/NewFilterField.h>
#include <vtkm/filter/mesh_info/vtkm_filter_mesh_info_export.h>
namespace vtkm
{
namespace filter
{
namespace mesh_info
{
enum IntegrationType
{
ArcLength = 0x01,
Area = 0x02,
Volume = 0x04,
AllMeasures = ArcLength | Area | Volume
};
/// \brief Compute the measure of each (3D) cell in a dataset.
///
/// CellMeasures is a filter that generates a new cell data array (i.e., one value
/// specified per cell) holding the signed measure of the cell
/// or 0 (if measure is not well defined or the cell type is unsupported).
///
/// By default, the new cell-data array is named "measure".
class VTKM_FILTER_MESH_INFO_EXPORT CellMeasures : public vtkm::filter::NewFilterField
{
public:
VTKM_CONT
explicit CellMeasures(IntegrationType);
/// Set/Get the name of the cell measure field. If not set, "measure" is used.
void SetCellMeasureName(const std::string& name) { this->SetOutputFieldName(name); }
const std::string& GetCellMeasureName() const { return this->GetOutputFieldName(); }
private:
VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override;
IntegrationType measure;
};
} // namespace mesh_info
} // namespace filter
} // namespace vtkm
#endif // vtk_m_filter_mesh_info_CellMeasure_h

@ -7,17 +7,11 @@
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#ifndef vtk_m_filter_GhostCellClassify_hxx
#define vtk_m_filter_GhostCellClassify_hxx
#include <vtkm/CellClassification.h>
#include <vtkm/RangeId.h>
#include <vtkm/RangeId2.h>
#include <vtkm/RangeId3.h>
#include <vtkm/Types.h>
#include <vtkm/cont/ArrayCopy.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ErrorFilterExecution.h>
#include <vtkm/filter/mesh_info/GhostCellClassify.h>
#include <vtkm/worklet/WorkletPointNeighborhood.h>
namespace vtkm
@ -30,7 +24,7 @@ namespace detail
class SetStructuredGhostCells1D : public vtkm::worklet::WorkletPointNeighborhood
{
public:
SetStructuredGhostCells1D(vtkm::IdComponent numLayers = 1)
explicit SetStructuredGhostCells1D(vtkm::IdComponent numLayers = 1)
: NumLayers(numLayers)
{
}
@ -51,7 +45,7 @@ private:
class SetStructuredGhostCells2D : public vtkm::worklet::WorkletPointNeighborhood
{
public:
SetStructuredGhostCells2D(vtkm::IdComponent numLayers = 1)
explicit SetStructuredGhostCells2D(vtkm::IdComponent numLayers = 1)
: NumLayers(numLayers)
{
}
@ -73,7 +67,7 @@ private:
class SetStructuredGhostCells3D : public vtkm::worklet::WorkletPointNeighborhood
{
public:
SetStructuredGhostCells3D(vtkm::IdComponent numLayers = 1)
explicit SetStructuredGhostCells3D(vtkm::IdComponent numLayers = 1)
: NumLayers(numLayers)
{
}
@ -92,11 +86,9 @@ private:
};
} // namespace detail
inline VTKM_CONT GhostCellClassify::GhostCellClassify() {}
template <typename Policy>
inline VTKM_CONT vtkm::cont::DataSet GhostCellClassify::DoExecute(const vtkm::cont::DataSet& input,
vtkm::filter::PolicyBase<Policy>)
namespace mesh_info
{
VTKM_CONT vtkm::cont::DataSet GhostCellClassify::DoExecute(const vtkm::cont::DataSet& input)
{
const vtkm::cont::UnknownCellSet& cellset = input.GetCellSet();
vtkm::cont::ArrayHandle<vtkm::UInt8> ghosts;
@ -149,8 +141,10 @@ inline VTKM_CONT vtkm::cont::DataSet GhostCellClassify::DoExecute(const vtkm::co
throw vtkm::cont::ErrorFilterExecution("Unsupported cellset type for GhostCellClassify.");
}
return CreateResultFieldCell(input, ghosts, "vtkmGhostCells");
auto output = this->CreateResult(input);
output.AddCellField("vtkmGhostCells", ghosts);
return output;
}
}
}
}
#endif

@ -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.
//============================================================================
#ifndef vtk_m_filter_mesh_info_GhostCellClassify_h
#define vtk_m_filter_mesh_info_GhostCellClassify_h
#include <vtkm/filter/NewFilter.h>
#include <vtkm/filter/mesh_info/vtkm_filter_mesh_info_export.h>
namespace vtkm
{
namespace filter
{
namespace mesh_info
{
class VTKM_FILTER_MESH_INFO_EXPORT GhostCellClassify : public vtkm::filter::NewFilter
{
VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& inData) override;
};
} // namespace mesh_info
} // namespace filter
} // namespace vtkm
#endif //vtk_m_filter_mesh_info_GhostCellClassify_h

@ -0,0 +1,132 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//=========================================================================
#include <vtkm/cont/Algorithm.h>
#include <vtkm/cont/ErrorFilterExecution.h>
#include <vtkm/cont/Field.h>
#include <vtkm/filter/CreateResult.h>
#include <vtkm/filter/mesh_info/MeshQuality.h>
#include <vtkm/filter/mesh_info/worklet/MeshQuality.h>
namespace vtkm
{
namespace filter
{
namespace mesh_info
{
namespace
{
//Names of the available cell metrics, for use in
//the output dataset fields
const std::map<CellMetric, std::string> MetricNames = {
{ CellMetric::AREA, "area" },
{ CellMetric::ASPECT_GAMMA, "aspectGamma" },
{ CellMetric::ASPECT_RATIO, "aspectRatio" },
{ CellMetric::CONDITION, "condition" },
{ CellMetric::DIAGONAL_RATIO, "diagonalRatio" },
{ CellMetric::DIMENSION, "dimension" },
{ CellMetric::JACOBIAN, "jacobian" },
{ CellMetric::MAX_ANGLE, "maxAngle" },
{ CellMetric::MAX_DIAGONAL, "maxDiagonal" },
{ CellMetric::MIN_ANGLE, "minAngle" },
{ CellMetric::MIN_DIAGONAL, "minDiagonal" },
{ CellMetric::ODDY, "oddy" },
{ CellMetric::RELATIVE_SIZE_SQUARED, "relativeSizeSquared" },
{ CellMetric::SCALED_JACOBIAN, "scaledJacobian" },
{ CellMetric::SHAPE, "shape" },
{ CellMetric::SHAPE_AND_SIZE, "shapeAndSize" },
{ CellMetric::SHEAR, "shear" },
{ CellMetric::SKEW, "skew" },
{ CellMetric::STRETCH, "stretch" },
{ CellMetric::TAPER, "taper" },
{ CellMetric::VOLUME, "volume" },
{ CellMetric::WARPAGE, "warpage" }
};
} // anonymous namespace
VTKM_CONT MeshQuality::MeshQuality(CellMetric metric)
: MyMetric(metric)
{
this->SetUseCoordinateSystemAsField(true);
this->SetOutputFieldName(MetricNames.at(this->MyMetric));
}
VTKM_CONT vtkm::cont::DataSet MeshQuality::DoExecute(const vtkm::cont::DataSet& input)
{
const auto& field = this->GetFieldFromDataSet(input);
if (!field.IsFieldPoint())
{
throw vtkm::cont::ErrorBadValue("Active field for MeshQuality must be point coordinates. "
"But the active field is not a point field.");
}
vtkm::cont::UnknownCellSet inputCellSet = input.GetCellSet();
vtkm::worklet::MeshQuality qualityWorklet;
if (this->MyMetric == CellMetric::RELATIVE_SIZE_SQUARED ||
this->MyMetric == CellMetric::SHAPE_AND_SIZE)
{
vtkm::worklet::MeshQuality subWorklet;
vtkm::FloatDefault totalArea;
vtkm::FloatDefault totalVolume;
auto resolveType = [&](const auto& concrete) {
// use std::decay to remove const ref from the decltype of concrete.
using T = typename std::decay_t<decltype(concrete)>::ValueType::ComponentType;
vtkm::cont::ArrayHandle<T> array;
subWorklet.SetMetric(CellMetric::AREA);
this->Invoke(subWorklet, inputCellSet, concrete, array);
totalArea = (vtkm::FloatDefault)vtkm::cont::Algorithm::Reduce(array, T{});
subWorklet.SetMetric(CellMetric::VOLUME);
this->Invoke(subWorklet, inputCellSet, concrete, array);
totalVolume = (vtkm::FloatDefault)vtkm::cont::Algorithm::Reduce(array, T{});
};
this->CastAndCallVecField<3>(field, resolveType);
vtkm::FloatDefault averageArea = 1.;
vtkm::FloatDefault averageVolume = 1.;
vtkm::Id numCells = inputCellSet.GetNumberOfCells();
if (numCells > 0)
{
averageArea = totalArea / static_cast<vtkm::FloatDefault>(numCells);
averageVolume = totalVolume / static_cast<vtkm::FloatDefault>(numCells);
}
qualityWorklet.SetAverageArea(averageArea);
qualityWorklet.SetAverageVolume(averageVolume);
}
vtkm::cont::UnknownArrayHandle outArray;
//Invoke the MeshQuality worklet
auto resolveType = [&](const auto& concrete) {
using T = typename std::decay_t<decltype(concrete)>::ValueType::ComponentType;
vtkm::cont::ArrayHandle<T> result;
qualityWorklet.SetMetric(this->MyMetric);
this->Invoke(qualityWorklet, inputCellSet, concrete, result);
outArray = result;
};
this->CastAndCallVecField<3>(field, resolveType);
return this->CreateResultFieldCell(input, this->GetOutputFieldName(), outArray);
}
} // namespace mesh_info
} // namespace filter
} // namespace vtkm

@ -0,0 +1,85 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_filter_mesh_info_MeshQuality_h
#define vtk_m_filter_mesh_info_MeshQuality_h
#include <vtkm/filter/NewFilterField.h>
#include <vtkm/filter/mesh_info/vtkm_filter_mesh_info_export.h>
namespace vtkm
{
namespace filter
{
namespace mesh_info
{
//Different cell metrics available to use
//This must follow the same order as the MetricNames above
enum class CellMetric
{
AREA,
ASPECT_GAMMA,
ASPECT_RATIO,
CONDITION,
DIAGONAL_RATIO,
DIMENSION,
JACOBIAN,
MAX_ANGLE,
MAX_DIAGONAL,
MIN_ANGLE,
MIN_DIAGONAL,
ODDY,
RELATIVE_SIZE_SQUARED,
SCALED_JACOBIAN,
SHAPE,
SHAPE_AND_SIZE,
SHEAR,
SKEW,
STRETCH,
TAPER,
VOLUME,
WARPAGE,
NUMBER_OF_CELL_METRICS,
EMPTY
};
/** \brief Computes the quality of an unstructured cell-based mesh. The quality is defined in terms of the
* summary statistics (frequency, mean, variance, min, max) of metrics computed over the mesh
* cells. One of several different metrics can be specified for a given cell type, and the mesh
* can consist of one or more different cell types. The resulting mesh quality is stored as one
* or more new fields in the output dataset of this filter, with a separate field for each cell type.
* Each field contains the metric summary statistics for the cell type.
* Summary statists with all 0 values imply that the specified metric does not support the cell type.
*/
class VTKM_FILTER_MESH_INFO_EXPORT MeshQuality : public vtkm::filter::NewFilterField
{
public:
VTKM_CONT explicit MeshQuality(CellMetric);
private:
VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override;
CellMetric MyMetric;
};
} // namespace mesh_info
} // namespace filter
} // namespace vtkm
#endif // vtk_m_filter_mesh_info_MeshQuality_h

@ -0,0 +1,25 @@
##============================================================================
## 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
UnitTestCellMeasuresFilter.cxx
UnitTestGhostCellClassify.cxx
UnitTestMeshQualityFilter.cxx
)
set(libraries
vtkm_filter_mesh_info
)
vtkm_unit_tests(
SOURCES ${unit_tests}
LIBRARIES ${libraries}
USE_VTKM_JOB_POOL
)

@ -8,12 +8,11 @@
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#include <vtkm/filter/CellMeasures.h>
#include <vtkm/cont/testing/MakeTestDataSet.h>
#include <vtkm/cont/testing/Testing.h>
#include <vector>
#include <vtkm/filter/mesh_info/CellMeasures.h>
namespace
{
@ -37,15 +36,14 @@ struct CheckCellMeasuresFunctor
}
};
template <typename IntegrationType>
void TestCellMeasuresFilter(vtkm::cont::DataSet& dataset,
const char* msg,
const std::vector<vtkm::Float32>& expected,
const IntegrationType&)
const vtkm::filter::mesh_info::IntegrationType& type)
{
std::cout << "Testing CellMeasures Filter on " << msg << "\n";
vtkm::filter::CellMeasures<IntegrationType> vols;
vtkm::filter::mesh_info::CellMeasures vols{ type };
vtkm::cont::DataSet outputData = vols.Execute(dataset);
VTKM_TEST_ASSERT(vols.GetCellMeasureName() == "measure");
@ -67,35 +65,36 @@ void TestCellMeasuresFilter(vtkm::cont::DataSet& dataset,
void TestCellMeasures()
{
using vtkm::AllMeasures;
using vtkm::Volume;
using vtkm::filter::mesh_info::IntegrationType;
vtkm::cont::testing::MakeTestDataSet factory;
vtkm::cont::DataSet data;
data = factory.Make3DExplicitDataSet2();
TestCellMeasuresFilter(data, "explicit dataset 2", { -1.f }, AllMeasures());
TestCellMeasuresFilter(data, "explicit dataset 2", { -1.f }, IntegrationType::AllMeasures);
data = factory.Make3DExplicitDataSet3();
TestCellMeasuresFilter(data, "explicit dataset 3", { -1.f / 6.f }, AllMeasures());
TestCellMeasuresFilter(data, "explicit dataset 3", { -1.f / 6.f }, IntegrationType::AllMeasures);
data = factory.Make3DExplicitDataSet4();
TestCellMeasuresFilter(data, "explicit dataset 4", { -1.f, -1.f }, AllMeasures());
TestCellMeasuresFilter(data, "explicit dataset 4", { -1.f, -1.f }, IntegrationType::AllMeasures);
data = factory.Make3DExplicitDataSet5();
TestCellMeasuresFilter(
data, "explicit dataset 5", { 1.f, 1.f / 3.f, 1.f / 6.f, -1.f / 2.f }, AllMeasures());
TestCellMeasuresFilter(data,
"explicit dataset 5",
{ 1.f, 1.f / 3.f, 1.f / 6.f, -1.f / 2.f },
IntegrationType::AllMeasures);
data = factory.Make3DExplicitDataSet6();
TestCellMeasuresFilter(data,
"explicit dataset 6 (only volume)",
{ 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.083426f, 0.25028f },
Volume());
IntegrationType::Volume);
TestCellMeasuresFilter(
data,
"explicit dataset 6 (all)",
{ 0.999924f, 0.999924f, 0.f, 0.f, 3.85516f, 1.00119f, 0.083426f, 0.25028f },
AllMeasures());
IntegrationType::AllMeasures);
}
} // anonymous namespace

@ -9,35 +9,33 @@
//============================================================================
#include <vtkm/cont/DataSet.h>
#include <vtkm/cont/DataSetBuilderExplicit.h>
#include <vtkm/cont/DataSetBuilderRectilinear.h>
#include <vtkm/cont/DataSetBuilderUniform.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/filter/GhostCellClassify.h>
#include <vtkm/CellClassification.h>
#include <vtkm/filter/mesh_info/GhostCellClassify.h>
namespace
{
static vtkm::cont::DataSet MakeUniform(vtkm::Id numI, vtkm::Id numJ, vtkm::Id numK)
vtkm::cont::DataSet MakeUniform(vtkm::Id numI, vtkm::Id numJ, vtkm::Id numK)
{
vtkm::cont::DataSetBuilderUniform dsb;
vtkm::cont::DataSet ds;
if (numJ == 0 && numK == 0)
ds = dsb.Create(numI + 1);
ds = vtkm::cont::DataSetBuilderUniform::Create(numI + 1);
else if (numK == 0)
ds = dsb.Create(vtkm::Id2(numI + 1, numJ + 1));
ds = vtkm::cont::DataSetBuilderUniform::Create(vtkm::Id2(numI + 1, numJ + 1));
else
ds = dsb.Create(vtkm::Id3(numI + 1, numJ + 1, numK + 1));
ds = vtkm::cont::DataSetBuilderUniform::Create(vtkm::Id3(numI + 1, numJ + 1, numK + 1));
return ds;
}
static vtkm::cont::DataSet MakeRectilinear(vtkm::Id numI, vtkm::Id numJ, vtkm::Id numK)
vtkm::cont::DataSet MakeRectilinear(vtkm::Id numI, vtkm::Id numJ, vtkm::Id numK)
{
vtkm::cont::DataSetBuilderRectilinear dsb;
vtkm::cont::DataSet ds;
std::size_t nx(static_cast<std::size_t>(numI + 1));
std::size_t ny(static_cast<std::size_t>(numJ + 1));
@ -49,14 +47,14 @@ static vtkm::cont::DataSet MakeRectilinear(vtkm::Id numI, vtkm::Id numJ, vtkm::I
y[i] = static_cast<float>(i);
if (numK == 0)
ds = dsb.Create(x, y);
ds = vtkm::cont::DataSetBuilderRectilinear::Create(x, y);
else
{
std::size_t nz(static_cast<std::size_t>(numK + 1));
std::vector<float> z(nz);
for (std::size_t i = 0; i < nz; i++)
z[i] = static_cast<float>(i);
ds = dsb.Create(x, y, z);
ds = vtkm::cont::DataSetBuilderRectilinear::Create(x, y, z);
}
return ds;
@ -100,7 +98,7 @@ void TestStructured()
else if (dsType == "rectilinear")
ds = MakeRectilinear(nx, ny, nz);
vtkm::filter::GhostCellClassify addGhost;
vtkm::filter::mesh_info::GhostCellClassify addGhost;
auto output = addGhost.Execute(ds);

@ -17,18 +17,16 @@
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <stdio.h>
#include <cstdio>
#include <string>
#include <typeinfo>
#include <vector>
#include <vtkm/cont/ArrayRangeCompute.h>
#include <vtkm/cont/CellSetSingleType.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/cont/DataSetBuilderExplicit.h>
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
#include <vtkm/cont/ErrorExecution.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/filter/MeshQuality.h>
#include <vtkm/io/VTKDataSetReader.h>
#include <vtkm/filter/mesh_info/MeshQuality.h>
namespace
{
@ -49,7 +47,6 @@ const char* GetCellShapeName(vtkm::UInt8 shape)
inline vtkm::cont::DataSet MakeExplicitDataSet()
{
vtkm::cont::DataSet dataSet;
vtkm::cont::DataSetBuilderExplicit dsb;
using CoordType = vtkm::Vec3f_64;
@ -115,7 +112,8 @@ inline vtkm::cont::DataSet MakeExplicitDataSet()
conn.push_back(28);
conn.push_back(29);
dataSet = dsb.Create(coords, shapes, numindices, conn, "coordinates");
dataSet =
vtkm::cont::DataSetBuilderExplicit::Create(coords, shapes, numindices, conn, "coordinates");
return dataSet;
}
@ -142,7 +140,7 @@ inline vtkm::cont::DataSet MakeSingleTypeDataSet()
bool TestMeshQualityFilter(const vtkm::cont::DataSet& input,
const std::vector<vtkm::FloatDefault>& expectedVals,
const std::string& outputname,
vtkm::filter::MeshQuality& filter)
vtkm::filter::mesh_info::MeshQuality& filter)
{
vtkm::cont::DataSet output;
try
@ -166,13 +164,13 @@ bool TestMeshQualityFilter(const vtkm::cont::DataSet& input,
}
bool anyFailures = false;
for (unsigned long i = 0; i < expectedVals.size(); i++)
for (size_t i = 0; i < expectedVals.size(); i++)
{
vtkm::Id id = (vtkm::Id)i;
if (!test_equal(portal1.Get(id), expectedVals[i]))
{
std::cout << "Metric `" << outputname << "` for cell " << i << " (type `"
<< GetCellShapeName(input.GetCellSet().GetCellSetBase()->GetCellShape(i))
<< GetCellShapeName(input.GetCellSet().GetCellSetBase()->GetCellShape(id))
<< "` does not match. Expected " << expectedVals[i] << " and got "
<< portal1.Get(id) << "\n";
anyFailures = true;
@ -193,170 +191,170 @@ int TestMeshQuality()
bool testFailed = false;
std::vector<FloatVec> expectedValues;
std::vector<vtkm::filter::CellMetric> metrics;
std::vector<vtkm::filter::mesh_info::CellMetric> metrics;
std::vector<std::string> metricName;
std::vector<vtkm::cont::DataSet> inputs;
expectedValues.push_back(FloatVec{ 0, 0, 1, 1.333333333f, 4, 4 });
metrics.push_back(vtkm::filter::CellMetric::VOLUME);
metricName.push_back("volume");
metrics.push_back(vtkm::filter::mesh_info::CellMetric::VOLUME);
metricName.emplace_back("volume");
inputs.push_back(explicitInput);
expectedValues.push_back(FloatVec{ 3, 4, 0, 0, 0, 0 });
metrics.push_back(vtkm::filter::CellMetric::AREA);
metricName.push_back("area");
metrics.push_back(vtkm::filter::mesh_info::CellMetric::AREA);
metricName.emplace_back("area");
inputs.push_back(explicitInput);
expectedValues.push_back(FloatVec{ 3, 1 });
metrics.push_back(vtkm::filter::CellMetric::AREA);
metricName.push_back("area");
metrics.push_back(vtkm::filter::mesh_info::CellMetric::AREA);
metricName.emplace_back("area");
inputs.push_back(singleTypeInput);
expectedValues.push_back(FloatVec{ 1.164010f, 1.118034f, 1.648938f, 0, 0, 1.1547f });
metrics.push_back(vtkm::filter::CellMetric::ASPECT_RATIO);
metricName.push_back("aspectRatio");
metrics.push_back(vtkm::filter::mesh_info::CellMetric::ASPECT_RATIO);
metricName.emplace_back("aspectRatio");
inputs.push_back(explicitInput);
expectedValues.push_back(FloatVec{ 1.164010f, 2.47582f });
metrics.push_back(vtkm::filter::CellMetric::ASPECT_RATIO);
metricName.push_back("aspectRatio");
metrics.push_back(vtkm::filter::mesh_info::CellMetric::ASPECT_RATIO);
metricName.emplace_back("aspectRatio");
inputs.push_back(singleTypeInput);
expectedValues.push_back(FloatVec{ 0, 0, 1.52012f, 0, 0, 0 });
metrics.push_back(vtkm::filter::CellMetric::ASPECT_GAMMA);
metricName.push_back("aspectGamma");
metrics.push_back(vtkm::filter::mesh_info::CellMetric::ASPECT_GAMMA);
metricName.emplace_back("aspectGamma");
inputs.push_back(explicitInput);
expectedValues.push_back(FloatVec{ 1.058475f, 2.25f, 1.354007f, 0, 0, 1.563472f });
metrics.push_back(vtkm::filter::CellMetric::CONDITION);
metricName.push_back("condition");
metrics.push_back(vtkm::filter::mesh_info::CellMetric::CONDITION);
metricName.emplace_back("condition");
inputs.push_back(explicitInput);
expectedValues.push_back(FloatVec{ 1.058475f, 2.02073f });
metrics.push_back(vtkm::filter::CellMetric::CONDITION);
metricName.push_back("condition");
metrics.push_back(vtkm::filter::mesh_info::CellMetric::CONDITION);
metricName.emplace_back("condition");
inputs.push_back(singleTypeInput);
expectedValues.push_back(FloatVec{ 45, 45, -1, -1, -1, -1 });
metrics.push_back(vtkm::filter::CellMetric::MIN_ANGLE);
metricName.push_back("minAngle");
metrics.push_back(vtkm::filter::mesh_info::CellMetric::MIN_ANGLE);
metricName.emplace_back("minAngle");
inputs.push_back(explicitInput);
expectedValues.push_back(FloatVec{ 45, 18.4348f });
metrics.push_back(vtkm::filter::CellMetric::MIN_ANGLE);
metricName.push_back("minAngle");
metrics.push_back(vtkm::filter::mesh_info::CellMetric::MIN_ANGLE);
metricName.emplace_back("minAngle");
inputs.push_back(singleTypeInput);
expectedValues.push_back(FloatVec{ 71.56505f, 135, -1, -1, -1, -1 });
metrics.push_back(vtkm::filter::CellMetric::MAX_ANGLE);
metricName.push_back("maxAngle");
metrics.push_back(vtkm::filter::mesh_info::CellMetric::MAX_ANGLE);
metricName.emplace_back("maxAngle");
inputs.push_back(explicitInput);
expectedValues.push_back(FloatVec{ 71.56505f, 116.565f });
metrics.push_back(vtkm::filter::CellMetric::MAX_ANGLE);
metricName.push_back("maxAngle");
metrics.push_back(vtkm::filter::mesh_info::CellMetric::MAX_ANGLE);
metricName.emplace_back("maxAngle");
inputs.push_back(singleTypeInput);
expectedValues.push_back(FloatVec{ -1, -1, -1, -1, -1, 1.73205f });
metrics.push_back(vtkm::filter::CellMetric::MIN_DIAGONAL);
metricName.push_back("minDiagonal");
metrics.push_back(vtkm::filter::mesh_info::CellMetric::MIN_DIAGONAL);
metricName.emplace_back("minDiagonal");
inputs.push_back(explicitInput);
expectedValues.push_back(FloatVec{ -1, -1, -1, -1, -1, 4.3589f });
metrics.push_back(vtkm::filter::CellMetric::MAX_DIAGONAL);
metricName.push_back("maxDiagonal");
metrics.push_back(vtkm::filter::mesh_info::CellMetric::MAX_DIAGONAL);
metricName.emplace_back("maxDiagonal");
inputs.push_back(explicitInput);
expectedValues.push_back(FloatVec{ 0, 2, 6, 0, 0, 4 });
metrics.push_back(vtkm::filter::CellMetric::JACOBIAN);
metricName.push_back("jacobian");
metrics.push_back(vtkm::filter::mesh_info::CellMetric::JACOBIAN);
metricName.emplace_back("jacobian");
inputs.push_back(explicitInput);
expectedValues.push_back(FloatVec{ 0.816497f, 0.707107f, 0.408248f, -2, -2, 0.57735f });
metrics.push_back(vtkm::filter::CellMetric::SCALED_JACOBIAN);
metricName.push_back("scaledJacobian");
metrics.push_back(vtkm::filter::mesh_info::CellMetric::SCALED_JACOBIAN);
metricName.emplace_back("scaledJacobian");
inputs.push_back(explicitInput);
expectedValues.push_back(FloatVec{ 0.816497f, 0.365148f });
metrics.push_back(vtkm::filter::CellMetric::SCALED_JACOBIAN);
metricName.push_back("scaledJacobian");
metrics.push_back(vtkm::filter::mesh_info::CellMetric::SCALED_JACOBIAN);
metricName.emplace_back("scaledJacobian");
inputs.push_back(singleTypeInput);
expectedValues.push_back(FloatVec{ -1, 8.125f, -1, -1, -1, 2.62484f });
metrics.push_back(vtkm::filter::CellMetric::ODDY);
metricName.push_back("oddy");
metrics.push_back(vtkm::filter::mesh_info::CellMetric::ODDY);
metricName.emplace_back("oddy");
inputs.push_back(explicitInput);
expectedValues.push_back(FloatVec{ -1, 0.620174f, -1, -1, -1, 0.397360f });
metrics.push_back(vtkm::filter::CellMetric::DIAGONAL_RATIO);
metricName.push_back("diagonalRatio");
metrics.push_back(vtkm::filter::mesh_info::CellMetric::DIAGONAL_RATIO);
metricName.emplace_back("diagonalRatio");
inputs.push_back(explicitInput);
expectedValues.push_back(FloatVec{ 0.944755f, 0.444444f, 0.756394f, -1, -1, 0.68723f });
metrics.push_back(vtkm::filter::CellMetric::SHAPE);
metricName.push_back("shape");
metrics.push_back(vtkm::filter::mesh_info::CellMetric::SHAPE);
metricName.emplace_back("shape");
inputs.push_back(explicitInput);
expectedValues.push_back(FloatVec{ 0.944755f, 0.494872f });
metrics.push_back(vtkm::filter::CellMetric::SHAPE);
metricName.push_back("shape");
metrics.push_back(vtkm::filter::mesh_info::CellMetric::SHAPE);
metricName.emplace_back("shape");
inputs.push_back(singleTypeInput);
expectedValues.push_back(FloatVec{ -1, 0.707107f, -1, -1, -1, 0.57735f });
metrics.push_back(vtkm::filter::CellMetric::SHEAR);
metricName.push_back("shear");
metrics.push_back(vtkm::filter::mesh_info::CellMetric::SHEAR);
metricName.emplace_back("shear");
inputs.push_back(explicitInput);
expectedValues.push_back(FloatVec{ -1, 0.447214f, -1, -1, -1, 0.57735f });
metrics.push_back(vtkm::filter::CellMetric::SKEW);
metricName.push_back("skew");
metrics.push_back(vtkm::filter::mesh_info::CellMetric::SKEW);
metricName.emplace_back("skew");
inputs.push_back(explicitInput);
expectedValues.push_back(FloatVec{ -1, (float)0.392232, -1, -1, -1, (float)0.688247 });
metrics.push_back(vtkm::filter::CellMetric::STRETCH);
metricName.push_back("stretch");
metrics.push_back(vtkm::filter::mesh_info::CellMetric::STRETCH);
metricName.emplace_back("stretch");
inputs.push_back(explicitInput);
expectedValues.push_back(FloatVec{ -1, 0.5, -1, -1, -1, 0 });
metrics.push_back(vtkm::filter::CellMetric::TAPER);
metricName.push_back("taper");
metrics.push_back(vtkm::filter::mesh_info::CellMetric::TAPER);
metricName.emplace_back("taper");
inputs.push_back(explicitInput);
expectedValues.push_back(FloatVec{ -1, 1, -1, -1, -1, -1 });
metrics.push_back(vtkm::filter::CellMetric::WARPAGE);
metricName.push_back("warpage");
metrics.push_back(vtkm::filter::mesh_info::CellMetric::WARPAGE);
metricName.emplace_back("warpage");
inputs.push_back(explicitInput);
expectedValues.push_back(FloatVec{ -1, -1, -1, -1, -1, 0.707107f });
metrics.push_back(vtkm::filter::CellMetric::DIMENSION);
metricName.push_back("dimension");
metrics.push_back(vtkm::filter::mesh_info::CellMetric::DIMENSION);
metricName.emplace_back("dimension");
inputs.push_back(explicitInput);
expectedValues.push_back(FloatVec{ 0.151235f, 0.085069f, 0.337149f, -1, -1, 0.185378f });
metrics.push_back(vtkm::filter::CellMetric::RELATIVE_SIZE_SQUARED);
metricName.push_back("relativeSizeSquared");
metrics.push_back(vtkm::filter::mesh_info::CellMetric::RELATIVE_SIZE_SQUARED);
metricName.emplace_back("relativeSizeSquared");
inputs.push_back(explicitInput);
expectedValues.push_back(FloatVec{ 0.444444f, 0.25f });
metrics.push_back(vtkm::filter::CellMetric::RELATIVE_SIZE_SQUARED);
metricName.push_back("relativeSizeSquared");
metrics.push_back(vtkm::filter::mesh_info::CellMetric::RELATIVE_SIZE_SQUARED);
metricName.emplace_back("relativeSizeSquared");
inputs.push_back(singleTypeInput);
expectedValues.push_back(FloatVec{ 0.142880f, 0.037809f, 0.255017f, -1, -1, 0.127397f });
metrics.push_back(vtkm::filter::CellMetric::SHAPE_AND_SIZE);
metricName.push_back("shapeAndSize");
metrics.push_back(vtkm::filter::mesh_info::CellMetric::SHAPE_AND_SIZE);
metricName.emplace_back("shapeAndSize");
inputs.push_back(explicitInput);
expectedValues.push_back(FloatVec{ 0.419891f, 0.123718f });
metrics.push_back(vtkm::filter::CellMetric::SHAPE_AND_SIZE);
metricName.push_back("shapeAndSize");
metrics.push_back(vtkm::filter::mesh_info::CellMetric::SHAPE_AND_SIZE);
metricName.emplace_back("shapeAndSize");
inputs.push_back(singleTypeInput);
unsigned long numTests = (unsigned long)metrics.size();
for (unsigned long i = 0; i < numTests; i++)
auto numTests = metrics.size();
for (size_t i = 0; i < numTests; i++)
{
printf("Testing metric %s\n", metricName[i].c_str());
vtkm::filter::MeshQuality filter(metrics[i]);
vtkm::filter::mesh_info::MeshQuality filter(metrics[i]);
testFailed = TestMeshQualityFilter(inputs[i], expectedValues[i], metricName[i], filter);
if (testFailed)
{

@ -0,0 +1,18 @@
##============================================================================
## 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
CellMeasure.h
MeshQuality.h
)
vtkm_declare_headers(${headers})
add_subdirectory(cellmetrics)

@ -11,33 +11,13 @@
#ifndef vtk_m_worklet_CellMeasure_h
#define vtk_m_worklet_CellMeasure_h
#include <vtkm/worklet/WorkletMapTopology.h>
#include <vtkm/exec/CellMeasure.h>
#include <vtkm/filter/mesh_info/CellMeasures.h>
#include <vtkm/worklet/WorkletMapTopology.h>
namespace vtkm
{
// Tags used to choose which types of integration are performed on cells:
struct IntegrateOver
{
};
struct IntegrateOverCurve : IntegrateOver
{
};
struct IntegrateOverSurface : IntegrateOver
{
};
struct IntegrateOverSolid : IntegrateOver
{
};
// Lists of acceptable types of integration
using ArcLength = vtkm::List<IntegrateOverCurve>;
using Area = vtkm::List<IntegrateOverSurface>;
using Volume = vtkm::List<IntegrateOverSolid>;
using AllMeasures = vtkm::List<IntegrateOverSolid, IntegrateOverSurface, IntegrateOverCurve>;
namespace worklet
{
@ -51,7 +31,6 @@ namespace worklet
*
* Note that the integrals are signed; inverted cells will report negative values.
*/
template <typename IntegrationTypeList>
class CellMeasure : public vtkm::worklet::WorkletVisitCellsWithPoints
{
public:
@ -61,6 +40,11 @@ public:
using ExecutionSignature = void(CellShape, PointCount, _2, _3);
using InputDomain = _1;
explicit CellMeasure(vtkm::filter::mesh_info::IntegrationType m)
: measure(m)
{
}
template <typename CellShape, typename PointCoordVecType, typename OutType>
VTKM_EXEC void operator()(CellShape shape,
const vtkm::IdComponent& numPoints,
@ -77,7 +61,7 @@ public:
}
}
protected:
private:
template <typename OutType, typename PointCoordVecType, typename CellShapeType>
VTKM_EXEC OutType ComputeMeasure(const vtkm::IdComponent& numPts,
const PointCoordVecType& pts,
@ -91,6 +75,7 @@ protected:
#pragma push
#pragma diag_suppress = code_is_unreachable
#endif
using vtkm::filter::mesh_info::IntegrationType;
vtkm::ErrorCode ec;
switch (vtkm::CellTraits<CellShapeType>::TOPOLOGICAL_DIMENSIONS)
@ -99,19 +84,19 @@ protected:
// Fall through to return 0 measure.
break;
case 1:
if (vtkm::ListHas<IntegrationTypeList, IntegrateOverCurve>::value)
if (this->measure & IntegrationType::ArcLength)
{
return vtkm::exec::CellMeasure<OutType>(numPts, pts, CellShapeType(), ec);
}
break;
case 2:
if (vtkm::ListHas<IntegrationTypeList, IntegrateOverSurface>::value)
if (this->measure & IntegrationType::Area)
{
return vtkm::exec::CellMeasure<OutType>(numPts, pts, CellShapeType(), ec);
}
break;
case 3:
if (vtkm::ListHas<IntegrationTypeList, IntegrateOverSolid>::value)
if (this->measure & IntegrationType::Volume)
{
return vtkm::exec::CellMeasure<OutType>(numPts, pts, CellShapeType(), ec);
}
@ -128,6 +113,8 @@ protected:
#pragma warning(pop)
#endif
}
vtkm::filter::mesh_info::IntegrationType measure;
};
}
} // namespace vtkm::worklet

@ -21,29 +21,30 @@
#ifndef vtk_m_worklet_MeshQuality_h
#define vtk_m_worklet_MeshQuality_h
#include "vtkm/ErrorCode.h"
#include "vtkm/worklet/CellMeasure.h"
#include "vtkm/worklet/WorkletMapTopology.h"
#include "vtkm/worklet/cellmetrics/CellAspectGammaMetric.h"
#include "vtkm/worklet/cellmetrics/CellAspectRatioMetric.h"
#include "vtkm/worklet/cellmetrics/CellConditionMetric.h"
#include "vtkm/worklet/cellmetrics/CellDiagonalRatioMetric.h"
#include "vtkm/worklet/cellmetrics/CellDimensionMetric.h"
#include "vtkm/worklet/cellmetrics/CellJacobianMetric.h"
#include "vtkm/worklet/cellmetrics/CellMaxAngleMetric.h"
#include "vtkm/worklet/cellmetrics/CellMaxDiagonalMetric.h"
#include "vtkm/worklet/cellmetrics/CellMinAngleMetric.h"
#include "vtkm/worklet/cellmetrics/CellMinDiagonalMetric.h"
#include "vtkm/worklet/cellmetrics/CellOddyMetric.h"
#include "vtkm/worklet/cellmetrics/CellRelativeSizeSquaredMetric.h"
#include "vtkm/worklet/cellmetrics/CellScaledJacobianMetric.h"
#include "vtkm/worklet/cellmetrics/CellShapeAndSizeMetric.h"
#include "vtkm/worklet/cellmetrics/CellShapeMetric.h"
#include "vtkm/worklet/cellmetrics/CellShearMetric.h"
#include "vtkm/worklet/cellmetrics/CellSkewMetric.h"
#include "vtkm/worklet/cellmetrics/CellStretchMetric.h"
#include "vtkm/worklet/cellmetrics/CellTaperMetric.h"
#include "vtkm/worklet/cellmetrics/CellWarpageMetric.h"
#include <vtkm/ErrorCode.h>
#include <vtkm/exec/CellMeasure.h>
#include <vtkm/filter/mesh_info/MeshQuality.h>
#include <vtkm/filter/mesh_info/worklet/cellmetrics/CellAspectGammaMetric.h>
#include <vtkm/filter/mesh_info/worklet/cellmetrics/CellAspectRatioMetric.h>
#include <vtkm/filter/mesh_info/worklet/cellmetrics/CellConditionMetric.h>
#include <vtkm/filter/mesh_info/worklet/cellmetrics/CellDiagonalRatioMetric.h>
#include <vtkm/filter/mesh_info/worklet/cellmetrics/CellDimensionMetric.h>
#include <vtkm/filter/mesh_info/worklet/cellmetrics/CellJacobianMetric.h>
#include <vtkm/filter/mesh_info/worklet/cellmetrics/CellMaxAngleMetric.h>
#include <vtkm/filter/mesh_info/worklet/cellmetrics/CellMaxDiagonalMetric.h>
#include <vtkm/filter/mesh_info/worklet/cellmetrics/CellMinAngleMetric.h>
#include <vtkm/filter/mesh_info/worklet/cellmetrics/CellMinDiagonalMetric.h>
#include <vtkm/filter/mesh_info/worklet/cellmetrics/CellOddyMetric.h>
#include <vtkm/filter/mesh_info/worklet/cellmetrics/CellRelativeSizeSquaredMetric.h>
#include <vtkm/filter/mesh_info/worklet/cellmetrics/CellScaledJacobianMetric.h>
#include <vtkm/filter/mesh_info/worklet/cellmetrics/CellShapeAndSizeMetric.h>
#include <vtkm/filter/mesh_info/worklet/cellmetrics/CellShapeMetric.h>
#include <vtkm/filter/mesh_info/worklet/cellmetrics/CellShearMetric.h>
#include <vtkm/filter/mesh_info/worklet/cellmetrics/CellSkewMetric.h>
#include <vtkm/filter/mesh_info/worklet/cellmetrics/CellStretchMetric.h>
#include <vtkm/filter/mesh_info/worklet/cellmetrics/CellTaperMetric.h>
#include <vtkm/filter/mesh_info/worklet/cellmetrics/CellWarpageMetric.h>
#include <vtkm/worklet/WorkletMapTopology.h>
namespace vtkm
{
@ -56,7 +57,6 @@ namespace worklet
* and this metric is invoked over all cells of that cell type. An array of
* the computed metric values (one per cell) is returned as output.
*/
template <typename MetricTagType>
class MeshQuality : public vtkm::worklet::WorkletVisitCellsWithPoints
{
public:
@ -66,16 +66,13 @@ public:
using ExecutionSignature = void(CellShape, PointCount, _2, _3);
using InputDomain = _1;
void SetMetric(MetricTagType m) { this->Metric = m; }
void SetMetric(vtkm::filter::mesh_info::CellMetric m) { this->Metric = m; }
void SetAverageArea(vtkm::FloatDefault a) { this->AverageArea = a; };
void SetAverageVolume(vtkm::FloatDefault v) { this->AverageVolume = v; };
template <typename CellShapeType, typename PointCoordVecType, typename OutType>
VTKM_EXEC void operator()(CellShapeType shape,
const vtkm::IdComponent& numPoints,
//const CountsArrayType& counts,
//const MetricsArrayType& metrics,
//MetricTagType metric,
const PointCoordVecType& pts,
OutType& metricValue) const
{
@ -97,11 +94,11 @@ public:
}
}
protected:
private:
// data member
MetricTagType Metric;
vtkm::FloatDefault AverageArea;
vtkm::FloatDefault AverageVolume;
vtkm::filter::mesh_info::CellMetric Metric{ vtkm::filter::mesh_info::CellMetric::EMPTY };
vtkm::FloatDefault AverageArea{};
vtkm::FloatDefault AverageVolume{};
template <typename OutType, typename PointCoordVecType, typename CellShapeType>
VTKM_EXEC OutType ComputeMetric(const vtkm::IdComponent& numPts,
@ -119,92 +116,92 @@ protected:
vtkm::ErrorCode ec{ vtkm::ErrorCode::Success };
switch (this->Metric)
{
case MetricTagType::AREA:
case vtkm::filter::mesh_info::CellMetric::AREA:
metricValue = vtkm::exec::CellMeasure<OutType>(numPts, pts, tag, ec);
if (dims != 2)
metricValue = 0.;
break;
case MetricTagType::ASPECT_GAMMA:
case vtkm::filter::mesh_info::CellMetric::ASPECT_GAMMA:
metricValue =
vtkm::worklet::cellmetrics::CellAspectGammaMetric<OutType>(numPts, pts, tag, ec);
break;
case MetricTagType::ASPECT_RATIO:
case vtkm::filter::mesh_info::CellMetric::ASPECT_RATIO:
metricValue =
vtkm::worklet::cellmetrics::CellAspectRatioMetric<OutType>(numPts, pts, tag, ec);
break;
case MetricTagType::CONDITION:
case vtkm::filter::mesh_info::CellMetric::CONDITION:
metricValue =
vtkm::worklet::cellmetrics::CellConditionMetric<OutType>(numPts, pts, tag, ec);
break;
case MetricTagType::DIAGONAL_RATIO:
case vtkm::filter::mesh_info::CellMetric::DIAGONAL_RATIO:
metricValue =
vtkm::worklet::cellmetrics::CellDiagonalRatioMetric<OutType>(numPts, pts, tag, ec);
break;
case MetricTagType::DIMENSION:
case vtkm::filter::mesh_info::CellMetric::DIMENSION:
metricValue =
vtkm::worklet::cellmetrics::CellDimensionMetric<OutType>(numPts, pts, tag, ec);
break;
case MetricTagType::JACOBIAN:
case vtkm::filter::mesh_info::CellMetric::JACOBIAN:
metricValue =
vtkm::worklet::cellmetrics::CellJacobianMetric<OutType>(numPts, pts, tag, ec);
break;
case MetricTagType::MAX_ANGLE:
case vtkm::filter::mesh_info::CellMetric::MAX_ANGLE:
metricValue =
vtkm::worklet::cellmetrics::CellMaxAngleMetric<OutType>(numPts, pts, tag, ec);
break;
case MetricTagType::MAX_DIAGONAL:
case vtkm::filter::mesh_info::CellMetric::MAX_DIAGONAL:
metricValue =
vtkm::worklet::cellmetrics::CellMaxDiagonalMetric<OutType>(numPts, pts, tag, ec);
break;
case MetricTagType::MIN_ANGLE:
case vtkm::filter::mesh_info::CellMetric::MIN_ANGLE:
metricValue =
vtkm::worklet::cellmetrics::CellMinAngleMetric<OutType>(numPts, pts, tag, ec);
break;
case MetricTagType::MIN_DIAGONAL:
case vtkm::filter::mesh_info::CellMetric::MIN_DIAGONAL:
metricValue =
vtkm::worklet::cellmetrics::CellMinDiagonalMetric<OutType>(numPts, pts, tag, ec);
break;
case MetricTagType::ODDY:
case vtkm::filter::mesh_info::CellMetric::ODDY:
metricValue = vtkm::worklet::cellmetrics::CellOddyMetric<OutType>(numPts, pts, tag, ec);
break;
case MetricTagType::RELATIVE_SIZE_SQUARED:
case vtkm::filter::mesh_info::CellMetric::RELATIVE_SIZE_SQUARED:
metricValue = vtkm::worklet::cellmetrics::CellRelativeSizeSquaredMetric<OutType>(
numPts, pts, static_cast<OutType>(average), tag, ec);
break;
case MetricTagType::SHAPE_AND_SIZE:
case vtkm::filter::mesh_info::CellMetric::SHAPE_AND_SIZE:
metricValue = vtkm::worklet::cellmetrics::CellShapeAndSizeMetric<OutType>(
numPts, pts, static_cast<OutType>(average), tag, ec);
break;
case MetricTagType::SCALED_JACOBIAN:
case vtkm::filter::mesh_info::CellMetric::SCALED_JACOBIAN:
metricValue =
vtkm::worklet::cellmetrics::CellScaledJacobianMetric<OutType>(numPts, pts, tag, ec);
break;
case MetricTagType::SHAPE:
case vtkm::filter::mesh_info::CellMetric::SHAPE:
metricValue = vtkm::worklet::cellmetrics::CellShapeMetric<OutType>(numPts, pts, tag, ec);
break;
case MetricTagType::SHEAR:
case vtkm::filter::mesh_info::CellMetric::SHEAR:
metricValue = vtkm::worklet::cellmetrics::CellShearMetric<OutType>(numPts, pts, tag, ec);
break;
case MetricTagType::SKEW:
case vtkm::filter::mesh_info::CellMetric::SKEW:
metricValue = vtkm::worklet::cellmetrics::CellSkewMetric<OutType>(numPts, pts, tag, ec);
break;
case MetricTagType::STRETCH:
case vtkm::filter::mesh_info::CellMetric::STRETCH:
metricValue =
vtkm::worklet::cellmetrics::CellStretchMetric<OutType>(numPts, pts, tag, ec);
break;
case MetricTagType::TAPER:
case vtkm::filter::mesh_info::CellMetric::TAPER:
metricValue = vtkm::worklet::cellmetrics::CellTaperMetric<OutType>(numPts, pts, tag, ec);
break;
case MetricTagType::VOLUME:
case vtkm::filter::mesh_info::CellMetric::VOLUME:
metricValue = vtkm::exec::CellMeasure<OutType>(numPts, pts, tag, ec);
if (dims != 3)
metricValue = 0.;
break;
case MetricTagType::WARPAGE:
case vtkm::filter::mesh_info::CellMetric::WARPAGE:
metricValue =
vtkm::worklet::cellmetrics::CellWarpageMetric<OutType>(numPts, pts, tag, ec);
break;
case MetricTagType::EMPTY:
case vtkm::filter::mesh_info::CellMetric::EMPTY:
break;
default:
//Only call metric function if a metric is specified for this shape type

@ -197,4 +197,4 @@ VTKM_EXEC OutType CellConditionMetric(const vtkm::IdComponent& numPts,
}
}
}
#endif // vtk_m_worklet_CellConditionMetric_h
#endif // vtk_m_worklet_cellmetrics_CellConditionMetric_h

@ -150,4 +150,4 @@ VTKM_EXEC OutType CellDiagonalRatioMetric(const vtkm::IdComponent& numPts,
} // namespace cellmetrics
} // namespace worklet
} // namespace vtkm
#endif // vtk_m_worklet_cellmetrics_CellEdgeRatioMetric_h
#endif // vtk_m_worklet_cellmetrics_CellDiagonalRatioMetric_h

@ -184,4 +184,4 @@ VTKM_EXEC OutType CellJacobianMetric(const vtkm::IdComponent& numPts,
} // namespace worklet
} // namespace vtkm
#endif // vtk_m_worklet_cellmetrics_CellJacobianMetric_h
#endif // vtk_m_worklet_cellmetrics_Jacobian_h

@ -35,12 +35,12 @@
* See: vtk/ThirdParty/verdict/vtkverdict (for VTK code implementation of this metric)
*/
#include "CellAspectFrobeniusMetric.h"
#include "vtkm/CellShape.h"
#include "vtkm/CellTraits.h"
#include "vtkm/VecTraits.h"
#include "vtkm/VectorAnalysis.h"
#include "vtkm/exec/FunctorBase.h"
#include "vtkm/worklet/cellmetrics/CellAspectFrobeniusMetric.h"
#define UNUSED(expr) (void)(expr);
@ -89,14 +89,11 @@ VTKM_EXEC OutType ComputeTetCondition(const VecType edges[])
// By default, cells have undefined aspect frobenius unless the shape type template is specialized below.
template <typename OutType, typename PointCoordVecType, typename CellShapeType>
VTKM_EXEC OutType CellMaxAspectFrobeniusMetric(const vtkm::IdComponent& numPts,
const PointCoordVecType& pts,
CellShapeType shape,
VTKM_EXEC OutType CellMaxAspectFrobeniusMetric(const vtkm::IdComponent&,
const PointCoordVecType&,
CellShapeType,
vtkm::ErrorCode& ec)
{
UNUSED(numPts);
UNUSED(pts);
UNUSED(shape);
ec = vtkm::ErrorCode::InvalidCellMetric;
return OutType(0.0);
}
@ -125,13 +122,11 @@ VTKM_EXEC OutType CellMaxAspectFrobeniusMetric(const vtkm::IdComponent& numPts,
//The max aspect frobenius metric is not supported for lines/edges.
template <typename OutType, typename PointCoordVecType>
VTKM_EXEC OutType CellMaxAspectFrobeniusMetric(const vtkm::IdComponent& numPts,
const PointCoordVecType& pts,
VTKM_EXEC OutType CellMaxAspectFrobeniusMetric(const vtkm::IdComponent&,
const PointCoordVecType&,
vtkm::CellShapeTagLine,
vtkm::ErrorCode& ec)
{
UNUSED(numPts);
UNUSED(pts);
ec = vtkm::ErrorCode::InvalidCellMetric;
return OutType(0.0);
}
@ -156,13 +151,11 @@ VTKM_EXEC OutType CellMaxAspectFrobeniusMetric(const vtkm::IdComponent& numPts,
//The max aspect frobenius metric is not supported for pyramids.
template <typename OutType, typename PointCoordVecType>
VTKM_EXEC OutType CellMaxAspectFrobeniusMetric(const vtkm::IdComponent& numPts,
const PointCoordVecType& pts,
VTKM_EXEC OutType CellMaxAspectFrobeniusMetric(const vtkm::IdComponent&,
const PointCoordVecType&,
vtkm::CellShapeTagPyramid,
vtkm::ErrorCode& ec)
{
UNUSED(numPts);
UNUSED(pts);
ec = vtkm::ErrorCode::InvalidCellMetric;
return OutType(0.0);
}
@ -371,11 +364,13 @@ VTKM_EXEC OutType CellMaxAspectFrobeniusMetric(const vtkm::IdComponent& numPts,
max_aspect_frobenius /= 1.16477;
if (max_aspect_frobenius > 0)
{
return vtkm::Min(max_aspect_frobenius, vtkm::Infinity<OutType>());
return vtkm::Max(max_aspect_frobenius, vtkm::NegativeInfinity<OutType>());
return OutType(0.0);
}
else
{
return vtkm::Max(max_aspect_frobenius, vtkm::NegativeInfinity<OutType>());
}
}
} // namespace cellmetrics
} // namespace worklet

@ -183,4 +183,4 @@ VTKM_EXEC OutType CellMinAngleMetric(const vtkm::IdComponent& numPts,
} // namespace cellmetrics
} // namespace worklet
} // namespace vtkm
#endif // vtk_m_worklet_cellmetrics_CellEdgeRatioMetric_h
#endif // vtk_m_worklet_cellmetrics_CellMinAngleMetric_h

@ -187,4 +187,4 @@ VTKM_EXEC OutType CellRelativeSizeSquaredMetric(const vtkm::IdComponent& numPts,
} // namespace worklet
} // namespace vtkm
#endif // vtk_m_exec_cellmetrics_CellRelativeSizeSquaredMetric.h
#endif // vtk_m_worklet_cellmetrics_CellRelativeSizeSquaredMetric_h

@ -307,4 +307,4 @@ VTKM_EXEC OutType CellScaledJacobianMetric(const vtkm::IdComponent& numPts,
} // namespace cellmetrics
} // namespace worklet
} // namespace vtkm
#endif // vtk_m_worklet_cellmetrics_CellEdgeRatioMetric_h
#endif // vtk_m_worklet_cellmetrics_ScaledJacobian_h

@ -31,12 +31,12 @@
* metric)
*/
#include "CellShapeMetric.h"
#include "vtkm/CellShape.h"
#include "vtkm/CellTraits.h"
#include "vtkm/VecTraits.h"
#include "vtkm/VectorAnalysis.h"
#include "vtkm/exec/FunctorBase.h"
#include "vtkm/worklet/cellmetrics/CellShapeMetric.h"
#define UNUSED(expr) (void)(expr);
@ -130,4 +130,4 @@ VTKM_EXEC OutType CellShapeAndSizeMetric(const vtkm::IdComponent& numPts,
} // namespace worklet
} // namespace vtkm
#endif // vtk_m_exec_cellmetrics_CellShapeAndSizeMetric.h
#endif // vtk_m_worklet_cellmetrics_CellShapeAndSizeMetric_h

@ -28,6 +28,8 @@
* See: vtk/ThirdParty/verdict/vtkverdict (for VTK code implementation of this metric)
*/
#include "CellConditionMetric.h"
#include "CellJacobianMetric.h"
#include "TypeOfCellHexahedral.h"
#include "TypeOfCellQuadrilateral.h"
#include "TypeOfCellTetrahedral.h"
@ -37,8 +39,6 @@
#include "vtkm/VecTraits.h"
#include "vtkm/VectorAnalysis.h"
#include "vtkm/exec/FunctorBase.h"
#include "vtkm/worklet/cellmetrics/CellConditionMetric.h"
#include "vtkm/worklet/cellmetrics/CellJacobianMetric.h"
namespace vtkm
{

@ -142,4 +142,4 @@ VTKM_EXEC OutType CellShearMetric(const vtkm::IdComponent& numPts,
} // namespace worklet
} // namespace vtkm
#endif // vtk_m_worklet_cellmetrics_CellEdgeRatioMetric_h
#endif // vtk_m_worklet_cellmetrics_CellShearMetric_h

@ -22,6 +22,7 @@
/*
*/
#include "CellConditionMetric.h"
#include "TypeOfCellHexahedral.h"
#include "TypeOfCellQuadrilateral.h"
#include "TypeOfCellTetrahedral.h"
@ -31,7 +32,6 @@
#include "vtkm/VecTraits.h"
#include "vtkm/VectorAnalysis.h"
#include "vtkm/exec/FunctorBase.h"
#include "vtkm/worklet/cellmetrics/CellConditionMetric.h"
namespace vtkm
{

@ -126,4 +126,4 @@ VTKM_EXEC OutType CellTaperMetric(const vtkm::IdComponent& numPts,
}
} // worklet
} // vtkm
#endif // vtk_m_worklet_CellTaper_Metric_h
#endif // vtk_m_worklet_CellTaperMetric_h

@ -78,4 +78,4 @@ VTKM_EXEC OutType CellWarpageMetric(const vtkm::IdComponent& numPts,
}
} // worklet
} // vtkm
#endif // vtk_m_worklet_CellWarpage_Metric_h
#endif // vtk_m_worklet_CellWarpageMetric_h

@ -13,18 +13,15 @@ set(headers
)
set(unit_tests
UnitTestCellMeasuresFilter.cxx
UnitTestContourTreeUniformFilter.cxx
UnitTestContourTreeUniformAugmentedFilter.cxx
UnitTestContourTreeUniformDistributedFilter.cxx
UnitTestFieldMetadata.cxx
UnitTestFieldSelection.cxx
UnitTestGhostCellClassify.cxx
UnitTestLagrangianFilter.cxx
UnitTestLagrangianStructuresFilter.cxx
UnitTestMapFieldMergeAverage.cxx
UnitTestMapFieldPermutation.cxx
UnitTestMeshQualityFilter.cxx
UnitTestMIRFilter.cxx
UnitTestMultiBlockFilter.cxx
UnitTestPartitionedDataSetFilters.cxx

@ -13,7 +13,6 @@ set(headers
BoundaryTypes.h
AveragePointNeighborhood.h
CellDeepCopy.h
CellMeasure.h
ContourTreeUniform.h
ContourTreeUniformAugmented.h
CosmoTools.h
@ -30,7 +29,6 @@ set(headers
MaskIndices.h
MaskNone.h
MaskSelect.h
MeshQuality.h
MIR.h
NDimsHistMarginalization.h
Normalize.h
@ -90,7 +88,6 @@ set(sources_device
#-----------------------------------------------------------------------------
add_subdirectory(internal)
add_subdirectory(cellmetrics)
add_subdirectory(colorconversion)
add_subdirectory(contourtree)
add_subdirectory(contourtree_augmented)

@ -13,6 +13,7 @@
#include <typeinfo>
#include <vtkm/VectorAnalysis.h>
#include <vtkm/cont/Algorithm.h>
#include <vtkm/cont/ArrayHandleCast.h>
#include <vtkm/cont/CellSetExplicit.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/cont/UnknownCellSet.h>
@ -40,35 +41,56 @@ public:
{
}
using ControlSignature = void(CellSetIn,
using ControlSignature = void(CellSetIn cellset,
WholeArrayIn pointCoords,
FieldOut nonIncidentPtsPerPolyline,
FieldOut ptsPerPolyline,
FieldOut ptsPerTube,
FieldOut numTubeConnIds,
FieldOut linesPerPolyline);
using ExecutionSignature = void(CellShape shapeType,
PointCount numPoints,
_2 ptsPerPolyline,
_3 ptsPerTube,
_4 numTubeConnIds,
_5 linesPerPolyline);
PointIndices ptIndices,
_2 inPts,
_3 nonIncidentPtsPerPolyline,
_4 ptsPerPolyline,
_5 ptsPerTube,
_6 numTubeConnIds,
_7 linesPerPolyline);
using InputDomain = _1;
template <typename CellShapeTag>
template <typename CellShapeTag, typename PointIndexType, typename InPointsType>
VTKM_EXEC void operator()(const CellShapeTag& shapeType,
const vtkm::IdComponent& numPoints,
const PointIndexType& ptIndices,
const InPointsType& inPts,
vtkm::IdComponent& nonIncidentPtsPerPolyline,
vtkm::Id& ptsPerPolyline,
vtkm::Id& ptsPerTube,
vtkm::Id& numTubeConnIds,
vtkm::Id& linesPerPolyline) const
{
// We only support polylines that contain 2 or more points.
if (shapeType.Id == vtkm::CELL_SHAPE_POLY_LINE && numPoints > 1)
vtkm::IdComponent numNonCoincidentPoints = 1;
vtkm::Vec3f p = inPts.Get(ptIndices[0]);
for (int i = 1; i < numPoints; ++i)
{
vtkm::Vec3f pNext = inPts.Get(ptIndices[i]);
if (vtkm::Magnitude(pNext - p) > vtkm::Epsilon<vtkm::FloatDefault>())
{
numNonCoincidentPoints++;
p = pNext;
}
}
if (shapeType.Id == vtkm::CELL_SHAPE_POLY_LINE && numNonCoincidentPoints > 1)
{
ptsPerPolyline = numPoints;
ptsPerTube = this->NumSides * numPoints;
nonIncidentPtsPerPolyline = numNonCoincidentPoints;
ptsPerTube = this->NumSides * numNonCoincidentPoints;
// (two tris per segment) X (numSides) X numVertsPerCell
numTubeConnIds = (numPoints - 1) * 2 * this->NumSides * this->NumVertsPerCell;
linesPerPolyline = numPoints - 1;
numTubeConnIds = (numNonCoincidentPoints - 1) * 2 * this->NumSides * this->NumVertsPerCell;
linesPerPolyline = numNonCoincidentPoints - 1;
//Capping adds center vertex in middle of cap, plus NumSides triangles for cap.
if (this->Capping)
@ -80,6 +102,7 @@ public:
else
{
ptsPerPolyline = 0;
nonIncidentPtsPerPolyline = 0;
ptsPerTube = 0;
numTubeConnIds = 0;
linesPerPolyline = 0;
@ -270,6 +293,7 @@ public:
using ControlSignature = void(CellSetIn cellset,
WholeArrayIn pointCoords,
WholeArrayIn normals,
FieldInCell numNonCoincidentPts,
FieldInCell tubePointOffsets,
FieldInCell polylineOffset,
WholeArrayOut newPointCoords,
@ -279,10 +303,11 @@ public:
PointIndices ptIndices,
_2 inPts,
_3 inNormals,
_4 tubePointOffsets,
_5 polylineOffset,
_6 outPts,
_7 outPointSrcIdx);
_4 numNonCoincidentPts,
_5 tubePointOffsets,
_6 polylineOffset,
_7 outPts,
_8 outPointSrcIdx);
using InputDomain = _1;
template <typename CellShapeTag,
@ -296,29 +321,44 @@ public:
const PointIndexType& ptIndices,
const InPointsType& inPts,
const InNormalsType& inNormals,
const vtkm::Id& numNonCoincidentPts,
const vtkm::Id& tubePointOffsets,
const vtkm::Id& polylineOffset,
OutPointsType& outPts,
OutPointSrcIdxType& outPointSrcIdx) const
{
if (shapeType.Id != vtkm::CELL_SHAPE_POLY_LINE || numPoints < 2)
if (shapeType.Id != vtkm::CELL_SHAPE_POLY_LINE || numNonCoincidentPts < 2)
return;
else
{
vtkm::Id outIdx = tubePointOffsets;
vtkm::Id pIdx = ptIndices[0];
vtkm::Id pNextIdx = ptIndices[1];
vtkm::Id pNextIdx =
ptIndices[this->FindNextNonCoincidentPointIndex(ptIndices, inPts, 0, numPoints)];
vtkm::Vec3f p = inPts.Get(pIdx);
vtkm::Vec3f pNext = inPts.Get(pNextIdx);
vtkm::Vec3f sNext = pNext - p;
vtkm::Vec3f sPrev = sNext;
for (vtkm::IdComponent j = 0; j < numPoints; j++)
vtkm::FloatDefault eps = vtkm::Epsilon<vtkm::FloatDefault>();
//Add the start cap vertex. This is just a point at the center of the tube (on the polyline).
if (this->Capping)
{
outPts.Set(outIdx, p);
outPointSrcIdx.Set(outIdx, pIdx);
outIdx++;
}
vtkm::IdComponent j = 0;
while (j < numPoints)
{
vtkm::IdComponent jNext =
this->FindNextNonCoincidentPointIndex(ptIndices, inPts, j, numPoints);
if (j == 0) //first point
{
//Variables initialized before loop started.
}
else if (j == numPoints - 1) //last point
else if (jNext == numPoints) //last point
{
sPrev = sNext;
p = pNext;
@ -328,26 +368,22 @@ public:
{
p = pNext;
pIdx = pNextIdx;
pNextIdx = ptIndices[j + 1];
pNextIdx = ptIndices[jNext];
pNext = inPts.Get(pNextIdx);
sPrev = sNext;
sNext = pNext - p;
}
vtkm::Vec3f n = inNormals.Get(polylineOffset + j);
//Coincident points.
if (vtkm::Magnitude(sNext) <= vtkm::Epsilon<vtkm::FloatDefault>())
this->RaiseError("Coincident points in Tube worklet.");
vtkm::Normalize(sNext);
auto s = (sPrev + sNext) / 2.;
if (vtkm::Magnitude(s) <= vtkm::Epsilon<vtkm::FloatDefault>())
if (vtkm::Magnitude(s) <= eps)
s = vtkm::Cross(sPrev, n);
vtkm::Normalize(s);
auto w = vtkm::Cross(s, n);
//Bad normal
if (vtkm::Magnitude(w) <= vtkm::Epsilon<vtkm::FloatDefault>())
if (vtkm::Magnitude(w) <= eps)
this->RaiseError("Bad normal in Tube worklet.");
vtkm::Normalize(w);
@ -355,14 +391,6 @@ public:
auto nP = vtkm::Cross(w, s);
vtkm::Normalize(nP);
//Add the start cap vertex. This is just a point at the center of the tube (on the polyline).
if (this->Capping && j == 0)
{
outPts.Set(outIdx, p);
outPointSrcIdx.Set(outIdx, pIdx);
outIdx++;
}
//this only implements the 'sides share vertices' line 476
vtkm::Vec3f normal;
for (vtkm::IdComponent k = 0; k < this->NumSides; k++)
@ -377,17 +405,41 @@ public:
outIdx++;
}
//Add the end cap vertex. This is just a point at the center of the tube (on the polyline).
if (this->Capping && j == numPoints - 1)
{
outPts.Set(outIdx, p);
outPointSrcIdx.Set(outIdx, pIdx);
outIdx++;
}
j = jNext;
}
//Add the end cap vertex. This is just a point at the center of the tube (on the polyline).
if (this->Capping)
{
outPts.Set(outIdx, p);
outPointSrcIdx.Set(outIdx, pIdx);
outIdx++;
}
}
}
template <typename PointIndexType, typename InPointsType>
VTKM_EXEC vtkm::IdComponent FindNextNonCoincidentPointIndex(const PointIndexType& ptIndices,
const InPointsType& inPts,
vtkm::IdComponent start,
vtkm::IdComponent numPoints) const
{
vtkm::Id pIdx = ptIndices[start];
vtkm::Id pNextIdx;
vtkm::Float32 eps = vtkm::Epsilon<vtkm::FloatDefault>();
for (vtkm::IdComponent i = start + 1; i < numPoints; ++i)
{
pNextIdx = ptIndices[i];
vtkm::FloatDefault pNext = vtkm::Magnitude(inPts.Get(pIdx) - inPts.Get(pNextIdx));
if (pNext > eps)
{
return i;
}
}
return numPoints;
}
private:
bool Capping;
vtkm::Id NumSides;
@ -407,18 +459,19 @@ public:
}
using ControlSignature = void(CellSetIn cellset,
FieldInCell ptsPerPolyline,
FieldInCell tubePointOffsets,
FieldInCell tubeConnOffsets,
FieldInCell segOffset,
WholeArrayOut outConnectivity,
WholeArrayOut outCellSrcIdx);
using ExecutionSignature = void(CellShape shapeType,
PointCount numPoints,
_2 tubePointOffset,
_3 tubeConnOffsets,
_4 segOffset,
_5 outConn,
_6 outCellSrcIdx);
_2 ptsPerPolyline,
_3 tubePointOffset,
_4 tubeConnOffsets,
_5 segOffset,
_6 outConn,
_7 outCellSrcIdx);
using InputDomain = _1;
template <typename CellShapeTag, typename OutConnType, typename OutCellSrcIdxType>
@ -525,7 +578,6 @@ public:
: Capping(capping)
, NumSides(n)
, Radius(r)
{
}
@ -552,9 +604,16 @@ public:
//Count number of polyline pts, tube pts and tube cells
vtkm::cont::ArrayHandle<vtkm::Id> ptsPerPolyline, ptsPerTube, numTubeConnIds, segPerPolyline;
vtkm::cont::ArrayHandle<vtkm::IdComponent> nonIncidentPtsPerPolyline;
CountSegments countSegs(this->Capping, this->NumSides);
vtkm::worklet::DispatcherMapTopology<CountSegments> countInvoker(countSegs);
countInvoker.Invoke(cellset, ptsPerPolyline, ptsPerTube, numTubeConnIds, segPerPolyline);
countInvoker.Invoke(cellset,
coords,
nonIncidentPtsPerPolyline,
ptsPerPolyline,
ptsPerTube,
numTubeConnIds,
segPerPolyline);
vtkm::Id totalPolylinePts = vtkm::cont::Algorithm::Reduce(ptsPerPolyline, vtkm::Id(0));
if (totalPolylinePts == 0)
@ -564,9 +623,12 @@ public:
//All cells are triangles, so cell count is simple to compute.
vtkm::Id totalTubeCells = totalTubeConnIds / 3;
vtkm::cont::ArrayHandle<vtkm::Id> polylinePtOffset, tubePointOffsets, tubeConnOffsets,
segOffset;
vtkm::cont::ArrayHandle<vtkm::Id> polylinePtOffset, nonIncidentPolylinePtOffset,
tubePointOffsets, tubeConnOffsets, segOffset;
vtkm::cont::Algorithm::ScanExclusive(ptsPerPolyline, polylinePtOffset);
vtkm::cont::Algorithm::ScanExclusive(
vtkm::cont::make_ArrayHandleCast<vtkm::Id>(nonIncidentPtsPerPolyline),
nonIncidentPolylinePtOffset);
vtkm::cont::Algorithm::ScanExclusive(ptsPerTube, tubePointOffsets);
vtkm::cont::Algorithm::ScanExclusive(numTubeConnIds, tubeConnOffsets);
vtkm::cont::Algorithm::ScanExclusive(segPerPolyline, segOffset);
@ -585,6 +647,7 @@ public:
genPtsDisp.Invoke(cellset,
coords,
normals,
nonIncidentPtsPerPolyline,
tubePointOffsets,
polylinePtOffset,
newPoints,
@ -597,6 +660,7 @@ public:
GenerateCells genCells(this->Capping, this->NumSides);
vtkm::worklet::DispatcherMapTopology<GenerateCells> genCellsDisp(genCells);
genCellsDisp.Invoke(cellset,
nonIncidentPtsPerPolyline,
tubePointOffsets,
tubeConnOffsets,
segOffset,

@ -17,7 +17,6 @@ set(unit_tests
UnitTestAverageByKey.cxx
UnitTestBoundingIntervalHierarchy.cxx
UnitTestCellDeepCopy.cxx
UnitTestCellMeasure.cxx
UnitTestContourTreeUniform.cxx
UnitTestContourTreeUniformAugmented.cxx
UnitTestContourTreeUniformDistributed.cxx

@ -11,7 +11,7 @@
#include <vtkm/cont/DataSetBuilderExplicit.h>
#include <vtkm/cont/DataSetBuilderRectilinear.h>
#include <vtkm/cont/DataSetBuilderUniform.h>
#include <vtkm/filter/GhostCellClassify.h>
#include <vtkm/filter/mesh_info/GhostCellClassify.h>
namespace vtkm
{
@ -46,7 +46,7 @@ inline vtkm::cont::DataSet CreateUniformDataSet(const vtkm::Bounds& bounds,
if (addGhost)
{
vtkm::filter::GhostCellClassify addGhostFilter;
vtkm::filter::mesh_info::GhostCellClassify addGhostFilter;
return addGhostFilter.Execute(ds);
}
return ds;
@ -84,7 +84,7 @@ inline vtkm::cont::DataSet CreateRectilinearDataSet(const vtkm::Bounds& bounds,
if (addGhost)
{
vtkm::filter::GhostCellClassify addGhostFilter;
vtkm::filter::mesh_info::GhostCellClassify addGhostFilter;
return addGhostFilter.Execute(ds);
}
return ds;

@ -1,118 +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/CellMeasure.h>
#include <vtkm/worklet/DispatcherMapTopology.h>
#include <vtkm/cont/testing/MakeTestDataSet.h>
#include <vtkm/cont/testing/Testing.h>
namespace
{
void TestCellMeasureUniform3D()
{
std::cout << "Testing CellMeasure Worklet on 3D structured data" << std::endl;
vtkm::cont::testing::MakeTestDataSet testDataSet;
vtkm::cont::DataSet dataSet = testDataSet.Make3DUniformDataSet0();
vtkm::cont::ArrayHandle<vtkm::FloatDefault> result;
vtkm::worklet::DispatcherMapTopology<vtkm::worklet::CellMeasure<vtkm::Volume>> dispatcher;
dispatcher.Invoke(
dataSet.GetCellSet(), dataSet.GetCoordinateSystem().GetDataAsMultiplexer(), result);
vtkm::Float32 expected[4] = { 1.f, 1.f, 1.f, 1.f };
for (int i = 0; i < 4; ++i)
{
VTKM_TEST_ASSERT(test_equal(result.ReadPortal().Get(vtkm::Id(i)), expected[i]),
"Wrong result for CellMeasure worklet on 3D uniform data");
}
}
template <typename IntegrationType>
void TestCellMeasureWorklet(vtkm::cont::DataSet& dataset,
const char* msg,
const std::vector<vtkm::Float32>& expected,
const IntegrationType&)
{
std::cout << "Testing CellMeasures Filter on " << msg << "\n";
vtkm::cont::ArrayHandle<vtkm::FloatDefault> result;
vtkm::worklet::DispatcherMapTopology<vtkm::worklet::CellMeasure<IntegrationType>> dispatcher;
dispatcher.Invoke(
dataset.GetCellSet(), dataset.GetCoordinateSystem().GetDataAsMultiplexer(), result);
VTKM_TEST_ASSERT(result.GetNumberOfValues() == static_cast<vtkm::Id>(expected.size()),
"Wrong number of values in the output array");
for (unsigned int i = 0; i < static_cast<unsigned int>(expected.size()); ++i)
{
VTKM_TEST_ASSERT(test_equal(result.ReadPortal().Get(vtkm::Id(i)), expected[i]),
"Wrong result for CellMeasure filter");
}
}
void TestCellMeasure()
{
using vtkm::AllMeasures;
using vtkm::ArcLength;
using vtkm::Area;
using vtkm::Volume;
TestCellMeasureUniform3D();
vtkm::cont::testing::MakeTestDataSet factory;
vtkm::cont::DataSet data;
data = factory.Make3DExplicitDataSet2();
TestCellMeasureWorklet(data, "explicit dataset 2", { -1.f }, Volume());
data = factory.Make3DExplicitDataSet3();
TestCellMeasureWorklet(data, "explicit dataset 3", { -1.f / 6.f }, Volume());
data = factory.Make3DExplicitDataSet4();
TestCellMeasureWorklet(data, "explicit dataset 4", { -1.f, -1.f }, Volume());
data = factory.Make3DExplicitDataSet5();
TestCellMeasureWorklet(
data, "explicit dataset 5", { 1.f, 1.f / 3.f, 1.f / 6.f, -1.f / 2.f }, Volume());
data = factory.Make3DExplicitDataSet6();
TestCellMeasureWorklet(
data,
"explicit dataset 6 (all)",
{ 0.999924f, 0.999924f, 0.f, 0.f, 3.85516f, 1.00119f, 0.083426f, 0.25028f },
AllMeasures());
TestCellMeasureWorklet(data,
"explicit dataset 6 (arc length)",
{ 0.999924f, 0.999924f, 0.f, 0.f, 0.0f, 0.0f, 0.0f, 0.0f },
ArcLength());
TestCellMeasureWorklet(data,
"explicit dataset 6 (area)",
{ 0.0f, 0.0f, 0.f, 0.f, 3.85516f, 1.00119f, 0.0f, 0.0f },
Area());
TestCellMeasureWorklet(data,
"explicit dataset 6 (volume)",
{ 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.083426f, 0.25028f },
Volume());
TestCellMeasureWorklet(data,
"explicit dataset 6 (empty)",
{ 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.0f, 0.0f },
vtkm::List<>());
}
}
int UnitTestCellMeasure(int argc, char* argv[])
{
return vtkm::cont::testing::Testing::Run(TestCellMeasure, argc, argv);
}

@ -13,7 +13,7 @@
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/filter/GhostCellClassify.h>
#include <vtkm/filter/mesh_info/GhostCellClassify.h>
#include <vtkm/io/VTKDataSetReader.h>
#include <vtkm/worklet/ParticleAdvection.h>
#include <vtkm/worklet/particleadvection/EulerIntegrator.h>

@ -206,6 +206,72 @@ void TestLinearPolylines()
}
}
void TestPolylinesWithCoincidentPoints()
{
using VecType = vtkm::Vec3f;
bool capEnds = false;
vtkm::Id numSides = 3;
vtkm::FloatDefault radius = 1;
vtkm::cont::DataSetBuilderExplicitIterative dsb;
std::vector<vtkm::Id> ids;
std::vector<vtkm::FloatDefault> ptVar;
vtkm::FloatDefault eps = vtkm::Epsilon<vtkm::FloatDefault>() * 0.1f;
vtkm::Id numPtsToSkip = 0;
vtkm::Id numPts = 0;
ids.clear();
appendPts(dsb, VecType(0.0f, 0.0f, 0.0f), ids);
ptVar.push_back(1);
appendPts(dsb, VecType(0.0f, 0.0f, 0.0f), ids);
ptVar.push_back(2);
appendPts(dsb, VecType(eps, 0.0f, 0.0f), ids);
ptVar.push_back(3);
dsb.AddCell(vtkm::CELL_SHAPE_POLY_LINE, ids);
numPts += 3;
numPtsToSkip += 3;
ids.clear();
appendPts(dsb, VecType(0.0f, 0.0f, 0.0f), ids);
ptVar.push_back(7);
appendPts(dsb, VecType(1.0f, 0.0f, 0.0f), ids);
ptVar.push_back(8);
appendPts(dsb, VecType(1.0f + eps, 0.0f, 0.0f), ids);
ptVar.push_back(9);
appendPts(dsb, VecType(1.0f, -eps, 0.0f), ids);
ptVar.push_back(13);
appendPts(dsb, VecType(2.0f, 0.0f, 0.0f), ids);
ptVar.push_back(10);
appendPts(dsb, VecType(2.0f, 0.0f, eps), ids);
ptVar.push_back(11);
appendPts(dsb, VecType(2.0f + eps, eps, eps), ids);
ptVar.push_back(12);
dsb.AddCell(vtkm::CELL_SHAPE_POLY_LINE, ids);
numPts += 7;
numPtsToSkip += 4;
vtkm::cont::DataSet ds = dsb.Create();
vtkm::Id reqNumPts = calcNumPoints(numPts - numPtsToSkip, numSides, capEnds);
vtkm::Id reqNumCells = calcNumCells(numPts - numPtsToSkip, numSides, capEnds);
vtkm::worklet::Tube tubeWorklet(capEnds, numSides, radius);
vtkm::cont::ArrayHandle<vtkm::Vec3f> newPoints;
vtkm::cont::CellSetSingleType<> newCells;
tubeWorklet.Run(
ds.GetCoordinateSystem(0).GetData().AsArrayHandle<vtkm::cont::ArrayHandle<vtkm::Vec3f>>(),
ds.GetCellSet(),
newPoints,
newCells);
VTKM_TEST_ASSERT(newPoints.GetNumberOfValues() == reqNumPts,
"Wrong number of points in Tube worklet");
VTKM_TEST_ASSERT(newCells.GetNumberOfCells() == reqNumCells, "Wrong cell shape in Tube worklet");
VTKM_TEST_ASSERT(newCells.GetCellShape(0) == vtkm::CELL_SHAPE_TRIANGLE,
"Wrong cell shape in Tube worklet");
}
void TestTubeWorklets()
{
std::cout << "Testing Tube Worklet" << std::endl;
@ -223,6 +289,7 @@ void TestTubeWorklets()
}
TestLinearPolylines();
TestPolylinesWithCoincidentPoints();
}
}